Files
expvintl 419f2e4752 init
2025-02-23 17:40:52 +08:00

330 lines
11 KiB
C++

#define REQUIRE_IOSTREAM
#pragma warning(push)
#pragma warning(disable : 4668)
#include <maya/MArgList.h>
#include <maya/MSelectionList.h>
#include <maya/MDagPath.h>
#pragma warning(pop)
#include "rageGeoDataSetCommands.h"
#include "rageMayaGeoInstanceCmd.h"
#include "rageMayaGeoInstance.h"
MStatus rageMayaGeoInstanceCmd::doIt(const MArgList &args)
{
MStatus status(MS::kSuccess);
MString strDagPathToNode = "";
for(unsigned i =0; i<args.length(); i++)
{
if(args.asString(i) == "-node")
{
strDagPathToNode = args.asString(++i);
}
else if(args.asString(i) == "-new")
{
MString strGeoType = args.asString(++i);
return NewInstanceOfType(strDagPathToNode, strGeoType);
}
else if(args.asString(i) == "-createExistingInstanceFromUID")
{
MString strGeoInstanceUID = args.asString(++i);
return CreateExistingInstanceFromUID(strGeoInstanceUID);
}
}
//MArgDatabase argData(syntax(), args);
//setResult(rageGeoDataSetCommands::GetDataSetVersion());
return MS::kSuccess;
}
MStatus rageMayaGeoInstanceCmd::NewInstanceOfType(const MString& strDagPathToNode, const MString& strGeoType)
{
// Get Instance Node
if(strDagPathToNode == "")
{
MGlobal::displayError("You must provide a node path before the -new option");
return MS::kFailure;
}
MSelectionList obTempSelectionList;
obTempSelectionList.add(strDagPathToNode);
MDagPath obDagPathToNode;
obTempSelectionList.getDagPath(0, obDagPathToNode);
// Do it
rageMayaGeoInstance::SetToNewInstanceOfType(obDagPathToNode.node(), strGeoType);
return MS::kSuccess;
}
MStatus rageMayaGeoInstanceCmd::CreateExistingInstanceFromUID(const MString& strGeoInstanceUID)
{
CreateExistingInstanceFromUID_Inner(strGeoInstanceUID);
return MS::kSuccess;
}
MObject rageMayaGeoInstanceCmd::CreateExistingInstanceFromUID_Inner(const MString& strGEOInstanceUUID)
{
//MGlobal::displayInfo("Recreating GEO Instance : "+ strGEOInstanceUUID);
//cout<<"Recreating GEO Instance : "<<strGEOInstanceUUID.asChar()<<endl;
// Get Info about Instance from name
MString strUID = strGEOInstanceUUID;
MString strName = rageGeoDataSetCommands::GetNameFromUUID(strGEOInstanceUUID);
MString strType = rageGeoDataSetCommands::GetTypeNameFromInstanceUUID(strGEOInstanceUUID);
// Create a GEO Instance node to represent this instance
bool bGeoTypeBasedHeirarchy = true;
MDagModifier obDagModifier;
MObject obNode = MObject::kNullObj;
if(bGeoTypeBasedHeirarchy)
{
obNode = obDagModifier.createNode("rageMayaGeoInstance", CreateParentTransformBasedOnGeoInstance(strUID));
}
else
{
obNode = obDagModifier.createNode("rageMayaGeoInstance");
}
obDagModifier.doIt();
// MGlobal::displayInfo("Created Node");
// cout<<"Created Node"<<endl;
// Set attributes
MFnDagNode obFnNode(obNode);
MPlug obUIDPlug = obFnNode.findPlug("rageGeoInstanceUID");
obUIDPlug.setLocked(false);
obUIDPlug.setValue(strUID);
obUIDPlug.setLocked(true);
//const char* pcUID = strUID.asChar();
//cout<<"Set UID attribute to : "<<pcUID<<endl;
// Set the attributes for the node
MPlug obNamePlug = obFnNode.findPlug("rageGeoInstanceName");
obNamePlug.setLocked(false);
obNamePlug.setValue(strName);
obNamePlug.setLocked(true);
// Get GeoType from name
MPlug obTypePlug = obFnNode.findPlug("rageGeoInstanceType");
obTypePlug.setLocked(false);
obTypePlug.setValue(strType);
obTypePlug.setLocked(true);
// Add container nodes
rageMayaGeoInstance::UpdateContainerParameters(obNode);
// Update the graphical representation
rageMayaGeoInstance::GiveGraphicalRepresentation(obNode);
// Move to the "correct" location
MMatrix obMatrix = rageGeoDataSetCommands::GetWorldSpaceMatrix(strGEOInstanceUUID);
MGlobal::executeCommand(MString("xform -worldSpace -matrix ")
+ obMatrix[0][0] +" "
+ obMatrix[0][1] +" "
+ obMatrix[0][2] +" "
+ obMatrix[0][3] +" "
+ obMatrix[1][0] +" "
+ obMatrix[1][1] +" "
+ obMatrix[1][2] +" "
+ obMatrix[1][3] +" "
+ obMatrix[2][0] +" "
+ obMatrix[2][1] +" "
+ obMatrix[2][2] +" "
+ obMatrix[2][3] +" "
+ obMatrix[3][0] +" "
+ obMatrix[3][1] +" "
+ obMatrix[3][2] +" "
+ obMatrix[3][3] +" "
+ obFnNode.fullPathName(), true);
// Give Graphical Representation
// cout<<MString("rageGeoInstance.GiveInstanceGraphicalRepresentationInMaya(\""+ obFnNode.fullPathName() +"\")").asChar()<<endl;
// MGlobal::executeCommand("rageGeoInstance.GiveInstanceGraphicalRepresentationInMaya(\""+ obFnNode.fullPathName() +"\")", true);
// Move to the correct place
// Recurse for all of my children
vector<MString> obAStrContainerUIDs = rageGeoDataSetCommands::GetContainerUIDsFromInstanceUID(strUID);
vector<MString> obAStrContainerNames = rageGeoDataSetCommands::GetContainerNamesFromInstanceUID(strUID);
// For each container
MDGModifier obDGModifier;
MStatus obStatus = MS::kSuccess;
for(unsigned i=0; i<obAStrContainerUIDs.size(); i++)
{
// cout<<"Populating container "<<obAStrContainerUIDs[i].asChar()<<endl;
MPlug obSourcePlug = obFnNode.findPlug("rageGeoContainer_"+ obAStrContainerNames[i], &obStatus);
if(obSourcePlug.isNull() || (obStatus != MS::kSuccess))
{
// Oh dear, I can't find the plug
cout<<"Unable to find attribute "<<obFnNode.name().asChar()<<"."<<"rageGeoContainer_"<<obAStrContainerNames[i].asChar()<<endl;
cout<<obStatus.errorString().asChar()<<endl;
}
vector<MString> obAStrContainedUIDs = rageGeoDataSetCommands::GetUIDsOfContainedInstancesFromParentInstanceUID(strUID, obAStrContainerUIDs[i]);
for(unsigned j=0; j<obAStrContainedUIDs.size(); j++)
{
// cout<<"Adding instance "<<obAStrContainedUIDs[j].asChar()<<endl;
MObject obContainedNode = CreateExistingInstanceFromUID_Inner(obAStrContainedUIDs[j]);
// Connect the two nodes up
MPlug obDestPlug = MFnDependencyNode(obContainedNode).findPlug("rageGeoInstanceContainerUID", &obStatus);
if(obDestPlug.isNull() || (obStatus != MS::kSuccess))
{
// Oh dear, I can't find the plug
cout<<"Unable to find attribute "<<MFnDependencyNode(obContainedNode).name().asChar()<<"."<<"rageGeoInstanceContainerUID"<<endl;
cout<<obStatus.errorString().asChar()<<endl;
}
obStatus = obDGModifier.connect(obSourcePlug, obDestPlug);
if(obStatus != MS::kSuccess)
{
// Oh dear, I can't connect
cout<<"Unable to connect attribute "<<obSourcePlug.name().asChar()<<" to "<<obDestPlug.name().asChar()<<endl;
cout<<obStatus.errorString().asChar()<<endl;
}
}
}
obStatus = obDGModifier.doIt();
if(obStatus != MS::kSuccess)
{
// Oh dear, I can't doIt
cout<<"Unable to doIt"<<endl;
cout<<obStatus.errorString().asChar()<<endl;
}
return obNode;
}
MObject rageMayaGeoInstanceCmd::CreateParentTransformBasedOnGeoInstance(const MString& strGeoInstanceUID)
{
// Get type of instance
MString strType = rageGeoDataSetCommands::GetTypeNameFromInstanceUUID(strGeoInstanceUID);
if(strType == "")
{
// Invalid type, so can't go any further
MSelectionList obTempSelectionList;
MStatus obStatus = obTempSelectionList.add("InstancesWithInvalidGeoType");
if(obStatus == MS::kSuccess)
{
MDagPath obDagPathToNode;
obStatus = obTempSelectionList.getDagPath(0, obDagPathToNode);
if(obStatus == MS::kSuccess)
{
// I already exist, so use it
return obDagPathToNode.node();
}
}
// I don't already exist, so create me
MDagModifier obDagModifier;
MObject obNode = obDagModifier.createNode("transform");
obDagModifier.renameNode(obNode, "InstancesWithInvalidGeoType");
obDagModifier.doIt();
return obNode;
}
// Get parent node for that type
return CreateParentTransformBasedOnGeoType(strType);
}
MObject rageMayaGeoInstanceCmd::CreateParentTransformBasedOnGeoType(const MString& strGeoTypeName)
{
// Get parent type of type
MString strParentTypeName = rageGeoDataSetCommands::GetParentTypeNameFromTypeName(strGeoTypeName);
// Get parent node for that type
MObject obParentNode;
if(strParentTypeName != "")
{
// I have a parent type, so use it
obParentNode = CreateParentTransformBasedOnGeoType(strParentTypeName);
}
else
{
// I don't have a parent type, so switch to templates
// Get template of type
MString strTemplateName = rageGeoDataSetCommands::GetTemplateNameFromTypeName(strGeoTypeName);
obParentNode = CreateParentTransformBasedOnGeoTemplate(strTemplateName);
}
// Do I already exist?
MFnDagNode obFnParentNode(obParentNode);
for(unsigned i=0; i<obFnParentNode.childCount(); i++)
{
// Get the name of the child node
MObject obChildNode = obFnParentNode.child(i);
MFnDagNode obFnChildNode(obChildNode);
if(obFnChildNode.name() == strGeoTypeName)
{
// Bingo! Already have this node
return obChildNode;
}
}
// If I am here, I do not exist, so create myself
MDagModifier obDagModifier;
MObject obNode = obDagModifier.createNode("transform", obParentNode);
obDagModifier.renameNode(obNode, strGeoTypeName);
obDagModifier.doIt();
return obNode;
}
MObject rageMayaGeoInstanceCmd::CreateParentTransformBasedOnGeoTemplate(const MString& strGeoTemplateName)
{
// Get parent Template of Template
MString strParentTemplateName = rageGeoDataSetCommands::GetParentTemplateNameFromTemplateName(strGeoTemplateName);
// Get parent node for that Template
if(strParentTemplateName != "")
{
// I have a parent Template, so use it
MObject obParentNode = CreateParentTransformBasedOnGeoTemplate(strParentTemplateName);
// Do I already exist?
MFnDagNode obFnParentNode(obParentNode);
for(unsigned i=0; i<obFnParentNode.childCount(); i++)
{
// Get the name of the child node
MObject obChildNode = obFnParentNode.child(i);
MFnDagNode obFnChildNode(obChildNode);
if(obFnChildNode.name() == strGeoTemplateName)
{
// Bingo! Already have this node
return obChildNode;
}
}
// If I am here, I do not exist, so create myself
MDagModifier obDagModifier;
MObject obNode = obDagModifier.createNode("transform", obParentNode);
obDagModifier.renameNode(obNode, strGeoTemplateName);
obDagModifier.doIt();
return obNode;
}
else
{
// I am the base root, so just create me
// But first, do I already exist?
MSelectionList obTempSelectionList;
MStatus obStatus = obTempSelectionList.add(strGeoTemplateName);
if(obStatus == MS::kSuccess)
{
MDagPath obDagPathToNode;
obStatus = obTempSelectionList.getDagPath(0, obDagPathToNode);
if(obStatus == MS::kSuccess)
{
// I already exist, so use it
return obDagPathToNode.node();
}
}
// I don't already exist, so create me
MDagModifier obDagModifier;
MObject obNode = obDagModifier.createNode("transform");
obDagModifier.renameNode(obNode, strGeoTemplateName);
obDagModifier.doIt();
return obNode;
}
}