PDA

View Full Version : Building the FFD modifier from scratch.


reForm
12-11-2008, 12:17 AM
I'm trying to learn some more in maxscript, and the thing I'm trying to do involves effectively coding a FFD box type behaviour.

I've got as far as getting all the control point positions, and the vertex positions normalised to the bounding box of the FFDBox, but I can't work out the math to reposition the vertices based on the new positions of the FFDBox control point positions.

I've been translating some c++ code I came across into maxscript, and I've almost got it working. The problem comes when using one of the libraries to translate the vertice positions based on the control points.
Here's the include code


namespace Wm4
{

template <class Real>
class WM4_FOUNDATION_ITEM BSplineVolume
{
public:
// Construction and destruction of an open uniform B-spline volume. The
// class will allocate space for the control points. The caller is
// responsible for setting the values with the member function
// ControlPoint.

BSplineVolume (int iNumUCtrlPoints, int iNumVCtrlPoints,
int iNumWCtrlPoints, int iUDegree, int iVDegree, int iWDegree);

~BSplineVolume ();

int GetNumCtrlPoints (int iDim) const;
int GetDegree (int iDim) const;

// Control points may be changed at any time. If any input index is
// invalid, the returned point is a vector whose components are all
// MAX_REAL.
void SetControlPoint (int iUIndex, int iVIndex, int iWIndex,
const Vector3<Real>& rkCtrlPoint);
Vector3<Real> GetControlPoint (int iUIndex, int iVIndex, int iWIndex)
const;

// The spline is defined for 0 <= u <= 1, 0 <= v <= 1, and 0 <= w <= 1.
// The input values should be in this domain. Any inputs smaller than 0
// are clamped to 0. Any inputs larger than 1 are clamped to 1.
Vector3<Real> GetPosition (Real fU, Real fV, Real fW) const;
Vector3<Real> GetDerivativeU (Real fU, Real fV, Real fW) const;
Vector3<Real> GetDerivativeV (Real fU, Real fV, Real fW) const;
Vector3<Real> GetDerivativeW (Real fU, Real fV, Real fW) const;

// for array indexing: i = 0 for u, i = 1 for v, i = 2 for w
Vector3<Real> GetPosition (Real afP[3]) const;
Vector3<Real> GetDerivative (int i, Real afP[3]) const;

private:
Vector3<Real>*** m_aaakCtrlPoint; // ctrl[unum][vnum][wnum]
BSplineBasis<Real> m_akBasis[3];
};

typedef BSplineVolume<float> BSplineVolumef;
typedef BSplineVolume<double> BSplineVolumed;

}

#endif

Is it possible to 'translate' this c++ code into some kind of workable maxscript?
It looks like you can get or set the vertice positions based on where the control points have been moved to. Perhaps there is some further underlying code using bspline curves to actually do the calculation of where the vert should be...

I dunno... I think I'm stumped!
Any C++ wizards that can point me on the right track?

eek
12-11-2008, 04:38 AM
Well basically your associating a weight with a vertex of a control mesh based on its distances. So you need to sum the vertices into a normalized weight space - similiar to how you have weighted curves.

I wouldnt do this in max script it would become super heavy - maxscript/controllers are great for math and transforms but not so hot in affecting verts on the fly. Maybe pFlow?

Or use skin wrap and wrap your object to an arbitary mesh, it doesnt have to be skinned.

reForm
12-11-2008, 09:29 AM
Hi Eek, thanks for your suggestions.
The thing I'm trying to make is a simpleobject plugin and I thought with this type of script, using modifiers to create your trimesh was a big no-no. It should be better to build the mesh directly with code.

I have the basics working using a standard FFD box modifier, but the modifier panel seems to be getting refreshed as I move the the ffd control points around causing a serious hit in performance. I thought that if I was able to rebuild the math of the FFD in maxscript I would be able to have live updates of the simple-object mesh without the modifier panel trying to refresh whenever a parameter is changed.
Basically i have an "on build mesh" which then recalculates the FFD control positions and rebuilds the mesh based on the new ffd control positions. At the moment this doesnt work well because the code to re-evaluate the ffd control positions causes the modifier panel to refresh.

If this fails, then I'll have to give up on live updates and simply have a button to initiate the creation of the mesh; a bit like having updates constant, on demand, or only at render.

Are there any efficiency workflows that I'm not aware of that would speed up using modifiers to create the mesh in a scripted simple-object plugin?

reForm
12-11-2008, 10:44 AM
Ahar, I fixed the modifier slowdown problem by changing to max create mode (must read manual more often!)... and its a big improvement.... still, no-where near realtime.

CGTalk Moderation
12-11-2008, 10:44 AM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.