コード例 #1
0
ファイル: Utility.cpp プロジェクト: andreaforapani/vHelix
	MStatus HelixBases_sort(MObjectArray & input, MObjectArray & result) {
		MStatus status;

		result.setSizeIncrement(input.length());

		while(input.length() > 0) {
			double z = std::numeric_limits<double>::max();
			unsigned int z_index = 0;

			for(unsigned int i = 0; i < input.length(); ++i) {
				MFnTransform transform(input[i]);

				MVector translation = transform.getTranslation(MSpace::kTransform, &status);

				if (!status) {
					status.perror("MFnTransform::getTranslation");
					return status;
				}

				if (translation.z < z) {
					z = translation.z;
					z_index = i;
				}
			}

			result.append(input[z_index]);
			input.remove(z_index);
		}

		return MStatus::kSuccess;
	}
コード例 #2
0
ファイル: util.cpp プロジェクト: BigRoy/Maya-devkit
MObjectArray getOutConnectedSG( const MDagPath &shapeDPath )
{
    MStatus status;

    // Array of connected Shaging Engines
    MObjectArray connSG;

    // Iterator through the dependency graph to find if there are
    // shading engines connected
    MObject obj(shapeDPath.node()); // non const MObject
    MItDependencyGraph itDG( obj, MFn::kShadingEngine,
                             MItDependencyGraph::kDownstream,
                             MItDependencyGraph::kBreadthFirst,
                             MItDependencyGraph::kNodeLevel, &status );

    if( status == MS::kFailure )
        return connSG;

    // we want to prune the iteration if the node is not a shading engine
    itDG.enablePruningOnFilter();

    // iterate through the output connected shading engines
    for( ; itDG.isDone()!= true; itDG.next() )
        connSG.append( itDG.thisNode() );

    return connSG;
}
コード例 #3
0
ファイル: Utility.cpp プロジェクト: andreaforapani/vHelix
	MStatus GetSelectedObjectsOfType(MObjectArray & objects, MTypeId & type) {
		MStatus status;
		MSelectionList selectionList;

		if (!(status = MGlobal::getActiveSelectionList(selectionList))) {
			status.perror("MGlobal::getActiveSelectionList");
			return status;
		}

		if (!(status = objects.clear())) {
			status.perror("MObjectArray::clear");
			return status;
		}

		unsigned int selectionList_length = selectionList.length(&status);

		if (!status) {
			status.perror("MSelectionList::length");
			return status;
		}

		for(unsigned int i = 0; i < selectionList_length; ++i) {
			//MDagPath dagPath;
			MObject object;

			if (!(status = selectionList.getDependNode(i, object))) {
				status.perror("MSelectionList::getDependNode");
				return status;
			}

			MObject relative = GetObjectOrParentsOfType(object, type, status);

			if (!status) {
				status.perror("GetObjectOrParentsOfType");
				return status;
			}

			if (relative != MObject::kNullObj) {
				/*
				 * Make sure it's not already added
				 */

				bool contains = false;
				for(unsigned int i = 0; i < objects.length(); ++i) {
					if (objects[i] == object) {
						contains = true;
						break;
					}
				}

				if (!contains)
					objects.append(relative);
			}
		}

		return MStatus::kSuccess;
	}
コード例 #4
0
void NeuronForMayaDevice::postConstructor()
{
	MObjectArray attrArray;
	attrArray.append( NeuronForMayaDevice::outputTranslate );
	setRefreshOutputAttributes( attrArray );

	// we'll be reading one set of translate x,y, z's at a time
	createMemoryPools( 24, 15, sizeof(double));
}
コード例 #5
0
ファイル: HesperisIO.cpp プロジェクト: spinos/aphid
void HesperisIO::LsChildren(MObjectArray & dst, 
	            const int & maxCount,
	            const MObject & oparent)
{
    MFnDagNode ppf(oparent);
    for(unsigned i = 0; i <ppf.childCount(); i++) {
        dst.append(ppf.child(i) );
        if(dst.length() >= maxCount)
            return;
    }
}
コード例 #6
0
ファイル: main.cpp プロジェクト: amadlover/setupRGBShaders
MStatus setupRGBShaders::doIt( const MArgList & args )
{
    unsigned int FIndex = args.flagIndex( "fp", "folderPath" );
    unsigned int fIndex = args.flagIndex( "fn", "fileName" );

    if( FIndex == MArgList::kInvalidArgIndex || fIndex == MArgList::kInvalidArgIndex ) {
        MGlobal::displayError( "Error specifying flag or flag values. \n-fp, -folderPath <folder_path> \t -fn, -fileName <file_name>" );
        return MS::kFailure;
    }

    folderPath = args.asString( FIndex );
    fileName = args.asString( fIndex );

    MItDag meshIt( MItDag::kDepthFirst, MFn::kMesh );

    for( ; !meshIt.isDone(); meshIt.next() ) {
        MDagPath dagPath;

        meshIt.getPath( dagPath );
        meshObjs.append( dagPath.transform() );
    }

    MItDag camIt( MItDag::kDepthFirst, MFn::kCamera );

    for( ; !camIt.isDone(); camIt.next() ) {
        MDagPath dagPath;

        camIt.getPath( dagPath );
        MFnDependencyNode camFn( dagPath.node() );

        bool isRenderable;
        camFn.findPlug( "renderable" ).getValue( isRenderable );

        if( isRenderable )
            camObjs.append( dagPath.transform() );
    }

    MGlobal::executeCommand( "setAttr miDefaultFramebuffer.datatype 5" );

    return redoIt();
}
コード例 #7
0
ファイル: tools.cpp プロジェクト: dictoon/appleseed-maya
// get direct connections and primary children connections for such plugs like color, vector, point
void getConnectedInNodes(MPlug& plug, MObjectArray& nodeList)
{
    MPlugArray connectedPlugs;
    plug.connectedTo(connectedPlugs, true, false);
    MString plugname = plug.name();
    int numConnections = connectedPlugs.length();

    for (int i = 0; i <  numConnections; i++)
    {
        MString otherSidePlug = connectedPlugs[i].name();
        MObject plugObject = connectedPlugs[i].node();
        if (plugObject != MObject::kNullObj)
            nodeList.append(plugObject);
    }
}
コード例 #8
0
ファイル: tools.cpp プロジェクト: MassW/OpenMaya
void findConnectedNodeTypes(uint nodeId, MObject thisObject, MObjectArray& connectedElements, MPlugArray& completeList, bool upstream)
{

	MGlobal::displayInfo(MString("thisNode: ") + getObjectName(thisObject));

	MString name = getObjectName(thisObject);

	MFnDependencyNode depFn(thisObject);
	if(depFn.typeId().id() == nodeId)
	{
		connectedElements.append(thisObject);
		MGlobal::displayInfo(MString("found object with correct id: ") + depFn.name());
		return;
	}

	bool downstream = !upstream;

	MPlugArray plugArray;
	depFn.getConnections(plugArray);

	int numc = plugArray.length();

	for( uint plugId = 0; plugId < plugArray.length(); plugId++)
	{
		MPlug plug = plugArray[plugId];
		if( isPlugInList(plug, completeList))
			continue;

		completeList.append(plug);

		MString pn = plug.name();
		if( upstream && plug.isDestination())
			continue;
		if( downstream && plug.isSource())
			continue;
		
		MPlugArray otherSidePlugs;
		bool asDest = plug.isDestination();
		bool asSrc = plug.isSource();
		MGlobal::displayInfo(MString("findConnectedNodeTypes: checking plug ") + plug.name());
		plug.connectedTo(otherSidePlugs, asDest, asSrc);
		for( uint cplugId = 0; cplugId < otherSidePlugs.length(); cplugId++)
		{
			findConnectedNodeTypes(nodeId, otherSidePlugs[cplugId].node(), connectedElements, completeList, upstream);
		}		
	}

}
コード例 #9
0
void EntityNode::GetImportNodes( MObjectArray& objects )
{
    MPlug plug(thisMObject(), m_ImportNodes);
    u32 num = plug.numElements();
    for( u32 i = 0; i < num; ++i )
    {
        MPlug elementPlug = plug.elementByLogicalIndex( i );
        if( elementPlug.isConnected() )
        {
            MPlugArray plugs;
            elementPlug.connectedTo( plugs, true, false );

            //should be one and only one
            HELIUM_ASSERT( plugs.length() == 1 );
            objects.append ( plugs[0].node() );
        }
    }
}
コード例 #10
0
    // --------------------------------------
    void ReferenceManager::getRootObjects(
        const MObject& referenceNode, 
        MDagPathArray& rootPaths, 
        MObjectArray& subReferences)
    {
        rootPaths.clear();
        subReferences.clear();

        MFnDependencyNode referenceNodeFn(referenceNode);

        // Get the paths of all the dag nodes included in this reference
        MStringArray nodeNames;
        MString command = MString("reference -rfn \"") + referenceNodeFn.name() + "\" -q -node -dp;";
        MGlobal::executeCommand(command, nodeNames);

        uint nodeNameCount = nodeNames.length();
        MDagPathArray nodePaths;
        for (uint j = 0; j < nodeNameCount; ++j)
        {
            MObject o = DagHelper::getNode(nodeNames[j]);
            MDagPath p = DagHelper::getShortestDagPath(o);
            if (p.length() > 0)
            {
                nodePaths.append(p);
            }
            else
            {
                if (o != MObject::kNullObj && o.apiType() == MFn::kReference
                    && strstr(nodeNames[j].asChar(), "_UNKNOWN_REF_NODE") == NULL)
                {
                    subReferences.append(o);
                }
            }
        }

        // Keep only the root transform for the reference in our path arrays
        uint nodePathCount = nodePaths.length();
        for (uint j = 0; j < nodePathCount; ++j)
        {
            const MDagPath& p = nodePaths[j];
            if ( !isRootTransform ( nodePaths, p ) ) continue;
            rootPaths.append(p);
        }
    }
コード例 #11
0
ファイル: tools.cpp プロジェクト: dictoon/appleseed-maya
void makeUniqueArray(MObjectArray& oa)
{
    MObjectArray tmpArray;
    for (uint i = 0; i < oa.length(); i++)
    {
        bool found = false;
        for (uint k = 0; k < tmpArray.length(); k++)
        {
            if (oa[i] == tmpArray[k])
            {
                found = true;
                break;
            }
        }
        if (!found)
            tmpArray.append(oa[i]);
    }
    oa = tmpArray;
}
コード例 #12
0
ファイル: tools.cpp プロジェクト: dictoon/appleseed-maya
void uniqueMObjectArray(MObjectArray& cleanMe)
{
    MObjectArray tmpArray;
    for (uint i = 0; i < cleanMe.length(); i++)
    {
        bool found = false;
        for (uint k = 0; k < tmpArray.length(); k++)
        {
            if (cleanMe[i] == tmpArray[k])
            {
                found = true;
                break;
            }
        }
        if (!found)
            tmpArray.append(cleanMe[i]);
    }
    cleanMe = tmpArray;
}
コード例 #13
0
ファイル: tools.cpp プロジェクト: MassW/OpenMaya
void getConnectedNodes(MObject& thisObject, MObjectArray& nodeList)
{
	MFnDependencyNode depFn(thisObject);
	MPlugArray connectedPlugs;
	depFn.getConnections(connectedPlugs);
	int numConnections = connectedPlugs.length();
	
	for( int i = 0; i <  numConnections; i++)
	{
		// check for incoming connections only. Outgoing connections are not relevant
		MPlug plug = connectedPlugs[i];
		// an plug can be source AND destination at the same time, like the displacement attribute of a displacementShader
		if( plug.isSource() && !plug.isDestination())
			continue;
		MObject plugObject = getOtherSideNode(plug);
		if( plugObject != MObject::kNullObj)
			nodeList.append(plugObject);
	}
	//return (numConnections > 0);
}
コード例 #14
0
MStatus ParameterisedHolder<B>::removeUnecessaryAttributes()
{
	MObjectArray toRemove;
	MFnDependencyNode fnDN( B::thisMObject() );
	for( unsigned i=0; i<fnDN.attributeCount(); i++ )
	{
		MObject attr = fnDN.attribute( i );
		MFnAttribute fnAttr( attr );

		MString attrName = fnAttr.name();
		if( 0==strncmp( attrName.asChar(), g_attributeNamePrefix.c_str(), g_attributeNamePrefix.size() ) )
		{
			if( m_attributeNamesToParameters.find( fnAttr.name() )==m_attributeNamesToParameters.end() )
			{
				MPlug plug( B::thisMObject(), attr );
				plug.setLocked( false ); // we can't remove things if they're locked
				if( fnAttr.parent().isNull() )
				{
					toRemove.append( attr );
				}
				else
				{
					// we don't need to remove attributes which are the children
					// of compounds as they'll be removed when their parent is removed
				}
			}
		}
	}
	for( unsigned i=0; i<toRemove.length(); i++ )
	{
		MStatus s = fnDN.removeAttribute( toRemove[i] );
		if( !s )
		{
			return s;
		}
	}

	return MStatus::kSuccess;
}
コード例 #15
0
ファイル: maTranslator.cpp プロジェクト: DimondTheCat/xray
void maTranslator::writeNonDagNodes(fstream& f)
{
	MItDependencyNodes	nodeIter;

	for (; !nodeIter.isDone(); nodeIter.next())
	{
		MObject				node = nodeIter.item();
		MFnDependencyNode	nodeFn(node);

		//
		// Save default nodes for later processing.
		//
		if (nodeFn.isDefaultNode())
		{
			fDefaultNodes.append(node);
		}
		else if (!nodeFn.isFromReferencedFile()
		&&	!nodeFn.isFlagSet(fCreateFlag))
		{
			//
			// If this node is either writable or shared, then write it out.
			// Otherwise don't, but still mark it as having been written so
			// that we don't end up processing it again at some later time.
			//
			if (nodeFn.canBeWritten() || nodeFn.isShared())
			{
				writeCreateNode(f, node);
				writeNodeAttrs(f, node, true);
				writeLockNode(f, node);
			}

			nodeFn.setFlag(fCreateFlag, true);
			nodeFn.setFlag(fAttrFlag, true);
		}
	}
}
コード例 #16
0
ファイル: polyModifierCmd.cpp プロジェクト: Byron/bsuite
// --------------------------------------------------------------------------------------------
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;
}
コード例 #17
0
ファイル: motionTraceCmd.cpp プロジェクト: DimondTheCat/xray
MStatus motionTrace::redoIt()
//
// Description
//     This method performs the action of the command.
//
//     This method iterates over all selected items and
//     prints out connected plug and dependency node type
//     information.
//
{
	MStatus stat;				// Status code

	MObjectArray picked;
	MObject		dependNode;		// Selected dependency node

	// Create a selection list iterator
	//
	MSelectionList slist;
	MGlobal::getActiveSelectionList( slist );
	MItSelectionList iter( slist, MFn::kInvalid,&stat );

	// Iterate over all selected dependency nodes
	// and save them in a list
	//
	for ( ; !iter.isDone(); iter.next() )
	{
		// Get the selected dependency node
		//
		if ( MS::kSuccess != iter.getDependNode( dependNode ) )
		{
			cerr << "Error getting the dependency node" << endl;
			continue;
		}
		picked.append( dependNode );
	}

	// array of arrays for object position

	MPointArray *pointArrays = new MPointArray [ picked.length() ];

	unsigned int i;
	double time;

	//	Sample the animation using start, end, by values

	for ( time = start; time <= end; time+=by )
	{
		MTime timeval(time);

		MGlobal::viewFrame( timeval );

		// Iterate over selected dependency nodes
		//

		for ( i = 0; i < picked.length(); i++ )
		{
			// Get the selected dependency node
			//
			dependNode = picked[i];

			// Create a function set for the dependency node
			//
			MFnDependencyNode fnDependNode( dependNode );

			// Get the translation attribute values

			MObject txAttr;
			txAttr = fnDependNode.attribute( MString("translateX"), &stat );
			MPlug txPlug( dependNode, txAttr );
			double tx;
			stat = txPlug.getValue( tx );

			MObject tyAttr;
			tyAttr = fnDependNode.attribute( MString("translateY"), &stat );
			MPlug tyPlug( dependNode, tyAttr );
			double ty;
			stat = tyPlug.getValue( ty );

			MObject tzAttr;
			tzAttr = fnDependNode.attribute( MString("translateZ"), &stat );
			MPlug tzPlug( dependNode, tzAttr );
			double tz;
			stat = tzPlug.getValue( tz );

#if 0
			fprintf( stderr,
				     "Time = %2.2lf, XYZ = ( %2.2lf, %2.2lf, %2.2lf )\n\n",
					 time, tx, ty, tz );
#endif

			pointArrays[i].append( MPoint( tx, ty, tz )) ;
		}
	}

	// make a path curve for each selected object

	for ( i = 0; i < picked.length(); i++ )
		jMakeCurve( pointArrays[i] );

	delete [] pointArrays;
	return MS::kSuccess;
}
コード例 #18
0
MStatus clusterWeightFunctionCmd::performWeighting(MFnWeightGeometryFilter &cluster,
										   MDagPath &dagPath,
										   MObject &component)
{
	MStatus status;
	MItGeometry geomIter(dagPath, component, &status);
	MObject comp;
	MObjectArray compArray;
	MDoubleArray weightArray;
	double weight = 0.0;

	if (MS::kSuccess == status) {
		for (; !geomIter.isDone(); geomIter.next()) {
			comp = geomIter.component();

			MPoint pnt = geomIter.position(MSpace::kWorld, &status);

			if (MS::kSuccess != status) {
				return MS::kFailure;
			}

			if (kSine == fEffectType) {
				weight = sin(pnt.x)*sin(pnt.z);
			}
			else if (kSineDistance == fEffectType) {
				double distance = pnt.distanceTo(MPoint::origin);
				weight = sin(distance);
			}
			else if (kSineDistance2 == fEffectType) {
				double distance = pnt.distanceTo(MPoint::origin);
				weight = sin(distance*distance);
			}
			else if (kDistanceSineDistance == fEffectType) {
				double distance = pnt.distanceTo(MPoint::origin);
				weight = distance*sin(distance);
			}
			else if (kInverseDistanceSineDistance == fEffectType) {
				double distance = pnt.distanceTo(MPoint::origin);
				weight = sin(distance)/(distance+1);
			}
			else if (kDistance == fEffectType) {
				double distance = pnt.distanceTo(MPoint::origin);
				weight = distance;
			}
			else if (kDistance2 == fEffectType) {
				double distance = pnt.distanceTo(MPoint::origin);
				weight = distance*distance;
			}
			else if (kDistance3 == fEffectType) {
				double distance = pnt.distanceTo(MPoint::origin);
				weight = distance*distance*distance;
			}
			else if (kDistance4 == fEffectType) {
				double distance = pnt.distanceTo(MPoint::origin);
				weight = distance*distance*distance*distance;
			}
			else if (kInverseDistance == fEffectType) {
				double dist = pnt.distanceTo(MPoint::origin) + 1;
				weight = 1/(dist);
			}
			else if (kInverseDistance2 == fEffectType) {
				double dist = pnt.distanceTo(MPoint::origin) + 1;
				weight = 1/(dist*dist);
			}
			else if (kInverseDistance3 == fEffectType) {
				double dist = pnt.distanceTo(MPoint::origin) + 1;
				weight = 1/(dist*dist*dist);
			}
			else if (kInverseDistance4 == fEffectType) {
				double dist = pnt.distanceTo(MPoint::origin) + 1;
				weight = 1/(dist*dist*dist*dist);
			}

			compArray.append(comp);
			weightArray.append(weight);
		}

		unsigned length = compArray.length();
		for (unsigned i = 0; i < length; i++) {
			cluster.setWeight(dagPath, compArray[i], (float) weightArray[i]);
		}

		return MS::kSuccess;
	} else
		return MS::kFailure;
}
コード例 #19
0
// Custom parsing to support array argument. Not using MSyntax.
MStatus skinClusterWeights::parseArgs( const MArgList& args )
{
    MStatus	    status = MS::kSuccess;
    MObject         node;
    MDagPath        dagPath;
    MSelectionList  selList;
    
    editUsed  = true;
    queryUsed = false;
    unsigned int i, nth = 0;
    unsigned int numArgs = args.length();	
    while(status == MS::kSuccess && nth < numArgs-1) {
	MString inputString = args.asString(nth, &status);

	if (status != MS::kSuccess) {
	    MGlobal::displayError("skinClusterWeights syntax error");
	    return status;
	}
      
	if (inputString == kEditFlag || inputString == kEditFlagLong) {
	    editUsed  = true;
	    queryUsed = false;
	    nth++;
	    continue;
	}
      
	if (inputString == kQueryFlag || inputString == kQueryFlagLong) {
	    queryUsed = true;
	    editUsed  = false;
	    nth++;
	    continue;
	}
      
	if (inputString == kInfluenceFlag || inputString == kInfluenceFlagLong) {	    
	    nth++;
	    MStringArray stringArray = args.asStringArray(nth, &status);
	    selList.clear();
	    for (i = 0; i < stringArray.length(); i++) {
	      selList.add(stringArray[i]);
	    }
	    for (i = 0; i < selList.length(); i++) {
	      status = selList.getDagPath(i, dagPath);
	      if (status == MS::kSuccess && dagPath.hasFn(MFn::kTransform)) {
		influenceArray.append(dagPath);
	      } else {
		MGlobal::displayError(inputString + " is not a valid influence object.\n");
		return status;
	      }
	    }
	    nth++;
	    continue;
	}

	if (inputString == kSkinClusterFlag || inputString == kSkinClusterFlagLong) {
	    nth++;
	    MStringArray stringArray = args.asStringArray(nth, &status);
	    selList.clear();
	    for (i = 0; i < stringArray.length(); i++) {
	      selList.add(stringArray[i]);
	    }
	    for (i = 0; i < selList.length(); i++) {
	      status = selList.getDependNode(i, node);
	      if (status == MS::kSuccess && node.hasFn(MFn::kSkinClusterFilter)) {
		skinClusterArray.append(node);
	      } else {
		MGlobal::displayError(inputString + " is not a valid skinCluster.\n");
		return status;
	      }
	    }
	    nth++;
	    continue;
	}

	if (inputString == kWeightFlag || inputString == kWeightFlagLong) {
	    nth++;
	    weightArray = args.asDoubleArray(nth, &status);
	    if (status != MS::kSuccess) {
		MGlobal::displayError("error while parsing weight array");
	    }
	    nth++;
	    continue;
	}

	if (inputString == kAssignAllToSingleFlag || inputString == kAssignAllToSingleFlagLong) {
	    assignAllToSingle = true;
	    nth++;
	    continue;
	}

	MGlobal::displayError("invalid command syntax at " + inputString);
	return MS::kFailure;
    }

    // parse command objects
    // nth should equals to numArgs-1 at this point
    geometryArray = args.asStringArray(nth, &status);
    if (status != MS::kSuccess) {
	MGlobal::displayError("Command object invalid");
	return status;
    }

    if (queryUsed) {
	if (assignAllToSingle) {
	    MGlobal::displayWarning("-as/-assignAllToSingle is ignored with query flag");
	}
	if (weightArray.length() > 0) {
	    MGlobal::displayWarning("-w/-weights is ignored with query flag");
	}
    }
    
    return status;
}
コード例 #20
0
MStatus AlembicExportCommand::doIt(const MArgList &args)
{
  ESS_PROFILE_SCOPE("AlembicExportCommand::doIt");

  MStatus status = MS::kFailure;

  MTime currentAnimStartTime = MAnimControl::animationStartTime(),
        currentAnimEndTime = MAnimControl::animationEndTime(),
        oldCurTime = MAnimControl::currentTime(),
        curMinTime = MAnimControl::minTime(),
        curMaxTime = MAnimControl::maxTime();
  MArgParser argData(syntax(), args, &status);

  if (argData.isFlagSet("help")) {
    // TODO: implement help for this command
    // MGlobal::displayInfo(util::getHelpText());
    return MS::kSuccess;
  }

  unsigned int jobCount = argData.numberOfFlagUses("jobArg");
  MStringArray jobStrings;
  if (jobCount == 0) {
    // TODO: display dialog
    MGlobal::displayError("[ExocortexAlembic] No jobs specified.");
    MPxCommand::setResult(
        "Error caught in AlembicExportCommand::doIt: no job specified");
    return status;
  }
  else {
    // get all of the jobstrings
    for (unsigned int i = 0; i < jobCount; i++) {
      MArgList jobArgList;
      argData.getFlagArgumentList("jobArg", i, jobArgList);
      jobStrings.append(jobArgList.asString(0));
    }
  }

  // create a vector to store the jobs
  std::vector<AlembicWriteJob *> jobPtrs;
  double minFrame = 1000000.0;
  double maxFrame = -1000000.0;
  double maxSteps = 1;
  double maxSubsteps = 1;

  // init the curve accumulators
  AlembicCurveAccumulator::Initialize();

  try {
    // for each job, check the arguments
    bool failure = false;
    for (unsigned int i = 0; i < jobStrings.length(); ++i) {
      double frameIn = 1.0;
      double frameOut = 1.0;
      double frameSteps = 1.0;
      double frameSubSteps = 1.0;
      MString filename;
      bool purepointcache = false;
      bool normals = true;
      bool uvs = true;
      bool facesets = true;
      bool bindpose = true;
      bool dynamictopology = false;
      bool globalspace = false;
      bool withouthierarchy = false;
      bool transformcache = false;
      bool useInitShadGrp = false;
      bool useOgawa = false;  // Later, will need to be changed!

      MStringArray objectStrings;
      std::vector<std::string> prefixFilters;
      std::set<std::string> attributes;
      std::vector<std::string> userPrefixFilters;
      std::set<std::string> userAttributes;
      MObjectArray objects;
      std::string search_str, replace_str;

      // process all tokens of the job
      MStringArray tokens;
      jobStrings[i].split(';', tokens);
      for (unsigned int j = 0; j < tokens.length(); j++) {
        MStringArray valuePair;
        tokens[j].split('=', valuePair);
        if (valuePair.length() != 2) {
          MGlobal::displayWarning(
              "[ExocortexAlembic] Skipping invalid token: " + tokens[j]);
          continue;
        }

        const MString &lowerValue = valuePair[0].toLowerCase();
        if (lowerValue == "in") {
          frameIn = valuePair[1].asDouble();
        }
        else if (lowerValue == "out") {
          frameOut = valuePair[1].asDouble();
        }
        else if (lowerValue == "step") {
          frameSteps = valuePair[1].asDouble();
        }
        else if (lowerValue == "substep") {
          frameSubSteps = valuePair[1].asDouble();
        }
        else if (lowerValue == "normals") {
          normals = valuePair[1].asInt() != 0;
        }
        else if (lowerValue == "uvs") {
          uvs = valuePair[1].asInt() != 0;
        }
        else if (lowerValue == "facesets") {
          facesets = valuePair[1].asInt() != 0;
        }
        else if (lowerValue == "bindpose") {
          bindpose = valuePair[1].asInt() != 0;
        }
        else if (lowerValue == "purepointcache") {
          purepointcache = valuePair[1].asInt() != 0;
        }
        else if (lowerValue == "dynamictopology") {
          dynamictopology = valuePair[1].asInt() != 0;
        }
        else if (lowerValue == "globalspace") {
          globalspace = valuePair[1].asInt() != 0;
        }
        else if (lowerValue == "withouthierarchy") {
          withouthierarchy = valuePair[1].asInt() != 0;
        }
        else if (lowerValue == "transformcache") {
          transformcache = valuePair[1].asInt() != 0;
        }
        else if (lowerValue == "filename") {
          filename = valuePair[1];
        }
        else if (lowerValue == "objects") {
          // try to find each object
          valuePair[1].split(',', objectStrings);
        }
        else if (lowerValue == "useinitshadgrp") {
          useInitShadGrp = valuePair[1].asInt() != 0;
        }

        // search/replace
        else if (lowerValue == "search") {
          search_str = valuePair[1].asChar();
        }
        else if (lowerValue == "replace") {
          replace_str = valuePair[1].asChar();
        }
        else if (lowerValue == "ogawa") {
          useOgawa = valuePair[1].asInt() != 0;
        }
        else if (lowerValue == "attrprefixes") {
          splitListArg(valuePair[1], prefixFilters);
        }
        else if (lowerValue == "attrs") {
          splitListArg(valuePair[1], attributes);
        }
        else if (lowerValue == "userattrprefixes") {
          splitListArg(valuePair[1], userPrefixFilters);
        }
        else if (lowerValue == "userattrs") {
          splitListArg(valuePair[1], userAttributes);
        }
        else {
          MGlobal::displayWarning(
              "[ExocortexAlembic] Skipping invalid token: " + tokens[j]);
          continue;
        }
      }

      // now check the object strings
      for (unsigned int k = 0; k < objectStrings.length(); k++) {
        MSelectionList sl;
        MString objectString = objectStrings[k];
        sl.add(objectString);
        MDagPath dag;
        for (unsigned int l = 0; l < sl.length(); l++) {
          sl.getDagPath(l, dag);
          MObject objRef = dag.node();
          if (objRef.isNull()) {
            MGlobal::displayWarning("[ExocortexAlembic] Skipping object '" +
                                    objectStrings[k] + "', not found.");
            break;
          }

          // get all parents
          MObjectArray parents;

          // check if this is a camera
          bool isCamera = false;
          for (unsigned int m = 0; m < dag.childCount(); ++m) {
            MFnDagNode child(dag.child(m));
            MFn::Type ctype = child.object().apiType();
            if (ctype == MFn::kCamera) {
              isCamera = true;
              break;
            }
          }

          if (dag.node().apiType() == MFn::kTransform && !isCamera &&
              !globalspace && !withouthierarchy) {
            MDagPath ppath = dag;
            while (!ppath.node().isNull() && ppath.length() > 0 &&
                   ppath.isValid()) {
              parents.append(ppath.node());
              if (ppath.pop() != MStatus::kSuccess) {
                break;
              }
            }
          }
          else {
            parents.append(dag.node());
          }

          // push all parents in
          while (parents.length() > 0) {
            bool found = false;
            for (unsigned int m = 0; m < objects.length(); m++) {
              if (objects[m] == parents[parents.length() - 1]) {
                found = true;
                break;
              }
            }
            if (!found) {
              objects.append(parents[parents.length() - 1]);
            }
            parents.remove(parents.length() - 1);
          }

          // check all of the shapes below
          if (!transformcache) {
            sl.getDagPath(l, dag);
            for (unsigned int m = 0; m < dag.childCount(); m++) {
              MFnDagNode child(dag.child(m));
              if (child.isIntermediateObject()) {
                continue;
              }
              objects.append(child.object());
            }
          }
        }
      }

      // check if we have incompatible subframes
      if (maxSubsteps > 1.0 && frameSubSteps > 1.0) {
        const double part = (frameSubSteps > maxSubsteps)
                                ? (frameSubSteps / maxSubsteps)
                                : (maxSubsteps / frameSubSteps);
        if (abs(part - floor(part)) > 0.001) {
          MString frameSubStepsStr, maxSubstepsStr;
          frameSubStepsStr.set(frameSubSteps);
          maxSubstepsStr.set(maxSubsteps);
          MGlobal::displayError(
              "[ExocortexAlembic] You cannot combine substeps " +
              frameSubStepsStr + " and " + maxSubstepsStr +
              " in one export. Aborting.");
          return MStatus::kInvalidParameter;
        }
      }

      // remember the min and max values for the frames
      if (frameIn < minFrame) {
        minFrame = frameIn;
      }
      if (frameOut > maxFrame) {
        maxFrame = frameOut;
      }
      if (frameSteps > maxSteps) {
        maxSteps = frameSteps;
      }
      if (frameSteps > 1.0) {
        frameSubSteps = 1.0;
      }
      if (frameSubSteps > maxSubsteps) {
        maxSubsteps = frameSubSteps;
      }

      // check if we have a filename
      if (filename.length() == 0) {
        MGlobal::displayError("[ExocortexAlembic] No filename specified.");
        for (size_t k = 0; k < jobPtrs.size(); k++) {
          delete (jobPtrs[k]);
        }
        MPxCommand::setResult(
            "Error caught in AlembicExportCommand::doIt: no filename "
            "specified");
        return MStatus::kFailure;
      }

      // construct the frames
      MDoubleArray frames;
      {
        const double frameIncr = frameSteps / frameSubSteps;
        for (double frame = frameIn; frame <= frameOut; frame += frameIncr) {
          frames.append(frame);
        }
      }

      AlembicWriteJob *job =
          new AlembicWriteJob(filename, objects, frames, useOgawa,
              prefixFilters, attributes, userPrefixFilters, userAttributes);
      job->SetOption("exportNormals", normals ? "1" : "0");
      job->SetOption("exportUVs", uvs ? "1" : "0");
      job->SetOption("exportFaceSets", facesets ? "1" : "0");
      job->SetOption("exportInitShadGrp", useInitShadGrp ? "1" : "0");
      job->SetOption("exportBindPose", bindpose ? "1" : "0");
      job->SetOption("exportPurePointCache", purepointcache ? "1" : "0");
      job->SetOption("exportDynamicTopology", dynamictopology ? "1" : "0");
      job->SetOption("indexedNormals", "1");
      job->SetOption("indexedUVs", "1");
      job->SetOption("exportInGlobalSpace", globalspace ? "1" : "0");
      job->SetOption("flattenHierarchy", withouthierarchy ? "1" : "0");
      job->SetOption("transformCache", transformcache ? "1" : "0");

      // check if the search/replace strings are valid!
      if (search_str.length() ? !replace_str.length()
                              : replace_str.length())  // either search or
                                                       // replace string is
                                                       // missing or empty!
      {
        ESS_LOG_WARNING(
            "Missing search or replace parameter. No strings will be "
            "replaced.");
        job->replacer = SearchReplace::createReplacer();
      }
      else {
        job->replacer = SearchReplace::createReplacer(search_str, replace_str);
      }

      // check if the job is satifsied
      if (job->PreProcess() != MStatus::kSuccess) {
        MGlobal::displayError("[ExocortexAlembic] Job skipped. Not satisfied.");
        delete (job);
        failure = true;
        break;
      }

      // push the job to our registry
      MGlobal::displayInfo("[ExocortexAlembic] Using WriteJob:" +
                           jobStrings[i]);
      jobPtrs.push_back(job);
    }

    if (failure) {
      for (size_t k = 0; k < jobPtrs.size(); k++) {
        delete (jobPtrs[k]);
      }
      return MS::kFailure;
    }

    // compute the job count
    unsigned int jobFrameCount = 0;
    for (size_t i = 0; i < jobPtrs.size(); i++)
      jobFrameCount += (unsigned int)jobPtrs[i]->GetNbObjects() *
                       (unsigned int)jobPtrs[i]->GetFrames().size();

    // now, let's run through all frames, and process the jobs
    const double frameRate = MTime(1.0, MTime::kSeconds).as(MTime::uiUnit());
    const double incrSteps = maxSteps / maxSubsteps;
    double nextFrame = minFrame + incrSteps;

    for (double frame = minFrame; frame <= maxFrame;
         frame += incrSteps, nextFrame += incrSteps) {
      MAnimControl::setCurrentTime(MTime(frame / frameRate, MTime::kSeconds));
      MAnimControl::setAnimationEndTime(
          MTime(nextFrame / frameRate, MTime::kSeconds));
      MAnimControl::playForward();  // this way, it forces Maya to play exactly
      // one frame! and particles are updated!

      AlembicCurveAccumulator::StartRecordingFrame();
      for (size_t i = 0; i < jobPtrs.size(); i++) {
        MStatus status = jobPtrs[i]->Process(frame);
        if (status != MStatus::kSuccess) {
          MGlobal::displayError("[ExocortexAlembic] Job aborted :" +
                                jobPtrs[i]->GetFileName());
          for (size_t k = 0; k < jobPtrs.size(); k++) {
            delete (jobPtrs[k]);
          }
          restoreOldTime(currentAnimStartTime, currentAnimEndTime, oldCurTime,
                         curMinTime, curMaxTime);
          return status;
        }
      }
      AlembicCurveAccumulator::StopRecordingFrame();
    }
  }
  catch (...) {
    MGlobal::displayError(
        "[ExocortexAlembic] Jobs aborted, force closing all archives!");
    for (std::vector<AlembicWriteJob *>::iterator beg = jobPtrs.begin();
         beg != jobPtrs.end(); ++beg) {
      (*beg)->forceCloseArchive();
    }
    restoreOldTime(currentAnimStartTime, currentAnimEndTime, oldCurTime,
                   curMinTime, curMaxTime);
    MPxCommand::setResult("Error caught in AlembicExportCommand::doIt");
    status = MS::kFailure;
  }
  MAnimControl::stop();
  AlembicCurveAccumulator::Destroy();

  // restore the animation start/end time and the current time!
  restoreOldTime(currentAnimStartTime, currentAnimEndTime, oldCurTime,
                 curMinTime, curMaxTime);

  // delete all jobs
  for (size_t k = 0; k < jobPtrs.size(); k++) {
    delete (jobPtrs[k]);
  }

  // remove all known archives
  deleteAllArchives();
  return status;
}
コード例 #21
0
void geometrySurfaceConstraint::getOutputAttributes(MObjectArray& attributeArray)
{
	attributeArray.clear();
	attributeArray.append( geometrySurfaceConstraint::constraintGeometry );
}
コード例 #22
0
bool getObjectShadingGroups(const MDagPath& shapeObjectDP, MIntArray& perFaceAssignments, MObjectArray& shadingGroups, bool needsPerFaceInfo=true)
{
    // if obj is a light, simply return the mobject
    if (shapeObjectDP.node().hasFn(MFn::kLight))
    {
        perFaceAssignments.clear();
        shadingGroups.clear();
        shadingGroups.append(shapeObjectDP.node());
        return true;
    }

    if (shapeObjectDP.node().hasFn(MFn::kMesh))
    {
        // Find the Shading Engines Connected to the SourceNode
        MFnMesh meshFn(shapeObjectDP.node());

        perFaceAssignments.clear();
        shadingGroups.clear();
        MObjectArray comps;

        // this one seems to be extremly much faster if we need no per face informations.
        // e.g. for a sphere with 90000 faces, the non per face method needs 0.05 sec. whereas the
        // method with per face info needs about 20 sec.
        if (!needsPerFaceInfo)
        {
            meshFn.getConnectedSetsAndMembers(shapeObjectDP.instanceNumber(), shadingGroups, comps, true);
            return true;
        }

        meshFn.getConnectedShaders(shapeObjectDP.instanceNumber(), shadingGroups, perFaceAssignments);

        if (!meshFn.findPlug("displaySmoothMesh").asBool())
            return true;

        MIntArray indices;
        indices = perFaceAssignments;

        int subdivs = 0;
        int multiplier = 0;

        if (meshFn.findPlug("displaySmoothMesh").asBool())
        {
            MMeshSmoothOptions options;
            MStatus status = meshFn.getSmoothMeshDisplayOptions(options);
            if (status)
            {
                if (!meshFn.findPlug("useSmoothPreviewForRender", false, &status).asBool())
                {
                    int smoothLevel = meshFn.findPlug("renderSmoothLevel", false, &status).asInt();
                    options.setDivisions(smoothLevel);
                }

                subdivs = options.divisions();
                if (subdivs > 0)
                    multiplier = static_cast<int> (pow(4.0f, (subdivs - 1)));
            }
        }

        if (multiplier > 0)
            perFaceAssignments.clear();

        for (unsigned int i = 0; i < indices.length(); i++)
        {
            int subdivisions = multiplier * meshFn.polygonVertexCount(i);
            int index = 0 > indices[i] ? 0 : indices[i]; // non assigned has -1, but we want 0
            perFaceAssignments.append(index);

            // simply replicate the index for all subdiv faces
            for (int k = 0; k < subdivisions - 1; k++)
                perFaceAssignments.append(index);
        }
        return true;
    }

    if (shapeObjectDP.node().hasFn(MFn::kNurbsSurface)||shapeObjectDP.hasFn(MFn::kParticle)||shapeObjectDP.hasFn(MFn::kNParticle))
    {
        MObject instObjGroupsAttr;
        if (shapeObjectDP.hasFn(MFn::kNurbsSurface))
        {
            MFnNurbsSurface fnNurbs(shapeObjectDP.node());
            instObjGroupsAttr = fnNurbs.attribute("instObjGroups");
        }
        if (shapeObjectDP.hasFn(MFn::kParticle)||shapeObjectDP.hasFn(MFn::kNParticle))
        {
            MFnParticleSystem fnPart(shapeObjectDP.node());
            instObjGroupsAttr = fnPart.attribute("instObjGroups");
        }
        MPlug instPlug(shapeObjectDP.node(), instObjGroupsAttr);

        // Get the instance that our node is referring to;
        // In other words get the Plug for instObjGroups[intanceNumber];
        MPlug instPlugElem = instPlug.elementByLogicalIndex(shapeObjectDP.instanceNumber());

        // Find the ShadingGroup plugs that we are connected to as Source
        MPlugArray SGPlugArray;
        instPlugElem.connectedTo(SGPlugArray, false, true);

        perFaceAssignments.clear();
        shadingGroups.clear();

        // Loop through each ShadingGroup Plug
        for (unsigned int i=0; i < SGPlugArray.length(); ++i)
        {
            shadingGroups.append(SGPlugArray[i].node());
            return true;
        }
    }
    return false;
}
コード例 #23
0
MStatus	Molecule3Cmd::redoIt()
{
	MStatus stat;
	MDagPath dagPath;
	MFnMesh meshFn;
		
	// Create a ball
	int nBallPolys;
	MPointArray ballVerts;
	MIntArray ballPolyCounts;
	MIntArray ballPolyConnects;
	MFloatArray ballUCoords;
	MFloatArray ballVCoords;
	MIntArray ballFvUVIDs;
	genBall( MPoint::origin, ballRodRatio * radius.value(), segs, nBallPolys, 
			 ballVerts, ballPolyCounts, ballPolyConnects,
			 true, ballUCoords, ballVCoords, ballFvUVIDs );
		
	unsigned int i, j, vertOffset;
	MPointArray meshVerts;
	MPoint p0, p1;
	MObject objTransform;
	
	// Setup for rods
	int nRodPolys;
	MPointArray rodVerts;
	MIntArray rodPolyCounts;
	MIntArray rodPolyConnects;
	MFloatArray rodUCoords;
	MFloatArray rodVCoords;
	MIntArray rodFvUVIDs;
	
	// Setup for newMesh
	int nNewPolys;
	MPointArray newVerts;
	MIntArray newPolyCounts;
	MIntArray newPolyConnects;
	MFloatArray newUCoords;
	MFloatArray newVCoords;
	MIntArray newFvUVIDs;
	
	int uvOffset; 
	MDagModifier dagMod;
	MFnDagNode dagFn;
	
	objTransforms.clear();
	
	// Iterate over the meshes
	unsigned int mi;
	for( mi=0; mi < selMeshes.length(); mi++ )
	{								
		dagPath = selMeshes[mi];
		meshFn.setObject( dagPath );
		
		uvOffset = 0;
		nNewPolys = 0;
		newVerts.clear();
		newPolyCounts.clear();
		newPolyConnects.clear();
		newUCoords.clear();
		newVCoords.clear();
		newFvUVIDs.clear();
		
		// Generate balls
		meshFn.getPoints( meshVerts, MSpace::kWorld );
		for( i=0; i < meshVerts.length(); i++ )
		{
			vertOffset = newVerts.length();
			
			// Add the ball to the new mesh
			nNewPolys += nBallPolys;
			
			// Move the ball vertices to the mesh vertex. Add it to the newMesh
			for( j=0; j < ballVerts.length(); j++ )
				newVerts.append( meshVerts[i] + ballVerts[j] );
				
			for( j=0; j < ballPolyCounts.length(); j++ )
				newPolyCounts.append( ballPolyCounts[j] );
				
			for( j=0; j < ballPolyConnects.length(); j++ )
				newPolyConnects.append( vertOffset + ballPolyConnects[j] );
		
			// Only add the uv coordinates once, since they are shared
			// by all balls
			if( i == 0 )
			{
				for( j=0; j < ballUCoords.length(); j++ )
				{
					newUCoords.append( ballUCoords[j] );
					newVCoords.append( ballVCoords[j] );
				}				
			}
			
			for( j=0; j < ballFvUVIDs.length(); j++ )
			{
				newFvUVIDs.append( uvOffset + ballFvUVIDs[j] );
			}
		}
		
		uvOffset = newUCoords.length();
		
		// Generate rods
		int nRods = 0;
		MItMeshEdge edgeIter( dagPath );
		for( ; !edgeIter.isDone(); edgeIter.next(), nRods++  )
		{	
			p0 = edgeIter.point( 0, MSpace::kWorld );		
			p1 = edgeIter.point( 1, MSpace::kWorld );
			
			// N.B. Generate the uv coordinates only once since they
			// are referenced by all rods
			genRod( p0, p1, 
					radius.value(), segs, nRodPolys, 
					rodVerts, rodPolyCounts, rodPolyConnects,
					nRods == 0,	rodUCoords, rodVCoords,
					rodFvUVIDs ); 

			vertOffset = newVerts.length();
			
			// Add the rod to the mesh
			nNewPolys += nRodPolys;
			
			for( i=0; i < rodVerts.length(); i++ )
				newVerts.append( rodVerts[i] );
				
			for( i=0; i < rodPolyCounts.length(); i++ )
				newPolyCounts.append( rodPolyCounts[i] );
				
			for( i=0; i < rodPolyConnects.length(); i++ )
				newPolyConnects.append( vertOffset + rodPolyConnects[i] );

			// First rod
			if( nRods == 0 )
			{
				// Add rod's uv coordinates to the list
				for( i=0; i < rodUCoords.length(); i++ )
				{
					newUCoords.append( rodUCoords[i] );
					newVCoords.append( rodVCoords[i] );
				}
			}
			
			// Set the face-vertex-uvIDs
			for( i=0; i < rodFvUVIDs.length(); i++ )
			{
				newFvUVIDs.append( uvOffset + rodFvUVIDs[i] );
			}
		}
		
		objTransform = meshFn.create( newVerts.length(), nNewPolys, newVerts, 
									  newPolyCounts, newPolyConnects,
									  newUCoords, newVCoords, 
									  MObject::kNullObj, &stat ); 
		if( !stat )
		{
			MGlobal::displayError( MString( "Unable to create mesh: " ) + stat.errorString() );
			return stat;
		}	
		
		objTransforms.append( objTransform );
				
		meshFn.assignUVs( newPolyCounts, newFvUVIDs );
				
		meshFn.updateSurface();
		
		// Rename transform node
		dagFn.setObject( objTransform );
		dagFn.setName( "molecule" );
				
		// Put mesh into the initial shading group
		dagMod.commandToExecute( MString( "sets -e -fe initialShadingGroup " ) + meshFn.name() );
	}

	// Select all the newly created molecule meshes
	MString cmd( "select -r" );
	for( i=0; i < objTransforms.length(); i++ )
	{
		dagFn.setObject( objTransforms[i] );
		cmd += " " + dagFn.name();	
	}

	dagMod.commandToExecute( cmd );
	
	return dagMod.doIt();
}
コード例 #24
0
ファイル: PRTAttrs.cpp プロジェクト: Esri/esri-cityengine-sdk
MStatus PRTAttrs::updateRuleFiles(MFnDependencyNode & node, MString & rulePkg) {
	PRTNode* prtNode = (PRTNode*)node.userNode();
	MStatus  stat;

	std::string utf8Path(rulePkg.asUTF8());
	std::vector<char> percentEncodedPath(2*utf8Path.size()+1);
	size_t len = percentEncodedPath.size();
	prt::StringUtils::percentEncode(utf8Path.c_str(), &percentEncodedPath[0], &len);
	if(len > percentEncodedPath.size()+1){
		percentEncodedPath.resize(len);
		prt::StringUtils::percentEncode(utf8Path.c_str(), &percentEncodedPath[0], &len);
	}

	std::string uri(FILE_PREFIX);
	uri.append(&percentEncodedPath[0]);

	prtNode->mLRulePkg = uri;

	if(prtNode->mCreatedInteractively) {
		int count = (int)node.attributeCount(&stat);
		MCHECK(stat);

		MObjectArray attrs;

		for(int i = 0; i < count; i++) {
			MObject attr = node.attribute(i, &stat);
			if(stat != MS::kSuccess) continue;
			attrs.append(attr);
		}

		for(unsigned int i = 0; i < attrs.length(); i++) {
			MPlug   plug(node.object(), attrs[i]);
			MString name = plug.partialName();

			if(prtNode->mBriefName2prtAttr.count(name.asWChar()))
				node.removeAttribute(attrs[i]);
		}
		prtNode->destroyEnums();
	} else {
		node.removeAttribute(node.attribute(NAME_GENERATE, &stat));
		MCHECK(stat);
	}

	prtNode->mRuleFile.clear();
	prtNode->mStartRule.clear();

	MString      unpackDir       = MGlobal::executeCommandStringResult("workspace -q -fullName");
	unpackDir += "/assets";
	prt::Status resolveMapStatus = prt::STATUS_UNSPECIFIED_ERROR;


	std::wstring utf16URI;
	utf16URI.resize(uri.size()+1);
	len = utf16URI.size();
	if(prt::StringUtils::toUTF16FromUTF8(uri.c_str(), &utf16URI[0], &len)) {
		utf16URI.resize(len);
		prt::StringUtils::toUTF16FromUTF8(uri.c_str(), &utf16URI[0], &len);
	}

	prtNode->mResolveMap = prt::createResolveMap(utf16URI.c_str(), unpackDir.asWChar(), &resolveMapStatus);
	if(resolveMapStatus == prt::STATUS_OK) {
		size_t nKeys;
		const wchar_t * const* keys   = prtNode->mResolveMap->getKeys(&nKeys);
		std::wstring           sCGB(L".cgb");
		for(size_t k = 0; k < nKeys; k++) {
			std::wstring key = std::wstring(keys[k]);
			if(std::equal(sCGB.rbegin(), sCGB.rend(), key.rbegin())) {
				prtNode->mRuleFile = key;
				break;
			}
		}
	} else {
		prtNode->mResolveMap = 0;
	}

	if(prtNode->mRuleFile.length() > 0)
		updateStartRules(node);

	return MS::kSuccess;
}
コード例 #25
0
liqRibCurvesData::liqRibCurvesData( MObject curveGroup )
: nverts(),
  CVs(),
  NuCurveWidth()
{
	CM_TRACE_FUNC("liqRibCurvesData::liqRibCurvesData("<<curveGroup.apiTypeStr()<<")");

	LIQDEBUGPRINTF( "-> creating nurbs curve group\n" );

	MStatus status( MS::kSuccess );
	MFnDagNode fnDag( curveGroup, &status );
	MFnDagNode fnTrans( fnDag.parent( 0 ) );

	MSelectionList groupList; 
	groupList.add( fnTrans.partialPathName() );
	MDagPath groupPath;
	groupList.getDagPath( 0, groupPath );
	MMatrix m( groupPath.inclusiveMatrix() );

	MStringArray curveList;
	MObjectArray curveObj;
	MDagPathArray curveDag;

	// using the transforms not the nurbsCurves so instances are supported
	MGlobal::executeCommand( MString( "ls -dag -type transform " ) + fnTrans.partialPathName(), curveList );
	for( unsigned i( 0 ); i < curveList.length(); i++ )
	{
		MSelectionList list; 
		list.add( curveList[i] );
		MObject curveNode;
		MDagPath path;
		list.getDependNode( 0, curveNode );
		list.getDagPath( 0, path );
		MFnDagNode fnCurve( curveNode );
		MObject shape( fnCurve.child( 0 ) );
		if( shape.hasFn( MFn::kNurbsCurve ) )
		{
			curveObj.append( curveNode );
			curveDag.append( path );
		}
	}

	if( liqglo.liqglo_renderAllCurves )
	  ncurves = curveObj.length();
	else
		ncurves = 0;  
	  
	if( !ncurves )
		return;

	nverts = shared_array< RtInt >( new RtInt[ ncurves ] );

	unsigned cvcount( 0 );

	unsigned long curvePts(0);
	for( unsigned i( 0 ); i < ncurves; i++ )
	{
		MFnDagNode fnDag( curveObj[i] );
		MFnNurbsCurve fnCurve( fnDag.child( 0 ) );
		nverts[i] = fnCurve.numCVs() + 4;
		cvcount += nverts[i];
	}

	CVs = shared_array< RtFloat >( new RtFloat[ cvcount * 3 ] );

	unsigned k( 0 );
	for( unsigned i( 0 ); i < ncurves; i++ )
	{
		MFnDagNode fnCurve( curveObj[i] );
		MMatrix mCurve( curveDag[i].inclusiveMatrix() );
		mCurve -= m;
		mCurve += MMatrix::identity;

		MObject oCurveChild( fnCurve.child( 0 ) );
		MItCurveCV curveIt( oCurveChild );
		MPoint pt = curveIt.position();
		pt *= mCurve;
		CVs[k++] = (float)pt.x;
		CVs[k++] = (float)pt.y;
		CVs[k++] = (float)pt.z;
		CVs[k++] = (float)pt.x;
		CVs[k++] = (float)pt.y;
		CVs[k++] = (float)pt.z;
		for( curveIt.reset(); !curveIt.isDone(); curveIt.next() )
		{
			pt = curveIt.position();
			pt *= mCurve;
			CVs[k++] = (float)pt.x;
			CVs[k++] = (float)pt.y;
			CVs[k++] = (float)pt.z;
		}
		CVs[k++] = (float)pt.x;
		CVs[k++] = (float)pt.y;
		CVs[k++] = (float)pt.z;
		CVs[k++] = (float)pt.x;
		CVs[k++] = (float)pt.y;
		CVs[k++] = (float)pt.z;
	}

	liqTokenPointer pointsPointerPair;
	pointsPointerPair.set( "P", rPoint, cvcount );
	pointsPointerPair.setDetailType( rVertex );
	pointsPointerPair.setTokenFloats( CVs );

	// Warning: CVs shares ownership with of its data with pointsPointerPair now!
  // Saves us from redundant copying as long as we know what we are doing
	tokenPointerArray.push_back( pointsPointerPair );

	// constant width or not
	float baseWidth( .1 ), tipWidth( .1 );
	bool constantWidth( false );
  liquidGetPlugValue( fnDag, "liquidCurveBaseWidth", baseWidth, status );
  liquidGetPlugValue( fnDag, "liquidCurveTipWidth", tipWidth, status );

	if( tipWidth == baseWidth )
		constantWidth = true;

	if ( constantWidth )
	{
		liqTokenPointer pConstWidthPointerPair;
		pConstWidthPointerPair.set( "constantwidth", rFloat );
		pConstWidthPointerPair.setDetailType( rConstant );
		pConstWidthPointerPair.setTokenFloat( 0, baseWidth );
		tokenPointerArray.push_back( pConstWidthPointerPair );
	}
	else
	{
		NuCurveWidth = shared_array< RtFloat >( new RtFloat[ cvcount - ncurves * 2 ] );
		k = 0;
		for( unsigned i( 0 ); i < ncurves; i++ )
		{
			// easy way just linear - might have to be refined
			MItCurveCV itCurve( curveObj[i] );
			NuCurveWidth[k++] = baseWidth;
			NuCurveWidth[k++] = baseWidth;
			for( unsigned n( 3 ); n < nverts[i] - 3; n++ )
			{
				float difference = tipWidth - baseWidth;
				if( difference < 0 )
					difference *= -1;
				float basew ( baseWidth );
				if( baseWidth > tipWidth )
					NuCurveWidth[k++] = basew - ( n - 2 ) * difference / ( nverts[i] - 5 );
				else
					NuCurveWidth[k++] = basew + ( n - 2 ) * difference / ( nverts[i] - 5 );
			}
			NuCurveWidth[k++] = tipWidth;
			NuCurveWidth[k++] = tipWidth;
		}
		liqTokenPointer widthPointerPair;
		widthPointerPair.set( "width", rFloat, cvcount - ncurves * 2 );
		widthPointerPair.setDetailType( rVarying );
		widthPointerPair.setTokenFloats( NuCurveWidth );
		tokenPointerArray.push_back( widthPointerPair );
	}
	addAdditionalSurfaceParameters( curveGroup );
}
コード例 #26
0
ファイル: createClipCmd.cpp プロジェクト: BigRoy/Maya-devkit
MStatus createClip::doIt( const MArgList& args )
{
	// parse the command arguments
	//
	MStatus stat = parseArgs(args);
	if (stat != MS::kSuccess) {
		return stat;
	}
	
	unsigned int count = 0;

	// if the character flag was used, create the clip on the specified
	// character, otherwise, create a character
	//
	MFnCharacter fnCharacter;
	if (fCharacter.isNull()) {
		MSelectionList activeList;
		MGlobal::getActiveSelectionList (activeList);
		if (0 == activeList.length()) {
			MString errMsg("No character was specified, and no objects were selected.");
			displayError(errMsg);
			return MS::kFailure;
		}
		// create a character using the selection list
		//
		fCharacter = fnCharacter.create(activeList,MFnSet::kNone,&stat);
		if (stat != MS::kSuccess) {
			MString errMsg("Failed to create character using the selection.");
			displayError(errMsg);
			return MS::kFailure;
		}
	} else {
		fnCharacter.setObject(fCharacter);
	}

	// Get the array of members of the character. We will create a clip
	// for them.
	//
	MPlugArray plugs;
	fnCharacter.getMemberPlugs(plugs);

	// Now create a animCurves to use as a clip for the character.
	// The curves will be set up between frames 0 and 10;
	//
	MTime start(0.0);
	MTime duration(10.0);
	MObjectArray clipCurves;
	
	for (count = 0; count < plugs.length(); ++count) {
		// Now create a bunch of animCurves to use as a clip for the
		// character
		//
		MFnAnimCurve fnCurve;
//		AnimCurveType plugType = fnCurve.timedAnimCurveTypeForPlug(plugs[count]);
		MObject curve = fnCurve.create(MFnAnimCurve::kAnimCurveTL); // plugType);
		fnCurve.addKeyframe(start,5.0);
		fnCurve.addKeyframe(duration,15.0);
		clipCurves.append(curve);
	}
	
	// Create a source clip node and add the animation to it
	//
	MFnClip fnClipCreate;
	MObject sourceClip = fnClipCreate.createSourceClip(start,duration,fMod,&stat);
	fnCharacter.attachSourceToCharacter(sourceClip,fMod);	
	for (count = 0; count < plugs.length(); ++count) {
		MPlug animPlug = plugs[count];
		fnCharacter.addCurveToClip(clipCurves[count],sourceClip,animPlug,fMod);
	}

	// instance the clip
	//
	MTime schedStart(15.0);
	MObject instancedClip = fnClipCreate.createInstancedClip(sourceClip,
															 schedStart,
															 fMod,
															 &stat);
	fnCharacter.attachInstanceToCharacter(instancedClip,fMod);

	// instance the clip a second time, at time 30
	//
	schedStart.setValue(30.0);
	MObject instancedClip2 = fnClipCreate.createInstancedClip(sourceClip,
															  schedStart,
															  fMod,
															  &stat);
	fnCharacter.attachInstanceToCharacter(instancedClip2,fMod);

	return stat;
}
コード例 #27
0
MStatus findFileTextures::doIt( const MArgList& args )
{

	MSelectionList list;
    MStatus        status;

	if ( args.length() > 0 ) {
		// Arg list is > 0 so use objects that were passes in
		//
		MString argStr;

		unsigned last = args.length();
		for ( unsigned i = 0; i < last; i++ ) {
			// Attempt to find all of the objects matched
			// by the string and add them to the list
			//
			args.get( i, argStr );  
			list.add( argStr ); 
		}
	} else {
		// Get arguments from Maya's selection list.
		MGlobal::getActiveSelectionList( list );
    }

	MObject             node;
    MFnDependencyNode   nodeFn,dgNodeFnSet;
    MItDependencyGraph* dgIt; 
    MObject             currentNode;
	MObject 			thisNode;
    MObjectArray        nodePath;

	for ( MItSelectionList iter( list ); !iter.isDone(); iter.next() ) {

		iter.getDependNode( node );

        //
        // The following code shows how to navigate the DG manually without
        // using an iterator.  First, find the attribute that you are 
        // interested.  Then connect a plug to it and see where the plug 
        // connected to.  Once you get all the connections, you can choose 
        // which route you want to go.
        //
        // In here, we wanted to get to the nodes that instObjGroups connected
        // to since we know that the shadingEngine connects to the instObjGroup
        // attribute.
        //

        nodeFn.setObject( node );
        MObject iogAttr = nodeFn.attribute( "instObjGroups", &status);
		if ( !status ) {
			cerr << nodeFn.name() << ": is not a renderable object, skipping\n";
			continue;
		}

        MPlug iogPlug( node, iogAttr );
        MPlugArray iogConnections;

        //
        // instObjGroups is a multi attribute.  In this example, just the
        // first connection will be tried.
        //
        iogPlug.elementByLogicalIndex(0).connectedTo( iogConnections, false, true, &status );

		if ( !status ) {
			cerr << nodeFn.name() << ": is not in a shading group, skipping\n";
			continue;
		}

        //
        // Now we would like to traverse the DG starting from the shadingEngine
        // since most likely all file texture nodes will be found.  Note the 
        // filter used to initialize the DG iterator.  There are lots of filter
        // type available in MF::Type that you can choose to suite your needs.
        //
		bool foundATexture = false;
        for ( unsigned int i=0; i<iogConnections.length(); i++ ) {

            currentNode = iogConnections[i].node();

            // 
            // Note that upon initilization, the current pointer of the 
            // iterator already points to the first valid node.
            //
            dgIt = new MItDependencyGraph( currentNode, 
                               MFn::kFileTexture,
                               MItDependencyGraph::kUpstream, 
                               MItDependencyGraph::kBreadthFirst,
                               MItDependencyGraph::kNodeLevel, 
                               &status );
			if ( !status ) {
				delete dgIt;
				continue;
			}
            dgIt->disablePruningOnFilter();

            for ( ; ! dgIt->isDone(); dgIt->next() ) {
              
			   	thisNode = dgIt->thisNode();
                dgNodeFnSet.setObject( thisNode ); 
                status = dgIt->getNodePath( nodePath );

                if ( !status ) {
					status.perror("getNodePath");
					continue;
                }

                //
                // append the starting node.
                //
                nodePath.append(node);
                dumpInfo( thisNode, dgNodeFnSet, nodePath );
				foundATexture = true;
            }
            delete dgIt;
        }
		
		if ( !foundATexture ) {
			cerr << nodeFn.name() << ": is not connected to a file texture\n";
		}
    }
    return MS::kSuccess; 
}
コード例 #28
0
ファイル: Utility.cpp プロジェクト: andreaforapani/vHelix
	MStatus SelectedBases(MObjectArray & result) {
		MStatus status;
		MSelectionList selectionList;

		if (!(status = MGlobal::getActiveSelectionList(selectionList))) {
			status.perror("MGlobal::getActiveSelectionList");
			return status;
		}

		if (!(status = result.clear())) {
			status.perror("MDagPathArray::clear");
			return status;
		}

		unsigned int selectionList_length = selectionList.length(&status);

		if (!status) {
			status.perror("MSelectionList::length");
			return status;
		}

		for(unsigned int i = 0; i < selectionList_length; ++i) {
			MObject depNode;
			if (!(status = selectionList.getDependNode(i, depNode))) {
				status.perror("MSelectionList::getDependNode");
				return status;
			}

			MFnDagNode dagNode(depNode);

			if (dagNode.typeId(&status) == HelixBase::id)
				result.append(depNode);
			else {
				// This is not a HelixBase, but it's parent might be?

				unsigned int parentCount = dagNode.parentCount(&status);

				if (!status) {
					status.perror("MFnDagNode::parentCount");
					continue;
				}

				for(unsigned int j = 0; j < parentCount; ++j) {
					MObject parent = dagNode.parent(j, &status);

					if (!status) {
						status.perror("MFnDagNode::parent");
						break;
					}

					MFnDagNode parent_dagNode(parent);

					if (parent_dagNode.typeId(&status) == HelixBase::id) {
						if (!(status = result.append(parent))) {
							status.perror("MObjectArray::append");
							return status;
						}
					}
				}
			}
		}

		return MStatus::kSuccess;
	}
コード例 #29
0
MStatus slopeShaderBehavior::connectNodeToNode( MObject &sourceNode, MObject &destinationNode, bool force )
//
//	Description:
//		Overloaded function from MPxDragAndDropBehavior
//	this method will handle the connection between the slopeShader and the shader it is
//	assigned to as well as any meshes that it is assigned to. 
//
{
	MStatus result = MS::kFailure;
	MFnDependencyNode src(sourceNode);

	//if we are dragging from a lambert
	//we want to check what we are dragging
	//onto.
	if(sourceNode.hasFn(MFn::kLambert))
	{
		MObject shaderNode;
		MPlugArray connections;
		MObjectArray shaderNodes;
		shaderNodes.clear();

		//if the source node was a lambert
		//than we will check the downstream connections to see 
		//if a slope shader is assigned to it.
		//
		src.getConnections(connections);
		unsigned i;
		for(i = 0; i < connections.length(); i++)
		{
			//check the incoming connections to this plug
			//
			MPlugArray connectedPlugs;
			connections[i].connectedTo(connectedPlugs, true, false);
			for(unsigned j = 0; j < connectedPlugs.length(); j++)
			{
				//if the incoming node is a slope shader than 
				//append the node to the shaderNodes array
				//
				MObject currentnode = connectedPlugs[j].node();
				if(MFnDependencyNode(currentnode).typeName() == "slopeShader")
				{
					shaderNodes.append(currentnode);
				}
			}
		}

		//if we found a shading node
		//than check the destination node 
		//type to see if it is a mesh
		//
		if(shaderNodes.length() > 0)
		{
			MFnDependencyNode dest(destinationNode);
			if(destinationNode.hasFn(MFn::kMesh))
			{
				//if the node is a mesh than for each slopeShader
				//connect the worldMesh attribute to the dirtyShaderPlug
				//attribute to force an evaluation of the node when the mesh
				//changes
				//
				for(i = 0; i < shaderNodes.length(); i++)
				{
					MPlug srcPlug = dest.findPlug("worldMesh");
					MPlug destPlug = MFnDependencyNode(shaderNodes[i]).findPlug("dirtyShaderPlug");

					if(!srcPlug.isNull() && !destPlug.isNull())
					{
						MString cmd = "connectAttr -na ";
						cmd += srcPlug.name() + " ";
						cmd += destPlug.name();
						MGlobal::executeCommand(cmd);
					}
				}

				//get the shading engine so we can assign the shader
				//to the mesh after doing the connection
				//
				MObject shadingEngine = findShadingEngine(sourceNode);

				//if there is a valid shading engine than make
				//the connection
				//
				if(!shadingEngine.isNull())
				{
					MString cmd = "sets -edit -forceElement ";
					cmd += MFnDependencyNode(shadingEngine).name() + " ";
					cmd += MFnDagNode(destinationNode).partialPathName();
					result = MGlobal::executeCommand(cmd);
				}
			}
		}
	}
	else if(src.typeName() == "slopeShader")
	//if we are dragging from a slope shader
	//than we want to see what we are dragging onto
	//
	{
		if(destinationNode.hasFn(MFn::kMesh))
		{
			//if the user is dragging onto a mesh
			//than make the connection from the worldMesh
			//to the dirtyShader plug on the slopeShader
			//
			MFnDependencyNode dest(destinationNode);
			MPlug srcPlug = dest.findPlug("worldMesh");
			MPlug destPlug = src.findPlug("dirtyShaderPlug");
			if(!srcPlug.isNull() && !destPlug.isNull())
			{
				MString cmd = "connectAttr -na ";
				cmd += srcPlug.name() + " ";
				cmd += destPlug.name();
				result = MGlobal::executeCommand(cmd);
			}
		}
	}

	return result;
}