forked from bartvdbraak/blender
merge with trunk/2.5 at r24378
This commit is contained in:
commit
2ead17843c
@ -76,6 +76,11 @@ MACRO(SETUP_LIBDIRS)
|
||||
IF(WITH_FFTW3)
|
||||
LINK_DIRECTORIES(${FFTW3_LIBPATH})
|
||||
ENDIF(WITH_FFTW3)
|
||||
IF(WITH_OPENCOLLADA)
|
||||
LINK_DIRECTORIES(${OPENCOLLADA_LIBPATH})
|
||||
LINK_DIRECTORIES(${PCRE_LIBPATH})
|
||||
LINK_DIRECTORIES(${EXPAT_LIBPATH})
|
||||
ENDIF(WITH_OPENCOLLADA)
|
||||
|
||||
IF(WIN32)
|
||||
LINK_DIRECTORIES(${PTHREADS_LIBPATH})
|
||||
@ -135,6 +140,11 @@ MACRO(SETUP_LIBLINKS
|
||||
IF(WITH_FFMPEG)
|
||||
TARGET_LINK_LIBRARIES(${target} ${FFMPEG_LIB})
|
||||
ENDIF(WITH_FFMPEG)
|
||||
IF(WITH_OPENCOLLADA)
|
||||
TARGET_LINK_LIBRARIES(${target} ${OPENCOLLADA_LIB})
|
||||
TARGET_LINK_LIBRARIES(${target} ${PCRE_LIB})
|
||||
TARGET_LINK_LIBRARIES(${target} ${EXPAT_LIB})
|
||||
ENDIF(WITH_OPENCOLLADA)
|
||||
IF(WIN32)
|
||||
TARGET_LINK_LIBRARIES(${target} ${PTHREADS_LIB})
|
||||
ENDIF(WIN32)
|
||||
|
@ -80,6 +80,7 @@ OPTION(WITH_LZMA "Enable best LZMA compression, used for pointcache" ON
|
||||
OPTION(WITH_CXX_GUARDEDALLOC "Enable GuardedAlloc for C++ memory allocation" OFF)
|
||||
OPTION(WITH_BUILDINFO "Include extra build details" ON)
|
||||
OPTION(WITH_INSTALL "Install accompanying scripts and language files needed to run blender" ON)
|
||||
OPTION(WITH_OPENCOLLADA "Enable OpenCollada Support (http://www.opencollada.org/)" OFF)
|
||||
|
||||
IF (APPLE)
|
||||
OPTION(WITH_COCOA "Use Cocoa framework instead of deprecated Carbon" ON)
|
||||
@ -90,6 +91,18 @@ IF(NOT WITH_GAMEENGINE AND WITH_PLAYER)
|
||||
MESSAGE("WARNING: WITH_PLAYER needs WITH_GAMEENGINE")
|
||||
ENDIF(NOT WITH_GAMEENGINE AND WITH_PLAYER)
|
||||
|
||||
IF (WITH_OPENCOLLADA AND NOT APPLE)
|
||||
SET(OPENCOLLADA /usr/local/opencollada CACHE FILEPATH "OpenCollada Directory")
|
||||
SET(OPENCOLLADA_LIBPATH ${OPENCOLLADA})
|
||||
SET(OPENCOLLADA_LIB OpenCollada)
|
||||
SET(PCRE /usr CACHE FILEPATH "PCRE Directory")
|
||||
SET(PCRE_LIBPATH ${PCRE}/lib)
|
||||
SET(PCRE_LIB pcre)
|
||||
SET(EXPAT /usr CACHE FILEPATH "Expat Directory")
|
||||
SET(EXPAT_LIBPATH ${EXPAT}/lib)
|
||||
SET(EXPAT_LIB expat)
|
||||
ENDIF (WITH_OPENCOLLADA AND NOT APPLE)
|
||||
|
||||
# For alternate Python locations the commandline can be used to override detected/default cache settings, e.g:
|
||||
# On Unix:
|
||||
# cmake -D PYTHON_LIB=/usr/local/lib/python2.3/config/libpython2.3.so -D PYTHON_INC=/usr/local/include/python2.3 -D PYTHON_BINARY=/usr/local/bin/python2.3 -G "Unix Makefiles" ../blender
|
||||
@ -503,12 +516,28 @@ IF(APPLE)
|
||||
SET(PLATFORM_CFLAGS "-pipe -fPIC -funsigned-char -fno-strict-aliasing")
|
||||
SET(PLATFORM_LINKFLAGS "-fexceptions -framework CoreServices -framework Foundation -framework IOKit -framework AppKit -framework Carbon -framework AGL -framework AudioUnit -framework AudioToolbox -framework CoreAudio -framework QuickTime")
|
||||
ENDIF (WITH_COCOA)
|
||||
|
||||
IF(WITH_OPENMP)
|
||||
SET(LLIBS "${LLIBS} -lgomp")
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fopenmp")
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp")
|
||||
ENDIF(WITH_OPENMP)
|
||||
|
||||
IF (WITH_OPENCOLLADA)
|
||||
SET(OPENCOLLADA ${LIBDIR}/opencollada)
|
||||
SET(OPENCOLLADA_INC ${OPENCOLLADA}/include)
|
||||
SET(OPENCOLLADA_LIBPATH ${OPENCOLLADA}/lib)
|
||||
SET(OPENCOLLADA_LIB "OpenCOLLADASaxFrameworkLoader -lOpenCOLLADAFramework -lOpenCOLLADABaseUtils -lOpenCOLLADAStreamWriter -lMathMLSolver -lGeneratedSaxParser -lUTF -lxml2" )
|
||||
#pcre is bundled with openCollada
|
||||
#SET(PCRE ${LIBDIR}/pcre)
|
||||
#SET(PCRE_LIBPATH ${PCRE}/lib)
|
||||
SET(PCRE_LIB pcre)
|
||||
#native OSX libxml2 is used
|
||||
#SET(EXPAT ${LIBDIR}/expat)
|
||||
#SET(EXPAT_LIBPATH ${EXPAT}/lib)
|
||||
#SET(EXPAT_LIB expat)
|
||||
ENDIF (WITH_OPENCOLLADA)
|
||||
|
||||
SET(SDL ${LIBDIR}/sdl)
|
||||
SET(SDL_INCLUDE_DIR ${SDL}/include)
|
||||
SET(SDL_LIBRARY SDL)
|
||||
@ -526,6 +555,16 @@ IF(APPLE)
|
||||
SET(TIFF_INC ${TIFF}/include)
|
||||
|
||||
SET(EXETYPE MACOSX_BUNDLE)
|
||||
|
||||
|
||||
IF(CMAKE_OSX_ARCHITECTURES MATCHES "i386")
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "-O3 -ftree-vectorize -msse -msse2 -fvariable-expansion-in-unroller")
|
||||
SET(CMAKE_C_FLAGS_RELEASE "-O3 -ftree-vectorize -msse -msse2 -fvariable-expansion-in-unroller")
|
||||
ELSEIF(CMAKE_OSX_ARCHITECTURES MATCHES "x86_64")
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "-O3 -ftree-vectorize -msse -msse2 -msse3 -mssse3 -fvariable-expansion-in-unroller")
|
||||
SET(CMAKE_C_FLAGS_RELEASE "-O3 -ftree-vectorize -msse -msse2 -msse3 -mssse3 -fvariable-expansion-in-unroller")
|
||||
ENDIF(CMAKE_OSX_ARCHITECTURES MATCHES "i386")
|
||||
|
||||
ENDIF(APPLE)
|
||||
|
||||
IF(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
@ -540,13 +579,19 @@ IF(WITH_BUILDINFO)
|
||||
IF(UNIX)
|
||||
EXEC_PROGRAM("date \"+%Y-%m-%d\"" OUTPUT_VARIABLE BUILD_DATE)
|
||||
EXEC_PROGRAM("date \"+%H:%M:%S\"" OUTPUT_VARIABLE BUILD_TIME)
|
||||
EXEC_PROGRAM("svnversion ${CMAKE_SOURCE_DIR}" OUTPUT_VARIABLE BUILD_REV)
|
||||
EXEC_PROGRAM("svnversion ${CMAKE_SOURCE_DIR}" OUTPUT_VARIABLE BUILD_REV RETURN_VALUE BUILD_REV_RETURN)
|
||||
IF(BUILD_REV_RETURN)
|
||||
SET(BUILD_REV "unknown")
|
||||
ENDIF(BUILD_REV_RETURN)
|
||||
ENDIF(UNIX)
|
||||
|
||||
IF(WIN32)
|
||||
EXEC_PROGRAM("cmd /c date /t" OUTPUT_VARIABLE BUILD_DATE)
|
||||
EXEC_PROGRAM("cmd /c time /t" OUTPUT_VARIABLE BUILD_TIME)
|
||||
EXEC_PROGRAM("svnversion ${CMAKE_SOURCE_DIR}" OUTPUT_VARIABLE BUILD_REV)
|
||||
EXEC_PROGRAM("svnversion ${CMAKE_SOURCE_DIR}" OUTPUT_VARIABLE BUILD_REV RETURN_VALUE BUILD_REV_RETURN)
|
||||
IF(BUILD_REV_RETURN)
|
||||
SET(BUILD_REV "unknown")
|
||||
ENDIF(BUILD_REV_RETURN)
|
||||
ENDIF(WIN32)
|
||||
ENDIF(WITH_BUILDINFO)
|
||||
|
||||
|
@ -123,6 +123,9 @@ if toolset:
|
||||
# xxx commented out, as was supressing warnings under mingw..
|
||||
#if env:
|
||||
# btools.SetupSpawn(env)
|
||||
else:
|
||||
if bitness==64 and platform=='win32':
|
||||
env = BlenderEnvironment(ENV = os.environ, MSVS_ARCH='amd64')
|
||||
else:
|
||||
env = BlenderEnvironment(ENV = os.environ)
|
||||
|
||||
@ -217,6 +220,11 @@ if env['WITH_BF_OPENMP'] == 1:
|
||||
env.Append(CPPFLAGS=['-fopenmp'])
|
||||
env.Append(CXXFLAGS=['-fopenmp'])
|
||||
|
||||
if env['WITH_GHOST_COCOA'] == True:
|
||||
env.Append(CFLAGS=['-DGHOST_COCOA'])
|
||||
env.Append(CXXFLAGS=['-DGHOST_COCOA'])
|
||||
env.Append(CPPFLAGS=['-DGHOST_COCOA'])
|
||||
|
||||
#check for additional debug libnames
|
||||
|
||||
if env.has_key('BF_DEBUG_LIBS'):
|
||||
|
@ -1,8 +1,23 @@
|
||||
#
|
||||
# Note : if you want to alter this file
|
||||
# copy it as a whole in the upper folder
|
||||
# as user-config.py
|
||||
# dont create a new file with only some
|
||||
# vars changed.
|
||||
|
||||
import commands
|
||||
|
||||
# IMPORTANT NOTE : OFFICIAL BUILDS SHOULD BE DONE WITH SDKs
|
||||
USE_SDK=True
|
||||
|
||||
#############################################################################
|
||||
################### Cocoa & architecture settings ##################
|
||||
#############################################################################
|
||||
|
||||
WITH_GHOST_COCOA=True
|
||||
MACOSX_ARCHITECTURE = 'i386' # valid archs: ppc, i386, ppc64, x86_64
|
||||
|
||||
|
||||
cmd = 'uname -p'
|
||||
MAC_PROC=commands.getoutput(cmd)
|
||||
cmd = 'uname -r'
|
||||
@ -11,13 +26,15 @@ if cmd_res[0]=='7':
|
||||
MAC_CUR_VER='10.3'
|
||||
elif cmd_res[0]=='8':
|
||||
MAC_CUR_VER='10.4'
|
||||
else:
|
||||
elif cmd_res[0]=='9':
|
||||
MAC_CUR_VER='10.5'
|
||||
elif cmd_res[0]=='10':
|
||||
MAC_CUR_VER='10.6'
|
||||
|
||||
if MAC_PROC == 'powerpc':
|
||||
LCGDIR = '#../lib/darwin-6.1-powerpc'
|
||||
else :
|
||||
LCGDIR = '#../lib/darwin-8.x.i386'
|
||||
LCGDIR = '#../lib/darwin-9.x.universal'
|
||||
LIBDIR = '${LCGDIR}'
|
||||
|
||||
BF_PYTHON_VERSION = '3.1'
|
||||
@ -25,14 +42,26 @@ BF_PYTHON_VERSION = '3.1'
|
||||
if MAC_PROC == 'powerpc' and BF_PYTHON_VERSION == '2.3':
|
||||
MAC_MIN_VERS = '10.3'
|
||||
MACOSX_SDK='/Developer/SDKs/MacOSX10.3.9.sdk'
|
||||
else:
|
||||
CC = 'gcc'
|
||||
CXX = 'g++'
|
||||
elif MACOSX_ARCHITECTURE == 'i386' or MACOSX_ARCHITECTURE == 'ppc':
|
||||
MAC_MIN_VERS = '10.4'
|
||||
MACOSX_SDK='/Developer/SDKs/MacOSX10.4u.sdk'
|
||||
CC = 'gcc-4.0'
|
||||
CXX = 'g++-4.0'
|
||||
else :
|
||||
MAC_MIN_VERS = '10.5'
|
||||
MACOSX_SDK='/Developer/SDKs/MacOSX10.5.sdk'
|
||||
CC = 'gcc-4.2'
|
||||
CXX = 'g++-4.2'
|
||||
|
||||
#############################################################################
|
||||
################### Dependency settings ##################
|
||||
#############################################################################
|
||||
|
||||
# enable ffmpeg support
|
||||
WITH_BF_FFMPEG = True # -DWITH_FFMPEG
|
||||
FFMPEG_PRECOMPILED = False
|
||||
FFMPEG_PRECOMPILED = True
|
||||
if FFMPEG_PRECOMPILED:
|
||||
# use precompiled ffmpeg in /lib
|
||||
BF_FFMPEG = LIBDIR + '/ffmpeg'
|
||||
@ -45,8 +74,8 @@ else:
|
||||
BF_FFMPEG_INC = '${BF_FFMPEG}'
|
||||
if USE_SDK==True:
|
||||
BF_FFMPEG_EXTRA = '-isysroot '+MACOSX_SDK+' -mmacosx-version-min='+MAC_MIN_VERS
|
||||
BF_XVIDCORE_CONFIG = '--disable-assembly' # currently causes errors, even with yasm installed
|
||||
BF_X264_CONFIG = '--disable-pthread'
|
||||
BF_XVIDCORE_CONFIG = '--disable-assembly --disable-mmx' # currently causes errors, even with yasm installed
|
||||
BF_X264_CONFIG = '--disable-pthread --disable-asm'
|
||||
|
||||
if BF_PYTHON_VERSION=='3.1':
|
||||
# python 3.1 uses precompiled libraries in bf svn /lib by default
|
||||
@ -76,9 +105,10 @@ else:
|
||||
if MAC_CUR_VER=='10.3' or MAC_CUR_VER=='10.4':
|
||||
BF_PYTHON_LINKFLAGS = ['-u', '__dummy']+BF_PYTHON_LINKFLAGS
|
||||
|
||||
BF_QUIET = '1'
|
||||
WITH_BF_OPENMP = '0'
|
||||
|
||||
WITH_BF_OPENMP = '0' # multithreading for fluids, cloth and smoke ( only works with ICC atm )
|
||||
|
||||
WITH_BF_OPENAL = True
|
||||
#different lib must be used following version of gcc
|
||||
# for gcc 3.3
|
||||
#BF_OPENAL = LIBDIR + '/openal'
|
||||
@ -89,11 +119,11 @@ else :
|
||||
BF_OPENAL = LIBDIR + '/openal'
|
||||
|
||||
WITH_BF_STATICOPENAL = False
|
||||
BF_OPENAL_INC = '${BF_OPENAL}/include'
|
||||
BF_OPENAL_LIB = 'openal'
|
||||
BF_OPENAL_LIBPATH = '${BF_OPENAL}/lib'
|
||||
BF_OPENAL_INC = '${BF_OPENAL}/include' # only headers from libdir needed for proper use of framework !!!!
|
||||
#BF_OPENAL_LIB = 'openal'
|
||||
#BF_OPENAL_LIBPATH = '${BF_OPENAL}/lib'
|
||||
# Warning, this static lib configuration is untested! users of this OS please confirm.
|
||||
BF_OPENAL_LIB_STATIC = '${BF_OPENAL}/lib/libopenal.a'
|
||||
#BF_OPENAL_LIB_STATIC = '${BF_OPENAL}/lib/libopenal.a'
|
||||
|
||||
# Warning, this static lib configuration is untested! users of this OS please confirm.
|
||||
BF_CXX = '/usr'
|
||||
@ -199,10 +229,13 @@ BF_FREETYPE_INC = '${BF_FREETYPE}/include ${BF_FREETYPE}/include/freetype2'
|
||||
BF_FREETYPE_LIB = 'freetype'
|
||||
BF_FREETYPE_LIBPATH = '${BF_FREETYPE}/lib'
|
||||
|
||||
WITH_BF_QUICKTIME = True # -DWITH_QUICKTIME
|
||||
if MACOSX_ARCHITECTURE == 'x86_64' or MACOSX_ARCHITECTURE == 'ppc64':
|
||||
WITH_BF_QUICKTIME = False # -DWITH_QUICKTIME ( disable for 64bit atm )
|
||||
else:
|
||||
WITH_BF_QUICKTIME = True
|
||||
|
||||
WITH_BF_ICONV = True
|
||||
BF_ICONV = LIBDIR + "/iconv"
|
||||
BF_ICONV = '/usr'
|
||||
BF_ICONV_INC = '${BF_ICONV}/include'
|
||||
BF_ICONV_LIB = 'iconv'
|
||||
#BF_ICONV_LIBPATH = '${BF_ICONV}/lib'
|
||||
@ -213,12 +246,33 @@ BF_OPENGL_LIB = 'GL GLU'
|
||||
BF_OPENGL_LIBPATH = '/System/Library/Frameworks/OpenGL.framework/Libraries'
|
||||
BF_OPENGL_LINKFLAGS = ['-framework', 'OpenGL']
|
||||
|
||||
CFLAGS = ['-pipe','-fPIC','-funsigned-char']
|
||||
#OpenCollada flags
|
||||
WITH_BF_COLLADA = False
|
||||
|
||||
CPPFLAGS = ['-fpascal-strings']
|
||||
CCFLAGS = ['-pipe','-fPIC','-funsigned-char','-fpascal-strings']
|
||||
CXXFLAGS = [ '-pipe','-fPIC','-funsigned-char', '-fpascal-strings']
|
||||
PLATFORM_LINKFLAGS = ['-fexceptions','-framework','CoreServices','-framework','Foundation','-framework','IOKit','-framework','AppKit','-framework','Carbon','-framework','AGL','-framework','AudioUnit','-framework','AudioToolbox','-framework','CoreAudio','-framework','QuickTime']
|
||||
#############################################################################
|
||||
################### various compile settings and flags ##################
|
||||
#############################################################################
|
||||
|
||||
BF_QUIET = '1' # suppress verbose output
|
||||
|
||||
if MACOSX_ARCHITECTURE == 'x86_64' or MACOSX_ARCHITECTURE == 'ppc64':
|
||||
ARCH_FLAGS = ['-m64']
|
||||
else:
|
||||
ARCH_FLAGS = ['-m32']
|
||||
|
||||
CFLAGS = ['-pipe','-funsigned-char']+ARCH_FLAGS
|
||||
|
||||
CPPFLAGS = ['-fpascal-strings']+ARCH_FLAGS
|
||||
CCFLAGS = ['-pipe','-funsigned-char','-fpascal-strings']+ARCH_FLAGS
|
||||
CXXFLAGS = ['-pipe','-funsigned-char', '-fpascal-strings']+ARCH_FLAGS
|
||||
|
||||
if WITH_GHOST_COCOA==True:
|
||||
PLATFORM_LINKFLAGS = ['-fexceptions','-framework','CoreServices','-framework','Foundation','-framework','IOKit','-framework','AppKit','-framework','Cocoa','-framework','Carbon','-framework','AudioUnit','-framework','AudioToolbox','-framework','CoreAudio','-framework','OpenAL']+ARCH_FLAGS
|
||||
else:
|
||||
PLATFORM_LINKFLAGS = ['-fexceptions','-framework','CoreServices','-framework','Foundation','-framework','IOKit','-framework','AppKit','-framework','Carbon','-framework','AGL','-framework','AudioUnit','-framework','AudioToolbox','-framework','CoreAudio','-framework','OpenAL']+ARCH_FLAGS
|
||||
|
||||
if WITH_BF_QUICKTIME == True:
|
||||
PLATFORM_LINKFLAGS = PLATFORM_LINKFLAGS+['-framework','QuickTime']
|
||||
|
||||
#note to build succesfully on 10.3.9 SDK you need to patch 10.3.9 by adding the SystemStubs.a lib from 10.4
|
||||
LLIBS = ['stdc++', 'SystemStubs']
|
||||
@ -232,33 +286,34 @@ if MAC_MIN_VERS == '10.3':
|
||||
|
||||
if USE_SDK==True:
|
||||
SDK_FLAGS=['-isysroot', MACOSX_SDK,'-mmacosx-version-min='+MAC_MIN_VERS]
|
||||
PLATFORM_LINKFLAGS = ['-mmacosx-version-min='+MAC_MIN_VERS, '-Wl,-syslibroot,' + MACOSX_SDK]+PLATFORM_LINKFLAGS
|
||||
PLATFORM_LINKFLAGS = ['-mmacosx-version-min='+MAC_MIN_VERS,'-Wl','-syslibroot '+MACOSX_SDK]+PLATFORM_LINKFLAGS
|
||||
CCFLAGS=SDK_FLAGS+CCFLAGS
|
||||
CXXFLAGS=SDK_FLAGS+CXXFLAGS
|
||||
|
||||
# you can add -mssse3 if gcc >= 4.2
|
||||
if MAC_PROC == 'i386':
|
||||
if MACOSX_ARCHITECTURE == 'i386' or MACOSX_ARCHITECTURE == 'x86_64':
|
||||
REL_CFLAGS = ['-O2','-ftree-vectorize','-msse','-msse2','-msse3']
|
||||
REL_CCFLAGS = ['-O2','-ftree-vectorize','-msse','-msse2','-msse3']
|
||||
else:
|
||||
CFLAGS = CFLAGS+['-fno-strict-aliasing']
|
||||
CCFLAGS = CCFLAGS+['-fno-strict-aliasing']
|
||||
CXXFLAGS = CXXFLAGS+['-fno-strict-aliasing']
|
||||
|
||||
REL_CFLAGS = ['-O2']
|
||||
REL_CCFLAGS = ['-O2']
|
||||
|
||||
# add -mssse3 for intel 64bit archs
|
||||
if MACOSX_ARCHITECTURE == 'x86_64':
|
||||
REL_CFLAGS = REL_CFLAGS+['-mssse3']
|
||||
REL_CCFLAGS = REL_CCFLAGS+['-mssse3']
|
||||
|
||||
##BF_DEPEND = True
|
||||
##
|
||||
##AR = ar
|
||||
##ARFLAGS = ruv
|
||||
##ARFLAGSQUIET = ru
|
||||
##
|
||||
CC = 'gcc'
|
||||
CXX = 'g++'
|
||||
C_WARN = ['-Wdeclaration-after-statement']
|
||||
#C_WARN = ['-Wdeclaration-after-statement']
|
||||
|
||||
CC_WARN = ['-Wall', '-Wno-long-double']
|
||||
CC_WARN = ['-Wall']
|
||||
|
||||
##FIX_STUBS_WARNINGS = -Wno-unused
|
||||
|
||||
@ -272,5 +327,9 @@ BF_PROFILE = False
|
||||
BF_DEBUG = False
|
||||
BF_DEBUG_CCFLAGS = ['-g']
|
||||
|
||||
#############################################################################
|
||||
################### Output directories ##################
|
||||
#############################################################################
|
||||
|
||||
BF_BUILDDIR='../build/darwin'
|
||||
BF_INSTALLDIR='../install/darwin'
|
||||
|
@ -151,6 +151,20 @@ BF_OPENGL_LIB = 'GL GLU X11 Xi'
|
||||
BF_OPENGL_LIBPATH = '/usr/X11R6/lib'
|
||||
BF_OPENGL_LIB_STATIC = '${BF_OPENGL_LIBPATH}/libGL.a ${BF_OPENGL_LIBPATH}/libGLU.a ${BF_OPENGL_LIBPATH}/libXxf86vm.a ${BF_OPENGL_LIBPATH}/libX11.a ${BF_OPENGL_LIBPATH}/libXi.a ${BF_OPENGL_LIBPATH}/libXext.a ${BF_OPENGL_LIBPATH}/libXxf86vm.a'
|
||||
|
||||
WITH_BF_COLLADA = False
|
||||
BF_COLLADA = '#source/blender/collada'
|
||||
BF_COLLADA_INC = '${BF_COLLADA}'
|
||||
BF_COLLADA_LIB = 'bf_collada'
|
||||
BF_OPENCOLLADA = ''
|
||||
BF_OPENCOLLADA_LIB = 'OpenCollada'
|
||||
BF_OPENCOLLADA_LIBPATH = '/usr/lib'
|
||||
BF_PCRE = ''
|
||||
BF_PCRE_LIB = 'pcre'
|
||||
BF_PCRE_LIBPATH = '/usr/lib'
|
||||
BF_EXPAT = '/usr'
|
||||
BF_EXPAT_LIB = 'expat'
|
||||
BF_EXPAT_LIBPATH = '/usr/lib'
|
||||
|
||||
##
|
||||
CC = 'gcc'
|
||||
CXX = 'g++'
|
||||
|
@ -126,6 +126,10 @@ BF_OPENGL_LIB = 'opengl32 glu32'
|
||||
BF_OPENGL_LIB_STATIC = [ '${BF_OPENGL}/lib/libGL.a', '${BF_OPENGL}/lib/libGLU.a',
|
||||
'${BF_OPENGL}/lib/libXmu.a', '${BF_OPENGL}/lib/libXext.a',
|
||||
'${BF_OPENGL}/lib/libX11.a', '${BF_OPENGL}/lib/libXi.a' ]
|
||||
|
||||
# Disable Collada by default
|
||||
WITH_BF_COLLADA = False
|
||||
|
||||
##
|
||||
CC = 'gcc'
|
||||
CXX = 'g++'
|
||||
|
@ -138,6 +138,16 @@ BF_FFTW3_LIBPATH = '${BF_FFTW3}/lib'
|
||||
WITH_BF_REDCODE = False
|
||||
BF_REDCODE_INC = '#extern'
|
||||
|
||||
WITH_BF_COLLADA = False
|
||||
BF_COLLADA = '#source/blender/collada'
|
||||
BF_COLLADA_INC = '${BF_COLLADA}'
|
||||
BF_COLLADA_LIB = 'bf_collada'
|
||||
|
||||
BF_OPENCOLLADA = LIBDIR + '/opencollada'
|
||||
BF_OPENCOLLADA_INC = '${BF_OPENCOLLADA}/include'
|
||||
BF_OPENCOLLADA_LIB = 'OpenCOLLADAStreamWriter OpenCOLLADASaxFrameworkLoader OpenCOLLADAFramework OpenCOLLADABaseUtils GeneratedSaxParser UTF MathMLSolver xml2 pcre'
|
||||
BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib'
|
||||
|
||||
WITH_BF_STATICOPENGL = False
|
||||
BF_OPENGL_INC = '${BF_OPENGL}/include'
|
||||
BF_OPENGL_LIBINC = '${BF_OPENGL}/lib'
|
||||
|
@ -151,6 +151,16 @@ BF_FFTW3_LIBPATH = '${BF_FFTW3}/lib'
|
||||
WITH_BF_REDCODE = False
|
||||
BF_REDCODE_INC = '#extern'
|
||||
|
||||
WITH_BF_COLLADA = False
|
||||
BF_COLLADA = '#source/blender/collada'
|
||||
BF_COLLADA_INC = '${BF_COLLADA}'
|
||||
BF_COLLADA_LIB = 'bf_collada'
|
||||
|
||||
BF_OPENCOLLADA = LIBDIR + '/opencollada'
|
||||
BF_OPENCOLLADA_INC = '${BF_OPENCOLLADA}/include'
|
||||
BF_OPENCOLLADA_LIB = 'OpenCOLLADAStreamWriter OpenCOLLADASaxFrameworkLoader OpenCOLLADAFramework OpenCOLLADABaseUtils GeneratedSaxParser UTF MathMLSolver xml2 pcre'
|
||||
BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib'
|
||||
|
||||
WITH_BF_STATICOPENGL = False
|
||||
BF_OPENGL_INC = '${BF_OPENGL}/include'
|
||||
BF_OPENGL_LIBINC = '${BF_OPENGL}/lib'
|
||||
|
@ -202,7 +202,6 @@ void btConvexConvexAlgorithm ::processCollision (btCollisionObject* body0,btColl
|
||||
input.m_maximumDistanceSquared*= input.m_maximumDistanceSquared;
|
||||
}
|
||||
|
||||
input.m_stackAlloc = dispatchInfo.m_stackAllocator;
|
||||
input.m_transformA = body0->getWorldTransform();
|
||||
input.m_transformB = body1->getWorldTransform();
|
||||
|
||||
|
@ -33,7 +33,7 @@ public:
|
||||
const btConvexShape* convexA,const btConvexShape* convexB,
|
||||
const btTransform& transA,const btTransform& transB,
|
||||
btVector3& v, btVector3& pa, btVector3& pb,
|
||||
class btIDebugDraw* debugDraw,btStackAlloc* stackAlloc
|
||||
class btIDebugDraw* debugDraw
|
||||
) = 0;
|
||||
|
||||
|
||||
|
4
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h
vendored
4
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h
vendored
@ -41,15 +41,13 @@ struct btDiscreteCollisionDetectorInterface
|
||||
struct ClosestPointInput
|
||||
{
|
||||
ClosestPointInput()
|
||||
:m_maximumDistanceSquared(btScalar(1e30)),
|
||||
m_stackAlloc(0)
|
||||
:m_maximumDistanceSquared(btScalar(1e30))
|
||||
{
|
||||
}
|
||||
|
||||
btTransform m_transformA;
|
||||
btTransform m_transformB;
|
||||
btScalar m_maximumDistanceSquared;
|
||||
btStackAlloc* m_stackAlloc;
|
||||
};
|
||||
|
||||
virtual ~btDiscreteCollisionDetectorInterface() {};
|
||||
|
2
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp
vendored
2
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp
vendored
@ -25,7 +25,7 @@ bool btGjkEpaPenetrationDepthSolver::calcPenDepth( btSimplexSolverInterface& sim
|
||||
const btConvexShape* pConvexA, const btConvexShape* pConvexB,
|
||||
const btTransform& transformA, const btTransform& transformB,
|
||||
btVector3& v, btVector3& wWitnessOnA, btVector3& wWitnessOnB,
|
||||
class btIDebugDraw* debugDraw, btStackAlloc* stackAlloc )
|
||||
class btIDebugDraw* debugDraw )
|
||||
{
|
||||
|
||||
(void)debugDraw;
|
||||
|
@ -29,7 +29,7 @@ class btGjkEpaPenetrationDepthSolver : public btConvexPenetrationDepthSolver
|
||||
const btConvexShape* pConvexA, const btConvexShape* pConvexB,
|
||||
const btTransform& transformA, const btTransform& transformB,
|
||||
btVector3& v, btVector3& wWitnessOnA, btVector3& wWitnessOnB,
|
||||
class btIDebugDraw* debugDraw,btStackAlloc* stackAlloc );
|
||||
class btIDebugDraw* debugDraw );
|
||||
|
||||
private :
|
||||
|
||||
|
@ -293,7 +293,7 @@ void btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result&
|
||||
m_minkowskiA,m_minkowskiB,
|
||||
localTransA,localTransB,
|
||||
m_cachedSeparatingAxis, tmpPointOnA, tmpPointOnB,
|
||||
debugDraw,input.m_stackAlloc
|
||||
debugDraw
|
||||
);
|
||||
|
||||
if (isValid2)
|
||||
|
3
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp
vendored
3
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp
vendored
@ -71,11 +71,10 @@ bool btMinkowskiPenetrationDepthSolver::calcPenDepth(btSimplexSolverInterface& s
|
||||
const btConvexShape* convexA,const btConvexShape* convexB,
|
||||
const btTransform& transA,const btTransform& transB,
|
||||
btVector3& v, btVector3& pa, btVector3& pb,
|
||||
class btIDebugDraw* debugDraw,btStackAlloc* stackAlloc
|
||||
class btIDebugDraw* debugDraw
|
||||
)
|
||||
{
|
||||
|
||||
(void)stackAlloc;
|
||||
(void)v;
|
||||
|
||||
|
||||
|
2
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h
vendored
2
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h
vendored
@ -28,7 +28,7 @@ public:
|
||||
const btConvexShape* convexA,const btConvexShape* convexB,
|
||||
const btTransform& transA,const btTransform& transB,
|
||||
btVector3& v, btVector3& pa, btVector3& pb,
|
||||
class btIDebugDraw* debugDraw,btStackAlloc* stackAlloc
|
||||
class btIDebugDraw* debugDraw
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -365,10 +365,6 @@ double plNearestPoints(float p1[3], float p2[3], float p3[3], float q1[3], float
|
||||
btPointCollector gjkOutput;
|
||||
btGjkPairDetector::ClosestPointInput input;
|
||||
|
||||
btStackAlloc gStackAlloc(1024*1024*2);
|
||||
|
||||
input.m_stackAlloc = &gStackAlloc;
|
||||
|
||||
btTransform tr;
|
||||
tr.setIdentity();
|
||||
|
||||
|
2
extern/glew/include/GL/glew.h
vendored
2
extern/glew/include/GL/glew.h
vendored
@ -208,7 +208,7 @@ extern "C" {
|
||||
#ifndef GL_VERSION_1_1
|
||||
#define GL_VERSION_1_1 1
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#if defined(__APPLE__) && !defined(__LP64__)
|
||||
typedef unsigned long GLenum;
|
||||
typedef unsigned long GLbitfield;
|
||||
typedef unsigned long GLuint;
|
||||
|
@ -5,8 +5,5 @@ sources = env.Glob('intern/*.cpp')
|
||||
|
||||
incs = 'intern ../container ../moto/include ../memutil'
|
||||
|
||||
if (env['OURPLATFORM'] == 'win32-mingw'):
|
||||
env.BlenderLib ('blender_BSP', sources, Split(incs), [], libtype='core', priority=26 )
|
||||
else:
|
||||
env.BlenderLib ('blender_BSP', sources, Split(incs), [], libtype='core', priority=20 )
|
||||
env.BlenderLib ('blender_BSP', sources, Split(incs), [], libtype='core', priority=200 )
|
||||
|
||||
|
@ -5,4 +5,4 @@ sources = env.Glob('intern/*.cpp')
|
||||
|
||||
incs = '. ../moto/include ../container ../memutil'
|
||||
|
||||
env.BlenderLib ('bf_decimation', sources, Split(incs) , [], libtype=['core'], priority = [10] )
|
||||
env.BlenderLib ('bf_decimation', sources, Split(incs) , [], libtype=['core'], priority = [200] )
|
||||
|
@ -7,6 +7,9 @@ Import ('env')
|
||||
window_system = env['OURPLATFORM']
|
||||
|
||||
sources = env.Glob('intern/*.cpp')
|
||||
if window_system == 'darwin':
|
||||
sources += env.Glob('intern/*.mm')
|
||||
|
||||
|
||||
pf = ['GHOST_DisplayManager', 'GHOST_System', 'GHOST_Window']
|
||||
|
||||
@ -19,9 +22,17 @@ elif window_system in ('win32-vc', 'win32-mingw', 'cygwin', 'linuxcross', 'win64
|
||||
sources.remove('intern' + os.sep + f + 'X11.cpp')
|
||||
sources.remove('intern' + os.sep + f + 'Carbon.cpp')
|
||||
elif window_system == 'darwin':
|
||||
if env['WITH_GHOST_COCOA']:
|
||||
for f in pf:
|
||||
sources.remove('intern' + os.sep + f + 'Win32.cpp')
|
||||
sources.remove('intern' + os.sep + f + 'X11.cpp')
|
||||
sources.remove('intern' + os.sep + f + 'Carbon.cpp')
|
||||
else:
|
||||
for f in pf:
|
||||
sources.remove('intern' + os.sep + f + 'Win32.cpp')
|
||||
sources.remove('intern' + os.sep + f + 'X11.cpp')
|
||||
sources.remove('intern' + os.sep + f + 'Cocoa.mm')
|
||||
|
||||
else:
|
||||
print "Unknown window system specified."
|
||||
Exit()
|
||||
@ -30,3 +41,4 @@ incs = '. ../string ' + env['BF_OPENGL_INC']
|
||||
if window_system in ('win32-vc', 'win32-mingw', 'cygwin', 'linuxcross', 'win64-vc'):
|
||||
incs = env['BF_WINTAB_INC'] + ' ' + incs
|
||||
env.BlenderLib ('bf_ghost', sources, Split(incs), defines=['_USE_MATH_DEFINES'], libtype=['intern','player'], priority = [40,15] )
|
||||
|
||||
|
@ -372,133 +372,6 @@ static GHOST_TKey convertKey(int rawCode, unichar recvChar)
|
||||
return GHOST_kKeyUnknown;
|
||||
}
|
||||
|
||||
/* MacOSX returns a Roman charset with kEventParamKeyMacCharCodes
|
||||
* as defined here: http://developer.apple.com/documentation/mac/Text/Text-516.html
|
||||
* I am not sure how international this works...
|
||||
* For cross-platform convention, we'll use the Latin ascii set instead.
|
||||
* As defined at: http://www.ramsch.org/martin/uni/fmi-hp/iso8859-1.html
|
||||
*
|
||||
*/
|
||||
static unsigned char convertRomanToLatin(unsigned char ascii)
|
||||
{
|
||||
|
||||
if(ascii<128) return ascii;
|
||||
|
||||
switch(ascii) {
|
||||
case 128: return 142;
|
||||
case 129: return 143;
|
||||
case 130: return 128;
|
||||
case 131: return 201;
|
||||
case 132: return 209;
|
||||
case 133: return 214;
|
||||
case 134: return 220;
|
||||
case 135: return 225;
|
||||
case 136: return 224;
|
||||
case 137: return 226;
|
||||
case 138: return 228;
|
||||
case 139: return 227;
|
||||
case 140: return 229;
|
||||
case 141: return 231;
|
||||
case 142: return 233;
|
||||
case 143: return 232;
|
||||
case 144: return 234;
|
||||
case 145: return 235;
|
||||
case 146: return 237;
|
||||
case 147: return 236;
|
||||
case 148: return 238;
|
||||
case 149: return 239;
|
||||
case 150: return 241;
|
||||
case 151: return 243;
|
||||
case 152: return 242;
|
||||
case 153: return 244;
|
||||
case 154: return 246;
|
||||
case 155: return 245;
|
||||
case 156: return 250;
|
||||
case 157: return 249;
|
||||
case 158: return 251;
|
||||
case 159: return 252;
|
||||
case 160: return 0;
|
||||
case 161: return 176;
|
||||
case 162: return 162;
|
||||
case 163: return 163;
|
||||
case 164: return 167;
|
||||
case 165: return 183;
|
||||
case 166: return 182;
|
||||
case 167: return 223;
|
||||
case 168: return 174;
|
||||
case 169: return 169;
|
||||
case 170: return 174;
|
||||
case 171: return 180;
|
||||
case 172: return 168;
|
||||
case 173: return 0;
|
||||
case 174: return 198;
|
||||
case 175: return 216;
|
||||
case 176: return 0;
|
||||
case 177: return 177;
|
||||
case 178: return 0;
|
||||
case 179: return 0;
|
||||
case 180: return 165;
|
||||
case 181: return 181;
|
||||
case 182: return 0;
|
||||
case 183: return 0;
|
||||
case 184: return 215;
|
||||
case 185: return 0;
|
||||
case 186: return 0;
|
||||
case 187: return 170;
|
||||
case 188: return 186;
|
||||
case 189: return 0;
|
||||
case 190: return 230;
|
||||
case 191: return 248;
|
||||
case 192: return 191;
|
||||
case 193: return 161;
|
||||
case 194: return 172;
|
||||
case 195: return 0;
|
||||
case 196: return 0;
|
||||
case 197: return 0;
|
||||
case 198: return 0;
|
||||
case 199: return 171;
|
||||
case 200: return 187;
|
||||
case 201: return 201;
|
||||
case 202: return 0;
|
||||
case 203: return 192;
|
||||
case 204: return 195;
|
||||
case 205: return 213;
|
||||
case 206: return 0;
|
||||
case 207: return 0;
|
||||
case 208: return 0;
|
||||
case 209: return 0;
|
||||
case 210: return 0;
|
||||
|
||||
case 214: return 247;
|
||||
|
||||
case 229: return 194;
|
||||
case 230: return 202;
|
||||
case 231: return 193;
|
||||
case 232: return 203;
|
||||
case 233: return 200;
|
||||
case 234: return 205;
|
||||
case 235: return 206;
|
||||
case 236: return 207;
|
||||
case 237: return 204;
|
||||
case 238: return 211;
|
||||
case 239: return 212;
|
||||
case 240: return 0;
|
||||
case 241: return 210;
|
||||
case 242: return 218;
|
||||
case 243: return 219;
|
||||
case 244: return 217;
|
||||
case 245: return 0;
|
||||
case 246: return 0;
|
||||
case 247: return 0;
|
||||
case 248: return 0;
|
||||
case 249: return 0;
|
||||
case 250: return 0;
|
||||
|
||||
|
||||
default: return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#define FIRSTFILEBUFLG 512
|
||||
static bool g_hasFirstFile = false;
|
||||
@ -827,7 +700,7 @@ GHOST_TSuccess GHOST_SystemCocoa::setCursorPosition(GHOST_TInt32 x, GHOST_TInt32
|
||||
//Quartz Display Services uses the old coordinates (top left origin)
|
||||
yf = screenRect.size.height -yf;
|
||||
|
||||
CGDisplayMoveCursorToPoint([[[windowScreen deviceDescription] objectForKey:@"NSScreenNumber"] unsignedIntValue], CGPointMake(xf, yf));
|
||||
CGDisplayMoveCursorToPoint((CGDirectDisplayID)[[[windowScreen deviceDescription] objectForKey:@"NSScreenNumber"] unsignedIntValue], CGPointMake(xf, yf));
|
||||
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
@ -913,7 +786,7 @@ bool GHOST_SystemCocoa::processEvents(bool waitForEvent)
|
||||
case NSFlagsChanged:
|
||||
handleKeyEvent(event);
|
||||
|
||||
/* Support system-wide keyboard shortcuts, like Exposé, ...) =>included in always NSApp sendEvent */
|
||||
/* Support system-wide keyboard shortcuts, like Exposé, ...) =>included in always NSApp sendEvent */
|
||||
/* if (([event modifierFlags] & NSCommandKeyMask) || [event type] == NSFlagsChanged) {
|
||||
[NSApp sendEvent:event];
|
||||
}*/
|
||||
@ -1018,8 +891,8 @@ GHOST_TUns8 GHOST_SystemCocoa::handleQuitRequest()
|
||||
//Check open windows if some changes are not saved
|
||||
if (m_windowManager->getAnyModifiedState())
|
||||
{
|
||||
int shouldQuit = NSRunAlertPanel(@"Exit Blender", @"Some changes have not been saved. Do you really want to quit ?",
|
||||
@"Cancel", @"Quit anyway", nil);
|
||||
int shouldQuit = NSRunAlertPanel(@"Exit Blender", @"Some changes have not been saved.\nDo you really want to quit ?",
|
||||
@"Cancel", @"Quit Anyway", nil);
|
||||
if (shouldQuit == NSAlertAlternateReturn)
|
||||
{
|
||||
pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventQuit, NULL) );
|
||||
@ -1255,8 +1128,10 @@ GHOST_TSuccess GHOST_SystemCocoa::handleKeyEvent(void *eventPtr)
|
||||
GHOST_IWindow* window = m_windowManager->getActiveWindow();
|
||||
unsigned int modifiers;
|
||||
NSString *characters;
|
||||
NSData *convertedCharacters;
|
||||
GHOST_TKey keyCode;
|
||||
unsigned char ascii;
|
||||
NSString* charsIgnoringModifiers;
|
||||
|
||||
/* Can happen, very rarely - seems to only be when command-H makes
|
||||
* the window go away and we still get an HKey up.
|
||||
@ -1269,17 +1144,26 @@ GHOST_TSuccess GHOST_SystemCocoa::handleKeyEvent(void *eventPtr)
|
||||
switch ([event type]) {
|
||||
case NSKeyDown:
|
||||
case NSKeyUp:
|
||||
characters = [event characters];
|
||||
if ([characters length]) { //Check for dead keys
|
||||
charsIgnoringModifiers = [event charactersIgnoringModifiers];
|
||||
if ([charsIgnoringModifiers length]>0)
|
||||
keyCode = convertKey([event keyCode],
|
||||
[[event charactersIgnoringModifiers] characterAtIndex:0]);
|
||||
ascii= convertRomanToLatin((char)[characters characterAtIndex:0]);
|
||||
} else {
|
||||
[charsIgnoringModifiers characterAtIndex:0]);
|
||||
else
|
||||
keyCode = convertKey([event keyCode],0);
|
||||
ascii= 0;
|
||||
}
|
||||
|
||||
|
||||
characters = [event characters];
|
||||
if ([characters length]>0) { //Check for dead keys
|
||||
//Convert characters to iso latin 1 encoding
|
||||
convertedCharacters = [characters dataUsingEncoding:NSISOLatin1StringEncoding];
|
||||
if ([convertedCharacters length]>0)
|
||||
ascii =((char*)[convertedCharacters bytes])[0];
|
||||
else
|
||||
ascii = 0; //Character not available in iso latin 1 encoding
|
||||
}
|
||||
else
|
||||
ascii= 0;
|
||||
|
||||
if ((keyCode == GHOST_kKeyQ) && (m_modifierMask & NSCommandKeyMask))
|
||||
break; //Cmd-Q is directly handled by Cocoa
|
||||
|
||||
|
@ -132,8 +132,8 @@
|
||||
|
||||
GHOST_SystemWin32::GHOST_SystemWin32()
|
||||
: m_hasPerformanceCounter(false), m_freq(0), m_start(0),
|
||||
m_seperateLeftRight(false),
|
||||
m_seperateLeftRightInitialized(false)
|
||||
m_separateLeftRight(false),
|
||||
m_separateLeftRightInitialized(false)
|
||||
{
|
||||
m_displayManager = new GHOST_DisplayManagerWin32 ();
|
||||
GHOST_ASSERT(m_displayManager, "GHOST_SystemWin32::GHOST_SystemWin32(): m_displayManager==0\n");
|
||||
@ -274,7 +274,7 @@ GHOST_TSuccess GHOST_SystemWin32::getModifierKeys(GHOST_ModifierKeys& keys) cons
|
||||
It didn't work all that well on some newer hardware, and worked less
|
||||
well with the passage of time, so it was fully disabled in ME.
|
||||
*/
|
||||
if (m_seperateLeftRight && m_seperateLeftRightInitialized) {
|
||||
if (m_separateLeftRight && m_separateLeftRightInitialized) {
|
||||
bool down = HIBYTE(::GetKeyState(VK_LSHIFT)) != 0;
|
||||
keys.set(GHOST_kModifierKeyLeftShift, down);
|
||||
down = HIBYTE(::GetKeyState(VK_RSHIFT)) != 0;
|
||||
@ -581,29 +581,29 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
|
||||
case VK_SHIFT:
|
||||
case VK_CONTROL:
|
||||
case VK_MENU:
|
||||
if (!system->m_seperateLeftRightInitialized) {
|
||||
if (!system->m_separateLeftRightInitialized) {
|
||||
// Check whether this system supports seperate left and right keys
|
||||
switch (wParam) {
|
||||
case VK_SHIFT:
|
||||
system->m_seperateLeftRight =
|
||||
system->m_separateLeftRight =
|
||||
(HIBYTE(::GetKeyState(VK_LSHIFT)) != 0) ||
|
||||
(HIBYTE(::GetKeyState(VK_RSHIFT)) != 0) ?
|
||||
true : false;
|
||||
break;
|
||||
case VK_CONTROL:
|
||||
system->m_seperateLeftRight =
|
||||
system->m_separateLeftRight =
|
||||
(HIBYTE(::GetKeyState(VK_LCONTROL)) != 0) ||
|
||||
(HIBYTE(::GetKeyState(VK_RCONTROL)) != 0) ?
|
||||
true : false;
|
||||
break;
|
||||
case VK_MENU:
|
||||
system->m_seperateLeftRight =
|
||||
system->m_separateLeftRight =
|
||||
(HIBYTE(::GetKeyState(VK_LMENU)) != 0) ||
|
||||
(HIBYTE(::GetKeyState(VK_RMENU)) != 0) ?
|
||||
true : false;
|
||||
break;
|
||||
}
|
||||
system->m_seperateLeftRightInitialized = true;
|
||||
system->m_separateLeftRightInitialized = true;
|
||||
}
|
||||
system->processModifierKeys(window);
|
||||
// Bypass call to DefWindowProc
|
||||
|
@ -283,9 +283,9 @@ protected:
|
||||
/** High frequency timer variable. */
|
||||
__int64 m_start;
|
||||
/** Stores the capability of this system to distinguish left and right modifier keys. */
|
||||
bool m_seperateLeftRight;
|
||||
bool m_separateLeftRight;
|
||||
/** Stores the initialization state of the member m_leftRightDistinguishable. */
|
||||
bool m_seperateLeftRightInitialized;
|
||||
bool m_separateLeftRightInitialized;
|
||||
|
||||
};
|
||||
|
||||
|
@ -43,16 +43,6 @@
|
||||
#include "GHOST_Debug.h"
|
||||
|
||||
|
||||
// Pixel Format Attributes for the windowed NSOpenGLContext
|
||||
static NSOpenGLPixelFormatAttribute pixelFormatAttrsWindow[] =
|
||||
{
|
||||
NSOpenGLPFADoubleBuffer,
|
||||
NSOpenGLPFAAccelerated,
|
||||
//NSOpenGLPFAAllowOfflineRenderers, // Removed to allow 10.4 builds, and 2 GPUs rendering is not used anyway
|
||||
NSOpenGLPFADepthSize, (NSOpenGLPixelFormatAttribute) 32,
|
||||
(NSOpenGLPixelFormatAttribute) 0
|
||||
};
|
||||
|
||||
#pragma mark Cocoa window delegate object
|
||||
/* live resize ugly patch
|
||||
extern "C" {
|
||||
@ -78,7 +68,7 @@ extern "C" {
|
||||
- (void)windowWillClose:(NSNotification *)notification;
|
||||
- (void)windowDidBecomeKey:(NSNotification *)notification;
|
||||
- (void)windowDidResignKey:(NSNotification *)notification;
|
||||
- (void)windowDidUpdate:(NSNotification *)notification;
|
||||
- (void)windowDidExpose:(NSNotification *)notification;
|
||||
- (void)windowDidResize:(NSNotification *)notification;
|
||||
@end
|
||||
|
||||
@ -101,13 +91,10 @@ extern "C" {
|
||||
|
||||
- (void)windowDidResignKey:(NSNotification *)notification
|
||||
{
|
||||
//The window is no more key when its own view becomes fullscreen
|
||||
//but ghost doesn't know the view/window difference, so hide this fact
|
||||
if (associatedWindow->getState() != GHOST_kWindowStateFullScreen)
|
||||
systemCocoa->handleWindowEvent(GHOST_kEventWindowDeactivate, associatedWindow);
|
||||
}
|
||||
|
||||
- (void)windowDidUpdate:(NSNotification *)notification
|
||||
- (void)windowDidExpose:(NSNotification *)notification
|
||||
{
|
||||
systemCocoa->handleWindowEvent(GHOST_kEventWindowUpdate, associatedWindow);
|
||||
}
|
||||
@ -191,9 +178,12 @@ GHOST_WindowCocoa::GHOST_WindowCocoa(
|
||||
GHOST_TDrawingContextType type,
|
||||
const bool stereoVisual
|
||||
) :
|
||||
GHOST_Window(title, left, top, width, height, state, GHOST_kDrawingContextTypeNone),
|
||||
GHOST_Window(title, left, top, width, height, state, GHOST_kDrawingContextTypeNone, stereoVisual),
|
||||
m_customCursor(0)
|
||||
{
|
||||
NSOpenGLPixelFormatAttribute pixelFormatAttrsWindow[40];
|
||||
int i;
|
||||
|
||||
m_systemCocoa = systemCocoa;
|
||||
m_fullScreen = false;
|
||||
|
||||
@ -225,6 +215,20 @@ GHOST_WindowCocoa::GHOST_WindowCocoa(
|
||||
setTitle(title);
|
||||
|
||||
|
||||
// Pixel Format Attributes for the windowed NSOpenGLContext
|
||||
i=0;
|
||||
pixelFormatAttrsWindow[i++] = NSOpenGLPFADoubleBuffer;
|
||||
pixelFormatAttrsWindow[i++] = NSOpenGLPFAAccelerated;
|
||||
//pixelFormatAttrsWindow[i++] = NSOpenGLPFAAllowOfflineRenderers,; // Removed to allow 10.4 builds, and 2 GPUs rendering is not used anyway
|
||||
|
||||
pixelFormatAttrsWindow[i++] = NSOpenGLPFADepthSize;
|
||||
pixelFormatAttrsWindow[i++] = (NSOpenGLPixelFormatAttribute) 32;
|
||||
|
||||
if (stereoVisual) pixelFormatAttrsWindow[i++] = NSOpenGLPFAStereo;
|
||||
|
||||
pixelFormatAttrsWindow[i] = (NSOpenGLPixelFormatAttribute) 0;
|
||||
|
||||
|
||||
//Creates the OpenGL View inside the window
|
||||
NSOpenGLPixelFormat *pixelFormat =
|
||||
[[NSOpenGLPixelFormat alloc] initWithAttributes:pixelFormatAttrsWindow];
|
||||
@ -615,6 +619,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state)
|
||||
//Make window normal and resize it
|
||||
[m_window setStyleMask:(NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask)];
|
||||
[m_window setFrame:[[m_window screen] visibleFrame] display:YES];
|
||||
//TODO for 10.6 only : window title is forgotten after the style change
|
||||
[m_window makeFirstResponder:m_openGLView];
|
||||
#else
|
||||
//With 10.5, we need to create a new window to change its style to borderless
|
||||
|
@ -76,7 +76,7 @@ abort();
|
||||
#endif /* breakpoint */
|
||||
|
||||
|
||||
#if defined(WIN32) && !defined(__GNUC__)
|
||||
#if defined(_WIN32) && !defined(__GNUC__)
|
||||
#define MT_assert(predicate) assert(predicate)
|
||||
#else
|
||||
|
||||
|
@ -7,6 +7,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "blender", "blender.vcproj",
|
||||
{6E24BF09-9653-4166-A871-F65CC9E98A9B} = {6E24BF09-9653-4166-A871-F65CC9E98A9B}
|
||||
{A90C4918-4B21-4277-93BD-AF65F30951D9} = {A90C4918-4B21-4277-93BD-AF65F30951D9}
|
||||
{FB88301F-F725-401B-ACD7-D2ABBF333B71} = {FB88301F-F725-401B-ACD7-D2ABBF333B71}
|
||||
{76D3102B-7DD2-8BA1-034A-8B19FE2897C2} = {76D3102B-7DD2-8BA1-034A-8B19FE2897C2}
|
||||
{BAAE3F2B-BCF8-4E84-B8BA-CFB2D64945FE} = {BAAE3F2B-BCF8-4E84-B8BA-CFB2D64945FE}
|
||||
{C66F722C-46BE-40C9-ABAE-2EAC7A697EB8} = {C66F722C-46BE-40C9-ABAE-2EAC7A697EB8}
|
||||
{884D8731-654C-4C7F-9A75-8F37A305BE1E} = {884D8731-654C-4C7F-9A75-8F37A305BE1E}
|
||||
@ -293,6 +294,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "INT_build_install_all", "..
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WM_windowmanager", "windowmanager\windowmanager.vcproj", "{884D8731-654C-4C7F-9A75-8F37A305BE1E}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{76D3102B-7DD2-8BA1-034A-8B19FE2897C2} = {76D3102B-7DD2-8BA1-034A-8B19FE2897C2}
|
||||
{DFE7F3E3-E62A-4677-B666-DF0DDF70C359} = {DFE7F3E3-E62A-4677-B666-DF0DDF70C359}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
@ -365,6 +367,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EXT_lzo", "..\..\extern\lzo
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BRE_raytrace", "render\BRE_raytrace.vcproj", "{37DB6A34-2E91-4ADB-BC1A-02F6D0A5E2F1}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BF_collada", "collada\BF_collada.vcproj", "{76D3102B-7DD2-8BA1-034A-8B19FE2897C2}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
3D Plugin Debug|Win32 = 3D Plugin Debug|Win32
|
||||
@ -1602,6 +1606,26 @@ Global
|
||||
{37DB6A34-2E91-4ADB-BC1A-02F6D0A5E2F1}.Debug|Win32.Build.0 = Blender Debug|Win32
|
||||
{37DB6A34-2E91-4ADB-BC1A-02F6D0A5E2F1}.Release|Win32.ActiveCfg = Blender Release|Win32
|
||||
{37DB6A34-2E91-4ADB-BC1A-02F6D0A5E2F1}.Release|Win32.Build.0 = Blender Release|Win32
|
||||
{76D3102B-7DD2-8BA1-034A-8B19FE2897C2}.3D Plugin Debug|Win32.ActiveCfg = Blender Release|Win32
|
||||
{76D3102B-7DD2-8BA1-034A-8B19FE2897C2}.3D Plugin Debug|Win32.Build.0 = Blender Release|Win32
|
||||
{76D3102B-7DD2-8BA1-034A-8B19FE2897C2}.3D Plugin Release|Win32.ActiveCfg = Blender Release|Win32
|
||||
{76D3102B-7DD2-8BA1-034A-8B19FE2897C2}.3D Plugin Release|Win32.Build.0 = Blender Release|Win32
|
||||
{76D3102B-7DD2-8BA1-034A-8B19FE2897C2}.3DPlugin Debug|Win32.ActiveCfg = Blender Release|Win32
|
||||
{76D3102B-7DD2-8BA1-034A-8B19FE2897C2}.3DPlugin Debug|Win32.Build.0 = Blender Release|Win32
|
||||
{76D3102B-7DD2-8BA1-034A-8B19FE2897C2}.3DPlugin Release|Win32.ActiveCfg = Blender Release|Win32
|
||||
{76D3102B-7DD2-8BA1-034A-8B19FE2897C2}.3DPlugin Release|Win32.Build.0 = Blender Release|Win32
|
||||
{76D3102B-7DD2-8BA1-034A-8B19FE2897C2}.Blender Debug|Win32.ActiveCfg = Blender Debug|Win32
|
||||
{76D3102B-7DD2-8BA1-034A-8B19FE2897C2}.Blender Debug|Win32.Build.0 = Blender Debug|Win32
|
||||
{76D3102B-7DD2-8BA1-034A-8B19FE2897C2}.Blender Release|Win32.ActiveCfg = Blender Release|Win32
|
||||
{76D3102B-7DD2-8BA1-034A-8B19FE2897C2}.Blender Release|Win32.Build.0 = Blender Release|Win32
|
||||
{76D3102B-7DD2-8BA1-034A-8B19FE2897C2}.BlenderPlayer Debug|Win32.ActiveCfg = Blender Release|Win32
|
||||
{76D3102B-7DD2-8BA1-034A-8B19FE2897C2}.BlenderPlayer Debug|Win32.Build.0 = Blender Release|Win32
|
||||
{76D3102B-7DD2-8BA1-034A-8B19FE2897C2}.BlenderPlayer Release|Win32.ActiveCfg = Blender Release|Win32
|
||||
{76D3102B-7DD2-8BA1-034A-8B19FE2897C2}.BlenderPlayer Release|Win32.Build.0 = Blender Release|Win32
|
||||
{76D3102B-7DD2-8BA1-034A-8B19FE2897C2}.Debug|Win32.ActiveCfg = Blender Debug|Win32
|
||||
{76D3102B-7DD2-8BA1-034A-8B19FE2897C2}.Debug|Win32.Build.0 = Blender Debug|Win32
|
||||
{76D3102B-7DD2-8BA1-034A-8B19FE2897C2}.Release|Win32.ActiveCfg = Blender Release|Win32
|
||||
{76D3102B-7DD2-8BA1-034A-8B19FE2897C2}.Release|Win32.Build.0 = Blender Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -74,12 +74,12 @@
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/MACHINE:I386"
|
||||
AdditionalDependencies="libsamplerate.lib SDL.lib freetype2ST.lib gnu_gettext.lib qtmlClient.lib OpenAL32.lib wrap_oal.lib ws2_32.lib dxguid.lib opengl32.lib libjpeg.lib glu32.lib vfw32.lib winmm.lib libpng_st.lib zlib.lib python31.lib pthreadVSE2.lib pthreadVC2.lib libtiff.lib Half.lib Iex.lib IlmImf.lib Imath.lib IlmThread.lib avcodec-52.lib avformat-52.lib avutil-50.lib swscale-0.lib avdevice-52.lib libsndfile-1.lib"
|
||||
AdditionalDependencies="libsamplerate.lib SDL.lib freetype2ST.lib gnu_gettext.lib qtmlClient.lib OpenAL32.lib wrap_oal.lib ws2_32.lib dxguid.lib opengl32.lib libjpeg.lib glu32.lib vfw32.lib winmm.lib libpng_st.lib zlib.lib python31.lib pthreadVSE2.lib pthreadVC2.lib libtiff.lib Half.lib Iex.lib IlmImf.lib Imath.lib IlmThread.lib avcodec-52.lib avformat-52.lib avutil-50.lib swscale-0.lib avdevice-52.lib libsndfile-1.lib OpenCOLLADABaseUtils.lib OpenCOLLADAFramework.lib OpenCOLLADAStreamWriter.lib OpenCOLLADASaxFrameworkLoader.lib pcre.lib UTF.lib GeneratedSaxParser.lib MathMLSolver.lib xml2.lib"
|
||||
ShowProgress="0"
|
||||
OutputFile="..\..\..\install\msvc_9\blender.exe"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
AdditionalLibraryDirectories="..\..\..\lib\windows\sdl\lib;..\..\..\lib\windows\ode\lib;..\..\..\lib\windows\zlib\lib;..\..\..\lib\windows\png\lib;..\..\..\lib\windows\jpeg\lib;..\..\..\lib\windows\gettext\lib;..\..\..\lib\windows\python\lib;..\..\..\lib\windows\freetype\lib;..\..\..\lib\windows\tiff\lib;..\..\..\lib\windows\pthreads\lib;..\..\..\lib\windows\openal\lib;..\..\..\lib\windows\openexr\lib_vs2008;..\..\..\lib\windows\QTDevWin\Libraries;..\..\..\build\msvc_9\libs\intern;..\..\..\build\msvc_9\libs\extern;..\..\..\lib\windows\ffmpeg\lib;..\..\..\lib\windows\samplerate\lib;..\..\..\lib\windows\sndfile\lib"
|
||||
AdditionalLibraryDirectories="..\..\..\lib\windows\sdl\lib;..\..\..\lib\windows\ode\lib;..\..\..\lib\windows\zlib\lib;..\..\..\lib\windows\png\lib;..\..\..\lib\windows\jpeg\lib;..\..\..\lib\windows\gettext\lib;..\..\..\lib\windows\python\lib;..\..\..\lib\windows\freetype\lib;..\..\..\lib\windows\tiff\lib;..\..\..\lib\windows\pthreads\lib;..\..\..\lib\windows\openal\lib;..\..\..\lib\windows\openexr\lib_vs2008;..\..\..\lib\windows\QTDevWin\Libraries;..\..\..\build\msvc_9\libs\intern;..\..\..\build\msvc_9\libs\extern;..\..\..\lib\windows\ffmpeg\lib;..\..\..\lib\windows\samplerate\lib;..\..\..\lib\windows\sndfile\lib;..\..\..\lib\windows\opencollada\lib"
|
||||
IgnoreAllDefaultLibraries="false"
|
||||
IgnoreDefaultLibraryNames="msvcprt.lib;glut32.lib;libc.lib;libcd.lib;libcpd.lib;libcp.lib;libcmtd.lib;odbc32.lib;odbccp32.lib"
|
||||
GenerateDebugInformation="true"
|
||||
@ -169,12 +169,12 @@
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/MACHINE:I386
"
|
||||
AdditionalDependencies="libsamplerate.lib SDL.lib freetype2ST.lib gnu_gettext.lib qtmlClient.lib OpenAL32.lib wrap_oal.lib ws2_32.lib dxguid.lib opengl32.lib libjpeg.lib glu32.lib vfw32.lib winmm.lib libpng_st.lib zlib.lib python31_d.lib pthreadVSE2.lib pthreadVC2.lib libtiff.lib Half_d.lib Iex_d.lib Imath_d.lib IlmImf_d.lib IlmThread_d.lib avcodec-52.lib avformat-52.lib avdevice-52.lib avutil-50.lib swscale-0.lib libsndfile-1.lib"
|
||||
AdditionalDependencies="libsamplerate.lib SDL.lib freetype2ST.lib gnu_gettext.lib qtmlClient.lib OpenAL32.lib wrap_oal.lib ws2_32.lib dxguid.lib opengl32.lib libjpeg.lib glu32.lib vfw32.lib winmm.lib libpng_st.lib zlib.lib python31_d.lib pthreadVSE2.lib pthreadVC2.lib libtiff.lib Half_d.lib Iex_d.lib Imath_d.lib IlmImf_d.lib IlmThread_d.lib avcodec-52.lib avformat-52.lib avdevice-52.lib avutil-50.lib swscale-0.lib libsndfile-1.lib OpenCOLLADABaseUtils.lib OpenCOLLADAFramework.lib OpenCOLLADAStreamWriter.lib OpenCOLLADASaxFrameworkLoader.lib pcre.lib UTF.lib GeneratedSaxParser.lib MathMLSolver.lib xml2.lib"
|
||||
ShowProgress="0"
|
||||
OutputFile="..\..\..\install\msvc_9d\blender.exe"
|
||||
LinkIncremental="2"
|
||||
SuppressStartupBanner="true"
|
||||
AdditionalLibraryDirectories="..\..\..\lib\windows\sdl\lib;..\..\..\lib\windows\ode\lib;..\..\..\lib\windows\zlib\lib;..\..\..\lib\windows\png\lib;..\..\..\lib\windows\jpeg\lib;..\..\..\lib\windows\pthreads\lib;..\..\..\lib\windows\tiff\lib;..\..\..\lib\windows\gettext\lib;..\..\..\lib\windows\freetype\lib;..\..\..\lib\windows\python\lib;..\..\..\lib\windows\openal\lib;..\..\..\lib\windows\openexr\lib_vs2008;..\..\..\lib\windows\QTDevWin\Libraries;..\..\..\lib\windows\ffmpeg\lib;..\..\..\build\msvc_9\libs\intern\debug;..\..\..\build\msvc_9\libs\extern\debug;..\..\..\lib\windows\samplerate\lib;..\..\..\lib\windows\sndfile\lib"
|
||||
AdditionalLibraryDirectories="..\..\..\lib\windows\sdl\lib;..\..\..\lib\windows\ode\lib;..\..\..\lib\windows\zlib\lib;..\..\..\lib\windows\png\lib;..\..\..\lib\windows\jpeg\lib;..\..\..\lib\windows\pthreads\lib;..\..\..\lib\windows\tiff\lib;..\..\..\lib\windows\gettext\lib;..\..\..\lib\windows\freetype\lib;..\..\..\lib\windows\python\lib;..\..\..\lib\windows\openal\lib;..\..\..\lib\windows\openexr\lib_vs2008;..\..\..\lib\windows\QTDevWin\Libraries;..\..\..\lib\windows\ffmpeg\lib;..\..\..\build\msvc_9\libs\intern\debug;..\..\..\build\msvc_9\libs\extern\debug;..\..\..\lib\windows\samplerate\lib;..\..\..\lib\windows\sndfile\lib;..\..\..\lib\windows\opencollada\lib"
|
||||
IgnoreDefaultLibraryNames="libc.lib, libcmt.lib, msvcrt.lib, libcd.lib, odbc32.lib, odbccp32.lib"
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="..\..\..\build\msvc_9\libs\debug\blender.pdb"
|
||||
|
214
projectfiles_vc9/blender/collada/BF_collada.vcproj
Normal file
214
projectfiles_vc9/blender/collada/BF_collada.vcproj
Normal file
@ -0,0 +1,214 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9,00"
|
||||
Name="BF_collada"
|
||||
ProjectGUID="{76D3102B-7DD2-8BA1-034A-8B19FE2897C2}"
|
||||
RootNamespace="BF_collada"
|
||||
TargetFrameworkVersion="131072"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Blender Debug|Win32"
|
||||
OutputDirectory="..\..\..\..\build\msvc_9\source\blender\collada\debug"
|
||||
IntermediateDirectory="..\..\..\..\build\msvc_9\source\blender\collada\debug"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\windowmanager;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\editors\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\lib\windows\opencollada\include\COLLADAStreamWriter\include;..\..\..\..\lib\windows\opencollada\include\COLLADABaseUtils\include;..\..\..\..\lib\windows\opencollada\include\COLLADAFramework\include;..\..\..\..\lib\windows\opencollada\include\COLLADASaxFrameworkLoader\include"
|
||||
PreprocessorDefinitions="WIN32,_DEBUG,_LIB"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
DefaultCharIsUnsigned="true"
|
||||
UsePrecompiledHeader="0"
|
||||
PrecompiledHeaderFile="..\..\..\..\build\msvc_9\source\blender\collada\debug\BF_collada.pch"
|
||||
AssemblerListingLocation="..\..\..\..\build\msvc_9\source\blender\collada\debug\"
|
||||
ObjectFile="..\..\..\..\build\msvc_9\source\blender\collada\debug\"
|
||||
ProgramDataBaseFileName="..\..\..\..\build\msvc_9\source\blender\collada\debug\"
|
||||
WarningLevel="2"
|
||||
SuppressStartupBanner="true"
|
||||
DebugInformationFormat="3"
|
||||
CompileAs="0"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="1043"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
OutputFile="..\..\..\..\build\msvc_9\libs\debug\BF_collada.lib"
|
||||
SuppressStartupBanner="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Blender Release|Win32"
|
||||
OutputDirectory="..\..\..\..\build\msvc_9\source\blender\collada"
|
||||
IntermediateDirectory="..\..\..\..\build\msvc_9\source\blender\collada"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="1"
|
||||
AdditionalIncludeDirectories="..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\windowmanager;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\editors\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\lib\windows\opencollada\include\COLLADAStreamWriter\include;..\..\..\..\lib\windows\opencollada\include\COLLADABaseUtils\include;..\..\..\..\lib\windows\opencollada\include\COLLADAFramework\include;..\..\..\..\lib\windows\opencollada\include\COLLADASaxFrameworkLoader\include"
|
||||
PreprocessorDefinitions="WIN32,NDEBUG,_LIB"
|
||||
StringPooling="true"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="true"
|
||||
DefaultCharIsUnsigned="true"
|
||||
UsePrecompiledHeader="0"
|
||||
PrecompiledHeaderFile="..\..\..\..\build\msvc_9\source\blender\yafray\BF_collada.pch"
|
||||
AssemblerListingLocation="..\..\..\..\build\msvc_9\source\blender\collada\"
|
||||
ObjectFile="..\..\..\..\build\msvc_9\source\blender\collada\"
|
||||
ProgramDataBaseFileName="..\..\..\..\build\msvc_9\source\blender\collada\"
|
||||
WarningLevel="2"
|
||||
SuppressStartupBanner="true"
|
||||
CompileAs="0"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="1043"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
OutputFile="..\..\..\..\build\msvc_9\libs\BF_collada.lib"
|
||||
SuppressStartupBanner="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\collada\collada.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\collada\DocumentExporter.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\collada\DocumentImporter.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\collada\collada.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\collada\collada_internal.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\collada\DocumentExporter.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\collada\DocumentImporter.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
@ -43,8 +43,8 @@
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="..\..\..\..\lib\windows\pthreads\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\ghost\include;..\..\..\..\build\msvc_9\intern\memutil\include;..\..\..\source\blender\blenlib;..\..\..\source\blender\imbuf;..\..\..\source\blender\python;..\..\..\source\blender\blenkernel;..\..\..\source\blender\blenfont;..\..\..\source\blender\blenloader;..\..\..\source\blender\gpu;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\kernel\gen_system;..\..\..\source\kernel\gen_messaging;..\..\..\source\blender\windowmanager;..\..\..\source\blender\editors\include;..\..\..\..\build\msvc_9\intern\bmfont\include;..\..\..\source\blender\render\extern\include;..\..\..\source\blender\radiosity\extern\include"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
|
||||
AdditionalIncludeDirectories="..\..\..\..\lib\windows\pthreads\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\ghost\include;..\..\..\..\build\msvc_9\intern\memutil\include;..\..\..\source\blender\blenlib;..\..\..\source\blender\imbuf;..\..\..\source\blender\python;..\..\..\source\blender\blenkernel;..\..\..\source\blender\blenfont;..\..\..\source\blender\blenloader;..\..\..\source\blender\gpu;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\kernel\gen_system;..\..\..\source\kernel\gen_messaging;..\..\..\source\blender\windowmanager;..\..\..\source\blender\editors\include;..\..\..\..\build\msvc_9\intern\bmfont\include;..\..\..\source\blender\render\extern\include;..\..\..\source\blender\radiosity\extern\include;..\..\..\source\blender\collada"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;WITH_COLLADA"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
@ -113,8 +113,8 @@
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
AdditionalIncludeDirectories="..\..\..\..\lib\windows\pthreads\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\ghost\include;..\..\..\..\build\msvc_9\intern\memutil\include;..\..\..\source\blender\blenlib;..\..\..\source\blender\imbuf;..\..\..\source\blender\python;..\..\..\source\blender\blenkernel;..\..\..\source\blender\blenfont;..\..\..\source\blender\blenloader;..\..\..\source\blender\gpu;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\kernel\gen_system;..\..\..\source\kernel\gen_messaging;..\..\..\source\blender\windowmanager;..\..\..\source\blender\editors\include;..\..\..\..\build\msvc_9\intern\bmfont\include;..\..\..\source\blender\render\extern\include;..\..\..\source\blender\radiosity\extern\include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
|
||||
AdditionalIncludeDirectories="..\..\..\..\lib\windows\pthreads\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\ghost\include;..\..\..\..\build\msvc_9\intern\memutil\include;..\..\..\source\blender\blenlib;..\..\..\source\blender\imbuf;..\..\..\source\blender\python;..\..\..\source\blender\blenkernel;..\..\..\source\blender\blenfont;..\..\..\source\blender\blenloader;..\..\..\source\blender\gpu;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\kernel\gen_system;..\..\..\source\kernel\gen_messaging;..\..\..\source\blender\windowmanager;..\..\..\source\blender\editors\include;..\..\..\..\build\msvc_9\intern\bmfont\include;..\..\..\source\blender\render\extern\include;..\..\..\source\blender\radiosity\extern\include;..\..\..\source\blender\collada"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;WITH_COLLADA"
|
||||
MinimalRebuild="true"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="false"
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 191 KiB After Width: | Height: | Size: 190 KiB |
@ -1,3 +1,21 @@
|
||||
# ##### 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
import bpy
|
||||
|
||||
from math import atan, pi, degrees
|
||||
@ -697,8 +715,8 @@ IntProperty( attr="pov_radio_recursion_limit",
|
||||
|
||||
|
||||
class PovrayRender(bpy.types.RenderEngine):
|
||||
__idname__ = 'POVRAY_RENDER'
|
||||
__label__ = "Povray"
|
||||
bl_idname = 'POVRAY_RENDER'
|
||||
bl_label = "Povray"
|
||||
DELAY = 0.02
|
||||
|
||||
def _export(self, scene):
|
||||
@ -826,33 +844,33 @@ class PovrayRender(bpy.types.RenderEngine):
|
||||
bpy.types.register(PovrayRender)
|
||||
|
||||
# Use some of the existing buttons.
|
||||
import buttons_render
|
||||
buttons_render.RENDER_PT_render.COMPAT_ENGINES.add('POVRAY_RENDER')
|
||||
buttons_render.RENDER_PT_dimensions.COMPAT_ENGINES.add('POVRAY_RENDER')
|
||||
buttons_render.RENDER_PT_antialiasing.COMPAT_ENGINES.add('POVRAY_RENDER')
|
||||
buttons_render.RENDER_PT_output.COMPAT_ENGINES.add('POVRAY_RENDER')
|
||||
del buttons_render
|
||||
import properties_render
|
||||
properties_render.RENDER_PT_render.COMPAT_ENGINES.add('POVRAY_RENDER')
|
||||
properties_render.RENDER_PT_dimensions.COMPAT_ENGINES.add('POVRAY_RENDER')
|
||||
properties_render.RENDER_PT_antialiasing.COMPAT_ENGINES.add('POVRAY_RENDER')
|
||||
properties_render.RENDER_PT_output.COMPAT_ENGINES.add('POVRAY_RENDER')
|
||||
del properties_render
|
||||
|
||||
# Use only a subset of the world panels
|
||||
import buttons_world
|
||||
buttons_world.WORLD_PT_preview.COMPAT_ENGINES.add('POVRAY_RENDER')
|
||||
buttons_world.WORLD_PT_context_world.COMPAT_ENGINES.add('POVRAY_RENDER')
|
||||
buttons_world.WORLD_PT_world.COMPAT_ENGINES.add('POVRAY_RENDER')
|
||||
buttons_world.WORLD_PT_mist.COMPAT_ENGINES.add('POVRAY_RENDER')
|
||||
del buttons_world
|
||||
import properties_world
|
||||
properties_world.WORLD_PT_preview.COMPAT_ENGINES.add('POVRAY_RENDER')
|
||||
properties_world.WORLD_PT_context_world.COMPAT_ENGINES.add('POVRAY_RENDER')
|
||||
properties_world.WORLD_PT_world.COMPAT_ENGINES.add('POVRAY_RENDER')
|
||||
properties_world.WORLD_PT_mist.COMPAT_ENGINES.add('POVRAY_RENDER')
|
||||
del properties_world
|
||||
|
||||
# Example of wrapping every class 'as is'
|
||||
import buttons_material
|
||||
for member in dir(buttons_material):
|
||||
subclass = getattr(buttons_material, member)
|
||||
import properties_material
|
||||
for member in dir(properties_material):
|
||||
subclass = getattr(properties_material, member)
|
||||
try: subclass.COMPAT_ENGINES.add('POVRAY_RENDER')
|
||||
except: pass
|
||||
del buttons_material
|
||||
del properties_material
|
||||
|
||||
class RenderButtonsPanel(bpy.types.Panel):
|
||||
__space_type__ = 'PROPERTIES'
|
||||
__region_type__ = 'WINDOW'
|
||||
__context__ = "render"
|
||||
bl_space_type = 'PROPERTIES'
|
||||
bl_region_type = 'WINDOW'
|
||||
bl_context = "render"
|
||||
# COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here
|
||||
|
||||
def poll(self, context):
|
||||
@ -860,7 +878,7 @@ class RenderButtonsPanel(bpy.types.Panel):
|
||||
return (rd.use_game_engine==False) and (rd.engine in self.COMPAT_ENGINES)
|
||||
|
||||
class RENDER_PT_povray_radiosity(RenderButtonsPanel):
|
||||
__label__ = "Radiosity"
|
||||
bl_label = "Radiosity"
|
||||
COMPAT_ENGINES = set(['POVRAY_RENDER'])
|
||||
|
||||
def draw_header(self, context):
|
||||
|
@ -1,4 +1,22 @@
|
||||
# coding: utf-8
|
||||
# ##### 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
__author__ = ["Campbell Barton", "Bob Holcomb", "Richard Lärkäng", "Damien McGinnes", "Mark Stijnman"]
|
||||
__url__ = ("blenderartists.org", "www.blender.org", "www.gametutorials.com", "lib3ds.sourceforge.net/")
|
||||
__version__ = "0.90a"
|
||||
@ -1090,19 +1108,19 @@ def save_3ds(filename, context):
|
||||
# else:
|
||||
# Blender.Draw.PupMenu("Error%t|This script requires a full python installation")
|
||||
# # save_3ds('/test_b.3ds')
|
||||
|
||||
class EXPORT_OT_3ds(bpy.types.Operator):
|
||||
from bpy.props import *
|
||||
class Export3DS(bpy.types.Operator):
|
||||
'''Export to 3DS file format (.3ds).'''
|
||||
__idname__ = "export.3ds"
|
||||
__label__ = 'Export 3DS'
|
||||
bl_idname = "export.autodesk_3ds"
|
||||
bl_label = 'Export 3DS'
|
||||
|
||||
# List of operator properties, the attributes will be assigned
|
||||
# to the class instance from the operator settings before calling.
|
||||
|
||||
__props__ = [
|
||||
# bpy.props.StringProperty(attr="filename", name="File Name", description="File name used for exporting the 3DS file", maxlen= 1024, default= ""),
|
||||
bpy.props.StringProperty(attr="path", name="File Path", description="File path used for exporting the 3DS file", maxlen= 1024, default= ""),
|
||||
]
|
||||
|
||||
# filename = StringProperty(name="File Name", description="File name used for exporting the 3DS file", maxlen= 1024, default= ""),
|
||||
path = StringProperty(name="File Path", description="File path used for exporting the 3DS file", maxlen= 1024, default= "")
|
||||
|
||||
|
||||
def execute(self, context):
|
||||
save_3ds(self.path, context)
|
||||
@ -1110,16 +1128,20 @@ class EXPORT_OT_3ds(bpy.types.Operator):
|
||||
|
||||
def invoke(self, context, event):
|
||||
wm = context.manager
|
||||
wm.add_fileselect(self.__operator__)
|
||||
wm.add_fileselect(self)
|
||||
return ('RUNNING_MODAL',)
|
||||
|
||||
def poll(self, context): # Poll isnt working yet
|
||||
print("Poll")
|
||||
return context.active_object != None
|
||||
|
||||
bpy.ops.add(EXPORT_OT_3ds)
|
||||
bpy.ops.add(Export3DS)
|
||||
|
||||
# Add to a menu
|
||||
import dynamic_menu
|
||||
menu_func = lambda self, context: self.layout.itemO("export.3ds", text="Autodesk 3DS...")
|
||||
|
||||
def menu_func(self, context):
|
||||
default_path = bpy.data.filename.replace(".blend", ".3ds")
|
||||
self.layout.item_stringO(Export3DS.bl_idname, "path", default_path, text="Autodesk 3DS...")
|
||||
|
||||
menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_export, menu_func)
|
||||
|
@ -1,3 +1,21 @@
|
||||
# ##### 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
__author__ = "Campbell Barton"
|
||||
__url__ = ['www.blender.org', 'blenderartists.org']
|
||||
__version__ = "1.2"
|
||||
@ -219,14 +237,14 @@ def sane_groupname(data): return sane_name(data, sane_name_mapping_group)
|
||||
# FORCE_CWD - dont use the basepath, just add a ./ to the filename.
|
||||
# use when we know the file will be in the basepath.
|
||||
# '''
|
||||
# fname = bpy.sys.expandpath(fname_orig)
|
||||
# fname = bpy.utils.expandpath(fname_orig)
|
||||
# # fname = Blender.sys.expandpath(fname_orig)
|
||||
# fname_strip = os.path.basename(fname)
|
||||
# # fname_strip = strip_path(fname)
|
||||
# if FORCE_CWD:
|
||||
# fname_rel = '.' + os.sep + fname_strip
|
||||
# else:
|
||||
# fname_rel = bpy.sys.relpath(fname, basepath)
|
||||
# fname_rel = bpy.utils.relpath(fname, basepath)
|
||||
# # fname_rel = Blender.sys.relpath(fname, basepath)
|
||||
# if fname_rel.startswith('//'): fname_rel = '.' + os.sep + fname_rel[2:]
|
||||
# return fname, fname_strip, fname_rel
|
||||
@ -331,7 +349,7 @@ def write(filename, batch_objects = None, \
|
||||
fbxpath = filename
|
||||
|
||||
# get the path component of filename
|
||||
tmp_exists = bpy.sys.exists(fbxpath)
|
||||
tmp_exists = bpy.utils.exists(fbxpath)
|
||||
# tmp_exists = Blender.sys.exists(fbxpath)
|
||||
|
||||
if tmp_exists != 2: # a file, we want a path
|
||||
@ -345,7 +363,7 @@ def write(filename, batch_objects = None, \
|
||||
# Draw.PupMenu('Error%t|Directory does not exist!')
|
||||
return
|
||||
|
||||
tmp_exists = bpy.sys.exists(fbxpath)
|
||||
tmp_exists = bpy.utils.exists(fbxpath)
|
||||
# tmp_exists = Blender.sys.exists(fbxpath)
|
||||
|
||||
if tmp_exists != 2:
|
||||
@ -380,7 +398,7 @@ def write(filename, batch_objects = None, \
|
||||
# path may alredy exist
|
||||
# TODO - might exist but be a file. unlikely but should probably account for it.
|
||||
|
||||
if bpy.sys.exists(new_fbxpath) == 0:
|
||||
if bpy.utils.exists(new_fbxpath) == 0:
|
||||
# if Blender.sys.exists(new_fbxpath) == 0:
|
||||
os.mkdir(new_fbxpath)
|
||||
|
||||
@ -3332,44 +3350,44 @@ def write_ui():
|
||||
|
||||
|
||||
# GLOBALS.clear()
|
||||
|
||||
class EXPORT_OT_fbx(bpy.types.Operator):
|
||||
from bpy.props import *
|
||||
class ExportFBX(bpy.types.Operator):
|
||||
'''Selection to an ASCII Autodesk FBX'''
|
||||
__idname__ = "export.fbx"
|
||||
__label__ = "Export 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.
|
||||
|
||||
__props__ = [
|
||||
bpy.props.StringProperty(attr="path", name="File Path", description="File path used for exporting the FBX file", maxlen= 1024, default= ""),
|
||||
|
||||
bpy.props.BoolProperty(attr="EXP_OBS_SELECTED", name="Selected Objects", description="Export selected objects on visible layers", default=True),
|
||||
# bpy.props.BoolProperty(attr="EXP_OBS_SCENE", name="Scene Objects", description="Export all objects in this scene", default=True),
|
||||
bpy.props.FloatProperty(attr="_SCALE", 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),
|
||||
bpy.props.BoolProperty(attr="_XROT90", name="Rot X90", description="Rotate all objects 90 degrese about the X axis", default=True),
|
||||
bpy.props.BoolProperty(attr="_YROT90", name="Rot Y90", description="Rotate all objects 90 degrese about the Y axis", default=False),
|
||||
bpy.props.BoolProperty(attr="_ZROT90", name="Rot Z90", description="Rotate all objects 90 degrese about the Z axis", default=False),
|
||||
bpy.props.BoolProperty(attr="EXP_EMPTY", name="Empties", description="Export empty objects", default=True),
|
||||
bpy.props.BoolProperty(attr="EXP_CAMERA", name="Cameras", description="Export camera objects", default=True),
|
||||
bpy.props.BoolProperty(attr="EXP_LAMP", name="Lamps", description="Export lamp objects", default=True),
|
||||
bpy.props.BoolProperty(attr="EXP_ARMATURE", name="Armatures", description="Export armature objects", default=True),
|
||||
bpy.props.BoolProperty(attr="EXP_MESH", name="Meshes", description="Export mesh objects", default=True),
|
||||
bpy.props.BoolProperty(attr="EXP_MESH_APPLY_MOD", name="Modifiers", description="Apply modifiers to mesh objects", default=True),
|
||||
bpy.props.BoolProperty(attr="EXP_MESH_HQ_NORMALS", name="HQ Normals", description="Generate high quality normals", default=True),
|
||||
bpy.props.BoolProperty(attr="EXP_IMAGE_COPY", name="Copy Image Files", description="Copy image files to the destination path", default=False),
|
||||
path = StringProperty(name="File Path", description="File path used for exporting the FBX file", maxlen= 1024, default= "")
|
||||
|
||||
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)
|
||||
_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)
|
||||
_XROT90 = BoolProperty(name="Rot X90", description="Rotate all objects 90 degrese about the X axis", default=True)
|
||||
_YROT90 = BoolProperty(name="Rot Y90", description="Rotate all objects 90 degrese about the Y axis", default=False)
|
||||
_ZROT90 = BoolProperty(name="Rot Z90", description="Rotate all objects 90 degrese 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
|
||||
bpy.props.BoolProperty(attr="ANIM_ENABLE", name="Enable Animation", description="Export keyframe animation", default=True),
|
||||
bpy.props.BoolProperty(attr="ANIM_OPTIMIZE", name="Optimize Keyframes", description="Remove double keyframes", default=True),
|
||||
bpy.props.FloatProperty(attr="ANIM_OPTIMIZE_PRECISSION", 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),
|
||||
# bpy.props.BoolProperty(attr="ANIM_ACTION_ALL", name="Current Action", description="Use actions currently applied to the armatures (use scene start/end frame)", default=True),
|
||||
bpy.props.BoolProperty(attr="ANIM_ACTION_ALL", name="All Actions", description="Use all actions for armatures, if false, use current action", default=False),
|
||||
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
|
||||
bpy.props.BoolProperty(attr="BATCH_ENABLE", name="Enable Batch", description="Automate exporting multiple scenes or groups to files", default=False),
|
||||
bpy.props.BoolProperty(attr="BATCH_GROUP", name="Group > File", description="Export each group as an FBX file, if false, export each scene as an FBX file", default=False),
|
||||
bpy.props.BoolProperty(attr="BATCH_OWN_DIR", name="Own Dir", description="Create a dir for each exported file", default=True),
|
||||
bpy.props.StringProperty(attr="BATCH_FILE_PREFIX", name="Prefix", description="Prefix each file with this name", maxlen= 1024, default=""),
|
||||
]
|
||||
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 poll(self, context):
|
||||
print("Poll")
|
||||
@ -3411,11 +3429,11 @@ class EXPORT_OT_fbx(bpy.types.Operator):
|
||||
|
||||
def invoke(self, context, event):
|
||||
wm = context.manager
|
||||
wm.add_fileselect(self.__operator__)
|
||||
wm.add_fileselect(self)
|
||||
return ('RUNNING_MODAL',)
|
||||
|
||||
|
||||
bpy.ops.add(EXPORT_OT_fbx)
|
||||
bpy.ops.add(ExportFBX)
|
||||
|
||||
# if __name__ == "__main__":
|
||||
# bpy.ops.EXPORT_OT_ply(filename="/tmp/test.ply")
|
||||
@ -3438,7 +3456,7 @@ bpy.ops.add(EXPORT_OT_fbx)
|
||||
# - bpy.data.remove_scene: line 366
|
||||
# - bpy.sys.time move to bpy.sys.util?
|
||||
# - new scene creation, activation: lines 327-342, 368
|
||||
# - uses bpy.sys.expandpath, *.relpath - replace at least relpath
|
||||
# - uses bpy.utils.expandpath, *.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')
|
||||
@ -3446,6 +3464,10 @@ bpy.ops.add(EXPORT_OT_fbx)
|
||||
|
||||
# Add to a menu
|
||||
import dynamic_menu
|
||||
menu_func = lambda self, context: self.layout.itemO("export.fbx", text="Autodesk FBX...")
|
||||
|
||||
def menu_func(self, context):
|
||||
default_path = bpy.data.filename.replace(".blend", ".fbx")
|
||||
self.layout.item_stringO(ExportFBX.bl_idname, "path", default_path, text="Autodesk FBX...")
|
||||
|
||||
menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_export, menu_func)
|
||||
|
||||
|
@ -1,3 +1,20 @@
|
||||
# ##### 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
__author__ = "Bill L.Nieuwendorp"
|
||||
__bpydoc__ = """\
|
||||
@ -61,18 +78,15 @@ def check_vertcount(mesh,vertcount):
|
||||
|
||||
|
||||
def write(filename, sce, ob, PREF_STARTFRAME, PREF_ENDFRAME, PREF_FPS):
|
||||
if not pack:
|
||||
raise Exception('Error, this script requires the "pack" module')
|
||||
|
||||
if ob.type != 'MESH':
|
||||
raise Exception('Error, active object is not a mesh')
|
||||
"""
|
||||
Window.EditMode(0)
|
||||
Blender.Window.WaitCursor(1)
|
||||
|
||||
mesh_orig = Mesh.New()
|
||||
mesh_orig.getFromObject(ob.name)
|
||||
"""
|
||||
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
|
||||
orig_frame = sce.current_frame
|
||||
sce.set_frame(PREF_STARTFRAME)
|
||||
me = ob.create_mesh(True, 'PREVIEW')
|
||||
@ -133,10 +147,12 @@ def write(filename, sce, ob, PREF_STARTFRAME, PREF_ENDFRAME, PREF_FPS):
|
||||
"""
|
||||
sce.set_frame(orig_frame)
|
||||
|
||||
class EXPORT_OT_mdd(bpy.types.Operator):
|
||||
from bpy.props import *
|
||||
|
||||
class ExportMDD(bpy.types.Operator):
|
||||
'''Animated mesh to MDD vertex keyframe file.'''
|
||||
__idname__ = "export.mdd"
|
||||
__label__ = "Export MDD"
|
||||
bl_idname = "export.mdd"
|
||||
bl_label = "Export MDD"
|
||||
|
||||
# get first scene to get min and max properties for frames, fps
|
||||
|
||||
@ -148,15 +164,14 @@ class EXPORT_OT_mdd(bpy.types.Operator):
|
||||
|
||||
# List of operator properties, the attributes will be assigned
|
||||
# to the class instance from the operator settings before calling.
|
||||
__props__ = [
|
||||
bpy.props.StringProperty(attr="path", name="File Path", description="File path used for exporting the MDD file", maxlen= 1024, default= "tmp.mdd"),
|
||||
bpy.props.IntProperty(attr="fps", name="Frames Per Second", description="Number of frames/second", min=minfps, max=maxfps, default= 25),
|
||||
bpy.props.IntProperty(attr="start_frame", name="Start Frame", description="Start frame for baking", min=minframe,max=maxframe,default=1),
|
||||
bpy.props.IntProperty(attr="end_frame", name="End Frame", description="End frame for baking", min=minframe, max=maxframe, default= 250),
|
||||
]
|
||||
path = StringProperty(name="File Path", description="File path used for exporting the MDD file", maxlen= 1024, default= "tmp.mdd")
|
||||
fps = IntProperty(name="Frames Per Second", description="Number of frames/second", min=minfps, max=maxfps, default= 25)
|
||||
start_frame = IntProperty(name="Start Frame", description="Start frame for baking", min=minframe,max=maxframe,default=1)
|
||||
end_frame = IntProperty(name="End Frame", description="End frame for baking", min=minframe, max=maxframe, default= 250)
|
||||
|
||||
def poll(self, context):
|
||||
return context.active_object != None
|
||||
ob = context.active_object
|
||||
return (ob and ob.type=='MESH')
|
||||
|
||||
def execute(self, context):
|
||||
if not self.path:
|
||||
@ -167,18 +182,20 @@ class EXPORT_OT_mdd(bpy.types.Operator):
|
||||
|
||||
def invoke(self, context, event):
|
||||
wm = context.manager
|
||||
wm.add_fileselect(self.__operator__)
|
||||
wm.add_fileselect(self)
|
||||
return ('RUNNING_MODAL',)
|
||||
|
||||
bpy.ops.add(EXPORT_OT_mdd)
|
||||
bpy.ops.add(ExportMDD)
|
||||
|
||||
# Add to a menu
|
||||
import dynamic_menu
|
||||
menu_func = lambda self, context: self.layout.itemO("export.mdd", text="Vertex Keyframe Animation (.mdd)...")
|
||||
|
||||
def menu_func(self, context):
|
||||
default_path = bpy.data.filename.replace(".blend", ".mdd")
|
||||
self.layout.item_stringO(ExportMDD.bl_idname, "path", default_path, text="Vertex Keyframe Animation (.mdd)...")
|
||||
|
||||
menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_export, menu_func)
|
||||
|
||||
if __name__=='__main__':
|
||||
#if not pack:
|
||||
# Draw.PupMenu('Error%t|This script requires a full python install')
|
||||
#Blender.Window.FileSelector(mdd_export_ui, 'EXPORT MDD', sys.makename(ext='.mdd'))
|
||||
bpy.ops.EXPORT_OT_mdd(path="/tmp/test.mdd")
|
||||
|
@ -1,4 +1,20 @@
|
||||
#!BPY
|
||||
# ##### 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
"""
|
||||
Name: 'Wavefront (.obj)...'
|
||||
@ -207,11 +223,11 @@ def copy_images(dest_dir):
|
||||
copyCount = 0
|
||||
|
||||
# for bImage in uniqueImages.values():
|
||||
# image_path = bpy.sys.expandpath(bImage.filename)
|
||||
# image_path = bpy.utils.expandpath(bImage.filename)
|
||||
# if bpy.sys.exists(image_path):
|
||||
# # Make a name for the target path.
|
||||
# dest_image_path = dest_dir + image_path.split('\\')[-1].split('/')[-1]
|
||||
# if not bpy.sys.exists(dest_image_path): # Image isnt alredy there
|
||||
# if not bpy.utils.exists(dest_image_path): # Image isnt alredy there
|
||||
# print('\tCopying "%s" > "%s"' % (image_path, dest_image_path))
|
||||
# copy_file(image_path, dest_image_path)
|
||||
# copyCount+=1
|
||||
@ -913,44 +929,46 @@ Currently the exporter lacks these features:
|
||||
* multiple scene export (only active scene is written)
|
||||
* particles
|
||||
'''
|
||||
class EXPORT_OT_obj(bpy.types.Operator):
|
||||
|
||||
from bpy.props import *
|
||||
|
||||
class ExportOBJ(bpy.types.Operator):
|
||||
'''Save a Wavefront OBJ File'''
|
||||
|
||||
__idname__ = "export.obj"
|
||||
__label__ = 'Export OBJ'
|
||||
bl_idname = "export.obj"
|
||||
bl_label = 'Export OBJ'
|
||||
|
||||
# List of operator properties, the attributes will be assigned
|
||||
# to the class instance from the operator settings before calling.
|
||||
|
||||
__props__ = [
|
||||
bpy.props.StringProperty(attr="path", name="File Path", description="File path used for exporting the OBJ file", maxlen= 1024, default= ""),
|
||||
path = StringProperty(name="File Path", description="File path used for exporting the OBJ file", maxlen= 1024, default= "")
|
||||
|
||||
# context group
|
||||
bpy.props.BoolProperty(attr="use_selection", name="Selection Only", description="", default= False),
|
||||
bpy.props.BoolProperty(attr="use_all_scenes", name="All Scenes", description="", default= False),
|
||||
bpy.props.BoolProperty(attr="use_animation", name="All Animation", description="", default= False),
|
||||
use_selection = BoolProperty(name="Selection Only", description="", default= False)
|
||||
use_all_scenes = BoolProperty(name="All Scenes", description="", default= False)
|
||||
use_animation = BoolProperty(name="All Animation", description="", default= False)
|
||||
|
||||
# object group
|
||||
bpy.props.BoolProperty(attr="use_modifiers", name="Apply Modifiers", description="", default= True),
|
||||
bpy.props.BoolProperty(attr="use_rotate90", name="Rotate X90", description="", default= True),
|
||||
use_modifiers = BoolProperty(name="Apply Modifiers", description="", default= True)
|
||||
use_rotate90 = BoolProperty(name="Rotate X90", description="", default= True)
|
||||
|
||||
# extra data group
|
||||
bpy.props.BoolProperty(attr="use_edges", name="Edges", description="", default= True),
|
||||
bpy.props.BoolProperty(attr="use_normals", name="Normals", description="", default= False),
|
||||
bpy.props.BoolProperty(attr="use_hq_normals", name="High Quality Normals", description="", default= True),
|
||||
bpy.props.BoolProperty(attr="use_uvs", name="UVs", description="", default= True),
|
||||
bpy.props.BoolProperty(attr="use_materials", name="Materials", description="", default= True),
|
||||
bpy.props.BoolProperty(attr="copy_images", name="Copy Images", description="", default= False),
|
||||
bpy.props.BoolProperty(attr="use_triangles", name="Triangulate", description="", default= False),
|
||||
bpy.props.BoolProperty(attr="use_vertex_groups", name="Polygroups", description="", default= False),
|
||||
bpy.props.BoolProperty(attr="use_nurbs", name="Nurbs", description="", default= False),
|
||||
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
|
||||
bpy.props.BoolProperty(attr="use_blen_objects", name="Objects as OBJ Objects", description="", default= True),
|
||||
bpy.props.BoolProperty(attr="group_by_object", name="Objects as OBJ Groups ", description="", default= False),
|
||||
bpy.props.BoolProperty(attr="group_by_material", name="Material Groups", description="", default= False),
|
||||
bpy.props.BoolProperty(attr="keep_vertex_order", name="Keep Vertex Order", description="", default= False)
|
||||
]
|
||||
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):
|
||||
|
||||
@ -977,17 +995,21 @@ class EXPORT_OT_obj(bpy.types.Operator):
|
||||
|
||||
def invoke(self, context, event):
|
||||
wm = context.manager
|
||||
wm.add_fileselect(self.__operator__)
|
||||
wm.add_fileselect(self)
|
||||
return ('RUNNING_MODAL',)
|
||||
|
||||
def poll(self, context): # Poll isnt working yet
|
||||
print("Poll")
|
||||
return context.active_object != None
|
||||
|
||||
bpy.ops.add(EXPORT_OT_obj)
|
||||
bpy.ops.add(ExportOBJ)
|
||||
|
||||
import dynamic_menu
|
||||
menu_func = lambda self, context: self.layout.itemO("export.obj", text="Wavefront (.obj)...")
|
||||
|
||||
def menu_func(self, context):
|
||||
default_path = bpy.data.filename.replace(".blend", ".obj")
|
||||
self.layout.item_stringO(ExportOBJ.bl_idname, "path", default_path, text="Wavefront (.obj)...")
|
||||
|
||||
menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_export, menu_func)
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
@ -1,3 +1,21 @@
|
||||
# ##### 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
import bpy
|
||||
|
||||
__author__ = "Bruce Merry"
|
||||
@ -231,21 +249,24 @@ def write(filename, scene, ob, \
|
||||
Blender.Window.EditMode(1, '', 0)
|
||||
"""
|
||||
|
||||
class EXPORT_OT_ply(bpy.types.Operator):
|
||||
from bpy.props import *
|
||||
|
||||
|
||||
class ExportPLY(bpy.types.Operator):
|
||||
'''Export a single object as a stanford PLY with normals, colours and texture coordinates.'''
|
||||
__idname__ = "export.ply"
|
||||
__label__ = "Export PLY"
|
||||
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.
|
||||
|
||||
__props__ = [
|
||||
bpy.props.StringProperty(attr="path", name="File Path", description="File path used for exporting the PLY file", maxlen= 1024, default= ""),
|
||||
bpy.props.BoolProperty(attr="use_modifiers", name="Apply Modifiers", description="Apply Modifiers to the exported mesh", default= True),
|
||||
bpy.props.BoolProperty(attr="use_normals", name="Export Normals", description="Export Normals for smooth and hard shaded faces", default= True),
|
||||
bpy.props.BoolProperty(attr="use_uvs", name="Export UVs", description="Exort the active UV layer", default= True),
|
||||
bpy.props.BoolProperty(attr="use_colors", name="Export Vertex Colors", description="Exort the active vertex color layer", default= True)
|
||||
]
|
||||
|
||||
path = StringProperty(name="File Path", description="File path used for exporting the PLY file", maxlen= 1024, default= "")
|
||||
use_modifiers = BoolProperty(name="Apply Modifiers", description="Apply Modifiers to the exported mesh", default= True)
|
||||
use_normals = BoolProperty(name="Export Normals", description="Export Normals for smooth and hard shaded faces", default= True)
|
||||
use_uvs = BoolProperty(name="Export UVs", description="Exort the active UV layer", default= True)
|
||||
use_colors = BoolProperty(name="Export Vertex Colors", description="Exort the active vertex color layer", default= True)
|
||||
|
||||
|
||||
def poll(self, context):
|
||||
return context.active_object != None
|
||||
@ -267,15 +288,19 @@ class EXPORT_OT_ply(bpy.types.Operator):
|
||||
|
||||
def invoke(self, context, event):
|
||||
wm = context.manager
|
||||
wm.add_fileselect(self.__operator__)
|
||||
wm.add_fileselect(self)
|
||||
return ('RUNNING_MODAL',)
|
||||
|
||||
|
||||
bpy.ops.add(EXPORT_OT_ply)
|
||||
bpy.ops.add(ExportPLY)
|
||||
|
||||
import dynamic_menu
|
||||
menu_func = lambda self, context: self.layout.itemO("export.ply", text="Stanford (.ply)...")
|
||||
|
||||
def menu_func(self, context):
|
||||
default_path = bpy.data.filename.replace(".blend", ".ply")
|
||||
self.layout.item_stringO(ExportPLY.bl_idname, "path", default_path, text="Stanford (.ply)...")
|
||||
|
||||
menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_export, menu_func)
|
||||
|
||||
if __name__ == "__main__":
|
||||
bpy.ops.EXPORT_OT_ply(path="/tmp/test.ply")
|
||||
bpy.ops.export.ply(path="/tmp/test.ply")
|
||||
|
@ -1,3 +1,20 @@
|
||||
# ##### 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
__author__ = ("Bart", "Campbell Barton")
|
||||
__email__ = ["Bart, bart:neeneenee*de"]
|
||||
@ -1196,21 +1213,21 @@ def x3d_export_ui(filename):
|
||||
# if __name__ == '__main__':
|
||||
# Blender.Window.FileSelector(x3d_export_ui,"Export X3D", Blender.Get('filename').replace('.blend', '.x3d'))
|
||||
|
||||
class EXPORT_OT_x3d(bpy.types.Operator):
|
||||
from bpy.props import *
|
||||
|
||||
class ExportX3D(bpy.types.Operator):
|
||||
'''Export selection to Extensible 3D file (.x3d)'''
|
||||
__idname__ = "export.x3d"
|
||||
__label__ = 'Export 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.
|
||||
path = StringProperty(name="File Path", description="File path used for exporting the X3D file", maxlen= 1024, default= "")
|
||||
|
||||
__props__ = [
|
||||
bpy.props.StringProperty(attr="path", name="File Path", description="File path used for exporting the X3D file", maxlen= 1024, default= ""),
|
||||
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)
|
||||
|
||||
bpy.props.BoolProperty(attr="apply_modifiers", name="Apply Modifiers", description="Use transformed mesh data from each object.", default=True),
|
||||
bpy.props.BoolProperty(attr="triangulate", name="Triangulate", description="Triangulate quads.", default=False),
|
||||
bpy.props.BoolProperty(attr="compress", name="Compress", description="GZip the resulting file, requires a full python install.", default=False),
|
||||
]
|
||||
|
||||
def execute(self, context):
|
||||
x3d_export(self.path, context, self.apply_modifiers, self.triangulate, self.compress)
|
||||
@ -1218,13 +1235,17 @@ class EXPORT_OT_x3d(bpy.types.Operator):
|
||||
|
||||
def invoke(self, context, event):
|
||||
wm = context.manager
|
||||
wm.add_fileselect(self.__operator__)
|
||||
wm.add_fileselect(self)
|
||||
return ('RUNNING_MODAL',)
|
||||
|
||||
bpy.ops.add(EXPORT_OT_x3d)
|
||||
bpy.ops.add(ExportX3D)
|
||||
|
||||
import dynamic_menu
|
||||
menu_func = lambda self, context: self.layout.itemO("export.x3d", text="X3D Extensible 3D (.x3d)...")
|
||||
|
||||
def menu_func(self, context):
|
||||
default_path = bpy.data.filename.replace(".blend", ".x3d")
|
||||
self.layout.item_stringO(ExportX3D.bl_idname, "path", default_path, text="X3D Extensible 3D (.x3d)...")
|
||||
|
||||
menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_export, menu_func)
|
||||
|
||||
# NOTES
|
||||
|
881
release/scripts/io/import_anim_bvh.py
Normal file
881
release/scripts/io/import_anim_bvh.py
Normal file
@ -0,0 +1,881 @@
|
||||
import math
|
||||
|
||||
# import Blender
|
||||
import bpy
|
||||
# import BPyMessages
|
||||
import Mathutils
|
||||
Vector= Mathutils.Vector
|
||||
Euler= Mathutils.Euler
|
||||
Matrix= Mathutils.Matrix
|
||||
RotationMatrix= Mathutils.RotationMatrix
|
||||
TranslationMatrix= Mathutils.TranslationMatrix
|
||||
|
||||
# NASTY GLOBAL
|
||||
ROT_STYLE = 'QUAT'
|
||||
|
||||
DEG2RAD = 0.017453292519943295
|
||||
|
||||
class bvh_node_class(object):
|
||||
__slots__=(\
|
||||
'name',# bvh joint name
|
||||
'parent',# bvh_node_class type or None for no parent
|
||||
'children',# a list of children of this type.
|
||||
'rest_head_world',# worldspace rest location for the head of this node
|
||||
'rest_head_local',# localspace rest location for the head of this node
|
||||
'rest_tail_world',# # worldspace rest location for the tail of this node
|
||||
'rest_tail_local',# # worldspace rest location for the tail of this node
|
||||
'channels',# list of 6 ints, -1 for an unused channel, otherwise an index for the BVH motion data lines, lock triple then rot triple
|
||||
'rot_order',# a triple of indicies as to the order rotation is applied. [0,1,2] is x/y/z - [None, None, None] if no rotation.
|
||||
'anim_data',# a list one tuple's one for each frame. (locx, locy, locz, rotx, roty, rotz)
|
||||
'has_loc',# Conveinience function, bool, same as (channels[0]!=-1 or channels[1]!=-1 channels[2]!=-1)
|
||||
'has_rot',# Conveinience function, bool, same as (channels[3]!=-1 or channels[4]!=-1 channels[5]!=-1)
|
||||
'temp')# use this for whatever you want
|
||||
|
||||
def __init__(self, name, rest_head_world, rest_head_local, parent, channels, rot_order):
|
||||
self.name= name
|
||||
self.rest_head_world= rest_head_world
|
||||
self.rest_head_local= rest_head_local
|
||||
self.rest_tail_world= None
|
||||
self.rest_tail_local= None
|
||||
self.parent= parent
|
||||
self.channels= channels
|
||||
self.rot_order= rot_order
|
||||
|
||||
# convenience functions
|
||||
self.has_loc= channels[0] != -1 or channels[1] != -1 or channels[2] != -1
|
||||
self.has_rot= channels[3] != -1 or channels[4] != -1 or channels[5] != -1
|
||||
|
||||
|
||||
self.children= []
|
||||
|
||||
# list of 6 length tuples: (lx,ly,lz, rx,ry,rz)
|
||||
# even if the channels arnt used they will just be zero
|
||||
#
|
||||
self.anim_data= [(0,0,0,0,0,0)]
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
return 'BVH name:"%s", rest_loc:(%.3f,%.3f,%.3f), rest_tail:(%.3f,%.3f,%.3f)' %\
|
||||
(self.name,\
|
||||
self.rest_head_world.x, self.rest_head_world.y, self.rest_head_world.z,\
|
||||
self.rest_head_world.x, self.rest_head_world.y, self.rest_head_world.z)
|
||||
|
||||
|
||||
|
||||
# Change the order rotation is applied.
|
||||
MATRIX_IDENTITY_3x3 = Matrix([1,0,0],[0,1,0],[0,0,1])
|
||||
MATRIX_IDENTITY_4x4 = Matrix([1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1])
|
||||
|
||||
def eulerRotate(x,y,z, rot_order):
|
||||
|
||||
# Clamp all values between 0 and 360, values outside this raise an error.
|
||||
mats=[RotationMatrix(math.radians(x%360),3,'x'), RotationMatrix(math.radians(y%360),3,'y'), RotationMatrix(math.radians(z%360),3,'z')]
|
||||
# print rot_order
|
||||
# Standard BVH multiplication order, apply the rotation in the order Z,X,Y
|
||||
|
||||
#XXX, order changes???
|
||||
#eul = (mats[rot_order[2]]*(mats[rot_order[1]]* (mats[rot_order[0]]* MATRIX_IDENTITY_3x3))).toEuler()
|
||||
eul = (MATRIX_IDENTITY_3x3*mats[rot_order[0]]*(mats[rot_order[1]]* (mats[rot_order[2]]))).toEuler()
|
||||
|
||||
eul = math.degrees(eul.x), math.degrees(eul.y), math.degrees(eul.z)
|
||||
|
||||
return eul
|
||||
|
||||
def read_bvh(context, file_path, GLOBAL_SCALE=1.0):
|
||||
# File loading stuff
|
||||
# Open the file for importing
|
||||
file = open(file_path, 'rU')
|
||||
|
||||
# Seperate into a list of lists, each line a list of words.
|
||||
file_lines = file.readlines()
|
||||
# Non standard carrage returns?
|
||||
if len(file_lines) == 1:
|
||||
file_lines = file_lines[0].split('\r')
|
||||
|
||||
# Split by whitespace.
|
||||
file_lines =[ll for ll in [ l.split() for l in file_lines] if ll]
|
||||
|
||||
|
||||
# Create Hirachy as empties
|
||||
|
||||
if file_lines[0][0].lower() == 'hierarchy':
|
||||
#print 'Importing the BVH Hierarchy for:', file_path
|
||||
pass
|
||||
else:
|
||||
raise 'ERROR: This is not a BVH file'
|
||||
|
||||
bvh_nodes= {None:None}
|
||||
bvh_nodes_serial = [None]
|
||||
|
||||
channelIndex = -1
|
||||
|
||||
|
||||
lineIdx = 0 # An index for the file.
|
||||
while lineIdx < len(file_lines) -1:
|
||||
#...
|
||||
if file_lines[lineIdx][0].lower() == 'root' or file_lines[lineIdx][0].lower() == 'joint':
|
||||
|
||||
# Join spaces into 1 word with underscores joining it.
|
||||
if len(file_lines[lineIdx]) > 2:
|
||||
file_lines[lineIdx][1] = '_'.join(file_lines[lineIdx][1:])
|
||||
file_lines[lineIdx] = file_lines[lineIdx][:2]
|
||||
|
||||
# MAY NEED TO SUPPORT MULTIPLE ROOT's HERE!!!, Still unsure weather multiple roots are possible.??
|
||||
|
||||
# Make sure the names are unique- Object names will match joint names exactly and both will be unique.
|
||||
name = file_lines[lineIdx][1]
|
||||
|
||||
#print '%snode: %s, parent: %s' % (len(bvh_nodes_serial) * ' ', name, bvh_nodes_serial[-1])
|
||||
|
||||
lineIdx += 2 # Incriment to the next line (Offset)
|
||||
rest_head_local = Vector( GLOBAL_SCALE*float(file_lines[lineIdx][1]), GLOBAL_SCALE*float(file_lines[lineIdx][2]), GLOBAL_SCALE*float(file_lines[lineIdx][3]) )
|
||||
lineIdx += 1 # Incriment to the next line (Channels)
|
||||
|
||||
# newChannel[Xposition, Yposition, Zposition, Xrotation, Yrotation, Zrotation]
|
||||
# newChannel references indecies to the motiondata,
|
||||
# if not assigned then -1 refers to the last value that will be added on loading at a value of zero, this is appended
|
||||
# We'll add a zero value onto the end of the MotionDATA so this is always refers to a value.
|
||||
my_channel = [-1, -1, -1, -1, -1, -1]
|
||||
my_rot_order= [None, None, None]
|
||||
rot_count= 0
|
||||
for channel in file_lines[lineIdx][2:]:
|
||||
channel= channel.lower()
|
||||
channelIndex += 1 # So the index points to the right channel
|
||||
if channel == 'xposition': my_channel[0] = channelIndex
|
||||
elif channel == 'yposition': my_channel[1] = channelIndex
|
||||
elif channel == 'zposition': my_channel[2] = channelIndex
|
||||
|
||||
elif channel == 'xrotation':
|
||||
my_channel[3] = channelIndex
|
||||
my_rot_order[rot_count]= 0
|
||||
rot_count+=1
|
||||
elif channel == 'yrotation':
|
||||
my_channel[4] = channelIndex
|
||||
my_rot_order[rot_count]= 1
|
||||
rot_count+=1
|
||||
elif channel == 'zrotation':
|
||||
my_channel[5] = channelIndex
|
||||
my_rot_order[rot_count]= 2
|
||||
rot_count+=1
|
||||
|
||||
channels = file_lines[lineIdx][2:]
|
||||
|
||||
my_parent= bvh_nodes_serial[-1] # account for none
|
||||
|
||||
|
||||
# Apply the parents offset accumletivly
|
||||
if my_parent==None:
|
||||
rest_head_world= Vector(rest_head_local)
|
||||
else:
|
||||
rest_head_world= my_parent.rest_head_world + rest_head_local
|
||||
|
||||
bvh_node= bvh_nodes[name]= bvh_node_class(name, rest_head_world, rest_head_local, my_parent, my_channel, my_rot_order)
|
||||
|
||||
# If we have another child then we can call ourselves a parent, else
|
||||
bvh_nodes_serial.append(bvh_node)
|
||||
|
||||
# Account for an end node
|
||||
if file_lines[lineIdx][0].lower() == 'end' and file_lines[lineIdx][1].lower() == 'site': # There is somtimes a name after 'End Site' but we will ignore it.
|
||||
lineIdx += 2 # Incriment to the next line (Offset)
|
||||
rest_tail = Vector( GLOBAL_SCALE*float(file_lines[lineIdx][1]), GLOBAL_SCALE*float(file_lines[lineIdx][2]), GLOBAL_SCALE*float(file_lines[lineIdx][3]) )
|
||||
|
||||
bvh_nodes_serial[-1].rest_tail_world= bvh_nodes_serial[-1].rest_head_world + rest_tail
|
||||
bvh_nodes_serial[-1].rest_tail_local= rest_tail
|
||||
|
||||
|
||||
# Just so we can remove the Parents in a uniform way- End end never has kids
|
||||
# so this is a placeholder
|
||||
bvh_nodes_serial.append(None)
|
||||
|
||||
if len(file_lines[lineIdx]) == 1 and file_lines[lineIdx][0] == '}': # == ['}']
|
||||
bvh_nodes_serial.pop() # Remove the last item
|
||||
|
||||
if len(file_lines[lineIdx]) == 1 and file_lines[lineIdx][0].lower() == 'motion':
|
||||
#print '\nImporting motion data'
|
||||
lineIdx += 3 # Set the cursor to the first frame
|
||||
break
|
||||
|
||||
lineIdx += 1
|
||||
|
||||
|
||||
# Remove the None value used for easy parent reference
|
||||
del bvh_nodes[None]
|
||||
# Dont use anymore
|
||||
del bvh_nodes_serial
|
||||
|
||||
bvh_nodes_list= bvh_nodes.values()
|
||||
|
||||
while lineIdx < len(file_lines):
|
||||
line= file_lines[lineIdx]
|
||||
for bvh_node in bvh_nodes_list:
|
||||
#for bvh_node in bvh_nodes_serial:
|
||||
lx= ly= lz= rx= ry= rz= 0.0
|
||||
channels= bvh_node.channels
|
||||
anim_data= bvh_node.anim_data
|
||||
if channels[0] != -1:
|
||||
lx= GLOBAL_SCALE * float( line[channels[0]] )
|
||||
|
||||
if channels[1] != -1:
|
||||
ly= GLOBAL_SCALE * float( line[channels[1]] )
|
||||
|
||||
if channels[2] != -1:
|
||||
lz= GLOBAL_SCALE * float( line[channels[2]] )
|
||||
|
||||
if channels[3] != -1 or channels[4] != -1 or channels[5] != -1:
|
||||
rx, ry, rz = float( line[channels[3]] ), float( line[channels[4]] ), float( line[channels[5]] )
|
||||
|
||||
if ROT_STYLE != 'NATIVE':
|
||||
rx, ry, rz = eulerRotate(rx, ry, rz, bvh_node.rot_order)
|
||||
|
||||
#x,y,z = x/10.0, y/10.0, z/10.0 # For IPO's 36 is 360d
|
||||
|
||||
# Make interpolation not cross between 180d, thjis fixes sub frame interpolation and time scaling.
|
||||
# Will go from (355d to 365d) rather then to (355d to 5d) - inbetween these 2 there will now be a correct interpolation.
|
||||
|
||||
while anim_data[-1][3] - rx > 180: rx+=360
|
||||
while anim_data[-1][3] - rx < -180: rx-=360
|
||||
|
||||
while anim_data[-1][4] - ry > 180: ry+=360
|
||||
while anim_data[-1][4] - ry < -180: ry-=360
|
||||
|
||||
while anim_data[-1][5] - rz > 180: rz+=360
|
||||
while anim_data[-1][5] - rz < -180: rz-=360
|
||||
|
||||
# Done importing motion data #
|
||||
anim_data.append( (lx, ly, lz, rx, ry, rz) )
|
||||
lineIdx += 1
|
||||
|
||||
# Assign children
|
||||
for bvh_node in bvh_nodes.values():
|
||||
bvh_node_parent= bvh_node.parent
|
||||
if bvh_node_parent:
|
||||
bvh_node_parent.children.append(bvh_node)
|
||||
|
||||
# Now set the tip of each bvh_node
|
||||
for bvh_node in bvh_nodes.values():
|
||||
|
||||
if not bvh_node.rest_tail_world:
|
||||
if len(bvh_node.children)==0:
|
||||
# could just fail here, but rare BVH files have childless nodes
|
||||
bvh_node.rest_tail_world = Vector(bvh_node.rest_head_world)
|
||||
bvh_node.rest_tail_local = Vector(bvh_node.rest_head_local)
|
||||
elif len(bvh_node.children)==1:
|
||||
bvh_node.rest_tail_world= Vector(bvh_node.children[0].rest_head_world)
|
||||
bvh_node.rest_tail_local= Vector(bvh_node.children[0].rest_head_local)
|
||||
else:
|
||||
# allow this, see above
|
||||
#if not bvh_node.children:
|
||||
# raise 'error, bvh node has no end and no children. bad file'
|
||||
|
||||
# Removed temp for now
|
||||
rest_tail_world= Vector(0,0,0)
|
||||
rest_tail_local= Vector(0,0,0)
|
||||
for bvh_node_child in bvh_node.children:
|
||||
rest_tail_world += bvh_node_child.rest_head_world
|
||||
rest_tail_local += bvh_node_child.rest_head_local
|
||||
|
||||
bvh_node.rest_tail_world= rest_tail_world * (1.0/len(bvh_node.children))
|
||||
bvh_node.rest_tail_local= rest_tail_local * (1.0/len(bvh_node.children))
|
||||
|
||||
# Make sure tail isnt the same location as the head.
|
||||
if (bvh_node.rest_tail_local-bvh_node.rest_head_local).length <= 0.001*GLOBAL_SCALE:
|
||||
|
||||
bvh_node.rest_tail_local.y= bvh_node.rest_tail_local.y + GLOBAL_SCALE/10
|
||||
bvh_node.rest_tail_world.y= bvh_node.rest_tail_world.y + GLOBAL_SCALE/10
|
||||
|
||||
|
||||
|
||||
return bvh_nodes
|
||||
|
||||
|
||||
|
||||
def bvh_node_dict2objects(context, bvh_nodes, IMPORT_START_FRAME= 1, IMPORT_LOOP= False):
|
||||
|
||||
if IMPORT_START_FRAME<1:
|
||||
IMPORT_START_FRAME= 1
|
||||
|
||||
scn= context.scene
|
||||
scn.objects.selected = []
|
||||
|
||||
objects= []
|
||||
|
||||
def add_ob(name):
|
||||
ob = scn.objects.new('Empty')
|
||||
objects.append(ob)
|
||||
return ob
|
||||
|
||||
# Add objects
|
||||
for name, bvh_node in bvh_nodes.items():
|
||||
bvh_node.temp= add_ob(name)
|
||||
|
||||
# Parent the objects
|
||||
for bvh_node in bvh_nodes.values():
|
||||
bvh_node.temp.makeParent([ bvh_node_child.temp for bvh_node_child in bvh_node.children ], 1, 0) # ojbs, noninverse, 1 = not fast.
|
||||
|
||||
# Offset
|
||||
for bvh_node in bvh_nodes.values():
|
||||
# Make relative to parents offset
|
||||
bvh_node.temp.loc= bvh_node.rest_head_local
|
||||
|
||||
# Add tail objects
|
||||
for name, bvh_node in bvh_nodes.items():
|
||||
if not bvh_node.children:
|
||||
ob_end= add_ob(name + '_end')
|
||||
bvh_node.temp.makeParent([ob_end], 1, 0) # ojbs, noninverse, 1 = not fast.
|
||||
ob_end.loc= bvh_node.rest_tail_local
|
||||
|
||||
|
||||
# Animate the data, the last used bvh_node will do since they all have the same number of frames
|
||||
for current_frame in range(len(bvh_node.anim_data)):
|
||||
Blender.Set('curframe', current_frame+IMPORT_START_FRAME)
|
||||
|
||||
for bvh_node in bvh_nodes.values():
|
||||
lx,ly,lz,rx,ry,rz= bvh_node.anim_data[current_frame]
|
||||
|
||||
rest_head_local= bvh_node.rest_head_local
|
||||
bvh_node.temp.loc= rest_head_local.x+lx, rest_head_local.y+ly, rest_head_local.z+lz
|
||||
|
||||
bvh_node.temp.rot= rx*DEG2RAD,ry*DEG2RAD,rz*DEG2RAD
|
||||
|
||||
bvh_node.temp.insertIpoKey(Blender.Object.IpoKeyTypes.LOCROT)
|
||||
|
||||
scn.update(1)
|
||||
return objects
|
||||
|
||||
|
||||
|
||||
def bvh_node_dict2armature(context, bvh_nodes, IMPORT_START_FRAME= 1, IMPORT_LOOP= False):
|
||||
|
||||
if IMPORT_START_FRAME<1:
|
||||
IMPORT_START_FRAME= 1
|
||||
|
||||
|
||||
# Add the new armature,
|
||||
scn = context.scene
|
||||
#XXX scn.objects.selected = []
|
||||
for ob in scn.objects:
|
||||
ob.selected = False
|
||||
|
||||
|
||||
#XXX arm_data= bpy.data.armatures.new()
|
||||
#XXX arm_ob = scn.objects.new(arm_data)
|
||||
bpy.ops.object.armature_add()
|
||||
arm_ob= scn.objects[-1]
|
||||
arm_data= arm_ob.data
|
||||
|
||||
|
||||
|
||||
|
||||
#XXX scn.objects.context = [arm_ob]
|
||||
#XXX scn.objects.active = arm_ob
|
||||
arm_ob.selected= True
|
||||
scn.objects.active= arm_ob
|
||||
print(scn.objects.active)
|
||||
|
||||
|
||||
# Put us into editmode
|
||||
#XXX arm_data.makeEditable()
|
||||
|
||||
bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
|
||||
bpy.ops.object.mode_set(mode='EDIT', toggle=False)
|
||||
|
||||
|
||||
|
||||
# Get the average bone length for zero length bones, we may not use this.
|
||||
average_bone_length= 0.0
|
||||
nonzero_count= 0
|
||||
for bvh_node in bvh_nodes.values():
|
||||
l= (bvh_node.rest_head_local-bvh_node.rest_tail_local).length
|
||||
if l:
|
||||
average_bone_length+= l
|
||||
nonzero_count+=1
|
||||
|
||||
# Very rare cases all bones couldbe zero length???
|
||||
if not average_bone_length:
|
||||
average_bone_length = 0.1
|
||||
else:
|
||||
# Normal operation
|
||||
average_bone_length = average_bone_length/nonzero_count
|
||||
|
||||
|
||||
#XXX - sloppy operator code
|
||||
|
||||
bpy.ops.armature.delete()
|
||||
bpy.ops.armature.select_all_toggle()
|
||||
bpy.ops.armature.delete()
|
||||
|
||||
ZERO_AREA_BONES= []
|
||||
for name, bvh_node in bvh_nodes.items():
|
||||
# New editbone
|
||||
bpy.ops.armature.bone_primitive_add(name="Bone")
|
||||
|
||||
#XXX bone= bvh_node.temp= Blender.Armature.Editbone()
|
||||
bone= bvh_node.temp= arm_data.edit_bones[-1]
|
||||
|
||||
bone.name= name
|
||||
# arm_data.bones[name]= bone
|
||||
|
||||
bone.head= bvh_node.rest_head_world
|
||||
bone.tail= bvh_node.rest_tail_world
|
||||
|
||||
# ZERO AREA BONES.
|
||||
if (bone.head-bone.tail).length < 0.001:
|
||||
if bvh_node.parent:
|
||||
ofs= bvh_node.parent.rest_head_local- bvh_node.parent.rest_tail_local
|
||||
if ofs.length: # is our parent zero length also?? unlikely
|
||||
bone.tail= bone.tail+ofs
|
||||
else:
|
||||
bone.tail.y= bone.tail.y+average_bone_length
|
||||
else:
|
||||
bone.tail.y= bone.tail.y+average_bone_length
|
||||
|
||||
ZERO_AREA_BONES.append(bone.name)
|
||||
|
||||
|
||||
for bvh_node in bvh_nodes.values():
|
||||
if bvh_node.parent:
|
||||
# bvh_node.temp is the Editbone
|
||||
|
||||
# Set the bone parent
|
||||
bvh_node.temp.parent= bvh_node.parent.temp
|
||||
|
||||
# Set the connection state
|
||||
if not bvh_node.has_loc and\
|
||||
bvh_node.parent and\
|
||||
bvh_node.parent.temp.name not in ZERO_AREA_BONES and\
|
||||
bvh_node.parent.rest_tail_local == bvh_node.rest_head_local:
|
||||
bvh_node.temp.connected= True
|
||||
|
||||
# Replace the editbone with the editbone name,
|
||||
# to avoid memory errors accessing the editbone outside editmode
|
||||
for bvh_node in bvh_nodes.values():
|
||||
bvh_node.temp= bvh_node.temp.name
|
||||
|
||||
#XXX arm_data.update()
|
||||
|
||||
# Now Apply the animation to the armature
|
||||
|
||||
# Get armature animation data
|
||||
bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
|
||||
bpy.ops.object.mode_set(mode='POSE', toggle=False)
|
||||
|
||||
pose= arm_ob.pose
|
||||
pose_bones= pose.pose_channels
|
||||
|
||||
|
||||
if ROT_STYLE=='NATIVE':
|
||||
eul_order_lookup = {\
|
||||
(0,1,2):'XYZ',
|
||||
(0,2,1):'XZY',
|
||||
(1,0,2):'YXZ',
|
||||
(1,2,0):'YZX',
|
||||
(2,0,1):'ZXY',
|
||||
(2,1,0):'ZYZ'
|
||||
}
|
||||
|
||||
for bvh_node in bvh_nodes.values():
|
||||
bone_name= bvh_node.temp # may not be the same name as the bvh_node, could have been shortened.
|
||||
pose_bone= pose_bones[bone_name]
|
||||
pose_bone.rotation_mode = eul_order_lookup[tuple(bvh_node.rot_order)]
|
||||
|
||||
elif ROT_STYLE=='XYZ':
|
||||
for pose_bone in pose_bones:
|
||||
pose_bone.rotation_mode = 'XYZ'
|
||||
else:
|
||||
# Quats default
|
||||
pass
|
||||
|
||||
|
||||
bpy.ops.pose.select_all_toggle() # set
|
||||
bpy.ops.anim.insert_keyframe_menu(type=-4) # XXX - -4 ???
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#for p in pose_bones:
|
||||
# print(p)
|
||||
|
||||
|
||||
#XXX action = Blender.Armature.NLA.NewAction("Action")
|
||||
#XXX action.setActive(arm_ob)
|
||||
|
||||
#bpy.ops.act.new()
|
||||
#action = bpy.data.actions[-1]
|
||||
|
||||
# arm_ob.animation_data.action = action
|
||||
action = arm_ob.animation_data.action
|
||||
|
||||
|
||||
|
||||
|
||||
#xformConstants= [ Blender.Object.Pose.LOC, Blender.Object.Pose.ROT ]
|
||||
|
||||
# Replace the bvh_node.temp (currently an editbone)
|
||||
# With a tuple (pose_bone, armature_bone, bone_rest_matrix, bone_rest_matrix_inv)
|
||||
for bvh_node in bvh_nodes.values():
|
||||
bone_name= bvh_node.temp # may not be the same name as the bvh_node, could have been shortened.
|
||||
pose_bone= pose_bones[bone_name]
|
||||
rest_bone= arm_data.bones[bone_name]
|
||||
#XXX bone_rest_matrix = rest_bone.matrix['ARMATURESPACE'].rotationPart()
|
||||
bone_rest_matrix = rest_bone.matrix.rotationPart()
|
||||
|
||||
|
||||
bone_rest_matrix_inv= Matrix(bone_rest_matrix)
|
||||
bone_rest_matrix_inv.invert()
|
||||
|
||||
bone_rest_matrix_inv.resize4x4()
|
||||
bone_rest_matrix.resize4x4()
|
||||
bvh_node.temp= (pose_bone, bone, bone_rest_matrix, bone_rest_matrix_inv)
|
||||
|
||||
|
||||
# Make a dict for fast access without rebuilding a list all the time.
|
||||
'''
|
||||
xformConstants_dict={
|
||||
(True,True): [Blender.Object.Pose.LOC, Blender.Object.Pose.ROT],\
|
||||
(False,True): [Blender.Object.Pose.ROT],\
|
||||
(True,False): [Blender.Object.Pose.LOC],\
|
||||
(False,False): [],\
|
||||
}
|
||||
'''
|
||||
|
||||
# KEYFRAME METHOD, SLOW, USE IPOS DIRECT
|
||||
|
||||
# Animate the data, the last used bvh_node will do since they all have the same number of frames
|
||||
for current_frame in range(len(bvh_node.anim_data)-1): # skip the first frame (rest frame)
|
||||
# print current_frame
|
||||
|
||||
#if current_frame==150: # debugging
|
||||
# break
|
||||
|
||||
# Dont neet to set the current frame
|
||||
for bvh_node in bvh_nodes.values():
|
||||
pose_bone, bone, bone_rest_matrix, bone_rest_matrix_inv= bvh_node.temp
|
||||
lx,ly,lz,rx,ry,rz= bvh_node.anim_data[current_frame+1]
|
||||
|
||||
if bvh_node.has_rot:
|
||||
|
||||
if ROT_STYLE=='QUAT':
|
||||
# Set the rotation, not so simple
|
||||
bone_rotation_matrix= Euler(math.radians(rx), math.radians(ry), math.radians(rz)).toMatrix()
|
||||
|
||||
bone_rotation_matrix.resize4x4()
|
||||
#XXX ORDER CHANGE???
|
||||
#pose_bone.rotation_quaternion= (bone_rest_matrix * bone_rotation_matrix * bone_rest_matrix_inv).toQuat() # ORIGINAL
|
||||
# pose_bone.rotation_quaternion= (bone_rest_matrix_inv * bone_rotation_matrix * bone_rest_matrix).toQuat()
|
||||
# pose_bone.rotation_quaternion= (bone_rotation_matrix * bone_rest_matrix).toQuat() # BAD
|
||||
# pose_bone.rotation_quaternion= bone_rotation_matrix.toQuat() # NOT GOOD
|
||||
# pose_bone.rotation_quaternion= bone_rotation_matrix.toQuat() # NOT GOOD
|
||||
|
||||
#pose_bone.rotation_quaternion= (bone_rotation_matrix * bone_rest_matrix_inv * bone_rest_matrix).toQuat()
|
||||
#pose_bone.rotation_quaternion= (bone_rest_matrix_inv * bone_rest_matrix * bone_rotation_matrix).toQuat()
|
||||
#pose_bone.rotation_quaternion= (bone_rest_matrix * bone_rotation_matrix * bone_rest_matrix_inv).toQuat()
|
||||
|
||||
#pose_bone.rotation_quaternion= ( bone_rest_matrix* bone_rest_matrix_inv * bone_rotation_matrix).toQuat()
|
||||
#pose_bone.rotation_quaternion= (bone_rotation_matrix * bone_rest_matrix * bone_rest_matrix_inv).toQuat()
|
||||
#pose_bone.rotation_quaternion= (bone_rest_matrix_inv * bone_rotation_matrix * bone_rest_matrix ).toQuat()
|
||||
|
||||
pose_bone.rotation_quaternion= (bone_rest_matrix_inv * bone_rotation_matrix * bone_rest_matrix).toQuat()
|
||||
|
||||
else:
|
||||
bone_rotation_matrix= Euler(math.radians(rx), math.radians(ry), math.radians(rz)).toMatrix()
|
||||
bone_rotation_matrix.resize4x4()
|
||||
|
||||
eul= (bone_rest_matrix * bone_rotation_matrix * bone_rest_matrix_inv).toEuler()
|
||||
|
||||
#pose_bone.rotation_euler = math.radians(rx), math.radians(ry), math.radians(rz)
|
||||
pose_bone.rotation_euler = eul
|
||||
|
||||
print("ROTATION" + str(Euler(math.radians(rx), math.radians(ry), math.radians(rz))))
|
||||
|
||||
if bvh_node.has_loc:
|
||||
# Set the Location, simple too
|
||||
|
||||
#XXX ORDER CHANGE
|
||||
# pose_bone.location= (TranslationMatrix(Vector(lx, ly, lz) - bvh_node.rest_head_local ) * bone_rest_matrix_inv).translationPart() # WHY * 10? - just how pose works
|
||||
# pose_bone.location= (bone_rest_matrix_inv * TranslationMatrix(Vector(lx, ly, lz) - bvh_node.rest_head_local )).translationPart()
|
||||
# pose_bone.location= lx, ly, lz
|
||||
pose_bone.location= Vector(lx, ly, lz) - bvh_node.rest_head_local
|
||||
|
||||
|
||||
#XXX # TODO- add in 2.5
|
||||
if 0:
|
||||
# Get the transform
|
||||
xformConstants= xformConstants_dict[bvh_node.has_loc, bvh_node.has_rot]
|
||||
|
||||
if xformConstants:
|
||||
# Insert the keyframe from the loc/quat
|
||||
pose_bone.insertKey(arm_ob, current_frame+IMPORT_START_FRAME, xformConstants, True )
|
||||
else:
|
||||
|
||||
if bvh_node.has_loc:
|
||||
pose_bone.keyframe_insert("location")
|
||||
if bvh_node.has_rot:
|
||||
if ROT_STYLE=='QUAT':
|
||||
pose_bone.keyframe_insert("rotation_quaternion")
|
||||
else:
|
||||
pose_bone.keyframe_insert("rotation_euler")
|
||||
|
||||
|
||||
|
||||
# bpy.ops.anim.insert_keyframe_menu(type=-4) # XXX - -4 ???
|
||||
bpy.ops.screen.frame_offset(delta=1)
|
||||
|
||||
# First time, set the IPO's to linear
|
||||
#XXX #TODO
|
||||
if 0:
|
||||
if current_frame==0:
|
||||
for ipo in action.getAllChannelIpos().values():
|
||||
if ipo:
|
||||
for cur in ipo:
|
||||
cur.interpolation = Blender.IpoCurve.InterpTypes.LINEAR
|
||||
if IMPORT_LOOP:
|
||||
cur.extend = Blender.IpoCurve.ExtendTypes.CYCLIC
|
||||
|
||||
|
||||
else:
|
||||
for cu in action.fcurves:
|
||||
for bez in cu.keyframe_points:
|
||||
bez.interpolation = 'CONSTANT'
|
||||
|
||||
# END KEYFRAME METHOD
|
||||
|
||||
|
||||
"""
|
||||
# IPO KEYFRAME SETTING
|
||||
# Add in the IPOs by adding keyframes, AFAIK theres no way to add IPOs to an action so I do this :/
|
||||
for bvh_node in bvh_nodes.values():
|
||||
pose_bone, bone, bone_rest_matrix, bone_rest_matrix_inv= bvh_node.temp
|
||||
|
||||
# Get the transform
|
||||
xformConstants= xformConstants_dict[bvh_node.has_loc, bvh_node.has_rot]
|
||||
if xformConstants:
|
||||
pose_bone.loc[:]= 0,0,0
|
||||
pose_bone.quat[:]= 0,0,1,0
|
||||
# Insert the keyframe from the loc/quat
|
||||
pose_bone.insertKey(arm_ob, IMPORT_START_FRAME, xformConstants)
|
||||
|
||||
|
||||
action_ipos= action.getAllChannelIpos()
|
||||
|
||||
|
||||
for bvh_node in bvh_nodes.values():
|
||||
has_loc= bvh_node.has_loc
|
||||
has_rot= bvh_node.has_rot
|
||||
|
||||
if not has_rot and not has_loc:
|
||||
# No animation data
|
||||
continue
|
||||
|
||||
ipo= action_ipos[bvh_node.temp[0].name] # posebones name as key
|
||||
|
||||
if has_loc:
|
||||
curve_xloc= ipo[Blender.Ipo.PO_LOCX]
|
||||
curve_yloc= ipo[Blender.Ipo.PO_LOCY]
|
||||
curve_zloc= ipo[Blender.Ipo.PO_LOCZ]
|
||||
|
||||
curve_xloc.interpolation= \
|
||||
curve_yloc.interpolation= \
|
||||
curve_zloc.interpolation= \
|
||||
Blender.IpoCurve.InterpTypes.LINEAR
|
||||
|
||||
|
||||
if has_rot:
|
||||
curve_wquat= ipo[Blender.Ipo.PO_QUATW]
|
||||
curve_xquat= ipo[Blender.Ipo.PO_QUATX]
|
||||
curve_yquat= ipo[Blender.Ipo.PO_QUATY]
|
||||
curve_zquat= ipo[Blender.Ipo.PO_QUATZ]
|
||||
|
||||
curve_wquat.interpolation= \
|
||||
curve_xquat.interpolation= \
|
||||
curve_yquat.interpolation= \
|
||||
curve_zquat.interpolation= \
|
||||
Blender.IpoCurve.InterpTypes.LINEAR
|
||||
|
||||
# Get the bone
|
||||
pose_bone, bone, bone_rest_matrix, bone_rest_matrix_inv= bvh_node.temp
|
||||
|
||||
|
||||
def pose_rot(anim_data):
|
||||
bone_rotation_matrix= Euler(anim_data[3], anim_data[4], anim_data[5]).toMatrix()
|
||||
bone_rotation_matrix.resize4x4()
|
||||
return tuple((bone_rest_matrix * bone_rotation_matrix * bone_rest_matrix_inv).toQuat()) # qw,qx,qy,qz
|
||||
|
||||
def pose_loc(anim_data):
|
||||
return tuple((TranslationMatrix(Vector(anim_data[0], anim_data[1], anim_data[2])) * bone_rest_matrix_inv).translationPart())
|
||||
|
||||
|
||||
last_frame= len(bvh_node.anim_data)+IMPORT_START_FRAME-1
|
||||
|
||||
if has_loc:
|
||||
pose_locations= [pose_loc(anim_key) for anim_key in bvh_node.anim_data]
|
||||
|
||||
# Add the start at the end, we know the start is just 0,0,0 anyway
|
||||
curve_xloc.append((last_frame, pose_locations[-1][0]))
|
||||
curve_yloc.append((last_frame, pose_locations[-1][1]))
|
||||
curve_zloc.append((last_frame, pose_locations[-1][2]))
|
||||
|
||||
if len(pose_locations) > 1:
|
||||
ox,oy,oz= pose_locations[0]
|
||||
x,y,z= pose_locations[1]
|
||||
|
||||
for i in range(1, len(pose_locations)-1): # from second frame to second last frame
|
||||
|
||||
nx,ny,nz= pose_locations[i+1]
|
||||
xset= yset= zset= True # we set all these by default
|
||||
if abs((ox+nx)/2 - x) < 0.00001: xset= False
|
||||
if abs((oy+ny)/2 - y) < 0.00001: yset= False
|
||||
if abs((oz+nz)/2 - z) < 0.00001: zset= False
|
||||
|
||||
if xset: curve_xloc.append((i+IMPORT_START_FRAME, x))
|
||||
if yset: curve_yloc.append((i+IMPORT_START_FRAME, y))
|
||||
if zset: curve_zloc.append((i+IMPORT_START_FRAME, z))
|
||||
|
||||
# Set the old and use the new
|
||||
ox,oy,oz= x,y,z
|
||||
x,y,z= nx,ny,nz
|
||||
|
||||
|
||||
if has_rot:
|
||||
pose_rotations= [pose_rot(anim_key) for anim_key in bvh_node.anim_data]
|
||||
|
||||
# Add the start at the end, we know the start is just 0,0,0 anyway
|
||||
curve_wquat.append((last_frame, pose_rotations[-1][0]))
|
||||
curve_xquat.append((last_frame, pose_rotations[-1][1]))
|
||||
curve_yquat.append((last_frame, pose_rotations[-1][2]))
|
||||
curve_zquat.append((last_frame, pose_rotations[-1][3]))
|
||||
|
||||
|
||||
if len(pose_rotations) > 1:
|
||||
ow,ox,oy,oz= pose_rotations[0]
|
||||
w,x,y,z= pose_rotations[1]
|
||||
|
||||
for i in range(1, len(pose_rotations)-1): # from second frame to second last frame
|
||||
|
||||
nw, nx,ny,nz= pose_rotations[i+1]
|
||||
wset= xset= yset= zset= True # we set all these by default
|
||||
if abs((ow+nw)/2 - w) < 0.00001: wset= False
|
||||
if abs((ox+nx)/2 - x) < 0.00001: xset= False
|
||||
if abs((oy+ny)/2 - y) < 0.00001: yset= False
|
||||
if abs((oz+nz)/2 - z) < 0.00001: zset= False
|
||||
|
||||
if wset: curve_wquat.append((i+IMPORT_START_FRAME, w))
|
||||
if xset: curve_xquat.append((i+IMPORT_START_FRAME, x))
|
||||
if yset: curve_yquat.append((i+IMPORT_START_FRAME, y))
|
||||
if zset: curve_zquat.append((i+IMPORT_START_FRAME, z))
|
||||
|
||||
# Set the old and use the new
|
||||
ow,ox,oy,oz= w,x,y,z
|
||||
w,x,y,z= nw,nx,ny,nz
|
||||
|
||||
# IPO KEYFRAME SETTING
|
||||
"""
|
||||
|
||||
# XXX NOT NEEDED NOW?
|
||||
# pose.update()
|
||||
return arm_ob
|
||||
|
||||
|
||||
#=============#
|
||||
# TESTING #
|
||||
#=============#
|
||||
|
||||
#('/metavr/mocap/bvh/boxer.bvh')
|
||||
#('/d/staggered_walk.bvh')
|
||||
#('/metavr/mocap/bvh/dg-306-g.bvh') # Incompleate EOF
|
||||
#('/metavr/mocap/bvh/wa8lk.bvh') # duplicate joint names, \r line endings.
|
||||
#('/metavr/mocap/bvh/walk4.bvh') # 0 channels
|
||||
|
||||
'''
|
||||
import os
|
||||
DIR = '/metavr/mocap/bvh/'
|
||||
for f in ('/d/staggered_walk.bvh',):
|
||||
#for f in os.listdir(DIR)[5:6]:
|
||||
#for f in os.listdir(DIR):
|
||||
if f.endswith('.bvh'):
|
||||
s = Blender.Scene.New(f)
|
||||
s.makeCurrent()
|
||||
#file= DIR + f
|
||||
file= f
|
||||
print f
|
||||
bvh_nodes= read_bvh(file, 1.0)
|
||||
bvh_node_dict2armature(bvh_nodes, 1)
|
||||
'''
|
||||
|
||||
def load_bvh_ui(context, file, PREF_UI= False):
|
||||
|
||||
#XXX if BPyMessages.Error_NoFile(file):
|
||||
#XXX return
|
||||
|
||||
#XXX Draw= Blender.Draw
|
||||
|
||||
IMPORT_SCALE = 0.1
|
||||
IMPORT_START_FRAME = 1
|
||||
IMPORT_AS_ARMATURE = 1
|
||||
IMPORT_AS_EMPTIES = 0
|
||||
IMPORT_LOOP = 0
|
||||
|
||||
# Get USER Options
|
||||
if PREF_UI:
|
||||
pup_block = [\
|
||||
('As Armature', IMPORT_AS_ARMATURE, 'Imports the BVH as an armature'),\
|
||||
('As Empties', IMPORT_AS_EMPTIES, 'Imports the BVH as empties'),\
|
||||
('Scale: ', IMPORT_SCALE, 0.001, 100.0, 'Scale the BVH, Use 0.01 when 1.0 is 1 metre'),\
|
||||
('Start Frame: ', IMPORT_START_FRAME, 1, 30000, 'Frame to start BVH motion'),\
|
||||
('Loop Animation', IMPORT_LOOP, 'Enable cyclic IPOs'),\
|
||||
]
|
||||
|
||||
#XXX if not Draw.PupBlock('BVH Import...', pup_block):
|
||||
#XXX return
|
||||
|
||||
# print('Attempting import BVH', file)
|
||||
|
||||
if not IMPORT_AS_ARMATURE and not IMPORT_AS_EMPTIES:
|
||||
raise('No import option selected')
|
||||
|
||||
#XXX Blender.Window.WaitCursor(1)
|
||||
# Get the BVH data and act on it.
|
||||
import time
|
||||
t1= time.time()
|
||||
print('\tparsing bvh...', end= "")
|
||||
bvh_nodes= read_bvh(context, file, IMPORT_SCALE)
|
||||
print('%.4f' % (time.time()-t1))
|
||||
t1= time.time()
|
||||
print('\timporting to blender...', end="")
|
||||
if IMPORT_AS_ARMATURE: bvh_node_dict2armature(context, bvh_nodes, IMPORT_START_FRAME, IMPORT_LOOP)
|
||||
if IMPORT_AS_EMPTIES: bvh_node_dict2objects(context, bvh_nodes, IMPORT_START_FRAME, IMPORT_LOOP)
|
||||
|
||||
print('Done in %.4f\n' % (time.time()-t1))
|
||||
#XXX Blender.Window.WaitCursor(0)
|
||||
|
||||
def main():
|
||||
Blender.Window.FileSelector(load_bvh_ui, 'Import BVH', '*.bvh')
|
||||
|
||||
from bpy.props import *
|
||||
|
||||
class BvhImporter(bpy.types.Operator):
|
||||
'''Load a Wavefront OBJ File.'''
|
||||
bl_idname = "import_anim.bvh"
|
||||
bl_label = "Import BVH"
|
||||
|
||||
path = StringProperty(name="File Path", description="File path used for importing the OBJ file", maxlen= 1024, default= "")
|
||||
|
||||
def execute(self, context):
|
||||
# print("Selected: " + context.active_object.name)
|
||||
|
||||
read_bvh(context, self.path)
|
||||
|
||||
return ('FINISHED',)
|
||||
|
||||
def invoke(self, context, event):
|
||||
wm = context.manager
|
||||
wm.add_fileselect(self)
|
||||
return ('RUNNING_MODAL',)
|
||||
|
||||
|
||||
bpy.ops.add(BvhImporter)
|
||||
|
||||
|
||||
import dynamic_menu
|
||||
menu_func = lambda self, context: self.layout.itemO(BvhImporter.bl_idname, text="Motion Capture (.bvh)...")
|
||||
menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_import, menu_func)
|
@ -1,3 +1,20 @@
|
||||
# ##### 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
__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/")
|
||||
@ -122,7 +139,7 @@ import os
|
||||
import time
|
||||
import struct
|
||||
|
||||
from import_obj import unpack_face_list, load_image
|
||||
from import_scene_obj import unpack_face_list, load_image
|
||||
|
||||
import bpy
|
||||
import Mathutils
|
||||
@ -1121,22 +1138,22 @@ else:
|
||||
print 'TOTAL TIME: %.6f' % (Blender.sys.time() - TIME)
|
||||
|
||||
'''
|
||||
from bpy.props import *
|
||||
|
||||
class IMPORT_OT_3ds(bpy.types.Operator):
|
||||
|
||||
class IMPORT_OT_autodesk_3ds(bpy.types.Operator):
|
||||
'''Import from 3DS file format (.3ds)'''
|
||||
__idname__ = "import.3ds"
|
||||
__label__ = 'Import 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.
|
||||
|
||||
__props__ = [
|
||||
bpy.props.StringProperty(attr="path", name="File Path", description="File path used for importing the 3DS file", maxlen= 1024, default= ""),
|
||||
path = StringProperty(name="File Path", description="File path used for importing the 3DS file", maxlen= 1024, default= ""),
|
||||
|
||||
# bpy.props.FloatProperty(attr="size_constraint", 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),
|
||||
# bpy.props.BoolProperty(attr="search_images", name="Image Search", description="Search subdirectories for any assosiated images (Warning, may be slow)", default=True),
|
||||
# bpy.props.BoolProperty(attr="apply_matrix", name="Transform Fix", description="Workaround for object transformations importing incorrectly", default=False),
|
||||
]
|
||||
# size_constraint = 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_matrix = BoolProperty(name="Transform Fix", description="Workaround for object transformations importing incorrectly", default=False),
|
||||
|
||||
def execute(self, context):
|
||||
load_3ds(self.path, context, 0.0, False, False)
|
||||
@ -1144,13 +1161,13 @@ class IMPORT_OT_3ds(bpy.types.Operator):
|
||||
|
||||
def invoke(self, context, event):
|
||||
wm = context.manager
|
||||
wm.add_fileselect(self.__operator__)
|
||||
wm.add_fileselect(self)
|
||||
return ('RUNNING_MODAL',)
|
||||
|
||||
bpy.ops.add(IMPORT_OT_3ds)
|
||||
bpy.ops.add(IMPORT_OT_autodesk_3ds)
|
||||
|
||||
import dynamic_menu
|
||||
menu_func = lambda self, context: self.layout.itemO("import.3ds", text="3D Studio (.3ds)...")
|
||||
menu_func = lambda self, context: self.layout.itemO(IMPORT_OT_autodesk_3ds.bl_idname, text="3D Studio (.3ds)...")
|
||||
menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_import, menu_func)
|
||||
|
||||
# NOTES:
|
@ -1,3 +1,20 @@
|
||||
# ##### 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
__author__= "Campbell Barton", "Jiri Hnidek", "Paolo Ciccone"
|
||||
__url__= ['http://wiki.blender.org/index.php/Scripts/Manual/Import/wavefront_obj', 'blender.org', 'blenderartists.org']
|
||||
@ -1553,31 +1570,33 @@ else:
|
||||
print 'TOTAL TIME: %.6f' % (sys.time() - TIME)
|
||||
'''
|
||||
|
||||
from bpy.props import *
|
||||
|
||||
class IMPORT_OT_obj(bpy.types.Operator):
|
||||
'''Load a Wavefront OBJ File.'''
|
||||
__idname__ = "import.obj"
|
||||
__label__ = "Import OBJ"
|
||||
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.
|
||||
|
||||
__props__ = [
|
||||
bpy.props.StringProperty(attr="path", name="File Path", description="File path used for importing the OBJ file", maxlen= 1024, default= ""),
|
||||
|
||||
bpy.props.BoolProperty(attr="CREATE_SMOOTH_GROUPS", name="Smooth Groups", description="Surround smooth groups by sharp edges", default= True),
|
||||
bpy.props.BoolProperty(attr="CREATE_FGONS", name="NGons as FGons", description="Import faces with more then 4 verts as fgons", default= True),
|
||||
bpy.props.BoolProperty(attr="CREATE_EDGES", name="Lines as Edges", description="Import lines and faces with 2 verts as edge", default= True),
|
||||
bpy.props.BoolProperty(attr="SPLIT_OBJECTS", name="Object", description="Import OBJ Objects into Blender Objects", default= True),
|
||||
bpy.props.BoolProperty(attr="SPLIT_GROUPS", name="Group", description="Import OBJ Groups into Blender Objects", default= True),
|
||||
bpy.props.BoolProperty(attr="SPLIT_MATERIALS", name="Material", description="Import each material into a seperate mesh (Avoids > 16 per mesh error)", default= True),
|
||||
path = StringProperty(name="File Path", description="File path 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)
|
||||
SPLIT_MATERIALS = BoolProperty(name="Material", description="Import each material into a seperate mesh (Avoids > 16 per mesh error)", 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
|
||||
# bpy.props.BoolProperty(attr="KEEP_VERT_ORDER", name="Keep Vert Order", description="Keep vert and face order, disables split options, enable for morph targets", default= True),
|
||||
bpy.props.BoolProperty(attr="ROTATE_X90", name="-X90", description="Rotate X 90.", default= True),
|
||||
bpy.props.FloatProperty(attr="CLAMP_SIZE", name="Clamp Scale", description="Clamp the size to this maximum (Zero to Disable)", min=0.01, max=1000.0, soft_min=0.0, soft_max=1000.0, default=0.0),
|
||||
bpy.props.BoolProperty(attr="POLYGROUPS", name="Poly Groups", description="Import OBJ groups as vertex groups.", default= True),
|
||||
bpy.props.BoolProperty(attr="IMAGE_SEARCH", name="Image Search", description="Search subdirs for any assosiated images (Warning, may be slow)", default= True),
|
||||
]
|
||||
# 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.01, 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)
|
||||
@ -1599,7 +1618,7 @@ class IMPORT_OT_obj(bpy.types.Operator):
|
||||
|
||||
def invoke(self, context, event):
|
||||
wm = context.manager
|
||||
wm.add_fileselect(self.__operator__)
|
||||
wm.add_fileselect(self)
|
||||
return ('RUNNING_MODAL',)
|
||||
|
||||
|
||||
@ -1607,7 +1626,7 @@ bpy.ops.add(IMPORT_OT_obj)
|
||||
|
||||
|
||||
import dynamic_menu
|
||||
menu_func = lambda self, context: self.layout.itemO("import.obj", text="Wavefront (.obj)...")
|
||||
menu_func = lambda self, context: self.layout.itemO(IMPORT_OT_obj.bl_idname, text="Wavefront (.obj)...")
|
||||
menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_import, menu_func)
|
||||
|
||||
|
@ -1,3 +1,21 @@
|
||||
# ##### 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
# This directory is a Python package.
|
||||
|
||||
import model
|
||||
@ -14,6 +32,7 @@ import ui
|
||||
|
||||
import bpy
|
||||
|
||||
bpy.data.netrender_jobs = []
|
||||
bpy.data.netrender_slaves = []
|
||||
bpy.data.netrender_blacklist = []
|
||||
bpy.netrender_jobs = []
|
||||
bpy.netrender_slaves = []
|
||||
bpy.netrender_blacklist = []
|
||||
|
||||
|
@ -1,3 +1,21 @@
|
||||
# ##### 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
import time
|
||||
|
||||
from netrender.utils import *
|
||||
|
@ -1,3 +1,21 @@
|
||||
# ##### 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
import bpy
|
||||
import sys, os, re
|
||||
import http, http.client, http.server, urllib
|
||||
@ -28,7 +46,7 @@ def addPointCache(job, ob, point_cache, default_path):
|
||||
if name == "":
|
||||
name = "".join(["%02X" % ord(c) for c in ob.name])
|
||||
|
||||
cache_path = bpy.sys.expandpath(point_cache.filepath) if point_cache.external else default_path
|
||||
cache_path = bpy.utils.expandpath(point_cache.filepath) if point_cache.external else default_path
|
||||
|
||||
index = "%02i" % point_cache.index
|
||||
|
||||
@ -93,14 +111,14 @@ def clientSendJob(conn, scene, anim = False):
|
||||
# LIBRARIES
|
||||
###########################
|
||||
for lib in bpy.data.libraries:
|
||||
job.addFile(bpy.sys.expandpath(lib_path))
|
||||
job.addFile(bpy.utils.expandpath(lib_path))
|
||||
|
||||
###########################
|
||||
# IMAGES
|
||||
###########################
|
||||
for image in bpy.data.images:
|
||||
if image.source == "FILE" and not image.packed_file:
|
||||
job.addFile(bpy.sys.expandpath(image.filename))
|
||||
job.addFile(bpy.utils.expandpath(image.filename))
|
||||
|
||||
###########################
|
||||
# FLUID + POINT CACHE
|
||||
@ -111,7 +129,7 @@ def clientSendJob(conn, scene, anim = False):
|
||||
for object in bpy.data.objects:
|
||||
for modifier in object.modifiers:
|
||||
if modifier.type == 'FLUID_SIMULATION' and modifier.settings.type == "DOMAIN":
|
||||
addFluidFiles(job, bpy.sys.expandpath(modifier.settings.path))
|
||||
addFluidFiles(job, bpy.utils.expandpath(modifier.settings.path))
|
||||
elif modifier.type == "CLOTH":
|
||||
addPointCache(job, object, modifier.point_cache, default_path)
|
||||
elif modifier.type == "SOFT_BODY":
|
||||
@ -159,8 +177,8 @@ def requestResult(conn, job_id, frame):
|
||||
|
||||
@rnaType
|
||||
class NetworkRenderEngine(bpy.types.RenderEngine):
|
||||
__idname__ = 'NET_RENDER'
|
||||
__label__ = "Network Render"
|
||||
bl_idname = 'NET_RENDER'
|
||||
bl_label = "Network Render"
|
||||
def render(self, scene):
|
||||
if scene.network_render.mode == "RENDER_CLIENT":
|
||||
self.render_client(scene)
|
||||
@ -235,3 +253,15 @@ class NetworkRenderEngine(bpy.types.RenderEngine):
|
||||
|
||||
conn.close()
|
||||
|
||||
def compatible(module):
|
||||
exec("import " + module)
|
||||
module = eval(module)
|
||||
for member in dir(module):
|
||||
subclass = getattr(module, member)
|
||||
try: subclass.COMPAT_ENGINES.add('NET_RENDER')
|
||||
except: pass
|
||||
del module
|
||||
|
||||
compatible("properties_render")
|
||||
compatible("properties_world")
|
||||
compatible("properties_material")
|
||||
|
@ -1,3 +1,21 @@
|
||||
# ##### 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
import sys, os
|
||||
import http, http.client, http.server, urllib, socket
|
||||
import subprocess, shutil, time, hashlib
|
||||
|
@ -1,3 +1,21 @@
|
||||
# ##### 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
import re
|
||||
|
||||
from netrender.utils import *
|
||||
|
@ -1,3 +1,21 @@
|
||||
# ##### 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
import sys, os
|
||||
import http, http.client, http.server, urllib
|
||||
import subprocess, shutil, time, hashlib
|
||||
|
@ -1,3 +1,21 @@
|
||||
# ##### 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
import bpy
|
||||
import sys, os
|
||||
import http, http.client, http.server, urllib, socket
|
||||
@ -10,13 +28,8 @@ import netrender.model
|
||||
@rnaOperator
|
||||
class RENDER_OT_netclientanim(bpy.types.Operator):
|
||||
'''Start rendering an animation on network'''
|
||||
__idname__ = "render.netclientanim"
|
||||
__label__ = "Animation on network"
|
||||
|
||||
# List of operator properties, the attributes will be assigned
|
||||
# to the class instance from the operator settings before calling.
|
||||
|
||||
__props__ = []
|
||||
bl_idname = "render.netclientanim"
|
||||
bl_label = "Animation on network"
|
||||
|
||||
def poll(self, context):
|
||||
return True
|
||||
@ -41,13 +54,8 @@ class RENDER_OT_netclientanim(bpy.types.Operator):
|
||||
@rnaOperator
|
||||
class RENDER_OT_netclientsend(bpy.types.Operator):
|
||||
'''Send Render Job to the Network'''
|
||||
__idname__ = "render.netclientsend"
|
||||
__label__ = "Send job"
|
||||
|
||||
# List of operator properties, the attributes will be assigned
|
||||
# to the class instance from the operator settings before calling.
|
||||
|
||||
__props__ = []
|
||||
bl_idname = "render.netclientsend"
|
||||
bl_label = "Send job"
|
||||
|
||||
def poll(self, context):
|
||||
return True
|
||||
@ -70,13 +78,8 @@ class RENDER_OT_netclientsend(bpy.types.Operator):
|
||||
@rnaOperator
|
||||
class RENDER_OT_netclientstatus(bpy.types.Operator):
|
||||
'''Refresh the status of the current jobs'''
|
||||
__idname__ = "render.netclientstatus"
|
||||
__label__ = "Client Status"
|
||||
|
||||
# List of operator properties, the attributes will be assigned
|
||||
# to the class instance from the operator settings before calling.
|
||||
|
||||
__props__ = []
|
||||
bl_idname = "render.netclientstatus"
|
||||
bl_label = "Client Status"
|
||||
|
||||
def poll(self, context):
|
||||
return True
|
||||
@ -96,10 +99,10 @@ class RENDER_OT_netclientstatus(bpy.types.Operator):
|
||||
while(len(netsettings.jobs) > 0):
|
||||
netsettings.jobs.remove(0)
|
||||
|
||||
bpy.data.netrender_jobs = []
|
||||
bpy.netrender_jobs = []
|
||||
|
||||
for j in jobs:
|
||||
bpy.data.netrender_jobs.append(j)
|
||||
bpy.netrender_jobs.append(j)
|
||||
netsettings.jobs.add()
|
||||
job = netsettings.jobs[-1]
|
||||
|
||||
@ -115,13 +118,8 @@ class RENDER_OT_netclientstatus(bpy.types.Operator):
|
||||
@rnaOperator
|
||||
class RENDER_OT_netclientblacklistslave(bpy.types.Operator):
|
||||
'''Operator documentation text, will be used for the operator tooltip and python docs.'''
|
||||
__idname__ = "render.netclientblacklistslave"
|
||||
__label__ = "Client Blacklist Slave"
|
||||
|
||||
# List of operator properties, the attributes will be assigned
|
||||
# to the class instance from the operator settings before calling.
|
||||
|
||||
__props__ = []
|
||||
bl_idname = "render.netclientblacklistslave"
|
||||
bl_label = "Client Blacklist Slave"
|
||||
|
||||
def poll(self, context):
|
||||
return True
|
||||
@ -132,8 +130,8 @@ class RENDER_OT_netclientblacklistslave(bpy.types.Operator):
|
||||
if netsettings.active_slave_index >= 0:
|
||||
|
||||
# deal with data
|
||||
slave = bpy.data.netrender_slaves.pop(netsettings.active_slave_index)
|
||||
bpy.data.netrender_blacklist.append(slave)
|
||||
slave = bpy.netrender_slaves.pop(netsettings.active_slave_index)
|
||||
bpy.netrender_blacklist.append(slave)
|
||||
|
||||
# deal with rna
|
||||
netsettings.slaves_blacklist.add()
|
||||
@ -150,13 +148,8 @@ class RENDER_OT_netclientblacklistslave(bpy.types.Operator):
|
||||
@rnaOperator
|
||||
class RENDER_OT_netclientwhitelistslave(bpy.types.Operator):
|
||||
'''Operator documentation text, will be used for the operator tooltip and python docs.'''
|
||||
__idname__ = "render.netclientwhitelistslave"
|
||||
__label__ = "Client Whitelist Slave"
|
||||
|
||||
# List of operator properties, the attributes will be assigned
|
||||
# to the class instance from the operator settings before calling.
|
||||
|
||||
__props__ = []
|
||||
bl_idname = "render.netclientwhitelistslave"
|
||||
bl_label = "Client Whitelist Slave"
|
||||
|
||||
def poll(self, context):
|
||||
return True
|
||||
@ -167,8 +160,8 @@ class RENDER_OT_netclientwhitelistslave(bpy.types.Operator):
|
||||
if netsettings.active_blacklisted_slave_index >= 0:
|
||||
|
||||
# deal with data
|
||||
slave = bpy.data.netrender_blacklist.pop(netsettings.active_blacklisted_slave_index)
|
||||
bpy.data.netrender_slaves.append(slave)
|
||||
slave = bpy.netrender_blacklist.pop(netsettings.active_blacklisted_slave_index)
|
||||
bpy.netrender_slaves.append(slave)
|
||||
|
||||
# deal with rna
|
||||
netsettings.slaves.add()
|
||||
@ -186,13 +179,8 @@ class RENDER_OT_netclientwhitelistslave(bpy.types.Operator):
|
||||
@rnaOperator
|
||||
class RENDER_OT_netclientslaves(bpy.types.Operator):
|
||||
'''Refresh status about available Render slaves'''
|
||||
__idname__ = "render.netclientslaves"
|
||||
__label__ = "Client Slaves"
|
||||
|
||||
# List of operator properties, the attributes will be assigned
|
||||
# to the class instance from the operator settings before calling.
|
||||
|
||||
__props__ = []
|
||||
bl_idname = "render.netclientslaves"
|
||||
bl_label = "Client Slaves"
|
||||
|
||||
def poll(self, context):
|
||||
return True
|
||||
@ -212,17 +200,17 @@ class RENDER_OT_netclientslaves(bpy.types.Operator):
|
||||
while(len(netsettings.slaves) > 0):
|
||||
netsettings.slaves.remove(0)
|
||||
|
||||
bpy.data.netrender_slaves = []
|
||||
bpy.netrender_slaves = []
|
||||
|
||||
for s in slaves:
|
||||
for i in range(len(bpy.data.netrender_blacklist)):
|
||||
slave = bpy.data.netrender_blacklist[i]
|
||||
for i in range(len(bpy.netrender_blacklist)):
|
||||
slave = bpy.netrender_blacklist[i]
|
||||
if slave.id == s.id:
|
||||
bpy.data.netrender_blacklist[i] = s
|
||||
bpy.netrender_blacklist[i] = s
|
||||
netsettings.slaves_blacklist[i].name = s.name
|
||||
break
|
||||
else:
|
||||
bpy.data.netrender_slaves.append(s)
|
||||
bpy.netrender_slaves.append(s)
|
||||
|
||||
netsettings.slaves.add()
|
||||
slave = netsettings.slaves[-1]
|
||||
@ -236,13 +224,8 @@ class RENDER_OT_netclientslaves(bpy.types.Operator):
|
||||
@rnaOperator
|
||||
class RENDER_OT_netclientcancel(bpy.types.Operator):
|
||||
'''Cancel the selected network rendering job.'''
|
||||
__idname__ = "render.netclientcancel"
|
||||
__label__ = "Client Cancel"
|
||||
|
||||
# List of operator properties, the attributes will be assigned
|
||||
# to the class instance from the operator settings before calling.
|
||||
|
||||
__props__ = []
|
||||
bl_idname = "render.netclientcancel"
|
||||
bl_label = "Client Cancel"
|
||||
|
||||
def poll(self, context):
|
||||
netsettings = context.scene.network_render
|
||||
@ -253,7 +236,7 @@ class RENDER_OT_netclientcancel(bpy.types.Operator):
|
||||
conn = clientConnection(context.scene)
|
||||
|
||||
if conn:
|
||||
job = bpy.data.netrender_jobs[netsettings.active_job_index]
|
||||
job = bpy.netrender_jobs[netsettings.active_job_index]
|
||||
|
||||
conn.request("POST", "/cancel", headers={"job-id":job.id})
|
||||
|
||||
@ -270,13 +253,8 @@ class RENDER_OT_netclientcancel(bpy.types.Operator):
|
||||
@rnaOperator
|
||||
class RENDER_OT_netclientcancelall(bpy.types.Operator):
|
||||
'''Cancel all running network rendering jobs.'''
|
||||
__idname__ = "render.netclientcancelall"
|
||||
__label__ = "Client Cancel All"
|
||||
|
||||
# List of operator properties, the attributes will be assigned
|
||||
# to the class instance from the operator settings before calling.
|
||||
|
||||
__props__ = []
|
||||
bl_idname = "render.netclientcancelall"
|
||||
bl_label = "Client Cancel All"
|
||||
|
||||
def poll(self, context):
|
||||
return True
|
||||
@ -302,13 +280,8 @@ class RENDER_OT_netclientcancelall(bpy.types.Operator):
|
||||
@rnaOperator
|
||||
class netclientdownload(bpy.types.Operator):
|
||||
'''Download render results from the network'''
|
||||
__idname__ = "render.netclientdownload"
|
||||
__label__ = "Client Download"
|
||||
|
||||
# List of operator properties, the attributes will be assigned
|
||||
# to the class instance from the operator settings before calling.
|
||||
|
||||
__props__ = []
|
||||
bl_idname = "render.netclientdownload"
|
||||
bl_label = "Client Download"
|
||||
|
||||
def poll(self, context):
|
||||
netsettings = context.scene.network_render
|
||||
@ -321,7 +294,7 @@ class netclientdownload(bpy.types.Operator):
|
||||
conn = clientConnection(context.scene)
|
||||
|
||||
if conn:
|
||||
job = bpy.data.netrender_jobs[netsettings.active_job_index]
|
||||
job = bpy.netrender_jobs[netsettings.active_job_index]
|
||||
|
||||
for frame in job.frames:
|
||||
client.requestResult(conn, job.id, frame.number)
|
||||
@ -352,13 +325,8 @@ class netclientdownload(bpy.types.Operator):
|
||||
@rnaOperator
|
||||
class netclientscan(bpy.types.Operator):
|
||||
'''Operator documentation text, will be used for the operator tooltip and python docs.'''
|
||||
__idname__ = "render.netclientscan"
|
||||
__label__ = "Client Scan"
|
||||
|
||||
# List of operator properties, the attributes will be assigned
|
||||
# to the class instance from the operator settings before calling.
|
||||
|
||||
__props__ = []
|
||||
bl_idname = "render.netclientscan"
|
||||
bl_label = "Client Scan"
|
||||
|
||||
def poll(self, context):
|
||||
return True
|
||||
@ -390,13 +358,8 @@ class netclientscan(bpy.types.Operator):
|
||||
@rnaOperator
|
||||
class netclientweb(bpy.types.Operator):
|
||||
'''Open new window with information about running rendering jobs'''
|
||||
__idname__ = "render.netclientweb"
|
||||
__label__ = "Open Master Monitor"
|
||||
|
||||
# List of operator properties, the attributes will be assigned
|
||||
# to the class instance from the operator settings before calling.
|
||||
|
||||
__props__ = []
|
||||
bl_idname = "render.netclientweb"
|
||||
bl_label = "Open Master Monitor"
|
||||
|
||||
def poll(self, context):
|
||||
return True
|
||||
|
@ -1,3 +1,21 @@
|
||||
# ##### 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
import sys, os, platform
|
||||
import http, http.client, http.server, urllib
|
||||
import subprocess, time
|
||||
|
@ -1,3 +1,21 @@
|
||||
# ##### 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
import bpy
|
||||
import sys, os
|
||||
import http, http.client, http.server, urllib
|
||||
@ -18,9 +36,9 @@ DONE = 2
|
||||
ERROR = 3
|
||||
|
||||
class RenderButtonsPanel(bpy.types.Panel):
|
||||
__space_type__ = "PROPERTIES"
|
||||
__region_type__ = "WINDOW"
|
||||
__context__ = "render"
|
||||
bl_space_type = "PROPERTIES"
|
||||
bl_region_type = "WINDOW"
|
||||
bl_context = "render"
|
||||
# COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here
|
||||
|
||||
def poll(self, context):
|
||||
@ -30,7 +48,7 @@ class RenderButtonsPanel(bpy.types.Panel):
|
||||
# Setting panel, use in the scene for now.
|
||||
@rnaType
|
||||
class RENDER_PT_network_settings(RenderButtonsPanel):
|
||||
__label__ = "Network Settings"
|
||||
bl_label = "Network Settings"
|
||||
COMPAT_ENGINES = set(['NET_RENDER'])
|
||||
|
||||
def draw(self, context):
|
||||
@ -56,7 +74,7 @@ class RENDER_PT_network_settings(RenderButtonsPanel):
|
||||
|
||||
@rnaType
|
||||
class RENDER_PT_network_job(RenderButtonsPanel):
|
||||
__label__ = "Job Settings"
|
||||
bl_label = "Job Settings"
|
||||
COMPAT_ENGINES = set(['NET_RENDER'])
|
||||
|
||||
def poll(self, context):
|
||||
@ -84,7 +102,7 @@ class RENDER_PT_network_job(RenderButtonsPanel):
|
||||
|
||||
@rnaType
|
||||
class RENDER_PT_network_slaves(RenderButtonsPanel):
|
||||
__label__ = "Slaves Status"
|
||||
bl_label = "Slaves Status"
|
||||
COMPAT_ENGINES = set(['NET_RENDER'])
|
||||
|
||||
def poll(self, context):
|
||||
@ -104,14 +122,14 @@ class RENDER_PT_network_slaves(RenderButtonsPanel):
|
||||
sub.itemO("render.netclientslaves", icon="ICON_FILE_REFRESH", text="")
|
||||
sub.itemO("render.netclientblacklistslave", icon="ICON_ZOOMOUT", text="")
|
||||
|
||||
if len(bpy.data.netrender_slaves) == 0 and len(netsettings.slaves) > 0:
|
||||
if len(bpy.netrender_slaves) == 0 and len(netsettings.slaves) > 0:
|
||||
while(len(netsettings.slaves) > 0):
|
||||
netsettings.slaves.remove(0)
|
||||
|
||||
if netsettings.active_slave_index >= 0 and len(netsettings.slaves) > 0:
|
||||
layout.itemS()
|
||||
|
||||
slave = bpy.data.netrender_slaves[netsettings.active_slave_index]
|
||||
slave = bpy.netrender_slaves[netsettings.active_slave_index]
|
||||
|
||||
layout.itemL(text="Name: " + slave.name)
|
||||
layout.itemL(text="Address: " + slave.address[0])
|
||||
@ -120,7 +138,7 @@ class RENDER_PT_network_slaves(RenderButtonsPanel):
|
||||
|
||||
@rnaType
|
||||
class RENDER_PT_network_slaves_blacklist(RenderButtonsPanel):
|
||||
__label__ = "Slaves Blacklist"
|
||||
bl_label = "Slaves Blacklist"
|
||||
COMPAT_ENGINES = set(['NET_RENDER'])
|
||||
|
||||
def poll(self, context):
|
||||
@ -139,14 +157,14 @@ class RENDER_PT_network_slaves_blacklist(RenderButtonsPanel):
|
||||
sub = row.column(align=True)
|
||||
sub.itemO("render.netclientwhitelistslave", icon="ICON_ZOOMOUT", text="")
|
||||
|
||||
if len(bpy.data.netrender_blacklist) == 0 and len(netsettings.slaves_blacklist) > 0:
|
||||
if len(bpy.netrender_blacklist) == 0 and len(netsettings.slaves_blacklist) > 0:
|
||||
while(len(netsettings.slaves_blacklist) > 0):
|
||||
netsettings.slaves_blacklist.remove(0)
|
||||
|
||||
if netsettings.active_blacklisted_slave_index >= 0 and len(netsettings.slaves_blacklist) > 0:
|
||||
layout.itemS()
|
||||
|
||||
slave = bpy.data.netrender_blacklist[netsettings.active_blacklisted_slave_index]
|
||||
slave = bpy.netrender_blacklist[netsettings.active_blacklisted_slave_index]
|
||||
|
||||
layout.itemL(text="Name: " + slave.name)
|
||||
layout.itemL(text="Address: " + slave.address[0])
|
||||
@ -155,7 +173,7 @@ class RENDER_PT_network_slaves_blacklist(RenderButtonsPanel):
|
||||
|
||||
@rnaType
|
||||
class RENDER_PT_network_jobs(RenderButtonsPanel):
|
||||
__label__ = "Jobs"
|
||||
bl_label = "Jobs"
|
||||
COMPAT_ENGINES = set(['NET_RENDER'])
|
||||
|
||||
def poll(self, context):
|
||||
@ -177,14 +195,14 @@ class RENDER_PT_network_jobs(RenderButtonsPanel):
|
||||
sub.itemO("render.netclientcancelall", icon="ICON_PANEL_CLOSE", text="")
|
||||
sub.itemO("render.netclientdownload", icon='ICON_RENDER_ANIMATION', text="")
|
||||
|
||||
if len(bpy.data.netrender_jobs) == 0 and len(netsettings.jobs) > 0:
|
||||
if len(bpy.netrender_jobs) == 0 and len(netsettings.jobs) > 0:
|
||||
while(len(netsettings.jobs) > 0):
|
||||
netsettings.jobs.remove(0)
|
||||
|
||||
if netsettings.active_job_index >= 0 and len(netsettings.jobs) > 0:
|
||||
layout.itemS()
|
||||
|
||||
job = bpy.data.netrender_jobs[netsettings.active_job_index]
|
||||
job = bpy.netrender_jobs[netsettings.active_job_index]
|
||||
|
||||
layout.itemL(text="Name: %s" % job.name)
|
||||
layout.itemL(text="Length: %04i" % len(job))
|
||||
|
@ -1,3 +1,21 @@
|
||||
# ##### 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
import bpy
|
||||
import sys, os
|
||||
import re
|
||||
|
@ -1,211 +0,0 @@
|
||||
|
||||
|
||||
def execute(bcon):
|
||||
'''
|
||||
This function has been taken from a BGE console autocomp I wrote a while ago
|
||||
the dictionaty bcon is not needed but it means I can copy and paste from the old func
|
||||
which works ok for now.
|
||||
|
||||
'bcon' dictionary keys, set by the caller
|
||||
* 'cursor' - index of the editing character (int)
|
||||
* 'edit_text' - text string for editing (string)
|
||||
* 'scrollback' - text to add to the scrollback, options are added here. (text)
|
||||
* 'namespace' - namespace, (dictionary)
|
||||
|
||||
'''
|
||||
|
||||
|
||||
def is_delimiter(ch):
|
||||
'''
|
||||
For skipping words
|
||||
'''
|
||||
if ch == '_':
|
||||
return False
|
||||
if ch.isalnum():
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def is_delimiter_autocomp(ch):
|
||||
'''
|
||||
When autocompleteing will earch back and
|
||||
'''
|
||||
if ch in '._[] "\'':
|
||||
return False
|
||||
if ch.isalnum():
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def do_autocomp(autocomp_prefix, autocomp_members):
|
||||
'''
|
||||
return text to insert and a list of options
|
||||
'''
|
||||
autocomp_members = [v for v in autocomp_members if v.startswith(autocomp_prefix)]
|
||||
|
||||
print("AUTO: '%s'" % autocomp_prefix)
|
||||
print("MEMBERS: '%s'" % str(autocomp_members))
|
||||
|
||||
if not autocomp_prefix:
|
||||
return '', autocomp_members
|
||||
elif len(autocomp_members) > 1:
|
||||
# find a common string between all members after the prefix
|
||||
# 'ge' [getA, getB, getC] --> 'get'
|
||||
|
||||
# get the shortest member
|
||||
min_len = min([len(v) for v in autocomp_members])
|
||||
|
||||
autocomp_prefix_ret = ''
|
||||
|
||||
for i in range(len(autocomp_prefix), min_len):
|
||||
char_soup = set()
|
||||
for v in autocomp_members:
|
||||
char_soup.add(v[i])
|
||||
|
||||
if len(char_soup) > 1:
|
||||
break
|
||||
else:
|
||||
autocomp_prefix_ret += char_soup.pop()
|
||||
|
||||
return autocomp_prefix_ret, autocomp_members
|
||||
elif len(autocomp_members) == 1:
|
||||
if autocomp_prefix == autocomp_members[0]:
|
||||
# the variable matched the prefix exactly
|
||||
# add a '.' so you can quickly continue.
|
||||
# Could try add [] or other possible extensions rather then '.' too if we had the variable.
|
||||
return '.', []
|
||||
else:
|
||||
# finish off the of the word word
|
||||
return autocomp_members[0][len(autocomp_prefix):], []
|
||||
else:
|
||||
return '', []
|
||||
|
||||
|
||||
def BCon_PrevChar(bcon):
|
||||
cursor = bcon['cursor']-1
|
||||
if cursor<0:
|
||||
return None
|
||||
|
||||
try:
|
||||
return bcon['edit_text'][cursor]
|
||||
except:
|
||||
return None
|
||||
|
||||
|
||||
def BCon_NextChar(bcon):
|
||||
try:
|
||||
return bcon['edit_text'][bcon['cursor']]
|
||||
except:
|
||||
return None
|
||||
|
||||
def BCon_cursorLeft(bcon):
|
||||
bcon['cursor'] -= 1
|
||||
if bcon['cursor'] < 0:
|
||||
bcon['cursor'] = 0
|
||||
|
||||
def BCon_cursorRight(bcon):
|
||||
bcon['cursor'] += 1
|
||||
if bcon['cursor'] > len(bcon['edit_text']):
|
||||
bcon['cursor'] = len(bcon['edit_text'])
|
||||
|
||||
def BCon_AddScrollback(bcon, text):
|
||||
|
||||
bcon['scrollback'] = bcon['scrollback'] + text
|
||||
|
||||
|
||||
def BCon_cursorInsertChar(bcon, ch):
|
||||
if bcon['cursor']==0:
|
||||
bcon['edit_text'] = ch + bcon['edit_text']
|
||||
elif bcon['cursor']==len(bcon['edit_text']):
|
||||
bcon['edit_text'] = bcon['edit_text'] + ch
|
||||
else:
|
||||
bcon['edit_text'] = bcon['edit_text'][:bcon['cursor']] + ch + bcon['edit_text'][bcon['cursor']:]
|
||||
|
||||
bcon['cursor']
|
||||
if bcon['cursor'] > len(bcon['edit_text']):
|
||||
bcon['cursor'] = len(bcon['edit_text'])
|
||||
BCon_cursorRight(bcon)
|
||||
|
||||
|
||||
TEMP_NAME = '___tempname___'
|
||||
|
||||
cursor_orig = bcon['cursor']
|
||||
|
||||
ch = BCon_PrevChar(bcon)
|
||||
while ch != None and (not is_delimiter(ch)):
|
||||
ch = BCon_PrevChar(bcon)
|
||||
BCon_cursorLeft(bcon)
|
||||
|
||||
if ch != None:
|
||||
BCon_cursorRight(bcon)
|
||||
|
||||
#print (cursor_orig, bcon['cursor'])
|
||||
|
||||
cursor_base = bcon['cursor']
|
||||
|
||||
autocomp_prefix = bcon['edit_text'][cursor_base:cursor_orig]
|
||||
|
||||
print("PREFIX:'%s'" % autocomp_prefix)
|
||||
|
||||
# Get the previous word
|
||||
if BCon_PrevChar(bcon)=='.':
|
||||
BCon_cursorLeft(bcon)
|
||||
ch = BCon_PrevChar(bcon)
|
||||
while ch != None and is_delimiter_autocomp(ch)==False:
|
||||
ch = BCon_PrevChar(bcon)
|
||||
BCon_cursorLeft(bcon)
|
||||
|
||||
cursor_new = bcon['cursor']
|
||||
|
||||
if ch != None:
|
||||
cursor_new+=1
|
||||
|
||||
pytxt = bcon['edit_text'][cursor_new:cursor_base-1].strip()
|
||||
print("AUTOCOMP EVAL: '%s'" % pytxt)
|
||||
#try:
|
||||
if pytxt:
|
||||
bcon['console'].runsource(TEMP_NAME + '=' + pytxt, '<input>', 'single')
|
||||
# print val
|
||||
else: ##except:
|
||||
val = None
|
||||
|
||||
try:
|
||||
val = bcon['namespace'][TEMP_NAME]
|
||||
del bcon['namespace'][TEMP_NAME]
|
||||
except:
|
||||
val = None
|
||||
|
||||
if val:
|
||||
autocomp_members = dir(val)
|
||||
|
||||
autocomp_prefix_ret, autocomp_members = do_autocomp(autocomp_prefix, autocomp_members)
|
||||
|
||||
bcon['cursor'] = cursor_orig
|
||||
for v in autocomp_prefix_ret:
|
||||
BCon_cursorInsertChar(bcon, v)
|
||||
cursor_orig = bcon['cursor']
|
||||
|
||||
if autocomp_members:
|
||||
BCon_AddScrollback(bcon, ', '.join(autocomp_members))
|
||||
|
||||
del val
|
||||
|
||||
else:
|
||||
# Autocomp global namespace
|
||||
autocomp_members = bcon['namespace'].keys()
|
||||
|
||||
if autocomp_prefix:
|
||||
autocomp_members = [v for v in autocomp_members if v.startswith(autocomp_prefix)]
|
||||
|
||||
autocomp_prefix_ret, autocomp_members = do_autocomp(autocomp_prefix, autocomp_members)
|
||||
|
||||
bcon['cursor'] = cursor_orig
|
||||
for v in autocomp_prefix_ret:
|
||||
BCon_cursorInsertChar(bcon, v)
|
||||
cursor_orig = bcon['cursor']
|
||||
|
||||
if autocomp_members:
|
||||
BCon_AddScrollback(bcon, ', '.join(autocomp_members))
|
||||
|
||||
bcon['cursor'] = cursor_orig
|
72
release/scripts/modules/bpy_ext/Mesh.py
Normal file
72
release/scripts/modules/bpy_ext/Mesh.py
Normal file
@ -0,0 +1,72 @@
|
||||
# ##### 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
def ord_ind(i1,i2):
|
||||
if i1<i2: return i1,i2
|
||||
return i2,i1
|
||||
|
||||
def edge_key(ed):
|
||||
v1, v2 = tuple(ed.verts)
|
||||
return ord_ind(v1, v2)
|
||||
|
||||
def face_edge_keys(face):
|
||||
verts = tuple(face.verts)
|
||||
if len(verts)==3:
|
||||
return ord_ind(verts[0], verts[1]), ord_ind(verts[1], verts[2]), ord_ind(verts[2], verts[0])
|
||||
|
||||
return ord_ind(verts[0], verts[1]), ord_ind(verts[1], verts[2]), ord_ind(verts[2], verts[3]), ord_ind(verts[3], verts[0])
|
||||
|
||||
def mesh_edge_keys(mesh):
|
||||
return [edge_key for face in mesh.faces for edge_key in face.edge_keys()]
|
||||
|
||||
def mesh_edge_face_count_dict(mesh, face_edge_keys=None):
|
||||
|
||||
# Optional speedup
|
||||
if face_edge_keys==None:
|
||||
face_edge_keys = [face.edge_keys() for face in face_list]
|
||||
|
||||
face_edge_count = {}
|
||||
for face_keys in face_edge_keys:
|
||||
for key in face_keys:
|
||||
try:
|
||||
face_edge_count[key] += 1
|
||||
except:
|
||||
face_edge_count[key] = 1
|
||||
|
||||
|
||||
return face_edge_count
|
||||
|
||||
def mesh_edge_face_count(mesh, face_edge_keys=None):
|
||||
edge_face_count_dict = mesh.edge_face_count_dict(face_edge_keys)
|
||||
return [edge_face_count_dict.get(ed.key(), 0) for ed in mesh.edges]
|
||||
|
||||
import bpy
|
||||
|
||||
# * Edge *
|
||||
class_obj = bpy.types.MeshEdge
|
||||
class_obj.key = edge_key
|
||||
|
||||
# * Face *
|
||||
class_obj = bpy.types.MeshFace
|
||||
class_obj.edge_keys = face_edge_keys
|
||||
|
||||
# * Mesh *
|
||||
class_obj = bpy.types.Mesh
|
||||
class_obj.edge_keys = mesh_edge_keys
|
||||
class_obj.edge_face_count = mesh_edge_face_count
|
||||
class_obj.edge_face_count_dict = mesh_edge_face_count_dict
|
22
release/scripts/modules/bpy_ext/Object.py
Normal file
22
release/scripts/modules/bpy_ext/Object.py
Normal file
@ -0,0 +1,22 @@
|
||||
# ##### 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
import bpy
|
||||
class_obj = bpy.types.Object
|
||||
|
||||
class_obj.getChildren = lambda self: [child for child in bpy.data.objects if child.parent == self]
|
20
release/scripts/modules/bpy_ext/__init__.py
Normal file
20
release/scripts/modules/bpy_ext/__init__.py
Normal file
@ -0,0 +1,20 @@
|
||||
# ##### 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
import bpy_ext.Object
|
||||
import bpy_ext.Mesh
|
@ -1,3 +1,23 @@
|
||||
# ##### 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
# <pep8-80 compliant>
|
||||
|
||||
# for slightly faster access
|
||||
from bpy.__ops__ import add as op_add
|
||||
from bpy.__ops__ import remove as op_remove
|
||||
@ -18,24 +38,28 @@ context_dict = {
|
||||
'EXEC_SCREEN': 7,
|
||||
}
|
||||
|
||||
|
||||
class bpy_ops(object):
|
||||
'''
|
||||
Fake module like class.
|
||||
|
||||
bpy.ops
|
||||
'''
|
||||
def add(self, pyop):
|
||||
op_add(pyop)
|
||||
|
||||
def remove(self, pyop):
|
||||
op_remove(pyop)
|
||||
|
||||
def __getattr__(self, module):
|
||||
'''
|
||||
gets a bpy.ops submodule
|
||||
'''
|
||||
if module.startswith('__'):
|
||||
raise AttributeError(module)
|
||||
return bpy_ops_submodule(module)
|
||||
|
||||
def add(self, pyop):
|
||||
op_add(pyop)
|
||||
|
||||
def remove(self, pyop):
|
||||
op_remove(pyop)
|
||||
|
||||
def __dir__(self):
|
||||
|
||||
submodules = set()
|
||||
@ -74,6 +98,8 @@ class bpy_ops_submodule(object):
|
||||
'''
|
||||
gets a bpy.ops.submodule function
|
||||
'''
|
||||
if func.startswith('__'):
|
||||
raise AttributeError(func)
|
||||
return bpy_ops_submodule_op(self.module, func)
|
||||
|
||||
def __dir__(self):
|
||||
@ -92,13 +118,22 @@ class bpy_ops_submodule(object):
|
||||
def __repr__(self):
|
||||
return "<module like class 'bpy.ops.%s'>" % self.module
|
||||
|
||||
|
||||
class bpy_ops_submodule_op(object):
|
||||
'''
|
||||
Utility class to fake submodule operators.
|
||||
|
||||
eg. bpy.ops.object.somefunc
|
||||
'''
|
||||
|
||||
__keys__ = ('module', 'func')
|
||||
|
||||
|
||||
def _get_doc(self):
|
||||
return op_as_string(self.idname())
|
||||
|
||||
__doc__ = property(_get_doc)
|
||||
|
||||
def __init__(self, module, func):
|
||||
self.module = module
|
||||
self.func = func
|
||||
@ -110,217 +145,50 @@ class bpy_ops_submodule_op(object):
|
||||
def __call__(self, *args, **kw):
|
||||
|
||||
# Get the operator from blender
|
||||
if len(args) > 1:
|
||||
raise ValueError("only one argument for the execution context is supported ")
|
||||
if len(args) > 2:
|
||||
raise ValueError("1 or 2 args execution context is supported")
|
||||
|
||||
C_dict = None
|
||||
|
||||
if args:
|
||||
try:
|
||||
context = context_dict[args[0]]
|
||||
except:
|
||||
raise ValueError("Expected a single context argument in: " + str(list(context_dict.keys())))
|
||||
|
||||
return op_call(self.idname(), kw, context)
|
||||
C_exec = 'EXEC_DEFAULT'
|
||||
|
||||
if len(args) == 2:
|
||||
C_exec = args[0]
|
||||
C_dict = args[1]
|
||||
else:
|
||||
if type(args[0]) != str:
|
||||
C_dict = args[0]
|
||||
else:
|
||||
C_exec = args[0]
|
||||
|
||||
try:
|
||||
context = context_dict[C_exec]
|
||||
except:
|
||||
raise ValueError("Expected a single context argument in: " + \
|
||||
str(list(context_dict.keys())))
|
||||
|
||||
if len(args) == 2:
|
||||
C_dict = args[1]
|
||||
|
||||
return op_call(self.idname(), C_dict, kw, context)
|
||||
|
||||
else:
|
||||
return op_call(self.idname(), kw)
|
||||
return op_call(self.idname(), C_dict, kw)
|
||||
|
||||
def get_rna(self):
|
||||
'''
|
||||
currently only used for '__rna__'
|
||||
currently only used for 'bl_rna'
|
||||
'''
|
||||
return op_get_rna(self.idname())
|
||||
|
||||
|
||||
def __repr__(self): # useful display, repr(op)
|
||||
return op_as_string(self.idname())
|
||||
|
||||
def __str__(self): # used for print(...)
|
||||
return "<function bpy.ops.%s.%s at 0x%x'>" % (self.module, self.func, id(self))
|
||||
return "<function bpy.ops.%s.%s at 0x%x'>" % \
|
||||
(self.module, self.func, id(self))
|
||||
|
||||
import bpy
|
||||
bpy.ops = bpy_ops()
|
||||
|
||||
# TODO, C macro's cant define settings :|
|
||||
|
||||
class MESH_OT_delete_edgeloop(bpy.types.Operator):
|
||||
'''Export a single object as a stanford PLY with normals, colours and texture coordinates.'''
|
||||
__idname__ = "mesh.delete_edgeloop"
|
||||
__label__ = "Delete Edge Loop"
|
||||
|
||||
def execute(self, context):
|
||||
bpy.ops.tfm.edge_slide(value=1.0)
|
||||
bpy.ops.mesh.select_more()
|
||||
bpy.ops.mesh.remove_doubles()
|
||||
return ('FINISHED',)
|
||||
|
||||
rna_path_prop = bpy.props.StringProperty(attr="path", name="Context Attributes", description="rna context string", maxlen= 1024, default= "")
|
||||
rna_reverse_prop = bpy.props.BoolProperty(attr="reverse", name="Reverse", description="Cycle backwards", default= False)
|
||||
|
||||
class NullPathMember:
|
||||
pass
|
||||
|
||||
def context_path_validate(context, path):
|
||||
import sys
|
||||
try:
|
||||
value = eval("context.%s" % path)
|
||||
except AttributeError:
|
||||
if "'NoneType'" in str(sys.exc_info()[1]):
|
||||
# One of the items in the rna path is None, just ignore this
|
||||
value = NullPathMember
|
||||
else:
|
||||
# We have a real error in the rna path, dont ignore that
|
||||
raise
|
||||
|
||||
return value
|
||||
|
||||
|
||||
|
||||
def execute_context_assign(self, context):
|
||||
if context_path_validate(context, self.path) == NullPathMember:
|
||||
return ('PASS_THROUGH',)
|
||||
|
||||
exec("context.%s=self.value" % self.path)
|
||||
return ('FINISHED',)
|
||||
|
||||
class WM_OT_context_set_boolean(bpy.types.Operator):
|
||||
'''Set a context value.'''
|
||||
__idname__ = "wm.context_set_boolean"
|
||||
__label__ = "Context Set"
|
||||
__props__ = [rna_path_prop, bpy.props.BoolProperty(attr="value", name="Value", description="Assignment value", default= True)]
|
||||
execute = execute_context_assign
|
||||
|
||||
class WM_OT_context_set_int(bpy.types.Operator): # same as enum
|
||||
'''Set a context value.'''
|
||||
__idname__ = "wm.context_set_int"
|
||||
__label__ = "Context Set"
|
||||
__props__ = [rna_path_prop, bpy.props.IntProperty(attr="value", name="Value", description="Assignment value", default= 0)]
|
||||
execute = execute_context_assign
|
||||
|
||||
class WM_OT_context_set_float(bpy.types.Operator): # same as enum
|
||||
'''Set a context value.'''
|
||||
__idname__ = "wm.context_set_int"
|
||||
__label__ = "Context Set"
|
||||
__props__ = [rna_path_prop, bpy.props.FloatProperty(attr="value", name="Value", description="Assignment value", default= 0.0)]
|
||||
execute = execute_context_assign
|
||||
|
||||
class WM_OT_context_set_string(bpy.types.Operator): # same as enum
|
||||
'''Set a context value.'''
|
||||
__idname__ = "wm.context_set_string"
|
||||
__label__ = "Context Set"
|
||||
__props__ = [rna_path_prop, bpy.props.StringProperty(attr="value", name="Value", description="Assignment value", maxlen= 1024, default= "")]
|
||||
execute = execute_context_assign
|
||||
|
||||
class WM_OT_context_set_enum(bpy.types.Operator):
|
||||
'''Set a context value.'''
|
||||
__idname__ = "wm.context_set_enum"
|
||||
__label__ = "Context Set"
|
||||
__props__ = [rna_path_prop, bpy.props.StringProperty(attr="value", name="Value", description="Assignment value (as a string)", maxlen= 1024, default= "")]
|
||||
execute = execute_context_assign
|
||||
|
||||
class WM_OT_context_toggle(bpy.types.Operator):
|
||||
'''Toggle a context value.'''
|
||||
__idname__ = "wm.context_toggle"
|
||||
__label__ = "Context Toggle"
|
||||
__props__ = [rna_path_prop]
|
||||
def execute(self, context):
|
||||
|
||||
if context_path_validate(context, self.path) == NullPathMember:
|
||||
return ('PASS_THROUGH',)
|
||||
|
||||
exec("context.%s=not (context.%s)" % (self.path, self.path)) # security nuts will complain.
|
||||
return ('FINISHED',)
|
||||
|
||||
class WM_OT_context_toggle_enum(bpy.types.Operator):
|
||||
'''Toggle a context value.'''
|
||||
__idname__ = "wm.context_toggle_enum"
|
||||
__label__ = "Context Toggle Values"
|
||||
__props__ = [
|
||||
rna_path_prop,
|
||||
bpy.props.StringProperty(attr="value_1", name="Value", description="Toggle enum", maxlen= 1024, default= ""),
|
||||
bpy.props.StringProperty(attr="value_2", name="Value", description="Toggle enum", maxlen= 1024, default= "")
|
||||
]
|
||||
def execute(self, context):
|
||||
|
||||
if context_path_validate(context, self.path) == NullPathMember:
|
||||
return ('PASS_THROUGH',)
|
||||
|
||||
exec("context.%s = ['%s', '%s'][context.%s!='%s']" % (self.path, self.value_1, self.value_2, self.path, self.value_2)) # security nuts will complain.
|
||||
return ('FINISHED',)
|
||||
|
||||
class WM_OT_context_cycle_int(bpy.types.Operator):
|
||||
'''Set a context value. Useful for cycling active material, vertex keys, groups' etc.'''
|
||||
__idname__ = "wm.context_cycle_int"
|
||||
__label__ = "Context Int Cycle"
|
||||
__props__ = [rna_path_prop, rna_reverse_prop]
|
||||
def execute(self, context):
|
||||
|
||||
value = context_path_validate(context, self.path)
|
||||
if value == NullPathMember:
|
||||
return ('PASS_THROUGH',)
|
||||
|
||||
self.value = value
|
||||
if self.reverse: self.value -= 1
|
||||
else: self.value += 1
|
||||
execute_context_assign(self, context)
|
||||
|
||||
if self.value != eval("context.%s" % self.path):
|
||||
# relies on rna clamping int's out of the range
|
||||
if self.reverse: self.value = (1<<32)
|
||||
else: self.value = -(1<<32)
|
||||
execute_context_assign(self, context)
|
||||
|
||||
return ('FINISHED',)
|
||||
|
||||
class WM_OT_context_cycle_enum(bpy.types.Operator):
|
||||
'''Toggle a context value.'''
|
||||
__idname__ = "wm.context_cycle_enum"
|
||||
__label__ = "Context Enum Cycle"
|
||||
__props__ = [rna_path_prop, rna_reverse_prop]
|
||||
def execute(self, context):
|
||||
|
||||
value = context_path_validate(context, self.path)
|
||||
if value == NullPathMember:
|
||||
return ('PASS_THROUGH',)
|
||||
|
||||
orig_value = value
|
||||
|
||||
# Have to get rna enum values
|
||||
rna_struct_str, rna_prop_str = self.path.rsplit('.', 1)
|
||||
i = rna_prop_str.find('[')
|
||||
if i != -1: rna_prop_str = rna_prop_str[0:i] # just incse we get "context.foo.bar[0]"
|
||||
|
||||
rna_struct = eval("context.%s.rna_type" % rna_struct_str)
|
||||
|
||||
rna_prop = rna_struct.properties[rna_prop_str]
|
||||
|
||||
if type(rna_prop) != bpy.types.EnumProperty:
|
||||
raise Exception("expected an enum property")
|
||||
|
||||
enums = rna_struct.properties[rna_prop_str].items.keys()
|
||||
orig_index = enums.index(orig_value)
|
||||
|
||||
# Have the info we need, advance to the next item
|
||||
if self.reverse:
|
||||
if orig_index==0: advance_enum = enums[-1]
|
||||
else: advance_enum = enums[orig_index-1]
|
||||
else:
|
||||
if orig_index==len(enums)-1: advance_enum = enums[0]
|
||||
else: advance_enum = enums[orig_index+1]
|
||||
|
||||
# set the new value
|
||||
exec("context.%s=advance_enum" % self.path)
|
||||
return ('FINISHED',)
|
||||
|
||||
|
||||
bpy.ops.add(MESH_OT_delete_edgeloop)
|
||||
|
||||
bpy.ops.add(WM_OT_context_set_boolean)
|
||||
bpy.ops.add(WM_OT_context_set_int)
|
||||
bpy.ops.add(WM_OT_context_set_float)
|
||||
bpy.ops.add(WM_OT_context_set_string)
|
||||
bpy.ops.add(WM_OT_context_set_enum)
|
||||
bpy.ops.add(WM_OT_context_toggle)
|
||||
bpy.ops.add(WM_OT_context_toggle_enum)
|
||||
bpy.ops.add(WM_OT_context_cycle_enum)
|
||||
bpy.ops.add(WM_OT_context_cycle_int)
|
||||
|
||||
|
@ -1,12 +0,0 @@
|
||||
import bpy
|
||||
import os
|
||||
|
||||
def expandpath(path):
|
||||
if path.startswith("//"):
|
||||
return os.path.join(os.path.dirname(bpy.data.filename), path[2:])
|
||||
|
||||
return path
|
||||
|
||||
import types
|
||||
bpy.sys = types.ModuleType("bpy.sys")
|
||||
bpy.sys.expandpath = expandpath
|
30
release/scripts/modules/bpy_utils.py
Normal file
30
release/scripts/modules/bpy_utils.py
Normal file
@ -0,0 +1,30 @@
|
||||
# ##### 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
import bpy
|
||||
import os
|
||||
|
||||
def expandpath(path):
|
||||
if path.startswith("//"):
|
||||
return os.path.join(os.path.dirname(bpy.data.filename), path[2:])
|
||||
|
||||
return path
|
||||
|
||||
import types
|
||||
bpy.utils = types.ModuleType("bpy.utils")
|
||||
bpy.utils.expandpath = expandpath
|
16
release/scripts/modules/console/__init__.py
Normal file
16
release/scripts/modules/console/__init__.py
Normal file
@ -0,0 +1,16 @@
|
||||
# Copyright (c) 2009 www.stani.be (GPL license)
|
||||
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""Package for console specific modules."""
|
180
release/scripts/modules/console/complete_import.py
Normal file
180
release/scripts/modules/console/complete_import.py
Normal file
@ -0,0 +1,180 @@
|
||||
# Copyright (c) 2009 Fernando Perez, www.stani.be (GPL license)
|
||||
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Original copyright (see docstring):
|
||||
#*****************************************************************************
|
||||
# Copyright (C) 2001-2006 Fernando Perez <fperez@colorado.edu>
|
||||
#
|
||||
# Distributed under the terms of the BSD License. The full license is in
|
||||
# the file COPYING, distributed as part of this software.
|
||||
#*****************************************************************************
|
||||
|
||||
"""Completer for import statements
|
||||
|
||||
Original code was from IPython/Extensions/ipy_completers.py. The following
|
||||
changes have been made:
|
||||
- ported to python3
|
||||
- pep8 polishing
|
||||
- limit list of modules to prefix in case of "from w"
|
||||
- sorted modules
|
||||
- added sphinx documentation
|
||||
"""
|
||||
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
TIMEOUT_STORAGE = 3 # Time in secs after which the rootmodules will be stored
|
||||
TIMEOUT_GIVEUP = 20 # Time in secs after which we give up
|
||||
|
||||
ROOT_MODULES = None
|
||||
|
||||
|
||||
def get_root_modules():
|
||||
"""
|
||||
Returns a list containing the names of all the modules available in the
|
||||
folders of the pythonpath.
|
||||
|
||||
:returns: modules
|
||||
:rtype: list
|
||||
"""
|
||||
global ROOT_MODULES
|
||||
modules = []
|
||||
if not(ROOT_MODULES is None):
|
||||
return ROOT_MODULES
|
||||
from time import time
|
||||
t = time()
|
||||
store = False
|
||||
for path in sys.path:
|
||||
modules += module_list(path)
|
||||
if time() - t >= TIMEOUT_STORAGE and not store:
|
||||
# Caching the list of root modules, please wait!
|
||||
store = True
|
||||
if time() - t > TIMEOUT_GIVEUP:
|
||||
# This is taking too long, we give up.
|
||||
ROOT_MODULES = []
|
||||
return []
|
||||
|
||||
modules += sys.builtin_module_names
|
||||
|
||||
modules = list(set(modules))
|
||||
if '__init__' in modules:
|
||||
modules.remove('__init__')
|
||||
modules = sorted(set(modules))
|
||||
if store:
|
||||
ROOT_MODULES = modules
|
||||
return modules
|
||||
|
||||
|
||||
def module_list(path):
|
||||
"""
|
||||
Return the list containing the names of the modules available in
|
||||
the given folder.
|
||||
|
||||
:param path: folder path
|
||||
:type path: str
|
||||
:returns: modules
|
||||
:rtype: list
|
||||
"""
|
||||
|
||||
if os.path.isdir(path):
|
||||
folder_list = os.listdir(path)
|
||||
elif path.endswith('.egg'):
|
||||
from zipimport import zipimporter
|
||||
try:
|
||||
folder_list = [f for f in zipimporter(path)._files]
|
||||
except:
|
||||
folder_list = []
|
||||
else:
|
||||
folder_list = []
|
||||
#folder_list = glob.glob(os.path.join(path,'*'))
|
||||
folder_list = [p for p in folder_list \
|
||||
if os.path.exists(os.path.join(path, p, '__init__.py'))\
|
||||
or p[-3:] in ('.py', '.so')\
|
||||
or p[-4:] in ('.pyc', '.pyo', '.pyd')]
|
||||
|
||||
folder_list = [os.path.basename(p).split('.')[0] for p in folder_list]
|
||||
return folder_list
|
||||
|
||||
|
||||
def complete(line):
|
||||
"""
|
||||
Returns a list containing the completion possibilities for an import line.
|
||||
|
||||
:param line:
|
||||
|
||||
incomplete line which contains an import statement::
|
||||
|
||||
import xml.d
|
||||
from xml.dom import
|
||||
|
||||
:type line: str
|
||||
:returns: list of completion possibilities
|
||||
:rtype: list
|
||||
|
||||
>>> complete('import weak')
|
||||
['weakref']
|
||||
>>> complete('from weakref import C')
|
||||
['CallableProxyType']
|
||||
"""
|
||||
import inspect
|
||||
|
||||
def try_import(mod, only_modules=False):
|
||||
|
||||
def is_importable(module, attr):
|
||||
if only_modules:
|
||||
return inspect.ismodule(getattr(module, attr))
|
||||
else:
|
||||
return not(attr[:2] == '__' and attr[-2:] == '__')
|
||||
|
||||
try:
|
||||
m = __import__(mod)
|
||||
except:
|
||||
return []
|
||||
mods = mod.split('.')
|
||||
for module in mods[1:]:
|
||||
m = getattr(m, module)
|
||||
if (not hasattr(m, '__file__')) or (not only_modules) or\
|
||||
(hasattr(m, '__file__') and '__init__' in m.__file__):
|
||||
completion_list = [attr for attr in dir(m)
|
||||
if is_importable(m, attr)]
|
||||
else:
|
||||
completion_list = []
|
||||
completion_list.extend(getattr(m, '__all__', []))
|
||||
if hasattr(m, '__file__') and '__init__' in m.__file__:
|
||||
completion_list.extend(module_list(os.path.dirname(m.__file__)))
|
||||
completion_list = list(set(completion_list))
|
||||
if '__init__' in completion_list:
|
||||
completion_list.remove('__init__')
|
||||
return completion_list
|
||||
|
||||
def filter_prefix(names, prefix):
|
||||
return [name for name in names if name.startswith(prefix)]
|
||||
|
||||
words = line.split(' ')
|
||||
if len(words) == 3 and words[0] == 'from':
|
||||
return ['import ']
|
||||
if len(words) < 3 and (words[0] in ['import', 'from']):
|
||||
if len(words) == 1:
|
||||
return get_root_modules()
|
||||
mod = words[1].split('.')
|
||||
if len(mod) < 2:
|
||||
return filter_prefix(get_root_modules(), words[-1])
|
||||
completion_list = try_import('.'.join(mod[:-1]), True)
|
||||
completion_list = ['.'.join(mod[:-1] + [el]) for el in completion_list]
|
||||
return filter_prefix(completion_list, words[-1])
|
||||
if len(words) >= 3 and words[0] == 'from':
|
||||
mod = words[1]
|
||||
return filter_prefix(try_import(mod), words[-1])
|
186
release/scripts/modules/console/complete_namespace.py
Normal file
186
release/scripts/modules/console/complete_namespace.py
Normal file
@ -0,0 +1,186 @@
|
||||
# Copyright (c) 2009 www.stani.be (GPL license)
|
||||
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""Autocomplete with the standard library"""
|
||||
|
||||
import re
|
||||
import rlcompleter
|
||||
|
||||
|
||||
RE_INCOMPLETE_INDEX = re.compile('(.*?)\[[^\]]+$')
|
||||
|
||||
TEMP = '__tEmP__' # only \w characters are allowed!
|
||||
TEMP_N = len(TEMP)
|
||||
|
||||
|
||||
def is_dict(obj):
|
||||
"""Returns whether obj is a dictionary"""
|
||||
return hasattr(obj, 'keys') and hasattr(getattr(obj, 'keys'), '__call__')
|
||||
|
||||
|
||||
def complete_names(word, namespace):
|
||||
"""Complete variable names or attributes
|
||||
|
||||
:param word: word to be completed
|
||||
:type word: str
|
||||
:param namespace: namespace
|
||||
:type namespace: dict
|
||||
:returns: completion matches
|
||||
:rtype: list of str
|
||||
|
||||
>>> complete_names('fo', {'foo': 'bar'})
|
||||
['foo', 'for', 'format(']
|
||||
"""
|
||||
# start completer
|
||||
completer = rlcompleter.Completer(namespace)
|
||||
# find matches with std library (don't try to implement this yourself)
|
||||
completer.complete(word, 0)
|
||||
return sorted(set(completer.matches))
|
||||
|
||||
|
||||
def complete_indices(word, namespace, obj=None, base=None):
|
||||
"""Complete a list or dictionary with its indices:
|
||||
|
||||
* integer numbers for list
|
||||
* any keys for dictionary
|
||||
|
||||
:param word: word to be completed
|
||||
:type word: str
|
||||
:param namespace: namespace
|
||||
:type namespace: dict
|
||||
:param obj: object evaluated from base
|
||||
:param base: substring which can be evaluated into an object
|
||||
:type base: str
|
||||
:returns: completion matches
|
||||
:rtype: list of str
|
||||
|
||||
>>> complete_indices('foo', {'foo': range(5)})
|
||||
['foo[0]', 'foo[1]', 'foo[2]', 'foo[3]', 'foo[4]']
|
||||
>>> complete_indices('foo', {'foo': {'bar':0, 1:2}})
|
||||
['foo[1]', "foo['bar']"]
|
||||
>>> complete_indices("foo['b", {'foo': {'bar':0, 1:2}}, base='foo')
|
||||
["foo['bar']"]
|
||||
"""
|
||||
#FIXME: 'foo["b'
|
||||
if base is None:
|
||||
base = word
|
||||
if obj is None:
|
||||
try:
|
||||
obj = eval(base, namespace)
|
||||
except Exception:
|
||||
return []
|
||||
if not hasattr(obj, '__getitem__'):
|
||||
# obj is not a list or dictionary
|
||||
return []
|
||||
if is_dict(obj):
|
||||
# dictionary type
|
||||
matches = ['%s[%r]' % (base, key) for key in sorted(obj.keys())]
|
||||
else:
|
||||
# list type
|
||||
matches = ['%s[%d]' % (base, idx) for idx in range(len(obj))]
|
||||
if word != base:
|
||||
matches = [match for match in matches if match.startswith(word)]
|
||||
return matches
|
||||
|
||||
|
||||
def complete(word, namespace, private=True):
|
||||
"""Complete word within a namespace with the standard rlcompleter
|
||||
module. Also supports index or key access [].
|
||||
|
||||
:param word: word to be completed
|
||||
:type word: str
|
||||
:param namespace: namespace
|
||||
:type namespace: dict
|
||||
:param private: whether private attribute/methods should be returned
|
||||
:type private: bool
|
||||
:returns: completion matches
|
||||
:rtype: list of str
|
||||
|
||||
>>> complete('foo[1', {'foo': range(14)})
|
||||
['foo[1]', 'foo[10]', 'foo[11]', 'foo[12]', 'foo[13]']
|
||||
>>> complete('foo[0]', {'foo': [range(5)]})
|
||||
['foo[0][0]', 'foo[0][1]', 'foo[0][2]', 'foo[0][3]', 'foo[0][4]']
|
||||
>>> complete('foo[0].i', {'foo': [range(5)]})
|
||||
['foo[0].index(', 'foo[0].insert(']
|
||||
>>> complete('rlcompleter', {'rlcompleter': rlcompleter})
|
||||
['rlcompleter.']
|
||||
"""
|
||||
#
|
||||
# if word is empty -> nothing to complete
|
||||
if not word:
|
||||
return []
|
||||
|
||||
re_incomplete_index = RE_INCOMPLETE_INDEX.search(word)
|
||||
if re_incomplete_index:
|
||||
# ignore incomplete index at the end, e.g 'a[1' -> 'a'
|
||||
matches = complete_indices(word, namespace,
|
||||
base=re_incomplete_index.group(1))
|
||||
|
||||
elif not('[' in word):
|
||||
matches = complete_names(word, namespace)
|
||||
|
||||
elif word[-1] == ']':
|
||||
matches = [word]
|
||||
|
||||
elif '.' in word:
|
||||
# brackets are normally not allowed -> work around
|
||||
|
||||
# remove brackets by using a temp var without brackets
|
||||
obj, attr = word.rsplit('.', 1)
|
||||
try:
|
||||
# do not run the obj expression in the console
|
||||
namespace[TEMP] = eval(obj, namespace)
|
||||
except Exception:
|
||||
return []
|
||||
matches = complete_names(TEMP + '.' + attr, namespace)
|
||||
matches = [obj + match[TEMP_N:] for match in matches]
|
||||
del namespace[TEMP]
|
||||
|
||||
else:
|
||||
# safety net, but when would this occur?
|
||||
return []
|
||||
|
||||
if not matches:
|
||||
return []
|
||||
|
||||
# add '.', '(' or '[' if no match has been found
|
||||
elif len(matches) == 1 and matches[0] == word:
|
||||
|
||||
# try to retrieve the object
|
||||
try:
|
||||
obj = eval(word, namespace)
|
||||
except Exception:
|
||||
return []
|
||||
# ignore basic types
|
||||
if type(obj) in (bool, float, int, str):
|
||||
return []
|
||||
# an extra char '[', '(' or '.' will be added
|
||||
if hasattr(obj, '__getitem__'):
|
||||
# list or dictionary
|
||||
matches = complete_indices(word, namespace, obj)
|
||||
elif hasattr(obj, '__call__'):
|
||||
# callables
|
||||
matches = [word + '(']
|
||||
else:
|
||||
# any other type
|
||||
matches = [word + '.']
|
||||
|
||||
# separate public from private
|
||||
public_matches = [match for match in matches if not('._' in match)]
|
||||
if private:
|
||||
private_matches = [match for match in matches if '._' in match]
|
||||
return public_matches + private_matches
|
||||
else:
|
||||
return public_matches
|
130
release/scripts/modules/console/intellisense.py
Normal file
130
release/scripts/modules/console/intellisense.py
Normal file
@ -0,0 +1,130 @@
|
||||
# Copyright (c) 2009 www.stani.be (GPL license)
|
||||
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""This module provides intellisense features such as:
|
||||
|
||||
* autocompletion
|
||||
* calltips
|
||||
|
||||
It unifies all completion plugins and only loads them on demand.
|
||||
"""
|
||||
|
||||
# TODO: file complete if startswith quotes
|
||||
import os
|
||||
import re
|
||||
|
||||
# regular expressions to find out which completer we need
|
||||
|
||||
# line which starts with an import statement
|
||||
RE_MODULE = re.compile('^import|from.+')
|
||||
|
||||
# The following regular expression means an 'unquoted' word
|
||||
RE_UNQUOTED_WORD = re.compile(
|
||||
# don't start with a quote
|
||||
'''(?:^|[^"'a-zA-Z0-9_])'''
|
||||
# start with a \w = [a-zA-Z0-9_]
|
||||
'''((?:\w+'''
|
||||
# allow also dots and closed bracket pairs []
|
||||
'''(?:\w|[.]|\[.+?\])*'''
|
||||
# allow empty string
|
||||
'''|)'''
|
||||
# allow an unfinished index at the end (including quotes)
|
||||
'''(?:\[[^\]]*$)?)$''',
|
||||
# allow unicode as theoretically this is possible
|
||||
re.UNICODE)
|
||||
|
||||
|
||||
def complete(line, cursor, namespace, private=True):
|
||||
"""Returns a list of possible completions:
|
||||
|
||||
* name completion
|
||||
* attribute completion (obj.attr)
|
||||
* index completion for lists and dictionaries
|
||||
* module completion (from/import)
|
||||
|
||||
:param line: incomplete text line
|
||||
:type line: str
|
||||
:param cursor: current character position
|
||||
:type cursor: int
|
||||
:param namespace: namespace
|
||||
:type namespace: dict
|
||||
:param private: whether private variables should be listed
|
||||
:type private: bool
|
||||
:returns: list of completions, word
|
||||
:rtype: list, str
|
||||
|
||||
>>> complete('re.sr', 5, {'re': re})
|
||||
(['re.sre_compile', 're.sre_parse'], 're.sr')
|
||||
"""
|
||||
re_unquoted_word = RE_UNQUOTED_WORD.search(line[:cursor])
|
||||
if re_unquoted_word:
|
||||
# unquoted word -> module or attribute completion
|
||||
word = re_unquoted_word.group(1)
|
||||
if RE_MODULE.match(line):
|
||||
import complete_import
|
||||
matches = complete_import.complete(line)
|
||||
else:
|
||||
import complete_namespace
|
||||
matches = complete_namespace.complete(word, namespace, private)
|
||||
else:
|
||||
# for now we don't have completers for strings
|
||||
# TODO: add file auto completer for strings
|
||||
word = ''
|
||||
matches = []
|
||||
return matches, word
|
||||
|
||||
|
||||
def expand(line, cursor, namespace, private=True):
|
||||
"""This method is invoked when the user asks autocompletion,
|
||||
e.g. when Ctrl+Space is clicked.
|
||||
|
||||
:param line: incomplete text line
|
||||
:type line: str
|
||||
:param cursor: current character position
|
||||
:type cursor: int
|
||||
:param namespace: namespace
|
||||
:type namespace: dict
|
||||
:param private: whether private variables should be listed
|
||||
:type private: bool
|
||||
:returns:
|
||||
|
||||
current expanded line, updated cursor position and scrollback
|
||||
|
||||
:rtype: str, int, str
|
||||
|
||||
>>> expand('os.path.isdir(', 14, {'os': os})[-1]
|
||||
'isdir(s)\\nReturn true if the pathname refers to an existing directory.'
|
||||
>>> expand('abs(', 4, {})[-1]
|
||||
'abs(number) -> number\\nReturn the absolute value of the argument.'
|
||||
"""
|
||||
if line[:cursor].strip().endswith('('):
|
||||
import complete_calltip
|
||||
matches, word, scrollback = complete_calltip.complete(line,
|
||||
cursor, namespace)
|
||||
no_calltip = False
|
||||
else:
|
||||
matches, word = complete(line, cursor, namespace, private)
|
||||
if len(matches) == 1:
|
||||
scrollback = ''
|
||||
else:
|
||||
scrollback = ' '.join([m.split('.')[-1] for m in matches])
|
||||
no_calltip = True
|
||||
prefix = os.path.commonprefix(matches)[len(word):]
|
||||
if prefix:
|
||||
line = line[:cursor] + prefix + line[cursor:]
|
||||
cursor += len(prefix)
|
||||
if no_calltip and prefix.endswith('('):
|
||||
return expand(line, cursor, namespace, private)
|
||||
return line, cursor, scrollback
|
@ -1,3 +1,21 @@
|
||||
# ##### 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
import bpy
|
||||
|
||||
def collect_baseclasses(_class, bases):
|
||||
|
139
release/scripts/op/add_mesh_torus.py
Normal file
139
release/scripts/op/add_mesh_torus.py
Normal file
@ -0,0 +1,139 @@
|
||||
# ##### 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
# <pep8-80 compliant>
|
||||
import bpy
|
||||
import Mathutils
|
||||
from math import cos, sin, pi
|
||||
|
||||
|
||||
def add_torus(major_rad, minor_rad, major_seg, minor_seg):
|
||||
Vector = Mathutils.Vector
|
||||
Quaternion = Mathutils.Quaternion
|
||||
|
||||
PI_2 = pi * 2
|
||||
z_axis = (0, 0, 1)
|
||||
|
||||
verts = []
|
||||
faces = []
|
||||
i1 = 0
|
||||
tot_verts = major_seg * minor_seg
|
||||
for major_index in range(major_seg):
|
||||
quat = Quaternion(z_axis, (major_index / major_seg) * PI_2)
|
||||
|
||||
for minor_index in range(minor_seg):
|
||||
angle = 2 * pi * minor_index / minor_seg
|
||||
|
||||
vec = Vector(major_rad + (cos(angle) * minor_rad), 0.0,
|
||||
(sin(angle) * minor_rad)) * quat
|
||||
|
||||
verts.extend([vec.x, vec.y, vec.z])
|
||||
|
||||
if minor_index + 1 == minor_seg:
|
||||
i2 = (major_index) * minor_seg
|
||||
i3 = i1 + minor_seg
|
||||
i4 = i2 + minor_seg
|
||||
|
||||
else:
|
||||
i2 = i1 + 1
|
||||
i3 = i1 + minor_seg
|
||||
i4 = i3 + 1
|
||||
|
||||
if i2 >= tot_verts:
|
||||
i2 = i2 - tot_verts
|
||||
if i3 >= tot_verts:
|
||||
i3 = i3 - tot_verts
|
||||
if i4 >= tot_verts:
|
||||
i4 = i4 - tot_verts
|
||||
|
||||
# stupid eekadoodle
|
||||
if i2:
|
||||
faces.extend([i1, i3, i4, i2])
|
||||
else:
|
||||
faces.extend([i2, i1, i3, i4])
|
||||
|
||||
i1 += 1
|
||||
|
||||
return verts, faces
|
||||
|
||||
from bpy.props import *
|
||||
|
||||
|
||||
class AddTorus(bpy.types.Operator):
|
||||
'''Add a torus mesh.'''
|
||||
bl_idname = "mesh.primitive_torus_add"
|
||||
bl_label = "Add Torus"
|
||||
bl_register = True
|
||||
bl_undo = True
|
||||
|
||||
major_radius = FloatProperty(name="Major Radius",
|
||||
description="Number of segments for the main ring of the torus",
|
||||
default=1.0, min=0.01, max=100.0)
|
||||
minor_radius = FloatProperty(name="Minor Radius",
|
||||
description="Number of segments for the minor ring of the torus",
|
||||
default=0.25, min=0.01, max=100.0)
|
||||
major_segments = IntProperty(name="Major Segments",
|
||||
description="Number of segments for the main ring of the torus",
|
||||
default=48, min=3, max=256)
|
||||
minor_segments = IntProperty(name="Minor Segments",
|
||||
description="Number of segments for the minor ring of the torus",
|
||||
default=16, min=3, max=256)
|
||||
|
||||
def execute(self, context):
|
||||
|
||||
verts_loc, faces = add_torus(self.major_radius,
|
||||
self.minor_radius,
|
||||
self.major_segments,
|
||||
self.minor_segments)
|
||||
|
||||
mesh = bpy.data.add_mesh("Torus")
|
||||
|
||||
mesh.add_geometry(int(len(verts_loc) / 3), 0, int(len(faces) / 4))
|
||||
mesh.verts.foreach_set("co", verts_loc)
|
||||
mesh.faces.foreach_set("verts_raw", faces)
|
||||
|
||||
scene = context.scene
|
||||
|
||||
# ugh
|
||||
for ob in scene.objects:
|
||||
ob.selected = False
|
||||
|
||||
mesh.update()
|
||||
ob_new = bpy.data.add_object('MESH', "Torus")
|
||||
ob_new.data = mesh
|
||||
scene.add_object(ob_new)
|
||||
scene.objects.active = ob_new
|
||||
ob_new.selected = True
|
||||
|
||||
ob_new.location = tuple(context.scene.cursor_location)
|
||||
|
||||
return ('FINISHED',)
|
||||
|
||||
# Register the operator
|
||||
bpy.ops.add(AddTorus)
|
||||
|
||||
# Add to a menu
|
||||
import dynamic_menu
|
||||
|
||||
menu_func = (lambda self, context: self.layout.itemO(AddTorus.bl_idname,
|
||||
text="Torus", icon='ICON_MESH_DONUT'))
|
||||
|
||||
menu_item = dynamic_menu.add(bpy.types.INFO_MT_mesh_add, menu_func)
|
||||
|
||||
if __name__ == "__main__":
|
||||
bpy.ops.mesh.primitive_torus_add()
|
71
release/scripts/op/mesh.py
Normal file
71
release/scripts/op/mesh.py
Normal file
@ -0,0 +1,71 @@
|
||||
# ##### 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
import bpy
|
||||
|
||||
def main(context):
|
||||
ob = context.active_object
|
||||
bpy.ops.mesh.selection_type(type='FACE')
|
||||
is_editmode = (ob.mode=='EDIT')
|
||||
if is_editmode:
|
||||
bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
|
||||
|
||||
mesh = ob.data
|
||||
|
||||
face_list = [face for face in mesh.faces]
|
||||
face_edge_keys = [face.edge_keys() for face in face_list]
|
||||
|
||||
edge_face_count = mesh.edge_face_count_dict(face_edge_keys)
|
||||
|
||||
def test_interior(index):
|
||||
for key in face_edge_keys[index]:
|
||||
if edge_face_count[key] < 3:
|
||||
return False
|
||||
return True
|
||||
|
||||
for index, face in enumerate(face_list):
|
||||
if(test_interior(index)):
|
||||
face.selected = True
|
||||
else:
|
||||
face.selected = False
|
||||
|
||||
if is_editmode:
|
||||
bpy.ops.object.mode_set(mode='EDIT', toggle=False)
|
||||
|
||||
class MeshSelectInteriorFaces(bpy.types.Operator):
|
||||
'''Select faces where all edges have more then 2 face users.'''
|
||||
|
||||
bl_idname = "mesh.faces_select_interior"
|
||||
bl_label = "Select Interior Faces"
|
||||
bl_register = True
|
||||
bl_undo = True
|
||||
|
||||
def poll(self, context):
|
||||
ob = context.active_object
|
||||
return (ob and ob.type == 'MESH')
|
||||
|
||||
def execute(self, context):
|
||||
main(context)
|
||||
return ('FINISHED',)
|
||||
|
||||
|
||||
# Register the operator
|
||||
bpy.ops.add(MeshSelectInteriorFaces)
|
||||
|
||||
if __name__ == "__main__":
|
||||
bpy.ops.mesh.faces_select_interior()
|
648
release/scripts/op/mesh_skin.py
Normal file
648
release/scripts/op/mesh_skin.py
Normal file
@ -0,0 +1,648 @@
|
||||
# ##### 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
# import Blender
|
||||
import time, functools
|
||||
import bpy
|
||||
# from Blender import Window
|
||||
from Mathutils import MidpointVecs, Vector
|
||||
from Mathutils import AngleBetweenVecs as _AngleBetweenVecs_
|
||||
# import BPyMessages
|
||||
|
||||
# from Blender.Draw import PupMenu
|
||||
|
||||
BIG_NUM = 1<<30
|
||||
|
||||
global CULL_METHOD
|
||||
CULL_METHOD = 0
|
||||
|
||||
def AngleBetweenVecs(a1,a2):
|
||||
import math
|
||||
try:
|
||||
return math.degrees(_AngleBetweenVecs_(a1,a2))
|
||||
except:
|
||||
return 180.0
|
||||
|
||||
class edge(object):
|
||||
__slots__ = 'v1', 'v2', 'co1', 'co2', 'length', 'removed', 'match', 'cent', 'angle', 'next', 'prev', 'normal', 'fake'
|
||||
def __init__(self, v1,v2):
|
||||
self.v1 = v1
|
||||
self.v2 = v2
|
||||
co1, co2= v1.co, v2.co
|
||||
self.co1= co1
|
||||
self.co2= co2
|
||||
|
||||
# uv1 uv2 vcol1 vcol2 # Add later
|
||||
self.length = (co1 - co2).length
|
||||
self.removed = 0 # Have we been culled from the eloop
|
||||
self.match = None # The other edge were making a face with
|
||||
|
||||
self.cent= MidpointVecs(co1, co2)
|
||||
self.angle= 0.0
|
||||
self.fake= False
|
||||
|
||||
class edgeLoop(object):
|
||||
__slots__ = 'centre', 'edges', 'normal', 'closed', 'backup_edges'
|
||||
def __init__(self, loop, me, closed): # Vert loop
|
||||
# Use next and prev, nextDist, prevDist
|
||||
|
||||
# Get Loops centre.
|
||||
fac= len(loop)
|
||||
verts = me.verts
|
||||
self.centre= functools.reduce(lambda a,b: a+verts[b].co/fac, loop, Vector())
|
||||
|
||||
# Convert Vert loop to Edges.
|
||||
self.edges = [edge(verts[loop[vIdx-1]], verts[loop[vIdx]]) for vIdx in range(len(loop))]
|
||||
|
||||
if not closed:
|
||||
self.edges[0].fake = True # fake edge option
|
||||
|
||||
self.closed = closed
|
||||
|
||||
|
||||
# Assign linked list
|
||||
for eIdx in range(len(self.edges)-1):
|
||||
self.edges[eIdx].next = self.edges[eIdx+1]
|
||||
self.edges[eIdx].prev = self.edges[eIdx-1]
|
||||
# Now last
|
||||
self.edges[-1].next = self.edges[0]
|
||||
self.edges[-1].prev = self.edges[-2]
|
||||
|
||||
|
||||
|
||||
# GENERATE AN AVERAGE NORMAL FOR THE WHOLE LOOP.
|
||||
self.normal = Vector()
|
||||
for e in self.edges:
|
||||
n = (self.centre-e.co1).cross(self.centre-e.co2)
|
||||
# Do we realy need tot normalize?
|
||||
n.normalize()
|
||||
self.normal += n
|
||||
|
||||
# Generate the angle
|
||||
va= e.cent - e.prev.cent
|
||||
vb= e.next.cent - e.cent
|
||||
|
||||
e.angle= AngleBetweenVecs(va, vb)
|
||||
|
||||
# Blur the angles
|
||||
#for e in self.edges:
|
||||
# e.angle= (e.angle+e.next.angle)/2
|
||||
|
||||
# Blur the angles
|
||||
#for e in self.edges:
|
||||
# e.angle= (e.angle+e.prev.angle)/2
|
||||
|
||||
self.normal.normalize()
|
||||
|
||||
# Generate a normal for each edge.
|
||||
for e in self.edges:
|
||||
|
||||
n1 = e.co1
|
||||
n2 = e.co2
|
||||
n3 = e.prev.co1
|
||||
|
||||
a = n1-n2
|
||||
b = n1-n3
|
||||
normal1 = a.cross(b)
|
||||
normal1.normalize()
|
||||
|
||||
n1 = e.co2
|
||||
n3 = e.next.co2
|
||||
n2 = e.co1
|
||||
|
||||
a = n1-n2
|
||||
b = n1-n3
|
||||
|
||||
normal2 = a.cross(b)
|
||||
normal2.normalize()
|
||||
|
||||
# Reuse normal1 var
|
||||
normal1 += normal1 + normal2
|
||||
normal1.normalize()
|
||||
|
||||
e.normal = normal1
|
||||
#print e.normal
|
||||
|
||||
|
||||
|
||||
def backup(self):
|
||||
# Keep a backup of the edges
|
||||
self.backup_edges = self.edges[:]
|
||||
|
||||
def restore(self):
|
||||
self.edges = self.backup_edges[:]
|
||||
for e in self.edges:
|
||||
e.removed = 0
|
||||
|
||||
def reverse(self):
|
||||
self.edges.reverse()
|
||||
self.normal.negate()
|
||||
|
||||
for e in self.edges:
|
||||
e.normal.negate()
|
||||
e.v1, e.v2 = e.v2, e.v1
|
||||
e.co1, e.co2 = e.co2, e.co1
|
||||
e.next, e.prev = e.prev, e.next
|
||||
|
||||
|
||||
def removeSmallest(self, cullNum, otherLoopLen):
|
||||
'''
|
||||
Removes N Smallest edges and backs up the loop,
|
||||
this is so we can loop between 2 loops as if they are the same length,
|
||||
backing up and restoring incase the loop needs to be skinned with another loop of a different length.
|
||||
'''
|
||||
global CULL_METHOD
|
||||
if CULL_METHOD == 1: # Shortest edge
|
||||
eloopCopy = self.edges[:]
|
||||
|
||||
# Length sort, smallest first
|
||||
try: eloopCopy.sort(key = lambda e1: e1.length)
|
||||
except: eloopCopy.sort(lambda e1, e2: cmp(e1.length, e2.length ))
|
||||
|
||||
# Dont use atm
|
||||
#eloopCopy.sort(lambda e1, e2: cmp(e1.angle*e1.length, e2.angle*e2.length)) # Length sort, smallest first
|
||||
#eloopCopy.sort(lambda e1, e2: cmp(e1.angle, e2.angle)) # Length sort, smallest first
|
||||
|
||||
remNum = 0
|
||||
for i, e in enumerate(eloopCopy):
|
||||
if not e.fake:
|
||||
e.removed = 1
|
||||
self.edges.remove( e ) # Remove from own list, still in linked list.
|
||||
remNum += 1
|
||||
|
||||
if not remNum < cullNum:
|
||||
break
|
||||
|
||||
else: # CULL METHOD is even
|
||||
|
||||
culled = 0
|
||||
|
||||
step = int(otherLoopLen / float(cullNum)) * 2
|
||||
|
||||
currentEdge = self.edges[0]
|
||||
while culled < cullNum:
|
||||
|
||||
# Get the shortest face in the next STEP
|
||||
step_count= 0
|
||||
bestAng= 360.0
|
||||
smallestEdge= None
|
||||
while step_count<=step or smallestEdge==None:
|
||||
step_count+=1
|
||||
if not currentEdge.removed: # 0 or -1 will not be accepted
|
||||
if currentEdge.angle<bestAng and not currentEdge.fake:
|
||||
smallestEdge= currentEdge
|
||||
bestAng= currentEdge.angle
|
||||
|
||||
currentEdge = currentEdge.next
|
||||
|
||||
# In that stepping length we have the smallest edge.remove it
|
||||
smallestEdge.removed = 1
|
||||
self.edges.remove(smallestEdge)
|
||||
|
||||
# Start scanning from the edge we found? - result is over fanning- no good.
|
||||
#currentEdge= smallestEdge.next
|
||||
|
||||
culled+=1
|
||||
|
||||
|
||||
# Returns face edges.
|
||||
# face must have edge data.
|
||||
|
||||
def mesh_faces_extend(me, faces, mat_idx = 0):
|
||||
orig_facetot = len(me.faces)
|
||||
new_facetot = len(faces)
|
||||
me.add_geometry(0, 0, new_facetot)
|
||||
tot = orig_facetot+new_facetot
|
||||
me_faces = me.faces
|
||||
i= 0
|
||||
while i < new_facetot:
|
||||
|
||||
f = [v.index for v in faces[i]]
|
||||
if len(f)==4 and f[3]==0:
|
||||
f = f[1], f[2], f[3], f[0]
|
||||
|
||||
mf = me_faces[orig_facetot+i]
|
||||
mf.verts_raw = f
|
||||
mf.material_index = mat_idx
|
||||
i+=1
|
||||
# end utils
|
||||
|
||||
|
||||
def getSelectedEdges(context, me, ob):
|
||||
MESH_MODE= context.scene.tool_settings.mesh_selection_mode
|
||||
|
||||
if MESH_MODE in ('EDGE', 'VERTEX'):
|
||||
context.scene.tool_settings.mesh_selection_mode = 'EDGE'
|
||||
edges= [ ed for ed in me.edges if ed.selected ]
|
||||
# print len(edges), len(me.edges)
|
||||
context.scene.tool_settings.mesh_selection_mode = MESH_MODE
|
||||
return edges
|
||||
|
||||
if MESH_MODE == 'FACE':
|
||||
context.scene.tool_settings.mesh_selection_mode = 'EDGE'
|
||||
# value is [edge, face_sel_user_in]
|
||||
edge_dict= dict((ed.key(), [ed, 0]) for ed in me.edges)
|
||||
|
||||
for f in me.faces:
|
||||
if f.selected:
|
||||
for edkey in f.edge_keys():
|
||||
edge_dict[edkey][1] += 1
|
||||
|
||||
context.scene.tool_settings.mesh_selection_mode = MESH_MODE
|
||||
return [ ed_data[0] for ed_data in edge_dict.values() if ed_data[1] == 1 ]
|
||||
|
||||
|
||||
|
||||
def getVertLoops(selEdges, me):
|
||||
'''
|
||||
return a list of vert loops, closed and open [(loop, closed)...]
|
||||
'''
|
||||
|
||||
mainVertLoops = []
|
||||
# second method
|
||||
tot = len(me.verts)
|
||||
vert_siblings = [[] for i in range(tot)]
|
||||
vert_used = [False] * tot
|
||||
|
||||
for ed in selEdges:
|
||||
i1, i2 = ed.key()
|
||||
vert_siblings[i1].append(i2)
|
||||
vert_siblings[i2].append(i1)
|
||||
|
||||
# find the first used vert and keep looping.
|
||||
for i in range(tot):
|
||||
if vert_siblings[i] and not vert_used[i]:
|
||||
sbl = vert_siblings[i] # siblings
|
||||
|
||||
if len(sbl) > 2:
|
||||
return None
|
||||
|
||||
vert_used[i] = True
|
||||
|
||||
# do an edgeloop seek
|
||||
if len(sbl) == 2:
|
||||
contextVertLoop= [sbl[0], i, sbl[1]] # start the vert loop
|
||||
vert_used[contextVertLoop[ 0]] = True
|
||||
vert_used[contextVertLoop[-1]] = True
|
||||
else:
|
||||
contextVertLoop= [i, sbl[0]]
|
||||
vert_used[contextVertLoop[ 1]] = True
|
||||
|
||||
# Always seek up
|
||||
ok = True
|
||||
while ok:
|
||||
ok = False
|
||||
closed = False
|
||||
sbl = vert_siblings[contextVertLoop[-1]]
|
||||
if len(sbl) == 2:
|
||||
next = sbl[not sbl.index( contextVertLoop[-2] )]
|
||||
if vert_used[next]:
|
||||
closed = True
|
||||
# break
|
||||
else:
|
||||
contextVertLoop.append( next ) # get the vert that isnt the second last
|
||||
vert_used[next] = True
|
||||
ok = True
|
||||
|
||||
# Seek down as long as the starting vert was not at the edge.
|
||||
if not closed and len(vert_siblings[i]) == 2:
|
||||
|
||||
ok = True
|
||||
while ok:
|
||||
ok = False
|
||||
sbl = vert_siblings[contextVertLoop[0]]
|
||||
if len(sbl) == 2:
|
||||
next = sbl[not sbl.index( contextVertLoop[1] )]
|
||||
if vert_used[next]:
|
||||
closed = True
|
||||
else:
|
||||
contextVertLoop.insert(0, next) # get the vert that isnt the second last
|
||||
vert_used[next] = True
|
||||
ok = True
|
||||
|
||||
mainVertLoops.append((contextVertLoop, closed))
|
||||
|
||||
|
||||
verts = me.verts
|
||||
# convert from indicies to verts
|
||||
# mainVertLoops = [([verts[i] for i in contextVertLoop], closed) for contextVertLoop, closed in mainVertLoops]
|
||||
# print len(mainVertLoops)
|
||||
return mainVertLoops
|
||||
|
||||
|
||||
|
||||
def skin2EdgeLoops(eloop1, eloop2, me, ob, MODE):
|
||||
|
||||
new_faces= [] #
|
||||
|
||||
# Make sure e1 loops is bigger then e2
|
||||
if len(eloop1.edges) != len(eloop2.edges):
|
||||
if len(eloop1.edges) < len(eloop2.edges):
|
||||
eloop1, eloop2 = eloop2, eloop1
|
||||
|
||||
eloop1.backup() # were about to cull faces
|
||||
CULL_FACES = len(eloop1.edges) - len(eloop2.edges)
|
||||
eloop1.removeSmallest(CULL_FACES, len(eloop1.edges))
|
||||
else:
|
||||
CULL_FACES = 0
|
||||
# First make sure poly vert loops are in sync with eachother.
|
||||
|
||||
# The vector allong which we are skinning.
|
||||
skinVector = eloop1.centre - eloop2.centre
|
||||
|
||||
loopDist = skinVector.length
|
||||
|
||||
# IS THE LOOP FLIPPED, IF SO FLIP BACK. we keep it flipped, its ok,
|
||||
if eloop1.closed or eloop2.closed:
|
||||
angleBetweenLoopNormals = AngleBetweenVecs(eloop1.normal, eloop2.normal)
|
||||
if angleBetweenLoopNormals > 90:
|
||||
eloop2.reverse()
|
||||
|
||||
|
||||
DIR= eloop1.centre - eloop2.centre
|
||||
|
||||
# if eloop2.closed:
|
||||
bestEloopDist = BIG_NUM
|
||||
bestOffset = 0
|
||||
# Loop rotation offset to test.1
|
||||
eLoopIdxs = list(range(len(eloop1.edges)))
|
||||
for offset in range(len(eloop1.edges)):
|
||||
totEloopDist = 0 # Measure this total distance for thsi loop.
|
||||
|
||||
offsetIndexLs = eLoopIdxs[offset:] + eLoopIdxs[:offset] # Make offset index list
|
||||
|
||||
|
||||
# e1Idx is always from 0uu to N, e2Idx is offset.
|
||||
for e1Idx, e2Idx in enumerate(offsetIndexLs):
|
||||
e1= eloop1.edges[e1Idx]
|
||||
e2= eloop2.edges[e2Idx]
|
||||
|
||||
|
||||
# Include fan connections in the measurement.
|
||||
OK= True
|
||||
while OK or e1.removed:
|
||||
OK= False
|
||||
|
||||
# Measure the vloop distance ===============
|
||||
diff= ((e1.cent - e2.cent).length) #/ nangle1
|
||||
|
||||
ed_dir= e1.cent-e2.cent
|
||||
a_diff= AngleBetweenVecs(DIR, ed_dir)/18 # 0 t0 18
|
||||
|
||||
totEloopDist += (diff * (1+a_diff)) / (1+loopDist)
|
||||
|
||||
# Premeture break if where no better off
|
||||
if totEloopDist > bestEloopDist:
|
||||
break
|
||||
|
||||
e1=e1.next
|
||||
|
||||
if totEloopDist < bestEloopDist:
|
||||
bestOffset = offset
|
||||
bestEloopDist = totEloopDist
|
||||
|
||||
# Modify V2 LS for Best offset
|
||||
eloop2.edges = eloop2.edges[bestOffset:] + eloop2.edges[:bestOffset]
|
||||
|
||||
else:
|
||||
# Both are open loops, easier to calculate.
|
||||
|
||||
|
||||
# Make sure the fake edges are at the start.
|
||||
for i, edloop in enumerate((eloop1, eloop2)):
|
||||
# print "LOOPO"
|
||||
if edloop.edges[0].fake:
|
||||
# alredy at the start
|
||||
#print "A"
|
||||
pass
|
||||
elif edloop.edges[-1].fake:
|
||||
# put the end at the start
|
||||
edloop.edges.insert(0, edloop.edges.pop())
|
||||
#print "B"
|
||||
|
||||
else:
|
||||
for j, ed in enumerate(edloop.edges):
|
||||
if ed.fake:
|
||||
#print "C"
|
||||
edloop.edges = edloop.edges = edloop.edges[j:] + edloop.edges[:j]
|
||||
break
|
||||
# print "DONE"
|
||||
ed1, ed2 = eloop1.edges[0], eloop2.edges[0]
|
||||
|
||||
if not ed1.fake or not ed2.fake:
|
||||
raise "Error"
|
||||
|
||||
# Find the join that isnt flipped (juts like detecting a bow-tie face)
|
||||
a1 = (ed1.co1 - ed2.co1).length + (ed1.co2 - ed2.co2).length
|
||||
a2 = (ed1.co1 - ed2.co2).length + (ed1.co2 - ed2.co1).length
|
||||
|
||||
if a1 > a2:
|
||||
eloop2.reverse()
|
||||
# make the first edge the start edge still
|
||||
eloop2.edges.insert(0, eloop2.edges.pop())
|
||||
|
||||
|
||||
|
||||
|
||||
for loopIdx in range(len(eloop2.edges)):
|
||||
e1 = eloop1.edges[loopIdx]
|
||||
e2 = eloop2.edges[loopIdx]
|
||||
|
||||
# Remember the pairs for fan filling culled edges.
|
||||
e1.match = e2; e2.match = e1
|
||||
|
||||
if not (e1.fake or e2.fake):
|
||||
new_faces.append([e1.v1, e1.v2, e2.v2, e2.v1])
|
||||
|
||||
# FAN FILL MISSING FACES.
|
||||
if CULL_FACES:
|
||||
# Culled edges will be in eloop1.
|
||||
FAN_FILLED_FACES = 0
|
||||
|
||||
contextEdge = eloop1.edges[0] # The larger of teh 2
|
||||
while FAN_FILLED_FACES < CULL_FACES:
|
||||
while contextEdge.next.removed == 0:
|
||||
contextEdge = contextEdge.next
|
||||
|
||||
vertFanPivot = contextEdge.match.v2
|
||||
|
||||
while contextEdge.next.removed == 1:
|
||||
#if not contextEdge.next.fake:
|
||||
new_faces.append([contextEdge.next.v1, contextEdge.next.v2, vertFanPivot])
|
||||
|
||||
# Should we use another var?, this will work for now.
|
||||
contextEdge.next.removed = 1
|
||||
|
||||
contextEdge = contextEdge.next
|
||||
FAN_FILLED_FACES += 1
|
||||
|
||||
# may need to fan fill backwards 1 for non closed loops.
|
||||
|
||||
eloop1.restore() # Add culled back into the list.
|
||||
|
||||
return new_faces
|
||||
|
||||
def main(context):
|
||||
global CULL_METHOD
|
||||
|
||||
ob = context.object
|
||||
|
||||
is_editmode = (ob.mode=='EDIT')
|
||||
if is_editmode: bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
|
||||
if ob == None or ob.type != 'MESH':
|
||||
raise Exception("BPyMessages.Error_NoMeshActive()")
|
||||
return
|
||||
|
||||
me = ob.data
|
||||
|
||||
time1 = time.time()
|
||||
selEdges = getSelectedEdges(context, me, ob)
|
||||
vertLoops = getVertLoops(selEdges, me) # list of lists of edges.
|
||||
if vertLoops == None:
|
||||
raise Exception('Error%t|Selection includes verts that are a part of more then 1 loop')
|
||||
if is_editmode: bpy.ops.object.mode_set(mode='EDIT', toggle=False)
|
||||
return
|
||||
# print len(vertLoops)
|
||||
|
||||
|
||||
if len(vertLoops) > 2:
|
||||
choice = PupMenu('Loft '+str(len(vertLoops))+' edge loops%t|loop|segment')
|
||||
if choice == -1:
|
||||
if is_editmode: bpy.ops.object.mode_set(mode='EDIT', toggle=False)
|
||||
return
|
||||
|
||||
elif len(vertLoops) < 2:
|
||||
raise Exception('Error%t|No Vertloops found!')
|
||||
if is_editmode: bpy.ops.object.mode_set(mode='EDIT', toggle=False)
|
||||
return
|
||||
else:
|
||||
choice = 2
|
||||
|
||||
|
||||
# The line below checks if any of the vert loops are differenyt in length.
|
||||
if False in [len(v[0]) == len(vertLoops[0][0]) for v in vertLoops]:
|
||||
CULL_METHOD = PupMenu('Small to large edge loop distrobution method%t|remove edges evenly|remove smallest edges')
|
||||
if CULL_METHOD == -1:
|
||||
if is_editmode: Window.EditMode(1)
|
||||
return
|
||||
|
||||
if CULL_METHOD ==1: # RESET CULL_METHOD
|
||||
CULL_METHOD = 0 # shortest
|
||||
else:
|
||||
CULL_METHOD = 1 # even
|
||||
|
||||
|
||||
time1 = time.time()
|
||||
# Convert to special edge data.
|
||||
edgeLoops = []
|
||||
for vloop, closed in vertLoops:
|
||||
edgeLoops.append(edgeLoop(vloop, me, closed))
|
||||
|
||||
|
||||
# VERT LOOP ORDERING CODE
|
||||
# "Build a worm" list - grow from Both ends
|
||||
edgeOrderedList = [edgeLoops.pop()]
|
||||
|
||||
# Find the closest.
|
||||
bestSoFar = BIG_NUM
|
||||
bestIdxSoFar = None
|
||||
for edLoopIdx, edLoop in enumerate(edgeLoops):
|
||||
l =(edgeOrderedList[-1].centre - edLoop.centre).length
|
||||
if l < bestSoFar:
|
||||
bestIdxSoFar = edLoopIdx
|
||||
bestSoFar = l
|
||||
|
||||
edgeOrderedList.append( edgeLoops.pop(bestIdxSoFar) )
|
||||
|
||||
# Now we have the 2 closest, append to either end-
|
||||
# Find the closest.
|
||||
while edgeLoops:
|
||||
bestSoFar = BIG_NUM
|
||||
bestIdxSoFar = None
|
||||
first_or_last = 0 # Zero is first
|
||||
for edLoopIdx, edLoop in enumerate(edgeLoops):
|
||||
l1 =(edgeOrderedList[-1].centre - edLoop.centre).length
|
||||
|
||||
if l1 < bestSoFar:
|
||||
bestIdxSoFar = edLoopIdx
|
||||
bestSoFar = l1
|
||||
first_or_last = 1 # last
|
||||
|
||||
l2 =(edgeOrderedList[0].centre - edLoop.centre).length
|
||||
if l2 < bestSoFar:
|
||||
bestIdxSoFar = edLoopIdx
|
||||
bestSoFar = l2
|
||||
first_or_last = 0 # last
|
||||
|
||||
if first_or_last: # add closest Last
|
||||
edgeOrderedList.append( edgeLoops.pop(bestIdxSoFar) )
|
||||
else: # Add closest First
|
||||
edgeOrderedList.insert(0, edgeLoops.pop(bestIdxSoFar) ) # First
|
||||
|
||||
faces = []
|
||||
|
||||
for i in range(len(edgeOrderedList)-1):
|
||||
faces.extend( skin2EdgeLoops(edgeOrderedList[i], edgeOrderedList[i+1], me, ob, 0) )
|
||||
if choice == 1 and len(edgeOrderedList) > 2: # Loop
|
||||
faces.extend( skin2EdgeLoops(edgeOrderedList[0], edgeOrderedList[-1], me, ob, 0) )
|
||||
|
||||
# REMOVE SELECTED FACES.
|
||||
MESH_MODE= ob.mode
|
||||
if MESH_MODE == 'EDGE' or MESH_MODE == 'VERTEX': pass
|
||||
elif MESH_MODE == 'FACE':
|
||||
try: me.faces.delete(1, [ f for f in me.faces if f.sel ])
|
||||
except: pass
|
||||
|
||||
if 1: # 2.5
|
||||
mesh_faces_extend(me, faces, ob.active_material_index)
|
||||
me.update(calc_edges=True)
|
||||
else:
|
||||
me.faces.extend(faces, smooth = True)
|
||||
|
||||
print('\nSkin done in %.4f sec.' % (time.time()-time1))
|
||||
|
||||
if is_editmode: bpy.ops.object.mode_set(mode='EDIT', toggle=False)
|
||||
|
||||
|
||||
class MESH_OT_skin(bpy.types.Operator):
|
||||
'''Bridge face loops.'''
|
||||
|
||||
bl_idname = "mesh.skin"
|
||||
bl_label = "Add Torus"
|
||||
bl_register = True
|
||||
bl_undo = True
|
||||
|
||||
'''
|
||||
loft_method = EnumProperty(attr="loft_method", items=[(), ()], description="", default= True)
|
||||
|
||||
'''
|
||||
|
||||
def execute(self, context):
|
||||
main(context)
|
||||
return ('FINISHED',)
|
||||
|
||||
|
||||
# Register the operator
|
||||
bpy.ops.add(MESH_OT_skin)
|
||||
|
||||
# Add to a menu
|
||||
import dynamic_menu
|
||||
menu_item = dynamic_menu.add(bpy.types.VIEW3D_MT_edit_mesh_faces, (lambda self, context: self.layout.itemO("mesh.skin", text="Bridge Faces")) )
|
||||
|
||||
if __name__ == "__main__":
|
||||
bpy.ops.mesh.skin()
|
1146
release/scripts/op/uvcalc_smart_project.py
Normal file
1146
release/scripts/op/uvcalc_smart_project.py
Normal file
File diff suppressed because it is too large
Load Diff
178
release/scripts/op/vertexpaint_dirt.py
Normal file
178
release/scripts/op/vertexpaint_dirt.py
Normal file
@ -0,0 +1,178 @@
|
||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||
#
|
||||
# Script copyright (C) Campbell J Barton
|
||||
#
|
||||
# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# ***** END GPL LICENCE BLOCK *****
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
# History
|
||||
#
|
||||
# Originally written by Campbell Barton aka ideasman42
|
||||
#
|
||||
# 2009-11-01: * 2.5 port by Keith "Wahooney" Boshoff
|
||||
# * Replaced old method with my own, speed is similar (about 0.001 sec on Suzanne)
|
||||
# but results are far more accurate
|
||||
#
|
||||
|
||||
import bpy
|
||||
import Mathutils
|
||||
import math
|
||||
import time
|
||||
|
||||
from Mathutils import Vector
|
||||
from bpy.props import *
|
||||
|
||||
def applyVertexDirt(me, blur_iterations, blur_strength, clamp_dirt, clamp_clean, dirt_only):
|
||||
## Window.WaitCursor(1)
|
||||
|
||||
#BPyMesh.meshCalcNormals(me)
|
||||
|
||||
vert_tone = [0.0] * len(me.verts)
|
||||
|
||||
min_tone =180.0
|
||||
max_tone =0.0
|
||||
|
||||
# create lookup table for each vertex's connected vertices (via edges)
|
||||
con = []
|
||||
|
||||
con = [[] for i in range(len(me.verts))]
|
||||
|
||||
# add connected verts
|
||||
for e in me.edges:
|
||||
con[e.verts[0]].append(e.verts[1])
|
||||
con[e.verts[1]].append(e.verts[0])
|
||||
|
||||
for v in me.verts:
|
||||
vec = Vector()
|
||||
no = v.normal
|
||||
co = v.co
|
||||
|
||||
# get the direction of the vectors between the vertex and it's connected vertices
|
||||
for c in con[v.index]:
|
||||
vec += Vector(me.verts[c].co - co).normalize()
|
||||
|
||||
# normalize the vector by dividing by the number of connected verts
|
||||
vec /= len(con[v.index])
|
||||
|
||||
# angle is the acos of the dot product between vert and connected verts normals
|
||||
ang = math.acos(no.dot(vec))
|
||||
|
||||
# enforce min/max
|
||||
ang = max(clamp_dirt, ang)
|
||||
|
||||
if not dirt_only:
|
||||
ang = min(clamp_clean, ang)
|
||||
|
||||
vert_tone[v.index] = ang
|
||||
|
||||
# blur tones
|
||||
for i in range(blur_iterations):
|
||||
# backup the original tones
|
||||
orig_vert_tone = list(vert_tone)
|
||||
|
||||
# use connected verts look up for blurring
|
||||
for j, c in enumerate(con):
|
||||
for v in c:
|
||||
vert_tone[j] += blur_strength * orig_vert_tone[v]
|
||||
|
||||
vert_tone[j] /= len(c) * blur_strength + 1
|
||||
|
||||
min_tone = min(vert_tone)
|
||||
max_tone = max(vert_tone)
|
||||
|
||||
# debug information
|
||||
# print(min_tone * 2 * math.pi)
|
||||
# print(max_tone * 2 * math.pi)
|
||||
# print(clamp_clean)
|
||||
# print(clamp_dirt)
|
||||
|
||||
tone_range = max_tone-min_tone
|
||||
|
||||
if not tone_range:
|
||||
return
|
||||
|
||||
active_col_layer = None
|
||||
|
||||
if len(me.vertex_colors):
|
||||
for lay in me.vertex_colors:
|
||||
if lay.active:
|
||||
active_col_layer = lay.data
|
||||
else:
|
||||
bpy.ops.mesh.vertex_color_add()
|
||||
me.vertex_colors[0].active = True
|
||||
active_col_layer = me.vertex_colors[0].data
|
||||
|
||||
if not active_col_layer:
|
||||
return("CANCELLED", )
|
||||
|
||||
for i, f in enumerate(me.faces):
|
||||
if not me.use_paint_mask or f.selected:
|
||||
|
||||
f_col = active_col_layer[i]
|
||||
|
||||
f_col = [f_col.color1, f_col.color2, f_col.color3, f_col.color4]
|
||||
|
||||
for j, v in enumerate(f.verts):
|
||||
col = f_col[j]
|
||||
tone = vert_tone[me.verts[v].index]
|
||||
tone = (tone-min_tone)/tone_range
|
||||
|
||||
if dirt_only:
|
||||
tone = min(tone, 0.5)
|
||||
tone *= 2
|
||||
|
||||
col[0] = tone*col[0]
|
||||
col[1] = tone*col[1]
|
||||
col[2] = tone*col[2]
|
||||
|
||||
## Window.WaitCursor(0)
|
||||
|
||||
class VertexPaintDirt(bpy.types.Operator):
|
||||
|
||||
bl_idname = "mesh.vertex_paint_dirt"
|
||||
bl_label = "Dirty Vertex Colors"
|
||||
bl_register = True
|
||||
bl_undo = True
|
||||
|
||||
blur_strength = FloatProperty(name = "Blur Strength", description = "Blur strength per iteration", default = 1.0, min = 0.01, max = 1.0)
|
||||
blur_iterations = IntProperty(name = "Blur Iterations", description = "Number times to blur the colors. (higher blurs more)", default = 1, min = 0, max = 40)
|
||||
clean_angle = FloatProperty(name = "Highlight Angle", description = "Less then 90 limits the angle used in the tonal range", default = 180.0, min = 0.0, max = 180.0)
|
||||
dirt_angle = FloatProperty(name = "Dirt Angle", description = "Less then 90 limits the angle used in the tonal range", default = 0.0, min = 0.0, max = 180.0)
|
||||
dirt_only = BoolProperty(name= "Dirt Only", description = "Dont calculate cleans for convex areas", default = False)
|
||||
|
||||
def execute(self, context):
|
||||
sce = context.scene
|
||||
ob = context.object
|
||||
|
||||
if not ob or ob.type != 'MESH':
|
||||
print('Error, no active mesh object, aborting.')
|
||||
return('CANCELLED',)
|
||||
|
||||
me = ob.data
|
||||
|
||||
t = time.time()
|
||||
|
||||
applyVertexDirt(me, self.blur_iterations, self.blur_strength, math.radians(self.dirt_angle), math.radians(self.clean_angle), self.dirt_only)
|
||||
|
||||
print('Dirt calculated in %.6f' % (time.time()-t))
|
||||
|
||||
return('FINISHED',)
|
||||
|
||||
bpy.ops.add(VertexPaintDirt)
|
||||
|
||||
if __name__ == "__main__":
|
||||
bpy.ops.mesh.vertex_paint_dirt()
|
378
release/scripts/op/wm.py
Normal file
378
release/scripts/op/wm.py
Normal file
@ -0,0 +1,378 @@
|
||||
# ##### 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
# <pep8-80 compliant>
|
||||
|
||||
import bpy
|
||||
|
||||
from bpy.props import *
|
||||
|
||||
class MESH_OT_delete_edgeloop(bpy.types.Operator):
|
||||
'''Export a single object as a stanford PLY with normals,
|
||||
colours and texture coordinates.'''
|
||||
bl_idname = "mesh.delete_edgeloop"
|
||||
bl_label = "Delete Edge Loop"
|
||||
|
||||
def execute(self, context):
|
||||
bpy.ops.tfm.edge_slide(value=1.0)
|
||||
bpy.ops.mesh.select_more()
|
||||
bpy.ops.mesh.remove_doubles()
|
||||
return ('FINISHED',)
|
||||
|
||||
rna_path_prop = StringProperty(name="Context Attributes",
|
||||
description="rna context string", maxlen=1024, default="")
|
||||
|
||||
rna_reverse_prop = BoolProperty(name="Reverse",
|
||||
description="Cycle backwards", default=False)
|
||||
|
||||
class NullPathMember:
|
||||
pass
|
||||
|
||||
|
||||
def context_path_validate(context, path):
|
||||
import sys
|
||||
try:
|
||||
value = eval("context.%s" % path)
|
||||
except AttributeError:
|
||||
if "'NoneType'" in str(sys.exc_info()[1]):
|
||||
# One of the items in the rna path is None, just ignore this
|
||||
value = NullPathMember
|
||||
else:
|
||||
# We have a real error in the rna path, dont ignore that
|
||||
raise
|
||||
|
||||
return value
|
||||
|
||||
|
||||
def execute_context_assign(self, context):
|
||||
if context_path_validate(context, self.path) == NullPathMember:
|
||||
return ('PASS_THROUGH',)
|
||||
|
||||
exec("context.%s=self.value" % self.path)
|
||||
return ('FINISHED',)
|
||||
|
||||
|
||||
class WM_OT_context_set_boolean(bpy.types.Operator):
|
||||
'''Set a context value.'''
|
||||
bl_idname = "wm.context_set_boolean"
|
||||
bl_label = "Context Set"
|
||||
|
||||
path = rna_path_prop
|
||||
value = BoolProperty(name="Value",
|
||||
description="Assignment value", default=True)
|
||||
|
||||
execute = execute_context_assign
|
||||
|
||||
|
||||
class WM_OT_context_set_int(bpy.types.Operator): # same as enum
|
||||
'''Set a context value.'''
|
||||
bl_idname = "wm.context_set_int"
|
||||
bl_label = "Context Set"
|
||||
|
||||
path = rna_path_prop
|
||||
value = IntProperty(name="Value", description="Assign value", default=0)
|
||||
|
||||
execute = execute_context_assign
|
||||
|
||||
|
||||
class WM_OT_context_set_float(bpy.types.Operator): # same as enum
|
||||
'''Set a context value.'''
|
||||
bl_idname = "wm.context_set_int"
|
||||
bl_label = "Context Set"
|
||||
|
||||
path = rna_path_prop
|
||||
value = FloatProperty(name="Value",
|
||||
description="Assignment value", default=0.0)
|
||||
|
||||
execute = execute_context_assign
|
||||
|
||||
|
||||
class WM_OT_context_set_string(bpy.types.Operator): # same as enum
|
||||
'''Set a context value.'''
|
||||
bl_idname = "wm.context_set_string"
|
||||
bl_label = "Context Set"
|
||||
|
||||
path = rna_path_prop
|
||||
value = StringProperty(name="Value",
|
||||
description="Assign value", maxlen=1024, default="")
|
||||
|
||||
execute = execute_context_assign
|
||||
|
||||
|
||||
class WM_OT_context_set_enum(bpy.types.Operator):
|
||||
'''Set a context value.'''
|
||||
bl_idname = "wm.context_set_enum"
|
||||
bl_label = "Context Set"
|
||||
|
||||
path = rna_path_prop
|
||||
value = StringProperty(name="Value",
|
||||
description="Assignment value (as a string)",
|
||||
maxlen=1024, default="")
|
||||
|
||||
execute = execute_context_assign
|
||||
|
||||
|
||||
class WM_OT_context_toggle(bpy.types.Operator):
|
||||
'''Toggle a context value.'''
|
||||
bl_idname = "wm.context_toggle"
|
||||
bl_label = "Context Toggle"
|
||||
path = rna_path_prop
|
||||
|
||||
def execute(self, context):
|
||||
|
||||
if context_path_validate(context, self.path) == NullPathMember:
|
||||
return ('PASS_THROUGH',)
|
||||
|
||||
exec("context.%s=not (context.%s)" % (self.path, self.path))
|
||||
return ('FINISHED',)
|
||||
|
||||
|
||||
class WM_OT_context_toggle_enum(bpy.types.Operator):
|
||||
'''Toggle a context value.'''
|
||||
bl_idname = "wm.context_toggle_enum"
|
||||
bl_label = "Context Toggle Values"
|
||||
|
||||
path = rna_path_prop
|
||||
value_1 = StringProperty(name="Value", \
|
||||
description="Toggle enum", maxlen=1024, default="")
|
||||
|
||||
value_2 = StringProperty(name="Value", \
|
||||
description="Toggle enum", maxlen=1024, default="")
|
||||
|
||||
def execute(self, context):
|
||||
|
||||
if context_path_validate(context, self.path) == NullPathMember:
|
||||
return ('PASS_THROUGH',)
|
||||
|
||||
exec("context.%s = ['%s', '%s'][context.%s!='%s']" % \
|
||||
(self.path, self.value_1, self.value_2, self.path, self.value_2))
|
||||
|
||||
return ('FINISHED',)
|
||||
|
||||
|
||||
class WM_OT_context_cycle_int(bpy.types.Operator):
|
||||
'''Set a context value. Useful for cycling active material,
|
||||
vertex keys, groups' etc.'''
|
||||
bl_idname = "wm.context_cycle_int"
|
||||
bl_label = "Context Int Cycle"
|
||||
path = rna_path_prop
|
||||
reverse = rna_reverse_prop
|
||||
|
||||
def execute(self, context):
|
||||
|
||||
value = context_path_validate(context, self.path)
|
||||
if value == NullPathMember:
|
||||
return ('PASS_THROUGH',)
|
||||
|
||||
self.value = value
|
||||
if self.reverse:
|
||||
self.value -= 1
|
||||
else:
|
||||
self.value += 1
|
||||
execute_context_assign(self, context)
|
||||
|
||||
if self.value != eval("context.%s" % self.path):
|
||||
# relies on rna clamping int's out of the range
|
||||
if self.reverse:
|
||||
self.value = (1 << 32)
|
||||
else:
|
||||
self.value = - (1 << 32)
|
||||
execute_context_assign(self, context)
|
||||
|
||||
return ('FINISHED',)
|
||||
|
||||
|
||||
class WM_OT_context_cycle_enum(bpy.types.Operator):
|
||||
'''Toggle a context value.'''
|
||||
bl_idname = "wm.context_cycle_enum"
|
||||
bl_label = "Context Enum Cycle"
|
||||
|
||||
path = rna_path_prop
|
||||
reverse = rna_reverse_prop
|
||||
|
||||
def execute(self, context):
|
||||
|
||||
value = context_path_validate(context, self.path)
|
||||
if value == NullPathMember:
|
||||
return ('PASS_THROUGH',)
|
||||
|
||||
orig_value = value
|
||||
|
||||
# Have to get rna enum values
|
||||
rna_struct_str, rna_prop_str = self.path.rsplit('.', 1)
|
||||
i = rna_prop_str.find('[')
|
||||
|
||||
# just incse we get "context.foo.bar[0]"
|
||||
if i != -1:
|
||||
rna_prop_str = rna_prop_str[0:i]
|
||||
|
||||
rna_struct = eval("context.%s.rna_type" % rna_struct_str)
|
||||
|
||||
rna_prop = rna_struct.properties[rna_prop_str]
|
||||
|
||||
if type(rna_prop) != bpy.types.EnumProperty:
|
||||
raise Exception("expected an enum property")
|
||||
|
||||
enums = rna_struct.properties[rna_prop_str].items.keys()
|
||||
orig_index = enums.index(orig_value)
|
||||
|
||||
# Have the info we need, advance to the next item
|
||||
if self.reverse:
|
||||
if orig_index == 0:
|
||||
advance_enum = enums[-1]
|
||||
else:
|
||||
advance_enum = enums[orig_index-1]
|
||||
else:
|
||||
if orig_index == len(enums) - 1:
|
||||
advance_enum = enums[0]
|
||||
else:
|
||||
advance_enum = enums[orig_index + 1]
|
||||
|
||||
# set the new value
|
||||
exec("context.%s=advance_enum" % self.path)
|
||||
return ('FINISHED',)
|
||||
|
||||
doc_id = StringProperty(name="Doc ID",
|
||||
description="ID for the documentation", maxlen=1024, default="")
|
||||
|
||||
doc_new = StringProperty(name="Doc New",
|
||||
description="", maxlen=1024, default="")
|
||||
|
||||
|
||||
class WM_OT_doc_view(bpy.types.Operator):
|
||||
'''Load online reference docs'''
|
||||
bl_idname = "wm.doc_view"
|
||||
bl_label = "View Documentation"
|
||||
|
||||
doc_id = doc_id
|
||||
_prefix = 'http://www.blender.org/documentation/250PythonDoc'
|
||||
|
||||
def _nested_class_string(self, class_string):
|
||||
ls = []
|
||||
class_obj = getattr(bpy.types, class_string, None).bl_rna
|
||||
while class_obj:
|
||||
ls.insert(0, class_obj)
|
||||
class_obj = class_obj.nested
|
||||
return '.'.join([class_obj.identifier for class_obj in ls])
|
||||
|
||||
def execute(self, context):
|
||||
id_split = self.doc_id.split('.')
|
||||
if len(id_split) == 1: # rna, class
|
||||
url = '%s/bpy.types.%s-class.html' % (self._prefix, id_split[0])
|
||||
elif len(id_split) == 2: # rna, class.prop
|
||||
class_name, class_prop = id_split
|
||||
|
||||
if hasattr(bpy.types, class_name.upper() + '_OT_' + class_prop):
|
||||
url = '%s/bpy.ops.%s-module.html#%s' % \
|
||||
(self._prefix, class_name, class_prop)
|
||||
else:
|
||||
# It so happens that epydoc nests these
|
||||
class_name_full = self._nested_class_string(class_name)
|
||||
url = '%s/bpy.types.%s-class.html#%s' % \
|
||||
(self._prefix, class_name_full, class_prop)
|
||||
|
||||
else:
|
||||
return ('PASS_THROUGH',)
|
||||
|
||||
import webbrowser
|
||||
webbrowser.open(url)
|
||||
|
||||
return ('FINISHED',)
|
||||
|
||||
|
||||
class WM_OT_doc_edit(bpy.types.Operator):
|
||||
'''Load online reference docs'''
|
||||
bl_idname = "wm.doc_edit"
|
||||
bl_label = "Edit Documentation"
|
||||
|
||||
doc_id = doc_id
|
||||
doc_new = doc_new
|
||||
|
||||
_url = "http://www.mindrones.com/blender/svn/xmlrpc.php"
|
||||
|
||||
def _send_xmlrpc(self, data_dict):
|
||||
print("sending data:", data_dict)
|
||||
|
||||
import xmlrpc.client
|
||||
user = 'blenderuser'
|
||||
pwd = 'blender>user'
|
||||
|
||||
docblog = xmlrpc.client.ServerProxy(self._url)
|
||||
docblog.metaWeblog.newPost(1, user, pwd, data_dict, 1)
|
||||
|
||||
def execute(self, context):
|
||||
|
||||
class_name, class_prop = self.doc_id.split('.')
|
||||
|
||||
if not self.doc_new:
|
||||
return ('RUNNING_MODAL',)
|
||||
|
||||
# check if this is an operator
|
||||
op_name = class_name.upper() + '_OT_' + class_prop
|
||||
op_class = getattr(bpy.types, op_name, None)
|
||||
|
||||
# Upload this to the web server
|
||||
upload = {}
|
||||
|
||||
if op_class:
|
||||
rna = op_class.bl_rna
|
||||
doc_orig = rna.description
|
||||
if doc_orig == self.doc_new:
|
||||
return ('RUNNING_MODAL',)
|
||||
|
||||
print("op - old:'%s' -> new:'%s'" % (doc_orig, self.doc_new))
|
||||
upload["title"] = 'OPERATOR %s:%s' % (self.doc_id, doc_orig)
|
||||
upload["description"] = self.doc_new
|
||||
|
||||
self._send_xmlrpc(upload)
|
||||
|
||||
else:
|
||||
rna = getattr(bpy.types, class_name).bl_rna
|
||||
doc_orig = rna.properties[class_prop].description
|
||||
if doc_orig == self.doc_new:
|
||||
return ('RUNNING_MODAL',)
|
||||
|
||||
print("rna - old:'%s' -> new:'%s'" % (doc_orig, self.doc_new))
|
||||
upload["title"] = 'RNA %s:%s' % (self.doc_id, doc_orig)
|
||||
|
||||
upload["description"] = self.doc_new
|
||||
|
||||
self._send_xmlrpc(upload)
|
||||
|
||||
return ('FINISHED',)
|
||||
|
||||
def invoke(self, context, event):
|
||||
wm = context.manager
|
||||
wm.invoke_props_popup(self, event)
|
||||
return ('RUNNING_MODAL',)
|
||||
|
||||
|
||||
bpy.ops.add(MESH_OT_delete_edgeloop)
|
||||
|
||||
bpy.ops.add(WM_OT_context_set_boolean)
|
||||
bpy.ops.add(WM_OT_context_set_int)
|
||||
bpy.ops.add(WM_OT_context_set_float)
|
||||
bpy.ops.add(WM_OT_context_set_string)
|
||||
bpy.ops.add(WM_OT_context_set_enum)
|
||||
bpy.ops.add(WM_OT_context_toggle)
|
||||
bpy.ops.add(WM_OT_context_toggle_enum)
|
||||
bpy.ops.add(WM_OT_context_cycle_enum)
|
||||
bpy.ops.add(WM_OT_context_cycle_int)
|
||||
|
||||
bpy.ops.add(WM_OT_doc_view)
|
||||
bpy.ops.add(WM_OT_doc_edit)
|
96
release/scripts/templates/gamelogic.py
Normal file
96
release/scripts/templates/gamelogic.py
Normal file
@ -0,0 +1,96 @@
|
||||
# ##### 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
# This script must be assigned to a python controller
|
||||
# where it can access the object that owns it and the sensors/actuators that it connects to.
|
||||
|
||||
# GameLogic has been added to the global namespace no need to import
|
||||
|
||||
# for keyboard event comparison
|
||||
# import GameKeys
|
||||
|
||||
# support for Vector(), Matrix() types and advanced functions like AngleBetweenVecs(v1,v2) and RotationMatrix(...)
|
||||
# import Mathutils
|
||||
|
||||
# for functions like getWindowWidth(), getWindowHeight()
|
||||
# import Rasterizer
|
||||
|
||||
def main():
|
||||
cont = GameLogic.getCurrentController()
|
||||
|
||||
# The KX_GameObject that owns this controller.
|
||||
own = cont.owner
|
||||
|
||||
# for scripts that deal with spacial logic
|
||||
own_pos = own.worldPosition
|
||||
|
||||
|
||||
# Some example functions, remove to write your own script.
|
||||
# check for a positive sensor, will run on any object without errors.
|
||||
print 'Logic info for KX_GameObject', own.name
|
||||
input = False
|
||||
|
||||
for sens in cont.sensors:
|
||||
# The sensor can be on another object, we may want to use it
|
||||
own_sens = sens.owner
|
||||
print ' sensor:', sens.name,
|
||||
if sens.positive:
|
||||
print '(true)'
|
||||
input = True
|
||||
else:
|
||||
print '(false)'
|
||||
|
||||
for actu in cont.actuators:
|
||||
# The actuator can be on another object, we may want to use it
|
||||
own_actu = actu.owner
|
||||
print ' actuator:', actu.name
|
||||
|
||||
# This runs the actuator or turns it off
|
||||
# note that actuators will continue to run unless explicitly turned off.
|
||||
if input:
|
||||
cont.activate(actu)
|
||||
else:
|
||||
cont.deactivate(actu)
|
||||
|
||||
# Its also good practice to get sensors and actuators by name
|
||||
# rather then index so any changes to their order wont break the script.
|
||||
|
||||
# sens_key = cont.sensors['key_sensor']
|
||||
# actu_motion = cont.actuators['motion']
|
||||
|
||||
|
||||
# Loop through all other objects in the scene
|
||||
sce = GameLogic.getCurrentScene()
|
||||
print 'Scene Objects:', sce.name
|
||||
for ob in sce.objects:
|
||||
print ' ', ob.name, ob.worldPosition
|
||||
|
||||
|
||||
# Example where collision objects are checked for their properties
|
||||
# adding to our objects "life" property
|
||||
"""
|
||||
actu_collide = cont.sensors['collision_sens']
|
||||
for ob in actu_collide.objectHitList:
|
||||
# Check to see the object has this property
|
||||
if ob.has_key('life'):
|
||||
own['life'] += ob['life']
|
||||
ob['life'] = 0
|
||||
print own['life']
|
||||
"""
|
||||
|
||||
main()
|
32
release/scripts/templates/gamelogic_basic.py
Normal file
32
release/scripts/templates/gamelogic_basic.py
Normal file
@ -0,0 +1,32 @@
|
||||
# ##### 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
def main():
|
||||
|
||||
cont = GameLogic.getCurrentController()
|
||||
own = cont.owner
|
||||
|
||||
sens = cont.sensors['mySensor']
|
||||
actu = cont.actuators['myActuator']
|
||||
|
||||
if sens.positive:
|
||||
cont.activate(actu)
|
||||
else:
|
||||
cont.deactivate(actu)
|
||||
|
||||
main()
|
44
release/scripts/templates/gamelogic_module.py
Normal file
44
release/scripts/templates/gamelogic_module.py
Normal file
@ -0,0 +1,44 @@
|
||||
# ##### 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
# This module can be accessed by a python controller with
|
||||
# its execution method set to 'Module'
|
||||
# * Set the module string to "gamelogic_module.main" (without quotes)
|
||||
# * When renaming the script it MUST have a .py extension
|
||||
# * External text modules are supported as long as they are at
|
||||
# the same location as the blendfile or one of its libraries.
|
||||
|
||||
import GameLogic
|
||||
|
||||
# variables defined here will only be set once when the
|
||||
# module is first imported. Set object spesific vars
|
||||
# inside the function if you intend to use the module
|
||||
# with multiple objects.
|
||||
|
||||
def main(cont):
|
||||
own = cont.owner
|
||||
|
||||
sens = cont.sensors['mySensor']
|
||||
actu = cont.actuators['myActuator']
|
||||
|
||||
if sens.positive:
|
||||
cont.activate(actu)
|
||||
else:
|
||||
cont.deactivate(actu)
|
||||
|
||||
# dont call main(GameLogic.getCurrentController()), the py controller will
|
76
release/scripts/templates/operator.py
Normal file
76
release/scripts/templates/operator.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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
import bpy
|
||||
|
||||
def write_some_data(context, path, use_some_setting):
|
||||
print("running write_some_data...")
|
||||
pass
|
||||
|
||||
from bpy.props import *
|
||||
|
||||
class ExportSomeData(bpy.types.Operator):
|
||||
'''This appiers in the tooltip of the operator and in the generated docs.'''
|
||||
bl_idname = "export.some_data" # this is important since its how bpy.ops.export.some_data is constructed
|
||||
bl_label = "Export Some Data"
|
||||
|
||||
# List of operator properties, the attributes will be assigned
|
||||
# to the class instance from the operator settings before calling.
|
||||
|
||||
# TODO, add better example props
|
||||
path = StringProperty(name="File Path", description="File path used for exporting the PLY file", maxlen= 1024, default= "")
|
||||
use_setting = BoolProperty(name="Example Boolean", description="Example Tooltip", default= True)
|
||||
|
||||
def poll(self, context):
|
||||
return context.active_object != None
|
||||
|
||||
def execute(self, context):
|
||||
|
||||
# # Bug, currently isnt working
|
||||
#if not self.is_property_set("path"):
|
||||
# raise Exception("filename not set")
|
||||
|
||||
write_some_data(self.path, context, self.use_setting)
|
||||
|
||||
return ('FINISHED',)
|
||||
|
||||
def invoke(self, context, event):
|
||||
wm = context.manager
|
||||
|
||||
if True:
|
||||
# File selector
|
||||
wm.add_fileselect(self) # will run self.execute()
|
||||
return ('RUNNING_MODAL',)
|
||||
elif 0:
|
||||
# Redo popup
|
||||
wm.invoke_props_popup(self, event) #
|
||||
return ('RUNNING_MODAL',)
|
||||
elif 0:
|
||||
return self.execute(context)
|
||||
|
||||
|
||||
bpy.ops.add(ExportSomeData)
|
||||
|
||||
# Only needed if you want to add into a dynamic menu
|
||||
import dynamic_menu
|
||||
menu_func = lambda self, context: self.layout.itemO("export.some_data", text="Example Exporter...")
|
||||
menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_export, menu_func)
|
||||
|
||||
# Use for running this script directly
|
||||
if __name__ == "__main__":
|
||||
bpy.ops.export.some_data(path="/tmp/test.ply")
|
38
release/scripts/templates/operator_simple.py
Normal file
38
release/scripts/templates/operator_simple.py
Normal file
@ -0,0 +1,38 @@
|
||||
# ##### 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
def main(context):
|
||||
for ob in context.scene.objects:
|
||||
print(ob)
|
||||
|
||||
class SimpleOperator(bpy.types.Operator):
|
||||
''''''
|
||||
bl_idname = "object.simple_operator"
|
||||
bl_label = "Simple Object Operator"
|
||||
|
||||
def poll(self, context):
|
||||
return context.active_object != None
|
||||
|
||||
def execute(self, context):
|
||||
main(context)
|
||||
return ('FINISHED',)
|
||||
|
||||
bpy.ops.add(SimpleOperator)
|
||||
|
||||
if __name__ == "__main__":
|
||||
bpy.ops.object.simple_operator()
|
@ -1,183 +0,0 @@
|
||||
|
||||
import bpy
|
||||
|
||||
class DataButtonsPanel(bpy.types.Panel):
|
||||
__space_type__ = 'PROPERTIES'
|
||||
__region_type__ = 'WINDOW'
|
||||
__context__ = "data"
|
||||
|
||||
def poll(self, context):
|
||||
return context.armature
|
||||
|
||||
class DATA_PT_context_arm(DataButtonsPanel):
|
||||
__show_header__ = False
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
ob = context.object
|
||||
arm = context.armature
|
||||
space = context.space_data
|
||||
|
||||
split = layout.split(percentage=0.65)
|
||||
|
||||
if ob:
|
||||
split.template_ID(ob, "data")
|
||||
split.itemS()
|
||||
elif arm:
|
||||
split.template_ID(space, "pin_id")
|
||||
split.itemS()
|
||||
|
||||
class DATA_PT_skeleton(DataButtonsPanel):
|
||||
__label__ = "Skeleton"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
ob = context.object
|
||||
arm = context.armature
|
||||
space = context.space_data
|
||||
|
||||
layout.itemR(arm, "pose_position", expand=True)
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Layers:")
|
||||
col.itemR(arm, "layer", text="")
|
||||
col.itemL(text="Protected Layers:")
|
||||
col.itemR(arm, "layer_protection", text="")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Deform:")
|
||||
col.itemR(arm, "deform_vertexgroups", text="Vertex Groups")
|
||||
col.itemR(arm, "deform_envelope", text="Envelopes")
|
||||
col.itemR(arm, "deform_quaternion", text="Quaternion")
|
||||
col.itemR(arm, "deform_bbone_rest", text="B-Bones Rest")
|
||||
|
||||
class DATA_PT_display(DataButtonsPanel):
|
||||
__label__ = "Display"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
arm = context.armature
|
||||
|
||||
layout.row().itemR(arm, "drawtype", expand=True)
|
||||
|
||||
flow = layout.column_flow()
|
||||
flow.itemR(arm, "draw_names", text="Names")
|
||||
flow.itemR(arm, "draw_axes", text="Axes")
|
||||
flow.itemR(arm, "draw_custom_bone_shapes", text="Shapes")
|
||||
flow.itemR(arm, "draw_group_colors", text="Colors")
|
||||
flow.itemR(arm, "delay_deform", text="Delay Refresh")
|
||||
|
||||
class DATA_PT_bone_groups(DataButtonsPanel):
|
||||
__label__ = "Bone Groups"
|
||||
|
||||
def poll(self, context):
|
||||
return (context.object and context.object.type=='ARMATURE' and context.object.pose)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
ob = context.object
|
||||
pose = ob.pose
|
||||
|
||||
row = layout.row()
|
||||
row.template_list(pose, "bone_groups", pose, "active_bone_group_index", rows=2)
|
||||
|
||||
col = row.column(align=True)
|
||||
col.active = (ob.proxy == None)
|
||||
col.itemO("pose.group_add", icon='ICON_ZOOMIN', text="")
|
||||
col.itemO("pose.group_remove", icon='ICON_ZOOMOUT', text="")
|
||||
|
||||
group = pose.active_bone_group
|
||||
if group:
|
||||
col = layout.column()
|
||||
col.active= (ob.proxy == None)
|
||||
col.itemR(group, "name")
|
||||
|
||||
split = layout.split(0.5)
|
||||
split.active= (ob.proxy == None)
|
||||
split.itemR(group, "color_set")
|
||||
if group.color_set:
|
||||
split.template_triColorSet(group, "colors")
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.active = (ob.proxy == None)
|
||||
|
||||
row.itemO("pose.group_assign", text="Assign")
|
||||
row.itemO("pose.group_remove", text="Remove") #row.itemO("pose.bone_group_remove_from", text="Remove")
|
||||
#row.itemO("object.bone_group_select", text="Select")
|
||||
#row.itemO("object.bone_group_deselect", text="Deselect")
|
||||
|
||||
class DATA_PT_paths(DataButtonsPanel):
|
||||
__label__ = "Paths"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
arm = context.armature
|
||||
|
||||
layout.itemR(arm, "paths_type", expand=True)
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
sub = col.column(align=True)
|
||||
if (arm.paths_type == 'CURRENT_FRAME'):
|
||||
sub.itemR(arm, "path_before_current", text="Before")
|
||||
sub.itemR(arm, "path_after_current", text="After")
|
||||
elif (arm.paths_type == 'RANGE'):
|
||||
sub.itemR(arm, "path_start_frame", text="Start")
|
||||
sub.itemR(arm, "path_end_frame", text="End")
|
||||
|
||||
sub.itemR(arm, "path_size", text="Step")
|
||||
col.row().itemR(arm, "paths_location", expand=True)
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Display:")
|
||||
col.itemR(arm, "paths_show_frame_numbers", text="Frame Numbers")
|
||||
col.itemR(arm, "paths_highlight_keyframes", text="Keyframes")
|
||||
col.itemR(arm, "paths_show_keyframe_numbers", text="Keyframe Numbers")
|
||||
|
||||
layout.itemS()
|
||||
|
||||
row = layout.row()
|
||||
row.itemO("pose.paths_calculate", text="Calculate Paths")
|
||||
row.itemO("pose.paths_clear", text="Clear Paths")
|
||||
|
||||
class DATA_PT_ghost(DataButtonsPanel):
|
||||
__label__ = "Ghost"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
arm = context.armature
|
||||
|
||||
layout.itemR(arm, "ghost_type", expand=True)
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
|
||||
sub = col.column(align=True)
|
||||
if arm.ghost_type == 'RANGE':
|
||||
sub.itemR(arm, "ghost_start_frame", text="Start")
|
||||
sub.itemR(arm, "ghost_end_frame", text="End")
|
||||
sub.itemR(arm, "ghost_size", text="Step")
|
||||
elif arm.ghost_type == 'CURRENT_FRAME':
|
||||
sub.itemR(arm, "ghost_step", text="Range")
|
||||
sub.itemR(arm, "ghost_size", text="Step")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Display:")
|
||||
col.itemR(arm, "ghost_only_selected", text="Selected Only")
|
||||
|
||||
bpy.types.register(DATA_PT_context_arm)
|
||||
bpy.types.register(DATA_PT_skeleton)
|
||||
bpy.types.register(DATA_PT_display)
|
||||
bpy.types.register(DATA_PT_bone_groups)
|
||||
bpy.types.register(DATA_PT_paths)
|
||||
bpy.types.register(DATA_PT_ghost)
|
@ -1,233 +0,0 @@
|
||||
|
||||
import bpy
|
||||
|
||||
class BoneButtonsPanel(bpy.types.Panel):
|
||||
__space_type__ = 'PROPERTIES'
|
||||
__region_type__ = 'WINDOW'
|
||||
__context__ = "bone"
|
||||
|
||||
def poll(self, context):
|
||||
return (context.bone or context.edit_bone)
|
||||
|
||||
class BONE_PT_context_bone(BoneButtonsPanel):
|
||||
__show_header__ = False
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
bone = context.bone
|
||||
if not bone:
|
||||
bone = context.edit_bone
|
||||
|
||||
row = layout.row()
|
||||
row.itemL(text="", icon='ICON_BONE_DATA')
|
||||
row.itemR(bone, "name", text="")
|
||||
|
||||
class BONE_PT_transform(BoneButtonsPanel):
|
||||
__label__ = "Transform"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
ob = context.object
|
||||
bone = context.bone
|
||||
if not bone:
|
||||
bone = context.edit_bone
|
||||
|
||||
row = layout.row()
|
||||
row.column().itemR(bone, "head")
|
||||
row.column().itemR(bone, "tail")
|
||||
|
||||
col = row.column()
|
||||
sub = col.column(align=True)
|
||||
sub.itemL(text="Roll:")
|
||||
sub.itemR(bone, "roll", text="")
|
||||
sub.itemL()
|
||||
sub.itemR(bone, "locked")
|
||||
|
||||
else:
|
||||
pchan = ob.pose.pose_channels[context.bone.name]
|
||||
|
||||
|
||||
|
||||
row = layout.row()
|
||||
col = row.column()
|
||||
col.itemR(pchan, "location")
|
||||
col.active = not (bone.parent and bone.connected)
|
||||
|
||||
col = row.column()
|
||||
if pchan.rotation_mode == 'QUATERNION':
|
||||
col.itemR(pchan, "rotation_quaternion", text="Rotation")
|
||||
elif pchan.rotation_mode == 'AXIS_ANGLE':
|
||||
#col.itemL(text="Rotation")
|
||||
#col.itemR(pchan, "rotation_angle", text="Angle")
|
||||
#col.itemR(pchan, "rotation_axis", text="Axis")
|
||||
col.itemR(pchan, "rotation_axis_angle", text="Rotation")
|
||||
else:
|
||||
col.itemR(pchan, "rotation_euler", text="Rotation")
|
||||
|
||||
row.column().itemR(pchan, "scale")
|
||||
|
||||
layout.itemR(pchan, "rotation_mode")
|
||||
|
||||
class BONE_PT_transform_locks(BoneButtonsPanel):
|
||||
__label__ = "Transform Locks"
|
||||
__default_closed__ = True
|
||||
|
||||
def poll(self, context):
|
||||
return context.bone
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
ob = context.object
|
||||
bone = context.bone
|
||||
pchan = ob.pose.pose_channels[context.bone.name]
|
||||
|
||||
row = layout.row()
|
||||
col = row.column()
|
||||
col.itemR(pchan, "lock_location")
|
||||
col.active = not (bone.parent and bone.connected)
|
||||
|
||||
col = row.column()
|
||||
if pchan.rotation_mode in ('QUATERNION', 'AXIS_ANGLE'):
|
||||
col.itemR(pchan, "lock_rotations_4d", text="Lock Rotation")
|
||||
if pchan.lock_rotations_4d:
|
||||
col.itemR(pchan, "lock_rotation_w", text="W")
|
||||
col.itemR(pchan, "lock_rotation", text="")
|
||||
else:
|
||||
col.itemR(pchan, "lock_rotation", text="Rotation")
|
||||
|
||||
row.column().itemR(pchan, "lock_scale")
|
||||
|
||||
class BONE_PT_relations(BoneButtonsPanel):
|
||||
__label__ = "Relations"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
ob = context.object
|
||||
bone = context.bone
|
||||
arm = context.armature
|
||||
|
||||
if not bone:
|
||||
bone = context.edit_bone
|
||||
pchan = None
|
||||
else:
|
||||
pchan = ob.pose.pose_channels[context.bone.name]
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Layers:")
|
||||
col.itemR(bone, "layer", text="")
|
||||
|
||||
col.itemS()
|
||||
|
||||
if ob and pchan:
|
||||
col.itemL(text="Bone Group:")
|
||||
col.item_pointerR(pchan, "bone_group", ob.pose, "bone_groups", text="")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Parent:")
|
||||
if context.bone:
|
||||
col.itemR(bone, "parent", text="")
|
||||
else:
|
||||
col.item_pointerR(bone, "parent", arm, "edit_bones", text="")
|
||||
|
||||
sub = col.column()
|
||||
sub.active = bone.parent != None
|
||||
sub.itemR(bone, "connected")
|
||||
sub.itemR(bone, "hinge", text="Inherit Rotation")
|
||||
sub.itemR(bone, "inherit_scale", text="Inherit Scale")
|
||||
|
||||
|
||||
class BONE_PT_display(BoneButtonsPanel):
|
||||
__label__ = "Display"
|
||||
|
||||
def poll(self, context):
|
||||
return context.bone
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
ob = context.object
|
||||
bone = context.bone
|
||||
arm = context.armature
|
||||
|
||||
if not bone:
|
||||
bone = context.edit_bone
|
||||
pchan = None
|
||||
else:
|
||||
pchan = ob.pose.pose_channels[context.bone.name]
|
||||
|
||||
if ob and pchan:
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
|
||||
col.itemR(bone, "draw_wire", text="Wireframe")
|
||||
col.itemR(bone, "hidden", text="Hide")
|
||||
|
||||
col = split.column()
|
||||
|
||||
col.itemL(text="Custom Shape:")
|
||||
col.itemR(pchan, "custom_shape", text="")
|
||||
|
||||
|
||||
class BONE_PT_deform(BoneButtonsPanel):
|
||||
__label__ = "Deform"
|
||||
__default_closed__ = True
|
||||
|
||||
def draw_header(self, context):
|
||||
bone = context.bone
|
||||
|
||||
if not bone:
|
||||
bone = context.edit_bone
|
||||
|
||||
self.layout.itemR(bone, "deform", text="")
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
bone = context.bone
|
||||
|
||||
if not bone:
|
||||
bone = context.edit_bone
|
||||
|
||||
layout.active = bone.deform
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Envelope:")
|
||||
|
||||
sub = col.column(align=True)
|
||||
sub.itemR(bone, "envelope_distance", text="Distance")
|
||||
sub.itemR(bone, "envelope_weight", text="Weight")
|
||||
col.itemR(bone, "multiply_vertexgroup_with_envelope", text="Multiply")
|
||||
|
||||
sub = col.column(align=True)
|
||||
sub.itemL(text="Radius:")
|
||||
sub.itemR(bone, "head_radius", text="Head")
|
||||
sub.itemR(bone, "tail_radius", text="Tail")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Curved Bones:")
|
||||
|
||||
sub = col.column(align=True)
|
||||
sub.itemR(bone, "bbone_segments", text="Segments")
|
||||
sub.itemR(bone, "bbone_in", text="Ease In")
|
||||
sub.itemR(bone, "bbone_out", text="Ease Out")
|
||||
|
||||
col.itemL(text="Offset:")
|
||||
col.itemR(bone, "cyclic_offset")
|
||||
|
||||
|
||||
bpy.types.register(BONE_PT_context_bone)
|
||||
bpy.types.register(BONE_PT_transform)
|
||||
bpy.types.register(BONE_PT_transform_locks)
|
||||
bpy.types.register(BONE_PT_relations)
|
||||
bpy.types.register(BONE_PT_display)
|
||||
bpy.types.register(BONE_PT_deform)
|
@ -1,98 +0,0 @@
|
||||
|
||||
import bpy
|
||||
|
||||
class DataButtonsPanel(bpy.types.Panel):
|
||||
__space_type__ = 'PROPERTIES'
|
||||
__region_type__ = 'WINDOW'
|
||||
__context__ = "data"
|
||||
|
||||
def poll(self, context):
|
||||
return context.camera
|
||||
|
||||
class DATA_PT_context_camera(DataButtonsPanel):
|
||||
__show_header__ = False
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
ob = context.object
|
||||
cam = context.camera
|
||||
space = context.space_data
|
||||
|
||||
split = layout.split(percentage=0.65)
|
||||
|
||||
if ob:
|
||||
split.template_ID(ob, "data")
|
||||
split.itemS()
|
||||
elif cam:
|
||||
split.template_ID(space, "pin_id")
|
||||
split.itemS()
|
||||
|
||||
class DATA_PT_camera(DataButtonsPanel):
|
||||
__label__ = "Lens"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
cam = context.camera
|
||||
|
||||
layout.itemR(cam, "type", expand=True)
|
||||
|
||||
row = layout.row()
|
||||
if cam.type == 'PERSP':
|
||||
if cam.lens_unit == 'MILLIMETERS':
|
||||
row.itemR(cam, "lens", text="Angle")
|
||||
elif cam.lens_unit == 'DEGREES':
|
||||
row.itemR(cam, "angle")
|
||||
row.itemR(cam, "lens_unit", text="")
|
||||
|
||||
elif cam.type == 'ORTHO':
|
||||
row.itemR(cam, "ortho_scale")
|
||||
|
||||
layout.itemR(cam, "panorama")
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column(align=True)
|
||||
col.itemL(text="Shift:")
|
||||
col.itemR(cam, "shift_x", text="X")
|
||||
col.itemR(cam, "shift_y", text="Y")
|
||||
|
||||
col = split.column(align=True)
|
||||
col.itemL(text="Clipping:")
|
||||
col.itemR(cam, "clip_start", text="Start")
|
||||
col.itemR(cam, "clip_end", text="End")
|
||||
|
||||
layout.itemL(text="Depth of Field:")
|
||||
|
||||
row = layout.row()
|
||||
row.itemR(cam, "dof_object", text="")
|
||||
row.itemR(cam, "dof_distance", text="Distance")
|
||||
|
||||
class DATA_PT_camera_display(DataButtonsPanel):
|
||||
__label__ = "Display"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
cam = context.camera
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemR(cam, "show_limits", text="Limits")
|
||||
col.itemR(cam, "show_mist", text="Mist")
|
||||
col.itemR(cam, "show_title_safe", text="Title Safe")
|
||||
col.itemR(cam, "show_name", text="Name")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(cam, "draw_size", text="Size")
|
||||
col.itemS()
|
||||
col.itemR(cam, "show_passepartout", text="Passepartout")
|
||||
sub = col.column()
|
||||
sub.active = cam.show_passepartout
|
||||
sub.itemR(cam, "passepartout_alpha", text="Alpha", slider=True)
|
||||
|
||||
bpy.types.register(DATA_PT_context_camera)
|
||||
bpy.types.register(DATA_PT_camera)
|
||||
bpy.types.register(DATA_PT_camera_display)
|
@ -1,227 +0,0 @@
|
||||
|
||||
import bpy
|
||||
|
||||
class DataButtonsPanel(bpy.types.Panel):
|
||||
__space_type__ = 'PROPERTIES'
|
||||
__region_type__ = 'WINDOW'
|
||||
__context__ = "data"
|
||||
|
||||
def poll(self, context):
|
||||
return (context.object and context.object.type in ('CURVE', 'SURFACE') and context.curve)
|
||||
|
||||
class DataButtonsPanelCurve(DataButtonsPanel):
|
||||
'''
|
||||
Same as above but for curves only
|
||||
'''
|
||||
def poll(self, context):
|
||||
return (context.object and context.object.type == 'CURVE' and context.curve)
|
||||
|
||||
class DataButtonsPanelActive(DataButtonsPanel):
|
||||
'''
|
||||
Same as above but for curves only
|
||||
'''
|
||||
def poll(self, context):
|
||||
curve = context.curve
|
||||
return (curve and curve.active_spline)
|
||||
|
||||
class DATA_PT_context_curve(DataButtonsPanel):
|
||||
__show_header__ = False
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
ob = context.object
|
||||
curve = context.curve
|
||||
space = context.space_data
|
||||
|
||||
split = layout.split(percentage=0.65)
|
||||
|
||||
if ob:
|
||||
split.template_ID(ob, "data")
|
||||
split.itemS()
|
||||
elif curve:
|
||||
split.template_ID(space, "pin_id")
|
||||
split.itemS()
|
||||
|
||||
class DATA_PT_shape_curve(DataButtonsPanel):
|
||||
__label__ = "Shape"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
ob = context.object
|
||||
curve = context.curve
|
||||
space = context.space_data
|
||||
is_surf = (ob.type == 'SURFACE')
|
||||
|
||||
if not is_surf:
|
||||
row = layout.row()
|
||||
row.itemR(curve, "dimensions", expand=True)
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
|
||||
if not is_surf:
|
||||
sub = col.column()
|
||||
sub.active = (curve.dimensions=='2D')
|
||||
sub.itemL(text="Caps:")
|
||||
row = sub.row()
|
||||
row.itemR(curve, "front")
|
||||
row.itemR(curve, "back")
|
||||
|
||||
col.itemL(text="Textures:")
|
||||
# col.itemR(curve, "uv_orco")
|
||||
col.itemR(curve, "auto_texspace")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Resolution:")
|
||||
sub = col.column(align=True)
|
||||
sub.itemR(curve, "resolution_u", text="Preview U")
|
||||
sub.itemR(curve, "render_resolution_u", text="Render U")
|
||||
|
||||
if is_surf:
|
||||
sub = col.column(align=True)
|
||||
sub.itemR(curve, "resolution_v", text="Preview V")
|
||||
sub.itemR(curve, "render_resolution_v", text="Render V")
|
||||
|
||||
# XXX - put somewhere nicer.
|
||||
row= layout.row()
|
||||
row.itemR(curve, "twist_mode")
|
||||
row.itemR(curve, "twist_smooth") # XXX - may not be kept
|
||||
|
||||
|
||||
# col.itemL(text="Display:")
|
||||
# col.itemL(text="HANDLES")
|
||||
# col.itemL(text="NORMALS")
|
||||
# col.itemR(curve, "vertex_normal_flip")
|
||||
|
||||
class DATA_PT_geometry_curve(DataButtonsPanel):
|
||||
__label__ = "Geometry"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
curve = context.curve
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Modification:")
|
||||
col.itemR(curve, "width")
|
||||
col.itemR(curve, "extrude")
|
||||
col.itemL(text="Taper Object:")
|
||||
col.itemR(curve, "taper_object", text="")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Bevel:")
|
||||
col.itemR(curve, "bevel_depth", text="Depth")
|
||||
col.itemR(curve, "bevel_resolution", text="Resolution")
|
||||
col.itemL(text="Bevel Object:")
|
||||
col.itemR(curve, "bevel_object", text="")
|
||||
|
||||
class DATA_PT_pathanim(DataButtonsPanelCurve):
|
||||
__label__ = "Path Animation"
|
||||
|
||||
def draw_header(self, context):
|
||||
curve = context.curve
|
||||
|
||||
self.layout.itemR(curve, "use_path", text="")
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
curve = context.curve
|
||||
|
||||
layout.active = curve.use_path
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemR(curve, "path_length", text="Frames")
|
||||
col.itemR(curve, "use_path_follow")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(curve, "use_stretch")
|
||||
col.itemR(curve, "use_radius")
|
||||
col.itemR(curve, "use_time_offset", text="Offset Children")
|
||||
|
||||
class DATA_PT_active_spline(DataButtonsPanelActive):
|
||||
__label__ = "Active Spline"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
ob = context.object
|
||||
curve = context.curve
|
||||
act_spline = curve.active_spline
|
||||
is_surf = (ob.type == 'SURFACE')
|
||||
is_poly = (act_spline.type == 'POLY')
|
||||
|
||||
split = layout.split()
|
||||
|
||||
if is_poly:
|
||||
# These settings are below but its easier to have
|
||||
# poly's set aside since they use so few settings
|
||||
col = split.column()
|
||||
col.itemL(text="Cyclic:")
|
||||
col.itemR(act_spline, "smooth")
|
||||
col = split.column()
|
||||
col.itemR(act_spline, "cyclic_u", text="U")
|
||||
|
||||
else:
|
||||
col = split.column()
|
||||
col.itemL(text="Cyclic:")
|
||||
if act_spline.type == 'NURBS':
|
||||
col.itemL(text="Bezier:")
|
||||
col.itemL(text="Endpoint:")
|
||||
col.itemL(text="Order:")
|
||||
|
||||
col.itemL(text="Resolution:")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(act_spline, "cyclic_u", text="U")
|
||||
|
||||
if act_spline.type == 'NURBS':
|
||||
sub = col.column()
|
||||
# sub.active = (not act_spline.cyclic_u)
|
||||
sub.itemR(act_spline, "bezier_u", text="U")
|
||||
sub.itemR(act_spline, "endpoint_u", text="U")
|
||||
|
||||
sub = col.column()
|
||||
sub.itemR(act_spline, "order_u", text="U")
|
||||
col.itemR(act_spline, "resolution_u", text="U")
|
||||
|
||||
if is_surf:
|
||||
col = split.column()
|
||||
col.itemR(act_spline, "cyclic_v", text="V")
|
||||
|
||||
# its a surface, assume its a nurb.
|
||||
sub = col.column()
|
||||
sub.active = (not act_spline.cyclic_v)
|
||||
sub.itemR(act_spline, "bezier_v", text="V")
|
||||
sub.itemR(act_spline, "endpoint_v", text="V")
|
||||
sub = col.column()
|
||||
sub.itemR(act_spline, "order_v", text="V")
|
||||
sub.itemR(act_spline, "resolution_v", text="V")
|
||||
|
||||
|
||||
if not is_surf:
|
||||
split = layout.split()
|
||||
col = split.column()
|
||||
col.active = (curve.dimensions=='3D')
|
||||
|
||||
col.itemL(text="Interpolation:")
|
||||
col.itemR(act_spline, "tilt_interpolation", text="Tilt")
|
||||
col.itemR(act_spline, "radius_interpolation", text="Radius")
|
||||
|
||||
split = layout.split()
|
||||
col = split.column()
|
||||
col.itemR(act_spline, "smooth")
|
||||
|
||||
|
||||
bpy.types.register(DATA_PT_context_curve)
|
||||
bpy.types.register(DATA_PT_shape_curve)
|
||||
bpy.types.register(DATA_PT_geometry_curve)
|
||||
bpy.types.register(DATA_PT_pathanim)
|
||||
bpy.types.register(DATA_PT_active_spline)
|
@ -1,23 +0,0 @@
|
||||
|
||||
import bpy
|
||||
|
||||
class DataButtonsPanel(bpy.types.Panel):
|
||||
__space_type__ = 'PROPERTIES'
|
||||
__region_type__ = 'WINDOW'
|
||||
__context__ = "data"
|
||||
|
||||
def poll(self, context):
|
||||
return (context.object and context.object.type == 'EMPTY')
|
||||
|
||||
class DATA_PT_empty(DataButtonsPanel):
|
||||
__label__ = "Empty"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
ob = context.object
|
||||
|
||||
layout.itemR(ob, "empty_draw_type", text="Display")
|
||||
layout.itemR(ob, "empty_draw_size", text="Size")
|
||||
|
||||
bpy.types.register(DATA_PT_empty)
|
@ -1,312 +0,0 @@
|
||||
|
||||
import bpy
|
||||
|
||||
class DataButtonsPanel(bpy.types.Panel):
|
||||
__space_type__ = 'PROPERTIES'
|
||||
__region_type__ = 'WINDOW'
|
||||
__context__ = "data"
|
||||
|
||||
def poll(self, context):
|
||||
return context.lamp
|
||||
|
||||
class DATA_PT_preview(DataButtonsPanel):
|
||||
__label__ = "Preview"
|
||||
|
||||
def draw(self, context):
|
||||
self.layout.template_preview(context.lamp)
|
||||
|
||||
class DATA_PT_context_lamp(DataButtonsPanel):
|
||||
__show_header__ = False
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
ob = context.object
|
||||
lamp = context.lamp
|
||||
space = context.space_data
|
||||
|
||||
split = layout.split(percentage=0.65)
|
||||
|
||||
if ob:
|
||||
split.template_ID(ob, "data")
|
||||
split.itemS()
|
||||
elif lamp:
|
||||
split.template_ID(space, "pin_id")
|
||||
split.itemS()
|
||||
|
||||
class DATA_PT_lamp(DataButtonsPanel):
|
||||
__label__ = "Lamp"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
lamp = context.lamp
|
||||
|
||||
layout.itemR(lamp, "type", expand=True)
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
sub = col.column()
|
||||
sub.itemR(lamp, "color", text="")
|
||||
sub.itemR(lamp, "energy")
|
||||
|
||||
if lamp.type in ('POINT', 'SPOT'):
|
||||
sub.itemL(text="Falloff:")
|
||||
sub.itemR(lamp, "falloff_type", text="")
|
||||
sub.itemR(lamp, "distance")
|
||||
|
||||
if lamp.falloff_type == 'LINEAR_QUADRATIC_WEIGHTED':
|
||||
col.itemL(text="Attenuation Factors:")
|
||||
sub = col.column(align=True)
|
||||
sub.itemR(lamp, "linear_attenuation", slider=True, text="Linear")
|
||||
sub.itemR(lamp, "quadratic_attenuation", slider=True, text="Quadratic")
|
||||
|
||||
col.itemR(lamp, "sphere")
|
||||
|
||||
if lamp.type == 'AREA':
|
||||
col.itemR(lamp, "distance")
|
||||
col.itemR(lamp, "gamma")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(lamp, "negative")
|
||||
col.itemR(lamp, "layer", text="This Layer Only")
|
||||
col.itemR(lamp, "specular")
|
||||
col.itemR(lamp, "diffuse")
|
||||
|
||||
class DATA_PT_sunsky(DataButtonsPanel):
|
||||
__label__ = "Sky & Atmosphere"
|
||||
|
||||
def poll(self, context):
|
||||
lamp = context.lamp
|
||||
return (lamp and lamp.type == 'SUN')
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
lamp = context.lamp.sky
|
||||
|
||||
layout.itemR(lamp, "sky")
|
||||
|
||||
row = layout.row()
|
||||
row.active = lamp.sky or lamp.atmosphere
|
||||
row.itemR(lamp, "atmosphere_turbidity", text="Turbidity")
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.active = lamp.sky
|
||||
col.itemL(text="Blending:")
|
||||
sub = col.column()
|
||||
sub.itemR(lamp, "sky_blend_type", text="")
|
||||
sub.itemR(lamp, "sky_blend", text="Factor")
|
||||
|
||||
col.itemL(text="Color Space:")
|
||||
sub = col.column()
|
||||
sub.row().itemR(lamp, "sky_color_space", expand=True)
|
||||
sub.itemR(lamp, "sky_exposure", text="Exposure")
|
||||
|
||||
col = split.column()
|
||||
col.active = lamp.sky
|
||||
col.itemL(text="Horizon:")
|
||||
sub = col.column()
|
||||
sub.itemR(lamp, "horizon_brightness", text="Brightness")
|
||||
sub.itemR(lamp, "spread", text="Spread")
|
||||
|
||||
col.itemL(text="Sun:")
|
||||
sub = col.column()
|
||||
sub.itemR(lamp, "sun_brightness", text="Brightness")
|
||||
sub.itemR(lamp, "sun_size", text="Size")
|
||||
sub.itemR(lamp, "backscattered_light", slider=True,text="Back Light")
|
||||
|
||||
layout.itemS()
|
||||
|
||||
layout.itemR(lamp, "atmosphere")
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.active = lamp.atmosphere
|
||||
col.itemL(text="Intensity:")
|
||||
col.itemR(lamp, "sun_intensity", text="Sun")
|
||||
col.itemR(lamp, "atmosphere_distance_factor", text="Distance")
|
||||
|
||||
col = split.column()
|
||||
col.active = lamp.atmosphere
|
||||
col.itemL(text="Scattering:")
|
||||
sub = col.column(align=True)
|
||||
sub.itemR(lamp, "atmosphere_inscattering", slider=True, text="Inscattering")
|
||||
sub.itemR(lamp, "atmosphere_extinction", slider=True ,text="Extinction")
|
||||
|
||||
class DATA_PT_shadow(DataButtonsPanel):
|
||||
__label__ = "Shadow"
|
||||
|
||||
def poll(self, context):
|
||||
lamp = context.lamp
|
||||
return (lamp and lamp.type in ('POINT','SUN', 'SPOT', 'AREA'))
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
lamp = context.lamp
|
||||
|
||||
layout.itemR(lamp, "shadow_method", expand=True)
|
||||
|
||||
if lamp.shadow_method != 'NOSHADOW':
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemR(lamp, "shadow_color", text="")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(lamp, "shadow_layer", text="This Layer Only")
|
||||
col.itemR(lamp, "only_shadow")
|
||||
|
||||
if lamp.shadow_method == 'RAY_SHADOW':
|
||||
col = layout.column()
|
||||
col.itemL(text="Sampling:")
|
||||
col.row().itemR(lamp, "shadow_ray_sampling_method", expand=True)
|
||||
|
||||
if lamp.type in ('POINT', 'SUN', 'SPOT'):
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemR(lamp, "shadow_soft_size", text="Soft Size")
|
||||
|
||||
col.itemR(lamp, "shadow_ray_samples", text="Samples")
|
||||
if lamp.shadow_ray_sampling_method == 'ADAPTIVE_QMC':
|
||||
col.itemR(lamp, "shadow_adaptive_threshold", text="Threshold")
|
||||
col = split.column()
|
||||
|
||||
elif lamp.type == 'AREA':
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
sub = split.column(align=True)
|
||||
if lamp.shape == 'SQUARE':
|
||||
col.itemR(lamp, "shadow_ray_samples_x", text="Samples")
|
||||
elif lamp.shape == 'RECTANGLE':
|
||||
col.itemR(lamp, "shadow_ray_samples_x", text="Samples X")
|
||||
col.itemR(lamp, "shadow_ray_samples_y", text="Samples Y")
|
||||
|
||||
if lamp.shadow_ray_sampling_method == 'ADAPTIVE_QMC':
|
||||
col.itemR(lamp, "shadow_adaptive_threshold", text="Threshold")
|
||||
|
||||
elif lamp.shadow_ray_sampling_method == 'CONSTANT_JITTERED':
|
||||
sub.itemR(lamp, "umbra")
|
||||
sub.itemR(lamp, "dither")
|
||||
sub.itemR(lamp, "jitter")
|
||||
|
||||
elif lamp.shadow_method == 'BUFFER_SHADOW':
|
||||
col = layout.column()
|
||||
col.itemL(text="Buffer Type:")
|
||||
col.row().itemR(lamp, "shadow_buffer_type", expand=True)
|
||||
|
||||
if lamp.shadow_buffer_type in ('REGULAR', 'HALFWAY', 'DEEP'):
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Filter Type:")
|
||||
col.itemR(lamp, "shadow_filter_type", text="")
|
||||
sub = col.column(align=True)
|
||||
sub.itemR(lamp, "shadow_buffer_soft", text="Soft")
|
||||
sub.itemR(lamp, "shadow_buffer_bias", text="Bias")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Sample Buffers:")
|
||||
col.itemR(lamp, "shadow_sample_buffers", text="")
|
||||
sub = col.column(align=True)
|
||||
sub.itemR(lamp, "shadow_buffer_size", text="Size")
|
||||
sub.itemR(lamp, "shadow_buffer_samples", text="Samples")
|
||||
if lamp.shadow_buffer_type == 'DEEP':
|
||||
col.itemR(lamp, "compression_threshold")
|
||||
|
||||
elif lamp.shadow_buffer_type == 'IRREGULAR':
|
||||
layout.itemR(lamp, "shadow_buffer_bias", text="Bias")
|
||||
|
||||
row = layout.row()
|
||||
row.itemR(lamp, "auto_clip_start", text="Autoclip Start")
|
||||
sub = row.row()
|
||||
sub.active = not lamp.auto_clip_start
|
||||
sub.itemR(lamp, "shadow_buffer_clip_start", text="Clip Start")
|
||||
|
||||
row = layout.row()
|
||||
row.itemR(lamp, "auto_clip_end", text="Autoclip End")
|
||||
sub = row.row()
|
||||
sub.active = not lamp.auto_clip_end
|
||||
sub.itemR(lamp, "shadow_buffer_clip_end", text=" Clip End")
|
||||
|
||||
class DATA_PT_area(DataButtonsPanel):
|
||||
__label__ = "Area Shape"
|
||||
|
||||
def poll(self, context):
|
||||
lamp = context.lamp
|
||||
return (lamp and lamp.type == 'AREA')
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
lamp = context.lamp
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.row().itemR(lamp, "shape", expand=True)
|
||||
|
||||
sub = col.column(align=True)
|
||||
if (lamp.shape == 'SQUARE'):
|
||||
sub.itemR(lamp, "size")
|
||||
elif (lamp.shape == 'RECTANGLE'):
|
||||
sub.itemR(lamp, "size", text="Size X")
|
||||
sub.itemR(lamp, "size_y", text="Size Y")
|
||||
|
||||
class DATA_PT_spot(DataButtonsPanel):
|
||||
__label__ = "Spot Shape"
|
||||
|
||||
def poll(self, context):
|
||||
lamp = context.lamp
|
||||
return (lamp and lamp.type == 'SPOT')
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
lamp = context.lamp
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
sub = col.column()
|
||||
sub.itemR(lamp, "spot_size", text="Size")
|
||||
sub.itemR(lamp, "spot_blend", text="Blend", slider=True)
|
||||
col.itemR(lamp, "square")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(lamp, "halo")
|
||||
sub = col.column(align=True)
|
||||
sub.active = lamp.halo
|
||||
sub.itemR(lamp, "halo_intensity", text="Intensity")
|
||||
if lamp.shadow_method == 'BUFFER_SHADOW':
|
||||
sub.itemR(lamp, "halo_step", text="Step")
|
||||
|
||||
class DATA_PT_falloff_curve(DataButtonsPanel):
|
||||
__label__ = "Falloff Curve"
|
||||
__default_closed__ = True
|
||||
|
||||
def poll(self, context):
|
||||
lamp = context.lamp
|
||||
|
||||
return (lamp and lamp.type in ('POINT', 'SPOT') and lamp.falloff_type == 'CUSTOM_CURVE')
|
||||
|
||||
def draw(self, context):
|
||||
lamp = context.lamp
|
||||
|
||||
self.layout.template_curve_mapping(lamp, "falloff_curve")
|
||||
|
||||
bpy.types.register(DATA_PT_context_lamp)
|
||||
bpy.types.register(DATA_PT_preview)
|
||||
bpy.types.register(DATA_PT_lamp)
|
||||
bpy.types.register(DATA_PT_falloff_curve)
|
||||
bpy.types.register(DATA_PT_area)
|
||||
bpy.types.register(DATA_PT_spot)
|
||||
bpy.types.register(DATA_PT_shadow)
|
||||
bpy.types.register(DATA_PT_sunsky)
|
@ -1,56 +0,0 @@
|
||||
|
||||
import bpy
|
||||
|
||||
class DataButtonsPanel(bpy.types.Panel):
|
||||
__space_type__ = 'PROPERTIES'
|
||||
__region_type__ = 'WINDOW'
|
||||
__context__ = "data"
|
||||
|
||||
def poll(self, context):
|
||||
return context.lattice
|
||||
|
||||
class DATA_PT_context_lattice(DataButtonsPanel):
|
||||
__show_header__ = False
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
ob = context.object
|
||||
lat = context.lattice
|
||||
space = context.space_data
|
||||
|
||||
split = layout.split(percentage=0.65)
|
||||
|
||||
if ob:
|
||||
split.template_ID(ob, "data")
|
||||
split.itemS()
|
||||
elif lat:
|
||||
split.template_ID(space, "pin_id")
|
||||
split.itemS()
|
||||
|
||||
class DATA_PT_lattice(DataButtonsPanel):
|
||||
__label__ = "Lattice"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
lat = context.lattice
|
||||
|
||||
row = layout.row()
|
||||
row.itemR(lat, "points_u")
|
||||
row.itemR(lat, "interpolation_type_u", expand=True)
|
||||
|
||||
row = layout.row()
|
||||
row.itemR(lat, "points_v")
|
||||
row.itemR(lat, "interpolation_type_v", expand=True)
|
||||
|
||||
row = layout.row()
|
||||
row.itemR(lat, "points_w")
|
||||
row.itemR(lat, "interpolation_type_w", expand=True)
|
||||
|
||||
row = layout.row()
|
||||
row.itemO("lattice.make_regular")
|
||||
row.itemR(lat, "outside")
|
||||
|
||||
bpy.types.register(DATA_PT_context_lattice)
|
||||
bpy.types.register(DATA_PT_lattice)
|
@ -1,242 +0,0 @@
|
||||
|
||||
import bpy
|
||||
|
||||
class DataButtonsPanel(bpy.types.Panel):
|
||||
__space_type__ = 'PROPERTIES'
|
||||
__region_type__ = 'WINDOW'
|
||||
__context__ = "data"
|
||||
|
||||
def poll(self, context):
|
||||
return context.mesh
|
||||
|
||||
class DATA_PT_context_mesh(DataButtonsPanel):
|
||||
__show_header__ = False
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
ob = context.object
|
||||
mesh = context.mesh
|
||||
space = context.space_data
|
||||
|
||||
split = layout.split(percentage=0.65)
|
||||
|
||||
if ob:
|
||||
split.template_ID(ob, "data")
|
||||
split.itemS()
|
||||
elif mesh:
|
||||
split.template_ID(space, "pin_id")
|
||||
split.itemS()
|
||||
|
||||
class DATA_PT_normals(DataButtonsPanel):
|
||||
__label__ = "Normals"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
mesh = context.mesh
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemR(mesh, "autosmooth")
|
||||
sub = col.column()
|
||||
sub.active = mesh.autosmooth
|
||||
sub.itemR(mesh, "autosmooth_angle", text="Angle")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(mesh, "vertex_normal_flip")
|
||||
col.itemR(mesh, "double_sided")
|
||||
|
||||
class DATA_PT_settings(DataButtonsPanel):
|
||||
__label__ = "Settings"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
mesh = context.mesh
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemR(mesh, "texture_mesh")
|
||||
|
||||
class DATA_PT_vertex_groups(DataButtonsPanel):
|
||||
__label__ = "Vertex Groups"
|
||||
|
||||
def poll(self, context):
|
||||
return (context.object and context.object.type in ('MESH', 'LATTICE'))
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
ob = context.object
|
||||
group = ob.active_vertex_group
|
||||
|
||||
rows = 2
|
||||
if group:
|
||||
rows= 5
|
||||
|
||||
row = layout.row()
|
||||
row.template_list(ob, "vertex_groups", ob, "active_vertex_group_index", rows=rows)
|
||||
|
||||
col = row.column(align=True)
|
||||
col.itemO("object.vertex_group_add", icon='ICON_ZOOMIN', text="")
|
||||
col.itemO("object.vertex_group_remove", icon='ICON_ZOOMOUT', text="")
|
||||
|
||||
col.itemO("object.vertex_group_copy", icon='ICON_COPY_ID', text="")
|
||||
if ob.data.users > 1:
|
||||
col.itemO("object.vertex_group_copy_to_linked", icon='ICON_LINK_AREA', text="")
|
||||
|
||||
if group:
|
||||
row = layout.row()
|
||||
row.itemR(group, "name")
|
||||
|
||||
if ob.mode == 'EDIT' and len(ob.vertex_groups) > 0:
|
||||
row = layout.row()
|
||||
|
||||
sub = row.row(align=True)
|
||||
sub.itemO("object.vertex_group_assign", text="Assign")
|
||||
sub.itemO("object.vertex_group_remove_from", text="Remove")
|
||||
|
||||
sub = row.row(align=True)
|
||||
sub.itemO("object.vertex_group_select", text="Select")
|
||||
sub.itemO("object.vertex_group_deselect", text="Deselect")
|
||||
|
||||
layout.itemR(context.tool_settings, "vertex_group_weight", text="Weight")
|
||||
|
||||
class DATA_PT_shape_keys(DataButtonsPanel):
|
||||
__label__ = "Shape Keys"
|
||||
|
||||
def poll(self, context):
|
||||
return (context.object and context.object.type in ('MESH', 'LATTICE', 'CURVE', 'SURFACE'))
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
ob = context.object
|
||||
key = ob.data.shape_keys
|
||||
kb = ob.active_shape_key
|
||||
|
||||
enable_edit = ob.mode != 'EDIT'
|
||||
enable_edit_value = False
|
||||
|
||||
if ob.shape_key_lock == False:
|
||||
if enable_edit or (ob.type == 'MESH' and ob.shape_key_edit_mode):
|
||||
enable_edit_value = True
|
||||
|
||||
row = layout.row()
|
||||
|
||||
rows = 2
|
||||
if kb:
|
||||
rows= 5
|
||||
row.template_list(key, "keys", ob, "active_shape_key_index", rows=rows)
|
||||
|
||||
col = row.column()
|
||||
|
||||
subcol = col.column(align=True)
|
||||
subcol.itemO("object.shape_key_add", icon='ICON_ZOOMIN', text="")
|
||||
subcol.itemO("object.shape_key_remove", icon='ICON_ZOOMOUT', text="")
|
||||
|
||||
if kb:
|
||||
col.itemS()
|
||||
|
||||
subcol = col.column(align=True)
|
||||
subcol.item_enumO("object.shape_key_move", "type", 'UP', icon='ICON_TRIA_UP', text="")
|
||||
subcol.item_enumO("object.shape_key_move", "type", 'DOWN', icon='ICON_TRIA_DOWN', text="")
|
||||
|
||||
split = layout.split(percentage=0.4)
|
||||
sub = split.row()
|
||||
sub.enabled = enable_edit
|
||||
sub.itemR(key, "relative")
|
||||
|
||||
sub = split.row()
|
||||
sub.alignment = 'RIGHT'
|
||||
|
||||
subrow = sub.row(align=True)
|
||||
subrow.active= enable_edit_value
|
||||
subrow.itemR(ob, "shape_key_lock", icon='ICON_UNPINNED', text="")
|
||||
subrow.itemR(kb, "mute", icon='ICON_MUTE_IPO_OFF', text="")
|
||||
subrow.itemO("object.shape_key_clear", icon='ICON_X', text="")
|
||||
|
||||
sub.itemO("object.shape_key_mirror", icon='ICON_MOD_MIRROR', text="")
|
||||
|
||||
sub.itemR(ob, "shape_key_edit_mode", text="")
|
||||
|
||||
row = layout.row()
|
||||
row.itemR(kb, "name")
|
||||
|
||||
if key.relative:
|
||||
if ob.active_shape_key_index != 0:
|
||||
row = layout.row()
|
||||
row.active = enable_edit_value
|
||||
row.itemR(kb, "value")
|
||||
|
||||
split = layout.split()
|
||||
sub = split.column(align=True)
|
||||
sub.active = enable_edit_value
|
||||
sub.itemL(text="Range:")
|
||||
sub.itemR(kb, "slider_min", text="Min")
|
||||
sub.itemR(kb, "slider_max", text="Max")
|
||||
|
||||
sub = split.column(align=True)
|
||||
sub.active = enable_edit_value
|
||||
sub.itemL(text="Blend:")
|
||||
sub.item_pointerR(kb, "vertex_group", ob, "vertex_groups", text="")
|
||||
sub.item_pointerR(kb, "relative_key", key, "keys", text="")
|
||||
|
||||
else:
|
||||
row = layout.row()
|
||||
row.active = enable_edit_value
|
||||
row.itemR(key, "slurph")
|
||||
|
||||
class DATA_PT_uv_texture(DataButtonsPanel):
|
||||
__label__ = "UV Texture"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
me = context.mesh
|
||||
|
||||
row = layout.row()
|
||||
col = row.column()
|
||||
|
||||
col.template_list(me, "uv_textures", me, "active_uv_texture_index", rows=2)
|
||||
|
||||
col = row.column(align=True)
|
||||
col.itemO("mesh.uv_texture_add", icon='ICON_ZOOMIN', text="")
|
||||
col.itemO("mesh.uv_texture_remove", icon='ICON_ZOOMOUT', text="")
|
||||
|
||||
lay = me.active_uv_texture
|
||||
if lay:
|
||||
layout.itemR(lay, "name")
|
||||
|
||||
class DATA_PT_vertex_colors(DataButtonsPanel):
|
||||
__label__ = "Vertex Colors"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
me = context.mesh
|
||||
|
||||
row = layout.row()
|
||||
col = row.column()
|
||||
|
||||
col.template_list(me, "vertex_colors", me, "active_vertex_color_index", rows=2)
|
||||
|
||||
col = row.column(align=True)
|
||||
col.itemO("mesh.vertex_color_add", icon='ICON_ZOOMIN', text="")
|
||||
col.itemO("mesh.vertex_color_remove", icon='ICON_ZOOMOUT', text="")
|
||||
|
||||
lay = me.active_vertex_color
|
||||
if lay:
|
||||
layout.itemR(lay, "name")
|
||||
|
||||
bpy.types.register(DATA_PT_context_mesh)
|
||||
bpy.types.register(DATA_PT_normals)
|
||||
bpy.types.register(DATA_PT_settings)
|
||||
bpy.types.register(DATA_PT_vertex_groups)
|
||||
bpy.types.register(DATA_PT_shape_keys)
|
||||
bpy.types.register(DATA_PT_uv_texture)
|
||||
bpy.types.register(DATA_PT_vertex_colors)
|
||||
|
@ -1,106 +0,0 @@
|
||||
import bpy
|
||||
|
||||
class DataButtonsPanel(bpy.types.Panel):
|
||||
__space_type__ = 'PROPERTIES'
|
||||
__region_type__ = 'WINDOW'
|
||||
__context__ = "data"
|
||||
|
||||
def poll(self, context):
|
||||
return context.meta_ball
|
||||
|
||||
class DATA_PT_context_metaball(DataButtonsPanel):
|
||||
__show_header__ = False
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
ob = context.object
|
||||
mball = context.meta_ball
|
||||
space = context.space_data
|
||||
|
||||
split = layout.split(percentage=0.65)
|
||||
|
||||
if ob:
|
||||
split.template_ID(ob, "data")
|
||||
split.itemS()
|
||||
elif mball:
|
||||
split.template_ID(space, "pin_id")
|
||||
split.itemS()
|
||||
|
||||
class DATA_PT_metaball(DataButtonsPanel):
|
||||
__label__ = "Metaball"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
mball = context.meta_ball
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Resolution:")
|
||||
sub = col.column(align=True)
|
||||
sub.itemR(mball, "wire_size", text="View")
|
||||
sub.itemR(mball, "render_size", text="Render")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Settings:")
|
||||
col.itemR(mball, "threshold", text="Threshold")
|
||||
|
||||
layout.itemL(text="Update:")
|
||||
layout.itemR(mball, "flag", expand=True)
|
||||
|
||||
class DATA_PT_metaball_element(DataButtonsPanel):
|
||||
__label__ = "Active Element"
|
||||
|
||||
def poll(self, context):
|
||||
return (context.meta_ball and context.meta_ball.active_element)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
metaelem = context.meta_ball.active_element
|
||||
|
||||
split = layout.split(percentage=0.3)
|
||||
split.itemL(text="Type:")
|
||||
split.itemR(metaelem, "type", text="")
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Settings:")
|
||||
col.itemR(metaelem, "stiffness", text="Stiffness")
|
||||
col.itemR(metaelem, "negative", text="Negative")
|
||||
col.itemR(metaelem, "hide", text="Hide")
|
||||
|
||||
if metaelem.type == 'BALL':
|
||||
col = split.column(align=True)
|
||||
|
||||
elif metaelem.type == 'CUBE':
|
||||
col = split.column(align=True)
|
||||
col.itemL(text="Size:")
|
||||
col.itemR(metaelem, "size_x", text="X")
|
||||
col.itemR(metaelem, "size_y", text="Y")
|
||||
col.itemR(metaelem, "size_z", text="Z")
|
||||
|
||||
elif metaelem.type == 'TUBE':
|
||||
col = split.column(align=True)
|
||||
col.itemL(text="Size:")
|
||||
col.itemR(metaelem, "size_x", text="X")
|
||||
|
||||
elif metaelem.type == 'PLANE':
|
||||
col = split.column(align=True)
|
||||
col.itemL(text="Size:")
|
||||
col.itemR(metaelem, "size_x", text="X")
|
||||
col.itemR(metaelem, "size_y", text="Y")
|
||||
|
||||
elif metaelem.type == 'ELLIPSOID':
|
||||
col = split.column(align=True)
|
||||
col.itemL(text="Size:")
|
||||
col.itemR(metaelem, "size_x", text="X")
|
||||
col.itemR(metaelem, "size_y", text="Y")
|
||||
col.itemR(metaelem, "size_z", text="Z")
|
||||
|
||||
bpy.types.register(DATA_PT_context_metaball)
|
||||
bpy.types.register(DATA_PT_metaball)
|
||||
bpy.types.register(DATA_PT_metaball_element)
|
@ -1,449 +0,0 @@
|
||||
|
||||
import bpy
|
||||
|
||||
class DataButtonsPanel(bpy.types.Panel):
|
||||
__space_type__ = 'PROPERTIES'
|
||||
__region_type__ = 'WINDOW'
|
||||
__context__ = "modifier"
|
||||
|
||||
class DATA_PT_modifiers(DataButtonsPanel):
|
||||
__label__ = "Modifiers"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
ob = context.object
|
||||
|
||||
row = layout.row()
|
||||
row.item_menu_enumO("object.modifier_add", "type")
|
||||
row.itemL()
|
||||
|
||||
for md in ob.modifiers:
|
||||
box = layout.template_modifier(md)
|
||||
if box:
|
||||
# match enum type to our functions, avoids a lookup table.
|
||||
getattr(self, md.type)(box, ob, md)
|
||||
|
||||
# the mt.type enum is (ab)used for a lookup on function names
|
||||
# ...to avoid lengthy if statements
|
||||
# so each type must have a function here.
|
||||
|
||||
def ARMATURE(self, layout, ob, md):
|
||||
layout.itemR(md, "object")
|
||||
|
||||
split = layout.split(percentage=0.5)
|
||||
split.itemL(text="Vertex Group:")
|
||||
sub = split.split(percentage=0.7)
|
||||
sub.item_pointerR(md, "vertex_group", ob, "vertex_groups", text="")
|
||||
subsub = sub.row()
|
||||
subsub.active = md.vertex_group
|
||||
subsub.itemR(md, "invert")
|
||||
|
||||
layout.itemS()
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Bind To:")
|
||||
col.itemR(md, "use_vertex_groups", text="Vertex Groups")
|
||||
col.itemR(md, "use_bone_envelopes", text="Bone Envelopes")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Deformation:")
|
||||
col.itemR(md, "quaternion")
|
||||
col.itemR(md, "multi_modifier")
|
||||
|
||||
def ARRAY(self, layout, ob, md):
|
||||
layout.itemR(md, "fit_type")
|
||||
if md.fit_type == 'FIXED_COUNT':
|
||||
layout.itemR(md, "count")
|
||||
elif md.fit_type == 'FIT_LENGTH':
|
||||
layout.itemR(md, "length")
|
||||
elif md.fit_type == 'FIT_CURVE':
|
||||
layout.itemR(md, "curve")
|
||||
|
||||
layout.itemS()
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemR(md, "constant_offset")
|
||||
sub = col.column()
|
||||
sub.active = md.constant_offset
|
||||
sub.itemR(md, "constant_offset_displacement", text="")
|
||||
|
||||
col.itemS()
|
||||
|
||||
col.itemR(md, "merge_adjacent_vertices", text="Merge")
|
||||
sub = col.column()
|
||||
sub.active = md.merge_adjacent_vertices
|
||||
sub.itemR(md, "merge_end_vertices", text="First Last")
|
||||
sub.itemR(md, "merge_distance", text="Distance")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(md, "relative_offset")
|
||||
sub = col.column()
|
||||
sub.active = md.relative_offset
|
||||
sub.itemR(md, "relative_offset_displacement", text="")
|
||||
|
||||
col.itemS()
|
||||
|
||||
col.itemR(md, "add_offset_object")
|
||||
sub = col.column()
|
||||
sub.active = md.add_offset_object
|
||||
sub.itemR(md, "offset_object", text="")
|
||||
|
||||
layout.itemS()
|
||||
|
||||
col = layout.column()
|
||||
col.itemR(md, "start_cap")
|
||||
col.itemR(md, "end_cap")
|
||||
|
||||
def BEVEL(self, layout, ob, md):
|
||||
row = layout.row()
|
||||
row.itemR(md, "width")
|
||||
row.itemR(md, "only_vertices")
|
||||
|
||||
layout.itemL(text="Limit Method:")
|
||||
layout.row().itemR(md, "limit_method", expand=True)
|
||||
if md.limit_method == 'ANGLE':
|
||||
layout.itemR(md, "angle")
|
||||
elif md.limit_method == 'WEIGHT':
|
||||
layout.row().itemR(md, "edge_weight_method", expand=True)
|
||||
|
||||
def BOOLEAN(self, layout, ob, md):
|
||||
layout.itemR(md, "operation")
|
||||
layout.itemR(md, "object")
|
||||
|
||||
def BUILD(self, layout, ob, md):
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemR(md, "start")
|
||||
col.itemR(md, "length")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(md, "randomize")
|
||||
sub = col.column()
|
||||
sub.active = md.randomize
|
||||
sub.itemR(md, "seed")
|
||||
|
||||
def CAST(self, layout, ob, md):
|
||||
layout.itemR(md, "cast_type")
|
||||
layout.itemR(md, "object")
|
||||
if md.object:
|
||||
layout.itemR(md, "use_transform")
|
||||
|
||||
flow = layout.column_flow()
|
||||
flow.itemR(md, "x")
|
||||
flow.itemR(md, "y")
|
||||
flow.itemR(md, "z")
|
||||
flow.itemR(md, "factor")
|
||||
flow.itemR(md, "radius")
|
||||
flow.itemR(md, "size")
|
||||
|
||||
layout.itemR(md, "from_radius")
|
||||
|
||||
layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
|
||||
|
||||
def CLOTH(self, layout, ob, md):
|
||||
layout.itemL(text="See Cloth panel.")
|
||||
|
||||
def COLLISION(self, layout, ob, md):
|
||||
layout.itemL(text="See Collision panel.")
|
||||
|
||||
def CURVE(self, layout, ob, md):
|
||||
layout.itemR(md, "object")
|
||||
layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
|
||||
layout.itemR(md, "deform_axis")
|
||||
|
||||
def DECIMATE(self, layout, ob, md):
|
||||
layout.itemR(md, "ratio")
|
||||
layout.itemR(md, "face_count")
|
||||
|
||||
def DISPLACE(self, layout, ob, md):
|
||||
layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
|
||||
layout.itemR(md, "texture")
|
||||
layout.itemR(md, "midlevel")
|
||||
layout.itemR(md, "strength")
|
||||
layout.itemR(md, "direction")
|
||||
layout.itemR(md, "texture_coordinates")
|
||||
if md.texture_coordinates == 'OBJECT':
|
||||
layout.itemR(md, "texture_coordinate_object", text="Object")
|
||||
elif md.texture_coordinates == 'UV' and ob.type == 'MESH':
|
||||
layout.item_pointerR(md, "uv_layer", ob.data, "uv_textures")
|
||||
|
||||
def EDGE_SPLIT(self, layout, ob, md):
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemR(md, "use_edge_angle", text="Edge Angle")
|
||||
sub = col.column()
|
||||
sub.active = md.use_edge_angle
|
||||
sub.itemR(md, "split_angle")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(md, "use_sharp", text="Sharp Edges")
|
||||
|
||||
def EXPLODE(self, layout, ob, md):
|
||||
layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
|
||||
layout.itemR(md, "protect")
|
||||
|
||||
flow = layout.column_flow(2)
|
||||
flow.itemR(md, "split_edges")
|
||||
flow.itemR(md, "unborn")
|
||||
flow.itemR(md, "alive")
|
||||
flow.itemR(md, "dead")
|
||||
|
||||
layout.itemO("object.explode_refresh", text="Refresh");
|
||||
|
||||
def FLUID_SIMULATION(self, layout, ob, md):
|
||||
layout.itemL(text="See Fluid panel.")
|
||||
|
||||
def HOOK(self, layout, ob, md):
|
||||
col = layout.column()
|
||||
col.itemR(md, "object")
|
||||
if md.object and md.object.type == 'ARMATURE':
|
||||
layout.item_pointerR(md, "subtarget", md.object.data, "bones", text="Bone")
|
||||
|
||||
layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
|
||||
|
||||
split = layout.split()
|
||||
split.itemR(md, "falloff")
|
||||
split.itemR(md, "force", slider=True)
|
||||
|
||||
layout.itemS()
|
||||
|
||||
row = layout.row()
|
||||
row.itemO("object.hook_reset", text="Reset")
|
||||
row.itemO("object.hook_recenter", text="Recenter")
|
||||
|
||||
if ob.mode == 'EDIT':
|
||||
row = layout.row()
|
||||
row.itemO("object.hook_select", text="Select")
|
||||
row.itemO("object.hook_assign", text="Assign")
|
||||
|
||||
def LATTICE(self, layout, ob, md):
|
||||
layout.itemR(md, "object")
|
||||
layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
|
||||
|
||||
def MASK(self, layout, ob, md):
|
||||
layout.itemR(md, "mode")
|
||||
if md.mode == 'ARMATURE':
|
||||
layout.itemR(md, "armature")
|
||||
elif md.mode == 'VERTEX_GROUP':
|
||||
layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
|
||||
layout.itemR(md, "inverse")
|
||||
|
||||
def MESH_DEFORM(self, layout, ob, md):
|
||||
layout.itemR(md, "object")
|
||||
layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
|
||||
layout.itemR(md, "invert")
|
||||
|
||||
layout.itemS()
|
||||
|
||||
if md.is_bound:
|
||||
layout.itemO("object.meshdeform_bind", text="Unbind")
|
||||
else:
|
||||
layout.itemO("object.meshdeform_bind", text="Bind")
|
||||
row = layout.row()
|
||||
row.itemR(md, "precision")
|
||||
row.itemR(md, "dynamic")
|
||||
|
||||
def MIRROR(self, layout, ob, md):
|
||||
layout.itemR(md, "merge_limit")
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemR(md, "x")
|
||||
col.itemR(md, "y")
|
||||
col.itemR(md, "z")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Textures:")
|
||||
col.itemR(md, "mirror_u")
|
||||
col.itemR(md, "mirror_v")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(md, "clip", text="Do Clipping")
|
||||
col.itemR(md, "mirror_vertex_groups", text="Vertex Group")
|
||||
|
||||
layout.itemR(md, "mirror_object")
|
||||
|
||||
def MULTIRES(self, layout, ob, md):
|
||||
layout.itemR(md, "subdivision_type")
|
||||
|
||||
row = layout.row()
|
||||
row.itemO("object.multires_subdivide", text="Subdivide")
|
||||
row.itemO("object.multires_higher_levels_delete", text="Delete Higher")
|
||||
|
||||
layout.itemR(md, "level")
|
||||
|
||||
def PARTICLE_INSTANCE(self, layout, ob, md):
|
||||
layout.itemR(md, "object")
|
||||
layout.itemR(md, "particle_system_number")
|
||||
|
||||
flow = layout.column_flow()
|
||||
flow.itemR(md, "normal")
|
||||
flow.itemR(md, "children")
|
||||
flow.itemR(md, "size")
|
||||
flow.itemR(md, "path")
|
||||
if md.path:
|
||||
flow.itemR(md, "keep_shape")
|
||||
flow.itemR(md, "unborn")
|
||||
flow.itemR(md, "alive")
|
||||
flow.itemR(md, "dead")
|
||||
flow.itemL(md, "")
|
||||
if md.path:
|
||||
flow.itemR(md, "axis", text="")
|
||||
|
||||
if md.path:
|
||||
row = layout.row()
|
||||
row.itemR(md, "position", slider=True)
|
||||
row.itemR(md, "random_position", text = "Random", slider=True)
|
||||
|
||||
def PARTICLE_SYSTEM(self, layout, ob, md):
|
||||
layout.itemL(text="See Particle panel.")
|
||||
|
||||
def SHRINKWRAP(self, layout, ob, md):
|
||||
layout.itemR(md, "target")
|
||||
layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
|
||||
layout.itemR(md, "offset")
|
||||
layout.itemR(md, "subsurf_levels")
|
||||
layout.itemR(md, "mode")
|
||||
if md.mode == 'PROJECT':
|
||||
layout.itemR(md, "subsurf_levels")
|
||||
layout.itemR(md, "auxiliary_target")
|
||||
|
||||
row = layout.row()
|
||||
row.itemR(md, "x")
|
||||
row.itemR(md, "y")
|
||||
row.itemR(md, "z")
|
||||
|
||||
flow = layout.column_flow()
|
||||
flow.itemR(md, "negative")
|
||||
flow.itemR(md, "positive")
|
||||
flow.itemR(md, "cull_front_faces")
|
||||
flow.itemR(md, "cull_back_faces")
|
||||
elif md.mode == 'NEAREST_SURFACEPOINT':
|
||||
layout.itemR(md, "keep_above_surface")
|
||||
|
||||
def SIMPLE_DEFORM(self, layout, ob, md):
|
||||
layout.itemR(md, "mode")
|
||||
layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
|
||||
layout.itemR(md, "origin")
|
||||
layout.itemR(md, "relative")
|
||||
layout.itemR(md, "factor")
|
||||
layout.itemR(md, "limits")
|
||||
if md.mode in ('TAPER', 'STRETCH'):
|
||||
layout.itemR(md, "lock_x_axis")
|
||||
layout.itemR(md, "lock_y_axis")
|
||||
|
||||
def SMOKE(self, layout, ob, md):
|
||||
layout.itemL(text="See Smoke panel.")
|
||||
|
||||
def SMOOTH(self, layout, ob, md):
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemR(md, "x")
|
||||
col.itemR(md, "y")
|
||||
col.itemR(md, "z")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(md, "factor")
|
||||
col.itemR(md, "repeat")
|
||||
|
||||
layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
|
||||
|
||||
def SOFT_BODY(self, layout, ob, md):
|
||||
layout.itemL(text="See Soft Body panel.")
|
||||
|
||||
def SUBSURF(self, layout, ob, md):
|
||||
layout.row().itemR(md, "subdivision_type", expand=True)
|
||||
|
||||
flow = layout.column_flow()
|
||||
flow.itemR(md, "levels", text="Preview")
|
||||
flow.itemR(md, "render_levels", text="Render")
|
||||
flow.itemR(md, "optimal_draw", text="Optimal Display")
|
||||
flow.itemR(md, "subsurf_uv")
|
||||
|
||||
def SURFACE(self, layout, ob, md):
|
||||
layout.itemL(text="See Fields panel.")
|
||||
|
||||
def UV_PROJECT(self, layout, ob, md):
|
||||
if ob.type == 'MESH':
|
||||
layout.item_pointerR(md, "uv_layer", ob.data, "uv_textures")
|
||||
layout.itemR(md, "image")
|
||||
layout.itemR(md, "override_image")
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Aspect Ratio:")
|
||||
|
||||
sub = col.column(align=True)
|
||||
sub.itemR(md, "horizontal_aspect_ratio", text="Horizontal")
|
||||
sub.itemR(md, "vertical_aspect_ratio", text="Vertical")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Projectors:")
|
||||
|
||||
sub = col.column(align=True)
|
||||
sub.itemR(md, "num_projectors", text="Number")
|
||||
for proj in md.projectors:
|
||||
sub.itemR(proj, "object", text="")
|
||||
|
||||
def WAVE(self, layout, ob, md):
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Motion:")
|
||||
col.itemR(md, "x")
|
||||
col.itemR(md, "y")
|
||||
col.itemR(md, "cyclic")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(md, "normals")
|
||||
sub = col.column()
|
||||
sub.active = md.normals
|
||||
sub.itemR(md, "x_normal", text="X")
|
||||
sub.itemR(md, "y_normal", text="Y")
|
||||
sub.itemR(md, "z_normal", text="Z")
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Time:")
|
||||
sub = col.column(align=True)
|
||||
sub.itemR(md, "time_offset", text="Offset")
|
||||
sub.itemR(md, "lifetime", text="Life")
|
||||
col.itemR(md, "damping_time", text="Damping")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Position:")
|
||||
sub = col.column(align=True)
|
||||
sub.itemR(md, "start_position_x", text="X")
|
||||
sub.itemR(md, "start_position_y", text="Y")
|
||||
col.itemR(md, "falloff_radius", text="Falloff")
|
||||
|
||||
layout.itemS()
|
||||
|
||||
layout.itemR(md, "start_position_object")
|
||||
layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
|
||||
layout.itemR(md, "texture")
|
||||
layout.itemR(md, "texture_coordinates")
|
||||
if md.texture_coordinates == 'MAP_UV' and ob.type == 'MESH':
|
||||
layout.item_pointerR(md, "uv_layer", ob.data, "uv_textures")
|
||||
elif md.texture_coordinates == 'OBJECT':
|
||||
layout.itemR(md, "texture_coordinates_object")
|
||||
|
||||
layout.itemS()
|
||||
|
||||
flow = layout.column_flow()
|
||||
flow.itemR(md, "speed", slider=True)
|
||||
flow.itemR(md, "height", slider=True)
|
||||
flow.itemR(md, "width", slider=True)
|
||||
flow.itemR(md, "narrowness", slider=True)
|
||||
|
||||
bpy.types.register(DATA_PT_modifiers)
|
@ -1,179 +0,0 @@
|
||||
|
||||
import bpy
|
||||
|
||||
class DataButtonsPanel(bpy.types.Panel):
|
||||
__space_type__ = 'PROPERTIES'
|
||||
__region_type__ = 'WINDOW'
|
||||
__context__ = "data"
|
||||
|
||||
def poll(self, context):
|
||||
return (context.object and context.object.type == 'TEXT' and context.curve)
|
||||
|
||||
class DATA_PT_context_text(DataButtonsPanel):
|
||||
__show_header__ = False
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
ob = context.object
|
||||
curve = context.curve
|
||||
space = context.space_data
|
||||
|
||||
split = layout.split(percentage=0.65)
|
||||
|
||||
if ob:
|
||||
split.template_ID(ob, "data")
|
||||
split.itemS()
|
||||
elif curve:
|
||||
split.template_ID(space, "pin_id")
|
||||
split.itemS()
|
||||
|
||||
class DATA_PT_shape_text(DataButtonsPanel):
|
||||
__label__ = "Shape Text"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
ob = context.object
|
||||
curve = context.curve
|
||||
space = context.space_data
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Caps:")
|
||||
row = col.row()
|
||||
row .itemR(curve, "front")
|
||||
row .itemR(curve, "back")
|
||||
# col = split.column()
|
||||
col.itemL(text="Textures:")
|
||||
col.itemR(curve, "uv_orco")
|
||||
col.itemR(curve, "auto_texspace")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Resolution:")
|
||||
sub = col.column(align=True)
|
||||
sub.itemR(curve, "resolution_u", text="Preview")
|
||||
sub.itemR(curve, "render_resolution_u", text="Render")
|
||||
|
||||
# resolution_v is not used for text
|
||||
|
||||
sub = col.column(align=True)
|
||||
col.itemL(text="Display:")
|
||||
col.itemR(curve, "fast", text="Fast Editing")
|
||||
|
||||
class DATA_PT_geometry_text(DataButtonsPanel):
|
||||
__label__ = "Geometry"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
curve = context.curve
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Modification:")
|
||||
col.itemR(curve, "width")
|
||||
col.itemR(curve, "extrude")
|
||||
col.itemL(text="Taper Object:")
|
||||
col.itemR(curve, "taper_object", text="")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Bevel:")
|
||||
col.itemR(curve, "bevel_depth", text="Depth")
|
||||
col.itemR(curve, "bevel_resolution", text="Resolution")
|
||||
col.itemL(text="Bevel Object:")
|
||||
col.itemR(curve, "bevel_object", text="")
|
||||
|
||||
class DATA_PT_font(DataButtonsPanel):
|
||||
__label__ = "Font"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
text = context.curve
|
||||
char = context.curve.edit_format
|
||||
|
||||
layout.itemR(text, "font")
|
||||
|
||||
row = layout.row()
|
||||
row.itemR(text, "text_size", text="Size")
|
||||
row.itemR(text, "shear")
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Object Font:")
|
||||
col.itemR(text, "family", text="")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Text on Curve:")
|
||||
col.itemR(text, "text_on_curve", text="")
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Character:")
|
||||
col.itemR(char, "bold")
|
||||
col.itemR(char, "italic")
|
||||
col.itemR(char, "underline")
|
||||
# col.itemR(char, "style")
|
||||
# col.itemR(char, "wrap")
|
||||
|
||||
col = split.column(align=True)
|
||||
col.itemL(text="Underline:")
|
||||
col.itemR(text, "ul_position", text="Position")
|
||||
col.itemR(text, "ul_height", text="Thickness")
|
||||
|
||||
class DATA_PT_paragraph(DataButtonsPanel):
|
||||
__label__ = "Paragraph"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
text = context.curve
|
||||
|
||||
layout.itemL(text="Align:")
|
||||
layout.itemR(text, "spacemode", expand=True)
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column(align=True)
|
||||
col.itemL(text="Spacing:")
|
||||
col.itemR(text, "spacing", text="Character")
|
||||
col.itemR(text, "word_spacing", text="Word")
|
||||
col.itemR(text, "line_dist", text="Line")
|
||||
|
||||
col = split.column(align=True)
|
||||
col.itemL(text="Offset:")
|
||||
col.itemR(text, "offset_x", text="X")
|
||||
col.itemR(text, "offset_y", text="Y")
|
||||
|
||||
class DATA_PT_textboxes(DataButtonsPanel):
|
||||
__label__ = "Text Boxes"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
text = context.curve
|
||||
|
||||
for box in text.textboxes:
|
||||
split = layout.box().split()
|
||||
|
||||
col = split.column(align=True)
|
||||
col.itemL(text="Dimensions:")
|
||||
col.itemR(box, "width", text="Width")
|
||||
col.itemR(box, "height", text="Height")
|
||||
|
||||
col = split.column(align=True)
|
||||
col.itemL(text="Offset:")
|
||||
col.itemR(box, "x", text="X")
|
||||
col.itemR(box, "y", text="Y")
|
||||
|
||||
bpy.types.register(DATA_PT_context_text)
|
||||
bpy.types.register(DATA_PT_shape_text)
|
||||
bpy.types.register(DATA_PT_geometry_text)
|
||||
bpy.types.register(DATA_PT_font)
|
||||
bpy.types.register(DATA_PT_paragraph)
|
||||
bpy.types.register(DATA_PT_textboxes)
|
@ -1,416 +0,0 @@
|
||||
|
||||
import bpy
|
||||
|
||||
class PhysicsButtonsPanel(bpy.types.Panel):
|
||||
__space_type__ = 'PROPERTIES'
|
||||
__region_type__ = 'WINDOW'
|
||||
__context__ = "physics"
|
||||
|
||||
def poll(self, context):
|
||||
ob = context.active_object
|
||||
rd = context.scene.render_data
|
||||
return ob and ob.game and (rd.engine == 'BLENDER_GAME')
|
||||
|
||||
class PHYSICS_PT_game_physics(PhysicsButtonsPanel):
|
||||
__label__ = "Physics"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
ob = context.active_object
|
||||
game = ob.game
|
||||
soft = ob.game.soft_body
|
||||
|
||||
layout.itemR(game, "physics_type")
|
||||
layout.itemS()
|
||||
|
||||
#if game.physics_type == 'DYNAMIC':
|
||||
if game.physics_type in ('DYNAMIC', 'RIGID_BODY'):
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemR(game, "actor")
|
||||
col.itemR(game, "ghost")
|
||||
col.itemR(ob, "restrict_render", text="Invisible") # out of place but useful
|
||||
|
||||
col = split.column()
|
||||
col.itemR(game, "material_physics")
|
||||
col.itemR(game, "rotate_from_normal")
|
||||
col.itemR(game, "no_sleeping")
|
||||
|
||||
layout.itemS()
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Attributes:")
|
||||
col.itemR(game, "mass")
|
||||
col.itemR(game, "radius")
|
||||
col.itemR(game, "form_factor")
|
||||
|
||||
col = split.column()
|
||||
sub = col.column()
|
||||
sub.active = (game.physics_type == 'RIGID_BODY')
|
||||
sub.itemR(game, "anisotropic_friction")
|
||||
subsub = sub.column()
|
||||
subsub.active = game.anisotropic_friction
|
||||
subsub.itemR(game, "friction_coefficients", text="", slider=True)
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Velocity:")
|
||||
sub = col.column(align=True)
|
||||
sub.itemR(game, "minimum_velocity", text="Minimum")
|
||||
sub.itemR(game, "maximum_velocity", text="Maximum")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Damping:")
|
||||
sub = col.column(align=True)
|
||||
sub.itemR(game, "damping", text="Translation", slider=True)
|
||||
sub.itemR(game, "rotation_damping", text="Rotation", slider=True)
|
||||
|
||||
layout.itemS()
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Lock Translation:")
|
||||
col.itemR(game, "lock_x_axis", text="X")
|
||||
col.itemR(game, "lock_y_axis", text="Y")
|
||||
col.itemR(game, "lock_z_axis", text="Z")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Lock Rotation:")
|
||||
col.itemR(game, "lock_x_rot_axis", text="X")
|
||||
col.itemR(game, "lock_y_rot_axis", text="Y")
|
||||
col.itemR(game, "lock_z_rot_axis", text="Z")
|
||||
|
||||
elif game.physics_type == 'SOFT_BODY':
|
||||
col = layout.column()
|
||||
col.itemR(game, "actor")
|
||||
col.itemR(game, "ghost")
|
||||
col.itemR(ob, "restrict_render", text="Invisible")
|
||||
|
||||
layout.itemS()
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Attributes:")
|
||||
col.itemR(game, "mass")
|
||||
col.itemR(soft, "welding")
|
||||
col.itemR(soft, "position_iterations")
|
||||
col.itemR(soft, "linstiff", slider=True)
|
||||
col.itemR(soft, "dynamic_friction", slider=True)
|
||||
col.itemR(soft, "margin", slider=True)
|
||||
col.itemR(soft, "bending_const", text="Bending Constraints")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(soft, "shape_match")
|
||||
sub = col.column()
|
||||
sub.active = soft.shape_match
|
||||
sub.itemR(soft, "threshold", slider=True)
|
||||
|
||||
col.itemS()
|
||||
|
||||
col.itemL(text="Cluster Collision:")
|
||||
col.itemR(soft, "cluster_rigid_to_softbody")
|
||||
col.itemR(soft, "cluster_soft_to_softbody")
|
||||
sub = col.column()
|
||||
sub.active = (soft.cluster_rigid_to_softbody or soft.cluster_soft_to_softbody)
|
||||
sub.itemR(soft, "cluster_iterations", text="Iterations")
|
||||
|
||||
elif game.physics_type == 'STATIC':
|
||||
col = layout.column()
|
||||
col.itemR(game, "actor")
|
||||
col.itemR(game, "ghost")
|
||||
col.itemR(ob, "restrict_render", text="Invisible")
|
||||
|
||||
elif game.physics_type in ('SENSOR', 'INVISIBLE', 'NO_COLLISION', 'OCCLUDE'):
|
||||
layout.itemR(ob, "restrict_render", text="Invisible")
|
||||
|
||||
class PHYSICS_PT_game_collision_bounds(PhysicsButtonsPanel):
|
||||
__label__ = "Collision Bounds"
|
||||
|
||||
def poll(self, context):
|
||||
game = context.object.game
|
||||
rd = context.scene.render_data
|
||||
return (game.physics_type in ('DYNAMIC', 'RIGID_BODY', 'SENSOR', 'SOFT_BODY', 'STATIC')) and (rd.engine == 'BLENDER_GAME')
|
||||
|
||||
def draw_header(self, context):
|
||||
game = context.active_object.game
|
||||
|
||||
self.layout.itemR(game, "use_collision_bounds", text="")
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
game = context.active_object.game
|
||||
|
||||
layout.active = game.use_collision_bounds
|
||||
layout.itemR(game, "collision_bounds", text="Bounds")
|
||||
|
||||
row = layout.row()
|
||||
row.itemR(game, "collision_compound", text="Compound")
|
||||
row.itemR(game, "collision_margin", text="Margin", slider=True)
|
||||
|
||||
bpy.types.register(PHYSICS_PT_game_physics)
|
||||
bpy.types.register(PHYSICS_PT_game_collision_bounds)
|
||||
|
||||
class RenderButtonsPanel(bpy.types.Panel):
|
||||
__space_type__ = 'PROPERTIES'
|
||||
__region_type__ = 'WINDOW'
|
||||
__context__ = "render"
|
||||
|
||||
def poll(self, context):
|
||||
rd = context.scene.render_data
|
||||
return (rd.engine == 'BLENDER_GAME')
|
||||
|
||||
class RENDER_PT_game(RenderButtonsPanel):
|
||||
__label__ = "Game"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
row = layout.row()
|
||||
row.itemO("view3d.game_start", text="Start")
|
||||
row.itemL()
|
||||
|
||||
class RENDER_PT_game_player(RenderButtonsPanel):
|
||||
__label__ = "Standalone Player"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
gs = context.scene.game_data
|
||||
|
||||
layout.itemR(gs, "fullscreen")
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Resolution:")
|
||||
sub = col.column(align=True)
|
||||
sub.itemR(gs, "resolution_x", slider=False, text="X")
|
||||
sub.itemR(gs, "resolution_y", slider=False, text="Y")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Quality:")
|
||||
sub = col.column(align=True)
|
||||
sub.itemR(gs, "depth", text="Bit Depth", slider=False)
|
||||
sub.itemR(gs, "frequency", text="FPS", slider=False)
|
||||
|
||||
# framing:
|
||||
col = layout.column()
|
||||
col.itemL(text="Framing:")
|
||||
col.row().itemR(gs, "framing_type", expand=True)
|
||||
if gs.framing_type == 'LETTERBOX':
|
||||
col.itemR(gs, "framing_color", text="")
|
||||
|
||||
class RENDER_PT_game_stereo(RenderButtonsPanel):
|
||||
__label__ = "Stereo"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
gs = context.scene.game_data
|
||||
stereo_mode = gs.stereo
|
||||
|
||||
# stereo options:
|
||||
layout.itemR(gs, "stereo", expand=True)
|
||||
|
||||
# stereo:
|
||||
if stereo_mode == 'STEREO':
|
||||
layout.itemR(gs, "stereo_mode")
|
||||
layout.itemL(text="To do: Focal Length")
|
||||
layout.itemL(text="To do: Eye Separation")
|
||||
|
||||
# dome:
|
||||
elif stereo_mode == 'DOME':
|
||||
layout.itemR(gs, "dome_mode", text="Dome Type")
|
||||
|
||||
dome_type = gs.dome_mode
|
||||
|
||||
split=layout.split()
|
||||
|
||||
if dome_type == 'FISHEYE' or \
|
||||
dome_type == 'TRUNCATED_REAR' or \
|
||||
dome_type == 'TRUNCATED_FRONT':
|
||||
|
||||
col=split.column()
|
||||
col.itemR(gs, "dome_angle", slider=True)
|
||||
col.itemR(gs, "dome_tilt")
|
||||
|
||||
col=split.column()
|
||||
col.itemR(gs, "dome_tesselation", text="Tesselation")
|
||||
col.itemR(gs, "dome_buffer_resolution", text="Resolution", slider=True)
|
||||
|
||||
elif dome_type == 'PANORAM_SPH':
|
||||
col=split.column()
|
||||
col.itemR(gs, "dome_tesselation", text="Tesselation")
|
||||
col.itemR(gs, "dome_buffer_resolution", text="Resolution", slider=True)
|
||||
|
||||
else: # cube map
|
||||
col=split.column()
|
||||
col.itemR(gs, "dome_buffer_resolution", text="Resolution", slider=True)
|
||||
|
||||
layout.itemR(gs, "dome_text")
|
||||
|
||||
class RENDER_PT_game_shading(RenderButtonsPanel):
|
||||
__label__ = "Shading"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
gs = context.scene.game_data
|
||||
layout.itemR(gs, "material_mode", expand=True)
|
||||
|
||||
if gs.material_mode == 'GLSL':
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemR(gs, "glsl_lights", text="Lights")
|
||||
col.itemR(gs, "glsl_shaders", text="Shaders")
|
||||
col.itemR(gs, "glsl_shadows", text="Shadows")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(gs, "glsl_ramps", text="Ramps")
|
||||
col.itemR(gs, "glsl_nodes", text="Nodes")
|
||||
col.itemR(gs, "glsl_extra_textures", text="Extra Textures")
|
||||
|
||||
class RENDER_PT_game_performance(RenderButtonsPanel):
|
||||
__label__ = "Performance"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
gs = context.scene.game_data
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Show:")
|
||||
col.itemR(gs, "show_debug_properties", text="Debug Properties")
|
||||
col.itemR(gs, "show_framerate_profile", text="Framerate and Profile")
|
||||
col.itemR(gs, "show_physics_visualization", text="Physics Visualization")
|
||||
col.itemR(gs, "deprecation_warnings")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Render:")
|
||||
col.itemR(gs, "all_frames")
|
||||
col.itemR(gs, "display_lists")
|
||||
|
||||
class RENDER_PT_game_sound(RenderButtonsPanel):
|
||||
__label__ = "Sound"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
scene = context.scene
|
||||
|
||||
layout.itemR(scene, "distance_model")
|
||||
layout.itemR(scene, "speed_of_sound", text="Speed")
|
||||
layout.itemR(scene, "doppler_factor")
|
||||
|
||||
bpy.types.register(RENDER_PT_game)
|
||||
bpy.types.register(RENDER_PT_game_player)
|
||||
bpy.types.register(RENDER_PT_game_stereo)
|
||||
bpy.types.register(RENDER_PT_game_shading)
|
||||
bpy.types.register(RENDER_PT_game_performance)
|
||||
bpy.types.register(RENDER_PT_game_sound)
|
||||
|
||||
class WorldButtonsPanel(bpy.types.Panel):
|
||||
__space_type__ = 'PROPERTIES'
|
||||
__region_type__ = 'WINDOW'
|
||||
__context__ = "world"
|
||||
|
||||
def poll(self, context):
|
||||
rd = context.scene.render_data
|
||||
return (rd.engine == 'BLENDER_GAME')
|
||||
|
||||
class WORLD_PT_game_context_world(WorldButtonsPanel):
|
||||
__show_header__ = False
|
||||
|
||||
def poll(self, context):
|
||||
rd = context.scene.render_data
|
||||
return (context.scene) and (rd.use_game_engine)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
scene = context.scene
|
||||
world = context.world
|
||||
space = context.space_data
|
||||
|
||||
split = layout.split(percentage=0.65)
|
||||
|
||||
if scene:
|
||||
split.template_ID(scene, "world", new="world.new")
|
||||
elif world:
|
||||
split.template_ID(space, "pin_id")
|
||||
|
||||
class WORLD_PT_game_world(WorldButtonsPanel):
|
||||
__label__ = "World"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
world = context.world
|
||||
|
||||
row = layout.row()
|
||||
row.column().itemR(world, "horizon_color")
|
||||
row.column().itemR(world, "ambient_color")
|
||||
|
||||
layout.itemR(world.mist, "enabled", text="Mist")
|
||||
|
||||
row = layout.column_flow()
|
||||
row.active = world.mist.enabled
|
||||
row.itemR(world.mist, "start")
|
||||
row.itemR(world.mist, "depth")
|
||||
|
||||
class WORLD_PT_game_physics(WorldButtonsPanel):
|
||||
__label__ = "Physics"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
gs = context.scene.game_data
|
||||
|
||||
layout.itemR(gs, "physics_engine")
|
||||
if gs.physics_engine != 'NONE':
|
||||
layout.itemR(gs, "physics_gravity", text="Gravity")
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Physics Steps:")
|
||||
sub = col.column(align=True)
|
||||
sub.itemR(gs, "physics_step_max", text="Max")
|
||||
sub.itemR(gs, "physics_step_sub", text="Substeps")
|
||||
col.itemR(gs, "fps", text="FPS")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Logic Steps:")
|
||||
col.itemR(gs, "logic_step_max", text="Max")
|
||||
|
||||
col = layout.column()
|
||||
col.itemR(gs, "use_occlusion_culling", text="Occlusion Culling")
|
||||
sub = col.column()
|
||||
sub.active = gs.use_occlusion_culling
|
||||
sub.itemR(gs, "occlusion_culling_resolution", text="Resolution")
|
||||
|
||||
else:
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Physics Steps:")
|
||||
col.itemR(gs, "fps", text="FPS")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Logic Steps:")
|
||||
col.itemR(gs, "logic_step_max", text="Max")
|
||||
|
||||
bpy.types.register(WORLD_PT_game_context_world)
|
||||
bpy.types.register(WORLD_PT_game_world)
|
||||
bpy.types.register(WORLD_PT_game_physics)
|
@ -1,750 +0,0 @@
|
||||
|
||||
import bpy
|
||||
|
||||
def active_node_mat(mat):
|
||||
# TODO, 2.4x has a pipeline section, for 2.5 we need to communicate
|
||||
# which settings from node-materials are used
|
||||
if mat:
|
||||
mat_node = mat.active_node_material
|
||||
if mat_node:
|
||||
return mat_node
|
||||
else:
|
||||
return mat
|
||||
|
||||
return None
|
||||
|
||||
|
||||
class MaterialButtonsPanel(bpy.types.Panel):
|
||||
__space_type__ = 'PROPERTIES'
|
||||
__region_type__ = 'WINDOW'
|
||||
__context__ = "material"
|
||||
# COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here
|
||||
|
||||
def poll(self, context):
|
||||
mat = context.material
|
||||
engine = context.scene.render_data.engine
|
||||
return mat and (engine in self.COMPAT_ENGINES)
|
||||
|
||||
class MATERIAL_PT_preview(MaterialButtonsPanel):
|
||||
__label__ = "Preview"
|
||||
COMPAT_ENGINES = set(['BLENDER_RENDER', 'BLENDER_GAME'])
|
||||
|
||||
def draw(self, context):
|
||||
self.layout.template_preview(context.material)
|
||||
|
||||
class MATERIAL_PT_context_material(MaterialButtonsPanel):
|
||||
__show_header__ = False
|
||||
COMPAT_ENGINES = set(['BLENDER_RENDER', 'BLENDER_GAME'])
|
||||
|
||||
def poll(self, context):
|
||||
# An exception, dont call the parent poll func because
|
||||
# this manages materials for all engine types
|
||||
|
||||
engine = context.scene.render_data.engine
|
||||
return (context.material or context.object) and (engine in self.COMPAT_ENGINES)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
mat = context.material
|
||||
ob = context.object
|
||||
slot = context.material_slot
|
||||
space = context.space_data
|
||||
|
||||
if ob:
|
||||
row = layout.row()
|
||||
|
||||
row.template_list(ob, "materials", ob, "active_material_index", rows=2)
|
||||
|
||||
col = row.column(align=True)
|
||||
col.itemO("object.material_slot_add", icon='ICON_ZOOMIN', text="")
|
||||
col.itemO("object.material_slot_remove", icon='ICON_ZOOMOUT', text="")
|
||||
col.itemO("object.material_slot_copy", icon='ICON_COPY_ID', text="")
|
||||
|
||||
if ob.mode == 'EDIT':
|
||||
row = layout.row(align=True)
|
||||
row.itemO("object.material_slot_assign", text="Assign")
|
||||
row.itemO("object.material_slot_select", text="Select")
|
||||
row.itemO("object.material_slot_deselect", text="Deselect")
|
||||
|
||||
split = layout.split(percentage=0.65)
|
||||
|
||||
if ob:
|
||||
split.template_ID(ob, "active_material", new="material.new")
|
||||
row = split.row()
|
||||
if slot:
|
||||
row.itemR(slot, "link", text="")
|
||||
else:
|
||||
row.itemL()
|
||||
elif mat:
|
||||
split.template_ID(space, "pin_id")
|
||||
split.itemS()
|
||||
|
||||
if mat:
|
||||
layout.itemR(mat, "type", expand=True)
|
||||
|
||||
class MATERIAL_PT_shading(MaterialButtonsPanel):
|
||||
__label__ = "Shading"
|
||||
COMPAT_ENGINES = set(['BLENDER_RENDER', 'BLENDER_GAME'])
|
||||
|
||||
def poll(self, context):
|
||||
mat = active_node_mat(context.material)
|
||||
engine = context.scene.render_data.engine
|
||||
return mat and (mat.type in ('SURFACE', 'WIRE', 'HALO')) and (engine in self.COMPAT_ENGINES)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
mat = active_node_mat(context.material)
|
||||
|
||||
if mat.type in ('SURFACE', 'WIRE'):
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
sub = col.column()
|
||||
sub.active = not mat.shadeless
|
||||
sub.itemR(mat, "emit")
|
||||
sub.itemR(mat, "ambient")
|
||||
sub = col.column()
|
||||
sub.itemR(mat, "translucency")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(mat, "shadeless")
|
||||
sub = col.column()
|
||||
sub.active = not mat.shadeless
|
||||
sub.itemR(mat, "tangent_shading")
|
||||
sub.itemR(mat, "cubic")
|
||||
|
||||
elif mat.type == 'HALO':
|
||||
layout.itemR(mat, "alpha")
|
||||
|
||||
class MATERIAL_PT_strand(MaterialButtonsPanel):
|
||||
__label__ = "Strand"
|
||||
__default_closed__ = True
|
||||
COMPAT_ENGINES = set(['BLENDER_RENDER'])
|
||||
|
||||
def poll(self, context):
|
||||
mat = context.material
|
||||
engine = context.scene.render_data.engine
|
||||
return mat and (mat.type in ('SURFACE', 'WIRE', 'HALO')) and (engine in self.COMPAT_ENGINES)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
mat = context.material # dont use node material
|
||||
tan = mat.strand
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column(align=True)
|
||||
col.itemL(text="Size:")
|
||||
col.itemR(tan, "root_size", text="Root")
|
||||
col.itemR(tan, "tip_size", text="Tip")
|
||||
col.itemR(tan, "min_size", text="Minimum")
|
||||
col.itemR(tan, "blender_units")
|
||||
sub = col.column()
|
||||
sub.active = (not mat.shadeless)
|
||||
sub.itemR(tan, "tangent_shading")
|
||||
col.itemR(tan, "shape")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Shading:")
|
||||
col.itemR(tan, "width_fade")
|
||||
ob = context.object
|
||||
if ob and ob.type == 'MESH': col.item_pointerR(tan, "uv_layer", ob.data, "uv_textures", text="")
|
||||
else: col.itemR(tan, "uv_layer", text="")
|
||||
col.itemS()
|
||||
sub = col.column()
|
||||
sub.active = (not mat.shadeless)
|
||||
sub.itemR(tan, "surface_diffuse")
|
||||
sub = col.column()
|
||||
sub.active = tan.surface_diffuse
|
||||
sub.itemR(tan, "blend_distance", text="Distance")
|
||||
|
||||
class MATERIAL_PT_physics(MaterialButtonsPanel):
|
||||
__label__ = "Physics"
|
||||
COMPAT_ENGINES = set(['BLENDER_GAME'])
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
phys = context.material.physics # dont use node material
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemR(phys, "distance")
|
||||
col.itemR(phys, "friction")
|
||||
col.itemR(phys, "align_to_normal")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(phys, "force", slider=True)
|
||||
col.itemR(phys, "elasticity", slider=True)
|
||||
col.itemR(phys, "damp", slider=True)
|
||||
|
||||
class MATERIAL_PT_options(MaterialButtonsPanel):
|
||||
__label__ = "Options"
|
||||
COMPAT_ENGINES = set(['BLENDER_RENDER', 'BLENDER_GAME'])
|
||||
|
||||
def poll(self, context):
|
||||
mat = active_node_mat(context.material)
|
||||
engine = context.scene.render_data.engine
|
||||
return mat and (mat.type in ('SURFACE', 'WIRE', 'HALO')) and (engine in self.COMPAT_ENGINES)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
mat = active_node_mat(context.material)
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemR(mat, "traceable")
|
||||
col.itemR(mat, "full_oversampling")
|
||||
col.itemR(mat, "sky")
|
||||
col.itemR(mat, "exclude_mist")
|
||||
col.itemR(mat, "invert_z")
|
||||
sub = col.row()
|
||||
sub.itemR(mat, "z_offset")
|
||||
sub.active = mat.transparency and mat.transparency_method == 'Z_TRANSPARENCY'
|
||||
sub = col.column(align=True)
|
||||
sub.itemL(text="Light Group:")
|
||||
sub.itemR(mat, "light_group", text="")
|
||||
row = sub.row()
|
||||
row.active = mat.light_group
|
||||
row.itemR(mat, "light_group_exclusive", text="Exclusive")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(mat, "face_texture")
|
||||
sub = col.column()
|
||||
sub.active = mat.face_texture
|
||||
sub.itemR(mat, "face_texture_alpha")
|
||||
col.itemS()
|
||||
col.itemR(mat, "vertex_color_paint")
|
||||
col.itemR(mat, "vertex_color_light")
|
||||
col.itemR(mat, "object_color")
|
||||
|
||||
class MATERIAL_PT_shadow(MaterialButtonsPanel):
|
||||
__label__ = "Shadow"
|
||||
__default_closed__ = True
|
||||
COMPAT_ENGINES = set(['BLENDER_RENDER', 'BLENDER_GAME'])
|
||||
|
||||
def poll(self, context):
|
||||
mat = active_node_mat(context.material)
|
||||
engine = context.scene.render_data.engine
|
||||
return mat and (mat.type in ('SURFACE', 'WIRE')) and (engine in self.COMPAT_ENGINES)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
mat = active_node_mat(context.material)
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemR(mat, "shadows", text="Receive")
|
||||
col.itemR(mat, "receive_transparent_shadows", text="Receive Transparent")
|
||||
col.itemR(mat, "only_shadow", text="Shadows Only")
|
||||
col.itemR(mat, "cast_shadows_only", text="Cast Only")
|
||||
col.itemR(mat, "shadow_casting_alpha", text="Casting Alpha")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(mat, "cast_buffer_shadows")
|
||||
sub = col.column()
|
||||
sub.active = mat.cast_buffer_shadows
|
||||
sub.itemR(mat, "shadow_buffer_bias", text="Buffer Bias")
|
||||
col.itemR(mat, "ray_shadow_bias", text="Auto Ray Bias")
|
||||
sub = col.column()
|
||||
sub.active = (not mat.ray_shadow_bias)
|
||||
sub.itemR(mat, "shadow_ray_bias", text="Ray Bias")
|
||||
|
||||
class MATERIAL_PT_diffuse(MaterialButtonsPanel):
|
||||
__label__ = "Diffuse"
|
||||
COMPAT_ENGINES = set(['BLENDER_RENDER', 'BLENDER_GAME'])
|
||||
|
||||
def poll(self, context):
|
||||
mat = active_node_mat(context.material)
|
||||
engine = context.scene.render_data.engine
|
||||
return mat and (mat.type in ('SURFACE', 'WIRE')) and (engine in self.COMPAT_ENGINES)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
mat = active_node_mat(context.material)
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemR(mat, "diffuse_color", text="")
|
||||
sub = col.column()
|
||||
sub.active = (not mat.shadeless)
|
||||
sub.itemR(mat, "diffuse_intensity", text="Intensity")
|
||||
|
||||
col = split.column()
|
||||
col.active = (not mat.shadeless)
|
||||
col.itemR(mat, "diffuse_shader", text="")
|
||||
col.itemR(mat, "use_diffuse_ramp", text="Ramp")
|
||||
|
||||
col = layout.column()
|
||||
col.active = (not mat.shadeless)
|
||||
if mat.diffuse_shader == 'OREN_NAYAR':
|
||||
col.itemR(mat, "roughness")
|
||||
elif mat.diffuse_shader == 'MINNAERT':
|
||||
col.itemR(mat, "darkness")
|
||||
elif mat.diffuse_shader == 'TOON':
|
||||
row = col.row()
|
||||
row.itemR(mat, "diffuse_toon_size", text="Size")
|
||||
row.itemR(mat, "diffuse_toon_smooth", text="Smooth")
|
||||
elif mat.diffuse_shader == 'FRESNEL':
|
||||
row = col.row()
|
||||
row.itemR(mat, "diffuse_fresnel", text="Fresnel")
|
||||
row.itemR(mat, "diffuse_fresnel_factor", text="Factor")
|
||||
|
||||
if mat.use_diffuse_ramp:
|
||||
layout.itemS()
|
||||
layout.template_color_ramp(mat, "diffuse_ramp", expand=True)
|
||||
layout.itemS()
|
||||
row = layout.row()
|
||||
split = row.split(percentage=0.3)
|
||||
split.itemL(text="Input:")
|
||||
split.itemR(mat, "diffuse_ramp_input", text="")
|
||||
split = row.split(percentage=0.3)
|
||||
split.itemL(text="Blend:")
|
||||
split.itemR(mat, "diffuse_ramp_blend", text="")
|
||||
row = layout.row()
|
||||
row.itemR(mat, "diffuse_ramp_factor", text="Factor")
|
||||
|
||||
class MATERIAL_PT_specular(MaterialButtonsPanel):
|
||||
__label__ = "Specular"
|
||||
COMPAT_ENGINES = set(['BLENDER_RENDER', 'BLENDER_GAME'])
|
||||
|
||||
def poll(self, context):
|
||||
mat = active_node_mat(context.material)
|
||||
engine = context.scene.render_data.engine
|
||||
return mat and (mat.type in ('SURFACE', 'WIRE')) and (engine in self.COMPAT_ENGINES)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
mat = active_node_mat(context.material)
|
||||
|
||||
layout.active = (not mat.shadeless)
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemR(mat, "specular_color", text="")
|
||||
col.itemR(mat, "specular_intensity", text="Intensity")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(mat, "specular_shader", text="")
|
||||
col.itemR(mat, "use_specular_ramp", text="Ramp")
|
||||
|
||||
col = layout.column()
|
||||
if mat.specular_shader in ('COOKTORR', 'PHONG'):
|
||||
col.itemR(mat, "specular_hardness", text="Hardness")
|
||||
elif mat.specular_shader == 'BLINN':
|
||||
row = col.row()
|
||||
row.itemR(mat, "specular_hardness", text="Hardness")
|
||||
row.itemR(mat, "specular_ior", text="IOR")
|
||||
elif mat.specular_shader == 'WARDISO':
|
||||
col.itemR(mat, "specular_slope", text="Slope")
|
||||
elif mat.specular_shader == 'TOON':
|
||||
row = col.row()
|
||||
row.itemR(mat, "specular_toon_size", text="Size")
|
||||
row.itemR(mat, "specular_toon_smooth", text="Smooth")
|
||||
|
||||
if mat.use_specular_ramp:
|
||||
layout.itemS()
|
||||
layout.template_color_ramp(mat, "specular_ramp", expand=True)
|
||||
layout.itemS()
|
||||
row = layout.row()
|
||||
split = row.split(percentage=0.3)
|
||||
split.itemL(text="Input:")
|
||||
split.itemR(mat, "specular_ramp_input", text="")
|
||||
split = row.split(percentage=0.3)
|
||||
split.itemL(text="Blend:")
|
||||
split.itemR(mat, "specular_ramp_blend", text="")
|
||||
row = layout.row()
|
||||
row.itemR(mat, "specular_ramp_factor", text="Factor")
|
||||
|
||||
class MATERIAL_PT_sss(MaterialButtonsPanel):
|
||||
__label__ = "Subsurface Scattering"
|
||||
__default_closed__ = True
|
||||
COMPAT_ENGINES = set(['BLENDER_RENDER'])
|
||||
|
||||
def poll(self, context):
|
||||
mat = active_node_mat(context.material)
|
||||
engine = context.scene.render_data.engine
|
||||
return mat and (mat.type in ('SURFACE', 'WIRE')) and (engine in self.COMPAT_ENGINES)
|
||||
|
||||
def draw_header(self, context):
|
||||
mat = active_node_mat(context.material)
|
||||
sss = mat.subsurface_scattering
|
||||
|
||||
self.layout.active = (not mat.shadeless)
|
||||
self.layout.itemR(sss, "enabled", text="")
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
mat = active_node_mat(context.material)
|
||||
sss = mat.subsurface_scattering
|
||||
|
||||
layout.active = sss.enabled
|
||||
|
||||
split = layout.split()
|
||||
split.active = (not mat.shadeless)
|
||||
|
||||
col = split.column()
|
||||
col.itemR(sss, "ior")
|
||||
col.itemR(sss, "scale")
|
||||
col.itemR(sss, "color", text="")
|
||||
col.itemR(sss, "radius", text="RGB Radius")
|
||||
|
||||
col = split.column()
|
||||
sub = col.column(align=True)
|
||||
sub.itemL(text="Blend:")
|
||||
sub.itemR(sss, "color_factor", text="Color")
|
||||
sub.itemR(sss, "texture_factor", text="Texture")
|
||||
sub.itemL(text="Scattering Weight:")
|
||||
sub.itemR(sss, "front")
|
||||
sub.itemR(sss, "back")
|
||||
col.itemS()
|
||||
col.itemR(sss, "error_tolerance", text="Error")
|
||||
|
||||
class MATERIAL_PT_mirror(MaterialButtonsPanel):
|
||||
__label__ = "Mirror"
|
||||
__default_closed__ = True
|
||||
COMPAT_ENGINES = set(['BLENDER_RENDER'])
|
||||
|
||||
def poll(self, context):
|
||||
mat = active_node_mat(context.material)
|
||||
engine = context.scene.render_data.engine
|
||||
return mat and (mat.type in ('SURFACE', 'WIRE')) and (engine in self.COMPAT_ENGINES)
|
||||
|
||||
def draw_header(self, context):
|
||||
raym = active_node_mat(context.material).raytrace_mirror
|
||||
|
||||
self.layout.itemR(raym, "enabled", text="")
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
mat = active_node_mat(context.material)
|
||||
raym = mat.raytrace_mirror
|
||||
|
||||
layout.active = raym.enabled
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemR(raym, "reflect_factor")
|
||||
col.itemR(mat, "mirror_color", text="")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(raym, "fresnel")
|
||||
sub = col.column()
|
||||
sub.active = raym.fresnel > 0
|
||||
sub.itemR(raym, "fresnel_factor", text="Blend")
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemS()
|
||||
col.itemR(raym, "distance", text="Max Dist")
|
||||
col.itemR(raym, "depth")
|
||||
col.itemS()
|
||||
sub = col.split(percentage=0.4)
|
||||
sub.itemL(text="Fade To:")
|
||||
sub.itemR(raym, "fade_to", text="")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Gloss:")
|
||||
col.itemR(raym, "gloss_factor", text="Amount")
|
||||
sub = col.column()
|
||||
sub.active = raym.gloss_factor < 1.0
|
||||
sub.itemR(raym, "gloss_threshold", text="Threshold")
|
||||
sub.itemR(raym, "gloss_samples", text="Samples")
|
||||
sub.itemR(raym, "gloss_anisotropic", text="Anisotropic")
|
||||
|
||||
class MATERIAL_PT_transp(MaterialButtonsPanel):
|
||||
__label__= "Transparency"
|
||||
__default_closed__ = True
|
||||
COMPAT_ENGINES = set(['BLENDER_RENDER'])
|
||||
|
||||
def poll(self, context):
|
||||
mat = active_node_mat(context.material)
|
||||
engine = context.scene.render_data.engine
|
||||
return mat and (mat.type in ('SURFACE', 'WIRE')) and (engine in self.COMPAT_ENGINES)
|
||||
|
||||
def draw_header(self, context):
|
||||
mat = active_node_mat(context.material)
|
||||
|
||||
self.layout.itemR(mat, "transparency", text="")
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
mat = active_node_mat(context.material)
|
||||
rayt = mat.raytrace_transparency
|
||||
|
||||
row = layout.row()
|
||||
row.active = mat.transparency and (not mat.shadeless)
|
||||
row.itemR(mat, "transparency_method", expand=True)
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemR(mat, "alpha")
|
||||
row = col.row()
|
||||
row.active = mat.transparency and (not mat.shadeless)
|
||||
row.itemR(mat, "specular_alpha", text="Specular")
|
||||
|
||||
col = split.column()
|
||||
col.active = (not mat.shadeless)
|
||||
col.itemR(rayt, "fresnel")
|
||||
sub = col.column()
|
||||
sub.active = rayt.fresnel > 0
|
||||
sub.itemR(rayt, "fresnel_factor", text="Blend")
|
||||
|
||||
if mat.transparency_method == 'RAYTRACE':
|
||||
layout.itemS()
|
||||
split = layout.split()
|
||||
split.active = mat.transparency
|
||||
|
||||
col = split.column()
|
||||
col.itemR(rayt, "ior")
|
||||
col.itemR(rayt, "filter")
|
||||
col.itemR(rayt, "falloff")
|
||||
col.itemR(rayt, "limit")
|
||||
col.itemR(rayt, "depth")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Gloss:")
|
||||
col.itemR(rayt, "gloss_factor", text="Amount")
|
||||
sub = col.column()
|
||||
sub.active = rayt.gloss_factor < 1.0
|
||||
sub.itemR(rayt, "gloss_threshold", text="Threshold")
|
||||
sub.itemR(rayt, "gloss_samples", text="Samples")
|
||||
|
||||
class MATERIAL_PT_halo(MaterialButtonsPanel):
|
||||
__label__= "Halo"
|
||||
COMPAT_ENGINES = set(['BLENDER_RENDER'])
|
||||
|
||||
def poll(self, context):
|
||||
mat = context.material
|
||||
engine = context.scene.render_data.engine
|
||||
return mat and (mat.type == 'HALO') and (engine in self.COMPAT_ENGINES)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
mat = context.material # dont use node material
|
||||
halo = mat.halo
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemR(mat, "diffuse_color", text="")
|
||||
col.itemR(halo, "size")
|
||||
col.itemR(halo, "hardness")
|
||||
col.itemR(halo, "add")
|
||||
col.itemL(text="Options:")
|
||||
col.itemR(halo, "texture")
|
||||
col.itemR(halo, "vertex_normal")
|
||||
col.itemR(halo, "xalpha")
|
||||
col.itemR(halo, "shaded")
|
||||
col.itemR(halo, "soft")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(halo, "ring")
|
||||
sub = col.column()
|
||||
sub.active = halo.ring
|
||||
sub.itemR(halo, "rings")
|
||||
sub.itemR(mat, "mirror_color", text="")
|
||||
col.itemS()
|
||||
col.itemR(halo, "lines")
|
||||
sub = col.column()
|
||||
sub.active = halo.lines
|
||||
sub.itemR(halo, "line_number", text="Lines")
|
||||
sub.itemR(mat, "specular_color", text="")
|
||||
col.itemS()
|
||||
col.itemR(halo, "star")
|
||||
sub = col.column()
|
||||
sub.active = halo.star
|
||||
sub.itemR(halo, "star_tips")
|
||||
|
||||
class MATERIAL_PT_flare(MaterialButtonsPanel):
|
||||
__label__= "Flare"
|
||||
COMPAT_ENGINES = set(['BLENDER_RENDER'])
|
||||
|
||||
def poll(self, context):
|
||||
mat = context.material
|
||||
engine = context.scene.render_data.engine
|
||||
return mat and (mat.type == 'HALO') and (engine in self.COMPAT_ENGINES)
|
||||
|
||||
def draw_header(self, context):
|
||||
halo = context.material.halo
|
||||
|
||||
self.layout.itemR(halo, "flare_mode", text="")
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
mat = context.material # dont use node material
|
||||
halo = mat.halo
|
||||
|
||||
layout.active = halo.flare_mode
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemR(halo, "flare_size", text="Size")
|
||||
col.itemR(halo, "flare_boost", text="Boost")
|
||||
col.itemR(halo, "flare_seed", text="Seed")
|
||||
col = split.column()
|
||||
col.itemR(halo, "flares_sub", text="Subflares")
|
||||
col.itemR(halo, "flare_subsize", text="Subsize")
|
||||
|
||||
bpy.types.register(MATERIAL_PT_context_material)
|
||||
bpy.types.register(MATERIAL_PT_preview)
|
||||
bpy.types.register(MATERIAL_PT_diffuse)
|
||||
bpy.types.register(MATERIAL_PT_specular)
|
||||
bpy.types.register(MATERIAL_PT_shading)
|
||||
bpy.types.register(MATERIAL_PT_transp)
|
||||
bpy.types.register(MATERIAL_PT_mirror)
|
||||
bpy.types.register(MATERIAL_PT_sss)
|
||||
bpy.types.register(MATERIAL_PT_halo)
|
||||
bpy.types.register(MATERIAL_PT_flare)
|
||||
bpy.types.register(MATERIAL_PT_physics)
|
||||
bpy.types.register(MATERIAL_PT_strand)
|
||||
bpy.types.register(MATERIAL_PT_options)
|
||||
bpy.types.register(MATERIAL_PT_shadow)
|
||||
|
||||
# Volumetrics
|
||||
class VolumeButtonsPanel(bpy.types.Panel):
|
||||
__space_type__ = 'PROPERTIES'
|
||||
__region_type__ = 'WINDOW'
|
||||
__context__ = "material"
|
||||
|
||||
def poll(self, context):
|
||||
mat = context.material
|
||||
engine = context.scene.render_data.engine
|
||||
return mat and (mat.type == 'VOLUME') and (engine in self.COMPAT_ENGINES)
|
||||
|
||||
class MATERIAL_PT_volume_density(VolumeButtonsPanel):
|
||||
__label__ = "Density"
|
||||
__default_closed__ = False
|
||||
COMPAT_ENGINES = set(['BLENDER_RENDER'])
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
vol = context.material.volume # dont use node material
|
||||
|
||||
split = layout.split()
|
||||
row = split.row()
|
||||
row.itemR(vol, "density")
|
||||
row.itemR(vol, "density_scale")
|
||||
|
||||
|
||||
class MATERIAL_PT_volume_shading(VolumeButtonsPanel):
|
||||
__label__ = "Shading"
|
||||
__default_closed__ = False
|
||||
COMPAT_ENGINES = set(['BLENDER_RENDER'])
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
vol = context.material.volume # dont use node material
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemR(vol, "scattering")
|
||||
col.itemR(vol, "asymmetry")
|
||||
col.itemR(vol, "transmission_color")
|
||||
|
||||
col = split.column()
|
||||
sub = col.column(align=True)
|
||||
sub.itemR(vol, "emission")
|
||||
sub.itemR(vol, "emission_color", text="")
|
||||
sub = col.column(align=True)
|
||||
sub.itemR(vol, "reflection")
|
||||
sub.itemR(vol, "reflection_color", text="")
|
||||
|
||||
class MATERIAL_PT_volume_lighting(VolumeButtonsPanel):
|
||||
__label__ = "Lighting"
|
||||
__default_closed__ = False
|
||||
COMPAT_ENGINES = set(['BLENDER_RENDER'])
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
vol = context.material.volume # dont use node material
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemR(vol, "lighting_mode", text="")
|
||||
|
||||
col = split.column()
|
||||
|
||||
if vol.lighting_mode == 'SHADED':
|
||||
col.itemR(vol, "external_shadows")
|
||||
col.itemR(vol, "light_cache")
|
||||
sub = col.column()
|
||||
sub.active = vol.light_cache
|
||||
sub.itemR(vol, "cache_resolution")
|
||||
elif vol.lighting_mode in ('MULTIPLE_SCATTERING', 'SHADED_PLUS_MULTIPLE_SCATTERING'):
|
||||
sub = col.column()
|
||||
sub.enabled = True
|
||||
sub.active = False
|
||||
sub.itemR(vol, "light_cache")
|
||||
col.itemR(vol, "cache_resolution")
|
||||
|
||||
sub = col.column(align=True)
|
||||
sub.itemR(vol, "ms_diffusion")
|
||||
sub.itemR(vol, "ms_spread")
|
||||
sub.itemR(vol, "ms_intensity")
|
||||
|
||||
|
||||
class MATERIAL_PT_volume_transp(VolumeButtonsPanel):
|
||||
__label__= "Transparency"
|
||||
COMPAT_ENGINES = set(['BLENDER_RENDER'])
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
mat = context.material # dont use node material
|
||||
|
||||
layout.itemR(mat, "transparency_method", expand=True)
|
||||
|
||||
class MATERIAL_PT_volume_integration(VolumeButtonsPanel):
|
||||
__label__ = "Integration"
|
||||
__default_closed__ = False
|
||||
COMPAT_ENGINES = set(['BLENDER_RENDER'])
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
vol = context.material.volume # dont use node material
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Step Calculation:")
|
||||
col.itemR(vol, "step_calculation", text="")
|
||||
col = col.column(align=True)
|
||||
col.itemR(vol, "step_size")
|
||||
|
||||
col = split.column()
|
||||
col.itemL()
|
||||
col.itemR(vol, "depth_cutoff")
|
||||
|
||||
bpy.types.register(MATERIAL_PT_volume_density)
|
||||
bpy.types.register(MATERIAL_PT_volume_shading)
|
||||
bpy.types.register(MATERIAL_PT_volume_lighting)
|
||||
bpy.types.register(MATERIAL_PT_volume_transp)
|
||||
bpy.types.register(MATERIAL_PT_volume_integration)
|
@ -1,223 +0,0 @@
|
||||
|
||||
import bpy
|
||||
|
||||
class ObjectButtonsPanel(bpy.types.Panel):
|
||||
__space_type__ = 'PROPERTIES'
|
||||
__region_type__ = 'WINDOW'
|
||||
__context__ = "object"
|
||||
|
||||
class OBJECT_PT_context_object(ObjectButtonsPanel):
|
||||
__show_header__ = False
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
ob = context.object
|
||||
|
||||
row = layout.row()
|
||||
row.itemL(text="", icon='ICON_OBJECT_DATA')
|
||||
row.itemR(ob, "name", text="")
|
||||
|
||||
class OBJECT_PT_transform(ObjectButtonsPanel):
|
||||
__label__ = "Transform"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
ob = context.object
|
||||
|
||||
row = layout.row()
|
||||
|
||||
row.column().itemR(ob, "location")
|
||||
if ob.rotation_mode == 'QUATERNION':
|
||||
row.column().itemR(ob, "rotation_quaternion", text="Rotation")
|
||||
elif ob.rotation_mode == 'AXIS_ANGLE':
|
||||
#row.column().itemL(text="Rotation")
|
||||
#row.column().itemR(pchan, "rotation_angle", text="Angle")
|
||||
#row.column().itemR(pchan, "rotation_axis", text="Axis")
|
||||
row.column().itemR(ob, "rotation_axis_angle", text="Rotation")
|
||||
else:
|
||||
row.column().itemR(ob, "rotation_euler", text="Rotation")
|
||||
|
||||
row.column().itemR(ob, "scale")
|
||||
|
||||
layout.itemR(ob, "rotation_mode")
|
||||
|
||||
class OBJECT_PT_transform_locks(ObjectButtonsPanel):
|
||||
__label__ = "Transform Locks"
|
||||
__default_closed__ = True
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
ob = context.object
|
||||
|
||||
row = layout.row()
|
||||
|
||||
col = row.column()
|
||||
col.itemR(ob, "lock_location")
|
||||
|
||||
col = row.column()
|
||||
if ob.rotation_mode in ('QUATERNION', 'AXIS_ANGLE'):
|
||||
col.itemR(ob, "lock_rotations_4d", text="Lock Rotation")
|
||||
if ob.lock_rotations_4d:
|
||||
col.itemR(ob, "lock_rotation_w", text="W")
|
||||
col.itemR(ob, "lock_rotation", text="")
|
||||
else:
|
||||
col.itemR(ob, "lock_rotation", text="Rotation")
|
||||
|
||||
row.column().itemR(ob, "lock_scale")
|
||||
|
||||
class OBJECT_PT_relations(ObjectButtonsPanel):
|
||||
__label__ = "Relations"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
ob = context.object
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemR(ob, "layers")
|
||||
col.itemS()
|
||||
col.itemR(ob, "pass_index")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Parent:")
|
||||
col.itemR(ob, "parent", text="")
|
||||
|
||||
sub = col.column()
|
||||
split = sub.split(percentage=0.3)
|
||||
split.itemL(text="Type:")
|
||||
split.itemR(ob, "parent_type", text="")
|
||||
parent = ob.parent
|
||||
if parent and ob.parent_type == 'BONE' and parent.type == 'ARMATURE':
|
||||
sub.item_pointerR(ob, "parent_bone", parent.data, "bones", text="")
|
||||
sub.active = parent != None
|
||||
|
||||
class OBJECT_PT_groups(ObjectButtonsPanel):
|
||||
__label__ = "Groups"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
ob = context.object
|
||||
|
||||
split = layout.split()
|
||||
split.item_menu_enumO("object.group_add", "group", text="Add to Group")
|
||||
split.itemL()
|
||||
|
||||
for group in bpy.data.groups:
|
||||
if ob.name in group.objects:
|
||||
col = layout.column(align=True)
|
||||
|
||||
col.set_context_pointer("group", group)
|
||||
|
||||
row = col.box().row()
|
||||
row.itemR(group, "name", text="")
|
||||
row.itemO("object.group_remove", text="", icon='VICON_X')
|
||||
|
||||
split = col.box().split()
|
||||
split.column().itemR(group, "layer", text="Dupli")
|
||||
split.column().itemR(group, "dupli_offset", text="")
|
||||
|
||||
class OBJECT_PT_display(ObjectButtonsPanel):
|
||||
__label__ = "Display"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
ob = context.object
|
||||
|
||||
split = layout.split()
|
||||
col = split.column()
|
||||
col.itemR(ob, "max_draw_type", text="Type")
|
||||
col = split.column()
|
||||
row = col.row()
|
||||
row.itemR(ob, "draw_bounds", text="Bounds")
|
||||
row.itemR(ob, "draw_bounds_type", text="")
|
||||
|
||||
flow = layout.column_flow()
|
||||
flow.itemR(ob, "draw_name", text="Name")
|
||||
flow.itemR(ob, "draw_axis", text="Axis")
|
||||
flow.itemR(ob, "draw_wire", text="Wire")
|
||||
flow.itemR(ob, "draw_texture_space", text="Texture Space")
|
||||
flow.itemR(ob, "x_ray", text="X-Ray")
|
||||
flow.itemR(ob, "draw_transparent", text="Transparency")
|
||||
|
||||
class OBJECT_PT_duplication(ObjectButtonsPanel):
|
||||
__label__ = "Duplication"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
ob = context.object
|
||||
|
||||
layout.itemR(ob, "dupli_type", expand=True)
|
||||
|
||||
if ob.dupli_type == 'FRAMES':
|
||||
split = layout.split()
|
||||
|
||||
col = split.column(align=True)
|
||||
col.itemR(ob, "dupli_frames_start", text="Start")
|
||||
col.itemR(ob, "dupli_frames_end", text="End")
|
||||
|
||||
col = split.column(align=True)
|
||||
col.itemR(ob, "dupli_frames_on", text="On")
|
||||
col.itemR(ob, "dupli_frames_off", text="Off")
|
||||
|
||||
layout.itemR(ob, "dupli_frames_no_speed", text="No Speed")
|
||||
|
||||
elif ob.dupli_type == 'VERTS':
|
||||
layout.itemR(ob, "dupli_verts_rotation", text="Rotation")
|
||||
|
||||
elif ob.dupli_type == 'FACES':
|
||||
row = layout.row()
|
||||
row.itemR(ob, "dupli_faces_scale", text="Scale")
|
||||
row.itemR(ob, "dupli_faces_inherit_scale", text="Inherit Scale")
|
||||
|
||||
elif ob.dupli_type == 'GROUP':
|
||||
layout.itemR(ob, "dupli_group", text="Group")
|
||||
|
||||
class OBJECT_PT_animation(ObjectButtonsPanel):
|
||||
__label__ = "Animation"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
ob = context.object
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Time Offset:")
|
||||
col.itemR(ob, "time_offset_edit", text="Edit")
|
||||
row = col.row()
|
||||
row.itemR(ob, "time_offset_particle", text="Particle")
|
||||
row.active = len(ob.particle_systems) != 0
|
||||
row = col.row()
|
||||
row.itemR(ob, "time_offset_parent", text="Parent")
|
||||
row.active = ob.parent != None
|
||||
row = col.row()
|
||||
row.itemR(ob, "slow_parent")
|
||||
row.active = ob.parent != None
|
||||
col.itemR(ob, "time_offset", text="Offset")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Track:")
|
||||
col.itemR(ob, "track", text="")
|
||||
col.itemR(ob, "track_axis", text="Axis")
|
||||
col.itemR(ob, "up_axis", text="Up Axis")
|
||||
row = col.row()
|
||||
row.itemR(ob, "track_override_parent", text="Override Parent")
|
||||
row.active = ob.parent != None
|
||||
|
||||
bpy.types.register(OBJECT_PT_context_object)
|
||||
bpy.types.register(OBJECT_PT_transform)
|
||||
bpy.types.register(OBJECT_PT_transform_locks)
|
||||
bpy.types.register(OBJECT_PT_relations)
|
||||
bpy.types.register(OBJECT_PT_groups)
|
||||
bpy.types.register(OBJECT_PT_display)
|
||||
bpy.types.register(OBJECT_PT_duplication)
|
||||
bpy.types.register(OBJECT_PT_animation)
|
@ -1,746 +0,0 @@
|
||||
|
||||
import bpy
|
||||
|
||||
class ConstraintButtonsPanel(bpy.types.Panel):
|
||||
__space_type__ = 'PROPERTIES'
|
||||
__region_type__ = 'WINDOW'
|
||||
__context__ = "constraint"
|
||||
|
||||
def draw_constraint(self, context, con):
|
||||
layout = self.layout
|
||||
|
||||
box = layout.template_constraint(con)
|
||||
|
||||
if box:
|
||||
# match enum type to our functions, avoids a lookup table.
|
||||
getattr(self, con.type)(context, box, con)
|
||||
|
||||
# show/key buttons here are most likely obsolete now, with
|
||||
# keyframing functionality being part of every button
|
||||
if con.type not in ('RIGID_BODY_JOINT', 'NULL'):
|
||||
box.itemR(con, "influence")
|
||||
|
||||
def space_template(self, layout, con, target=True, owner=True):
|
||||
if target or owner:
|
||||
row = layout.row()
|
||||
|
||||
row.itemL(text="Convert:")
|
||||
|
||||
if target:
|
||||
row.itemR(con, "target_space", text="")
|
||||
|
||||
if target and owner:
|
||||
row.itemL(icon='ICON_ARROW_LEFTRIGHT')
|
||||
|
||||
if owner:
|
||||
row.itemR(con, "owner_space", text="")
|
||||
|
||||
def target_template(self, layout, con, subtargets=True):
|
||||
layout.itemR(con, "target") # XXX limiting settings for only 'curves' or some type of object
|
||||
|
||||
if con.target and subtargets:
|
||||
if con.target.type == 'ARMATURE':
|
||||
layout.item_pointerR(con, "subtarget", con.target.data, "bones", text="Bone")
|
||||
|
||||
if con.type == 'COPY_LOCATION':
|
||||
row = layout.row()
|
||||
row.itemL(text="Head/Tail:")
|
||||
row.itemR(con, "head_tail", text="")
|
||||
elif con.target.type in ('MESH', 'LATTICE'):
|
||||
layout.item_pointerR(con, "subtarget", con.target, "vertex_groups", text="Vertex Group")
|
||||
|
||||
def ik_template(self, layout, con):
|
||||
# only used for iTaSC
|
||||
layout.itemR(con, "pole_target")
|
||||
|
||||
if con.pole_target and con.pole_target.type == 'ARMATURE':
|
||||
layout.item_pointerR(con, "pole_subtarget", con.pole_target.data, "bones", text="Bone")
|
||||
|
||||
if con.pole_target:
|
||||
row = layout.row()
|
||||
row.itemL()
|
||||
row.itemR(con, "pole_angle")
|
||||
|
||||
split = layout.split(percentage=0.33)
|
||||
col = split.column()
|
||||
col.itemR(con, "tail")
|
||||
col.itemR(con, "stretch")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(con, "chain_length")
|
||||
col.itemR(con, "targetless")
|
||||
|
||||
def CHILD_OF(self, context, layout, con):
|
||||
self.target_template(layout, con)
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Location:")
|
||||
col.itemR(con, "locationx", text="X")
|
||||
col.itemR(con, "locationy", text="Y")
|
||||
col.itemR(con, "locationz", text="Z")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Rotation:")
|
||||
col.itemR(con, "rotationx", text="X")
|
||||
col.itemR(con, "rotationy", text="Y")
|
||||
col.itemR(con, "rotationz", text="Z")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Scale:")
|
||||
col.itemR(con, "sizex", text="X")
|
||||
col.itemR(con, "sizey", text="Y")
|
||||
col.itemR(con, "sizez", text="Z")
|
||||
|
||||
row = layout.row()
|
||||
row.itemO("constraint.childof_set_inverse")
|
||||
row.itemO("constraint.childof_clear_inverse")
|
||||
|
||||
def TRACK_TO(self, context, layout, con):
|
||||
self.target_template(layout, con)
|
||||
|
||||
row = layout.row()
|
||||
row.itemL(text="To:")
|
||||
row.itemR(con, "track", expand=True)
|
||||
|
||||
row = layout.row()
|
||||
#row.itemR(con, "up", text="Up", expand=True) # XXX: up and expand don't play nice together
|
||||
row.itemR(con, "up", text="Up")
|
||||
row.itemR(con, "target_z")
|
||||
|
||||
self.space_template(layout, con)
|
||||
|
||||
def IK(self, context, layout, con):
|
||||
if context.object.pose.ik_solver == "ITASC":
|
||||
layout.itemR(con, "ik_type")
|
||||
getattr(self, "IK_"+con.ik_type)(context, layout, con)
|
||||
else:
|
||||
# Legacy IK constraint
|
||||
self.target_template(layout, con)
|
||||
layout.itemR(con, "pole_target")
|
||||
|
||||
if con.pole_target and con.pole_target.type == 'ARMATURE':
|
||||
layout.item_pointerR(con, "pole_subtarget", con.pole_target.data, "bones", text="Bone")
|
||||
|
||||
if con.pole_target:
|
||||
row = layout.row()
|
||||
row.itemL()
|
||||
row.itemR(con, "pole_angle")
|
||||
|
||||
split = layout.split()
|
||||
col = split.column()
|
||||
col.itemR(con, "tail")
|
||||
col.itemR(con, "stretch")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(con, "iterations")
|
||||
col.itemR(con, "chain_length")
|
||||
|
||||
split = layout.split()
|
||||
col = split.column()
|
||||
col.itemL()
|
||||
col.itemR(con, "targetless")
|
||||
col.itemR(con, "rotation")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Weight:")
|
||||
col.itemR(con, "weight", text="Position", slider=True)
|
||||
sub = col.column()
|
||||
sub.active = con.rotation
|
||||
sub.itemR(con, "orient_weight", text="Rotation", slider=True)
|
||||
|
||||
def IK_COPY_POSE(self, context, layout, con):
|
||||
self.target_template(layout, con)
|
||||
self.ik_template(layout, con)
|
||||
|
||||
row = layout.row()
|
||||
row.itemL(text="Axis Ref:")
|
||||
row.itemR(con, "axis_reference", expand=True)
|
||||
split = layout.split(percentage=0.33)
|
||||
split.row().itemR(con, "position")
|
||||
row = split.row()
|
||||
row.itemR(con, "weight", text="Weight", slider=True)
|
||||
row.active = con.position
|
||||
split = layout.split(percentage=0.33)
|
||||
row = split.row()
|
||||
row.itemL(text="Lock:")
|
||||
row = split.row()
|
||||
row.itemR(con, "pos_lock_x", text="X")
|
||||
row.itemR(con, "pos_lock_y", text="Y")
|
||||
row.itemR(con, "pos_lock_z", text="Z")
|
||||
split.active = con.position
|
||||
|
||||
split = layout.split(percentage=0.33)
|
||||
split.row().itemR(con, "rotation")
|
||||
row = split.row()
|
||||
row.itemR(con, "orient_weight", text="Weight", slider=True)
|
||||
row.active = con.rotation
|
||||
split = layout.split(percentage=0.33)
|
||||
row = split.row()
|
||||
row.itemL(text="Lock:")
|
||||
row = split.row()
|
||||
row.itemR(con, "rot_lock_x", text="X")
|
||||
row.itemR(con, "rot_lock_y", text="Y")
|
||||
row.itemR(con, "rot_lock_z", text="Z")
|
||||
split.active = con.rotation
|
||||
|
||||
def IK_DISTANCE(self, context, layout, con):
|
||||
self.target_template(layout, con)
|
||||
self.ik_template(layout, con)
|
||||
|
||||
layout.itemR(con, "limit_mode")
|
||||
row = layout.row()
|
||||
row.itemR(con, "weight", text="Weight", slider=True)
|
||||
row.itemR(con, "distance", text="Distance", slider=True)
|
||||
|
||||
def FOLLOW_PATH(self, context, layout, con):
|
||||
self.target_template(layout, con)
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemR(con, "use_curve_follow")
|
||||
col.itemR(con, "use_curve_radius")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(con, "use_fixed_position")
|
||||
if con.use_fixed_position:
|
||||
col.itemR(con, "offset_factor", text="Offset")
|
||||
else:
|
||||
col.itemR(con, "offset")
|
||||
|
||||
row = layout.row()
|
||||
row.itemL(text="Forward:")
|
||||
row.itemR(con, "forward", expand=True)
|
||||
|
||||
row = layout.row()
|
||||
row.itemR(con, "up", text="Up")
|
||||
row.itemL()
|
||||
|
||||
def LIMIT_ROTATION(self, context, layout, con):
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemR(con, "use_limit_x")
|
||||
sub = col.column()
|
||||
sub.active = con.use_limit_x
|
||||
sub.itemR(con, "minimum_x", text="Min")
|
||||
sub.itemR(con, "maximum_x", text="Max")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(con, "use_limit_y")
|
||||
sub = col.column()
|
||||
sub.active = con.use_limit_y
|
||||
sub.itemR(con, "minimum_y", text="Min")
|
||||
sub.itemR(con, "maximum_y", text="Max")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(con, "use_limit_z")
|
||||
sub = col.column()
|
||||
sub.active = con.use_limit_z
|
||||
sub.itemR(con, "minimum_z", text="Min")
|
||||
sub.itemR(con, "maximum_z", text="Max")
|
||||
|
||||
row = layout.row()
|
||||
row.itemR(con, "limit_transform")
|
||||
row.itemL()
|
||||
|
||||
row = layout.row()
|
||||
row.itemL(text="Convert:")
|
||||
row.itemR(con, "owner_space", text="")
|
||||
|
||||
def LIMIT_LOCATION(self, context, layout, con):
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemR(con, "use_minimum_x")
|
||||
sub = col.column()
|
||||
sub.active = con.use_minimum_x
|
||||
sub.itemR(con, "minimum_x", text="")
|
||||
col.itemR(con, "use_maximum_x")
|
||||
sub = col.column()
|
||||
sub.active = con.use_maximum_x
|
||||
sub.itemR(con, "maximum_x", text="")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(con, "use_minimum_y")
|
||||
sub = col.column()
|
||||
sub.active = con.use_minimum_y
|
||||
sub.itemR(con, "minimum_y", text="")
|
||||
col.itemR(con, "use_maximum_y")
|
||||
sub = col.column()
|
||||
sub.active = con.use_maximum_y
|
||||
sub.itemR(con, "maximum_y", text="")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(con, "use_minimum_z")
|
||||
sub = col.column()
|
||||
sub.active = con.use_minimum_z
|
||||
sub.itemR(con, "minimum_z", text="")
|
||||
col.itemR(con, "use_maximum_z")
|
||||
sub = col.column()
|
||||
sub.active = con.use_maximum_z
|
||||
sub.itemR(con, "maximum_z", text="")
|
||||
|
||||
row = layout.row()
|
||||
row.itemR(con, "limit_transform")
|
||||
row.itemL()
|
||||
|
||||
row = layout.row()
|
||||
row.itemL(text="Convert:")
|
||||
row.itemR(con, "owner_space", text="")
|
||||
|
||||
def LIMIT_SCALE(self, context, layout, con):
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemR(con, "use_minimum_x")
|
||||
sub = col.column()
|
||||
sub.active = con.use_minimum_x
|
||||
sub.itemR(con, "minimum_x", text="")
|
||||
col.itemR(con, "use_maximum_x")
|
||||
sub = col.column()
|
||||
sub.active = con.use_maximum_x
|
||||
sub.itemR(con, "maximum_x", text="")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(con, "use_minimum_y")
|
||||
sub = col.column()
|
||||
sub.active = con.use_minimum_y
|
||||
sub.itemR(con, "minimum_y", text="")
|
||||
col.itemR(con, "use_maximum_y")
|
||||
sub = col.column()
|
||||
sub.active = con.use_maximum_y
|
||||
sub.itemR(con, "maximum_y", text="")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(con, "use_minimum_z")
|
||||
sub = col.column()
|
||||
sub.active = con.use_minimum_z
|
||||
sub.itemR(con, "minimum_z", text="")
|
||||
col.itemR(con, "use_maximum_z")
|
||||
sub = col.column()
|
||||
sub.active = con.use_maximum_z
|
||||
sub.itemR(con, "maximum_z", text="")
|
||||
|
||||
row = layout.row()
|
||||
row.itemR(con, "limit_transform")
|
||||
row.itemL()
|
||||
|
||||
row = layout.row()
|
||||
row.itemL(text="Convert:")
|
||||
row.itemR(con, "owner_space", text="")
|
||||
|
||||
def COPY_ROTATION(self, context, layout, con):
|
||||
self.target_template(layout, con)
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemR(con, "rotate_like_x", text="X")
|
||||
sub = col.column()
|
||||
sub.active = con.rotate_like_x
|
||||
sub.itemR(con, "invert_x", text="Invert")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(con, "rotate_like_y", text="Y")
|
||||
sub = col.column()
|
||||
sub.active = con.rotate_like_y
|
||||
sub.itemR(con, "invert_y", text="Invert")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(con, "rotate_like_z", text="Z")
|
||||
sub = col.column()
|
||||
sub.active = con.rotate_like_z
|
||||
sub.itemR(con, "invert_z", text="Invert")
|
||||
|
||||
layout.itemR(con, "offset")
|
||||
|
||||
self.space_template(layout, con)
|
||||
|
||||
def COPY_LOCATION(self, context, layout, con):
|
||||
self.target_template(layout, con)
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemR(con, "locate_like_x", text="X")
|
||||
sub = col.column()
|
||||
sub.active = con.locate_like_x
|
||||
sub.itemR(con, "invert_x", text="Invert")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(con, "locate_like_y", text="Y")
|
||||
sub = col.column()
|
||||
sub.active = con.locate_like_y
|
||||
sub.itemR(con, "invert_y", text="Invert")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(con, "locate_like_z", text="Z")
|
||||
sub = col.column()
|
||||
sub.active = con.locate_like_z
|
||||
sub.itemR(con, "invert_z", text="Invert")
|
||||
|
||||
layout.itemR(con, "offset")
|
||||
|
||||
self.space_template(layout, con)
|
||||
|
||||
def COPY_SCALE(self, context, layout, con):
|
||||
self.target_template(layout, con)
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.itemR(con, "size_like_x", text="X")
|
||||
row.itemR(con, "size_like_y", text="Y")
|
||||
row.itemR(con, "size_like_z", text="Z")
|
||||
|
||||
layout.itemR(con, "offset")
|
||||
|
||||
self.space_template(layout, con)
|
||||
|
||||
#def SCRIPT(self, context, layout, con):
|
||||
|
||||
def ACTION(self, context, layout, con):
|
||||
self.target_template(layout, con)
|
||||
|
||||
layout.itemR(con, "action")
|
||||
layout.itemR(con, "transform_channel")
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column(align=True)
|
||||
col.itemR(con, "start_frame", text="Start")
|
||||
col.itemR(con, "end_frame", text="End")
|
||||
|
||||
col = split.column(align=True)
|
||||
col.itemR(con, "minimum", text="Min")
|
||||
col.itemR(con, "maximum", text="Max")
|
||||
|
||||
row = layout.row()
|
||||
row.itemL(text="Convert:")
|
||||
row.itemR(con, "owner_space", text="")
|
||||
|
||||
def LOCKED_TRACK(self, context, layout, con):
|
||||
self.target_template(layout, con)
|
||||
|
||||
row = layout.row()
|
||||
row.itemL(text="To:")
|
||||
row.itemR(con, "track", expand=True)
|
||||
|
||||
row = layout.row()
|
||||
row.itemL(text="Lock:")
|
||||
row.itemR(con, "locked", expand=True)
|
||||
|
||||
def LIMIT_DISTANCE(self, context, layout, con):
|
||||
self.target_template(layout, con)
|
||||
|
||||
col = layout.column(align=True);
|
||||
col.itemR(con, "distance")
|
||||
col.itemO("constraint.limitdistance_reset")
|
||||
|
||||
row = layout.row()
|
||||
row.itemL(text="Clamp Region:")
|
||||
row.itemR(con, "limit_mode", text="")
|
||||
|
||||
def STRETCH_TO(self, context, layout, con):
|
||||
self.target_template(layout, con)
|
||||
|
||||
row = layout.row()
|
||||
row.itemR(con, "original_length", text="Rest Length")
|
||||
row.itemO("constraint.stretchto_reset", text="Reset")
|
||||
|
||||
col = layout.column()
|
||||
col.itemR(con, "bulge", text="Volume Variation")
|
||||
|
||||
row = layout.row()
|
||||
row.itemL(text="Volume:")
|
||||
row.itemR(con, "volume", expand=True)
|
||||
row.itemL(text="Plane:")
|
||||
row.itemR(con, "keep_axis", expand=True)
|
||||
|
||||
def FLOOR(self, context, layout, con):
|
||||
self.target_template(layout, con)
|
||||
|
||||
row = layout.row()
|
||||
row.itemR(con, "sticky")
|
||||
row.itemR(con, "use_rotation")
|
||||
|
||||
layout.itemR(con, "offset")
|
||||
|
||||
row = layout.row()
|
||||
row.itemL(text="Min/Max:")
|
||||
row.itemR(con, "floor_location", expand=True)
|
||||
|
||||
def RIGID_BODY_JOINT(self, context, layout, con):
|
||||
self.target_template(layout, con)
|
||||
|
||||
layout.itemR(con, "pivot_type")
|
||||
layout.itemR(con, "child")
|
||||
|
||||
row = layout.row()
|
||||
row.itemR(con, "disable_linked_collision", text="No Collision")
|
||||
row.itemR(con, "draw_pivot", text="Display Pivot")
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column(align=True)
|
||||
col.itemL(text="Pivot:")
|
||||
col.itemR(con, "pivot_x", text="X")
|
||||
col.itemR(con, "pivot_y", text="Y")
|
||||
col.itemR(con, "pivot_z", text="Z")
|
||||
|
||||
col = split.column(align=True)
|
||||
col.itemL(text="Axis:")
|
||||
col.itemR(con, "axis_x", text="X")
|
||||
col.itemR(con, "axis_y", text="Y")
|
||||
col.itemR(con, "axis_z", text="Z")
|
||||
|
||||
#Missing: Limit arrays (not wrapped in RNA yet)
|
||||
|
||||
def CLAMP_TO(self, context, layout, con):
|
||||
self.target_template(layout, con)
|
||||
|
||||
row = layout.row()
|
||||
row.itemL(text="Main Axis:")
|
||||
row.itemR(con, "main_axis", expand=True)
|
||||
|
||||
row = layout.row()
|
||||
row.itemR(con, "cyclic")
|
||||
|
||||
def TRANSFORM(self, context, layout, con):
|
||||
self.target_template(layout, con)
|
||||
|
||||
layout.itemR(con, "extrapolate_motion", text="Extrapolate")
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Source:")
|
||||
col.row().itemR(con, "map_from", expand=True)
|
||||
|
||||
sub = col.row(align=True)
|
||||
sub.itemL(text="X:")
|
||||
sub.itemR(con, "from_min_x", text="")
|
||||
sub.itemR(con, "from_max_x", text="")
|
||||
|
||||
sub = col.row(align=True)
|
||||
sub.itemL(text="Y:")
|
||||
sub.itemR(con, "from_min_y", text="")
|
||||
sub.itemR(con, "from_max_y", text="")
|
||||
|
||||
sub = col.row(align=True)
|
||||
sub.itemL(text="Z:")
|
||||
sub.itemR(con, "from_min_z", text="")
|
||||
sub.itemR(con, "from_max_z", text="")
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Destination:")
|
||||
col.row().itemR(con, "map_to", expand=True)
|
||||
|
||||
sub = col.row(align=True)
|
||||
sub.itemR(con, "map_to_x_from", text="")
|
||||
sub.itemR(con, "to_min_x", text="")
|
||||
sub.itemR(con, "to_max_x", text="")
|
||||
|
||||
sub = col.row(align=True)
|
||||
sub.itemR(con, "map_to_y_from", text="")
|
||||
sub.itemR(con, "to_min_y", text="")
|
||||
sub.itemR(con, "to_max_y", text="")
|
||||
|
||||
sub = col.row(align=True)
|
||||
sub.itemR(con, "map_to_z_from", text="")
|
||||
sub.itemR(con, "to_min_z", text="")
|
||||
sub.itemR(con, "to_max_z", text="")
|
||||
|
||||
self.space_template(layout, con)
|
||||
|
||||
def SHRINKWRAP (self, context, layout, con):
|
||||
self.target_template(layout, con)
|
||||
|
||||
layout.itemR(con, "distance")
|
||||
layout.itemR(con, "shrinkwrap_type")
|
||||
|
||||
if con.shrinkwrap_type == 'PROJECT':
|
||||
row = layout.row(align=True)
|
||||
row.itemR(con, "axis_x")
|
||||
row.itemR(con, "axis_y")
|
||||
row.itemR(con, "axis_z")
|
||||
|
||||
class OBJECT_PT_constraints(ConstraintButtonsPanel):
|
||||
__label__ = "Constraints"
|
||||
__context__ = "constraint"
|
||||
|
||||
def poll(self, context):
|
||||
return (context.object)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
ob = context.object
|
||||
|
||||
row = layout.row()
|
||||
row.item_menu_enumO("object.constraint_add", "type")
|
||||
row.itemL();
|
||||
|
||||
for con in ob.constraints:
|
||||
self.draw_constraint(context, con)
|
||||
|
||||
class BONE_PT_inverse_kinematics(ConstraintButtonsPanel):
|
||||
__label__ = "Inverse Kinematics"
|
||||
__default_closed__ = True
|
||||
__context__ = "bone_constraint"
|
||||
|
||||
def poll(self, context):
|
||||
ob = context.object
|
||||
bone = context.bone
|
||||
|
||||
if ob and bone:
|
||||
pchan = ob.pose.pose_channels[bone.name]
|
||||
return pchan.has_ik
|
||||
|
||||
return False
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
ob = context.object
|
||||
bone = context.bone
|
||||
pchan = ob.pose.pose_channels[bone.name]
|
||||
|
||||
row = layout.row()
|
||||
row.itemR(ob.pose, "ik_solver")
|
||||
|
||||
split = layout.split(percentage=0.25)
|
||||
split.itemR(pchan, "ik_dof_x", text="X")
|
||||
row = split.row()
|
||||
row.itemR(pchan, "ik_stiffness_x", text="Stiffness", slider=True)
|
||||
row.active = pchan.ik_dof_x
|
||||
|
||||
split = layout.split(percentage=0.25)
|
||||
row = split.row()
|
||||
row.itemR(pchan, "ik_limit_x", text="Limit")
|
||||
row.active = pchan.ik_dof_x
|
||||
row = split.row(align=True)
|
||||
row.itemR(pchan, "ik_min_x", text="")
|
||||
row.itemR(pchan, "ik_max_x", text="")
|
||||
row.active = pchan.ik_dof_x and pchan.ik_limit_x
|
||||
|
||||
split = layout.split(percentage=0.25)
|
||||
split.itemR(pchan, "ik_dof_y", text="Y")
|
||||
row = split.row()
|
||||
row.itemR(pchan, "ik_stiffness_y", text="Stiffness", slider=True)
|
||||
row.active = pchan.ik_dof_y
|
||||
|
||||
split = layout.split(percentage=0.25)
|
||||
row = split.row()
|
||||
row.itemR(pchan, "ik_limit_y", text="Limit")
|
||||
row.active = pchan.ik_dof_y
|
||||
row = split.row(align=True)
|
||||
row.itemR(pchan, "ik_min_y", text="")
|
||||
row.itemR(pchan, "ik_max_y", text="")
|
||||
row.active = pchan.ik_dof_y and pchan.ik_limit_y
|
||||
|
||||
split = layout.split(percentage=0.25)
|
||||
split.itemR(pchan, "ik_dof_z", text="Z")
|
||||
row = split.row()
|
||||
row.itemR(pchan, "ik_stiffness_z", text="Stiffness", slider=True)
|
||||
row.active = pchan.ik_dof_z
|
||||
|
||||
split = layout.split(percentage=0.25)
|
||||
row = split.row()
|
||||
row.itemR(pchan, "ik_limit_z", text="Limit")
|
||||
row.active = pchan.ik_dof_z
|
||||
row = split.row(align=True)
|
||||
row.itemR(pchan, "ik_min_z", text="")
|
||||
row.itemR(pchan, "ik_max_z", text="")
|
||||
row.active = pchan.ik_dof_z and pchan.ik_limit_z
|
||||
split = layout.split()
|
||||
split.itemR(pchan, "ik_stretch", text="Stretch", slider=True)
|
||||
split.itemL()
|
||||
|
||||
if ob.pose.ik_solver == "ITASC":
|
||||
row = layout.row()
|
||||
row.itemR(pchan, "ik_rot_control", text="Control Rotation")
|
||||
row.itemR(pchan, "ik_rot_weight", text="Weight", slider=True)
|
||||
# not supported yet
|
||||
#row = layout.row()
|
||||
#row.itemR(pchan, "ik_lin_control", text="Joint Size")
|
||||
#row.itemR(pchan, "ik_lin_weight", text="Weight", slider=True)
|
||||
|
||||
class BONE_PT_iksolver_itasc(ConstraintButtonsPanel):
|
||||
__label__ = "iTaSC parameters"
|
||||
__default_closed__ = True
|
||||
__context__ = "bone_constraint"
|
||||
|
||||
def poll(self, context):
|
||||
ob = context.object
|
||||
bone = context.bone
|
||||
|
||||
if ob and bone:
|
||||
pchan = ob.pose.pose_channels[bone.name]
|
||||
return pchan.has_ik and ob.pose.ik_solver == "ITASC" and ob.pose.ik_param
|
||||
|
||||
return False
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
ob = context.object
|
||||
itasc = ob.pose.ik_param
|
||||
|
||||
layout.itemR(itasc, "mode", expand=True)
|
||||
simulation = itasc.mode == "SIMULATION"
|
||||
if simulation:
|
||||
layout.itemL(text="Reiteration:")
|
||||
layout.itemR(itasc, "reiteration", expand=True)
|
||||
|
||||
flow = layout.column_flow()
|
||||
flow.itemR(itasc, "precision", text="Prec")
|
||||
flow.itemR(itasc, "num_iter", text="Iter")
|
||||
flow.active = not simulation or itasc.reiteration != "NEVER"
|
||||
|
||||
if simulation:
|
||||
layout.itemR(itasc, "auto_step")
|
||||
row = layout.row()
|
||||
if itasc.auto_step:
|
||||
row.itemR(itasc, "min_step", text="Min")
|
||||
row.itemR(itasc, "max_step", text="Max")
|
||||
else:
|
||||
row.itemR(itasc, "num_step")
|
||||
|
||||
layout.itemR(itasc, "solver")
|
||||
if simulation:
|
||||
layout.itemR(itasc, "feedback")
|
||||
layout.itemR(itasc, "max_velocity")
|
||||
if itasc.solver == "DLS":
|
||||
row = layout.row()
|
||||
row.itemR(itasc, "dampmax", text="Damp", slider=True)
|
||||
row.itemR(itasc, "dampeps", text="Eps", slider=True)
|
||||
|
||||
class BONE_PT_constraints(ConstraintButtonsPanel):
|
||||
__label__ = "Constraints"
|
||||
__context__ = "bone_constraint"
|
||||
|
||||
def poll(self, context):
|
||||
ob = context.object
|
||||
return (ob and ob.type == 'ARMATURE' and context.bone)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
ob = context.object
|
||||
pchan = ob.pose.pose_channels[context.bone.name]
|
||||
|
||||
row = layout.row()
|
||||
row.item_menu_enumO("pose.constraint_add", "type")
|
||||
row.itemL();
|
||||
|
||||
for con in pchan.constraints:
|
||||
self.draw_constraint(context, con)
|
||||
|
||||
bpy.types.register(OBJECT_PT_constraints)
|
||||
bpy.types.register(BONE_PT_iksolver_itasc)
|
||||
bpy.types.register(BONE_PT_inverse_kinematics)
|
||||
bpy.types.register(BONE_PT_constraints)
|
@ -1,953 +0,0 @@
|
||||
|
||||
import bpy
|
||||
|
||||
from buttons_physics_common import point_cache_ui
|
||||
from buttons_physics_common import effector_weights_ui
|
||||
from buttons_physics_common import basic_force_field_settings_ui
|
||||
from buttons_physics_common import basic_force_field_falloff_ui
|
||||
|
||||
def particle_panel_enabled(context, psys):
|
||||
return psys.point_cache.baked==False and psys.edited==False and (not context.particle_system_editable)
|
||||
|
||||
def particle_panel_poll(context):
|
||||
psys = context.particle_system
|
||||
if psys==None: return False
|
||||
if psys.settings==None: return False
|
||||
return psys.settings.type in ('EMITTER', 'REACTOR', 'HAIR')
|
||||
|
||||
|
||||
class ParticleButtonsPanel(bpy.types.Panel):
|
||||
__space_type__ = 'PROPERTIES'
|
||||
__region_type__ = 'WINDOW'
|
||||
__context__ = "particle"
|
||||
|
||||
def poll(self, context):
|
||||
return particle_panel_poll(context)
|
||||
|
||||
class PARTICLE_PT_particles(ParticleButtonsPanel):
|
||||
__show_header__ = False
|
||||
|
||||
def poll(self, context):
|
||||
return (context.particle_system or context.object)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
ob = context.object
|
||||
psys = context.particle_system
|
||||
|
||||
if ob:
|
||||
row = layout.row()
|
||||
|
||||
row.template_list(ob, "particle_systems", ob, "active_particle_system_index", rows=2)
|
||||
|
||||
col = row.column(align=True)
|
||||
col.itemO("object.particle_system_add", icon='ICON_ZOOMIN', text="")
|
||||
col.itemO("object.particle_system_remove", icon='ICON_ZOOMOUT', text="")
|
||||
|
||||
if psys and not psys.settings:
|
||||
split = layout.split(percentage=0.32)
|
||||
col = split.column()
|
||||
col.itemL(text="Name:")
|
||||
col.itemL(text="Settings:")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(psys, "name", text="")
|
||||
col.template_ID(psys, "settings", new="particle.new")
|
||||
elif psys:
|
||||
part = psys.settings
|
||||
|
||||
split = layout.split(percentage=0.32)
|
||||
col = split.column()
|
||||
col.itemL(text="Name:")
|
||||
if part.type in ('EMITTER', 'REACTOR', 'HAIR'):
|
||||
col.itemL(text="Settings:")
|
||||
col.itemL(text="Type:")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(psys, "name", text="")
|
||||
if part.type in ('EMITTER', 'REACTOR', 'HAIR'):
|
||||
col.template_ID(psys, "settings", new="particle.new")
|
||||
|
||||
#row = layout.row()
|
||||
#row.itemL(text="Viewport")
|
||||
#row.itemL(text="Render")
|
||||
|
||||
if part:
|
||||
if part.type not in ('EMITTER', 'REACTOR', 'HAIR'):
|
||||
layout.itemL(text="No settings for fluid particles")
|
||||
return
|
||||
|
||||
row=col.row()
|
||||
row.enabled = particle_panel_enabled(context, psys)
|
||||
row.itemR(part, "type", text="")
|
||||
row.itemR(psys, "seed")
|
||||
|
||||
split = layout.split(percentage=0.65)
|
||||
if part.type=='HAIR':
|
||||
if psys.edited==True:
|
||||
split.itemO("particle.edited_clear", text="Free Edit")
|
||||
else:
|
||||
split.itemL(text="")
|
||||
row = split.row()
|
||||
row.enabled = particle_panel_enabled(context, psys)
|
||||
row.itemR(part, "hair_step")
|
||||
if psys.edited==True:
|
||||
if psys.global_hair:
|
||||
layout.itemO("particle.connect_hair")
|
||||
layout.itemL(text="Hair is disconnected.")
|
||||
else:
|
||||
layout.itemO("particle.disconnect_hair")
|
||||
layout.itemL(text="")
|
||||
elif part.type=='REACTOR':
|
||||
split.enabled = particle_panel_enabled(context, psys)
|
||||
split.itemR(psys, "reactor_target_object")
|
||||
split.itemR(psys, "reactor_target_particle_system", text="Particle System")
|
||||
|
||||
class PARTICLE_PT_emission(ParticleButtonsPanel):
|
||||
__label__ = "Emission"
|
||||
|
||||
def poll(self, context):
|
||||
if particle_panel_poll(context):
|
||||
return not context.particle_system.point_cache.external
|
||||
else:
|
||||
return False
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
psys = context.particle_system
|
||||
part = psys.settings
|
||||
|
||||
layout.enabled = particle_panel_enabled(context, psys) and not psys.multiple_caches
|
||||
|
||||
row = layout.row()
|
||||
row.active = part.distribution != 'GRID'
|
||||
row.itemR(part, "amount")
|
||||
|
||||
if part.type != 'HAIR':
|
||||
split = layout.split()
|
||||
|
||||
col = split.column(align=True)
|
||||
col.itemR(part, "start")
|
||||
col.itemR(part, "end")
|
||||
|
||||
col = split.column(align=True)
|
||||
col.itemR(part, "lifetime")
|
||||
col.itemR(part, "random_lifetime", slider=True)
|
||||
|
||||
layout.row().itemL(text="Emit From:")
|
||||
|
||||
row = layout.row()
|
||||
row.itemR(part, "emit_from", expand=True)
|
||||
row = layout.row()
|
||||
row.itemR(part, "trand")
|
||||
if part.distribution!='GRID':
|
||||
row.itemR(part, "even_distribution")
|
||||
|
||||
if part.emit_from=='FACE' or part.emit_from=='VOLUME':
|
||||
row = layout.row()
|
||||
row.itemR(part, "distribution", expand=True)
|
||||
|
||||
row = layout.row()
|
||||
|
||||
if part.distribution=='JIT':
|
||||
row.itemR(part, "userjit", text="Particles/Face")
|
||||
row.itemR(part, "jitter_factor", text="Jittering Amount", slider=True)
|
||||
elif part.distribution=='GRID':
|
||||
row.itemR(part, "grid_resolution")
|
||||
|
||||
class PARTICLE_PT_hair_dynamics(ParticleButtonsPanel):
|
||||
__label__ = "Hair dynamics"
|
||||
__default_closed__ = True
|
||||
|
||||
def poll(self, context):
|
||||
psys = context.particle_system
|
||||
if psys==None: return False
|
||||
if psys.settings==None: return False
|
||||
return psys.settings.type == 'HAIR'
|
||||
|
||||
def draw_header(self, context):
|
||||
#cloth = context.cloth.collision_settings
|
||||
|
||||
#self.layout.active = cloth_panel_enabled(context.cloth)
|
||||
#self.layout.itemR(cloth, "enable_collision", text="")
|
||||
psys = context.particle_system
|
||||
self.layout.itemR(psys, "hair_dynamics", text="")
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
psys = context.particle_system
|
||||
part = psys.settings
|
||||
cloth = psys.cloth.settings
|
||||
|
||||
layout.enabled = psys.hair_dynamics
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Material:")
|
||||
sub = col.column(align=True)
|
||||
sub.itemR(cloth, "pin_stiffness", text="Stiffness")
|
||||
sub.itemR(cloth, "mass")
|
||||
sub.itemR(cloth, "bending_stiffness", text="Bending")
|
||||
sub.itemR(cloth, "internal_friction", slider="True")
|
||||
|
||||
col = split.column()
|
||||
|
||||
col.itemL(text="Damping:")
|
||||
sub = col.column(align=True)
|
||||
sub.itemR(cloth, "spring_damping", text="Spring")
|
||||
sub.itemR(cloth, "air_damping", text="Air")
|
||||
|
||||
col.itemL(text="Quality:")
|
||||
col.itemR(cloth, "quality", text="Steps",slider=True)
|
||||
|
||||
class PARTICLE_PT_cache(ParticleButtonsPanel):
|
||||
__label__ = "Cache"
|
||||
__default_closed__ = True
|
||||
|
||||
def poll(self, context):
|
||||
psys = context.particle_system
|
||||
if psys==None: return False
|
||||
if psys.settings==None: return False
|
||||
phystype = psys.settings.physics_type
|
||||
if phystype == 'NO' or phystype == 'KEYED':
|
||||
return False
|
||||
return psys.settings.type in ('EMITTER', 'REACTOR') or (psys.settings.type == 'HAIR' and psys.hair_dynamics)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
psys = context.particle_system
|
||||
|
||||
point_cache_ui(self, psys.point_cache, particle_panel_enabled(context, psys), not psys.hair_dynamics, 0)
|
||||
|
||||
class PARTICLE_PT_velocity(ParticleButtonsPanel):
|
||||
__label__ = "Velocity"
|
||||
|
||||
def poll(self, context):
|
||||
if particle_panel_poll(context):
|
||||
psys = context.particle_system
|
||||
return psys.settings.physics_type != 'BOIDS' and not psys.point_cache.external
|
||||
else:
|
||||
return False
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
psys = context.particle_system
|
||||
part = psys.settings
|
||||
|
||||
layout.enabled = particle_panel_enabled(context, psys)
|
||||
|
||||
split = layout.split()
|
||||
|
||||
sub = split.column()
|
||||
sub.itemL(text="Emitter Geometry:")
|
||||
sub.itemR(part, "normal_factor")
|
||||
subsub = sub.column(align=True)
|
||||
subsub.itemR(part, "tangent_factor")
|
||||
subsub.itemR(part, "tangent_phase", slider=True)
|
||||
|
||||
sub = split.column()
|
||||
sub.itemL(text="Emitter Object")
|
||||
sub.itemR(part, "object_aligned_factor", text="")
|
||||
|
||||
layout.row().itemL(text="Other:")
|
||||
split = layout.split()
|
||||
sub = split.column()
|
||||
if part.emit_from=='PARTICLE':
|
||||
sub.itemR(part, "particle_factor")
|
||||
else:
|
||||
sub.itemR(part, "object_factor", slider=True)
|
||||
sub = split.column()
|
||||
sub.itemR(part, "random_factor")
|
||||
|
||||
#if part.type=='REACTOR':
|
||||
# sub.itemR(part, "reactor_factor")
|
||||
# sub.itemR(part, "reaction_shape", slider=True)
|
||||
|
||||
class PARTICLE_PT_rotation(ParticleButtonsPanel):
|
||||
__label__ = "Rotation"
|
||||
|
||||
def poll(self, context):
|
||||
if particle_panel_poll(context):
|
||||
psys = context.particle_system
|
||||
return psys.settings.physics_type != 'BOIDS' and not psys.point_cache.external
|
||||
else:
|
||||
return False
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
psys = context.particle_system
|
||||
part = psys.settings
|
||||
|
||||
layout.enabled = particle_panel_enabled(context, psys)
|
||||
|
||||
split = layout.split()
|
||||
split.itemL(text="Initial Rotation:")
|
||||
split.itemR(part, "rotation_dynamic")
|
||||
split = layout.split()
|
||||
|
||||
sub = split.column(align=True)
|
||||
sub.itemR(part, "rotation_mode", text="")
|
||||
sub.itemR(part, "random_rotation_factor", slider=True, text="Random")
|
||||
|
||||
sub = split.column(align=True)
|
||||
sub.itemR(part, "phase_factor", slider=True)
|
||||
sub.itemR(part, "random_phase_factor", text="Random", slider=True)
|
||||
|
||||
layout.row().itemL(text="Angular Velocity:")
|
||||
layout.row().itemR(part, "angular_velocity_mode", expand=True)
|
||||
split = layout.split()
|
||||
|
||||
sub = split.column()
|
||||
|
||||
sub.itemR(part, "angular_velocity_factor", text="")
|
||||
|
||||
class PARTICLE_PT_physics(ParticleButtonsPanel):
|
||||
__label__ = "Physics"
|
||||
|
||||
def poll(self, context):
|
||||
if particle_panel_poll(context):
|
||||
return not context.particle_system.point_cache.external
|
||||
else:
|
||||
return False
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
psys = context.particle_system
|
||||
part = psys.settings
|
||||
|
||||
layout.enabled = particle_panel_enabled(context, psys)
|
||||
|
||||
row = layout.row()
|
||||
row.itemR(part, "physics_type", expand=True)
|
||||
if part.physics_type != 'NO':
|
||||
row = layout.row()
|
||||
col = row.column(align=True)
|
||||
col.itemR(part, "particle_size")
|
||||
col.itemR(part, "random_size", slider=True)
|
||||
col = row.column(align=True)
|
||||
col.itemR(part, "mass")
|
||||
col.itemR(part, "sizemass", text="Multiply mass with size")
|
||||
|
||||
if part.physics_type == 'NEWTON':
|
||||
split = layout.split()
|
||||
sub = split.column()
|
||||
|
||||
sub.itemL(text="Forces:")
|
||||
sub.itemR(part, "brownian_factor")
|
||||
sub.itemR(part, "drag_factor", slider=True)
|
||||
sub.itemR(part, "damp_factor", slider=True)
|
||||
sub = split.column()
|
||||
sub.itemR(part, "size_deflect")
|
||||
sub.itemR(part, "die_on_collision")
|
||||
sub.itemR(part, "integrator")
|
||||
sub.itemR(part, "time_tweak")
|
||||
|
||||
elif part.physics_type == 'KEYED':
|
||||
split = layout.split()
|
||||
sub = split.column()
|
||||
|
||||
row = layout.row()
|
||||
col = row.column()
|
||||
col.active = not psys.keyed_timing
|
||||
col.itemR(part, "keyed_loops", text="Loops")
|
||||
row.itemR(psys, "keyed_timing", text="Use Timing")
|
||||
|
||||
layout.itemL(text="Keys:")
|
||||
elif part.physics_type=='BOIDS':
|
||||
boids = part.boids
|
||||
|
||||
|
||||
row = layout.row()
|
||||
row.itemR(boids, "allow_flight")
|
||||
row.itemR(boids, "allow_land")
|
||||
row.itemR(boids, "allow_climb")
|
||||
|
||||
split = layout.split()
|
||||
|
||||
sub = split.column()
|
||||
col = sub.column(align=True)
|
||||
col.active = boids.allow_flight
|
||||
col.itemR(boids, "air_max_speed")
|
||||
col.itemR(boids, "air_min_speed", slider="True")
|
||||
col.itemR(boids, "air_max_acc", slider="True")
|
||||
col.itemR(boids, "air_max_ave", slider="True")
|
||||
col.itemR(boids, "air_personal_space")
|
||||
row = col.row()
|
||||
row.active = (boids.allow_land or boids.allow_climb) and boids.allow_flight
|
||||
row.itemR(boids, "landing_smoothness")
|
||||
|
||||
sub = split.column()
|
||||
col = sub.column(align=True)
|
||||
col.active = boids.allow_land or boids.allow_climb
|
||||
col.itemR(boids, "land_max_speed")
|
||||
col.itemR(boids, "land_jump_speed")
|
||||
col.itemR(boids, "land_max_acc", slider="True")
|
||||
col.itemR(boids, "land_max_ave", slider="True")
|
||||
col.itemR(boids, "land_personal_space")
|
||||
col.itemR(boids, "land_stick_force")
|
||||
|
||||
row = layout.row()
|
||||
|
||||
col = row.column(align=True)
|
||||
col.itemL(text="Battle:")
|
||||
col.itemR(boids, "health")
|
||||
col.itemR(boids, "strength")
|
||||
col.itemR(boids, "aggression")
|
||||
col.itemR(boids, "accuracy")
|
||||
col.itemR(boids, "range")
|
||||
|
||||
col = row.column()
|
||||
col.itemL(text="Misc:")
|
||||
col.itemR(boids, "banking", slider=True)
|
||||
col.itemR(boids, "height", slider=True)
|
||||
|
||||
if part.physics_type=='KEYED' or part.physics_type=='BOIDS':
|
||||
if part.physics_type=='BOIDS':
|
||||
layout.itemL(text="Relations:")
|
||||
|
||||
row = layout.row()
|
||||
row.template_list(psys, "targets", psys, "active_particle_target_index")
|
||||
|
||||
col = row.column()
|
||||
subrow = col.row()
|
||||
subcol = subrow.column(align=True)
|
||||
subcol.itemO("particle.new_target", icon='ICON_ZOOMIN', text="")
|
||||
subcol.itemO("particle.remove_target", icon='ICON_ZOOMOUT', text="")
|
||||
subrow = col.row()
|
||||
subcol = subrow.column(align=True)
|
||||
subcol.itemO("particle.target_move_up", icon='VICON_MOVE_UP', text="")
|
||||
subcol.itemO("particle.target_move_down", icon='VICON_MOVE_DOWN', text="")
|
||||
|
||||
key = psys.active_particle_target
|
||||
if key:
|
||||
row = layout.row()
|
||||
if part.physics_type=='KEYED':
|
||||
col = row.column()
|
||||
#doesn't work yet
|
||||
#col.red_alert = key.valid
|
||||
col.itemR(key, "object", text="")
|
||||
col.itemR(key, "system", text="System")
|
||||
col = row.column();
|
||||
col.active = psys.keyed_timing
|
||||
col.itemR(key, "time")
|
||||
col.itemR(key, "duration")
|
||||
else:
|
||||
subrow = row.row()
|
||||
#doesn't work yet
|
||||
#subrow.red_alert = key.valid
|
||||
subrow.itemR(key, "object", text="")
|
||||
subrow.itemR(key, "system", text="System")
|
||||
|
||||
layout.itemR(key, "mode", expand=True)
|
||||
|
||||
class PARTICLE_PT_boidbrain(ParticleButtonsPanel):
|
||||
__label__ = "Boid Brain"
|
||||
|
||||
def poll(self, context):
|
||||
psys = context.particle_system
|
||||
if psys==None: return False
|
||||
if psys.settings==None: return False
|
||||
if psys.point_cache.external: return False
|
||||
return psys.settings.physics_type=='BOIDS'
|
||||
|
||||
def draw(self, context):
|
||||
boids = context.particle_system.settings.boids
|
||||
layout = self.layout
|
||||
|
||||
layout.enabled = particle_panel_enabled(context, context.particle_system)
|
||||
|
||||
# Currently boids can only use the first state so these are commented out for now.
|
||||
#row = layout.row()
|
||||
#row.template_list(boids, "states", boids, "active_boid_state_index", compact="True")
|
||||
#col = row.row()
|
||||
#subrow = col.row(align=True)
|
||||
#subrow.itemO("boid.state_add", icon='ICON_ZOOMIN', text="")
|
||||
#subrow.itemO("boid.state_del", icon='ICON_ZOOMOUT', text="")
|
||||
#subrow = row.row(align=True)
|
||||
#subrow.itemO("boid.state_move_up", icon='VICON_MOVE_UP', text="")
|
||||
#subrow.itemO("boid.state_move_down", icon='VICON_MOVE_DOWN', text="")
|
||||
|
||||
state = boids.active_boid_state
|
||||
|
||||
#layout.itemR(state, "name", text="State name")
|
||||
|
||||
row = layout.row()
|
||||
row.itemR(state, "ruleset_type")
|
||||
if state.ruleset_type=='FUZZY':
|
||||
row.itemR(state, "rule_fuzziness", slider=True)
|
||||
else:
|
||||
row.itemL(text="")
|
||||
|
||||
row = layout.row()
|
||||
row.template_list(state, "rules", state, "active_boid_rule_index")
|
||||
|
||||
col = row.column()
|
||||
subrow = col.row()
|
||||
subcol = subrow.column(align=True)
|
||||
subcol.item_menu_enumO("boid.rule_add", "type", icon='ICON_ZOOMIN', text="")
|
||||
subcol.itemO("boid.rule_del", icon='ICON_ZOOMOUT', text="")
|
||||
subrow = col.row()
|
||||
subcol = subrow.column(align=True)
|
||||
subcol.itemO("boid.rule_move_up", icon='VICON_MOVE_UP', text="")
|
||||
subcol.itemO("boid.rule_move_down", icon='VICON_MOVE_DOWN', text="")
|
||||
|
||||
rule = state.active_boid_rule
|
||||
|
||||
if rule:
|
||||
row = layout.row()
|
||||
row.itemR(rule, "name", text="")
|
||||
#somebody make nice icons for boids here please! -jahka
|
||||
row.itemR(rule, "in_air", icon='VICON_MOVE_UP', text="")
|
||||
row.itemR(rule, "on_land", icon='VICON_MOVE_DOWN', text="")
|
||||
|
||||
row = layout.row()
|
||||
|
||||
if rule.type == 'GOAL':
|
||||
row.itemR(rule, "object")
|
||||
row = layout.row()
|
||||
row.itemR(rule, "predict")
|
||||
elif rule.type == 'AVOID':
|
||||
row.itemR(rule, "object")
|
||||
row = layout.row()
|
||||
row.itemR(rule, "predict")
|
||||
row.itemR(rule, "fear_factor")
|
||||
elif rule.type == 'FOLLOW_PATH':
|
||||
row.itemL(text="Not yet functional.")
|
||||
elif rule.type == 'AVOID_COLLISION':
|
||||
row.itemR(rule, "boids")
|
||||
row.itemR(rule, "deflectors")
|
||||
row.itemR(rule, "look_ahead")
|
||||
elif rule.type == 'FOLLOW_LEADER':
|
||||
row.itemR(rule, "object", text="")
|
||||
row.itemR(rule, "distance")
|
||||
row = layout.row()
|
||||
row.itemR(rule, "line")
|
||||
subrow = row.row()
|
||||
subrow.active = rule.line
|
||||
subrow.itemR(rule, "queue_size")
|
||||
elif rule.type == 'AVERAGE_SPEED':
|
||||
row.itemR(rule, "speed", slider=True)
|
||||
row.itemR(rule, "wander", slider=True)
|
||||
row.itemR(rule, "level", slider=True)
|
||||
elif rule.type == 'FIGHT':
|
||||
row.itemR(rule, "distance")
|
||||
row.itemR(rule, "flee_distance")
|
||||
|
||||
|
||||
class PARTICLE_PT_render(ParticleButtonsPanel):
|
||||
__label__ = "Render"
|
||||
|
||||
def poll(self, context):
|
||||
psys = context.particle_system
|
||||
if psys==None: return False
|
||||
if psys.settings==None: return False
|
||||
return True;
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
psys = context.particle_system
|
||||
part = psys.settings
|
||||
|
||||
row = layout.row()
|
||||
row.itemR(part, "material")
|
||||
row.itemR(psys, "parent");
|
||||
|
||||
split = layout.split()
|
||||
|
||||
sub = split.column()
|
||||
sub.itemR(part, "emitter");
|
||||
sub.itemR(part, "parent");
|
||||
sub = split.column()
|
||||
sub.itemR(part, "unborn");
|
||||
sub.itemR(part, "died");
|
||||
|
||||
row = layout.row()
|
||||
row.itemR(part, "ren_as", expand=True)
|
||||
|
||||
split = layout.split()
|
||||
|
||||
sub = split.column()
|
||||
|
||||
if part.ren_as == 'LINE':
|
||||
sub.itemR(part, "line_length_tail")
|
||||
sub.itemR(part, "line_length_head")
|
||||
sub = split.column()
|
||||
sub.itemR(part, "velocity_length")
|
||||
elif part.ren_as == 'PATH':
|
||||
|
||||
if (part.type!='HAIR' and part.physics_type!='KEYED' and psys.point_cache.baked==False):
|
||||
box = layout.box()
|
||||
box.itemL(text="Baked or keyed particles needed for correct rendering.")
|
||||
return
|
||||
|
||||
sub.itemR(part, "render_strand")
|
||||
colsub = sub.column()
|
||||
colsub.active = part.render_strand == False
|
||||
colsub.itemR(part, "render_adaptive")
|
||||
colsub = sub.column()
|
||||
colsub.active = part.render_adaptive or part.render_strand == True
|
||||
colsub.itemR(part, "adaptive_angle")
|
||||
colsub = sub.column()
|
||||
colsub.active = part.render_adaptive == True and part.render_strand == False
|
||||
colsub.itemR(part, "adaptive_pix")
|
||||
sub.itemR(part, "hair_bspline")
|
||||
sub.itemR(part, "render_step", text="Steps")
|
||||
sub = split.column()
|
||||
|
||||
sub.itemL(text="Timing:")
|
||||
sub.itemR(part, "abs_path_time")
|
||||
sub.itemR(part, "path_start", text="Start", slider= not part.abs_path_time)
|
||||
sub.itemR(part, "path_end", text="End", slider= not part.abs_path_time)
|
||||
sub.itemR(part, "random_length", text="Random", slider=True)
|
||||
|
||||
row = layout.row()
|
||||
col = row.column()
|
||||
|
||||
if part.type=='HAIR' and part.render_strand==True and part.child_type=='FACES':
|
||||
layout.itemR(part, "enable_simplify")
|
||||
if part.enable_simplify==True:
|
||||
row = layout.row()
|
||||
row.itemR(part, "simplify_refsize")
|
||||
row.itemR(part, "simplify_rate")
|
||||
row.itemR(part, "simplify_transition")
|
||||
row = layout.row()
|
||||
row.itemR(part, "viewport")
|
||||
subrow = row.row()
|
||||
subrow.active = part.viewport==True
|
||||
subrow.itemR(part, "simplify_viewport")
|
||||
|
||||
|
||||
elif part.ren_as == 'OBJECT':
|
||||
sub.itemR(part, "dupli_object")
|
||||
sub.itemR(part, "use_global_dupli")
|
||||
elif part.ren_as == 'GROUP':
|
||||
sub.itemR(part, "dupli_group")
|
||||
split = layout.split()
|
||||
sub = split.column()
|
||||
sub.itemR(part, "whole_group")
|
||||
colsub = sub.column()
|
||||
colsub.active = part.whole_group == False
|
||||
colsub.itemR(part, "use_group_count")
|
||||
|
||||
sub = split.column()
|
||||
colsub = sub.column()
|
||||
colsub.active = part.whole_group == False
|
||||
colsub.itemR(part, "use_global_dupli")
|
||||
colsub.itemR(part, "rand_group")
|
||||
|
||||
if part.use_group_count and not part.whole_group:
|
||||
row = layout.row()
|
||||
row.template_list(part, "dupliweights", part, "active_dupliweight_index")
|
||||
|
||||
col = row.column()
|
||||
subrow = col.row()
|
||||
subcol = subrow.column(align=True)
|
||||
subcol.itemO("particle.dupliob_copy", icon='ICON_ZOOMIN', text="")
|
||||
subcol.itemO("particle.dupliob_remove", icon='ICON_ZOOMOUT', text="")
|
||||
subcol.itemO("particle.dupliob_move_up", icon='VICON_MOVE_UP', text="")
|
||||
subcol.itemO("particle.dupliob_move_down", icon='VICON_MOVE_DOWN', text="")
|
||||
|
||||
weight = part.active_dupliweight
|
||||
if weight:
|
||||
row = layout.row()
|
||||
row.itemR(weight, "count")
|
||||
|
||||
elif part.ren_as == 'BILLBOARD':
|
||||
sub.itemL(text="Align:")
|
||||
|
||||
row = layout.row()
|
||||
row.itemR(part, "billboard_align", expand=True)
|
||||
row.itemR(part, "billboard_lock", text="Lock")
|
||||
row = layout.row()
|
||||
row.itemR(part, "billboard_object")
|
||||
|
||||
row = layout.row()
|
||||
col = row.column(align=True)
|
||||
col.itemL(text="Tilt:")
|
||||
col.itemR(part, "billboard_tilt", text="Angle", slider=True)
|
||||
col.itemR(part, "billboard_random_tilt", slider=True)
|
||||
col = row.column()
|
||||
col.itemR(part, "billboard_offset")
|
||||
|
||||
row = layout.row()
|
||||
row.itemR(psys, "billboard_normal_uv")
|
||||
row = layout.row()
|
||||
row.itemR(psys, "billboard_time_index_uv")
|
||||
|
||||
row = layout.row()
|
||||
row.itemL(text="Split uv's:")
|
||||
row.itemR(part, "billboard_uv_split", text="Number of splits")
|
||||
row = layout.row()
|
||||
row.itemR(psys, "billboard_split_uv")
|
||||
row = layout.row()
|
||||
row.itemL(text="Animate:")
|
||||
row.itemR(part, "billboard_animation", expand=True)
|
||||
row.itemL(text="Offset:")
|
||||
row.itemR(part, "billboard_split_offset", expand=True)
|
||||
if part.ren_as == 'HALO' or part.ren_as == 'LINE' or part.ren_as=='BILLBOARD':
|
||||
row = layout.row()
|
||||
col = row.column()
|
||||
col.itemR(part, "trail_count")
|
||||
if part.trail_count > 1:
|
||||
col.itemR(part, "abs_path_time", text="Length in frames")
|
||||
col = row.column()
|
||||
col.itemR(part, "path_end", text="Length", slider=not part.abs_path_time)
|
||||
col.itemR(part, "random_length", text="Random", slider=True)
|
||||
else:
|
||||
col = row.column()
|
||||
col.itemL(text="")
|
||||
|
||||
class PARTICLE_PT_draw(ParticleButtonsPanel):
|
||||
__label__ = "Display"
|
||||
__default_closed__ = True
|
||||
|
||||
def poll(self, context):
|
||||
psys = context.particle_system
|
||||
if psys==None: return False
|
||||
if psys.settings==None: return False
|
||||
return True;
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
psys = context.particle_system
|
||||
part = psys.settings
|
||||
|
||||
row = layout.row()
|
||||
row.itemR(part, "draw_as", expand=True)
|
||||
|
||||
if part.draw_as=='NONE' or (part.ren_as=='NONE' and part.draw_as=='RENDER'):
|
||||
return
|
||||
|
||||
path = (part.ren_as=='PATH' and part.draw_as=='RENDER') or part.draw_as=='PATH'
|
||||
|
||||
if path and part.type!='HAIR' and part.physics_type!='KEYED' and psys.point_cache.baked==False:
|
||||
box = layout.box()
|
||||
box.itemL(text="Baked or keyed particles needed for correct drawing.")
|
||||
return
|
||||
|
||||
row = layout.row()
|
||||
row.itemR(part, "display", slider=True)
|
||||
if part.draw_as!='RENDER' or part.ren_as=='HALO':
|
||||
row.itemR(part, "draw_size")
|
||||
else:
|
||||
row.itemL(text="")
|
||||
|
||||
row = layout.row()
|
||||
col = row.column()
|
||||
col.itemR(part, "show_size")
|
||||
col.itemR(part, "velocity")
|
||||
col.itemR(part, "num")
|
||||
if part.physics_type == 'BOIDS':
|
||||
col.itemR(part, "draw_health")
|
||||
|
||||
col = row.column()
|
||||
col.itemR(part, "material_color", text="Use material color")
|
||||
|
||||
if (path):
|
||||
col.itemR(part, "draw_step")
|
||||
else:
|
||||
subcol = col.column()
|
||||
subcol.active = part.material_color==False
|
||||
#subcol.itemL(text="color")
|
||||
#subcol.itemL(text="Override material color")
|
||||
|
||||
class PARTICLE_PT_children(ParticleButtonsPanel):
|
||||
__label__ = "Children"
|
||||
__default_closed__ = True
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
psys = context.particle_system
|
||||
part = psys.settings
|
||||
|
||||
layout.row().itemR(part, "child_type", expand=True)
|
||||
|
||||
if part.child_type=='NONE':
|
||||
return
|
||||
|
||||
row = layout.row()
|
||||
|
||||
col = row.column(align=True)
|
||||
col.itemR(part, "child_nbr", text="Display")
|
||||
col.itemR(part, "rendered_child_nbr", text="Render")
|
||||
|
||||
col = row.column(align=True)
|
||||
|
||||
if part.child_type=='FACES':
|
||||
col.itemR(part, "virtual_parents", slider=True)
|
||||
else:
|
||||
col.itemR(part, "child_radius", text="Radius")
|
||||
col.itemR(part, "child_roundness", text="Roundness", slider=True)
|
||||
|
||||
col = row.column(align=True)
|
||||
col.itemR(part, "child_size", text="Size")
|
||||
col.itemR(part, "child_random_size", text="Random")
|
||||
|
||||
layout.row().itemL(text="Effects:")
|
||||
|
||||
row = layout.row()
|
||||
|
||||
col = row.column(align=True)
|
||||
col.itemR(part, "clump_factor", slider=True)
|
||||
col.itemR(part, "clumppow", slider=True)
|
||||
|
||||
col = row.column(align=True)
|
||||
col.itemR(part, "rough_endpoint")
|
||||
col.itemR(part, "rough_end_shape")
|
||||
|
||||
row = layout.row()
|
||||
|
||||
col = row.column(align=True)
|
||||
col.itemR(part, "rough1")
|
||||
col.itemR(part, "rough1_size")
|
||||
|
||||
col = row.column(align=True)
|
||||
col.itemR(part, "rough2")
|
||||
col.itemR(part, "rough2_size")
|
||||
col.itemR(part, "rough2_thres", slider=True)
|
||||
|
||||
row = layout.row()
|
||||
col = row.column(align=True)
|
||||
col.itemR(part, "child_length", slider=True)
|
||||
col.itemR(part, "child_length_thres", slider=True)
|
||||
|
||||
col = row.column(align=True)
|
||||
col.itemL(text="Space reserved for")
|
||||
col.itemL(text="hair parting controls")
|
||||
|
||||
layout.row().itemL(text="Kink:")
|
||||
layout.row().itemR(part, "kink", expand=True)
|
||||
|
||||
split = layout.split()
|
||||
|
||||
sub = split.column()
|
||||
sub.itemR(part, "kink_amplitude")
|
||||
sub.itemR(part, "kink_frequency")
|
||||
sub = split.column()
|
||||
sub.itemR(part, "kink_shape", slider=True)
|
||||
|
||||
class PARTICLE_PT_field_weights(ParticleButtonsPanel):
|
||||
__label__ = "Field Weights"
|
||||
__default_closed__ = True
|
||||
|
||||
def draw(self, context):
|
||||
part = context.particle_system.settings
|
||||
effector_weights_ui(self, part.effector_weights)
|
||||
|
||||
if part.type == 'HAIR':
|
||||
self.layout.itemR(part.effector_weights, "do_growing_hair")
|
||||
|
||||
class PARTICLE_PT_force_fields(ParticleButtonsPanel):
|
||||
__label__ = "Force Field Settings"
|
||||
__default_closed__ = True
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
part = context.particle_system.settings
|
||||
|
||||
layout.itemR(part, "self_effect")
|
||||
|
||||
split = layout.split(percentage=0.2)
|
||||
split.itemL(text="Type 1:")
|
||||
split.itemR(part.force_field_1, "type",text="")
|
||||
basic_force_field_settings_ui(self, part.force_field_1)
|
||||
basic_force_field_falloff_ui(self, part.force_field_1)
|
||||
|
||||
if part.force_field_1.type != 'NONE':
|
||||
layout.itemL(text="")
|
||||
|
||||
split = layout.split(percentage=0.2)
|
||||
split.itemL(text="Type 2:")
|
||||
split.itemR(part.force_field_2, "type",text="")
|
||||
basic_force_field_settings_ui(self, part.force_field_2)
|
||||
basic_force_field_falloff_ui(self, part.force_field_2)
|
||||
|
||||
class PARTICLE_PT_vertexgroups(ParticleButtonsPanel):
|
||||
__label__ = "Vertexgroups"
|
||||
__default_closed__ = True
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
psys = context.particle_system
|
||||
part = psys.settings
|
||||
|
||||
layout.itemL(text="Nothing here yet.")
|
||||
|
||||
#row = layout.row()
|
||||
#row.itemL(text="Vertex Group")
|
||||
#row.itemL(text="Negate")
|
||||
|
||||
|
||||
#row = layout.row()
|
||||
#row.itemR(psys, "vertex_group_density")
|
||||
#row.itemR(psys, "vertex_group_density_negate", text="")
|
||||
|
||||
#row = layout.row()
|
||||
#row.itemR(psys, "vertex_group_velocity")
|
||||
#row.itemR(psys, "vertex_group_velocity_negate", text="")
|
||||
|
||||
#row = layout.row()
|
||||
#row.itemR(psys, "vertex_group_length")
|
||||
#row.itemR(psys, "vertex_group_length_negate", text="")
|
||||
|
||||
#row = layout.row()
|
||||
#row.itemR(psys, "vertex_group_clump")
|
||||
#row.itemR(psys, "vertex_group_clump_negate", text="")
|
||||
|
||||
#row = layout.row()
|
||||
#row.itemR(psys, "vertex_group_kink")
|
||||
#row.itemR(psys, "vertex_group_kink_negate", text="")
|
||||
|
||||
#row = layout.row()
|
||||
#row.itemR(psys, "vertex_group_roughness1")
|
||||
#row.itemR(psys, "vertex_group_roughness1_negate", text="")
|
||||
|
||||
#row = layout.row()
|
||||
#row.itemR(psys, "vertex_group_roughness2")
|
||||
#row.itemR(psys, "vertex_group_roughness2_negate", text="")
|
||||
|
||||
#row = layout.row()
|
||||
#row.itemR(psys, "vertex_group_roughness_end")
|
||||
#row.itemR(psys, "vertex_group_roughness_end_negate", text="")
|
||||
|
||||
#row = layout.row()
|
||||
#row.itemR(psys, "vertex_group_size")
|
||||
#row.itemR(psys, "vertex_group_size_negate", text="")
|
||||
|
||||
#row = layout.row()
|
||||
#row.itemR(psys, "vertex_group_tangent")
|
||||
#row.itemR(psys, "vertex_group_tangent_negate", text="")
|
||||
|
||||
#row = layout.row()
|
||||
#row.itemR(psys, "vertex_group_rotation")
|
||||
#row.itemR(psys, "vertex_group_rotation_negate", text="")
|
||||
|
||||
#row = layout.row()
|
||||
#row.itemR(psys, "vertex_group_field")
|
||||
#row.itemR(psys, "vertex_group_field_negate", text="")
|
||||
|
||||
bpy.types.register(PARTICLE_PT_particles)
|
||||
bpy.types.register(PARTICLE_PT_hair_dynamics)
|
||||
bpy.types.register(PARTICLE_PT_cache)
|
||||
bpy.types.register(PARTICLE_PT_emission)
|
||||
bpy.types.register(PARTICLE_PT_velocity)
|
||||
bpy.types.register(PARTICLE_PT_rotation)
|
||||
bpy.types.register(PARTICLE_PT_physics)
|
||||
bpy.types.register(PARTICLE_PT_boidbrain)
|
||||
bpy.types.register(PARTICLE_PT_render)
|
||||
bpy.types.register(PARTICLE_PT_draw)
|
||||
bpy.types.register(PARTICLE_PT_children)
|
||||
bpy.types.register(PARTICLE_PT_field_weights)
|
||||
bpy.types.register(PARTICLE_PT_force_fields)
|
||||
bpy.types.register(PARTICLE_PT_vertexgroups)
|
@ -1,186 +0,0 @@
|
||||
|
||||
import bpy
|
||||
|
||||
from buttons_physics_common import point_cache_ui
|
||||
from buttons_physics_common import effector_weights_ui
|
||||
|
||||
def cloth_panel_enabled(md):
|
||||
return md.point_cache.baked==False
|
||||
|
||||
class PhysicButtonsPanel(bpy.types.Panel):
|
||||
__space_type__ = 'PROPERTIES'
|
||||
__region_type__ = 'WINDOW'
|
||||
__context__ = "physics"
|
||||
|
||||
def poll(self, context):
|
||||
ob = context.object
|
||||
rd = context.scene.render_data
|
||||
return (ob and ob.type == 'MESH') and (not rd.use_game_engine)
|
||||
|
||||
class PHYSICS_PT_cloth(PhysicButtonsPanel):
|
||||
__label__ = "Cloth"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
md = context.cloth
|
||||
ob = context.object
|
||||
|
||||
split = layout.split()
|
||||
split.operator_context = 'EXEC_DEFAULT'
|
||||
|
||||
if md:
|
||||
# remove modifier + settings
|
||||
split.set_context_pointer("modifier", md)
|
||||
split.itemO("object.modifier_remove", text="Remove")
|
||||
|
||||
row = split.row(align=True)
|
||||
row.itemR(md, "render", text="")
|
||||
row.itemR(md, "realtime", text="")
|
||||
else:
|
||||
# add modifier
|
||||
split.item_enumO("object.modifier_add", "type", 'CLOTH', text="Add")
|
||||
split.itemL()
|
||||
|
||||
if md:
|
||||
cloth = md.settings
|
||||
|
||||
layout.active = cloth_panel_enabled(md)
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Material:")
|
||||
sub = col.column(align=True)
|
||||
sub.itemR(cloth, "mass")
|
||||
sub.itemR(cloth, "structural_stiffness", text="Structural")
|
||||
sub.itemR(cloth, "bending_stiffness", text="Bending")
|
||||
|
||||
col.itemR(cloth, "pin_cloth", text="Pin")
|
||||
sub = col.column(align=True)
|
||||
sub.active = cloth.pin_cloth
|
||||
sub.itemR(cloth, "pin_stiffness", text="Stiffness")
|
||||
sub.item_pointerR(cloth, "mass_vertex_group", ob, "vertex_groups", text="")
|
||||
|
||||
col = split.column()
|
||||
|
||||
col.itemL(text="Damping:")
|
||||
sub = col.column(align=True)
|
||||
sub.itemR(cloth, "spring_damping", text="Spring")
|
||||
sub.itemR(cloth, "air_damping", text="Air")
|
||||
|
||||
col.itemL(text="Presets...")
|
||||
col.itemL(text="TODO!")
|
||||
|
||||
col.itemL(text="Quality:")
|
||||
col.itemR(cloth, "quality", text="Steps",slider=True)
|
||||
|
||||
# Disabled for now
|
||||
"""
|
||||
if cloth.mass_vertex_group:
|
||||
layout.itemL(text="Goal:")
|
||||
|
||||
col = layout.column_flow()
|
||||
col.itemR(cloth, "goal_default", text="Default")
|
||||
col.itemR(cloth, "goal_spring", text="Stiffness")
|
||||
col.itemR(cloth, "goal_friction", text="Friction")
|
||||
"""
|
||||
|
||||
class PHYSICS_PT_cloth_cache(PhysicButtonsPanel):
|
||||
__label__ = "Cloth Cache"
|
||||
__default_closed__ = True
|
||||
|
||||
def poll(self, context):
|
||||
return context.cloth
|
||||
|
||||
def draw(self, context):
|
||||
md = context.cloth
|
||||
point_cache_ui(self, md.point_cache, cloth_panel_enabled(md), 0, 0)
|
||||
|
||||
class PHYSICS_PT_cloth_collision(PhysicButtonsPanel):
|
||||
__label__ = "Cloth Collision"
|
||||
__default_closed__ = True
|
||||
|
||||
def poll(self, context):
|
||||
return context.cloth
|
||||
|
||||
def draw_header(self, context):
|
||||
cloth = context.cloth.collision_settings
|
||||
|
||||
self.layout.active = cloth_panel_enabled(context.cloth)
|
||||
self.layout.itemR(cloth, "enable_collision", text="")
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
cloth = context.cloth.collision_settings
|
||||
md = context.cloth
|
||||
|
||||
layout.active = cloth.enable_collision and cloth_panel_enabled(md)
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemR(cloth, "collision_quality", slider=True, text="Quality")
|
||||
col.itemR(cloth, "min_distance", slider=True, text="Distance")
|
||||
col.itemR(cloth, "friction")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(cloth, "enable_self_collision", text="Self Collision")
|
||||
sub = col.column()
|
||||
sub.active = cloth.enable_self_collision
|
||||
sub.itemR(cloth, "self_collision_quality", slider=True, text="Quality")
|
||||
sub.itemR(cloth, "self_min_distance", slider=True, text="Distance")
|
||||
|
||||
class PHYSICS_PT_cloth_stiffness(PhysicButtonsPanel):
|
||||
__label__ = "Cloth Stiffness Scaling"
|
||||
__default_closed__ = True
|
||||
|
||||
def poll(self, context):
|
||||
return context.cloth
|
||||
|
||||
def draw_header(self, context):
|
||||
cloth = context.cloth.settings
|
||||
|
||||
self.layout.active = cloth_panel_enabled(context.cloth)
|
||||
self.layout.itemR(cloth, "stiffness_scaling", text="")
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
md = context.cloth
|
||||
ob = context.object
|
||||
cloth = context.cloth.settings
|
||||
|
||||
layout.active = cloth.stiffness_scaling and cloth_panel_enabled(md)
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Structural Stiffness:")
|
||||
sub = col.column(align=True)
|
||||
sub.itemR(cloth, "structural_stiffness_max", text="Max")
|
||||
sub.item_pointerR(cloth, "structural_stiffness_vertex_group", ob, "vertex_groups", text="")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Bending Stiffness:")
|
||||
sub = col.column(align=True)
|
||||
sub.itemR(cloth, "bending_stiffness_max", text="Max")
|
||||
sub.item_pointerR(cloth, "bending_vertex_group", ob, "vertex_groups", text="")
|
||||
|
||||
class PHYSICS_PT_cloth_field_weights(PhysicButtonsPanel):
|
||||
__label__ = "Cloth Field Weights"
|
||||
__default_closed__ = True
|
||||
|
||||
def poll(self, context):
|
||||
return (context.cloth)
|
||||
|
||||
def draw(self, context):
|
||||
cloth = context.cloth.settings
|
||||
effector_weights_ui(self, cloth.effector_weights)
|
||||
|
||||
bpy.types.register(PHYSICS_PT_cloth)
|
||||
bpy.types.register(PHYSICS_PT_cloth_cache)
|
||||
bpy.types.register(PHYSICS_PT_cloth_collision)
|
||||
bpy.types.register(PHYSICS_PT_cloth_stiffness)
|
||||
bpy.types.register(PHYSICS_PT_cloth_field_weights)
|
@ -1,154 +0,0 @@
|
||||
import bpy
|
||||
|
||||
def point_cache_ui(self, cache, enabled, particles, smoke):
|
||||
layout = self.layout
|
||||
layout.set_context_pointer("PointCache", cache)
|
||||
|
||||
row = layout.row()
|
||||
row.template_list(cache, "point_cache_list", cache, "active_point_cache_index", rows=2 )
|
||||
col = row.column(align=True)
|
||||
col.itemO("ptcache.add_new", icon='ICON_ZOOMIN', text="")
|
||||
col.itemO("ptcache.remove", icon='ICON_ZOOMOUT', text="")
|
||||
|
||||
row = layout.row()
|
||||
row.itemL(text="File Name:")
|
||||
if particles:
|
||||
row.itemR(cache, "external")
|
||||
|
||||
if cache.external:
|
||||
split = layout.split(percentage=0.80)
|
||||
split.itemR(cache, "name", text="")
|
||||
split.itemR(cache, "index", text="")
|
||||
|
||||
layout.itemL(text="File Path:")
|
||||
layout.itemR(cache, "filepath", text="")
|
||||
|
||||
layout.itemL(text=cache.info)
|
||||
else:
|
||||
layout.itemR(cache, "name", text="")
|
||||
|
||||
if not particles:
|
||||
row = layout.row()
|
||||
row.enabled = enabled
|
||||
row.itemR(cache, "start_frame")
|
||||
row.itemR(cache, "end_frame")
|
||||
|
||||
row = layout.row()
|
||||
|
||||
if cache.baked == True:
|
||||
row.itemO("ptcache.free_bake", text="Free Bake")
|
||||
else:
|
||||
row.item_booleanO("ptcache.bake", "bake", True, text="Bake")
|
||||
|
||||
sub = row.row()
|
||||
sub.enabled = (cache.frames_skipped or cache.outdated) and enabled
|
||||
sub.itemO("ptcache.bake", "bake", False, text="Calculate to Current Frame")
|
||||
|
||||
row = layout.row()
|
||||
row.enabled = enabled
|
||||
row.itemO("ptcache.bake_from_cache", text="Current Cache to Bake")
|
||||
if not smoke:
|
||||
row.itemR(cache, "step");
|
||||
|
||||
if not smoke:
|
||||
row = layout.row()
|
||||
sub = row.row()
|
||||
sub.enabled = enabled
|
||||
sub.itemR(cache, "quick_cache")
|
||||
row.itemR(cache, "disk_cache")
|
||||
|
||||
layout.itemL(text=cache.info)
|
||||
|
||||
layout.itemS()
|
||||
|
||||
row = layout.row()
|
||||
row.item_booleanO("ptcache.bake_all", "bake", True, text="Bake All Dynamics")
|
||||
row.itemO("ptcache.free_bake_all", text="Free All Bakes")
|
||||
layout.itemO("ptcache.bake_all", "bake", False, text="Update All Dynamics to current frame")
|
||||
|
||||
def effector_weights_ui(self, weights):
|
||||
layout = self.layout
|
||||
|
||||
layout.itemR(weights, "group")
|
||||
|
||||
split = layout.split()
|
||||
split.itemR(weights, "gravity", slider=True)
|
||||
split.itemR(weights, "all", slider=True)
|
||||
|
||||
layout.itemS()
|
||||
|
||||
flow = layout.column_flow()
|
||||
flow.itemR(weights, "force", slider=True)
|
||||
flow.itemR(weights, "vortex", slider=True)
|
||||
flow.itemR(weights, "magnetic", slider=True)
|
||||
flow.itemR(weights, "wind", slider=True)
|
||||
flow.itemR(weights, "curveguide", slider=True)
|
||||
flow.itemR(weights, "texture", slider=True)
|
||||
flow.itemR(weights, "harmonic", slider=True)
|
||||
flow.itemR(weights, "charge", slider=True)
|
||||
flow.itemR(weights, "lennardjones", slider=True)
|
||||
flow.itemR(weights, "turbulence", slider=True)
|
||||
flow.itemR(weights, "drag", slider=True)
|
||||
flow.itemR(weights, "boid", slider=True)
|
||||
|
||||
def basic_force_field_settings_ui(self, field):
|
||||
layout = self.layout
|
||||
split = layout.split()
|
||||
|
||||
if not field or field.type == 'NONE':
|
||||
return
|
||||
|
||||
col = split.column()
|
||||
|
||||
if field.type == 'DRAG':
|
||||
col.itemR(field, "linear_drag", text="Linear")
|
||||
else:
|
||||
col.itemR(field, "strength")
|
||||
|
||||
if field.type == 'TURBULENCE':
|
||||
col.itemR(field, "size")
|
||||
col.itemR(field, "flow")
|
||||
elif field.type == 'HARMONIC':
|
||||
col.itemR(field, "harmonic_damping", text="Damping")
|
||||
elif field.type == 'VORTEX' and field.shape != 'POINT':
|
||||
col.itemR(field, "inflow")
|
||||
elif field.type == 'DRAG':
|
||||
col.itemR(field, "quadratic_drag", text="Quadratic")
|
||||
else:
|
||||
col.itemR(field, "flow")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(field, "noise")
|
||||
col.itemR(field, "seed")
|
||||
if field.type == 'TURBULENCE':
|
||||
col.itemR(field, "global_coordinates", text="Global")
|
||||
|
||||
row = layout.row()
|
||||
row.itemL(text="Effect point:")
|
||||
row.itemR(field, "do_location")
|
||||
row.itemR(field, "do_rotation")
|
||||
|
||||
|
||||
def basic_force_field_falloff_ui(self, field):
|
||||
layout = self.layout
|
||||
split = layout.split(percentage=0.35)
|
||||
|
||||
if not field or field.type == 'NONE':
|
||||
return
|
||||
|
||||
col = split.column()
|
||||
col.itemR(field, "z_direction", text="")
|
||||
col.itemR(field, "use_min_distance", text="Use Minimum")
|
||||
col.itemR(field, "use_max_distance", text="Use Maximum")
|
||||
col.itemR(field, "do_absorption")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(field, "falloff_power", text="Power")
|
||||
|
||||
sub = col.column()
|
||||
sub.active = field.use_min_distance
|
||||
sub.itemR(field, "minimum_distance", text="Distance")
|
||||
|
||||
sub = col.column()
|
||||
sub.active = field.use_max_distance
|
||||
sub.itemR(field, "maximum_distance", text="Distance")
|
@ -1,200 +0,0 @@
|
||||
|
||||
import bpy
|
||||
|
||||
from buttons_physics_common import basic_force_field_settings_ui
|
||||
from buttons_physics_common import basic_force_field_falloff_ui
|
||||
|
||||
class PhysicButtonsPanel(bpy.types.Panel):
|
||||
__space_type__ = 'PROPERTIES'
|
||||
__region_type__ = 'WINDOW'
|
||||
__context__ = "physics"
|
||||
|
||||
def poll(self, context):
|
||||
rd = context.scene.render_data
|
||||
return (context.object) and (not rd.use_game_engine)
|
||||
|
||||
class PHYSICS_PT_field(PhysicButtonsPanel):
|
||||
__label__ = "Force Fields"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
ob = context.object
|
||||
field = ob.field
|
||||
|
||||
split = layout.split(percentage=0.2)
|
||||
split.itemL(text="Type:")
|
||||
split.itemR(field, "type",text="")
|
||||
|
||||
if field.type not in ('NONE', 'GUIDE', 'TEXTURE'):
|
||||
split = layout.split(percentage=0.2)
|
||||
#split = layout.row()
|
||||
split.itemL(text="Shape:")
|
||||
split.itemR(field, "shape", text="")
|
||||
|
||||
split = layout.split()
|
||||
|
||||
if field.type == 'NONE':
|
||||
return # nothing to draw
|
||||
elif field.type == 'GUIDE':
|
||||
col = split.column()
|
||||
col.itemR(field, "guide_minimum")
|
||||
col.itemR(field, "guide_free")
|
||||
col.itemR(field, "falloff_power")
|
||||
col.itemR(field, "guide_path_add")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Clumping:")
|
||||
col.itemR(field, "guide_clump_amount")
|
||||
col.itemR(field, "guide_clump_shape")
|
||||
|
||||
row = layout.row()
|
||||
row.itemR(field, "use_max_distance")
|
||||
sub = row.row()
|
||||
sub.active = field.use_max_distance
|
||||
sub.itemR(field, "maximum_distance")
|
||||
|
||||
layout.itemS()
|
||||
|
||||
layout.itemR(field, "guide_kink_type")
|
||||
if (field.guide_kink_type != "NONE"):
|
||||
layout.itemR(field, "guide_kink_axis")
|
||||
|
||||
flow = layout.column_flow()
|
||||
flow.itemR(field, "guide_kink_frequency")
|
||||
flow.itemR(field, "guide_kink_shape")
|
||||
flow.itemR(field, "guide_kink_amplitude")
|
||||
elif field.type == 'TEXTURE':
|
||||
col = split.column()
|
||||
col.itemR(field, "strength")
|
||||
col.itemR(field, "texture", text="")
|
||||
col.itemR(field, "texture_mode", text="")
|
||||
col.itemR(field, "texture_nabla")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(field, "use_coordinates")
|
||||
col.itemR(field, "root_coordinates")
|
||||
col.itemR(field, "force_2d")
|
||||
else :
|
||||
basic_force_field_settings_ui(self, field)
|
||||
|
||||
if field.type not in ('NONE', 'GUIDE'):
|
||||
|
||||
layout.itemL(text="Falloff:")
|
||||
layout.itemR(field, "falloff_type", expand=True)
|
||||
|
||||
basic_force_field_falloff_ui(self, field)
|
||||
|
||||
if field.falloff_type == 'CONE':
|
||||
layout.itemS()
|
||||
|
||||
split = layout.split(percentage=0.35)
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Angular:")
|
||||
col.itemR(field, "use_radial_min", text="Use Minimum")
|
||||
col.itemR(field, "use_radial_max", text="Use Maximum")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(field, "radial_falloff", text="Power")
|
||||
|
||||
sub = col.column()
|
||||
sub.active = field.use_radial_min
|
||||
sub.itemR(field, "radial_minimum", text="Angle")
|
||||
|
||||
sub = col.column()
|
||||
sub.active = field.use_radial_max
|
||||
sub.itemR(field, "radial_maximum", text="Angle")
|
||||
|
||||
elif field.falloff_type == 'TUBE':
|
||||
layout.itemS()
|
||||
|
||||
split = layout.split(percentage=0.35)
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Radial:")
|
||||
col.itemR(field, "use_radial_min", text="Use Minimum")
|
||||
col.itemR(field, "use_radial_max", text="Use Maximum")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(field, "radial_falloff", text="Power")
|
||||
|
||||
sub = col.column()
|
||||
sub.active = field.use_radial_min
|
||||
sub.itemR(field, "radial_minimum", text="Distance")
|
||||
|
||||
sub = col.column()
|
||||
sub.active = field.use_radial_max
|
||||
sub.itemR(field, "radial_maximum", text="Distance")
|
||||
|
||||
class PHYSICS_PT_collision(PhysicButtonsPanel):
|
||||
__label__ = "Collision"
|
||||
#__default_closed__ = True
|
||||
|
||||
def poll(self, context):
|
||||
ob = context.object
|
||||
rd = context.scene.render_data
|
||||
return (ob and ob.type == 'MESH') and (not rd.use_game_engine)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
md = context.collision
|
||||
|
||||
split = layout.split()
|
||||
split.operator_context = 'EXEC_DEFAULT'
|
||||
|
||||
if md:
|
||||
# remove modifier + settings
|
||||
split.set_context_pointer("modifier", md)
|
||||
split.itemO("object.modifier_remove", text="Remove")
|
||||
col = split.column()
|
||||
|
||||
#row = split.row(align=True)
|
||||
#row.itemR(md, "render", text="")
|
||||
#row.itemR(md, "realtime", text="")
|
||||
|
||||
coll = md.settings
|
||||
|
||||
else:
|
||||
# add modifier
|
||||
split.item_enumO("object.modifier_add", "type", 'COLLISION', text="Add")
|
||||
split.itemL()
|
||||
|
||||
coll = None
|
||||
|
||||
if coll:
|
||||
settings = context.object.collision
|
||||
|
||||
layout.active = settings.enabled
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Particle:")
|
||||
col.itemR(settings, "permeability", slider=True)
|
||||
col.itemL(text="Particle Damping:")
|
||||
sub = col.column(align=True)
|
||||
sub.itemR(settings, "damping_factor", text="Factor", slider=True)
|
||||
sub.itemR(settings, "random_damping", text="Random", slider=True)
|
||||
|
||||
col.itemL(text="Soft Body and Cloth:")
|
||||
sub = col.column(align=True)
|
||||
sub.itemR(settings, "outer_thickness", text="Outer", slider=True)
|
||||
sub.itemR(settings, "inner_thickness", text="Inner", slider=True)
|
||||
|
||||
layout.itemL(text="Force Fields:")
|
||||
layout.itemR(settings, "absorption", text="Absorption")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="")
|
||||
col.itemR(settings, "kill_particles")
|
||||
col.itemL(text="Particle Friction:")
|
||||
sub = col.column(align=True)
|
||||
sub.itemR(settings, "friction_factor", text="Factor", slider=True)
|
||||
sub.itemR(settings, "random_friction", text="Random", slider=True)
|
||||
col.itemL(text="Soft Body Damping:")
|
||||
col.itemR(settings, "damping", text="Factor", slider=True)
|
||||
|
||||
bpy.types.register(PHYSICS_PT_field)
|
||||
bpy.types.register(PHYSICS_PT_collision)
|
@ -1,257 +0,0 @@
|
||||
|
||||
import bpy
|
||||
|
||||
class PhysicButtonsPanel(bpy.types.Panel):
|
||||
__space_type__ = 'PROPERTIES'
|
||||
__region_type__ = 'WINDOW'
|
||||
__context__ = "physics"
|
||||
|
||||
def poll(self, context):
|
||||
ob = context.object
|
||||
rd = context.scene.render_data
|
||||
return (ob and ob.type == 'MESH') and (not rd.use_game_engine)
|
||||
|
||||
class PHYSICS_PT_fluid(PhysicButtonsPanel):
|
||||
__label__ = "Fluid"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
md = context.fluid
|
||||
ob = context.object
|
||||
|
||||
split = layout.split()
|
||||
split.operator_context = 'EXEC_DEFAULT'
|
||||
|
||||
if md:
|
||||
# remove modifier + settings
|
||||
split.set_context_pointer("modifier", md)
|
||||
split.itemO("object.modifier_remove", text="Remove")
|
||||
|
||||
row = split.row(align=True)
|
||||
row.itemR(md, "render", text="")
|
||||
row.itemR(md, "realtime", text="")
|
||||
|
||||
fluid = md.settings
|
||||
|
||||
else:
|
||||
# add modifier
|
||||
split.item_enumO("object.modifier_add", "type", 'FLUID_SIMULATION', text="Add")
|
||||
split.itemL()
|
||||
|
||||
fluid = None
|
||||
|
||||
|
||||
if fluid:
|
||||
layout.itemR(fluid, "type")
|
||||
|
||||
if fluid.type == 'DOMAIN':
|
||||
layout.itemO("fluid.bake", text="Bake Fluid Simulation", icon='ICON_MOD_FLUIDSIM')
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Resolution:")
|
||||
col.itemR(fluid, "resolution", text="Final")
|
||||
col.itemL(text="Render Display:")
|
||||
col.itemR(fluid, "render_display_mode", text="")
|
||||
col.itemL(text="Time:")
|
||||
sub = col.column(align=True)
|
||||
sub.itemR(fluid, "start_time", text="Start")
|
||||
sub.itemR(fluid, "end_time", text="End")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Required Memory: " + fluid.memory_estimate)
|
||||
col.itemR(fluid, "preview_resolution", text="Preview")
|
||||
col.itemL(text="Viewport Display:")
|
||||
col.itemR(fluid, "viewport_display_mode", text="")
|
||||
col.itemL()
|
||||
col.itemR(fluid, "generate_speed_vectors")
|
||||
col.itemR(fluid, "reverse_frames")
|
||||
|
||||
layout.itemR(fluid, "path", text="")
|
||||
|
||||
elif fluid.type == 'FLUID':
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Volume Initialization:")
|
||||
col.itemR(fluid, "volume_initialization", text="")
|
||||
col.itemR(fluid, "export_animated_mesh")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Initial Velocity:")
|
||||
col.itemR(fluid, "initial_velocity", text="")
|
||||
|
||||
elif fluid.type == 'OBSTACLE':
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Volume Initialization:")
|
||||
col.itemR(fluid, "volume_initialization", text="")
|
||||
col.itemR(fluid, "export_animated_mesh")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Slip Type:")
|
||||
col.itemR(fluid, "slip_type", text="")
|
||||
if fluid.slip_type == 'PARTIALSLIP':
|
||||
col.itemR(fluid, "partial_slip_factor", slider=True, text="Amount")
|
||||
|
||||
col.itemL(text="Impact:")
|
||||
col.itemR(fluid, "impact_factor", text="Factor")
|
||||
|
||||
elif fluid.type == 'INFLOW':
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Volume Initialization:")
|
||||
col.itemR(fluid, "volume_initialization", text="")
|
||||
col.itemR(fluid, "export_animated_mesh")
|
||||
col.itemR(fluid, "local_coordinates")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Inflow Velocity:")
|
||||
col.itemR(fluid, "inflow_velocity", text="")
|
||||
|
||||
elif fluid.type == 'OUTFLOW':
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Volume Initialization:")
|
||||
col.itemR(fluid, "volume_initialization", text="")
|
||||
col.itemR(fluid, "export_animated_mesh")
|
||||
|
||||
split.column()
|
||||
|
||||
elif fluid.type == 'PARTICLE':
|
||||
split = layout.split(percentage=0.5)
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Influence:")
|
||||
col.itemR(fluid, "particle_influence", text="Size")
|
||||
col.itemR(fluid, "alpha_influence", text="Alpha")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Type:")
|
||||
col.itemR(fluid, "drops")
|
||||
col.itemR(fluid, "floats")
|
||||
col = split.column()
|
||||
col.itemL()
|
||||
col.itemR(fluid, "tracer")
|
||||
|
||||
layout.itemR(fluid, "path", text="")
|
||||
|
||||
elif fluid.type == 'CONTROL':
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="")
|
||||
col.itemR(fluid, "quality", slider=True)
|
||||
col.itemR(fluid, "reverse_frames")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Time:")
|
||||
sub = col.column(align=True)
|
||||
sub.itemR(fluid, "start_time", text="Start")
|
||||
sub.itemR(fluid, "end_time", text="End")
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Attraction Force:")
|
||||
sub = col.column(align=True)
|
||||
sub.itemR(fluid, "attraction_strength", text="Strength")
|
||||
sub.itemR(fluid, "attraction_radius", text="Radius")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Velocity Force:")
|
||||
sub = col.column(align=True)
|
||||
sub.itemR(fluid, "velocity_strength", text="Strength")
|
||||
sub.itemR(fluid, "velocity_radius", text="Radius")
|
||||
|
||||
class PHYSICS_PT_domain_gravity(PhysicButtonsPanel):
|
||||
__label__ = "Domain World"
|
||||
__default_closed__ = True
|
||||
|
||||
def poll(self, context):
|
||||
md = context.fluid
|
||||
return md and (md.settings.type == 'DOMAIN')
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
fluid = context.fluid.settings
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Gravity:")
|
||||
col.itemR(fluid, "gravity", text="")
|
||||
col.itemL(text="Real World Size:")
|
||||
col.itemR(fluid, "real_world_size", text="Metres")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Viscosity Presets:")
|
||||
sub = col.column(align=True)
|
||||
sub.itemR(fluid, "viscosity_preset", text="")
|
||||
|
||||
if fluid.viscosity_preset == 'MANUAL':
|
||||
sub.itemR(fluid, "viscosity_base", text="Base")
|
||||
sub.itemR(fluid, "viscosity_exponent", text="Exponent", slider=True)
|
||||
else:
|
||||
sub.itemL()
|
||||
sub.itemL()
|
||||
|
||||
col.itemL(text="Optimization:")
|
||||
sub = col.column(align=True)
|
||||
sub.itemR(fluid, "grid_levels", slider=True)
|
||||
sub.itemR(fluid, "compressibility", slider=True)
|
||||
|
||||
class PHYSICS_PT_domain_boundary(PhysicButtonsPanel):
|
||||
__label__ = "Domain Boundary"
|
||||
__default_closed__ = True
|
||||
|
||||
def poll(self, context):
|
||||
md = context.fluid
|
||||
return md and (md.settings.type == 'DOMAIN')
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
fluid = context.fluid.settings
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Slip Type:")
|
||||
sub = col.column(align=True)
|
||||
sub.itemR(fluid, "slip_type", text="")
|
||||
if fluid.slip_type == 'PARTIALSLIP':
|
||||
sub.itemR(fluid, "partial_slip_factor", slider=True, text="Amount")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Surface:")
|
||||
sub = col.column(align=True)
|
||||
sub.itemR(fluid, "surface_smoothing", text="Smoothing")
|
||||
sub.itemR(fluid, "surface_subdivisions", text="Subdivisions")
|
||||
|
||||
class PHYSICS_PT_domain_particles(PhysicButtonsPanel):
|
||||
__label__ = "Domain Particles"
|
||||
__default_closed__ = True
|
||||
|
||||
def poll(self, context):
|
||||
md = context.fluid
|
||||
return md and (md.settings.type == 'DOMAIN')
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
fluid = context.fluid.settings
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.itemR(fluid, "tracer_particles")
|
||||
col.itemR(fluid, "generate_particles")
|
||||
|
||||
bpy.types.register(PHYSICS_PT_fluid)
|
||||
bpy.types.register(PHYSICS_PT_domain_gravity)
|
||||
bpy.types.register(PHYSICS_PT_domain_boundary)
|
||||
bpy.types.register(PHYSICS_PT_domain_particles)
|
@ -1,193 +0,0 @@
|
||||
|
||||
import bpy
|
||||
|
||||
from buttons_physics_common import point_cache_ui
|
||||
from buttons_physics_common import effector_weights_ui
|
||||
|
||||
class PhysicButtonsPanel(bpy.types.Panel):
|
||||
__space_type__ = 'PROPERTIES'
|
||||
__region_type__ = 'WINDOW'
|
||||
__context__ = "physics"
|
||||
|
||||
def poll(self, context):
|
||||
ob = context.object
|
||||
rd = context.scene.render_data
|
||||
return (ob and ob.type == 'MESH') and (not rd.use_game_engine)
|
||||
|
||||
class PHYSICS_PT_smoke(PhysicButtonsPanel):
|
||||
__label__ = "Smoke"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
md = context.smoke
|
||||
ob = context.object
|
||||
|
||||
split = layout.split()
|
||||
split.operator_context = 'EXEC_DEFAULT'
|
||||
|
||||
if md:
|
||||
# remove modifier + settings
|
||||
split.set_context_pointer("modifier", md)
|
||||
split.itemO("object.modifier_remove", text="Remove")
|
||||
|
||||
row = split.row(align=True)
|
||||
row.itemR(md, "render", text="")
|
||||
row.itemR(md, "realtime", text="")
|
||||
|
||||
else:
|
||||
# add modifier
|
||||
split.item_enumO("object.modifier_add", "type", 'SMOKE', text="Add")
|
||||
split.itemL()
|
||||
|
||||
if md:
|
||||
layout.itemR(md, "smoke_type", expand=True)
|
||||
|
||||
if md.smoke_type == 'TYPE_DOMAIN':
|
||||
|
||||
domain = md.domain_settings
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Resolution:")
|
||||
col.itemR(domain, "maxres", text="Divisions")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Behavior:")
|
||||
col.itemR(domain, "alpha")
|
||||
col.itemR(domain, "beta")
|
||||
col.itemR(domain, "dissolve_smoke", text="Dissolve")
|
||||
sub = col.column()
|
||||
sub.active = domain.dissolve_smoke
|
||||
sub.itemR(domain, "dissolve_speed", text="Time")
|
||||
sub.itemR(domain, "dissolve_smoke_log", text="Slow")
|
||||
|
||||
elif md.smoke_type == 'TYPE_FLOW':
|
||||
|
||||
flow = md.flow_settings
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemR(flow, "outflow")
|
||||
col.itemL(text="Particle System:")
|
||||
col.item_pointerR(flow, "psys", ob, "particle_systems", text="")
|
||||
|
||||
if md.flow_settings.outflow:
|
||||
col = split.column()
|
||||
else:
|
||||
col = split.column()
|
||||
col.itemL(text="Behavior:")
|
||||
col.itemR(flow, "temperature")
|
||||
col.itemR(flow, "density")
|
||||
|
||||
#elif md.smoke_type == 'TYPE_COLL':
|
||||
# layout.itemS()
|
||||
|
||||
class PHYSICS_PT_smoke_groups(PhysicButtonsPanel):
|
||||
__label__ = "Smoke Groups"
|
||||
__default_closed__ = True
|
||||
|
||||
def poll(self, context):
|
||||
md = context.smoke
|
||||
return md and (md.smoke_type == 'TYPE_DOMAIN')
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
group = context.smoke.domain_settings
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Flow Group:")
|
||||
col.itemR(group, "fluid_group", text="")
|
||||
|
||||
#col.itemL(text="Effector Group:")
|
||||
#col.itemR(group, "eff_group", text="")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Collision Group:")
|
||||
col.itemR(group, "coll_group", text="")
|
||||
|
||||
class PHYSICS_PT_smoke_cache(PhysicButtonsPanel):
|
||||
__label__ = "Smoke Cache"
|
||||
__default_closed__ = True
|
||||
|
||||
def poll(self, context):
|
||||
md = context.smoke
|
||||
return md and (md.smoke_type == 'TYPE_DOMAIN')
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
md = context.smoke.domain_settings
|
||||
cache = md.point_cache_low
|
||||
|
||||
point_cache_ui(self, cache, cache.baked==False, 0, 1)
|
||||
|
||||
class PHYSICS_PT_smoke_highres(PhysicButtonsPanel):
|
||||
__label__ = "Smoke High Resolution"
|
||||
__default_closed__ = True
|
||||
|
||||
def poll(self, context):
|
||||
md = context.smoke
|
||||
return md and (md.smoke_type == 'TYPE_DOMAIN')
|
||||
|
||||
def draw_header(self, context):
|
||||
high = context.smoke.domain_settings
|
||||
|
||||
self.layout.itemR(high, "highres", text="")
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
md = context.smoke.domain_settings
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Resolution:")
|
||||
col.itemR(md, "amplify", text="Divisions")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Noise Method:")
|
||||
col.row().itemR(md, "noise_type", text="")
|
||||
col.itemR(md, "strength")
|
||||
col.itemR(md, "viewhighres")
|
||||
|
||||
class PHYSICS_PT_smoke_cache_highres(PhysicButtonsPanel):
|
||||
__label__ = "Smoke High Resolution Cache"
|
||||
__default_closed__ = True
|
||||
|
||||
def poll(self, context):
|
||||
md = context.smoke
|
||||
return md and (md.smoke_type == 'TYPE_DOMAIN') and md.domain_settings.highres
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
md = context.smoke.domain_settings
|
||||
cache = md.point_cache_high
|
||||
|
||||
point_cache_ui(self, cache, cache.baked==False, 0, 1)
|
||||
|
||||
class PHYSICS_PT_smoke_field_weights(PhysicButtonsPanel):
|
||||
__label__ = "Smoke Field Weights"
|
||||
__default_closed__ = True
|
||||
|
||||
def poll(self, context):
|
||||
smoke = context.smoke
|
||||
return (smoke and smoke.smoke_type == 'TYPE_DOMAIN')
|
||||
|
||||
def draw(self, context):
|
||||
domain = context.smoke.domain_settings
|
||||
effector_weights_ui(self, domain.effector_weights)
|
||||
|
||||
bpy.types.register(PHYSICS_PT_smoke)
|
||||
bpy.types.register(PHYSICS_PT_smoke_field_weights)
|
||||
bpy.types.register(PHYSICS_PT_smoke_cache)
|
||||
bpy.types.register(PHYSICS_PT_smoke_highres)
|
||||
bpy.types.register(PHYSICS_PT_smoke_groups)
|
||||
bpy.types.register(PHYSICS_PT_smoke_cache_highres)
|
@ -1,244 +0,0 @@
|
||||
|
||||
import bpy
|
||||
|
||||
from buttons_physics_common import point_cache_ui
|
||||
from buttons_physics_common import effector_weights_ui
|
||||
|
||||
def softbody_panel_enabled(md):
|
||||
return md.point_cache.baked==False
|
||||
|
||||
class PhysicButtonsPanel(bpy.types.Panel):
|
||||
__space_type__ = 'PROPERTIES'
|
||||
__region_type__ = 'WINDOW'
|
||||
__context__ = "physics"
|
||||
|
||||
def poll(self, context):
|
||||
ob = context.object
|
||||
rd = context.scene.render_data
|
||||
return (ob and ob.type == 'MESH') and (not rd.use_game_engine)
|
||||
|
||||
class PHYSICS_PT_softbody(PhysicButtonsPanel):
|
||||
__label__ = "Soft Body"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
md = context.soft_body
|
||||
ob = context.object
|
||||
|
||||
split = layout.split()
|
||||
split.operator_context = "EXEC_DEFAULT"
|
||||
|
||||
if md:
|
||||
# remove modifier + settings
|
||||
split.set_context_pointer("modifier", md)
|
||||
split.itemO("object.modifier_remove", text="Remove")
|
||||
|
||||
row = split.row(align=True)
|
||||
row.itemR(md, "render", text="")
|
||||
row.itemR(md, "realtime", text="")
|
||||
else:
|
||||
# add modifier
|
||||
split.item_enumO("object.modifier_add", "type", 'SOFT_BODY', text="Add")
|
||||
split.itemL("")
|
||||
|
||||
if md:
|
||||
softbody = md.settings
|
||||
|
||||
# General
|
||||
split = layout.split()
|
||||
split.enabled = softbody_panel_enabled(md)
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Object:")
|
||||
col.itemR(softbody, "mass")
|
||||
col.itemR(softbody, "friction")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Simulation:")
|
||||
col.itemR(softbody, "speed")
|
||||
|
||||
class PHYSICS_PT_softbody_cache(PhysicButtonsPanel):
|
||||
__label__ = "Soft Body Cache"
|
||||
__default_closed__ = True
|
||||
|
||||
def poll(self, context):
|
||||
return context.soft_body
|
||||
|
||||
def draw(self, context):
|
||||
md = context.soft_body
|
||||
point_cache_ui(self, md.point_cache, softbody_panel_enabled(md), 0, 0)
|
||||
|
||||
class PHYSICS_PT_softbody_goal(PhysicButtonsPanel):
|
||||
__label__ = "Soft Body Goal"
|
||||
__default_closed__ = True
|
||||
|
||||
def poll(self, context):
|
||||
return context.soft_body
|
||||
|
||||
def draw_header(self, context):
|
||||
softbody = context.soft_body.settings
|
||||
|
||||
self.layout.active = softbody_panel_enabled(context.soft_body)
|
||||
self.layout.itemR(softbody, "use_goal", text="")
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
md = context.soft_body
|
||||
softbody = md.settings
|
||||
ob = context.object
|
||||
|
||||
layout.active = softbody.use_goal and softbody_panel_enabled(md)
|
||||
|
||||
split = layout.split()
|
||||
|
||||
# Goal
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Goal Strengths:")
|
||||
col.itemR(softbody, "goal_default", text="Default")
|
||||
sub = col.column(align=True)
|
||||
sub.itemR(softbody, "goal_min", text="Minimum")
|
||||
sub.itemR(softbody, "goal_max", text="Maximum")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Goal Settings:")
|
||||
col.itemR(softbody, "goal_spring", text="Stiffness")
|
||||
col.itemR(softbody, "goal_friction", text="Damping")
|
||||
|
||||
layout.item_pointerR(softbody, "goal_vertex_group", ob, "vertex_groups", text="Vertex Group")
|
||||
|
||||
class PHYSICS_PT_softbody_edge(PhysicButtonsPanel):
|
||||
__label__ = "Soft Body Edges"
|
||||
__default_closed__ = True
|
||||
|
||||
def poll(self, context):
|
||||
return context.soft_body
|
||||
|
||||
def draw_header(self, context):
|
||||
softbody = context.soft_body.settings
|
||||
|
||||
self.layout.active = softbody_panel_enabled(context.soft_body)
|
||||
self.layout.itemR(softbody, "use_edges", text="")
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
md = context.soft_body
|
||||
softbody = md.settings
|
||||
ob = context.object
|
||||
|
||||
layout.active = softbody.use_edges and softbody_panel_enabled(md)
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Springs:")
|
||||
col.itemR(softbody, "pull")
|
||||
col.itemR(softbody, "push")
|
||||
col.itemR(softbody, "damp")
|
||||
col.itemR(softbody, "plastic")
|
||||
col.itemR(softbody, "bending")
|
||||
col.itemR(softbody, "spring_length", text="Length")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(softbody, "stiff_quads")
|
||||
sub = col.column()
|
||||
sub.active = softbody.stiff_quads
|
||||
sub.itemR(softbody, "shear")
|
||||
|
||||
col.itemR(softbody, "new_aero", text="Aero")
|
||||
sub = col.column()
|
||||
sub.enabled = softbody.new_aero
|
||||
sub.itemR(softbody, "aero", text="Factor")
|
||||
|
||||
col.itemL(text="Collision:")
|
||||
col.itemR(softbody, "edge_collision", text="Edge")
|
||||
col.itemR(softbody, "face_collision", text="Face")
|
||||
|
||||
class PHYSICS_PT_softbody_collision(PhysicButtonsPanel):
|
||||
__label__ = "Soft Body Collision"
|
||||
__default_closed__ = True
|
||||
|
||||
def poll(self, context):
|
||||
return context.soft_body
|
||||
|
||||
def draw_header(self, context):
|
||||
softbody = context.soft_body.settings
|
||||
|
||||
self.layout.active = softbody_panel_enabled(context.soft_body)
|
||||
self.layout.itemR(softbody, "self_collision", text="")
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
md = context.soft_body
|
||||
softbody = md.settings
|
||||
ob = context.object
|
||||
|
||||
layout.active = softbody.self_collision and softbody_panel_enabled(md)
|
||||
|
||||
layout.itemL(text="Collision Type:")
|
||||
layout.itemR(softbody, "collision_type", expand=True)
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.itemL(text="Ball:")
|
||||
col.itemR(softbody, "ball_size", text="Size")
|
||||
col.itemR(softbody, "ball_stiff", text="Stiffness")
|
||||
col.itemR(softbody, "ball_damp", text="Dampening")
|
||||
|
||||
class PHYSICS_PT_softbody_solver(PhysicButtonsPanel):
|
||||
__label__ = "Soft Body Solver"
|
||||
__default_closed__ = True
|
||||
|
||||
def poll(self, context):
|
||||
return context.soft_body
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
md = context.soft_body
|
||||
softbody = md.settings
|
||||
ob = context.object
|
||||
|
||||
layout.active = softbody_panel_enabled(md)
|
||||
|
||||
# Solver
|
||||
split = layout.split()
|
||||
|
||||
col = split.column(align=True)
|
||||
col.itemL(text="Step Size:")
|
||||
col.itemR(softbody, "minstep")
|
||||
col.itemR(softbody, "maxstep")
|
||||
col.itemR(softbody, "auto_step", text="Auto-Step")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(softbody, "error_limit")
|
||||
col.itemL(text="Helpers:")
|
||||
col.itemR(softbody, "choke")
|
||||
col.itemR(softbody, "fuzzy")
|
||||
|
||||
layout.itemL(text="Diagnostics:")
|
||||
layout.itemR(softbody, "diagnose")
|
||||
|
||||
class PHYSICS_PT_softbody_field_weights(PhysicButtonsPanel):
|
||||
__label__ = "Soft Body Field Weights"
|
||||
__default_closed__ = True
|
||||
|
||||
def poll(self, context):
|
||||
return (context.soft_body)
|
||||
|
||||
def draw(self, context):
|
||||
md = context.soft_body
|
||||
softbody = md.settings
|
||||
effector_weights_ui(self, softbody.effector_weights)
|
||||
|
||||
bpy.types.register(PHYSICS_PT_softbody)
|
||||
bpy.types.register(PHYSICS_PT_softbody_cache)
|
||||
bpy.types.register(PHYSICS_PT_softbody_goal)
|
||||
bpy.types.register(PHYSICS_PT_softbody_edge)
|
||||
bpy.types.register(PHYSICS_PT_softbody_collision)
|
||||
bpy.types.register(PHYSICS_PT_softbody_solver)
|
||||
bpy.types.register(PHYSICS_PT_softbody_field_weights)
|
@ -1,137 +0,0 @@
|
||||
|
||||
import bpy
|
||||
|
||||
class SceneButtonsPanel(bpy.types.Panel):
|
||||
__space_type__ = 'PROPERTIES'
|
||||
__region_type__ = 'WINDOW'
|
||||
__context__ = "scene"
|
||||
|
||||
def poll(self, context):
|
||||
return context.scene
|
||||
|
||||
class SCENE_PT_scene(SceneButtonsPanel):
|
||||
__label__ = "Scene"
|
||||
COMPAT_ENGINES = set(['BLENDER_RENDER'])
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
scene = context.scene
|
||||
|
||||
layout.itemR(scene, "camera")
|
||||
layout.itemR(scene, "set", text="Background")
|
||||
|
||||
class SCENE_PT_unit(SceneButtonsPanel):
|
||||
__label__ = "Units"
|
||||
COMPAT_ENGINES = set(['BLENDER_RENDER'])
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
unit = context.scene.unit_settings
|
||||
|
||||
col = layout.column()
|
||||
col.row().itemR(unit, "system", expand=True)
|
||||
|
||||
row = layout.row()
|
||||
row.active = (unit.system != 'NONE')
|
||||
row.itemR(unit, "scale_length", text="Scale")
|
||||
row.itemR(unit, "use_separate")
|
||||
|
||||
class SCENE_PT_keying_sets(SceneButtonsPanel):
|
||||
__label__ = "Keying Sets"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
scene = context.scene
|
||||
|
||||
row = layout.row()
|
||||
|
||||
col = row.column()
|
||||
col.template_list(scene, "keying_sets", scene, "active_keying_set_index", rows=2)
|
||||
|
||||
col = row.column(align=True)
|
||||
col.itemO("anim.keying_set_add", icon='ICON_ZOOMIN', text="")
|
||||
col.itemO("anim.keying_set_remove", icon='ICON_ZOOMOUT', text="")
|
||||
|
||||
ks = scene.active_keying_set
|
||||
if ks:
|
||||
row = layout.row()
|
||||
|
||||
col = row.column()
|
||||
col.itemR(ks, "name")
|
||||
col.itemR(ks, "absolute")
|
||||
|
||||
col = row.column()
|
||||
col.itemL(text="Keyframing Settings:")
|
||||
col.itemR(ks, "insertkey_needed", text="Needed")
|
||||
col.itemR(ks, "insertkey_visual", text="Visual")
|
||||
|
||||
class SCENE_PT_keying_set_paths(SceneButtonsPanel):
|
||||
__label__ = "Active Keying Set"
|
||||
|
||||
def poll(self, context):
|
||||
return (context.scene != None) and (context.scene.active_keying_set != None)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
scene = context.scene
|
||||
ks = scene.active_keying_set
|
||||
|
||||
row = layout.row()
|
||||
row.itemL(text="Paths:")
|
||||
|
||||
row = layout.row()
|
||||
|
||||
col = row.column()
|
||||
col.template_list(ks, "paths", ks, "active_path_index", rows=2)
|
||||
|
||||
col = row.column(align=True)
|
||||
col.itemO("anim.keying_set_path_add", icon='ICON_ZOOMIN', text="")
|
||||
col.itemO("anim.keying_set_path_remove", icon='ICON_ZOOMOUT', text="")
|
||||
|
||||
ksp = ks.active_path
|
||||
if ksp:
|
||||
col = layout.column()
|
||||
col.itemL(text="Target:")
|
||||
col.template_any_ID(ksp, "id", "id_type")
|
||||
col.template_path_builder(ksp, "rna_path", ksp.id)
|
||||
|
||||
|
||||
row = layout.row()
|
||||
|
||||
col = row.column()
|
||||
col.itemL(text="Array Target:")
|
||||
col.itemR(ksp, "entire_array")
|
||||
if ksp.entire_array == False:
|
||||
col.itemR(ksp, "array_index")
|
||||
|
||||
col = row.column()
|
||||
col.itemL(text="F-Curve Grouping:")
|
||||
col.itemR(ksp, "grouping")
|
||||
if ksp.grouping == 'NAMED':
|
||||
col.itemR(ksp, "group")
|
||||
|
||||
class SCENE_PT_physics(SceneButtonsPanel):
|
||||
__label__ = "Gravity"
|
||||
COMPAT_ENGINES = set(['BLENDER_RENDER'])
|
||||
|
||||
def draw_header(self, context):
|
||||
self.layout.itemR(context.scene, "use_gravity", text="")
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
scene = context.scene
|
||||
|
||||
layout.active = scene.use_gravity
|
||||
|
||||
layout.itemR(scene, "gravity", text="")
|
||||
|
||||
bpy.types.register(SCENE_PT_scene)
|
||||
bpy.types.register(SCENE_PT_unit)
|
||||
bpy.types.register(SCENE_PT_keying_sets)
|
||||
bpy.types.register(SCENE_PT_keying_set_paths)
|
||||
bpy.types.register(SCENE_PT_physics)
|
@ -1,793 +0,0 @@
|
||||
|
||||
import bpy
|
||||
|
||||
def active_node_mat(mat):
|
||||
if mat:
|
||||
mat_node = mat.active_node_material
|
||||
if mat_node:
|
||||
return mat_node
|
||||
else:
|
||||
return mat
|
||||
|
||||
return None
|
||||
|
||||
def context_tex_datablock(context):
|
||||
|
||||
idblock = active_node_mat(context.material)
|
||||
if idblock: return idblock
|
||||
|
||||
idblock = context.lamp
|
||||
if idblock: return idblock
|
||||
|
||||
idblock = context.world
|
||||
if idblock: return idblock
|
||||
|
||||
idblock = context.brush
|
||||
return idblock
|
||||
|
||||
class TextureButtonsPanel(bpy.types.Panel):
|
||||
__space_type__ = 'PROPERTIES'
|
||||
__region_type__ = 'WINDOW'
|
||||
__context__ = "texture"
|
||||
|
||||
def poll(self, context):
|
||||
tex = context.texture
|
||||
return (tex and (tex.type != 'NONE' or tex.use_nodes))
|
||||
|
||||
class TEXTURE_PT_preview(TextureButtonsPanel):
|
||||
__label__ = "Preview"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
tex = context.texture
|
||||
slot = context.texture_slot
|
||||
|
||||
idblock = context_tex_datablock(context)
|
||||
|
||||
if idblock:
|
||||
layout.template_preview(tex, parent=idblock, slot=slot)
|
||||
else:
|
||||
layout.template_preview(tex, slot=slot)
|
||||
|
||||
class TEXTURE_PT_context_texture(TextureButtonsPanel):
|
||||
__show_header__ = False
|
||||
|
||||
def poll(self, context):
|
||||
return (context.material or context.world or context.lamp or context.brush or context.texture)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
tex = context.texture
|
||||
|
||||
idblock = context_tex_datablock(context)
|
||||
|
||||
space = context.space_data
|
||||
|
||||
if idblock:
|
||||
row = layout.row()
|
||||
|
||||
row.template_list(idblock, "textures", idblock, "active_texture_index", rows=2)
|
||||
|
||||
col = row.column(align=True)
|
||||
col.item_enumO("texture.slot_move", "type", 'UP', text="", icon='ICON_TRIA_UP')
|
||||
col.item_enumO("texture.slot_move", "type", 'DOWN', text="", icon='ICON_TRIA_DOWN')
|
||||
|
||||
|
||||
split = layout.split(percentage=0.65)
|
||||
|
||||
if idblock:
|
||||
split.template_ID(idblock, "active_texture", new="texture.new")
|
||||
elif tex:
|
||||
split.template_ID(space, "pin_id")
|
||||
|
||||
if (not space.pin_id) and (
|
||||
context.sculpt_object or
|
||||
context.vertex_paint_object or
|
||||
context.weight_paint_object or
|
||||
context.texture_paint_object
|
||||
):
|
||||
split.itemR(space, "brush_texture", text="Brush", toggle=True)
|
||||
|
||||
if tex:
|
||||
layout.itemR(tex, "use_nodes")
|
||||
|
||||
split = layout.split(percentage=0.2)
|
||||
|
||||
if tex.use_nodes:
|
||||
slot = context.texture_slot
|
||||
|
||||
if slot:
|
||||
split.itemL(text="Output:")
|
||||
split.itemR(slot, "output_node", text="")
|
||||
|
||||
else:
|
||||
split.itemL(text="Type:")
|
||||
split.itemR(tex, "type", text="")
|
||||
|
||||
class TEXTURE_PT_colors(TextureButtonsPanel):
|
||||
__label__ = "Colors"
|
||||
__default_closed__ = True
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
tex = context.texture
|
||||
|
||||
layout.itemR(tex, "use_color_ramp", text="Ramp")
|
||||
if tex.use_color_ramp:
|
||||
layout.template_color_ramp(tex, "color_ramp", expand=True)
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="RGB Multiply:")
|
||||
sub = col.column(align=True)
|
||||
sub.itemR(tex, "factor_red", text="R")
|
||||
sub.itemR(tex, "factor_green", text="G")
|
||||
sub.itemR(tex, "factor_blue", text="B")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Adjust:")
|
||||
col.itemR(tex, "brightness")
|
||||
col.itemR(tex, "contrast")
|
||||
|
||||
# Texture Slot Panels #
|
||||
|
||||
class TextureSlotPanel(TextureButtonsPanel):
|
||||
def poll(self, context):
|
||||
return (
|
||||
context.texture_slot and
|
||||
TextureButtonsPanel.poll(self, context)
|
||||
)
|
||||
|
||||
class TEXTURE_PT_mapping(TextureSlotPanel):
|
||||
__label__ = "Mapping"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
idblock = context_tex_datablock(context)
|
||||
|
||||
tex = context.texture_slot
|
||||
textype = context.texture
|
||||
|
||||
if type(idblock) != bpy.types.Brush:
|
||||
split = layout.split(percentage=0.3)
|
||||
col = split.column()
|
||||
col.itemL(text="Coordinates:")
|
||||
col = split.column()
|
||||
col.itemR(tex, "texture_coordinates", text="")
|
||||
|
||||
if tex.texture_coordinates == 'ORCO':
|
||||
"""
|
||||
ob = context.object
|
||||
if ob and ob.type == 'MESH':
|
||||
split = layout.split(percentage=0.3)
|
||||
split.itemL(text="Mesh:")
|
||||
split.itemR(ob.data, "texco_mesh", text="")
|
||||
"""
|
||||
elif tex.texture_coordinates == 'UV':
|
||||
split = layout.split(percentage=0.3)
|
||||
split.itemL(text="Layer:")
|
||||
ob = context.object
|
||||
if ob and ob.type == 'MESH': split.item_pointerR(tex, "uv_layer", ob.data, "uv_textures", text="")
|
||||
else: split.itemR(tex, "uv_layer", text="")
|
||||
elif tex.texture_coordinates == 'OBJECT':
|
||||
split = layout.split(percentage=0.3)
|
||||
split.itemL(text="Object:")
|
||||
split.itemR(tex, "object", text="")
|
||||
|
||||
if type(idblock) == bpy.types.Brush:
|
||||
layout.itemR(tex, "map_mode", expand=True)
|
||||
|
||||
row = layout.row()
|
||||
row.active = tex.map_mode in ('FIXED', 'TILED')
|
||||
row.itemR(tex, "angle")
|
||||
|
||||
row = layout.row()
|
||||
row.active = tex.map_mode in ('TILED', '3D')
|
||||
row.column().itemR(tex, "size")
|
||||
else:
|
||||
if type(idblock) == bpy.types.Material:
|
||||
split = layout.split(percentage=0.3)
|
||||
split.itemL(text="Projection:")
|
||||
split.itemR(tex, "mapping", text="")
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
if tex.texture_coordinates in ('ORCO', 'UV'):
|
||||
col.itemR(tex, "from_dupli")
|
||||
elif tex.texture_coordinates == 'OBJECT':
|
||||
col.itemR(tex, "from_original")
|
||||
else:
|
||||
col.itemL()
|
||||
|
||||
col = split.column()
|
||||
row = col.row()
|
||||
row.itemR(tex, "x_mapping", text="")
|
||||
row.itemR(tex, "y_mapping", text="")
|
||||
row.itemR(tex, "z_mapping", text="")
|
||||
|
||||
# any non brush
|
||||
row = layout.row()
|
||||
row.column().itemR(tex, "offset")
|
||||
row.column().itemR(tex, "size")
|
||||
|
||||
|
||||
class TEXTURE_PT_influence(TextureSlotPanel):
|
||||
__label__ = "Influence"
|
||||
def poll(self, context):
|
||||
return context.texture_slot
|
||||
|
||||
|
||||
def draw(self, context):
|
||||
|
||||
layout = self.layout
|
||||
|
||||
idblock = context_tex_datablock(context)
|
||||
|
||||
textype = context.texture
|
||||
tex = context.texture_slot
|
||||
|
||||
def factor_but(layout, active, toggle, factor, name):
|
||||
row = layout.row(align=True)
|
||||
row.itemR(tex, toggle, text="")
|
||||
sub = row.row()
|
||||
sub.active = active
|
||||
sub.itemR(tex, factor, text=name, slider=True)
|
||||
|
||||
if type(idblock) == bpy.types.Material:
|
||||
if idblock.type in ('SURFACE', 'HALO', 'WIRE'):
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Diffuse:")
|
||||
factor_but(col, tex.map_diffuse, "map_diffuse", "diffuse_factor", "Intensity")
|
||||
factor_but(col, tex.map_colordiff, "map_colordiff", "colordiff_factor", "Color")
|
||||
factor_but(col, tex.map_alpha, "map_alpha", "alpha_factor", "Alpha")
|
||||
factor_but(col, tex.map_translucency, "map_translucency", "translucency_factor", "Translucency")
|
||||
|
||||
col.itemL(text="Specular:")
|
||||
factor_but(col, tex.map_specular, "map_specular", "specular_factor", "Intensity")
|
||||
factor_but(col, tex.map_colorspec, "map_colorspec", "colorspec_factor", "Color")
|
||||
factor_but(col, tex.map_hardness, "map_hardness", "hardness_factor", "Hardness")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Shading:")
|
||||
factor_but(col, tex.map_ambient, "map_ambient", "ambient_factor", "Ambient")
|
||||
factor_but(col, tex.map_emit, "map_emit", "emit_factor", "Emit")
|
||||
factor_but(col, tex.map_mirror, "map_mirror", "mirror_factor", "Mirror")
|
||||
factor_but(col, tex.map_raymir, "map_raymir", "raymir_factor", "Ray Mirror")
|
||||
|
||||
col.itemL(text="Geometry:")
|
||||
factor_but(col, tex.map_normal, "map_normal", "normal_factor", "Normal")
|
||||
factor_but(col, tex.map_warp, "map_warp", "warp_factor", "Warp")
|
||||
factor_but(col, tex.map_displacement, "map_displacement", "displacement_factor", "Displace")
|
||||
|
||||
#sub = col.column()
|
||||
#sub.active = tex.map_translucency or tex.map_emit or tex.map_alpha or tex.map_raymir or tex.map_hardness or tex.map_ambient or tex.map_specularity or tex.map_reflection or tex.map_mirror
|
||||
#sub.itemR(tex, "default_value", text="Amount", slider=True)
|
||||
elif idblock.type == 'VOLUME':
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
factor_but(col, tex.map_density, "map_density", "density_factor", "Density")
|
||||
factor_but(col, tex.map_emission, "map_emission", "emission_factor", "Emission")
|
||||
factor_but(col, tex.map_scattering, "map_scattering", "scattering_factor", "Scattering")
|
||||
factor_but(col, tex.map_reflection, "map_reflection", "reflection_factor", "Reflection")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text=" ")
|
||||
factor_but(col, tex.map_alpha, "map_coloremission", "coloremission_factor", "Emission Color")
|
||||
factor_but(col, tex.map_colortransmission, "map_colortransmission", "colortransmission_factor", "Transmission Color")
|
||||
factor_but(col, tex.map_colorreflection, "map_colorreflection", "colorreflection_factor", "Reflection Color")
|
||||
|
||||
elif type(idblock) == bpy.types.Lamp:
|
||||
row = layout.row()
|
||||
factor_but(row, tex.map_color, "map_color", "color_factor", "Color")
|
||||
factor_but(row, tex.map_shadow, "map_shadow", "shadow_factor", "Shadow")
|
||||
|
||||
elif type(idblock) == bpy.types.World:
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
factor_but(col, tex.map_blend, "map_blend", "blend_factor", "Blend")
|
||||
factor_but(col, tex.map_horizon, "map_horizon", "horizon_factor", "Horizon")
|
||||
|
||||
col = split.column()
|
||||
factor_but(col, tex.map_zenith_up, "map_zenith_up", "zenith_up_factor", "Zenith Up")
|
||||
factor_but(col, tex.map_zenith_down, "map_zenith_down", "zenith_down_factor", "Zenith Down")
|
||||
|
||||
layout.itemS()
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemR(tex, "blend_type", text="Blend")
|
||||
col.itemR(tex, "rgb_to_intensity")
|
||||
sub = col.column()
|
||||
sub.active = tex.rgb_to_intensity
|
||||
sub.itemR(tex, "color", text="")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(tex, "negate", text="Negative")
|
||||
col.itemR(tex, "stencil")
|
||||
|
||||
if type(idblock) in (bpy.types.Material, bpy.types.World):
|
||||
col.itemR(tex, "default_value", text="DVar", slider=True)
|
||||
|
||||
# Texture Type Panels #
|
||||
|
||||
class TextureTypePanel(TextureButtonsPanel):
|
||||
def poll(self, context):
|
||||
tex = context.texture
|
||||
return (tex and tex.type == self.tex_type and not tex.use_nodes)
|
||||
|
||||
class TEXTURE_PT_clouds(TextureTypePanel):
|
||||
__label__ = "Clouds"
|
||||
tex_type = 'CLOUDS'
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
tex = context.texture
|
||||
|
||||
layout.itemR(tex, "stype", expand=True)
|
||||
layout.itemL(text="Noise:")
|
||||
layout.itemR(tex, "noise_type", text="Type", expand=True)
|
||||
layout.itemR(tex, "noise_basis", text="Basis")
|
||||
|
||||
flow = layout.column_flow()
|
||||
flow.itemR(tex, "noise_size", text="Size")
|
||||
flow.itemR(tex, "noise_depth", text="Depth")
|
||||
flow.itemR(tex, "nabla", text="Nabla")
|
||||
|
||||
class TEXTURE_PT_wood(TextureTypePanel):
|
||||
__label__ = "Wood"
|
||||
tex_type = 'WOOD'
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
tex = context.texture
|
||||
|
||||
layout.itemR(tex, "noisebasis2", expand=True)
|
||||
layout.itemR(tex, "stype", expand=True)
|
||||
|
||||
col = layout.column()
|
||||
col.active = tex.stype in ('RINGNOISE', 'BANDNOISE')
|
||||
col.itemL(text="Noise:")
|
||||
col.row().itemR(tex, "noise_type", text="Type", expand=True)
|
||||
col.itemR(tex, "noise_basis", text="Basis")
|
||||
|
||||
flow = layout.column_flow()
|
||||
flow.active = tex.stype in ('RINGNOISE', 'BANDNOISE')
|
||||
flow.itemR(tex, "noise_size", text="Size")
|
||||
flow.itemR(tex, "turbulence")
|
||||
flow.itemR(tex, "nabla")
|
||||
|
||||
class TEXTURE_PT_marble(TextureTypePanel):
|
||||
__label__ = "Marble"
|
||||
tex_type = 'MARBLE'
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
tex = context.texture
|
||||
|
||||
layout.itemR(tex, "stype", expand=True)
|
||||
layout.itemR(tex, "noisebasis2", expand=True)
|
||||
layout.itemL(text="Noise:")
|
||||
layout.itemR(tex, "noise_type", text="Type", expand=True)
|
||||
layout.itemR(tex, "noise_basis", text="Basis")
|
||||
|
||||
flow = layout.column_flow()
|
||||
flow.itemR(tex, "noise_size", text="Size")
|
||||
flow.itemR(tex, "noise_depth", text="Depth")
|
||||
flow.itemR(tex, "turbulence")
|
||||
flow.itemR(tex, "nabla")
|
||||
|
||||
class TEXTURE_PT_magic(TextureTypePanel):
|
||||
__label__ = "Magic"
|
||||
tex_type = 'MAGIC'
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
tex = context.texture
|
||||
|
||||
row = layout.row()
|
||||
row.itemR(tex, "noise_depth", text="Depth")
|
||||
row.itemR(tex, "turbulence")
|
||||
|
||||
class TEXTURE_PT_blend(TextureTypePanel):
|
||||
__label__ = "Blend"
|
||||
tex_type = 'BLEND'
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
tex = context.texture
|
||||
|
||||
layout.itemR(tex, "progression")
|
||||
sub = layout.row()
|
||||
|
||||
sub.active = (tex.progression in ('LINEAR', 'QUADRATIC', 'EASING', 'RADIAL'))
|
||||
sub.itemR(tex, "flip_axis", expand=True)
|
||||
|
||||
class TEXTURE_PT_stucci(TextureTypePanel):
|
||||
__label__ = "Stucci"
|
||||
tex_type = 'STUCCI'
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
tex = context.texture
|
||||
|
||||
layout.itemR(tex, "stype", expand=True)
|
||||
layout.itemL(text="Noise:")
|
||||
layout.itemR(tex, "noise_type", text="Type", expand=True)
|
||||
layout.itemR(tex, "noise_basis", text="Basis")
|
||||
|
||||
row = layout.row()
|
||||
row.itemR(tex, "noise_size", text="Size")
|
||||
row.itemR(tex, "turbulence")
|
||||
|
||||
class TEXTURE_PT_image(TextureTypePanel):
|
||||
__label__ = "Image"
|
||||
tex_type = 'IMAGE'
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
tex = context.texture
|
||||
|
||||
layout.template_image(tex, "image", tex.image_user)
|
||||
|
||||
class TEXTURE_PT_image_sampling(TextureTypePanel):
|
||||
__label__ = "Image Sampling"
|
||||
__default_closed__ = True
|
||||
tex_type = 'IMAGE'
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
tex = context.texture
|
||||
slot = context.texture_slot
|
||||
|
||||
split = layout.split()
|
||||
|
||||
"""
|
||||
col = split.column()
|
||||
col.itemR(tex, "flip_axis")
|
||||
col.itemR(tex, "normal_map")
|
||||
if slot:
|
||||
row = col.row()
|
||||
row.active = tex.normal_map
|
||||
row.itemR(slot, "normal_map_space", text="")
|
||||
"""
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Alpha:")
|
||||
col.itemR(tex, "use_alpha", text="Use")
|
||||
col.itemR(tex, "calculate_alpha", text="Calculate")
|
||||
col.itemR(tex, "invert_alpha", text="Invert")
|
||||
|
||||
col.itemL(text="Flip:")
|
||||
col.itemR(tex, "flip_axis", text="X/Y Axis")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Filter:")
|
||||
col.itemR(tex, "filter", text="")
|
||||
col.itemR(tex, "mipmap")
|
||||
|
||||
row = col.row()
|
||||
row.active = tex.mipmap
|
||||
row.itemR(tex, "mipmap_gauss", text="Gauss")
|
||||
|
||||
col.itemR(tex, "interpolation")
|
||||
if tex.mipmap and tex.filter != 'DEFAULT':
|
||||
if tex.filter == 'FELINE':
|
||||
col.itemR(tex, "filter_probes", text="Probes")
|
||||
else:
|
||||
col.itemR(tex, "filter_eccentricity", text="Eccentricity")
|
||||
|
||||
class TEXTURE_PT_image_mapping(TextureTypePanel):
|
||||
__label__ = "Image Mapping"
|
||||
__default_closed__ = True
|
||||
tex_type = 'IMAGE'
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
tex = context.texture
|
||||
|
||||
layout.itemR(tex, "extension")
|
||||
|
||||
split = layout.split()
|
||||
|
||||
if tex.extension == 'REPEAT':
|
||||
col = split.column(align=True)
|
||||
col.itemL(text="Repeat:")
|
||||
col.itemR(tex, "repeat_x", text="X")
|
||||
col.itemR(tex, "repeat_y", text="Y")
|
||||
|
||||
col = split.column(align=True)
|
||||
col.itemL(text="Mirror:")
|
||||
col.itemR(tex, "mirror_x", text="X")
|
||||
col.itemR(tex, "mirror_y", text="Y")
|
||||
elif tex.extension == 'CHECKER':
|
||||
col = split.column(align=True)
|
||||
row = col.row()
|
||||
row.itemR(tex, "checker_even", text="Even")
|
||||
row.itemR(tex, "checker_odd", text="Odd")
|
||||
|
||||
split.itemR(tex, "checker_distance", text="Distance")
|
||||
|
||||
layout.itemS()
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column(align=True)
|
||||
#col.itemR(tex, "crop_rectangle")
|
||||
col.itemL(text="Crop Minimum:")
|
||||
col.itemR(tex, "crop_min_x", text="X")
|
||||
col.itemR(tex, "crop_min_y", text="Y")
|
||||
|
||||
col = split.column(align=True)
|
||||
col.itemL(text="Crop Maximum:")
|
||||
col.itemR(tex, "crop_max_x", text="X")
|
||||
col.itemR(tex, "crop_max_y", text="Y")
|
||||
|
||||
class TEXTURE_PT_plugin(TextureTypePanel):
|
||||
__label__ = "Plugin"
|
||||
tex_type = 'PLUGIN'
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
tex = context.texture
|
||||
|
||||
layout.itemL(text="Nothing yet")
|
||||
|
||||
class TEXTURE_PT_envmap(TextureTypePanel):
|
||||
__label__ = "Environment Map"
|
||||
tex_type = 'ENVIRONMENT_MAP'
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
tex = context.texture
|
||||
|
||||
layout.itemL(text="Nothing yet")
|
||||
|
||||
class TEXTURE_PT_musgrave(TextureTypePanel):
|
||||
__label__ = "Musgrave"
|
||||
tex_type = 'MUSGRAVE'
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
tex = context.texture
|
||||
|
||||
layout.itemR(tex, "musgrave_type")
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemR(tex, "highest_dimension", text="Dimension")
|
||||
col.itemR(tex, "lacunarity")
|
||||
col.itemR(tex, "octaves")
|
||||
|
||||
col = split.column()
|
||||
if (tex.musgrave_type in ('HETERO_TERRAIN', 'RIDGED_MULTIFRACTAL', 'HYBRID_MULTIFRACTAL')):
|
||||
col.itemR(tex, "offset")
|
||||
if (tex.musgrave_type in ('RIDGED_MULTIFRACTAL', 'HYBRID_MULTIFRACTAL')):
|
||||
col.itemR(tex, "gain")
|
||||
col.itemR(tex, "noise_intensity", text="Intensity")
|
||||
|
||||
layout.itemL(text="Noise:")
|
||||
|
||||
layout.itemR(tex, "noise_basis", text="Basis")
|
||||
|
||||
row = layout.row()
|
||||
row.itemR(tex, "noise_size", text="Size")
|
||||
row.itemR(tex, "nabla")
|
||||
|
||||
class TEXTURE_PT_voronoi(TextureTypePanel):
|
||||
__label__ = "Voronoi"
|
||||
tex_type = 'VORONOI'
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
tex = context.texture
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Distance Metric:")
|
||||
col.itemR(tex, "distance_metric", text="")
|
||||
sub = col.column()
|
||||
sub.active = tex.distance_metric == 'MINKOVSKY'
|
||||
sub.itemR(tex, "minkovsky_exponent", text="Exponent")
|
||||
col.itemL(text="Coloring:")
|
||||
col.itemR(tex, "coloring", text="")
|
||||
col.itemR(tex, "noise_intensity", text="Intensity")
|
||||
|
||||
col = split.column(align=True)
|
||||
col.itemL(text="Feature Weights:")
|
||||
col.itemR(tex, "weight_1", text="1", slider=True)
|
||||
col.itemR(tex, "weight_2", text="2", slider=True)
|
||||
col.itemR(tex, "weight_3", text="3", slider=True)
|
||||
col.itemR(tex, "weight_4", text="4", slider=True)
|
||||
|
||||
layout.itemL(text="Noise:")
|
||||
|
||||
row = layout.row()
|
||||
row.itemR(tex, "noise_size", text="Size")
|
||||
row.itemR(tex, "nabla")
|
||||
|
||||
class TEXTURE_PT_distortednoise(TextureTypePanel):
|
||||
__label__ = "Distorted Noise"
|
||||
tex_type = 'DISTORTED_NOISE'
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
tex = context.texture
|
||||
|
||||
layout.itemR(tex, "noise_distortion")
|
||||
layout.itemR(tex, "noise_basis", text="Basis")
|
||||
|
||||
flow = layout.column_flow()
|
||||
flow.itemR(tex, "distortion", text="Distortion")
|
||||
flow.itemR(tex, "noise_size", text="Size")
|
||||
flow.itemR(tex, "nabla")
|
||||
|
||||
class TEXTURE_PT_voxeldata(TextureButtonsPanel):
|
||||
__label__ = "Voxel Data"
|
||||
|
||||
def poll(self, context):
|
||||
tex = context.texture
|
||||
return (tex and tex.type == 'VOXEL_DATA')
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
tex = context.texture
|
||||
vd = tex.voxeldata
|
||||
|
||||
layout.itemR(vd, "file_format")
|
||||
if vd.file_format in ['BLENDER_VOXEL', 'RAW_8BIT']:
|
||||
layout.itemR(vd, "source_path")
|
||||
if vd.file_format == 'RAW_8BIT':
|
||||
layout.itemR(vd, "resolution")
|
||||
elif vd.file_format == 'SMOKE':
|
||||
layout.itemR(vd, "domain_object")
|
||||
|
||||
layout.itemR(vd, "still")
|
||||
row = layout.row()
|
||||
row.active = vd.still
|
||||
row.itemR(vd, "still_frame_number")
|
||||
|
||||
layout.itemR(vd, "interpolation")
|
||||
layout.itemR(vd, "extension")
|
||||
layout.itemR(vd, "intensity")
|
||||
|
||||
class TEXTURE_PT_pointdensity(TextureButtonsPanel):
|
||||
__label__ = "Point Density"
|
||||
|
||||
def poll(self, context):
|
||||
tex = context.texture
|
||||
return (tex and tex.type == 'POINT_DENSITY')
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
tex = context.texture
|
||||
pd = tex.pointdensity
|
||||
|
||||
layout.itemR(pd, "point_source", expand=True)
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
if pd.point_source == 'PARTICLE_SYSTEM':
|
||||
col.itemL(text="Object:")
|
||||
col.itemR(pd, "object", text="")
|
||||
|
||||
sub = col.column()
|
||||
sub.enabled = pd.object
|
||||
if pd.object:
|
||||
sub.itemL(text="System:")
|
||||
sub.item_pointerR(pd, "particle_system", pd.object, "particle_systems", text="")
|
||||
sub.itemL(text="Cache:")
|
||||
sub.itemR(pd, "particle_cache", text="")
|
||||
else:
|
||||
col.itemL(text="Object:")
|
||||
col.itemR(pd, "object", text="")
|
||||
col.itemL(text="Cache:")
|
||||
col.itemR(pd, "vertices_cache", text="")
|
||||
|
||||
col.itemS()
|
||||
|
||||
col.itemL(text="Color Source:")
|
||||
col.itemR(pd, "color_source", text="")
|
||||
if pd.color_source in ('PARTICLE_SPEED', 'PARTICLE_VELOCITY'):
|
||||
col.itemR(pd, "speed_scale")
|
||||
if pd.color_source in ('PARTICLE_SPEED', 'PARTICLE_AGE'):
|
||||
layout.template_color_ramp(pd, "color_ramp", expand=True)
|
||||
|
||||
col = split.column()
|
||||
col.itemL()
|
||||
col.itemR(pd, "radius")
|
||||
col.itemL(text="Falloff:")
|
||||
col.itemR(pd, "falloff", text="")
|
||||
if pd.falloff == 'SOFT':
|
||||
col.itemR(pd, "falloff_softness")
|
||||
|
||||
class TEXTURE_PT_pointdensity_turbulence(TextureButtonsPanel):
|
||||
__label__ = "Turbulence"
|
||||
|
||||
def poll(self, context):
|
||||
tex = context.texture
|
||||
return (tex and tex.type == 'POINT_DENSITY')
|
||||
|
||||
def draw_header(self, context):
|
||||
layout = self.layout
|
||||
|
||||
tex = context.texture
|
||||
pd = tex.pointdensity
|
||||
|
||||
layout.itemR(pd, "turbulence", text="")
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
tex = context.texture
|
||||
pd = tex.pointdensity
|
||||
layout.active = pd.turbulence
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Influence:")
|
||||
col.itemR(pd, "turbulence_influence", text="")
|
||||
col.itemL(text="Noise Basis:")
|
||||
col.itemR(pd, "noise_basis", text="")
|
||||
|
||||
col = split.column()
|
||||
col.itemL()
|
||||
col.itemR(pd, "turbulence_size")
|
||||
col.itemR(pd, "turbulence_depth")
|
||||
col.itemR(pd, "turbulence_strength")
|
||||
|
||||
bpy.types.register(TEXTURE_PT_context_texture)
|
||||
bpy.types.register(TEXTURE_PT_preview)
|
||||
|
||||
bpy.types.register(TEXTURE_PT_clouds) # Texture Type Panels
|
||||
bpy.types.register(TEXTURE_PT_wood)
|
||||
bpy.types.register(TEXTURE_PT_marble)
|
||||
bpy.types.register(TEXTURE_PT_magic)
|
||||
bpy.types.register(TEXTURE_PT_blend)
|
||||
bpy.types.register(TEXTURE_PT_stucci)
|
||||
bpy.types.register(TEXTURE_PT_image)
|
||||
bpy.types.register(TEXTURE_PT_image_sampling)
|
||||
bpy.types.register(TEXTURE_PT_image_mapping)
|
||||
bpy.types.register(TEXTURE_PT_plugin)
|
||||
bpy.types.register(TEXTURE_PT_envmap)
|
||||
bpy.types.register(TEXTURE_PT_musgrave)
|
||||
bpy.types.register(TEXTURE_PT_voronoi)
|
||||
bpy.types.register(TEXTURE_PT_distortednoise)
|
||||
bpy.types.register(TEXTURE_PT_voxeldata)
|
||||
bpy.types.register(TEXTURE_PT_pointdensity)
|
||||
bpy.types.register(TEXTURE_PT_pointdensity_turbulence)
|
||||
|
||||
bpy.types.register(TEXTURE_PT_colors)
|
||||
bpy.types.register(TEXTURE_PT_mapping)
|
||||
bpy.types.register(TEXTURE_PT_influence)
|
||||
|
@ -1,182 +0,0 @@
|
||||
|
||||
import bpy
|
||||
|
||||
class WorldButtonsPanel(bpy.types.Panel):
|
||||
__space_type__ = 'PROPERTIES'
|
||||
__region_type__ = 'WINDOW'
|
||||
__context__ = "world"
|
||||
# COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here
|
||||
|
||||
def poll(self, context):
|
||||
rd = context.scene.render_data
|
||||
return (context.world) and (not rd.use_game_engine) and (rd.engine in self.COMPAT_ENGINES)
|
||||
|
||||
class WORLD_PT_preview(WorldButtonsPanel):
|
||||
__label__ = "Preview"
|
||||
COMPAT_ENGINES = set(['BLENDER_RENDER'])
|
||||
|
||||
def draw(self, context):
|
||||
self.layout.template_preview(context.world)
|
||||
|
||||
class WORLD_PT_context_world(WorldButtonsPanel):
|
||||
__show_header__ = False
|
||||
COMPAT_ENGINES = set(['BLENDER_RENDER'])
|
||||
|
||||
def poll(self, context):
|
||||
rd = context.scene.render_data
|
||||
return (not rd.use_game_engine) and (rd.engine in self.COMPAT_ENGINES)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
scene = context.scene
|
||||
world = context.world
|
||||
space = context.space_data
|
||||
|
||||
split = layout.split(percentage=0.65)
|
||||
|
||||
if scene:
|
||||
split.template_ID(scene, "world", new="world.new")
|
||||
elif world:
|
||||
split.template_ID(space, "pin_id")
|
||||
|
||||
class WORLD_PT_world(WorldButtonsPanel):
|
||||
__label__ = "World"
|
||||
COMPAT_ENGINES = set(['BLENDER_RENDER'])
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
world = context.world
|
||||
|
||||
row = layout.row()
|
||||
row.itemR(world, "paper_sky")
|
||||
row.itemR(world, "blend_sky")
|
||||
row.itemR(world, "real_sky")
|
||||
|
||||
row = layout.row()
|
||||
row.column().itemR(world, "horizon_color")
|
||||
col = row.column()
|
||||
col.itemR(world, "zenith_color")
|
||||
col.active = world.blend_sky
|
||||
row.column().itemR(world, "ambient_color")
|
||||
|
||||
class WORLD_PT_mist(WorldButtonsPanel):
|
||||
__label__ = "Mist"
|
||||
COMPAT_ENGINES = set(['BLENDER_RENDER'])
|
||||
|
||||
def draw_header(self, context):
|
||||
world = context.world
|
||||
|
||||
self.layout.itemR(world.mist, "enabled", text="")
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
world = context.world
|
||||
|
||||
layout.active = world.mist.enabled
|
||||
|
||||
flow = layout.column_flow()
|
||||
flow.itemR(world.mist, "intensity", slider=True)
|
||||
flow.itemR(world.mist, "start")
|
||||
flow.itemR(world.mist, "depth")
|
||||
flow.itemR(world.mist, "height")
|
||||
|
||||
layout.itemR(world.mist, "falloff")
|
||||
|
||||
class WORLD_PT_stars(WorldButtonsPanel):
|
||||
__label__ = "Stars"
|
||||
COMPAT_ENGINES = set(['BLENDER_RENDER'])
|
||||
|
||||
def draw_header(self, context):
|
||||
world = context.world
|
||||
|
||||
self.layout.itemR(world.stars, "enabled", text="")
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
world = context.world
|
||||
|
||||
layout.active = world.stars.enabled
|
||||
|
||||
flow = layout.column_flow()
|
||||
flow.itemR(world.stars, "size")
|
||||
flow.itemR(world.stars, "color_randomization", text="Colors")
|
||||
flow.itemR(world.stars, "min_distance", text="Min. Dist")
|
||||
flow.itemR(world.stars, "average_separation", text="Separation")
|
||||
|
||||
class WORLD_PT_ambient_occlusion(WorldButtonsPanel):
|
||||
__label__ = "Ambient Occlusion"
|
||||
COMPAT_ENGINES = set(['BLENDER_RENDER'])
|
||||
|
||||
def draw_header(self, context):
|
||||
world = context.world
|
||||
|
||||
self.layout.itemR(world.ambient_occlusion, "enabled", text="")
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
ao = context.world.ambient_occlusion
|
||||
|
||||
layout.active = ao.enabled
|
||||
|
||||
layout.itemR(ao, "gather_method", expand=True)
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Attenuation:")
|
||||
if ao.gather_method == 'RAYTRACE':
|
||||
col.itemR(ao, "distance")
|
||||
col.itemR(ao, "falloff")
|
||||
sub = col.row()
|
||||
sub.active = ao.falloff
|
||||
sub.itemR(ao, "falloff_strength", text="Strength")
|
||||
|
||||
if ao.gather_method == 'RAYTRACE':
|
||||
col = split.column()
|
||||
|
||||
col.itemL(text="Sampling:")
|
||||
col.itemR(ao, "sample_method", text="")
|
||||
|
||||
sub = col.column()
|
||||
sub.itemR(ao, "samples")
|
||||
|
||||
if ao.sample_method == 'ADAPTIVE_QMC':
|
||||
sub.itemR(ao, "threshold")
|
||||
sub.itemR(ao, "adapt_to_speed", slider=True)
|
||||
elif ao.sample_method == 'CONSTANT_JITTERED':
|
||||
sub.itemR(ao, "bias")
|
||||
|
||||
if ao.gather_method == 'APPROXIMATE':
|
||||
col = split.column()
|
||||
|
||||
col.itemL(text="Sampling:")
|
||||
col.itemR(ao, "error_tolerance", text="Error")
|
||||
col.itemR(ao, "pixel_cache")
|
||||
col.itemR(ao, "correction")
|
||||
|
||||
col = layout.column()
|
||||
col.itemL(text="Influence:")
|
||||
|
||||
col.row().itemR(ao, "blend_mode", expand=True)
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemR(ao, "energy")
|
||||
|
||||
col = split.column()
|
||||
sub = col.split(percentage=0.3)
|
||||
sub.itemL(text="Color:")
|
||||
sub.itemR(ao, "color", text="")
|
||||
|
||||
bpy.types.register(WORLD_PT_context_world)
|
||||
bpy.types.register(WORLD_PT_preview)
|
||||
bpy.types.register(WORLD_PT_world)
|
||||
bpy.types.register(WORLD_PT_ambient_occlusion)
|
||||
bpy.types.register(WORLD_PT_mist)
|
||||
bpy.types.register(WORLD_PT_stars)
|
209
release/scripts/ui/properties_data_armature.py
Normal file
209
release/scripts/ui/properties_data_armature.py
Normal file
@ -0,0 +1,209 @@
|
||||
# ##### 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
# <pep8 compliant>
|
||||
import bpy
|
||||
|
||||
|
||||
class DataButtonsPanel(bpy.types.Panel):
|
||||
bl_space_type = 'PROPERTIES'
|
||||
bl_region_type = 'WINDOW'
|
||||
bl_context = "data"
|
||||
|
||||
def poll(self, context):
|
||||
return context.armature
|
||||
|
||||
|
||||
class DATA_PT_context_arm(DataButtonsPanel):
|
||||
bl_label = ""
|
||||
bl_show_header = False
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
ob = context.object
|
||||
arm = context.armature
|
||||
space = context.space_data
|
||||
|
||||
split = layout.split(percentage=0.65)
|
||||
|
||||
if ob:
|
||||
split.template_ID(ob, "data")
|
||||
split.itemS()
|
||||
elif arm:
|
||||
split.template_ID(space, "pin_id")
|
||||
split.itemS()
|
||||
|
||||
|
||||
class DATA_PT_skeleton(DataButtonsPanel):
|
||||
bl_label = "Skeleton"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
ob = context.object
|
||||
arm = context.armature
|
||||
space = context.space_data
|
||||
|
||||
layout.itemR(arm, "pose_position", expand=True)
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Layers:")
|
||||
col.itemR(arm, "layer", text="")
|
||||
col.itemL(text="Protected Layers:")
|
||||
col.itemR(arm, "layer_protection", text="")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Deform:")
|
||||
col.itemR(arm, "deform_vertexgroups", text="Vertex Groups")
|
||||
col.itemR(arm, "deform_envelope", text="Envelopes")
|
||||
col.itemR(arm, "deform_quaternion", text="Quaternion")
|
||||
col.itemR(arm, "deform_bbone_rest", text="B-Bones Rest")
|
||||
|
||||
|
||||
class DATA_PT_display(DataButtonsPanel):
|
||||
bl_label = "Display"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
arm = context.armature
|
||||
|
||||
layout.row().itemR(arm, "drawtype", expand=True)
|
||||
|
||||
flow = layout.column_flow()
|
||||
flow.itemR(arm, "draw_names", text="Names")
|
||||
flow.itemR(arm, "draw_axes", text="Axes")
|
||||
flow.itemR(arm, "draw_custom_bone_shapes", text="Shapes")
|
||||
flow.itemR(arm, "draw_group_colors", text="Colors")
|
||||
flow.itemR(arm, "delay_deform", text="Delay Refresh")
|
||||
|
||||
|
||||
class DATA_PT_bone_groups(DataButtonsPanel):
|
||||
bl_label = "Bone Groups"
|
||||
|
||||
def poll(self, context):
|
||||
return (context.object and context.object.type == 'ARMATURE' and context.object.pose)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
ob = context.object
|
||||
pose = ob.pose
|
||||
|
||||
row = layout.row()
|
||||
row.template_list(pose, "bone_groups", pose, "active_bone_group_index", rows=2)
|
||||
|
||||
col = row.column(align=True)
|
||||
col.active = (ob.proxy == None)
|
||||
col.itemO("pose.group_add", icon='ICON_ZOOMIN', text="")
|
||||
col.itemO("pose.group_remove", icon='ICON_ZOOMOUT', text="")
|
||||
|
||||
group = pose.active_bone_group
|
||||
if group:
|
||||
col = layout.column()
|
||||
col.active = (ob.proxy == None)
|
||||
col.itemR(group, "name")
|
||||
|
||||
split = layout.split(0.5)
|
||||
split.active = (ob.proxy == None)
|
||||
split.itemR(group, "color_set")
|
||||
if group.color_set:
|
||||
split.template_triColorSet(group, "colors")
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.active = (ob.proxy == None)
|
||||
|
||||
row.itemO("pose.group_assign", text="Assign")
|
||||
row.itemO("pose.group_remove", text="Remove") #row.itemO("pose.bone_group_remove_from", text="Remove")
|
||||
#row.itemO("object.bone_group_select", text="Select")
|
||||
#row.itemO("object.bone_group_deselect", text="Deselect")
|
||||
|
||||
|
||||
class DATA_PT_paths(DataButtonsPanel):
|
||||
bl_label = "Paths"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
arm = context.armature
|
||||
|
||||
layout.itemR(arm, "paths_type", expand=True)
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
sub = col.column(align=True)
|
||||
if (arm.paths_type == 'CURRENT_FRAME'):
|
||||
sub.itemR(arm, "path_before_current", text="Before")
|
||||
sub.itemR(arm, "path_after_current", text="After")
|
||||
elif (arm.paths_type == 'RANGE'):
|
||||
sub.itemR(arm, "path_start_frame", text="Start")
|
||||
sub.itemR(arm, "path_end_frame", text="End")
|
||||
|
||||
sub.itemR(arm, "path_size", text="Step")
|
||||
col.row().itemR(arm, "paths_location", expand=True)
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Display:")
|
||||
col.itemR(arm, "paths_show_frame_numbers", text="Frame Numbers")
|
||||
col.itemR(arm, "paths_highlight_keyframes", text="Keyframes")
|
||||
col.itemR(arm, "paths_show_keyframe_numbers", text="Keyframe Numbers")
|
||||
|
||||
layout.itemS()
|
||||
|
||||
row = layout.row()
|
||||
row.itemO("pose.paths_calculate", text="Calculate Paths")
|
||||
row.itemO("pose.paths_clear", text="Clear Paths")
|
||||
|
||||
|
||||
class DATA_PT_ghost(DataButtonsPanel):
|
||||
bl_label = "Ghost"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
arm = context.armature
|
||||
|
||||
layout.itemR(arm, "ghost_type", expand=True)
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
|
||||
sub = col.column(align=True)
|
||||
if arm.ghost_type == 'RANGE':
|
||||
sub.itemR(arm, "ghost_start_frame", text="Start")
|
||||
sub.itemR(arm, "ghost_end_frame", text="End")
|
||||
sub.itemR(arm, "ghost_size", text="Step")
|
||||
elif arm.ghost_type == 'CURRENT_FRAME':
|
||||
sub.itemR(arm, "ghost_step", text="Range")
|
||||
sub.itemR(arm, "ghost_size", text="Step")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Display:")
|
||||
col.itemR(arm, "ghost_only_selected", text="Selected Only")
|
||||
|
||||
bpy.types.register(DATA_PT_context_arm)
|
||||
bpy.types.register(DATA_PT_skeleton)
|
||||
bpy.types.register(DATA_PT_display)
|
||||
bpy.types.register(DATA_PT_bone_groups)
|
||||
bpy.types.register(DATA_PT_paths)
|
||||
bpy.types.register(DATA_PT_ghost)
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user