A simple modifier is a special case of a geometry modifier. Simple modifiers can derive from SimpleMod2 instead of Modifier and will have fewer methods to implement. The Bend modifier example is derived from SimpleMod2.
To be a 'simple' modifier, the following assumptions are made:
Simple Modifiers don't directly implement Modifier::ModifyObject() instead they implement the method SimpleMod::GetDeformer(). This method returns a callback object which is an instance of the Deformer class. The Deformer class provides a virtual method Deformer::Map() that performs the alteration of a single point of an object. To see an example of an implementation of this method see \MAXSDK\SAMPLES\MODIFIERS\BEND.CPP.
The base class SimpleMod provides the following default implementations for Modifier::InputType(), Modifier::ChannelsUsed() and Modifier::ChannelsChanged():
Class_ID InputType() { return defObjectClassID; } ChannelMask ChannelsUsed() { return PART_GEOM|PART_TOPO|SELECT_CHANNEL|SUBSEL_TYPE_CHANNEL; } ChannelMask ChannelsChanged() { return PART_GEOM; }
Note that Modifier::InputType() return the Class_ID of deformable objects. As noted above, these are a type of objects that have 'points' to deform. Also notice that simple modifiers require the geometry, topology, and selection channels. They need the topology channel up to date because these modifiers can work on a selection set.
In this case a modifier needs to find the vertices that are selected because they are part of selected faces. To make sure the face selection is up to date the topology channel is specified. The selection channels are required for the same reason -- the modifier may operate on only the selection set if that's what the object is providing in the pipeline.
The base class SimpleMod also provides an implementation of ModifyObject() that calls Object::Deform() method on the input object. The object in turn calls Deformer::Map() on all points. Here is the implementation of SimpleMod::ModifyObject():
void SimpleMod::ModifyObject(TimeValue t, ModContext &mc, ObjectState *os, INode *node) { Interval valid = GetValidity(t); Matrix3 modmat,minv; // These are inverted because that's what is usually needed // for displaying/hit testing minv = CompMatrix(t,mc,idTM,valid,TRUE); modmat = Inverse(minv); os->obj->Deform(&GetDeformer(t,mc,modmat, minv), TRUE); os->obj->UpdateValidity(GEOM_CHAN_NUM,valid); }
Here is the default implementation of Object::Deform():
void Object::Deform(Deformer *defProc,int useSel) { int nv = NumPoints(); for (int i=0; i<nv; i++) SetPoint(i,defProc->Map(i,GetPoint(i))); PointsWereChanged(); }
The method Object::PointsWereChanged() is called to let that object know that its points have been altered.
Some objects override the base class definition of Object::Deform() to provide other ways of modifying the object, such as the PatchObject and SplineShape objects. If an object only wants to modify selected points only for example, it would need to override Object::Deform() and observe the useSel parameter that indicates it should use the current selection. The default method ignores the useSel parameter.