//- // ========================================================================== // Copyright (C) 1995 - 2005 Alias Systems Corp. and/or its licensors. All // rights reserved. // // The coded instructions, statements, computer programs, and/or related // material (collectively the "Data") in these files are provided by Alias // Systems Corp. ("Alias") and/or its licensors for the exclusive use of the // Customer (as defined in the Alias Software License Agreement that // accompanies this Alias software). Such Customer has the right to use, // modify, and incorporate the Data into other products and to distribute such // products for use by end-users. // // THE DATA IS PROVIDED "AS IS". ALIAS HEREBY DISCLAIMS ALL WARRANTIES // RELATING TO THE DATA, INCLUDING, WITHOUT LIMITATION, ANY AND ALL EXPRESS OR // IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND/OR FITNESS FOR A // PARTICULAR PURPOSE. IN NO EVENT SHALL ALIAS BE LIABLE FOR ANY DAMAGES // WHATSOEVER, WHETHER DIRECT, INDIRECT, SPECIAL, OR PUNITIVE, WHETHER IN AN // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, OR IN EQUITY, // ARISING OUT OF ACCESS TO, USE OF, OR RELIANCE UPON THE DATA. // ========================================================================== //+ ///////////////////////////////////////////////////////////////////////////// // // polyTrgNode.cpp // // Description: // This node register a user defined face triangulation function. // After the function is register it can be used by any mesh in // the scene to do the triangulation (replace the mesh native // triangulation). In order for the mesh to use this function, // an attribute on the mesh: 'userTrg' has to be set to the name // of the function. // // Different meshes may use different functions. Each of them // needs to be register. The same node can provide more than // one function. // // Example: // createNode polyTrgNode -n ptrg; // // polyPlane -w 1 -h 1 -sx 10 -sy 10 -ax 0 1 0 -tx 0 -ch 1 -n pp1; // // select -r pp1Shape; // setAttr pp1Shape.userTrg -type "string" "triangulate"; // ///////////////////////////////////////////////////////////////////////////// #include // API stuff. #include // Node stuff. #include #include // Command stuff. #include #include #include #include #include #include #include #include ///////////////////////////////////////////////////////////////////////////// // // MACROS DECLARATION // ///////////////////////////////////////////////////////////////////////////// #define MCHECKERR(stat,msg) \ if ( MS::kSuccess != stat ) { \ return MS::kFailure; \ } #define EQUAL(a,b) ( (((a-b) > -0.00001) && ((a-b) < 0.00001)) ? 1 : 0 ) #define EQUAL2(a,b) ((EQUAL(a[0],b[0]) && EQUAL(a[1],b[1]) ) ? 1 : 0) #define EQUAL3(a,b) ((EQUAL(a[0],b[0]) && EQUAL(a[1],b[1]) && EQUAL(a[2],b[2]) ) ? 1 : 0) #define MCHECKERR_RETURN(stat,msg) \ if ( MS::kSuccess != stat ) { \ displayError( msg ); \ fErrorCount = 1; \ return MS::kFailure; \ } #define MCHECKERR_BREAK(stat,msg) \ if ( MS::kSuccess != stat ) { \ displayError( msg ); \ fErrorCount = 1; \ break; \ } ///////////////////////////////////////////////////////////////////////////// // // testPolyTrgNode node declaration // ///////////////////////////////////////////////////////////////////////////// class polyTrgNode : public MPxPolyTrg { public: polyTrgNode() {}; virtual ~polyTrgNode(); virtual MStatus compute(const MPlug& plug, MDataBlock& data); virtual void postConstructor( void ); virtual bool isAbstractClass( void ) const; static void* creator(); static MStatus initialize(); // User triangulation - this is a triangulation per face. static void triangulateFace( const float *vert, const float *norm, const int *loopSizes, const int nbLoops, const int nbTrg, unsigned short *trg ); public: static MTypeId id; private: }; ///////////////////////////////////////////////////////////////////////////// // // polyTrgNode implementation // ///////////////////////////////////////////////////////////////////////////// MTypeId polyTrgNode::id(0x101015); polyTrgNode::~polyTrgNode() // // Description: // Destructor: unregister the triangulation function. // { // Unregister the triangulation function. /* MStatus stat = */ unregisterTrgFunction( "triangulate" ); } void * polyTrgNode::creator() { return new polyTrgNode(); } void polyTrgNode::postConstructor() // // Description: // Constructor: register the triangulation function. // { // Register the triangulation function. // The string given as a first parameter has to be // the same as the name given when setting the usrTrg // attribute on the mesh. See example above. // /* MStatus stat = */ registerTrgFunction( "triangulate", polyTrgNode::triangulateFace ); } bool polyTrgNode::isAbstractClass( void ) const { return false; } MStatus polyTrgNode::initialize() { return MS::kSuccess; } MStatus polyTrgNode::compute(const MPlug& plug, MDataBlock& data) { return MS::kSuccess; } void polyTrgNode::triangulateFace( const float *vert, // I: face vertex position const float *norm, // I: face normals per vertex const int *loopSizes, // I: number of vertices per loop const int nbLoops, // I: number of loops in the face const int nbTrg, // I: number of triangles to generate unsigned short *trg // O: triangles - size = 3*nbTrg. // Note: this array is already allocated. ) // // Description: // Triangulate a given face. Returns triangles given by // the relative vertex ids. Example: // nbTrg = 2 // trg: 0, 1, 2, 2, 3, 0 // { // ====================================== // Print the input. // ====================================== cerr << "polyTrgNode::triangulate() - This is an API registered triangulation.\n"; // Dump the data - this is a good example. cerr << "Numb Loops = " << nbLoops << "\n"; int nbVert = 0; cerr << "Loop sizes: "; for (int i=0; i= nbVert) { v2 = 0; } } // ====================================== // ====================================== // Print the result. // ====================================== cerr << "Triangulation\n"; for (int k1=0; k1