makepanda: Remove Autodesk Maya plug-ins

These now live at https://github.com/panda3d/maya-egg

Fixes #1584
This commit is contained in:
rdb 2024-08-13 11:06:04 +02:00
parent fff9ea594c
commit ad4ecbcc16
60 changed files with 3 additions and 15778 deletions

View File

@ -86,7 +86,7 @@ PkgListSet(["PYTHON", "DIRECT", # Python support
"ODE", "BULLET", "PANDAPHYSICS", # Physics
"SPEEDTREE", # SpeedTree
"ZLIB", "PNG", "JPEG", "TIFF", "OPENEXR", "SQUISH", # 2D Formats support
] + MAYAVERSIONS + [ "FCOLLADA", "ASSIMP", "EGG", # 3D Formats support
"FCOLLADA", "ASSIMP", "EGG", # 3D Formats support
"FREETYPE", "HARFBUZZ", # Text rendering
"VRPN", "OPENSSL", # Transport
"FFTW", # Algorithm helpers
@ -522,7 +522,6 @@ LoadDependencyCache()
MakeBuildTree()
SdkLocateDirectX(STRDXSDKVERSION)
SdkLocateMaya()
SdkLocateMacOSX(OSX_ARCHS)
SdkLocatePython(False)
SdkLocateWindows(WINDOWS_SDK)
@ -530,7 +529,6 @@ SdkLocateSpeedTree()
SdkLocateAndroid()
SdkAutoDisableDirectX()
SdkAutoDisableMaya()
SdkAutoDisableSpeedTree()
if not PkgSkip("PYTHON") and SDK["PYTHONVERSION"] == "python2.7":
@ -581,11 +579,7 @@ if (COMPILER == "MSVC"):
SmartPkgEnable("EIGEN", "eigen3", (), ("Eigen/Dense",), target_pkg = 'ALWAYS')
for pkg in PkgListGet():
if not PkgSkip(pkg):
if (pkg[:4]=="MAYA"):
IncDirectory(pkg, SDK[pkg] + "/include")
DefSymbol(pkg, "MAYAVERSION", pkg)
DefSymbol(pkg, "MLIBRARY_DONTUSE_MFC_MANIFEST", "")
elif (pkg[:2]=="DX"):
if (pkg[:2]=="DX"):
IncDirectory(pkg, SDK[pkg] + "/include")
elif GetThirdpartyDir() is not None:
IncDirectory(pkg, GetThirdpartyDir() + pkg.lower() + "/include")
@ -761,12 +755,6 @@ if (COMPILER == "MSVC"):
if not os.path.isfile(path):
path = GetThirdpartyDir() + "opus/lib/{0}.lib".format(lib)
LibName("OPUS", path)
for pkg in MAYAVERSIONS:
if not PkgSkip(pkg):
LibName(pkg, '"' + SDK[pkg] + '/lib/Foundation.lib"')
LibName(pkg, '"' + SDK[pkg] + '/lib/OpenMaya.lib"')
LibName(pkg, '"' + SDK[pkg] + '/lib/OpenMayaAnim.lib"')
LibName(pkg, '"' + SDK[pkg] + '/lib/OpenMayaUI.lib"')
if not PkgSkip("SPEEDTREE"):
if GetTargetArch() == 'x64':
@ -1065,28 +1053,6 @@ if (COMPILER=="GCC"):
elif not PkgSkip("X11"):
LibDirectory("ALWAYS", "/usr/X11R6/lib")
for pkg in MAYAVERSIONS:
if (PkgSkip(pkg)==0 and (pkg in SDK)):
if (GetHost() == "darwin"):
# Sheesh, Autodesk really can't make up their mind
# regarding the location of the Maya devkit on macOS.
if (os.path.isdir(SDK[pkg] + "/Maya.app/Contents/lib")):
LibDirectory(pkg, SDK[pkg] + "/Maya.app/Contents/lib")
if (os.path.isdir(SDK[pkg] + "/Maya.app/Contents/MacOS")):
LibDirectory(pkg, SDK[pkg] + "/Maya.app/Contents/MacOS")
if (os.path.isdir(SDK[pkg] + "/lib")):
LibDirectory(pkg, SDK[pkg] + "/lib")
if (os.path.isdir(SDK[pkg] + "/Maya.app/Contents/include/maya")):
IncDirectory(pkg, SDK[pkg] + "/Maya.app/Contents/include")
if (os.path.isdir(SDK[pkg] + "/devkit/include/maya")):
IncDirectory(pkg, SDK[pkg] + "/devkit/include")
if (os.path.isdir(SDK[pkg] + "/include/maya")):
IncDirectory(pkg, SDK[pkg] + "/include")
else:
LibDirectory(pkg, SDK[pkg] + "/lib")
IncDirectory(pkg, SDK[pkg] + "/include")
DefSymbol(pkg, "MAYAVERSION", pkg)
if GetTarget() == 'darwin':
LibName("ALWAYS", "-framework AppKit")
LibName("IOKIT", "-framework IOKit")
@ -1114,40 +1080,6 @@ if (COMPILER=="GCC"):
LibName("JNIGRAPHICS", '-ljnigraphics')
LibName("OPENSLES", '-lOpenSLES')
for pkg in MAYAVERSIONS:
if (PkgSkip(pkg)==0 and (pkg in SDK)):
if GetTarget() == 'darwin':
LibName(pkg, "-Wl,-rpath,/Applications/Autodesk/" + pkg.lower() + "/Maya.app/Contents/MacOS")
else:
LibName(pkg, "-Wl,-rpath," + SDK[pkg] + "/lib")
LibName(pkg, "-lOpenMaya")
LibName(pkg, "-lOpenMayaAnim")
LibName(pkg, "-lOpenMayaUI")
LibName(pkg, "-lAnimSlice")
LibName(pkg, "-lDeformSlice")
LibName(pkg, "-lModifiers")
LibName(pkg, "-lDynSlice")
LibName(pkg, "-lKinSlice")
LibName(pkg, "-lModelSlice")
LibName(pkg, "-lNurbsSlice")
LibName(pkg, "-lPolySlice")
LibName(pkg, "-lProjectSlice")
LibName(pkg, "-lImage")
LibName(pkg, "-lShared")
LibName(pkg, "-lTranslators")
LibName(pkg, "-lDataModel")
LibName(pkg, "-lRenderModel")
LibName(pkg, "-lNurbsEngine")
LibName(pkg, "-lDependEngine")
LibName(pkg, "-lCommandEngine")
LibName(pkg, "-lFoundation")
if pkg not in ("MAYA2020", "MAYA2022"):
LibName(pkg, "-lIMFbase")
if GetTarget() != 'darwin':
LibName(pkg, "-lOpenMayalib")
else:
LibName(pkg, "-dylib_file /System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib:/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib")
DefSymbol("WITHINPANDA", "WITHIN_PANDA", "1")
if GetLinkAllStatic() or GetTarget() == 'emscripten':
DefSymbol("ALWAYS", "LINK_ALL_STATIC")
@ -2394,7 +2326,6 @@ DTOOL_CONFIG=[
("PYTHON_FRAMEWORK", 'UNDEF', 'UNDEF'),
("COMPILE_IN_DEFAULT_FONT", '1', '1'),
("STDFLOAT_DOUBLE", 'UNDEF', 'UNDEF'),
("HAVE_MAYA", '1', '1'),
("REPORT_OPENSSL_ERRORS", '1', '1'),
("USE_PANDAFILESTREAM", '1', '1'),
("USE_DELETED_CHAIN", '1', '1'),
@ -3268,10 +3199,6 @@ else:
CopyFile(GetOutputDir()+"/", "doc/LICENSE")
CopyFile(GetOutputDir()+"/", "doc/ReleaseNotes")
if not PkgSkip("PANDATOOL"):
CopyAllFiles(GetOutputDir()+"/plugins/", "pandatool/src/scripts/", ".mel")
CopyAllFiles(GetOutputDir()+"/plugins/", "pandatool/src/scripts/", ".ms")
if not PkgSkip("PYTHON") and os.path.isdir(GetThirdpartyBase() + "/Pmw"):
CopyTree(GetOutputDir() + "/Pmw", GetThirdpartyBase() + "/Pmw", exclude=["Pmw_1_3", "Pmw_1_3_3"])
@ -3437,8 +3364,6 @@ if not PkgSkip("PANDATOOL"):
CopyAllHeaders('pandatool/src/lwo')
CopyAllHeaders('pandatool/src/lwoegg')
CopyAllHeaders('pandatool/src/lwoprogs')
CopyAllHeaders('pandatool/src/maya')
CopyAllHeaders('pandatool/src/mayaegg')
CopyAllHeaders('pandatool/src/objegg')
CopyAllHeaders('pandatool/src/objprogs')
CopyAllHeaders('pandatool/src/vrml')
@ -5740,34 +5665,6 @@ if not PkgSkip("PANDATOOL"):
TargetAdd('lwo2egg.exe', input=COMMON_EGG2X_LIBS)
TargetAdd('lwo2egg.exe', opts=['ADVAPI'])
#
# DIRECTORY: pandatool/src/maya/
#
for VER in MAYAVERSIONS:
VNUM = VER[4:]
if PkgSkip(VER) or PkgSkip("PANDATOOL"):
continue
OPTS=['DIR:pandatool/src/maya', VER]
TargetAdd('maya'+VNUM+'_composite1.obj', opts=OPTS, input='p3maya_composite1.cxx')
TargetAdd('libmaya'+VNUM+'.lib', input='maya'+VNUM+'_composite1.obj')
#
# DIRECTORY: pandatool/src/mayaegg/
#
for VER in MAYAVERSIONS:
VNUM = VER[4:]
if PkgSkip(VER) or PkgSkip("PANDATOOL") or PkgSkip("EGG"):
continue
OPTS=['DIR:pandatool/src/mayaegg', 'DIR:pandatool/src/maya', VER]
TargetAdd('mayaegg'+VNUM+'_loader.obj', opts=OPTS, input='mayaEggLoader.cxx')
TargetAdd('mayaegg'+VNUM+'_composite1.obj', opts=OPTS, input='p3mayaegg_composite1.cxx')
TargetAdd('libmayaegg'+VNUM+'.lib', input='mayaegg'+VNUM+'_loader.obj')
TargetAdd('libmayaegg'+VNUM+'.lib', input='mayaegg'+VNUM+'_composite1.obj')
#
# DIRECTORY: pandatool/src/vrml/
#
@ -5972,127 +5869,6 @@ if not PkgSkip("PANDATOOL"):
TargetAdd('x2egg.exe', input=COMMON_EGG2X_LIBS)
TargetAdd('x2egg.exe', opts=['ADVAPI'])
#
# DIRECTORY: pandatool/src/mayaprogs/
#
MAYA_BUILT = False
for VER in MAYAVERSIONS:
VNUM = VER[4:]
if PkgSkip(VER) or PkgSkip("PANDATOOL") or PkgSkip("EGG"):
continue
if GetTarget() == 'darwin':
if int(VNUM) < 2009:
# No x86_64 support.
continue
if tuple(OSX_ARCHS) == ('arm64',):
# No arm64 support.
continue
ARCH_OPTS = ['NOARCH:ARM64']
else:
ARCH_OPTS = []
MAYA_BUILT = True
OPTS=['DIR:pandatool/src/mayaprogs', 'DIR:pandatool/src/maya', 'DIR:pandatool/src/mayaegg', 'BUILDING:MISC', VER] + ARCH_OPTS
TargetAdd('mayaeggimport'+VNUM+'_mayaeggimport.obj', opts=OPTS, input='mayaEggImport.cxx')
TargetAdd('mayaeggimport'+VNUM+'.mll', input='mayaegg'+VNUM+'_loader.obj')
TargetAdd('mayaeggimport'+VNUM+'.mll', input='mayaeggimport'+VNUM+'_mayaeggimport.obj')
TargetAdd('mayaeggimport'+VNUM+'.mll', input='libpandaegg.dll')
TargetAdd('mayaeggimport'+VNUM+'.mll', input=COMMON_PANDA_LIBS)
TargetAdd('mayaeggimport'+VNUM+'.mll', opts=['ADVAPI', VER]+ARCH_OPTS)
TargetAdd('mayaloader'+VNUM+'_config_mayaloader.obj', opts=OPTS, input='config_mayaloader.cxx')
TargetAdd('libp3mayaloader'+VNUM+'.dll', input='mayaloader'+VNUM+'_config_mayaloader.obj')
TargetAdd('libp3mayaloader'+VNUM+'.dll', input='libmayaegg'+VNUM+'.lib')
TargetAdd('libp3mayaloader'+VNUM+'.dll', input='libp3ptloader.dll')
TargetAdd('libp3mayaloader'+VNUM+'.dll', input='libmaya'+VNUM+'.lib')
TargetAdd('libp3mayaloader'+VNUM+'.dll', input='libp3fltegg.lib')
TargetAdd('libp3mayaloader'+VNUM+'.dll', input='libp3flt.lib')
TargetAdd('libp3mayaloader'+VNUM+'.dll', input='libp3lwoegg.lib')
TargetAdd('libp3mayaloader'+VNUM+'.dll', input='libp3lwo.lib')
TargetAdd('libp3mayaloader'+VNUM+'.dll', input='libp3dxfegg.lib')
TargetAdd('libp3mayaloader'+VNUM+'.dll', input='libp3dxf.lib')
TargetAdd('libp3mayaloader'+VNUM+'.dll', input='libp3objegg.lib')
TargetAdd('libp3mayaloader'+VNUM+'.dll', input='libp3vrmlegg.lib')
TargetAdd('libp3mayaloader'+VNUM+'.dll', input='libp3vrml.lib')
TargetAdd('libp3mayaloader'+VNUM+'.dll', input='libp3xfileegg.lib')
TargetAdd('libp3mayaloader'+VNUM+'.dll', input='libp3xfile.lib')
TargetAdd('libp3mayaloader'+VNUM+'.dll', input='libp3eggbase.lib')
TargetAdd('libp3mayaloader'+VNUM+'.dll', input='libp3progbase.lib')
TargetAdd('libp3mayaloader'+VNUM+'.dll', input='libp3converter.lib')
TargetAdd('libp3mayaloader'+VNUM+'.dll', input='libp3pandatoolbase.lib')
TargetAdd('libp3mayaloader'+VNUM+'.dll', input='libpandaegg.dll')
TargetAdd('libp3mayaloader'+VNUM+'.dll', input=COMMON_PANDA_LIBS)
TargetAdd('libp3mayaloader'+VNUM+'.dll', opts=['ADVAPI', VER]+ARCH_OPTS)
TargetAdd('mayapview'+VNUM+'_mayaPview.obj', opts=OPTS, input='mayaPview.cxx')
TargetAdd('libmayapview'+VNUM+'.mll', input='mayapview'+VNUM+'_mayaPview.obj')
TargetAdd('libmayapview'+VNUM+'.mll', input='libmayaegg'+VNUM+'.lib')
TargetAdd('libmayapview'+VNUM+'.mll', input='libmaya'+VNUM+'.lib')
TargetAdd('libmayapview'+VNUM+'.mll', input='libp3framework.dll')
TargetAdd('libmayapview'+VNUM+'.mll', input=COMMON_EGG2X_LIBS)
TargetAdd('libmayapview'+VNUM+'.mll', opts=['ADVAPI', VER]+ARCH_OPTS)
TargetAdd('mayaprogs'+VNUM+'_eggToMaya.obj', opts=OPTS, input='eggToMaya.cxx')
TargetAdd('mayaprogs'+VNUM+'_mayaToEgg.obj', opts=OPTS, input='mayaToEgg.cxx')
TargetAdd('mayaprogs_mayaConversionServer.obj', opts=OPTS, input='mayaConversionServer.cxx')
TargetAdd('maya2egg'+VNUM+'_mayaToEggBin.obj', opts=OPTS, input='mayaToEggBin.cxx')
TargetAdd('maya2egg'+VNUM+'_bin.exe', input='mayaprogs'+VNUM+'_eggToMaya.obj')
TargetAdd('maya2egg'+VNUM+'_bin.exe', input='mayaprogs'+VNUM+'_mayaToEgg.obj')
TargetAdd('maya2egg'+VNUM+'_bin.exe', input='mayaprogs_mayaConversionServer.obj')
TargetAdd('maya2egg'+VNUM+'_bin.exe', input='maya2egg'+VNUM+'_mayaToEggBin.obj')
TargetAdd('maya2egg'+VNUM+'_bin.exe', input='libmayaegg'+VNUM+'.lib')
TargetAdd('maya2egg'+VNUM+'_bin.exe', input='libmaya'+VNUM+'.lib')
TargetAdd('maya2egg'+VNUM+'_bin.exe', input=COMMON_EGG2X_LIBS)
TargetAdd('maya2egg'+VNUM+'_bin.exe', opts=['ADVAPI', VER]+ARCH_OPTS)
TargetAdd('egg2maya'+VNUM+'_eggToMayaBin.obj', opts=OPTS, input='eggToMayaBin.cxx')
TargetAdd('egg2maya'+VNUM+'_bin.exe', input='mayaprogs'+VNUM+'_eggToMaya.obj')
TargetAdd('egg2maya'+VNUM+'_bin.exe', input='mayaprogs'+VNUM+'_mayaToEgg.obj')
TargetAdd('egg2maya'+VNUM+'_bin.exe', input='mayaprogs_mayaConversionServer.obj')
TargetAdd('egg2maya'+VNUM+'_bin.exe', input='egg2maya'+VNUM+'_eggToMayaBin.obj')
TargetAdd('egg2maya'+VNUM+'_bin.exe', input='libmayaegg'+VNUM+'.lib')
TargetAdd('egg2maya'+VNUM+'_bin.exe', input='libmaya'+VNUM+'.lib')
TargetAdd('egg2maya'+VNUM+'_bin.exe', input=COMMON_EGG2X_LIBS)
TargetAdd('egg2maya'+VNUM+'_bin.exe', opts=['ADVAPI', VER]+ARCH_OPTS)
TargetAdd('mayasavepview'+VNUM+'_mayaSavePview.obj', opts=OPTS, input='mayaSavePview.cxx')
TargetAdd('libmayasavepview'+VNUM+'.mll', input='mayasavepview'+VNUM+'_mayaSavePview.obj')
TargetAdd('libmayasavepview'+VNUM+'.mll', opts=['ADVAPI', VER]+ARCH_OPTS)
TargetAdd('mayapath'+VNUM+'.obj', opts=OPTS, input='mayapath.cxx')
TargetAdd('maya2egg'+VNUM+'.exe', input='mayapath'+VNUM+'.obj')
TargetAdd('maya2egg'+VNUM+'.exe', input='libpandaexpress.dll')
TargetAdd('maya2egg'+VNUM+'.exe', input=COMMON_DTOOL_LIBS)
TargetAdd('maya2egg'+VNUM+'.exe', opts=['ADVAPI']+ARCH_OPTS)
TargetAdd('egg2maya'+VNUM+'.exe', input='mayapath'+VNUM+'.obj')
TargetAdd('egg2maya'+VNUM+'.exe', input='libpandaexpress.dll')
TargetAdd('egg2maya'+VNUM+'.exe', input=COMMON_DTOOL_LIBS)
TargetAdd('egg2maya'+VNUM+'.exe', opts=['ADVAPI']+ARCH_OPTS)
if MAYA_BUILT:
OPTS=['DIR:pandatool/src/mayaprogs', 'DIR:pandatool/src/maya', 'DIR:pandatool/src/mayaegg', 'BUILDING:MISC', 'NOARCH:ARM64']
TargetAdd('mayaprogs_mayaConversionClient.obj', opts=OPTS, input='mayaConversionClient.cxx')
TargetAdd('maya2egg_mayaToEggClient.obj', opts=OPTS, input='mayaToEggClient.cxx')
TargetAdd('maya2egg_client.exe', input='mayaprogs_mayaConversionClient.obj')
TargetAdd('maya2egg_client.exe', input='maya2egg_mayaToEggClient.obj')
TargetAdd('maya2egg_client.exe', input=COMMON_EGG2X_LIBS)
TargetAdd('maya2egg_client.exe', opts=['NOARCH:ARM64'])
TargetAdd('egg2maya_eggToMayaClient.obj', opts=OPTS, input='eggToMayaClient.cxx')
TargetAdd('egg2maya_client.exe', input='mayaprogs_mayaConversionClient.obj')
TargetAdd('egg2maya_client.exe', input='egg2maya_eggToMayaClient.obj')
TargetAdd('egg2maya_client.exe', input=COMMON_EGG2X_LIBS)
TargetAdd('egg2maya_client.exe', opts=['NOARCH:ARM64'])
#
# DIRECTORY: contrib/src/ai/
#

View File

@ -93,39 +93,12 @@ MSVCVERSIONINFO = {
########################################################################
##
## Maya and Max Version List (with registry keys)
## DirectX Version List
##
########################################################################
MAYAVERSIONINFO = [("MAYA6", "6.0"),
("MAYA65", "6.5"),
("MAYA7", "7.0"),
("MAYA8", "8.0"),
("MAYA85", "8.5"),
("MAYA2008","2008"),
("MAYA2009","2009"),
("MAYA2010","2010"),
("MAYA2011","2011"),
("MAYA2012","2012"),
("MAYA2013","2013"),
("MAYA20135","2013.5"),
("MAYA2014","2014"),
("MAYA2015","2015"),
("MAYA2016","2016"),
("MAYA20165","2016.5"),
("MAYA2017","2017"),
("MAYA2018","2018"),
("MAYA2019","2019"),
("MAYA2020","2020"),
("MAYA2022","2022"),
]
MAYAVERSIONS = []
DXVERSIONS = ["DX9"]
for (ver,key) in MAYAVERSIONINFO:
MAYAVERSIONS.append(ver)
########################################################################
##
## Potentially Conflicting Files
@ -2116,32 +2089,6 @@ def SdkLocateDirectX( strMode = 'default' ):
if ("DX9" in SDK):
SDK["DIRECTCAM"] = SDK["DX9"]
def SdkLocateMaya():
for (ver, key) in MAYAVERSIONINFO:
if (PkgSkip(ver)==0 and ver not in SDK):
GetSdkDir(ver.lower().replace("x",""), ver)
if (not ver in SDK):
if (GetHost() == "windows"):
for dev in ["Alias|Wavefront","Alias","Autodesk"]:
fullkey="SOFTWARE\\"+dev+"\\Maya\\"+key+"\\Setup\\InstallPath"
res = GetRegistryKey(fullkey, "MAYA_INSTALL_LOCATION", override64=False)
if (res != 0):
res = res.replace("\\", "/").rstrip("/")
SDK[ver] = res
elif (GetHost() == "darwin"):
ddir = "/Applications/Autodesk/maya"+key
if (os.path.isdir(ddir)): SDK[ver] = ddir
else:
if (GetTargetArch() in ("x86_64", "amd64")):
ddir1 = "/usr/autodesk/maya"+key+"-x64"
ddir2 = "/usr/aw/maya"+key+"-x64"
else:
ddir1 = "/usr/autodesk/maya"+key
ddir2 = "/usr/aw/maya"+key
if (os.path.isdir(ddir1)): SDK[ver] = ddir1
elif (os.path.isdir(ddir2)): SDK[ver] = ddir2
def SdkLocatePython(prefer_thirdparty_python=False):
if PkgSkip("PYTHON"):
# We're not compiling with Python support. We still need to set this
@ -2687,16 +2634,6 @@ def SdkAutoDisableDirectX():
else:
WARNINGS.append("Using "+ver+" sdk: "+SDK[ver])
def SdkAutoDisableMaya():
for (ver,key) in MAYAVERSIONINFO:
if (ver not in SDK) and (PkgSkip(ver)==0):
if (GetHost() == "windows"):
WARNINGS.append("The registry does not appear to contain a pointer to the "+ver+" SDK.")
else:
WARNINGS.append("I cannot locate SDK for "+ver)
WARNINGS.append("I have automatically added this command-line option: --no-"+ver.lower())
PkgDisable(ver)
def SdkAutoDisableSpeedTree():
if ("SPEEDTREE" not in SDK) and (PkgSkip("SPEEDTREE")==0):
PkgDisable("SPEEDTREE")

View File

@ -1,48 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file config_maya.cxx
* @author drose
* @date 2002-04-15
*/
#include "config_maya.h"
#include "dconfig.h"
Configure(config_maya);
NotifyCategoryDef(maya, "");
ConfigureFn(config_maya) {
init_libmaya();
}
ConfigVariableInt init_maya_repeat_count
("init-maya-repeat-count", 5,
PRC_DESC("The number of times to attempt to initialize Maya and acquire the "
"Maya license before giving up."));
ConfigVariableDouble init_maya_timeout
("init-maya-timeout", 5.0,
PRC_DESC("The number of seconds to wait between attempts to acquire the "
"Maya license."));
/**
* Initializes the library. This must be called at least once before any of
* the functions or classes in this library can be used. Normally it will be
* called by the static initializers and need not be called explicitly, but
* special cases exist.
*/
void
init_libmaya() {
static bool initialized = false;
if (initialized) {
return;
}
initialized = true;
}

View File

@ -1,29 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file config_maya.h
* @author drose
* @date 2002-04-15
*/
#ifndef CONFIG_MAYA_H
#define CONFIG_MAYA_H
#include "pandatoolbase.h"
#include "notifyCategoryProxy.h"
#include "configVariableInt.h"
#include "configVariableDouble.h"
NotifyCategoryDeclNoExport(maya);
extern ConfigVariableInt init_maya_repeat_count;
extern ConfigVariableDouble init_maya_timeout;
extern void init_libmaya();
#endif

View File

@ -1,49 +0,0 @@
//
// This is a sample mel script to flag a Maya node with at least
// one eggObjectTypes* attribute. These attributes are used to tag
// geometry with special meaning to Panda. There are a handful of
// attribute values that are predefined within Panda, but you can also
// make up your own attribute values, and define an arbitrary egg
// syntax to associate with each one.
//
// Each type you invoke this script to add an attribute to a node, it
// adds a new pull-down menu on the node attributes list, giving all
// of the values listed in $eggFlags, below. You can then select one
// of these values to assign to the node. If you need to assign
// multiple different values to the same node, run this script
// multiple times.
//
// The maya2egg converter will look for eggObjectTypes* attributes and
// insert the line "<ObjectType> { value }" for each one found, where
// "value" is the particular value you have selected from the
// pull-down menu. Eventually, when the egg loader loads the egg file
// into Panda (either by loading the egg file interactively into a
// Panda session, or via an egg2bam command), the <ObjectType> line
// will be replaced with arbitrary egg syntax defined by your
// Config.prc file with a line like this:
//
// egg-object-type-value [your egg syntax here]
//
// See panda/src/configfiles/panda.prc.pp and
// direct/src/configfiles/direct.prc.pp for examples of this.
//
global proc eggObjectFlags() {
string $sel[] =`ls -sl`;
// Modify this line as needed to add your own object types.
string $eggFlags = "none:portal:polylight:seq24:seq12:indexed:model:dcs:barrier:sphere:tube:trigger:trigger-sphere:bubble:ghost:keep-all-uvsets";
for ($i in $sel) {
string $attrName = "eggObjectTypes";
string $object = ($i + "." + $attrName);
int $num = 1;
while (`objExists ($object + $num)`) {
$num++;
}
addAttr -ln ($attrName + $num) -k 1 -at "enum" -en ($eggFlags) $i;
}
}

View File

@ -1,428 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file mayaApi.cxx
* @author drose
* @date 2002-04-15
*/
#include "mayaApi.h"
#include "config_maya.h"
#include "string_utils.h"
#include "thread.h"
#include "pre_maya_include.h"
#include <maya/MGlobal.h>
#include <maya/MDistance.h>
#include <maya/MFileIO.h>
#include <maya/MLibrary.h>
#include <maya/MStatus.h>
#include <maya/MFnAnimCurve.h>
#include "post_maya_include.h"
#ifdef _WIN32
#include <direct.h> // for chdir()
#endif
using std::string;
PT(MayaApi) MayaApi::_global_api = nullptr;
// We need this bogus object just to force the application to link with
// OpenMayaAnim.lib; otherwise, Maya will complain (when compiled on Windows)
// that it is unable to find source plug 'ikRPsolver.msg'.
static MFnAnimCurve force_link_with_OpenMayaAnim;
/**
* Don't attempt to create this object directly; instead, use the open_api()
* method.
*/
MayaApi::
MayaApi(const string &program_name, bool view_license, bool revert_dir) {
if (program_name == "plug-in") {
// In this special case, we are invoking the code from within a plug-in,
// so we need not (and should not) call MLibrary::initialize().
_plug_in = true;
_is_valid = true;
return;
}
// Otherwise, if program_name is any other name, we are invoking the code
// from a standalone application and we do need to call
// MLibrary::initialize().
_plug_in = false;
// Beginning with Maya4.5, the call to initialize seems to change the
// current directory! Yikes!
// Furthermore, the current directory may change during the call to any Maya
// function! Egad!
_cwd = ExecutionEnvironment::get_cwd();
MStatus stat = MLibrary::initialize(false, (char *)program_name.c_str(), view_license);
int error_count = init_maya_repeat_count;
while (!stat && error_count > 1) {
stat.perror("MLibrary::initialize");
Thread::sleep(init_maya_timeout);
stat = MLibrary::initialize(false, (char *)program_name.c_str(), view_license);
--error_count;
}
// Restore the current directory. Ever since Maya 2010, there seems to be
// some bad mojo when you do this.
if( revert_dir ){
string dirname = _cwd.to_os_specific();
if (chdir(dirname.c_str()) < 0) {
maya_cat.warning()
<< "Unable to restore current directory to " << _cwd
<< " after initializing Maya.\n";
} else {
if (maya_cat.is_debug()) {
maya_cat.debug()
<< "Restored current directory to " << _cwd << "\n";
}
}
}
if (!stat) {
stat.perror("MLibrary::initialize");
_is_valid = false;
} else {
_is_valid = true;
}
}
/**
* Don't attempt to copy MayaApi objects. There should be only one of these
* in the world at a time.
*/
MayaApi::
MayaApi(const MayaApi &copy) {
nassertv(false);
}
/**
* Don't attempt to copy MayaApi objects. There should be only one of these
* in the world at a time.
*/
void MayaApi::
operator = (const MayaApi &copy) {
nassertv(false);
}
/**
*
*/
MayaApi::
~MayaApi() {
nassertv(_global_api == this);
if (_is_valid && !_plug_in) {
// Caution! Calling this function seems to call exit() somewhere within
// Maya code.
MLibrary::cleanup();
}
_global_api = nullptr;
}
/**
* Opens the Maya API, if it is not already open, and returns a pointer
* representing this connection. When you are done using the Maya API, let
* the pointer destruct.
*
* If program_name is supplied, it is passed to Maya as the name of the
* currently-executing program. Otherwise, the current program name is
* extracted from the execution environment, if possible. The special
* program_name "plug-in" is used for code that is intended to be invoked as a
* plug-in only; in this case, the maya library is not re-initialized.
*/
PT(MayaApi) MayaApi::
open_api(string program_name, bool view_license, bool revertdir) {
if (_global_api == nullptr) {
// We need to create a new MayaApi object.
if (program_name.empty()) {
program_name = ExecutionEnvironment::get_binary_name();
if (program_name.empty()) {
program_name = "Panda";
}
}
_global_api = new MayaApi(program_name, view_license, revertdir);
// Try to compare the string-formatted runtime version number with the
// numeric compile-time version number, so we can sanity check our runtime
// environment. (Sure would be nice if Maya provided an apples-to-apples
// comparison for us.)
// According to the Maya specs, the numeric value is derived by taking the
// Maya version number and deleting the '.' characters, while also
// ignoring everything after the second dot (and, for some reason,
// appending a 0).
string runtime_version = MGlobal::mayaVersion().asChar();
string simple_runtime_version = runtime_version;
runtime_version = trim(runtime_version);
// If the version number contains a space, stop there (that would be
// "service pack 1" or whatever).
size_t space = runtime_version.find(' ');
if (space != string::npos) {
runtime_version = runtime_version.substr(0, space);
}
int rtver_a, rtver_b;
size_t dot1 = runtime_version.find('.');
if (dot1 == string::npos) {
string_to_int(runtime_version, rtver_a);
rtver_b = 0;
} else {
string_to_int(runtime_version.substr(0, dot1), rtver_a);
size_t dot2 = runtime_version.find('.', dot1 + 1);
if (dot2 == string::npos) {
string_to_int(runtime_version.substr(dot1 + 1), rtver_b);
} else {
string_to_int(runtime_version.substr(dot1 + 1, dot2 - dot1 - 1), rtver_b);
simple_runtime_version = runtime_version.substr(0, dot2);
}
}
int runtime_version_int = rtver_a * 100 + rtver_b * 10;
if (maya_cat.is_debug()) {
maya_cat.debug()
<< "Compiled with Maya library version "
<< (MAYA_API_VERSION / 100) << "." << (MAYA_API_VERSION / 10) % 10
<< " (" << MAYA_API_VERSION << "); running with library version "
<< runtime_version << ".\n";
}
if (MAYA_API_VERSION / 10 != runtime_version_int / 10) {
maya_cat.warning()
<< "This program was compiled using Maya version "
<< (MAYA_API_VERSION / 100) << "." << (MAYA_API_VERSION / 10) % 10
<< ", but you are now running it with Maya version "
<< simple_runtime_version
<< ". The program may crash or produce incorrect results.\n\n";
}
}
return _global_api;
}
/**
* Returns true if the global API has been successfully opened and may be used, or
* false if the API has not created yet or if there is some problem.
*/
bool MayaApi::
is_api_valid() {
return _global_api != nullptr && _global_api->is_valid();
}
/**
* Returns true if the API has been successfully opened and may be used, or
* false if there is some problem.
*/
bool MayaApi::
is_valid() const {
return _is_valid;
}
#ifdef _WIN32
static string
back_to_front_slash(const string &str) {
string result = str;
string::iterator si;
for (si = result.begin(); si != result.end(); ++si) {
if ((*si) == '\\') {
(*si) = '/';
}
}
return result;
}
#endif // WIN32
/**
* Reads the indicated maya file into the global model space. Returns true if
* successful, false otherwise.
*/
bool MayaApi::
read(const Filename &filename) {
MFileIO::newFile(true);
maya_cat.info() << "Reading " << filename << "\n";
// Load the file into Maya. Maya seems to want forward slashes, even on
// Windows.
string os_filename = filename.to_os_generic();
string dirname = _cwd.to_os_specific();
if (maya_cat.is_debug()) {
maya_cat.debug() << "cwd(read:before): " << dirname.c_str() << std::endl;
}
MFileIO::newFile(true);
MStatus stat = MFileIO::open(os_filename.c_str());
// Beginning with Maya2008, the call to read seem to change the current
// directory specially if there is a refrence file! Yikes!
// Furthermore, the current directory may change during the call to any Maya
// function! Egad!
if (chdir(dirname.c_str()) < 0) {
maya_cat.warning()
<< "Unable to restore current directory after ::read to " << _cwd
<< " after initializing Maya.\n";
} else {
if (maya_cat.is_debug()) {
maya_cat.debug()
<< "Restored current directory after ::read to " << _cwd << "\n";
}
}
if (!stat) {
stat.perror(os_filename.c_str());
return false;
}
return true;
}
/**
* Writes the global model space to the indicated file. Returns true if
* successful, false otherwise.
*/
bool MayaApi::
write(const Filename &filename) {
maya_cat.info() << "Writing " << filename << "\n";
string os_filename = filename.to_os_generic();
string dirname = _cwd.to_os_specific();
if (maya_cat.is_debug()) {
maya_cat.debug() << "cwd(write:before): " << dirname.c_str() << std::endl;
}
const char *type = "mayaBinary";
string extension = filename.get_extension();
if (extension == "ma") {
type = "mayaAscii";
}
MStatus stat = MFileIO::saveAs(os_filename.c_str(), type, true);
if (!stat) {
stat.perror(os_filename.c_str());
return false;
}
// Beginning with Maya2008, the call to read seem to change the current
// directory specially if there is a refrence file! Yikes!
// Furthermore, the current directory may change during the call to any Maya
// function! Egad!
if (chdir(dirname.c_str()) < 0) {
maya_cat.warning()
<< "Unable to restore current directory after ::write to " << _cwd
<< " after initializing Maya.\n";
} else {
if (maya_cat.is_debug()) {
maya_cat.debug()
<< "Restored current directory after ::write to " << _cwd << "\n";
}
}
return true;
}
/**
* Resets the global model space to the empty state, for instance in
* preparation for building a new file. Returns true if successful, false
* otherwise.
*/
bool MayaApi::
clear() {
MStatus stat = MFileIO::newFile(true);
if (!stat) {
stat.perror("clear");
return false;
}
return true;
}
/**
* Returns Maya's internal units in effect.
*/
DistanceUnit MayaApi::
get_units() {
switch (MDistance::internalUnit()) {
case MDistance::kInches:
return DU_inches;
case MDistance::kFeet:
return DU_feet;
case MDistance::kYards:
return DU_yards;
case MDistance::kMiles:
return DU_statute_miles;
case MDistance::kMillimeters:
return DU_millimeters;
case MDistance::kCentimeters:
return DU_centimeters;
case MDistance::kKilometers:
return DU_kilometers;
case MDistance::kMeters:
return DU_meters;
default:
return DU_invalid;
}
}
/**
* Set Maya's UI units.
*/
void MayaApi::
set_units(DistanceUnit unit) {
switch (unit) {
case DU_inches:
MDistance::setUIUnit(MDistance::kInches);
break;
case DU_feet:
MDistance::setUIUnit(MDistance::kFeet);
break;
case DU_yards:
MDistance::setUIUnit(MDistance::kYards);
break;
case DU_statute_miles:
MDistance::setUIUnit(MDistance::kMiles);
break;
case DU_millimeters:
MDistance::setUIUnit(MDistance::kMillimeters);
break;
case DU_centimeters:
MDistance::setUIUnit(MDistance::kCentimeters);
break;
case DU_kilometers:
MDistance::setUIUnit(MDistance::kKilometers);
break;
case DU_meters:
MDistance::setUIUnit(MDistance::kMeters);
break;
default:
;
}
}
/**
* Returns Maya's internal coordinate system in effect.
*/
CoordinateSystem MayaApi::
get_coordinate_system() {
if (MGlobal::isYAxisUp()) {
return CS_yup_right;
} else {
return CS_zup_right;
}
}

View File

@ -1,58 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file mayaApi.h
* @author drose
* @date 2002-04-15
*/
#ifndef MAYAAPI_H
#define MAYAAPI_H
#include "pandatoolbase.h"
#include "distanceUnit.h"
#include "coordinateSystem.h"
#include "referenceCount.h"
#include "pointerTo.h"
class Filename;
/**
* This class presents a wrapper around the global Maya interface. While the
* reference count is held, it keeps the Maya interface open, and closes the
* interface when the object destructs.
*/
class MayaApi : public ReferenceCount {
protected:
MayaApi(const std::string &program_name, bool view_license = false, bool revertdir = true);
MayaApi(const MayaApi &copy);
void operator = (const MayaApi &copy);
public:
~MayaApi();
static PT(MayaApi) open_api(std::string program_name = "", bool view_license = false, bool revertdir = true);
static bool is_api_valid();
bool is_valid() const;
bool read(const Filename &filename);
bool write(const Filename &filename);
bool clear();
DistanceUnit get_units();
void set_units(DistanceUnit unit);
CoordinateSystem get_coordinate_system();
private:
bool _is_valid;
bool _plug_in;
Filename _cwd;
static PT(MayaApi) _global_api;
};
#endif

View File

@ -1,517 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file mayaShader.cxx
* @author drose
* @date 2000-02-01
* Modified 19Mar10 by ETC PandaSE team (see
* header comment for mayaToEgg.cxx for details)
*/
#include "mayaShader.h"
#include "maya_funcs.h"
#include "config_maya.h"
#include "string_utils.h"
#include "pnmImageHeader.h" // for lumin_red, etc.
#include "pset.h"
#include "pre_maya_include.h"
#include <maya/MFnDependencyNode.h>
#include <maya/MFnLambertShader.h>
#include <maya/MFnPhongShader.h>
#include <maya/MFnMesh.h>
#include <maya/MPlug.h>
#include <maya/MPlugArray.h>
#include <maya/MColor.h>
#include <maya/MObject.h>
#include <maya/MStatus.h>
#include "post_maya_include.h"
using std::endl;
using std::string;
/**
* Reads the Maya "shading engine" to determine the relevant shader
* properties.
*/
MayaShader::
MayaShader(MObject engine, bool legacy_shader) {
MFnDependencyNode engine_fn(engine);
set_name(engine_fn.name().asChar());
if (maya_cat.is_debug()) {
maya_cat.debug()
<< "Reading shading engine " << get_name() << "\n";
}
_legacy_mode = false;
_flat_color.set(1,1,1,1);
MPlug shader_plug = engine_fn.findPlug("surfaceShader");
bool found_shader = false;
if (!shader_plug.isNull()) {
MPlugArray shader_pa;
shader_plug.connectedTo(shader_pa, true, false);
maya_cat.spam() << "shader plug connected to: " << shader_pa.length() << endl;
for (size_t i = 0; i < shader_pa.length() && !found_shader; i++) {
MObject shader = shader_pa[0].node();
if (shader.hasFn(MFn::kPhong)) {
if (legacy_shader) {
found_shader = find_textures_legacy(shader);
} else {
found_shader = find_textures_modern(shader);
}
} else if (shader.hasFn(MFn::kLambert)) {
found_shader = find_textures_legacy(shader);
if (found_shader) {
_legacy_mode = true;
}
} else if (shader.hasFn(MFn::kSurfaceShader)) {
found_shader = find_textures_legacy(shader);
if (found_shader) {
_legacy_mode = true;
}
} else {
maya_cat.warning() <<
"Unrecognized shader type: only lambert and phong supported (lambert deprecated).\n";
}
}
}
}
/**
*
*/
MayaShader::
~MayaShader() {
}
/**
*
*/
void MayaShader::
output(std::ostream &out) const {
out << "Shader " << get_name();
}
/**
*
*/
void MayaShader::
write(std::ostream &out) const {
out << "Shader " << get_name() << "\n";
}
/**
* This is part of the deprecated codepath. return the color def i.e.
* texture at idx
*/
MayaShaderColorDef *MayaShader::
get_color_def(size_t idx) const {
if (_color.size() > 0)
return _color[idx];
else
return nullptr;
}
/**
* Returns the overall color of the shader as a single-precision rgba value,
* where the alpha component represents transparency according to the Panda
* convention. If no overall color is specified (_has_flat_color is not
* true), this returns white.
*
* Normally, Maya makes texture color override the flat color, so if a texture
* is also applied (_has_texture is true), this value is not used by Maya.
*/
LColor MayaShader::
get_rgba(size_t idx) const {
LColor rgba(1.0f, 1.0f, 1.0f, 1.0f);
if (_color.size() && _color[idx]->_has_flat_color) {
rgba[0] = (PN_stdfloat)_color[idx]->_flat_color[0];
rgba[1] = (PN_stdfloat)_color[idx]->_flat_color[1];
rgba[2] = (PN_stdfloat)_color[idx]->_flat_color[2];
}
if (_transparency._has_flat_color) {
// Maya supports colored transparency, but we only support grayscale
// transparency. Use the pnmimage constants to convert color to
// grayscale.
double trans =
_transparency._flat_color[0] * lumin_red +
_transparency._flat_color[1] * lumin_grn +
_transparency._flat_color[2] * lumin_blu;
rgba[3] = 1.0f - (PN_stdfloat)trans;
}
return rgba;
}
/**
* Recalculates the all_maps list.
*/
void MayaShader::
collect_maps() {
_all_maps.clear();
for (size_t i=0; i<_color_maps.size(); i++) {
_all_maps.push_back(_color_maps[i]);
}
for (size_t i=0; i<_trans_maps.size(); i++) {
_all_maps.push_back(_trans_maps[i]);
}
for (size_t i=0; i<_normal_maps.size(); i++) {
_all_maps.push_back(_normal_maps[i]);
}
for (size_t i=0; i<_glow_maps.size(); i++) {
_all_maps.push_back(_glow_maps[i]);
}
for (size_t i=0; i<_gloss_maps.size(); i++) {
_all_maps.push_back(_gloss_maps[i]);
}
for (size_t i=0; i<_height_maps.size(); i++) {
_all_maps.push_back(_height_maps[i]);
}
for (size_t i=0; i<_color.size(); i++) {
if (_color[i]->_has_texture) {
_all_maps.push_back(_color[i]);
}
}
if (_transparency._has_texture) {
_all_maps.push_back(&_transparency);
}
}
/**
* Locates all file textures leading into the given shader.
*/
bool MayaShader::
find_textures_modern(MObject shader) {
if (!shader.hasFn(MFn::kPhong)) {
maya_cat.warning()
<< "The new codepath expects to see phong shaders only.\n";
return false;
}
MStatus status;
MFnPhongShader phong_fn(shader);
MFnDependencyNode shader_fn(shader);
if (maya_cat.is_spam()) {
maya_cat.spam()
<< " Reading modern surface shader " << shader_fn.name().asChar() << "\n";
}
string n = shader_fn.name().asChar();
MayaShaderColorDef::find_textures_modern(n, _color_maps, shader_fn.findPlug("color"), false);
if (_color_maps.size() == 0) {
MayaShaderColorDef::find_textures_modern(n, _color_maps, shader_fn.findPlug("colorR"), false);
}
MayaShaderColorDef::find_textures_modern(n, _trans_maps, shader_fn.findPlug("transparency"), true);
if (_trans_maps.size() == 0) {
MayaShaderColorDef::find_textures_modern(n, _trans_maps, shader_fn.findPlug("transparencyR"), true);
}
MayaShaderColorDef::find_textures_modern(n, _normal_maps, shader_fn.findPlug("normalCamera"), false);
if (_normal_maps.size() == 0) {
MayaShaderColorDef::find_textures_modern(n, _normal_maps, shader_fn.findPlug("normalCameraR"), false);
}
MayaShaderColorDef::find_textures_modern(n, _gloss_maps, shader_fn.findPlug("specularColor"), true);
if (_gloss_maps.size() == 0) {
MayaShaderColorDef::find_textures_modern(n, _gloss_maps, shader_fn.findPlug("specularColorR"), true);
}
MayaShaderColorDef::find_textures_modern(n, _glow_maps, shader_fn.findPlug("incandescence"), true);
if (_glow_maps.size() == 0) {
MayaShaderColorDef::find_textures_modern(n, _glow_maps, shader_fn.findPlug("incandescenceR"), true);
}
MayaShaderColorDef::find_textures_modern(n, _height_maps, shader_fn.findPlug("surfaceThickness"), true);
if (_height_maps.size() == 0) {
MayaShaderColorDef::find_textures_modern(n, _height_maps, shader_fn.findPlug("surfaceThicknessR"), true);
}
collect_maps();
MColor color = phong_fn.color(&status);
if (status) {
_flat_color.set(color.r, color.g, color.b, color.a);
}
color = phong_fn.transparency(&status);
if (status) {
_flat_color[3] = 1.0 - ((color[0] + color[1] + color[2]) * (1.0/3.0));
}
return true;
}
/**
* Assigns the uvset_name of each MayaShaderColorDef using the given file-to-
* uvset map.
*/
void MayaShader::
bind_uvsets(MayaFileToUVSetMap &map) {
for (size_t i=0; i<_all_maps.size(); i++) {
MayaShaderColorDef *def = _all_maps[i];
MayaFileToUVSetMap::iterator p = map.find(def->_texture_name);
if (p == map.end()) {
def->_uvset_name = "map1";
} else {
def->_uvset_name = (*p).second;
}
}
calculate_pairings();
}
/**
* For each Alpha texture, try to find an RGB texture that has the same
* properties. Attempt to make it so that the alpha texture isn't a separate
* texture, but rather, an Alpha-Filename associated with an existing texture.
*/
void MayaShader::
calculate_pairings() {
if (_legacy_mode) {
return;
}
for (size_t i=0; i<_all_maps.size(); i++) {
_all_maps[i]->_opposite = 0;
}
bool using_transparency = (_trans_maps.size() > 0);
for (int retry=0; retry<2; retry++) {
bool perfect=(retry==0);
for (size_t i=0; i<_color_maps.size(); i++) {
if ((_color_maps[i]->_blend_type == MayaShaderColorDef::BT_modulate)||
(_color_maps[i]->_blend_type == MayaShaderColorDef::BT_unspecified)) {
for (size_t j=0; j<_trans_maps.size(); j++) {
try_pair(_color_maps[i], _trans_maps[j], perfect);
}
}
}
}
if (!using_transparency) {
for (int retry=0; retry<2; retry++) {
bool perfect=(retry==0);
for (size_t i=0; i<_color_maps.size(); i++) {
for (size_t j=0; j<_glow_maps.size(); j++) {
try_pair(_color_maps[i], _glow_maps[j], perfect);
}
for (size_t j=0; j<_gloss_maps.size(); j++) {
try_pair(_color_maps[i], _gloss_maps[j], perfect);
}
}
}
}
for (int retry=0; retry<2; retry++) {
bool perfect=(retry==0);
for (size_t i=0; i<_normal_maps.size(); i++) {
for (size_t j=0; j<_height_maps.size(); j++) {
try_pair(_normal_maps[i], _height_maps[j], perfect);
}
}
}
for (size_t i=0; i<_normal_maps.size(); i++) {
_normal_maps[i]->_blend_type = MayaShaderColorDef::BT_normal;
}
for (size_t i=0; i<_glow_maps.size(); i++) {
if (_glow_maps[i]->_opposite) {
_glow_maps[i]->_blend_type = MayaShaderColorDef::BT_unspecified;
_glow_maps[i]->_opposite->_blend_type = MayaShaderColorDef::BT_modulate_glow;
} else {
_glow_maps[i]->_blend_type = MayaShaderColorDef::BT_glow;
}
}
for (size_t i=0; i<_gloss_maps.size(); i++) {
if (_gloss_maps[i]->_opposite) {
_gloss_maps[i]->_blend_type = MayaShaderColorDef::BT_unspecified;
_gloss_maps[i]->_opposite->_blend_type = MayaShaderColorDef::BT_modulate_gloss;
} else {
_gloss_maps[i]->_blend_type = MayaShaderColorDef::BT_gloss;
}
}
for (size_t i=0; i<_height_maps.size(); i++) {
if (_height_maps[i]->_opposite) {
_height_maps[i]->_blend_type = MayaShaderColorDef::BT_unspecified;
_height_maps[i]->_opposite->_blend_type = MayaShaderColorDef::BT_normal_height;
} else {
_height_maps[i]->_blend_type = MayaShaderColorDef::BT_height;
}
}
for (size_t i=0; i<_trans_maps.size(); i++) {
if (_trans_maps[i]->_opposite) {
_trans_maps[i]->_blend_type = MayaShaderColorDef::BT_unspecified;
_trans_maps[i]->_opposite->_blend_type = MayaShaderColorDef::BT_modulate;
} else {
_trans_maps[i]->_blend_type = MayaShaderColorDef::BT_modulate;
}
}
}
/**
* Try to associate an RGB tex with an Alpha tex.
*/
bool MayaShader::try_pair(MayaShaderColorDef *map1,
MayaShaderColorDef *map2,
bool perfect) {
if ((map1->_opposite)||(map2->_opposite)) {
// one of the maps is already paired
return false;
}
if (perfect) {
if (map1->_texture_filename != map2->_texture_filename) {
// perfect mode requires a filename match.
return false;
}
} else {
string pre1 = get_file_prefix(map1->_texture_filename);
string pre2 = get_file_prefix(map2->_texture_filename);
if (pre1 != pre2) {
// imperfect mode requires a filename prefix match.
return false;
}
}
if ((map1->_projection_type != map2->_projection_type) ||
(map1->_projection_matrix != map2->_projection_matrix) ||
(map1->_u_angle != map2->_u_angle) ||
(map1->_v_angle != map2->_v_angle) ||
(map1->_uvset_name != map2->_uvset_name) ||
(map1->_mirror != map2->_mirror) ||
(map1->_stagger != map2->_stagger) ||
(map1->_wrap_u != map2->_wrap_u) ||
(map1->_wrap_v != map2->_wrap_v) ||
(map1->_repeat_uv != map2->_repeat_uv) ||
(map1->_offset != map2->_offset) ||
(map1->_rotate_uv != map2->_rotate_uv)) {
return false;
}
// Pairing successful.
map1->_opposite = map2;
map2->_opposite = map1;
return true;
}
/**
* Try to associate an RGB tex with an Alpha tex.
*/
string MayaShader::
get_file_prefix(const string &fn) {
Filename pfn = Filename::from_os_specific(fn);
string base = pfn.get_basename_wo_extension();
size_t offs = base.find("_");
if (offs != string::npos) {
base = base.substr(0, offs);
}
offs = base.find("-");
if (offs != string::npos) {
base = base.substr(0, offs);
}
return base;
}
/**
* This is part of the legacy codepath. Extracts out the shading information
* from the Maya surface shader.
*/
bool MayaShader::
find_textures_legacy(MObject shader) {
MStatus status;
MFnDependencyNode shader_fn(shader);
if (maya_cat.is_spam()) {
maya_cat.spam()
<< " Reading legacy surface shader " << shader_fn.name().asChar() << "\n";
}
// First, check for a connection to the color attribute. This could be a
// texture map or something, and will override whatever the shader says for
// color.
MPlug color_plug = shader_fn.findPlug("color");
if (color_plug.isNull()) {
// Or maybe a connection to outColor. Not sure how this differs from just
// color, but empirically it seems that either might be used.
color_plug = shader_fn.findPlug("outColor");
}
if (!color_plug.isNull()) {
MPlugArray color_pa;
color_plug.connectedTo(color_pa, true, false);
MayaShaderColorDef *color_p = new MayaShaderColorDef;
for (size_t i = 0; i < color_pa.length(); i++) {
maya_cat.spam() << "color_pa[" << i << "]:" << color_pa[i].name().asChar() << endl;
color_p->find_textures_legacy(this, color_pa[0].node());
}
if (color_pa.length() < 1) {
// assign a blank default color to this shader
maya_cat.spam() << shader_fn.name().asChar() << " was not connected to texture" << endl;
this->_color.push_back(color_p);
}
}
// Transparency is stored separately.
MPlug trans_plug = shader_fn.findPlug("transparency");
if (trans_plug.isNull()) {
trans_plug = shader_fn.findPlug("outTransparency");
}
if (!trans_plug.isNull()) {
MPlugArray trans_pa;
trans_plug.connectedTo(trans_pa, true, false);
for (size_t i = 0; i < trans_pa.length(); i++) {
maya_cat.spam() << "read a transparency texture" << endl;
_transparency.find_textures_legacy(this, trans_pa[0].node(), true);
}
}
// Also try to get the ordinary color directly from the surface shader.
bool b_color_def = true;
if (shader.hasFn(MFn::kLambert)) {
MFnLambertShader lambert_fn(shader);
MColor color = lambert_fn.color(&status);
if (status) {
// Warning! The alpha component of color doesn't mean transparency in
// Maya.
for (size_t i=0; i<_color.size(); ++i) {
_color[i]->_has_flat_color = true;
_color[i]->_flat_color.set(color.r, color.g, color.b, color.a);
maya_cat.spam() << shader_fn.name().asChar() << " set shader color" << endl;
// needed to print the final check
if (!_color[i]->_has_flat_color && !_color[i]->_has_texture)
b_color_def = false;
_transparency._flat_color.set(0.0, 0.0, 0.0, 0.0);
// Get the transparency separately.
color = lambert_fn.transparency(&status);
if (status) {
_transparency._has_flat_color = true;
_transparency._flat_color.set(color.r, color.g, color.b, color.a);
}
}
}
}
// if (!_color._has_flat_color && !_color._has_texture) {
if (!b_color_def) {
maya_cat.info() << shader_fn.name().asChar() << "Color def not found" << endl;
if (maya_cat.is_spam()) {
maya_cat.spam()
<< " Color definition not found.\n";
}
}
collect_maps();
return true;
}

View File

@ -1,80 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file mayaShader.h
* @author drose
* @date 2000-02-01
*/
#ifndef MAYASHADER_H
#define MAYASHADER_H
#include "pandatoolbase.h"
#include "mayaShaderColorDef.h"
#include "luse.h"
#include "lmatrix.h"
#include "namable.h"
/**
* Corresponds to a single "shader" in Maya. This extracts out all the
* parameters of a Maya shader that we might care about. There are many more
* parameters that we don't care about or don't know enough to extract.
*/
class MayaShader : public Namable {
public:
MayaShader(MObject engine, bool legacy_shader);
~MayaShader();
void output(std::ostream &out) const;
void write(std::ostream &out) const;
private:
bool find_textures_modern(MObject shader);
bool find_textures_legacy(MObject shader);
public:
void collect_maps();
bool _legacy_mode;
MayaShaderColorList _all_maps;
public: // relevant only to modern mode.
LColord _flat_color;
MayaShaderColorList _color_maps;
MayaShaderColorList _trans_maps;
MayaShaderColorList _normal_maps;
MayaShaderColorList _glow_maps;
MayaShaderColorList _gloss_maps;
MayaShaderColorList _height_maps;
void bind_uvsets(MayaFileToUVSetMap &map);
private:
void calculate_pairings();
bool try_pair(MayaShaderColorDef *map1,
MayaShaderColorDef *map2,
bool perfect);
std::string get_file_prefix(const std::string &fn);
bool _legacy_shader;
public: // relevant only to legacy mode.
MayaShaderColorList _color;
MayaShaderColorDef _transparency;
LColor get_rgba(size_t idx=0) const;
MayaShaderColorDef *get_color_def(size_t idx=0) const;
};
INLINE std::ostream &operator << (std::ostream &out, const MayaShader &shader) {
shader.output(out);
return out;
}
#endif

View File

@ -1,799 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file mayaShaderColorDef.cxx
* @author drose
* @date 2003-04-12
* Modified 19Mar10 by ETC PandaSE team (see
* header comment for mayaToEgg.cxx for details)
*/
#include "mayaShaderColorDef.h"
#include "mayaShader.h"
#include "maya_funcs.h"
#include "config_maya.h"
#include "string_utils.h"
#include "pset.h"
#include "pre_maya_include.h"
#include <maya/MFnDependencyNode.h>
#include <maya/MPlug.h>
#include <maya/MPlugArray.h>
#include <maya/MObject.h>
#include <maya/MStatus.h>
#include <maya/MFnEnumAttribute.h>
#include "post_maya_include.h"
using std::endl;
using std::string;
/**
*
*/
MayaShaderColorDef::
MayaShaderColorDef() {
_blend_type = BT_unspecified;
_projection_type = PT_off;
_projection_matrix = LMatrix4d::ident_mat();
_u_angle = 0.0;
_v_angle = 0.0;
_texture_filename = "";
_texture_name = "";
_color_gain.set(1.0f, 1.0f, 1.0f, 1.0f);
_coverage.set(1.0, 1.0);
_translate_frame.set(0.0, 0.0);
_rotate_frame = 0.0;
_mirror = false;
_stagger = false;
_wrap_u = true;
_wrap_v = true;
_repeat_uv.set(1.0, 1.0);
_offset.set(0.0, 0.0);
_rotate_uv = 0.0;
_is_alpha = false;
_opposite = 0;
_color_object = nullptr;
_has_texture = false;
_has_flat_color = false;
_flat_color.set(0.0, 0.0, 0.0, 0.0);
_has_alpha_channel = false;
_keep_color = false; // classic mode overwrites color: new mode retains color with a 3rd layer
_keep_alpha = false;
_interpolate = false;
_uvset_name = "map1";
_map_uvs = nullptr;
}
/**
*
*/
MayaShaderColorDef::
MayaShaderColorDef(MayaShaderColorDef &copy) {
_has_texture = copy._has_texture;
_texture_filename = copy._texture_filename;
_texture_name = copy._texture_name;
_uvset_name = copy._uvset_name;
_color_gain = copy._color_gain;
_has_flat_color = copy._has_flat_color;
_flat_color = copy._flat_color;
_projection_type = copy._projection_type;
_projection_matrix = copy._projection_matrix;
_u_angle = copy._u_angle;
_v_angle = copy._v_angle;
_coverage = copy._coverage;
_translate_frame = copy._translate_frame;
_rotate_frame = copy._rotate_frame;
_mirror = copy._mirror;
_stagger = copy._stagger;
_wrap_u = copy._wrap_u;
_wrap_v = copy._wrap_v;
_blend_type = copy._blend_type;
_has_alpha_channel = copy._has_alpha_channel;
_keep_color = copy._keep_color;
_keep_alpha = copy._keep_alpha;
_interpolate = copy._interpolate;
_repeat_uv = copy._repeat_uv;
_offset = copy._offset;
_rotate_uv = copy._rotate_uv;
_is_alpha = copy._is_alpha;
_map_uvs = copy._map_uvs;
_color_object = copy._color_object;
_opposite = 0;
}
/**
*
*/
MayaShaderColorDef::
~MayaShaderColorDef() {
delete _color_object;
}
/**
* Returns a texture matrix corresponding to the texture transforms indicated
* by the shader.
*/
LMatrix3d MayaShaderColorDef::
compute_texture_matrix() const {
LVector2d scale(_repeat_uv[0] / _coverage[0],
_repeat_uv[1] / _coverage[1]);
LVector2d trans(_offset[0] - _translate_frame[0] / _coverage[0],
_offset[1] - _translate_frame[1] / _coverage[1]);
return
(LMatrix3d::translate_mat(LVector2d(-0.5, -0.5)) *
LMatrix3d::rotate_mat(_rotate_frame) *
LMatrix3d::translate_mat(LVector2d(0.5, 0.5))) *
LMatrix3d::scale_mat(scale) *
LMatrix3d::translate_mat(trans);
}
/**
* Returns true if the shader has a projection in effect.
*/
bool MayaShaderColorDef::
has_projection() const {
return (_projection_type != PT_off);
}
/**
* If the shader has a projection (has_projection() returns true), this
* computes the appropriate UV corresponding to the indicated 3-d point.
* Seams that might be introduced on polygons that cross quadrants are closed
* up by ensuring the point is in the same quadrant as the indicated reference
* point.
*/
LTexCoordd MayaShaderColorDef::
project_uv(const LPoint3d &pos, const LPoint3d &centroid) const {
nassertr(_map_uvs != nullptr, LTexCoordd::zero());
return (this->*_map_uvs)(pos * _projection_matrix, centroid * _projection_matrix);
}
/**
*
*/
void MayaShaderColorDef::
write(std::ostream &out) const {
if (_has_texture) {
out << " texture filename is " << _texture_filename << "\n"
<< " texture name is " << _texture_name << "\n"
<< " uv_set name is " << _uvset_name << "\n"
<< " coverage is " << _coverage << "\n"
<< " translate_frame is " << _translate_frame << "\n"
<< " rotate_frame is " << _rotate_frame << "\n"
<< " mirror is " << _mirror << "\n"
<< " stagger is " << _stagger << "\n"
<< " wrap_u is " << _wrap_u << "\n"
<< " wrap_v is " << _wrap_v << "\n"
<< " repeat_uv is " << _repeat_uv << "\n"
<< " offset is " << _offset << "\n"
<< " rotate_uv is " << _rotate_uv << "\n"
<< " color_gain is " << _color_gain << "\n";
} else if (_has_flat_color) {
out << " flat color is " << _flat_color << "\n";
}
}
/**
* Changes the texture filename stored in the Maya file for this particular
* shader.
*/
bool MayaShaderColorDef::
reset_maya_texture(const Filename &texture) {
if (_color_object != nullptr) {
_has_texture = set_string_attribute(*_color_object, "fileTextureName",
texture.to_os_generic());
_texture_filename = texture;
if (!_has_texture) {
maya_cat.error()
<< "Unable to reset texture filename.\n";
}
return _has_texture;
}
maya_cat.error()
<< "Attempt to reset texture on Maya object that has no color set.\n";
return false;
}
/**
* Maya's default uvset name is "map1". Panda's default uvset name is
* "default". Otherwise, leaves uvset name untranslated.
*/
string MayaShaderColorDef::
get_panda_uvset_name() {
if (_uvset_name == "map1") {
return "default";
}
return _uvset_name;
}
/**
* This is part of the deprecated codepath. Determines the surface color
* specified by the shader. This includes texturing and other advanced shader
* properties.
*/
void MayaShaderColorDef::
find_textures_legacy(MayaShader *shader, MObject color, bool trans) {
LRGBColor color_gain;
if (get_vec3_attribute(color, "colorGain", color_gain)) {
color_gain[0] = color_gain[0] > 1.0 ? 1.0 : color_gain[0];
color_gain[0] = color_gain[0] < 0.0 ? 0.0 : color_gain[0];
_color_gain[0] *= color_gain[0];
color_gain[1] = color_gain[1] > 1.0 ? 1.0 : color_gain[1];
color_gain[1] = color_gain[1] < 0.0 ? 0.0 : color_gain[1];
_color_gain[1] *= color_gain[1];
color_gain[2] = color_gain[2] > 1.0 ? 1.0 : color_gain[2];
color_gain[2] = color_gain[2] < 0.0 ? 0.0 : color_gain[2];
_color_gain[2] *= color_gain[2];
}
PN_stdfloat alpha_gain;
if (get_maya_attribute(color, "alphaGain", alpha_gain)) {
alpha_gain = alpha_gain > 1.0 ? 1.0 : alpha_gain;
alpha_gain = alpha_gain < 0.0 ? 0.0 : alpha_gain;
_color_gain[3] *= alpha_gain;
}
if (color.hasFn(MFn::kFileTexture)) {
MFnDependencyNode dfn(color);
_color_object = new MObject(color);
_texture_name = dfn.name().asChar();
string filename;
_has_texture = get_string_attribute(color, "fileTextureName", filename);
_has_texture = _has_texture && !filename.empty();
if (_has_texture) {
_texture_filename = Filename::from_os_specific(filename);
if (_texture_filename.is_directory()) {
maya_cat.warning()
<< "Shader " << shader->get_name()
<< " references texture filename " << filename
<< " which is a directory; clearing.\n";
_has_texture = false;
set_string_attribute(color, "fileTextureName", "");
}
}
get_vec2_attribute(color, "coverage", _coverage);
get_vec2_attribute(color, "translateFrame", _translate_frame);
get_angle_attribute(color, "rotateFrame", _rotate_frame);
// get_bool_attribute(color, "alphaIsLuminance", _alpha_is_luminance);
get_bool_attribute(color, "mirror", _mirror);
get_bool_attribute(color, "stagger", _stagger);
get_bool_attribute(color, "wrapU", _wrap_u);
get_bool_attribute(color, "wrapV", _wrap_v);
get_vec2_attribute(color, "repeatUV", _repeat_uv);
get_vec2_attribute(color, "offset", _offset);
get_angle_attribute(color, "rotateUV", _rotate_uv);
if (!trans) {
if (maya_cat.is_debug()) {
maya_cat.debug() << "pushed a file texture" << endl;
}
shader->_color.push_back(this);
}
} else if (color.hasFn(MFn::kProjection)) {
if (maya_cat.is_debug()) {
maya_cat.debug() << "reading a projection texture" << endl;
}
// This is a projected texture. We will have to step one level deeper to
// find the actual texture.
MFnDependencyNode projection_fn(color);
MPlug image_plug = projection_fn.findPlug("image");
if (!image_plug.isNull()) {
MPlugArray image_pa;
image_plug.connectedTo(image_pa, true, false);
for (size_t i = 0; i < image_pa.length(); i++) {
find_textures_legacy(shader, image_pa[0].node());
}
}
if (!get_mat4d_attribute(color, "placementMatrix", _projection_matrix)) {
_projection_matrix = LMatrix4d::ident_mat();
}
// The uAngle and vAngle might be used for certain kinds of projections.
if (!get_angle_attribute(color, "uAngle", _u_angle)) {
_u_angle = 360.0;
}
if (!get_angle_attribute(color, "vAngle", _v_angle)) {
_v_angle = 180.0;
}
string type;
if (get_enum_attribute(color, "projType", type)) {
set_projection_type(type);
}
} else if (color.hasFn(MFn::kLayeredTexture)) {
if (maya_cat.is_debug()) {
maya_cat.debug() << "Found layered texture" << endl;
}
int blendValue;
MStatus status;
MPlugArray color_pa;
MFnDependencyNode layered_fn(color);
layered_fn.getConnections(color_pa);
MPlug inputsPlug = layered_fn.findPlug("inputs", &status);
MPlug blendModePlug = layered_fn.findPlug("blendMode", &status);
if (maya_cat.is_debug()) {
maya_cat.debug() << "number of connections: " << color_pa.length() << endl;
}
bool first = true;
BlendType bt = BT_modulate;
for (size_t i=0; i<color_pa.length(); ++i) {
MPlug pl = color_pa[i];
MPlugArray pla;
pl.connectedTo(pla, true, false);
// First figure out the blend mode intended for this shadercolordef
int li = pl.logicalIndex();
if (li > -1) {
// found a blend mode
if (maya_cat.is_spam()) {
MString name = inputsPlug.name();
maya_cat.spam() << "*** Start doIt... ***" << endl;
maya_cat.spam() << "inputsPlug Name: " << name.asChar() << endl;
}
status = blendModePlug.selectAncestorLogicalIndex(li,inputsPlug);
blendModePlug.getValue(blendValue);
if (maya_cat.is_spam()) {
MString name = blendModePlug.name();
maya_cat.spam()
<< name.asChar() << ": has value " << blendValue << endl;
}
MFnEnumAttribute blendModeEnum(blendModePlug);
MString blendName = blendModeEnum.fieldName(blendValue, &status);
switch (blendValue) {
case 1:
bt = BT_decal;
get_bool_attribute(color, "interpolate", _interpolate);
maya_cat.info() << "interpolate: " << _interpolate << endl;
_keep_color = true;
break;
case 6:
bt = BT_modulate;
get_bool_attribute(color, "keepAlpha", _keep_alpha);
maya_cat.info() << "keepAlpha: " << _keep_alpha << endl;
break;
case 4:
bt = BT_add;
break;
}
if (maya_cat.is_info()) {
MString name = layered_fn.name();
maya_cat.info() << name.asChar() << ": blendMode used " << blendName.asChar() << endl;
if (maya_cat.is_spam()) {
maya_cat.spam() << "*** END doIt... ***" << endl;
}
}
// advance to the next plug, because that is where the shader info are
pl = color_pa[++i];
pl.connectedTo(pla, true, false);
}
for (size_t j=0; j<pla.length(); ++j) {
// maya_cat.debug() << pl.name() << " is(pl) " <<
// pl.node().apiTypeStr() << endl; maya_cat.debug() << pla[j].name()
// << " is(pla) " << pla[j].node().apiTypeStr() << endl;
string pla_name = pla[j].name().asChar();
// sometimes, by default, maya gives a outAlpha on subsequent plugs,
// ignore that
if (pla_name.find("outAlpha") != string::npos) {
// top texture has an alpha channel, so make sure that this alpha is
// retained by egg file
if (maya_cat.is_debug()) {
maya_cat.debug() << pl.name().asChar() << ":has alpha channel" << pla_name << endl;
}
_has_alpha_channel = true;
continue;
}
if (!first) {
if (maya_cat.is_debug()) {
maya_cat.debug() << pl.name().asChar() << " next:connectedTo: " << pla_name << endl;
}
MayaShaderColorDef *color_p = new MayaShaderColorDef;
color_p->find_textures_legacy(shader, pla[j].node());
color_p->_blend_type = bt;
size_t loc = color_p->_texture_name.find('.',0);
if (loc != string::npos) {
color_p->_texture_name.resize(loc);
}
if (maya_cat.is_debug()) {
maya_cat.debug() << "uv_name : " << color_p->_texture_name << endl;
}
}
else {
if (maya_cat.is_debug()) {
maya_cat.debug() << pl.name().asChar() << " first:connectedTo: " << pla_name << endl;
}
find_textures_legacy(shader, pla[j].node());
_texture_name.assign(pla[j].name().asChar());
_blend_type = bt;
size_t loc = _texture_name.find('.',0);
if (loc != string::npos) {
_texture_name.resize(loc);
}
if (maya_cat.is_debug()) {
maya_cat.debug() << "uv_name : " << _texture_name << endl;
}
first = false;
}
}
}
} else {
// This shader wasn't understood.
if (maya_cat.is_debug()) {
maya_cat.info()
<< "**Don't know how to interpret color attribute type "
<< color.apiTypeStr() << "\n";
} else {
// If we don't have a heavy verbose count, only report each type of
// unsupported shader once.
static pset<MFn::Type> bad_types;
if (bad_types.insert(color.apiType()).second) {
maya_cat.info()
<< "**Don't know how to interpret color attribute type "
<< color.apiTypeStr() << "\n";
}
}
}
}
/**
* Search to find any file textures that lead into the given input plug. Any
* textures found will be added to the provided MayaShaderColorList.
*/
void MayaShaderColorDef::
find_textures_modern(const string &shadername, MayaShaderColorList &list, MPlug inplug, bool is_alpha) {
MPlugArray outplugs;
inplug.connectedTo(outplugs, true, false);
if (outplugs.length() == 0) {
return;
}
if (outplugs.length() > 1) {
// Only one output plug should be connected to a given input plug.
maya_cat.warning()
<< "Shader " << shadername << " has weird plug connections.\n";
return;
}
MPlug outplug = outplugs[0];
MObject source = outplug.node();
MFnDependencyNode sourceFn(source);
if (source.hasFn(MFn::kFileTexture)) {
string filename;
bool hasfn = get_string_attribute(source, "fileTextureName", filename);
if ((!hasfn) || (filename.empty())) {
maya_cat.warning()
<< "Shader " << shadername << " references file texture "
<< "with no file name, ignoring invalid file texture.\n";
return;
}
Filename fn = filename;
if (fn.is_directory()) {
maya_cat.warning()
<< "Shader " << shadername << " references file name "
<< filename << " which is a directory, ignoring it.\n";
return;
}
MayaShaderColorDef *def = new MayaShaderColorDef;
def->_color_object = new MObject(source);
def->_texture_filename = Filename::from_os_specific(filename);
def->_texture_name = sourceFn.name().asChar();
get_vec2_attribute(source, "coverage", def->_coverage);
get_vec2_attribute(source, "translateFrame", def->_translate_frame);
get_angle_attribute(source, "rotateFrame", def->_rotate_frame);
get_bool_attribute(source, "mirror", def->_mirror);
get_bool_attribute(source, "stagger", def->_stagger);
get_bool_attribute(source, "wrapU", def->_wrap_u);
get_bool_attribute(source, "wrapV", def->_wrap_v);
get_vec2_attribute(source, "repeatUV", def->_repeat_uv);
get_vec2_attribute(source, "offset", def->_offset);
get_angle_attribute(source, "rotateUV", def->_rotate_uv);
LRGBColor color_gain;
PN_stdfloat alpha_gain;
get_vec3_attribute(source, "colorGain", color_gain);
get_maya_attribute(source, "alphaGain", alpha_gain);
def->_color_gain[0] = color_gain[0];
def->_color_gain[1] = color_gain[1];
def->_color_gain[2] = color_gain[2];
def->_color_gain[3] = alpha_gain;
def->_is_alpha = is_alpha;
if (maya_cat.is_debug()) {
maya_cat.debug() << "pushed a file texture" << endl;
}
list.push_back(def);
return;
}
if (source.hasFn(MFn::kProjection)) {
// This is a projected texture. We will have to step one level deeper to
// find the actual texture.
size_t before = list.size();
MPlug image_plug = sourceFn.findPlug("image");
if (!image_plug.isNull()) {
MPlugArray image_pa;
image_plug.connectedTo(image_pa, true, false);
for (size_t i = 0; i < image_pa.length(); i++) {
find_textures_modern(shadername, list, image_pa[0], is_alpha);
}
}
// Now apply any inherited attributes to all textures found.
for (size_t i=before; i<list.size(); i++) {
MayaShaderColorDef *def = list[i];
if (!get_mat4d_attribute(source, "placementMatrix", def->_projection_matrix)) {
def->_projection_matrix = LMatrix4d::ident_mat();
}
// The uAngle and vAngle might be used for certain kinds of projections.
if (!get_angle_attribute(source, "uAngle", def->_u_angle)) {
def->_u_angle = 360.0;
}
if (!get_angle_attribute(source, "vAngle", def->_v_angle)) {
def->_v_angle = 180.0;
}
string type;
if (get_enum_attribute(source, "projType", type)) {
def->set_projection_type(type);
}
}
return;
}
if (source.hasFn(MFn::kLayeredTexture)) {
if (maya_cat.is_debug()) {
maya_cat.debug() << "Found layered texture" << endl;
}
MPlug inputsPlug = sourceFn.findPlug("inputs");
size_t nlayers = inputsPlug.numElements();
for (size_t layer=0; layer<nlayers; layer++) {
MPlug elt = inputsPlug.elementByPhysicalIndex(layer);
MPlug color;
MPlug blend;
for (size_t j=0; j<elt.numChildren(); j++) {
MPlug child = elt.child(j);
MFnAttribute att(child.attribute());
if (att.name() == "color") color = child;
if (att.name() == "blendMode") blend = child;
}
if (color.isNull() || blend.isNull()) {
maya_cat.warning() << "Invalid layered texture - bad inputs.\n";
return;
}
size_t before = list.size();
find_textures_modern(shadername, list, color, is_alpha);
int blendValue;
blend.getValue(blendValue);
for (size_t sub=before; sub<list.size(); sub++) {
MayaShaderColorDef *def = list[sub];
switch (blendValue) {
case 1: def->_blend_type = BT_decal; break;
case 6: def->_blend_type = BT_modulate; break;
case 4: def->_blend_type = BT_add; break;
}
}
}
return;
}
if (source.apiType() == MFn::kReverse) {
MPlug input_plug = sourceFn.findPlug("input");
find_textures_modern(shadername, list, input_plug, is_alpha);
return;
}
// This shader wasn't understood.
if (maya_cat.is_debug()) {
maya_cat.info()
<< "**Don't know how to interpret color attribute type "
<< source.apiTypeStr() << "\n";
} else {
// If we don't have a heavy verbose count, only report each type of
// unsupported shader once.
static pset<MFn::Type> bad_types;
if (bad_types.insert(source.apiType()).second) {
maya_cat.warning()
<< "Don't know how to export a shader of type "
<< source.apiTypeStr() << " " << sourceFn.type() << "\n";
}
}
}
/**
* Sets up the shader to apply UV's according to the indicated projection
* type.
*/
void MayaShaderColorDef::
set_projection_type(const string &type) {
if (cmp_nocase(type, "planar") == 0) {
_projection_type = PT_planar;
_map_uvs = &MayaShaderColorDef::map_planar;
// The Planar projection normally projects to a range (-1, 1) in both
// axes. Scale this into our UV range of (0, 1).
_projection_matrix = _projection_matrix * LMatrix4d(0.5, 0.0, 0.0, 0.0,
0.0, 0.5, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.5, 0.5, 0.0, 1.0);
} else if (cmp_nocase(type, "cylindrical") == 0) {
_projection_type = PT_cylindrical;
_map_uvs = &MayaShaderColorDef::map_cylindrical;
// The cylindrical projection is orthographic in the Y axis; scale the
// range (-1, 1) in this axis into our UV range (0, 1).
_projection_matrix = _projection_matrix * LMatrix4d(1.0, 0.0, 0.0, 0.0,
0.0, 0.5, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.5, 0.0, 1.0);
} else if (cmp_nocase(type, "spherical") == 0) {
_projection_type = PT_spherical;
_map_uvs = &MayaShaderColorDef::map_spherical;
} else {
// Other projection types are currently unimplemented by the converter.
maya_cat.error()
<< "Don't know how to handle type " << type << " projections.\n";
_projection_type = PT_off;
_map_uvs = nullptr;
}
}
/**
* Computes a UV based on the given point in space, using a planar projection.
*/
LPoint2d MayaShaderColorDef::
map_planar(const LPoint3d &pos, const LPoint3d &) const {
// A planar projection is about as easy as can be. We ignore the Z axis,
// and project the point into the XY plane. Done.
return LPoint2d(pos[0], pos[1]);
}
/**
* Computes a UV based on the given point in space, using a spherical
* projection.
*/
LPoint2d MayaShaderColorDef::
map_spherical(const LPoint3d &pos, const LPoint3d &centroid) const {
// To compute the x position on the frame, we only need to consider the
// angle of the vector about the Y axis. Project the vector into the XZ
// plane to do this.
LVector2d xz(pos[0], pos[2]);
double xz_length = xz.length();
if (xz_length < 0.01) {
// If we have a point on or near either pole, we've got problems. This
// point maps to the entire bottom edge of the image, so which U value
// should we choose? It does make a difference, especially if we have a
// number of polygons around the south pole that all share the common
// vertex.
// We choose the U value based on the polygon's centroid.
xz.set(centroid[0], centroid[2]);
}
// Now, if the polygon crosses the seam, we also have problems. Make sure
// that the u value is in the same half of the texture as the centroid's u
// value.
double u = rad_2_deg(atan2(xz[0], xz[1])) / (2.0 * _u_angle);
double c = rad_2_deg(atan2(centroid[0], centroid[2])) / (2.0 * _u_angle);
if (u - c > 0.5) {
u -= floor(u - c + 0.5);
} else if (u - c < -0.5) {
u += floor(c - u + 0.5);
}
// Now rotate the vector into the YZ plane, and the V value is based on the
// latitude: the angle about the X axis.
LVector2d yz(pos[1], xz_length);
double v = rad_2_deg(atan2(yz[0], yz[1])) / (2.0 * _v_angle);
LPoint2d uv(u - 0.5, v - 0.5);
nassertr(fabs(u - c) <= 0.5, uv);
return uv;
}
/**
* Computes a UV based on the given point in space, using a cylindrical
* projection.
*/
LPoint2d MayaShaderColorDef::
map_cylindrical(const LPoint3d &pos, const LPoint3d &centroid) const {
// This is almost identical to the spherical projection, except for the
// computation of V.
LVector2d xz(pos[0], pos[2]);
double xz_length = xz.length();
if (xz_length < 0.01) {
/*
* A cylindrical mapping has the same singularity problem at the pole as a
* spherical mapping does: points at the pole do not map to a single point on
* the texture. (It's technically a slightly different problem: in a
* cylindrical mapping, points at the pole do not map to any point on the
* texture, while in a spherical mapping, points at the pole map to the top or
* bottom edge of the texture. But this is a technicality that doesn't really
* apply to us.) We still solve it the same way: if our point is at or near
* the pole, compute the angle based on the centroid of the polygon (which we
* assume is further from the pole).
*/
xz.set(centroid[0], centroid[2]);
}
// And cylinders do still have a seam at the back.
double u = rad_2_deg(atan2(xz[0], xz[1])) / _u_angle;
double c = rad_2_deg(atan2(centroid[0], centroid[2])) / _u_angle;
if (u - c > 0.5) {
u -= floor(u - c + 0.5);
} else if (u - c < -0.5) {
u += floor(c - u + 0.5);
}
// For a cylindrical mapping, the V value comes directly from Y. Easy.
LPoint2d uv(u - 0.5, pos[1]);
nassertr(fabs(u - c) <= 0.5, uv);
return uv;
}

View File

@ -1,150 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file mayaShaderColorDef.h
* @author drose
* @date 2003-04-12
*/
#ifndef MAYASHADERCOLORDEF_H
#define MAYASHADERCOLORDEF_H
#include "pandatoolbase.h"
#include "luse.h"
#include "lmatrix.h"
#include "pmap.h"
#include "pvector.h"
class MayaShader;
class MayaShaderColorDef;
typedef pvector<MayaShaderColorDef *> MayaShaderColorList;
typedef pmap<std::string, std::string> MayaFileToUVSetMap;
/**
* This defines the various attributes that Maya may associate with the
* "color" channel for a particular shader (as well as on the "transparency"
* channel).
*/
class MayaShaderColorDef {
public:
MayaShaderColorDef();
MayaShaderColorDef (MayaShaderColorDef&);
~MayaShaderColorDef();
std::string strip_prefix(std::string full_name);
LMatrix3d compute_texture_matrix() const;
bool has_projection() const;
LTexCoordd project_uv(const LPoint3d &pos, const LPoint3d &ref_point) const;
bool reset_maya_texture(const Filename &texture);
void write(std::ostream &out) const;
enum BlendType {
BT_unspecified,
BT_modulate,
BT_decal,
BT_blend,
BT_replace,
BT_add,
BT_blend_color_scale,
BT_modulate_glow,
BT_modulate_gloss,
BT_normal,
BT_normal_height,
BT_gloss,
BT_glow,
BT_height,
BT_selector,
};
enum ProjectionType {
PT_off,
PT_planar,
PT_spherical,
PT_cylindrical,
PT_ball,
PT_cubic,
PT_triplanar,
PT_concentric,
PT_perspective,
};
BlendType _blend_type;
ProjectionType _projection_type;
LMatrix4d _projection_matrix;
double _u_angle;
double _v_angle;
Filename _texture_filename;
std::string _texture_name;
LColor _color_gain;
LVector2 _coverage;
LVector2 _translate_frame;
double _rotate_frame;
bool _mirror;
bool _stagger;
bool _wrap_u;
bool _wrap_v;
LVector2 _repeat_uv;
LVector2 _offset;
double _rotate_uv;
bool _is_alpha;
std::string _uvset_name;
MayaShaderColorDef *_opposite;
std::string get_panda_uvset_name();
private:
MObject *_color_object;
private:
static void find_textures_modern(const std::string &shadername, MayaShaderColorList &list, MPlug inplug, bool is_alpha);
void find_textures_legacy(MayaShader *shader, MObject color, bool trans=false);
void set_projection_type(const std::string &type);
LPoint2d map_planar(const LPoint3d &pos, const LPoint3d &centroid) const;
LPoint2d map_spherical(const LPoint3d &pos, const LPoint3d &centroid) const;
LPoint2d map_cylindrical(const LPoint3d &pos, const LPoint3d &centroid) const;
// Define a pointer to one of the above member functions.
LPoint2d (MayaShaderColorDef::*_map_uvs)(const LPoint3d &pos, const LPoint3d &centroid) const;
friend class MayaShader;
/*
* Legacy Fields - these fields are only used by the legacy codepath. These
* fields are deprecated for the following reasons: * has_texture is redundant
* --- if there's no texture, just don't allocate a MayaShaderColorDef. *
* has_flat_color and flat_color don't belong here, they belong in the shader.
* * has_alpha_channel is not needed - there are better ways to determine if a
* texture stage involves an alpha channel. * keep_color, keep_alpha, and
* interpolate are all adjuncts to blend_mode - it would make more sense just
* to add some more blend_modes.
*/
public:
bool _has_texture; // deprecated, see above.
bool _has_flat_color; // deprecated, see above.
LColord _flat_color; // deprecated, see above.
bool _has_alpha_channel; // deprecated, see above.
bool _keep_color; // deprecated, see above.
bool _keep_alpha; // deprecated, see above.
bool _interpolate; // deprecated, see above.
};
#endif

View File

@ -1,200 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file mayaShaders.cxx
* @author drose
* @date 2000-02-11
*/
#include "mayaShaders.h"
#include "mayaShader.h"
#include "maya_funcs.h"
#include "config_maya.h"
#include "pre_maya_include.h"
#include <maya/MStatus.h>
#include <maya/MObject.h>
#include <maya/MFnDependencyNode.h>
#include <maya/MFnMesh.h>
#include <maya/MObjectArray.h>
#include <maya/MPlug.h>
#include <maya/MPlugArray.h>
#include <maya/MFn.h>
#include "post_maya_include.h"
using std::string;
/**
*
*/
MayaShaders::
MayaShaders() {
}
/**
*
*/
MayaShaders::
~MayaShaders() {
clear();
}
/**
* Extracts the shader assigned to the indicated node.
*/
MayaShader *MayaShaders::
find_shader_for_node(MObject node, bool legacy_shader) {
MStatus status;
MFnDependencyNode node_fn(node);
// Look on the instObjGroups attribute for shading engines.
MObject iog_attr = node_fn.attribute("instObjGroups", &status);
if (!status) {
// The node is not renderable. What are you thinking?
maya_cat.error()
<< node_fn.name().asChar() << " : not a renderable object.\n";
return nullptr;
}
// instObjGroups is a multi attribute, whatever that means. For now, we'll
// just get the first connection, since that's what the example code did.
// Is there any reason to search deeper?
MPlug iog_plug(node, iog_attr);
MPlugArray iog_pa;
iog_plug.elementByLogicalIndex(0).connectedTo(iog_pa, false, true, &status);
if (!status) {
// No shading group defined for this object.
maya_cat.error()
<< node_fn.name().asChar() << " : no shading group defined.\n";
return nullptr;
}
// Now we have a number of ShadingEngines defined, one for each of these
// connections we just turned up. Usually there will only be one. In fact,
// we'll just take the first one we find.
size_t i;
for (i = 0; i < iog_pa.length(); i++) {
MObject engine = iog_pa[i].node();
if (engine.hasFn(MFn::kShadingEngine)) {
return find_shader_for_shading_engine(engine, legacy_shader);
}
}
// Well, we didn't find a ShadingEngine after all. Huh.
if (maya_cat.is_debug()) {
maya_cat.debug()
<< node_fn.name().asChar() << " : no shading engine found.\n";
}
return nullptr;
}
/**
* Causes all shaders in the set to use the given mesh as a file-to-uvset map.
*/
void MayaShaders::
bind_uvsets(MObject mesh) {
_uvset_names.clear();
_file_to_uvset.clear();
if (mesh.hasFn(MFn::kMesh)) {
MFnMesh mesh_fn(mesh);
MStatus status;
MStringArray maya_uvset_names;
status = mesh_fn.getUVSetNames(maya_uvset_names);
for (size_t i=0; i<maya_uvset_names.length(); ++i) {
MObjectArray moa;
string uvset_name = maya_uvset_names[i].asChar();
_uvset_names.push_back(uvset_name);
mesh_fn.getAssociatedUVSetTextures(maya_uvset_names[i], moa);
for (size_t j=0; j<moa.length(); ++j){
MFnDependencyNode dt(moa[j]);
string tex_name = dt.name().asChar();
_file_to_uvset[tex_name] = uvset_name;
}
}
}
Shaders::iterator sha;
for (sha=_shaders.begin(); sha!=_shaders.end(); sha++) {
(*sha).second->bind_uvsets(_file_to_uvset);
}
}
/**
* Returns the MayaShader object associated with the indicated "shading
* engine". This will create a new MayaShader object if this is the first
* time we have encountered the indicated engine.
*/
MayaShader *MayaShaders::
find_shader_for_shading_engine(MObject engine, bool legacy_shader) {
MFnDependencyNode engine_fn(engine);
// See if we have already decoded this engine.
string engine_name = engine_fn.name().asChar();
Shaders::const_iterator si = _shaders.find(engine_name);
if (si != _shaders.end()) {
return (*si).second;
}
// All right, this is a newly encountered shading engine. Create a new
// MayaShader object to represent it.
MayaShader *shader = new MayaShader(engine, legacy_shader);
shader->bind_uvsets(_file_to_uvset);
// Record this for the future.
_shaders.insert(Shaders::value_type(engine_name, shader));
_shaders_in_order.push_back(shader);
return shader;
}
/**
* Returns the current mapping from file to uvset for the given file texture
* name.
*/
string MayaShaders::
find_uv_link(const string &match) {
MayaFileToUVSetMap::iterator it = _file_to_uvset.find(match);
if (it == _file_to_uvset.end()) {
return "not found";
} else {
return (*it).second;
}
}
/**
* Returns the number of unique MayaShaders that have been discovered so far.
*/
int MayaShaders::
get_num_shaders() const {
return _shaders_in_order.size();
}
/**
* Returns the nth MayaShader that has been discovered so far.
*/
MayaShader *MayaShaders::
get_shader(int n) const {
nassertr(n >= 0 && n < (int)_shaders_in_order.size(), nullptr);
return _shaders_in_order[n];
}
/**
* Frees all of the previously-defined MayaShader objects associated with this
* set.
*/
void MayaShaders::
clear() {
ShadersInOrder::iterator si;
for (si = _shaders_in_order.begin(); si != _shaders_in_order.end(); ++si) {
delete (*si);
}
_shaders.clear();
_shaders_in_order.clear();
_file_to_uvset.clear();
}

View File

@ -1,51 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file mayaShaders.h
* @author drose
* @date 2000-02-11
*/
#ifndef MAYASHADERS_H
#define MAYASHADERS_H
#include "pandatoolbase.h"
#include "pmap.h"
#include "pvector.h"
#include "mayaShaderColorDef.h"
class MayaShader;
/**
* Collects the set of MayaShaders that have been encountered so far.
*/
class MayaShaders {
public:
MayaShaders();
~MayaShaders();
MayaShader *find_shader_for_node(MObject node, bool legacy_shader);
MayaShader *find_shader_for_shading_engine(MObject engine, bool legacy_shader);
int get_num_shaders() const;
MayaShader *get_shader(int n) const;
MayaFileToUVSetMap _file_to_uvset;
pvector<std::string> _uvset_names;
void clear();
void bind_uvsets(MObject mesh);
std::string find_uv_link(const std::string &match);
private:
typedef pmap<std::string, MayaShader *> Shaders;
Shaders _shaders;
typedef pvector<MayaShader *> ShadersInOrder;
ShadersInOrder _shaders_in_order;
};
#endif

View File

@ -1,26 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file maya_funcs.I
* @author drose
* @date 2002-04-15
*/
/**
*
*/
INLINE std::ostream &operator << (std::ostream &out, const MString &str) {
return out << str.asChar();
}
/**
*
*/
INLINE std::ostream &operator << (std::ostream &out, const MVector &vec) {
return out << vec.x << " " << vec.y << " " << vec.z;
}

View File

@ -1,48 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file maya_funcs.T
* @author drose
* @date 2000-02-16
*/
/**
* A generic function to extract an attribute of some type from an MObject.
* This is used to implement get_bool_attribute(), etc.
*/
template<class ValueType>
bool
get_maya_attribute(MObject &node, const std::string &attribute_name,
ValueType &value) {
bool status = false;
MPlug plug;
if (get_maya_plug(node, attribute_name, plug)) {
status = plug.getValue(value);
}
return status;
}
/**
* A generic function to set an attribute of some type on an MObject. This is
* used to implement set_bool_attribute(), etc.
*/
template<class ValueType>
bool
set_maya_attribute(MObject &node, const std::string &attribute_name,
ValueType &value) {
bool status = false;
MPlug plug;
if (get_maya_plug(node, attribute_name, plug)) {
status = plug.setValue(value);
}
return status;
}

View File

@ -1,731 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file maya_funcs.cxx
* @author drose
* @date 2000-02-16
*/
#include "maya_funcs.h"
#include "pre_maya_include.h"
#include <maya/MObject.h>
#include <maya/MAngle.h>
#include <maya/MFnDependencyNode.h>
#include <maya/MStatus.h>
#include <maya/MFnStringData.h>
#include <maya/MFnNumericData.h>
#include <maya/MPlugArray.h>
#include <maya/MPlug.h>
#include <maya/MFnAttribute.h>
#include <maya/MFnTypedAttribute.h>
#include <maya/MFnNumericAttribute.h>
#include <maya/MFnEnumAttribute.h>
#include <maya/MFnCompoundAttribute.h>
#include <maya/MFnMatrixData.h>
#include <maya/MMatrix.h>
#include "post_maya_include.h"
using std::endl;
using std::string;
/**
* Gets the named MPlug associated, if any.
*/
bool
get_maya_plug(MObject &node, const string &attribute_name, MPlug &plug) {
MStatus status;
MFnDependencyNode node_fn(node, &status);
if (!status) {
maya_cat.error()
<< "Object is a " << node.apiTypeStr() << ", not a DependencyNode.\n";
return false;
}
MObject attr = node_fn.attribute(attribute_name.c_str(), &status);
if (!status) {
return false;
}
MFnAttribute attr_fn(attr, &status);
if (!status) {
maya_cat.error()
<< "Attribute " << attribute_name << " on " << node_fn.name().asChar()
<< " is a " << attr.apiTypeStr() << ", not an Attribute.\n";
return false;
}
plug = MPlug(node, attr);
return true;
}
/**
* Returns true if the named connection exists on the node and is connected to
* anything, false otherwise.
*/
bool
is_connected(MObject &node, const string &attribute_name) {
MPlug plug;
if (!get_maya_plug(node, attribute_name, plug)) {
return false;
}
return plug.isConnected();
}
/**
* Returns true if the node has the indicated attribute, false otherwise.
*/
bool
has_attribute(MObject &node, const string &attribute_name) {
MStatus status;
MFnDependencyNode node_fn(node, &status);
if (!status) {
maya_cat.error()
<< "Object is a " << node.apiTypeStr() << ", not a DependencyNode.\n";
return false;
}
node_fn.attribute(attribute_name.c_str(), &status);
if (!status) {
// No such attribute.
return false;
}
return true;
}
/**
* Removes the named attribute from the indicated Maya node. Returns true if
* successful, false otherwise.
*/
bool
remove_attribute(MObject &node, const string &attribute_name) {
MStatus status;
MFnDependencyNode node_fn(node, &status);
if (!status) {
maya_cat.error()
<< "Object is a " << node.apiTypeStr() << ", not a DependencyNode.\n";
return false;
}
MObject attr = node_fn.attribute(attribute_name.c_str(), &status);
if (!status) {
return false;
}
{
// Just to prove the the attr is, in fact, an Attribute. According to the
// Maya docs, we shouldn't leave the MFnAttribute object around while we
// remove the attribute, though.
MFnAttribute attr_fn(attr, &status);
if (!status) {
maya_cat.error()
<< "Attribute " << attribute_name << " on " << node_fn.name().asChar()
<< " is a " << attr.apiTypeStr() << ", not an Attribute.\n";
return false;
}
}
MFnDependencyNode::MAttrClass type = node_fn.attributeClass(attr, &status);
if (!status) {
maya_cat.error()
<< "Couldn't get class of attribute " << attribute_name << " on "
<< node_fn.name().asChar() << ".\n";
return false;
}
status = node_fn.removeAttribute(attr, type);
if (!status) {
maya_cat.error()
<< "Couldn't remove attribute " << attribute_name << " from "
<< node_fn.name().asChar() << ".\n";
return false;
}
return true;
}
/**
* Extracts the named boolean attribute from the MObject.
*/
bool
get_bool_attribute(MObject &node, const string &attribute_name,
bool &value) {
if (!has_attribute(node, attribute_name)) {
// For bool attributes only, we assume if the attribute is absent it's the
// same thing as being false.
return false;
}
if (!get_maya_attribute(node, attribute_name, value)) {
maya_cat.warning()
<< "Attribute " << attribute_name
<< " does not have a bool value.\n";
describe_maya_attribute(node, attribute_name);
return false;
}
return true;
}
/**
* Extracts the named angle in degrees from the MObject.
*/
bool
get_angle_attribute(MObject &node, const string &attribute_name,
double &value) {
MAngle maya_value;
if (!get_maya_attribute(node, attribute_name, maya_value)) {
maya_cat.warning()
<< "Attribute " << attribute_name
<< " does not have an angle value.\n";
describe_maya_attribute(node, attribute_name);
return false;
}
value = maya_value.asDegrees();
return true;
}
/**
* Extracts the named two-component vector from the MObject.
*/
bool
get_vec2_attribute(MObject &node, const string &attribute_name,
LVecBase2 &value) {
MStatus status;
MObject vec2_object;
if (!get_maya_attribute(node, attribute_name, vec2_object)) {
maya_cat.warning()
<< "Attribute " << attribute_name
<< " does not have a vec2 object value.\n";
describe_maya_attribute(node, attribute_name);
return false;
}
MFnNumericData data(vec2_object, &status);
if (!status) {
maya_cat.warning()
<< "Attribute " << attribute_name << " is of type "
<< vec2_object.apiTypeStr() << ", not a NumericData.\n";
return false;
}
status = data.getData(value[0], value[1]);
if (!status) {
maya_cat.warning()
<< "Unable to extract 2 floats from " << attribute_name
<< ", of type " << vec2_object.apiTypeStr() << "\n";
}
return true;
}
/**
* Extracts the named three-component vector from the MObject.
*/
bool
get_vec3_attribute(MObject &node, const string &attribute_name,
LVecBase3 &value) {
MStatus status;
MObject vec3_object;
if (!get_maya_attribute(node, attribute_name, vec3_object)) {
maya_cat.warning()
<< "Attribute " << attribute_name
<< " does not have a vec3 object value.\n";
describe_maya_attribute(node, attribute_name);
return false;
}
MFnNumericData data(vec3_object, &status);
if (!status) {
maya_cat.warning()
<< "Attribute " << attribute_name << " is of type "
<< vec3_object.apiTypeStr() << ", not a NumericData.\n";
return false;
}
status = data.getData(value[0], value[1], value[2]);
if (!status) {
maya_cat.warning()
<< "Unable to extract 3 floats from " << attribute_name
<< ", of type " << vec3_object.apiTypeStr() << "\n";
}
return true;
}
/**
* Extracts the named two-component vector from the MObject.
*/
bool
get_vec2d_attribute(MObject &node, const string &attribute_name,
LVecBase2d &value) {
MStatus status;
MObject vec2d_object;
if (!get_maya_attribute(node, attribute_name, vec2d_object)) {
maya_cat.warning()
<< "Attribute " << attribute_name
<< " does not have a vec2d object value.\n";
describe_maya_attribute(node, attribute_name);
return false;
}
MFnNumericData data(vec2d_object, &status);
if (!status) {
maya_cat.warning()
<< "Attribute " << attribute_name << " is of type "
<< vec2d_object.apiTypeStr() << ", not a NumericData.\n";
return false;
}
status = data.getData(value[0], value[1]);
if (!status) {
maya_cat.warning()
<< "Unable to extract 2 doubles from " << attribute_name
<< ", of type " << vec2d_object.apiTypeStr() << "\n";
}
return true;
}
/**
* Extracts the named three-component vector from the MObject.
*/
bool
get_vec3d_attribute(MObject &node, const string &attribute_name,
LVecBase3d &value) {
MStatus status;
MObject vec3d_object;
if (!get_maya_attribute(node, attribute_name, vec3d_object)) {
maya_cat.warning()
<< "Attribute " << attribute_name
<< " does not have a vec3d object value.\n";
describe_maya_attribute(node, attribute_name);
return false;
}
MFnNumericData data(vec3d_object, &status);
if (!status) {
maya_cat.warning()
<< "Attribute " << attribute_name << " is of type "
<< vec3d_object.apiTypeStr() << ", not a NumericData.\n";
return false;
}
status = data.getData(value[0], value[1], value[2]);
if (!status) {
maya_cat.warning()
<< "Unable to extract 3 doubles from " << attribute_name
<< ", of type " << vec3d_object.apiTypeStr() << "\n";
}
return true;
}
/**
* Extracts the named 4x4 matrix from the MObject.
*/
bool
get_mat4d_attribute(MObject &node, const string &attribute_name,
LMatrix4d &value) {
MStatus status;
MObject matrix;
if (!get_maya_attribute(node, attribute_name, matrix)) {
return false;
}
MFnMatrixData matrix_data(matrix, &status);
if (!status) {
maya_cat.warning()
<< "Attribute " << attribute_name << " is of type "
<< node.apiTypeStr() << ", not a Matrix.\n";
return false;
}
const MMatrix &mat = matrix_data.matrix();
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
value(i, j) = mat(i, j);
}
}
return true;
}
/**
* artists should be able to set arbitrary tags. Query all the attributes on
* this object and return the lists of attribute names that has "tag" prefix
*/
void
get_tag_attribute_names(MObject &node, pvector<string> &tag_names) {
MStatus status;
MFnDependencyNode node_fn(node, &status);
if (!status) {
maya_cat.warning()
<< "Object is a " << node.apiTypeStr() << ", not a DependencyNode.\n";
return;
}
string name = node_fn.name().asChar();
unsigned i;
for (i = 0; i < node_fn.attributeCount(); i++) {
MObject attr = node_fn.attribute(i, &status);
if (status) {
MFnAttribute attrib(attr, &status);
if (status) {
string attribute_name = attrib.name().asChar();
if (attribute_name.find("tag", 0) != string::npos) {
maya_cat.info() << ":" << name << ":" << " is tagged with <"
<< attribute_name << ">" << endl;
tag_names.push_back(attribute_name);
}
}
}
}
}
/**
* Extracts the enum attribute from the MObject as a string value.
*/
bool
get_enum_attribute(MObject &node, const string &attribute_name,
string &value) {
MStatus status;
MPlug plug;
if (!get_maya_plug(node, attribute_name.c_str(), plug)) {
return false;
}
MObject attrib = plug.attribute();
MFnEnumAttribute enum_attrib(attrib, &status);
if (!status) {
maya_cat.warning()
<< "Not an enum attribute: " << attribute_name << "\n";
return false;
}
short index;
status = plug.getValue(index);
if (!status) {
maya_cat.warning()
<< "Could not get numeric value of " << attribute_name << "\n";
status.perror("MPlug::getValue(short)");
return false;
}
MString name = enum_attrib.fieldName(index, &status);
if (!status) {
maya_cat.warning()
<< "Invalid value for " << attribute_name << ": " << index << "\n";
status.perror("MFnEnumAttribute::fieldName()");
return false;
}
value = name.asChar();
return true;
}
/**
* Extracts the named string attribute from the MObject.
*/
bool
get_string_attribute(MObject &node, const string &attribute_name,
string &value) {
MStatus status;
MObject string_object;
if (!get_maya_attribute(node, attribute_name, string_object)) {
maya_cat.warning()
<< "Attribute " << attribute_name
<< " does not have an string object value.\n";
describe_maya_attribute(node, attribute_name);
return false;
}
MFnStringData data(string_object, &status);
if (!status) {
maya_cat.warning()
<< "Attribute " << attribute_name << " is of type "
<< string_object.apiTypeStr() << ", not a StringData.\n";
return false;
}
value = data.string().asChar();
return true;
}
/**
* Sets the named string attribute on the MObject.
*/
bool
set_string_attribute(MObject &node, const string &attribute_name,
const string &value) {
MStatus status;
// First, we get the string_object, then we set its string.
MObject string_object;
if (!get_maya_attribute(node, attribute_name, string_object)) {
maya_cat.warning()
<< "Attribute " << attribute_name
<< " does not have a string object value.\n";
describe_maya_attribute(node, attribute_name);
return false;
}
MFnStringData data(string_object, &status);
if (!status) {
maya_cat.warning()
<< "Attribute " << attribute_name << " is of type "
<< string_object.apiTypeStr() << ", not a StringData.\n";
return false;
}
MString mstring_value(value.data(), value.length());
status = data.set(mstring_value);
if (!status) {
status.perror(attribute_name.c_str());
return false;
}
// And it appears we now need to set the string object back.
if (!set_maya_attribute(node, attribute_name, string_object)) {
maya_cat.warning()
<< "Attribute " << attribute_name
<< " suddenly does not have a string object value.\n";
return false;
}
return true;
}
/**
* Extracts the children of this attribute from the MObject. test for now
*/
bool
describe_compound_attribute(MObject &node) {
MStatus status;
MFnCompoundAttribute comp_attr(node, &status);
maya_cat.info() << "comp_attr has:" << comp_attr.numChildren() << " children" << endl;
for (size_t i = 0; i < comp_attr.numChildren(); i++) {
MObject child = comp_attr.child(i, &status);
if (child.apiType() == MFn::kAttribute3Float){
/*
LRGBColor color;
if (get_vec3_attribute(child, "color", color)) {
maya_cat.info() << "color: " << color << endl;
}
*/
}
else if (child.apiType() == MFn::kNumericAttribute) {
MFnNumericAttribute numeric(child, &status);
if (status) {
switch(numeric.unitType()) {
case MFnNumericData::kFloat :
PN_stdfloat alpha;
status = numeric.getDefault(alpha);
maya_cat.info() << "found a float :" << alpha << endl;
break;
case MFnNumericData::kBoolean :
bool v;
status = numeric.getDefault(v);
maya_cat.info() << "found a bool :" << v << endl;
default:
maya_cat.info() << numeric.unitType() << endl;
}
}
}
else if (child.apiType() == MFn::kEnumAttribute) {
MFnEnumAttribute enu(child, &status);
if (status) {
MString blah;
status = enu.getDefault(blah);
maya_cat.info() << "found a string :" << blah.asChar() << endl;
MPlug plug = MPlug(node, child);
maya_cat.info() << "plug name" << plug.name().asChar() << endl;
}
}
}
return true;
}
/**
* Writes some warning output about the indicated Maya attribute.
*/
void
describe_maya_attribute(MObject &node, const string &attribute_name) {
MStatus status;
MFnDependencyNode node_fn(node, &status);
if (!status) {
maya_cat.warning()
<< "Object is a " << node.apiTypeStr() << ", not a DependencyNode.\n";
return;
}
MObject attr = node_fn.attribute(attribute_name.c_str(), &status);
if (!status) {
maya_cat.warning()
<< "Object " << node_fn.name().asChar() << " does not support attribute "
<< attribute_name << "\n";
return;
}
maya_cat.warning()
<< "Attribute " << attribute_name << " on object "
<< node_fn.name().asChar() << " has type " << attr.apiTypeStr() << "\n";
}
string
string_mfndata_type(MFnData::Type type) {
switch (type) {
case MFnData::kInvalid:
return "kInvalid";
case MFnData::kNumeric:
return "kNumeric";
case MFnData::kPlugin:
return "kPlugin";
case MFnData::kPluginGeometry:
return "kPluginGeometry";
case MFnData::kString:
return "kString";
case MFnData::kMatrix:
return "kMatrix";
case MFnData::kStringArray:
return "kStringArray";
case MFnData::kDoubleArray:
return "kDoubleArray";
case MFnData::kIntArray:
return "kIntArray";
case MFnData::kPointArray:
return "kPointArray";
case MFnData::kVectorArray:
return "kVectorArray";
case MFnData::kComponentList:
return "kComponentList";
case MFnData::kMesh:
return "kMesh";
case MFnData::kLattice:
return "kLattice";
case MFnData::kNurbsCurve:
return "kNurbsCurve";
case MFnData::kNurbsSurface:
return "kNurbsSurface";
case MFnData::kSphere:
return "kSphere";
case MFnData::kDynArrayAttrs:
return "kDynArrayAttrs";
case MFnData::kDynSweptGeometry:
return "kDynSweptGeometry";
case MFnData::kSubdSurface:
return "kSubdSurface";
case MFnData::kLast:
default:
break;
}
return "**invalid**";
}
/**
* Writes some info output showing all the attributes on the given dependency
* node. Primarily useful during development, to figure out where the heck
* Maya hides some of the connected properties.
*/
void
list_maya_attributes(MObject &node) {
MStatus status;
MFnDependencyNode node_fn(node, &status);
if (!status) {
maya_cat.warning()
<< "Object is a " << node.apiTypeStr() << ", not a DependencyNode.\n";
return;
}
string name = node_fn.name().asChar();
unsigned i;
MPlugArray connections;
status = node_fn.getConnections(connections);
if (!status) {
status.perror("MFnDependencyNode::getConnections");
} else {
maya_cat.info()
<< name << " has " << connections.length() << " connections.\n";
for (i = 0; i < connections.length(); i++) {
MPlug plug = connections[i];
maya_cat.info(false)
<< " " << i << ". " << plug.name().asChar() << ", "
<< plug.attribute().apiTypeStr() << ", "
<< plug.node().apiTypeStr();
if (plug.attribute().apiType() == MFn::kCompoundAttribute) {
// maya_cat.info() << plug.info();
// describe_compound_attribute(plug.attribute());
}
if (plug.isConnected()) {
maya_cat.info(false)
<< " (*)";
}
maya_cat.info(false)
<< "\n";
}
}
maya_cat.info()
<< name << " has " << node_fn.attributeCount() << " attributes.\n";
for (i = 0; i < node_fn.attributeCount(); i++) {
MObject attr = node_fn.attribute(i, &status);
if (status) {
MFnTypedAttribute typed_attrib(attr, &status);
if (status) {
// It's a typed attrib.
maya_cat.info(false)
<< " " << i << ". " << typed_attrib.name().asChar()
<< " [" << attr.apiTypeStr() << ", "
<< string_mfndata_type(typed_attrib.attrType()) << "]\n";
} else {
MFnAttribute attrib(attr, &status);
if (status) {
// It's a generic attrib.
maya_cat.info(false)
<< " " << i << ". " << attrib.name().asChar()
<< " [" << attr.apiTypeStr() << "]\n";
} else {
// Don't know what it is.
maya_cat.info(false)
<< " " << i << ". [" << attr.apiTypeStr() << "]\n";
}
}
}
}
}

View File

@ -1,118 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file maya_funcs.h
* @author drose
* @date 2000-02-16
*/
#ifndef MAYA_FUNCS_H
#define MAYA_FUNCS_H
#include "pandatoolbase.h"
#include "luse.h"
#include "config_maya.h"
#include "pre_maya_include.h"
#include <maya/MFnAttribute.h>
#include <maya/MPlug.h>
#include <maya/MStatus.h>
#include <maya/MFnDependencyNode.h>
#include <maya/MObject.h>
#include <maya/MString.h>
#include <maya/MVector.h>
#include "post_maya_include.h"
bool
get_maya_plug(MObject &node, const std::string &attribute_name, MPlug &plug);
bool
is_connected(MObject &node, const std::string &attribute_name);
template<class ValueType>
bool
get_maya_attribute(MObject &node, const std::string &attribute_name,
ValueType &value);
template<class ValueType>
bool
set_maya_attribute(MObject &node, const std::string &attribute_name,
ValueType &value);
bool
has_attribute(MObject &node, const std::string &attribute_name);
bool
remove_attribute(MObject &node, const std::string &attribute_name);
bool
get_bool_attribute(MObject &node, const std::string &attribute_name,
bool &value);
bool
get_angle_attribute(MObject &node, const std::string &attribute_name,
double &value);
bool
get_vec2_attribute(MObject &node, const std::string &attribute_name,
LVecBase2 &value);
bool
get_vec3_attribute(MObject &node, const std::string &attribute_name,
LVecBase3 &value);
bool
get_vec2d_attribute(MObject &node, const std::string &attribute_name,
LVecBase2d &value);
bool
get_vec3d_attribute(MObject &node, const std::string &attribute_name,
LVecBase3d &value);
bool
get_mat4d_attribute(MObject &node, const std::string &attribute_name,
LMatrix4d &value);
void
get_tag_attribute_names(MObject &node, pvector<std::string> &tag_names);
bool
get_enum_attribute(MObject &node, const std::string &attribute_name,
std::string &value);
bool
get_string_attribute(MObject &node, const std::string &attribute_name,
std::string &value);
bool
set_string_attribute(MObject &node, const std::string &attribute_name,
const std::string &value);
void
describe_maya_attribute(MObject &node, const std::string &attribute_name);
bool
describe_compound_attribute(MObject &node);
std::string
string_mfndata_type(MFnData::Type type);
void
list_maya_attributes(MObject &node);
// Also, we must define some output functions for Maya objects, since we can't
// use those built into Maya (which forward-defines the ostream type
// incorrectly).
INLINE std::ostream &operator << (std::ostream &out, const MString &str);
INLINE std::ostream &operator << (std::ostream &out, const MVector &vec);
#include "maya_funcs.I"
#include "maya_funcs.T"
#endif

View File

@ -1,6 +0,0 @@
#include "config_maya.cxx"
#include "mayaApi.cxx"
#include "mayaShader.cxx"
#include "mayaShaderColorDef.cxx"
#include "mayaShaders.cxx"
#include "maya_funcs.cxx"

View File

@ -1,15 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file post_maya_include.h
* @author drose
* @date 2002-04-11
*/
// This header file works in conjunction with pre_maya_include.h; it cleans up
// some of the definitions that it left open.

View File

@ -1,63 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file pre_maya_include.h
* @author drose
* @date 2002-04-11
*/
// This header file defines a few things that are necessary to define before
// including any Maya headers, just to work around some of Maya's assumptions
// about the compiler. It must not try to protect itself from multiple
// inclusion with #ifdef .. #endif, since it must be used each time it is
// included.
// Maya 2008 will declare some VS2005-specific hacks unless we define this.
#if defined(_MSC_VER) && _MSC_VER < 1400
#define MLIBRARY_DONTUSE_MFC_MANIFEST
#endif
// Maya will try to typedef bool unless this symbol is defined.
#ifndef _BOOL
#define _BOOL 1
#endif
// In Maya 5.0, the headers seem to provide the manifest REQUIRE_IOSTREAM,
// which forces it to use the new <iostream> headers instead of the old
// <iostream.h> headers. It also says this is for Linux only, but it seems to
// work just fine on Windows, obviating the need for sneaky #defines in this
// and in post_maya_include.h.
#ifdef PHAVE_IOSTREAM
#define REQUIRE_IOSTREAM
#endif // PHAVE_IOSTREAM
#ifdef __MACH__
#define OSMac_ 1
// This defines MAYA_API_VERSION
#include <maya/MTypes.h>
#if MAYA_API_VERSION < 201600
#include <maya/OpenMayaMac.h>
#endif
#else
// This defines MAYA_API_VERSION
#include <maya/MTypes.h>
#endif
#if MAYA_API_VERSION >= 20180000
#include <maya/MApiNamespace.h>
#else
class MObject;
class MDagPath;
class MFloatArray;
class MFnDagNode;
class MFnMesh;
class MFnNurbsCurve;
class MFnNurbsSurface;
class MPlug;
class MPointArray;
#endif

View File

@ -1,64 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file config_mayaegg.cxx
* @author drose
* @date 2002-04-15
*/
#include "config_mayaegg.h"
#include "mayaEggGroupUserData.h"
#include "mayaNodeDesc.h"
#include "mayaBlendDesc.h"
#include "configVariableBool.h"
#include "dconfig.h"
Configure(config_mayaegg);
NotifyCategoryDef(mayaegg, ":maya");
ConfigureFn(config_mayaegg) {
init_libmayaegg();
}
// These control the default behavior of the mayaegg converter, but not
// necessarily the default behavior of the maya2egg command-line tool (which
// has its own defaults).
// Should we respect the Maya double-sided flag (true) or ignore it and assume
// everything is single-sided (false)?
bool maya_default_double_sided;
// Should we apply vertex color even when a texture is applied (true) or only
// when no texture is applied or the vertex-color egg flag is set (false)?
bool maya_default_vertex_color;
/**
* Initializes the library. This must be called at least once before any of
* the functions or classes in this library can be used. Normally it will be
* called by the static initializers and need not be called explicitly, but
* special cases exist.
*/
void
init_libmayaegg() {
static bool initialized = false;
if (initialized) {
return;
}
initialized = true;
MayaEggGroupUserData::init_type();
MayaNodeDesc::init_type();
MayaBlendDesc::init_type();
// For some reason, static init is not reliably running when this is loaded
// as a plug-in of a plug-in. Initialize these explicitly here.
maya_default_double_sided = ConfigVariableBool("maya-default-double-sided", false).get_value();
maya_default_vertex_color = ConfigVariableBool("maya-default-vertex-color", true).get_value();
}

View File

@ -1,27 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file config_mayaegg.h
* @author drose
* @date 2002-04-15
*/
#ifndef CONFIG_MAYAEGG_H
#define CONFIG_MAYAEGG_H
#include "pandatoolbase.h"
#include "notifyCategoryProxy.h"
NotifyCategoryDeclNoExport(mayaegg);
extern bool maya_default_double_sided;
extern bool maya_default_vertex_color;
extern void init_libmayaegg();
#endif

View File

@ -1,69 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file mayaBlendDesc.cxx
* @author drose
* @date 2004-02-10
*/
#include "mayaBlendDesc.h"
#include "config_mayaegg.h"
TypeHandle MayaBlendDesc::_type_handle;
/**
*
*/
MayaBlendDesc::
MayaBlendDesc(MFnBlendShapeDeformer &deformer, int weight_index) :
_deformer(deformer.object()),
_weight_index(weight_index)
{
std::ostringstream strm;
strm << _deformer.name().asChar() << "." << _weight_index;
set_name(strm.str());
_anim = nullptr;
}
/**
*
*/
MayaBlendDesc::
~MayaBlendDesc() {
}
/**
* Moves the Maya slider associated with this blend shape to the indicated
* value. This will move all the affected vertices.
*/
void MayaBlendDesc::
set_slider(PN_stdfloat value) {
MStatus status = _deformer.setWeight(_weight_index, value);
if (!status) {
mayaegg_cat.warning()
<< "Unable to set slider " << get_name() << "\n";
}
}
/**
* Returns the current position of the Maya slider associated with this blend
* shape.
*/
PN_stdfloat MayaBlendDesc::
get_slider() const {
return _deformer.weight(_weight_index);
}
/**
* Clears the egg pointers from this blend desc.
*/
void MayaBlendDesc::
clear_egg() {
_anim = nullptr;
}

View File

@ -1,74 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file mayaBlendDesc.h
* @author drose
* @date 2004-02-10
*/
#ifndef MAYABLENDDESC_H
#define MAYABLENDDESC_H
#include "pandatoolbase.h"
#include "referenceCount.h"
#include "pointerTo.h"
#include "namable.h"
#include "pre_maya_include.h"
#include <maya/MFnBlendShapeDeformer.h>
#include <maya/MObject.h>
#include "post_maya_include.h"
class EggTable;
class EggSAnimData;
/**
* A handle to a Maya blend shape description. This is just one target of a
* Maya BlendShape object, and thus corresponds more or less one-to-one with a
* single Egg morph target. (We don't attempt to support Maya's chained
* target shapes here; should we need to later, it would mean breaking each of
* those target shapes on the one continuous Maya slider into a separate
* MayaBlendDesc object, and synthesizing the egg slider values
* appropriately.)
*/
class MayaBlendDesc : public ReferenceCount, public Namable {
public:
MayaBlendDesc(MFnBlendShapeDeformer &deformer, int weight_index);
~MayaBlendDesc();
void set_slider(PN_stdfloat value);
PN_stdfloat get_slider() const;
private:
void clear_egg();
MFnBlendShapeDeformer _deformer;
int _weight_index;
EggSAnimData *_anim;
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
ReferenceCount::init_type();
Namable::init_type();
register_type(_type_handle, "MayaBlendDesc",
ReferenceCount::get_class_type(),
Namable::get_class_type());
}
private:
static TypeHandle _type_handle;
friend class MayaNodeTree;
};
#endif

View File

@ -1,44 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file mayaEggGroupUserData.I
* @author drose
* @date 2003-06-03
*/
/**
*
*/
INLINE MayaEggGroupUserData::
MayaEggGroupUserData() {
_vertex_color = false;
_double_sided = false;
}
/**
*
*/
INLINE MayaEggGroupUserData::
MayaEggGroupUserData(const MayaEggGroupUserData &copy) :
EggUserData(copy),
_vertex_color(copy._vertex_color),
_double_sided(copy._double_sided)
{
}
/**
*
*/
INLINE void MayaEggGroupUserData::
operator = (const MayaEggGroupUserData &copy) {
EggUserData::operator = (copy);
_vertex_color = copy._vertex_color;
_double_sided = copy._double_sided;
}

View File

@ -1,16 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file mayaEggGroupUserData.cxx
* @author drose
* @date 2003-06-03
*/
#include "mayaEggGroupUserData.h"
TypeHandle MayaEggGroupUserData::_type_handle;

View File

@ -1,53 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file mayaEggGroupUserData.h
* @author drose
* @date 2003-06-03
*/
#ifndef MAYAEGGGROUPUSERDATA_H
#define MAYAEGGGROUPUSERDATA_H
#include "pandatoolbase.h"
#include "eggUserData.h"
/**
* This class contains extra user data which is piggybacked onto EggGroup
* objects for the purpose of the maya converter.
*/
class MayaEggGroupUserData : public EggUserData {
public:
INLINE MayaEggGroupUserData();
INLINE MayaEggGroupUserData(const MayaEggGroupUserData &copy);
INLINE void operator = (const MayaEggGroupUserData &copy);
bool _vertex_color;
bool _double_sided;
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
EggUserData::init_type();
register_type(_type_handle, "MayaEggGroupUserData",
EggUserData::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
private:
static TypeHandle _type_handle;
};
#include "mayaEggGroupUserData.I"
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,22 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file mayaEggLoader.h
* @author jyelon
* @date 2005-07-20
*/
#ifndef MAYAEGGLOADER_H
#define MAYAEGGLOADER_H
class EggData;
bool MayaLoadEggData(EggData *data, bool merge, bool model, bool anim, bool respect_normals);
bool MayaLoadEggFile(const char *name, bool merge, bool model, bool anim, bool respect_normals);
#endif

View File

@ -1,572 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file mayaNodeDesc.cxx
* @author drose
* @date 2003-06-06
*/
#include "mayaNodeDesc.h"
#include "mayaNodeTree.h"
#include "mayaBlendDesc.h"
#include "mayaToEggConverter.h"
#include "maya_funcs.h"
#include "eggGroup.h"
#include "config_mayaegg.h"
#include "pre_maya_include.h"
#include <maya/MFnBlendShapeDeformer.h>
#include <maya/MItDependencyGraph.h>
#include <maya/MFnNurbsSurface.h>
#include <maya/MFnMesh.h>
#include "post_maya_include.h"
using std::string;
TypeHandle MayaNodeDesc::_type_handle;
// This is a list of the names of Maya connections that count as a transform.
static const char *transform_connections[] = {
"translate",
"translateX",
"translateY",
"translateZ",
"rotate",
"rotateX",
"rotateY",
"rotateZ",
};
static const int num_transform_connections = sizeof(transform_connections) / sizeof(const char *);
/**
*
*/
MayaNodeDesc::
MayaNodeDesc(MayaNodeTree *tree, MayaNodeDesc *parent, const string &name) :
Namable(name),
_tree(tree),
_parent(parent)
{
_dag_path = nullptr;
_egg_group = nullptr;
_egg_table = nullptr;
_anim = nullptr;
_joint_type = JT_none;
_is_lod = false;
_tagged = false;
_joint_tagged = false;
// Add ourselves to our parent.
if (_parent != nullptr) {
_parent->_children.push_back(this);
}
}
/**
*
*/
MayaNodeDesc::
~MayaNodeDesc() {
delete _dag_path;
}
/**
* Indicates an association between the MayaNodeDesc and some Maya instance.
*/
void MayaNodeDesc::
from_dag_path(const MDagPath &dag_path, MayaToEggConverter *converter) {
MStatus status;
if (_dag_path == nullptr) {
_dag_path = new MDagPath(dag_path);
string name;
MFnDagNode dag_node(dag_path, &status);
if (!status) {
status.perror("MFnDagNode constructor");
} else {
name = dag_node.name().asChar();
}
if (_dag_path->hasFn(MFn::kJoint) || converter->force_joint(name)) {
// This node is a joint, or the user specifically asked to treat it like
// a joint.
_joint_type = JT_joint;
if (_parent != nullptr) {
_parent->mark_joint_parent();
}
} else {
// The node is not a joint, but maybe its transform is controlled by
// connected inputs. If so, we should treat it like a joint.
bool transform_connected = false;
MStatus status;
MObject node = dag_path.node(&status);
if (status) {
for (int i = 0;
i < num_transform_connections && !transform_connected;
i++) {
if (is_connected(node, transform_connections[i])) {
transform_connected = true;
}
}
}
if (transform_connected) {
_joint_type = JT_joint;
if (_parent != nullptr) {
_parent->mark_joint_parent();
}
}
}
if (dag_path.hasFn(MFn::kNurbsSurface)) {
MFnNurbsSurface surface(dag_path, &status);
if (status) {
check_blend_shapes(surface, "create");
}
} else if (dag_path.hasFn(MFn::kMesh)) {
MFnMesh mesh(dag_path, &status);
if (status) {
check_blend_shapes(mesh, "inMesh");
}
}
}
}
/**
* Returns true if a Maya dag path has been associated with this node, false
* otherwise.
*/
bool MayaNodeDesc::
has_dag_path() const {
return (_dag_path != nullptr);
}
/**
* Returns the dag path associated with this node. It is an error to call
* this unless has_dag_path() returned true.
*/
const MDagPath &MayaNodeDesc::
get_dag_path() const {
nassertr(_dag_path != nullptr, *_dag_path);
return *_dag_path;
}
/**
* Returns the number of unique MayaBlendDesc objects (and hence the number of
* morph sliders) that affect the geometry in this node.
*/
int MayaNodeDesc::
get_num_blend_descs() const {
return _blend_descs.size();
}
/**
* Returns the nth MayaBlendDesc object that affects the geometry in this
* node.
*/
MayaBlendDesc *MayaNodeDesc::
get_blend_desc(int n) const {
nassertr(n >= 0 && n < (int)_blend_descs.size(), nullptr);
return _blend_descs[n];
}
/**
* Returns true if the node should be treated as a joint by the converter.
*/
bool MayaNodeDesc::
is_joint() const {
// return _joint_type == JT_joint || _joint_type == JT_pseudo_joint;
return _joint_tagged && (_joint_type == JT_joint || _joint_type == JT_pseudo_joint);
}
/**
* Returns true if the node is the parent or ancestor of a joint.
*/
bool MayaNodeDesc::
is_joint_parent() const {
return _joint_type == JT_joint_parent;
// return _joint_tagged && (_joint_type == JT_joint_parent);
}
/**
* Returns true if the node has been joint_tagged to be converted, false
* otherwise.
*/
bool MayaNodeDesc::
is_joint_tagged() const {
return _joint_tagged;
}
/**
* Tags this node for conversion, but does not tag child nodes.
*/
void MayaNodeDesc::
tag_joint() {
_joint_tagged = true;
}
/**
* Tags this node and all descendant nodes for conversion.
*/
void MayaNodeDesc::
tag_joint_recursively() {
_joint_tagged = true;
// mayaegg_cat.info() << "tjr: " << get_name() << endl;
Children::const_iterator ci;
for (ci = _children.begin(); ci != _children.end(); ++ci) {
MayaNodeDesc *child = (*ci);
child->tag_joint_recursively();
}
}
/**
* Returns true if the node has been tagged to be converted, false otherwise.
*/
bool MayaNodeDesc::
is_tagged() const {
return _tagged;
}
/**
* Tags this node for conversion, but does not tag child nodes.
*/
void MayaNodeDesc::
tag() {
_tagged = true;
}
/**
* Un-tags this node for conversion, but does not tag child nodes.
*/
void MayaNodeDesc::
untag() {
_tagged = false;
}
/**
* Tags this node and all descendant nodes for conversion.
*/
void MayaNodeDesc::
tag_recursively() {
_tagged = true;
Children::const_iterator ci;
for (ci = _children.begin(); ci != _children.end(); ++ci) {
MayaNodeDesc *child = (*ci);
child->tag_recursively();
}
}
/**
* Un-tags this node and all descendant nodes for conversion.
*/
void MayaNodeDesc::
untag_recursively() {
_tagged = false;
Children::const_iterator ci;
for (ci = _children.begin(); ci != _children.end(); ++ci) {
MayaNodeDesc *child = (*ci);
child->untag_recursively();
}
}
/**
* Returns true if this node or any of its parent has_object_type of
* object_type.
*/
bool MayaNodeDesc::
has_object_type(string object_type) const {
bool ret = false;
if ((_egg_group != nullptr)
&& _egg_group->has_object_type(object_type)) {
return true;
}
if (_parent != nullptr) {
ret |= _parent->has_object_type(object_type);
}
return ret;
}
/**
* Recursively clears the egg pointers from this node and all children.
*/
void MayaNodeDesc::
clear_egg() {
_egg_group = nullptr;
_egg_table = nullptr;
_anim = nullptr;
Children::const_iterator ci;
for (ci = _children.begin(); ci != _children.end(); ++ci) {
MayaNodeDesc *child = (*ci);
child->clear_egg();
}
}
/**
* Indicates that this node has at least one child that is a joint or a
* pseudo-joint.
*/
void MayaNodeDesc::
mark_joint_parent() {
if (_joint_type == JT_none) {
_joint_type = JT_joint_parent;
if (_parent != nullptr) {
_parent->mark_joint_parent();
}
}
}
/**
* Walks the hierarchy, looking for non-joint nodes that are both children and
* parents of a joint. These nodes are deemed to be pseudo joints, since the
* converter must treat them as joints.
*/
void MayaNodeDesc::
check_pseudo_joints(bool joint_above) {
static uint32_t space_count = 0;
string space;
for (uint32_t idx=0; idx<space_count; ++idx) {
space.append(" ");
}
if (mayaegg_cat.is_spam()) {
mayaegg_cat.spam() << "cpj:" << space << get_name() << " joint_type: " << _joint_type << std::endl;
}
if (_joint_type == JT_joint_parent && joint_above) {
// This is one such node: it is the parent of a joint (JT_joint_parent is
// set), and it is the child of a joint (joint_above is set).
_joint_type = JT_pseudo_joint;
}
if (_joint_type == JT_joint) {
// If this node is itself a joint, then joint_above is true for all child
// nodes.
joint_above = true;
}
// Don't bother traversing further if _joint_type is none, since that means
// this node has no joint children.
if (_joint_type != JT_none) {
bool any_joints = false;
Children::const_iterator ci;
for (ci = _children.begin(); ci != _children.end(); ++ci) {
MayaNodeDesc *child = (*ci);
if (mayaegg_cat.is_spam()) {
++space_count;
}
child->check_pseudo_joints(joint_above);
// if (child->is_joint()) {
if (child->_joint_type == JT_joint || child->_joint_type == JT_pseudo_joint) {
any_joints = true;
}
}
// If any children qualify as joints, then any sibling nodes that are
// parents of joints are also elevated to joints.
if (any_joints) {
bool all_joints = true;
for (ci = _children.begin(); ci != _children.end(); ++ci) {
MayaNodeDesc *child = (*ci);
MStatus status;
MFnDagNode dag_node(child->get_dag_path(), &status);
if (!status) {
status.perror("MFnDagNode constructor");
}
string type_name = dag_node.typeName().asChar();
if (child->_joint_type == JT_joint_parent) {
child->_joint_type = JT_pseudo_joint;
} else if (child->_joint_type == JT_none) {
if (mayaegg_cat.is_spam()) {
mayaegg_cat.spam() << "cpj: " << space << "jt_none for " << child->get_name() << std::endl;
}
if (type_name.find("transform") == string::npos) {
if (mayaegg_cat.is_spam()) {
mayaegg_cat.spam() << "cpj: " << space << "all_joints false for " << get_name() << std::endl;
}
all_joints = false;
}
}
}
if (all_joints) {
// Finally, if all children are joints, then we are too.
if (_joint_type == JT_joint_parent) {
if (!get_name().empty()) { // make sure parent of root is not a joint
_joint_type = JT_pseudo_joint;
}
}
}
}
}
if (mayaegg_cat.is_spam()) {
if (space_count > 0)
--space_count;
}
}
/**
* Looks for blend shapes on a NURBS surface or polygon mesh and records any
* blend shapes found. This is similar to
* MayaToEggConverter::get_vertex_weights(), which checks for membership of
* vertices to joints; Maya stores the blend shape table in the same place.
* See the comments in get_vertex_weights() for a more in-depth description of
* the iteration process here.
*/
void MayaNodeDesc::
check_blend_shapes(const MFnDagNode &node, const string &attrib_name) {
MStatus status;
MObject attr = node.attribute(attrib_name.c_str());
MPlug history(node.object(), attr);
MItDependencyGraph it(history, MFn::kDependencyNode,
MItDependencyGraph::kUpstream,
MItDependencyGraph::kDepthFirst,
MItDependencyGraph::kNodeLevel);
while (!it.isDone()) {
MObject c_node = it.thisNode();
if (c_node.hasFn(MFn::kBlendShape)) {
MFnBlendShapeDeformer blends(c_node, &status);
if (!status) {
status.perror("MFnBlendShapeDeformer constructor");
} else {
// Check if the slider is a "parallel blender", which is a construct
// created by Maya for Maya's internal purposes only. We don't want
// to fiddle with the parallel blenders.
MPlug plug = blends.findPlug("pb");
bool is_parallel_blender;
status = plug.getValue(is_parallel_blender);
if (!status) {
status.perror("Could not get value of pb plug.");
is_parallel_blender = false;
}
if (is_parallel_blender ||
_tree->ignore_slider(blends.name().asChar())) {
_tree->report_ignored_slider(blends.name().asChar());
} else {
MObjectArray base_objects;
status = blends.getBaseObjects(base_objects);
if (!status) {
status.perror("MFnBlendShapeDeformer::getBaseObjects");
} else {
for (unsigned int oi = 0; oi < base_objects.length(); oi++) {
MObject base_object = base_objects[oi];
MIntArray index_list;
status = blends.weightIndexList(index_list);
if (!status) {
status.perror("MFnBlendShapeDeformer::weightIndexList");
} else {
for (unsigned int i = 0; i < index_list.length(); i++) {
int wi = index_list[i];
PT(MayaBlendDesc) blend_desc = new MayaBlendDesc(blends, wi);
blend_desc = _tree->add_blend_desc(blend_desc);
_blend_descs.push_back(blend_desc);
}
}
}
}
}
}
}
it.next();
}
}
/**
* Walks through the hierarchy again and checks for LOD specifications. Any
* such specifications found are recorded on the child nodes of the lodGroups
* themselves: the nodes that actually switch in and out. (This is the way
* they are recorded in an egg file.)
*/
void MayaNodeDesc::
check_lods() {
// Walk through the children first. This makes it easier in the below (we
// only have to return in the event of an error).
Children::iterator ci;
for (ci = _children.begin(); ci != _children.end(); ++ci) {
MayaNodeDesc *child = (*ci);
child->check_lods();
}
// Now consider whether this node is an lodGroup.
if (_dag_path != nullptr &&
_dag_path->hasFn(MFn::kLodGroup)) {
// This node is a parent lodGroup; its children, therefore, are LOD's.
MStatus status;
MFnDagNode dag_node(*_dag_path, &status);
if (!status) {
status.perror("Couldn't get node from dag path for lodGroup");
return;
}
MPlug plug = dag_node.findPlug("threshold", &status);
if (!status) {
status.perror("Couldn't get threshold attributes on lodGroup");
return;
}
// There ought to be the one fewer elements in the array than there are
// children of the node.
unsigned int num_elements = plug.numElements();
unsigned int num_children = _children.size();
if (num_elements + 1 != num_children) {
mayaegg_cat.warning()
<< "Node " << get_name() << " has " << num_elements
<< " LOD entries, but " << num_children << " children.\n";
}
// Should we also consider cameraMatrix, to transform the LOD's origin?
// It's not clear precisely what this transform matrix means in Maya, so
// we'll wait until we have a sample file that demonstrates its use.
double switch_out = 0.0;
unsigned int i = 0;
while (i < num_elements && i < num_children) {
MPlug element = plug.elementByLogicalIndex(i);
MayaNodeDesc *child = _children[i];
double switch_in;
status = element.getValue(switch_in);
if (!status) {
status.perror("Couldn't get double value from threshold.");
return;
}
child->_is_lod = true;
child->_switch_in = switch_in;
child->_switch_out = switch_out;
switch_out = switch_in;
++i;
}
while (i < num_children) {
// Also set the last child(ren). Maya wants this to switch in at
// infinity, but Panda doesn't have such a concept; we'll settle for
// four times the switch_out distance.
MayaNodeDesc *child = _children[i];
child->_is_lod = true;
child->_switch_in = switch_out * 4.0;
child->_switch_out = switch_out;
++i;
}
}
}

View File

@ -1,122 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file mayaNodeDesc.h
* @author drose
* @date 2003-06-06
*/
#ifndef MAYANODEDESC_H
#define MAYANODEDESC_H
#include "pandatoolbase.h"
#include "mayaBlendDesc.h"
#include "referenceCount.h"
#include "pointerTo.h"
#include "namable.h"
#include "pre_maya_include.h"
#include <maya/MDagPath.h>
#include <maya/MFnDagNode.h>
#include "post_maya_include.h"
class MayaToEggConverter;
class MayaNodeTree;
class EggGroup;
class EggTable;
class EggXfmSAnim;
/**
* Describes a single instance of a node in the Maya scene graph, relating it
* to the corresponding egg structures (e.g. node, group, or table entry)
* that will be created.
*/
class MayaNodeDesc : public ReferenceCount, public Namable {
public:
MayaNodeDesc(MayaNodeTree *tree,
MayaNodeDesc *parent = nullptr, const std::string &name = std::string());
~MayaNodeDesc();
void from_dag_path(const MDagPath &dag_path, MayaToEggConverter *converter);
bool has_dag_path() const;
const MDagPath &get_dag_path() const;
int get_num_blend_descs() const;
MayaBlendDesc *get_blend_desc(int n) const;
bool is_joint() const;
bool is_joint_parent() const;
bool is_tagged() const;
bool is_joint_tagged() const;
bool has_object_type(std::string object_type) const;
MayaNodeTree *_tree;
MayaNodeDesc *_parent;
typedef pvector< PT(MayaNodeDesc) > Children;
Children _children;
private:
void tag();
void untag();
void tag_recursively();
void untag_recursively();
void tag_joint();
void tag_joint_recursively();
void clear_egg();
void mark_joint_parent();
void check_pseudo_joints(bool joint_above);
void check_blend_shapes(const MFnDagNode &node,
const std::string &attrib_name);
void check_lods();
MDagPath *_dag_path;
EggGroup *_egg_group;
EggTable *_egg_table;
EggXfmSAnim *_anim;
typedef pvector< PT(MayaBlendDesc) > BlendDescs;
BlendDescs _blend_descs;
enum JointType {
JT_none, // Not a joint.
JT_joint, // An actual joint in Maya.
JT_pseudo_joint, // Not a joint in Maya, but treated just like a
// joint for the purposes of the converter.
JT_joint_parent, // A parent or ancestor of a joint or pseudo joint.
};
JointType _joint_type;
bool _is_lod;
double _switch_in, _switch_out;
bool _tagged;
bool _joint_tagged;
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
ReferenceCount::init_type();
Namable::init_type();
register_type(_type_handle, "MayaNodeDesc",
ReferenceCount::get_class_type(),
Namable::get_class_type());
}
private:
static TypeHandle _type_handle;
friend class MayaNodeTree;
};
#endif

View File

@ -1,634 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file mayaNodeTree.cxx
* @author drose
* @date 2003-06-06
*/
#include "mayaNodeTree.h"
#include "mayaBlendDesc.h"
#include "mayaEggGroupUserData.h"
#include "mayaToEggConverter.h"
#include "config_mayaegg.h"
#include "maya_funcs.h"
#include "eggGroup.h"
#include "eggTable.h"
#include "eggXfmSAnim.h"
#include "eggSAnimData.h"
#include "eggData.h"
#include "eggSwitchCondition.h"
#include "dcast.h"
#include "pre_maya_include.h"
#include <maya/MString.h>
#include <maya/MItDag.h>
#include <maya/MSelectionList.h>
#include <maya/MGlobal.h>
#include "post_maya_include.h"
#include <sstream>
using std::string;
/**
*
*/
MayaNodeTree::
MayaNodeTree(MayaToEggConverter *converter) :
_converter(converter)
{
_root = new MayaNodeDesc(this);
_fps = 0.0;
_egg_data = nullptr;
_egg_root = nullptr;
_skeleton_node = nullptr;
_morph_node = nullptr;
}
/**
* Returns a pointer to the node corresponding to the indicated dag_path
* object, creating it first if necessary.
*/
MayaNodeDesc *MayaNodeTree::
build_node(const MDagPath &dag_path) {
MayaNodeDesc *node_desc = r_build_node(dag_path.fullPathName().asChar());
node_desc->from_dag_path(dag_path, _converter);
return node_desc;
}
/**
* Walks through the complete Maya hierarchy but does not tag any nodes for
* conversion.
*/
bool MayaNodeTree::
build_hierarchy() {
MStatus status;
MItDag dag_iterator(MItDag::kDepthFirst, MFn::kTransform, &status);
if (!status) {
status.perror("MItDag constructor");
return false;
}
/*
// this is how you can reset the traverser to a specific node
status = dag_iterator.reset(dag_iterator.item(),MItDag::kDepthFirst, MFn::kTransform);
*/
// Get the entire Maya scene.
// This while loop walks through the entire Maya hierarchy, one node at a
// time. Maya's MItDag object automatically performs a depth-first
// traversal of its scene graph.
bool all_ok = true;
while (!dag_iterator.isDone()) {
MDagPath dag_path;
status = dag_iterator.getPath(dag_path);
if (!status) {
status.perror("MItDag::getPath");
} else {
build_node(dag_path);
}
dag_iterator.next();
}
if (all_ok) {
_root->check_pseudo_joints(false);
_root->check_lods();
}
return all_ok;
}
/**
* Tags the entire hierarchy for conversion. This is the normal behavior.
*/
void MayaNodeTree::
tag_joint_all() {
_root->tag_joint_recursively();
}
/**
* Tags nodes matching the indicated glob (and all of their children) for
* conversion. Returns true on success, false otherwise (e.g. the named node
* does not exist).
*/
bool MayaNodeTree::
tag_joint_named(const GlobPattern &glob) {
// There might be multiple nodes matching the name; search for all of them.
bool found_any = false;
Nodes::iterator ni;
for (ni = _nodes.begin(); ni != _nodes.end(); ++ni) {
MayaNodeDesc *node = (*ni);
if (glob.matches(node->get_name())) {
node->tag_joint_recursively();
found_any = true;
}
}
return found_any;
}
/**
* Tags the entire hierarchy for conversion. This is the normal behavior.
*/
void MayaNodeTree::
tag_all() {
_root->tag_recursively();
}
/**
* Tags nodes matching the indicated glob (and all of their children) for
* conversion. Returns true on success, false otherwise (e.g. the named node
* does not exist).
*/
bool MayaNodeTree::
tag_named(const GlobPattern &glob) {
// There might be multiple nodes matching the name; search for all of them.
bool found_any = false;
Nodes::iterator ni;
for (ni = _nodes.begin(); ni != _nodes.end(); ++ni) {
MayaNodeDesc *node = (*ni);
if (glob.matches(node->get_name())) {
node->tag_recursively();
found_any = true;
}
}
return found_any;
}
/**
* Un-tags nodes matching the indicated glob (and all of their children) for
* conversion. Returns true on success, false otherwise (e.g. the named node
* does not exist).
*/
bool MayaNodeTree::
untag_named(const GlobPattern &glob) {
// There might be multiple nodes matching the name; search for all of them.
bool found_any = false;
Nodes::iterator ni;
for (ni = _nodes.begin(); ni != _nodes.end(); ++ni) {
MayaNodeDesc *node = (*ni);
if (glob.matches(node->get_name())) {
node->untag_recursively();
found_any = true;
}
}
return found_any;
}
/**
* Tags the just the selected hierarchy for conversion, or the entire
* hierarchy if nothing is selected. Returns true on success, false on
* failure.
*/
bool MayaNodeTree::
tag_selected() {
MStatus status;
MItDag dag_iterator(MItDag::kDepthFirst, MFn::kTransform, &status);
if (!status) {
status.perror("MItDag constructor");
return false;
}
MSelectionList selection;
status = MGlobal::getActiveSelectionList(selection);
if (!status) {
status.perror("MGlobal::getActiveSelectionList");
return false;
}
if (selection.isEmpty()) {
mayaegg_cat.info()
<< "Selection list is empty.\n";
tag_all();
return true;
}
bool all_ok = true;
unsigned int length = selection.length();
for (unsigned int i = 0; i < length; i++) {
MDagPath root_path;
status = selection.getDagPath(i, root_path);
if (!status) {
status.perror("MSelectionList::getDagPath");
} else {
// Now traverse through the selected dag path and all nested dag paths.
dag_iterator.reset(root_path);
while (!dag_iterator.isDone()) {
MDagPath dag_path;
status = dag_iterator.getPath(dag_path);
if (!status) {
status.perror("MItDag::getPath");
} else {
build_node(dag_path)->tag();
}
dag_iterator.next();
}
}
}
if (all_ok) {
_root->check_pseudo_joints(false);
}
return all_ok;
}
/**
* Returns the total number of nodes in the hierarchy, not counting the root
* node.
*/
int MayaNodeTree::
get_num_nodes() const {
return _nodes.size();
}
/**
* Returns the nth node in the hierarchy, in an arbitrary ordering.
*/
MayaNodeDesc *MayaNodeTree::
get_node(int n) const {
nassertr(n >= 0 && n < (int)_nodes.size(), nullptr);
return _nodes[n];
}
/**
* Resets the entire tree in preparation for repopulating with a new scene.
*/
void MayaNodeTree::
clear() {
_root = new MayaNodeDesc(this);
_fps = 0.0;
_egg_data = nullptr;
_egg_root = nullptr;
_skeleton_node = nullptr;
_morph_node = nullptr;
_nodes_by_path.clear();
_nodes.clear();
}
/**
* Removes all of the references to generated egg structures from the tree,
* and prepares the tree for generating new egg structures.
*/
void MayaNodeTree::
clear_egg(EggData *egg_data, EggGroupNode *egg_root,
EggGroupNode *skeleton_node, EggGroupNode *morph_node) {
_root->clear_egg();
BlendDescs::iterator bi;
for (bi = _blend_descs.begin(); bi != _blend_descs.end(); ++bi) {
(*bi)->clear_egg();
}
_egg_data = egg_data;
_egg_root = egg_root;
_skeleton_node = skeleton_node;
_morph_node = morph_node;
}
/**
* Returns the EggGroupNode corresponding to the group or joint for the
* indicated node. Creates the group node if it has not already been created.
*/
EggGroup *MayaNodeTree::
get_egg_group(MayaNodeDesc *node_desc) {
nassertr(_egg_root != nullptr, nullptr);
if (node_desc->_egg_group == nullptr) {
// We need to make a new group node.
EggGroup *egg_group;
nassertr(node_desc->_parent != nullptr, nullptr);
egg_group = new EggGroup(node_desc->get_name());
if (node_desc->is_joint()) {
if (_converter->get_animation_convert() == AC_model ||
_converter->get_animation_convert() == AC_both) {
egg_group->set_group_type(EggGroup::GT_joint);
}
}
MayaEggGroupUserData *parent_user_data = nullptr;
if (node_desc->_parent == _root) {
// The parent is the root.
_egg_root->add_child(egg_group);
} else {
// The parent is another node.
EggGroup *parent_egg_group = get_egg_group(node_desc->_parent);
parent_egg_group->add_child(egg_group);
if (parent_egg_group->has_user_data()) {
DCAST_INTO_R(parent_user_data, parent_egg_group->get_user_data(), nullptr);
}
}
if (node_desc->has_dag_path()) {
// Check for an object type setting, from Oliver's plug-in.
MObject dag_object = node_desc->get_dag_path().node();
string object_type;
LVector3d value;
for (unsigned int i = 1; ; i++) {
std::ostringstream attr;
attr << "eggObjectTypes" << i;
if (!get_enum_attribute(dag_object, attr.str(), object_type)) {
if (i < 3) {
// Support out-of-order legacy object types.
continue;
}
// We have run out of object types to add.
break;
}
egg_group->add_object_type(object_type);
}
if(has_attribute(dag_object, "scrollUV")) {
if(get_vec3d_attribute(dag_object, "scrollUV", value)) {
egg_group->set_scroll_u(value[0]);
egg_group->set_scroll_v(value[1]);
egg_group->set_scroll_r(value[2]);
}
}
pvector<string> tag_attribute_names;
get_tag_attribute_names(dag_object, tag_attribute_names);
for (unsigned int ti=0; ti < tag_attribute_names.size(); ti++) {
if (get_enum_attribute(dag_object, tag_attribute_names[ti], object_type)) {
egg_group->set_tag(tag_attribute_names[ti].substr(3), object_type);
}
}
// Is the node flagged to be invisible? If it is, it is tagged with the
// "hidden" visibility flag, so it won't get converted in the normal
// case (unless it represents a collision solid or something).
bool visible = true;
get_bool_attribute(dag_object, "visibility", visible);
if (!visible && egg_group->get_num_object_types() == 0) {
egg_group->set_visibility_mode(EggGroup::VM_hidden);
}
// We treat the object type "billboard" as a special case: we apply this
// one right away and also flag the group as an instance.
if (egg_group->has_object_type("billboard")) {
egg_group->remove_object_type("billboard");
egg_group->set_group_type(EggGroup::GT_instance);
egg_group->set_billboard_type(EggGroup::BT_axis);
} else if (egg_group->has_object_type("billboard-point")) {
egg_group->remove_object_type("billboard-point");
egg_group->set_group_type(EggGroup::GT_instance);
egg_group->set_billboard_type(EggGroup::BT_point_camera_relative);
} else if (egg_group->has_object_type("bbpoint")) {
egg_group->remove_object_type("bbpoint");
egg_group->set_group_type(EggGroup::GT_instance);
egg_group->set_billboard_type(EggGroup::BT_point_camera_relative);
}
// We also treat the object type "dcs" and "model" as a special case, so
// we can test for these flags later.
if (egg_group->has_object_type("dcs")) {
egg_group->remove_object_type("dcs");
egg_group->set_dcs_type(EggGroup::DC_default);
}
if (egg_group->has_object_type("model")) {
egg_group->remove_object_type("model");
egg_group->set_model_flag(true);
}
// And "vertex-color" and "double-sided" have meaning only to this
// converter.
MayaEggGroupUserData *user_data;
if (parent_user_data == nullptr) {
user_data = new MayaEggGroupUserData;
} else {
// Inherit the flags from above.
user_data = new MayaEggGroupUserData(*parent_user_data);
}
if (egg_group->has_object_type("vertex-color")) {
egg_group->remove_object_type("vertex-color");
user_data->_vertex_color = true;
}
if (egg_group->has_object_type("double-sided")) {
egg_group->remove_object_type("double-sided");
user_data->_double_sided = true;
}
egg_group->set_user_data(user_data);
}
if (node_desc->_is_lod) {
// Create an LOD specification.
egg_group->set_lod(EggSwitchConditionDistance(node_desc->_switch_in,
node_desc->_switch_out,
LPoint3d::zero()));
}
node_desc->_egg_group = egg_group;
}
return node_desc->_egg_group;
}
/**
* Returns the EggTable corresponding to the joint for the indicated node.
* Creates the table node if it has not already been created.
*/
EggTable *MayaNodeTree::
get_egg_table(MayaNodeDesc *node_desc) {
nassertr(_skeleton_node != nullptr, nullptr);
nassertr(node_desc->is_joint(), nullptr);
if (node_desc->_egg_table == nullptr) {
// We need to make a new table node.
nassertr(node_desc->_parent != nullptr, nullptr);
EggTable *egg_table = new EggTable(node_desc->get_name());
node_desc->_anim = new EggXfmSAnim("xform", _egg_data->get_coordinate_system());
node_desc->_anim->set_fps(_fps);
egg_table->add_child(node_desc->_anim);
if (!node_desc->_parent->is_joint()) {
// The parent is not a joint; put it at the top.
_skeleton_node->add_child(egg_table);
} else {
// The parent is another joint.
EggTable *parent_egg_table = get_egg_table(node_desc->_parent);
parent_egg_table->add_child(egg_table);
}
node_desc->_egg_table = egg_table;
}
return node_desc->_egg_table;
}
/**
* Returns the anim table corresponding to the joint for the indicated node.
* Creates the table node if it has not already been created.
*/
EggXfmSAnim *MayaNodeTree::
get_egg_anim(MayaNodeDesc *node_desc) {
get_egg_table(node_desc);
return node_desc->_anim;
}
/**
* Returns the anim table corresponding to the slider for the indicated blend.
* Creates the table node if it has not already been created.
*/
EggSAnimData *MayaNodeTree::
get_egg_slider(MayaBlendDesc *blend_desc) {
nassertr(_morph_node != nullptr, nullptr);
if (blend_desc->_anim == nullptr) {
// We need to make a new anim table.
EggSAnimData *egg_anim = new EggSAnimData(blend_desc->get_name());
egg_anim->set_fps(_fps);
_morph_node->add_child(egg_anim);
blend_desc->_anim = egg_anim;
}
return blend_desc->_anim;
}
/**
* Returns true if the indicated name is on the list of sliders to ignore,
* false otherwise.
*/
bool MayaNodeTree::
ignore_slider(const string &name) const {
return _converter->ignore_slider(name);
}
/**
* Outputs a message to the user reporting that a slider was ignored. Each
* slider is only reported once.
*/
void MayaNodeTree::
report_ignored_slider(const string &name) {
if (_ignored_slider_names.insert(name).second) {
mayaegg_cat.info()
<< "Ignoring slider " << name << "\n";
}
}
/**
* Adds the indicated MayaBlendDesc object to the list of blends collected so
* far. If a MayaBlendDesc object with the same name is already part of the
* tree, the supplied object is discarded and the previously-added object is
* returned; otherwise, the supplied object is added to the tree and the same
* object is returned.
*
* In either case, the return value is the MayaBlendDesc that should be used
* henceforth.
*/
MayaBlendDesc *MayaNodeTree::
add_blend_desc(MayaBlendDesc *blend_desc) {
BlendDescs::iterator bi = _blend_descs.insert(blend_desc).first;
return (*bi);
}
/**
* Returns the number of unique MayaBlendDesc objects (and hence the number of
* morph sliders) discovered in the tree.
*/
int MayaNodeTree::
get_num_blend_descs() const {
return _blend_descs.size();
}
/**
* Returns the nth MayaBlendDesc object discovered in the tree.
*/
MayaBlendDesc *MayaNodeTree::
get_blend_desc(int n) const {
nassertr(n >= 0 && n < (int)_blend_descs.size(), nullptr);
return _blend_descs[n];
}
/**
* Resets all of the sliders associated with all blend shapes down to 0.
*/
void MayaNodeTree::
reset_sliders() {
BlendDescs::iterator bi;
for (bi = _blend_descs.begin(); bi != _blend_descs.end(); ++bi) {
(*bi)->set_slider(0.0);
}
}
/**
* The recursive implementation of build_node().
*/
MayaNodeDesc *MayaNodeTree::
r_build_node(const string &path) {
// If we have already encountered this pathname, return the corresponding
// MayaNodeDesc immediately.
NodesByPath::const_iterator ni = _nodes_by_path.find(path);
if (ni != _nodes_by_path.end()) {
return (*ni).second;
}
// Otherwise, we have to create it. Do this recursively, so we create each
// node along the path.
MayaNodeDesc *node_desc = nullptr;
// mayaegg_cat.info() << "path: " << path << endl;
if (path.empty()) {
// This is the top. mayaegg_cat.info() << "found empty path: " << path <<
// endl;
node_desc = _root;
} else {
// Maya uses vertical bars to separate path components. Remove everything
// from the rightmost bar on; this will give us the parent's path name.
size_t bar = path.rfind("|");
string parent_path, local_name;
if (bar != string::npos) {
parent_path = path.substr(0, bar);
// mayaegg_cat.info() << "parent_path: " << parent_path << endl;
local_name = path.substr(bar + 1);
if (local_name == _subroot_parent_name) {
node_desc = _root;
}
} else {
local_name = path;
}
// mayaegg_cat.info() << "local_name: " << local_name << endl;
if (node_desc != _root) {
MayaNodeDesc *parent_node_desc = r_build_node(parent_path);
if (parent_node_desc == nullptr)
mayaegg_cat.info() << "empty parent: " << local_name << std::endl;
node_desc = new MayaNodeDesc(this, parent_node_desc, local_name);
_nodes.push_back(node_desc);
}
}
_nodes_by_path.insert(NodesByPath::value_type(path, node_desc));
return node_desc;
}

View File

@ -1,100 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file mayaNodeTree.h
* @author drose
* @date 2003-06-06
*/
#ifndef MAYANODETREE_H
#define MAYANODETREE_H
#include "pandatoolbase.h"
#include "mayaNodeDesc.h"
#include "mayaBlendDesc.h"
#include "globPattern.h"
#include "indirectCompareNames.h"
#include "ordered_vector.h"
#include "pset.h"
#include "pmap.h"
class MayaToEggConverter;
class EggData;
class EggGroupNode;
class EggTable;
class EggXfmSAnim;
class EggSAnimData;
/**
* Describes a complete tree of maya nodes for conversion.
*/
class MayaNodeTree {
public:
MayaNodeTree(MayaToEggConverter *converter);
MayaNodeDesc *build_node(const MDagPath &dag_path);
bool build_hierarchy();
void tag_joint_all();
// bool tag_joint_selected();
bool tag_joint_named(const GlobPattern &glob);
void tag_all();
bool tag_selected();
bool tag_named(const GlobPattern &glob);
bool untag_named(const GlobPattern &glob);
int get_num_nodes() const;
MayaNodeDesc *get_node(int n) const;
void clear();
void clear_egg(EggData *egg_data, EggGroupNode *egg_root,
EggGroupNode *skeleton_node, EggGroupNode *morph_node);
EggGroup *get_egg_group(MayaNodeDesc *node_desc);
EggTable *get_egg_table(MayaNodeDesc *node_desc);
EggXfmSAnim *get_egg_anim(MayaNodeDesc *node_desc);
EggSAnimData *get_egg_slider(MayaBlendDesc *blend_desc);
bool ignore_slider(const std::string &name) const;
void report_ignored_slider(const std::string &name);
MayaBlendDesc *add_blend_desc(MayaBlendDesc *blend_desc);
int get_num_blend_descs() const;
MayaBlendDesc *get_blend_desc(int n) const;
void reset_sliders();
public:
std::string _subroot_parent_name;
PT(MayaNodeDesc) _root;
PN_stdfloat _fps;
private:
MayaNodeDesc *r_build_node(const std::string &path);
MayaToEggConverter *_converter;
EggData *_egg_data;
EggGroupNode *_egg_root;
EggGroupNode *_skeleton_node;
EggGroupNode *_morph_node;
typedef pmap<std::string, MayaNodeDesc *> NodesByPath;
NodesByPath _nodes_by_path;
typedef pvector<MayaNodeDesc *> Nodes;
Nodes _nodes;
typedef ov_set<PT(MayaBlendDesc), IndirectCompareNames<MayaBlendDesc> > BlendDescs;
BlendDescs _blend_descs;
typedef pset<std::string> Strings;
Strings _ignored_slider_names;
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,203 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file mayaToEggConverter.h
* @author drose
* @date 1999-11-10
*/
#ifndef MAYATOEGGCONVERTER_H
#define MAYATOEGGCONVERTER_H
#include "pandatoolbase.h"
#include "somethingToEggConverter.h"
#include "mayaNodeTree.h"
#include "mayaApi.h"
#include "mayaShaders.h"
#include "mayaShaderColorDef.h"
#include "eggTextureCollection.h"
#include "distanceUnit.h"
#include "coordinateSystem.h"
#include "globPattern.h"
#include "pvector.h"
#include "vector_string.h"
#include "pre_maya_include.h"
#include <maya/MDagPath.h>
#include <maya/MItMeshPolygon.h>
#include "post_maya_include.h"
class EggData;
class EggGroup;
class EggTable;
class EggVertexPool;
class EggNurbsCurve;
class EggPrimitive;
class EggXfmSAnim;
class MayaShaderColorDef;
/**
* This class supervises the construction of an EggData structure from a
* single Maya file, or from the data already in the global Maya model space.
*
* Note that since the Maya API presents just one global model space, it is
* not possible to simultaneously load two distinct Maya files.
*/
class MayaToEggConverter : public SomethingToEggConverter {
public:
MayaToEggConverter(const std::string &program_name = "");
MayaToEggConverter(const MayaToEggConverter &copy);
virtual ~MayaToEggConverter();
virtual SomethingToEggConverter *make_copy();
virtual std::string get_name() const;
virtual std::string get_extension() const;
virtual std::string get_additional_extensions() const;
virtual bool convert_file(const Filename &filename);
virtual DistanceUnit get_input_units();
void clear_subroots();
void add_subroot(const GlobPattern &glob);
void clear_subsets();
void add_subset(const GlobPattern &glob);
void clear_excludes();
void add_exclude(const GlobPattern &glob);
void clear_ignore_sliders();
void add_ignore_slider(const GlobPattern &glob);
bool ignore_slider(const std::string &name) const;
void clear_force_joints();
void add_force_joint(const GlobPattern &glob);
bool force_joint(const std::string &name) const;
void set_from_selection(bool from_selection);
bool convert_maya();
void clear();
bool open_api(bool revert_directory=true);
void close_api();
private:
bool convert_flip(double start_frame, double end_frame,
double frame_inc, double output_frame_rate);
bool convert_char_model();
bool convert_char_chan(double start_frame, double end_frame,
double frame_inc, double output_frame_rate);
bool convert_hierarchy(EggGroupNode *egg_root);
bool process_model_node(MayaNodeDesc *node_desc);
void get_transform(MayaNodeDesc *node_desc, const MDagPath &dag_path,
EggGroup *egg_group);
void get_joint_transform(const MDagPath &dag_path, EggGroup *egg_group);
void apply_lod_attributes(EggGroup *egg_group, MFnDagNode &lod_group);
// I ran into core dumps trying to pass around a MFnMesh object by value.
// From now on, all MFn* objects will be passed around by reference. void
// make_tex_names(const MFnMesh &mesh, const MObject &mesh_object);
void make_nurbs_surface(MayaNodeDesc *node_desc,
const MDagPath &dag_path,
MFnNurbsSurface &surface,
EggGroup *group);
EggNurbsCurve *make_trim_curve(const MFnNurbsCurve &curve,
const std::string &nurbs_name,
EggGroupNode *egg_group,
int trim_curve_index);
void make_nurbs_curve(const MDagPath &dag_path,
const MFnNurbsCurve &curve,
EggGroup *group);
void make_polyset(MayaNodeDesc *node_desc, const MDagPath &dag_path,
const MFnMesh &mesh, EggGroup *egg_group,
MayaShader *default_shader = nullptr);
void make_locator(const MDagPath &dag_path, const MFnDagNode &dag_node,
EggGroup *egg_group);
void make_camera_locator(const MDagPath &dag_path, const MFnDagNode &dag_node,
EggGroup *egg_group);
void make_light_locator(const MDagPath &dag_path, const MFnDagNode &dag_node,
EggGroup *egg_group);
bool get_vertex_weights(const MDagPath &dag_path, const MFnMesh &mesh,
pvector<EggGroup *> &joints, MFloatArray &weights);
bool get_vertex_weights(const MDagPath &dag_path, const MFnNurbsSurface &surface,
pvector<EggGroup *> &joints, MFloatArray &weights);
void apply_texture_uvprops(EggTexture &tex,
const MayaShaderColorDef &color_def);
void apply_texture_blendtype(EggTexture &tex,
const MayaShaderColorDef &color_def);
void apply_texture_filename(EggTexture &tex,
const MayaShaderColorDef &color_def);
void apply_texture_alpha_filename(EggTexture &tex,
const MayaShaderColorDef &color_def);
bool compare_texture_uvprops(EggTexture &tex,
const MayaShaderColorDef &color_def);
bool reparent_decals(EggGroupNode *egg_parent);
void set_shader_attributes(EggPrimitive &primitive, const MayaShader &shader,
bool mesh = false);
void set_shader_modern(EggPrimitive &primitive, const MayaShader &shader,
bool mesh);
void set_shader_legacy(EggPrimitive &primitive, const MayaShader &shader,
bool mesh);
void set_vertex_color(EggVertex &vert, MItMeshPolygon &pi, int vert_index, const MayaShader *shader, const LColor &color);
void set_vertex_color_legacy(EggVertex &vert, MItMeshPolygon &pi, int vert_index, const MayaShader *shader, const LColor &color);
void set_vertex_color_modern(EggVertex &vert, MItMeshPolygon &pi, int vert_index, const MayaShader *shader, const LColor &color);
int round(double value);
std::string _program_name;
bool _from_selection;
std::string _subroot;
typedef pvector<GlobPattern> Globs;
Globs _subsets;
Globs _subroots;
Globs _excludes;
Globs _ignore_sliders;
Globs _force_joints;
MayaNodeTree _tree;
public:
MayaShaders _shaders;
EggTextureCollection _textures;
PT(MayaApi) _maya;
bool _polygon_output;
double _polygon_tolerance;
bool _respect_maya_double_sided;
bool _always_show_vertex_color;
bool _keep_all_uvsets;
bool _convert_cameras;
bool _convert_lights;
bool _round_uvs;
bool _legacy_shader;
enum TransformType {
TT_invalid,
TT_all,
TT_model,
TT_dcs,
TT_none,
};
TransformType _transform_type;
static TransformType string_transform_type(const std::string &arg);
};
#endif

View File

@ -1,6 +0,0 @@
#include "config_mayaegg.cxx"
#include "mayaEggGroupUserData.cxx"
#include "mayaBlendDesc.cxx"
#include "mayaNodeDesc.cxx"
#include "mayaNodeTree.cxx"
#include "mayaToEggConverter.cxx"

View File

@ -1,240 +0,0 @@
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <string>
#ifndef _BOOL
#define _BOOL 1
#endif
#define REQUIRE_IOSTREAM
#include <maya/MGlobal.h>
#include <maya/MFileIO.h>
#include <maya/MLibrary.h>
#include <maya/MStatus.h>
#include <maya/MItDag.h>
#include <maya/MDagPath.h>
#include <maya/MFnDagNode.h>
#include <maya/MFnBlendShapeDeformer.h>
#include <maya/MFnMesh.h>
#include <maya/MPointArray.h>
using std::cerr;
void
scan_nodes() {
MStatus status;
MItDag dag_iterator(MItDag::kDepthFirst, MFn::kTransform, &status);
if (!status) {
status.perror("MItDag constructor");
exit(1);
}
while (!dag_iterator.isDone()) {
MDagPath dag_path;
status = dag_iterator.getPath(dag_path);
if (!status) {
status.perror("MItDag::getPath");
exit(1);
}
MFnDagNode dag_node(dag_path, &status);
if (!status) {
status.perror("MFnDagNode constructor");
exit(1);
}
cerr << dag_node.name() << "\n";
dag_iterator.next();
}
}
MFnBlendShapeDeformer *
get_slider(MString slider_name) {
MStatus status;
status = MGlobal::selectByName(slider_name, MGlobal::kReplaceList);
if (!status) {
status.perror(slider_name);
exit(1);
}
MSelectionList list;
status = MGlobal::getActiveSelectionList(list);
if (!status) {
status.perror("MGLobal::getActiveSelectionList");
exit(1);
}
unsigned int num_objects = list.length();
if (num_objects != 1) {
cerr << "Warning: multiple objects match " << slider_name << "\n";
}
for (unsigned int i = 0; i < num_objects; i++) {
MObject obj;
status = list.getDependNode(i, obj);
if (!status) {
cerr << "selected element is not a dependency node.\n";
status.perror("getDependNode");
} else {
if (obj.hasFn(MFn::kBlendShape)) {
MFnBlendShapeDeformer *slider = new MFnBlendShapeDeformer(obj, &status);
if (!status) {
status.perror("MFnBlendShapeDeformer constructor");
} else {
cerr << "got slider " << slider->name() << "\n";
return slider;
}
}
cerr << "selected element is not a blend shape\n";
}
}
cerr << "Couldn't find slider " << slider_name << "\n";
exit(1);
}
MFnMesh *
get_mesh(MString mesh_name) {
MStatus status;
status = MGlobal::selectByName(mesh_name, MGlobal::kReplaceList);
if (!status) {
status.perror(mesh_name);
exit(1);
}
MSelectionList list;
status = MGlobal::getActiveSelectionList(list);
if (!status) {
status.perror("MGLobal::getActiveSelectionList");
exit(1);
}
unsigned int num_objects = list.length();
if (num_objects != 1) {
cerr << "Warning: multiple objects match " << mesh_name << "\n";
}
for (unsigned int i = 0; i < num_objects; i++) {
MObject obj;
status = list.getDependNode(i, obj);
if (!status) {
cerr << "selected element is not a dependency node.\n";
status.perror("getDependNode");
} else {
if (obj.hasFn(MFn::kMesh)) {
// Maybe it's a mesh object itself.
MFnMesh *mesh = new MFnMesh(obj, &status);
if (!status) {
status.perror("MFnMesh constructor");
} else {
cerr << "got mesh " << mesh->name() << "\n";
return mesh;
}
} else if (obj.hasFn(MFn::kDagNode)) {
// Maybe it's a dag node.
MDagPath path;
status = MDagPath::getAPathTo(obj, path);
if (!status) {
status.perror("MDagPath::getAPathTo");
exit(1);
}
if (path.hasFn(MFn::kMesh)) {
MFnMesh *mesh = new MFnMesh(path, &status);
if (!status) {
status.perror("MFnMesh constructor");
} else {
cerr << "got mesh " << mesh->name() << "\n";
return mesh;
}
}
}
cerr << "selected element is not a mesh\n";
}
}
cerr << "Couldn't find mesh " << mesh_name << "\n";
exit(1);
}
void
output_vertices(const char *filename, MFnMesh &mesh) {
MStatus status;
MPointArray verts;
// status = mesh.getPoints(verts, MSpace::kObject);
status = mesh.getPoints(verts, MSpace::kWorld);
if (!status) {
status.perror("mesh.getPoints");
exit(1);
}
std::ofstream file(filename, std::ios::out | std::ios::trunc);
if (!file) {
cerr << "Couldn't open " << filename << " for output.\n";
exit(1);
}
unsigned int num_verts = verts.length();
cerr << "writing " << num_verts << " vertices to " << filename << "\n";
for (unsigned int i = 0; i < num_verts; i++) {
file << i << ". " << verts[i] << "\n";
}
}
int
main(int argc, char *argv[]) {
cerr << "Initializing Maya\n";
MStatus status;
status = MLibrary::initialize(argv[0]);
if (!status) {
status.perror("Could not initialize");
exit(1);
}
cerr << "Using Maya library version " << MGlobal::mayaVersion() << "\n";
if (argc < 4) {
cerr << "\nUsage:\n\nblend_test.cxx file.mb slider_name mesh_name\n\n";
exit(1);
}
MString filename = argv[1];
MString slider_name = argv[2];
MString mesh_name = argv[3];
MFileIO::newFile(true);
cerr << "Reading " << filename << "\n";
status = MFileIO::open(filename);
if (!status) {
status.perror(filename);
exit(1);
}
MFnBlendShapeDeformer *slider = get_slider(slider_name);
MFnMesh *mesh = get_mesh(mesh_name);
cerr << "\nOriginal slider value is " << slider->weight(0) << "\n";
output_vertices("before.txt", *mesh);
cerr << "Setting slider to 1\n";
status = slider->setWeight(0, 1.0);
if (!status) {
status.perror("MFnBlendShapeDeformer::setWeight");
exit(1);
}
output_vertices("after.txt", *mesh);
return 0;
}

View File

@ -1,55 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file config_mayaloader.cxx
* @author drose
* @date 2003-10-09
*/
#ifdef __MACH__
#define __OPENTRANSPORTPROVIDERS__
#endif
#include "pandatoolbase.h"
#include "loaderFileTypePandatool.h"
#include "config_mayaegg.h"
#include "mayaToEggConverter.h"
#include "dconfig.h"
#include "loaderFileTypeRegistry.h"
Configure(config_mayaloader);
void EXPCL_MISC init_libmayaloader();
ConfigureFn(config_mayaloader) {
init_libmayaloader();
}
/**
* Initializes the library. This must be called at least once before any of
* the functions or classes in this library can be used. Normally it will be
* called by the static initializers and need not be called explicitly, but
* special cases exist.
*/
void
init_libmayaloader() {
static bool initialized = false;
if (initialized) {
return;
}
initialized = true;
LoaderFileTypePandatool::init_type();
LoaderFileTypeRegistry *reg = LoaderFileTypeRegistry::get_global_ptr();
init_libmayaegg();
MayaToEggConverter *maya = new MayaToEggConverter;
reg->register_type(new LoaderFileTypePandatool(maya));
}

View File

@ -1,110 +0,0 @@
global proc int eggImportOptions ( string $parent,
string $action,
string $initialSettings,
string $resultCallback )
//
// Description:
// This script posts the OBJ file translator options.
// The optionsString is of the form:
// varName1=value1;varName2=value2;...
//
// Parameters:
// $parent - the elf parent layout for this options layout. It is
// always a scrollLayout.
// $action - the action that is to be performed with this invokation
// of this proc. Valid options are:
// "query" - construct the options string and pass it
// to the resultCallback.
// "post" - post all the elf controls.
// $initialSettings - the current options string in effect at the
// time this script is invoked.
// $resultCallback -
// This is the proc to be called with the result string.
// resultCallback ( string $optionsString )
//
// Returns:
// 1 if successfull.
// 0 otherwise.
//
{
int $bResult;
string $currentOptions;
string $optionList[];
string $optionBreakDown[];
int $index;
if ($action == "post") {
setParent $parent;
columnLayout -adj true objTypeCol;
radioButtonGrp
-l "Merge with Current Scene"
-nrb 2 -cw3 175 75 75
-la2 "On" "Off" objMerge;
radioButtonGrp
-l "Import Model"
-nrb 2 -cw3 175 75 75
-la2 "On" "Off" objModel;
radioButtonGrp
-l "Import Animation"
-nrb 2 -cw3 175 75 75
-la2 "On" "Off" objAnim;
$currentOptions = $initialSettings;
if (size($currentOptions) > 0) {
tokenize($currentOptions, ";", $optionList);
for ($index = 0; $index < size($optionList); $index++) {
tokenize($optionList[$index], "=", $optionBreakDown);
if ($optionBreakDown[0] == "merge") {
if ($optionBreakDown[1] == "0") {
radioButtonGrp -e -sl 2 objMerge;
} else {
radioButtonGrp -e -sl 1 objMerge;
}
} else if ($optionBreakDown[0] == "model") {
if ($optionBreakDown[1] == "0") {
radioButtonGrp -e -sl 2 objModel;
} else {
radioButtonGrp -e -sl 1 objModel;
}
} else if ($optionBreakDown[0] == "anim") {
if ($optionBreakDown[1] == "0") {
radioButtonGrp -e -sl 2 objAnim;
} else {
radioButtonGrp -e -sl 1 objAnim;
}
}
}
}
$result = 1;
} else if ($action == "query") {
if (`radioButtonGrp -q -sl objMerge` == 1) {
$currentOptions = $currentOptions + "merge=1";
} else {
$currentOptions = $currentOptions + "merge=0";
}
if (`radioButtonGrp -q -sl objModel` == 1) {
$currentOptions = $currentOptions + ";model=1";
} else {
$currentOptions = $currentOptions + ";model=0";
}
if (`radioButtonGrp -q -sl objAnim` == 1) {
$currentOptions = $currentOptions + ";anim=1";
} else {
$currentOptions = $currentOptions + ";anim=0";
}
eval($resultCallback+" \""+$currentOptions+"\"");
$result = 1;
} else {
$bResult = 0;
}
return $bResult;
}

View File

@ -1,169 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file eggToMaya.cxx
* @author drose
* @date 2005-08-11
*/
#include "eggToMaya.h"
#include "mayaEggLoader.h"
#include "mayaApi.h"
#include "mayaConversionServer.h"
// We must define this to prevent Maya from doubly-declaring its MApiVersion
// string in this file as well as in libmayaegg.
#define _MApiVersion
#include "pre_maya_include.h"
#include <maya/MString.h>
#include <maya/MFileIO.h>
#include "post_maya_include.h"
/**
*
*/
EggToMaya::
EggToMaya() :
EggToSomething("Maya", ".mb", true, false)
{
add_units_options();
set_binary_output(true);
set_program_brief("convert .egg files to Maya .mb or .ma files");
set_program_description
("egg2maya converts files from egg format to Maya .mb or .ma "
"format. It contains support for basic geometry (polygons with textures)."
"It also supports animation for joints.");
add_option
("a", "", 0,
"Convert animation tables.",
&EggToMaya::dispatch_none, &_convert_anim);
add_option
("m", "", 0,
"Convert polygon models. You may specify both -a and -m at the same "
"time. If you specify neither, the default is -m.",
&EggToMaya::dispatch_none, &_convert_model);
add_option
("nv", "", 0,
"respect vertex and polygon normals.",
&EggToMaya::dispatch_none, &_respect_normals);
add_option("server", "", 0,
"Runs the Maya model conversion server. This server can be used in tandem "
"with the egg2maya_client and maya2egg_client utilities to batch convert "
"both Maya and Panda3D model files.",
&EggToMaya::dispatch_none, &_run_server);
// Maya files always store centimeters.
_output_units = DU_centimeters;
}
/**
* Attempts to create the global Maya API.
* Exits the program if unsuccessful.
*/
PT(MayaApi) EggToMaya::
open_api() {
if (!MayaApi::is_api_valid()) {
nout << "Initializing Maya...\n";
}
PT(MayaApi) api = MayaApi::open_api(_program_name, true, true);
if (!api || !api->is_valid()) {
nout << "Unable to initialize Maya.\n";
exit(1);
}
return api;
}
/**
* Returns true if the model has been successfully converted.
*/
bool EggToMaya::
run() {
if (!_convert_anim && !_convert_model) {
_convert_model = true;
}
// Let's convert the output file to a full path before we initialize Maya,
// since Maya now has a nasty habit of changing the current directory.
_output_filename.make_absolute();
PT(MayaApi) maya = open_api();
MStatus status;
status = MFileIO::newFile(true);
if (!status) {
status.perror("Could not initialize file");
return false;
}
// [gjeon] since maya's internal unit is fixed to cm and when we can't
// change UI unit without affecting data all distance data is converted to
// cm we need to convert them back to proper output unit user provided here
// along with UI unit
maya->set_units(_output_units);
if (_output_units != DU_centimeters && _output_units != DU_invalid) {
nout << "Converting from centimeters"
<< " to " << format_long_unit(_output_units) << "\n";
}
// Now convert the data.
if (!MayaLoadEggData(_data, true, _convert_model, _convert_anim, _respect_normals)) {
nout << "Unable to convert egg file.\n";
return false;
}
if (!maya->write(_output_filename)) {
status.perror("Could not save file");
return false;
}
/*
// And write out the resulting Maya file.
string os_specific = _output_filename.to_os_generic();
const char *file_type = NULL;
if (_output_filename.get_extension() == "mb") {
file_type = "mayaBinary";
}
status = MFileIO::saveAs(os_specific.c_str(), file_type);
if (!status) {
status.perror("Could not save file");
return false;
}
*/
return true;
}
/**
* Processes the arguments parsed by the program.
*
* If the server flag is specified, the Maya conversion server is started
* up rather than the usual conversion utility functionality.
*/
bool EggToMaya::
handle_args(ProgramBase::Args &args) {
if (_run_server) {
open_api();
MayaConversionServer server;
server.listen();
exit(0);
return true;
}
return EggToSomething::handle_args(args);
}

View File

@ -1,44 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file eggToMaya.h
* @author drose
* @date 2005-08-11
*/
#ifndef EGGTOMAYA_H
#define EGGTOMAYA_H
#include "pandatoolbase.h"
#include "eggToSomething.h"
#include "mayaApi.h"
#include "programBase.h"
/**
* A program to read an egg file and write a maya file.
*/
class EggToMaya : public EggToSomething {
public:
EggToMaya();
bool run();
private:
virtual bool handle_args(ProgramBase::Args &args);
PT(MayaApi) open_api();
bool _convert_anim;
bool _convert_model;
bool _respect_normals;
bool _run_server;
};
#endif

View File

@ -1,28 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file eggToMayaBin.cxx
* @author Derzsi Dániel
* @date 2020-10-01
*/
#include "eggToMaya.h"
/**
* Entrypoint for egg2maya.
*/
int main(int argc, char *argv[]) {
EggToMaya prog;
prog.parse_command_line(argc, argv);
if (!prog.run()) {
return 1;
}
return 0;
}

View File

@ -1,22 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file eggToMayaClient.cxx
* @author Derzsi Dániel
* @date 2020-10-01
*/
#include "mayaConversionClient.h"
/**
* Entrypoint for egg2maya_client.
*/
int main(int argc, char *argv[]) {
MayaConversionClient client;
return client.main(argc, argv, MayaConversionServer::ConversionType::CT_egg_to_maya);
}

View File

@ -1,189 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file mayaConversionClient.cxx
* @author Derzsi Dániel
* @date 2020-10-01
*/
#include "mayaConversionClient.h"
#include "mayaConversionServer.h"
#include "datagramIterator.h"
/**
* Initializes the Maya conversion client.
*/
MayaConversionClient::
MayaConversionClient() : _reader(&_manager, 0), _writer(&_manager, 0)
{
}
/**
* Cleans up the Maya conversison client's pending connections.
*/
MayaConversionClient::
~MayaConversionClient() {
close();
}
/**
* Attempts to connect to a Maya conversion server.
* If a connection is already active, it will be removed.
*
* Returns true if the connection was created successfully.
*/
bool MayaConversionClient::
connect(NetAddress server) {
if (_conn) {
// Remove this connection from the readers list
_reader.remove_connection(_conn);
_conn = nullptr;
}
// Attempt to open a connection
_conn = _manager.open_TCP_client_connection(server, 0);
if (!_conn || _conn.is_null()) {
// This connection could not be opened
return false;
}
// Add this connection to the readers list
_reader.add_connection(_conn);
return true;
}
/**
* Sends a conversion workload to the Maya conversion server.
* It will be processed as soon as the server's queue is empty.
*
* Specify the working directory in where the models are located,
* the command line arguments, and the conversion type.
*
* Returns true if the workload has been successfully sent.
*/
bool MayaConversionClient::
queue(Filename working_directory, int argc, char *argv[], MayaConversionServer::ConversionType conversion_type) {
if (!_conn) {
return false;
}
std::string s_cwd = (std::string) working_directory.to_os_specific();
NetDatagram datagram;
// First part of the datagram is the argc
datagram.add_uint8(argc);
// Add the rest of the arguments as strings to the datagram
for (int i = 0; i < argc; i++) {
datagram.add_string(argv[i]);
}
// Add the current working dir as a string to the datagram
datagram.add_string(s_cwd);
// Lastly, add the conversion type
datagram.add_uint8(conversion_type);
// Send the conversion request
if (!_writer.send(datagram, _conn) || !_conn->flush()) {
nout << "Failed to send workload to server process.\n";
return false;
}
// Wait for a response
while (_conn->get_socket()->Active() && !_reader.data_available()) {
_reader.poll();
}
if (!_reader.data_available()) {
// No response has been given by the server.
nout << "No response has been given by the conversion server.\n";
return false;
}
NetDatagram response;
// Let's read the response now!
if (!_reader.get_data(response)) {
nout << "The conversion response could not be read.\n";
return false;
}
// Iterate through the response.
DatagramIterator response_data(response);
// Read the first and only argument.
// Did our conversion request succeed?
bool converted = response_data.get_bool();
if (!converted) {
nout << "The server reported that the conversion has failed.\n"
<< "Please check the server logs for further information.\n";
return false;
}
return true;
}
/**
* Closes the current connection to the Maya conversion server,
* waiting for all currently queued requests to finish.
*
* Does nothing if the connection has not been made yet.
*/
void MayaConversionClient::
close() {
if (!_conn) {
return;
}
while (true) {
_reader.data_available();
if (_manager.reset_connection_available()) {
PT(Connection) connection;
if (_manager.get_reset_connection(connection)) {
_manager.close_connection(_conn);
_conn = nullptr;
return;
}
}
Thread::sleep(0.1);
}
}
/**
* The entrypoint to this Maya conversion client.
*
* Connects to the default server at port 4242, queues
* one conversion request and waits for its completion.
*/
int MayaConversionClient::
main(int argc, char *argv[], MayaConversionServer::ConversionType conversion_type) {
NetAddress server;
// We assume the server is local and on port 4242
server.set_host("localhost", 4242);
if (!connect(server)) {
nout << "Failed to open port to server process.\n"
<< "Make sure maya2egg -server or egg2maya -server is running on localhost!\n";
return 1;
}
if (!queue(ExecutionEnvironment::get_cwd(), argc, argv, conversion_type)) {
return 1;
}
nout << "Conversion successful!\n";
close();
return 0;
}

View File

@ -1,53 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file mayaConversionClient.h
* @author Derzsi Dániel
* @date 2020-10-01
*/
#ifndef MAYACONVERSIONCLIENT_H
#define MAYACONVERSIONCLIENT_H
#include "queuedConnectionManager.h"
#include "queuedConnectionReader.h"
#include "connectionWriter.h"
#include "netAddress.h"
#include "filename.h"
#include "mayaConversionServer.h"
/**
* The Maya conversion client sends batch conversion
* requests to the Maya conversion server.
*
* These utilities rely on the Maya conversion server.
* Use egg2maya or maya2egg to boot up the Maya conversion server.
* Use egg2maya_client and maya2egg_client as a replacement for
*
* Very useful in case you need to batch convert models.
* The regular utilities can only convert one model at a time.
*/
class MayaConversionClient {
public:
MayaConversionClient();
~MayaConversionClient();
bool connect(NetAddress server);
bool queue(Filename working_directory, int argc, char *argv[], MayaConversionServer::ConversionType conversion_type);
void close();
int main(int argc, char *argv[], MayaConversionServer::ConversionType conversion_type);
private:
QueuedConnectionManager _manager;
QueuedConnectionReader _reader;
ConnectionWriter _writer;
PT(Connection) _conn;
};
#endif

View File

@ -1,220 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file mayaConversionServer.cxx
* @author cbrunner
* @author Derzsi Dániel
* @date 2020-10-01
*/
#ifdef _WIN32
#include <direct.h> // for chdir
#endif
#include "mayaConversionServer.h"
#include "mayaToEgg.h"
#include "eggToMaya.h"
#include "virtualFileSystem.h"
#include "filename.h"
/**
* Initializes the Maya conversion server.
*/
MayaConversionServer::
MayaConversionServer() : _listener(&_manager, 0), _reader(&_manager, 0),
_writer(&_manager, 0) {
}
/**
* Checks for any network activity and handles it, if appropriate, and then
* returns. This must be called periodically
*/
void MayaConversionServer::
poll() {
// Listen for new connections
_listener.poll();
// If we have a new connection from a client create a new connection pointer
// and add it to the reader list
if (_listener.new_connection_available()) {
PT(Connection) rendezvous;
PT(Connection) connection;
NetAddress address;
if (_listener.get_new_connection(rendezvous, address, connection)) {
_reader.add_connection(connection);
_clients.insert(connection);
}
}
// Check for reset clients
if (_manager.reset_connection_available()) {
PT(Connection) connection;
if (_manager.get_reset_connection(connection)) {
_clients.erase(connection);
_manager.close_connection(connection);
}
}
// Poll the readers (created above) and if they have data process it
_reader.poll();
if (_reader.data_available()) {
// Grab the incoming data and unpack it
NetDatagram datagram;
if (_reader.get_data(datagram)) {
DatagramIterator data(datagram);
// First data should be the "argc" (argument count) from the client
int argc = data.get_uint8();
// Now we have to get clever because the rest of the data comes as
// strings and parse_command_line() expects arguments of the standard
// argc, argv*[] variety. First, we need a string vector to hold all
// the strings from the datagram. We also need a char * array to keep
// track of all the pointers we're gonna malloc. Needed later for
// cleanup.
vector_string vargv;
std::vector<char *> buffers;
// Get the strings from the datagram and put them into the string vector
for (int i = 0; i < argc; i++) {
vargv.push_back(data.get_string().c_str());
}
// Last string is the current directory the client was run from. Not
// part of the argument list, but we still need it
std::string cwd = data.get_string();
// We allocate some memory to hold the pointers to the pointers we're
// going to pass in to parse_command_line().
char **cargv = (char**) malloc(sizeof(char**) * argc);
// Loop through the string arguments we got from the datagram and
// convert them to const char *'s. parse_command_line() expects char
// *'s, so we have to copy these const versions into fresh char *, since
// there is no casting from const char * to char *.
for (int i = 0; i < argc; i++) {
// string to const char *
const char *cptr = vargv[i].c_str();
// memory allocated for a new char * of size of the string
char *buffer = (char *) malloc(vargv[i].capacity() + 1);
// Copy the const char * to the char *
strcpy(buffer, cptr);
// put this into the arry we defined above. This is what will
// eventually be passed to parse_command_line()
cargv[i] = buffer;
// keep track of the pointers to the allocated memory for cleanup
// later
buffers.push_back(buffer);
}
// Change to the client's current dir
#ifdef _WIN64
_chdir(cwd.c_str());
#else
chdir(cwd.c_str());
#endif
// Change the VirtualFileSystem's current dir as well
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
vfs->chdir(Filename::from_os_specific(cwd));
// Next, we'll need to read the conversion type.
// Are we converting from egg to maya or from maya to egg?
int conversion_type = data.get_uint8();
bool converted = false;
switch (conversion_type) {
case ConversionType::CT_maya_to_egg:
{
MayaToEgg egg;
// Pass in the 'new' argc and argv we got from the client
if (egg.parse_command_line(argc, cargv, false) == ProgramBase::ExitCode::EC_not_exited) {
// Actually run the damn thing
converted = egg.run();
}
break;
}
case ConversionType::CT_egg_to_maya:
{
EggToMaya maya;
maya.set_exit_on_failure(false);
// Pass in the 'new' argc and argv we got from the client
if (maya.parse_command_line(argc, cargv, false) == ProgramBase::ExitCode::EC_not_exited) {
// Actually run the damn thing
converted = maya.run();
}
break;
}
}
// Let's send the result back to the client
NetDatagram response;
// The first and only part of the response is the success value
response.add_bool(converted);
// Send the response
if (!_writer.send(response, datagram.get_connection())) {
// Looks like we couldn't send the response
nout << "Could not send response to the client.\n";
}
std::cout.flush();
// Cleanup first, release the string vector
vargv.clear();
// No, iterate through the char * vector and cleanup the malloc'd
// pointers
std::vector<char *>::iterator vi;
for ( vi = buffers.begin() ; vi != buffers.end(); vi++) {
free(*vi);
}
// Clean up the malloc'd pointer pointer
free(cargv);
} // qReader.get_data
Clients::iterator ci;
for (ci = _clients.begin(); ci != _clients.end(); ++ci) {
_manager.close_connection(*ci);
}
} // qReader.data_available
} // poll
/**
* Blocks the current thread and listens to conversion requests.
*/
void MayaConversionServer::
listen() {
// Open a rendezvous port for receiving new connections from the client
PT(Connection) rend = _manager.open_TCP_server_rendezvous(4242, 100);
if (rend.is_null()) {
nout << "Port opening failed!\n";
return;
}
nout << "Server opened on port 4242, waiting for requests...\n";
// Add this connection to the listeners list
_listener.add_connection(rend);
// Main loop. Keep polling for connections, but don't eat up all the CPU.
while (true) {
this->poll();
Thread::force_yield();
}
}

View File

@ -1,57 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file mayaConversionServer.h
* @author Derzsi Dániel
* @date 2020-10-01
*/
#ifndef MAYACONVERSIONSERVER_H
#define MAYACONVERSIONSERVER_H
#include "queuedConnectionManager.h"
#include "queuedConnectionListener.h"
#include "queuedConnectionReader.h"
#include "connectionWriter.h"
/**
* The Maya conversion server listens for incoming requests to
* handle maya-to-egg and egg-to-maya model conversions.
*
* This server listens to port 4242 after being started with
* egg2maya -server or maya2egg -server.
*
* Use egg2maya_client and maya2egg_client as a replacement for
* the egg2maya and maya2egg utilities after starting the server.
*
* Very useful in case you need to batch convert models.
* The regular utilities can only convert one model at a time.
*/
class MayaConversionServer {
public:
enum ConversionType {
CT_maya_to_egg = 0,
CT_egg_to_maya = 1
};
MayaConversionServer();
void listen();
void poll();
protected:
typedef pset< PT(Connection) > Clients;
Clients _clients;
QueuedConnectionManager _manager;
QueuedConnectionListener _listener;
QueuedConnectionReader _reader;
ConnectionWriter _writer;
};
#endif

View File

@ -1,166 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file mayaEggImport.cxx
* @author jyelon
* @date 2005-07-20
*
* This is the wrapper code for the maya importer plugin.
* It includes:
*
* - user interface dialogs and popups
* - plugin initialization/registration
*
* It does not include the actual code to traverse the EggData.
*/
#include <string.h>
#include <sys/types.h>
#include "dtoolbase.h"
// We must define this to prevent Maya from doubly-declaring its MApiVersion
// string in this file as well as in libmayaegg.
#define _MApiVersion
#include "pre_maya_include.h"
#include <maya/MStatus.h>
#include <maya/MPxCommand.h>
#include <maya/MString.h>
#include <maya/MStringArray.h>
#include <maya/MArgList.h>
#include <maya/MGlobal.h>
#include <maya/MFnPlugin.h>
#include <maya/MObject.h>
#include <maya/MPlug.h>
#include <maya/MPxFileTranslator.h>
#include "post_maya_include.h"
#include "mayaEggLoader.h"
#include "notifyCategoryProxy.h"
class MayaEggImporter : public MPxFileTranslator
{
public:
MayaEggImporter () {};
virtual ~MayaEggImporter () {};
static void* creator();
MStatus reader ( const MFileObject& file,
const MString& optionsString,
FileAccessMode mode);
MStatus writer ( const MFileObject& file,
const MString& optionsString,
FileAccessMode mode );
bool haveReadMethod () const { return true; }
bool haveWriteMethod () const { return false; }
MString defaultExtension () const { return "egg"; }
MFileKind identifyFile ( const MFileObject& fileName,
const char* buffer,
short size) const;
};
void* MayaEggImporter::creator()
{
return new MayaEggImporter();
}
MStatus MayaEggImporter::reader ( const MFileObject& file,
const MString& options,
FileAccessMode mode)
{
MString fileName = file.fullName();
bool model=false;
bool anim=false;
if (options.length() > 0) {
const MString flagModel("model");
const MString flagAnim("anim");
// 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] == flagModel && theOption.length() > 1) {
model = atoi(theOption[1].asChar()) ? true:false;
} else if (theOption[0] == flagAnim && theOption.length() > 1) {
anim = atoi(theOption[1].asChar()) ? true:false;
}
}
}
if ((mode != kImportAccessMode)&&(mode != kOpenAccessMode))
return MS::kFailure;
bool merge = (mode == kImportAccessMode);
std::ostringstream log;
Notify::ptr()->set_ostream_ptr(&log, false);
bool ok = MayaLoadEggFile(fileName.asChar(), merge, model, anim, false);
std::string txt = log.str();
if (txt != "") {
MGlobal::displayError(txt.c_str());
} else {
if (!ok) MGlobal::displayError("Cannot import Egg file, unknown reason");
}
return ok ? MS::kSuccess : MS::kFailure;
}
MStatus MayaEggImporter::writer ( const MFileObject& file,
const MString& options,
FileAccessMode mode )
{
fprintf(stderr, "MayaEggImporter::writer called in error\n");
return MS::kFailure;
}
MPxFileTranslator::MFileKind MayaEggImporter::identifyFile (
const MFileObject& fileName,
const char* buffer,
short size) const
{
const char * name = fileName.name().asChar();
int nameLength = strlen(name);
if ((nameLength > 4) && !strcmp(name+nameLength-4, ".egg"))
return kCouldBeMyFileType;
else
return kNotMyFileType;
}
EXPCL_MISC MStatus initializePlugin( MObject obj )
{
MFnPlugin plugin( obj, "Alias", "3.0", "Any");
// Register the translator with the system
return plugin.registerFileTranslator( "Panda3D Egg Import", "none",
MayaEggImporter::creator,
"eggImportOptions",
"merge=1;model=1;anim=0;");
}
EXPCL_MISC MStatus uninitializePlugin( MObject obj )
{
MFnPlugin plugin( obj );
return plugin.deregisterFileTranslator( "Panda3D Egg Import" );
}

View File

@ -1,335 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file mayaPview.cxx
* @author drose
* @date 2003-03-10
*/
#ifdef __MACH__
#define __OPENTRANSPORTPROVIDERS__
#endif
#include "mayaPview.h"
#include "mayaToEggConverter.h"
#include "eggData.h"
#include "load_egg_file.h"
#include "config_putil.h"
#include "config_chan.h"
#include "config_gobj.h"
#include "textNode.h"
#include "multiplexStream.h"
#include "distanceUnit.h"
#include "configVariableEnum.h"
// We must define this to prevent Maya from doubly-declaring its MApiVersion
// string in this file as well as in libmayaegg.
#define _MApiVersion
#include "pre_maya_include.h"
#include <maya/MString.h>
#include <maya/MFnPlugin.h>
#include <maya/MFileIO.h>
#include <maya/MArgParser.h>
#include <maya/MArgList.h>
#include <maya/MSyntax.h>
#include <maya/MProgressWindow.h>
#include "post_maya_include.h"
// On Windows, we have code to fork pview as a separate process, which seems
// to be better for Maya.
#ifdef _WIN32
#include <windows.h>
#include <process.h>
#define SEPARATE_PVIEW 1
#endif // _WIN32
/**
*
*/
MayaPview::
MayaPview() {
}
/**
* Called when the plugin command is invoked.
*/
MStatus MayaPview::
doIt(const MArgList &args) {
MStatus result;
// First, parse the plugin arguments.
MSyntax syntax;
syntax.addFlag("a", "animate");
MArgParser parser(syntax, args, &result);
if (!result) {
result.perror("arguments");
return result;
}
bool animate = parser.isFlagSet("a", &result);
if (!result) {
result.perror("isFlagSet");
return result;
}
if (!MProgressWindow::reserve()) {
nout << "Couldn't reserve progress window.\n";
return MS::kFailure;
}
MProgressWindow::setTitle("Sending to pview");
MProgressWindow::setInterruptable(false);
MProgressWindow::setProgressRange(0, 3);
MProgressWindow::setProgressStatus("Converting scene");
MProgressWindow::startProgress();
#ifdef SEPARATE_PVIEW
// We'll write the bam file to a temporary file first.
Filename bam_filename = Filename::temporary("", "pview");
bam_filename.set_extension("bam");
// Since we're just writing to a bam file in this process, and running pview
// in a separate process, we don't actually need to load textures at this
// point. Disable the loading of textures.
textures_header_only = true;
NodePath root("root");
if (!convert(root, animate)) {
nout << "failure in conversion.\n";
MProgressWindow::endProgress();
return MS::kFailure;
}
MProgressWindow::setProgressStatus("Writing bam file");
MProgressWindow::advanceProgress(1);
if (!root.write_bam_file(bam_filename)) {
nout << "Couldn't write to " << bam_filename << ".\n";
MProgressWindow::endProgress();
return MS::kFailure;
}
MProgressWindow::setProgressStatus("Spawning pview");
MProgressWindow::advanceProgress(1);
// Now spawn a pview instance to view this temporary file.
std::string pview_args = "-clD";
if (animate) {
pview_args = "-clDa";
}
// On Windows, we use the spawn function to run pview asynchronously.
std::string quoted = std::string("\"") + bam_filename.get_fullpath() + std::string("\"");
nout << "pview " << pview_args << " " << quoted << "\n";
int retval = _spawnlp(_P_DETACH, "pview",
"pview", pview_args.c_str(), quoted.c_str(), nullptr);
if (retval == -1) {
bam_filename.unlink();
MProgressWindow::endProgress();
return MS::kFailure;
}
nout << "pview running.\n";
MProgressWindow::endProgress();
#else // SEPARATE_PVIEW
// We'll run PandaFramework directly within this process.
// Maya seems to run each invocation of the plugin in a separate thread. To
// minimize conflict in our not-yet-completely-thread-safe Panda, we'll
// create a separate PandaFramework for each invocation, even though in
// principle we could be sharing one framework for all of them.
int argc = 0;
char **argv = nullptr;
PandaFramework framework;
framework.open_framework(argc, argv);
framework.set_window_title("Panda Viewer");
framework.enable_default_keys();
PT(WindowFramework) window;
window = framework.open_window();
if (window == nullptr) {
// Couldn't open a window.
nout << "Couldn't open a window!\n";
MProgressWindow::endProgress();
return MS::kFailure;
}
// We've successfully opened a window.
// Put up a "loading" message for the user's benefit.
NodePath aspect_2d = window->get_aspect_2d();
PT(TextNode) loading = new TextNode("loading");
NodePath loading_np = aspect_2d.attach_new_node(loading);
loading_np.set_scale(0.125f);
loading->set_text_color(1.0f, 1.0f, 1.0f, 1.0f);
loading->set_shadow_color(0.0f, 0.0f, 0.0f, 1.0f);
loading->set_shadow(0.04, 0.04);
loading->set_align(TextNode::A_center);
loading->set_text("Loading...");
// Allow a couple of frames to go by so the window will be fully created and
// the text will be visible.
framework.do_frame(Thread::get_current_thread());
framework.do_frame(Thread::get_current_thread());
window->enable_keyboard();
window->setup_trackball();
framework.get_models().instance_to(window->get_render());
if (!convert(framework.get_models(), animate)) {
nout << "failure in conversion.\n";
MProgressWindow::endProgress();
return MS::kFailure;
}
nout << "successfully converted.\n";
loading_np.remove_node();
window->center_trackball(framework.get_models());
window->loop_animations();
if (animate) {
window->set_anim_controls(true);
}
MProgressWindow::endProgress();
framework.main_loop();
#endif // SEPARATE_PVIEW
return MS::kSuccess;
}
/**
* This is used to create a new instance of the plugin.
*/
void *MayaPview::
creator() {
return new MayaPview;
}
/**
* Actually converts the Maya selection to Panda geometry, and parents it to
* the indicated NodePath.
*/
bool MayaPview::
convert(const NodePath &parent, bool animate) {
// Now make a converter to get all the Maya structures.
MayaToEggConverter converter("plug-in");
// We always want polygon output since we want to be able to see the
// results.
converter._polygon_output = true;
converter._polygon_tolerance = 0.01;
if (animate) {
// We also want to get the animation if there is any.
converter.set_animation_convert(AC_both);
// Don't compress animation channels; that can introduce confusing
// artifacts.
compress_channels = false;
}
PathReplace *path_replace = converter.get_path_replace();
// Accept relative pathnames in the Maya file.
Filename source_file =
Filename::from_os_specific(MFileIO::currentFile().asChar());
std::string source_dir = source_file.get_dirname();
if (!source_dir.empty()) {
path_replace->_path.append_directory(source_dir);
}
// Also search along the model path.
path_replace->_path.append_path(get_model_path());
PT(EggData) egg_data = new EggData;
converter.set_egg_data(egg_data);
converter.set_from_selection(true);
converter.set_neutral_frame(-1);
if (!converter.convert_maya()) {
nout << "Errors in conversion.\n";
return false;
}
MProgressWindow::setProgressStatus("Converting to bam");
MProgressWindow::advanceProgress(1);
// Now the converter has filled up our egg structure with data, so convert
// this egg data to Panda data for immediate viewing.
DistanceUnit input_units = converter.get_input_units();
ConfigVariableEnum<DistanceUnit> ptloader_units("ptloader-units", DU_invalid);
if (input_units != DU_invalid && ptloader_units != DU_invalid &&
input_units != ptloader_units) {
// Convert the file to the units specified by the ptloader-units Configrc
// variable.
nout
<< "Converting from " << format_long_unit(input_units)
<< " to " << format_long_unit(ptloader_units) << "\n";
double scale = convert_units(input_units, ptloader_units);
egg_data->transform(LMatrix4d::scale_mat(scale));
}
egg_data->set_coordinate_system(CS_default);
PT(PandaNode) result = load_egg_data(egg_data);
if (result == nullptr) {
nout << "Unable to load converted egg data.\n";
return false;
}
parent.attach_new_node(result);
return true;
}
/**
* Called by Maya when the plugin is loaded.
*/
EXPCL_MISC MStatus
initializePlugin(MObject obj) {
// This code is just for debugging, to cause Notify to write its output to a
// log file we can inspect, so we can see the error messages output by DX7
// or DX8 just before it does a panic exit (and thereby shuts down Maya and
// its output window).
/*
MultiplexStream *local_nout = new MultiplexStream();
Notify::ptr()->set_ostream_ptr(local_nout, 0);
local_nout->add_file(Filename::expand_from("$TEMP/libmayapview.log"));
local_nout->add_standard_output();
*/
MFnPlugin plugin(obj, "VR Studio", "1.0");
MStatus status;
status = plugin.registerCommand("pview", MayaPview::creator);
if (!status) {
status.perror("registerCommand");
}
return status;
}
/**
* Called by Maya when the plugin is unloaded.
*/
EXPCL_MISC MStatus
uninitializePlugin(MObject obj) {
MFnPlugin plugin(obj);
MStatus status;
status = plugin.deregisterCommand("pview");
if (!status) {
status.perror("deregisterCommand");
}
return status;
}

View File

@ -1,45 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file mayaPview.h
* @author drose
* @date 2003-03-11
*/
#ifndef MAYAPVIEW_H
#define MAYAPVIEW_H
#include "pandatoolbase.h"
#include "pandaFramework.h"
#include "pre_maya_include.h"
#include <maya/MArgList.h>
#include <maya/MPxCommand.h>
#include <maya/MObject.h>
#include "post_maya_include.h"
/**
* This class serves as a plug-in to Maya to allow viewing the current Maya
* selection as it will be converted to Panda.
*/
class MayaPview : public MPxCommand {
public:
MayaPview();
virtual MStatus doIt(const MArgList &args);
static void *creator();
private:
bool convert(const NodePath &parent, bool animate);
};
EXPCL_MISC MStatus initializePlugin(MObject obj);
EXPCL_MISC MStatus uninitializePlugin(MObject obj);
#endif

View File

@ -1,133 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file mayaSavePview.cxx
* @author drose
* @date 2003-10-27
*/
#include "mayaSavePview.h"
#include <maya/MString.h>
#include <maya/MFnPlugin.h>
#include <maya/MFileIO.h>
#include <maya/MArgParser.h>
#include <maya/MArgList.h>
#include <maya/MSyntax.h>
#include <stdlib.h>
#ifdef _WIN32
#include <process.h>
#endif
/**
*
*/
MayaSavePview::
MayaSavePview() {
}
/**
* Called when the plugin command is invoked.
*/
MStatus MayaSavePview::
doIt(const MArgList &args) {
MStatus result;
// First, parse the plugin arguments.
MSyntax syntax;
syntax.addFlag("a", "animate");
MArgParser parser(syntax, args, &result);
if (!result) {
result.perror("arguments");
return result;
}
bool animate = parser.isFlagSet("a", &result);
if (!result) {
result.perror("isFlagSet");
return result;
}
// Now make sure the current buffer is saved.
result = MFileIO::save(false);
if (result != MS::kSuccess) {
return result;
}
MString filename = MFileIO::currentFile();
MString pview_args = "-cl";
if (animate) {
pview_args = "-cla";
}
#ifdef _WIN32
// On Windows, we use the spawn function to run pview asynchronously.
MString quoted = MString("\"") + filename + MString("\"");
intptr_t retval = _spawnlp(_P_DETACH, "pview",
"pview", pview_args.asChar(), quoted.asChar(), nullptr);
if (retval == -1) {
return MS::kFailure;
}
#else // _WIN32
// On non-Windows (e.g. Unix), we just use the system function, which runs
// synchronously. We could fork a process, but no one's asked for this yet.
MString command = MString("pview " + pview_args + MString(" \"") + filename + MString("\""));
int command_result = system(command.asChar());
if (command_result != 0) {
return MS::kFailure;
}
#endif // _WIN32
return MS::kSuccess;
}
/**
* This is used to create a new instance of the plugin.
*/
void *MayaSavePview::
creator() {
return new MayaSavePview;
}
/**
* Called by Maya when the plugin is loaded.
*/
EXPCL_MISC MStatus
initializePlugin(MObject obj) {
MFnPlugin plugin(obj, "VR Studio", "1.0");
MStatus status;
status = plugin.registerCommand("pview", MayaSavePview::creator);
if (!status) {
status.perror("registerCommand");
}
return status;
}
/**
* Called by Maya when the plugin is unloaded.
*/
EXPCL_MISC MStatus
uninitializePlugin(MObject obj) {
MFnPlugin plugin(obj);
MStatus status;
status = plugin.deregisterCommand("pview");
if (!status) {
status.perror("deregisterCommand");
}
return status;
}

View File

@ -1,84 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file mayaSavePview.h
* @author drose
* @date 2003-10-27
*/
#ifndef MAYASAVEPVIEW_H
#define MAYASAVEPVIEW_H
// We don't want to include pre_maya_include.h here, since that would
// necessitate linking with Pandatool's libmaya.dll, which would in turn bring
// in a lot of stuff from panda that we don't really need. Instead, we'll
// just define the Maya symbols we require here.
// Maya will try to typedef bool unless this symbol is defined.
#ifndef _BOOL
#define _BOOL 1
#endif
#ifdef __MACH__
#define OSMac_ 1
// This defines MAYA_API_VERSION
#include <maya/MTypes.h>
#if MAYA_API_VERSION < 201600
#include <maya/OpenMayaMac.h>
#endif
#endif
// Even though we don't include any Panda headers, it's safe to include this
// one, since it only defines some macros that we need to make this program
// platform-independent.
#include "dtool_config.h"
#ifdef PHAVE_IOSTREAM
// This will ask Maya 5.0 or better to use the new <iostream> library instead
// of the old <iostream.h> library.
#define REQUIRE_IOSTREAM
#endif // PHAVE_IOSTREAM
#include <maya/MArgList.h>
#include <maya/MPxCommand.h>
#include <maya/MObject.h>
/**
* This class serves as a plug-in to Maya to save the scene and view it using
* the external pview program, rather than linking in any part of Panda to a
* Maya plugin.
*
* Since it does not link with any Panda code, and hence is a very lean
* plugin, it is less likely than MayaPview to cause interoperability problems
* within Maya. However, it does force a save-to-disk and a spawning of a
* separate executable, including a complete reloading of all of the Maya
* libraries, so it is quite a bit slower to execute. And the potential for
* interactive control is substantially reduced.
*/
class MayaSavePview : public MPxCommand {
public:
MayaSavePview();
virtual MStatus doIt(const MArgList &args);
static void *creator();
};
// Since we don't include any of the Panda headers (other than
// dtool_config.h), we have to define this macro ourselves, to tell Windows to
// export the following functions from the DLL.
#ifdef _WIN32
#define EXPCL_MISC __declspec(dllexport)
#else
#define EXPCL_MISC
#endif
EXPCL_MISC MStatus initializePlugin(MObject obj);
EXPCL_MISC MStatus uninitializePlugin(MObject obj);
#endif

View File

@ -1,383 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file mayaToEgg.cxx
* @author drose
* @date 2000-02-15
*
* Additional Maintenance by the PandaSE team
* Carnegie Mellon Entertainment Technology Center
* Spring '10
* Team Members:
* Deepak Chandraskeran - producer / programmer
* Andrew Gartner - programmer/technical artist
* Federico Perazzi - programmer
* Shuying Feng - programmer
* Wei-Feng Huang - programmer
* (Egger additions by Andrew Gartner and Wei-Feng Huang)
* The egger can now support vertex color in a variety
* of combinations with flat color and file color textures
* (see set_vertex_color). Also, there are two new
* command line options "legacy-shaders" and "texture-copy".
* The first treats any Maya material/shader as if it were
* a legacy shader. Passing it through the legacy codepath.
* This feature was originally intended to fix a bug where
* flat-color was being ignored in the modern (Phong) codepath
* However, with the new vertex and flat color functions it
* may not be necessary. Still, until the newer color functions
* have been tried and tested more, the feature has been left in
* to anticipate any problems that may arise. The texture copy
* feature was added to provide a way to resolve build path issues
* and can support both relative and absolute paths. The feature
* will copy any file maps/textures to the specified directory
* and update the egg file accordingly.
*/
#include "mayaToEgg.h"
#include "mayaToEggConverter.h"
#include "config_mayaegg.h"
#include "config_maya.h" // for maya_cat
#include "globPattern.h"
#include "mayaConversionServer.h"
/**
*
*/
MayaToEgg::
MayaToEgg() :
SomethingToEgg("Maya", ".mb")
{
add_path_replace_options();
add_path_store_options();
add_animation_options();
add_units_options();
add_normals_options();
add_transform_options();
set_program_brief("convert Maya model files to .egg");
set_program_description
("This program converts Maya model files to egg. Static and animatable "
"models can be converted, with polygon or NURBS output. Animation tables "
"can also be generated to apply to an animatable model.");
add_option
("p", "", 0,
"Generate polygon output only. Tesselate all NURBS surfaces to "
"polygons via the built-in Maya tesselator. The tesselation will "
"be based on the tolerance factor given by -ptol.",
&MayaToEgg::dispatch_none, &_polygon_output);
add_option
("ptol", "tolerance", 0,
"Specify the fit tolerance for Maya polygon tesselation. The smaller "
"the number, the more polygons will be generated. The default is "
"0.01.",
&MayaToEgg::dispatch_double, nullptr, &_polygon_tolerance);
add_option
("bface", "", 0,
"Respect the Maya \"double sided\" rendering flag to indicate whether "
"polygons should be double-sided or single-sided. Since this flag "
"is set to double-sided by default in Maya, it is often better to "
"ignore this flag (unless your modelers are diligent in turning it "
"off where it is not desired). If this flag is not specified, the "
"default is to treat all polygons as single-sided, unless an "
"egg object type of \"double-sided\" is set.",
&MayaToEgg::dispatch_none, &_respect_maya_double_sided);
add_option
("suppress-vcolor", "", 0,
"Ignore vertex color for geometry that has a texture applied. "
"(This is the way Maya normally renders internally.) The egg flag "
"'vertex-color' may be applied to a particular model to override "
"this setting locally.",
&MayaToEgg::dispatch_none, &_suppress_vertex_color);
add_option
("convert-cameras", "", 0,
"Convert all camera nodes to locators. Will preserve position and rotation.",
&MayaToEgg::dispatch_none, &_convert_cameras);
add_option
("convert-lights", "", 0,
"Convert all light nodes to locators. Will preserve position and rotation only.",
&MayaToEgg::dispatch_none, &_convert_lights);
add_option
("keep-uvs", "", 0,
"Convert all UV sets on all vertices, even those that do not appear "
"to be referenced by any textures.",
&MayaToEgg::dispatch_none, &_keep_all_uvsets);
add_option
("round-uvs", "", 0,
"round up uv coordinates to the nearest 1/100th. i.e. -0.001 becomes"
"0.0; 0.444 becomes 0.44; 0.778 becomes 0.78.",
&MayaToEgg::dispatch_none, &_round_uvs);
add_option
("copytex", "dir", 41,
"Legacy option. Same as -pc.",
&MayaToEgg::dispatch_filename, &_legacy_copytex, &_legacy_copytex_dir);
add_option("server", "", 0,
"Runs the Maya model conversion server. This server can be used in tandem "
"with the egg2maya_client and maya2egg_client utilities to batch convert "
"both Maya and Panda3D model files.",
&MayaToEgg::dispatch_none, &_run_server);
add_option
("trans", "type", 0,
"Specifies which transforms in the Maya file should be converted to "
"transforms in the egg file. The option may be one of all, model, "
"dcs, or none. The default is model, which means only transforms on "
"nodes that have the model flag or the dcs flag are preserved.",
&MayaToEgg::dispatch_transform_type, nullptr, &_transform_type);
add_option
("subroot", "name", 0,
"Specifies that only a subroot of the geometry in the Maya file should "
"be converted; specifically, the geometry under the node or nodes whose "
"name matches the parameter (which may include globbing characters "
"like * or ?). This parameter may be repeated multiple times to name "
"multiple roots. If it is omitted altogether, the entire file is "
"converted.",
&MayaToEgg::dispatch_vector_string, nullptr, &_subroots);
add_option
("subset", "name", 0,
"Specifies that only a subset of the geometry in the Maya file should "
"be converted; specifically, the geometry under the node or nodes whose "
"name matches the parameter (which may include globbing characters "
"like * or ?). This parameter may be repeated multiple times to name "
"multiple roots. If it is omitted altogether, the entire file is "
"converted.",
&MayaToEgg::dispatch_vector_string, nullptr, &_subsets);
add_option
("exclude", "name", 0,
"Specifies that a subset of the geometry in the Maya file should "
"not be converted; specifically, the geometry under the node or nodes whose "
"name matches the parameter (which may include globbing characters "
"like * or ?). This parameter may be repeated multiple times to name "
"multiple roots.",
&MayaToEgg::dispatch_vector_string, nullptr, &_excludes);
add_option
("ignore-slider", "name", 0,
"Specifies the name of a slider (blend shape deformer) that maya2egg "
"should not process. The slider will not be touched during conversion "
"and it will not become a part of the animation. This "
"parameter may including globbing characters, and it may be repeated "
"as needed.",
&MayaToEgg::dispatch_vector_string, nullptr, &_ignore_sliders);
add_option
("force-joint", "name", 0,
"Specifies the name of a DAG node that maya2egg "
"should treat as a joint, even if it does not appear to be a Maya joint "
"and does not appear to be animated.",
&MayaToEgg::dispatch_vector_string, nullptr, &_force_joints);
add_option
("v", "", 0,
"Increase verbosity. More v's means more verbose.",
&MayaToEgg::dispatch_count, nullptr, &_verbose);
add_option
("legacy-shaders", "", 0,
"Use this flag to turn off modern (Phong) shader generation"
"and treat all shaders as if they were Lamberts (legacy).",
&MayaToEgg::dispatch_none, &_legacy_shader);
// Unfortunately, the Maya API doesn't allow us to differentiate between
// relative and absolute pathnames--everything comes out as an absolute
// pathname, even if it is stored in the Maya file as a relative path. So
// we can't support -noabs.
remove_option("noabs");
_verbose = 0;
_polygon_tolerance = 0.01;
_transform_type = MayaToEggConverter::TT_model;
_got_tbnauto = true;
}
/**
*
*/
MayaToEgg::
~MayaToEgg() {
}
/**
* Attempts to create the global Maya API.
* Exits the program if unsuccessful.
*/
PT(MayaApi) MayaToEgg::
open_api() {
if (!MayaApi::is_api_valid()) {
nout << "Initializing Maya...\n";
}
PT(MayaApi) api = MayaApi::open_api(_program_name, true, true);
if (!api || !api->is_valid()) {
nout << "Unable to initialize Maya.\n";
exit(1);
}
return api;
}
/**
* Returns true if the model has been successfully converted.
*/
bool MayaToEgg::
run() {
// Set the verbose level by using Notify.
if (_verbose >= 3) {
maya_cat->set_severity(NS_spam);
mayaegg_cat->set_severity(NS_spam);
} else if (_verbose >= 2) {
maya_cat->set_severity(NS_debug);
mayaegg_cat->set_severity(NS_debug);
} else if (_verbose >= 1) {
maya_cat->set_severity(NS_info);
mayaegg_cat->set_severity(NS_info);
}
if (_legacy_copytex && !_path_replace->_copy_files) {
_path_replace->_copy_files = true;
_path_replace->_copy_into_directory = _legacy_copytex_dir;
}
// Let's convert the output file to a full path before we initialize Maya,
// since Maya now has a nasty habit of changing the current directory.
if (_got_output_filename) {
_output_filename.make_absolute();
_path_replace->_path_directory.make_absolute();
}
open_api();
MayaToEggConverter converter(_program_name);
// Copy in the command-line parameters.
converter._polygon_output = _polygon_output;
converter._polygon_tolerance = _polygon_tolerance;
converter._respect_maya_double_sided = _respect_maya_double_sided;
converter._always_show_vertex_color = !_suppress_vertex_color;
converter._keep_all_uvsets = _keep_all_uvsets;
converter._convert_cameras = _convert_cameras;
converter._convert_lights = _convert_lights;
converter._round_uvs = _round_uvs;
converter._transform_type = _transform_type;
converter._legacy_shader = _legacy_shader;
vector_string::const_iterator si;
if (!_subroots.empty()) {
converter.clear_subroots();
for (si = _subroots.begin(); si != _subroots.end(); ++si) {
converter.add_subroot(GlobPattern(*si));
}
}
if (!_subsets.empty()) {
converter.clear_subsets();
for (si = _subsets.begin(); si != _subsets.end(); ++si) {
converter.add_subset(GlobPattern(*si));
}
}
if (!_excludes.empty()) {
converter.clear_excludes();
for (si = _excludes.begin(); si != _excludes.end(); ++si) {
converter.add_exclude(GlobPattern(*si));
}
}
if (!_ignore_sliders.empty()) {
converter.clear_ignore_sliders();
for (si = _ignore_sliders.begin(); si != _ignore_sliders.end(); ++si) {
converter.add_ignore_slider(GlobPattern(*si));
}
}
if (!_force_joints.empty()) {
converter.clear_force_joints();
for (si = _force_joints.begin(); si != _force_joints.end(); ++si) {
converter.add_force_joint(GlobPattern(*si));
}
}
// Copy in the path and animation parameters.
apply_parameters(converter);
// Set the coordinate system to match Maya's.
if (!_got_coordinate_system) {
_coordinate_system = converter._maya->get_coordinate_system();
}
_data->set_coordinate_system(_coordinate_system);
converter.set_egg_data(_data);
if (!converter.convert_file(_input_filename)) {
nout << "Errors in conversion.\n";
return false;
}
// Use the standard Maya units, if the user didn't specify otherwise. This
// always returns centimeters, which is the way all Maya files are stored
// internally (and is the units returned by all of the API functions called
// here).
if (_input_units == DU_invalid) {
_input_units = converter.get_input_units();
}
// Write output file
write_egg_file();
close_output();
return true;
}
/**
* Dispatches a parameter that expects a MayaToEggConverter::TransformType
* option.
*/
bool MayaToEgg::
dispatch_transform_type(const std::string &opt, const std::string &arg, void *var) {
MayaToEggConverter::TransformType *ip = (MayaToEggConverter::TransformType *)var;
(*ip) = MayaToEggConverter::string_transform_type(arg);
if ((*ip) == MayaToEggConverter::TT_invalid) {
nout << "Invalid type for -" << opt << ": " << arg << "\n"
<< "Valid types are all, model, dcs, and none.\n";
return false;
}
return true;
}
/**
* Processes the arguments parsed by the program.
*
* If the server flag is specified, the Maya conversion server is started
* up rather than the usual conversion utility functionality.
*/
bool MayaToEgg::
handle_args(ProgramBase::Args &args) {
if (_run_server) {
open_api();
MayaConversionServer server;
server.listen();
exit(0);
return true;
}
return SomethingToEgg::handle_args(args);
}

View File

@ -1,64 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file mayaToEgg.h
* @author drose
* @date 2000-02-15
*/
#ifndef MAYATOEGG_H
#define MAYATOEGG_H
#include "pandatoolbase.h"
#include "somethingToEgg.h"
#include "mayaToEggConverter.h"
#include "mayaApi.h"
#include "programBase.h"
/**
*
*/
class MayaToEgg : public SomethingToEgg {
public:
MayaToEgg();
~MayaToEgg();
bool run();
protected:
static bool dispatch_transform_type(const std::string &opt, const std::string &arg, void *var);
virtual bool handle_args(ProgramBase::Args &args);
PT(MayaApi) open_api();
int _verbose;
bool _polygon_output;
double _polygon_tolerance;
bool _respect_maya_double_sided;
bool _suppress_vertex_color;
bool _keep_all_uvsets;
bool _convert_cameras;
bool _convert_lights;
bool _round_uvs;
bool _legacy_shader;
bool _legacy_copytex;
Filename _legacy_copytex_dir;
MayaToEggConverter::TransformType _transform_type;
vector_string _subroots;
vector_string _subsets;
vector_string _excludes;
vector_string _ignore_sliders;
vector_string _force_joints;
public:
bool _run_server;
};
#endif

View File

@ -1,28 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file mayaToEggBin.cxx
* @author Derzsi Dániel
* @date 2020-10-01
*/
#include "mayaToEgg.h"
/**
* Entrypoint for maya2egg.
*/
int main(int argc, char *argv[]) {
MayaToEgg prog;
prog.parse_command_line(argc, argv);
if (!prog.run()) {
return 1;
}
return 0;
}

View File

@ -1,22 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file mayaToEggClient.cxx
* @author Derzsi Dániel
* @date 2020-10-01
*/
#include "mayaConversionClient.h"
/**
* Entrypoint for maya2egg_client.
*/
int main(int argc, char *argv[]) {
MayaConversionClient client;
return client.main(argc, argv, MayaConversionServer::ConversionType::CT_maya_to_egg);
}

View File

@ -1,474 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file mayapath.cxx
* @author drose
* @date 2008-04-07
*/
// This program works as a stub to launch maya2egg, egg2maya, and similar
// programs that invoke OpenMaya and require certain environment variables to
// be set first.
// It used to duplicate code in mayaWrapper.cxx, but now the functionality for
// these two separate programs are unified here.
// If MAYAVERSION is defined at the time this is compiled, then that
// particular version of Maya is insisted upon, and the desired Maya location
// is found in the Registry; otherwise, we require that $MAYA_LOCATION be set
// at runtime and points to the desired Maya installation.
/*
* If MAYAVERSION is defined and $MAYA_LOCATION is also set, then we check
* that definition of $MAYA_LOCATION is reasonable, which we define as
* pointing to the same version of OpenMaya.dll. If so, then we use the
* runtime $MAYA_LOCATION, allowing the user to (slightly) override the
* runtime Maya directory. If $MAYA_LOCATION is set but points to a different
* version of OpenMaya.dll, we ignore it altogether and replace it with our
* registry data, which allows the user to have MAYA_LOCATION pointing to a
* different version of Maya without interfering with this program.
*/
#include "dtoolbase.h"
#include "filename.h"
#include "globPattern.h"
#include "dSearchPath.h"
#include "executionEnvironment.h"
#include "hashVal.h"
#include <stdlib.h>
#if defined(_WIN32)
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#else
#include <sys/stat.h>
#endif
using std::cerr;
using std::endl;
using std::string;
#define QUOTESTR(x) #x
#define TOSTRING(x) QUOTESTR(x)
// Searches for python26.zip or whatever version it is.
static Filename
find_pyzip(const Filename &maya_location) {
// This is where python26.zip appears on Windows. Should it be in other
// locations on other platforms?
Filename dirname(maya_location, "bin");
vector_string results;
GlobPattern glob("python*.zip");
if (glob.match_files(results, dirname) != 0) {
return Filename(dirname, results[0]);
}
return Filename();
}
struct MayaVerInfo {
const char *ver, *key;
};
struct MayaVerInfo maya_versions[] = {
{ "MAYA6", "6.0" },
{ "MAYA65", "6.5" },
{ "MAYA7", "7.0" },
{ "MAYA8", "8.0" },
{ "MAYA85", "8.5" },
{ "MAYA2008", "2008"},
{ "MAYA2009", "2009"},
{ "MAYA2010", "2010"},
{ "MAYA2011", "2011"},
{ "MAYA2012", "2012"},
{ "MAYA2013", "2013"},
{ "MAYA20135", "2013.5"},
{ "MAYA2014", "2014"},
{ "MAYA2015", "2015"},
{ "MAYA2016", "2016"},
{ "MAYA20165", "2016.5"},
{ "MAYA2017", "2017"},
{ "MAYA2018", "2018"},
{ "MAYA2019", "2019"},
{ "MAYA2020", "2020"},
{ "MAYA2022", "2022"},
{ 0, 0 },
};
static const char *
get_version_number(const char *ver) {
for (int i = 0; maya_versions[i].ver != 0; ++i) {
if (strcmp(maya_versions[i].ver, ver) == 0) {
return maya_versions[i].key;
}
}
return 0;
}
static Filename
get_openmaya_filename(const Filename &maya_location) {
#ifdef _WIN32
// Note: Filename::dso_filename changes .so to .dll automatically.
// Maya 2022 has two versions of OpenMaya.dll, one for Python 3 and
// one for Python 2, in bin3 and bin2 folders.
Filename bin3 = Filename(maya_location, "bin3");
Filename bin3_openmaya = Filename::dso_filename(maya_location / "bin3/OpenMaya.so");
if (bin3_openmaya.is_regular_file()) {
return bin3_openmaya;
}
return Filename::dso_filename(maya_location / "bin/OpenMaya.so");
#elif defined(IS_OSX)
return Filename::dso_filename(maya_location / "MacOS/libOpenMaya.dylib");
#else
return Filename::dso_filename(maya_location / "lib/libOpenMaya.so");
#endif // _WIN32
}
#if defined(_WIN32)
static void
get_maya_location(const char *ver, string &loc) {
char fullkey[1024];
const char *developer;
LONG res;
for (int dev=0; dev<3; dev++) {
switch (dev) {
case 0: developer="Alias|Wavefront"; break;
case 1: developer="Alias"; break;
case 2: developer="Autodesk"; break;
}
sprintf(fullkey, "SOFTWARE\\%s\\Maya\\%s\\Setup\\InstallPath", developer, ver);
for (int hive=0; hive<2; hive++) {
HKEY hkey;
res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, fullkey, 0, KEY_READ | (hive ? 256:0), &hkey);
if (res == ERROR_SUCCESS) {
DWORD dtype;
DWORD size = 4096;
char result[4096 + 1];
res = RegQueryValueEx(hkey, "MAYA_INSTALL_LOCATION", nullptr, &dtype, (LPBYTE)result, &size);
if ((res == ERROR_SUCCESS)&&(dtype == REG_SZ)) {
result[size] = 0;
loc = result;
}
RegCloseKey(hkey);
}
}
}
}
#elif defined(__APPLE__)
static void
get_maya_location(const char *ver, string &loc) {
char mpath[64];
sprintf(mpath, "/Applications/Autodesk/maya%s/Maya.app/Contents", ver);
struct stat st;
if(stat(mpath, &st) == 0) {
loc = mpath;
}
}
#else // _WIN32
static void
get_maya_location(const char *ver, string &loc) {
char mpath[64];
#if __WORDSIZE == 64
sprintf(mpath, "/usr/autodesk/maya%s-x64", ver);
#else
sprintf(mpath, "/usr/autodesk/maya%s", ver);
#endif
struct stat st;
if(stat(mpath, &st) == 0) {
loc = mpath;
} else {
#if __WORDSIZE == 64
sprintf(mpath, "/usr/aw/maya%s-x64", ver);
#else
sprintf(mpath, "/usr/aw/maya%s", ver);
#endif
if(stat(mpath, &st) == 0) {
loc = mpath;
}
}
}
#endif // _WIN32
int
main(int argc, char *argv[]) {
// First, get the command line and append _bin, so we will actually run
// maya2egg_bin.exe, egg2maya_bin.exe, etc.
Filename command = ExecutionEnvironment::get_binary_name();
if (command.empty() || command == "unknown" || !command.exists()) {
command = Filename::from_os_specific(argv[0]);
if (!command.is_fully_qualified()) {
DSearchPath path;
path.append_path(ExecutionEnvironment::get_environment_variable("PATH"));
#ifdef _WIN32
command.set_extension("exe");
#endif
command.resolve_filename(path);
}
}
command.set_basename_wo_extension(command.get_basename_wo_extension() + "_bin");
string os_command = command.to_os_specific();
// First start with $PANDA_MAYA_LOCATION. If it is set, it overrides
// everything else.
Filename maya_location = Filename::expand_from("$PANDA_MAYA_LOCATION");
if (!maya_location.empty()) {
// Reset maya_location to its full long name, because Maya requires this.
maya_location.make_canonical();
maya_location = Filename::from_os_specific(maya_location.to_os_long_name());
} else {
// $PANDA_MAYA_LOCATION wasn't set, so check the normal locations. First,
// we get the standard location, as a point of reference.
Filename standard_maya_location;
#ifdef MAYAVERSION
const char *key = get_version_number(TOSTRING(MAYAVERSION));
if (key == nullptr) {
cerr << "Unknown Maya version: " << TOSTRING(MAYAVERSION) << "\n";
} else {
string loc;
get_maya_location(key, loc);
if (loc.empty()) {
cerr << "Cannot locate " << TOSTRING(MAYAVERSION) << ": it does not appear to be installed.\n";
} else {
standard_maya_location = Filename::from_os_specific(loc);
}
}
if (!standard_maya_location.empty()) {
// Reset standard_maya_location to its full long name, so we can compare
// reliably to the given version.
standard_maya_location.make_canonical();
standard_maya_location = Filename::from_os_specific(standard_maya_location.to_os_long_name());
}
#endif // MAYAVERSION
// Now check if $MAYA_LOCATION is set. If it is, and it's consistent with
// the standard location, we respect it.
maya_location = Filename::expand_from("$MAYA_LOCATION");
if (!maya_location.empty()) {
// Reset maya_location to its full long name, so we can compare it
// reliably to the standard location; and also because Maya requires
// this.
maya_location.make_canonical();
maya_location = Filename::from_os_specific(maya_location.to_os_long_name());
}
if (maya_location.empty()) {
// If it is not set, we use the standard version instead.
maya_location = standard_maya_location;
} else if (maya_location != standard_maya_location) {
// If it *is* set, we verify that OpenMaya.dll matches the standard
// version.
Filename openmaya_given = get_openmaya_filename(maya_location);
Filename openmaya_standard = get_openmaya_filename(standard_maya_location);
if (openmaya_given != openmaya_standard) {
// Check the md5 hashes of the DLL.
HashVal hash_given, hash_standard;
if (!hash_standard.hash_file(openmaya_standard)) {
// Couldn't read the standard file, so use the given one.
} else {
if (!hash_given.hash_file(openmaya_given)) {
// Couldn't even read the given file; use the standard one
// instead.
maya_location = standard_maya_location;
} else {
if (hash_standard != hash_given) {
// No match; it must be the wrong version.
cerr << "$MAYA_LOCATION points to wrong version; using standard location instead.\n";
maya_location = standard_maya_location;
} else {
// The hash matches; keep the given MAYA_LOCATION setting.
}
}
}
}
}
}
if (maya_location.empty()) {
cerr << "$MAYA_LOCATION is not set!\n";
exit(1);
}
cerr << "MAYA_LOCATION: " << maya_location.to_os_specific() << endl;
if (!maya_location.is_directory()) {
cerr << "The directory referred to by $MAYA_LOCATION does not exist!\n";
exit(1);
}
// Look for OpenMaya.dll as a sanity check.
Filename openmaya = get_openmaya_filename(maya_location);
if (!openmaya.is_regular_file()) {
cerr << "Could not find OpenMaya library in $MAYA_LOCATION!\n";
exit(1);
}
// Re-set MAYA_LOCATION to its properly sanitized form.
{
string putenv_str = "MAYA_LOCATION=" + maya_location.to_os_specific();
char *putenv_cstr = strdup(putenv_str.c_str());
putenv(putenv_cstr);
}
#ifdef _WIN32
string sep = ";";
#else
string sep = ":";
#endif
// Now set PYTHONHOME & PYTHONPATH. Maya2008 requires this to be set and
// pointing within $MAYA_LOCATION, or it might get itself confused with
// another Python installation (e.g. Panda's).
Filename python = Filename(maya_location, "Python");
if (python.is_directory()) {
{
string putenv_str = "PYTHONHOME=" + python.to_os_specific();
char *putenv_cstr = strdup(putenv_str.c_str());
putenv(putenv_cstr);
}
{
string putenv_str = "PYTHONPATH=" + python.to_os_specific();
Filename pyzip = find_pyzip(maya_location);
if (!pyzip.empty() && pyzip.exists()) {
putenv_str += sep;
putenv_str += pyzip.to_os_specific();
}
Filename site_packages(python, "lib/site-packages");
if (site_packages.is_directory()) {
putenv_str += sep;
putenv_str += site_packages.to_os_specific();
}
char *putenv_cstr = strdup(putenv_str.c_str());
putenv(putenv_cstr);
}
}
// Also put the Maya bin directory on the PATH.
#ifdef IS_OSX
Filename bin = Filename(maya_location, "MacOS");
#else
Filename bin = Filename(maya_location, "bin");
#endif
if (bin.is_directory()) {
const char *path = getenv("PATH");
if (path == nullptr) {
path = "";
}
string putenv_str = "PATH=";
// On Windows, there may also be a bin3 or bin2 directory, we should
// add either one to the PATH.
#ifdef _WIN32
Filename bin3 = Filename(maya_location, "bin3");
if (bin3.is_directory()) {
putenv_str += bin3.to_os_specific() + sep;
}
#endif
putenv_str += bin.to_os_specific() + sep + path;
char *putenv_cstr = strdup(putenv_str.c_str());
putenv(putenv_cstr);
}
#ifdef IS_OSX
// And on DYLD_LIBRARY_PATH.
if (bin.is_directory()) {
const char *path = getenv("DYLD_LIBRARY_PATH");
if (path == nullptr) {
path = "";
}
string sep = ":";
string putenv_str = "DYLD_LIBRARY_PATH=" + bin.to_os_specific() + sep + path;
char *putenv_cstr = strdup(putenv_str.c_str());
putenv(putenv_cstr);
}
// We also have to give it a way to find the Maya frameworks.
Filename fw_dir = Filename(maya_location, "Frameworks");
if (fw_dir.is_directory()) {
const char *path = getenv("DYLD_FALLBACK_FRAMEWORK_PATH");
if (path == nullptr) {
path = "";
}
string sep = ":";
string putenv_str = "DYLD_FALLBACK_FRAMEWORK_PATH=" + fw_dir.to_os_specific() + sep + path;
char *putenv_cstr = strdup(putenv_str.c_str());
putenv(putenv_cstr);
}
#elif !defined(_WIN32)
// Linux (or other non-Windows OS) gets it added to LD_LIBRARY_PATH.
if (bin.is_directory()) {
const char *path = getenv("LD_LIBRARY_PATH");
if (path == nullptr) {
path = "";
}
string sep = ":";
string putenv_str = "LD_LIBRARY_PATH=" + bin.to_os_specific() + sep + path;
char *putenv_cstr = strdup(putenv_str.c_str());
putenv(putenv_cstr);
}
#endif // IS_OSX
// Now that we have set up the environment variables properly, chain to the
// actual maya2egg_bin (or whichever) executable.
#ifdef _WIN32
// Windows case.
char *command_line = strdup(GetCommandLine());
STARTUPINFO startup_info;
PROCESS_INFORMATION process_info;
GetStartupInfo(&startup_info);
BOOL result = CreateProcess(os_command.c_str(),
command_line,
nullptr, nullptr, true, 0,
nullptr, nullptr,
&startup_info,
&process_info);
if (result) {
WaitForSingleObject(process_info.hProcess, INFINITE);
DWORD exit_code = 0;
if (GetExitCodeProcess(process_info.hProcess, &exit_code)) {
if (exit_code != 0) {
cerr << "Program exited with status " << exit_code << "\n";
}
}
CloseHandle(process_info.hProcess);
CloseHandle(process_info.hThread);
exit(exit_code);
}
cerr << "Couldn't execute " << command << ": " << GetLastError() << "\n";
#else
// Unix case.
execvp(os_command.c_str(), argv);
#endif
// Couldn't execute for some reason.
return 1;
}

View File

@ -1,289 +0,0 @@
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <string>
#ifndef _BOOL
#define _BOOL 1
#endif
#define REQUIRE_IOSTREAM
#include <maya/MGlobal.h>
#include <maya/MFileIO.h>
#include <maya/MLibrary.h>
#include <maya/MStatus.h>
#include <maya/MItDag.h>
#include <maya/MDagPath.h>
#include <maya/MFnDagNode.h>
#include <maya/MItMeshPolygon.h>
#include <maya/MItSelectionList.h>
#include <maya/MFnBlendShapeDeformer.h>
#include <maya/MFnMesh.h>
#include <maya/MPointArray.h>
using std::cerr;
using std::endl;
void
scan_nodes() {
MStatus status;
MItDag dag_iterator(MItDag::kDepthFirst, MFn::kTransform, &status);
if (!status) {
status.perror("MItDag constructor");
exit(1);
}
while (!dag_iterator.isDone()) {
MDagPath dag_path;
status = dag_iterator.getPath(dag_path);
if (!status) {
status.perror("MItDag::getPath");
exit(1);
}
MFnDagNode dag_node(dag_path, &status);
if (!status) {
status.perror("MFnDagNode constructor");
exit(1);
}
cerr << dag_node.name() << "\n";
dag_iterator.next();
}
}
MFnBlendShapeDeformer *
get_slider(MString slider_name) {
MStatus status;
status = MGlobal::selectByName(slider_name, MGlobal::kReplaceList);
if (!status) {
status.perror(slider_name);
exit(1);
}
MSelectionList list;
status = MGlobal::getActiveSelectionList(list);
if (!status) {
status.perror("MGLobal::getActiveSelectionList");
exit(1);
}
unsigned int num_objects = list.length();
if (num_objects != 1) {
cerr << "Warning: multiple objects match " << slider_name << "\n";
}
for (unsigned int i = 0; i < num_objects; i++) {
MObject obj;
status = list.getDependNode(i, obj);
if (!status) {
cerr << "selected element is not a dependency node.\n";
status.perror("getDependNode");
} else {
if (obj.hasFn(MFn::kBlendShape)) {
MFnBlendShapeDeformer *slider = new MFnBlendShapeDeformer(obj, &status);
if (!status) {
status.perror("MFnBlendShapeDeformer constructor");
} else {
cerr << "got slider " << slider->name() << "\n";
return slider;
}
}
cerr << "selected element is not a blend shape\n";
}
}
cerr << "Couldn't find slider " << slider_name << "\n";
exit(1);
}
MFnMesh *
get_mesh(MString mesh_name) {
MStatus status;
status = MGlobal::selectByName(mesh_name, MGlobal::kReplaceList);
if (!status) {
status.perror(mesh_name);
exit(1);
}
MSelectionList list;
status = MGlobal::getActiveSelectionList(list);
if (!status) {
status.perror("MGLobal::getActiveSelectionList");
exit(1);
}
unsigned int num_objects = list.length();
if (num_objects != 1) {
cerr << "Warning: multiple objects match " << mesh_name << "\n";
}
for (unsigned int i = 0; i < num_objects; i++) {
MObject obj;
status = list.getDependNode(i, obj);
if (!status) {
cerr << "selected element is not a dependency node.\n";
status.perror("getDependNode");
} else {
if (obj.hasFn(MFn::kMesh)) {
// Maybe it's a mesh object itself.
MFnMesh *mesh = new MFnMesh(obj, &status);
if (!status) {
status.perror("MFnMesh constructor");
} else {
cerr << "got mesh " << mesh->name() << "\n";
return mesh;
}
} else if (obj.hasFn(MFn::kDagNode)) {
// Maybe it's a dag node.
MDagPath path;
status = MDagPath::getAPathTo(obj, path);
if (!status) {
status.perror("MDagPath::getAPathTo");
exit(1);
}
if (path.hasFn(MFn::kMesh)) {
MFnMesh *mesh = new MFnMesh(path, &status);
if (!status) {
status.perror("MFnMesh constructor");
} else {
cerr << "got mesh " << mesh->name() << "\n";
return mesh;
}
}
}
cerr << "selected element is not a mesh\n";
}
}
cerr << "Couldn't find mesh " << mesh_name << "\n";
exit(1);
}
void
output_vertices(const char *filename, MFnMesh &mesh) {
MStatus status;
MPointArray verts;
// status = mesh.getPoints(verts, MSpace::kObject);
status = mesh.getPoints(verts, MSpace::kWorld);
if (!status) {
status.perror("mesh.getPoints");
exit(1);
}
std::ofstream file(filename, std::ios::out | std::ios::trunc);
if (!file) {
cerr << "Couldn't open " << filename << " for output.\n";
exit(1);
}
unsigned int num_verts = verts.length();
cerr << "writing " << num_verts << " vertices to " << filename << "\n";
for (unsigned int i = 0; i < num_verts; i++) {
file << i << ". " << verts[i] << "\n";
}
}
void
output_normals() {
MStatus status;
MDagPath dagPath, *_dag_path;
MObject component;
MItDag dag_iterator(MItDag::kDepthFirst, MFn::kTransform, &status);
if (!status) {
status.perror("MItDag constructor");
exit(1);
}
while (!dag_iterator.isDone()) {
status = dag_iterator.getPath(dagPath);
if (!status) {
status.perror("MItDag::getPath");
exit(1);
}
_dag_path = new MDagPath(dagPath);
MFnDagNode dag_node(*_dag_path, &status);
if (!status) {
status.perror("MFnDagNode constructor");
exit(1);
}
cerr << dag_node.name() << "\n";
if (_dag_path->hasFn(MFn::kMesh)) {
unsigned int numShapes;
status = _dag_path->numberOfShapesDirectlyBelow(numShapes);
cerr << "----numShapes: " << numShapes << "\n";
/*
if (numShapes == 1) {
_dag_path->extendToShape();
}
*/
}
MItMeshPolygon faceIter(*_dag_path, component, &status);
if( !status ) cerr << "Error at MItMeshPolygon" << endl;
MFnMesh meshFn(*_dag_path);
// Traverse the polygonal face
for (; !faceIter.isDone();faceIter.next()) {
int nVerts = faceIter.polygonVertexCount();
// Traverse the vertices to get their indexes and print out the normals
for (int i = 0;i<nVerts;i++) {
MVector normal;
faceIter.getNormal( i, normal, MSpace::kWorld );
cerr << "MItMeshPolygon::getNormal for the vertex [" << faceIter.vertexIndex(i)
<< "] for face [" << faceIter.index() << "] is " << normal << endl;
}
}
dag_iterator.next();
}
}
int
main(int argc, char *argv[]) {
cerr << "Initializing Maya\n";
MStatus status;
status = MLibrary::initialize(argv[0]);
if (!status) {
status.perror("Could not initialize");
exit(1);
}
cerr << "Using Maya library version " << MGlobal::mayaVersion() << "\n";
if (argc < 2) {
cerr << "\nUsage:\n\nnormal_test.cxx file.mb mesh_name\n\n";
exit(1);
}
MString filename = argv[1];
MFileIO::newFile(true);
cerr << "Reading " << filename << "\n";
status = MFileIO::open(filename);
if (!status) {
status.perror(filename);
exit(1);
}
output_normals();
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,64 +0,0 @@
--created by Andrew Gartner andrewgartner@gmail.com
--PandaSE team Spring semester 2010
--Carnegie Mellon Entertainment Technology Center
--TagSelectedObjects.ms
--creates a CF and CS type for any selected object
--in a max scene in order for the egger to apply
--a collision tag of that type based on the script's rollouts
(
global TagSelectedObjects
try(destroyDialog TagSelectedObjects)catch()
rollout TagSelectedObjects "Tag Selected Objects"
(
--key = #("Test","Test2")
--val = #("Test")
dropdownlist dlist_CStype "Collision Solid Type" items:#("plane","polyset","polygon","sphere","invsphere","tube","floormesh")
dropdownlist dlist_CFtype "Collision Flag Type" items:#("descend","keep","event","solid","center","intangible","level","turnstile")
button btn_tag "Tag Objects" width:140 height:30
button btn_remTag "Remove Tag" width:140 height:30
fn tagObjects =
(
theObjs = for obj in geometry collect obj
for obj in theObjs do
(
key = dlist_CStype.selected
val = dlist_CFtype.selected
print key
print val
setUserProp obj key 1
setUserProp obj val 1
--obj.wirecolor = gray
)--for
)--fn
fn removeTags =
(
theObjs = for obj in geometry collect obj
for obj in theObjs do
(
Cs_type = #("plane","polyset","polygon","sphere","invsphere","tube","floormesh")
Cf_type = #("descend","keep","event","solid","center","intangible","level","turnstile")
for cs_type in Cs_type do
(
key = cs_type as string
if getUserProp obj key != undefined do
setUserProp obj key 0
)
for cf_type in Cf_type do
(
key2 = cf_type as string
if getUserProp obj key2 != undefined do
setUserProp obj key2 0
)
)
)
on btn_tag pressed do tagObjects()
on btn_remTag pressed do removeTags()
)--rollout
createDialog TagSelectedObjects
)--globals