getting modifier info (SDK)


Hi Everybody!
Im very new using the sdk from 3ds Max, so i have a lot of silly problems.
Im doing a exporter plugin and i have problems exporting information from
the modifiers applied in my scene objects (materials and mesh works perfectly).

I have my scene nodes and check for modifiers like this:

  if (node->GetObjectRef()->SuperClassID() == GEN_DERIVOB_CLASS_ID) {
 	IDerivedObject* derivedObject = (IDerivedObject*) node->GetObjectRef();
 	unsigned int numMod = derivedObject->NumModifiers();
 	for(unsigned int i = 0; i<numMod;i++) {
 		//check modifier info
 		MSTR s;
 		//Getting info errors

My problems are inside the previous for loop, in //Getting info errors
Now i want only info from displace modifiers so, i check that inside the loop.

  if (derivedObject->GetModifier(i)->ClassID() == Class_ID(DISPLACEOSM_CLASS_ID,0) ) {
  //get info

Looks like all the info in modifiers should be in a IParamblock2* structure.
but always gets null pointer from the modifier.
i tried:

  Modifier* modifier = derivedObject->GetModifier(i);


  SimpleMod2* modifier = (SimpleMod2*)derivedObject->GetModifier(i);

but anyway pointers are NULL, so getValue crashes.

  IParamArray* pa = modifier->getParamBlock(); //gets NULL
  IParamBlock* pblock = modifier->pblock; //gets NULL
  IParamBlock* pblock2 = modifier->pblock2; //gets NULL
  pblock->GetValue(DISPLACE_STRENGTH,t,str,FOREVER); //getting crash example 
  //for strength info from displace mod and "str" previous defined

and i suppose get info from any modifier is always the same.

I try too getting subAnim info from modifiers, and i can get all the subAnims
(and the subAnims from the preovius subAnims) but something like this is wrong too
(i think is because there is no animation keys) to get the parameters value:

for(int num = 0; num < numsub; num++){
 	MSTR sa;
 	sa = modifier->SubAnimName(num);
 	Animatable* anim = modifier->SubAnim(num);
 	int numpba = anim->NumParamBlocks();
 	int numsub2 = anim->NumSubs();
 	for(int num2 = 0; num2 < numsub2; num2++){
 		MSTR sa2;
 		sa2 = anim->SubAnimName(num2);
 		if (sa2 == (MSTR)"Strength") {
 			Animatable *anim2 = anim->SubAnim(num2);
 			Interval valid;
 			Control *cont = GetControlInterface(anim);

Very Thanks for any help and sorry if its a very silly problem, but im used to script with MaxScript and not the SDK.


PD. I wrote this question in area forums too, if somebody answer me there i update here if someone could have the same problem.


try this to access the modifier pblock

IParamBlock2* GetParamBlock(ReferenceMaker* obj)
 	int nRefs = obj->NumRefs();
 	for ( int i = 0; i < nRefs; ++i )
 		ReferenceTarget* ref = obj->GetReference(i);
 		if ( ref && ref->SuperClassID() == PARAMETER_BLOCK2_CLASS_ID )
 			return dynamic_cast<IParamBlock2*>( ref );
 	return NULL;

call with something like

 IParamBlock2* pb = GetParamBlock((ReferenceMaker*)modifier);


Thanks claude666!

That gives me the solution.
Looks like displace modifier doesnt have IParamBlock2* parameters because always give NULL, but i made the variant version: IParamBlock* GetParamBlock(ReferenceMaker* obj) and works perfectly.

This is my working code if anyone have the same problem.

 float strength = 0.f;
 if (node->GetObjectRef()->SuperClassID() == GEN_DERIVOB_CLASS_ID) {
 	IDerivedObject* derivedObject = (IDerivedObject*) node->GetObjectRef();
 	for(unsigned int i = 0; i < derivedObject->NumModifiers(); ++i)  {
 		Modifier* modifier = derivedObject->GetModifier(i);
 		if (modifier->ClassID() == Class_ID(DISPLACEOSM_CLASS_ID,0) ) {
 			IParamBlock2* pb2 = Util::GetParamBlock2((ReferenceMaker*)modifier);
 			IParamBlock* pb = NULL;
 			if (pb2 == NULL){
 				pb = Util::GetParamBlock((ReferenceMaker*)modifier);
 				if (pb != NULL)
 					strength = pb->GetFloat(DISPLACE_STRENGTH); 
 			else {
 				strength = pb2->GetFloat(DISPLACE_STRENGTH);  

Util is my small class for conversion and utilities functions


glad it worked, wish i could claim credit :slight_smile: but that function is hidden somewhere in the sdk documentation but I can’t remember where.


Wel, you still have my gratitude!!:thumbsup:


if you know that the property in ‘ParamBlock’ why do you search in ‘ParamBlock2’?
if you don’t know this for sure why do you not search in all 'ParamBlock2’s and all 'ParamBlock’s?


Hi denisT,
I wrote that just for check the IParamBlock2 is always NULL with Displace Modifier (but i still dont know why, SDK says IParamBlock is deprecated and all plugins should have IParamBlock2* ).

My finish code dont look for IParamBlock2, i wrote that here to explain why i look for IParamBlock instead of IParamBlock2.

Accept my apologies for not explain me very well.


probably the Displace modifier is very old…

so finally we have:

if (modifier->ClassID() == Class_ID(DISPLACEOSM_CLASS_ID,0)) 
	for ( int i = 0, numrefs = modifier->NumRefs(); i < numrefs; ++i )
		ReferenceTarget* ref = modifier->GetReference(i);
		if ( ref && ref->SuperClassID() == PARAMETER_BLOCK_CLASS_ID)
			IParamBlock *pBlock = (IParamBlock*)ref;
			float strength;
			pBlock->GetValue(DISPLACE_STRENGTH, GetCOREInterface()->GetTime(), strength, FOREVER);
			return strength;

because we know that displace modifier has one param block and it’s not paramblock2. also we have to use the GetValue if we want to get animatable value. the GetFloat returns value at frame 0 as i remember.


i was interested what modifiers use paramBlock and paramBlock2, and how many.
if anyone wants to know it too here is a list:


btw. can anyone show the right way how to get ParamBlock’s parameter name? the ParamBlock2 has GetLocalName method. for the ParamBlock i don’t see any simple solution.


This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.