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

459 lines
15 KiB
C++

#include "file/token.h"
#include "file/stream.h"
#include "shaderMaterial/shaderMaterialGeoParamValueTexture.h"
#include "shaderMaterial/shaderMaterialGeoParamDescriptionTexture.h"
#include "rageShaderMaterialMayaParam.h"
#include "rageShaderMaterialMaya.h"
#include "rageShaderMaya65.h"
#define REQUIRE_IOSTREAM
#pragma warning(push)
#pragma warning(disable : 4668)
#include <maya/MPlug.h>
#include <maya/MPlugArray.h>
#include <maya/MFnAttribute.h>
#include <maya/MItDependencyNodes.h>
#include <maya/MSelectionList.h>
#include <maya/MDGModifier.h>
#pragma warning(pop)
using namespace rage;
extern bool g_bDisplayMGlobalExecuteCommands;
bool rageShaderMaterialMaya::AddToMayaNode(MObject obNode, const rageShaderMaterial& obMaterial, bool* DeletedExistingDataDuringCreation)
{
MFnDependencyNode obFnThis(obNode);
Assert(DeletedExistingDataDuringCreation);
(*DeletedExistingDataDuringCreation) = false;
if (!obFnThis.isLocked() && !obFnThis.isFromReferencedFile())
{
if (obFnThis.attributeCount())
{
bool attribsAreEqual = true;
// Check the shader attributes
for (int i=0; i<obMaterial.GetShaderParamCount(); i++)
{
if (!rageShaderMaterialMayaParam::IsAttributeSameValue(obNode, obMaterial.GetShaderParam(i)))
{
attribsAreEqual = false;
break;
}
}
if (attribsAreEqual)
{
//All the same so exit
return true;
}
else
{
if (MFnDependencyNode(obNode).isLocked())
{
//message that says we are locked so no connections changed
Displayf("message that says we are locked so no connections changed");
return true;
}
}
}
// Texture overide support
MPlug obTextureOveridePlug = obFnThis.findPlug("TextureOveride");
bool bUseExistingTextureNodes;
obTextureOveridePlug.getValue(bUseExistingTextureNodes);
// Delete all the old attrs
for(unsigned int i=0; i<obFnThis.attributeCount(); i++ )
{
bool bDeleteAttribute = false;
MFnAttribute obFnAttribute(obFnThis.attribute(i));
if(obFnAttribute.isDynamic())
{
// It is a dynamic attribute, so maybe delete it
// Is it a child attribute?
bool bChildAttribute = (obFnAttribute.parent() != MObject::kNullObj);
if(!bChildAttribute)
{
// It is a dynamic attribute and not a child attribute, so maybe delete it
if(bUseExistingTextureNodes && obFnAttribute.isUsedAsColor())
{
// It is a dynamic attribute, not a child attribute, it is a texture attribute and might have to retain it
// Does a param with the same name exist in the given material
bDeleteAttribute = true;
MString strExistingParamName = obFnAttribute.name();
for (int j=0; j<obMaterial.GetParamCount(); j++)
{
// Set the values
const shaderMaterialGeoParamValue * param = obMaterial.GetParam(j);
// Displayf("(\"%s\" == \"%s\") = %d", strExistingParamName.asChar(), param->GetName(), (strExistingParamName == MString(param->GetName())));
if(strExistingParamName == MString(param->GetParamDescription()->GetUIName()))
{
// It still exists, so don't kill it
bDeleteAttribute = false;
break;
}
}
if(bDeleteAttribute)
{
// Displayf("Going to delete %s", obFnAttribute.name().asChar());
}
}
else
{
// It is a dynamic attribute, not a child attribute and I do not have to retain the existing textures, so delete it!
bDeleteAttribute = true;
}
}
}
if(bDeleteAttribute)
{
//(*DeletedExistingDataDuringCreation) = true;
// Safe to delete
//Displayf("Deleting %s", obFnAttribute.name().asChar());
MStatus obStatus = obFnThis.removeAttribute(obFnThis.attribute(i), MFnDependencyNode::kLocalDynamicAttr);
if(obStatus != MS::kSuccess)
{
Displayf("An error occured removing attribute %s from node %s : %s %s %d", obFnAttribute.name().asChar(), obFnThis.name().asChar(), obStatus.errorString().asChar(), __FILE__, __LINE__);
return false;
}
i--;
}
}
}
// Add the new shader attributes
for (int i=0; i<obMaterial.GetShaderParamCount(); i++)
{
MPlug obExistingPlug = obFnThis.findPlug(obMaterial.GetShaderParam(i)->GetParamDescription()->GetUIName());
if(obExistingPlug.isNull())
{
//Displayf("Add Attribute [%s]", obMaterial.GetShaderParam(i)->GetParamDescription()->GetUIName());
// Don't exist, so add me
//if (!rageShaderMaya::getIgnoreReferencedNodesDuringWireUpTextures())
//{
rageShaderMaterialMayaParam::AddAttributesToMayaNode(obNode, obMaterial.GetShaderParam(i));
//}
}
else
{
//Displayf("Not going to add %s because already exists", obExistingPlug.name().asChar());
}
}
// Restore the locked-ness
return true;
}
bool rageShaderMaterialMaya::RemoveFromMayaNode(MObject obNode, const rageShaderMaterial& /*obMaterial*/)
{
MFnDependencyNode obFnThis(obNode);
if (obFnThis.isLocked())
{
//nothing we can do
return true;
}
MPlug obTextureOveridePlug = obFnThis.findPlug("TextureOveride");
bool bUseExistingTextureNodes;
obTextureOveridePlug.getValue(bUseExistingTextureNodes);
// Delete all the attrs of the material
for(unsigned int i=0; i<obFnThis.attributeCount(); i++ )
{
bool bDeleteAttribute = false;
MFnAttribute obFnAttribute(obFnThis.attribute(i));
if(obFnAttribute.isDynamic())
{
// It is a dynamic attribute, so maybe delete it
// Is it a child attribute?
bool bChildAttribute = (obFnAttribute.parent() != MObject::kNullObj);
if(!bChildAttribute)
{
if(bUseExistingTextureNodes && obFnAttribute.isUsedAsColor())
{
bDeleteAttribute = false;
}
else
{
bDeleteAttribute = true;
}
}
}
if(bDeleteAttribute)
{
// Safe to delete
//Displayf("Deleting %s", obFnAttribute.name().asChar());
MStatus obStatus = obFnThis.removeAttribute(obFnThis.attribute(i), MFnDependencyNode::kLocalDynamicAttr);
if(obStatus != MS::kSuccess)
{
Errorf("An error occured removing attribute %s from node %s : %s %s %d", obFnAttribute.name().asChar(), obFnThis.name().asChar(), obStatus.errorString().asChar(), __FILE__, __LINE__);
return false;
}
i--;
}
}
return true;
}
bool rageShaderMaterialMaya::WireUpTextureNode(MObject obNode, const shaderMaterialGeoParamValue& obParam)
{
// Initialize the dependency object
MFnDependencyNode obFnShaderNode(obNode);
//Displayf("Node %s", obFnShaderNode.name().asChar());
if (obFnShaderNode.isLocked())
{
//Displayf("Node %s is locked no texture connection attempted\n", obFnShaderNode.name().asChar());
//early out cause we cant change anything that is locked.
return true;
}
if (obFnShaderNode.isFromReferencedFile())
{
//Displayf("Node %s is from referenced file, no texture connection attempted\n", obFnShaderNode.name().asChar());
//early out cause we cant change anything that is from a referenced file.
return true;
}
// Got a valid texture param
shaderMaterialGeoParamValueTexture* pobTextureParam = (shaderMaterialGeoParamValueTexture*) &obParam;
const shaderMaterialGeoParamDescriptionTexture* textureDesc = (const shaderMaterialGeoParamDescriptionTexture*)pobTextureParam->GetParamDescription();
Assert(textureDesc);
// Get texture name
const char * pcTextureFilename = pobTextureParam->GetValue();
if (!pcTextureFilename)
{
Errorf("No texture name from RSM: %s PARAM: %s\n", obFnShaderNode.name().asChar(), obParam.GetName());
return false;
}
if (stricmp(pcTextureFilename, "none"))
{
//Displayf("Using Texture: %s from RSM: %s PARAM: %s", pcTextureFilename, obFnShaderNode.name().asChar(), obParam.GetName());
MItDependencyNodes depIterator( MFn::kFileTexture);
// Do I already have a file node matching that texture file name?
MObject obFileNode = MObject::kNullObj;
MString strFileNodeName = "";
MStatus obStatus;
for (; !depIterator.isDone(); depIterator.next() )
{
MFnDependencyNode node( depIterator.item() );
if (rageShaderMaya::getIgnoreReferencedNodesDuringWireUpTextures() && node.isFromReferencedFile())
{
continue;
}
else
{
MPlug plug = node.findPlug("fileTextureName");
if (!plug.isNull())
{
MString textureFileName;
plug.getValue(textureFileName);
//Displayf("Comparing %s and %s (%s)", pcTextureFilename, textureFileName.asChar());
if (stricmp(fiAssetManager::FileName(textureFileName.asChar()), fiAssetManager::FileName(pcTextureFilename))==0)
{
//check the full path to make sure it is the same.
if (stricmp(textureFileName.asChar(), pcTextureFilename)==0)
{
strFileNodeName = node.name();
obFileNode = depIterator.item();
//Displayf("Found file node: %s", strFileNodeName.asChar());
break;
}
}
}
}
}
if(strFileNodeName == "")
{
// Unable to find an existing filename that works, so make one
// Can't find a good node, so create the maya texture file node
MGlobal::executeCommand("shadingNode -asTexture file", strFileNodeName, g_bDisplayMGlobalExecuteCommands);
// Convert node name into actual API node
MSelectionList list;
list.add(strFileNodeName);
list.getDependNode(0, obFileNode);
// Set the filename of the new node
MFnDependencyNode obFnFileNode(obFileNode);
MPlug obFileTextureNamePlug = obFnFileNode.findPlug("fileTextureName");
obFileTextureNamePlug.setValue(pcTextureFilename);
//Displayf("Create File node with texture %s", pcTextureFilename);
}
// Get plugs for connections
MFnDependencyNode obFnFileNode( obFileNode );
MPlug obOutColorPlug = obFnFileNode.findPlug("outColor", &obStatus);
if(obOutColorPlug.isNull())
{
// Oh dear
MGlobal::displayError("Unable to find outColor attribute on \""+ obFnFileNode.name() +"\"");
return false;
}
CHECK_STATUS( obStatus );
MString strTextureParamUIName = pobTextureParam->GetParamDescription()->GetUIName();
MString strSafeTextureParamUIName = rageShaderMaterialMayaParam::GetCleanVersionOfString(strTextureParamUIName.asChar());
MPlug obInColorPlug = obFnShaderNode.findPlug(strSafeTextureParamUIName, &obStatus);
if(obInColorPlug.isNull())
{
// Oh dear
MGlobal::displayError("Unable to find \""+ strSafeTextureParamUIName +"\" attribute on \""+ obFnShaderNode.name() +"\"");
return false;
}
CHECK_STATUS( obStatus );
// Make sure I'm not already connected
MPlugArray aobPlugsConnectedToOutColor;
obOutColorPlug.connectedTo(aobPlugsConnectedToOutColor, true, true, &obStatus);
CHECK_STATUS( obStatus );
MPlugArray aobPlugsConnectedToInColor;
obInColorPlug.connectedTo(aobPlugsConnectedToInColor, true, true, &obStatus);
CHECK_STATUS( obStatus );
//Displayf("aobPlugsConnectedToInColor.length() = %d", aobPlugsConnectedToInColor.length());
//for(unsigned i=0; i<aobPlugsConnectedToInColor.length(); i++)
//{
// Displayf("aobPlugsConnectedToInColor[%d] = %s\n", i, aobPlugsConnectedToInColor[i].name().asChar());
//}
//Displayf("aobPlugsConnectedToOutColor.length() = %d", aobPlugsConnectedToOutColor.length());
//for(unsigned i=0; i<aobPlugsConnectedToOutColor.length(); i++)
//{
// Displayf("aobPlugsConnectedToOutColor[%d] = %s\n", i, aobPlugsConnectedToOutColor[i].name().asChar());
//}
MString plugName = obFnShaderNode.name();
plugName += ".";
plugName += rageShaderMaterialMayaParam::GetCleanVersionOfString(textureDesc->GetUIName());
bool bAlreadyConnected = false;
for(unsigned i=0; i<aobPlugsConnectedToOutColor.length(); i++)
{
if (!stricmp(plugName.asChar(), aobPlugsConnectedToOutColor[i].name().asChar()))
{
MPlugArray aobPlugsConnectedToOutColorPlug;
aobPlugsConnectedToOutColor[i].connectedTo(aobPlugsConnectedToOutColorPlug, true, true, &obStatus);
//Displayf("aobPlugsConnectedToOutColorPlug.length() = %d", aobPlugsConnectedToOutColorPlug.length());
//for(unsigned j=0; j<aobPlugsConnectedToOutColorPlug.length(); j++)
//{
// Displayf("aobPlugsConnectedToOutColorPlug[%d] = %s\n", j, aobPlugsConnectedToOutColorPlug[j].name().asChar());
//}
for(unsigned j=0; j<aobPlugsConnectedToOutColorPlug.length(); j++)
{
for(unsigned k=0; k<aobPlugsConnectedToInColor.length(); k++)
{
//Displayf("Comparing %s and %s\n", aobPlugsConnectedToInColor[k].name().asChar(), aobPlugsConnectedToOutColorPlug[j].name().asChar());
if(aobPlugsConnectedToInColor[k] == aobPlugsConnectedToOutColorPlug[j])
{
// Already connected so forget about it
//Displayf("\nAlready connected\n");
bAlreadyConnected = true;
break;
}
}
if (bAlreadyConnected)
{
break;
}
}
}
if (bAlreadyConnected)
{
break;
}
}
if(!bAlreadyConnected)
{
MDGModifier obModifier;
if (obInColorPlug.isLocked())
{
//Displayf("Atrribute %s is locked no texture connection attempted\n", obInColorPlug.name().asChar());
//early out cause we cant change anything that is locked.
return true;
}
if (obOutColorPlug.isLocked())
{
//Displayf("Atrribute %s is locked no texture connection attempted\n", obOutColorPlug.name().asChar());
//early out cause we cant change anything that is locked.
return true;
}
MFnAttribute obA1( obInColorPlug.attribute() );
if (!obA1.isWritable())
{
//Displayf("Atrribute %s from plug %s is not writable no texture connection attempted\n", obA1.name().asChar(), obInColorPlug.name().asChar());
//early out cause we cant change anything that is locked.
return true;
}
//Having to force this connection seems wrong, but we are running into an error case
// which is that the file nodes' outColor attribute (obOutColorPlug) is not writable
// which is causing the connection to error resulting in the connection not happening.
//By forcing the connection we get the desired effect of shared file nodes.
//The command bellow forces the connection between the file node and the RSM without an error.
//The code above this is not changed because we still want all checks to happen to protect
// referenced in RSM nodes and other "locked" cases.
//Executing this script line is the same as doing the drag drop step to link a file node
// to an RSM.
//connectAttr -force DiffuseTexture2.outColor p_gen_basketIndian01_.DiffuseTexture;
MString command = "connectAttr -force ";
command += obOutColorPlug.name();
command += " ";
command += obInColorPlug.name();
command += ";";
// Connect the attributes
//Displayf("%d Connecting %s -> %s", (int)__LINE__, obOutColorPlug.name().asChar(), obInColorPlug.name().asChar());
CHECK_STATUS(obModifier.commandToExecute(command));
MStatus obStatus = obModifier.doIt();
CHECK_STATUS(obStatus);
if(obStatus != MS::kSuccess)
{
// An error occured
Displayf("An error occurred connecting %s to %s\n", obOutColorPlug.name().asChar(), obInColorPlug.name().asChar());
}
}
}
return true;
}
bool rageShaderMaterialMaya::ExpandTextureNodes(MObject obNode, const rageShaderMaterial& obMaterial)
{
// Wire up all the nodes
for (int iParam=0; iParam<obMaterial.GetParamCount(); iParam++)
{
// Lets find all the texture pobParameters
const shaderMaterialGeoParamValue * pobParam = obMaterial.GetParam(iParam);
if (pobParam && pobParam->GetType() == grcEffect::VT_TEXTURE)
{
WireUpTextureNode(obNode, *pobParam);
}
}
return true;
}