632 lines
21 KiB
C++
632 lines
21 KiB
C++
//
|
|
// Copyright (C)
|
|
//
|
|
// File: rageMayaGeoInstance.cpp
|
|
//
|
|
// Dependency Graph Node: rageMayaGeoInstance
|
|
//
|
|
// Author: Maya Plug-in Wizard 2.0
|
|
//
|
|
|
|
#include "rageGeoDataSetCommands.h"
|
|
#include "rageMayaGeoInstance.h"
|
|
|
|
#define REQUIRE_IOSTREAM
|
|
#pragma warning(push)
|
|
#pragma warning(disable : 4668)
|
|
#include <maya/MPlug.h>
|
|
#include <maya/MDataBlock.h>
|
|
#include <maya/MDataHandle.h>
|
|
#include <maya/MGlobal.h>
|
|
#include <maya/MFnTypedAttribute.h>
|
|
#include <maya/MDGMessage.h>
|
|
#include <maya/MSceneMessage.h>
|
|
#include <maya/MNodeMessage.h>
|
|
#include <maya/MDGModifier.h>
|
|
#include <maya/MItDependencyNodes.h>
|
|
#include <maya/MFileObject.h>
|
|
#pragma warning(pop)
|
|
|
|
#include <Windows.h>
|
|
#include <stdio.h>
|
|
|
|
#define CHECK_STATUS(x) \
|
|
{ \
|
|
MStatus _maya_status = (x); \
|
|
if ( MStatus::kSuccess != _maya_status ) \
|
|
{ \
|
|
MString obStrErrorMessage(__FILE__); \
|
|
obStrErrorMessage += ":"; \
|
|
obStrErrorMessage += __LINE__; \
|
|
obStrErrorMessage += ":"; \
|
|
_maya_status.perror (obStrErrorMessage); \
|
|
} \
|
|
} \
|
|
|
|
// You MUST change this to a unique value!!! The id is a 32bit value used
|
|
// to identify this type of node in the binary file format.
|
|
//
|
|
MTypeId rageMayaGeoInstance::id( 0x7021 );
|
|
bool rageMayaGeoInstance::m_bBetweenBeforeSceneOpenAndAfterSceneOpen = false;
|
|
|
|
// Attributes
|
|
//
|
|
MObject rageMayaGeoInstance::m_obGeoInstanceUIDAttribute;
|
|
MObject rageMayaGeoInstance::m_obGeoInstanceTypeAttribute;
|
|
MObject rageMayaGeoInstance::m_obGeoInstanceNameAttribute;
|
|
MObject rageMayaGeoInstance::m_obGeoInstanceContainerUIDAttribute;
|
|
MCallbackId rageMayaGeoInstance::m_NodeAddedCallbackId;
|
|
MCallbackId rageMayaGeoInstance::m_BeforeMayaSaveCallbackId;
|
|
MCallbackId rageMayaGeoInstance::m_BeforeOpenCallbackId;
|
|
MCallbackId rageMayaGeoInstance::m_BeforeNewCallbackId;
|
|
MCallbackId rageMayaGeoInstance::m_AfterNewCallbackId;
|
|
|
|
rageMayaGeoInstance::rageMayaGeoInstance()
|
|
{
|
|
// InitializeNodeCallbacks();
|
|
}
|
|
|
|
rageMayaGeoInstance::~rageMayaGeoInstance()
|
|
{
|
|
UninitializeNodeCallbacks();
|
|
MString strMyUID;
|
|
MPlug obMyUIDPlug(thisMObject(), m_obGeoInstanceUIDAttribute);
|
|
obMyUIDPlug.getValue(strMyUID);
|
|
// printf("%s is being destroyed\n", strMyUID.asChar());
|
|
// _flushall();
|
|
}
|
|
|
|
void rageMayaGeoInstance::postConstructor()
|
|
{
|
|
InitializeNodeCallbacks();
|
|
|
|
// Was I just created during a file load? If so, commit suicide
|
|
m_bNodeWasCreatedDuringFileOpenSoKillMe = false;
|
|
if(MFileIO::isReadingFile())
|
|
{
|
|
// Kill myself
|
|
m_bNodeWasCreatedDuringFileOpenSoKillMe = true;
|
|
//printf("Commiting suicide\n");
|
|
}
|
|
}
|
|
|
|
void* rageMayaGeoInstance::creator()
|
|
//
|
|
// Description:
|
|
// this method exists to give Maya a way to create new objects
|
|
// of this type.
|
|
//
|
|
// Return Value:
|
|
// a new object of this type
|
|
//
|
|
{
|
|
return new rageMayaGeoInstance();
|
|
}
|
|
|
|
MStatus rageMayaGeoInstance::initialize()
|
|
//
|
|
// Description:
|
|
// This method is called to create and initialize all of the attributes
|
|
// and attribute dependencies for this node type. This is only called
|
|
// once when the node type is registered with Maya.
|
|
//
|
|
// Return Values:
|
|
// MS::kSuccess
|
|
// MS::kFailure
|
|
//
|
|
{
|
|
MFnTypedAttribute tAttr;
|
|
MStatus status;
|
|
m_obGeoInstanceUIDAttribute = tAttr.create( "rageGeoInstanceUID", "UID", MFnData::kString, MObject::kNullObj , &status );
|
|
CHECK_STATUS( status );
|
|
//CHECK_STATUS( tAttr.setInternal( true ) );
|
|
CHECK_STATUS( tAttr.setHidden( true ) );
|
|
//CHECK_STATUS( tAttr.setReadable( true ) );
|
|
//CHECK_STATUS( tAttr.setWritable( false ) );
|
|
//CHECK_STATUS( tAttr.setInternal( true ) );
|
|
CHECK_STATUS( tAttr.setConnectable( false ) );
|
|
CHECK_STATUS( addAttribute( m_obGeoInstanceUIDAttribute ) );
|
|
|
|
m_obGeoInstanceTypeAttribute = tAttr.create( "rageGeoInstanceType", "Type", MFnData::kString, MObject::kNullObj , &status );
|
|
CHECK_STATUS( status );
|
|
//CHECK_STATUS( tAttr.setInternal( true ) );
|
|
CHECK_STATUS( tAttr.setHidden( true ) );
|
|
//CHECK_STATUS( tAttr.setReadable( true ) );
|
|
//CHECK_STATUS( tAttr.setWritable( false ) );
|
|
CHECK_STATUS( tAttr.setConnectable( false ) );
|
|
CHECK_STATUS( tAttr.setInternal( true ) );
|
|
CHECK_STATUS( addAttribute( m_obGeoInstanceTypeAttribute ) );
|
|
|
|
m_obGeoInstanceNameAttribute = tAttr.create( "rageGeoInstanceName", "Name", MFnData::kString, MObject::kNullObj , &status );
|
|
CHECK_STATUS( status );
|
|
//CHECK_STATUS( tAttr.setInternal( true ) );
|
|
CHECK_STATUS( tAttr.setHidden( true ) );
|
|
//CHECK_STATUS( tAttr.setReadable( true ) );
|
|
//CHECK_STATUS( tAttr.setWritable( false ) );
|
|
//CHECK_STATUS( tAttr.setInternal( true ) );
|
|
CHECK_STATUS( tAttr.setConnectable( false ) );
|
|
CHECK_STATUS( addAttribute( m_obGeoInstanceNameAttribute ) );
|
|
|
|
m_obGeoInstanceContainerUIDAttribute = tAttr.create( "rageGeoInstanceContainerUID", "ContainerUID", MFnData::kString, MObject::kNullObj , &status );
|
|
CHECK_STATUS( status );
|
|
//CHECK_STATUS( tAttr.setInternal( true ) );
|
|
CHECK_STATUS( tAttr.setHidden( false ) );
|
|
//CHECK_STATUS( tAttr.setReadable( true ) );
|
|
//CHECK_STATUS( tAttr.setWritable( false ) );
|
|
//CHECK_STATUS( tAttr.setInternal( true ) );
|
|
CHECK_STATUS( tAttr.setConnectable( true ) );
|
|
CHECK_STATUS( addAttribute( m_obGeoInstanceContainerUIDAttribute ) );
|
|
|
|
return MS::kSuccess;
|
|
}
|
|
|
|
void rageMayaGeoInstance::InitializeNodeCallbacks()
|
|
{
|
|
MStatus obStatus;
|
|
MObject obThisNode = thisMObject();
|
|
m_NodePreRemovalCallbackId = MNodeMessage::addNodePreRemovalCallback(obThisNode, NodePreRemovalCallback, this, &obStatus);
|
|
if(obStatus != MS::kSuccess)
|
|
{
|
|
MGlobal::displayError("An error occurred registering NodePreRemovalCallback : "+ obStatus.errorString());
|
|
}
|
|
|
|
m_AfterOpenCallbackId = MSceneMessage::addCallback(MSceneMessage::kAfterOpen, AfterOpenCallback, this);
|
|
m_AfterImportCallbackId = MSceneMessage::addCallback(MSceneMessage::kAfterImport, AfterImportCallback, this);
|
|
}
|
|
|
|
|
|
void rageMayaGeoInstance::UninitializeNodeCallbacks()
|
|
{
|
|
MMessage::removeCallback(m_NodePreRemovalCallbackId);
|
|
MMessage::removeCallback(m_AfterOpenCallbackId);
|
|
MMessage::removeCallback(m_AfterImportCallbackId);
|
|
}
|
|
|
|
|
|
void rageMayaGeoInstance::InitializeGlobalCallbacks()
|
|
{
|
|
m_NodeAddedCallbackId = MDGMessage::addNodeAddedCallback(NodeAddedCallback, "rageMayaGeoInstance");
|
|
m_BeforeMayaSaveCallbackId = MSceneMessage::addCallback(MSceneMessage::kBeforeSave, BeforeMayaSaveCallback);
|
|
m_BeforeOpenCallbackId = MSceneMessage::addCallback(MSceneMessage::kBeforeOpen, BeforeOpenCallback);
|
|
m_BeforeNewCallbackId = MSceneMessage::addCallback(MSceneMessage::kBeforeNew, BeforeNewCallback);
|
|
m_AfterNewCallbackId = MSceneMessage::addCallback(MSceneMessage::kAfterNew, AfterNewCallback);
|
|
}
|
|
|
|
|
|
void rageMayaGeoInstance::UninitializeGlobalCallbacks()
|
|
{
|
|
MMessage::removeCallback(m_NodeAddedCallbackId);
|
|
MMessage::removeCallback(m_BeforeMayaSaveCallbackId);
|
|
MMessage::removeCallback(m_BeforeOpenCallbackId);
|
|
MMessage::removeCallback(m_BeforeNewCallbackId);
|
|
MMessage::removeCallback(m_AfterNewCallbackId);
|
|
}
|
|
|
|
void rageMayaGeoInstance::BeforeMayaSaveCallback(void* /*thisPtr*/)
|
|
{
|
|
MGlobal::executeCommand("rageGeoInstance.SaveAll()", true);
|
|
}
|
|
|
|
void rageMayaGeoInstance::BeforeOpenCallback(void* /*thisPtr*/)
|
|
{
|
|
m_bBetweenBeforeSceneOpenAndAfterSceneOpen = true;
|
|
}
|
|
|
|
void rageMayaGeoInstance::AfterOpenCallback(void* thisPtr)
|
|
{
|
|
m_bBetweenBeforeSceneOpenAndAfterSceneOpen = false;
|
|
|
|
// Kill myself
|
|
rageMayaGeoInstance* pobThis = (rageMayaGeoInstance*)thisPtr;
|
|
MGlobal::executeCommandOnIdle("delete "+ MFnDependencyNode(pobThis->thisMObject()).name(), false);
|
|
}
|
|
|
|
|
|
void rageMayaGeoInstance::AfterImportCallback(void* thisPtr)
|
|
{
|
|
m_bBetweenBeforeSceneOpenAndAfterSceneOpen = false;
|
|
|
|
rageMayaGeoInstance* pobThis = (rageMayaGeoInstance*)thisPtr;
|
|
|
|
//// Update the container parameters
|
|
UpdateContainerParameters(pobThis->thisMObject());
|
|
GiveGraphicalRepresentation(pobThis->thisMObject());
|
|
}
|
|
|
|
|
|
void rageMayaGeoInstance::BeforeNewCallback(void* /*thisPtr*/)
|
|
{
|
|
m_bBetweenBeforeSceneOpenAndAfterSceneOpen = true;
|
|
}
|
|
|
|
void rageMayaGeoInstance::AfterNewCallback(void* /*thisPtr*/)
|
|
{
|
|
m_bBetweenBeforeSceneOpenAndAfterSceneOpen = false;
|
|
}
|
|
|
|
void rageMayaGeoInstance::NodeAddedCallback(MObject& obNode, void* /*thisPtr*/)
|
|
{
|
|
// Get the type of it
|
|
MFnDependencyNode obFnNode(obNode);
|
|
MPlug obGeoInstanceTypePlug = obFnNode.findPlug("rageGeoInstanceType");
|
|
MString strGeoType;
|
|
obGeoInstanceTypePlug.getValue(strGeoType);
|
|
if(strGeoType != "")
|
|
{
|
|
// const char* pcGeoType = strGeoType.asChar();
|
|
// cout<<"obGeoInstanceTypePlug = "<<pcGeoType<<endl;
|
|
SetToNewInstanceOfType(obNode, strGeoType);
|
|
}
|
|
obGeoInstanceTypePlug.setLocked(true);
|
|
}
|
|
|
|
MStatus rageMayaGeoInstance::connectionMade(const MPlug& obPlug, const MPlug& obOtherPlug, bool bAsSource)
|
|
{
|
|
if(rageMayaGeoInstance::ActDumb()) return MStatus::kUnknownParameter;
|
|
//printf("rageMayaGeoInstance::connectionMade\n");
|
|
//printf("obPlug = %s\n", obPlug.info().asChar());
|
|
//printf("obOtherPlug = %s\n", obOtherPlug.info().asChar());
|
|
//printf("bAsSource = %d\n", bAsSource);
|
|
//_flushall();
|
|
if((obPlug == m_obGeoInstanceContainerUIDAttribute) && (!bAsSource))
|
|
{
|
|
// Something was just connected to my container UID attribute, that means that I am now contained within something else
|
|
// Get the UID of the container on the other node
|
|
MString strUIDOfContainer;
|
|
obOtherPlug.getValue(strUIDOfContainer);
|
|
|
|
// Get the UID of the other node
|
|
MString strUIDOfContainerNode;
|
|
MPlug obOtherNodeUIDPlug(obOtherPlug.node(), m_obGeoInstanceUIDAttribute);
|
|
obOtherNodeUIDPlug.getValue(strUIDOfContainerNode);
|
|
|
|
// Get my UID
|
|
MString strMyUID;
|
|
MPlug obMyUIDPlug(thisMObject(), m_obGeoInstanceUIDAttribute);
|
|
obMyUIDPlug.getValue(strMyUID);
|
|
|
|
//printf("%s is now contained in container %s inside instance %s\n", strMyUID.asChar(), strUIDOfContainer.asChar(), strUIDOfContainerNode.asChar());
|
|
//_flushall();
|
|
|
|
// Move the Instance
|
|
MGlobal::executeCommand("GeoMoveInstance \""+ strUIDOfContainerNode +"\" \""+ strUIDOfContainer +"\" \""+ strMyUID +"\"", true, false);
|
|
}
|
|
return MStatus::kUnknownParameter;
|
|
}
|
|
|
|
|
|
MStatus rageMayaGeoInstance::connectionBroken(const MPlug& obPlug, const MPlug& obOtherPlug, bool bAsSource)
|
|
{
|
|
if(rageMayaGeoInstance::ActDumb()) return MStatus::kUnknownParameter;
|
|
//printf("rageMayaGeoInstance::connectionMade\n");
|
|
//printf("obPlug = %s\n", obPlug.info().asChar());
|
|
//printf("obOtherPlug = %s\n", obOtherPlug.info().asChar());
|
|
//printf("bAsSource = %d\n", bAsSource);
|
|
//_flushall();
|
|
if((obPlug == m_obGeoInstanceContainerUIDAttribute) && (!bAsSource))
|
|
{
|
|
// Something was just disconnected from my container UID attribute, that means that I am now not contained within something else
|
|
// Get the UID of the container on the other node
|
|
MString strUIDOfContainer;
|
|
obOtherPlug.getValue(strUIDOfContainer);
|
|
|
|
// Get the UID of the other node
|
|
MString strUIDOfContainerNode;
|
|
MPlug obOtherNodeUIDPlug(obOtherPlug.node(), m_obGeoInstanceUIDAttribute);
|
|
obOtherNodeUIDPlug.getValue(strUIDOfContainerNode);
|
|
|
|
// Get my UID
|
|
MString strMyUID;
|
|
MPlug obMyUIDPlug(thisMObject(), m_obGeoInstanceUIDAttribute);
|
|
obMyUIDPlug.getValue(strMyUID);
|
|
|
|
//printf("%s is no longer contained in container %s inside instance %s\n", strMyUID.asChar(), strUIDOfContainer.asChar(), strUIDOfContainerNode.asChar());
|
|
//_flushall();
|
|
|
|
// Move the Instance
|
|
MGlobal::executeCommand("GeoMoveInstance \"\" \"\" \""+ strMyUID +"\"", true, false);
|
|
}
|
|
return MStatus::kUnknownParameter;
|
|
}
|
|
|
|
void rageMayaGeoInstance::NodePreRemovalCallback(MObject& obNode, void* thisPtr)
|
|
{
|
|
rageMayaGeoInstance* pobThis = (rageMayaGeoInstance*)thisPtr;
|
|
if(pobThis->ActDumb()) return;
|
|
MString strMyUID;
|
|
MPlug obMyUIDPlug(obNode, m_obGeoInstanceUIDAttribute);
|
|
obMyUIDPlug.getValue(strMyUID);
|
|
// printf("%s is being removed and MFileIO::isReadingFile() = %d\n", strMyUID.asChar(), MFileIO::isReadingFile());
|
|
// _flushall();
|
|
MGlobal::executeCommand("GeoDeleteInstance -typeid \""+ strMyUID + "\"", true);
|
|
}
|
|
|
|
MStatus rageMayaGeoInstance::legalConnection(const MPlug& obPlug, const MPlug& obOtherPlug, bool bAsSource, bool& bResult ) const
|
|
{
|
|
//printf("rageMayaGeoInstance::connectionMade\n");
|
|
//printf("obPlug = %s\n", obPlug.info().asChar());
|
|
//printf("obOtherPlug = %s\n", obOtherPlug.info().asChar());
|
|
//printf("bAsSource = %d\n", bAsSource);
|
|
//_flushall();
|
|
// Unless I specify otherwise, connections are allowed so the default is...
|
|
bResult = true;
|
|
|
|
// Next check if it is a case I don't allow
|
|
if((obPlug == m_obGeoInstanceContainerUIDAttribute) && (!bAsSource))
|
|
{
|
|
// Something was just connected to my container UID attribute, that means that I am now contained within something else
|
|
// Get the UID of the container on the other node
|
|
MString strUIDOfContainer;
|
|
obOtherPlug.getValue(strUIDOfContainer);
|
|
|
|
// Get the UID of the other node
|
|
MString strUIDOfContainerNode;
|
|
MPlug obOtherNodeUIDPlug(obOtherPlug.node(), m_obGeoInstanceUIDAttribute);
|
|
obOtherNodeUIDPlug.getValue(strUIDOfContainerNode);
|
|
|
|
// Get my UID
|
|
MString strMyUID;
|
|
MPlug obMyUIDPlug(thisMObject(), m_obGeoInstanceUIDAttribute);
|
|
obMyUIDPlug.getValue(strMyUID);
|
|
|
|
//printf("Testing to see if %s can be contained in container %s inside instance %s\n", strMyUID.asChar(), strUIDOfContainer.asChar(), strUIDOfContainerNode.asChar());
|
|
//_flushall();
|
|
|
|
// Is it legal?
|
|
int bLegal = true;
|
|
MGlobal::executeCommand("GeoCanContainerHoldGeoInstance \""+ strUIDOfContainerNode +"\" \""+ strUIDOfContainer +"\" \""+ strMyUID +"\"", bLegal, true, false);
|
|
bResult = (bLegal != 0);
|
|
}
|
|
return MStatus::kSuccess;
|
|
}
|
|
|
|
void rageMayaGeoInstance::UpdateContainerParameters(const MObject& obNode)
|
|
{
|
|
// Get UID
|
|
// Get my UID
|
|
MString strMyUID;
|
|
MPlug obMyUIDPlug(obNode, m_obGeoInstanceUIDAttribute);
|
|
obMyUIDPlug.getValue(strMyUID);
|
|
//const char* pcUID = strMyUID.asChar();
|
|
//cout<<"Got UID attribute as : "<<pcUID<<endl;
|
|
|
|
// Do I have a valid UID?
|
|
if(strMyUID != "")
|
|
{
|
|
// Add container attributes
|
|
// Get the list of container attributes
|
|
MStringArray astrContainerNames;
|
|
MGlobal::executeCommand("GeoGetInstanceContainerNamesFromUUID \""+ strMyUID +"\"", astrContainerNames, true);
|
|
MStringArray astrContainerUUIDs;
|
|
MGlobal::executeCommand("GeoGetInstanceContainerUUIDsFromUUID \""+ strMyUID +"\"", astrContainerUUIDs, true);
|
|
|
|
if(astrContainerNames.length() > 0)
|
|
{
|
|
// I have containers, so add them
|
|
// Add one attribute for each container, for connection purposes
|
|
MFnDependencyNode obFnThisNode(obNode);
|
|
for(unsigned i=0; i<astrContainerNames.length(); i++)
|
|
{
|
|
// Get UI safe name
|
|
MString strContainerName;
|
|
MGlobal::executeCommand("rageValidateGEONameUI(\""+ astrContainerNames[i] +"\")", strContainerName, true);
|
|
|
|
// Do I already have this container attribute
|
|
if(obFnThisNode.findPlug("rageGeoContainer_"+ strContainerName).isNull())
|
|
{
|
|
// Add the attribute
|
|
MFnTypedAttribute nAttr;
|
|
MStatus status;
|
|
MObject obAttribute = nAttr.create( "rageGeoContainer_"+ strContainerName, "rageGeoContainer_"+ strContainerName +"s", MFnData::kString, MObject::kNullObj, &status );
|
|
nAttr.setStorable( true );
|
|
nAttr.setHidden( true );
|
|
nAttr.setReadable( true );
|
|
nAttr.setWritable( true );
|
|
nAttr.setInternal( false );
|
|
|
|
MDGModifier obModifier;
|
|
obModifier.addAttribute(obNode, obAttribute);
|
|
obModifier.doIt();
|
|
|
|
// Set the value
|
|
MPlug obContainerPlug(obNode, obAttribute);
|
|
// Displayf("Setting value of container attribute %s to be %s", obContainerPlug.name().asChar(), astrContainerUUIDs[i].asChar());
|
|
obContainerPlug.setValue(astrContainerUUIDs[i]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// ActDumb is used to turn off all the clever interfacing with the GEO Dataset, this is required to manipulate the nodes when loading scenes
|
|
bool rageMayaGeoInstance::ActDumb()
|
|
{
|
|
if(OldSceneIsBeingCleared()) return true;
|
|
if(NewSceneIsBeingOpened()) return true;
|
|
if(MFileIO::isReadingFile()) return true;
|
|
if(m_bNodeWasCreatedDuringFileOpenSoKillMe) return true;
|
|
// int bActDumb;
|
|
// MGlobal::executeCommand("rageGeoInstance.ActDumb()", bActDumb, true);
|
|
// if(bActDumb) return true;
|
|
return false;
|
|
}
|
|
|
|
void rageMayaGeoInstance::SetToNewInstanceOfType(const MObject& obNode, const MString& strGeoType)
|
|
{
|
|
// Get plugs
|
|
MStatus obStatus;
|
|
MFnDependencyNode obFnNode(obNode);
|
|
MPlug obGeoInstanceUIDPlug = obFnNode.findPlug("rageGeoInstanceUID");
|
|
MPlug obGeoInstanceNamePlug = obFnNode.findPlug("rageGeoInstanceName");
|
|
MPlug obGeoInstanceTypePlug = obFnNode.findPlug("rageGeoInstanceType");
|
|
|
|
// Create new GEO Instance
|
|
MStringArray astrNewNameAndUUID;
|
|
MGlobal::executeCommand("GeoCreateInstanceOfType \""+ strGeoType +"\"", astrNewNameAndUUID, true, false);
|
|
|
|
// Set Attrs
|
|
MString strType = strGeoType;
|
|
obGeoInstanceUIDPlug.setLocked(false);
|
|
obGeoInstanceNamePlug.setLocked(false);
|
|
obGeoInstanceTypePlug.setLocked(false);
|
|
obGeoInstanceNamePlug.setValue(astrNewNameAndUUID[0]);
|
|
obGeoInstanceUIDPlug.setValue(astrNewNameAndUUID[1]);
|
|
obGeoInstanceTypePlug.setValue(strType);
|
|
obGeoInstanceUIDPlug.setLocked(true);
|
|
obGeoInstanceNamePlug.setLocked(true);
|
|
obGeoInstanceTypePlug.setLocked(true);
|
|
|
|
// Update the container parameters
|
|
UpdateContainerParameters(obNode);
|
|
|
|
// Update the graphical representation
|
|
GiveGraphicalRepresentation(obNode);
|
|
}
|
|
|
|
void rageMayaGeoInstance::HuntColladaFiles(const MString& obFolder, MStringArray& astrColladaFiles)
|
|
{
|
|
// Get all the Collada files in this folder
|
|
LPWIN32_FIND_DATAA pData = new WIN32_FIND_DATAA();
|
|
char acSearchString[512];
|
|
strcpy_s(acSearchString, obFolder.asChar());
|
|
strcat_s(acSearchString, "/*.dae");
|
|
HANDLE fHandle = FindFirstFileA(acSearchString, pData);
|
|
while(fHandle != INVALID_HANDLE_VALUE)
|
|
{
|
|
if( (pData->cFileName[0] != '.') &&
|
|
(!(pData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) )
|
|
{
|
|
// Bingo! Found a collada file
|
|
astrColladaFiles.append(obFolder +"/"+ pData->cFileName);
|
|
}
|
|
if(!FindNextFileA(fHandle, pData))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Recurse
|
|
strcpy_s(acSearchString, obFolder.asChar());
|
|
strcat_s(acSearchString, "/*");
|
|
fHandle = FindFirstFileA(acSearchString, pData);
|
|
while(fHandle != INVALID_HANDLE_VALUE)
|
|
{
|
|
if((pData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && (pData->cFileName[0] != '.'))
|
|
{
|
|
// Bingo! Found a folder
|
|
HuntColladaFiles(obFolder +"/"+ pData->cFileName, astrColladaFiles);
|
|
}
|
|
if(!FindNextFileA(fHandle, pData))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
delete pData;
|
|
}
|
|
|
|
void rageMayaGeoInstance::GiveGraphicalRepresentation(const MObject& obNode)
|
|
{
|
|
MStatus obStatus;
|
|
MFnDependencyNode obFnNode(obNode);
|
|
|
|
// Get type
|
|
MPlug obGeoInstanceTypePlug = obFnNode.findPlug("rageGeoInstanceType");
|
|
MString strGeoType;
|
|
obGeoInstanceTypePlug.getValue(strGeoType);
|
|
// cout<<"strGeoType = "<<strGeoType.asChar()<<endl;
|
|
|
|
// Is there a proxy?
|
|
MStringArray astrColladaFiles;
|
|
MString strBaseGeoFolder = rageGeoDataSetCommands::GetBaseGeoFolder();
|
|
// cout<<"strBaseGeoFolder = "<<strBaseGeoFolder.asChar()<<endl;
|
|
|
|
MString strProxyFile = strBaseGeoFolder +"GEOInstanceProxies/"+ strGeoType +".dae";
|
|
MFileObject obProxyFile;
|
|
obProxyFile.setFullName(strProxyFile);
|
|
if(obProxyFile.exists())
|
|
{
|
|
// Got a proxy file, so use it
|
|
astrColladaFiles.append(strProxyFile);
|
|
}
|
|
else
|
|
{
|
|
// No proxy found, so look elsewhere
|
|
HuntColladaFiles(strBaseGeoFolder +"GEOTypes/"+ strGeoType, astrColladaFiles);
|
|
}
|
|
|
|
// Add all the collada file
|
|
for(unsigned int c=0; c<astrColladaFiles.length(); c++)
|
|
{
|
|
// Create node
|
|
MDagModifier obDagModifier;
|
|
MObject obColladaNode = obDagModifier.createNode("rageMayaColladaLocator", obNode);
|
|
obDagModifier.doIt();
|
|
|
|
// Set attr
|
|
MFnDependencyNode obFnColladaNode(obColladaNode);
|
|
MPlug obColladaPathAndFilenamePlug = obFnColladaNode.findPlug("ColladaPathAndFilename");
|
|
obColladaPathAndFilenamePlug.setValue(astrColladaFiles[c]);
|
|
}
|
|
|
|
// Finally layer me
|
|
MString strGeoTemplateName = rageGeoDataSetCommands::GetTemplateNameFromTypeName(strGeoType);
|
|
|
|
// Does a layer exist with this name?
|
|
MObject obLayerNode = MObject::kNullObj;
|
|
for(MItDependencyNodes obIt(MFn::kDisplayLayer); !obIt.isDone(); obIt.next())
|
|
{
|
|
// Does it have a GEO template attribute?
|
|
MPlug obGeoTemplatePlug = MFnDependencyNode(obIt.item()).findPlug("rageGeoTemplateLayer");
|
|
if(!obGeoTemplatePlug.isNull())
|
|
{
|
|
// Got the attribute, do I care?
|
|
MString strGeoTemplateOnThisLayer;
|
|
obGeoTemplatePlug.getValue(strGeoTemplateOnThisLayer);
|
|
if(strGeoTemplateOnThisLayer == strGeoTemplateName)
|
|
{
|
|
// Bingo!
|
|
obLayerNode = obIt.item();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(obLayerNode == MObject::kNullObj)
|
|
{
|
|
// No layer found, so create one
|
|
MString strLayerNodeName;
|
|
MGlobal::executeCommand("createDisplayLayer -name \""+ strGeoTemplateName +"\" -empty", strLayerNodeName, true);
|
|
MSelectionList obTempSelectionList;
|
|
obStatus = obTempSelectionList.add(strLayerNodeName);
|
|
obStatus = obTempSelectionList.getDependNode(0, obLayerNode);
|
|
|
|
// Add the attribute
|
|
MFnTypedAttribute nAttr;
|
|
MStatus status;
|
|
MObject obAttribute = nAttr.create( "rageGeoTemplateLayer", "rageGTempLayer", MFnData::kString, MObject::kNullObj, &status );
|
|
nAttr.setStorable( true );
|
|
nAttr.setHidden( true );
|
|
nAttr.setReadable( true );
|
|
nAttr.setWritable( true );
|
|
nAttr.setInternal( false );
|
|
|
|
MDGModifier obModifier;
|
|
obModifier.addAttribute(obLayerNode, obAttribute);
|
|
obModifier.doIt();
|
|
|
|
// Set the value
|
|
MPlug obGeoTemplatePlug = MFnDependencyNode(obLayerNode).findPlug("rageGeoTemplateLayer");
|
|
obGeoTemplatePlug.setValue(strGeoTemplateName);
|
|
|
|
// Give it a random colour
|
|
MPlug obColourPlug = MFnDependencyNode(obLayerNode).findPlug("color");
|
|
int iRandomColor = 4 + (rand() % 27);
|
|
// cout<<"iRandomColor = "<<iRandomColor<<endl;
|
|
obColourPlug.setValue(iRandomColor);
|
|
}
|
|
|
|
// Add this geo to the layer
|
|
MGlobal::executeCommand("editDisplayLayerMembers -noRecurse "+ MFnDependencyNode(obLayerNode).name() +" {\""+ obFnNode.name() +"\"}", true);
|
|
}
|
|
|