makepanda: Remove Autodesk Maya plug-ins
These now live at https://github.com/panda3d/maya-egg Fixes #1584
This commit is contained in:
parent
fff9ea594c
commit
ad4ecbcc16
|
|
@ -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/
|
||||
#
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
//
|
||||
// This is a sample mel script to flag a Maya node with at least
|
||||
// one eggObjectTypes* attribute. These attributes are used to tag
|
||||
// geometry with special meaning to Panda. There are a handful of
|
||||
// attribute values that are predefined within Panda, but you can also
|
||||
// make up your own attribute values, and define an arbitrary egg
|
||||
// syntax to associate with each one.
|
||||
//
|
||||
// Each type you invoke this script to add an attribute to a node, it
|
||||
// adds a new pull-down menu on the node attributes list, giving all
|
||||
// of the values listed in $eggFlags, below. You can then select one
|
||||
// of these values to assign to the node. If you need to assign
|
||||
// multiple different values to the same node, run this script
|
||||
// multiple times.
|
||||
//
|
||||
// The maya2egg converter will look for eggObjectTypes* attributes and
|
||||
// insert the line "<ObjectType> { value }" for each one found, where
|
||||
// "value" is the particular value you have selected from the
|
||||
// pull-down menu. Eventually, when the egg loader loads the egg file
|
||||
// into Panda (either by loading the egg file interactively into a
|
||||
// Panda session, or via an egg2bam command), the <ObjectType> line
|
||||
// will be replaced with arbitrary egg syntax defined by your
|
||||
// Config.prc file with a line like this:
|
||||
//
|
||||
// egg-object-type-value [your egg syntax here]
|
||||
//
|
||||
// See panda/src/configfiles/panda.prc.pp and
|
||||
// direct/src/configfiles/direct.prc.pp for examples of this.
|
||||
//
|
||||
|
||||
global proc eggObjectFlags() {
|
||||
string $sel[] =`ls -sl`;
|
||||
|
||||
// Modify this line as needed to add your own object types.
|
||||
string $eggFlags = "none:portal:polylight:seq24:seq12:indexed:model:dcs:barrier:sphere:tube:trigger:trigger-sphere:bubble:ghost:keep-all-uvsets";
|
||||
|
||||
for ($i in $sel) {
|
||||
string $attrName = "eggObjectTypes";
|
||||
string $object = ($i + "." + $attrName);
|
||||
|
||||
int $num = 1;
|
||||
|
||||
while (`objExists ($object + $num)`) {
|
||||
$num++;
|
||||
}
|
||||
|
||||
addAttr -ln ($attrName + $num) -k 1 -at "enum" -en ($eggFlags) $i;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,428 +0,0 @@
|
|||
/**
|
||||
* PANDA 3D SOFTWARE
|
||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
*
|
||||
* All use of this software is subject to the terms of the revised BSD
|
||||
* license. You should have received a copy of this license along
|
||||
* with this source code in a file named "LICENSE."
|
||||
*
|
||||
* @file mayaApi.cxx
|
||||
* @author drose
|
||||
* @date 2002-04-15
|
||||
*/
|
||||
|
||||
#include "mayaApi.h"
|
||||
#include "config_maya.h"
|
||||
#include "string_utils.h"
|
||||
#include "thread.h"
|
||||
|
||||
#include "pre_maya_include.h"
|
||||
#include <maya/MGlobal.h>
|
||||
#include <maya/MDistance.h>
|
||||
#include <maya/MFileIO.h>
|
||||
#include <maya/MLibrary.h>
|
||||
#include <maya/MStatus.h>
|
||||
#include <maya/MFnAnimCurve.h>
|
||||
#include "post_maya_include.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <direct.h> // for chdir()
|
||||
#endif
|
||||
|
||||
using std::string;
|
||||
|
||||
PT(MayaApi) MayaApi::_global_api = nullptr;
|
||||
|
||||
// We need this bogus object just to force the application to link with
|
||||
// OpenMayaAnim.lib; otherwise, Maya will complain (when compiled on Windows)
|
||||
// that it is unable to find source plug 'ikRPsolver.msg'.
|
||||
static MFnAnimCurve force_link_with_OpenMayaAnim;
|
||||
|
||||
/**
|
||||
* Don't attempt to create this object directly; instead, use the open_api()
|
||||
* method.
|
||||
*/
|
||||
MayaApi::
|
||||
MayaApi(const string &program_name, bool view_license, bool revert_dir) {
|
||||
if (program_name == "plug-in") {
|
||||
// In this special case, we are invoking the code from within a plug-in,
|
||||
// so we need not (and should not) call MLibrary::initialize().
|
||||
_plug_in = true;
|
||||
_is_valid = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise, if program_name is any other name, we are invoking the code
|
||||
// from a standalone application and we do need to call
|
||||
// MLibrary::initialize().
|
||||
_plug_in = false;
|
||||
|
||||
// Beginning with Maya4.5, the call to initialize seems to change the
|
||||
// current directory! Yikes!
|
||||
|
||||
// Furthermore, the current directory may change during the call to any Maya
|
||||
// function! Egad!
|
||||
_cwd = ExecutionEnvironment::get_cwd();
|
||||
MStatus stat = MLibrary::initialize(false, (char *)program_name.c_str(), view_license);
|
||||
|
||||
int error_count = init_maya_repeat_count;
|
||||
while (!stat && error_count > 1) {
|
||||
stat.perror("MLibrary::initialize");
|
||||
Thread::sleep(init_maya_timeout);
|
||||
stat = MLibrary::initialize(false, (char *)program_name.c_str(), view_license);
|
||||
--error_count;
|
||||
}
|
||||
|
||||
// Restore the current directory. Ever since Maya 2010, there seems to be
|
||||
// some bad mojo when you do this.
|
||||
if( revert_dir ){
|
||||
string dirname = _cwd.to_os_specific();
|
||||
if (chdir(dirname.c_str()) < 0) {
|
||||
maya_cat.warning()
|
||||
<< "Unable to restore current directory to " << _cwd
|
||||
<< " after initializing Maya.\n";
|
||||
} else {
|
||||
if (maya_cat.is_debug()) {
|
||||
maya_cat.debug()
|
||||
<< "Restored current directory to " << _cwd << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!stat) {
|
||||
stat.perror("MLibrary::initialize");
|
||||
_is_valid = false;
|
||||
} else {
|
||||
_is_valid = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Don't attempt to copy MayaApi objects. There should be only one of these
|
||||
* in the world at a time.
|
||||
*/
|
||||
MayaApi::
|
||||
MayaApi(const MayaApi ©) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -1,517 +0,0 @@
|
|||
/**
|
||||
* PANDA 3D SOFTWARE
|
||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
*
|
||||
* All use of this software is subject to the terms of the revised BSD
|
||||
* license. You should have received a copy of this license along
|
||||
* with this source code in a file named "LICENSE."
|
||||
*
|
||||
* @file mayaShader.cxx
|
||||
* @author drose
|
||||
* @date 2000-02-01
|
||||
* Modified 19Mar10 by ETC PandaSE team (see
|
||||
* header comment for mayaToEgg.cxx for details)
|
||||
*/
|
||||
|
||||
#include "mayaShader.h"
|
||||
#include "maya_funcs.h"
|
||||
#include "config_maya.h"
|
||||
#include "string_utils.h"
|
||||
#include "pnmImageHeader.h" // for lumin_red, etc.
|
||||
#include "pset.h"
|
||||
|
||||
#include "pre_maya_include.h"
|
||||
#include <maya/MFnDependencyNode.h>
|
||||
#include <maya/MFnLambertShader.h>
|
||||
#include <maya/MFnPhongShader.h>
|
||||
#include <maya/MFnMesh.h>
|
||||
#include <maya/MPlug.h>
|
||||
#include <maya/MPlugArray.h>
|
||||
#include <maya/MColor.h>
|
||||
#include <maya/MObject.h>
|
||||
#include <maya/MStatus.h>
|
||||
#include "post_maya_include.h"
|
||||
|
||||
using std::endl;
|
||||
using std::string;
|
||||
|
||||
/**
|
||||
* Reads the Maya "shading engine" to determine the relevant shader
|
||||
* properties.
|
||||
*/
|
||||
MayaShader::
|
||||
MayaShader(MObject engine, bool legacy_shader) {
|
||||
MFnDependencyNode engine_fn(engine);
|
||||
|
||||
set_name(engine_fn.name().asChar());
|
||||
|
||||
if (maya_cat.is_debug()) {
|
||||
maya_cat.debug()
|
||||
<< "Reading shading engine " << get_name() << "\n";
|
||||
}
|
||||
_legacy_mode = false;
|
||||
_flat_color.set(1,1,1,1);
|
||||
|
||||
MPlug shader_plug = engine_fn.findPlug("surfaceShader");
|
||||
bool found_shader = false;
|
||||
if (!shader_plug.isNull()) {
|
||||
MPlugArray shader_pa;
|
||||
shader_plug.connectedTo(shader_pa, true, false);
|
||||
maya_cat.spam() << "shader plug connected to: " << shader_pa.length() << endl;
|
||||
for (size_t i = 0; i < shader_pa.length() && !found_shader; i++) {
|
||||
MObject shader = shader_pa[0].node();
|
||||
if (shader.hasFn(MFn::kPhong)) {
|
||||
if (legacy_shader) {
|
||||
found_shader = find_textures_legacy(shader);
|
||||
} else {
|
||||
found_shader = find_textures_modern(shader);
|
||||
}
|
||||
} else if (shader.hasFn(MFn::kLambert)) {
|
||||
found_shader = find_textures_legacy(shader);
|
||||
if (found_shader) {
|
||||
_legacy_mode = true;
|
||||
}
|
||||
} else if (shader.hasFn(MFn::kSurfaceShader)) {
|
||||
found_shader = find_textures_legacy(shader);
|
||||
if (found_shader) {
|
||||
_legacy_mode = true;
|
||||
}
|
||||
} else {
|
||||
maya_cat.warning() <<
|
||||
"Unrecognized shader type: only lambert and phong supported (lambert deprecated).\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
MayaShader::
|
||||
~MayaShader() {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void MayaShader::
|
||||
output(std::ostream &out) const {
|
||||
out << "Shader " << get_name();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void MayaShader::
|
||||
write(std::ostream &out) const {
|
||||
out << "Shader " << get_name() << "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* This is part of the deprecated codepath. return the color def i.e.
|
||||
* texture at idx
|
||||
*/
|
||||
MayaShaderColorDef *MayaShader::
|
||||
get_color_def(size_t idx) const {
|
||||
if (_color.size() > 0)
|
||||
return _color[idx];
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
/**
|
||||
* Returns the overall color of the shader as a single-precision rgba value,
|
||||
* where the alpha component represents transparency according to the Panda
|
||||
* convention. If no overall color is specified (_has_flat_color is not
|
||||
* true), this returns white.
|
||||
*
|
||||
* Normally, Maya makes texture color override the flat color, so if a texture
|
||||
* is also applied (_has_texture is true), this value is not used by Maya.
|
||||
*/
|
||||
LColor MayaShader::
|
||||
get_rgba(size_t idx) const {
|
||||
LColor rgba(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
if (_color.size() && _color[idx]->_has_flat_color) {
|
||||
rgba[0] = (PN_stdfloat)_color[idx]->_flat_color[0];
|
||||
rgba[1] = (PN_stdfloat)_color[idx]->_flat_color[1];
|
||||
rgba[2] = (PN_stdfloat)_color[idx]->_flat_color[2];
|
||||
}
|
||||
|
||||
if (_transparency._has_flat_color) {
|
||||
// Maya supports colored transparency, but we only support grayscale
|
||||
// transparency. Use the pnmimage constants to convert color to
|
||||
// grayscale.
|
||||
double trans =
|
||||
_transparency._flat_color[0] * lumin_red +
|
||||
_transparency._flat_color[1] * lumin_grn +
|
||||
_transparency._flat_color[2] * lumin_blu;
|
||||
rgba[3] = 1.0f - (PN_stdfloat)trans;
|
||||
}
|
||||
|
||||
return rgba;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recalculates the all_maps list.
|
||||
*/
|
||||
void MayaShader::
|
||||
collect_maps() {
|
||||
_all_maps.clear();
|
||||
|
||||
for (size_t i=0; i<_color_maps.size(); i++) {
|
||||
_all_maps.push_back(_color_maps[i]);
|
||||
}
|
||||
for (size_t i=0; i<_trans_maps.size(); i++) {
|
||||
_all_maps.push_back(_trans_maps[i]);
|
||||
}
|
||||
for (size_t i=0; i<_normal_maps.size(); i++) {
|
||||
_all_maps.push_back(_normal_maps[i]);
|
||||
}
|
||||
for (size_t i=0; i<_glow_maps.size(); i++) {
|
||||
_all_maps.push_back(_glow_maps[i]);
|
||||
}
|
||||
for (size_t i=0; i<_gloss_maps.size(); i++) {
|
||||
_all_maps.push_back(_gloss_maps[i]);
|
||||
}
|
||||
for (size_t i=0; i<_height_maps.size(); i++) {
|
||||
_all_maps.push_back(_height_maps[i]);
|
||||
}
|
||||
|
||||
for (size_t i=0; i<_color.size(); i++) {
|
||||
if (_color[i]->_has_texture) {
|
||||
_all_maps.push_back(_color[i]);
|
||||
}
|
||||
}
|
||||
if (_transparency._has_texture) {
|
||||
_all_maps.push_back(&_transparency);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Locates all file textures leading into the given shader.
|
||||
*/
|
||||
bool MayaShader::
|
||||
find_textures_modern(MObject shader) {
|
||||
if (!shader.hasFn(MFn::kPhong)) {
|
||||
maya_cat.warning()
|
||||
<< "The new codepath expects to see phong shaders only.\n";
|
||||
return false;
|
||||
}
|
||||
MStatus status;
|
||||
MFnPhongShader phong_fn(shader);
|
||||
MFnDependencyNode shader_fn(shader);
|
||||
|
||||
if (maya_cat.is_spam()) {
|
||||
maya_cat.spam()
|
||||
<< " Reading modern surface shader " << shader_fn.name().asChar() << "\n";
|
||||
}
|
||||
|
||||
string n = shader_fn.name().asChar();
|
||||
|
||||
MayaShaderColorDef::find_textures_modern(n, _color_maps, shader_fn.findPlug("color"), false);
|
||||
if (_color_maps.size() == 0) {
|
||||
MayaShaderColorDef::find_textures_modern(n, _color_maps, shader_fn.findPlug("colorR"), false);
|
||||
}
|
||||
MayaShaderColorDef::find_textures_modern(n, _trans_maps, shader_fn.findPlug("transparency"), true);
|
||||
if (_trans_maps.size() == 0) {
|
||||
MayaShaderColorDef::find_textures_modern(n, _trans_maps, shader_fn.findPlug("transparencyR"), true);
|
||||
}
|
||||
MayaShaderColorDef::find_textures_modern(n, _normal_maps, shader_fn.findPlug("normalCamera"), false);
|
||||
if (_normal_maps.size() == 0) {
|
||||
MayaShaderColorDef::find_textures_modern(n, _normal_maps, shader_fn.findPlug("normalCameraR"), false);
|
||||
}
|
||||
MayaShaderColorDef::find_textures_modern(n, _gloss_maps, shader_fn.findPlug("specularColor"), true);
|
||||
if (_gloss_maps.size() == 0) {
|
||||
MayaShaderColorDef::find_textures_modern(n, _gloss_maps, shader_fn.findPlug("specularColorR"), true);
|
||||
}
|
||||
MayaShaderColorDef::find_textures_modern(n, _glow_maps, shader_fn.findPlug("incandescence"), true);
|
||||
if (_glow_maps.size() == 0) {
|
||||
MayaShaderColorDef::find_textures_modern(n, _glow_maps, shader_fn.findPlug("incandescenceR"), true);
|
||||
}
|
||||
MayaShaderColorDef::find_textures_modern(n, _height_maps, shader_fn.findPlug("surfaceThickness"), true);
|
||||
if (_height_maps.size() == 0) {
|
||||
MayaShaderColorDef::find_textures_modern(n, _height_maps, shader_fn.findPlug("surfaceThicknessR"), true);
|
||||
}
|
||||
|
||||
collect_maps();
|
||||
|
||||
MColor color = phong_fn.color(&status);
|
||||
if (status) {
|
||||
_flat_color.set(color.r, color.g, color.b, color.a);
|
||||
}
|
||||
|
||||
color = phong_fn.transparency(&status);
|
||||
if (status) {
|
||||
_flat_color[3] = 1.0 - ((color[0] + color[1] + color[2]) * (1.0/3.0));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns the uvset_name of each MayaShaderColorDef using the given file-to-
|
||||
* uvset map.
|
||||
*/
|
||||
void MayaShader::
|
||||
bind_uvsets(MayaFileToUVSetMap &map) {
|
||||
for (size_t i=0; i<_all_maps.size(); i++) {
|
||||
MayaShaderColorDef *def = _all_maps[i];
|
||||
MayaFileToUVSetMap::iterator p = map.find(def->_texture_name);
|
||||
if (p == map.end()) {
|
||||
def->_uvset_name = "map1";
|
||||
} else {
|
||||
def->_uvset_name = (*p).second;
|
||||
}
|
||||
}
|
||||
|
||||
calculate_pairings();
|
||||
}
|
||||
|
||||
/**
|
||||
* For each Alpha texture, try to find an RGB texture that has the same
|
||||
* properties. Attempt to make it so that the alpha texture isn't a separate
|
||||
* texture, but rather, an Alpha-Filename associated with an existing texture.
|
||||
*/
|
||||
void MayaShader::
|
||||
calculate_pairings() {
|
||||
|
||||
if (_legacy_mode) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t i=0; i<_all_maps.size(); i++) {
|
||||
_all_maps[i]->_opposite = 0;
|
||||
}
|
||||
|
||||
bool using_transparency = (_trans_maps.size() > 0);
|
||||
|
||||
for (int retry=0; retry<2; retry++) {
|
||||
bool perfect=(retry==0);
|
||||
for (size_t i=0; i<_color_maps.size(); i++) {
|
||||
if ((_color_maps[i]->_blend_type == MayaShaderColorDef::BT_modulate)||
|
||||
(_color_maps[i]->_blend_type == MayaShaderColorDef::BT_unspecified)) {
|
||||
for (size_t j=0; j<_trans_maps.size(); j++) {
|
||||
try_pair(_color_maps[i], _trans_maps[j], perfect);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!using_transparency) {
|
||||
for (int retry=0; retry<2; retry++) {
|
||||
bool perfect=(retry==0);
|
||||
for (size_t i=0; i<_color_maps.size(); i++) {
|
||||
for (size_t j=0; j<_glow_maps.size(); j++) {
|
||||
try_pair(_color_maps[i], _glow_maps[j], perfect);
|
||||
}
|
||||
for (size_t j=0; j<_gloss_maps.size(); j++) {
|
||||
try_pair(_color_maps[i], _gloss_maps[j], perfect);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int retry=0; retry<2; retry++) {
|
||||
bool perfect=(retry==0);
|
||||
for (size_t i=0; i<_normal_maps.size(); i++) {
|
||||
for (size_t j=0; j<_height_maps.size(); j++) {
|
||||
try_pair(_normal_maps[i], _height_maps[j], perfect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i=0; i<_normal_maps.size(); i++) {
|
||||
_normal_maps[i]->_blend_type = MayaShaderColorDef::BT_normal;
|
||||
}
|
||||
for (size_t i=0; i<_glow_maps.size(); i++) {
|
||||
if (_glow_maps[i]->_opposite) {
|
||||
_glow_maps[i]->_blend_type = MayaShaderColorDef::BT_unspecified;
|
||||
_glow_maps[i]->_opposite->_blend_type = MayaShaderColorDef::BT_modulate_glow;
|
||||
} else {
|
||||
_glow_maps[i]->_blend_type = MayaShaderColorDef::BT_glow;
|
||||
}
|
||||
}
|
||||
for (size_t i=0; i<_gloss_maps.size(); i++) {
|
||||
if (_gloss_maps[i]->_opposite) {
|
||||
_gloss_maps[i]->_blend_type = MayaShaderColorDef::BT_unspecified;
|
||||
_gloss_maps[i]->_opposite->_blend_type = MayaShaderColorDef::BT_modulate_gloss;
|
||||
} else {
|
||||
_gloss_maps[i]->_blend_type = MayaShaderColorDef::BT_gloss;
|
||||
}
|
||||
}
|
||||
for (size_t i=0; i<_height_maps.size(); i++) {
|
||||
if (_height_maps[i]->_opposite) {
|
||||
_height_maps[i]->_blend_type = MayaShaderColorDef::BT_unspecified;
|
||||
_height_maps[i]->_opposite->_blend_type = MayaShaderColorDef::BT_normal_height;
|
||||
} else {
|
||||
_height_maps[i]->_blend_type = MayaShaderColorDef::BT_height;
|
||||
}
|
||||
}
|
||||
for (size_t i=0; i<_trans_maps.size(); i++) {
|
||||
if (_trans_maps[i]->_opposite) {
|
||||
_trans_maps[i]->_blend_type = MayaShaderColorDef::BT_unspecified;
|
||||
_trans_maps[i]->_opposite->_blend_type = MayaShaderColorDef::BT_modulate;
|
||||
} else {
|
||||
_trans_maps[i]->_blend_type = MayaShaderColorDef::BT_modulate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to associate an RGB tex with an Alpha tex.
|
||||
*/
|
||||
bool MayaShader::try_pair(MayaShaderColorDef *map1,
|
||||
MayaShaderColorDef *map2,
|
||||
bool perfect) {
|
||||
if ((map1->_opposite)||(map2->_opposite)) {
|
||||
// one of the maps is already paired
|
||||
return false;
|
||||
}
|
||||
if (perfect) {
|
||||
if (map1->_texture_filename != map2->_texture_filename) {
|
||||
// perfect mode requires a filename match.
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
string pre1 = get_file_prefix(map1->_texture_filename);
|
||||
string pre2 = get_file_prefix(map2->_texture_filename);
|
||||
if (pre1 != pre2) {
|
||||
// imperfect mode requires a filename prefix match.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ((map1->_projection_type != map2->_projection_type) ||
|
||||
(map1->_projection_matrix != map2->_projection_matrix) ||
|
||||
(map1->_u_angle != map2->_u_angle) ||
|
||||
(map1->_v_angle != map2->_v_angle) ||
|
||||
(map1->_uvset_name != map2->_uvset_name) ||
|
||||
(map1->_mirror != map2->_mirror) ||
|
||||
(map1->_stagger != map2->_stagger) ||
|
||||
(map1->_wrap_u != map2->_wrap_u) ||
|
||||
(map1->_wrap_v != map2->_wrap_v) ||
|
||||
(map1->_repeat_uv != map2->_repeat_uv) ||
|
||||
(map1->_offset != map2->_offset) ||
|
||||
(map1->_rotate_uv != map2->_rotate_uv)) {
|
||||
return false;
|
||||
}
|
||||
// Pairing successful.
|
||||
map1->_opposite = map2;
|
||||
map2->_opposite = map1;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to associate an RGB tex with an Alpha tex.
|
||||
*/
|
||||
string MayaShader::
|
||||
get_file_prefix(const string &fn) {
|
||||
Filename pfn = Filename::from_os_specific(fn);
|
||||
string base = pfn.get_basename_wo_extension();
|
||||
size_t offs = base.find("_");
|
||||
if (offs != string::npos) {
|
||||
base = base.substr(0, offs);
|
||||
}
|
||||
offs = base.find("-");
|
||||
if (offs != string::npos) {
|
||||
base = base.substr(0, offs);
|
||||
}
|
||||
return base;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is part of the legacy codepath. Extracts out the shading information
|
||||
* from the Maya surface shader.
|
||||
*/
|
||||
bool MayaShader::
|
||||
find_textures_legacy(MObject shader) {
|
||||
MStatus status;
|
||||
MFnDependencyNode shader_fn(shader);
|
||||
|
||||
if (maya_cat.is_spam()) {
|
||||
maya_cat.spam()
|
||||
<< " Reading legacy surface shader " << shader_fn.name().asChar() << "\n";
|
||||
}
|
||||
|
||||
// First, check for a connection to the color attribute. This could be a
|
||||
// texture map or something, and will override whatever the shader says for
|
||||
// color.
|
||||
|
||||
MPlug color_plug = shader_fn.findPlug("color");
|
||||
if (color_plug.isNull()) {
|
||||
// Or maybe a connection to outColor. Not sure how this differs from just
|
||||
// color, but empirically it seems that either might be used.
|
||||
color_plug = shader_fn.findPlug("outColor");
|
||||
}
|
||||
|
||||
if (!color_plug.isNull()) {
|
||||
MPlugArray color_pa;
|
||||
color_plug.connectedTo(color_pa, true, false);
|
||||
|
||||
MayaShaderColorDef *color_p = new MayaShaderColorDef;
|
||||
for (size_t i = 0; i < color_pa.length(); i++) {
|
||||
maya_cat.spam() << "color_pa[" << i << "]:" << color_pa[i].name().asChar() << endl;
|
||||
color_p->find_textures_legacy(this, color_pa[0].node());
|
||||
}
|
||||
|
||||
if (color_pa.length() < 1) {
|
||||
// assign a blank default color to this shader
|
||||
maya_cat.spam() << shader_fn.name().asChar() << " was not connected to texture" << endl;
|
||||
this->_color.push_back(color_p);
|
||||
}
|
||||
}
|
||||
|
||||
// Transparency is stored separately.
|
||||
MPlug trans_plug = shader_fn.findPlug("transparency");
|
||||
if (trans_plug.isNull()) {
|
||||
trans_plug = shader_fn.findPlug("outTransparency");
|
||||
}
|
||||
|
||||
if (!trans_plug.isNull()) {
|
||||
MPlugArray trans_pa;
|
||||
trans_plug.connectedTo(trans_pa, true, false);
|
||||
|
||||
for (size_t i = 0; i < trans_pa.length(); i++) {
|
||||
maya_cat.spam() << "read a transparency texture" << endl;
|
||||
_transparency.find_textures_legacy(this, trans_pa[0].node(), true);
|
||||
}
|
||||
}
|
||||
|
||||
// Also try to get the ordinary color directly from the surface shader.
|
||||
bool b_color_def = true;
|
||||
if (shader.hasFn(MFn::kLambert)) {
|
||||
MFnLambertShader lambert_fn(shader);
|
||||
MColor color = lambert_fn.color(&status);
|
||||
if (status) {
|
||||
// Warning! The alpha component of color doesn't mean transparency in
|
||||
// Maya.
|
||||
for (size_t i=0; i<_color.size(); ++i) {
|
||||
_color[i]->_has_flat_color = true;
|
||||
_color[i]->_flat_color.set(color.r, color.g, color.b, color.a);
|
||||
maya_cat.spam() << shader_fn.name().asChar() << " set shader color" << endl;
|
||||
// needed to print the final check
|
||||
if (!_color[i]->_has_flat_color && !_color[i]->_has_texture)
|
||||
b_color_def = false;
|
||||
|
||||
_transparency._flat_color.set(0.0, 0.0, 0.0, 0.0);
|
||||
|
||||
// Get the transparency separately.
|
||||
color = lambert_fn.transparency(&status);
|
||||
if (status) {
|
||||
_transparency._has_flat_color = true;
|
||||
_transparency._flat_color.set(color.r, color.g, color.b, color.a);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// if (!_color._has_flat_color && !_color._has_texture) {
|
||||
if (!b_color_def) {
|
||||
maya_cat.info() << shader_fn.name().asChar() << "Color def not found" << endl;
|
||||
if (maya_cat.is_spam()) {
|
||||
maya_cat.spam()
|
||||
<< " Color definition not found.\n";
|
||||
}
|
||||
}
|
||||
|
||||
collect_maps();
|
||||
return true;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -1,799 +0,0 @@
|
|||
/**
|
||||
* PANDA 3D SOFTWARE
|
||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
*
|
||||
* All use of this software is subject to the terms of the revised BSD
|
||||
* license. You should have received a copy of this license along
|
||||
* with this source code in a file named "LICENSE."
|
||||
*
|
||||
* @file mayaShaderColorDef.cxx
|
||||
* @author drose
|
||||
* @date 2003-04-12
|
||||
* Modified 19Mar10 by ETC PandaSE team (see
|
||||
* header comment for mayaToEgg.cxx for details)
|
||||
*/
|
||||
|
||||
#include "mayaShaderColorDef.h"
|
||||
#include "mayaShader.h"
|
||||
#include "maya_funcs.h"
|
||||
#include "config_maya.h"
|
||||
#include "string_utils.h"
|
||||
#include "pset.h"
|
||||
|
||||
#include "pre_maya_include.h"
|
||||
#include <maya/MFnDependencyNode.h>
|
||||
#include <maya/MPlug.h>
|
||||
#include <maya/MPlugArray.h>
|
||||
#include <maya/MObject.h>
|
||||
#include <maya/MStatus.h>
|
||||
#include <maya/MFnEnumAttribute.h>
|
||||
#include "post_maya_include.h"
|
||||
|
||||
using std::endl;
|
||||
using std::string;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
MayaShaderColorDef::
|
||||
MayaShaderColorDef() {
|
||||
|
||||
_blend_type = BT_unspecified;
|
||||
|
||||
_projection_type = PT_off;
|
||||
_projection_matrix = LMatrix4d::ident_mat();
|
||||
_u_angle = 0.0;
|
||||
_v_angle = 0.0;
|
||||
|
||||
_texture_filename = "";
|
||||
_texture_name = "";
|
||||
_color_gain.set(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
_coverage.set(1.0, 1.0);
|
||||
_translate_frame.set(0.0, 0.0);
|
||||
_rotate_frame = 0.0;
|
||||
|
||||
_mirror = false;
|
||||
_stagger = false;
|
||||
_wrap_u = true;
|
||||
_wrap_v = true;
|
||||
|
||||
_repeat_uv.set(1.0, 1.0);
|
||||
_offset.set(0.0, 0.0);
|
||||
_rotate_uv = 0.0;
|
||||
|
||||
_is_alpha = false;
|
||||
|
||||
_opposite = 0;
|
||||
|
||||
_color_object = nullptr;
|
||||
|
||||
_has_texture = false;
|
||||
_has_flat_color = false;
|
||||
_flat_color.set(0.0, 0.0, 0.0, 0.0);
|
||||
_has_alpha_channel = false;
|
||||
_keep_color = false; // classic mode overwrites color: new mode retains color with a 3rd layer
|
||||
_keep_alpha = false;
|
||||
_interpolate = false;
|
||||
_uvset_name = "map1";
|
||||
|
||||
_map_uvs = nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
MayaShaderColorDef::
|
||||
MayaShaderColorDef(MayaShaderColorDef ©) {
|
||||
_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<color_pa.length(); ++i) {
|
||||
MPlug pl = color_pa[i];
|
||||
MPlugArray pla;
|
||||
pl.connectedTo(pla, true, false);
|
||||
|
||||
// First figure out the blend mode intended for this shadercolordef
|
||||
int li = pl.logicalIndex();
|
||||
if (li > -1) {
|
||||
// found a blend mode
|
||||
if (maya_cat.is_spam()) {
|
||||
MString name = inputsPlug.name();
|
||||
maya_cat.spam() << "*** Start doIt... ***" << endl;
|
||||
maya_cat.spam() << "inputsPlug Name: " << name.asChar() << endl;
|
||||
}
|
||||
status = blendModePlug.selectAncestorLogicalIndex(li,inputsPlug);
|
||||
blendModePlug.getValue(blendValue);
|
||||
|
||||
if (maya_cat.is_spam()) {
|
||||
MString name = blendModePlug.name();
|
||||
maya_cat.spam()
|
||||
<< name.asChar() << ": has value " << blendValue << endl;
|
||||
}
|
||||
|
||||
MFnEnumAttribute blendModeEnum(blendModePlug);
|
||||
MString blendName = blendModeEnum.fieldName(blendValue, &status);
|
||||
|
||||
switch (blendValue) {
|
||||
case 1:
|
||||
bt = BT_decal;
|
||||
get_bool_attribute(color, "interpolate", _interpolate);
|
||||
maya_cat.info() << "interpolate: " << _interpolate << endl;
|
||||
_keep_color = true;
|
||||
break;
|
||||
case 6:
|
||||
bt = BT_modulate;
|
||||
get_bool_attribute(color, "keepAlpha", _keep_alpha);
|
||||
maya_cat.info() << "keepAlpha: " << _keep_alpha << endl;
|
||||
break;
|
||||
case 4:
|
||||
bt = BT_add;
|
||||
break;
|
||||
}
|
||||
|
||||
if (maya_cat.is_info()) {
|
||||
MString name = layered_fn.name();
|
||||
maya_cat.info() << name.asChar() << ": blendMode used " << blendName.asChar() << endl;
|
||||
if (maya_cat.is_spam()) {
|
||||
maya_cat.spam() << "*** END doIt... ***" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
// advance to the next plug, because that is where the shader info are
|
||||
pl = color_pa[++i];
|
||||
pl.connectedTo(pla, true, false);
|
||||
}
|
||||
for (size_t j=0; j<pla.length(); ++j) {
|
||||
// maya_cat.debug() << pl.name() << " is(pl) " <<
|
||||
// pl.node().apiTypeStr() << endl; maya_cat.debug() << pla[j].name()
|
||||
// << " is(pla) " << pla[j].node().apiTypeStr() << endl;
|
||||
string pla_name = pla[j].name().asChar();
|
||||
// sometimes, by default, maya gives a outAlpha on subsequent plugs,
|
||||
// ignore that
|
||||
if (pla_name.find("outAlpha") != string::npos) {
|
||||
// top texture has an alpha channel, so make sure that this alpha is
|
||||
// retained by egg file
|
||||
if (maya_cat.is_debug()) {
|
||||
maya_cat.debug() << pl.name().asChar() << ":has alpha channel" << pla_name << endl;
|
||||
}
|
||||
_has_alpha_channel = true;
|
||||
continue;
|
||||
}
|
||||
if (!first) {
|
||||
if (maya_cat.is_debug()) {
|
||||
maya_cat.debug() << pl.name().asChar() << " next:connectedTo: " << pla_name << endl;
|
||||
}
|
||||
MayaShaderColorDef *color_p = new MayaShaderColorDef;
|
||||
color_p->find_textures_legacy(shader, pla[j].node());
|
||||
color_p->_blend_type = bt;
|
||||
size_t loc = color_p->_texture_name.find('.',0);
|
||||
if (loc != string::npos) {
|
||||
color_p->_texture_name.resize(loc);
|
||||
}
|
||||
if (maya_cat.is_debug()) {
|
||||
maya_cat.debug() << "uv_name : " << color_p->_texture_name << endl;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (maya_cat.is_debug()) {
|
||||
maya_cat.debug() << pl.name().asChar() << " first:connectedTo: " << pla_name << endl;
|
||||
}
|
||||
find_textures_legacy(shader, pla[j].node());
|
||||
_texture_name.assign(pla[j].name().asChar());
|
||||
_blend_type = bt;
|
||||
size_t loc = _texture_name.find('.',0);
|
||||
if (loc != string::npos) {
|
||||
_texture_name.resize(loc);
|
||||
}
|
||||
if (maya_cat.is_debug()) {
|
||||
maya_cat.debug() << "uv_name : " << _texture_name << endl;
|
||||
}
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// This shader wasn't understood.
|
||||
if (maya_cat.is_debug()) {
|
||||
maya_cat.info()
|
||||
<< "**Don't know how to interpret color attribute type "
|
||||
<< color.apiTypeStr() << "\n";
|
||||
|
||||
} else {
|
||||
// If we don't have a heavy verbose count, only report each type of
|
||||
// unsupported shader once.
|
||||
static pset<MFn::Type> bad_types;
|
||||
if (bad_types.insert(color.apiType()).second) {
|
||||
maya_cat.info()
|
||||
<< "**Don't know how to interpret color attribute type "
|
||||
<< color.apiTypeStr() << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Search to find any file textures that lead into the given input plug. Any
|
||||
* textures found will be added to the provided MayaShaderColorList.
|
||||
*/
|
||||
void MayaShaderColorDef::
|
||||
find_textures_modern(const string &shadername, MayaShaderColorList &list, MPlug inplug, bool is_alpha) {
|
||||
|
||||
MPlugArray outplugs;
|
||||
inplug.connectedTo(outplugs, true, false);
|
||||
if (outplugs.length() == 0) {
|
||||
return;
|
||||
}
|
||||
if (outplugs.length() > 1) {
|
||||
// Only one output plug should be connected to a given input plug.
|
||||
maya_cat.warning()
|
||||
<< "Shader " << shadername << " has weird plug connections.\n";
|
||||
return;
|
||||
}
|
||||
MPlug outplug = outplugs[0];
|
||||
MObject source = outplug.node();
|
||||
MFnDependencyNode sourceFn(source);
|
||||
|
||||
if (source.hasFn(MFn::kFileTexture)) {
|
||||
|
||||
string filename;
|
||||
bool hasfn = get_string_attribute(source, "fileTextureName", filename);
|
||||
if ((!hasfn) || (filename.empty())) {
|
||||
maya_cat.warning()
|
||||
<< "Shader " << shadername << " references file texture "
|
||||
<< "with no file name, ignoring invalid file texture.\n";
|
||||
return;
|
||||
}
|
||||
Filename fn = filename;
|
||||
if (fn.is_directory()) {
|
||||
maya_cat.warning()
|
||||
<< "Shader " << shadername << " references file name "
|
||||
<< filename << " which is a directory, ignoring it.\n";
|
||||
return;
|
||||
}
|
||||
|
||||
MayaShaderColorDef *def = new MayaShaderColorDef;
|
||||
|
||||
def->_color_object = new MObject(source);
|
||||
def->_texture_filename = Filename::from_os_specific(filename);
|
||||
def->_texture_name = sourceFn.name().asChar();
|
||||
|
||||
get_vec2_attribute(source, "coverage", def->_coverage);
|
||||
get_vec2_attribute(source, "translateFrame", def->_translate_frame);
|
||||
get_angle_attribute(source, "rotateFrame", def->_rotate_frame);
|
||||
|
||||
get_bool_attribute(source, "mirror", def->_mirror);
|
||||
get_bool_attribute(source, "stagger", def->_stagger);
|
||||
get_bool_attribute(source, "wrapU", def->_wrap_u);
|
||||
get_bool_attribute(source, "wrapV", def->_wrap_v);
|
||||
|
||||
get_vec2_attribute(source, "repeatUV", def->_repeat_uv);
|
||||
get_vec2_attribute(source, "offset", def->_offset);
|
||||
get_angle_attribute(source, "rotateUV", def->_rotate_uv);
|
||||
|
||||
LRGBColor color_gain;
|
||||
PN_stdfloat alpha_gain;
|
||||
get_vec3_attribute(source, "colorGain", color_gain);
|
||||
get_maya_attribute(source, "alphaGain", alpha_gain);
|
||||
def->_color_gain[0] = color_gain[0];
|
||||
def->_color_gain[1] = color_gain[1];
|
||||
def->_color_gain[2] = color_gain[2];
|
||||
def->_color_gain[3] = alpha_gain;
|
||||
|
||||
def->_is_alpha = is_alpha;
|
||||
|
||||
if (maya_cat.is_debug()) {
|
||||
maya_cat.debug() << "pushed a file texture" << endl;
|
||||
}
|
||||
list.push_back(def);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (source.hasFn(MFn::kProjection)) {
|
||||
// This is a projected texture. We will have to step one level deeper to
|
||||
// find the actual texture.
|
||||
size_t before = list.size();
|
||||
MPlug image_plug = sourceFn.findPlug("image");
|
||||
if (!image_plug.isNull()) {
|
||||
MPlugArray image_pa;
|
||||
image_plug.connectedTo(image_pa, true, false);
|
||||
|
||||
for (size_t i = 0; i < image_pa.length(); i++) {
|
||||
find_textures_modern(shadername, list, image_pa[0], is_alpha);
|
||||
}
|
||||
}
|
||||
|
||||
// Now apply any inherited attributes to all textures found.
|
||||
|
||||
for (size_t i=before; i<list.size(); i++) {
|
||||
MayaShaderColorDef *def = list[i];
|
||||
|
||||
if (!get_mat4d_attribute(source, "placementMatrix", def->_projection_matrix)) {
|
||||
def->_projection_matrix = LMatrix4d::ident_mat();
|
||||
}
|
||||
|
||||
// The uAngle and vAngle might be used for certain kinds of projections.
|
||||
if (!get_angle_attribute(source, "uAngle", def->_u_angle)) {
|
||||
def->_u_angle = 360.0;
|
||||
}
|
||||
if (!get_angle_attribute(source, "vAngle", def->_v_angle)) {
|
||||
def->_v_angle = 180.0;
|
||||
}
|
||||
|
||||
string type;
|
||||
if (get_enum_attribute(source, "projType", type)) {
|
||||
def->set_projection_type(type);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (source.hasFn(MFn::kLayeredTexture)) {
|
||||
if (maya_cat.is_debug()) {
|
||||
maya_cat.debug() << "Found layered texture" << endl;
|
||||
}
|
||||
|
||||
MPlug inputsPlug = sourceFn.findPlug("inputs");
|
||||
size_t nlayers = inputsPlug.numElements();
|
||||
for (size_t layer=0; layer<nlayers; layer++) {
|
||||
MPlug elt = inputsPlug.elementByPhysicalIndex(layer);
|
||||
MPlug color;
|
||||
MPlug blend;
|
||||
for (size_t j=0; j<elt.numChildren(); j++) {
|
||||
MPlug child = elt.child(j);
|
||||
MFnAttribute att(child.attribute());
|
||||
if (att.name() == "color") color = child;
|
||||
if (att.name() == "blendMode") blend = child;
|
||||
}
|
||||
if (color.isNull() || blend.isNull()) {
|
||||
maya_cat.warning() << "Invalid layered texture - bad inputs.\n";
|
||||
return;
|
||||
}
|
||||
size_t before = list.size();
|
||||
find_textures_modern(shadername, list, color, is_alpha);
|
||||
int blendValue;
|
||||
blend.getValue(blendValue);
|
||||
for (size_t sub=before; sub<list.size(); sub++) {
|
||||
MayaShaderColorDef *def = list[sub];
|
||||
switch (blendValue) {
|
||||
case 1: def->_blend_type = BT_decal; break;
|
||||
case 6: def->_blend_type = BT_modulate; break;
|
||||
case 4: def->_blend_type = BT_add; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (source.apiType() == MFn::kReverse) {
|
||||
MPlug input_plug = sourceFn.findPlug("input");
|
||||
find_textures_modern(shadername, list, input_plug, is_alpha);
|
||||
return;
|
||||
}
|
||||
|
||||
// This shader wasn't understood.
|
||||
if (maya_cat.is_debug()) {
|
||||
maya_cat.info()
|
||||
<< "**Don't know how to interpret color attribute type "
|
||||
<< source.apiTypeStr() << "\n";
|
||||
} else {
|
||||
// If we don't have a heavy verbose count, only report each type of
|
||||
// unsupported shader once.
|
||||
static pset<MFn::Type> bad_types;
|
||||
if (bad_types.insert(source.apiType()).second) {
|
||||
maya_cat.warning()
|
||||
<< "Don't know how to export a shader of type "
|
||||
<< source.apiTypeStr() << " " << sourceFn.type() << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the shader to apply UV's according to the indicated projection
|
||||
* type.
|
||||
*/
|
||||
void MayaShaderColorDef::
|
||||
set_projection_type(const string &type) {
|
||||
if (cmp_nocase(type, "planar") == 0) {
|
||||
_projection_type = PT_planar;
|
||||
_map_uvs = &MayaShaderColorDef::map_planar;
|
||||
|
||||
// The Planar projection normally projects to a range (-1, 1) in both
|
||||
// axes. Scale this into our UV range of (0, 1).
|
||||
_projection_matrix = _projection_matrix * LMatrix4d(0.5, 0.0, 0.0, 0.0,
|
||||
0.0, 0.5, 0.0, 0.0,
|
||||
0.0, 0.0, 1.0, 0.0,
|
||||
0.5, 0.5, 0.0, 1.0);
|
||||
|
||||
} else if (cmp_nocase(type, "cylindrical") == 0) {
|
||||
_projection_type = PT_cylindrical;
|
||||
_map_uvs = &MayaShaderColorDef::map_cylindrical;
|
||||
|
||||
// The cylindrical projection is orthographic in the Y axis; scale the
|
||||
// range (-1, 1) in this axis into our UV range (0, 1).
|
||||
_projection_matrix = _projection_matrix * LMatrix4d(1.0, 0.0, 0.0, 0.0,
|
||||
0.0, 0.5, 0.0, 0.0,
|
||||
0.0, 0.0, 1.0, 0.0,
|
||||
0.0, 0.5, 0.0, 1.0);
|
||||
|
||||
} else if (cmp_nocase(type, "spherical") == 0) {
|
||||
_projection_type = PT_spherical;
|
||||
_map_uvs = &MayaShaderColorDef::map_spherical;
|
||||
|
||||
} else {
|
||||
// Other projection types are currently unimplemented by the converter.
|
||||
maya_cat.error()
|
||||
<< "Don't know how to handle type " << type << " projections.\n";
|
||||
_projection_type = PT_off;
|
||||
_map_uvs = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes a UV based on the given point in space, using a planar projection.
|
||||
*/
|
||||
LPoint2d MayaShaderColorDef::
|
||||
map_planar(const LPoint3d &pos, const LPoint3d &) const {
|
||||
// A planar projection is about as easy as can be. We ignore the Z axis,
|
||||
// and project the point into the XY plane. Done.
|
||||
return LPoint2d(pos[0], pos[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes a UV based on the given point in space, using a spherical
|
||||
* projection.
|
||||
*/
|
||||
LPoint2d MayaShaderColorDef::
|
||||
map_spherical(const LPoint3d &pos, const LPoint3d ¢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;
|
||||
}
|
||||
|
|
@ -1,150 +0,0 @@
|
|||
/**
|
||||
* PANDA 3D SOFTWARE
|
||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
*
|
||||
* All use of this software is subject to the terms of the revised BSD
|
||||
* license. You should have received a copy of this license along
|
||||
* with this source code in a file named "LICENSE."
|
||||
*
|
||||
* @file mayaShaderColorDef.h
|
||||
* @author drose
|
||||
* @date 2003-04-12
|
||||
*/
|
||||
|
||||
#ifndef MAYASHADERCOLORDEF_H
|
||||
#define MAYASHADERCOLORDEF_H
|
||||
|
||||
#include "pandatoolbase.h"
|
||||
|
||||
#include "luse.h"
|
||||
#include "lmatrix.h"
|
||||
#include "pmap.h"
|
||||
#include "pvector.h"
|
||||
|
||||
class MayaShader;
|
||||
class MayaShaderColorDef;
|
||||
typedef pvector<MayaShaderColorDef *> MayaShaderColorList;
|
||||
typedef pmap<std::string, std::string> MayaFileToUVSetMap;
|
||||
|
||||
/**
|
||||
* This defines the various attributes that Maya may associate with the
|
||||
* "color" channel for a particular shader (as well as on the "transparency"
|
||||
* channel).
|
||||
*/
|
||||
class MayaShaderColorDef {
|
||||
public:
|
||||
MayaShaderColorDef();
|
||||
MayaShaderColorDef (MayaShaderColorDef&);
|
||||
~MayaShaderColorDef();
|
||||
|
||||
std::string strip_prefix(std::string full_name);
|
||||
|
||||
LMatrix3d compute_texture_matrix() const;
|
||||
bool has_projection() const;
|
||||
LTexCoordd project_uv(const LPoint3d &pos, const LPoint3d &ref_point) const;
|
||||
bool reset_maya_texture(const Filename &texture);
|
||||
|
||||
void write(std::ostream &out) const;
|
||||
|
||||
enum BlendType {
|
||||
BT_unspecified,
|
||||
BT_modulate,
|
||||
BT_decal,
|
||||
BT_blend,
|
||||
BT_replace,
|
||||
BT_add,
|
||||
BT_blend_color_scale,
|
||||
BT_modulate_glow,
|
||||
BT_modulate_gloss,
|
||||
BT_normal,
|
||||
BT_normal_height,
|
||||
BT_gloss,
|
||||
BT_glow,
|
||||
BT_height,
|
||||
BT_selector,
|
||||
};
|
||||
|
||||
enum ProjectionType {
|
||||
PT_off,
|
||||
PT_planar,
|
||||
PT_spherical,
|
||||
PT_cylindrical,
|
||||
PT_ball,
|
||||
PT_cubic,
|
||||
PT_triplanar,
|
||||
PT_concentric,
|
||||
PT_perspective,
|
||||
};
|
||||
|
||||
BlendType _blend_type;
|
||||
ProjectionType _projection_type;
|
||||
LMatrix4d _projection_matrix;
|
||||
double _u_angle;
|
||||
double _v_angle;
|
||||
|
||||
Filename _texture_filename;
|
||||
std::string _texture_name;
|
||||
LColor _color_gain;
|
||||
|
||||
LVector2 _coverage;
|
||||
LVector2 _translate_frame;
|
||||
double _rotate_frame;
|
||||
|
||||
bool _mirror;
|
||||
bool _stagger;
|
||||
bool _wrap_u;
|
||||
bool _wrap_v;
|
||||
|
||||
LVector2 _repeat_uv;
|
||||
LVector2 _offset;
|
||||
double _rotate_uv;
|
||||
|
||||
bool _is_alpha;
|
||||
|
||||
std::string _uvset_name;
|
||||
MayaShaderColorDef *_opposite;
|
||||
|
||||
std::string get_panda_uvset_name();
|
||||
|
||||
private:
|
||||
MObject *_color_object;
|
||||
|
||||
private:
|
||||
static void find_textures_modern(const std::string &shadername, MayaShaderColorList &list, MPlug inplug, bool is_alpha);
|
||||
void find_textures_legacy(MayaShader *shader, MObject color, bool trans=false);
|
||||
|
||||
void set_projection_type(const std::string &type);
|
||||
|
||||
LPoint2d map_planar(const LPoint3d &pos, const LPoint3d ¢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
|
||||
|
|
@ -1,200 +0,0 @@
|
|||
/**
|
||||
* PANDA 3D SOFTWARE
|
||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
*
|
||||
* All use of this software is subject to the terms of the revised BSD
|
||||
* license. You should have received a copy of this license along
|
||||
* with this source code in a file named "LICENSE."
|
||||
*
|
||||
* @file mayaShaders.cxx
|
||||
* @author drose
|
||||
* @date 2000-02-11
|
||||
*/
|
||||
|
||||
#include "mayaShaders.h"
|
||||
#include "mayaShader.h"
|
||||
#include "maya_funcs.h"
|
||||
#include "config_maya.h"
|
||||
|
||||
#include "pre_maya_include.h"
|
||||
#include <maya/MStatus.h>
|
||||
#include <maya/MObject.h>
|
||||
#include <maya/MFnDependencyNode.h>
|
||||
#include <maya/MFnMesh.h>
|
||||
#include <maya/MObjectArray.h>
|
||||
#include <maya/MPlug.h>
|
||||
#include <maya/MPlugArray.h>
|
||||
#include <maya/MFn.h>
|
||||
#include "post_maya_include.h"
|
||||
|
||||
using std::string;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
MayaShaders::
|
||||
MayaShaders() {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
MayaShaders::
|
||||
~MayaShaders() {
|
||||
clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the shader assigned to the indicated node.
|
||||
*/
|
||||
MayaShader *MayaShaders::
|
||||
find_shader_for_node(MObject node, bool legacy_shader) {
|
||||
MStatus status;
|
||||
MFnDependencyNode node_fn(node);
|
||||
// Look on the instObjGroups attribute for shading engines.
|
||||
MObject iog_attr = node_fn.attribute("instObjGroups", &status);
|
||||
if (!status) {
|
||||
// The node is not renderable. What are you thinking?
|
||||
maya_cat.error()
|
||||
<< node_fn.name().asChar() << " : not a renderable object.\n";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// instObjGroups is a multi attribute, whatever that means. For now, we'll
|
||||
// just get the first connection, since that's what the example code did.
|
||||
// Is there any reason to search deeper?
|
||||
|
||||
MPlug iog_plug(node, iog_attr);
|
||||
MPlugArray iog_pa;
|
||||
iog_plug.elementByLogicalIndex(0).connectedTo(iog_pa, false, true, &status);
|
||||
if (!status) {
|
||||
// No shading group defined for this object.
|
||||
maya_cat.error()
|
||||
<< node_fn.name().asChar() << " : no shading group defined.\n";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Now we have a number of ShadingEngines defined, one for each of these
|
||||
// connections we just turned up. Usually there will only be one. In fact,
|
||||
// we'll just take the first one we find.
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < iog_pa.length(); i++) {
|
||||
MObject engine = iog_pa[i].node();
|
||||
if (engine.hasFn(MFn::kShadingEngine)) {
|
||||
return find_shader_for_shading_engine(engine, legacy_shader);
|
||||
}
|
||||
}
|
||||
|
||||
// Well, we didn't find a ShadingEngine after all. Huh.
|
||||
if (maya_cat.is_debug()) {
|
||||
maya_cat.debug()
|
||||
<< node_fn.name().asChar() << " : no shading engine found.\n";
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Causes all shaders in the set to use the given mesh as a file-to-uvset map.
|
||||
*/
|
||||
void MayaShaders::
|
||||
bind_uvsets(MObject mesh) {
|
||||
_uvset_names.clear();
|
||||
_file_to_uvset.clear();
|
||||
|
||||
if (mesh.hasFn(MFn::kMesh)) {
|
||||
MFnMesh mesh_fn(mesh);
|
||||
MStatus status;
|
||||
MStringArray maya_uvset_names;
|
||||
status = mesh_fn.getUVSetNames(maya_uvset_names);
|
||||
for (size_t i=0; i<maya_uvset_names.length(); ++i) {
|
||||
MObjectArray moa;
|
||||
string uvset_name = maya_uvset_names[i].asChar();
|
||||
_uvset_names.push_back(uvset_name);
|
||||
mesh_fn.getAssociatedUVSetTextures(maya_uvset_names[i], moa);
|
||||
for (size_t j=0; j<moa.length(); ++j){
|
||||
MFnDependencyNode dt(moa[j]);
|
||||
string tex_name = dt.name().asChar();
|
||||
_file_to_uvset[tex_name] = uvset_name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Shaders::iterator sha;
|
||||
for (sha=_shaders.begin(); sha!=_shaders.end(); sha++) {
|
||||
(*sha).second->bind_uvsets(_file_to_uvset);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the MayaShader object associated with the indicated "shading
|
||||
* engine". This will create a new MayaShader object if this is the first
|
||||
* time we have encountered the indicated engine.
|
||||
*/
|
||||
MayaShader *MayaShaders::
|
||||
find_shader_for_shading_engine(MObject engine, bool legacy_shader) {
|
||||
MFnDependencyNode engine_fn(engine);
|
||||
// See if we have already decoded this engine.
|
||||
string engine_name = engine_fn.name().asChar();
|
||||
Shaders::const_iterator si = _shaders.find(engine_name);
|
||||
if (si != _shaders.end()) {
|
||||
return (*si).second;
|
||||
}
|
||||
|
||||
// All right, this is a newly encountered shading engine. Create a new
|
||||
// MayaShader object to represent it.
|
||||
MayaShader *shader = new MayaShader(engine, legacy_shader);
|
||||
shader->bind_uvsets(_file_to_uvset);
|
||||
|
||||
// Record this for the future.
|
||||
_shaders.insert(Shaders::value_type(engine_name, shader));
|
||||
_shaders_in_order.push_back(shader);
|
||||
return shader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current mapping from file to uvset for the given file texture
|
||||
* name.
|
||||
*/
|
||||
string MayaShaders::
|
||||
find_uv_link(const string &match) {
|
||||
MayaFileToUVSetMap::iterator it = _file_to_uvset.find(match);
|
||||
if (it == _file_to_uvset.end()) {
|
||||
return "not found";
|
||||
} else {
|
||||
return (*it).second;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of unique MayaShaders that have been discovered so far.
|
||||
*/
|
||||
int MayaShaders::
|
||||
get_num_shaders() const {
|
||||
return _shaders_in_order.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the nth MayaShader that has been discovered so far.
|
||||
*/
|
||||
MayaShader *MayaShaders::
|
||||
get_shader(int n) const {
|
||||
nassertr(n >= 0 && n < (int)_shaders_in_order.size(), nullptr);
|
||||
return _shaders_in_order[n];
|
||||
}
|
||||
|
||||
/**
|
||||
* Frees all of the previously-defined MayaShader objects associated with this
|
||||
* set.
|
||||
*/
|
||||
void MayaShaders::
|
||||
clear() {
|
||||
ShadersInOrder::iterator si;
|
||||
for (si = _shaders_in_order.begin(); si != _shaders_in_order.end(); ++si) {
|
||||
delete (*si);
|
||||
}
|
||||
|
||||
_shaders.clear();
|
||||
_shaders_in_order.clear();
|
||||
_file_to_uvset.clear();
|
||||
}
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
/**
|
||||
* PANDA 3D SOFTWARE
|
||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
*
|
||||
* All use of this software is subject to the terms of the revised BSD
|
||||
* license. You should have received a copy of this license along
|
||||
* with this source code in a file named "LICENSE."
|
||||
*
|
||||
* @file mayaShaders.h
|
||||
* @author drose
|
||||
* @date 2000-02-11
|
||||
*/
|
||||
|
||||
#ifndef MAYASHADERS_H
|
||||
#define MAYASHADERS_H
|
||||
|
||||
#include "pandatoolbase.h"
|
||||
|
||||
#include "pmap.h"
|
||||
#include "pvector.h"
|
||||
#include "mayaShaderColorDef.h"
|
||||
|
||||
class MayaShader;
|
||||
|
||||
/**
|
||||
* Collects the set of MayaShaders that have been encountered so far.
|
||||
*/
|
||||
class MayaShaders {
|
||||
public:
|
||||
MayaShaders();
|
||||
~MayaShaders();
|
||||
MayaShader *find_shader_for_node(MObject node, bool legacy_shader);
|
||||
MayaShader *find_shader_for_shading_engine(MObject engine, bool legacy_shader);
|
||||
|
||||
int get_num_shaders() const;
|
||||
MayaShader *get_shader(int n) const;
|
||||
|
||||
MayaFileToUVSetMap _file_to_uvset;
|
||||
pvector<std::string> _uvset_names;
|
||||
void clear();
|
||||
void bind_uvsets(MObject mesh);
|
||||
std::string find_uv_link(const std::string &match);
|
||||
|
||||
private:
|
||||
typedef pmap<std::string, MayaShader *> Shaders;
|
||||
Shaders _shaders;
|
||||
typedef pvector<MayaShader *> ShadersInOrder;
|
||||
ShadersInOrder _shaders_in_order;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
/**
|
||||
* PANDA 3D SOFTWARE
|
||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
*
|
||||
* All use of this software is subject to the terms of the revised BSD
|
||||
* license. You should have received a copy of this license along
|
||||
* with this source code in a file named "LICENSE."
|
||||
*
|
||||
* @file maya_funcs.T
|
||||
* @author drose
|
||||
* @date 2000-02-16
|
||||
*/
|
||||
|
||||
/**
|
||||
* A generic function to extract an attribute of some type from an MObject.
|
||||
* This is used to implement get_bool_attribute(), etc.
|
||||
*/
|
||||
template<class ValueType>
|
||||
bool
|
||||
get_maya_attribute(MObject &node, const std::string &attribute_name,
|
||||
ValueType &value) {
|
||||
bool status = false;
|
||||
|
||||
MPlug plug;
|
||||
if (get_maya_plug(node, attribute_name, plug)) {
|
||||
status = plug.getValue(value);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* A generic function to set an attribute of some type on an MObject. This is
|
||||
* used to implement set_bool_attribute(), etc.
|
||||
*/
|
||||
template<class ValueType>
|
||||
bool
|
||||
set_maya_attribute(MObject &node, const std::string &attribute_name,
|
||||
ValueType &value) {
|
||||
bool status = false;
|
||||
|
||||
MPlug plug;
|
||||
if (get_maya_plug(node, attribute_name, plug)) {
|
||||
status = plug.setValue(value);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
|
@ -1,731 +0,0 @@
|
|||
/**
|
||||
* PANDA 3D SOFTWARE
|
||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
*
|
||||
* All use of this software is subject to the terms of the revised BSD
|
||||
* license. You should have received a copy of this license along
|
||||
* with this source code in a file named "LICENSE."
|
||||
*
|
||||
* @file maya_funcs.cxx
|
||||
* @author drose
|
||||
* @date 2000-02-16
|
||||
*/
|
||||
|
||||
#include "maya_funcs.h"
|
||||
|
||||
#include "pre_maya_include.h"
|
||||
#include <maya/MObject.h>
|
||||
#include <maya/MAngle.h>
|
||||
#include <maya/MFnDependencyNode.h>
|
||||
#include <maya/MStatus.h>
|
||||
#include <maya/MFnStringData.h>
|
||||
#include <maya/MFnNumericData.h>
|
||||
#include <maya/MPlugArray.h>
|
||||
#include <maya/MPlug.h>
|
||||
#include <maya/MFnAttribute.h>
|
||||
#include <maya/MFnTypedAttribute.h>
|
||||
#include <maya/MFnNumericAttribute.h>
|
||||
#include <maya/MFnEnumAttribute.h>
|
||||
#include <maya/MFnCompoundAttribute.h>
|
||||
#include <maya/MFnMatrixData.h>
|
||||
#include <maya/MMatrix.h>
|
||||
#include "post_maya_include.h"
|
||||
|
||||
using std::endl;
|
||||
using std::string;
|
||||
|
||||
/**
|
||||
* Gets the named MPlug associated, if any.
|
||||
*/
|
||||
bool
|
||||
get_maya_plug(MObject &node, const string &attribute_name, MPlug &plug) {
|
||||
MStatus status;
|
||||
MFnDependencyNode node_fn(node, &status);
|
||||
if (!status) {
|
||||
maya_cat.error()
|
||||
<< "Object is a " << node.apiTypeStr() << ", not a DependencyNode.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
MObject attr = node_fn.attribute(attribute_name.c_str(), &status);
|
||||
if (!status) {
|
||||
return false;
|
||||
}
|
||||
|
||||
MFnAttribute attr_fn(attr, &status);
|
||||
if (!status) {
|
||||
maya_cat.error()
|
||||
<< "Attribute " << attribute_name << " on " << node_fn.name().asChar()
|
||||
<< " is a " << attr.apiTypeStr() << ", not an Attribute.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
plug = MPlug(node, attr);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the named connection exists on the node and is connected to
|
||||
* anything, false otherwise.
|
||||
*/
|
||||
bool
|
||||
is_connected(MObject &node, const string &attribute_name) {
|
||||
MPlug plug;
|
||||
if (!get_maya_plug(node, attribute_name, plug)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return plug.isConnected();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the node has the indicated attribute, false otherwise.
|
||||
*/
|
||||
bool
|
||||
has_attribute(MObject &node, const string &attribute_name) {
|
||||
MStatus status;
|
||||
MFnDependencyNode node_fn(node, &status);
|
||||
if (!status) {
|
||||
maya_cat.error()
|
||||
<< "Object is a " << node.apiTypeStr() << ", not a DependencyNode.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
node_fn.attribute(attribute_name.c_str(), &status);
|
||||
if (!status) {
|
||||
// No such attribute.
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the named attribute from the indicated Maya node. Returns true if
|
||||
* successful, false otherwise.
|
||||
*/
|
||||
bool
|
||||
remove_attribute(MObject &node, const string &attribute_name) {
|
||||
MStatus status;
|
||||
MFnDependencyNode node_fn(node, &status);
|
||||
if (!status) {
|
||||
maya_cat.error()
|
||||
<< "Object is a " << node.apiTypeStr() << ", not a DependencyNode.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
MObject attr = node_fn.attribute(attribute_name.c_str(), &status);
|
||||
if (!status) {
|
||||
return false;
|
||||
}
|
||||
|
||||
{
|
||||
// Just to prove the the attr is, in fact, an Attribute. According to the
|
||||
// Maya docs, we shouldn't leave the MFnAttribute object around while we
|
||||
// remove the attribute, though.
|
||||
MFnAttribute attr_fn(attr, &status);
|
||||
if (!status) {
|
||||
maya_cat.error()
|
||||
<< "Attribute " << attribute_name << " on " << node_fn.name().asChar()
|
||||
<< " is a " << attr.apiTypeStr() << ", not an Attribute.\n";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
MFnDependencyNode::MAttrClass type = node_fn.attributeClass(attr, &status);
|
||||
if (!status) {
|
||||
maya_cat.error()
|
||||
<< "Couldn't get class of attribute " << attribute_name << " on "
|
||||
<< node_fn.name().asChar() << ".\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
status = node_fn.removeAttribute(attr, type);
|
||||
if (!status) {
|
||||
maya_cat.error()
|
||||
<< "Couldn't remove attribute " << attribute_name << " from "
|
||||
<< node_fn.name().asChar() << ".\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the named boolean attribute from the MObject.
|
||||
*/
|
||||
bool
|
||||
get_bool_attribute(MObject &node, const string &attribute_name,
|
||||
bool &value) {
|
||||
if (!has_attribute(node, attribute_name)) {
|
||||
// For bool attributes only, we assume if the attribute is absent it's the
|
||||
// same thing as being false.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!get_maya_attribute(node, attribute_name, value)) {
|
||||
maya_cat.warning()
|
||||
<< "Attribute " << attribute_name
|
||||
<< " does not have a bool value.\n";
|
||||
describe_maya_attribute(node, attribute_name);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the named angle in degrees from the MObject.
|
||||
*/
|
||||
bool
|
||||
get_angle_attribute(MObject &node, const string &attribute_name,
|
||||
double &value) {
|
||||
MAngle maya_value;
|
||||
if (!get_maya_attribute(node, attribute_name, maya_value)) {
|
||||
maya_cat.warning()
|
||||
<< "Attribute " << attribute_name
|
||||
<< " does not have an angle value.\n";
|
||||
describe_maya_attribute(node, attribute_name);
|
||||
return false;
|
||||
}
|
||||
value = maya_value.asDegrees();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the named two-component vector from the MObject.
|
||||
*/
|
||||
bool
|
||||
get_vec2_attribute(MObject &node, const string &attribute_name,
|
||||
LVecBase2 &value) {
|
||||
MStatus status;
|
||||
|
||||
MObject vec2_object;
|
||||
if (!get_maya_attribute(node, attribute_name, vec2_object)) {
|
||||
maya_cat.warning()
|
||||
<< "Attribute " << attribute_name
|
||||
<< " does not have a vec2 object value.\n";
|
||||
describe_maya_attribute(node, attribute_name);
|
||||
return false;
|
||||
}
|
||||
|
||||
MFnNumericData data(vec2_object, &status);
|
||||
if (!status) {
|
||||
maya_cat.warning()
|
||||
<< "Attribute " << attribute_name << " is of type "
|
||||
<< vec2_object.apiTypeStr() << ", not a NumericData.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
status = data.getData(value[0], value[1]);
|
||||
if (!status) {
|
||||
maya_cat.warning()
|
||||
<< "Unable to extract 2 floats from " << attribute_name
|
||||
<< ", of type " << vec2_object.apiTypeStr() << "\n";
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the named three-component vector from the MObject.
|
||||
*/
|
||||
bool
|
||||
get_vec3_attribute(MObject &node, const string &attribute_name,
|
||||
LVecBase3 &value) {
|
||||
MStatus status;
|
||||
|
||||
MObject vec3_object;
|
||||
if (!get_maya_attribute(node, attribute_name, vec3_object)) {
|
||||
maya_cat.warning()
|
||||
<< "Attribute " << attribute_name
|
||||
<< " does not have a vec3 object value.\n";
|
||||
describe_maya_attribute(node, attribute_name);
|
||||
return false;
|
||||
}
|
||||
|
||||
MFnNumericData data(vec3_object, &status);
|
||||
if (!status) {
|
||||
maya_cat.warning()
|
||||
<< "Attribute " << attribute_name << " is of type "
|
||||
<< vec3_object.apiTypeStr() << ", not a NumericData.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
status = data.getData(value[0], value[1], value[2]);
|
||||
if (!status) {
|
||||
maya_cat.warning()
|
||||
<< "Unable to extract 3 floats from " << attribute_name
|
||||
<< ", of type " << vec3_object.apiTypeStr() << "\n";
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the named two-component vector from the MObject.
|
||||
*/
|
||||
bool
|
||||
get_vec2d_attribute(MObject &node, const string &attribute_name,
|
||||
LVecBase2d &value) {
|
||||
MStatus status;
|
||||
|
||||
MObject vec2d_object;
|
||||
if (!get_maya_attribute(node, attribute_name, vec2d_object)) {
|
||||
maya_cat.warning()
|
||||
<< "Attribute " << attribute_name
|
||||
<< " does not have a vec2d object value.\n";
|
||||
describe_maya_attribute(node, attribute_name);
|
||||
return false;
|
||||
}
|
||||
|
||||
MFnNumericData data(vec2d_object, &status);
|
||||
if (!status) {
|
||||
maya_cat.warning()
|
||||
<< "Attribute " << attribute_name << " is of type "
|
||||
<< vec2d_object.apiTypeStr() << ", not a NumericData.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
status = data.getData(value[0], value[1]);
|
||||
if (!status) {
|
||||
maya_cat.warning()
|
||||
<< "Unable to extract 2 doubles from " << attribute_name
|
||||
<< ", of type " << vec2d_object.apiTypeStr() << "\n";
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the named three-component vector from the MObject.
|
||||
*/
|
||||
bool
|
||||
get_vec3d_attribute(MObject &node, const string &attribute_name,
|
||||
LVecBase3d &value) {
|
||||
MStatus status;
|
||||
|
||||
MObject vec3d_object;
|
||||
if (!get_maya_attribute(node, attribute_name, vec3d_object)) {
|
||||
maya_cat.warning()
|
||||
<< "Attribute " << attribute_name
|
||||
<< " does not have a vec3d object value.\n";
|
||||
describe_maya_attribute(node, attribute_name);
|
||||
return false;
|
||||
}
|
||||
|
||||
MFnNumericData data(vec3d_object, &status);
|
||||
if (!status) {
|
||||
maya_cat.warning()
|
||||
<< "Attribute " << attribute_name << " is of type "
|
||||
<< vec3d_object.apiTypeStr() << ", not a NumericData.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
status = data.getData(value[0], value[1], value[2]);
|
||||
if (!status) {
|
||||
maya_cat.warning()
|
||||
<< "Unable to extract 3 doubles from " << attribute_name
|
||||
<< ", of type " << vec3d_object.apiTypeStr() << "\n";
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the named 4x4 matrix from the MObject.
|
||||
*/
|
||||
bool
|
||||
get_mat4d_attribute(MObject &node, const string &attribute_name,
|
||||
LMatrix4d &value) {
|
||||
MStatus status;
|
||||
MObject matrix;
|
||||
if (!get_maya_attribute(node, attribute_name, matrix)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
MFnMatrixData matrix_data(matrix, &status);
|
||||
if (!status) {
|
||||
maya_cat.warning()
|
||||
<< "Attribute " << attribute_name << " is of type "
|
||||
<< node.apiTypeStr() << ", not a Matrix.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
const MMatrix &mat = matrix_data.matrix();
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int j = 0; j < 4; j++) {
|
||||
value(i, j) = mat(i, j);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* artists should be able to set arbitrary tags. Query all the attributes on
|
||||
* this object and return the lists of attribute names that has "tag" prefix
|
||||
*/
|
||||
void
|
||||
get_tag_attribute_names(MObject &node, pvector<string> &tag_names) {
|
||||
MStatus status;
|
||||
MFnDependencyNode node_fn(node, &status);
|
||||
if (!status) {
|
||||
maya_cat.warning()
|
||||
<< "Object is a " << node.apiTypeStr() << ", not a DependencyNode.\n";
|
||||
return;
|
||||
}
|
||||
|
||||
string name = node_fn.name().asChar();
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < node_fn.attributeCount(); i++) {
|
||||
MObject attr = node_fn.attribute(i, &status);
|
||||
if (status) {
|
||||
MFnAttribute attrib(attr, &status);
|
||||
if (status) {
|
||||
string attribute_name = attrib.name().asChar();
|
||||
if (attribute_name.find("tag", 0) != string::npos) {
|
||||
maya_cat.info() << ":" << name << ":" << " is tagged with <"
|
||||
<< attribute_name << ">" << endl;
|
||||
tag_names.push_back(attribute_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Extracts the enum attribute from the MObject as a string value.
|
||||
*/
|
||||
bool
|
||||
get_enum_attribute(MObject &node, const string &attribute_name,
|
||||
string &value) {
|
||||
MStatus status;
|
||||
|
||||
MPlug plug;
|
||||
if (!get_maya_plug(node, attribute_name.c_str(), plug)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
MObject attrib = plug.attribute();
|
||||
MFnEnumAttribute enum_attrib(attrib, &status);
|
||||
if (!status) {
|
||||
maya_cat.warning()
|
||||
<< "Not an enum attribute: " << attribute_name << "\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
short index;
|
||||
status = plug.getValue(index);
|
||||
if (!status) {
|
||||
maya_cat.warning()
|
||||
<< "Could not get numeric value of " << attribute_name << "\n";
|
||||
status.perror("MPlug::getValue(short)");
|
||||
return false;
|
||||
}
|
||||
|
||||
MString name = enum_attrib.fieldName(index, &status);
|
||||
if (!status) {
|
||||
maya_cat.warning()
|
||||
<< "Invalid value for " << attribute_name << ": " << index << "\n";
|
||||
status.perror("MFnEnumAttribute::fieldName()");
|
||||
return false;
|
||||
}
|
||||
|
||||
value = name.asChar();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the named string attribute from the MObject.
|
||||
*/
|
||||
bool
|
||||
get_string_attribute(MObject &node, const string &attribute_name,
|
||||
string &value) {
|
||||
MStatus status;
|
||||
|
||||
MObject string_object;
|
||||
if (!get_maya_attribute(node, attribute_name, string_object)) {
|
||||
maya_cat.warning()
|
||||
<< "Attribute " << attribute_name
|
||||
<< " does not have an string object value.\n";
|
||||
describe_maya_attribute(node, attribute_name);
|
||||
return false;
|
||||
}
|
||||
|
||||
MFnStringData data(string_object, &status);
|
||||
if (!status) {
|
||||
maya_cat.warning()
|
||||
<< "Attribute " << attribute_name << " is of type "
|
||||
<< string_object.apiTypeStr() << ", not a StringData.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
value = data.string().asChar();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the named string attribute on the MObject.
|
||||
*/
|
||||
bool
|
||||
set_string_attribute(MObject &node, const string &attribute_name,
|
||||
const string &value) {
|
||||
MStatus status;
|
||||
|
||||
// First, we get the string_object, then we set its string.
|
||||
MObject string_object;
|
||||
if (!get_maya_attribute(node, attribute_name, string_object)) {
|
||||
maya_cat.warning()
|
||||
<< "Attribute " << attribute_name
|
||||
<< " does not have a string object value.\n";
|
||||
describe_maya_attribute(node, attribute_name);
|
||||
return false;
|
||||
}
|
||||
|
||||
MFnStringData data(string_object, &status);
|
||||
if (!status) {
|
||||
maya_cat.warning()
|
||||
<< "Attribute " << attribute_name << " is of type "
|
||||
<< string_object.apiTypeStr() << ", not a StringData.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
MString mstring_value(value.data(), value.length());
|
||||
status = data.set(mstring_value);
|
||||
if (!status) {
|
||||
status.perror(attribute_name.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
// And it appears we now need to set the string object back.
|
||||
if (!set_maya_attribute(node, attribute_name, string_object)) {
|
||||
maya_cat.warning()
|
||||
<< "Attribute " << attribute_name
|
||||
<< " suddenly does not have a string object value.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the children of this attribute from the MObject. test for now
|
||||
*/
|
||||
bool
|
||||
describe_compound_attribute(MObject &node) {
|
||||
MStatus status;
|
||||
|
||||
MFnCompoundAttribute comp_attr(node, &status);
|
||||
|
||||
maya_cat.info() << "comp_attr has:" << comp_attr.numChildren() << " children" << endl;
|
||||
for (size_t i = 0; i < comp_attr.numChildren(); i++) {
|
||||
MObject child = comp_attr.child(i, &status);
|
||||
if (child.apiType() == MFn::kAttribute3Float){
|
||||
/*
|
||||
LRGBColor color;
|
||||
if (get_vec3_attribute(child, "color", color)) {
|
||||
maya_cat.info() << "color: " << color << endl;
|
||||
}
|
||||
*/
|
||||
}
|
||||
else if (child.apiType() == MFn::kNumericAttribute) {
|
||||
MFnNumericAttribute numeric(child, &status);
|
||||
if (status) {
|
||||
switch(numeric.unitType()) {
|
||||
case MFnNumericData::kFloat :
|
||||
PN_stdfloat alpha;
|
||||
status = numeric.getDefault(alpha);
|
||||
maya_cat.info() << "found a float :" << alpha << endl;
|
||||
break;
|
||||
case MFnNumericData::kBoolean :
|
||||
bool v;
|
||||
status = numeric.getDefault(v);
|
||||
maya_cat.info() << "found a bool :" << v << endl;
|
||||
default:
|
||||
maya_cat.info() << numeric.unitType() << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (child.apiType() == MFn::kEnumAttribute) {
|
||||
MFnEnumAttribute enu(child, &status);
|
||||
if (status) {
|
||||
MString blah;
|
||||
status = enu.getDefault(blah);
|
||||
maya_cat.info() << "found a string :" << blah.asChar() << endl;
|
||||
MPlug plug = MPlug(node, child);
|
||||
maya_cat.info() << "plug name" << plug.name().asChar() << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes some warning output about the indicated Maya attribute.
|
||||
*/
|
||||
void
|
||||
describe_maya_attribute(MObject &node, const string &attribute_name) {
|
||||
MStatus status;
|
||||
MFnDependencyNode node_fn(node, &status);
|
||||
if (!status) {
|
||||
maya_cat.warning()
|
||||
<< "Object is a " << node.apiTypeStr() << ", not a DependencyNode.\n";
|
||||
return;
|
||||
}
|
||||
|
||||
MObject attr = node_fn.attribute(attribute_name.c_str(), &status);
|
||||
if (!status) {
|
||||
maya_cat.warning()
|
||||
<< "Object " << node_fn.name().asChar() << " does not support attribute "
|
||||
<< attribute_name << "\n";
|
||||
return;
|
||||
}
|
||||
|
||||
maya_cat.warning()
|
||||
<< "Attribute " << attribute_name << " on object "
|
||||
<< node_fn.name().asChar() << " has type " << attr.apiTypeStr() << "\n";
|
||||
}
|
||||
|
||||
string
|
||||
string_mfndata_type(MFnData::Type type) {
|
||||
switch (type) {
|
||||
case MFnData::kInvalid:
|
||||
return "kInvalid";
|
||||
|
||||
case MFnData::kNumeric:
|
||||
return "kNumeric";
|
||||
|
||||
case MFnData::kPlugin:
|
||||
return "kPlugin";
|
||||
|
||||
case MFnData::kPluginGeometry:
|
||||
return "kPluginGeometry";
|
||||
|
||||
case MFnData::kString:
|
||||
return "kString";
|
||||
|
||||
case MFnData::kMatrix:
|
||||
return "kMatrix";
|
||||
|
||||
case MFnData::kStringArray:
|
||||
return "kStringArray";
|
||||
|
||||
case MFnData::kDoubleArray:
|
||||
return "kDoubleArray";
|
||||
|
||||
case MFnData::kIntArray:
|
||||
return "kIntArray";
|
||||
|
||||
case MFnData::kPointArray:
|
||||
return "kPointArray";
|
||||
|
||||
case MFnData::kVectorArray:
|
||||
return "kVectorArray";
|
||||
|
||||
case MFnData::kComponentList:
|
||||
return "kComponentList";
|
||||
|
||||
case MFnData::kMesh:
|
||||
return "kMesh";
|
||||
|
||||
case MFnData::kLattice:
|
||||
return "kLattice";
|
||||
|
||||
case MFnData::kNurbsCurve:
|
||||
return "kNurbsCurve";
|
||||
|
||||
case MFnData::kNurbsSurface:
|
||||
return "kNurbsSurface";
|
||||
|
||||
case MFnData::kSphere:
|
||||
return "kSphere";
|
||||
|
||||
case MFnData::kDynArrayAttrs:
|
||||
return "kDynArrayAttrs";
|
||||
|
||||
case MFnData::kDynSweptGeometry:
|
||||
return "kDynSweptGeometry";
|
||||
|
||||
case MFnData::kSubdSurface:
|
||||
return "kSubdSurface";
|
||||
|
||||
case MFnData::kLast:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return "**invalid**";
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes some info output showing all the attributes on the given dependency
|
||||
* node. Primarily useful during development, to figure out where the heck
|
||||
* Maya hides some of the connected properties.
|
||||
*/
|
||||
void
|
||||
list_maya_attributes(MObject &node) {
|
||||
MStatus status;
|
||||
MFnDependencyNode node_fn(node, &status);
|
||||
if (!status) {
|
||||
maya_cat.warning()
|
||||
<< "Object is a " << node.apiTypeStr() << ", not a DependencyNode.\n";
|
||||
return;
|
||||
}
|
||||
|
||||
string name = node_fn.name().asChar();
|
||||
unsigned i;
|
||||
|
||||
MPlugArray connections;
|
||||
status = node_fn.getConnections(connections);
|
||||
if (!status) {
|
||||
status.perror("MFnDependencyNode::getConnections");
|
||||
|
||||
} else {
|
||||
maya_cat.info()
|
||||
<< name << " has " << connections.length() << " connections.\n";
|
||||
for (i = 0; i < connections.length(); i++) {
|
||||
MPlug plug = connections[i];
|
||||
|
||||
maya_cat.info(false)
|
||||
<< " " << i << ". " << plug.name().asChar() << ", "
|
||||
<< plug.attribute().apiTypeStr() << ", "
|
||||
<< plug.node().apiTypeStr();
|
||||
if (plug.attribute().apiType() == MFn::kCompoundAttribute) {
|
||||
// maya_cat.info() << plug.info();
|
||||
// describe_compound_attribute(plug.attribute());
|
||||
}
|
||||
if (plug.isConnected()) {
|
||||
maya_cat.info(false)
|
||||
<< " (*)";
|
||||
}
|
||||
maya_cat.info(false)
|
||||
<< "\n";
|
||||
}
|
||||
}
|
||||
|
||||
maya_cat.info()
|
||||
<< name << " has " << node_fn.attributeCount() << " attributes.\n";
|
||||
for (i = 0; i < node_fn.attributeCount(); i++) {
|
||||
MObject attr = node_fn.attribute(i, &status);
|
||||
if (status) {
|
||||
MFnTypedAttribute typed_attrib(attr, &status);
|
||||
if (status) {
|
||||
// It's a typed attrib.
|
||||
maya_cat.info(false)
|
||||
<< " " << i << ". " << typed_attrib.name().asChar()
|
||||
<< " [" << attr.apiTypeStr() << ", "
|
||||
<< string_mfndata_type(typed_attrib.attrType()) << "]\n";
|
||||
} else {
|
||||
MFnAttribute attrib(attr, &status);
|
||||
if (status) {
|
||||
// It's a generic attrib.
|
||||
maya_cat.info(false)
|
||||
<< " " << i << ". " << attrib.name().asChar()
|
||||
<< " [" << attr.apiTypeStr() << "]\n";
|
||||
} else {
|
||||
// Don't know what it is.
|
||||
maya_cat.info(false)
|
||||
<< " " << i << ". [" << attr.apiTypeStr() << "]\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,118 +0,0 @@
|
|||
/**
|
||||
* PANDA 3D SOFTWARE
|
||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
*
|
||||
* All use of this software is subject to the terms of the revised BSD
|
||||
* license. You should have received a copy of this license along
|
||||
* with this source code in a file named "LICENSE."
|
||||
*
|
||||
* @file maya_funcs.h
|
||||
* @author drose
|
||||
* @date 2000-02-16
|
||||
*/
|
||||
|
||||
#ifndef MAYA_FUNCS_H
|
||||
#define MAYA_FUNCS_H
|
||||
|
||||
#include "pandatoolbase.h"
|
||||
#include "luse.h"
|
||||
#include "config_maya.h"
|
||||
|
||||
#include "pre_maya_include.h"
|
||||
#include <maya/MFnAttribute.h>
|
||||
#include <maya/MPlug.h>
|
||||
#include <maya/MStatus.h>
|
||||
#include <maya/MFnDependencyNode.h>
|
||||
#include <maya/MObject.h>
|
||||
#include <maya/MString.h>
|
||||
#include <maya/MVector.h>
|
||||
#include "post_maya_include.h"
|
||||
|
||||
|
||||
bool
|
||||
get_maya_plug(MObject &node, const std::string &attribute_name, MPlug &plug);
|
||||
|
||||
bool
|
||||
is_connected(MObject &node, const std::string &attribute_name);
|
||||
|
||||
template<class ValueType>
|
||||
bool
|
||||
get_maya_attribute(MObject &node, const std::string &attribute_name,
|
||||
ValueType &value);
|
||||
|
||||
template<class ValueType>
|
||||
bool
|
||||
set_maya_attribute(MObject &node, const std::string &attribute_name,
|
||||
ValueType &value);
|
||||
|
||||
bool
|
||||
has_attribute(MObject &node, const std::string &attribute_name);
|
||||
|
||||
bool
|
||||
remove_attribute(MObject &node, const std::string &attribute_name);
|
||||
|
||||
bool
|
||||
get_bool_attribute(MObject &node, const std::string &attribute_name,
|
||||
bool &value);
|
||||
|
||||
bool
|
||||
get_angle_attribute(MObject &node, const std::string &attribute_name,
|
||||
double &value);
|
||||
|
||||
bool
|
||||
get_vec2_attribute(MObject &node, const std::string &attribute_name,
|
||||
LVecBase2 &value);
|
||||
|
||||
bool
|
||||
get_vec3_attribute(MObject &node, const std::string &attribute_name,
|
||||
LVecBase3 &value);
|
||||
|
||||
bool
|
||||
get_vec2d_attribute(MObject &node, const std::string &attribute_name,
|
||||
LVecBase2d &value);
|
||||
|
||||
bool
|
||||
get_vec3d_attribute(MObject &node, const std::string &attribute_name,
|
||||
LVecBase3d &value);
|
||||
|
||||
bool
|
||||
get_mat4d_attribute(MObject &node, const std::string &attribute_name,
|
||||
LMatrix4d &value);
|
||||
|
||||
void
|
||||
get_tag_attribute_names(MObject &node, pvector<std::string> &tag_names);
|
||||
|
||||
bool
|
||||
get_enum_attribute(MObject &node, const std::string &attribute_name,
|
||||
std::string &value);
|
||||
|
||||
bool
|
||||
get_string_attribute(MObject &node, const std::string &attribute_name,
|
||||
std::string &value);
|
||||
|
||||
bool
|
||||
set_string_attribute(MObject &node, const std::string &attribute_name,
|
||||
const std::string &value);
|
||||
|
||||
void
|
||||
describe_maya_attribute(MObject &node, const std::string &attribute_name);
|
||||
|
||||
bool
|
||||
describe_compound_attribute(MObject &node);
|
||||
|
||||
std::string
|
||||
string_mfndata_type(MFnData::Type type);
|
||||
|
||||
void
|
||||
list_maya_attributes(MObject &node);
|
||||
|
||||
// Also, we must define some output functions for Maya objects, since we can't
|
||||
// use those built into Maya (which forward-defines the ostream type
|
||||
// incorrectly).
|
||||
INLINE std::ostream &operator << (std::ostream &out, const MString &str);
|
||||
INLINE std::ostream &operator << (std::ostream &out, const MVector &vec);
|
||||
|
||||
#include "maya_funcs.I"
|
||||
#include "maya_funcs.T"
|
||||
|
||||
#endif
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
#include "config_maya.cxx"
|
||||
#include "mayaApi.cxx"
|
||||
#include "mayaShader.cxx"
|
||||
#include "mayaShaderColorDef.cxx"
|
||||
#include "mayaShaders.cxx"
|
||||
#include "maya_funcs.cxx"
|
||||
|
|
@ -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.
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
/**
|
||||
* PANDA 3D SOFTWARE
|
||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
*
|
||||
* All use of this software is subject to the terms of the revised BSD
|
||||
* license. You should have received a copy of this license along
|
||||
* with this source code in a file named "LICENSE."
|
||||
*
|
||||
* @file pre_maya_include.h
|
||||
* @author drose
|
||||
* @date 2002-04-11
|
||||
*/
|
||||
|
||||
// This header file defines a few things that are necessary to define before
|
||||
// including any Maya headers, just to work around some of Maya's assumptions
|
||||
// about the compiler. It must not try to protect itself from multiple
|
||||
// inclusion with #ifdef .. #endif, since it must be used each time it is
|
||||
// included.
|
||||
|
||||
// Maya 2008 will declare some VS2005-specific hacks unless we define this.
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1400
|
||||
#define MLIBRARY_DONTUSE_MFC_MANIFEST
|
||||
#endif
|
||||
|
||||
// Maya will try to typedef bool unless this symbol is defined.
|
||||
#ifndef _BOOL
|
||||
#define _BOOL 1
|
||||
#endif
|
||||
|
||||
// In Maya 5.0, the headers seem to provide the manifest REQUIRE_IOSTREAM,
|
||||
// which forces it to use the new <iostream> headers instead of the old
|
||||
// <iostream.h> headers. It also says this is for Linux only, but it seems to
|
||||
// work just fine on Windows, obviating the need for sneaky #defines in this
|
||||
// and in post_maya_include.h.
|
||||
#ifdef PHAVE_IOSTREAM
|
||||
#define REQUIRE_IOSTREAM
|
||||
#endif // PHAVE_IOSTREAM
|
||||
|
||||
#ifdef __MACH__
|
||||
#define OSMac_ 1
|
||||
// This defines MAYA_API_VERSION
|
||||
#include <maya/MTypes.h>
|
||||
#if MAYA_API_VERSION < 201600
|
||||
#include <maya/OpenMayaMac.h>
|
||||
#endif
|
||||
#else
|
||||
// This defines MAYA_API_VERSION
|
||||
#include <maya/MTypes.h>
|
||||
#endif
|
||||
|
||||
#if MAYA_API_VERSION >= 20180000
|
||||
#include <maya/MApiNamespace.h>
|
||||
#else
|
||||
class MObject;
|
||||
class MDagPath;
|
||||
class MFloatArray;
|
||||
class MFnDagNode;
|
||||
class MFnMesh;
|
||||
class MFnNurbsCurve;
|
||||
class MFnNurbsSurface;
|
||||
class MPlug;
|
||||
class MPointArray;
|
||||
#endif
|
||||
|
|
@ -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();
|
||||
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
/**
|
||||
* PANDA 3D SOFTWARE
|
||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
*
|
||||
* All use of this software is subject to the terms of the revised BSD
|
||||
* license. You should have received a copy of this license along
|
||||
* with this source code in a file named "LICENSE."
|
||||
*
|
||||
* @file mayaBlendDesc.h
|
||||
* @author drose
|
||||
* @date 2004-02-10
|
||||
*/
|
||||
|
||||
#ifndef MAYABLENDDESC_H
|
||||
#define MAYABLENDDESC_H
|
||||
|
||||
#include "pandatoolbase.h"
|
||||
|
||||
#include "referenceCount.h"
|
||||
#include "pointerTo.h"
|
||||
#include "namable.h"
|
||||
|
||||
#include "pre_maya_include.h"
|
||||
#include <maya/MFnBlendShapeDeformer.h>
|
||||
#include <maya/MObject.h>
|
||||
#include "post_maya_include.h"
|
||||
|
||||
class EggTable;
|
||||
class EggSAnimData;
|
||||
|
||||
/**
|
||||
* A handle to a Maya blend shape description. This is just one target of a
|
||||
* Maya BlendShape object, and thus corresponds more or less one-to-one with a
|
||||
* single Egg morph target. (We don't attempt to support Maya's chained
|
||||
* target shapes here; should we need to later, it would mean breaking each of
|
||||
* those target shapes on the one continuous Maya slider into a separate
|
||||
* MayaBlendDesc object, and synthesizing the egg slider values
|
||||
* appropriately.)
|
||||
*/
|
||||
class MayaBlendDesc : public ReferenceCount, public Namable {
|
||||
public:
|
||||
MayaBlendDesc(MFnBlendShapeDeformer &deformer, int weight_index);
|
||||
~MayaBlendDesc();
|
||||
|
||||
void set_slider(PN_stdfloat value);
|
||||
PN_stdfloat get_slider() const;
|
||||
|
||||
private:
|
||||
void clear_egg();
|
||||
|
||||
MFnBlendShapeDeformer _deformer;
|
||||
int _weight_index;
|
||||
|
||||
EggSAnimData *_anim;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
ReferenceCount::init_type();
|
||||
Namable::init_type();
|
||||
register_type(_type_handle, "MayaBlendDesc",
|
||||
ReferenceCount::get_class_type(),
|
||||
Namable::get_class_type());
|
||||
}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
|
||||
friend class MayaNodeTree;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
@ -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
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -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
|
||||
|
|
@ -1,572 +0,0 @@
|
|||
/**
|
||||
* PANDA 3D SOFTWARE
|
||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
*
|
||||
* All use of this software is subject to the terms of the revised BSD
|
||||
* license. You should have received a copy of this license along
|
||||
* with this source code in a file named "LICENSE."
|
||||
*
|
||||
* @file mayaNodeDesc.cxx
|
||||
* @author drose
|
||||
* @date 2003-06-06
|
||||
*/
|
||||
|
||||
#include "mayaNodeDesc.h"
|
||||
#include "mayaNodeTree.h"
|
||||
#include "mayaBlendDesc.h"
|
||||
#include "mayaToEggConverter.h"
|
||||
#include "maya_funcs.h"
|
||||
#include "eggGroup.h"
|
||||
#include "config_mayaegg.h"
|
||||
|
||||
#include "pre_maya_include.h"
|
||||
#include <maya/MFnBlendShapeDeformer.h>
|
||||
#include <maya/MItDependencyGraph.h>
|
||||
#include <maya/MFnNurbsSurface.h>
|
||||
#include <maya/MFnMesh.h>
|
||||
#include "post_maya_include.h"
|
||||
|
||||
using std::string;
|
||||
|
||||
TypeHandle MayaNodeDesc::_type_handle;
|
||||
|
||||
// This is a list of the names of Maya connections that count as a transform.
|
||||
static const char *transform_connections[] = {
|
||||
"translate",
|
||||
"translateX",
|
||||
"translateY",
|
||||
"translateZ",
|
||||
"rotate",
|
||||
"rotateX",
|
||||
"rotateY",
|
||||
"rotateZ",
|
||||
};
|
||||
static const int num_transform_connections = sizeof(transform_connections) / sizeof(const char *);
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
MayaNodeDesc::
|
||||
MayaNodeDesc(MayaNodeTree *tree, MayaNodeDesc *parent, const string &name) :
|
||||
Namable(name),
|
||||
_tree(tree),
|
||||
_parent(parent)
|
||||
{
|
||||
_dag_path = nullptr;
|
||||
_egg_group = nullptr;
|
||||
_egg_table = nullptr;
|
||||
_anim = nullptr;
|
||||
_joint_type = JT_none;
|
||||
_is_lod = false;
|
||||
_tagged = false;
|
||||
_joint_tagged = false;
|
||||
|
||||
// Add ourselves to our parent.
|
||||
if (_parent != nullptr) {
|
||||
_parent->_children.push_back(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
MayaNodeDesc::
|
||||
~MayaNodeDesc() {
|
||||
delete _dag_path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates an association between the MayaNodeDesc and some Maya instance.
|
||||
*/
|
||||
void MayaNodeDesc::
|
||||
from_dag_path(const MDagPath &dag_path, MayaToEggConverter *converter) {
|
||||
MStatus status;
|
||||
|
||||
if (_dag_path == nullptr) {
|
||||
_dag_path = new MDagPath(dag_path);
|
||||
|
||||
string name;
|
||||
MFnDagNode dag_node(dag_path, &status);
|
||||
if (!status) {
|
||||
status.perror("MFnDagNode constructor");
|
||||
} else {
|
||||
name = dag_node.name().asChar();
|
||||
}
|
||||
|
||||
if (_dag_path->hasFn(MFn::kJoint) || converter->force_joint(name)) {
|
||||
// This node is a joint, or the user specifically asked to treat it like
|
||||
// a joint.
|
||||
_joint_type = JT_joint;
|
||||
if (_parent != nullptr) {
|
||||
_parent->mark_joint_parent();
|
||||
}
|
||||
|
||||
} else {
|
||||
// The node is not a joint, but maybe its transform is controlled by
|
||||
// connected inputs. If so, we should treat it like a joint.
|
||||
bool transform_connected = false;
|
||||
|
||||
MStatus status;
|
||||
MObject node = dag_path.node(&status);
|
||||
if (status) {
|
||||
for (int i = 0;
|
||||
i < num_transform_connections && !transform_connected;
|
||||
i++) {
|
||||
if (is_connected(node, transform_connections[i])) {
|
||||
transform_connected = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (transform_connected) {
|
||||
_joint_type = JT_joint;
|
||||
if (_parent != nullptr) {
|
||||
_parent->mark_joint_parent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dag_path.hasFn(MFn::kNurbsSurface)) {
|
||||
MFnNurbsSurface surface(dag_path, &status);
|
||||
if (status) {
|
||||
check_blend_shapes(surface, "create");
|
||||
}
|
||||
} else if (dag_path.hasFn(MFn::kMesh)) {
|
||||
MFnMesh mesh(dag_path, &status);
|
||||
if (status) {
|
||||
check_blend_shapes(mesh, "inMesh");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if a Maya dag path has been associated with this node, false
|
||||
* otherwise.
|
||||
*/
|
||||
bool MayaNodeDesc::
|
||||
has_dag_path() const {
|
||||
return (_dag_path != nullptr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the dag path associated with this node. It is an error to call
|
||||
* this unless has_dag_path() returned true.
|
||||
*/
|
||||
const MDagPath &MayaNodeDesc::
|
||||
get_dag_path() const {
|
||||
nassertr(_dag_path != nullptr, *_dag_path);
|
||||
return *_dag_path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of unique MayaBlendDesc objects (and hence the number of
|
||||
* morph sliders) that affect the geometry in this node.
|
||||
*/
|
||||
int MayaNodeDesc::
|
||||
get_num_blend_descs() const {
|
||||
return _blend_descs.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the nth MayaBlendDesc object that affects the geometry in this
|
||||
* node.
|
||||
*/
|
||||
MayaBlendDesc *MayaNodeDesc::
|
||||
get_blend_desc(int n) const {
|
||||
nassertr(n >= 0 && n < (int)_blend_descs.size(), nullptr);
|
||||
return _blend_descs[n];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the node should be treated as a joint by the converter.
|
||||
*/
|
||||
bool MayaNodeDesc::
|
||||
is_joint() const {
|
||||
// return _joint_type == JT_joint || _joint_type == JT_pseudo_joint;
|
||||
return _joint_tagged && (_joint_type == JT_joint || _joint_type == JT_pseudo_joint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the node is the parent or ancestor of a joint.
|
||||
*/
|
||||
bool MayaNodeDesc::
|
||||
is_joint_parent() const {
|
||||
return _joint_type == JT_joint_parent;
|
||||
// return _joint_tagged && (_joint_type == JT_joint_parent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the node has been joint_tagged to be converted, false
|
||||
* otherwise.
|
||||
*/
|
||||
bool MayaNodeDesc::
|
||||
is_joint_tagged() const {
|
||||
return _joint_tagged;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tags this node for conversion, but does not tag child nodes.
|
||||
*/
|
||||
void MayaNodeDesc::
|
||||
tag_joint() {
|
||||
_joint_tagged = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tags this node and all descendant nodes for conversion.
|
||||
*/
|
||||
void MayaNodeDesc::
|
||||
tag_joint_recursively() {
|
||||
_joint_tagged = true;
|
||||
// mayaegg_cat.info() << "tjr: " << get_name() << endl;
|
||||
Children::const_iterator ci;
|
||||
for (ci = _children.begin(); ci != _children.end(); ++ci) {
|
||||
MayaNodeDesc *child = (*ci);
|
||||
child->tag_joint_recursively();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the node has been tagged to be converted, false otherwise.
|
||||
*/
|
||||
bool MayaNodeDesc::
|
||||
is_tagged() const {
|
||||
return _tagged;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tags this node for conversion, but does not tag child nodes.
|
||||
*/
|
||||
void MayaNodeDesc::
|
||||
tag() {
|
||||
_tagged = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Un-tags this node for conversion, but does not tag child nodes.
|
||||
*/
|
||||
void MayaNodeDesc::
|
||||
untag() {
|
||||
_tagged = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tags this node and all descendant nodes for conversion.
|
||||
*/
|
||||
void MayaNodeDesc::
|
||||
tag_recursively() {
|
||||
_tagged = true;
|
||||
|
||||
Children::const_iterator ci;
|
||||
for (ci = _children.begin(); ci != _children.end(); ++ci) {
|
||||
MayaNodeDesc *child = (*ci);
|
||||
child->tag_recursively();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Un-tags this node and all descendant nodes for conversion.
|
||||
*/
|
||||
void MayaNodeDesc::
|
||||
untag_recursively() {
|
||||
_tagged = false;
|
||||
|
||||
Children::const_iterator ci;
|
||||
for (ci = _children.begin(); ci != _children.end(); ++ci) {
|
||||
MayaNodeDesc *child = (*ci);
|
||||
child->untag_recursively();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this node or any of its parent has_object_type of
|
||||
* object_type.
|
||||
*/
|
||||
bool MayaNodeDesc::
|
||||
has_object_type(string object_type) const {
|
||||
bool ret = false;
|
||||
if ((_egg_group != nullptr)
|
||||
&& _egg_group->has_object_type(object_type)) {
|
||||
return true;
|
||||
}
|
||||
if (_parent != nullptr) {
|
||||
ret |= _parent->has_object_type(object_type);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively clears the egg pointers from this node and all children.
|
||||
*/
|
||||
void MayaNodeDesc::
|
||||
clear_egg() {
|
||||
_egg_group = nullptr;
|
||||
_egg_table = nullptr;
|
||||
_anim = nullptr;
|
||||
|
||||
Children::const_iterator ci;
|
||||
for (ci = _children.begin(); ci != _children.end(); ++ci) {
|
||||
MayaNodeDesc *child = (*ci);
|
||||
child->clear_egg();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates that this node has at least one child that is a joint or a
|
||||
* pseudo-joint.
|
||||
*/
|
||||
void MayaNodeDesc::
|
||||
mark_joint_parent() {
|
||||
if (_joint_type == JT_none) {
|
||||
_joint_type = JT_joint_parent;
|
||||
if (_parent != nullptr) {
|
||||
_parent->mark_joint_parent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Walks the hierarchy, looking for non-joint nodes that are both children and
|
||||
* parents of a joint. These nodes are deemed to be pseudo joints, since the
|
||||
* converter must treat them as joints.
|
||||
*/
|
||||
void MayaNodeDesc::
|
||||
check_pseudo_joints(bool joint_above) {
|
||||
static uint32_t space_count = 0;
|
||||
string space;
|
||||
for (uint32_t idx=0; idx<space_count; ++idx) {
|
||||
space.append(" ");
|
||||
}
|
||||
if (mayaegg_cat.is_spam()) {
|
||||
mayaegg_cat.spam() << "cpj:" << space << get_name() << " joint_type: " << _joint_type << std::endl;
|
||||
}
|
||||
if (_joint_type == JT_joint_parent && joint_above) {
|
||||
// This is one such node: it is the parent of a joint (JT_joint_parent is
|
||||
// set), and it is the child of a joint (joint_above is set).
|
||||
_joint_type = JT_pseudo_joint;
|
||||
}
|
||||
|
||||
if (_joint_type == JT_joint) {
|
||||
// If this node is itself a joint, then joint_above is true for all child
|
||||
// nodes.
|
||||
joint_above = true;
|
||||
}
|
||||
|
||||
// Don't bother traversing further if _joint_type is none, since that means
|
||||
// this node has no joint children.
|
||||
if (_joint_type != JT_none) {
|
||||
|
||||
bool any_joints = false;
|
||||
Children::const_iterator ci;
|
||||
for (ci = _children.begin(); ci != _children.end(); ++ci) {
|
||||
MayaNodeDesc *child = (*ci);
|
||||
if (mayaegg_cat.is_spam()) {
|
||||
++space_count;
|
||||
}
|
||||
child->check_pseudo_joints(joint_above);
|
||||
// if (child->is_joint()) {
|
||||
if (child->_joint_type == JT_joint || child->_joint_type == JT_pseudo_joint) {
|
||||
any_joints = true;
|
||||
}
|
||||
}
|
||||
|
||||
// If any children qualify as joints, then any sibling nodes that are
|
||||
// parents of joints are also elevated to joints.
|
||||
if (any_joints) {
|
||||
bool all_joints = true;
|
||||
for (ci = _children.begin(); ci != _children.end(); ++ci) {
|
||||
MayaNodeDesc *child = (*ci);
|
||||
MStatus status;
|
||||
MFnDagNode dag_node(child->get_dag_path(), &status);
|
||||
if (!status) {
|
||||
status.perror("MFnDagNode constructor");
|
||||
}
|
||||
string type_name = dag_node.typeName().asChar();
|
||||
if (child->_joint_type == JT_joint_parent) {
|
||||
child->_joint_type = JT_pseudo_joint;
|
||||
} else if (child->_joint_type == JT_none) {
|
||||
if (mayaegg_cat.is_spam()) {
|
||||
mayaegg_cat.spam() << "cpj: " << space << "jt_none for " << child->get_name() << std::endl;
|
||||
}
|
||||
if (type_name.find("transform") == string::npos) {
|
||||
if (mayaegg_cat.is_spam()) {
|
||||
mayaegg_cat.spam() << "cpj: " << space << "all_joints false for " << get_name() << std::endl;
|
||||
}
|
||||
all_joints = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (all_joints) {
|
||||
// Finally, if all children are joints, then we are too.
|
||||
if (_joint_type == JT_joint_parent) {
|
||||
if (!get_name().empty()) { // make sure parent of root is not a joint
|
||||
_joint_type = JT_pseudo_joint;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mayaegg_cat.is_spam()) {
|
||||
if (space_count > 0)
|
||||
--space_count;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks for blend shapes on a NURBS surface or polygon mesh and records any
|
||||
* blend shapes found. This is similar to
|
||||
* MayaToEggConverter::get_vertex_weights(), which checks for membership of
|
||||
* vertices to joints; Maya stores the blend shape table in the same place.
|
||||
* See the comments in get_vertex_weights() for a more in-depth description of
|
||||
* the iteration process here.
|
||||
*/
|
||||
void MayaNodeDesc::
|
||||
check_blend_shapes(const MFnDagNode &node, const string &attrib_name) {
|
||||
MStatus status;
|
||||
|
||||
MObject attr = node.attribute(attrib_name.c_str());
|
||||
|
||||
MPlug history(node.object(), attr);
|
||||
MItDependencyGraph it(history, MFn::kDependencyNode,
|
||||
MItDependencyGraph::kUpstream,
|
||||
MItDependencyGraph::kDepthFirst,
|
||||
MItDependencyGraph::kNodeLevel);
|
||||
|
||||
while (!it.isDone()) {
|
||||
MObject c_node = it.thisNode();
|
||||
|
||||
if (c_node.hasFn(MFn::kBlendShape)) {
|
||||
MFnBlendShapeDeformer blends(c_node, &status);
|
||||
if (!status) {
|
||||
status.perror("MFnBlendShapeDeformer constructor");
|
||||
|
||||
} else {
|
||||
// Check if the slider is a "parallel blender", which is a construct
|
||||
// created by Maya for Maya's internal purposes only. We don't want
|
||||
// to fiddle with the parallel blenders.
|
||||
MPlug plug = blends.findPlug("pb");
|
||||
bool is_parallel_blender;
|
||||
status = plug.getValue(is_parallel_blender);
|
||||
if (!status) {
|
||||
status.perror("Could not get value of pb plug.");
|
||||
is_parallel_blender = false;
|
||||
}
|
||||
|
||||
if (is_parallel_blender ||
|
||||
_tree->ignore_slider(blends.name().asChar())) {
|
||||
_tree->report_ignored_slider(blends.name().asChar());
|
||||
|
||||
} else {
|
||||
MObjectArray base_objects;
|
||||
status = blends.getBaseObjects(base_objects);
|
||||
if (!status) {
|
||||
status.perror("MFnBlendShapeDeformer::getBaseObjects");
|
||||
} else {
|
||||
for (unsigned int oi = 0; oi < base_objects.length(); oi++) {
|
||||
MObject base_object = base_objects[oi];
|
||||
|
||||
MIntArray index_list;
|
||||
status = blends.weightIndexList(index_list);
|
||||
if (!status) {
|
||||
status.perror("MFnBlendShapeDeformer::weightIndexList");
|
||||
} else {
|
||||
for (unsigned int i = 0; i < index_list.length(); i++) {
|
||||
int wi = index_list[i];
|
||||
PT(MayaBlendDesc) blend_desc = new MayaBlendDesc(blends, wi);
|
||||
blend_desc = _tree->add_blend_desc(blend_desc);
|
||||
_blend_descs.push_back(blend_desc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
it.next();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Walks through the hierarchy again and checks for LOD specifications. Any
|
||||
* such specifications found are recorded on the child nodes of the lodGroups
|
||||
* themselves: the nodes that actually switch in and out. (This is the way
|
||||
* they are recorded in an egg file.)
|
||||
*/
|
||||
void MayaNodeDesc::
|
||||
check_lods() {
|
||||
// Walk through the children first. This makes it easier in the below (we
|
||||
// only have to return in the event of an error).
|
||||
Children::iterator ci;
|
||||
for (ci = _children.begin(); ci != _children.end(); ++ci) {
|
||||
MayaNodeDesc *child = (*ci);
|
||||
child->check_lods();
|
||||
}
|
||||
|
||||
// Now consider whether this node is an lodGroup.
|
||||
if (_dag_path != nullptr &&
|
||||
_dag_path->hasFn(MFn::kLodGroup)) {
|
||||
// This node is a parent lodGroup; its children, therefore, are LOD's.
|
||||
MStatus status;
|
||||
MFnDagNode dag_node(*_dag_path, &status);
|
||||
if (!status) {
|
||||
status.perror("Couldn't get node from dag path for lodGroup");
|
||||
return;
|
||||
}
|
||||
|
||||
MPlug plug = dag_node.findPlug("threshold", &status);
|
||||
if (!status) {
|
||||
status.perror("Couldn't get threshold attributes on lodGroup");
|
||||
return;
|
||||
}
|
||||
|
||||
// There ought to be the one fewer elements in the array than there are
|
||||
// children of the node.
|
||||
unsigned int num_elements = plug.numElements();
|
||||
unsigned int num_children = _children.size();
|
||||
if (num_elements + 1 != num_children) {
|
||||
mayaegg_cat.warning()
|
||||
<< "Node " << get_name() << " has " << num_elements
|
||||
<< " LOD entries, but " << num_children << " children.\n";
|
||||
}
|
||||
|
||||
// Should we also consider cameraMatrix, to transform the LOD's origin?
|
||||
// It's not clear precisely what this transform matrix means in Maya, so
|
||||
// we'll wait until we have a sample file that demonstrates its use.
|
||||
|
||||
double switch_out = 0.0;
|
||||
unsigned int i = 0;
|
||||
while (i < num_elements && i < num_children) {
|
||||
MPlug element = plug.elementByLogicalIndex(i);
|
||||
MayaNodeDesc *child = _children[i];
|
||||
|
||||
double switch_in;
|
||||
status = element.getValue(switch_in);
|
||||
if (!status) {
|
||||
status.perror("Couldn't get double value from threshold.");
|
||||
return;
|
||||
}
|
||||
|
||||
child->_is_lod = true;
|
||||
child->_switch_in = switch_in;
|
||||
child->_switch_out = switch_out;
|
||||
|
||||
switch_out = switch_in;
|
||||
++i;
|
||||
}
|
||||
|
||||
while (i < num_children) {
|
||||
// Also set the last child(ren). Maya wants this to switch in at
|
||||
// infinity, but Panda doesn't have such a concept; we'll settle for
|
||||
// four times the switch_out distance.
|
||||
MayaNodeDesc *child = _children[i];
|
||||
child->_is_lod = true;
|
||||
child->_switch_in = switch_out * 4.0;
|
||||
child->_switch_out = switch_out;
|
||||
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,122 +0,0 @@
|
|||
/**
|
||||
* PANDA 3D SOFTWARE
|
||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
*
|
||||
* All use of this software is subject to the terms of the revised BSD
|
||||
* license. You should have received a copy of this license along
|
||||
* with this source code in a file named "LICENSE."
|
||||
*
|
||||
* @file mayaNodeDesc.h
|
||||
* @author drose
|
||||
* @date 2003-06-06
|
||||
*/
|
||||
|
||||
#ifndef MAYANODEDESC_H
|
||||
#define MAYANODEDESC_H
|
||||
|
||||
#include "pandatoolbase.h"
|
||||
|
||||
#include "mayaBlendDesc.h"
|
||||
#include "referenceCount.h"
|
||||
#include "pointerTo.h"
|
||||
#include "namable.h"
|
||||
|
||||
#include "pre_maya_include.h"
|
||||
#include <maya/MDagPath.h>
|
||||
#include <maya/MFnDagNode.h>
|
||||
#include "post_maya_include.h"
|
||||
|
||||
class MayaToEggConverter;
|
||||
class MayaNodeTree;
|
||||
class EggGroup;
|
||||
class EggTable;
|
||||
class EggXfmSAnim;
|
||||
|
||||
/**
|
||||
* Describes a single instance of a node in the Maya scene graph, relating it
|
||||
* to the corresponding egg structures (e.g. node, group, or table entry)
|
||||
* that will be created.
|
||||
*/
|
||||
class MayaNodeDesc : public ReferenceCount, public Namable {
|
||||
public:
|
||||
MayaNodeDesc(MayaNodeTree *tree,
|
||||
MayaNodeDesc *parent = nullptr, const std::string &name = std::string());
|
||||
~MayaNodeDesc();
|
||||
|
||||
void from_dag_path(const MDagPath &dag_path, MayaToEggConverter *converter);
|
||||
bool has_dag_path() const;
|
||||
const MDagPath &get_dag_path() const;
|
||||
|
||||
int get_num_blend_descs() const;
|
||||
MayaBlendDesc *get_blend_desc(int n) const;
|
||||
|
||||
bool is_joint() const;
|
||||
bool is_joint_parent() const;
|
||||
|
||||
bool is_tagged() const;
|
||||
bool is_joint_tagged() const;
|
||||
bool has_object_type(std::string object_type) const;
|
||||
|
||||
MayaNodeTree *_tree;
|
||||
MayaNodeDesc *_parent;
|
||||
typedef pvector< PT(MayaNodeDesc) > Children;
|
||||
Children _children;
|
||||
|
||||
private:
|
||||
void tag();
|
||||
void untag();
|
||||
void tag_recursively();
|
||||
void untag_recursively();
|
||||
void tag_joint();
|
||||
void tag_joint_recursively();
|
||||
|
||||
void clear_egg();
|
||||
void mark_joint_parent();
|
||||
void check_pseudo_joints(bool joint_above);
|
||||
void check_blend_shapes(const MFnDagNode &node,
|
||||
const std::string &attrib_name);
|
||||
void check_lods();
|
||||
|
||||
MDagPath *_dag_path;
|
||||
|
||||
EggGroup *_egg_group;
|
||||
EggTable *_egg_table;
|
||||
EggXfmSAnim *_anim;
|
||||
|
||||
typedef pvector< PT(MayaBlendDesc) > BlendDescs;
|
||||
BlendDescs _blend_descs;
|
||||
|
||||
enum JointType {
|
||||
JT_none, // Not a joint.
|
||||
JT_joint, // An actual joint in Maya.
|
||||
JT_pseudo_joint, // Not a joint in Maya, but treated just like a
|
||||
// joint for the purposes of the converter.
|
||||
JT_joint_parent, // A parent or ancestor of a joint or pseudo joint.
|
||||
};
|
||||
JointType _joint_type;
|
||||
|
||||
bool _is_lod;
|
||||
double _switch_in, _switch_out;
|
||||
|
||||
bool _tagged;
|
||||
bool _joint_tagged;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
ReferenceCount::init_type();
|
||||
Namable::init_type();
|
||||
register_type(_type_handle, "MayaNodeDesc",
|
||||
ReferenceCount::get_class_type(),
|
||||
Namable::get_class_type());
|
||||
}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
|
||||
friend class MayaNodeTree;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,634 +0,0 @@
|
|||
/**
|
||||
* PANDA 3D SOFTWARE
|
||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
*
|
||||
* All use of this software is subject to the terms of the revised BSD
|
||||
* license. You should have received a copy of this license along
|
||||
* with this source code in a file named "LICENSE."
|
||||
*
|
||||
* @file mayaNodeTree.cxx
|
||||
* @author drose
|
||||
* @date 2003-06-06
|
||||
*/
|
||||
|
||||
#include "mayaNodeTree.h"
|
||||
#include "mayaBlendDesc.h"
|
||||
#include "mayaEggGroupUserData.h"
|
||||
#include "mayaToEggConverter.h"
|
||||
#include "config_mayaegg.h"
|
||||
#include "maya_funcs.h"
|
||||
#include "eggGroup.h"
|
||||
#include "eggTable.h"
|
||||
#include "eggXfmSAnim.h"
|
||||
#include "eggSAnimData.h"
|
||||
#include "eggData.h"
|
||||
#include "eggSwitchCondition.h"
|
||||
#include "dcast.h"
|
||||
|
||||
#include "pre_maya_include.h"
|
||||
#include <maya/MString.h>
|
||||
#include <maya/MItDag.h>
|
||||
#include <maya/MSelectionList.h>
|
||||
#include <maya/MGlobal.h>
|
||||
#include "post_maya_include.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
using std::string;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
MayaNodeTree::
|
||||
MayaNodeTree(MayaToEggConverter *converter) :
|
||||
_converter(converter)
|
||||
{
|
||||
_root = new MayaNodeDesc(this);
|
||||
_fps = 0.0;
|
||||
_egg_data = nullptr;
|
||||
_egg_root = nullptr;
|
||||
_skeleton_node = nullptr;
|
||||
_morph_node = nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a pointer to the node corresponding to the indicated dag_path
|
||||
* object, creating it first if necessary.
|
||||
*/
|
||||
MayaNodeDesc *MayaNodeTree::
|
||||
build_node(const MDagPath &dag_path) {
|
||||
MayaNodeDesc *node_desc = r_build_node(dag_path.fullPathName().asChar());
|
||||
node_desc->from_dag_path(dag_path, _converter);
|
||||
return node_desc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Walks through the complete Maya hierarchy but does not tag any nodes for
|
||||
* conversion.
|
||||
*/
|
||||
bool MayaNodeTree::
|
||||
build_hierarchy() {
|
||||
MStatus status;
|
||||
|
||||
MItDag dag_iterator(MItDag::kDepthFirst, MFn::kTransform, &status);
|
||||
if (!status) {
|
||||
status.perror("MItDag constructor");
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
// this is how you can reset the traverser to a specific node
|
||||
status = dag_iterator.reset(dag_iterator.item(),MItDag::kDepthFirst, MFn::kTransform);
|
||||
*/
|
||||
// Get the entire Maya scene.
|
||||
|
||||
// This while loop walks through the entire Maya hierarchy, one node at a
|
||||
// time. Maya's MItDag object automatically performs a depth-first
|
||||
// traversal of its scene graph.
|
||||
|
||||
bool all_ok = true;
|
||||
while (!dag_iterator.isDone()) {
|
||||
MDagPath dag_path;
|
||||
status = dag_iterator.getPath(dag_path);
|
||||
if (!status) {
|
||||
status.perror("MItDag::getPath");
|
||||
} else {
|
||||
build_node(dag_path);
|
||||
}
|
||||
|
||||
dag_iterator.next();
|
||||
}
|
||||
|
||||
if (all_ok) {
|
||||
_root->check_pseudo_joints(false);
|
||||
_root->check_lods();
|
||||
}
|
||||
|
||||
return all_ok;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tags the entire hierarchy for conversion. This is the normal behavior.
|
||||
*/
|
||||
void MayaNodeTree::
|
||||
tag_joint_all() {
|
||||
_root->tag_joint_recursively();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tags nodes matching the indicated glob (and all of their children) for
|
||||
* conversion. Returns true on success, false otherwise (e.g. the named node
|
||||
* does not exist).
|
||||
*/
|
||||
bool MayaNodeTree::
|
||||
tag_joint_named(const GlobPattern &glob) {
|
||||
// There might be multiple nodes matching the name; search for all of them.
|
||||
bool found_any = false;
|
||||
|
||||
Nodes::iterator ni;
|
||||
for (ni = _nodes.begin(); ni != _nodes.end(); ++ni) {
|
||||
MayaNodeDesc *node = (*ni);
|
||||
if (glob.matches(node->get_name())) {
|
||||
node->tag_joint_recursively();
|
||||
found_any = true;
|
||||
}
|
||||
}
|
||||
|
||||
return found_any;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tags the entire hierarchy for conversion. This is the normal behavior.
|
||||
*/
|
||||
void MayaNodeTree::
|
||||
tag_all() {
|
||||
_root->tag_recursively();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tags nodes matching the indicated glob (and all of their children) for
|
||||
* conversion. Returns true on success, false otherwise (e.g. the named node
|
||||
* does not exist).
|
||||
*/
|
||||
bool MayaNodeTree::
|
||||
tag_named(const GlobPattern &glob) {
|
||||
// There might be multiple nodes matching the name; search for all of them.
|
||||
bool found_any = false;
|
||||
|
||||
Nodes::iterator ni;
|
||||
for (ni = _nodes.begin(); ni != _nodes.end(); ++ni) {
|
||||
MayaNodeDesc *node = (*ni);
|
||||
if (glob.matches(node->get_name())) {
|
||||
node->tag_recursively();
|
||||
found_any = true;
|
||||
}
|
||||
}
|
||||
|
||||
return found_any;
|
||||
}
|
||||
|
||||
/**
|
||||
* Un-tags nodes matching the indicated glob (and all of their children) for
|
||||
* conversion. Returns true on success, false otherwise (e.g. the named node
|
||||
* does not exist).
|
||||
*/
|
||||
bool MayaNodeTree::
|
||||
untag_named(const GlobPattern &glob) {
|
||||
// There might be multiple nodes matching the name; search for all of them.
|
||||
bool found_any = false;
|
||||
|
||||
Nodes::iterator ni;
|
||||
for (ni = _nodes.begin(); ni != _nodes.end(); ++ni) {
|
||||
MayaNodeDesc *node = (*ni);
|
||||
if (glob.matches(node->get_name())) {
|
||||
node->untag_recursively();
|
||||
found_any = true;
|
||||
}
|
||||
}
|
||||
|
||||
return found_any;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tags the just the selected hierarchy for conversion, or the entire
|
||||
* hierarchy if nothing is selected. Returns true on success, false on
|
||||
* failure.
|
||||
*/
|
||||
bool MayaNodeTree::
|
||||
tag_selected() {
|
||||
MStatus status;
|
||||
|
||||
MItDag dag_iterator(MItDag::kDepthFirst, MFn::kTransform, &status);
|
||||
if (!status) {
|
||||
status.perror("MItDag constructor");
|
||||
return false;
|
||||
}
|
||||
|
||||
MSelectionList selection;
|
||||
status = MGlobal::getActiveSelectionList(selection);
|
||||
if (!status) {
|
||||
status.perror("MGlobal::getActiveSelectionList");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (selection.isEmpty()) {
|
||||
mayaegg_cat.info()
|
||||
<< "Selection list is empty.\n";
|
||||
tag_all();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool all_ok = true;
|
||||
unsigned int length = selection.length();
|
||||
for (unsigned int i = 0; i < length; i++) {
|
||||
MDagPath root_path;
|
||||
status = selection.getDagPath(i, root_path);
|
||||
if (!status) {
|
||||
status.perror("MSelectionList::getDagPath");
|
||||
} else {
|
||||
// Now traverse through the selected dag path and all nested dag paths.
|
||||
dag_iterator.reset(root_path);
|
||||
while (!dag_iterator.isDone()) {
|
||||
MDagPath dag_path;
|
||||
status = dag_iterator.getPath(dag_path);
|
||||
if (!status) {
|
||||
status.perror("MItDag::getPath");
|
||||
} else {
|
||||
build_node(dag_path)->tag();
|
||||
}
|
||||
|
||||
dag_iterator.next();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (all_ok) {
|
||||
_root->check_pseudo_joints(false);
|
||||
}
|
||||
|
||||
return all_ok;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the total number of nodes in the hierarchy, not counting the root
|
||||
* node.
|
||||
*/
|
||||
int MayaNodeTree::
|
||||
get_num_nodes() const {
|
||||
return _nodes.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the nth node in the hierarchy, in an arbitrary ordering.
|
||||
*/
|
||||
MayaNodeDesc *MayaNodeTree::
|
||||
get_node(int n) const {
|
||||
nassertr(n >= 0 && n < (int)_nodes.size(), nullptr);
|
||||
return _nodes[n];
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the entire tree in preparation for repopulating with a new scene.
|
||||
*/
|
||||
void MayaNodeTree::
|
||||
clear() {
|
||||
_root = new MayaNodeDesc(this);
|
||||
_fps = 0.0;
|
||||
_egg_data = nullptr;
|
||||
_egg_root = nullptr;
|
||||
_skeleton_node = nullptr;
|
||||
_morph_node = nullptr;
|
||||
_nodes_by_path.clear();
|
||||
_nodes.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all of the references to generated egg structures from the tree,
|
||||
* and prepares the tree for generating new egg structures.
|
||||
*/
|
||||
void MayaNodeTree::
|
||||
clear_egg(EggData *egg_data, EggGroupNode *egg_root,
|
||||
EggGroupNode *skeleton_node, EggGroupNode *morph_node) {
|
||||
_root->clear_egg();
|
||||
BlendDescs::iterator bi;
|
||||
for (bi = _blend_descs.begin(); bi != _blend_descs.end(); ++bi) {
|
||||
(*bi)->clear_egg();
|
||||
}
|
||||
|
||||
_egg_data = egg_data;
|
||||
_egg_root = egg_root;
|
||||
_skeleton_node = skeleton_node;
|
||||
_morph_node = morph_node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the EggGroupNode corresponding to the group or joint for the
|
||||
* indicated node. Creates the group node if it has not already been created.
|
||||
*/
|
||||
EggGroup *MayaNodeTree::
|
||||
get_egg_group(MayaNodeDesc *node_desc) {
|
||||
nassertr(_egg_root != nullptr, nullptr);
|
||||
|
||||
if (node_desc->_egg_group == nullptr) {
|
||||
// We need to make a new group node.
|
||||
EggGroup *egg_group;
|
||||
|
||||
nassertr(node_desc->_parent != nullptr, nullptr);
|
||||
egg_group = new EggGroup(node_desc->get_name());
|
||||
if (node_desc->is_joint()) {
|
||||
if (_converter->get_animation_convert() == AC_model ||
|
||||
_converter->get_animation_convert() == AC_both) {
|
||||
egg_group->set_group_type(EggGroup::GT_joint);
|
||||
}
|
||||
}
|
||||
|
||||
MayaEggGroupUserData *parent_user_data = nullptr;
|
||||
|
||||
if (node_desc->_parent == _root) {
|
||||
// The parent is the root.
|
||||
_egg_root->add_child(egg_group);
|
||||
|
||||
} else {
|
||||
// The parent is another node.
|
||||
EggGroup *parent_egg_group = get_egg_group(node_desc->_parent);
|
||||
parent_egg_group->add_child(egg_group);
|
||||
|
||||
if (parent_egg_group->has_user_data()) {
|
||||
DCAST_INTO_R(parent_user_data, parent_egg_group->get_user_data(), nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
if (node_desc->has_dag_path()) {
|
||||
// Check for an object type setting, from Oliver's plug-in.
|
||||
MObject dag_object = node_desc->get_dag_path().node();
|
||||
string object_type;
|
||||
LVector3d value;
|
||||
|
||||
for (unsigned int i = 1; ; i++) {
|
||||
std::ostringstream attr;
|
||||
attr << "eggObjectTypes" << i;
|
||||
|
||||
if (!get_enum_attribute(dag_object, attr.str(), object_type)) {
|
||||
if (i < 3) {
|
||||
// Support out-of-order legacy object types.
|
||||
continue;
|
||||
}
|
||||
|
||||
// We have run out of object types to add.
|
||||
break;
|
||||
}
|
||||
|
||||
egg_group->add_object_type(object_type);
|
||||
}
|
||||
|
||||
if(has_attribute(dag_object, "scrollUV")) {
|
||||
if(get_vec3d_attribute(dag_object, "scrollUV", value)) {
|
||||
egg_group->set_scroll_u(value[0]);
|
||||
egg_group->set_scroll_v(value[1]);
|
||||
egg_group->set_scroll_r(value[2]);
|
||||
}
|
||||
}
|
||||
|
||||
pvector<string> tag_attribute_names;
|
||||
get_tag_attribute_names(dag_object, tag_attribute_names);
|
||||
for (unsigned int ti=0; ti < tag_attribute_names.size(); ti++) {
|
||||
if (get_enum_attribute(dag_object, tag_attribute_names[ti], object_type)) {
|
||||
egg_group->set_tag(tag_attribute_names[ti].substr(3), object_type);
|
||||
}
|
||||
}
|
||||
|
||||
// Is the node flagged to be invisible? If it is, it is tagged with the
|
||||
// "hidden" visibility flag, so it won't get converted in the normal
|
||||
// case (unless it represents a collision solid or something).
|
||||
bool visible = true;
|
||||
get_bool_attribute(dag_object, "visibility", visible);
|
||||
if (!visible && egg_group->get_num_object_types() == 0) {
|
||||
egg_group->set_visibility_mode(EggGroup::VM_hidden);
|
||||
}
|
||||
|
||||
// We treat the object type "billboard" as a special case: we apply this
|
||||
// one right away and also flag the group as an instance.
|
||||
if (egg_group->has_object_type("billboard")) {
|
||||
egg_group->remove_object_type("billboard");
|
||||
egg_group->set_group_type(EggGroup::GT_instance);
|
||||
egg_group->set_billboard_type(EggGroup::BT_axis);
|
||||
|
||||
} else if (egg_group->has_object_type("billboard-point")) {
|
||||
egg_group->remove_object_type("billboard-point");
|
||||
egg_group->set_group_type(EggGroup::GT_instance);
|
||||
egg_group->set_billboard_type(EggGroup::BT_point_camera_relative);
|
||||
|
||||
} else if (egg_group->has_object_type("bbpoint")) {
|
||||
egg_group->remove_object_type("bbpoint");
|
||||
egg_group->set_group_type(EggGroup::GT_instance);
|
||||
egg_group->set_billboard_type(EggGroup::BT_point_camera_relative);
|
||||
}
|
||||
|
||||
// We also treat the object type "dcs" and "model" as a special case, so
|
||||
// we can test for these flags later.
|
||||
if (egg_group->has_object_type("dcs")) {
|
||||
egg_group->remove_object_type("dcs");
|
||||
egg_group->set_dcs_type(EggGroup::DC_default);
|
||||
}
|
||||
if (egg_group->has_object_type("model")) {
|
||||
egg_group->remove_object_type("model");
|
||||
egg_group->set_model_flag(true);
|
||||
}
|
||||
|
||||
// And "vertex-color" and "double-sided" have meaning only to this
|
||||
// converter.
|
||||
MayaEggGroupUserData *user_data;
|
||||
if (parent_user_data == nullptr) {
|
||||
user_data = new MayaEggGroupUserData;
|
||||
} else {
|
||||
// Inherit the flags from above.
|
||||
user_data = new MayaEggGroupUserData(*parent_user_data);
|
||||
}
|
||||
|
||||
if (egg_group->has_object_type("vertex-color")) {
|
||||
egg_group->remove_object_type("vertex-color");
|
||||
user_data->_vertex_color = true;
|
||||
}
|
||||
if (egg_group->has_object_type("double-sided")) {
|
||||
egg_group->remove_object_type("double-sided");
|
||||
user_data->_double_sided = true;
|
||||
}
|
||||
egg_group->set_user_data(user_data);
|
||||
}
|
||||
|
||||
if (node_desc->_is_lod) {
|
||||
// Create an LOD specification.
|
||||
egg_group->set_lod(EggSwitchConditionDistance(node_desc->_switch_in,
|
||||
node_desc->_switch_out,
|
||||
LPoint3d::zero()));
|
||||
}
|
||||
|
||||
node_desc->_egg_group = egg_group;
|
||||
}
|
||||
|
||||
return node_desc->_egg_group;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the EggTable corresponding to the joint for the indicated node.
|
||||
* Creates the table node if it has not already been created.
|
||||
*/
|
||||
EggTable *MayaNodeTree::
|
||||
get_egg_table(MayaNodeDesc *node_desc) {
|
||||
nassertr(_skeleton_node != nullptr, nullptr);
|
||||
nassertr(node_desc->is_joint(), nullptr);
|
||||
|
||||
if (node_desc->_egg_table == nullptr) {
|
||||
// We need to make a new table node.
|
||||
nassertr(node_desc->_parent != nullptr, nullptr);
|
||||
|
||||
EggTable *egg_table = new EggTable(node_desc->get_name());
|
||||
node_desc->_anim = new EggXfmSAnim("xform", _egg_data->get_coordinate_system());
|
||||
node_desc->_anim->set_fps(_fps);
|
||||
egg_table->add_child(node_desc->_anim);
|
||||
|
||||
if (!node_desc->_parent->is_joint()) {
|
||||
// The parent is not a joint; put it at the top.
|
||||
_skeleton_node->add_child(egg_table);
|
||||
|
||||
} else {
|
||||
// The parent is another joint.
|
||||
EggTable *parent_egg_table = get_egg_table(node_desc->_parent);
|
||||
parent_egg_table->add_child(egg_table);
|
||||
}
|
||||
|
||||
node_desc->_egg_table = egg_table;
|
||||
}
|
||||
|
||||
return node_desc->_egg_table;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the anim table corresponding to the joint for the indicated node.
|
||||
* Creates the table node if it has not already been created.
|
||||
*/
|
||||
EggXfmSAnim *MayaNodeTree::
|
||||
get_egg_anim(MayaNodeDesc *node_desc) {
|
||||
get_egg_table(node_desc);
|
||||
return node_desc->_anim;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the anim table corresponding to the slider for the indicated blend.
|
||||
* Creates the table node if it has not already been created.
|
||||
*/
|
||||
EggSAnimData *MayaNodeTree::
|
||||
get_egg_slider(MayaBlendDesc *blend_desc) {
|
||||
nassertr(_morph_node != nullptr, nullptr);
|
||||
|
||||
if (blend_desc->_anim == nullptr) {
|
||||
// We need to make a new anim table.
|
||||
EggSAnimData *egg_anim = new EggSAnimData(blend_desc->get_name());
|
||||
egg_anim->set_fps(_fps);
|
||||
_morph_node->add_child(egg_anim);
|
||||
|
||||
blend_desc->_anim = egg_anim;
|
||||
}
|
||||
|
||||
return blend_desc->_anim;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the indicated name is on the list of sliders to ignore,
|
||||
* false otherwise.
|
||||
*/
|
||||
bool MayaNodeTree::
|
||||
ignore_slider(const string &name) const {
|
||||
return _converter->ignore_slider(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs a message to the user reporting that a slider was ignored. Each
|
||||
* slider is only reported once.
|
||||
*/
|
||||
void MayaNodeTree::
|
||||
report_ignored_slider(const string &name) {
|
||||
if (_ignored_slider_names.insert(name).second) {
|
||||
mayaegg_cat.info()
|
||||
<< "Ignoring slider " << name << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the indicated MayaBlendDesc object to the list of blends collected so
|
||||
* far. If a MayaBlendDesc object with the same name is already part of the
|
||||
* tree, the supplied object is discarded and the previously-added object is
|
||||
* returned; otherwise, the supplied object is added to the tree and the same
|
||||
* object is returned.
|
||||
*
|
||||
* In either case, the return value is the MayaBlendDesc that should be used
|
||||
* henceforth.
|
||||
*/
|
||||
MayaBlendDesc *MayaNodeTree::
|
||||
add_blend_desc(MayaBlendDesc *blend_desc) {
|
||||
BlendDescs::iterator bi = _blend_descs.insert(blend_desc).first;
|
||||
|
||||
return (*bi);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of unique MayaBlendDesc objects (and hence the number of
|
||||
* morph sliders) discovered in the tree.
|
||||
*/
|
||||
int MayaNodeTree::
|
||||
get_num_blend_descs() const {
|
||||
return _blend_descs.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the nth MayaBlendDesc object discovered in the tree.
|
||||
*/
|
||||
MayaBlendDesc *MayaNodeTree::
|
||||
get_blend_desc(int n) const {
|
||||
nassertr(n >= 0 && n < (int)_blend_descs.size(), nullptr);
|
||||
return _blend_descs[n];
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets all of the sliders associated with all blend shapes down to 0.
|
||||
*/
|
||||
void MayaNodeTree::
|
||||
reset_sliders() {
|
||||
BlendDescs::iterator bi;
|
||||
for (bi = _blend_descs.begin(); bi != _blend_descs.end(); ++bi) {
|
||||
(*bi)->set_slider(0.0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The recursive implementation of build_node().
|
||||
*/
|
||||
MayaNodeDesc *MayaNodeTree::
|
||||
r_build_node(const string &path) {
|
||||
// If we have already encountered this pathname, return the corresponding
|
||||
// MayaNodeDesc immediately.
|
||||
NodesByPath::const_iterator ni = _nodes_by_path.find(path);
|
||||
if (ni != _nodes_by_path.end()) {
|
||||
return (*ni).second;
|
||||
}
|
||||
|
||||
// Otherwise, we have to create it. Do this recursively, so we create each
|
||||
// node along the path.
|
||||
MayaNodeDesc *node_desc = nullptr;
|
||||
|
||||
// mayaegg_cat.info() << "path: " << path << endl;
|
||||
if (path.empty()) {
|
||||
// This is the top. mayaegg_cat.info() << "found empty path: " << path <<
|
||||
// endl;
|
||||
node_desc = _root;
|
||||
|
||||
} else {
|
||||
// Maya uses vertical bars to separate path components. Remove everything
|
||||
// from the rightmost bar on; this will give us the parent's path name.
|
||||
size_t bar = path.rfind("|");
|
||||
string parent_path, local_name;
|
||||
if (bar != string::npos) {
|
||||
parent_path = path.substr(0, bar);
|
||||
// mayaegg_cat.info() << "parent_path: " << parent_path << endl;
|
||||
local_name = path.substr(bar + 1);
|
||||
if (local_name == _subroot_parent_name) {
|
||||
node_desc = _root;
|
||||
}
|
||||
} else {
|
||||
local_name = path;
|
||||
}
|
||||
// mayaegg_cat.info() << "local_name: " << local_name << endl;
|
||||
|
||||
if (node_desc != _root) {
|
||||
MayaNodeDesc *parent_node_desc = r_build_node(parent_path);
|
||||
if (parent_node_desc == nullptr)
|
||||
mayaegg_cat.info() << "empty parent: " << local_name << std::endl;
|
||||
node_desc = new MayaNodeDesc(this, parent_node_desc, local_name);
|
||||
_nodes.push_back(node_desc);
|
||||
}
|
||||
}
|
||||
|
||||
_nodes_by_path.insert(NodesByPath::value_type(path, node_desc));
|
||||
return node_desc;
|
||||
}
|
||||
|
|
@ -1,100 +0,0 @@
|
|||
/**
|
||||
* PANDA 3D SOFTWARE
|
||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
*
|
||||
* All use of this software is subject to the terms of the revised BSD
|
||||
* license. You should have received a copy of this license along
|
||||
* with this source code in a file named "LICENSE."
|
||||
*
|
||||
* @file mayaNodeTree.h
|
||||
* @author drose
|
||||
* @date 2003-06-06
|
||||
*/
|
||||
|
||||
#ifndef MAYANODETREE_H
|
||||
#define MAYANODETREE_H
|
||||
|
||||
#include "pandatoolbase.h"
|
||||
|
||||
#include "mayaNodeDesc.h"
|
||||
#include "mayaBlendDesc.h"
|
||||
#include "globPattern.h"
|
||||
#include "indirectCompareNames.h"
|
||||
#include "ordered_vector.h"
|
||||
#include "pset.h"
|
||||
#include "pmap.h"
|
||||
|
||||
class MayaToEggConverter;
|
||||
class EggData;
|
||||
class EggGroupNode;
|
||||
class EggTable;
|
||||
class EggXfmSAnim;
|
||||
class EggSAnimData;
|
||||
|
||||
/**
|
||||
* Describes a complete tree of maya nodes for conversion.
|
||||
*/
|
||||
class MayaNodeTree {
|
||||
public:
|
||||
MayaNodeTree(MayaToEggConverter *converter);
|
||||
MayaNodeDesc *build_node(const MDagPath &dag_path);
|
||||
bool build_hierarchy();
|
||||
|
||||
void tag_joint_all();
|
||||
// bool tag_joint_selected();
|
||||
bool tag_joint_named(const GlobPattern &glob);
|
||||
|
||||
void tag_all();
|
||||
bool tag_selected();
|
||||
bool tag_named(const GlobPattern &glob);
|
||||
bool untag_named(const GlobPattern &glob);
|
||||
|
||||
int get_num_nodes() const;
|
||||
MayaNodeDesc *get_node(int n) const;
|
||||
|
||||
void clear();
|
||||
void clear_egg(EggData *egg_data, EggGroupNode *egg_root,
|
||||
EggGroupNode *skeleton_node, EggGroupNode *morph_node);
|
||||
EggGroup *get_egg_group(MayaNodeDesc *node_desc);
|
||||
EggTable *get_egg_table(MayaNodeDesc *node_desc);
|
||||
EggXfmSAnim *get_egg_anim(MayaNodeDesc *node_desc);
|
||||
EggSAnimData *get_egg_slider(MayaBlendDesc *blend_desc);
|
||||
|
||||
bool ignore_slider(const std::string &name) const;
|
||||
void report_ignored_slider(const std::string &name);
|
||||
|
||||
MayaBlendDesc *add_blend_desc(MayaBlendDesc *blend_desc);
|
||||
int get_num_blend_descs() const;
|
||||
MayaBlendDesc *get_blend_desc(int n) const;
|
||||
|
||||
void reset_sliders();
|
||||
|
||||
public:
|
||||
std::string _subroot_parent_name;
|
||||
PT(MayaNodeDesc) _root;
|
||||
PN_stdfloat _fps;
|
||||
|
||||
private:
|
||||
MayaNodeDesc *r_build_node(const std::string &path);
|
||||
|
||||
MayaToEggConverter *_converter;
|
||||
|
||||
EggData *_egg_data;
|
||||
EggGroupNode *_egg_root;
|
||||
EggGroupNode *_skeleton_node;
|
||||
EggGroupNode *_morph_node;
|
||||
|
||||
typedef pmap<std::string, MayaNodeDesc *> NodesByPath;
|
||||
NodesByPath _nodes_by_path;
|
||||
|
||||
typedef pvector<MayaNodeDesc *> Nodes;
|
||||
Nodes _nodes;
|
||||
|
||||
typedef ov_set<PT(MayaBlendDesc), IndirectCompareNames<MayaBlendDesc> > BlendDescs;
|
||||
BlendDescs _blend_descs;
|
||||
|
||||
typedef pset<std::string> Strings;
|
||||
Strings _ignored_slider_names;
|
||||
};
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,203 +0,0 @@
|
|||
/**
|
||||
* PANDA 3D SOFTWARE
|
||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
*
|
||||
* All use of this software is subject to the terms of the revised BSD
|
||||
* license. You should have received a copy of this license along
|
||||
* with this source code in a file named "LICENSE."
|
||||
*
|
||||
* @file mayaToEggConverter.h
|
||||
* @author drose
|
||||
* @date 1999-11-10
|
||||
*/
|
||||
|
||||
#ifndef MAYATOEGGCONVERTER_H
|
||||
#define MAYATOEGGCONVERTER_H
|
||||
|
||||
#include "pandatoolbase.h"
|
||||
#include "somethingToEggConverter.h"
|
||||
#include "mayaNodeTree.h"
|
||||
|
||||
#include "mayaApi.h"
|
||||
#include "mayaShaders.h"
|
||||
#include "mayaShaderColorDef.h"
|
||||
#include "eggTextureCollection.h"
|
||||
#include "distanceUnit.h"
|
||||
#include "coordinateSystem.h"
|
||||
#include "globPattern.h"
|
||||
#include "pvector.h"
|
||||
#include "vector_string.h"
|
||||
|
||||
#include "pre_maya_include.h"
|
||||
#include <maya/MDagPath.h>
|
||||
#include <maya/MItMeshPolygon.h>
|
||||
#include "post_maya_include.h"
|
||||
|
||||
class EggData;
|
||||
class EggGroup;
|
||||
class EggTable;
|
||||
class EggVertexPool;
|
||||
class EggNurbsCurve;
|
||||
class EggPrimitive;
|
||||
class EggXfmSAnim;
|
||||
class MayaShaderColorDef;
|
||||
|
||||
/**
|
||||
* This class supervises the construction of an EggData structure from a
|
||||
* single Maya file, or from the data already in the global Maya model space.
|
||||
*
|
||||
* Note that since the Maya API presents just one global model space, it is
|
||||
* not possible to simultaneously load two distinct Maya files.
|
||||
*/
|
||||
class MayaToEggConverter : public SomethingToEggConverter {
|
||||
public:
|
||||
MayaToEggConverter(const std::string &program_name = "");
|
||||
MayaToEggConverter(const MayaToEggConverter ©);
|
||||
virtual ~MayaToEggConverter();
|
||||
|
||||
virtual SomethingToEggConverter *make_copy();
|
||||
|
||||
virtual std::string get_name() const;
|
||||
virtual std::string get_extension() const;
|
||||
virtual std::string get_additional_extensions() const;
|
||||
|
||||
virtual bool convert_file(const Filename &filename);
|
||||
virtual DistanceUnit get_input_units();
|
||||
|
||||
void clear_subroots();
|
||||
void add_subroot(const GlobPattern &glob);
|
||||
|
||||
void clear_subsets();
|
||||
void add_subset(const GlobPattern &glob);
|
||||
|
||||
void clear_excludes();
|
||||
void add_exclude(const GlobPattern &glob);
|
||||
|
||||
void clear_ignore_sliders();
|
||||
void add_ignore_slider(const GlobPattern &glob);
|
||||
bool ignore_slider(const std::string &name) const;
|
||||
|
||||
void clear_force_joints();
|
||||
void add_force_joint(const GlobPattern &glob);
|
||||
bool force_joint(const std::string &name) const;
|
||||
|
||||
void set_from_selection(bool from_selection);
|
||||
|
||||
bool convert_maya();
|
||||
|
||||
void clear();
|
||||
|
||||
bool open_api(bool revert_directory=true);
|
||||
void close_api();
|
||||
|
||||
private:
|
||||
bool convert_flip(double start_frame, double end_frame,
|
||||
double frame_inc, double output_frame_rate);
|
||||
|
||||
bool convert_char_model();
|
||||
bool convert_char_chan(double start_frame, double end_frame,
|
||||
double frame_inc, double output_frame_rate);
|
||||
bool convert_hierarchy(EggGroupNode *egg_root);
|
||||
bool process_model_node(MayaNodeDesc *node_desc);
|
||||
|
||||
void get_transform(MayaNodeDesc *node_desc, const MDagPath &dag_path,
|
||||
EggGroup *egg_group);
|
||||
void get_joint_transform(const MDagPath &dag_path, EggGroup *egg_group);
|
||||
void apply_lod_attributes(EggGroup *egg_group, MFnDagNode &lod_group);
|
||||
|
||||
// I ran into core dumps trying to pass around a MFnMesh object by value.
|
||||
// From now on, all MFn* objects will be passed around by reference. void
|
||||
// make_tex_names(const MFnMesh &mesh, const MObject &mesh_object);
|
||||
|
||||
void make_nurbs_surface(MayaNodeDesc *node_desc,
|
||||
const MDagPath &dag_path,
|
||||
MFnNurbsSurface &surface,
|
||||
EggGroup *group);
|
||||
EggNurbsCurve *make_trim_curve(const MFnNurbsCurve &curve,
|
||||
const std::string &nurbs_name,
|
||||
EggGroupNode *egg_group,
|
||||
int trim_curve_index);
|
||||
void make_nurbs_curve(const MDagPath &dag_path,
|
||||
const MFnNurbsCurve &curve,
|
||||
EggGroup *group);
|
||||
void make_polyset(MayaNodeDesc *node_desc, const MDagPath &dag_path,
|
||||
const MFnMesh &mesh, EggGroup *egg_group,
|
||||
MayaShader *default_shader = nullptr);
|
||||
void make_locator(const MDagPath &dag_path, const MFnDagNode &dag_node,
|
||||
EggGroup *egg_group);
|
||||
void make_camera_locator(const MDagPath &dag_path, const MFnDagNode &dag_node,
|
||||
EggGroup *egg_group);
|
||||
void make_light_locator(const MDagPath &dag_path, const MFnDagNode &dag_node,
|
||||
EggGroup *egg_group);
|
||||
bool get_vertex_weights(const MDagPath &dag_path, const MFnMesh &mesh,
|
||||
pvector<EggGroup *> &joints, MFloatArray &weights);
|
||||
bool get_vertex_weights(const MDagPath &dag_path, const MFnNurbsSurface &surface,
|
||||
pvector<EggGroup *> &joints, MFloatArray &weights);
|
||||
void apply_texture_uvprops(EggTexture &tex,
|
||||
const MayaShaderColorDef &color_def);
|
||||
void apply_texture_blendtype(EggTexture &tex,
|
||||
const MayaShaderColorDef &color_def);
|
||||
void apply_texture_filename(EggTexture &tex,
|
||||
const MayaShaderColorDef &color_def);
|
||||
void apply_texture_alpha_filename(EggTexture &tex,
|
||||
const MayaShaderColorDef &color_def);
|
||||
bool compare_texture_uvprops(EggTexture &tex,
|
||||
const MayaShaderColorDef &color_def);
|
||||
bool reparent_decals(EggGroupNode *egg_parent);
|
||||
void set_shader_attributes(EggPrimitive &primitive, const MayaShader &shader,
|
||||
bool mesh = false);
|
||||
void set_shader_modern(EggPrimitive &primitive, const MayaShader &shader,
|
||||
bool mesh);
|
||||
void set_shader_legacy(EggPrimitive &primitive, const MayaShader &shader,
|
||||
bool mesh);
|
||||
void set_vertex_color(EggVertex &vert, MItMeshPolygon &pi, int vert_index, const MayaShader *shader, const LColor &color);
|
||||
|
||||
void set_vertex_color_legacy(EggVertex &vert, MItMeshPolygon &pi, int vert_index, const MayaShader *shader, const LColor &color);
|
||||
|
||||
void set_vertex_color_modern(EggVertex &vert, MItMeshPolygon &pi, int vert_index, const MayaShader *shader, const LColor &color);
|
||||
|
||||
int round(double value);
|
||||
|
||||
std::string _program_name;
|
||||
|
||||
bool _from_selection;
|
||||
std::string _subroot;
|
||||
typedef pvector<GlobPattern> Globs;
|
||||
Globs _subsets;
|
||||
Globs _subroots;
|
||||
Globs _excludes;
|
||||
Globs _ignore_sliders;
|
||||
Globs _force_joints;
|
||||
|
||||
MayaNodeTree _tree;
|
||||
|
||||
public:
|
||||
MayaShaders _shaders;
|
||||
EggTextureCollection _textures;
|
||||
PT(MayaApi) _maya;
|
||||
|
||||
bool _polygon_output;
|
||||
double _polygon_tolerance;
|
||||
bool _respect_maya_double_sided;
|
||||
bool _always_show_vertex_color;
|
||||
bool _keep_all_uvsets;
|
||||
bool _convert_cameras;
|
||||
bool _convert_lights;
|
||||
bool _round_uvs;
|
||||
bool _legacy_shader;
|
||||
|
||||
|
||||
enum TransformType {
|
||||
TT_invalid,
|
||||
TT_all,
|
||||
TT_model,
|
||||
TT_dcs,
|
||||
TT_none,
|
||||
};
|
||||
TransformType _transform_type;
|
||||
|
||||
static TransformType string_transform_type(const std::string &arg);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
#include "config_mayaegg.cxx"
|
||||
#include "mayaEggGroupUserData.cxx"
|
||||
#include "mayaBlendDesc.cxx"
|
||||
#include "mayaNodeDesc.cxx"
|
||||
#include "mayaNodeTree.cxx"
|
||||
#include "mayaToEggConverter.cxx"
|
||||
|
|
@ -1,240 +0,0 @@
|
|||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <stdlib.h>
|
||||
#include <string>
|
||||
|
||||
#ifndef _BOOL
|
||||
#define _BOOL 1
|
||||
#endif
|
||||
|
||||
#define REQUIRE_IOSTREAM
|
||||
|
||||
#include <maya/MGlobal.h>
|
||||
#include <maya/MFileIO.h>
|
||||
#include <maya/MLibrary.h>
|
||||
#include <maya/MStatus.h>
|
||||
#include <maya/MItDag.h>
|
||||
#include <maya/MDagPath.h>
|
||||
#include <maya/MFnDagNode.h>
|
||||
#include <maya/MFnBlendShapeDeformer.h>
|
||||
#include <maya/MFnMesh.h>
|
||||
#include <maya/MPointArray.h>
|
||||
|
||||
using std::cerr;
|
||||
|
||||
void
|
||||
scan_nodes() {
|
||||
MStatus status;
|
||||
|
||||
MItDag dag_iterator(MItDag::kDepthFirst, MFn::kTransform, &status);
|
||||
if (!status) {
|
||||
status.perror("MItDag constructor");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
while (!dag_iterator.isDone()) {
|
||||
MDagPath dag_path;
|
||||
status = dag_iterator.getPath(dag_path);
|
||||
if (!status) {
|
||||
status.perror("MItDag::getPath");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
MFnDagNode dag_node(dag_path, &status);
|
||||
if (!status) {
|
||||
status.perror("MFnDagNode constructor");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
cerr << dag_node.name() << "\n";
|
||||
|
||||
dag_iterator.next();
|
||||
}
|
||||
}
|
||||
|
||||
MFnBlendShapeDeformer *
|
||||
get_slider(MString slider_name) {
|
||||
MStatus status;
|
||||
|
||||
status = MGlobal::selectByName(slider_name, MGlobal::kReplaceList);
|
||||
if (!status) {
|
||||
status.perror(slider_name);
|
||||
exit(1);
|
||||
}
|
||||
MSelectionList list;
|
||||
status = MGlobal::getActiveSelectionList(list);
|
||||
if (!status) {
|
||||
status.perror("MGLobal::getActiveSelectionList");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
unsigned int num_objects = list.length();
|
||||
if (num_objects != 1) {
|
||||
cerr << "Warning: multiple objects match " << slider_name << "\n";
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < num_objects; i++) {
|
||||
MObject obj;
|
||||
status = list.getDependNode(i, obj);
|
||||
if (!status) {
|
||||
cerr << "selected element is not a dependency node.\n";
|
||||
status.perror("getDependNode");
|
||||
} else {
|
||||
if (obj.hasFn(MFn::kBlendShape)) {
|
||||
MFnBlendShapeDeformer *slider = new MFnBlendShapeDeformer(obj, &status);
|
||||
if (!status) {
|
||||
status.perror("MFnBlendShapeDeformer constructor");
|
||||
} else {
|
||||
cerr << "got slider " << slider->name() << "\n";
|
||||
return slider;
|
||||
}
|
||||
}
|
||||
|
||||
cerr << "selected element is not a blend shape\n";
|
||||
}
|
||||
}
|
||||
|
||||
cerr << "Couldn't find slider " << slider_name << "\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
MFnMesh *
|
||||
get_mesh(MString mesh_name) {
|
||||
MStatus status;
|
||||
|
||||
status = MGlobal::selectByName(mesh_name, MGlobal::kReplaceList);
|
||||
if (!status) {
|
||||
status.perror(mesh_name);
|
||||
exit(1);
|
||||
}
|
||||
MSelectionList list;
|
||||
status = MGlobal::getActiveSelectionList(list);
|
||||
if (!status) {
|
||||
status.perror("MGLobal::getActiveSelectionList");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
unsigned int num_objects = list.length();
|
||||
if (num_objects != 1) {
|
||||
cerr << "Warning: multiple objects match " << mesh_name << "\n";
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < num_objects; i++) {
|
||||
MObject obj;
|
||||
status = list.getDependNode(i, obj);
|
||||
if (!status) {
|
||||
cerr << "selected element is not a dependency node.\n";
|
||||
status.perror("getDependNode");
|
||||
|
||||
} else {
|
||||
if (obj.hasFn(MFn::kMesh)) {
|
||||
// Maybe it's a mesh object itself.
|
||||
MFnMesh *mesh = new MFnMesh(obj, &status);
|
||||
if (!status) {
|
||||
status.perror("MFnMesh constructor");
|
||||
} else {
|
||||
cerr << "got mesh " << mesh->name() << "\n";
|
||||
return mesh;
|
||||
}
|
||||
|
||||
} else if (obj.hasFn(MFn::kDagNode)) {
|
||||
// Maybe it's a dag node.
|
||||
MDagPath path;
|
||||
status = MDagPath::getAPathTo(obj, path);
|
||||
if (!status) {
|
||||
status.perror("MDagPath::getAPathTo");
|
||||
exit(1);
|
||||
}
|
||||
if (path.hasFn(MFn::kMesh)) {
|
||||
MFnMesh *mesh = new MFnMesh(path, &status);
|
||||
if (!status) {
|
||||
status.perror("MFnMesh constructor");
|
||||
} else {
|
||||
cerr << "got mesh " << mesh->name() << "\n";
|
||||
return mesh;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cerr << "selected element is not a mesh\n";
|
||||
}
|
||||
}
|
||||
|
||||
cerr << "Couldn't find mesh " << mesh_name << "\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void
|
||||
output_vertices(const char *filename, MFnMesh &mesh) {
|
||||
MStatus status;
|
||||
|
||||
MPointArray verts;
|
||||
// status = mesh.getPoints(verts, MSpace::kObject);
|
||||
status = mesh.getPoints(verts, MSpace::kWorld);
|
||||
if (!status) {
|
||||
status.perror("mesh.getPoints");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
std::ofstream file(filename, std::ios::out | std::ios::trunc);
|
||||
if (!file) {
|
||||
cerr << "Couldn't open " << filename << " for output.\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
unsigned int num_verts = verts.length();
|
||||
cerr << "writing " << num_verts << " vertices to " << filename << "\n";
|
||||
for (unsigned int i = 0; i < num_verts; i++) {
|
||||
file << i << ". " << verts[i] << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[]) {
|
||||
cerr << "Initializing Maya\n";
|
||||
MStatus status;
|
||||
status = MLibrary::initialize(argv[0]);
|
||||
if (!status) {
|
||||
status.perror("Could not initialize");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
cerr << "Using Maya library version " << MGlobal::mayaVersion() << "\n";
|
||||
|
||||
if (argc < 4) {
|
||||
cerr << "\nUsage:\n\nblend_test.cxx file.mb slider_name mesh_name\n\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
MString filename = argv[1];
|
||||
MString slider_name = argv[2];
|
||||
MString mesh_name = argv[3];
|
||||
|
||||
MFileIO::newFile(true);
|
||||
|
||||
cerr << "Reading " << filename << "\n";
|
||||
status = MFileIO::open(filename);
|
||||
if (!status) {
|
||||
status.perror(filename);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
MFnBlendShapeDeformer *slider = get_slider(slider_name);
|
||||
MFnMesh *mesh = get_mesh(mesh_name);
|
||||
|
||||
cerr << "\nOriginal slider value is " << slider->weight(0) << "\n";
|
||||
|
||||
output_vertices("before.txt", *mesh);
|
||||
|
||||
cerr << "Setting slider to 1\n";
|
||||
status = slider->setWeight(0, 1.0);
|
||||
if (!status) {
|
||||
status.perror("MFnBlendShapeDeformer::setWeight");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
output_vertices("after.txt", *mesh);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -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));
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -1,169 +0,0 @@
|
|||
/**
|
||||
* PANDA 3D SOFTWARE
|
||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
*
|
||||
* All use of this software is subject to the terms of the revised BSD
|
||||
* license. You should have received a copy of this license along
|
||||
* with this source code in a file named "LICENSE."
|
||||
*
|
||||
* @file eggToMaya.cxx
|
||||
* @author drose
|
||||
* @date 2005-08-11
|
||||
*/
|
||||
|
||||
#include "eggToMaya.h"
|
||||
#include "mayaEggLoader.h"
|
||||
#include "mayaApi.h"
|
||||
#include "mayaConversionServer.h"
|
||||
|
||||
// We must define this to prevent Maya from doubly-declaring its MApiVersion
|
||||
// string in this file as well as in libmayaegg.
|
||||
#define _MApiVersion
|
||||
|
||||
#include "pre_maya_include.h"
|
||||
#include <maya/MString.h>
|
||||
#include <maya/MFileIO.h>
|
||||
#include "post_maya_include.h"
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
EggToMaya::
|
||||
EggToMaya() :
|
||||
EggToSomething("Maya", ".mb", true, false)
|
||||
{
|
||||
add_units_options();
|
||||
|
||||
set_binary_output(true);
|
||||
set_program_brief("convert .egg files to Maya .mb or .ma files");
|
||||
set_program_description
|
||||
("egg2maya converts files from egg format to Maya .mb or .ma "
|
||||
"format. It contains support for basic geometry (polygons with textures)."
|
||||
"It also supports animation for joints.");
|
||||
|
||||
add_option
|
||||
("a", "", 0,
|
||||
"Convert animation tables.",
|
||||
&EggToMaya::dispatch_none, &_convert_anim);
|
||||
|
||||
add_option
|
||||
("m", "", 0,
|
||||
"Convert polygon models. You may specify both -a and -m at the same "
|
||||
"time. If you specify neither, the default is -m.",
|
||||
&EggToMaya::dispatch_none, &_convert_model);
|
||||
|
||||
add_option
|
||||
("nv", "", 0,
|
||||
"respect vertex and polygon normals.",
|
||||
&EggToMaya::dispatch_none, &_respect_normals);
|
||||
|
||||
add_option("server", "", 0,
|
||||
"Runs the Maya model conversion server. This server can be used in tandem "
|
||||
"with the egg2maya_client and maya2egg_client utilities to batch convert "
|
||||
"both Maya and Panda3D model files.",
|
||||
&EggToMaya::dispatch_none, &_run_server);
|
||||
|
||||
// Maya files always store centimeters.
|
||||
_output_units = DU_centimeters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to create the global Maya API.
|
||||
* Exits the program if unsuccessful.
|
||||
*/
|
||||
PT(MayaApi) EggToMaya::
|
||||
open_api() {
|
||||
if (!MayaApi::is_api_valid()) {
|
||||
nout << "Initializing Maya...\n";
|
||||
}
|
||||
|
||||
PT(MayaApi) api = MayaApi::open_api(_program_name, true, true);
|
||||
|
||||
if (!api || !api->is_valid()) {
|
||||
nout << "Unable to initialize Maya.\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return api;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the model has been successfully converted.
|
||||
*/
|
||||
bool EggToMaya::
|
||||
run() {
|
||||
if (!_convert_anim && !_convert_model) {
|
||||
_convert_model = true;
|
||||
}
|
||||
|
||||
// Let's convert the output file to a full path before we initialize Maya,
|
||||
// since Maya now has a nasty habit of changing the current directory.
|
||||
_output_filename.make_absolute();
|
||||
|
||||
PT(MayaApi) maya = open_api();
|
||||
|
||||
MStatus status;
|
||||
status = MFileIO::newFile(true);
|
||||
if (!status) {
|
||||
status.perror("Could not initialize file");
|
||||
return false;
|
||||
}
|
||||
|
||||
// [gjeon] since maya's internal unit is fixed to cm and when we can't
|
||||
// change UI unit without affecting data all distance data is converted to
|
||||
// cm we need to convert them back to proper output unit user provided here
|
||||
// along with UI unit
|
||||
maya->set_units(_output_units);
|
||||
|
||||
if (_output_units != DU_centimeters && _output_units != DU_invalid) {
|
||||
nout << "Converting from centimeters"
|
||||
<< " to " << format_long_unit(_output_units) << "\n";
|
||||
}
|
||||
|
||||
// Now convert the data.
|
||||
if (!MayaLoadEggData(_data, true, _convert_model, _convert_anim, _respect_normals)) {
|
||||
nout << "Unable to convert egg file.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!maya->write(_output_filename)) {
|
||||
status.perror("Could not save file");
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
// And write out the resulting Maya file.
|
||||
string os_specific = _output_filename.to_os_generic();
|
||||
const char *file_type = NULL;
|
||||
if (_output_filename.get_extension() == "mb") {
|
||||
file_type = "mayaBinary";
|
||||
}
|
||||
status = MFileIO::saveAs(os_specific.c_str(), file_type);
|
||||
if (!status) {
|
||||
status.perror("Could not save file");
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes the arguments parsed by the program.
|
||||
*
|
||||
* If the server flag is specified, the Maya conversion server is started
|
||||
* up rather than the usual conversion utility functionality.
|
||||
*/
|
||||
bool EggToMaya::
|
||||
handle_args(ProgramBase::Args &args) {
|
||||
if (_run_server) {
|
||||
open_api();
|
||||
|
||||
MayaConversionServer server;
|
||||
server.listen();
|
||||
exit(0);
|
||||
return true;
|
||||
}
|
||||
|
||||
return EggToSomething::handle_args(args);
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -1,220 +0,0 @@
|
|||
/**
|
||||
* PANDA 3D SOFTWARE
|
||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
*
|
||||
* All use of this software is subject to the terms of the revised BSD
|
||||
* license. You should have received a copy of this license along
|
||||
* with this source code in a file named "LICENSE."
|
||||
*
|
||||
* @file mayaConversionServer.cxx
|
||||
* @author cbrunner
|
||||
* @author Derzsi Dániel
|
||||
* @date 2020-10-01
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <direct.h> // for chdir
|
||||
#endif
|
||||
|
||||
#include "mayaConversionServer.h"
|
||||
#include "mayaToEgg.h"
|
||||
#include "eggToMaya.h"
|
||||
#include "virtualFileSystem.h"
|
||||
#include "filename.h"
|
||||
|
||||
/**
|
||||
* Initializes the Maya conversion server.
|
||||
*/
|
||||
MayaConversionServer::
|
||||
MayaConversionServer() : _listener(&_manager, 0), _reader(&_manager, 0),
|
||||
_writer(&_manager, 0) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for any network activity and handles it, if appropriate, and then
|
||||
* returns. This must be called periodically
|
||||
*/
|
||||
void MayaConversionServer::
|
||||
poll() {
|
||||
// Listen for new connections
|
||||
_listener.poll();
|
||||
|
||||
// If we have a new connection from a client create a new connection pointer
|
||||
// and add it to the reader list
|
||||
if (_listener.new_connection_available()) {
|
||||
PT(Connection) rendezvous;
|
||||
PT(Connection) connection;
|
||||
NetAddress address;
|
||||
|
||||
if (_listener.get_new_connection(rendezvous, address, connection)) {
|
||||
_reader.add_connection(connection);
|
||||
_clients.insert(connection);
|
||||
}
|
||||
}
|
||||
|
||||
// Check for reset clients
|
||||
if (_manager.reset_connection_available()) {
|
||||
PT(Connection) connection;
|
||||
|
||||
if (_manager.get_reset_connection(connection)) {
|
||||
_clients.erase(connection);
|
||||
_manager.close_connection(connection);
|
||||
}
|
||||
}
|
||||
|
||||
// Poll the readers (created above) and if they have data process it
|
||||
_reader.poll();
|
||||
|
||||
if (_reader.data_available()) {
|
||||
// Grab the incoming data and unpack it
|
||||
NetDatagram datagram;
|
||||
|
||||
if (_reader.get_data(datagram)) {
|
||||
DatagramIterator data(datagram);
|
||||
|
||||
// First data should be the "argc" (argument count) from the client
|
||||
int argc = data.get_uint8();
|
||||
|
||||
// Now we have to get clever because the rest of the data comes as
|
||||
// strings and parse_command_line() expects arguments of the standard
|
||||
// argc, argv*[] variety. First, we need a string vector to hold all
|
||||
// the strings from the datagram. We also need a char * array to keep
|
||||
// track of all the pointers we're gonna malloc. Needed later for
|
||||
// cleanup.
|
||||
vector_string vargv;
|
||||
std::vector<char *> buffers;
|
||||
|
||||
// Get the strings from the datagram and put them into the string vector
|
||||
for (int i = 0; i < argc; i++) {
|
||||
vargv.push_back(data.get_string().c_str());
|
||||
}
|
||||
|
||||
// Last string is the current directory the client was run from. Not
|
||||
// part of the argument list, but we still need it
|
||||
std::string cwd = data.get_string();
|
||||
|
||||
// We allocate some memory to hold the pointers to the pointers we're
|
||||
// going to pass in to parse_command_line().
|
||||
char **cargv = (char**) malloc(sizeof(char**) * argc);
|
||||
|
||||
// Loop through the string arguments we got from the datagram and
|
||||
// convert them to const char *'s. parse_command_line() expects char
|
||||
// *'s, so we have to copy these const versions into fresh char *, since
|
||||
// there is no casting from const char * to char *.
|
||||
for (int i = 0; i < argc; i++) {
|
||||
// string to const char *
|
||||
const char *cptr = vargv[i].c_str();
|
||||
// memory allocated for a new char * of size of the string
|
||||
char *buffer = (char *) malloc(vargv[i].capacity() + 1);
|
||||
|
||||
// Copy the const char * to the char *
|
||||
strcpy(buffer, cptr);
|
||||
// put this into the arry we defined above. This is what will
|
||||
// eventually be passed to parse_command_line()
|
||||
cargv[i] = buffer;
|
||||
// keep track of the pointers to the allocated memory for cleanup
|
||||
// later
|
||||
buffers.push_back(buffer);
|
||||
}
|
||||
|
||||
// Change to the client's current dir
|
||||
#ifdef _WIN64
|
||||
_chdir(cwd.c_str());
|
||||
#else
|
||||
chdir(cwd.c_str());
|
||||
#endif
|
||||
|
||||
// Change the VirtualFileSystem's current dir as well
|
||||
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
|
||||
vfs->chdir(Filename::from_os_specific(cwd));
|
||||
|
||||
// Next, we'll need to read the conversion type.
|
||||
// Are we converting from egg to maya or from maya to egg?
|
||||
int conversion_type = data.get_uint8();
|
||||
bool converted = false;
|
||||
|
||||
switch (conversion_type) {
|
||||
case ConversionType::CT_maya_to_egg:
|
||||
{
|
||||
MayaToEgg egg;
|
||||
|
||||
// Pass in the 'new' argc and argv we got from the client
|
||||
if (egg.parse_command_line(argc, cargv, false) == ProgramBase::ExitCode::EC_not_exited) {
|
||||
// Actually run the damn thing
|
||||
converted = egg.run();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case ConversionType::CT_egg_to_maya:
|
||||
{
|
||||
EggToMaya maya;
|
||||
maya.set_exit_on_failure(false);
|
||||
|
||||
// Pass in the 'new' argc and argv we got from the client
|
||||
if (maya.parse_command_line(argc, cargv, false) == ProgramBase::ExitCode::EC_not_exited) {
|
||||
// Actually run the damn thing
|
||||
converted = maya.run();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Let's send the result back to the client
|
||||
NetDatagram response;
|
||||
|
||||
// The first and only part of the response is the success value
|
||||
response.add_bool(converted);
|
||||
|
||||
// Send the response
|
||||
if (!_writer.send(response, datagram.get_connection())) {
|
||||
// Looks like we couldn't send the response
|
||||
nout << "Could not send response to the client.\n";
|
||||
}
|
||||
|
||||
std::cout.flush();
|
||||
|
||||
// Cleanup first, release the string vector
|
||||
vargv.clear();
|
||||
// No, iterate through the char * vector and cleanup the malloc'd
|
||||
// pointers
|
||||
std::vector<char *>::iterator vi;
|
||||
for ( vi = buffers.begin() ; vi != buffers.end(); vi++) {
|
||||
free(*vi);
|
||||
}
|
||||
// Clean up the malloc'd pointer pointer
|
||||
free(cargv);
|
||||
} // qReader.get_data
|
||||
|
||||
Clients::iterator ci;
|
||||
for (ci = _clients.begin(); ci != _clients.end(); ++ci) {
|
||||
_manager.close_connection(*ci);
|
||||
}
|
||||
} // qReader.data_available
|
||||
} // poll
|
||||
|
||||
/**
|
||||
* Blocks the current thread and listens to conversion requests.
|
||||
*/
|
||||
void MayaConversionServer::
|
||||
listen() {
|
||||
// Open a rendezvous port for receiving new connections from the client
|
||||
PT(Connection) rend = _manager.open_TCP_server_rendezvous(4242, 100);
|
||||
|
||||
if (rend.is_null()) {
|
||||
nout << "Port opening failed!\n";
|
||||
return;
|
||||
}
|
||||
|
||||
nout << "Server opened on port 4242, waiting for requests...\n";
|
||||
|
||||
// Add this connection to the listeners list
|
||||
_listener.add_connection(rend);
|
||||
|
||||
// Main loop. Keep polling for connections, but don't eat up all the CPU.
|
||||
while (true) {
|
||||
this->poll();
|
||||
Thread::force_yield();
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -1,166 +0,0 @@
|
|||
/**
|
||||
* PANDA 3D SOFTWARE
|
||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
*
|
||||
* All use of this software is subject to the terms of the revised BSD
|
||||
* license. You should have received a copy of this license along
|
||||
* with this source code in a file named "LICENSE."
|
||||
*
|
||||
* @file mayaEggImport.cxx
|
||||
* @author jyelon
|
||||
* @date 2005-07-20
|
||||
*
|
||||
* This is the wrapper code for the maya importer plugin.
|
||||
* It includes:
|
||||
*
|
||||
* - user interface dialogs and popups
|
||||
* - plugin initialization/registration
|
||||
*
|
||||
* It does not include the actual code to traverse the EggData.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "dtoolbase.h"
|
||||
|
||||
// We must define this to prevent Maya from doubly-declaring its MApiVersion
|
||||
// string in this file as well as in libmayaegg.
|
||||
#define _MApiVersion
|
||||
|
||||
#include "pre_maya_include.h"
|
||||
#include <maya/MStatus.h>
|
||||
#include <maya/MPxCommand.h>
|
||||
#include <maya/MString.h>
|
||||
#include <maya/MStringArray.h>
|
||||
#include <maya/MArgList.h>
|
||||
#include <maya/MGlobal.h>
|
||||
#include <maya/MFnPlugin.h>
|
||||
#include <maya/MObject.h>
|
||||
#include <maya/MPlug.h>
|
||||
#include <maya/MPxFileTranslator.h>
|
||||
#include "post_maya_include.h"
|
||||
|
||||
#include "mayaEggLoader.h"
|
||||
#include "notifyCategoryProxy.h"
|
||||
|
||||
|
||||
class MayaEggImporter : public MPxFileTranslator
|
||||
{
|
||||
public:
|
||||
MayaEggImporter () {};
|
||||
virtual ~MayaEggImporter () {};
|
||||
static void* creator();
|
||||
|
||||
MStatus reader ( const MFileObject& file,
|
||||
const MString& optionsString,
|
||||
FileAccessMode mode);
|
||||
|
||||
MStatus writer ( const MFileObject& file,
|
||||
const MString& optionsString,
|
||||
FileAccessMode mode );
|
||||
|
||||
bool haveReadMethod () const { return true; }
|
||||
bool haveWriteMethod () const { return false; }
|
||||
MString defaultExtension () const { return "egg"; }
|
||||
MFileKind identifyFile ( const MFileObject& fileName,
|
||||
const char* buffer,
|
||||
short size) const;
|
||||
};
|
||||
|
||||
|
||||
void* MayaEggImporter::creator()
|
||||
{
|
||||
return new MayaEggImporter();
|
||||
}
|
||||
|
||||
MStatus MayaEggImporter::reader ( const MFileObject& file,
|
||||
const MString& options,
|
||||
FileAccessMode mode)
|
||||
{
|
||||
MString fileName = file.fullName();
|
||||
bool model=false;
|
||||
bool anim=false;
|
||||
|
||||
if (options.length() > 0) {
|
||||
const MString flagModel("model");
|
||||
const MString flagAnim("anim");
|
||||
|
||||
// Start parsing.
|
||||
MStringArray optionList;
|
||||
MStringArray theOption;
|
||||
options.split(';', optionList);
|
||||
|
||||
unsigned nOptions = optionList.length();
|
||||
for (unsigned i = 0; i < nOptions; i++) {
|
||||
|
||||
theOption.clear();
|
||||
optionList[i].split('=', theOption);
|
||||
if (theOption.length() < 1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (theOption[0] == flagModel && theOption.length() > 1) {
|
||||
model = atoi(theOption[1].asChar()) ? true:false;
|
||||
} else if (theOption[0] == flagAnim && theOption.length() > 1) {
|
||||
anim = atoi(theOption[1].asChar()) ? true:false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((mode != kImportAccessMode)&&(mode != kOpenAccessMode))
|
||||
return MS::kFailure;
|
||||
|
||||
bool merge = (mode == kImportAccessMode);
|
||||
std::ostringstream log;
|
||||
Notify::ptr()->set_ostream_ptr(&log, false);
|
||||
bool ok = MayaLoadEggFile(fileName.asChar(), merge, model, anim, false);
|
||||
std::string txt = log.str();
|
||||
if (txt != "") {
|
||||
MGlobal::displayError(txt.c_str());
|
||||
} else {
|
||||
if (!ok) MGlobal::displayError("Cannot import Egg file, unknown reason");
|
||||
}
|
||||
return ok ? MS::kSuccess : MS::kFailure;
|
||||
}
|
||||
|
||||
MStatus MayaEggImporter::writer ( const MFileObject& file,
|
||||
const MString& options,
|
||||
FileAccessMode mode )
|
||||
|
||||
{
|
||||
fprintf(stderr, "MayaEggImporter::writer called in error\n");
|
||||
return MS::kFailure;
|
||||
}
|
||||
|
||||
MPxFileTranslator::MFileKind MayaEggImporter::identifyFile (
|
||||
const MFileObject& fileName,
|
||||
const char* buffer,
|
||||
short size) const
|
||||
{
|
||||
const char * name = fileName.name().asChar();
|
||||
int nameLength = strlen(name);
|
||||
|
||||
if ((nameLength > 4) && !strcmp(name+nameLength-4, ".egg"))
|
||||
return kCouldBeMyFileType;
|
||||
else
|
||||
return kNotMyFileType;
|
||||
}
|
||||
|
||||
EXPCL_MISC MStatus initializePlugin( MObject obj )
|
||||
{
|
||||
MFnPlugin plugin( obj, "Alias", "3.0", "Any");
|
||||
|
||||
// Register the translator with the system
|
||||
return plugin.registerFileTranslator( "Panda3D Egg Import", "none",
|
||||
MayaEggImporter::creator,
|
||||
|
||||
"eggImportOptions",
|
||||
"merge=1;model=1;anim=0;");
|
||||
}
|
||||
|
||||
EXPCL_MISC MStatus uninitializePlugin( MObject obj )
|
||||
{
|
||||
MFnPlugin plugin( obj );
|
||||
return plugin.deregisterFileTranslator( "Panda3D Egg Import" );
|
||||
}
|
||||
|
|
@ -1,335 +0,0 @@
|
|||
/**
|
||||
* PANDA 3D SOFTWARE
|
||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
*
|
||||
* All use of this software is subject to the terms of the revised BSD
|
||||
* license. You should have received a copy of this license along
|
||||
* with this source code in a file named "LICENSE."
|
||||
*
|
||||
* @file mayaPview.cxx
|
||||
* @author drose
|
||||
* @date 2003-03-10
|
||||
*/
|
||||
|
||||
#ifdef __MACH__
|
||||
#define __OPENTRANSPORTPROVIDERS__
|
||||
#endif
|
||||
|
||||
#include "mayaPview.h"
|
||||
#include "mayaToEggConverter.h"
|
||||
#include "eggData.h"
|
||||
#include "load_egg_file.h"
|
||||
#include "config_putil.h"
|
||||
#include "config_chan.h"
|
||||
#include "config_gobj.h"
|
||||
#include "textNode.h"
|
||||
#include "multiplexStream.h"
|
||||
#include "distanceUnit.h"
|
||||
#include "configVariableEnum.h"
|
||||
|
||||
// We must define this to prevent Maya from doubly-declaring its MApiVersion
|
||||
// string in this file as well as in libmayaegg.
|
||||
#define _MApiVersion
|
||||
|
||||
#include "pre_maya_include.h"
|
||||
#include <maya/MString.h>
|
||||
#include <maya/MFnPlugin.h>
|
||||
#include <maya/MFileIO.h>
|
||||
#include <maya/MArgParser.h>
|
||||
#include <maya/MArgList.h>
|
||||
#include <maya/MSyntax.h>
|
||||
#include <maya/MProgressWindow.h>
|
||||
#include "post_maya_include.h"
|
||||
|
||||
// On Windows, we have code to fork pview as a separate process, which seems
|
||||
// to be better for Maya.
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include <process.h>
|
||||
#define SEPARATE_PVIEW 1
|
||||
#endif // _WIN32
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
MayaPview::
|
||||
MayaPview() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the plugin command is invoked.
|
||||
*/
|
||||
MStatus MayaPview::
|
||||
doIt(const MArgList &args) {
|
||||
MStatus result;
|
||||
|
||||
// First, parse the plugin arguments.
|
||||
MSyntax syntax;
|
||||
syntax.addFlag("a", "animate");
|
||||
|
||||
MArgParser parser(syntax, args, &result);
|
||||
if (!result) {
|
||||
result.perror("arguments");
|
||||
return result;
|
||||
}
|
||||
|
||||
bool animate = parser.isFlagSet("a", &result);
|
||||
if (!result) {
|
||||
result.perror("isFlagSet");
|
||||
return result;
|
||||
}
|
||||
|
||||
if (!MProgressWindow::reserve()) {
|
||||
nout << "Couldn't reserve progress window.\n";
|
||||
return MS::kFailure;
|
||||
}
|
||||
MProgressWindow::setTitle("Sending to pview");
|
||||
MProgressWindow::setInterruptable(false);
|
||||
MProgressWindow::setProgressRange(0, 3);
|
||||
MProgressWindow::setProgressStatus("Converting scene");
|
||||
MProgressWindow::startProgress();
|
||||
|
||||
#ifdef SEPARATE_PVIEW
|
||||
// We'll write the bam file to a temporary file first.
|
||||
Filename bam_filename = Filename::temporary("", "pview");
|
||||
bam_filename.set_extension("bam");
|
||||
|
||||
// Since we're just writing to a bam file in this process, and running pview
|
||||
// in a separate process, we don't actually need to load textures at this
|
||||
// point. Disable the loading of textures.
|
||||
textures_header_only = true;
|
||||
|
||||
NodePath root("root");
|
||||
if (!convert(root, animate)) {
|
||||
nout << "failure in conversion.\n";
|
||||
MProgressWindow::endProgress();
|
||||
return MS::kFailure;
|
||||
}
|
||||
|
||||
MProgressWindow::setProgressStatus("Writing bam file");
|
||||
MProgressWindow::advanceProgress(1);
|
||||
|
||||
if (!root.write_bam_file(bam_filename)) {
|
||||
nout << "Couldn't write to " << bam_filename << ".\n";
|
||||
MProgressWindow::endProgress();
|
||||
return MS::kFailure;
|
||||
}
|
||||
|
||||
MProgressWindow::setProgressStatus("Spawning pview");
|
||||
MProgressWindow::advanceProgress(1);
|
||||
|
||||
// Now spawn a pview instance to view this temporary file.
|
||||
std::string pview_args = "-clD";
|
||||
if (animate) {
|
||||
pview_args = "-clDa";
|
||||
}
|
||||
|
||||
// On Windows, we use the spawn function to run pview asynchronously.
|
||||
std::string quoted = std::string("\"") + bam_filename.get_fullpath() + std::string("\"");
|
||||
nout << "pview " << pview_args << " " << quoted << "\n";
|
||||
int retval = _spawnlp(_P_DETACH, "pview",
|
||||
"pview", pview_args.c_str(), quoted.c_str(), nullptr);
|
||||
if (retval == -1) {
|
||||
bam_filename.unlink();
|
||||
MProgressWindow::endProgress();
|
||||
return MS::kFailure;
|
||||
}
|
||||
|
||||
nout << "pview running.\n";
|
||||
MProgressWindow::endProgress();
|
||||
|
||||
#else // SEPARATE_PVIEW
|
||||
// We'll run PandaFramework directly within this process.
|
||||
|
||||
// Maya seems to run each invocation of the plugin in a separate thread. To
|
||||
// minimize conflict in our not-yet-completely-thread-safe Panda, we'll
|
||||
// create a separate PandaFramework for each invocation, even though in
|
||||
// principle we could be sharing one framework for all of them.
|
||||
int argc = 0;
|
||||
char **argv = nullptr;
|
||||
PandaFramework framework;
|
||||
framework.open_framework(argc, argv);
|
||||
framework.set_window_title("Panda Viewer");
|
||||
framework.enable_default_keys();
|
||||
|
||||
PT(WindowFramework) window;
|
||||
window = framework.open_window();
|
||||
if (window == nullptr) {
|
||||
// Couldn't open a window.
|
||||
nout << "Couldn't open a window!\n";
|
||||
MProgressWindow::endProgress();
|
||||
return MS::kFailure;
|
||||
}
|
||||
|
||||
// We've successfully opened a window.
|
||||
|
||||
// Put up a "loading" message for the user's benefit.
|
||||
NodePath aspect_2d = window->get_aspect_2d();
|
||||
PT(TextNode) loading = new TextNode("loading");
|
||||
NodePath loading_np = aspect_2d.attach_new_node(loading);
|
||||
loading_np.set_scale(0.125f);
|
||||
loading->set_text_color(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
loading->set_shadow_color(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
loading->set_shadow(0.04, 0.04);
|
||||
loading->set_align(TextNode::A_center);
|
||||
loading->set_text("Loading...");
|
||||
|
||||
// Allow a couple of frames to go by so the window will be fully created and
|
||||
// the text will be visible.
|
||||
framework.do_frame(Thread::get_current_thread());
|
||||
framework.do_frame(Thread::get_current_thread());
|
||||
|
||||
window->enable_keyboard();
|
||||
window->setup_trackball();
|
||||
framework.get_models().instance_to(window->get_render());
|
||||
|
||||
if (!convert(framework.get_models(), animate)) {
|
||||
nout << "failure in conversion.\n";
|
||||
MProgressWindow::endProgress();
|
||||
return MS::kFailure;
|
||||
}
|
||||
|
||||
nout << "successfully converted.\n";
|
||||
|
||||
loading_np.remove_node();
|
||||
window->center_trackball(framework.get_models());
|
||||
window->loop_animations();
|
||||
|
||||
if (animate) {
|
||||
window->set_anim_controls(true);
|
||||
}
|
||||
|
||||
MProgressWindow::endProgress();
|
||||
framework.main_loop();
|
||||
#endif // SEPARATE_PVIEW
|
||||
|
||||
return MS::kSuccess;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is used to create a new instance of the plugin.
|
||||
*/
|
||||
void *MayaPview::
|
||||
creator() {
|
||||
return new MayaPview;
|
||||
}
|
||||
|
||||
/**
|
||||
* Actually converts the Maya selection to Panda geometry, and parents it to
|
||||
* the indicated NodePath.
|
||||
*/
|
||||
bool MayaPview::
|
||||
convert(const NodePath &parent, bool animate) {
|
||||
// Now make a converter to get all the Maya structures.
|
||||
MayaToEggConverter converter("plug-in");
|
||||
|
||||
// We always want polygon output since we want to be able to see the
|
||||
// results.
|
||||
converter._polygon_output = true;
|
||||
converter._polygon_tolerance = 0.01;
|
||||
|
||||
if (animate) {
|
||||
// We also want to get the animation if there is any.
|
||||
converter.set_animation_convert(AC_both);
|
||||
|
||||
// Don't compress animation channels; that can introduce confusing
|
||||
// artifacts.
|
||||
compress_channels = false;
|
||||
}
|
||||
|
||||
PathReplace *path_replace = converter.get_path_replace();
|
||||
|
||||
// Accept relative pathnames in the Maya file.
|
||||
Filename source_file =
|
||||
Filename::from_os_specific(MFileIO::currentFile().asChar());
|
||||
std::string source_dir = source_file.get_dirname();
|
||||
if (!source_dir.empty()) {
|
||||
path_replace->_path.append_directory(source_dir);
|
||||
}
|
||||
|
||||
// Also search along the model path.
|
||||
path_replace->_path.append_path(get_model_path());
|
||||
|
||||
PT(EggData) egg_data = new EggData;
|
||||
converter.set_egg_data(egg_data);
|
||||
converter.set_from_selection(true);
|
||||
converter.set_neutral_frame(-1);
|
||||
|
||||
if (!converter.convert_maya()) {
|
||||
nout << "Errors in conversion.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
MProgressWindow::setProgressStatus("Converting to bam");
|
||||
MProgressWindow::advanceProgress(1);
|
||||
|
||||
// Now the converter has filled up our egg structure with data, so convert
|
||||
// this egg data to Panda data for immediate viewing.
|
||||
DistanceUnit input_units = converter.get_input_units();
|
||||
ConfigVariableEnum<DistanceUnit> ptloader_units("ptloader-units", DU_invalid);
|
||||
if (input_units != DU_invalid && ptloader_units != DU_invalid &&
|
||||
input_units != ptloader_units) {
|
||||
// Convert the file to the units specified by the ptloader-units Configrc
|
||||
// variable.
|
||||
nout
|
||||
<< "Converting from " << format_long_unit(input_units)
|
||||
<< " to " << format_long_unit(ptloader_units) << "\n";
|
||||
double scale = convert_units(input_units, ptloader_units);
|
||||
egg_data->transform(LMatrix4d::scale_mat(scale));
|
||||
}
|
||||
|
||||
egg_data->set_coordinate_system(CS_default);
|
||||
PT(PandaNode) result = load_egg_data(egg_data);
|
||||
|
||||
if (result == nullptr) {
|
||||
nout << "Unable to load converted egg data.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
parent.attach_new_node(result);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Called by Maya when the plugin is loaded.
|
||||
*/
|
||||
EXPCL_MISC MStatus
|
||||
initializePlugin(MObject obj) {
|
||||
// This code is just for debugging, to cause Notify to write its output to a
|
||||
// log file we can inspect, so we can see the error messages output by DX7
|
||||
// or DX8 just before it does a panic exit (and thereby shuts down Maya and
|
||||
// its output window).
|
||||
/*
|
||||
MultiplexStream *local_nout = new MultiplexStream();
|
||||
Notify::ptr()->set_ostream_ptr(local_nout, 0);
|
||||
local_nout->add_file(Filename::expand_from("$TEMP/libmayapview.log"));
|
||||
local_nout->add_standard_output();
|
||||
*/
|
||||
|
||||
MFnPlugin plugin(obj, "VR Studio", "1.0");
|
||||
MStatus status;
|
||||
status = plugin.registerCommand("pview", MayaPview::creator);
|
||||
if (!status) {
|
||||
status.perror("registerCommand");
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by Maya when the plugin is unloaded.
|
||||
*/
|
||||
EXPCL_MISC MStatus
|
||||
uninitializePlugin(MObject obj) {
|
||||
MFnPlugin plugin(obj);
|
||||
MStatus status;
|
||||
status = plugin.deregisterCommand("pview");
|
||||
|
||||
if (!status) {
|
||||
status.perror("deregisterCommand");
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
/**
|
||||
* PANDA 3D SOFTWARE
|
||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
*
|
||||
* All use of this software is subject to the terms of the revised BSD
|
||||
* license. You should have received a copy of this license along
|
||||
* with this source code in a file named "LICENSE."
|
||||
*
|
||||
* @file mayaPview.h
|
||||
* @author drose
|
||||
* @date 2003-03-11
|
||||
*/
|
||||
|
||||
#ifndef MAYAPVIEW_H
|
||||
#define MAYAPVIEW_H
|
||||
|
||||
#include "pandatoolbase.h"
|
||||
#include "pandaFramework.h"
|
||||
|
||||
#include "pre_maya_include.h"
|
||||
#include <maya/MArgList.h>
|
||||
#include <maya/MPxCommand.h>
|
||||
#include <maya/MObject.h>
|
||||
#include "post_maya_include.h"
|
||||
|
||||
/**
|
||||
* This class serves as a plug-in to Maya to allow viewing the current Maya
|
||||
* selection as it will be converted to Panda.
|
||||
*/
|
||||
class MayaPview : public MPxCommand {
|
||||
public:
|
||||
MayaPview();
|
||||
virtual MStatus doIt(const MArgList &args);
|
||||
|
||||
static void *creator();
|
||||
|
||||
private:
|
||||
bool convert(const NodePath &parent, bool animate);
|
||||
};
|
||||
|
||||
EXPCL_MISC MStatus initializePlugin(MObject obj);
|
||||
EXPCL_MISC MStatus uninitializePlugin(MObject obj);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -1,133 +0,0 @@
|
|||
/**
|
||||
* PANDA 3D SOFTWARE
|
||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
*
|
||||
* All use of this software is subject to the terms of the revised BSD
|
||||
* license. You should have received a copy of this license along
|
||||
* with this source code in a file named "LICENSE."
|
||||
*
|
||||
* @file mayaSavePview.cxx
|
||||
* @author drose
|
||||
* @date 2003-10-27
|
||||
*/
|
||||
|
||||
#include "mayaSavePview.h"
|
||||
|
||||
#include <maya/MString.h>
|
||||
#include <maya/MFnPlugin.h>
|
||||
#include <maya/MFileIO.h>
|
||||
#include <maya/MArgParser.h>
|
||||
#include <maya/MArgList.h>
|
||||
#include <maya/MSyntax.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <process.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
MayaSavePview::
|
||||
MayaSavePview() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the plugin command is invoked.
|
||||
*/
|
||||
MStatus MayaSavePview::
|
||||
doIt(const MArgList &args) {
|
||||
MStatus result;
|
||||
|
||||
// First, parse the plugin arguments.
|
||||
MSyntax syntax;
|
||||
syntax.addFlag("a", "animate");
|
||||
|
||||
MArgParser parser(syntax, args, &result);
|
||||
if (!result) {
|
||||
result.perror("arguments");
|
||||
return result;
|
||||
}
|
||||
|
||||
bool animate = parser.isFlagSet("a", &result);
|
||||
if (!result) {
|
||||
result.perror("isFlagSet");
|
||||
return result;
|
||||
}
|
||||
|
||||
// Now make sure the current buffer is saved.
|
||||
result = MFileIO::save(false);
|
||||
if (result != MS::kSuccess) {
|
||||
return result;
|
||||
}
|
||||
|
||||
MString filename = MFileIO::currentFile();
|
||||
|
||||
MString pview_args = "-cl";
|
||||
if (animate) {
|
||||
pview_args = "-cla";
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
// On Windows, we use the spawn function to run pview asynchronously.
|
||||
MString quoted = MString("\"") + filename + MString("\"");
|
||||
intptr_t retval = _spawnlp(_P_DETACH, "pview",
|
||||
"pview", pview_args.asChar(), quoted.asChar(), nullptr);
|
||||
if (retval == -1) {
|
||||
return MS::kFailure;
|
||||
}
|
||||
|
||||
#else // _WIN32
|
||||
// On non-Windows (e.g. Unix), we just use the system function, which runs
|
||||
// synchronously. We could fork a process, but no one's asked for this yet.
|
||||
MString command = MString("pview " + pview_args + MString(" \"") + filename + MString("\""));
|
||||
|
||||
int command_result = system(command.asChar());
|
||||
if (command_result != 0) {
|
||||
return MS::kFailure;
|
||||
}
|
||||
#endif // _WIN32
|
||||
|
||||
return MS::kSuccess;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is used to create a new instance of the plugin.
|
||||
*/
|
||||
void *MayaSavePview::
|
||||
creator() {
|
||||
return new MayaSavePview;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Called by Maya when the plugin is loaded.
|
||||
*/
|
||||
EXPCL_MISC MStatus
|
||||
initializePlugin(MObject obj) {
|
||||
MFnPlugin plugin(obj, "VR Studio", "1.0");
|
||||
MStatus status;
|
||||
status = plugin.registerCommand("pview", MayaSavePview::creator);
|
||||
if (!status) {
|
||||
status.perror("registerCommand");
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by Maya when the plugin is unloaded.
|
||||
*/
|
||||
EXPCL_MISC MStatus
|
||||
uninitializePlugin(MObject obj) {
|
||||
MFnPlugin plugin(obj);
|
||||
MStatus status;
|
||||
status = plugin.deregisterCommand("pview");
|
||||
|
||||
if (!status) {
|
||||
status.perror("deregisterCommand");
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
|
@ -1,84 +0,0 @@
|
|||
/**
|
||||
* PANDA 3D SOFTWARE
|
||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
*
|
||||
* All use of this software is subject to the terms of the revised BSD
|
||||
* license. You should have received a copy of this license along
|
||||
* with this source code in a file named "LICENSE."
|
||||
*
|
||||
* @file mayaSavePview.h
|
||||
* @author drose
|
||||
* @date 2003-10-27
|
||||
*/
|
||||
|
||||
#ifndef MAYASAVEPVIEW_H
|
||||
#define MAYASAVEPVIEW_H
|
||||
|
||||
// We don't want to include pre_maya_include.h here, since that would
|
||||
// necessitate linking with Pandatool's libmaya.dll, which would in turn bring
|
||||
// in a lot of stuff from panda that we don't really need. Instead, we'll
|
||||
// just define the Maya symbols we require here.
|
||||
|
||||
// Maya will try to typedef bool unless this symbol is defined.
|
||||
#ifndef _BOOL
|
||||
#define _BOOL 1
|
||||
#endif
|
||||
|
||||
#ifdef __MACH__
|
||||
#define OSMac_ 1
|
||||
// This defines MAYA_API_VERSION
|
||||
#include <maya/MTypes.h>
|
||||
#if MAYA_API_VERSION < 201600
|
||||
#include <maya/OpenMayaMac.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Even though we don't include any Panda headers, it's safe to include this
|
||||
// one, since it only defines some macros that we need to make this program
|
||||
// platform-independent.
|
||||
#include "dtool_config.h"
|
||||
|
||||
#ifdef PHAVE_IOSTREAM
|
||||
// This will ask Maya 5.0 or better to use the new <iostream> library instead
|
||||
// of the old <iostream.h> library.
|
||||
#define REQUIRE_IOSTREAM
|
||||
#endif // PHAVE_IOSTREAM
|
||||
|
||||
#include <maya/MArgList.h>
|
||||
#include <maya/MPxCommand.h>
|
||||
#include <maya/MObject.h>
|
||||
|
||||
/**
|
||||
* This class serves as a plug-in to Maya to save the scene and view it using
|
||||
* the external pview program, rather than linking in any part of Panda to a
|
||||
* Maya plugin.
|
||||
*
|
||||
* Since it does not link with any Panda code, and hence is a very lean
|
||||
* plugin, it is less likely than MayaPview to cause interoperability problems
|
||||
* within Maya. However, it does force a save-to-disk and a spawning of a
|
||||
* separate executable, including a complete reloading of all of the Maya
|
||||
* libraries, so it is quite a bit slower to execute. And the potential for
|
||||
* interactive control is substantially reduced.
|
||||
*/
|
||||
class MayaSavePview : public MPxCommand {
|
||||
public:
|
||||
MayaSavePview();
|
||||
virtual MStatus doIt(const MArgList &args);
|
||||
|
||||
static void *creator();
|
||||
};
|
||||
|
||||
// Since we don't include any of the Panda headers (other than
|
||||
// dtool_config.h), we have to define this macro ourselves, to tell Windows to
|
||||
// export the following functions from the DLL.
|
||||
#ifdef _WIN32
|
||||
#define EXPCL_MISC __declspec(dllexport)
|
||||
#else
|
||||
#define EXPCL_MISC
|
||||
#endif
|
||||
|
||||
EXPCL_MISC MStatus initializePlugin(MObject obj);
|
||||
EXPCL_MISC MStatus uninitializePlugin(MObject obj);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -1,474 +0,0 @@
|
|||
/**
|
||||
* PANDA 3D SOFTWARE
|
||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
*
|
||||
* All use of this software is subject to the terms of the revised BSD
|
||||
* license. You should have received a copy of this license along
|
||||
* with this source code in a file named "LICENSE."
|
||||
*
|
||||
* @file mayapath.cxx
|
||||
* @author drose
|
||||
* @date 2008-04-07
|
||||
*/
|
||||
|
||||
// This program works as a stub to launch maya2egg, egg2maya, and similar
|
||||
// programs that invoke OpenMaya and require certain environment variables to
|
||||
// be set first.
|
||||
|
||||
// It used to duplicate code in mayaWrapper.cxx, but now the functionality for
|
||||
// these two separate programs are unified here.
|
||||
|
||||
// If MAYAVERSION is defined at the time this is compiled, then that
|
||||
// particular version of Maya is insisted upon, and the desired Maya location
|
||||
// is found in the Registry; otherwise, we require that $MAYA_LOCATION be set
|
||||
// at runtime and points to the desired Maya installation.
|
||||
|
||||
/*
|
||||
* If MAYAVERSION is defined and $MAYA_LOCATION is also set, then we check
|
||||
* that definition of $MAYA_LOCATION is reasonable, which we define as
|
||||
* pointing to the same version of OpenMaya.dll. If so, then we use the
|
||||
* runtime $MAYA_LOCATION, allowing the user to (slightly) override the
|
||||
* runtime Maya directory. If $MAYA_LOCATION is set but points to a different
|
||||
* version of OpenMaya.dll, we ignore it altogether and replace it with our
|
||||
* registry data, which allows the user to have MAYA_LOCATION pointing to a
|
||||
* different version of Maya without interfering with this program.
|
||||
*/
|
||||
|
||||
#include "dtoolbase.h"
|
||||
#include "filename.h"
|
||||
#include "globPattern.h"
|
||||
#include "dSearchPath.h"
|
||||
#include "executionEnvironment.h"
|
||||
#include "hashVal.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
#if defined(_WIN32)
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
using std::string;
|
||||
|
||||
#define QUOTESTR(x) #x
|
||||
#define TOSTRING(x) QUOTESTR(x)
|
||||
|
||||
// Searches for python26.zip or whatever version it is.
|
||||
static Filename
|
||||
find_pyzip(const Filename &maya_location) {
|
||||
// This is where python26.zip appears on Windows. Should it be in other
|
||||
// locations on other platforms?
|
||||
Filename dirname(maya_location, "bin");
|
||||
|
||||
vector_string results;
|
||||
GlobPattern glob("python*.zip");
|
||||
if (glob.match_files(results, dirname) != 0) {
|
||||
return Filename(dirname, results[0]);
|
||||
}
|
||||
|
||||
return Filename();
|
||||
}
|
||||
|
||||
struct MayaVerInfo {
|
||||
const char *ver, *key;
|
||||
};
|
||||
|
||||
struct MayaVerInfo maya_versions[] = {
|
||||
{ "MAYA6", "6.0" },
|
||||
{ "MAYA65", "6.5" },
|
||||
{ "MAYA7", "7.0" },
|
||||
{ "MAYA8", "8.0" },
|
||||
{ "MAYA85", "8.5" },
|
||||
{ "MAYA2008", "2008"},
|
||||
{ "MAYA2009", "2009"},
|
||||
{ "MAYA2010", "2010"},
|
||||
{ "MAYA2011", "2011"},
|
||||
{ "MAYA2012", "2012"},
|
||||
{ "MAYA2013", "2013"},
|
||||
{ "MAYA20135", "2013.5"},
|
||||
{ "MAYA2014", "2014"},
|
||||
{ "MAYA2015", "2015"},
|
||||
{ "MAYA2016", "2016"},
|
||||
{ "MAYA20165", "2016.5"},
|
||||
{ "MAYA2017", "2017"},
|
||||
{ "MAYA2018", "2018"},
|
||||
{ "MAYA2019", "2019"},
|
||||
{ "MAYA2020", "2020"},
|
||||
{ "MAYA2022", "2022"},
|
||||
{ 0, 0 },
|
||||
};
|
||||
|
||||
static const char *
|
||||
get_version_number(const char *ver) {
|
||||
for (int i = 0; maya_versions[i].ver != 0; ++i) {
|
||||
if (strcmp(maya_versions[i].ver, ver) == 0) {
|
||||
return maya_versions[i].key;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static Filename
|
||||
get_openmaya_filename(const Filename &maya_location) {
|
||||
#ifdef _WIN32
|
||||
// Note: Filename::dso_filename changes .so to .dll automatically.
|
||||
// Maya 2022 has two versions of OpenMaya.dll, one for Python 3 and
|
||||
// one for Python 2, in bin3 and bin2 folders.
|
||||
Filename bin3 = Filename(maya_location, "bin3");
|
||||
Filename bin3_openmaya = Filename::dso_filename(maya_location / "bin3/OpenMaya.so");
|
||||
if (bin3_openmaya.is_regular_file()) {
|
||||
return bin3_openmaya;
|
||||
}
|
||||
return Filename::dso_filename(maya_location / "bin/OpenMaya.so");
|
||||
#elif defined(IS_OSX)
|
||||
return Filename::dso_filename(maya_location / "MacOS/libOpenMaya.dylib");
|
||||
#else
|
||||
return Filename::dso_filename(maya_location / "lib/libOpenMaya.so");
|
||||
#endif // _WIN32
|
||||
}
|
||||
|
||||
#if defined(_WIN32)
|
||||
static void
|
||||
get_maya_location(const char *ver, string &loc) {
|
||||
char fullkey[1024];
|
||||
const char *developer;
|
||||
LONG res;
|
||||
|
||||
for (int dev=0; dev<3; dev++) {
|
||||
switch (dev) {
|
||||
case 0: developer="Alias|Wavefront"; break;
|
||||
case 1: developer="Alias"; break;
|
||||
case 2: developer="Autodesk"; break;
|
||||
}
|
||||
sprintf(fullkey, "SOFTWARE\\%s\\Maya\\%s\\Setup\\InstallPath", developer, ver);
|
||||
for (int hive=0; hive<2; hive++) {
|
||||
HKEY hkey;
|
||||
res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, fullkey, 0, KEY_READ | (hive ? 256:0), &hkey);
|
||||
if (res == ERROR_SUCCESS) {
|
||||
DWORD dtype;
|
||||
DWORD size = 4096;
|
||||
char result[4096 + 1];
|
||||
res = RegQueryValueEx(hkey, "MAYA_INSTALL_LOCATION", nullptr, &dtype, (LPBYTE)result, &size);
|
||||
if ((res == ERROR_SUCCESS)&&(dtype == REG_SZ)) {
|
||||
result[size] = 0;
|
||||
loc = result;
|
||||
}
|
||||
RegCloseKey(hkey);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(__APPLE__)
|
||||
static void
|
||||
get_maya_location(const char *ver, string &loc) {
|
||||
char mpath[64];
|
||||
sprintf(mpath, "/Applications/Autodesk/maya%s/Maya.app/Contents", ver);
|
||||
struct stat st;
|
||||
if(stat(mpath, &st) == 0) {
|
||||
loc = mpath;
|
||||
}
|
||||
}
|
||||
|
||||
#else // _WIN32
|
||||
static void
|
||||
get_maya_location(const char *ver, string &loc) {
|
||||
char mpath[64];
|
||||
#if __WORDSIZE == 64
|
||||
sprintf(mpath, "/usr/autodesk/maya%s-x64", ver);
|
||||
#else
|
||||
sprintf(mpath, "/usr/autodesk/maya%s", ver);
|
||||
#endif
|
||||
struct stat st;
|
||||
if(stat(mpath, &st) == 0) {
|
||||
loc = mpath;
|
||||
} else {
|
||||
#if __WORDSIZE == 64
|
||||
sprintf(mpath, "/usr/aw/maya%s-x64", ver);
|
||||
#else
|
||||
sprintf(mpath, "/usr/aw/maya%s", ver);
|
||||
#endif
|
||||
if(stat(mpath, &st) == 0) {
|
||||
loc = mpath;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // _WIN32
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char *argv[]) {
|
||||
// First, get the command line and append _bin, so we will actually run
|
||||
// maya2egg_bin.exe, egg2maya_bin.exe, etc.
|
||||
Filename command = ExecutionEnvironment::get_binary_name();
|
||||
|
||||
if (command.empty() || command == "unknown" || !command.exists()) {
|
||||
command = Filename::from_os_specific(argv[0]);
|
||||
|
||||
if (!command.is_fully_qualified()) {
|
||||
DSearchPath path;
|
||||
path.append_path(ExecutionEnvironment::get_environment_variable("PATH"));
|
||||
#ifdef _WIN32
|
||||
command.set_extension("exe");
|
||||
#endif
|
||||
command.resolve_filename(path);
|
||||
}
|
||||
}
|
||||
|
||||
command.set_basename_wo_extension(command.get_basename_wo_extension() + "_bin");
|
||||
string os_command = command.to_os_specific();
|
||||
|
||||
// First start with $PANDA_MAYA_LOCATION. If it is set, it overrides
|
||||
// everything else.
|
||||
Filename maya_location = Filename::expand_from("$PANDA_MAYA_LOCATION");
|
||||
if (!maya_location.empty()) {
|
||||
// Reset maya_location to its full long name, because Maya requires this.
|
||||
maya_location.make_canonical();
|
||||
maya_location = Filename::from_os_specific(maya_location.to_os_long_name());
|
||||
|
||||
} else {
|
||||
// $PANDA_MAYA_LOCATION wasn't set, so check the normal locations. First,
|
||||
// we get the standard location, as a point of reference.
|
||||
Filename standard_maya_location;
|
||||
#ifdef MAYAVERSION
|
||||
const char *key = get_version_number(TOSTRING(MAYAVERSION));
|
||||
if (key == nullptr) {
|
||||
cerr << "Unknown Maya version: " << TOSTRING(MAYAVERSION) << "\n";
|
||||
} else {
|
||||
string loc;
|
||||
get_maya_location(key, loc);
|
||||
if (loc.empty()) {
|
||||
cerr << "Cannot locate " << TOSTRING(MAYAVERSION) << ": it does not appear to be installed.\n";
|
||||
} else {
|
||||
standard_maya_location = Filename::from_os_specific(loc);
|
||||
}
|
||||
}
|
||||
if (!standard_maya_location.empty()) {
|
||||
// Reset standard_maya_location to its full long name, so we can compare
|
||||
// reliably to the given version.
|
||||
standard_maya_location.make_canonical();
|
||||
standard_maya_location = Filename::from_os_specific(standard_maya_location.to_os_long_name());
|
||||
}
|
||||
#endif // MAYAVERSION
|
||||
|
||||
// Now check if $MAYA_LOCATION is set. If it is, and it's consistent with
|
||||
// the standard location, we respect it.
|
||||
maya_location = Filename::expand_from("$MAYA_LOCATION");
|
||||
if (!maya_location.empty()) {
|
||||
// Reset maya_location to its full long name, so we can compare it
|
||||
// reliably to the standard location; and also because Maya requires
|
||||
// this.
|
||||
maya_location.make_canonical();
|
||||
maya_location = Filename::from_os_specific(maya_location.to_os_long_name());
|
||||
}
|
||||
|
||||
if (maya_location.empty()) {
|
||||
// If it is not set, we use the standard version instead.
|
||||
maya_location = standard_maya_location;
|
||||
|
||||
} else if (maya_location != standard_maya_location) {
|
||||
// If it *is* set, we verify that OpenMaya.dll matches the standard
|
||||
// version.
|
||||
Filename openmaya_given = get_openmaya_filename(maya_location);
|
||||
Filename openmaya_standard = get_openmaya_filename(standard_maya_location);
|
||||
|
||||
if (openmaya_given != openmaya_standard) {
|
||||
// Check the md5 hashes of the DLL.
|
||||
HashVal hash_given, hash_standard;
|
||||
if (!hash_standard.hash_file(openmaya_standard)) {
|
||||
// Couldn't read the standard file, so use the given one.
|
||||
|
||||
} else {
|
||||
if (!hash_given.hash_file(openmaya_given)) {
|
||||
// Couldn't even read the given file; use the standard one
|
||||
// instead.
|
||||
maya_location = standard_maya_location;
|
||||
|
||||
} else {
|
||||
if (hash_standard != hash_given) {
|
||||
// No match; it must be the wrong version.
|
||||
cerr << "$MAYA_LOCATION points to wrong version; using standard location instead.\n";
|
||||
maya_location = standard_maya_location;
|
||||
} else {
|
||||
// The hash matches; keep the given MAYA_LOCATION setting.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (maya_location.empty()) {
|
||||
cerr << "$MAYA_LOCATION is not set!\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
cerr << "MAYA_LOCATION: " << maya_location.to_os_specific() << endl;
|
||||
if (!maya_location.is_directory()) {
|
||||
cerr << "The directory referred to by $MAYA_LOCATION does not exist!\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Look for OpenMaya.dll as a sanity check.
|
||||
Filename openmaya = get_openmaya_filename(maya_location);
|
||||
if (!openmaya.is_regular_file()) {
|
||||
cerr << "Could not find OpenMaya library in $MAYA_LOCATION!\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Re-set MAYA_LOCATION to its properly sanitized form.
|
||||
{
|
||||
string putenv_str = "MAYA_LOCATION=" + maya_location.to_os_specific();
|
||||
char *putenv_cstr = strdup(putenv_str.c_str());
|
||||
putenv(putenv_cstr);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
string sep = ";";
|
||||
#else
|
||||
string sep = ":";
|
||||
#endif
|
||||
|
||||
// Now set PYTHONHOME & PYTHONPATH. Maya2008 requires this to be set and
|
||||
// pointing within $MAYA_LOCATION, or it might get itself confused with
|
||||
// another Python installation (e.g. Panda's).
|
||||
Filename python = Filename(maya_location, "Python");
|
||||
if (python.is_directory()) {
|
||||
{
|
||||
string putenv_str = "PYTHONHOME=" + python.to_os_specific();
|
||||
char *putenv_cstr = strdup(putenv_str.c_str());
|
||||
putenv(putenv_cstr);
|
||||
}
|
||||
{
|
||||
string putenv_str = "PYTHONPATH=" + python.to_os_specific();
|
||||
|
||||
Filename pyzip = find_pyzip(maya_location);
|
||||
if (!pyzip.empty() && pyzip.exists()) {
|
||||
putenv_str += sep;
|
||||
putenv_str += pyzip.to_os_specific();
|
||||
}
|
||||
|
||||
Filename site_packages(python, "lib/site-packages");
|
||||
if (site_packages.is_directory()) {
|
||||
putenv_str += sep;
|
||||
putenv_str += site_packages.to_os_specific();
|
||||
}
|
||||
|
||||
char *putenv_cstr = strdup(putenv_str.c_str());
|
||||
putenv(putenv_cstr);
|
||||
}
|
||||
}
|
||||
|
||||
// Also put the Maya bin directory on the PATH.
|
||||
#ifdef IS_OSX
|
||||
Filename bin = Filename(maya_location, "MacOS");
|
||||
#else
|
||||
Filename bin = Filename(maya_location, "bin");
|
||||
#endif
|
||||
if (bin.is_directory()) {
|
||||
const char *path = getenv("PATH");
|
||||
if (path == nullptr) {
|
||||
path = "";
|
||||
}
|
||||
string putenv_str = "PATH=";
|
||||
|
||||
// On Windows, there may also be a bin3 or bin2 directory, we should
|
||||
// add either one to the PATH.
|
||||
#ifdef _WIN32
|
||||
Filename bin3 = Filename(maya_location, "bin3");
|
||||
if (bin3.is_directory()) {
|
||||
putenv_str += bin3.to_os_specific() + sep;
|
||||
}
|
||||
#endif
|
||||
putenv_str += bin.to_os_specific() + sep + path;
|
||||
|
||||
char *putenv_cstr = strdup(putenv_str.c_str());
|
||||
putenv(putenv_cstr);
|
||||
}
|
||||
|
||||
#ifdef IS_OSX
|
||||
// And on DYLD_LIBRARY_PATH.
|
||||
if (bin.is_directory()) {
|
||||
const char *path = getenv("DYLD_LIBRARY_PATH");
|
||||
if (path == nullptr) {
|
||||
path = "";
|
||||
}
|
||||
string sep = ":";
|
||||
string putenv_str = "DYLD_LIBRARY_PATH=" + bin.to_os_specific() + sep + path;
|
||||
char *putenv_cstr = strdup(putenv_str.c_str());
|
||||
putenv(putenv_cstr);
|
||||
}
|
||||
|
||||
// We also have to give it a way to find the Maya frameworks.
|
||||
Filename fw_dir = Filename(maya_location, "Frameworks");
|
||||
if (fw_dir.is_directory()) {
|
||||
const char *path = getenv("DYLD_FALLBACK_FRAMEWORK_PATH");
|
||||
if (path == nullptr) {
|
||||
path = "";
|
||||
}
|
||||
string sep = ":";
|
||||
string putenv_str = "DYLD_FALLBACK_FRAMEWORK_PATH=" + fw_dir.to_os_specific() + sep + path;
|
||||
char *putenv_cstr = strdup(putenv_str.c_str());
|
||||
putenv(putenv_cstr);
|
||||
}
|
||||
|
||||
#elif !defined(_WIN32)
|
||||
// Linux (or other non-Windows OS) gets it added to LD_LIBRARY_PATH.
|
||||
if (bin.is_directory()) {
|
||||
const char *path = getenv("LD_LIBRARY_PATH");
|
||||
if (path == nullptr) {
|
||||
path = "";
|
||||
}
|
||||
string sep = ":";
|
||||
string putenv_str = "LD_LIBRARY_PATH=" + bin.to_os_specific() + sep + path;
|
||||
char *putenv_cstr = strdup(putenv_str.c_str());
|
||||
putenv(putenv_cstr);
|
||||
}
|
||||
|
||||
#endif // IS_OSX
|
||||
|
||||
// Now that we have set up the environment variables properly, chain to the
|
||||
// actual maya2egg_bin (or whichever) executable.
|
||||
|
||||
#ifdef _WIN32
|
||||
// Windows case.
|
||||
char *command_line = strdup(GetCommandLine());
|
||||
STARTUPINFO startup_info;
|
||||
PROCESS_INFORMATION process_info;
|
||||
GetStartupInfo(&startup_info);
|
||||
BOOL result = CreateProcess(os_command.c_str(),
|
||||
command_line,
|
||||
nullptr, nullptr, true, 0,
|
||||
nullptr, nullptr,
|
||||
&startup_info,
|
||||
&process_info);
|
||||
if (result) {
|
||||
WaitForSingleObject(process_info.hProcess, INFINITE);
|
||||
DWORD exit_code = 0;
|
||||
|
||||
if (GetExitCodeProcess(process_info.hProcess, &exit_code)) {
|
||||
if (exit_code != 0) {
|
||||
cerr << "Program exited with status " << exit_code << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
CloseHandle(process_info.hProcess);
|
||||
CloseHandle(process_info.hThread);
|
||||
exit(exit_code);
|
||||
}
|
||||
cerr << "Couldn't execute " << command << ": " << GetLastError() << "\n";
|
||||
|
||||
#else
|
||||
// Unix case.
|
||||
execvp(os_command.c_str(), argv);
|
||||
#endif
|
||||
|
||||
// Couldn't execute for some reason.
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -1,289 +0,0 @@
|
|||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <stdlib.h>
|
||||
#include <string>
|
||||
|
||||
#ifndef _BOOL
|
||||
#define _BOOL 1
|
||||
#endif
|
||||
|
||||
#define REQUIRE_IOSTREAM
|
||||
|
||||
#include <maya/MGlobal.h>
|
||||
#include <maya/MFileIO.h>
|
||||
#include <maya/MLibrary.h>
|
||||
#include <maya/MStatus.h>
|
||||
#include <maya/MItDag.h>
|
||||
#include <maya/MDagPath.h>
|
||||
#include <maya/MFnDagNode.h>
|
||||
#include <maya/MItMeshPolygon.h>
|
||||
#include <maya/MItSelectionList.h>
|
||||
#include <maya/MFnBlendShapeDeformer.h>
|
||||
#include <maya/MFnMesh.h>
|
||||
#include <maya/MPointArray.h>
|
||||
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
|
||||
void
|
||||
scan_nodes() {
|
||||
MStatus status;
|
||||
|
||||
MItDag dag_iterator(MItDag::kDepthFirst, MFn::kTransform, &status);
|
||||
if (!status) {
|
||||
status.perror("MItDag constructor");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
while (!dag_iterator.isDone()) {
|
||||
MDagPath dag_path;
|
||||
status = dag_iterator.getPath(dag_path);
|
||||
if (!status) {
|
||||
status.perror("MItDag::getPath");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
MFnDagNode dag_node(dag_path, &status);
|
||||
if (!status) {
|
||||
status.perror("MFnDagNode constructor");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
cerr << dag_node.name() << "\n";
|
||||
|
||||
dag_iterator.next();
|
||||
}
|
||||
}
|
||||
|
||||
MFnBlendShapeDeformer *
|
||||
get_slider(MString slider_name) {
|
||||
MStatus status;
|
||||
|
||||
status = MGlobal::selectByName(slider_name, MGlobal::kReplaceList);
|
||||
if (!status) {
|
||||
status.perror(slider_name);
|
||||
exit(1);
|
||||
}
|
||||
MSelectionList list;
|
||||
status = MGlobal::getActiveSelectionList(list);
|
||||
if (!status) {
|
||||
status.perror("MGLobal::getActiveSelectionList");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
unsigned int num_objects = list.length();
|
||||
if (num_objects != 1) {
|
||||
cerr << "Warning: multiple objects match " << slider_name << "\n";
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < num_objects; i++) {
|
||||
MObject obj;
|
||||
status = list.getDependNode(i, obj);
|
||||
if (!status) {
|
||||
cerr << "selected element is not a dependency node.\n";
|
||||
status.perror("getDependNode");
|
||||
} else {
|
||||
if (obj.hasFn(MFn::kBlendShape)) {
|
||||
MFnBlendShapeDeformer *slider = new MFnBlendShapeDeformer(obj, &status);
|
||||
if (!status) {
|
||||
status.perror("MFnBlendShapeDeformer constructor");
|
||||
} else {
|
||||
cerr << "got slider " << slider->name() << "\n";
|
||||
return slider;
|
||||
}
|
||||
}
|
||||
|
||||
cerr << "selected element is not a blend shape\n";
|
||||
}
|
||||
}
|
||||
|
||||
cerr << "Couldn't find slider " << slider_name << "\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
MFnMesh *
|
||||
get_mesh(MString mesh_name) {
|
||||
MStatus status;
|
||||
|
||||
status = MGlobal::selectByName(mesh_name, MGlobal::kReplaceList);
|
||||
if (!status) {
|
||||
status.perror(mesh_name);
|
||||
exit(1);
|
||||
}
|
||||
MSelectionList list;
|
||||
status = MGlobal::getActiveSelectionList(list);
|
||||
if (!status) {
|
||||
status.perror("MGLobal::getActiveSelectionList");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
unsigned int num_objects = list.length();
|
||||
if (num_objects != 1) {
|
||||
cerr << "Warning: multiple objects match " << mesh_name << "\n";
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < num_objects; i++) {
|
||||
MObject obj;
|
||||
status = list.getDependNode(i, obj);
|
||||
if (!status) {
|
||||
cerr << "selected element is not a dependency node.\n";
|
||||
status.perror("getDependNode");
|
||||
|
||||
} else {
|
||||
if (obj.hasFn(MFn::kMesh)) {
|
||||
// Maybe it's a mesh object itself.
|
||||
MFnMesh *mesh = new MFnMesh(obj, &status);
|
||||
if (!status) {
|
||||
status.perror("MFnMesh constructor");
|
||||
} else {
|
||||
cerr << "got mesh " << mesh->name() << "\n";
|
||||
return mesh;
|
||||
}
|
||||
|
||||
} else if (obj.hasFn(MFn::kDagNode)) {
|
||||
// Maybe it's a dag node.
|
||||
MDagPath path;
|
||||
status = MDagPath::getAPathTo(obj, path);
|
||||
if (!status) {
|
||||
status.perror("MDagPath::getAPathTo");
|
||||
exit(1);
|
||||
}
|
||||
if (path.hasFn(MFn::kMesh)) {
|
||||
MFnMesh *mesh = new MFnMesh(path, &status);
|
||||
if (!status) {
|
||||
status.perror("MFnMesh constructor");
|
||||
} else {
|
||||
cerr << "got mesh " << mesh->name() << "\n";
|
||||
return mesh;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cerr << "selected element is not a mesh\n";
|
||||
}
|
||||
}
|
||||
|
||||
cerr << "Couldn't find mesh " << mesh_name << "\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void
|
||||
output_vertices(const char *filename, MFnMesh &mesh) {
|
||||
MStatus status;
|
||||
|
||||
MPointArray verts;
|
||||
// status = mesh.getPoints(verts, MSpace::kObject);
|
||||
status = mesh.getPoints(verts, MSpace::kWorld);
|
||||
if (!status) {
|
||||
status.perror("mesh.getPoints");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
std::ofstream file(filename, std::ios::out | std::ios::trunc);
|
||||
if (!file) {
|
||||
cerr << "Couldn't open " << filename << " for output.\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
unsigned int num_verts = verts.length();
|
||||
cerr << "writing " << num_verts << " vertices to " << filename << "\n";
|
||||
for (unsigned int i = 0; i < num_verts; i++) {
|
||||
file << i << ". " << verts[i] << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
output_normals() {
|
||||
MStatus status;
|
||||
MDagPath dagPath, *_dag_path;
|
||||
MObject component;
|
||||
|
||||
MItDag dag_iterator(MItDag::kDepthFirst, MFn::kTransform, &status);
|
||||
if (!status) {
|
||||
status.perror("MItDag constructor");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
while (!dag_iterator.isDone()) {
|
||||
status = dag_iterator.getPath(dagPath);
|
||||
if (!status) {
|
||||
status.perror("MItDag::getPath");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
_dag_path = new MDagPath(dagPath);
|
||||
|
||||
MFnDagNode dag_node(*_dag_path, &status);
|
||||
if (!status) {
|
||||
status.perror("MFnDagNode constructor");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
cerr << dag_node.name() << "\n";
|
||||
|
||||
if (_dag_path->hasFn(MFn::kMesh)) {
|
||||
unsigned int numShapes;
|
||||
status = _dag_path->numberOfShapesDirectlyBelow(numShapes);
|
||||
cerr << "----numShapes: " << numShapes << "\n";
|
||||
/*
|
||||
if (numShapes == 1) {
|
||||
_dag_path->extendToShape();
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
MItMeshPolygon faceIter(*_dag_path, component, &status);
|
||||
if( !status ) cerr << "Error at MItMeshPolygon" << endl;
|
||||
|
||||
MFnMesh meshFn(*_dag_path);
|
||||
|
||||
// Traverse the polygonal face
|
||||
for (; !faceIter.isDone();faceIter.next()) {
|
||||
int nVerts = faceIter.polygonVertexCount();
|
||||
|
||||
// Traverse the vertices to get their indexes and print out the normals
|
||||
for (int i = 0;i<nVerts;i++) {
|
||||
MVector normal;
|
||||
faceIter.getNormal( i, normal, MSpace::kWorld );
|
||||
cerr << "MItMeshPolygon::getNormal for the vertex [" << faceIter.vertexIndex(i)
|
||||
<< "] for face [" << faceIter.index() << "] is " << normal << endl;
|
||||
}
|
||||
}
|
||||
|
||||
dag_iterator.next();
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[]) {
|
||||
cerr << "Initializing Maya\n";
|
||||
MStatus status;
|
||||
status = MLibrary::initialize(argv[0]);
|
||||
if (!status) {
|
||||
status.perror("Could not initialize");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
cerr << "Using Maya library version " << MGlobal::mayaVersion() << "\n";
|
||||
|
||||
if (argc < 2) {
|
||||
cerr << "\nUsage:\n\nnormal_test.cxx file.mb mesh_name\n\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
MString filename = argv[1];
|
||||
|
||||
MFileIO::newFile(true);
|
||||
|
||||
cerr << "Reading " << filename << "\n";
|
||||
status = MFileIO::open(filename);
|
||||
if (!status) {
|
||||
status.perror(filename);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
output_normals();
|
||||
|
||||
return 0;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -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
|
||||
Loading…
Reference in New Issue