//- // ========================================================================== // Copyright (C) 1995 - 2006 Autodesk, Inc. and/or its licensors. All // rights reserved. // // The coded instructions, statements, computer programs, and/or related // material (collectively the "Data") in these files contain unpublished // information proprietary to Autodesk, Inc. ("Autodesk") and/or its // licensors, which is protected by U.S. and Canadian federal copyright // law and by international treaties. // // The Data is provided for use exclusively by You. You have the right // to use, modify, and incorporate this Data into other products for // purposes authorized by the Autodesk software license agreement, // without fee. // // The copyright notices in the Software and this entire statement, // including the above license grant, this restriction and the // following disclaimer, must be included in all copies of the // Software, in whole or in part, and all derivative works of // the Software, unless such copies or derivative works are solely // in the form of machine-executable object code generated by a // source language processor. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND. // AUTODESK DOES NOT MAKE AND HEREBY DISCLAIMS ANY EXPRESS OR IMPLIED // WARRANTIES INCLUDING, BUT NOT LIMITED TO, THE WARRANTIES OF // NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR // PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE, OR // TRADE PRACTICE. IN NO EVENT WILL AUTODESK AND/OR ITS LICENSORS // BE LIABLE FOR ANY LOST REVENUES, DATA, OR PROFITS, OR SPECIAL, // DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES, EVEN IF AUTODESK // AND/OR ITS LICENSORS HAS BEEN ADVISED OF THE POSSIBILITY // OR PROBABILITY OF SUCH DAMAGES. // // ========================================================================== //+ // Example Plugin: instancerListCmd.cpp // // This plugin demonstrates how to use the MFnInstancer class and the // MItInstancer class to enumerate particle instances in a scene. If // one or more instancer nodes are selected when the command is invoked, // MFnInstancer will be used to enumerate each instancer's instances, with // both the instancesForParticle() and allInstances() methods exercised. // If no instancers are selected, then MItInstancer is used to iterate through // all the particle instances in the scene. // #include #include #include #include #include #include #include #include #include #include DeclareSimpleCommand( listParticleInstances, PLUGIN_COMPANY, "8.0"); void printInstancerUsingFunctionSet( const MDagPath& instancerPath ) { char str[256]; MString pathName = instancerPath.fullPathName(); sprintf( str, "Instancer %s:", pathName.asChar() ); MGlobal::displayInfo( MString(str) ); MFnInstancer fnInst( instancerPath ); int numParticles = fnInst.particleCount(); sprintf( str, " num particles = %d", numParticles ); // // Step 1: Use the MFnInstancer::instancesForParticle() to enumerate // the paths instanced under each particle. // MGlobal::displayInfo( " Using instancesForParticle()...." ); MMatrix instancerWorldMatrix = instancerPath.inclusiveMatrix(); int p = 0; for( p = 0; p < numParticles; p++ ) { MMatrix particleMatrix; MDagPathArray particlePaths; int numInstances = fnInst.instancesForParticle( p, particlePaths, particleMatrix ); // iterate over all the instances under this particle // for( int i = 0; i < numInstances; i++ ) { const MDagPath& instancedPath = particlePaths[i]; MMatrix instancedPathMatrix = instancedPath.inclusiveMatrix(); // the final world position of the instanced shape is determined // by the original path's matrix combined with the offset matrix // provided by the instancer // MMatrix finalMatrixForPath = instancedPathMatrix * particleMatrix; MPoint finalPoint = MPoint::origin * finalMatrixForPath; MString instancedPathName = instancedPath.fullPathName(); sprintf( str, " Path %-50s at position (%lf,%lf,%lf)", instancedPathName.asChar(), finalPoint.x, finalPoint.y, finalPoint.z ); MGlobal::displayInfo( str ); } } // // Step 2: Use the MFnInstancer::allInstances() method to enumerate all // particle instances generated by this instancer. The same // information that was extracted one particle at a time in // Step 1 is now retrieved with one function call, and stored in // a set of arrays. // MGlobal::displayInfo( " Using allInstances()...." ); MDagPathArray allPaths; MMatrixArray allMatrices; MIntArray pathIndices; MIntArray pathStartIndices; fnInst.allInstances( allPaths, allMatrices, pathStartIndices, pathIndices ); for( p = 0; p < numParticles; p++ ) { MMatrix particleMatrix = allMatrices[p]; // the number of paths instanced under a particle is computed by // taking the difference between the starting path index for this // particle and that of the next particle. The size of the start // index array is always one larger than the number of particles. // int numPaths = pathStartIndices[p+1]-pathStartIndices[p]; // the values pathIndices[pathStart...pathStart+numPaths] give the // indices in the allPaths array of the paths instanced under this // particular particle. Remember, different paths can be instanced // under each particle. // int pathStart = pathStartIndices[p]; // loop through the instanced paths for this particle // for( int i = pathStart; i < pathStart+numPaths; i++ ) { int curPathIndex = pathIndices[i]; const MDagPath& curPath = allPaths[curPathIndex]; MMatrix instancedPathMatrix = curPath.inclusiveMatrix(); MMatrix finalMatrixForPath = instancedPathMatrix * particleMatrix; MPoint finalPoint = MPoint::origin * finalMatrixForPath; MString instancedPathName = curPath.fullPathName(); sprintf( str, " Path %-50s at position (%lf,%lf,%lf)", instancedPathName.asChar(), finalPoint.x, finalPoint.y, finalPoint.z ); MGlobal::displayInfo( str ); } } } void printAllInstancesUsingIterator() { // // Just use the MItInstancer iterator to enumerate all particles in // all instancers in the scene. // MItInstancer it; while( !it.isDone() ) { MObject instancerNode = it.instancer(); MDagPath instancerPath = it.instancerPath(); MDagPath instancePath = it.path(); MMatrix instanceMatrix = it.matrix(); MString instancerNodeName = MFnDependencyNode(instancerNode).name(); MString instancerPathName = instancerPath.fullPathName(); MString instancePathName = instancePath.fullPathName(); MMatrix pathMatrix = instancePath.inclusiveMatrix(); MMatrix finalMatrixForPath = pathMatrix * instanceMatrix; MPoint pos = MPoint::origin * finalMatrixForPath; char str[512]; sprintf( str, "Instancer node %s, instancer path %s, instancing path %s at position (%lf,%lf,%lf)", instancerNodeName.asChar(), instancerPathName.asChar(), instancePathName.asChar(), pos.x, pos.y, pos.z ); MGlobal::displayInfo( MString(str) ); it.next(); } } MStatus listParticleInstances::doIt( const MArgList& ) { MSelectionList curSel; MGlobal::getActiveSelectionList( curSel ); MItSelectionList it( curSel, MFn::kInstancer ); if( it.isDone() ) { // use MItInstancer to enumerate all particle instances // MGlobal::displayInfo( "Using iterator to enumerate all particle instances..." ); printAllInstancesUsingIterator(); } else { // use MFnInstancer to list instances // while( !it.isDone() ) { MDagPath instancerPath; if( it.getDagPath( instancerPath ) == MS::kSuccess ) { printInstancerUsingFunctionSet( instancerPath ); } else { MGlobal::displayError( "Error retrieving instancer" ); return MS::kFailure; } it.next(); } } return MS::kSuccess; }