#include <maya/MDagPath.h>
#include <maya/MDagPathArray.h>
#include <maya/MFileIO.h>
#include <maya/MFileObject.h>
#include <maya/MFnAttribute.h>
#include <maya/MFnCompoundAttribute.h>
#include <maya/MFnDagNode.h>
#include <maya/MFnDependencyNode.h>
#include <maya/MFnPlugin.h>
#include <maya/MGlobal.h>
#include <maya/MItDag.h>
#include <maya/MItDependencyNodes.h>
#include <maya/MObjectArray.h>
#include <maya/MPlug.h>
#include <maya/MPlugArray.h>
#include <maya/MPxFileTranslator.h>
#include <maya/MString.h>
#include <maya/MStringArray.h>
#include <ctype.h>
#include <maya/MFStream.h>
#include <time.h>
class maTranslator : public MPxFileTranslator
{
public:
bool haveReadMethod() const;
bool haveWriteMethod() const;
MString defaultExtension() const;
MFileKind identifyFile(
const MFileObject& file,
const char* buffer,
short size
) const;
MStatus reader(
const MFileObject& file,
const MString& options,
FileAccessMode mode
);
MStatus writer(
const MFileObject& file,
const MString& options,
FileAccessMode mode
);
static void* creator();
static void setPluginName(const MString& name);
static MString translatorName();
protected:
void getAddAttrCmds(const MObject& node, MStringArray& cmds);
void getSetAttrCmds(const MObject& node, MStringArray& cmds);
void writeBrokenRefConnections(fstream& f);
void writeConnections(fstream& f);
void writeCreateNode(fstream& f, const MObject& node);
void writeCreateNode(
fstream& f, const MDagPath& nodePath, const MDagPath& parentPath
);
void writeDagNodes(fstream& f);
void writeDefaultNodes(fstream& f);
void writeFileInfo(fstream& f);
void writeFooter(fstream& f, const MString& fileName);
void writeHeader(fstream& f, const MString& fileName);
void writeInstances(fstream& f);
void writeLockNode(fstream& f, const MObject& node);
void writeNodeAttrs(fstream& f, const MObject& node, bool isSelected);
void writeNodeConnections(fstream& f, const MObject& node);
void writeNonDagNodes(fstream& f);
void writeParent(
fstream& f,
const MDagPath& parent,
const MDagPath& child,
bool addIt
);
void writePlugSizeHint(fstream& f, const MPlug& plug);
void writeReferences(fstream& f);
void writeReferenceNodes(fstream& f);
void writeRefNodeParenting(fstream& f);
void writeRequirements(fstream& f);
void writeSelectNode(fstream& f, const MObject& node);
void writeUnits(fstream& f);
static MString comment(const MString& text);
static MString quote(const MString& text);
static MString fExtension;
static MString fFileVersion;
static MString fPluginName;
static MString fTranslatorName;
private:
MPlugArray fBrokenConnSrcs;
MPlugArray fBrokenConnDests;
MObjectArray fDefaultNodes;
MDagPathArray fInstanceChildren;
MDagPathArray fInstanceParents;
MDagPathArray fParentingRequired;
unsigned int fAttrFlag;
unsigned int fCreateFlag;
unsigned int fConnectionFlag;
};
MString maTranslator::fFileVersion = "4.5ff01";
MString maTranslator::fExtension = "pma";
MString maTranslator::fPluginName = "";
MString maTranslator::fTranslatorName = "Maya ASCII (via plugin)";
inline MString maTranslator::defaultExtension() const
{ return fExtension; }
inline bool maTranslator::haveReadMethod() const
{ return false; }
inline bool maTranslator::haveWriteMethod() const
{ return true; }
inline void maTranslator::setPluginName(const MString& name)
{ fPluginName = name; }
inline MString maTranslator::translatorName()
{ return fTranslatorName; }
void* maTranslator::creator()
{
return new maTranslator();
}
MPxFileTranslator::MFileKind maTranslator::identifyFile(
const MFileObject& file, const char* buffer, short bufferLen
) const
{
MString tagStr = comment(fTranslatorName);
int tagLen = tagStr.length();
if (bufferLen >= tagLen)
{
MString initialContents(buffer, bufferLen);
MStringArray initialLines;
initialContents.split('\n', initialLines);
if (initialLines.length() > 0)
{
if (((int)initialLines[0].length() >= tagLen)
&& (initialLines[0].substring(0, tagLen-1) == tagStr))
{
return kIsMyFileType;
}
}
}
else
{
MString fileName(file.name());
int fileNameLen = fileName.length();
int startOfExtension = fileName.rindex('.') + 1;
if ((startOfExtension > 0)
&& (startOfExtension < fileNameLen)
&& (fileName.substring(startOfExtension, fileNameLen) == fExtension))
{
return kIsMyFileType;
}
}
return kNotMyFileType;
}
MStatus maTranslator::writer(
const MFileObject& file,
const MString& ,
MPxFileTranslator::FileAccessMode mode
)
{
if ((mode != kSaveAccessMode) && (mode != kExportAccessMode))
return MS::kNotImplemented;
fstream output(file.fullName().asChar(), ios::out | ios::trunc);
if (!output.good()) return MS::kNotFound;
MStatus status;
fCreateFlag = MFnDependencyNode::allocateFlag(fPluginName, &status);
if (status)
fAttrFlag = MFnDependencyNode::allocateFlag(fPluginName, &status);
if (status)
fConnectionFlag = MFnDependencyNode::allocateFlag(fPluginName, &status);
if (!status)
{
MGlobal::displayError(
"Could not allocate three free node flags."
" Try unloading some other plugins."
);
return MS::kFailure;
}
MItDependencyNodes nodesIter;
for (; !nodesIter.isDone(); nodesIter.next())
{
MObject node = nodesIter.item();
MFnDependencyNode nodeFn(node);
nodeFn.setFlag(fCreateFlag, false);
nodeFn.setFlag(fAttrFlag, false);
nodeFn.setFlag(fConnectionFlag, false);
}
writeHeader(output, file.name());
writeFileInfo(output);
writeReferences(output);
writeRequirements(output);
writeUnits(output);
writeDagNodes(output);
writeNonDagNodes(output);
writeDefaultNodes(output);
writeReferenceNodes(output);
writeConnections(output);
writeFooter(output, file.name());
output.close();
MFnDependencyNode::deallocateFlag(fPluginName, fCreateFlag);
return MS::kSuccess;
}
void maTranslator::writeHeader(fstream& f, const MString& fileName)
{
time_t tempTime = time(NULL);
struct tm* curTime = localtime(&tempTime);
char formattedTime[100];
strftime(
formattedTime, sizeof(formattedTime), "%a, %b %e, %Y %r", curTime
);
f << comment(fTranslatorName).asChar() << " "
<< fFileVersion.asChar() << " scene" << endl;
f << comment("Name: ").asChar() << fileName.asChar() << endl;
f << comment("Last modified: ").asChar() << formattedTime << endl;
}
void maTranslator::writeFileInfo(fstream& f)
{
MStringArray fileInfo;
if (MGlobal::executeCommand("fileInfo -q", fileInfo))
{
unsigned numEntries = fileInfo.length();
unsigned i;
for (i = 0; i < numEntries; i += 2)
{
f << "fileInfo " << quote(fileInfo[i]).asChar() << " "
<< quote(fileInfo[i+1]).asChar() << ";" << endl;
}
}
else
MGlobal::displayWarning("Could not get scene's fileInfo.");
}
void maTranslator::writeReferences(fstream& f)
{
MStringArray files;
MFileIO::getReferences(files);
unsigned numRefs = files.length();
unsigned i;
for (i = 0; i < numRefs; i++)
{
MString refCmd = "file -r";
MString fileName = files[i];
MString nsName = "";
MString tempCmd = "file -q -ns \"";
tempCmd += fileName + "\"";
if (MGlobal::executeCommand(tempCmd, nsName))
{
refCmd += " -ns \"";
refCmd += nsName + "\"";
}
else
MGlobal::displayWarning("Could not get namespace name.");
tempCmd = "file -q -dr \"";
tempCmd += fileName + "\"";
int isDeferred;
if (MGlobal::executeCommand(tempCmd, isDeferred))
{
if (isDeferred) refCmd += " -dr 1";
}
else
MGlobal::displayWarning("Could not get deferred reference info.");
tempCmd = "file -q -rfn \"";
tempCmd += fileName + "\"";
MString refNode;
if (MGlobal::executeCommand(tempCmd, refNode))
{
if (refNode.length() > 0)
{
refCmd += " -rfn \"";
refCmd += refNode + "\"";
}
}
else
MGlobal::displayInfo("Could not query reference node name.");
f << refCmd.asChar() << " \"" << fileName.asChar() << "\";" << endl;
}
}
void maTranslator::writeRequirements(fstream& f)
{
f << "requires maya \"" << fFileVersion.asChar() << "\";" << endl;
MStringArray pluginsUsed;
if (MGlobal::executeCommand("pluginInfo -q -pluginsInUse", pluginsUsed))
{
unsigned numPlugins = pluginsUsed.length();
unsigned i;
for (i = 0; i < numPlugins; i += 2)
{
f << "requires " << quote(pluginsUsed[i]).asChar() << " "
<< quote(pluginsUsed[i+1]).asChar() << ";" << endl;
}
}
else
{
MGlobal::displayWarning(
"Could not get list of plugins currently in use."
);
}
}
void maTranslator::writeUnits(fstream& f)
{
MString args = "";
MString result;
if (MGlobal::executeCommand("currentUnit -q -fullName -linear", result))
args += " -l " + result;
else
MGlobal::displayWarning("Could not get current linear units.");
if (MGlobal::executeCommand("currentUnit -q -fullName -angle", result))
args += " -a " + result;
else
MGlobal::displayWarning("Could not get current linear units.");
if (MGlobal::executeCommand("currentUnit -q -fullName -time", result))
args += " -t " + result;
else
MGlobal::displayWarning("Could not get current linear units.");
if (args != "")
{
f << "currentUnit" << args.asChar() << ";" << endl;
}
}
void maTranslator::writeDagNodes(fstream& f)
{
fParentingRequired.clear();
MItDag dagIter;
dagIter.traverseUnderWorld(true);
MDagPath worldPath;
dagIter.getPath(worldPath);
for (dagIter.next(); !dagIter.isDone(); dagIter.next())
{
MDagPath path;
dagIter.getPath(path);
MFnDagNode dagNodeFn(path);
if (dagNodeFn.isFlagSet(fCreateFlag))
{
dagIter.prune();
continue;
}
if (dagNodeFn.isDefaultNode()) continue;
if (!dagNodeFn.canBeWritten() && !dagNodeFn.isShared())
{
dagNodeFn.setFlag(fCreateFlag, true);
continue;
}
unsigned int numParents = dagNodeFn.parentCount();
if (dagNodeFn.isFromReferencedFile())
{
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
{
MDagPath parentPath = worldPath;
if (path.length() > 1)
{
parentPath = path;
parentPath.pop();
if (parentPath.pathCount() > 1)
{
path.getPath(parentPath, 0);
}
}
MFnDagNode parentNodeFn(parentPath);
if (parentNodeFn.isFromReferencedFile())
{
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;
writeCreateNode(f, path, worldPath);
fParentingRequired.append(path);
}
else
{
writeCreateNode(f, path, parentPath);
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 (hasRefParents && hasOtherNonRefParents) break;
}
}
if (hasRefParents) fParentingRequired.append(path);
if (hasOtherNonRefParents)
{
fInstanceChildren.append(path);
fInstanceParents.append(parentPath);
}
}
writeNodeAttrs(f, path.node(), true);
writeLockNode(f, path.node());
}
dagNodeFn.setFlag(fCreateFlag, true);
}
writeInstances(f);
}
void maTranslator::writeInstances(fstream& f)
{
unsigned int numInstancedNodes = fInstanceChildren.length();
unsigned int i;
for (i = 0; i < numInstancedNodes; i++)
{
MFnDagNode nodeFn(fInstanceChildren[i]);
unsigned int numParents = nodeFn.parentCount();
unsigned int p;
for (p = 0; p < numParents; p++)
{
if (nodeFn.parent(i) != fInstanceParents[i].node())
{
MObject parent = nodeFn.parent(i);
MFnDagNode parentFn(parent);
if (!parentFn.isFromReferencedFile())
{
MDagPath parentPath;
MDagPath::getAPathTo(parentFn.object(), parentPath);
writeParent(f, parentPath, fInstanceChildren[i], true);
}
}
}
}
fInstanceChildren.clear();
fInstanceParents.clear();
}
void maTranslator::writeParent(
fstream& f, const MDagPath& parent, const MDagPath& child, bool addIt
)
{
f << "parent -s -nc -r ";
if (addIt) f << "-a ";
if (parent.length() == 0) f << "-w ";
f << "\"" << child.partialPathName().asChar() << "\"";
if (parent.length() != 0)
f << " \"" << parent.partialPathName().asChar() << "\"";
f << ";" << endl;
}
void maTranslator::writeNonDagNodes(fstream& f)
{
MItDependencyNodes nodeIter;
for (; !nodeIter.isDone(); nodeIter.next())
{
MObject node = nodeIter.item();
MFnDependencyNode nodeFn(node);
if (nodeFn.isDefaultNode())
{
fDefaultNodes.append(node);
}
else if (!nodeFn.isFromReferencedFile()
&& !nodeFn.isFlagSet(fCreateFlag))
{
if (nodeFn.canBeWritten() || nodeFn.isShared())
{
writeCreateNode(f, node);
writeNodeAttrs(f, node, true);
writeLockNode(f, node);
}
nodeFn.setFlag(fCreateFlag, true);
nodeFn.setFlag(fAttrFlag, true);
}
}
}
void maTranslator::writeDefaultNodes(fstream& f)
{
unsigned int numNodes = fDefaultNodes.length();
unsigned int i;
for (i = 0; i < numNodes; i++)
{
writeNodeAttrs(f, fDefaultNodes[i], false);
MFnDependencyNode nodeFn(fDefaultNodes[i]);
nodeFn.setFlag(fAttrFlag, true);
}
}
void maTranslator::writeNodeAttrs(
fstream& f, const MObject& node, bool isSelected
)
{
MFnDependencyNode nodeFn(node);
if (nodeFn.canBeWritten())
{
MStringArray addAttrCmds;
MStringArray setAttrCmds;
getAddAttrCmds(node, addAttrCmds);
getSetAttrCmds(node, setAttrCmds);
unsigned int numAddAttrCmds = addAttrCmds.length();
unsigned int numSetAttrCmds = setAttrCmds.length();
if (numAddAttrCmds + numSetAttrCmds > 0)
{
if (!isSelected) writeSelectNode(f, node);
unsigned int i;
for (i = 0; i < numAddAttrCmds; i++)
f << addAttrCmds[i].asChar() << endl;
for (i = 0; i < numSetAttrCmds; i++)
f << setAttrCmds[i].asChar() << endl;
}
}
}
void maTranslator::writeReferenceNodes(fstream& f)
{
writeRefNodeParenting(f);
MItDag dagIter;
for (dagIter.next(); !dagIter.isDone(); dagIter.next())
{
MObject node = dagIter.item();
MFnDependencyNode nodeFn(node);
if (nodeFn.isFromReferencedFile()
&& !nodeFn.isFlagSet(fAttrFlag))
{
writeNodeAttrs(f, node, false);
MFileIO::getReferenceConnectionsBroken(
node, fBrokenConnSrcs, fBrokenConnDests, true, true
);
nodeFn.setFlag(fAttrFlag, true);
}
}
MItDependencyNodes nodeIter;
for (; !nodeIter.isDone(); nodeIter.next())
{
MObject node = nodeIter.item();
MFnDependencyNode nodeFn(node);
if (nodeFn.isFromReferencedFile()
&& !nodeFn.isFlagSet(fAttrFlag))
{
writeNodeAttrs(f, node, false);
MFileIO::getReferenceConnectionsBroken(
node, fBrokenConnSrcs, fBrokenConnDests, true, true
);
nodeFn.setFlag(fAttrFlag, true);
}
}
}
void maTranslator::writeConnections(fstream& f)
{
writeBrokenRefConnections(f);
MItDag dagIter;
dagIter.traverseUnderWorld(true);
for (dagIter.next(); !dagIter.isDone(); dagIter.next())
{
MObject node = dagIter.item();
MFnDagNode dagNodeFn(node);
if (!dagNodeFn.isFlagSet(fConnectionFlag)
&& dagNodeFn.canBeWritten()
&& !dagNodeFn.isDefaultNode())
{
writeNodeConnections(f, dagIter.item());
dagNodeFn.setFlag(fConnectionFlag, true);
}
}
MItDependencyNodes nodeIter;
for (; !nodeIter.isDone(); nodeIter.next())
{
MFnDependencyNode nodeFn(nodeIter.item());
if (!nodeFn.isFlagSet(fConnectionFlag)
&& nodeFn.canBeWritten()
&& !nodeFn.isDefaultNode())
{
writeNodeConnections(f, nodeIter.item());
nodeFn.setFlag(fConnectionFlag, true);
}
}
unsigned int numNodes = fDefaultNodes.length();
unsigned int i;
for (i = 0; i < numNodes; i++)
{
MFnDependencyNode nodeFn(fDefaultNodes[i]);
if (!nodeFn.isFlagSet(fConnectionFlag)
&& nodeFn.canBeWritten()
&& nodeFn.isDefaultNode())
{
writeNodeConnections(f, fDefaultNodes[i]);
nodeFn.setFlag(fConnectionFlag, true);
}
}
}
void maTranslator::writeBrokenRefConnections(fstream& f)
{
unsigned int numBrokenConnections = fBrokenConnSrcs.length();
unsigned int i;
for (i = 0; i < numBrokenConnections; i++)
{
f << "disconnectAttr \""
<< fBrokenConnSrcs[i].partialName(true).asChar()
<< "\" \""
<< fBrokenConnDests[i].partialName(true).asChar()
<< "\"";
MObject attr = fBrokenConnDests[i].attribute();
MFnAttribute attrFn(attr);
if (!attrFn.indexMatters()) f << " -na";
f << ";" << endl;
}
}
void maTranslator::writeNodeConnections(fstream& f, const MObject& node)
{
MFnDependencyNode nodeFn(node);
MPlugArray plugs;
nodeFn.getConnections(plugs);
unsigned int numBrokenConns = fBrokenConnSrcs.length();
unsigned int numPlugs = plugs.length();
unsigned int i;
for (i = 0; i < numPlugs; i++)
{
MPlug destPlug = plugs[i];
MPlugArray srcPlug;
destPlug.connectedTo(srcPlug, true, false);
if (srcPlug.length() > 0)
{
MObject srcNode = srcPlug[0].node();
MFnDependencyNode srcNodeFn(srcNode);
if (!srcNodeFn.canBeWritten()) continue;
if (destPlug.isFromReferencedFile()) continue;
if (destPlug.isProcedural()) continue;
if (srcNodeFn.isDefaultNode() && nodeFn.isShared()) continue;
f << "connectAttr \"";
if (srcNodeFn.isDefaultNode()) f << ":";
f << srcPlug[0].partialName(true).asChar()
<< "\" \"";
if (nodeFn.isDefaultNode()) f << ":";
f << destPlug.partialName(true).asChar()
<< "\"";
if (srcNodeFn.isFromReferencedFile())
{
unsigned int j;
for (j = 0; j < numBrokenConns; j++)
{
if (fBrokenConnSrcs[j] == srcPlug[0])
{
f << " -rd \""
<< fBrokenConnDests[j].partialName(true).asChar()
<< "\"";
break;
}
}
}
if (destPlug.isLocked()) f << " -l on";
MObject attr = destPlug.attribute();
MFnAttribute attrFn(attr);
if (!attrFn.indexMatters()) f << " -na";
f << ";" << endl;
}
}
}
void maTranslator::writeCreateNode(
fstream& f, const MDagPath& nodePath, const MDagPath& parentPath
)
{
MObject node(nodePath.node());
MFnDagNode nodeFn(node);
f << "createNode " << nodeFn.typeName().asChar();
if (nodeFn.isShared()) f << " -s";
f << " -n \"" << nodeFn.name().asChar() << "\"";
if (parentPath.length() > 0)
f << " -p \"" << parentPath.partialPathName().asChar() << "\"";
f << ";" << endl;
}
void maTranslator::writeCreateNode(fstream& f, const MObject& node)
{
MFnDependencyNode nodeFn(node);
f << "createNode " << nodeFn.typeName().asChar();
if (nodeFn.isShared()) f << " -s";
f << " -n \"" << nodeFn.name().asChar() << "\";" << endl;
}
void maTranslator::writeLockNode(fstream& f, const MObject& node)
{
MFnDependencyNode nodeFn(node);
if (nodeFn.isLocked()) f << "lockNode;" << endl;
}
void maTranslator::writeSelectNode(fstream& f, const MObject& node)
{
MStatus status;
MFnDependencyNode nodeFn(node);
MString nodeName;
if (nodeFn.hasUniqueName())
nodeName = nodeFn.name();
else
{
MFnDagNode dagNodeFn(node, &status);
if (!status)
{
MGlobal::displayWarning(
MString("Node '") + nodeFn.name()
+ "' has a non-unique name but claimes to not be a DAG node.\n"
+ "Using non-unique name."
);
nodeName = nodeFn.name();
}
else
nodeName = dagNodeFn.partialPathName();
}
f << "select -ne ";
if (nodeFn.isDefaultNode()) f << ":";
f << nodeName.asChar() << ";\n";
}
void maTranslator::writeRefNodeParenting(fstream& f)
{
unsigned int numNodes = fParentingRequired.length();
unsigned int i;
for (i = 0; i < numNodes; i++)
{
MFnDagNode nodeFn(fParentingRequired[i]);
bool hasRefParents = false;
bool hasNonRefParents = false;
unsigned int numParents = nodeFn.parentCount();
unsigned int p;
for (p = 0; p < numParents; p++)
{
MObject parent = nodeFn.parent(p);
MFnDagNode parentFn(parent);
if (parentFn.isFromReferencedFile())
hasRefParents = true;
else
hasNonRefParents = true;
if (hasRefParents && hasNonRefParents) break;
}
bool alreadyHasFirstParent =
(nodeFn.isFromReferencedFile() ? hasRefParents : hasNonRefParents);
for (p = 0; p < numParents; p++)
{
MObject parent = nodeFn.parent(p);
MFnDagNode parentFn(parent);
if (parentFn.isFromReferencedFile() != nodeFn.isFromReferencedFile())
{
MDagPath parentPath;
MDagPath::getAPathTo(parentFn.object(), parentPath);
writeParent(
f, parentPath, fParentingRequired[i], alreadyHasFirstParent
);
alreadyHasFirstParent = true;
}
}
}
}
void maTranslator::writeFooter(fstream& f, const MString& fileName)
{
f << comment(" End of ").asChar() << fileName.asChar() << endl;
}
void maTranslator::getAddAttrCmds(const MObject& node, MStringArray& cmds)
{
MFnDependencyNode nodeFn(node);
unsigned int numAttrs = nodeFn.attributeCount();
unsigned int i;
for (i = 0; i < numAttrs; i++)
{
MObject attr = nodeFn.reorderedAttribute(i);
if (nodeFn.isNewAttribute(attr))
{
MFnAttribute attrFn(attr);
MStatus status;
attrFn.parent(&status);
if (status == MS::kNotFound)
{
MFnCompoundAttribute cAttrFn(attr, &status);
if (status)
{
MStringArray newCmds;
cAttrFn.getAddAttrCmds(newCmds);
unsigned int numCommands = newCmds.length();
unsigned int c;
for (c = 0; c < numCommands; c++)
{
if (newCmds[c] != "")
cmds.append(newCmds[c]);
}
}
else
{
MString newCmd = attrFn.getAddAttrCmd();
if (newCmd != "") cmds.append(newCmd);
}
}
}
}
}
void maTranslator::getSetAttrCmds(const MObject& node, MStringArray& cmds)
{
cmds.clear();
MFnDependencyNode nodeFn(node);
unsigned int numAttrs = nodeFn.attributeCount();
unsigned int i;
for (i = 0; i < numAttrs; i++)
{
MObject attr = nodeFn.reorderedAttribute(i);
MFnAttribute attrFn(attr);
MStatus status;
attrFn.parent(&status);
bool isChild = (status != MS::kNotFound);
if (!isChild && attrFn.isStorable() && attrFn.isWritable())
{
MPlug plug(node, attr);
MStringArray newCmds;
plug.getSetAttrCmds(newCmds, MPlug::kChanged, false);
unsigned int numCommands = newCmds.length();
unsigned int c;
for (c = 0; c < numCommands; c++)
{
if (newCmds[c] != "")
cmds.append(newCmds[c]);
}
}
}
}
MStatus maTranslator::reader(
const MFileObject& ,
const MString& ,
MPxFileTranslator::FileAccessMode
)
{
return MS::kNotImplemented;
}
MString maTranslator::comment(const MString& text)
{
MString result("//");
result += text;
return result;
}
MString maTranslator::quote(const MString& str)
{
const char* cstr = str.asChar();
int strLen = str.length();
int i;
MString result("\"");
for (i = 0; i < strLen; i++)
{
int c = cstr[i];
if (isprint(c))
{
switch (c)
{
case '"':
result += "\\\"";
break;
case '\\':
result += "\\\\";
break;
default:
result += MString((const char*)&c, 1);
break;
}
}
else
{
switch (c)
{
case '\n':
result += "\\n";
break;
case '\t':
result += "\\t";
break;
case '\b':
result += "\\b";
break;
case '\r':
result += "\\r";
break;
case '\f':
result += "\\f";
break;
case '\v':
result += "\\v";
break;
case '\007':
result += "\\a";
break;
default:
{
char buff[5];
sprintf(buff, "\\%.3o", c);
result += MString(buff, 4);
}
}
}
}
result += "\"";
return result;
}
MStatus initializePlugin(MObject obj)
{
MFnPlugin plugin(obj, PLUGIN_COMPANY, "1.0", "Any");
maTranslator::setPluginName(plugin.name());
plugin.registerFileTranslator(
maTranslator::translatorName(),
NULL,
maTranslator::creator,
NULL,
NULL,
false
);
return MS::kSuccess;
}
MStatus uninitializePlugin(MObject obj)
{
MFnPlugin plugin( obj );
plugin.deregisterFileTranslator(maTranslator::translatorName());
return MS::kSuccess;
}