(SDK) equivalent to mxs "modPanel"


#1

I swear I have searched for this several times and I can’t find anything.

What’s the way to get the current object selected in the modify panel through the SDK? The other modpanel commands can help me too (and if it’s in SDK.NET, perfect).

Thanks again. :bowdown:


#2

GetCurEditObject()
Returns a pointer to the object (or modifier) that is currently being edited in the modifier panel.

You may also want to take a look at the IDerivedObject Class.


#3

From MXS you can test it like:

(
 	GlobalInterface = (dotnetclass "Autodesk.Max.GlobalInterface").Instance
 	I7 = GlobalInterface.COREInterface7
 	
 	currObject = I7.CurEditObject
 	
 	format "METHODS

"
 	showmethods currObject
 	
 	format "

PROPERTIES

"
 	showproperties currObject
 	
 	messagebox currObject.Name -- For modifiers
 )

As all methods starting with ‘Get’ in the SDK, it was implemented as a property in C#, so it is <INTERFACE>.CurEditObject instead of <INTERFACE>.GetCurEditObject().


#4

Thanks a lot, Jorge! That’s just what I needed… and much more.
Never thought I had to search directly in the CoreInterface.
There are lot of things accessible from there. In less than 10 years, I’m sure I will be able to do something serious in Max! :blush:


#5

Here’s a code in SDK.NET to get the current object:

        // GetCurrentObject in ModifyPanel
        static public void GetCurrentObject_Test()
        {
            IGlobal global = GlobalInterface.Instance;
            IInterface14 ip = global.COREInterface14;

            IBaseObject modif = ip.CurEditObject;

            if (modif == null)
            {
                //("Modify Panel closed or any node selected");
            }
            else
            {
                Type modifType = modif.GetType();
                string modifTypeName = modifType.Name;

                if (modifTypeName == "OSModifier") //Autodesk.Max.Wrappers.OSModifier
                {
                    //("It's an Object Space Modifier");
                    IModifier theModif = modif as IModifier;
                }
                else
                {
                    if (modifTypeName == "Modifier") //Autodesk.Max.Wrappers.Modifier
                    {
                        //("It's a World Space Modifier");
                        IModifier theModif = modif as IModifier;
                    }
                    else
                    {
                        //("It's the Base Object");
                    }
                }
            }
        }

What is a headache, and haven’t got how to do it, it’s to get the “dependentnodes” of this modifier.
I have found this code in the SDK help, but I’m not able to convert it to SDK.NET:

INode* GetNodeFromObject(BaseObject* obj) {
  ULONG handle = 0;
  rm->NotifyDependents(FOREVER, (PartID)&handle, REFMSG_GET_NODE_HANDLE);
  INode *node = GetCOREInterface()->GetINodeByHandle(handle);
  return node;
}

My attemp of “translation” is:

        static public IINode GetNodeFromObject(IBaseObject obj)
        {
            IGlobal global = GlobalInterface.Instance;
            IInterface14 ip = global.COREInterface14;

            // make an interval class and set it to forever
            IInterval interval = global.Interval.Create();
            interval.SetInfinite();

            uint handle = 0;
            IReferenceMaker rm = default(IReferenceMaker);
            RefMessage message = (RefMessage)544; //NodeHandle
            SClass_ID sclass = (SClass_ID)16; //GeometryObject
           
            rm.NotifyDependents(interval, (UIntPtr)handle, message, sclass, false, obj); //fails
            IINode node = ip.GetINodeByHandle(handle);
            return node;
        }

But it doesn’t work at all.
‘NotifyDependents’ has more parameters in C# version than in C++, and there’s any serious description;

    RefResult NotifyDependents(IInterval changeInt, UIntPtr partID, RefMessage message, SClass_ID sclass, bool propagate, IReferenceTarget hTarg);

Any suggestions?


#6

The refs structure source code is in the SDK. Take a look at “refs.cpp”


#7

Thanks for your reply, Jorge.
Sadly, I can’t understand anything of what I see there. My know-how of c++ is equal to zero. Not even by intuition I can follow it. :cry:


#8

look at FindNodeFromBaseObject in the Interface7. it has to work in your case.

but if you want to know all nodes for example that some modifier is applied to, you have to search all its dependents.


#9

the code above works only for BaseObjects. It can’t work for Modifiers (or ReferenceTargets) in general.


#10

it has to be not a default ReferenceMaker. It must be the maker made for your object.

but anyway, as i said it works only for BaseObjects.


#11

Hi DenisT.
Thanks for your help. ‘FindNodeFromBaseObject’ works fine but, as you said, only retreives one node.

IINode node = ip.FindNodeFromBaseObject(modif);

When you say " It must be the maker made for your object."… is not that (more or less) what I’m looking for?
I’m totaly lost. Please, can you show me the way?


#12

what do you want to know? what nodes is a specified modifier applied to?


#13

there is another statement of the question:
what nodes are depends on a specified modifier?


#14

Yes. Or more generally, create a function in C# that does the same than “refs.dependentNodes” in MaxScript.

I don’t understand the question. Sorry.


#15

my questions above might have a different answers.

If a modifier is applied to some node this node depends on this modifier.
But if a node depends on some modifier it doesn’t automatically mean that this modifier is applied to this node.
See the difference?


#16

Ummm, yes. I suppose it’s like you say, because I believe in you.
My knowledge of 3DMax is not fantastic. I can’t think about a situation where the second sentence applies, but I’m sure it can be.


#17

refs.dependentNodes recursively enumerates all dependents of a specified reference target by searching and collecting nodes.

the only one criteria for node to be added to the list is the fact of any dependency. But there is an optional flag - baseObjectOnly. it filters only nodes where the specified reference is a base object of these nodes

there is no flag to and a direct way to filter only nodes where a specified reference is an applied modifier.
you have to do this filtering yourself.

but… as i already showed on this forum in general case is cleaner and usually faster do find all ‘applied to’ nodes as:

for node in objects where (finditem node.modifiers modi > 0) collect node

#18

That is really faster??!! There’s any flag saying “hey, I depend on you”?
Thanks a lot DenisT.
I’ll do it this way. It’s just what I need.


#19

you have to use what works better for you. you can make a function that will work faster and do what you need. i don’t have max 2015+ right now and can’t do and test C# sdk code


#20

check this setup:

modiTest = attributes modiTest
(
	parameters params 
	(
		modi type:#maxobject
	)
)
delete objects
b = box()
custattributes.add b modiTest baseobject:on
uv_modi = Uvwmap()
b.modiTest.modi = uv_modi

if you ask:

refs.dependentnodes uv_modi

it will return you empty array.

but if you ask:

refs.dependencyLoopTest b uv_modi

it will return you TRUE

these two methods are using different level of tested ‘dependency’
if we need all really dependent nodes you have to do something:

fn getAllDependentNodes maxobj nodes:#() = 
(
	objs = refs.dependents maxobj
	for obj in objs do
	(
		if isvalidnode obj do appendifunique nodes obj
		getAllDependentNodes obj nodes:nodes
	)
	nodes
)
getAllDependentNodes uv_modi