MStatus sweptEmitter::emitCountPerPoint ( const MPlug &plug, MDataBlock &block, int length, // length of emitCountPP MIntArray &emitCountPP // output: emitCount for each point ) // // Descriptions: // Compute emitCount for each point where new particles come from. // { MStatus status; int plugIndex = plug.logicalIndex( &status ); McheckErr(status, "ERROR in emitCountPerPoint: when plug.logicalIndex.\n"); // Get rate and delta time. // double rate = rateValue( block ); MTime dt = deltaTimeValue( plugIndex, block ); // Compute emitCount for each point. // double dblCount = rate * dt.as( MTime::kSeconds ); int intCount = (int)dblCount; for( int i = 0; i < length; i++ ) { emitCountPP.append( intCount ); } return( MS::kSuccess ); }
MStatus vixo_visImport::connectionBroken(const MPlug& plug,const MPlug& otherPlug,bool asSrc) { if(plug.array()==this->vis) { mapObjName.erase(plug.logicalIndex()); return MS::kSuccess; } return MPxNode::connectionMade( plug, otherPlug, asSrc ); }
//--------------------------------------------------- // set the bind pose for a transform // MStatus DagHelper::setBindPoseInverse ( const MObject& node, const MMatrix& bindPoseInverse ) { MStatus status; MFnDependencyNode dgFn ( node ); MPlug bindPosePlug = dgFn.findPlug ( "bindPose", &status ); if ( status != MS::kSuccess ) { MGlobal::displayWarning ( MString ( "No bindPose found on node " ) + dgFn.name() ); return status; } MFnMatrixData matrixFn; MObject val = matrixFn.create ( bindPoseInverse.inverse(), &status ); MObject invval = matrixFn.create ( bindPoseInverse, &status ); if ( status != MS::kSuccess ) { MGlobal::displayWarning ( MString ( "Error setting bindPose on node " ) + dgFn.name() ); return status; } // set the bind pose on the joint itself bindPosePlug.setValue ( val ); // Now, perhaps more significantly, see if there's a // skinCluster using this bone and update its bind // pose (as the joint bind pose is not connected to // the skin - it's set at bind time from the joint's // current position, and our importer may not want to // disturb the current scene state just to put bones // in a bind position before creating skin clusters) MObject _node ( node ); MItDependencyGraph it ( _node, MFn::kSkinClusterFilter ); while ( !it.isDone() ) { MPlug plug = it.thisPlug(); unsigned int idx = plug.logicalIndex(); MFnDependencyNode skinFn ( plug.node() ); MPlug skinBindPosePlug = skinFn.findPlug ( "bindPreMatrix", &status ); if ( status == MS::kSuccess ) { // The skinCluster stores inverse inclusive matrix // so notice we use invval (the MObject created off // the inverse matrix here) skinBindPosePlug = skinBindPosePlug.elementByLogicalIndex ( idx ); skinBindPosePlug.setValue ( invval ); } it.next(); } return status; }
// ---------------------------------------------------------- int AnimationClip::findPlug ( const MPlug& p ) { uint count = plugs.length(); for ( uint i = 0; i < count; ++i ) { if ( p == plugs[i] ) { if ( !p.isElement() || p.logicalIndex() == plugs[i].logicalIndex() ) { return i; } } } return -1; }
MStatus nailConstraintNode::compute(const MPlug& plug, MDataBlock& data) { //std::cout << "nailConstraintNode::compute: " << plug.name() << std::endl; //MTime time = data.inputValue( nailConstraintNode::inTime ).asTime(); if(plug == ca_constraint) { computeConstraint(plug, data); } else if(plug == ca_constraintParam) { computeConstraintParam(plug, data); } else if(plug.isElement()) { if(plug.array() == worldMatrix && plug.logicalIndex() == 0) { computeWorldMatrix(plug, data); } else { return MStatus::kUnknownParameter; } } else { return MStatus::kUnknownParameter; } return MStatus::kSuccess; }
int physicalIndex(MPlug& p) { MPlug parent = p; while (parent.isChild()) parent = parent.parent(); if (!parent.isElement()) return -1; if (!parent.array()) return - 1; MPlug arrayPlug = parent.array(); for (uint i = 0; i < arrayPlug.numElements(); i++) if (arrayPlug[i].logicalIndex() == parent.logicalIndex()) return i; return -1; }
// getBindPoseMatrix. // should be a relatively harmless function. // well you're wrong: this is one of the most stupid/difficult things in // Maya: // 1st try: just get the "bindPose"-plug, and use it as matrix: // MFnIkJoint joint(jointPath.node()); // MPlug bindMatrixPlug = joint.findPlug("bindPose"); // MObject bindMatrixObject; // bindMatrixPlug.getValue(bindMatrixObject); // MFnMatrixData matrixData(bindMatrixObject); // MMatrix bindMatrix = matrixData.matrix(); // Looks correct. But isn't. Not only, that we want the local // transform (but that wouldn't be difficult (just look at the // parent...), the bindPose plug seems // to be shared between instances. If a joint is instanced, the // bindMatrix would be the same as for the other instance. Bad luck :( // 2nd try: extract the local-transform out of the bindPose-plug. That's // what is done here. (at least for now. (seen first in // MS' xporttranslator). // Still not the really correct way: it's possible to break the // bindPose-plug. Maya still works, but our exporter doesn't. // 3rd (and correct way): // http://www.greggman.com/pages/mayastuff.htm // // again: not yet very much error-checking... MMatrix BindPoseTool::getBindPoseMatrix(MFnIkJoint joint) const { // get bindPose-plug on joint MPlug tempBindPosePlug = joint.findPlug("bindPose"); MPlugArray mapConnections; tempBindPosePlug.connectedTo(mapConnections, false, true); if (mapConnections.length() != 1) { //cout << "returning currentMatrix" << endl; // certainly not the most correct way of dealing with the problem... return joint.transformation().asMatrix(); } // find the other end. actually we shouldn't call it "bindPosePlug", // but worldTransformPlug (as that's where it enters). // theoretically someone could bind the bindPose to other nodes, // than the bindPose-node. in this case there's a problem. MPlug bindPosePlug = mapConnections[0]; // this node should be a "dagPose"-node (in case you want to look it // up in the help) MFnDependencyNode bindPoseNode(bindPosePlug.node()); // and as such, has the "xformMatrix"-attribute. MObject xformMatrixAttribute = bindPoseNode.attribute("xformMatrix"); MPlug localTransformPlug(bindPosePlug.node(), xformMatrixAttribute); // xformMatrix is an array. to get our localmatrix we need to select // the same index, as our bindPosePlug (logicalIndex()). localTransformPlug.selectAncestorLogicalIndex( bindPosePlug.logicalIndex(), xformMatrixAttribute); MObject localMatrixObject; localTransformPlug.getValue(localMatrixObject); // extract the matrix out of the object. return MFnMatrixData(localMatrixObject).matrix(); }
MStatus rigidBodyNode::compute(const MPlug& plug, MDataBlock& data) { // std::cout << "rigidBodyNode::compute | plug " << plug.name() << std::endl; //MTime time = data.inputValue( rigidBodyNode::inTime ).asTime(); if(plug == ca_rigidBody) { computeRigidBody(plug, data); } else if(plug == ca_rigidBodyParam) { computeRigidBodyParam(plug, data); } else if(plug == ca_solver) { data.inputValue(ia_solver).asBool(); } else if(plug.isElement()) { if(plug.array() == worldMatrix && plug.logicalIndex() == 0) { computeWorldMatrix(plug, data); } else { return MStatus::kUnknownParameter; } } else { return MStatus::kUnknownParameter; } return MStatus::kSuccess; }
MStatus vixo_visImport::connectionMade(const MPlug& plug,const MPlug& otherPlug,bool asSrc) { if(plug.array()==this->vis) { //cout<<plug.info().asChar()<<" "<<plug.array().name().asChar()<<" "<<plug.logicalIndex()<<endl; MPlugArray arr; plug.connectedTo(arr,false,true); MFnDagNode dagNodeFn(arr[0].node()); if(dagNodeFn.parentCount()<=0) return MS::kSuccess; //MFnDagNode transformFn(dagNodeFn.parent(0)); MStringArray tempArray; dagNodeFn.name().split(':',tempArray); if(tempArray.length()<2) return MS::kSuccess; //cout<<tempArray[tempArray.length()-1].asChar()<<endl; mapObjName.insert(pair<int,string>(plug.logicalIndex(),tempArray[tempArray.length()-1].asChar())); return MS::kSuccess; } return MPxNode::connectionMade( plug, otherPlug, asSrc ); }
MStatus dynExprField::compute(const MPlug& plug, MDataBlock& block) // // Descriptions: // compute output force. // { MStatus status; if( !(plug == mOutputForce) ) return( MS::kUnknownParameter ); // get the logical index of the element this plug refers to. // int multiIndex = plug.logicalIndex( &status ); McheckErr(status, "ERROR in plug.logicalIndex.\n"); // Get input data handle, use outputArrayValue since we do not // want to evaluate both inputs, only the one related to the // requested multiIndex. Evaluating both inputs at once would cause // a dependency graph loop. MArrayDataHandle hInputArray = block.outputArrayValue( mInputData, &status ); McheckErr(status,"ERROR in hInputArray = block.outputArrayValue().\n"); status = hInputArray.jumpToElement( multiIndex ); McheckErr(status, "ERROR: hInputArray.jumpToElement failed.\n"); // get children of aInputData. MDataHandle hCompond = hInputArray.inputValue( &status ); McheckErr(status, "ERROR in hCompond=hInputArray.inputValue\n"); MDataHandle hPosition = hCompond.child( mInputPositions ); MObject dPosition = hPosition.data(); MFnVectorArrayData fnPosition( dPosition ); MVectorArray points = fnPosition.array( &status ); McheckErr(status, "ERROR in fnPosition.array(), not find points.\n"); // Comment out the following since velocity, and mass are // not needed in this field. // // MDataHandle hVelocity = hCompond.child( mInputVelocities ); // MObject dVelocity = hVelocity.data(); // MFnVectorArrayData fnVelocity( dVelocity ); // MVectorArray velocities = fnVelocity.array( &status ); // McheckErr(status, "ERROR in fnVelocity.array(), not find velocities.\n"); // // MDataHandle hMass = hCompond.child( mInputMass ); // MObject dMass = hMass.data(); // MFnDoubleArrayData fnMass( dMass ); // MDoubleArray masses = fnMass.array( &status ); // McheckErr(status, "ERROR in fnMass.array(), not find masses.\n"); // The attribute mInputPPData contains the attribute in an array form // parpared by the particleShape if the particleShape has per particle // attribute fieldName_attrName. // // Suppose a field with the name dynExprField1 is connecting to // particleShape1, and the particleShape1 has per particle float attribute // dynExprField1_magnitude and vector attribute dynExprField1_direction, // then hInputPPArray will contains a MdoubleArray with the corresponding // name "magnitude" and a MvectorArray with the name "direction". This // is a mechanism to allow the field attributes being driven by dynamic // expression. MArrayDataHandle mhInputPPData = block.inputArrayValue( mInputPPData, &status ); McheckErr(status,"ERROR in mhInputPPData = block.inputArrayValue().\n"); status = mhInputPPData.jumpToElement( multiIndex ); McheckErr(status, "ERROR: mhInputPPArray.jumpToElement failed.\n"); MDataHandle hInputPPData = mhInputPPData.inputValue( &status ); McheckErr(status, "ERROR in hInputPPData = mhInputPPData.inputValue\n"); MObject dInputPPData = hInputPPData.data(); MFnArrayAttrsData inputPPArray( dInputPPData ); MDataHandle hOwnerPPData = block.inputValue( mOwnerPPData, &status ); McheckErr(status, "ERROR in hOwnerPPData = block.inputValue\n"); MObject dOwnerPPData = hOwnerPPData.data(); MFnArrayAttrsData ownerPPArray( dOwnerPPData ); const MString magString("magnitude"); MFnArrayAttrsData::Type doubleType(MFnArrayAttrsData::kDoubleArray); bool arrayExist; MDoubleArray magnitudeArray; arrayExist = inputPPArray.checkArrayExist(magString, doubleType, &status); // McheckErr(status, "ERROR in checkArrayExist(magnitude)\n"); if(arrayExist) { magnitudeArray = inputPPArray.getDoubleData(magString, &status); // McheckErr(status, "ERROR in inputPPArray.doubleArray(magnitude)\n"); } MDoubleArray magnitudeOwnerArray; arrayExist = ownerPPArray.checkArrayExist(magString, doubleType, &status); // McheckErr(status, "ERROR in checkArrayExist(magnitude)\n"); if(arrayExist) { magnitudeOwnerArray = ownerPPArray.getDoubleData(magString, &status); // McheckErr(status, "ERROR in ownerPPArray.doubleArray(magnitude)\n"); } const MString dirString("direction"); MFnArrayAttrsData::Type vectorType(MFnArrayAttrsData::kVectorArray); arrayExist = inputPPArray.checkArrayExist(dirString, vectorType, &status); MVectorArray directionArray; // McheckErr(status, "ERROR in checkArrayExist(direction)\n"); if(arrayExist) { directionArray = inputPPArray.getVectorData(dirString, &status); // McheckErr(status, "ERROR in inputPPArray.vectorArray(direction)\n"); } arrayExist = ownerPPArray.checkArrayExist(dirString, vectorType, &status); MVectorArray directionOwnerArray; // McheckErr(status, "ERROR in checkArrayExist(direction)\n"); if(arrayExist) { directionOwnerArray = ownerPPArray.getVectorData(dirString, &status); // McheckErr(status, "ERROR in ownerPPArray.vectorArray(direction)\n"); } // Compute the output force. // MVectorArray forceArray; apply( block, points.length(), magnitudeArray, magnitudeOwnerArray, directionArray, directionOwnerArray, forceArray ); // get output data handle // MArrayDataHandle hOutArray = block.outputArrayValue( mOutputForce, &status); McheckErr(status, "ERROR in hOutArray = block.outputArrayValue.\n"); MArrayDataBuilder bOutArray = hOutArray.builder( &status ); McheckErr(status, "ERROR in bOutArray = hOutArray.builder.\n"); // get output force array from block. // MDataHandle hOut = bOutArray.addElement(multiIndex, &status); McheckErr(status, "ERROR in hOut = bOutArray.addElement.\n"); MFnVectorArrayData fnOutputForce; MObject dOutputForce = fnOutputForce.create( forceArray, &status ); McheckErr(status, "ERROR in dOutputForce = fnOutputForce.create\n"); // update data block with new output force data. // hOut.set( dOutputForce ); block.setClean( plug ); return( MS::kSuccess ); }
MStatus CmpMeshModifierCmd::transferTweaks( const MDagPath &shapePath, MObject &tweakNode, MDagModifier &dagMod ) { // Get the tweaks from the mesh shape and apply them to the // to the tweak node MFnDagNode shapeNodeFn( shapePath ); MPlug srcTweaksPlug = shapeNodeFn.findPlug( "pnts" ); MFnDependencyNode tweakNodeFn( tweakNode ); MPlug dstTweaksPlug = tweakNodeFn.findPlug( "tweak" ); //MGlobal::displayInfo( MString( "storing tweaks from " ) + shapePath.fullPathName() + "\n" ); MPlugArray plugs; MPlug srcTweakPlug; MPlug dstTweakPlug; MObject dataObj; MFloatVector tweak; unsigned int nTweaks = srcTweaksPlug.numElements(); unsigned int i, j, ci, logicalIndex; for( i=0; i < nTweaks; i++ ) { srcTweakPlug = srcTweaksPlug.elementByPhysicalIndex( i ); if( !srcTweakPlug.isNull() ) { logicalIndex = srcTweakPlug.logicalIndex(); // Set tweak node tweak element srcTweakPlug.getValue( dataObj ); MFnNumericData numDataFn( dataObj ); numDataFn.getData( tweak[0], tweak[1], tweak[2] ); dagMod.commandToExecute( MString( "setAttr " ) + tweakNodeFn.name() + ".tweak[" + logicalIndex + "] " + tweak[0] + " " + tweak[1] + " " + tweak[2] ); // Handle transfer of incoming and outgoing connections to "pnts" elements dstTweakPlug = dstTweaksPlug.elementByLogicalIndex(logicalIndex); if( srcTweakPlug.isConnected() ) { // As source, transfer source to tweak node tweak srcTweakPlug.connectedTo( plugs, false, true ); for( j=0; j < plugs.length(); j++ ) { dagMod.disconnect( srcTweakPlug, plugs[j] ); dagMod.connect( dstTweakPlug, plugs[j] ); } // As destination, transfer destination to tweak node tweak srcTweakPlug.connectedTo( plugs, true, false ); if( plugs.length() == 1 ) // There can only be one input connection { dagMod.disconnect( plugs[0], srcTweakPlug ); dagMod.connect( plugs[0], dstTweakPlug ); } } else // Check children { MPlug srcTweakChildPlug; MPlug dstTweakChildPlug; for( ci=0; ci < srcTweakPlug.numChildren(); ci++ ) { srcTweakChildPlug = srcTweakPlug.child(ci); dstTweakChildPlug = dstTweakPlug.child(ci); if( srcTweakChildPlug.isConnected() ) { // As souce, transfer source to tweak node tweak srcTweakChildPlug.connectedTo( plugs, false, true ); for( j=0; j < plugs.length(); j++ ) { dagMod.disconnect( srcTweakChildPlug, plugs[j] ); dagMod.connect( dstTweakChildPlug, plugs[j] ); } // As destination, transfer destination to tweak node tweak srcTweakChildPlug.connectedTo( plugs, true, false ); if( plugs.length() == 1 ) // There can only be one input connection { dagMod.disconnect( plugs[0], srcTweakChildPlug ); dagMod.connect( plugs[0], dstTweakChildPlug ); } } } } // With the tweak values and any connections now transferred to // the tweak node's tweak element, this source element can be reset dagMod.commandToExecute( MString( "setAttr " ) + shapePath.fullPathName() + ".pnts[" + logicalIndex + "] 0 0 0" ); //MGlobal::displayInfo( MString(" tweak: ") + tweakIndices[i] + ": " + tweaks[i].x + ", " + tweaks[i].y + ", " + tweaks[i].z + "\n" ); } } return MS::kSuccess; }
// -------------------------------------------------------------------------------------------- MStatus polyModifierCmd::processTweaks( modifyPolyData& data ) // -------------------------------------------------------------------------------------------- { MStatus status = MS::kSuccess; // Clear tweak undo information (to be rebuilt) // fTweakIndexArray.clear(); fTweakVectorArray.clear(); // Extract the tweaks and place them into a polyTweak node. This polyTweak node // will be placed ahead of the modifier node to maintain the order of operations. // Special care must be taken into recreating the tweaks: // // 1) Copy tweak info (including connections!) // 2) Remove tweak info from both meshNode and a duplicate meshNode (if applicable) // 3) Cache tweak info for undo operations // //if( fHasTweaks && fHasHistory && !speedupTweakProcessing()) if( fHasTweaks && fHasHistory ) { // Declare our function sets // MFnDependencyNode depNodeFn; // Declare our attributes and plugs // MPlug meshTweakPlug; MPlug upstreamTweakPlug; MObject tweakNodeTweakAttr; // Declare our tweak processing variables // MPlug tweak; MPlug tweakChild; MObject tweakData; MObjectArray tweakDataArray; MFloatVector tweakVector; MIntArray tweakSrcConnectionCountArray; MPlugArray tweakSrcConnectionPlugArray; MIntArray tweakDstConnectionCountArray; MPlugArray tweakDstConnectionPlugArray; MPlugArray tempPlugArray; unsigned i; unsigned j; unsigned k; // Create the tweak node and get its attributes // data.tweakNode = fDGModifier.MDGModifier::createNode( "polyTweak" ); depNodeFn.setObject( data.tweakNode ); data.tweakNodeSrcAttr = depNodeFn.attribute( "output" ); data.tweakNodeDestAttr = depNodeFn.attribute( "inputPolymesh" ); tweakNodeTweakAttr = depNodeFn.attribute( "tweak" ); depNodeFn.setObject( data.meshNodeShape ); meshTweakPlug = depNodeFn.findPlug( "pnts" ); // ASSERT: meshTweakPlug should be an array plug! // MStatusAssert( (meshTweakPlug.isArray()), "meshTweakPlug.isArray() -- meshTweakPlug is not an array plug" ); unsigned numElements = meshTweakPlug.numElements(); // Gather meshTweakPlug data // for( i = 0; i < numElements; i++ ) { // MPlug::numElements() only returns the number of physical elements // in the array plug. Thus we must use elementByPhysical index when using // the index i. // tweak = meshTweakPlug.elementByPhysicalIndex(i); // If the method fails, the element is NULL. Only append the index // if it is a valid plug. // if( !tweak.isNull() ) { // Cache the logical index of this element plug // unsigned logicalIndex = tweak.logicalIndex(); // Collect tweak data and cache the indices and float vectors // tweak.getValue( tweakData ); tweakDataArray.append( tweakData ); getFloat3PlugValue( tweak, tweakVector ); fTweakIndexArray.append( logicalIndex ); fTweakVectorArray.append( tweakVector ); // Collect tweak connection data // // Parse down to the deepest level of the plug tree and check // for connections - look at the child nodes of the element plugs. // If any connections are found, record the connection and disconnect // it. // // ASSERT: The element plug should be compound! // MStatusAssert( (tweak.isCompound()), "tweak.isCompound() -- Element tweak plug is not compound" ); unsigned numChildren = tweak.numChildren(); for( j = 0; j < numChildren; j++ ) { tweakChild = tweak.child(j); if( tweakChild.isConnected() ) { // Get all connections with this plug as source, if they exist // tempPlugArray.clear(); if( tweakChild.connectedTo( tempPlugArray, false, true ) ) { unsigned numSrcConnections = tempPlugArray.length(); tweakSrcConnectionCountArray.append( numSrcConnections ); for( k = 0; k < numSrcConnections; k++ ) { tweakSrcConnectionPlugArray.append( tempPlugArray[k] ); fDGModifier.disconnect( tweakChild, tempPlugArray[k] ); } } else { tweakSrcConnectionCountArray.append(0); } // Get the connection with this plug as destination, if it exists // tempPlugArray.clear(); if( tweakChild.connectedTo( tempPlugArray, true, false ) ) { // ASSERT: tweakChild should only have one connection as destination! // MStatusAssert( (tempPlugArray.length() == 1), "tempPlugArray.length() == 1 -- 0 or >1 connections on tweakChild" ); tweakDstConnectionCountArray.append(1); tweakDstConnectionPlugArray.append( tempPlugArray[0] ); fDGModifier.disconnect( tempPlugArray[0], tweakChild ); } else { tweakDstConnectionCountArray.append(0); } } else { tweakSrcConnectionCountArray.append(0); tweakDstConnectionCountArray.append(0); } } } } // Apply meshTweakPlug data to our polyTweak node // MPlug polyTweakPlug( data.tweakNode, tweakNodeTweakAttr ); unsigned numTweaks = fTweakIndexArray.length(); int srcOffset = 0; int dstOffset = 0; //Progress initialisieren progressBar progress("Processing Tweaks", numTweaks); for( i = 0; i < numTweaks; i++ ) { // Apply tweak data // tweak = polyTweakPlug.elementByLogicalIndex( fTweakIndexArray[i] ); tweak.setValue( tweakDataArray[i] ); // ASSERT: Element plug should be compound! // MStatusAssert( (tweak.isCompound()), "tweak.isCompound() -- Element plug, 'tweak', is not compound" ); unsigned numChildren = tweak.numChildren(); for( j = 0; j < numChildren; j++ ) { tweakChild = tweak.child(j); // Apply tweak source connection data // if( 0 < tweakSrcConnectionCountArray[i*numChildren + j] ) { for( k = 0; k < (unsigned) tweakSrcConnectionCountArray[i*numChildren + j]; k++ ) { fDGModifier.connect( tweakChild, tweakSrcConnectionPlugArray[srcOffset] ); srcOffset++; } } // Apply tweak destination connection data // if( 0 < tweakDstConnectionCountArray[i*numChildren + j] ) { fDGModifier.connect( tweakDstConnectionPlugArray[dstOffset], tweakChild ); dstOffset++; } } if(i%50 == 0) { progress.set(i); } } // Now, set the tweak values on the meshNode(s) to zero (History dependent) // MFnNumericData numDataFn; MObject nullVector; // Create a NULL vector (0,0,0) using MFnNumericData to pass into the plug // numDataFn.create( MFnNumericData::k3Float ); numDataFn.setData( 0, 0, 0 ); nullVector = numDataFn.object(); for( i = 0; i < numTweaks; i++ ) { // Access using logical indices since they are the only plugs guaranteed // to hold tweak data. // tweak = meshTweakPlug.elementByLogicalIndex( fTweakIndexArray[i] ); tweak.setValue( nullVector ); } // Only have to clear the tweaks off the duplicate mesh if we do not have history // and we want history. // if( !fHasHistory && fHasRecordHistory ) { depNodeFn.setObject( data.upstreamNodeShape ); upstreamTweakPlug = depNodeFn.findPlug( "pnts" ); if( !upstreamTweakPlug.isNull() ) { for( i = 0; i < numTweaks; i++ ) { tweak = meshTweakPlug.elementByLogicalIndex( fTweakIndexArray[i] ); tweak.setValue( nullVector ); } } } } else fHasTweaks = false; return status; }
MStatus finalproject::compute(const MPlug& plug, MDataBlock& data) { // do this if we are using an OpenMP implementation that is not the same as Maya's. // Even if it is the same, it does no harm to make this call. MThreadUtils::syncNumOpenMPThreads(); MStatus status = MStatus::kUnknownParameter; if (plug.attribute() != outputGeom) { return status; } unsigned int index = plug.logicalIndex(); MObject thisNode = this->thisMObject(); // get input value MPlug inPlug(thisNode,input); inPlug.selectAncestorLogicalIndex(index,input); MDataHandle hInput = data.inputValue(inPlug, &status); MCheckStatus(status, "ERROR getting input mesh\n"); // get the input geometry MDataHandle inputData = hInput.child(inputGeom); if (inputData.type() != MFnData::kMesh) { printf("Incorrect input geometry type\n"); return MStatus::kFailure; } // get the input groupId - ignored for now... MDataHandle hGroup = inputData.child(groupId); unsigned int groupId = hGroup.asLong(); // get deforming mesh MDataHandle deformData = data.inputValue(deformingMesh, &status); MCheckStatus(status, "ERROR getting deforming mesh\n"); if (deformData.type() != MFnData::kMesh) { printf("Incorrect deformer geometry type %d\n", deformData.type()); return MStatus::kFailure; } MDataHandle offloadData = data.inputValue(offload, &status); //gathers world space positions of the object and the magnet MObject dSurf = deformData.asMeshTransformed(); MObject iSurf = inputData.asMeshTransformed(); MFnMesh fnDeformingMesh, fnInputMesh; fnDeformingMesh.setObject( dSurf ) ; fnInputMesh.setObject( iSurf ) ; MDataHandle outputData = data.outputValue(plug); outputData.copy(inputData); if (outputData.type() != MFnData::kMesh) { printf("Incorrect output mesh type\n"); return MStatus::kFailure; } MItGeometry iter(outputData, groupId, false); // get all points at once. Faster to query, and also better for // threading than using iterator MPointArray objVerts; iter.allPositions(objVerts); int objNumPoints = objVerts.length(); MPointArray magVerts, tempverts; fnDeformingMesh.getPoints(magVerts); fnInputMesh.getPoints(tempverts); int magNumPoints = magVerts.length(); double min = DBL_MAX, max = -DBL_MAX; //finds min and max z-coordinate values to determine middle point (choice of z-axis was ours) for (int i = 0; i < magNumPoints; i++) { min = magVerts[i].z < min ? magVerts[i].z : min; max = magVerts[i].z > max ? magVerts[i].z : max; } double middle = (min + max) / 2; double polarity[magNumPoints]; //assigns polarity based on middle point of mesh for (int i = 0; i < magNumPoints; i++) { polarity[i] = magVerts[i].z > middle ? max / magVerts[i].z : -min / magVerts[i].z; } double* objdVerts = (double *)malloc(sizeof(double) * objNumPoints * 3); double* magdVerts = (double *)malloc(sizeof(double) * magNumPoints * 3); //creates handles to use attribute data MDataHandle vecX = data.inputValue(transX, &status); MDataHandle vecY = data.inputValue(transY, &status); MDataHandle vecZ = data.inputValue(transZ, &status); //gathers previously stored coordinates of the center of the object double moveX = vecX.asFloat(); double moveY = vecY.asFloat(); double moveZ = vecZ.asFloat(); //translates object based on the position stored in the attribute values for (int i=0; i<objNumPoints; i++) { objdVerts[i * 3] = tempverts[i].x + moveX; objdVerts[i * 3 + 1] = tempverts[i].y + moveY; objdVerts[i * 3 + 2] = tempverts[i].z + moveZ; } for (int i=0; i<magNumPoints; i++) { magdVerts[i * 3] = magVerts[i].x; magdVerts[i * 3 + 1] = magVerts[i].y; magdVerts[i * 3 + 2] = magVerts[i].z; } double teslaData = data.inputValue(tesla, &status).asDouble(); MDataHandle posiData = data.inputValue(positivelycharged, &status); double pivot[6] = {DBL_MAX, -DBL_MAX, DBL_MAX, -DBL_MAX, DBL_MAX, -DBL_MAX}; //finds the pivot point of the object in world space prior to being affected by the magnet for (int i = 0; i < tempverts.length(); i++) { pivot[0] = tempverts[i].x < pivot[0] ? tempverts[i].x : pivot[0]; pivot[1] = tempverts[i].x > pivot[1] ? tempverts[i].x : pivot[1]; pivot[2] = tempverts[i].y < pivot[2] ? tempverts[i].y : pivot[2]; pivot[3] = tempverts[i].y > pivot[3] ? tempverts[i].y : pivot[3]; pivot[4] = tempverts[i].z < pivot[4] ? tempverts[i].z : pivot[4]; pivot[5] = tempverts[i].z > pivot[5] ? tempverts[i].z : pivot[5]; } MTimer timer; timer.beginTimer(); //main function call magnetForce(magNumPoints, objNumPoints, teslaData, magdVerts, objdVerts, polarity, posiData.asBool(), offloadData.asBool()); timer.endTimer(); printf("Runtime for threaded loop %f\n", timer.elapsedTime()); for (int i=0; i<objNumPoints; i++) { objVerts[i].x = objdVerts[i * 3 + 0]; objVerts[i].y = objdVerts[i * 3 + 1]; objVerts[i].z = objdVerts[i * 3 + 2]; } //finds the pivot point of object in world space after being affected by the magnet double objCenter[6] = {DBL_MAX, -DBL_MAX, DBL_MAX, -DBL_MAX, DBL_MAX, -DBL_MAX}; for (int i = 0; i < tempverts.length(); i++) { objCenter[0] = objVerts[i].x < objCenter[0] ? objVerts[i].x : objCenter[0]; objCenter[1] = objVerts[i].x > objCenter[1] ? objVerts[i].x : objCenter[1]; objCenter[2] = objVerts[i].y < objCenter[2] ? objVerts[i].y : objCenter[2]; objCenter[3] = objVerts[i].y > objCenter[3] ? objVerts[i].y : objCenter[3]; objCenter[4] = objVerts[i].z < objCenter[4] ? objVerts[i].z : objCenter[4]; objCenter[5] = objVerts[i].z > objCenter[5] ? objVerts[i].z : objCenter[5]; } //creates vector based on the two calculated pivot points moveX = (objCenter[0] + objCenter[1]) / 2 - (pivot[0] + pivot[1]) / 2; moveY = (objCenter[2] + objCenter[3]) / 2 - (pivot[2] + pivot[3]) / 2; moveZ = (objCenter[4] + objCenter[5]) / 2 - (pivot[4] + pivot[5]) / 2; //stores pivot vector for next computation if (teslaData) { vecX.setFloat(moveX); vecY.setFloat(moveY); vecZ.setFloat(moveZ); } // write values back onto output using fast set method on iterator iter.setAllPositions(objVerts, MSpace::kWorld); free(objdVerts); free(magdVerts); return status; }
MStatus proWater::compute(const MPlug& plug, MDataBlock& dataBlock) { MStatus status = MStatus::kUnknownParameter; if (plug.attribute() == outputGeom) { // get the input corresponding to this output // unsigned int index = plug.logicalIndex(); MObject thisNode = this->thisMObject(); MPlug inPlug(thisNode,input); inPlug.selectAncestorLogicalIndex(index,input); MDataHandle hInput = dataBlock.inputValue(inPlug); // get the input geometry and input groupId // MDataHandle hGeom = hInput.child(inputGeom); MDataHandle hGroup = hInput.child(groupId); unsigned int groupId = hGroup.asLong(); MDataHandle hOutput = dataBlock.outputValue(plug); hOutput.copy(hGeom); MStatus returnStatus; MDataHandle envData = dataBlock.inputValue(envelope, &returnStatus); if (MS::kSuccess != returnStatus) return returnStatus; float env = envData.asFloat(); MDataHandle timeData = dataBlock.inputValue(time, &returnStatus); if(MS::kSuccess != returnStatus) return returnStatus; double t = timeData.asDouble(); MDataHandle dirData = dataBlock.inputValue(dir, &returnStatus); if(MS::kSuccess != returnStatus) return returnStatus; double dirDeg = dirData.asDouble(); MDataHandle bigData = dataBlock.inputValue(bigFreq, &returnStatus); if(MS::kSuccess != returnStatus) return returnStatus; double bigFreqAmp = bigData.asDouble(); MDataHandle ampData = dataBlock.inputValue(amplitude1, &returnStatus); if(MS::kSuccess != returnStatus) return returnStatus; double amp1 = ampData.asDouble(); MDataHandle freqData = dataBlock.inputValue(frequency1, &returnStatus); if(MS::kSuccess != returnStatus) return returnStatus; double freq1 = freqData.asDouble(); MDataHandle ampData2 = dataBlock.inputValue(amplitude2, &returnStatus); if(MS::kSuccess != returnStatus) return returnStatus; double amp2 = ampData2.asDouble(); MDataHandle freqData2 = dataBlock.inputValue(frequency2, &returnStatus); if(MS::kSuccess != returnStatus) return returnStatus; double freq2 = freqData2.asDouble(); // Get the MFnMesh MStatus stat; MObject inputObj = hOutput.data(); MFnMesh * meshFn = new MFnMesh(inputObj, &stat); // do the deformation // MItGeometry iter(hOutput,groupId,false); for ( ; !iter.isDone(); iter.next()) { MPoint pt = iter.position(); //float2 uvPoint; //float u,v; //uvPoint[0] = u; //uvPoint[1] = v; //meshFn->getUVAtPoint(pt, uvPoint, MSpace::kObject); float u = pt.x; //uvPoint[0]*100; float v = pt.z; //uvPoint[1]*100; float degDir = dirDeg; float dir = degDir* M_PI/180; float dirX = cos(dir); float dirY = sin(dir); float bigFreq = 0.01; float bigWaves = scaled_raw_noise_3d(0, 1, (u + 3*t*dirX)*bigFreq*dirX, (v + 3*t*dirY)*bigFreq*dirY*2, t*0.01); float frequency1 = freq1/10;//0.2; float amplitude1 = amp1;//1.3; float firstOctave = -(std::abs(scaled_raw_noise_3d(-amplitude1, amplitude1, (float)(u + 0.7*t*dirX)*frequency1*0.4, (float)(v + 0.7*t*dirY)*frequency1*0.6, 0.05*t))-amplitude1); float frequency2 = freq2/10; float amplitude2 = amp2; float secondOctave = - (std::abs(scaled_raw_noise_3d(-amplitude2, amplitude2, (float)(u + 0.7*t*dirX)*frequency2*0.35, (float)(v + 0.7*t*dirY)*frequency2*0.65, 0.005*t))-amplitude2); float frequency3 = freq1/10; float amplitude3 = amp1/1.5; float thirdOctave = - (std::abs(scaled_raw_noise_3d(-amplitude3, amplitude3, (float)(u + t*0.5*dirX)*frequency3*0.4, (float)(v + t*0.5*dirY)*frequency3*0.6, 30))-amplitude3); float frequency4 = freq2/10; float amplitude4 = amp2/1.5; float fourthOctave = scaled_raw_noise_3d(-amplitude4, amplitude4, (float)(u + t*0.5*dirX)*frequency4*0.4, (float)(v + t*0.5*dirY)*frequency4*0.6, 50); float frequency5 = freq2; float amplitude5 = amp2/2; float fifthOctave = scaled_raw_noise_3d(-amplitude5, amplitude5, (float)(u + t*0.5*dirX)*frequency5*0.15, (float)(v + t*0.5*dirY)*frequency5*0.85, 0.001*t); float disp = bigFreqAmp*bigWaves + 7*(bigWaves)*firstOctave + secondOctave + thirdOctave*thirdOctave + fourthOctave + std::abs(bigWaves-1)*fifthOctave; pt = pt + iter.normal()*disp; iter.setPosition(pt); } delete meshFn; status = MStatus::kSuccess; } return status; }
MStatus splatDeformer::compute(const MPlug& plug, MDataBlock& data) { // do this if we are using an OpenMP implementation that is not the same as Maya's. // Even if it is the same, it does no harm to make this call. MThreadUtils::syncNumOpenMPThreads(); MStatus status = MStatus::kUnknownParameter; if (plug.attribute() != outputGeom) { return status; } unsigned int index = plug.logicalIndex(); MObject thisNode = this->thisMObject(); // get input value MPlug inPlug(thisNode,input); inPlug.selectAncestorLogicalIndex(index,input); MDataHandle hInput = data.inputValue(inPlug, &status); MCheckStatus(status, "ERROR getting input mesh\n"); // get the input geometry MDataHandle inputData = hInput.child(inputGeom); if (inputData.type() != MFnData::kMesh) { printf("Incorrect input geometry type\n"); return MStatus::kFailure; } // get the input groupId - ignored for now... MDataHandle hGroup = inputData.child(groupId); unsigned int groupId = hGroup.asLong(); // get deforming mesh MDataHandle deformData = data.inputValue(deformingMesh, &status); MCheckStatus(status, "ERROR getting deforming mesh\n"); if (deformData.type() != MFnData::kMesh) { printf("Incorrect deformer geometry type %d\n", deformData.type()); return MStatus::kFailure; } MObject dSurf = deformData.asMeshTransformed(); MFnMesh fnDeformingMesh; fnDeformingMesh.setObject( dSurf ) ; MDataHandle outputData = data.outputValue(plug); outputData.copy(inputData); if (outputData.type() != MFnData::kMesh) { printf("Incorrect output mesh type\n"); return MStatus::kFailure; } MItGeometry iter(outputData, groupId, false); // create fast intersector structure MMeshIntersector intersector; intersector.create(dSurf); // get all points at once. Faster to query, and also better for // threading than using iterator MPointArray verts; iter.allPositions(verts); int nPoints = verts.length(); // use bool variable as lightweight object for failure check in loop below bool failed = false; MTimer timer; timer.beginTimer(); #ifdef _OPENMP #pragma omp parallel for #endif for(int i=0; i<nPoints; i++) { // Cannot break out of an OpenMP loop, so if one of the // intersections failed, skip the rest if(failed) continue; // mesh point object must be in loop-local scope to avoid race conditions MPointOnMesh meshPoint; // Do intersection. Need to use per-thread status value as // MStatus has internal state and may trigger race conditions // if set from multiple threads. Probably benign in this case, // but worth being careful. MStatus localStatus = intersector.getClosestPoint(verts[i], meshPoint); if(localStatus != MStatus::kSuccess) { // NOTE - we cannot break out of an OpenMP region, so set // bad status and skip remaining iterations failed = true; continue; } // default OpenMP scheduling breaks traversal into large // chunks, so low risk of false sharing here in array write. verts[i] = meshPoint.getPoint(); } timer.endTimer(); printf("Runtime for threaded loop %f\n", timer.elapsedTime()); // write values back onto output using fast set method on iterator iter.setAllPositions(verts); if(failed) { printf("Closest point failed\n"); return MStatus::kFailure; } return status; }
MStatus sweptEmitter::compute(const MPlug& plug, MDataBlock& block) // // Descriptions: // Call emit emit method to generate new particles. // { MStatus status; // Determine if we are requesting the output plug for this emitter node. // if( !(plug == mOutput) ) return( MS::kUnknownParameter ); // Get the logical index of the element this plug refers to, // because the node can be emitting particles into more // than one particle shape. // int multiIndex = plug.logicalIndex( &status ); McheckErr(status, "ERROR in plug.logicalIndex.\n"); // Get output data arrays (position, velocity, or parentId) // that the particle shape is holding from the previous frame. // MArrayDataHandle hOutArray = block.outputArrayValue(mOutput, &status); McheckErr(status, "ERROR in hOutArray = block.outputArrayValue.\n"); // Create a builder to aid in the array construction efficiently. // MArrayDataBuilder bOutArray = hOutArray.builder( &status ); McheckErr(status, "ERROR in bOutArray = hOutArray.builder.\n"); // Get the appropriate data array that is being currently evaluated. // MDataHandle hOut = bOutArray.addElement(multiIndex, &status); McheckErr(status, "ERROR in hOut = bOutArray.addElement.\n"); // Get the data and apply the function set. // MFnArrayAttrsData fnOutput; MObject dOutput = fnOutput.create ( &status ); McheckErr(status, "ERROR in fnOutput.create.\n"); // Check if the particle object has reached it's maximum, // hence is full. If it is full then just return with zero particles. // bool beenFull = isFullValue( multiIndex, block ); if( beenFull ) { return( MS::kSuccess ); } // Get deltaTime, currentTime and startTime. // If deltaTime <= 0.0, or currentTime <= startTime, // do not emit new pariticles and return. // MTime cT = currentTimeValue( block ); MTime sT = startTimeValue( multiIndex, block ); MTime dT = deltaTimeValue( multiIndex, block ); if( (cT <= sT) || (dT <= 0.0) ) { // We do not emit particles before the start time, // and do not emit particles when moving backwards in time. // // This code is necessary primarily the first time to // establish the new data arrays allocated, and since we have // already set the data array to length zero it does // not generate any new particles. // hOut.set( dOutput ); block.setClean( plug ); return( MS::kSuccess ); } // Get speed, direction vector, and inheritFactor attributes. // double speed = speedValue( block ); MVector dirV = directionVector( block ); double inheritFactor = inheritFactorValue( multiIndex, block ); // Get the position and velocity arrays to append new particle data. // MVectorArray fnOutPos = fnOutput.vectorArray("position", &status); MVectorArray fnOutVel = fnOutput.vectorArray("velocity", &status); // Convert deltaTime into seconds. // double dt = dT.as( MTime::kSeconds ); // Apply rotation to the direction vector MVector rotatedV = useRotation ( dirV ); // position, MVectorArray inPosAry; // velocity MVectorArray inVelAry; // emission rate MIntArray emitCountPP; // Get the swept geometry data // MObject thisObj = this->thisMObject(); MPlug sweptPlug( thisObj, mSweptGeometry ); if ( sweptPlug.isConnected() ) { MDataHandle sweptHandle = block.inputValue( mSweptGeometry ); // MObject sweptData = sweptHandle.asSweptGeometry(); MObject sweptData = sweptHandle.data(); MFnDynSweptGeometryData fnSweptData( sweptData ); // Curve emission // if (fnSweptData.lineCount() > 0) { int numLines = fnSweptData.lineCount(); for ( int i=0; i<numLines; i++ ) { inPosAry.clear(); inVelAry.clear(); emitCountPP.clear(); MDynSweptLine line = fnSweptData.sweptLine( i ); // ... process current line ... MVector p1 = line.vertex( 0 ); MVector p2 = line.vertex( 1 ); inPosAry.append( p1 ); inPosAry.append( p2 ); inVelAry.append( MVector( 0,0,0 ) ); inVelAry.append( MVector( 0,0,0 ) ); // emit Rate for two points on line emitCountPP.clear(); status = emitCountPerPoint( plug, block, 2, emitCountPP ); emit( inPosAry, inVelAry, emitCountPP, dt, speed, inheritFactor, rotatedV, fnOutPos, fnOutVel ); } } // Surface emission (nurb or polygon) // if (fnSweptData.triangleCount() > 0) { int numTriangles = fnSweptData.triangleCount(); for ( int i=0; i<numTriangles; i++ ) { inPosAry.clear(); inVelAry.clear(); emitCountPP.clear(); MDynSweptTriangle tri = fnSweptData.sweptTriangle( i ); // ... process current triangle ... MVector p1 = tri.vertex( 0 ); MVector p2 = tri.vertex( 1 ); MVector p3 = tri.vertex( 2 ); MVector center = p1 + p2 + p3; center /= 3.0; inPosAry.append( center ); inVelAry.append( MVector( 0,0,0 ) ); // emit Rate for two points on line emitCountPP.clear(); status = emitCountPerPoint( plug, block, 1, emitCountPP ); emit( inPosAry, inVelAry, emitCountPP, dt, speed, inheritFactor, rotatedV, fnOutPos, fnOutVel ); } } } // Update the data block with new dOutput and set plug clean. // hOut.set( dOutput ); block.setClean( plug ); return( MS::kSuccess ); }
MStatus sseDeformer::compute(const MPlug& plug, MDataBlock& data) { MStatus status; if (plug.attribute() != outputGeom) { printf("Ignoring requested plug\n"); return status; } unsigned int index = plug.logicalIndex(); MObject thisNode = this->thisMObject(); // get input value MPlug inPlug(thisNode,input); inPlug.selectAncestorLogicalIndex(index,input); MDataHandle hInput = data.inputValue(inPlug, &status); MCheckStatus(status, "ERROR getting input mesh\n"); // get the input geometry MDataHandle inputData = hInput.child(inputGeom); if (inputData.type() != MFnData::kMesh) { printf("Incorrect input geometry type\n"); return MStatus::kFailure; } MObject iSurf = inputData.asMesh() ; MFnMesh inMesh; inMesh.setObject( iSurf ) ; MDataHandle outputData = data.outputValue(plug); outputData.copy(inputData); if (outputData.type() != MFnData::kMesh) { printf("Incorrect output mesh type\n"); return MStatus::kFailure; } MObject oSurf = outputData.asMesh() ; if(oSurf.isNull()) { printf("Output surface is NULL\n"); return MStatus::kFailure; } MFnMesh outMesh; outMesh.setObject( oSurf ) ; MCheckStatus(status, "ERROR setting points\n"); // get all points at once for demo purposes. Really should get points from the current group using iterator MFloatPointArray pts; outMesh.getPoints(pts); int nPoints = pts.length(); MDataHandle envData = data.inputValue(envelope, &status); float env = envData.asFloat(); MDataHandle sseData = data.inputValue(sseEnabled, &status); bool sseEnabled = (bool) sseData.asBool(); // NOTE: Using MTimer and possibly other classes disables // autovectorization with Intel <=10.1 compiler on OSX and Linux!! // Must compile this function with -fno-exceptions on OSX and // Linux to guarantee autovectorization is done. Use -fvec_report2 // to check for vectorization status messages with Intel compiler. MTimer timer; timer.beginTimer(); if(sseEnabled) { // Innter loop will autovectorize. Around 3x faster than the // loop below it. It would be faster if first element was // guaranteed to be aligned on 16 byte boundary. for(int i=0; i<nPoints; i++) { float* ptPtr = &pts[i].x; for(int j=0; j<4; j++) { ptPtr[j] = env * (cosf(ptPtr[j]) * sinf(ptPtr[j]) * tanf(ptPtr[j])); } } } else { // This inner loop will not autovectorize. for(int i=0; i<nPoints; i++) { MFloatPoint& pt = pts[i]; for(int j=0; j<3; j++) { pt[j] = env * (cosf(pt[j]) * sinf(pt[j]) * tanf(pt[j])); } } } timer.endTimer(); if(sseEnabled) { printf("SSE enabled, runtime %f\n", timer.elapsedTime()); } else { printf("SSE disabled, runtime %f\n", timer.elapsedTime()); } outMesh.setPoints(pts); return status; }
MStatus vixo_visImport::compute( const MPlug& plug, MDataBlock& data ) { MStatus stat=MS::kSuccess; if(plug.array()!=vis) return MS::kSuccess; //cout<<plug.info().asChar()<<endl; int objIdx=plug.logicalIndex(); MDataHandle file_handle=data.inputValue(file); MString filename=file_handle.asString(); MDataHandle timeHandle=data.inputValue(time); int t=timeHandle.asTime().as(MTime::Unit::kFilm); if(mapObjName.count(objIdx)<=0) return MS::kSuccess; //cout<<"test"<<endl; MString objNameValue(mapObjName.find(objIdx)->second.c_str()); bool res=true; ifstream fin(filename.asChar(),ios_base::in|ios_base::binary); if(fin.fail()) { MDataHandle eleHandle=data.outputValue(plug); eleHandle.set(res); data.setClean(plug); return MS::kSuccess; } int objNum=0; fin.read((char*)&objNum,sizeof(int)); vector<struct_visBasicInfo> objIndexes(objNum); fin.read((char*)&objIndexes[0],sizeof(struct_visBasicInfo)*objNum); int fileObjIndex=-1; for(int i=0;i<objNum;i++) { MStringArray tempArr; MString tempStr(objIndexes[i].objName); tempStr.split(':',tempArr); if(tempArr[tempArr.length()-1]==objNameValue) { fileObjIndex=i; break; } } if(fileObjIndex==-1) { MDataHandle eleHandle=data.outputValue(plug); eleHandle.set(res); data.setClean(plug); fin.close(); return MS::kSuccess; } //cout<<"test1"<<endl; if(t<objIndexes[fileObjIndex].startFrame||t>objIndexes[fileObjIndex].endFrame) { fin.close(); MDataHandle eleHandle=data.outputValue(plug); eleHandle.set(res); data.setClean(plug); return MS::kSuccess; } //cout<<"test2"<<endl; fin.seekg(objIndexes[fileObjIndex].visBegin.operator+(sizeof(char)*(t-objIndexes[fileObjIndex].startFrame))); char value; fin.read((char *)&value,sizeof(char)); fin.close(); //cout<<t<<" "<<(int)value<<endl; if(value==0) res=0; MDataHandle eleHandle=data.outputValue(plug); eleHandle.set(res); data.setClean(plug); return MS::kSuccess; }
MStatus HesMeshNode::compute( const MPlug& plug, MDataBlock& data ) { MStatus stat; MPlug pnames(thisMObject(), ameshname); const unsigned numMeshes = pnames.numElements(); MString cacheName = data.inputValue( input ).asString(); std::string substitutedCacheName(cacheName.asChar()); EnvVar::replace(substitutedCacheName); MArrayDataHandle meshNameArray = data.inputArrayValue( ameshname ); MArrayDataHandle meshArry = data.outputArrayValue(outMesh, &stat); bool hesStat = false; if( plug.array() == outMesh ) { const unsigned idx = plug.logicalIndex(); if(BaseUtil::IsImporting) hesStat = true; else { if(idx == 0) AHelper::Info<std::string>(" hes mesh open file ", substitutedCacheName ); hesStat = BaseUtil::OpenHes(substitutedCacheName, HDocument::oReadOnly); } if(!hesStat) { AHelper::Info<std::string >("hes mesh cannot open file ", substitutedCacheName); return MS::kFailure; } meshNameArray.jumpToElement(idx); const MString meshName = meshNameArray.inputValue().asString(); if(!BaseUtil::HesDoc->find(meshName.asChar())) { AHelper::Info<MString>(" hes cannot find mesh ", meshName ); return MS::kFailure; } meshArry.jumpToElement(idx); MDataHandle hmesh = meshArry.outputValue(); HPolygonalMesh entryMesh(meshName.asChar() ); APolygonalMesh dataMesh; entryMesh.load(&dataMesh); entryMesh.close(); MFnMeshData dataCreator; MObject outMeshData = dataCreator.create(&stat); if( !stat ) { MGlobal::displayWarning("hes mesh cannot create " + meshName); return MS::kFailure; } AHelper::Info<MString>(" hes init mesh ", meshName); HesperisPolygonalMeshCreator::create(&dataMesh, outMeshData); hmesh.set(outMeshData); data.setClean(plug); if( (idx+1)>=numMeshes ) { if(!BaseUtil::IsImporting) { AHelper::Info<std::string>(" hes mesh close file ", substitutedCacheName ); BaseUtil::CloseHes(); } } } else { return MS::kUnknownParameter; } return MS::kSuccess; }
// -------------------------------------------------------------------------------------------- MStatus polyModifierCmd::cacheMeshTweaks() // -------------------------------------------------------------------------------------------- { MStatus status = MS::kSuccess; // Clear tweak undo information (to be rebuilt) // fTweakIndexArray.clear(); fTweakVectorArray.clear(); // Extract the tweaks and store them in our local tweak cache members // if( fHasTweaks ) { // Declare our function sets // MFnDependencyNode depNodeFn; MObject meshNode = fDagPath.node(); MPlug meshTweakPlug; // Declare our tweak processing variables // MPlug tweak; MPlug tweakChild; MObject tweakData; MObjectArray tweakDataArray; MFloatVector tweakVector; MPlugArray tempPlugArray; unsigned i; depNodeFn.setObject( meshNode ); meshTweakPlug = depNodeFn.findPlug( "pnts" ); // ASSERT: meshTweakPlug should be an array plug! // MStatusAssert( (meshTweakPlug.isArray()), "meshTweakPlug.isArray() -- meshTweakPlug is not an array plug" ); unsigned numElements = meshTweakPlug.numElements(); // Gather meshTweakPlug data // for( i = 0; i < numElements; i++ ) { // MPlug::numElements() only returns the number of physical elements // in the array plug. Thus we must use elementByPhysical index when using // the index i. // tweak = meshTweakPlug.elementByPhysicalIndex(i); // If the method fails, the element is NULL. Only append the index // if it is a valid plug. // if( !tweak.isNull() ) { // Cache the logical index of this element plug // unsigned logicalIndex = tweak.logicalIndex(); // Collect tweak data and cache the indices and float vectors // getFloat3PlugValue( tweak, tweakVector ); fTweakIndexArray.append( logicalIndex ); fTweakVectorArray.append( tweakVector ); } } } return status; }