コード例 #1
0
//-----------------------------------------------------------------------------
// Get the starting list of objects to export
//-----------------------------------------------------------------------------
MStatus CVstSmdIOCmd::GetOptSelection(
	const MArgDatabase &mArgDatabase,
	MSelectionList &mSelectionList )
{
	if ( mArgDatabase.isFlagSet( kOptSelection ) )
	{
		// Get the user's specified selection of stuff to export
		if ( !mArgDatabase.getObjects( mSelectionList ) )
		{
			MGlobal::displayError( "Cannot get list of specified objects to export" );
			return MS::kFailure;
		}
		else if ( mSelectionList.isEmpty() )
		{
			MGlobal::displayError( "-export -selection specified but nothing is selected" );
			return MS::kFailure;
		}
	}
	else
	{
		MDagPath mDagPath;
		const bool exportInvisible( mArgDatabase.isFlagSet( kOptExportInvisible ) );

		for ( MItDag dagIt( MItDag::kBreadthFirst, MFn::kDagNode ); !dagIt.isDone() && dagIt.depth() <= 1; dagIt.next() )
		{
			if ( dagIt.depth() == 1)
			{
				if ( dagIt.getPath( mDagPath ) )
				{
					if ( exportInvisible || ValveMaya::IsPathVisible( mDagPath ) )
					{
						mSelectionList.add( mDagPath, MObject::kNullObj, true );
					}
				}
			}
		}
	}

	if ( mSelectionList.isEmpty() )
	{
		MGlobal::displayError( "Cannot find anything to export" );
		return MS::kFailure;
	}

	return MS::kSuccess;
}
コード例 #2
0
MStatus animExport::exportSelected(	ofstream &animFile, 
									MString &copyFlags,
									bool nodeNames /* false */,
									bool verboseUnits /* false */)
{
	MStatus status = MS::kFailure;

	//	If the selection list is empty, then there are no anim curves
	//	to export.
	//
	MSelectionList sList;
	MGlobal::getActiveSelectionList(sList);
	if (sList.isEmpty()) {
		MString msg = MStringResource::getString(kNothingSelected, status);
		MGlobal::displayError(msg);
		return (MS::kFailure);
	}

	//	Copy any anim curves to the API clipboard.
	//
	int result = 0;
	MString command(copyFlags);

	if (MS::kSuccess != (status = 
		MGlobal::executeCommand(command, result, false, true))) {
		MStatus stringStat;
		MString msg = MStringResource::getString(kAnimCurveNotFound, stringStat);
		MGlobal::displayError(msg);
		return status;
			}

	if (result == 0 || MAnimCurveClipboard::theAPIClipboard().isEmpty()) {
		MString msg = MStringResource::getString(kAnimCurveNotFound, status);
		MGlobal::displayError(msg);
		return (MS::kFailure);
	}

	if (MS::kSuccess != (	status = 
							fWriter.writeClipboard(animFile, 
							MAnimCurveClipboard::theAPIClipboard(),
							nodeNames, verboseUnits))) {
		return (MS::kFailure);
	}

	return status;
}
コード例 #3
0
MStatus 
animImport::importAnim(ifstream &animFile, const MString &pasteFlags)
{
	MStatus status = MS::kFailure;
	MAnimCurveClipboard::theAPIClipboard().clear();

	//	If the selection list is empty, there is nothing to import.
	//
	MSelectionList sList;
	MGlobal::getActiveSelectionList(sList);
	if (sList.isEmpty()) {
		MString msg = MStringResource::getString(kNothingSelected, status);
		MGlobal::displayError(msg);
		return (MS::kFailure);
	}

	if (MS::kSuccess != 
			(status = fReader.readClipboard(animFile, 
			MAnimCurveClipboard::theAPIClipboard()))) {

		return status;
	}

	if (MAnimCurveClipboard::theAPIClipboard().isEmpty()) {
		return (MS::kFailure);
	}

		MString command("pasteKey -cb api ");
		command += pasteFlags;

		int result;
		if (MS::kSuccess != (status =  
			MGlobal::executeCommand(command, result, false, true))) {
			MString msg = MStringResource::getString(kPasteFailed, status);
			MGlobal::displayError(msg);
			return status;
		}

	return status;
}
コード例 #4
0
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CVstSelectCoincidentFacesCmd::GetSpecifiedMeshes(
	MSelectionList &meshList )
{
	meshList.clear();

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

	MDagPath mDagPath;
	MObject cObj;
	for ( MItSelectionList sIt( optSelectionList ); !sIt.isDone(); sIt.next() )
	{
		if ( sIt.itemType() == MItSelectionList::kDagSelectionItem && sIt.getDagPath( mDagPath, cObj ) )
		{
			if ( mDagPath.hasFn( MFn::kMesh ) )
			{
				if ( sIt.hasComponents() || !cObj.isNull() )
				{
					meshList.add( mDagPath, cObj );
				}
				else
				{
					mDagPath.extendToShapeDirectlyBelow( 0U );
					meshList.add( mDagPath, MObject::kNullObj, true );
				}
			}
		}
	}

	if ( meshList.isEmpty() )
	{
		for ( MItDag dIt( MItDag::kDepthFirst, MFn::kMesh ); !dIt.isDone(); dIt.next() )
		{
			if ( dIt.getPath( mDagPath ) )
			{
				meshList.add( mDagPath, MObject::kNullObj, true );
			}
		}
	}
}
コード例 #5
0
MStatus atomExport::exportSelected(	ofstream &animFile, 
									MString &copyFlags,
									std::set<std::string> &attrStrings,
									bool includeChildren, 
									bool useSpecifiedTimes, 
									MTime &startTime,
									MTime &endTime,
									bool statics,
									bool cached,
									bool sdk,
									bool constraint,
									bool layers,
									const MString& exportEditsFile,
									atomTemplateReader &templateReader)
{
	MStatus status = MS::kFailure;

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


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


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


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

	unsigned int numObjects = sList.length();

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

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

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

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

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

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

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

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

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

			fWriter.writeNodeStart(animFile,nodeType,name);

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


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

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

	if(hasActiveProgress)
		MProgressWindow::endProgress();

	if(haveAnyAnimatableStuff == false)
	{
		MString msg = MStringResource::getString(kAnimCurveNotFound, status);
		MGlobal::displayError(msg);
		return (MS::kFailure);
	}
	else return (MS::kSuccess);
}	
コード例 #6
0
MStatus atomImport::reader(	const MFileObject& file,
								const MString& options,
								FileAccessMode mode)
{
	MStatus status = MS::kFailure;

	MString fileName = file.fullName();
#if defined (OSMac_)	
	char fname[MAXPATHLEN];
	strcpy (fname, fileName.asChar());
	ifstream animFile(fname);
#else
	ifstream animFile(fileName.asChar());
#endif
	// 	Parse the options. The options syntax is in the form of
	//	"flag=val;flag1=val;flag2=val"
	//

	if(animFile.good()==false)
		return status;
	MString pasteFlags;
	MString	prefix;
	MString	suffix;
	MString	search;
	MString	replace;
	MString	mapFile;
	bool replaceLayers = false;
	MString	exportEditsFile;	
	bool includeChildren = false;
	atomNodeNameReplacer::ReplaceType type = atomNodeNameReplacer::eHierarchy;
	MString templateName;
	MString viewName;
	bool useTemplate = false;

	if (options.length() > 0) {
		//	Set up the flags for the paste command.
		//
		const MString flagSrcTime("srcTime");
		const MString flagDstTime("dstTime");
		const MString flagOldDstTime("time");
		const MString flagCopies("copies");
		const MString flagOption("option");
		const MString flagConnect("connect");
		const MString flagMatch("match");
		const MString flagSearch("search");
		const MString flagReplace("replace");
		const MString flagPrefix("prefix");
		const MString flagSuffix("suffix");
		const MString flagMapFile("mapFile");
		const MString flagHierarchy("hierarchy");
		const MString flagString("string");
		const MString flagSelected("selected");
		const MString flagTemplate("template");
		const MString flagView("view");
		const MString optionChildrenToo("childrenToo");
		const MString optionTemplate("template");
		const MString flagExportEdits("exportEdits");
		MString copyValue;
		MString flagValue;
		MString connectValue;
		MString match;
		MString srcTimeValue;
		MString dstTimeValue;

		//	Start parsing.
		//
		MStringArray optionList;
		MStringArray theOption;
		options.split(';', optionList);

		unsigned nOptions = optionList.length();
		for (unsigned i = 0; i < nOptions; i++) {

			theOption.clear();
			optionList[i].split('=', theOption);
			if (theOption.length() < 1) {
				continue;
			}

			if (theOption[0] == flagCopies && theOption.length() > 1) {
				copyValue = theOption[1];;
			} else if (theOption[0] == flagOption && theOption.length() > 1) {
				flagValue = theOption[1];
			} else if (theOption[0] == flagConnect && theOption.length() > 1) {
				if (theOption[1].asInt() != 0) {
					connectValue += theOption[1];
				}
			} 
			else if( theOption[0] == flagTemplate && theOption.length() > 1)
			{
				templateName = theOption[1];
			}
			else if( theOption[0] == flagView && theOption.length() > 1)
			{
				viewName = theOption[1];
			}
			else if (theOption[0] == flagSrcTime && theOption.length() > 1) {
				srcTimeValue += theOption[1];
			}
			else if ((theOption[0] == flagDstTime || theOption[0] == flagOldDstTime )&& theOption.length() > 1) {
				dstTimeValue += theOption[1];
			}
			else if (theOption[0] == flagMatch && theOption.length() > 1) {
				match =  theOption[1];
			} 
			else if (theOption[0] == flagSearch && theOption.length() > 1) {
				search =  theOption[1];
			} 
			else if (theOption[0] == flagReplace && theOption.length() > 1) {
				replace =  theOption[1];
			} 
			else if (theOption[0] == flagPrefix && theOption.length() > 1) {
				prefix =  theOption[1];
			} 
			else if (theOption[0] == flagSuffix && theOption.length() > 1) {
				suffix =  theOption[1];
			} 
			else if (theOption[0] == flagMapFile && theOption.length() > 1) {
				mapFile =  theOption[1];
			}
			else if (theOption[0] == flagSelected && theOption.length() > 1) {
				includeChildren =   (theOption[1] == optionChildrenToo) ? true : false;
				if(theOption[1] == optionTemplate)
					useTemplate = true;
			}
			else if (theOption[0] == flagExportEdits && theOption.length() > 1) {
				exportEditsFile =  theOption[1];
			}
		}
	
		if (copyValue.length() > 0) {
			pasteFlags += " -copies ";
			pasteFlags += copyValue;
			pasteFlags += " ";
		} 
		if (flagValue.length() > 0) {
			pasteFlags += " -option \"";
			pasteFlags += flagValue;
			pasteFlags += "\" ";
			if(flagValue == MString("replace"))
				replaceLayers = true;
		} 
		if (connectValue.length() > 0) {
			pasteFlags += " -connect ";
			pasteFlags += connectValue;
			pasteFlags += " ";
		} 
		if (dstTimeValue.length() > 0) {
			bool useQuotes = !dstTimeValue.isDouble();
			pasteFlags += " -time ";
			if (useQuotes) pasteFlags += "\"";
			pasteFlags +=  dstTimeValue;
			if (useQuotes) pasteFlags += "\"";
			pasteFlags += " ";
		} 		
		if (srcTimeValue.length() > 0) 
		{
			MTime lClipStartTime;
			MTime lClipEndTime;
			MStringArray lTimes;

			if ( MStatus::kSuccess == srcTimeValue.split( L':', lTimes ) )
			{
				if ( lTimes.length() > 0 )
				{
					double lImportStartFrame = lTimes[0].asDouble();
					double lImportEndFrame   = lImportStartFrame;
					
					if ( lTimes.length() > 1 )
					{
						lImportEndFrame = lTimes[1].asDouble();
					}
					fReader.setImportFrameRange( lImportStartFrame, lImportEndFrame );
				}
				else
				{
					fReader.clearImportFrameRange();
				}
			}
		} 
        else
        {
            fReader.clearImportFrameRange();
        }
		if(match.length() >0)
		{
			if(match == flagHierarchy)
				type = atomNodeNameReplacer::eHierarchy;
			else if(match == flagString)
				type = atomNodeNameReplacer::eSearchReplace;
			else if(match == flagMapFile)
				type = atomNodeNameReplacer::eMapFile;
		} //not set, then we leave what we had

		
	}

	//	If the selection list is empty, there is nothing to import.
	//
	MSelectionList sList;
	std::vector<unsigned int> depths;
	atomTemplateReader templateReader;
	if(useTemplate == true)
	{
		templateReader.setTemplate(templateName,viewName);
		includeChildren = false;
		templateReader.selectNodes(); //make the selection set be us.
	}
	SelectionGetter::getSelectedObjects(includeChildren,sList,depths);
	if (sList.isEmpty()) {
		MString msg = MStringResource::getString(kNothingSelected, status);
		MGlobal::displayError(msg);
		return (MS::kFailure);
	}


	atomNodeNameReplacer replacer(type,sList,depths,prefix,suffix,search,replace,mapFile);
	if (mode == kImportAccessMode) {
		status = importAnim(sList,animFile,pasteFlags,replacer,exportEditsFile,templateReader,replaceLayers);
	}

	animFile.close();
	return status;
}
コード例 #7
0
ファイル: MayaCameraWriter.cpp プロジェクト: alembic/alembic
MayaCameraWriter::MayaCameraWriter(MDagPath & iDag,
    Alembic::Abc::OObject & iParent, Alembic::Util::uint32_t iTimeIndex,
    const JobArgs & iArgs) :
    mIsAnimated(false),
    mDagPath(iDag),
    mUseRenderShutter(false),
    mShutterOpen(0.0),
    mShutterClose(0.0)
{
    MStatus status = MS::kSuccess;
    MFnCamera cam(iDag, &status);
    if (!status)
    {
        MGlobal::displayError( "MFnCamera() failed for MayaCameraWriter" );
    }

    MString name = cam.name();
    name = util::stripNamespaces(name, iArgs.stripNamespace);

    Alembic::AbcGeom::OCamera obj(iParent, name.asChar(), iTimeIndex);
    mSchema = obj.getSchema();

    MObject cameraObj = iDag.node();
    if (iTimeIndex != 0 && util::isAnimated(cameraObj))
    {
        mIsAnimated = true;
    }
    else
    {
        iTimeIndex = 0;
    }

    MObject renderObj;
    MSelectionList sel;
    sel.add("defaultRenderGlobals");

    if (!sel.isEmpty())
    {
        sel.getDependNode(0, renderObj);
        MFnDependencyNode dep(renderObj);
        MPlug plug = dep.findPlug("motionBlurUseShutter", true);
        if (plug.asBool())
        {
            MTime sec(1.0, MTime::kSeconds);
            double val = sec.as(MTime::uiUnit());

            mUseRenderShutter = true;
            plug = dep.findPlug("motionBlurShutterOpen", true);
            mShutterOpen = plug.asDouble() / val;
            plug = dep.findPlug("motionBlurShutterClose", true);
            mShutterClose = plug.asDouble() / val;
        }
    }

    Alembic::Abc::OCompoundProperty cp;
    Alembic::Abc::OCompoundProperty up;
    if (AttributesWriter::hasAnyAttr(cam, iArgs))
    {
        cp = mSchema.getArbGeomParams();
        up = mSchema.getUserProperties();
    }

    mAttrs = AttributesWriterPtr(new AttributesWriter(cp, up, obj, cam,
        iTimeIndex, iArgs, true));

    if (!mIsAnimated || iArgs.setFirstAnimShape)
    {
        write();
    }
}
コード例 #8
0
ファイル: richMoveCmd.cpp プロジェクト: BigRoy/Maya-devkit
MStatus richMoveCmd::action( int flag )
//
// Description
// 		Do the actual work here to move the objects	by vector
//
{
	MStatus stat;
	MVector vector = delta;

	switch( flag )
	{
		case UNDOIT:	// undo
			vector.x = -vector.x;
			vector.y = -vector.y;
			vector.z = -vector.z;
			break;
		case REDOIT:	// redo
			break;
		case DOIT:		// do command
			break;
		default:
			break;
	}

	// Create a selection list iterator
	//
	MSelectionList slist;
	MSpace::Space spc = MSpace::kWorld;
	MRichSelection rs;
	MGlobal::getRichSelection( rs);

	// Translate all selected objects
	//
	rs.getSelection( slist);
	if( !slist.isEmpty())
	{
		for ( MItSelectionList iter( slist, MFn::kInvalid); !iter.isDone(); iter.next() ) 
		{
			// Get path and possibly a component
			//
			MDagPath 	mdagPath;		// Item dag path
			MObject 	mComponent;		// Current component
			iter.getDagPath( mdagPath, mComponent );
			MPlane seam;
			rs.getSymmetryPlane( mdagPath, spc, seam);

			if( mComponent.isNull())
			{
				// Transform move
				MFnTransform transFn( mdagPath, &stat );
				if ( MS::kSuccess == stat ) {
					stat = transFn.translateBy( vector, spc );
					CHECKRESULT(stat,"Error doing translate on transform");
					continue;
				}
			}
			else
			{
				// Component move
				iter.getDagPath( mdagPath, mComponent );
				for( MItGeometry geoIter( mdagPath, mComponent); !geoIter.isDone(); geoIter.next())
				{
					MVector origPosition = geoIter.position( spc);
					MWeight weight = geoIter.weight();

					// Calculate the soft move
					MVector position = origPosition + vector * weight.influence();

					// Calculate the soft seam
					position += seam.normal() * (weight.seam() * (seam.directedDistance( origPosition) - seam.directedDistance( position)));
					geoIter.setPosition( position, spc);
				}
			}
		}
	}

	// Translate all symmetry objects
	//
	slist.clear();
	rs.getSymmetry( slist);
	if( !slist.isEmpty())
	{
		for ( MItSelectionList iter( slist, MFn::kInvalid); !iter.isDone(); iter.next() ) 
		{
			// Get path and possibly a component
			//
			MDagPath 	mdagPath;		// Item dag path
			MObject 	mComponent;		// Current component
			iter.getDagPath( mdagPath, mComponent );
			MPlane seam;
			rs.getSymmetryPlane( mdagPath, spc, seam);

			// Reflect our world space move
			//
			MMatrix symmetryMatrix;
			rs.getSymmetryMatrix( mdagPath, spc, symmetryMatrix);
			MVector symmetryVector =  vector * symmetryMatrix;

			if( mComponent.isNull())
			{
				// Transform move
				MFnTransform transFn( mdagPath, &stat );
				if ( MS::kSuccess == stat ) {
					stat = transFn.translateBy( symmetryVector, spc );
					CHECKRESULT(stat,"Error doing translate on transform");
					continue;
				}
			}
			else
			{
				// Component move
				iter.getDagPath( mdagPath, mComponent );
				for( MItGeometry geoIter( mdagPath, mComponent); !geoIter.isDone(); geoIter.next())
				{
					MVector origPosition = geoIter.position( spc);
					MWeight weight = geoIter.weight();

					// Calculate the soft move
					MVector position = origPosition + symmetryVector * weight.influence();

					// Calculate the soft seam
					position += seam.normal() * (weight.seam() * (seam.directedDistance( origPosition) - seam.directedDistance( position)));
					geoIter.setPosition( position, spc);
				}
			}
		}
	}

	return MS::kSuccess;
}