// The compute() method does the actual work of the node using the inputs // of the node to generate its output. // // Compute takes two parameters: plug and data. // - Plug is the the data value that needs to be recomputed // - Data provides handles to all of the nodes attributes, only these // handles should be used when performing computations. // MStatus affects::compute( const MPlug& plug, MDataBlock& data ) { MStatus status; MObject thisNode = thisMObject(); MFnDependencyNode fnThisNode( thisNode ); fprintf(stderr,"affects::compute(), plug being computed is \"%s\"\n", plug.name().asChar()); if ( plug.partialName() == "B" ) { // Plug "B" is being computed. Assign it the value on plug "A" // if "A" exists. // MPlug pA = fnThisNode.findPlug( "A", &status ); if ( MStatus::kSuccess == status ) { fprintf(stderr,"\t\t... found dynamic attribute \"A\", copying its value to \"B\"\n"); MDataHandle inputData = data.inputValue( pA, &status ); CHECK_MSTATUS( status ); int value = inputData.asInt(); MDataHandle outputHandle = data.outputValue( plug ); outputHandle.set( value ); data.setClean(plug); } } else { return MS::kUnknownParameter; } return( MS::kSuccess ); }
MStatus vixo_visImport::setDependentsDirty( const MPlug &plugBeingDirtied,MPlugArray &affectedPlugs ) { MStatus status; MObject thisNode = thisMObject(); if ( plugBeingDirtied.partialName() == "t" || plugBeingDirtied.partialName() == "f") { MPlug arrayVis(thisNode,this->vis); //affectedPlugs.append(arrayVis); //cout<<"idr"<<arrayVis.numElements()<<endl; for(int i=0;i<arrayVis.numElements();i++) { affectedPlugs.append(arrayVis.elementByLogicalIndex(i)); } } return( MS::kSuccess ); }
IECore::ParameterPtr ParameterisedHolder<B>::plugParameter( const MPlug &plug ) { assert( ! plug.isNull() ); // to update the parameter->name map if necessary getParameterised(); AttributeNameToParameterMap::const_iterator it = m_attributeNamesToParameters.find( plug.partialName() ); if( it==m_attributeNamesToParameters.end() ) { return 0; } return it->second; }
void ParameterisedHolderModificationCmd::despatchClassSetCallbacks() const { MFnDependencyNode fnNode( m_node ); MString nodeName = fnNode.name(); MFnDagNode fnDN( m_node ); if( fnDN.hasObj( m_node ) ) { nodeName = fnDN.fullPathName(); } ParameterisedInterface *parameterised = m_parameterisedHolder->getParameterisedInterface(); std::set<IECore::InternedString> names; for( IECore::CompoundDataMap::const_iterator it=m_originalClasses->readable().begin(); it!=m_originalClasses->readable().end(); it++ ) { names.insert( it->first ); } for( IECore::CompoundDataMap::const_iterator it=m_newClasses->readable().begin(); it!=m_newClasses->readable().end(); it++ ) { names.insert( it->first ); } for( std::set<IECore::InternedString>::const_iterator it=names.begin(); it!=names.end(); it++ ) { Parameter *parameter = parameterFromPath( parameterised, *it ); if( parameter ) { IECore::CompoundDataMap::const_iterator it1 = m_originalClasses->readable().find( *it ); IECore::CompoundDataMap::const_iterator it2 = m_newClasses->readable().find( *it ); if( it1==m_originalClasses->readable().end() || it2==m_newClasses->readable().end() || !(it1->second->isEqualTo( it2->second.get() ) ) ) { MPlug parameterPlug = m_parameterisedHolder->parameterPlug( parameter ); MString plugName = nodeName + "." + parameterPlug.partialName(); if( parameter->isInstanceOf( "ClassParameter" ) ) { MGlobal::executePythonCommand( "import IECoreMaya; IECoreMaya.FnParameterisedHolder._despatchSetClassParameterClassCallbacks( \"" + plugName + "\" )" ); } else { MGlobal::executePythonCommand( "import IECoreMaya; IECoreMaya.FnParameterisedHolder._despatchSetClassVectorParameterClassesCallbacks( \"" + plugName + "\" )" ); } } } } }
MObject getOtherSideNode(MString& plugName, MObject& thisObject, MString& otherSidePlugName) { MStatus stat; MObject result = MObject::kNullObj; MFnDependencyNode depFn(thisObject, &stat); if( stat != MStatus::kSuccess) return result; MPlug plug = depFn.findPlug(plugName, &stat); if( stat != MStatus::kSuccess)return result; if( !plug.isConnected() ) return result; MPlugArray plugArray; plug.connectedTo(plugArray, 1, 0, &stat);if( stat != MStatus::kSuccess) return result; if( plugArray.length() == 0) return result; MPlug otherSidePlug = plugArray[0]; result = otherSidePlug.node(); otherSidePlugName = otherSidePlug.name(); otherSidePlugName = otherSidePlug.partialName(false, false, false, false, false, true); return result; }
bool atomImport::checkPlugAgainstTemplate(const MString& nodeName, const MPlug& plug, atomTemplateReader* templateReader) { // Check if the plug is filtered out // if (NULL != templateReader) { // get long attribute name MString plugName = plug.partialName(true,false,false,false,false,true); MStringArray nameParts; plugName.split('.', nameParts); MString leafAttr = nameParts[nameParts.length()-1]; return (templateReader->findNodeAndAttr(nodeName,leafAttr)); } // No template, nothing to do // return true; }
MStatus OpHolder<B>::setDependentsDirty( const MPlug &plug, MPlugArray &plugArray ) { /// This isn't the best way of doing it, but at this point we can't even be sure that the Op has been loaded, /// so calling plugParameter() may not work. We can't call getOp() or getParameterised() here, as it seems /// we can't do things such as adding/removing attributes within this function if( std::string( plug.partialName().substring( 0, 4 ).asChar() ) == ParameterisedHolder<B>::g_attributeNamePrefix || plug==aResultDependency ) { MFnDependencyNode fnDN( B::thisMObject() ); MStatus s; MPlug resultPlug = fnDN.findPlug( "result" , &s); if ( s && !resultPlug.isNull() ) { plugArray.append( resultPlug ); } } return ParameterisedHolder<B>::setDependentsDirty( plug, plugArray ); }
MObject getOtherSideNode(const MString& plugName, MObject& thisObject, MStringArray& otherSidePlugNames) { MStatus stat; MObject result = MObject::kNullObj; MFnDependencyNode depFn(thisObject, &stat); if (stat != MStatus::kSuccess) return result; MPlug plug = depFn.findPlug(plugName, &stat); if (stat != MStatus::kSuccess)return result; if (!plug.isConnected()) { int numChildConnects = plug.numConnectedChildren(); if (numChildConnects == 0) return result; else { for (int i = 0; i < numChildConnects; i++) { MPlug child = plug.child(i); MString otherSidePlugName; MObject childObj = getOtherSideNode(child.partialName(false), thisObject, otherSidePlugName); if (childObj != MObject::kNullObj) { otherSidePlugNames.append(otherSidePlugName); result = childObj; } else otherSidePlugNames.append(MString("")); } } } else { MPlugArray plugArray; plug.connectedTo(plugArray, 1, 0, &stat); if (stat != MStatus::kSuccess) return result; if (plugArray.length() == 0) return result; MPlug otherSidePlug = plugArray[0]; result = otherSidePlug.node(); otherSidePlugNames.append(otherSidePlug.name()); } return result; }
//setDependentsDirty //----------------------------------------------- MStatus Ocio_test::setDependentsDirty(const MPlug& plugBeingDirtied, MPlugArray& affectedPlugs) { MStatus status; MObject node = thisMObject(); MFnDependencyNode fn_dep_node(node); if(plugBeingDirtied.partialName() == "input_colorspace") { MPlug p_output = fn_dep_node.findPlug( "output_color", &status ); if(MStatus::kSuccess == status) { CHECK_MSTATUS(affectedPlugs.append(p_output)); MGlobal::displayInfo("Plug output appended"); } } return MStatus::kSuccess; };
// The setDependentsDirty() method allows attributeAffects relationships // in a much more general way than via MPxNode::attributeAffects // which is limited to static attributes only. // The setDependentsDirty() method allows relationships to be established // between any combination of dynamic and static attributes. // // Within a setDependentsDirty() implementation you get passed in the // plug which is being set dirty, and then, based upon which plug it is, // you may choose to dirty any other plugs by adding them to the // affectedPlugs list. // // In almost all cases, the relationships you set up will be fixed for // the duration of Maya, such as "A affects B". However, you can also // set up relationships which depend upon some external factor, such // as the current frame number, the time of day, if maya was invoked in // batch mode, etc. These sorts of relationships are straightforward to // implement in your setDependentsDirty() method. // // There may also be situations where you need to look at values in the // dependency graph. It is VERY IMPORTANT that when accessing DG values // you do not cause a DG evaluation. This is because your setDependentsDirty() // method is called during dirty processing and causing an evalutaion could // put Maya into an infinite loop. The only safe way to look at values // on plugs is via the MDataBlock::outputValue() which does not trigger // an evaluation. It is recommeneded that you only look at plugs whose // values are constant or you know have already been computed. // // For this example routine, we will only implement the simplest case // of a relationship. // MStatus affects::setDependentsDirty( const MPlug &plugBeingDirtied, MPlugArray &affectedPlugs ) { MStatus status; MObject thisNode = thisMObject(); MFnDependencyNode fnThisNode( thisNode ); if ( plugBeingDirtied.partialName() == "A" ) { // "A" is dirty, so mark "B" dirty if "B" exists. // This implements the relationship "A affects B". // fprintf(stderr,"affects::setDependentsDirty, \"A\" being dirtied\n"); MPlug pB = fnThisNode.findPlug( "B", &status ); if ( MStatus::kSuccess == status ) { fprintf(stderr,"\t\t... dirtying \"B\"\n"); CHECK_MSTATUS( affectedPlugs.append( pB ) ); } } return( MS::kSuccess ); }
void disconnectProps(MFnDependencyNode & iNode, std::vector<Prop> & iSampledPropList, std::size_t iFirstProp) { // get prop names and make sure they are disconnected before // trying to connect to them std::size_t numProps = iSampledPropList.size(); for (std::size_t i = iFirstProp; i < numProps; ++i) { std::string propName; if (iSampledPropList[i].mArray.valid()) { propName = iSampledPropList[i].mArray.getName(); } else { propName = iSampledPropList[i].mScalar.getName(); } // disconnect connections to animated props MPlug dstPlug; if (propName == Alembic::AbcGeom::kVisibilityPropertyName) { dstPlug = iNode.findPlug("visibility"); } else { dstPlug = iNode.findPlug(propName.c_str()); } // make sure the long name matches if (propName == Alembic::AbcGeom::kVisibilityPropertyName || dstPlug.partialName(false, false, false, false, false, true) == propName.c_str()) { disconnectAllPlugsTo(dstPlug); } } }
static void _GatherPrefixedAttrs( const std::map<std::string, std::string>& attrPrefixes, const std::map<std::string, std::string>& primvarPrefixes, const MDagPath &dag, std::vector<_AttributeEntry>* attrs) { MStatus status; MFnDependencyNode depFn(dag.node()); unsigned int numAttrs = depFn.attributeCount(); for (unsigned int i=0; i < numAttrs; ++i) { MObject attrObj = depFn.attribute(i); MPlug plg = depFn.findPlug(attrObj, true); if (plg.isNull()) { continue; } // Skip if not dynamic attr (user attribute) if (!plg.isDynamic()) { continue; } MString mayaPlgName = plg.partialName(false, false, false, false, false, true, &status); std::string plgName(mayaPlgName.asChar()); // Skip if it's an AbcExport-suffixed hint attribute. if (_EndsWithAbcTag(plgName)) { continue; } // Add entries based on attribute prefix list and primvar prefix list. _AddAttributeNameEntry(plgName, attrPrefixes, false, attrs); _AddAttributeNameEntry(plgName, primvarPrefixes, true, attrs); } }
CStringA FxInternal::EncodePlug(const MPlug& plug) { MString name= plug.partialName(false, true, false, false, true, true); return CStringA(name.asChar()); }
MStatus ColorSplineParameterHandler<S>::doSetValue( IECore::ConstParameterPtr parameter, MPlug &plug ) const { assert( parameter ); typename IECore::TypedParameter< S >::ConstPtr p = IECore::runTimeCast<const IECore::TypedParameter< S > >( parameter ); if( !p ) { return MS::kFailure; } MRampAttribute fnRAttr( plug ); if ( !fnRAttr.isColorRamp() ) { return MS::kFailure; } const S &spline = p->getTypedValue(); MStatus s; MIntArray indicesToReuse; plug.getExistingArrayAttributeIndices( indicesToReuse, &s ); assert( s ); int nextNewLogicalIndex = 0; if( indicesToReuse.length() ) { nextNewLogicalIndex = 1 + *std::max_element( MArrayIter<MIntArray>::begin( indicesToReuse ), MArrayIter<MIntArray>::end( indicesToReuse ) ); } assert( indicesToReuse.length() == fnRAttr.getNumEntries() ); size_t pointsSizeMinus2 = spline.points.size() - 2; unsigned pointIndex = 0; unsigned numExpectedPoints = 0; for ( typename S::PointContainer::const_iterator it = spline.points.begin(); it != spline.points.end(); ++it, ++pointIndex ) { // we commonly double up the endpoints on cortex splines to force interpolation to the end. // maya does this implicitly, so we skip duplicated endpoints when passing the splines into maya. // this avoids users having to be responsible for managing the duplicates, and gives them some consistency // with the splines they edit elsewhere in maya. if( ( pointIndex==1 && *it == *spline.points.begin() ) || ( pointIndex==pointsSizeMinus2 && *it == *spline.points.rbegin() ) ) { continue; } MPlug pointPlug; if( indicesToReuse.length() ) { pointPlug = plug.elementByLogicalIndex( indicesToReuse[0] ); indicesToReuse.remove( 0 ); } else { pointPlug = plug.elementByLogicalIndex( nextNewLogicalIndex++ ); } s = pointPlug.child( 0 ).setValue( it->first ); assert( s ); MPlug colorPlug = pointPlug.child( 1 ); colorPlug.child( 0 ).setValue( it->second[0] ); colorPlug.child( 1 ).setValue( it->second[1] ); colorPlug.child( 2 ).setValue( it->second[2] ); // hardcoding interpolation of 3 (spline) because the MRampAttribute::MInterpolation enum values don't actually // correspond to the necessary plug values at all. s = pointPlug.child( 2 ).setValue( 3 ); assert( s ); numExpectedPoints++; } // delete any of the original indices which we didn't reuse. we can't use MRampAttribute::deleteEntries // here as it's utterly unreliable. if( indicesToReuse.length() ) { MString plugName = plug.name(); MObject node = plug.node(); MFnDagNode fnDAGN( node ); if( fnDAGN.hasObj( node ) ) { plugName = fnDAGN.fullPathName() + "." + plug.partialName(); } for( unsigned i=0; i<indicesToReuse.length(); i++ ) { // using mel because there's no equivalant api method as far as i know. MString command = "removeMultiInstance -b true \"" + plugName + "[" + indicesToReuse[i] + "]\""; s = MGlobal::executeCommand( command ); assert( s ); if( !s ) { return s; } } } #ifndef NDEBUG { assert( fnRAttr.getNumEntries() == numExpectedPoints ); MIntArray indices; MFloatArray positions; MColorArray colors; MIntArray interps; fnRAttr.getEntries( indices, positions, colors, interps, &s ); assert( s ); assert( numExpectedPoints == positions.length() ); assert( numExpectedPoints == colors.length() ); assert( numExpectedPoints == interps.length() ); assert( numExpectedPoints == indices.length() ); for ( unsigned i = 0; i < positions.length(); i++ ) { float position = positions[ i ]; const MVector color( colors[ i ][ 0 ], colors[ i ][ 1 ], colors[ i ][ 2 ] ); bool found = false; for ( typename S::PointContainer::const_iterator it = spline.points.begin(); it != spline.points.end() && !found; ++it ) { MVector color2( it->second[0], it->second[1], it->second[2] ); if ( fabs( it->first - position ) < 1.e-3f && ( color2 - color ).length() < 1.e-3f ) { found = true; } } assert( found ); } } #endif return MS::kSuccess; }
// // Write the 'connectAttr' commands for all of a node's incoming // connections. // void maTranslator::writeNodeConnections(fstream& f, const MObject& node) { MFnDependencyNode nodeFn(node); MPlugArray plugs; nodeFn.getConnections(plugs); unsigned int numBrokenConns = fBrokenConnSrcs.length(); unsigned int numPlugs = plugs.length(); unsigned int i; for (i = 0; i < numPlugs; i++) { // // We only care about connections where we are the destination. // MPlug destPlug = plugs[i]; MPlugArray srcPlug; destPlug.connectedTo(srcPlug, true, false); if (srcPlug.length() > 0) { MObject srcNode = srcPlug[0].node(); MFnDependencyNode srcNodeFn(srcNode); // // Don't write the connection if the source is not writable... // if (!srcNodeFn.canBeWritten()) continue; // // or the connection was made in a referenced file... // if (destPlug.isFromReferencedFile()) continue; // // or the plug is procedural... // if (destPlug.isProcedural()) continue; // // or it is a connection between a default node and a shared // node (because those will get set up automatically). // if (srcNodeFn.isDefaultNode() && nodeFn.isShared()) continue; f << "connectAttr \""; // // Default nodes get a colon at the start of their names. // if (srcNodeFn.isDefaultNode()) f << ":"; f << srcPlug[0].partialName(true).asChar() << "\" \""; if (nodeFn.isDefaultNode()) f << ":"; f << destPlug.partialName(true).asChar() << "\""; // // If the src plug is also one from which a broken // connection originated, then add the "-rd/referenceDest" flag // to the command. That will help Maya to better adjust if the // referenced file has changed the next time it is loaded. // if (srcNodeFn.isFromReferencedFile()) { unsigned int j; for (j = 0; j < numBrokenConns; j++) { if (fBrokenConnSrcs[j] == srcPlug[0]) { f << " -rd \"" << fBrokenConnDests[j].partialName(true).asChar() << "\""; break; } } } // // If the plug is locked, then add a "-l/lock" flag to the // command. // if (destPlug.isLocked()) f << " -l on"; // // If the destination attribute is a multi for which index // does not matter, then we must add the "-na/nextAvailable" // flag to the command. // MObject attr = destPlug.attribute(); MFnAttribute attrFn(attr); if (!attrFn.indexMatters()) f << " -na"; f << ";" << endl; } } }
MStatus TransformationMatrixParameterHandler<T>::doUpdate( IECore::ConstParameterPtr parameter, MPlug &plug ) const { typename IECore::TypedParameter<IECore::TransformationMatrix<T> >::ConstPtr p = IECore::runTimeCast<const IECore::TypedParameter<IECore::TransformationMatrix<T> > >( parameter ); if( !p ) { return MS::kFailure; } MObject attribute = plug.attribute(); MFnCompoundAttribute fnCAttr( attribute ); if( !fnCAttr.hasObj( attribute ) ) { return MS::kFailure; } if( plug.numChildren() != 8 ) { return MS::kFailure; } MStatus stat; MPlug tmpPlug; for( unsigned int i=0; i<8; i++ ) { tmpPlug = plug.child( i, &stat ); // Verify the naming of the child plugs. const MString name = tmpPlug.partialName(); const unsigned int len = name.length() - 1; const unsigned int nlen = g_attributeNames[i].length() - 1; const MString nameEnd = name.substringW( len - nlen, len ); if( !stat || nameEnd != g_attributeNames[i] ) { return MS::kFailure; } MObject attr = tmpPlug.attribute(); fnCAttr.setObject( attr ); if( !fnCAttr.hasObj( attr ) ) { return MS::kFailure; } } IECore::TransformationMatrix<T> tMatrix = p->typedDefaultValue(); if( !setUnitVecDefaultValues( plug.child( TRANSLATE_INDEX ), tMatrix.translate ) ) return MS::kFailure; if( !setUnitVecDefaultValues( plug.child( ROTATE_INDEX ), tMatrix.rotate ) ) return MS::kFailure; if( !setVecDefaultValues( plug.child( SCALE_INDEX ), tMatrix.scale ) ) return MS::kFailure; if( !setVecDefaultValues( plug.child( SHEAR_INDEX ), tMatrix.shear ) ) return MS::kFailure; if( !setVecDefaultValues( plug.child( SCALEPIVOT_INDEX ), tMatrix.scalePivot ) ) return MS::kFailure; if( !setVecDefaultValues( plug.child( SCALEPIVOTTRANS_INDEX ), tMatrix.scalePivotTranslation ) ) return MS::kFailure; if( !setVecDefaultValues( plug.child( ROTATEPIVOT_INDEX ), tMatrix.rotatePivot ) ) return MS::kFailure; if( !setVecDefaultValues( plug.child( ROTATEPIVOTTRANS_INDEX ), tMatrix.rotatePivotTranslation ) ) return MS::kFailure; return finishUpdating( parameter, plug ); }