Whole Object Modifiers
 
 
 

Whole object modifiers that don't alter any parts of the object, instead they completely replace an object with a new object. Examples of this are the Extrude and Lathe modifiers. Both Extrude and Lathe convert a spline object into a mesh, patch or NURBS object, completely replacing the entire object. The full source code for Extrude is available in \MAXSDK\SAMPLES\MODIFIERS\EXTRUDE.CPP.

Below are the implementations of Modifier::InputType(), Modifier::ChannelsUsed(), and Modifier::ChannelsChanged().

Class_ID InputType() {
  returngenericShapeClassID;
}
 
ChannelMask ChannelsUsed() {
  returnPART_GEOM|PART_TOPO;
}
 
ChannelMask ChannelsChanged() {
  returnPART_ALL;
}

Note that the modifier indicates it changes all the channels by returning PART_ALL from Modifier::ChannelsChanged().

Below is a subset of the implementation of Modifier::ModifyObject() for the Extrude modifier with the code for the NURBS and Patch cases are removed for brevity and simplicity. In the mesh case, the key thing to notice is that a new TriObject is created, the TriObject's mesh is created from the spline, and the new object is placed into the pipeline by assigning its pointer to the ObjectState's object pointer.

void ExtrudeMod::ModifyObject(TimeValue t, ModContext &mc,
              ObjectState *os, INode *node)
{ 
   // Get our personal validity interval...
   Interval valid = GetValidity(t);
   valid &= os->obj->ChannelValidity(t,TOPO_CHAN_NUM);
   valid &= os->obj->ChannelValidity(t,GEOM_CHAN_NUM);
 
   intoutput;
   pblock->GetValue(PB_OUTPUT, TimeValue(0), output, FOREVER);
   switch (output)
   {
     case NURBS_OUTPUT:
     {
      // ...
      break;
     }
     case PATCH_OUTPUT:
     {
      // ...
      break;
     }
     case MESH_OUTPUT:
     {
      // BuildMeshFromShape fills in the TriObject's mesh,
      // then we stuff the TriObj into the pipeline.
       TriObject *tri = CreateNewTriObject();
      BuildMeshFromShape(t, mc, os, tri->mesh);
      tri->SetChannelValidity(TOPO_CHAN_NUM, valid);
      tri->SetChannelValidity(GEOM_CHAN_NUM, valid);
      tri->SetChannelValidity(TEXMAP_CHAN_NUM, valid);
      tri->SetChannelValidity(MTL_CHAN_NUM, valid);
      tri->SetChannelValidity(SELECT_CHAN_NUM, valid);
      tri->SetChannelValidity(SUBSEL_TYPE_CHAN_NUM, valid);
      tri->SetChannelValidity(DISP_ATTRIB_CHAN_NUM, valid);
      os->obj = tri;
      break;
     }
   }
   os->obj->UnlockObject();
}