* Merged changes in the trunk up to revision 31789.
* Made a local fix for a compilation error with VC++ 2008 and CMake, reported to the bf-committers mailing list: http://lists.blender.org/pipermail/bf-committers/2010-September/028643.html
This commit is contained in:
@@ -300,7 +300,7 @@ IF(UNIX AND NOT APPLE)
|
|||||||
|
|
||||||
IF(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
IF(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||||
# BSD's dont use libdl.so
|
# BSD's dont use libdl.so
|
||||||
SET(LLIBS "${LLIBS} -ldl")
|
LIST(APPEND LLIBS -ldl)
|
||||||
|
|
||||||
# binreloc is linux only
|
# binreloc is linux only
|
||||||
SET(BINRELOC ${CMAKE_SOURCE_DIR}/extern/binreloc)
|
SET(BINRELOC ${CMAKE_SOURCE_DIR}/extern/binreloc)
|
||||||
@@ -308,9 +308,9 @@ IF(UNIX AND NOT APPLE)
|
|||||||
ENDIF(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
ENDIF(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||||
|
|
||||||
IF(WITH_OPENMP)
|
IF(WITH_OPENMP)
|
||||||
SET(LLIBS "${LLIBS} -lgomp")
|
LIST(APPEND LLIBS -lgomp)
|
||||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fopenmp")
|
LIST(APPEND CMAKE_C_FLAGS -fopenmp)
|
||||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp")
|
LIST(APPEND CMAKE_CXX_FLAGS -fopenmp)
|
||||||
ENDIF(WITH_OPENMP)
|
ENDIF(WITH_OPENMP)
|
||||||
|
|
||||||
|
|
||||||
@@ -415,11 +415,19 @@ IF(WIN32)
|
|||||||
SET(CMAKE_CXX_FLAGS "/D_CRT_NONSTDC_NO_DEPRECATE /D_CRT_SECURE_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /wd4800 /wd4244 /wd4305" CACHE STRING "MSVC MT C++ flags " FORCE)
|
SET(CMAKE_CXX_FLAGS "/D_CRT_NONSTDC_NO_DEPRECATE /D_CRT_SECURE_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /wd4800 /wd4244 /wd4305" CACHE STRING "MSVC MT C++ flags " FORCE)
|
||||||
SET(CMAKE_C_FLAGS "/D_CRT_NONSTDC_NO_DEPRECATE /D_CRT_SECURE_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /wd4800 /wd4244 /wd4305" CACHE STRING "MSVC MT C++ flags " FORCE)
|
SET(CMAKE_C_FLAGS "/D_CRT_NONSTDC_NO_DEPRECATE /D_CRT_SECURE_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /wd4800 /wd4244 /wd4305" CACHE STRING "MSVC MT C++ flags " FORCE)
|
||||||
|
|
||||||
SET(CMAKE_CXX_FLAGS_DEBUG "/D_DEBUG /Od /Gm /EHsc /RTC1 /MTd /W3 /nologo /ZI /J" CACHE STRING "MSVC MT flags " FORCE)
|
IF(CMAKE_CL_64)
|
||||||
|
SET(CMAKE_CXX_FLAGS_DEBUG "/D_DEBUG /Od /Gm /EHsc /RTC1 /MTd /W3 /nologo /Zi /J" CACHE STRING "MSVC MT flags " FORCE)
|
||||||
|
ELSE(CMAKE_CL_64)
|
||||||
|
SET(CMAKE_CXX_FLAGS_DEBUG "/D_DEBUG /Od /Gm /EHsc /RTC1 /MTd /W3 /nologo /ZI /J" CACHE STRING "MSVC MT flags " FORCE)
|
||||||
|
ENDIF(CMAKE_CL_64)
|
||||||
SET(CMAKE_CXX_FLAGS_RELEASE "/O2 /Ob2 /DNDEBUG /EHsc /MT /W3 /nologo /J" CACHE STRING "MSVC MT flags " FORCE)
|
SET(CMAKE_CXX_FLAGS_RELEASE "/O2 /Ob2 /DNDEBUG /EHsc /MT /W3 /nologo /J" CACHE STRING "MSVC MT flags " FORCE)
|
||||||
SET(CMAKE_CXX_FLAGS_MINSIZEREL "/O1 /Ob1 /DNDEBUG /EHsc /MT /W3 /nologo /J" CACHE STRING "MSVC MT flags " FORCE)
|
SET(CMAKE_CXX_FLAGS_MINSIZEREL "/O1 /Ob1 /DNDEBUG /EHsc /MT /W3 /nologo /J" CACHE STRING "MSVC MT flags " FORCE)
|
||||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "/O2 /Ob1 /DNDEBUG /EHsc /MT /W3 /nologo /Zi /J" CACHE STRING "MSVC MT flags " FORCE)
|
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "/O2 /Ob1 /DNDEBUG /EHsc /MT /W3 /nologo /Zi /J" CACHE STRING "MSVC MT flags " FORCE)
|
||||||
SET(CMAKE_C_FLAGS_DEBUG "/D_DEBUG /Od /Gm /EHsc /RTC1 /MTd /W3 /nologo /ZI /J" CACHE STRING "MSVC MT flags " FORCE)
|
IF(CMAKE_CL_64)
|
||||||
|
SET(CMAKE_C_FLAGS_DEBUG "/D_DEBUG /Od /Gm /EHsc /RTC1 /MTd /W3 /nologo /Zi /J" CACHE STRING "MSVC MT flags " FORCE)
|
||||||
|
ELSE(CMAKE_CL_64)
|
||||||
|
SET(CMAKE_C_FLAGS_DEBUG "/D_DEBUG /Od /Gm /EHsc /RTC1 /MTd /W3 /nologo /ZI /J" CACHE STRING "MSVC MT flags " FORCE)
|
||||||
|
ENDIF(CMAKE_CL_64)
|
||||||
SET(CMAKE_C_FLAGS_RELEASE "/O2 /Ob2 /DNDEBUG /EHsc /MT /W3 /nologo /J" CACHE STRING "MSVC MT flags " FORCE)
|
SET(CMAKE_C_FLAGS_RELEASE "/O2 /Ob2 /DNDEBUG /EHsc /MT /W3 /nologo /J" CACHE STRING "MSVC MT flags " FORCE)
|
||||||
SET(CMAKE_C_FLAGS_MINSIZEREL "/O1 /Ob1 /DNDEBUG /EHsc /MT /W3 /nologo /J" CACHE STRING "MSVC MT flags " FORCE)
|
SET(CMAKE_C_FLAGS_MINSIZEREL "/O1 /Ob1 /DNDEBUG /EHsc /MT /W3 /nologo /J" CACHE STRING "MSVC MT flags " FORCE)
|
||||||
SET(CMAKE_C_FLAGS_RELWITHDEBINFO "/O2 /Ob1 /DNDEBUG /EHsc /MT /W3 /nologo /Zi /J" CACHE STRING "MSVC MT flags " FORCE)
|
SET(CMAKE_C_FLAGS_RELWITHDEBINFO "/O2 /Ob1 /DNDEBUG /EHsc /MT /W3 /nologo /Zi /J" CACHE STRING "MSVC MT flags " FORCE)
|
||||||
|
|||||||
640
SConstruct
640
SConstruct
@@ -33,9 +33,9 @@ import platform as pltfrm
|
|||||||
|
|
||||||
# Need a better way to do this. Automagical maybe is not the best thing, maybe it is.
|
# Need a better way to do this. Automagical maybe is not the best thing, maybe it is.
|
||||||
if pltfrm.architecture()[0] == '64bit':
|
if pltfrm.architecture()[0] == '64bit':
|
||||||
bitness = 64
|
bitness = 64
|
||||||
else:
|
else:
|
||||||
bitness = 32
|
bitness = 32
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
@@ -79,15 +79,15 @@ B.binarykind = ['blender' , 'blenderplayer']
|
|||||||
# XX cheating for BF_FANCY, we check for BF_FANCY before args are validated
|
# XX cheating for BF_FANCY, we check for BF_FANCY before args are validated
|
||||||
use_color = ARGUMENTS.get('BF_FANCY', '1')
|
use_color = ARGUMENTS.get('BF_FANCY', '1')
|
||||||
if platform=='win32':
|
if platform=='win32':
|
||||||
use_color = None
|
use_color = None
|
||||||
|
|
||||||
if not use_color=='1':
|
if not use_color=='1':
|
||||||
B.bc.disable()
|
B.bc.disable()
|
||||||
|
|
||||||
#on defaut white Os X terminal, some colors are totally unlegible
|
#on defaut white Os X terminal, some colors are totally unlegible
|
||||||
if platform=='darwin':
|
if platform=='darwin':
|
||||||
B.bc.OKGREEN = '\033[34m'
|
B.bc.OKGREEN = '\033[34m'
|
||||||
B.bc.WARNING = '\033[36m'
|
B.bc.WARNING = '\033[36m'
|
||||||
|
|
||||||
# arguments
|
# arguments
|
||||||
print B.bc.HEADER+'Command-line arguments'+B.bc.ENDC
|
print B.bc.HEADER+'Command-line arguments'+B.bc.ENDC
|
||||||
@@ -110,100 +110,100 @@ quickie = B.arguments.get('BF_QUICK', None)
|
|||||||
quickdebug = B.arguments.get('BF_QUICKDEBUG', None)
|
quickdebug = B.arguments.get('BF_QUICKDEBUG', None)
|
||||||
|
|
||||||
if quickdebug:
|
if quickdebug:
|
||||||
B.quickdebug=string.split(quickdebug, ',')
|
B.quickdebug=string.split(quickdebug, ',')
|
||||||
else:
|
else:
|
||||||
B.quickdebug=[]
|
B.quickdebug=[]
|
||||||
|
|
||||||
if quickie:
|
if quickie:
|
||||||
B.quickie=string.split(quickie,',')
|
B.quickie=string.split(quickie,',')
|
||||||
else:
|
else:
|
||||||
B.quickie=[]
|
B.quickie=[]
|
||||||
|
|
||||||
toolset = B.arguments.get('BF_TOOLSET', None)
|
toolset = B.arguments.get('BF_TOOLSET', None)
|
||||||
if toolset:
|
if toolset:
|
||||||
print "Using " + toolset
|
print "Using " + toolset
|
||||||
if toolset=='mstoolkit':
|
if toolset=='mstoolkit':
|
||||||
env = BlenderEnvironment(ENV = os.environ)
|
env = BlenderEnvironment(ENV = os.environ)
|
||||||
env.Tool('mstoolkit', [toolpath])
|
env.Tool('mstoolkit', [toolpath])
|
||||||
else:
|
else:
|
||||||
env = BlenderEnvironment(tools=[toolset], ENV = os.environ)
|
env = BlenderEnvironment(tools=[toolset], ENV = os.environ)
|
||||||
# xxx commented out, as was supressing warnings under mingw..
|
# xxx commented out, as was supressing warnings under mingw..
|
||||||
#if env:
|
#if env:
|
||||||
# btools.SetupSpawn(env)
|
# btools.SetupSpawn(env)
|
||||||
else:
|
else:
|
||||||
if bitness==64 and platform=='win32':
|
if bitness==64 and platform=='win32':
|
||||||
env = BlenderEnvironment(ENV = os.environ, MSVS_ARCH='amd64')
|
env = BlenderEnvironment(ENV = os.environ, MSVS_ARCH='amd64')
|
||||||
else:
|
else:
|
||||||
env = BlenderEnvironment(ENV = os.environ)
|
env = BlenderEnvironment(ENV = os.environ)
|
||||||
|
|
||||||
if not env:
|
if not env:
|
||||||
print "Could not create a build environment"
|
print "Could not create a build environment"
|
||||||
Exit()
|
Exit()
|
||||||
|
|
||||||
|
|
||||||
cc = B.arguments.get('CC', None)
|
cc = B.arguments.get('CC', None)
|
||||||
cxx = B.arguments.get('CXX', None)
|
cxx = B.arguments.get('CXX', None)
|
||||||
if cc:
|
if cc:
|
||||||
env['CC'] = cc
|
env['CC'] = cc
|
||||||
if cxx:
|
if cxx:
|
||||||
env['CXX'] = cxx
|
env['CXX'] = cxx
|
||||||
|
|
||||||
if env['CC'] in ['cl', 'cl.exe'] and sys.platform=='win32':
|
if env['CC'] in ['cl', 'cl.exe'] and sys.platform=='win32':
|
||||||
if bitness == 64:
|
if bitness == 64:
|
||||||
platform = 'win64-vc'
|
platform = 'win64-vc'
|
||||||
else:
|
else:
|
||||||
platform = 'win32-vc'
|
platform = 'win32-vc'
|
||||||
elif env['CC'] in ['gcc'] and sys.platform=='win32':
|
elif env['CC'] in ['gcc'] and sys.platform=='win32':
|
||||||
platform = 'win32-mingw'
|
platform = 'win32-mingw'
|
||||||
|
|
||||||
env.SConscriptChdir(0)
|
env.SConscriptChdir(0)
|
||||||
|
|
||||||
crossbuild = B.arguments.get('BF_CROSS', None)
|
crossbuild = B.arguments.get('BF_CROSS', None)
|
||||||
if crossbuild and platform not in ('win32-vc', 'win64-vc'):
|
if crossbuild and platform not in ('win32-vc', 'win64-vc'):
|
||||||
platform = 'linuxcross'
|
platform = 'linuxcross'
|
||||||
|
|
||||||
env['OURPLATFORM'] = platform
|
env['OURPLATFORM'] = platform
|
||||||
|
|
||||||
configfile = os.path.join("build_files", "scons", "config", platform + "-config.py")
|
configfile = os.path.join("build_files", "scons", "config", platform + "-config.py")
|
||||||
|
|
||||||
if os.path.exists(configfile):
|
if os.path.exists(configfile):
|
||||||
print B.bc.OKGREEN + "Using config file: " + B.bc.ENDC + configfile
|
print B.bc.OKGREEN + "Using config file: " + B.bc.ENDC + configfile
|
||||||
else:
|
else:
|
||||||
print B.bc.FAIL + configfile + " doesn't exist" + B.bc.ENDC
|
print B.bc.FAIL + configfile + " doesn't exist" + B.bc.ENDC
|
||||||
|
|
||||||
if crossbuild and env['PLATFORM'] != 'win32':
|
if crossbuild and env['PLATFORM'] != 'win32':
|
||||||
print B.bc.HEADER+"Preparing for crossbuild"+B.bc.ENDC
|
print B.bc.HEADER+"Preparing for crossbuild"+B.bc.ENDC
|
||||||
env.Tool('crossmingw', [toolpath])
|
env.Tool('crossmingw', [toolpath])
|
||||||
# todo: determine proper libs/includes etc.
|
# todo: determine proper libs/includes etc.
|
||||||
# Needed for gui programs, console programs should do without it
|
# Needed for gui programs, console programs should do without it
|
||||||
|
|
||||||
# Now we don't need this option to have console window
|
# Now we don't need this option to have console window
|
||||||
# env.Append(LINKFLAGS=['-mwindows'])
|
# env.Append(LINKFLAGS=['-mwindows'])
|
||||||
|
|
||||||
userconfig = B.arguments.get('BF_CONFIG', 'user-config.py')
|
userconfig = B.arguments.get('BF_CONFIG', 'user-config.py')
|
||||||
# first read platform config. B.arguments will override
|
# first read platform config. B.arguments will override
|
||||||
optfiles = [configfile]
|
optfiles = [configfile]
|
||||||
if os.path.exists(userconfig):
|
if os.path.exists(userconfig):
|
||||||
print B.bc.OKGREEN + "Using user-config file: " + B.bc.ENDC + userconfig
|
print B.bc.OKGREEN + "Using user-config file: " + B.bc.ENDC + userconfig
|
||||||
optfiles += [userconfig]
|
optfiles += [userconfig]
|
||||||
else:
|
else:
|
||||||
print B.bc.WARNING + userconfig + " not found, no user overrides" + B.bc.ENDC
|
print B.bc.WARNING + userconfig + " not found, no user overrides" + B.bc.ENDC
|
||||||
|
|
||||||
opts = btools.read_opts(env, optfiles, B.arguments)
|
opts = btools.read_opts(env, optfiles, B.arguments)
|
||||||
opts.Update(env)
|
opts.Update(env)
|
||||||
|
|
||||||
if not env['BF_FANCY']:
|
if not env['BF_FANCY']:
|
||||||
B.bc.disable()
|
B.bc.disable()
|
||||||
|
|
||||||
|
|
||||||
# remove install dir so old and new files are not mixed.
|
# remove install dir so old and new files are not mixed.
|
||||||
# NOTE: only do the scripts directory for now, otherwise is too disruptive for developers
|
# NOTE: only do the scripts directory for now, otherwise is too disruptive for developers
|
||||||
# TODO: perhaps we need an option (off by default) to not do this altogether...
|
# TODO: perhaps we need an option (off by default) to not do this altogether...
|
||||||
if not env['WITHOUT_BF_INSTALL'] and not env['WITHOUT_BF_OVERWRITE_INSTALL']:
|
if not env['WITHOUT_BF_INSTALL'] and not env['WITHOUT_BF_OVERWRITE_INSTALL']:
|
||||||
scriptsDir = os.path.join(env['BF_INSTALLDIR'], VERSION, 'scripts')
|
scriptsDir = os.path.join(env['BF_INSTALLDIR'], VERSION, 'scripts')
|
||||||
if os.path.isdir(scriptsDir):
|
if os.path.isdir(scriptsDir):
|
||||||
print B.bc.OKGREEN + "Clearing installation directory%s: %s" % (B.bc.ENDC, os.path.abspath(scriptsDir))
|
print B.bc.OKGREEN + "Clearing installation directory%s: %s" % (B.bc.ENDC, os.path.abspath(scriptsDir))
|
||||||
shutil.rmtree(scriptsDir)
|
shutil.rmtree(scriptsDir)
|
||||||
|
|
||||||
|
|
||||||
SetOption('num_jobs', int(env['BF_NUMJOBS']))
|
SetOption('num_jobs', int(env['BF_NUMJOBS']))
|
||||||
@@ -211,158 +211,158 @@ print B.bc.OKGREEN + "Build with parallel jobs%s: %s" % (B.bc.ENDC, GetOption('n
|
|||||||
print B.bc.OKGREEN + "Build with debug symbols%s: %s" % (B.bc.ENDC, env['BF_DEBUG'])
|
print B.bc.OKGREEN + "Build with debug symbols%s: %s" % (B.bc.ENDC, env['BF_DEBUG'])
|
||||||
|
|
||||||
if 'blenderlite' in B.targets:
|
if 'blenderlite' in B.targets:
|
||||||
target_env_defs = {}
|
target_env_defs = {}
|
||||||
target_env_defs['WITH_BF_GAMEENGINE'] = False
|
target_env_defs['WITH_BF_GAMEENGINE'] = False
|
||||||
target_env_defs['WITH_BF_OPENAL'] = False
|
target_env_defs['WITH_BF_OPENAL'] = False
|
||||||
target_env_defs['WITH_BF_OPENEXR'] = False
|
target_env_defs['WITH_BF_OPENEXR'] = False
|
||||||
target_env_defs['WITH_BF_OPENMP'] = False
|
target_env_defs['WITH_BF_OPENMP'] = False
|
||||||
target_env_defs['WITH_BF_ICONV'] = False
|
target_env_defs['WITH_BF_ICONV'] = False
|
||||||
target_env_defs['WITH_BF_INTERNATIONAL'] = False
|
target_env_defs['WITH_BF_INTERNATIONAL'] = False
|
||||||
target_env_defs['WITH_BF_OPENJPEG'] = False
|
target_env_defs['WITH_BF_OPENJPEG'] = False
|
||||||
target_env_defs['WITH_BF_FFMPEG'] = False
|
target_env_defs['WITH_BF_FFMPEG'] = False
|
||||||
target_env_defs['WITH_BF_QUICKTIME'] = False
|
target_env_defs['WITH_BF_QUICKTIME'] = False
|
||||||
target_env_defs['WITH_BF_REDCODE'] = False
|
target_env_defs['WITH_BF_REDCODE'] = False
|
||||||
target_env_defs['WITH_BF_DDS'] = False
|
target_env_defs['WITH_BF_DDS'] = False
|
||||||
target_env_defs['WITH_BF_CINEON'] = False
|
target_env_defs['WITH_BF_CINEON'] = False
|
||||||
target_env_defs['WITH_BF_HDR'] = False
|
target_env_defs['WITH_BF_HDR'] = False
|
||||||
target_env_defs['WITH_BF_ZLIB'] = False
|
target_env_defs['WITH_BF_ZLIB'] = False
|
||||||
target_env_defs['WITH_BF_SDL'] = False
|
target_env_defs['WITH_BF_SDL'] = False
|
||||||
target_env_defs['WITH_BF_JPEG'] = False
|
target_env_defs['WITH_BF_JPEG'] = False
|
||||||
target_env_defs['WITH_BF_PNG'] = False
|
target_env_defs['WITH_BF_PNG'] = False
|
||||||
target_env_defs['WITH_BF_BULLET'] = False
|
target_env_defs['WITH_BF_BULLET'] = False
|
||||||
target_env_defs['WITH_BF_BINRELOC'] = False
|
target_env_defs['WITH_BF_BINRELOC'] = False
|
||||||
target_env_defs['BF_BUILDINFO'] = False
|
target_env_defs['BF_BUILDINFO'] = False
|
||||||
target_env_defs['BF_NO_ELBEEM'] = True
|
target_env_defs['BF_NO_ELBEEM'] = True
|
||||||
target_env_defs['WITH_BF_PYTHON'] = False
|
target_env_defs['WITH_BF_PYTHON'] = False
|
||||||
|
|
||||||
# Merge blenderlite, let command line to override
|
# Merge blenderlite, let command line to override
|
||||||
for k,v in target_env_defs.iteritems():
|
for k,v in target_env_defs.iteritems():
|
||||||
if k not in B.arguments:
|
if k not in B.arguments:
|
||||||
env[k] = v
|
env[k] = v
|
||||||
|
|
||||||
|
|
||||||
if env['WITH_BF_OPENMP'] == 1:
|
if env['WITH_BF_OPENMP'] == 1:
|
||||||
if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
|
if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
|
||||||
env['CCFLAGS'].append('/openmp')
|
env['CCFLAGS'].append('/openmp')
|
||||||
env['CPPFLAGS'].append('/openmp')
|
env['CPPFLAGS'].append('/openmp')
|
||||||
env['CXXFLAGS'].append('/openmp')
|
env['CXXFLAGS'].append('/openmp')
|
||||||
else:
|
else:
|
||||||
if env['CC'].endswith('icc'): # to be able to handle CC=/opt/bla/icc case
|
if env['CC'].endswith('icc'): # to be able to handle CC=/opt/bla/icc case
|
||||||
env.Append(LINKFLAGS=['-openmp', '-static-intel'])
|
env.Append(LINKFLAGS=['-openmp', '-static-intel'])
|
||||||
env['CCFLAGS'].append('-openmp')
|
env['CCFLAGS'].append('-openmp')
|
||||||
env['CPPFLAGS'].append('-openmp')
|
env['CPPFLAGS'].append('-openmp')
|
||||||
env['CXXFLAGS'].append('-openmp')
|
env['CXXFLAGS'].append('-openmp')
|
||||||
else:
|
else:
|
||||||
env.Append(CCFLAGS=['-fopenmp'])
|
env.Append(CCFLAGS=['-fopenmp'])
|
||||||
env.Append(CPPFLAGS=['-fopenmp'])
|
env.Append(CPPFLAGS=['-fopenmp'])
|
||||||
env.Append(CXXFLAGS=['-fopenmp'])
|
env.Append(CXXFLAGS=['-fopenmp'])
|
||||||
|
|
||||||
if env['WITH_GHOST_COCOA'] == True:
|
if env['WITH_GHOST_COCOA'] == True:
|
||||||
env.Append(CFLAGS=['-DGHOST_COCOA'])
|
env.Append(CFLAGS=['-DGHOST_COCOA'])
|
||||||
env.Append(CXXFLAGS=['-DGHOST_COCOA'])
|
env.Append(CXXFLAGS=['-DGHOST_COCOA'])
|
||||||
env.Append(CPPFLAGS=['-DGHOST_COCOA'])
|
env.Append(CPPFLAGS=['-DGHOST_COCOA'])
|
||||||
|
|
||||||
if env['USE_QTKIT'] == True:
|
if env['USE_QTKIT'] == True:
|
||||||
env.Append(CFLAGS=['-DUSE_QTKIT'])
|
env.Append(CFLAGS=['-DUSE_QTKIT'])
|
||||||
env.Append(CXXFLAGS=['-DUSE_QTKIT'])
|
env.Append(CXXFLAGS=['-DUSE_QTKIT'])
|
||||||
env.Append(CPPFLAGS=['-DUSE_QTKIT'])
|
env.Append(CPPFLAGS=['-DUSE_QTKIT'])
|
||||||
|
|
||||||
#check for additional debug libnames
|
#check for additional debug libnames
|
||||||
|
|
||||||
if env.has_key('BF_DEBUG_LIBS'):
|
if env.has_key('BF_DEBUG_LIBS'):
|
||||||
B.quickdebug += env['BF_DEBUG_LIBS']
|
B.quickdebug += env['BF_DEBUG_LIBS']
|
||||||
|
|
||||||
printdebug = B.arguments.get('BF_LISTDEBUG', 0)
|
printdebug = B.arguments.get('BF_LISTDEBUG', 0)
|
||||||
|
|
||||||
if len(B.quickdebug) > 0 and printdebug != 0:
|
if len(B.quickdebug) > 0 and printdebug != 0:
|
||||||
print B.bc.OKGREEN + "Buildings these libs with debug symbols:" + B.bc.ENDC
|
print B.bc.OKGREEN + "Buildings these libs with debug symbols:" + B.bc.ENDC
|
||||||
for l in B.quickdebug:
|
for l in B.quickdebug:
|
||||||
print "\t" + l
|
print "\t" + l
|
||||||
|
|
||||||
# remove stdc++ from LLIBS if we are building a statc linked CXXFLAGS
|
# remove stdc++ from LLIBS if we are building a statc linked CXXFLAGS
|
||||||
if env['WITH_BF_STATICCXX']:
|
if env['WITH_BF_STATICCXX']:
|
||||||
if 'stdc++' in env['LLIBS']:
|
if 'stdc++' in env['LLIBS']:
|
||||||
env['LLIBS'].remove('stdc++')
|
env['LLIBS'].remove('stdc++')
|
||||||
else:
|
else:
|
||||||
print '\tcould not remove stdc++ library from LLIBS, WITH_BF_STATICCXX may not work for your platform'
|
print '\tcould not remove stdc++ library from LLIBS, WITH_BF_STATICCXX may not work for your platform'
|
||||||
|
|
||||||
# check target for blenderplayer. Set WITH_BF_PLAYER if found on cmdline
|
# check target for blenderplayer. Set WITH_BF_PLAYER if found on cmdline
|
||||||
if 'blenderplayer' in B.targets:
|
if 'blenderplayer' in B.targets:
|
||||||
env['WITH_BF_PLAYER'] = True
|
env['WITH_BF_PLAYER'] = True
|
||||||
|
|
||||||
if 'blendernogame' in B.targets:
|
if 'blendernogame' in B.targets:
|
||||||
env['WITH_BF_GAMEENGINE'] = False
|
env['WITH_BF_GAMEENGINE'] = False
|
||||||
|
|
||||||
# disable elbeem (fluidsim) compilation?
|
# disable elbeem (fluidsim) compilation?
|
||||||
if env['BF_NO_ELBEEM'] == 1:
|
if env['BF_NO_ELBEEM'] == 1:
|
||||||
env['CPPFLAGS'].append('-DDISABLE_ELBEEM')
|
env['CPPFLAGS'].append('-DDISABLE_ELBEEM')
|
||||||
env['CXXFLAGS'].append('-DDISABLE_ELBEEM')
|
env['CXXFLAGS'].append('-DDISABLE_ELBEEM')
|
||||||
env['CCFLAGS'].append('-DDISABLE_ELBEEM')
|
env['CCFLAGS'].append('-DDISABLE_ELBEEM')
|
||||||
|
|
||||||
if env['WITH_BF_SDL'] == False and env['OURPLATFORM'] in ('win32-vc', 'win32-ming', 'win64-vc'):
|
if env['WITH_BF_SDL'] == False and env['OURPLATFORM'] in ('win32-vc', 'win32-ming', 'win64-vc'):
|
||||||
env['PLATFORM_LINKFLAGS'].remove('/ENTRY:mainCRTStartup')
|
env['PLATFORM_LINKFLAGS'].remove('/ENTRY:mainCRTStartup')
|
||||||
env['PLATFORM_LINKFLAGS'].append('/ENTRY:main')
|
env['PLATFORM_LINKFLAGS'].append('/ENTRY:main')
|
||||||
|
|
||||||
# lastly we check for root_build_dir ( we should not do before, otherwise we might do wrong builddir
|
# lastly we check for root_build_dir ( we should not do before, otherwise we might do wrong builddir
|
||||||
B.root_build_dir = env['BF_BUILDDIR']
|
B.root_build_dir = env['BF_BUILDDIR']
|
||||||
B.doc_build_dir = os.path.join(env['BF_INSTALLDIR'], 'doc')
|
B.doc_build_dir = os.path.join(env['BF_INSTALLDIR'], 'doc')
|
||||||
if not B.root_build_dir[-1]==os.sep:
|
if not B.root_build_dir[-1]==os.sep:
|
||||||
B.root_build_dir += os.sep
|
B.root_build_dir += os.sep
|
||||||
if not B.doc_build_dir[-1]==os.sep:
|
if not B.doc_build_dir[-1]==os.sep:
|
||||||
B.doc_build_dir += os.sep
|
B.doc_build_dir += os.sep
|
||||||
|
|
||||||
# We do a shortcut for clean when no quicklist is given: just delete
|
# We do a shortcut for clean when no quicklist is given: just delete
|
||||||
# builddir without reading in SConscripts
|
# builddir without reading in SConscripts
|
||||||
do_clean = None
|
do_clean = None
|
||||||
if 'clean' in B.targets:
|
if 'clean' in B.targets:
|
||||||
do_clean = True
|
do_clean = True
|
||||||
|
|
||||||
if not quickie and do_clean:
|
if not quickie and do_clean:
|
||||||
if os.path.exists(B.doc_build_dir):
|
if os.path.exists(B.doc_build_dir):
|
||||||
print B.bc.HEADER+'Cleaning doc dir...'+B.bc.ENDC
|
print B.bc.HEADER+'Cleaning doc dir...'+B.bc.ENDC
|
||||||
dirs = os.listdir(B.doc_build_dir)
|
dirs = os.listdir(B.doc_build_dir)
|
||||||
for entry in dirs:
|
for entry in dirs:
|
||||||
if os.path.isdir(B.doc_build_dir + entry) == 1:
|
if os.path.isdir(B.doc_build_dir + entry) == 1:
|
||||||
print "clean dir %s"%(B.doc_build_dir+entry)
|
print "clean dir %s"%(B.doc_build_dir+entry)
|
||||||
shutil.rmtree(B.doc_build_dir+entry)
|
shutil.rmtree(B.doc_build_dir+entry)
|
||||||
else: # remove file
|
else: # remove file
|
||||||
print "remove file %s"%(B.doc_build_dir+entry)
|
print "remove file %s"%(B.doc_build_dir+entry)
|
||||||
os.remove(B.root_build_dir+entry)
|
os.remove(B.root_build_dir+entry)
|
||||||
if os.path.exists(B.root_build_dir):
|
if os.path.exists(B.root_build_dir):
|
||||||
print B.bc.HEADER+'Cleaning build dir...'+B.bc.ENDC
|
print B.bc.HEADER+'Cleaning build dir...'+B.bc.ENDC
|
||||||
dirs = os.listdir(B.root_build_dir)
|
dirs = os.listdir(B.root_build_dir)
|
||||||
for entry in dirs:
|
for entry in dirs:
|
||||||
if os.path.isdir(B.root_build_dir + entry) == 1:
|
if os.path.isdir(B.root_build_dir + entry) == 1:
|
||||||
print "clean dir %s"%(B.root_build_dir+entry)
|
print "clean dir %s"%(B.root_build_dir+entry)
|
||||||
shutil.rmtree(B.root_build_dir+entry)
|
shutil.rmtree(B.root_build_dir+entry)
|
||||||
else: # remove file
|
else: # remove file
|
||||||
print "remove file %s"%(B.root_build_dir+entry)
|
print "remove file %s"%(B.root_build_dir+entry)
|
||||||
os.remove(B.root_build_dir+entry)
|
os.remove(B.root_build_dir+entry)
|
||||||
for confile in ['extern/ffmpeg/config.mak', 'extern/x264/config.mak',
|
for confile in ['extern/ffmpeg/config.mak', 'extern/x264/config.mak',
|
||||||
'extern/xvidcore/build/generic/platform.inc', 'extern/ffmpeg/include']:
|
'extern/xvidcore/build/generic/platform.inc', 'extern/ffmpeg/include']:
|
||||||
if os.path.exists(confile):
|
if os.path.exists(confile):
|
||||||
print "clean file %s"%confile
|
print "clean file %s"%confile
|
||||||
if os.path.isdir(confile):
|
if os.path.isdir(confile):
|
||||||
for root, dirs, files in os.walk(confile):
|
for root, dirs, files in os.walk(confile):
|
||||||
for name in files:
|
for name in files:
|
||||||
os.remove(os.path.join(root, name))
|
os.remove(os.path.join(root, name))
|
||||||
else:
|
else:
|
||||||
os.remove(confile)
|
os.remove(confile)
|
||||||
print B.bc.OKGREEN+'...done'+B.bc.ENDC
|
print B.bc.OKGREEN+'...done'+B.bc.ENDC
|
||||||
else:
|
else:
|
||||||
print B.bc.HEADER+'Already Clean, nothing to do.'+B.bc.ENDC
|
print B.bc.HEADER+'Already Clean, nothing to do.'+B.bc.ENDC
|
||||||
Exit()
|
Exit()
|
||||||
|
|
||||||
if not os.path.isdir ( B.root_build_dir):
|
if not os.path.isdir ( B.root_build_dir):
|
||||||
os.makedirs ( B.root_build_dir )
|
os.makedirs ( B.root_build_dir )
|
||||||
os.makedirs ( B.root_build_dir + 'source' )
|
os.makedirs ( B.root_build_dir + 'source' )
|
||||||
os.makedirs ( B.root_build_dir + 'intern' )
|
os.makedirs ( B.root_build_dir + 'intern' )
|
||||||
os.makedirs ( B.root_build_dir + 'extern' )
|
os.makedirs ( B.root_build_dir + 'extern' )
|
||||||
os.makedirs ( B.root_build_dir + 'lib' )
|
os.makedirs ( B.root_build_dir + 'lib' )
|
||||||
os.makedirs ( B.root_build_dir + 'bin' )
|
os.makedirs ( B.root_build_dir + 'bin' )
|
||||||
# # Docs not working with epy anymore
|
# # Docs not working with epy anymore
|
||||||
# if not os.path.isdir(B.doc_build_dir) and env['WITH_BF_DOCS']:
|
# if not os.path.isdir(B.doc_build_dir) and env['WITH_BF_DOCS']:
|
||||||
# os.makedirs ( B.doc_build_dir )
|
# os.makedirs ( B.doc_build_dir )
|
||||||
|
|
||||||
Help(opts.GenerateHelpText(env))
|
Help(opts.GenerateHelpText(env))
|
||||||
|
|
||||||
@@ -370,10 +370,10 @@ Help(opts.GenerateHelpText(env))
|
|||||||
# commands, do 'scons BF_QUIET=0'
|
# commands, do 'scons BF_QUIET=0'
|
||||||
bf_quietoutput = B.arguments.get('BF_QUIET', '1')
|
bf_quietoutput = B.arguments.get('BF_QUIET', '1')
|
||||||
if env['BF_QUIET']:
|
if env['BF_QUIET']:
|
||||||
B.set_quiet_output(env)
|
B.set_quiet_output(env)
|
||||||
else:
|
else:
|
||||||
if toolset=='msvc':
|
if toolset=='msvc':
|
||||||
B.msvc_hack(env)
|
B.msvc_hack(env)
|
||||||
|
|
||||||
print B.bc.HEADER+'Building in: ' + B.bc.ENDC + os.path.abspath(B.root_build_dir)
|
print B.bc.HEADER+'Building in: ' + B.bc.ENDC + os.path.abspath(B.root_build_dir)
|
||||||
env.SConsignFile(B.root_build_dir+'scons-signatures')
|
env.SConsignFile(B.root_build_dir+'scons-signatures')
|
||||||
@@ -395,23 +395,23 @@ SConscript(B.root_build_dir+'/source/SConscript')
|
|||||||
# libraries to give as objects to linking phase
|
# libraries to give as objects to linking phase
|
||||||
mainlist = []
|
mainlist = []
|
||||||
for tp in B.possible_types:
|
for tp in B.possible_types:
|
||||||
if not tp == 'player':
|
if not tp == 'player':
|
||||||
mainlist += B.create_blender_liblist(env, tp)
|
mainlist += B.create_blender_liblist(env, tp)
|
||||||
|
|
||||||
if B.arguments.get('BF_PRIORITYLIST', '0')=='1':
|
if B.arguments.get('BF_PRIORITYLIST', '0')=='1':
|
||||||
B.propose_priorities()
|
B.propose_priorities()
|
||||||
|
|
||||||
dobj = B.buildinfo(env, "dynamic") + B.resources
|
dobj = B.buildinfo(env, "dynamic") + B.resources
|
||||||
thestatlibs, thelibincs = B.setup_staticlibs(env)
|
thestatlibs, thelibincs = B.setup_staticlibs(env)
|
||||||
thesyslibs = B.setup_syslibs(env)
|
thesyslibs = B.setup_syslibs(env)
|
||||||
|
|
||||||
if 'blender' in B.targets or not env['WITH_BF_NOBLENDER']:
|
if 'blender' in B.targets or not env['WITH_BF_NOBLENDER']:
|
||||||
env.BlenderProg(B.root_build_dir, "blender", mainlist + thestatlibs + dobj, thesyslibs, [B.root_build_dir+'/lib'] + thelibincs, 'blender')
|
env.BlenderProg(B.root_build_dir, "blender", mainlist + thestatlibs + dobj, thesyslibs, [B.root_build_dir+'/lib'] + thelibincs, 'blender')
|
||||||
if env['WITH_BF_PLAYER']:
|
if env['WITH_BF_PLAYER']:
|
||||||
playerlist = B.create_blender_liblist(env, 'player')
|
playerlist = B.create_blender_liblist(env, 'player')
|
||||||
playerlist += B.create_blender_liblist(env, 'intern')
|
playerlist += B.create_blender_liblist(env, 'intern')
|
||||||
playerlist += B.create_blender_liblist(env, 'extern')
|
playerlist += B.create_blender_liblist(env, 'extern')
|
||||||
env.BlenderProg(B.root_build_dir, "blenderplayer", playerlist, thestatlibs + dobj + thesyslibs, [B.root_build_dir+'/lib'] + thelibincs, 'blenderplayer')
|
env.BlenderProg(B.root_build_dir, "blenderplayer", playerlist, thestatlibs + dobj + thesyslibs, [B.root_build_dir+'/lib'] + thelibincs, 'blenderplayer')
|
||||||
|
|
||||||
##### Now define some targets
|
##### Now define some targets
|
||||||
|
|
||||||
@@ -421,19 +421,19 @@ if env['WITH_BF_PLAYER']:
|
|||||||
#-- binaries
|
#-- binaries
|
||||||
blenderinstall = []
|
blenderinstall = []
|
||||||
if env['OURPLATFORM']=='darwin':
|
if env['OURPLATFORM']=='darwin':
|
||||||
for prg in B.program_list:
|
for prg in B.program_list:
|
||||||
bundle = '%s.app' % prg[0]
|
bundle = '%s.app' % prg[0]
|
||||||
bundledir = os.path.dirname(bundle)
|
bundledir = os.path.dirname(bundle)
|
||||||
for dp, dn, df in os.walk(bundle):
|
for dp, dn, df in os.walk(bundle):
|
||||||
if '.svn' in dn:
|
if '.svn' in dn:
|
||||||
dn.remove('.svn')
|
dn.remove('.svn')
|
||||||
if '_svn' in dn:
|
if '_svn' in dn:
|
||||||
dn.remove('_svn')
|
dn.remove('_svn')
|
||||||
dir=env['BF_INSTALLDIR']+dp[len(bundledir):]
|
dir=env['BF_INSTALLDIR']+dp[len(bundledir):]
|
||||||
source=[dp+os.sep+f for f in df]
|
source=[dp+os.sep+f for f in df]
|
||||||
blenderinstall.append(env.Install(dir=dir,source=source))
|
blenderinstall.append(env.Install(dir=dir,source=source))
|
||||||
else:
|
else:
|
||||||
blenderinstall = env.Install(dir=env['BF_INSTALLDIR'], source=B.program_list)
|
blenderinstall = env.Install(dir=env['BF_INSTALLDIR'], source=B.program_list)
|
||||||
|
|
||||||
#-- local path = config files in install dir: installdir\VERSION
|
#-- local path = config files in install dir: installdir\VERSION
|
||||||
#- dont do config and scripts for darwin, it is already in the bundle
|
#- dont do config and scripts for darwin, it is already in the bundle
|
||||||
@@ -444,98 +444,98 @@ dottargetlist = []
|
|||||||
scriptinstall = []
|
scriptinstall = []
|
||||||
|
|
||||||
if env['OURPLATFORM']!='darwin':
|
if env['OURPLATFORM']!='darwin':
|
||||||
for dp, dn, df in os.walk('bin/.blender'):
|
for dp, dn, df in os.walk('bin/.blender'):
|
||||||
if '.svn' in dn:
|
if '.svn' in dn:
|
||||||
dn.remove('.svn')
|
dn.remove('.svn')
|
||||||
if '_svn' in dn:
|
if '_svn' in dn:
|
||||||
dn.remove('_svn')
|
dn.remove('_svn')
|
||||||
|
|
||||||
for f in df:
|
for f in df:
|
||||||
if not env['WITH_BF_INTERNATIONAL']:
|
if not env['WITH_BF_INTERNATIONAL']:
|
||||||
if 'locale' in dp:
|
if 'locale' in dp:
|
||||||
continue
|
continue
|
||||||
if f == '.Blanguages':
|
if f == '.Blanguages':
|
||||||
continue
|
continue
|
||||||
if not env['WITH_BF_FREETYPE']:
|
if not env['WITH_BF_FREETYPE']:
|
||||||
if f.endswith('.ttf'):
|
if f.endswith('.ttf'):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if 'locale' in dp:
|
if 'locale' in dp:
|
||||||
datafileslist.append(os.path.join(dp,f))
|
datafileslist.append(os.path.join(dp,f))
|
||||||
dir= os.path.join(*([env['BF_INSTALLDIR']] + [VERSION] + ['datafiles'] + dp.split(os.sep)[1:])) # skip bin
|
dir= os.path.join(*([env['BF_INSTALLDIR']] + [VERSION] + ['datafiles'] + dp.split(os.sep)[1:])) # skip bin
|
||||||
datafilestargetlist.append(dir + os.sep + f)
|
datafilestargetlist.append(dir + os.sep + f)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
dotblendlist.append(os.path.join(dp, f))
|
dotblendlist.append(os.path.join(dp, f))
|
||||||
dir= os.path.join(*([env['BF_INSTALLDIR']] + [VERSION] + ['config'] + dp.split(os.sep)[1:])) # skip bin
|
dir= os.path.join(*([env['BF_INSTALLDIR']] + [VERSION] + ['config'] + dp.split(os.sep)[1:])) # skip bin
|
||||||
dottargetlist.append(dir + os.sep + f)
|
dottargetlist.append(dir + os.sep + f)
|
||||||
|
|
||||||
dotblenderinstall = []
|
dotblenderinstall = []
|
||||||
for targetdir,srcfile in zip(dottargetlist, dotblendlist):
|
for targetdir,srcfile in zip(dottargetlist, dotblendlist):
|
||||||
td, tf = os.path.split(targetdir)
|
td, tf = os.path.split(targetdir)
|
||||||
dotblenderinstall.append(env.Install(dir=td, source=srcfile))
|
dotblenderinstall.append(env.Install(dir=td, source=srcfile))
|
||||||
for targetdir,srcfile in zip(datafilestargetlist, datafileslist):
|
for targetdir,srcfile in zip(datafilestargetlist, datafileslist):
|
||||||
td, tf = os.path.split(targetdir)
|
td, tf = os.path.split(targetdir)
|
||||||
dotblenderinstall.append(env.Install(dir=td, source=srcfile))
|
dotblenderinstall.append(env.Install(dir=td, source=srcfile))
|
||||||
|
|
||||||
if env['WITH_BF_PYTHON']:
|
if env['WITH_BF_PYTHON']:
|
||||||
#-- local/VERSION/scripts
|
#-- local/VERSION/scripts
|
||||||
scriptpaths=['release/scripts']
|
scriptpaths=['release/scripts']
|
||||||
for scriptpath in scriptpaths:
|
for scriptpath in scriptpaths:
|
||||||
for dp, dn, df in os.walk(scriptpath):
|
for dp, dn, df in os.walk(scriptpath):
|
||||||
if '.svn' in dn:
|
if '.svn' in dn:
|
||||||
dn.remove('.svn')
|
dn.remove('.svn')
|
||||||
if '_svn' in dn:
|
if '_svn' in dn:
|
||||||
dn.remove('_svn')
|
dn.remove('_svn')
|
||||||
|
|
||||||
dir = os.path.join(env['BF_INSTALLDIR'], VERSION)
|
dir = os.path.join(env['BF_INSTALLDIR'], VERSION)
|
||||||
dir += os.sep + os.path.basename(scriptpath) + dp[len(scriptpath):]
|
dir += os.sep + os.path.basename(scriptpath) + dp[len(scriptpath):]
|
||||||
|
|
||||||
source=[os.path.join(dp, f) for f in df if f[-3:]!='pyc']
|
source=[os.path.join(dp, f) for f in df if f[-3:]!='pyc']
|
||||||
scriptinstall.append(env.Install(dir=dir,source=source))
|
scriptinstall.append(env.Install(dir=dir,source=source))
|
||||||
|
|
||||||
#-- icons
|
#-- icons
|
||||||
if env['OURPLATFORM']=='linux2':
|
if env['OURPLATFORM']=='linux2':
|
||||||
iconlist = []
|
iconlist = []
|
||||||
icontargetlist = []
|
icontargetlist = []
|
||||||
|
|
||||||
for tp, tn, tf in os.walk('release/freedesktop/icons'):
|
for tp, tn, tf in os.walk('release/freedesktop/icons'):
|
||||||
if '.svn' in tn:
|
if '.svn' in tn:
|
||||||
tn.remove('.svn')
|
tn.remove('.svn')
|
||||||
if '_svn' in tn:
|
if '_svn' in tn:
|
||||||
tn.remove('_svn')
|
tn.remove('_svn')
|
||||||
for f in tf:
|
for f in tf:
|
||||||
iconlist.append(os.path.join(tp, f))
|
iconlist.append(os.path.join(tp, f))
|
||||||
icontargetlist.append( os.path.join(*([env['BF_INSTALLDIR']] + tp.split(os.sep)[2:] + [f])) )
|
icontargetlist.append( os.path.join(*([env['BF_INSTALLDIR']] + tp.split(os.sep)[2:] + [f])) )
|
||||||
|
|
||||||
iconinstall = []
|
iconinstall = []
|
||||||
for targetdir,srcfile in zip(icontargetlist, iconlist):
|
for targetdir,srcfile in zip(icontargetlist, iconlist):
|
||||||
td, tf = os.path.split(targetdir)
|
td, tf = os.path.split(targetdir)
|
||||||
iconinstall.append(env.Install(dir=td, source=srcfile))
|
iconinstall.append(env.Install(dir=td, source=srcfile))
|
||||||
|
|
||||||
# dlls for linuxcross
|
# dlls for linuxcross
|
||||||
# TODO - add more libs, for now this lets blenderlite run
|
# TODO - add more libs, for now this lets blenderlite run
|
||||||
if env['OURPLATFORM']=='linuxcross':
|
if env['OURPLATFORM']=='linuxcross':
|
||||||
dir=env['BF_INSTALLDIR']
|
dir=env['BF_INSTALLDIR']
|
||||||
source = []
|
source = []
|
||||||
|
|
||||||
if env['WITH_BF_OPENMP']:
|
if env['WITH_BF_OPENMP']:
|
||||||
source += ['../lib/windows/pthreads/lib/pthreadGC2.dll']
|
source += ['../lib/windows/pthreads/lib/pthreadGC2.dll']
|
||||||
|
|
||||||
scriptinstall.append(env.Install(dir=dir, source=source))
|
scriptinstall.append(env.Install(dir=dir, source=source))
|
||||||
|
|
||||||
#-- plugins
|
#-- plugins
|
||||||
pluglist = []
|
pluglist = []
|
||||||
plugtargetlist = []
|
plugtargetlist = []
|
||||||
for tp, tn, tf in os.walk('release/plugins'):
|
for tp, tn, tf in os.walk('release/plugins'):
|
||||||
if '.svn' in tn:
|
if '.svn' in tn:
|
||||||
tn.remove('.svn')
|
tn.remove('.svn')
|
||||||
if '_svn' in tn:
|
if '_svn' in tn:
|
||||||
tn.remove('_svn')
|
tn.remove('_svn')
|
||||||
df = tp[8:] # remove 'release/'
|
df = tp[8:] # remove 'release/'
|
||||||
for f in tf:
|
for f in tf:
|
||||||
pluglist.append(os.path.join(tp, f))
|
pluglist.append(os.path.join(tp, f))
|
||||||
plugtargetlist.append( os.path.join(env['BF_INSTALLDIR'], df, f) )
|
plugtargetlist.append( os.path.join(env['BF_INSTALLDIR'], df, f) )
|
||||||
|
|
||||||
|
|
||||||
# header files for plugins
|
# header files for plugins
|
||||||
@@ -556,82 +556,82 @@ plugtargetlist.append(os.path.join(env['BF_INSTALLDIR'], 'plugins', 'include', '
|
|||||||
|
|
||||||
plugininstall = []
|
plugininstall = []
|
||||||
for targetdir,srcfile in zip(plugtargetlist, pluglist):
|
for targetdir,srcfile in zip(plugtargetlist, pluglist):
|
||||||
td, tf = os.path.split(targetdir)
|
td, tf = os.path.split(targetdir)
|
||||||
plugininstall.append(env.Install(dir=td, source=srcfile))
|
plugininstall.append(env.Install(dir=td, source=srcfile))
|
||||||
|
|
||||||
textlist = []
|
textlist = []
|
||||||
texttargetlist = []
|
texttargetlist = []
|
||||||
for tp, tn, tf in os.walk('release/text'):
|
for tp, tn, tf in os.walk('release/text'):
|
||||||
if '.svn' in tn:
|
if '.svn' in tn:
|
||||||
tn.remove('.svn')
|
tn.remove('.svn')
|
||||||
if '_svn' in tn:
|
if '_svn' in tn:
|
||||||
tn.remove('_svn')
|
tn.remove('_svn')
|
||||||
for f in tf:
|
for f in tf:
|
||||||
textlist.append(tp+os.sep+f)
|
textlist.append(tp+os.sep+f)
|
||||||
|
|
||||||
textinstall = env.Install(dir=env['BF_INSTALLDIR'], source=textlist)
|
textinstall = env.Install(dir=env['BF_INSTALLDIR'], source=textlist)
|
||||||
|
|
||||||
if env['OURPLATFORM']=='darwin':
|
if env['OURPLATFORM']=='darwin':
|
||||||
allinstall = [blenderinstall, plugininstall, textinstall]
|
allinstall = [blenderinstall, plugininstall, textinstall]
|
||||||
elif env['OURPLATFORM']=='linux2':
|
elif env['OURPLATFORM']=='linux2':
|
||||||
allinstall = [blenderinstall, dotblenderinstall, scriptinstall, plugininstall, textinstall, iconinstall]
|
allinstall = [blenderinstall, dotblenderinstall, scriptinstall, plugininstall, textinstall, iconinstall]
|
||||||
else:
|
else:
|
||||||
allinstall = [blenderinstall, dotblenderinstall, scriptinstall, plugininstall, textinstall]
|
allinstall = [blenderinstall, dotblenderinstall, scriptinstall, plugininstall, textinstall]
|
||||||
|
|
||||||
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'win64-vc', 'linuxcross'):
|
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'win64-vc', 'linuxcross'):
|
||||||
dllsources = []
|
dllsources = []
|
||||||
|
|
||||||
if not env['OURPLATFORM'] in ('win32-mingw', 'win64-vc', 'linuxcross'):
|
if not env['OURPLATFORM'] in ('win32-mingw', 'win64-vc', 'linuxcross'):
|
||||||
# For MinGW and linuxcross static linking will be used
|
# For MinGW and linuxcross static linking will be used
|
||||||
dllsources += ['${LCGDIR}/gettext/lib/gnu_gettext.dll']
|
dllsources += ['${LCGDIR}/gettext/lib/gnu_gettext.dll']
|
||||||
|
|
||||||
#currently win64-vc doesn't appear to have libpng.dll
|
#currently win64-vc doesn't appear to have libpng.dll
|
||||||
if env['OURPLATFORM'] != 'win64-vc':
|
if env['OURPLATFORM'] != 'win64-vc':
|
||||||
dllsources += ['${BF_PNG_LIBPATH}/libpng.dll']
|
dllsources += ['${BF_PNG_LIBPATH}/libpng.dll']
|
||||||
|
|
||||||
dllsources += ['${BF_ZLIB_LIBPATH}/zlib.dll']
|
dllsources += ['${BF_ZLIB_LIBPATH}/zlib.dll']
|
||||||
# Used when linking to libtiff was dynamic
|
# Used when linking to libtiff was dynamic
|
||||||
# keep it here until compilation on all platform would be ok
|
# keep it here until compilation on all platform would be ok
|
||||||
# dllsources += ['${BF_TIFF_LIBPATH}/${BF_TIFF_LIB}.dll']
|
# dllsources += ['${BF_TIFF_LIBPATH}/${BF_TIFF_LIB}.dll']
|
||||||
|
|
||||||
if env['OURPLATFORM'] != 'linuxcross':
|
if env['OURPLATFORM'] != 'linuxcross':
|
||||||
# pthreads library is already added
|
# pthreads library is already added
|
||||||
dllsources += ['${BF_PTHREADS_LIBPATH}/${BF_PTHREADS_LIB}.dll']
|
dllsources += ['${BF_PTHREADS_LIBPATH}/${BF_PTHREADS_LIB}.dll']
|
||||||
|
|
||||||
if env['WITH_BF_SDL']:
|
if env['WITH_BF_SDL']:
|
||||||
if env['OURPLATFORM'] == 'win64-vc':
|
if env['OURPLATFORM'] == 'win64-vc':
|
||||||
pass # we link statically already to SDL on win64
|
pass # we link statically already to SDL on win64
|
||||||
else:
|
else:
|
||||||
dllsources.append('${BF_SDL_LIBPATH}/SDL.dll')
|
dllsources.append('${BF_SDL_LIBPATH}/SDL.dll')
|
||||||
|
|
||||||
if env['WITH_BF_PYTHON']:
|
if env['WITH_BF_PYTHON']:
|
||||||
if env['BF_DEBUG']:
|
if env['BF_DEBUG']:
|
||||||
dllsources.append('${BF_PYTHON_LIBPATH}/${BF_PYTHON_DLL}_d.dll')
|
dllsources.append('${BF_PYTHON_LIBPATH}/${BF_PYTHON_DLL}_d.dll')
|
||||||
else:
|
else:
|
||||||
dllsources.append('${BF_PYTHON_LIBPATH}/${BF_PYTHON_DLL}.dll')
|
dllsources.append('${BF_PYTHON_LIBPATH}/${BF_PYTHON_DLL}.dll')
|
||||||
|
|
||||||
if env['WITH_BF_ICONV']:
|
if env['WITH_BF_ICONV']:
|
||||||
if env['OURPLATFORM'] == 'win64-vc':
|
if env['OURPLATFORM'] == 'win64-vc':
|
||||||
pass # we link statically to iconv on win64
|
pass # we link statically to iconv on win64
|
||||||
elif not env['OURPLATFORM'] in ('win32-mingw', 'linuxcross'):
|
elif not env['OURPLATFORM'] in ('win32-mingw', 'linuxcross'):
|
||||||
#gettext for MinGW and cross-compilation is compiled staticly
|
#gettext for MinGW and cross-compilation is compiled staticly
|
||||||
dllsources += ['${BF_ICONV_LIBPATH}/iconv.dll']
|
dllsources += ['${BF_ICONV_LIBPATH}/iconv.dll']
|
||||||
|
|
||||||
if env['WITH_BF_OPENAL']:
|
if env['WITH_BF_OPENAL']:
|
||||||
dllsources.append('${LCGDIR}/openal/lib/OpenAL32.dll')
|
dllsources.append('${LCGDIR}/openal/lib/OpenAL32.dll')
|
||||||
dllsources.append('${LCGDIR}/openal/lib/wrap_oal.dll')
|
dllsources.append('${LCGDIR}/openal/lib/wrap_oal.dll')
|
||||||
|
|
||||||
if env['WITH_BF_SNDFILE']:
|
if env['WITH_BF_SNDFILE']:
|
||||||
dllsources.append('${LCGDIR}/sndfile/lib/libsndfile-1.dll')
|
dllsources.append('${LCGDIR}/sndfile/lib/libsndfile-1.dll')
|
||||||
|
|
||||||
if env['WITH_BF_FFMPEG']:
|
if env['WITH_BF_FFMPEG']:
|
||||||
dllsources += ['${BF_FFMPEG_LIBPATH}/avcodec-52.dll',
|
dllsources += ['${BF_FFMPEG_LIBPATH}/avcodec-52.dll',
|
||||||
'${BF_FFMPEG_LIBPATH}/avformat-52.dll',
|
'${BF_FFMPEG_LIBPATH}/avformat-52.dll',
|
||||||
'${BF_FFMPEG_LIBPATH}/avdevice-52.dll',
|
'${BF_FFMPEG_LIBPATH}/avdevice-52.dll',
|
||||||
'${BF_FFMPEG_LIBPATH}/avutil-50.dll',
|
'${BF_FFMPEG_LIBPATH}/avutil-50.dll',
|
||||||
'${BF_FFMPEG_LIBPATH}/swscale-0.dll']
|
'${BF_FFMPEG_LIBPATH}/swscale-0.dll']
|
||||||
windlls = env.Install(dir=env['BF_INSTALLDIR'], source = dllsources)
|
windlls = env.Install(dir=env['BF_INSTALLDIR'], source = dllsources)
|
||||||
allinstall += windlls
|
allinstall += windlls
|
||||||
|
|
||||||
installtarget = env.Alias('install', allinstall)
|
installtarget = env.Alias('install', allinstall)
|
||||||
bininstalltarget = env.Alias('install-bin', blenderinstall)
|
bininstalltarget = env.Alias('install-bin', blenderinstall)
|
||||||
@@ -641,24 +641,24 @@ nsiscmd = env.Command('nsisinstaller', None, nsisaction)
|
|||||||
nsisalias = env.Alias('nsis', nsiscmd)
|
nsisalias = env.Alias('nsis', nsiscmd)
|
||||||
|
|
||||||
if 'blender' in B.targets:
|
if 'blender' in B.targets:
|
||||||
blenderexe= env.Alias('blender', B.program_list)
|
blenderexe= env.Alias('blender', B.program_list)
|
||||||
Depends(blenderexe,installtarget)
|
Depends(blenderexe,installtarget)
|
||||||
|
|
||||||
if env['WITH_BF_PLAYER']:
|
if env['WITH_BF_PLAYER']:
|
||||||
blenderplayer = env.Alias('blenderplayer', B.program_list)
|
blenderplayer = env.Alias('blenderplayer', B.program_list)
|
||||||
Depends(blenderplayer,installtarget)
|
Depends(blenderplayer,installtarget)
|
||||||
|
|
||||||
if not env['WITH_BF_GAMEENGINE']:
|
if not env['WITH_BF_GAMEENGINE']:
|
||||||
blendernogame = env.Alias('blendernogame', B.program_list)
|
blendernogame = env.Alias('blendernogame', B.program_list)
|
||||||
Depends(blendernogame,installtarget)
|
Depends(blendernogame,installtarget)
|
||||||
|
|
||||||
if 'blenderlite' in B.targets:
|
if 'blenderlite' in B.targets:
|
||||||
blenderlite = env.Alias('blenderlite', B.program_list)
|
blenderlite = env.Alias('blenderlite', B.program_list)
|
||||||
Depends(blenderlite,installtarget)
|
Depends(blenderlite,installtarget)
|
||||||
|
|
||||||
Depends(nsiscmd, allinstall)
|
Depends(nsiscmd, allinstall)
|
||||||
|
|
||||||
Default(B.program_list)
|
Default(B.program_list)
|
||||||
|
|
||||||
if not env['WITHOUT_BF_INSTALL']:
|
if not env['WITHOUT_BF_INSTALL']:
|
||||||
Default(installtarget)
|
Default(installtarget)
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -32,4 +32,4 @@ license@blender.org for further information.
|
|||||||
|
|
||||||
Ton Roosendaal
|
Ton Roosendaal
|
||||||
Chairman Blender Foundation.
|
Chairman Blender Foundation.
|
||||||
June 2005
|
June 2005
|
||||||
|
|||||||
@@ -1390,4 +1390,4 @@ Radoslav Dejanovic
|
|||||||
James H. Cloos, Jr.
|
James H. Cloos, Jr.
|
||||||
Karl Erlandsen (LethalSideParting)
|
Karl Erlandsen (LethalSideParting)
|
||||||
Kari Pulli
|
Kari Pulli
|
||||||
Dave Shemano
|
Dave Shemano
|
||||||
|
|||||||
4
extern/SConscript
vendored
4
extern/SConscript
vendored
@@ -17,7 +17,7 @@ if env['OURPLATFORM'] == 'linux2':
|
|||||||
SConscript(['binreloc/SConscript']);
|
SConscript(['binreloc/SConscript']);
|
||||||
|
|
||||||
if env['WITH_BF_LZO']:
|
if env['WITH_BF_LZO']:
|
||||||
SConscript(['lzo/SConscript'])
|
SConscript(['lzo/SConscript'])
|
||||||
|
|
||||||
if env['WITH_BF_LZMA']:
|
if env['WITH_BF_LZMA']:
|
||||||
SConscript(['lzma/SConscript'])
|
SConscript(['lzma/SConscript'])
|
||||||
|
|||||||
1
extern/binreloc/CMakeLists.txt
vendored
1
extern/binreloc/CMakeLists.txt
vendored
@@ -23,4 +23,3 @@ ADD_DEFINITIONS(-DENABLE_BINRELOC)
|
|||||||
FILE(GLOB SRC *.c)
|
FILE(GLOB SRC *.c)
|
||||||
|
|
||||||
BLENDERLIB(extern_binreloc "${SRC}" "${INC}")
|
BLENDERLIB(extern_binreloc "${SRC}" "${INC}")
|
||||||
#, libtype=['core','player'], priority = [25,15] )
|
|
||||||
|
|||||||
@@ -24,12 +24,13 @@ btConvexHullShape ::btConvexHullShape (const btScalar* points,int numPoints,int
|
|||||||
m_shapeType = CONVEX_HULL_SHAPE_PROXYTYPE;
|
m_shapeType = CONVEX_HULL_SHAPE_PROXYTYPE;
|
||||||
m_unscaledPoints.resize(numPoints);
|
m_unscaledPoints.resize(numPoints);
|
||||||
|
|
||||||
unsigned char* pointsBaseAddress = (unsigned char*)points;
|
unsigned char* pointsAddress = (unsigned char*)points;
|
||||||
|
|
||||||
for (int i=0;i<numPoints;i++)
|
for (int i=0;i<numPoints;i++)
|
||||||
{
|
{
|
||||||
btVector3* point = (btVector3*)(pointsBaseAddress + i*stride);
|
btScalar* point = (btScalar*)pointsAddress;
|
||||||
m_unscaledPoints[i] = point[0];
|
m_unscaledPoints[i] = btVector3(point[0], point[1], point[2]);
|
||||||
|
pointsAddress += stride;
|
||||||
}
|
}
|
||||||
|
|
||||||
recalcLocalAabb();
|
recalcLocalAabb();
|
||||||
|
|||||||
10
extern/libopenjpeg/SConscript
vendored
10
extern/libopenjpeg/SConscript
vendored
@@ -11,15 +11,15 @@ flags = []
|
|||||||
defs = []
|
defs = []
|
||||||
|
|
||||||
if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
|
if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
|
||||||
flags = []
|
flags = []
|
||||||
defs.append('OPJ_STATIC')
|
defs.append('OPJ_STATIC')
|
||||||
else:
|
else:
|
||||||
flags = ['-Wall', '-O3', '-ffast-math', '-std=c99']
|
flags = ['-Wall', '-O3', '-ffast-math', '-std=c99']
|
||||||
|
|
||||||
oj_env = env.Clone()
|
oj_env = env.Clone()
|
||||||
if not env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
|
if not env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
|
||||||
oj_env.Replace(CCFLAGS = '')
|
oj_env.Replace(CCFLAGS = '')
|
||||||
oj_env.Replace(BF_DEBUG_FLAGS = '')
|
oj_env.Replace(BF_DEBUG_FLAGS = '')
|
||||||
|
|
||||||
oj_env.BlenderLib ( libname='extern_openjpeg',
|
oj_env.BlenderLib ( libname='extern_openjpeg',
|
||||||
sources=sources, includes=Split(incs),
|
sources=sources, includes=Split(incs),
|
||||||
|
|||||||
@@ -20,36 +20,52 @@
|
|||||||
#
|
#
|
||||||
# ***** END LGPL LICENSE BLOCK *****
|
# ***** END LGPL LICENSE BLOCK *****
|
||||||
|
|
||||||
SET(INC . intern FX SRC ${PTHREADS_INC} ${LIBSAMPLERATE_INC})
|
SET(INC
|
||||||
|
.
|
||||||
|
intern
|
||||||
|
FX SRC
|
||||||
|
${PTHREADS_INC}
|
||||||
|
${LIBSAMPLERATE_INC}
|
||||||
|
)
|
||||||
|
|
||||||
FILE(GLOB SRC intern/*.cpp intern/*.h FX/*.cpp SRC/*.cpp)
|
FILE(GLOB SRC
|
||||||
|
intern/*.cpp
|
||||||
|
intern/*.h
|
||||||
|
FX/*.cpp
|
||||||
|
SRC/*.cpp
|
||||||
|
)
|
||||||
|
|
||||||
IF(WITH_FFMPEG)
|
IF(WITH_FFMPEG)
|
||||||
SET(INC ${INC} ffmpeg ${FFMPEG_INC})
|
LIST(APPEND INC ffmpeg)
|
||||||
|
LIST(APPEND INC ${FFMPEG_INC})
|
||||||
FILE(GLOB FFMPEGSRC ffmpeg/*.cpp)
|
FILE(GLOB FFMPEGSRC ffmpeg/*.cpp)
|
||||||
ADD_DEFINITIONS(-DWITH_FFMPEG)
|
ADD_DEFINITIONS(-DWITH_FFMPEG)
|
||||||
ENDIF(WITH_FFMPEG)
|
ENDIF(WITH_FFMPEG)
|
||||||
|
|
||||||
IF(WITH_SDL)
|
IF(WITH_SDL)
|
||||||
SET(INC ${INC} SDL ${SDL_INCLUDE_DIR})
|
LIST(APPEND INC SDL)
|
||||||
|
LIST(APPEND INC ${SDL_INCLUDE_DIR})
|
||||||
FILE(GLOB SDLSRC SDL/*.cpp)
|
FILE(GLOB SDLSRC SDL/*.cpp)
|
||||||
ADD_DEFINITIONS(-DWITH_SDL)
|
ADD_DEFINITIONS(-DWITH_SDL)
|
||||||
ENDIF(WITH_SDL)
|
ENDIF(WITH_SDL)
|
||||||
|
|
||||||
IF(WITH_OPENAL)
|
IF(WITH_OPENAL)
|
||||||
SET(INC ${INC} OpenAL ${OPENAL_INCLUDE_DIR})
|
LIST(APPEND INC OpenAL)
|
||||||
|
LIST(APPEND INC ${OPENAL_INCLUDE_DIR})
|
||||||
FILE(GLOB OPENALSRC OpenAL/*.cpp)
|
FILE(GLOB OPENALSRC OpenAL/*.cpp)
|
||||||
ADD_DEFINITIONS(-DWITH_OPENAL)
|
ADD_DEFINITIONS(-DWITH_OPENAL)
|
||||||
ENDIF(WITH_OPENAL)
|
ENDIF(WITH_OPENAL)
|
||||||
|
|
||||||
IF(WITH_JACK)
|
IF(WITH_JACK)
|
||||||
SET(INC ${INC} jack ${JACK_INC})
|
LIST(APPEND INC jack)
|
||||||
|
LIST(APPEND INC ${JACK_INC})
|
||||||
FILE(GLOB JACKSRC jack/*.cpp)
|
FILE(GLOB JACKSRC jack/*.cpp)
|
||||||
ADD_DEFINITIONS(-DWITH_JACK)
|
ADD_DEFINITIONS(-DWITH_JACK)
|
||||||
ENDIF(WITH_JACK)
|
ENDIF(WITH_JACK)
|
||||||
|
|
||||||
IF(WITH_SNDFILE)
|
IF(WITH_SNDFILE)
|
||||||
SET(INC ${INC} sndfile ${SNDFILE_INC})
|
LIST(APPEND INC sndfile)
|
||||||
|
LIST(APPEND INC ${SNDFILE_INC})
|
||||||
FILE(GLOB SNDFILESRC sndfile/*.cpp)
|
FILE(GLOB SNDFILESRC sndfile/*.cpp)
|
||||||
ADD_DEFINITIONS(-DWITH_SNDFILE)
|
ADD_DEFINITIONS(-DWITH_SNDFILE)
|
||||||
ENDIF(WITH_SNDFILE)
|
ENDIF(WITH_SNDFILE)
|
||||||
@@ -61,7 +77,8 @@ ENDIF(WITH_SNDFILE)
|
|||||||
#ENDIF(WITH_FFTW3)
|
#ENDIF(WITH_FFTW3)
|
||||||
|
|
||||||
IF(WITH_PYTHON)
|
IF(WITH_PYTHON)
|
||||||
SET(INC ${INC} Python ${PYTHON_INC})
|
LIST(APPEND INC Python)
|
||||||
|
LIST(APPEND INC ${PYTHON_INC})
|
||||||
FILE(GLOB PYTHONSRC Python/*.cpp)
|
FILE(GLOB PYTHONSRC Python/*.cpp)
|
||||||
ELSE(WITH_PYTHON)
|
ELSE(WITH_PYTHON)
|
||||||
ADD_DEFINITIONS(-DDISABLE_PYTHON)
|
ADD_DEFINITIONS(-DDISABLE_PYTHON)
|
||||||
|
|||||||
@@ -243,7 +243,10 @@ void AUD_OpenALDevice::updateStreams()
|
|||||||
stop(sound);
|
stop(sound);
|
||||||
// decrement again, so that we get the next sound in the
|
// decrement again, so that we get the next sound in the
|
||||||
// next loop run
|
// next loop run
|
||||||
--it;
|
if(m_playingSounds->empty())
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
--it;
|
||||||
}
|
}
|
||||||
// continue playing
|
// continue playing
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -7,40 +7,40 @@ incs = '. intern FX SRC ' + env['BF_PTHREADS_INC'] + ' ' + env['BF_LIBSAMPLERATE
|
|||||||
defs = []
|
defs = []
|
||||||
|
|
||||||
if env['WITH_BF_FFMPEG']:
|
if env['WITH_BF_FFMPEG']:
|
||||||
sources += env.Glob('ffmpeg/*.cpp')
|
sources += env.Glob('ffmpeg/*.cpp')
|
||||||
incs += ' ffmpeg ' + env['BF_FFMPEG_INC']
|
incs += ' ffmpeg ' + env['BF_FFMPEG_INC']
|
||||||
defs.append('WITH_FFMPEG')
|
defs.append('WITH_FFMPEG')
|
||||||
|
|
||||||
if env['WITH_BF_SDL']:
|
if env['WITH_BF_SDL']:
|
||||||
sources += env.Glob('SDL/*.cpp')
|
sources += env.Glob('SDL/*.cpp')
|
||||||
incs += ' SDL ' + env['BF_SDL_INC']
|
incs += ' SDL ' + env['BF_SDL_INC']
|
||||||
defs.append('WITH_SDL')
|
defs.append('WITH_SDL')
|
||||||
|
|
||||||
if env['WITH_BF_OPENAL']:
|
if env['WITH_BF_OPENAL']:
|
||||||
sources += env.Glob('OpenAL/*.cpp')
|
sources += env.Glob('OpenAL/*.cpp')
|
||||||
incs += ' OpenAL ' + env['BF_OPENAL_INC']
|
incs += ' OpenAL ' + env['BF_OPENAL_INC']
|
||||||
defs.append('WITH_OPENAL')
|
defs.append('WITH_OPENAL')
|
||||||
|
|
||||||
if env['WITH_BF_JACK']:
|
if env['WITH_BF_JACK']:
|
||||||
sources += env.Glob('jack/*.cpp')
|
sources += env.Glob('jack/*.cpp')
|
||||||
incs += ' jack ' + env['BF_JACK_INC']
|
incs += ' jack ' + env['BF_JACK_INC']
|
||||||
defs.append('WITH_JACK')
|
defs.append('WITH_JACK')
|
||||||
|
|
||||||
if env['WITH_BF_SNDFILE']:
|
if env['WITH_BF_SNDFILE']:
|
||||||
sources += env.Glob('sndfile/*.cpp')
|
sources += env.Glob('sndfile/*.cpp')
|
||||||
incs += ' sndfile ' + env['BF_SNDFILE_INC']
|
incs += ' sndfile ' + env['BF_SNDFILE_INC']
|
||||||
defs.append('WITH_SNDFILE')
|
defs.append('WITH_SNDFILE')
|
||||||
|
|
||||||
#if env['WITH_BF_FFTW3']:
|
#if env['WITH_BF_FFTW3']:
|
||||||
# sources += env.Glob('fftw/*.cpp')
|
# sources += env.Glob('fftw/*.cpp')
|
||||||
# incs += ' fftw ' + env['BF_FFTW3_INC']
|
# incs += ' fftw ' + env['BF_FFTW3_INC']
|
||||||
# defs.append('WITH_FFTW3')
|
# defs.append('WITH_FFTW3')
|
||||||
|
|
||||||
if env['WITH_BF_PYTHON']:
|
if env['WITH_BF_PYTHON']:
|
||||||
sources += env.Glob('Python/*.cpp')
|
sources += env.Glob('Python/*.cpp')
|
||||||
incs += ' Python ' + env['BF_PYTHON_INC']
|
incs += ' Python ' + env['BF_PYTHON_INC']
|
||||||
else:
|
else:
|
||||||
defs.append('DISABLE_PYTHON')
|
defs.append('DISABLE_PYTHON')
|
||||||
|
|
||||||
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'):
|
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'):
|
||||||
incs += ' ' + env['BF_PTHREADS_INC']
|
incs += ' ' + env['BF_PTHREADS_INC']
|
||||||
|
|||||||
@@ -96,7 +96,6 @@ typedef AUD_Handle AUD_Channel;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static AUD_IDevice* AUD_device = NULL;
|
static AUD_IDevice* AUD_device = NULL;
|
||||||
static int AUD_available_devices[4];
|
|
||||||
static AUD_I3DDevice* AUD_3ddevice = NULL;
|
static AUD_I3DDevice* AUD_3ddevice = NULL;
|
||||||
|
|
||||||
void AUD_initOnce()
|
void AUD_initOnce()
|
||||||
@@ -161,22 +160,6 @@ int AUD_init(AUD_DeviceType device, AUD_DeviceSpecs specs, int buffersize)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int* AUD_enumDevices()
|
|
||||||
{
|
|
||||||
int i = 0;
|
|
||||||
#ifdef WITH_SDL
|
|
||||||
AUD_available_devices[i++] = AUD_SDL_DEVICE;
|
|
||||||
#endif
|
|
||||||
#ifdef WITH_OPENAL
|
|
||||||
AUD_available_devices[i++] = AUD_OPENAL_DEVICE;
|
|
||||||
#endif
|
|
||||||
#ifdef WITH_JACK
|
|
||||||
AUD_available_devices[i++] = AUD_JACK_DEVICE;
|
|
||||||
#endif
|
|
||||||
AUD_available_devices[i++] = AUD_NULL_DEVICE;
|
|
||||||
return AUD_available_devices;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AUD_exit()
|
void AUD_exit()
|
||||||
{
|
{
|
||||||
#ifndef DISABLE_PYTHON
|
#ifndef DISABLE_PYTHON
|
||||||
|
|||||||
@@ -69,12 +69,6 @@ extern void AUD_initOnce();
|
|||||||
*/
|
*/
|
||||||
extern int AUD_init(AUD_DeviceType device, AUD_DeviceSpecs specs, int buffersize);
|
extern int AUD_init(AUD_DeviceType device, AUD_DeviceSpecs specs, int buffersize);
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a integer list with available sound devices. The last one is always
|
|
||||||
* AUD_NULL_DEVICE.
|
|
||||||
*/
|
|
||||||
extern int* AUD_enumDevices();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unitinitializes an audio device.
|
* Unitinitializes an audio device.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -8,56 +8,56 @@ window_system = env['OURPLATFORM']
|
|||||||
|
|
||||||
sources = env.Glob('intern/*.cpp')
|
sources = env.Glob('intern/*.cpp')
|
||||||
if window_system == 'darwin':
|
if window_system == 'darwin':
|
||||||
sources += env.Glob('intern/*.mm')
|
sources += env.Glob('intern/*.mm')
|
||||||
|
|
||||||
|
|
||||||
pf = ['GHOST_DisplayManager', 'GHOST_System', 'GHOST_Window', 'GHOST_DropTarget']
|
pf = ['GHOST_DisplayManager', 'GHOST_System', 'GHOST_Window', 'GHOST_DropTarget']
|
||||||
defs=['_USE_MATH_DEFINES']
|
defs=['_USE_MATH_DEFINES']
|
||||||
|
|
||||||
if window_system in ('linux2', 'openbsd3', 'sunos5', 'freebsd7', 'freebsd8', 'freebsd9', 'irix6', 'aix4', 'aix5'):
|
if window_system in ('linux2', 'openbsd3', 'sunos5', 'freebsd7', 'freebsd8', 'freebsd9', 'irix6', 'aix4', 'aix5'):
|
||||||
for f in pf:
|
for f in pf:
|
||||||
try:
|
try:
|
||||||
sources.remove('intern' + os.sep + f + 'Win32.cpp')
|
sources.remove('intern' + os.sep + f + 'Win32.cpp')
|
||||||
sources.remove('intern' + os.sep + f + 'Carbon.cpp')
|
sources.remove('intern' + os.sep + f + 'Carbon.cpp')
|
||||||
except ValueError:
|
except ValueError:
|
||||||
pass
|
pass
|
||||||
elif window_system in ('win32-vc', 'win32-mingw', 'cygwin', 'linuxcross', 'win64-vc'):
|
elif window_system in ('win32-vc', 'win32-mingw', 'cygwin', 'linuxcross', 'win64-vc'):
|
||||||
for f in pf:
|
for f in pf:
|
||||||
try:
|
try:
|
||||||
sources.remove('intern' + os.sep + f + 'X11.cpp')
|
sources.remove('intern' + os.sep + f + 'X11.cpp')
|
||||||
sources.remove('intern' + os.sep + f + 'Carbon.cpp')
|
sources.remove('intern' + os.sep + f + 'Carbon.cpp')
|
||||||
except ValueError:
|
except ValueError:
|
||||||
pass
|
pass
|
||||||
elif window_system == 'darwin':
|
elif window_system == 'darwin':
|
||||||
if env['WITH_GHOST_COCOA']:
|
if env['WITH_GHOST_COCOA']:
|
||||||
if env['WITH_BF_QUICKTIME']:
|
if env['WITH_BF_QUICKTIME']:
|
||||||
defs.append('WITH_QUICKTIME')
|
defs.append('WITH_QUICKTIME')
|
||||||
if env['USE_QTKIT']:
|
if env['USE_QTKIT']:
|
||||||
defs.append('USE_QTKIT')
|
defs.append('USE_QTKIT')
|
||||||
for f in pf:
|
for f in pf:
|
||||||
try:
|
try:
|
||||||
sources.remove('intern' + os.sep + f + 'Win32.cpp')
|
sources.remove('intern' + os.sep + f + 'Win32.cpp')
|
||||||
sources.remove('intern' + os.sep + f + 'X11.cpp')
|
sources.remove('intern' + os.sep + f + 'X11.cpp')
|
||||||
sources.remove('intern' + os.sep + f + 'Carbon.cpp')
|
sources.remove('intern' + os.sep + f + 'Carbon.cpp')
|
||||||
except ValueError:
|
except ValueError:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
for f in pf:
|
for f in pf:
|
||||||
try:
|
try:
|
||||||
sources.remove('intern' + os.sep + f + 'Win32.cpp')
|
sources.remove('intern' + os.sep + f + 'Win32.cpp')
|
||||||
sources.remove('intern' + os.sep + f + 'X11.cpp')
|
sources.remove('intern' + os.sep + f + 'X11.cpp')
|
||||||
sources.remove('intern' + os.sep + f + 'Cocoa.mm')
|
sources.remove('intern' + os.sep + f + 'Cocoa.mm')
|
||||||
except ValueError:
|
except ValueError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
else:
|
else:
|
||||||
print "Unknown window system specified."
|
print "Unknown window system specified."
|
||||||
Exit()
|
Exit()
|
||||||
|
|
||||||
if env['BF_GHOST_DEBUG']:
|
if env['BF_GHOST_DEBUG']:
|
||||||
defs.append('BF_GHOST_DEBUG')
|
defs.append('BF_GHOST_DEBUG')
|
||||||
|
|
||||||
incs = '. ../string #extern/glew/include #source/blender/imbuf #source/blender/makesdna ' + env['BF_OPENGL_INC']
|
incs = '. ../string #extern/glew/include #source/blender/imbuf #source/blender/makesdna ' + env['BF_OPENGL_INC']
|
||||||
if window_system in ('win32-vc', 'win32-mingw', 'cygwin', 'linuxcross', 'win64-vc'):
|
if window_system in ('win32-vc', 'win32-mingw', 'cygwin', 'linuxcross', 'win64-vc'):
|
||||||
incs = env['BF_WINTAB_INC'] + ' ' + incs
|
incs = env['BF_WINTAB_INC'] + ' ' + incs
|
||||||
env.BlenderLib ('bf_intern_ghost', sources, Split(incs), defines=defs, libtype=['intern','player'], priority = [40,15] )
|
env.BlenderLib ('bf_intern_ghost', sources, Split(incs), defines=defs, libtype=['intern','player'], priority = [40,15] )
|
||||||
|
|||||||
@@ -212,4 +212,4 @@ bool GHOST_WindowManager::getAnyModifiedState()
|
|||||||
}
|
}
|
||||||
|
|
||||||
return isAnyModified;
|
return isAnyModified;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ SOURCE=..\..\..\..\source\blender\blenkernel\bad_level_call_stubs\stubs.c
|
|||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\..\..\..\source\icons\winplayer.rc
|
SOURCE=..\..\..\..\source\icons\winblender.rc
|
||||||
# End Source File
|
# End Source File
|
||||||
# End Group
|
# End Group
|
||||||
# Begin Group "Header Files"
|
# Begin Group "Header Files"
|
||||||
@@ -145,7 +145,7 @@ SOURCE=..\..\..\..\source\gameengine\GamePlayer\ghost\GPG_System.h
|
|||||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\..\..\..\source\icons\winplayer.ico
|
SOURCE=..\..\..\..\source\icons\winblender.ico
|
||||||
# End Source File
|
# End Source File
|
||||||
# End Group
|
# End Group
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|||||||
@@ -189,7 +189,7 @@ ECHO Done
|
|||||||
RelativePath="..\..\..\..\source\blender\blenkernel\bad_level_call_stubs\stubs.c">
|
RelativePath="..\..\..\..\source\blender\blenkernel\bad_level_call_stubs\stubs.c">
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\..\source\icons\winplayer.rc">
|
RelativePath="..\..\..\..\source\icons\winblender.rc">
|
||||||
<FileConfiguration
|
<FileConfiguration
|
||||||
Name="BlenderPlayer Debug|Win32">
|
Name="BlenderPlayer Debug|Win32">
|
||||||
<Tool
|
<Tool
|
||||||
@@ -224,7 +224,7 @@ ECHO Done
|
|||||||
Name="Resource Files"
|
Name="Resource Files"
|
||||||
Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
|
Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\..\source\icons\winplayer.ico">
|
RelativePath="..\..\..\..\source\icons\winblender.ico">
|
||||||
</File>
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
<File
|
<File
|
||||||
|
|||||||
@@ -239,7 +239,7 @@
|
|||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\..\source\icons\winplayer.rc"
|
RelativePath="..\..\..\..\source\icons\winblender.rc"
|
||||||
>
|
>
|
||||||
<FileConfiguration
|
<FileConfiguration
|
||||||
Name="BlenderPlayer Debug|Win32"
|
Name="BlenderPlayer Debug|Win32"
|
||||||
@@ -285,7 +285,7 @@
|
|||||||
Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||||
>
|
>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\..\source\icons\winplayer.ico"
|
RelativePath="..\..\..\..\source\icons\winblender.ico"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
[Desktop Entry]
|
[Desktop Entry]
|
||||||
Encoding=UTF-8
|
|
||||||
Name=Blender
|
Name=Blender
|
||||||
|
GenericName=3D modeller
|
||||||
|
GenericName[es]=modelador 3D
|
||||||
|
GenericName[de]=3D Modellierer
|
||||||
|
GenericName[fr]=modeleur 3D
|
||||||
|
GenericName[ru]=Редактор 3D-моделей
|
||||||
Comment=3D modeling, animation, rendering and post-production
|
Comment=3D modeling, animation, rendering and post-production
|
||||||
|
Comment[es]=modelado 3D, animación, renderizado y post-producción
|
||||||
Exec=blender
|
Exec=blender
|
||||||
Icon=blender.svg
|
Icon=blender.svg
|
||||||
Terminal=false
|
Terminal=false
|
||||||
|
|||||||
@@ -1,208 +0,0 @@
|
|||||||
# ##### BEGIN GPL LICENSE BLOCK #####
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or
|
|
||||||
# modify it under the terms of the GNU General Public License
|
|
||||||
# as published by the Free Software Foundation; either version 2
|
|
||||||
# of the License, or (at your option) any later version.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software Foundation,
|
|
||||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
#
|
|
||||||
# ##### END GPL LICENSE BLOCK #####
|
|
||||||
|
|
||||||
# <pep8 compliant>
|
|
||||||
|
|
||||||
__author__ = "Bill L.Nieuwendorp"
|
|
||||||
__bpydoc__ = """\
|
|
||||||
This script Exports Lightwaves MotionDesigner format.
|
|
||||||
|
|
||||||
The .mdd format has become quite a popular Pipeline format<br>
|
|
||||||
for moving animations from package to package.
|
|
||||||
|
|
||||||
Be sure not to use modifiers that change the number or order of verts in the mesh
|
|
||||||
"""
|
|
||||||
#Please send any fixes,updates,bugs to Slow67_at_Gmail.com or cbarton_at_metavr.com
|
|
||||||
#Bill Niewuendorp
|
|
||||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or
|
|
||||||
# modify it under the terms of the GNU General Public License
|
|
||||||
# as published by the Free Software Foundation; either version 2
|
|
||||||
# of the License, or (at your option) any later version.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software Foundation,
|
|
||||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
#
|
|
||||||
# ***** END GPL LICENCE BLOCK *****
|
|
||||||
|
|
||||||
import bpy
|
|
||||||
import mathutils
|
|
||||||
from struct import pack
|
|
||||||
|
|
||||||
|
|
||||||
def zero_file(filepath):
|
|
||||||
'''
|
|
||||||
If a file fails, this replaces it with 1 char, better not remove it?
|
|
||||||
'''
|
|
||||||
file = open(filepath, 'w')
|
|
||||||
file.write('\n') # apparently macosx needs some data in a blank file?
|
|
||||||
file.close()
|
|
||||||
|
|
||||||
|
|
||||||
def check_vertcount(mesh, vertcount):
|
|
||||||
'''
|
|
||||||
check and make sure the vertcount is consistent throughout the frame range
|
|
||||||
'''
|
|
||||||
if len(mesh.vertices) != vertcount:
|
|
||||||
raise Exception('Error, number of verts has changed during animation, cannot export')
|
|
||||||
f.close()
|
|
||||||
zero_file(filepath)
|
|
||||||
return
|
|
||||||
|
|
||||||
|
|
||||||
def write(filename, sce, ob, PREF_STARTFRAME, PREF_ENDFRAME, PREF_FPS):
|
|
||||||
"""
|
|
||||||
Blender.Window.WaitCursor(1)
|
|
||||||
|
|
||||||
mesh_orig = Mesh.New()
|
|
||||||
mesh_orig.getFromObject(ob.name)
|
|
||||||
"""
|
|
||||||
|
|
||||||
bpy.ops.object.mode_set(mode='OBJECT')
|
|
||||||
|
|
||||||
orig_frame = sce.frame_current
|
|
||||||
sce.set_frame(PREF_STARTFRAME)
|
|
||||||
me = ob.create_mesh(sce, True, 'PREVIEW')
|
|
||||||
|
|
||||||
#Flip y and z
|
|
||||||
mat_flip = mathutils.Matrix(\
|
|
||||||
[1.0, 0.0, 0.0, 0.0],\
|
|
||||||
[0.0, 0.0, 1.0, 0.0],\
|
|
||||||
[0.0, 1.0, 0.0, 0.0],\
|
|
||||||
[0.0, 0.0, 0.0, 1.0],\
|
|
||||||
)
|
|
||||||
|
|
||||||
numverts = len(me.vertices)
|
|
||||||
|
|
||||||
numframes = PREF_ENDFRAME - PREF_STARTFRAME + 1
|
|
||||||
PREF_FPS = float(PREF_FPS)
|
|
||||||
f = open(filename, 'wb') #no Errors yet:Safe to create file
|
|
||||||
|
|
||||||
# Write the header
|
|
||||||
f.write(pack(">2i", numframes, numverts))
|
|
||||||
|
|
||||||
# Write the frame times (should we use the time IPO??)
|
|
||||||
f.write(pack(">%df" % (numframes), *[frame / PREF_FPS for frame in range(numframes)])) # seconds
|
|
||||||
|
|
||||||
#rest frame needed to keep frames in sync
|
|
||||||
"""
|
|
||||||
Blender.Set('curframe', PREF_STARTFRAME)
|
|
||||||
me_tmp.getFromObject(ob.name)
|
|
||||||
"""
|
|
||||||
|
|
||||||
check_vertcount(me, numverts)
|
|
||||||
me.transform(mat_flip * ob.matrix_world)
|
|
||||||
f.write(pack(">%df" % (numverts * 3), *[axis for v in me.vertices for axis in v.co]))
|
|
||||||
|
|
||||||
for frame in range(PREF_STARTFRAME, PREF_ENDFRAME + 1):#in order to start at desired frame
|
|
||||||
"""
|
|
||||||
Blender.Set('curframe', frame)
|
|
||||||
me_tmp.getFromObject(ob.name)
|
|
||||||
"""
|
|
||||||
|
|
||||||
sce.set_frame(frame)
|
|
||||||
me = ob.create_mesh(sce, True, 'PREVIEW')
|
|
||||||
check_vertcount(me, numverts)
|
|
||||||
me.transform(mat_flip * ob.matrix_world)
|
|
||||||
|
|
||||||
# Write the vertex data
|
|
||||||
f.write(pack(">%df" % (numverts * 3), *[axis for v in me.vertices for axis in v.co]))
|
|
||||||
|
|
||||||
"""
|
|
||||||
me_tmp.vertices= None
|
|
||||||
"""
|
|
||||||
f.close()
|
|
||||||
|
|
||||||
print('MDD Exported: %s frames:%d\n' % (filename, numframes - 1))
|
|
||||||
"""
|
|
||||||
Blender.Window.WaitCursor(0)
|
|
||||||
Blender.Set('curframe', orig_frame)
|
|
||||||
"""
|
|
||||||
sce.set_frame(orig_frame)
|
|
||||||
|
|
||||||
from bpy.props import *
|
|
||||||
|
|
||||||
|
|
||||||
class ExportMDD(bpy.types.Operator):
|
|
||||||
'''Animated mesh to MDD vertex keyframe file'''
|
|
||||||
bl_idname = "export.mdd"
|
|
||||||
bl_label = "Export MDD"
|
|
||||||
|
|
||||||
# get first scene to get min and max properties for frames, fps
|
|
||||||
|
|
||||||
minframe = 1
|
|
||||||
maxframe = 300000
|
|
||||||
minfps = 1
|
|
||||||
maxfps = 120
|
|
||||||
|
|
||||||
# List of operator properties, the attributes will be assigned
|
|
||||||
# to the class instance from the operator settings before calling.
|
|
||||||
filepath = StringProperty(name="File Path", description="Filepath used for exporting the MDD file", maxlen=1024)
|
|
||||||
check_existing = BoolProperty(name="Check Existing", description="Check and warn on overwriting existing files", default=True, options={'HIDDEN'})
|
|
||||||
fps = IntProperty(name="Frames Per Second", description="Number of frames/second", min=minfps, max=maxfps, default=25)
|
|
||||||
frame_start = IntProperty(name="Start Frame", description="Start frame for baking", min=minframe, max=maxframe, default=1)
|
|
||||||
frame_end = IntProperty(name="End Frame", description="End frame for baking", min=minframe, max=maxframe, default=250)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def poll(cls, context):
|
|
||||||
ob = context.active_object
|
|
||||||
return (ob and ob.type == 'MESH')
|
|
||||||
|
|
||||||
def execute(self, context):
|
|
||||||
filepath = self.properties.filepath
|
|
||||||
filepath = bpy.path.ensure_ext(filepath, ".mdd")
|
|
||||||
|
|
||||||
write(filepath,
|
|
||||||
context.scene,
|
|
||||||
context.active_object,
|
|
||||||
self.properties.frame_start,
|
|
||||||
self.properties.frame_end,
|
|
||||||
self.properties.fps,
|
|
||||||
)
|
|
||||||
|
|
||||||
return {'FINISHED'}
|
|
||||||
|
|
||||||
def invoke(self, context, event):
|
|
||||||
import os
|
|
||||||
if not self.properties.is_property_set("filepath"):
|
|
||||||
self.properties.filepath = os.path.splitext(bpy.data.filepath)[0] + ".mdd"
|
|
||||||
|
|
||||||
context.manager.add_fileselect(self)
|
|
||||||
return {'RUNNING_MODAL'}
|
|
||||||
|
|
||||||
|
|
||||||
def menu_func(self, context):
|
|
||||||
self.layout.operator(ExportMDD.bl_idname, text="Lightwave Point Cache (.mdd)")
|
|
||||||
|
|
||||||
|
|
||||||
def register():
|
|
||||||
bpy.types.INFO_MT_file_export.append(menu_func)
|
|
||||||
|
|
||||||
|
|
||||||
def unregister():
|
|
||||||
bpy.types.INFO_MT_file_export.remove(menu_func)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
register()
|
|
||||||
@@ -1,327 +0,0 @@
|
|||||||
# ##### BEGIN GPL LICENSE BLOCK #####
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or
|
|
||||||
# modify it under the terms of the GNU General Public License
|
|
||||||
# as published by the Free Software Foundation; either version 2
|
|
||||||
# of the License, or (at your option) any later version.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software Foundation,
|
|
||||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
#
|
|
||||||
# ##### END GPL LICENSE BLOCK #####
|
|
||||||
|
|
||||||
# <pep8 compliant>
|
|
||||||
|
|
||||||
import bpy
|
|
||||||
|
|
||||||
__author__ = "Bruce Merry"
|
|
||||||
__version__ = "0.93"
|
|
||||||
__bpydoc__ = """\
|
|
||||||
This script exports Stanford PLY files from Blender. It supports normals,
|
|
||||||
colours, and texture coordinates per face or per vertex.
|
|
||||||
Only one mesh can be exported at a time.
|
|
||||||
"""
|
|
||||||
|
|
||||||
# Copyright (C) 2004, 2005: Bruce Merry, bmerry@cs.uct.ac.za
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or
|
|
||||||
# modify it under the terms of the GNU General Public License
|
|
||||||
# as published by the Free Software Foundation; either version 2
|
|
||||||
# of the License, or (at your option) any later version.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software Foundation,
|
|
||||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
# Vector rounding se we can use as keys
|
|
||||||
#
|
|
||||||
# Updated on Aug 11, 2008 by Campbell Barton
|
|
||||||
# - added 'comment' prefix to comments - Needed to comply with the PLY spec.
|
|
||||||
#
|
|
||||||
# Updated on Jan 1, 2007 by Gabe Ghearing
|
|
||||||
# - fixed normals so they are correctly smooth/flat
|
|
||||||
# - fixed crash when the model doesn't have uv coords or vertex colors
|
|
||||||
# - fixed crash when the model has vertex colors but doesn't have uv coords
|
|
||||||
# - changed float32 to float and uint8 to uchar for compatibility
|
|
||||||
# Errata/Notes as of Jan 1, 2007
|
|
||||||
# - script exports texture coords if they exist even if TexFace isn't selected (not a big deal to me)
|
|
||||||
# - ST(R) should probably be renamed UV(T) like in most PLY files (importer needs to be updated to take either)
|
|
||||||
#
|
|
||||||
# Updated on Jan 3, 2007 by Gabe Ghearing
|
|
||||||
# - fixed "sticky" vertex UV exporting
|
|
||||||
# - added pupmenu to enable/disable exporting normals, uv coords, and colors
|
|
||||||
# Errata/Notes as of Jan 3, 2007
|
|
||||||
# - ST(R) coords should probably be renamed UV(T) like in most PLY files (importer needs to be updated to take either)
|
|
||||||
# - edges should be exported since PLY files support them
|
|
||||||
# - code is getting spaghettish, it should be refactored...
|
|
||||||
#
|
|
||||||
|
|
||||||
|
|
||||||
def rvec3d(v):
|
|
||||||
return round(v[0], 6), round(v[1], 6), round(v[2], 6)
|
|
||||||
|
|
||||||
|
|
||||||
def rvec2d(v):
|
|
||||||
return round(v[0], 6), round(v[1], 6)
|
|
||||||
|
|
||||||
|
|
||||||
def write(filename, scene, ob, \
|
|
||||||
EXPORT_APPLY_MODIFIERS=True,\
|
|
||||||
EXPORT_NORMALS=True,\
|
|
||||||
EXPORT_UV=True,\
|
|
||||||
EXPORT_COLORS=True):
|
|
||||||
|
|
||||||
if not filename.lower().endswith('.ply'):
|
|
||||||
filename += '.ply'
|
|
||||||
|
|
||||||
if not ob:
|
|
||||||
raise Exception("Error, Select 1 active object")
|
|
||||||
return
|
|
||||||
|
|
||||||
file = open(filename, 'w')
|
|
||||||
|
|
||||||
|
|
||||||
#EXPORT_EDGES = Draw.Create(0)
|
|
||||||
"""
|
|
||||||
is_editmode = Blender.Window.EditMode()
|
|
||||||
if is_editmode:
|
|
||||||
Blender.Window.EditMode(0, '', 0)
|
|
||||||
|
|
||||||
Window.WaitCursor(1)
|
|
||||||
"""
|
|
||||||
if scene.objects.active:
|
|
||||||
bpy.ops.object.mode_set(mode='OBJECT')
|
|
||||||
|
|
||||||
#mesh = BPyMesh.getMeshFromObject(ob, None, EXPORT_APPLY_MODIFIERS, False, scn) # XXX
|
|
||||||
if EXPORT_APPLY_MODIFIERS:
|
|
||||||
mesh = ob.create_mesh(scene, True, 'PREVIEW')
|
|
||||||
else:
|
|
||||||
mesh = ob.data
|
|
||||||
|
|
||||||
if not mesh:
|
|
||||||
raise ("Error, could not get mesh data from active object")
|
|
||||||
return
|
|
||||||
|
|
||||||
# mesh.transform(ob.matrix_world) # XXX
|
|
||||||
|
|
||||||
faceUV = (len(mesh.uv_textures) > 0)
|
|
||||||
vertexUV = (len(mesh.sticky) > 0)
|
|
||||||
vertexColors = len(mesh.vertex_colors) > 0
|
|
||||||
|
|
||||||
if (not faceUV) and (not vertexUV):
|
|
||||||
EXPORT_UV = False
|
|
||||||
if not vertexColors:
|
|
||||||
EXPORT_COLORS = False
|
|
||||||
|
|
||||||
if not EXPORT_UV:
|
|
||||||
faceUV = vertexUV = False
|
|
||||||
if not EXPORT_COLORS:
|
|
||||||
vertexColors = False
|
|
||||||
|
|
||||||
if faceUV:
|
|
||||||
active_uv_layer = mesh.uv_textures.active
|
|
||||||
if not active_uv_layer:
|
|
||||||
EXPORT_UV = False
|
|
||||||
faceUV = None
|
|
||||||
else:
|
|
||||||
active_uv_layer = active_uv_layer.data
|
|
||||||
|
|
||||||
if vertexColors:
|
|
||||||
active_col_layer = mesh.vertex_colors.active
|
|
||||||
if not active_col_layer:
|
|
||||||
EXPORT_COLORS = False
|
|
||||||
vertexColors = None
|
|
||||||
else:
|
|
||||||
active_col_layer = active_col_layer.data
|
|
||||||
|
|
||||||
# incase
|
|
||||||
color = uvcoord = uvcoord_key = normal = normal_key = None
|
|
||||||
|
|
||||||
mesh_verts = mesh.vertices # save a lookup
|
|
||||||
ply_verts = [] # list of dictionaries
|
|
||||||
# vdict = {} # (index, normal, uv) -> new index
|
|
||||||
vdict = [{} for i in range(len(mesh_verts))]
|
|
||||||
ply_faces = [[] for f in range(len(mesh.faces))]
|
|
||||||
vert_count = 0
|
|
||||||
for i, f in enumerate(mesh.faces):
|
|
||||||
|
|
||||||
|
|
||||||
smooth = f.use_smooth
|
|
||||||
if not smooth:
|
|
||||||
normal = tuple(f.normal)
|
|
||||||
normal_key = rvec3d(normal)
|
|
||||||
|
|
||||||
if faceUV:
|
|
||||||
uv = active_uv_layer[i]
|
|
||||||
uv = uv.uv1, uv.uv2, uv.uv3, uv.uv4 # XXX - crufty :/
|
|
||||||
if vertexColors:
|
|
||||||
col = active_col_layer[i]
|
|
||||||
col = col.color1, col.color2, col.color3, col.color4
|
|
||||||
|
|
||||||
f_verts = f.vertices
|
|
||||||
|
|
||||||
pf = ply_faces[i]
|
|
||||||
for j, vidx in enumerate(f_verts):
|
|
||||||
v = mesh_verts[vidx]
|
|
||||||
|
|
||||||
if smooth:
|
|
||||||
normal = tuple(v.normal)
|
|
||||||
normal_key = rvec3d(normal)
|
|
||||||
|
|
||||||
if faceUV:
|
|
||||||
uvcoord = uv[j][0], 1.0 - uv[j][1]
|
|
||||||
uvcoord_key = rvec2d(uvcoord)
|
|
||||||
elif vertexUV:
|
|
||||||
uvcoord = v.uvco[0], 1.0 - v.uvco[1]
|
|
||||||
uvcoord_key = rvec2d(uvcoord)
|
|
||||||
|
|
||||||
if vertexColors:
|
|
||||||
color = col[j]
|
|
||||||
color = int(color[0] * 255.0), int(color[1] * 255.0), int(color[2] * 255.0)
|
|
||||||
|
|
||||||
|
|
||||||
key = normal_key, uvcoord_key, color
|
|
||||||
|
|
||||||
vdict_local = vdict[vidx]
|
|
||||||
pf_vidx = vdict_local.get(key) # Will be None initially
|
|
||||||
|
|
||||||
if pf_vidx == None: # same as vdict_local.has_key(key)
|
|
||||||
pf_vidx = vdict_local[key] = vert_count
|
|
||||||
ply_verts.append((vidx, normal, uvcoord, color))
|
|
||||||
vert_count += 1
|
|
||||||
|
|
||||||
pf.append(pf_vidx)
|
|
||||||
|
|
||||||
file.write('ply\n')
|
|
||||||
file.write('format ascii 1.0\n')
|
|
||||||
file.write('comment Created by Blender %s - www.blender.org, source file: %s\n' % (bpy.app.version_string, bpy.data.filepath.split('/')[-1].split('\\')[-1]))
|
|
||||||
|
|
||||||
file.write('element vertex %d\n' % len(ply_verts))
|
|
||||||
|
|
||||||
file.write('property float x\n')
|
|
||||||
file.write('property float y\n')
|
|
||||||
file.write('property float z\n')
|
|
||||||
|
|
||||||
if EXPORT_NORMALS:
|
|
||||||
file.write('property float nx\n')
|
|
||||||
file.write('property float ny\n')
|
|
||||||
file.write('property float nz\n')
|
|
||||||
if EXPORT_UV:
|
|
||||||
file.write('property float s\n')
|
|
||||||
file.write('property float t\n')
|
|
||||||
if EXPORT_COLORS:
|
|
||||||
file.write('property uchar red\n')
|
|
||||||
file.write('property uchar green\n')
|
|
||||||
file.write('property uchar blue\n')
|
|
||||||
|
|
||||||
file.write('element face %d\n' % len(mesh.faces))
|
|
||||||
file.write('property list uchar uint vertex_indices\n')
|
|
||||||
file.write('end_header\n')
|
|
||||||
|
|
||||||
for i, v in enumerate(ply_verts):
|
|
||||||
file.write('%.6f %.6f %.6f ' % tuple(mesh_verts[v[0]].co)) # co
|
|
||||||
if EXPORT_NORMALS:
|
|
||||||
file.write('%.6f %.6f %.6f ' % v[1]) # no
|
|
||||||
if EXPORT_UV:
|
|
||||||
file.write('%.6f %.6f ' % v[2]) # uv
|
|
||||||
if EXPORT_COLORS:
|
|
||||||
file.write('%u %u %u' % v[3]) # col
|
|
||||||
file.write('\n')
|
|
||||||
|
|
||||||
for pf in ply_faces:
|
|
||||||
if len(pf) == 3:
|
|
||||||
file.write('3 %d %d %d\n' % tuple(pf))
|
|
||||||
else:
|
|
||||||
file.write('4 %d %d %d %d\n' % tuple(pf))
|
|
||||||
|
|
||||||
file.close()
|
|
||||||
print("writing", filename, "done")
|
|
||||||
|
|
||||||
if EXPORT_APPLY_MODIFIERS:
|
|
||||||
bpy.data.meshes.remove(mesh)
|
|
||||||
|
|
||||||
# XXX
|
|
||||||
"""
|
|
||||||
if is_editmode:
|
|
||||||
Blender.Window.EditMode(1, '', 0)
|
|
||||||
"""
|
|
||||||
|
|
||||||
from bpy.props import *
|
|
||||||
|
|
||||||
|
|
||||||
class ExportPLY(bpy.types.Operator):
|
|
||||||
'''Export a single object as a stanford PLY with normals, colours and texture coordinates.'''
|
|
||||||
bl_idname = "export.ply"
|
|
||||||
bl_label = "Export PLY"
|
|
||||||
|
|
||||||
# List of operator properties, the attributes will be assigned
|
|
||||||
# to the class instance from the operator settings before calling.
|
|
||||||
|
|
||||||
|
|
||||||
filepath = StringProperty(name="File Path", description="Filepath used for exporting the PLY file", maxlen=1024, default="")
|
|
||||||
check_existing = BoolProperty(name="Check Existing", description="Check and warn on overwriting existing files", default=True, options={'HIDDEN'})
|
|
||||||
use_modifiers = BoolProperty(name="Apply Modifiers", description="Apply Modifiers to the exported mesh", default=True)
|
|
||||||
use_normals = BoolProperty(name="Normals", description="Export Normals for smooth and hard shaded faces", default=True)
|
|
||||||
use_uvs = BoolProperty(name="UVs", description="Exort the active UV layer", default=True)
|
|
||||||
use_colors = BoolProperty(name="Vertex Colors", description="Exort the active vertex color layer", default=True)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def poll(cls, context):
|
|
||||||
return context.active_object != None
|
|
||||||
|
|
||||||
def execute(self, context):
|
|
||||||
filepath = self.properties.filepath
|
|
||||||
filepath = bpy.path.ensure_ext(filepath, ".ply")
|
|
||||||
|
|
||||||
write(filepath, context.scene, context.active_object,\
|
|
||||||
EXPORT_APPLY_MODIFIERS=self.properties.use_modifiers,
|
|
||||||
EXPORT_NORMALS=self.properties.use_normals,
|
|
||||||
EXPORT_UV=self.properties.use_uvs,
|
|
||||||
EXPORT_COLORS=self.properties.use_colors,
|
|
||||||
)
|
|
||||||
|
|
||||||
return {'FINISHED'}
|
|
||||||
|
|
||||||
def invoke(self, context, event):
|
|
||||||
import os
|
|
||||||
if not self.properties.is_property_set("filepath"):
|
|
||||||
self.properties.filepath = os.path.splitext(bpy.data.filepath)[0] + ".ply"
|
|
||||||
|
|
||||||
context.manager.add_fileselect(self)
|
|
||||||
return {'RUNNING_MODAL'}
|
|
||||||
|
|
||||||
def draw(self, context):
|
|
||||||
layout = self.layout
|
|
||||||
props = self.properties
|
|
||||||
|
|
||||||
row = layout.row()
|
|
||||||
row.prop(props, "use_modifiers")
|
|
||||||
row.prop(props, "use_normals")
|
|
||||||
row = layout.row()
|
|
||||||
row.prop(props, "use_uvs")
|
|
||||||
row.prop(props, "use_colors")
|
|
||||||
|
|
||||||
|
|
||||||
def menu_func(self, context):
|
|
||||||
self.layout.operator(ExportPLY.bl_idname, text="Stanford (.ply)")
|
|
||||||
|
|
||||||
|
|
||||||
def register():
|
|
||||||
bpy.types.INFO_MT_file_export.append(menu_func)
|
|
||||||
|
|
||||||
|
|
||||||
def unregister():
|
|
||||||
bpy.types.INFO_MT_file_export.remove(menu_func)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
register()
|
|
||||||
@@ -1,154 +0,0 @@
|
|||||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or
|
|
||||||
# modify it under the terms of the GNU General Public License
|
|
||||||
# as published by the Free Software Foundation; either version 2
|
|
||||||
# of the License, or (at your option) any later version.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software Foundation,
|
|
||||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
#
|
|
||||||
# ***** END GPL LICENCE BLOCK *****
|
|
||||||
|
|
||||||
# <pep8 compliant>
|
|
||||||
|
|
||||||
# mdd importer by Bill L.Nieuwendorp
|
|
||||||
# conversion to blender 2.5: Ivo Grigull (loolarge)
|
|
||||||
#
|
|
||||||
# Warning if the vertex order or vertex count differs from the
|
|
||||||
# origonal model the mdd was Baked out from their will be Strange
|
|
||||||
# behavior
|
|
||||||
#
|
|
||||||
# vertex animation to ShapeKeys with ipo and gives the frame a value of 1.0
|
|
||||||
# A modifier to read mdd files would be Ideal but thats for another day :)
|
|
||||||
#
|
|
||||||
# Please send any fixes,updates,bugs to Slow67_at_Gmail.com
|
|
||||||
# Bill Niewuendorp
|
|
||||||
|
|
||||||
import bpy
|
|
||||||
from struct import unpack
|
|
||||||
|
|
||||||
|
|
||||||
def mdd_import(filepath, ob, scene, PREF_START_FRAME=0, PREF_JUMP=1):
|
|
||||||
|
|
||||||
print('\n\nimporting mdd "%s"' % filepath)
|
|
||||||
|
|
||||||
bpy.ops.object.mode_set(mode='OBJECT')
|
|
||||||
|
|
||||||
file = open(filepath, 'rb')
|
|
||||||
frames, points = unpack(">2i", file.read(8))
|
|
||||||
time = unpack((">%df" % frames), file.read(frames * 4))
|
|
||||||
|
|
||||||
print('\tpoints:%d frames:%d' % (points, frames))
|
|
||||||
|
|
||||||
# If target object doesn't have Basis shape key, create it.
|
|
||||||
try:
|
|
||||||
num_keys = len(ob.data.shape_keys.keys)
|
|
||||||
except:
|
|
||||||
basis = ob.add_shape_key()
|
|
||||||
basis.name = "Basis"
|
|
||||||
ob.data.update()
|
|
||||||
|
|
||||||
scene.frame_current = PREF_START_FRAME
|
|
||||||
|
|
||||||
def UpdateMesh(ob, fr):
|
|
||||||
|
|
||||||
# Insert new shape key
|
|
||||||
new_shapekey = ob.add_shape_key()
|
|
||||||
new_shapekey.name = ("frame_%.4d" % fr)
|
|
||||||
new_shapekey_name = new_shapekey.name
|
|
||||||
|
|
||||||
ob.active_shape_key_index = len(ob.data.shape_keys.keys)-1
|
|
||||||
index = len(ob.data.shape_keys.keys)-1
|
|
||||||
ob.show_shape_key = True
|
|
||||||
|
|
||||||
verts = ob.data.shape_keys.keys[len(ob.data.shape_keys.keys)-1].data
|
|
||||||
|
|
||||||
|
|
||||||
for v in verts: # 12 is the size of 3 floats
|
|
||||||
v.co[:] = unpack('>3f', file.read(12))
|
|
||||||
#me.update()
|
|
||||||
ob.show_shape_key = False
|
|
||||||
|
|
||||||
|
|
||||||
# insert keyframes
|
|
||||||
shape_keys = ob.data.shape_keys
|
|
||||||
|
|
||||||
scene.frame_current -= 1
|
|
||||||
ob.data.shape_keys.keys[index].value = 0.0
|
|
||||||
shape_keys.keys[len(ob.data.shape_keys.keys)-1].keyframe_insert("value")
|
|
||||||
|
|
||||||
scene.frame_current += 1
|
|
||||||
ob.data.shape_keys.keys[index].value = 1.0
|
|
||||||
shape_keys.keys[len(ob.data.shape_keys.keys)-1].keyframe_insert("value")
|
|
||||||
|
|
||||||
scene.frame_current += 1
|
|
||||||
ob.data.shape_keys.keys[index].value = 0.0
|
|
||||||
shape_keys.keys[len(ob.data.shape_keys.keys)-1].keyframe_insert("value")
|
|
||||||
|
|
||||||
ob.data.update()
|
|
||||||
|
|
||||||
|
|
||||||
for i in range(frames):
|
|
||||||
UpdateMesh(ob, i)
|
|
||||||
|
|
||||||
|
|
||||||
from bpy.props import *
|
|
||||||
|
|
||||||
|
|
||||||
class importMDD(bpy.types.Operator):
|
|
||||||
'''Import MDD vertex keyframe file to shape keys'''
|
|
||||||
bl_idname = "import_shape.mdd"
|
|
||||||
bl_label = "Import MDD"
|
|
||||||
|
|
||||||
# get first scene to get min and max properties for frames, fps
|
|
||||||
|
|
||||||
minframe = 1
|
|
||||||
maxframe = 300000
|
|
||||||
minfps = 1
|
|
||||||
maxfps = 120
|
|
||||||
|
|
||||||
# List of operator properties, the attributes will be assigned
|
|
||||||
# to the class instance from the operator settings before calling.
|
|
||||||
filepath = StringProperty(name="File Path", description="Filepath used for importing the MDD file", maxlen=1024)
|
|
||||||
#fps = IntProperty(name="Frames Per Second", description="Number of frames/second", min=minfps, max=maxfps, default=25)
|
|
||||||
frame_start = IntProperty(name="Start Frame", description="Start frame for inserting animation", min=minframe, max=maxframe, default=0)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def poll(cls, context):
|
|
||||||
ob = context.active_object
|
|
||||||
return (ob and ob.type == 'MESH')
|
|
||||||
|
|
||||||
def execute(self, context):
|
|
||||||
if not self.properties.filepath:
|
|
||||||
raise Exception("filename not set")
|
|
||||||
|
|
||||||
mdd_import(self.properties.filepath, bpy.context.active_object, context.scene, self.properties.frame_start, 1)
|
|
||||||
|
|
||||||
return {'FINISHED'}
|
|
||||||
|
|
||||||
def invoke(self, context, event):
|
|
||||||
wm = context.manager
|
|
||||||
wm.add_fileselect(self)
|
|
||||||
return {'RUNNING_MODAL'}
|
|
||||||
|
|
||||||
|
|
||||||
def menu_func(self, context):
|
|
||||||
self.layout.operator(importMDD.bl_idname, text="Lightwave Point Cache (.mdd)")
|
|
||||||
|
|
||||||
|
|
||||||
def register():
|
|
||||||
bpy.types.INFO_MT_file_import.append(menu_func)
|
|
||||||
|
|
||||||
|
|
||||||
def unregister():
|
|
||||||
bpy.types.INFO_MT_file_import.remove(menu_func)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
register()
|
|
||||||
@@ -19,9 +19,7 @@
|
|||||||
# This directory is a Python package.
|
# This directory is a Python package.
|
||||||
|
|
||||||
# To support reload properly, try to access a package var, if it's there, reload everything
|
# To support reload properly, try to access a package var, if it's there, reload everything
|
||||||
try:
|
if "bpy" in locals():
|
||||||
init_data
|
|
||||||
|
|
||||||
reload(model)
|
reload(model)
|
||||||
reload(operators)
|
reload(operators)
|
||||||
reload(client)
|
reload(client)
|
||||||
@@ -32,7 +30,7 @@ try:
|
|||||||
reload(balancing)
|
reload(balancing)
|
||||||
reload(ui)
|
reload(ui)
|
||||||
reload(repath)
|
reload(repath)
|
||||||
except:
|
else:
|
||||||
from netrender import model
|
from netrender import model
|
||||||
from netrender import operators
|
from netrender import operators
|
||||||
from netrender import client
|
from netrender import client
|
||||||
@@ -49,7 +47,6 @@ slaves = []
|
|||||||
blacklist = []
|
blacklist = []
|
||||||
|
|
||||||
init_file = ""
|
init_file = ""
|
||||||
init_data = True
|
|
||||||
init_address = True
|
init_address = True
|
||||||
|
|
||||||
def register():
|
def register():
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ from _bpy import ops as ops_module
|
|||||||
|
|
||||||
# op_add = ops_module.add
|
# op_add = ops_module.add
|
||||||
op_dir = ops_module.dir
|
op_dir = ops_module.dir
|
||||||
|
op_poll = ops_module.poll
|
||||||
op_call = ops_module.call
|
op_call = ops_module.call
|
||||||
op_as_string = ops_module.as_string
|
op_as_string = ops_module.as_string
|
||||||
op_get_rna = ops_module.get_rna
|
op_get_rna = ops_module.get_rna
|
||||||
@@ -120,6 +121,9 @@ class bpy_ops_submodule_op(object):
|
|||||||
self.module = module
|
self.module = module
|
||||||
self.func = func
|
self.func = func
|
||||||
|
|
||||||
|
def poll(self, context=None):
|
||||||
|
return op_poll(self.idname_py(), context)
|
||||||
|
|
||||||
def idname(self):
|
def idname(self):
|
||||||
# submod.foo -> SUBMOD_OT_foo
|
# submod.foo -> SUBMOD_OT_foo
|
||||||
return self.module.upper() + "_OT_" + self.func
|
return self.module.upper() + "_OT_" + self.func
|
||||||
|
|||||||
102
release/scripts/modules/io_utils.py
Normal file
102
release/scripts/modules/io_utils.py
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
# ##### BEGIN GPL LICENSE BLOCK #####
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software Foundation,
|
||||||
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
#
|
||||||
|
# ##### END GPL LICENSE BLOCK #####
|
||||||
|
|
||||||
|
# <pep8 compliant>
|
||||||
|
|
||||||
|
import bpy
|
||||||
|
from bpy.props import *
|
||||||
|
|
||||||
|
class ExportHelper:
|
||||||
|
filepath = StringProperty(name="File Path", description="Filepath used for exporting the file", maxlen= 1024, default= "", subtype='FILE_PATH')
|
||||||
|
check_existing = BoolProperty(name="Check Existing", description="Check and warn on overwriting existing files", default=True, options={'HIDDEN'})
|
||||||
|
|
||||||
|
def invoke(self, context, event):
|
||||||
|
import os
|
||||||
|
if not self.properties.is_property_set("filepath"):
|
||||||
|
self.properties.filepath = os.path.splitext(context.blend_data.filepath)[0] + self.filename_ext
|
||||||
|
|
||||||
|
context.window_manager.add_fileselect(self)
|
||||||
|
return {'RUNNING_MODAL'}
|
||||||
|
|
||||||
|
|
||||||
|
class ImportHelper:
|
||||||
|
filepath = StringProperty(name="File Path", description="Filepath used for importing the file", maxlen= 1024, default= "", subtype='FILE_PATH')
|
||||||
|
|
||||||
|
def invoke(self, context, event):
|
||||||
|
context.window_manager.add_fileselect(self)
|
||||||
|
return {'RUNNING_MODAL'}
|
||||||
|
|
||||||
|
|
||||||
|
# limited replacement for BPyImage.comprehensiveImageLoad
|
||||||
|
def load_image(imagepath, dirname):
|
||||||
|
import os
|
||||||
|
|
||||||
|
if os.path.exists(imagepath):
|
||||||
|
return bpy.data.images.load(imagepath)
|
||||||
|
|
||||||
|
variants = [imagepath, os.path.join(dirname, imagepath), os.path.join(dirname, os.path.basename(imagepath))]
|
||||||
|
|
||||||
|
for filepath in variants:
|
||||||
|
for nfilepath in (filepath, bpy.path.resolve_ncase(filepath)):
|
||||||
|
if os.path.exists(nfilepath):
|
||||||
|
return bpy.data.images.load(nfilepath)
|
||||||
|
|
||||||
|
# TODO comprehensiveImageLoad also searched in bpy.config.textureDir
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
# return a tuple (free, object list), free is True if memory should be freed later with free_derived_objects()
|
||||||
|
def create_derived_objects(scene, ob):
|
||||||
|
if ob.parent and ob.parent.dupli_type != 'NONE':
|
||||||
|
return False, None
|
||||||
|
|
||||||
|
if ob.dupli_type != 'NONE':
|
||||||
|
ob.create_dupli_list(scene)
|
||||||
|
return True, [(dob.object, dob.matrix) for dob in ob.dupli_list]
|
||||||
|
else:
|
||||||
|
return False, [(ob, ob.matrix_world)]
|
||||||
|
|
||||||
|
|
||||||
|
def free_derived_objects(ob):
|
||||||
|
ob.free_dupli_list()
|
||||||
|
|
||||||
|
|
||||||
|
def unpack_list(list_of_tuples):
|
||||||
|
flat_list = []
|
||||||
|
flat_list_extend = flat_list.extend # a tich faster
|
||||||
|
for t in list_of_tuples:
|
||||||
|
flat_list_extend(t)
|
||||||
|
return flat_list
|
||||||
|
|
||||||
|
# same as above except that it adds 0 for triangle faces
|
||||||
|
def unpack_face_list(list_of_tuples):
|
||||||
|
# allocate the entire list
|
||||||
|
flat_ls = [0] * (len(list_of_tuples) * 4)
|
||||||
|
i = 0
|
||||||
|
|
||||||
|
for t in list_of_tuples:
|
||||||
|
if len(t) == 3:
|
||||||
|
if t[2] == 0:
|
||||||
|
t = t[1], t[2], t[0]
|
||||||
|
else: # assuem quad
|
||||||
|
if t[3] == 0 or t[2] == 0:
|
||||||
|
t = t[2], t[3], t[0], t[1]
|
||||||
|
|
||||||
|
flat_ls[i:i + len(t)] = t
|
||||||
|
i += 4
|
||||||
|
return flat_ls
|
||||||
@@ -84,6 +84,8 @@ def draw(layout, context, context_member, use_edit=True):
|
|||||||
props.data_path = context_member
|
props.data_path = context_member
|
||||||
del row
|
del row
|
||||||
|
|
||||||
|
rna_properties = {prop.identifier for prop in rna_item.bl_rna.properties if prop.is_runtime} if items else None
|
||||||
|
|
||||||
for key, val in items:
|
for key, val in items:
|
||||||
|
|
||||||
if key == '_RNA_UI':
|
if key == '_RNA_UI':
|
||||||
@@ -113,7 +115,10 @@ def draw(layout, context, context_member, use_edit=True):
|
|||||||
if convert_to_pyobject and not hasattr(val_orig, "len"):
|
if convert_to_pyobject and not hasattr(val_orig, "len"):
|
||||||
row.label(text=val_draw)
|
row.label(text=val_draw)
|
||||||
else:
|
else:
|
||||||
row.prop(rna_item, '["%s"]' % key, text="")
|
if key in rna_properties:
|
||||||
|
row.prop(rna_item, key, text="")
|
||||||
|
else:
|
||||||
|
row.prop(rna_item, '["%s"]' % key, text="")
|
||||||
|
|
||||||
if use_edit:
|
if use_edit:
|
||||||
row = split.row(align=True)
|
row = split.row(align=True)
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ class AddTorus(bpy.types.Operator):
|
|||||||
|
|
||||||
|
|
||||||
def menu_func(self, context):
|
def menu_func(self, context):
|
||||||
self.layout.operator(AddTorus.bl_idname, text="Torus", icon='MESH_DONUT')
|
self.layout.operator(AddTorus.bl_idname, text="Torus", icon='MESH_TORUS')
|
||||||
|
|
||||||
|
|
||||||
def register():
|
def register():
|
||||||
|
|||||||
@@ -681,7 +681,7 @@ import bpy
|
|||||||
|
|
||||||
|
|
||||||
class UpdateAnimData(bpy.types.Operator):
|
class UpdateAnimData(bpy.types.Operator):
|
||||||
''''''
|
'''Update data paths from 2.53 to edited data paths of drivers and fcurves'''
|
||||||
bl_idname = "anim.update_data_paths"
|
bl_idname = "anim.update_data_paths"
|
||||||
bl_label = "Update Animation Data"
|
bl_label = "Update Animation Data"
|
||||||
|
|
||||||
@@ -696,4 +696,4 @@ if __name__ == "__main__":
|
|||||||
bpy.ops.anim.update_data_paths()
|
bpy.ops.anim.update_data_paths()
|
||||||
|
|
||||||
def register():
|
def register():
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ def get_console(console_id):
|
|||||||
from code import InteractiveConsole
|
from code import InteractiveConsole
|
||||||
|
|
||||||
consoles = getattr(get_console, "consoles", None)
|
consoles = getattr(get_console, "consoles", None)
|
||||||
hash_next = hash(bpy.context.manager)
|
hash_next = hash(bpy.context.window_manager)
|
||||||
|
|
||||||
if consoles is None:
|
if consoles is None:
|
||||||
consoles = get_console.consoles = {}
|
consoles = get_console.consoles = {}
|
||||||
|
|||||||
74
release/scripts/op/io_anim_bvh/__init__.py
Normal file
74
release/scripts/op/io_anim_bvh/__init__.py
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
# ##### BEGIN GPL LICENSE BLOCK #####
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software Foundation,
|
||||||
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
#
|
||||||
|
# ##### END GPL LICENSE BLOCK #####
|
||||||
|
|
||||||
|
# <pep8 compliant>
|
||||||
|
|
||||||
|
# To support reload properly, try to access a package var, if it's there, reload everything
|
||||||
|
if "bpy" in locals():
|
||||||
|
# only reload if we alredy loaded, highly annoying
|
||||||
|
import sys
|
||||||
|
reload(sys.modules.get("io_mesh_ply.export_ply", sys))
|
||||||
|
|
||||||
|
|
||||||
|
import bpy
|
||||||
|
from bpy.props import *
|
||||||
|
from io_utils import ImportHelper
|
||||||
|
|
||||||
|
|
||||||
|
class BvhImporter(bpy.types.Operator, ImportHelper):
|
||||||
|
'''Load a OBJ Motion Capture File'''
|
||||||
|
bl_idname = "import_anim.bvh"
|
||||||
|
bl_label = "Import BVH"
|
||||||
|
|
||||||
|
filename_ext = ".bvh"
|
||||||
|
|
||||||
|
scale = FloatProperty(name="Scale", description="Scale the BVH by this value", min=0.0001, max=1000000.0, soft_min=0.001, soft_max=100.0, default=0.1)
|
||||||
|
frame_start = IntProperty(name="Start Frame", description="Starting frame for the animation", default=1)
|
||||||
|
loop = BoolProperty(name="Loop", description="Loop the animation playback", default=False)
|
||||||
|
rotate_mode = EnumProperty(items=(
|
||||||
|
('QUATERNION', "Quaternion", "Convert rotations to quaternions"),
|
||||||
|
('NATIVE', "Euler (Native)", "Use the rotation order defined in the BVH file"),
|
||||||
|
('XYZ', "Euler (XYZ)", "Convert rotations to euler XYZ"),
|
||||||
|
('XZY', "Euler (XZY)", "Convert rotations to euler XZY"),
|
||||||
|
('YXZ', "Euler (YXZ)", "Convert rotations to euler YXZ"),
|
||||||
|
('YZX', "Euler (YZX)", "Convert rotations to euler YZX"),
|
||||||
|
('ZXY', "Euler (ZXY)", "Convert rotations to euler ZXY"),
|
||||||
|
('ZYX', "Euler (ZYX)", "Convert rotations to euler ZYX"),
|
||||||
|
),
|
||||||
|
name="Rotation",
|
||||||
|
description="Rotation conversion.",
|
||||||
|
default='NATIVE')
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
import io_anim_bvh.import_bvh
|
||||||
|
return io_anim_bvh.import_bvh.load(self, context, **self.properties)
|
||||||
|
|
||||||
|
|
||||||
|
def menu_func(self, context):
|
||||||
|
self.layout.operator(BvhImporter.bl_idname, text="Motion Capture (.bvh)")
|
||||||
|
|
||||||
|
|
||||||
|
def register():
|
||||||
|
bpy.types.INFO_MT_file_import.append(menu_func)
|
||||||
|
|
||||||
|
|
||||||
|
def unregister():
|
||||||
|
bpy.types.INFO_MT_file_import.remove(menu_func)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
register()
|
||||||
@@ -18,6 +18,8 @@
|
|||||||
|
|
||||||
# <pep8 compliant>
|
# <pep8 compliant>
|
||||||
|
|
||||||
|
# Script copyright (C) Campbell Barton
|
||||||
|
|
||||||
import math
|
import math
|
||||||
from math import radians
|
from math import radians
|
||||||
|
|
||||||
@@ -349,7 +351,7 @@ def bvh_node_dict2armature(context, bvh_nodes, ROT_MODE='XYZ', IMPORT_START_FRAM
|
|||||||
for ob in scn.objects:
|
for ob in scn.objects:
|
||||||
ob.select = False
|
ob.select = False
|
||||||
|
|
||||||
scn.set_frame(IMPORT_START_FRAME)
|
scn.frame_set(IMPORT_START_FRAME)
|
||||||
|
|
||||||
arm_data = bpy.data.armatures.new("MyBVH")
|
arm_data = bpy.data.armatures.new("MyBVH")
|
||||||
arm_ob = bpy.data.objects.new("MyBVH", arm_data)
|
arm_ob = bpy.data.objects.new("MyBVH", arm_data)
|
||||||
@@ -553,70 +555,24 @@ def bvh_node_dict2armature(context, bvh_nodes, ROT_MODE='XYZ', IMPORT_START_FRAM
|
|||||||
return arm_ob
|
return arm_ob
|
||||||
|
|
||||||
|
|
||||||
from bpy.props import *
|
def load(operator, context, filepath="", rotate_mode='NATIVE', scale=1.0, use_cyclic=False, frame_start=1):
|
||||||
|
import time
|
||||||
|
t1 = time.time()
|
||||||
|
print('\tparsing bvh %r...' % filepath, end="")
|
||||||
|
|
||||||
|
bvh_nodes = read_bvh(context, filepath,
|
||||||
|
ROT_MODE=rotate_mode,
|
||||||
|
GLOBAL_SCALE=scale)
|
||||||
|
|
||||||
class BvhImporter(bpy.types.Operator):
|
print('%.4f' % (time.time() - t1))
|
||||||
'''Load a OBJ Motion Capture File'''
|
t1 = time.time()
|
||||||
bl_idname = "import_anim.bvh"
|
print('\timporting to blender...', end="")
|
||||||
bl_label = "Import BVH"
|
|
||||||
|
|
||||||
filepath = StringProperty(name="File Path", description="Filepath used for importing the OBJ file", maxlen=1024, default="")
|
bvh_node_dict2armature(context, bvh_nodes,
|
||||||
scale = FloatProperty(name="Scale", description="Scale the BVH by this value", min=0.0001, max=1000000.0, soft_min=0.001, soft_max=100.0, default=0.1)
|
ROT_MODE=rotate_mode,
|
||||||
frame_start = IntProperty(name="Start Frame", description="Starting frame for the animation", default=1)
|
IMPORT_START_FRAME=frame_start,
|
||||||
loop = BoolProperty(name="Loop", description="Loop the animation playback", default=False)
|
IMPORT_LOOP=use_cyclic)
|
||||||
rotate_mode = EnumProperty(items=(
|
|
||||||
('QUATERNION', "Quaternion", "Convert rotations to quaternions"),
|
|
||||||
('NATIVE', "Euler (Native)", "Use the rotation order defined in the BVH file"),
|
|
||||||
('XYZ', "Euler (XYZ)", "Convert rotations to euler XYZ"),
|
|
||||||
('XZY', "Euler (XZY)", "Convert rotations to euler XZY"),
|
|
||||||
('YXZ', "Euler (YXZ)", "Convert rotations to euler YXZ"),
|
|
||||||
('YZX', "Euler (YZX)", "Convert rotations to euler YZX"),
|
|
||||||
('ZXY', "Euler (ZXY)", "Convert rotations to euler ZXY"),
|
|
||||||
('ZYX', "Euler (ZYX)", "Convert rotations to euler ZYX"),
|
|
||||||
),
|
|
||||||
name="Rotation",
|
|
||||||
description="Rotation conversion.",
|
|
||||||
default='NATIVE')
|
|
||||||
|
|
||||||
def execute(self, context):
|
print('Done in %.4f\n' % (time.time() - t1))
|
||||||
# print("Selected: " + context.active_object.name)
|
|
||||||
import time
|
return {'FINISHED'}
|
||||||
t1 = time.time()
|
|
||||||
print('\tparsing bvh...', end="")
|
|
||||||
|
|
||||||
bvh_nodes = read_bvh(context, self.properties.filepath,
|
|
||||||
ROT_MODE=self.properties.rotate_mode,
|
|
||||||
GLOBAL_SCALE=self.properties.scale)
|
|
||||||
|
|
||||||
print('%.4f' % (time.time() - t1))
|
|
||||||
t1 = time.time()
|
|
||||||
print('\timporting to blender...', end="")
|
|
||||||
|
|
||||||
bvh_node_dict2armature(context, bvh_nodes,
|
|
||||||
ROT_MODE=self.properties.rotate_mode,
|
|
||||||
IMPORT_START_FRAME=self.properties.frame_start,
|
|
||||||
IMPORT_LOOP=self.properties.loop)
|
|
||||||
|
|
||||||
print('Done in %.4f\n' % (time.time() - t1))
|
|
||||||
return {'FINISHED'}
|
|
||||||
|
|
||||||
def invoke(self, context, event):
|
|
||||||
wm = context.manager
|
|
||||||
wm.add_fileselect(self)
|
|
||||||
return {'RUNNING_MODAL'}
|
|
||||||
|
|
||||||
|
|
||||||
def menu_func(self, context):
|
|
||||||
self.layout.operator(BvhImporter.bl_idname, text="Motion Capture (.bvh)")
|
|
||||||
|
|
||||||
|
|
||||||
def register():
|
|
||||||
bpy.types.INFO_MT_file_import.append(menu_func)
|
|
||||||
|
|
||||||
|
|
||||||
def unregister():
|
|
||||||
bpy.types.INFO_MT_file_import.remove(menu_func)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
register()
|
|
||||||
76
release/scripts/op/io_mesh_ply/__init__.py
Normal file
76
release/scripts/op/io_mesh_ply/__init__.py
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
# ##### BEGIN GPL LICENSE BLOCK #####
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software Foundation,
|
||||||
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
#
|
||||||
|
# ##### END GPL LICENSE BLOCK #####
|
||||||
|
|
||||||
|
# To support reload properly, try to access a package var, if it's there, reload everything
|
||||||
|
if "bpy" in locals():
|
||||||
|
import sys
|
||||||
|
reload(sys.modules.get("io_mesh_ply.export_ply", sys))
|
||||||
|
|
||||||
|
|
||||||
|
import bpy
|
||||||
|
from bpy.props import *
|
||||||
|
from io_utils import ExportHelper
|
||||||
|
|
||||||
|
|
||||||
|
class ExportPLY(bpy.types.Operator, ExportHelper):
|
||||||
|
'''Export a single object as a stanford PLY with normals, colours and texture coordinates.'''
|
||||||
|
bl_idname = "export.ply"
|
||||||
|
bl_label = "Export PLY"
|
||||||
|
|
||||||
|
filename_ext = ".ply"
|
||||||
|
|
||||||
|
use_modifiers = BoolProperty(name="Apply Modifiers", description="Apply Modifiers to the exported mesh", default=True)
|
||||||
|
use_normals = BoolProperty(name="Normals", description="Export Normals for smooth and hard shaded faces", default=True)
|
||||||
|
use_uv_coords = BoolProperty(name="UVs", description="Exort the active UV layer", default=True)
|
||||||
|
use_colors = BoolProperty(name="Vertex Colors", description="Exort the active vertex color layer", default=True)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def poll(cls, context):
|
||||||
|
return context.active_object != None
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
filepath = self.properties.filepath
|
||||||
|
filepath = bpy.path.ensure_ext(filepath, self.filename_ext)
|
||||||
|
import io_mesh_ply.export_ply
|
||||||
|
return io_mesh_ply.export_ply.save(self, context, **self.properties)
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
props = self.properties
|
||||||
|
|
||||||
|
row = layout.row()
|
||||||
|
row.prop(props, "use_modifiers")
|
||||||
|
row.prop(props, "use_normals")
|
||||||
|
row = layout.row()
|
||||||
|
row.prop(props, "use_uv_coords")
|
||||||
|
row.prop(props, "use_colors")
|
||||||
|
|
||||||
|
|
||||||
|
def menu_func(self, context):
|
||||||
|
self.layout.operator(ExportPLY.bl_idname, text="Stanford (.ply)")
|
||||||
|
|
||||||
|
|
||||||
|
def register():
|
||||||
|
bpy.types.INFO_MT_file_export.append(menu_func)
|
||||||
|
|
||||||
|
|
||||||
|
def unregister():
|
||||||
|
bpy.types.INFO_MT_file_export.remove(menu_func)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
register()
|
||||||
206
release/scripts/op/io_mesh_ply/export_ply.py
Normal file
206
release/scripts/op/io_mesh_ply/export_ply.py
Normal file
@@ -0,0 +1,206 @@
|
|||||||
|
# ##### BEGIN GPL LICENSE BLOCK #####
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software Foundation,
|
||||||
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
#
|
||||||
|
# ##### END GPL LICENSE BLOCK #####
|
||||||
|
|
||||||
|
# <pep8 compliant>
|
||||||
|
|
||||||
|
# Copyright (C) 2004, 2005: Bruce Merry, bmerry@cs.uct.ac.za
|
||||||
|
# Contributors: Bruce Merry, Campbell Barton
|
||||||
|
|
||||||
|
"""
|
||||||
|
This script exports Stanford PLY files from Blender. It supports normals,
|
||||||
|
colours, and texture coordinates per face or per vertex.
|
||||||
|
Only one mesh can be exported at a time.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import bpy
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
def save(operator, context, filepath="", use_modifiers=True, use_normals=True, use_uv_coords=True, use_colors=True):
|
||||||
|
|
||||||
|
def rvec3d(v):
|
||||||
|
return round(v[0], 6), round(v[1], 6), round(v[2], 6)
|
||||||
|
|
||||||
|
|
||||||
|
def rvec2d(v):
|
||||||
|
return round(v[0], 6), round(v[1], 6)
|
||||||
|
|
||||||
|
scene = context.scene
|
||||||
|
obj = context.object
|
||||||
|
|
||||||
|
if not obj:
|
||||||
|
raise Exception("Error, Select 1 active object")
|
||||||
|
|
||||||
|
file = open(filepath, 'w')
|
||||||
|
|
||||||
|
if scene.objects.active:
|
||||||
|
bpy.ops.object.mode_set(mode='OBJECT')
|
||||||
|
|
||||||
|
if use_modifiers:
|
||||||
|
mesh = obj.create_mesh(scene, True, 'PREVIEW')
|
||||||
|
else:
|
||||||
|
mesh = obj.data
|
||||||
|
|
||||||
|
if not mesh:
|
||||||
|
raise Exception("Error, could not get mesh data from active object")
|
||||||
|
|
||||||
|
# mesh.transform(obj.matrix_world) # XXX
|
||||||
|
|
||||||
|
faceUV = (len(mesh.uv_textures) > 0)
|
||||||
|
vertexUV = (len(mesh.sticky) > 0)
|
||||||
|
vertexColors = len(mesh.vertex_colors) > 0
|
||||||
|
|
||||||
|
if (not faceUV) and (not vertexUV):
|
||||||
|
use_uv_coords = False
|
||||||
|
if not vertexColors:
|
||||||
|
use_colors = False
|
||||||
|
|
||||||
|
if not use_uv_coords:
|
||||||
|
faceUV = vertexUV = False
|
||||||
|
if not use_colors:
|
||||||
|
vertexColors = False
|
||||||
|
|
||||||
|
if faceUV:
|
||||||
|
active_uv_layer = mesh.uv_textures.active
|
||||||
|
if not active_uv_layer:
|
||||||
|
use_uv_coords = False
|
||||||
|
faceUV = None
|
||||||
|
else:
|
||||||
|
active_uv_layer = active_uv_layer.data
|
||||||
|
|
||||||
|
if vertexColors:
|
||||||
|
active_col_layer = mesh.vertex_colors.active
|
||||||
|
if not active_col_layer:
|
||||||
|
use_colors = False
|
||||||
|
vertexColors = None
|
||||||
|
else:
|
||||||
|
active_col_layer = active_col_layer.data
|
||||||
|
|
||||||
|
# incase
|
||||||
|
color = uvcoord = uvcoord_key = normal = normal_key = None
|
||||||
|
|
||||||
|
mesh_verts = mesh.vertices # save a lookup
|
||||||
|
ply_verts = [] # list of dictionaries
|
||||||
|
# vdict = {} # (index, normal, uv) -> new index
|
||||||
|
vdict = [{} for i in range(len(mesh_verts))]
|
||||||
|
ply_faces = [[] for f in range(len(mesh.faces))]
|
||||||
|
vert_count = 0
|
||||||
|
for i, f in enumerate(mesh.faces):
|
||||||
|
|
||||||
|
|
||||||
|
smooth = f.use_smooth
|
||||||
|
if not smooth:
|
||||||
|
normal = tuple(f.normal)
|
||||||
|
normal_key = rvec3d(normal)
|
||||||
|
|
||||||
|
if faceUV:
|
||||||
|
uv = active_uv_layer[i]
|
||||||
|
uv = uv.uv1, uv.uv2, uv.uv3, uv.uv4 # XXX - crufty :/
|
||||||
|
if vertexColors:
|
||||||
|
col = active_col_layer[i]
|
||||||
|
col = col.color1, col.color2, col.color3, col.color4
|
||||||
|
|
||||||
|
f_verts = f.vertices
|
||||||
|
|
||||||
|
pf = ply_faces[i]
|
||||||
|
for j, vidx in enumerate(f_verts):
|
||||||
|
v = mesh_verts[vidx]
|
||||||
|
|
||||||
|
if smooth:
|
||||||
|
normal = tuple(v.normal)
|
||||||
|
normal_key = rvec3d(normal)
|
||||||
|
|
||||||
|
if faceUV:
|
||||||
|
uvcoord = uv[j][0], 1.0 - uv[j][1]
|
||||||
|
uvcoord_key = rvec2d(uvcoord)
|
||||||
|
elif vertexUV:
|
||||||
|
uvcoord = v.uvco[0], 1.0 - v.uvco[1]
|
||||||
|
uvcoord_key = rvec2d(uvcoord)
|
||||||
|
|
||||||
|
if vertexColors:
|
||||||
|
color = col[j]
|
||||||
|
color = int(color[0] * 255.0), int(color[1] * 255.0), int(color[2] * 255.0)
|
||||||
|
|
||||||
|
|
||||||
|
key = normal_key, uvcoord_key, color
|
||||||
|
|
||||||
|
vdict_local = vdict[vidx]
|
||||||
|
pf_vidx = vdict_local.get(key) # Will be None initially
|
||||||
|
|
||||||
|
if pf_vidx == None: # same as vdict_local.has_key(key)
|
||||||
|
pf_vidx = vdict_local[key] = vert_count
|
||||||
|
ply_verts.append((vidx, normal, uvcoord, color))
|
||||||
|
vert_count += 1
|
||||||
|
|
||||||
|
pf.append(pf_vidx)
|
||||||
|
|
||||||
|
file.write('ply\n')
|
||||||
|
file.write('format ascii 1.0\n')
|
||||||
|
file.write('comment Created by Blender %s - www.blender.org, source file: %r\n' % (bpy.app.version_string, os.path.basename(bpy.data.filepath)))
|
||||||
|
|
||||||
|
file.write('element vertex %d\n' % len(ply_verts))
|
||||||
|
|
||||||
|
file.write('property float x\n')
|
||||||
|
file.write('property float y\n')
|
||||||
|
file.write('property float z\n')
|
||||||
|
|
||||||
|
if use_normals:
|
||||||
|
file.write('property float nx\n')
|
||||||
|
file.write('property float ny\n')
|
||||||
|
file.write('property float nz\n')
|
||||||
|
if use_uv_coords:
|
||||||
|
file.write('property float s\n')
|
||||||
|
file.write('property float t\n')
|
||||||
|
if use_colors:
|
||||||
|
file.write('property uchar red\n')
|
||||||
|
file.write('property uchar green\n')
|
||||||
|
file.write('property uchar blue\n')
|
||||||
|
|
||||||
|
file.write('element face %d\n' % len(mesh.faces))
|
||||||
|
file.write('property list uchar uint vertex_indices\n')
|
||||||
|
file.write('end_header\n')
|
||||||
|
|
||||||
|
for i, v in enumerate(ply_verts):
|
||||||
|
file.write('%.6f %.6f %.6f ' % tuple(mesh_verts[v[0]].co)) # co
|
||||||
|
if use_normals:
|
||||||
|
file.write('%.6f %.6f %.6f ' % v[1]) # no
|
||||||
|
if use_uv_coords:
|
||||||
|
file.write('%.6f %.6f ' % v[2]) # uv
|
||||||
|
if use_colors:
|
||||||
|
file.write('%u %u %u' % v[3]) # col
|
||||||
|
file.write('\n')
|
||||||
|
|
||||||
|
for pf in ply_faces:
|
||||||
|
if len(pf) == 3:
|
||||||
|
file.write('3 %d %d %d\n' % tuple(pf))
|
||||||
|
else:
|
||||||
|
file.write('4 %d %d %d %d\n' % tuple(pf))
|
||||||
|
|
||||||
|
file.close()
|
||||||
|
print("writing %r done" % filepath)
|
||||||
|
|
||||||
|
if use_modifiers:
|
||||||
|
bpy.data.meshes.remove(mesh)
|
||||||
|
|
||||||
|
# XXX
|
||||||
|
"""
|
||||||
|
if is_editmode:
|
||||||
|
Blender.Window.EditMode(1, '', 0)
|
||||||
|
"""
|
||||||
|
|
||||||
|
return {'FINISHED'}
|
||||||
86
release/scripts/op/io_scene_3ds/__init__.py
Normal file
86
release/scripts/op/io_scene_3ds/__init__.py
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
# ##### BEGIN GPL LICENSE BLOCK #####
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software Foundation,
|
||||||
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
#
|
||||||
|
# ##### END GPL LICENSE BLOCK #####
|
||||||
|
|
||||||
|
# <pep8 compliant>
|
||||||
|
|
||||||
|
# To support reload properly, try to access a package var, if it's there, reload everything
|
||||||
|
if "bpy" in locals():
|
||||||
|
import sys
|
||||||
|
reload(sys.modules.get("io_scene_3ds.import_3ds", sys))
|
||||||
|
reload(sys.modules.get("io_scene_3ds.export_3ds", sys))
|
||||||
|
|
||||||
|
|
||||||
|
import bpy
|
||||||
|
from bpy.props import *
|
||||||
|
from io_utils import ImportHelper, ExportHelper
|
||||||
|
|
||||||
|
|
||||||
|
class Import3DS(bpy.types.Operator, ImportHelper):
|
||||||
|
'''Import from 3DS file format (.3ds)'''
|
||||||
|
bl_idname = "import_scene.autodesk_3ds"
|
||||||
|
bl_label = 'Import 3DS'
|
||||||
|
|
||||||
|
filename_ext = ".3ds"
|
||||||
|
|
||||||
|
constrain_size = FloatProperty(name="Size Constraint", description="Scale the model by 10 until it reacehs the size constraint. Zero Disables.", min=0.0, max=1000.0, soft_min=0.0, soft_max=1000.0, default=10.0)
|
||||||
|
use_image_search = BoolProperty(name="Image Search", description="Search subdirectories for any assosiated images (Warning, may be slow)", default=True)
|
||||||
|
use_apply_transform = BoolProperty(name="Apply Transform", description="Workaround for object transformations importing incorrectly", default=False)
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
import io_scene_3ds.import_3ds
|
||||||
|
return io_scene_3ds.import_3ds.load(self, context, **self.properties)
|
||||||
|
|
||||||
|
|
||||||
|
class Export3DS(bpy.types.Operator, ExportHelper):
|
||||||
|
'''Export to 3DS file format (.3ds)'''
|
||||||
|
bl_idname = "export_scene.autodesk_3ds"
|
||||||
|
bl_label = 'Export 3DS'
|
||||||
|
|
||||||
|
filename_ext = ".3ds"
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
import io_scene_3ds.export_3ds
|
||||||
|
return io_scene_3ds.export_3ds.save(self, context, **self.properties)
|
||||||
|
|
||||||
|
|
||||||
|
# Add to a menu
|
||||||
|
def menu_func_export(self, context):
|
||||||
|
self.layout.operator(Export3DS.bl_idname, text="3D Studio (.3ds)")
|
||||||
|
|
||||||
|
def menu_func_import(self, context):
|
||||||
|
self.layout.operator(Import3DS.bl_idname, text="3D Studio (.3ds)")
|
||||||
|
|
||||||
|
def register():
|
||||||
|
bpy.types.INFO_MT_file_import.append(menu_func_import)
|
||||||
|
bpy.types.INFO_MT_file_export.append(menu_func_export)
|
||||||
|
|
||||||
|
|
||||||
|
def unregister():
|
||||||
|
bpy.types.INFO_MT_file_import.remove(menu_func_import)
|
||||||
|
bpy.types.INFO_MT_file_export.remove(menu_func_export)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
register()
|
||||||
|
|
||||||
|
# NOTES:
|
||||||
|
# why add 1 extra vertex? and remove it when done? - "Answer - eekadoodle - would need to re-order UV's without this since face order isnt always what we give blender, BMesh will solve :D"
|
||||||
|
# disabled scaling to size, this requires exposing bb (easy) and understanding how it works (needs some time)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
register()
|
||||||
|
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
# coding: utf-8
|
|
||||||
# ##### BEGIN GPL LICENSE BLOCK #####
|
# ##### BEGIN GPL LICENSE BLOCK #####
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or
|
# This program is free software; you can redistribute it and/or
|
||||||
@@ -19,74 +18,74 @@
|
|||||||
|
|
||||||
# <pep8 compliant>
|
# <pep8 compliant>
|
||||||
|
|
||||||
__author__ = ["Campbell Barton", "Bob Holcomb", "Richard Lärkäng", "Damien McGinnes", "Mark Stijnman"]
|
# Script copyright (C) Bob Holcomb
|
||||||
__url__ = ("blenderartists.org", "www.blender.org", "www.gametutorials.com", "lib3ds.sourceforge.net/")
|
# Contributors: Campbell Barton, Bob Holcomb, Richard Lärkäng, Damien McGinnes, Mark Stijnman
|
||||||
__version__ = "0.90a"
|
|
||||||
__bpydoc__ = """\
|
|
||||||
|
|
||||||
3ds Exporter
|
|
||||||
|
|
||||||
This script Exports a 3ds file.
|
|
||||||
|
|
||||||
|
"""
|
||||||
Exporting is based on 3ds loader from www.gametutorials.com(Thanks DigiBen) and using information
|
Exporting is based on 3ds loader from www.gametutorials.com(Thanks DigiBen) and using information
|
||||||
from the lib3ds project (http://lib3ds.sourceforge.net/) sourcecode.
|
from the lib3ds project (http://lib3ds.sourceforge.net/) sourcecode.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
|
||||||
#
|
|
||||||
# Script copyright (C) Bob Holcomb
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or
|
|
||||||
# modify it under the terms of the GNU General Public License
|
|
||||||
# as published by the Free Software Foundation; either version 2
|
|
||||||
# of the License, or (at your option) any later version.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software Foundation,
|
|
||||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
#
|
|
||||||
# ***** END GPL LICENCE BLOCK *****
|
|
||||||
# --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
######################################################
|
######################################################
|
||||||
# Importing modules
|
# Data Structures
|
||||||
######################################################
|
######################################################
|
||||||
|
|
||||||
|
#Some of the chunks that we will export
|
||||||
|
#----- Primary Chunk, at the beginning of each file
|
||||||
|
PRIMARY= 0x4D4D
|
||||||
|
|
||||||
|
#------ Main Chunks
|
||||||
|
OBJECTINFO = 0x3D3D #This gives the version of the mesh and is found right before the material and object information
|
||||||
|
VERSION = 0x0002 #This gives the version of the .3ds file
|
||||||
|
KFDATA = 0xB000 #This is the header for all of the key frame info
|
||||||
|
|
||||||
|
#------ sub defines of OBJECTINFO
|
||||||
|
MATERIAL=45055 #0xAFFF // This stored the texture info
|
||||||
|
OBJECT=16384 #0x4000 // This stores the faces, vertices, etc...
|
||||||
|
|
||||||
|
#>------ sub defines of MATERIAL
|
||||||
|
MATNAME = 0xA000 # This holds the material name
|
||||||
|
MATAMBIENT = 0xA010 # Ambient color of the object/material
|
||||||
|
MATDIFFUSE = 0xA020 # This holds the color of the object/material
|
||||||
|
MATSPECULAR = 0xA030 # SPecular color of the object/material
|
||||||
|
MATSHINESS = 0xA040 # ??
|
||||||
|
MATMAP = 0xA200 # This is a header for a new material
|
||||||
|
MATMAPFILE = 0xA300 # This holds the file name of the texture
|
||||||
|
|
||||||
|
RGB1= 0x0011
|
||||||
|
RGB2= 0x0012
|
||||||
|
|
||||||
|
#>------ sub defines of OBJECT
|
||||||
|
OBJECT_MESH = 0x4100 # This lets us know that we are reading a new object
|
||||||
|
OBJECT_LIGHT = 0x4600 # This lets un know we are reading a light object
|
||||||
|
OBJECT_CAMERA= 0x4700 # This lets un know we are reading a camera object
|
||||||
|
|
||||||
|
#>------ sub defines of CAMERA
|
||||||
|
OBJECT_CAM_RANGES= 0x4720 # The camera range values
|
||||||
|
|
||||||
|
#>------ sub defines of OBJECT_MESH
|
||||||
|
OBJECT_VERTICES = 0x4110 # The objects vertices
|
||||||
|
OBJECT_FACES = 0x4120 # The objects faces
|
||||||
|
OBJECT_MATERIAL = 0x4130 # This is found if the object has a material, either texture map or color
|
||||||
|
OBJECT_UV = 0x4140 # The UV texture coordinates
|
||||||
|
OBJECT_TRANS_MATRIX = 0x4160 # The Object Matrix
|
||||||
|
|
||||||
|
#>------ sub defines of KFDATA
|
||||||
|
KFDATA_KFHDR = 0xB00A
|
||||||
|
KFDATA_KFSEG = 0xB008
|
||||||
|
KFDATA_KFCURTIME = 0xB009
|
||||||
|
KFDATA_OBJECT_NODE_TAG = 0xB002
|
||||||
|
|
||||||
|
#>------ sub defines of OBJECT_NODE_TAG
|
||||||
|
OBJECT_NODE_ID = 0xB030
|
||||||
|
OBJECT_NODE_HDR = 0xB010
|
||||||
|
OBJECT_PIVOT = 0xB013
|
||||||
|
OBJECT_INSTANCE_NAME = 0xB011
|
||||||
|
POS_TRACK_TAG = 0xB020
|
||||||
|
ROT_TRACK_TAG = 0xB021
|
||||||
|
SCL_TRACK_TAG = 0xB022
|
||||||
|
|
||||||
import struct
|
import struct
|
||||||
import os
|
|
||||||
import time
|
|
||||||
|
|
||||||
import bpy
|
|
||||||
|
|
||||||
# import Blender
|
|
||||||
# from BPyMesh import getMeshFromObject
|
|
||||||
# from BPyObject import getDerivedObjects
|
|
||||||
# try:
|
|
||||||
# import struct
|
|
||||||
# except:
|
|
||||||
# struct = None
|
|
||||||
|
|
||||||
# also used by X3D exporter
|
|
||||||
# return a tuple (free, object list), free is True if memory should be freed later with free_derived_objects()
|
|
||||||
def create_derived_objects(scene, ob):
|
|
||||||
if ob.parent and ob.parent.dupli_type != 'NONE':
|
|
||||||
return False, None
|
|
||||||
|
|
||||||
if ob.dupli_type != 'NONE':
|
|
||||||
ob.create_dupli_list(scene)
|
|
||||||
return True, [(dob.object, dob.matrix) for dob in ob.dupli_list]
|
|
||||||
else:
|
|
||||||
return False, [(ob, ob.matrix_world)]
|
|
||||||
|
|
||||||
# also used by X3D exporter
|
|
||||||
def free_derived_objects(ob):
|
|
||||||
ob.free_dupli_list()
|
|
||||||
|
|
||||||
# So 3ds max can open files, limit names to 12 in length
|
# So 3ds max can open files, limit names to 12 in length
|
||||||
# this is verry annoying for filenames!
|
# this is verry annoying for filenames!
|
||||||
@@ -94,13 +93,10 @@ name_unique = []
|
|||||||
name_mapping = {}
|
name_mapping = {}
|
||||||
def sane_name(name):
|
def sane_name(name):
|
||||||
name_fixed = name_mapping.get(name)
|
name_fixed = name_mapping.get(name)
|
||||||
if name_fixed != None:
|
if name_fixed is not None:
|
||||||
return name_fixed
|
return name_fixed
|
||||||
|
|
||||||
if len(name) > 12:
|
new_name = name[:12]
|
||||||
new_name = name[:12]
|
|
||||||
else:
|
|
||||||
new_name = name
|
|
||||||
|
|
||||||
i = 0
|
i = 0
|
||||||
|
|
||||||
@@ -112,65 +108,6 @@ def sane_name(name):
|
|||||||
name_mapping[name] = new_name
|
name_mapping[name] = new_name
|
||||||
return new_name
|
return new_name
|
||||||
|
|
||||||
######################################################
|
|
||||||
# Data Structures
|
|
||||||
######################################################
|
|
||||||
|
|
||||||
#Some of the chunks that we will export
|
|
||||||
#----- Primary Chunk, at the beginning of each file
|
|
||||||
PRIMARY= int("0x4D4D",16)
|
|
||||||
|
|
||||||
#------ Main Chunks
|
|
||||||
OBJECTINFO = int("0x3D3D",16); #This gives the version of the mesh and is found right before the material and object information
|
|
||||||
VERSION = int("0x0002",16); #This gives the version of the .3ds file
|
|
||||||
KFDATA = int("0xB000",16); #This is the header for all of the key frame info
|
|
||||||
|
|
||||||
#------ sub defines of OBJECTINFO
|
|
||||||
MATERIAL=45055 #0xAFFF // This stored the texture info
|
|
||||||
OBJECT=16384 #0x4000 // This stores the faces, vertices, etc...
|
|
||||||
|
|
||||||
#>------ sub defines of MATERIAL
|
|
||||||
MATNAME = int("0xA000",16); # This holds the material name
|
|
||||||
MATAMBIENT = int("0xA010",16); # Ambient color of the object/material
|
|
||||||
MATDIFFUSE = int("0xA020",16); # This holds the color of the object/material
|
|
||||||
MATSPECULAR = int("0xA030",16); # SPecular color of the object/material
|
|
||||||
MATSHINESS = int("0xA040",16); # ??
|
|
||||||
MATMAP = int("0xA200",16); # This is a header for a new material
|
|
||||||
MATMAPFILE = int("0xA300",16); # This holds the file name of the texture
|
|
||||||
|
|
||||||
RGB1= int("0x0011",16)
|
|
||||||
RGB2= int("0x0012",16)
|
|
||||||
|
|
||||||
#>------ sub defines of OBJECT
|
|
||||||
OBJECT_MESH = int("0x4100",16); # This lets us know that we are reading a new object
|
|
||||||
OBJECT_LIGHT = int("0x4600",16); # This lets un know we are reading a light object
|
|
||||||
OBJECT_CAMERA= int("0x4700",16); # This lets un know we are reading a camera object
|
|
||||||
|
|
||||||
#>------ sub defines of CAMERA
|
|
||||||
OBJECT_CAM_RANGES= int("0x4720",16); # The camera range values
|
|
||||||
|
|
||||||
#>------ sub defines of OBJECT_MESH
|
|
||||||
OBJECT_VERTICES = int("0x4110",16); # The objects vertices
|
|
||||||
OBJECT_FACES = int("0x4120",16); # The objects faces
|
|
||||||
OBJECT_MATERIAL = int("0x4130",16); # This is found if the object has a material, either texture map or color
|
|
||||||
OBJECT_UV = int("0x4140",16); # The UV texture coordinates
|
|
||||||
OBJECT_TRANS_MATRIX = int("0x4160",16); # The Object Matrix
|
|
||||||
|
|
||||||
#>------ sub defines of KFDATA
|
|
||||||
KFDATA_KFHDR = int("0xB00A",16);
|
|
||||||
KFDATA_KFSEG = int("0xB008",16);
|
|
||||||
KFDATA_KFCURTIME = int("0xB009",16);
|
|
||||||
KFDATA_OBJECT_NODE_TAG = int("0xB002",16);
|
|
||||||
|
|
||||||
#>------ sub defines of OBJECT_NODE_TAG
|
|
||||||
OBJECT_NODE_ID = int("0xB030",16);
|
|
||||||
OBJECT_NODE_HDR = int("0xB010",16);
|
|
||||||
OBJECT_PIVOT = int("0xB013",16);
|
|
||||||
OBJECT_INSTANCE_NAME = int("0xB011",16);
|
|
||||||
POS_TRACK_TAG = int("0xB020",16);
|
|
||||||
ROT_TRACK_TAG = int("0xB021",16);
|
|
||||||
SCL_TRACK_TAG = int("0xB022",16);
|
|
||||||
|
|
||||||
def uv_key(uv):
|
def uv_key(uv):
|
||||||
return round(uv[0], 6), round(uv[1], 6)
|
return round(uv[0], 6), round(uv[1], 6)
|
||||||
# return round(uv.x, 6), round(uv.y, 6)
|
# return round(uv.x, 6), round(uv.y, 6)
|
||||||
@@ -379,7 +316,7 @@ class _3ds_named_variable(object):
|
|||||||
if (self.value!=None):
|
if (self.value!=None):
|
||||||
spaces=""
|
spaces=""
|
||||||
for i in range(indent):
|
for i in range(indent):
|
||||||
spaces+=" ";
|
spaces += " "
|
||||||
if (self.name!=""):
|
if (self.name!=""):
|
||||||
print(spaces, self.name, " = ", self.value)
|
print(spaces, self.name, " = ", self.value)
|
||||||
else:
|
else:
|
||||||
@@ -444,7 +381,7 @@ class _3ds_chunk(object):
|
|||||||
Uses the dump function of the named variables and the subchunks to do the actual work.'''
|
Uses the dump function of the named variables and the subchunks to do the actual work.'''
|
||||||
spaces=""
|
spaces=""
|
||||||
for i in range(indent):
|
for i in range(indent):
|
||||||
spaces+=" ";
|
spaces += " "
|
||||||
print(spaces, "ID=", hex(self.ID.value), "size=", self.get_size())
|
print(spaces, "ID=", hex(self.ID.value), "size=", self.get_size())
|
||||||
for variable in self.variables:
|
for variable in self.variables:
|
||||||
variable.dump(indent+1)
|
variable.dump(indent+1)
|
||||||
@@ -479,11 +416,11 @@ def make_material_subchunk(id, color):
|
|||||||
Used for color subchunks, such as diffuse color or ambient color subchunks.'''
|
Used for color subchunks, such as diffuse color or ambient color subchunks.'''
|
||||||
mat_sub = _3ds_chunk(id)
|
mat_sub = _3ds_chunk(id)
|
||||||
col1 = _3ds_chunk(RGB1)
|
col1 = _3ds_chunk(RGB1)
|
||||||
col1.add_variable("color1", _3ds_rgb_color(color));
|
col1.add_variable("color1", _3ds_rgb_color(color))
|
||||||
mat_sub.add_subchunk(col1)
|
mat_sub.add_subchunk(col1)
|
||||||
# optional:
|
# optional:
|
||||||
# col2 = _3ds_chunk(RGB1)
|
# col2 = _3ds_chunk(RGB1)
|
||||||
# col2.add_variable("color2", _3ds_rgb_color(color));
|
# col2.add_variable("color2", _3ds_rgb_color(color))
|
||||||
# mat_sub.add_subchunk(col2)
|
# mat_sub.add_subchunk(col2)
|
||||||
return mat_sub
|
return mat_sub
|
||||||
|
|
||||||
@@ -921,27 +858,21 @@ def make_kf_obj_node(obj, name_to_id):
|
|||||||
return kf_obj_node
|
return kf_obj_node
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# import BPyMessages
|
|
||||||
def write(filename, context):
|
def save(operator, context, filepath=""):
|
||||||
|
import bpy
|
||||||
|
import time
|
||||||
|
from io_utils import create_derived_objects, free_derived_objects
|
||||||
|
|
||||||
'''Save the Blender scene to a 3ds file.'''
|
'''Save the Blender scene to a 3ds file.'''
|
||||||
|
|
||||||
# Time the export
|
# Time the export
|
||||||
|
|
||||||
if not filename.lower().endswith('.3ds'):
|
|
||||||
filename += '.3ds'
|
|
||||||
|
|
||||||
# XXX
|
|
||||||
# if not BPyMessages.Warning_SaveOver(filename):
|
|
||||||
# return
|
|
||||||
|
|
||||||
# XXX
|
|
||||||
time1 = time.clock()
|
time1 = time.clock()
|
||||||
# time1= Blender.sys.time()
|
|
||||||
# Blender.Window.WaitCursor(1)
|
# Blender.Window.WaitCursor(1)
|
||||||
|
|
||||||
sce = context.scene
|
sce = context.scene
|
||||||
# sce= bpy.data.scenes.active
|
|
||||||
|
|
||||||
if context.object:
|
if bpy.ops.object.mode_set.poll():
|
||||||
bpy.ops.object.mode_set(mode='OBJECT')
|
bpy.ops.object.mode_set(mode='OBJECT')
|
||||||
|
|
||||||
# Initialize the main chunk (primary):
|
# Initialize the main chunk (primary):
|
||||||
@@ -1090,7 +1021,7 @@ def write(filename, context):
|
|||||||
# Check the size:
|
# Check the size:
|
||||||
primary.get_size()
|
primary.get_size()
|
||||||
# Open the file for writing:
|
# Open the file for writing:
|
||||||
file = open( filename, 'wb' )
|
file = open(filepath, 'wb')
|
||||||
|
|
||||||
# Recursively write the chunks to file:
|
# Recursively write the chunks to file:
|
||||||
primary.write(file)
|
primary.write(file)
|
||||||
@@ -1098,56 +1029,15 @@ def write(filename, context):
|
|||||||
# Close the file:
|
# Close the file:
|
||||||
file.close()
|
file.close()
|
||||||
|
|
||||||
|
# Clear name mapping vars, could make locals too
|
||||||
|
name_unique[:] = []
|
||||||
|
name_mapping.clear()
|
||||||
|
|
||||||
# Debugging only: report the exporting time:
|
# Debugging only: report the exporting time:
|
||||||
# Blender.Window.WaitCursor(0)
|
# Blender.Window.WaitCursor(0)
|
||||||
print("3ds export time: %.2f" % (time.clock() - time1))
|
print("3ds export time: %.2f" % (time.clock() - time1))
|
||||||
# print("3ds export time: %.2f" % (Blender.sys.time() - time1))
|
|
||||||
|
|
||||||
# Debugging only: dump the chunk hierarchy:
|
# Debugging only: dump the chunk hierarchy:
|
||||||
#primary.dump()
|
#primary.dump()
|
||||||
|
|
||||||
|
return {'FINISHED'}
|
||||||
# # write('/test_b.3ds')
|
|
||||||
from bpy.props import *
|
|
||||||
class Export3DS(bpy.types.Operator):
|
|
||||||
'''Export to 3DS file format (.3ds)'''
|
|
||||||
bl_idname = "export.autodesk_3ds"
|
|
||||||
bl_label = 'Export 3DS'
|
|
||||||
|
|
||||||
filepath = StringProperty(name="File Path", description="Filepath used for exporting the 3DS file", maxlen= 1024, default= "")
|
|
||||||
check_existing = BoolProperty(name="Check Existing", description="Check and warn on overwriting existing files", default=True, options={'HIDDEN'})
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def poll(cls, context): # Poll isnt working yet
|
|
||||||
return context.active_object != None
|
|
||||||
|
|
||||||
def execute(self, context):
|
|
||||||
filepath = self.properties.filepath
|
|
||||||
filepath = bpy.path.ensure_ext(filepath, ".3ds")
|
|
||||||
|
|
||||||
write(filepath, context)
|
|
||||||
return {'FINISHED'}
|
|
||||||
|
|
||||||
def invoke(self, context, event):
|
|
||||||
import os
|
|
||||||
if not self.properties.is_property_set("filepath"):
|
|
||||||
self.properties.filepath = os.path.splitext(bpy.data.filepath)[0] + ".3ds"
|
|
||||||
|
|
||||||
context.manager.add_fileselect(self)
|
|
||||||
return {'RUNNING_MODAL'}
|
|
||||||
|
|
||||||
|
|
||||||
# Add to a menu
|
|
||||||
def menu_func(self, context):
|
|
||||||
self.layout.operator(Export3DS.bl_idname, text="3D Studio (.3ds)")
|
|
||||||
|
|
||||||
|
|
||||||
def register():
|
|
||||||
bpy.types.INFO_MT_file_export.append(menu_func)
|
|
||||||
|
|
||||||
|
|
||||||
def unregister():
|
|
||||||
bpy.types.INFO_MT_file_export.remove(menu_func)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
register()
|
|
||||||
@@ -18,130 +18,14 @@
|
|||||||
|
|
||||||
# <pep8 compliant>
|
# <pep8 compliant>
|
||||||
|
|
||||||
__author__= ['Bob Holcomb', 'Richard L?rk?ng', 'Damien McGinnes', 'Campbell Barton', 'Mario Lapin']
|
|
||||||
__url__ = ("blenderartists.org", "www.blender.org", "www.gametutorials.com", "lib3ds.sourceforge.net/")
|
|
||||||
__version__= '0.996'
|
|
||||||
__bpydoc__= '''\
|
|
||||||
|
|
||||||
3ds Importer
|
|
||||||
|
|
||||||
This script imports a 3ds file and the materials into Blender for editing.
|
|
||||||
|
|
||||||
Loader is based on 3ds loader from www.gametutorials.com (Thanks DigiBen).
|
|
||||||
|
|
||||||
0.996 by Mario Lapin (mario.lapin@gmail.com) 13/04/200 <br>
|
|
||||||
- Implemented workaround to correct association between name, geometry and materials of
|
|
||||||
imported meshes.
|
|
||||||
|
|
||||||
Without this patch, version 0.995 of this importer would associate to each mesh object the
|
|
||||||
geometry and the materials of the previously parsed mesh object. By so, the name of the
|
|
||||||
first mesh object would be thrown away, and the name of the last mesh object would be
|
|
||||||
automatically merged with a '.001' at the end. No object would desappear, however object's
|
|
||||||
names and materials would be completely jumbled.
|
|
||||||
|
|
||||||
0.995 by Campbell Barton<br>
|
|
||||||
- workaround for buggy mesh vert delete
|
|
||||||
- minor tweaks
|
|
||||||
|
|
||||||
0.99 by Bob Holcomb<br>
|
|
||||||
- added support for floating point color values that previously broke on import.
|
|
||||||
|
|
||||||
0.98 by Campbell Barton<br>
|
|
||||||
- import faces and verts to lists instead of a mesh, convert to a mesh later
|
|
||||||
- use new index mapping feature of mesh to re-map faces that were not added.
|
|
||||||
|
|
||||||
0.97 by Campbell Barton<br>
|
|
||||||
- Strip material names of spaces
|
|
||||||
- Added import as instance to import the 3ds into its own
|
|
||||||
scene and add a group instance to the current scene
|
|
||||||
- New option to scale down imported objects so they are within a limited bounding area.
|
|
||||||
|
|
||||||
0.96 by Campbell Barton<br>
|
|
||||||
- Added workaround for bug in setting UV's for Zero vert index UV faces.
|
|
||||||
- Removed unique name function, let blender make the names unique.
|
|
||||||
|
|
||||||
0.95 by Campbell Barton<br>
|
|
||||||
- Removed workarounds for Blender 2.41
|
|
||||||
- Mesh objects split by material- many 3ds objects used more then 16 per mesh.
|
|
||||||
- Removed a lot of unneeded variable creation.
|
|
||||||
|
|
||||||
0.94 by Campbell Barton<br>
|
|
||||||
- Face import tested to be about overall 16x speedup over 0.93.
|
|
||||||
- Material importing speedup.
|
|
||||||
- Tested with more models.
|
|
||||||
- Support some corrupt models.
|
|
||||||
|
|
||||||
0.93 by Campbell Barton<br>
|
|
||||||
- Tested with 400 3ds files from turbosquid and samples.
|
|
||||||
- Tactfully ignore faces that used the same verts twice.
|
|
||||||
- Rollback to 0.83 sloppy un-reorganized code, this broke UV coord loading.
|
|
||||||
- Converted from NMesh to Mesh.
|
|
||||||
- Faster and cleaner new names.
|
|
||||||
- Use external comprehensive image loader.
|
|
||||||
- Re intergrated 0.92 and 0.9 changes
|
|
||||||
- Fixes for 2.41 compat.
|
|
||||||
- Non textured faces do not use a texture flag.
|
|
||||||
|
|
||||||
0.92<br>
|
|
||||||
- Added support for diffuse, alpha, spec, bump maps in a single material
|
|
||||||
|
|
||||||
0.9<br>
|
|
||||||
- Reorganized code into object/material block functions<br>
|
|
||||||
- Use of Matrix() to copy matrix data<br>
|
|
||||||
- added support for material transparency<br>
|
|
||||||
|
|
||||||
0.83 2005-08-07: Campell Barton
|
|
||||||
- Aggressive image finding and case insensitivy for posisx systems.
|
|
||||||
|
|
||||||
0.82a 2005-07-22
|
|
||||||
- image texture loading (both for face uv and renderer)
|
|
||||||
|
|
||||||
0.82 - image texture loading (for face uv)
|
|
||||||
|
|
||||||
0.81a (fork- not 0.9) Campbell Barton 2005-06-08
|
|
||||||
- Simplified import code
|
|
||||||
- Never overwrite data
|
|
||||||
- Faster list handling
|
|
||||||
- Leaves import selected
|
|
||||||
|
|
||||||
0.81 Damien McGinnes 2005-01-09
|
|
||||||
- handle missing images better
|
|
||||||
|
|
||||||
0.8 Damien McGinnes 2005-01-08
|
|
||||||
- copies sticky UV coords to face ones
|
|
||||||
- handles images better
|
|
||||||
- Recommend that you run 'RemoveDoubles' on each imported mesh after using this script
|
|
||||||
|
|
||||||
'''
|
|
||||||
|
|
||||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
|
||||||
#
|
|
||||||
# Script copyright (C) Bob Holcomb
|
# Script copyright (C) Bob Holcomb
|
||||||
#
|
# Contributors: Bob Holcomb, Richard L?rk?ng, Damien McGinnes, Campbell Barton, Mario Lapin
|
||||||
# This program is free software; you can redistribute it and/or
|
|
||||||
# modify it under the terms of the GNU General Public License
|
|
||||||
# as published by the Free Software Foundation; either version 2
|
|
||||||
# of the License, or (at your option) any later version.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software Foundation,
|
|
||||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
#
|
|
||||||
# ***** END GPL LICENCE BLOCK *****
|
|
||||||
# --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
# Importing modules
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
import struct
|
import struct
|
||||||
|
|
||||||
from import_scene_obj import load_image
|
from io_utils import load_image
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
import mathutils
|
import mathutils
|
||||||
@@ -158,9 +42,9 @@ BOUNDS_3DS = []
|
|||||||
PRIMARY = int('0x4D4D',16)
|
PRIMARY = int('0x4D4D',16)
|
||||||
|
|
||||||
#------ Main Chunks
|
#------ Main Chunks
|
||||||
OBJECTINFO = int('0x3D3D',16); #This gives the version of the mesh and is found right before the material and object information
|
OBJECTINFO = 0x3D3D #This gives the version of the mesh and is found right before the material and object information
|
||||||
VERSION = int('0x0002',16); #This gives the version of the .3ds file
|
VERSION = 0x0002 #This gives the version of the .3ds file
|
||||||
EDITKEYFRAME= int('0xB000',16); #This is the header for all of the key frame info
|
EDITKEYFRAME= 0xB000 #This is the header for all of the key frame info
|
||||||
|
|
||||||
#------ sub defines of OBJECTINFO
|
#------ sub defines of OBJECTINFO
|
||||||
MATERIAL = 45055 #0xAFFF // This stored the texture info
|
MATERIAL = 45055 #0xAFFF // This stored the texture info
|
||||||
@@ -168,62 +52,62 @@ OBJECT = 16384 #0x4000 // This stores the faces, vertices, etc...
|
|||||||
|
|
||||||
#>------ sub defines of MATERIAL
|
#>------ sub defines of MATERIAL
|
||||||
#------ sub defines of MATERIAL_BLOCK
|
#------ sub defines of MATERIAL_BLOCK
|
||||||
MAT_NAME = int('0xA000',16) # This holds the material name
|
MAT_NAME = 0xA000 # This holds the material name
|
||||||
MAT_AMBIENT = int('0xA010',16) # Ambient color of the object/material
|
MAT_AMBIENT = 0xA010 # Ambient color of the object/material
|
||||||
MAT_DIFFUSE = int('0xA020',16) # This holds the color of the object/material
|
MAT_DIFFUSE = 0xA020 # This holds the color of the object/material
|
||||||
MAT_SPECULAR = int('0xA030',16) # SPecular color of the object/material
|
MAT_SPECULAR = 0xA030 # SPecular color of the object/material
|
||||||
MAT_SHINESS = int('0xA040',16) # ??
|
MAT_SHINESS = 0xA040 # ??
|
||||||
MAT_TRANSPARENCY= int('0xA050',16) # Transparency value of material
|
MAT_TRANSPARENCY= 0xA050 # Transparency value of material
|
||||||
MAT_SELF_ILLUM = int('0xA080',16) # Self Illumination value of material
|
MAT_SELF_ILLUM = 0xA080 # Self Illumination value of material
|
||||||
MAT_WIRE = int('0xA085',16) # Only render's wireframe
|
MAT_WIRE = 0xA085 # Only render's wireframe
|
||||||
|
|
||||||
MAT_TEXTURE_MAP = int('0xA200',16) # This is a header for a new texture map
|
MAT_TEXTURE_MAP = 0xA200 # This is a header for a new texture map
|
||||||
MAT_SPECULAR_MAP= int('0xA204',16) # This is a header for a new specular map
|
MAT_SPECULAR_MAP= 0xA204 # This is a header for a new specular map
|
||||||
MAT_OPACITY_MAP = int('0xA210',16) # This is a header for a new opacity map
|
MAT_OPACITY_MAP = 0xA210 # This is a header for a new opacity map
|
||||||
MAT_REFLECTION_MAP= int('0xA220',16) # This is a header for a new reflection map
|
MAT_REFLECTION_MAP= 0xA220 # This is a header for a new reflection map
|
||||||
MAT_BUMP_MAP = int('0xA230',16) # This is a header for a new bump map
|
MAT_BUMP_MAP = 0xA230 # This is a header for a new bump map
|
||||||
MAT_MAP_FILENAME = int('0xA300',16) # This holds the file name of the texture
|
MAT_MAP_FILEPATH = 0xA300 # This holds the file name of the texture
|
||||||
|
|
||||||
MAT_FLOAT_COLOR = int ('0x0010', 16) #color defined as 3 floats
|
MAT_FLOAT_COLOR = 0x0010 #color defined as 3 floats
|
||||||
MAT_24BIT_COLOR = int ('0x0011', 16) #color defined as 3 bytes
|
MAT_24BIT_COLOR = 0x0011 #color defined as 3 bytes
|
||||||
|
|
||||||
#>------ sub defines of OBJECT
|
#>------ sub defines of OBJECT
|
||||||
OBJECT_MESH = int('0x4100',16); # This lets us know that we are reading a new object
|
OBJECT_MESH = 0x4100 # This lets us know that we are reading a new object
|
||||||
OBJECT_LAMP = int('0x4600',16); # This lets un know we are reading a light object
|
OBJECT_LAMP = 0x4600 # This lets un know we are reading a light object
|
||||||
OBJECT_LAMP_SPOT = int('0x4610',16); # The light is a spotloght.
|
OBJECT_LAMP_SPOT = 0x4610 # The light is a spotloght.
|
||||||
OBJECT_LAMP_OFF = int('0x4620',16); # The light off.
|
OBJECT_LAMP_OFF = 0x4620 # The light off.
|
||||||
OBJECT_LAMP_ATTENUATE = int('0x4625',16);
|
OBJECT_LAMP_ATTENUATE = 0x4625
|
||||||
OBJECT_LAMP_RAYSHADE = int('0x4627',16);
|
OBJECT_LAMP_RAYSHADE = 0x4627
|
||||||
OBJECT_LAMP_SHADOWED = int('0x4630',16);
|
OBJECT_LAMP_SHADOWED = 0x4630
|
||||||
OBJECT_LAMP_LOCAL_SHADOW = int('0x4640',16);
|
OBJECT_LAMP_LOCAL_SHADOW = 0x4640
|
||||||
OBJECT_LAMP_LOCAL_SHADOW2 = int('0x4641',16);
|
OBJECT_LAMP_LOCAL_SHADOW2 = 0x4641
|
||||||
OBJECT_LAMP_SEE_CONE = int('0x4650',16);
|
OBJECT_LAMP_SEE_CONE = 0x4650
|
||||||
OBJECT_LAMP_SPOT_RECTANGULAR = int('0x4651',16);
|
OBJECT_LAMP_SPOT_RECTANGULAR = 0x4651
|
||||||
OBJECT_LAMP_SPOT_OVERSHOOT = int('0x4652',16);
|
OBJECT_LAMP_SPOT_OVERSHOOT = 0x4652
|
||||||
OBJECT_LAMP_SPOT_PROJECTOR = int('0x4653',16);
|
OBJECT_LAMP_SPOT_PROJECTOR = 0x4653
|
||||||
OBJECT_LAMP_EXCLUDE = int('0x4654',16);
|
OBJECT_LAMP_EXCLUDE = 0x4654
|
||||||
OBJECT_LAMP_RANGE = int('0x4655',16);
|
OBJECT_LAMP_RANGE = 0x4655
|
||||||
OBJECT_LAMP_ROLL = int('0x4656',16);
|
OBJECT_LAMP_ROLL = 0x4656
|
||||||
OBJECT_LAMP_SPOT_ASPECT = int('0x4657',16);
|
OBJECT_LAMP_SPOT_ASPECT = 0x4657
|
||||||
OBJECT_LAMP_RAY_BIAS = int('0x4658',16);
|
OBJECT_LAMP_RAY_BIAS = 0x4658
|
||||||
OBJECT_LAMP_INNER_RANGE = int('0x4659',16);
|
OBJECT_LAMP_INNER_RANGE = 0x4659
|
||||||
OBJECT_LAMP_OUTER_RANGE = int('0x465A',16);
|
OBJECT_LAMP_OUTER_RANGE = 0x465A
|
||||||
OBJECT_LAMP_MULTIPLIER = int('0x465B',16);
|
OBJECT_LAMP_MULTIPLIER = 0x465B
|
||||||
OBJECT_LAMP_AMBIENT_LIGHT = int('0x4680',16);
|
OBJECT_LAMP_AMBIENT_LIGHT = 0x4680
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
OBJECT_CAMERA= int('0x4700',16); # This lets un know we are reading a camera object
|
OBJECT_CAMERA= 0x4700 # This lets un know we are reading a camera object
|
||||||
|
|
||||||
#>------ sub defines of CAMERA
|
#>------ sub defines of CAMERA
|
||||||
OBJECT_CAM_RANGES= int('0x4720',16); # The camera range values
|
OBJECT_CAM_RANGES= 0x4720 # The camera range values
|
||||||
|
|
||||||
#>------ sub defines of OBJECT_MESH
|
#>------ sub defines of OBJECT_MESH
|
||||||
OBJECT_VERTICES = int('0x4110',16); # The objects vertices
|
OBJECT_VERTICES = 0x4110 # The objects vertices
|
||||||
OBJECT_FACES = int('0x4120',16); # The objects faces
|
OBJECT_FACES = 0x4120 # The objects faces
|
||||||
OBJECT_MATERIAL = int('0x4130',16); # This is found if the object has a material, either texture map or color
|
OBJECT_MATERIAL = 0x4130 # This is found if the object has a material, either texture map or color
|
||||||
OBJECT_UV = int('0x4140',16); # The UV texture coordinates
|
OBJECT_UV = 0x4140 # The UV texture coordinates
|
||||||
OBJECT_TRANS_MATRIX = int('0x4160',16); # The Object Matrix
|
OBJECT_TRANS_MATRIX = 0x4160 # The Object Matrix
|
||||||
|
|
||||||
global scn
|
global scn
|
||||||
scn = None
|
scn = None
|
||||||
@@ -299,7 +183,19 @@ def add_texture_to_material(image, texture, material, mapto):
|
|||||||
if image:
|
if image:
|
||||||
texture.image = image
|
texture.image = image
|
||||||
|
|
||||||
material.add_texture(texture, "UV", mapto)
|
mtex = material.texture_slots.add()
|
||||||
|
mtex.texture = texture
|
||||||
|
mtex.texture_coords = 'UV'
|
||||||
|
mtex.use_map_color_diffuse = False
|
||||||
|
|
||||||
|
if mapto == 'COLOR':
|
||||||
|
mtex.use_map_color_diffuse = True
|
||||||
|
elif mapto == 'SPECULARITY':
|
||||||
|
mtex.use_map_specular = True
|
||||||
|
elif mapto == 'ALPHA':
|
||||||
|
mtex.use_map_alpha = True
|
||||||
|
elif mapto == 'NORMAL':
|
||||||
|
mtex.use_map_normal = True
|
||||||
|
|
||||||
|
|
||||||
def process_next_chunk(file, previous_chunk, importedObjects, IMAGE_SEARCH):
|
def process_next_chunk(file, previous_chunk, importedObjects, IMAGE_SEARCH):
|
||||||
@@ -356,7 +252,7 @@ def process_next_chunk(file, previous_chunk, importedObjects, IMAGE_SEARCH):
|
|||||||
bmat = MATDICT[matName][1]
|
bmat = MATDICT[matName][1]
|
||||||
img = TEXTURE_DICT.get(bmat.name)
|
img = TEXTURE_DICT.get(bmat.name)
|
||||||
|
|
||||||
bmesh.materials.link(bmat) # can be None
|
bmesh.materials.append(bmat) # can be None
|
||||||
|
|
||||||
if uv_faces and img:
|
if uv_faces and img:
|
||||||
for fidx in faces:
|
for fidx in faces:
|
||||||
@@ -420,7 +316,7 @@ def process_next_chunk(file, previous_chunk, importedObjects, IMAGE_SEARCH):
|
|||||||
#print 'MAT_TEXTURE_MAP..while', new_chunk.bytes_read, new_chunk.length
|
#print 'MAT_TEXTURE_MAP..while', new_chunk.bytes_read, new_chunk.length
|
||||||
read_chunk(file, temp_chunk)
|
read_chunk(file, temp_chunk)
|
||||||
|
|
||||||
if (temp_chunk.ID == MAT_MAP_FILENAME):
|
if (temp_chunk.ID == MAT_MAP_FILEPATH):
|
||||||
texture_name = read_string(file)
|
texture_name = read_string(file)
|
||||||
img = TEXTURE_DICT[contextMaterial.name] = load_image(texture_name, dirname)
|
img = TEXTURE_DICT[contextMaterial.name] = load_image(texture_name, dirname)
|
||||||
new_chunk.bytes_read += (len(texture_name)+1) #plus one for the null character that gets removed
|
new_chunk.bytes_read += (len(texture_name)+1) #plus one for the null character that gets removed
|
||||||
@@ -434,7 +330,7 @@ def process_next_chunk(file, previous_chunk, importedObjects, IMAGE_SEARCH):
|
|||||||
if img:
|
if img:
|
||||||
add_texture_to_material(img, new_texture, contextMaterial, mapto)
|
add_texture_to_material(img, new_texture, contextMaterial, mapto)
|
||||||
|
|
||||||
dirname = os.path.dirname(FILENAME)
|
dirname = os.path.dirname(file.name)
|
||||||
|
|
||||||
#loop through all the data for this chunk (previous chunk) and see what it is
|
#loop through all the data for this chunk (previous chunk) and see what it is
|
||||||
while (previous_chunk.bytes_read < previous_chunk.length):
|
while (previous_chunk.bytes_read < previous_chunk.length):
|
||||||
@@ -720,14 +616,14 @@ def process_next_chunk(file, previous_chunk, importedObjects, IMAGE_SEARCH):
|
|||||||
#contextMatrix = contextMatrix * tx
|
#contextMatrix = contextMatrix * tx
|
||||||
#contextMatrix = contextMatrix *tx
|
#contextMatrix = contextMatrix *tx
|
||||||
|
|
||||||
elif (new_chunk.ID == MAT_MAP_FILENAME):
|
elif (new_chunk.ID == MAT_MAP_FILEPATH):
|
||||||
texture_name = read_string(file)
|
texture_name = read_string(file)
|
||||||
try:
|
try:
|
||||||
TEXTURE_DICT[contextMaterial.name]
|
TEXTURE_DICT[contextMaterial.name]
|
||||||
except:
|
except:
|
||||||
#img = TEXTURE_DICT[contextMaterial.name]= BPyImage.comprehensiveImageLoad(texture_name, FILENAME)
|
#img = TEXTURE_DICT[contextMaterial.name]= BPyImage.comprehensiveImageLoad(texture_name, FILEPATH)
|
||||||
img = TEXTURE_DICT[contextMaterial.name] = load_image(texture_name, dirname)
|
img = TEXTURE_DICT[contextMaterial.name] = load_image(texture_name, dirname)
|
||||||
# img = TEXTURE_DICT[contextMaterial.name]= BPyImage.comprehensiveImageLoad(texture_name, FILENAME, PLACE_HOLDER=False, RECURSIVE=IMAGE_SEARCH)
|
# img = TEXTURE_DICT[contextMaterial.name]= BPyImage.comprehensiveImageLoad(texture_name, FILEPATH, PLACE_HOLDER=False, RECURSIVE=IMAGE_SEARCH)
|
||||||
|
|
||||||
new_chunk.bytes_read += len(texture_name)+1 #plus one for the null character that gets removed
|
new_chunk.bytes_read += len(texture_name)+1 #plus one for the null character that gets removed
|
||||||
|
|
||||||
@@ -750,30 +646,27 @@ def process_next_chunk(file, previous_chunk, importedObjects, IMAGE_SEARCH):
|
|||||||
if CreateBlenderObject:
|
if CreateBlenderObject:
|
||||||
putContextMesh(contextMesh_vertls, contextMesh_facels, contextMeshMaterials)
|
putContextMesh(contextMesh_vertls, contextMesh_facels, contextMeshMaterials)
|
||||||
|
|
||||||
def load_3ds(filename, context, IMPORT_CONSTRAIN_BOUNDS=10.0, IMAGE_SEARCH=True, APPLY_MATRIX=False):
|
def load_3ds(filepath, context, IMPORT_CONSTRAIN_BOUNDS=10.0, IMAGE_SEARCH=True, APPLY_MATRIX=False):
|
||||||
global FILENAME, SCN
|
global SCN
|
||||||
# global FILENAME, SCN_OBJECTS
|
|
||||||
|
|
||||||
# XXX
|
# XXX
|
||||||
# if BPyMessages.Error_NoFile(filename):
|
# if BPyMessages.Error_NoFile(filepath):
|
||||||
# return
|
# return
|
||||||
|
|
||||||
print('\n\nImporting 3DS: "%s"' % (filename))
|
print('\n\nImporting 3DS: %r' % (filepath))
|
||||||
# print('\n\nImporting 3DS: "%s"' % (Blender.sys.expandpath(filename)))
|
|
||||||
|
|
||||||
time1 = time.clock()
|
time1 = time.clock()
|
||||||
# time1 = Blender.sys.time()
|
# time1 = Blender.sys.time()
|
||||||
|
|
||||||
FILENAME = filename
|
|
||||||
current_chunk = chunk()
|
current_chunk = chunk()
|
||||||
|
|
||||||
file = open(filename,'rb')
|
file = open(filepath, 'rb')
|
||||||
|
|
||||||
#here we go!
|
#here we go!
|
||||||
# print 'reading the first chunk'
|
# print 'reading the first chunk'
|
||||||
read_chunk(file, current_chunk)
|
read_chunk(file, current_chunk)
|
||||||
if (current_chunk.ID!=PRIMARY):
|
if (current_chunk.ID!=PRIMARY):
|
||||||
print('\tFatal Error: Not a valid 3ds file: ', filename)
|
print('\tFatal Error: Not a valid 3ds file: %r' % filepath)
|
||||||
file.close()
|
file.close()
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -834,7 +727,7 @@ def load_3ds(filename, context, IMPORT_CONSTRAIN_BOUNDS=10.0, IMAGE_SEARCH=True,
|
|||||||
# Done DUMMYVERT
|
# Done DUMMYVERT
|
||||||
"""
|
"""
|
||||||
if IMPORT_AS_INSTANCE:
|
if IMPORT_AS_INSTANCE:
|
||||||
name = filename.split('\\')[-1].split('/')[-1]
|
name = filepath.split('\\')[-1].split('/')[-1]
|
||||||
# Create a group for this import.
|
# Create a group for this import.
|
||||||
group_scn = Scene.New(name)
|
group_scn = Scene.New(name)
|
||||||
for ob in importedObjects:
|
for ob in importedObjects:
|
||||||
@@ -892,96 +785,10 @@ def load_3ds(filename, context, IMPORT_CONSTRAIN_BOUNDS=10.0, IMAGE_SEARCH=True,
|
|||||||
# Done constraining to bounds.
|
# Done constraining to bounds.
|
||||||
|
|
||||||
# Select all new objects.
|
# Select all new objects.
|
||||||
print('finished importing: "%s" in %.4f sec.' % (filename, (time.clock()-time1)))
|
print('finished importing: %r in %.4f sec.' % (filepath, (time.clock()-time1)))
|
||||||
# print('finished importing: "%s" in %.4f sec.' % (filename, (Blender.sys.time()-time1)))
|
|
||||||
file.close()
|
file.close()
|
||||||
|
|
||||||
|
|
||||||
DEBUG = False
|
def load(operator, context, filepath="", constrain_size=0.0, use_image_search=True, use_apply_transform=True):
|
||||||
# For testing compatibility
|
load_3ds(filepath, context, IMPORT_CONSTRAIN_BOUNDS=constrain_size, IMAGE_SEARCH=use_image_search, APPLY_MATRIX=use_apply_transform)
|
||||||
#load_3ds('/metavr/convert/vehicle/truck_002/TruckTanker1.3DS', False)
|
return {'FINISHED'}
|
||||||
#load_3ds('/metavr/archive/convert/old/arranged_3ds_to_hpx-2/only-need-engine-trains/Engine2.3DS', False)
|
|
||||||
'''
|
|
||||||
|
|
||||||
else:
|
|
||||||
import os
|
|
||||||
# DEBUG ONLY
|
|
||||||
TIME = Blender.sys.time()
|
|
||||||
import os
|
|
||||||
print 'Searching for files'
|
|
||||||
os.system('find /metavr/ -iname "*.3ds" > /tmp/temp3ds_list')
|
|
||||||
# os.system('find /storage/ -iname "*.3ds" > /tmp/temp3ds_list')
|
|
||||||
print '...Done'
|
|
||||||
file = open('/tmp/temp3ds_list', 'r')
|
|
||||||
lines = file.readlines()
|
|
||||||
file.close()
|
|
||||||
# sort by filesize for faster testing
|
|
||||||
lines_size = [(os.path.getsize(f[:-1]), f[:-1]) for f in lines]
|
|
||||||
lines_size.sort()
|
|
||||||
lines = [f[1] for f in lines_size]
|
|
||||||
|
|
||||||
|
|
||||||
def between(v,a,b):
|
|
||||||
if v <= max(a,b) and v >= min(a,b):
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
for i, _3ds in enumerate(lines):
|
|
||||||
if between(i, 650,800):
|
|
||||||
#_3ds= _3ds[:-1]
|
|
||||||
print 'Importing', _3ds, '\nNUMBER', i, 'of', len(lines)
|
|
||||||
_3ds_file= _3ds.split('/')[-1].split('\\')[-1]
|
|
||||||
newScn = Blender.Scene.New(_3ds_file)
|
|
||||||
newScn.makeCurrent()
|
|
||||||
load_3ds(_3ds, False)
|
|
||||||
|
|
||||||
print 'TOTAL TIME: %.6f' % (Blender.sys.time() - TIME)
|
|
||||||
|
|
||||||
'''
|
|
||||||
from bpy.props import *
|
|
||||||
|
|
||||||
|
|
||||||
class IMPORT_OT_autodesk_3ds(bpy.types.Operator):
|
|
||||||
'''Import from 3DS file format (.3ds)'''
|
|
||||||
bl_idname = "import_scene.autodesk_3ds"
|
|
||||||
bl_label = 'Import 3DS'
|
|
||||||
|
|
||||||
# List of operator properties, the attributes will be assigned
|
|
||||||
# to the class instance from the operator settings before calling.
|
|
||||||
filepath = StringProperty(name="File Path", description="Filepath used for importing the 3DS file", maxlen= 1024, default= "")
|
|
||||||
|
|
||||||
constrain_size = FloatProperty(name="Size Constraint", description="Scale the model by 10 until it reacehs the size constraint. Zero Disables.", min=0.0, max=1000.0, soft_min=0.0, soft_max=1000.0, default=10.0)
|
|
||||||
search_images = BoolProperty(name="Image Search", description="Search subdirectories for any assosiated images (Warning, may be slow)", default=True)
|
|
||||||
apply_transform = BoolProperty(name="Apply Transform", description="Workaround for object transformations importing incorrectly", default=False)
|
|
||||||
|
|
||||||
def execute(self, context):
|
|
||||||
load_3ds(self.properties.filepath,
|
|
||||||
context,
|
|
||||||
IMPORT_CONSTRAIN_BOUNDS=self.properties.constrain_size,
|
|
||||||
IMAGE_SEARCH=self.properties.search_images,
|
|
||||||
APPLY_MATRIX=self.properties.apply_transform)
|
|
||||||
|
|
||||||
return {'FINISHED'}
|
|
||||||
|
|
||||||
def invoke(self, context, event):
|
|
||||||
wm = context.manager
|
|
||||||
wm.add_fileselect(self)
|
|
||||||
return {'RUNNING_MODAL'}
|
|
||||||
|
|
||||||
|
|
||||||
def menu_func(self, context):
|
|
||||||
self.layout.operator(IMPORT_OT_autodesk_3ds.bl_idname, text="3D Studio (.3ds)")
|
|
||||||
|
|
||||||
def register():
|
|
||||||
bpy.types.INFO_MT_file_import.append(menu_func)
|
|
||||||
|
|
||||||
def unregister():
|
|
||||||
bpy.types.INFO_MT_file_import.remove(menu_func)
|
|
||||||
|
|
||||||
# NOTES:
|
|
||||||
# why add 1 extra vertex? and remove it when done? - "Answer - eekadoodle - would need to re-order UV's without this since face order isnt always what we give blender, BMesh will solve :D"
|
|
||||||
# disabled scaling to size, this requires exposing bb (easy) and understanding how it works (needs some time)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
register()
|
|
||||||
|
|
||||||
102
release/scripts/op/io_scene_fbx/__init__.py
Normal file
102
release/scripts/op/io_scene_fbx/__init__.py
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
# ##### BEGIN GPL LICENSE BLOCK #####
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software Foundation,
|
||||||
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
#
|
||||||
|
# ##### END GPL LICENSE BLOCK #####
|
||||||
|
|
||||||
|
# <pep8 compliant>
|
||||||
|
|
||||||
|
# To support reload properly, try to access a package var, if it's there, reload everything
|
||||||
|
if "bpy" in locals():
|
||||||
|
# only reload if we alredy loaded, highly annoying
|
||||||
|
import sys
|
||||||
|
reload(sys.modules.get("io_scene_fbx.export_fbx", sys))
|
||||||
|
|
||||||
|
|
||||||
|
import bpy
|
||||||
|
from bpy.props import *
|
||||||
|
from io_utils import ExportHelper
|
||||||
|
|
||||||
|
|
||||||
|
class ExportFBX(bpy.types.Operator, ExportHelper):
|
||||||
|
'''Selection to an ASCII Autodesk FBX'''
|
||||||
|
bl_idname = "export_scene.fbx"
|
||||||
|
bl_label = "Export FBX"
|
||||||
|
|
||||||
|
filename_ext = ".fbx"
|
||||||
|
|
||||||
|
# List of operator properties, the attributes will be assigned
|
||||||
|
# to the class instance from the operator settings before calling.
|
||||||
|
|
||||||
|
EXP_OBS_SELECTED = BoolProperty(name="Selected Objects", description="Export selected objects on visible layers", default=True)
|
||||||
|
# EXP_OBS_SCENE = BoolProperty(name="Scene Objects", description="Export all objects in this scene", default=True)
|
||||||
|
TX_SCALE = FloatProperty(name="Scale", description="Scale all data, (Note! some imports dont support scaled armatures)", min=0.01, max=1000.0, soft_min=0.01, soft_max=1000.0, default=1.0)
|
||||||
|
TX_XROT90 = BoolProperty(name="Rot X90", description="Rotate all objects 90 degrees about the X axis", default=True)
|
||||||
|
TX_YROT90 = BoolProperty(name="Rot Y90", description="Rotate all objects 90 degrees about the Y axis", default=False)
|
||||||
|
TX_ZROT90 = BoolProperty(name="Rot Z90", description="Rotate all objects 90 degrees about the Z axis", default=False)
|
||||||
|
EXP_EMPTY = BoolProperty(name="Empties", description="Export empty objects", default=True)
|
||||||
|
EXP_CAMERA = BoolProperty(name="Cameras", description="Export camera objects", default=True)
|
||||||
|
EXP_LAMP = BoolProperty(name="Lamps", description="Export lamp objects", default=True)
|
||||||
|
EXP_ARMATURE = BoolProperty(name="Armatures", description="Export armature objects", default=True)
|
||||||
|
EXP_MESH = BoolProperty(name="Meshes", description="Export mesh objects", default=True)
|
||||||
|
EXP_MESH_APPLY_MOD = BoolProperty(name="Modifiers", description="Apply modifiers to mesh objects", default=True)
|
||||||
|
EXP_MESH_HQ_NORMALS = BoolProperty(name="HQ Normals", description="Generate high quality normals", default=True)
|
||||||
|
EXP_IMAGE_COPY = BoolProperty(name="Copy Image Files", description="Copy image files to the destination path", default=False)
|
||||||
|
# armature animation
|
||||||
|
ANIM_ENABLE = BoolProperty(name="Enable Animation", description="Export keyframe animation", default=True)
|
||||||
|
ANIM_OPTIMIZE = BoolProperty(name="Optimize Keyframes", description="Remove double keyframes", default=True)
|
||||||
|
ANIM_OPTIMIZE_PRECISSION = FloatProperty(name="Precision", description="Tolerence for comparing double keyframes (higher for greater accuracy)", min=1, max=16, soft_min=1, soft_max=16, default=6.0)
|
||||||
|
# ANIM_ACTION_ALL = BoolProperty(name="Current Action", description="Use actions currently applied to the armatures (use scene start/end frame)", default=True)
|
||||||
|
ANIM_ACTION_ALL = BoolProperty(name="All Actions", description="Use all actions for armatures, if false, use current action", default=False)
|
||||||
|
# batch
|
||||||
|
BATCH_ENABLE = BoolProperty(name="Enable Batch", description="Automate exporting multiple scenes or groups to files", default=False)
|
||||||
|
BATCH_GROUP = BoolProperty(name="Group > File", description="Export each group as an FBX file, if false, export each scene as an FBX file", default=False)
|
||||||
|
BATCH_OWN_DIR = BoolProperty(name="Own Dir", description="Create a dir for each exported file", default=True)
|
||||||
|
BATCH_FILE_PREFIX = StringProperty(name="Prefix", description="Prefix each file with this name", maxlen=1024, default="")
|
||||||
|
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
import math
|
||||||
|
from mathutils import Matrix
|
||||||
|
if not self.properties.filepath:
|
||||||
|
raise Exception("filepath not set")
|
||||||
|
|
||||||
|
mtx4_x90n = Matrix.Rotation(-math.pi/2.0, 4, 'X')
|
||||||
|
mtx4_y90n = Matrix.Rotation(-math.pi/2.0, 4, 'Y')
|
||||||
|
mtx4_z90n = Matrix.Rotation(-math.pi/2.0, 4, 'Z')
|
||||||
|
|
||||||
|
GLOBAL_MATRIX = Matrix()
|
||||||
|
GLOBAL_MATRIX[0][0] = GLOBAL_MATRIX[1][1] = GLOBAL_MATRIX[2][2] = self.properties.TX_SCALE
|
||||||
|
if self.properties.TX_XROT90: GLOBAL_MATRIX = mtx4_x90n * GLOBAL_MATRIX
|
||||||
|
if self.properties.TX_YROT90: GLOBAL_MATRIX = mtx4_y90n * GLOBAL_MATRIX
|
||||||
|
if self.properties.TX_ZROT90: GLOBAL_MATRIX = mtx4_z90n * GLOBAL_MATRIX
|
||||||
|
|
||||||
|
import io_scene_fbx.export_fbx
|
||||||
|
return io_scene_fbx.export_fbx.save(self, context, GLOBAL_MATRIX=GLOBAL_MATRIX, **self.properties)
|
||||||
|
|
||||||
|
|
||||||
|
def menu_func(self, context):
|
||||||
|
self.layout.operator(ExportFBX.bl_idname, text="Autodesk FBX (.fbx)")
|
||||||
|
|
||||||
|
|
||||||
|
def register():
|
||||||
|
bpy.types.INFO_MT_file_export.append(menu_func)
|
||||||
|
|
||||||
|
|
||||||
|
def unregister():
|
||||||
|
bpy.types.INFO_MT_file_export.remove(menu_func)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
register()
|
||||||
@@ -18,36 +18,13 @@
|
|||||||
|
|
||||||
# <pep8 compliant>
|
# <pep8 compliant>
|
||||||
|
|
||||||
__author__ = "Campbell Barton"
|
# Script copyright (C) Campbell Barton
|
||||||
__url__ = ['www.blender.org', 'blenderartists.org']
|
|
||||||
__version__ = "1.2"
|
|
||||||
|
|
||||||
__bpydoc__ = """\
|
"""
|
||||||
This script is an exporter to the FBX file format.
|
This script is an exporter to the FBX file format.
|
||||||
|
|
||||||
http://wiki.blender.org/index.php/Scripts/Manual/Export/autodesk_fbx
|
http://wiki.blender.org/index.php/Scripts/Manual/Export/autodesk_fbx
|
||||||
"""
|
"""
|
||||||
# --------------------------------------------------------------------------
|
|
||||||
# FBX Export v0.1 by Campbell Barton (AKA Ideasman)
|
|
||||||
# --------------------------------------------------------------------------
|
|
||||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or
|
|
||||||
# modify it under the terms of the GNU General Public License
|
|
||||||
# as published by the Free Software Foundation; either version 2
|
|
||||||
# of the License, or (at your option) any later version.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software Foundation,
|
|
||||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
#
|
|
||||||
# ***** END GPL LICENCE BLOCK *****
|
|
||||||
# --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
@@ -57,19 +34,10 @@ import shutil # for file copying
|
|||||||
import bpy
|
import bpy
|
||||||
from mathutils import Vector, Euler, Matrix
|
from mathutils import Vector, Euler, Matrix
|
||||||
|
|
||||||
def copy_file(source, dest):
|
|
||||||
# XXX - remove, can use shutil
|
|
||||||
file = open(source, 'rb')
|
|
||||||
data = file.read()
|
|
||||||
file.close()
|
|
||||||
|
|
||||||
file = open(dest, 'wb')
|
|
||||||
file.write(data)
|
|
||||||
file.close()
|
|
||||||
|
|
||||||
|
|
||||||
# XXX not used anymore, images are copied one at a time
|
# XXX not used anymore, images are copied one at a time
|
||||||
def copy_images(dest_dir, textures):
|
def copy_images(dest_dir, textures):
|
||||||
|
import shutil
|
||||||
|
|
||||||
if not dest_dir.endswith(os.sep):
|
if not dest_dir.endswith(os.sep):
|
||||||
dest_dir += os.sep
|
dest_dir += os.sep
|
||||||
|
|
||||||
@@ -84,12 +52,12 @@ def copy_images(dest_dir, textures):
|
|||||||
# Make a name for the target path.
|
# Make a name for the target path.
|
||||||
dest_image_path = dest_dir + image_path.split('\\')[-1].split('/')[-1]
|
dest_image_path = dest_dir + image_path.split('\\')[-1].split('/')[-1]
|
||||||
if not Blender.sys.exists(dest_image_path): # Image isnt already there
|
if not Blender.sys.exists(dest_image_path): # Image isnt already there
|
||||||
print('\tCopying "%s" > "%s"' % (image_path, dest_image_path))
|
print("\tCopying %r > %r" % (image_path, dest_image_path))
|
||||||
try:
|
try:
|
||||||
copy_file(image_path, dest_image_path)
|
shutil.copy(image_path, dest_image_path)
|
||||||
copyCount+=1
|
copyCount+=1
|
||||||
except:
|
except:
|
||||||
print('\t\tWarning, file failed to copy, skipping.')
|
print("\t\tWarning, file failed to copy, skipping.")
|
||||||
|
|
||||||
print('\tCopied %d images' % copyCount)
|
print('\tCopied %d images' % copyCount)
|
||||||
|
|
||||||
@@ -104,27 +72,11 @@ def eulerRadToDeg(eul):
|
|||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
mtx4_identity = Matrix()
|
|
||||||
|
|
||||||
# testing
|
|
||||||
mtx_x90 = Matrix.Rotation( math.pi/2, 3, 'X') # used
|
|
||||||
#mtx_x90n = Matrix.Rotation(-90, 3, 'x')
|
|
||||||
#mtx_y90 = Matrix.Rotation( 90, 3, 'y')
|
|
||||||
#mtx_y90n = Matrix.Rotation(-90, 3, 'y')
|
|
||||||
#mtx_z90 = Matrix.Rotation( 90, 3, 'z')
|
|
||||||
#mtx_z90n = Matrix.Rotation(-90, 3, 'z')
|
|
||||||
|
|
||||||
#mtx4_x90 = Matrix.Rotation( 90, 4, 'x')
|
|
||||||
mtx4_x90n = Matrix.Rotation(-math.pi/2, 4, 'X') # used
|
|
||||||
#mtx4_y90 = Matrix.Rotation( 90, 4, 'y')
|
|
||||||
mtx4_y90n = Matrix.Rotation(-math.pi/2, 4, 'Y') # used
|
|
||||||
mtx4_z90 = Matrix.Rotation( math.pi/2, 4, 'Z') # used
|
|
||||||
mtx4_z90n = Matrix.Rotation(-math.pi/2, 4, 'Z') # used
|
|
||||||
|
|
||||||
# def strip_path(p):
|
# def strip_path(p):
|
||||||
# return p.split('\\')[-1].split('/')[-1]
|
# return p.split('\\')[-1].split('/')[-1]
|
||||||
|
|
||||||
# Used to add the scene name into the filename without using odd chars
|
# Used to add the scene name into the filepath without using odd chars
|
||||||
sane_name_mapping_ob = {}
|
sane_name_mapping_ob = {}
|
||||||
sane_name_mapping_mat = {}
|
sane_name_mapping_mat = {}
|
||||||
sane_name_mapping_tex = {}
|
sane_name_mapping_tex = {}
|
||||||
@@ -197,7 +149,7 @@ def sane_groupname(data): return sane_name(data, sane_name_mapping_group)
|
|||||||
# '''
|
# '''
|
||||||
# fname_orig - blender path, can be relative
|
# fname_orig - blender path, can be relative
|
||||||
# basepath - fname_rel will be relative to this
|
# basepath - fname_rel will be relative to this
|
||||||
# FORCE_CWD - dont use the basepath, just add a ./ to the filename.
|
# FORCE_CWD - dont use the basepath, just add a ./ to the filepath.
|
||||||
# use when we know the file will be in the basepath.
|
# use when we know the file will be in the basepath.
|
||||||
# '''
|
# '''
|
||||||
# fname = bpy.path.abspath(fname_orig)
|
# fname = bpy.path.abspath(fname_orig)
|
||||||
@@ -282,19 +234,17 @@ header_comment = \
|
|||||||
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
# This func can be called with just the filename
|
# This func can be called with just the filepath
|
||||||
def write(filename, batch_objects = None, \
|
def save(operator, context, filepath="", \
|
||||||
context = None,
|
|
||||||
EXP_OBS_SELECTED = True,
|
EXP_OBS_SELECTED = True,
|
||||||
EXP_MESH = True,
|
EXP_MESH = True,
|
||||||
EXP_MESH_APPLY_MOD = True,
|
EXP_MESH_APPLY_MOD = True,
|
||||||
# EXP_MESH_HQ_NORMALS = False,
|
|
||||||
EXP_ARMATURE = True,
|
EXP_ARMATURE = True,
|
||||||
EXP_LAMP = True,
|
EXP_LAMP = True,
|
||||||
EXP_CAMERA = True,
|
EXP_CAMERA = True,
|
||||||
EXP_EMPTY = True,
|
EXP_EMPTY = True,
|
||||||
EXP_IMAGE_COPY = False,
|
EXP_IMAGE_COPY = False,
|
||||||
GLOBAL_MATRIX = Matrix(),
|
GLOBAL_MATRIX = None,
|
||||||
ANIM_ENABLE = True,
|
ANIM_ENABLE = True,
|
||||||
ANIM_OPTIMIZE = True,
|
ANIM_OPTIMIZE = True,
|
||||||
ANIM_OPTIMIZE_PRECISSION = 6,
|
ANIM_OPTIMIZE_PRECISSION = 6,
|
||||||
@@ -305,16 +255,26 @@ def write(filename, batch_objects = None, \
|
|||||||
BATCH_OWN_DIR = False
|
BATCH_OWN_DIR = False
|
||||||
):
|
):
|
||||||
|
|
||||||
if bpy.context.object:
|
#XXX, missing arg
|
||||||
|
batch_objects = None
|
||||||
|
|
||||||
|
# testing
|
||||||
|
mtx_x90 = Matrix.Rotation( math.pi/2.0, 3, 'X') # used
|
||||||
|
mtx4_z90 = Matrix.Rotation( math.pi/2.0, 4, 'Z')
|
||||||
|
|
||||||
|
if GLOBAL_MATRIX is None:
|
||||||
|
GLOBAL_MATRIX = Matrix()
|
||||||
|
|
||||||
|
if bpy.ops.object.mode_set.poll():
|
||||||
bpy.ops.object.mode_set(mode='OBJECT')
|
bpy.ops.object.mode_set(mode='OBJECT')
|
||||||
|
|
||||||
# ----------------- Batch support!
|
# ----------------- Batch support!
|
||||||
if BATCH_ENABLE:
|
if BATCH_ENABLE:
|
||||||
if os == None: BATCH_OWN_DIR = False
|
if os == None: BATCH_OWN_DIR = False
|
||||||
|
|
||||||
fbxpath = filename
|
fbxpath = filepath
|
||||||
|
|
||||||
# get the path component of filename
|
# get the path component of filepath
|
||||||
tmp_exists = bpy.utils.exists(fbxpath)
|
tmp_exists = bpy.utils.exists(fbxpath)
|
||||||
# tmp_exists = Blender.sys.exists(fbxpath)
|
# tmp_exists = Blender.sys.exists(fbxpath)
|
||||||
|
|
||||||
@@ -323,7 +283,7 @@ def write(filename, batch_objects = None, \
|
|||||||
# while fbxpath and fbxpath[-1] not in ('/', '\\'):
|
# while fbxpath and fbxpath[-1] not in ('/', '\\'):
|
||||||
# fbxpath = fbxpath[:-1]
|
# fbxpath = fbxpath[:-1]
|
||||||
if not fbxpath:
|
if not fbxpath:
|
||||||
# if not filename:
|
# if not filepath:
|
||||||
# XXX
|
# XXX
|
||||||
print('Error%t|Directory does not exist!')
|
print('Error%t|Directory does not exist!')
|
||||||
# Draw.PupMenu('Error%t|Directory does not exist!')
|
# Draw.PupMenu('Error%t|Directory does not exist!')
|
||||||
@@ -368,9 +328,9 @@ def write(filename, batch_objects = None, \
|
|||||||
os.mkdir(new_fbxpath)
|
os.mkdir(new_fbxpath)
|
||||||
|
|
||||||
|
|
||||||
filename = new_fbxpath + newname + '.fbx'
|
filepath = new_fbxpath + newname + '.fbx'
|
||||||
|
|
||||||
print('\nBatch exporting %s as...\n\t"%s"' % (data, filename))
|
print('\nBatch exporting %s as...\n\t%r' % (data, filepath))
|
||||||
|
|
||||||
# XXX don't know what to do with this, probably do the same? (Arystan)
|
# XXX don't know what to do with this, probably do the same? (Arystan)
|
||||||
if BATCH_GROUP: #group
|
if BATCH_GROUP: #group
|
||||||
@@ -393,12 +353,11 @@ def write(filename, batch_objects = None, \
|
|||||||
|
|
||||||
# Call self with modified args
|
# Call self with modified args
|
||||||
# Dont pass batch options since we already usedt them
|
# Dont pass batch options since we already usedt them
|
||||||
write(filename, data.objects,
|
write(filepath, data.objects,
|
||||||
context,
|
context,
|
||||||
False,
|
False,
|
||||||
EXP_MESH,
|
EXP_MESH,
|
||||||
EXP_MESH_APPLY_MOD,
|
EXP_MESH_APPLY_MOD,
|
||||||
# EXP_MESH_HQ_NORMALS,
|
|
||||||
EXP_ARMATURE,
|
EXP_ARMATURE,
|
||||||
EXP_LAMP,
|
EXP_LAMP,
|
||||||
EXP_CAMERA,
|
EXP_CAMERA,
|
||||||
@@ -423,9 +382,9 @@ def write(filename, batch_objects = None, \
|
|||||||
# end batch support
|
# end batch support
|
||||||
|
|
||||||
# Use this for working out paths relative to the export location
|
# Use this for working out paths relative to the export location
|
||||||
basepath = os.path.dirname(filename) or '.'
|
basepath = os.path.dirname(filepath) or '.'
|
||||||
basepath += os.sep
|
basepath += os.sep
|
||||||
# basepath = Blender.sys.dirname(filename)
|
# basepath = Blender.sys.dirname(filepath)
|
||||||
|
|
||||||
# ----------------------------------------------
|
# ----------------------------------------------
|
||||||
# storage classes
|
# storage classes
|
||||||
@@ -572,11 +531,11 @@ def write(filename, batch_objects = None, \
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
print('\nFBX export starting...', filename)
|
print('\nFBX export starting... %r' % filepath)
|
||||||
start_time = time.clock()
|
start_time = time.clock()
|
||||||
# start_time = Blender.sys.time()
|
# start_time = Blender.sys.time()
|
||||||
try:
|
try:
|
||||||
file = open(filename, 'w')
|
file = open(filepath, 'w')
|
||||||
except:
|
except:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@@ -2006,7 +1965,7 @@ def write(filename, batch_objects = None, \
|
|||||||
ob_base.update(scene)
|
ob_base.update(scene)
|
||||||
|
|
||||||
# This causes the makeDisplayList command to effect the mesh
|
# This causes the makeDisplayList command to effect the mesh
|
||||||
scene.set_frame(scene.frame_current)
|
scene.frame_set(scene.frame_current)
|
||||||
# Blender.Set('curframe', Blender.Get('curframe'))
|
# Blender.Set('curframe', Blender.Get('curframe'))
|
||||||
|
|
||||||
|
|
||||||
@@ -2179,7 +2138,7 @@ def write(filename, batch_objects = None, \
|
|||||||
if ob_base.type == 'ARMATURE':
|
if ob_base.type == 'ARMATURE':
|
||||||
ob_base.update(scene)
|
ob_base.update(scene)
|
||||||
# This causes the makeDisplayList command to effect the mesh
|
# This causes the makeDisplayList command to effect the mesh
|
||||||
scene.set_frame(scene.frame_current)
|
scene.frame_set(scene.frame_current)
|
||||||
# Blender.Set('curframe', Blender.Get('curframe'))
|
# Blender.Set('curframe', Blender.Get('curframe'))
|
||||||
|
|
||||||
del tmp_ob_type, tmp_objects
|
del tmp_ob_type, tmp_objects
|
||||||
@@ -2472,7 +2431,7 @@ Objects: {''')
|
|||||||
file.write('\n\t\tPoseNode: {')
|
file.write('\n\t\tPoseNode: {')
|
||||||
file.write('\n\t\t\tNode: "Model::%s"' % fbxName )
|
file.write('\n\t\t\tNode: "Model::%s"' % fbxName )
|
||||||
if matrix: file.write('\n\t\t\tMatrix: %s' % mat4x4str(matrix))
|
if matrix: file.write('\n\t\t\tMatrix: %s' % mat4x4str(matrix))
|
||||||
else: file.write('\n\t\t\tMatrix: %s' % mat4x4str(mtx4_identity))
|
else: file.write('\n\t\t\tMatrix: %s' % mat4x4str(Matrix()))
|
||||||
file.write('\n\t\t}')
|
file.write('\n\t\t}')
|
||||||
|
|
||||||
file.write('\n\t}')
|
file.write('\n\t}')
|
||||||
@@ -2760,7 +2719,9 @@ Takes: {''')
|
|||||||
else:
|
else:
|
||||||
file.write('\n\tTake: "%s" {' % sane_takename(blenAction))
|
file.write('\n\tTake: "%s" {' % sane_takename(blenAction))
|
||||||
|
|
||||||
act_start, act_end = blenAction.get_frame_range()
|
act_start, act_end = blenAction.frame_range
|
||||||
|
act_start = int(act_start)
|
||||||
|
act_end = int(act_end)
|
||||||
# tmp = blenAction.getFrameNumbers()
|
# tmp = blenAction.getFrameNumbers()
|
||||||
# if tmp:
|
# if tmp:
|
||||||
# act_start = min(tmp)
|
# act_start = min(tmp)
|
||||||
@@ -2797,7 +2758,7 @@ Takes: {''')
|
|||||||
'''
|
'''
|
||||||
i = act_start
|
i = act_start
|
||||||
while i <= act_end:
|
while i <= act_end:
|
||||||
scene.set_frame(i)
|
scene.frame_set(i)
|
||||||
# Blender.Set('curframe', i)
|
# Blender.Set('curframe', i)
|
||||||
for ob_generic in ob_anim_lists:
|
for ob_generic in ob_anim_lists:
|
||||||
for my_ob in ob_generic:
|
for my_ob in ob_generic:
|
||||||
@@ -2937,8 +2898,7 @@ Takes: {''')
|
|||||||
|
|
||||||
file.write('\n}')
|
file.write('\n}')
|
||||||
|
|
||||||
scene.set_frame(frame_orig)
|
scene.frame_set(frame_orig)
|
||||||
# Blender.Set('curframe', frame_orig)
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# no animation
|
# no animation
|
||||||
@@ -2967,12 +2927,10 @@ Takes: {''')
|
|||||||
mist_start = m.start
|
mist_start = m.start
|
||||||
mist_end = m.depth
|
mist_end = m.depth
|
||||||
mist_height = m.height
|
mist_height = m.height
|
||||||
# mist_intense, mist_start, mist_end, mist_height = world.mist
|
|
||||||
world_hor = world.horizon_color
|
world_hor = world.horizon_color
|
||||||
# world_hor = world.hor
|
|
||||||
else:
|
else:
|
||||||
has_mist = mist_intense = mist_start = mist_end = mist_height = 0
|
has_mist = mist_intense = mist_start = mist_end = mist_height = 0
|
||||||
world_hor = 0,0,0
|
world_hor = 0, 0, 0
|
||||||
|
|
||||||
file.write('\n;Version 5 settings')
|
file.write('\n;Version 5 settings')
|
||||||
file.write('\n;------------------------------------------------------------------')
|
file.write('\n;------------------------------------------------------------------')
|
||||||
@@ -3024,394 +2982,7 @@ Takes: {''')
|
|||||||
# bpy.util.copy_images( [ tex[1] for tex in textures if tex[1] != None ], basepath)
|
# bpy.util.copy_images( [ tex[1] for tex in textures if tex[1] != None ], basepath)
|
||||||
|
|
||||||
print('export finished in %.4f sec.' % (time.clock() - start_time))
|
print('export finished in %.4f sec.' % (time.clock() - start_time))
|
||||||
# print 'export finished in %.4f sec.' % (Blender.sys.time() - start_time)
|
return {'FINISHED'}
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
# --------------------------------------------
|
|
||||||
# UI Function - not a part of the exporter.
|
|
||||||
# this is to separate the user interface from the rest of the exporter.
|
|
||||||
# from Blender import Draw, Window
|
|
||||||
EVENT_NONE = 0
|
|
||||||
EVENT_EXIT = 1
|
|
||||||
EVENT_REDRAW = 2
|
|
||||||
EVENT_FILESEL = 3
|
|
||||||
|
|
||||||
GLOBALS = {}
|
|
||||||
|
|
||||||
# export opts
|
|
||||||
|
|
||||||
def do_redraw(e,v): GLOBALS['EVENT'] = e
|
|
||||||
|
|
||||||
# toggle between these 2, only allow one on at once
|
|
||||||
def do_obs_sel(e,v):
|
|
||||||
GLOBALS['EVENT'] = e
|
|
||||||
GLOBALS['EXP_OBS_SCENE'].val = 0
|
|
||||||
GLOBALS['EXP_OBS_SELECTED'].val = 1
|
|
||||||
|
|
||||||
def do_obs_sce(e,v):
|
|
||||||
GLOBALS['EVENT'] = e
|
|
||||||
GLOBALS['EXP_OBS_SCENE'].val = 1
|
|
||||||
GLOBALS['EXP_OBS_SELECTED'].val = 0
|
|
||||||
|
|
||||||
def do_batch_type_grp(e,v):
|
|
||||||
GLOBALS['EVENT'] = e
|
|
||||||
GLOBALS['BATCH_GROUP'].val = 1
|
|
||||||
GLOBALS['BATCH_SCENE'].val = 0
|
|
||||||
|
|
||||||
def do_batch_type_sce(e,v):
|
|
||||||
GLOBALS['EVENT'] = e
|
|
||||||
GLOBALS['BATCH_GROUP'].val = 0
|
|
||||||
GLOBALS['BATCH_SCENE'].val = 1
|
|
||||||
|
|
||||||
def do_anim_act_all(e,v):
|
|
||||||
GLOBALS['EVENT'] = e
|
|
||||||
GLOBALS['ANIM_ACTION_ALL'][0].val = 1
|
|
||||||
GLOBALS['ANIM_ACTION_ALL'][1].val = 0
|
|
||||||
|
|
||||||
def do_anim_act_cur(e,v):
|
|
||||||
if GLOBALS['BATCH_ENABLE'].val and GLOBALS['BATCH_GROUP'].val:
|
|
||||||
Draw.PupMenu('Warning%t|Cant use this with batch export group option')
|
|
||||||
else:
|
|
||||||
GLOBALS['EVENT'] = e
|
|
||||||
GLOBALS['ANIM_ACTION_ALL'][0].val = 0
|
|
||||||
GLOBALS['ANIM_ACTION_ALL'][1].val = 1
|
|
||||||
|
|
||||||
def fbx_ui_exit(e,v):
|
|
||||||
GLOBALS['EVENT'] = e
|
|
||||||
|
|
||||||
def do_help(e,v):
|
|
||||||
url = 'http://wiki.blender.org/index.php/Scripts/Manual/Export/autodesk_fbx'
|
|
||||||
print('Trying to open web browser with documentation at this address...')
|
|
||||||
print('\t' + url)
|
|
||||||
|
|
||||||
try:
|
|
||||||
import webbrowser
|
|
||||||
webbrowser.open(url)
|
|
||||||
except:
|
|
||||||
Blender.Draw.PupMenu("Error%t|Opening a webbrowser requires a full python installation")
|
|
||||||
print('...could not open a browser window.')
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# run when export is pressed
|
|
||||||
#def fbx_ui_write(e,v):
|
|
||||||
def fbx_ui_write(filename, context):
|
|
||||||
|
|
||||||
# Dont allow overwriting files when saving normally
|
|
||||||
if not GLOBALS['BATCH_ENABLE'].val:
|
|
||||||
if not BPyMessages.Warning_SaveOver(filename):
|
|
||||||
return
|
|
||||||
|
|
||||||
GLOBALS['EVENT'] = EVENT_EXIT
|
|
||||||
|
|
||||||
# Keep the order the same as above for simplicity
|
|
||||||
# the [] is a dummy arg used for objects
|
|
||||||
|
|
||||||
Blender.Window.WaitCursor(1)
|
|
||||||
|
|
||||||
# Make the matrix
|
|
||||||
GLOBAL_MATRIX = mtx4_identity
|
|
||||||
GLOBAL_MATRIX[0][0] = GLOBAL_MATRIX[1][1] = GLOBAL_MATRIX[2][2] = GLOBALS['_SCALE'].val
|
|
||||||
if GLOBALS['_XROT90'].val: GLOBAL_MATRIX = mtx4_x90n * GLOBAL_MATRIX
|
|
||||||
if GLOBALS['_YROT90'].val: GLOBAL_MATRIX = mtx4_y90n * GLOBAL_MATRIX
|
|
||||||
if GLOBALS['_ZROT90'].val: GLOBAL_MATRIX = mtx4_z90n * GLOBAL_MATRIX
|
|
||||||
|
|
||||||
ret = write(\
|
|
||||||
filename, None,\
|
|
||||||
context,
|
|
||||||
GLOBALS['EXP_OBS_SELECTED'].val,\
|
|
||||||
GLOBALS['EXP_MESH'].val,\
|
|
||||||
GLOBALS['EXP_MESH_APPLY_MOD'].val,\
|
|
||||||
GLOBALS['EXP_MESH_HQ_NORMALS'].val,\
|
|
||||||
GLOBALS['EXP_ARMATURE'].val,\
|
|
||||||
GLOBALS['EXP_LAMP'].val,\
|
|
||||||
GLOBALS['EXP_CAMERA'].val,\
|
|
||||||
GLOBALS['EXP_EMPTY'].val,\
|
|
||||||
GLOBALS['EXP_IMAGE_COPY'].val,\
|
|
||||||
GLOBAL_MATRIX,\
|
|
||||||
GLOBALS['ANIM_ENABLE'].val,\
|
|
||||||
GLOBALS['ANIM_OPTIMIZE'].val,\
|
|
||||||
GLOBALS['ANIM_OPTIMIZE_PRECISSION'].val,\
|
|
||||||
GLOBALS['ANIM_ACTION_ALL'][0].val,\
|
|
||||||
GLOBALS['BATCH_ENABLE'].val,\
|
|
||||||
GLOBALS['BATCH_GROUP'].val,\
|
|
||||||
GLOBALS['BATCH_SCENE'].val,\
|
|
||||||
GLOBALS['BATCH_FILE_PREFIX'].val,\
|
|
||||||
GLOBALS['BATCH_OWN_DIR'].val,\
|
|
||||||
)
|
|
||||||
|
|
||||||
Blender.Window.WaitCursor(0)
|
|
||||||
GLOBALS.clear()
|
|
||||||
|
|
||||||
if ret == False:
|
|
||||||
Draw.PupMenu('Error%t|Path cannot be written to!')
|
|
||||||
|
|
||||||
|
|
||||||
def fbx_ui():
|
|
||||||
# Only to center the UI
|
|
||||||
x,y = GLOBALS['MOUSE']
|
|
||||||
x-=180; y-=0 # offset... just to get it centered
|
|
||||||
|
|
||||||
Draw.Label('Export Objects...', x+20,y+165, 200, 20)
|
|
||||||
|
|
||||||
if not GLOBALS['BATCH_ENABLE'].val:
|
|
||||||
Draw.BeginAlign()
|
|
||||||
GLOBALS['EXP_OBS_SELECTED'] = Draw.Toggle('Selected Objects', EVENT_REDRAW, x+20, y+145, 160, 20, GLOBALS['EXP_OBS_SELECTED'].val, 'Export selected objects on visible layers', do_obs_sel)
|
|
||||||
GLOBALS['EXP_OBS_SCENE'] = Draw.Toggle('Scene Objects', EVENT_REDRAW, x+180, y+145, 160, 20, GLOBALS['EXP_OBS_SCENE'].val, 'Export all objects in this scene', do_obs_sce)
|
|
||||||
Draw.EndAlign()
|
|
||||||
|
|
||||||
Draw.BeginAlign()
|
|
||||||
GLOBALS['_SCALE'] = Draw.Number('Scale:', EVENT_NONE, x+20, y+120, 140, 20, GLOBALS['_SCALE'].val, 0.01, 1000.0, 'Scale all data, (Note! some imports dont support scaled armatures)')
|
|
||||||
GLOBALS['_XROT90'] = Draw.Toggle('Rot X90', EVENT_NONE, x+160, y+120, 60, 20, GLOBALS['_XROT90'].val, 'Rotate all objects 90 degrees about the X axis')
|
|
||||||
GLOBALS['_YROT90'] = Draw.Toggle('Rot Y90', EVENT_NONE, x+220, y+120, 60, 20, GLOBALS['_YROT90'].val, 'Rotate all objects 90 degrees about the Y axis')
|
|
||||||
GLOBALS['_ZROT90'] = Draw.Toggle('Rot Z90', EVENT_NONE, x+280, y+120, 60, 20, GLOBALS['_ZROT90'].val, 'Rotate all objects 90 degrees about the Z axis')
|
|
||||||
Draw.EndAlign()
|
|
||||||
|
|
||||||
y -= 35
|
|
||||||
|
|
||||||
Draw.BeginAlign()
|
|
||||||
GLOBALS['EXP_EMPTY'] = Draw.Toggle('Empty', EVENT_NONE, x+20, y+120, 60, 20, GLOBALS['EXP_EMPTY'].val, 'Export empty objects')
|
|
||||||
GLOBALS['EXP_CAMERA'] = Draw.Toggle('Camera', EVENT_NONE, x+80, y+120, 60, 20, GLOBALS['EXP_CAMERA'].val, 'Export camera objects')
|
|
||||||
GLOBALS['EXP_LAMP'] = Draw.Toggle('Lamp', EVENT_NONE, x+140, y+120, 60, 20, GLOBALS['EXP_LAMP'].val, 'Export lamp objects')
|
|
||||||
GLOBALS['EXP_ARMATURE'] = Draw.Toggle('Armature', EVENT_NONE, x+200, y+120, 60, 20, GLOBALS['EXP_ARMATURE'].val, 'Export armature objects')
|
|
||||||
GLOBALS['EXP_MESH'] = Draw.Toggle('Mesh', EVENT_REDRAW, x+260, y+120, 80, 20, GLOBALS['EXP_MESH'].val, 'Export mesh objects', do_redraw) #, do_axis_z)
|
|
||||||
Draw.EndAlign()
|
|
||||||
|
|
||||||
if GLOBALS['EXP_MESH'].val:
|
|
||||||
# below mesh but
|
|
||||||
Draw.BeginAlign()
|
|
||||||
GLOBALS['EXP_MESH_APPLY_MOD'] = Draw.Toggle('Modifiers', EVENT_NONE, x+260, y+100, 80, 20, GLOBALS['EXP_MESH_APPLY_MOD'].val, 'Apply modifiers to mesh objects') #, do_axis_z)
|
|
||||||
GLOBALS['EXP_MESH_HQ_NORMALS'] = Draw.Toggle('HQ Normals', EVENT_NONE, x+260, y+80, 80, 20, GLOBALS['EXP_MESH_HQ_NORMALS'].val, 'Generate high quality normals') #, do_axis_z)
|
|
||||||
Draw.EndAlign()
|
|
||||||
|
|
||||||
GLOBALS['EXP_IMAGE_COPY'] = Draw.Toggle('Copy Image Files', EVENT_NONE, x+20, y+80, 160, 20, GLOBALS['EXP_IMAGE_COPY'].val, 'Copy image files to the destination path') #, do_axis_z)
|
|
||||||
|
|
||||||
|
|
||||||
Draw.Label('Export Armature Animation...', x+20,y+45, 300, 20)
|
|
||||||
|
|
||||||
GLOBALS['ANIM_ENABLE'] = Draw.Toggle('Enable Animation', EVENT_REDRAW, x+20, y+25, 160, 20, GLOBALS['ANIM_ENABLE'].val, 'Export keyframe animation', do_redraw)
|
|
||||||
if GLOBALS['ANIM_ENABLE'].val:
|
|
||||||
Draw.BeginAlign()
|
|
||||||
GLOBALS['ANIM_OPTIMIZE'] = Draw.Toggle('Optimize Keyframes', EVENT_REDRAW, x+20, y+0, 160, 20, GLOBALS['ANIM_OPTIMIZE'].val, 'Remove double keyframes', do_redraw)
|
|
||||||
if GLOBALS['ANIM_OPTIMIZE'].val:
|
|
||||||
GLOBALS['ANIM_OPTIMIZE_PRECISSION'] = Draw.Number('Precission: ', EVENT_NONE, x+180, y+0, 160, 20, GLOBALS['ANIM_OPTIMIZE_PRECISSION'].val, 1, 16, 'Tolerence for comparing double keyframes (higher for greater accuracy)')
|
|
||||||
Draw.EndAlign()
|
|
||||||
|
|
||||||
Draw.BeginAlign()
|
|
||||||
GLOBALS['ANIM_ACTION_ALL'][1] = Draw.Toggle('Current Action', EVENT_REDRAW, x+20, y-25, 160, 20, GLOBALS['ANIM_ACTION_ALL'][1].val, 'Use actions currently applied to the armatures (use scene start/end frame)', do_anim_act_cur)
|
|
||||||
GLOBALS['ANIM_ACTION_ALL'][0] = Draw.Toggle('All Actions', EVENT_REDRAW, x+180,y-25, 160, 20, GLOBALS['ANIM_ACTION_ALL'][0].val, 'Use all actions for armatures', do_anim_act_all)
|
|
||||||
Draw.EndAlign()
|
|
||||||
|
|
||||||
|
|
||||||
Draw.Label('Export Batch...', x+20,y-60, 300, 20)
|
|
||||||
GLOBALS['BATCH_ENABLE'] = Draw.Toggle('Enable Batch', EVENT_REDRAW, x+20, y-80, 160, 20, GLOBALS['BATCH_ENABLE'].val, 'Automate exporting multiple scenes or groups to files', do_redraw)
|
|
||||||
|
|
||||||
if GLOBALS['BATCH_ENABLE'].val:
|
|
||||||
Draw.BeginAlign()
|
|
||||||
GLOBALS['BATCH_GROUP'] = Draw.Toggle('Group > File', EVENT_REDRAW, x+20, y-105, 160, 20, GLOBALS['BATCH_GROUP'].val, 'Export each group as an FBX file', do_batch_type_grp)
|
|
||||||
GLOBALS['BATCH_SCENE'] = Draw.Toggle('Scene > File', EVENT_REDRAW, x+180, y-105, 160, 20, GLOBALS['BATCH_SCENE'].val, 'Export each scene as an FBX file', do_batch_type_sce)
|
|
||||||
|
|
||||||
# Own dir requires OS module
|
|
||||||
if os:
|
|
||||||
GLOBALS['BATCH_OWN_DIR'] = Draw.Toggle('Own Dir', EVENT_NONE, x+20, y-125, 80, 20, GLOBALS['BATCH_OWN_DIR'].val, 'Create a dir for each exported file')
|
|
||||||
GLOBALS['BATCH_FILE_PREFIX'] = Draw.String('Prefix: ', EVENT_NONE, x+100, y-125, 240, 20, GLOBALS['BATCH_FILE_PREFIX'].val, 64, 'Prefix each file with this name ')
|
|
||||||
else:
|
|
||||||
GLOBALS['BATCH_FILE_PREFIX'] = Draw.String('Prefix: ', EVENT_NONE, x+20, y-125, 320, 20, GLOBALS['BATCH_FILE_PREFIX'].val, 64, 'Prefix each file with this name ')
|
|
||||||
|
|
||||||
|
|
||||||
Draw.EndAlign()
|
|
||||||
|
|
||||||
#y+=80
|
|
||||||
|
|
||||||
'''
|
|
||||||
Draw.BeginAlign()
|
|
||||||
GLOBALS['FILENAME'] = Draw.String('path: ', EVENT_NONE, x+20, y-170, 300, 20, GLOBALS['FILENAME'].val, 64, 'Prefix each file with this name ')
|
|
||||||
Draw.PushButton('..', EVENT_FILESEL, x+320, y-170, 20, 20, 'Select the path', do_redraw)
|
|
||||||
'''
|
|
||||||
# Until batch is added
|
|
||||||
#
|
|
||||||
|
|
||||||
|
|
||||||
#Draw.BeginAlign()
|
|
||||||
Draw.PushButton('Online Help', EVENT_REDRAW, x+20, y-160, 100, 20, 'Open online help in a browser window', do_help)
|
|
||||||
Draw.PushButton('Cancel', EVENT_EXIT, x+130, y-160, 100, 20, 'Exit the exporter', fbx_ui_exit)
|
|
||||||
Draw.PushButton('Export', EVENT_FILESEL, x+240, y-160, 100, 20, 'Export the fbx file', do_redraw)
|
|
||||||
|
|
||||||
#Draw.PushButton('Export', EVENT_EXIT, x+180, y-160, 160, 20, 'Export the fbx file', fbx_ui_write)
|
|
||||||
#Draw.EndAlign()
|
|
||||||
|
|
||||||
# exit when mouse out of the view?
|
|
||||||
# GLOBALS['EVENT'] = EVENT_EXIT
|
|
||||||
|
|
||||||
#def write_ui(filename):
|
|
||||||
def write_ui():
|
|
||||||
|
|
||||||
# globals
|
|
||||||
GLOBALS['EVENT'] = EVENT_REDRAW
|
|
||||||
#GLOBALS['MOUSE'] = Window.GetMouseCoords()
|
|
||||||
GLOBALS['MOUSE'] = [i/2 for i in Window.GetScreenSize()]
|
|
||||||
GLOBALS['FILENAME'] = ''
|
|
||||||
'''
|
|
||||||
# IF called from the fileselector
|
|
||||||
if filename == None:
|
|
||||||
GLOBALS['FILENAME'] = filename # Draw.Create(Blender.sys.makename(ext='.fbx'))
|
|
||||||
else:
|
|
||||||
GLOBALS['FILENAME'].val = filename
|
|
||||||
'''
|
|
||||||
GLOBALS['EXP_OBS_SELECTED'] = Draw.Create(1) # dont need 2 variables but just do this for clarity
|
|
||||||
GLOBALS['EXP_OBS_SCENE'] = Draw.Create(0)
|
|
||||||
|
|
||||||
GLOBALS['EXP_MESH'] = Draw.Create(1)
|
|
||||||
GLOBALS['EXP_MESH_APPLY_MOD'] = Draw.Create(1)
|
|
||||||
GLOBALS['EXP_MESH_HQ_NORMALS'] = Draw.Create(0)
|
|
||||||
GLOBALS['EXP_ARMATURE'] = Draw.Create(1)
|
|
||||||
GLOBALS['EXP_LAMP'] = Draw.Create(1)
|
|
||||||
GLOBALS['EXP_CAMERA'] = Draw.Create(1)
|
|
||||||
GLOBALS['EXP_EMPTY'] = Draw.Create(1)
|
|
||||||
GLOBALS['EXP_IMAGE_COPY'] = Draw.Create(0)
|
|
||||||
# animation opts
|
|
||||||
GLOBALS['ANIM_ENABLE'] = Draw.Create(1)
|
|
||||||
GLOBALS['ANIM_OPTIMIZE'] = Draw.Create(1)
|
|
||||||
GLOBALS['ANIM_OPTIMIZE_PRECISSION'] = Draw.Create(4) # decimal places
|
|
||||||
GLOBALS['ANIM_ACTION_ALL'] = [Draw.Create(0), Draw.Create(1)] # not just the current action
|
|
||||||
|
|
||||||
# batch export options
|
|
||||||
GLOBALS['BATCH_ENABLE'] = Draw.Create(0)
|
|
||||||
GLOBALS['BATCH_GROUP'] = Draw.Create(1) # cant have both of these enabled at once.
|
|
||||||
GLOBALS['BATCH_SCENE'] = Draw.Create(0) # see above
|
|
||||||
GLOBALS['BATCH_FILE_PREFIX'] = Draw.Create(Blender.sys.makename(ext='_').split('\\')[-1].split('/')[-1])
|
|
||||||
GLOBALS['BATCH_OWN_DIR'] = Draw.Create(0)
|
|
||||||
# done setting globals
|
|
||||||
|
|
||||||
# Used by the user interface
|
|
||||||
GLOBALS['_SCALE'] = Draw.Create(1.0)
|
|
||||||
GLOBALS['_XROT90'] = Draw.Create(True)
|
|
||||||
GLOBALS['_YROT90'] = Draw.Create(False)
|
|
||||||
GLOBALS['_ZROT90'] = Draw.Create(False)
|
|
||||||
|
|
||||||
# best not do move the cursor
|
|
||||||
# Window.SetMouseCoords(*[i/2 for i in Window.GetScreenSize()])
|
|
||||||
|
|
||||||
# hack so the toggle buttons redraw. this is not nice at all
|
|
||||||
while GLOBALS['EVENT'] != EVENT_EXIT:
|
|
||||||
|
|
||||||
if GLOBALS['BATCH_ENABLE'].val and GLOBALS['BATCH_GROUP'].val and GLOBALS['ANIM_ACTION_ALL'][1].val:
|
|
||||||
#Draw.PupMenu("Warning%t|Cant batch export groups with 'Current Action' ")
|
|
||||||
GLOBALS['ANIM_ACTION_ALL'][0].val = 1
|
|
||||||
GLOBALS['ANIM_ACTION_ALL'][1].val = 0
|
|
||||||
|
|
||||||
if GLOBALS['EVENT'] == EVENT_FILESEL:
|
|
||||||
if GLOBALS['BATCH_ENABLE'].val:
|
|
||||||
txt = 'Batch FBX Dir'
|
|
||||||
name = Blender.sys.expandpath('//')
|
|
||||||
else:
|
|
||||||
txt = 'Export FBX'
|
|
||||||
name = Blender.sys.makename(ext='.fbx')
|
|
||||||
|
|
||||||
Blender.Window.FileSelector(fbx_ui_write, txt, name)
|
|
||||||
#fbx_ui_write('/test.fbx')
|
|
||||||
break
|
|
||||||
|
|
||||||
Draw.UIBlock(fbx_ui, 0)
|
|
||||||
|
|
||||||
|
|
||||||
# GLOBALS.clear()
|
|
||||||
from bpy.props import *
|
|
||||||
class ExportFBX(bpy.types.Operator):
|
|
||||||
'''Selection to an ASCII Autodesk FBX'''
|
|
||||||
bl_idname = "export.fbx"
|
|
||||||
bl_label = "Export FBX"
|
|
||||||
|
|
||||||
# List of operator properties, the attributes will be assigned
|
|
||||||
# to the class instance from the operator settings before calling.
|
|
||||||
|
|
||||||
|
|
||||||
filepath = StringProperty(name="File Path", description="Filepath used for exporting the FBX file", maxlen= 1024, default="")
|
|
||||||
check_existing = BoolProperty(name="Check Existing", description="Check and warn on overwriting existing files", default=True, options={'HIDDEN'})
|
|
||||||
|
|
||||||
EXP_OBS_SELECTED = BoolProperty(name="Selected Objects", description="Export selected objects on visible layers", default=True)
|
|
||||||
# EXP_OBS_SCENE = BoolProperty(name="Scene Objects", description="Export all objects in this scene", default=True)
|
|
||||||
TX_SCALE = FloatProperty(name="Scale", description="Scale all data, (Note! some imports dont support scaled armatures)", min=0.01, max=1000.0, soft_min=0.01, soft_max=1000.0, default=1.0)
|
|
||||||
TX_XROT90 = BoolProperty(name="Rot X90", description="Rotate all objects 90 degrees about the X axis", default=True)
|
|
||||||
TX_YROT90 = BoolProperty(name="Rot Y90", description="Rotate all objects 90 degrees about the Y axis", default=False)
|
|
||||||
TX_ZROT90 = BoolProperty(name="Rot Z90", description="Rotate all objects 90 degrees about the Z axis", default=False)
|
|
||||||
EXP_EMPTY = BoolProperty(name="Empties", description="Export empty objects", default=True)
|
|
||||||
EXP_CAMERA = BoolProperty(name="Cameras", description="Export camera objects", default=True)
|
|
||||||
EXP_LAMP = BoolProperty(name="Lamps", description="Export lamp objects", default=True)
|
|
||||||
EXP_ARMATURE = BoolProperty(name="Armatures", description="Export armature objects", default=True)
|
|
||||||
EXP_MESH = BoolProperty(name="Meshes", description="Export mesh objects", default=True)
|
|
||||||
EXP_MESH_APPLY_MOD = BoolProperty(name="Modifiers", description="Apply modifiers to mesh objects", default=True)
|
|
||||||
EXP_MESH_HQ_NORMALS = BoolProperty(name="HQ Normals", description="Generate high quality normals", default=True)
|
|
||||||
EXP_IMAGE_COPY = BoolProperty(name="Copy Image Files", description="Copy image files to the destination path", default=False)
|
|
||||||
# armature animation
|
|
||||||
ANIM_ENABLE = BoolProperty(name="Enable Animation", description="Export keyframe animation", default=True)
|
|
||||||
ANIM_OPTIMIZE = BoolProperty(name="Optimize Keyframes", description="Remove double keyframes", default=True)
|
|
||||||
ANIM_OPTIMIZE_PRECISSION = FloatProperty(name="Precision", description="Tolerence for comparing double keyframes (higher for greater accuracy)", min=1, max=16, soft_min=1, soft_max=16, default=6.0)
|
|
||||||
# ANIM_ACTION_ALL = BoolProperty(name="Current Action", description="Use actions currently applied to the armatures (use scene start/end frame)", default=True)
|
|
||||||
ANIM_ACTION_ALL = BoolProperty(name="All Actions", description="Use all actions for armatures, if false, use current action", default=False)
|
|
||||||
# batch
|
|
||||||
BATCH_ENABLE = BoolProperty(name="Enable Batch", description="Automate exporting multiple scenes or groups to files", default=False)
|
|
||||||
BATCH_GROUP = BoolProperty(name="Group > File", description="Export each group as an FBX file, if false, export each scene as an FBX file", default=False)
|
|
||||||
BATCH_OWN_DIR = BoolProperty(name="Own Dir", description="Create a dir for each exported file", default=True)
|
|
||||||
BATCH_FILE_PREFIX = StringProperty(name="Prefix", description="Prefix each file with this name", maxlen=1024, default="")
|
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def poll(cls, context):
|
|
||||||
return context.active_object
|
|
||||||
|
|
||||||
def execute(self, context):
|
|
||||||
if not self.properties.filepath:
|
|
||||||
raise Exception("filepath not set")
|
|
||||||
|
|
||||||
filepath = self.properties.filepath
|
|
||||||
filepath = bpy.path.ensure_ext(filepath, ".fbx")
|
|
||||||
|
|
||||||
GLOBAL_MATRIX = mtx4_identity
|
|
||||||
GLOBAL_MATRIX[0][0] = GLOBAL_MATRIX[1][1] = GLOBAL_MATRIX[2][2] = self.properties.TX_SCALE
|
|
||||||
if self.properties.TX_XROT90: GLOBAL_MATRIX = mtx4_x90n * GLOBAL_MATRIX
|
|
||||||
if self.properties.TX_YROT90: GLOBAL_MATRIX = mtx4_y90n * GLOBAL_MATRIX
|
|
||||||
if self.properties.TX_ZROT90: GLOBAL_MATRIX = mtx4_z90n * GLOBAL_MATRIX
|
|
||||||
|
|
||||||
write(filepath,
|
|
||||||
None, # XXX
|
|
||||||
context,
|
|
||||||
self.properties.EXP_OBS_SELECTED,
|
|
||||||
self.properties.EXP_MESH,
|
|
||||||
self.properties.EXP_MESH_APPLY_MOD,
|
|
||||||
# self.properties.EXP_MESH_HQ_NORMALS,
|
|
||||||
self.properties.EXP_ARMATURE,
|
|
||||||
self.properties.EXP_LAMP,
|
|
||||||
self.properties.EXP_CAMERA,
|
|
||||||
self.properties.EXP_EMPTY,
|
|
||||||
self.properties.EXP_IMAGE_COPY,
|
|
||||||
GLOBAL_MATRIX,
|
|
||||||
self.properties.ANIM_ENABLE,
|
|
||||||
self.properties.ANIM_OPTIMIZE,
|
|
||||||
self.properties.ANIM_OPTIMIZE_PRECISSION,
|
|
||||||
self.properties.ANIM_ACTION_ALL,
|
|
||||||
self.properties.BATCH_ENABLE,
|
|
||||||
self.properties.BATCH_GROUP,
|
|
||||||
self.properties.BATCH_FILE_PREFIX,
|
|
||||||
self.properties.BATCH_OWN_DIR,
|
|
||||||
)
|
|
||||||
|
|
||||||
return {'FINISHED'}
|
|
||||||
|
|
||||||
def invoke(self, context, event):
|
|
||||||
import os
|
|
||||||
if not self.properties.is_property_set("filepath"):
|
|
||||||
self.properties.filepath = os.path.splitext(bpy.data.filepath)[0] + ".fbx"
|
|
||||||
|
|
||||||
context.manager.add_fileselect(self)
|
|
||||||
return {'RUNNING_MODAL'}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# if __name__ == "__main__":
|
|
||||||
# bpy.ops.EXPORT_OT_ply(filepath="/tmp/test.ply")
|
|
||||||
|
|
||||||
|
|
||||||
# NOTES (all line numbers correspond to original export_fbx.py (under release/scripts)
|
# NOTES (all line numbers correspond to original export_fbx.py (under release/scripts)
|
||||||
@@ -3432,21 +3003,3 @@ class ExportFBX(bpy.types.Operator):
|
|||||||
# - bpy.sys.time move to bpy.sys.util?
|
# - bpy.sys.time move to bpy.sys.util?
|
||||||
# - new scene creation, activation: lines 327-342, 368
|
# - new scene creation, activation: lines 327-342, 368
|
||||||
# - uses bpy.path.abspath, *.relpath - replace at least relpath
|
# - uses bpy.path.abspath, *.relpath - replace at least relpath
|
||||||
|
|
||||||
# SMALL or COSMETICAL
|
|
||||||
# - find a way to get blender version, and put it in bpy.util?, old was Blender.Get('version')
|
|
||||||
|
|
||||||
|
|
||||||
def menu_func(self, context):
|
|
||||||
self.layout.operator(ExportFBX.bl_idname, text="Autodesk FBX (.fbx)")
|
|
||||||
|
|
||||||
|
|
||||||
def register():
|
|
||||||
bpy.types.INFO_MT_file_export.append(menu_func)
|
|
||||||
|
|
||||||
|
|
||||||
def unregister():
|
|
||||||
bpy.types.INFO_MT_file_export.remove(menu_func)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
register()
|
|
||||||
144
release/scripts/op/io_scene_obj/__init__.py
Normal file
144
release/scripts/op/io_scene_obj/__init__.py
Normal file
@@ -0,0 +1,144 @@
|
|||||||
|
# ##### BEGIN GPL LICENSE BLOCK #####
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software Foundation,
|
||||||
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
#
|
||||||
|
# ##### END GPL LICENSE BLOCK #####
|
||||||
|
|
||||||
|
# <pep8 compliant>
|
||||||
|
|
||||||
|
# To support reload properly, try to access a package var, if it's there, reload everything
|
||||||
|
if "bpy" in locals():
|
||||||
|
# only reload if we alredy loaded, highly annoying
|
||||||
|
import sys
|
||||||
|
reload(sys.modules.get("io_scene_obj.import_obj", sys))
|
||||||
|
reload(sys.modules.get("io_scene_obj.export_obj", sys))
|
||||||
|
|
||||||
|
|
||||||
|
import bpy
|
||||||
|
from bpy.props import *
|
||||||
|
from io_utils import ExportHelper, ImportHelper
|
||||||
|
|
||||||
|
|
||||||
|
class ImportOBJ(bpy.types.Operator, ImportHelper):
|
||||||
|
'''Load a Wavefront OBJ File'''
|
||||||
|
bl_idname = "import_scene.obj"
|
||||||
|
bl_label = "Import OBJ"
|
||||||
|
|
||||||
|
filename_ext = ".obj"
|
||||||
|
|
||||||
|
CREATE_SMOOTH_GROUPS = BoolProperty(name="Smooth Groups", description="Surround smooth groups by sharp edges", default= True)
|
||||||
|
CREATE_FGONS = BoolProperty(name="NGons as FGons", description="Import faces with more then 4 verts as fgons", default= True)
|
||||||
|
CREATE_EDGES = BoolProperty(name="Lines as Edges", description="Import lines and faces with 2 verts as edge", default= True)
|
||||||
|
SPLIT_OBJECTS = BoolProperty(name="Object", description="Import OBJ Objects into Blender Objects", default= True)
|
||||||
|
SPLIT_GROUPS = BoolProperty(name="Group", description="Import OBJ Groups into Blender Objects", default= True)
|
||||||
|
# old comment: only used for user feedback
|
||||||
|
# disabled this option because in old code a handler for it disabled SPLIT* params, it's not passed to load_obj
|
||||||
|
# KEEP_VERT_ORDER = BoolProperty(name="Keep Vert Order", description="Keep vert and face order, disables split options, enable for morph targets", default= True)
|
||||||
|
ROTATE_X90 = BoolProperty(name="-X90", description="Rotate X 90.", default= True)
|
||||||
|
CLAMP_SIZE = FloatProperty(name="Clamp Scale", description="Clamp the size to this maximum (Zero to Disable)", min=0.0, max=1000.0, soft_min=0.0, soft_max=1000.0, default=0.0)
|
||||||
|
POLYGROUPS = BoolProperty(name="Poly Groups", description="Import OBJ groups as vertex groups.", default= True)
|
||||||
|
IMAGE_SEARCH = BoolProperty(name="Image Search", description="Search subdirs for any assosiated images (Warning, may be slow)", default= True)
|
||||||
|
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
# print("Selected: " + context.active_object.name)
|
||||||
|
import io_scene_obj.import_obj
|
||||||
|
return io_scene_obj.import_obj.load(self, context, **self.properties)
|
||||||
|
'''
|
||||||
|
load_obj(self.properties.filepath,
|
||||||
|
context,
|
||||||
|
self.properties.CLAMP_SIZE,
|
||||||
|
self.properties.CREATE_FGONS,
|
||||||
|
self.properties.CREATE_SMOOTH_GROUPS,
|
||||||
|
self.properties.CREATE_EDGES,
|
||||||
|
self.properties.SPLIT_OBJECTS,
|
||||||
|
self.properties.SPLIT_GROUPS,
|
||||||
|
self.properties.ROTATE_X90,
|
||||||
|
self.properties.IMAGE_SEARCH,
|
||||||
|
self.properties.POLYGROUPS)
|
||||||
|
'''
|
||||||
|
|
||||||
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
|
class ExportOBJ(bpy.types.Operator, ExportHelper):
|
||||||
|
'''Save a Wavefront OBJ File'''
|
||||||
|
|
||||||
|
bl_idname = "export_scene.obj"
|
||||||
|
bl_label = 'Export OBJ'
|
||||||
|
|
||||||
|
filename_ext = ".obj"
|
||||||
|
|
||||||
|
# List of operator properties, the attributes will be assigned
|
||||||
|
# to the class instance from the operator settings before calling.
|
||||||
|
|
||||||
|
# context group
|
||||||
|
use_selection = BoolProperty(name="Selection Only", description="Export selected objects only", default= False)
|
||||||
|
use_all_scenes = BoolProperty(name="All Scenes", description="", default= False)
|
||||||
|
use_animation = BoolProperty(name="Animation", description="", default= False)
|
||||||
|
|
||||||
|
# object group
|
||||||
|
use_modifiers = BoolProperty(name="Apply Modifiers", description="Apply modifiers (preview resolution)", default= True)
|
||||||
|
use_rotate_x90 = BoolProperty(name="Rotate X90", description="", default= True)
|
||||||
|
|
||||||
|
# extra data group
|
||||||
|
use_edges = BoolProperty(name="Edges", description="", default=True)
|
||||||
|
use_normals = BoolProperty(name="Normals", description="", default=False)
|
||||||
|
use_hq_normals = BoolProperty(name="High Quality Normals", description="", default=True)
|
||||||
|
use_uvs = BoolProperty(name="UVs", description="", default= True)
|
||||||
|
use_materials = BoolProperty(name="Materials", description="", default=True)
|
||||||
|
copy_images = BoolProperty(name="Copy Images", description="", default=False)
|
||||||
|
use_triangles = BoolProperty(name="Triangulate", description="", default=False)
|
||||||
|
use_vertex_groups = BoolProperty(name="Polygroups", description="", default=False)
|
||||||
|
use_nurbs = BoolProperty(name="Nurbs", description="", default=False)
|
||||||
|
|
||||||
|
# grouping group
|
||||||
|
use_blen_objects = BoolProperty(name="Objects as OBJ Objects", description="", default= True)
|
||||||
|
group_by_object = BoolProperty(name="Objects as OBJ Groups ", description="", default= False)
|
||||||
|
group_by_material = BoolProperty(name="Material Groups", description="", default= False)
|
||||||
|
keep_vertex_order = BoolProperty(name="Keep Vertex Order", description="", default= False)
|
||||||
|
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
import io_scene_obj.export_obj
|
||||||
|
print(self.properties.keys())
|
||||||
|
return io_scene_obj.export_obj.save(self, context, **self.properties)
|
||||||
|
|
||||||
|
|
||||||
|
def menu_func_import(self, context):
|
||||||
|
self.layout.operator(ImportOBJ.bl_idname, text="Wavefront (.obj)")
|
||||||
|
|
||||||
|
|
||||||
|
def menu_func_export(self, context):
|
||||||
|
self.layout.operator(ExportOBJ.bl_idname, text="Wavefront (.obj)")
|
||||||
|
|
||||||
|
|
||||||
|
def register():
|
||||||
|
bpy.types.INFO_MT_file_import.append(menu_func_import)
|
||||||
|
bpy.types.INFO_MT_file_export.append(menu_func_export)
|
||||||
|
|
||||||
|
def unregister():
|
||||||
|
bpy.types.INFO_MT_file_import.remove(menu_func_import)
|
||||||
|
bpy.types.INFO_MT_file_export.remove(menu_func_export)
|
||||||
|
|
||||||
|
|
||||||
|
# CONVERSION ISSUES
|
||||||
|
# - matrix problem
|
||||||
|
# - duplis - only tested dupliverts
|
||||||
|
# - all scenes export
|
||||||
|
# + normals calculation
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
register()
|
||||||
@@ -18,23 +18,6 @@
|
|||||||
|
|
||||||
# <pep8 compliant>
|
# <pep8 compliant>
|
||||||
|
|
||||||
__author__ = "Campbell Barton, Jiri Hnidek, Paolo Ciccone"
|
|
||||||
__url__ = ['http://wiki.blender.org/index.php/Scripts/Manual/Export/wavefront_obj', 'www.blender.org', 'blenderartists.org']
|
|
||||||
__version__ = "1.21"
|
|
||||||
|
|
||||||
__bpydoc__ = """\
|
|
||||||
This script is an exporter to OBJ file format.
|
|
||||||
|
|
||||||
Usage:
|
|
||||||
|
|
||||||
Select the objects you wish to export and run this script from "File->Export" menu.
|
|
||||||
Selecting the default options from the popup box will be good in most cases.
|
|
||||||
All objects that can be represented as a mesh (mesh, curve, metaball, surface, text3d)
|
|
||||||
will be exported as mesh data.
|
|
||||||
"""
|
|
||||||
|
|
||||||
# import math and other in functions that use them for the sake of fast Blender startup
|
|
||||||
# import math
|
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
import shutil
|
import shutil
|
||||||
@@ -122,7 +105,7 @@ def write_mtl(scene, filepath, copy_images, mtl_dict):
|
|||||||
try:
|
try:
|
||||||
filepath = copy_image(mtex.texture.image)
|
filepath = copy_image(mtex.texture.image)
|
||||||
# filepath = mtex.texture.image.filepath.split('\\')[-1].split('/')[-1]
|
# filepath = mtex.texture.image.filepath.split('\\')[-1].split('/')[-1]
|
||||||
file.write('map_Kd %s\n' % filepath) # Diffuse mapping image
|
file.write('map_Kd %s\n' % repr(filepath)[1:-1]) # Diffuse mapping image
|
||||||
break
|
break
|
||||||
except:
|
except:
|
||||||
# Texture has no image though its an image type, best ignore.
|
# Texture has no image though its an image type, best ignore.
|
||||||
@@ -332,7 +315,7 @@ def write_file(filepath, objects, scene,
|
|||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
print('OBJ Export path: "%s"' % filepath)
|
print('OBJ Export path: %r' % filepath)
|
||||||
temp_mesh_name = '~tmp-mesh'
|
temp_mesh_name = '~tmp-mesh'
|
||||||
|
|
||||||
time1 = time.clock()
|
time1 = time.clock()
|
||||||
@@ -342,13 +325,13 @@ def write_file(filepath, objects, scene,
|
|||||||
file = open(filepath, "w")
|
file = open(filepath, "w")
|
||||||
|
|
||||||
# Write Header
|
# Write Header
|
||||||
file.write('# Blender v%s OBJ File: %s\n' % (bpy.app.version_string, bpy.data.filepath.split('/')[-1].split('\\')[-1] ))
|
file.write('# Blender v%s OBJ File: %r\n' % (bpy.app.version_string, os.path.basename(bpy.data.filepath)))
|
||||||
file.write('# www.blender.org\n')
|
file.write('# www.blender.org\n')
|
||||||
|
|
||||||
# Tell the obj file what material file to use.
|
# Tell the obj file what material file to use.
|
||||||
if EXPORT_MTL:
|
if EXPORT_MTL:
|
||||||
mtlfilepath = '%s.mtl' % '.'.join(filepath.split('.')[:-1])
|
mtlfilepath = os.path.splitext(filepath)[0] + ".mtl"
|
||||||
file.write('mtllib %s\n' % ( mtlfilepath.split('\\')[-1].split('/')[-1] ))
|
file.write('mtllib %s\n' % repr(os.path.basename(mtlfilepath))[1:-1]) # filepath can contain non utf8 chars, use repr
|
||||||
|
|
||||||
if EXPORT_ROTX90:
|
if EXPORT_ROTX90:
|
||||||
mat_xrot90= mathutils.Matrix.Rotation(-math.pi/2, 4, 'X')
|
mat_xrot90= mathutils.Matrix.Rotation(-math.pi/2, 4, 'X')
|
||||||
@@ -751,7 +734,8 @@ def write_file(filepath, objects, scene,
|
|||||||
|
|
||||||
print("OBJ Export time: %.2f" % (time.clock() - time1))
|
print("OBJ Export time: %.2f" % (time.clock() - time1))
|
||||||
|
|
||||||
def write(filepath, context,
|
#
|
||||||
|
def _write(context, filepath,
|
||||||
EXPORT_TRI, # ok
|
EXPORT_TRI, # ok
|
||||||
EXPORT_EDGES,
|
EXPORT_EDGES,
|
||||||
EXPORT_NORMALS, # not yet
|
EXPORT_NORMALS, # not yet
|
||||||
@@ -777,7 +761,7 @@ def write(filepath, context,
|
|||||||
orig_scene = context.scene
|
orig_scene = context.scene
|
||||||
|
|
||||||
# Exit edit mode before exporting, so current object states are exported properly.
|
# Exit edit mode before exporting, so current object states are exported properly.
|
||||||
if context.object:
|
if bpy.ops.object.mode_set.poll():
|
||||||
bpy.ops.object.mode_set(mode='OBJECT')
|
bpy.ops.object.mode_set(mode='OBJECT')
|
||||||
|
|
||||||
# if EXPORT_ALL_SCENES:
|
# if EXPORT_ALL_SCENES:
|
||||||
@@ -848,105 +832,51 @@ def write(filepath, context,
|
|||||||
|
|
||||||
'''
|
'''
|
||||||
Currently the exporter lacks these features:
|
Currently the exporter lacks these features:
|
||||||
* nurbs
|
|
||||||
* multiple scene export (only active scene is written)
|
* multiple scene export (only active scene is written)
|
||||||
* particles
|
* particles
|
||||||
'''
|
'''
|
||||||
|
|
||||||
from bpy.props import *
|
|
||||||
|
|
||||||
class ExportOBJ(bpy.types.Operator):
|
def save(operator, context, filepath="",
|
||||||
'''Save a Wavefront OBJ File'''
|
use_triangles=False,
|
||||||
|
use_edges=False,
|
||||||
|
use_normals=False,
|
||||||
|
use_hq_normals=False,
|
||||||
|
use_uvs=True,
|
||||||
|
use_materials=True,
|
||||||
|
copy_images=False,
|
||||||
|
use_modifiers=True,
|
||||||
|
use_rotate_x90=True,
|
||||||
|
use_blen_objects=True,
|
||||||
|
group_by_object=False,
|
||||||
|
group_by_material=False,
|
||||||
|
keep_vertex_order=False,
|
||||||
|
use_vertex_groups=False,
|
||||||
|
use_nurbs=True,
|
||||||
|
use_selection=True,
|
||||||
|
use_all_scenes=False,
|
||||||
|
use_animation=False,
|
||||||
|
):
|
||||||
|
|
||||||
bl_idname = "export.obj"
|
_write(context, filepath,
|
||||||
bl_label = 'Export OBJ'
|
EXPORT_TRI=use_triangles,
|
||||||
|
EXPORT_EDGES=use_edges,
|
||||||
|
EXPORT_NORMALS=use_normals,
|
||||||
|
EXPORT_NORMALS_HQ=use_hq_normals,
|
||||||
|
EXPORT_UV=use_uvs,
|
||||||
|
EXPORT_MTL=use_materials,
|
||||||
|
EXPORT_COPY_IMAGES=copy_images,
|
||||||
|
EXPORT_APPLY_MODIFIERS=use_modifiers,
|
||||||
|
EXPORT_ROTX90=use_rotate_x90,
|
||||||
|
EXPORT_BLEN_OBS=use_blen_objects,
|
||||||
|
EXPORT_GROUP_BY_OB=group_by_object,
|
||||||
|
EXPORT_GROUP_BY_MAT=group_by_material,
|
||||||
|
EXPORT_KEEP_VERT_ORDER=keep_vertex_order,
|
||||||
|
EXPORT_POLYGROUPS=use_vertex_groups,
|
||||||
|
EXPORT_CURVE_AS_NURBS=use_nurbs,
|
||||||
|
EXPORT_SEL_ONLY=use_selection,
|
||||||
|
EXPORT_ALL_SCENES=use_all_scenes,
|
||||||
|
EXPORT_ANIMATION=use_animation,
|
||||||
|
)
|
||||||
|
|
||||||
# List of operator properties, the attributes will be assigned
|
return {'FINISHED'}
|
||||||
# to the class instance from the operator settings before calling.
|
|
||||||
|
|
||||||
filepath = StringProperty(name="File Path", description="Filepath used for exporting the OBJ file", maxlen= 1024, default= "")
|
|
||||||
check_existing = BoolProperty(name="Check Existing", description="Check and warn on overwriting existing files", default=True, options={'HIDDEN'})
|
|
||||||
|
|
||||||
# context group
|
|
||||||
use_selection = BoolProperty(name="Selection Only", description="Export selected objects only", default= False)
|
|
||||||
use_all_scenes = BoolProperty(name="All Scenes", description="", default= False)
|
|
||||||
use_animation = BoolProperty(name="Animation", description="", default= False)
|
|
||||||
|
|
||||||
# object group
|
|
||||||
use_modifiers = BoolProperty(name="Apply Modifiers", description="Apply modifiers (preview resolution)", default= True)
|
|
||||||
use_rotate90 = BoolProperty(name="Rotate X90", description="", default= True)
|
|
||||||
|
|
||||||
# extra data group
|
|
||||||
use_edges = BoolProperty(name="Edges", description="", default=True)
|
|
||||||
use_normals = BoolProperty(name="Normals", description="", default=False)
|
|
||||||
use_hq_normals = BoolProperty(name="High Quality Normals", description="", default=True)
|
|
||||||
use_uvs = BoolProperty(name="UVs", description="", default= True)
|
|
||||||
use_materials = BoolProperty(name="Materials", description="", default=True)
|
|
||||||
copy_images = BoolProperty(name="Copy Images", description="", default=False)
|
|
||||||
use_triangles = BoolProperty(name="Triangulate", description="", default=False)
|
|
||||||
use_vertex_groups = BoolProperty(name="Polygroups", description="", default=False)
|
|
||||||
use_nurbs = BoolProperty(name="Nurbs", description="", default=False)
|
|
||||||
|
|
||||||
# grouping group
|
|
||||||
use_blen_objects = BoolProperty(name="Objects as OBJ Objects", description="", default= True)
|
|
||||||
group_by_object = BoolProperty(name="Objects as OBJ Groups ", description="", default= False)
|
|
||||||
group_by_material = BoolProperty(name="Material Groups", description="", default= False)
|
|
||||||
keep_vertex_order = BoolProperty(name="Keep Vertex Order", description="", default= False)
|
|
||||||
|
|
||||||
|
|
||||||
def execute(self, context):
|
|
||||||
|
|
||||||
filepath = self.properties.filepath
|
|
||||||
filepath = bpy.path.ensure_ext(filepath, ".obj")
|
|
||||||
|
|
||||||
write(filepath, context,
|
|
||||||
EXPORT_TRI=self.properties.use_triangles,
|
|
||||||
EXPORT_EDGES=self.properties.use_edges,
|
|
||||||
EXPORT_NORMALS=self.properties.use_normals,
|
|
||||||
EXPORT_NORMALS_HQ=self.properties.use_hq_normals,
|
|
||||||
EXPORT_UV=self.properties.use_uvs,
|
|
||||||
EXPORT_MTL=self.properties.use_materials,
|
|
||||||
EXPORT_COPY_IMAGES=self.properties.copy_images,
|
|
||||||
EXPORT_APPLY_MODIFIERS=self.properties.use_modifiers,
|
|
||||||
EXPORT_ROTX90=self.properties.use_rotate90,
|
|
||||||
EXPORT_BLEN_OBS=self.properties.use_blen_objects,
|
|
||||||
EXPORT_GROUP_BY_OB=self.properties.group_by_object,
|
|
||||||
EXPORT_GROUP_BY_MAT=self.properties.group_by_material,
|
|
||||||
EXPORT_KEEP_VERT_ORDER=self.properties.keep_vertex_order,
|
|
||||||
EXPORT_POLYGROUPS=self.properties.use_vertex_groups,
|
|
||||||
EXPORT_CURVE_AS_NURBS=self.properties.use_nurbs,
|
|
||||||
EXPORT_SEL_ONLY=self.properties.use_selection,
|
|
||||||
EXPORT_ALL_SCENES=self.properties.use_all_scenes,
|
|
||||||
EXPORT_ANIMATION=self.properties.use_animation)
|
|
||||||
|
|
||||||
return {'FINISHED'}
|
|
||||||
|
|
||||||
def invoke(self, context, event):
|
|
||||||
import os
|
|
||||||
if not self.properties.is_property_set("filepath"):
|
|
||||||
self.properties.filepath = os.path.splitext(bpy.data.filepath)[0] + ".obj"
|
|
||||||
|
|
||||||
context.manager.add_fileselect(self)
|
|
||||||
return {'RUNNING_MODAL'}
|
|
||||||
|
|
||||||
|
|
||||||
def menu_func(self, context):
|
|
||||||
self.layout.operator(ExportOBJ.bl_idname, text="Wavefront (.obj)")
|
|
||||||
|
|
||||||
|
|
||||||
def register():
|
|
||||||
bpy.types.INFO_MT_file_export.append(menu_func)
|
|
||||||
|
|
||||||
def unregister():
|
|
||||||
bpy.types.INFO_MT_file_export.remove(menu_func)
|
|
||||||
|
|
||||||
|
|
||||||
# CONVERSION ISSUES
|
|
||||||
# - matrix problem
|
|
||||||
# - duplis - only tested dupliverts
|
|
||||||
# - NURBS - needs API additions
|
|
||||||
# - all scenes export
|
|
||||||
# + normals calculation
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
register()
|
|
||||||
@@ -18,16 +18,17 @@
|
|||||||
|
|
||||||
# <pep8 compliant>
|
# <pep8 compliant>
|
||||||
|
|
||||||
__author__= "Campbell Barton", "Jiri Hnidek", "Paolo Ciccone"
|
# Script copyright (C) Campbell Barton
|
||||||
__url__= ['http://wiki.blender.org/index.php/Scripts/Manual/Import/wavefront_obj', 'blender.org', 'blenderartists.org']
|
# Contributors: Campbell Barton, Jiri Hnidek, Paolo Ciccone
|
||||||
__version__= "2.11"
|
|
||||||
|
|
||||||
__bpydoc__= """\
|
"""
|
||||||
This script imports a Wavefront OBJ files to Blender.
|
This script imports a Wavefront OBJ files to Blender.
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
Run this script from "File->Import" menu and then load the desired OBJ file.
|
Run this script from "File->Import" menu and then load the desired OBJ file.
|
||||||
Note, This loads mesh objects and materials only, nurbs and curves are not supported.
|
Note, This loads mesh objects and materials only, nurbs and curves are not supported.
|
||||||
|
|
||||||
|
http://wiki.blender.org/index.php/Scripts/Manual/Import/wavefront_obj
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
@@ -35,30 +36,8 @@ import time
|
|||||||
import bpy
|
import bpy
|
||||||
import mathutils
|
import mathutils
|
||||||
from geometry import PolyFill
|
from geometry import PolyFill
|
||||||
|
from io_utils import load_image, unpack_list, unpack_face_list
|
||||||
|
|
||||||
def unpack_list(list_of_tuples):
|
|
||||||
l = []
|
|
||||||
for t in list_of_tuples:
|
|
||||||
l.extend(t)
|
|
||||||
return l
|
|
||||||
|
|
||||||
# same as above except that it adds 0 for triangle faces
|
|
||||||
def unpack_face_list(list_of_tuples):
|
|
||||||
# allocate the entire list
|
|
||||||
flat_ls = [0] * (len(list_of_tuples) * 4)
|
|
||||||
i = 0
|
|
||||||
|
|
||||||
for t in list_of_tuples:
|
|
||||||
if len(t) == 3:
|
|
||||||
if t[2] == 0:
|
|
||||||
t = t[1], t[2], t[0]
|
|
||||||
else: # assuem quad
|
|
||||||
if t[3] == 0 or t[2] == 0:
|
|
||||||
t = t[2], t[3], t[0], t[1]
|
|
||||||
|
|
||||||
flat_ls[i:i + len(t)] = t
|
|
||||||
i += 4
|
|
||||||
return flat_ls
|
|
||||||
|
|
||||||
def BPyMesh_ngon(from_data, indices, PREF_FIX_LOOPS= True):
|
def BPyMesh_ngon(from_data, indices, PREF_FIX_LOOPS= True):
|
||||||
'''
|
'''
|
||||||
@@ -78,7 +57,7 @@ def BPyMesh_ngon(from_data, indices, PREF_FIX_LOOPS= True):
|
|||||||
if not indices:
|
if not indices:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
# return []
|
# return []
|
||||||
def rvec(co): return round(co.x, 6), round(co.y, 6), round(co.z, 6)
|
def rvec(co): return round(co.x, 6), round(co.y, 6), round(co.z, 6)
|
||||||
def mlen(co): return abs(co[0])+abs(co[1])+abs(co[2]) # manhatten length of a vector, faster then length
|
def mlen(co): return abs(co[0])+abs(co[1])+abs(co[2]) # manhatten length of a vector, faster then length
|
||||||
|
|
||||||
@@ -259,21 +238,6 @@ def line_value(line_split):
|
|||||||
elif length > 2:
|
elif length > 2:
|
||||||
return ' '.join( line_split[1:] )
|
return ' '.join( line_split[1:] )
|
||||||
|
|
||||||
# limited replacement for BPyImage.comprehensiveImageLoad
|
|
||||||
def load_image(imagepath, dirname):
|
|
||||||
|
|
||||||
if os.path.exists(imagepath):
|
|
||||||
return bpy.data.images.load(imagepath)
|
|
||||||
|
|
||||||
variants = [imagepath, os.path.join(dirname, imagepath), os.path.join(dirname, os.path.basename(imagepath))]
|
|
||||||
|
|
||||||
for filepath in variants:
|
|
||||||
for nfilepath in (filepath, bpy.path.resolve_ncase(filepath)):
|
|
||||||
if os.path.exists(nfilepath):
|
|
||||||
return bpy.data.images.load(nfilepath)
|
|
||||||
|
|
||||||
# TODO comprehensiveImageLoad also searched in bpy.config.textureDir
|
|
||||||
return None
|
|
||||||
|
|
||||||
def obj_image_load(imagepath, DIR, IMAGE_SEARCH):
|
def obj_image_load(imagepath, DIR, IMAGE_SEARCH):
|
||||||
if '_' in imagepath:
|
if '_' in imagepath:
|
||||||
@@ -289,21 +253,21 @@ def obj_image_load(imagepath, DIR, IMAGE_SEARCH):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
# def obj_image_load(imagepath, DIR, IMAGE_SEARCH):
|
# def obj_image_load(imagepath, DIR, IMAGE_SEARCH):
|
||||||
# '''
|
# '''
|
||||||
# Mainly uses comprehensiveImageLoad
|
# Mainly uses comprehensiveImageLoad
|
||||||
# but tries to replace '_' with ' ' for Max's exporter replaces spaces with underscores.
|
# but tries to replace '_' with ' ' for Max's exporter replaces spaces with underscores.
|
||||||
# '''
|
# '''
|
||||||
|
|
||||||
# if '_' in imagepath:
|
# if '_' in imagepath:
|
||||||
# image= BPyImage.comprehensiveImageLoad(imagepath, DIR, PLACE_HOLDER= False, RECURSIVE= IMAGE_SEARCH)
|
# image= BPyImage.comprehensiveImageLoad(imagepath, DIR, PLACE_HOLDER= False, RECURSIVE= IMAGE_SEARCH)
|
||||||
# if image: return image
|
# if image: return image
|
||||||
# # Did the exporter rename the image?
|
# # Did the exporter rename the image?
|
||||||
# image= BPyImage.comprehensiveImageLoad(imagepath.replace('_', ' '), DIR, PLACE_HOLDER= False, RECURSIVE= IMAGE_SEARCH)
|
# image= BPyImage.comprehensiveImageLoad(imagepath.replace('_', ' '), DIR, PLACE_HOLDER= False, RECURSIVE= IMAGE_SEARCH)
|
||||||
# if image: return image
|
# if image: return image
|
||||||
|
|
||||||
# # Return an image, placeholder if it dosnt exist
|
# # Return an image, placeholder if it dosnt exist
|
||||||
# image= BPyImage.comprehensiveImageLoad(imagepath, DIR, PLACE_HOLDER= True, RECURSIVE= IMAGE_SEARCH)
|
# image= BPyImage.comprehensiveImageLoad(imagepath, DIR, PLACE_HOLDER= True, RECURSIVE= IMAGE_SEARCH)
|
||||||
# return image
|
# return image
|
||||||
|
|
||||||
|
|
||||||
def create_materials(filepath, material_libs, unique_materials, unique_material_images, IMAGE_SEARCH):
|
def create_materials(filepath, material_libs, unique_materials, unique_material_images, IMAGE_SEARCH):
|
||||||
@@ -334,42 +298,65 @@ def create_materials(filepath, material_libs, unique_materials, unique_material_
|
|||||||
# Image has alpha
|
# Image has alpha
|
||||||
|
|
||||||
# XXX bitmask won't work?
|
# XXX bitmask won't work?
|
||||||
blender_material.add_texture(texture, 'UV', {'COLOR', 'ALPHA'})
|
mtex = blender_material.texture_slots.add()
|
||||||
|
mtex.texture = texture
|
||||||
|
mtex.texture_coords = 'UV'
|
||||||
|
mtex.use_map_color_diffuse = True
|
||||||
|
mtex.use_map_alpha = True
|
||||||
|
|
||||||
texture.mipmap = True
|
texture.mipmap = True
|
||||||
texture.interpolation = True
|
texture.interpolation = True
|
||||||
texture.use_alpha = True
|
texture.use_alpha = True
|
||||||
blender_material.use_transparency = True
|
blender_material.use_transparency = True
|
||||||
blender_material.alpha = 0.0
|
blender_material.alpha = 0.0
|
||||||
else:
|
else:
|
||||||
blender_material.add_texture(texture, 'UV', 'COLOR')
|
mtex = blender_material.texture_slots.add()
|
||||||
|
mtex.texture = texture
|
||||||
|
mtex.texture_coords = 'UV'
|
||||||
|
mtex.use_map_color_diffuse = True
|
||||||
|
|
||||||
# adds textures to faces (Textured/Alt-Z mode)
|
# adds textures to faces (Textured/Alt-Z mode)
|
||||||
# Only apply the diffuse texture to the face if the image has not been set with the inline usemat func.
|
# Only apply the diffuse texture to the face if the image has not been set with the inline usemat func.
|
||||||
unique_material_images[context_material_name]= image, has_data # set the texface image
|
unique_material_images[context_material_name]= image, has_data # set the texface image
|
||||||
|
|
||||||
elif type == 'Ka':
|
elif type == 'Ka':
|
||||||
blender_material.add_texture(texture, 'UV', 'AMBIENT')
|
mtex = blender_material.texture_slots.add()
|
||||||
# blender_material.setTexture(1, texture, Texture.TexCo.UV, Texture.MapTo.CMIR) # TODO- Add AMB to BPY API
|
mtex.texture = texture
|
||||||
|
mtex.texture_coords = 'UV'
|
||||||
|
mtex.use_map_ambient = True
|
||||||
|
# blender_material.setTexture(1, texture, Texture.TexCo.UV, Texture.MapTo.CMIR) # TODO- Add AMB to BPY API
|
||||||
|
|
||||||
elif type == 'Ks':
|
elif type == 'Ks':
|
||||||
blender_material.add_texture(texture, 'UV', 'SPECULARITY')
|
mtex = blender_material.texture_slots.add()
|
||||||
# blender_material.setTexture(2, texture, Texture.TexCo.UV, Texture.MapTo.SPEC)
|
mtex.texture = texture
|
||||||
|
mtex.texture_coords = 'UV'
|
||||||
|
mtex.use_map_specular = True
|
||||||
|
# blender_material.setTexture(2, texture, Texture.TexCo.UV, Texture.MapTo.SPEC)
|
||||||
|
|
||||||
elif type == 'Bump':
|
elif type == 'Bump':
|
||||||
blender_material.add_texture(texture, 'UV', 'NORMAL')
|
mtex = blender_material.texture_slots.add()
|
||||||
# blender_material.setTexture(3, texture, Texture.TexCo.UV, Texture.MapTo.NOR)
|
mtex.texture = texture
|
||||||
|
mtex.texture_coords = 'UV'
|
||||||
|
mtex.use_map_normal = True
|
||||||
|
# blender_material.setTexture(3, texture, Texture.TexCo.UV, Texture.MapTo.NOR)
|
||||||
elif type == 'D':
|
elif type == 'D':
|
||||||
blender_material.add_texture(texture, 'UV', 'ALPHA')
|
mtex = blender_material.texture_slots.add()
|
||||||
|
mtex.texture = texture
|
||||||
|
mtex.texture_coords = 'UV'
|
||||||
|
mtex.use_map_alpha = True
|
||||||
blender_material.z_transparency = True
|
blender_material.z_transparency = True
|
||||||
blender_material.alpha = 0.0
|
blender_material.alpha = 0.0
|
||||||
# blender_material.setTexture(4, texture, Texture.TexCo.UV, Texture.MapTo.ALPHA)
|
# blender_material.setTexture(4, texture, Texture.TexCo.UV, Texture.MapTo.ALPHA)
|
||||||
# blender_material.mode |= Material.Modes.ZTRANSP
|
# blender_material.mode |= Material.Modes.ZTRANSP
|
||||||
# blender_material.alpha = 0.0
|
# blender_material.alpha = 0.0
|
||||||
# Todo, unset deffuse material alpha if it has an alpha channel
|
# Todo, unset deffuse material alpha if it has an alpha channel
|
||||||
|
|
||||||
elif type == 'refl':
|
elif type == 'refl':
|
||||||
blender_material.add_texture(texture, 'UV', 'REFLECTION')
|
mtex = blender_material.texture_slots.add()
|
||||||
# blender_material.setTexture(5, texture, Texture.TexCo.UV, Texture.MapTo.REF)
|
mtex.texture = texture
|
||||||
|
mtex.texture_coords = 'UV'
|
||||||
|
mtex.use_map_reflect = True
|
||||||
|
# blender_material.setTexture(5, texture, Texture.TexCo.UV, Texture.MapTo.REF)
|
||||||
|
|
||||||
|
|
||||||
# Add an MTL with the same name as the obj if no MTLs are spesified.
|
# Add an MTL with the same name as the obj if no MTLs are spesified.
|
||||||
@@ -629,7 +616,7 @@ def create_mesh(new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_loc, v
|
|||||||
|
|
||||||
# make sure the list isnt too big
|
# make sure the list isnt too big
|
||||||
for material in materials:
|
for material in materials:
|
||||||
me.materials.link(material)
|
me.materials.append(material)
|
||||||
|
|
||||||
me.vertices.add(len(verts_loc))
|
me.vertices.add(len(verts_loc))
|
||||||
me.faces.add(len(faces))
|
me.faces.add(len(faces))
|
||||||
@@ -676,7 +663,7 @@ def create_mesh(new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_loc, v
|
|||||||
context_material_old= context_material
|
context_material_old= context_material
|
||||||
|
|
||||||
blender_face.material_index= mat
|
blender_face.material_index= mat
|
||||||
# blender_face.mat= mat
|
# blender_face.mat= mat
|
||||||
|
|
||||||
|
|
||||||
if verts_tex:
|
if verts_tex:
|
||||||
@@ -708,10 +695,10 @@ def create_mesh(new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_loc, v
|
|||||||
if len(face_vert_loc_indicies)==4:
|
if len(face_vert_loc_indicies)==4:
|
||||||
blender_tface.uv4= verts_tex[face_vert_tex_indicies[3]]
|
blender_tface.uv4= verts_tex[face_vert_tex_indicies[3]]
|
||||||
|
|
||||||
# for ii, uv in enumerate(blender_face.uv):
|
# for ii, uv in enumerate(blender_face.uv):
|
||||||
# uv.x, uv.y= verts_tex[face_vert_tex_indicies[ii]]
|
# uv.x, uv.y= verts_tex[face_vert_tex_indicies[ii]]
|
||||||
del me_faces
|
del me_faces
|
||||||
# del ALPHA
|
# del ALPHA
|
||||||
|
|
||||||
if CREATE_EDGES:
|
if CREATE_EDGES:
|
||||||
|
|
||||||
@@ -719,46 +706,46 @@ def create_mesh(new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_loc, v
|
|||||||
|
|
||||||
# edges should be a list of (a, b) tuples
|
# edges should be a list of (a, b) tuples
|
||||||
me.edges.foreach_set("vertices", unpack_list(edges))
|
me.edges.foreach_set("vertices", unpack_list(edges))
|
||||||
# me_edges.extend( edges )
|
# me_edges.extend( edges )
|
||||||
|
|
||||||
# del me_edges
|
# del me_edges
|
||||||
|
|
||||||
# Add edge faces.
|
# Add edge faces.
|
||||||
# me_edges= me.edges
|
# me_edges= me.edges
|
||||||
|
|
||||||
def edges_match(e1, e2):
|
def edges_match(e1, e2):
|
||||||
return (e1[0] == e2[0] and e1[1] == e2[1]) or (e1[0] == e2[1] and e1[1] == e2[0])
|
return (e1[0] == e2[0] and e1[1] == e2[1]) or (e1[0] == e2[1] and e1[1] == e2[0])
|
||||||
|
|
||||||
# XXX slow
|
# XXX slow
|
||||||
# if CREATE_FGONS and fgon_edges:
|
# if CREATE_FGONS and fgon_edges:
|
||||||
# for fgon_edge in fgon_edges.keys():
|
# for fgon_edge in fgon_edges.keys():
|
||||||
# for ed in me.edges:
|
# for ed in me.edges:
|
||||||
# if edges_match(fgon_edge, ed.vertices):
|
# if edges_match(fgon_edge, ed.vertices):
|
||||||
# ed.is_fgon = True
|
# ed.is_fgon = True
|
||||||
|
|
||||||
# if CREATE_FGONS and fgon_edges:
|
# if CREATE_FGONS and fgon_edges:
|
||||||
# FGON= Mesh.EdgeFlags.FGON
|
# FGON= Mesh.EdgeFlags.FGON
|
||||||
# for ed in me.findEdges( fgon_edges.keys() ):
|
# for ed in me.findEdges( fgon_edges.keys() ):
|
||||||
# if ed!=None:
|
# if ed!=None:
|
||||||
# me_edges[ed].flag |= FGON
|
# me_edges[ed].flag |= FGON
|
||||||
# del FGON
|
# del FGON
|
||||||
|
|
||||||
# XXX slow
|
# XXX slow
|
||||||
# if unique_smooth_groups and sharp_edges:
|
# if unique_smooth_groups and sharp_edges:
|
||||||
# for sharp_edge in sharp_edges.keys():
|
# for sharp_edge in sharp_edges.keys():
|
||||||
# for ed in me.edges:
|
# for ed in me.edges:
|
||||||
# if edges_match(sharp_edge, ed.vertices):
|
# if edges_match(sharp_edge, ed.vertices):
|
||||||
# ed.use_edge_sharp = True
|
# ed.use_edge_sharp = True
|
||||||
|
|
||||||
# if unique_smooth_groups and sharp_edges:
|
# if unique_smooth_groups and sharp_edges:
|
||||||
# SHARP= Mesh.EdgeFlags.SHARP
|
# SHARP= Mesh.EdgeFlags.SHARP
|
||||||
# for ed in me.findEdges( sharp_edges.keys() ):
|
# for ed in me.findEdges( sharp_edges.keys() ):
|
||||||
# if ed!=None:
|
# if ed!=None:
|
||||||
# me_edges[ed].flag |= SHARP
|
# me_edges[ed].flag |= SHARP
|
||||||
# del SHARP
|
# del SHARP
|
||||||
|
|
||||||
me.update()
|
me.update()
|
||||||
# me.calcNormals()
|
# me.calcNormals()
|
||||||
|
|
||||||
ob= bpy.data.objects.new("Mesh", me)
|
ob= bpy.data.objects.new("Mesh", me)
|
||||||
new_objects.append(ob)
|
new_objects.append(ob)
|
||||||
@@ -768,8 +755,7 @@ def create_mesh(new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_loc, v
|
|||||||
# the following test will never run
|
# the following test will never run
|
||||||
for group_name, group_indicies in vertex_groups.items():
|
for group_name, group_indicies in vertex_groups.items():
|
||||||
group= ob.vertex_groups.new(group_name)
|
group= ob.vertex_groups.new(group_name)
|
||||||
for vertex_index in group_indicies:
|
ob.vertex_groups.assign(group_indicies, group, 1.0, 'REPLACE')
|
||||||
ob.vertex_groups.assign(vertex_index, group, 1.0, 'REPLACE')
|
|
||||||
|
|
||||||
|
|
||||||
def create_nurbs(context_nurbs, vert_loc, new_objects):
|
def create_nurbs(context_nurbs, vert_loc, new_objects):
|
||||||
@@ -860,7 +846,7 @@ def strip_slash(line_split):
|
|||||||
def get_float_func(filepath):
|
def get_float_func(filepath):
|
||||||
'''
|
'''
|
||||||
find the float function for this obj file
|
find the float function for this obj file
|
||||||
- weather to replace commas or not
|
- whether to replace commas or not
|
||||||
'''
|
'''
|
||||||
file= open(filepath, 'rU')
|
file= open(filepath, 'rU')
|
||||||
for line in file: #.xreadlines():
|
for line in file: #.xreadlines():
|
||||||
@@ -874,31 +860,29 @@ def get_float_func(filepath):
|
|||||||
# incase all vert values were ints
|
# incase all vert values were ints
|
||||||
return float
|
return float
|
||||||
|
|
||||||
def load_obj(filepath,
|
def load(operator, context, filepath,
|
||||||
context,
|
CLAMP_SIZE= 0.0,
|
||||||
CLAMP_SIZE= 0.0,
|
CREATE_FGONS= True,
|
||||||
CREATE_FGONS= True,
|
CREATE_SMOOTH_GROUPS= True,
|
||||||
CREATE_SMOOTH_GROUPS= True,
|
CREATE_EDGES= True,
|
||||||
CREATE_EDGES= True,
|
SPLIT_OBJECTS= True,
|
||||||
SPLIT_OBJECTS= True,
|
SPLIT_GROUPS= True,
|
||||||
SPLIT_GROUPS= True,
|
ROTATE_X90= True,
|
||||||
SPLIT_MATERIALS= True,
|
IMAGE_SEARCH=True,
|
||||||
ROTATE_X90= True,
|
POLYGROUPS=False):
|
||||||
IMAGE_SEARCH=True,
|
|
||||||
POLYGROUPS=False):
|
|
||||||
'''
|
'''
|
||||||
Called by the user interface or another script.
|
Called by the user interface or another script.
|
||||||
load_obj(path) - should give acceptable results.
|
load_obj(path) - should give acceptable results.
|
||||||
This function passes the file and sends the data off
|
This function passes the file and sends the data off
|
||||||
to be split into objects and then converted into mesh objects
|
to be split into objects and then converted into mesh objects
|
||||||
'''
|
'''
|
||||||
print('\nimporting obj "%s"' % filepath)
|
print('\nimporting obj %r' % filepath)
|
||||||
|
|
||||||
if SPLIT_OBJECTS or SPLIT_GROUPS or SPLIT_MATERIALS:
|
if SPLIT_OBJECTS or SPLIT_GROUPS:
|
||||||
POLYGROUPS = False
|
POLYGROUPS = False
|
||||||
|
|
||||||
time_main= time.time()
|
time_main= time.time()
|
||||||
# time_main= sys.time()
|
# time_main= sys.time()
|
||||||
|
|
||||||
verts_loc= []
|
verts_loc= []
|
||||||
verts_tex= []
|
verts_tex= []
|
||||||
@@ -932,12 +916,12 @@ def load_obj(filepath,
|
|||||||
# when there are faces that end with \
|
# when there are faces that end with \
|
||||||
# it means they are multiline-
|
# it means they are multiline-
|
||||||
# since we use xreadline we cant skip to the next line
|
# since we use xreadline we cant skip to the next line
|
||||||
# so we need to know weather
|
# so we need to know whether
|
||||||
context_multi_line= ''
|
context_multi_line= ''
|
||||||
|
|
||||||
print('\tparsing obj file "%s"...' % filepath)
|
print("\tparsing obj file...")
|
||||||
time_sub= time.time()
|
time_sub= time.time()
|
||||||
# time_sub= sys.time()
|
# time_sub= sys.time()
|
||||||
|
|
||||||
file= open(filepath, 'rU')
|
file= open(filepath, 'rU')
|
||||||
for line in file: #.xreadlines():
|
for line in file: #.xreadlines():
|
||||||
@@ -988,7 +972,7 @@ def load_obj(filepath,
|
|||||||
vert_loc_index= int(obj_vert[0])-1
|
vert_loc_index= int(obj_vert[0])-1
|
||||||
# Add the vertex to the current group
|
# Add the vertex to the current group
|
||||||
# *warning*, this wont work for files that have groups defined around verts
|
# *warning*, this wont work for files that have groups defined around verts
|
||||||
if POLYGROUPS and context_vgroup:
|
if POLYGROUPS and context_vgroup:
|
||||||
vertex_groups[context_vgroup].append(vert_loc_index)
|
vertex_groups[context_vgroup].append(vert_loc_index)
|
||||||
|
|
||||||
# Make relative negative vert indicies absolute
|
# Make relative negative vert indicies absolute
|
||||||
@@ -1080,8 +1064,7 @@ def load_obj(filepath,
|
|||||||
context_material= line_value(line.split())
|
context_material= line_value(line.split())
|
||||||
unique_materials[context_material]= None
|
unique_materials[context_material]= None
|
||||||
elif line.startswith('mtllib'): # usemap or usemat
|
elif line.startswith('mtllib'): # usemap or usemat
|
||||||
material_libs.extend( line.split()[1:] ) # can have multiple mtllib filenames per line
|
material_libs = list(set(material_libs) | set(line.split()[1:])) # can have multiple mtllib filenames per line, mtllib can appear more than once, so make sure only occurance of material exists
|
||||||
|
|
||||||
|
|
||||||
# Nurbs support
|
# Nurbs support
|
||||||
elif line.startswith('cstype '):
|
elif line.startswith('cstype '):
|
||||||
@@ -1146,7 +1129,7 @@ def load_obj(filepath,
|
|||||||
|
|
||||||
file.close()
|
file.close()
|
||||||
time_new= time.time()
|
time_new= time.time()
|
||||||
# time_new= sys.time()
|
# time_new= sys.time()
|
||||||
print('%.4f sec' % (time_new-time_sub))
|
print('%.4f sec' % (time_new-time_sub))
|
||||||
time_sub= time_new
|
time_sub= time_new
|
||||||
|
|
||||||
@@ -1155,7 +1138,7 @@ def load_obj(filepath,
|
|||||||
create_materials(filepath, material_libs, unique_materials, unique_material_images, IMAGE_SEARCH)
|
create_materials(filepath, material_libs, unique_materials, unique_material_images, IMAGE_SEARCH)
|
||||||
|
|
||||||
time_new= time.time()
|
time_new= time.time()
|
||||||
# time_new= sys.time()
|
# time_new= sys.time()
|
||||||
print('%.4f sec' % (time_new-time_sub))
|
print('%.4f sec' % (time_new-time_sub))
|
||||||
time_sub= time_new
|
time_sub= time_new
|
||||||
|
|
||||||
@@ -1166,13 +1149,13 @@ def load_obj(filepath,
|
|||||||
bpy.ops.object.select_all(action='DESELECT')
|
bpy.ops.object.select_all(action='DESELECT')
|
||||||
|
|
||||||
scene = context.scene
|
scene = context.scene
|
||||||
# scn.objects.selected = []
|
# scn.objects.selected = []
|
||||||
new_objects= [] # put new objects here
|
new_objects= [] # put new objects here
|
||||||
|
|
||||||
print('\tbuilding geometry...\n\tverts:%i faces:%i materials: %i smoothgroups:%i ...' % ( len(verts_loc), len(faces), len(unique_materials), len(unique_smooth_groups) ))
|
print('\tbuilding geometry...\n\tverts:%i faces:%i materials: %i smoothgroups:%i ...' % ( len(verts_loc), len(faces), len(unique_materials), len(unique_smooth_groups) ))
|
||||||
# Split the mesh by objects/materials, may
|
# Split the mesh by objects/materials, may
|
||||||
if SPLIT_OBJECTS or SPLIT_GROUPS: SPLIT_OB_OR_GROUP = True
|
if SPLIT_OBJECTS or SPLIT_GROUPS: SPLIT_OB_OR_GROUP = True
|
||||||
else: SPLIT_OB_OR_GROUP = False
|
else: SPLIT_OB_OR_GROUP = False
|
||||||
|
|
||||||
for verts_loc_split, faces_split, unique_materials_split, dataname in split_mesh(verts_loc, faces, unique_materials, filepath, SPLIT_OB_OR_GROUP):
|
for verts_loc_split, faces_split, unique_materials_split, dataname in split_mesh(verts_loc, faces, unique_materials, filepath, SPLIT_OB_OR_GROUP):
|
||||||
# Create meshes from the data, warning 'vertex_groups' wont support splitting
|
# Create meshes from the data, warning 'vertex_groups' wont support splitting
|
||||||
@@ -1193,327 +1176,34 @@ def load_obj(filepath,
|
|||||||
axis_min= [ 1000000000]*3
|
axis_min= [ 1000000000]*3
|
||||||
axis_max= [-1000000000]*3
|
axis_max= [-1000000000]*3
|
||||||
|
|
||||||
# if CLAMP_SIZE:
|
# if CLAMP_SIZE:
|
||||||
# # Get all object bounds
|
# # Get all object bounds
|
||||||
# for ob in new_objects:
|
# for ob in new_objects:
|
||||||
# for v in ob.getBoundBox():
|
# for v in ob.getBoundBox():
|
||||||
# for axis, value in enumerate(v):
|
# for axis, value in enumerate(v):
|
||||||
# if axis_min[axis] > value: axis_min[axis]= value
|
# if axis_min[axis] > value: axis_min[axis]= value
|
||||||
# if axis_max[axis] < value: axis_max[axis]= value
|
# if axis_max[axis] < value: axis_max[axis]= value
|
||||||
|
|
||||||
# # Scale objects
|
# # Scale objects
|
||||||
# max_axis= max(axis_max[0]-axis_min[0], axis_max[1]-axis_min[1], axis_max[2]-axis_min[2])
|
# max_axis= max(axis_max[0]-axis_min[0], axis_max[1]-axis_min[1], axis_max[2]-axis_min[2])
|
||||||
# scale= 1.0
|
# scale= 1.0
|
||||||
|
|
||||||
# while CLAMP_SIZE < max_axis * scale:
|
# while CLAMP_SIZE < max_axis * scale:
|
||||||
# scale= scale/10.0
|
# scale= scale/10.0
|
||||||
|
|
||||||
# for ob in new_objects:
|
# for ob in new_objects:
|
||||||
# ob.setSize(scale, scale, scale)
|
# ob.setSize(scale, scale, scale)
|
||||||
|
|
||||||
# Better rotate the vert locations
|
# Better rotate the vert locations
|
||||||
#if not ROTATE_X90:
|
#if not ROTATE_X90:
|
||||||
# for ob in new_objects:
|
# for ob in new_objects:
|
||||||
# ob.RotX = -1.570796326794896558
|
# ob.RotX = -1.570796326794896558
|
||||||
|
|
||||||
time_new= time.time()
|
time_new= time.time()
|
||||||
# time_new= sys.time()
|
# time_new= sys.time()
|
||||||
|
|
||||||
print('%.4f sec' % (time_new-time_sub))
|
print('finished importing: %r in %.4f sec.' % (filepath, (time_new-time_main)))
|
||||||
print('finished importing: "%s" in %.4f sec.' % (filepath, (time_new-time_main)))
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
DEBUG= True
|
|
||||||
|
|
||||||
|
|
||||||
def load_obj_ui(filepath, BATCH_LOAD= False):
|
|
||||||
if BPyMessages.Error_NoFile(filepath):
|
|
||||||
return
|
|
||||||
|
|
||||||
global CREATE_SMOOTH_GROUPS, CREATE_FGONS, CREATE_EDGES, SPLIT_OBJECTS, SPLIT_GROUPS, CLAMP_SIZE, IMAGE_SEARCH, POLYGROUPS, KEEP_VERT_ORDER, ROTATE_X90
|
|
||||||
|
|
||||||
CREATE_SMOOTH_GROUPS= Draw.Create(0)
|
|
||||||
CREATE_FGONS= Draw.Create(1)
|
|
||||||
CREATE_EDGES= Draw.Create(1)
|
|
||||||
SPLIT_OBJECTS= Draw.Create(0)
|
|
||||||
SPLIT_GROUPS= Draw.Create(0)
|
|
||||||
CLAMP_SIZE= Draw.Create(10.0)
|
|
||||||
IMAGE_SEARCH= Draw.Create(1)
|
|
||||||
POLYGROUPS= Draw.Create(0)
|
|
||||||
KEEP_VERT_ORDER= Draw.Create(1)
|
|
||||||
ROTATE_X90= Draw.Create(1)
|
|
||||||
|
|
||||||
|
|
||||||
# Get USER Options
|
|
||||||
# Note, Works but not pretty, instead use a more complicated GUI
|
|
||||||
'''
|
|
||||||
pup_block= [\
|
|
||||||
'Import...',\
|
|
||||||
('Smooth Groups', CREATE_SMOOTH_GROUPS, 'Surround smooth groups by sharp edges'),\
|
|
||||||
('Create FGons', CREATE_FGONS, 'Import faces with more then 4 verts as fgons.'),\
|
|
||||||
('Lines', CREATE_EDGES, 'Import lines and faces with 2 verts as edges'),\
|
|
||||||
'Separate objects from obj...',\
|
|
||||||
('Object', SPLIT_OBJECTS, 'Import OBJ Objects into Blender Objects'),\
|
|
||||||
('Group', SPLIT_GROUPS, 'Import OBJ Groups into Blender Objects'),\
|
|
||||||
'Options...',\
|
|
||||||
('Keep Vert Order', KEEP_VERT_ORDER, 'Keep vert and face order, disables some other options.'),\
|
|
||||||
('Clamp Scale:', CLAMP_SIZE, 0.0, 1000.0, 'Clamp the size to this maximum (Zero to Disable)'),\
|
|
||||||
('Image Search', IMAGE_SEARCH, 'Search subdirs for any assosiated images (Warning, may be slow)'),\
|
|
||||||
]
|
|
||||||
|
|
||||||
if not Draw.PupBlock('Import OBJ...', pup_block):
|
|
||||||
return
|
|
||||||
|
|
||||||
if KEEP_VERT_ORDER.val:
|
|
||||||
SPLIT_OBJECTS.val = False
|
|
||||||
SPLIT_GROUPS.val = False
|
|
||||||
'''
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# BEGIN ALTERNATIVE UI *******************
|
|
||||||
if True:
|
|
||||||
|
|
||||||
EVENT_NONE = 0
|
|
||||||
EVENT_EXIT = 1
|
|
||||||
EVENT_REDRAW = 2
|
|
||||||
EVENT_IMPORT = 3
|
|
||||||
|
|
||||||
GLOBALS = {}
|
|
||||||
GLOBALS['EVENT'] = EVENT_REDRAW
|
|
||||||
#GLOBALS['MOUSE'] = Window.GetMouseCoords()
|
|
||||||
GLOBALS['MOUSE'] = [i/2 for i in Window.GetScreenSize()]
|
|
||||||
|
|
||||||
def obj_ui_set_event(e,v):
|
|
||||||
GLOBALS['EVENT'] = e
|
|
||||||
|
|
||||||
def do_split(e,v):
|
|
||||||
global SPLIT_OBJECTS, SPLIT_GROUPS, KEEP_VERT_ORDER, POLYGROUPS
|
|
||||||
if SPLIT_OBJECTS.val or SPLIT_GROUPS.val:
|
|
||||||
KEEP_VERT_ORDER.val = 0
|
|
||||||
POLYGROUPS.val = 0
|
|
||||||
else:
|
|
||||||
KEEP_VERT_ORDER.val = 1
|
|
||||||
|
|
||||||
def do_vertorder(e,v):
|
|
||||||
global SPLIT_OBJECTS, SPLIT_GROUPS, KEEP_VERT_ORDER
|
|
||||||
if KEEP_VERT_ORDER.val:
|
|
||||||
SPLIT_OBJECTS.val = SPLIT_GROUPS.val = 0
|
|
||||||
else:
|
|
||||||
if not (SPLIT_OBJECTS.val or SPLIT_GROUPS.val):
|
|
||||||
KEEP_VERT_ORDER.val = 1
|
|
||||||
|
|
||||||
def do_polygroups(e,v):
|
|
||||||
global SPLIT_OBJECTS, SPLIT_GROUPS, KEEP_VERT_ORDER, POLYGROUPS
|
|
||||||
if POLYGROUPS.val:
|
|
||||||
SPLIT_OBJECTS.val = SPLIT_GROUPS.val = 0
|
|
||||||
|
|
||||||
def do_help(e,v):
|
|
||||||
url = __url__[0]
|
|
||||||
print('Trying to open web browser with documentation at this address...')
|
|
||||||
print('\t' + url)
|
|
||||||
|
|
||||||
try:
|
|
||||||
import webbrowser
|
|
||||||
webbrowser.open(url)
|
|
||||||
except:
|
|
||||||
print('...could not open a browser window.')
|
|
||||||
|
|
||||||
def obj_ui():
|
|
||||||
ui_x, ui_y = GLOBALS['MOUSE']
|
|
||||||
|
|
||||||
# Center based on overall pup size
|
|
||||||
ui_x -= 165
|
|
||||||
ui_y -= 90
|
|
||||||
|
|
||||||
global CREATE_SMOOTH_GROUPS, CREATE_FGONS, CREATE_EDGES, SPLIT_OBJECTS, SPLIT_GROUPS, CLAMP_SIZE, IMAGE_SEARCH, POLYGROUPS, KEEP_VERT_ORDER, ROTATE_X90
|
|
||||||
|
|
||||||
Draw.Label('Import...', ui_x+9, ui_y+159, 220, 21)
|
|
||||||
Draw.BeginAlign()
|
|
||||||
CREATE_SMOOTH_GROUPS = Draw.Toggle('Smooth Groups', EVENT_NONE, ui_x+9, ui_y+139, 110, 20, CREATE_SMOOTH_GROUPS.val, 'Surround smooth groups by sharp edges')
|
|
||||||
CREATE_FGONS = Draw.Toggle('NGons as FGons', EVENT_NONE, ui_x+119, ui_y+139, 110, 20, CREATE_FGONS.val, 'Import faces with more then 4 verts as fgons')
|
|
||||||
CREATE_EDGES = Draw.Toggle('Lines as Edges', EVENT_NONE, ui_x+229, ui_y+139, 110, 20, CREATE_EDGES.val, 'Import lines and faces with 2 verts as edges')
|
|
||||||
Draw.EndAlign()
|
|
||||||
|
|
||||||
Draw.Label('Separate objects by OBJ...', ui_x+9, ui_y+110, 220, 20)
|
|
||||||
Draw.BeginAlign()
|
|
||||||
SPLIT_OBJECTS = Draw.Toggle('Object', EVENT_REDRAW, ui_x+9, ui_y+89, 55, 21, SPLIT_OBJECTS.val, 'Import OBJ Objects into Blender Objects', do_split)
|
|
||||||
SPLIT_GROUPS = Draw.Toggle('Group', EVENT_REDRAW, ui_x+64, ui_y+89, 55, 21, SPLIT_GROUPS.val, 'Import OBJ Groups into Blender Objects', do_split)
|
|
||||||
Draw.EndAlign()
|
|
||||||
|
|
||||||
# Only used for user feedback
|
|
||||||
KEEP_VERT_ORDER = Draw.Toggle('Keep Vert Order', EVENT_REDRAW, ui_x+184, ui_y+89, 113, 21, KEEP_VERT_ORDER.val, 'Keep vert and face order, disables split options, enable for morph targets', do_vertorder)
|
|
||||||
|
|
||||||
ROTATE_X90 = Draw.Toggle('-X90', EVENT_REDRAW, ui_x+302, ui_y+89, 38, 21, ROTATE_X90.val, 'Rotate X 90.')
|
|
||||||
|
|
||||||
Draw.Label('Options...', ui_x+9, ui_y+60, 211, 20)
|
|
||||||
CLAMP_SIZE = Draw.Number('Clamp Scale: ', EVENT_NONE, ui_x+9, ui_y+39, 130, 21, CLAMP_SIZE.val, 0.0, 1000.0, 'Clamp the size to this maximum (Zero to Disable)')
|
|
||||||
POLYGROUPS = Draw.Toggle('Poly Groups', EVENT_REDRAW, ui_x+144, ui_y+39, 90, 21, POLYGROUPS.val, 'Import OBJ groups as vertex groups.', do_polygroups)
|
|
||||||
IMAGE_SEARCH = Draw.Toggle('Image Search', EVENT_NONE, ui_x+239, ui_y+39, 100, 21, IMAGE_SEARCH.val, 'Search subdirs for any assosiated images (Warning, may be slow)')
|
|
||||||
Draw.BeginAlign()
|
|
||||||
Draw.PushButton('Online Help', EVENT_REDRAW, ui_x+9, ui_y+9, 110, 21, 'Load the wiki page for this script', do_help)
|
|
||||||
Draw.PushButton('Cancel', EVENT_EXIT, ui_x+119, ui_y+9, 110, 21, '', obj_ui_set_event)
|
|
||||||
Draw.PushButton('Import', EVENT_IMPORT, ui_x+229, ui_y+9, 110, 21, 'Import with these settings', obj_ui_set_event)
|
|
||||||
Draw.EndAlign()
|
|
||||||
|
|
||||||
|
|
||||||
# hack so the toggle buttons redraw. this is not nice at all
|
|
||||||
while GLOBALS['EVENT'] not in (EVENT_EXIT, EVENT_IMPORT):
|
|
||||||
Draw.UIBlock(obj_ui, 0)
|
|
||||||
|
|
||||||
if GLOBALS['EVENT'] != EVENT_IMPORT:
|
|
||||||
return
|
|
||||||
|
|
||||||
# END ALTERNATIVE UI *********************
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Window.WaitCursor(1)
|
|
||||||
|
|
||||||
if BATCH_LOAD: # load the dir
|
|
||||||
try:
|
|
||||||
files= [ f for f in os.listdir(filepath) if f.lower().endswith('.obj') ]
|
|
||||||
except:
|
|
||||||
Window.WaitCursor(0)
|
|
||||||
Draw.PupMenu('Error%t|Could not open path ' + filepath)
|
|
||||||
return
|
|
||||||
|
|
||||||
if not files:
|
|
||||||
Window.WaitCursor(0)
|
|
||||||
Draw.PupMenu('Error%t|No files at path ' + filepath)
|
|
||||||
return
|
|
||||||
|
|
||||||
for f in files:
|
|
||||||
scn= bpy.data.scenes.new(os.path.splitext(f)[0])
|
|
||||||
scn.makeCurrent()
|
|
||||||
|
|
||||||
load_obj(sys.join(filepath, f),\
|
|
||||||
CLAMP_SIZE.val,\
|
|
||||||
CREATE_FGONS.val,\
|
|
||||||
CREATE_SMOOTH_GROUPS.val,\
|
|
||||||
CREATE_EDGES.val,\
|
|
||||||
SPLIT_OBJECTS.val,\
|
|
||||||
SPLIT_GROUPS.val,\
|
|
||||||
ROTATE_X90.val,\
|
|
||||||
IMAGE_SEARCH.val,\
|
|
||||||
POLYGROUPS.val
|
|
||||||
)
|
|
||||||
|
|
||||||
else: # Normal load
|
|
||||||
load_obj(filepath,\
|
|
||||||
CLAMP_SIZE.val,\
|
|
||||||
CREATE_FGONS.val,\
|
|
||||||
CREATE_SMOOTH_GROUPS.val,\
|
|
||||||
CREATE_EDGES.val,\
|
|
||||||
SPLIT_OBJECTS.val,\
|
|
||||||
SPLIT_GROUPS.val,\
|
|
||||||
ROTATE_X90.val,\
|
|
||||||
IMAGE_SEARCH.val,\
|
|
||||||
POLYGROUPS.val
|
|
||||||
)
|
|
||||||
|
|
||||||
Window.WaitCursor(0)
|
|
||||||
|
|
||||||
|
|
||||||
def load_obj_ui_batch(file):
|
|
||||||
load_obj_ui(file, True)
|
|
||||||
|
|
||||||
DEBUG= False
|
|
||||||
|
|
||||||
# if __name__=='__main__' and not DEBUG:
|
|
||||||
# if os and Window.GetKeyQualifiers() & Window.Qual.SHIFT:
|
|
||||||
# Window.FileSelector(load_obj_ui_batch, 'Import OBJ Dir', '')
|
|
||||||
# else:
|
|
||||||
# Window.FileSelector(load_obj_ui, 'Import a Wavefront OBJ', '*.obj')
|
|
||||||
|
|
||||||
# For testing compatibility
|
|
||||||
'''
|
|
||||||
else:
|
|
||||||
# DEBUG ONLY
|
|
||||||
TIME= sys.time()
|
|
||||||
DIR = '/fe/obj'
|
|
||||||
import os
|
|
||||||
print 'Searching for files'
|
|
||||||
def fileList(path):
|
|
||||||
for dirpath, dirnames, filenames in os.walk(path):
|
|
||||||
for filename in filenames:
|
|
||||||
yield os.path.join(dirpath, filename)
|
|
||||||
|
|
||||||
files = [f for f in fileList(DIR) if f.lower().endswith('.obj')]
|
|
||||||
files.sort()
|
|
||||||
|
|
||||||
for i, obj_file in enumerate(files):
|
|
||||||
if 0 < i < 20:
|
|
||||||
print 'Importing', obj_file, '\nNUMBER', i, 'of', len(files)
|
|
||||||
newScn= bpy.data.scenes.new(os.path.basename(obj_file))
|
|
||||||
newScn.makeCurrent()
|
|
||||||
load_obj(obj_file, False, IMAGE_SEARCH=0)
|
|
||||||
|
|
||||||
print 'TOTAL TIME: %.6f' % (sys.time() - TIME)
|
|
||||||
'''
|
|
||||||
|
|
||||||
from bpy.props import *
|
|
||||||
|
|
||||||
class IMPORT_OT_obj(bpy.types.Operator):
|
|
||||||
'''Load a Wavefront OBJ File'''
|
|
||||||
bl_idname = "import_scene.obj"
|
|
||||||
bl_label = "Import OBJ"
|
|
||||||
|
|
||||||
# List of operator properties, the attributes will be assigned
|
|
||||||
# to the class instance from the operator settings before calling.
|
|
||||||
|
|
||||||
|
|
||||||
filepath = StringProperty(name="File Path", description="Filepath used for importing the OBJ file", maxlen= 1024, default= "")
|
|
||||||
|
|
||||||
CREATE_SMOOTH_GROUPS = BoolProperty(name="Smooth Groups", description="Surround smooth groups by sharp edges", default= True)
|
|
||||||
CREATE_FGONS = BoolProperty(name="NGons as FGons", description="Import faces with more then 4 verts as fgons", default= True)
|
|
||||||
CREATE_EDGES = BoolProperty(name="Lines as Edges", description="Import lines and faces with 2 verts as edge", default= True)
|
|
||||||
SPLIT_OBJECTS = BoolProperty(name="Object", description="Import OBJ Objects into Blender Objects", default= True)
|
|
||||||
SPLIT_GROUPS = BoolProperty(name="Group", description="Import OBJ Groups into Blender Objects", default= True)
|
|
||||||
# old comment: only used for user feedback
|
|
||||||
# disabled this option because in old code a handler for it disabled SPLIT* params, it's not passed to load_obj
|
|
||||||
# KEEP_VERT_ORDER = BoolProperty(name="Keep Vert Order", description="Keep vert and face order, disables split options, enable for morph targets", default= True)
|
|
||||||
ROTATE_X90 = BoolProperty(name="-X90", description="Rotate X 90.", default= True)
|
|
||||||
CLAMP_SIZE = FloatProperty(name="Clamp Scale", description="Clamp the size to this maximum (Zero to Disable)", min=0.0, max=1000.0, soft_min=0.0, soft_max=1000.0, default=0.0)
|
|
||||||
POLYGROUPS = BoolProperty(name="Poly Groups", description="Import OBJ groups as vertex groups.", default= True)
|
|
||||||
IMAGE_SEARCH = BoolProperty(name="Image Search", description="Search subdirs for any assosiated images (Warning, may be slow)", default= True)
|
|
||||||
|
|
||||||
|
|
||||||
def execute(self, context):
|
|
||||||
# print("Selected: " + context.active_object.name)
|
|
||||||
|
|
||||||
load_obj(self.properties.filepath,
|
|
||||||
context,
|
|
||||||
self.properties.CLAMP_SIZE,
|
|
||||||
self.properties.CREATE_FGONS,
|
|
||||||
self.properties.CREATE_SMOOTH_GROUPS,
|
|
||||||
self.properties.CREATE_EDGES,
|
|
||||||
self.properties.SPLIT_OBJECTS,
|
|
||||||
self.properties.SPLIT_GROUPS,
|
|
||||||
self.properties.ROTATE_X90,
|
|
||||||
self.properties.IMAGE_SEARCH,
|
|
||||||
self.properties.POLYGROUPS)
|
|
||||||
|
|
||||||
return {'FINISHED'}
|
|
||||||
|
|
||||||
def invoke(self, context, event):
|
|
||||||
context.manager.add_fileselect(self)
|
|
||||||
return {'RUNNING_MODAL'}
|
|
||||||
|
|
||||||
|
|
||||||
def menu_func(self, context):
|
|
||||||
self.layout.operator(IMPORT_OT_obj.bl_idname, text="Wavefront (.obj)")
|
|
||||||
|
|
||||||
|
|
||||||
def register():
|
|
||||||
bpy.types.INFO_MT_file_import.append(menu_func)
|
|
||||||
|
|
||||||
def unregister():
|
|
||||||
bpy.types.INFO_MT_file_import.remove(menu_func)
|
|
||||||
|
|
||||||
|
|
||||||
# NOTES (all line numbers refer to 2.4x import_obj.py, not this file)
|
# NOTES (all line numbers refer to 2.4x import_obj.py, not this file)
|
||||||
61
release/scripts/op/io_scene_x3d/__init__.py
Normal file
61
release/scripts/op/io_scene_x3d/__init__.py
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
# ##### BEGIN GPL LICENSE BLOCK #####
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software Foundation,
|
||||||
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
#
|
||||||
|
# ##### END GPL LICENSE BLOCK #####
|
||||||
|
|
||||||
|
# To support reload properly, try to access a package var, if it's there, reload everything
|
||||||
|
if "bpy" in locals():
|
||||||
|
# only reload if we alredy loaded, highly annoying
|
||||||
|
import sys
|
||||||
|
reload(sys.modules.get("io_scene_x3d.export_x3d", sys))
|
||||||
|
|
||||||
|
|
||||||
|
import bpy
|
||||||
|
from bpy.props import *
|
||||||
|
from io_utils import ExportHelper
|
||||||
|
|
||||||
|
|
||||||
|
class ExportX3D(bpy.types.Operator, ExportHelper):
|
||||||
|
'''Export selection to Extensible 3D file (.x3d)'''
|
||||||
|
bl_idname = "export_scene.x3d"
|
||||||
|
bl_label = 'Export X3D'
|
||||||
|
|
||||||
|
filename_ext = ".x3d"
|
||||||
|
|
||||||
|
use_apply_modifiers = BoolProperty(name="Apply Modifiers", description="Use transformed mesh data from each object", default=True)
|
||||||
|
use_triangulate = BoolProperty(name="Triangulate", description="Triangulate quads.", default=False)
|
||||||
|
use_compress = BoolProperty(name="Compress", description="GZip the resulting file, requires a full python install", default=False)
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
import io_scene_x3d.export_x3d
|
||||||
|
return io_scene_x3d.export_x3d.save(self, context, **self.properties)
|
||||||
|
|
||||||
|
|
||||||
|
def menu_func(self, context):
|
||||||
|
self.layout.operator(ExportX3D.bl_idname, text="X3D Extensible 3D (.x3d)")
|
||||||
|
|
||||||
|
|
||||||
|
def register():
|
||||||
|
bpy.types.INFO_MT_file_export.append(menu_func)
|
||||||
|
|
||||||
|
def unregister():
|
||||||
|
bpy.types.INFO_MT_file_export.remove(menu_func)
|
||||||
|
|
||||||
|
# NOTES
|
||||||
|
# - blender version is hardcoded
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
register()
|
||||||
@@ -18,68 +18,29 @@
|
|||||||
|
|
||||||
# <pep8 compliant>
|
# <pep8 compliant>
|
||||||
|
|
||||||
__author__ = ("Bart", "Campbell Barton")
|
# Contributors: bart:neeneenee*de, http://www.neeneenee.de/vrml, Campbell Barton
|
||||||
__email__ = ["Bart, bart:neeneenee*de"]
|
|
||||||
__url__ = ["Author's (Bart) homepage, http://www.neeneenee.de/vrml"]
|
"""
|
||||||
__version__ = "2006/01/17"
|
|
||||||
__bpydoc__ = """\
|
|
||||||
This script exports to X3D format.
|
This script exports to X3D format.
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
|
|
||||||
Run this script from "File->Export" menu. A pop-up will ask whether you
|
Run this script from "File->Export" menu. A pop-up will ask whether you
|
||||||
want to export only selected or all relevant objects.
|
want to export only selected or all relevant objects.
|
||||||
|
|
||||||
Known issues:<br>
|
Known issues:
|
||||||
Doesn't handle multiple materials (don't use material indices);<br>
|
Doesn't handle multiple materials (don't use material indices);<br>
|
||||||
Doesn't handle multiple UV textures on a single mesh (create a mesh for each texture);<br>
|
Doesn't handle multiple UV textures on a single mesh (create a mesh for each texture);<br>
|
||||||
Can't get the texture array associated with material * not the UV ones;
|
Can't get the texture array associated with material * not the UV ones;
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
# $Id$
|
|
||||||
#
|
|
||||||
#------------------------------------------------------------------------
|
|
||||||
# X3D exporter for blender 2.36 or above
|
|
||||||
#
|
|
||||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or
|
|
||||||
# modify it under the terms of the GNU General Public License
|
|
||||||
# as published by the Free Software Foundation; either version 2
|
|
||||||
# of the License, or (at your option) any later version.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software Foundation,
|
|
||||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
#
|
|
||||||
# ***** END GPL LICENCE BLOCK *****
|
|
||||||
#
|
|
||||||
|
|
||||||
####################################
|
|
||||||
# Library dependancies
|
|
||||||
####################################
|
|
||||||
|
|
||||||
import math
|
import math
|
||||||
import os
|
import os
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
import mathutils
|
import mathutils
|
||||||
|
|
||||||
from export_3ds import create_derived_objects, free_derived_objects
|
from io_utils import create_derived_objects, free_derived_objects
|
||||||
|
|
||||||
# import Blender
|
|
||||||
# from Blender import Object, Lamp, Draw, Image, Text, sys, Mesh
|
|
||||||
# from Blender.Scene import Render
|
|
||||||
# import BPyObject
|
|
||||||
# import BPyMesh
|
|
||||||
|
|
||||||
#
|
|
||||||
DEG2RAD=0.017453292519943295
|
DEG2RAD=0.017453292519943295
|
||||||
MATWORLD= mathutils.Matrix.Rotation(-90, 4, 'X')
|
MATWORLD= mathutils.Matrix.Rotation(-90, 4, 'X')
|
||||||
|
|
||||||
@@ -87,8 +48,7 @@ MATWORLD= mathutils.Matrix.Rotation(-90, 4, 'X')
|
|||||||
# Global Variables
|
# Global Variables
|
||||||
####################################
|
####################################
|
||||||
|
|
||||||
filename = ""
|
filepath = ""
|
||||||
# filename = Blender.Get('filename')
|
|
||||||
_safeOverwrite = True
|
_safeOverwrite = True
|
||||||
|
|
||||||
extension = ''
|
extension = ''
|
||||||
@@ -99,7 +59,7 @@ extension = ''
|
|||||||
|
|
||||||
class x3d_class:
|
class x3d_class:
|
||||||
|
|
||||||
def __init__(self, filename):
|
def __init__(self, filepath):
|
||||||
#--- public you can change these ---
|
#--- public you can change these ---
|
||||||
self.writingcolor = 0
|
self.writingcolor = 0
|
||||||
self.writingtexture = 0
|
self.writingtexture = 0
|
||||||
@@ -122,18 +82,18 @@ class x3d_class:
|
|||||||
self.matNames={} # dictionary of materiaNames
|
self.matNames={} # dictionary of materiaNames
|
||||||
self.meshNames={} # dictionary of meshNames
|
self.meshNames={} # dictionary of meshNames
|
||||||
self.indentLevel=0 # keeps track of current indenting
|
self.indentLevel=0 # keeps track of current indenting
|
||||||
self.filename=filename
|
self.filepath=filepath
|
||||||
self.file = None
|
self.file = None
|
||||||
if filename.lower().endswith('.x3dz'):
|
if filepath.lower().endswith('.x3dz'):
|
||||||
try:
|
try:
|
||||||
import gzip
|
import gzip
|
||||||
self.file = gzip.open(filename, "w")
|
self.file = gzip.open(filepath, "w")
|
||||||
except:
|
except:
|
||||||
print("failed to import compression modules, exporting uncompressed")
|
print("failed to import compression modules, exporting uncompressed")
|
||||||
self.filename = filename[:-1] # remove trailing z
|
self.filepath = filepath[:-1] # remove trailing z
|
||||||
|
|
||||||
if self.file == None:
|
if self.file == None:
|
||||||
self.file = open(self.filename, "w")
|
self.file = open(self.filepath, "w")
|
||||||
|
|
||||||
self.bNav=0
|
self.bNav=0
|
||||||
self.nodeID=0
|
self.nodeID=0
|
||||||
@@ -175,13 +135,13 @@ class x3d_class:
|
|||||||
##########################################################
|
##########################################################
|
||||||
|
|
||||||
def writeHeader(self):
|
def writeHeader(self):
|
||||||
#bfile = sys.expandpath( Blender.Get('filename') ).replace('<', '<').replace('>', '>')
|
#bfile = sys.expandpath( Blender.Get('filepath') ).replace('<', '<').replace('>', '>')
|
||||||
bfile = self.filename.replace('<', '<').replace('>', '>') # use outfile name
|
bfile = repr(os.path.basename(self.filepath).replace('<', '<').replace('>', '>'))[1:-1] # use outfile name
|
||||||
self.file.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
|
self.file.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
|
||||||
self.file.write("<!DOCTYPE X3D PUBLIC \"ISO//Web3D//DTD X3D 3.0//EN\" \"http://www.web3d.org/specifications/x3d-3.0.dtd\">\n")
|
self.file.write("<!DOCTYPE X3D PUBLIC \"ISO//Web3D//DTD X3D 3.0//EN\" \"http://www.web3d.org/specifications/x3d-3.0.dtd\">\n")
|
||||||
self.file.write("<X3D version=\"3.0\" profile=\"Immersive\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema-instance\" xsd:noNamespaceSchemaLocation=\"http://www.web3d.org/specifications/x3d-3.0.xsd\">\n")
|
self.file.write("<X3D version=\"3.0\" profile=\"Immersive\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema-instance\" xsd:noNamespaceSchemaLocation=\"http://www.web3d.org/specifications/x3d-3.0.xsd\">\n")
|
||||||
self.file.write("<head>\n")
|
self.file.write("<head>\n")
|
||||||
self.file.write("\t<meta name=\"filename\" content=\"%s\" />\n" % os.path.basename(bfile))
|
self.file.write("\t<meta name=\"filename\" content=\"%s\" />\n" % bfile)
|
||||||
# self.file.write("\t<meta name=\"filename\" content=\"%s\" />\n" % sys.basename(bfile))
|
# self.file.write("\t<meta name=\"filename\" content=\"%s\" />\n" % sys.basename(bfile))
|
||||||
self.file.write("\t<meta name=\"generator\" content=\"Blender %s\" />\n" % bpy.app.version_string)
|
self.file.write("\t<meta name=\"generator\" content=\"Blender %s\" />\n" % bpy.app.version_string)
|
||||||
# self.file.write("\t<meta name=\"generator\" content=\"Blender %s\" />\n" % Blender.Get('version'))
|
# self.file.write("\t<meta name=\"generator\" content=\"Blender %s\" />\n" % Blender.Get('version'))
|
||||||
@@ -465,6 +425,7 @@ class x3d_class:
|
|||||||
self.writeIndented("<Appearance>\n", 1)
|
self.writeIndented("<Appearance>\n", 1)
|
||||||
# right now this script can only handle a single material per mesh.
|
# right now this script can only handle a single material per mesh.
|
||||||
if len(maters) >= 1 and maters[0].use_face_texture == False:
|
if len(maters) >= 1 and maters[0].use_face_texture == False:
|
||||||
|
mat = maters[0]
|
||||||
self.writeMaterial(mat, self.cleanStr(mat.name,''), world)
|
self.writeMaterial(mat, self.cleanStr(mat.name,''), world)
|
||||||
if len(maters) > 1:
|
if len(maters) > 1:
|
||||||
print("Warning: mesh named %s has multiple materials" % meshName)
|
print("Warning: mesh named %s has multiple materials" % meshName)
|
||||||
@@ -711,13 +672,13 @@ class x3d_class:
|
|||||||
|
|
||||||
def writeImageTexture(self, image):
|
def writeImageTexture(self, image):
|
||||||
name = image.name
|
name = image.name
|
||||||
filename = os.path.basename(image.filepath)
|
filepath = os.path.basename(image.filepath)
|
||||||
if name in self.texNames:
|
if name in self.texNames:
|
||||||
self.writeIndented("<ImageTexture USE=\"%s\" />\n" % self.cleanStr(name))
|
self.writeIndented("<ImageTexture USE=\"%s\" />\n" % self.cleanStr(name))
|
||||||
self.texNames[name] += 1
|
self.texNames[name] += 1
|
||||||
else:
|
else:
|
||||||
self.writeIndented("<ImageTexture DEF=\"%s\" " % self.cleanStr(name), 1)
|
self.writeIndented("<ImageTexture DEF=\"%s\" " % self.cleanStr(name), 1)
|
||||||
self.file.write("url=\"%s\" />" % filename)
|
self.file.write("url=\"%s\" />" % filepath)
|
||||||
self.writeIndented("\n",-1)
|
self.writeIndented("\n",-1)
|
||||||
self.texNames[name] = 1
|
self.texNames[name] = 1
|
||||||
|
|
||||||
@@ -820,7 +781,7 @@ class x3d_class:
|
|||||||
EXPORT_TRI= False,\
|
EXPORT_TRI= False,\
|
||||||
):
|
):
|
||||||
|
|
||||||
print("Info: starting X3D export to " + self.filename + "...")
|
print("Info: starting X3D export to %r..." % self.filepath)
|
||||||
self.writeHeader()
|
self.writeHeader()
|
||||||
# self.writeScript()
|
# self.writeScript()
|
||||||
self.writeNavigationInfo(scene)
|
self.writeNavigationInfo(scene)
|
||||||
@@ -918,7 +879,7 @@ class x3d_class:
|
|||||||
self.texNames={}
|
self.texNames={}
|
||||||
self.matNames={}
|
self.matNames={}
|
||||||
self.indentLevel=0
|
self.indentLevel=0
|
||||||
print("Info: finished X3D export to %s\n" % self.filename)
|
print("Info: finished X3D export to %r" % self.filepath)
|
||||||
|
|
||||||
def cleanStr(self, name, prefix='rsvd_'):
|
def cleanStr(self, name, prefix='rsvd_'):
|
||||||
"""cleanStr(name,prefix) - try to create a valid VRML DEF name from object name"""
|
"""cleanStr(name,prefix) - try to create a valid VRML DEF name from object name"""
|
||||||
@@ -1128,91 +1089,35 @@ class x3d_class:
|
|||||||
# Callbacks, needed before Main
|
# Callbacks, needed before Main
|
||||||
##########################################################
|
##########################################################
|
||||||
|
|
||||||
def write(filename,
|
def save(operator, context, filepath="",
|
||||||
context,
|
use_apply_modifiers=False,
|
||||||
EXPORT_APPLY_MODIFIERS=False,
|
use_triangulate=False,
|
||||||
EXPORT_TRI=False,
|
use_compress=False):
|
||||||
EXPORT_GZIP=False):
|
|
||||||
|
|
||||||
if EXPORT_GZIP:
|
if use_compress:
|
||||||
if not filename.lower().endswith('.x3dz'):
|
if not filepath.lower().endswith('.x3dz'):
|
||||||
filename = '.'.join(filename.split('.')[:-1]) + '.x3dz'
|
filepath = '.'.join(filepath.split('.')[:-1]) + '.x3dz'
|
||||||
else:
|
else:
|
||||||
if not filename.lower().endswith('.x3d'):
|
if not filepath.lower().endswith('.x3d'):
|
||||||
filename = '.'.join(filename.split('.')[:-1]) + '.x3d'
|
filepath = '.'.join(filepath.split('.')[:-1]) + '.x3d'
|
||||||
|
|
||||||
|
|
||||||
scene = context.scene
|
scene = context.scene
|
||||||
world = scene.world
|
world = scene.world
|
||||||
|
|
||||||
if scene.objects.active:
|
if bpy.ops.object.mode_set.poll():
|
||||||
bpy.ops.object.mode_set(mode='OBJECT')
|
bpy.ops.object.mode_set(mode='OBJECT')
|
||||||
|
|
||||||
# XXX these are global textures while .Get() returned only scene's?
|
# XXX these are global textures while .Get() returned only scene's?
|
||||||
alltextures = bpy.data.textures
|
alltextures = bpy.data.textures
|
||||||
# alltextures = Blender.Texture.Get()
|
# alltextures = Blender.Texture.Get()
|
||||||
|
|
||||||
wrlexport=x3d_class(filename)
|
wrlexport = x3d_class(filepath)
|
||||||
wrlexport.export(\
|
wrlexport.export(scene,
|
||||||
scene,\
|
world,
|
||||||
world,\
|
alltextures,
|
||||||
alltextures,\
|
EXPORT_APPLY_MODIFIERS=use_apply_modifiers,
|
||||||
\
|
EXPORT_TRI=use_triangulate,
|
||||||
EXPORT_APPLY_MODIFIERS = EXPORT_APPLY_MODIFIERS,\
|
)
|
||||||
EXPORT_TRI = EXPORT_TRI,\
|
|
||||||
)
|
|
||||||
|
|
||||||
|
return {'FINISHED'}
|
||||||
|
|
||||||
from bpy.props import *
|
|
||||||
|
|
||||||
class ExportX3D(bpy.types.Operator):
|
|
||||||
'''Export selection to Extensible 3D file (.x3d)'''
|
|
||||||
bl_idname = "export.x3d"
|
|
||||||
bl_label = 'Export X3D'
|
|
||||||
|
|
||||||
# List of operator properties, the attributes will be assigned
|
|
||||||
# to the class instance from the operator settings before calling.
|
|
||||||
filepath = StringProperty(name="File Path", description="Filepath used for exporting the X3D file", maxlen= 1024, default= "")
|
|
||||||
check_existing = BoolProperty(name="Check Existing", description="Check and warn on overwriting existing files", default=True, options={'HIDDEN'})
|
|
||||||
|
|
||||||
apply_modifiers = BoolProperty(name="Apply Modifiers", description="Use transformed mesh data from each object", default=True)
|
|
||||||
triangulate = BoolProperty(name="Triangulate", description="Triangulate quads.", default=False)
|
|
||||||
compress = BoolProperty(name="Compress", description="GZip the resulting file, requires a full python install", default=False)
|
|
||||||
|
|
||||||
def execute(self, context):
|
|
||||||
filepath = self.properties.filepath
|
|
||||||
filepath = bpy.path.ensure_ext(filepath, ".x3d")
|
|
||||||
|
|
||||||
write(filepath,
|
|
||||||
context,
|
|
||||||
self.properties.apply_modifiers,
|
|
||||||
self.properties.triangulate,
|
|
||||||
self.properties.compress,
|
|
||||||
)
|
|
||||||
|
|
||||||
return {'FINISHED'}
|
|
||||||
|
|
||||||
def invoke(self, context, event):
|
|
||||||
import os
|
|
||||||
if not self.properties.is_property_set("filepath"):
|
|
||||||
self.properties.filepath = os.path.splitext(bpy.data.filepath)[0] + ".x3d"
|
|
||||||
|
|
||||||
context.manager.add_fileselect(self)
|
|
||||||
return {'RUNNING_MODAL'}
|
|
||||||
|
|
||||||
|
|
||||||
def menu_func(self, context):
|
|
||||||
self.layout.operator(ExportX3D.bl_idname, text="X3D Extensible 3D (.x3d)")
|
|
||||||
|
|
||||||
|
|
||||||
def register():
|
|
||||||
bpy.types.INFO_MT_file_export.append(menu_func)
|
|
||||||
|
|
||||||
def unregister():
|
|
||||||
bpy.types.INFO_MT_file_export.remove(menu_func)
|
|
||||||
|
|
||||||
# NOTES
|
|
||||||
# - blender version is hardcoded
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
register()
|
|
||||||
115
release/scripts/op/io_shape_mdd/__init__.py
Normal file
115
release/scripts/op/io_shape_mdd/__init__.py
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
# ##### BEGIN GPL LICENSE BLOCK #####
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software Foundation,
|
||||||
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
#
|
||||||
|
# ##### END GPL LICENSE BLOCK #####
|
||||||
|
|
||||||
|
# <pep8 compliant>
|
||||||
|
|
||||||
|
# To support reload properly, try to access a package var, if it's there, reload everything
|
||||||
|
if "bpy" in locals():
|
||||||
|
# only reload if we alredy loaded, highly annoying
|
||||||
|
import sys
|
||||||
|
reload(sys.modules.get("io_shape_mdd.import_mdd", sys))
|
||||||
|
reload(sys.modules.get("io_shape_mdd.export_mdd", sys))
|
||||||
|
|
||||||
|
|
||||||
|
import bpy
|
||||||
|
from bpy.props import *
|
||||||
|
from io_utils import ExportHelper, ImportHelper
|
||||||
|
|
||||||
|
|
||||||
|
class ImportMDD(bpy.types.Operator, ImportHelper):
|
||||||
|
'''Import MDD vertex keyframe file to shape keys'''
|
||||||
|
bl_idname = "import_shape.mdd"
|
||||||
|
bl_label = "Import MDD"
|
||||||
|
|
||||||
|
filename_ext = ".mdd"
|
||||||
|
frame_start = IntProperty(name="Start Frame", description="Start frame for inserting animation", min=-300000, max=300000, default=0)
|
||||||
|
frame_step = IntProperty(name="Step", min=1, max=1000, default=1)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def poll(cls, context):
|
||||||
|
ob = context.active_object
|
||||||
|
return (ob and ob.type == 'MESH')
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
|
||||||
|
# initialize from scene if unset
|
||||||
|
scene = context.scene
|
||||||
|
if not self.properties.is_property_set("frame_start"):
|
||||||
|
self.properties.frame_start = scene.frame_current
|
||||||
|
|
||||||
|
import io_shape_mdd.import_mdd
|
||||||
|
return io_shape_mdd.import_mdd.load(self, context, **self.properties)
|
||||||
|
|
||||||
|
class ExportMDD(bpy.types.Operator, ExportHelper):
|
||||||
|
'''Animated mesh to MDD vertex keyframe file'''
|
||||||
|
bl_idname = "export_shape.mdd"
|
||||||
|
bl_label = "Export MDD"
|
||||||
|
|
||||||
|
filename_ext = ".mdd"
|
||||||
|
|
||||||
|
# get first scene to get min and max properties for frames, fps
|
||||||
|
|
||||||
|
minframe = 1
|
||||||
|
maxframe = 300000
|
||||||
|
minfps = 1
|
||||||
|
maxfps = 120
|
||||||
|
|
||||||
|
# List of operator properties, the attributes will be assigned
|
||||||
|
# to the class instance from the operator settings before calling.
|
||||||
|
fps = IntProperty(name="Frames Per Second", description="Number of frames/second", min=minfps, max=maxfps, default=25)
|
||||||
|
frame_start = IntProperty(name="Start Frame", description="Start frame for baking", min=minframe, max=maxframe, default=1)
|
||||||
|
frame_end = IntProperty(name="End Frame", description="End frame for baking", min=minframe, max=maxframe, default=250)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def poll(cls, context):
|
||||||
|
obj = context.active_object
|
||||||
|
return (obj and obj.type == 'MESH')
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
# initialize from scene if unset
|
||||||
|
scene = context.scene
|
||||||
|
if not self.properties.is_property_set("frame_start"):
|
||||||
|
self.properties.frame_start = scene.frame_start
|
||||||
|
if not self.properties.is_property_set("frame_end"):
|
||||||
|
self.properties.frame_end = scene.frame_end
|
||||||
|
if not self.properties.is_property_set("fps"):
|
||||||
|
self.properties.fps = scene.render.fps
|
||||||
|
|
||||||
|
import io_shape_mdd.export_mdd
|
||||||
|
return io_shape_mdd.export_mdd.save(self, context, **self.properties)
|
||||||
|
|
||||||
|
|
||||||
|
def menu_func_import(self, context):
|
||||||
|
self.layout.operator(ImportMDD.bl_idname, text="Lightwave Point Cache (.mdd)")
|
||||||
|
|
||||||
|
|
||||||
|
def menu_func_export(self, context):
|
||||||
|
self.layout.operator(ExportMDD.bl_idname, text="Lightwave Point Cache (.mdd)")
|
||||||
|
|
||||||
|
|
||||||
|
def register():
|
||||||
|
bpy.types.INFO_MT_file_import.append(menu_func_import)
|
||||||
|
bpy.types.INFO_MT_file_export.append(menu_func_export)
|
||||||
|
|
||||||
|
|
||||||
|
def unregister():
|
||||||
|
bpy.types.INFO_MT_file_import.remove(menu_func_import)
|
||||||
|
bpy.types.INFO_MT_file_export.remove(menu_func_export)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
register()
|
||||||
131
release/scripts/op/io_shape_mdd/export_mdd.py
Normal file
131
release/scripts/op/io_shape_mdd/export_mdd.py
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
# ##### BEGIN GPL LICENSE BLOCK #####
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software Foundation,
|
||||||
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
#
|
||||||
|
# ##### END GPL LICENSE BLOCK #####
|
||||||
|
|
||||||
|
# <pep8 compliant>
|
||||||
|
|
||||||
|
# Contributors: Bill L.Nieuwendorp
|
||||||
|
|
||||||
|
"""
|
||||||
|
This script Exports Lightwaves MotionDesigner format.
|
||||||
|
|
||||||
|
The .mdd format has become quite a popular Pipeline format<br>
|
||||||
|
for moving animations from package to package.
|
||||||
|
|
||||||
|
Be sure not to use modifiers that change the number or order of verts in the mesh
|
||||||
|
"""
|
||||||
|
|
||||||
|
import bpy
|
||||||
|
import mathutils
|
||||||
|
from struct import pack
|
||||||
|
|
||||||
|
|
||||||
|
def zero_file(filepath):
|
||||||
|
'''
|
||||||
|
If a file fails, this replaces it with 1 char, better not remove it?
|
||||||
|
'''
|
||||||
|
file = open(filepath, 'w')
|
||||||
|
file.write('\n') # apparently macosx needs some data in a blank file?
|
||||||
|
file.close()
|
||||||
|
|
||||||
|
|
||||||
|
def check_vertcount(mesh, vertcount):
|
||||||
|
'''
|
||||||
|
check and make sure the vertcount is consistent throughout the frame range
|
||||||
|
'''
|
||||||
|
if len(mesh.vertices) != vertcount:
|
||||||
|
raise Exception('Error, number of verts has changed during animation, cannot export')
|
||||||
|
f.close()
|
||||||
|
zero_file(filepath)
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def save(operator, context, filepath="", frame_start=1, frame_end=300, fps=25):
|
||||||
|
"""
|
||||||
|
Blender.Window.WaitCursor(1)
|
||||||
|
|
||||||
|
mesh_orig = Mesh.New()
|
||||||
|
mesh_orig.getFromObject(obj.name)
|
||||||
|
"""
|
||||||
|
|
||||||
|
scene = context.scene
|
||||||
|
obj = context.object
|
||||||
|
|
||||||
|
if bpy.ops.object.mode_set.poll():
|
||||||
|
bpy.ops.object.mode_set(mode='OBJECT')
|
||||||
|
|
||||||
|
orig_frame = scene.frame_current
|
||||||
|
scene.frame_set(frame_start)
|
||||||
|
me = obj.create_mesh(scene, True, 'PREVIEW')
|
||||||
|
|
||||||
|
#Flip y and z
|
||||||
|
mat_flip = mathutils.Matrix(\
|
||||||
|
[1.0, 0.0, 0.0, 0.0],\
|
||||||
|
[0.0, 0.0, 1.0, 0.0],\
|
||||||
|
[0.0, 1.0, 0.0, 0.0],\
|
||||||
|
[0.0, 0.0, 0.0, 1.0],\
|
||||||
|
)
|
||||||
|
|
||||||
|
numverts = len(me.vertices)
|
||||||
|
|
||||||
|
numframes = frame_end - frame_start + 1
|
||||||
|
fps = float(fps)
|
||||||
|
f = open(filepath, 'wb') #no Errors yet:Safe to create file
|
||||||
|
|
||||||
|
# Write the header
|
||||||
|
f.write(pack(">2i", numframes, numverts))
|
||||||
|
|
||||||
|
# Write the frame times (should we use the time IPO??)
|
||||||
|
f.write(pack(">%df" % (numframes), *[frame / fps for frame in range(numframes)])) # seconds
|
||||||
|
|
||||||
|
#rest frame needed to keep frames in sync
|
||||||
|
"""
|
||||||
|
Blender.Set('curframe', frame_start)
|
||||||
|
me_tmp.getFromObject(obj.name)
|
||||||
|
"""
|
||||||
|
|
||||||
|
check_vertcount(me, numverts)
|
||||||
|
me.transform(mat_flip * obj.matrix_world)
|
||||||
|
f.write(pack(">%df" % (numverts * 3), *[axis for v in me.vertices for axis in v.co]))
|
||||||
|
|
||||||
|
for frame in range(frame_start, frame_end + 1):#in order to start at desired frame
|
||||||
|
"""
|
||||||
|
Blender.Set('curframe', frame)
|
||||||
|
me_tmp.getFromObject(obj.name)
|
||||||
|
"""
|
||||||
|
|
||||||
|
scene.frame_set(frame)
|
||||||
|
me = obj.create_mesh(scene, True, 'PREVIEW')
|
||||||
|
check_vertcount(me, numverts)
|
||||||
|
me.transform(mat_flip * obj.matrix_world)
|
||||||
|
|
||||||
|
# Write the vertex data
|
||||||
|
f.write(pack(">%df" % (numverts * 3), *[axis for v in me.vertices for axis in v.co]))
|
||||||
|
|
||||||
|
"""
|
||||||
|
me_tmp.vertices= None
|
||||||
|
"""
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
print('MDD Exported: %r frames:%d\n' % (filepath, numframes - 1))
|
||||||
|
"""
|
||||||
|
Blender.Window.WaitCursor(0)
|
||||||
|
Blender.Set('curframe', orig_frame)
|
||||||
|
"""
|
||||||
|
scene.frame_set(orig_frame)
|
||||||
|
|
||||||
|
return {'FINISHED'}
|
||||||
105
release/scripts/op/io_shape_mdd/import_mdd.py
Normal file
105
release/scripts/op/io_shape_mdd/import_mdd.py
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
# ##### BEGIN GPL LICENSE BLOCK #####
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software Foundation,
|
||||||
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
#
|
||||||
|
# ##### END GPL LICENSE BLOCK #####
|
||||||
|
|
||||||
|
# <pep8 compliant>
|
||||||
|
|
||||||
|
# mdd importer by Bill L.Nieuwendorp
|
||||||
|
# conversion to blender 2.5: Ivo Grigull (loolarge)
|
||||||
|
#
|
||||||
|
# Warning if the vertex order or vertex count differs from the
|
||||||
|
# origonal model the mdd was Baked out from their will be Strange
|
||||||
|
# behavior
|
||||||
|
#
|
||||||
|
# vertex animation to ShapeKeys with ipo and gives the frame a value of 1.0
|
||||||
|
# A modifier to read mdd files would be Ideal but thats for another day :)
|
||||||
|
#
|
||||||
|
# Please send any fixes,updates,bugs to Slow67_at_Gmail.com
|
||||||
|
# Bill Niewuendorp
|
||||||
|
|
||||||
|
import bpy
|
||||||
|
from struct import unpack
|
||||||
|
|
||||||
|
|
||||||
|
def load(operator, context, filepath, frame_start=0, frame_step=1):
|
||||||
|
|
||||||
|
scene = context.scene
|
||||||
|
obj = context.object
|
||||||
|
|
||||||
|
print('\n\nimporting mdd %r' % filepath)
|
||||||
|
|
||||||
|
if bpy.ops.object.mode_set.poll():
|
||||||
|
bpy.ops.object.mode_set(mode='OBJECT')
|
||||||
|
|
||||||
|
file = open(filepath, 'rb')
|
||||||
|
frames, points = unpack(">2i", file.read(8))
|
||||||
|
time = unpack((">%df" % frames), file.read(frames * 4))
|
||||||
|
|
||||||
|
print('\tpoints:%d frames:%d' % (points, frames))
|
||||||
|
|
||||||
|
# If target object doesn't have Basis shape key, create it.
|
||||||
|
try:
|
||||||
|
num_keys = len(obj.data.shape_keys.keys)
|
||||||
|
except:
|
||||||
|
basis = obj.add_shape_key()
|
||||||
|
basis.name = "Basis"
|
||||||
|
obj.data.update()
|
||||||
|
|
||||||
|
scene.frame_current = frame_start
|
||||||
|
|
||||||
|
def UpdateMesh(ob, fr):
|
||||||
|
|
||||||
|
# Insert new shape key
|
||||||
|
new_shapekey = obj.add_shape_key()
|
||||||
|
new_shapekey.name = ("frame_%.4d" % fr)
|
||||||
|
new_shapekey_name = new_shapekey.name
|
||||||
|
|
||||||
|
obj.active_shape_key_index = len(obj.data.shape_keys.keys)-1
|
||||||
|
index = len(obj.data.shape_keys.keys)-1
|
||||||
|
obj.show_shape_key = True
|
||||||
|
|
||||||
|
verts = obj.data.shape_keys.keys[len(obj.data.shape_keys.keys)-1].data
|
||||||
|
|
||||||
|
|
||||||
|
for v in verts: # 12 is the size of 3 floats
|
||||||
|
v.co[:] = unpack('>3f', file.read(12))
|
||||||
|
#me.update()
|
||||||
|
obj.show_shape_key = False
|
||||||
|
|
||||||
|
|
||||||
|
# insert keyframes
|
||||||
|
shape_keys = obj.data.shape_keys
|
||||||
|
|
||||||
|
scene.frame_current -= 1
|
||||||
|
obj.data.shape_keys.keys[index].value = 0.0
|
||||||
|
shape_keys.keys[len(obj.data.shape_keys.keys)-1].keyframe_insert("value")
|
||||||
|
|
||||||
|
scene.frame_current += 1
|
||||||
|
obj.data.shape_keys.keys[index].value = 1.0
|
||||||
|
shape_keys.keys[len(obj.data.shape_keys.keys)-1].keyframe_insert("value")
|
||||||
|
|
||||||
|
scene.frame_current += 1
|
||||||
|
obj.data.shape_keys.keys[index].value = 0.0
|
||||||
|
shape_keys.keys[len(obj.data.shape_keys.keys)-1].keyframe_insert("value")
|
||||||
|
|
||||||
|
obj.data.update()
|
||||||
|
|
||||||
|
|
||||||
|
for i in range(frames):
|
||||||
|
UpdateMesh(obj, i)
|
||||||
|
|
||||||
|
return {'FINISHED'}
|
||||||
@@ -87,7 +87,7 @@ def bake(frame_start, frame_end, step=1, only_selected=False):
|
|||||||
|
|
||||||
# could spped this up by applying steps here too...
|
# could spped this up by applying steps here too...
|
||||||
for f in frame_range:
|
for f in frame_range:
|
||||||
scene.set_frame(f)
|
scene.frame_set(f)
|
||||||
|
|
||||||
info = pose_info()
|
info = pose_info()
|
||||||
info_ls.append(info)
|
info_ls.append(info)
|
||||||
@@ -169,7 +169,7 @@ class BakeAction(bpy.types.Operator):
|
|||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
def invoke(self, context, event):
|
def invoke(self, context, event):
|
||||||
wm = context.manager
|
wm = context.window_manager
|
||||||
return wm.invoke_props_dialog(self)
|
return wm.invoke_props_dialog(self)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ class SelectPattern(bpy.types.Operator):
|
|||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
def invoke(self, context, event):
|
def invoke(self, context, event):
|
||||||
wm = context.manager
|
wm = context.window_manager
|
||||||
# return wm.invoke_props_popup(self, event)
|
# return wm.invoke_props_popup(self, event)
|
||||||
wm.invoke_props_popup(self, event)
|
wm.invoke_props_popup(self, event)
|
||||||
return {'RUNNING_MODAL'}
|
return {'RUNNING_MODAL'}
|
||||||
@@ -573,4 +573,4 @@ def unregister():
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
register()
|
register()
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ class AddPresetBase():
|
|||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
def invoke(self, context, event):
|
def invoke(self, context, event):
|
||||||
wm = context.manager
|
wm = context.window_manager
|
||||||
#crashes, TODO - fix
|
#crashes, TODO - fix
|
||||||
#return wm.invoke_props_popup(self, event)
|
#return wm.invoke_props_popup(self, event)
|
||||||
|
|
||||||
|
|||||||
@@ -207,7 +207,7 @@ class ExportUVLayout(bpy.types.Operator):
|
|||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
def invoke(self, context, event):
|
def invoke(self, context, event):
|
||||||
wm = context.manager
|
wm = context.window_manager
|
||||||
wm.add_fileselect(self)
|
wm.add_fileselect(self)
|
||||||
return {'RUNNING_MODAL'}
|
return {'RUNNING_MODAL'}
|
||||||
|
|
||||||
|
|||||||
@@ -449,7 +449,7 @@ class WM_OT_context_modal_mouse(bpy.types.Operator):
|
|||||||
else:
|
else:
|
||||||
self.properties.initial_x = event.mouse_x
|
self.properties.initial_x = event.mouse_x
|
||||||
|
|
||||||
context.manager.add_modal_handler(self)
|
context.window_manager.add_modal_handler(self)
|
||||||
return {'RUNNING_MODAL'}
|
return {'RUNNING_MODAL'}
|
||||||
|
|
||||||
|
|
||||||
@@ -505,7 +505,7 @@ class WM_OT_doc_view(bpy.types.Operator):
|
|||||||
bl_label = "View Documentation"
|
bl_label = "View Documentation"
|
||||||
|
|
||||||
doc_id = doc_id
|
doc_id = doc_id
|
||||||
_prefix = 'http://www.blender.org/documentation/250PythonDoc'
|
_prefix = "http://www.blender.org/documentation/blender_python_api_%s" % "_".join(str(v) for v in bpy.app.version)
|
||||||
|
|
||||||
def _nested_class_string(self, class_string):
|
def _nested_class_string(self, class_string):
|
||||||
ls = []
|
ls = []
|
||||||
@@ -608,7 +608,7 @@ class WM_OT_doc_edit(bpy.types.Operator):
|
|||||||
layout.prop(props, "doc_new", text="")
|
layout.prop(props, "doc_new", text="")
|
||||||
|
|
||||||
def invoke(self, context, event):
|
def invoke(self, context, event):
|
||||||
wm = context.manager
|
wm = context.window_manager
|
||||||
return wm.invoke_props_dialog(self, width=600)
|
return wm.invoke_props_dialog(self, width=600)
|
||||||
|
|
||||||
|
|
||||||
@@ -692,7 +692,7 @@ class WM_OT_properties_edit(bpy.types.Operator):
|
|||||||
self.properties.max = prop_ui.get("max", 1000000000)
|
self.properties.max = prop_ui.get("max", 1000000000)
|
||||||
self.properties.description = prop_ui.get("description", "")
|
self.properties.description = prop_ui.get("description", "")
|
||||||
|
|
||||||
wm = context.manager
|
wm = context.window_manager
|
||||||
# This crashes, TODO - fix
|
# This crashes, TODO - fix
|
||||||
#return wm.invoke_props_popup(self, event)
|
#return wm.invoke_props_popup(self, event)
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# Configuration Blender
|
# Configuration Blender
|
||||||
import bpy
|
import bpy
|
||||||
|
|
||||||
wm = bpy.context.manager
|
wm = bpy.context.window_manager
|
||||||
wm.keyconfigs.active = wm.keyconfigs['Blender']
|
wm.keyconfigs.active = wm.keyconfigs['Blender']
|
||||||
|
|
||||||
bpy.context.user_preferences.view.use_mouse_auto_depth = False
|
bpy.context.user_preferences.view.use_mouse_auto_depth = False
|
||||||
|
|||||||
@@ -1,378 +1,378 @@
|
|||||||
# Configuration Maya
|
# Configuration Maya
|
||||||
import bpy
|
import bpy
|
||||||
|
|
||||||
wm = bpy.context.manager
|
wm = bpy.context.window_manager
|
||||||
kc = wm.add_keyconfig('Maya')
|
kc = wm.keyconfigs.new('Maya')
|
||||||
|
|
||||||
# Map 3D View
|
# Map 3D View
|
||||||
km = kc.add_keymap('3D View', space_type='VIEW_3D', region_type='WINDOW', modal=False)
|
km = kc.keymaps.new('3D View', space_type='VIEW_3D', region_type='WINDOW', modal=False)
|
||||||
|
|
||||||
kmi = km.items.add('view3d.manipulator', 'LEFTMOUSE', 'PRESS', any=True)
|
kmi = km.items.new('view3d.manipulator', 'LEFTMOUSE', 'PRESS', any=True)
|
||||||
kmi.properties.release_confirm = True
|
kmi.properties.release_confirm = True
|
||||||
kmi = km.items.add('view3d.cursor3d', 'ACTIONMOUSE', 'PRESS')
|
kmi = km.items.new('view3d.cursor3d', 'ACTIONMOUSE', 'PRESS')
|
||||||
kmi = km.items.add('view3d.rotate', 'LEFTMOUSE', 'PRESS', alt=True)
|
kmi = km.items.new('view3d.rotate', 'LEFTMOUSE', 'PRESS', alt=True)
|
||||||
kmi = km.items.add('view3d.move', 'MIDDLEMOUSE', 'PRESS', alt=True)
|
kmi = km.items.new('view3d.move', 'MIDDLEMOUSE', 'PRESS', alt=True)
|
||||||
kmi = km.items.add('view3d.zoom', 'RIGHTMOUSE', 'PRESS', alt=True)
|
kmi = km.items.new('view3d.zoom', 'RIGHTMOUSE', 'PRESS', alt=True)
|
||||||
kmi = km.items.add('view3d.view_selected', 'NUMPAD_PERIOD', 'PRESS')
|
kmi = km.items.new('view3d.view_selected', 'NUMPAD_PERIOD', 'PRESS')
|
||||||
kmi = km.items.add('view3d.view_center_cursor', 'NUMPAD_PERIOD', 'PRESS', ctrl=True)
|
kmi = km.items.new('view3d.view_center_cursor', 'NUMPAD_PERIOD', 'PRESS', ctrl=True)
|
||||||
kmi = km.items.add('view3d.fly', 'F', 'PRESS', shift=True)
|
kmi = km.items.new('view3d.fly', 'F', 'PRESS', shift=True)
|
||||||
kmi = km.items.add('view3d.smoothview', 'TIMER1', 'ANY', any=True)
|
kmi = km.items.new('view3d.smoothview', 'TIMER1', 'ANY', any=True)
|
||||||
kmi = km.items.add('view3d.rotate', 'TRACKPADPAN', 'ANY', alt=True)
|
kmi = km.items.new('view3d.rotate', 'TRACKPADPAN', 'ANY', alt=True)
|
||||||
kmi = km.items.add('view3d.rotate', 'MOUSEROTATE', 'ANY')
|
kmi = km.items.new('view3d.rotate', 'MOUSEROTATE', 'ANY')
|
||||||
kmi = km.items.add('view3d.move', 'TRACKPADPAN', 'ANY')
|
kmi = km.items.new('view3d.move', 'TRACKPADPAN', 'ANY')
|
||||||
kmi = km.items.add('view3d.zoom', 'TRACKPADZOOM', 'ANY')
|
kmi = km.items.new('view3d.zoom', 'TRACKPADZOOM', 'ANY')
|
||||||
kmi = km.items.add('view3d.zoom', 'NUMPAD_PLUS', 'PRESS')
|
kmi = km.items.new('view3d.zoom', 'NUMPAD_PLUS', 'PRESS')
|
||||||
kmi.properties.delta = 1
|
kmi.properties.delta = 1
|
||||||
kmi = km.items.add('view3d.zoom', 'NUMPAD_MINUS', 'PRESS')
|
kmi = km.items.new('view3d.zoom', 'NUMPAD_MINUS', 'PRESS')
|
||||||
kmi.properties.delta = -1
|
kmi.properties.delta = -1
|
||||||
kmi = km.items.add('view3d.zoom', 'EQUAL', 'PRESS', ctrl=True)
|
kmi = km.items.new('view3d.zoom', 'EQUAL', 'PRESS', ctrl=True)
|
||||||
kmi.properties.delta = 1
|
kmi.properties.delta = 1
|
||||||
kmi = km.items.add('view3d.zoom', 'MINUS', 'PRESS', ctrl=True)
|
kmi = km.items.new('view3d.zoom', 'MINUS', 'PRESS', ctrl=True)
|
||||||
kmi.properties.delta = -1
|
kmi.properties.delta = -1
|
||||||
kmi = km.items.add('view3d.zoom', 'WHEELINMOUSE', 'PRESS')
|
kmi = km.items.new('view3d.zoom', 'WHEELINMOUSE', 'PRESS')
|
||||||
kmi.properties.delta = 1
|
kmi.properties.delta = 1
|
||||||
kmi = km.items.add('view3d.zoom', 'WHEELOUTMOUSE', 'PRESS')
|
kmi = km.items.new('view3d.zoom', 'WHEELOUTMOUSE', 'PRESS')
|
||||||
kmi.properties.delta = -1
|
kmi.properties.delta = -1
|
||||||
kmi = km.items.add('view3d.view_all', 'HOME', 'PRESS')
|
kmi = km.items.new('view3d.view_all', 'HOME', 'PRESS')
|
||||||
kmi.properties.center = False
|
kmi.properties.center = False
|
||||||
kmi = km.items.add('view3d.view_all', 'C', 'PRESS', shift=True)
|
kmi = km.items.new('view3d.view_all', 'C', 'PRESS', shift=True)
|
||||||
kmi.properties.center = True
|
kmi.properties.center = True
|
||||||
kmi = km.items.add('view3d.viewnumpad', 'NUMPAD_0', 'PRESS')
|
kmi = km.items.new('view3d.viewnumpad', 'NUMPAD_0', 'PRESS')
|
||||||
kmi.properties.type = 'CAMERA'
|
kmi.properties.type = 'CAMERA'
|
||||||
kmi = km.items.add('view3d.viewnumpad', 'NUMPAD_1', 'PRESS')
|
kmi = km.items.new('view3d.viewnumpad', 'NUMPAD_1', 'PRESS')
|
||||||
kmi.properties.type = 'FRONT'
|
kmi.properties.type = 'FRONT'
|
||||||
kmi = km.items.add('view3d.view_orbit', 'NUMPAD_2', 'PRESS')
|
kmi = km.items.new('view3d.view_orbit', 'NUMPAD_2', 'PRESS')
|
||||||
kmi.properties.type = 'ORBITDOWN'
|
kmi.properties.type = 'ORBITDOWN'
|
||||||
kmi = km.items.add('view3d.viewnumpad', 'NUMPAD_3', 'PRESS')
|
kmi = km.items.new('view3d.viewnumpad', 'NUMPAD_3', 'PRESS')
|
||||||
kmi.properties.type = 'RIGHT'
|
kmi.properties.type = 'RIGHT'
|
||||||
kmi = km.items.add('view3d.view_orbit', 'NUMPAD_4', 'PRESS')
|
kmi = km.items.new('view3d.view_orbit', 'NUMPAD_4', 'PRESS')
|
||||||
kmi.properties.type = 'ORBITLEFT'
|
kmi.properties.type = 'ORBITLEFT'
|
||||||
kmi = km.items.add('view3d.view_persportho', 'NUMPAD_5', 'PRESS')
|
kmi = km.items.new('view3d.view_persportho', 'NUMPAD_5', 'PRESS')
|
||||||
kmi = km.items.add('view3d.view_orbit', 'NUMPAD_6', 'PRESS')
|
kmi = km.items.new('view3d.view_orbit', 'NUMPAD_6', 'PRESS')
|
||||||
kmi.properties.type = 'ORBITRIGHT'
|
kmi.properties.type = 'ORBITRIGHT'
|
||||||
kmi = km.items.add('view3d.viewnumpad', 'NUMPAD_7', 'PRESS')
|
kmi = km.items.new('view3d.viewnumpad', 'NUMPAD_7', 'PRESS')
|
||||||
kmi.properties.type = 'TOP'
|
kmi.properties.type = 'TOP'
|
||||||
kmi = km.items.add('view3d.view_orbit', 'NUMPAD_8', 'PRESS')
|
kmi = km.items.new('view3d.view_orbit', 'NUMPAD_8', 'PRESS')
|
||||||
kmi.properties.type = 'ORBITUP'
|
kmi.properties.type = 'ORBITUP'
|
||||||
kmi = km.items.add('view3d.viewnumpad', 'NUMPAD_1', 'PRESS', ctrl=True)
|
kmi = km.items.new('view3d.viewnumpad', 'NUMPAD_1', 'PRESS', ctrl=True)
|
||||||
kmi.properties.type = 'BACK'
|
kmi.properties.type = 'BACK'
|
||||||
kmi = km.items.add('view3d.viewnumpad', 'NUMPAD_3', 'PRESS', ctrl=True)
|
kmi = km.items.new('view3d.viewnumpad', 'NUMPAD_3', 'PRESS', ctrl=True)
|
||||||
kmi.properties.type = 'LEFT'
|
kmi.properties.type = 'LEFT'
|
||||||
kmi = km.items.add('view3d.viewnumpad', 'NUMPAD_7', 'PRESS', ctrl=True)
|
kmi = km.items.new('view3d.viewnumpad', 'NUMPAD_7', 'PRESS', ctrl=True)
|
||||||
kmi.properties.type = 'BOTTOM'
|
kmi.properties.type = 'BOTTOM'
|
||||||
kmi = km.items.add('view3d.view_pan', 'NUMPAD_2', 'PRESS', ctrl=True)
|
kmi = km.items.new('view3d.view_pan', 'NUMPAD_2', 'PRESS', ctrl=True)
|
||||||
kmi.properties.type = 'PANDOWN'
|
kmi.properties.type = 'PANDOWN'
|
||||||
kmi = km.items.add('view3d.view_pan', 'NUMPAD_4', 'PRESS', ctrl=True)
|
kmi = km.items.new('view3d.view_pan', 'NUMPAD_4', 'PRESS', ctrl=True)
|
||||||
kmi.properties.type = 'PANLEFT'
|
kmi.properties.type = 'PANLEFT'
|
||||||
kmi = km.items.add('view3d.view_pan', 'NUMPAD_6', 'PRESS', ctrl=True)
|
kmi = km.items.new('view3d.view_pan', 'NUMPAD_6', 'PRESS', ctrl=True)
|
||||||
kmi.properties.type = 'PANRIGHT'
|
kmi.properties.type = 'PANRIGHT'
|
||||||
kmi = km.items.add('view3d.view_pan', 'NUMPAD_8', 'PRESS', ctrl=True)
|
kmi = km.items.new('view3d.view_pan', 'NUMPAD_8', 'PRESS', ctrl=True)
|
||||||
kmi.properties.type = 'PANUP'
|
kmi.properties.type = 'PANUP'
|
||||||
kmi = km.items.add('view3d.view_pan', 'WHEELUPMOUSE', 'PRESS', ctrl=True)
|
kmi = km.items.new('view3d.view_pan', 'WHEELUPMOUSE', 'PRESS', ctrl=True)
|
||||||
kmi.properties.type = 'PANRIGHT'
|
kmi.properties.type = 'PANRIGHT'
|
||||||
kmi = km.items.add('view3d.view_pan', 'WHEELDOWNMOUSE', 'PRESS', ctrl=True)
|
kmi = km.items.new('view3d.view_pan', 'WHEELDOWNMOUSE', 'PRESS', ctrl=True)
|
||||||
kmi.properties.type = 'PANLEFT'
|
kmi.properties.type = 'PANLEFT'
|
||||||
kmi = km.items.add('view3d.view_pan', 'WHEELUPMOUSE', 'PRESS', shift=True)
|
kmi = km.items.new('view3d.view_pan', 'WHEELUPMOUSE', 'PRESS', shift=True)
|
||||||
kmi.properties.type = 'PANUP'
|
kmi.properties.type = 'PANUP'
|
||||||
kmi = km.items.add('view3d.view_pan', 'WHEELDOWNMOUSE', 'PRESS', shift=True)
|
kmi = km.items.new('view3d.view_pan', 'WHEELDOWNMOUSE', 'PRESS', shift=True)
|
||||||
kmi.properties.type = 'PANDOWN'
|
kmi.properties.type = 'PANDOWN'
|
||||||
kmi = km.items.add('view3d.view_orbit', 'WHEELUPMOUSE', 'PRESS', ctrl=True, alt=True)
|
kmi = km.items.new('view3d.view_orbit', 'WHEELUPMOUSE', 'PRESS', ctrl=True, alt=True)
|
||||||
kmi.properties.type = 'ORBITLEFT'
|
kmi.properties.type = 'ORBITLEFT'
|
||||||
kmi = km.items.add('view3d.view_orbit', 'WHEELDOWNMOUSE', 'PRESS', ctrl=True, alt=True)
|
kmi = km.items.new('view3d.view_orbit', 'WHEELDOWNMOUSE', 'PRESS', ctrl=True, alt=True)
|
||||||
kmi.properties.type = 'ORBITRIGHT'
|
kmi.properties.type = 'ORBITRIGHT'
|
||||||
kmi = km.items.add('view3d.view_orbit', 'WHEELUPMOUSE', 'PRESS', shift=True, alt=True)
|
kmi = km.items.new('view3d.view_orbit', 'WHEELUPMOUSE', 'PRESS', shift=True, alt=True)
|
||||||
kmi.properties.type = 'ORBITUP'
|
kmi.properties.type = 'ORBITUP'
|
||||||
kmi = km.items.add('view3d.view_orbit', 'WHEELDOWNMOUSE', 'PRESS', shift=True, alt=True)
|
kmi = km.items.new('view3d.view_orbit', 'WHEELDOWNMOUSE', 'PRESS', shift=True, alt=True)
|
||||||
kmi.properties.type = 'ORBITDOWN'
|
kmi.properties.type = 'ORBITDOWN'
|
||||||
kmi = km.items.add('view3d.viewnumpad', 'NUMPAD_1', 'PRESS', shift=True)
|
kmi = km.items.new('view3d.viewnumpad', 'NUMPAD_1', 'PRESS', shift=True)
|
||||||
kmi.properties.align_active = True
|
kmi.properties.align_active = True
|
||||||
kmi.properties.type = 'FRONT'
|
kmi.properties.type = 'FRONT'
|
||||||
kmi = km.items.add('view3d.viewnumpad', 'NUMPAD_3', 'PRESS', shift=True)
|
kmi = km.items.new('view3d.viewnumpad', 'NUMPAD_3', 'PRESS', shift=True)
|
||||||
kmi.properties.align_active = True
|
kmi.properties.align_active = True
|
||||||
kmi.properties.type = 'RIGHT'
|
kmi.properties.type = 'RIGHT'
|
||||||
kmi = km.items.add('view3d.viewnumpad', 'NUMPAD_7', 'PRESS', shift=True)
|
kmi = km.items.new('view3d.viewnumpad', 'NUMPAD_7', 'PRESS', shift=True)
|
||||||
kmi.properties.align_active = True
|
kmi.properties.align_active = True
|
||||||
kmi.properties.type = 'TOP'
|
kmi.properties.type = 'TOP'
|
||||||
kmi = km.items.add('view3d.viewnumpad', 'NUMPAD_1', 'PRESS', shift=True, ctrl=True)
|
kmi = km.items.new('view3d.viewnumpad', 'NUMPAD_1', 'PRESS', shift=True, ctrl=True)
|
||||||
kmi.properties.align_active = True
|
kmi.properties.align_active = True
|
||||||
kmi.properties.type = 'BACK'
|
kmi.properties.type = 'BACK'
|
||||||
kmi = km.items.add('view3d.viewnumpad', 'NUMPAD_3', 'PRESS', shift=True, ctrl=True)
|
kmi = km.items.new('view3d.viewnumpad', 'NUMPAD_3', 'PRESS', shift=True, ctrl=True)
|
||||||
kmi.properties.align_active = True
|
kmi.properties.align_active = True
|
||||||
kmi.properties.type = 'LEFT'
|
kmi.properties.type = 'LEFT'
|
||||||
kmi = km.items.add('view3d.viewnumpad', 'NUMPAD_7', 'PRESS', shift=True, ctrl=True)
|
kmi = km.items.new('view3d.viewnumpad', 'NUMPAD_7', 'PRESS', shift=True, ctrl=True)
|
||||||
kmi.properties.align_active = True
|
kmi.properties.align_active = True
|
||||||
kmi.properties.type = 'BOTTOM'
|
kmi.properties.type = 'BOTTOM'
|
||||||
kmi = km.items.add('view3d.localview', 'NUMPAD_SLASH', 'PRESS')
|
kmi = km.items.new('view3d.localview', 'NUMPAD_SLASH', 'PRESS')
|
||||||
kmi = km.items.add('view3d.layers', 'ACCENT_GRAVE', 'PRESS')
|
kmi = km.items.new('view3d.layers', 'ACCENT_GRAVE', 'PRESS')
|
||||||
kmi.properties.nr = 0
|
kmi.properties.nr = 0
|
||||||
kmi = km.items.add('view3d.layers', 'ONE', 'PRESS', any=True)
|
kmi = km.items.new('view3d.layers', 'ONE', 'PRESS', any=True)
|
||||||
kmi.properties.nr = 1
|
kmi.properties.nr = 1
|
||||||
kmi = km.items.add('view3d.layers', 'TWO', 'PRESS', any=True)
|
kmi = km.items.new('view3d.layers', 'TWO', 'PRESS', any=True)
|
||||||
kmi.properties.nr = 2
|
kmi.properties.nr = 2
|
||||||
kmi = km.items.add('view3d.layers', 'THREE', 'PRESS', any=True)
|
kmi = km.items.new('view3d.layers', 'THREE', 'PRESS', any=True)
|
||||||
kmi.properties.nr = 3
|
kmi.properties.nr = 3
|
||||||
kmi = km.items.add('view3d.layers', 'FOUR', 'PRESS', any=True)
|
kmi = km.items.new('view3d.layers', 'FOUR', 'PRESS', any=True)
|
||||||
kmi.properties.nr = 4
|
kmi.properties.nr = 4
|
||||||
kmi = km.items.add('view3d.layers', 'FIVE', 'PRESS', any=True)
|
kmi = km.items.new('view3d.layers', 'FIVE', 'PRESS', any=True)
|
||||||
kmi.properties.nr = 5
|
kmi.properties.nr = 5
|
||||||
kmi = km.items.add('view3d.layers', 'SIX', 'PRESS', any=True)
|
kmi = km.items.new('view3d.layers', 'SIX', 'PRESS', any=True)
|
||||||
kmi.properties.nr = 6
|
kmi.properties.nr = 6
|
||||||
kmi = km.items.add('view3d.layers', 'SEVEN', 'PRESS', any=True)
|
kmi = km.items.new('view3d.layers', 'SEVEN', 'PRESS', any=True)
|
||||||
kmi.properties.nr = 7
|
kmi.properties.nr = 7
|
||||||
kmi = km.items.add('view3d.layers', 'EIGHT', 'PRESS', any=True)
|
kmi = km.items.new('view3d.layers', 'EIGHT', 'PRESS', any=True)
|
||||||
kmi.properties.nr = 8
|
kmi.properties.nr = 8
|
||||||
kmi = km.items.add('view3d.layers', 'NINE', 'PRESS', any=True)
|
kmi = km.items.new('view3d.layers', 'NINE', 'PRESS', any=True)
|
||||||
kmi.properties.nr = 9
|
kmi.properties.nr = 9
|
||||||
kmi = km.items.add('view3d.layers', 'ZERO', 'PRESS', any=True)
|
kmi = km.items.new('view3d.layers', 'ZERO', 'PRESS', any=True)
|
||||||
kmi.properties.nr = 10
|
kmi.properties.nr = 10
|
||||||
kmi = km.items.add('wm.context_toggle_enum', 'Z', 'PRESS')
|
kmi = km.items.new('wm.context_toggle_enum', 'Z', 'PRESS')
|
||||||
kmi.properties.data_path = 'space_data.viewport_shade'
|
kmi.properties.data_path = 'space_data.viewport_shade'
|
||||||
kmi.properties.value_1 = 'SOLID'
|
kmi.properties.value_1 = 'SOLID'
|
||||||
kmi.properties.value_2 = 'WIREFRAME'
|
kmi.properties.value_2 = 'WIREFRAME'
|
||||||
kmi = km.items.add('wm.context_toggle_enum', 'Z', 'PRESS', alt=True)
|
kmi = km.items.new('wm.context_toggle_enum', 'Z', 'PRESS', alt=True)
|
||||||
kmi.properties.data_path = 'space_data.viewport_shade'
|
kmi.properties.data_path = 'space_data.viewport_shade'
|
||||||
kmi.properties.value_1 = 'TEXTURED'
|
kmi.properties.value_1 = 'TEXTURED'
|
||||||
kmi.properties.value_2 = 'SOLID'
|
kmi.properties.value_2 = 'SOLID'
|
||||||
kmi = km.items.add('view3d.select', 'SELECTMOUSE', 'PRESS')
|
kmi = km.items.new('view3d.select', 'SELECTMOUSE', 'PRESS')
|
||||||
kmi = km.items.add('view3d.select', 'SELECTMOUSE', 'PRESS', shift=True)
|
kmi = km.items.new('view3d.select', 'SELECTMOUSE', 'PRESS', shift=True)
|
||||||
kmi.properties.extend = True
|
kmi.properties.extend = True
|
||||||
kmi = km.items.add('view3d.select', 'SELECTMOUSE', 'PRESS', ctrl=True)
|
kmi = km.items.new('view3d.select', 'SELECTMOUSE', 'PRESS', ctrl=True)
|
||||||
kmi.properties.center = True
|
kmi.properties.center = True
|
||||||
kmi = km.items.add('view3d.select', 'SELECTMOUSE', 'PRESS', alt=True)
|
kmi = km.items.new('view3d.select', 'SELECTMOUSE', 'PRESS', alt=True)
|
||||||
kmi.properties.enumerate = True
|
kmi.properties.enumerate = True
|
||||||
kmi = km.items.add('view3d.select', 'SELECTMOUSE', 'PRESS', shift=True, ctrl=True)
|
kmi = km.items.new('view3d.select', 'SELECTMOUSE', 'PRESS', shift=True, ctrl=True)
|
||||||
kmi.properties.center = True
|
kmi.properties.center = True
|
||||||
kmi.properties.extend = True
|
kmi.properties.extend = True
|
||||||
kmi = km.items.add('view3d.select', 'SELECTMOUSE', 'PRESS', ctrl=True, alt=True)
|
kmi = km.items.new('view3d.select', 'SELECTMOUSE', 'PRESS', ctrl=True, alt=True)
|
||||||
kmi.properties.center = True
|
kmi.properties.center = True
|
||||||
kmi.properties.enumerate = True
|
kmi.properties.enumerate = True
|
||||||
kmi = km.items.add('view3d.select', 'SELECTMOUSE', 'PRESS', shift=True, alt=True)
|
kmi = km.items.new('view3d.select', 'SELECTMOUSE', 'PRESS', shift=True, alt=True)
|
||||||
kmi.properties.enumerate = True
|
kmi.properties.enumerate = True
|
||||||
kmi.properties.extend = True
|
kmi.properties.extend = True
|
||||||
kmi = km.items.add('view3d.select', 'SELECTMOUSE', 'PRESS', shift=True, ctrl=True, alt=True)
|
kmi = km.items.new('view3d.select', 'SELECTMOUSE', 'PRESS', shift=True, ctrl=True, alt=True)
|
||||||
kmi.properties.center = True
|
kmi.properties.center = True
|
||||||
kmi.properties.enumerate = True
|
kmi.properties.enumerate = True
|
||||||
kmi.properties.extend = True
|
kmi.properties.extend = True
|
||||||
kmi = km.items.add('view3d.select_border', 'EVT_TWEAK_S', 'ANY')
|
kmi = km.items.new('view3d.select_border', 'EVT_TWEAK_S', 'ANY')
|
||||||
kmi.properties.extend = False
|
kmi.properties.extend = False
|
||||||
kmi = km.items.add('view3d.select_lasso', 'EVT_TWEAK_A', 'ANY', ctrl=True)
|
kmi = km.items.new('view3d.select_lasso', 'EVT_TWEAK_A', 'ANY', ctrl=True)
|
||||||
kmi = km.items.add('view3d.select_lasso', 'EVT_TWEAK_A', 'ANY', shift=True, ctrl=True)
|
kmi = km.items.new('view3d.select_lasso', 'EVT_TWEAK_A', 'ANY', shift=True, ctrl=True)
|
||||||
kmi.properties.deselect = True
|
kmi.properties.deselect = True
|
||||||
kmi = km.items.add('view3d.select_circle', 'C', 'PRESS')
|
kmi = km.items.new('view3d.select_circle', 'C', 'PRESS')
|
||||||
kmi = km.items.add('view3d.clip_border', 'B', 'PRESS', alt=True)
|
kmi = km.items.new('view3d.clip_border', 'B', 'PRESS', alt=True)
|
||||||
kmi = km.items.add('view3d.zoom_border', 'B', 'PRESS', shift=True)
|
kmi = km.items.new('view3d.zoom_border', 'B', 'PRESS', shift=True)
|
||||||
kmi = km.items.add('view3d.render_border', 'B', 'PRESS', shift=True)
|
kmi = km.items.new('view3d.render_border', 'B', 'PRESS', shift=True)
|
||||||
kmi = km.items.add('view3d.camera_to_view', 'NUMPAD_0', 'PRESS', ctrl=True, alt=True)
|
kmi = km.items.new('view3d.camera_to_view', 'NUMPAD_0', 'PRESS', ctrl=True, alt=True)
|
||||||
kmi = km.items.add('view3d.object_as_camera', 'NUMPAD_0', 'PRESS', ctrl=True)
|
kmi = km.items.new('view3d.object_as_camera', 'NUMPAD_0', 'PRESS', ctrl=True)
|
||||||
kmi = km.items.add('wm.call_menu', 'S', 'PRESS', shift=True)
|
kmi = km.items.new('wm.call_menu', 'S', 'PRESS', shift=True)
|
||||||
kmi.properties.name = 'VIEW3D_MT_snap'
|
kmi.properties.name = 'VIEW3D_MT_snap'
|
||||||
kmi = km.items.add('wm.context_set_enum', 'COMMA', 'PRESS')
|
kmi = km.items.new('wm.context_set_enum', 'COMMA', 'PRESS')
|
||||||
kmi.properties.data_path = 'space_data.pivot_point'
|
kmi.properties.data_path = 'space_data.pivot_point'
|
||||||
kmi.properties.value = 'BOUNDING_BOX_CENTER'
|
kmi.properties.value = 'BOUNDING_BOX_CENTER'
|
||||||
kmi = km.items.add('wm.context_set_enum', 'COMMA', 'PRESS', ctrl=True)
|
kmi = km.items.new('wm.context_set_enum', 'COMMA', 'PRESS', ctrl=True)
|
||||||
kmi.properties.data_path = 'space_data.pivot_point'
|
kmi.properties.data_path = 'space_data.pivot_point'
|
||||||
kmi.properties.value = 'MEDIAN_POINT'
|
kmi.properties.value = 'MEDIAN_POINT'
|
||||||
kmi = km.items.add('wm.context_toggle', 'COMMA', 'PRESS', alt=True)
|
kmi = km.items.new('wm.context_toggle', 'COMMA', 'PRESS', alt=True)
|
||||||
kmi.properties.data_path = 'space_data.use_pivot_point_align'
|
kmi.properties.data_path = 'space_data.use_pivot_point_align'
|
||||||
kmi = km.items.add('wm.context_toggle', 'Q', 'PRESS')
|
kmi = km.items.new('wm.context_toggle', 'Q', 'PRESS')
|
||||||
kmi.properties.data_path = 'space_data.show_manipulator'
|
kmi.properties.data_path = 'space_data.show_manipulator'
|
||||||
kmi = km.items.add('wm.context_set_enum', 'PERIOD', 'PRESS')
|
kmi = km.items.new('wm.context_set_enum', 'PERIOD', 'PRESS')
|
||||||
kmi.properties.data_path = 'space_data.pivot_point'
|
kmi.properties.data_path = 'space_data.pivot_point'
|
||||||
kmi.properties.value = 'CURSOR'
|
kmi.properties.value = 'CURSOR'
|
||||||
kmi = km.items.add('wm.context_set_enum', 'PERIOD', 'PRESS', ctrl=True)
|
kmi = km.items.new('wm.context_set_enum', 'PERIOD', 'PRESS', ctrl=True)
|
||||||
kmi.properties.data_path = 'space_data.pivot_point'
|
kmi.properties.data_path = 'space_data.pivot_point'
|
||||||
kmi.properties.value = 'INDIVIDUAL_ORIGINS'
|
kmi.properties.value = 'INDIVIDUAL_ORIGINS'
|
||||||
kmi = km.items.add('wm.context_set_enum', 'PERIOD', 'PRESS', alt=True)
|
kmi = km.items.new('wm.context_set_enum', 'PERIOD', 'PRESS', alt=True)
|
||||||
kmi.properties.data_path = 'space_data.pivot_point'
|
kmi.properties.data_path = 'space_data.pivot_point'
|
||||||
kmi.properties.value = 'ACTIVE_ELEMENT'
|
kmi.properties.value = 'ACTIVE_ELEMENT'
|
||||||
kmi = km.items.add('transform.translate', 'G', 'PRESS', shift=True)
|
kmi = km.items.new('transform.translate', 'G', 'PRESS', shift=True)
|
||||||
kmi = km.items.add('transform.translate', 'EVT_TWEAK_S', 'ANY')
|
kmi = km.items.new('transform.translate', 'EVT_TWEAK_S', 'ANY')
|
||||||
kmi = km.items.add('transform.rotate', 'R', 'PRESS', shift=True)
|
kmi = km.items.new('transform.rotate', 'R', 'PRESS', shift=True)
|
||||||
kmi = km.items.add('transform.resize', 'S', 'PRESS', shift=True)
|
kmi = km.items.new('transform.resize', 'S', 'PRESS', shift=True)
|
||||||
kmi = km.items.add('transform.warp', 'W', 'PRESS', shift=True)
|
kmi = km.items.new('transform.warp', 'W', 'PRESS', shift=True)
|
||||||
kmi = km.items.add('transform.tosphere', 'S', 'PRESS', shift=True, alt=True)
|
kmi = km.items.new('transform.tosphere', 'S', 'PRESS', shift=True, alt=True)
|
||||||
kmi = km.items.add('transform.shear', 'S', 'PRESS', shift=True, ctrl=True, alt=True)
|
kmi = km.items.new('transform.shear', 'S', 'PRESS', shift=True, ctrl=True, alt=True)
|
||||||
kmi = km.items.add('transform.select_orientation', 'SPACE', 'PRESS', alt=True)
|
kmi = km.items.new('transform.select_orientation', 'SPACE', 'PRESS', alt=True)
|
||||||
kmi = km.items.add('transform.create_orientation', 'SPACE', 'PRESS', ctrl=True, alt=True)
|
kmi = km.items.new('transform.create_orientation', 'SPACE', 'PRESS', ctrl=True, alt=True)
|
||||||
kmi.properties.use = True
|
kmi.properties.use = True
|
||||||
kmi = km.items.add('transform.mirror', 'M', 'PRESS', ctrl=True)
|
kmi = km.items.new('transform.mirror', 'M', 'PRESS', ctrl=True)
|
||||||
kmi = km.items.add('wm.context_toggle', 'TAB', 'PRESS', shift=True)
|
kmi = km.items.new('wm.context_toggle', 'TAB', 'PRESS', shift=True)
|
||||||
kmi.properties.data_path = 'tool_settings.snap'
|
kmi.properties.data_path = 'tool_settings.use_snap'
|
||||||
kmi = km.items.add('transform.snap_type', 'TAB', 'PRESS', shift=True, ctrl=True)
|
kmi = km.items.new('transform.snap_type', 'TAB', 'PRESS', shift=True, ctrl=True)
|
||||||
kmi = km.items.add('view3d.enable_manipulator', 'W', 'PRESS')
|
kmi = km.items.new('view3d.enable_manipulator', 'W', 'PRESS')
|
||||||
kmi.properties.translate = True
|
kmi.properties.translate = True
|
||||||
kmi = km.items.add('view3d.enable_manipulator', 'E', 'PRESS')
|
kmi = km.items.new('view3d.enable_manipulator', 'E', 'PRESS')
|
||||||
kmi.properties.rotate = True
|
kmi.properties.rotate = True
|
||||||
kmi = km.items.add('view3d.enable_manipulator', 'R', 'PRESS')
|
kmi = km.items.new('view3d.enable_manipulator', 'R', 'PRESS')
|
||||||
kmi.properties.scale = True
|
kmi.properties.scale = True
|
||||||
kmi = km.items.add('view3d.select_border', 'EVT_TWEAK_S', 'ANY', shift=True)
|
kmi = km.items.new('view3d.select_border', 'EVT_TWEAK_S', 'ANY', shift=True)
|
||||||
kmi.properties.extend = True
|
kmi.properties.extend = True
|
||||||
|
|
||||||
# Map Object Mode
|
# Map Object Mode
|
||||||
km = kc.add_keymap('Object Mode', space_type='EMPTY', region_type='WINDOW', modal=False)
|
km = kc.keymaps.new('Object Mode', space_type='EMPTY', region_type='WINDOW', modal=False)
|
||||||
|
|
||||||
kmi = km.items.add('wm.context_cycle_enum', 'O', 'PRESS', shift=True)
|
kmi = km.items.new('wm.context_cycle_enum', 'O', 'PRESS', shift=True)
|
||||||
kmi.properties.data_path = 'tool_settings.proportional_edit_falloff'
|
kmi.properties.data_path = 'tool_settings.proportional_edit_falloff'
|
||||||
kmi = km.items.add('wm.context_toggle_enum', 'O', 'PRESS')
|
kmi = km.items.new('wm.context_toggle_enum', 'O', 'PRESS')
|
||||||
kmi.properties.data_path = 'tool_settings.proportional_edit'
|
kmi.properties.data_path = 'tool_settings.proportional_edit'
|
||||||
kmi.properties.value_1 = 'DISABLED'
|
kmi.properties.value_1 = 'DISABLED'
|
||||||
kmi.properties.value_2 = 'ENABLED'
|
kmi.properties.value_2 = 'ENABLED'
|
||||||
kmi = km.items.add('view3d.game_start', 'P', 'PRESS')
|
kmi = km.items.new('view3d.game_start', 'P', 'PRESS')
|
||||||
kmi = km.items.add('object.select_all', 'A', 'PRESS')
|
kmi = km.items.new('object.select_all', 'A', 'PRESS')
|
||||||
kmi = km.items.add('object.select_inverse', 'I', 'PRESS', ctrl=True)
|
kmi = km.items.new('object.select_inverse', 'I', 'PRESS', ctrl=True)
|
||||||
kmi = km.items.add('object.select_linked', 'L', 'PRESS', shift=True)
|
kmi = km.items.new('object.select_linked', 'L', 'PRESS', shift=True)
|
||||||
kmi = km.items.add('object.select_grouped', 'G', 'PRESS', shift=True)
|
kmi = km.items.new('object.select_grouped', 'G', 'PRESS', shift=True)
|
||||||
kmi = km.items.add('object.select_mirror', 'M', 'PRESS', shift=True, ctrl=True)
|
kmi = km.items.new('object.select_mirror', 'M', 'PRESS', shift=True, ctrl=True)
|
||||||
kmi = km.items.add('object.select_hierarchy', 'LEFT_BRACKET', 'PRESS')
|
kmi = km.items.new('object.select_hierarchy', 'LEFT_BRACKET', 'PRESS')
|
||||||
kmi.properties.direction = 'PARENT'
|
kmi.properties.direction = 'PARENT'
|
||||||
kmi = km.items.add('object.select_hierarchy', 'LEFT_BRACKET', 'PRESS', shift=True)
|
kmi = km.items.new('object.select_hierarchy', 'LEFT_BRACKET', 'PRESS', shift=True)
|
||||||
kmi.properties.direction = 'PARENT'
|
kmi.properties.direction = 'PARENT'
|
||||||
kmi.properties.extend = True
|
kmi.properties.extend = True
|
||||||
kmi = km.items.add('object.select_hierarchy', 'RIGHT_BRACKET', 'PRESS')
|
kmi = km.items.new('object.select_hierarchy', 'RIGHT_BRACKET', 'PRESS')
|
||||||
kmi.properties.direction = 'CHILD'
|
kmi.properties.direction = 'CHILD'
|
||||||
kmi = km.items.add('object.select_hierarchy', 'RIGHT_BRACKET', 'PRESS', shift=True)
|
kmi = km.items.new('object.select_hierarchy', 'RIGHT_BRACKET', 'PRESS', shift=True)
|
||||||
kmi.properties.direction = 'CHILD'
|
kmi.properties.direction = 'CHILD'
|
||||||
kmi.properties.extend = True
|
kmi.properties.extend = True
|
||||||
kmi = km.items.add('object.parent_set', 'P', 'PRESS', ctrl=True)
|
kmi = km.items.new('object.parent_set', 'P', 'PRESS', ctrl=True)
|
||||||
kmi = km.items.add('object.parent_no_inverse_set', 'P', 'PRESS', shift=True, ctrl=True)
|
kmi = km.items.new('object.parent_no_inverse_set', 'P', 'PRESS', shift=True, ctrl=True)
|
||||||
kmi = km.items.add('object.parent_clear', 'P', 'PRESS', alt=True)
|
kmi = km.items.new('object.parent_clear', 'P', 'PRESS', alt=True)
|
||||||
kmi = km.items.add('object.track_set', 'T', 'PRESS', ctrl=True)
|
kmi = km.items.new('object.track_set', 'T', 'PRESS', ctrl=True)
|
||||||
kmi = km.items.add('object.track_clear', 'T', 'PRESS', alt=True)
|
kmi = km.items.new('object.track_clear', 'T', 'PRESS', alt=True)
|
||||||
kmi = km.items.add('object.constraint_add_with_targets', 'C', 'PRESS', shift=True, ctrl=True)
|
kmi = km.items.new('object.constraint_add_with_targets', 'C', 'PRESS', shift=True, ctrl=True)
|
||||||
kmi = km.items.add('object.constraints_clear', 'C', 'PRESS', ctrl=True, alt=True)
|
kmi = km.items.new('object.constraints_clear', 'C', 'PRESS', ctrl=True, alt=True)
|
||||||
kmi = km.items.add('object.location_clear', 'G', 'PRESS', alt=True)
|
kmi = km.items.new('object.location_clear', 'G', 'PRESS', alt=True)
|
||||||
kmi = km.items.add('object.rotation_clear', 'R', 'PRESS', alt=True)
|
kmi = km.items.new('object.rotation_clear', 'R', 'PRESS', alt=True)
|
||||||
kmi = km.items.add('object.scale_clear', 'S', 'PRESS', alt=True)
|
kmi = km.items.new('object.scale_clear', 'S', 'PRESS', alt=True)
|
||||||
kmi = km.items.add('object.origin_clear', 'O', 'PRESS', alt=True)
|
kmi = km.items.new('object.origin_clear', 'O', 'PRESS', alt=True)
|
||||||
kmi = km.items.add('object.hide_view_clear', 'H', 'PRESS', alt=True)
|
kmi = km.items.new('object.hide_view_clear', 'H', 'PRESS', alt=True)
|
||||||
kmi = km.items.add('object.hide_view_set', 'H', 'PRESS')
|
kmi = km.items.new('object.hide_view_set', 'H', 'PRESS')
|
||||||
kmi = km.items.add('object.hide_view_set', 'H', 'PRESS', shift=True)
|
kmi = km.items.new('object.hide_view_set', 'H', 'PRESS', shift=True)
|
||||||
kmi.properties.unselected = True
|
kmi.properties.unselected = True
|
||||||
kmi = km.items.add('object.move_to_layer', 'M', 'PRESS')
|
kmi = km.items.new('object.move_to_layer', 'M', 'PRESS')
|
||||||
kmi = km.items.add('object.delete', 'X', 'PRESS')
|
kmi = km.items.new('object.delete', 'X', 'PRESS')
|
||||||
kmi = km.items.add('object.delete', 'DEL', 'PRESS')
|
kmi = km.items.new('object.delete', 'DEL', 'PRESS')
|
||||||
kmi = km.items.add('wm.call_menu', 'A', 'PRESS', shift=True)
|
kmi = km.items.new('wm.call_menu', 'A', 'PRESS', shift=True)
|
||||||
kmi.properties.name = 'INFO_MT_add'
|
kmi.properties.name = 'INFO_MT_add'
|
||||||
kmi = km.items.add('object.duplicates_make_real', 'A', 'PRESS', shift=True, ctrl=True)
|
kmi = km.items.new('object.duplicates_make_real', 'A', 'PRESS', shift=True, ctrl=True)
|
||||||
kmi = km.items.add('wm.call_menu', 'A', 'PRESS', ctrl=True)
|
kmi = km.items.new('wm.call_menu', 'A', 'PRESS', ctrl=True)
|
||||||
kmi.properties.name = 'VIEW3D_MT_object_apply'
|
kmi.properties.name = 'VIEW3D_MT_object_apply'
|
||||||
kmi = km.items.add('wm.call_menu', 'U', 'PRESS')
|
kmi = km.items.new('wm.call_menu', 'U', 'PRESS')
|
||||||
kmi.properties.name = 'VIEW3D_MT_make_single_user'
|
kmi.properties.name = 'VIEW3D_MT_make_single_user'
|
||||||
kmi = km.items.add('wm.call_menu', 'L', 'PRESS', ctrl=True)
|
kmi = km.items.new('wm.call_menu', 'L', 'PRESS', ctrl=True)
|
||||||
kmi.properties.name = 'VIEW3D_MT_make_links'
|
kmi.properties.name = 'VIEW3D_MT_make_links'
|
||||||
kmi = km.items.add('object.duplicate_move', 'D', 'PRESS', shift=True)
|
kmi = km.items.new('object.duplicate_move', 'D', 'PRESS', shift=True)
|
||||||
kmi = km.items.add('object.duplicate_move_linked', 'D', 'PRESS', alt=True)
|
kmi = km.items.new('object.duplicate_move_linked', 'D', 'PRESS', alt=True)
|
||||||
kmi = km.items.add('object.join', 'J', 'PRESS', ctrl=True)
|
kmi = km.items.new('object.join', 'J', 'PRESS', ctrl=True)
|
||||||
kmi = km.items.add('object.convert', 'C', 'PRESS', alt=True)
|
kmi = km.items.new('object.convert', 'C', 'PRESS', alt=True)
|
||||||
kmi = km.items.add('object.proxy_make', 'P', 'PRESS', ctrl=True, alt=True)
|
kmi = km.items.new('object.proxy_make', 'P', 'PRESS', ctrl=True, alt=True)
|
||||||
kmi = km.items.add('object.make_local', 'L', 'PRESS')
|
kmi = km.items.new('object.make_local', 'L', 'PRESS')
|
||||||
kmi = km.items.add('anim.keyframe_insert_menu', 'I', 'PRESS')
|
kmi = km.items.new('anim.keyframe_insert_menu', 'I', 'PRESS')
|
||||||
kmi = km.items.add('anim.keyframe_delete_v3d', 'I', 'PRESS', alt=True)
|
kmi = km.items.new('anim.keyframe_delete_v3d', 'I', 'PRESS', alt=True)
|
||||||
kmi = km.items.add('anim.keying_set_active_set', 'I', 'PRESS', shift=True, ctrl=True, alt=True)
|
kmi = km.items.new('anim.keying_set_active_set', 'I', 'PRESS', shift=True, ctrl=True, alt=True)
|
||||||
kmi = km.items.add('group.create', 'G', 'PRESS', ctrl=True)
|
kmi = km.items.new('group.create', 'G', 'PRESS', ctrl=True)
|
||||||
kmi = km.items.add('group.objects_remove', 'G', 'PRESS', ctrl=True, alt=True)
|
kmi = km.items.new('group.objects_remove', 'G', 'PRESS', ctrl=True, alt=True)
|
||||||
kmi = km.items.add('group.objects_add_active', 'G', 'PRESS', shift=True, ctrl=True)
|
kmi = km.items.new('group.objects_add_active', 'G', 'PRESS', shift=True, ctrl=True)
|
||||||
kmi = km.items.add('group.objects_remove_active', 'G', 'PRESS', shift=True, alt=True)
|
kmi = km.items.new('group.objects_remove_active', 'G', 'PRESS', shift=True, alt=True)
|
||||||
kmi = km.items.add('wm.call_menu', 'W', 'PRESS', ctrl=True)
|
kmi = km.items.new('wm.call_menu', 'W', 'PRESS', ctrl=True)
|
||||||
kmi.properties.name = 'VIEW3D_MT_object_specials'
|
kmi.properties.name = 'VIEW3D_MT_object_specials'
|
||||||
kmi = km.items.add('object.subdivision_set', 'ZERO', 'PRESS', ctrl=True)
|
kmi = km.items.new('object.subdivision_set', 'ZERO', 'PRESS', ctrl=True)
|
||||||
kmi.properties.level = 0
|
kmi.properties.level = 0
|
||||||
kmi = km.items.add('object.subdivision_set', 'ONE', 'PRESS', ctrl=True)
|
kmi = km.items.new('object.subdivision_set', 'ONE', 'PRESS', ctrl=True)
|
||||||
kmi.properties.level = 1
|
kmi.properties.level = 1
|
||||||
kmi = km.items.add('object.subdivision_set', 'TWO', 'PRESS', ctrl=True)
|
kmi = km.items.new('object.subdivision_set', 'TWO', 'PRESS', ctrl=True)
|
||||||
kmi.properties.level = 2
|
kmi.properties.level = 2
|
||||||
kmi = km.items.add('object.subdivision_set', 'THREE', 'PRESS', ctrl=True)
|
kmi = km.items.new('object.subdivision_set', 'THREE', 'PRESS', ctrl=True)
|
||||||
kmi.properties.level = 3
|
kmi.properties.level = 3
|
||||||
kmi = km.items.add('object.subdivision_set', 'FOUR', 'PRESS', ctrl=True)
|
kmi = km.items.new('object.subdivision_set', 'FOUR', 'PRESS', ctrl=True)
|
||||||
kmi.properties.level = 4
|
kmi.properties.level = 4
|
||||||
kmi = km.items.add('object.subdivision_set', 'FIVE', 'PRESS', ctrl=True)
|
kmi = km.items.new('object.subdivision_set', 'FIVE', 'PRESS', ctrl=True)
|
||||||
kmi.properties.level = 5
|
kmi.properties.level = 5
|
||||||
kmi = km.items.add('object.select_all', 'SELECTMOUSE', 'CLICK')
|
kmi = km.items.new('object.select_all', 'SELECTMOUSE', 'CLICK')
|
||||||
kmi.properties.action = 'DESELECT'
|
kmi.properties.action = 'DESELECT'
|
||||||
|
|
||||||
# Map Mesh
|
# Map Mesh
|
||||||
km = kc.add_keymap('Mesh', space_type='EMPTY', region_type='WINDOW', modal=False)
|
km = kc.keymaps.new('Mesh', space_type='EMPTY', region_type='WINDOW', modal=False)
|
||||||
|
|
||||||
kmi = km.items.add('mesh.loopcut_slide', 'R', 'PRESS', ctrl=True)
|
kmi = km.items.new('mesh.loopcut_slide', 'R', 'PRESS', ctrl=True)
|
||||||
kmi = km.items.add('mesh.loop_select', 'SELECTMOUSE', 'PRESS', ctrl=True, alt=True)
|
kmi = km.items.new('mesh.loop_select', 'SELECTMOUSE', 'PRESS', ctrl=True, alt=True)
|
||||||
kmi = km.items.add('mesh.loop_select', 'SELECTMOUSE', 'PRESS', shift=True, alt=True)
|
kmi = km.items.new('mesh.loop_select', 'SELECTMOUSE', 'PRESS', shift=True, alt=True)
|
||||||
kmi.properties.extend = True
|
kmi.properties.extend = True
|
||||||
kmi = km.items.add('mesh.edgering_select', 'SELECTMOUSE', 'PRESS', ctrl=True, alt=True)
|
kmi = km.items.new('mesh.edgering_select', 'SELECTMOUSE', 'PRESS', ctrl=True, alt=True)
|
||||||
kmi = km.items.add('mesh.edgering_select', 'SELECTMOUSE', 'PRESS', shift=True, ctrl=True, alt=True)
|
kmi = km.items.new('mesh.edgering_select', 'SELECTMOUSE', 'PRESS', shift=True, ctrl=True, alt=True)
|
||||||
kmi.properties.extend = True
|
kmi.properties.extend = True
|
||||||
kmi = km.items.add('mesh.select_shortest_path', 'SELECTMOUSE', 'PRESS', ctrl=True)
|
kmi = km.items.new('mesh.select_shortest_path', 'SELECTMOUSE', 'PRESS', ctrl=True)
|
||||||
kmi = km.items.add('mesh.select_all', 'A', 'PRESS')
|
kmi = km.items.new('mesh.select_all', 'A', 'PRESS')
|
||||||
kmi = km.items.add('mesh.select_more', 'NUMPAD_PLUS', 'PRESS', ctrl=True)
|
kmi = km.items.new('mesh.select_more', 'NUMPAD_PLUS', 'PRESS', ctrl=True)
|
||||||
kmi = km.items.add('mesh.select_less', 'NUMPAD_MINUS', 'PRESS', ctrl=True)
|
kmi = km.items.new('mesh.select_less', 'NUMPAD_MINUS', 'PRESS', ctrl=True)
|
||||||
kmi = km.items.add('mesh.select_inverse', 'I', 'PRESS', ctrl=True)
|
kmi = km.items.new('mesh.select_inverse', 'I', 'PRESS', ctrl=True)
|
||||||
kmi = km.items.add('mesh.select_non_manifold', 'M', 'PRESS', shift=True, ctrl=True, alt=True)
|
kmi = km.items.new('mesh.select_non_manifold', 'M', 'PRESS', shift=True, ctrl=True, alt=True)
|
||||||
kmi = km.items.add('mesh.select_linked', 'L', 'PRESS', ctrl=True)
|
kmi = km.items.new('mesh.select_linked', 'L', 'PRESS', ctrl=True)
|
||||||
kmi = km.items.add('mesh.select_linked_pick', 'L', 'PRESS')
|
kmi = km.items.new('mesh.select_linked_pick', 'L', 'PRESS')
|
||||||
kmi = km.items.add('mesh.select_linked_pick', 'L', 'PRESS', shift=True)
|
kmi = km.items.new('mesh.select_linked_pick', 'L', 'PRESS', shift=True)
|
||||||
kmi.properties.deselect = True
|
kmi.properties.deselect = True
|
||||||
kmi = km.items.add('mesh.faces_select_linked_flat', 'F', 'PRESS', shift=True, ctrl=True, alt=True)
|
kmi = km.items.new('mesh.faces_select_linked_flat', 'F', 'PRESS', shift=True, ctrl=True, alt=True)
|
||||||
kmi.properties.sharpness = 135.0
|
kmi.properties.sharpness = 135.0
|
||||||
kmi = km.items.add('mesh.select_similar', 'G', 'PRESS', shift=True)
|
kmi = km.items.new('mesh.select_similar', 'G', 'PRESS', shift=True)
|
||||||
kmi = km.items.add('wm.call_menu', 'TAB', 'PRESS', ctrl=True)
|
kmi = km.items.new('wm.call_menu', 'TAB', 'PRESS', ctrl=True)
|
||||||
kmi.properties.name = 'VIEW3D_MT_edit_mesh_selection_mode'
|
kmi.properties.name = 'VIEW3D_MT_edit_mesh_selection_mode'
|
||||||
kmi = km.items.add('mesh.hide', 'H', 'PRESS')
|
kmi = km.items.new('mesh.hide', 'H', 'PRESS')
|
||||||
kmi = km.items.add('mesh.hide', 'H', 'PRESS', shift=True)
|
kmi = km.items.new('mesh.hide', 'H', 'PRESS', shift=True)
|
||||||
kmi.properties.unselected = True
|
kmi.properties.unselected = True
|
||||||
kmi = km.items.add('mesh.reveal', 'H', 'PRESS', alt=True)
|
kmi = km.items.new('mesh.reveal', 'H', 'PRESS', alt=True)
|
||||||
kmi = km.items.add('mesh.normals_make_consistent', 'N', 'PRESS', ctrl=True)
|
kmi = km.items.new('mesh.normals_make_consistent', 'N', 'PRESS', ctrl=True)
|
||||||
kmi = km.items.add('mesh.normals_make_consistent', 'N', 'PRESS', shift=True, ctrl=True)
|
kmi = km.items.new('mesh.normals_make_consistent', 'N', 'PRESS', shift=True, ctrl=True)
|
||||||
kmi.properties.inside = True
|
kmi.properties.inside = True
|
||||||
kmi = km.items.add('view3d.edit_mesh_extrude_move_normal', 'E', 'PRESS', ctrl=True)
|
kmi = km.items.new('view3d.edit_mesh_extrude_move_normal', 'E', 'PRESS', ctrl=True)
|
||||||
kmi = km.items.add('view3d.edit_mesh_extrude_individual_move', 'E', 'PRESS', shift=True)
|
kmi = km.items.new('view3d.edit_mesh_extrude_individual_move', 'E', 'PRESS', shift=True)
|
||||||
kmi = km.items.add('wm.call_menu', 'E', 'PRESS', alt=True)
|
kmi = km.items.new('wm.call_menu', 'E', 'PRESS', alt=True)
|
||||||
kmi.properties.name = 'VIEW3D_MT_edit_mesh_extrude'
|
kmi.properties.name = 'VIEW3D_MT_edit_mesh_extrude'
|
||||||
kmi = km.items.add('mesh.spin', 'R', 'PRESS', alt=True)
|
kmi = km.items.new('mesh.spin', 'R', 'PRESS', alt=True)
|
||||||
kmi = km.items.add('mesh.fill', 'F', 'PRESS', alt=True)
|
kmi = km.items.new('mesh.fill', 'F', 'PRESS', alt=True)
|
||||||
kmi = km.items.add('mesh.beautify_fill', 'F', 'PRESS', shift=True, alt=True)
|
kmi = km.items.new('mesh.beautify_fill', 'F', 'PRESS', shift=True, alt=True)
|
||||||
kmi = km.items.add('mesh.quads_convert_to_tris', 'T', 'PRESS', ctrl=True)
|
kmi = km.items.new('mesh.quads_convert_to_tris', 'T', 'PRESS', ctrl=True)
|
||||||
kmi = km.items.add('mesh.tris_convert_to_quads', 'J', 'PRESS', alt=True)
|
kmi = km.items.new('mesh.tris_convert_to_quads', 'J', 'PRESS', alt=True)
|
||||||
kmi = km.items.add('mesh.edge_flip', 'F', 'PRESS', shift=True, ctrl=True)
|
kmi = km.items.new('mesh.edge_flip', 'F', 'PRESS', shift=True, ctrl=True)
|
||||||
kmi = km.items.add('mesh.rip_move', 'V', 'PRESS')
|
kmi = km.items.new('mesh.rip_move', 'V', 'PRESS')
|
||||||
kmi = km.items.add('mesh.merge', 'M', 'PRESS', alt=True)
|
kmi = km.items.new('mesh.merge', 'M', 'PRESS', alt=True)
|
||||||
kmi = km.items.add('transform.shrink_fatten', 'S', 'PRESS', ctrl=True, alt=True)
|
kmi = km.items.new('transform.shrink_fatten', 'S', 'PRESS', ctrl=True, alt=True)
|
||||||
kmi = km.items.add('mesh.edge_face_add', 'F', 'PRESS')
|
kmi = km.items.new('mesh.edge_face_add', 'F', 'PRESS')
|
||||||
kmi = km.items.add('mesh.duplicate_move', 'D', 'PRESS', shift=True)
|
kmi = km.items.new('mesh.duplicate_move', 'D', 'PRESS', shift=True)
|
||||||
kmi = km.items.add('wm.call_menu', 'A', 'PRESS', shift=True)
|
kmi = km.items.new('wm.call_menu', 'A', 'PRESS', shift=True)
|
||||||
kmi.properties.name = 'INFO_MT_mesh_add'
|
kmi.properties.name = 'INFO_MT_mesh_add'
|
||||||
kmi = km.items.add('mesh.separate', 'P', 'PRESS')
|
kmi = km.items.new('mesh.separate', 'P', 'PRESS')
|
||||||
kmi = km.items.add('mesh.split', 'Y', 'PRESS')
|
kmi = km.items.new('mesh.split', 'Y', 'PRESS')
|
||||||
kmi = km.items.add('mesh.dupli_extrude_cursor', 'ACTIONMOUSE', 'CLICK', ctrl=True)
|
kmi = km.items.new('mesh.dupli_extrude_cursor', 'ACTIONMOUSE', 'CLICK', ctrl=True)
|
||||||
kmi = km.items.add('mesh.delete', 'X', 'PRESS')
|
kmi = km.items.new('mesh.delete', 'X', 'PRESS')
|
||||||
kmi = km.items.add('mesh.delete', 'DEL', 'PRESS')
|
kmi = km.items.new('mesh.delete', 'DEL', 'PRESS')
|
||||||
kmi = km.items.add('mesh.knife_cut', 'LEFTMOUSE', 'PRESS', key_modifier='K')
|
kmi = km.items.new('mesh.knife_cut', 'LEFTMOUSE', 'PRESS', key_modifier='K')
|
||||||
kmi = km.items.add('mesh.knife_cut', 'LEFTMOUSE', 'PRESS', shift=True, key_modifier='K')
|
kmi = km.items.new('mesh.knife_cut', 'LEFTMOUSE', 'PRESS', shift=True, key_modifier='K')
|
||||||
kmi.properties.type = 'MIDPOINTS'
|
kmi.properties.type = 'MIDPOINTS'
|
||||||
kmi = km.items.add('object.vertex_parent_set', 'P', 'PRESS', ctrl=True)
|
kmi = km.items.new('object.vertex_parent_set', 'P', 'PRESS', ctrl=True)
|
||||||
kmi = km.items.add('wm.call_menu', 'W', 'PRESS', ctrl=True)
|
kmi = km.items.new('wm.call_menu', 'W', 'PRESS', ctrl=True)
|
||||||
kmi.properties.name = 'VIEW3D_MT_edit_mesh_specials'
|
kmi.properties.name = 'VIEW3D_MT_edit_mesh_specials'
|
||||||
kmi = km.items.add('wm.call_menu', 'F', 'PRESS', ctrl=True)
|
kmi = km.items.new('wm.call_menu', 'F', 'PRESS', ctrl=True)
|
||||||
kmi.properties.name = 'VIEW3D_MT_edit_mesh_faces'
|
kmi.properties.name = 'VIEW3D_MT_edit_mesh_faces'
|
||||||
kmi = km.items.add('wm.call_menu', 'E', 'PRESS', ctrl=True)
|
kmi = km.items.new('wm.call_menu', 'E', 'PRESS', ctrl=True)
|
||||||
kmi.properties.name = 'VIEW3D_MT_edit_mesh_edges'
|
kmi.properties.name = 'VIEW3D_MT_edit_mesh_edges'
|
||||||
kmi = km.items.add('wm.call_menu', 'V', 'PRESS', ctrl=True)
|
kmi = km.items.new('wm.call_menu', 'V', 'PRESS', ctrl=True)
|
||||||
kmi.properties.name = 'VIEW3D_MT_edit_mesh_vertices'
|
kmi.properties.name = 'VIEW3D_MT_edit_mesh_vertices'
|
||||||
kmi = km.items.add('wm.call_menu', 'H', 'PRESS', ctrl=True)
|
kmi = km.items.new('wm.call_menu', 'H', 'PRESS', ctrl=True)
|
||||||
kmi.properties.name = 'VIEW3D_MT_hook'
|
kmi.properties.name = 'VIEW3D_MT_hook'
|
||||||
kmi = km.items.add('wm.call_menu', 'U', 'PRESS')
|
kmi = km.items.new('wm.call_menu', 'U', 'PRESS')
|
||||||
kmi.properties.name = 'VIEW3D_MT_uv_map'
|
kmi.properties.name = 'VIEW3D_MT_uv_map'
|
||||||
kmi = km.items.add('wm.call_menu', 'G', 'PRESS', ctrl=True)
|
kmi = km.items.new('wm.call_menu', 'G', 'PRESS', ctrl=True)
|
||||||
kmi.properties.name = 'VIEW3D_MT_vertex_group'
|
kmi.properties.name = 'VIEW3D_MT_vertex_group'
|
||||||
kmi = km.items.add('wm.context_cycle_enum', 'O', 'PRESS', shift=True)
|
kmi = km.items.new('wm.context_cycle_enum', 'O', 'PRESS', shift=True)
|
||||||
kmi.properties.data_path = 'tool_settings.proportional_edit_falloff'
|
kmi.properties.data_path = 'tool_settings.proportional_edit_falloff'
|
||||||
kmi = km.items.add('wm.context_toggle_enum', 'O', 'PRESS')
|
kmi = km.items.new('wm.context_toggle_enum', 'O', 'PRESS')
|
||||||
kmi.properties.data_path = 'tool_settings.proportional_edit'
|
kmi.properties.data_path = 'tool_settings.proportional_edit'
|
||||||
kmi.properties.value_1 = 'DISABLED'
|
kmi.properties.value_1 = 'DISABLED'
|
||||||
kmi.properties.value_2 = 'ENABLED'
|
kmi.properties.value_2 = 'ENABLED'
|
||||||
kmi = km.items.add('wm.context_toggle_enum', 'O', 'PRESS', alt=True)
|
kmi = km.items.new('wm.context_toggle_enum', 'O', 'PRESS', alt=True)
|
||||||
kmi.properties.data_path = 'tool_settings.proportional_edit'
|
kmi.properties.data_path = 'tool_settings.proportional_edit'
|
||||||
kmi.properties.value_1 = 'DISABLED'
|
kmi.properties.value_1 = 'DISABLED'
|
||||||
kmi.properties.value_2 = 'CONNECTED'
|
kmi.properties.value_2 = 'CONNECTED'
|
||||||
kmi = km.items.add('mesh.select_all', 'SELECTMOUSE', 'CLICK')
|
kmi = km.items.new('mesh.select_all', 'SELECTMOUSE', 'CLICK')
|
||||||
kmi.properties.action = 'DESELECT'
|
kmi.properties.action = 'DESELECT'
|
||||||
|
|
||||||
wm.keyconfigs.active = kc
|
wm.keyconfigs.active = kc
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ class ExportSomeData(bpy.types.Operator):
|
|||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
def invoke(self, context, event):
|
def invoke(self, context, event):
|
||||||
wm = context.manager
|
wm = context.window_manager
|
||||||
|
|
||||||
if True:
|
if True:
|
||||||
# File selector
|
# File selector
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ class ModalOperator(bpy.types.Operator):
|
|||||||
|
|
||||||
def invoke(self, context, event):
|
def invoke(self, context, event):
|
||||||
if context.object:
|
if context.object:
|
||||||
context.manager.add_modal_handler(self)
|
context.window_manager.add_modal_handler(self)
|
||||||
self.properties.first_mouse_x = event.mouse_x
|
self.properties.first_mouse_x = event.mouse_x
|
||||||
self.properties.first_value = context.object.location.x
|
self.properties.first_value = context.object.location.x
|
||||||
return {'RUNNING_MODAL'}
|
return {'RUNNING_MODAL'}
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ class ModalDrawOperator(bpy.types.Operator):
|
|||||||
|
|
||||||
def invoke(self, context, event):
|
def invoke(self, context, event):
|
||||||
if context.area.type == 'VIEW_3D':
|
if context.area.type == 'VIEW_3D':
|
||||||
context.manager.add_modal_handler(self)
|
context.window_manager.add_modal_handler(self)
|
||||||
|
|
||||||
# Add the region OpenGL drawing callback
|
# Add the region OpenGL drawing callback
|
||||||
# draw in view space with 'POST_VIEW' and 'PRE_VIEW'
|
# draw in view space with 'POST_VIEW' and 'PRE_VIEW'
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ class ViewOperator(bpy.types.Operator):
|
|||||||
v3d = context.space_data
|
v3d = context.space_data
|
||||||
rv3d = v3d.region_3d
|
rv3d = v3d.region_3d
|
||||||
|
|
||||||
context.manager.add_modal_handler(self)
|
context.window_manager.add_modal_handler(self)
|
||||||
|
|
||||||
if rv3d.view_perspective == 'CAMERA':
|
if rv3d.view_perspective == 'CAMERA':
|
||||||
rv3d.view_perspective = 'PERSP'
|
rv3d.view_perspective = 'PERSP'
|
||||||
|
|||||||
@@ -250,7 +250,7 @@ class AsScript(bpy.types.Operator):
|
|||||||
import os
|
import os
|
||||||
obj = context.object
|
obj = context.object
|
||||||
self.properties.filepath = os.path.splitext(bpy.data.filepath)[0] + "-" + bpy.path.clean_name(obj.name) + ".py"
|
self.properties.filepath = os.path.splitext(bpy.data.filepath)[0] + "-" + bpy.path.clean_name(obj.name) + ".py"
|
||||||
wm = context.manager
|
wm = context.window_manager
|
||||||
wm.add_fileselect(self)
|
wm.add_fileselect(self)
|
||||||
return {'RUNNING_MODAL'}
|
return {'RUNNING_MODAL'}
|
||||||
|
|
||||||
|
|||||||
@@ -54,13 +54,15 @@ class DATA_PT_context_lamp(DataButtonsPanel, bpy.types.Panel):
|
|||||||
|
|
||||||
split = layout.split(percentage=0.65)
|
split = layout.split(percentage=0.65)
|
||||||
|
|
||||||
|
texture_count = len(lamp.texture_slots.keys())
|
||||||
|
|
||||||
if ob:
|
if ob:
|
||||||
split.template_ID(ob, "data")
|
split.template_ID(ob, "data")
|
||||||
split.separator()
|
|
||||||
elif lamp:
|
elif lamp:
|
||||||
split.template_ID(space, "pin_id")
|
split.template_ID(space, "pin_id")
|
||||||
split.separator()
|
|
||||||
|
|
||||||
|
if texture_count != 0:
|
||||||
|
split.label(text=str(texture_count), icon='TEXTURE')
|
||||||
|
|
||||||
class DATA_PT_preview(DataButtonsPanel, bpy.types.Panel):
|
class DATA_PT_preview(DataButtonsPanel, bpy.types.Panel):
|
||||||
bl_label = "Preview"
|
bl_label = "Preview"
|
||||||
|
|||||||
@@ -755,7 +755,6 @@ class VolumeButtonsPanel():
|
|||||||
|
|
||||||
class MATERIAL_PT_volume_density(VolumeButtonsPanel, bpy.types.Panel):
|
class MATERIAL_PT_volume_density(VolumeButtonsPanel, bpy.types.Panel):
|
||||||
bl_label = "Density"
|
bl_label = "Density"
|
||||||
bl_default_closed = False
|
|
||||||
COMPAT_ENGINES = {'BLENDER_RENDER'}
|
COMPAT_ENGINES = {'BLENDER_RENDER'}
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
@@ -773,7 +772,6 @@ class MATERIAL_PT_volume_density(VolumeButtonsPanel, bpy.types.Panel):
|
|||||||
|
|
||||||
class MATERIAL_PT_volume_shading(VolumeButtonsPanel, bpy.types.Panel):
|
class MATERIAL_PT_volume_shading(VolumeButtonsPanel, bpy.types.Panel):
|
||||||
bl_label = "Shading"
|
bl_label = "Shading"
|
||||||
bl_default_closed = False
|
|
||||||
COMPAT_ENGINES = {'BLENDER_RENDER'}
|
COMPAT_ENGINES = {'BLENDER_RENDER'}
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
@@ -799,7 +797,6 @@ class MATERIAL_PT_volume_shading(VolumeButtonsPanel, bpy.types.Panel):
|
|||||||
|
|
||||||
class MATERIAL_PT_volume_lighting(VolumeButtonsPanel, bpy.types.Panel):
|
class MATERIAL_PT_volume_lighting(VolumeButtonsPanel, bpy.types.Panel):
|
||||||
bl_label = "Lighting"
|
bl_label = "Lighting"
|
||||||
bl_default_closed = False
|
|
||||||
COMPAT_ENGINES = {'BLENDER_RENDER'}
|
COMPAT_ENGINES = {'BLENDER_RENDER'}
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
@@ -847,7 +844,6 @@ class MATERIAL_PT_volume_transp(VolumeButtonsPanel, bpy.types.Panel):
|
|||||||
|
|
||||||
class MATERIAL_PT_volume_integration(VolumeButtonsPanel, bpy.types.Panel):
|
class MATERIAL_PT_volume_integration(VolumeButtonsPanel, bpy.types.Panel):
|
||||||
bl_label = "Integration"
|
bl_label = "Integration"
|
||||||
bl_default_closed = False
|
|
||||||
COMPAT_ENGINES = {'BLENDER_RENDER'}
|
COMPAT_ENGINES = {'BLENDER_RENDER'}
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ class OBJECT_PT_groups(ObjectButtonsPanel, bpy.types.Panel):
|
|||||||
if ob.name in group.objects:
|
if ob.name in group.objects:
|
||||||
col = layout.column(align=True)
|
col = layout.column(align=True)
|
||||||
|
|
||||||
col.set_context_pointer("group", group)
|
col.context_pointer_set("group", group)
|
||||||
|
|
||||||
row = col.box().row()
|
row = col.box().row()
|
||||||
row.prop(group, "name", text="")
|
row.prop(group, "name", text="")
|
||||||
|
|||||||
@@ -487,12 +487,12 @@ class PARTICLE_PT_physics(ParticleButtonsPanel, bpy.types.Panel):
|
|||||||
col.prop(boids, "air_ave_max", slider=True)
|
col.prop(boids, "air_ave_max", slider=True)
|
||||||
col.prop(boids, "air_personal_space")
|
col.prop(boids, "air_personal_space")
|
||||||
row = col.row()
|
row = col.row()
|
||||||
row.active = (boids.use_land or boids.allow_climb) and boids.allow_flight
|
row.active = (boids.use_land or boids.use_climb) and boids.use_flight
|
||||||
row.prop(boids, "land_smooth")
|
row.prop(boids, "land_smooth")
|
||||||
|
|
||||||
sub = split.column()
|
sub = split.column()
|
||||||
col = sub.column(align=True)
|
col = sub.column(align=True)
|
||||||
col.active = boids.use_land or boids.allow_climb
|
col.active = boids.use_land or boids.use_climb
|
||||||
col.prop(boids, "land_speed_max")
|
col.prop(boids, "land_speed_max")
|
||||||
col.prop(boids, "land_jump_speed")
|
col.prop(boids, "land_jump_speed")
|
||||||
col.prop(boids, "land_acc_max", slider=True)
|
col.prop(boids, "land_acc_max", slider=True)
|
||||||
@@ -862,6 +862,15 @@ class PARTICLE_PT_draw(ParticleButtonsPanel, bpy.types.Panel):
|
|||||||
else:
|
else:
|
||||||
row.label(text="")
|
row.label(text="")
|
||||||
|
|
||||||
|
if part.draw_percentage != 100:
|
||||||
|
if part.type == 'HAIR':
|
||||||
|
if psys.hair_dynamics and psys.point_cache.is_baked == False:
|
||||||
|
layout.row().label(text="Display percentage makes dynamics inaccurate without baking!")
|
||||||
|
else:
|
||||||
|
phystype = part.physics_type
|
||||||
|
if phystype != 'NO' and phystype != 'KEYED' and psys.point_cache.is_baked == False:
|
||||||
|
layout.row().label(text="Display percentage makes dynamics inaccurate without baking!")
|
||||||
|
|
||||||
row = layout.row()
|
row = layout.row()
|
||||||
col = row.column()
|
col = row.column()
|
||||||
col.prop(part, "show_size")
|
col.prop(part, "show_size")
|
||||||
@@ -1028,9 +1037,10 @@ class PARTICLE_PT_vertexgroups(ParticleButtonsPanel, bpy.types.Panel):
|
|||||||
row.prop_search(psys, "vertex_group_density", ob, "vertex_groups", text="Density")
|
row.prop_search(psys, "vertex_group_density", ob, "vertex_groups", text="Density")
|
||||||
row.prop(psys, "invert_vertex_group_density", text="")
|
row.prop(psys, "invert_vertex_group_density", text="")
|
||||||
|
|
||||||
row = layout.row()
|
# Commented out vertex groups don't work and are still waiting for better implementation
|
||||||
row.prop_search(psys, "vertex_group_velocity", ob, "vertex_groups", text="Velocity")
|
# row = layout.row()
|
||||||
row.prop(psys, "invert_vertex_group_velocity", text="")
|
# row.prop_search(psys, "vertex_group_velocity", ob, "vertex_groups", text="Velocity")
|
||||||
|
# row.prop(psys, "invert_vertex_group_velocity", text="")
|
||||||
|
|
||||||
row = layout.row()
|
row = layout.row()
|
||||||
row.prop_search(psys, "vertex_group_length", ob, "vertex_groups", text="Length")
|
row.prop_search(psys, "vertex_group_length", ob, "vertex_groups", text="Length")
|
||||||
@@ -1056,21 +1066,21 @@ class PARTICLE_PT_vertexgroups(ParticleButtonsPanel, bpy.types.Panel):
|
|||||||
row.prop_search(psys, "vertex_group_roughness_end", ob, "vertex_groups", text="Roughness End")
|
row.prop_search(psys, "vertex_group_roughness_end", ob, "vertex_groups", text="Roughness End")
|
||||||
row.prop(psys, "invert_vertex_group_roughness_end", text="")
|
row.prop(psys, "invert_vertex_group_roughness_end", text="")
|
||||||
|
|
||||||
row = layout.row()
|
# row = layout.row()
|
||||||
row.prop_search(psys, "vertex_group_size", ob, "vertex_groups", text="Size")
|
# row.prop_search(psys, "vertex_group_size", ob, "vertex_groups", text="Size")
|
||||||
row.prop(psys, "invert_vertex_group_size", text="")
|
# row.prop(psys, "invert_vertex_group_size", text="")
|
||||||
|
|
||||||
row = layout.row()
|
# row = layout.row()
|
||||||
row.prop_search(psys, "vertex_group_tangent", ob, "vertex_groups", text="Tangent")
|
# row.prop_search(psys, "vertex_group_tangent", ob, "vertex_groups", text="Tangent")
|
||||||
row.prop(psys, "invert_vertex_group_tangent", text="")
|
# row.prop(psys, "invert_vertex_group_tangent", text="")
|
||||||
|
|
||||||
row = layout.row()
|
# row = layout.row()
|
||||||
row.prop_search(psys, "vertex_group_rotation", ob, "vertex_groups", text="Rotation")
|
# row.prop_search(psys, "vertex_group_rotation", ob, "vertex_groups", text="Rotation")
|
||||||
row.prop(psys, "invert_vertex_group_rotation", text="")
|
# row.prop(psys, "invert_vertex_group_rotation", text="")
|
||||||
|
|
||||||
row = layout.row()
|
# row = layout.row()
|
||||||
row.prop_search(psys, "vertex_group_field", ob, "vertex_groups", text="Field")
|
# row.prop_search(psys, "vertex_group_field", ob, "vertex_groups", text="Field")
|
||||||
row.prop(psys, "invert_vertex_group_field", text="")
|
# row.prop(psys, "invert_vertex_group_field", text="")
|
||||||
|
|
||||||
|
|
||||||
class PARTICLE_PT_custom_props(ParticleButtonsPanel, PropertyPanel, bpy.types.Panel):
|
class PARTICLE_PT_custom_props(ParticleButtonsPanel, PropertyPanel, bpy.types.Panel):
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ class PHYSICS_PT_cloth(PhysicButtonsPanel, bpy.types.Panel):
|
|||||||
|
|
||||||
if md:
|
if md:
|
||||||
# remove modifier + settings
|
# remove modifier + settings
|
||||||
split.set_context_pointer("modifier", md)
|
split.context_pointer_set("modifier", md)
|
||||||
split.operator("object.modifier_remove", text="Remove")
|
split.operator("object.modifier_remove", text="Remove")
|
||||||
|
|
||||||
row = split.row(align=True)
|
row = split.row(align=True)
|
||||||
@@ -105,7 +105,7 @@ class PHYSICS_PT_cloth(PhysicButtonsPanel, bpy.types.Panel):
|
|||||||
col.prop(cloth, "use_pin_cloth", text="Pinning")
|
col.prop(cloth, "use_pin_cloth", text="Pinning")
|
||||||
sub = col.column()
|
sub = col.column()
|
||||||
sub.active = cloth.use_pin_cloth
|
sub.active = cloth.use_pin_cloth
|
||||||
sub.prop_search(cloth, "mass_vertex_group", ob, "vertex_groups", text="")
|
sub.prop_search(cloth, "vertex_group_mass", ob, "vertex_groups", text="")
|
||||||
sub.prop(cloth, "pin_stiffness", text="Stiffness")
|
sub.prop(cloth, "pin_stiffness", text="Stiffness")
|
||||||
|
|
||||||
col.label(text="Pre roll:")
|
col.label(text="Pre roll:")
|
||||||
@@ -113,7 +113,7 @@ class PHYSICS_PT_cloth(PhysicButtonsPanel, bpy.types.Panel):
|
|||||||
|
|
||||||
# Disabled for now
|
# Disabled for now
|
||||||
"""
|
"""
|
||||||
if cloth.mass_vertex_group:
|
if cloth.vertex_group_mass:
|
||||||
layout.label(text="Goal:")
|
layout.label(text="Goal:")
|
||||||
|
|
||||||
col = layout.column_flow()
|
col = layout.column_flow()
|
||||||
@@ -208,12 +208,12 @@ class PHYSICS_PT_cloth_stiffness(PhysicButtonsPanel, bpy.types.Panel):
|
|||||||
|
|
||||||
col = split.column()
|
col = split.column()
|
||||||
col.label(text="Structural Stiffness:")
|
col.label(text="Structural Stiffness:")
|
||||||
col.prop_search(cloth, "structural_stiffness_vertex_group", ob, "vertex_groups", text="")
|
col.prop_search(cloth, "vertex_group_structural_stiffness", ob, "vertex_groups", text="")
|
||||||
col.prop(cloth, "structural_stiffness_max", text="Max")
|
col.prop(cloth, "structural_stiffness_max", text="Max")
|
||||||
|
|
||||||
col = split.column()
|
col = split.column()
|
||||||
col.label(text="Bending Stiffness:")
|
col.label(text="Bending Stiffness:")
|
||||||
col.prop_search(cloth, "bending_vertex_group", ob, "vertex_groups", text="")
|
col.prop_search(cloth, "vertex_group_bending", ob, "vertex_groups", text="")
|
||||||
col.prop(cloth, "bending_stiffness_max", text="Max")
|
col.prop(cloth, "bending_stiffness_max", text="Max")
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ import bpy
|
|||||||
def point_cache_ui(self, context, cache, enabled, cachetype):
|
def point_cache_ui(self, context, cache, enabled, cachetype):
|
||||||
layout = self.layout
|
layout = self.layout
|
||||||
|
|
||||||
layout.set_context_pointer("point_cache", cache)
|
layout.context_pointer_set("point_cache", cache)
|
||||||
|
|
||||||
row = layout.row()
|
row = layout.row()
|
||||||
row.template_list(cache, "point_caches", cache.point_caches, "active_index", rows=2)
|
row.template_list(cache, "point_caches", cache.point_caches, "active_index", rows=2)
|
||||||
|
|||||||
@@ -175,7 +175,7 @@ class PHYSICS_PT_collision(PhysicButtonsPanel, bpy.types.Panel):
|
|||||||
|
|
||||||
if md:
|
if md:
|
||||||
# remove modifier + settings
|
# remove modifier + settings
|
||||||
split.set_context_pointer("modifier", md)
|
split.context_pointer_set("modifier", md)
|
||||||
split.operator("object.modifier_remove", text="Remove")
|
split.operator("object.modifier_remove", text="Remove")
|
||||||
col = split.column()
|
col = split.column()
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ class PHYSICS_PT_fluid(PhysicButtonsPanel, bpy.types.Panel):
|
|||||||
|
|
||||||
if md:
|
if md:
|
||||||
# remove modifier + settings
|
# remove modifier + settings
|
||||||
split.set_context_pointer("modifier", md)
|
split.context_pointer_set("modifier", md)
|
||||||
split.operator("object.modifier_remove", text="Remove")
|
split.operator("object.modifier_remove", text="Remove")
|
||||||
|
|
||||||
row = split.row(align=True)
|
row = split.row(align=True)
|
||||||
@@ -58,10 +58,8 @@ class PHYSICS_PT_fluid(PhysicButtonsPanel, bpy.types.Panel):
|
|||||||
split.operator("object.modifier_add", text="Add").type = 'FLUID_SIMULATION'
|
split.operator("object.modifier_add", text="Add").type = 'FLUID_SIMULATION'
|
||||||
split.label()
|
split.label()
|
||||||
|
|
||||||
fluid = None
|
|
||||||
|
|
||||||
|
if md:
|
||||||
if fluid:
|
|
||||||
row = layout.row()
|
row = layout.row()
|
||||||
row.prop(fluid, "type")
|
row.prop(fluid, "type")
|
||||||
if fluid.type not in ('NONE', 'DOMAIN', 'PARTICLE'):
|
if fluid.type not in ('NONE', 'DOMAIN', 'PARTICLE'):
|
||||||
@@ -72,7 +70,7 @@ class PHYSICS_PT_fluid(PhysicButtonsPanel, bpy.types.Panel):
|
|||||||
layout.active = fluid.use
|
layout.active = fluid.use
|
||||||
|
|
||||||
if fluid.type == 'DOMAIN':
|
if fluid.type == 'DOMAIN':
|
||||||
layout.operator("fluid.bake", text="Bake Fluid Simulation", icon='MOD_FLUIDSIM')
|
layout.operator("fluid.bake", text="Bake (Req. Memory: %s)" % fluid.memory_estimate, icon='MOD_FLUIDSIM')
|
||||||
split = layout.split()
|
split = layout.split()
|
||||||
|
|
||||||
col = split.column()
|
col = split.column()
|
||||||
@@ -82,7 +80,7 @@ class PHYSICS_PT_fluid(PhysicButtonsPanel, bpy.types.Panel):
|
|||||||
col.prop(fluid, "render_display_mode", text="")
|
col.prop(fluid, "render_display_mode", text="")
|
||||||
|
|
||||||
col = split.column()
|
col = split.column()
|
||||||
col.label(text="Required Memory: " + fluid.memory_estimate)
|
col.label()
|
||||||
col.prop(fluid, "preview_resolution", text="Preview")
|
col.prop(fluid, "preview_resolution", text="Preview")
|
||||||
col.label(text="Viewport Display:")
|
col.label(text="Viewport Display:")
|
||||||
col.prop(fluid, "viewport_display_mode", text="")
|
col.prop(fluid, "viewport_display_mode", text="")
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ class PHYSICS_PT_smoke(PhysicButtonsPanel, bpy.types.Panel):
|
|||||||
|
|
||||||
if md:
|
if md:
|
||||||
# remove modifier + settings
|
# remove modifier + settings
|
||||||
split.set_context_pointer("modifier", md)
|
split.context_pointer_set("modifier", md)
|
||||||
split.operator("object.modifier_remove", text="Remove")
|
split.operator("object.modifier_remove", text="Remove")
|
||||||
|
|
||||||
row = split.row(align=True)
|
row = split.row(align=True)
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ class PHYSICS_PT_softbody(PhysicButtonsPanel, bpy.types.Panel):
|
|||||||
|
|
||||||
if md:
|
if md:
|
||||||
# remove modifier + settings
|
# remove modifier + settings
|
||||||
split.set_context_pointer("modifier", md)
|
split.context_pointer_set("modifier", md)
|
||||||
split.operator("object.modifier_remove", text="Remove")
|
split.operator("object.modifier_remove", text="Remove")
|
||||||
|
|
||||||
row = split.row(align=True)
|
row = split.row(align=True)
|
||||||
@@ -77,7 +77,7 @@ class PHYSICS_PT_softbody(PhysicButtonsPanel, bpy.types.Panel):
|
|||||||
col.label(text="Object:")
|
col.label(text="Object:")
|
||||||
col.prop(softbody, "friction")
|
col.prop(softbody, "friction")
|
||||||
col.prop(softbody, "mass")
|
col.prop(softbody, "mass")
|
||||||
col.prop_search(softbody, "mass_vertex_group", ob, "vertex_groups", text="Mass:")
|
col.prop_search(softbody, "vertex_group_mass", ob, "vertex_groups", text="Mass:")
|
||||||
|
|
||||||
col = split.column()
|
col = split.column()
|
||||||
col.label(text="Simulation:")
|
col.label(text="Simulation:")
|
||||||
@@ -137,7 +137,7 @@ class PHYSICS_PT_softbody_goal(PhysicButtonsPanel, bpy.types.Panel):
|
|||||||
col.prop(softbody, "goal_spring", text="Stiffness")
|
col.prop(softbody, "goal_spring", text="Stiffness")
|
||||||
col.prop(softbody, "goal_friction", text="Damping")
|
col.prop(softbody, "goal_friction", text="Damping")
|
||||||
|
|
||||||
layout.prop_search(softbody, "goal_vertex_group", ob, "vertex_groups", text="Vertex Group")
|
layout.prop_search(softbody, "vertex_group_goal", ob, "vertex_groups", text="Vertex Group")
|
||||||
|
|
||||||
|
|
||||||
class PHYSICS_PT_softbody_edge(PhysicButtonsPanel, bpy.types.Panel):
|
class PHYSICS_PT_softbody_edge(PhysicButtonsPanel, bpy.types.Panel):
|
||||||
@@ -173,7 +173,7 @@ class PHYSICS_PT_softbody_edge(PhysicButtonsPanel, bpy.types.Panel):
|
|||||||
col.prop(softbody, "plastic")
|
col.prop(softbody, "plastic")
|
||||||
col.prop(softbody, "bend")
|
col.prop(softbody, "bend")
|
||||||
col.prop(softbody, "spring_length", text="Length")
|
col.prop(softbody, "spring_length", text="Length")
|
||||||
col.prop_search(softbody, "spring_vertex_group", ob, "vertex_groups", text="Springs:")
|
col.prop_search(softbody, "vertex_group_spring", ob, "vertex_groups", text="Springs:")
|
||||||
|
|
||||||
col = split.column()
|
col = split.column()
|
||||||
col.prop(softbody, "use_stiff_quads")
|
col.prop(softbody, "use_stiff_quads")
|
||||||
|
|||||||
@@ -238,7 +238,7 @@ class ANIM_OT_keying_set_export(bpy.types.Operator):
|
|||||||
|
|
||||||
# Add KeyingSet and set general settings
|
# Add KeyingSet and set general settings
|
||||||
f.write("# Keying Set Level declarations\n")
|
f.write("# Keying Set Level declarations\n")
|
||||||
f.write("ks= scene.add_keying_set(name=\"%s\")\n" % ks.name)
|
f.write("ks= scene.keying_sets.new(name=\"%s\")\n" % ks.name)
|
||||||
|
|
||||||
if not ks.is_path_absolute:
|
if not ks.is_path_absolute:
|
||||||
f.write("ks.is_path_absolute = False\n")
|
f.write("ks.is_path_absolute = False\n")
|
||||||
@@ -314,7 +314,7 @@ class ANIM_OT_keying_set_export(bpy.types.Operator):
|
|||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
def invoke(self, context, event):
|
def invoke(self, context, event):
|
||||||
wm = context.manager
|
wm = context.window_manager
|
||||||
wm.add_fileselect(self)
|
wm.add_fileselect(self)
|
||||||
return {'RUNNING_MODAL'}
|
return {'RUNNING_MODAL'}
|
||||||
|
|
||||||
|
|||||||
@@ -362,8 +362,8 @@ class TEXTURE_PT_influence(TextureSlotPanel, bpy.types.Panel):
|
|||||||
col = split.column()
|
col = split.column()
|
||||||
factor_but(col, tex.use_map_density, "use_map_density", "density_factor", "Density")
|
factor_but(col, tex.use_map_density, "use_map_density", "density_factor", "Density")
|
||||||
factor_but(col, tex.use_map_emission, "use_map_emission", "emission_factor", "Emission")
|
factor_but(col, tex.use_map_emission, "use_map_emission", "emission_factor", "Emission")
|
||||||
factor_but(col, tex.use_map_scatter, "use_map_scattering", "scattering_factor", "Scattering")
|
factor_but(col, tex.use_map_scatter, "use_map_scatter", "scattering_factor", "Scattering")
|
||||||
factor_but(col, tex.use_map_reflect, "use_map_reflection", "reflection_factor", "Reflection")
|
factor_but(col, tex.use_map_reflect, "use_map_reflect", "reflection_factor", "Reflection")
|
||||||
|
|
||||||
col = split.column()
|
col = split.column()
|
||||||
col.label(text=" ")
|
col.label(text=" ")
|
||||||
|
|||||||
@@ -50,6 +50,8 @@ class WORLD_PT_context_world(WorldButtonsPanel, bpy.types.Panel):
|
|||||||
scene = context.scene
|
scene = context.scene
|
||||||
world = context.world
|
world = context.world
|
||||||
space = context.space_data
|
space = context.space_data
|
||||||
|
|
||||||
|
texture_count = world and len(world.texture_slots.keys())
|
||||||
|
|
||||||
split = layout.split(percentage=0.65)
|
split = layout.split(percentage=0.65)
|
||||||
if scene:
|
if scene:
|
||||||
@@ -57,6 +59,8 @@ class WORLD_PT_context_world(WorldButtonsPanel, bpy.types.Panel):
|
|||||||
elif world:
|
elif world:
|
||||||
split.template_ID(space, "pin_id")
|
split.template_ID(space, "pin_id")
|
||||||
|
|
||||||
|
if texture_count:
|
||||||
|
split.label(text=str(texture_count), icon='TEXTURE')
|
||||||
|
|
||||||
class WORLD_PT_preview(WorldButtonsPanel, bpy.types.Panel):
|
class WORLD_PT_preview(WorldButtonsPanel, bpy.types.Panel):
|
||||||
bl_label = "Preview"
|
bl_label = "Preview"
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ class FILEBROWSER_HT_header(bpy.types.Header):
|
|||||||
layout = self.layout
|
layout = self.layout
|
||||||
|
|
||||||
st = context.space_data
|
st = context.space_data
|
||||||
params = st.params
|
|
||||||
|
|
||||||
layout.template_header(menus=False)
|
layout.template_header(menus=False)
|
||||||
|
|
||||||
@@ -45,24 +44,28 @@ class FILEBROWSER_HT_header(bpy.types.Header):
|
|||||||
|
|
||||||
row = layout.row(align=True)
|
row = layout.row(align=True)
|
||||||
row.operator("file.directory_new", text="", icon='NEWFOLDER')
|
row.operator("file.directory_new", text="", icon='NEWFOLDER')
|
||||||
|
|
||||||
|
params = st.params
|
||||||
|
|
||||||
layout.prop(params, "display_type", expand=True, text="")
|
# can be None when save/reload with a file selector open
|
||||||
layout.prop(params, "sort_method", expand=True, text="")
|
if params:
|
||||||
|
layout.prop(params, "display_type", expand=True, text="")
|
||||||
|
layout.prop(params, "sort_method", expand=True, text="")
|
||||||
|
|
||||||
layout.prop(params, "show_hidden")
|
layout.prop(params, "show_hidden")
|
||||||
layout.prop(params, "use_filter", text="", icon='FILTER')
|
layout.prop(params, "use_filter", text="", icon='FILTER')
|
||||||
|
|
||||||
row = layout.row(align=True)
|
row = layout.row(align=True)
|
||||||
row.active = params.use_filter
|
row.active = params.use_filter
|
||||||
|
|
||||||
row.prop(params, "use_filter_folder", text="")
|
row.prop(params, "use_filter_folder", text="")
|
||||||
row.prop(params, "use_filter_blender", text="")
|
row.prop(params, "use_filter_blender", text="")
|
||||||
row.prop(params, "use_filter_image", text="")
|
row.prop(params, "use_filter_image", text="")
|
||||||
row.prop(params, "use_filter_movie", text="")
|
row.prop(params, "use_filter_movie", text="")
|
||||||
row.prop(params, "use_filter_script", text="")
|
row.prop(params, "use_filter_script", text="")
|
||||||
row.prop(params, "use_filter_font", text="")
|
row.prop(params, "use_filter_font", text="")
|
||||||
row.prop(params, "use_filter_sound", text="")
|
row.prop(params, "use_filter_sound", text="")
|
||||||
row.prop(params, "use_filter_text", text="")
|
row.prop(params, "use_filter_text", text="")
|
||||||
|
|
||||||
|
|
||||||
def register():
|
def register():
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ class INFO_HT_header(bpy.types.Header):
|
|||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
layout = self.layout
|
layout = self.layout
|
||||||
|
|
||||||
wm = context.manager
|
wm = context.window_manager
|
||||||
window = context.window
|
window = context.window
|
||||||
scene = context.scene
|
scene = context.scene
|
||||||
rd = scene.render
|
rd = scene.render
|
||||||
@@ -169,7 +169,7 @@ class INFO_MT_mesh_add(bpy.types.Menu):
|
|||||||
layout.operator("mesh.primitive_circle_add", icon='MESH_CIRCLE', text="Circle")
|
layout.operator("mesh.primitive_circle_add", icon='MESH_CIRCLE', text="Circle")
|
||||||
layout.operator("mesh.primitive_uv_sphere_add", icon='MESH_UVSPHERE', text="UV Sphere")
|
layout.operator("mesh.primitive_uv_sphere_add", icon='MESH_UVSPHERE', text="UV Sphere")
|
||||||
layout.operator("mesh.primitive_ico_sphere_add", icon='MESH_ICOSPHERE', text="Icosphere")
|
layout.operator("mesh.primitive_ico_sphere_add", icon='MESH_ICOSPHERE', text="Icosphere")
|
||||||
layout.operator("mesh.primitive_tube_add", icon='MESH_TUBE', text="Tube")
|
layout.operator("mesh.primitive_cylinder_add", icon='MESH_CYLINDER', text="Cylinder")
|
||||||
layout.operator("mesh.primitive_cone_add", icon='MESH_CONE', text="Cone")
|
layout.operator("mesh.primitive_cone_add", icon='MESH_CONE', text="Cone")
|
||||||
layout.separator()
|
layout.separator()
|
||||||
layout.operator("mesh.primitive_grid_add", icon='MESH_GRID', text="Grid")
|
layout.operator("mesh.primitive_grid_add", icon='MESH_GRID', text="Grid")
|
||||||
@@ -200,9 +200,9 @@ class INFO_MT_surface_add(bpy.types.Menu):
|
|||||||
layout.operator("surface.primitive_nurbs_surface_curve_add", icon='SURFACE_NCURVE', text="NURBS Curve")
|
layout.operator("surface.primitive_nurbs_surface_curve_add", icon='SURFACE_NCURVE', text="NURBS Curve")
|
||||||
layout.operator("surface.primitive_nurbs_surface_circle_add", icon='SURFACE_NCIRCLE', text="NURBS Circle")
|
layout.operator("surface.primitive_nurbs_surface_circle_add", icon='SURFACE_NCIRCLE', text="NURBS Circle")
|
||||||
layout.operator("surface.primitive_nurbs_surface_surface_add", icon='SURFACE_NSURFACE', text="NURBS Surface")
|
layout.operator("surface.primitive_nurbs_surface_surface_add", icon='SURFACE_NSURFACE', text="NURBS Surface")
|
||||||
layout.operator("surface.primitive_nurbs_surface_tube_add", icon='SURFACE_NTUBE', text="NURBS Tube")
|
layout.operator("surface.primitive_nurbs_surface_cylinder_add", icon='SURFACE_NCYLINDER', text="NURBS Cylinder")
|
||||||
layout.operator("surface.primitive_nurbs_surface_sphere_add", icon='SURFACE_NSPHERE', text="NURBS Sphere")
|
layout.operator("surface.primitive_nurbs_surface_sphere_add", icon='SURFACE_NSPHERE', text="NURBS Sphere")
|
||||||
layout.operator("surface.primitive_nurbs_surface_donut_add", icon='SURFACE_NDONUT', text="NURBS Torus")
|
layout.operator("surface.primitive_nurbs_surface_torus_add", icon='SURFACE_NTORUS', text="NURBS Torus")
|
||||||
|
|
||||||
|
|
||||||
class INFO_MT_armature_add(bpy.types.Menu):
|
class INFO_MT_armature_add(bpy.types.Menu):
|
||||||
@@ -316,8 +316,10 @@ class INFO_MT_help(bpy.types.Menu):
|
|||||||
layout.separator()
|
layout.separator()
|
||||||
layout.operator("wm.url_open", text="Report a Bug", icon='URL').url = 'http://projects.blender.org/tracker/?atid=498&group_id=9&func=browse'
|
layout.operator("wm.url_open", text="Report a Bug", icon='URL').url = 'http://projects.blender.org/tracker/?atid=498&group_id=9&func=browse'
|
||||||
layout.separator()
|
layout.separator()
|
||||||
layout.operator("wm.url_open", text="Python API Reference", icon='URL').url = 'http://www.blender.org/documentation/250PythonDoc/contents.html'
|
layout.operator("wm.url_open", text="Python API Reference", icon='URL').url = "http://www.blender.org/documentation/blender_python_api_%s/contents.html" % "_".join(str(v) for v in bpy.app.version)
|
||||||
layout.operator("help.operator_cheat_sheet")
|
layout.operator("help.operator_cheat_sheet", icon='TEXT')
|
||||||
|
layout.separator()
|
||||||
|
layout.operator("anim.update_data_paths", text="FCurve/Driver 2.54 fix", icon='HELP')
|
||||||
layout.separator()
|
layout.separator()
|
||||||
layout.operator("wm.splash")
|
layout.operator("wm.splash")
|
||||||
|
|
||||||
|
|||||||
@@ -796,7 +796,7 @@ class USERPREF_PT_input(InputKeyMapPanel):
|
|||||||
#start = time.time()
|
#start = time.time()
|
||||||
|
|
||||||
userpref = context.user_preferences
|
userpref = context.user_preferences
|
||||||
wm = context.manager
|
wm = context.window_manager
|
||||||
|
|
||||||
inputs = userpref.inputs
|
inputs = userpref.inputs
|
||||||
|
|
||||||
@@ -980,7 +980,8 @@ class USERPREF_PT_addons(bpy.types.Panel):
|
|||||||
|
|
||||||
rowsub = row.row()
|
rowsub = row.row()
|
||||||
rowsub.active = is_enabled
|
rowsub.active = is_enabled
|
||||||
rowsub.label(text=info["name"], icon='ERROR' if info["warning"] else 'BLENDER')
|
rowsub.label(text='%s: %s' % (info['category'], info["name"]))
|
||||||
|
if info["warning"]: rowsub.label(icon='ERROR')
|
||||||
|
|
||||||
if is_enabled:
|
if is_enabled:
|
||||||
row.operator("wm.addon_disable", icon='CHECKBOX_HLT', text="", emboss=False).module = module_name
|
row.operator("wm.addon_disable", icon='CHECKBOX_HLT', text="", emboss=False).module = module_name
|
||||||
@@ -1004,7 +1005,7 @@ class USERPREF_PT_addons(bpy.types.Panel):
|
|||||||
if info["version"]:
|
if info["version"]:
|
||||||
split = colsub.row().split(percentage=0.15)
|
split = colsub.row().split(percentage=0.15)
|
||||||
split.label(text='Version:')
|
split.label(text='Version:')
|
||||||
split.label(text=info["version"])
|
split.label(text='.'.join([str(x) for x in info["version"]]))
|
||||||
if info["warning"]:
|
if info["warning"]:
|
||||||
split = colsub.row().split(percentage=0.15)
|
split = colsub.row().split(percentage=0.15)
|
||||||
split.label(text="Warning:")
|
split.label(text="Warning:")
|
||||||
@@ -1045,7 +1046,7 @@ class USERPREF_PT_addons(bpy.types.Panel):
|
|||||||
from bpy.props import *
|
from bpy.props import *
|
||||||
|
|
||||||
|
|
||||||
def addon_info_get(mod, info_basis={"name": "", "author": "", "version": "", "blender": "", "location": "", "description": "", "wiki_url": "", "tracker_url": "", "category": "", "warning": "", "show_expanded": False}):
|
def addon_info_get(mod, info_basis={"name": "", "author": "", "version": (), "blender": (), "api": 0, "location": "", "description": "", "wiki_url": "", "tracker_url": "", "category": "", "warning": "", "show_expanded": False}):
|
||||||
addon_info = getattr(mod, "bl_addon_info", {})
|
addon_info = getattr(mod, "bl_addon_info", {})
|
||||||
|
|
||||||
# avoid re-initializing
|
# avoid re-initializing
|
||||||
@@ -1189,7 +1190,7 @@ class WM_OT_addon_install(bpy.types.Operator):
|
|||||||
self.report({'ERROR'}, "No 'addons' path could be found in " + str(bpy.utils.script_paths()))
|
self.report({'ERROR'}, "No 'addons' path could be found in " + str(bpy.utils.script_paths()))
|
||||||
return {'CANCELLED'}
|
return {'CANCELLED'}
|
||||||
|
|
||||||
wm = context.manager
|
wm = context.window_manager
|
||||||
wm.add_fileselect(self)
|
wm.add_fileselect(self)
|
||||||
return {'RUNNING_MODAL'}
|
return {'RUNNING_MODAL'}
|
||||||
|
|
||||||
@@ -1225,4 +1226,4 @@ def unregister():
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
register()
|
register()
|
||||||
|
|||||||
@@ -138,10 +138,10 @@ class InputKeyMapPanel(bpy.types.Panel):
|
|||||||
self.draw_km(display_keymaps, kc, km, children, col, level)
|
self.draw_km(display_keymaps, kc, km, children, col, level)
|
||||||
|
|
||||||
'''
|
'''
|
||||||
km = kc.find_keymap(idname, space_type=spaceid, region_type=regionid)
|
km = kc.keymaps.find(idname, space_type=spaceid, region_type=regionid)
|
||||||
if not km:
|
if not km:
|
||||||
kc = defkc
|
kc = defkc
|
||||||
km = kc.find_keymap(idname, space_type=spaceid, region_type=regionid)
|
km = kc.keymaps.find(idname, space_type=spaceid, region_type=regionid)
|
||||||
|
|
||||||
if km:
|
if km:
|
||||||
self.draw_km(kc, km, children, col, level)
|
self.draw_km(kc, km, children, col, level)
|
||||||
@@ -161,7 +161,7 @@ class InputKeyMapPanel(bpy.types.Panel):
|
|||||||
def draw_km(self, display_keymaps, kc, km, children, layout, level):
|
def draw_km(self, display_keymaps, kc, km, children, layout, level):
|
||||||
km = km.active()
|
km = km.active()
|
||||||
|
|
||||||
layout.set_context_pointer("keymap", km)
|
layout.context_pointer_set("keymap", km)
|
||||||
|
|
||||||
col = self.indented_layout(layout, level)
|
col = self.indented_layout(layout, level)
|
||||||
|
|
||||||
@@ -211,6 +211,19 @@ class InputKeyMapPanel(bpy.types.Panel):
|
|||||||
for entry in children:
|
for entry in children:
|
||||||
self.draw_entry(display_keymaps, entry, col, level + 1)
|
self.draw_entry(display_keymaps, entry, col, level + 1)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def draw_kmi_properties(box, properties, title=None):
|
||||||
|
box.separator()
|
||||||
|
if title:
|
||||||
|
box.label(text=title)
|
||||||
|
flow = box.column_flow(columns=2)
|
||||||
|
for pname, value in properties.bl_rna.properties.items():
|
||||||
|
if pname != "rna_type" and not properties.is_property_hidden(pname):
|
||||||
|
if isinstance(value, bpy.types.OperatorProperties):
|
||||||
|
__class__.draw_kmi_properties(box, value, title=pname)
|
||||||
|
else:
|
||||||
|
flow.prop(properties, pname)
|
||||||
|
|
||||||
def draw_kmi(self, display_keymaps, kc, km, kmi, layout, level):
|
def draw_kmi(self, display_keymaps, kc, km, kmi, layout, level):
|
||||||
map_type = kmi.map_type
|
map_type = kmi.map_type
|
||||||
|
|
||||||
@@ -293,34 +306,22 @@ class InputKeyMapPanel(bpy.types.Panel):
|
|||||||
subrow.prop(kmi, "oskey", text="Cmd")
|
subrow.prop(kmi, "oskey", text="Cmd")
|
||||||
subrow.prop(kmi, "key_modifier", text="", event=True)
|
subrow.prop(kmi, "key_modifier", text="", event=True)
|
||||||
|
|
||||||
def display_properties(properties, title=None):
|
|
||||||
box.separator()
|
|
||||||
if title:
|
|
||||||
box.label(text=title)
|
|
||||||
flow = box.column_flow(columns=2)
|
|
||||||
for pname, value in properties.items():
|
|
||||||
if not properties.is_property_hidden(pname):
|
|
||||||
if isinstance(value, bpy.types.OperatorProperties):
|
|
||||||
display_properties(value, title=pname)
|
|
||||||
else:
|
|
||||||
flow.prop(properties, pname)
|
|
||||||
|
|
||||||
# Operator properties
|
# Operator properties
|
||||||
props = kmi.properties
|
props = kmi.properties
|
||||||
if props is not None:
|
if props is not None:
|
||||||
display_properties(props)
|
__class__.draw_kmi_properties(box, props)
|
||||||
|
|
||||||
# Modal key maps attached to this operator
|
# Modal key maps attached to this operator
|
||||||
if not km.is_modal:
|
if not km.is_modal:
|
||||||
kmm = kc.find_keymap_modal(kmi.idname)
|
kmm = kc.keymaps.find_modal(kmi.idname)
|
||||||
if kmm:
|
if kmm:
|
||||||
self.draw_km(display_keymaps, kc, kmm, None, layout, level + 1)
|
self.draw_km(display_keymaps, kc, kmm, None, layout, level + 1)
|
||||||
layout.set_context_pointer("keymap", km)
|
layout.context_pointer_set("keymap", km)
|
||||||
|
|
||||||
def draw_filtered(self, display_keymaps, filter_text, layout):
|
def draw_filtered(self, display_keymaps, filter_text, layout):
|
||||||
for km, kc in display_keymaps:
|
for km, kc in display_keymaps:
|
||||||
km = km.active()
|
km = km.active()
|
||||||
layout.set_context_pointer("keymap", km)
|
layout.context_pointer_set("keymap", km)
|
||||||
|
|
||||||
filtered_items = [kmi for kmi in km.items if filter_text in kmi.name.lower()]
|
filtered_items = [kmi for kmi in km.items if filter_text in kmi.name.lower()]
|
||||||
|
|
||||||
@@ -352,7 +353,7 @@ class InputKeyMapPanel(bpy.types.Panel):
|
|||||||
self.draw_entry(display_keymaps, entry, layout)
|
self.draw_entry(display_keymaps, entry, layout)
|
||||||
|
|
||||||
def draw_keymaps(self, context, layout):
|
def draw_keymaps(self, context, layout):
|
||||||
wm = context.manager
|
wm = context.window_manager
|
||||||
kc = wm.keyconfigs.active
|
kc = wm.keyconfigs.active
|
||||||
defkc = wm.keyconfigs.default
|
defkc = wm.keyconfigs.default
|
||||||
|
|
||||||
@@ -364,7 +365,7 @@ class InputKeyMapPanel(bpy.types.Panel):
|
|||||||
|
|
||||||
row = subcol.row()
|
row = subcol.row()
|
||||||
row.prop_search(wm.keyconfigs, "active", wm, "keyconfigs", text="Key Config:")
|
row.prop_search(wm.keyconfigs, "active", wm, "keyconfigs", text="Key Config:")
|
||||||
layout.set_context_pointer("keyconfig", wm.keyconfigs.active)
|
layout.context_pointer_set("keyconfig", wm.keyconfigs.active)
|
||||||
row.operator("wm.keyconfig_remove", text="", icon='X')
|
row.operator("wm.keyconfig_remove", text="", icon='X')
|
||||||
|
|
||||||
row.prop(context.space_data, "filter_text", icon="VIEWZOOM")
|
row.prop(context.space_data, "filter_text", icon="VIEWZOOM")
|
||||||
@@ -386,7 +387,7 @@ def export_properties(prefix, properties, lines=None):
|
|||||||
if lines is None:
|
if lines is None:
|
||||||
lines = []
|
lines = []
|
||||||
|
|
||||||
for value, pname in properties.items():
|
for pname, value in properties.items():
|
||||||
if not properties.is_property_hidden(pname):
|
if not properties.is_property_hidden(pname):
|
||||||
if isinstance(value, bpy.types.OperatorProperties):
|
if isinstance(value, bpy.types.OperatorProperties):
|
||||||
export_properties(prefix + "." + pname, value, lines)
|
export_properties(prefix + "." + pname, value, lines)
|
||||||
@@ -407,9 +408,9 @@ class WM_OT_keyconfig_test(bpy.types.Operator):
|
|||||||
|
|
||||||
def kmistr(kmi):
|
def kmistr(kmi):
|
||||||
if km.is_modal:
|
if km.is_modal:
|
||||||
s = ["kmi = km.items.add_modal(\'%s\', \'%s\', \'%s\'" % (kmi.propvalue, kmi.type, kmi.value)]
|
s = ["kmi = km.items.new_modal(\'%s\', \'%s\', \'%s\'" % (kmi.propvalue, kmi.type, kmi.value)]
|
||||||
else:
|
else:
|
||||||
s = ["kmi = km.items.add(\'%s\', \'%s\', \'%s\'" % (kmi.idname, kmi.type, kmi.value)]
|
s = ["kmi = km.items.new(\'%s\', \'%s\', \'%s\'" % (kmi.idname, kmi.type, kmi.value)]
|
||||||
|
|
||||||
if kmi.any:
|
if kmi.any:
|
||||||
s.append(", any=True")
|
s.append(", any=True")
|
||||||
@@ -436,7 +437,7 @@ class WM_OT_keyconfig_test(bpy.types.Operator):
|
|||||||
|
|
||||||
idname, spaceid, regionid, children = entry
|
idname, spaceid, regionid, children = entry
|
||||||
|
|
||||||
km = kc.find_keymap(idname, space_type=spaceid, region_type=regionid)
|
km = kc.keymaps.find(idname, space_type=spaceid, region_type=regionid)
|
||||||
|
|
||||||
if km:
|
if km:
|
||||||
km = km.active()
|
km = km.active()
|
||||||
@@ -485,7 +486,7 @@ class WM_OT_keyconfig_test(bpy.types.Operator):
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
wm = context.manager
|
wm = context.window_manager
|
||||||
kc = wm.keyconfigs.default
|
kc = wm.keyconfigs.default
|
||||||
|
|
||||||
if self.testConfig(kc):
|
if self.testConfig(kc):
|
||||||
@@ -528,8 +529,8 @@ class WM_OT_keyconfig_import(bpy.types.Operator):
|
|||||||
|
|
||||||
config_name = None
|
config_name = None
|
||||||
for line in f:
|
for line in f:
|
||||||
if line.startswith("kc = wm.add_keyconfig("):
|
if line.startswith("kc = wm.keyconfigs.new("):
|
||||||
config_name = line[23:-3]
|
config_name = line[24:-3]
|
||||||
break
|
break
|
||||||
|
|
||||||
if config_name is None:
|
if config_name is None:
|
||||||
@@ -551,23 +552,23 @@ class WM_OT_keyconfig_import(bpy.types.Operator):
|
|||||||
shutil.move(self.properties.filepath, path)
|
shutil.move(self.properties.filepath, path)
|
||||||
|
|
||||||
# sneaky way to check we're actually running the code.
|
# sneaky way to check we're actually running the code.
|
||||||
wm = context.manager
|
wm = context.window_manager
|
||||||
while config_name in wm.keyconfigs:
|
while config_name in wm.keyconfigs:
|
||||||
wm.remove_keyconfig(wm.keyconfigs[config_name])
|
wm.keyconfigs.remove(wm.keyconfigs[config_name])
|
||||||
|
|
||||||
wm = context.manager
|
wm = context.window_manager
|
||||||
totmap = len(wm.keyconfigs)
|
totmap = len(wm.keyconfigs)
|
||||||
mod = __import__(config_name)
|
mod = __import__(config_name)
|
||||||
if totmap == len(wm.keyconfigs):
|
if totmap == len(wm.keyconfigs):
|
||||||
reload(mod)
|
reload(mod)
|
||||||
|
|
||||||
wm = bpy.context.manager
|
wm = bpy.context.window_manager
|
||||||
wm.keyconfigs.active = wm.keyconfigs[config_name]
|
wm.keyconfigs.active = wm.keyconfigs[config_name]
|
||||||
|
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
def invoke(self, context, event):
|
def invoke(self, context, event):
|
||||||
wm = context.manager
|
wm = context.window_manager
|
||||||
wm.add_fileselect(self)
|
wm.add_fileselect(self)
|
||||||
return {'RUNNING_MODAL'}
|
return {'RUNNING_MODAL'}
|
||||||
|
|
||||||
@@ -593,7 +594,7 @@ class WM_OT_keyconfig_export(bpy.types.Operator):
|
|||||||
if not f:
|
if not f:
|
||||||
raise Exception("Could not open file")
|
raise Exception("Could not open file")
|
||||||
|
|
||||||
wm = context.manager
|
wm = context.window_manager
|
||||||
kc = wm.keyconfigs.active
|
kc = wm.keyconfigs.active
|
||||||
|
|
||||||
if self.properties.kc_name != '':
|
if self.properties.kc_name != '':
|
||||||
@@ -606,8 +607,8 @@ class WM_OT_keyconfig_export(bpy.types.Operator):
|
|||||||
f.write("# Configuration %s\n" % name)
|
f.write("# Configuration %s\n" % name)
|
||||||
|
|
||||||
f.write("import bpy\n\n")
|
f.write("import bpy\n\n")
|
||||||
f.write("wm = bpy.context.manager\n")
|
f.write("wm = bpy.context.window_manager\n")
|
||||||
f.write("kc = wm.add_keyconfig('%s')\n\n" % name)
|
f.write("kc = wm.keyconfigs.new('%s')\n\n" % name)
|
||||||
|
|
||||||
# Generate a list of keymaps to export:
|
# Generate a list of keymaps to export:
|
||||||
#
|
#
|
||||||
@@ -633,12 +634,12 @@ class WM_OT_keyconfig_export(bpy.types.Operator):
|
|||||||
km = km.active()
|
km = km.active()
|
||||||
|
|
||||||
f.write("# Map %s\n" % km.name)
|
f.write("# Map %s\n" % km.name)
|
||||||
f.write("km = kc.add_keymap('%s', space_type='%s', region_type='%s', modal=%s)\n\n" % (km.name, km.space_type, km.region_type, km.is_modal))
|
f.write("km = kc.keymaps.new('%s', space_type='%s', region_type='%s', modal=%s)\n\n" % (km.name, km.space_type, km.region_type, km.is_modal))
|
||||||
for kmi in km.items:
|
for kmi in km.items:
|
||||||
if km.is_modal:
|
if km.is_modal:
|
||||||
f.write("kmi = km.items.add_modal('%s', '%s', '%s'" % (kmi.propvalue, kmi.type, kmi.value))
|
f.write("kmi = km.items.new_modal('%s', '%s', '%s'" % (kmi.propvalue, kmi.type, kmi.value))
|
||||||
else:
|
else:
|
||||||
f.write("kmi = km.items.add('%s', '%s', '%s'" % (kmi.idname, kmi.type, kmi.value))
|
f.write("kmi = km.items.new('%s', '%s', '%s'" % (kmi.idname, kmi.type, kmi.value))
|
||||||
if kmi.any:
|
if kmi.any:
|
||||||
f.write(", any=True")
|
f.write(", any=True")
|
||||||
else:
|
else:
|
||||||
@@ -666,7 +667,7 @@ class WM_OT_keyconfig_export(bpy.types.Operator):
|
|||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
def invoke(self, context, event):
|
def invoke(self, context, event):
|
||||||
wm = context.manager
|
wm = context.window_manager
|
||||||
wm.add_fileselect(self)
|
wm.add_fileselect(self)
|
||||||
return {'RUNNING_MODAL'}
|
return {'RUNNING_MODAL'}
|
||||||
|
|
||||||
@@ -677,7 +678,7 @@ class WM_OT_keymap_edit(bpy.types.Operator):
|
|||||||
bl_label = "Edit Key Map"
|
bl_label = "Edit Key Map"
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
wm = context.manager
|
wm = context.window_manager
|
||||||
km = context.keymap
|
km = context.keymap
|
||||||
km.copy_to_user()
|
km.copy_to_user()
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
@@ -691,7 +692,7 @@ class WM_OT_keymap_restore(bpy.types.Operator):
|
|||||||
all = BoolProperty(attr="all", name="All Keymaps", description="Restore all keymaps to default")
|
all = BoolProperty(attr="all", name="All Keymaps", description="Restore all keymaps to default")
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
wm = context.manager
|
wm = context.window_manager
|
||||||
|
|
||||||
if self.properties.all:
|
if self.properties.all:
|
||||||
for km in wm.keyconfigs.default.keymaps:
|
for km in wm.keyconfigs.default.keymaps:
|
||||||
@@ -711,9 +712,9 @@ class WM_OT_keyitem_restore(bpy.types.Operator):
|
|||||||
item_id = IntProperty(attr="item_id", name="Item Identifier", description="Identifier of the item to remove")
|
item_id = IntProperty(attr="item_id", name="Item Identifier", description="Identifier of the item to remove")
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
wm = context.manager
|
wm = context.window_manager
|
||||||
km = context.keymap
|
km = context.keymap
|
||||||
kmi = km.item_from_id(self.properties.item_id)
|
kmi = km.items.from_id(self.properties.item_id)
|
||||||
|
|
||||||
km.restore_item_to_default(kmi)
|
km.restore_item_to_default(kmi)
|
||||||
|
|
||||||
@@ -726,14 +727,14 @@ class WM_OT_keyitem_add(bpy.types.Operator):
|
|||||||
bl_label = "Add Key Map Item"
|
bl_label = "Add Key Map Item"
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
wm = context.manager
|
wm = context.window_manager
|
||||||
km = context.keymap
|
km = context.keymap
|
||||||
kc = wm.keyconfigs.default
|
kc = wm.keyconfigs.default
|
||||||
|
|
||||||
if km.is_modal:
|
if km.is_modal:
|
||||||
km.items.add_modal("", 'A', 'PRESS') # kmi
|
km.items.new_modal("", 'A', 'PRESS') # kmi
|
||||||
else:
|
else:
|
||||||
km.items.add("none", 'A', 'PRESS') # kmi
|
km.items.new("none", 'A', 'PRESS') # kmi
|
||||||
|
|
||||||
# clear filter and expand keymap so we can see the newly added item
|
# clear filter and expand keymap so we can see the newly added item
|
||||||
if context.space_data.filter_text != "":
|
if context.space_data.filter_text != "":
|
||||||
@@ -752,10 +753,10 @@ class WM_OT_keyitem_remove(bpy.types.Operator):
|
|||||||
item_id = IntProperty(attr="item_id", name="Item Identifier", description="Identifier of the item to remove")
|
item_id = IntProperty(attr="item_id", name="Item Identifier", description="Identifier of the item to remove")
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
wm = context.manager
|
wm = context.window_manager
|
||||||
km = context.keymap
|
km = context.keymap
|
||||||
kmi = km.item_from_id(self.properties.item_id)
|
kmi = km.items.from_id(self.properties.item_id)
|
||||||
km.remove_item(kmi)
|
km.items.remove(kmi)
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
@@ -766,12 +767,12 @@ class WM_OT_keyconfig_remove(bpy.types.Operator):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def poll(cls, context):
|
def poll(cls, context):
|
||||||
wm = context.manager
|
wm = context.window_manager
|
||||||
return wm.keyconfigs.active.is_user_defined
|
return wm.keyconfigs.active.is_user_defined
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
import sys
|
import sys
|
||||||
wm = context.manager
|
wm = context.window_manager
|
||||||
|
|
||||||
keyconfig = wm.keyconfigs.active
|
keyconfig = wm.keyconfigs.active
|
||||||
|
|
||||||
@@ -787,7 +788,7 @@ class WM_OT_keyconfig_remove(bpy.types.Operator):
|
|||||||
if os.path.exists(path):
|
if os.path.exists(path):
|
||||||
os.remove(path)
|
os.remove(path)
|
||||||
|
|
||||||
wm.remove_keyconfig(keyconfig)
|
wm.keyconfigs.remove(keyconfig)
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
def register():
|
def register():
|
||||||
|
|||||||
133
release/test/rna_info_dump.py
Normal file
133
release/test/rna_info_dump.py
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
# ##### BEGIN GPL LICENSE BLOCK #####
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software Foundation,
|
||||||
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
#
|
||||||
|
# ##### END GPL LICENSE BLOCK #####
|
||||||
|
|
||||||
|
# <pep8 compliant>
|
||||||
|
|
||||||
|
# Used for generating API diff's between releases
|
||||||
|
# ./blender.bin --background --python release/test/rna_info_dump.py
|
||||||
|
|
||||||
|
import bpy
|
||||||
|
|
||||||
|
def api_dump(use_properties=True, use_functions=True):
|
||||||
|
|
||||||
|
def prop_type(prop):
|
||||||
|
if prop.type == "pointer":
|
||||||
|
return prop.fixed_type.identifier
|
||||||
|
else:
|
||||||
|
return prop.type
|
||||||
|
|
||||||
|
def func_to_str(struct_id_str, func_id, func):
|
||||||
|
|
||||||
|
args = []
|
||||||
|
for prop in func.args:
|
||||||
|
data_str = "%s %s" % (prop_type(prop), prop.identifier)
|
||||||
|
if prop.array_length:
|
||||||
|
data_str += "[%d]" % prop.array_length
|
||||||
|
if not prop.is_required:
|
||||||
|
data_str += "=%s" % prop.default_str
|
||||||
|
args.append(data_str)
|
||||||
|
|
||||||
|
|
||||||
|
data_str = "%s.%s(%s)" % (struct_id_str, func_id, ", ".join(args))
|
||||||
|
if func.return_values:
|
||||||
|
return_args = ", ".join([prop_type(arg) for arg in func.return_values])
|
||||||
|
if len(func.return_values) > 1:
|
||||||
|
data_str += " --> (%s)" % return_args
|
||||||
|
else:
|
||||||
|
data_str += " --> %s" % return_args
|
||||||
|
return data_str
|
||||||
|
|
||||||
|
|
||||||
|
def prop_to_str(struct_id_str, prop_id, prop):
|
||||||
|
|
||||||
|
prop_str = " <-- %s" % prop_type(prop)
|
||||||
|
if prop.array_length:
|
||||||
|
prop_str += "[%d]" % prop.array_length
|
||||||
|
|
||||||
|
data_str = "%s.%s %s" % (struct_id_str, prop_id, prop_str)
|
||||||
|
return data_str
|
||||||
|
|
||||||
|
def struct_full_id(v):
|
||||||
|
struct_id_str = v.identifier # "".join(sid for sid in struct_id if struct_id)
|
||||||
|
|
||||||
|
for base in v.get_bases():
|
||||||
|
struct_id_str = base.identifier + "|" + struct_id_str
|
||||||
|
|
||||||
|
return struct_id_str
|
||||||
|
|
||||||
|
|
||||||
|
def dump_funcs():
|
||||||
|
data = []
|
||||||
|
for struct_id, v in sorted(struct.items()):
|
||||||
|
struct_id_str = struct_full_id(v)
|
||||||
|
|
||||||
|
funcs = [(func.identifier, func) for func in v.functions]
|
||||||
|
|
||||||
|
for func_id, func in funcs:
|
||||||
|
data.append(func_to_str(struct_id_str, func_id, func))
|
||||||
|
|
||||||
|
for prop in v.properties:
|
||||||
|
if prop.collection_type:
|
||||||
|
funcs = [(prop.identifier + "." + func.identifier, func) for func in prop.collection_type.functions]
|
||||||
|
for func_id, func in funcs:
|
||||||
|
data.append(func_to_str(struct_id_str, func_id, func))
|
||||||
|
data.sort()
|
||||||
|
data.append("# * functions *")
|
||||||
|
return data
|
||||||
|
|
||||||
|
def dump_props():
|
||||||
|
data = []
|
||||||
|
for struct_id, v in sorted(struct.items()):
|
||||||
|
struct_id_str = struct_full_id(v)
|
||||||
|
|
||||||
|
props = [(prop.identifier, prop) for prop in v.properties]
|
||||||
|
|
||||||
|
for prop_id, prop in props:
|
||||||
|
data.append(prop_to_str(struct_id_str, prop_id, prop))
|
||||||
|
|
||||||
|
for prop in v.properties:
|
||||||
|
if prop.collection_type:
|
||||||
|
props = [(prop.identifier + "." + prop_sub.identifier, prop_sub) for prop_sub in prop.collection_type.properties]
|
||||||
|
for prop_sub_id, prop_sub in props:
|
||||||
|
data.append(prop_to_str(struct_id_str, prop_sub_id, prop_sub))
|
||||||
|
data.sort()
|
||||||
|
data.insert(0, "# * properties *")
|
||||||
|
return data
|
||||||
|
|
||||||
|
import rna_info
|
||||||
|
struct = rna_info.BuildRNAInfo()[0]
|
||||||
|
data = []
|
||||||
|
|
||||||
|
if use_functions:
|
||||||
|
data.extend(dump_funcs())
|
||||||
|
|
||||||
|
if use_properties:
|
||||||
|
data.extend(dump_props())
|
||||||
|
|
||||||
|
if bpy.app.background:
|
||||||
|
import sys
|
||||||
|
sys.stderr.write("\n".join(data))
|
||||||
|
sys.stderr.write("\n\nEOF\n")
|
||||||
|
else:
|
||||||
|
text = bpy.data.texts.new(name="api.py")
|
||||||
|
text.from_string(data)
|
||||||
|
|
||||||
|
print("END")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
api_dump()
|
||||||
@@ -2,13 +2,13 @@
|
|||||||
Import ('env')
|
Import ('env')
|
||||||
|
|
||||||
SConscript(['blender/SConscript',
|
SConscript(['blender/SConscript',
|
||||||
'kernel/SConscript',
|
'kernel/SConscript',
|
||||||
'creator/SConscript'])
|
'creator/SConscript'])
|
||||||
if env['WITH_BF_GAMEENGINE']:
|
if env['WITH_BF_GAMEENGINE']:
|
||||||
SConscript (['gameengine/SConscript'])
|
SConscript (['gameengine/SConscript'])
|
||||||
|
|
||||||
if env['WITH_BF_PLAYER']:
|
if env['WITH_BF_PLAYER']:
|
||||||
SConscript (['blenderplayer/bad_level_call_stubs/SConscript'])
|
SConscript (['blenderplayer/bad_level_call_stubs/SConscript'])
|
||||||
|
|
||||||
if env['OURPLATFORM'] in ('win64-vc', 'win32-vc', 'win32-mingw', 'linuxcross'):
|
if env['OURPLATFORM'] in ('win64-vc', 'win32-vc', 'win32-mingw', 'linuxcross'):
|
||||||
SConscript (['icons/SConscript'])
|
SConscript (['icons/SConscript'])
|
||||||
|
|||||||
@@ -27,7 +27,8 @@
|
|||||||
FILE(GLOB SRC intern/*.c)
|
FILE(GLOB SRC intern/*.c)
|
||||||
|
|
||||||
SET(INC
|
SET(INC
|
||||||
. ../../../intern/guardedalloc
|
.
|
||||||
|
../../../intern/guardedalloc
|
||||||
${JPEG_INC}
|
${JPEG_INC}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -24,14 +24,19 @@
|
|||||||
|
|
||||||
FILE(GLOB SRC intern/*.c)
|
FILE(GLOB SRC intern/*.c)
|
||||||
|
|
||||||
SET(INC
|
SET(INC
|
||||||
../../../intern/guardedalloc ../blenlib ../makesdna ../editors/include
|
.
|
||||||
../blenkernel ../../../extern/glew/include .
|
../blenlib
|
||||||
|
../makesdna
|
||||||
|
../editors/include
|
||||||
|
../blenkernel
|
||||||
|
../../../intern/guardedalloc
|
||||||
|
../../../extern/glew/include
|
||||||
${FREETYPE_INCLUDE_DIRS}
|
${FREETYPE_INCLUDE_DIRS}
|
||||||
)
|
)
|
||||||
|
|
||||||
IF(WITH_INTERNATIONAL)
|
IF(WITH_INTERNATIONAL)
|
||||||
SET(INC ${INC} ${GETTEXT_INC})
|
LIST(APPEND INC ${GETTEXT_INC})
|
||||||
ADD_DEFINITIONS(-DINTERNATIONAL)
|
ADD_DEFINITIONS(-DINTERNATIONAL)
|
||||||
ENDIF(WITH_INTERNATIONAL)
|
ENDIF(WITH_INTERNATIONAL)
|
||||||
|
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ incs += ' ' + env['BF_GETTEXT_INC']
|
|||||||
defs = []
|
defs = []
|
||||||
|
|
||||||
if sys.platform == 'win32' or env['OURPLATFORM'] == 'linuxcross':
|
if sys.platform == 'win32' or env['OURPLATFORM'] == 'linuxcross':
|
||||||
defs.append('_WIN32')
|
defs.append('_WIN32')
|
||||||
defs.append('USE_GETTEXT_DLL')
|
defs.append('USE_GETTEXT_DLL')
|
||||||
|
|
||||||
if env['WITH_BF_INTERNATIONAL']:
|
if env['WITH_BF_INTERNATIONAL']:
|
||||||
defs.append('INTERNATIONAL')
|
defs.append('INTERNATIONAL')
|
||||||
|
|||||||
@@ -57,6 +57,9 @@ void automatname(struct Material *);
|
|||||||
|
|
||||||
struct Material ***give_matarar(struct Object *ob);
|
struct Material ***give_matarar(struct Object *ob);
|
||||||
short *give_totcolp(struct Object *ob);
|
short *give_totcolp(struct Object *ob);
|
||||||
|
struct Material ***give_matarar_id(struct ID *id); /* same but for ID's */
|
||||||
|
short *give_totcolp_id(struct ID *id);
|
||||||
|
|
||||||
struct Material *give_current_material(struct Object *ob, int act);
|
struct Material *give_current_material(struct Object *ob, int act);
|
||||||
struct ID *material_from(struct Object *ob, int act);
|
struct ID *material_from(struct Object *ob, int act);
|
||||||
void assign_material(struct Object *ob, struct Material *ma, int act);
|
void assign_material(struct Object *ob, struct Material *ma, int act);
|
||||||
@@ -67,6 +70,10 @@ int find_material_index(struct Object *ob, struct Material *ma);
|
|||||||
int object_add_material_slot(struct Object *ob);
|
int object_add_material_slot(struct Object *ob);
|
||||||
int object_remove_material_slot(struct Object *ob);
|
int object_remove_material_slot(struct Object *ob);
|
||||||
|
|
||||||
|
/* rna api */
|
||||||
|
void material_append_id(struct ID *id, struct Material *ma);
|
||||||
|
struct Material *material_pop_id(struct ID *id, int index);
|
||||||
|
|
||||||
/* rendering */
|
/* rendering */
|
||||||
|
|
||||||
void init_render_material(struct Material *, int, float *);
|
void init_render_material(struct Material *, int, float *);
|
||||||
|
|||||||
@@ -253,6 +253,7 @@ ParticleThread *psys_threads_create(struct ParticleSimulationData *sim);
|
|||||||
void psys_threads_free(ParticleThread *threads);
|
void psys_threads_free(ParticleThread *threads);
|
||||||
|
|
||||||
void psys_make_billboard(ParticleBillboardData *bb, float xvec[3], float yvec[3], float zvec[3], float center[3]);
|
void psys_make_billboard(ParticleBillboardData *bb, float xvec[3], float yvec[3], float zvec[3], float center[3]);
|
||||||
|
void psys_apply_hair_lattice(struct Scene *scene, struct Object *ob, struct ParticleSystem *psys);
|
||||||
|
|
||||||
/* particle_system.c */
|
/* particle_system.c */
|
||||||
struct ParticleSystem *psys_get_target_system(struct Object *ob, struct ParticleTarget *pt);
|
struct ParticleSystem *psys_get_target_system(struct Object *ob, struct ParticleTarget *pt);
|
||||||
@@ -282,6 +283,8 @@ void psys_mat_hair_to_object(struct Object *ob, struct DerivedMesh *dm, short fr
|
|||||||
void psys_mat_hair_to_global(struct Object *ob, struct DerivedMesh *dm, short from, struct ParticleData *pa, float hairmat[][4]);
|
void psys_mat_hair_to_global(struct Object *ob, struct DerivedMesh *dm, short from, struct ParticleData *pa, float hairmat[][4]);
|
||||||
void psys_mat_hair_to_orco(struct Object *ob, struct DerivedMesh *dm, short from, struct ParticleData *pa, float hairmat[][4]);
|
void psys_mat_hair_to_orco(struct Object *ob, struct DerivedMesh *dm, short from, struct ParticleData *pa, float hairmat[][4]);
|
||||||
|
|
||||||
|
float psys_get_dietime_from_cache(struct PointCache *cache, int index);
|
||||||
|
|
||||||
void psys_free_pdd(struct ParticleSystem *psys);
|
void psys_free_pdd(struct ParticleSystem *psys);
|
||||||
|
|
||||||
float *psys_cache_vgroup(struct DerivedMesh *dm, struct ParticleSystem *psys, int vgroup);
|
float *psys_cache_vgroup(struct DerivedMesh *dm, struct ParticleSystem *psys, int vgroup);
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ struct Tex *add_texture(const char *name);
|
|||||||
void tex_set_type(struct Tex *tex, int type);
|
void tex_set_type(struct Tex *tex, int type);
|
||||||
void default_mtex(struct MTex *mtex);
|
void default_mtex(struct MTex *mtex);
|
||||||
struct MTex *add_mtex(void);
|
struct MTex *add_mtex(void);
|
||||||
|
struct MTex *add_mtex_id(struct ID *id, int slot);
|
||||||
struct Tex *copy_texture(struct Tex *tex);
|
struct Tex *copy_texture(struct Tex *tex);
|
||||||
void make_local_texture(struct Tex *tex);
|
void make_local_texture(struct Tex *tex);
|
||||||
void autotexname(struct Tex *tex);
|
void autotexname(struct Tex *tex);
|
||||||
|
|||||||
@@ -27,13 +27,30 @@
|
|||||||
FILE(GLOB SRC intern/*.c)
|
FILE(GLOB SRC intern/*.c)
|
||||||
|
|
||||||
SET(INC
|
SET(INC
|
||||||
. ../../../intern/guardedalloc ../../../intern/memutil ../editors/include ../blenlib ../makesdna ../modifiers
|
.
|
||||||
../render/extern/include ../../../intern/decimation/extern
|
../avi
|
||||||
../imbuf ../avi ../../../intern/elbeem/extern ../../../intern/opennl/extern
|
../blenlib
|
||||||
../../../intern/iksolver/extern ../blenloader ../ikplugin ../freestyle
|
../blenloader
|
||||||
../nodes ../../../extern/glew/include ../gpu ../makesrna ../../../intern/smoke/extern
|
../editors/include
|
||||||
../../../intern/bsp/extern ../blenfont
|
../freestyle
|
||||||
|
../gpu
|
||||||
|
../ikplugin
|
||||||
|
../imbuf
|
||||||
|
../makesdna
|
||||||
|
../makesrna
|
||||||
|
../modifiers
|
||||||
|
../nodes
|
||||||
|
../render/extern/include
|
||||||
|
../../../extern/glew/include
|
||||||
../../../intern/audaspace/intern
|
../../../intern/audaspace/intern
|
||||||
|
../../../intern/bsp/extern ../blenfont
|
||||||
|
../../../intern/decimation/extern
|
||||||
|
../../../intern/elbeem/extern
|
||||||
|
../../../intern/guardedalloc
|
||||||
|
../../../intern/iksolver/extern
|
||||||
|
../../../intern/memutil
|
||||||
|
../../../intern/opennl/extern
|
||||||
|
../../../intern/smoke/extern
|
||||||
../../../source/blender/windowmanager # XXX - BAD LEVEL CALL WM_api.h
|
../../../source/blender/windowmanager # XXX - BAD LEVEL CALL WM_api.h
|
||||||
${ZLIB_INC}
|
${ZLIB_INC}
|
||||||
)
|
)
|
||||||
@@ -42,7 +59,7 @@ SET(INC
|
|||||||
ADD_DEFINITIONS(-DGLEW_STATIC)
|
ADD_DEFINITIONS(-DGLEW_STATIC)
|
||||||
|
|
||||||
IF(WITH_BULLET)
|
IF(WITH_BULLET)
|
||||||
SET(INC ${INC} ../../../extern/bullet2/src)
|
LIST(APPEND INC ../../../extern/bullet2/src)
|
||||||
ADD_DEFINITIONS(-DUSE_BULLET)
|
ADD_DEFINITIONS(-DUSE_BULLET)
|
||||||
ENDIF(WITH_BULLET)
|
ENDIF(WITH_BULLET)
|
||||||
|
|
||||||
@@ -71,22 +88,24 @@ IF(WITH_IMAGE_HDR)
|
|||||||
ENDIF(WITH_IMAGE_HDR)
|
ENDIF(WITH_IMAGE_HDR)
|
||||||
|
|
||||||
IF(WITH_QUICKTIME)
|
IF(WITH_QUICKTIME)
|
||||||
SET(INC ${INC} ../quicktime ${QUICKTIME_INC})
|
LIST(APPEND INC ../quicktime)
|
||||||
|
LIST(APPEND INC ${QUICKTIME_INC})
|
||||||
ADD_DEFINITIONS(-DWITH_QUICKTIME)
|
ADD_DEFINITIONS(-DWITH_QUICKTIME)
|
||||||
ENDIF(WITH_QUICKTIME)
|
ENDIF(WITH_QUICKTIME)
|
||||||
|
|
||||||
IF(WITH_FFMPEG)
|
IF(WITH_FFMPEG)
|
||||||
SET(INC ${INC} ${FFMPEG_INC})
|
LIST(APPEND INC ${FFMPEG_INC})
|
||||||
ADD_DEFINITIONS(-DWITH_FFMPEG)
|
ADD_DEFINITIONS(-DWITH_FFMPEG)
|
||||||
ENDIF(WITH_FFMPEG)
|
ENDIF(WITH_FFMPEG)
|
||||||
|
|
||||||
IF(WITH_LCMS)
|
IF(WITH_LCMS)
|
||||||
SET(INC ${INC} ${LCMS_INCLUDE_DIR})
|
LIST(APPEND INC ${LCMS_INCLUDE_DIR})
|
||||||
ADD_DEFINITIONS(-DWITH_LCMS)
|
ADD_DEFINITIONS(-DWITH_LCMS)
|
||||||
ENDIF(WITH_LCMS)
|
ENDIF(WITH_LCMS)
|
||||||
|
|
||||||
IF(WITH_PYTHON)
|
IF(WITH_PYTHON)
|
||||||
SET(INC ${INC} ../python ${PYTHON_INC})
|
LIST(APPEND INC ../python)
|
||||||
|
LIST(APPEND INC ${PYTHON_INC})
|
||||||
ELSE(WITH_PYTHON)
|
ELSE(WITH_PYTHON)
|
||||||
ADD_DEFINITIONS(-DDISABLE_PYTHON)
|
ADD_DEFINITIONS(-DDISABLE_PYTHON)
|
||||||
ENDIF(WITH_PYTHON)
|
ENDIF(WITH_PYTHON)
|
||||||
@@ -100,18 +119,17 @@ IF(NOT WITH_FLUID)
|
|||||||
ENDIF(NOT WITH_FLUID)
|
ENDIF(NOT WITH_FLUID)
|
||||||
|
|
||||||
IF(WITH_LZO)
|
IF(WITH_LZO)
|
||||||
SET(INC ${INC} ../../../extern/lzo/minilzo)
|
LIST(APPEND INC ../../../extern/lzo/minilzo)
|
||||||
ADD_DEFINITIONS(-DWITH_LZO)
|
ADD_DEFINITIONS(-DWITH_LZO)
|
||||||
ENDIF(WITH_LZO)
|
ENDIF(WITH_LZO)
|
||||||
|
|
||||||
IF(WITH_LZMA)
|
IF(WITH_LZMA)
|
||||||
SET(INC ${INC} ../../../extern/lzma)
|
LIST(APPEND INC ../../../extern/lzma)
|
||||||
ADD_DEFINITIONS(-DWITH_LZMA)
|
ADD_DEFINITIONS(-DWITH_LZMA)
|
||||||
ENDIF(WITH_LZMA)
|
ENDIF(WITH_LZMA)
|
||||||
|
|
||||||
IF(WIN32)
|
IF(WIN32)
|
||||||
SET(INC ${INC} ${PTHREADS_INC})
|
LIST(APPEND INC ${PTHREADS_INC})
|
||||||
ENDIF(WIN32)
|
ENDIF(WIN32)
|
||||||
|
|
||||||
BLENDERLIB(bf_blenkernel "${SRC}" "${INC}")
|
BLENDERLIB(bf_blenkernel "${SRC}" "${INC}")
|
||||||
|
|
||||||
|
|||||||
@@ -20,68 +20,68 @@ incs += ' ' + env['BF_ZLIB_INC']
|
|||||||
defs = [ 'GLEW_STATIC' ]
|
defs = [ 'GLEW_STATIC' ]
|
||||||
|
|
||||||
if not env['WITH_BF_PYTHON']:
|
if not env['WITH_BF_PYTHON']:
|
||||||
defs.append('DISABLE_PYTHON')
|
defs.append('DISABLE_PYTHON')
|
||||||
else:
|
else:
|
||||||
incs += ' ../python'
|
incs += ' ../python'
|
||||||
incs += ' ' + env['BF_PYTHON_INC']
|
incs += ' ' + env['BF_PYTHON_INC']
|
||||||
if env['BF_DEBUG']:
|
if env['BF_DEBUG']:
|
||||||
defs.append('_DEBUG')
|
defs.append('_DEBUG')
|
||||||
|
|
||||||
if env['WITH_BF_QUICKTIME']:
|
if env['WITH_BF_QUICKTIME']:
|
||||||
incs += ' ../quicktime'
|
incs += ' ../quicktime'
|
||||||
|
|
||||||
if env['WITH_BF_SDL']:
|
if env['WITH_BF_SDL']:
|
||||||
incs += ' ' + env['BF_SDL_INC']
|
incs += ' ' + env['BF_SDL_INC']
|
||||||
else:
|
else:
|
||||||
defs.append('DISABLE_SDL')
|
defs.append('DISABLE_SDL')
|
||||||
|
|
||||||
if env['WITH_BF_OPENEXR']:
|
if env['WITH_BF_OPENEXR']:
|
||||||
defs.append('WITH_OPENEXR')
|
defs.append('WITH_OPENEXR')
|
||||||
|
|
||||||
if env['WITH_BF_TIFF']:
|
if env['WITH_BF_TIFF']:
|
||||||
defs.append('WITH_TIFF')
|
defs.append('WITH_TIFF')
|
||||||
|
|
||||||
if env['WITH_BF_OPENJPEG']:
|
if env['WITH_BF_OPENJPEG']:
|
||||||
defs.append('WITH_OPENJPEG')
|
defs.append('WITH_OPENJPEG')
|
||||||
|
|
||||||
if env['WITH_BF_DDS']:
|
if env['WITH_BF_DDS']:
|
||||||
defs.append('WITH_DDS')
|
defs.append('WITH_DDS')
|
||||||
|
|
||||||
if env['WITH_BF_CINEON']:
|
if env['WITH_BF_CINEON']:
|
||||||
defs.append('WITH_CINEON')
|
defs.append('WITH_CINEON')
|
||||||
|
|
||||||
if env['WITH_BF_HDR']:
|
if env['WITH_BF_HDR']:
|
||||||
defs.append('WITH_HDR')
|
defs.append('WITH_HDR')
|
||||||
|
|
||||||
if env['WITH_BF_FFMPEG']:
|
if env['WITH_BF_FFMPEG']:
|
||||||
defs.append('WITH_FFMPEG')
|
defs.append('WITH_FFMPEG')
|
||||||
incs += ' ' + env['BF_FFMPEG_INC']
|
incs += ' ' + env['BF_FFMPEG_INC']
|
||||||
|
|
||||||
if env['WITH_BF_QUICKTIME']:
|
if env['WITH_BF_QUICKTIME']:
|
||||||
defs.append('WITH_QUICKTIME')
|
defs.append('WITH_QUICKTIME')
|
||||||
incs += ' ' + env['BF_QUICKTIME_INC']
|
incs += ' ' + env['BF_QUICKTIME_INC']
|
||||||
|
|
||||||
if env['WITH_BF_BULLET']:
|
if env['WITH_BF_BULLET']:
|
||||||
defs.append('USE_BULLET')
|
defs.append('USE_BULLET')
|
||||||
|
|
||||||
if env['OURPLATFORM'] == 'darwin':
|
if env['OURPLATFORM'] == 'darwin':
|
||||||
if env['WITH_BF_OPENMP']:
|
if env['WITH_BF_OPENMP']:
|
||||||
defs.append('PARALLEL=1')
|
defs.append('PARALLEL=1')
|
||||||
|
|
||||||
if env['BF_NO_ELBEEM']:
|
if env['BF_NO_ELBEEM']:
|
||||||
defs.append('DISABLE_ELBEEM')
|
defs.append('DISABLE_ELBEEM')
|
||||||
|
|
||||||
if env['WITH_BF_LCMS']:
|
if env['WITH_BF_LCMS']:
|
||||||
defs.append('WITH_LCMS')
|
defs.append('WITH_LCMS')
|
||||||
incs += ' ' + env['BF_LCMS_INC']
|
incs += ' ' + env['BF_LCMS_INC']
|
||||||
|
|
||||||
if env['WITH_BF_LZO']:
|
if env['WITH_BF_LZO']:
|
||||||
incs += ' #/extern/lzo/minilzo'
|
incs += ' #/extern/lzo/minilzo'
|
||||||
defs.append('WITH_LZO')
|
defs.append('WITH_LZO')
|
||||||
|
|
||||||
if env['WITH_BF_LZMA']:
|
if env['WITH_BF_LZMA']:
|
||||||
incs += ' #/extern/lzma'
|
incs += ' #/extern/lzma'
|
||||||
defs.append('WITH_LZMA')
|
defs.append('WITH_LZMA')
|
||||||
|
|
||||||
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'):
|
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'):
|
||||||
incs += ' ' + env['BF_PTHREADS_INC']
|
incs += ' ' + env['BF_PTHREADS_INC']
|
||||||
|
|||||||
@@ -1285,6 +1285,12 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
|
|||||||
size = psys_get_child_size(psys, cpa, ctime, 0);
|
size = psys_get_child_size(psys, cpa, ctime, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* some hair paths might be non-existent so they can't be used for duplication */
|
||||||
|
if(hair &&
|
||||||
|
((a < totpart && psys->pathcache[a]->steps < 0) ||
|
||||||
|
(a >= totpart && psys->childcache[a-totpart]->steps < 0)))
|
||||||
|
continue;
|
||||||
|
|
||||||
if(part->ren_as==PART_DRAW_GR) {
|
if(part->ren_as==PART_DRAW_GR) {
|
||||||
/* for groups, pick the object based on settings */
|
/* for groups, pick the object based on settings */
|
||||||
if(part->draw&PART_DRAW_RAND_GR)
|
if(part->draw&PART_DRAW_RAND_GR)
|
||||||
|
|||||||
@@ -231,7 +231,7 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, char *filename)
|
|||||||
curscene= bfd->curscene;
|
curscene= bfd->curscene;
|
||||||
if(curscene==NULL) curscene= bfd->main->scene.first;
|
if(curscene==NULL) curscene= bfd->main->scene.first;
|
||||||
/* and we enforce curscene to be in current screen */
|
/* and we enforce curscene to be in current screen */
|
||||||
curscreen->scene= curscene;
|
if(curscreen) curscreen->scene= curscene; /* can run in bgmode */
|
||||||
|
|
||||||
/* clear_global will free G.main, here we can still restore pointers */
|
/* clear_global will free G.main, here we can still restore pointers */
|
||||||
lib_link_screen_restore(bfd->main, curscreen, curscene);
|
lib_link_screen_restore(bfd->main, curscreen, curscene);
|
||||||
|
|||||||
@@ -910,6 +910,7 @@ void boid_brain(BoidBrainData *bbd, int p, ParticleData *pa)
|
|||||||
|
|
||||||
if(bpa->data.health <= 0.0f) {
|
if(bpa->data.health <= 0.0f) {
|
||||||
pa->alive = PARS_DYING;
|
pa->alive = PARS_DYING;
|
||||||
|
pa->dietime = bbd->cfra;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -701,7 +701,7 @@ Main *CTX_data_main(const bContext *C)
|
|||||||
{
|
{
|
||||||
Main *bmain;
|
Main *bmain;
|
||||||
|
|
||||||
if(ctx_data_pointer_verify(C, "main", (void*)&bmain))
|
if(ctx_data_pointer_verify(C, "blend_data", (void*)&bmain))
|
||||||
return bmain;
|
return bmain;
|
||||||
else
|
else
|
||||||
return C->data.main;
|
return C->data.main;
|
||||||
|
|||||||
@@ -265,13 +265,11 @@ static PackedFile *get_builtin_packedfile(void)
|
|||||||
void free_ttfont(void)
|
void free_ttfont(void)
|
||||||
{
|
{
|
||||||
struct TmpFont *tf;
|
struct TmpFont *tf;
|
||||||
|
|
||||||
tf= ttfdata.first;
|
for(tf= ttfdata.first; tf; tf= tf->next) {
|
||||||
while(tf) {
|
if(tf->pf) freePackedFile(tf->pf); /* NULL when the font file can't be found on disk */
|
||||||
freePackedFile(tf->pf);
|
|
||||||
tf->pf= NULL;
|
tf->pf= NULL;
|
||||||
tf->vfont= NULL;
|
tf->vfont= NULL;
|
||||||
tf= tf->next;
|
|
||||||
}
|
}
|
||||||
BLI_freelistN(&ttfdata);
|
BLI_freelistN(&ttfdata);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1301,13 +1301,14 @@ static void icu_to_fcurves (ID *id, ListBase *groups, ListBase *list, IpoCurve *
|
|||||||
/* correct times for rotation drivers
|
/* correct times for rotation drivers
|
||||||
* - need to go from degrees to radians...
|
* - need to go from degrees to radians...
|
||||||
* - there's only really 1 target to worry about
|
* - there's only really 1 target to worry about
|
||||||
|
* - were also degrees/10
|
||||||
*/
|
*/
|
||||||
if (fcu->driver && fcu->driver->variables.first) {
|
if (fcu->driver && fcu->driver->variables.first) {
|
||||||
DriverVar *dvar= fcu->driver->variables.first;
|
DriverVar *dvar= fcu->driver->variables.first;
|
||||||
DriverTarget *dtar= &dvar->targets[0];
|
DriverTarget *dtar= &dvar->targets[0];
|
||||||
|
|
||||||
if (ELEM3(dtar->transChan, DTAR_TRANSCHAN_ROTX, DTAR_TRANSCHAN_ROTY, DTAR_TRANSCHAN_ROTZ)) {
|
if (ELEM3(dtar->transChan, DTAR_TRANSCHAN_ROTX, DTAR_TRANSCHAN_ROTY, DTAR_TRANSCHAN_ROTZ)) {
|
||||||
const float fac= (float)M_PI / 180.0f;
|
const float fac= (float)M_PI / 18.0f;
|
||||||
|
|
||||||
dst->vec[0][0] *= fac;
|
dst->vec[0][0] *= fac;
|
||||||
dst->vec[1][0] *= fac;
|
dst->vec[1][0] *= fac;
|
||||||
|
|||||||
@@ -1160,7 +1160,7 @@ static int check_for_dupid(ListBase *lb, ID *id, char *name)
|
|||||||
/* this would overflow name buffer */
|
/* this would overflow name buffer */
|
||||||
left[16] = 0;
|
left[16] = 0;
|
||||||
/* left_len = 16; */ /* for now this isnt used again */
|
/* left_len = 16; */ /* for now this isnt used again */
|
||||||
memcpy(name, left, sizeof(char) * 16);
|
memcpy(name, left, sizeof(char) * 17);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/* this format specifier is from hell... */
|
/* this format specifier is from hell... */
|
||||||
@@ -1199,8 +1199,15 @@ int new_id(ListBase *lb, ID *id, const char *tname)
|
|||||||
* easier to assign each time then to check if its needed */
|
* easier to assign each time then to check if its needed */
|
||||||
name[sizeof(name)-1]= 0;
|
name[sizeof(name)-1]= 0;
|
||||||
|
|
||||||
if(name[0] == '\0')
|
if(name[0] == '\0') {
|
||||||
|
/* disallow empty names */
|
||||||
strcpy(name, ID_FALLBACK_NAME);
|
strcpy(name, ID_FALLBACK_NAME);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* disallow non utf8 chars,
|
||||||
|
* the interface checks for this but new ID's based on file names dont */
|
||||||
|
BLI_utf8_invalid_strip(name, strlen(name));
|
||||||
|
}
|
||||||
|
|
||||||
result = check_for_dupid(lb, id, name);
|
result = check_for_dupid(lb, id, name);
|
||||||
strcpy(id->name+2, name);
|
strcpy(id->name+2, name);
|
||||||
@@ -1391,8 +1398,9 @@ void text_idbutton(struct ID *id, char *text)
|
|||||||
text[4]= 0;
|
text[4]= 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
strcpy(text, "");
|
text[0]= '\0';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void rename_id(ID *id, char *name)
|
void rename_id(ID *id, char *name)
|
||||||
|
|||||||
@@ -435,6 +435,90 @@ short *give_totcolp(Object *ob)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* same as above but for ID's */
|
||||||
|
Material ***give_matarar_id(ID *id)
|
||||||
|
{
|
||||||
|
switch(GS(id->name)) {
|
||||||
|
case ID_ME:
|
||||||
|
return &(((Mesh *)id)->mat);
|
||||||
|
break;
|
||||||
|
case ID_CU:
|
||||||
|
return &(((Curve *)id)->mat);
|
||||||
|
break;
|
||||||
|
case ID_MB:
|
||||||
|
return &(((Curve *)id)->mat);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
short *give_totcolp_id(ID *id)
|
||||||
|
{
|
||||||
|
switch(GS(id->name)) {
|
||||||
|
case ID_ME:
|
||||||
|
return &(((Mesh *)id)->totcol);
|
||||||
|
break;
|
||||||
|
case ID_CU:
|
||||||
|
return &(((Curve *)id)->totcol);
|
||||||
|
break;
|
||||||
|
case ID_MB:
|
||||||
|
return &(((Curve *)id)->totcol);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void material_append_id(ID *id, Material *ma)
|
||||||
|
{
|
||||||
|
Material ***matar;
|
||||||
|
if((matar= give_matarar_id(id))) {
|
||||||
|
short *totcol= give_totcolp_id(id);
|
||||||
|
Material **mat= MEM_callocN(sizeof(void *) * ((*totcol) + 1), "newmatar");
|
||||||
|
if(*totcol) memcpy(mat, *matar, sizeof(void *) * (*totcol));
|
||||||
|
if(*matar) MEM_freeN(*matar);
|
||||||
|
|
||||||
|
*matar= mat;
|
||||||
|
(*matar)[(*totcol)++]= ma;
|
||||||
|
|
||||||
|
id_us_plus((ID *)ma);
|
||||||
|
test_object_materials(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Material *material_pop_id(ID *id, int index)
|
||||||
|
{
|
||||||
|
Material *ret= NULL;
|
||||||
|
Material ***matar;
|
||||||
|
if((matar= give_matarar_id(id))) {
|
||||||
|
short *totcol= give_totcolp_id(id);
|
||||||
|
if(index >= 0 && index < (*totcol)) {
|
||||||
|
ret= (*matar)[index];
|
||||||
|
if(*totcol <= 1) {
|
||||||
|
*totcol= 0;
|
||||||
|
MEM_freeN(*matar);
|
||||||
|
*matar= NULL;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Material **mat;
|
||||||
|
|
||||||
|
if(index + 1 != (*totcol))
|
||||||
|
memmove((*matar), (*matar) + 1, (*totcol) - (index + 1));
|
||||||
|
|
||||||
|
(*totcol)--;
|
||||||
|
|
||||||
|
mat= MEM_callocN(sizeof(void *) * (*totcol), "newmatar");
|
||||||
|
memcpy(mat, *matar, sizeof(void *) * (*totcol));
|
||||||
|
MEM_freeN(*matar);
|
||||||
|
|
||||||
|
*matar= mat;
|
||||||
|
test_object_materials(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
Material *give_current_material(Object *ob, int act)
|
Material *give_current_material(Object *ob, int act)
|
||||||
{
|
{
|
||||||
Material ***matarar, *ma;
|
Material ***matarar, *ma;
|
||||||
@@ -454,7 +538,7 @@ Material *give_current_material(Object *ob, int act)
|
|||||||
}
|
}
|
||||||
else { /* in data */
|
else { /* in data */
|
||||||
|
|
||||||
/* check for inconsistancy */
|
/* check for inconsistency */
|
||||||
if(*totcolp < ob->totcol)
|
if(*totcolp < ob->totcol)
|
||||||
ob->totcol= *totcolp;
|
ob->totcol= *totcolp;
|
||||||
if(act>ob->totcol) act= ob->totcol;
|
if(act>ob->totcol) act= ob->totcol;
|
||||||
|
|||||||
@@ -2553,7 +2553,7 @@ void object_handle_update(Scene *scene, Object *ob)
|
|||||||
while(psys) {
|
while(psys) {
|
||||||
if(psys_check_enabled(ob, psys)) {
|
if(psys_check_enabled(ob, psys)) {
|
||||||
/* check use of dupli objects here */
|
/* check use of dupli objects here */
|
||||||
if(psys->part && psys->part->draw_as == PART_DRAW_REND &&
|
if(psys->part && (psys->part->draw_as == PART_DRAW_REND || G.rendering) &&
|
||||||
((psys->part->ren_as == PART_DRAW_OB && psys->part->dup_ob)
|
((psys->part->ren_as == PART_DRAW_OB && psys->part->dup_ob)
|
||||||
|| (psys->part->ren_as == PART_DRAW_GR && psys->part->dup_group)))
|
|| (psys->part->ren_as == PART_DRAW_GR && psys->part->dup_group)))
|
||||||
ob->transflag |= OB_DUPLIPARTS;
|
ob->transflag |= OB_DUPLIPARTS;
|
||||||
|
|||||||
@@ -709,6 +709,10 @@ void psys_render_set(Object *ob, ParticleSystem *psys, float viewmat[][4], float
|
|||||||
data->timeoffset= timeoffset;
|
data->timeoffset= timeoffset;
|
||||||
|
|
||||||
psys->renderdata= data;
|
psys->renderdata= data;
|
||||||
|
|
||||||
|
/* Hair can and has to be recalculated if everything isn't displayed. */
|
||||||
|
if(psys->part->disp != 100 && psys->part->type == PART_HAIR)
|
||||||
|
psys->recalc |= PSYS_RECALC_RESET;
|
||||||
}
|
}
|
||||||
|
|
||||||
void psys_render_restore(Object *ob, ParticleSystem *psys)
|
void psys_render_restore(Object *ob, ParticleSystem *psys)
|
||||||
@@ -1117,6 +1121,24 @@ static int get_pointcache_times_for_particle(PointCache *cache, int index, float
|
|||||||
|
|
||||||
return ret == 2;
|
return ret == 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float psys_get_dietime_from_cache(PointCache *cache, int index) {
|
||||||
|
PTCacheMem *pm;
|
||||||
|
int dietime = 10000000; /* some max value so that we can default to pa->time+lifetime */
|
||||||
|
|
||||||
|
for(pm=cache->mem_cache.last; pm; pm=pm->prev) {
|
||||||
|
if(pm->index_array) {
|
||||||
|
if(pm->index_array[index])
|
||||||
|
return (float)pm->frame;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return (float)pm->frame;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (float)dietime;
|
||||||
|
}
|
||||||
|
|
||||||
static void init_particle_interpolation(Object *ob, ParticleSystem *psys, ParticleData *pa, ParticleInterpolationData *pind)
|
static void init_particle_interpolation(Object *ob, ParticleSystem *psys, ParticleData *pa, ParticleInterpolationData *pind)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -2009,6 +2031,10 @@ void precalc_guides(ParticleSimulationData *sim, ListBase *effectors)
|
|||||||
|
|
||||||
LOOP_PARTICLES {
|
LOOP_PARTICLES {
|
||||||
psys_particle_on_emitter(sim->psmd,sim->psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,state.co,0,0,0,0,0);
|
psys_particle_on_emitter(sim->psmd,sim->psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,state.co,0,0,0,0,0);
|
||||||
|
|
||||||
|
mul_m4_v3(sim->ob->obmat, state.co);
|
||||||
|
mul_mat3_m4_v3(sim->ob->obmat, state.vel);
|
||||||
|
|
||||||
pd_point_from_particle(sim, pa, &state, &point);
|
pd_point_from_particle(sim, pa, &state, &point);
|
||||||
|
|
||||||
for(eff = effectors->first; eff; eff=eff->next) {
|
for(eff = effectors->first; eff; eff=eff->next) {
|
||||||
@@ -3164,7 +3190,7 @@ void psys_cache_edit_paths(Scene *scene, Object *ob, PTCacheEdit *edit, float cf
|
|||||||
|
|
||||||
/* at the moment this is only used for weight painting.
|
/* at the moment this is only used for weight painting.
|
||||||
* will need to move out of this check if its used elsewhere. */
|
* will need to move out of this check if its used elsewhere. */
|
||||||
t2 = birthtime + ((float)(k+1)/(float)steps) * (dietime - birthtime);
|
t2 = birthtime + ((float)k/(float)steps) * (dietime - birthtime);
|
||||||
|
|
||||||
while (pind.hkey[1]->time < t2) pind.hkey[1]++;
|
while (pind.hkey[1]->time < t2) pind.hkey[1]++;
|
||||||
pind.hkey[0] = pind.hkey[1] - 1;
|
pind.hkey[0] = pind.hkey[1] - 1;
|
||||||
@@ -4423,3 +4449,34 @@ void psys_make_billboard(ParticleBillboardData *bb, float xvec[3], float yvec[3]
|
|||||||
VECADDFAC(center, center, yvec, bb->offset[1]);
|
VECADDFAC(center, center, yvec, bb->offset[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void psys_apply_hair_lattice(Scene *scene, Object *ob, ParticleSystem *psys) {
|
||||||
|
ParticleSimulationData sim = {scene, ob, psys, psys_get_modifier(ob, psys)};
|
||||||
|
|
||||||
|
psys->lattice = psys_get_lattice(&sim);
|
||||||
|
|
||||||
|
if(psys->lattice) {
|
||||||
|
ParticleData *pa = psys->particles;
|
||||||
|
HairKey *hkey;
|
||||||
|
int p, h;
|
||||||
|
float hairmat[4][4], imat[4][4];
|
||||||
|
|
||||||
|
for(p=0; p<psys->totpart; p++, pa++) {
|
||||||
|
psys_mat_hair_to_global(sim.ob, sim.psmd->dm, psys->part->from, pa, hairmat);
|
||||||
|
invert_m4_m4(imat, hairmat);
|
||||||
|
|
||||||
|
hkey = pa->hair;
|
||||||
|
for(h=0; h<pa->totkey; h++, hkey++) {
|
||||||
|
mul_m4_v3(hairmat, hkey->co);
|
||||||
|
calc_latt_deform(psys->lattice, hkey->co, 1.0f);
|
||||||
|
mul_m4_v3(imat, hkey->co);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
end_latt_deform(psys->lattice);
|
||||||
|
psys->lattice= NULL;
|
||||||
|
|
||||||
|
/* protect the applied shape */
|
||||||
|
psys->flag |= PSYS_EDITED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -106,19 +106,25 @@
|
|||||||
/* Reacting to system events */
|
/* Reacting to system events */
|
||||||
/************************************************/
|
/************************************************/
|
||||||
|
|
||||||
static int get_current_display_percentage(ParticleSystem *psys)
|
static int particles_are_dynamic(ParticleSystem *psys) {
|
||||||
|
if(psys->pointcache->flag & PTCACHE_BAKED)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if(psys->part->type == PART_HAIR)
|
||||||
|
return psys->flag & PSYS_HAIR_DYNAMICS;
|
||||||
|
else
|
||||||
|
return ELEM3(psys->part->phystype, PART_PHYS_NEWTON, PART_PHYS_BOIDS, PART_PHYS_FLUID);
|
||||||
|
}
|
||||||
|
int psys_get_current_display_percentage(ParticleSystem *psys)
|
||||||
{
|
{
|
||||||
ParticleSettings *part=psys->part;
|
ParticleSettings *part=psys->part;
|
||||||
|
|
||||||
if(psys->renderdata || (part->child_nbr && part->childtype)
|
if((psys->renderdata && !particles_are_dynamic(psys)) /* non-dynamic particles can be rendered fully */
|
||||||
|| (psys->pointcache->flag & PTCACHE_BAKING))
|
|| (part->child_nbr && part->childtype) /* display percentage applies to children */
|
||||||
|
|| (psys->pointcache->flag & PTCACHE_BAKING)) /* baking is always done with full amount */
|
||||||
return 100;
|
return 100;
|
||||||
|
|
||||||
if(part->phystype==PART_PHYS_KEYED){
|
return psys->part->disp;
|
||||||
return psys->part->disp;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return psys->part->disp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void psys_reset(ParticleSystem *psys, int mode)
|
void psys_reset(ParticleSystem *psys, int mode)
|
||||||
@@ -1567,8 +1573,6 @@ void initialize_particle(ParticleSimulationData *sim, ParticleData *pa, int p)
|
|||||||
/* TODO: needs some work to make most blendtypes generally usefull */
|
/* TODO: needs some work to make most blendtypes generally usefull */
|
||||||
psys_get_texture(sim,ma,pa,&ptex,MAP_PA_INIT);
|
psys_get_texture(sim,ma,pa,&ptex,MAP_PA_INIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
pa->lifetime= part->lifetime*ptex.life;
|
|
||||||
|
|
||||||
if(part->type==PART_HAIR)
|
if(part->type==PART_HAIR)
|
||||||
pa->time= 0.0f;
|
pa->time= 0.0f;
|
||||||
@@ -1584,25 +1588,6 @@ void initialize_particle(ParticleSimulationData *sim, ParticleData *pa, int p)
|
|||||||
pa->time= part->sta + (part->end - part->sta)*ptex.time;
|
pa->time= part->sta + (part->end - part->sta)*ptex.time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if(part->type==PART_HAIR){
|
|
||||||
pa->lifetime=100.0f;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
#if 0 // XXX old animation system
|
|
||||||
icu=find_ipocurve(psys->part->ipo,PART_EMIT_LIFE);
|
|
||||||
if(icu){
|
|
||||||
calc_icu(icu,100*ptex.time);
|
|
||||||
pa->lifetime*=icu->curval;
|
|
||||||
}
|
|
||||||
#endif // XXX old animation system
|
|
||||||
|
|
||||||
if(part->randlife!=0.0)
|
|
||||||
pa->lifetime*= 1.0f - part->randlife * BLI_frand();
|
|
||||||
}
|
|
||||||
|
|
||||||
pa->dietime= pa->time+pa->lifetime;
|
|
||||||
|
|
||||||
if(part->type!=PART_HAIR && part->distr!=PART_DISTR_GRID && part->from != PART_FROM_VERT){
|
if(part->type!=PART_HAIR && part->distr!=PART_DISTR_GRID && part->from != PART_FROM_VERT){
|
||||||
if(ptex.exist < BLI_frand())
|
if(ptex.exist < BLI_frand())
|
||||||
pa->flag |= PARS_UNEXIST;
|
pa->flag |= PARS_UNEXIST;
|
||||||
@@ -1695,6 +1680,7 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime,
|
|||||||
part=psys->part;
|
part=psys->part;
|
||||||
|
|
||||||
ptex.ivel=1.0;
|
ptex.ivel=1.0;
|
||||||
|
ptex.life=1.0;
|
||||||
|
|
||||||
/* we need to get every random even if they're not used so that they don't effect eachother */
|
/* we need to get every random even if they're not used so that they don't effect eachother */
|
||||||
r_vel[0] = 2.0f * (PSYS_FRAND(p + 10) - 0.5f);
|
r_vel[0] = 2.0f * (PSYS_FRAND(p + 10) - 0.5f);
|
||||||
@@ -1752,7 +1738,7 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime,
|
|||||||
psys_particle_on_emitter(sim->psmd, part->from,pa->num, pa->num_dmcache, pa->fuv,pa->foffset,loc,nor,0,0,0,0);
|
psys_particle_on_emitter(sim->psmd, part->from,pa->num, pa->num_dmcache, pa->fuv,pa->foffset,loc,nor,0,0,0,0);
|
||||||
|
|
||||||
/* get possible textural influence */
|
/* get possible textural influence */
|
||||||
psys_get_texture(sim, give_current_material(sim->ob,part->omat), pa, &ptex, MAP_PA_IVEL);
|
psys_get_texture(sim, give_current_material(sim->ob,part->omat), pa, &ptex, MAP_PA_IVEL|MAP_PA_LIFE);
|
||||||
|
|
||||||
//if(vg_vel && pa->num != -1)
|
//if(vg_vel && pa->num != -1)
|
||||||
// ptex.ivel*=psys_particle_value_from_verts(sim->psmd->dm,part->from,pa,vg_vel);
|
// ptex.ivel*=psys_particle_value_from_verts(sim->psmd->dm,part->from,pa,vg_vel);
|
||||||
@@ -1975,8 +1961,25 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(part->type == PART_HAIR){
|
||||||
|
pa->lifetime = 100.0f;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
pa->lifetime = part->lifetime*ptex.life;
|
||||||
|
|
||||||
|
if(part->randlife != 0.0)
|
||||||
|
pa->lifetime *= 1.0f - part->randlife * PSYS_FRAND(p + 21);
|
||||||
|
}
|
||||||
|
|
||||||
pa->dietime = pa->time + pa->lifetime;
|
pa->dietime = pa->time + pa->lifetime;
|
||||||
|
|
||||||
|
if(sim->psys->pointcache && sim->psys->pointcache->flag & PTCACHE_BAKED &&
|
||||||
|
sim->psys->pointcache->mem_cache.first) {
|
||||||
|
float dietime = psys_get_dietime_from_cache(sim->psys->pointcache, p);
|
||||||
|
pa->dietime = MIN2(pa->dietime, dietime);
|
||||||
|
}
|
||||||
|
|
||||||
if(pa->time > cfra)
|
if(pa->time > cfra)
|
||||||
pa->alive = PARS_UNBORN;
|
pa->alive = PARS_UNBORN;
|
||||||
else if(pa->dietime <= cfra)
|
else if(pa->dietime <= cfra)
|
||||||
@@ -3052,7 +3055,7 @@ static void deflect_particle(ParticleSimulationData *sim, int p, float dfra, flo
|
|||||||
|
|
||||||
/* Stickness to surface */
|
/* Stickness to surface */
|
||||||
normalize_v3(nor_vec);
|
normalize_v3(nor_vec);
|
||||||
madd_v3_v3fl(pa->state.vel, nor_vec, -pd->pdef_stickness);
|
madd_v3_v3fl(pa->state.vel, col.nor, -pd->pdef_stickness);
|
||||||
}
|
}
|
||||||
|
|
||||||
col.t = dt;
|
col.t = dt;
|
||||||
@@ -3250,7 +3253,7 @@ static void hair_step(ParticleSimulationData *sim, float cfra)
|
|||||||
ParticleSystem *psys = sim->psys;
|
ParticleSystem *psys = sim->psys;
|
||||||
/* ParticleSettings *part = psys->part; */
|
/* ParticleSettings *part = psys->part; */
|
||||||
PARTICLE_P;
|
PARTICLE_P;
|
||||||
float disp = (float)get_current_display_percentage(psys)/100.0f;
|
float disp = (float)psys_get_current_display_percentage(psys)/100.0f;
|
||||||
|
|
||||||
BLI_srandom(psys->seed);
|
BLI_srandom(psys->seed);
|
||||||
|
|
||||||
@@ -3518,7 +3521,7 @@ static void cached_step(ParticleSimulationData *sim, float cfra)
|
|||||||
|
|
||||||
psys_update_effectors(sim);
|
psys_update_effectors(sim);
|
||||||
|
|
||||||
disp= (float)get_current_display_percentage(psys)/100.0f;
|
disp= (float)psys_get_current_display_percentage(psys)/100.0f;
|
||||||
|
|
||||||
LOOP_PARTICLES {
|
LOOP_PARTICLES {
|
||||||
pa->size = part->size;
|
pa->size = part->size;
|
||||||
@@ -3785,7 +3788,7 @@ static void system_step(ParticleSimulationData *sim, float cfra)
|
|||||||
|
|
||||||
/* 3. do dynamics */
|
/* 3. do dynamics */
|
||||||
/* set particles to be not calculated TODO: can't work with pointcache */
|
/* set particles to be not calculated TODO: can't work with pointcache */
|
||||||
disp= (float)get_current_display_percentage(psys)/100.0f;
|
disp= (float)psys_get_current_display_percentage(psys)/100.0f;
|
||||||
|
|
||||||
BLI_srandom(psys->seed);
|
BLI_srandom(psys->seed);
|
||||||
LOOP_PARTICLES {
|
LOOP_PARTICLES {
|
||||||
@@ -4035,6 +4038,10 @@ void particle_system_update(Scene *scene, Object *ob, ParticleSystem *psys)
|
|||||||
{
|
{
|
||||||
PARTICLE_P;
|
PARTICLE_P;
|
||||||
|
|
||||||
|
/* Particles without dynamics haven't been reset yet because they don't use pointcache */
|
||||||
|
if(psys->recalc & PSYS_RECALC_RESET)
|
||||||
|
psys_reset(psys, PSYS_RESET_ALL);
|
||||||
|
|
||||||
if(emit_particles(&sim, NULL, cfra)) {
|
if(emit_particles(&sim, NULL, cfra)) {
|
||||||
free_keyed_keys(psys);
|
free_keyed_keys(psys);
|
||||||
distribute_particles(&sim, part->from);
|
distribute_particles(&sim, part->from);
|
||||||
|
|||||||
@@ -273,4 +273,4 @@ Report *BKE_reports_last_displayable(ReportList *reports)
|
|||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -572,9 +572,22 @@ void set_sca_new_poins_ob(Object *ob)
|
|||||||
bObjectActuator *oa= act->data;
|
bObjectActuator *oa= act->data;
|
||||||
ID_NEW(oa->reference);
|
ID_NEW(oa->reference);
|
||||||
}
|
}
|
||||||
else if(act->type==ACT_SCENE) {
|
else if(act->type==ACT_MESSAGE) {
|
||||||
bSceneActuator *sca= act->data;
|
bMessageActuator *ma= act->data;
|
||||||
ID_NEW(sca->camera);
|
ID_NEW(ma->toObject);
|
||||||
|
}
|
||||||
|
else if(act->type==ACT_PARENT) {
|
||||||
|
bParentActuator *para = act->data;
|
||||||
|
ID_NEW(para->ob);
|
||||||
|
}
|
||||||
|
else if(act->type==ACT_ARMATURE) {
|
||||||
|
bArmatureActuator *aa = act->data;
|
||||||
|
ID_NEW(aa->target);
|
||||||
|
ID_NEW(aa->subtarget);
|
||||||
|
}
|
||||||
|
else if(act->type==ACT_PROPERTY) {
|
||||||
|
bPropertyActuator *pa= act->data;
|
||||||
|
ID_NEW(pa->ob);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
act= act->next;
|
act= act->next;
|
||||||
|
|||||||
@@ -689,6 +689,49 @@ MTex *add_mtex()
|
|||||||
return mtex;
|
return mtex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* slot -1 for first free ID */
|
||||||
|
MTex *add_mtex_id(ID *id, int slot)
|
||||||
|
{
|
||||||
|
MTex **mtex_ar;
|
||||||
|
short act;
|
||||||
|
|
||||||
|
give_active_mtex(id, &mtex_ar, &act);
|
||||||
|
|
||||||
|
if(mtex_ar==NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(slot==-1) {
|
||||||
|
/* find first free */
|
||||||
|
int i;
|
||||||
|
for (i= 0; i < MAX_MTEX; i++) {
|
||||||
|
if (!mtex_ar[i]) {
|
||||||
|
slot= i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(slot == -1) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* make sure slot is valid */
|
||||||
|
if(slot < 0 || slot >= MAX_MTEX) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mtex_ar[slot]) {
|
||||||
|
id_us_min((ID *)mtex_ar[slot]->tex);
|
||||||
|
MEM_freeN(mtex_ar[slot]);
|
||||||
|
mtex_ar[slot]= NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
mtex_ar[slot]= add_mtex();
|
||||||
|
|
||||||
|
return mtex_ar[slot];
|
||||||
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
Tex *copy_texture(Tex *tex)
|
Tex *copy_texture(Tex *tex)
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user