diff --git a/makepanda/makepanda.py b/makepanda/makepanda.py index 38a354f3e6..41731ba1a6 100755 --- a/makepanda/makepanda.py +++ b/makepanda/makepanda.py @@ -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/ # diff --git a/makepanda/makepandacore.py b/makepanda/makepandacore.py index 75385c567c..d30ec3df4e 100644 --- a/makepanda/makepandacore.py +++ b/makepanda/makepandacore.py @@ -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") diff --git a/pandatool/src/maya/config_maya.cxx b/pandatool/src/maya/config_maya.cxx deleted file mode 100644 index 2608243f9d..0000000000 --- a/pandatool/src/maya/config_maya.cxx +++ /dev/null @@ -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; -} diff --git a/pandatool/src/maya/config_maya.h b/pandatool/src/maya/config_maya.h deleted file mode 100644 index 256f4842e3..0000000000 --- a/pandatool/src/maya/config_maya.h +++ /dev/null @@ -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 diff --git a/pandatool/src/maya/eggObjectFlags.mel b/pandatool/src/maya/eggObjectFlags.mel deleted file mode 100644 index 7ad070d7fd..0000000000 --- a/pandatool/src/maya/eggObjectFlags.mel +++ /dev/null @@ -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 " { 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 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; - } -} diff --git a/pandatool/src/maya/mayaApi.cxx b/pandatool/src/maya/mayaApi.cxx deleted file mode 100644 index ce24e72d68..0000000000 --- a/pandatool/src/maya/mayaApi.cxx +++ /dev/null @@ -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 -#include -#include -#include -#include -#include -#include "post_maya_include.h" - -#ifdef _WIN32 -#include // 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 ©) { - 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 ©) { - 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; - } -} diff --git a/pandatool/src/maya/mayaApi.h b/pandatool/src/maya/mayaApi.h deleted file mode 100644 index f4e19e45da..0000000000 --- a/pandatool/src/maya/mayaApi.h +++ /dev/null @@ -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 ©); - void operator = (const MayaApi ©); - -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 diff --git a/pandatool/src/maya/mayaShader.cxx b/pandatool/src/maya/mayaShader.cxx deleted file mode 100644 index 9be62a60d3..0000000000 --- a/pandatool/src/maya/mayaShader.cxx +++ /dev/null @@ -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 -#include -#include -#include -#include -#include -#include -#include -#include -#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; -} diff --git a/pandatool/src/maya/mayaShader.h b/pandatool/src/maya/mayaShader.h deleted file mode 100644 index 34ff13a808..0000000000 --- a/pandatool/src/maya/mayaShader.h +++ /dev/null @@ -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 diff --git a/pandatool/src/maya/mayaShaderColorDef.cxx b/pandatool/src/maya/mayaShaderColorDef.cxx deleted file mode 100644 index 38aa294949..0000000000 --- a/pandatool/src/maya/mayaShaderColorDef.cxx +++ /dev/null @@ -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 -#include -#include -#include -#include -#include -#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 ©) { - _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 ¢roid) 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 -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; jfind_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 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_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_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 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 ¢roid) 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 ¢roid) 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; -} diff --git a/pandatool/src/maya/mayaShaderColorDef.h b/pandatool/src/maya/mayaShaderColorDef.h deleted file mode 100644 index 2609f2bb43..0000000000 --- a/pandatool/src/maya/mayaShaderColorDef.h +++ /dev/null @@ -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 MayaShaderColorList; -typedef pmap 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 ¢roid) const; - LPoint2d map_spherical(const LPoint3d &pos, const LPoint3d ¢roid) const; - LPoint2d map_cylindrical(const LPoint3d &pos, const LPoint3d ¢roid) const; - - // Define a pointer to one of the above member functions. - LPoint2d (MayaShaderColorDef::*_map_uvs)(const LPoint3d &pos, const LPoint3d ¢roid) 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 diff --git a/pandatool/src/maya/mayaShaders.cxx b/pandatool/src/maya/mayaShaders.cxx deleted file mode 100644 index 3809574bcb..0000000000 --- a/pandatool/src/maya/mayaShaders.cxx +++ /dev/null @@ -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 -#include -#include -#include -#include -#include -#include -#include -#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; ibind_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(); -} diff --git a/pandatool/src/maya/mayaShaders.h b/pandatool/src/maya/mayaShaders.h deleted file mode 100644 index 5428ab5f73..0000000000 --- a/pandatool/src/maya/mayaShaders.h +++ /dev/null @@ -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 _uvset_names; - void clear(); - void bind_uvsets(MObject mesh); - std::string find_uv_link(const std::string &match); - -private: - typedef pmap Shaders; - Shaders _shaders; - typedef pvector ShadersInOrder; - ShadersInOrder _shaders_in_order; -}; - -#endif diff --git a/pandatool/src/maya/maya_funcs.I b/pandatool/src/maya/maya_funcs.I deleted file mode 100644 index 1a56126c44..0000000000 --- a/pandatool/src/maya/maya_funcs.I +++ /dev/null @@ -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; -} diff --git a/pandatool/src/maya/maya_funcs.T b/pandatool/src/maya/maya_funcs.T deleted file mode 100644 index 3418ce3647..0000000000 --- a/pandatool/src/maya/maya_funcs.T +++ /dev/null @@ -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 -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 -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; -} diff --git a/pandatool/src/maya/maya_funcs.cxx b/pandatool/src/maya/maya_funcs.cxx deleted file mode 100644 index b07b8089d1..0000000000 --- a/pandatool/src/maya/maya_funcs.cxx +++ /dev/null @@ -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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#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 &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"; - } - } - } - } -} diff --git a/pandatool/src/maya/maya_funcs.h b/pandatool/src/maya/maya_funcs.h deleted file mode 100644 index ad0a7210b3..0000000000 --- a/pandatool/src/maya/maya_funcs.h +++ /dev/null @@ -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 -#include -#include -#include -#include -#include -#include -#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 -bool -get_maya_attribute(MObject &node, const std::string &attribute_name, - ValueType &value); - -template -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 &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 diff --git a/pandatool/src/maya/p3maya_composite1.cxx b/pandatool/src/maya/p3maya_composite1.cxx deleted file mode 100644 index 6d952402b6..0000000000 --- a/pandatool/src/maya/p3maya_composite1.cxx +++ /dev/null @@ -1,6 +0,0 @@ -#include "config_maya.cxx" -#include "mayaApi.cxx" -#include "mayaShader.cxx" -#include "mayaShaderColorDef.cxx" -#include "mayaShaders.cxx" -#include "maya_funcs.cxx" diff --git a/pandatool/src/maya/post_maya_include.h b/pandatool/src/maya/post_maya_include.h deleted file mode 100644 index 34e7152b63..0000000000 --- a/pandatool/src/maya/post_maya_include.h +++ /dev/null @@ -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. diff --git a/pandatool/src/maya/pre_maya_include.h b/pandatool/src/maya/pre_maya_include.h deleted file mode 100644 index 85442c1e7b..0000000000 --- a/pandatool/src/maya/pre_maya_include.h +++ /dev/null @@ -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 headers instead of the old -// 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 -#if MAYA_API_VERSION < 201600 -#include -#endif -#else -// This defines MAYA_API_VERSION -#include -#endif - -#if MAYA_API_VERSION >= 20180000 -#include -#else -class MObject; -class MDagPath; -class MFloatArray; -class MFnDagNode; -class MFnMesh; -class MFnNurbsCurve; -class MFnNurbsSurface; -class MPlug; -class MPointArray; -#endif diff --git a/pandatool/src/mayaegg/config_mayaegg.cxx b/pandatool/src/mayaegg/config_mayaegg.cxx deleted file mode 100644 index 396af69344..0000000000 --- a/pandatool/src/mayaegg/config_mayaegg.cxx +++ /dev/null @@ -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(); - -} diff --git a/pandatool/src/mayaegg/config_mayaegg.h b/pandatool/src/mayaegg/config_mayaegg.h deleted file mode 100644 index ede177ab26..0000000000 --- a/pandatool/src/mayaegg/config_mayaegg.h +++ /dev/null @@ -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 diff --git a/pandatool/src/mayaegg/mayaBlendDesc.cxx b/pandatool/src/mayaegg/mayaBlendDesc.cxx deleted file mode 100644 index b396ed86b6..0000000000 --- a/pandatool/src/mayaegg/mayaBlendDesc.cxx +++ /dev/null @@ -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; -} diff --git a/pandatool/src/mayaegg/mayaBlendDesc.h b/pandatool/src/mayaegg/mayaBlendDesc.h deleted file mode 100644 index 3be9183a82..0000000000 --- a/pandatool/src/mayaegg/mayaBlendDesc.h +++ /dev/null @@ -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 -#include -#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 diff --git a/pandatool/src/mayaegg/mayaEggGroupUserData.I b/pandatool/src/mayaegg/mayaEggGroupUserData.I deleted file mode 100644 index d3e6061e73..0000000000 --- a/pandatool/src/mayaegg/mayaEggGroupUserData.I +++ /dev/null @@ -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 ©) : - EggUserData(copy), - _vertex_color(copy._vertex_color), - _double_sided(copy._double_sided) -{ -} - - -/** - * - */ -INLINE void MayaEggGroupUserData:: -operator = (const MayaEggGroupUserData ©) { - EggUserData::operator = (copy); - _vertex_color = copy._vertex_color; - _double_sided = copy._double_sided; -} diff --git a/pandatool/src/mayaegg/mayaEggGroupUserData.cxx b/pandatool/src/mayaegg/mayaEggGroupUserData.cxx deleted file mode 100644 index 47fd08227f..0000000000 --- a/pandatool/src/mayaegg/mayaEggGroupUserData.cxx +++ /dev/null @@ -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; diff --git a/pandatool/src/mayaegg/mayaEggGroupUserData.h b/pandatool/src/mayaegg/mayaEggGroupUserData.h deleted file mode 100644 index 46b2d2ba79..0000000000 --- a/pandatool/src/mayaegg/mayaEggGroupUserData.h +++ /dev/null @@ -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 ©); - INLINE void operator = (const MayaEggGroupUserData ©); - - 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 diff --git a/pandatool/src/mayaegg/mayaEggLoader.cxx b/pandatool/src/mayaegg/mayaEggLoader.cxx deleted file mode 100644 index 200154bdc5..0000000000 --- a/pandatool/src/mayaegg/mayaEggLoader.cxx +++ /dev/null @@ -1,2209 +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.cxx - * @author jyelon - * @date 2005-07-20 - * - * This file contains the code for class MayaEggLoader. This class - * does the actual work of copying an EggData tree into the maya scene. - */ - -#include "pandatoolbase.h" -#include "notifyCategoryProxy.h" - -#include "eggBin.h" -#include "eggData.h" -#include "eggTable.h" -#include "eggVertex.h" -#include "eggPolygon.h" -#include "eggComment.h" -#include "eggXfmSAnim.h" -#include "eggSAnimData.h" -#include "eggPrimitive.h" -#include "eggGroupNode.h" -#include "eggVertexPool.h" -#include "eggPolysetMaker.h" -#include "eggNurbsSurface.h" -#include "texture.h" -#include "texturePool.h" - -#include "pre_maya_include.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "post_maya_include.h" - -#include "mayaEggLoader.h" - -using std::cerr; -using std::endl; -using std::ostringstream; -using std::string; -using std::vector; - -class MayaEggGroup; -class MayaEggGeom; -class MayaEggMesh; -class MayaEggJoint; -class MayaEggTex; -class MayaAnim; -class MayaEggNurbsSurface; - -NotifyCategoryDeclNoExport(mayaloader); -NotifyCategoryDef(mayaloader, ""); - -class MayaEggLoader -{ -public: - bool ConvertEggData(EggData *data, bool merge, bool model, bool anim, bool respect_normals); - bool ConvertEggFile(const char *name, bool merge, bool model, bool anim, bool respect_normals); - - -public: - void TraverseEggNode(EggNode *node, EggGroup *context, string delim); - MayaEggMesh *GetMesh(EggVertexPool *pool, EggGroup *parent); - MayaEggJoint *FindJoint(EggGroup *joint); - MayaEggJoint *MakeJoint(EggGroup *joint, EggGroup *context); - MayaEggGroup *FindGroup(EggGroup *group); - MayaEggGroup *MakeGroup(EggGroup *group, EggGroup *context); - MayaEggTex *GetTex(EggTexture *etex); - void CreateSkinCluster(MayaEggGeom *M); - - MayaAnim *GetAnim(EggXfmSAnim *pool); - MObject GetDependencyNode(string givenName); - - MayaEggNurbsSurface *GetSurface(EggVertexPool *pool, EggGroup *parent); - - typedef phash_map MeshTable; - typedef phash_map AnimTable; - typedef phash_map JointTable; - typedef phash_map GroupTable; - typedef phash_map TexTable; - typedef phash_map SurfaceTable; - - MeshTable _mesh_tab; - AnimTable _anim_tab; - JointTable _joint_tab; - GroupTable _group_tab; - TexTable _tex_tab; - SurfaceTable _surface_tab; - - vector _joint_list; - - int _start_frame; - int _end_frame; - int _frame_rate; - MTime::Unit _timeUnit; - - void ParseFrameInfo(string comment); - void PrintData(MayaEggMesh *mesh); - -private: - int _unnamed_idx; - MSelectionList _collision_nodes; -}; - -MPoint MakeMPoint(const LVector3d &vec) -{ - return MPoint(vec[0], vec[1], vec[2]); -} - -MFloatPoint MakeMayaPoint(const LVector3d &vec) -{ - return MFloatPoint(vec[0], vec[1], vec[2]); -} - -MVector MakeMayaVector(const LVector3d &vec) -{ - return MVector(vec[0], vec[1], vec[2]); -} - -MColor MakeMayaColor(const LColor &vec) -{ - return MColor(vec[0], vec[1], vec[2], vec[3]); -} - -// [gjeon] to create enum attribute, fieldNames is a stringArray of enum -// names, and filedIndex is the default index value -MStatus create_enum_attribute(MObject &node, MString fullName, MString briefName, - MStringArray fieldNames, unsigned fieldIndex) { - MStatus stat; - - MFnDependencyNode fnDN( node, &stat ); - if ( MS::kSuccess != stat ) { - mayaloader_cat.error() - << "Could not create MFnDependencyNode" << "\n"; - return stat; - } - - MFnEnumAttribute fnAttr; - MObject newAttr = fnAttr.create( fullName, briefName, - 0, &stat ); - if ( MS::kSuccess != stat ) { - mayaloader_cat.error() - << "Could not create new enum attribute " << fullName.asChar() << "\n"; - return stat; - } - for (unsigned i = 0; i < fieldNames.length(); i++){ - fnAttr.addField(fieldNames[i], i); - } - - stat = fnAttr.setDefault(fieldIndex); - if ( MS::kSuccess != stat ) { - mayaloader_cat.error() - << "Could not set value for enum attribute " << fullName.asChar() << "\n"; - return stat; - } - - fnAttr.setKeyable( true ); - fnAttr.setReadable( true ); - fnAttr.setWritable( true ); - fnAttr.setStorable( true ); - - // Now add the new attribute to this dependency node - stat = fnDN.addAttribute(newAttr, MFnDependencyNode::kLocalDynamicAttr); - if ( MS::kSuccess != stat ) { - mayaloader_cat.error() - << "Could not add new enum attribute " << fullName.asChar() << "\n"; - return stat; - } - - return stat; -} - -// MayaEggTex - -class MayaEggTex -{ -public: - string _name; - string _path; - MObject _file_texture; - MObject _shader; - MObject _shading_group; - - MFnSingleIndexedComponent _component; - void AssignNames(void); -}; - -void MayaEggTex::AssignNames(void) -{ - if (_name == "") { - return; - } - MFnDependencyNode shader(_shader); - MFnDependencyNode sgroup(_shading_group); - MFnDependencyNode filetex(_file_texture); - shader.setName(MString(_name.c_str())+"Shader"); - sgroup.setName(MString(_name.c_str())); - if (_file_texture != MObject::kNullObj) { - filetex.setName(MString(_name.c_str())+"File"); - } -} - -MayaEggTex *MayaEggLoader::GetTex(EggTexture* etex) -{ - string name = ""; - string fn = ""; - if (etex != nullptr) { - name = etex->get_name(); - fn = etex->get_fullpath().to_os_specific(); - } - - if (_tex_tab.count(fn)) { - return _tex_tab[fn]; - } - - MStatus status; - MFnLambertShader shader; - MFnDependencyNode filetex; - MFnSet sgroup; - MPlugArray oldplugs; - MDGModifier dgmod; - - /* - if (fn=="") { - MSelectionList selection; - MObject initGroup; - selection.clear(); - MGlobal::getSelectionListByName("initialShadingGroup",selection); - selection.getDependNode(0, initGroup); - sgroup.setObject(initGroup); - } else { - */ - if (1) { - shader.create(true,&status); - MColor firstColor(1.0,1.0,1.0,1.0); - status = shader.setColor(firstColor); - if (status != MStatus::kSuccess) { - mayaloader_cat.error() << "setColor failed on LambertShader\n"; - status.perror("shader setColor failed!"); - } - sgroup.create(MSelectionList(), MFnSet::kRenderableOnly, &status); - MPlug surfplug = sgroup.findPlug("surfaceShader"); - if (surfplug.connectedTo(oldplugs,true,false)) { - for (unsigned int i=0; iget_fullpath(), 0, false, options); - if (((tex != nullptr) && (tex->get_num_components() == 4)) - || (etex->get_format() == EggTexture::F_alpha) - || (etex->get_format() == EggTexture::F_luminance_alpha)) - dgmod.connect(filetex.findPlug("outTransparency"),shader.findPlug("transparency")); - } - status = dgmod.doIt(); - if (status != MStatus::kSuccess) { - status.perror("DGMod doIt"); - } - } - - MayaEggTex *res = new MayaEggTex; - res->_name = name; - res->_path = fn; - res->_file_texture = filetex.object(); - res->_shader = shader.object(); - res->_shading_group = sgroup.object(); - - _tex_tab[fn] = res; - return res; -} - -// MayaEggGroup - -class MayaEggGroup -{ -public: - string _name; - MObject _parent; - MObject _group; - - bool _addedEggFlag; -}; - -MayaEggGroup *MayaEggLoader::MakeGroup(EggGroup *group, EggGroup *context) -{ - MStatus status; - MayaEggGroup *pg = FindGroup(context); - MayaEggGroup *result = new MayaEggGroup; - MFnDagNode dgn; - - MObject parent = MObject::kNullObj; - if (pg) { - parent = pg->_group; - if (mayaloader_cat.is_debug()) { - mayaloader_cat.debug() << "parent (group) :" << ((MFnDagNode)parent).name().asChar() << endl; - } - } - - result->_name = group->get_name(); - result->_group = dgn.create("transform", MString(result->_name.c_str()), parent, &status); - result->_addedEggFlag = false; - - if (group->get_cs_type() != EggGroup::CST_none) - _collision_nodes.add(result->_group, true); - - if (group->has_transform3d()) { - LMatrix4d tMat = group->get_transform3d(); - double matData[4][4] = {{tMat.get_cell(0,0), tMat.get_cell(0,1), tMat.get_cell(0,2), tMat.get_cell(0,3)}, - {tMat.get_cell(1,0), tMat.get_cell(1,1), tMat.get_cell(1,2), tMat.get_cell(1,3)}, - {tMat.get_cell(2,0), tMat.get_cell(2,1), tMat.get_cell(2,2), tMat.get_cell(2,3)}, - {tMat.get_cell(3,0), tMat.get_cell(3,1), tMat.get_cell(3,2), tMat.get_cell(3,3)}}; - MMatrix mat(matData); - - MTransformationMatrix matrix = MTransformationMatrix(mat); - MFnTransform tFn(result->_group, &status); - if (status != MStatus::kSuccess) { - status.perror("MFnTransformNode:create failed!"); - } else { - tFn.set(matrix); - } - } - - if (status != MStatus::kSuccess) { - status.perror("MFnDagNode:create failed!"); - } - - if ((pg) && (pg->_addedEggFlag == false)){ - // [gjeon] to handle other flags - MStringArray eggFlags; - for (int i = 0; i < context->get_num_object_types(); i++) { - eggFlags.append(MString(context->get_object_type(i).c_str())); - } - - for (unsigned i = 0; i < eggFlags.length(); i++) { - MString attrName = "eggObjectTypes"; - attrName += (int)(i + 1); - status = create_enum_attribute(parent, attrName, attrName, eggFlags, i); - if (status != MStatus::kSuccess) { - status.perror("create_enum_attribute failed!"); - } - } - pg->_addedEggFlag = true; - } - - _group_tab[group] = result; - return result; -} - -MayaEggGroup *MayaEggLoader::FindGroup(EggGroup *group) -{ - if (group==0) { - return 0; - } - return _group_tab[group]; -} - -// MayaEggJoint - -class MayaEggJoint -{ -public: - LMatrix4d _trans; - LVector3d _endpos; - LVector3d _perp; - double _thickness; - MObject _joint; - MMatrix _joint_abs; - MDagPath _joint_dag_path; - bool _inskin; - int _index; - EggGroup *_egg_joint; - EggGroup *_egg_parent; - MayaEggJoint *_parent; - vector _children; - -public: - void GetRotation(LVector3d &xv, LVector3d &yv, LVector3d &zv); - LVector3d GetPos(void) { return _trans.get_row3(3); } - MayaEggJoint *ChooseBestChild(LVector3d dir); - void ChooseEndPos(double thickness); - void CreateMayaBone(MayaEggGroup *eggParent); - void AssignNames(void); -}; - -void MayaEggJoint::GetRotation(LVector3d &xv, LVector3d &yv, LVector3d &zv) -{ - xv = _trans.get_row3(0); - yv = _trans.get_row3(1); - zv = _trans.get_row3(2); - xv.normalize(); - yv.normalize(); - zv = xv.cross(yv); - zv.normalize(); - yv = zv.cross(xv); -} - -void MayaEggJoint::AssignNames(void) -{ - string name = _egg_joint->get_name(); - MFnDependencyNode joint(_joint); - joint.setName(name.c_str()); - if (mayaloader_cat.is_spam()) { - mayaloader_cat.spam() << "joint " << joint.name().asChar() << ": -> " << name << endl; - } -} - -MayaEggJoint *MayaEggLoader::FindJoint(EggGroup *joint) -{ - if (joint==nullptr) { - if (mayaloader_cat.is_spam()) { - mayaloader_cat.spam() << "joint:" << joint->get_name() << " is null: " << endl; - } - return 0; - } - if (!joint->is_joint()) { - if (mayaloader_cat.is_spam()) { - mayaloader_cat.spam() << "joint:" << joint->get_name() << " is not a joint: " << endl; - } - return 0; - } - return _joint_tab[joint]; -} - -MayaEggJoint *MayaEggLoader::MakeJoint(EggGroup *joint, EggGroup *context) -{ - MayaEggJoint *parent = FindJoint(context); - if (mayaloader_cat.is_debug()) { - string parent_name = ""; - if (parent) - parent_name = context->get_name(); - } - MayaEggJoint *result = new MayaEggJoint; - LMatrix4d t = joint->get_transform3d(); - if (parent) { - result->_trans = t * parent->_trans; - } else { - result->_trans = t; - } - result->_endpos = LVector3d(0,0,0); - result->_perp = LVector3d(0,0,0); - result->_thickness = 0.0; - result->_egg_joint = joint; - result->_egg_parent = context; - result->_parent = parent; - result->_joint = MObject::kNullObj; - result->_inskin = false; - result->_index = -1; - if (parent) { - parent->_children.push_back(result); - } - _joint_tab[joint] = result; - - // [gjeon] since _joint_tab is not always properly sorted - _joint_list.push_back(result); - - return result; -} - -MayaEggJoint *MayaEggJoint::ChooseBestChild(LVector3d dir) -{ - if (dir.length() < 0.001) { - return 0; - } - dir.normalize(); - double firstbest = -1000; - MayaEggJoint *firstchild = 0; - LVector3d firstpos = GetPos(); - double secondbest = 0; - for (unsigned int i=0; i<_children.size(); i++) { - MayaEggJoint *child = _children[i]; - LVector3d tryfwd = child->GetPos() - GetPos(); - if ((child->GetPos() != firstpos) && (tryfwd.length() > 0.001)) { - LVector3d trydir = tryfwd; - trydir.normalize(); - double quality = trydir.dot(dir); - if (quality > firstbest) { - secondbest = firstbest; - firstbest = quality; - firstpos = child->GetPos(); - firstchild = child; - } else if (quality > secondbest) { - secondbest = quality; - } - } - } - if (firstbest > secondbest + 0.1) { - return firstchild; - } - return 0; -} - -void MayaEggJoint::ChooseEndPos(double thickness) -{ - LVector3d parentpos(0,0,0); - LVector3d parentendpos(0,0,1); - if (_parent) { - parentpos = _parent->GetPos(); - parentendpos = _parent->_endpos; - } - LVector3d fwd = GetPos() - parentpos; - if (fwd.length() < 0.001) { - fwd = parentendpos - parentpos; - } - // mayaloader_cat.debug() << "fwd : " << fwd << endl; - fwd.normalize(); - MayaEggJoint *child = ChooseBestChild(fwd); - if (child == 0) { - _endpos = fwd * thickness * 0.8 + GetPos(); - _thickness = thickness * 0.8; - } else { - _endpos = child->GetPos(); - _thickness = (_endpos - GetPos()).length(); - if (_thickness > thickness) _thickness = thickness; - } - LVector3d orient = _endpos - GetPos(); - orient.normalize(); - LVector3d altaxis = orient.cross(LVector3d(0,-1,0)); - if (altaxis.length() < 0.001) { - altaxis = orient.cross(LVector3d(0,0,1)); - } - _perp = altaxis.cross(orient); - _perp.normalize(); -} - -void MayaEggJoint::CreateMayaBone(MayaEggGroup *eggParent) -{ - LVector3d rxv, ryv, rzv; - // GetRotation(rxv, ryv, rzv); [gjeon] I think we shouldn't need to use this - // GetRotation function here since this function removes scale information - // from the matrix. Let's just use the matrix directly. - rxv = _trans.get_row3(0); - ryv = _trans.get_row3(1); - rzv = _trans.get_row3(2); - - MFloatPoint xv(MakeMayaPoint(rxv)); - MFloatPoint yv(MakeMayaPoint(ryv)); - MFloatPoint zv(MakeMayaPoint(rzv)); - MFloatPoint pos(MakeMayaPoint(GetPos())); - MFloatPoint endpos(MakeMayaPoint(_endpos)); - MFloatPoint tzv(MakeMayaPoint(_perp)); - double m[4][4]; - m[0][0]=xv.x; m[0][1]=xv.y; m[0][2]=xv.z; m[0][3]=0; - m[1][0]=yv.x; m[1][1]=yv.y; m[1][2]=yv.z; m[1][3]=0; - m[2][0]=zv.x; m[2][1]=zv.y; m[2][2]=zv.z; m[2][3]=0; - m[3][0]=pos.x; m[3][1]=pos.y; m[3][2]=pos.z; m[3][3]=1; - MMatrix trans(m); - _joint_abs = trans; - if (_parent) { - trans = trans * _parent->_joint_abs.inverse(); - } - MTransformationMatrix mtm(trans); - - MFnIkJoint ikj; - if (_parent) { - ikj.create(_parent->_joint); - } - else { - if (eggParent) { - // must be part of a group that is not a joint - ikj.create(eggParent->_group); - } else { - ikj.create(); - } - } - ikj.set(mtm); - - _joint = ikj.object(); - ikj.getPath(_joint_dag_path); -} - - -// MayaEggGeom : base abstract class of MayaEggMesh and MayaEggNurbsSurface - -typedef std::pair MayaEggWeight; - -struct MayaEggVertex -{ - LVertexd _pos; - LNormald _normal; - LTexCoordd _uv; - vector _weights; - double _sumWeights; // [gjeon] to be used in normalizing weights - int _index; - int _external_index; // masad: use egg's index directly -}; - -struct MEV_Compare: public stl_hash_compare -{ - size_t operator()(const MayaEggVertex &key) const - { - return key._pos.add_hash(key._normal.get_hash()); - } - bool operator()(const MayaEggVertex &k1, const MayaEggVertex &k2) const - { - int n = k1._pos.compare_to(k2._pos); - if (n < 0) { - return true; - } - if (n > 0) { - return false; - } - n = k1._normal.compare_to(k2._normal); - if (n < 0) { - return true; - } - if (n > 0) { - return false; - } - n = k1._uv.compare_to(k2._uv); - if (n < 0) { - return true; - } - if (n > 0) { - return false; - } - n = k1._weights.size() - k2._weights.size(); - if (n < 0) { - return true; - } - if (n > 0) { - return false; - } - for (unsigned int i=0; i 0) { - return false; - } - EggGroup *g1 = k1._weights[i].second; - EggGroup *g2 = k2._weights[i].second; - if (g1 < g2) { - return true; - } - if (g1 > g2) { - return false; - } - } - n = k1._external_index - k2._external_index; - - if (n < 0) { - return true; - } - if (n > 0) { - return false; - } - - return false; - } -}; - -typedef phash_set VertTable; - -class MayaEggGeom -{ -public: - - EggVertexPool *_pool; - MObject _transNode; - MObject _shapeNode; - EggGroup *_parent; - MDagPath _shape_dag_path; - int _vert_count; - - string _name; - - MFloatPointArray _vertexArray; - MVectorArray _normalArray; - MColorArray _vertColorArray; - MIntArray _vertColorIndices; - MIntArray _vertNormalIndices; - - MStringArray _eggObjectTypes; - VertTable _vert_tab; - - bool _renameTrans; - - int GetVert(EggVertex *vert, EggGroup *context); - EggGroup *GetControlJoint(void); - - virtual void ConnectTextures(void) = 0; - void AssignNames(void); - void AddEggFlag(MString); -}; - -// [gjeon] moved from MayaEggMesh to MayaEggGeom -int MayaEggGeom::GetVert(EggVertex *vert, EggGroup *context) -{ - MayaEggVertex vtx; - vtx._sumWeights = 0.0; - - const LMatrix4d &xform = context->get_vertex_to_node(); - - vtx._pos = vert->get_pos3() * xform; - if (vert->has_normal()) { - vtx._normal = vert->get_normal() * xform; - } - if (vert->has_uv()) { - vtx._uv = vert->get_uv(); - } - vtx._index = 0; - vtx._external_index = vert->get_index()-1; - - EggVertex::GroupRef::const_iterator gri; - // double remaining_weight = 1.0; - for (gri = vert->gref_begin(); gri != vert->gref_end(); ++gri) { - EggGroup *egg_joint = (*gri); - double membership = egg_joint->get_vertex_membership(vert); - - if (membership < 0) - { - mayaloader_cat.warning() << "negative weight value " << membership << " is replaced with 0 on: " << context->get_name() << endl; - membership = 0.0; - } - // remaining_weight -= membership; - vtx._weights.push_back(MayaEggWeight(membership, egg_joint)); - vtx._sumWeights += membership; // [gjeon] to be used in normalizing weights - } - - if (vtx._weights.size()==0) { - if (context != 0) { - vtx._weights.push_back(MayaEggWeight(1.0, context)); - vtx._sumWeights = 1.0; // [gjeon] to be used in normalizing weights - } - // remaining_weight = 0.0; - }/* else { - // some soft models came up short of 1.0 on vertex membership add the - // remainder of the weight on first joint in the membership - if ((remaining_weight) > 0.01) { - gri = vert->gref_begin(); - EggGroup *egg_joint = (*gri); - double membership = egg_joint->get_vertex_membership(vert); - vtx._weights.push_back(MayaEggWeight(membership+remaining_weight, egg_joint)); - vtx._sumWeights += (membership + remaining_weight); - } - }*/ //[gjeon] we had better nomarlize weights than add remaining weight to first weight - - VertTable::const_iterator vti = _vert_tab.find(vtx); - if (vti != _vert_tab.end()) { - /* if ((remaining_weight) > 0.01) { - mayaloader_cat.warning() << "weight munged to 1.0 by " << remaining_weight << " on: " << context->get_name() << " idx:" << vti->_index << endl; - } */ - if (mayaloader_cat.is_spam()) { - ostringstream stream; - stream << "(" << vti->_pos << " " << vti->_normal << " " << vti->_uv << ")\n"; - stream << "[" << vtx._pos << " " << vtx._normal << " " << vtx._uv << "]\n"; - stream << "{" << vert->get_pos3() << " "; - if (vert->has_normal()) { - stream << vert->get_normal() << " "; - } - if (vert->has_uv()) { - stream << vert->get_uv(); - } - stream << "}"; - mayaloader_cat.spam() << "found a matching vertex: " << *vert << endl << stream.str() << endl; - } - return vti->_index; - } - - // _vert_count++; - vtx._index = _vert_count++; - /* - if ((remaining_weight) > 0.01) { - mayaloader_cat.warning() << "weight munged to 1.0 by " << remaining_weight << " on: " << context->get_name() << " idx:" << vtx._index << endl; - } */ - - _vertexArray.append(MakeMayaPoint(vtx._pos)); - if (vert->has_normal()) { - _normalArray.append(MakeMayaVector(vtx._normal)); - _vertNormalIndices.append(vtx._index); - } - if (vert->has_color()) { - if (mayaloader_cat.is_spam()) { - mayaloader_cat.spam() << "found a vertex color\n"; - } - _vertColorArray.append(MakeMayaColor(vert->get_color())); - _vertColorIndices.append(vtx._index); - } - _vert_tab.insert(vtx); - return vtx._index; -} - -// [gjeon] moved from MayaEggMesh to MayaEggGeom -void MayaEggGeom::AssignNames(void) -{ - string name = _pool->get_name(); - size_t nsize = name.size(); - if (nsize > 6 && name.rfind(".verts") == (nsize - 6)) { - name.resize(nsize - 6); - } - if (nsize > 4 && name.rfind(".cvs") == (nsize - 4)) { - name.resize(nsize - 4); - } - - MFnDependencyNode dnshape(_shapeNode); - MFnDependencyNode dntrans(_transNode); - - if (_renameTrans) { - dntrans.setName(MString(name.c_str())); - } - - string shape_name = string(dntrans.name().asChar()); - string numbers ("0123456789"); - size_t found; - - found=shape_name.find_last_not_of(numbers); - if (found!=string::npos) - shape_name.insert(found+1, "Shape"); - else - shape_name.append("Shape"); - - dnshape.setName(MString(shape_name.c_str())); -} - -#define CTRLJOINT_DEFORM ((EggGroup*)((char*)(-1))) - -// [gjeon] moved from MayaEggMesh to MayaEggGeom -EggGroup *MayaEggGeom::GetControlJoint(void) -{ - EggGroup *result; - VertTable::const_iterator vert = _vert_tab.begin(); - if (vert == _vert_tab.end()) { - return 0; - } - switch (vert->_weights.size()) { - case 0: - for (++vert; vert != _vert_tab.end(); ++vert) { - if (vert->_weights.size() != 0) { - return CTRLJOINT_DEFORM; - } - } - return 0; - case 1: - result = vert->_weights[0].second; - for (++vert; vert != _vert_tab.end(); ++vert) { - if ((vert->_weights.size() != 1) || (vert->_weights[0].second != result)) { - return CTRLJOINT_DEFORM; - } - } - return result; - default: - return CTRLJOINT_DEFORM; - } -} - -void MayaEggGeom::AddEggFlag(MString fieldName) { - bool addNewFlag = true; - for (unsigned i = 0; i < _eggObjectTypes.length(); i++) { - if (_eggObjectTypes[i] == fieldName) { - addNewFlag = false; - break; - } - } - if (addNewFlag) { - _eggObjectTypes.append(fieldName); - } -} - -// MayaEggMesh -typedef phash_map TVertTable; -typedef phash_map CVertTable; - -class MayaEggMesh final : public MayaEggGeom -{ -public: - MColorArray _faceColorArray; - MIntArray _faceIndices; - MIntArray _polygonCounts; - MIntArray _polygonConnects; - MFloatArray _uarray; - MFloatArray _varray; - MIntArray _uvIds; - - - int _tvert_count; - int _cvert_count; - int _face_count; - vector _face_tex; - - TVertTable _tvert_tab; - CVertTable _cvert_tab; - - int GetTVert(const LTexCoordd &uv); - int GetCVert(const LColor &col); - int AddFace(unsigned numVertices, MIntArray mvertIndices, MIntArray mtvertIndices, MayaEggTex *tex); - - void ConnectTextures(void) override; -}; - -int MayaEggMesh::GetTVert(const LTexCoordd &uv) -{ - if (_tvert_tab.count(uv)) { - if (mayaloader_cat.is_spam()) { - mayaloader_cat.spam() << "found uv coords idx: " << _tvert_tab[uv] << endl; - } - return _tvert_tab[uv]; - } - int idx = _tvert_count++; - _uarray.append(uv.get_x()); - _varray.append(uv.get_y()); - _tvert_tab[uv] = idx; - if (mayaloader_cat.is_spam()) { - mayaloader_cat.spam() << "adding uv coords idx:" << idx << endl; - } - return idx; -} - -int MayaEggMesh::GetCVert(const LColor &col) -{ -/* - * if (_cvert_tab.count(col)) return _cvert_tab[col]; if (_cvert_count == - * _mesh->numCVerts) { int nsize = _cvert_count*2 + 100; - * _mesh->setNumVertCol(nsize, _cvert_count?TRUE:FALSE); } int idx = - * _cvert_count++; _mesh->vertCol[idx] = Point3(col.get_x(), col.get_y(), - * col.get_z()); _cvert_tab[col] = idx; return idx; - */ - return 0; -} - -MayaEggMesh *MayaEggLoader::GetMesh(EggVertexPool *pool, EggGroup *parent) -{ - MayaEggMesh *result = _mesh_tab[parent]; - if (result == 0) { - result = new MayaEggMesh; - if (parent != nullptr) { - result->_name = parent->get_name(); - } - result->_pool = pool; - result->_parent = parent; - result->_vert_count = 0; - result->_tvert_count = 0; - result->_cvert_count = 0; - result->_face_count = 0; - result->_vertColorArray.clear(); - result->_vertNormalIndices.clear(); - result->_vertColorIndices.clear(); - result->_faceColorArray.clear(); - result->_faceIndices.clear(); - result->_eggObjectTypes.clear(); - result->_renameTrans = false; - _mesh_tab[parent] = result; - } - return result; -} - -int MayaEggMesh::AddFace(unsigned numVertices, MIntArray mvertIndices, MIntArray mtvertIndices, MayaEggTex *tex) -{ - int idx = _face_count++; - _polygonCounts.append(numVertices); - for (unsigned i = 0; i < mvertIndices.length(); i++) - { - _polygonConnects.append(mvertIndices[i]); - _uvIds.append(mtvertIndices[i]); - } - _face_tex.push_back(tex); - return idx; -} - -void MayaEggMesh::ConnectTextures(void) -{ - bool subtex = false; - for (int i=1; i<_face_count; i++) { - if (_face_tex[i] != _face_tex[0]) { - subtex = true; - } - } - if (!subtex) { - MFnSet sg(_face_tex[0]->_shading_group); - sg.addMember(_shapeNode); - return; - } - for (int i=0; i<_face_count; i++) { - MayaEggTex *tex = _face_tex[i]; - if (tex->_component.object()==MObject::kNullObj) { - tex->_component.create(MFn::kMeshPolygonComponent); - } - tex->_component.addElement(i); - } - for (int i=0; i<_face_count; i++) { - MayaEggTex *tex = _face_tex[i]; - if (tex->_component.object()!=MObject::kNullObj) { - MFnSet sg(tex->_shading_group); - sg.addMember(_shape_dag_path, tex->_component.object()); - tex->_component.setObject(MObject::kNullObj); - } - } -} - - -// MayaEggNurbsSurface -class MayaEggNurbsSurface : public MayaEggGeom -{ -public: - - - MPointArray _cvArray; - MDoubleArray _uKnotArray; - MDoubleArray _vKnotArray; - unsigned _uDegree; - unsigned _vDegree; - unsigned _uNumCvs; - unsigned _vNumCvs; - - MFnNurbsSurface::Form _uForm; - MFnNurbsSurface::Form _vForm; - - MayaEggTex *_tex; - - void ConnectTextures(void); - void PrintData(void); -}; - -MayaEggNurbsSurface *MayaEggLoader::GetSurface(EggVertexPool *pool, EggGroup *parent) -{ - MayaEggNurbsSurface *result = _surface_tab[parent]; - if (result == 0) { - result = new MayaEggNurbsSurface; - result->_pool = pool; - result->_parent = parent; - result->_name = parent->get_name(); - - result->_vert_count = 0; - result->_vertColorArray.clear(); - result->_vertNormalIndices.clear(); - result->_vertColorIndices.clear(); - - result->_cvArray.clear(); - result->_uKnotArray.clear(); - result->_vKnotArray.clear(); - - result->_uDegree = 0; - result->_vDegree = 0; - result->_uNumCvs = 0; - result->_vNumCvs = 0; - result->_uForm = MFnNurbsSurface::kClosed; - result->_vForm = MFnNurbsSurface::kClosed; - - result->_eggObjectTypes.clear(); - result->_renameTrans = false; - _surface_tab[parent] = result; - } - return result; -} - -void MayaEggNurbsSurface::ConnectTextures(void) -{ - // masad: since nurbs surfaces do not support vertex colors I am infusing - // the surface's first vertex color (if any) into the shader to achive the - // color. masad: check if there is any vertex color for this surface - MStatus status; - MColor firstColor(0.5,0.5,0.5,1.0); - if (_vertColorArray.length() > 0) { - firstColor = _vertColorArray[0]; - MFnLambertShader sh(_tex->_shader); - status = sh.setColor(firstColor); - if (status != MStatus::kSuccess) { - mayaloader_cat.error() << "setColor failed on " << _name; - status.perror("shader setColor failed!"); - } - } - MFnSet sg(_tex->_shading_group); - status = sg.addMember(_shapeNode); - if (status != MStatus::kSuccess) { - mayaloader_cat.error() << "addMember failed on " << _name; - status.perror("shader addMember failed!"); - } - return; -} - -void MayaEggNurbsSurface::PrintData(void) -{ - if (mayaloader_cat.is_debug()) { - mayaloader_cat.debug() << "nurbsSurface : " << _name << endl; - - mayaloader_cat.debug() << "u_form : " << _uForm << endl; - mayaloader_cat.debug() << "v_form : " << _vForm << endl; - } - - /* - for (unsigned i = 0; i < _cvArray.length(); i++) - { - MPoint cv =_cvArray[i]; - mayaloader_cat.debug() << cv[0] << " " << cv[1] << " " << cv[2] << endl; - } - - for (unsigned i = 0; i < _uKnotArray.length(); i++) - { - mayaloader_cat.debug() << _uKnotArray[i] << endl; - } - - for (unsigned i = 0; i < _vKnotArray.length(); i++) - { - mayaloader_cat.debug() << _vKnotArray[i] << endl; - } - */ -} - -// MayaAnim: -class MayaAnim -{ -public: - string _name; - EggTable *_joint; - EggXfmSAnim *_pool; - void PrintData(void); -}; - -MayaAnim *MayaEggLoader::GetAnim(EggXfmSAnim *pool) -{ - MayaAnim *result = _anim_tab[pool]; - if (result == 0) { - result = new MayaAnim; - result->_pool = pool; - result->_name = pool->get_name(); - _anim_tab[pool] = result; - EggNode *jointNode = (DCAST(EggNode, pool))->get_parent(); - EggTable *joint = DCAST(EggTable, jointNode); - result->_joint = joint; - - } - return result; -} - -void MayaAnim::PrintData(void) -{ - if (mayaloader_cat.is_debug()) { - mayaloader_cat.debug() << "anim on joint : " << _joint->get_name() << endl; - } - _pool->write(mayaloader_cat.debug(), 0); -} - -// MayaEggLoader functions - -void MayaEggLoader::CreateSkinCluster(MayaEggGeom *M) -{ - MString cmd("skinCluster -mi "); - vector joints; - - VertTable::const_iterator vert; - int maxInfluences = 0; - for (vert=M->_vert_tab.begin(); vert != M->_vert_tab.end(); ++vert) { - if ((int)(vert->_weights.size()) > maxInfluences) { - maxInfluences = vert->_weights.size(); - } - for (unsigned int i=0; i_weights.size(); i++) { - MayaEggJoint *joint = FindJoint(vert->_weights[i].second); - if (joint && !joint->_inskin) { - joint->_inskin = true; - joint->_index = joints.size(); - joints.push_back(joint); - /* - if (mayaloader_cat.is_spam()) { - mayaloader_cat.spam() << joints[i]->_egg_joint->get_name() << ": adding to skin\n"; - } - */ - } - } - } - cmd += maxInfluences; - - /* - if (mayaloader_cat.is_spam()) { - mayaloader_cat.spam() << joints.size() << " joints have weights on " << M->_pool->get_name() << endl; - } - */ - if (joints.size() == 0) { - // no need to cluster; there are no weights - return; - } - - for (unsigned int i=0; i_joint); - cmd = cmd + " "; - cmd = cmd + joint.name(); - } - - MFnDependencyNode shape(M->_shapeNode); - cmd = cmd + " "; - cmd = cmd + shape.name(); - - MStatus status; - MDGModifier dgmod; - if (mayaloader_cat.is_spam()) { - mayaloader_cat.spam() << cmd.asChar() << endl; - string spamCmd = M->_pool->get_name(); - for (unsigned int i=0; i_egg_joint->get_name(); - } - mayaloader_cat.spam() << spamCmd << ": total = " << joints.size() << endl; - } - status = dgmod.commandToExecute(cmd); - if (status != MStatus::kSuccess) { - perror("skinCluster commandToExecute"); - return; - } - status = dgmod.doIt(); - if (status != MStatus::kSuccess) { - perror("skinCluster doIt"); - return; - } - - MPlugArray oldplugs; - MPlug inPlug; - if (shape.typeName() == "mesh") { - inPlug = shape.findPlug("inMesh"); - } else if (shape.typeName() == "nurbsSurface") { - inPlug = shape.findPlug("create"); - } else { - // we only support mesh and nurbsSurface - return; - } - - if ((!inPlug.connectedTo(oldplugs,true,false))||(oldplugs.length() != 1)) { - cerr << "skinCluster command failed"; - return; - } - MFnSkinCluster skinCluster(oldplugs[0].node()); - MIntArray influenceIndices; - MFnSingleIndexedComponent component; - component.create(MFn::kMeshVertComponent); // [gjeon] Interestingly, we can use MFn::kMeshVertComponent for NURBS surface, too - component.setCompleteData(M->_vert_count); - for (unsigned int i=0; i_joint_dag_path, &status); - if (status != MStatus::kSuccess) { - perror("skinCluster index"); - return; - } - influenceIndices.append((int)index); - } - - MDagPathArray paths; - unsigned infcount = skinCluster.influenceObjects(paths, &status); - if (status != MStatus::kSuccess) { - perror("influenceObjects"); - return; - } - for (unsigned int i=0; i_shape_dag_path, component.object(), index, 0.0, false, nullptr); - } - - MFloatArray values; - int tot = M->_vert_count * joints.size(); - values.setLength(tot); - for (int i=0; i_vert_tab.begin(); vert != M->_vert_tab.end(); ++vert) { - for (unsigned int i=0; i_weights.size(); i++) { - double strength = vert->_weights[i].first / vert->_sumWeights; // [gjeon] nomalizing weights - MayaEggJoint *joint = FindJoint(vert->_weights[i].second); - values[vert->_index * joints.size() + joint->_index] = (PN_stdfloat)strength; - } - } - skinCluster.setWeights(M->_shape_dag_path, component.object(), influenceIndices, values, false, nullptr); - - for (unsigned int i=0; i_egg_joint->get_name() << ": clearing skin\n"; - } - */ - joints[i]->_inskin = false; - joints[i]->_index = -1; - } -} - -// TraverseEggData We have an EggData in memory, and now we're going to copy -// that over into the maya scene graph. - -void MayaEggLoader::TraverseEggNode(EggNode *node, EggGroup *context, string delim) -{ - vector vertIndices; - vector tvertIndices; - vector cvertIndices; - - string delstring = " "; - - if (node->is_of_type(EggPolygon::get_class_type())) { - /* - if (mayaloader_cat.is_debug()) { - mayaloader_cat.debug() << delim+delstring << "found an EggMesh: " << node->get_name() << endl; - } - */ - EggPolygon *poly = DCAST(EggPolygon, node); - if (poly->empty()) { - return; - } - poly->cleanup(); - - MayaEggTex *tex = 0; - LMatrix3d uvtrans = LMatrix3d::ident_mat(); - - if (poly->has_texture()) { - EggTexture *etex = poly->get_texture(0); - if (mayaloader_cat.is_spam()) { - mayaloader_cat.spam() << "Texture format : " << etex->get_format() << endl; - } - tex = GetTex(etex); - if (etex->has_transform()) - uvtrans = etex->get_transform2d(); - } else { - tex = GetTex(nullptr); - } - - EggPolygon::const_iterator ci; - MayaEggMesh *mesh = GetMesh(poly->get_pool(), context); - if (mayaloader_cat.is_spam()) { - mayaloader_cat.spam() << "traverse mesh pointer " << mesh << "\n"; - } - vertIndices.clear(); - tvertIndices.clear(); - cvertIndices.clear(); - int numVertices = 0; - for (ci = poly->begin(); ci != poly->end(); ++ci) { - EggVertex *vtx = (*ci); - LTexCoordd uv(0,0); - if (vtx->has_uv()) { - uv = vtx->get_uv(); - } - vertIndices.push_back(mesh->GetVert(vtx, context)); - tvertIndices.push_back(mesh->GetTVert(uv * uvtrans)); - cvertIndices.push_back(mesh->GetCVert(vtx->get_color())); - numVertices++; - } - if (mayaloader_cat.is_spam()) { - mayaloader_cat.spam() << "num vertices: " << vertIndices.size() << "\n"; - } - - if (numVertices < 3) - return; - - MIntArray mvertIndices; - MIntArray mtvertIndices; - for (int i = 0; i < numVertices; i++) { - mvertIndices.append(vertIndices[i]); - mtvertIndices.append(tvertIndices[i]); - } - if (poly->has_color()) { - if (mayaloader_cat.is_spam()) { - mayaloader_cat.spam() << "found a face color of " << poly->get_color() << endl; - } - mesh->_faceIndices.append(mesh->_face_count); - mesh->_faceColorArray.append(MakeMayaColor(poly->get_color())); - } - mesh->AddFace(numVertices, mvertIndices, mtvertIndices, tex); - - // [gjeon] to handle double-sided flag - if (poly->get_bface_flag()) { - mesh->AddEggFlag("double-sided"); - } - - // [gjeon] to handle model flag - if (context->get_model_flag()) { - mesh->AddEggFlag("model"); - } - - // [gjeon] to handle billboard flag - switch (context->get_billboard_type()) { - case EggGroup::BT_axis: - mesh->AddEggFlag("billboard"); - break; - - case EggGroup::BT_point_camera_relative: - mesh->AddEggFlag("billboard-point"); - break; - - default: - ; - } - - // [gjeon] to handle other flags - for (int i = 0; i < context->get_num_object_types(); i++) { - mesh->AddEggFlag(MString(context->get_object_type(i).c_str())); - } - - } else if (node->is_of_type(EggNurbsSurface::get_class_type())) { - // [gjeon] to convert nurbsSurface - EggNurbsSurface *eggNurbsSurface = DCAST(EggNurbsSurface, node); - - EggNurbsSurface::const_iterator ci; - EggVertexPool *pool = eggNurbsSurface->get_pool(); - MayaEggNurbsSurface *surface = GetSurface(pool, context); - - for (ci = eggNurbsSurface->begin(); ci != eggNurbsSurface->end(); ++ci) { - EggVertex *vtx = (*ci); - surface->GetVert(vtx, context); - } - - // [gjeon] finding textures - MayaEggTex *tex = 0; - LMatrix3d uvtrans = LMatrix3d::ident_mat(); - - if (eggNurbsSurface->has_texture()) { - EggTexture *etex = eggNurbsSurface->get_texture(0); - tex = GetTex(etex); - if (etex->has_transform()) - { - mayaloader_cat.debug() << "uvtrans?" << endl; - uvtrans = etex->get_transform2d(); - } - } else { - tex = GetTex(nullptr); - } - - surface->_tex = tex; - surface->_uNumCvs = eggNurbsSurface->get_num_u_cvs(); - surface->_vNumCvs = eggNurbsSurface->get_num_v_cvs(); - - // [gjeon] building cvArray - for (unsigned int ui = 0; ui < surface->_uNumCvs; ui++) { - for (unsigned int vi = 0; vi < surface->_vNumCvs; vi++) { - EggVertex *vtx = eggNurbsSurface->get_vertex(eggNurbsSurface->get_vertex_index(ui, vi)); - surface->_cvArray.append(MakeMPoint(vtx->get_pos3())); - } - } - - // [gjeon] building u knotArray - for (int i = 1; i < eggNurbsSurface->get_num_u_knots()-1; i++) { - surface->_uKnotArray.append(eggNurbsSurface->get_u_knot(i)); - } - - // [gjeon] building v knotArray - for (int i = 1; i < eggNurbsSurface->get_num_v_knots()-1; i++) { - surface->_vKnotArray.append(eggNurbsSurface->get_v_knot(i)); - } - - surface->_uDegree = eggNurbsSurface->get_u_degree(); - surface->_vDegree = eggNurbsSurface->get_v_degree(); - - if (eggNurbsSurface->is_closed_u()) { - surface->_uForm = MFnNurbsSurface::kClosed; - } else { - surface->_vForm = MFnNurbsSurface::kOpen; - } - - if (eggNurbsSurface->is_closed_v()) { - surface->_vForm = MFnNurbsSurface::kClosed; - } else { - surface->_vForm = MFnNurbsSurface::kOpen; - } - - // [gjeon] to handle double-sided flag - if (eggNurbsSurface->get_bface_flag()) { - surface->AddEggFlag("double-sided"); - } - - // [gjeon] to handle model flag - if (context->get_model_flag()) { - surface->AddEggFlag("model"); - } - - // [gjeon] to handle other flags - for (int i = 0; i < context->get_num_object_types(); i++) { - surface->AddEggFlag(MString(context->get_object_type(i).c_str())); - } - - } else if (node->is_of_type(EggComment::get_class_type())) { - string comment = (DCAST(EggComment, node))->get_comment(); - if (comment.find("2egg") != string::npos) { - if (mayaloader_cat.is_spam()) { - mayaloader_cat.spam() << delim+delstring << "found an EggComment: " << comment << endl; - } - if (comment.find("chan") != string::npos) { - ParseFrameInfo(comment); - } - } - } else if (node->is_of_type(EggSAnimData::get_class_type())) { - if (mayaloader_cat.is_debug()) { - mayaloader_cat.debug() << delim+delstring << "found an EggSAnimData: " << node->get_name() << endl; - } - // EggSAnimData *anim = DCAST(EggSAnimData, node); MayaAnimData *animData - // = GetAnimData(anim, DCAST(EggXfmSAnim, node->get_parent())); - // animData->PrintData(); if (_end_frame < - // animData->_pool->get_num_rows()) { _end_frame = - // animData->_pool->get_num_rows(); } - } else if (node->is_of_type(EggGroupNode::get_class_type())) { - EggGroupNode *group = DCAST(EggGroupNode, node); - if (node->is_of_type(EggGroup::get_class_type())) { - EggGroup *group = DCAST(EggGroup, node); - - if (group->get_name() == "") { - ostringstream stream; - stream << _unnamed_idx; - group->set_name("unnamed" + stream.str()); - _unnamed_idx++; - } - - string group_name = group->get_name(); - size_t found = group_name.find(":"); - if (found != string::npos) - group->set_name(group_name.replace(int(found), 1, "_")); - - string parent_name = ""; - if (context) - parent_name = context->get_name(); - if (group->is_joint()) { - if (mayaloader_cat.is_debug()) { - mayaloader_cat.debug() << delim+delstring << group->get_name() << ":" << parent_name << endl; - } - MakeJoint(group, context); - context = group; - } else { - // lets create a group node for it so that it is reflected in Maya - if (mayaloader_cat.is_debug()) { - mayaloader_cat.debug() << delim+delstring << group->get_name() << "@" << parent_name << endl; - } - MakeGroup(group, context); - context = group; - } - } else if (node->is_of_type(EggTable::get_class_type())) { - // EggTable *anim = DCAST(EggTable, node); - if (mayaloader_cat.is_debug()) { - mayaloader_cat.debug() << delim+delstring << "found an EggTable: " << node->get_name() << endl; - } - } else if (node->is_of_type(EggXfmSAnim::get_class_type())) { - // Create a MayaAnim equivalent of the EggXfmSAnim - GetAnim(DCAST(EggXfmSAnim, node)); - //anim->PrintData(); - if (mayaloader_cat.is_debug()) { - mayaloader_cat.debug() << delim+delstring << "found an EggXfmSAnim: " << node->get_name() << endl; - } - } - - EggGroupNode::const_iterator ci; - for (ci = group->begin(); ci != group->end(); ++ci) { - TraverseEggNode(*ci, context, delim+delstring); - } - } -} - -bool MayaEggLoader::ConvertEggData(EggData *data, bool merge, bool model, bool anim, bool respect_normals) -{ - if (!merge) { - mayaloader_cat.error() << "Currently, only 'merge' mode is implemented.\n"; - return false; - } - - /* - if ((anim) || (!model)) { - mayaloader_cat.error() << "Currently, only model-loading is implemented.\n"; - return false; - } - */ - - _start_frame = 0; - _end_frame = 0; - _frame_rate = 24; - _timeUnit = MTime::kFilm; - _unnamed_idx = 1; - - MeshTable::const_iterator ci; - JointTable::const_iterator ji; - TexTable::const_iterator ti; - SurfaceTable::const_iterator si; - AnimTable::const_iterator ei; - - if (MGlobal::isYAxisUp()) { - data->set_coordinate_system(CS_yup_right); - } else { - data->set_coordinate_system(CS_zup_right); - } - - if (mayaloader_cat.is_debug()) { - mayaloader_cat.debug() << "root node: " << data->get_type() << endl; - } - TraverseEggNode(data, nullptr, ""); - - MStatus status; - - MFnSet collision_set; - collision_set.create(_collision_nodes, MFnSet::kNone, &status); - - if (mayaloader_cat.is_spam()) { - mayaloader_cat.spam() << "num meshes : " << _mesh_tab.size() << endl; - } - for (ci = _mesh_tab.begin(); ci != _mesh_tab.end(); ++ci) { - MayaEggMesh *mesh = (*ci).second; - if (mesh->_face_count==0) { - continue; - } - - // MStatus status; - MFnMesh mfn; - MString cset; - - MayaEggGroup *parentNode = FindGroup(mesh->_parent); - MObject parent = MObject::kNullObj; - if (parentNode) { - parent = parentNode->_group; - if (mayaloader_cat.is_debug()) { - mayaloader_cat.debug() << "mesh's parent (group) : " << parentNode->_name << endl; - } - } else { - mesh->_renameTrans = true; - if (mayaloader_cat.is_debug()) { - mayaloader_cat.debug() << "mesh's parent (null) : " << endl; - } - } - if (mayaloader_cat.is_spam()) { - mayaloader_cat.spam() << "mesh pointer : " << mesh << " and parent_pointer: " << &parent << endl; - mayaloader_cat.spam() << "mesh vert_count : " << mesh->_vert_count << endl; - mayaloader_cat.spam() << "mesh face_count : " << mesh->_face_count << endl; - mayaloader_cat.spam() << "mesh vertexArray size: " << mesh->_vertexArray.length() << endl; - mayaloader_cat.spam() << "mesh polygonCounts size: " << mesh->_polygonCounts.length() << endl; - mayaloader_cat.spam() << "mesh polygonConnects size: " << mesh->_polygonConnects.length() << endl; - mayaloader_cat.spam() << "mesh uarray size: " << mesh->_uarray.length() << endl; - mayaloader_cat.spam() << "mesh varray size: " << mesh->_varray.length() << endl; - } - mesh->_transNode = mfn.create(mesh->_vert_count, mesh->_face_count, - mesh->_vertexArray, mesh->_polygonCounts, mesh->_polygonConnects, - mesh->_uarray, mesh->_varray, - parent, &status); - if (mayaloader_cat.is_spam()) { - mayaloader_cat.spam() << "transNode created." << endl; - } - - if (!mesh->_renameTrans) { - mesh->_transNode = parent; - } - - // [gjeon] add eggFlag attributes if any exists - for (unsigned i = 0; i < mesh->_eggObjectTypes.length(); i++) { - MString attrName = "eggObjectTypes"; - attrName += (int)(i + 1); - status = create_enum_attribute(mesh->_transNode, attrName, attrName, mesh->_eggObjectTypes, i); - if (status != MStatus::kSuccess) { - status.perror("create_enum_attribute failed!"); - } - } - - // Check the "Display Colors" box by default, so that vertex colors (if - // any) will be visible. - MPlug displayColors = mfn.findPlug("displayColors"); - displayColors.setValue((bool)true); - - mesh->_shapeNode = mfn.object(); - mfn.getPath(mesh->_shape_dag_path); - mesh->ConnectTextures(); - - if (mayaloader_cat.is_spam()) { - mayaloader_cat.spam() << "textures connected." << endl; - } - - mfn.getCurrentUVSetName(cset); - status = mfn.assignUVs(mesh->_polygonCounts, mesh->_uvIds, &cset); - - if (status != MStatus::kSuccess) { - status.perror("assignUVs failed"); - if (mayaloader_cat.is_spam()) { - PrintData(mesh); - } - } - else { - if (mayaloader_cat.is_spam()) { - mayaloader_cat.spam() << "uvs assigned." << endl; - } - } - - // lets try to set normals per vertex - if (respect_normals) { - status = mfn.setVertexNormals(mesh->_normalArray, mesh->_vertNormalIndices, MSpace::kTransform); - if (status != MStatus::kSuccess) { - status.perror("setVertexNormals failed!"); - } - } - - if (mayaloader_cat.is_spam()) { - mayaloader_cat.spam() << "vertex normals set." << endl; - } - - // lets try to set colors per vertex - /* - MDGModifier dgmod; - status = dgmod.doIt(); - if (status != MStatus::kSuccess) { - status.perror("setVertexColors doIt"); - } - status = mfn.setVertexColors(mesh->_vertColorArray, mesh->_vertColorIndices, &dgmod); - */ - status = mfn.setVertexColors(mesh->_vertColorArray, mesh->_vertColorIndices); - if (status != MStatus::kSuccess) { - status.perror("setVertexColors failed!"); - } - status = mfn.setFaceColors(mesh->_faceColorArray, mesh->_faceIndices); - /* - if (status != MStatus::kSuccess) { - status.perror("setFaceColors failed!"); - } - */ - } - - for (si = _surface_tab.begin(); si != _surface_tab.end(); ++si) { - MayaEggNurbsSurface *surface = (*si).second; - if (surface->_cvArray.length()==0) { - continue; - } - - // MStatus status; - MFnNurbsSurface mfnNurbsSurface; - - MayaEggGroup *parentNode = FindGroup(surface->_parent); - MObject parent = MObject::kNullObj; - if (parentNode) { - parent = parentNode->_group; - if (mayaloader_cat.is_debug()) { - mayaloader_cat.debug() << "surface's parent (group) : " << parentNode->_name << endl; - } - } else { - surface->_renameTrans = true; - if (mayaloader_cat.is_debug()) { - mayaloader_cat.debug() << "surface's parent (null) : " << endl; - } - } - - surface->_transNode = mfnNurbsSurface.create(surface->_cvArray, surface->_uKnotArray, surface->_vKnotArray, - surface->_uDegree, surface->_vDegree, surface->_uForm, surface->_vForm, - true, parent, &status); - - if (!surface->_renameTrans) { - surface->_transNode = parent; - } - - // [gjeon] add eggFlag attributes if any exists - for (unsigned i = 0; i < surface->_eggObjectTypes.length(); i++) { - MString attrName = "eggObjectTypes"; - attrName += (int)(i + 1); - status = create_enum_attribute(surface->_transNode, attrName, attrName, surface->_eggObjectTypes, i); - if (status != MStatus::kSuccess) { - status.perror("create_enum_attribute failed!"); - } - } - surface->_shapeNode = mfnNurbsSurface.object(); - mfnNurbsSurface.getPath(surface->_shape_dag_path); - surface->ConnectTextures(); - - mayaloader_cat.debug() << status.errorString().asChar() << endl; - } - - - double thickness = 0.0; - for (ji = _joint_tab.begin(); ji != _joint_tab.end(); ++ji) { - MayaEggJoint *joint = (*ji).second; - double dfo = (joint->GetPos()).length(); - if (dfo > thickness) { - thickness = dfo; - } - } - if (mayaloader_cat.is_spam()) { - mayaloader_cat.spam() << "thickness from joints: " << thickness << endl; - } - thickness = thickness * 0.025; - for (unsigned int i=0; i<_joint_list.size(); i++) { - MayaEggJoint *joint = _joint_list[i]; - if (mayaloader_cat.is_spam()) { - mayaloader_cat.spam() << "creating a joint: " << joint->_egg_joint->get_name() << endl; - } - joint->ChooseEndPos(thickness); - joint->CreateMayaBone(FindGroup(joint->_egg_parent)); - } - if (mayaloader_cat.is_spam()) { - mayaloader_cat.spam() << "went past all the joints" << endl; - } - for (ci = _mesh_tab.begin(); ci != _mesh_tab.end(); ++ci) { - MayaEggMesh *mesh = (*ci).second; - EggGroup *joint = mesh->GetControlJoint(); - if (joint) { - CreateSkinCluster(mesh); - } - } - for (si = _surface_tab.begin(); si != _surface_tab.end(); ++si) { - MayaEggNurbsSurface *surface = (*si).second; - EggGroup *joint = surface->GetControlJoint(); - if (joint) { - CreateSkinCluster(surface); - } - } - if (mayaloader_cat.is_spam()) { - mayaloader_cat.spam() << "went past creating skin cluster" << endl; - } - for (ci = _mesh_tab.begin(); ci != _mesh_tab.end(); ++ci) { - (*ci).second->AssignNames(); - } - for (si = _surface_tab.begin(); si != _surface_tab.end(); ++si) { - (*si).second->AssignNames(); - } - if (mayaloader_cat.is_spam()) { - mayaloader_cat.spam() << "went past mesh AssignNames" << endl; - } - for (ji = _joint_tab.begin(); ji != _joint_tab.end(); ++ji) { - (*ji).second->AssignNames(); - } - if (mayaloader_cat.is_spam()) { - mayaloader_cat.spam() << "went past joint AssignNames" << endl; - } - for (ti = _tex_tab.begin(); ti != _tex_tab.end(); ++ti) { - (*ti).second->AssignNames(); - } - if (mayaloader_cat.is_spam()) { - mayaloader_cat.spam() << "went past tex AssignNames" << endl; - } - - if (mayaloader_cat.is_debug()) { - mayaloader_cat.debug() << "-fri: " << _frame_rate << " -sf: " << _start_frame - << " -ef: " << _end_frame << endl; - } - - // masad: keep track of maximum frames of animation on all these joints - MTime maxFrame(_start_frame - 1, _timeUnit); - MTime minFrame = maxFrame; - - for (ei = _anim_tab.begin(); ei != _anim_tab.end(); ++ei) { - MayaAnim *anim = (*ei).second; - MObject node = GetDependencyNode(anim->_joint->get_name()); - MFnDagNode mfnNode(node, &status); - - MMatrix mMat = mfnNode.transformationMatrix(&status); - - MObject attrTX = mfnNode.attribute("translateX", &status); - MObject attrTY = mfnNode.attribute("translateY", &status); - MObject attrTZ = mfnNode.attribute("translateZ", &status); - MObject attrRX = mfnNode.attribute("rotateX", &status); - MObject attrRY = mfnNode.attribute("rotateY", &status); - MObject attrRZ = mfnNode.attribute("rotateZ", &status); - MObject attrSX = mfnNode.attribute("scaleX", &status); - MObject attrSY = mfnNode.attribute("scaleY", &status); - MObject attrSZ = mfnNode.attribute("scaleZ", &status); - - MFnAnimCurve mfnAnimCurveTX; - MFnAnimCurve mfnAnimCurveTY; - MFnAnimCurve mfnAnimCurveTZ; - MFnAnimCurve mfnAnimCurveRX; - MFnAnimCurve mfnAnimCurveRY; - MFnAnimCurve mfnAnimCurveRZ; - MFnAnimCurve mfnAnimCurveSX; - MFnAnimCurve mfnAnimCurveSY; - MFnAnimCurve mfnAnimCurveSZ; - - mfnAnimCurveTX.create(node, attrTX, MFnAnimCurve::kAnimCurveTL, nullptr, &status); - mfnAnimCurveTY.create(node, attrTY, MFnAnimCurve::kAnimCurveTL, nullptr, &status); - mfnAnimCurveTZ.create(node, attrTZ, MFnAnimCurve::kAnimCurveTL, nullptr, &status); - mfnAnimCurveRX.create(node, attrRX, MFnAnimCurve::kAnimCurveTA, nullptr, &status); - mfnAnimCurveRY.create(node, attrRY, MFnAnimCurve::kAnimCurveTA, nullptr, &status); - mfnAnimCurveRZ.create(node, attrRZ, MFnAnimCurve::kAnimCurveTA, nullptr, &status); - mfnAnimCurveSX.create(node, attrSX, MFnAnimCurve::kAnimCurveTU, nullptr, &status); - mfnAnimCurveSY.create(node, attrSY, MFnAnimCurve::kAnimCurveTU, nullptr, &status); - mfnAnimCurveSZ.create(node, attrSZ, MFnAnimCurve::kAnimCurveTU, nullptr, &status); - - MTransformationMatrix matrix( mMat ); - MVector trans = matrix.translation(MSpace::kTransform, &status); - - double rot[3]; - MTransformationMatrix::RotationOrder order = MTransformationMatrix::kXYZ; - status = matrix.getRotation(rot, order); - - double scale[3]; - status = matrix.getScale(scale, MSpace::kTransform); - MFnAnimCurve::TangentType tangent = MFnAnimCurve::kTangentClamped; - MTime time(_start_frame - 1, _timeUnit); - - mfnAnimCurveTX.addKey(time, trans.x, tangent, tangent, nullptr, &status); - mfnAnimCurveTY.addKey(time, trans.y, tangent, tangent, nullptr, &status); - mfnAnimCurveTZ.addKey(time, trans.z, tangent, tangent, nullptr, &status); - mfnAnimCurveRX.addKey(time, rot[0], tangent, tangent, nullptr, &status); - mfnAnimCurveRY.addKey(time, rot[1], tangent, tangent, nullptr, &status); - mfnAnimCurveRZ.addKey(time, rot[2], tangent, tangent, nullptr, &status); - mfnAnimCurveSX.addKey(time, scale[0], tangent, tangent, nullptr, &status); - mfnAnimCurveSY.addKey(time, scale[1], tangent, tangent, nullptr, &status); - mfnAnimCurveSZ.addKey(time, scale[2], tangent, tangent, nullptr, &status); - - for (int frame = 0; frame < anim->_pool->get_num_rows(); frame++) - { - LMatrix4d tMat; - anim->_pool->get_value(frame, tMat); - - double matData[4][4] = {{tMat.get_cell(0,0), tMat.get_cell(0,1), tMat.get_cell(0,2), tMat.get_cell(0,3)}, - {tMat.get_cell(1,0), tMat.get_cell(1,1), tMat.get_cell(1,2), tMat.get_cell(1,3)}, - {tMat.get_cell(2,0), tMat.get_cell(2,1), tMat.get_cell(2,2), tMat.get_cell(2,3)}, - {tMat.get_cell(3,0), tMat.get_cell(3,1), tMat.get_cell(3,2), tMat.get_cell(3,3)}}; - MMatrix mat(matData); - - matrix = MTransformationMatrix(mat); - trans = matrix.translation(MSpace::kTransform, &status); - status = matrix.getRotation(rot, order); - status = matrix.getScale(scale, MSpace::kTransform); - time = MTime(frame + _start_frame, _timeUnit); - - mfnAnimCurveTX.addKey(time, trans.x, tangent, tangent, nullptr, &status); - mfnAnimCurveTY.addKey(time, trans.y, tangent, tangent, nullptr, &status); - mfnAnimCurveTZ.addKey(time, trans.z, tangent, tangent, nullptr, &status); - mfnAnimCurveRX.addKey(time, rot[0], tangent, tangent, nullptr, &status); - mfnAnimCurveRY.addKey(time, rot[1], tangent, tangent, nullptr, &status); - mfnAnimCurveRZ.addKey(time, rot[2], tangent, tangent, nullptr, &status); - mfnAnimCurveSX.addKey(time, scale[0], tangent, tangent, nullptr, &status); - mfnAnimCurveSY.addKey(time, scale[1], tangent, tangent, nullptr, &status); - mfnAnimCurveSZ.addKey(time, scale[2], tangent, tangent, nullptr, &status); - } - if (maxFrame < time) { - maxFrame = time; - } - } - if (anim) { - // masad: set the control's max time with maxFrame - MAnimControl::setMaxTime(maxFrame); - MAnimControl::setMinTime(minFrame); - } - - for (ci = _mesh_tab.begin(); ci != _mesh_tab.end(); ++ci) { - delete (*ci).second; - } - for (ji = _joint_tab.begin(); ji != _joint_tab.end(); ++ji) { - delete (*ji).second; - } - for (ti = _tex_tab.begin(); ti != _tex_tab.end(); ++ti) { - delete (*ti).second; - } - for (ei = _anim_tab.begin(); ei != _anim_tab.end(); ++ei) { - delete (*ei).second; - } - - // ResumeSetKeyMode(); ResumeAnimate(); - - mayaloader_cat.info() << "Egg import successful\n"; - return true; -} - -void MayaEggLoader::PrintData(MayaEggMesh *mesh) -{ - if (mayaloader_cat.is_spam()) { - mayaloader_cat.spam() << "Mesh: " << mesh->_name << endl; - mayaloader_cat.spam() << "num vertexArray: " << mesh->_vertexArray.length() << endl; - ostringstream stream3; - for (unsigned int i=0; i < mesh->_vertexArray.length(); ++i) { - stream3 << "[" << mesh->_vertexArray[i].x << " " << mesh->_vertexArray[i].y << " " << mesh->_vertexArray[i].z << "]" << endl; - } - - mayaloader_cat.spam() << "vertexArray: \n" << stream3.str() << endl; - mayaloader_cat.spam() << "num polygonConnects: " << mesh->_polygonConnects.length() << endl; - mayaloader_cat.spam() << "num uvCounts: " << mesh->_polygonCounts.length() << endl; - mayaloader_cat.spam() << "num uvIds: " << mesh->_uvIds.length() << endl; - ostringstream stream1, stream4; - unsigned int k=0; - for (unsigned int i=0; i < mesh->_polygonCounts.length(); ++i) { - stream1 << mesh->_polygonCounts[i] << ":->"; - stream4 << mesh->_polygonCounts[i] << ":->"; - for (int j=0; j < mesh->_polygonCounts[i]; ++j, ++k) { - stream1 << mesh->_uvIds[k] << ","; - stream4 << mesh->_polygonConnects[k] << ","; - } - stream1 << endl; - stream4 << endl; - } - mayaloader_cat.spam() << "uvCounts:->uvIds " << endl << stream1.str() << endl; - mayaloader_cat.spam() << "vertexCount:->polygonConnects" << endl << stream4.str() << endl; - } -} - -void MayaEggLoader::ParseFrameInfo(string comment) -{ - size_t pos, ls, le; - - pos = comment.find("-fri"); - if (pos != string::npos) { - ls = comment.find(" ", pos+4); - le = comment.find(" ", ls+1); - if (mayaloader_cat.is_debug()) { - mayaloader_cat.debug() << comment.substr(ls+1, le-ls-1) << endl; - } - _frame_rate = atoi(comment.substr(ls+1,le-ls-1).data()); - // mayaloader_cat.debug() << "le = " << le << "; and ls = " << ls << "; - // frame_rate = " << _frame_rate << endl; - - switch (_frame_rate) { - case 15: - _timeUnit = MTime::kGames; - break; - case 24: - _timeUnit = MTime::kFilm; - break; - case 25: - _timeUnit = MTime::kPALFrame; - break; - case 30: - _timeUnit = MTime::kNTSCFrame; - break; - case 48: - _timeUnit = MTime::kShowScan; - break; - case 50: - _timeUnit = MTime::kPALField; - break; - case 60: - _timeUnit = MTime::kNTSCField; - break; - case 2: - _timeUnit = MTime::k2FPS; - break; - case 3: - _timeUnit = MTime::k3FPS; - break; - case 4: - _timeUnit = MTime::k4FPS; - break; - case 5: - _timeUnit = MTime::k5FPS; - break; - case 6: - _timeUnit = MTime::k6FPS; - break; - case 8: - _timeUnit = MTime::k8FPS; - break; - case 10: - _timeUnit = MTime::k10FPS; - break; - case 12: - _timeUnit = MTime::k12FPS; - break; - case 16: - _timeUnit = MTime::k16FPS; - break; - case 20: - _timeUnit = MTime::k20FPS; - break; - case 40: - _timeUnit = MTime::k40FPS; - break; - case 75: - _timeUnit = MTime::k75FPS; - break; - case 80: - _timeUnit = MTime::k80FPS; - break; - case 100: - _timeUnit = MTime::k100FPS; - break; - default: - _timeUnit = MTime::kFilm; - } - - } - - pos = comment.find("-sf"); - if (pos != string::npos) { - ls = comment.find(" ", pos+3); - le = comment.find(" ", ls+1); - if (mayaloader_cat.is_debug()) { - mayaloader_cat.debug() << comment.substr(ls+1, le-ls-1) << endl; - } - if (le == string::npos) { - _start_frame = atoi(comment.substr(ls+1,le).data()); - } else { - _start_frame = atoi(comment.substr(ls+1,le-ls-1).data()); - } - // mayaloader_cat.debug() << "le = " << le << "; and ls = " << ls << "; - // start_frame = " << _start_frame << endl; - } - pos = comment.find("-ef"); - if (pos != string::npos) { - ls = comment.find(" ", pos+3); - le = comment.find(" ", ls+1); - if (mayaloader_cat.is_debug()) { - mayaloader_cat.debug() << comment.substr(ls+1, le-ls-1) << endl; - } - if (le == string::npos) { - _end_frame = atoi(comment.substr(ls+1,le).data()); - } else { - _end_frame = atoi(comment.substr(ls+1,le-ls-1).data()); - } - // mayaloader_cat.debug() << "le = " << le << "; and ls = " << ls << "; - // end_frame = " << _end_frame << endl; - } - - -} - -bool MayaEggLoader::ConvertEggFile(const char *name, bool merge, bool model, bool anim, bool respect_normals) -{ - EggData data; - Filename datafn = Filename::from_os_specific(name); - if (!data.read(datafn)) { - mayaloader_cat.error() << "Cannot read Egg file for import\n"; - return false; - } - return ConvertEggData(&data, merge, model, anim, respect_normals); -} - -MObject MayaEggLoader::GetDependencyNode(string givenName) -{ - MObject node = MObject::kNullObj; - size_t pos; - string name; - - pos = givenName.find(":"); - if (pos != string::npos) { - name = givenName.substr(pos+1); - } else - name = givenName; - - /* - // masad: I do not think you want to return a mesh node because keyframes - // should only apply to joint nodes. - MeshTable::const_iterator ci; - for (ci = _mesh_tab.begin(); ci != _mesh_tab.end(); ++ci) { - MayaEggMesh *mesh = (*ci).second; - - string meshName = mesh->_pool->get_name(); - int nsize = meshName.size(); - if ((nsize > 6) && (meshName.rfind(".verts")==(nsize-6))) { - meshName.resize(nsize-6); - } - if (meshName == name) - { - node = mesh->_transNode; - cerr << "foo get dependency node returning a mesh's transNode? why? : " << givenName << endl; - return node; - } - } - */ - - JointTable::const_iterator ji; - for (ji = _joint_tab.begin(); ji != _joint_tab.end(); ++ji) { - MayaEggJoint *joint = (*ji).second; - if (mayaloader_cat.is_spam()) { - mayaloader_cat.spam() << "traversing a joint: " << joint->_egg_joint->get_name() << endl; - } - string jointName = joint->_egg_joint->get_name(); - if (jointName == name) - { - node = joint->_joint; - return node; - } - } - - return node; -} - -// The two global functions that form the API of this module. - -bool MayaLoadEggData(EggData *data, bool merge, bool model, bool anim, bool respect_normals) -{ - MayaEggLoader loader; - bool temp = loader.ConvertEggData(data, merge, model, anim, respect_normals); - return temp; -} - -bool MayaLoadEggFile(const char *name, bool merge, bool model, bool anim, bool respect_normals) -{ - MayaEggLoader loader; - return loader.ConvertEggFile(name, merge, model, anim, respect_normals); -} diff --git a/pandatool/src/mayaegg/mayaEggLoader.h b/pandatool/src/mayaegg/mayaEggLoader.h deleted file mode 100644 index 077d0da5ae..0000000000 --- a/pandatool/src/mayaegg/mayaEggLoader.h +++ /dev/null @@ -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 diff --git a/pandatool/src/mayaegg/mayaNodeDesc.cxx b/pandatool/src/mayaegg/mayaNodeDesc.cxx deleted file mode 100644 index 2c251ac9ca..0000000000 --- a/pandatool/src/mayaegg/mayaNodeDesc.cxx +++ /dev/null @@ -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 -#include -#include -#include -#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; idxcheck_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; - } - } -} diff --git a/pandatool/src/mayaegg/mayaNodeDesc.h b/pandatool/src/mayaegg/mayaNodeDesc.h deleted file mode 100644 index f4123ee9a2..0000000000 --- a/pandatool/src/mayaegg/mayaNodeDesc.h +++ /dev/null @@ -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 -#include -#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 diff --git a/pandatool/src/mayaegg/mayaNodeTree.cxx b/pandatool/src/mayaegg/mayaNodeTree.cxx deleted file mode 100644 index 977fec2925..0000000000 --- a/pandatool/src/mayaegg/mayaNodeTree.cxx +++ /dev/null @@ -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 -#include -#include -#include -#include "post_maya_include.h" - -#include - -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 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; -} diff --git a/pandatool/src/mayaegg/mayaNodeTree.h b/pandatool/src/mayaegg/mayaNodeTree.h deleted file mode 100644 index e355c45ff3..0000000000 --- a/pandatool/src/mayaegg/mayaNodeTree.h +++ /dev/null @@ -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 NodesByPath; - NodesByPath _nodes_by_path; - - typedef pvector Nodes; - Nodes _nodes; - - typedef ov_set > BlendDescs; - BlendDescs _blend_descs; - - typedef pset Strings; - Strings _ignored_slider_names; -}; - -#endif diff --git a/pandatool/src/mayaegg/mayaToEggConverter.cxx b/pandatool/src/mayaegg/mayaToEggConverter.cxx deleted file mode 100644 index 3f693dd004..0000000000 --- a/pandatool/src/mayaegg/mayaToEggConverter.cxx +++ /dev/null @@ -1,3221 +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.cxx - * @author drose - * @date 1999-11-10 - * Modified 19Mar10 by ETC PandaSE team - * Added set_vertex_color_modern to fix Phong shader bug; also see - * header comment for mayaToEgg.cxx for more details - */ - -#include "mayaToEggConverter.h" -#include "mayaShader.h" -#include "maya_funcs.h" -#include "config_mayaegg.h" -#include "mayaEggGroupUserData.h" - -#include "eggData.h" -#include "eggGroup.h" -#include "eggTable.h" -#include "eggVertex.h" -#include "eggVertexPool.h" -#include "eggNurbsSurface.h" -#include "eggNurbsCurve.h" -#include "eggPolygon.h" -#include "eggPrimitive.h" -#include "eggTexture.h" -#include "eggTextureCollection.h" -#include "eggXfmSAnim.h" -#include "eggSAnimData.h" -#include "string_utils.h" -#include "dcast.h" - -#include "pre_maya_include.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "post_maya_include.h" - -using std::endl; -using std::string; - - -/** - * - */ -MayaToEggConverter:: -MayaToEggConverter(const string &program_name) : - _program_name(program_name), - _tree(this) -{ - // Make sure the library is properly initialized. - init_libmayaegg(); - - _from_selection = false; - - _polygon_output = false; - _polygon_tolerance = 0.01; - _respect_maya_double_sided = maya_default_double_sided; - _always_show_vertex_color = maya_default_vertex_color; - _keep_all_uvsets = false; - _round_uvs = false; - _legacy_shader = false; - _convert_cameras = false; - _convert_lights = false; - - _transform_type = TT_model; -} - -/** - * - */ -MayaToEggConverter:: -MayaToEggConverter(const MayaToEggConverter ©) : - _program_name(copy._program_name), - _from_selection(copy._from_selection), - _subsets(copy._subsets), - _subroots(copy._subroots), - _excludes(copy._excludes), - _ignore_sliders(copy._ignore_sliders), - _force_joints(copy._force_joints), - _tree(this), - _maya(copy._maya), - _polygon_output(copy._polygon_output), - _polygon_tolerance(copy._polygon_tolerance), - _respect_maya_double_sided(copy._respect_maya_double_sided), - _always_show_vertex_color(copy._always_show_vertex_color), - _keep_all_uvsets(copy._keep_all_uvsets), - _convert_cameras(copy._convert_cameras), - _convert_lights(copy._convert_lights), - _round_uvs(copy._round_uvs), - _legacy_shader(copy._legacy_shader), - _transform_type(copy._transform_type) -{ -} - -/** - * - */ -MayaToEggConverter:: -~MayaToEggConverter() { - close_api(); -} - -/** - * Allocates and returns a new copy of the converter. - */ -SomethingToEggConverter *MayaToEggConverter:: -make_copy() { - return new MayaToEggConverter(*this); -} - -/** - * Returns the English name of the file type this converter supports. - */ -string MayaToEggConverter:: -get_name() const { - return "Maya"; -} - -/** - * Returns the common extension of the file type this converter supports. - */ -string MayaToEggConverter:: -get_extension() const { - return "mb"; -} - -/** - * Returns a space-separated list of extension, in addition to the one - * returned by get_extension(), that are recognized by this converter. - */ -string MayaToEggConverter:: -get_additional_extensions() const { - return "ma"; -} - -/** - * Handles the reading of the input file and converting it to egg. Returns - * true if successful, false otherwise. - * - * This is designed to be as generic as possible, generally in support of run- - * time loading. Also see convert_maya(). - */ -bool MayaToEggConverter:: -convert_file(const Filename &filename) { - if (!open_api()) { - mayaegg_cat.error() - << "Maya is not available.\n"; - return false; - } - - // We must ensure our Maya pointers are cleared before we reset the Maya - // scene, because resetting the Maya scene will invalidate all the Maya - // pointers we are holding and cause a crash if we try to free them later. - clear(); - - if (!_maya->read(filename)) { - mayaegg_cat.error() - << "Unable to read " << filename << "\n"; - return false; - } - - if (_character_name.empty()) { - _character_name = filename.get_basename_wo_extension(); - } - - return convert_maya(); -} - -/** - * Empties the list of subroot nodes added via add_subroot(). The entire file - * will once again be converted. - */ -void MayaToEggConverter:: -clear_subroots() { - _subroots.clear(); -} - -/** - * Adds a name pattern to the list of subroot nodes. If the list of subroot - * nodes is not empty, then only a subroot of the nodes in the maya file will - * be converted: those whose names match one of the patterns given on this - * list. - */ -void MayaToEggConverter:: -add_subroot(const GlobPattern &glob) { - _subroots.push_back(glob); -} - -/** - * Empties the list of subset nodes added via add_subset(). The entire file - * will once again be converted. - */ -void MayaToEggConverter:: -clear_subsets() { - _subsets.clear(); -} - -/** - * Adds a name pattern to the list of subset nodes. If the list of subset - * nodes is not empty, then only a subset of the nodes in the maya file will - * be converted: those whose names match one of the patterns given on this - * list. - */ -void MayaToEggConverter:: -add_subset(const GlobPattern &glob) { - _subsets.push_back(glob); -} - -/** - * Empties the list of excluded nodes added via add_exclude(). - */ -void MayaToEggConverter:: -clear_excludes() { - _excludes.clear(); -} - -/** - * Adds a name pattern to the list of excluded nodes. - */ -void MayaToEggConverter:: -add_exclude(const GlobPattern &glob) { - _excludes.push_back(glob); -} - -/** - * Empties the list of ignore_sliders added via add_ignore_slider(). No - * sliders will be ignored. - */ -void MayaToEggConverter:: -clear_ignore_sliders() { - _ignore_sliders.clear(); -} - -/** - * Adds a name pattern to the list of ignore_sliders. Any slider (blend shape - * deformer) that matches a name on the list will not be converted or - * otherwise molested by the converter. This is occasionally necessary to - * filter out automatically-created sliders that are not intended to be used - * directly, but instead have an indirect effect on other sliders. - */ -void MayaToEggConverter:: -add_ignore_slider(const GlobPattern &glob) { - _ignore_sliders.push_back(glob); -} - -/** - * Returns true if the indicated name is on the list of sliders to ignore, - * false otherwise. - */ -bool MayaToEggConverter:: -ignore_slider(const string &name) const { - Globs::const_iterator gi; - for (gi = _ignore_sliders.begin(); gi != _ignore_sliders.end(); ++gi) { - if ((*gi).matches(name)) { - return true; - } - } - - return false; -} - -/** - * Empties the list of force_joints added via add_force_joint(). No joints - * will be forced. - */ -void MayaToEggConverter:: -clear_force_joints() { - _force_joints.clear(); -} - -/** - * Adds a name pattern to the list of force_joints. - * - * Any DAG node that matches a name on the list will be treated as if it were - * a joint during the conversion process; it will receive animation and - * position information. Normally, a true Maya joint, as well as any DAG - * nodes whose transforms are animated, will automatically be flagged as a - * Panda joint. - */ -void MayaToEggConverter:: -add_force_joint(const GlobPattern &glob) { - _force_joints.push_back(glob); -} - -/** - * Returns true if the indicated name is on the list of DAG nodes to treat as - * a joint, false otherwise. - */ -bool MayaToEggConverter:: -force_joint(const string &name) const { - Globs::const_iterator gi; - for (gi = _force_joints.begin(); gi != _force_joints.end(); ++gi) { - if ((*gi).matches(name)) { - return true; - } - } - - return false; -} - -/** - * Sets the flag that indicates whether the currently selected Maya geometry - * will be converted. If this is true, and the selection is nonempty, then - * only the selected geometry will be converted. If this is false, the entire - * file will be converted. - */ -void MayaToEggConverter:: -set_from_selection(bool from_selection) { - _from_selection = from_selection; -} - -/** - * This may be called after convert_file() has been called and returned true, - * indicating a successful conversion. It will return the distance units - * represented by the converted egg file, if known, or DU_invalid if not - * known. - */ -DistanceUnit MayaToEggConverter:: -get_input_units() { - return _maya->get_units(); -} - -/** - * Fills up the egg_data structure according to the global maya model data. - * Returns true if successful, false if there is an error. - */ -bool MayaToEggConverter:: -convert_maya() { - clear(); - clear_error(); - - if (!open_api()) { - mayaegg_cat.error() - << "Maya is not available.\n"; - return false; - } - - if (_egg_data->get_coordinate_system() == CS_default) { - _egg_data->set_coordinate_system(_maya->get_coordinate_system()); - } - - mayaegg_cat.info() - << "Converting from Maya.\n"; - - // Figure out the animation parameters. - double start_frame, end_frame, frame_inc, input_frame_rate, output_frame_rate; - if (has_start_frame()) { - start_frame = get_start_frame(); - } else { - start_frame = MAnimControl::minTime().value(); - } - if (has_end_frame()) { - end_frame = get_end_frame(); - } else { - end_frame = MAnimControl::maxTime().value(); - // end_frame = MAnimControl::animationEndTime().value(); masad: we could - // use this - } - if (has_frame_inc()) { - frame_inc = get_frame_inc(); - } else { - frame_inc = 1.0; - } - if (has_input_frame_rate()) { - input_frame_rate = get_input_frame_rate(); - } else { - MTime time(1.0, MTime::kSeconds); - input_frame_rate = time.as(MTime::uiUnit()); - } - if (has_output_frame_rate()) { - output_frame_rate = get_output_frame_rate(); - } else { - output_frame_rate = input_frame_rate; - } - - frame_inc = frame_inc * input_frame_rate / output_frame_rate; - - bool all_ok = _tree.build_hierarchy(); - - if (all_ok) { - if (!_subroots.empty()) { - Globs::const_iterator gi; - for (gi = _subroots.begin(); gi != _subroots.end(); ++gi) { - if (!_tree.tag_joint_named(*gi)) { - mayaegg_cat.info() - << "No node matching " << *gi << " found.\n"; - } - } - - } else { - // This call makes every node a potential joint; but it does not - // necessarily force nodes to be joints. - _tree.tag_joint_all(); - } - } - - if (all_ok) { - if (_from_selection) { - all_ok = _tree.tag_selected(); - } else if (!_subsets.empty()) { - Globs::const_iterator gi; - for (gi = _subsets.begin(); gi != _subsets.end(); ++gi) { - if (!_tree.tag_named(*gi)) { - mayaegg_cat.info() - << "No node matching " << *gi << " found.\n"; - } - } - - } else { - _tree.tag_all(); - } - } - - if (all_ok) { - if (!_excludes.empty()) { - Globs::const_iterator gi; - for (gi = _excludes.begin(); gi != _excludes.end(); ++gi) { - if (!_tree.untag_named(*gi)) { - mayaegg_cat.info() - << "No node matching " << *gi << " found.\n"; - } - } - } - } - - if (all_ok) { - switch (get_animation_convert()) { - case AC_pose: - // pose: set to a specific frame, then get out the static geometry. - mayaegg_cat.info(false) - << "frame " << start_frame << "\n"; - MGlobal::viewFrame(MTime(start_frame, MTime::uiUnit())); - // fall through - - case AC_none: - // none: just get out a static model, no animation. - mayaegg_cat.info() << "ac_none" << endl; - all_ok = convert_hierarchy(get_egg_data()); - break; - - case AC_flip: - case AC_strobe: - // flip or strobe: get out a series of static models, one per frame, - // under a sequence node for AC_flip. - all_ok = convert_flip(start_frame, end_frame, frame_inc, - output_frame_rate); - break; - - case AC_model: - // model: get out an animatable model with joints and vertex membership. - all_ok = convert_char_model(); - break; - - case AC_chan: - // chan: get out a series of animation tables. - all_ok = convert_char_chan(start_frame, end_frame, frame_inc, - output_frame_rate); - break; - - case AC_both: - // both: Put a model and its animation into the same egg file. - _animation_convert = AC_model; - if (!convert_char_model()) { - all_ok = false; - } - _animation_convert = AC_chan; - if (!convert_char_chan(start_frame, end_frame, frame_inc, - output_frame_rate)) { - all_ok = false; - } - break; - - case AC_invalid: - break; - }; - - reparent_decals(get_egg_data()); - } - - if (had_error()) { - all_ok = false; - } - - if (all_ok) { - mayaegg_cat.info() - << "Converted, no errors.\n"; - } else { - mayaegg_cat.info() - << "Errors encountered in conversion.\n"; - } - - return all_ok; -} - -/** - * Attempts to open the Maya API if it was not already open, and returns true - * if successful, or false if there is an error. - */ -bool MayaToEggConverter:: -open_api(bool revert_directory) { - - if (_maya == nullptr || !_maya->is_valid()) { - // maya to egg converter only needs a read license. only egg2maya need - // write lisences. - _maya = MayaApi::open_api(_program_name, true, revert_directory); - } - return _maya->is_valid(); -} - -/** - * Closes the Maya API, if it was previously opened. Caution! Maya appears - * to call exit() when its API is closed. - */ -void MayaToEggConverter:: -close_api() { - // We have to clear the shaders, at least, before we release the Maya API. - clear(); - _maya.clear(); -} - -/** - * Frees all of the Maya pointers kept within this object, in preparation for - * loading a new scene or releasing the Maya API. - */ -void MayaToEggConverter:: -clear() { - _tree.clear(); - _textures.clear(); - _shaders.clear(); -} - -/** - * Converts the animation as a series of models that cycle (flip) from one to - * the next at the appropriate frame rate. This is the most likely to convert - * precisely (since we ask Maya to tell us the vertex position each time) but - * it is the most wasteful in terms of memory utilization (since a complete of - * the model is stored for each frame). - */ -bool MayaToEggConverter:: -convert_flip(double start_frame, double end_frame, double frame_inc, - double output_frame_rate) { - bool all_ok = true; - - EggGroup *sequence_node = new EggGroup(_character_name); - get_egg_data()->add_child(sequence_node); - if (_animation_convert == AC_flip) { - sequence_node->set_switch_flag(true); - sequence_node->set_switch_fps(output_frame_rate); - } - - MTime frame(start_frame, MTime::uiUnit()); - MTime frame_stop(end_frame, MTime::uiUnit()); - while (frame <= frame_stop) { - mayaegg_cat.info(false) - << "frame " << frame.value() << "\n"; - std::ostringstream name_strm; - name_strm << "frame" << frame.value(); - EggGroup *frame_root = new EggGroup(name_strm.str()); - sequence_node->add_child(frame_root); - - MGlobal::viewFrame(frame); - if (!convert_hierarchy(frame_root)) { - all_ok = false; - } - - frame += frame_inc; - } - - return all_ok; -} - -/** - * Converts the file as an animatable character model, with joints and vertex - * membership. - */ -bool MayaToEggConverter:: -convert_char_model() { - if (has_neutral_frame()) { - MTime frame(get_neutral_frame(), MTime::uiUnit()); - mayaegg_cat.info(false) - << "neutral frame " << frame.value() << "\n"; - MGlobal::viewFrame(frame); - } - - // It's also important for us to reset all the blend shape sliders to 0 - // before we get out the model. Otherwise, the model we convert will have - // the current positions of the sliders baked in. - _tree.reset_sliders(); - - EggGroup *char_node = new EggGroup(_character_name); - get_egg_data()->add_child(char_node); - char_node->set_dart_type(EggGroup::DT_default); - - return convert_hierarchy(char_node); -} - -/** - * Converts the animation as a series of tables to apply to the character - * model, as retrieved earlier via AC_model. - */ -bool MayaToEggConverter:: -convert_char_chan(double start_frame, double end_frame, double frame_inc, - double output_frame_rate) { - // MStatus status; - - EggTable *root_table_node = new EggTable(); - get_egg_data()->add_child(root_table_node); - EggTable *bundle_node = new EggTable(_character_name); - bundle_node->set_table_type(EggTable::TT_bundle); - root_table_node->add_child(bundle_node); - EggTable *skeleton_node = new EggTable(""); - bundle_node->add_child(skeleton_node); - EggTable *morph_node = new EggTable("morph"); - bundle_node->add_child(morph_node); - - // Set the frame rate before we start asking for anim tables to be created. - _tree._fps = output_frame_rate; - _tree.clear_egg(get_egg_data(), nullptr, skeleton_node, morph_node); - - // Now we can get the animation data by walking through all of the frames, - // one at a time, and getting the joint angles at each frame. - - // This is just a temporary EggGroup to receive the transform for each joint - // each frame. - PT(EggGroup) tgroup = new EggGroup; - - int num_nodes = _tree.get_num_nodes(); - int num_sliders = _tree.get_num_blend_descs(); - int i; - - MTime frame(start_frame, MTime::uiUnit()); - MTime frame_stop(end_frame, MTime::uiUnit()); - while (frame <= frame_stop) { - if (mayaegg_cat.is_spam()) { - mayaegg_cat.spam(false) - << "frame " << frame.value() << "\n"; - } else { - // We have to write to cerr instead of mayaegg_cat to allow flushing - // without writing a newline. - std::cerr << "." << std::flush; - } - MGlobal::viewFrame(frame); - - for (i = 0; i < num_nodes; i++) { - MayaNodeDesc *node_desc = _tree.get_node(i); - if (node_desc->is_joint()) { - if (mayaegg_cat.is_spam()) { - mayaegg_cat.spam() - << "joint " << node_desc->get_name() << "\n"; - } - get_joint_transform(node_desc->get_dag_path(), tgroup); - EggXfmSAnim *anim = _tree.get_egg_anim(node_desc); - if (!anim->add_data(tgroup->get_transform3d())) { - mayaegg_cat.error() - << "Invalid transform on " << node_desc->get_name() - << " frame " << frame.value() << ".\n"; - } - } - } - - for (i = 0; i < num_sliders; i++) { - MayaBlendDesc *blend_desc = _tree.get_blend_desc(i); - if (mayaegg_cat.is_spam()) { - mayaegg_cat.spam() - << "slider " << blend_desc->get_name() << "\n"; - } - EggSAnimData *anim = _tree.get_egg_slider(blend_desc); - anim->add_data(blend_desc->get_slider()); - } - - frame += frame_inc; - } - - // Now optimize all of the tables we just filled up, for no real good - // reason, except that it makes the resulting egg file a little easier to - // read. - for (i = 0; i < num_nodes; i++) { - MayaNodeDesc *node_desc = _tree.get_node(i); - if (node_desc->is_joint()) { - _tree.get_egg_anim(node_desc)->optimize(); - } - } - - for (i = 0; i < num_sliders; i++) { - MayaBlendDesc *blend_desc = _tree.get_blend_desc(i); - EggSAnimData *anim = _tree.get_egg_slider(blend_desc); - anim->optimize(); - } - - mayaegg_cat.info(false) - << "\n"; - - return true; -} - -/** - * Generates egg structures for each node in the Maya hierarchy. - */ -bool MayaToEggConverter:: -convert_hierarchy(EggGroupNode *egg_root) { - int num_nodes = _tree.get_num_nodes(); - - if (_round_uvs) { - mayaegg_cat.info() << "will round up uv coordinates" << endl; - } - - if (_keep_all_uvsets) { - mayaegg_cat.info() << "will keep_all_uvsets" << endl; - } - if (_polygon_output) { - mayaegg_cat.info() << "will convert NURBS to polys" << endl; - } - if (_convert_cameras) { - mayaegg_cat.info() << "will convert camera nodes to locators" << endl; - } - if (_convert_lights) { - mayaegg_cat.info() << "will convert light nodes to locators" << endl; - } - // give some feedback about whether special options are on - if (_legacy_shader) { - mayaegg_cat.info() << "will disable modern Phong shader path. using legacy" << endl; - } - _tree.clear_egg(get_egg_data(), egg_root, nullptr, nullptr); - for (int i = 0; i < num_nodes; i++) { - MayaNodeDesc *node = _tree.get_node(i); - if (!process_model_node(node)) { - return false; - } - } - return true; -} - -/** - * Converts the indicated Maya node (given a MDagPath, similar in concept to - * Panda's NodePath) to the corresponding Egg structure. Returns true if - * successful, false if an error was encountered. - */ -bool MayaToEggConverter:: -process_model_node(MayaNodeDesc *node_desc) { - if (!node_desc->has_dag_path()) { - // If the node has no Maya equivalent, never mind. - return true; - } - - MDagPath dag_path = node_desc->get_dag_path(); - - MStatus status; - MFnDagNode dag_node(dag_path, &status); - if (!status) { - status.perror("MFnDagNode constructor"); - mayaegg_cat.error() << dag_path.fullPathName().asChar() << "\n"; - return false; - } - - MObject node = dag_path.transform(&status); - if (!status) { - status.perror("dag_path.transform()"); - return false; - } - - string path = dag_path.fullPathName().asChar(); - - if (mayaegg_cat.is_debug()) { - mayaegg_cat.debug() - << path << ": " << dag_node.typeName().asChar(); - - if (MAnimUtil::isAnimated(dag_path)) { - mayaegg_cat.debug(false) - << " (animated)"; - } - - mayaegg_cat.debug(false) << "\n"; - } - - if (dag_node.inUnderWorld()) { - if (mayaegg_cat.is_debug()) { - mayaegg_cat.debug() - << "Ignoring underworld node " << path - << "\n"; - } - - } else if (dag_node.isIntermediateObject()) { - if (mayaegg_cat.is_debug()) { - mayaegg_cat.debug() - << "Ignoring intermediate object " << path - << "\n"; - } - - } else if (dag_path.hasFn(MFn::kCamera)) { - if (_convert_cameras) { - MFnCamera camera (dag_path, &status); - if ( !status ) { - status.perror("MFnCamera constructor"); - return false; - } - - // Extract some interesting Camera data - if (mayaegg_cat.is_spam()) { - MPoint eyePoint = camera.eyePoint(MSpace::kWorld); - MVector upDirection = camera.upDirection(MSpace::kWorld); - MVector viewDirection = camera.viewDirection(MSpace::kWorld); - mayaegg_cat.spam() << " eyePoint: " << eyePoint.x << " " - << eyePoint.y << " " << eyePoint.z << endl; - mayaegg_cat.spam() << " upDirection: " << upDirection.x << " " - << upDirection.y << " " << upDirection.z << endl; - mayaegg_cat.spam() << " viewDirection: " << viewDirection.x << " " - << viewDirection.y << " " << viewDirection.z << endl; - mayaegg_cat.spam() << " aspectRatio: " << camera.aspectRatio() << endl; - mayaegg_cat.spam() << " horizontalFilmAperture: " - << camera.horizontalFilmAperture() << endl; - mayaegg_cat.spam() << " verticalFilmAperture: " - << camera.verticalFilmAperture() << endl; - } - - EggGroup *egg_group = _tree.get_egg_group(node_desc); - - if (mayaegg_cat.is_debug()) { - mayaegg_cat.warning() - << "Saving camera nodes as a locator: " << path << "\n"; - } - - if (node_desc->is_tagged()) { - // Presumably, the camera's position has some meaning to the end-user, - // so we will implicitly tag it with the DCS flag so it won't get - // flattened out. - if (_animation_convert != AC_model) { - // For now, don't set the DCS flag on cameras within character - // models, since egg-optchar doesn't understand this. Perhaps - // there's no reason to ever change this, since cameras within - // character models may not be meaningful. - egg_group->set_dcs_type(EggGroup::DC_net); - } - get_transform(node_desc, dag_path, egg_group); - make_camera_locator(dag_path, dag_node, egg_group); - } else { - if (mayaegg_cat.is_debug()) { - mayaegg_cat.debug() - << "Ignoring camera node " << path - << "\n"; - } - } - } - - } else if (dag_path.hasFn(MFn::kLight)) { - if (_convert_lights) { - MFnLight light (dag_path, &status); - if ( !status ) { - status.perror("MFnLight constructor"); - return false; - } - - EggGroup *egg_group = _tree.get_egg_group(node_desc); - - if (mayaegg_cat.is_debug()) { - mayaegg_cat.warning() << "Saving light node as a locator: " << path << endl; - } - - if (node_desc->is_tagged()) { - // Presumably, the lighht's position has some meaning to the end-user, - // so we will implicitly tag it with the DCS flag so it won't get - // flattened out. - if (_animation_convert != AC_model) { - // For now, don't set the DCS flag on lights within character - // models, since egg-optchar doesn't understand this. Perhaps - // there's no reason to ever change this, since lights within - // character models may not be meaningful. - egg_group->set_dcs_type(EggGroup::DC_net); - } - get_transform(node_desc, dag_path, egg_group); - make_light_locator(dag_path, dag_node, egg_group); - } else { - if (mayaegg_cat.is_debug()) { - mayaegg_cat.debug() - << "Ignoring light node " << path - << "\n"; - } - } - } - - MFnLight light (dag_path, &status); - if ( !status ) { - status.perror("MFnLight constructor"); - mayaegg_cat.error() << "light extraction failed" << endl; - return false; - } - - if (mayaegg_cat.is_info()) { - MString name = dag_path.partialPathName(); - mayaegg_cat.info() << "-- Light found -- tranlations in cm, rotations in rads\n"; - mayaegg_cat.info() << "\"" << name.asChar() << "\" : \n"; - } - - // Get the translationrotationscale data - MObject transformNode = dag_path.transform(&status); - // This node has no transform - i.e., it's the world node - if (!status && status.statusCode () == MStatus::kInvalidParameter) - return false; - MFnDagNode transform (transformNode, &status); - if (!status) { - status.perror("MFnDagNode constructor"); - return false; - } - MTransformationMatrix matrix (transform.transformationMatrix()); - MVector tl = matrix.translation(MSpace::kWorld); - // Stop rediculously small values like -4.43287e-013 - if (tl.x < 0.0001) { - tl.x = 0; - } - if (tl.y < 0.0001) { - tl.y = 0; - } - if (tl.z < 0.0001) { - tl.z = 0; - } - // We swap Y and Z in the next few bits cuz Panda is Z-up by default and - // Maya is Y-up - mayaegg_cat.info() << " \"translation\" : (" << tl.x << ", " << tl.z << ", " << tl.y << ")" - << endl; - double threeDoubles[3]; - MTransformationMatrix::RotationOrder rOrder; - - matrix.getRotation (threeDoubles, rOrder, MSpace::kWorld); - mayaegg_cat.info() << " \"rotation\": (" - << threeDoubles[0] << ", " - << threeDoubles[2] << ", " - << threeDoubles[1] << ")\n"; - matrix.getScale (threeDoubles, MSpace::kWorld); - mayaegg_cat.info() << " \"scale\" : (" - << threeDoubles[0] << ", " - << threeDoubles[2] << ", " - << threeDoubles[1] << ")\n"; - - // Extract some interesting Light data - MColor color; - color = light.color(); - mayaegg_cat.info() << " \"color\" : (" - << color.r << ", " - << color.g << ", " - << color.b << ")\n"; - color = light.shadowColor(); - mayaegg_cat.info() << " \"intensity\" : " << light.intensity() << endl; - - } else if (dag_path.hasFn(MFn::kNurbsSurface)) { - EggGroup *egg_group = _tree.get_egg_group(node_desc); - get_transform(node_desc, dag_path, egg_group); - - if (node_desc->is_tagged()) { - MFnNurbsSurface surface(dag_path, &status); - if (!status) { - mayaegg_cat.info() - << "Error in node " << path - << ":\n" - << " it appears to have a NURBS surface, but does not.\n"; - } else { - make_nurbs_surface(node_desc, dag_path, surface, egg_group); - } - } - } else if (dag_path.hasFn(MFn::kNurbsCurve)) { - // Only convert NurbsCurves if we aren't making an animated model. - // Animated models, as a general rule, don't want these sorts of things in - // them. - if (_animation_convert != AC_model) { - EggGroup *egg_group = _tree.get_egg_group(node_desc); - get_transform(node_desc, dag_path, egg_group); - - if (node_desc->is_tagged()) { - MFnNurbsCurve curve(dag_path, &status); - if (!status) { - mayaegg_cat.info() - << "Error in node " << path << ":\n" - << " it appears to have a NURBS curve, but does not.\n"; - } else { - make_nurbs_curve(dag_path, curve, egg_group); - } - } - } - - } else if (dag_path.hasFn(MFn::kMesh)) { - if (node_desc->is_tagged()) { - EggGroup *egg_group = _tree.get_egg_group(node_desc); - get_transform(node_desc, dag_path, egg_group); - MFnMesh mesh(dag_path, &status); - if (!status) { - mayaegg_cat.info() - << "Error in node " << path << ":\n" - << " it appears to have a polygon mesh, but does not.\n"; - } else { - make_polyset(node_desc, dag_path, mesh, egg_group); - } - } - /* - EggGroup *egg_group = _tree.get_egg_group(node_desc); - get_transform(node_desc, dag_path, egg_group); - - if (node_desc->is_tagged()) { - MFnMesh mesh(dag_path, &status); - if (!status) { - mayaegg_cat.info() - << "Error in node " << path << ":\n" - << " it appears to have a polygon mesh, but does not.\n"; - } else { - make_polyset(node_desc, dag_path, mesh, egg_group); - } - } - */ - } else if (dag_path.hasFn(MFn::kLocator)) { - if (_animation_convert == AC_none) { - if (!node_desc->is_tagged()) { - return true; - } - } - EggGroup *egg_group = _tree.get_egg_group(node_desc); - - if (mayaegg_cat.is_debug()) { - mayaegg_cat.debug() - << "Locator at " << path << "\n"; - } - - if (node_desc->is_tagged()) { - // Presumably, the locator's position has some meaning to the end-user, - // so we will implicitly tag it with the DCS flag so it won't get - // flattened out. - if (_animation_convert != AC_model) { - // For now, don't set the DCS flag on locators within character - // models, since egg-optchar doesn't understand this. Perhaps there's - // no reason to ever change this, since locators within character - // models may not be meaningful. - egg_group->set_dcs_type(EggGroup::DC_net); - } - get_transform(node_desc, dag_path, egg_group); - make_locator(dag_path, dag_node, egg_group); - } - - } else { - // Just a generic node. - if (_animation_convert == AC_none) { - if (!node_desc->is_tagged()) { - return true; - } - } - EggGroup *egg_group = _tree.get_egg_group(node_desc); - get_transform(node_desc, dag_path, egg_group); - } - - return true; -} - -/** - * Extracts the transform on the indicated Maya node, and applies it to the - * corresponding Egg node. - */ -void MayaToEggConverter:: -get_transform(MayaNodeDesc *node_desc, const MDagPath &dag_path, - EggGroup *egg_group) { - if (_animation_convert == AC_model) { - // When we're getting an animated model, we only get transforms for - // joints, and they get converted in a special way. - - if (node_desc->is_joint()) { - if (mayaegg_cat.is_spam()) { - mayaegg_cat.spam() - << "gt: joint " << node_desc->get_name() << "\n"; - } - get_joint_transform(dag_path, egg_group); - } - return; - } - - MStatus status; - MObject transformNode = dag_path.transform(&status); - if (!status && status.statusCode() == MStatus::kInvalidParameter) { - // This node has no transform - i.e., it's the world node - return; - } - - // Billboards always get the transform set. - if (egg_group->get_billboard_type() == EggGroup::BT_none) { - switch (_transform_type) { - case TT_all: - break; - - case TT_model: - if (!egg_group->get_model_flag() && !egg_group->has_dcs_type()) { - return; - } - break; - - case TT_dcs: - if (!egg_group->has_dcs_type()) { - return; - } - break; - - case TT_none: - case TT_invalid: - return; - } - } - - // Extract the matrix from the dag path. - MMatrix mat = dag_path.inclusiveMatrix(&status); - if (!status) { - status.perror("Can't get transform matrix"); - return; - } - LMatrix4d m4d(mat[0][0], mat[0][1], mat[0][2], mat[0][3], - mat[1][0], mat[1][1], mat[1][2], mat[1][3], - mat[2][0], mat[2][1], mat[2][2], mat[2][3], - mat[3][0], mat[3][1], mat[3][2], mat[3][3]); - - // Maya has a rotate pivot, separate from its transform. Usually we care - // more about the rotate pivot than we do about the transform, so get the - // rotate pivot too. - MFnTransform transform(transformNode, &status); - if (!status) { - status.perror("MFnTransform constructor"); - return; - } - MPoint pivot = transform.rotatePivot(MSpace::kObject, &status); - if (!status) { - status.perror("Can't get rotate pivot"); - return; - } - - // We need to convert the pivot to world coordinates. (Maya can only tell - // it to us in local coordinates.) - LPoint3d p3d(pivot[0], pivot[1], pivot[2]); - p3d = p3d * m4d; - - // Now recenter the matrix about the pivot point. - m4d.set_row(3, p3d); - - // Convert the recentered matrix into the group's space and store it. - m4d = m4d * egg_group->get_node_frame_inv(); - if (!m4d.almost_equal(LMatrix4d::ident_mat(), 0.0001)) { - egg_group->add_matrix4(m4d); - } - return; -} - -/** - * Extracts the transform on the indicated Maya node, as appropriate for a - * joint in an animated character, and applies it to the indicated node. This - * is different from get_transform() in that it does not respect the - * _transform_type flag, and it does not consider the relative transforms - * within the egg file. - */ -void MayaToEggConverter:: -get_joint_transform(const MDagPath &dag_path, EggGroup *egg_group) { - // First, make sure there's not a transform on the group already. - egg_group->clear_transform(); - - MStatus status; - MObject transformNode = dag_path.transform(&status); - // This node has no transform - i.e., it's the world node - if (!status && status.statusCode() == MStatus::kInvalidParameter) { - return; - } - - MFnDagNode transform(transformNode, &status); - if (!status) { - status.perror("MFnDagNode constructor"); - return; - } - - MTransformationMatrix matrix(transform.transformationMatrix()); - - if (mayaegg_cat.is_spam()) { - MVector t = matrix.translation(MSpace::kWorld); - mayaegg_cat.spam() - << " translation: [" - << t[0] << ", " - << t[1] << ", " - << t[2] << "]\n"; - double d[3]; - MTransformationMatrix::RotationOrder rOrder; - - matrix.getRotation(d, rOrder, MSpace::kWorld); - mayaegg_cat.spam() - << " rotation: [" - << d[0] << ", " - << d[1] << ", " - << d[2] << "]\n"; - matrix.getScale(d, MSpace::kWorld); - mayaegg_cat.spam() - << " scale: [" - << d[0] << ", " - << d[1] << ", " - << d[2] << "]\n"; - matrix.getShear(d, MSpace::kWorld); - mayaegg_cat.spam() - << " shear: [" - << d[0] << ", " - << d[1] << ", " - << d[2] << "]\n"; - } - - MMatrix mat = matrix.asMatrix(); - MMatrix ident_mat; - ident_mat.setToIdentity(); - - if (!mat.isEquivalent(ident_mat, 0.0001)) { - egg_group->set_transform3d - (LMatrix4d(mat[0][0], mat[0][1], mat[0][2], mat[0][3], - mat[1][0], mat[1][1], mat[1][2], mat[1][3], - mat[2][0], mat[2][1], mat[2][2], mat[2][3], - mat[3][0], mat[3][1], mat[3][2], mat[3][3])); - } -} - -/** - * Converts the indicated Maya NURBS surface to a corresponding egg structure, - * and attaches it to the indicated egg group. - */ -void MayaToEggConverter:: -make_nurbs_surface(MayaNodeDesc *node_desc, const MDagPath &dag_path, - MFnNurbsSurface &surface, EggGroup *egg_group) { - MStatus status; - string name = surface.name().asChar(); - - if (mayaegg_cat.is_spam()) { - mayaegg_cat.spam() - << " numCVs: " - << surface.numCVsInU() - << " * " - << surface.numCVsInV() - << "\n"; - mayaegg_cat.spam() - << " numKnots: " - << surface.numKnotsInU() - << " * " - << surface.numKnotsInV() - << "\n"; - mayaegg_cat.spam() - << " numSpans: " - << surface.numSpansInU() - << " * " - << surface.numSpansInV() - << "\n"; - } - MayaShader *shader = _shaders.find_shader_for_node(surface.object(), _legacy_shader); - - if (_polygon_output) { - // If we want polygon output only, tesselate the NURBS and output that. - MTesselationParams params; - params.setFormatType(MTesselationParams::kStandardFitFormat); - params.setOutputType(MTesselationParams::kQuads); - params.setStdFractionalTolerance(_polygon_tolerance); - - // We'll create the tesselation as a sibling of the NURBS surface. That - // way we inherit all of the transformations. - MDagPath polyset_path = dag_path; - MObject polyset_parent = polyset_path.node(); - MObject polyset = - surface.tesselate(params, polyset_parent, &status); - if (!status) { - status.perror("MFnNurbsSurface::tesselate"); - return; - } - - status = polyset_path.push(polyset); - if (!status) { - status.perror("MDagPath::push"); - } - - MFnMesh polyset_fn(polyset, &status); - if (!status) { - status.perror("MFnMesh constructor"); - return; - } - make_polyset(node_desc, polyset_path, polyset_fn, egg_group, shader); - - // Now remove the polyset we created. - MFnDagNode parent_node(polyset_parent, &status); - if (!status) { - status.perror("MFnDagNode constructor"); - return; - } - status = parent_node.removeChild(polyset); - if (!status) { - status.perror("MFnDagNode::removeChild"); - } - - return; - } - - MPointArray cv_array; - status = surface.getCVs(cv_array, MSpace::kWorld); - if (!status) { - status.perror("MFnNurbsSurface::getCVs"); - return; - } - - // Also get out all the alternate blend shapes for the surface by applying - // each morph slider one at a time. - pvector morph_cvs; - if (_animation_convert == AC_model) { - int num_sliders = node_desc->get_num_blend_descs(); - morph_cvs.reserve(num_sliders); - for (int i = 0; i < num_sliders; i++) { - MayaBlendDesc *blend_desc = node_desc->get_blend_desc(i); - - // Temporarily push the slider up to 1.0 so we can see what the surface - // looks like at that value. - blend_desc->set_slider(1.0); - MPointArray cv_array; - status = surface.getCVs(cv_array, MSpace::kWorld); - blend_desc->set_slider(0.0); - - if (!status) { - status.perror("MFnNurbsSurface::getCVs"); - return; - } - morph_cvs.push_back(cv_array); - } - } - - MDoubleArray u_knot_array, v_knot_array; - status = surface.getKnotsInU(u_knot_array); - if (!status) { - status.perror("MFnNurbsSurface::getKnotsInU"); - return; - } - status = surface.getKnotsInV(v_knot_array); - if (!status) { - status.perror("MFnNurbsSurface::getKnotsInV"); - return; - } - - MFnNurbsSurface::Form u_form = surface.formInU(); - MFnNurbsSurface::Form v_form = surface.formInV(); - - int u_degree = surface.degreeU(); - int v_degree = surface.degreeV(); - - int u_cvs = surface.numCVsInU(); - int v_cvs = surface.numCVsInV(); - - // Maya repeats CVS at the end for a periodic surface, and doesn't count - // them in the joint weight array, below. - int maya_u_cvs = (u_form == MFnNurbsSurface::kPeriodic) ? u_cvs - u_degree : u_cvs; - int maya_v_cvs = (v_form == MFnNurbsSurface::kPeriodic) ? v_cvs - v_degree : v_cvs; - - int u_knots = surface.numKnotsInU(); - int v_knots = surface.numKnotsInV(); - - assert(u_knots == u_cvs + u_degree - 1); - assert(v_knots == v_cvs + v_degree - 1); - - string vpool_name = name + ".cvs"; - EggVertexPool *vpool = new EggVertexPool(vpool_name); - egg_group->add_child(vpool); - - EggNurbsSurface *egg_nurbs = new EggNurbsSurface(name); - egg_nurbs->setup(u_degree + 1, v_degree + 1, - u_knots + 2, v_knots + 2); - - int i; - - egg_nurbs->set_u_knot(0, u_knot_array[0]); - for (i = 0; i < u_knots; i++) { - egg_nurbs->set_u_knot(i + 1, u_knot_array[i]); - } - egg_nurbs->set_u_knot(u_knots + 1, u_knot_array[u_knots - 1]); - - egg_nurbs->set_v_knot(0, v_knot_array[0]); - for (i = 0; i < v_knots; i++) { - egg_nurbs->set_v_knot(i + 1, v_knot_array[i]); - } - egg_nurbs->set_v_knot(v_knots + 1, v_knot_array[v_knots - 1]); - - LMatrix4d vertex_frame_inv = egg_group->get_vertex_frame_inv(); - - for (i = 0; i < egg_nurbs->get_num_cvs(); i++) { - int ui = egg_nurbs->get_u_index(i); - int vi = egg_nurbs->get_v_index(i); - int maya_vi = v_cvs * ui + vi; - - double v[4]; - status = cv_array[maya_vi].get(v); - if (!status) { - status.perror("MPoint::get"); - } else { - EggVertex *vert = vpool->add_vertex(new EggVertex, i); - LPoint4d p4d(v[0], v[1], v[2], v[3]); - p4d = p4d * vertex_frame_inv; - vert->set_pos(p4d); - - // Now generate the morph targets for the vertex. - if (!morph_cvs.empty()) { - // Morph deltas are given in 3-d space, not in 4-d homogenous space. - LPoint3d p3d(v[0] / v[3], v[1] / v[3], v[2] / v[3]); - - for (unsigned int si = 0; si < morph_cvs.size(); si++) { - MayaBlendDesc *blend_desc = node_desc->get_blend_desc(si); - status = morph_cvs[si][maya_vi].get(v); - if (!status) { - status.perror("MPoint::get"); - } else { - LPoint3d m3d(v[0] / v[3], v[1] / v[3], v[2] / v[3]); - LVector3d delta = m3d - p3d; - if (!delta.almost_equal(LVector3d::zero())) { - EggMorphVertex dxyz(blend_desc->get_name(), delta); - vert->_dxyzs.insert(dxyz); - } - } - } - } - - egg_nurbs->add_vertex(vert); - } - } - - // Now consider the trim curves, if any. - unsigned num_trims = surface.numRegions(); - int trim_curve_index = 0; - for (unsigned ti = 0; ti < num_trims; ti++) { - unsigned num_loops = surface.numBoundaries(ti); - - if (num_loops > 0) { - egg_nurbs->_trims.push_back(EggNurbsSurface::Trim()); - EggNurbsSurface::Trim &egg_trim = egg_nurbs->_trims.back(); - - for (unsigned li = 0; li < num_loops; li++) { - egg_trim.push_back(EggNurbsSurface::Loop()); - EggNurbsSurface::Loop &egg_loop = egg_trim.back(); - - MFnNurbsSurface::BoundaryType type = - surface.boundaryType(ti, li, &status); - bool keep_loop = false; - - if (!status) { - status.perror("MFnNurbsSurface::BoundaryType"); - } else { - keep_loop = (type == MFnNurbsSurface::kInner || - type == MFnNurbsSurface::kOuter); - } - - if (keep_loop) { - unsigned num_edges = surface.numEdges(ti, li); - for (unsigned ei = 0; ei < num_edges; ei++) { - MObjectArray edge = surface.edge(ti, li, ei, true, &status); - if (!status) { - status.perror("MFnNurbsSurface::edge"); - } else { - unsigned num_segs = edge.length(); - for (unsigned si = 0; si < num_segs; si++) { - MObject segment = edge[si]; - if (segment.hasFn(MFn::kNurbsCurve)) { - MFnNurbsCurve curve(segment, &status); - if (!status) { - mayaegg_cat.error() - << "Trim curve appears to be a nurbs curve, but isn't.\n"; - } else { - // Finally, we have a valid curve! - EggNurbsCurve *egg_curve = - make_trim_curve(curve, name, egg_group, trim_curve_index); - trim_curve_index++; - if (egg_curve != nullptr) { - egg_loop.push_back(egg_curve); - } - } - } else { - mayaegg_cat.error() - << "Trim curve segment is not a nurbs curve.\n"; - } - } - } - } - } - } - } - } - - // We add the NURBS to the group down here, after all of the vpools for the - // trim curves have been added. - egg_group->add_child(egg_nurbs); - - if (shader != nullptr) { - set_shader_attributes(*egg_nurbs, *shader); - } - - // Now try to find the skinning information for the surface. - bool got_weights = false; - - pvector joints; - MFloatArray weights; - if (_animation_convert == AC_model) { - got_weights = - get_vertex_weights(dag_path, surface, joints, weights); - } - - if (got_weights && !joints.empty()) { - int num_joints = joints.size(); - int num_weights = (int)weights.length(); - int num_verts = num_weights / num_joints; - // The number of weights should be an even multiple of verts * joints. - nassertv(num_weights == num_verts * num_joints); - - for (i = 0; i < egg_nurbs->get_num_cvs(); i++) { - int ui = egg_nurbs->get_u_index(i) % maya_u_cvs; - int vi = egg_nurbs->get_v_index(i) % maya_v_cvs; - - int maya_vi = maya_v_cvs * ui + vi; - nassertv(maya_vi < num_verts); - EggVertex *vert = vpool->get_vertex(i); - - for (int ji = 0; ji < num_joints; ++ji) { - PN_stdfloat weight = weights[maya_vi * num_joints + ji]; - if (weight != 0.0f) { - EggGroup *joint = joints[ji]; - if (joint != nullptr) { - joint->ref_vertex(vert, weight); - } - } - } - } - } -} - -/** - * Converts the indicated Maya NURBS trim curve to a corresponding egg - * structure, and returns it, or NULL if there is a problem. - */ -EggNurbsCurve *MayaToEggConverter:: -make_trim_curve(const MFnNurbsCurve &curve, const string &nurbs_name, - EggGroupNode *egg_group, int trim_curve_index) { - if (mayaegg_cat.is_spam()) { - mayaegg_cat.spam() - << "Trim curve:\n"; - mayaegg_cat.spam() - << " numCVs: " - << curve.numCVs() - << "\n"; - mayaegg_cat.spam() - << " numKnots: " - << curve.numKnots() - << "\n"; - mayaegg_cat.spam() - << " numSpans: " - << curve.numSpans() - << "\n"; - } - - MStatus status; - - MPointArray cv_array; - status = curve.getCVs(cv_array, MSpace::kWorld); - if (!status) { - status.perror("MFnNurbsCurve::getCVs"); - return nullptr; - } - MDoubleArray knot_array; - status = curve.getKnots(knot_array); - if (!status) { - status.perror("MFnNurbsCurve::getKnots"); - return nullptr; - } - - /* - MFnNurbsCurve::Form form = curve.form(); - */ - - int degree = curve.degree(); - int cvs = curve.numCVs(); - int knots = curve.numKnots(); - - assert(knots == cvs + degree - 1); - - string trim_name = "trim" + format_string(trim_curve_index); - - string vpool_name = nurbs_name + "." + trim_name; - EggVertexPool *vpool = new EggVertexPool(vpool_name); - egg_group->add_child(vpool); - - EggNurbsCurve *egg_curve = new EggNurbsCurve(trim_name); - egg_curve->setup(degree + 1, knots + 2); - - int i; - - egg_curve->set_knot(0, knot_array[0]); - for (i = 0; i < knots; i++) { - egg_curve->set_knot(i + 1, knot_array[i]); - } - egg_curve->set_knot(knots + 1, knot_array[knots - 1]); - - for (i = 0; i < egg_curve->get_num_cvs(); i++) { - double v[4]; - MStatus status = cv_array[i].get(v); - if (!status) { - status.perror("MPoint::get"); - } else { - EggVertex vert; - vert.set_pos(LPoint3d(v[0], v[1], v[3])); - egg_curve->add_vertex(vpool->create_unique_vertex(vert)); - } - } - - return egg_curve; -} - -/** - * Converts the indicated Maya NURBS curve (a standalone curve, not a trim - * curve) to a corresponding egg structure and attaches it to the indicated - * egg group. - */ -void MayaToEggConverter:: -make_nurbs_curve(const MDagPath &, const MFnNurbsCurve &curve, - EggGroup *egg_group) { - MStatus status; - string name = curve.name().asChar(); - - if (mayaegg_cat.is_spam()) { - mayaegg_cat.spam() - << " numCVs: " - << curve.numCVs() - << "\n"; - mayaegg_cat.spam() - << " numKnots: " - << curve.numKnots() - << "\n"; - mayaegg_cat.spam() - << " numSpans: " - << curve.numSpans() - << "\n"; - } - - MPointArray cv_array; - status = curve.getCVs(cv_array, MSpace::kWorld); - if (!status) { - status.perror("MFnNurbsCurve::getCVs"); - return; - } - MDoubleArray knot_array; - status = curve.getKnots(knot_array); - if (!status) { - status.perror("MFnNurbsCurve::getKnots"); - return; - } - - /* - MFnNurbsCurve::Form form = curve.form(); - */ - - int degree = curve.degree(); - int cvs = curve.numCVs(); - int knots = curve.numKnots(); - - assert(knots == cvs + degree - 1); - - string vpool_name = name + ".cvs"; - EggVertexPool *vpool = new EggVertexPool(vpool_name); - egg_group->add_child(vpool); - - EggNurbsCurve *egg_curve = new EggNurbsCurve(name); - egg_group->add_child(egg_curve); - egg_curve->setup(degree + 1, knots + 2); - - int i; - - egg_curve->set_knot(0, knot_array[0]); - for (i = 0; i < knots; i++) { - egg_curve->set_knot(i + 1, knot_array[i]); - } - egg_curve->set_knot(knots + 1, knot_array[knots - 1]); - - LMatrix4d vertex_frame_inv = egg_group->get_vertex_frame_inv(); - - for (i = 0; i < egg_curve->get_num_cvs(); i++) { - double v[4]; - MStatus status = cv_array[i].get(v); - if (!status) { - status.perror("MPoint::get"); - } else { - EggVertex vert; - LPoint4d p4d(v[0], v[1], v[2], v[3]); - p4d = p4d * vertex_frame_inv; - vert.set_pos(p4d); - egg_curve->add_vertex(vpool->create_unique_vertex(vert)); - } - } - MayaShader *shader = _shaders.find_shader_for_node(curve.object(), _legacy_shader); - if (shader != nullptr) { - set_shader_attributes(*egg_curve, *shader); - } -} - -/** - * given uvsets, round them up or down - */ -int MayaToEggConverter:: -round(double value) { - if (value < 0) - return -(floor(-value + 0.5)); - // or as an alternate use: return ceil ( value - 0.5); - else - return floor( value + 0.5); -} - -/** - * Converts the indicated Maya polyset to a bunch of EggPolygons and parents - * them to the indicated egg group. - */ -void MayaToEggConverter:: -make_polyset(MayaNodeDesc *node_desc, const MDagPath &dag_path, - const MFnMesh &mesh, EggGroup *egg_group, - MayaShader *default_shader) { - MStatus status; - string name = mesh.name().asChar(); - - MObject mesh_object = mesh.object(); - bool maya_double_sided = false; - get_bool_attribute(mesh_object, "doubleSided", maya_double_sided); - - if (mayaegg_cat.is_spam()) { - mayaegg_cat.spam() - << " numPolygons: " - << mesh.numPolygons() - << "\n"; - mayaegg_cat.spam() - << " numVertices: " - << mesh.numVertices() - << "\n"; - } - - if (mesh.numPolygons() == 0) { - if (mayaegg_cat.is_debug()) { - mayaegg_cat.debug() - << "Ignoring empty mesh " << name << "\n"; - } - return; - } - - string vpool_name = name + ".verts"; - EggVertexPool *vpool = new EggVertexPool(vpool_name); - egg_group->add_child(vpool); - - // One way to convert the mesh would be to first get out all the vertices in - // the mesh and add them into the vpool, then when we traverse the polygons - // we would only have to index them into the vpool according to their Maya - // vertex index. - - // Unfortunately, since Maya may store multiple normals andor colors for - // each vertex according to which polygon it is in, that approach won't - // necessarily work. In egg, those split-property vertices have to become - // separate vertices. So instead of adding all the vertices up front, we'll - // start with an empty vpool, and add vertices to it on the fly. - - MObject component_obj; - MItMeshPolygon pi(dag_path, component_obj, &status); - if (!status) { - status.perror("MItMeshPolygon constructor"); - return; - } - - MObjectArray shaders; - MIntArray poly_shader_indices; - - status = mesh.getConnectedShaders(dag_path.instanceNumber(), - shaders, poly_shader_indices); - if (!status) { - status.perror("MFnMesh::getConnectedShaders"); - } - - // We will need to transform all vertices from world coordinate space into - // the vertex space appropriate to this node. Usually, this is the same - // thing as world coordinate space, and this matrix will be identity; but if - // the node is under an instance (particularly, for instance, a billboard) - // then the vertex space will be different from world space. - LMatrix4d vertex_frame_inv = egg_group->get_vertex_frame_inv(); - - // Save these modeling flags for the check below. - bool egg_vertex_color = false; - bool egg_double_sided = false; - if (egg_group->has_user_data(MayaEggGroupUserData::get_class_type())) { - MayaEggGroupUserData *user_data = - DCAST(MayaEggGroupUserData, egg_group->get_user_data()); - egg_vertex_color = user_data->_vertex_color; - egg_double_sided = user_data->_double_sided; - } - - bool double_sided = maya_double_sided; - if (!_respect_maya_double_sided) { - // If this flag is false, we respect the maya double-sided settings only - // if the egg "double-sided" flag is also set. - if (!egg_double_sided) { - double_sided = false; - } - } - - bool keep_all_uvsets = _keep_all_uvsets || node_desc->has_object_type("keep-all-uvsets"); - if (node_desc->has_object_type("keep-all-uvsets")) { - mayaegg_cat.info() << "will keep_all_uvsets" << endl; - } - - _shaders.bind_uvsets(mesh.object()); - - while (!pi.isDone()) { - EggPolygon *egg_poly = new EggPolygon; - egg_group->add_child(egg_poly); - - egg_poly->set_bface_flag(double_sided); - - // Determine the MayaShader for this particular polygon. There appears to - // be two diverging paths for any Maya node with a Material (MayaShader) - // on it This next bit kicks us out into mayaShader et al. to pull - // textures and everything else. - MayaShader *shader = nullptr; - int index = pi.index(); - nassertv(index >= 0 && index < (int)poly_shader_indices.length()); - int shader_index = poly_shader_indices[index]; - - if (shader_index != -1) { - nassertv(shader_index >= 0 && shader_index < (int)shaders.length()); - MObject engine = shaders[shader_index]; - shader = - _shaders.find_shader_for_shading_engine(engine, _legacy_shader); //head out to the other classes - // does this mean if we didn't find a Maya shader give it a default - // value anyway? - } else if (default_shader != nullptr) { - shader = default_shader; - } - - const MayaShaderColorDef *default_color_def = nullptr; - - // And apply the shader properties to the polygon. - if (shader != nullptr) { - set_shader_attributes(*egg_poly, *shader, true); - default_color_def = shader->get_color_def(); - } - - // Should we extract the color from the vertices? Normally, in Maya a - // texture completely replaces the vertex color, so we should ignore the - // vertex color if we have a texture. - - // However, this is an inconvenient property of Maya; sometimes we really - // do want both vertex color and texture applied to the same object. To - // allow this, we define the special egg flag "vertex-color", which when - // set indicates that we should respect the vertex color anyway. - - // Furthermore, if _always_show_vertex_color is true, we pretend that the - // "vertex-color" flag is always set. - bool ignore_vertex_color = false; - if ( default_color_def != nullptr) { - ignore_vertex_color = default_color_def->_has_texture && !(egg_vertex_color || _always_show_vertex_color); - } - - LColor poly_color(1.0f, 1.0f, 1.0f, 1.0f); - if (!ignore_vertex_color) { - // If we're respecting the vertex color, then remove the color - // specification from the polygon (so we can apply it to the vertices). - poly_color = egg_poly->get_color(); - egg_poly->clear_color(); - } - - // Get the vertices for the polygon. - long num_verts = pi.polygonVertexCount(); - long i; - LPoint3d centroid(0.0, 0.0, 0.0); - - if (default_color_def != nullptr && default_color_def->has_projection()) { - // If the shader has a projection, we may need to compute the polygon's - // centroid to avoid seams at the edges. - for (i = 0; i < num_verts; i++) { - MPoint p = pi.point(i, MSpace::kWorld); - LPoint3d p3d(p[0], p[1], p[2]); - p3d = p3d * vertex_frame_inv; - centroid += p3d; - } - centroid /= (double)num_verts; - } - for (i = 0; i < num_verts; i++) { - EggVertex vert; - - MPoint p = pi.point(i, MSpace::kWorld); - LPoint3d p3d(p[0] / p[3], p[1] / p[3], p[2] / p[3]); - p3d = p3d * vertex_frame_inv; - vert.set_pos(p3d); - - MVector n; - status = pi.getNormal(i, n, MSpace::kWorld); - if (!status) { - status.perror("MItMeshPolygon::getNormal"); - } else { - LNormald n3d(n[0], n[1], n[2]); - n3d = n3d * vertex_frame_inv; - vert.set_normal(n3d); - } - - // Go thru all the texture references for this primitive and set uvs - if (mayaegg_cat.is_spam()) { - if (shader != nullptr) { - mayaegg_cat.spam() << "shader->_color.size is " << shader->_color.size() << endl; - } - mayaegg_cat.spam() << "primitive->tref.size is " << egg_poly->get_num_textures() << endl; - } - for (size_t ti=0; ti< _shaders._uvset_names.size(); ++ti) { - // get the eggTexture pointer - string uvset_name(_shaders._uvset_names[ti]); - string panda_uvset_name = uvset_name; - if (panda_uvset_name == "map1") { - panda_uvset_name = "default"; - } - if (mayaegg_cat.is_spam()) { - mayaegg_cat.spam() << "--uvset_name :" << uvset_name << endl; - } - - // get the shader color def that matches this EggTexture Asad: - // optimizing uvset: to discard unused uvsets. This for loop figures - // out which ones are unused. - - bool keep_uv = keep_all_uvsets; - bool project_uv = false; - LTexCoordd uv_projection; - - if (shader != nullptr) { - for (size_t tj = 0; tj < shader->_all_maps.size(); ++tj) { - MayaShaderColorDef *def = shader->_all_maps[tj]; - if (def->_uvset_name == uvset_name) { - if (mayaegg_cat.is_spam()) { - mayaegg_cat.spam() << "matched colordef idx: " << tj << endl; - } - keep_uv = true; - if (def->has_projection()) { - project_uv = true; - uv_projection = def->project_uv(p3d, centroid); - } - break; - } - } - } - - // if uvset is not used don't add it to the vertex - if (!keep_uv) { - if (mayaegg_cat.is_spam()) { - mayaegg_cat.spam() << "discarding unused uvset " << uvset_name << endl; - } - continue; - } - - if (project_uv) { - // If the shader has a projection, use it instead of the polygon's - // built-in UV's. - vert.set_uv(panda_uvset_name, uv_projection); - } else { - // Get the UV's from the polygon. - float2 uvs; - MString uv_mstring(uvset_name.c_str()); - if (pi.hasUVs(uv_mstring, &status)) { - status = pi.getUV(i, uvs, &uv_mstring); - if (!status) { - status.perror("MItMeshPolygon::getUV"); - } else { - if (_round_uvs) { - if (uvs[0] > 1.0 || uvs[0] < -1.0) { - // apply upto 11000th precision, but round up - uvs[0] = (long)(uvs[0]*1000); - mayaegg_cat.debug() << "before rounding uvs[0]: " << uvs[0] << endl; - uvs[0] = (double)(round((double)uvs[0]/10.0)*10.0)/1000.0; - mayaegg_cat.debug() << "after rounding uvs[0]: " << uvs[0] << endl; - } - if (uvs[1] > 1.0 || uvs[1] < -1.0) { - uvs[1] = (long)(uvs[1]*1000); - mayaegg_cat.debug() << "before rounding uvs[1]: " << uvs[1] << endl; - uvs[1] = (double)(round((double)uvs[1]/10.0)*10.0)/1000.0; - mayaegg_cat.debug() << "after rounding uvs[1]: " << uvs[1] << endl; - } - } - vert.set_uv(panda_uvset_name, LTexCoordd(uvs[0], uvs[1])); - } - } - } - } - - if (!ignore_vertex_color) { - if (mayaegg_cat.is_spam()) { - mayaegg_cat.spam() << "poly_color = " << poly_color << endl; - } - set_vertex_color(vert,pi,i,shader,poly_color); - } - - vert.set_external_index(pi.vertexIndex(i, &status)); - vert.set_external_index2(pi.normalIndex(i, &status)); - - egg_poly->add_vertex(vpool->create_unique_vertex(vert)); - } - - // Also get the face normal for the polygon. - LNormald face_normal; - bool got_face_normal = false; - - MVector n; - status = pi.getNormal(n, MSpace::kWorld); - if (!status) { - status.perror("MItMeshPolygon::getNormal face"); - } else { - face_normal.set(n[0], n[1], n[2]); - face_normal = face_normal * vertex_frame_inv; - got_face_normal = true; - egg_poly->set_normal(face_normal); - } - - // Now, check that the vertex ordering is consistent with the direction of - // the normals. If not, reverse the vertex ordering (since we have seen - // cases where Maya sets this in contradiction to its normals). - LNormald order_normal; - if (got_face_normal && egg_poly->calculate_normal(order_normal)) { - if (order_normal.dot(face_normal) < 0.0) { - egg_poly->reverse_vertex_ordering(); - if (mayaegg_cat.is_debug()) { - mayaegg_cat.debug() - << "reversing polygon\n"; - } - } - } - - pi.next(); - } - if (mayaegg_cat.is_spam()) { - mayaegg_cat.spam() << "done traversing polys" << endl; - } - - // Now that we've added all the polygons (and created all the vertices), go - // back through the vertex pool and set up the appropriate joint membership - // for each of the vertices. - bool got_weights = false; - - pvector joints; - MFloatArray weights; - if (_animation_convert == AC_model) { - got_weights = - get_vertex_weights(dag_path, mesh, joints, weights); - } - - if (got_weights && !joints.empty()) { - int num_joints = joints.size(); - int num_weights = (int)weights.length(); - int num_verts = num_weights / num_joints; - // The number of weights should be an even multiple of verts * joints. - nassertv(num_weights == num_verts * num_joints); - - EggVertexPool::iterator vi; - for (vi = vpool->begin(); vi != vpool->end(); ++vi) { - EggVertex *vert = (*vi); - int maya_vi = vert->get_external_index(); - nassertv(maya_vi >= 0 && maya_vi < num_verts); - - for (int ji = 0; ji < num_joints; ++ji) { - PN_stdfloat weight = weights[maya_vi * num_joints + ji]; - if (weight != 0.0f) { - EggGroup *joint = joints[ji]; - if (joint != nullptr) { - joint->ref_vertex(vert, weight); - } - } - } - } - } - - - // We also need to compute the vertex morphs for the polyset, based on - // whatever blend shapes may be present. This is similar to the code in - // make_nurbs_surface(), except that since we don't have a one-to-one - // relationship of egg vertices to Maya vertices, we have to get the morphs - // down here, after we have added all of the egg vertices. - - if (_animation_convert == AC_model) { - int num_orig_mesh_verts = mesh.numVertices(); - - int num_sliders = node_desc->get_num_blend_descs(); - for (int i = 0; i < num_sliders; i++) { - MayaBlendDesc *blend_desc = node_desc->get_blend_desc(i); - - // Temporarily push the slider up to 1.0 so we can see what the surface - // looks like at that value. - blend_desc->set_slider(1.0); - - // We have to get the mesh object from the dag again after fiddling with - // the slider. - MFnMesh blend_mesh(dag_path, &status); - if (!status) { - mayaegg_cat.warning() - << name << " no longer has a mesh after applying " - << blend_desc->get_name() << "\n"; - - } else { - if (blend_mesh.numVertices() != num_orig_mesh_verts) { - mayaegg_cat.warning() - << "Ignoring " << blend_desc->get_name() << " for " - << name << "; blend shape has " << blend_mesh.numVertices() - << " vertices while original shape has " - << num_orig_mesh_verts << ".\n"; - - } else { - MPointArray verts; - status = blend_mesh.getPoints(verts, MSpace::kWorld); - if (!status) { - status.perror("MFnMesh::getPoints"); - } else { - int num_verts = (int)verts.length(); - EggVertexPool::iterator vi; - for (vi = vpool->begin(); vi != vpool->end(); ++vi) { - EggVertex *vert = (*vi); - int maya_vi = vert->get_external_index(); - nassertv(maya_vi >= 0 && maya_vi < num_verts); - - const MPoint &m = verts[maya_vi]; - LPoint3d m3d(m[0] / m[3], m[1] / m[3], m[2] / m[3]); - m3d = m3d * vertex_frame_inv; - - LVector3d delta = m3d - vert->get_pos3(); - if (!delta.almost_equal(LVector3d::zero())) { - EggMorphVertex dxyz(blend_desc->get_name(), delta); - vert->_dxyzs.insert(dxyz); - } - } - } - - MFloatVectorArray norms; - status = blend_mesh.getNormals(norms, MSpace::kWorld); - if (!status) { - status.perror("MFnMesh::getNormals"); - } else { - int num_norms = (int)norms.length(); - EggVertexPool::iterator vi; - for (vi = vpool->begin(); vi != vpool->end(); ++vi) { - EggVertex *vert = (*vi); - int maya_vi = vert->get_external_index2(); - nassertv(maya_vi >= 0 && maya_vi < num_norms); - - const MFloatVector &m = norms[maya_vi]; - LVector3d m3d(m[0], m[1], m[2]); - m3d = m3d * vertex_frame_inv; - - LNormald delta = m3d - vert->get_normal(); - if (!delta.almost_equal(LVector3d::zero())) { - EggMorphNormal dnormal(blend_desc->get_name(), delta); - vert->_dnormals.insert(dnormal); - } - } - } - } - } - - blend_desc->set_slider(0.0); - } - } -} - -/** - * Locators are used in Maya to indicate a particular position in space to the - * user or the modeler. We represent that in egg with an ordinary Group node, - * which we transform by the locator's position, so that the indicated point - * becomes the origin at this node and below. - */ -void MayaToEggConverter:: -make_locator(const MDagPath &dag_path, const MFnDagNode &dag_node, - EggGroup *egg_group) { - MStatus status; - - unsigned int num_children = dag_node.childCount(); - MObject locator; - bool found_locator = false; - for (unsigned int ci = 0; ci < num_children && !found_locator; ci++) { - locator = dag_node.child(ci); - found_locator = (locator.apiType() == MFn::kLocator); - } - - if (!found_locator) { - mayaegg_cat.error() - << "Couldn't find locator within locator node " - << dag_path.fullPathName().asChar() << "\n"; - return; - } - - LPoint3d p3d; - if (!get_vec3d_attribute(locator, "localPosition", p3d)) { - mayaegg_cat.error() - << "Couldn't get position of locator " - << dag_path.fullPathName().asChar() << "\n"; - return; - } - - // We need to convert the position to world coordinates. For some reason, - // Maya can only tell it to us in local coordinates. - MMatrix mat = dag_path.inclusiveMatrix(&status); - if (!status) { - status.perror("Can't get coordinate space for locator"); - return; - } - LMatrix4d n2w(mat[0][0], mat[0][1], mat[0][2], mat[0][3], - mat[1][0], mat[1][1], mat[1][2], mat[1][3], - mat[2][0], mat[2][1], mat[2][2], mat[2][3], - mat[3][0], mat[3][1], mat[3][2], mat[3][3]); - p3d = p3d * n2w; - - // Now convert the locator point into the group's space. - p3d = p3d * egg_group->get_node_frame_inv(); - - egg_group->add_translate3d(p3d); -} - -/** - * Locators are used in Maya to indicate a particular position in space to the - * user or the modeler. We represent that in egg with an ordinary Group node, - * which we transform by the locator's position, so that the indicated point - * becomes the origin at this node and below. - */ -void MayaToEggConverter:: -make_camera_locator(const MDagPath &dag_path, const MFnDagNode &dag_node, - EggGroup *egg_group) { - MStatus status; - - unsigned int num_children = dag_node.childCount(); - MObject locator; - bool found_camera = false; - for (unsigned int ci = 0; ci < num_children && !found_camera; ci++) { - locator = dag_node.child(ci); - found_camera = (locator.apiType() == MFn::kCamera); - } - - if (!found_camera) { - mayaegg_cat.error() - << "Couldn't find camera" - << dag_path.fullPathName().asChar() << "\n"; - return; - } - MFnCamera camera (dag_path, &status); - if ( !status ) { - status.perror("MFnCamera constructor"); - return; - } - MPoint eyePoint = camera.eyePoint(MSpace::kWorld); - LPoint3d p3d (eyePoint.x, eyePoint.y, eyePoint.z); - - // Now convert the locator point into the group's space. - p3d = p3d * egg_group->get_node_frame_inv(); - - egg_group->add_translate3d(p3d); -} - - -/** - * Locators are used in Maya to indicate a particular position in space to the - * user or the modeler. We represent that in egg with an ordinary Group node, - * which we transform by the locator's position, so that the indicated point - * becomes the origin at this node and below. - */ -void MayaToEggConverter:: -make_light_locator(const MDagPath &dag_path, const MFnDagNode &dag_node, - EggGroup *egg_group) { - MStatus status; - - unsigned int num_children = dag_node.childCount(); - MObject locator; - bool found_alight = false; - bool found_dlight = false; - bool found_plight = false; - for (unsigned int ci = 0; ci < num_children && !found_alight && !found_dlight && !found_plight; ci++) { - locator = dag_node.child(ci); - found_alight = (locator.apiType() == MFn::kAmbientLight); - found_dlight = (locator.apiType() == MFn::kDirectionalLight); - found_plight = (locator.apiType() == MFn::kPointLight); - } - - if (!found_alight && !found_dlight && !found_plight) { - mayaegg_cat.error() - << "Couldn't find light within locator node " - << dag_path.fullPathName().asChar() << "\n"; - return; - } - - LPoint3d p3d; - - // We need to convert the position to world coordinates. For some reason, - // Maya can only tell it to us in local coordinates. - MMatrix mat = dag_path.inclusiveMatrix(&status); - if (!status) { - status.perror("Can't get coordinate space for light"); - return; - } - LMatrix4d n2w(mat[0][0], mat[0][1], mat[0][2], mat[0][3], - mat[1][0], mat[1][1], mat[1][2], mat[1][3], - mat[2][0], mat[2][1], mat[2][2], mat[2][3], - mat[3][0], mat[3][1], mat[3][2], mat[3][3]); - p3d = p3d * n2w; - - // Now convert the locator point into the group's space. - p3d = p3d * egg_group->get_node_frame_inv(); - - egg_group->add_translate3d(p3d); -} - - -/** - * - */ -bool MayaToEggConverter:: -get_vertex_weights(const MDagPath &dag_path, const MFnMesh &mesh, - pvector &joints, MFloatArray &weights) { - MStatus status; - - // Since we are working with a mesh the input attribute that creates the - // mesh is named "inMesh" - MObject attr = mesh.attribute("inMesh"); - - // Create the plug to the "inMesh" attribute then use the DG iterator to - // walk through the DG, at the node level. - MPlug history(mesh.object(), attr); - MItDependencyGraph it(history, MFn::kDependencyNode, - MItDependencyGraph::kUpstream, - MItDependencyGraph::kDepthFirst, - MItDependencyGraph::kNodeLevel); - - while (!it.isDone()) { - // We will walk along the node level of the DG until we spot a skinCluster - // node. - MObject c_node = it.thisNode(); - if (c_node.hasFn(MFn::kSkinClusterFilter)) { - // We've found the cluster handle. Try to get the weight data. - MFnSkinCluster cluster(c_node, &status); - if (!status) { - status.perror("MFnSkinCluster constructor"); - return false; - } - - // Get the set of objects that influence the vertices of this mesh. - // Hopefully these will all be joints. - MDagPathArray influence_objects; - cluster.influenceObjects(influence_objects, &status); - if (!status) { - status.perror("MFnSkinCluster::influenceObjects"); - - } else { - // Fill up the vector with the corresponding table of egg groups for - // each joint. - joints.clear(); - for (unsigned oi = 0; oi < influence_objects.length(); oi++) { - MDagPath joint_dag_path = influence_objects[oi]; - MayaNodeDesc *joint_node_desc = _tree.build_node(joint_dag_path); - EggGroup *joint = _tree.get_egg_group(joint_node_desc); - joints.push_back(joint); - } - - // Now use a component object to retrieve all of the weight data in - // one API call. - MFnSingleIndexedComponent sic; - MObject sic_object = sic.create(MFn::kMeshVertComponent); - sic.setCompleteData(mesh.numVertices()); - unsigned influence_count; - - status = cluster.getWeights(dag_path, sic_object, - weights, influence_count); - if (!status) { - status.perror("MFnSkinCluster::getWeights"); - } else { - if (influence_count != influence_objects.length()) { - mayaegg_cat.error() - << "MFnSkinCluster::influenceObjects() returns " - << influence_objects.length() - << " objects, but MFnSkinCluster::getWeights() reports " - << influence_count << " objects.\n"; - - } else { - // We've got the weights and the set of objects. That's all we - // need. - return true; - } - } - } - } else if (c_node.hasFn(MFn::kWeightGeometryFilt)) { - // We've found the joint cluster handle. (rigid Binding) - MFnWeightGeometryFilter cluster(c_node, &status); - if (!status) { - status.perror("MFnWeightGeometryFilter constructor"); - return false; - } - - MPlug matrix_plug = cluster.findPlug("matrix"); - if (!matrix_plug.isNull()) { - MPlugArray matrix_pa; - matrix_plug.connectedTo(matrix_pa, true, false, &status); - if (!status) { - status.perror("Can't find connected Joint"); - } else { - MObject jointObj = matrix_pa[0].node(); - MFnIkJoint jointFn(jointObj, &status); - if (!status) { - status.perror("Can't find connected JointDag"); - } else { - joints.clear(); - MDagPath joint_dag_path = MDagPath(); - status = jointFn.getPath(joint_dag_path); - if (!status) { - status.perror("MFnIkJoint::dagPath"); - } else { - MayaNodeDesc *joint_node_desc = _tree.build_node(joint_dag_path); - EggGroup *joint = _tree.get_egg_group(joint_node_desc); - joints.push_back(joint); - - // Now use a component object to retrieve all of the weight data - // in one API call. - MFnSingleIndexedComponent sic; - MObject sic_object = sic.create(MFn::kMeshVertComponent); - sic.setCompleteData(mesh.numVertices()); - - status = cluster.getWeights(dag_path, sic_object, - weights); - if (!status) { - status.perror("MFnWeightGeometryFilter::getWeights"); - } else { - // We've got the weights and the set of objects. That's all - // we need. - return true; - } - } - } - } - } - } - - it.next(); - } - - // The mesh was not soft-skinned. - return false; -} - -/** - * As above, for a NURBS surface instead of a polygon mesh. - */ -bool MayaToEggConverter:: -get_vertex_weights(const MDagPath &dag_path, const MFnNurbsSurface &surface, - pvector &joints, MFloatArray &weights) { - MStatus status; - - // Since we are working with a NURBS surface the input attribute that - // creates the surface is named "create" - MObject attr = surface.attribute("create"); - - // Create the plug to the "create" attribute then use the DG iterator to - // walk through the DG, at the node level. - MPlug history(surface.object(), attr); - MItDependencyGraph it(history, MFn::kDependencyNode, - MItDependencyGraph::kUpstream, - MItDependencyGraph::kDepthFirst, - MItDependencyGraph::kNodeLevel); - - while (!it.isDone()) { - // We will walk along the node level of the DG until we spot a skinCluster - // node. - MObject c_node = it.thisNode(); - if (c_node.hasFn(MFn::kSkinClusterFilter)) { - // We've found the cluster handle. Try to get the weight data. - MFnSkinCluster cluster(c_node, &status); - if (!status) { - status.perror("MFnSkinCluster constructor"); - return false; - } - - // Get the set of objects that influence the vertices of this surface. - // Hopefully these will all be joints. - MDagPathArray influence_objects; - cluster.influenceObjects(influence_objects, &status); - if (!status) { - status.perror("MFnSkinCluster::influenceObjects"); - - } else { - // Fill up the vector with the corresponding table of egg groups for - // each joint. - joints.clear(); - for (unsigned oi = 0; oi < influence_objects.length(); oi++) { - MDagPath joint_dag_path = influence_objects[oi]; - MayaNodeDesc *joint_node_desc = _tree.build_node(joint_dag_path); - EggGroup *joint = _tree.get_egg_group(joint_node_desc); - joints.push_back(joint); - } - - // Now use a component object to retrieve all of the weight data in - // one API call. - MFnDoubleIndexedComponent dic; - MObject dic_object = dic.create(MFn::kSurfaceCVComponent); - dic.setCompleteData(surface.numCVsInU(), surface.numCVsInV()); - unsigned influence_count; - - status = cluster.getWeights(dag_path, dic_object, - weights, influence_count); - if (!status) { - status.perror("MFnSkinCluster::getWeights"); - } else { - if (influence_count != influence_objects.length()) { - mayaegg_cat.error() - << "MFnSkinCluster::influenceObjects() returns " - << influence_objects.length() - << " objects, but MFnSkinCluster::getWeights() reports " - << influence_count << " objects.\n"; - - } else { - // We've got the weights and the set of objects. That's all we - // need. - return true; - } - } - } - } - - it.next(); - } - - // The surface was not soft-skinned. - return false; -} - -/** - * Applies the known shader attributes to the indicated egg primitive. Note: - * For multi-textures, Maya lists the top most texture in slot 0. But Panda - * puts the base texture at slot 0. Hence I parse the list of textures from - * last to first. - */ -void MayaToEggConverter:: -set_shader_attributes(EggPrimitive &primitive, const MayaShader &shader, - bool mesh) { - if (shader._legacy_mode) { - set_shader_legacy(primitive, shader, mesh); - } else { - set_shader_modern(primitive, shader, mesh); - } -} - -/** - * The modern implementation of set_shader_attributes. - * - * In the modern codepath, the MayaShader is a direct, literal representation - * of a list of EggTextures. All this exporter has to do is translate the - * list without interpretation. All the complex interpretation is handled - * elsewhere, in the MayaShader module. - */ -void MayaToEggConverter:: -set_shader_modern(EggPrimitive &primitive, const MayaShader &shader, - bool mesh) { - - for (size_t idx=0; idx < shader._all_maps.size(); idx++) { - MayaShaderColorDef *def = shader._all_maps[idx]; - if ((def->_is_alpha)&&(def->_opposite != 0)) { - // This texture represents an alpha-filename. It doesn't get its own - // - continue; - } - - EggTexture tex(shader.get_name(), ""); - tex.set_format(def->_is_alpha ? EggTexture::F_alpha : EggTexture::F_rgb); - apply_texture_filename(tex, *def); - if (def->_opposite) { - apply_texture_alpha_filename(tex, *def); - } - apply_texture_uvprops(tex, *def); - apply_texture_blendtype(tex, *def); - tex.set_uv_name(def->get_panda_uvset_name()); - - EggTexture *new_tex = - _textures.create_unique_texture(tex, ~0); - primitive.add_texture(new_tex); - } -} - -/** - * The legacy implementation of set_shader_attributes. The old behavior of - * the exporter is just plain weird. It seems to be a result of an - * inexperienced coder who made some core mistakes, and then patched them up - * with kludges. It seems to produce plausible results in certain specific - * cases, but overall, it doesn't make any sense. Unfortunately, this weird - * behavior cannot be discarded - vast numbers of 3D models have been created - * that rely on this behavior. The solution is to compartmentalize the - * weirdness. The legacy codepath, when activated, implements the old weird - * behavior. A brand-new codepath that shares almost nothing with the legacy - * codepath implements a much more straightforward behavior. - */ -void MayaToEggConverter:: -set_shader_legacy(EggPrimitive &primitive, const MayaShader &shader, - bool mesh) { - - // determine if the base texture or any of the top texture need to be rgb - // only - MayaShaderColorDef *color_def = nullptr; - bool is_rgb = false; - bool is_decal = false; - bool is_interpolate = false; - int i; - // last shader is the base so lets skip it - for (i=0; i<(int)shader._color.size()-1; ++i) { - color_def = shader.get_color_def(i); - if (color_def->_has_texture) { - if ((EggTexture::EnvType)color_def->_interpolate) { - is_interpolate = true; - } - else if ((EggTexture::EnvType)color_def->_blend_type == EggTexture::ET_modulate) { - // Maya's multiply is slightly different than panda's. Unless, - // _keep_alpha is set, we are dropping the alpha. - if (!color_def->_keep_alpha) - is_rgb = true; // modulate forces the alpha to be ignored - } - else if ((EggTexture::EnvType)color_def->_blend_type == EggTexture::ET_decal) { - is_decal = true; - } - } - } - - // we don't want an extra light stage for interpolate mode, it takes care of - // automatically - if (is_interpolate) - is_decal = false; - - // new decal mode needs an extra dummy layers of textureStage - EggTexture *dummy_tex = nullptr; - string dummy_uvset_name; - - // In Maya, a polygon is either textured or colored. The texture, if - // present, replaces the color. Also now there could be multiple textures - const MayaShaderColorDef &trans_def = shader._transparency; - for (i=shader._color.size()-1; i>=0; --i) { - color_def = shader.get_color_def(i); - if (mayaegg_cat.is_spam()) { - mayaegg_cat.spam() << "slot " << i << ":got color_def: " << color_def << endl; - } - if (color_def->_has_texture || trans_def._has_texture) { - EggTexture tex(shader.get_name(), ""); - if (mayaegg_cat.is_spam()) { - mayaegg_cat.spam() << "got shader name:" << shader.get_name() << endl; - mayaegg_cat.spam() << "ssa:texture name[" << i << "]: " << color_def->_texture_name << endl; - } - - string uvset_name = _shaders.find_uv_link(color_def->_texture_name); - if (mayaegg_cat.is_spam()) { - mayaegg_cat.spam() << "ssa:corresponding uvset name is " << uvset_name << endl; - } - - if (color_def->_has_texture) { - // If we have a texture on color, apply it as the filename. if - // (mayaegg_cat.is_debug()) { mayaegg_cat.debug() << "ssa:got texture - // name" << color_def->_texture_filename << endl; } - Filename filename = Filename::from_os_specific(color_def->_texture_filename); - Filename fullpath, outpath; - _path_replace->full_convert_path(filename, get_model_path(), fullpath, outpath); - tex.set_filename(outpath); - tex.set_fullpath(fullpath); - apply_texture_uvprops(tex, *color_def); - - // If we also have a texture on transparency, apply it as the alpha - // filename. - if (trans_def._has_texture) { - if (color_def->_wrap_u != trans_def._wrap_u || - color_def->_wrap_u != trans_def._wrap_u) { - mayaegg_cat.warning() - << "Shader " << shader.get_name() - << " has contradictory wrap modes on color and texture.\n"; - } - - if (!compare_texture_uvprops(tex, trans_def)) { - // Only report each broken shader once. - static pset bad_shaders; - if (bad_shaders.insert(shader.get_name()).second) { - mayaegg_cat.error() - << "Color and transparency texture properties differ on shader " - << shader.get_name() << "\n"; - } - } - // tex.set_format(EggTexture::F_rgba); - - // We should try to be smarter about whether the transparency value - // is connected to the texture's alpha channel or to its grayscale - // channel. However, I'm not sure how to detect this at the moment; - // rather than spending days trying to figure out, for now I'll just - // assume that if the same texture image is used for both color and - // transparency, then the artist meant to use the alpha channel for - // transparency. - if (trans_def._texture_filename == color_def->_texture_filename) { - // That means that we don't need to do anything special: use all - // the channels of the texture. - - } else { - // Otherwise, pull the alpha channel from the other image file. - // Ideally, we should figure out which channel from the other - // image supplies alpha (and specify this via - // set_alpha_file_channel()), but for now we assume it comes from - // the grayscale data. - filename = Filename::from_os_specific(trans_def._texture_filename); - _path_replace->full_convert_path(filename, get_model_path(), - fullpath, outpath); - tex.set_alpha_filename(outpath); - tex.set_alpha_fullpath(fullpath); - } - } else { - // If there is no transparency texture specified, we don't have any - // transparency, so tell the egg format to ignore any alpha channel - // that might be on the color texture. - // tex.set_format(EggTexture::F_rgb); - } - - if (shader._color.size() > 1) { - // if multi-textured, first texture in maya is on top, so last - // shader on the list is the base one, which should always pick up - // the alpha from the texture file. But the top textures may have - // to strip the alpha - if ((size_t)i != shader._color.size() - 1) { - if (!i && is_interpolate) { - // this is the grass path mode where alpha on this texture - // determines whether to show layer1 or layer2. Since by now - // other layers are set lets change those to get this effect - tex.set_combine_mode(EggTexture::CC_rgb, EggTexture::CM_interpolate); - tex.set_combine_source(EggTexture::CC_rgb, 0, EggTexture::CS_previous); - tex.set_combine_operand(EggTexture::CC_rgb, 0, EggTexture::CO_src_color); - tex.set_combine_source(EggTexture::CC_rgb, 1, EggTexture::CS_last_saved_result); - tex.set_combine_operand(EggTexture::CC_rgb, 1, EggTexture::CO_src_color); - tex.set_combine_source(EggTexture::CC_rgb, 2, EggTexture::CS_texture); - tex.set_combine_operand(EggTexture::CC_rgb, 2, EggTexture::CO_src_alpha); - - tex.set_combine_mode(EggTexture::CC_alpha, EggTexture::CM_interpolate); - tex.set_combine_source(EggTexture::CC_alpha, 0, EggTexture::CS_previous); - tex.set_combine_operand(EggTexture::CC_alpha, 0, EggTexture::CO_src_alpha); - tex.set_combine_source(EggTexture::CC_alpha, 1, EggTexture::CS_last_saved_result); - tex.set_combine_operand(EggTexture::CC_alpha, 1, EggTexture::CO_src_alpha); - tex.set_combine_source(EggTexture::CC_alpha, 2, EggTexture::CS_texture); - tex.set_combine_operand(EggTexture::CC_alpha, 2, EggTexture::CO_src_alpha); - } - else { - if (is_interpolate) { - tex.set_combine_mode(EggTexture::CC_rgb, EggTexture::CM_modulate); - tex.set_combine_source(EggTexture::CC_rgb, 0, EggTexture::CS_primary_color); - tex.set_combine_operand(EggTexture::CC_rgb, 0, EggTexture::CO_src_color); - tex.set_combine_source(EggTexture::CC_rgb, 1, EggTexture::CS_texture); - tex.set_combine_operand(EggTexture::CC_rgb, 1, EggTexture::CO_src_color); - } - else { - tex.set_env_type((EggTexture::EnvType)color_def->_blend_type); - if (tex.get_env_type() == EggTexture::ET_modulate) { - if (color_def->_has_alpha_channel) { - // lets caution the artist that they should not be using a - // alpha channel on this texture. - if (mayaegg_cat.is_spam()) { - maya_cat.spam() - << color_def->_texture_name - << " should not have alpha channel in multiply mode: ignoring\n"; - } - } - if (is_rgb) { - // tex.set_alpha_mode(EggRenderMode::AM_off); force - // alpha off - tex.set_format(EggTexture::F_rgb); // Change the format to be rgb only - } - } - } - } - } - else { - if (is_interpolate) { - // base shader need to save result - tex.set_saved_result(true); - } - else if (is_decal) { - // decal in classic time, always overwrote the base color. That - // causes problem when the polygon wants to be lit or wants to - // retain vertexpolygon color In the new decal mode, we achieve - // this with a third dummy layer copy this layer to a new dummy - // layer - EggTexture texDummy(shader.get_name()+".dummy", ""); - if (mayaegg_cat.is_debug()) { - mayaegg_cat.debug() << "creating dummy shader: " << texDummy.get_name() << endl; - } - texDummy.set_filename(outpath); - texDummy.set_fullpath(fullpath); - apply_texture_uvprops(texDummy, *color_def); - texDummy.set_combine_mode(EggTexture::CC_rgb, EggTexture::CM_modulate); - texDummy.set_combine_source(EggTexture::CC_rgb, 0, EggTexture::CS_primary_color); - texDummy.set_combine_operand(EggTexture::CC_rgb, 0, EggTexture::CO_src_color); - texDummy.set_combine_source(EggTexture::CC_rgb, 1, EggTexture::CS_previous); - texDummy.set_combine_operand(EggTexture::CC_rgb, 1, EggTexture::CO_src_color); - dummy_tex = _textures.create_unique_texture(texDummy, ~0); - - // make this layer ET_replace - tex.set_env_type(EggTexture::ET_replace); - } - } - } - } else { // trans_def._has_texture - // We have a texture on transparency only. Apply it as the primary - // filename, and set the format accordingly. - Filename filename = Filename::from_os_specific(trans_def._texture_filename); - Filename fullpath,outpath; - _path_replace->full_convert_path(filename, get_model_path(), - fullpath, outpath); - tex.set_filename(outpath); - tex.set_fullpath(fullpath); - tex.set_format(EggTexture::F_alpha); - apply_texture_uvprops(tex, trans_def); - } - - if (mayaegg_cat.is_debug()) { - mayaegg_cat.debug() << "ssa:tref_name:" << tex.get_name() << endl; - } - if (is_rgb && i == (int)shader._color.size()-1) { - // make base layer rgb only - tex.set_format(EggTexture::F_rgb); // Change the format to be rgb only - } - EggTexture *new_tex = - _textures.create_unique_texture(tex, ~0); - - if (mesh) { - if (uvset_name.find("not found") == string::npos) { - primitive.add_texture(new_tex); - color_def->_uvset_name.assign(uvset_name.c_str()); - if (uvset_name != "map1") { - new_tex->set_uv_name(uvset_name); - } - if (i == (int)shader._color.size()-1 && is_decal) { - dummy_uvset_name.assign(color_def->_uvset_name); - } - } - } else { - primitive.add_texture(new_tex); - if (color_def->_uvset_name != "map1") { - new_tex->set_uv_name(color_def->_uvset_name); - } - } - } - } - if (dummy_tex != nullptr) { - primitive.add_texture(dummy_tex); - dummy_tex->set_uv_name(dummy_uvset_name); - } - // Also apply an overall color to the primitive. - LColor rgba = shader.get_rgba(); - if (mayaegg_cat.is_spam()) { - mayaegg_cat.spam() << "ssa:rgba = " << rgba << endl; - } - - // The existence of a texture on either color channel completely replaces - // the corresponding flat color. - if (color_def && color_def->_has_texture) { - rgba[0] = 1.0f; - rgba[1] = 1.0f; - rgba[2] = 1.0f; - } - if (trans_def._has_texture) { - rgba[3] = 1.0f; - } - - // But the color gain always gets applied. - if (color_def) { - rgba[0] *= color_def->_color_gain[0]; - rgba[1] *= color_def->_color_gain[1]; - rgba[2] *= color_def->_color_gain[2]; - rgba[3] *= color_def->_color_gain[3]; - if (mayaegg_cat.is_spam()) { - mayaegg_cat.spam() << "ssa:rgba = " << rgba << endl; - } - } - - primitive.set_color(rgba); - - if (mayaegg_cat.is_spam()) { - mayaegg_cat.spam() << " set_shader_attributes : end\n"; - } -} - -/** - * Applies all the appropriate texture properties to the EggTexture object, - * including wrap modes and texture matrix. - */ -void MayaToEggConverter:: -apply_texture_uvprops(EggTexture &tex, const MayaShaderColorDef &color_def) { - // Let's mipmap all textures by default. - tex.set_minfilter(EggTexture::FT_linear_mipmap_linear); - tex.set_magfilter(EggTexture::FT_linear); - - EggTexture::WrapMode wrap_u = color_def._wrap_u ? EggTexture::WM_repeat : EggTexture::WM_clamp; - EggTexture::WrapMode wrap_v = color_def._wrap_v ? EggTexture::WM_repeat : EggTexture::WM_clamp; - - tex.set_wrap_u(wrap_u); - tex.set_wrap_v(wrap_v); - - LMatrix3d mat = color_def.compute_texture_matrix(); - if (!mat.almost_equal(LMatrix3d::ident_mat())) { - tex.set_transform2d(mat); - } -} - -/** - * Applies the blendtype to the EggTexture. - */ -void MayaToEggConverter:: -apply_texture_blendtype(EggTexture &tex, const MayaShaderColorDef &color_def) { - switch (color_def._blend_type) { - case MayaShaderColorDef::BT_unspecified: - tex.set_env_type(EggTexture::ET_unspecified); - return; - case MayaShaderColorDef::BT_modulate: - tex.set_env_type(EggTexture::ET_modulate); - return; - case MayaShaderColorDef::BT_decal: - tex.set_env_type(EggTexture::ET_decal); - return; - case MayaShaderColorDef::BT_blend: - tex.set_env_type(EggTexture::ET_blend); - return; - case MayaShaderColorDef::BT_replace: - tex.set_env_type(EggTexture::ET_replace); - return; - case MayaShaderColorDef::BT_add: - tex.set_env_type(EggTexture::ET_add); - return; - case MayaShaderColorDef::BT_blend_color_scale: - tex.set_env_type(EggTexture::ET_blend_color_scale); - return; - case MayaShaderColorDef::BT_modulate_glow: - tex.set_env_type(EggTexture::ET_modulate_glow); - return; - case MayaShaderColorDef::BT_modulate_gloss: - tex.set_env_type(EggTexture::ET_modulate_gloss); - return; - case MayaShaderColorDef::BT_normal: - tex.set_env_type(EggTexture::ET_normal); - return; - case MayaShaderColorDef::BT_normal_height: - tex.set_env_type(EggTexture::ET_normal_height); - return; - case MayaShaderColorDef::BT_glow: - tex.set_env_type(EggTexture::ET_glow); - return; - case MayaShaderColorDef::BT_gloss: - tex.set_env_type(EggTexture::ET_gloss); - return; - case MayaShaderColorDef::BT_height: - tex.set_env_type(EggTexture::ET_height); - return; - case MayaShaderColorDef::BT_selector: - tex.set_env_type(EggTexture::ET_selector); - return; - } -} - -/** - * Applies the filename to the EggTexture. - */ -void MayaToEggConverter:: -apply_texture_filename(EggTexture &tex, const MayaShaderColorDef &def) { - Filename filename = Filename::from_os_specific(def._texture_filename); - Filename fullpath, outpath; - _path_replace->full_convert_path(filename, get_model_path(), fullpath, outpath); - tex.set_filename(outpath); - tex.set_fullpath(fullpath); -} - -/** - * Applies the alpha filename to the EggTexture. - */ -void MayaToEggConverter:: -apply_texture_alpha_filename(EggTexture &tex, const MayaShaderColorDef &def) { - if (def._opposite) { - tex.set_format(EggTexture::F_rgba); - if (def._opposite->_texture_filename != def._texture_filename) { - Filename filename = Filename::from_os_specific(def._opposite->_texture_filename); - Filename fullpath, outpath; - _path_replace->full_convert_path(filename, get_model_path(), fullpath, outpath); - tex.set_alpha_filename(outpath); - tex.set_alpha_fullpath(fullpath); - } - } -} - -/** - * Compares the texture properties already on the texture (presumably set by a - * previous call to apply_texture_uvprops()) and returns false if they differ - * from that specified by the indicated color_def object, or true if they - * match. - */ -bool MayaToEggConverter:: -compare_texture_uvprops(EggTexture &tex, - const MayaShaderColorDef &color_def) { - bool okflag = true; - - EggTexture::WrapMode wrap_u = color_def._wrap_u ? EggTexture::WM_repeat : EggTexture::WM_clamp; - EggTexture::WrapMode wrap_v = color_def._wrap_v ? EggTexture::WM_repeat : EggTexture::WM_clamp; - - if (wrap_u != tex.determine_wrap_u()) { - // Choose the more general of the two. - if (wrap_u == EggTexture::WM_repeat) { - tex.set_wrap_u(wrap_u); - } - okflag = false; - } - if (wrap_v != tex.determine_wrap_v()) { - if (wrap_v == EggTexture::WM_repeat) { - tex.set_wrap_v(wrap_v); - } - okflag = false; - } - - LMatrix3d m = color_def.compute_texture_matrix(); - LMatrix4d mat4(m(0, 0), m(0, 1), 0.0, m(0, 2), - m(1, 0), m(1, 1), 0.0, m(1, 2), - 0.0, 0.0, 1.0, 0.0, - m(2, 0), m(2, 1), 0.0, m(2, 2)); - if (!mat4.almost_equal(tex.get_transform3d())) { - okflag = false; - } - - return okflag; -} - -/** - * Recursively walks the egg hierarchy, reparenting "decal" type nodes below - * their corresponding "decalbase" type nodes, and setting the flags. - * - * Returns true on success, false if some nodes were incorrect. - */ -bool MayaToEggConverter:: -reparent_decals(EggGroupNode *egg_parent) { - bool okflag = true; - - // First, walk through all children of this node, looking for the one decal - // base, if any. - EggGroup *decal_base = nullptr; - pvector decal_children; - - EggGroupNode::iterator ci; - for (ci = egg_parent->begin(); ci != egg_parent->end(); ++ci) { - EggNode *child = (*ci); - if (child->is_of_type(EggGroup::get_class_type())) { - EggGroup *child_group = DCAST(EggGroup, child); - if (child_group->has_object_type("decalbase")) { - if (decal_base != nullptr) { - mayaegg_cat.error() - << "Two children of " << egg_parent->get_name() - << " both have decalbase set: " << decal_base->get_name() - << " and " << child_group->get_name() << "\n"; - okflag = false; - } - child_group->remove_object_type("decalbase"); - decal_base = child_group; - - } else if (child_group->has_object_type("decal")) { - child_group->remove_object_type("decal"); - decal_children.push_back(child_group); - } - } - } - - if (decal_base == nullptr) { - if (!decal_children.empty()) { - mayaegg_cat.warning() - << decal_children.front()->get_name() - << " has decal, but no sibling node has decalbase.\n"; - } - - } else { - if (decal_children.empty()) { - mayaegg_cat.warning() - << decal_base->get_name() - << " has decalbase, but no sibling nodes have decal.\n"; - - } else { - // All the decal children get moved to be a child of decal base. This - // usually will not affect the vertex positions, but it could if the - // decal base has a transform and the decal child is an instance node. - // So don't do that. - pvector::iterator di; - for (di = decal_children.begin(); di != decal_children.end(); ++di) { - EggGroup *child_group = (*di); - decal_base->add_child(child_group); - } - - // Also set the decal state on the base. - decal_base->set_decal_flag(true); - } - } - - // Now recurse on each of the child nodes. - for (ci = egg_parent->begin(); ci != egg_parent->end(); ++ci) { - EggNode *child = (*ci); - if (child->is_of_type(EggGroupNode::get_class_type())) { - EggGroupNode *child_group = DCAST(EggGroupNode, child); - if (!reparent_decals(child_group)) { - okflag = false; - } - } - } - - return okflag; -} - -/** - * Returns the TransformType value corresponding to the indicated string, or - * TT_invalid. - */ -MayaToEggConverter::TransformType MayaToEggConverter:: -string_transform_type(const string &arg) { - if (cmp_nocase(arg, "all") == 0) { - return TT_all; - } else if (cmp_nocase(arg, "model") == 0) { - return TT_model; - } else if (cmp_nocase(arg, "dcs") == 0) { - return TT_dcs; - } else if (cmp_nocase(arg, "none") == 0) { - return TT_none; - } else { - return TT_invalid; - } -} -/** - * Checks to see if we're using legacy or modern shaders and based on the - * result, it passes the vertex color calculations off to either the legacy or - * modern vertex color functions. - */ -void MayaToEggConverter:: -set_vertex_color(EggVertex &vert, MItMeshPolygon &pi, int vert_index, const MayaShader *shader, const LColor &color) { - if (shader == nullptr || shader->_legacy_mode) { - set_vertex_color_legacy(vert, pi, vert_index, shader, color); - } else { - set_vertex_color_modern(vert, pi, vert_index, shader, color); - } -} -/** - * Calls set_color on an EggVertex, determining the correct color values, - * based on the shader, vert_color Maya's vertex & flat color(s). This is the - * original implementation that works only on Lambert shaders/materials in - * Maya. - */ -void MayaToEggConverter:: -set_vertex_color_legacy(EggVertex &vert, MItMeshPolygon &pi, int vert_index, const MayaShader *shader, const LColor &color){ - if (pi.hasColor()) { - MColor c; - MStatus status = pi.getColor(c, vert_index); - if (!status) { - status.perror("MItMeshPolygon::getColor"); - } else { - // I saw instances where the color components exceeded 1.0 so lets clamp - // the values to 0 to 1 - c /= 1.0; - // The vertex color is a color scale that modifies the polygon color, - // not an override that replaces it. - vert.set_color(LColor(c.r * color[0], c.g * color[1], c.b * color[2], c.a * color[3])); - - if (mayaegg_cat.is_spam()) { - mayaegg_cat.spam() << "maya_color = " << c.r << " " << c.g << " " << c.b << " " << c.a << endl; - mayaegg_cat.spam() << "vert_color = " << vert.get_color() << endl; - } - } - } else { - vert.set_color(color); - } - -} -/** - * Calls set_color on an EggVertex, determining the correct color values, - * based on the shader, vert_color Maya's vertex & flat color(s). This - * implementation is designed to work specifically with Phong materials or - * shaders. - */ -void MayaToEggConverter:: -set_vertex_color_modern(EggVertex &vert, MItMeshPolygon &pi, int vert_index, const MayaShader *shader, const LColor &color) { - // If there's an explicit vertex color, output it. - if (pi.hasColor(vert_index)) { - MColor c; - MStatus status = pi.getColor(c, vert_index); - if (status) { - vert.set_color(LColor(c.r, c.g, c.b, c.a)); - return; - } - } - - // If there's no explicit color, use flat color, or white on a textured - // model. - if (shader->_color_maps.empty()) { - const LColord &c = shader->_flat_color; - vert.set_color(LColor((PN_stdfloat)c[0], (PN_stdfloat)c[1], (PN_stdfloat)c[2], (PN_stdfloat)c[3])); - } else { - // there's no explicit color anywhere, must be textured (or blank) - vert.set_color(LColor(1.0f, 1.0f, 1.0f, 1.0f)); - } -} diff --git a/pandatool/src/mayaegg/mayaToEggConverter.h b/pandatool/src/mayaegg/mayaToEggConverter.h deleted file mode 100644 index c2266e0096..0000000000 --- a/pandatool/src/mayaegg/mayaToEggConverter.h +++ /dev/null @@ -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 -#include -#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 ©); - 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 &joints, MFloatArray &weights); - bool get_vertex_weights(const MDagPath &dag_path, const MFnNurbsSurface &surface, - pvector &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 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 diff --git a/pandatool/src/mayaegg/p3mayaegg_composite1.cxx b/pandatool/src/mayaegg/p3mayaegg_composite1.cxx deleted file mode 100644 index 75ab5187af..0000000000 --- a/pandatool/src/mayaegg/p3mayaegg_composite1.cxx +++ /dev/null @@ -1,6 +0,0 @@ -#include "config_mayaegg.cxx" -#include "mayaEggGroupUserData.cxx" -#include "mayaBlendDesc.cxx" -#include "mayaNodeDesc.cxx" -#include "mayaNodeTree.cxx" -#include "mayaToEggConverter.cxx" diff --git a/pandatool/src/mayaprogs/blend_test.cxx b/pandatool/src/mayaprogs/blend_test.cxx deleted file mode 100644 index ed03fd3661..0000000000 --- a/pandatool/src/mayaprogs/blend_test.cxx +++ /dev/null @@ -1,240 +0,0 @@ - -#include -#include -#include -#include - -#ifndef _BOOL -#define _BOOL 1 -#endif - -#define REQUIRE_IOSTREAM - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -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; -} diff --git a/pandatool/src/mayaprogs/config_mayaloader.cxx b/pandatool/src/mayaprogs/config_mayaloader.cxx deleted file mode 100644 index 80ccd1f373..0000000000 --- a/pandatool/src/mayaprogs/config_mayaloader.cxx +++ /dev/null @@ -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)); -} diff --git a/pandatool/src/mayaprogs/eggImportOptions.mel b/pandatool/src/mayaprogs/eggImportOptions.mel deleted file mode 100644 index cf75a777a0..0000000000 --- a/pandatool/src/mayaprogs/eggImportOptions.mel +++ /dev/null @@ -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; -} diff --git a/pandatool/src/mayaprogs/eggToMaya.cxx b/pandatool/src/mayaprogs/eggToMaya.cxx deleted file mode 100644 index 36be9362db..0000000000 --- a/pandatool/src/mayaprogs/eggToMaya.cxx +++ /dev/null @@ -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 -#include -#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); -} diff --git a/pandatool/src/mayaprogs/eggToMaya.h b/pandatool/src/mayaprogs/eggToMaya.h deleted file mode 100644 index d18dc928d1..0000000000 --- a/pandatool/src/mayaprogs/eggToMaya.h +++ /dev/null @@ -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 diff --git a/pandatool/src/mayaprogs/eggToMayaBin.cxx b/pandatool/src/mayaprogs/eggToMayaBin.cxx deleted file mode 100644 index e388255aac..0000000000 --- a/pandatool/src/mayaprogs/eggToMayaBin.cxx +++ /dev/null @@ -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; -} diff --git a/pandatool/src/mayaprogs/eggToMayaClient.cxx b/pandatool/src/mayaprogs/eggToMayaClient.cxx deleted file mode 100644 index e3f95155f4..0000000000 --- a/pandatool/src/mayaprogs/eggToMayaClient.cxx +++ /dev/null @@ -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); -} diff --git a/pandatool/src/mayaprogs/mayaConversionClient.cxx b/pandatool/src/mayaprogs/mayaConversionClient.cxx deleted file mode 100644 index 83735f3186..0000000000 --- a/pandatool/src/mayaprogs/mayaConversionClient.cxx +++ /dev/null @@ -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; -} diff --git a/pandatool/src/mayaprogs/mayaConversionClient.h b/pandatool/src/mayaprogs/mayaConversionClient.h deleted file mode 100644 index 2685c7166d..0000000000 --- a/pandatool/src/mayaprogs/mayaConversionClient.h +++ /dev/null @@ -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 diff --git a/pandatool/src/mayaprogs/mayaConversionServer.cxx b/pandatool/src/mayaprogs/mayaConversionServer.cxx deleted file mode 100644 index 3557082ace..0000000000 --- a/pandatool/src/mayaprogs/mayaConversionServer.cxx +++ /dev/null @@ -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 // 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 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::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(); - } -} diff --git a/pandatool/src/mayaprogs/mayaConversionServer.h b/pandatool/src/mayaprogs/mayaConversionServer.h deleted file mode 100644 index c5d89910e0..0000000000 --- a/pandatool/src/mayaprogs/mayaConversionServer.h +++ /dev/null @@ -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 diff --git a/pandatool/src/mayaprogs/mayaEggImport.cxx b/pandatool/src/mayaprogs/mayaEggImport.cxx deleted file mode 100644 index 5e38271517..0000000000 --- a/pandatool/src/mayaprogs/mayaEggImport.cxx +++ /dev/null @@ -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 -#include - -#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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#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" ); -} diff --git a/pandatool/src/mayaprogs/mayaPview.cxx b/pandatool/src/mayaprogs/mayaPview.cxx deleted file mode 100644 index 1c956672b3..0000000000 --- a/pandatool/src/mayaprogs/mayaPview.cxx +++ /dev/null @@ -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 -#include -#include -#include -#include -#include -#include -#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 -#include -#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 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; -} diff --git a/pandatool/src/mayaprogs/mayaPview.h b/pandatool/src/mayaprogs/mayaPview.h deleted file mode 100644 index 79cff017f2..0000000000 --- a/pandatool/src/mayaprogs/mayaPview.h +++ /dev/null @@ -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 -#include -#include -#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 diff --git a/pandatool/src/mayaprogs/mayaSavePview.cxx b/pandatool/src/mayaprogs/mayaSavePview.cxx deleted file mode 100644 index 65a29236f3..0000000000 --- a/pandatool/src/mayaprogs/mayaSavePview.cxx +++ /dev/null @@ -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 -#include -#include -#include -#include -#include - -#include - -#ifdef _WIN32 -#include -#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; -} diff --git a/pandatool/src/mayaprogs/mayaSavePview.h b/pandatool/src/mayaprogs/mayaSavePview.h deleted file mode 100644 index 56a84bf14c..0000000000 --- a/pandatool/src/mayaprogs/mayaSavePview.h +++ /dev/null @@ -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 -#if MAYA_API_VERSION < 201600 -#include -#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 library instead -// of the old library. -#define REQUIRE_IOSTREAM -#endif // PHAVE_IOSTREAM - -#include -#include -#include - -/** - * 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 diff --git a/pandatool/src/mayaprogs/mayaToEgg.cxx b/pandatool/src/mayaprogs/mayaToEgg.cxx deleted file mode 100644 index 10a09d1798..0000000000 --- a/pandatool/src/mayaprogs/mayaToEgg.cxx +++ /dev/null @@ -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); -} diff --git a/pandatool/src/mayaprogs/mayaToEgg.h b/pandatool/src/mayaprogs/mayaToEgg.h deleted file mode 100644 index 237266f04e..0000000000 --- a/pandatool/src/mayaprogs/mayaToEgg.h +++ /dev/null @@ -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 diff --git a/pandatool/src/mayaprogs/mayaToEggBin.cxx b/pandatool/src/mayaprogs/mayaToEggBin.cxx deleted file mode 100644 index d65bdcae24..0000000000 --- a/pandatool/src/mayaprogs/mayaToEggBin.cxx +++ /dev/null @@ -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; -} diff --git a/pandatool/src/mayaprogs/mayaToEggClient.cxx b/pandatool/src/mayaprogs/mayaToEggClient.cxx deleted file mode 100644 index 066b41ae31..0000000000 --- a/pandatool/src/mayaprogs/mayaToEggClient.cxx +++ /dev/null @@ -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); -} diff --git a/pandatool/src/mayaprogs/mayapath.cxx b/pandatool/src/mayaprogs/mayapath.cxx deleted file mode 100644 index 4cbf19324f..0000000000 --- a/pandatool/src/mayaprogs/mayapath.cxx +++ /dev/null @@ -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 - -#if defined(_WIN32) -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif -#include -#else -#include -#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; -} diff --git a/pandatool/src/mayaprogs/normal_test.cxx b/pandatool/src/mayaprogs/normal_test.cxx deleted file mode 100644 index 41680254de..0000000000 --- a/pandatool/src/mayaprogs/normal_test.cxx +++ /dev/null @@ -1,289 +0,0 @@ - -#include -#include -#include -#include - -#ifndef _BOOL -#define _BOOL 1 -#endif - -#define REQUIRE_IOSTREAM - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -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 1 ) && ( substring( $dir, $sz, $sz ) == "/" ) ) - // { - // $dir = substring( $dir, 1, ($sz - 1) ); - // } - return $dir; -} - -/////////////////////////////////////////////////////////////// -// Process: exportScene // -// exports the entire scene/selected objects // -/////////////////////////////////////////////////////////////// -global proc string exportScene( string $selection ) -{ - print "Exporting scene...\n"; - - string $sceneFilePath = `file -q -sceneName`; //get scene filename and path - - if ( $sceneFilePath == "" ) - { - error "You have not yet saved this scene.\nPlease save your scene or specify a custom output directory and filename.\n"; - return "failed"; - } - - string $scenePath = pathPart($sceneFilePath); - string $sceneFile = filePart($sceneFilePath); - string $fileName = `match "^[^\.]*" $sceneFile`; //cut off the file extension - string $tempScenePath = ($scenePath + $fileName + "_temp.mb"); - - if ( $selection == "all") - { - file -op "v=1" -typ "mayaBinary" -ea $tempScenePath; //export the whole scene - print ("Saved entire scene as temporary file: " + $fileName + "_temp.mb\n"); - } - else - { - file -op "v=1" -typ "mayaBinary" -es $tempScenePath; //export only selected objects - print ("Saved selected objects as temporary file: " + $fileName + "_temp.mb\n"); - } - - return $tempScenePath; -} - -/////////////////////////////////////////////////////////////// -// Process: argsBuilder // -// constructs the arguments to pass to maya2egg // -/////////////////////////////////////////////////////////////// -global proc string argsBuilder() -{ - string $args = "maya2egg"; - - //get the version of maya and append it to the maya2egg call - string $mayaVersionLong = `getApplicationVersionAsFloat`; - string $mayaVersionShort = substituteAllString($mayaVersionLong, ".", ""); - print ("MAYA VERSION : "+$mayaVersionShort+"\n"); - //only strips the zeroes if the version number is less than 4 - if (`size($mayaVersionShort)`<4) - { - $mayaVersionShort = substituteAllString($mayaVersionShort, "0", ""); - } - - $args += $mayaVersionShort; - - $args += " "; - - // We always want polygons, never nurbs. - $args += "-p "; - - //check back face culling - if ( `checkBox -query -value bfaceCB` ) - { - $args += "-bface "; - } - - //check animation options - string $exportOptionsARGS = `radioCollection -query -select exportOptionsRC`; - - switch ($exportOptionsARGS) - { - case "chooseMeshRB": - $args += "-a none "; - break; - case "chooseActorRB": - $args += "-a model "; - break; - case "chooseAnimationRB": - $args += "-a chan "; - - //set the start frames **Does not check if start frame < end frame **Does not support negative values **Does not check if start/end frame is within bounds of the scene - if ( `radioCollection -query -select animationOptionsRC` == "chooseCustomRangeRB" ) - { - string $startFrameARGS = `textField -query -text startFrameTF`; - string $endFrameARGS = `textField -query -text endFrameTF`; - - //start frame - if ( `match "[0-9]+" $startFrameARGS` == $startFrameARGS && $startFrameARGS != "") - { - $args += ( "-sf " + `match "[0-9]+" $startFrameARGS` + " " ); - } - else - { - error "Start Frame entered data is the wrong format. Should be an integer.\n"; - return "failed"; - } - - //end frame - if ( `match "[0-9]+" $endFrameARGS` == $endFrameARGS && $endFrameARGS != "") - { - $args += ( "-ef " + `match "[0-9]+" $endFrameARGS` + " " ); - } - else - { - error "End Frame entered data is the wrong format. Should be an integer.\n"; - return "failed"; - } - } - break; - case "chooseBothRB": - $args += "-a both "; - - //set the start frames **Does not check if start frame < end frame **Does not support negative values **Does not check if start/end frame is within bounds of the scene - if ( `radioCollection -query -select animationOptionsRC` == "chooseCustomRangeRB" ) - { - string $startFrameARGS = `textField -query -text startFrameTF`; - string $endFrameARGS = `textField -query -text endFrameTF`; - - //start frame - if ( `match "[0-9]+" $startFrameARGS` == $startFrameARGS && $startFrameARGS != "") - { - $args += ( "-sf " + `match "[0-9]+" $startFrameARGS` + " " ); - } - else - { - error "Start Frame entered data is the wrong format. Should be an integer.\n"; - return "failed"; - } - - //end frame - if ( `match "[0-9]+" $endFrameARGS` == $endFrameARGS && $endFrameARGS != "") - { - $args += ( "-ef " + `match "[0-9]+" $endFrameARGS` + " " ); - } - else - { - error "End Frame entered data is the wrong format. Should be an integer.\n"; - return "failed"; - } - } - - - break; - case "choosePoseRB": - $args += "-a pose "; - - //set the start frames **Does not check if start frame < end frame **Does not support negative values **Does not check if start/end frame is within bounds of the scene - //start frame - string $startFrameARGS = `textField -query -text startFrameTF`; - - if ( `match "[0-9]+" $startFrameARGS` == $startFrameARGS && $startFrameARGS != "") - { - $args += ( "-sf " + `match "[0-9]+" $startFrameARGS` + " " ); - } - else - { - error "Start Frame entered data is the wrong format. Should be an integer.\n"; - return "failed"; - } - break; - } - - //Relative path check - if ( `radioCollection -query -select texPathOptionsRC` == "chooseCustomTexPathRB" ) - { - $args += ( "-pd " + "\"" + `textField -query -text customTexPathTF` + "\"" + " " ); - } - - print ( "Using these arguments: " + $args + "[END]\n" ); - - return $args; -} - -/////////////////////////////////////////////////////////// -// Process: export2Egg // -/////////////////////////////////////////////////////////// -global proc string export2Egg ( string $mbfile, string $destPath, string $destFilename, string $transformMode, string $ARGS) -{ - string $pandaEnvSetup = "set PATH=%MAYA_LOCATION%\\bin;%PATH% & "; - - //Check if there is a valid maya binary file to operate on - if ( $mbfile == "" ) - { - error "Not a valid Maya Binary file."; - - return "failed"; - } - //Start export process - else - { - //make the final egg path - string $eggFile = ( $destPath + $destFilename ); - string $up=`upAxis -q -axis`; - string $unit=`optionMenu -q -value unitMenu`; - - $ARGS += " -cs " + $up+"-up"; - $ARGS += " -uo " + $unit; - $ARGS += " -trans " + $transformMode; - - print ("Your scene will be saved as this egg file: " + $destFilename + "\n" ); - - print ("In this directory: " + $destPath + "\n" ); - - //Check if overwriting is enabled - if ( `checkBox -query -value overwriteCB` ) - { - //Overwrite - print "!!Overwrite enabled!!\n"; - string $result = - system - ( - $pandaEnvSetup + $ARGS - + " -o " - + "\"" + $eggFile + "\"" - + " " - + "\"" + $mbfile + "\"" - ); - - print ($result + "\n"); - } - else - { - //Don't overwrite - string $result = - system - ( - $pandaEnvSetup + $ARGS - + "\"" + $mbfile + "\"" - + " " - + "\"" + $eggFile + "\"" - ); - - print ($result + "\n"); - } - - string $unit=`optionMenu -q -value unitMenu`; - print ("Finished exporting (.mb -> .egg), unit : "+$unit+"\n"); - return $eggFile; - } -} - -/////////////////////////////////////////////////////////// -// Process: exportButton // -/////////////////////////////////////////////////////////// -global proc int exportButton () -{ - //We need to do before calling export2EGG/BAM/Pview: - //-Export a temporary MB - //-Get the destination path - //-Get the filename - //-Get the custom arguments - - //Export the scene as a temporary file - string $tempMBFile = ""; - if ( `checkBox -query -value selectedCB` ) - { - $tempMBFile = exportScene( "selected" ); - if ( $tempMBFile == "failed" ) - { - return 0; - } - } - else - { - $tempMBFile = exportScene( "all" ); - if ( $tempMBFile == "failed" ) - { - return 0; - } - } - - //get the original scene name - string $origFileName = filePart ( `file -q -sceneName` ); - $origFileName = `match "^[^\.]*" $origFileName`; //cut off the file extension - - //-Get the destination path - //-Get the filename - //-Get the custom arguments - - string $eggFile = exportPrep ( $tempMBFile, $origFileName ); - - if ( $eggFile == "failed" ) - { - return 0; - } - else - { - return 1; - } -} - -/////////////////////////////////////////////////////////// -// Process: send2Pview // -/////////////////////////////////////////////////////////// -global proc send2Pview( string $file ) -{ - print "\nStarting pview...\n"; - - string $result = - system - ( - "shell pview -l -c " - + "\"" + $file + "\"" - ); - - print ($result + "\n"); -} - -/////////////////////////////////////////////////////////// -// Process: getFile2Pview // -/////////////////////////////////////////////////////////// -global proc getFile2Pview() -{ - string $selectedFile = `fileDialog -directoryMask "*.egg;*.bam"`; - - string $origFileName = filePart ( $selectedFile ); - $origFileName = `match "^[^\.]*" $origFileName`; //cut off the file extension - - if ( $selectedFile == "") - { - error ( "No file selected\n" ); - } - else - { - send2Pview ( $selectedFile ); - } -} - -/////////////////////////////////////////////////////////// -// Process: getFile2Bam // -/////////////////////////////////////////////////////////// -global proc getFile2Bam() -{ - string $selectedFile = `fileDialog -directoryMask "*.egg"`; - - if ( $selectedFile == "") - { - error ( "No file selected\n" ); - } - else - { - export2Bam ( $selectedFile ); - } -} - -/////////////////////////////////////////////////////////// -// Process: getFile2Egg // -/////////////////////////////////////////////////////////// -global proc getFile2Egg() -{ - string $selectedFile = `fileDialog -directoryMask "*.mb"`; - - string $fileName = filePart ( $selectedFile ); - $fileName = `match "^[^\.]*" $fileName`; //cut off the file extension - - if ( $selectedFile == "") - { - error ( "No file selected\n" ); - } - else - { - exportPrep ( $selectedFile, $fileName ); - } -} -/////////////////////////////////////////////////////////// -// Process: exportPrep // -/////////////////////////////////////////////////////////// -global proc string exportPrep( string $workFile, string $fileName ) -{ - //Get the destination path - string $destPath = ""; - if ( `radioCollection -query -select outputPathOptionsRC` == "chooseDefaultOutputPathRB" ) - { - $destPath = pathPart($workFile); - } - else - { - if ( `textField -query -text customOutputPathTF` == "") - { - error "Output directory field is empty"; - return "failed"; - } - else - { - $destPath = `textField -query -text customOutputPathTF` + "/"; - } - } - - //Get the filename - string $destFilename = ""; - if ( `radioCollection -query -select outputFilenameOptionsRC` == "chooseOriginalFilenameRB" ) - { - $destFilename = $fileName + ".egg"; - } - else - { - if ( `textField -query -text customFilenameTF` == "") - { - error "Custom filename field is empty"; - return "failed"; - } - else - { - $destFilename = `textField -query -text customFilenameTF` + ".egg"; - } - } - - //Get the transform mode - string $transformMode = ""; - if ( `radioCollection -query -select transformModeRC` == "chooseTransformModelRB" ) - { - $transformMode = "model"; - } - else - { - $transformMode = "all"; - } - - //-Get the custom arguments - string $ARGS = argsBuilder(); - - if ( $ARGS == "failed" ) - { - return "failed"; - } - - //export the egg - string $eggFile = export2Egg ( $workFile, $destPath, $destFilename, $transformMode, $ARGS); - - if ( $eggFile == "failed" ) - { - return "failed"; - } - - //run pview if option is selected - if ( `checkBox -query -value pviewCB` ) - { - send2Pview ( $eggFile ); - } - - if ( `radioCollection -query -select outputFileOptionsRC` == "chooseEggBamRB" ) - { - export2Bam ( $eggFile ); - } - - return $eggFile; -} - -/////////////////////////////////////////////////////////// -// Process: export2Bam // -/////////////////////////////////////////////////////////// -global proc export2Bam ( string $eggFile ) -{ - //Check if there is a valid egg file to operate on - if ( $eggFile == "" ) - { - //Cannot operate without an egg first - //throw error if the scene has no associated egg file - error "Invalid egg file"; - } - //Call egg2bam - else - { - string $bamFile = ""; - string $fileName = filePart($eggFile); - string $filePath = pathPart($eggFile); - - //Use either the original fileName or a new fileName for the output - if ( `radioCollection -query -select outputFilenameOptionsRC` == "chooseCustomFilenameRB" ) - { - $bamFile = $filePath + `textField -query -text customFilenameTF` + ".bam"; - } - else - { - $bamFile = $filePath + `match "^[^\.]*" $fileName` + ".bam"; - } - - print ("Your file is: " + $fileName + "\nFound in path: " + $filePath + "\n\n"); - - print ("Your file will be saved as this bam file: " + $bamFile + "\n"); - - //Check if overwriting is enabled - if ( `checkBox -query -value overwriteCB` ) - { - //Overwrite - string $result = - system - ( - "egg2bam -o " - + "\"" + $bamFile + "\"" - + " " - + "\"" + $eggFile + "\"" - ); - - print ($result + "\n"); - } - else - { - //Don't overwrite - string $result = - system - ( - "egg2bam " - + "\"" + $eggFile + "\"" - + " " - + "\"" + $bamFile + "\"" - ); - - print ($result + "\n"); - } - } - - string $unit=`optionMenu -q -value unitMenu`; - print ("Finished exporting (.egg -> .bam), unit : "+$unit+"\n"); -} diff --git a/pandatool/src/scripts/TagSelectedObjects.ms b/pandatool/src/scripts/TagSelectedObjects.ms deleted file mode 100644 index 31136abe27..0000000000 --- a/pandatool/src/scripts/TagSelectedObjects.ms +++ /dev/null @@ -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 \ No newline at end of file