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:
Deformer
to do the modification.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.