void liqRibSubdivisionData::addExtraTags( MObject &dstNode, float extraTagValue, SBD_EXTRA_TAG extraTag )
{
	CM_TRACE_FUNC("liqRibSubdivisionData::addExtraTags("<<MFnDependencyNode(dstNode).name()<<","<<extraTagValue<<","<<extraTag<<")");

	if( TAG_BOUNDARY == extraTag )
	{
		v_tags.push_back( "interpolateboundary" );
		v_nargs.push_back( 1 );		// 0 intargs
		v_nargs.push_back( 0 );		// 0 floatargs
		v_intargs.push_back( (int)extraTagValue );
		return;
	}

	if( TAG_FACEVARYINGBOUNDARY == extraTag )
	{
		v_tags.push_back( "facevaryinginterpolateboundary" );
		v_nargs.push_back( 1 );		// 1 intargs
		v_nargs.push_back( 0 );		// 0 floatargs
		v_intargs.push_back( (int)extraTagValue );
	}

	MStatus status = MS::kSuccess;
	MFnSet elemSet( dstNode, &status ); // dstNode is maya components set
	if( status == MS::kSuccess )
	{
		MSelectionList members;
		status = elemSet.getMembers( members, true ); // get flatten members list
		if( status == MS::kSuccess )
		{
			for ( unsigned i( 0 ) ; i < members.length() ; i++ )
			{
				MObject component;
				MDagPath dagPath;
				members.getDagPath ( i, dagPath, component );

				// since the crease set could contain more that one mesh
				// we only want the current one - Alf
				if( dagPath.fullPathName() != longName )
					continue;

				switch ( extraTag )
				{
					case TAG_CREASE:
					if( !component.isNull() && component.hasFn( MFn::kMeshEdgeComponent ) )
					{
						MItMeshEdge edgeIter( dagPath, component );
						for(  ; !edgeIter.isDone(); edgeIter.next() )
						{
							v_tags.push_back( "crease" );
							v_nargs.push_back( 2 );                 // 2 intargs
							v_nargs.push_back( 1 );                 // 1 floatargs
							v_intargs.push_back( edgeIter.index( 0 ) );
							v_intargs.push_back( edgeIter.index( 1 ) );
							v_floatargs.push_back( extraTagValue ); // 1 floatargs
						}
					}
					break;

					case TAG_CORNER:
					if( !component.isNull() && component.hasFn( MFn::kMeshVertComponent ) )
					{
						MItMeshVertex  vertexIter( dagPath, component );
						for(  ; !vertexIter.isDone(); vertexIter.next() )
						{
							v_tags.push_back( "corner" );
							v_nargs.push_back( 1 );                 // 1 intargs
							v_nargs.push_back( 1 );                 // 1 floatargs
							v_intargs.push_back( vertexIter.index() );
							v_floatargs.push_back( extraTagValue ); // 1 floatargs
						}
					}
					break;

					case TAG_HOLE:
					if( !component.isNull() && component.hasFn( MFn::kMeshPolygonComponent ) )
					{
						MItMeshPolygon  faceIter( dagPath, component );
						for(  ; !faceIter.isDone(); faceIter.next() )
						{
							v_tags.push_back( "hole" );
							v_nargs.push_back( 1 );                // 1 intargs
							v_nargs.push_back( 0 );                // 0 floatargs
							v_intargs.push_back( faceIter.index() );
						}
					}
					break;

					case TAG_STITCH:
					if( !component.isNull() && component.hasFn( MFn::kMeshVertComponent ) )
					{
						MItMeshVertex vertexIter( dagPath, component );
						v_tags.push_back( "stitch" );
						v_nargs.push_back( vertexIter.count() + 1 ); // vertex count in chain + 1 integer identifier
						v_nargs.push_back( 0 );                      // 0 floatargs
						v_intargs.push_back( ( int ) extraTagValue );
						for(  ; !vertexIter.isDone(); vertexIter.next() )
						{
							v_intargs.push_back( vertexIter.index() );
						}
					}
					break;

					case TAG_BOUNDARY:
					default:
					break;
				}

			}
		}
	}
}
Пример #2
0
MStatus AbcImport::doIt(const MArgList & args)
{
    MStatus status;

    MArgParser argData(syntax(), args, &status);

    MString filename("");
    MString connectRootNodes("");
    MString filterString("");
    MString excludeFilterString("");

    MObject reparentObj = MObject::kNullObj;

    bool    swap = false;
    bool    createIfNotFound = false;
    bool    removeIfNoUpdate = false;

    bool    debugOn = false;

    if (argData.isFlagSet("help"))
    {
        MGlobal::displayInfo(usage);
        return status;
    }

    if (argData.isFlagSet("debug"))
        debugOn = true;

    if (argData.isFlagSet("reparent"))
    {
        MString parent("");
        MDagPath reparentDagPath;
        status = argData.getFlagArgument("reparent", 0, parent);
        if (status == MS::kSuccess
            && getDagPathByName(parent, reparentDagPath) == MS::kSuccess)
        {
            reparentObj = reparentDagPath.node();
        }
        else
        {
            MString theWarning = parent;
            theWarning += MString(" is not a valid DagPath");
            printWarning(theWarning);
        }
    }

    if (!argData.isFlagSet("connect") && argData.isFlagSet("mode"))
    {
        MString modeStr;
        argData.getFlagArgument("mode", 0, modeStr);
        if (modeStr == "replace")
            deleteCurrentSelection();
        else if (modeStr == "open")
        {
            MFileIO fileIo;
            fileIo.newFile(true);
        }
    }
    else if (argData.isFlagSet("connect"))
    {
        swap = true;
        argData.getFlagArgument("connect", 0, connectRootNodes);

        if (argData.isFlagSet("createIfNotFound"))
        {
            createIfNotFound = true;
        }

        if (argData.isFlagSet("removeIfNoUpdate"))
            removeIfNoUpdate = true;
    }

    if (argData.isFlagSet("filterObjects"))
    {
        argData.getFlagArgument("filterObjects", 0, filterString);
    }

    if (argData.isFlagSet("excludeFilterObjects"))
    {
        argData.getFlagArgument("excludeFilterObjects", 0, excludeFilterString);
    }

    // if the flag isn't specified we'll only do stuff marked with the Maya
    // meta data
    bool recreateColorSets = false;
    if (argData.isFlagSet("recreateAllColorSets"))
    {
        recreateColorSets = true;
    }

    status = argData.getCommandArgument(0, filename);
    MString abcNodeName;
    if (status == MS::kSuccess)
    {
        {
            MString fileRule, expandName;
            MString alembicFileRule = "alembicCache";
            MString alembicFilePath = "cache/alembic";

            MString queryFileRuleCmd;
            queryFileRuleCmd.format("workspace -q -fre \"^1s\"",
                alembicFileRule);
            MString queryFolderCmd;
            queryFolderCmd.format("workspace -en `workspace -q -fre \"^1s\"`",
                alembicFileRule);

            // query the file rule for alembic cache
            MGlobal::executeCommand(queryFileRuleCmd, fileRule);
            if (fileRule.length() > 0)
            {
                // we have alembic file rule, query the folder
                MGlobal::executeCommand(queryFolderCmd, expandName);
            }

            // resolve the expanded file rule
            if (expandName.length() == 0)
            {
                expandName = alembicFilePath;
            }

            // get the path to the alembic file rule
            MFileObject directory;
            directory.setRawFullName(expandName);
            MString directoryName = directory.resolvedFullName();

            // resolve the relative path
            MFileObject absoluteFile;
            absoluteFile.setRawFullName(filename);
#if MAYA_API_VERSION < 201300
            if (absoluteFile.resolvedFullName() != 
                absoluteFile.expandedFullName())
            {
#else
            if (!MFileObject::isAbsolutePath(filename)) {
#endif
                // this is a relative path
                MString absoluteFileName = directoryName + "/" + filename;
                absoluteFile.setRawFullName(absoluteFileName);
                filename = absoluteFile.resolvedFullName();
            }
            else
            {
                filename = absoluteFile.resolvedFullName();
            }
        }

        MFileObject fileObj;
        status = fileObj.setRawFullName(filename);
        if (status == MS::kSuccess && fileObj.exists())
        {
            ArgData inputData(filename, debugOn, reparentObj,
                swap, connectRootNodes, createIfNotFound, removeIfNoUpdate,
                recreateColorSets, filterString, excludeFilterString);
            abcNodeName = createScene(inputData);

            if (inputData.mSequenceStartTime != inputData.mSequenceEndTime &&
                inputData.mSequenceStartTime != -DBL_MAX &&
                inputData.mSequenceEndTime != DBL_MAX)
            {
                if (argData.isFlagSet("fitTimeRange"))
                {
                    MTime sec(1.0, MTime::kSeconds);
                    setPlayback(
                        inputData.mSequenceStartTime * sec.as(MTime::uiUnit()),
                        inputData.mSequenceEndTime * sec.as(MTime::uiUnit()) );
                }

                if (argData.isFlagSet("setToStartFrame"))
                {
                    MTime sec(1.0, MTime::kSeconds);
                    MGlobal::viewFrame( inputData.mSequenceStartTime *
                        sec.as(MTime::uiUnit()) );
                }
            }
        }
        else
        {
            MString theError("In AbcImport::doIt(), ");
            theError += filename;
            theError += MString(" doesn't exist");
            printError(theError);
        }
    }

    MPxCommand::setResult(abcNodeName);

    return status;
}
Пример #3
0
void maTranslator::writeDagNodes(fstream& f)
{
	fParentingRequired.clear();

	MItDag		dagIter;

	dagIter.traverseUnderWorld(true);

	MDagPath	worldPath;

	dagIter.getPath(worldPath);

	//
	// We step over the world node before starting the loop, because it
	// doesn't get written out.
	//
	for (dagIter.next(); !dagIter.isDone(); dagIter.next())
	{
		MDagPath	path;
		dagIter.getPath(path);

		//
		// If the node has already been written, then all of its descendants
		// must have been written, or at least checked, as well, so prune
		// this branch of the tree from the iteration.
		//
		MFnDagNode	dagNodeFn(path);

		if (dagNodeFn.isFlagSet(fCreateFlag))
		{
			dagIter.prune();
			continue;
		}

		//
		// If this is a default node, it will be written out later, so skip
		// it.
		//
		if (dagNodeFn.isDefaultNode()) continue;

		//
		// If this node is not writable, and is not a shared node, then mark
		// it as having been written, and skip it.
		//
		if (!dagNodeFn.canBeWritten() && !dagNodeFn.isShared())
		{
			dagNodeFn.setFlag(fCreateFlag, true);
			continue;
		}

		unsigned int	numParents = dagNodeFn.parentCount();

		if (dagNodeFn.isFromReferencedFile())
		{
			//
			// We don't issue 'creatNode' commands for nodes from referenced
			// files, but if the node has any parents which are not from
			// referenced files, other than the world, then make a note that
			// we'll need to issue extra 'parent' commands for it later on.
			//
			unsigned int i;

			for (i = 0; i < numParents; i++)
			{
				MObject		altParent = dagNodeFn.parent(i);
				MFnDagNode	altParentFn(altParent);

				if (!altParentFn.isFromReferencedFile()
				&&	(altParentFn.object() != worldPath.node()))
				{
					fParentingRequired.append(path);
					break;
				}
			}
		}
		else
		{
			//
			// Find the node's parent.
			//
			MDagPath	parentPath = worldPath;

			if (path.length() > 1)
			{
				//
				// Get the parent's path.
				//
				parentPath = path;
				parentPath.pop();

				//
				// If the parent is in the underworld, then find the closest
				// ancestor which is not.
				//
				if (parentPath.pathCount() > 1)
				{
					//
					// The first segment of the path contains whatever
					// portion of the path exists in the world.  So the closest
					// worldly ancestor is simply the one at the end of that
					// first path segment.
					//
					path.getPath(parentPath, 0);
				}
			}

			MFnDagNode	parentNodeFn(parentPath);

			if (parentNodeFn.isFromReferencedFile())
			{
				//
				// We prefer to parent to a non-referenced node.  So if this
				// node has any other parents, which are not from referenced
				// files and have not already been processed, then we'll
				// skip this instance and wait for an instance through one
				// of those parents.
				//
				unsigned i;

				for (i = 0; i < numParents; i++)
				{
					if (dagNodeFn.parent(i) != parentNodeFn.object())
					{
						MObject		altParent = dagNodeFn.parent(i);
						MFnDagNode	altParentFn(altParent);

						if (!altParentFn.isFromReferencedFile()
						&&	!altParentFn.isFlagSet(fCreateFlag))
						{
							break;
						}
					}
				}

				if (i < numParents) continue;

				//
				// This node only has parents within referenced files, so
				// create it without a parent and note that we need to issue
				// 'parent' commands for it later on.
				//
				writeCreateNode(f, path, worldPath);

				fParentingRequired.append(path);
			}
			else
			{
				writeCreateNode(f, path, parentPath);

				//
				// Let's see if this node has any parents from referenced
				// files, or any parents other than this one which are not
				// from referenced files.
				//
				unsigned	int i;
				bool		hasRefParents = false;
				bool		hasOtherNonRefParents = false;

				for (i = 0; i < numParents; i++)
				{
					if (dagNodeFn.parent(i) != parentNodeFn.object())
					{
						MObject		altParent = dagNodeFn.parent(i);
						MFnDagNode	altParentFn(altParent);

						if (altParentFn.isFromReferencedFile())
							hasRefParents = true;
						else
							hasOtherNonRefParents = true;

						//
						// If we've already got positives for both tests,
						// then there's no need in continuing.
						//
						if (hasRefParents && hasOtherNonRefParents) break;
					}
				}

				//
				// If this node has parents from referenced files, then
				// make note that we will have to issue 'parent' commands
				// later on.
				//
				if (hasRefParents) fParentingRequired.append(path);

				//
				// If this node has parents other than this one which are
				// not from referenced files, then make note that the
				// parenting for the other instances still has to be done.
				//
				if (hasOtherNonRefParents)
				{
					fInstanceChildren.append(path);
					fInstanceParents.append(parentPath);
				}
			}

			//
			// Write out the node's 'addAttr', 'setAttr' and 'lockNode'
			// commands.
			//
			writeNodeAttrs(f, path.node(), true);
			writeLockNode(f, path.node());
		}

		//
		// Mark the node as having been written.
		//
		dagNodeFn.setFlag(fCreateFlag, true);
	}

	//
	// Write out the parenting for instances.
	//
	writeInstances(f);
}
	String DocumentExporter::dagPathToColladaSid(const MDagPath & dagPath)
	{
		return mayaNameToColladaName(dagPath.partialPathName());
	}
Пример #5
0
std::string HesperisIO::H5PathNameTo(const MDagPath & path)
{
	std::string r(path.fullPathName().asChar());
	H5PathName(r);
    return r;
}
Пример #6
0
MFnMesh* GDExporter::GetSelectedMesh(void)
{
	MSelectionList currSelection;
	MGlobal::getActiveSelectionList(currSelection);

	unsigned int selectionCount = currSelection.length();
	
	MFnMesh* exportingMesh = 0;

	for(unsigned int selectionIndex = 0; selectionIndex < selectionCount; ++selectionIndex )
	{
		MDagPath currPath;
		currSelection.getDagPath(selectionIndex, currPath);

		if( currPath.apiType() != MFn::kTransform )
			continue;

		MFnTransform currTransform(currPath);
		unsigned int childCount = currTransform.childCount();
		for(unsigned int childIndex = 0; childIndex < childCount; ++childIndex)
		{
			MObject childObject = currTransform.child(childIndex);
			if( childObject.apiType() == MFn::kMesh )
			{
				MFnDagNode dagNode;
				dagNode.setObject(childObject);
				MDagPath childPath;
				dagNode.getPath(childPath);
				
				MFnMesh* pChildMesh = new MFnMesh(childPath);
				
				if( pChildMesh->isIntermediateObject() )
					continue;
				
				bool bExportMesh = true;
				if( pChildMesh->isInstanced(false) )
					if( childPath.instanceNumber() != 0 )
						bExportMesh = false;

				if( bExportMesh )
				{
					if( exportingMesh != 0 )
					{
						delete exportingMesh;
						delete pChildMesh;
						MGlobal::displayError(MString("GDExporter - More than one mesh object selected."));
						return 0;
					}

					exportingMesh = pChildMesh;
				}
			}
		}
	}

	if( exportingMesh == 0 )
	{
		MGlobal::displayError(MString("GDExporter - No mesh objects currently selected."));
		return 0;
	}

	return exportingMesh;
}
Пример #7
0
void liqBoundingBoxLocator::draw( M3dView & view, 
                                  const MDagPath & path,
                                  M3dView::DisplayStyle style, 
                                  M3dView::DisplayStatus status )
{ 
	MFnDagNode dagFn( thisMObject() );
	MFnDagNode transFn( dagFn.parent( 0 ) );

	MStatus stat;

	bool drawBox( 0 );
	MPlug plug = dagFn.findPlug( "drawBox", stat );
	if ( stat == MS::kSuccess ) plug.getValue( drawBox );
	if ( !drawBox ) return;

	MDoubleArray bb( 6 );
	MGlobal::executeCommand( MString( "exactWorldBoundingBox " ) + transFn.fullPathName(), bb );

	pts = shared_array< MPoint >( new MPoint[ 8 ] );

	pts[0].x = bb[0];
	pts[0].y = bb[4];
	pts[0].z = bb[2];

	pts[1].x = bb[0];
	pts[1].y = bb[4];
	pts[1].z = bb[5];

	pts[2].x = bb[3];
	pts[2].y = bb[4];
	pts[2].z = bb[5];

	pts[3].x = bb[3];
	pts[3].y = bb[4];
	pts[3].z = bb[2];

	pts[4].x = bb[0];
	pts[4].y = bb[1];
	pts[4].z = bb[2];

	pts[5].x = bb[0];
	pts[5].y = bb[1];
	pts[5].z = bb[5];

	pts[6].x = bb[3];
	pts[6].y = bb[1];
	pts[6].z = bb[5];

	pts[7].x = bb[3];
	pts[7].y = bb[1];
	pts[7].z = bb[2];

	MMatrix m( path.inclusiveMatrix() );

	for( unsigned i( 0 ); i < 8; i++ )
		pts[i] *= m.inverse();

	// draw box
	view.beginGL();
	view.setDrawColor( MColor( .57f, 0, .57f ) );
	glPushAttrib( GL_CURRENT_BIT );

	glBegin(GL_LINE_STRIP);
	glVertex3f( (float)pts[0].x, (float)pts[0].y, (float)pts[0].z );
	glVertex3f( (float)pts[1].x, (float)pts[1].y, (float)pts[1].z );
	glVertex3f( (float)pts[2].x, (float)pts[2].y, (float)pts[2].z );
	glVertex3f( (float)pts[3].x, (float)pts[3].y, (float)pts[3].z );
	glVertex3f( (float)pts[0].x, (float)pts[0].y, (float)pts[0].z );
	glEnd();
	glBegin(GL_LINE_STRIP);
	glVertex3f( (float)pts[4].x, (float)pts[4].y, (float)pts[4].z );
	glVertex3f( (float)pts[5].x, (float)pts[5].y, (float)pts[5].z );
	glVertex3f( (float)pts[6].x, (float)pts[6].y, (float)pts[6].z );
	glVertex3f( (float)pts[7].x, (float)pts[7].y, (float)pts[7].z );
	glVertex3f( (float)pts[4].x, (float)pts[4].y, (float)pts[4].z );
	glEnd();
	glBegin(GL_LINE_STRIP);
	glVertex3f( (float)pts[0].x, (float)pts[0].y, (float)pts[0].z );
	glVertex3f( (float)pts[4].x, (float)pts[4].y, (float)pts[4].z );
	glEnd();
	glBegin(GL_LINE_STRIP);
	glVertex3f( (float)pts[1].x, (float)pts[1].y, (float)pts[1].z );
	glVertex3f( (float)pts[5].x, (float)pts[5].y, (float)pts[5].z );
	glEnd();
	glBegin(GL_LINE_STRIP);
	glVertex3f( (float)pts[2].x, (float)pts[2].y, (float)pts[2].z );
	glVertex3f( (float)pts[6].x, (float)pts[6].y, (float)pts[6].z );
	glEnd();
	glBegin(GL_LINE_STRIP);
	glVertex3f( (float)pts[3].x, (float)pts[3].y, (float)pts[3].z );
	glVertex3f( (float)pts[7].x, (float)pts[7].y, (float)pts[7].z );
	glEnd();
	view.endGL();
}
void NifAnimationImporter::ImportControllers( NiAVObjectRef niAVObj, MDagPath & path ) {
	list<NiTimeControllerRef> controllers = niAVObj->GetControllers();

	//Iterate over the controllers, reacting properly to each type
	for ( list<NiTimeControllerRef>::iterator it = controllers.begin(); it != controllers.end(); ++it ) {
		if ( (*it)->IsDerivedType( NiKeyframeController::TYPE ) ) {
			//--NiKeyframeController--//
			NiKeyframeControllerRef niKeyCont = DynamicCast<NiKeyframeController>(*it);

			NiKeyframeDataRef niKeyData = niKeyCont->GetData();

			MFnTransform transFn( path.node() );

			MFnAnimCurve traXFn;
			MFnAnimCurve traYFn;
			MFnAnimCurve traZFn;

			MObject traXcurve = traXFn.create( transFn.findPlug("translateX") );
			MObject traYcurve = traYFn.create( transFn.findPlug("translateY") );
			MObject traZcurve = traZFn.create( transFn.findPlug("translateZ") );

			MTimeArray traTimes;
			MDoubleArray traXValues;
			MDoubleArray traYValues;
			MDoubleArray traZValues;

			vector<Key<Vector3> > tra_keys = niKeyData->GetTranslateKeys();

			for ( size_t i = 0; i < tra_keys.size(); ++i) {
				traTimes.append( MTime( tra_keys[i].time, MTime::kSeconds ) );
				traXValues.append( tra_keys[i].data.x );
				traYValues.append( tra_keys[i].data.y );
				traZValues.append( tra_keys[i].data.z );

				//traXFn.addKeyframe( tra_keys[i].time * 24.0, tra_keys[i].data.x );
				//traYFn.addKeyframe( tra_keys[i].time * 24.0, tra_keys[i].data.y );
				//traZFn.addKeyframe( tra_keys[i].time * 24.0, tra_keys[i].data.z );
			}

			traXFn.addKeys( &traTimes, &traXValues );
			traYFn.addKeys( &traTimes, &traYValues );
			traZFn.addKeys( &traTimes, &traZValues );

			KeyType kt = niKeyData->GetRotateType();

			if ( kt != XYZ_ROTATION_KEY ) {
				vector<Key<Quaternion> > rot_keys = niKeyData->GetQuatRotateKeys();

				MFnAnimCurve rotXFn;
				MFnAnimCurve rotYFn;
				MFnAnimCurve rotZFn;

				MObject rotXcurve = rotXFn.create( transFn.findPlug("rotateX") );
				//rotXFn.findPlug("rotationInterpolation").setValue(3);
				MObject rotYcurve = rotYFn.create( transFn.findPlug("rotateY") );
				//rotYFn.findPlug("rotationInterpolation").setValue(3);
				MObject rotZcurve = rotZFn.create( transFn.findPlug("rotateZ") );
				//rotZFn.findPlug("rotationInterpolation").setValue(3);

				MTimeArray rotTimes;
				MDoubleArray rotXValues;
				MDoubleArray rotYValues;
				MDoubleArray rotZValues;

				MEulerRotation mPrevRot;
				for( size_t i = 0; i < rot_keys.size(); ++i ) {
					Quaternion niQuat = rot_keys[i].data;

					MQuaternion mQuat( niQuat.x, niQuat.y, niQuat.z, niQuat.w );
					MEulerRotation mRot = mQuat.asEulerRotation();
					MEulerRotation mAlt;
					mAlt[0] = PI + mRot[0];
					mAlt[1] = PI - mRot[1];
					mAlt[2] = PI + mRot[2];

					for ( size_t j = 0; j < 3; ++j ) {
						double prev_diff = abs(mRot[j] - mPrevRot[j]);
						//Try adding and subtracting multiples of 2 pi radians to get
						//closer to the previous angle
						while (true) {
							double new_angle = mRot[j] - (PI * 2);
							double diff = abs( new_angle - mPrevRot[j] );
							if ( diff < prev_diff ) {
								mRot[j] = new_angle;
								prev_diff = diff;
							} else {
								break;
							}
						}
						while (true) {
							double new_angle = mRot[j] + (PI * 2);
							double diff = abs( new_angle - mPrevRot[j] );
							if ( diff < prev_diff ) {
								mRot[j] = new_angle;
								prev_diff = diff;
							} else {
								break;
							}
						}
					}

					for ( size_t j = 0; j < 3; ++j ) {
						double prev_diff = abs(mAlt[j] - mPrevRot[j]);
						//Try adding and subtracting multiples of 2 pi radians to get
						//closer to the previous angle
						while (true) {
							double new_angle = mAlt[j] - (PI * 2);
							double diff = abs( new_angle - mPrevRot[j] );
							if ( diff < prev_diff ) {
								mAlt[j] = new_angle;
								prev_diff = diff;
							} else {
								break;
							}
						}
						while (true) {
							double new_angle = mAlt[j] + (PI * 2);
							double diff = abs( new_angle - mPrevRot[j] );
							if ( diff < prev_diff ) {
								mAlt[j] = new_angle;
								prev_diff = diff;
							} else {
								break;
							}
						}
					}


					//Try taking advantage of the fact that:
					//Rotate(x,y,z) = Rotate(pi + x, pi - y, pi +z)
					double rot_diff = ( (abs(mRot[0] - mPrevRot[0]) + abs(mRot[1] - mPrevRot[1]) + abs(mRot[2] - mPrevRot[2]) ) / 3.0 );
					double alt_diff = ( (abs(mAlt[0] - mPrevRot[0]) + abs(mAlt[1] - mPrevRot[1]) + abs(mAlt[2] - mPrevRot[2]) ) / 3.0 );

					if ( alt_diff < rot_diff ) {
						mRot = mAlt;
					}

					mPrevRot = mRot;

					rotTimes.append( MTime(rot_keys[i].time, MTime::kSeconds) );
					rotXValues.append( mRot[0] );
					rotYValues.append( mRot[1] );
					rotZValues.append( mRot[2] );
				}


				rotXFn.addKeys( &rotTimes, &rotXValues );
				rotYFn.addKeys( &rotTimes, &rotYValues );
				rotZFn.addKeys( &rotTimes, &rotZValues );
			}
		}
	}
}
Пример #9
0
/**
 * Insert a new node into the hash table.
 */
int liqRibHT::insert( MDagPath &path, double /*lframe*/, int sample,
                      ObjectType objType,
                      int CountID,
                      MMatrix *matrix,
                      const MString instanceStr,
                      int particleId )
{
	CM_TRACE_FUNC("liqRibClipPlaneData::insert("<<path.fullPathName()<<",lframe,"
		<<sample<<","<<objType<<","<<CountID<<",matrix,"<<instanceStr<<","<<particleId<<")");

  LIQDEBUGPRINTF( "-> inserting node into hash table\n" );
  MFnDagNode  fnDagNode( path );
  MStatus    returnStatus;

  objTypeVec.push_back( objType );

  MString nodeName = fnDagNode.fullPathName( &returnStatus );
  if ( objType == MRT_RibGen ) 
    nodeName += "RIBGEN";

  const char* name( nodeName.asChar() );

  ulong hc = hash( name ,CountID );

  RibHashVec.push_back( nodeName );
  LIQDEBUGPRINTF( "-> hashed node name: %s", name );
  LIQDEBUGPRINTF( " ID: %u\n", hc );

  liqRibNodePtr  node;
  /*node = find( path.node(), objType );*/
  node = find( nodeName, path, objType );
  liqRibNodePtr     newNode;
  liqRibNodePtr    instance;

  // If "node" is non-null then there's already a hash table entry at
  // this point
  //
  liqRibNodePtr tail;
  if( node ) 
  {
    while( node ) 
    {
      tail = node;

      // Break if we've already dealt with this DAG path
      // (and instance string - by default this is "", which
      //  will match for most objects - allowing us to deal
      //  with particle-instancing).
      //
      if ( path        == node->path() &&
           instanceStr == node->getInstanceStr() )
      {
        break;
      }

      if ( path.node() == node->path().node() ) 
      {
        // We have found another instance of the object we are object
        // looking for
        instance = node;
      }
      node = node->next;
    }
    if ( ( !node ) && ( instance ) ) 
    {
      // We have not found a node with a matching path, but we have found
      // one with a matching object, so we need to insert a new instance
      newNode = liqRibNodePtr( new liqRibNode( instance, instanceStr ) );
    }
  }
  if( !newNode ) 
  {
    // We have to make a new node
    if ( !node) 
    {
      node = liqRibNodePtr( new liqRibNode( liqRibNodePtr(), instanceStr) );
      if ( tail ) 
      {
        assert( !tail->next );
        tail->next = node;
        RibNodeMap.insert( RNMAP::value_type( hc, node ) );
      } 
      else 
        RibNodeMap.insert( RNMAP::value_type( hc, node ) );
    }
  } 
  else 
  {
    assert( !node );
    // Append new instance node onto tail of linked list
    node = newNode;
    if( tail ) 
    {
      assert( !tail->next );
      tail->next = node;
      RibNodeMap.insert( RNMAP::value_type( hc, node ) );
    } 
    else 
      RibNodeMap.insert( RNMAP::value_type( hc, node ) );
  }

  node->set( path, sample, objType, particleId );

  // If we were given a specific matrix to use (this only
  // happens when we've got particle-instancing.
  //
  if( matrix != NULL )
  {
    // Calculate the inclusive matrix for the instanced
    // object (as a product of the original object's
    // exclusive matrix - see Maya docs - and the given
    // matrix).
    //
    MMatrix inclusiveMatrix = path.exclusiveMatrix() * ( *matrix );
    node->object( sample )->setMatrix( 0, inclusiveMatrix );
  }

  // We can NOT support deformation blur on particle instancing,
  // since there's no way to guarantee that the objects are
  // topologically identical over the sample range.
  //
  if( instanceStr != "" )
    node->motion.deformationBlur = false;

  LIQDEBUGPRINTF( "-> finished inserting node into hash table\n" );
  return 0;
}
MStatus AlembicExportCommand::doIt(const MArgList &args)
{
  ESS_PROFILE_SCOPE("AlembicExportCommand::doIt");

  MStatus status = MS::kFailure;

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

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

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

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

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

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

      // Each frames to export can manually be specified via the "frames" parameter.
      // This allow for very specific frames to be exported.
      // In our case (Squeeze Studio) this allow the animator to export only specific subframes.
      // The advantage of exporting specific subframes instead of using the "substep" parameter is that the animator don't have to
      // fix all the flipping occuring in a rig when trying to work with substeps.
      MDoubleArray frames;

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

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

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

        // search/replace
        else if (lowerValue == "search") {
          search_str = valuePair[1].asChar();
        }
        else if (lowerValue == "replace") {
          replace_str = valuePair[1].asChar();
        }
        else if (lowerValue == "ogawa") {
          useOgawa = valuePair[1].asInt() != 0;
        }
        else if(lowerValue == "frames")
        {
          MStringArray strFrames;
          valuePair[1].split(',', strFrames);
          for(unsigned int i=0;i<strFrames.length();i++)
          {
            double frame = strFrames[i].asDouble();
            frames.append(frame);
          }
        }
        else if (lowerValue == "attrprefixes") {
          splitListArg(valuePair[1], prefixFilters);
        }
        else if (lowerValue == "attrs") {
          splitListArg(valuePair[1], attributes);
        }
        else if (lowerValue == "userattrprefixes") {
          splitListArg(valuePair[1], userPrefixFilters);
        }
        else if (lowerValue == "userattrs") {
          splitListArg(valuePair[1], userAttributes);
        }
        else {
          MGlobal::displayWarning(
              "[ExocortexAlembic] Skipping invalid token: " + tokens[j]);
          continue;
        }
      }

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

          // get all parents
          MObjectArray parents;

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

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

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

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

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

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

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

      // construct the frames if they are not already provided
      if (frames.length() == 0)
      {
        const double frameIncr = frameSteps / frameSubSteps;
        for (double frame = frameIn; frame <= frameOut; frame += frameIncr) {
          frames.append(frame);
        }
      }

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

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

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

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

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

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

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

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

      AlembicCurveAccumulator::StartRecordingFrame();
      for (size_t i = 0; i < jobPtrs.size(); i++) {
        MStatus status = jobPtrs[i]->Process(frame);
        if (status != MStatus::kSuccess) {
          MGlobal::displayError("[ExocortexAlembic] Job aborted :" +
                                jobPtrs[i]->GetFileName());
          for (size_t k = 0; k < jobPtrs.size(); k++) {
            delete (jobPtrs[k]);
          }
          restoreOldTime(currentAnimStartTime, currentAnimEndTime, oldCurTime,
                         curMinTime, curMaxTime);
          return status;
        }
      }
      AlembicCurveAccumulator::StopRecordingFrame();
    }
    */
    // Collect all job frames
    std::vector<double> all_frames;
    for(size_t i=0;i<jobPtrs.size();i++)
    {
      const std::vector<double> jobFrames = jobPtrs[i]->GetFrames();
      for (unsigned int j=0;j<jobFrames.size();++j)
      {
        all_frames.push_back(jobFrames[j]);
      }
    }

    // Force Maya to play the animation in sequence. This way particles are updated.
    unsigned int num_frames_to_export = all_frames.size();
    all_frames.push_back(all_frames[num_frames_to_export -1] + incrSteps);
    for (unsigned int i=0;i<num_frames_to_export;++i)
    {
      frame = all_frames[i];
      nextFrame = all_frames[i+1];

      // debuging
      MString msg = "Exporting frame ";
      msg += frame;
      msg += ". Next is ";
      msg += nextFrame;
      MGlobal::displayInfo(msg);

      MAnimControl::setCurrentTime(MTime(frame/frameRate,MTime::kSeconds));
      MAnimControl::setAnimationEndTime( MTime(nextFrame/frameRate,MTime::kSeconds) );
      MAnimControl::playForward();  // this way, it forces Maya to play exactly one frame! and particles are updated!

      AlembicCurveAccumulator::StartRecordingFrame();
      for(size_t i=0;i<jobPtrs.size();i++)
      {
        MStatus status = jobPtrs[i]->Process(frame);
        if(status != MStatus::kSuccess)
        {
          MGlobal::displayError("[ExocortexAlembic] Job aborted :"+jobPtrs[i]->GetFileName());
          for(size_t k=0;k<jobPtrs.size();k++)
          {
            delete(jobPtrs[k]);
          }

          restoreOldTime(currentAnimStartTime, currentAnimEndTime, oldCurTime, curMinTime, curMaxTime);
          return status;
        }

      }
      AlembicCurveAccumulator::StopRecordingFrame();
    }
  }
  catch (...) {
    MGlobal::displayError(
        "[ExocortexAlembic] Jobs aborted, force closing all archives!");
    for (std::vector<AlembicWriteJob *>::iterator beg = jobPtrs.begin();
         beg != jobPtrs.end(); ++beg) {
      (*beg)->forceCloseArchive();
    }
    restoreOldTime(currentAnimStartTime, currentAnimEndTime, oldCurTime,
                   curMinTime, curMaxTime);
    MPxCommand::setResult("Error caught in AlembicExportCommand::doIt");
    status = MS::kFailure;
  }
  MAnimControl::stop();
  AlembicCurveAccumulator::Destroy();

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

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

  // remove all known archives
  deleteAllArchives();
  return status;
}
Пример #11
0
MStatus MayaToCorona::doIt( const MArgList& args)
{
    MStatus stat = MStatus::kSuccess;
    std::unique_ptr<MayaTo::CmdArgs> cmdArgs(new MayaTo::CmdArgs);

    MArgDatabase argData(syntax(), args);

    if (argData.isFlagSet("-version", &stat))
    {
        MStringArray res;
        for (auto v : getFullVersionString())
            res.append(v.c_str());
        setResult(res);

        return MS::kSuccess;
    }

    MayaTo::MayaToWorld::WorldRenderState rstate = MayaTo::getWorldPtr()->renderState;
    if (argData.isFlagSet("-state", &stat))
    {
        if (rstate == MayaTo::MayaToWorld::RSTATETRANSLATING)
            setResult("rstatetranslating");
        if (rstate == MayaTo::MayaToWorld::RSTATERENDERING)
            setResult("rstaterendering");
        if (rstate == MayaTo::MayaToWorld::RSTATEDONE)
            setResult("rstatedone");
        if (rstate == MayaTo::MayaToWorld::RSTATENONE)
            setResult("rstatenone");
        if (rstate == MayaTo::MayaToWorld::RSTATESTOPPED)
            setResult("rstatestopped");
        return MS::kSuccess;
    }

    MGlobal::displayInfo("Executing mayaToCorona...");
    setLogLevel();

    if (argData.isFlagSet("-canDoIPR", &stat))
    {
        if(MayaTo::getWorldPtr()->canDoIPR())
            setResult("yes");
        else
            setResult("no");
        return MS::kSuccess;
    }

    if ( argData.isFlagSet("-stopIpr", &stat))
    {
        Logging::debug(MString("-stopIpr"));
        EventQueue::Event e;
        e.type = EventQueue::Event::IPRSTOP;
        theRenderEventQueue()->push(e);
        return MS::kSuccess;
    }

    if ( argData.isFlagSet("-pauseIpr", &stat))
    {
        Logging::debug(MString("-pauseIpr"));
        Logging::debug(MString("-stopIpr"));
        EventQueue::Event e;
        e.type = EventQueue::Event::IPRPAUSE;
        theRenderEventQueue()->push(e);
        return MS::kSuccess;
    }

    if (argData.isFlagSet("-usrDataString", &stat))
    {
        Logging::debug(MString("-usrDataString"));
        argData.getFlagArgument("-usrDataString", 0, cmdArgs->userDataString);
    }

    if (argData.isFlagSet("-usrDataInt", &stat))
    {
        Logging::debug(MString("-usrDataInt"));
        argData.getFlagArgument("-usrDataInt", 0, cmdArgs->userDataInt);
    }

    if (argData.isFlagSet("-usrDataFloat", &stat))
    {
        Logging::debug(MString("-usrDataFloat"));
        argData.getFlagArgument("-usrDataFloat", 0, cmdArgs->userDataFloat);
    }

    if (argData.isFlagSet("-usrEvent", &stat))
    {
        Logging::debug(MString("-usrEvent"));
        argData.getFlagArgument("-usrEvent", 0, cmdArgs->userEvent);

        EventQueue::Event e;
        e.cmdArgsData = std::move(cmdArgs);
        e.type = EventQueue::Event::USER;
        theRenderEventQueue()->push(e);
        return MS::kSuccess;
    }

    // I have to request useRenderRegion here because as soon the command is finished, what happens immediatly after the command is
    // put into the queue, the value is set back to false.
    MObject drg = objectFromName("defaultRenderGlobals");
    MFnDependencyNode drgfn(drg);
    cmdArgs->useRenderRegion = drgfn.findPlug("useRenderRegion").asBool();

    cmdArgs->renderType = MayaTo::MayaToWorld::WorldRenderType::UIRENDER;
    if (MGlobal::mayaState() == MGlobal::kBatch)
        cmdArgs->renderType = MayaTo::MayaToWorld::WorldRenderType::BATCHRENDER;

    if ( argData.isFlagSet("-startIpr", &stat))
    {
        Logging::debug(MString("-startIpr"));
        cmdArgs->renderType = MayaTo::MayaToWorld::WorldRenderType::IPRRENDER;
    }

    if (argData.isFlagSet("-width", &stat))
    {
        argData.getFlagArgument("-width", 0, cmdArgs->width);
        Logging::debug(MString("width: ") + cmdArgs->width);
    }

    if (argData.isFlagSet("-height", &stat))
    {
        argData.getFlagArgument("-height", 0, cmdArgs->height);
        Logging::debug(MString("height: ") + cmdArgs->height);
    }

    if ( argData.isFlagSet("-camera", &stat))
    {
        MDagPath camera;
        MSelectionList selectionList;
        argData.getFlagArgument("-camera", 0, selectionList);
        stat = selectionList.getDagPath(0, camera);
        camera.extendToShape();
        Logging::debug(MString("camera: ") + camera.fullPathName());
        cmdArgs->cameraDagPath = camera;
    }

    EventQueue::Event e;
    e.cmdArgsData = std::move(cmdArgs);
    e.type = EventQueue::Event::INITRENDER;
    theRenderEventQueue()->push(e);

    //
    if (MGlobal::mayaState() == MGlobal::kBatch)
    {
        RenderQueueWorker::startRenderQueueWorker();
    }
    return MStatus::kSuccess;
}
Пример #12
0
MStatus CIKSolverNode::doSimpleSolver()
{
	MStatus stat;

	// Get the handle and create a function set for it
	//	
	MIkHandleGroup* handle_group = handleGroup();
	if (NULL == handle_group) {
		return MS::kFailure;
	}
	MObject handle = handle_group->handle(0);
	MDagPath handlePath = MDagPath::getAPathTo(handle);
	MFnIkHandle fnHandle(handlePath, &stat);

	// End-Effector
	MDagPath endEffectorPath;
	fnHandle.getEffector(endEffectorPath);
	MFnIkEffector  fnEffector(endEffectorPath);
	MPoint effectorPos = fnEffector.rotatePivot(MSpace::kWorld);

	unsigned int numJoints = endEffectorPath.length();
	std::vector<MDagPath> jointsDagPaths; jointsDagPaths.reserve(numJoints);
	while (endEffectorPath.length() > 1)
	{
		endEffectorPath.pop();
		jointsDagPaths.push_back( endEffectorPath );
	}
	std::reverse(jointsDagPaths.begin(), jointsDagPaths.end());

	static bool builtLocalSkeleton = false;
	if (builtLocalSkeleton == false)
	{
		for (int jointIdx = 0; jointIdx < jointsDagPaths.size(); ++jointIdx)
		{
			MFnIkJoint curJoint(jointsDagPaths[jointIdx]);
			m_localJointsPos.push_back( curJoint.getTranslation(MSpace::kWorld) );
		}
		m_localJointsPos.push_back(effectorPos );
		builtLocalSkeleton = true;
	}

	MPoint startJointPos = MFnIkJoint(jointsDagPaths.front()).getTranslation(MSpace::kWorld);

	MVector startToEndEff = m_localJointsPos.back() - m_localJointsPos.front();
	double curveLength = (getPosition(1.0) - getPosition(0.0)).length();
	double chainLength = startToEndEff.length(); // in local space.
	double stretchFactor = curveLength / chainLength;
	
	double uVal = 0.0f;
	MVector jointPosL = m_localJointsPos[0];
	for (int jointIdx = 0; jointIdx < jointsDagPaths.size(); ++jointIdx)
	{
		MFnIkJoint curJoint(jointsDagPaths[jointIdx]);

		MVector curJointPosL = m_localJointsPos[jointIdx];

		double dist = stretchFactor * (curJointPosL - jointPosL).length();
		uVal = uVal + dist / curveLength;

		MVector curCurveJointPos = getPosition(uVal);
		curJoint.setTranslation(curCurveJointPos, MSpace::kWorld);
		jointPosL = curJointPosL;
	}
	MVector effectorCurvePos = getPosition(1.0);
	MVector curCurveJointPos = getPosition(uVal);
	MVector effectorVec = (effectorCurvePos - curCurveJointPos).normal();
	double endJointAngle[3]; 
	MVector effectorVecXY = MVector(effectorVec(0), effectorVec(1), 0.0);
	endJointAngle[2] = effectorVecXY.angle(MVector(1, 0, 0));
	if ((MVector(1, 0, 0) ^ effectorVecXY) * MVector(0, 0, 1) < 0.0) { endJointAngle[2] = -endJointAngle[2]; }
	MVector effectorVecXZ = MVector(effectorVec(0), 0.0, effectorVec(2));
	endJointAngle[1] = effectorVecXZ.angle(MVector(1, 0, 0));
	if ((MVector(1, 0, 0) ^ effectorVecXZ) * MVector(0, 1, 0) < 0.0) { endJointAngle[1] = -endJointAngle[1]; }
	endJointAngle[0] = 0.0;
	MFnIkJoint curJoint(jointsDagPaths.back()); curJoint.setRotation(endJointAngle, curJoint.rotationOrder());
	return MS::kSuccess;
}
Пример #13
0
bool getObjectShadingGroups(const MDagPath& shapeObjectDP, MObject& shadingGroup)
{
    // if obj is a light, simply return the mobject
    if (shapeObjectDP.hasFn(MFn::kLight))
        shadingGroup = shapeObjectDP.node();

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

        // A ShadingGroup will have a MFnSet
        MObjectArray sets, comps;
        fnMesh.getConnectedSetsAndMembers(shapeObjectDP.instanceNumber(), sets, comps, true);

        // Each set is a Shading Group. Loop through them
        for (unsigned int i = 0; i < sets.length(); ++i)
        {
            shadingGroup = sets[i];
            return true;
        }
    }

    if (shapeObjectDP.hasFn(MFn::kNurbsSurface)||shapeObjectDP.hasFn(MFn::kParticle)||shapeObjectDP.hasFn(MFn::kNParticle))
    {

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

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

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

        // Loop through each ShadingGroup Plug
        for (unsigned int i=0; i < SGPlugArray.length(); ++i)
        {
            shadingGroup = SGPlugArray[i].node();
            return true;
        }
    }
    return false;
}
Пример #14
0
bool getObjectShadingGroups(const MDagPath& shapeObjectDP, MIntArray& perFaceAssignments, MObjectArray& shadingGroups, bool needsPerFaceInfo=true)
{
    // if obj is a light, simply return the mobject
    if (shapeObjectDP.node().hasFn(MFn::kLight))
    {
        perFaceAssignments.clear();
        shadingGroups.clear();
        shadingGroups.append(shapeObjectDP.node());
        return true;
    }

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

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

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

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

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

        MIntArray indices;
        indices = perFaceAssignments;

        int subdivs = 0;
        int multiplier = 0;

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

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

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

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

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

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

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

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

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

        // Loop through each ShadingGroup Plug
        for (unsigned int i=0; i < SGPlugArray.length(); ++i)
        {
            shadingGroups.append(SGPlugArray[i].node());
            return true;
        }
    }
    return false;
}
Пример #15
0
MStatus meshOp::doIt( const MArgList& argList )
//
//	Description:
//		implements the MEL meshOp command.
//
//	Arguments:
//		argList - the argument list that was passes to the command from MEL
//
//	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.
//
{
	MStatus status;
	bool badArgument = false;

	// Only one parameter is expected to be passed to this command: the mesh
	// operation type. Get it, validate it or stop prematurely
	//
	if (argList.length() == 1)
	{
		int operationTypeArgument = argList.asInt(0);
		if (operationTypeArgument < 0
			|| operationTypeArgument > kMeshOperationCount - 1)
		{
			badArgument = true;
		}
		else
		{
			fOperation = (MeshOperation)operationTypeArgument;
		}
	}
	else badArgument = true;

	if (badArgument)
	{
		cerr << "Expecting one parameter: the operation type." << endl;
		cerr << "Valid types are: " << endl;
		cerr << "   0 - Subdivide edge(s)." << endl;
		cerr << "   1 - Subdivide face(s)." << endl;
		cerr << "   2 - Extrude edge(s)." << endl;
		cerr << "   3 - Extrude face(s)." << endl;
		cerr << "   4 - Collapse edge(s)." << endl;
		cerr << "   5 - Collapse face(s)." << endl;
		cerr << "   6 - Duplicate face(s)." << endl;
		cerr << "   7 - Extract face(s)." << endl;
		cerr << "   8 - Split face(s)." << endl;
		cerr << "   8 - Chamfer vertex(s)." << endl;
		displayError(" Expecting one parameter: the operation type.");
		return MS::kFailure;
	}

	// Each mesh operation only supports one type of components
	// 
	MFn::Type componentType = meshOpFty::getExpectedComponentType(fOperation);

	// Parse the selection list for selected components of the right type.
	// To simplify things, we only take the first object that we find with
	// selected components and operate on that object alone.
	//
	// All other objects are ignored and return warning messages indicating
	// this limitation.
	//
	MSelectionList selList;
	MGlobal::getActiveSelectionList( selList );
	MItSelectionList selListIter( selList );
	selListIter.setFilter( MFn::kMesh );

	// The meshOperation node only accepts a component list input, so we build
	// a component list using MFnComponentListData.
	//
	// MIntArrays could also be passed into the node to represent the ids,
	// but are less storage efficient than component lists, since consecutive 
	// components are bundled into a single entry in component lists.
	//
	MFnComponentListData compListFn;
	compListFn.create();
	bool found = false;
	bool foundMultiple = false;

	for( ; !selListIter.isDone(); selListIter.next() )
	{
		MDagPath dagPath;
		MObject component;
		selListIter.getDagPath( dagPath, component );

		// Check for selected components of the right type
		//
		if( component.apiType() == componentType )
		{
			if( !found )
			{
				// The variable 'component' holds all selected components 
				// on the selected object, thus only a single call to 
				// MFnComponentListData::add() is needed to store the selected
				// components for a given object.
				//
				compListFn.add( component );

				// Copy the component list created by MFnComponentListData
				// into our local component list MObject member.
				//
				fComponentList = compListFn.object();

				// Locally store the actual ids of the selected components so 
				// that this command can directly modify the mesh in the case 
				// when there is no history and history is turned off.
				//
				MFnSingleIndexedComponent compFn( component );

				// Ensure that this DAG path will point to the shape 
				// of our object. Set the DAG path for the polyModifierCmd.
				//
				dagPath.extendToShape();
				setMeshNode( dagPath );
				found = true;
			}
			else
			{
				// Break once we have found a multiple object holding 
				// selected components, since we are not interested in how 
				// many multiple objects there are, only the fact that there
				// are multiple objects.
				//
				foundMultiple = true;
				break;
			}
		}
	}
	if( foundMultiple )
	{
		displayWarning("Found more than one object with selected components.");
		displayWarning("Only operating on first found object.");
	}

	// Initialize the polyModifierCmd node type - mesh node already set
	//
	setModifierNodeType( meshOpNode::id );

	if( found )
	{
		// Now, pass control over to the polyModifierCmd::doModifyPoly() method
		// to handle the operation.
		//
		status = doModifyPoly();
		
		if( status == MS::kSuccess )
		{
			setResult( "meshOp command succeeded!" );
		}
		else
		{
			displayError( "meshOp command failed!" );
		}
	}
	else
	{
		displayError(
			"meshOp command failed: Unable to find selected components" );
		status = MS::kFailure;
	}
	
	return status;
}
Пример #16
0
MStatus closestPointOnCurveCommand::redoIt()

{

   // DOUBLE-CHECK TO MAKE SURE THERE'S A SPECIFIED OBJECT TO EVALUATE ON:

   if (sList.length() == 0)

   {
	   MStatus stat;
	   MString msg = MStringResource::getString(kNoValidObject, stat);
       displayError(msg);
       return MStatus::kFailure;
   }



   // RETRIEVE THE SPECIFIED OBJECT AS A DAGPATH:

   MDagPath curveDagPath;
   sList.getDagPath(0, curveDagPath);


   // CHECK FOR INVALID NODE-TYPE INPUT WHEN SPECIFIED/SELECTED NODE IS *NOT* A "CURVE" NOR "CURVE TRANSFORM":

   if (!curveDagPath.node().hasFn(MFn::kNurbsCurve) && !(curveDagPath.node().hasFn(MFn::kTransform) && curveDagPath.hasFn(MFn::kNurbsCurve)))

   {
	   MStatus stat;
	   MString msg; 
	   // Use format to place variable string into message
	   MString msgFmt = MStringResource::getString(kInvalidType, stat);
	   MStringArray selectionStrings;
	   sList.getSelectionStrings(0, selectionStrings);
	   msg.format(msgFmt, selectionStrings[0]);
	   displayError(msg);
       return MStatus::kFailure;
   }



   // WHEN COMMAND *NOT* IN "QUERY MODE" (I.E. "CREATION MODE"), CREATE AND CONNECT A "closestPointOnCurve" NODE AND RETURN ITS NODE NAME:

   if (!queryFlagSet)

   {

      // CREATE THE NODE:

      MFnDependencyNode depNodeFn;

      if (closestPointOnCurveNodeName == "")

         depNodeFn.create("closestPointOnCurve");

      else

         depNodeFn.create("closestPointOnCurve", closestPointOnCurveNodeName);

      closestPointOnCurveNodeName = depNodeFn.name();



      // SET THE ".inPosition" ATTRIBUTE, IF SPECIFIED IN THE COMMAND:

      if (inPositionFlagSet)

      {

         MPlug inPositionXPlug = depNodeFn.findPlug("inPositionX");

         inPositionXPlug.setValue(inPosition.x);

         MPlug inPositionYPlug = depNodeFn.findPlug("inPositionY");

         inPositionYPlug.setValue(inPosition.y);

         MPlug inPositionZPlug = depNodeFn.findPlug("inPositionZ");

         inPositionZPlug.setValue(inPosition.z);

      }



      // MAKE SOME ADJUSTMENTS WHEN THE SPECIFIED NODE IS A "TRANSFORM" OF A CURVE SHAPE:

      unsigned instanceNumber=0;

      if (curveDagPath.node().hasFn(MFn::kTransform))

      {

         // EXTEND THE DAGPATH TO ITS CURVE "SHAPE" NODE:

         curveDagPath.extendToShape();



         // TRANSFORMS ARE *NOT* NECESSARILY THE "FIRST" INSTANCE TRANSFORM OF A CURVE SHAPE:

         instanceNumber = curveDagPath.instanceNumber();

      }



      // CONNECT THE NODES:

      MPlug worldCurvePlug, inCurvePlug;

      inCurvePlug = depNodeFn.findPlug("inCurve");

      depNodeFn.setObject(curveDagPath.node());

      worldCurvePlug = depNodeFn.findPlug("worldSpace");

      worldCurvePlug = worldCurvePlug.elementByLogicalIndex(instanceNumber);

      MDGModifier dgModifier;

      dgModifier.connect(worldCurvePlug, inCurvePlug);

      dgModifier.doIt();



      // SET COMMAND RESULT TO BE NEW NODE'S NAME, AND RETURN:

      setResult(closestPointOnCurveNodeName);

      return MStatus::kSuccess;

   }

   // OTHERWISE, WE'RE IN THE COMMAND'S "QUERY MODE":

   else

   {

      // COMPUTE THE CLOSEST POSITION, NORMAL, TANGENT, PARAMETER-U AND DISTANCE, USING THE *FIRST* INSTANCE TRANSFORM WHEN CURVE IS SPECIFIED AS A "SHAPE":

      MPoint position;

      MVector normal, tangent;

      double paramU, distance;

      closestTangentUAndDistance(curveDagPath, inPosition, position, normal, tangent, paramU, distance);



      // WHEN NO QUERYABLE FLAG IS SPECIFIED, INDICATE AN ERROR:

      if (!positionFlagSet && !normalFlagSet && !tangentFlagSet && !paramUFlagSet && !distanceFlagSet)

      {
		  MStatus stat;
		  MString msg = MStringResource::getString(kNoQueryFlag, stat);
		  displayError(msg);
          return MStatus::kFailure;
     }

      // WHEN JUST THE "DISTANCE" IS QUERIED, RETURN A SINGLE "FLOAT" INSTEAD OF AN ENTIRE FLOAT ARRAY FROM THE COMMAND:

      else if (distanceFlagSet && !(positionFlagSet || normalFlagSet || tangentFlagSet || paramUFlagSet))

         setResult(distance);

      // WHEN JUST THE "PARAMETER-U" IS QUERIED, RETURN A SINGLE "FLOAT" INSTEAD OF AN ENTIRE FLOAT ARRAY FROM THE COMMAND:

      else if (paramUFlagSet && !(positionFlagSet || normalFlagSet || tangentFlagSet || distanceFlagSet))

         setResult(paramU);

      // OTHERWISE, SET THE RETURN VALUE OF THE COMMAND'S RESULT TO A "COMPOSITE ARRAY OF FLOATS":

      else

      {

         // HOLDS FLOAT ARRAY RESULT:

         MDoubleArray floatArrayResult;



         // APPEND THE RESULTS OF THE CLOSEST POSITION, NORMAL, TANGENT, PARAMETER-U AND DISTANCE VALUES TO THE FLOAT ARRAY RESULT:

         if (positionFlagSet)

         {

            floatArrayResult.append(position.x);

            floatArrayResult.append(position.y);

            floatArrayResult.append(position.z);

         }

         if (normalFlagSet)

         {

            floatArrayResult.append(normal.x);

            floatArrayResult.append(normal.y);

            floatArrayResult.append(normal.z);

         }

         if (tangentFlagSet)

         {

            floatArrayResult.append(tangent.x);

            floatArrayResult.append(tangent.y);

            floatArrayResult.append(tangent.z);

         }

         if (paramUFlagSet)

            floatArrayResult.append(paramU);

         if (distanceFlagSet)

            floatArrayResult.append(distance);



         // FINALLY, SET THE COMMAND'S RESULT:

         setResult(floatArrayResult);

      }



      return MStatus::kSuccess;

   }

}
MStatus sgCurveEditBrush_context::editCurve( MDagPath dagPathCurve,
		int beforeX, int beforeY, int currentX, int currentY, float radius, 
		const MDoubleArray& dArrLength, MPointArray &points )
{
	MStatus status;

	if( radius < 0 ) return MS::kSuccess;

	MDagPath dagPathCam;
	M3dView view = M3dView::active3dView( &status );
	CHECK_MSTATUS_AND_RETURN_IT( status );

	view.getCamera( dagPathCam );

	MPoint  camPos = dagPathCam.inclusiveMatrix()[3];
	MVector vCamUp  = dagPathCam.inclusiveMatrix()[1];
	vCamUp.normalize();

	radius *= .05;

	MPoint nearClipBefore;
	MPoint farClipBefore;
	view.viewToWorld( beforeX, beforeY, nearClipBefore, farClipBefore );

	MVector rayBefore  = nearClipBefore - camPos;
	rayBefore.normalize();
	rayBefore *= 20;
	MPoint  posBefore = rayBefore + camPos;

	MPoint nearClipCurrent;
	MPoint farClipCurrent;
	view.viewToWorld( currentX, currentY, nearClipCurrent, farClipCurrent );

	MVector rayCurrent = nearClipCurrent - camPos;
	rayCurrent.normalize();
	rayCurrent *= 20;
	MPoint  posCurrent = rayCurrent + camPos;

	MVector vMove = posCurrent - posBefore;

	MMatrix mtxCurve = dagPathCurve.inclusiveMatrix();
	MFnNurbsCurve fnCurve( dagPathCurve );

	fnCurve.getCVs( points );

	for( int i=0; i< points.length(); i++ )
	{
		points[i] *= mtxCurve;
	}

	for( int i=1; i< points.length(); i++ )
	{
		MPoint cuPoint = points[i];
		MVector vPoint = cuPoint - camPos;

		MVector projV = ( vPoint * rayBefore )/( pow( rayBefore.length(), 2 ) )* rayBefore;
		MVector vertical = vPoint - projV;
		
		float radiusForPoint = vertical.length() / projV.length();

		if( radius < radiusForPoint )
			continue;
		MPoint parentPoint = points[i-1];

		MVector vCurveDirection = cuPoint - parentPoint;
		double vDirLength = vCurveDirection.length();

		MVector vEditDirection = vCurveDirection + vMove/rayBefore.length()*projV.length();

		double dotEdit = vCurveDirection.normal() * vEditDirection.normal();
		if( dotEdit < 0 ) continue;
		vEditDirection = vEditDirection * dotEdit + vCurveDirection*( 1-dotEdit );

		MVector vEditLength = vEditDirection / vEditDirection.length() * vCurveDirection.length();

		MVector vEdit = (vEditLength - vCurveDirection) * pow((double)(1-radiusForPoint/radius), 1 );
		points[i] += vEdit;

		for( int j=i+1; j< points.length(); j++ )
		{
			MPoint beforePoint = points[j];
			MPoint pPoint = points[j-1];
			MPoint beforePPoint = pPoint - vEdit;

			MVector vBefore = points[j] - beforePPoint;
			MVector vAfter  = points[j] - pPoint;
			MVector vCurrent = vAfter.normal() * dArrLength[j];
			
			points[j] = vCurrent + pPoint;

			vEdit = points[j] - beforePoint;
		}
	}

	MMatrix invMtxCurve = mtxCurve.inverse();
	for( int i=0; i< points.length(); i++ )
	{
		points[i] *= invMtxCurve;
	}

	fnCurve.setCVs( points );
	fnCurve.updateCurve();

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

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

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

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

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

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

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

    if (queryUsed) {
	if (assignAllToSingle) {
	    MGlobal::displayWarning("-as/-assignAllToSingle is ignored with query flag");
	}
	if (weightArray.length() > 0) {
	    MGlobal::displayWarning("-w/-weights is ignored with query flag");
	}
    }
    
    return status;
}
Пример #19
0
/*

	emits particles with color sampled from specified
	shading node/shading engine

*/
MStatus sampleParticles::doIt( const MArgList& args )
{
	unsigned int i;
	bool shadow = 0;
	bool reuse = 0;

	for ( i = 0; i < args.length(); i++ )
		if ( args.asString(i) == MString("-shadow") || 
			args.asString(i) == MString("-s") )
			shadow = 1;
		else if ( args.asString(i) == MString("-reuse") || 
			args.asString(i) == MString("-r") )
			reuse = 1;
		else
			break;
	if ( args.length() - i < 5 )
	{
		displayError( "Usage: sampleParticles [-shadow|-reuse] particleName <shadingEngine|shadingNode.plug> resX resY scale\n"
			"  Example: sampleParticles -shadow particle1 phong1SG 64 64 10;\n"
			"  Example: sampleParticles particle1 file1.outColor 128 128 5;\n" );
		return MS::kFailure;
	}
	if ( reuse && !shadow )	// can only reuse if shadow is turned on
		reuse = 0;

	MString particleName = args.asString( i );
	MString node = args.asString( i+1 );
	short resX = args.asInt( i+2 );
	short resY = args.asInt( i+3 );
	double scale = args.asDouble( i+4 );

	if ( scale <= 0.0 )
		scale = 1.0;

	MFloatArray uCoord, vCoord;
	MFloatPointArray points;
	MFloatVectorArray normals, tanUs, tanVs;

	if ( resX <= 0 )
		resX = 1;
	if ( resY <= 0 )
		resY = 1;

	MString command( "emit -o " );
	command += particleName;
	char tmp[2048];

	float stepU = (float) (1.0 / resX);
	float stepV = (float) (1.0 / resY);

	// stuff sample data by iterating over grid
	// Y is set to arch along the X axis

	int x, y;
	for ( y = 0; y < resY; y++ )
		for ( x = 0; x < resX; x++ )
		{
			uCoord.append( stepU * x );
			vCoord.append( stepV * y );

			float curY = (float) (sin( stepU * (x) * M_PI )*2.0);

			MFloatPoint curPt(
				(float) (stepU * x * scale),
				curY,
				(float) (stepV * y * scale ));

			MFloatPoint uPt(
				(float) (stepU * (x+1) * scale),
				(float) (sin( stepU * (x+1) * M_PI )*2.0),
				(float) (stepV * y * scale ));

			MFloatPoint vPt(
				(float) (stepU * (x) * scale),
				curY,
				(float) (stepV * (y+1) * scale ));

			MFloatVector du, dv, n;
			du = uPt-curPt;
			dv = vPt-curPt;

			n = dv^du;	// normal is based on dU x dV
			n = n.normal();
			normals.append( n );

			du.normal();
			dv.normal();
			tanUs.append( du );
			tanVs.append( dv );

			points.append( curPt );
		}

	// get current camera's world matrix

	MDagPath cameraPath;
	M3dView::active3dView().getCamera( cameraPath );
	MMatrix mat = cameraPath.inclusiveMatrix();
	MFloatMatrix cameraMat( mat.matrix );

	MFloatVectorArray colors, transps;
	if ( MS::kSuccess == MRenderUtil::sampleShadingNetwork( 
			node, 
			points.length(),
			shadow,
			reuse,

			cameraMat,

			&points,
			&uCoord,
			&vCoord,
			&normals,
			&points,
			&tanUs,
			&tanVs,
			NULL,	// don't need filterSize

			colors,
			transps ) )
	{
		fprintf( stderr, "%u points sampled...\n", points.length() );
		for ( i = 0; i < uCoord.length(); i++ )
		{
			sprintf( tmp, " -pos %g %g %g -at velocity -vv %g %g %g -at rgbPP -vv %g %g %g",
				points[i].x,
				points[i].y,
				points[i].z,

				normals[i].x,
				normals[i].y,
				normals[i].z,

				colors[i].x,
				colors[i].y,
				colors[i].z );

			command += MString( tmp );

			// execute emit command once every 512 samples
			if ( i % 512 == 0 )
			{
				fprintf( stderr, "%u...\n", i );
				MGlobal::executeCommand( command, false, false );
				command = MString( "emit -o " );
				command += particleName;
			}
		}

		if ( i % 512 )
			MGlobal::executeCommand( command, true, true );
	}
	else
	{
		displayError( node + MString(" is not a shading engine!  Specify node.attr or shading group node." ) );
	}

	return MS::kSuccess;
}
Пример #20
0
MStatus skinClusterWeights::redoIt()
{
    MStatus status;
    unsigned int ptr = 0;
	
    MSelectionList selList;
    int geomLen = geometryArray.length();
    fDagPathArray.setLength(geomLen);
    fComponentArray.setLength(geomLen);
    fInfluenceIndexArrayPtrArray = new MIntArray[geomLen];
    fWeightsPtrArray = new MDoubleArray[geomLen];

    for (int i = 0; i < geomLen; i++) {
	MDagPath dagPath;
	MObject  component;
	
	selList.clear();
	selList.add(geometryArray[i]);
	MStatus status = selList.getDagPath(0, dagPath, component);
	if (status != MS::kSuccess) {
	    continue;
	}
	if (component.isNull()) dagPath.extendToShape();

	MObject skinCluster = findSkinCluster(dagPath);
	if (!isSkinClusterIncluded(skinCluster)) {
	    continue;
	}

	MFnSkinCluster skinClusterFn(skinCluster, &status);
	if (status != MS::kSuccess) {
	    continue; 
	}

	MIntArray influenceIndexArray;
	populateInfluenceIndexArray(skinClusterFn, influenceIndexArray);

	unsigned numInf = influenceIndexArray.length();
	if (numInf == 0) continue;
	  
	unsigned numCV = 0;
	if (dagPath.node().hasFn(MFn::kMesh)) {
	    MItMeshVertex polyIter(dagPath, component, &status);
	    if (status == MS::kSuccess) {
		numCV = polyIter.count();
	    } 
	} else if (dagPath.node().hasFn(MFn::kNurbsSurface)) {
	    MItSurfaceCV nurbsIter(dagPath, component, true, &status);
	    if (status == MS::kSuccess) {
		while (!nurbsIter.isDone()) {
		    numCV++;
		    nurbsIter.next();
		}
	    }
	} else if (dagPath.node().hasFn(MFn::kNurbsCurve)) {
	    MItCurveCV curveIter(dagPath, component, &status);
	    if (status == MS::kSuccess) {
		while (!curveIter.isDone()) {
		    numCV++;
		    curveIter.next();
		}
	    }
	}
	unsigned numEntry = numCV * numInf;

	if (numEntry > 0) {
	    MDoubleArray weights(numEntry);
	    unsigned int numWeights = weightArray.length();
	    if (assignAllToSingle) {
		if (numInf <= numWeights) {
		    for (unsigned j = 0; j < numEntry; j++) {
			weights[j] = weightArray[j % numInf];
		    }
		} else {
		    MGlobal::displayError("Not enough weights specified\n");
		    return MS::kFailure;
		}
	    } else {
		for (unsigned j = 0; j < numEntry; j++, ptr++) {
		    if (ptr < numWeights) {
			weights[j] = weightArray[ptr];
		    } else {
			MGlobal::displayError("Not enough weights specified\n");
			return MS::kFailure;
		    }
		}
	    }

	    // support for undo
	    fDagPathArray[i] = dagPath;
	    fComponentArray[i] = component;
	    fInfluenceIndexArrayPtrArray[i] = influenceIndexArray;
	    MDoubleArray oldWeights;
	    skinClusterFn.getWeights(dagPath, component, influenceIndexArray, oldWeights);
	    fWeightsPtrArray[i] = oldWeights;
	    
	    skinClusterFn.setWeights(dagPath, component, influenceIndexArray, weights);
	}
    }
    return MS::kSuccess;
}
Пример #21
0
MStatus AbcExport::doIt(const MArgList & args)
{
try
{
    MStatus status;
    
    util::clearIsAnimatedCache();

    MTime oldCurTime = MAnimControl::currentTime();

    MArgParser argData(syntax(), args, &status);

    if (argData.isFlagSet("help"))
    {
        MGlobal::displayInfo(util::getHelpText());
        return MS::kSuccess;
    }

    bool verbose = argData.isFlagSet("verbose");

    // If skipFrame is true, when going through the playback range of the
    // scene, as much frames are skipped when possible.  This could cause
    // a problem for, time dependent solutions like
    // particle system / hair simulation
    bool skipFrame = true;
    if (argData.isFlagSet("dontSkipUnwrittenFrames"))
        skipFrame = false;

    double startEvaluationTime = DBL_MAX;
    if (argData.isFlagSet("preRollStartFrame"))
    {
        double startAt = 0.0;
        argData.getFlagArgument("preRollStartFrame", 0, startAt);
        startEvaluationTime = startAt;
    }

    unsigned int jobSize = argData.numberOfFlagUses("jobArg");

    if (jobSize == 0)
        return status;

    // the frame range we will be iterating over for all jobs,
    // includes frames which are not skipped and the startAt offset
    std::set<double> allFrameRange;

    // this will eventually hold only the animated jobs.
    // its a list because we will be removing jobs from it
    std::list < AbcWriteJobPtr > jobList;

    for (unsigned int jobIndex = 0; jobIndex < jobSize; jobIndex++)
    {
        JobArgs jobArgs;
        MArgList jobArgList;
        argData.getFlagArgumentList("jobArg", jobIndex, jobArgList);
        MString jobArgsStr = jobArgList.asString(0);
        MStringArray jobArgsArray;

        {
            // parse the job arguments
            // e.g. -perFrameCallbackMel "print \"something\"" will be splitted to
            //    [0] -perFrameCallbackMel
            //    [1] print "something"
            enum State {
                kArgument,               // parsing an argument (not quoted)
                kDoubleQuotedString,     // parsing a double quoted string
                kSingleQuotedString,     // parsing a single quoted string
            };

            State state = kArgument;
            MString stringBuffer;
            for (unsigned int charIdx = 0; charIdx < jobArgsStr.numChars();
                charIdx++)
            {
                MString ch = jobArgsStr.substringW(charIdx, charIdx);
                switch (state)
                {
                case kArgument:
                    if (ch == " ")
                    {
                        // space terminates the current argument
                        if (stringBuffer.length() > 0) {
                            jobArgsArray.append(stringBuffer);
                            stringBuffer.clear();
                        }
                        // goto another argument
                        state = kArgument;
                    }
                    else if (ch == "\"")
                    {
                        if (stringBuffer.length() > 0)
                        {
                            // double quote is part of the argument
                            stringBuffer += ch;
                        }
                        else
                        {
                            // goto double quoted string
                            state = kDoubleQuotedString;
                        }
                    }
                    else if (ch == "'")
                    {
                        if (stringBuffer.length() > 0)
                        {
                            // single quote is part of the argument
                            stringBuffer += ch;
                        }
                        else
                        {
                            // goto single quoted string
                            state = kSingleQuotedString;
                        }
                    }
                    else
                    {
                        stringBuffer += ch;
                    }
                break;

                case kDoubleQuotedString:
                    // double quote terminates the current string
                    if (ch == "\"")
                    {
                        jobArgsArray.append(stringBuffer);
                        stringBuffer.clear();
                        state = kArgument;
                    }
                    else if (ch == "\\")
                    {
                        // escaped character
                        MString nextCh = (++charIdx < jobArgsStr.numChars())
                            ? jobArgsStr.substringW(charIdx, charIdx) : "\\";
                        if (nextCh == "n")       stringBuffer += "\n";
                        else if (nextCh == "t")  stringBuffer += "\t";
                        else if (nextCh == "r")  stringBuffer += "\r";
                        else if (nextCh == "\\") stringBuffer += "\\";
                        else if (nextCh == "'")  stringBuffer += "'";
                        else if (nextCh == "\"") stringBuffer += "\"";
                        else                     stringBuffer += nextCh;
                    }
                    else
                    {
                        stringBuffer += ch;
                    }
                break;

                case kSingleQuotedString:
                    // single quote terminates the current string
                    if (ch == "'")
                    {
                        jobArgsArray.append(stringBuffer);
                        stringBuffer.clear();
                        state = kArgument;
                    }
                    else if (ch == "\\")
                    {
                        // escaped character
                        MString nextCh = (++charIdx < jobArgsStr.numChars())
                            ? jobArgsStr.substringW(charIdx, charIdx) : "\\";
                        if (nextCh == "n")       stringBuffer += "\n";
                        else if (nextCh == "t")  stringBuffer += "\t";
                        else if (nextCh == "r")  stringBuffer += "\r";
                        else if (nextCh == "\\") stringBuffer += "\\";
                        else if (nextCh == "'")  stringBuffer += "'";
                        else if (nextCh == "\"") stringBuffer += "\"";
                        else                     stringBuffer += nextCh;
                    }
                    else
                    {
                        stringBuffer += ch;
                    }
                break;
                }
            }

            // the rest of the argument
            if (stringBuffer.length() > 0)
            {
                jobArgsArray.append(stringBuffer);
            }
        }

        // the frame range within this job
        std::vector< FrameRangeArgs > frameRanges(1);
        frameRanges.back().startTime = oldCurTime.value();
        frameRanges.back().endTime = oldCurTime.value();
        frameRanges.back().strideTime = 1.0;

        bool hasRange = false;
        bool hasRoot = false;
        bool sampleGeo  = true; // whether or not to subsample geometry
        std::string fileName;
        bool asOgawa = true;

        unsigned int numJobArgs = jobArgsArray.length();
        for (unsigned int i = 0; i < numJobArgs; ++i)
        {
            MString arg = jobArgsArray[i];
            arg.toLowerCase();

            if (arg == "-f" || arg == "-file")
            {
                if (i+1 >= numJobArgs)
                {
                    MGlobal::displayError("File incorrectly specified.");
                    return MS::kFailure;
                }
                fileName = jobArgsArray[++i].asChar();
            }

            else if (arg == "-fr" || arg == "-framerange")
            {
                if (i+2 >= numJobArgs || !jobArgsArray[i+1].isDouble() ||
                    !jobArgsArray[i+2].isDouble())
                {
                    MGlobal::displayError("Frame Range incorrectly specified.");
                    return MS::kFailure;
                }

                // this is not the first -frameRange argument, we are going
                // to add one more frame range to the frame range array.
                if (hasRange)
                {
                    frameRanges.push_back(FrameRangeArgs());
                }

                hasRange = true;
                frameRanges.back().startTime = jobArgsArray[++i].asDouble();
                frameRanges.back().endTime = jobArgsArray[++i].asDouble();

                // make sure start frame is smaller or equal to endTime
                if (frameRanges.back().startTime > frameRanges.back().endTime)
                {
                    std::swap(frameRanges.back().startTime,
                        frameRanges.back().endTime);
                }
            }

            else if (arg == "-frs" || arg == "-framerelativesample")
            {
                if (i+1 >= numJobArgs || !jobArgsArray[i+1].isDouble())
                {
                    MGlobal::displayError(
                        "Frame Relative Sample incorrectly specified.");
                    return MS::kFailure;
                }
                frameRanges.back().shutterSamples.insert(
                    jobArgsArray[++i].asDouble());
            }

            else if (arg == "-nn" || arg == "-nonormals")
            {
                jobArgs.noNormals = true;
            }

            else if (arg == "-pr" || arg == "-preroll")
            {
                frameRanges.back().preRoll = true;
            }

            else if (arg == "-ro" || arg == "-renderableonly")
            {
                jobArgs.excludeInvisible = true;
            }

            else if (arg == "-s" || arg == "-step")
            {
                if (i+1 >= numJobArgs || !jobArgsArray[i+1].isDouble())
                {
                    MGlobal::displayError("Step incorrectly specified.");
                    return MS::kFailure;
                }
                frameRanges.back().strideTime = jobArgsArray[++i].asDouble();
            }

            else if (arg == "-sl" || arg == "-selection")
            {
                jobArgs.useSelectionList = true;
            }

            else if (arg == "-sn" || arg == "-stripnamespaces")
            {
                if (i+1 >= numJobArgs || !jobArgsArray[i+1].isUnsigned())
                {
                    // the strip all namespaces case
                    // so we pick a very LARGE number
                    jobArgs.stripNamespace = 0xffffffff;
                }
                else
                {
                    jobArgs.stripNamespace = jobArgsArray[++i].asUnsigned();
                }
            }

            else if (arg == "-uv" || arg == "-uvwrite")
            {
                jobArgs.writeUVs = true;
            }

            else if (arg == "-wcs" || arg == "-writecolorsets")
            {
                jobArgs.writeColorSets = true;
            }

            else if (arg == "-wfs" || arg == "-writefacesets")
            {
                jobArgs.writeFaceSets = true;
            }

            else if (arg == "-wfg" || arg == "-wholeframegeo")
            {
                sampleGeo = false;
            }

            else if (arg == "-ws" || arg == "-worldspace")
            {
                jobArgs.worldSpace = true;
            }

            else if (arg == "-wv" || arg == "-writevisibility")
            {
                jobArgs.writeVisibility = true;
            }

            else if (arg == "-wc" || arg == "-writecreases")
            {
                jobArgs.writeCreases = true;
            }

            else if (arg == "-mfc" || arg == "-melperframecallback")
            {
                if (i+1 >= numJobArgs)
                {
                    MGlobal::displayError(
                        "melPerFrameCallback incorrectly specified.");
                    return MS::kFailure;
                }
                jobArgs.melPerFrameCallback = jobArgsArray[++i].asChar();
            }

            else if (arg == "-pfc" || arg == "-pythonperframecallback")
            {
                if (i+1 >= numJobArgs)
                {
                    MGlobal::displayError(
                        "pythonPerFrameCallback incorrectly specified.");
                    return MS::kFailure;
                }
                jobArgs.pythonPerFrameCallback = jobArgsArray[++i].asChar();
            }

            else if (arg == "-mpc" || arg == "-melpostjobcallback")
            {
                if (i+1 >= numJobArgs)
                {
                    MGlobal::displayError(
                        "melPostJobCallback incorrectly specified.");
                    return MS::kFailure;
                }
                jobArgs.melPostCallback = jobArgsArray[++i].asChar();
            }

            else if (arg == "-ppc" || arg == "-pythonpostjobcallback")
            {
                if (i+1 >= numJobArgs)
                {
                    MGlobal::displayError(
                        "pythonPostJobCallback incorrectly specified.");
                    return MS::kFailure;
                }
                jobArgs.pythonPostCallback = jobArgsArray[++i].asChar();
            }

            // geomArbParams - attribute filtering stuff
            else if (arg == "-atp" || arg == "-attrprefix")
            {
                if (i+1 >= numJobArgs)
                {
                    MGlobal::displayError(
                        "attrPrefix incorrectly specified.");
                    return MS::kFailure;
                }
                jobArgs.prefixFilters.push_back(jobArgsArray[++i].asChar());
            }

            else if (arg == "-a" || arg == "-attr")
            {
                if (i+1 >= numJobArgs)
                {
                    MGlobal::displayError(
                        "attr incorrectly specified.");
                    return MS::kFailure;
                }
                jobArgs.attribs.insert(jobArgsArray[++i].asChar());
            }

            // userProperties - attribute filtering stuff
            else if (arg == "-uatp" || arg == "-userattrprefix")
            {
                if (i+1 >= numJobArgs)
                {
                    MGlobal::displayError(
                        "userAttrPrefix incorrectly specified.");
                    return MS::kFailure;
                }
                jobArgs.userPrefixFilters.push_back(jobArgsArray[++i].asChar());
            }

            else if (arg == "-u" || arg == "-userattr")
            {
                if (i+1 >= numJobArgs)
                {
                    MGlobal::displayError(
                        "userAttr incorrectly specified.");
                    return MS::kFailure;
                }
                jobArgs.userAttribs.insert(jobArgsArray[++i].asChar());
            }

            else if (arg == "-rt" || arg == "-root")
            {
                if (i+1 >= numJobArgs)
                {
                    MGlobal::displayError(
                        "root incorrectly specified.");
                    return MS::kFailure;
                }
                hasRoot = true;
                MString root = jobArgsArray[++i];

                MSelectionList sel;
                if (sel.add(root) != MS::kSuccess)
                {
                    MString warn = root;
                    warn += " could not be select, skipping.";
                    MGlobal::displayWarning(warn);
                    continue;
                }

                unsigned int numRoots = sel.length();
                for (unsigned int j = 0; j < numRoots; ++j)
                {
                    MDagPath path;
                    if (sel.getDagPath(j, path) != MS::kSuccess)
                    {
                        MString warn = path.fullPathName();
                        warn += " (part of ";
                        warn += root;
                        warn += " ) not a DAG Node, skipping.";
                        MGlobal::displayWarning(warn);
                        continue;
                    }
                    jobArgs.dagPaths.insert(path);
                }
            }
            else if (arg == "-ef" || arg == "-eulerfilter")
            {
                jobArgs.filterEulerRotations = true;
            }
            else if (arg == "-df" || arg == "-dataformat")
            {
                if (i+1 >= numJobArgs)
                {
                    MGlobal::displayError(
                        "dataFormat incorrectly specified.");
                    return MS::kFailure;
                }
                MString dataFormat = jobArgsArray[++i];
                dataFormat.toLowerCase();
                if (dataFormat == "hdf")
                {
                    asOgawa = false;
                }
                else if (dataFormat == "ogawa")
                {
                    asOgawa = true;
                }
            }
            else
            {
                MString warn = "Ignoring unsupported flag: ";
                warn += jobArgsArray[i];
                MGlobal::displayWarning(warn);
            }
        } //  for i

        if (fileName == "")
        {
            MString error = "-file not specified.";
            MGlobal::displayError(error);
            return MS::kFailure;
        }

        {
            MString fileRule, expandName;
            MString alembicFileRule = "alembicCache";
            MString alembicFilePath = "cache/alembic";

            MString queryFileRuleCmd;
            queryFileRuleCmd.format("workspace -q -fre \"^1s\"",
                alembicFileRule);

            MString queryFolderCmd;
            queryFolderCmd.format("workspace -en `workspace -q -fre \"^1s\"`",
                alembicFileRule);

            // query the file rule for alembic cache
            MGlobal::executeCommand(queryFileRuleCmd, fileRule);
            if (fileRule.length() > 0)
            {
                // we have alembic file rule, query the folder
                MGlobal::executeCommand(queryFolderCmd, expandName);
            }
            else
            {
                // alembic file rule does not exist, create it
                MString addFileRuleCmd;
                addFileRuleCmd.format("workspace -fr \"^1s\" \"^2s\"",
                    alembicFileRule, alembicFilePath);
                MGlobal::executeCommand(addFileRuleCmd);

                // save the workspace. maya may discard file rules on exit
                MGlobal::executeCommand("workspace -s");

                // query the folder
                MGlobal::executeCommand(queryFolderCmd, expandName);
            }

            // resolve the expanded file rule
            if (expandName.length() == 0)
            {
                expandName = alembicFilePath;
            }

            // get the path to the alembic file rule
            MFileObject directory;
            directory.setRawFullName(expandName);
            MString directoryName = directory.resolvedFullName();

            // make sure the cache folder exists
            if (!directory.exists())
            {
                // create the cache folder
                MString createFolderCmd;
                createFolderCmd.format("sysFile -md \"^1s\"", directoryName);
                MGlobal::executeCommand(createFolderCmd);
            }

            // resolve the relative path
            MFileObject absoluteFile;
            absoluteFile.setRawFullName(fileName.c_str());
#if MAYA_API_VERSION < 201300
            if (absoluteFile.resolvedFullName() !=
                absoluteFile.expandedFullName())
            {
#else
            if (!MFileObject::isAbsolutePath(fileName.c_str())) {
#endif
                // this is a relative path
                MString absoluteFileName = directoryName + "/" +
                    fileName.c_str();
                absoluteFile.setRawFullName(absoluteFileName);
                fileName = absoluteFile.resolvedFullName().asChar();
            }
            else
            {
                fileName = absoluteFile.resolvedFullName().asChar();
            }

            // check the path must exist before writing
            MFileObject absoluteFilePath;
            absoluteFilePath.setRawFullName(absoluteFile.path());
            if (!absoluteFilePath.exists()) {
                MString error;
                error.format("Path ^1s does not exist!", absoluteFilePath.resolvedFullName());
                MGlobal::displayError(error);
                return MS::kFailure;
            }

            // check the file is used by any AlembicNode in the scene
            MItDependencyNodes dgIter(MFn::kPluginDependNode);
            for (; !dgIter.isDone(); dgIter.next()) {
                MFnDependencyNode alembicNode(dgIter.thisNode());
                if (alembicNode.typeName() != "AlembicNode") {
                    continue;
                }

                MPlug abcFilePlug = alembicNode.findPlug("abc_File");
                if (abcFilePlug.isNull()) {
                    continue;
                }

                MFileObject alembicFile;
                alembicFile.setRawFullName(abcFilePlug.asString());
                if (!alembicFile.exists()) {
                    continue;
                }

                if (alembicFile.resolvedFullName() == absoluteFile.resolvedFullName()) {
                    MString error = "Can't export to an Alembic file which is in use.";
                    MGlobal::displayError(error);
                    return MS::kFailure;
                }
            }

            std::ofstream ofs(fileName.c_str());
            if (!ofs.is_open()) {
                MString error = MString("Can't write to file: ") + fileName.c_str();
                MGlobal::displayError(error);
                return MS::kFailure;
            }
            ofs.close();
        }

        // if -frameRelativeSample argument is not specified for a frame range,
        // we are assuming a -frameRelativeSample 0.0
        for (std::vector<FrameRangeArgs>::iterator range =
            frameRanges.begin(); range != frameRanges.end(); ++range)
        {
            if (range->shutterSamples.empty())
                range->shutterSamples.insert(0.0);
        }

        if (jobArgs.prefixFilters.empty())
        {
            jobArgs.prefixFilters.push_back("ABC_");
        }

        // the list of frame ranges for sampling
        std::vector<FrameRangeArgs> sampleRanges;
        std::vector<FrameRangeArgs> preRollRanges;
        for (std::vector<FrameRangeArgs>::const_iterator range =
            frameRanges.begin(); range != frameRanges.end(); ++range)
        {
            if (range->preRoll)
                preRollRanges.push_back(*range);
            else
                sampleRanges.push_back(*range);
        }

        // the list of frames written into the abc file
        std::set<double> geoSamples;
        std::set<double> transSamples;
        for (std::vector<FrameRangeArgs>::const_iterator range =
            sampleRanges.begin(); range != sampleRanges.end(); ++range)
        {
            for (double frame = range->startTime;
                frame <= range->endTime;
                frame += range->strideTime)
            {
                for (std::set<double>::const_iterator shutter =
                    range->shutterSamples.begin();
                    shutter != range->shutterSamples.end(); ++shutter)
                {
                    double curFrame = *shutter + frame;
                    if (!sampleGeo)
                    {
                        double intFrame = (double)(int)(
                            curFrame >= 0 ? curFrame + .5 : curFrame - .5);

                        // only insert samples that are close to being an integer
                        if (fabs(curFrame - intFrame) < 1e-4)
                        {
                            geoSamples.insert(curFrame);
                        }
                    }
                    else
                    {
                        geoSamples.insert(curFrame);
                    }
                    transSamples.insert(curFrame);
                }
            }

            if (geoSamples.empty())
            {
                geoSamples.insert(range->startTime);
            }

            if (transSamples.empty())
            {
                transSamples.insert(range->startTime);
            }
        }

        bool isAcyclic = false;
        if (sampleRanges.empty())
        {
            // no frame ranges or all frame ranges are pre-roll ranges
            hasRange = false;
            geoSamples.insert(frameRanges.back().startTime);
            transSamples.insert(frameRanges.back().startTime);
        }
        else
        {
            // check if the time range is even (cyclic)
            // otherwise, we will use acyclic
            // sub frames pattern
            std::vector<double> pattern(
                sampleRanges.begin()->shutterSamples.begin(),
                sampleRanges.begin()->shutterSamples.end());
            std::transform(pattern.begin(), pattern.end(), pattern.begin(),
                std::bind2nd(std::plus<double>(),
                    sampleRanges.begin()->startTime));

            // check the frames against the pattern
            std::vector<double> timeSamples(
                transSamples.begin(), transSamples.end());
            for (size_t i = 0; i < timeSamples.size(); i++)
            {
                // next pattern
                if (i % pattern.size() == 0 && i / pattern.size() > 0)
                {
                    std::transform(pattern.begin(), pattern.end(),
                        pattern.begin(), std::bind2nd(std::plus<double>(),
                            sampleRanges.begin()->strideTime));
                }

                // pattern mismatch, we use acyclic time sampling type
                if (timeSamples[i] != pattern[i % pattern.size()])
                {
                    isAcyclic = true;
                    break;
                }
            }
        }

        // the list of frames to pre-roll
        std::set<double> preRollSamples;
        for (std::vector<FrameRangeArgs>::const_iterator range =
            preRollRanges.begin(); range != preRollRanges.end(); ++range)
        {
            for (double frame = range->startTime;
                frame <= range->endTime;
                frame += range->strideTime)
            {
                for (std::set<double>::const_iterator shutter =
                    range->shutterSamples.begin();
                    shutter != range->shutterSamples.end(); ++shutter)
                {
                    double curFrame = *shutter + frame;
                    preRollSamples.insert(curFrame);
                }
            }

            if (preRollSamples.empty())
            {
                preRollSamples.insert(range->startTime);
            }
        }

        if (jobArgs.dagPaths.size() > 1)
        {
            // check for validity of the DagPath relationships complexity : n^2

            util::ShapeSet::const_iterator m, n;
            util::ShapeSet::const_iterator end = jobArgs.dagPaths.end();
            for (m = jobArgs.dagPaths.begin(); m != end; )
            {
                MDagPath path1 = *m;
                m++;
                for (n = m; n != end; n++)
                {
                    MDagPath path2 = *n;
                    if (util::isAncestorDescendentRelationship(path1,path2))
                    {
                        MString errorMsg = path1.fullPathName();
                        errorMsg += " and ";
                        errorMsg += path2.fullPathName();
                        errorMsg += " have an ancestor relationship.";
                        MGlobal::displayError(errorMsg);
                        return MS::kFailure;
                    }
                }  // for n
            }  // for m
        }
        // no root is specified, and we aren't using a selection
        // so we'll try to translate the whole Maya scene by using all
        // children of the world as roots.
        else if (!hasRoot && !jobArgs.useSelectionList)
        {
            MSelectionList sel;
#if MAYA_API_VERSION >= 201100
            sel.add("|*", true);
#else
            // older versions of Maya will not be able to find top level nodes
            // within namespaces
            sel.add("|*");
#endif
            unsigned int numRoots = sel.length();
            for (unsigned int i = 0; i < numRoots; ++i)
            {
                MDagPath path;
                sel.getDagPath(i, path);
                jobArgs.dagPaths.insert(path);
            }
        }
        else if (hasRoot && jobArgs.dagPaths.empty())
        {
            MString errorMsg = "No valid root nodes were specified.";
            MGlobal::displayError(errorMsg);
            return MS::kFailure;
        }
        else if (jobArgs.useSelectionList)
        {
            MSelectionList activeList;
            MGlobal::getActiveSelectionList(activeList);
            if (activeList.length() == 0)
            {
                MString errorMsg =
                    "-selection specified but nothing is actively selected.";
                MGlobal::displayError(errorMsg);
                return MS::kFailure;
            }
        }

        AbcA::TimeSamplingPtr transTime, geoTime;

        if (hasRange)
        {
            if (isAcyclic)
            {
                // acyclic, uneven time sampling
                // e.g. [0.8, 1, 1.2], [2.8, 3, 3.2], .. not continuous
                //      [0.8, 1, 1.2], [1.7, 2, 2.3], .. shutter different
                std::vector<double> samples(
                    transSamples.begin(), transSamples.end());
                std::transform(samples.begin(), samples.end(), samples.begin(),
                    std::bind2nd(std::multiplies<double>(), util::spf()));
                transTime.reset(new AbcA::TimeSampling(AbcA::TimeSamplingType(
                    AbcA::TimeSamplingType::kAcyclic), samples));
            }
            else
            {
                // cyclic, even time sampling between time periods
                // e.g. [0.8, 1, 1.2], [1.8, 2, 2.2], ...
                std::vector<double> samples;
                double startTime = sampleRanges[0].startTime;
                double strideTime = sampleRanges[0].strideTime;
                for (std::set<double>::const_iterator shutter =
                    sampleRanges[0].shutterSamples.begin();
                    shutter != sampleRanges[0].shutterSamples.end();
                    ++shutter)
                {
                    samples.push_back((startTime + *shutter) * util::spf());
                }

                if (samples.size() > 1)
                {
                    Alembic::Util::uint32_t numSamples =
                        static_cast<Alembic::Util::uint32_t>(samples.size());
                    transTime.reset(
                        new AbcA::TimeSampling(AbcA::TimeSamplingType(
                            numSamples, strideTime * util::spf()), samples));
                }
                // uniform sampling
                else
                {
                    transTime.reset(new AbcA::TimeSampling(
                        strideTime * util::spf(), samples[0]));
                }
            }
        }
        else
        {
            // time ranges are not specified
            transTime.reset(new AbcA::TimeSampling());
        }

        if (sampleGeo || !hasRange)
        {
            geoTime = transTime;
        }
        else
        {
            // sampling geo on whole frames
            if (isAcyclic)
            {
                // acyclic, uneven time sampling
                std::vector<double> samples(
                    geoSamples.begin(), geoSamples.end());
                // one more sample for setup()
                if (*transSamples.begin() != *geoSamples.begin())
                    samples.insert(samples.begin(), *transSamples.begin());
                std::transform(samples.begin(), samples.end(), samples.begin(),
                    std::bind2nd(std::multiplies<double>(), util::spf()));
                geoTime.reset(new AbcA::TimeSampling(AbcA::TimeSamplingType(
                    AbcA::TimeSamplingType::kAcyclic), samples));
            }
            else
            {
                double geoStride = sampleRanges[0].strideTime;
                if (geoStride < 1.0)
                    geoStride = 1.0;

                double geoStart = *geoSamples.begin() * util::spf();
                geoTime.reset(new AbcA::TimeSampling(
                    geoStride * util::spf(), geoStart));
            }
        }

        AbcWriteJobPtr job(new AbcWriteJob(fileName.c_str(), asOgawa,
            transSamples, transTime, geoSamples, geoTime, jobArgs));

       jobList.push_front(job);

        // make sure we add additional whole frames, if we arent skipping
        // the inbetween ones
        if (!skipFrame && !allFrameRange.empty())
        {
            double localMin = *(transSamples.begin());
            std::set<double>::iterator last = transSamples.end();
            last--;
            double localMax = *last;

            double globalMin = *(allFrameRange.begin());
            last = allFrameRange.end();
            last--;
            double globalMax = *last;

            // if the min of our current frame range is beyond
            // what we know about, pad a few more frames
            if (localMin > globalMax)
            {
                for (double f = globalMax; f < localMin; f++)
                {
                    allFrameRange.insert(f);
                }
            }

            // if the max of our current frame range is beyond
            // what we know about, pad a few more frames
            if (localMax < globalMin)
            {
                for (double f = localMax; f < globalMin; f++)
                {
                    allFrameRange.insert(f);
                }
            }
        }

        // right now we just copy over the translation samples since
        // they are guaranteed to contain all the geometry samples
        allFrameRange.insert(transSamples.begin(), transSamples.end());

        // copy over the pre-roll samples
        allFrameRange.insert(preRollSamples.begin(), preRollSamples.end());
    }

    // add extra evaluation run up, if necessary
    if (startEvaluationTime != DBL_MAX && !allFrameRange.empty())
    {
        double firstFrame = *allFrameRange.begin();
        for (double f = startEvaluationTime; f < firstFrame; ++f)
        {
            allFrameRange.insert(f);
        }
    }

    std::set<double>::iterator it = allFrameRange.begin();
    std::set<double>::iterator itEnd = allFrameRange.end();

    MComputation computation;
    computation.beginComputation();

    // loop through every frame in the list, if a job has that frame in it's
    // list of transform or shape frames, then it will write out data and
    // call the perFrameCallback, if that frame is also the last one it has
    // to work on then it will also call the postCallback.
    // If it doesn't have this frame, then it does nothing
    for (; it != itEnd; it++)
    {
        if (verbose)
        {
            double frame = *it;
            MString info;
            info = frame;
            MGlobal::displayInfo(info);
        }

        MGlobal::viewFrame(*it);
        std::list< AbcWriteJobPtr >::iterator j = jobList.begin();
        std::list< AbcWriteJobPtr >::iterator jend = jobList.end();
        while (j != jend)
        {
            if (computation.isInterruptRequested())
                return MS::kFailure;

            bool lastFrame = (*j)->eval(*it);

            if (lastFrame)
            {
                j = jobList.erase(j);
            }
            else
                j++;
        }
    }
    computation.endComputation();

    // set the time back
    MGlobal::viewFrame(oldCurTime);

    return MS::kSuccess;
}
catch (Alembic::Util::Exception & e)
{
    MString theError("Alembic Exception encountered: ");
    theError += e.what();
    MGlobal::displayError(theError);
    return MS::kFailure;
}
catch (std::exception & e)
{
    MString theError("std::exception encountered: ");
    theError += e.what();
    MGlobal::displayError(theError);
    return MS::kFailure;
}

}
Пример #22
0
// Load a joint
void skeleton::loadJoint(MDagPath& jointDag,joint* parent)
{
	int i;
	joint newJoint;
	joint* parentJoint = parent;
	if (jointDag.hasFn(MFn::kJoint))
	{
		MFnIkJoint jointFn(jointDag);

		// Get parent index
		int idx=-1;
		if (parent)
		{
			idx = parent->id;
		}
		// Get joint matrix
		MMatrix worldMatrix = jointDag.inclusiveMatrix();
		/*float translation1[3];
		float rotation1[4];
		float scale1[3];
		extractTranMatrix(worldMatrix,translation1,rotation1,scale1);
		Quaternion q(rotation1[0],rotation1[1],rotation1[2],rotation1[3]);
		float angle;
		Vector3 axis;
		q.ToAngleAxis(angle,axis);
		Vector3 x,y,z;
		q.ToAxes(x,y,z);*/
		//printMatrix(worldMatrix);
	
		// Calculate scaling factor inherited by parent
		// Calculate Local Matrix
		MMatrix localMatrix = worldMatrix;
		if (parent)
			localMatrix = worldMatrix * parent->worldMatrix.inverse();
		float translation2[3];
		float rotation2[4];
		float scale2[3];
		extractTranMatrix(worldMatrix,translation2,rotation2,scale2);
		//printMatrix(localMatrix);
	
		// Set joint info
		newJoint.name = jointFn.partialPathName();
		newJoint.id = m_joints.size();
		newJoint.parentIndex = idx;
		newJoint.jointDag = jointDag;
		newJoint.worldMatrix = worldMatrix;
		newJoint.localMatrix = localMatrix;

		for (int iRow = 0; iRow < 4; iRow++)
			for (int iCol = 0; iCol < 3; iCol++)
				newJoint.tran.m_mat[iRow][iCol] = (FLOAT)worldMatrix[iRow][iCol];

		//printMatrix(worldMatrix);

		/*MQuaternion q;
		q = worldMatrix;
		newJoint.tran.q[0] = (float)q.x;
		newJoint.tran.q[1] = (float)q.y;
		newJoint.tran.q[2] = (float)q.z;
		newJoint.tran.q[3] = (float)q.w;
		newJoint.tran.t[0] = (float)worldMatrix[3][0];
		newJoint.tran.t[1] = (float)worldMatrix[3][1];
		newJoint.tran.t[2] = (float)worldMatrix[3][2];*/

		MPlug plug = jointFn.findPlug("unRibbonEnabled");
		if(!plug.isNull())
		{
			bool enabled;
			plug.getValue(enabled);
			if(enabled)
			{
				plug = jointFn.findPlug("unRibbonVisible");
				bool visible;
				plug.getValue(visible);
				plug = jointFn.findPlug("unRibbonAbove");
				float above;
				plug.getValue(above);
				plug = jointFn.findPlug("unRibbonBelow");
				float below;
				plug.getValue(below);
				plug = jointFn.findPlug("unRibbonEdgesPerSecond");
				short edgePerSecond;
				plug.getValue(edgePerSecond);
				plug = jointFn.findPlug("unRibbonEdgeLife");
				float edgeLife;
				plug.getValue(edgeLife);
				plug = jointFn.findPlug("unRibbonGravity");
				float gravity;
				plug.getValue(gravity);
				plug = jointFn.findPlug("unRibbonTextureRows");
				short rows;
				plug.getValue(rows);
				plug = jointFn.findPlug("unRibbonTextureCols");
				short cols;
				plug.getValue(cols);
				plug = jointFn.findPlug("unRibbonTextureSlot");
				short slot;
				plug.getValue(slot);
				plug = jointFn.findPlug("unRibbonVertexColor");
				MObject object;
				plug.getValue(object);
				MFnNumericData data(object);
				float r,g,b;
				data.getData(r,g,b);
				plug = jointFn.findPlug("unRibbonVertexAlpha");
				float alpha;
				plug.getValue(alpha);
				plug = jointFn.findPlug("unRibbonBlendMode");
				short blendMode;
				plug.getValue(blendMode);
				plug = jointFn.findPlug("unRibbonTextureFilename");

				MItDependencyGraph dgIt(plug, MFn::kFileTexture,
					MItDependencyGraph::kUpstream, 
					MItDependencyGraph::kBreadthFirst,
					MItDependencyGraph::kNodeLevel);

				dgIt.disablePruningOnFilter();

				MString textureName;
				if (!dgIt.isDone())
				{
					MObject textureNode = dgIt.thisNode();
					MPlug filenamePlug = MFnDependencyNode(textureNode).findPlug("fileTextureName");
					filenamePlug.getValue(textureName);
				}
				else
				{
					char str[256];
					sprintf(str,"%s ribbon system must has file-texture",newJoint.name.asChar());
					MessageBox(0,str,0,0);
				}

				newJoint.hasRibbonSystem = true;
				newJoint.ribbon.visible = visible;
				newJoint.ribbon.above = above;
				newJoint.ribbon.below = below;
				newJoint.ribbon.gravity = gravity;
				newJoint.ribbon.edgePerSecond = edgePerSecond;
				newJoint.ribbon.edgeLife = edgeLife;
				newJoint.ribbon.rows = rows;
				newJoint.ribbon.cols = cols;
				newJoint.ribbon.slot = slot;
				newJoint.ribbon.color[0] = r;
				newJoint.ribbon.color[1] = g;
				newJoint.ribbon.color[2] = b;
				newJoint.ribbon.alpha = alpha;
				newJoint.ribbon.blendMode = blendMode;
				newJoint.ribbon.textureFilename = textureName.asChar();
			}
		}
		plug = jointFn.findPlug("unParticleEnabled");
		if(!plug.isNull())
		{
			bool enabled;
			plug.getValue(enabled);
			if(enabled)
			{
				newJoint.hasParticleSystem = true;

				plug = jointFn.findPlug("unParticleVisible");
				bool visible;
				plug.getValue(visible);
				plug = jointFn.findPlug("unParticleSpeed");
				float speed;
				plug.getValue(speed);
				plug = jointFn.findPlug("unParticleVariationPercent");
				float variation;
				plug.getValue(variation);
				plug = jointFn.findPlug("unParticleConeAngle");
				float coneAngle;
				plug.getValue(coneAngle);
				plug = jointFn.findPlug("unParticleGravity");
				float gravity;
				plug.getValue(gravity);
				plug = jointFn.findPlug("unParticleExplosiveForce");
				float explosiveForce = 0.0f;
				if(!plug.isNull())
				{
					plug.getValue(explosiveForce);
				}
				plug = jointFn.findPlug("unParticleLife");
				float life;
				plug.getValue(life);
				plug = jointFn.findPlug("unParticleLifeVariation");
				float lifeVar;
				if(plug.isNull())
				{
					lifeVar = 0.0f;
				}
				else
				{
					plug.getValue(lifeVar);
				}
				plug = jointFn.findPlug("unParticleEmissionRate");
				float emissionRate;
				plug.getValue(emissionRate);
				plug = jointFn.findPlug("unParticleLimitNum");
				short limitNum;
				plug.getValue(limitNum);
				plug = jointFn.findPlug("unParticleInitialNum");
				short initialNum = 0;
				if(!plug.isNull())plug.getValue(initialNum);
				plug = jointFn.findPlug("unParticleAttachToEmitter");
				bool attachToEmitter;
				plug.getValue(attachToEmitter);
				plug = jointFn.findPlug("unParticleMoveWithEmitter");
				bool moveWithEmitter = false;
				if(!plug.isNull())plug.getValue(moveWithEmitter);
				//23
				plug = jointFn.findPlug("unParticleForTheSword");
				bool forTheSword = false;
				if(!plug.isNull())plug.getValue(forTheSword);
				//24
				plug = jointFn.findPlug("unParticleForTheSwordInitialAngle");
				float forTheSwordInitialAngle = 0;
				if(!plug.isNull())plug.getValue(forTheSwordInitialAngle);
				//25
				plug = jointFn.findPlug("unParticleWander");
				bool wander = false;
				if(!plug.isNull())plug.getValue(wander);
				//25
				plug = jointFn.findPlug("unParticleWanderRadius");
				float wanderRadius = 0.0f;
				if(!plug.isNull())plug.getValue(wanderRadius);
				//25
				plug = jointFn.findPlug("unParticleWanderSpeed");
				float wanderSpeed = 0.0f;
				if(!plug.isNull())plug.getValue(wanderSpeed);
				plug = jointFn.findPlug("unParticleAspectRatio");
				float aspectRatio;
				if(plug.isNull())
				{
					aspectRatio = 1.0f;
				}
				else
				{
					plug.getValue(aspectRatio);
				}
				plug = jointFn.findPlug("unParticleInitialAngleBegin");
				float angleBegin;
				if(plug.isNull())
				{
					angleBegin = 0.0f;
				}
				else
				{
					plug.getValue(angleBegin);
				}
				plug = jointFn.findPlug("unParticleInitialAngleEnd");
				float angleEnd;
				if(plug.isNull())
				{
					angleEnd = 0.0f;
				}
				else
				{
					plug.getValue(angleEnd);
				}
				plug = jointFn.findPlug("unParticleRotationSpeed");
				float rotationSpeed;
				if(plug.isNull())
				{
					rotationSpeed = 0;
				}
				else
				{
					plug.getValue(rotationSpeed);
				}
				plug = jointFn.findPlug("unParticleRotationSpeedVar");
				float rotationSpeedVar;
				if(plug.isNull())
				{
					rotationSpeedVar = 0;
				}
				else
				{
					plug.getValue(rotationSpeedVar);
				}
				plug = jointFn.findPlug("unParticleEmitterWidth");
				float width;
				plug.getValue(width);
				plug = jointFn.findPlug("unParticleEmitterLength");
				float length;
				plug.getValue(length);
				plug = jointFn.findPlug("unParticleEmitterHeight");
				float height = 0.0f;
				if(!plug.isNull())
				{
					plug.getValue(height);
				}
				plug = jointFn.findPlug("unParticleBlendMode");
				short blendMode;
				plug.getValue(blendMode);
				plug = jointFn.findPlug("unParticleTextureFilename");

				MItDependencyGraph dgIt(plug, MFn::kFileTexture,
					MItDependencyGraph::kUpstream, 
					MItDependencyGraph::kBreadthFirst,
					MItDependencyGraph::kNodeLevel);

				dgIt.disablePruningOnFilter();

				MString textureName;
				if (!dgIt.isDone())
				{
					MObject textureNode = dgIt.thisNode();
					MPlug filenamePlug = MFnDependencyNode(textureNode).findPlug("fileTextureName");
					filenamePlug.getValue(textureName);
				}
				else
				{
					char str[256];
					sprintf(str,"%s particle system must has file-texture",newJoint.name.asChar());
					MessageBox(0,str,0,0);
				}
				plug = jointFn.findPlug("unParticleTextureRows");
				short rows;
				plug.getValue(rows);
				plug = jointFn.findPlug("unParticleTextureCols");
				short cols;
				plug.getValue(cols);
				plug = jointFn.findPlug("unParticleTextureChangeStyle");
				short changeStyle;
				if(plug.isNull())
				{
					//0 - 顺序
					//1 - 随机
					changeStyle = 0;
				}
				else
				{
					plug.getValue(changeStyle);
				}
				plug = jointFn.findPlug("unParticleTextureChangeInterval");
				short changeInterval;
				if(plug.isNull())
				{
					//默认30ms换一个
					changeInterval = 30;
				}
				else
				{
					plug.getValue(changeInterval);
				}
				plug = jointFn.findPlug("unParticleTailLength");
				float tailLength;
				plug.getValue(tailLength);
				plug = jointFn.findPlug("unParticleTimeMiddle");
				float timeMiddle;
				plug.getValue(timeMiddle);
				plug = jointFn.findPlug("unParticleColorStart");
				MObject object;
				plug.getValue(object);
				MFnNumericData dataS(object);
				float colorStart[3];
				dataS.getData(colorStart[0],colorStart[1],colorStart[2]);
				plug = jointFn.findPlug("unParticleColorMiddle");
				plug.getValue(object);
				MFnNumericData dataM(object);
				float colorMiddle[3];
				dataM.getData(colorMiddle[0],colorMiddle[1],colorMiddle[2]);
				plug = jointFn.findPlug("unParticleColorEnd");
				plug.getValue(object);
				MFnNumericData dataE(object);
				float colorEnd[3];
				dataE.getData(colorEnd[0],colorEnd[1],colorEnd[2]);
				plug = jointFn.findPlug("unParticleAlpha");
				plug.getValue(object);
				MFnNumericData dataAlpha(object);
				float alpha[3];
				dataAlpha.getData(alpha[0],alpha[1],alpha[2]);
				//Scale
				plug = jointFn.findPlug("unParticleScale");
				plug.getValue(object);
				MFnNumericData dataScale(object);
				float scale[3];
				dataScale.getData(scale[0],scale[1],scale[2]);
				//ScaleVar
				plug = jointFn.findPlug("unParticleScaleVar");
				float scaleVar[3] = {0.0f,0.0f,0.0f};
				if(!plug.isNull())
				{
					plug.getValue(object);
					MFnNumericData dataScaleVar(object);
					dataScaleVar.getData(scaleVar[0],scaleVar[1],scaleVar[2]);
				}
				//FixedSize
				plug = jointFn.findPlug("unParticleFixedSize");
				bool fixedSize = false;
				if(!plug.isNull())
				{
					plug.getValue(fixedSize);
				}
				//HeadLifeSpan
				plug = jointFn.findPlug("unParticleHeadLifeSpan");
				plug.getValue(object);
				MFnNumericData dataHeadLifeSpan(object);
				short headLifeSpan[3];
				dataHeadLifeSpan.getData(headLifeSpan[0],headLifeSpan[1],headLifeSpan[2]);
				plug = jointFn.findPlug("unParticleHeadDecay");
				plug.getValue(object);
				MFnNumericData dataHeadDecay(object);
				short headDecay[3];
				dataHeadDecay.getData(headDecay[0],headDecay[1],headDecay[2]);
				plug = jointFn.findPlug("unParticleTailLifeSpan");
				plug.getValue(object);
				MFnNumericData dataTailLifeSpan(object);
				short tailLifeSpan[3];
				dataTailLifeSpan.getData(tailLifeSpan[0],tailLifeSpan[1],tailLifeSpan[2]);
				plug = jointFn.findPlug("unParticleTailDecay");
				plug.getValue(object);
				MFnNumericData dataTailDecay(object);
				short tailDecay[3];
				dataTailDecay.getData(tailDecay[0],tailDecay[1],tailDecay[2]);
				plug = jointFn.findPlug("unParticleHead");
				bool head;
				plug.getValue(head);
				plug = jointFn.findPlug("unParticleTail");
				bool tail;
				plug.getValue(tail);
				plug = jointFn.findPlug("unParticleUnShaded");
				bool unshaded;
				plug.getValue(unshaded);
				plug = jointFn.findPlug("unParticleUnFogged");
				bool unfogged;
				plug.getValue(unfogged);
				plug = jointFn.findPlug("unParticleBlockByY0");
				bool blockByY0 = false;
				if(!plug.isNull())
					plug.getValue(blockByY0);

				newJoint.particle.visible = visible;
				newJoint.particle.speed = speed;
				newJoint.particle.variation = variation / 100.0f;
				newJoint.particle.coneAngle = coneAngle;
				newJoint.particle.gravity = gravity;
				newJoint.particle.explosiveForce = explosiveForce;
				newJoint.particle.life = life;
				newJoint.particle.lifeVar = lifeVar;
				newJoint.particle.emissionRate = emissionRate;
				newJoint.particle.initialNum = initialNum;
				newJoint.particle.limitNum = limitNum;
				newJoint.particle.attachToEmitter = attachToEmitter;
				newJoint.particle.moveWithEmitter = moveWithEmitter;
				newJoint.particle.forTheSword = forTheSword;
				newJoint.particle.forTheSwordInitialAngle = forTheSwordInitialAngle;
				newJoint.particle.wander = wander;
				newJoint.particle.wanderRadius = wanderRadius;
				newJoint.particle.wanderSpeed = wanderSpeed;
				newJoint.particle.aspectRatio = aspectRatio;
				newJoint.particle.initialAngleBegin = angleBegin;
				newJoint.particle.initialAngleEnd = angleEnd;
				newJoint.particle.rotationSpeed = rotationSpeed;
				newJoint.particle.rotationSpeedVar = rotationSpeedVar;
				newJoint.particle.width = width;
				newJoint.particle.length = length;
				newJoint.particle.height = height;
				newJoint.particle.blendMode = blendMode;
				newJoint.particle.textureFilename = textureName.asChar();
				newJoint.particle.textureRows = rows;
				newJoint.particle.textureCols = cols;
				newJoint.particle.changeStyle = changeStyle;
				newJoint.particle.changeInterval = changeInterval;
				newJoint.particle.tailLength = tailLength;
				newJoint.particle.timeMiddle = timeMiddle;
				newJoint.particle.colorStart[0] = colorStart[0];
				newJoint.particle.colorStart[1] = colorStart[1];
				newJoint.particle.colorStart[2] = colorStart[2];
				newJoint.particle.colorMiddle[0] = colorMiddle[0];
				newJoint.particle.colorMiddle[1] = colorMiddle[1];
				newJoint.particle.colorMiddle[2] = colorMiddle[2];
				newJoint.particle.colorEnd[0] = colorEnd[0];
				newJoint.particle.colorEnd[1] = colorEnd[1];
				newJoint.particle.colorEnd[2] = colorEnd[2];
				newJoint.particle.alpha[0] = alpha[0];
				newJoint.particle.alpha[1] = alpha[1];
				newJoint.particle.alpha[2] = alpha[2];
				newJoint.particle.scale[0] = scale[0];
				newJoint.particle.scale[1] = scale[1];
				newJoint.particle.scale[2] = scale[2];
				newJoint.particle.scaleVar[0] = scaleVar[0];
				newJoint.particle.scaleVar[1] = scaleVar[1];
				newJoint.particle.scaleVar[2] = scaleVar[2];
				newJoint.particle.fixedSize = fixedSize;
				newJoint.particle.headLifeSpan[0] = headLifeSpan[0];
				newJoint.particle.headLifeSpan[1] = headLifeSpan[1];
				newJoint.particle.headLifeSpan[2] = headLifeSpan[2];
				newJoint.particle.headDecay[0] = headDecay[0];
				newJoint.particle.headDecay[1] = headDecay[1];
				newJoint.particle.headDecay[2] = headDecay[2];
				newJoint.particle.tailLifeSpan[0] = tailLifeSpan[0];
				newJoint.particle.tailLifeSpan[1] = tailLifeSpan[1];
				newJoint.particle.tailLifeSpan[2] = tailLifeSpan[2];
				newJoint.particle.tailDecay[0] = tailDecay[0];
				newJoint.particle.tailDecay[1] = tailDecay[1];
				newJoint.particle.tailDecay[2] = tailDecay[2];
				newJoint.particle.head = head;
				newJoint.particle.tail = tail;
				newJoint.particle.unshaded = unshaded;
				newJoint.particle.unfogged = unfogged;
				newJoint.particle.blockByY0 = blockByY0;
			}
		}

		m_joints.push_back(newJoint);
		// Get pointer to newly created joint
		parentJoint = &newJoint;
	}
	// Load children joints
	for (i=0; i<jointDag.childCount();i++)
	{
		MObject child;
		child = jointDag.child(i);
		MDagPath childDag = jointDag;
		childDag.push(child);
		loadJoint(childDag,parentJoint);
	}

}
Пример #23
0
MStatus splineSolverNode::preSolve()
{

    MStatus stat;
    setRotatePlane(false);
    setSingleChainOnly(true);
    setPositionOnly(false);
    //Get Handle
    MIkHandleGroup * handle_group = handleGroup();
    if (NULL == handle_group) {
        return MS::kFailure;
    }
    MObject handle = handle_group->handle( 0 );
    MDagPath handlePath = MDagPath::getAPathTo( handle );
    fnHandle.setObject( handlePath );
    //Get Curve
    MPlug inCurvePlug = fnHandle.findPlug( "inCurve" );
    MDataHandle curveHandle = inCurvePlug.asMDataHandle();
    MObject inputCurveObject = curveHandle.asNurbsCurveTransformed();
    curveFn.setObject( inputCurveObject );
    float initCurveLength = curveFn.length();
    MVector initNormal = curveFn.normal(0);
    MVector initTangent = curveFn.tangent(0);
    float stretchRatio = 1;
    // Get the position of the end_effector
    //
    MDagPath effectorPath;
    fnHandle.getEffector(effectorPath);
    tran.setObject( effectorPath );
    // Get the start joint position
    //
    MDagPath startJointPath;
    fnHandle.getStartJoint( startJointPath );
    joints.clear();
    //Get Joints
    while (true)
    {
        effectorPath.pop();
        joints.push_back( effectorPath );
        if (effectorPath == startJointPath)
            break;
    }
    std::reverse(joints.begin(), joints.end());
    if (!fnHandle.hasAttribute("str"))
    {
        //Add Custom Attributes to Handle
        MFnNumericAttribute fnAttr;
        MObject attr = fnAttr.create("stretchRatio", "str", MFnNumericData::kDouble, stretchRatio);
        fnAttr.setKeyable(1);
        fnAttr.setWritable(1);
        fnAttr.setMin(0);
        fnAttr.setMax(1);
        fnAttr.setHidden(0);
        fnAttr.setStorable(1);
        fnAttr.setReadable(1);
        fnHandle.addAttribute(attr, MFnDependencyNode::kLocalDynamicAttr);
        attr = fnAttr.create("anchorPosition", "ancp", MFnNumericData::kDouble, 0.0);
        fnAttr.setKeyable(1);
        fnAttr.setWritable(1);
        fnAttr.setMin(0);
        fnAttr.setMax(1);
        fnAttr.setHidden(0);
        fnAttr.setStorable(1);
        fnAttr.setReadable(1);
        fnHandle.addAttribute(attr, MFnDependencyNode::kLocalDynamicAttr);
        attr = fnAttr.create("curveLength", "cvLen", MFnNumericData::kDouble, initCurveLength);
        fnAttr.setKeyable(0);
        fnAttr.setWritable(1);
        fnAttr.setHidden(1);
        fnAttr.setStorable(1);
        fnAttr.setReadable(1);
        fnHandle.addAttribute(attr, MFnDependencyNode::kLocalDynamicAttr);
        attr = fnAttr.create("initNormal", "norm", MFnNumericData::k3Double);
        fnAttr.setDefault(initNormal.x, initNormal.y, initNormal.z);
        fnAttr.setKeyable(0);
        fnAttr.setWritable(1);
        fnAttr.setHidden(1);
        fnAttr.setStorable(1);
        fnAttr.setReadable(1);
        fnHandle.addAttribute(attr, MFnDependencyNode::kLocalDynamicAttr);
        attr = fnAttr.create("initTangent", "tang", MFnNumericData::k3Double);
        fnAttr.setDefault(initTangent.x, initTangent.y, initTangent.z);
        fnAttr.setKeyable(0);
        fnAttr.setWritable(1);
        fnAttr.setHidden(1);
        fnAttr.setStorable(1);
        fnAttr.setReadable(1);
        fnHandle.addAttribute(attr, MFnDependencyNode::kLocalDynamicAttr);
        attr = fnAttr.create("jointsLength", "jsLen", MFnNumericData::kDouble, getJointsTotalLenght());
        fnAttr.setKeyable(0);
        fnAttr.setWritable(1);
        fnAttr.setHidden(1);
        fnAttr.setStorable(1);
        fnAttr.setReadable(1);
        fnHandle.addAttribute(attr, MFnDependencyNode::kLocalDynamicAttr);
        attr = fnAttr.create("startTwist", "strtw", MFnNumericData::kDouble, 0.0);
        fnAttr.setKeyable(1);
        fnAttr.setWritable(1);
        fnAttr.setHidden(0);
        fnAttr.setStorable(1);
        fnAttr.setReadable(1);
        fnHandle.addAttribute(attr, MFnDependencyNode::kLocalDynamicAttr);
        attr = fnAttr.create("endTwist", "endtw", MFnNumericData::kDouble, 0.0);
        fnAttr.setKeyable(1);
        fnAttr.setWritable(1);
        fnAttr.setHidden(0);
        fnAttr.setStorable(1);
        fnAttr.setReadable(1);
        fnHandle.addAttribute(attr, MFnDependencyNode::kLocalDynamicAttr);
        MObject twistRamp = MRampAttribute::createCurveRamp("twistRamp", "twr");
        fnHandle.addAttribute(twistRamp, MFnDependencyNode::kLocalDynamicAttr);
        MObject scaleRamp = MRampAttribute::createCurveRamp("scaleRamp", "scr");
        fnHandle.addAttribute(scaleRamp, MFnDependencyNode::kLocalDynamicAttr);
    } else
    {
        MPlug strPlug = fnHandle.findPlug("str");
        stretchRatio = strPlug.asDouble();
    }

    return MS::kSuccess;
}
Пример #24
0
MStatus unCreateParticleSystem::doIt( const MArgList& args )
{
	bool create = true;

	MSelectionList activeList;
	MStatus stat = MGlobal::getActiveSelectionList(activeList);
	if (MS::kSuccess != stat)
	{
		MessageBox(0,"please select one joint first!",0,0);
		return MS::kFailure;
	}

	if(activeList.length() != 1)
	{
		MessageBox(0,"please select ONLY one joint!",0,0);
		return MS::kFailure;
	}
	MItSelectionList iter(activeList);
	MDagPath dagPath;
	for ( ; !iter.isDone(); iter.next())
	{
		stat = iter.getDagPath(dagPath);
		break;
	}
	if(!stat)
	{
		MessageBox(0,"can't getDagPath!",0,0);
		return MS::kFailure;
	}

	if(!dagPath.hasFn(MFn::kJoint))
	{
		MessageBox(0,"muse select joint node!",0,0);
		return MS::kFailure;
	}

	MFnIkJoint joint(dagPath);

	if(args.length())
		create = args.asBool(0);

	if(!create)
	{
		if(!joint.hasAttribute("unParticleEnabled"))
		{
			MessageBox(0,"no particle system exists!",0,0);
			return MS::kFailure;
		}
		removeParticleAttributes(joint);
		return MS::kSuccess;
	}

	if(joint.hasAttribute("unParticleEnabled"))
	{
		MessageBox(0,"particle system already exists!",0,0);
		return MS::kSuccess;
	}

	if(joint.hasAttribute("unRibbonEnabled"))
	{
		if(MessageBox(0,"will delete ribbon system and attach a particle system to the joint,continue?",0,MB_YESNO) == IDNO)return MS::kFailure;
		removeRibbonAttributes(joint);
	}

	MFnNumericAttribute attr;
	unParticleEnabled = attr.create("unParticleEnabled","Enabled",MFnNumericData::kBoolean,true);
	attr.setStorable(true);

	unParticleVisible = attr.create("unParticleVisible","Visible",MFnNumericData::kBoolean,true);
	attr.setStorable(true);
	attr.setKeyable(true);

	unParticleSpeed = attr.create("unParticleSpeed","Speed",MFnNumericData::kFloat,40.0f);
	attr.setStorable(true);
	attr.setMin(-1000.0f);
	attr.setMax(1000.0f);
	attr.setKeyable(true);

	unParticleVariation = attr.create("unParticleVariationPercent","VariationPercent",MFnNumericData::kFloat,2.0f);
	attr.setStorable(true);
	attr.setMin(0.0f);
	attr.setMax(100.0f);
	attr.setKeyable(true);

	unParticleConeAngle = attr.create("unParticleConeAngle","ConeAngle",MFnNumericData::kFloat,0.0f);
	attr.setStorable(true);
	attr.setMin(0.0f);
	attr.setMax(180.0f);
	attr.setKeyable(true);

	unParticleGravity = attr.create("unParticleGravity","Gravity",MFnNumericData::kFloat,0.0f);
	attr.setStorable(true);
	attr.setMin(-1000.0f);
	attr.setMax(1000.0f);
	attr.setKeyable(true);

	unParticleExplosiveForce = attr.create("unParticleExplosiveForce","ExplosiveForce",MFnNumericData::kFloat,0.0f);
	attr.setStorable(true);
	attr.setMin(-100.0f);
	attr.setMax(100.0f);
	attr.setKeyable(true);

	unParticleLife = attr.create("unParticleLife","Life",MFnNumericData::kFloat,1.0f);
	attr.setStorable(true);
	attr.setMin(0.0f);
	attr.setMax(1000.0f);

	unParticleLifeVariation = attr.create("unParticleLifeVariation","LifeVar",MFnNumericData::kFloat,0.0f);
	attr.setStorable(true);
	attr.setMin(-16.0f);
	attr.setMax(16.0f);

	unParticleEmissionRate = attr.create("unParticleEmissionRate","EmissionRate",MFnNumericData::kFloat,50.0f);
	attr.setStorable(true);
	attr.setMin(0.0f);
	attr.setMax(1000.0f);
	attr.setKeyable(true);

	//版本号17加入,初始粒子数
	unParticleInitialNum = attr.create("unParticleInitialNum","InitialNum",MFnNumericData	::kShort,0);
	attr.setStorable(true);
	attr.setMin(0);
	attr.setMax(512);

	//版本号11加入,最大粒子数
	unParticleLimitNum = attr.create("unParticleLimitNum","LimitNum",MFnNumericData	::kShort,32);
	attr.setStorable(true);
	attr.setMin(1);
	attr.setMax(512);

	//版本号13加入,粒子全部跟随发射点
	unParticleAttachToEmitter = attr.create("unParticleAttachToEmitter","AttachToEmitter",MFnNumericData::kBoolean,false);
	attr.setStorable(true);

	//版本号18加入,粒子跟随发射点移动
	unParticleMoveWithEmitter = attr.create("unParticleMoveWithEmitter","MoveWithEmitter",MFnNumericData::kBoolean,false);
	attr.setStorable(true);

	//版本号23加入,粒子指向速度方向
	unParticleForTheSword = attr.create("unParticleForTheSword","ForTheSword",MFnNumericData::kBoolean,false);
	attr.setStorable(true);

	//版本号24加入,粒子指向速度方向,提供一个角度供初始化
	unParticleForTheSwordInitialAngle = attr.create("unParticleForTheSwordInitialAngle","ForTheSwordInitialAngle",MFnNumericData::kFloat,0);
	attr.setStorable(true);
	attr.setMin(-180.0f);
	attr.setMax(180.0f);

	//版本号25,Wander
	unParticleWander = attr.create("unParticleWander","Wander",MFnNumericData::kBoolean,false);
	attr.setStorable(true);
	//版本号25,WanderRadius
	unParticleWanderRadius = attr.create("unParticleWanderRadius","WanderRadius",MFnNumericData::kFloat,0.0f);
	attr.setStorable(true);
	attr.setMin(0.0f);
	attr.setMax(1024.0f);
	//版本号25,WanderSpeed
	unParticleWanderSpeed = attr.create("unParticleWanderSpeed","WanderSpeed",MFnNumericData::kFloat,0.0f);
	attr.setStorable(true);
	attr.setMin(0.0f);
	attr.setMax(16.0f);

	unParticleAspectRatio = attr.create("unParticleAspectRatio","AspectRatio",MFnNumericData::kFloat,1.0f);
	attr.setStorable(true);
	attr.setMin(0.0625f);
	attr.setMax(16.0f);

	unParticleInitialAngleBegin = attr.create("unParticleInitialAngleBegin","InitialAngleBegin",MFnNumericData::kFloat,0.0f);
	attr.setStorable(true);
	attr.setMin(-180.0f);
	attr.setMax(180.0f);

	unParticleInitialAngleEnd = attr.create("unParticleInitialAngleEnd","InitialAngleEnd",MFnNumericData::kFloat,0.0f);
	attr.setStorable(true);
	attr.setMin(-180.0f);
	attr.setMax(180.0f);

	unParticleRotationSpeed = attr.create("unParticleRotationSpeed","RotationSpeed",MFnNumericData::kFloat,0);
	attr.setStorable(true);
	attr.setMin(-64.0f);	//原来默认为16,鲍振伟要求改大
	attr.setMax(64.0f);

	unParticleRotationSpeedVar = attr.create("unParticleRotationSpeedVar","RotationSpeedVar",MFnNumericData::kFloat,0);
	attr.setStorable(true);
	attr.setMin(0);
	attr.setMax(64);

	unParticleEmitterWidth = attr.create("unParticleEmitterWidth","EmitterWidth",MFnNumericData::kFloat,0.0f);
	attr.setStorable(true);
	attr.setMin(0.0f);
	attr.setMax(1000.0f);
	attr.setKeyable(true);

	unParticleEmitterLength = attr.create("unParticleEmitterLength","EmitterLength",MFnNumericData::kFloat,0.0f);
	attr.setStorable(true);
	attr.setMin(0.0f);
	attr.setMax(1000.0f);
	attr.setKeyable(true);

	unParticleEmitterHeight = attr.create("unParticleEmitterHeight","EmitterHeight",MFnNumericData::kFloat,0.0f);
	attr.setStorable(true);
	attr.setMin(0.0f);
	attr.setMax(1000.0f);
	attr.setKeyable(true);

	MFnEnumAttribute eAttr;
	unParticleBlendMode = eAttr.create("unParticleBlendMode","BlendMode",3);
	eAttr.setStorable(true);
	eAttr.addField("Opaque",0);
	eAttr.addField("Transparent",1);
	eAttr.addField("AlphaBlend",2);
	eAttr.addField("Additive",3);
	eAttr.addField("AdditiveAlpha",4);
	eAttr.addField("Modulate",5);

	/*unParticleBlendModeSrc = eAttr.create("unParticleBlendModeSrc","BlendModeSrc",3);
	eAttr.setStorable(true);
	eAttr.addField("SBF_ONE",0);
	eAttr.addField("SBF_ZERO",1);
	eAttr.addField("SBF_DEST_COLOR",2);
	eAttr.addField("SBF_SOURCE_COLOR",3);
	eAttr.addField("SBF_ONE_MINUS_DEST_COLOR",4);
	eAttr.addField("SBF_ONE_MINUS_SOURCE_COLOR",5);
	eAttr.addField("SBF_DEST_ALPHA",6);
	eAttr.addField("SBF_SOURCE_ALPHA",7);
	eAttr.addField("SBF_ONE_MINUS_DEST_ALPHA",8);
	eAttr.addField("SBF_ONE_MINUS_SOURCE_ALPHA",9);

	unParticleBlendModeDst = eAttr.create("unParticleBlendModeDst","BlendModeDst",0);
	eAttr.setStorable(true);
	eAttr.addField("SBF_ONE",0);
	eAttr.addField("SBF_ZERO",1);
	eAttr.addField("SBF_DEST_COLOR",2);
	eAttr.addField("SBF_SOURCE_COLOR",3);
	eAttr.addField("SBF_ONE_MINUS_DEST_COLOR",4);
	eAttr.addField("SBF_ONE_MINUS_SOURCE_COLOR",5);
	eAttr.addField("SBF_DEST_ALPHA",6);
	eAttr.addField("SBF_SOURCE_ALPHA",7);
	eAttr.addField("SBF_ONE_MINUS_DEST_ALPHA",8);
	eAttr.addField("SBF_ONE_MINUS_SOURCE_ALPHA",9);*/

	unParticleTextureFilename = attr.createColor("unParticleTextureFilename","TextureFilename");
	attr.setStorable(true);

	unParticleTextureRows = attr.create("unParticleTextureRows","TextureRows",MFnNumericData::kShort,1);
	attr.setStorable(true);
	attr.setMin(1);
	attr.setMax(16);

	unParticleTextureCols = attr.create("unParticleTextureCols","TextureCols",MFnNumericData::kShort,1);
	attr.setStorable(true);
	attr.setMin(1);
	attr.setMax(16);

	unParticleTextureChangeStyle = eAttr.create("unParticleTextureChangeStyle","TextureChangeStyle",0);
	eAttr.setStorable(true);
	eAttr.addField("Sequence",0);
	eAttr.addField("Random",1);

	unParticleTextureChangeInterval = attr.create("unParticleTextureChangeInterval","TextureChangeInterval",MFnNumericData::kShort,30);
	attr.setStorable(true);
	attr.setMin(1);
	attr.setMax(5000);

	unParticleTailLength = attr.create("unParticleTailLength","TailLength",MFnNumericData::kFloat,1.0f);
	attr.setStorable(true);
	attr.setMin(0.0f);
	attr.setMax(10.0f);

	unParticleTimeMiddle = attr.create("unParticleTimeMiddle","TimeMiddle",MFnNumericData::kFloat,0.3f);
	attr.setStorable(true);
	attr.setMin(0.05f);
	attr.setMax(0.95f);

	unParticleColorStart = attr.createColor("unParticleColorStart","ColorStart");
	attr.setStorable(true);
	attr.setDefault(1.0f,1.0f,1.0f);

	unParticleColorMiddle = attr.createColor("unParticleColorMiddle","ColorMiddle");
	attr.setStorable(true);
	attr.setDefault(1.0f,1.0f,1.0f);

	unParticleColorEnd = attr.createColor("unParticleColorEnd","ColorEnd");
	attr.setStorable(true);
	attr.setDefault(1.0f,1.0f,1.0f);

	unParticleAlpha = attr.create("unParticleAlpha","Alpha",MFnNumericData::k3Float);
	attr.setStorable(true);
	attr.setDefault(1.0f,1.0f,0.0f);
	attr.setMin(0.0f,0.0f,0.0f);
	attr.setMax(1.0f,1.0f,1.0f);

	unParticleScale = attr.create("unParticleScale","Scale",MFnNumericData::k3Float);
	attr.setStorable(true);
	attr.setDefault(10.0f,10.0f,10.0f);
	attr.setMin(0.001f,0.001f,0.001f);
	attr.setMax(1500.0f,1500.0f,1500.0f);	//原来是500,鲍振伟要求改大

	unParticleScaleVar = attr.create("unParticleScaleVar","ScaleVar",MFnNumericData::k3Float);
	attr.setStorable(true);
	attr.setDefault(0.0f,0.0f,0.0f);
	attr.setMin(0.0f,0.0f,0.0f);
	attr.setMax(500.0f,500.0f,500.0f);//原来是100,鲍振伟要求改大

	unParticleFixedSize = attr.create("unParticleFixedSize","FixedSize",MFnNumericData::kBoolean,false);
	attr.setStorable(true);

	unParticleHeadLifeSpan = attr.create("unParticleHeadLifeSpan","HeadLifeSpan",MFnNumericData::k3Short);
	attr.setStorable(true);
	attr.setDefault(0,0,1);
	attr.setMin(0,0,1);
	attr.setMax(255,255,255);

	unParticleHeadDecay = attr.create("unParticleHeadDecay","HeadDecay",MFnNumericData::k3Short);
	attr.setStorable(true);
	attr.setDefault(0,0,1);
	attr.setMin(0,0,1);
	attr.setMax(255,255,255);

	unParticleTailLifeSpan = attr.create("unParticleTailLifeSpan","TailLifeSpan",MFnNumericData::k3Short);
	attr.setStorable(true);
	attr.setDefault(0,0,1);
	attr.setMin(0,0,1);
	attr.setMax(255,255,255);

	unParticleTailDecay = attr.create("unParticleTailDecay","TailDecay",MFnNumericData::k3Short);
	attr.setStorable(true);
	attr.setDefault(0,0,1);
	attr.setMin(0,0,1);
	attr.setMax(255,255,255);

	unParticleHead = attr.create("unParticleHead","Head",MFnNumericData::kBoolean,true);
	attr.setStorable(true);

	unParticleTail = attr.create("unParticleTail","Tail",MFnNumericData::kBoolean,false);
	attr.setStorable(true);

	unParticleUnShaded = attr.create("unParticleUnShaded","UnShaded",MFnNumericData::kBoolean,true);
	attr.setStorable(true);

	unParticleUnFogged = attr.create("unParticleUnFogged","UnFogged",MFnNumericData::kBoolean,true);
	attr.setStorable(true);

	unParticleBlockByY0 = attr.create("unParticleBlockByY0","blockByY0",MFnNumericData::kBoolean,false);
	attr.setStorable(true);

	addParticleAttributes(joint);

	return MS::kSuccess;
}
Пример #25
0
IECore::ObjectPtr FromMayaLocatorConverter::doConversion( const MDagPath &dagPath, IECore::ConstCompoundObjectPtr operands ) const
{
	MStatus st;

	bool hasLocator = dagPath.hasFn( MFn::kLocator, &st );
	if (!st || !hasLocator)
	{
		throw Exception( "Could not find locator!" );
	}

	MObject locatorObj = dagPath.node();
	if ( !locatorObj.hasFn( MFn::kLocator ) )
	{
		throw Exception( "Not a locator!" );
	}
	
	MFnDagNode fnLocator( locatorObj );

	CoordinateSystemPtr result = new CoordinateSystem;
	result->setName( IECore::convert<std::string>( fnLocator.name() ) );

	/// obtain local position and scale from locator
	Imath::V3f position(0), scale(0);

	MPlug positionPlug = fnLocator.findPlug( "localPositionX", &st );
	if ( !st )
		throw Exception("Could not find 'localPositionX' plug!");
	positionPlug.getValue(position[0]);

	positionPlug = fnLocator.findPlug( "localPositionY", &st );
	if ( !st )
		throw Exception("Could not find 'localPositionY' plug!");
	positionPlug.getValue(position[1]);

	positionPlug = fnLocator.findPlug( "localPositionZ", &st );
	if ( !st )
		throw Exception("Could not find 'localPositionZ' plug!");
	positionPlug.getValue(position[2]);

	MPlug scalePlug = fnLocator.findPlug( "localScaleX", &st );
	if ( !st )
		throw Exception("Could not find 'localScaleX' plug!");
	scalePlug.getValue(scale[0]);

	scalePlug = fnLocator.findPlug( "localScaleY", &st );
	if ( !st )
		throw Exception("Could not find 'localScaleY' plug!");
	scalePlug.getValue(scale[1]);

	scalePlug = fnLocator.findPlug( "localScaleZ", &st );
	if ( !st )
		throw Exception("Could not find 'localScaleZ' plug!");
	scalePlug.getValue(scale[2]);

	Imath::M44f scaleM,translateM;
	scaleM.scale(scale);
	translateM.translate(position);
	result->setTransform( new MatrixTransform( scaleM * translateM ) );

	return result;
}
Пример #26
0
MStatus unCreateRibbonSystem::doIt( const MArgList& args )
{
	bool create = true;

	MSelectionList activeList;
	MStatus stat = MGlobal::getActiveSelectionList(activeList);
	if (MS::kSuccess != stat)
	{
		MessageBox(0,"please select one joint first!",0,0);
		return MS::kFailure;
	}

	if(activeList.length() != 1)
	{
		MessageBox(0,"please select ONLY one joint!",0,0);
		return MS::kFailure;
	}
	MItSelectionList iter(activeList);
	MDagPath dagPath;
	for ( ; !iter.isDone(); iter.next())
	{
		stat = iter.getDagPath(dagPath);
		break;
	}
	if(!stat)
	{
		MessageBox(0,"can't getDagPath!",0,0);
		return MS::kFailure;
	}

	if(!dagPath.hasFn(MFn::kJoint))
	{
		MessageBox(0,"muse select joint node!",0,0);
		return MS::kFailure;
	}

	MFnIkJoint joint(dagPath);

	if(args.length())
		create = args.asBool(0);

	if(!create)
	{
		if(!joint.hasAttribute("unRibbonEnabled"))
		{
			MessageBox(0,"no ribbon system exists!",0,0);
			return MS::kFailure;
		}
		removeRibbonAttributes(joint);
		return MS::kSuccess;
	}

	if(joint.hasAttribute("unRibbonEnabled"))
	{
		MessageBox(0,"ribbon system already exists!",0,0);
		return MS::kSuccess;
	}

	if(joint.hasAttribute("unParticleEnabled"))
	{
		if(MessageBox(0,"will delete particle system and attach a ribbon system to the joint,continue?",0,MB_YESNO) == IDNO)return MS::kFailure;
		removeParticleAttributes(joint);
	}

	MFnNumericAttribute attr;
	unRibbonEnabled = attr.create("unRibbonEnabled","enabled",MFnNumericData::kBoolean,true);
	attr.setStorable(true);
	unRibbonVisible = attr.create("unRibbonVisible","visible",MFnNumericData::kBoolean,true);
	attr.setStorable(true);
	attr.setKeyable(true);
	unRibbonAbove = attr.create("unRibbonAbove","above",MFnNumericData::kFloat,20.0f);
	attr.setStorable(true);
	attr.setMin(0.0f);
	attr.setMax(5000.0f);
	attr.setKeyable(true);
	unRibbonBelow = attr.create("unRibbonBelow","below",MFnNumericData::kFloat,20.0f);
	attr.setStorable(true);
	attr.setMin(0.0f);
	attr.setMax(5000.0f);
	attr.setKeyable(true);
	unRibbonEdgesPerSecond = attr.create("unRibbonEdgesPerSecond","EdgePerSec",MFnNumericData::kShort,10);
	attr.setStorable(true);
	attr.setMin(0);
	attr.setMax(100);
	unRibbonEdgeLife = attr.create("unRibbonEdgeLife","EdgeLife",MFnNumericData::kFloat,2.0f);
	attr.setStorable(true);
	attr.setMin(0.001f);
	attr.setMax(100.0f);
	unRibbonGravity = attr.create("unRibbonGravity","Gravity",MFnNumericData::kFloat,0.0f);
	attr.setStorable(true);
	attr.setMin(-1000.0f);
	attr.setMax(1000.0f);
	unRibbonTextureRows = attr.create("unRibbonTextureRows","TextureRows",MFnNumericData::kShort,1);
	attr.setStorable(true);
	attr.setMin(1);
	attr.setMax(16);
	unRibbonTextureCols = attr.create("unRibbonTextureCols","TextureCols",MFnNumericData::kShort,1);
	attr.setStorable(true);
	attr.setMin(1);
	attr.setMax(16);
	unRibbonTextureSlot = attr.create("unRibbonTextureSlot","TextureSlot",MFnNumericData::kShort,0);
	attr.setStorable(true);
	attr.setMin(0);
	attr.setMax(255);
	attr.setKeyable(true);
	unRibbonVertexColor = attr.create("unRibbonVertexColor","VertexColor",MFnNumericData::k3Float);
	attr.setStorable(true);
	attr.setDefault(1.0f,0.0f,0.0f);
	attr.setUsedAsColor(true);
	attr.setKeyable(true);
	unRibbonVertexAlpha = attr.create("unRibbonVertexAlpha","VertexAlpha",MFnNumericData::kFloat,1.0f);
	attr.setStorable(true);
	attr.setMin(0.0f);
	attr.setMax(1.0f);
	attr.setKeyable(true);
	MFnEnumAttribute eAttr;
	unRibbonBlendMode = eAttr.create("unRibbonBlendMode","BlendMode",3);
	eAttr.setStorable(true);
	eAttr.addField("Opaque",0);
	eAttr.addField("Transparent",1);
	eAttr.addField("AlphaBlend",2);
	eAttr.addField("Additive",3);
	eAttr.addField("AdditiveAlpha",4);
	eAttr.addField("Modulate",5);
	{
		MFnEnumAttribute eAttr;
		unRibbonWanderMode = eAttr.create("unRibbonWanderMode","WanderMode",0);
		eAttr.setStorable(true);
		eAttr.addField("0",0);
		eAttr.addField("1",1);
	}
	/*unRibbonBlendModeSrc = eAttr.create("unRibbonBlendModeSrc","BlendModeSrc",3);
	eAttr.setStorable(true);
	eAttr.addField("SBF_ONE",0);
	eAttr.addField("SBF_ZERO",1);
	eAttr.addField("SBF_DEST_COLOR",2);
	eAttr.addField("SBF_SOURCE_COLOR",3);
	eAttr.addField("SBF_ONE_MINUS_DEST_COLOR",4);
	eAttr.addField("SBF_ONE_MINUS_SOURCE_COLOR",5);
	eAttr.addField("SBF_DEST_ALPHA",6);
	eAttr.addField("SBF_SOURCE_ALPHA",7);
	eAttr.addField("SBF_ONE_MINUS_DEST_ALPHA",8);
	eAttr.addField("SBF_ONE_MINUS_SOURCE_ALPHA",9);
	unRibbonBlendModeDst = eAttr.create("unRibbonBlendModeDst","BlendModeDst",0);
	eAttr.setStorable(true);
	eAttr.addField("SBF_ONE",0);
	eAttr.addField("SBF_ZERO",1);
	eAttr.addField("SBF_DEST_COLOR",2);
	eAttr.addField("SBF_SOURCE_COLOR",3);
	eAttr.addField("SBF_ONE_MINUS_DEST_COLOR",4);
	eAttr.addField("SBF_ONE_MINUS_SOURCE_COLOR",5);
	eAttr.addField("SBF_DEST_ALPHA",6);
	eAttr.addField("SBF_SOURCE_ALPHA",7);
	eAttr.addField("SBF_ONE_MINUS_DEST_ALPHA",8);
	eAttr.addField("SBF_ONE_MINUS_SOURCE_ALPHA",9);*/
	unRibbonTextureFilename = attr.createColor("unRibbonTextureFilename","TextureFilename");
	attr.setStorable(true);

	addRibbonAttributes(joint);

	return MS::kSuccess;
}
Пример #27
0
//
//	Check if the selected nodes exist in the scene->MayaObject lists. 
//
void mtco_MayaScene::mobjectListToMayaObjectList(std::vector<MObject>& mObjectList, std::vector<MayaObject *>& mtapObjectList)
{
	std::vector<MObject>::iterator moIter, moIterFound;
	std::vector<MayaObject *>::iterator mIter;
	std::vector<MObject> cleanMObjectList;
	std::vector<MObject> foundMObjectList;

	for( moIter = mObjectList.begin(); moIter != mObjectList.end(); moIter++)
	{
		bool found = false;
		MSelectionList select;
		MString objName = getObjectName(*moIter);
		logger.debug(MString("Object to modify:") + objName);
		select.add(objName);
		MDagPath dp;
		select.getDagPath(0, dp);
		//dp.extendToShape();
		MObject dagObj = dp.node();

		if( (*moIter).hasFn(MFn::kCamera))
		{
			for( mIter = this->camList.begin(); mIter != camList.end(); mIter++)
			{
				MayaObject *mo = *mIter;
				if( dagObj == mo->mobject)
				{
					mtapObjectList.push_back(mo);
					foundMObjectList.push_back(*moIter);
					found = true;
					break;
				}
			}		
			if( found )
				continue;
		}

		for( mIter = this->objectList.begin(); mIter != objectList.end(); mIter++)
		{
			MayaObject *mo = *mIter;
			if( dagObj == mo->mobject)
			{
				mtapObjectList.push_back(mo);
				foundMObjectList.push_back(*moIter);
				found = true;
				break;
			}
		}		
		if( found )
			continue;
		for( mIter = this->lightList.begin(); mIter != lightList.end(); mIter++)
		{
			MayaObject *mo = *mIter;
			if( dagObj == mo->mobject)
			{
				mtapObjectList.push_back(mo);
				foundMObjectList.push_back(*moIter);
				found = true;
				break;
			}
		}		
		if( found )
			continue;
	}

	for( moIter = mObjectList.begin(); moIter != mObjectList.end(); moIter++)
	{
		bool found = false;
		for( moIterFound = foundMObjectList.begin(); moIterFound != foundMObjectList.end(); moIterFound++)
		{
			if( *moIter == *moIterFound)
			{
				found = true;
				continue;
			}
		}
		if(!found)
			cleanMObjectList.push_back(*moIter);
	}

	mObjectList = cleanMObjectList;

}
Пример #28
0
ConstObjectPtr LiveScene::readAttribute( const Name &name, double time ) const
{
	if ( !m_isRoot && m_dagPath.length() == 0 )
	{
		throw Exception( "IECoreMaya::LiveScene::readAttribute: Dag path no longer exists!" );
	}
	
	tbb::mutex::scoped_lock l( s_mutex );
	if ( !m_isRoot )
	{

		if( name == SceneInterface::visibilityName )
		{
			bool visible = true;

			MStatus st;
			MFnDagNode dagFn( m_dagPath );
			MPlug visibilityPlug = dagFn.findPlug( MPxTransform::visibility, &st );
			if( st )
			{
				visible = visibilityPlug.asBool();
			}

			if( visible )
			{
				MDagPath childDag;

				// find an object that's either a SceneShape, or has a cortex converter and check its visibility:
				unsigned int childCount = 0;
				m_dagPath.numberOfShapesDirectlyBelow(childCount);

				for ( unsigned int c = 0; c < childCount; c++ )
				{
					MDagPath d = m_dagPath;
					if( d.extendToShapeDirectlyBelow( c ) )
					{
						MFnDagNode fnChildDag(d);
						if( fnChildDag.typeId() == SceneShape::id )
						{
							childDag = d;
							break;
						}

						if ( fnChildDag.isIntermediateObject() )
						{
							continue;
						}

						FromMayaShapeConverterPtr shapeConverter = FromMayaShapeConverter::create( d );
						if( shapeConverter )
						{
							childDag = d;
							break;
						}

						FromMayaDagNodeConverterPtr dagConverter = FromMayaDagNodeConverter::create( d );
						if( dagConverter )
						{
							childDag = d;
							break;
						}
					}
				}

				if( childDag.isValid() )
				{
					MFnDagNode dagFn( childDag );
					MPlug visibilityPlug = dagFn.findPlug( MPxSurfaceShape::visibility, &st );
					if( st )
					{
						visible = visibilityPlug.asBool();
					}
				}

			}

			return new BoolData( visible );
		}

	}
	else if( name == SceneInterface::visibilityName )
	{
		return new BoolData( true );
	}

	std::vector< CustomAttributeReader > &attributeReaders = customAttributeReaders();
	for ( std::vector< CustomAttributeReader >::const_reverse_iterator it = attributeReaders.rbegin(); it != attributeReaders.rend(); ++it )
	{
		ConstObjectPtr attr = it->m_read( m_dagPath, name );
		if( !attr )
		{
			continue;
		}
		return attr;
	}

	if( strstr( name.c_str(), "user:"******"ieAttr_" + name.string().substr(5) ).c_str(), false, &st );
		if( st )
		{
			FromMayaConverterPtr plugConverter = FromMayaPlugConverter::create( attrPlug );
			if( !plugConverter )
			{
				return IECore::NullObject::defaultNullObject();
			}
			return plugConverter->convert();
		}
	}

	return IECore::NullObject::defaultNullObject();
}
// Get shading engine
//
void CScriptedShapeTranslator::GetShapeInstanceShader(MDagPath& dagPath, MFnDependencyNode &shadingEngineNode)
{
   // Get instance shadingEngine
   shadingEngineNode.setObject(MObject::kNullObj);
   
   // First try the usual way
   MPlug shadingGroupPlug = GetNodeShadingGroup(dagPath.node(), (dagPath.isInstanced() ? dagPath.instanceNumber() : 0));
   if (!shadingGroupPlug.isNull())
   {
      shadingEngineNode.setObject(shadingGroupPlug.node());
      return;
   }
   
   char buffer[64];
   
   // Check connection from any shadingEngine on shape
   MStringArray connections;
   MGlobal::executeCommand("listConnections -s 1 -d 0 -c 1 -type shadingEngine "+dagPath.fullPathName(), connections);
   
   MSelectionList sl;
   
   if (connections.length() == 0)
   {
      // Check for direct surface shader connection
      MGlobal::executeCommand("listConnections -s 1 -d 0 -c 1 "+dagPath.fullPathName(), connections);
      
      for (unsigned int cidx=0; cidx<connections.length(); cidx+=2)
      {
         MString srcNode = connections[cidx+1];
         // Get node classification, if can find arnold/shader/surface -> got it
         MStringArray rv;
         MGlobal::executeCommand("getClassification `nodeType "+srcNode+"`", rv);
         if (rv.length() > 0 && rv[0].indexW("arnold/shader/surface") != -1)
         {
            connections.clear();
            
            MGlobal::executeCommand("listConnections -s 0 -d 1 -c 1 -type shadingEngine "+srcNode, connections);
            
            if (connections.length() == 2)
            {
               sl.add(connections[1]);
            }
            
            break;
         }
      }
   }
   else if (connections.length() == 2)
   {
      // Single connection, use same shader for all instances
      sl.add(connections[1]);
   }
   else if (connections.length() > 2)
   {
      // Many connections, expects the destination plug in shape to be an array
      // Use instance number as logical index, if this fails, use first shadingEngine in list
      
      bool found = false;
      
      sprintf(buffer, "[%d]", dagPath.instanceNumber());
      MString iidx = buffer;
      
      for (unsigned int cidx = 0; cidx < connections.length(); cidx += 2)
      {
         MString conn = connections[cidx];
         
         if (conn.length() < iidx.length())
         {
            continue;
         }
         
         if (conn.substring(conn.length() - iidx.length(), conn.length() - 1) != iidx)
         {
            continue;
         }
         
         sl.add(connections[cidx+1]);
         
         found = true;
         
         break;
      }
      
      if (!found)
      {
         MGlobal::displayWarning("[mtoaScriptedTranslators] Instance shader plug not found, use first found shadingEngine \"" + connections[1] + "\"");
         sl.add(connections[1]);
      }
   }
   
   if (sl.length() == 1)
   {
      MObject shadingEngineObj;
      
      if (sl.getDependNode(0, shadingEngineObj) == MS::kSuccess && shadingEngineObj.apiType() == MFn::kShadingEngine)
      {
         shadingEngineNode.setObject(shadingEngineObj);
      }
      else
      {
         if (shadingEngineObj != MObject::kNullObj)
         {
            MFnDependencyNode dn(shadingEngineObj);
            MGlobal::displayWarning("[mtoaScriptedTranslators] Not a shading engine \"" + dn.name() + "\"");
         }
      }
   }
}
MStatus meshInfo5::doIt( const MArgList& args )
{
	MStatus stat = MS::kSuccess;

	MSelectionList selection;
	MGlobal::getActiveSelectionList( selection );

	MDagPath dagPath;
	MObject component;
	
	unsigned int i, nVerts;
	int fIndex, vIndex, fvIndex;
	MVector fNormal, vNormal, fvNormal;
	
	MString txt;
	MItSelectionList iter( selection );
	for ( ; !iter.isDone(); iter.next() )
	{								
		iter.getDagPath( dagPath, component );
		
		MFnMesh meshFn( dagPath );
		
		// This handles whole mesh selections and mesh-face component selections
		MItMeshPolygon faceIter( dagPath, component, &stat );
		if( stat == MS::kSuccess )
		{
			txt += MString( "Object: " ) + dagPath.fullPathName() + "\n";	
									
			for( ; !faceIter.isDone(); faceIter.next() )
			{
				nVerts = faceIter.polygonVertexCount();
				
				for( i=0; i < nVerts; i++ )
				{
					fvIndex = i;
					fIndex = faceIter.index();
					vIndex = faceIter.vertexIndex( i );
					
					faceIter.getNormal( fNormal );
					meshFn.getVertexNormal( vIndex, vNormal );					
					faceIter.getNormal( fvIndex, fvNormal );

					addData( txt, fIndex, vIndex, fvIndex, fNormal, vNormal, fvNormal );
				}
			}
		} 
		else
		{
			// This handles mesh-vertex component selections
			MItMeshVertex vertIter( dagPath, component, &stat );
			if( stat == MS::kSuccess )
			{
				txt += MString( "Object: " ) + dagPath.fullPathName() + "\n";	

				MIntArray faceIds;
				MIntArray vertIds;
						
				for( ; !vertIter.isDone(); vertIter.next() )
				{
					vIndex = vertIter.index();
					
					vertIter.getNormal( vNormal );
					vertIter.getConnectedFaces( faceIds );
					
					for( i=0; i < faceIds.length(); i++ )
					{
						fIndex = faceIds[i];
						
						meshFn.getPolygonNormal( fIndex, fNormal );
						meshFn.getFaceVertexNormal( fIndex, vIndex, fvNormal );
						meshFn.getPolygonVertices( fIndex, vertIds );
												
						for( fvIndex=0; fvIndex < int(vertIds.length()); fvIndex++ )
						{
							if( vertIds[fvIndex] == vIndex )
								break;
						}
						
						addData( txt, fIndex, vIndex, fvIndex, fNormal, vNormal, fvNormal ); 
					}
				}
			}
		}
	}
	
	MGlobal::displayInfo( txt );

	return MS::kSuccess;
}