MManipData V3Manipulator::vectorManipToPlugConversion( unsigned int plugIndex ) { MFnFreePointTriadManip translateFn( m_translateManip ); MPoint t; getConverterManipValue( translateFn.pointIndex(), t ); t = t * m_localMatrixInv; MFnNumericData numericData; MObject returnData; // We have to check what type of data to generate so Maya // will be able to set it back into the attribute correctly. MFnNumericAttribute attr( m_translatePlug.attribute() ); if( attr.unitType() == MFnNumericData::k3Float ) { returnData = numericData.create( MFnNumericData::k3Float ); numericData.setData( float(t.x), float(t.y), float(t.z) ); } else { returnData = numericData.create( MFnNumericData::k3Double ); numericData.setData( t.x, t.y, t.z ); } return MManipData( returnData ); }
MManipData componentScaleManip::plugToManipConversion(unsigned index) { MObject obj = MObject::kNullObj; // If we entered the callback with an invalid index, print an error and // return. Since we registered the callback only for one index, all // invocations of the callback should be for that index. // MFnScaleManip scaleManip(fScaleManip); if (index == scaleManip.scaleCenterIndex()) { // Set the center point for scaling to the centroid of the CV's. // MFnNumericData numericData; obj = numericData.create( MFnNumericData::k3Double ); numericData.setData(centroid.x,centroid.y,centroid.z); return MManipData(obj); } MGlobal::displayError("Invalid index in plugToManipConversion()!"); // For invalid indices, return vector of 0's MFnNumericData numericData; obj = numericData.create( MFnNumericData::k3Double ); numericData.setData(0.0,0.0,0.0); return obj; }
MManipData componentScaleManip::manipToPlugConversion(unsigned index) { MObject obj = MObject::kNullObj; MFnScaleManip scaleManip(fScaleManip); if (index < (unsigned)numComponents) { // // Now we need to determine the scaled position of the CV specified by // index. // MVector scaleVal; getConverterManipValue(scaleManip.scaleIndex(), scaleVal); // Determine the vector from the centroid to the CV // MVector positionVec = initialPositions[index] - centroid; // Scale the vector // MVector newPosition(positionVec.x*scaleVal.x, positionVec.y*scaleVal.y, positionVec.z*scaleVal.z); // Form the vector from the initial position to the new position. // newPosition = newPosition - positionVec; // Move the control point from the initial control point position along // the vector. Control point positions are always measured relative to // the initial position of the control point, which is why a separate // array of control point positions is required. // newPosition += initialControlPoint[index]; MFnNumericData numericData; obj = numericData.create( MFnNumericData::k3Double ); numericData.setData(newPosition.x,newPosition.y,newPosition.z); return MManipData(obj); } // If we entered the handler with an invalid index, print an error and // return. The callback should only be called for indices from 0 to // numComponents-1. // MGlobal::displayError("Invalid index in scale changed callback!"); // For invalid indices, return vector of 0's MFnNumericData numericData; obj = numericData.create( MFnNumericData::k3Double ); numericData.setData(0.0,0.0,0.0); return obj; }
//--------------------------------------------------- bool DagHelper::setPlugValue ( MPlug& plug, float x, float y ) { MFnNumericData data; MObject obj = data.create ( MFnNumericData::k2Float ); data.setData ( x, y ); return plug.setValue ( obj ); }
MStatus PRTAttrs::addColorParameter(MFnDependencyNode & node, MObject & attr, const MString & name, MString & value ) { MStatus stat; MFnNumericAttribute nAttr; const wchar_t* s = value.asWChar(); attr = nAttr.createColor(longName(name), briefName(name), &stat ); MCHECK(stat); double r = 0.0; double g = 0.0; double b = 0.0; if (s[0] == '#' && wcslen(s) >= 7) { r = (double)((prtu::fromHex(s[1]) << 4) + prtu::fromHex(s[2])) / 255.0; g = (double)((prtu::fromHex(s[3]) << 4) + prtu::fromHex(s[4])) / 255.0; b = (double)((prtu::fromHex(s[5]) << 4) + prtu::fromHex(s[6])) / 255.0; nAttr.setDefault(r, g, b); } MCHECK(addParameter(node, attr, nAttr)); MFnNumericData fnData; MObject rgb = fnData.create(MFnNumericData::k3Double, &stat); MCHECK(stat); fnData.setData(r, g, b); MPlug plug(node.object(), attr); MCHECK(plug.setValue(rgb)); return MS::kSuccess; }
// -------------------------------------------------------------------------------------------- void polyModifierCmd::deleteTweaks() // -------------------------------------------------------------------------------------------- { // Now, set the tweak values on the meshNode(s) to zero (History dependent) // MStatus stat; MFnNumericData numDataFn; MObject nullVector; // Create a NULL vector (0,0,0) using MFnNumericData to pass into the plug // MFnDependencyNode depTmpFn(fDagPath.node(),&stat); //stat.perror(""); MPlug meshTweakPlug = depTmpFn.findPlug("pnts"); numDataFn.create( MFnNumericData::k3Float ); numDataFn.setData( 0, 0, 0 ); nullVector = numDataFn.object(); unsigned numTweaks = meshTweakPlug.numElements(); MPlug tweak; for(unsigned i = 0; i < numTweaks; i++ ) { // Access using logical indices since they are the only plugs guaranteed // to hold tweak data. // tweak = meshTweakPlug.elementByPhysicalIndex(i); tweak.setValue( nullVector ); } }
//############################################### tima: bool polyModifierCmd::setZeroTweaks() { MFnNumericData numDataFn; MObject nullVector; MFnDependencyNode depNodeFn; numDataFn.create( MFnNumericData::k3Float ); numDataFn.setData( 0, 0, 0 ); nullVector = numDataFn.object(); MObject object = fDagPath.node(); depNodeFn.setObject( object); MPlug meshTweakPlug = depNodeFn.findPlug( "pnts" ); MPlug tweak; unsigned numTweaks = fTweakIndexArray.length(); if( !meshTweakPlug.isNull() ) { for( unsigned i = 0; i < numTweaks; i++ ) { tweak = meshTweakPlug.elementByLogicalIndex( fTweakIndexArray[i] ); tweak.setValue( nullVector ); } } return true; }
MStatus polyModifierCmd::getFloat3asMObject( MFloatVector value, MObject& object ) { // Convert the float value into an MObject // MFnNumericData numDataFn; numDataFn.create( MFnNumericData::k3Float ); numDataFn.setData( value[0], value[1], value[2] ); object = numDataFn.object(); return MS::kSuccess; }
MManipData V3Manipulator::vectorPlugToManipConversion( unsigned int manipIndex ) { MFnFreePointTriadManip translateFn( m_translateManip ); MFnNumericData numericData; MObject returnData = numericData.create( MFnNumericData::k3Double ); numericData.setData( 0.0, 0.0, 0.0 ); MPoint p = getPlugValues( m_translatePlug ) * m_localMatrix; numericData.setData( p.x, p.y, p.z ); return MManipData( returnData ); }
MManipData swissArmyLocatorManip::startPointCallback(unsigned /*index*/) const { MManipData manipData; MFnNumericData numData; MObject numDataObj = numData.create(MFnNumericData::k3Double); MVector vec = nodeTranslation(); numData.setData(vec.x, vec.y, vec.z); manipData = numDataObj; return manipData; }
//--------------------------------------------------- bool DagHelper::setPlugValue ( MPlug& plug, const MVector& value ) { MStatus status; MFnNumericData dataCreator; MObject float3Data = dataCreator.create ( MFnNumericData::k3Float, &status ); if ( status != MStatus::kSuccess ) return false; dataCreator.setData ( ( float ) value.x, ( float ) value.y, ( float ) value.z ); status = plug.setValue ( float3Data ); if ( status != MStatus::kSuccess ) return false; return true; }
MStatus geometrySurfaceConstraintCommand::connectObjectAndConstraint( MDGModifier& modifier ) { MObject transform = transformObject(); if ( transform.isNull() ) { MGlobal::displayError("Failed to get transformObject()"); return MS::kFailure; } MStatus status; MFnTransform transformFn( transform ); MVector translate = transformFn.getTranslation(MSpace::kTransform,&status); if (!status) { status.perror(" transformFn.getTranslation"); return status;} MPlug translatePlug = transformFn.findPlug( "translate", &status ); if (!status) { status.perror(" transformFn.findPlug"); return status;} if ( MPlug::kFreeToChange == translatePlug.isFreeToChange() ) { MFnNumericData nd; MObject translateData = nd.create( MFnNumericData::k3Double, &status ); status = nd.setData3Double( translate.x,translate.y,translate.z); if (!status) { status.perror("nd.setData3Double"); return status;} status = modifier.newPlugValue( translatePlug, translateData ); if (!status) { status.perror("modifier.newPlugValue"); return status;} status = connectObjectAttribute( MPxTransform::geometry, geometrySurfaceConstraint::constraintGeometry, false ); if (!status) { status.perror("connectObjectAttribute"); return status;} } status = connectObjectAttribute( MPxTransform::parentInverseMatrix, geometrySurfaceConstraint::constraintParentInverseMatrix, true, true ); if (!status) { status.perror("connectObjectAttribute"); return status;} return MS::kSuccess; }
//- This method is plugToManipConversionCallback function //- You implement it so that a specific component of the manipulator //- will be modified automatically when some plug value changes on //- the custom locator. //- Arguments: //- manipIndex - the index of the component on the manip you want to affect, //- in this case, it is the center point of this manip //- Return Values: //- MManipData object, which represents the updated value MManipData arrowLocatorManip::centerPointCallback(unsigned int manipIndex) { MStatus status; //Get parent transform node of the locator node MObject parentTransform = fNodePath.transform(&status); //Get the transform node DAG path MDagPath transformPath; MDagPath::getAPathTo(parentTransform,transformPath); //Retrieve world space translation MFnTransform fnTrans(transformPath,&status); MVector translation = fnTrans.getTranslation(MSpace::kWorld,&status); MFnNumericData numData; MObject numDataValue = numData.create(MFnNumericData::k3Double,&status); status = numData.setData3Double(translation.x,translation.y,translation.z); MManipData manipData(numDataValue); return manipData; }
// -------------------------------------------------------------------------------------------- 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; }
MManipData exampleRotateManip::rotationChangedCallback(unsigned index) { static MEulerRotation cache; MObject obj = MObject::kNullObj; // If we entered the callback with an invalid index, print an error and // return. Since we registered the callback only for one plug, all // invocations of the callback should be for that plug. // if (index != rotatePlugIndex) { MGlobal::displayError("Invalid index in rotation changed callback!"); // For invalid indices, return vector of 0's MFnNumericData numericData; obj = numericData.create( MFnNumericData::k3Double ); numericData.setData(0.0,0.0,0.0); return obj; } // Assign function sets to the manipulators // MFnStateManip stateManip(fStateManip); MFnRotateManip rotateManip(fRotateManip); // Adjust settings on the rotate manip based on the state of the state // manip. // int mode = stateManip.state(); if (mode != 3) { rotateManip.setRotateMode((MFnRotateManip::RotateMode) stateManip.state()); rotateManip.setSnapMode(false); } else { // State 3 enables snapping for an object space manip. In this case, // we snap every 15.0 degrees. // rotateManip.setRotateMode(MFnRotateManip::kObjectSpace); rotateManip.setSnapMode(true); rotateManip.setSnapIncrement(15.0); } // The following code creates a data object to be returned in the // MManipData. In this case, the plug to be computed must be a 3-component // vector, so create data as MFnNumericData::k3Double // MFnNumericData numericData; obj = numericData.create( MFnNumericData::k3Double ); // Retrieve the value for the rotation from the manipulator and return it // directly without modification. If the manipulator should eg. slow down // rotation, this method would need to do some math with the value before // returning it. // MEulerRotation manipRotation; if (!getConverterManipValue (rotateManip.rotationIndex(), manipRotation)) { MGlobal::displayError("Error retrieving manip value"); numericData.setData(0.0,0.0,0.0); } else { numericData.setData(manipRotation.x, manipRotation.y, manipRotation.z); } return MManipData(obj); }