void ParameterisedHolder<B>::nonNetworkedConnections( const MPlug &plug, MPlugArray &connectionsFromPlug, MPlugArray &connectionsToPlug ) const
{
    MPlugArray from;
    MPlugArray to;

    // the MPlug.connectedTo() method is documented as always returning networked plugs.
    plug.connectedTo( from, false, true );
    plug.connectedTo( to, true, false );

    connectionsFromPlug.clear();
    connectionsFromPlug.setLength( from.length() );
    connectionsToPlug.clear();
    connectionsToPlug.setLength( to.length() );

    for( unsigned i=0; i<from.length(); i++ )
    {
        // the MPlug( node, attribute ) constructor is documented as always returning non-networked plugs.
        connectionsFromPlug.set( MPlug( from[i].node(), from[i].attribute() ), i );
    }

    for( unsigned i=0; i<to.length(); i++ )
    {
        connectionsToPlug.set( MPlug( to[i].node(), to[i].attribute() ), i );
    }
}
void vixo_hairCacheExport::getInCurveInfo(map<int,int>& plugMapVID,MString vixoHairNode,map<int,MVectorArray>& inCurveShape)
{

	MSelectionList slist;
	MGlobal::getSelectionListByName(vixoHairNode,slist);
	MDagPath vixoHairNodeDag;
	slist.getDagPath(0,vixoHairNodeDag);
	vixoHairNodeDag.extendToShape();
	MFnDagNode fnVixoHair(vixoHairNodeDag);
	MPlug plugInCtrlCurveData=fnVixoHair.findPlug("inCtrlCurveData");

	map<int,int>::iterator iterPlugMapVID;
	for(iterPlugMapVID=plugMapVID.begin();iterPlugMapVID!=plugMapVID.end();iterPlugMapVID++)
	{
		MPlug inCurvePlug=plugInCtrlCurveData.elementByLogicalIndex(iterPlugMapVID->first);
		MFnVectorArrayData fnVector(inCurvePlug.asMObject());
		MVectorArray data=fnVector.array();
		MVectorArray tangent(data.length()-1);

		MPlugArray tempArr;
		inCurvePlug.connectedTo(tempArr,true,false);
		MFnDependencyNode fnHairSystem(tempArr[0].node());
		MPlug inputHairs=fnHairSystem.findPlug("inputHair");
		tempArr.clear();
		inputHairs.elementByLogicalIndex(iterPlugMapVID->first).connectedTo(tempArr,true,false);
		MFnDependencyNode fnFolli(tempArr[0].node());
		MFnMatrixData fnMatData(fnFolli.findPlug("worldMatrix[0]").asMObject());
		MMatrix mat=fnMatData.matrix();

		for(int i=0;i<data.length()-1;i++)
		{
			tangent[i]=data[i+1]*mat-data[i]*mat;
		}

		inCurveShape.insert(pair<int,MVectorArray>(iterPlugMapVID->second,tangent));
	}
	
}
MStatus vixo_hairCacheExport::doIt(const MArgList& args)
{
	MString vixoHairNode;
	int startFrame,endFrame;
	unsigned index;
	index=args.flagIndex("vhn","vixoHairNode");
	if(MArgList::kInvalidArgIndex!=index)
	{
		args.get(index+1,vixoHairNode);
	}
	index=args.flagIndex("sf","startFrame");
	if(MArgList::kInvalidArgIndex!=index)
	{
		args.get(index+1,startFrame);
	}
	index=args.flagIndex("ef","endFrame");
	if(MArgList::kInvalidArgIndex!=index)
	{
		args.get(index+1,endFrame);
	}

	//get hairCacheFileName
	MSelectionList slist;
	MGlobal::getSelectionListByName(vixoHairNode,slist);
	MDagPath vixoHairNodeDag;
	slist.getDagPath(0,vixoHairNodeDag);
	vixoHairNodeDag.extendToShape();
	MFnDagNode fnVixoHair(vixoHairNodeDag);
	MPlug plugCacheFileName=fnVixoHair.findPlug("hairCacheFileName");
	MString cacheFileName=plugCacheFileName.asString();
	//~get hairCacheFileName

	//get staticMesh
	MPlug plugStaticMesh=fnVixoHair.findPlug("staticInMesh");
	MObject staticMeshObj=MFnMeshData(plugStaticMesh.asMObject()).object();
	//~get staticMesh

	//build out dataBase
	MFnMesh fnStaticMesh(staticMeshObj);
	map<int,set<outInVertexRelationInfo>> outVertexDataBase;
	map<int,vector<outVIDCtrlInfo>> outVertexControlData;
	for(int i=0;i<fnStaticMesh.numVertices();i++)
	{
		set<outInVertexRelationInfo> temp;
		temp.clear();
		outVertexDataBase.insert(pair<int,set<outInVertexRelationInfo>>(i,temp));
	}
	//build out dataBase

	//get inCurveVID
	map<int,int> plugMapVID;
	map<int,int> VIDMapPlug;
	map<int,inVertexBasicInfo> inVIDMapInVertexDataBase;
	MPlug plugAllInCurve=fnVixoHair.findPlug("inCtrlCurveData");
	MIntArray existIndex;
	plugAllInCurve.getExistingArrayAttributeIndices(existIndex);
	for(int i=0;i<existIndex.length();i++)
	{
		MPlugArray arr;
		plugAllInCurve.elementByLogicalIndex(existIndex[i]).connectedTo(arr,true,false);
		MFnDependencyNode fnHairSystem(arr[0].node());
		MPlug inputHairs=fnHairSystem.findPlug("inputHair");
		arr.clear();
		inputHairs.elementByLogicalIndex(existIndex[i]).connectedTo(arr,true,false);
		MFnDependencyNode fnFolli(arr[0].node());
		int vid=fnFolli.findPlug("vertexID").asInt();
		plugMapVID.insert(pair<int,int>(existIndex[i],vid));
		VIDMapPlug.insert(pair<int,int>(vid,existIndex[i]));
		initBasicStepInfo(vid,staticMeshObj,inVIDMapInVertexDataBase);
	}	
	//~get inCurveVID

	//build in out relation
	map<int,inVertexBasicInfo>::iterator inDBIter;
	for(inDBIter=inVIDMapInVertexDataBase.begin();inDBIter!=inVIDMapInVertexDataBase.end();inDBIter++)
	{
		buileRelationBetweenInOut(inDBIter->first,inVIDMapInVertexDataBase,outVertexDataBase);
	}

	map<int,set<outInVertexRelationInfo>>::iterator outDBIter;
	for(outDBIter=outVertexDataBase.begin();outDBIter!=outVertexDataBase.end();outDBIter++)
	{
		sortControlOrder(outDBIter->first,outVertexDataBase,outVertexControlData);
	}
	//~build in out relation

	for(int i=startFrame;i<=endFrame;i++)
	{
		MString currentTime;
		currentTime.set(i);
		MGlobal::executeCommand("currentTime "+currentTime);
		MGlobal::executeCommand("dgeval "+vixoHairNode+".hiddenOutput");

		//get dynamic mesh
		MPlug plugDynamicMesh=fnVixoHair.findPlug("dynamicInMesh");
		MObject dynamicMeshObj=MFnMeshData(plugDynamicMesh.asMObject()).object();
		//~get dynamic mesh

		//export cache
		//faceid triid vid position normal tangent
		vector<forExportHairCache> exportData;
		exportBasicData(dynamicMeshObj,exportData);
		//curve tangent
		//get in curve infos
		map<int,MVectorArray> inCurveShape;
		getInCurveInfo(plugMapVID,vixoHairNode,inCurveShape);
		//~get in curve infos

		vector<vec3> outCurveCacheData;
		vec3 init;
		init.x=0;
		init.y=0;
		init.z=0;
		outCurveCacheData.resize(fnStaticMesh.numVertices()*inCurveShape.begin()->second.length(),init);
		buildCache(inCurveShape.begin()->second.length(),dynamicMeshObj,outCurveCacheData,inCurveShape,outVertexControlData);
		//~export cache

		//write to file
		MString fileName=getFileName(cacheFileName,i);
		fstream fout(fileName.asChar(),ios_base::out|ios_base::binary);
		int triNumvertexNum[3];
		triNumvertexNum[0]=exportData.size();
		triNumvertexNum[1]=fnStaticMesh.numVertices();
		triNumvertexNum[2]=inCurveShape.begin()->second.length();
		fout.write((char*)triNumvertexNum,sizeof(int)*3);
		fout.write((char*)&exportData[0],sizeof(forExportHairCache)*exportData.size());
		fout.write((char*)&outCurveCacheData[0],sizeof(vec3)*outCurveCacheData.size());
		fout.flush();
		fout.close();
		/*
		MString fileNameDebug=fileName+".dbg";
		fout.open(fileNameDebug.asChar(),ios_base::out);
		for(int i=0;i<outCurveCacheData.size();i++)
		{
			fout<<outCurveCacheData[i].x<<" "<<outCurveCacheData[i].y<<" "<<outCurveCacheData[i].z<<endl;
		}
		fout.flush();
		fout.close();
		*/
		//~write to file
	}

	return MS::kSuccess;
}
Beispiel #4
0
// --------------------------------------------------------------------------------------------
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;
}