#include "testNobjectNode.h"
#include <maya/MIOStream.h>
#include <maya/MPlug.h>
#include <maya/MDataBlock.h>
#include <maya/MDataHandle.h>
#include <maya/MGlobal.h>
#include <maya/MTime.h>
#include <maya/MFnMesh.h>
#include <maya/MFnMeshData.h>
#include <maya/MFnUnitAttribute.h>
#include <maya/MFnNumericAttribute.h>
#include <maya/MFnTypedAttribute.h>
#include <maya/MFnIntArrayData.h>
#include <maya/MFnComponentListData.h>
#include <maya/MFnSingleIndexedComponent.h>
#include <maya/MDagPath.h>
#include <maya/MPoint.h>
#include <maya/MFloatPointArray.h>
#include <maya/MItMeshVertex.h>
#include <maya/MFnPlugin.h>
#include <maya/MFnNObjectData.h>
#include "stdio.h"
const MTypeId testNobjectNode::id( 0x85003 );
MObject testNobjectNode::startState;
MObject testNobjectNode::currentState;
MObject testNobjectNode::currentTime;
MObject testNobjectNode::nextState;
MObject testNobjectNode::inputGeom;
MObject testNobjectNode::outputGeom;
inline void statCheck( MStatus stat, MString msg )
{
if ( !stat )
{
cout<<msg<<"\n";
}
}
testNobjectNode::testNobjectNode()
{
fNObject.createNCloth();
}
MStatus testNobjectNode::compute(const MPlug &plug, MDataBlock &data)
{
MStatus stat;
if ( plug == outputGeom )
{
MObject inMeshObj = data.inputValue(inputGeom).asMesh();
cerr<<"pull on outputGeom\n";
MFnMeshData meshDataFn;
MFnMesh inputMesh(inMeshObj);
MObject newMeshObj = meshDataFn.create();
MFnMesh newMeshFn;
newMeshFn.copy( inMeshObj, newMeshObj );
data.inputValue(currentTime).asTime();
MObject nextNObj = data.inputValue(nextState).data();
MFloatPointArray pts;
fNObject.getPositions(pts);
if(pts.length() == (unsigned int) inputMesh.numVertices()) {
newMeshFn.setPoints(pts);
}
newMeshFn.setObject( newMeshObj );
data.outputValue(outputGeom).set(newMeshObj);
data.setClean(plug);
}
if ( plug == currentState )
{
MFnNObjectData outputData;
MObject mayaNObjectData = outputData.create();
outputData.setObject(mayaNObjectData);
outputData.setObjectPtr(&fNObject);
outputData.setCached(false);
MDataHandle currStateOutputHandle = data.outputValue(currentState);
currStateOutputHandle.set(outputData.object());
cerr<<"pull on currentState\n";
}
if ( plug == startState )
{
int ii,jj;
MObject inMeshObj = data.inputValue(inputGeom).asMesh();
MFnMesh inputMesh(inMeshObj);
int numPolygons = inputMesh.numPolygons();
int * faceVertCounts = new int[numPolygons];
int facesArrayLength = 0;
for(ii=0;ii<numPolygons;ii++) {
MIntArray verts;
inputMesh.getPolygonVertices(ii,verts);
faceVertCounts[ii] = verts.length();
facesArrayLength += verts.length();
}
int * faces = new int[facesArrayLength];
int currIndex = 0;
for(ii=0;ii<numPolygons;ii++) {
MIntArray verts;
inputMesh.getPolygonVertices(ii,verts);
for(jj=0;jj<(int)verts.length();jj++) {
faces[currIndex++] = verts[jj];
}
}
int numEdges = inputMesh.numEdges();
int * edges = new int[2*numEdges];
currIndex = 0;
for(ii=0;ii<numEdges;ii++) {
int2 edge;
inputMesh.getEdgeVertices(ii,edge);
edges[currIndex++] = edge[0];
edges[currIndex++] = edge[1];
}
fNObject.setTopology(numPolygons, faceVertCounts, faces,numEdges, edges );
delete[] faceVertCounts;
delete[] faces;
delete[] edges;
unsigned int numVerts = 0;
numVerts = inputMesh.numVertices();
MFloatPointArray vertexArray;
inputMesh.getPoints(vertexArray);
fNObject.setPositions(vertexArray,true);
MFloatPointArray velocitiesArray;
velocitiesArray.setLength(numVerts);
for(ii=0;ii<(int)numVerts;ii++) {
velocitiesArray[ii].x = 0.0f;
velocitiesArray[ii].y = 0.0f;
velocitiesArray[ii].z = 0.0f;
velocitiesArray[ii].w = 0.0f;
}
fNObject.setVelocities(velocitiesArray);
fNObject.setThickness(0.05f);
fNObject.setInverseMass(1.0f);
fNObject.setBounce(0.0f);
fNObject.setFriction(0.1f);
fNObject.setDamping(0.0f);
fNObject.setBendResistance(0.0f);
fNObject.setMaxIterations(100);
fNObject.setMaxSelfCollisionIterations(100);
fNObject.setStretchAndCompressionResistance(20.0f,10.0f);
fNObject.setSelfCollisionFlags(false);
fNObject.setCollisionFlags(true);
MFnNObjectData outputData;
MObject mayaNObjectData = outputData.create();
outputData.setObject(mayaNObjectData);
outputData.setObjectPtr(&fNObject);
outputData.setCached(false);
MDataHandle startStateOutputHandle = data.outputValue(startState);
startStateOutputHandle.set(outputData.object());
cerr<<"pull on startState\n";
}
else {
stat = MS::kUnknownParameter;
}
return stat;
}
MStatus testNobjectNode::initialize()
{
MStatus stat;
MFnTypedAttribute tAttr;
nextState = tAttr.create("nextState", "nxs", MFnData::kNObject, MObject::kNullObj, &stat );
statCheck(stat, "failed to create nextState");
tAttr.setWritable(true);
tAttr.setStorable(true);
tAttr.setHidden(true);
inputGeom = tAttr.create("inputGeom", "ing", MFnData::kMesh, MObject::kNullObj, &stat );
statCheck(stat, "failed to create inputGeom");
tAttr.setWritable(true);
tAttr.setStorable(true);
tAttr.setHidden(true);
currentState = tAttr.create("currentState", "cus", MFnData::kNObject, MObject::kNullObj, &stat );
statCheck(stat, "failed to create currentState");
tAttr.setWritable(true);
tAttr.setStorable(false);
tAttr.setHidden(true);
startState = tAttr.create( "startState", "sts", MFnData::kNObject, MObject::kNullObj, &stat );
statCheck(stat, "failed to create startState");
tAttr.setWritable(true);
tAttr.setStorable(false);
tAttr.setHidden(true);
outputGeom = tAttr.create("outputGeom", "outg", MFnData::kMesh, MObject::kNullObj, &stat );
statCheck(stat, "failed to create outputGeom");
tAttr.setWritable(true);
tAttr.setStorable(false);
tAttr.setHidden(true);
MFnUnitAttribute uniAttr;
currentTime = uniAttr.create( "currentTime", "ctm" , MFnUnitAttribute::kTime, 0.0, &stat );
addAttribute(inputGeom);
addAttribute(outputGeom);
addAttribute(currentTime);
addAttribute(startState);
addAttribute(currentState);
addAttribute(nextState);
attributeAffects(inputGeom, outputGeom);
attributeAffects(nextState, outputGeom);
attributeAffects(inputGeom, startState);
attributeAffects(currentTime, outputGeom);
attributeAffects(currentTime, currentState);
attributeAffects(currentTime, startState);
return MStatus::kSuccess;
}
MStatus initializePlugin ( MObject obj )
{
MStatus status;
MFnPlugin plugin(obj, "Autodesk - nCloth Prototype 5", "8.5", "Any");
status = plugin.registerNode ( "testNobjectNode", testNobjectNode::id,testNobjectNode ::creator, testNobjectNode::initialize );
if ( !status )
{
status.perror("registerNode");
return status;
}
return status;
}
MStatus uninitializePlugin ( MObject obj )
{
MStatus status;
MFnPlugin plugin(obj);
status = plugin.deregisterNode(testNobjectNode::id);
if ( !status )
{
status.perror("deregisterNode");
return status;
}
return status;
}