[Solved] 3dsmax sdk modifier problems..


#1

I’m working on a modifier written in c++, I have hit a snag I cannot figure out, all though I have an idea on what is going on.
The modifier is created with the 3dsmax sdk wizard, and everything in it works the way I want except for what I explain below…

It’s a simple modifier with variables in it, it does not edit the object \ mesh in any way, it’s purely to hold data for a exporter.

The problem I’m having now, is that my exporter (also written in c++) cannot ‘see’ the modifier in the stack, all tough I put it there.
But I can see it with maxscript. When looping over my nodes - and their modifiers It just does not see it, as if the modifier does not become ‘valid’.

The only way to get the modifier to be found is to convert my objects to editable poly \edit mesh, then apply the modifier again after that is done.
Also - when for example I create a sphere, apply the modifier on this primitive shape - deselect the sphere, and select it again in modify mode - the ‘trash’ icon is disabled,
I then have to click on my modifier in the stack to activate the trash icon and then I can delete my modifier with it,
if I do the same after converting the object to mesh\poly then applying the modifier - then the trash icon works as expected.
So I feel there is something stupid I’m missing here, some flag or something that causes it not to ‘apply’ the modifier unless object is converted to poly\mesh first - even though the modifier is visible in the stack…

Have anyone of you seen this issue before?
Any help with this would be greatly appreciated, I’ve tried everything I can think of - without success.

Edit:
The way I see it - there is 2 possibilities, one being that the modifier is doing something unexpected, or the loop where I go through the modifiers is wrong.

I loop like this, and nummodifiers returns 0 when the modifier is applied to a sphere\box etc that are not converted to edit poly first.


Object *pObj = currNode->GetObjectRef();       
IDerivedObject *pDerObj;
Modifier *Mod;
pDerObj = static_cast<IDerivedObject *> (pObj);
#define MYMODIFIER_CLASSID Class_ID(1873130787, 1554990649)

for (int i = 0; i < pDerObj->NumModifiers(); i++)
{
    Mod = pDerObj->GetModifier(i);
    if (Mod->ClassID() ==MYMODIFIER_CLASSID)
    {
        mprintf(L"found  modifier on object: ");
        mprintf(currNode->GetName());
        mprintf(L"
");
    }
}


#2

show the modifier’s code… all problems are in the header …


#3

edit:
removed code, the modifier was not the issue, it was the way I looped through nodes\modifiers, see below for answer.


#4

what version of max is it for?

for max 2014+ all TSTR must be MSTR… that’s why your plugin is not visible

check:
class definition …
GetObjectName()
GetClassName

ClassDesc …
ClassName
InternalName
Category


#5

btw… you don’t need to override most of virtual methods as you do it


#6

why do you use XTCObject? it looks as too much for things you tells above (hold data for a exporter)


#7

all TSTR must be MSTR that’s why your plugin is not visible
it is visible in the stack, visible in the modifier list, but when I loop through objects in c++ before collapsing the object its not ‘seen’ in c++, but it is in the stack, and I can find it through maxscript.
it’s visible in stack and through maxscript by for example - $.modifiers[1], but not through c++ during export, the nummodifiers returns as 0, unless the object is collapsed to edit mesh\poly then has the modifier applied.
This is why I also mentioned that it might be the loop where I loop through objects\modifiers in c++ that is causing it to ‘miss’ it.

The plugin wizard made this (max 2018).
And everything works fine if i collapse the object and then apply the modifier.
So I have a feeling it’s something else causing this.

you don’t need to override most of virtual methods as you do it
all overrides are there because the plugin wizard made them.

why do you use XTCObject? it looks as too much for things you tells above (hold data for a exporter)
same as above - plugin wizard set this up this way.

I’ll try more when I get home from work later today.


#8

So, I’ve been poking around some more tonight.
Now I have also created a new modifier from scratch with the wizard, but this time I made it inherit from simplemod2,
but that gave the same problem.

Then I decided to see if I could find other modifiers applied on my objects, they behave in the same way, so to me now it seems as if it’s not the modifier.
It’s either the way I loop through modifiers, or something I’m missing.

So, what I did now was to add bend modifier on my sphere primitives, export, then pass the node through this function:


#define BEND_CLASSID Class_ID(16, 0)

void findBendModifier(INode* node) {
    if (!node)return;

    Object *obj = node->GetObjOrWSMRef();
    IDerivedObject *D_obj = NULL;

    if (obj->SuperClassID() == GEN_DERIVOB_CLASS_ID) {
        D_obj = static_cast<IDerivedObject *> (obj);
    }
    else 
    {
        D_obj = CreateDerivedObject();
        D_obj->TransferReferences(obj);
        D_obj->ReferenceObject(obj);
    }
    const int NumMods = D_obj->NumModifiers();   
    mprintf(L"Object name: %s num modifiers = %i
", node->GetName(), NumMods );

    for (int i = 0; i < NumMods; i++) 
    {
        if (D_obj->GetModifier(i)->ClassID() == BEND_CLASSID)
        {
            mprintf(L"We found BEND modifier at node: %s index: %i
", node->GetName(), i);
        }
    }
}

It then behaves the exact same way,
if the sphere is not converted (staying as a primitive shape) and has the bend modifier applied - it does not find the modifier (nummodifiers returns 0 all though it’s in the stack).

For example, a geosphere with bend applied returns:


"Object name: GeoSphere002 num modifiers = 0"

collapse the geosphere to editable poly, then reapply the bend modifier it returns:


"Object name: GeoSphere002 num modifiers = 1"
"found BEND modifier at node: GeoSphere002 index: 0"


#9

bool StackBoss::FindStackBossModifier (INode* node)
{
// Get object from node. Abort if no object.
Object* pObj = node->GetObjectRef();

if (!pObj) return false;

// Is derived object ?
while (pObj->SuperClassID() == GEN_DERIVOB_CLASS_ID)
{
IDerivedObject* pDerObj = (IDerivedObject*) pObj;

  // Iterate over all entries of the modifier stack.
  int Idx = 0;
  while (Idx &lt; pDerObj-&gt;NumModifiers())
  {
     // Get current modifier.
     Modifier* mod = pDerObj-&gt;GetModifier(Idx);

     // Is this Skin ?
     if (mod-&gt;ClassID() == STACKBOSSMOD_CLASS_ID)
     {
        // Yes -&gt; Exit.
        return true;
     }

     // Next modifier stack entry.
     Idx++;
  }
  pObj = pDerObj-&gt;GetObjRef();

}

// Not found.
return false;
}


NEW LOOK of this site. Do you like it?
#10

Klvnk , thank you so much, that finally worked!