Free-Form-Deformation (Lattice) Data [MEL]

 

 

 

The FFD (Free-Form-Deformation) deformer node takes a Base lattice shape, a Deformed lattice shape and the original surface shape as an input. The FFD then tweaks the input geometry into the final output shape.

 

 

 

 

Enabling / Disabling Lattices

 

One initial issue that you must consider if you wish to export lattices is that you should disable the effect of the lattice deformers before reading the geometry data. The reason is to ensure that we export the un-deformed surfaces rather than after a lattice deformation has been applied.

 

 

All lattice deformers in maya have an envelope (en) attribute. This attribute can be set to 0 to disable the actual effect. Therefore, before we export, we can disable all of the lattices, and then re-enable them after exporting the data.

 

 

 

 

 

 

 

 

 


#include<maya/MFnLatticeDeformer.h>
#include<maya/MItDependencyNodes.h>
#include<maya/MPlug.h>

void DisableFFDs()
{
 

MItDependencyNodes it(MFn::kFFD);
while( !it.isDone() )
{

 

MFnLatticeDeformer fn(it.item());

// get the envelope attribute plug
MPlug plug = fn.findPlug("en");

// set to 0 to disable FFD effect
plug.setValue(0.0f);

it.next();

}

}

void EnableFFDs()
{
 

MItDependencyNodes it(MFn::kFFD);
while( !it.isDone() )
{

 

MFnLatticeDeformer fn(it.item());

// get the envelope attribute plug
MPlug plug = fn.findPlug("en");

// set to 1 to enable FFD effect
plug.setValue(1.0f);

it.next();

}

}




 

Outputting Lattice Deformer (FFD) Information

A lattice deformer is composed of three nodes:

  • MFn::kFFD - the actual deformer node itself.
  • MFn::kBaseLattice - a box that describes the initial orientation of the lattice before any deformation has been applied to the surface.
  • MFn::kLattice - This is the deformed lattice shape.

 

The main information we want from the MFn::kFFD node is a list of objects that this deformer affects. We can also use it to get information about the deformed and base lattices.

 

 

 

 

 


#include<maya/MFnLatticeDeformer.h>
#include<maya/MFnDependencyNode.h>
#include<maya/MItDependencyNodes.h>
#include<maya/MObjectArray.h>

void OutputFFDs()
{
 

// iterate through all lattice deformers
MItDependencyNodes
it(MFn::kFFD);
while( !it.isDone() )
{
 

// attach a lattice deformer function set
MFnLatticeDeformer
fn(it.item());
MObjectArray Affected;

// get an array of objects affected by this
// lattice deformer

fn.getAffectedGeometry(Affected);

// output each affected geometry
for
(int i=0;i<Affected.length();++i)
{

  MFnDependencyNode fnDep(Affected[i]);
cout << fnDep.name().asChar() << endl;

}

// explained below
OutputBaseLattice(fn.baseLattice());
OutputLattice(fn.deformLattice());

it.next();

}

}

 

 

The Base Lattice

When we access the base lattice shape, there is really very little to get back from the node itself since it's size and orientation is defined by it's parent transform. The parent transform is therefore all we need to access.

 

 


#include<maya/MFnDagNode.h>

void OutputBaseLattice(MObject& obj)
{
 

MFnDagNode fn(obj);
MFnDagNode fnParent(fn.parent(0));

cout << "baseLattice "
<< fn.name().asChar()
<< "\nparent "
<< fnParent.name().asChar()
<< endl;

}




 

The Deformed Lattice

The deformed lattice is simply a 3D grid of points. The number of points is determined by the number of divisions on the lattice.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

#include<maya/MFnDagNode.h>
#include<maya/MFnLattice.h>


void OutputLattice(MObject& obj)
{
  // attach a lattice function set to the object
MFnLattice fn(obj);
// ignore intermediate objects
if ( !fn.isIntermediateObject() )
{
  MFnDagNode fnParent( fn.parent(0) ) ;
fn.name().asChar();

unsigned int s,t,u;
fn.getDivisions(s,t,u);
cout << "Lattice "
<< fn.
name().asChar()
<<
"\n\tparent "
<< fnParent.
name().asChar()
<<
"\n\tdivisionsS" << s
<<
"\n\tdivisionsT" << t
<<
"\n\tdivisionsU" << u
<<
"\n\tpoints\n";

for (int i=0;i<s;++i)
{
  for (int j=0;j<t;++j)
{
  for (int k=0;k<s;++k)
{
  MPoint p = fn.point(i,j,k);
cout << "\t\t" << p.x
<<
" " << p.y
<<
" " << p.z
<<
endl;
}

}

}

}

}


 

 

What Next?

Transformation Data

Polygonal Mesh Data


Nurbs Surface Data


Blend Shape Deformers

Rigid Skinned Surfaces

Soft Skinned Surfaces

index

Rob Bateman [2004]

[HOME] [MEL] [API]