//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
MDagPath CVsSkinnerCmd::GetSpecifiedSkinnerNode()
{
	MSelectionList skinnerNodes;
	MSelectionList optSelectionList;

	m_undo.ArgDatabase().getObjects( optSelectionList );

	GetSpecifiedSkinnerNodes( optSelectionList, skinnerNodes );

	MDagPath mDagPath;

	if ( skinnerNodes.length() == 0U )
		return mDagPath;

	if ( skinnerNodes.length() > 1U )
	{
		skinnerNodes.getDagPath( 0U, mDagPath );

		mwarn << "Using vsSkinnerNode " << mDagPath.partialPathName() << ", ignoring extra vsSkinnerNode";
		if ( skinnerNodes.length() > 2U )
			mwarn << "s";
		mwarn << ":";

		for ( uint i( 1U ); i != skinnerNodes.length(); ++i )
		{
			skinnerNodes.getDagPath( i, mDagPath );
			mwarn << " " << mDagPath.partialPathName();
		}

		mwarn << std::endl;
	}

	skinnerNodes.getDagPath( 0U, mDagPath );
	return mDagPath;
}
示例#2
0
//
// Write out a 'parent' command to parent one DAG node under another.
//
void maTranslator::writeParent(
		fstream& f, const MDagPath& parent, const MDagPath& child, bool addIt
)
{
	f << "parent -s -nc -r ";
 
	//
	// If this is not the first parent then we have to include the "-a/add"
	// flag.
	//
	if (addIt) f << "-a ";

	//
	// If the parent is the world, then we must include the "-w/world" flag.
	//
	if (parent.length() == 0) f << "-w ";

	f << "\"" << child.partialPathName().asChar() << "\"";

	//
	// If the parent is NOT the world, then give the parent's name.
	//
	if (parent.length() != 0)
		f << " \"" << parent.partialPathName().asChar() << "\"";

	f << ";" << endl;
}
示例#3
0
//
// Write out a 'createNode' command for a DAG node.
//
void maTranslator::writeCreateNode(
		fstream& f, const MDagPath& nodePath, const MDagPath& parentPath
)
{
	MObject		node(nodePath.node());
	MFnDagNode	nodeFn(node);

	//
	// Write out the 'createNode' command for this node.
	//
	f << "createNode " << nodeFn.typeName().asChar();

	//
	// If the node is shared, then add a "-s/shared" flag to the command.
	//
	if (nodeFn.isShared()) f << " -s";

	f << " -n \"" << nodeFn.name().asChar() << "\"";

	//
	// If this is not a top-level node, then include its first parent in the
	// command.
	//
	if (parentPath.length() > 0)
		f << " -p \"" << parentPath.partialPathName().asChar() << "\"";
   
	f << ";" << endl;
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
MStatus CVsSkinnerCmd::DoLs()
{
	MSelectionList tmpList;

	if ( m_undo.ArgDatabase().isFlagSet( kOptSelected ) )
	{
		MSelectionList skinnerNodes;
		m_undo.ArgDatabase().getObjects( skinnerNodes );

		GetSpecifiedSkinnerNodes( skinnerNodes, tmpList );
	}
	else
	{
		MDagPath eDagPath;
		FindSkinnerNodesInHierarchy( eDagPath, tmpList );
	}

	const bool longPath( m_undo.ArgDatabase().isFlagSet( kOptLong ) );
	MStringArray result;

	MDagPath mDagPath;
	for ( MItSelectionList sIt( tmpList ); !sIt.isDone(); sIt.next() )
	{
		if ( sIt.getDagPath( mDagPath ) )
		{
			result.append( longPath ? mDagPath.fullPathName() : mDagPath.partialPathName() );
		}
	}

	setResult( result );

	return MS::kSuccess;
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
MStatus CVsSkinnerCmd::DoCreate()
{
	// Get name command line arg
	MString optName;
	if ( m_undo.ArgDatabase().isFlagSet( kOptName ) )
	{
		m_undo.ArgDatabase().getFlagArgument( kOptName, 0, optName );
	}

	// Create vsSkinner node
	MObject stObj;			// Skinner transform object
	MObject vsSkinnerObj;	// Skinner shape object

	MDagModifier &mDagModifier( m_undo.DagModifier() );

	if ( vm::CreateDagNode(
		"vsSkinner",
		optName.length() ? optName.asChar() : GetName().asChar(),
		MObject ::kNullObj,
		&stObj,
		&vsSkinnerObj,
		&mDagModifier ) != MS::kSuccess )
	{
		displayError( MString( "Couldn't create " ) + GetName() + " transform node" );
		m_undo.Undo();

		return MS::kFailure;
	}

	MDagPath stPath;
	MDagPath::getAPathTo( stObj, stPath );
	setResult( stPath.partialPathName() );

	MDagPath skinnerPath;
	MDagPath::getAPathTo( vsSkinnerObj, skinnerPath );

	MSelectionList optSelectionList;
	m_undo.ArgDatabase().getObjects( optSelectionList );
	MSelectionList volumeList( DoNewVolumes( skinnerPath, optSelectionList ) );

	if ( volumeList.length() )
	{
		MGlobal::setActiveSelectionList( volumeList, MGlobal::kReplaceList );
	}
	else
	{
		MGlobal::select( stPath, MObject::kNullObj, MGlobal::kReplaceList );
	}

	return MS::kSuccess;
}
示例#6
0
MStatus unShowAvailableSystems::findAvailableSystems(std::string& str,MDagPath& dagPath)
{
	MStatus stat = MS::kSuccess;

	if(dagPath.hasFn(MFn::kJoint))
	{
		MFnIkJoint jointFn(dagPath);
		std::string name = dagPath.partialPathName().asChar();
		MPlug plug = jointFn.findPlug("unRibbonEnabled");
		if(!plug.isNull())
		{
			bool enabled;
			plug.getValue(enabled);
			char s[256];
			sprintf(s,"%s RibbonSystem %s\n",name.c_str(),enabled ? "True" : "False");
			str += s;
		}
		plug = jointFn.findPlug("unParticleEnabled");
		if(!plug.isNull())
		{
			bool enabled;
			plug.getValue(enabled);
			char s[256];
			sprintf(s,"%s ParticleSystem %s\n",name.c_str(),enabled ? "True" : "False");
			str += s;
		}
	}

	for (unsigned int i = 0; i < dagPath.childCount(); i++)
	{
		MObject child = dagPath.child(i);
		MDagPath childPath;
		stat = MDagPath::getAPathTo(child,childPath);
		if (MS::kSuccess != stat)
		{
			return MS::kFailure;
		}
		stat = findAvailableSystems(str,childPath);
		if (MS::kSuccess != stat)
			return MS::kFailure;
	}
	return MS::kSuccess;
}
MStatus CMayaManager::BindViewerToPanel (const char* strView)
{
    //HRESULT hr= S_OK;
    HWND renderwnd= NULL;
    MDagPath MayaCamera;

    if(strView == NULL)
        strView= "";

    StringCchCopyA(m_ViewerBinding, MAX_PATH, strView);

    if(strView && (strView[0] != '\0'))
    {
        if(0 == lstrcmpiA(strView, "floating"))
        {
            g_Viewer.BindToWindow(NULL, true);
        }
        else
        {
            M3dView ourView;
            M3dView::get3dView(0,ourView);

            for(UINT iView= 0; iView < M3dView::numberOf3dViews(); iView++)
            {
                M3dView::get3dView(iView, ourView);
                ourView.getCamera(MayaCamera);
                MayaCamera.pop();
                if(MayaCamera.partialPathName() == MString(strView))
                {
                    renderwnd= (HWND)ourView.window();
                    g_Viewer.BindToWindow(ourView.window(), true);
                    break;
                }
            }
        }
    }

//e_Exit:

    return MS::kSuccess;
}
void Exporter::OutputSkinCluster(MObject& obj)
{
	// attach a skin cluster function set to
	// access the data
	skinData SD;
	MFnSkinCluster fn(obj);
	MDagPathArray infs;

	//Get influences
	SD.influences = fn.influenceObjects(infs);

	// loop through the geometries affected by this cluster
	int nGeoms = fn.numOutputConnections();
	for (int i = 0; i < nGeoms; ++i) {
		unsigned int index;
		index = fn.indexForOutputConnection(i);

		// get the dag path of the i'th geometry
		MDagPath skinPath;
		fn.getPathAtIndex(index, skinPath);

		// iterate through the components of this geometry
		MItGeometry gIter(skinPath);

		// print out the name of the skin cluster,
		// the vertexCount and the influenceCount
		cout << "Skin: " << skinPath.partialPathName().asChar() << endl;
		cout << "pointcount: " << gIter.count() << endl;
		cout << "numInfluences: " << SD.influences << endl;

		//Get points affected
		SD.points = gIter.count();

		for (; !gIter.isDone(); gIter.next()) {

			MObject comp = gIter.component();
			// Get the weights for this vertex (one per influence object)
			//
			MFloatArray wts;
			unsigned int infCount;
			fn.getWeights(skinPath, comp, wts, infCount);
			if (0 != infCount && !gIter.isDone())
			{
				int numWeights = 0;
				float outWts[40] = { 1.0f, 0 };
				int outInfs[40] = { 0 };

				// Output the weight data for this vertex
				//
				for (int j = 0; j != infCount; ++j)
				{
					// ignore weights of little effect
					if (wts[j] > 0.001f)
					{
						if (numWeights != 0)
						{
							outWts[0] -= wts[j];
							outWts[numWeights] = wts[j];
						}
						outInfs[numWeights] = j;
						++numWeights;
					}
				}
				float norm = outWts[0] + outWts[1] + outWts[2] + outWts[3];


				MDagPath dag_path;
				MItDag dag_iter(MItDag::kBreadthFirst, MFn::kMesh);
				int currentmesh = 0, y = 0;
				while (!dag_iter.isDone())
				{
					if (dag_iter.getPath(dag_path))
					{
						MFnDagNode dag_node = dag_path.node();
						if (!dag_node.isIntermediateObject())
						{
							MFnMesh mesh(dag_path);
							if (!strcmp(skinPath.partialPathName().asChar(), mesh.partialPathName().asChar()))
								currentmesh = y;
							y++;
						}
					}

					dag_iter.next();
				}


				for (int x = 0; x < 4; x++)
				{
					scene_.meshes[currentmesh].points[gIter.index()].boneIndices[x] = outInfs[x];
					scene_.meshes[currentmesh].points[gIter.index()].boneWeigths[x] = outWts[x] / norm;
				}
				scene_.meshes[currentmesh].hasSkeleton = true;
			}
		}
	}
}
MStatus exportJointClusterData::doIt( const MArgList& args )
//
// Process the command	
// 1. parse the args
// 2. find the jointClusters in the scene
// 3. iterate over their members, writing their weight data out to file	
//
{
	// parse args to get the file name from the command-line
	//
	MStatus stat = parseArgs(args);
	if (stat != MS::kSuccess) {
		return stat;
	}

	// count the processed jointClusters
	//
	unsigned int jcCount = 0;

	// Iterate through graph and search for jointCluster nodes
	//
	MItDependencyNodes iter( MFn::kJointCluster);
	for ( ; !iter.isDone(); iter.next() ) {
		MObject object = iter.item();
		MFnWeightGeometryFilter jointCluster(object);

		// get the joint driving this cluster
		//
		MObject joint = jointForCluster(object);
		if (joint.isNull()) {
			displayError("Joint is not attached to cluster.");
			continue;
		}

		MObject deformSet = jointCluster.deformerSet(&stat);
		CheckError(stat,"Error getting deformer set.");
			
		MFnSet setFn(deformSet, &stat);	//need the fn to get the members
		CheckError(stat,"Error getting deformer set fn.");
		
		MSelectionList clusterSetList;

		//get all the members
		//
		stat = setFn.getMembers(clusterSetList, true);
		CheckError(stat,"Could not make member list with getMembers.");

		// print out the name of joint and the number of associated skins
		//
		MFnDependencyNode fnJoint(joint);
		fprintf(file,"%s %u\n",fnJoint.name().asChar(),
				clusterSetList.length());
		
		for (unsigned int kk = 0; kk < clusterSetList.length(); ++kk) {
			MDagPath skinpath;
			MObject components;
			MFloatArray weights;

			clusterSetList.getDagPath(kk,skinpath,components);
			jointCluster.getWeights(skinpath,components,weights);

			// print out the path name of the skin & the weight count
			//
			fprintf(file,
					"%s %u\n",skinpath.partialPathName().asChar(),
					weights.length());

			// loop through the components and print their index and weight
			//
			unsigned counter =0;
			MItGeometry gIter(skinpath,components);
			for (/* nothing */ ; !gIter.isDone() &&
								   counter < weights.length(); gIter.next()) {
				fprintf(file,"%d %f\n",gIter.index(),weights[counter]);
				counter++;
			}
		}
		jcCount++;
	}

	fclose(file);

	if (0 == jcCount) {
		displayError("No jointClusters found in this scene.");
		return MS::kFailure;
	}

	return MS::kSuccess;
}
HRESULT CMayaManager::PerspectiveCamera_Synchronize()
{
    MDagPath MayaCamera;
    M3dView panel;
    for(UINT iView= 0; iView < M3dView::numberOf3dViews(); iView++)
    {
        D3DXMATRIX mCamera;
        M3dView::get3dView(iView, panel);
        panel.getCamera(MayaCamera);
        MayaCamera.pop();

        MString perspNameStr( "persp" );
        MString cameraNameStr = MayaCamera.partialPathName();

        cameraNameStr = cameraNameStr.substring(0, perspNameStr.length()-1 );
        const char* cameraName= cameraNameStr.asChar();

        if(cameraNameStr == perspNameStr )
        {
            MayaCamera.extendToShape();
            MFloatMatrix fView(MayaCamera.inclusiveMatrix().matrix );

            ConvertWorldMatrix(mCamera, fView);

            panel.getCamera(MayaCamera);
            MFnCamera fnMayaCamera(MayaCamera.node());

            MVector mUp= fnMayaCamera.upDirection();
            MVector mAt= fnMayaCamera.viewDirection();
            MPoint mEye= fnMayaCamera.eyePoint(MSpace::kWorld);

            D3DXVECTOR3 dxEye( (float)mEye.x, (float)mEye.y, (float)-mEye.z );
            D3DXVECTOR3 dxAt( (float)mAt.x, (float)mAt.y, (float)-mAt.z );
            D3DXVECTOR3 dxUp( (float)mUp.x, (float)mUp.y, (float)-mUp.z );
            D3DXVECTOR4 fEye;
            D3DXVECTOR4 fAt;
            D3DXVECTOR3 fUp;

            D3DXVec3Transform(&fEye, &dxEye,(D3DXMATRIX*)&mCamera);
            D3DXVec3Transform(&fAt, &dxAt,(D3DXMATRIX*)&mCamera);
            D3DXVec3TransformNormal(&fUp, &dxUp,(D3DXMATRIX*)&mCamera);


            D3DXMatrixLookAtLH(&PerspectiveCamera_View,
                               (D3DXVECTOR3*)&fEye,
                               (D3DXVECTOR3*)&fAt,
                               &fUp);

            // Projection matrix
            float zNear = (float)fnMayaCamera.nearClippingPlane();
            float zFar = (float)fnMayaCamera.farClippingPlane();
            float hFOV = (float)fnMayaCamera.horizontalFieldOfView();
            float f = (float) (1.0f / (float) tan( hFOV / 2.0f ));

            ZeroMemory( &PerspectiveCamera_Projection, sizeof(PerspectiveCamera_Projection) );
            PerspectiveCamera_Projection._11 = f;
            PerspectiveCamera_Projection._22 = f;
            PerspectiveCamera_Projection._33 = (zFar+zNear) / (zFar-zNear);
            PerspectiveCamera_Projection._34 = 1.0f;
            PerspectiveCamera_Projection._43 = -2 * (zFar*zNear)/(zFar-zNear);

            break;
        }
    }
    return S_OK;
}
示例#11
0
MStatus mshUtil::doIt( const MArgList& args ) 
{
	MString objname, mcfname;
	MArgDatabase argData(syntax(), args);
	
	MSelectionList selList;
	MGlobal::getActiveSelectionList ( selList );

	if ( selList.length() < 2 ) {
		MGlobal:: displayError ( "Not sufficient selection!" );
		return MS::kSuccess;
	}
	
	MItSelectionList iter( selList );
	
	iter.reset();
	
	MDagPath meshPath;		
	iter.getDagPath( meshPath );
	
	meshPath.extendToShape();
	
	MObject meshObj = meshPath.node();

	MString surface = meshPath.partialPathName();
	
	MStatus status;
	MFnMesh meshFn(meshPath, &status );
	
	if(!status) {
		MGlobal:: displayError ( "Not sufficient selection!" );
		return MS::kSuccess;
	}
	
	MPointArray vxa;
	meshFn.getPoints (vxa, MSpace::kWorld);
	
	MPoint cenfrom(0.f, 0.f, 0.f);
	for(unsigned i=0; i<vxa.length(); i++) cenfrom += vxa[i];
	
	cenfrom = cenfrom/(float)vxa.length();
	
	iter.next();
	iter.getDagPath( meshPath );
	
	meshPath.extendToShape();
	
	MFnMesh mesh1Fn(meshPath, &status );
	
	if(!status) {
		MGlobal:: displayError ( "Not sufficient selection!" );
		return MS::kSuccess;
	}
	
	vxa.clear();
	mesh1Fn.getPoints (vxa, MSpace::kWorld);
	
	MPoint cento(0.f, 0.f, 0.f);
	for(unsigned i=0; i<vxa.length(); i++) cento += vxa[i];
	
	cento = cento/(float)vxa.length();
	
	MVector diff = cento - cenfrom;
	
	MDoubleArray res;
	res.append(diff.x);
	res.append(diff.y);
	res.append(diff.z);
	
	setResult ( res );
	
	/*	
	if ( !argData.isFlagSet("-i") || !argData.isFlagSet("-o") ) {
		//MGlobal::displayError( "No .obj or .mcf file specified to translate! Example: mshUtil -i filename.obj -o filename.mcf" );
		return MS::kSuccess;
	}
	else {
		argData.getFlagArgument("-i", 0, objname);
		argData.getFlagArgument("-o", 0, mcfname);
		
				
		return MS::kSuccess;
	}
*/
	return MS::kSuccess;
}
    // --------------------------------------------------------------------
    bool SceneGraph::getIsExportNode ( 
        const MDagPath& dagPath, 
        bool& isForced,
        bool& isVisible )
    {
        // Does this dagPath already exist? If so, only recurse if FollowInstancedChildren() is set.
        MFnDagNode dagFn ( dagPath );
        String dagNodeName = dagFn.name().asChar();

        bool isSceneRoot = dagPath.length() == 0;

        // Ignore default and intermediate nodes (history items)
        bool isIntermediateObject = dagFn.isIntermediateObject();
        if ( ( dagFn.isDefaultNode() && !isSceneRoot ) || isIntermediateObject )
        {
            return false;
        }

        MString nodeName = dagPath.partialPathName();
        if ( nodeName == MString ( NIMA_INTERNAL_PHYSIKS ) )
        {
            // Skip this node, which is only used
            // by Nima as a work-around for a Maya bug.
            return false;
        }

        // If we are not already forcing this node, its children
        // check whether we should be forcing it (skinning of hidden joints).
        isForced = isForcedNode ( dagPath );
        DagHelper::getPlugValue ( dagPath.node(), ATTR_VISIBILITY, isVisible );
        bool isInstanced = dagPath.isInstanced();
        uint instanceNumber = dagPath.instanceNumber();

        if ( !isForced )
        {
            // Check for visibility
            if ( !ExportOptions::exportInvisibleNodes() && !isVisible )
            {
                // Check if the visibility of the element is animated.
                AnimationSampleCache* animationCache = mDocumentExporter->getAnimationCache();
                if ( !AnimationHelper::isAnimated ( animationCache, dagPath.node(), ATTR_VISIBILITY ) )
                {
                    return false;
                }
            }
            else if ( !isVisible && !ExportOptions::exportDefaultCameras() )
            {
                // Check for the default camera transform names.
                if ( nodeName == CAMERA_PERSP || nodeName == CAMERA_TOP || nodeName == CAMERA_SIDE || nodeName == CAMERA_FRONT ||
                     nodeName == CAMERA_PERSP_SHAPE || nodeName == CAMERA_TOP_SHAPE || nodeName == CAMERA_SIDE_SHAPE || nodeName == CAMERA_FRONT_SHAPE )
                    return false;
            }
        }

        isForced &= !isVisible;
        if ( !isForced )
        {
            // We don't want to process manipulators
            if ( dagPath.hasFn ( MFn::kManipulator ) || dagPath.hasFn ( MFn::kViewManip ) ) return false;

            // Check for constraints which are not exported
            //if ( !ExportOptions::exportConstraints() && dagPath.hasFn ( MFn::kConstraint ) ) return false;
            if ( dagPath.hasFn ( MFn::kConstraint ) ) return false;

            // Check set membership exclusion/inclusion
            if ( SetHelper::isExcluded ( dagPath ) ) return false;
        }

        return true;
    }
示例#13
0
文件: Mesh.cpp 项目: cpzhang/zen
MStatus Mesh::load(MDagPath& meshDag,MDagPath *pDagPath)
{
	MStatus stat;
	std::vector<MFloatArray> weights;
	std::vector<MIntArray> Ids;
	std::vector<MIntArray> jointIds;
	unsigned int numJoints = 0;
	std::vector<vertexInfo> vertices;
	MFloatPointArray points;
	MFloatVectorArray normals;

	if (!meshDag.hasFn(MFn::kMesh))
		return MS::kFailure;

	MFnMesh mesh(meshDag);
	/*{
		mesh.getPoints(points,MSpace::kWorld);
		MPoint pos;
		mesh.getPoint(1,pos,MSpace::kWorld);
		for(unsigned i = 0;i < points.length();i++)
		{
			MFloatPoint fp = points[i];
			float x = fp.x;
			float y = fp.y;
			float z = fp.z;
			fp = fp;
		}
	}*/
	int numVertices = mesh.numVertices();
	vertices.resize(numVertices);
	weights.resize(numVertices);
	Ids.resize(numVertices);
	jointIds.resize(numVertices);

	// 获取UV坐标集的名称
	MStringArray uvsets;
	int numUVSets = mesh.numUVSets();
	if (numUVSets > 0)
	{
		stat = mesh.getUVSetNames(uvsets);
		if (MS::kSuccess != stat)
		{
			std::cout << "Error retrieving UV sets names\n";
			return MS::kFailure;
		}
	}
	// 保存UV集信息
	for (int i=m_uvsets.size(); i<uvsets.length(); i++)
	{
		uvset uv;
		uv.size = 2;
		uv.name = uvsets[i].asChar();
		m_uvsets.push_back(uv);
	}

	MStringArray colorSetsNameArray;
	m_colorSets.clear();
	int numColorSets = mesh.numColorSets();
	if (numColorSets > 0)
	{
		mesh.getColorSetNames(colorSetsNameArray);
	}
	for (int i = 0; i != colorSetsNameArray.length(); ++i)
	{
		std::string name = colorSetsNameArray[i].asChar();
		m_colorSets.push_back(name);
	}
	// 检查法线是否反
	bool opposite = false;
	mesh.findPlug("opposite",true).getValue(opposite);

	// get connected skin cluster (if present)
	bool foundSkinCluster = false;
	MItDependencyNodes kDepNodeIt( MFn::kSkinClusterFilter );            
	for( ;!kDepNodeIt.isDone() && !foundSkinCluster; kDepNodeIt.next()) 
	{            
		MObject kObject = kDepNodeIt.item();
		m_pSkinCluster = new MFnSkinCluster(kObject);
		unsigned int uiNumGeometries = m_pSkinCluster->numOutputConnections();
		for(unsigned int uiGeometry = 0; uiGeometry < uiNumGeometries; ++uiGeometry ) 
		{
			unsigned int uiIndex = m_pSkinCluster->indexForOutputConnection(uiGeometry);
			MObject kOutputObject = m_pSkinCluster->outputShapeAtIndex(uiIndex);
			if(kOutputObject == mesh.object()) 
			{
				foundSkinCluster = true;
			}
			else
			{
				delete m_pSkinCluster;
				m_pSkinCluster = NULL;
			}
		}

		// load connected skeleton (if present)
		if (m_pSkinCluster)
		{
			if (!m_pSkeleton)
				m_pSkeleton = new skeleton();
			stat = m_pSkeleton->load(m_pSkinCluster);
			if (MS::kSuccess != stat)
				std::cout << "Error loading skeleton data\n";
		}
		else
		{
//			breakable;
		}
	}
	// get connected shaders
	MObjectArray shaders;
	MIntArray shaderPolygonMapping;
	stat = mesh.getConnectedShaders(0,shaders,shaderPolygonMapping);
	if (MS::kSuccess != stat)
	{
		std::cout << "Error getting connected shaders\n";
		return MS::kFailure;
	}

	if (shaders.length() <= 0)
	{
		std::cout << "No connected shaders, skipping mesh\n";
		return MS::kFailure;
	}

	// create a series of arrays of faces for each different submesh
	std::vector<faceArray> polygonSets;
	polygonSets.resize(shaders.length());

	// Get faces data
	// prepare vertex table
	for (int i=0; i<vertices.size(); i++)
		vertices[i].next = -2;
	//get vertex positions from mesh data

	mesh.getPoints(points,MSpace::kWorld);
	mesh.getNormals(normals,MSpace::kWorld);

	//get list of vertex weights
	if (m_pSkinCluster)
	{
		MItGeometry iterGeom(meshDag);
		for (int i=0; !iterGeom.isDone(); iterGeom.next(), i++)
		{
			weights[i].clear();
			Ids[i].clear();
			MObject component = iterGeom.component();
			MFloatArray vertexWeights;
			stat=m_pSkinCluster->getWeights(meshDag,component,vertexWeights,numJoints);
			int nWeights = vertexWeights.length();
			for(int j = 0;j<nWeights;j++)
			{
				if(vertexWeights[j] >= 0.00001f || vertexWeights[j] <= -0.00001f  )
				{
					// 记录该节点j
					Ids[i].append(j);
					weights[i].append(vertexWeights[j]);
				}
			}
		
			//weights[i]= vertexWeights;

			if (MS::kSuccess != stat)
			{
				std::cout << "Error retrieving vertex weights\n";
			}
			// get ids for the joints
			if (m_pSkeleton)
			{
				jointIds[i].clear();
				if(weights[i].length() > 0 )
				{
					MDagPathArray influenceObjs;
					m_pSkinCluster->influenceObjects(influenceObjs,&stat);
					if (MS::kSuccess != stat)
					{
						std::cout << "Error retrieving influence objects for given skin cluster\n";
					}
					jointIds[i].setLength(weights[i].length());
					for (int j=0; j<jointIds[i].length(); j++)
					{
						bool foundJoint = false;
						for (int k=0; k<m_pSkeleton->getJoints().size() && !foundJoint; k++)
						{
							if (influenceObjs[Ids[i][j]].partialPathName() == m_pSkeleton->getJoints()[k].name)
							{
								foundJoint=true;
								jointIds[i][j] = m_pSkeleton->getJoints()[k].id;
							}
						}
					}
				}
				
			}
		}
	}
	// create an iterator to go through mesh polygons
	if (mesh.numPolygons() > 0)
	{
		const char *name = mesh.name().asChar();
		MItMeshPolygon faceIter(mesh.object(),&stat);
		if (MS::kSuccess != stat)
		{
			std::cout << "Error accessing mesh polygons\n";
			return MS::kFailure;
		}

		// iterate over mesh polygons
		for (; !faceIter.isDone(); faceIter.next())
		{
			int numTris=0;
			faceIter.numTriangles(numTris);
			// for every triangle composing current polygon extract triangle info
			for (int iTris=0; iTris<numTris; iTris++)
			{
				MPointArray triPoints;
				MIntArray tempTriVertexIdx,triVertexIdx;
				int idx;
				// create a new face to store triangle info
				face newFace;
				// extract triangle vertex indices
				faceIter.getTriangle(iTris,triPoints,tempTriVertexIdx);
				// convert indices to face-relative indices
				MIntArray polyIndices;
				faceIter.getVertices(polyIndices);
				unsigned int iPoly, iObj;
				for (iObj=0; iObj < tempTriVertexIdx.length(); ++iObj)
				{
					// iPoly is face-relative vertex index
					for (iPoly=0; iPoly < polyIndices.length(); ++iPoly)
					{
						if (tempTriVertexIdx[iObj] == polyIndices[iPoly]) 
						{
							triVertexIdx.append(iPoly);
							break;
						}
					}
				}
				// iterate over triangle's vertices
				for (int i=0; i<3; i++)
				{
					bool different = true;
					int vtxIdx = faceIter.vertexIndex(triVertexIdx[i]);
					int nrmIdx = faceIter.normalIndex(triVertexIdx[i]);

					// get vertex color
					MColor color;
					if (faceIter.hasColor(triVertexIdx[i]))
					{
						//This method gets the average color of the all the vertices in this face
						stat = faceIter.getColor(color,triVertexIdx[i]);
						if (MS::kSuccess != stat)
						{
							color = MColor(1,1,1,1);
						}
						if (color.r > 1)
							color.r = 1;
						if (color.g > 1)
							color.g = 1;
						if (color.b > 1)
							color.b = 1;
						if (color.a > 1)
							color.a = 1;
					}
					else
					{
						color = MColor(1,1,1,1);
					}
					if (vertices[vtxIdx].next == -2)	// first time we encounter a vertex in this position
					{
						// save vertex position
						points[vtxIdx].cartesianize();
						vertices[vtxIdx].pointIdx = vtxIdx;
						// save vertex normal
						vertices[vtxIdx].normalIdx = nrmIdx;
						// save vertex colour
						vertices[vtxIdx].r = color.r;
						vertices[vtxIdx].g = color.g;
						vertices[vtxIdx].b = color.b;
						vertices[vtxIdx].a = color.a;
						// save vertex texture coordinates
						vertices[vtxIdx].u.resize(uvsets.length());
						vertices[vtxIdx].v.resize(uvsets.length());
						// save vbas
						vertices[vtxIdx].vba.resize(weights[vtxIdx].length());
						for (int j=0; j<weights[vtxIdx].length(); j++)
						{
							vertices[vtxIdx].vba[j] = (weights[vtxIdx])[j];
						}
						// save joint ids
						vertices[vtxIdx].jointIds.resize(jointIds[vtxIdx].length());
						for (int j=0; j<jointIds[vtxIdx].length(); j++)
						{
							vertices[vtxIdx].jointIds[j] = (jointIds[vtxIdx])[j];
						}
						// save uv sets data
						for (int j=0; j<uvsets.length(); j++)
						{
							float2 uv;
							stat = faceIter.getUV(triVertexIdx[i],uv,&uvsets[j]);
							if (MS::kSuccess != stat)
							{
								uv[0] = 0;
								uv[1] = 0;
							}
							vertices[vtxIdx].u[j] = uv[0];
							vertices[vtxIdx].v[j] = (-1)*(uv[1]-1);
						}
						// save vertex index in face info
						newFace.v[i] = vtxIdx;
						// update value of index to next vertex info (-1 means nothing next)
						vertices[vtxIdx].next = -1;
					}
					else	// already found at least 1 vertex in this position
					{
						// check if a vertex with same attributes has been saved already
						for (int k=vtxIdx; k!=-1 && different; k=vertices[k].next)
						{
							different = false;

							MFloatVector n1 = normals[vertices[k].normalIdx];
							MFloatVector n2 = normals[nrmIdx];
							if (n1.x!=n2.x || n1.y!=n2.y || n1.z!=n2.z)
							{
								different = true;
							}


							if (vertices[k].r!=color.r || vertices[k].g!=color.g || vertices[k].b!= color.b || vertices[k].a!=color.a)
							{
								different = true;
							}

							for (int j=0; j<uvsets.length(); j++)
							{
								float2 uv;
								stat = faceIter.getUV(triVertexIdx[i],uv,&uvsets[j]);
								if (MS::kSuccess != stat)
								{
									uv[0] = 0;
									uv[1] = 0;
								}
								uv[1] = (-1)*(uv[1]-1);
								if (vertices[k].u[j]!=uv[0] || vertices[k].v[j]!=uv[1])
								{
									different = true;
								}
							}

							idx = k;
						}
						// if no identical vertex has been saved, then save the vertex info
						if (different)
						{
							vertexInfo vtx;
							// save vertex position
							vtx.pointIdx = vtxIdx;
							// save vertex normal
							vtx.normalIdx = nrmIdx;
							// save vertex colour
							vtx.r = color.r;
							vtx.g = color.g;
							vtx.b = color.b;
							vtx.a = color.a;
							// save vertex vba
							vtx.vba.resize(weights[vtxIdx].length());
							for (int j=0; j<weights[vtxIdx].length(); j++)
							{
								vtx.vba[j] = (weights[vtxIdx])[j];
							}
							// save joint ids
							vtx.jointIds.resize(jointIds[vtxIdx].length());
							for (int j=0; j<jointIds[vtxIdx].length(); j++)
							{
								vtx.jointIds[j] = (jointIds[vtxIdx])[j];
							}
							// save vertex texture coordinates
							vtx.u.resize(uvsets.length());
							vtx.v.resize(uvsets.length());
							for (int j=0; j<uvsets.length(); j++)
							{
								float2 uv;
								stat = faceIter.getUV(triVertexIdx[i],uv,&uvsets[j]);
								if (MS::kSuccess != stat)
								{
									uv[0] = 0;
									uv[1] = 0;
								}
								vtx.u[j] = uv[0];
								vtx.v[j] = (-1)*(uv[1]-1);
							}
							vtx.next = -1;
							vertices.push_back(vtx);
							// save vertex index in face info
							newFace.v[i] = vertices.size()-1;
							vertices[idx].next = vertices.size()-1;
						}
						else
						{
							newFace.v[i] = idx;
						}
					}
				} // end iteration of triangle vertices
				// add face info to the array corresponding to the submesh it belongs
				// skip faces with no shaders assigned
				if (shaderPolygonMapping[faceIter.index()] >= 0)
					polygonSets[shaderPolygonMapping[faceIter.index()]].push_back(newFace);
			} // end iteration of triangles
		}
	}
	std::cout << "done reading mesh triangles\n";

	// create a submesh for every different shader linked to the mesh
	unsigned shaderLength = shaders.length();
	for (int i=0; i<shaderLength; i++)
	{
		// check if the submesh has at least 1 triangle
		if (polygonSets[i].size() > 0)
		{
			//create new submesh
			SubMesh* pSubmesh = new SubMesh();
const char *nm = mesh.name().asChar();
const char *nm1 = mesh.partialPathName().asChar();
const char *nm2 = mesh.parentNamespace().asChar();
const char *nm3 = mesh.fullPathName().asChar();
const char *nm4 = meshDag.fullPathName().asChar();

			pSubmesh->m_name = meshDag.partialPathName();
			if(pDagPath)
				pSubmesh->m_name = pDagPath->partialPathName();
			const char *szName = pSubmesh->m_name.asChar();

			if(shaderLength > 1)
			{
				char a[256];
				sprintf(a,"%d",i);
				pSubmesh->m_name += a;
			}
			OutputDebugString(pSubmesh->m_name.asChar());
			OutputDebugString("\n");

			//OutputDebugString(szName);
			//OutputDebugString("\n");

			//load linked shader
			stat = pSubmesh->loadMaterial(shaders[i],uvsets);
			if (stat != MS::kSuccess)
			{
				MFnDependencyNode shadingGroup(shaders[i]);
				std::cout << "Error loading submesh linked to shader " << shadingGroup.name().asChar() << "\n";
				return MS::kFailure;
			}

			//load vertex and face data
			stat = pSubmesh->load(polygonSets[i],vertices,points,normals,opposite);

			//add submesh to current mesh
			m_submeshes.push_back(pSubmesh);
		}
	}

	return MS::kSuccess;
}
示例#14
0
MStatus
cgfxShaderCmd::doCmd(const MArgList& args)
//
//	Description:
//		implements the MEL cgfxShader command.
//
//	Arguments:
//		-fx/fxFile	The CgFX file to load.
//		-e/edit		Edit an existing cgfxShader rather than creating
//					a new one.
//      -q/query    Get specified info
//
//	Return Value:
//		MS::kSuccess - command succeeded
//		MS::kFailure - command failed (returning this value will cause the 
//                     MEL script that is being run to terminate unless the
//                     error is caught using a "catch" statement.
//
{
	// Get the current state of the flag
	// and store it in a temporary variable
	// static int tmpFlag = -1;

#if defined(_WIN32) && defined(CGFX_DEBUG_MEMORY)
	if (tmpFlag == -1)
	{
		tmpFlag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG );

		// Turn On (OR) - call _CrtCheckMemory at every
		// allocation request
		tmpFlag |= _CRTDBG_CHECK_ALWAYS_DF;

		// Turn on (OR) - check for memory leaks at end
		// of program.
		tmpFlag |= _CRTDBG_LEAK_CHECK_DF;

		_CrtSetDbgFlag( tmpFlag );
	}
#endif /* _WIN32 && CGFX_DEBUG_MEMORY */

	MStatus        status;
	MSelectionList selList;
	MObject        oNode;
	MString        sResult;
	MStringArray   saResult;
	MString        sFeedback;
	MString        sTemp;
	MString        sWho = "cgfxShader : ";

	status = parseArgs(args, selList);
	if (!status)
	{
		return status;
	}

	// -pp / -pluginPath 
	//     Returns the directory path where this plug-in's auxiliary
	//     files, such as MEL scripts, are expected to be found.
	//     The path name is in Maya format ('/' delimited) with no
	//     trailing slash.  Result type is string.  (Query only)
	if ( fPluginPath )
	{
		setResult( sPluginPath );
		return MS::kSuccess;
	}

	// -lp / -listProfiles
    //  
	//     Return the names of the profiles supported on the current
	//     platform.
	//
	//     Each item in the result array has the form
	//         "VertexProfileName<,GeometryProfileName,FragmentProfileName"
	//
	//     Result type is string[].  (Query only; set internally)
	if ( fListProfiles )
	{
        setResult( cgfxProfile::getProfileList() );
		return status;
	}

	// -mtc / -maxTexCoords
	//     Returns the maximum number of texcoord inputs that can be
	//     passed to vertex shaders under the currently installed
	//     OpenGL implementation.  Returns 0 if the information is
	//     not available.  Result type is integer.  (Query only)
	//
	// Don't use GL_MAX_TEXTURE_UNITS as this does not provide a proper
	// count when the # of image or texcoord inputs differs
	// from the conventional (older) notion of texture unit. 
	//
	// Instead take the minimum of GL_MAX_TEXTURE_COORDS_ARB and
	// GL_MAX_TEXUTRE_IMAGE_UNITS_ARB according to the 
	// ARB_FRAGMENT_PROGRAM specification.
	if ( fMaxTexCoords )    
	{
		GLint     mtc = 0;
		M3dView vw = M3dView::active3dView( &status );
		if ( status &&
			vw.beginGL() )
		{
			glGetIntegerv( GL_MAX_TEXTURE_COORDS_ARB, &mtc );
			GLint mic = 0;
			glGetIntegerv( GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &mic );
			if (mic < mtc)
				mtc = mic;

			if ( mtc < 1 )
				mtc = 1;
			else if ( mtc > CGFXSHADERNODE_GL_TEXTURE_MAX )
				mtc = CGFXSHADERNODE_GL_TEXTURE_MAX;
			
			vw.endGL();
		}
		setResult( (int)mtc );
		return MS::kSuccess;
	}

	// If edit or query, find the specified cgfxShaderNode.
	MFnDependencyNode fnNode;
	cgfxShaderNode*   pNode = NULL;
	if ( fIsEdit || fIsQuery )
	{
		// We are editing an existing node which must have been
		// provided in the args (or the current selection list).
		// Get the correct node name into fNodeName;
		//
		if (selList.length() != 1)
		{
			status = MS::kNotFound;
			return status;
		}

		// Get the name of the node into fNodeName so that it can
		// be saved for undo/redo
		//
		MStringArray tmpList;
		selList.getSelectionStrings(tmpList);
		fNodeName = tmpList[0];
		if ( fNodeName.length() ) 
		{
			sWho += " \"";
			sWho += fNodeName;
			sWho += "\"";
		}

		status = selList.getDependNode(0, oNode);
		if (!status)
		{
			return status;
		}

		status = fnNode.setObject( oNode );
		if (!status)
		{
			sFeedback = sWho;
			sFeedback += " is not a cgfxShader node.";
			MGlobal::displayError( sFeedback );

			return status;
		}

		if (fnNode.typeId() != cgfxShaderNode::sId)
		{
			status = MS::kInvalidParameter;
			sFeedback = sWho;
			sFeedback += " is not a cgfxShader node.";
			MGlobal::displayError( sFeedback );
			return status;
		}

		pNode = (cgfxShaderNode*)fnNode.userNode();
		if (!pNode)
		{
			status = MS::kInvalidParameter;
			sFeedback = sWho;
			sFeedback += " is not cgfxShader node.";
			MGlobal::displayError( sFeedback );
			return status;
		}
	}

	if ( fIsQuery ) {
        
        // -fx / -fxFile
        //     Returns the shader file name. 
        if ( fFxFile )
        {
            MString path = pNode->shaderFxFile();
            setResult( path );
            return MS::kSuccess;
        }

        // -fxp / -fxPath 
        //     Returns the path of the fx file.  The path name is in Maya
        //     format ('/' delimited).  Result type is string.
        //     (Query only)
        if ( fFxPath )
        {
            MString path = cgfxFindFile(pNode->shaderFxFile());
            setResult( path );
            return MS::kSuccess;
        }

        // -t / -technique
        //     Returns the currently active technique
        if ( fTechnique )
        {
            MString path = pNode->getTechnique();
            setResult( path );
            return MS::kSuccess;
        }

        // -p / -profile
        //     Returns the current profile
        if ( fProfile )
        {
            MString path = pNode->getProfile();
            setResult( path );
            return MS::kSuccess;
        }

        // -lt / -listTechniques
        //     Return the technique names defined by the current effect.
        //
        //     Each item in the result array has the form
        //         "techniqueName<TAB>numPasses"
        //     where 
        //         numPasses is the number of passes defined by the 
        //             technique, or 0 if the technique is not valid.   
        //     (Future versions of the cgfxShader plug-in may append
        //      additional tab-separated fields.)
        //
        //     Result type is string[].  (Query only; set internally)
        if ( fListTechniques )
        {
            setResult( pNode->getTechniqueList() );
            return status;
        }

        // -lp / -listParameters
        //     Return the attribute names corresponding to the
        //     shader's tweakable uniform parameters.
        //     Result type is string[].  (Query only; set internally)
        // -des / -description
        //     If specified, each item in the result array has the form
        //          "attrName<TAB>type<TAB>semantic<TAB>description<TAB>extraAttrSuffix"
        //     (Future versions of the cgfxShader plug-in may provide
        //       additional tab-separated fields after the semantic.)
        //     A missing field is indicated by a single space (" ") 
        //       so the string can be parsed more easily using the MEL
        //       "tokenize" function, which treats a group of consecutive
        //       delimiters the same as a single delimiter.
        if ( fListParameters )
        {
            cgfxRCPtr<cgfxAttrDefList> list = cgfxAttrDef::attrsFromNode( oNode );
            for ( cgfxAttrDefList::iterator it = list; it; ++it )
            {
                cgfxAttrDef* aDef = *it;
                if ( fDescription )
                {
                    sResult = aDef->fName.length() ? aDef->fName : " ";
                    sResult += "\t";
                    sTemp = aDef->typeName();
                    sResult += sTemp.length() ? sTemp : " ";
                    sResult += "\t";               
                    sResult += aDef->fSemantic.length() ? aDef->fSemantic : " ";
                    sResult += "\t";
                    sResult += aDef->fDescription.length() ? aDef->fDescription : " ";
                    sResult += "\t";               
                    const char* suffix = aDef->getExtraAttrSuffix();
                    sResult += suffix ? suffix : " ";
                }
                else
                    sResult = aDef->fName;
                saResult.append( sResult );
            }
            setResult( saResult );
            return status;
        }

        // -p  / -parameter <name>
        //     Return a string describing the data type and usage of 
        //     the attribute whose name is specified.  
        //     Result type is string (with no -description flag), or
        //     string array (if you specify -description).  
        //     (Query only; set internally)
        // -ci / -caseInsensitive
        //     If specified, returns information for the first 
        //     attribute that matches the specified name assuming
        //     no distinction between upper and lower case letters.
        // -des / -description
        //     If specified, the result is a string array containing:
        //          [0] = attribute name
        //          [1] = type
        //          [2] = semantic 
        //          [3] = description from "desc" or "uiname" annotation
        //          [4] = extra attribute suffix for Vector4 ("W") / Color4 ("Alpha")
        //          (Future versions of the cgfxShader plug-in may provide
        //          additional tab-separated fields after the semantic.)
        //     If omitted, only the type is returned (a string).
        if ( fParameterName.length() > 0 )
        {
            cgfxRCPtr<cgfxAttrDefList> list = cgfxAttrDef::attrsFromNode( oNode );
            cgfxAttrDefList::iterator it; 
            if ( fCaseInsensitive )
                it = list->findInsensitive( fParameterName );
            else
                it = list->find( fParameterName );
            if ( fDescription )
            {
                if ( it )
                {
                    cgfxAttrDef* aDef = *it;
                    saResult.append( aDef->fName );
                    saResult.append( aDef->typeName() );
                    saResult.append( aDef->fSemantic );
                    saResult.append( aDef->fDescription );
                    const char* suffix = aDef->getExtraAttrSuffix();
                    saResult.append( suffix ? suffix : "" );
                }
                setResult( saResult );
            }
            else
            {
                if ( it )
                    sResult = (*it)->typeName();
                setResult( sResult );
            }
            return status;
        }

        // -euv / -emptyUV
        //     Returns the names of blacklisted UV sets.  These UV sets
        //     are disabled from being passed to the shader because there
        //     is at least one mesh where the UV set name is defined but 
        //     has no faces mapped.  Due to a bug in Maya (in 5.0 and
        //     possibly some other releases), Maya crashes if an empty
        //     UV set is accessed by a hardware shader.  Blacklisting is
        //     intended to protect the user against accidentally hitting
        //     the bug and crashing Maya.  After the Maya fix has been
        //     verified, this option can continue to be accepted for awhile
        //     for compatibility, returning an empty result array.
        //     Result type is string[].  (Query only; set internally)
        if ( fEmptyUV )
        {
            setResult( pNode->getEmptyUVSets() );
            return MS::kSuccess;
        }

        // -eus / -emptyUVShapes
        //     Returns the names of shape nodes that have empty UV sets 
        //     which are causing the UV set names to be blacklisted.
        //     After the Maya bug fix has been verified, this option
        //     can remain for awhile for compatibility, returning an
        //     empty result array.
        //     Result type is string[].  (Query only; set internally)
        if ( fEmptyUVShapes )
        {
            const MObjectArray& oaShapes = pNode->getEmptyUVSetShapes();
            MFnDagNode          fnDagNode;
            MDagPath            dpShape;
            for ( unsigned iShape = 0; iShape < oaShapes.length(); ++iShape )
            {
                fnDagNode.setObject( oaShapes[ iShape ] );
                fnDagNode.getPath( dpShape );
                saResult.append( dpShape.partialPathName() );
            }
            setResult( saResult );
            return MS::kSuccess;
        }

        // -tcs / -texCoordSource
        //     Returns the value of the texCoordSource attribute, because
        //     the MEL "getAttr" command doesn't work with string arrays.
        //     Result type is string[].  (Query only; set via "setAttr")
        if ( fTexCoordSource )
        {
            setResult( pNode->getTexCoordSource() );
            return MS::kSuccess;
        }

#if MAYA_API_VERSION >= 700

        // -cs / -colorSource
        //     Returns the value of the colorSource attribute, because
        //     the MEL "getAttr" command doesn't work with string arrays.
        //     Result type is string[].  (Query only; set via "setAttr")
        if ( fColorSource )
        {
            setResult( pNode->getColorSource() );
            return MS::kSuccess;
        }

#endif

        // Error if -q with no other query flags.
		return MS::kInvalidParameter;
    }

	// If user didn't specify shader fx file, default to current
	// value of our cgfxShader node's "shader" attribute.
	if (!fFxFile && pNode)
		fNewFxFile = pNode->shaderFxFile();

	// If user didn't specify technique name, default to current
	// value of our cgfxShader node's "technique" attribute.
    //
    // If a new fx file has been specified without a technique, we
    // leave the technique name empty so that the first technique of
    // the effect will be selected.
	if (!fTechnique && pNode)
		fNewTechnique = pNode->getTechnique();

	// If user didn't specify profile name, default to current
	// value of our cgfxShader node's "profile" attribute.
	if (!fProfile && pNode)
		fNewProfile = pNode->getProfile();

	//
	// Load the effect from the .fx file.
	//
	if (fFxFile)
	{
		// Attempt to read the new fEffect from the file
		//
		MString file = cgfxFindFile(fNewFxFile);
        MString projectFile = cgfxFindFile(fNewFxFile, true);

		// Compile and create the effect.
		fNewEffect = cgfxEffect::loadEffect(file, cgfxProfile::getProfile(fNewProfile));

		//// Set the device.
		if (fNewEffect->isValid())
		{           
			// There is no current view in batch mode, just return
			// success then
			const MGlobal::MMayaState mayaState = MGlobal::mayaState(&status);
			if ( !status ) return status;
			if ( mayaState == MGlobal::kBatch ) return MS::kSuccess;

			fNewFxFile = projectFile;

			M3dView view = M3dView::active3dView();

			// The M3dView class doesn't return the correct status if
			// there isn't an active 3D view, so we rely on the
			// success of beginGL() which will make the context
			// current.
			//
			if (!view.beginGL()) 
			{
				MString es = "There is no active view to bind " + sWho + " to.";
				MGlobal::displayWarning( es );
				return MS::kSuccess;
			}

			view.endGL();
		}

		// Tell user if successful.
		if (fNewEffect->isValid())
		{
			sFeedback = sWho;
			sFeedback += " loaded effect \"";
			sFeedback += file;
			sFeedback += "\"";
			MGlobal::displayInfo( sFeedback );
		}
		else
		{
			sFeedback = sWho;
			sFeedback += " unable to load effect \"";
			sFeedback += file.length() ? file : fNewFxFile;
			sFeedback += "\"";
			MGlobal::displayError( sFeedback );
			return MS::kFailure;
		}
	}

	// Create an MDGModifier to hold an agenda of operations to be
	//   performed to update the DG.  We build the agenda here;
	//   then invoke it to do/redo/undo the updates.
	fDagMod = new MDGModifier;

	// Create new cgfxShader node if requested.  
	if ( !fIsEdit )
	{
		// Create node.
		oNode = fDagMod->createNode(cgfxShaderNode::sId, &status);
		M_CHECK( status );

		if ( fNodeName.length() > 0 )
		{
			status = fDagMod->renameNode(oNode, fNodeName);
			M_CHECK( status );
		}

		status = fnNode.setObject( oNode );
		M_CHECK( status && fnNode.typeId() == cgfxShaderNode::sId );

		pNode = (cgfxShaderNode*)fnNode.userNode();
		M_CHECK( pNode );

		// On successful completion, redoCmd() will select the new node.
		// Save old selection for undo.
		status = MGlobal::getActiveSelectionList( fOldSelection );
		M_CHECK( status );
	}

	if (fFxFile) {
        // Save the current state of the node for undo purposes
        fOldFxFile    = pNode->shaderFxFile();
        fOldEffect = pNode->effect();   // save old CGeffect

		cgfxShaderNode::NodeList nodes;
		// getNodesToUpdate will return the list of nodes that will need to be updated :
		// if the new fx file is the same as the old fx file, the action is considered a reload,
		//     we'll gather all the nodes that are using the old effect and reload them all.
		// else the effect file is different and only the current node will be updated.
		getNodesToUpdate(fOldEffect, pNode, nodes);

		cgfxShaderNode::NodeList::const_iterator it = nodes.begin();
		cgfxShaderNode::NodeList::const_iterator itEnd = nodes.end();
		for(; it != itEnd; ++it)
		{
			cgfxShaderNode* node = *it;

			MStringArray &oldAttributeList = fOldAttributeList[node];
			cgfxRCPtr<cgfxAttrDefList> &oldAttrDefList = fOldAttrDefList[node];

			MStringArray &newAttributeList = fNewAttributeList[node];
			cgfxRCPtr<cgfxAttrDefList> &newAttrDefList = fNewAttrDefList[node];


			node->getAttributeList( oldAttributeList );

			oldAttrDefList = node->attrDefList(); // save old cgfxAttrDefList ptr

			// Now figure out what to do with the node.
			//
			// updateNode does a fair amount of work.  First, it gets the
			// cgfxAttrDefList from the effect.  Then it gets the equivalent
			// list from the node itself.  It determines which attributes need
			// to be added and which need to be deleted and fills in all the
			// changes in the MDagModifier fDagMod.  Then it builds a new value
			// for the attributeList attribute.  Finally, it builds a new
			// value for the attrDefList internal value.  All these values are
			// returned here where we can set them into the node.
			//
			cgfxAttrDef::updateNode( fNewEffect,             // IN
									 node,                   // IN
									 fDagMod,                // UPD
									 newAttrDefList,         // OUT
									 newAttributeList );     // OUT
		}
    }

	// Save a reference to the node in a selection list for undo/redo.
	status = fNodeSelection.add( oNode );
	M_CHECK( status );

	// Save the current state of the node for undo purposes
	fOldTechnique = pNode->getTechnique();
	fOldProfile   = pNode->getProfile();

	// I think we have all the information to redoIt().
	//
	// Typically, the doIt() method only collects the infomation required
	// to do/undo the action and then stores it in class members.  The 
	// redo method is then called to do the actuall work.  This prevents
	// code duplication.
	//
	return redoCmd( oNode, fnNode, pNode );
}                                      // cgfxShaderCmd::doCmd
void DMPDSExporter::fillBones( DMPSkeletonData::SubSkeletonStruct* subSkel, string parent, DMPParameters* param, MDagPath& jointDag )
{
	MStatus status;
	if (jointDag.apiType() != MFn::kJoint)
	{
		return; // early out.
	}
	DMPSkeletonData::BoneStruct newBone;
	newBone.boneHandle = (unsigned int)subSkel->bones.size();
	newBone.name = jointDag.partialPathName().asUTF8();
	newBone.parentName = parent;

	MFnIkJoint fnJoint(jointDag, &status);
	//	matrix = [S] * [RO] * [R] * [JO] * [IS] * [T]
	/*
		These matrices are defined as follows:
		•[S] : scale
		•[RO] : rotateOrient (attribute name is rotateAxis)
		•[R] : rotate
		•[JO] : jointOrient
		•[IS] : parentScaleInverse
		•[T] : translate

		The methods to get the value of these matrices are:
		•[S] : getScale
		•[RO] : getScaleOrientation
		•[R] : getRotation
		•[JO] : getOrientation
		•[IS] : (the inverse of the getScale on the parent transformation matrix)
		•[T] : translation

	*/
	MVector trans = fnJoint.getTranslation(MSpace::kTransform);
	double scale[3];
	fnJoint.getScale(scale);
	MQuaternion R, RO, JO;
	fnJoint.getScaleOrientation(RO);
	fnJoint.getRotation(R);
	fnJoint.getOrientation(JO);
	MQuaternion rot = RO * R * JO; 
	
	newBone.translate[0] = trans.x * param->lum;
	newBone.translate[1] = trans.y * param->lum;
	newBone.translate[2] = trans.z * param->lum;

	newBone.orientation[0] = rot.w;
	newBone.orientation[1] = rot.x;
	newBone.orientation[2] = rot.y;
	newBone.orientation[3] = rot.z;

	newBone.scale[0] = scale[0];
	newBone.scale[1] = scale[1];
	newBone.scale[2] = scale[2];

	subSkel->bones.push_back(newBone);
	// Load child joints
	for (unsigned int i=0; i<jointDag.childCount();i++)
	{
		MObject child;
		child = jointDag.child(i);
		MDagPath childDag = jointDag;
		childDag.push(child);
		fillBones(subSkel, newBone.name, param, childDag);
	}
	// now go for animations
	if (param->bExportSkelAnimation)
	{
		for (unsigned int i = 0; i < subSkel->animations.size(); ++i)
		{
			DMPSkeletonData::TransformAnimation& anim = subSkel->animations[i];
			DMPSkeletonData::TransformTrack subTrack;
			subTrack.targetBone = newBone.name;

			MPlug		plugT;	// translate
 			MPlug		plugR;	// R
 			MPlug		plugRO;	// RO
 			MPlug		plugJO;	// JO
			MPlug		plugS;	// scale
			double		dataT[3];
			double		dataR[3];
			double		dataRO[3];
			double		dataJO[3];
			double		dataS[3];
			MFnDependencyNode	fnDependNode( jointDag.node(), &status );
			
			plugT = fnDependNode.findPlug("translate", false, &status);
 			plugR = fnDependNode.findPlug("rotate", false, &status);
 			plugRO = fnDependNode.findPlug("rotateAxis", false, &status);
 			plugJO = fnDependNode.findPlug("jointOrient", false, &status);
			plugS = fnDependNode.findPlug("scale", false, &status);

			float timeStep = param->samplerRate;
			if (param->animSampleType == DMPParameters::AST_Frame)
			{
				timeStep /= param->fps;
			}
			for (float curTime = anim.startTime; curTime <= anim.endTime; curTime += timeStep)
			{
				MTime		mayaTime;
				DMPSkeletonData::TransformKeyFrame keyframe;
				keyframe.time = curTime - anim.startTime;
				mayaTime.setUnit(MTime::kSeconds);
				mayaTime.setValue(curTime);

				// Get its value at the specified Time.
				plugT.child(0).getValue(dataT[0], MDGContext(mayaTime));
				plugT.child(1).getValue(dataT[1], MDGContext(mayaTime));
				plugT.child(2).getValue(dataT[2], MDGContext(mayaTime));

				plugR.child(0).getValue(dataR[0], MDGContext(mayaTime));
				plugR.child(1).getValue(dataR[1], MDGContext(mayaTime));
				plugR.child(2).getValue(dataR[2], MDGContext(mayaTime));

				plugRO.child(0).getValue(dataRO[0], MDGContext(mayaTime));
				plugRO.child(1).getValue(dataRO[1], MDGContext(mayaTime));
				plugRO.child(2).getValue(dataRO[2], MDGContext(mayaTime));

				plugJO.child(0).getValue(dataJO[0], MDGContext(mayaTime));
				plugJO.child(1).getValue(dataJO[1], MDGContext(mayaTime));
				plugJO.child(2).getValue(dataJO[2], MDGContext(mayaTime));

				plugS.child(0).getValue(dataS[0], MDGContext(mayaTime));
				plugS.child(1).getValue(dataS[1], MDGContext(mayaTime));
				plugS.child(2).getValue(dataS[2], MDGContext(mayaTime));

				// fill the frame.
				keyframe.translate[0] = dataT[0] * param->lum;
				keyframe.translate[1] = dataT[1] * param->lum;
				keyframe.translate[2] = dataT[2] * param->lum;
				// calculate quaternion.
				MEulerRotation	rotR(dataR[0], dataR[1], dataR[2]);
				MEulerRotation	rotRO(dataRO[0], dataRO[1], dataRO[2]);
				MEulerRotation	rotJO(dataJO[0], dataJO[1], dataJO[2]);

				MQuaternion finalRot = rotRO.asQuaternion()*rotR.asQuaternion()*rotJO.asQuaternion();
				
				keyframe.orientation[0] = finalRot.w;
				keyframe.orientation[1] = finalRot.x;
				keyframe.orientation[2] = finalRot.y;
				keyframe.orientation[3] = finalRot.z;

				keyframe.scale[0] = dataS[0];
				keyframe.scale[1] = dataS[1];
				keyframe.scale[2] = dataS[2];

				subTrack.frames.push_back(keyframe);
			}
			anim.tracks.push_back(subTrack);
		}
	}
}
示例#16
0
bool
atomExport::setUpAnimLayers(MSelectionList &sList,atomAnimLayers &animLayers, std::vector<atomNodeWithAnimLayers *> &nodesWithAnimLayers,
						std::set<std::string> &attrStrings, atomTemplateReader &templateReader)
					
{
	unsigned int numObjects = sList.length();
	nodesWithAnimLayers.resize(numObjects);

	bool somethingIsAnimLayered = false; 
	for (unsigned int i = 0; i < numObjects; i++) 
	{
		atomNodeWithAnimLayers *nodeWithLayer = NULL;
		//make sure it's a NULL, and preset it in case we skip this node
		nodesWithAnimLayers[i] = nodeWithLayer;

		MDagPath path;
		MObject node;
		if (sList.getDagPath (i, path) == MS::kSuccess) 
		{
			MString name = path.partialPathName();
			//if the name is in the template, only then write it out...
			if(templateReader.findNode(name)== false)
			{
				continue;
			}
			node = path.node();
		}
		else if (sList.getDependNode (i, node) == MS::kSuccess) {
			
			if (!node.hasFn (MFn::kDependencyNode)) {
				continue;
			}
			MFnDependencyNode fnNode (node);
			MString name = fnNode.name();
			if(templateReader.findNode(name)== false)
			{
				continue;
			}
		}
		if(node.isNull()==false)
		{
			MSelectionList localList;
			localList.add(node);
			MPlugArray animatablePlugs;
			MAnimUtil::findAnimatablePlugs(localList,animatablePlugs);
			unsigned int numPlugs = animatablePlugs.length();
			MPlugArray cachedPlugs;
			for (unsigned int k = 0; k < numPlugs; k++)
			{
				MPlug plug = animatablePlugs[k];
				MObjectArray layers;
				MPlugArray	 plugs;
				if(MAnimUtil::findAnimationLayers(plug,layers,plugs) && layers.length() > 0)
				{
					bool layerAdded = animLayers.addAnimLayers(layers);
					if(layerAdded)
					{
						if(nodeWithLayer == NULL)
							nodeWithLayer = new atomNodeWithAnimLayers();
						nodeWithLayer->addPlugWithLayer(plug,layers,plugs);
					}
					somethingIsAnimLayered = somethingIsAnimLayered == false ? layerAdded : true;
				}
			}
			nodesWithAnimLayers[i] = nodeWithLayer;

		}
	}
	return somethingIsAnimLayered;
}
示例#17
0
文件: usdWriteJob.cpp 项目: MWDD/USD
bool usdWriteJob::beginJob(const std::string &iFileName,
                         bool append,
                         double startTime,
                         double endTime)
{
    // Check for DAG nodes that are a child of an already specified DAG node to export
    // if that's the case, report the issue and skip the export
    PxrUsdMayaUtil::ShapeSet::const_iterator m, n;
    PxrUsdMayaUtil::ShapeSet::const_iterator endPath = mArgs.dagPaths.end();
    for (m = mArgs.dagPaths.begin(); m != endPath; ) {
        MDagPath path1 = *m; m++;
        for (n = m; n != endPath; n++) {
            MDagPath path2 = *n;
            if (PxrUsdMayaUtil::isAncestorDescendentRelationship(path1,path2)) {
                MString errorMsg = path1.fullPathName();
                errorMsg += " and ";
                errorMsg += path2.fullPathName();
                errorMsg += " have an ancestor relationship. Skipping USD Export.";
                MGlobal::displayError(errorMsg);
                return false;
            }
        }  // for n
    }  // for m

    // Make sure the file name is a valid one with a proper USD extension.
    const std::string iFileExtension = TfStringGetSuffix(iFileName, '.');
    if (iFileExtension == PxrUsdMayaTranslatorTokens->UsdFileExtensionDefault   || 
            iFileExtension == PxrUsdMayaTranslatorTokens->UsdFileExtensionASCII || 
            iFileExtension == PxrUsdMayaTranslatorTokens->UsdFileExtensionCrate) {
        mFileName = iFileName;
    } else {
        mFileName = TfStringPrintf("%s.%s",
                                   iFileName.c_str(),
                                   PxrUsdMayaTranslatorTokens->UsdFileExtensionDefault.GetText());
    }

    MGlobal::displayInfo("usdWriteJob::beginJob: Create stage file "+MString(mFileName.c_str()));

    ArResolverContext resolverCtx = ArGetResolver().GetCurrentContext();
    if (append) {
        mStage = UsdStage::Open(SdfLayer::FindOrOpen(mFileName), resolverCtx);
        if (!mStage) {
            MGlobal::displayError("Failed to open stage file "+MString(mFileName.c_str()));
            return false;
            }
    } else {
        mStage = UsdStage::CreateNew(mFileName, resolverCtx);
        if (!mStage) {
            MGlobal::displayError("Failed to create stage file "+MString(mFileName.c_str()));
            return false;
        }
    }

    // Set time range for the USD file
    mStage->SetStartTimeCode(startTime);
    mStage->SetEndTimeCode(endTime);
    
    mModelKindWriter.Reset();

    // Setup the requested render layer mode:
    //     defaultLayer    - Switch to the default render layer before exporting,
    //                       then switch back afterwards (no layer switching if
    //                       the current layer IS the default layer).
    //     currentLayer    - No layer switching before or after exporting. Just
    //                       use whatever is the current render layer for export.
    //     modelingVariant - Switch to the default render layer before exporting,
    //                       and export each render layer in the scene as a
    //                       modeling variant, then switch back afterwards (no
    //                       layer switching if the current layer IS the default
    //                       layer). The default layer will be made the default
    //                       modeling variant.
    MFnRenderLayer currentLayer(MFnRenderLayer::currentLayer());
    mCurrentRenderLayerName = currentLayer.name();

    if (mArgs.renderLayerMode == PxUsdExportJobArgsTokens->modelingVariant) {
        // Handle usdModelRootOverridePath for USD Variants
        MFnRenderLayer::listAllRenderLayers(mRenderLayerObjs);
        if (mRenderLayerObjs.length() > 1) {
            mArgs.usdModelRootOverridePath = SdfPath("/_BaseModel_");
        }
    }

    // Switch to the default render layer unless the renderLayerMode is
    // 'currentLayer', or the default layer is already the current layer.
    if (mArgs.renderLayerMode != PxUsdExportJobArgsTokens->currentLayer &&
            MFnRenderLayer::currentLayer() != MFnRenderLayer::defaultRenderLayer()) {
        // Set the RenderLayer to the default render layer
        MFnRenderLayer defaultLayer(MFnRenderLayer::defaultRenderLayer());
        MGlobal::executeCommand(MString("editRenderLayerGlobals -currentRenderLayer ")+
                                        defaultLayer.name(), false, false);
    }

    // Pre-process the argument dagPath path names into two sets. One set
    // contains just the arg dagPaths, and the other contains all parents of
    // arg dagPaths all the way up to the world root. Partial path names are
    // enough because Maya guarantees them to still be unique, and they require
    // less work to hash and compare than full path names.
    TfHashSet<std::string, TfHash> argDagPaths;
    TfHashSet<std::string, TfHash> argDagPathParents;
    PxrUsdMayaUtil::ShapeSet::const_iterator end = mArgs.dagPaths.end();
    for (PxrUsdMayaUtil::ShapeSet::const_iterator it = mArgs.dagPaths.begin();
            it != end; ++it) {
        MDagPath curDagPath = *it;
        std::string curDagPathStr(curDagPath.partialPathName().asChar());
        argDagPaths.insert(curDagPathStr);

        while (curDagPath.pop() && curDagPath.length() >= 0) {
            curDagPathStr = curDagPath.partialPathName().asChar();
            if (argDagPathParents.find(curDagPathStr) != argDagPathParents.end()) {
                // We've already traversed up from this path.
                break;
            }
            argDagPathParents.insert(curDagPathStr);
        }
    }

    // Now do a depth-first traversal of the Maya DAG from the world root.
    // We keep a reference to arg dagPaths as we encounter them.
    MDagPath curLeafDagPath;
    for (MItDag itDag(MItDag::kDepthFirst, MFn::kInvalid); !itDag.isDone(); itDag.next()) {
        MDagPath curDagPath;
        itDag.getPath(curDagPath);
        std::string curDagPathStr(curDagPath.partialPathName().asChar());

        if (argDagPathParents.find(curDagPathStr) != argDagPathParents.end()) {
            // This dagPath is a parent of one of the arg dagPaths. It should
            // be included in the export, but not necessarily all of its
            // children should be, so we continue to traverse down.
        } else if (argDagPaths.find(curDagPathStr) != argDagPaths.end()) {
            // This dagPath IS one of the arg dagPaths. It AND all of its
            // children should be included in the export.
            curLeafDagPath = curDagPath;
        } else if (!MFnDagNode(curDagPath).hasParent(curLeafDagPath.node())) {
            // This dagPath is not a child of one of the arg dagPaths, so prune
            // it and everything below it from the traversal.
            itDag.prune();
            continue;
        }

        MayaPrimWriterPtr primWriter = nullptr;
        if (!createPrimWriter(curDagPath, &primWriter) &&
                curDagPath.length() > 0) {
            // This dagPath and all of its children should be pruned.
            itDag.prune();
            continue;
        }

        if (primWriter) {
            mMayaPrimWriterList.push_back(primWriter);

            // Write out data (non-animated/default values).
            if (UsdPrim usdPrim = primWriter->write(UsdTimeCode::Default())) {
                MDagPath dag = primWriter->getDagPath();
                mDagPathToUsdPathMap[dag] = usdPrim.GetPath();

                // If we are merging transforms and the object derives from
                // MayaTransformWriter but isn't actually a transform node, we
                // need to add its parent.
                if (mArgs.mergeTransformAndShape) {
                    MayaTransformWriterPtr xformWriter =
                            boost::dynamic_pointer_cast<MayaTransformWriter>(
                                    primWriter);
                    if (xformWriter) {
                        MDagPath xformDag = xformWriter->getTransformDagPath();
                        mDagPathToUsdPathMap[xformDag] = usdPrim.GetPath();
                    }
                }

                mModelKindWriter.OnWritePrim(usdPrim, primWriter);

                if (primWriter->shouldPruneChildren()) {
                    itDag.prune();
                }
            }
        }
    }

    // Writing Materials/Shading
    PxrUsdMayaTranslatorMaterial::ExportShadingEngines(
                mStage, 
                mArgs.dagPaths,
                mArgs.shadingMode,
                mArgs.mergeTransformAndShape,
                mArgs.usdModelRootOverridePath);

    if (!mModelKindWriter.MakeModelHierarchy(mStage)) {
        return false;
    }

    // now we populate the chasers and run export default
    mChasers.clear();
    PxrUsdMayaChaserRegistry::FactoryContext ctx(mStage, mDagPathToUsdPathMap, mArgs);
    for (const std::string& chaserName : mArgs.chaserNames) {
        if (PxrUsdMayaChaserRefPtr fn = 
                PxrUsdMayaChaserRegistry::GetInstance().Create(chaserName, ctx)) {
            mChasers.push_back(fn);
        }
        else {
            std::string error = TfStringPrintf("Failed to create chaser: %s",
                                               chaserName.c_str());
            MGlobal::displayError(MString(error.c_str()));
        }
    }

    for (const PxrUsdMayaChaserRefPtr& chaser : mChasers) {
        if (!chaser->ExportDefault()) {
            return false;
        }
    }

    return true;
}
	String DocumentExporter::dagPathToColladaSid(const MDagPath & dagPath)
	{
		return mayaNameToColladaName(dagPath.partialPathName());
	}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
MSelectionList CVsSkinnerCmd::DoNewVolumes(
	const MDagPath &skinnerPath,
	const MSelectionList &skeletonList )
{
	MSelectionList retList;

	const bool optSelected( m_undo.ArgDatabase().isFlagSet( kOptSelected ) );

	MSelectionList optSelection;
	m_undo.ArgDatabase().getObjects( optSelection );

	// TODO: Maybe some fancier logic to only create volumes on joints that make sense?
	//		 Perhaps the ol' has children but no shapes gag?  Watch out for vstHelperBones!

	MDagPath mDagPath;
	for ( MItSelectionList sIt( optSelection ); !sIt.isDone(); sIt.next() )
	{
		if ( sIt.itemType() == MItSelectionList::kDagSelectionItem && sIt.getDagPath( mDagPath ) && mDagPath.hasFn( MFn::kTransform ) )
		{
			if ( optSelected )
			{
				MObject cObj( DoNewVolume( skinnerPath, mDagPath ) );
				if ( cObj.isNull() )
				{
					mwarn << "Couldn't create new volume on " << skinnerPath.partialPathName()
						<< " using " << mDagPath.partialPathName() << " as a parent" << std::endl;
				}
				else
				{
					retList.add( skinnerPath, cObj, true );
				}
			}
			else
			{
				MItDag dIt;
				for ( dIt.reset( mDagPath ); !dIt.isDone(); dIt.next() )
				{
					dIt.getPath( mDagPath );

					if ( mDagPath.childCount() )
					{
						uint nShapes( 0 );
						mDagPath.numberOfShapesDirectlyBelow( nShapes );

						if ( nShapes == 0U || mDagPath.hasFn( MFn::kJoint ) )
						{
							MObject cObj( DoNewVolume( skinnerPath, mDagPath ) );
							if ( cObj.isNull() )
							{
								mwarn << "Couldn't create new volume on " << skinnerPath.partialPathName()
									<< " using " << mDagPath.partialPathName() << " as a parent" << std::endl;
							}
							else
							{
								retList.add( skinnerPath, cObj, true );
							}
						}
					}
				}
			}
		}
	}

	return retList;
}
示例#20
0
bool
atomExport::setUpCache(MSelectionList &sList, std::vector<atomCachedPlugs *> &cachedPlugs,atomAnimLayers &animLayers,
						bool sdk, bool constraint, bool layers,
						std::set<std::string> &attrStrings, atomTemplateReader &templateReader,
						MTime &startTime, MTime &endTime, MAngle::Unit angularUnit,
						MDistance::Unit	linearUnit)
{
	if(endTime<startTime)
		return false; //should never happen but just in case.
	unsigned int numObjects = sList.length();
	cachedPlugs.resize(numObjects);

	double dStart = startTime.value();
	double dEnd = endTime.value() +  (.0000001); //little nudge in case of round off errors
	MTime::Unit unit = startTime.unit();
	double tickStep = MTime(1.0,unit).value();
	unsigned int numItems = ((unsigned int)((dEnd - dStart)/tickStep)) + 1;
	bool somethingIsCached = false; //if nothing get's cached no reason to run computation loop
	for (unsigned int i = 0; i < numObjects; i++) 
	{
		atomCachedPlugs *plug = NULL;
		//make sure it's a NULL, and preset it in case we skip this node
		cachedPlugs[i] = plug;

		MDagPath path;
		MObject node;
		MString name;
		if (sList.getDagPath (i, path) == MS::kSuccess) 
		{
			node = path.node();
			name = path.partialPathName();
		}
		else if (sList.getDependNode (i, node) == MS::kSuccess) {
			
			if (!node.hasFn (MFn::kDependencyNode)) {
				continue;
			}
			MFnDependencyNode fnNode (node);
			name = fnNode.name();
		}
		if(node.isNull()==false)
		{
			if(i< animLayers.length())
			{
				MPlugArray plugs;
				animLayers.getPlugs(i,plugs);
				std::set<std::string> tempAttrStrings;
				atomTemplateReader tempTemplateReader;
				plug = new atomCachedPlugs(name,node,plugs,sdk,constraint,layers,
					tempAttrStrings,tempTemplateReader,numItems,angularUnit,
				linearUnit);
				if(plug->hasCached() ==false)
					delete plug;
				else
				{
					cachedPlugs[i] = plug;
					somethingIsCached = true;
				}
			}
			else
			{
				if(templateReader.findNode(name)== false)
				{
					continue;
				}
				MSelectionList localList;
				localList.add(node);
				MPlugArray animatablePlugs;
				MAnimUtil::findAnimatablePlugs(localList,animatablePlugs);
				plug = new atomCachedPlugs(name,node,animatablePlugs,sdk,constraint,layers,attrStrings,templateReader,numItems,angularUnit,
					linearUnit);
				if(plug->hasCached() ==false)
					delete plug;
				else
				{
					cachedPlugs[i] = plug;
					somethingIsCached = true;
				}
			}
		}
	}
	
	bool computationFinished = true; //if no interrupt happens we will finish the computation
	if(somethingIsCached)
	{
		bool hasActiveProgress = false;
		if (MProgressWindow::reserve()) {
			hasActiveProgress = true;
			MProgressWindow::setInterruptable(true);
   			MProgressWindow::startProgress();
    		MProgressWindow::setProgressRange(0, numObjects);
			MProgressWindow::setProgress(0);
			MStatus stringStat;
			MString msg = MStringResource::getString(kBakingProgress, stringStat);
			if(stringStat == MS::kSuccess)
				MProgressWindow::setTitle(msg);
		}

		unsigned int count =0;
		for(double tick = dStart; tick <= dEnd; tick += tickStep)
		{
			if(hasActiveProgress)
				MProgressWindow::setProgress(count);
			MTime time(tick,unit);
			MDGContext ctx(time);
			for(unsigned int z = 0; z< cachedPlugs.size(); ++z)
			{
				if(cachedPlugs[z])
					cachedPlugs[z]->calculateValue(ctx,count);
			}

			if  (hasActiveProgress && MProgressWindow::isCancelled())
			{
				computationFinished = false;
				break;
			}
			++count;
		}
		if(hasActiveProgress)
			MProgressWindow::endProgress();
	}
	return computationFinished;

}
//-----------------------------------------------------------------------------
// Creates a vstAttachment Locator
//-----------------------------------------------------------------------------
MStatus CVstAttachmentCmd::DoCreate()
{
	MDagModifier *mDagModifier( new MDagModifier );

	if ( !mDagModifier )
	{
		merr << "Can't create new MDagModifier" << std::endl;
		return MS::kFailure;
	}

	MString optName( "vstAttachment" );
	if ( m_mArgDatabase->isFlagSet( kOptName ) )
	{
		m_mArgDatabase->getFlagArgument( kOptName, 0, optName );
	}

	// Create the helper bone locator's transform
	MObject xObj = mDagModifier->createNode( "transform" );
	mDagModifier->doIt();

	if ( xObj.isNull() )
	{
		merr << "Can't create new transform node" << std::endl;
		return MS::kFailure;
	}

	// name the shape & the transform the same thing
	mDagModifier->renameNode( xObj, optName );
	mDagModifier->doIt();

	MObject vstAttachmentObj = mDagModifier->createNode( "vstAttachment", xObj );

	if ( vstAttachmentObj.isNull() )
	{
		merr << "Can't create new vstAttachment node" << std::endl;
		mDagModifier->undoIt();
		return MS::kFailure;
	}

	// name the shape & the transform the same thing
	mDagModifier->renameNode( vstAttachmentObj, MFnDependencyNode( xObj ).name() );
	mDagModifier->doIt();

	m_undoable = true;
	m_mDagModifier = mDagModifier;

	if ( m_mArgDatabase->isFlagSet( kOptParent ) )
	{
		MSelectionList mSelectionList;
		m_mArgDatabase->getObjects( mSelectionList );
		for ( MItSelectionList sIt( mSelectionList, MFn::kDagNode ); !sIt.isDone(); sIt.next() )
		{
			MDagPath mDagPath;
			if ( sIt.getDagPath( mDagPath ) )
			{
				m_mDagModifier->reparentNode( xObj, mDagPath.node() );
				m_mDagModifier->doIt();
				break;
			}
		}
	}

	// Save the current selection just in case we want to undo stuff
	MGlobal::getActiveSelectionList( m_mSelectionList );

	MDagPath xDagPath;
	MDagPath::getAPathTo( xObj, xDagPath );
	MGlobal::select( xDagPath, MObject::kNullObj, MGlobal::kReplaceList );
	setResult( xDagPath.partialPathName() );

	return MS::kSuccess;
}
示例#22
0
MStatus atomExport::exportSelected(	ofstream &animFile, 
									MString &copyFlags,
									std::set<std::string> &attrStrings,
									bool includeChildren, 
									bool useSpecifiedTimes, 
									MTime &startTime,
									MTime &endTime,
									bool statics,
									bool cached,
									bool sdk,
									bool constraint,
									bool layers,
									const MString& exportEditsFile,
									atomTemplateReader &templateReader)
{
	MStatus status = MS::kFailure;

	//	If the selection list is empty, then there are no anim curves
	//	to export.
	//
	MSelectionList sList;
	std::vector<unsigned int> depths;


	SelectionGetter::getSelectedObjects(includeChildren,sList,depths);
	if (sList.isEmpty()) {
		MString msg = MStringResource::getString(kNothingSelected, status);
		MGlobal::displayError(msg);
		return (MS::kFailure);
	}
	//	Copy any anim curves to the API clipboard.
	//
	MString command(copyFlags);
	


	// Always write out header
	if (!fWriter.writeHeader(animFile,useSpecifiedTimes,
							 startTime,endTime)) {
		return (MS::kFailure);
	}


	atomAnimLayers animLayers;
	std::vector<atomNodeWithAnimLayers *> nodesWithAnimLayers;
	if(layers)
	{
		bool hasAnimLayers =  animLayers.getOrderedAnimLayers(); //any layers in the scene?
		hasAnimLayers = setUpAnimLayers(sList,animLayers, nodesWithAnimLayers,attrStrings,templateReader);
		//any layers on our selection?
		if(hasAnimLayers)
		{
			//add the layers to the sList...
			unsigned int oldLength = sList.length();
			animLayers.addLayersToStartOfSelectionList(sList);
			unsigned int diffLength = sList.length() - oldLength;
			atomNodeWithAnimLayers * nullPad = NULL;
			for(unsigned int k =0 ;k < diffLength;++k) //need to pad the beginning of the nodesWithAnimlayers with any layer that was added
			{
				nodesWithAnimLayers.insert(nodesWithAnimLayers.begin(),nullPad);
				depths.insert(depths.begin(),0);
			}
		}
	}
	
	//if caching is on, we pre iterate through the objects, find 
	//each plug that's cached and then cache the data all at once
	std::vector<atomCachedPlugs *> cachedPlugs;
	if(cached)
	{
		bool passed = setUpCache(sList,cachedPlugs,animLayers,sdk, constraint, layers, attrStrings,templateReader,startTime, endTime,
			fWriter.getAngularUnit(), fWriter.getLinearUnit()); //this sets it up and runs the cache;
		if(passed == false) //failed for some reason, one reason is that the user canceled the computation
		{
			//first delete everything though
			//delete any cachedPlugs objects that we created.
			for(unsigned int z = 0; z< cachedPlugs.size(); ++z)
			{
				if(cachedPlugs[z])
					delete cachedPlugs[z];
			}
			//and delete any any layers too
			for(unsigned int zz = 0; zz< nodesWithAnimLayers.size(); ++zz)
			{
				if(nodesWithAnimLayers[zz])
					delete nodesWithAnimLayers[zz];
			}
			MString msg = MStringResource::getString(kCachingCanceled, status);
			MGlobal::displayError(msg);
			return (MS::kFailure);
		}
	}

	unsigned int numObjects = sList.length();

	bool computationFinished = true;
	//not sure if in a headless mode we may want to not show the progress, should
	//still run if that's the case
	bool hasActiveProgress = false;
	if (MProgressWindow::reserve()) {
		hasActiveProgress = true;
		MProgressWindow::setInterruptable(true);
   		MProgressWindow::startProgress();
    	MProgressWindow::setProgressRange(0, numObjects);
		MProgressWindow::setProgress(0);
		MStatus stringStat;
		MString msg = MStringResource::getString(kExportProgress, stringStat);
		if(stringStat == MS::kSuccess)
			MProgressWindow::setTitle(msg);
	}

	if (exportEditsFile.length() > 0) {
		fWriter.writeExportEditsFilePresent(animFile);
	}

	if(layers)
	{
		animLayers.writeAnimLayers(animFile,fWriter);
	}

	bool haveAnyAnimatableStuff = false; //will remain false if no curves or statics
	for (unsigned int i = 0; i < numObjects; i++) 
	{
		if(hasActiveProgress)
			MProgressWindow::setProgress(i);
		MString localCommand;
		bool haveAnimatedCurves = false; //local flag, if true this node has animated curves
		bool haveAnimatableChannels = false; //local flag, if true node has some animatable statics

		MDagPath path;
		MObject node;
		if (sList.getDagPath (i, path) == MS::kSuccess) 
		{
			MString name = path.partialPathName();
			//if the name is in the template, only then write it out...
			if(templateReader.findNode(name)== false)
				continue;

			//we use this to both write out the cached plugs for this node but for also to not write out
			//the plugs which are cached when writing anim curves.
			atomCachedPlugs * cachedPlug = NULL;
			if(cached && i < cachedPlugs.size())
				cachedPlug = cachedPlugs[i];

			atomNodeWithAnimLayers  *layerPlug = NULL;
			if(layers && i < nodesWithAnimLayers.size())
				layerPlug = nodesWithAnimLayers[i];

			unsigned int depth = depths[i];
			unsigned int childCount = path.childCount();
			MObject object = path.node();
			atomNodeNameReplacer::NodeType nodeType = (object.hasFn(MFn::kShape)) ? atomNodeNameReplacer::eShape : atomNodeNameReplacer::eDag;
			fWriter.writeNodeStart(animFile,nodeType,name,depth,childCount);
			
			
			MPlugArray animatablePlugs;
			MSelectionList localList;
			localList.add(object);
			MAnimUtil::findAnimatablePlugs(localList,animatablePlugs);
			
			if(writeAnimCurves(animFile,name,cachedPlug, layerPlug, command, haveAnimatedCurves,templateReader) != MS::kSuccess )
			{
				return (MS::kFailure);
			}
			else if(haveAnimatedCurves)
			{
				haveAnyAnimatableStuff = true;
			}
			if(statics||cached)
			{
				writeStaticAndCached (animatablePlugs,cachedPlug,statics,cached,animFile,attrStrings,name,depth,childCount, haveAnimatableChannels,templateReader);
			}
			fWriter.writeNodeEnd(animFile);

		}
		else if (sList.getDependNode (i, node) == MS::kSuccess) {
			
			if (!node.hasFn (MFn::kDependencyNode)) {
				return (MS::kFailure);
			}
			MPlugArray animatablePlugs;
			MFnDependencyNode fnNode (node, &status);
			MString name = fnNode.name();
			atomNodeNameReplacer::NodeType nodeType = atomNodeNameReplacer::eDepend;
			atomNodeWithAnimLayers  *layerPlug = NULL;
			//if a layer we get our own attrs
			if(i< animLayers.length())
			{
				MPlugArray plugs;
				animLayers.getPlugs(i,animatablePlugs);
				nodeType = atomNodeNameReplacer::eAnimLayer;
			}
			else
			{
				if(templateReader.findNode(name)== false)
				{
					continue;
				}
				MSelectionList localList;
				localList.add(node);
				MAnimUtil::findAnimatablePlugs(localList,animatablePlugs);
				if(layers && i < nodesWithAnimLayers.size())
					layerPlug = nodesWithAnimLayers[i];
			}
			//we use this to both write out the cached plugs for this node but for also to not write out
			//the plugs which are cached when writing anim curves.
			atomCachedPlugs * cachedPlug = NULL;
			if(cached && i < cachedPlugs.size())
				cachedPlug = cachedPlugs[i];

			fWriter.writeNodeStart(animFile,nodeType,name);

			if(writeAnimCurves(animFile,name, cachedPlug,layerPlug,command, haveAnimatedCurves,templateReader) != MS::kSuccess )
			{
				return (MS::kFailure);
			}
			else if(haveAnimatedCurves)
			{
				haveAnyAnimatableStuff = true;
			}


			if(statics||cached)
			{
				writeStaticAndCached (animatablePlugs,cachedPlug,statics,cached,animFile,attrStrings,name,0,0,haveAnimatableChannels,templateReader);
			}
			fWriter.writeNodeEnd(animFile);
		}
		if(haveAnimatableChannels==true)
			haveAnyAnimatableStuff = true;

		if  (hasActiveProgress && MProgressWindow::isCancelled())
		{
			computationFinished = false;
			break;
		}
		
	}
	
	if (exportEditsFile.length() > 0) {
		fWriter.writeExportEditsFile(animFile,exportEditsFile);
	}
	
	//delete any cachedPlugs objects that we created.
	for(unsigned int z = 0; z< cachedPlugs.size(); ++z)
	{
		if(cachedPlugs[z])
			delete cachedPlugs[z];
	}
	//and delete any any layers too
	for(unsigned int zz = 0; zz< nodesWithAnimLayers.size(); ++zz)
	{
		if(nodesWithAnimLayers[zz])
			delete nodesWithAnimLayers[zz];
	}
	if(computationFinished == false) //failed for some reason, one reason is that the user canceled the computation
	{
		MString msg = MStringResource::getString(kSavingCanceled, status);
		MGlobal::displayError(msg);
		return (MS::kFailure);
	}

	if(hasActiveProgress)
		MProgressWindow::endProgress();

	if(haveAnyAnimatableStuff == false)
	{
		MString msg = MStringResource::getString(kAnimCurveNotFound, status);
		MGlobal::displayError(msg);
		return (MS::kFailure);
	}
	else return (MS::kSuccess);
}	
示例#23
0
MStatus vxCache::doIt( const MArgList& args ) 
{

	MStatus status = parseArgs( args );
	
	if( status != MS::kSuccess ) return status;
	
	MArgDatabase argData(syntax(), args);
	
	MAnimControl timeControl;
	MTime time = timeControl.currentTime();
	int frame =int(time.value());

	MString proj;
	MGlobal::executeCommand( MString ("string $p = `workspace -q -fn`"), proj );
	
	MSelectionList selList;
	MGlobal::getActiveSelectionList ( selList );
	MItSelectionList iter( selList );

	MString cache_path = proj + "/data/";
	MString cache_name;
	MString scene_name = "untitled";
	worldSpace = false;
	
	if (argData.isFlagSet("-p")) argData.getFlagArgument("-p", 0, cache_path);
	if (argData.isFlagSet("-n")) argData.getFlagArgument("-n", 0, cache_name);
	if (argData.isFlagSet("-w")) argData.getFlagArgument("-w", 0, worldSpace);

	for ( ; !iter.isDone(); iter.next() )
	{								
		MDagPath meshPath;		
		iter.getDagPath( meshPath );
		
		meshPath.extendToShape();
		
		MObject meshObj = meshPath.node();
	
		MString surface = meshPath.partialPathName();
	
		zWorks::validateFilePath(surface);

		char filename[512];

		cache_name = surface;
		
		if(argData.isFlagSet("-sg")) sprintf( filename, "%s/%s.mcf", cache_path.asChar(), cache_name.asChar() );
		else sprintf( filename, "%s/%s.%d.mcf", cache_path.asChar(), cache_name.asChar(), frame );

		MDagPath surfDag;

		if ( meshPath.hasFn(MFn::kMesh)) 
		{
			writeMesh(filename, meshPath, meshObj);
			MGlobal::displayInfo ( MString("vxCache writes ") + filename);
		}
		else
			MGlobal::displayError ( surface + "- Cannot find mesh to write!" );
	}

	if ( selList.length() == 0 )
	{
		MGlobal:: displayError ( "Nothing is selected!" );
		return MS::kSuccess;
	}
	

	
 return MS::kSuccess;
 }