#include <math.h>
#include <maya/MIOStream.h>
#include "apiMeshShape.h"
#include "apiMeshShapeUI.h"
#include "apiMeshGeometryOverride.h"
#include "apiMeshSubSceneOverride.h"
#include "apiMeshCreator.h"
#include "apiMeshData.h"
#include "api_macros.h"
#include <maya/MFnDependencyNode.h>
#include <maya/MFnPlugin.h>
#include <maya/MFnPluginData.h>
#include <maya/MDrawRegistry.h>
#include <maya/MMatrix.h>
#include <maya/MAttributeSpecArray.h>
#include <maya/MAttributeSpec.h>
#include <maya/MAttributeIndex.h>
#include <maya/MObjectArray.h>
#include <maya/MFnSingleIndexedComponent.h>
#include <maya/MDagPath.h>
#include <maya/MFnAttribute.h>
#include <maya/MFnNumericAttribute.h>
#include <maya/MFnTypedAttribute.h>
#include <maya/MPointArray.h>
#include <maya/MViewport2Renderer.h>
#include <maya/MPlane.h>
#include <maya/MArrayDataBuilder.h>
#include <maya/MEvaluationNode.h>
namespace
{
bool debug = false;
const char* sPlugConnection = "->-";
void *clientData)
{
apiMesh *pMesh = static_cast<apiMesh *>(clientData);
{
pMesh->setMaterialDirty(true);
}
}
}
MObject apiMesh::useWeightedTransformUsingFunction;
MObject apiMesh::useWeightedTweakUsingFunction;
MObject apiMesh::enableNumericDisplay;
apiMesh::apiMesh() {}
apiMesh::~apiMesh()
{
for(std::map<std::string, MCallbackId>::const_iterator i = fMaterialDirtyCbIds.begin();
i != fMaterialDirtyCbIds.end(); i++)
{
}
}
void apiMesh::postConstructor()
{
setRenderable( true );
fHasHistoryOnCreate = false;
fShapeDirty = true;
fMaterialDirty = true;
}
{
if (debug)
cerr <<
"apiMesh::compute : plug " << plug.
info() << endl;
if ( plug == outputSurface ) {
return computeOutputSurface( plug, datablock );
}
else if ( plug == cachedSurface ) {
return computeOutputSurface( plug, datablock );
}
else if ( plug == worldSurface ) {
return computeWorldSurface( plug, datablock );
}
else {
return MS::kUnknownParameter;
}
}
{
{
)
{
setShapeDirty();
}
}
}
{
if (context.
isNormal() && evalType != kLeaveDirty)
{
)
{
notifyViewport();
}
}
}
{
if ( plug == inputSurface ||
plug == mControlPoints ||
plug == mControlValueX ||
plug == mControlValueY ||
plug == mControlValueZ ||
plug == enableNumericDisplay )
{
signalDirtyToViewport();
}
return MS::kSuccess;
}
{
bool isOk = true;
if( (plug == mControlPoints) ||
(plug == mControlValueX) ||
(plug == mControlValueY) ||
(plug == mControlValueZ) )
{
if ( hasHistory() ) {
}
else {
double val = 0.0;
if (!status) {
datablock = forceCache();
}
if ( (plug == mControlPoints) && !plug.
isArray() ) {
value( datablock, index, pnt );
result.
set( pnt[0], pnt[1], pnt[2] );
}
else if ( plug == mControlValueX ) {
value( datablock, index, 0, val );
}
else if ( plug == mControlValueY ) {
value( datablock, index, 1, val );
}
else if ( plug == mControlValueZ ) {
value( datablock, index, 2, val );
}
}
}
else if ( plug == mHasHistoryOnCreate ) {
result.
set( fHasHistoryOnCreate );
}
else {
}
return isOk;
}
{
bool isOk = true;
if (!status) {
datablock = forceCache();
}
if( (plug == mControlPoints) ||
(plug == mControlValueX) ||
(plug == mControlValueY) ||
(plug == mControlValueZ) )
{
if ( hasHistory() ) {
{
verticesUpdated();
}
}
else {
if( plug == mControlPoints && !plug.
isArray()) {
setValue( datablock, index, point );
}
else if( plug == mControlValueX ) {
setValue( datablock, index, 0, handle.
asDouble() );
}
else if( plug == mControlValueY ) {
setValue( datablock, index, 1, handle.
asDouble() );
}
else if( plug == mControlValueZ ) {
setValue( datablock, index, 2, handle.
asDouble() );
}
}
}
else if ( plug == mHasHistoryOnCreate ) {
{
fHasHistoryOnCreate = handle.
asBool();
}
else
{
return false;
}
}
else {
}
return isOk;
}
bool asSrc )
{
if ( plug == inputSurface )
{
MPlug historyPlug( thisObj, mHasHistoryOnCreate );
stat = historyPlug.setValue( true );
MCHECKERROR( stat, "connectionMade: setValue(mHasHistoryOnCreate)" );
}
else if ( asSrc )
{
{
setMaterialDirty(true);
otherNode, MaterialDirtyCb, this, &stat);
if (stat)
{
k += sPlugConnection;
#ifdef _DEBUG
cout << "apiMesh::connectionMade: " << k << endl;
#endif
fMaterialDirtyCbIds[k] = cbId;
}
}
}
}
bool asSrc )
{
if ( plug == inputSurface )
{
MPlug historyPlug( thisObj, mHasHistoryOnCreate );
stat = historyPlug.setValue( false );
MCHECKERROR( stat, "connectionBroken: setValue(mHasHistoryOnCreate)" );
}
{
setMaterialDirty(true);
k += sPlugConnection;
#ifdef _DEBUG
cout << "apiMesh::connectionBroken: " << k << endl;
#endif
if (fMaterialDirtyCbIds.find(k) != fMaterialDirtyCbIds.end())
{
fMaterialDirtyCbIds.erase(k);
}
}
}
MStatus apiMesh::shouldSave(
const MPlug& plug,
bool& result )
{
if( plug == mControlPoints || plug == mControlValueX ||
plug == mControlValueY || plug == mControlValueZ )
{
if( hasHistory() ) {
}
else {
result = false;
}
}
else if ( plug == cachedSurface ) {
if ( hasHistory() ) {
result = false;
}
else {
MCHECKERROR( status, "shouldSave: MPlug::getValue" );
}
}
else {
}
return status;
}
void apiMesh::componentToPlugs(
MObject & component,
{
apiMesh* nonConstPtr = (apiMesh*)this;
MObject vtxComp = nonConstPtr->convertToVertexComponent(component);
MPlug plug( thisNode, mControlPoints );
convertToTweakNodePlug(plug);
int len = fnVtxComp.elementCount();
for ( int i = 0; i < len; i++ )
{
list.add(plug);
}
}
}
{
if ( (1 == spec.
length()) && (dim > 0) && ((name ==
"vtx") || (name ==
"f")) ) {
int numComp;
if (name == "f") {
numComp = meshGeomToUse()->faceCount;
}
else {
numComp = meshGeomToUse()->vertices.length();
}
int upper = 0;
int lower = 0;
}
}
if ( (lower > upper) || (upper >= numComp) ) {
}
else {
for ( int i=lower; i<=upper; i++ )
{
}
list.
add( path, objComp );
}
}
else {
}
return result;
}
{
bool result = false;
if( componentList.length() == 0 ) {
}
else {
for ( int i=0; i<(int)componentList.length(); i++ ) {
) {
result = true;
break;
}
}
}
return result;
}
{
}
{
return retVal;
}
MObject apiMesh::createFullVertexGroup() const
{
int numVertices = ((apiMesh*)this)->meshGeomToUse()->vertices.length();
return fullComponent;
}
MObject apiMesh::localShapeInAttr() const
{
return inputSurface;
}
MObject apiMesh::localShapeOutAttr() const
{
return outputSurface;
}
MObject apiMesh::worldShapeOutAttr() const
{
return worldSurface;
}
MObject apiMesh::cachedShapeAttr() const
{
return cachedSurface;
}
MObject apiMesh::geometryData() const
{
apiMesh* nonConstThis = (apiMesh*)this;
MDataBlock datablock = nonConstThis->forceCache();
}
void apiMesh:: closestPoint (
const MPoint & toThisPoint, \
MPoint & theClosestPoint,
double tolerance )
const
{
apiMeshGeom* geomPtr = ((apiMesh*)this)->meshGeomToUse();
int numVertices = geomPtr->vertices.length();
for (int ii=0; ii<numVertices; ii++)
{
MPoint tryThisOne = geomPtr->vertices[ii];
}
theClosestPoint = geomPtr->vertices[0];
}
void apiMesh::transformUsing(
const MMatrix & mat,
{
transformUsing( mat,
componentList,
NULL);
}
void apiMesh::transformUsing(
const MMatrix & mat,
MVertexCachingMode cachingMode,
{
apiMeshGeom* geomPtr = meshGeomToUse();
unsigned int i=0,j=0;
unsigned int len = componentList.
length();
if ( restorePoints ) {
unsigned int cacheLen = pointCache->
length();
if (len > 0) {
for ( i = 0; i < len && j < cacheLen; i++ )
{
MObject comp = convertToVertexComponent(componentList[i]);
for ( int idx=0; idx<elemCount && j < cacheLen; idx++, ++j ) {
int elemIndex = fnComp.
element( idx );
geomPtr->vertices[elemIndex] = (*pointCache)[j];
}
}
} else {
len = geomPtr->vertices.length();
for ( unsigned int idx = 0; idx < len && j < cacheLen; ++idx, ++j ) {
geomPtr->vertices[idx] = (*pointCache)[j];
}
}
} else {
if (len > 0) {
for ( i=0; i<len; i++ )
{
MObject comp = convertToVertexComponent(componentList[i]);
if (savePoints && 0 == i) {
}
for ( int idx=0; idx<elemCount; idx++ )
{
int elemIndex = fnComp.
element( idx );
if (savePoints) {
pointCache->
append(geomPtr->vertices[elemIndex]);
}
geomPtr->vertices[elemIndex] *= mat;
geomPtr->normals[idx] =
geomPtr->normals[idx].transformAsNormal( mat );
}
}
} else {
len = geomPtr->vertices.length();
if (savePoints) {
}
for ( unsigned int idx = 0; idx < len; ++idx ) {
if (savePoints) {
pointCache->
append(geomPtr->vertices[idx]);
}
geomPtr->vertices[idx] *= mat;
geomPtr->normals[idx] =
geomPtr->normals[idx].transformAsNormal( mat );
}
}
}
updateCachedSurface( geomPtr, componentList );
}
void apiMesh::updateCachedSurface(
const apiMeshGeom* geomPtr,
const MObjectArray & componentList )
{
unsigned int len = componentList.
length();
MCHECKERRORNORET( stat, "computeInputSurface error getting cachedSurface")
apiMeshData* cached = (apiMeshData*) cachedHandle.asPluginData();
MDataHandle dHandle = datablock.outputValue( mControlPoints, &stat );
MCHECKERRORNORET( stat, "updateCachedSurface get dHandle" )
if ( hasHistory() && (NULL != cached) ) {
stat = buildControlPoints( datablock, geomPtr->vertices.length() );
MCHECKERRORNORET( stat, "updateCachedSurface buildControlPoints" )
MCHECKERRORNORET( stat, "updateCachedSurface get cpHandle" )
for ( unsigned int i=0; i<len; i++ )
{
MObject comp = convertToVertexComponent(componentList[i]);
for ( int idx=0; idx<elemCount; idx++ )
{
int elemIndex = fnComp.
element( idx );
cpHandle.jumpToElement( elemIndex );
MPoint oldPnt = cached->fGeometry->vertices[elemIndex];
MPoint newPnt = geomPtr->vertices[elemIndex];
MPoint offset = newPnt - oldPnt;
pnt[0] += offset[0];
pnt[1] += offset[1];
pnt[2] += offset[2];
}
}
}
if ( NULL == cached ) {
cerr << "NULL cachedSurface data found\n";
}
else {
*(cached->fGeometry) = *geomPtr;
}
MPlug pCPs(thisMObject(),mControlPoints);
pCPs.setValue(dHandle);
computeBoundingBox( datablock );
{
signalDirtyToViewport();
}
}
void
apiMesh::tweakUsing(
const MMatrix & mat,
MVertexCachingMode cachingMode,
{
apiMeshGeom* geomPtr = meshGeomToUse();
unsigned int i=0;
unsigned int len = componentList.
length();
unsigned int cacheIndex = 0;
unsigned int cacheLen = (NULL != pointCache) ? pointCache->
length() : 0;
if ( restorePoints ) {
if (len > 0) {
for ( i=0; i<len; i++ )
{
MObject comp = convertToVertexComponent(componentList[i]);
for ( int idx=0; idx<elemCount && cacheIndex < cacheLen; idx++, cacheIndex++) {
int elemIndex = fnComp.
element( idx );
MPoint& cachePt = (*pointCache)[cacheIndex];
}
}
} else {
len = geomPtr->vertices.length();
for ( unsigned int idx = 0; idx < len && idx < cacheLen; ++idx ) {
MPoint& cachePt = (*pointCache)[cacheIndex];
}
}
} else {
if (len > 0) {
for ( i=0; i<len; i++ )
{
MObject comp = convertToVertexComponent(componentList[i]);
if (savePoints) {
}
for ( int idx=0; idx<elemCount; idx++ )
{
int elemIndex = fnComp.
element( idx );
currPt = newPt = geomPtr->vertices[elemIndex];
newPt *= mat;
delta.
x = newPt.
x - currPt.
x;
delta.
y = newPt.
y - currPt.
y;
delta.
z = newPt.
z - currPt.
z;
if (savePoints) {
pointCache->
append(delta*(-1.0));
} else if (updatePoints && cacheIndex < cacheLen) {
MPoint& cachePt = (*pointCache)[cacheIndex];
cacheIndex++;
}
}
}
} else {
len = geomPtr->vertices.length();
if (savePoints) {
}
for ( unsigned int idx = 0; idx < len; ++idx ) {
currPt = newPt = geomPtr->vertices[idx];
newPt *= mat;
delta.
x = newPt.
x - currPt.
x;
delta.
y = newPt.
y - currPt.
y;
delta.
z = newPt.
z - currPt.
z;
if (savePoints) {
pointCache->
append(delta*-1.0);
} else if (updatePoints && idx < cacheLen) {
MPoint& cachePt = (*pointCache)[idx];
}
}
}
}
signalDirtyToViewport();
}
MVertexCachingMode cachingMode,
{
MPlug plg_useWeightedTransformUsingFunction( thisMObject(), useWeightedTransformUsingFunction );
bool val_useWeightedTransformUsingFunction = plg_useWeightedTransformUsingFunction.asBool();
if (!val_useWeightedTransformUsingFunction)
{
signalDirtyToViewport();
return;
}
if (space) {
}
apiMeshGeom* geomPtr = meshGeomToUse();
float almostZero = 1.0e-5f;
int pointCacheIndex = 0;
unsigned int len = componentList.
length();
for ( unsigned int i=0; i<len; i++ )
{
MObject comp = convertToVertexComponent(componentList[i]);
bool hasSeam = (NULL != freezePlane);
if (savePoints && (0 == i) ) {
}
for ( int idx=0; idx<elemCount; idx++ )
{
int elemIndex = fnComp.
element( idx );
if (perc > almostZero) {
if (restorePoints) {
geomPtr->vertices[elemIndex] =
MVector( (*pointCache)[pointCacheIndex] );
pointCacheIndex++;
}
else {
if (savePoints) {
pointCache->
append( geomPtr->vertices[elemIndex] );
}
else if ( transformOrigPoints ) {
geomPtr->vertices[elemIndex] =
MVector( (*pointCache)[pointCacheIndex] );
}
else if ( updatePoints ) {
(*pointCache)[pointCacheIndex] = geomPtr->vertices[elemIndex];
}
if (perc == 1.0) {
}
else {
mat = (space) ? (*space) * xform.
asMatrix(perc) * (spaceInv) : xform.
asMatrix(perc) ;
}
MPoint pt = geomPtr->vertices[elemIndex];
newp *= mat;
{
}
geomPtr->vertices[elemIndex] =
MVector( newp );
pointCacheIndex++;
}
}
}
}
updateCachedSurface( geomPtr, componentList );
}
void apiMesh::weightedTweakUsing(
MVertexCachingMode cachingMode,
{
MPlug plg_useWeightedTweakUsingFunction( thisMObject(), useWeightedTweakUsingFunction );
bool val_useWeightedTweakUsingFunction = plg_useWeightedTweakUsingFunction.asBool();
if (!val_useWeightedTweakUsingFunction) {
}
apiMeshGeom* geomPtr = meshGeomToUse();
unsigned int i=0;
unsigned int len = componentList.
length();
unsigned int cacheIndex = 0;
unsigned int cacheLen = (NULL != pointCache) ? pointCache->
length() : 0;
if ( restorePoints ) {
for ( i=0; i<len; i++ )
{
MObject comp = convertToVertexComponent(componentList[i]);
for ( int idx=0; idx<elemCount && cacheIndex < cacheLen; idx++, cacheIndex++) {
int elemIndex = fnComp.
element( idx );
MPoint& cachePt = (*pointCache)[cacheIndex];
}
}
} else {
float almostZero = 1.0e-5f;
if (space) {
}
for ( i=0; i<len; i++ )
{
MObject comp = convertToVertexComponent(componentList[i]);
bool hasSeam = (NULL != freezePlane);
if (savePoints) {
}
for ( int idx=0; idx<elemCount; idx++ )
{
int elemIndex = fnComp.
element( idx );
if (perc > almostZero) {
if (perc == 1.0) {
}
else {
mat = (space) ? (*space) * xform.
asMatrix(perc) * (spaceInv) : xform.
asMatrix(perc) ;
}
if ( transformOrigPoints ) {
geomPtr->vertices[elemIndex] =
MVector( (*pointCache)[cacheIndex] );
}
currPt = newPt = geomPtr->vertices[elemIndex];
newPt *= mat;
{
}
delta.
x = newPt.
x - currPt.
x;
delta.
y = newPt.
y - currPt.
y;
delta.
z = newPt.
z - currPt.
z;
if (savePoints) {
pointCache->
append(delta*(-1.0));
} else if (updatePoints && cacheIndex < cacheLen) {
MPoint& cachePt = (*pointCache)[cacheIndex];
cacheIndex++;
}
}
}
}
}
}
bool apiMesh::vertexOffsetDirection(
MObject & component,
MVertexOffsetMode mode,
bool normalize )
{
bool offsetOkay = false ;
MObject vtxComp = convertToVertexComponent(component);
return false;
}
offsetOkay = true ;
apiMeshGeom * geomPtr = meshGeomToUse();
if ( NULL == geomPtr ) {
return false;
}
for ( int idx=0; idx<count; idx++ )
{
}
else {
int i, j, k;
double a;
i = 0; a = fabs( normal[0] );
if ( a < fabs(normal[1]) ) { i = 1; a = fabs(normal[1]); }
if ( a < fabs(normal[2]) ) i = 2;
j = (i+1)%3; k = (j+1)%3;
a = sqrt(normal[i]*normal[i] + normal[j]*normal[j]);
uAxis[i] = -normal[j]/a; uAxis[j] = normal[i]/a; uAxis[k] = 0.0;
vAxis = normal^uAxis;
{
}
{
}
}
}
}
return offsetOkay ;
}
bool apiMesh::isBounded() const
{
return true;
}
{
apiMesh *msPtr = const_cast<apiMesh *>(this);
if ( fShapeDirty )
{
msPtr->meshDataRef(datablock);
}
MPlug c1Plug( thisNode, bboxCorner1 );
MPlug c2Plug( thisNode, bboxCorner2 );
c1Plug.getValue( corner1Object );
c2Plug.getValue( corner2Object );
double3 corner1, corner2;
fnData.
getData( corner1[0], corner1[1], corner1[2] );
fnData.
getData( corner2[0], corner2[1], corner2[2] );
MPoint corner1Point( corner1[0], corner1[1], corner1[2] );
MPoint corner2Point( corner2[0], corner2[1], corner2[2] );
}
{
{
MFn::Type srcComponentType = srcComponent.componentType();
std::set<int> srcIndices;
for (int i=0; i<srcComponent.elementCount(); ++i)
srcIndices.insert( srcComponent.element(i) );
const apiMeshGeom* geomPtr = meshGeomToUse();
unsigned int base = 0;
int edgeId = 0;
for (int faceIdx=0; faceIdx<geomPtr->faceCount; faceIdx++)
{
int numVerts = geomPtr->face_counts[faceIdx];
if (numVerts > 2)
{
for (int v=0; v<numVerts; v++)
{
{
if (srcIndices.count(edgeId))
{
unsigned int vindex1 = base + (v % numVerts);
unsigned int vindex2 = base + ((v+1) % numVerts);
int vertexId1 = geomPtr->face_connects[vindex1];
int vertexId2 = geomPtr->face_connects[vindex2];
vtxComponent.addElement(vertexId1);
vtxComponent.addElement(vertexId2);
}
++edgeId;
}
else
{
if (srcIndices.count(faceIdx))
{
unsigned int vindex = base + (v % numVerts);
int vertexId = geomPtr->face_connects[vindex];
vtxComponent.addElement(vertexId);
}
}
}
base += numVerts;
}
}
}
return retVal;
}
bool forReadOnly )
{
apiMeshGeomIterator * result = NULL;
for (
int i=0; i<(int)componentList.
length(); i++ )
{
vtxComponents.
append(convertToVertexComponent(componentList[i]));
}
result = new apiMeshGeomIterator( meshGeomToUse(), vtxComponents );
}
else {
MObject vtxComponent = convertToVertexComponent(components);
result = new apiMeshGeomIterator( meshGeomToUse(), vtxComponent );
}
return result;
}
bool apiMesh::acceptsGeometryIterator( bool writeable )
{
return true;
}
bool apiMesh::acceptsGeometryIterator(
MObject&,
bool writeable,
bool forReadOnly )
{
return true;
}
bool apiMesh::hasHistory()
{
return fHasHistoryOnCreate;
}
bool apiMesh::shapeDirty()
{
return fShapeDirty;
}
void apiMesh::resetShapeDirty()
{
fShapeDirty = false;
}
bool apiMesh::materialDirty() const
{
return fMaterialDirty;
}
void apiMesh::setMaterialDirty(bool dirty)
{
fMaterialDirty = dirty;
}
{
apiMeshGeom* geomPtr = meshGeom( datablock );
int cnt = geomPtr->vertices.length();
if ( cnt == 0 ) return stat;
MPoint tmppnt = geomPtr->vertices[0];
lower[0] = tmppnt[0]; lower[1] = tmppnt[1]; lower[2] = tmppnt[2];
upper[0] = tmppnt[0]; upper[1] = tmppnt[1]; upper[2] = tmppnt[2];
for ( int i=0; i<cnt; i++ )
{
MPoint pnt = geomPtr->vertices[i];
if ( pnt[0] < lower[0] ) lower[0] = pnt[0];
if ( pnt[1] < lower[1] ) lower[1] = pnt[1];
if ( pnt[2] > lower[2] ) lower[2] = pnt[2];
if ( pnt[0] > upper[0] ) upper[0] = pnt[0];
if ( pnt[1] > upper[1] ) upper[1] = pnt[1];
if ( pnt[2] < upper[2] ) upper[2] = pnt[2];
}
{
}
return stat;
}
{
if ( hasHistory() ) {
MCHECKERROR( stat, "computeInputSurface error getting inputSurface")
apiMeshData* surf = (apiMeshData*) inputHandle.asPluginData();
if ( NULL == surf ) {
cerr << "NULL inputSurface data found\n";
return stat;
}
apiMeshGeom* geomPtr = surf->fGeometry;
fnDataCreator.
create( tmpid, &stat );
MCHECKERROR( stat, "compute : error creating Cached apiMeshData")
apiMeshData * newCachedData = (apiMeshData*)fnDataCreator.data( &stat );
MCHECKERROR( stat, " error gettin proxy cached apiMeshData object")
*(newCachedData->fGeometry) = *geomPtr;
MDataHandle cachedHandle = datablock.outputValue( cachedSurface,&stat );
MCHECKERROR( stat, "computeInputSurface error getting cachedSurface")
cachedHandle.set( newCachedData );
}
return stat;
}
{
if ( ! computeInputSurface( plug, datablock ) ) {
return MS::kFailure;
}
MDataHandle cachedHandle = datablock.outputValue( cachedSurface, &stat );
MCHECKERROR( stat, "computeInputSurface error getting cachedSurface")
apiMeshData* cached = (apiMeshData*) cachedHandle.asPluginData();
if ( NULL == cached ) {
cerr << "NULL cachedSurface data found\n";
}
if ( hasHistory() ) {
applyTweaks( datablock, cached->fGeometry );
}
else {
&stat );
}
fnDataCreator.
create( tmpid, &stat );
MCHECKERROR( stat, "compute : error creating apiMeshData")
apiMeshData * newData = (apiMeshData*)fnDataCreator.data( &stat );
MCHECKERROR( stat, "compute : error gettin at proxy apiMeshData object")
if ( NULL != cached ) {
*(newData->fGeometry) = *(cached->fGeometry);
}
else {
cerr << "computeOutputSurface: NULL cachedSurface data\n";
}
MDataHandle outHandle = datablock.outputValue( outputSurface );
outHandle.
set( newData );
stat = computeBoundingBox( datablock );
MCHECKERROR( stat, "computeBoundingBox" )
return stat;
}
{
computeOutputSurface( plug, datablock );
MDataHandle inHandle = datablock.outputValue( outputSurface );
apiMeshData* outSurf = (apiMeshData*)inHandle.
asPluginData();
if ( NULL == outSurf ) {
cerr << "computeWorldSurface: outSurf NULL\n";
return MS::kFailure;
}
fnDataCreator.
create( tmpid, &stat );
MCHECKERROR( stat, "compute : error creating apiMeshData")
apiMeshData * newData = (apiMeshData*)fnDataCreator.data( &stat );
MCHECKERROR( stat, "compute : error gettin at proxy apiMeshData object")
MMatrix worldMat = getWorldMatrix(datablock, 0);
newData->setMatrix( worldMat );
*(newData->fGeometry) = *(outSurf->fGeometry);
int arrayIndex = plug.logicalIndex( &stat );
MCHECKERROR( stat, "computWorldSurface : logicalIndex" );
&stat );
MCHECKERROR( stat, "computWorldSurface : outputArrayValue" );
MCHECKERROR( stat, "computWorldSurface : builder" );
MDataHandle outHandle = builder.addElement( arrayIndex, &stat );
MCHECKERROR( stat, "computWorldSurface : addElement" );
outHandle.set( newData );
return stat;
}
{
&stat );
MCHECKERROR( stat, "applyTweaks get cpHandle" )
int elemCount = cpHandle.elementCount();
for ( int idx=0; idx<elemCount; idx++ )
{
MPoint offset( pnt[0], pnt[1], pnt[2] );
if (elemIndex < (int)geomPtr->vertices.length())
{
MPoint& oldPnt = geomPtr->vertices[elemIndex];
oldPnt = oldPnt + offset;
}
}
return stat;
}
bool apiMesh::value(
MDataBlock& datablock,
int pntInd,
int vlInd,
double & val )
const
{
bool result = false;
apiMesh* nonConstThis = (apiMesh*)this;
apiMeshGeom* geomPtr = nonConstThis->cachedGeom(datablock);
if ( NULL != geomPtr ) {
MPoint point = geomPtr->vertices[ pntInd ];
val = point[ vlInd ];
result = true;
}
return result;
}
{
bool result = false;
apiMesh* nonConstThis = (apiMesh*)this;
apiMeshGeom* geomPtr = nonConstThis->cachedGeom(datablock);
if ( NULL != geomPtr ) {
MPoint point = geomPtr->vertices[ pntInd ];
val = point;
result = true;
}
return result;
}
bool apiMesh::setValue(
MDataBlock& datablock,
int pntInd,
int vlInd,
double val )
{
bool result = false;
apiMesh* nonConstThis = (apiMesh*)this;
apiMeshGeom* geomPtr = nonConstThis->cachedGeom(datablock);
if ( NULL != geomPtr ) {
MPoint& point = geomPtr->vertices[ pntInd ];
point[ vlInd ] = val;
result = true;
}
{
verticesUpdated();
}
return result;
}
{
bool result = false;
apiMesh* nonConstThis = (apiMesh*)this;
apiMeshGeom* geomPtr = nonConstThis->cachedGeom(datablock);
if ( NULL != geomPtr ) {
geomPtr->vertices[ pntInd ] = val;
result = true;
}
{
verticesUpdated();
}
return result;
}
{
}
apiMeshGeom* apiMesh::meshGeom(
MDataBlock& datablock )
{
apiMeshGeom * result = NULL;
MObject tmpObj = meshDataRef(datablock);
apiMeshData * data = (apiMeshData*)fnData.data( &stat );
MCHECKERRORNORET( stat, "meshGeom : Failed to get apiMeshData");
if ( NULL != data ) {
result = data->fGeometry;
}
return result;
}
apiMeshGeom* apiMesh::meshGeomToUse( )
{
return meshGeom(datablock);
}
{
}
apiMeshGeom* apiMesh::cachedGeom(
MDataBlock& datablock )
{
apiMeshGeom * result = NULL;
MObject tmpObj = cachedDataRef(datablock);
apiMeshData * data = (apiMeshData*)fnData.data( &stat );
MCHECKERRORNORET( stat, "cachedGeom : Failed to get apiMeshData");
if ( NULL != data ) {
result = data->fGeometry;
}
return result;
}
{
MCHECKERROR( stat, "compute get cpH" )
if ( count != (int)oldBuilder.elementCount() )
{
MCHECKERROR( stat, "compute - create builder" )
for ( int vtx=0; vtx<count; vtx++ )
{
builder.addElement( vtx ).asDouble3();
}
}
return stat;
}
void apiMesh::verticesUpdated()
{
}
void apiMesh::setShapeDirty()
{
fShapeDirty = true;
}
void apiMesh::notifyViewport()
{
}
void apiMesh::signalDirtyToViewport()
{
setShapeDirty();
notifyViewport();
}
void* apiMesh::creator()
{
return new apiMesh();
}
{
inputSurface = typedAttr.
create(
"inputSurface",
"is",
apiMeshData::id,
MCHECKERROR( stat, "create inputSurface attribute" )
typedAttr.setStorable( false );
ADD_ATTRIBUTE( inputSurface );
useWeightedTransformUsingFunction = numericAttr.create( "useWeightedTransformUsingFunction", "utru",
MFnNumericData::kBoolean, true, &stat);
MCHECKERROR( stat, "create useWeightedTransformUsingFunction attribute" )
numericAttr.setKeyable(true);
ADD_ATTRIBUTE( useWeightedTransformUsingFunction );
useWeightedTweakUsingFunction = numericAttr.create( "useWeightedTweakUsingFunction", "utwu",
MFnNumericData::kBoolean, true, &stat);
MCHECKERROR( stat, "create useWeightedTweakUsingFunction attribute" )
numericAttr.setKeyable(true);
ADD_ATTRIBUTE( useWeightedTweakUsingFunction );
enableNumericDisplay = numericAttr.create("enableNumericDisplay", "end",
MFnNumericData::kBoolean, true, &stat);
MCHECKERROR( stat, "create enableNumericDisplay attribute" )
numericAttr.setKeyable(true);
ADD_ATTRIBUTE( enableNumericDisplay );
MAKE_NUMERIC_ATTR( bboxCorner1, "bboxCorner1", "bb1",
false, false, false );
MAKE_NUMERIC_ATTR( bboxCorner2, "bboxCorner2", "bb2",
false, false, false );
outputSurface = typedAttr.create( "outputSurface", "os",
apiMeshData::id,
MCHECKERROR( stat, "create outputSurface attribute" )
ADD_ATTRIBUTE( outputSurface );
typedAttr.setWritable( false );
worldSurface = typedAttr.create( "worldSurface", "ws",
apiMeshData::id,
MCHECKERROR( stat, "create worldSurface attribute" );
typedAttr.setCached( false );
typedAttr.setWritable( false );
stat = typedAttr.setArray( true );
MCHECKERROR( stat, "set array" );
stat = typedAttr.setUsesArrayDataBuilder( true );
MCHECKERROR( stat, "set uses array data builder" );
stat = typedAttr.setDisconnectBehavior(
MFnAttribute::kDelete );
MCHECKERROR( stat, "set disconnect behavior data builder" );
stat = typedAttr.setWorldSpace( true );
MCHECKERROR( stat, "set world space" );
ADD_ATTRIBUTE( worldSurface );
cachedSurface = typedAttr.create( "cachedSurface", "cs",
apiMeshData::id,
MCHECKERROR( stat, "create cachedSurface attribute" )
typedAttr.setReadable( true );
typedAttr.setWritable( true );
typedAttr.setStorable( true );
ADD_ATTRIBUTE( cachedSurface );
ATTRIBUTE_AFFECTS( enableNumericDisplay, outputSurface );
ATTRIBUTE_AFFECTS( inputSurface, outputSurface );
ATTRIBUTE_AFFECTS( inputSurface, worldSurface );
ATTRIBUTE_AFFECTS( outputSurface, worldSurface );
ATTRIBUTE_AFFECTS( inputSurface, bboxCorner1 );
ATTRIBUTE_AFFECTS( inputSurface, bboxCorner2 );
ATTRIBUTE_AFFECTS( cachedSurface, outputSurface );
ATTRIBUTE_AFFECTS( cachedSurface, worldSurface );
ATTRIBUTE_AFFECTS( mControlPoints, outputSurface );
ATTRIBUTE_AFFECTS( mControlValueX, outputSurface );
ATTRIBUTE_AFFECTS( mControlValueY, outputSurface );
ATTRIBUTE_AFFECTS( mControlValueZ, outputSurface );
ATTRIBUTE_AFFECTS( mControlPoints, cachedSurface );
ATTRIBUTE_AFFECTS( mControlValueX, cachedSurface );
ATTRIBUTE_AFFECTS( mControlValueY, cachedSurface );
ATTRIBUTE_AFFECTS( mControlValueZ, cachedSurface );
ATTRIBUTE_AFFECTS( mControlPoints, worldSurface );
ATTRIBUTE_AFFECTS( mControlValueX, worldSurface );
ATTRIBUTE_AFFECTS( mControlValueY, worldSurface );
ATTRIBUTE_AFFECTS( mControlValueZ, worldSurface );
return MS::kSuccess;
}
static bool sUseSubSceneOverride = (getenv("MAYA_APIMESHSHAPE_USE_SUBSCENEOVERRIDE") != NULL);
static bool sMakeGeometryOverridePointLight = (getenv("MAYA_APIMESHSHAPE_AS_POINTLIGHT") != NULL);
static
MString sDrawDbClassification(sUseSubSceneOverride
? "drawdb/subscene/apiMesh"
: "drawdb/geometry/apiMesh");
static
MString sLightClass = "light:" + sDrawDbClassification + ":drawdb/light/pointLight";
static
MString sDrawRegistrantId("apiMeshPlugin");
{
MFnPlugin plugin( obj, PLUGIN_COMPANY,
"3.0",
"Any");
MStatus stat1, stat2, stat3, stat4;
stat1 = plugin.registerData( "apiMeshData", apiMeshData::id,
&apiMeshData::creator,
if ( ! stat1 ) {
cerr << "Failed to register geometry data : apiMeshData \n";
return stat1;
}
stat2 = plugin.registerShape( "apiMesh", apiMesh::id,
&apiMesh::creator,
&apiMesh::initialize,
&apiMeshUI::creator,
sMakeGeometryOverridePointLight ? &sLightClass : &sDrawDbClassification );
if ( ! stat2 ) {
cerr << "Failed to register shape\n";
if ( stat1) plugin.deregisterData( apiMeshData::id );
return stat2;
}
stat3 = plugin.registerNode( "apiMeshCreator", apiMeshCreator::id,
&apiMeshCreator::creator,
&apiMeshCreator::initialize );
if ( ! stat3 ) {
cerr << "Failed to register creator\n";
if ( stat2 ) {
plugin.deregisterNode( apiMesh::id );
plugin.deregisterData( apiMeshData::id );
}
}
if (sUseSubSceneOverride)
{
sDrawDbClassification,
sDrawRegistrantId,
apiMeshSubSceneOverride::Creator);
if (!stat4)
{
cerr << "Failed to register Viewport 2.0 sub-scene override\n";
}
else {
stat4 = apiMeshSubSceneOverride::registerComponentConverters();
if (!stat4)
{
cerr << "Failed to register component converters\n";
}
}
}
else
{
sDrawDbClassification,
sDrawRegistrantId,
apiMeshGeometryOverride::Creator);
if (!stat4)
{
cerr << "Failed to register Viewport 2.0 geometry override\n";
}
else {
stat4 = apiMeshGeometryOverride::registerComponentConverters();
if (!stat4)
{
cerr << "Failed to register component converters\n";
}
}
}
return stat3;
}
{
if (sUseSubSceneOverride)
{
stat = apiMeshSubSceneOverride::deregisterComponentConverters();
if (!stat)
{
cerr << "Failed to deregister component converters \n";
}
sDrawDbClassification,
sDrawRegistrantId);
if (!stat)
{
cerr << "Failed to deregister sub-scene override : apiMeshSubSceneOverride \n";
}
}
else
{
stat = apiMeshGeometryOverride::deregisterComponentConverters();
if (!stat)
{
cerr << "Failed to deregister component converters \n";
}
sDrawDbClassification,
sDrawRegistrantId);
if (!stat)
{
cerr << "Failed to deregister geometry override : apiMeshGeometryOverride \n";
}
}
stat = plugin.deregisterNode( apiMesh::id );
if ( ! stat ) {
cerr << "Failed to deregister shape : apiMeshShape \n";
}
stat = plugin.deregisterData( apiMeshData::id );
if ( ! stat ) {
cerr << "Failed to deregister geometry data : apiMeshData \n";
}
stat = plugin.deregisterNode( apiMeshCreator::id );
if ( ! stat ) {
cerr << "Failed to deregister node : apiMeshCreator \n";
}
return stat;
}