[Closed] HelperObject that works in a Deform modifier
Is it possible ?
A deformable object is an object with modifiable points that flows through the pipeline. It is not a separate type, but rather is an instance of the Object type that will return TRUE to the Object::IsDeformable() method. Deformable objects must support the following Object methods: Object::NumPoints(), Object::GetPoint(), Object::SetPoint(), and Object::Deform().
Requests by the geometry pipeline for deformable objects are done using the Class_IDdefObjectClassID. Objects that are deformable should return TRUE in the method Object::CanConvertToType() when passed defObjectClassID. A deformable object should also return its this pointer from the implementation of the function Object::ConvertToType() when passed defObjectClassID.
Examples of deformable objects are LinearShape, ParticleObject, PatchObject, PolyObject, SplineShape, and TriObject. An example of a non-deformable object is the CameraObject
even with all the above implemented max still crashes if you try it with a helperObject
this seems to be a workable solution…
Tab<Point3> points;
Interval geomValid;
MyHelper(BOOL shallow = FALSE) : pblock(NULL), geomValid(FOREVER)
{
if(!shallow) //
{
MyHelperDesc.MakeAutoParamBlocks(this);
// initialize points here
SetAFlag(A_OBJ_CREATING);
}
}
BOOL IsSubClassOf(Class_ID classID) { return classID == ClassID() || classID == DEFORMABLE_HELPER_CLASS_ID; }
float GetSize() { return pblock->GetFloat(khelper_size) * 0.5f; }
int IsDeformable() { return TRUE; }
int NumPoints() { return points.Count(); }
Point3 GetPoint(int i) { return points[i] * GetSize(); }
void SetPoint(int i, const Point3& p) { points[i] = p/GetSize(); }
void Deform(Deformer *defProc, int useSel)
{
float size = GetSize();
int npts = points.Count();
for (int i = 0; i < npts; ++i)
{
Point3 pt = points[i] * size;
pt = defProc->Map(i, pt);
points[i] = pt/size;
}
}
int CanConvertToType(Class_ID objtype) { return IsSubClassOf(objtype) || objtype == defObjectClassID; }
Object* ConvertToType(TimeValue t, Class_ID objtype)
{
return (IsSubClassOf(objtype) || objtype == defObjectClassID) ? this : NULL;
}
Object *MakeShallowCopy(ChannelMask channels)
{
MyHelper* newobj = new MyHelper(TRUE);
newobj->ShallowCopy(this, channels);
return newobj;
}
void ShallowCopy(Object* fromObj, ChannelMask channels)
{
assert(fromObj->ClassID()==ClassID());
MyHelper*fobj = static_cast<MyHelper*>(fromObj);
pblock = fobj->pblock;
Object::ShallowCopy(fromObj,channels);
if(channels & GEOM_CHANNEL)
{
points = fobj->points;
geomValid = fobj->geomValid;
}
}
Interval ChannelValidity(TimeValue t, int nchan)
{
if(IsBaseClassOwnedChannel(nchan))
return Object::ChannelValidity(t,nchan);
switch(nchan)
{
case GEOM_CHAN_NUM: return geomValid; break;
default: return FOREVER;
}
}
void SetChannelValidity(int nchan, Interval v)
{
Object::SetChannelValidity(nchan,v);
switch(nchan)
{
case GEOM_CHAN_NUM: geomValid = v; break;
}
}
void InvalidateChannels(ChannelMask channels)
{
Object::InvalidateChannels(channels);
if (channels & GEOM_CHANNEL) geomValid.SetEmpty();
}