Merged changes in the trunk up to revision 26260.
This commit is contained in:
@@ -248,7 +248,7 @@ IF(UNIX AND NOT APPLE)
|
|||||||
SET(PLATFORM_LINKFLAGS "-pthread")
|
SET(PLATFORM_LINKFLAGS "-pthread")
|
||||||
|
|
||||||
# Better warnings
|
# Better warnings
|
||||||
SET(C_WARNINGS "-Wall -Wno-char-subscripts -Wpointer-arith -Wcast-align -Wdeclaration-after-statement")
|
SET(C_WARNINGS "-Wall -Wno-char-subscripts -Wpointer-arith -Wcast-align -Wdeclaration-after-statement -Wno-unknown-pragmas")
|
||||||
SET(CXX_WARNINGS "-Wall -Wno-invalid-offsetof -Wno-sign-compare")
|
SET(CXX_WARNINGS "-Wall -Wno-invalid-offsetof -Wno-sign-compare")
|
||||||
|
|
||||||
INCLUDE_DIRECTORIES(${JPEG_INCLUDE_DIR} ${PNG_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR} )
|
INCLUDE_DIRECTORIES(${JPEG_INCLUDE_DIR} ${PNG_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR} )
|
||||||
@@ -601,7 +601,7 @@ IF(APPLE)
|
|||||||
ENDIF(CMAKE_OSX_ARCHITECTURES MATCHES "i386")
|
ENDIF(CMAKE_OSX_ARCHITECTURES MATCHES "i386")
|
||||||
|
|
||||||
# Better warnings
|
# Better warnings
|
||||||
SET(C_WARNINGS "-Wall -Wno-char-subscripts -Wpointer-arith -Wcast-align -Wdeclaration-after-statement")
|
SET(C_WARNINGS "-Wall -Wno-char-subscripts -Wpointer-arith -Wcast-align -Wdeclaration-after-statement -Wno-unknown-pragmas")
|
||||||
SET(CXX_WARNINGS "-Wall -Wno-invalid-offsetof -Wno-sign-compare")
|
SET(CXX_WARNINGS "-Wall -Wno-invalid-offsetof -Wno-sign-compare")
|
||||||
|
|
||||||
ENDIF(APPLE)
|
ENDIF(APPLE)
|
||||||
|
|||||||
225
config/aix4-config.py
Normal file
225
config/aix4-config.py
Normal file
@@ -0,0 +1,225 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
|
LCGDIR = os.getcwd()+"/../lib/aix-4.3-ppc"
|
||||||
|
LIBDIR = LCGDIR
|
||||||
|
print LCGDIR
|
||||||
|
|
||||||
|
WITH_BF_VERSE = 'false'
|
||||||
|
BF_VERSE_INCLUDE = "#extern/verse/dist"
|
||||||
|
|
||||||
|
BF_PYTHON = LCGDIR+'/python'
|
||||||
|
BF_PYTHON_VERSION = '3.1'
|
||||||
|
WITH_BF_STATICPYTHON = 'true'
|
||||||
|
BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}'
|
||||||
|
BF_PYTHON_BINARY = '${BF_PYTHON}/bin/python${BF_PYTHON_VERSION}'
|
||||||
|
BF_PYTHON_LIB = 'python${BF_PYTHON_VERSION}' #BF_PYTHON+'/lib/python'+BF_PYTHON_VERSION+'/config/libpython'+BF_PYTHON_VERSION+'.a'
|
||||||
|
BF_PYTHON_LINKFLAGS = ['-Xlinker', '-export-dynamic']
|
||||||
|
BF_PYTHON_LIB_STATIC = '${BF_PYTHON}/lib/python2.5/config/libpython${BF_PYTHON_VERSION}.a'
|
||||||
|
|
||||||
|
WITH_BF_OPENAL = 'false'
|
||||||
|
WITH_BF_STATICOPENAL = 'false'
|
||||||
|
BF_OPENAL = LCGDIR+'/openal'
|
||||||
|
BF_OPENAL_INC = '${BF_OPENAL}/include'
|
||||||
|
BF_OPENAL_LIB = 'openal'
|
||||||
|
BF_OPENAL_LIB_STATIC = '${BF_OPENAL}/lib/libopenal.a'
|
||||||
|
BF_OPENAL_LIBPATH = LIBDIR + '/lib'
|
||||||
|
|
||||||
|
BF_CXX = '/usr'
|
||||||
|
WITH_BF_STATICCXX = 'false'
|
||||||
|
BF_CXX_LIB_STATIC = '${BF_CXX}/lib/libstdc++.a'
|
||||||
|
|
||||||
|
WITH_BF_SDL = 'false'
|
||||||
|
BF_SDL = LCGDIR+'/sdl' #$(shell sdl-config --prefix)
|
||||||
|
BF_SDL_INC = '${BF_SDL}/include/SDL' #$(shell $(BF_SDL)/bin/sdl-config --cflags)
|
||||||
|
BF_SDL_LIB = 'SDL audio iconv charset' #BF_SDL #$(shell $(BF_SDL)/bin/sdl-config --libs) -lSDL_mixer
|
||||||
|
BF_SDL_LIBPATH = '${BF_SDL}/lib'
|
||||||
|
|
||||||
|
WITH_BF_OPENEXR = 'false'
|
||||||
|
WITH_BF_STATICOPENEXR = 'false'
|
||||||
|
BF_OPENEXR = '/usr'
|
||||||
|
# when compiling with your own openexr lib you might need to set...
|
||||||
|
# BF_OPENEXR_INC = '${BF_OPENEXR}/include/OpenEXR ${BF_OPENEXR}/include'
|
||||||
|
|
||||||
|
BF_OPENEXR_INC = '${BF_OPENEXR}/include/OpenEXR'
|
||||||
|
BF_OPENEXR_LIB = 'Half IlmImf Iex Imath '
|
||||||
|
BF_OPENEXR_LIB_STATIC = '${BF_OPENEXR}/lib/libHalf.a ${BF_OPENEXR}/lib/libIlmImf.a ${BF_OPENEXR}/lib/libIex.a ${BF_OPENEXR}/lib/libImath.a ${BF_OPENEXR}/lib/libIlmThread.a'
|
||||||
|
# BF_OPENEXR_LIBPATH = '${BF_OPENEXR}/lib'
|
||||||
|
|
||||||
|
|
||||||
|
WITH_BF_DDS = 'false'
|
||||||
|
|
||||||
|
WITH_BF_JPEG = 'false'
|
||||||
|
BF_JPEG = LCGDIR+'/jpeg'
|
||||||
|
BF_JPEG_INC = '${BF_JPEG}/include'
|
||||||
|
BF_JPEG_LIB = 'jpeg'
|
||||||
|
BF_JPEG_LIBPATH = '${BF_JPEG}/lib'
|
||||||
|
|
||||||
|
WITH_BF_PNG = 'false'
|
||||||
|
BF_PNG = LCGDIR+"/png"
|
||||||
|
BF_PNG_INC = '${BF_PNG}/include'
|
||||||
|
BF_PNG_LIB = 'png'
|
||||||
|
BF_PNG_LIBPATH = '${BF_PNG}/lib'
|
||||||
|
|
||||||
|
BF_TIFF = '/usr/nekoware'
|
||||||
|
BF_TIFF_INC = '${BF_TIFF}/include'
|
||||||
|
|
||||||
|
WITH_BF_ZLIB = 'true'
|
||||||
|
BF_ZLIB = LCGDIR+"/zlib"
|
||||||
|
BF_ZLIB_INC = '${BF_ZLIB}/include'
|
||||||
|
BF_ZLIB_LIB = 'z'
|
||||||
|
BF_ZLIB_LIBPATH = '${BF_ZLIB}/lib'
|
||||||
|
|
||||||
|
WITH_BF_INTERNATIONAL = 'false'
|
||||||
|
|
||||||
|
BF_GETTEXT = LCGDIR+'/gettext'
|
||||||
|
BF_GETTEXT_INC = '${BF_GETTEXT}/include'
|
||||||
|
BF_GETTEXT_LIB = 'gettextpo intl'
|
||||||
|
BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib'
|
||||||
|
|
||||||
|
WITH_BF_FTGL = 'false'
|
||||||
|
BF_FTGL = '#extern/bFTGL'
|
||||||
|
BF_FTGL_INC = '${BF_FTGL}/include'
|
||||||
|
BF_FTGL_LIB = 'extern_ftgl'
|
||||||
|
|
||||||
|
WITH_BF_GAMEENGINE='false'
|
||||||
|
|
||||||
|
WITH_BF_ODE = 'false'
|
||||||
|
BF_ODE = LIBDIR + '/ode'
|
||||||
|
BF_ODE_INC = BF_ODE + '/include'
|
||||||
|
BF_ODE_LIB = BF_ODE + '/lib/libode.a'
|
||||||
|
|
||||||
|
WITH_BF_BULLET = 'true'
|
||||||
|
BF_BULLET = '#extern/bullet2/src'
|
||||||
|
BF_BULLET_INC = '${BF_BULLET}'
|
||||||
|
BF_BULLET_LIB = 'extern_bullet'
|
||||||
|
|
||||||
|
BF_SOLID = '#extern/solid'
|
||||||
|
BF_SOLID_INC = '${BF_SOLID}'
|
||||||
|
BF_SOLID_LIB = 'extern_solid'
|
||||||
|
|
||||||
|
WITH_BF_YAFRAY = 'true'
|
||||||
|
|
||||||
|
#WITH_BF_NSPR = 'true'
|
||||||
|
#BF_NSPR = $(LIBDIR)/nspr
|
||||||
|
#BF_NSPR_INC = -I$(BF_NSPR)/include -I$(BF_NSPR)/include/nspr
|
||||||
|
#BF_NSPR_LIB =
|
||||||
|
|
||||||
|
# Uncomment the following line to use Mozilla inplace of netscape
|
||||||
|
#CPPFLAGS += -DMOZ_NOT_NET
|
||||||
|
# Location of MOZILLA/Netscape header files...
|
||||||
|
#BF_MOZILLA = $(LIBDIR)/mozilla
|
||||||
|
#BF_MOZILLA_INC = -I$(BF_MOZILLA)/include/mozilla/nspr -I$(BF_MOZILLA)/include/mozilla -I$(BF_MOZILLA)/include/mozilla/xpcom -I$(BF_MOZILLA)/include/mozilla/idl
|
||||||
|
#BF_MOZILLA_LIB =
|
||||||
|
# Will fall back to look in BF_MOZILLA_INC/nspr and BF_MOZILLA_LIB
|
||||||
|
# if this is not set.
|
||||||
|
#
|
||||||
|
# Be paranoid regarding library creation (do not update archives)
|
||||||
|
#BF_PARANOID = 'true'
|
||||||
|
|
||||||
|
# enable freetype2 support for text objects
|
||||||
|
BF_FREETYPE = LCGDIR+'/freetype'
|
||||||
|
BF_FREETYPE_INC = '${BF_FREETYPE}/include ${BF_FREETYPE}/include/freetype2'
|
||||||
|
BF_FREETYPE_LIB = 'freetype'
|
||||||
|
BF_FREETYPE_LIBPATH = '${BF_FREETYPE}/lib'
|
||||||
|
|
||||||
|
WITH_BF_QUICKTIME = 'false' # -DWITH_QUICKTIME
|
||||||
|
BF_QUICKTIME = '/usr/local'
|
||||||
|
BF_QUICKTIME_INC = '${BF_QUICKTIME}/include'
|
||||||
|
|
||||||
|
WITH_BF_ICONV = 'false'
|
||||||
|
BF_ICONV = LIBDIR + "/iconv"
|
||||||
|
BF_ICONV_INC = '${BF_ICONV}/include'
|
||||||
|
BF_ICONV_LIB = 'iconv charset'
|
||||||
|
BF_ICONV_LIBPATH = '${BF_ICONV}/lib'
|
||||||
|
|
||||||
|
WITH_BF_BINRELOC = 'false'
|
||||||
|
|
||||||
|
# enable ffmpeg support
|
||||||
|
WITH_BF_FFMPEG = 'false' # -DWITH_FFMPEG
|
||||||
|
# Uncomment the following two lines to use system's ffmpeg
|
||||||
|
BF_FFMPEG = LCGDIR+'/ffmpeg'
|
||||||
|
BF_FFMPEG_LIB = 'avformat avcodec swscale avutil avdevice faad faac vorbis x264 ogg mp3lame z'
|
||||||
|
BF_FFMPEG_INC = '${BF_FFMPEG}/include'
|
||||||
|
BF_FFMPEG_LIBPATH='${BF_FFMPEG}/lib'
|
||||||
|
|
||||||
|
# enable ogg, vorbis and theora in ffmpeg
|
||||||
|
WITH_BF_OGG = 'false' # -DWITH_OGG
|
||||||
|
BF_OGG = '/usr'
|
||||||
|
BF_OGG_INC = '${BF_OGG}/include'
|
||||||
|
BF_OGG_LIB = 'ogg vorbis theoraenc theoradec'
|
||||||
|
|
||||||
|
WITH_BF_OPENJPEG = 'false'
|
||||||
|
BF_OPENJPEG = '#extern/libopenjpeg'
|
||||||
|
BF_OPENJPEG_LIB = ''
|
||||||
|
BF_OPENJPEG_INC = '${BF_OPENJPEG}'
|
||||||
|
BF_OPENJPEG_LIBPATH='${BF_OPENJPEG}/lib'
|
||||||
|
|
||||||
|
WITH_BF_REDCODE = 'false'
|
||||||
|
BF_REDCODE = '#extern/libredcode'
|
||||||
|
BF_REDCODE_LIB = ''
|
||||||
|
BF_REDCODE_INC = '${BF_REDCODE}/include'
|
||||||
|
BF_REDCODE_LIBPATH='${BF_REDCODE}/lib'
|
||||||
|
|
||||||
|
# Mesa Libs should go here if your using them as well....
|
||||||
|
WITH_BF_STATICOPENGL = 'false'
|
||||||
|
BF_OPENGL = '/usr'
|
||||||
|
BF_OPENGL_INC = '${BF_OPENGL}/include'
|
||||||
|
BF_OPENGL_LIB = 'GL GLU X11 Xi Xext'
|
||||||
|
BF_OPENGL_LIBPATH = '/usr/X11R6/lib'
|
||||||
|
BF_OPENGL_LIB_STATIC = '${BF_OPENGL}/libGL.a ${BF_OPENGL}/libGLU.a ${BF_OPENGL}/libXxf86vm.a ${BF_OPENGL}/libX11.a ${BF_OPENGL}/libXi.a ${BF_OPENGL}/libXext.a ${BF_OPENGL}/libXxf86vm.a'
|
||||||
|
|
||||||
|
|
||||||
|
CC = 'gcc'
|
||||||
|
CXX = 'g++'
|
||||||
|
|
||||||
|
CCFLAGS = [ '-pipe', '-funsigned-char', '-fno-strict-aliasing' ]
|
||||||
|
|
||||||
|
CPPFLAGS = [ '-DXP_UNIX', '-DWIN32', '-DFREE_WINDOWS' ]
|
||||||
|
CXXFLAGS = ['-pipe', '-funsigned-char', '-fno-strict-aliasing' ]
|
||||||
|
REL_CFLAGS = [ '-O2' ]
|
||||||
|
REL_CCFLAGS = [ '-O2' ]
|
||||||
|
C_WARN = [ '-Wall' , '-Wno-char-subscripts', '-Wdeclaration-after-statement' ]
|
||||||
|
|
||||||
|
CC_WARN = [ '-Wall' ]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
##BF_DEPEND = 'true'
|
||||||
|
##
|
||||||
|
##AR = ar
|
||||||
|
##ARFLAGS = ruv
|
||||||
|
##ARFLAGSQUIET = ru
|
||||||
|
##
|
||||||
|
|
||||||
|
##FIX_STUBS_WARNINGS = -Wno-unused
|
||||||
|
|
||||||
|
LLIBS = 'c m dl pthread dmedia movie'
|
||||||
|
##LOPTS = --dynamic
|
||||||
|
##DYNLDFLAGS = -shared $(LDFLAGS)
|
||||||
|
|
||||||
|
BF_PROFILE_FLAGS = ['-pg','-g']
|
||||||
|
BF_PROFILE = 'false'
|
||||||
|
|
||||||
|
BF_DEBUG = 'false'
|
||||||
|
BF_DEBUG_FLAGS = '-g'
|
||||||
|
|
||||||
|
BF_BUILDDIR = '../build/aix4'
|
||||||
|
BF_INSTALLDIR='../install/aix4'
|
||||||
|
BF_DOCDIR='../install/doc'
|
||||||
|
|
||||||
|
#Link against pthread
|
||||||
|
LDIRS = []
|
||||||
|
LDIRS.append(BF_FREETYPE_LIBPATH)
|
||||||
|
LDIRS.append(BF_PNG_LIBPATH)
|
||||||
|
LDIRS.append(BF_ZLIB_LIBPATH)
|
||||||
|
LDIRS.append(BF_SDL_LIBPATH)
|
||||||
|
LDIRS.append(BF_OPENAL_LIBPATH)
|
||||||
|
LDIRS.append(BF_ICONV_LIBPATH)
|
||||||
|
|
||||||
|
PLATFORM_LINKFLAGS = []
|
||||||
|
for x in LDIRS:
|
||||||
|
PLATFORM_LINKFLAGS.append("-L"+x)
|
||||||
|
|
||||||
|
PLATFORM_LINKFLAGS += ['-L${LCGDIR}/jpeg/lib' , '-L/usr/lib32', '-n32', '-v', '-no_prelink']
|
||||||
|
print PLATFORM_LINKFLAGS
|
||||||
|
LINKFLAGS= PLATFORM_LINKFLAGS
|
||||||
@@ -4,7 +4,7 @@ LCGDIR = os.getcwd()+"/../lib/irix-6.5-mips"
|
|||||||
LIBDIR = LCGDIR
|
LIBDIR = LCGDIR
|
||||||
|
|
||||||
BF_PYTHON = LCGDIR+'/python'
|
BF_PYTHON = LCGDIR+'/python'
|
||||||
BF_PYTHON_VERSION = '2.5'
|
BF_PYTHON_VERSION = '3.1'
|
||||||
WITH_BF_STATICPYTHON = 'true'
|
WITH_BF_STATICPYTHON = 'true'
|
||||||
BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}'
|
BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}'
|
||||||
BF_PYTHON_BINARY = '${BF_PYTHON}/bin/python${BF_PYTHON_VERSION}'
|
BF_PYTHON_BINARY = '${BF_PYTHON}/bin/python${BF_PYTHON_VERSION}'
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ LCGDIR = '#../lib/windows'
|
|||||||
LIBDIR = '${LCGDIR}'
|
LIBDIR = '${LCGDIR}'
|
||||||
|
|
||||||
BF_PYTHON = LIBDIR + '/python'
|
BF_PYTHON = LIBDIR + '/python'
|
||||||
BF_PYTHON_VERSION = '2.5'
|
BF_PYTHON_VERSION = '3.1'
|
||||||
BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}'
|
BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}'
|
||||||
BF_PYTHON_BINARY = 'python'
|
BF_PYTHON_BINARY = 'python'
|
||||||
BF_PYTHON_LIB = 'python25'
|
BF_PYTHON_LIB = 'python25'
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ LCGDIR = '../lib/openbsd3'
|
|||||||
LIBDIR = '${LCGDIR}'
|
LIBDIR = '${LCGDIR}'
|
||||||
|
|
||||||
BF_PYTHON = '/usr/local'
|
BF_PYTHON = '/usr/local'
|
||||||
BF_PYTHON_VERSION = '2.5'
|
BF_PYTHON_VERSION = '3.1'
|
||||||
BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}'
|
BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}'
|
||||||
BF_PYTHON_BINARY = '${BF_PYTHON}/bin/python${BF_PYTHON_VERSION}'
|
BF_PYTHON_BINARY = '${BF_PYTHON}/bin/python${BF_PYTHON_VERSION}'
|
||||||
BF_PYTHON_LIB = 'python${BF_PYTHON_VERSION}'
|
BF_PYTHON_LIB = 'python${BF_PYTHON_VERSION}'
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ LCGDIR = '../lib/sunos5'
|
|||||||
LIBDIR = '${LCGDIR}'
|
LIBDIR = '${LCGDIR}'
|
||||||
|
|
||||||
BF_PYTHON = '/usr/local'
|
BF_PYTHON = '/usr/local'
|
||||||
BF_PYTHON_VERSION = '2.5'
|
BF_PYTHON_VERSION = '3.1'
|
||||||
BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}'
|
BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}'
|
||||||
BF_PYTHON_BINARY = '${BF_PYTHON}/bin/python${BF_PYTHON_VERSION}'
|
BF_PYTHON_BINARY = '${BF_PYTHON}/bin/python${BF_PYTHON_VERSION}'
|
||||||
BF_PYTHON_LIB = 'python${BF_PYTHON_VERSION}' #BF_PYTHON+'/lib/python'+BF_PYTHON_VERSION+'/config/libpython'+BF_PYTHON_VERSION+'.a'
|
BF_PYTHON_LIB = 'python${BF_PYTHON_VERSION}' #BF_PYTHON+'/lib/python'+BF_PYTHON_VERSION+'/config/libpython'+BF_PYTHON_VERSION+'.a'
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
#
|
#
|
||||||
# ***** END LGPL LICENSE BLOCK *****
|
# ***** END LGPL LICENSE BLOCK *****
|
||||||
|
|
||||||
SET(INC . intern FX SRC ${PTHREADS_INC} ${LIBSAMPLERATE_INC} ${OPENAL_INCLUDE_DIR})
|
SET(INC . intern FX SRC ${PTHREADS_INC} ${LIBSAMPLERATE_INC})
|
||||||
|
|
||||||
FILE(GLOB SRC intern/*.cpp intern/*.h FX/*.cpp SRC/*.cpp)
|
FILE(GLOB SRC intern/*.cpp intern/*.h FX/*.cpp SRC/*.cpp)
|
||||||
|
|
||||||
|
|||||||
@@ -284,9 +284,7 @@ AUD_OpenALDevice::AUD_OpenALDevice(AUD_DeviceSpecs specs, int buffersize)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_device = alcOpenDevice("ALSA Software");
|
m_device = alcOpenDevice(NULL);
|
||||||
if(m_device == NULL)
|
|
||||||
m_device = alcOpenDevice(NULL);
|
|
||||||
|
|
||||||
if(!m_device)
|
if(!m_device)
|
||||||
AUD_THROW(AUD_ERROR_OPENAL);
|
AUD_THROW(AUD_ERROR_OPENAL);
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ if window_system == 'darwin':
|
|||||||
pf = ['GHOST_DisplayManager', 'GHOST_System', 'GHOST_Window', 'GHOST_DropTarget']
|
pf = ['GHOST_DisplayManager', 'GHOST_System', 'GHOST_Window', 'GHOST_DropTarget']
|
||||||
defs=['_USE_MATH_DEFINES']
|
defs=['_USE_MATH_DEFINES']
|
||||||
|
|
||||||
if window_system in ('linux2', 'openbsd3', 'sunos5', 'freebsd6', 'irix6'):
|
if window_system in ('linux2', 'openbsd3', 'sunos5', 'freebsd6', 'irix6', 'aix4', 'aix5'):
|
||||||
for f in pf:
|
for f in pf:
|
||||||
try:
|
try:
|
||||||
sources.remove('intern' + os.sep + f + 'Win32.cpp')
|
sources.remove('intern' + os.sep + f + 'Win32.cpp')
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
#include <X11/cursorfont.h>
|
#include <X11/cursorfont.h>
|
||||||
#include <X11/Xatom.h>
|
#include <X11/Xatom.h>
|
||||||
|
|
||||||
#if defined(__sun__) || defined( __sun ) || defined (__sparc) || defined (__sparc__)
|
#if defined(__sun__) || defined( __sun ) || defined (__sparc) || defined (__sparc__) || defined (_AIX)
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -1435,7 +1435,7 @@ setWindowCursorGrab(
|
|||||||
setWindowCursorVisibility(false);
|
setWindowCursorVisibility(false);
|
||||||
|
|
||||||
}
|
}
|
||||||
XGrabPointer(m_display, m_window, True, ButtonPressMask| ButtonReleaseMask|PointerMotionMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
|
XGrabPointer(m_display, m_window, False, ButtonPressMask| ButtonReleaseMask|PointerMotionMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (m_cursorGrab==GHOST_kGrabHide) {
|
if (m_cursorGrab==GHOST_kGrabHide) {
|
||||||
|
|||||||
@@ -487,8 +487,10 @@ short MEM_testN(void *vmemh) {
|
|||||||
if (membl) membl = MEMNEXT(membl);
|
if (membl) membl = MEMNEXT(membl);
|
||||||
|
|
||||||
while(membl) {
|
while(membl) {
|
||||||
if (vmemh == membl+1)
|
if (vmemh == membl+1) {
|
||||||
|
mem_unlock_thread();
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
if(membl->next)
|
if(membl->next)
|
||||||
membl= MEMNEXT(membl->next);
|
membl= MEMNEXT(membl->next);
|
||||||
@@ -628,8 +630,8 @@ static void rem_memblock(MemHead *memh)
|
|||||||
mmap_in_use -= memh->len;
|
mmap_in_use -= memh->len;
|
||||||
if (munmap(memh, memh->len + sizeof(MemHead) + sizeof(MemTail)))
|
if (munmap(memh, memh->len + sizeof(MemHead) + sizeof(MemTail)))
|
||||||
printf("Couldn't unmap memory %s\n", memh->name);
|
printf("Couldn't unmap memory %s\n", memh->name);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(malloc_debug_memset && memh->len)
|
if(malloc_debug_memset && memh->len)
|
||||||
memset(memh+1, 255, memh->len);
|
memset(memh+1, 255, memh->len);
|
||||||
free(memh);
|
free(memh);
|
||||||
|
|||||||
885
intern/smoke/intern/EIGENVALUE_HELPER.cpp
Normal file
885
intern/smoke/intern/EIGENVALUE_HELPER.cpp
Normal file
@@ -0,0 +1,885 @@
|
|||||||
|
|
||||||
|
#include "EIGENVALUE_HELPER.h"
|
||||||
|
|
||||||
|
|
||||||
|
void Eigentred2(sEigenvalue& eval) {
|
||||||
|
|
||||||
|
// This is derived from the Algol procedures tred2 by
|
||||||
|
// Bowdler, Martin, Reinsch, and Wilkinson, Handbook for
|
||||||
|
// Auto. Comp., Vol.ii-Linear Algebra, and the corresponding
|
||||||
|
// Fortran subroutine in EISPACK.
|
||||||
|
|
||||||
|
int n=eval.n;
|
||||||
|
|
||||||
|
for (int j = 0; j < n; j++) {
|
||||||
|
eval.d[j] = eval.V[n-1][j];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Householder reduction to tridiagonal form.
|
||||||
|
|
||||||
|
for (int i = n-1; i > 0; i--) {
|
||||||
|
|
||||||
|
// Scale to avoid under/overflow.
|
||||||
|
|
||||||
|
float scale = 0.0;
|
||||||
|
float h = 0.0;
|
||||||
|
for (int k = 0; k < i; k++) {
|
||||||
|
scale = scale + fabs(eval.d[k]);
|
||||||
|
}
|
||||||
|
if (scale == 0.0) {
|
||||||
|
eval.e[i] = eval.d[i-1];
|
||||||
|
for (int j = 0; j < i; j++) {
|
||||||
|
eval.d[j] = eval.V[i-1][j];
|
||||||
|
eval.V[i][j] = 0.0;
|
||||||
|
eval.V[j][i] = 0.0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// Generate Householder vector.
|
||||||
|
|
||||||
|
for (int k = 0; k < i; k++) {
|
||||||
|
eval.d[k] /= scale;
|
||||||
|
h += eval.d[k] * eval.d[k];
|
||||||
|
}
|
||||||
|
float f = eval.d[i-1];
|
||||||
|
float g = sqrt(h);
|
||||||
|
if (f > 0) {
|
||||||
|
g = -g;
|
||||||
|
}
|
||||||
|
eval.e[i] = scale * g;
|
||||||
|
h = h - f * g;
|
||||||
|
eval.d[i-1] = f - g;
|
||||||
|
for (int j = 0; j < i; j++) {
|
||||||
|
eval.e[j] = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply similarity transformation to remaining columns.
|
||||||
|
|
||||||
|
for (int j = 0; j < i; j++) {
|
||||||
|
f = eval.d[j];
|
||||||
|
eval.V[j][i] = f;
|
||||||
|
g = eval.e[j] + eval.V[j][j] * f;
|
||||||
|
for (int k = j+1; k <= i-1; k++) {
|
||||||
|
g += eval.V[k][j] * eval.d[k];
|
||||||
|
eval.e[k] += eval.V[k][j] * f;
|
||||||
|
}
|
||||||
|
eval.e[j] = g;
|
||||||
|
}
|
||||||
|
f = 0.0;
|
||||||
|
for (int j = 0; j < i; j++) {
|
||||||
|
eval.e[j] /= h;
|
||||||
|
f += eval.e[j] * eval.d[j];
|
||||||
|
}
|
||||||
|
float hh = f / (h + h);
|
||||||
|
for (int j = 0; j < i; j++) {
|
||||||
|
eval.e[j] -= hh * eval.d[j];
|
||||||
|
}
|
||||||
|
for (int j = 0; j < i; j++) {
|
||||||
|
f = eval.d[j];
|
||||||
|
g = eval.e[j];
|
||||||
|
for (int k = j; k <= i-1; k++) {
|
||||||
|
eval.V[k][j] -= (f * eval.e[k] + g * eval.d[k]);
|
||||||
|
}
|
||||||
|
eval.d[j] = eval.V[i-1][j];
|
||||||
|
eval.V[i][j] = 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
eval.d[i] = h;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Accumulate transformations.
|
||||||
|
|
||||||
|
for (int i = 0; i < n-1; i++) {
|
||||||
|
eval.V[n-1][i] = eval.V[i][i];
|
||||||
|
eval.V[i][i] = 1.0;
|
||||||
|
float h = eval.d[i+1];
|
||||||
|
if (h != 0.0) {
|
||||||
|
for (int k = 0; k <= i; k++) {
|
||||||
|
eval.d[k] = eval.V[k][i+1] / h;
|
||||||
|
}
|
||||||
|
for (int j = 0; j <= i; j++) {
|
||||||
|
float g = 0.0;
|
||||||
|
for (int k = 0; k <= i; k++) {
|
||||||
|
g += eval.V[k][i+1] * eval.V[k][j];
|
||||||
|
}
|
||||||
|
for (int k = 0; k <= i; k++) {
|
||||||
|
eval.V[k][j] -= g * eval.d[k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int k = 0; k <= i; k++) {
|
||||||
|
eval.V[k][i+1] = 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int j = 0; j < n; j++) {
|
||||||
|
eval.d[j] = eval.V[n-1][j];
|
||||||
|
eval.V[n-1][j] = 0.0;
|
||||||
|
}
|
||||||
|
eval.V[n-1][n-1] = 1.0;
|
||||||
|
eval.e[0] = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Eigencdiv(sEigenvalue& eval, float xr, float xi, float yr, float yi) {
|
||||||
|
float r,d;
|
||||||
|
if (fabs(yr) > fabs(yi)) {
|
||||||
|
r = yi/yr;
|
||||||
|
d = yr + r*yi;
|
||||||
|
eval.cdivr = (xr + r*xi)/d;
|
||||||
|
eval.cdivi = (xi - r*xr)/d;
|
||||||
|
} else {
|
||||||
|
r = yr/yi;
|
||||||
|
d = yi + r*yr;
|
||||||
|
eval.cdivr = (r*xr + xi)/d;
|
||||||
|
eval.cdivi = (r*xi - xr)/d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Eigentql2 (sEigenvalue& eval) {
|
||||||
|
|
||||||
|
// This is derived from the Algol procedures tql2, by
|
||||||
|
// Bowdler, Martin, Reinsch, and Wilkinson, Handbook for
|
||||||
|
// Auto. Comp., Vol.ii-Linear Algebra, and the corresponding
|
||||||
|
// Fortran subroutine in EISPACK.
|
||||||
|
|
||||||
|
int n=eval.n;
|
||||||
|
|
||||||
|
for (int i = 1; i < n; i++) {
|
||||||
|
eval.e[i-1] = eval.e[i];
|
||||||
|
}
|
||||||
|
eval.e[n-1] = 0.0;
|
||||||
|
|
||||||
|
float f = 0.0;
|
||||||
|
float tst1 = 0.0;
|
||||||
|
float eps = pow(2.0,-52.0);
|
||||||
|
for (int l = 0; l < n; l++) {
|
||||||
|
|
||||||
|
// Find small subdiagonal element
|
||||||
|
|
||||||
|
tst1 = max(tst1,fabs(eval.d[l]) + fabs(eval.e[l]));
|
||||||
|
int m = l;
|
||||||
|
|
||||||
|
// Original while-loop from Java code
|
||||||
|
while (m < n) {
|
||||||
|
if (fabs(eval.e[m]) <= eps*tst1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
m++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// If m == l, d[l] is an eigenvalue,
|
||||||
|
// otherwise, iterate.
|
||||||
|
|
||||||
|
if (m > l) {
|
||||||
|
int iter = 0;
|
||||||
|
do {
|
||||||
|
iter = iter + 1; // (Could check iteration count here.)
|
||||||
|
|
||||||
|
// Compute implicit shift
|
||||||
|
|
||||||
|
float g = eval.d[l];
|
||||||
|
float p = (eval.d[l+1] - g) / (2.0 * eval.e[l]);
|
||||||
|
float r = hypot(p,1.0);
|
||||||
|
if (p < 0) {
|
||||||
|
r = -r;
|
||||||
|
}
|
||||||
|
eval.d[l] = eval.e[l] / (p + r);
|
||||||
|
eval.d[l+1] = eval.e[l] * (p + r);
|
||||||
|
float dl1 = eval.d[l+1];
|
||||||
|
float h = g - eval.d[l];
|
||||||
|
for (int i = l+2; i < n; i++) {
|
||||||
|
eval.d[i] -= h;
|
||||||
|
}
|
||||||
|
f = f + h;
|
||||||
|
|
||||||
|
// Implicit QL transformation.
|
||||||
|
|
||||||
|
p = eval.d[m];
|
||||||
|
float c = 1.0;
|
||||||
|
float c2 = c;
|
||||||
|
float c3 = c;
|
||||||
|
float el1 = eval.e[l+1];
|
||||||
|
float s = 0.0;
|
||||||
|
float s2 = 0.0;
|
||||||
|
for (int i = m-1; i >= l; i--) {
|
||||||
|
c3 = c2;
|
||||||
|
c2 = c;
|
||||||
|
s2 = s;
|
||||||
|
g = c * eval.e[i];
|
||||||
|
h = c * p;
|
||||||
|
r = hypot(p,eval.e[i]);
|
||||||
|
eval.e[i+1] = s * r;
|
||||||
|
s = eval.e[i] / r;
|
||||||
|
c = p / r;
|
||||||
|
p = c * eval.d[i] - s * g;
|
||||||
|
eval.d[i+1] = h + s * (c * g + s * eval.d[i]);
|
||||||
|
|
||||||
|
// Accumulate transformation.
|
||||||
|
|
||||||
|
for (int k = 0; k < n; k++) {
|
||||||
|
h = eval.V[k][i+1];
|
||||||
|
eval.V[k][i+1] = s * eval.V[k][i] + c * h;
|
||||||
|
eval.V[k][i] = c * eval.V[k][i] - s * h;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p = -s * s2 * c3 * el1 * eval.e[l] / dl1;
|
||||||
|
eval.e[l] = s * p;
|
||||||
|
eval.d[l] = c * p;
|
||||||
|
|
||||||
|
// Check for convergence.
|
||||||
|
|
||||||
|
} while (fabs(eval.e[l]) > eps*tst1);
|
||||||
|
}
|
||||||
|
eval.d[l] = eval.d[l] + f;
|
||||||
|
eval.e[l] = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort eigenvalues and corresponding vectors.
|
||||||
|
|
||||||
|
for (int i = 0; i < n-1; i++) {
|
||||||
|
int k = i;
|
||||||
|
float p = eval.d[i];
|
||||||
|
for (int j = i+1; j < n; j++) {
|
||||||
|
if (eval.d[j] < p) {
|
||||||
|
k = j;
|
||||||
|
p = eval.d[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (k != i) {
|
||||||
|
eval.d[k] = eval.d[i];
|
||||||
|
eval.d[i] = p;
|
||||||
|
for (int j = 0; j < n; j++) {
|
||||||
|
p = eval.V[j][i];
|
||||||
|
eval.V[j][i] = eval.V[j][k];
|
||||||
|
eval.V[j][k] = p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Eigenorthes (sEigenvalue& eval) {
|
||||||
|
|
||||||
|
// This is derived from the Algol procedures orthes and ortran,
|
||||||
|
// by Martin and Wilkinson, Handbook for Auto. Comp.,
|
||||||
|
// Vol.ii-Linear Algebra, and the corresponding
|
||||||
|
// Fortran subroutines in EISPACK.
|
||||||
|
|
||||||
|
int n=eval.n;
|
||||||
|
|
||||||
|
int low = 0;
|
||||||
|
int high = n-1;
|
||||||
|
|
||||||
|
for (int m = low+1; m <= high-1; m++) {
|
||||||
|
|
||||||
|
// Scale column.
|
||||||
|
|
||||||
|
float scale = 0.0;
|
||||||
|
for (int i = m; i <= high; i++) {
|
||||||
|
scale = scale + fabs(eval.H[i][m-1]);
|
||||||
|
}
|
||||||
|
if (scale != 0.0) {
|
||||||
|
|
||||||
|
// Compute Householder transformation.
|
||||||
|
|
||||||
|
float h = 0.0;
|
||||||
|
for (int i = high; i >= m; i--) {
|
||||||
|
eval.ort[i] = eval.H[i][m-1]/scale;
|
||||||
|
h += eval.ort[i] * eval.ort[i];
|
||||||
|
}
|
||||||
|
float g = sqrt(h);
|
||||||
|
if (eval.ort[m] > 0) {
|
||||||
|
g = -g;
|
||||||
|
}
|
||||||
|
h = h - eval.ort[m] * g;
|
||||||
|
eval.ort[m] = eval.ort[m] - g;
|
||||||
|
|
||||||
|
// Apply Householder similarity transformation
|
||||||
|
// H = (I-u*u'/h)*H*(I-u*u')/h)
|
||||||
|
|
||||||
|
for (int j = m; j < n; j++) {
|
||||||
|
float f = 0.0;
|
||||||
|
for (int i = high; i >= m; i--) {
|
||||||
|
f += eval.ort[i]*eval.H[i][j];
|
||||||
|
}
|
||||||
|
f = f/h;
|
||||||
|
for (int i = m; i <= high; i++) {
|
||||||
|
eval.H[i][j] -= f*eval.ort[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i <= high; i++) {
|
||||||
|
float f = 0.0;
|
||||||
|
for (int j = high; j >= m; j--) {
|
||||||
|
f += eval.ort[j]*eval.H[i][j];
|
||||||
|
}
|
||||||
|
f = f/h;
|
||||||
|
for (int j = m; j <= high; j++) {
|
||||||
|
eval.H[i][j] -= f*eval.ort[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
eval.ort[m] = scale*eval.ort[m];
|
||||||
|
eval.H[m][m-1] = scale*g;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Accumulate transformations (Algol's ortran).
|
||||||
|
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
for (int j = 0; j < n; j++) {
|
||||||
|
eval.V[i][j] = (i == j ? 1.0 : 0.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int m = high-1; m >= low+1; m--) {
|
||||||
|
if (eval.H[m][m-1] != 0.0) {
|
||||||
|
for (int i = m+1; i <= high; i++) {
|
||||||
|
eval.ort[i] = eval.H[i][m-1];
|
||||||
|
}
|
||||||
|
for (int j = m; j <= high; j++) {
|
||||||
|
float g = 0.0;
|
||||||
|
for (int i = m; i <= high; i++) {
|
||||||
|
g += eval.ort[i] * eval.V[i][j];
|
||||||
|
}
|
||||||
|
// Double division avoids possible underflow
|
||||||
|
g = (g / eval.ort[m]) / eval.H[m][m-1];
|
||||||
|
for (int i = m; i <= high; i++) {
|
||||||
|
eval.V[i][j] += g * eval.ort[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Eigenhqr2 (sEigenvalue& eval) {
|
||||||
|
|
||||||
|
// This is derived from the Algol procedure hqr2,
|
||||||
|
// by Martin and Wilkinson, Handbook for Auto. Comp.,
|
||||||
|
// Vol.ii-Linear Algebra, and the corresponding
|
||||||
|
// Fortran subroutine in EISPACK.
|
||||||
|
|
||||||
|
// Initialize
|
||||||
|
|
||||||
|
int nn = eval.n;
|
||||||
|
int n = nn-1;
|
||||||
|
int low = 0;
|
||||||
|
int high = nn-1;
|
||||||
|
float eps = pow(2.0,-52.0);
|
||||||
|
float exshift = 0.0;
|
||||||
|
float p=0,q=0,r=0,s=0,z=0,t,w,x,y;
|
||||||
|
|
||||||
|
// Store roots isolated by balanc and compute matrix norm
|
||||||
|
|
||||||
|
float norm = 0.0;
|
||||||
|
for (int i = 0; i < nn; i++) {
|
||||||
|
if ((i < low) || (i > high)) {
|
||||||
|
eval.d[i] = eval.H[i][i];
|
||||||
|
eval.e[i] = 0.0;
|
||||||
|
}
|
||||||
|
for (int j = max(i-1,0); j < nn; j++) {
|
||||||
|
norm = norm + fabs(eval.H[i][j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Outer loop over eigenvalue index
|
||||||
|
|
||||||
|
int iter = 0;
|
||||||
|
int totIter = 0;
|
||||||
|
while (n >= low) {
|
||||||
|
|
||||||
|
// NT limit no. of iterations
|
||||||
|
totIter++;
|
||||||
|
if(totIter>100) {
|
||||||
|
//if(totIter>15) std::cout<<"!!!!iter ABORT !!!!!!! "<<totIter<<"\n";
|
||||||
|
// NT hack/fix, return large eigenvalues
|
||||||
|
for (int i = 0; i < nn; i++) {
|
||||||
|
eval.d[i] = 10000.;
|
||||||
|
eval.e[i] = 10000.;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look for single small sub-diagonal element
|
||||||
|
|
||||||
|
int l = n;
|
||||||
|
while (l > low) {
|
||||||
|
s = fabs(eval.H[l-1][l-1]) + fabs(eval.H[l][l]);
|
||||||
|
if (s == 0.0) {
|
||||||
|
s = norm;
|
||||||
|
}
|
||||||
|
if (fabs(eval.H[l][l-1]) < eps * s) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
l--;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for convergence
|
||||||
|
// One root found
|
||||||
|
|
||||||
|
if (l == n) {
|
||||||
|
eval.H[n][n] = eval.H[n][n] + exshift;
|
||||||
|
eval.d[n] = eval.H[n][n];
|
||||||
|
eval.e[n] = 0.0;
|
||||||
|
n--;
|
||||||
|
iter = 0;
|
||||||
|
|
||||||
|
// Two roots found
|
||||||
|
|
||||||
|
} else if (l == n-1) {
|
||||||
|
w = eval.H[n][n-1] * eval.H[n-1][n];
|
||||||
|
p = (eval.H[n-1][n-1] - eval.H[n][n]) / 2.0;
|
||||||
|
q = p * p + w;
|
||||||
|
z = sqrt(fabs(q));
|
||||||
|
eval.H[n][n] = eval.H[n][n] + exshift;
|
||||||
|
eval.H[n-1][n-1] = eval.H[n-1][n-1] + exshift;
|
||||||
|
x = eval.H[n][n];
|
||||||
|
|
||||||
|
// float pair
|
||||||
|
|
||||||
|
if (q >= 0) {
|
||||||
|
if (p >= 0) {
|
||||||
|
z = p + z;
|
||||||
|
} else {
|
||||||
|
z = p - z;
|
||||||
|
}
|
||||||
|
eval.d[n-1] = x + z;
|
||||||
|
eval.d[n] = eval.d[n-1];
|
||||||
|
if (z != 0.0) {
|
||||||
|
eval.d[n] = x - w / z;
|
||||||
|
}
|
||||||
|
eval.e[n-1] = 0.0;
|
||||||
|
eval.e[n] = 0.0;
|
||||||
|
x = eval.H[n][n-1];
|
||||||
|
s = fabs(x) + fabs(z);
|
||||||
|
p = x / s;
|
||||||
|
q = z / s;
|
||||||
|
r = sqrt(p * p+q * q);
|
||||||
|
p = p / r;
|
||||||
|
q = q / r;
|
||||||
|
|
||||||
|
// Row modification
|
||||||
|
|
||||||
|
for (int j = n-1; j < nn; j++) {
|
||||||
|
z = eval.H[n-1][j];
|
||||||
|
eval.H[n-1][j] = q * z + p * eval.H[n][j];
|
||||||
|
eval.H[n][j] = q * eval.H[n][j] - p * z;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Column modification
|
||||||
|
|
||||||
|
for (int i = 0; i <= n; i++) {
|
||||||
|
z = eval.H[i][n-1];
|
||||||
|
eval.H[i][n-1] = q * z + p * eval.H[i][n];
|
||||||
|
eval.H[i][n] = q * eval.H[i][n] - p * z;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Accumulate transformations
|
||||||
|
|
||||||
|
for (int i = low; i <= high; i++) {
|
||||||
|
z = eval.V[i][n-1];
|
||||||
|
eval.V[i][n-1] = q * z + p * eval.V[i][n];
|
||||||
|
eval.V[i][n] = q * eval.V[i][n] - p * z;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Complex pair
|
||||||
|
|
||||||
|
} else {
|
||||||
|
eval.d[n-1] = x + p;
|
||||||
|
eval.d[n] = x + p;
|
||||||
|
eval.e[n-1] = z;
|
||||||
|
eval.e[n] = -z;
|
||||||
|
}
|
||||||
|
n = n - 2;
|
||||||
|
iter = 0;
|
||||||
|
|
||||||
|
// No convergence yet
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// Form shift
|
||||||
|
|
||||||
|
x = eval.H[n][n];
|
||||||
|
y = 0.0;
|
||||||
|
w = 0.0;
|
||||||
|
if (l < n) {
|
||||||
|
y = eval.H[n-1][n-1];
|
||||||
|
w = eval.H[n][n-1] * eval.H[n-1][n];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wilkinson's original ad hoc shift
|
||||||
|
|
||||||
|
if (iter == 10) {
|
||||||
|
exshift += x;
|
||||||
|
for (int i = low; i <= n; i++) {
|
||||||
|
eval.H[i][i] -= x;
|
||||||
|
}
|
||||||
|
s = fabs(eval.H[n][n-1]) + fabs(eval.H[n-1][n-2]);
|
||||||
|
x = y = 0.75 * s;
|
||||||
|
w = -0.4375 * s * s;
|
||||||
|
}
|
||||||
|
|
||||||
|
// MATLAB's new ad hoc shift
|
||||||
|
|
||||||
|
if (iter == 30) {
|
||||||
|
s = (y - x) / 2.0;
|
||||||
|
s = s * s + w;
|
||||||
|
if (s > 0) {
|
||||||
|
s = sqrt(s);
|
||||||
|
if (y < x) {
|
||||||
|
s = -s;
|
||||||
|
}
|
||||||
|
s = x - w / ((y - x) / 2.0 + s);
|
||||||
|
for (int i = low; i <= n; i++) {
|
||||||
|
eval.H[i][i] -= s;
|
||||||
|
}
|
||||||
|
exshift += s;
|
||||||
|
x = y = w = 0.964;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
iter = iter + 1; // (Could check iteration count here.)
|
||||||
|
|
||||||
|
// Look for two consecutive small sub-diagonal elements
|
||||||
|
|
||||||
|
int m = n-2;
|
||||||
|
while (m >= l) {
|
||||||
|
z = eval.H[m][m];
|
||||||
|
r = x - z;
|
||||||
|
s = y - z;
|
||||||
|
p = (r * s - w) / eval.H[m+1][m] + eval.H[m][m+1];
|
||||||
|
q = eval.H[m+1][m+1] - z - r - s;
|
||||||
|
r = eval.H[m+2][m+1];
|
||||||
|
s = fabs(p) + fabs(q) + fabs(r);
|
||||||
|
p = p / s;
|
||||||
|
q = q / s;
|
||||||
|
r = r / s;
|
||||||
|
if (m == l) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (fabs(eval.H[m][m-1]) * (fabs(q) + fabs(r)) <
|
||||||
|
eps * (fabs(p) * (fabs(eval.H[m-1][m-1]) + fabs(z) +
|
||||||
|
fabs(eval.H[m+1][m+1])))) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
m--;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = m+2; i <= n; i++) {
|
||||||
|
eval.H[i][i-2] = 0.0;
|
||||||
|
if (i > m+2) {
|
||||||
|
eval.H[i][i-3] = 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Double QR step involving rows l:n and columns m:n
|
||||||
|
|
||||||
|
for (int k = m; k <= n-1; k++) {
|
||||||
|
int notlast = (k != n-1);
|
||||||
|
if (k != m) {
|
||||||
|
p = eval.H[k][k-1];
|
||||||
|
q = eval.H[k+1][k-1];
|
||||||
|
r = (notlast ? eval.H[k+2][k-1] : 0.0);
|
||||||
|
x = fabs(p) + fabs(q) + fabs(r);
|
||||||
|
if (x != 0.0) {
|
||||||
|
p = p / x;
|
||||||
|
q = q / x;
|
||||||
|
r = r / x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (x == 0.0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
s = sqrt(p * p + q * q + r * r);
|
||||||
|
if (p < 0) {
|
||||||
|
s = -s;
|
||||||
|
}
|
||||||
|
if (s != 0) {
|
||||||
|
if (k != m) {
|
||||||
|
eval.H[k][k-1] = -s * x;
|
||||||
|
} else if (l != m) {
|
||||||
|
eval.H[k][k-1] = -eval.H[k][k-1];
|
||||||
|
}
|
||||||
|
p = p + s;
|
||||||
|
x = p / s;
|
||||||
|
y = q / s;
|
||||||
|
z = r / s;
|
||||||
|
q = q / p;
|
||||||
|
r = r / p;
|
||||||
|
|
||||||
|
// Row modification
|
||||||
|
|
||||||
|
for (int j = k; j < nn; j++) {
|
||||||
|
p = eval.H[k][j] + q * eval.H[k+1][j];
|
||||||
|
if (notlast) {
|
||||||
|
p = p + r * eval.H[k+2][j];
|
||||||
|
eval.H[k+2][j] = eval.H[k+2][j] - p * z;
|
||||||
|
}
|
||||||
|
eval.H[k][j] = eval.H[k][j] - p * x;
|
||||||
|
eval.H[k+1][j] = eval.H[k+1][j] - p * y;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Column modification
|
||||||
|
|
||||||
|
for (int i = 0; i <= min(n,k+3); i++) {
|
||||||
|
p = x * eval.H[i][k] + y * eval.H[i][k+1];
|
||||||
|
if (notlast) {
|
||||||
|
p = p + z * eval.H[i][k+2];
|
||||||
|
eval.H[i][k+2] = eval.H[i][k+2] - p * r;
|
||||||
|
}
|
||||||
|
eval.H[i][k] = eval.H[i][k] - p;
|
||||||
|
eval.H[i][k+1] = eval.H[i][k+1] - p * q;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Accumulate transformations
|
||||||
|
|
||||||
|
for (int i = low; i <= high; i++) {
|
||||||
|
p = x * eval.V[i][k] + y * eval.V[i][k+1];
|
||||||
|
if (notlast) {
|
||||||
|
p = p + z * eval.V[i][k+2];
|
||||||
|
eval.V[i][k+2] = eval.V[i][k+2] - p * r;
|
||||||
|
}
|
||||||
|
eval.V[i][k] = eval.V[i][k] - p;
|
||||||
|
eval.V[i][k+1] = eval.V[i][k+1] - p * q;
|
||||||
|
}
|
||||||
|
} // (s != 0)
|
||||||
|
} // k loop
|
||||||
|
} // check convergence
|
||||||
|
} // while (n >= low)
|
||||||
|
//if(totIter>15) std::cout<<"!!!!iter "<<totIter<<"\n";
|
||||||
|
|
||||||
|
// Backsubstitute to find vectors of upper triangular form
|
||||||
|
|
||||||
|
if (norm == 0.0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (n = nn-1; n >= 0; n--) {
|
||||||
|
p = eval.d[n];
|
||||||
|
q = eval.e[n];
|
||||||
|
|
||||||
|
// float vector
|
||||||
|
|
||||||
|
if (q == 0) {
|
||||||
|
int l = n;
|
||||||
|
eval.H[n][n] = 1.0;
|
||||||
|
for (int i = n-1; i >= 0; i--) {
|
||||||
|
w = eval.H[i][i] - p;
|
||||||
|
r = 0.0;
|
||||||
|
for (int j = l; j <= n; j++) {
|
||||||
|
r = r + eval.H[i][j] * eval.H[j][n];
|
||||||
|
}
|
||||||
|
if (eval.e[i] < 0.0) {
|
||||||
|
z = w;
|
||||||
|
s = r;
|
||||||
|
} else {
|
||||||
|
l = i;
|
||||||
|
if (eval.e[i] == 0.0) {
|
||||||
|
if (w != 0.0) {
|
||||||
|
eval.H[i][n] = -r / w;
|
||||||
|
} else {
|
||||||
|
eval.H[i][n] = -r / (eps * norm);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Solve real equations
|
||||||
|
|
||||||
|
} else {
|
||||||
|
x = eval.H[i][i+1];
|
||||||
|
y = eval.H[i+1][i];
|
||||||
|
q = (eval.d[i] - p) * (eval.d[i] - p) + eval.e[i] * eval.e[i];
|
||||||
|
t = (x * s - z * r) / q;
|
||||||
|
eval.H[i][n] = t;
|
||||||
|
if (fabs(x) > fabs(z)) {
|
||||||
|
eval.H[i+1][n] = (-r - w * t) / x;
|
||||||
|
} else {
|
||||||
|
eval.H[i+1][n] = (-s - y * t) / z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Overflow control
|
||||||
|
|
||||||
|
t = fabs(eval.H[i][n]);
|
||||||
|
if ((eps * t) * t > 1) {
|
||||||
|
for (int j = i; j <= n; j++) {
|
||||||
|
eval.H[j][n] = eval.H[j][n] / t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Complex vector
|
||||||
|
|
||||||
|
} else if (q < 0) {
|
||||||
|
int l = n-1;
|
||||||
|
|
||||||
|
// Last vector component imaginary so matrix is triangular
|
||||||
|
|
||||||
|
if (fabs(eval.H[n][n-1]) > fabs(eval.H[n-1][n])) {
|
||||||
|
eval.H[n-1][n-1] = q / eval.H[n][n-1];
|
||||||
|
eval.H[n-1][n] = -(eval.H[n][n] - p) / eval.H[n][n-1];
|
||||||
|
} else {
|
||||||
|
Eigencdiv(eval, 0.0,-eval.H[n-1][n],eval.H[n-1][n-1]-p,q);
|
||||||
|
eval.H[n-1][n-1] = eval.cdivr;
|
||||||
|
eval.H[n-1][n] = eval.cdivi;
|
||||||
|
}
|
||||||
|
eval.H[n][n-1] = 0.0;
|
||||||
|
eval.H[n][n] = 1.0;
|
||||||
|
for (int i = n-2; i >= 0; i--) {
|
||||||
|
float ra,sa,vr,vi;
|
||||||
|
ra = 0.0;
|
||||||
|
sa = 0.0;
|
||||||
|
for (int j = l; j <= n; j++) {
|
||||||
|
ra = ra + eval.H[i][j] * eval.H[j][n-1];
|
||||||
|
sa = sa + eval.H[i][j] * eval.H[j][n];
|
||||||
|
}
|
||||||
|
w = eval.H[i][i] - p;
|
||||||
|
|
||||||
|
if (eval.e[i] < 0.0) {
|
||||||
|
z = w;
|
||||||
|
r = ra;
|
||||||
|
s = sa;
|
||||||
|
} else {
|
||||||
|
l = i;
|
||||||
|
if (eval.e[i] == 0) {
|
||||||
|
Eigencdiv(eval,-ra,-sa,w,q);
|
||||||
|
eval.H[i][n-1] = eval.cdivr;
|
||||||
|
eval.H[i][n] = eval.cdivi;
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// Solve complex equations
|
||||||
|
|
||||||
|
x = eval.H[i][i+1];
|
||||||
|
y = eval.H[i+1][i];
|
||||||
|
vr = (eval.d[i] - p) * (eval.d[i] - p) + eval.e[i] * eval.e[i] - q * q;
|
||||||
|
vi = (eval.d[i] - p) * 2.0 * q;
|
||||||
|
if ((vr == 0.0) && (vi == 0.0)) {
|
||||||
|
vr = eps * norm * (fabs(w) + fabs(q) +
|
||||||
|
fabs(x) + fabs(y) + fabs(z));
|
||||||
|
}
|
||||||
|
Eigencdiv(eval, x*r-z*ra+q*sa,x*s-z*sa-q*ra,vr,vi);
|
||||||
|
eval.H[i][n-1] = eval.cdivr;
|
||||||
|
eval.H[i][n] = eval.cdivi;
|
||||||
|
if (fabs(x) > (fabs(z) + fabs(q))) {
|
||||||
|
eval.H[i+1][n-1] = (-ra - w * eval.H[i][n-1] + q * eval.H[i][n]) / x;
|
||||||
|
eval.H[i+1][n] = (-sa - w * eval.H[i][n] - q * eval.H[i][n-1]) / x;
|
||||||
|
} else {
|
||||||
|
Eigencdiv(eval, -r-y*eval.H[i][n-1],-s-y*eval.H[i][n],z,q);
|
||||||
|
eval.H[i+1][n-1] = eval.cdivr;
|
||||||
|
eval.H[i+1][n] = eval.cdivi;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Overflow control
|
||||||
|
|
||||||
|
t = max(fabs(eval.H[i][n-1]),fabs(eval.H[i][n]));
|
||||||
|
if ((eps * t) * t > 1) {
|
||||||
|
for (int j = i; j <= n; j++) {
|
||||||
|
eval.H[j][n-1] = eval.H[j][n-1] / t;
|
||||||
|
eval.H[j][n] = eval.H[j][n] / t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Vectors of isolated roots
|
||||||
|
|
||||||
|
for (int i = 0; i < nn; i++) {
|
||||||
|
if (i < low || i > high) {
|
||||||
|
for (int j = i; j < nn; j++) {
|
||||||
|
eval.V[i][j] = eval.H[i][j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Back transformation to get eigenvectors of original matrix
|
||||||
|
|
||||||
|
for (int j = nn-1; j >= low; j--) {
|
||||||
|
for (int i = low; i <= high; i++) {
|
||||||
|
z = 0.0;
|
||||||
|
for (int k = low; k <= min(j,high); k++) {
|
||||||
|
z = z + eval.V[i][k] * eval.H[k][j];
|
||||||
|
}
|
||||||
|
eval.V[i][j] = z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int computeEigenvalues3x3(
|
||||||
|
float dout[3],
|
||||||
|
float a[3][3])
|
||||||
|
{
|
||||||
|
/*TNT::Array2D<float> A = TNT::Array2D<float>(3,3, &a[0][0]);
|
||||||
|
TNT::Array1D<float> eig = TNT::Array1D<float>(3);
|
||||||
|
TNT::Array1D<float> eigImag = TNT::Array1D<float>(3);
|
||||||
|
JAMA::Eigenvalue<float> jeig = JAMA::Eigenvalue<float>(A);*/
|
||||||
|
|
||||||
|
sEigenvalue jeig;
|
||||||
|
|
||||||
|
// Compute the values
|
||||||
|
{
|
||||||
|
jeig.n = 3;
|
||||||
|
int n=3;
|
||||||
|
//V = Array2D<float>(n,n);
|
||||||
|
//d = Array1D<float>(n);
|
||||||
|
//e = Array1D<float>(n);
|
||||||
|
for (int y=0; y<3; y++)
|
||||||
|
{
|
||||||
|
jeig.d[y]=0.0f;
|
||||||
|
jeig.e[y]=0.0f;
|
||||||
|
for (int t=0; t<3; t++) jeig.V[y][t]=0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
jeig.issymmetric = 1;
|
||||||
|
for (int j = 0; (j < 3) && jeig.issymmetric; j++) {
|
||||||
|
for (int i = 0; (i < 3) && jeig.issymmetric; i++) {
|
||||||
|
jeig.issymmetric = (a[i][j] == a[j][i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (jeig.issymmetric) {
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
for (int j = 0; j < 3; j++) {
|
||||||
|
jeig.V[i][j] = a[i][j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tridiagonalize.
|
||||||
|
Eigentred2(jeig);
|
||||||
|
|
||||||
|
// Diagonalize.
|
||||||
|
Eigentql2(jeig);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
//H = TNT::Array2D<float>(n,n);
|
||||||
|
for (int y=0; y<3; y++)
|
||||||
|
{
|
||||||
|
jeig.ort[y]=0.0f;
|
||||||
|
for (int t=0; t<3; t++) jeig.H[y][t]=0.0f;
|
||||||
|
}
|
||||||
|
//ort = TNT::Array1D<float>(n);
|
||||||
|
|
||||||
|
for (int j = 0; j < n; j++) {
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
jeig.H[i][j] = a[i][j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reduce to Hessenberg form.
|
||||||
|
Eigenorthes(jeig);
|
||||||
|
|
||||||
|
// Reduce Hessenberg to real Schur form.
|
||||||
|
Eigenhqr2(jeig);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//jeig.getfloatEigenvalues(eig);
|
||||||
|
|
||||||
|
// complex ones
|
||||||
|
//jeig.getImagEigenvalues(eigImag);
|
||||||
|
dout[0] = sqrt(jeig.d[0]*jeig.d[0] + jeig.e[0]*jeig.e[0]);
|
||||||
|
dout[1] = sqrt(jeig.d[1]*jeig.d[1] + jeig.e[1]*jeig.e[1]);
|
||||||
|
dout[2] = sqrt(jeig.d[2]*jeig.d[2] + jeig.e[2]*jeig.e[2]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -15,33 +15,60 @@
|
|||||||
// along with Wavelet Turbulence. If not, see <http://www.gnu.org/licenses/>.
|
// along with Wavelet Turbulence. If not, see <http://www.gnu.org/licenses/>.
|
||||||
//
|
//
|
||||||
// Copyright 2008 Theodore Kim and Nils Thuerey
|
// Copyright 2008 Theodore Kim and Nils Thuerey
|
||||||
//
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// Modified to not require TNT matrix library anymore. It was very slow
|
||||||
|
// when being run in parallel. Required TNT JAMA::Eigenvalue libraries were
|
||||||
|
// converted into independent functions.
|
||||||
|
// - MiikaH
|
||||||
|
//
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// Helper function, compute eigenvalues of 3x3 matrix
|
// Helper function, compute eigenvalues of 3x3 matrix
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include "tnt/jama_eig.h"
|
#ifndef EIGENVAL_HELPER_H
|
||||||
|
#define EIGENVAL_HELPER_H
|
||||||
|
|
||||||
|
//#include "tnt/jama_eig.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// eigenvalues of 3x3 non-symmetric matrix
|
// eigenvalues of 3x3 non-symmetric matrix
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
int inline computeEigenvalues3x3(
|
|
||||||
float dout[3],
|
|
||||||
float a[3][3])
|
struct sEigenvalue
|
||||||
{
|
{
|
||||||
TNT::Array2D<float> A = TNT::Array2D<float>(3,3, &a[0][0]);
|
int n;
|
||||||
TNT::Array1D<float> eig = TNT::Array1D<float>(3);
|
int issymmetric;
|
||||||
TNT::Array1D<float> eigImag = TNT::Array1D<float>(3);
|
float d[3]; /* real part */
|
||||||
JAMA::Eigenvalue<float> jeig = JAMA::Eigenvalue<float>(A);
|
float e[3]; /* img part */
|
||||||
jeig.getRealEigenvalues(eig);
|
float V[3][3]; /* Eigenvectors */
|
||||||
|
|
||||||
// complex ones
|
float H[3][3];
|
||||||
jeig.getImagEigenvalues(eigImag);
|
|
||||||
dout[0] = sqrt(eig[0]*eig[0] + eigImag[0]*eigImag[0]);
|
|
||||||
dout[1] = sqrt(eig[1]*eig[1] + eigImag[1]*eigImag[1]);
|
|
||||||
dout[2] = sqrt(eig[2]*eig[2] + eigImag[2]*eigImag[2]);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#undef rfabs
|
float ort[3];
|
||||||
#undef ROT
|
|
||||||
|
float cdivr;
|
||||||
|
float cdivi;
|
||||||
|
};
|
||||||
|
|
||||||
|
void Eigentred2(sEigenvalue& eval);
|
||||||
|
|
||||||
|
void Eigencdiv(sEigenvalue& eval, float xr, float xi, float yr, float yi);
|
||||||
|
|
||||||
|
void Eigentql2 (sEigenvalue& eval);
|
||||||
|
|
||||||
|
void Eigenorthes (sEigenvalue& eval);
|
||||||
|
|
||||||
|
void Eigenhqr2 (sEigenvalue& eval);
|
||||||
|
|
||||||
|
int computeEigenvalues3x3(float dout[3], float a[3][3]);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -19,6 +19,11 @@
|
|||||||
// FLUID_3D.cpp: implementation of the FLUID_3D class.
|
// FLUID_3D.cpp: implementation of the FLUID_3D class.
|
||||||
//
|
//
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// Heavy parallel optimization done. Many of the old functions now
|
||||||
|
// take begin and end parameters and process only specified part of the data.
|
||||||
|
// Some functions were divided into multiple ones.
|
||||||
|
// - MiikaH
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include "FLUID_3D.h"
|
#include "FLUID_3D.h"
|
||||||
#include "IMAGE.h"
|
#include "IMAGE.h"
|
||||||
@@ -26,6 +31,10 @@
|
|||||||
#include "SPHERE.h"
|
#include "SPHERE.h"
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
|
|
||||||
|
#if PARALLEL==1
|
||||||
|
#include <omp.h>
|
||||||
|
#endif // PARALLEL
|
||||||
|
|
||||||
// boundary conditions of the fluid domain
|
// boundary conditions of the fluid domain
|
||||||
#define DOMAIN_BC_FRONT 0 // z
|
#define DOMAIN_BC_FRONT 0 // z
|
||||||
#define DOMAIN_BC_TOP 1 // y
|
#define DOMAIN_BC_TOP 1 // y
|
||||||
@@ -90,6 +99,13 @@ FLUID_3D::FLUID_3D(int *res, float *p0, float dt) :
|
|||||||
_heatOld = new float[_totalCells];
|
_heatOld = new float[_totalCells];
|
||||||
_obstacles = new unsigned char[_totalCells]; // set 0 at end of step
|
_obstacles = new unsigned char[_totalCells]; // set 0 at end of step
|
||||||
|
|
||||||
|
// For threaded version:
|
||||||
|
_xVelocityTemp = new float[_totalCells];
|
||||||
|
_yVelocityTemp = new float[_totalCells];
|
||||||
|
_zVelocityTemp = new float[_totalCells];
|
||||||
|
_densityTemp = new float[_totalCells];
|
||||||
|
_heatTemp = new float[_totalCells];
|
||||||
|
|
||||||
// DG TODO: check if alloc went fine
|
// DG TODO: check if alloc went fine
|
||||||
|
|
||||||
for (int x = 0; x < _totalCells; x++)
|
for (int x = 0; x < _totalCells; x++)
|
||||||
@@ -167,6 +183,12 @@ FLUID_3D::~FLUID_3D()
|
|||||||
if (_obstacles) delete[] _obstacles;
|
if (_obstacles) delete[] _obstacles;
|
||||||
// if (_wTurbulence) delete _wTurbulence;
|
// if (_wTurbulence) delete _wTurbulence;
|
||||||
|
|
||||||
|
if (_xVelocityTemp) delete[] _xVelocityTemp;
|
||||||
|
if (_yVelocityTemp) delete[] _yVelocityTemp;
|
||||||
|
if (_zVelocityTemp) delete[] _zVelocityTemp;
|
||||||
|
if (_densityTemp) delete[] _densityTemp;
|
||||||
|
if (_heatTemp) delete[] _heatTemp;
|
||||||
|
|
||||||
// printf("deleted fluid\n");
|
// printf("deleted fluid\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -182,108 +204,306 @@ void FLUID_3D::initBlenderRNA(float *alpha, float *beta)
|
|||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
void FLUID_3D::step()
|
void FLUID_3D::step()
|
||||||
{
|
{
|
||||||
// addSmokeTestCase(_density, _res);
|
|
||||||
// addSmokeTestCase(_heat, _res);
|
|
||||||
|
|
||||||
wipeBoundaries();
|
int threadval = 1;
|
||||||
|
#if PARALLEL==1
|
||||||
|
threadval = omp_get_max_threads();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int stepParts = 1;
|
||||||
|
float partSize = _zRes;
|
||||||
|
|
||||||
|
#if PARALLEL==1
|
||||||
|
stepParts = threadval*2; // Dividing parallelized sections into numOfThreads * 2 sections
|
||||||
|
partSize = (float)_zRes/stepParts; // Size of one part;
|
||||||
|
|
||||||
|
if (partSize < 4) {stepParts = threadval; // If the slice gets too low (might actually slow things down, change it to larger
|
||||||
|
partSize = (float)_zRes/stepParts;}
|
||||||
|
if (partSize < 4) {stepParts = (int)(ceil((float)_zRes/4.0f)); // If it's still too low (only possible on future systems with +24 cores), change it to 4
|
||||||
|
partSize = (float)_zRes/stepParts;}
|
||||||
|
#else
|
||||||
|
int zBegin=0;
|
||||||
|
int zEnd=_zRes;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if PARALLEL==1
|
||||||
|
#pragma omp parallel
|
||||||
|
{
|
||||||
|
#pragma omp for schedule(static,1)
|
||||||
|
for (int i=0; i<stepParts; i++)
|
||||||
|
{
|
||||||
|
int zBegin = (int)((float)i*partSize + 0.5f);
|
||||||
|
int zEnd = (int)((float)(i+1)*partSize + 0.5f);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
wipeBoundariesSL(zBegin, zEnd);
|
||||||
|
addVorticity(zBegin, zEnd);
|
||||||
|
addBuoyancy(_heat, _density, zBegin, zEnd);
|
||||||
|
addForce(zBegin, zEnd);
|
||||||
|
|
||||||
|
#if PARALLEL==1
|
||||||
|
} // end of parallel
|
||||||
|
#pragma omp barrier
|
||||||
|
|
||||||
|
#pragma omp single
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
SWAP_POINTERS(_xVelocity, _xVelocityTemp);
|
||||||
|
SWAP_POINTERS(_yVelocity, _yVelocityTemp);
|
||||||
|
SWAP_POINTERS(_zVelocity, _zVelocityTemp);
|
||||||
|
#if PARALLEL==1
|
||||||
|
} // end of single
|
||||||
|
|
||||||
|
#pragma omp barrier
|
||||||
|
|
||||||
|
#pragma omp for
|
||||||
|
for (int i=0; i<2; i++)
|
||||||
|
{
|
||||||
|
if (i==0)
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
project();
|
||||||
|
#if PARALLEL==1
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
diffuseHeat();
|
||||||
|
#if PARALLEL==1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma omp barrier
|
||||||
|
|
||||||
|
#pragma omp single
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
SWAP_POINTERS(_xVelocity, _xVelocityOld);
|
||||||
|
SWAP_POINTERS(_yVelocity, _yVelocityOld);
|
||||||
|
SWAP_POINTERS(_zVelocity, _zVelocityOld);
|
||||||
|
SWAP_POINTERS(_density, _densityOld);
|
||||||
|
SWAP_POINTERS(_heat, _heatOld);
|
||||||
|
|
||||||
|
advectMacCormackBegin(0, _zRes);
|
||||||
|
|
||||||
|
#if PARALLEL==1
|
||||||
|
} // end of single
|
||||||
|
|
||||||
|
#pragma omp barrier
|
||||||
|
|
||||||
|
|
||||||
|
#pragma omp for schedule(static,1)
|
||||||
|
for (int i=0; i<stepParts; i++)
|
||||||
|
{
|
||||||
|
|
||||||
|
int zBegin = (int)((float)i*partSize + 0.5f);
|
||||||
|
int zEnd = (int)((float)(i+1)*partSize + 0.5f);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
advectMacCormackEnd1(zBegin, zEnd);
|
||||||
|
|
||||||
|
#if PARALLEL==1
|
||||||
|
} // end of parallel
|
||||||
|
|
||||||
|
#pragma omp barrier
|
||||||
|
|
||||||
|
#pragma omp for schedule(static,1)
|
||||||
|
for (int i=0; i<stepParts; i++)
|
||||||
|
{
|
||||||
|
|
||||||
|
int zBegin = (int)((float)i*partSize + 0.5f);
|
||||||
|
int zEnd = (int)((float)(i+1)*partSize + 0.5f);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
advectMacCormackEnd2(zBegin, zEnd);
|
||||||
|
|
||||||
|
artificialDampingSL(zBegin, zEnd);
|
||||||
|
|
||||||
|
// Using forces as temp arrays
|
||||||
|
|
||||||
|
#if PARALLEL==1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
for (int i=1; i<stepParts; i++)
|
||||||
|
{
|
||||||
|
int zPos=(int)((float)i*partSize + 0.5f);
|
||||||
|
|
||||||
|
artificialDampingExactSL(zPos);
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SWAP_POINTERS(_xVelocity, _xForce);
|
||||||
|
SWAP_POINTERS(_yVelocity, _yForce);
|
||||||
|
SWAP_POINTERS(_zVelocity, _zForce);
|
||||||
|
|
||||||
|
|
||||||
// run the solvers
|
|
||||||
addVorticity();
|
|
||||||
addBuoyancy(_heat, _density);
|
|
||||||
addForce();
|
|
||||||
project();
|
|
||||||
diffuseHeat();
|
|
||||||
|
|
||||||
// advect everything
|
|
||||||
advectMacCormack();
|
|
||||||
|
|
||||||
// if(_wTurbulence) {
|
|
||||||
// _wTurbulence->stepTurbulenceFull(_dt/_dx,
|
|
||||||
// _xVelocity, _yVelocity, _zVelocity, _obstacles);
|
|
||||||
// _wTurbulence->stepTurbulenceReadable(_dt/_dx,
|
|
||||||
// _xVelocity, _yVelocity, _zVelocity, _obstacles);
|
|
||||||
// }
|
|
||||||
/*
|
|
||||||
// no file output
|
|
||||||
float *src = _density;
|
|
||||||
string prefix = string("./original.preview/density_fullxy_");
|
|
||||||
writeImageSliceXY(src,_res, _res[2]/2, prefix, _totalSteps);
|
|
||||||
*/
|
|
||||||
// artificial damping -- this is necessary because we use a
|
|
||||||
// collated grid, and at very coarse grid resolutions, banding
|
|
||||||
// artifacts can occur
|
|
||||||
artificialDamping(_xVelocity);
|
|
||||||
artificialDamping(_yVelocity);
|
|
||||||
artificialDamping(_zVelocity);
|
|
||||||
/*
|
|
||||||
// no file output
|
|
||||||
string pbrtPrefix = string("./pbrt/density_small_");
|
|
||||||
IMAGE::dumpPBRT(_totalSteps, pbrtPrefix, _density, _res[0],_res[1],_res[2]);
|
|
||||||
*/
|
|
||||||
_totalTime += _dt;
|
_totalTime += _dt;
|
||||||
_totalSteps++;
|
_totalSteps++;
|
||||||
|
|
||||||
// todo xxx dg: only clear obstacles, not boundaries
|
|
||||||
// memset(_obstacles, 0, sizeof(unsigned char)*_xRes*_yRes*_zRes);
|
|
||||||
|
|
||||||
// wipe forces
|
|
||||||
// for external forces we can't do it at the beginning of this function but at the end
|
|
||||||
for (int i = 0; i < _totalCells; i++)
|
for (int i = 0; i < _totalCells; i++)
|
||||||
{
|
{
|
||||||
_xForce[i] = _yForce[i] = _zForce[i] = 0.0f;
|
_xForce[i] = _yForce[i] = _zForce[i] = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// helper function to dampen co-located grid artifacts of given arrays in intervals
|
// helper function to dampen co-located grid artifacts of given arrays in intervals
|
||||||
// (only needed for velocity, strength (w) depends on testcase...
|
// (only needed for velocity, strength (w) depends on testcase...
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
void FLUID_3D::artificialDamping(float* field) {
|
|
||||||
|
|
||||||
|
void FLUID_3D::artificialDampingSL(int zBegin, int zEnd) {
|
||||||
const float w = 0.9;
|
const float w = 0.9;
|
||||||
|
|
||||||
|
memmove(_xForce+(_slabSize*zBegin), _xVelocityTemp+(_slabSize*zBegin), sizeof(float)*_slabSize*(zEnd-zBegin));
|
||||||
|
memmove(_yForce+(_slabSize*zBegin), _yVelocityTemp+(_slabSize*zBegin), sizeof(float)*_slabSize*(zEnd-zBegin));
|
||||||
|
memmove(_zForce+(_slabSize*zBegin), _zVelocityTemp+(_slabSize*zBegin), sizeof(float)*_slabSize*(zEnd-zBegin));
|
||||||
|
|
||||||
|
|
||||||
if(_totalSteps % 4 == 1) {
|
if(_totalSteps % 4 == 1) {
|
||||||
for (int z = 1; z < _res[2]-1; z++)
|
for (int z = zBegin+1; z < zEnd-1; z++)
|
||||||
for (int y = 1; y < _res[1]-1; y++)
|
for (int y = 1; y < _res[1]-1; y++)
|
||||||
for (int x = 1+(y+z)%2; x < _res[0]-1; x+=2) {
|
for (int x = 1+(y+z)%2; x < _res[0]-1; x+=2) {
|
||||||
const int index = x + y*_res[0] + z * _slabSize;
|
const int index = x + y*_res[0] + z * _slabSize;
|
||||||
field[index] = (1-w)*field[index] + 1./6. * w*(
|
_xForce[index] = (1-w)*_xVelocityTemp[index] + 1./6. * w*(
|
||||||
field[index+1] + field[index-1] +
|
_xVelocityTemp[index+1] + _xVelocityTemp[index-1] +
|
||||||
field[index+_res[0]] + field[index-_res[0]] +
|
_xVelocityTemp[index+_res[0]] + _xVelocityTemp[index-_res[0]] +
|
||||||
field[index+_slabSize] + field[index-_slabSize] );
|
_xVelocityTemp[index+_slabSize] + _xVelocityTemp[index-_slabSize] );
|
||||||
|
|
||||||
|
_yForce[index] = (1-w)*_yVelocityTemp[index] + 1./6. * w*(
|
||||||
|
_yVelocityTemp[index+1] + _yVelocityTemp[index-1] +
|
||||||
|
_yVelocityTemp[index+_res[0]] + _yVelocityTemp[index-_res[0]] +
|
||||||
|
_yVelocityTemp[index+_slabSize] + _yVelocityTemp[index-_slabSize] );
|
||||||
|
|
||||||
|
_zForce[index] = (1-w)*_zVelocityTemp[index] + 1./6. * w*(
|
||||||
|
_zVelocityTemp[index+1] + _zVelocityTemp[index-1] +
|
||||||
|
_zVelocityTemp[index+_res[0]] + _zVelocityTemp[index-_res[0]] +
|
||||||
|
_zVelocityTemp[index+_slabSize] + _zVelocityTemp[index-_slabSize] );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_totalSteps % 4 == 3) {
|
if(_totalSteps % 4 == 3) {
|
||||||
for (int z = 1; z < _res[2]-1; z++)
|
for (int z = zBegin+1; z < zEnd-1; z++)
|
||||||
for (int y = 1; y < _res[1]-1; y++)
|
for (int y = 1; y < _res[1]-1; y++)
|
||||||
for (int x = 1+(y+z+1)%2; x < _res[0]-1; x+=2) {
|
for (int x = 1+(y+z+1)%2; x < _res[0]-1; x+=2) {
|
||||||
const int index = x + y*_res[0] + z * _slabSize;
|
const int index = x + y*_res[0] + z * _slabSize;
|
||||||
field[index] = (1-w)*field[index] + 1./6. * w*(
|
_xForce[index] = (1-w)*_xVelocityTemp[index] + 1./6. * w*(
|
||||||
field[index+1] + field[index-1] +
|
_xVelocityTemp[index+1] + _xVelocityTemp[index-1] +
|
||||||
field[index+_res[0]] + field[index-_res[0]] +
|
_xVelocityTemp[index+_res[0]] + _xVelocityTemp[index-_res[0]] +
|
||||||
field[index+_slabSize] + field[index-_slabSize] );
|
_xVelocityTemp[index+_slabSize] + _xVelocityTemp[index-_slabSize] );
|
||||||
|
|
||||||
|
_yForce[index] = (1-w)*_yVelocityTemp[index] + 1./6. * w*(
|
||||||
|
_yVelocityTemp[index+1] + _yVelocityTemp[index-1] +
|
||||||
|
_yVelocityTemp[index+_res[0]] + _yVelocityTemp[index-_res[0]] +
|
||||||
|
_yVelocityTemp[index+_slabSize] + _yVelocityTemp[index-_slabSize] );
|
||||||
|
|
||||||
|
_zForce[index] = (1-w)*_zVelocityTemp[index] + 1./6. * w*(
|
||||||
|
_zVelocityTemp[index+1] + _zVelocityTemp[index-1] +
|
||||||
|
_zVelocityTemp[index+_res[0]] + _zVelocityTemp[index-_res[0]] +
|
||||||
|
_zVelocityTemp[index+_slabSize] + _zVelocityTemp[index-_slabSize] );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void FLUID_3D::artificialDampingExactSL(int pos) {
|
||||||
|
const float w = 0.9;
|
||||||
|
int index, x,y,z;
|
||||||
|
|
||||||
|
|
||||||
|
size_t posslab;
|
||||||
|
|
||||||
|
for (z=pos-1; z<=pos; z++)
|
||||||
|
{
|
||||||
|
posslab=z * _slabSize;
|
||||||
|
|
||||||
|
if(_totalSteps % 4 == 1) {
|
||||||
|
for (y = 1; y < _res[1]-1; y++)
|
||||||
|
for (x = 1+(y+z)%2; x < _res[0]-1; x+=2) {
|
||||||
|
index = x + y*_res[0] + posslab;
|
||||||
|
_xForce[index] = (1-w)*_xVelocityTemp[index] + 1./6. * w*(
|
||||||
|
_xVelocityTemp[index+1] + _xVelocityTemp[index-1] +
|
||||||
|
_xVelocityTemp[index+_res[0]] + _xVelocityTemp[index-_res[0]] +
|
||||||
|
_xVelocityTemp[index+_slabSize] + _xVelocityTemp[index-_slabSize] );
|
||||||
|
|
||||||
|
_yForce[index] = (1-w)*_yVelocityTemp[index] + 1./6. * w*(
|
||||||
|
_yVelocityTemp[index+1] + _yVelocityTemp[index-1] +
|
||||||
|
_yVelocityTemp[index+_res[0]] + _yVelocityTemp[index-_res[0]] +
|
||||||
|
_yVelocityTemp[index+_slabSize] + _yVelocityTemp[index-_slabSize] );
|
||||||
|
|
||||||
|
_zForce[index] = (1-w)*_zVelocityTemp[index] + 1./6. * w*(
|
||||||
|
_zVelocityTemp[index+1] + _zVelocityTemp[index-1] +
|
||||||
|
_zVelocityTemp[index+_res[0]] + _zVelocityTemp[index-_res[0]] +
|
||||||
|
_zVelocityTemp[index+_slabSize] + _zVelocityTemp[index-_slabSize] );
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(_totalSteps % 4 == 3) {
|
||||||
|
for (y = 1; y < _res[1]-1; y++)
|
||||||
|
for (x = 1+(y+z+1)%2; x < _res[0]-1; x+=2) {
|
||||||
|
index = x + y*_res[0] + posslab;
|
||||||
|
_xForce[index] = (1-w)*_xVelocityTemp[index] + 1./6. * w*(
|
||||||
|
_xVelocityTemp[index+1] + _xVelocityTemp[index-1] +
|
||||||
|
_xVelocityTemp[index+_res[0]] + _xVelocityTemp[index-_res[0]] +
|
||||||
|
_xVelocityTemp[index+_slabSize] + _xVelocityTemp[index-_slabSize] );
|
||||||
|
|
||||||
|
_yForce[index] = (1-w)*_yVelocityTemp[index] + 1./6. * w*(
|
||||||
|
_yVelocityTemp[index+1] + _yVelocityTemp[index-1] +
|
||||||
|
_yVelocityTemp[index+_res[0]] + _yVelocityTemp[index-_res[0]] +
|
||||||
|
_yVelocityTemp[index+_slabSize] + _yVelocityTemp[index-_slabSize] );
|
||||||
|
|
||||||
|
_zForce[index] = (1-w)*_zVelocityTemp[index] + 1./6. * w*(
|
||||||
|
_zVelocityTemp[index+1] + _zVelocityTemp[index-1] +
|
||||||
|
_zVelocityTemp[index+_res[0]] + _zVelocityTemp[index-_res[0]] +
|
||||||
|
_zVelocityTemp[index+_slabSize] + _zVelocityTemp[index-_slabSize] );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// copy out the boundary in all directions
|
// copy out the boundary in all directions
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
void FLUID_3D::copyBorderAll(float* field)
|
void FLUID_3D::copyBorderAll(float* field, int zBegin, int zEnd)
|
||||||
{
|
{
|
||||||
int index;
|
int index, x, y, z;
|
||||||
|
int zSize = zEnd-zBegin;
|
||||||
|
int _blockTotalCells=_slabSize * zSize;
|
||||||
|
|
||||||
|
if ((zBegin==0))
|
||||||
for (int y = 0; y < _yRes; y++)
|
for (int y = 0; y < _yRes; y++)
|
||||||
for (int x = 0; x < _xRes; x++)
|
for (int x = 0; x < _xRes; x++)
|
||||||
{
|
{
|
||||||
// front slab
|
// front slab
|
||||||
index = x + y * _xRes;
|
index = x + y * _xRes;
|
||||||
field[index] = field[index + _slabSize];
|
field[index] = field[index + _slabSize];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (zEnd==_zRes)
|
||||||
|
for (y = 0; y < _yRes; y++)
|
||||||
|
for (x = 0; x < _xRes; x++)
|
||||||
|
{
|
||||||
|
|
||||||
// back slab
|
// back slab
|
||||||
index += _totalCells - _slabSize;
|
index = x + y * _xRes + _blockTotalCells - _slabSize;
|
||||||
field[index] = field[index - _slabSize];
|
field[index] = field[index - _slabSize];
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int z = 0; z < _zRes; z++)
|
for (z = 0; z < zSize; z++)
|
||||||
for (int x = 0; x < _xRes; x++)
|
for (x = 0; x < _xRes; x++)
|
||||||
{
|
{
|
||||||
// bottom slab
|
// bottom slab
|
||||||
index = x + z * _slabSize;
|
index = x + z * _slabSize;
|
||||||
@@ -294,8 +514,8 @@ void FLUID_3D::copyBorderAll(float* field)
|
|||||||
field[index] = field[index - _xRes];
|
field[index] = field[index - _xRes];
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int z = 0; z < _zRes; z++)
|
for (z = 0; z < zSize; z++)
|
||||||
for (int y = 0; y < _yRes; y++)
|
for (y = 0; y < _yRes; y++)
|
||||||
{
|
{
|
||||||
// left slab
|
// left slab
|
||||||
index = y * _xRes + z * _slabSize;
|
index = y * _xRes + z * _slabSize;
|
||||||
@@ -310,27 +530,123 @@ void FLUID_3D::copyBorderAll(float* field)
|
|||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// wipe boundaries of velocity and density
|
// wipe boundaries of velocity and density
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
void FLUID_3D::wipeBoundaries()
|
void FLUID_3D::wipeBoundaries(int zBegin, int zEnd)
|
||||||
{
|
{
|
||||||
setZeroBorder(_xVelocity, _res);
|
setZeroBorder(_xVelocity, _res, zBegin, zEnd);
|
||||||
setZeroBorder(_yVelocity, _res);
|
setZeroBorder(_yVelocity, _res, zBegin, zEnd);
|
||||||
setZeroBorder(_zVelocity, _res);
|
setZeroBorder(_zVelocity, _res, zBegin, zEnd);
|
||||||
setZeroBorder(_density, _res);
|
setZeroBorder(_density, _res, zBegin, zEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FLUID_3D::wipeBoundariesSL(int zBegin, int zEnd)
|
||||||
|
{
|
||||||
|
|
||||||
|
/////////////////////////////////////
|
||||||
|
// setZeroBorder to all:
|
||||||
|
/////////////////////////////////////
|
||||||
|
|
||||||
|
/////////////////////////////////////
|
||||||
|
// setZeroX
|
||||||
|
/////////////////////////////////////
|
||||||
|
|
||||||
|
const int slabSize = _xRes * _yRes;
|
||||||
|
int index, x,y,z;
|
||||||
|
|
||||||
|
for (z = zBegin; z < zEnd; z++)
|
||||||
|
for (y = 0; y < _yRes; y++)
|
||||||
|
{
|
||||||
|
// left slab
|
||||||
|
index = y * _xRes + z * slabSize;
|
||||||
|
_xVelocity[index] = 0.0f;
|
||||||
|
_yVelocity[index] = 0.0f;
|
||||||
|
_zVelocity[index] = 0.0f;
|
||||||
|
_density[index] = 0.0f;
|
||||||
|
|
||||||
|
// right slab
|
||||||
|
index += _xRes - 1;
|
||||||
|
_xVelocity[index] = 0.0f;
|
||||||
|
_yVelocity[index] = 0.0f;
|
||||||
|
_zVelocity[index] = 0.0f;
|
||||||
|
_density[index] = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////
|
||||||
|
// setZeroY
|
||||||
|
/////////////////////////////////////
|
||||||
|
|
||||||
|
for (z = zBegin; z < zEnd; z++)
|
||||||
|
for (x = 0; x < _xRes; x++)
|
||||||
|
{
|
||||||
|
// bottom slab
|
||||||
|
index = x + z * slabSize;
|
||||||
|
_xVelocity[index] = 0.0f;
|
||||||
|
_yVelocity[index] = 0.0f;
|
||||||
|
_zVelocity[index] = 0.0f;
|
||||||
|
_density[index] = 0.0f;
|
||||||
|
|
||||||
|
// top slab
|
||||||
|
index += slabSize - _xRes;
|
||||||
|
_xVelocity[index] = 0.0f;
|
||||||
|
_yVelocity[index] = 0.0f;
|
||||||
|
_zVelocity[index] = 0.0f;
|
||||||
|
_density[index] = 0.0f;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////
|
||||||
|
// setZeroZ
|
||||||
|
/////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
const int totalCells = _xRes * _yRes * _zRes;
|
||||||
|
|
||||||
|
index = 0;
|
||||||
|
if ((zBegin == 0))
|
||||||
|
for (y = 0; y < _yRes; y++)
|
||||||
|
for (x = 0; x < _xRes; x++, index++)
|
||||||
|
{
|
||||||
|
// front slab
|
||||||
|
_xVelocity[index] = 0.0f;
|
||||||
|
_yVelocity[index] = 0.0f;
|
||||||
|
_zVelocity[index] = 0.0f;
|
||||||
|
_density[index] = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (zEnd == _zRes)
|
||||||
|
{
|
||||||
|
index=0;
|
||||||
|
int indexx=0;
|
||||||
|
const int cellsslab = totalCells - slabSize;
|
||||||
|
|
||||||
|
for (y = 0; y < _yRes; y++)
|
||||||
|
for (x = 0; x < _xRes; x++, index++)
|
||||||
|
{
|
||||||
|
|
||||||
|
// back slab
|
||||||
|
indexx = index + cellsslab;
|
||||||
|
_xVelocity[indexx] = 0.0f;
|
||||||
|
_yVelocity[indexx] = 0.0f;
|
||||||
|
_zVelocity[indexx] = 0.0f;
|
||||||
|
_density[indexx] = 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// add forces to velocity field
|
// add forces to velocity field
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
void FLUID_3D::addForce()
|
void FLUID_3D::addForce(int zBegin, int zEnd)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < _totalCells; i++)
|
int begin=zBegin * _slabSize;
|
||||||
|
int end=begin + (zEnd - zBegin) * _slabSize;
|
||||||
|
|
||||||
|
for (int i = begin; i < end; i++)
|
||||||
{
|
{
|
||||||
_xVelocity[i] += _dt * _xForce[i];
|
_xVelocityTemp[i] = _xVelocity[i] + _dt * _xForce[i];
|
||||||
_yVelocity[i] += _dt * _yForce[i];
|
_yVelocityTemp[i] = _yVelocity[i] + _dt * _yForce[i];
|
||||||
_zVelocity[i] += _dt * _zForce[i];
|
_zVelocityTemp[i] = _zVelocity[i] + _dt * _zForce[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// project into divergence free field
|
// project into divergence free field
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
@@ -344,18 +660,18 @@ void FLUID_3D::project()
|
|||||||
|
|
||||||
memset(_pressure, 0, sizeof(float)*_totalCells);
|
memset(_pressure, 0, sizeof(float)*_totalCells);
|
||||||
memset(_divergence, 0, sizeof(float)*_totalCells);
|
memset(_divergence, 0, sizeof(float)*_totalCells);
|
||||||
|
|
||||||
setObstacleBoundaries(_pressure);
|
setObstacleBoundaries(_pressure, 0, _zRes);
|
||||||
|
|
||||||
// copy out the boundaries
|
// copy out the boundaries
|
||||||
if(DOMAIN_BC_LEFT == 0) setNeumannX(_xVelocity, _res);
|
if(DOMAIN_BC_LEFT == 0) setNeumannX(_xVelocity, _res, 0, _zRes);
|
||||||
else setZeroX(_xVelocity, _res);
|
else setZeroX(_xVelocity, _res, 0, _zRes);
|
||||||
|
|
||||||
if(DOMAIN_BC_TOP == 0) setNeumannY(_yVelocity, _res);
|
if(DOMAIN_BC_TOP == 0) setNeumannY(_yVelocity, _res, 0, _zRes);
|
||||||
else setZeroY(_yVelocity, _res);
|
else setZeroY(_yVelocity, _res, 0, _zRes);
|
||||||
|
|
||||||
if(DOMAIN_BC_FRONT == 0) setNeumannZ(_zVelocity, _res);
|
if(DOMAIN_BC_FRONT == 0) setNeumannZ(_zVelocity, _res, 0, _zRes);
|
||||||
else setZeroZ(_zVelocity, _res);
|
else setZeroZ(_zVelocity, _res, 0, _zRes);
|
||||||
|
|
||||||
// calculate divergence
|
// calculate divergence
|
||||||
index = _slabSize + _xRes + 1;
|
index = _slabSize + _xRes + 1;
|
||||||
@@ -385,12 +701,12 @@ void FLUID_3D::project()
|
|||||||
// DG: commenting this helps CG to get a better start, 10-20% speed improvement
|
// DG: commenting this helps CG to get a better start, 10-20% speed improvement
|
||||||
// _pressure[index] = 0.0f;
|
// _pressure[index] = 0.0f;
|
||||||
}
|
}
|
||||||
copyBorderAll(_pressure);
|
copyBorderAll(_pressure, 0, _zRes);
|
||||||
|
|
||||||
// solve Poisson equation
|
// solve Poisson equation
|
||||||
solvePressurePre(_pressure, _divergence, _obstacles);
|
solvePressurePre(_pressure, _divergence, _obstacles);
|
||||||
|
|
||||||
setObstaclePressure(_pressure);
|
setObstaclePressure(_pressure, 0, _zRes);
|
||||||
|
|
||||||
// project out solution
|
// project out solution
|
||||||
float invDx = 1.0f / _dx;
|
float invDx = 1.0f / _dx;
|
||||||
@@ -411,6 +727,9 @@ void FLUID_3D::project()
|
|||||||
if (_divergence) delete[] _divergence;
|
if (_divergence) delete[] _divergence;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// diffuse heat
|
// diffuse heat
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
@@ -418,13 +737,14 @@ void FLUID_3D::diffuseHeat()
|
|||||||
{
|
{
|
||||||
SWAP_POINTERS(_heat, _heatOld);
|
SWAP_POINTERS(_heat, _heatOld);
|
||||||
|
|
||||||
copyBorderAll(_heatOld);
|
copyBorderAll(_heatOld, 0, _zRes);
|
||||||
solveHeat(_heat, _heatOld, _obstacles);
|
solveHeat(_heat, _heatOld, _obstacles);
|
||||||
|
|
||||||
// zero out inside obstacles
|
// zero out inside obstacles
|
||||||
for (int x = 0; x < _totalCells; x++)
|
for (int x = 0; x < _totalCells; x++)
|
||||||
if (_obstacles[x])
|
if (_obstacles[x])
|
||||||
_heat[x] = 0.0f;
|
_heat[x] = 0.0f;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
@@ -444,12 +764,28 @@ void FLUID_3D::addObstacle(OBSTACLE* obstacle)
|
|||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// calculate the obstacle directional types
|
// calculate the obstacle directional types
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
void FLUID_3D::setObstaclePressure(float *_pressure)
|
void FLUID_3D::setObstaclePressure(float *_pressure, int zBegin, int zEnd)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// compleately TODO
|
||||||
|
|
||||||
|
const size_t index_ = _slabSize + _xRes + 1;
|
||||||
|
|
||||||
|
//int vIndex=_slabSize + _xRes + 1;
|
||||||
|
|
||||||
|
int bb=0;
|
||||||
|
int bt=0;
|
||||||
|
|
||||||
|
if (zBegin == 0) {bb = 1;}
|
||||||
|
if (zEnd == _zRes) {bt = 1;}
|
||||||
|
|
||||||
// tag remaining obstacle blocks
|
// tag remaining obstacle blocks
|
||||||
for (int z = 1, index = _slabSize + _xRes + 1;
|
for (int z = zBegin + bb; z < zEnd - bt; z++)
|
||||||
z < _zRes - 1; z++, index += 2 * _xRes)
|
{
|
||||||
|
size_t index = index_ +(z-1)*_slabSize;
|
||||||
|
|
||||||
for (int y = 1; y < _yRes - 1; y++, index += 2)
|
for (int y = 1; y < _yRes - 1; y++, index += 2)
|
||||||
|
{
|
||||||
for (int x = 1; x < _xRes - 1; x++, index++)
|
for (int x = 1; x < _xRes - 1; x++, index++)
|
||||||
{
|
{
|
||||||
// could do cascade of ifs, but they are a pain
|
// could do cascade of ifs, but they are a pain
|
||||||
@@ -507,15 +843,33 @@ void FLUID_3D::setObstaclePressure(float *_pressure)
|
|||||||
// this means it's not a full no-slip boundary condition
|
// this means it's not a full no-slip boundary condition
|
||||||
// but a "half-slip" - still looks ok right now
|
// but a "half-slip" - still looks ok right now
|
||||||
}
|
}
|
||||||
}
|
//vIndex++;
|
||||||
|
} // x loop
|
||||||
|
//vIndex += 2;
|
||||||
|
} // y loop
|
||||||
|
//vIndex += 2 * _xRes;
|
||||||
|
} // z loop
|
||||||
}
|
}
|
||||||
|
|
||||||
void FLUID_3D::setObstacleBoundaries(float *_pressure)
|
void FLUID_3D::setObstacleBoundaries(float *_pressure, int zBegin, int zEnd)
|
||||||
{
|
{
|
||||||
// cull degenerate obstacles , move to addObstacle?
|
// cull degenerate obstacles , move to addObstacle?
|
||||||
for (int z = 1, index = _slabSize + _xRes + 1;
|
|
||||||
z < _zRes - 1; z++, index += 2 * _xRes)
|
// r = b - Ax
|
||||||
|
const size_t index_ = _slabSize + _xRes + 1;
|
||||||
|
|
||||||
|
int bb=0;
|
||||||
|
int bt=0;
|
||||||
|
|
||||||
|
if (zBegin == 0) {bb = 1;}
|
||||||
|
if (zEnd == _zRes) {bt = 1;}
|
||||||
|
|
||||||
|
for (int z = zBegin + bb; z < zEnd - bt; z++)
|
||||||
|
{
|
||||||
|
size_t index = index_ +(z-1)*_slabSize;
|
||||||
|
|
||||||
for (int y = 1; y < _yRes - 1; y++, index += 2)
|
for (int y = 1; y < _yRes - 1; y++, index += 2)
|
||||||
|
{
|
||||||
for (int x = 1; x < _xRes - 1; x++, index++)
|
for (int x = 1; x < _xRes - 1; x++, index++)
|
||||||
{
|
{
|
||||||
if (_obstacles[index] != EMPTY)
|
if (_obstacles[index] != EMPTY)
|
||||||
@@ -545,17 +899,22 @@ void FLUID_3D::setObstacleBoundaries(float *_pressure)
|
|||||||
_zVelocity[index] = 0.0f;
|
_zVelocity[index] = 0.0f;
|
||||||
_pressure[index] = 0.0f;
|
_pressure[index] = 0.0f;
|
||||||
}
|
}
|
||||||
}
|
//vIndex++;
|
||||||
|
} // x-loop
|
||||||
|
//vIndex += 2;
|
||||||
|
} // y-loop
|
||||||
|
//vIndex += 2* _xRes;
|
||||||
|
} // z-loop
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// add buoyancy forces
|
// add buoyancy forces
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
void FLUID_3D::addBuoyancy(float *heat, float *density)
|
void FLUID_3D::addBuoyancy(float *heat, float *density, int zBegin, int zEnd)
|
||||||
{
|
{
|
||||||
int index = 0;
|
int index = zBegin*_slabSize;
|
||||||
|
|
||||||
for (int z = 0; z < _zRes; z++)
|
for (int z = zBegin; z < zEnd; z++)
|
||||||
for (int y = 0; y < _yRes; y++)
|
for (int y = 0; y < _yRes; y++)
|
||||||
for (int x = 0; x < _xRes; x++, index++)
|
for (int x = 0; x < _xRes; x++, index++)
|
||||||
{
|
{
|
||||||
@@ -566,30 +925,55 @@ void FLUID_3D::addBuoyancy(float *heat, float *density)
|
|||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// add vorticity to the force field
|
// add vorticity to the force field
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
void FLUID_3D::addVorticity()
|
void FLUID_3D::addVorticity(int zBegin, int zEnd)
|
||||||
{
|
{
|
||||||
int x,y,z,index;
|
//int x,y,z,index;
|
||||||
if(_vorticityEps<=0.) return;
|
if(_vorticityEps<=0.) return;
|
||||||
|
|
||||||
|
int _blockSize=zEnd-zBegin;
|
||||||
|
int _blockTotalCells = _slabSize * (_blockSize+2);
|
||||||
|
|
||||||
float *_xVorticity, *_yVorticity, *_zVorticity, *_vorticity;
|
float *_xVorticity, *_yVorticity, *_zVorticity, *_vorticity;
|
||||||
|
|
||||||
_xVorticity = new float[_totalCells];
|
int _vIndex = _slabSize + _xRes + 1;
|
||||||
_yVorticity = new float[_totalCells];
|
int bb=0;
|
||||||
_zVorticity = new float[_totalCells];
|
int bt=0;
|
||||||
_vorticity = new float[_totalCells];
|
int bb1=-1;
|
||||||
|
int bt1=-1;
|
||||||
|
|
||||||
memset(_xVorticity, 0, sizeof(float)*_totalCells);
|
if (zBegin == 0) {bb1 = 1; bb = 1; _blockTotalCells-=_blockSize;}
|
||||||
memset(_yVorticity, 0, sizeof(float)*_totalCells);
|
if (zEnd == _zRes) {bt1 = 1;bt = 1; _blockTotalCells-=_blockSize;}
|
||||||
memset(_zVorticity, 0, sizeof(float)*_totalCells);
|
|
||||||
memset(_vorticity, 0, sizeof(float)*_totalCells);
|
_xVorticity = new float[_blockTotalCells];
|
||||||
|
_yVorticity = new float[_blockTotalCells];
|
||||||
|
_zVorticity = new float[_blockTotalCells];
|
||||||
|
_vorticity = new float[_blockTotalCells];
|
||||||
|
|
||||||
|
memset(_xVorticity, 0, sizeof(float)*_blockTotalCells);
|
||||||
|
memset(_yVorticity, 0, sizeof(float)*_blockTotalCells);
|
||||||
|
memset(_zVorticity, 0, sizeof(float)*_blockTotalCells);
|
||||||
|
memset(_vorticity, 0, sizeof(float)*_blockTotalCells);
|
||||||
|
|
||||||
|
//const size_t indexsetupV=_slabSize;
|
||||||
|
const size_t index_ = _slabSize + _xRes + 1;
|
||||||
|
|
||||||
// calculate vorticity
|
// calculate vorticity
|
||||||
float gridSize = 0.5f / _dx;
|
float gridSize = 0.5f / _dx;
|
||||||
index = _slabSize + _xRes + 1;
|
//index = _slabSize + _xRes + 1;
|
||||||
for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
|
|
||||||
for (y = 1; y < _yRes - 1; y++, index += 2)
|
|
||||||
for (x = 1; x < _xRes - 1; x++, index++)
|
size_t vIndex=_xRes + 1;
|
||||||
|
|
||||||
|
for (int z = zBegin + bb1; z < (zEnd - bt1); z++)
|
||||||
|
{
|
||||||
|
size_t index = index_ +(z-1)*_slabSize;
|
||||||
|
vIndex = index-(zBegin-1+bb)*_slabSize;
|
||||||
|
|
||||||
|
for (int y = 1; y < _yRes - 1; y++, index += 2)
|
||||||
|
{
|
||||||
|
for (int x = 1; x < _xRes - 1; x++, index++)
|
||||||
{
|
{
|
||||||
|
|
||||||
int up = _obstacles[index + _xRes] ? index : index + _xRes;
|
int up = _obstacles[index + _xRes] ? index : index + _xRes;
|
||||||
int down = _obstacles[index - _xRes] ? index : index - _xRes;
|
int down = _obstacles[index - _xRes] ? index : index - _xRes;
|
||||||
float dy = (up == index || down == index) ? 1.0f / _dx : gridSize;
|
float dy = (up == index || down == index) ? 1.0f / _dx : gridSize;
|
||||||
@@ -600,34 +984,51 @@ void FLUID_3D::addVorticity()
|
|||||||
int left = _obstacles[index - 1] ? index : index - 1;
|
int left = _obstacles[index - 1] ? index : index - 1;
|
||||||
float dx = (right == index || right == index) ? 1.0f / _dx : gridSize;
|
float dx = (right == index || right == index) ? 1.0f / _dx : gridSize;
|
||||||
|
|
||||||
_xVorticity[index] = (_zVelocity[up] - _zVelocity[down]) * dy + (-_yVelocity[out] + _yVelocity[in]) * dz;
|
_xVorticity[vIndex] = (_zVelocity[up] - _zVelocity[down]) * dy + (-_yVelocity[out] + _yVelocity[in]) * dz;
|
||||||
_yVorticity[index] = (_xVelocity[out] - _xVelocity[in]) * dz + (-_zVelocity[right] + _zVelocity[left]) * dx;
|
_yVorticity[vIndex] = (_xVelocity[out] - _xVelocity[in]) * dz + (-_zVelocity[right] + _zVelocity[left]) * dx;
|
||||||
_zVorticity[index] = (_yVelocity[right] - _yVelocity[left]) * dx + (-_xVelocity[up] + _xVelocity[down])* dy;
|
_zVorticity[vIndex] = (_yVelocity[right] - _yVelocity[left]) * dx + (-_xVelocity[up] + _xVelocity[down])* dy;
|
||||||
|
|
||||||
_vorticity[index] = sqrtf(_xVorticity[index] * _xVorticity[index] +
|
_vorticity[vIndex] = sqrtf(_xVorticity[vIndex] * _xVorticity[vIndex] +
|
||||||
_yVorticity[index] * _yVorticity[index] +
|
_yVorticity[vIndex] * _yVorticity[vIndex] +
|
||||||
_zVorticity[index] * _zVorticity[index]);
|
_zVorticity[vIndex] * _zVorticity[vIndex]);
|
||||||
|
|
||||||
|
vIndex++;
|
||||||
}
|
}
|
||||||
|
vIndex+=2;
|
||||||
|
}
|
||||||
|
//vIndex+=2*_xRes;
|
||||||
|
}
|
||||||
|
|
||||||
// calculate normalized vorticity vectors
|
// calculate normalized vorticity vectors
|
||||||
float eps = _vorticityEps;
|
float eps = _vorticityEps;
|
||||||
index = _slabSize + _xRes + 1;
|
|
||||||
for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
|
//index = _slabSize + _xRes + 1;
|
||||||
for (y = 1; y < _yRes - 1; y++, index += 2)
|
vIndex=_slabSize + _xRes + 1;
|
||||||
for (x = 1; x < _xRes - 1; x++, index++)
|
|
||||||
|
for (int z = zBegin + bb; z < (zEnd - bt); z++)
|
||||||
|
{
|
||||||
|
size_t index = index_ +(z-1)*_slabSize;
|
||||||
|
vIndex = index-(zBegin-1+bb)*_slabSize;
|
||||||
|
|
||||||
|
for (int y = 1; y < _yRes - 1; y++, index += 2)
|
||||||
|
{
|
||||||
|
for (int x = 1; x < _xRes - 1; x++, index++)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
|
||||||
if (!_obstacles[index])
|
if (!_obstacles[index])
|
||||||
{
|
{
|
||||||
float N[3];
|
float N[3];
|
||||||
|
|
||||||
int up = _obstacles[index + _xRes] ? index : index + _xRes;
|
int up = _obstacles[index + _xRes] ? vIndex : vIndex + _xRes;
|
||||||
int down = _obstacles[index - _xRes] ? index : index - _xRes;
|
int down = _obstacles[index - _xRes] ? vIndex : vIndex - _xRes;
|
||||||
float dy = (up == index || down == index) ? 1.0f / _dx : gridSize;
|
float dy = (up == vIndex || down == vIndex) ? 1.0f / _dx : gridSize;
|
||||||
int out = _obstacles[index + _slabSize] ? index : index + _slabSize;
|
int out = _obstacles[index + _slabSize] ? vIndex : vIndex + _slabSize;
|
||||||
int in = _obstacles[index - _slabSize] ? index : index - _slabSize;
|
int in = _obstacles[index - _slabSize] ? vIndex : vIndex - _slabSize;
|
||||||
float dz = (out == index || in == index) ? 1.0f / _dx : gridSize;
|
float dz = (out == vIndex || in == vIndex) ? 1.0f / _dx : gridSize;
|
||||||
int right = _obstacles[index + 1] ? index : index + 1;
|
int right = _obstacles[index + 1] ? vIndex : vIndex + 1;
|
||||||
int left = _obstacles[index - 1] ? index : index - 1;
|
int left = _obstacles[index - 1] ? vIndex : vIndex - 1;
|
||||||
float dx = (right == index || right == index) ? 1.0f / _dx : gridSize;
|
float dx = (right == vIndex || right == vIndex) ? 1.0f / _dx : gridSize;
|
||||||
N[0] = (_vorticity[right] - _vorticity[left]) * dx;
|
N[0] = (_vorticity[right] - _vorticity[left]) * dx;
|
||||||
N[1] = (_vorticity[up] - _vorticity[down]) * dy;
|
N[1] = (_vorticity[up] - _vorticity[down]) * dy;
|
||||||
N[2] = (_vorticity[out] - _vorticity[in]) * dz;
|
N[2] = (_vorticity[out] - _vorticity[in]) * dz;
|
||||||
@@ -640,11 +1041,17 @@ void FLUID_3D::addVorticity()
|
|||||||
N[1] *= magnitude;
|
N[1] *= magnitude;
|
||||||
N[2] *= magnitude;
|
N[2] *= magnitude;
|
||||||
|
|
||||||
_xForce[index] += (N[1] * _zVorticity[index] - N[2] * _yVorticity[index]) * _dx * eps;
|
_xForce[index] += (N[1] * _zVorticity[vIndex] - N[2] * _yVorticity[vIndex]) * _dx * eps;
|
||||||
_yForce[index] -= (N[0] * _zVorticity[index] - N[2] * _xVorticity[index]) * _dx * eps;
|
_yForce[index] -= (N[0] * _zVorticity[vIndex] - N[2] * _xVorticity[vIndex]) * _dx * eps;
|
||||||
_zForce[index] += (N[0] * _yVorticity[index] - N[1] * _xVorticity[index]) * _dx * eps;
|
_zForce[index] += (N[0] * _yVorticity[vIndex] - N[1] * _xVorticity[vIndex]) * _dx * eps;
|
||||||
}
|
}
|
||||||
}
|
} // if
|
||||||
|
vIndex++;
|
||||||
|
} // x loop
|
||||||
|
vIndex+=2;
|
||||||
|
} // y loop
|
||||||
|
//vIndex+=2*_xRes;
|
||||||
|
} // z loop
|
||||||
|
|
||||||
if (_xVorticity) delete[] _xVorticity;
|
if (_xVorticity) delete[] _xVorticity;
|
||||||
if (_yVorticity) delete[] _yVorticity;
|
if (_yVorticity) delete[] _yVorticity;
|
||||||
@@ -652,54 +1059,80 @@ void FLUID_3D::addVorticity()
|
|||||||
if (_vorticity) delete[] _vorticity;
|
if (_vorticity) delete[] _vorticity;
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
|
||||||
// Advect using the MacCormack method from the Selle paper
|
void FLUID_3D::advectMacCormackBegin(int zBegin, int zEnd)
|
||||||
//////////////////////////////////////////////////////////////////////
|
|
||||||
void FLUID_3D::advectMacCormack()
|
|
||||||
{
|
{
|
||||||
Vec3Int res = Vec3Int(_xRes,_yRes,_zRes);
|
Vec3Int res = Vec3Int(_xRes,_yRes,_zRes);
|
||||||
|
|
||||||
if(DOMAIN_BC_LEFT == 0) copyBorderX(_xVelocity, res);
|
if(DOMAIN_BC_LEFT == 0) copyBorderX(_xVelocityOld, res, zBegin, zEnd);
|
||||||
else setZeroX(_xVelocity, res);
|
else setZeroX(_xVelocityOld, res, zBegin, zEnd);
|
||||||
|
|
||||||
if(DOMAIN_BC_TOP == 0) copyBorderY(_yVelocity, res);
|
if(DOMAIN_BC_TOP == 0) copyBorderY(_yVelocityOld, res, zBegin, zEnd);
|
||||||
else setZeroY(_yVelocity, res);
|
else setZeroY(_yVelocityOld, res, zBegin, zEnd);
|
||||||
|
|
||||||
if(DOMAIN_BC_FRONT == 0) copyBorderZ(_zVelocity, res);
|
if(DOMAIN_BC_FRONT == 0) copyBorderZ(_zVelocityOld, res, zBegin, zEnd);
|
||||||
else setZeroZ(_zVelocity, res);
|
else setZeroZ(_zVelocityOld, res, zBegin, zEnd);
|
||||||
|
}
|
||||||
|
|
||||||
SWAP_POINTERS(_xVelocity, _xVelocityOld);
|
//////////////////////////////////////////////////////////////////////
|
||||||
SWAP_POINTERS(_yVelocity, _yVelocityOld);
|
// Advect using the MacCormack method from the Selle paper
|
||||||
SWAP_POINTERS(_zVelocity, _zVelocityOld);
|
//////////////////////////////////////////////////////////////////////
|
||||||
SWAP_POINTERS(_density, _densityOld);
|
void FLUID_3D::advectMacCormackEnd1(int zBegin, int zEnd)
|
||||||
SWAP_POINTERS(_heat, _heatOld);
|
{
|
||||||
|
Vec3Int res = Vec3Int(_xRes,_yRes,_zRes);
|
||||||
|
|
||||||
const float dt0 = _dt / _dx;
|
const float dt0 = _dt / _dx;
|
||||||
// use force arrays as temp arrays
|
|
||||||
for (int x = 0; x < _totalCells; x++)
|
|
||||||
_xForce[x] = _yForce[x] = 0.0;
|
|
||||||
|
|
||||||
float* t1 = _xForce;
|
int begin=zBegin * _slabSize;
|
||||||
float* t2 = _yForce;
|
int end=begin + (zEnd - zBegin) * _slabSize;
|
||||||
|
for (int x = begin; x < end; x++)
|
||||||
|
_xForce[x] = 0.0;
|
||||||
|
|
||||||
advectFieldMacCormack(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _densityOld, _density, t1,t2, res, _obstacles);
|
// advectFieldMacCormack1(dt, xVelocity, yVelocity, zVelocity, oldField, newField, res)
|
||||||
advectFieldMacCormack(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _heatOld, _heat, t1,t2, res, _obstacles);
|
|
||||||
advectFieldMacCormack(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _xVelocityOld, _xVelocity, t1,t2, res, _obstacles);
|
|
||||||
advectFieldMacCormack(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _yVelocityOld, _yVelocity, t1,t2, res, _obstacles);
|
|
||||||
advectFieldMacCormack(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _zVelocityOld, _zVelocity, t1,t2, res, _obstacles);
|
|
||||||
|
|
||||||
if(DOMAIN_BC_LEFT == 0) copyBorderX(_xVelocity, res);
|
advectFieldMacCormack1(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _densityOld, _densityTemp, res, zBegin, zEnd);
|
||||||
else setZeroX(_xVelocity, res);
|
advectFieldMacCormack1(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _heatOld, _heatTemp, res, zBegin, zEnd);
|
||||||
|
advectFieldMacCormack1(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _xVelocityOld, _xVelocity, res, zBegin, zEnd);
|
||||||
|
advectFieldMacCormack1(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _yVelocityOld, _yVelocity, res, zBegin, zEnd);
|
||||||
|
advectFieldMacCormack1(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _zVelocityOld, _zVelocity, res, zBegin, zEnd);
|
||||||
|
|
||||||
if(DOMAIN_BC_TOP == 0) copyBorderY(_yVelocity, res);
|
// Have to wait untill all the threads are done -> so continuing in step 3
|
||||||
else setZeroY(_yVelocity, res);
|
}
|
||||||
|
|
||||||
if(DOMAIN_BC_FRONT == 0) copyBorderZ(_zVelocity, res);
|
//////////////////////////////////////////////////////////////////////
|
||||||
else setZeroZ(_zVelocity, res);
|
// Advect using the MacCormack method from the Selle paper
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
setZeroBorder(_density, res);
|
void FLUID_3D::advectMacCormackEnd2(int zBegin, int zEnd)
|
||||||
setZeroBorder(_heat, res);
|
{
|
||||||
|
const float dt0 = _dt / _dx;
|
||||||
for (int x = 0; x < _totalCells; x++)
|
Vec3Int res = Vec3Int(_xRes,_yRes,_zRes);
|
||||||
t1[x] = t2[x] = 0.0;
|
|
||||||
|
// use force array as temp arrays
|
||||||
|
float* t1 = _xForce;
|
||||||
|
|
||||||
|
// advectFieldMacCormack2(dt, xVelocity, yVelocity, zVelocity, oldField, newField, tempfield, temp, res, obstacles)
|
||||||
|
|
||||||
|
advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _densityOld, _density, _densityTemp, t1, res, _obstacles, zBegin, zEnd);
|
||||||
|
advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _heatOld, _heat, _heatTemp, t1, res, _obstacles, zBegin, zEnd);
|
||||||
|
advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _xVelocityOld, _xVelocityTemp, _xVelocity, t1, res, _obstacles, zBegin, zEnd);
|
||||||
|
advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _yVelocityOld, _yVelocityTemp, _yVelocity, t1, res, _obstacles, zBegin, zEnd);
|
||||||
|
advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _zVelocityOld, _zVelocityTemp, _zVelocity, t1, res, _obstacles, zBegin, zEnd);
|
||||||
|
|
||||||
|
if(DOMAIN_BC_LEFT == 0) copyBorderX(_xVelocityTemp, res, zBegin, zEnd);
|
||||||
|
else setZeroX(_xVelocityTemp, res, zBegin, zEnd);
|
||||||
|
|
||||||
|
if(DOMAIN_BC_TOP == 0) copyBorderY(_yVelocityTemp, res, zBegin, zEnd);
|
||||||
|
else setZeroY(_yVelocityTemp, res, zBegin, zEnd);
|
||||||
|
|
||||||
|
if(DOMAIN_BC_FRONT == 0) copyBorderZ(_zVelocityTemp, res, zBegin, zEnd);
|
||||||
|
else setZeroZ(_zVelocityTemp, res, zBegin, zEnd);
|
||||||
|
|
||||||
|
setZeroBorder(_density, res, zBegin, zEnd);
|
||||||
|
setZeroBorder(_heat, res, zBegin, zEnd);
|
||||||
|
|
||||||
|
|
||||||
|
/*int begin=zBegin * _slabSize;
|
||||||
|
int end=begin + (zEnd - zBegin) * _slabSize;
|
||||||
|
for (int x = begin; x < end; x++)
|
||||||
|
_xForce[x] = _yForce[x] = 0.0f;*/
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,11 @@
|
|||||||
// FLUID_3D.h: interface for the FLUID_3D class.
|
// FLUID_3D.h: interface for the FLUID_3D class.
|
||||||
//
|
//
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// Heavy parallel optimization done. Many of the old functions now
|
||||||
|
// take begin and end parameters and process only specified part of the data.
|
||||||
|
// Some functions were divided into multiple ones.
|
||||||
|
// - MiikaH
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#ifndef FLUID_3D_H
|
#ifndef FLUID_3D_H
|
||||||
#define FLUID_3D_H
|
#define FLUID_3D_H
|
||||||
@@ -74,7 +79,8 @@ class FLUID_3D
|
|||||||
int _totalImgDumps;
|
int _totalImgDumps;
|
||||||
int _totalVelDumps;
|
int _totalVelDumps;
|
||||||
|
|
||||||
void artificialDamping(float* field);
|
void artificialDampingSL(int zBegin, int zEnd);
|
||||||
|
void artificialDampingExactSL(int pos);
|
||||||
|
|
||||||
// fields
|
// fields
|
||||||
float* _density;
|
float* _density;
|
||||||
@@ -92,6 +98,13 @@ class FLUID_3D
|
|||||||
float* _zForce;
|
float* _zForce;
|
||||||
unsigned char* _obstacles;
|
unsigned char* _obstacles;
|
||||||
|
|
||||||
|
// Required for proper threading:
|
||||||
|
float* _xVelocityTemp;
|
||||||
|
float* _yVelocityTemp;
|
||||||
|
float* _zVelocityTemp;
|
||||||
|
float* _heatTemp;
|
||||||
|
float* _densityTemp;
|
||||||
|
|
||||||
// CG fields
|
// CG fields
|
||||||
int _iterations;
|
int _iterations;
|
||||||
|
|
||||||
@@ -107,13 +120,14 @@ class FLUID_3D
|
|||||||
// WTURBULENCE* _wTurbulence;
|
// WTURBULENCE* _wTurbulence;
|
||||||
|
|
||||||
// boundary setting functions
|
// boundary setting functions
|
||||||
void copyBorderAll(float* field);
|
void copyBorderAll(float* field, int zBegin, int zEnd);
|
||||||
|
|
||||||
// timestepping functions
|
// timestepping functions
|
||||||
void wipeBoundaries();
|
void wipeBoundaries(int zBegin, int zEnd);
|
||||||
void addForce();
|
void wipeBoundariesSL(int zBegin, int zEnd);
|
||||||
void addVorticity();
|
void addForce(int zBegin, int zEnd);
|
||||||
void addBuoyancy(float *heat, float *density);
|
void addVorticity(int zBegin, int zEnd);
|
||||||
|
void addBuoyancy(float *heat, float *density, int zBegin, int zEnd);
|
||||||
|
|
||||||
// solver stuff
|
// solver stuff
|
||||||
void project();
|
void project();
|
||||||
@@ -122,41 +136,58 @@ class FLUID_3D
|
|||||||
void solvePressurePre(float* field, float* b, unsigned char* skip);
|
void solvePressurePre(float* field, float* b, unsigned char* skip);
|
||||||
void solveHeat(float* field, float* b, unsigned char* skip);
|
void solveHeat(float* field, float* b, unsigned char* skip);
|
||||||
|
|
||||||
|
|
||||||
// handle obstacle boundaries
|
// handle obstacle boundaries
|
||||||
void setObstacleBoundaries(float *_pressure);
|
void setObstacleBoundaries(float *_pressure, int zBegin, int zEnd);
|
||||||
void setObstaclePressure(float *_pressure);
|
void setObstaclePressure(float *_pressure, int zBegin, int zEnd);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// advection, accessed e.g. by WTURBULENCE class
|
// advection, accessed e.g. by WTURBULENCE class
|
||||||
void advectMacCormack();
|
//void advectMacCormack();
|
||||||
|
void advectMacCormackBegin(int zBegin, int zEnd);
|
||||||
|
void advectMacCormackEnd1(int zBegin, int zEnd);
|
||||||
|
void advectMacCormackEnd2(int zBegin, int zEnd);
|
||||||
|
|
||||||
// boundary setting functions
|
// boundary setting functions
|
||||||
static void copyBorderX(float* field, Vec3Int res);
|
static void copyBorderX(float* field, Vec3Int res, int zBegin, int zEnd);
|
||||||
static void copyBorderY(float* field, Vec3Int res);
|
static void copyBorderY(float* field, Vec3Int res, int zBegin, int zEnd);
|
||||||
static void copyBorderZ(float* field, Vec3Int res);
|
static void copyBorderZ(float* field, Vec3Int res, int zBegin, int zEnd);
|
||||||
static void setNeumannX(float* field, Vec3Int res);
|
static void setNeumannX(float* field, Vec3Int res, int zBegin, int zEnd);
|
||||||
static void setNeumannY(float* field, Vec3Int res);
|
static void setNeumannY(float* field, Vec3Int res, int zBegin, int zEnd);
|
||||||
static void setNeumannZ(float* field, Vec3Int res);
|
static void setNeumannZ(float* field, Vec3Int res, int zBegin, int zEnd);
|
||||||
static void setZeroX(float* field, Vec3Int res);
|
static void setZeroX(float* field, Vec3Int res, int zBegin, int zEnd);
|
||||||
static void setZeroY(float* field, Vec3Int res);
|
static void setZeroY(float* field, Vec3Int res, int zBegin, int zEnd);
|
||||||
static void setZeroZ(float* field, Vec3Int res);
|
static void setZeroZ(float* field, Vec3Int res, int zBegin, int zEnd);
|
||||||
static void setZeroBorder(float* field, Vec3Int res) {
|
static void setZeroBorder(float* field, Vec3Int res, int zBegin, int zEnd) {
|
||||||
setZeroX(field, res);
|
setZeroX(field, res, zBegin, zEnd);
|
||||||
setZeroY(field, res);
|
setZeroY(field, res, zBegin, zEnd);
|
||||||
setZeroZ(field, res);
|
setZeroZ(field, res, zBegin, zEnd);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// static advection functions, also used by WTURBULENCE
|
// static advection functions, also used by WTURBULENCE
|
||||||
static void advectFieldSemiLagrange(const float dt, const float* velx, const float* vely, const float* velz,
|
static void advectFieldSemiLagrange(const float dt, const float* velx, const float* vely, const float* velz,
|
||||||
float* oldField, float* newField, Vec3Int res);
|
float* oldField, float* newField, Vec3Int res, int zBegin, int zEnd);
|
||||||
static void advectFieldMacCormack(const float dt, const float* xVelocity, const float* yVelocity, const float* zVelocity,
|
static void advectFieldMacCormack1(const float dt, const float* xVelocity, const float* yVelocity, const float* zVelocity,
|
||||||
float* oldField, float* newField, float* temp1, float* temp2, Vec3Int res, const unsigned char* obstacles);
|
float* oldField, float* tempResult, Vec3Int res, int zBegin, int zEnd);
|
||||||
|
static void advectFieldMacCormack2(const float dt, const float* xVelocity, const float* yVelocity, const float* zVelocity,
|
||||||
|
float* oldField, float* newField, float* tempResult, float* temp1,Vec3Int res, const unsigned char* obstacles, int zBegin, int zEnd);
|
||||||
|
|
||||||
|
|
||||||
|
// temp ones for testing
|
||||||
|
/*static void advectFieldMacCormack(const float dt, const float* xVelocity, const float* yVelocity, const float* zVelocity,
|
||||||
|
float* oldField, float* newField, float* temp1, float* temp2, Vec3Int res, const unsigned char* obstacles);*/
|
||||||
|
/*static void advectFieldSemiLagrange2(const float dt, const float* velx, const float* vely, const float* velz,
|
||||||
|
float* oldField, float* newField, Vec3Int res);*/
|
||||||
|
|
||||||
// maccormack helper functions
|
// maccormack helper functions
|
||||||
static void clampExtrema(const float dt, const float* xVelocity, const float* yVelocity, const float* zVelocity,
|
static void clampExtrema(const float dt, const float* xVelocity, const float* yVelocity, const float* zVelocity,
|
||||||
float* oldField, float* newField, Vec3Int res);
|
float* oldField, float* newField, Vec3Int res, int zBegin, int zEnd);
|
||||||
static void clampOutsideRays(const float dt, const float* xVelocity, const float* yVelocity, const float* zVelocity,
|
static void clampOutsideRays(const float dt, const float* xVelocity, const float* yVelocity, const float* zVelocity,
|
||||||
float* oldField, float* newField, Vec3Int res, const unsigned char* obstacles, const float *oldAdvection);
|
float* oldField, float* newField, Vec3Int res, const unsigned char* obstacles, const float *oldAdvection, int zBegin, int zEnd);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// output helper functions
|
// output helper functions
|
||||||
// static void writeImageSliceXY(const float *field, Vec3Int res, int slice, string prefix, int picCnt, float scale=1.);
|
// static void writeImageSliceXY(const float *field, Vec3Int res, int slice, string prefix, int picCnt, float scale=1.);
|
||||||
|
|||||||
@@ -19,11 +19,150 @@
|
|||||||
// FLUID_3D.cpp: implementation of the FLUID_3D class.
|
// FLUID_3D.cpp: implementation of the FLUID_3D class.
|
||||||
//
|
//
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// Both solvers optimized by merging loops and precalculating
|
||||||
|
// stuff used in iteration loop.
|
||||||
|
// - MiikaH
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include "FLUID_3D.h"
|
#include "FLUID_3D.h"
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#define SOLVER_ACCURACY 1e-06
|
#define SOLVER_ACCURACY 1e-06
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// solve the heat equation with CG
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
void FLUID_3D::solveHeat(float* field, float* b, unsigned char* skip)
|
||||||
|
{
|
||||||
|
int x, y, z;
|
||||||
|
const int twoxr = 2 * _xRes;
|
||||||
|
size_t index;
|
||||||
|
const float heatConst = _dt * _heatDiffusion / (_dx * _dx);
|
||||||
|
float *_q, *_residual, *_direction, *_Acenter;
|
||||||
|
|
||||||
|
// i = 0
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
_residual = new float[_totalCells]; // set 0
|
||||||
|
_direction = new float[_totalCells]; // set 0
|
||||||
|
_q = new float[_totalCells]; // set 0
|
||||||
|
_Acenter = new float[_totalCells]; // set 0
|
||||||
|
|
||||||
|
memset(_residual, 0, sizeof(float)*_totalCells);
|
||||||
|
memset(_q, 0, sizeof(float)*_totalCells);
|
||||||
|
memset(_direction, 0, sizeof(float)*_totalCells);
|
||||||
|
memset(_Acenter, 0, sizeof(float)*_totalCells);
|
||||||
|
|
||||||
|
float deltaNew = 0.0f;
|
||||||
|
|
||||||
|
// r = b - Ax
|
||||||
|
index = _slabSize + _xRes + 1;
|
||||||
|
for (z = 1; z < _zRes - 1; z++, index += twoxr)
|
||||||
|
for (y = 1; y < _yRes - 1; y++, index += 2)
|
||||||
|
for (x = 1; x < _xRes - 1; x++, index++)
|
||||||
|
{
|
||||||
|
// if the cell is a variable
|
||||||
|
_Acenter[index] = 1.0f;
|
||||||
|
if (!skip[index])
|
||||||
|
{
|
||||||
|
// set the matrix to the Poisson stencil in order
|
||||||
|
if (!skip[index + 1]) _Acenter[index] += heatConst;
|
||||||
|
if (!skip[index - 1]) _Acenter[index] += heatConst;
|
||||||
|
if (!skip[index + _xRes]) _Acenter[index] += heatConst;
|
||||||
|
if (!skip[index - _xRes]) _Acenter[index] += heatConst;
|
||||||
|
if (!skip[index + _slabSize]) _Acenter[index] += heatConst;
|
||||||
|
if (!skip[index - _slabSize]) _Acenter[index] += heatConst;
|
||||||
|
|
||||||
|
_residual[index] = b[index] - (_Acenter[index] * field[index] +
|
||||||
|
field[index - 1] * (skip[index - 1] ? 0.0 : -heatConst) +
|
||||||
|
field[index + 1] * (skip[index + 1] ? 0.0 : -heatConst) +
|
||||||
|
field[index - _xRes] * (skip[index - _xRes] ? 0.0 : -heatConst) +
|
||||||
|
field[index + _xRes] * (skip[index + _xRes] ? 0.0 : -heatConst) +
|
||||||
|
field[index - _slabSize] * (skip[index - _slabSize] ? 0.0 : -heatConst) +
|
||||||
|
field[index + _slabSize] * (skip[index + _slabSize] ? 0.0 : -heatConst));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_residual[index] = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
_direction[index] = _residual[index];
|
||||||
|
deltaNew += _residual[index] * _residual[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// While deltaNew > (eps^2) * delta0
|
||||||
|
const float eps = SOLVER_ACCURACY;
|
||||||
|
float maxR = 2.0f * eps;
|
||||||
|
while ((i < _iterations) && (maxR > eps))
|
||||||
|
{
|
||||||
|
// q = Ad
|
||||||
|
float alpha = 0.0f;
|
||||||
|
|
||||||
|
index = _slabSize + _xRes + 1;
|
||||||
|
for (z = 1; z < _zRes - 1; z++, index += twoxr)
|
||||||
|
for (y = 1; y < _yRes - 1; y++, index += 2)
|
||||||
|
for (x = 1; x < _xRes - 1; x++, index++)
|
||||||
|
{
|
||||||
|
// if the cell is a variable
|
||||||
|
if (!skip[index])
|
||||||
|
{
|
||||||
|
|
||||||
|
_q[index] = (_Acenter[index] * _direction[index] +
|
||||||
|
_direction[index - 1] * (skip[index - 1] ? 0.0 : -heatConst) +
|
||||||
|
_direction[index + 1] * (skip[index + 1] ? 0.0 : -heatConst) +
|
||||||
|
_direction[index - _xRes] * (skip[index - _xRes] ? 0.0 : -heatConst) +
|
||||||
|
_direction[index + _xRes] * (skip[index + _xRes] ? 0.0 : -heatConst) +
|
||||||
|
_direction[index - _slabSize] * (skip[index - _slabSize] ? 0.0 : -heatConst) +
|
||||||
|
_direction[index + _slabSize] * (skip[index + _slabSize] ? 0.0 : -heatConst));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_q[index] = 0.0f;
|
||||||
|
}
|
||||||
|
alpha += _direction[index] * _q[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fabs(alpha) > 0.0f)
|
||||||
|
alpha = deltaNew / alpha;
|
||||||
|
|
||||||
|
float deltaOld = deltaNew;
|
||||||
|
deltaNew = 0.0f;
|
||||||
|
|
||||||
|
maxR = 0.0f;
|
||||||
|
|
||||||
|
index = _slabSize + _xRes + 1;
|
||||||
|
for (z = 1; z < _zRes - 1; z++, index += twoxr)
|
||||||
|
for (y = 1; y < _yRes - 1; y++, index += 2)
|
||||||
|
for (x = 1; x < _xRes - 1; x++, index++)
|
||||||
|
{
|
||||||
|
field[index] += alpha * _direction[index];
|
||||||
|
|
||||||
|
_residual[index] -= alpha * _q[index];
|
||||||
|
maxR = (_residual[index] > maxR) ? _residual[index] : maxR;
|
||||||
|
|
||||||
|
deltaNew += _residual[index] * _residual[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
float beta = deltaNew / deltaOld;
|
||||||
|
|
||||||
|
index = _slabSize + _xRes + 1;
|
||||||
|
for (z = 1; z < _zRes - 1; z++, index += twoxr)
|
||||||
|
for (y = 1; y < _yRes - 1; y++, index += 2)
|
||||||
|
for (x = 1; x < _xRes - 1; x++, index++)
|
||||||
|
_direction[index] = _residual[index] + beta * _direction[index];
|
||||||
|
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
// cout << i << " iterations converged to " << maxR << endl;
|
||||||
|
|
||||||
|
if (_residual) delete[] _residual;
|
||||||
|
if (_direction) delete[] _direction;
|
||||||
|
if (_q) delete[] _q;
|
||||||
|
if (_Acenter) delete[] _Acenter;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void FLUID_3D::solvePressurePre(float* field, float* b, unsigned char* skip)
|
void FLUID_3D::solvePressurePre(float* field, float* b, unsigned char* skip)
|
||||||
{
|
{
|
||||||
int x, y, z;
|
int x, y, z;
|
||||||
@@ -45,6 +184,8 @@ void FLUID_3D::solvePressurePre(float* field, float* b, unsigned char* skip)
|
|||||||
memset(_h, 0, sizeof(float)*_xRes*_yRes*_zRes);
|
memset(_h, 0, sizeof(float)*_xRes*_yRes*_zRes);
|
||||||
memset(_Precond, 0, sizeof(float)*_xRes*_yRes*_zRes);
|
memset(_Precond, 0, sizeof(float)*_xRes*_yRes*_zRes);
|
||||||
|
|
||||||
|
float deltaNew = 0.0f;
|
||||||
|
|
||||||
// r = b - Ax
|
// r = b - Ax
|
||||||
index = _slabSize + _xRes + 1;
|
index = _slabSize + _xRes + 1;
|
||||||
for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
|
for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
|
||||||
@@ -62,16 +203,19 @@ void FLUID_3D::solvePressurePre(float* field, float* b, unsigned char* skip)
|
|||||||
if (!skip[index - _xRes]) Acenter += 1.;
|
if (!skip[index - _xRes]) Acenter += 1.;
|
||||||
if (!skip[index + _slabSize]) Acenter += 1.;
|
if (!skip[index + _slabSize]) Acenter += 1.;
|
||||||
if (!skip[index - _slabSize]) Acenter += 1.;
|
if (!skip[index - _slabSize]) Acenter += 1.;
|
||||||
}
|
|
||||||
|
_residual[index] = b[index] - (Acenter * field[index] +
|
||||||
_residual[index] = b[index] - (Acenter * field[index] +
|
|
||||||
field[index - 1] * (skip[index - 1] ? 0.0 : -1.0f)+
|
field[index - 1] * (skip[index - 1] ? 0.0 : -1.0f)+
|
||||||
field[index + 1] * (skip[index + 1] ? 0.0 : -1.0f)+
|
field[index + 1] * (skip[index + 1] ? 0.0 : -1.0f)+
|
||||||
field[index - _xRes] * (skip[index - _xRes] ? 0.0 : -1.0f)+
|
field[index - _xRes] * (skip[index - _xRes] ? 0.0 : -1.0f)+
|
||||||
field[index + _xRes] * (skip[index + _xRes] ? 0.0 : -1.0f)+
|
field[index + _xRes] * (skip[index + _xRes] ? 0.0 : -1.0f)+
|
||||||
field[index - _slabSize] * (skip[index - _slabSize] ? 0.0 : -1.0f)+
|
field[index - _slabSize] * (skip[index - _slabSize] ? 0.0 : -1.0f)+
|
||||||
field[index + _slabSize] * (skip[index + _slabSize] ? 0.0 : -1.0f) );
|
field[index + _slabSize] * (skip[index + _slabSize] ? 0.0 : -1.0f) );
|
||||||
_residual[index] = (skip[index]) ? 0.0f : _residual[index];
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_residual[index] = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
// P^-1
|
// P^-1
|
||||||
if(Acenter < 1.0)
|
if(Acenter < 1.0)
|
||||||
@@ -81,18 +225,10 @@ void FLUID_3D::solvePressurePre(float* field, float* b, unsigned char* skip)
|
|||||||
|
|
||||||
// p = P^-1 * r
|
// p = P^-1 * r
|
||||||
_direction[index] = _residual[index] * _Precond[index];
|
_direction[index] = _residual[index] * _Precond[index];
|
||||||
|
|
||||||
|
deltaNew += _residual[index] * _direction[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
// deltaNew = transpose(r) * p
|
|
||||||
float deltaNew = 0.0f;
|
|
||||||
index = _slabSize + _xRes + 1;
|
|
||||||
for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
|
|
||||||
for (y = 1; y < _yRes - 1; y++, index += 2)
|
|
||||||
for (x = 1; x < _xRes - 1; x++, index++)
|
|
||||||
deltaNew += _residual[index] * _direction[index];
|
|
||||||
|
|
||||||
// delta0 = deltaNew
|
|
||||||
// float delta0 = deltaNew;
|
|
||||||
|
|
||||||
// While deltaNew > (eps^2) * delta0
|
// While deltaNew > (eps^2) * delta0
|
||||||
const float eps = SOLVER_ACCURACY;
|
const float eps = SOLVER_ACCURACY;
|
||||||
@@ -101,7 +237,9 @@ void FLUID_3D::solvePressurePre(float* field, float* b, unsigned char* skip)
|
|||||||
// while (i < _iterations)
|
// while (i < _iterations)
|
||||||
while ((i < _iterations) && (maxR > 0.001*eps))
|
while ((i < _iterations) && (maxR > 0.001*eps))
|
||||||
{
|
{
|
||||||
// (s) q = Ad (p)
|
|
||||||
|
float alpha = 0.0f;
|
||||||
|
|
||||||
index = _slabSize + _xRes + 1;
|
index = _slabSize + _xRes + 1;
|
||||||
for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
|
for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
|
||||||
for (y = 1; y < _yRes - 1; y++, index += 2)
|
for (y = 1; y < _yRes - 1; y++, index += 2)
|
||||||
@@ -118,71 +256,52 @@ void FLUID_3D::solvePressurePre(float* field, float* b, unsigned char* skip)
|
|||||||
if (!skip[index - _xRes]) Acenter += 1.;
|
if (!skip[index - _xRes]) Acenter += 1.;
|
||||||
if (!skip[index + _slabSize]) Acenter += 1.;
|
if (!skip[index + _slabSize]) Acenter += 1.;
|
||||||
if (!skip[index - _slabSize]) Acenter += 1.;
|
if (!skip[index - _slabSize]) Acenter += 1.;
|
||||||
}
|
|
||||||
|
_q[index] = Acenter * _direction[index] +
|
||||||
_q[index] = Acenter * _direction[index] +
|
|
||||||
_direction[index - 1] * (skip[index - 1] ? 0.0 : -1.0f) +
|
_direction[index - 1] * (skip[index - 1] ? 0.0 : -1.0f) +
|
||||||
_direction[index + 1] * (skip[index + 1] ? 0.0 : -1.0f) +
|
_direction[index + 1] * (skip[index + 1] ? 0.0 : -1.0f) +
|
||||||
_direction[index - _xRes] * (skip[index - _xRes] ? 0.0 : -1.0f) +
|
_direction[index - _xRes] * (skip[index - _xRes] ? 0.0 : -1.0f) +
|
||||||
_direction[index + _xRes] * (skip[index + _xRes] ? 0.0 : -1.0f)+
|
_direction[index + _xRes] * (skip[index + _xRes] ? 0.0 : -1.0f)+
|
||||||
_direction[index - _slabSize] * (skip[index - _slabSize] ? 0.0 : -1.0f) +
|
_direction[index - _slabSize] * (skip[index - _slabSize] ? 0.0 : -1.0f) +
|
||||||
_direction[index + _slabSize] * (skip[index + _slabSize] ? 0.0 : -1.0f);
|
_direction[index + _slabSize] * (skip[index + _slabSize] ? 0.0 : -1.0f);
|
||||||
_q[index] = (skip[index]) ? 0.0f : _q[index];
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_q[index] = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
alpha += _direction[index] * _q[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
// alpha = deltaNew / (transpose(d) * q)
|
|
||||||
float alpha = 0.0f;
|
|
||||||
index = _slabSize + _xRes + 1;
|
|
||||||
for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
|
|
||||||
for (y = 1; y < _yRes - 1; y++, index += 2)
|
|
||||||
for (x = 1; x < _xRes - 1; x++, index++)
|
|
||||||
alpha += _direction[index] * _q[index];
|
|
||||||
if (fabs(alpha) > 0.0f)
|
if (fabs(alpha) > 0.0f)
|
||||||
alpha = deltaNew / alpha;
|
alpha = deltaNew / alpha;
|
||||||
|
|
||||||
|
float deltaOld = deltaNew;
|
||||||
|
deltaNew = 0.0f;
|
||||||
|
|
||||||
|
maxR = 0.0;
|
||||||
|
|
||||||
|
float tmp;
|
||||||
|
|
||||||
// x = x + alpha * d
|
// x = x + alpha * d
|
||||||
index = _slabSize + _xRes + 1;
|
index = _slabSize + _xRes + 1;
|
||||||
for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
|
for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
|
||||||
for (y = 1; y < _yRes - 1; y++, index += 2)
|
for (y = 1; y < _yRes - 1; y++, index += 2)
|
||||||
for (x = 1; x < _xRes - 1; x++, index++)
|
for (x = 1; x < _xRes - 1; x++, index++)
|
||||||
|
{
|
||||||
field[index] += alpha * _direction[index];
|
field[index] += alpha * _direction[index];
|
||||||
|
|
||||||
// r = r - alpha * q
|
_residual[index] -= alpha * _q[index];
|
||||||
maxR = 0.0;
|
|
||||||
index = _slabSize + _xRes + 1;
|
|
||||||
for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
|
|
||||||
for (y = 1; y < _yRes - 1; y++, index += 2)
|
|
||||||
for (x = 1; x < _xRes - 1; x++, index++)
|
|
||||||
{
|
|
||||||
_residual[index] -= alpha * _q[index];
|
|
||||||
// maxR = (_residual[index] > maxR) ? _residual[index] : maxR;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if(maxR <= eps)
|
_h[index] = _Precond[index] * _residual[index];
|
||||||
// break;
|
|
||||||
|
tmp = _residual[index] * _h[index];
|
||||||
|
deltaNew += tmp;
|
||||||
|
maxR = (tmp > maxR) ? tmp : maxR;
|
||||||
|
|
||||||
// h = P^-1 * r
|
|
||||||
index = _slabSize + _xRes + 1;
|
|
||||||
for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
|
|
||||||
for (y = 1; y < _yRes - 1; y++, index += 2)
|
|
||||||
for (x = 1; x < _xRes - 1; x++, index++)
|
|
||||||
{
|
|
||||||
_h[index] = _Precond[index] * _residual[index];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// deltaOld = deltaNew
|
|
||||||
float deltaOld = deltaNew;
|
|
||||||
|
|
||||||
// deltaNew = transpose(r) * h
|
|
||||||
deltaNew = 0.0f;
|
|
||||||
index = _slabSize + _xRes + 1;
|
|
||||||
for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
|
|
||||||
for (y = 1; y < _yRes - 1; y++, index += 2)
|
|
||||||
for (x = 1; x < _xRes - 1; x++, index++)
|
|
||||||
{
|
|
||||||
deltaNew += _residual[index] * _h[index];
|
|
||||||
maxR = (_residual[index]* _h[index] > maxR) ? _residual[index]* _h[index] : maxR;
|
|
||||||
}
|
|
||||||
|
|
||||||
// beta = deltaNew / deltaOld
|
// beta = deltaNew / deltaOld
|
||||||
float beta = deltaNew / deltaOld;
|
float beta = deltaNew / deltaOld;
|
||||||
@@ -205,320 +324,3 @@ void FLUID_3D::solvePressurePre(float* field, float* b, unsigned char* skip)
|
|||||||
if (_direction) delete[] _direction;
|
if (_direction) delete[] _direction;
|
||||||
if (_q) delete[] _q;
|
if (_q) delete[] _q;
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
|
||||||
// solve the poisson equation with CG
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
|
||||||
#if 0
|
|
||||||
void FLUID_3D::solvePressure(float* field, float* b, unsigned char* skip)
|
|
||||||
{
|
|
||||||
int x, y, z;
|
|
||||||
size_t index;
|
|
||||||
|
|
||||||
// i = 0
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
memset(_residual, 0, sizeof(float)*_xRes*_yRes*_zRes);
|
|
||||||
memset(_q, 0, sizeof(float)*_xRes*_yRes*_zRes);
|
|
||||||
memset(_direction, 0, sizeof(float)*_xRes*_yRes*_zRes);
|
|
||||||
|
|
||||||
// r = b - Ax
|
|
||||||
index = _slabSize + _xRes + 1;
|
|
||||||
for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
|
|
||||||
for (y = 1; y < _yRes - 1; y++, index += 2)
|
|
||||||
for (x = 1; x < _xRes - 1; x++, index++)
|
|
||||||
{
|
|
||||||
// if the cell is a variable
|
|
||||||
float Acenter = 0.0f;
|
|
||||||
if (!skip[index])
|
|
||||||
{
|
|
||||||
// set the matrix to the Poisson stencil in order
|
|
||||||
if (!skip[index + 1]) Acenter += 1.;
|
|
||||||
if (!skip[index - 1]) Acenter += 1.;
|
|
||||||
if (!skip[index + _xRes]) Acenter += 1.;
|
|
||||||
if (!skip[index - _xRes]) Acenter += 1.;
|
|
||||||
if (!skip[index + _slabSize]) Acenter += 1.;
|
|
||||||
if (!skip[index - _slabSize]) Acenter += 1.;
|
|
||||||
}
|
|
||||||
|
|
||||||
_residual[index] = b[index] - (Acenter * field[index] +
|
|
||||||
field[index - 1] * (skip[index - 1] ? 0.0 : -1.0f)+
|
|
||||||
field[index + 1] * (skip[index + 1] ? 0.0 : -1.0f)+
|
|
||||||
field[index - _xRes] * (skip[index - _xRes] ? 0.0 : -1.0f)+
|
|
||||||
field[index + _xRes] * (skip[index + _xRes] ? 0.0 : -1.0f)+
|
|
||||||
field[index - _slabSize] * (skip[index - _slabSize] ? 0.0 : -1.0f)+
|
|
||||||
field[index + _slabSize] * (skip[index + _slabSize] ? 0.0 : -1.0f) );
|
|
||||||
_residual[index] = (skip[index]) ? 0.0f : _residual[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// d = r
|
|
||||||
index = _slabSize + _xRes + 1;
|
|
||||||
for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
|
|
||||||
for (y = 1; y < _yRes - 1; y++, index += 2)
|
|
||||||
for (x = 1; x < _xRes - 1; x++, index++)
|
|
||||||
_direction[index] = _residual[index];
|
|
||||||
|
|
||||||
// deltaNew = transpose(r) * r
|
|
||||||
float deltaNew = 0.0f;
|
|
||||||
index = _slabSize + _xRes + 1;
|
|
||||||
for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
|
|
||||||
for (y = 1; y < _yRes - 1; y++, index += 2)
|
|
||||||
for (x = 1; x < _xRes - 1; x++, index++)
|
|
||||||
deltaNew += _residual[index] * _residual[index];
|
|
||||||
|
|
||||||
// delta0 = deltaNew
|
|
||||||
// float delta0 = deltaNew;
|
|
||||||
|
|
||||||
// While deltaNew > (eps^2) * delta0
|
|
||||||
const float eps = SOLVER_ACCURACY;
|
|
||||||
float maxR = 2.0f * eps;
|
|
||||||
while ((i < _iterations) && (maxR > eps))
|
|
||||||
{
|
|
||||||
// q = Ad
|
|
||||||
index = _slabSize + _xRes + 1;
|
|
||||||
for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
|
|
||||||
for (y = 1; y < _yRes - 1; y++, index += 2)
|
|
||||||
for (x = 1; x < _xRes - 1; x++, index++)
|
|
||||||
{
|
|
||||||
// if the cell is a variable
|
|
||||||
float Acenter = 0.0f;
|
|
||||||
if (!skip[index])
|
|
||||||
{
|
|
||||||
// set the matrix to the Poisson stencil in order
|
|
||||||
if (!skip[index + 1]) Acenter += 1.;
|
|
||||||
if (!skip[index - 1]) Acenter += 1.;
|
|
||||||
if (!skip[index + _xRes]) Acenter += 1.;
|
|
||||||
if (!skip[index - _xRes]) Acenter += 1.;
|
|
||||||
if (!skip[index + _slabSize]) Acenter += 1.;
|
|
||||||
if (!skip[index - _slabSize]) Acenter += 1.;
|
|
||||||
}
|
|
||||||
|
|
||||||
_q[index] = Acenter * _direction[index] +
|
|
||||||
_direction[index - 1] * (skip[index - 1] ? 0.0 : -1.0f) +
|
|
||||||
_direction[index + 1] * (skip[index + 1] ? 0.0 : -1.0f) +
|
|
||||||
_direction[index - _xRes] * (skip[index - _xRes] ? 0.0 : -1.0f) +
|
|
||||||
_direction[index + _xRes] * (skip[index + _xRes] ? 0.0 : -1.0f)+
|
|
||||||
_direction[index - _slabSize] * (skip[index - _slabSize] ? 0.0 : -1.0f) +
|
|
||||||
_direction[index + _slabSize] * (skip[index + _slabSize] ? 0.0 : -1.0f);
|
|
||||||
_q[index] = (skip[index]) ? 0.0f : _q[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
// alpha = deltaNew / (transpose(d) * q)
|
|
||||||
float alpha = 0.0f;
|
|
||||||
index = _slabSize + _xRes + 1;
|
|
||||||
for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
|
|
||||||
for (y = 1; y < _yRes - 1; y++, index += 2)
|
|
||||||
for (x = 1; x < _xRes - 1; x++, index++)
|
|
||||||
alpha += _direction[index] * _q[index];
|
|
||||||
if (fabs(alpha) > 0.0f)
|
|
||||||
alpha = deltaNew / alpha;
|
|
||||||
|
|
||||||
// x = x + alpha * d
|
|
||||||
index = _slabSize + _xRes + 1;
|
|
||||||
for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
|
|
||||||
for (y = 1; y < _yRes - 1; y++, index += 2)
|
|
||||||
for (x = 1; x < _xRes - 1; x++, index++)
|
|
||||||
field[index] += alpha * _direction[index];
|
|
||||||
|
|
||||||
// r = r - alpha * q
|
|
||||||
maxR = 0.0f;
|
|
||||||
index = _slabSize + _xRes + 1;
|
|
||||||
for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
|
|
||||||
for (y = 1; y < _yRes - 1; y++, index += 2)
|
|
||||||
for (x = 1; x < _xRes - 1; x++, index++)
|
|
||||||
{
|
|
||||||
_residual[index] -= alpha * _q[index];
|
|
||||||
maxR = (_residual[index] > maxR) ? _residual[index] : maxR;
|
|
||||||
}
|
|
||||||
|
|
||||||
// deltaOld = deltaNew
|
|
||||||
float deltaOld = deltaNew;
|
|
||||||
|
|
||||||
// deltaNew = transpose(r) * r
|
|
||||||
deltaNew = 0.0f;
|
|
||||||
index = _slabSize + _xRes + 1;
|
|
||||||
for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
|
|
||||||
for (y = 1; y < _yRes - 1; y++, index += 2)
|
|
||||||
for (x = 1; x < _xRes - 1; x++, index++)
|
|
||||||
deltaNew += _residual[index] * _residual[index];
|
|
||||||
|
|
||||||
// beta = deltaNew / deltaOld
|
|
||||||
float beta = deltaNew / deltaOld;
|
|
||||||
|
|
||||||
// d = r + beta * d
|
|
||||||
index = _slabSize + _xRes + 1;
|
|
||||||
for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
|
|
||||||
for (y = 1; y < _yRes - 1; y++, index += 2)
|
|
||||||
for (x = 1; x < _xRes - 1; x++, index++)
|
|
||||||
_direction[index] = _residual[index] + beta * _direction[index];
|
|
||||||
|
|
||||||
// i = i + 1
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
// cout << i << " iterations converged to " << maxR << endl;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
|
||||||
// solve the heat equation with CG
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
|
||||||
void FLUID_3D::solveHeat(float* field, float* b, unsigned char* skip)
|
|
||||||
{
|
|
||||||
int x, y, z;
|
|
||||||
size_t index;
|
|
||||||
const float heatConst = _dt * _heatDiffusion / (_dx * _dx);
|
|
||||||
float *_q, *_residual, *_direction;
|
|
||||||
|
|
||||||
// i = 0
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
_residual = new float[_totalCells]; // set 0
|
|
||||||
_direction = new float[_totalCells]; // set 0
|
|
||||||
_q = new float[_totalCells]; // set 0
|
|
||||||
|
|
||||||
memset(_residual, 0, sizeof(float)*_xRes*_yRes*_zRes);
|
|
||||||
memset(_q, 0, sizeof(float)*_xRes*_yRes*_zRes);
|
|
||||||
memset(_direction, 0, sizeof(float)*_xRes*_yRes*_zRes);
|
|
||||||
|
|
||||||
// r = b - Ax
|
|
||||||
index = _slabSize + _xRes + 1;
|
|
||||||
for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
|
|
||||||
for (y = 1; y < _yRes - 1; y++, index += 2)
|
|
||||||
for (x = 1; x < _xRes - 1; x++, index++)
|
|
||||||
{
|
|
||||||
// if the cell is a variable
|
|
||||||
float Acenter = 1.0f;
|
|
||||||
if (!skip[index])
|
|
||||||
{
|
|
||||||
// set the matrix to the Poisson stencil in order
|
|
||||||
if (!skip[index + 1]) Acenter += heatConst;
|
|
||||||
if (!skip[index - 1]) Acenter += heatConst;
|
|
||||||
if (!skip[index + _xRes]) Acenter += heatConst;
|
|
||||||
if (!skip[index - _xRes]) Acenter += heatConst;
|
|
||||||
if (!skip[index + _slabSize]) Acenter += heatConst;
|
|
||||||
if (!skip[index - _slabSize]) Acenter += heatConst;
|
|
||||||
}
|
|
||||||
|
|
||||||
_residual[index] = b[index] - (Acenter * field[index] +
|
|
||||||
field[index - 1] * (skip[index - 1] ? 0.0 : -heatConst) +
|
|
||||||
field[index + 1] * (skip[index + 1] ? 0.0 : -heatConst) +
|
|
||||||
field[index - _xRes] * (skip[index - _xRes] ? 0.0 : -heatConst) +
|
|
||||||
field[index + _xRes] * (skip[index + _xRes] ? 0.0 : -heatConst) +
|
|
||||||
field[index - _slabSize] * (skip[index - _slabSize] ? 0.0 : -heatConst) +
|
|
||||||
field[index + _slabSize] * (skip[index + _slabSize] ? 0.0 : -heatConst));
|
|
||||||
_residual[index] = (skip[index]) ? 0.0f : _residual[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
// d = r
|
|
||||||
index = _slabSize + _xRes + 1;
|
|
||||||
for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
|
|
||||||
for (y = 1; y < _yRes - 1; y++, index += 2)
|
|
||||||
for (x = 1; x < _xRes - 1; x++, index++)
|
|
||||||
_direction[index] = _residual[index];
|
|
||||||
|
|
||||||
// deltaNew = transpose(r) * r
|
|
||||||
float deltaNew = 0.0f;
|
|
||||||
index = _slabSize + _xRes + 1;
|
|
||||||
for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
|
|
||||||
for (y = 1; y < _yRes - 1; y++, index += 2)
|
|
||||||
for (x = 1; x < _xRes - 1; x++, index++)
|
|
||||||
deltaNew += _residual[index] * _residual[index];
|
|
||||||
|
|
||||||
// delta0 = deltaNew
|
|
||||||
// float delta0 = deltaNew;
|
|
||||||
|
|
||||||
// While deltaNew > (eps^2) * delta0
|
|
||||||
const float eps = SOLVER_ACCURACY;
|
|
||||||
float maxR = 2.0f * eps;
|
|
||||||
while ((i < _iterations) && (maxR > eps))
|
|
||||||
{
|
|
||||||
// q = Ad
|
|
||||||
index = _slabSize + _xRes + 1;
|
|
||||||
for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
|
|
||||||
for (y = 1; y < _yRes - 1; y++, index += 2)
|
|
||||||
for (x = 1; x < _xRes - 1; x++, index++)
|
|
||||||
{
|
|
||||||
// if the cell is a variable
|
|
||||||
float Acenter = 1.0f;
|
|
||||||
if (!skip[index])
|
|
||||||
{
|
|
||||||
// set the matrix to the Poisson stencil in order
|
|
||||||
if (!skip[index + 1]) Acenter += heatConst;
|
|
||||||
if (!skip[index - 1]) Acenter += heatConst;
|
|
||||||
if (!skip[index + _xRes]) Acenter += heatConst;
|
|
||||||
if (!skip[index - _xRes]) Acenter += heatConst;
|
|
||||||
if (!skip[index + _slabSize]) Acenter += heatConst;
|
|
||||||
if (!skip[index - _slabSize]) Acenter += heatConst;
|
|
||||||
}
|
|
||||||
|
|
||||||
_q[index] = (Acenter * _direction[index] +
|
|
||||||
_direction[index - 1] * (skip[index - 1] ? 0.0 : -heatConst) +
|
|
||||||
_direction[index + 1] * (skip[index + 1] ? 0.0 : -heatConst) +
|
|
||||||
_direction[index - _xRes] * (skip[index - _xRes] ? 0.0 : -heatConst) +
|
|
||||||
_direction[index + _xRes] * (skip[index + _xRes] ? 0.0 : -heatConst) +
|
|
||||||
_direction[index - _slabSize] * (skip[index - _slabSize] ? 0.0 : -heatConst) +
|
|
||||||
_direction[index + _slabSize] * (skip[index + _slabSize] ? 0.0 : -heatConst));
|
|
||||||
|
|
||||||
_q[index] = (skip[index]) ? 0.0f : _q[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
// alpha = deltaNew / (transpose(d) * q)
|
|
||||||
float alpha = 0.0f;
|
|
||||||
index = _slabSize + _xRes + 1;
|
|
||||||
for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
|
|
||||||
for (y = 1; y < _yRes - 1; y++, index += 2)
|
|
||||||
for (x = 1; x < _xRes - 1; x++, index++)
|
|
||||||
alpha += _direction[index] * _q[index];
|
|
||||||
if (fabs(alpha) > 0.0f)
|
|
||||||
alpha = deltaNew / alpha;
|
|
||||||
|
|
||||||
// x = x + alpha * d
|
|
||||||
index = _slabSize + _xRes + 1;
|
|
||||||
for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
|
|
||||||
for (y = 1; y < _yRes - 1; y++, index += 2)
|
|
||||||
for (x = 1; x < _xRes - 1; x++, index++)
|
|
||||||
field[index] += alpha * _direction[index];
|
|
||||||
|
|
||||||
// r = r - alpha * q
|
|
||||||
maxR = 0.0f;
|
|
||||||
index = _slabSize + _xRes + 1;
|
|
||||||
for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
|
|
||||||
for (y = 1; y < _yRes - 1; y++, index += 2)
|
|
||||||
for (x = 1; x < _xRes - 1; x++, index++)
|
|
||||||
{
|
|
||||||
_residual[index] -= alpha * _q[index];
|
|
||||||
maxR = (_residual[index] > maxR) ? _residual[index] : maxR;
|
|
||||||
}
|
|
||||||
|
|
||||||
// deltaOld = deltaNew
|
|
||||||
float deltaOld = deltaNew;
|
|
||||||
|
|
||||||
// deltaNew = transpose(r) * r
|
|
||||||
deltaNew = 0.0f;
|
|
||||||
index = _slabSize + _xRes + 1;
|
|
||||||
for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
|
|
||||||
for (y = 1; y < _yRes - 1; y++, index += 2)
|
|
||||||
for (x = 1; x < _xRes - 1; x++, index++)
|
|
||||||
deltaNew += _residual[index] * _residual[index];
|
|
||||||
|
|
||||||
// beta = deltaNew / deltaOld
|
|
||||||
float beta = deltaNew / deltaOld;
|
|
||||||
|
|
||||||
// d = r + beta * d
|
|
||||||
index = _slabSize + _xRes + 1;
|
|
||||||
for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
|
|
||||||
for (y = 1; y < _yRes - 1; y++, index += 2)
|
|
||||||
for (x = 1; x < _xRes - 1; x++, index++)
|
|
||||||
_direction[index] = _residual[index] + beta * _direction[index];
|
|
||||||
|
|
||||||
// i = i + 1
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
// cout << i << " iterations converged to " << maxR << endl;
|
|
||||||
|
|
||||||
if (_residual) delete[] _residual;
|
|
||||||
if (_direction) delete[] _direction;
|
|
||||||
if (_q) delete[] _q;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,11 @@
|
|||||||
// FLUID_3D.cpp: implementation of the static functions of the FLUID_3D class.
|
// FLUID_3D.cpp: implementation of the static functions of the FLUID_3D class.
|
||||||
//
|
//
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// Heavy parallel optimization done. Many of the old functions now
|
||||||
|
// take begin and end parameters and process only specified part of the data.
|
||||||
|
// Some functions were divided into multiple ones.
|
||||||
|
// - MiikaH
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
#include "FLUID_3D.h"
|
#include "FLUID_3D.h"
|
||||||
@@ -75,11 +80,11 @@ void FLUID_3D::addSmokeTestCase(float* field, Vec3Int res)
|
|||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// set x direction to Neumann boundary conditions
|
// set x direction to Neumann boundary conditions
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
void FLUID_3D::setNeumannX(float* field, Vec3Int res)
|
void FLUID_3D::setNeumannX(float* field, Vec3Int res, int zBegin, int zEnd)
|
||||||
{
|
{
|
||||||
const int slabSize = res[0] * res[1];
|
const int slabSize = res[0] * res[1];
|
||||||
int index;
|
int index;
|
||||||
for (int z = 0; z < res[2]; z++)
|
for (int z = zBegin; z < zEnd; z++)
|
||||||
for (int y = 0; y < res[1]; y++)
|
for (int y = 0; y < res[1]; y++)
|
||||||
{
|
{
|
||||||
// left slab
|
// left slab
|
||||||
@@ -93,7 +98,7 @@ void FLUID_3D::setNeumannX(float* field, Vec3Int res)
|
|||||||
|
|
||||||
// fix, force top slab to only allow outwards flux
|
// fix, force top slab to only allow outwards flux
|
||||||
for (int y = 0; y < res[1]; y++)
|
for (int y = 0; y < res[1]; y++)
|
||||||
for (int z = 0; z < res[2]; z++)
|
for (int z = zBegin; z < zEnd; z++)
|
||||||
{
|
{
|
||||||
// top slab
|
// top slab
|
||||||
index = y * res[0] + z * slabSize;
|
index = y * res[0] + z * slabSize;
|
||||||
@@ -107,11 +112,11 @@ void FLUID_3D::setNeumannX(float* field, Vec3Int res)
|
|||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// set y direction to Neumann boundary conditions
|
// set y direction to Neumann boundary conditions
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
void FLUID_3D::setNeumannY(float* field, Vec3Int res)
|
void FLUID_3D::setNeumannY(float* field, Vec3Int res, int zBegin, int zEnd)
|
||||||
{
|
{
|
||||||
const int slabSize = res[0] * res[1];
|
const int slabSize = res[0] * res[1];
|
||||||
int index;
|
int index;
|
||||||
for (int z = 0; z < res[2]; z++)
|
for (int z = zBegin; z < zEnd; z++)
|
||||||
for (int x = 0; x < res[0]; x++)
|
for (int x = 0; x < res[0]; x++)
|
||||||
{
|
{
|
||||||
// bottom slab
|
// bottom slab
|
||||||
@@ -124,7 +129,7 @@ void FLUID_3D::setNeumannY(float* field, Vec3Int res)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// fix, force top slab to only allow outwards flux
|
// fix, force top slab to only allow outwards flux
|
||||||
for (int z = 0; z < res[2]; z++)
|
for (int z = zBegin; z < zEnd; z++)
|
||||||
for (int x = 0; x < res[0]; x++)
|
for (int x = 0; x < res[0]; x++)
|
||||||
{
|
{
|
||||||
// top slab
|
// top slab
|
||||||
@@ -140,22 +145,36 @@ void FLUID_3D::setNeumannY(float* field, Vec3Int res)
|
|||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// set z direction to Neumann boundary conditions
|
// set z direction to Neumann boundary conditions
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
void FLUID_3D::setNeumannZ(float* field, Vec3Int res)
|
void FLUID_3D::setNeumannZ(float* field, Vec3Int res, int zBegin, int zEnd)
|
||||||
{
|
{
|
||||||
const int slabSize = res[0] * res[1];
|
const int slabSize = res[0] * res[1];
|
||||||
const int totalCells = res[0] * res[1] * res[2];
|
const int totalCells = res[0] * res[1] * res[2];
|
||||||
|
const int cellsslab = totalCells - slabSize;
|
||||||
int index;
|
int index;
|
||||||
|
|
||||||
|
index = 0;
|
||||||
|
if (zBegin == 0)
|
||||||
for (int y = 0; y < res[1]; y++)
|
for (int y = 0; y < res[1]; y++)
|
||||||
for (int x = 0; x < res[0]; x++)
|
for (int x = 0; x < res[0]; x++, index++)
|
||||||
{
|
{
|
||||||
// front slab
|
// front slab
|
||||||
index = x + y * res[0];
|
|
||||||
field[index] = field[index + 2 * slabSize];
|
field[index] = field[index + 2 * slabSize];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (zEnd == res[2])
|
||||||
|
{
|
||||||
|
index = 0;
|
||||||
|
int indexx = 0;
|
||||||
|
|
||||||
|
for (int y = 0; y < res[1]; y++)
|
||||||
|
for (int x = 0; x < res[0]; x++, index++)
|
||||||
|
{
|
||||||
|
|
||||||
// back slab
|
// back slab
|
||||||
index += totalCells - slabSize;
|
indexx = index + cellsslab;
|
||||||
field[index] = field[index - 2 * slabSize];
|
field[indexx] = field[indexx - 2 * slabSize];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// fix, force top slab to only allow outwards flux
|
// fix, force top slab to only allow outwards flux
|
||||||
for (int y = 0; y < res[1]; y++)
|
for (int y = 0; y < res[1]; y++)
|
||||||
@@ -163,22 +182,24 @@ void FLUID_3D::setNeumannZ(float* field, Vec3Int res)
|
|||||||
{
|
{
|
||||||
// top slab
|
// top slab
|
||||||
index = x + y * res[0];
|
index = x + y * res[0];
|
||||||
index += totalCells - slabSize;
|
index += cellsslab;
|
||||||
if(field[index]<0.) field[index] = 0.;
|
if(field[index]<0.) field[index] = 0.;
|
||||||
index -= slabSize;
|
index -= slabSize;
|
||||||
if(field[index]<0.) field[index] = 0.;
|
if(field[index]<0.) field[index] = 0.;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // zEnd == res[2]
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// set x direction to zero
|
// set x direction to zero
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
void FLUID_3D::setZeroX(float* field, Vec3Int res)
|
void FLUID_3D::setZeroX(float* field, Vec3Int res, int zBegin, int zEnd)
|
||||||
{
|
{
|
||||||
const int slabSize = res[0] * res[1];
|
const int slabSize = res[0] * res[1];
|
||||||
int index;
|
int index;
|
||||||
for (int z = 0; z < res[2]; z++)
|
for (int z = zBegin; z < zEnd; z++)
|
||||||
for (int y = 0; y < res[1]; y++)
|
for (int y = 0; y < res[1]; y++)
|
||||||
{
|
{
|
||||||
// left slab
|
// left slab
|
||||||
@@ -194,11 +215,11 @@ void FLUID_3D::setZeroX(float* field, Vec3Int res)
|
|||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// set y direction to zero
|
// set y direction to zero
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
void FLUID_3D::setZeroY(float* field, Vec3Int res)
|
void FLUID_3D::setZeroY(float* field, Vec3Int res, int zBegin, int zEnd)
|
||||||
{
|
{
|
||||||
const int slabSize = res[0] * res[1];
|
const int slabSize = res[0] * res[1];
|
||||||
int index;
|
int index;
|
||||||
for (int z = 0; z < res[2]; z++)
|
for (int z = zBegin; z < zEnd; z++)
|
||||||
for (int x = 0; x < res[0]; x++)
|
for (int x = 0; x < res[0]; x++)
|
||||||
{
|
{
|
||||||
// bottom slab
|
// bottom slab
|
||||||
@@ -214,32 +235,44 @@ void FLUID_3D::setZeroY(float* field, Vec3Int res)
|
|||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// set z direction to zero
|
// set z direction to zero
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
void FLUID_3D::setZeroZ(float* field, Vec3Int res)
|
void FLUID_3D::setZeroZ(float* field, Vec3Int res, int zBegin, int zEnd)
|
||||||
{
|
{
|
||||||
const int slabSize = res[0] * res[1];
|
const int slabSize = res[0] * res[1];
|
||||||
const int totalCells = res[0] * res[1] * res[2];
|
const int totalCells = res[0] * res[1] * res[2];
|
||||||
int index;
|
|
||||||
|
int index = 0;
|
||||||
|
if ((zBegin == 0))
|
||||||
for (int y = 0; y < res[1]; y++)
|
for (int y = 0; y < res[1]; y++)
|
||||||
for (int x = 0; x < res[0]; x++)
|
for (int x = 0; x < res[0]; x++, index++)
|
||||||
{
|
{
|
||||||
// front slab
|
// front slab
|
||||||
index = x + y * res[0];
|
|
||||||
field[index] = 0.0f;
|
field[index] = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
// back slab
|
if (zEnd == res[2])
|
||||||
index += totalCells - slabSize;
|
{
|
||||||
field[index] = 0.0f;
|
index=0;
|
||||||
}
|
int indexx=0;
|
||||||
|
const int cellsslab = totalCells - slabSize;
|
||||||
|
|
||||||
|
for (int y = 0; y < res[1]; y++)
|
||||||
|
for (int x = 0; x < res[0]; x++, index++)
|
||||||
|
{
|
||||||
|
|
||||||
|
// back slab
|
||||||
|
indexx = index + cellsslab;
|
||||||
|
field[indexx] = 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// copy grid boundary
|
// copy grid boundary
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
void FLUID_3D::copyBorderX(float* field, Vec3Int res)
|
void FLUID_3D::copyBorderX(float* field, Vec3Int res, int zBegin, int zEnd)
|
||||||
{
|
{
|
||||||
const int slabSize = res[0] * res[1];
|
const int slabSize = res[0] * res[1];
|
||||||
int index;
|
int index;
|
||||||
for (int z = 0; z < res[2]; z++)
|
for (int z = zBegin; z < zEnd; z++)
|
||||||
for (int y = 0; y < res[1]; y++)
|
for (int y = 0; y < res[1]; y++)
|
||||||
{
|
{
|
||||||
// left slab
|
// left slab
|
||||||
@@ -251,12 +284,12 @@ void FLUID_3D::copyBorderX(float* field, Vec3Int res)
|
|||||||
field[index] = field[index - 1];
|
field[index] = field[index - 1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void FLUID_3D::copyBorderY(float* field, Vec3Int res)
|
void FLUID_3D::copyBorderY(float* field, Vec3Int res, int zBegin, int zEnd)
|
||||||
{
|
{
|
||||||
const int slabSize = res[0] * res[1];
|
const int slabSize = res[0] * res[1];
|
||||||
const int totalCells = res[0] * res[1] * res[2];
|
//const int totalCells = res[0] * res[1] * res[2];
|
||||||
int index;
|
int index;
|
||||||
for (int z = 0; z < res[2]; z++)
|
for (int z = zBegin; z < zEnd; z++)
|
||||||
for (int x = 0; x < res[0]; x++)
|
for (int x = 0; x < res[0]; x++)
|
||||||
{
|
{
|
||||||
// bottom slab
|
// bottom slab
|
||||||
@@ -267,40 +300,49 @@ void FLUID_3D::copyBorderY(float* field, Vec3Int res)
|
|||||||
field[index] = field[index - res[0]];
|
field[index] = field[index - res[0]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void FLUID_3D::copyBorderZ(float* field, Vec3Int res)
|
void FLUID_3D::copyBorderZ(float* field, Vec3Int res, int zBegin, int zEnd)
|
||||||
{
|
{
|
||||||
const int slabSize = res[0] * res[1];
|
const int slabSize = res[0] * res[1];
|
||||||
const int totalCells = res[0] * res[1] * res[2];
|
const int totalCells = res[0] * res[1] * res[2];
|
||||||
int index;
|
int index=0;
|
||||||
|
|
||||||
|
if ((zBegin == 0))
|
||||||
for (int y = 0; y < res[1]; y++)
|
for (int y = 0; y < res[1]; y++)
|
||||||
for (int x = 0; x < res[0]; x++)
|
for (int x = 0; x < res[0]; x++, index++)
|
||||||
{
|
{
|
||||||
// front slab
|
|
||||||
index = x + y * res[0];
|
|
||||||
field[index] = field[index + slabSize];
|
field[index] = field[index + slabSize];
|
||||||
// back slab
|
|
||||||
index += totalCells - slabSize;
|
|
||||||
field[index] = field[index - slabSize];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((zEnd == res[2]))
|
||||||
|
{
|
||||||
|
|
||||||
|
index=0;
|
||||||
|
int indexx=0;
|
||||||
|
const int cellsslab = totalCells - slabSize;
|
||||||
|
|
||||||
|
for (int y = 0; y < res[1]; y++)
|
||||||
|
for (int x = 0; x < res[0]; x++, index++)
|
||||||
|
{
|
||||||
|
// back slab
|
||||||
|
indexx = index + cellsslab;
|
||||||
|
field[indexx] = field[indexx - slabSize];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
||||||
// advect field with the semi lagrangian method
|
// advect field with the semi lagrangian method
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
void FLUID_3D::advectFieldSemiLagrange(const float dt, const float* velx, const float* vely, const float* velz,
|
void FLUID_3D::advectFieldSemiLagrange(const float dt, const float* velx, const float* vely, const float* velz,
|
||||||
float* oldField, float* newField, Vec3Int res)
|
float* oldField, float* newField, Vec3Int res, int zBegin, int zEnd)
|
||||||
{
|
{
|
||||||
const int xres = res[0];
|
const int xres = res[0];
|
||||||
const int yres = res[1];
|
const int yres = res[1];
|
||||||
const int zres = res[2];
|
const int zres = res[2];
|
||||||
const int slabSize = res[0] * res[1];
|
const int slabSize = res[0] * res[1];
|
||||||
|
|
||||||
// scale dt up to grid resolution
|
|
||||||
#if PARALLEL==1 && !_WIN32
|
for (int z = zBegin; z < zEnd; z++)
|
||||||
#pragma omp parallel
|
|
||||||
#pragma omp for schedule(static)
|
|
||||||
#endif
|
|
||||||
for (int z = 0; z < zres; z++)
|
|
||||||
for (int y = 0; y < yres; y++)
|
for (int y = 0; y < yres; y++)
|
||||||
for (int x = 0; x < xres; x++)
|
for (int x = 0; x < xres; x++)
|
||||||
{
|
{
|
||||||
@@ -357,50 +399,69 @@ void FLUID_3D::advectFieldSemiLagrange(const float dt, const float* velx, const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
||||||
// advect field with the maccormack method
|
// advect field with the maccormack method
|
||||||
//
|
//
|
||||||
// comments are the pseudocode from selle's paper
|
// comments are the pseudocode from selle's paper
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
void FLUID_3D::advectFieldMacCormack(const float dt, const float* xVelocity, const float* yVelocity, const float* zVelocity,
|
void FLUID_3D::advectFieldMacCormack1(const float dt, const float* xVelocity, const float* yVelocity, const float* zVelocity,
|
||||||
float* oldField, float* newField, float* temp1, float* temp2, Vec3Int res, const unsigned char* obstacles)
|
float* oldField, float* tempResult, Vec3Int res, int zBegin, int zEnd)
|
||||||
{
|
{
|
||||||
float* phiHatN = temp1;
|
|
||||||
float* phiHatN1 = temp2;
|
|
||||||
const int sx= res[0];
|
const int sx= res[0];
|
||||||
const int sy= res[1];
|
const int sy= res[1];
|
||||||
const int sz= res[2];
|
const int sz= res[2];
|
||||||
|
|
||||||
for (int x = 0; x < sx * sy * sz; x++)
|
/*for (int x = 0; x < sx * sy * sz; x++)
|
||||||
phiHatN[x] = phiHatN1[x] = oldField[x];
|
phiHatN[x] = phiHatN1[x] = oldField[x];*/ // not needed as all the values are written first
|
||||||
|
|
||||||
|
float*& phiN = oldField;
|
||||||
|
float*& phiN1 = tempResult;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// phiHatN1 = A(phiN)
|
||||||
|
advectFieldSemiLagrange( dt, xVelocity, yVelocity, zVelocity, phiN, phiN1, res, zBegin, zEnd); // uses wide data from old field and velocities (both are whole)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void FLUID_3D::advectFieldMacCormack2(const float dt, const float* xVelocity, const float* yVelocity, const float* zVelocity,
|
||||||
|
float* oldField, float* newField, float* tempResult, float* temp1, Vec3Int res, const unsigned char* obstacles, int zBegin, int zEnd)
|
||||||
|
{
|
||||||
|
float* phiHatN = tempResult;
|
||||||
|
float* t1 = temp1;
|
||||||
|
const int sx= res[0];
|
||||||
|
const int sy= res[1];
|
||||||
|
const int sz= res[2];
|
||||||
|
|
||||||
float*& phiN = oldField;
|
float*& phiN = oldField;
|
||||||
float*& phiN1 = newField;
|
float*& phiN1 = newField;
|
||||||
|
|
||||||
// phiHatN1 = A(phiN)
|
|
||||||
advectFieldSemiLagrange( dt, xVelocity, yVelocity, zVelocity, phiN, phiHatN1, res);
|
|
||||||
|
|
||||||
// phiHatN = A^R(phiHatN1)
|
// phiHatN = A^R(phiHatN1)
|
||||||
advectFieldSemiLagrange( -1.0*dt, xVelocity, yVelocity, zVelocity, phiHatN1, phiHatN, res);
|
advectFieldSemiLagrange( -1.0*dt, xVelocity, yVelocity, zVelocity, phiHatN, t1, res, zBegin, zEnd); // uses wide data from old field and velocities (both are whole)
|
||||||
|
|
||||||
// phiN1 = phiHatN1 + (phiN - phiHatN) / 2
|
// phiN1 = phiHatN1 + (phiN - phiHatN) / 2
|
||||||
const int border = 0;
|
const int border = 0;
|
||||||
for (int z = border; z < sz-border; z++)
|
for (int z = zBegin+border; z < zEnd-border; z++)
|
||||||
for (int y = border; y < sy-border; y++)
|
for (int y = border; y < sy-border; y++)
|
||||||
for (int x = border; x < sx-border; x++) {
|
for (int x = border; x < sx-border; x++) {
|
||||||
int index = x + y * sx + z * sx*sy;
|
int index = x + y * sx + z * sx*sy;
|
||||||
phiN1[index] = phiHatN1[index] + (phiN[index] - phiHatN[index]) * 0.50f;
|
phiN1[index] = phiHatN[index] + (phiN[index] - t1[index]) * 0.50f;
|
||||||
//phiN1[index] = phiHatN1[index]; // debug, correction off
|
//phiN1[index] = phiHatN1[index]; // debug, correction off
|
||||||
}
|
}
|
||||||
copyBorderX(phiN1, res);
|
copyBorderX(phiN1, res, zBegin, zEnd);
|
||||||
copyBorderY(phiN1, res);
|
copyBorderY(phiN1, res, zBegin, zEnd);
|
||||||
copyBorderZ(phiN1, res);
|
copyBorderZ(phiN1, res, zBegin, zEnd);
|
||||||
|
|
||||||
// clamp any newly created extrema
|
// clamp any newly created extrema
|
||||||
clampExtrema(dt, xVelocity, yVelocity, zVelocity, oldField, newField, res);
|
clampExtrema(dt, xVelocity, yVelocity, zVelocity, oldField, newField, res, zBegin, zEnd); // uses wide data from old field and velocities (both are whole)
|
||||||
|
|
||||||
// if the error estimate was bad, revert to first order
|
// if the error estimate was bad, revert to first order
|
||||||
clampOutsideRays(dt, xVelocity, yVelocity, zVelocity, oldField, newField, res, obstacles, phiHatN1);
|
clampOutsideRays(dt, xVelocity, yVelocity, zVelocity, oldField, newField, res, obstacles, phiHatN, zBegin, zEnd); // phiHatN is only used at cells within thread range, so its ok
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -408,13 +469,21 @@ void FLUID_3D::advectFieldMacCormack(const float dt, const float* xVelocity, con
|
|||||||
// Clamp the extrema generated by the BFECC error correction
|
// Clamp the extrema generated by the BFECC error correction
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
void FLUID_3D::clampExtrema(const float dt, const float* velx, const float* vely, const float* velz,
|
void FLUID_3D::clampExtrema(const float dt, const float* velx, const float* vely, const float* velz,
|
||||||
float* oldField, float* newField, Vec3Int res)
|
float* oldField, float* newField, Vec3Int res, int zBegin, int zEnd)
|
||||||
{
|
{
|
||||||
const int xres= res[0];
|
const int xres= res[0];
|
||||||
const int yres= res[1];
|
const int yres= res[1];
|
||||||
const int zres= res[2];
|
const int zres= res[2];
|
||||||
const int slabSize = res[0] * res[1];
|
const int slabSize = res[0] * res[1];
|
||||||
for (int z = 1; z < zres-1; z++)
|
|
||||||
|
int bb=0;
|
||||||
|
int bt=0;
|
||||||
|
|
||||||
|
if (zBegin == 0) {bb = 1;}
|
||||||
|
if (zEnd == res[2]) {bt = 1;}
|
||||||
|
|
||||||
|
|
||||||
|
for (int z = zBegin+bb; z < zEnd-bt; z++)
|
||||||
for (int y = 1; y < yres-1; y++)
|
for (int y = 1; y < yres-1; y++)
|
||||||
for (int x = 1; x < xres-1; x++)
|
for (int x = 1; x < xres-1; x++)
|
||||||
{
|
{
|
||||||
@@ -484,14 +553,20 @@ void FLUID_3D::clampExtrema(const float dt, const float* velx, const float* vely
|
|||||||
// incorrect
|
// incorrect
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
void FLUID_3D::clampOutsideRays(const float dt, const float* velx, const float* vely, const float* velz,
|
void FLUID_3D::clampOutsideRays(const float dt, const float* velx, const float* vely, const float* velz,
|
||||||
float* oldField, float* newField, Vec3Int res, const unsigned char* obstacles, const float *oldAdvection)
|
float* oldField, float* newField, Vec3Int res, const unsigned char* obstacles, const float *oldAdvection, int zBegin, int zEnd)
|
||||||
{
|
{
|
||||||
const int sx= res[0];
|
const int sx= res[0];
|
||||||
const int sy= res[1];
|
const int sy= res[1];
|
||||||
const int sz= res[2];
|
const int sz= res[2];
|
||||||
const int slabSize = res[0] * res[1];
|
const int slabSize = res[0] * res[1];
|
||||||
|
|
||||||
for (int z = 1; z < sz-1; z++)
|
int bb=0;
|
||||||
|
int bt=0;
|
||||||
|
|
||||||
|
if (zBegin == 0) {bb = 1;}
|
||||||
|
if (zEnd == res[2]) {bt = 1;}
|
||||||
|
|
||||||
|
for (int z = zBegin+bb; z < zEnd-bt; z++)
|
||||||
for (int y = 1; y < sy-1; y++)
|
for (int y = 1; y < sy-1; y++)
|
||||||
for (int x = 1; x < sx-1; x++)
|
for (int x = 1; x < sx-1; x++)
|
||||||
{
|
{
|
||||||
@@ -607,4 +682,3 @@ void FLUID_3D::clampOutsideRays(const float dt, const float* velx, const float*
|
|||||||
}
|
}
|
||||||
} // xyz
|
} // xyz
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
136
intern/smoke/intern/LU_HELPER.cpp
Normal file
136
intern/smoke/intern/LU_HELPER.cpp
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
|
||||||
|
#include "LU_HELPER.h"
|
||||||
|
|
||||||
|
int isNonsingular (sLU LU_) {
|
||||||
|
for (int j = 0; j < 3; j++) {
|
||||||
|
if (LU_.values[j][j] == 0)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
sLU computeLU( float a[3][3])
|
||||||
|
{
|
||||||
|
sLU result;
|
||||||
|
int m=3;
|
||||||
|
int n=3;
|
||||||
|
|
||||||
|
//float LU_[3][3];
|
||||||
|
for (int i = 0; i < m; i++) {
|
||||||
|
result.piv[i] = i;
|
||||||
|
for (int j = 0; j < n; j++) result.values[i][j]=a[i][j];
|
||||||
|
}
|
||||||
|
|
||||||
|
result.pivsign = 1;
|
||||||
|
//Real *LUrowi = 0;;
|
||||||
|
//Array1D<Real> LUcolj(m);
|
||||||
|
//float *LUrowi = 0;
|
||||||
|
float LUcolj[3];
|
||||||
|
|
||||||
|
// Outer loop.
|
||||||
|
|
||||||
|
for (int j = 0; j < n; j++) {
|
||||||
|
|
||||||
|
// Make a copy of the j-th column to localize references.
|
||||||
|
|
||||||
|
for (int i = 0; i < m; i++) {
|
||||||
|
LUcolj[i] = result.values[i][j];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply previous transformations.
|
||||||
|
|
||||||
|
for (int i = 0; i < m; i++) {
|
||||||
|
//float LUrowi[3];
|
||||||
|
//LUrowi = result.values[i];
|
||||||
|
|
||||||
|
// Most of the time is spent in the following dot product.
|
||||||
|
|
||||||
|
int kmax = min(i,j);
|
||||||
|
double s = 0.0;
|
||||||
|
for (int k = 0; k < kmax; k++) {
|
||||||
|
s += result.values[i][k]*LUcolj[k];
|
||||||
|
}
|
||||||
|
|
||||||
|
result.values[i][j] = LUcolj[i] -= s;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find pivot and exchange if necessary.
|
||||||
|
|
||||||
|
int p = j;
|
||||||
|
for (int i = j+1; i < m; i++) {
|
||||||
|
if (abs(LUcolj[i]) > abs(LUcolj[p])) {
|
||||||
|
p = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (p != j) {
|
||||||
|
int k=0;
|
||||||
|
for (k = 0; k < n; k++) {
|
||||||
|
double t = result.values[p][k];
|
||||||
|
result.values[p][k] = result.values[j][k];
|
||||||
|
result.values[j][k] = t;
|
||||||
|
}
|
||||||
|
k = result.piv[p];
|
||||||
|
result.piv[p] = result.piv[j];
|
||||||
|
result.piv[j] = k;
|
||||||
|
result.pivsign = -result.pivsign;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute multipliers.
|
||||||
|
|
||||||
|
if ((j < m) && (result.values[j][j] != 0.0)) {
|
||||||
|
for (int i = j+1; i < m; i++) {
|
||||||
|
result.values[i][j] /= result.values[j][j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void solveLU3x3(sLU& A, float x[3], float b[3])
|
||||||
|
{
|
||||||
|
//TNT::Array1D<float> jamaB = TNT::Array1D<float>(3, &b[0]);
|
||||||
|
//TNT::Array1D<float> jamaX = A.solve(jamaB);
|
||||||
|
|
||||||
|
|
||||||
|
// Solve A, B
|
||||||
|
|
||||||
|
{
|
||||||
|
if (!isNonsingular(A)) {
|
||||||
|
x[0]=0.0f;
|
||||||
|
x[1]=0.0f;
|
||||||
|
x[2]=0.0f;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Array1D<Real> Ax = permute_copy(b, piv);
|
||||||
|
float Ax[3];
|
||||||
|
|
||||||
|
// permute copy: b , A.piv
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
Ax[i] = b[A.piv[i]];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Solve L*Y = B(piv)
|
||||||
|
for (int k = 0; k < 3; k++) {
|
||||||
|
for (int i = k+1; i < 3; i++) {
|
||||||
|
Ax[i] -= Ax[k]*A.values[i][k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Solve U*X = Y;
|
||||||
|
for (int k = 2; k >= 0; k--) {
|
||||||
|
Ax[k] /= A.values[k][k];
|
||||||
|
for (int i = 0; i < k; i++)
|
||||||
|
Ax[i] -= Ax[k]*A.values[i][k];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
x[0] = Ax[0];
|
||||||
|
x[1] = Ax[1];
|
||||||
|
x[2] = Ax[2];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,40 +17,35 @@
|
|||||||
// Copyright 2008 Theodore Kim and Nils Thuerey
|
// Copyright 2008 Theodore Kim and Nils Thuerey
|
||||||
//
|
//
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// Modified to not require TNT matrix library anymore. It was very slow
|
||||||
|
// when being run in parallel. Required TNT JAMA:LU libraries were
|
||||||
|
// converted into independent functions.
|
||||||
|
// - MiikaH
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#ifndef LU_HELPER_H
|
#ifndef LU_HELPER_H
|
||||||
#define LU_HELPER_H
|
#define LU_HELPER_H
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// Helper function, compute eigenvalues of 3x3 matrix
|
// Helper function, compute eigenvalues of 3x3 matrix
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include "tnt/jama_lu.h"
|
struct sLU
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
|
||||||
// LU decomposition of 3x3 non-symmetric matrix
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
|
||||||
JAMA::LU<float> inline computeLU3x3(
|
|
||||||
float a[3][3])
|
|
||||||
{
|
{
|
||||||
TNT::Array2D<float> A = TNT::Array2D<float>(3,3, &a[0][0]);
|
float values[3][3];
|
||||||
JAMA::LU<float> jLU= JAMA::LU<float>(A);
|
int pivsign;
|
||||||
return jLU;
|
int piv[3];
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int isNonsingular (sLU LU_);
|
||||||
|
sLU computeLU( float a[3][3]);
|
||||||
|
void solveLU3x3(sLU& A, float x[3], float b[3]);
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
|
||||||
// LU decomposition of 3x3 non-symmetric matrix
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
|
||||||
void inline solveLU3x3(
|
|
||||||
JAMA::LU<float>& A,
|
|
||||||
float x[3],
|
|
||||||
float b[3])
|
|
||||||
{
|
|
||||||
TNT::Array1D<float> jamaB = TNT::Array1D<float>(3, &b[0]);
|
|
||||||
TNT::Array1D<float> jamaX = A.solve(jamaB);
|
|
||||||
|
|
||||||
x[0] = jamaX[0];
|
|
||||||
x[1] = jamaX[1];
|
|
||||||
x[2] = jamaX[2];
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -18,6 +18,10 @@
|
|||||||
//
|
//
|
||||||
// WTURBULENCE handling
|
// WTURBULENCE handling
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Parallelized turbulence even further. TNT matrix library functions
|
||||||
|
// rewritten to improve performance.
|
||||||
|
// - MiikaH
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include "WTURBULENCE.h"
|
#include "WTURBULENCE.h"
|
||||||
#include "INTERPOLATE.h"
|
#include "INTERPOLATE.h"
|
||||||
@@ -29,6 +33,7 @@
|
|||||||
#include "LU_HELPER.h"
|
#include "LU_HELPER.h"
|
||||||
#include "SPHERE.h"
|
#include "SPHERE.h"
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
// needed to access static advection functions
|
// needed to access static advection functions
|
||||||
#include "FLUID_3D.h"
|
#include "FLUID_3D.h"
|
||||||
@@ -278,27 +283,34 @@ static float minDz(int x, int y, int z, float* input, Vec3Int res)
|
|||||||
// Beware -- uses big density maccormack as temporary arrays
|
// Beware -- uses big density maccormack as temporary arrays
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
void WTURBULENCE::advectTextureCoordinates (float dtOrg, float* xvel, float* yvel, float* zvel, float *tempBig1, float *tempBig2) {
|
void WTURBULENCE::advectTextureCoordinates (float dtOrg, float* xvel, float* yvel, float* zvel, float *tempBig1, float *tempBig2) {
|
||||||
|
|
||||||
// advection
|
// advection
|
||||||
SWAP_POINTERS(_tcTemp, _tcU);
|
SWAP_POINTERS(_tcTemp, _tcU);
|
||||||
FLUID_3D::copyBorderX(_tcTemp, _resSm);
|
FLUID_3D::copyBorderX(_tcTemp, _resSm, 0 , _resSm[2]);
|
||||||
FLUID_3D::copyBorderY(_tcTemp, _resSm);
|
FLUID_3D::copyBorderY(_tcTemp, _resSm, 0 , _resSm[2]);
|
||||||
FLUID_3D::copyBorderZ(_tcTemp, _resSm);
|
FLUID_3D::copyBorderZ(_tcTemp, _resSm, 0 , _resSm[2]);
|
||||||
FLUID_3D::advectFieldMacCormack(dtOrg, xvel, yvel, zvel,
|
FLUID_3D::advectFieldMacCormack1(dtOrg, xvel, yvel, zvel,
|
||||||
_tcTemp, _tcU, tempBig1, tempBig2, _resSm, NULL);
|
_tcTemp, tempBig1, _resSm, 0 , _resSm[2]);
|
||||||
|
FLUID_3D::advectFieldMacCormack2(dtOrg, xvel, yvel, zvel,
|
||||||
|
_tcTemp, _tcU, tempBig1, tempBig2, _resSm, NULL, 0 , _resSm[2]);
|
||||||
|
|
||||||
SWAP_POINTERS(_tcTemp, _tcV);
|
SWAP_POINTERS(_tcTemp, _tcV);
|
||||||
FLUID_3D::copyBorderX(_tcTemp, _resSm);
|
FLUID_3D::copyBorderX(_tcTemp, _resSm, 0 , _resSm[2]);
|
||||||
FLUID_3D::copyBorderY(_tcTemp, _resSm);
|
FLUID_3D::copyBorderY(_tcTemp, _resSm, 0 , _resSm[2]);
|
||||||
FLUID_3D::copyBorderZ(_tcTemp, _resSm);
|
FLUID_3D::copyBorderZ(_tcTemp, _resSm, 0 , _resSm[2]);
|
||||||
FLUID_3D::advectFieldMacCormack(dtOrg, xvel, yvel, zvel,
|
FLUID_3D::advectFieldMacCormack1(dtOrg, xvel, yvel, zvel,
|
||||||
_tcTemp, _tcV, tempBig1, tempBig2, _resSm, NULL);
|
_tcTemp, tempBig1, _resSm, 0 , _resSm[2]);
|
||||||
|
FLUID_3D::advectFieldMacCormack2(dtOrg, xvel, yvel, zvel,
|
||||||
|
_tcTemp, _tcV, tempBig1, tempBig2, _resSm, NULL, 0 , _resSm[2]);
|
||||||
|
|
||||||
SWAP_POINTERS(_tcTemp, _tcW);
|
SWAP_POINTERS(_tcTemp, _tcW);
|
||||||
FLUID_3D::copyBorderX(_tcTemp, _resSm);
|
FLUID_3D::copyBorderX(_tcTemp, _resSm, 0 , _resSm[2]);
|
||||||
FLUID_3D::copyBorderY(_tcTemp, _resSm);
|
FLUID_3D::copyBorderY(_tcTemp, _resSm, 0 , _resSm[2]);
|
||||||
FLUID_3D::copyBorderZ(_tcTemp, _resSm);
|
FLUID_3D::copyBorderZ(_tcTemp, _resSm, 0 , _resSm[2]);
|
||||||
FLUID_3D::advectFieldMacCormack(dtOrg, xvel, yvel, zvel,
|
FLUID_3D::advectFieldMacCormack1(dtOrg, xvel, yvel, zvel,
|
||||||
_tcTemp, _tcW, tempBig1, tempBig2, _resSm, NULL);
|
_tcTemp, tempBig1, _resSm, 0 , _resSm[2]);
|
||||||
|
FLUID_3D::advectFieldMacCormack2(dtOrg, xvel, yvel, zvel,
|
||||||
|
_tcTemp, _tcW, tempBig1, tempBig2, _resSm, NULL, 0 , _resSm[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
@@ -325,9 +337,9 @@ void WTURBULENCE::computeEigenvalues(float *_eigMin, float *_eigMax) {
|
|||||||
|
|
||||||
// ONLY compute the eigenvalues after checking that the matrix
|
// ONLY compute the eigenvalues after checking that the matrix
|
||||||
// is nonsingular
|
// is nonsingular
|
||||||
JAMA::LU<float> LU = computeLU3x3(jacobian);
|
sLU LU = computeLU(jacobian);
|
||||||
|
|
||||||
if (LU.isNonsingular())
|
if (isNonsingular(LU))
|
||||||
{
|
{
|
||||||
// get the analytic eigenvalues, quite slow right now...
|
// get the analytic eigenvalues, quite slow right now...
|
||||||
Vec3 eigenvalues = Vec3(1.);
|
Vec3 eigenvalues = Vec3(1.);
|
||||||
@@ -422,9 +434,9 @@ void WTURBULENCE::computeEnergy(float *_energy, float* xvel, float* yvel, float*
|
|||||||
for (int x = 0; x < _totalCellsSm; x++)
|
for (int x = 0; x < _totalCellsSm; x++)
|
||||||
_energy[x] = 0.5f * (xvel[x] * xvel[x] + yvel[x] * yvel[x] + zvel[x] * zvel[x]);
|
_energy[x] = 0.5f * (xvel[x] * xvel[x] + yvel[x] * yvel[x] + zvel[x] * zvel[x]);
|
||||||
|
|
||||||
FLUID_3D::copyBorderX(_energy, _resSm);
|
FLUID_3D::copyBorderX(_energy, _resSm, 0 , _resSm[2]);
|
||||||
FLUID_3D::copyBorderY(_energy, _resSm);
|
FLUID_3D::copyBorderY(_energy, _resSm, 0 , _resSm[2]);
|
||||||
FLUID_3D::copyBorderZ(_energy, _resSm);
|
FLUID_3D::copyBorderZ(_energy, _resSm, 0 , _resSm[2]);
|
||||||
|
|
||||||
// pseudo-march the values into the obstacles
|
// pseudo-march the values into the obstacles
|
||||||
// the wavelet upsampler only uses a 3x3 support neighborhood, so
|
// the wavelet upsampler only uses a 3x3 support neighborhood, so
|
||||||
@@ -563,7 +575,7 @@ Vec3 WTURBULENCE::WVelocityWithJacobian(Vec3 orgPos, float* xUnwarped, float* yU
|
|||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// perform an actual noise advection step
|
// perform an actual noise advection step
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
void WTURBULENCE::stepTurbulenceReadable(float dtOrg, float* xvel, float* yvel, float* zvel, unsigned char *obstacles)
|
/*void WTURBULENCE::stepTurbulenceReadable(float dtOrg, float* xvel, float* yvel, float* zvel, unsigned char *obstacles)
|
||||||
{
|
{
|
||||||
// enlarge timestep to match grid
|
// enlarge timestep to match grid
|
||||||
const float dt = dtOrg * _amplify;
|
const float dt = dtOrg * _amplify;
|
||||||
@@ -689,9 +701,9 @@ void WTURBULENCE::stepTurbulenceReadable(float dtOrg, float* xvel, float* yvel,
|
|||||||
const float dtSubdiv = dt / (float)totalSubsteps;
|
const float dtSubdiv = dt / (float)totalSubsteps;
|
||||||
|
|
||||||
// set boundaries of big velocity grid
|
// set boundaries of big velocity grid
|
||||||
FLUID_3D::setZeroX(bigUx, _resBig);
|
FLUID_3D::setZeroX(bigUx, _resBig, 0, _resBig[2]);
|
||||||
FLUID_3D::setZeroY(bigUy, _resBig);
|
FLUID_3D::setZeroY(bigUy, _resBig, 0, _resBig[2]);
|
||||||
FLUID_3D::setZeroZ(bigUz, _resBig);
|
FLUID_3D::setZeroZ(bigUz, _resBig, 0, _resBig[2]);
|
||||||
|
|
||||||
// do the MacCormack advection, with substepping if necessary
|
// do the MacCormack advection, with substepping if necessary
|
||||||
for(int substep = 0; substep < totalSubsteps; substep++)
|
for(int substep = 0; substep < totalSubsteps; substep++)
|
||||||
@@ -704,7 +716,7 @@ void WTURBULENCE::stepTurbulenceReadable(float dtOrg, float* xvel, float* yvel,
|
|||||||
} // substep
|
} // substep
|
||||||
|
|
||||||
// wipe the density borders
|
// wipe the density borders
|
||||||
FLUID_3D::setZeroBorder(_densityBig, _resBig);
|
FLUID_3D::setZeroBorder(_densityBig, _resBig, 0, _resBig[2]);
|
||||||
|
|
||||||
// reset texture coordinates now in preparation for next timestep
|
// reset texture coordinates now in preparation for next timestep
|
||||||
// Shouldn't do this before generating the noise because then the
|
// Shouldn't do this before generating the noise because then the
|
||||||
@@ -724,7 +736,9 @@ void WTURBULENCE::stepTurbulenceReadable(float dtOrg, float* xvel, float* yvel,
|
|||||||
|
|
||||||
|
|
||||||
_totalStepsBig++;
|
_totalStepsBig++;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
|
//struct
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// perform the full turbulence algorithm, including OpenMP
|
// perform the full turbulence algorithm, including OpenMP
|
||||||
@@ -747,6 +761,7 @@ void WTURBULENCE::stepTurbulenceFull(float dtOrg, float* xvel, float* yvel, floa
|
|||||||
|
|
||||||
memset(_tcTemp, 0, sizeof(float)*_totalCellsSm);
|
memset(_tcTemp, 0, sizeof(float)*_totalCellsSm);
|
||||||
|
|
||||||
|
|
||||||
// prepare textures
|
// prepare textures
|
||||||
advectTextureCoordinates(dtOrg, xvel,yvel,zvel, tempBig1, tempBig2);
|
advectTextureCoordinates(dtOrg, xvel,yvel,zvel, tempBig1, tempBig2);
|
||||||
|
|
||||||
@@ -763,25 +778,38 @@ void WTURBULENCE::stepTurbulenceFull(float dtOrg, float* xvel, float* yvel, floa
|
|||||||
if (obstacles[x]) highFreqEnergy[x] = 0.f;
|
if (obstacles[x]) highFreqEnergy[x] = 0.f;
|
||||||
|
|
||||||
Vec3Int ressm(_xResSm, _yResSm, _zResSm);
|
Vec3Int ressm(_xResSm, _yResSm, _zResSm);
|
||||||
FLUID_3D::setNeumannX(highFreqEnergy, ressm);
|
FLUID_3D::setNeumannX(highFreqEnergy, ressm, 0 , ressm[2]);
|
||||||
FLUID_3D::setNeumannY(highFreqEnergy, ressm);
|
FLUID_3D::setNeumannY(highFreqEnergy, ressm, 0 , ressm[2]);
|
||||||
FLUID_3D::setNeumannZ(highFreqEnergy, ressm);
|
FLUID_3D::setNeumannZ(highFreqEnergy, ressm, 0 , ressm[2]);
|
||||||
|
|
||||||
|
|
||||||
|
int threadval = 1;
|
||||||
|
#if PARALLEL==1
|
||||||
|
threadval = omp_get_max_threads();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// parallel region setup
|
// parallel region setup
|
||||||
float maxVelMagThreads[8] = { -1., -1., -1., -1., -1., -1., -1., -1. };
|
// Uses omp_get_max_trheads to get number of required cells.
|
||||||
#if PARALLEL==1 && !_WIN32
|
float* maxVelMagThreads = new float[threadval];
|
||||||
|
|
||||||
|
for (int i=0; i<threadval; i++) maxVelMagThreads[i] = -1.0f;
|
||||||
|
|
||||||
|
#if PARALLEL==1
|
||||||
|
|
||||||
#pragma omp parallel
|
#pragma omp parallel
|
||||||
#endif
|
#endif
|
||||||
{ float maxVelMag1 = 0.;
|
{ float maxVelMag1 = 0.;
|
||||||
#if PARALLEL==1 && !_WIN32
|
#if PARALLEL==1
|
||||||
const int id = omp_get_thread_num(); /*, num = omp_get_num_threads(); */
|
const int id = omp_get_thread_num(); /*, num = omp_get_num_threads(); */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// vector noise main loop
|
// vector noise main loop
|
||||||
#if PARALLEL==1 && !_WIN32
|
#if PARALLEL==1
|
||||||
#pragma omp for schedule(static)
|
#pragma omp for schedule(static,1)
|
||||||
#endif
|
#endif
|
||||||
for (int zSmall = 0; zSmall < _zResSm; zSmall++)
|
for (int zSmall = 0; zSmall < _zResSm; zSmall++)
|
||||||
|
{
|
||||||
for (int ySmall = 0; ySmall < _yResSm; ySmall++)
|
for (int ySmall = 0; ySmall < _yResSm; ySmall++)
|
||||||
for (int xSmall = 0; xSmall < _xResSm; xSmall++)
|
for (int xSmall = 0; xSmall < _xResSm; xSmall++)
|
||||||
{
|
{
|
||||||
@@ -796,14 +824,14 @@ void WTURBULENCE::stepTurbulenceFull(float dtOrg, float* xvel, float* yvel, floa
|
|||||||
|
|
||||||
// get LU factorization of texture jacobian and apply
|
// get LU factorization of texture jacobian and apply
|
||||||
// it to unit vectors
|
// it to unit vectors
|
||||||
JAMA::LU<float> LU = computeLU3x3(jacobian);
|
sLU LU = computeLU(jacobian);
|
||||||
float xUnwarped[] = {1.0f, 0.0f, 0.0f};
|
float xUnwarped[] = {1.0f, 0.0f, 0.0f};
|
||||||
float yUnwarped[] = {0.0f, 1.0f, 0.0f};
|
float yUnwarped[] = {0.0f, 1.0f, 0.0f};
|
||||||
float zUnwarped[] = {0.0f, 0.0f, 1.0f};
|
float zUnwarped[] = {0.0f, 0.0f, 1.0f};
|
||||||
float xWarped[] = {1.0f, 0.0f, 0.0f};
|
float xWarped[] = {1.0f, 0.0f, 0.0f};
|
||||||
float yWarped[] = {0.0f, 1.0f, 0.0f};
|
float yWarped[] = {0.0f, 1.0f, 0.0f};
|
||||||
float zWarped[] = {0.0f, 0.0f, 1.0f};
|
float zWarped[] = {0.0f, 0.0f, 1.0f};
|
||||||
bool nonSingular = LU.isNonsingular();
|
bool nonSingular = isNonsingular(LU);
|
||||||
#if 0
|
#if 0
|
||||||
// UNUSED
|
// UNUSED
|
||||||
float eigMax = 10.0f;
|
float eigMax = 10.0f;
|
||||||
@@ -908,24 +936,27 @@ void WTURBULENCE::stepTurbulenceFull(float dtOrg, float* xvel, float* yvel, floa
|
|||||||
obstacles, posSm[0], posSm[1], posSm[2], _xResSm, _yResSm, _zResSm);
|
obstacles, posSm[0], posSm[1], posSm[2], _xResSm, _yResSm, _zResSm);
|
||||||
if (obsCheck > 0.95)
|
if (obsCheck > 0.95)
|
||||||
bigUx[index] = bigUy[index] = bigUz[index] = 0.;
|
bigUx[index] = bigUy[index] = bigUz[index] = 0.;
|
||||||
} // xyz
|
} // xyz*/
|
||||||
|
|
||||||
#if PARALLEL==1 && !_WIN32
|
#if PARALLEL==1
|
||||||
maxVelMagThreads[id] = maxVelMag1;
|
maxVelMagThreads[id] = maxVelMag1;
|
||||||
#else
|
#else
|
||||||
maxVelMagThreads[0] = maxVelMag1;
|
maxVelMagThreads[0] = maxVelMag1;
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} // omp
|
} // omp
|
||||||
|
|
||||||
// compute maximum over threads
|
// compute maximum over threads
|
||||||
float maxVelMag = maxVelMagThreads[0];
|
float maxVelMag = maxVelMagThreads[0];
|
||||||
#if PARALLEL==1 && !_WIN32
|
#if PARALLEL==1
|
||||||
for (int i = 1; i < 8; i++)
|
for (int i = 1; i < threadval; i++)
|
||||||
if (maxVelMag < maxVelMagThreads[i])
|
if (maxVelMag < maxVelMagThreads[i])
|
||||||
maxVelMag = maxVelMagThreads[i];
|
maxVelMag = maxVelMagThreads[i];
|
||||||
|
delete [] maxVelMagThreads;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// prepare density for an advection
|
// prepare density for an advection
|
||||||
SWAP_POINTERS(_densityBig, _densityBigOld);
|
SWAP_POINTERS(_densityBig, _densityBigOld);
|
||||||
|
|
||||||
@@ -941,15 +972,56 @@ void WTURBULENCE::stepTurbulenceFull(float dtOrg, float* xvel, float* yvel, floa
|
|||||||
const float dtSubdiv = dt / (float)totalSubsteps;
|
const float dtSubdiv = dt / (float)totalSubsteps;
|
||||||
|
|
||||||
// set boundaries of big velocity grid
|
// set boundaries of big velocity grid
|
||||||
FLUID_3D::setZeroX(bigUx, _resBig);
|
FLUID_3D::setZeroX(bigUx, _resBig, 0 , _resBig[2]);
|
||||||
FLUID_3D::setZeroY(bigUy, _resBig);
|
FLUID_3D::setZeroY(bigUy, _resBig, 0 , _resBig[2]);
|
||||||
FLUID_3D::setZeroZ(bigUz, _resBig);
|
FLUID_3D::setZeroZ(bigUz, _resBig, 0 , _resBig[2]);
|
||||||
|
|
||||||
|
#if PARALLEL==1
|
||||||
|
int stepParts = threadval*2; // Dividing parallelized sections into numOfThreads * 2 sections
|
||||||
|
float partSize = (float)_zResBig/stepParts; // Size of one part;
|
||||||
|
|
||||||
|
if (partSize < 4) {stepParts = threadval; // If the slice gets too low (might actually slow things down, change it to larger
|
||||||
|
partSize = (float)_zResBig/stepParts;}
|
||||||
|
if (partSize < 4) {stepParts = (int)(ceil((float)_zResBig/4.0f)); // If it's still too low (only possible on future systems with +24 cores), change it to 4
|
||||||
|
partSize = (float)_zResBig/stepParts;}
|
||||||
|
#else
|
||||||
|
int zBegin=0;
|
||||||
|
int zEnd=_resBig[2];
|
||||||
|
#endif
|
||||||
|
|
||||||
// do the MacCormack advection, with substepping if necessary
|
// do the MacCormack advection, with substepping if necessary
|
||||||
for(int substep = 0; substep < totalSubsteps; substep++)
|
for(int substep = 0; substep < totalSubsteps; substep++)
|
||||||
{
|
{
|
||||||
FLUID_3D::advectFieldMacCormack(dtSubdiv, bigUx, bigUy, bigUz,
|
|
||||||
_densityBigOld, _densityBig, tempBig1, tempBig2, _resBig, NULL);
|
#if PARALLEL==1
|
||||||
|
#pragma omp parallel
|
||||||
|
{
|
||||||
|
|
||||||
|
#pragma omp for schedule(static,1)
|
||||||
|
for (int i=0; i<stepParts; i++)
|
||||||
|
{
|
||||||
|
int zBegin = (int)((float)i*partSize + 0.5f);
|
||||||
|
int zEnd = (int)((float)(i+1)*partSize + 0.5f);
|
||||||
|
#endif
|
||||||
|
FLUID_3D::advectFieldMacCormack1(dtSubdiv, bigUx, bigUy, bigUz,
|
||||||
|
_densityBigOld, tempBig1, _resBig, zBegin, zEnd);
|
||||||
|
#if PARALLEL==1
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma omp barrier
|
||||||
|
|
||||||
|
#pragma omp for schedule(static,1)
|
||||||
|
for (int i=0; i<stepParts; i++)
|
||||||
|
{
|
||||||
|
int zBegin = (int)((float)i*partSize + 0.5f);
|
||||||
|
int zEnd = (int)((float)(i+1)*partSize + 0.5f);
|
||||||
|
#endif
|
||||||
|
FLUID_3D::advectFieldMacCormack2(dtSubdiv, bigUx, bigUy, bigUz,
|
||||||
|
_densityBigOld, _densityBig, tempBig1, tempBig2, _resBig, NULL, zBegin, zEnd);
|
||||||
|
#if PARALLEL==1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (substep < totalSubsteps - 1)
|
if (substep < totalSubsteps - 1)
|
||||||
SWAP_POINTERS(_densityBig, _densityBigOld);
|
SWAP_POINTERS(_densityBig, _densityBigOld);
|
||||||
@@ -964,7 +1036,7 @@ void WTURBULENCE::stepTurbulenceFull(float dtOrg, float* xvel, float* yvel, floa
|
|||||||
free(highFreqEnergy);
|
free(highFreqEnergy);
|
||||||
|
|
||||||
// wipe the density borders
|
// wipe the density borders
|
||||||
FLUID_3D::setZeroBorder(_densityBig, _resBig);
|
FLUID_3D::setZeroBorder(_densityBig, _resBig, 0 , _resBig[2]);
|
||||||
|
|
||||||
// reset texture coordinates now in preparation for next timestep
|
// reset texture coordinates now in preparation for next timestep
|
||||||
// Shouldn't do this before generating the noise because then the
|
// Shouldn't do this before generating the noise because then the
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
// y in smoke is z in blender
|
// y in smoke is z in blender
|
||||||
extern "C" FLUID_3D *smoke_init(int *res, float *p0, float dt)
|
extern "C" FLUID_3D *smoke_init(int *res, float *p0, float dt)
|
||||||
@@ -110,8 +111,8 @@ extern "C" void smoke_dissolve(FLUID_3D *fluid, int speed, int log)
|
|||||||
|
|
||||||
heat[i] *= (1.0 - dydx);
|
heat[i] *= (1.0 - dydx);
|
||||||
|
|
||||||
if(heat[i] < 0.0f)
|
/*if(heat[i] < 0.0f)
|
||||||
heat[i] = 0.0f;
|
heat[i] = 0.0f;*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // linear falloff
|
else // linear falloff
|
||||||
@@ -127,10 +128,9 @@ extern "C" void smoke_dissolve(FLUID_3D *fluid, int speed, int log)
|
|||||||
if(density[i] < 0.0f)
|
if(density[i] < 0.0f)
|
||||||
density[i] = 0.0f;
|
density[i] = 0.0f;
|
||||||
|
|
||||||
heat[i] -= dydx;
|
if(abs(heat[i]) < dydx) heat[i] = 0.0f;
|
||||||
|
else if (heat[i]>0.0f) heat[i] -= dydx;
|
||||||
if(heat[i] < 0.0f)
|
else if (heat[i]<0.0f) heat[i] += dydx;
|
||||||
heat[i] = 0.0f;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,6 +39,9 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#if defined(__sun__) || defined( __sun ) || defined (__sparc) || defined (__sparc__) || defined (_AIX)
|
||||||
|
#include <strings.h>
|
||||||
|
#endif
|
||||||
#include "STR_String.h"
|
#include "STR_String.h"
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------------------------------
|
/*-------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -355,6 +355,10 @@
|
|||||||
RelativePath="..\..\..\source\blender\python\intern\bpy_operator_wrap.c"
|
RelativePath="..\..\..\source\blender\python\intern\bpy_operator_wrap.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\source\blender\python\intern\bpy_props.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\source\blender\python\intern\bpy_rna.c"
|
RelativePath="..\..\..\source\blender\python\intern\bpy_rna.c"
|
||||||
>
|
>
|
||||||
@@ -444,6 +448,10 @@
|
|||||||
RelativePath="..\..\..\source\blender\python\intern\bpy_panel_wrap.h"
|
RelativePath="..\..\..\source\blender\python\intern\bpy_panel_wrap.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\source\blender\python\intern\bpy_props.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\source\blender\python\intern\bpy_rna.h"
|
RelativePath="..\..\..\source\blender\python\intern\bpy_rna.h"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -571,6 +571,10 @@
|
|||||||
RelativePath="..\..\..\source\blender\blenlib\intern\math_base.c"
|
RelativePath="..\..\..\source\blender\blenlib\intern\math_base.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\source\blender\blenlib\intern\math_base_inline.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\source\blender\blenlib\intern\math_color.c"
|
RelativePath="..\..\..\source\blender\blenlib\intern\math_color.c"
|
||||||
>
|
>
|
||||||
@@ -736,6 +740,10 @@
|
|||||||
RelativePath="..\..\..\source\blender\blenlib\BLI_math_geom.h"
|
RelativePath="..\..\..\source\blender\blenlib\BLI_math_geom.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\source\blender\blenlib\BLI_math_inline.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\source\blender\blenlib\BLI_math_matrix.h"
|
RelativePath="..\..\..\source\blender\blenlib\BLI_math_matrix.h"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -44,7 +44,7 @@
|
|||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="2"
|
Optimization="2"
|
||||||
InlineFunctionExpansion="1"
|
InlineFunctionExpansion="1"
|
||||||
AdditionalIncludeDirectories="..\..\..\..\lib\windows\QTDevWin\CIncludes;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\python\include\python2.6;..\..\..\..\build\msvc_9\intern\bsp\include;..\..\..\..\build\msvc_9\intern\ghost\include;..\..\..\..\build\msvc_9\intern\elbeem\include;..\..\..\..\build\msvc_9\intern\opennl\include;..\..\..\..\build\msvc_9\intern\bmfont\include;..\..\..\..\build\msvc_9\intern\blenkey\include;..\..\..\..\build\msvc_9\intern\decimation\include;..\..\..\..\build\msvc_9\intern\memutil\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\smoke\include;..\..\..\..\build\msvc_9\intern\soundsystem\include;..\..\..\source\blender;..\..\..\source\blender\img;..\..\..\source\blender\verify;..\..\..\source\blender\ftfont;..\..\..\source\blender\misc;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\python;..\..\..\source\blender\editors\include;..\..\..\source\blender\renderui;..\..\..\source\blender\blenloader;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenkernel;..\..\..\source\blender\blenfont;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\nodes;..\..\..\source\blender\windowmanager;..\..\..\source\blender\blenpluginapi;..\..\..\source\blender\renderconverter;..\..\..\source\blender\readstreamglue;..\..\..\source\blender\render\extern\include;..\..\..\source\blender\radiosity\extern\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\network;..\..\..\source\gameengine\soundsystem\snd_openal;..\..\..\..\build\msvc_9\extern\verse\include;..\..\..\..\lib\windows\pthreads\include;..\..\..\..\lib\windows\ffmpeg\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\blender\gpu;..\..\..\intern\audaspace\intern;..\..\..\source\blender\ikplugin"
|
AdditionalIncludeDirectories="..\..\..\..\lib\windows\QTDevWin\CIncludes;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\python\include\python2.6;..\..\..\..\build\msvc_9\intern\bsp\include;..\..\..\..\build\msvc_9\intern\ghost\include;..\..\..\..\build\msvc_9\intern\elbeem\include;..\..\..\..\build\msvc_9\intern\opennl\include;..\..\..\..\build\msvc_9\intern\bmfont\include;..\..\..\..\build\msvc_9\intern\blenkey\include;..\..\..\..\build\msvc_9\intern\decimation\include;..\..\..\..\build\msvc_9\intern\memutil\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\smoke\include;..\..\..\..\build\msvc_9\intern\soundsystem\include;..\..\..\source\blender;..\..\..\source\blender\img;..\..\..\source\blender\verify;..\..\..\source\blender\ftfont;..\..\..\source\blender\misc;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\python;..\..\..\source\blender\editors\include;..\..\..\source\blender\editors\interface;..\..\..\source\blender\renderui;..\..\..\source\blender\blenloader;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenkernel;..\..\..\source\blender\blenfont;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\nodes;..\..\..\source\blender\windowmanager;..\..\..\source\blender\blenpluginapi;..\..\..\source\blender\renderconverter;..\..\..\source\blender\readstreamglue;..\..\..\source\blender\render\extern\include;..\..\..\source\blender\radiosity\extern\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\network;..\..\..\source\gameengine\soundsystem\snd_openal;..\..\..\..\build\msvc_9\extern\verse\include;..\..\..\..\lib\windows\pthreads\include;..\..\..\..\lib\windows\ffmpeg\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\blender\gpu;..\..\..\intern\audaspace\intern;..\..\..\source\blender\ikplugin"
|
||||||
PreprocessorDefinitions="NDEBUG;WIN32;_LIB;_CONSOLE;GAMEBLENDER=1;WITH_QUICKTIME;INTERNATIONAL;WITH_FREETYPE2;WITH_INTERNATIONAL;WITH_OPENEXR;WITH_DDS;WITH_BULLET=1;WITH_FFMPEG"
|
PreprocessorDefinitions="NDEBUG;WIN32;_LIB;_CONSOLE;GAMEBLENDER=1;WITH_QUICKTIME;INTERNATIONAL;WITH_FREETYPE2;WITH_INTERNATIONAL;WITH_OPENEXR;WITH_DDS;WITH_BULLET=1;WITH_FFMPEG"
|
||||||
StringPooling="true"
|
StringPooling="true"
|
||||||
RuntimeLibrary="0"
|
RuntimeLibrary="0"
|
||||||
@@ -119,7 +119,7 @@
|
|||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories="..\..\..\..\lib\windows\QTDevWin\CIncludes;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\python\include\python2.6;..\..\..\..\build\msvc_9\intern\bsp\include;..\..\..\..\build\msvc_9\intern\ghost\include;..\..\..\..\build\msvc_9\intern\elbeem\include;..\..\..\..\build\msvc_9\intern\opennl\include;..\..\..\..\build\msvc_9\intern\bmfont\include;..\..\..\..\build\msvc_9\intern\blenkey\include;..\..\..\..\build\msvc_9\intern\decimation\include;..\..\..\..\build\msvc_9\intern\memutil\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\smoke\include;..\..\..\..\build\msvc_9\intern\soundsystem\include;..\..\..\source\blender;..\..\..\source\blender\img;..\..\..\source\blender\verify;..\..\..\source\blender\ftfont;..\..\..\source\blender\misc;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\python;..\..\..\source\blender\editors\include;..\..\..\source\blender\renderui;..\..\..\source\blender\blenloader;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenkernel;..\..\..\source\blender\blenfont;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\nodes;..\..\..\source\blender\windowmanager;..\..\..\source\blender\blenpluginapi;..\..\..\source\blender\renderconverter;..\..\..\source\blender\readstreamglue;..\..\..\source\blender\render\extern\include;..\..\..\source\blender\radiosity\extern\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\network;..\..\..\source\gameengine\soundsystem\snd_openal;..\..\..\..\build\msvc_9\extern\verse\include;..\..\..\..\lib\windows\pthreads\include;..\..\..\..\lib\windows\ffmpeg\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\blender\gpu;..\..\..\intern\audaspace\intern;..\..\..\source\blender\ikplugin"
|
AdditionalIncludeDirectories="..\..\..\..\lib\windows\QTDevWin\CIncludes;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\python\include\python2.6;..\..\..\..\build\msvc_9\intern\bsp\include;..\..\..\..\build\msvc_9\intern\ghost\include;..\..\..\..\build\msvc_9\intern\elbeem\include;..\..\..\..\build\msvc_9\intern\opennl\include;..\..\..\..\build\msvc_9\intern\bmfont\include;..\..\..\..\build\msvc_9\intern\blenkey\include;..\..\..\..\build\msvc_9\intern\decimation\include;..\..\..\..\build\msvc_9\intern\memutil\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\smoke\include;..\..\..\..\build\msvc_9\intern\soundsystem\include;..\..\..\source\blender;..\..\..\source\blender\img;..\..\..\source\blender\verify;..\..\..\source\blender\ftfont;..\..\..\source\blender\misc;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\python;..\..\..\source\blender\editors\include;..\..\..\source\blender\editors\interface;..\..\..\source\blender\renderui;..\..\..\source\blender\blenloader;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenkernel;..\..\..\source\blender\blenfont;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\nodes;..\..\..\source\blender\windowmanager;..\..\..\source\blender\blenpluginapi;..\..\..\source\blender\renderconverter;..\..\..\source\blender\readstreamglue;..\..\..\source\blender\render\extern\include;..\..\..\source\blender\radiosity\extern\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\network;..\..\..\source\gameengine\soundsystem\snd_openal;..\..\..\..\build\msvc_9\extern\verse\include;..\..\..\..\lib\windows\pthreads\include;..\..\..\..\lib\windows\ffmpeg\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\blender\gpu;..\..\..\intern\audaspace\intern;..\..\..\source\blender\ikplugin"
|
||||||
PreprocessorDefinitions="_DEBUG;WIN32;_LIB;_CONSOLE;GAMEBLENDER=1;WITH_QUICKTIME;INTERNATIONAL;WITH_BF_INTERNATIONAL;WITH_FREETYPE2;WITH_OPENEXR;WITH_DDS;WITH_BULLET = 1;WITH_FFMPEG"
|
PreprocessorDefinitions="_DEBUG;WIN32;_LIB;_CONSOLE;GAMEBLENDER=1;WITH_QUICKTIME;INTERNATIONAL;WITH_BF_INTERNATIONAL;WITH_FREETYPE2;WITH_OPENEXR;WITH_DDS;WITH_BULLET = 1;WITH_FFMPEG"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
RuntimeLibrary="1"
|
RuntimeLibrary="1"
|
||||||
@@ -459,6 +459,10 @@
|
|||||||
<Filter
|
<Filter
|
||||||
Name="space_view3d"
|
Name="space_view3d"
|
||||||
>
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\source\blender\editors\space_view3d\drawanimviz.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\source\blender\editors\space_view3d\drawarmature.c"
|
RelativePath="..\..\..\source\blender\editors\space_view3d\drawarmature.c"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -349,6 +349,10 @@
|
|||||||
RelativePath="..\..\..\source\blender\nodes\intern\CMP_nodes\CMP_chromaMatte.c"
|
RelativePath="..\..\..\source\blender\nodes\intern\CMP_nodes\CMP_chromaMatte.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\source\blender\nodes\intern\CMP_nodes\CMP_colorbalance.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\source\blender\nodes\intern\CMP_nodes\CMP_colorMatte.c"
|
RelativePath="..\..\..\source\blender\nodes\intern\CMP_nodes\CMP_colorMatte.c"
|
||||||
>
|
>
|
||||||
@@ -409,6 +413,10 @@
|
|||||||
RelativePath="..\..\..\source\blender\nodes\intern\CMP_nodes\CMP_glare.c"
|
RelativePath="..\..\..\source\blender\nodes\intern\CMP_nodes\CMP_glare.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\source\blender\nodes\intern\CMP_nodes\CMP_huecorrect.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\source\blender\nodes\intern\CMP_nodes\CMP_hueSatVal.c"
|
RelativePath="..\..\..\source\blender\nodes\intern\CMP_nodes\CMP_hueSatVal.c"
|
||||||
>
|
>
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 204 KiB After Width: | Height: | Size: 205 KiB |
@@ -146,7 +146,7 @@ def write_pov(filename, scene=None, info_callback=None):
|
|||||||
file.write('\tup <0, 1, 0>\n')
|
file.write('\tup <0, 1, 0>\n')
|
||||||
file.write('\tangle %f \n' % (360.0 * atan(16.0 / camera.data.lens) / pi))
|
file.write('\tangle %f \n' % (360.0 * atan(16.0 / camera.data.lens) / pi))
|
||||||
|
|
||||||
file.write('\trotate <%.6f, %.6f, %.6f>\n' % tuple([degrees(e) for e in matrix.rotationPart().toEuler()]))
|
file.write('\trotate <%.6f, %.6f, %.6f>\n' % tuple([degrees(e) for e in matrix.rotation_part().to_euler()]))
|
||||||
file.write('\ttranslate <%.6f, %.6f, %.6f>\n' % (matrix[3][0], matrix[3][1], matrix[3][2]))
|
file.write('\ttranslate <%.6f, %.6f, %.6f>\n' % (matrix[3][0], matrix[3][1], matrix[3][2]))
|
||||||
file.write('}\n')
|
file.write('}\n')
|
||||||
|
|
||||||
|
|||||||
@@ -839,7 +839,7 @@ def make_track_chunk(ID, obj):
|
|||||||
track_chunk.add_variable("position", _3ds_point_3d(obj.getLocation()))
|
track_chunk.add_variable("position", _3ds_point_3d(obj.getLocation()))
|
||||||
elif ID==ROT_TRACK_TAG:
|
elif ID==ROT_TRACK_TAG:
|
||||||
# rotation (quaternion, angle first, followed by axis):
|
# rotation (quaternion, angle first, followed by axis):
|
||||||
q = obj.getEuler().toQuat()
|
q = obj.getEuler().to_quat()
|
||||||
track_chunk.add_variable("rotation", _3ds_point_4d((q.angle, q.axis[0], q.axis[1], q.axis[2])))
|
track_chunk.add_variable("rotation", _3ds_point_4d((q.angle, q.axis[0], q.axis[1], q.axis[2])))
|
||||||
elif ID==SCL_TRACK_TAG:
|
elif ID==SCL_TRACK_TAG:
|
||||||
# scale vector:
|
# scale vector:
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ def eulerRadToDeg(eul):
|
|||||||
mtx4_identity = Mathutils.Matrix()
|
mtx4_identity = Mathutils.Matrix()
|
||||||
|
|
||||||
# testing
|
# testing
|
||||||
mtx_x90 = Mathutils.RotationMatrix( math.pi/2, 3, 'x') # used
|
mtx_x90 = Mathutils.RotationMatrix( math.pi/2, 3, 'X') # used
|
||||||
#mtx_x90n = RotationMatrix(-90, 3, 'x')
|
#mtx_x90n = RotationMatrix(-90, 3, 'x')
|
||||||
#mtx_y90 = RotationMatrix( 90, 3, 'y')
|
#mtx_y90 = RotationMatrix( 90, 3, 'y')
|
||||||
#mtx_y90n = RotationMatrix(-90, 3, 'y')
|
#mtx_y90n = RotationMatrix(-90, 3, 'y')
|
||||||
@@ -154,11 +154,11 @@ mtx_x90 = Mathutils.RotationMatrix( math.pi/2, 3, 'x') # used
|
|||||||
#mtx_z90n = RotationMatrix(-90, 3, 'z')
|
#mtx_z90n = RotationMatrix(-90, 3, 'z')
|
||||||
|
|
||||||
#mtx4_x90 = RotationMatrix( 90, 4, 'x')
|
#mtx4_x90 = RotationMatrix( 90, 4, 'x')
|
||||||
mtx4_x90n = Mathutils.RotationMatrix(-math.pi/2, 4, 'x') # used
|
mtx4_x90n = Mathutils.RotationMatrix(-math.pi/2, 4, 'X') # used
|
||||||
#mtx4_y90 = RotationMatrix( 90, 4, 'y')
|
#mtx4_y90 = RotationMatrix( 90, 4, 'y')
|
||||||
mtx4_y90n = Mathutils.RotationMatrix(-math.pi/2, 4, 'y') # used
|
mtx4_y90n = Mathutils.RotationMatrix(-math.pi/2, 4, 'Y') # used
|
||||||
mtx4_z90 = Mathutils.RotationMatrix( math.pi/2, 4, 'z') # used
|
mtx4_z90 = Mathutils.RotationMatrix( math.pi/2, 4, 'Z') # used
|
||||||
mtx4_z90n = Mathutils.RotationMatrix(-math.pi/2, 4, 'z') # used
|
mtx4_z90n = Mathutils.RotationMatrix(-math.pi/2, 4, 'Z') # used
|
||||||
|
|
||||||
# def strip_path(p):
|
# def strip_path(p):
|
||||||
# return p.split('\\')[-1].split('/')[-1]
|
# return p.split('\\')[-1].split('/')[-1]
|
||||||
@@ -590,9 +590,9 @@ def write(filename, batch_objects = None, \
|
|||||||
def getAnimParRelMatrixRot(self, frame):
|
def getAnimParRelMatrixRot(self, frame):
|
||||||
type = self.blenObject.type
|
type = self.blenObject.type
|
||||||
if self.fbxParent:
|
if self.fbxParent:
|
||||||
matrix_rot = (((self.__anim_poselist[frame] * GLOBAL_MATRIX) * (self.fbxParent.__anim_poselist[frame] * GLOBAL_MATRIX).invert())).rotationPart()
|
matrix_rot = (((self.__anim_poselist[frame] * GLOBAL_MATRIX) * (self.fbxParent.__anim_poselist[frame] * GLOBAL_MATRIX).invert())).rotation_part()
|
||||||
else:
|
else:
|
||||||
matrix_rot = (self.__anim_poselist[frame] * GLOBAL_MATRIX).rotationPart()
|
matrix_rot = (self.__anim_poselist[frame] * GLOBAL_MATRIX).rotation_part()
|
||||||
|
|
||||||
# Lamps need to be rotated
|
# Lamps need to be rotated
|
||||||
if type =='LAMP':
|
if type =='LAMP':
|
||||||
@@ -600,7 +600,7 @@ def write(filename, batch_objects = None, \
|
|||||||
elif type =='CAMERA':
|
elif type =='CAMERA':
|
||||||
# elif ob and type =='Camera':
|
# elif ob and type =='Camera':
|
||||||
y = Mathutils.Vector(0,1,0) * matrix_rot
|
y = Mathutils.Vector(0,1,0) * matrix_rot
|
||||||
matrix_rot = matrix_rot * Mathutils.RotationMatrix(math.pi/2, 3, 'r', y)
|
matrix_rot = matrix_rot * Mathutils.RotationMatrix(math.pi/2, 3, y)
|
||||||
|
|
||||||
return matrix_rot
|
return matrix_rot
|
||||||
|
|
||||||
@@ -676,11 +676,11 @@ def write(filename, batch_objects = None, \
|
|||||||
# par_matrix = mtx4_z90 * parent.matrix['ARMATURESPACE'] # dont apply armature matrix anymore
|
# par_matrix = mtx4_z90 * parent.matrix['ARMATURESPACE'] # dont apply armature matrix anymore
|
||||||
matrix = matrix * par_matrix.copy().invert()
|
matrix = matrix * par_matrix.copy().invert()
|
||||||
|
|
||||||
matrix_rot = matrix.rotationPart()
|
matrix_rot = matrix.rotation_part()
|
||||||
|
|
||||||
loc = tuple(matrix.translationPart())
|
loc = tuple(matrix.translation_part())
|
||||||
scale = tuple(matrix.scalePart())
|
scale = tuple(matrix.scale_part())
|
||||||
rot = tuple(matrix_rot.toEuler())
|
rot = tuple(matrix_rot.to_euler())
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# This is bad because we need the parent relative matrix from the fbx parent (if we have one), dont use anymore
|
# This is bad because we need the parent relative matrix from the fbx parent (if we have one), dont use anymore
|
||||||
@@ -692,20 +692,20 @@ def write(filename, batch_objects = None, \
|
|||||||
# matrix = matrix_scale * matrix
|
# matrix = matrix_scale * matrix
|
||||||
|
|
||||||
if matrix:
|
if matrix:
|
||||||
loc = tuple(matrix.translationPart())
|
loc = tuple(matrix.translation_part())
|
||||||
scale = tuple(matrix.scalePart())
|
scale = tuple(matrix.scale_part())
|
||||||
|
|
||||||
matrix_rot = matrix.rotationPart()
|
matrix_rot = matrix.rotation_part()
|
||||||
# Lamps need to be rotated
|
# Lamps need to be rotated
|
||||||
if ob and ob.type =='Lamp':
|
if ob and ob.type =='Lamp':
|
||||||
matrix_rot = mtx_x90 * matrix_rot
|
matrix_rot = mtx_x90 * matrix_rot
|
||||||
rot = tuple(matrix_rot.toEuler())
|
rot = tuple(matrix_rot.to_euler())
|
||||||
elif ob and ob.type =='Camera':
|
elif ob and ob.type =='Camera':
|
||||||
y = Mathutils.Vector(0,1,0) * matrix_rot
|
y = Mathutils.Vector(0,1,0) * matrix_rot
|
||||||
matrix_rot = matrix_rot * Mathutils.RotationMatrix(math.pi/2, 3, 'r', y)
|
matrix_rot = matrix_rot * Mathutils.RotationMatrix(math.pi/2, 3, y)
|
||||||
rot = tuple(matrix_rot.toEuler())
|
rot = tuple(matrix_rot.to_euler())
|
||||||
else:
|
else:
|
||||||
rot = tuple(matrix_rot.toEuler())
|
rot = tuple(matrix_rot.to_euler())
|
||||||
else:
|
else:
|
||||||
if not loc:
|
if not loc:
|
||||||
loc = 0,0,0
|
loc = 0,0,0
|
||||||
@@ -1131,7 +1131,7 @@ def write(filename, batch_objects = None, \
|
|||||||
else:
|
else:
|
||||||
do_light = 1
|
do_light = 1
|
||||||
|
|
||||||
scale = abs(GLOBAL_MATRIX.scalePart()[0]) # scale is always uniform in this case
|
scale = abs(GLOBAL_MATRIX.scale_part()[0]) # scale is always uniform in this case
|
||||||
|
|
||||||
file.write('\n\t\t\tProperty: "LightType", "enum", "",%i' % light_type)
|
file.write('\n\t\t\tProperty: "LightType", "enum", "",%i' % light_type)
|
||||||
file.write('\n\t\t\tProperty: "CastLightOnObject", "bool", "",1')
|
file.write('\n\t\t\tProperty: "CastLightOnObject", "bool", "",1')
|
||||||
@@ -1753,7 +1753,7 @@ def write(filename, batch_objects = None, \
|
|||||||
for uf in uvlayer.data:
|
for uf in uvlayer.data:
|
||||||
# for f in me.faces:
|
# for f in me.faces:
|
||||||
# workaround, since uf.uv iteration is wrong atm
|
# workaround, since uf.uv iteration is wrong atm
|
||||||
for uv in [uf.uv1, uf.uv2, uf.uv3, uf.uv4][:len(uf.uv)]:
|
for uv in uf.uv:
|
||||||
# for uv in f.uv:
|
# for uv in f.uv:
|
||||||
if i==-1:
|
if i==-1:
|
||||||
file.write('%.6f,%.6f' % tuple(uv))
|
file.write('%.6f,%.6f' % tuple(uv))
|
||||||
@@ -2866,18 +2866,18 @@ Takes: {''')
|
|||||||
# ----------------
|
# ----------------
|
||||||
for TX_LAYER, TX_CHAN in enumerate('TRS'): # transform, rotate, scale
|
for TX_LAYER, TX_CHAN in enumerate('TRS'): # transform, rotate, scale
|
||||||
|
|
||||||
if TX_CHAN=='T': context_bone_anim_vecs = [mtx[0].translationPart() for mtx in context_bone_anim_mats]
|
if TX_CHAN=='T': context_bone_anim_vecs = [mtx[0].translation_part() for mtx in context_bone_anim_mats]
|
||||||
elif TX_CHAN=='S': context_bone_anim_vecs = [mtx[0].scalePart() for mtx in context_bone_anim_mats]
|
elif TX_CHAN=='S': context_bone_anim_vecs = [mtx[0].scale_part() for mtx in context_bone_anim_mats]
|
||||||
elif TX_CHAN=='R':
|
elif TX_CHAN=='R':
|
||||||
# Was....
|
# Was....
|
||||||
# elif TX_CHAN=='R': context_bone_anim_vecs = [mtx[1].toEuler() for mtx in context_bone_anim_mats]
|
# elif TX_CHAN=='R': context_bone_anim_vecs = [mtx[1].to_euler() for mtx in context_bone_anim_mats]
|
||||||
#
|
#
|
||||||
# ...but we need to use the previous euler for compatible conversion.
|
# ...but we need to use the previous euler for compatible conversion.
|
||||||
context_bone_anim_vecs = []
|
context_bone_anim_vecs = []
|
||||||
prev_eul = None
|
prev_eul = None
|
||||||
for mtx in context_bone_anim_mats:
|
for mtx in context_bone_anim_mats:
|
||||||
if prev_eul: prev_eul = mtx[1].toEuler(prev_eul)
|
if prev_eul: prev_eul = mtx[1].to_euler(prev_eul)
|
||||||
else: prev_eul = mtx[1].toEuler()
|
else: prev_eul = mtx[1].to_euler()
|
||||||
context_bone_anim_vecs.append(eulerRadToDeg(prev_eul))
|
context_bone_anim_vecs.append(eulerRadToDeg(prev_eul))
|
||||||
# context_bone_anim_vecs.append(prev_eul)
|
# context_bone_anim_vecs.append(prev_eul)
|
||||||
|
|
||||||
|
|||||||
@@ -564,7 +564,7 @@ def write(filename, objects, scene,
|
|||||||
tface = uv_layer.data[f_index]
|
tface = uv_layer.data[f_index]
|
||||||
|
|
||||||
# workaround, since tface.uv iteration is wrong atm
|
# workaround, since tface.uv iteration is wrong atm
|
||||||
uvs = [tface.uv1, tface.uv2, tface.uv3, tface.uv4][:len(tface.uv)]
|
uvs = tface.uv
|
||||||
# uvs = [tface.uv1, tface.uv2, tface.uv3]
|
# uvs = [tface.uv1, tface.uv2, tface.uv3]
|
||||||
|
|
||||||
# # add another UV if it's a quad
|
# # add another UV if it's a quad
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ from export_3ds import create_derived_objects, free_derived_objects
|
|||||||
|
|
||||||
#
|
#
|
||||||
DEG2RAD=0.017453292519943295
|
DEG2RAD=0.017453292519943295
|
||||||
MATWORLD= Mathutils.RotationMatrix(-90, 4, 'x')
|
MATWORLD= Mathutils.RotationMatrix(-90, 4, 'X')
|
||||||
|
|
||||||
####################################
|
####################################
|
||||||
# Global Variables
|
# Global Variables
|
||||||
@@ -239,8 +239,8 @@ class x3d_class:
|
|||||||
# get the camera location, subtract 90 degress from X to orient like X3D does
|
# get the camera location, subtract 90 degress from X to orient like X3D does
|
||||||
# mat = ob.matrixWorld - mat is now passed!
|
# mat = ob.matrixWorld - mat is now passed!
|
||||||
|
|
||||||
loc = self.rotatePointForVRML(mat.translationPart())
|
loc = self.rotatePointForVRML(mat.translation_part())
|
||||||
rot = mat.toEuler()
|
rot = mat.to_euler()
|
||||||
rot = (((rot[0]-90)), rot[1], rot[2])
|
rot = (((rot[0]-90)), rot[1], rot[2])
|
||||||
# rot = (((rot[0]-90)*DEG2RAD), rot[1]*DEG2RAD, rot[2]*DEG2RAD)
|
# rot = (((rot[0]-90)*DEG2RAD), rot[1]*DEG2RAD, rot[2]*DEG2RAD)
|
||||||
nRot = self.rotatePointForVRML( rot )
|
nRot = self.rotatePointForVRML( rot )
|
||||||
@@ -300,8 +300,8 @@ class x3d_class:
|
|||||||
# note -dz seems to equal om[3][1]
|
# note -dz seems to equal om[3][1]
|
||||||
# note dy seems to equal om[3][2]
|
# note dy seems to equal om[3][2]
|
||||||
|
|
||||||
#location=(ob.matrixWorld*MATWORLD).translationPart() # now passed
|
#location=(ob.matrixWorld*MATWORLD).translation_part() # now passed
|
||||||
location=(mtx*MATWORLD).translationPart()
|
location=(mtx*MATWORLD).translation_part()
|
||||||
|
|
||||||
radius = lamp.distance*math.cos(beamWidth)
|
radius = lamp.distance*math.cos(beamWidth)
|
||||||
# radius = lamp.dist*math.cos(beamWidth)
|
# radius = lamp.dist*math.cos(beamWidth)
|
||||||
@@ -346,8 +346,8 @@ class x3d_class:
|
|||||||
ambi = 0
|
ambi = 0
|
||||||
ambientIntensity = 0
|
ambientIntensity = 0
|
||||||
|
|
||||||
# location=(ob.matrixWorld*MATWORLD).translationPart() # now passed
|
# location=(ob.matrixWorld*MATWORLD).translation_part() # now passed
|
||||||
location= (mtx*MATWORLD).translationPart()
|
location= (mtx*MATWORLD).translation_part()
|
||||||
|
|
||||||
self.file.write("<PointLight DEF=\"%s\" " % safeName)
|
self.file.write("<PointLight DEF=\"%s\" " % safeName)
|
||||||
self.file.write("ambientIntensity=\"%s\" " % (round(ambientIntensity,self.cp)))
|
self.file.write("ambientIntensity=\"%s\" " % (round(ambientIntensity,self.cp)))
|
||||||
@@ -364,8 +364,8 @@ class x3d_class:
|
|||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
dx,dy,dz = self.computeDirection(mtx)
|
dx,dy,dz = self.computeDirection(mtx)
|
||||||
# location=(ob.matrixWorld*MATWORLD).translationPart()
|
# location=(ob.matrixWorld*MATWORLD).translation_part()
|
||||||
location=(mtx*MATWORLD).translationPart()
|
location=(mtx*MATWORLD).translation_part()
|
||||||
self.writeIndented("<%s\n" % obname,1)
|
self.writeIndented("<%s\n" % obname,1)
|
||||||
self.writeIndented("direction=\"%s %s %s\"\n" % (round(dx,3),round(dy,3),round(dz,3)))
|
self.writeIndented("direction=\"%s %s %s\"\n" % (round(dx,3),round(dy,3),round(dz,3)))
|
||||||
self.writeIndented("location=\"%s %s %s\"\n" % (round(location[0],3), round(location[1],3), round(location[2],3)))
|
self.writeIndented("location=\"%s %s %s\"\n" % (round(location[0],3), round(location[1],3), round(location[2],3)))
|
||||||
@@ -448,9 +448,9 @@ class x3d_class:
|
|||||||
# mtx = ob.matrixWorld * MATWORLD # mtx is now passed
|
# mtx = ob.matrixWorld * MATWORLD # mtx is now passed
|
||||||
mtx = mtx * MATWORLD
|
mtx = mtx * MATWORLD
|
||||||
|
|
||||||
loc= mtx.translationPart()
|
loc= mtx.translation_part()
|
||||||
sca= mtx.scalePart()
|
sca= mtx.scale_part()
|
||||||
quat = mtx.toQuat()
|
quat = mtx.to_quat()
|
||||||
rot= quat.axis
|
rot= quat.axis
|
||||||
|
|
||||||
self.writeIndented('<Transform DEF="%s" translation="%.6f %.6f %.6f" scale="%.6f %.6f %.6f" rotation="%.6f %.6f %.6f %.6f">\n' % \
|
self.writeIndented('<Transform DEF="%s" translation="%.6f %.6f %.6f" scale="%.6f %.6f %.6f" rotation="%.6f %.6f %.6f %.6f">\n' % \
|
||||||
@@ -617,7 +617,7 @@ class x3d_class:
|
|||||||
for face in mesh.active_uv_texture.data:
|
for face in mesh.active_uv_texture.data:
|
||||||
# for face in mesh.faces:
|
# for face in mesh.faces:
|
||||||
# workaround, since tface.uv iteration is wrong atm
|
# workaround, since tface.uv iteration is wrong atm
|
||||||
uvs = [face.uv1, face.uv2, face.uv3, face.uv4][:len(face.uv)]
|
uvs = face.uv
|
||||||
# uvs = [face.uv1, face.uv2, face.uv3, face.uv4] if face.verts[3] else [face.uv1, face.uv2, face.uv3]
|
# uvs = [face.uv1, face.uv2, face.uv3, face.uv4] if face.verts[3] else [face.uv1, face.uv2, face.uv3]
|
||||||
|
|
||||||
for uv in uvs:
|
for uv in uvs:
|
||||||
@@ -1048,7 +1048,7 @@ class x3d_class:
|
|||||||
def computeDirection(self, mtx):
|
def computeDirection(self, mtx):
|
||||||
x,y,z=(0,-1.0,0) # point down
|
x,y,z=(0,-1.0,0) # point down
|
||||||
|
|
||||||
ax,ay,az = (mtx*MATWORLD).toEuler()
|
ax,ay,az = (mtx*MATWORLD).to_euler()
|
||||||
|
|
||||||
# ax *= DEG2RAD
|
# ax *= DEG2RAD
|
||||||
# ay *= DEG2RAD
|
# ay *= DEG2RAD
|
||||||
|
|||||||
@@ -89,13 +89,13 @@ 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):
|
def eulerRotate(x,y,z, rot_order):
|
||||||
|
|
||||||
# Clamp all values between 0 and 360, values outside this raise an error.
|
# 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')]
|
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
|
# print rot_order
|
||||||
# Standard BVH multiplication order, apply the rotation in the order Z,X,Y
|
# Standard BVH multiplication order, apply the rotation in the order Z,X,Y
|
||||||
|
|
||||||
#XXX, order changes???
|
#XXX, order changes???
|
||||||
#eul = (mats[rot_order[2]]*(mats[rot_order[1]]* (mats[rot_order[0]]* MATRIX_IDENTITY_3x3))).toEuler()
|
#eul = (mats[rot_order[2]]*(mats[rot_order[1]]* (mats[rot_order[0]]* MATRIX_IDENTITY_3x3))).to_euler()
|
||||||
eul = (MATRIX_IDENTITY_3x3*mats[rot_order[0]]*(mats[rot_order[1]]* (mats[rot_order[2]]))).toEuler()
|
eul = (MATRIX_IDENTITY_3x3*mats[rot_order[0]]*(mats[rot_order[1]]* (mats[rot_order[2]]))).to_euler()
|
||||||
|
|
||||||
eul = math.degrees(eul.x), math.degrees(eul.y), math.degrees(eul.z)
|
eul = math.degrees(eul.x), math.degrees(eul.y), math.degrees(eul.z)
|
||||||
|
|
||||||
@@ -534,8 +534,8 @@ def bvh_node_dict2armature(context, bvh_nodes, IMPORT_START_FRAME= 1, IMPORT_LOO
|
|||||||
bone_name= bvh_node.temp # may not be the same name as the bvh_node, could have been shortened.
|
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= pose_bones[bone_name]
|
||||||
rest_bone= arm_data.bones[bone_name]
|
rest_bone= arm_data.bones[bone_name]
|
||||||
#XXX bone_rest_matrix = rest_bone.matrix['ARMATURESPACE'].rotationPart()
|
#XXX bone_rest_matrix = rest_bone.matrix['ARMATURESPACE'].rotation_part()
|
||||||
bone_rest_matrix = rest_bone.matrix.rotationPart()
|
bone_rest_matrix = rest_bone.matrix.rotation_part()
|
||||||
|
|
||||||
|
|
||||||
bone_rest_matrix_inv= Matrix(bone_rest_matrix)
|
bone_rest_matrix_inv= Matrix(bone_rest_matrix)
|
||||||
@@ -575,31 +575,31 @@ def bvh_node_dict2armature(context, bvh_nodes, IMPORT_START_FRAME= 1, IMPORT_LOO
|
|||||||
|
|
||||||
if ROT_STYLE=='QUAT':
|
if ROT_STYLE=='QUAT':
|
||||||
# Set the rotation, not so simple
|
# Set the rotation, not so simple
|
||||||
bone_rotation_matrix= Euler(math.radians(rx), math.radians(ry), math.radians(rz)).toMatrix()
|
bone_rotation_matrix= Euler(math.radians(rx), math.radians(ry), math.radians(rz)).to_matrix()
|
||||||
|
|
||||||
bone_rotation_matrix.resize4x4()
|
bone_rotation_matrix.resize4x4()
|
||||||
#XXX ORDER CHANGE???
|
#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 * bone_rotation_matrix * bone_rest_matrix_inv).to_quat() # ORIGINAL
|
||||||
# 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).to_quat()
|
||||||
# pose_bone.rotation_quaternion= (bone_rotation_matrix * bone_rest_matrix).toQuat() # BAD
|
# pose_bone.rotation_quaternion= (bone_rotation_matrix * bone_rest_matrix).to_quat() # BAD
|
||||||
# pose_bone.rotation_quaternion= bone_rotation_matrix.toQuat() # NOT GOOD
|
# pose_bone.rotation_quaternion= bone_rotation_matrix.to_quat() # NOT GOOD
|
||||||
# pose_bone.rotation_quaternion= bone_rotation_matrix.toQuat() # NOT GOOD
|
# pose_bone.rotation_quaternion= bone_rotation_matrix.to_quat() # NOT GOOD
|
||||||
|
|
||||||
#pose_bone.rotation_quaternion= (bone_rotation_matrix * bone_rest_matrix_inv * bone_rest_matrix).toQuat()
|
#pose_bone.rotation_quaternion= (bone_rotation_matrix * bone_rest_matrix_inv * bone_rest_matrix).to_quat()
|
||||||
#pose_bone.rotation_quaternion= (bone_rest_matrix_inv * bone_rest_matrix * bone_rotation_matrix).toQuat()
|
#pose_bone.rotation_quaternion= (bone_rest_matrix_inv * bone_rest_matrix * bone_rotation_matrix).to_quat()
|
||||||
#pose_bone.rotation_quaternion= (bone_rest_matrix * bone_rotation_matrix * bone_rest_matrix_inv).toQuat()
|
#pose_bone.rotation_quaternion= (bone_rest_matrix * bone_rotation_matrix * bone_rest_matrix_inv).to_quat()
|
||||||
|
|
||||||
#pose_bone.rotation_quaternion= ( bone_rest_matrix* bone_rest_matrix_inv * bone_rotation_matrix).toQuat()
|
#pose_bone.rotation_quaternion= ( bone_rest_matrix* bone_rest_matrix_inv * bone_rotation_matrix).to_quat()
|
||||||
#pose_bone.rotation_quaternion= (bone_rotation_matrix * bone_rest_matrix * bone_rest_matrix_inv).toQuat()
|
#pose_bone.rotation_quaternion= (bone_rotation_matrix * bone_rest_matrix * bone_rest_matrix_inv).to_quat()
|
||||||
#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 ).to_quat()
|
||||||
|
|
||||||
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).to_quat()
|
||||||
|
|
||||||
else:
|
else:
|
||||||
bone_rotation_matrix= Euler(math.radians(rx), math.radians(ry), math.radians(rz)).toMatrix()
|
bone_rotation_matrix= Euler(math.radians(rx), math.radians(ry), math.radians(rz)).to_matrix()
|
||||||
bone_rotation_matrix.resize4x4()
|
bone_rotation_matrix.resize4x4()
|
||||||
|
|
||||||
eul= (bone_rest_matrix * bone_rotation_matrix * bone_rest_matrix_inv).toEuler()
|
eul= (bone_rest_matrix * bone_rotation_matrix * bone_rest_matrix_inv).to_euler()
|
||||||
|
|
||||||
#pose_bone.rotation_euler = math.radians(rx), math.radians(ry), math.radians(rz)
|
#pose_bone.rotation_euler = math.radians(rx), math.radians(ry), math.radians(rz)
|
||||||
pose_bone.rotation_euler = eul
|
pose_bone.rotation_euler = eul
|
||||||
@@ -610,8 +610,8 @@ def bvh_node_dict2armature(context, bvh_nodes, IMPORT_START_FRAME= 1, IMPORT_LOO
|
|||||||
# Set the Location, simple too
|
# Set the Location, simple too
|
||||||
|
|
||||||
#XXX ORDER CHANGE
|
#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= (TranslationMatrix(Vector(lx, ly, lz) - bvh_node.rest_head_local ) * bone_rest_matrix_inv).translation_part() # 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= (bone_rest_matrix_inv * TranslationMatrix(Vector(lx, ly, lz) - bvh_node.rest_head_local )).translation_part()
|
||||||
# pose_bone.location= lx, ly, lz
|
# pose_bone.location= lx, ly, lz
|
||||||
pose_bone.location= Vector(lx, ly, lz) - bvh_node.rest_head_local
|
pose_bone.location= Vector(lx, ly, lz) - bvh_node.rest_head_local
|
||||||
|
|
||||||
@@ -714,12 +714,12 @@ def bvh_node_dict2armature(context, bvh_nodes, IMPORT_START_FRAME= 1, IMPORT_LOO
|
|||||||
|
|
||||||
|
|
||||||
def pose_rot(anim_data):
|
def pose_rot(anim_data):
|
||||||
bone_rotation_matrix= Euler(anim_data[3], anim_data[4], anim_data[5]).toMatrix()
|
bone_rotation_matrix= Euler(anim_data[3], anim_data[4], anim_data[5]).to_matrix()
|
||||||
bone_rotation_matrix.resize4x4()
|
bone_rotation_matrix.resize4x4()
|
||||||
return tuple((bone_rest_matrix * bone_rotation_matrix * bone_rest_matrix_inv).toQuat()) # qw,qx,qy,qz
|
return tuple((bone_rest_matrix * bone_rotation_matrix * bone_rest_matrix_inv).to_quat()) # qw,qx,qy,qz
|
||||||
|
|
||||||
def pose_loc(anim_data):
|
def pose_loc(anim_data):
|
||||||
return tuple((TranslationMatrix(Vector(anim_data[0], anim_data[1], anim_data[2])) * bone_rest_matrix_inv).translationPart())
|
return tuple((TranslationMatrix(Vector(anim_data[0], anim_data[1], anim_data[2])) * bone_rest_matrix_inv).translation_part())
|
||||||
|
|
||||||
|
|
||||||
last_frame= len(bvh_node.anim_data)+IMPORT_START_FRAME-1
|
last_frame= len(bvh_node.anim_data)+IMPORT_START_FRAME-1
|
||||||
|
|||||||
@@ -34,8 +34,8 @@ from bpy import ops as _ops_module
|
|||||||
# fake operator module
|
# fake operator module
|
||||||
ops = _ops_module.ops_fake_module
|
ops = _ops_module.ops_fake_module
|
||||||
|
|
||||||
import sys
|
import sys as _sys
|
||||||
DEBUG = ("-d" in sys.argv)
|
DEBUG = ("-d" in _sys.argv)
|
||||||
|
|
||||||
|
|
||||||
def load_scripts(reload_scripts=False):
|
def load_scripts(reload_scripts=False):
|
||||||
@@ -65,6 +65,12 @@ def load_scripts(reload_scripts=False):
|
|||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def test_reload(module):
|
||||||
|
try:
|
||||||
|
reload(module)
|
||||||
|
except:
|
||||||
|
traceback.print_exc()
|
||||||
|
|
||||||
if reload_scripts:
|
if reload_scripts:
|
||||||
# reload modules that may not be directly included
|
# reload modules that may not be directly included
|
||||||
for type_class_name in dir(types):
|
for type_class_name in dir(types):
|
||||||
@@ -76,14 +82,14 @@ def load_scripts(reload_scripts=False):
|
|||||||
|
|
||||||
for module_name in loaded_modules:
|
for module_name in loaded_modules:
|
||||||
print("Reloading:", module_name)
|
print("Reloading:", module_name)
|
||||||
reload(sys.modules[module_name])
|
test_reload(_sys.modules[module_name])
|
||||||
|
|
||||||
for base_path in utils.script_paths():
|
for base_path in utils.script_paths():
|
||||||
for path_subdir in ("ui", "op", "io"):
|
for path_subdir in ("ui", "op", "io"):
|
||||||
path = os.path.join(base_path, path_subdir)
|
path = os.path.join(base_path, path_subdir)
|
||||||
if os.path.isdir(path):
|
if os.path.isdir(path):
|
||||||
if path not in sys.path: # reloading would add twice
|
if path not in _sys.path: # reloading would add twice
|
||||||
sys.path.insert(0, path)
|
_sys.path.insert(0, path)
|
||||||
for f in sorted(os.listdir(path)):
|
for f in sorted(os.listdir(path)):
|
||||||
if f.endswith(".py"):
|
if f.endswith(".py"):
|
||||||
# python module
|
# python module
|
||||||
@@ -96,7 +102,7 @@ def load_scripts(reload_scripts=False):
|
|||||||
|
|
||||||
if reload_scripts and mod:
|
if reload_scripts and mod:
|
||||||
print("Reloading:", mod)
|
print("Reloading:", mod)
|
||||||
reload(mod)
|
test_reload(mod)
|
||||||
|
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
print("Time %.4f" % (time.time() - t_main))
|
print("Time %.4f" % (time.time() - t_main))
|
||||||
@@ -104,10 +110,13 @@ def load_scripts(reload_scripts=False):
|
|||||||
|
|
||||||
def _main():
|
def _main():
|
||||||
|
|
||||||
|
# security issue, dont allow the $CWD in the path.
|
||||||
|
_sys.path[:] = filter(None, _sys.path)
|
||||||
|
|
||||||
# a bit nasty but this prevents help() and input() from locking blender
|
# a bit nasty but this prevents help() and input() from locking blender
|
||||||
# Ideally we could have some way for the console to replace sys.stdin but
|
# Ideally we could have some way for the console to replace sys.stdin but
|
||||||
# python would lock blender while waiting for a return value, not easy :|
|
# python would lock blender while waiting for a return value, not easy :|
|
||||||
sys.stdin = None
|
_sys.stdin = None
|
||||||
|
|
||||||
# if "-d" in sys.argv: # Enable this to measure startup speed
|
# if "-d" in sys.argv: # Enable this to measure startup speed
|
||||||
if 0:
|
if 0:
|
||||||
|
|||||||
@@ -18,6 +18,27 @@
|
|||||||
|
|
||||||
# <pep8 compliant>
|
# <pep8 compliant>
|
||||||
|
|
||||||
|
"""
|
||||||
|
This module contains application values that remain unchanged during runtime.
|
||||||
|
|
||||||
|
.. data:: version
|
||||||
|
|
||||||
|
The Blender version as a tuple of 3 numbers. eg. (2, 50, 11)
|
||||||
|
|
||||||
|
|
||||||
|
.. data:: version_string
|
||||||
|
|
||||||
|
The Blender version formatted as a string.
|
||||||
|
|
||||||
|
.. data:: home
|
||||||
|
|
||||||
|
The blender home directory, normally matching $HOME
|
||||||
|
|
||||||
|
.. data:: binary_path
|
||||||
|
|
||||||
|
The location of blenders executable, useful for utilities that spawn new instances.
|
||||||
|
|
||||||
|
"""
|
||||||
# constants
|
# constants
|
||||||
import _bpy
|
import _bpy
|
||||||
version = _bpy._VERSION
|
version = _bpy._VERSION
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ class bpy_ops_submodule_op(object):
|
|||||||
|
|
||||||
def idname(self):
|
def idname(self):
|
||||||
# submod.foo -> SUBMOD_OT_foo
|
# submod.foo -> SUBMOD_OT_foo
|
||||||
return self.module.upper() + '_OT_' + self.func
|
return self.module + '.' + self.func
|
||||||
|
|
||||||
def __call__(self, *args, **kw):
|
def __call__(self, *args, **kw):
|
||||||
|
|
||||||
|
|||||||
@@ -18,13 +18,18 @@
|
|||||||
|
|
||||||
# <pep8 compliant>
|
# <pep8 compliant>
|
||||||
|
|
||||||
import bpy
|
"""
|
||||||
import os
|
This module contains utility functions spesific to blender but
|
||||||
|
not assosiated with blenders internal data.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import bpy as _bpy
|
||||||
|
import os as _os
|
||||||
|
|
||||||
|
|
||||||
def expandpath(path):
|
def expandpath(path):
|
||||||
if path.startswith("//"):
|
if path.startswith("//"):
|
||||||
return os.path.join(os.path.dirname(bpy.data.filename), path[2:])
|
return _os.path.join(_os.path.dirname(_bpy.data.filename), path[2:])
|
||||||
|
|
||||||
return path
|
return path
|
||||||
|
|
||||||
@@ -47,67 +52,74 @@ _unclean_chars = ''.join([chr(i) for i in _unclean_chars])
|
|||||||
|
|
||||||
|
|
||||||
def clean_name(name, replace="_"):
|
def clean_name(name, replace="_"):
|
||||||
'''
|
"""
|
||||||
|
Returns a name with characters replaced that may cause problems under various circumstances, such as writing to a file.
|
||||||
All characters besides A-Z/a-z, 0-9 are replaced with "_"
|
All characters besides A-Z/a-z, 0-9 are replaced with "_"
|
||||||
or the replace argumet if defined.
|
or the replace argumet if defined.
|
||||||
'''
|
"""
|
||||||
for ch in _unclean_chars:
|
for ch in _unclean_chars:
|
||||||
name = name.replace(ch, replace)
|
name = name.replace(ch, replace)
|
||||||
return name
|
return name
|
||||||
|
|
||||||
|
|
||||||
def display_name(name):
|
def display_name(name):
|
||||||
'''
|
"""
|
||||||
Only capitalize all lowercase names, mixed case use them as is.
|
Creates a display string from name to be used menus and the user interface.
|
||||||
should work with filenames and module names.
|
Capitalize the first letter in all lowercase names, mixed case names are kept as is.
|
||||||
'''
|
Intended for use with filenames and module names.
|
||||||
name_base = os.path.splitext(name)[0]
|
"""
|
||||||
|
name_base = _os.path.splitext(name)[0]
|
||||||
|
|
||||||
# string replacements
|
# string replacements
|
||||||
name_base = name_base.replace("_colon_", ":")
|
name_base = name_base.replace("_colon_", ":")
|
||||||
|
|
||||||
name_base = name_base.replace("_", " ")
|
name_base = name_base.replace("_", " ")
|
||||||
|
|
||||||
if name_base.lower() == name_base:
|
if name_base.islower():
|
||||||
return ' '.join([w[0].upper() + w[1:] for w in name_base.split()])
|
return name_base.capitalize()
|
||||||
else:
|
else:
|
||||||
return name_base
|
return name_base
|
||||||
|
|
||||||
|
|
||||||
# base scripts
|
# base scripts
|
||||||
_scripts = os.path.join(os.path.dirname(__file__), os.path.pardir, os.path.pardir)
|
_scripts = _os.path.join(_os.path.dirname(__file__), _os.path.pardir, _os.path.pardir)
|
||||||
_scripts = (os.path.normpath(_scripts), )
|
_scripts = (_os.path.normpath(_scripts), )
|
||||||
|
|
||||||
|
|
||||||
def script_paths(*args):
|
def script_paths(*args):
|
||||||
|
"""
|
||||||
|
Returns a list of valid script paths from the home directory and user preferences.
|
||||||
|
|
||||||
|
Accepts any number of string arguments which are joined to make a path.
|
||||||
|
"""
|
||||||
scripts = list(_scripts)
|
scripts = list(_scripts)
|
||||||
|
|
||||||
# add user scripts dir
|
# add user scripts dir
|
||||||
user_script_path = bpy.context.user_preferences.filepaths.python_scripts_directory
|
user_script_path = _bpy.context.user_preferences.filepaths.python_scripts_directory
|
||||||
|
|
||||||
if not user_script_path:
|
if not user_script_path:
|
||||||
# XXX - WIN32 needs checking, perhaps better call a blender internal function.
|
# XXX - WIN32 needs checking, perhaps better call a blender internal function.
|
||||||
user_script_path = os.path.join(os.path.expanduser("~"), ".blender", "scripts")
|
user_script_path = _os.path.join(_os.path.expanduser("~"), ".blender", "scripts")
|
||||||
|
|
||||||
user_script_path = os.path.normpath(user_script_path)
|
user_script_path = _os.path.normpath(user_script_path)
|
||||||
|
|
||||||
if user_script_path not in scripts and os.path.isdir(user_script_path):
|
if user_script_path not in scripts and _os.path.isdir(user_script_path):
|
||||||
scripts.append(user_script_path)
|
scripts.append(user_script_path)
|
||||||
|
|
||||||
if not args:
|
if not args:
|
||||||
return scripts
|
return scripts
|
||||||
|
|
||||||
subdir = os.path.join(*args)
|
subdir = _os.path.join(*args)
|
||||||
script_paths = []
|
script_paths = []
|
||||||
for path in scripts:
|
for path in scripts:
|
||||||
path_subdir = os.path.join(path, subdir)
|
path_subdir = _os.path.join(path, subdir)
|
||||||
if os.path.isdir(path_subdir):
|
if _os.path.isdir(path_subdir):
|
||||||
script_paths.append(path_subdir)
|
script_paths.append(path_subdir)
|
||||||
|
|
||||||
return script_paths
|
return script_paths
|
||||||
|
|
||||||
|
|
||||||
_presets = os.path.join(_scripts[0], "presets") # FIXME - multiple paths
|
_presets = _os.path.join(_scripts[0], "presets") # FIXME - multiple paths
|
||||||
|
|
||||||
|
|
||||||
def preset_paths(subdir):
|
def preset_paths(subdir):
|
||||||
@@ -115,4 +127,4 @@ def preset_paths(subdir):
|
|||||||
Returns a list of paths for a spesific preset.
|
Returns a list of paths for a spesific preset.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
return (os.path.join(_presets, subdir), )
|
return (_os.path.join(_presets, subdir), )
|
||||||
|
|||||||
@@ -94,19 +94,19 @@ class _GenericBone:
|
|||||||
def x_axis(self):
|
def x_axis(self):
|
||||||
""" Vector pointing down the x-axis of the bone.
|
""" Vector pointing down the x-axis of the bone.
|
||||||
"""
|
"""
|
||||||
return self.matrix.rotationPart() * Vector(1,0,0)
|
return self.matrix.rotation_part() * Vector(1,0,0)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def y_axis(self):
|
def y_axis(self):
|
||||||
""" Vector pointing down the x-axis of the bone.
|
""" Vector pointing down the x-axis of the bone.
|
||||||
"""
|
"""
|
||||||
return self.matrix.rotationPart() * Vector(0,1,0)
|
return self.matrix.rotation_part() * Vector(0,1,0)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def z_axis(self):
|
def z_axis(self):
|
||||||
""" Vector pointing down the x-axis of the bone.
|
""" Vector pointing down the x-axis of the bone.
|
||||||
"""
|
"""
|
||||||
return self.matrix.rotationPart() * Vector(0,0,1)
|
return self.matrix.rotation_part() * Vector(0,0,1)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def basename(self):
|
def basename(self):
|
||||||
@@ -236,7 +236,7 @@ class EditBone(StructRNA, _GenericBone):
|
|||||||
Expects a 4x4 or 3x3 matrix.
|
Expects a 4x4 or 3x3 matrix.
|
||||||
"""
|
"""
|
||||||
from Mathutils import Vector
|
from Mathutils import Vector
|
||||||
z_vec = self.matrix.rotationPart() * Vector(0.0, 0.0, 1.0)
|
z_vec = self.matrix.rotation_part() * Vector(0.0, 0.0, 1.0)
|
||||||
self.tail = matrix * self.tail
|
self.tail = matrix * self.tail
|
||||||
self.head = matrix * self.head
|
self.head = matrix * self.head
|
||||||
scalar = matrix.median_scale
|
scalar = matrix.median_scale
|
||||||
@@ -421,8 +421,8 @@ class OrderedMeta(type):
|
|||||||
|
|
||||||
|
|
||||||
# Only defined so operators members can be used by accessing self.order
|
# Only defined so operators members can be used by accessing self.order
|
||||||
class Operator(StructRNA, metaclass=OrderedMeta):
|
#class Operator(StructRNA, metaclass=OrderedMeta):
|
||||||
__slots__ = ()
|
# __slots__ = ()
|
||||||
|
|
||||||
|
|
||||||
class Macro(StructRNA, metaclass=OrderedMeta):
|
class Macro(StructRNA, metaclass=OrderedMeta):
|
||||||
|
|||||||
@@ -30,14 +30,14 @@ def get_hub(co, _hubs, EPS_SPLINE):
|
|||||||
if (hub.co - co).length < EPS_SPLINE:
|
if (hub.co - co).length < EPS_SPLINE:
|
||||||
return hub
|
return hub
|
||||||
|
|
||||||
key = co.toTuple(3)
|
key = co.to_tuple(3)
|
||||||
hub = _hubs[key] = Hub(co, key, len(_hubs))
|
hub = _hubs[key] = Hub(co, key, len(_hubs))
|
||||||
return hub
|
return hub
|
||||||
else:
|
else:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
'''
|
'''
|
||||||
key = co.toTuple(3)
|
key = co.to_tuple(3)
|
||||||
try:
|
try:
|
||||||
return _hubs[key]
|
return _hubs[key]
|
||||||
except:
|
except:
|
||||||
@@ -274,9 +274,7 @@ def get_splines(gp):
|
|||||||
|
|
||||||
|
|
||||||
def xsect_spline(sp_a, sp_b, _hubs):
|
def xsect_spline(sp_a, sp_b, _hubs):
|
||||||
from Mathutils import LineIntersect
|
from Geometry import ClosestPointOnLine, LineIntersect
|
||||||
from Mathutils import MidpointVecs
|
|
||||||
from Geometry import ClosestPointOnLine
|
|
||||||
pt_a_prev = pt_b_prev = None
|
pt_a_prev = pt_b_prev = None
|
||||||
EPS_SPLINE = (sp_a.length + sp_b.length) / (EPS_SPLINE_DIV * 2)
|
EPS_SPLINE = (sp_a.length + sp_b.length) / (EPS_SPLINE_DIV * 2)
|
||||||
pt_a_prev = sp_a.points[0]
|
pt_a_prev = sp_a.points[0]
|
||||||
@@ -296,7 +294,7 @@ def xsect_spline(sp_a, sp_b, _hubs):
|
|||||||
# if f >= 0.0-EPS_SPLINE and f <= 1.0+EPS_SPLINE:
|
# if f >= 0.0-EPS_SPLINE and f <= 1.0+EPS_SPLINE:
|
||||||
if f >= 0.0 and f <= 1.0:
|
if f >= 0.0 and f <= 1.0:
|
||||||
# This wont happen often
|
# This wont happen often
|
||||||
co = MidpointVecs(xsect[0], xsect[1])
|
co = xsect[0].lerp(xsect[1], 0.5)
|
||||||
hub = get_hub(co, _hubs, EPS_SPLINE)
|
hub = get_hub(co, _hubs, EPS_SPLINE)
|
||||||
|
|
||||||
sp_a.hubs.append((a, hub))
|
sp_a.hubs.append((a, hub))
|
||||||
@@ -309,7 +307,6 @@ def xsect_spline(sp_a, sp_b, _hubs):
|
|||||||
|
|
||||||
def connect_splines(splines):
|
def connect_splines(splines):
|
||||||
HASH_PREC = 8
|
HASH_PREC = 8
|
||||||
from Mathutils import AngleBetweenVecs
|
|
||||||
from math import radians
|
from math import radians
|
||||||
ANG_LIMIT = radians(ANGLE_JOIN_LIMIT)
|
ANG_LIMIT = radians(ANGLE_JOIN_LIMIT)
|
||||||
def sort_pair(a, b):
|
def sort_pair(a, b):
|
||||||
@@ -341,7 +338,7 @@ def connect_splines(splines):
|
|||||||
v1 = p1a - p1b
|
v1 = p1a - p1b
|
||||||
v2 = p2b - p2a
|
v2 = p2b - p2a
|
||||||
|
|
||||||
if AngleBetweenVecs(v1, v2) > ANG_LIMIT:
|
if v1.angle(v2) > ANG_LIMIT:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# print("joining!")
|
# print("joining!")
|
||||||
@@ -354,8 +351,8 @@ def connect_splines(splines):
|
|||||||
while do_join:
|
while do_join:
|
||||||
do_join = False
|
do_join = False
|
||||||
for i, s1 in enumerate(splines):
|
for i, s1 in enumerate(splines):
|
||||||
key1a = s1.points[0].toTuple(HASH_PREC)
|
key1a = s1.points[0].to_tuple(HASH_PREC)
|
||||||
key1b = s1.points[-1].toTuple(HASH_PREC)
|
key1b = s1.points[-1].to_tuple(HASH_PREC)
|
||||||
|
|
||||||
for j, s2 in enumerate(splines):
|
for j, s2 in enumerate(splines):
|
||||||
if s1 is s2:
|
if s1 is s2:
|
||||||
@@ -363,8 +360,8 @@ def connect_splines(splines):
|
|||||||
|
|
||||||
length_average = min(s1.length, s2.length)
|
length_average = min(s1.length, s2.length)
|
||||||
|
|
||||||
key2a = s2.points[0].toTuple(HASH_PREC)
|
key2a = s2.points[0].to_tuple(HASH_PREC)
|
||||||
key2b = s2.points[-1].toTuple(HASH_PREC)
|
key2b = s2.points[-1].to_tuple(HASH_PREC)
|
||||||
|
|
||||||
# there are 4 ways this may be joined
|
# there are 4 ways this may be joined
|
||||||
key_pair = sort_pair(key1a, key2a)
|
key_pair = sort_pair(key1a, key2a)
|
||||||
|
|||||||
@@ -154,6 +154,8 @@ def generate_rig(context, obj_orig, prefix="ORG-", META_DEF=True):
|
|||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
import rigify_utils
|
import rigify_utils
|
||||||
reload(rigify_utils)
|
reload(rigify_utils)
|
||||||
|
|
||||||
|
print("Begin...")
|
||||||
|
|
||||||
# Not needed but catches any errors before duplicating
|
# Not needed but catches any errors before duplicating
|
||||||
validate_rig(context, obj_orig)
|
validate_rig(context, obj_orig)
|
||||||
@@ -164,23 +166,85 @@ def generate_rig(context, obj_orig, prefix="ORG-", META_DEF=True):
|
|||||||
rest_backup = obj_orig.data.pose_position
|
rest_backup = obj_orig.data.pose_position
|
||||||
obj_orig.data.pose_position = 'REST'
|
obj_orig.data.pose_position = 'REST'
|
||||||
|
|
||||||
|
|
||||||
bpy.ops.object.mode_set(mode='OBJECT')
|
bpy.ops.object.mode_set(mode='OBJECT')
|
||||||
|
|
||||||
scene = context.scene
|
scene = context.scene
|
||||||
|
|
||||||
# copy object and data
|
# Check if the generated rig already exists, so we can
|
||||||
|
# regenerate in the same object. If not, create a new
|
||||||
|
# object to generate the rig in.
|
||||||
|
print("Fetch rig.")
|
||||||
|
try:
|
||||||
|
name = obj_orig["rig_object_name"]
|
||||||
|
except KeyError:
|
||||||
|
name = "rig"
|
||||||
|
|
||||||
|
try:
|
||||||
|
obj = scene.objects[name]
|
||||||
|
except KeyError:
|
||||||
|
obj = bpy.data.objects.new(name, type='ARMATURE')
|
||||||
|
obj.data = bpy.data.armatures.new(name)
|
||||||
|
scene.objects.link(obj)
|
||||||
|
|
||||||
|
obj.data.pose_position = 'POSE'
|
||||||
|
|
||||||
|
# Get rid of anim data in case the rig already existed
|
||||||
|
print("Clear rig animation data.")
|
||||||
|
obj.animation_data_clear()
|
||||||
|
|
||||||
|
# Select generated rig object
|
||||||
obj_orig.selected = False
|
obj_orig.selected = False
|
||||||
obj = obj_orig.copy()
|
|
||||||
obj.data = obj_orig.data.copy()
|
|
||||||
scene.objects.link(obj)
|
|
||||||
scene.objects.active = obj
|
|
||||||
obj.selected = True
|
obj.selected = True
|
||||||
|
scene.objects.active = obj
|
||||||
|
|
||||||
|
# Remove all bones from the generated rig armature.
|
||||||
|
bpy.ops.object.mode_set(mode='EDIT')
|
||||||
|
for bone in obj.data.edit_bones:
|
||||||
|
obj.data.edit_bones.remove(bone)
|
||||||
|
bpy.ops.object.mode_set(mode='OBJECT')
|
||||||
|
|
||||||
|
# Create temporary duplicates for merging
|
||||||
|
temp_rig_1 = obj_orig.copy()
|
||||||
|
temp_rig_1.data = obj_orig.data.copy()
|
||||||
|
scene.objects.link(temp_rig_1)
|
||||||
|
|
||||||
|
temp_rig_2 = obj_orig.copy()
|
||||||
|
temp_rig_2.data = obj.data
|
||||||
|
scene.objects.link(temp_rig_2)
|
||||||
|
|
||||||
|
# Select the temp rigs for merging
|
||||||
|
for objt in scene.objects:
|
||||||
|
objt.selected = False # deselect all objects
|
||||||
|
temp_rig_1.selected = True
|
||||||
|
temp_rig_2.selected = True
|
||||||
|
scene.objects.active = temp_rig_2
|
||||||
|
|
||||||
|
# Merge the temporary rigs
|
||||||
|
bpy.ops.object.join(context)
|
||||||
|
|
||||||
|
# Delete the second temp rig
|
||||||
|
bpy.ops.object.delete()
|
||||||
|
|
||||||
|
# Select the generated rig
|
||||||
|
for objt in scene.objects:
|
||||||
|
objt.selected = False # deselect all objects
|
||||||
|
obj.selected = True
|
||||||
|
scene.objects.active = obj
|
||||||
|
|
||||||
|
# Copy over the pose_bone custom properties
|
||||||
|
for bone in obj_orig.pose.bones:
|
||||||
|
for prop in bone.keys():
|
||||||
|
obj.pose.bones[bone.name][prop] = bone[prop]
|
||||||
|
|
||||||
|
# Create proxy deformation rig
|
||||||
|
# TODO: remove this
|
||||||
if META_DEF:
|
if META_DEF:
|
||||||
obj_def = obj_orig.copy()
|
obj_def = obj_orig.copy()
|
||||||
obj_def.data = obj_orig.data.copy()
|
obj_def.data = obj_orig.data.copy()
|
||||||
scene.objects.link(obj_def)
|
scene.objects.link(obj_def)
|
||||||
|
|
||||||
|
scene.update()
|
||||||
|
print("On to the real work.")
|
||||||
|
|
||||||
arm = obj.data
|
arm = obj.data
|
||||||
|
|
||||||
@@ -255,7 +319,7 @@ def generate_rig(context, obj_orig, prefix="ORG-", META_DEF=True):
|
|||||||
# for pbone in obj.pose.bones:
|
# for pbone in obj.pose.bones:
|
||||||
for pbone in bones_sorted:
|
for pbone in bones_sorted:
|
||||||
bone_name = pbone.name
|
bone_name = pbone.name
|
||||||
|
print(bone_name)
|
||||||
if bone_name not in bone_typeinfos:
|
if bone_name not in bone_typeinfos:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@@ -268,6 +332,7 @@ def generate_rig(context, obj_orig, prefix="ORG-", META_DEF=True):
|
|||||||
bone_names_pre = {bone.name for bone in arm.bones}
|
bone_names_pre = {bone.name for bone in arm.bones}
|
||||||
|
|
||||||
for type_name, type_func in bone_typeinfos[bone_name]:
|
for type_name, type_func in bone_typeinfos[bone_name]:
|
||||||
|
print(" " + type_name)
|
||||||
# this bones definition of the current typeinfo
|
# this bones definition of the current typeinfo
|
||||||
definition = bone_def_dict[type_name]
|
definition = bone_def_dict[type_name]
|
||||||
options = get_bone_type_options(pbone, type_name)
|
options = get_bone_type_options(pbone, type_name)
|
||||||
@@ -386,7 +451,10 @@ def generate_rig(context, obj_orig, prefix="ORG-", META_DEF=True):
|
|||||||
bpy.ops.object.mode_set(mode=mode_orig)
|
bpy.ops.object.mode_set(mode=mode_orig)
|
||||||
obj_orig.data.pose_position = rest_backup
|
obj_orig.data.pose_position = rest_backup
|
||||||
obj.data.pose_position = 'POSE'
|
obj.data.pose_position = 'POSE'
|
||||||
|
obj_orig.data.pose_position = 'POSE'
|
||||||
context.user_preferences.edit.global_undo = global_undo
|
context.user_preferences.edit.global_undo = global_undo
|
||||||
|
|
||||||
|
print("Done.\n")
|
||||||
|
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
@@ -431,7 +499,7 @@ def generate_test(context, metarig_type="", GENERATE_FINAL=True):
|
|||||||
else:
|
else:
|
||||||
new_objects.append((obj, None))
|
new_objects.append((obj, None))
|
||||||
else:
|
else:
|
||||||
print("note: rig type '%s' has no metarig_template(), can't test this", module_name)
|
print("note: rig type '%s' has no metarig_template(), can't test this" % module_name)
|
||||||
|
|
||||||
return new_objects
|
return new_objects
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
# <pep8 compliant>
|
# <pep8 compliant>
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
from math import radians
|
from math import radians, pi
|
||||||
from rigify import RigifyError, get_layer_dict, ORG_PREFIX
|
from rigify import RigifyError, get_layer_dict, ORG_PREFIX
|
||||||
from rigify_utils import bone_class_instance, copy_bone_simple, add_pole_target_bone, add_stretch_to, blend_bone_list, get_side_name, get_base_name
|
from rigify_utils import bone_class_instance, copy_bone_simple, add_pole_target_bone, add_stretch_to, blend_bone_list, get_side_name, get_base_name
|
||||||
from rna_prop_ui import rna_idprop_ui_prop_get
|
from rna_prop_ui import rna_idprop_ui_prop_get
|
||||||
@@ -162,7 +162,7 @@ def ik(obj, definitions, base_names, options):
|
|||||||
con.use_target = True
|
con.use_target = True
|
||||||
con.use_rotation = False
|
con.use_rotation = False
|
||||||
con.chain_length = 2
|
con.chain_length = 2
|
||||||
con.pole_angle = -90.0 # XXX, RAD2DEG
|
con.pole_angle = -pi/2
|
||||||
|
|
||||||
# last step setup layers
|
# last step setup layers
|
||||||
if "ik_layer" in options:
|
if "ik_layer" in options:
|
||||||
@@ -223,6 +223,7 @@ def fk(obj, definitions, base_names, options):
|
|||||||
fk_chain.forearm_p.rotation_mode = 'XYZ'
|
fk_chain.forearm_p.rotation_mode = 'XYZ'
|
||||||
fk_chain.forearm_p.lock_rotation = (False, True, True)
|
fk_chain.forearm_p.lock_rotation = (False, True, True)
|
||||||
fk_chain.hand_p.rotation_mode = 'ZXY'
|
fk_chain.hand_p.rotation_mode = 'ZXY'
|
||||||
|
fk_chain.arm_p.lock_location = True, True, True
|
||||||
|
|
||||||
con = fk_chain.arm_p.constraints.new('COPY_LOCATION')
|
con = fk_chain.arm_p.constraints.new('COPY_LOCATION')
|
||||||
con.target = obj
|
con.target = obj
|
||||||
@@ -276,7 +277,14 @@ def fk(obj, definitions, base_names, options):
|
|||||||
fk_chain.arm_b.layer = layer
|
fk_chain.arm_b.layer = layer
|
||||||
fk_chain.forearm_b.layer = layer
|
fk_chain.forearm_b.layer = layer
|
||||||
fk_chain.hand_b.layer = layer
|
fk_chain.hand_b.layer = layer
|
||||||
|
|
||||||
|
# Forearm was getting wrong roll somehow. Hack to fix that.
|
||||||
|
bpy.ops.object.mode_set(mode='EDIT')
|
||||||
|
fk_chain.update()
|
||||||
|
mt.update()
|
||||||
|
fk_chain.forearm_e.roll = mt.forearm_e.roll
|
||||||
|
bpy.ops.object.mode_set(mode='OBJECT')
|
||||||
|
|
||||||
bpy.ops.object.mode_set(mode='EDIT')
|
bpy.ops.object.mode_set(mode='EDIT')
|
||||||
return None, fk_chain.arm, fk_chain.forearm, fk_chain.hand
|
return None, fk_chain.arm, fk_chain.forearm, fk_chain.hand
|
||||||
|
|
||||||
@@ -338,6 +346,11 @@ def deform(obj, definitions, base_names, options):
|
|||||||
con.target = obj
|
con.target = obj
|
||||||
con.subtarget = definitions[2]
|
con.subtarget = definitions[2]
|
||||||
|
|
||||||
|
con = uarm1.constraints.new('COPY_SCALE')
|
||||||
|
con.name = "trackto"
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = definitions[1]
|
||||||
|
|
||||||
con = uarm2.constraints.new('COPY_ROTATION')
|
con = uarm2.constraints.new('COPY_ROTATION')
|
||||||
con.name = "copy_rot"
|
con.name = "copy_rot"
|
||||||
con.target = obj
|
con.target = obj
|
||||||
@@ -349,6 +362,11 @@ def deform(obj, definitions, base_names, options):
|
|||||||
con.target = obj
|
con.target = obj
|
||||||
con.subtarget = definitions[2]
|
con.subtarget = definitions[2]
|
||||||
|
|
||||||
|
con = farm1.constraints.new('COPY_SCALE')
|
||||||
|
con.name = "copy_rot"
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = definitions[2]
|
||||||
|
|
||||||
con = farm2.constraints.new('COPY_ROTATION')
|
con = farm2.constraints.new('COPY_ROTATION')
|
||||||
con.name = "copy_rot"
|
con.name = "copy_rot"
|
||||||
con.target = obj
|
con.target = obj
|
||||||
|
|||||||
@@ -127,8 +127,8 @@ def main(obj, bone_definition, base_names, options):
|
|||||||
|
|
||||||
delta_pbone.rotation_mode = 'XYZ'
|
delta_pbone.rotation_mode = 'XYZ'
|
||||||
|
|
||||||
rot = delta_pmatrix.invert().rotationPart() * child_pmatrix.rotationPart()
|
rot = delta_pmatrix.invert().rotation_part() * child_pmatrix.rotation_part()
|
||||||
rot = rot.invert().toEuler()
|
rot = rot.invert().to_euler()
|
||||||
|
|
||||||
fcurve_drivers = delta_pbone.driver_add("rotation_euler", -1)
|
fcurve_drivers = delta_pbone.driver_add("rotation_euler", -1)
|
||||||
for i, fcurve_driver in enumerate(fcurve_drivers):
|
for i, fcurve_driver in enumerate(fcurve_drivers):
|
||||||
@@ -141,7 +141,7 @@ def main(obj, bone_definition, base_names, options):
|
|||||||
mod.coefficients[1] = 0.0
|
mod.coefficients[1] = 0.0
|
||||||
|
|
||||||
# tricky, find the transform to drive the bone to this location.
|
# tricky, find the transform to drive the bone to this location.
|
||||||
delta_head_offset = child_pmatrix.rotationPart() * (delta_phead - child_phead)
|
delta_head_offset = child_pmatrix.rotation_part() * (delta_phead - child_phead)
|
||||||
|
|
||||||
fcurve_drivers = delta_pbone.driver_add("location", -1)
|
fcurve_drivers = delta_pbone.driver_add("location", -1)
|
||||||
for i, fcurve_driver in enumerate(fcurve_drivers):
|
for i, fcurve_driver in enumerate(fcurve_drivers):
|
||||||
|
|||||||
277
release/scripts/modules/rigify/eye_balls.py
Normal file
277
release/scripts/modules/rigify/eye_balls.py
Normal file
@@ -0,0 +1,277 @@
|
|||||||
|
# ##### 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
|
||||||
|
from rna_prop_ui import rna_idprop_ui_prop_get
|
||||||
|
from math import acos
|
||||||
|
from Mathutils import Vector
|
||||||
|
from rigify import get_layer_dict
|
||||||
|
from rigify_utils import bone_class_instance, copy_bone_simple
|
||||||
|
|
||||||
|
#METARIG_NAMES = ("cpy",)
|
||||||
|
RIG_TYPE = "eye_balls"
|
||||||
|
|
||||||
|
def mark_actions():
|
||||||
|
for action in bpy.data.actions:
|
||||||
|
action.tag = True
|
||||||
|
|
||||||
|
def get_unmarked_action():
|
||||||
|
for action in bpy.data.actions:
|
||||||
|
if action.tag != True:
|
||||||
|
return action
|
||||||
|
return None
|
||||||
|
|
||||||
|
def add_action(name=None):
|
||||||
|
mark_actions()
|
||||||
|
bpy.ops.action.new()
|
||||||
|
action = get_unmarked_action()
|
||||||
|
if name is not None:
|
||||||
|
action.name = name
|
||||||
|
return action
|
||||||
|
|
||||||
|
|
||||||
|
def metarig_template():
|
||||||
|
# generated by rigify.write_meta_rig
|
||||||
|
bpy.ops.object.mode_set(mode='EDIT')
|
||||||
|
obj = bpy.context.active_object
|
||||||
|
arm = obj.data
|
||||||
|
bone = arm.edit_bones.new('Bone')
|
||||||
|
bone.head[:] = 0.0000, 0.0000, 0.0000
|
||||||
|
bone.tail[:] = 0.0000, 0.0000, 1.0000
|
||||||
|
bone.roll = 0.0000
|
||||||
|
bone.connected = False
|
||||||
|
|
||||||
|
bpy.ops.object.mode_set(mode='OBJECT')
|
||||||
|
pbone = obj.pose.bones['Bone']
|
||||||
|
pbone['type'] = 'copy'
|
||||||
|
|
||||||
|
|
||||||
|
def metarig_definition(obj, orig_bone_name):
|
||||||
|
bone = obj.data.bones[orig_bone_name]
|
||||||
|
chain = []
|
||||||
|
|
||||||
|
try:
|
||||||
|
chain += [bone.parent.name, bone.name]
|
||||||
|
except AttributeError:
|
||||||
|
raise RigifyError("'%s' rig type requires a parent (bone: %s)" % (RIG_TYPE, base_names[0]))
|
||||||
|
|
||||||
|
return chain
|
||||||
|
|
||||||
|
|
||||||
|
def deform(obj, definitions, base_names, options):
|
||||||
|
bpy.ops.object.mode_set(mode='EDIT')
|
||||||
|
|
||||||
|
eb = obj.data.edit_bones
|
||||||
|
pb = obj.pose.bones
|
||||||
|
|
||||||
|
# Get list of eyes
|
||||||
|
if "eyes" in options:
|
||||||
|
eye_base_names = options["eyes"].replace(" ", "").split(",")
|
||||||
|
else:
|
||||||
|
eye_base_names = []
|
||||||
|
|
||||||
|
# Get their ORG- names
|
||||||
|
eyes = []
|
||||||
|
for name in eye_base_names:
|
||||||
|
eyes += ["ORG-"+name]
|
||||||
|
|
||||||
|
# Duplicate the eyes to make deformation bones
|
||||||
|
def_eyes = [] # def/org pairs
|
||||||
|
for eye in eyes:
|
||||||
|
def_eyes += [(copy_bone_simple(obj.data, eye, "DEF-"+base_names[eye], parent=True).name, eye)]
|
||||||
|
|
||||||
|
|
||||||
|
bpy.ops.object.mode_set(mode='OBJECT')
|
||||||
|
|
||||||
|
# Constraints
|
||||||
|
for eye in def_eyes:
|
||||||
|
con = pb[eye[0]].constraints.new('COPY_TRANSFORMS')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = eye[1]
|
||||||
|
|
||||||
|
return (None,)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def control(obj, definitions, base_names, options):
|
||||||
|
bpy.ops.object.mode_set(mode='EDIT')
|
||||||
|
|
||||||
|
eb = obj.data.edit_bones
|
||||||
|
bb = obj.data.bones
|
||||||
|
pb = obj.pose.bones
|
||||||
|
|
||||||
|
head = definitions[0]
|
||||||
|
eye_target = definitions[1]
|
||||||
|
|
||||||
|
# Get list of eyes
|
||||||
|
if "eyes" in options:
|
||||||
|
eye_base_names = options["eyes"].replace(" ", "").split(",")
|
||||||
|
else:
|
||||||
|
eye_base_names = []
|
||||||
|
|
||||||
|
# Get their ORG- names
|
||||||
|
eyes = []
|
||||||
|
for name in eye_base_names:
|
||||||
|
eyes += ["ORG-"+name]
|
||||||
|
|
||||||
|
# Get the average position of the eyes
|
||||||
|
center = Vector(0,0,0)
|
||||||
|
for eye in eyes:
|
||||||
|
center += eb[eye].head
|
||||||
|
if len(eyes) != 0:
|
||||||
|
center /= len(eyes)
|
||||||
|
|
||||||
|
# Get the average length of the eyes
|
||||||
|
length = 0.0
|
||||||
|
for eye in eyes:
|
||||||
|
length += eb[eye].length
|
||||||
|
if len(eyes) == 0:
|
||||||
|
length = 1.0
|
||||||
|
else:
|
||||||
|
length /= len(eyes)
|
||||||
|
|
||||||
|
|
||||||
|
# Make the mind's eye
|
||||||
|
minds_eye = copy_bone_simple(obj.data, eye_target, "MCH-"+base_names[eye_target]+".mind", parent=True).name
|
||||||
|
eb[minds_eye].head = center
|
||||||
|
eb[minds_eye].tail = eb[eye_target].head
|
||||||
|
eb[minds_eye].roll = 0.0
|
||||||
|
eb[minds_eye].length = length
|
||||||
|
|
||||||
|
# Create org/copy/control eye sets
|
||||||
|
eye_sets = []
|
||||||
|
for eye in eyes:
|
||||||
|
copy = copy_bone_simple(obj.data, minds_eye, "MCH-"+base_names[eye]+".cpy", parent=True).name
|
||||||
|
eb[copy].translate(eb[eye].head - eb[copy].head)
|
||||||
|
eb[copy].parent = eb[eye].parent
|
||||||
|
|
||||||
|
control = copy_bone_simple(obj.data, eye, base_names[eye], parent=True).name
|
||||||
|
eb[control].parent = eb[copy]
|
||||||
|
|
||||||
|
eye_sets += [(eye, copy, control)]
|
||||||
|
|
||||||
|
# Bones for parent/free switch for eye target
|
||||||
|
target_ctrl = copy_bone_simple(obj.data, eye_target, base_names[eye_target], parent=True).name
|
||||||
|
parent = copy_bone_simple(obj.data, head, "MCH-eye_target_parent", parent=False).name
|
||||||
|
|
||||||
|
eb[target_ctrl].parent = eb[parent]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bpy.ops.object.mode_set(mode='OBJECT')
|
||||||
|
|
||||||
|
# Axis locks
|
||||||
|
pb[target_ctrl].lock_scale = False, True, True
|
||||||
|
|
||||||
|
# Add eye_spread action if it doesn't already exist
|
||||||
|
action_name = "eye_spread"
|
||||||
|
if action_name in bpy.data.actions:
|
||||||
|
spread_action = bpy.data.actions[action_name]
|
||||||
|
else:
|
||||||
|
spread_action = add_action(name=action_name)
|
||||||
|
|
||||||
|
# Add free property
|
||||||
|
prop_name = "free"
|
||||||
|
prop = rna_idprop_ui_prop_get(pb[target_ctrl], prop_name, create=True)
|
||||||
|
pb[target_ctrl][prop_name] = 0.0
|
||||||
|
prop["soft_min"] = 0.0
|
||||||
|
prop["soft_max"] = 1.0
|
||||||
|
prop["min"] = 0.0
|
||||||
|
prop["max"] = 1.0
|
||||||
|
|
||||||
|
free_driver_path = pb[target_ctrl].path_to_id() + '["free"]'
|
||||||
|
|
||||||
|
# Constraints
|
||||||
|
# Mind's eye tracks eye target control
|
||||||
|
con = pb[minds_eye].constraints.new('DAMPED_TRACK')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = target_ctrl
|
||||||
|
|
||||||
|
# Parent copies transforms of head
|
||||||
|
con = pb[parent].constraints.new('COPY_TRANSFORMS')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = head
|
||||||
|
|
||||||
|
fcurve = con.driver_add("influence", 0)
|
||||||
|
driver = fcurve.driver
|
||||||
|
driver.type = 'AVERAGE'
|
||||||
|
mod = fcurve.modifiers[0]
|
||||||
|
mod.coefficients[0] = 1.0
|
||||||
|
mod.coefficients[1] = -1.0
|
||||||
|
|
||||||
|
var = driver.variables.new()
|
||||||
|
var.name = "free"
|
||||||
|
var.targets[0].id_type = 'OBJECT'
|
||||||
|
var.targets[0].id = obj
|
||||||
|
var.targets[0].data_path = free_driver_path
|
||||||
|
|
||||||
|
# Eye set's constraints
|
||||||
|
for eye in eye_sets:
|
||||||
|
# Org copies transforms of control
|
||||||
|
con = pb[eye[0]].constraints.new('COPY_TRANSFORMS')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = eye[2]
|
||||||
|
|
||||||
|
# Copy copies rotation of mind's eye
|
||||||
|
con = pb[eye[1]].constraints.new('COPY_ROTATION')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = minds_eye
|
||||||
|
|
||||||
|
# Control gets action constraint for eye spread
|
||||||
|
con = pb[eye[2]].constraints.new('ACTION')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = target_ctrl
|
||||||
|
con.action = spread_action
|
||||||
|
con.transform_channel = 'SCALE_X'
|
||||||
|
con.start_frame = -20
|
||||||
|
con.end_frame = 20
|
||||||
|
con.minimum = 0.0
|
||||||
|
con.maximum = 2.0
|
||||||
|
con.target_space = 'LOCAL'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Set layers
|
||||||
|
#layer = list(bb[definitions[2]].layer)
|
||||||
|
#bb[lid1].layer = layer
|
||||||
|
#bb[lid2].layer = layer
|
||||||
|
#bb[lid3].layer = layer
|
||||||
|
#bb[lid4].layer = layer
|
||||||
|
#bb[lid5].layer = layer
|
||||||
|
#bb[lid6].layer = layer
|
||||||
|
#bb[lid7].layer = layer
|
||||||
|
#bb[lid8].layer = layer
|
||||||
|
|
||||||
|
|
||||||
|
return (None,)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def main(obj, bone_definition, base_names, options):
|
||||||
|
# Create control rig
|
||||||
|
control(obj, bone_definition, base_names, options)
|
||||||
|
# Create deform rig
|
||||||
|
deform(obj, bone_definition, base_names, options)
|
||||||
|
|
||||||
|
return (None,)
|
||||||
|
|
||||||
686
release/scripts/modules/rigify/eye_lid.py
Normal file
686
release/scripts/modules/rigify/eye_lid.py
Normal file
@@ -0,0 +1,686 @@
|
|||||||
|
# ##### 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
|
||||||
|
from rna_prop_ui import rna_idprop_ui_prop_get
|
||||||
|
from math import acos
|
||||||
|
from Mathutils import Vector
|
||||||
|
from rigify import get_layer_dict
|
||||||
|
from rigify_utils import bone_class_instance, copy_bone_simple
|
||||||
|
|
||||||
|
#METARIG_NAMES = ("cpy",)
|
||||||
|
RIG_TYPE = "eye_lid"
|
||||||
|
|
||||||
|
def mark_actions():
|
||||||
|
for action in bpy.data.actions:
|
||||||
|
action.tag = True
|
||||||
|
|
||||||
|
def get_unmarked_action():
|
||||||
|
for action in bpy.data.actions:
|
||||||
|
if action.tag != True:
|
||||||
|
return action
|
||||||
|
return None
|
||||||
|
|
||||||
|
def add_action(name=None):
|
||||||
|
mark_actions()
|
||||||
|
bpy.ops.action.new()
|
||||||
|
action = get_unmarked_action()
|
||||||
|
if name is not None:
|
||||||
|
action.name = name
|
||||||
|
return action
|
||||||
|
|
||||||
|
|
||||||
|
def metarig_template():
|
||||||
|
# generated by rigify.write_meta_rig
|
||||||
|
bpy.ops.object.mode_set(mode='EDIT')
|
||||||
|
obj = bpy.context.active_object
|
||||||
|
arm = obj.data
|
||||||
|
bone = arm.edit_bones.new('Bone')
|
||||||
|
bone.head[:] = 0.0000, 0.0000, 0.0000
|
||||||
|
bone.tail[:] = 0.0000, 0.0000, 1.0000
|
||||||
|
bone.roll = 0.0000
|
||||||
|
bone.connected = False
|
||||||
|
|
||||||
|
bpy.ops.object.mode_set(mode='OBJECT')
|
||||||
|
pbone = obj.pose.bones['Bone']
|
||||||
|
pbone['type'] = 'copy'
|
||||||
|
|
||||||
|
|
||||||
|
def metarig_definition(obj, orig_bone_name):
|
||||||
|
bb = obj.data.bones
|
||||||
|
bone = bb[orig_bone_name]
|
||||||
|
chain = []
|
||||||
|
|
||||||
|
try:
|
||||||
|
chain += [bone.parent.parent.name, bone.parent.name, bone.name]
|
||||||
|
except AttributeError:
|
||||||
|
raise RigifyError("'%s' rig type requires a chain of two parents (bone: %s)" % (RIG_TYPE, base_names[0]))
|
||||||
|
|
||||||
|
chain += [child.name for child in bone.children_recursive_basename]
|
||||||
|
|
||||||
|
if len(chain) < 10:
|
||||||
|
raise RigifyError("'%s' rig type requires a chain of 10 bones (bone: %s)" % (RIG_TYPE, base_names[0]))
|
||||||
|
|
||||||
|
chain = chain[:10]
|
||||||
|
|
||||||
|
try:
|
||||||
|
chain += [bb[chain[9]].children[0].name]
|
||||||
|
chain += [bb[chain[10]].children[0].name]
|
||||||
|
except IndexError:
|
||||||
|
raise RigifyError("'%s' rig type requires a chain of 10 bones (bone: %s)" % (RIG_TYPE, base_names[0]))
|
||||||
|
|
||||||
|
return chain
|
||||||
|
|
||||||
|
|
||||||
|
def deform(obj, definitions, base_names, options):
|
||||||
|
bpy.ops.object.mode_set(mode='EDIT')
|
||||||
|
|
||||||
|
eb = obj.data.edit_bones
|
||||||
|
pb = obj.pose.bones
|
||||||
|
|
||||||
|
|
||||||
|
# Upper lid MCH
|
||||||
|
lid1 = make_lid_stretch_bone(obj, "MCH-lid", definitions[2], definitions[3], 1.0)
|
||||||
|
lid2 = make_lid_stretch_bone(obj, "MCH-lid", definitions[3], definitions[4], 1.0)
|
||||||
|
lid22 = make_lid_stretch_bone(obj, "MCH-lid", definitions[4], definitions[5], 1.0)
|
||||||
|
lid33 = make_lid_stretch_bone(obj, "MCH-lid", definitions[4], definitions[3], 1.0)
|
||||||
|
lid3 = make_lid_stretch_bone(obj, "MCH-lid", definitions[5], definitions[4], 1.0)
|
||||||
|
lid4 = make_lid_stretch_bone(obj, "MCH-lid", definitions[6], definitions[5], 1.0)
|
||||||
|
|
||||||
|
dlid22 = copy_bone_simple(obj.data, lid22, "MCH-lid", parent=True).name
|
||||||
|
dlid33 = copy_bone_simple(obj.data, lid33, "MCH-lid", parent=True).name
|
||||||
|
eb[dlid22].bbone_segments = 8
|
||||||
|
eb[dlid33].bbone_segments = 8
|
||||||
|
|
||||||
|
eb[lid1].parent = eb[definitions[2]]
|
||||||
|
eb[lid2].parent = eb[definitions[3]]
|
||||||
|
eb[lid22].parent = eb[definitions[4]]
|
||||||
|
eb[lid33].parent = eb[definitions[4]]
|
||||||
|
eb[lid3].parent = eb[definitions[5]]
|
||||||
|
eb[lid4].parent = eb[definitions[6]]
|
||||||
|
|
||||||
|
# Lower lid MCH
|
||||||
|
lid5 = make_lid_stretch_bone(obj, "MCH-lid", definitions[6], definitions[7], 1.0)
|
||||||
|
lid6 = make_lid_stretch_bone(obj, "MCH-lid", definitions[7], definitions[8], 1.0)
|
||||||
|
lid66 = make_lid_stretch_bone(obj, "MCH-lid", definitions[8], definitions[9], 1.0)
|
||||||
|
lid77 = make_lid_stretch_bone(obj, "MCH-lid", definitions[8], definitions[7], 1.0)
|
||||||
|
lid7 = make_lid_stretch_bone(obj, "MCH-lid", definitions[9], definitions[8], 1.0)
|
||||||
|
lid8 = make_lid_stretch_bone(obj, "MCH-lid", definitions[2], definitions[9], 1.0)
|
||||||
|
|
||||||
|
dlid66 = copy_bone_simple(obj.data, lid66, "MCH-lid", parent=True).name
|
||||||
|
dlid77 = copy_bone_simple(obj.data, lid77, "MCH-lid", parent=True).name
|
||||||
|
eb[dlid66].bbone_segments = 8
|
||||||
|
eb[dlid77].bbone_segments = 8
|
||||||
|
|
||||||
|
eb[lid5].parent = eb[definitions[6]]
|
||||||
|
eb[lid6].parent = eb[definitions[7]]
|
||||||
|
eb[lid66].parent = eb[definitions[8]]
|
||||||
|
eb[lid77].parent = eb[definitions[8]]
|
||||||
|
eb[lid7].parent = eb[definitions[9]]
|
||||||
|
eb[lid8].parent = eb[definitions[2]]
|
||||||
|
|
||||||
|
# Upper lid DEF
|
||||||
|
dlid1 = copy_bone_simple(obj.data, lid1, "DEF-" + base_names[definitions[2]], parent=True).name
|
||||||
|
dlid2 = copy_bone_simple(obj.data, lid2, "DEF-" + base_names[definitions[3]], parent=True).name
|
||||||
|
dlid3 = copy_bone_simple(obj.data, lid3, "DEF-" + base_names[definitions[4]], parent=True).name
|
||||||
|
dlid4 = copy_bone_simple(obj.data, lid4, "DEF-" + base_names[definitions[5]], parent=True).name
|
||||||
|
|
||||||
|
eb[dlid2].parent = eb[dlid1]
|
||||||
|
eb[dlid22].parent = eb[dlid2]
|
||||||
|
|
||||||
|
eb[dlid3].parent = eb[dlid4]
|
||||||
|
eb[dlid33].parent = eb[dlid3]
|
||||||
|
|
||||||
|
eb[dlid2].connected = True
|
||||||
|
eb[dlid22].connected = True
|
||||||
|
eb[dlid3].connected = True
|
||||||
|
eb[dlid33].connected = True
|
||||||
|
|
||||||
|
eb[dlid1].bbone_segments = 8
|
||||||
|
eb[dlid2].bbone_segments = 8
|
||||||
|
eb[dlid3].bbone_segments = 8
|
||||||
|
eb[dlid4].bbone_segments = 8
|
||||||
|
|
||||||
|
# Lower lid DEF
|
||||||
|
dlid5 = copy_bone_simple(obj.data, lid5, "DEF-" + base_names[definitions[6]], parent=True).name
|
||||||
|
dlid6 = copy_bone_simple(obj.data, lid6, "DEF-" + base_names[definitions[7]], parent=True).name
|
||||||
|
dlid7 = copy_bone_simple(obj.data, lid7, "DEF-" + base_names[definitions[8]], parent=True).name
|
||||||
|
dlid8 = copy_bone_simple(obj.data, lid8, "DEF-" + base_names[definitions[9]], parent=True).name
|
||||||
|
|
||||||
|
eb[dlid6].parent = eb[dlid5]
|
||||||
|
eb[dlid66].parent = eb[dlid6]
|
||||||
|
|
||||||
|
eb[dlid7].parent = eb[dlid8]
|
||||||
|
eb[dlid77].parent = eb[dlid7]
|
||||||
|
|
||||||
|
eb[dlid6].connected = True
|
||||||
|
eb[dlid66].connected = True
|
||||||
|
eb[dlid7].connected = True
|
||||||
|
eb[dlid77].connected = True
|
||||||
|
|
||||||
|
eb[dlid5].bbone_segments = 8
|
||||||
|
eb[dlid6].bbone_segments = 8
|
||||||
|
eb[dlid7].bbone_segments = 8
|
||||||
|
eb[dlid8].bbone_segments = 8
|
||||||
|
|
||||||
|
|
||||||
|
bpy.ops.object.mode_set(mode='OBJECT')
|
||||||
|
|
||||||
|
# Constraints
|
||||||
|
con = pb[dlid1].constraints.new('COPY_TRANSFORMS')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = lid1
|
||||||
|
|
||||||
|
con = pb[dlid22].constraints.new('COPY_TRANSFORMS')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = lid22
|
||||||
|
|
||||||
|
con = pb[dlid33].constraints.new('COPY_TRANSFORMS')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = lid33
|
||||||
|
|
||||||
|
con = pb[dlid2].constraints.new('COPY_TRANSFORMS')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = lid2
|
||||||
|
|
||||||
|
con = pb[dlid3].constraints.new('COPY_TRANSFORMS')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = lid3
|
||||||
|
|
||||||
|
con = pb[dlid4].constraints.new('COPY_TRANSFORMS')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = lid4
|
||||||
|
|
||||||
|
con = pb[dlid5].constraints.new('COPY_TRANSFORMS')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = lid5
|
||||||
|
|
||||||
|
con = pb[dlid6].constraints.new('COPY_TRANSFORMS')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = lid6
|
||||||
|
|
||||||
|
con = pb[dlid66].constraints.new('COPY_TRANSFORMS')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = lid66
|
||||||
|
|
||||||
|
con = pb[dlid77].constraints.new('COPY_TRANSFORMS')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = lid77
|
||||||
|
|
||||||
|
con = pb[dlid7].constraints.new('COPY_TRANSFORMS')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = lid7
|
||||||
|
|
||||||
|
con = pb[dlid8].constraints.new('COPY_TRANSFORMS')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = lid8
|
||||||
|
|
||||||
|
return (None,)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def control(obj, definitions, base_names, options):
|
||||||
|
bpy.ops.object.mode_set(mode='EDIT')
|
||||||
|
|
||||||
|
eb = obj.data.edit_bones
|
||||||
|
bb = obj.data.bones
|
||||||
|
pb = obj.pose.bones
|
||||||
|
|
||||||
|
head_e = eb[definitions[0]]
|
||||||
|
eye_e = eb[definitions[1]]
|
||||||
|
|
||||||
|
|
||||||
|
# Make eye "flower"
|
||||||
|
flo1 = copy_bone_simple(obj.data, definitions[1], "MCH-"+base_names[definitions[2]]+".flower", parent=True).name
|
||||||
|
flo2 = copy_bone_simple(obj.data, definitions[1], "MCH-"+base_names[definitions[3]]+".flower", parent=True).name
|
||||||
|
flo3 = copy_bone_simple(obj.data, definitions[1], "MCH-"+base_names[definitions[4]]+".flower", parent=True).name
|
||||||
|
flo4 = copy_bone_simple(obj.data, definitions[1], "MCH-"+base_names[definitions[5]]+".flower", parent=True).name
|
||||||
|
flo5 = copy_bone_simple(obj.data, definitions[1], "MCH-"+base_names[definitions[6]]+".flower", parent=True).name
|
||||||
|
flo6 = copy_bone_simple(obj.data, definitions[1], "MCH-"+base_names[definitions[7]]+".flower", parent=True).name
|
||||||
|
flo7 = copy_bone_simple(obj.data, definitions[1], "MCH-"+base_names[definitions[8]]+".flower", parent=True).name
|
||||||
|
flo8 = copy_bone_simple(obj.data, definitions[1], "MCH-"+base_names[definitions[9]]+".flower", parent=True).name
|
||||||
|
|
||||||
|
eb[flo1].tail = eb[definitions[2]].head
|
||||||
|
eb[flo2].tail = eb[definitions[3]].head
|
||||||
|
eb[flo3].tail = eb[definitions[4]].head
|
||||||
|
eb[flo4].tail = eb[definitions[5]].head
|
||||||
|
eb[flo5].tail = eb[definitions[6]].head
|
||||||
|
eb[flo6].tail = eb[definitions[7]].head
|
||||||
|
eb[flo7].tail = eb[definitions[8]].head
|
||||||
|
eb[flo8].tail = eb[definitions[9]].head
|
||||||
|
|
||||||
|
|
||||||
|
# Make eye lids on tips of flowers
|
||||||
|
flid1 = copy_bone_simple(obj.data, definitions[2], "MCH-"+base_names[definitions[2]]).name
|
||||||
|
flid2 = copy_bone_simple(obj.data, definitions[3], "MCH-"+base_names[definitions[3]]).name
|
||||||
|
flid3 = copy_bone_simple(obj.data, definitions[4], "MCH-"+base_names[definitions[4]]).name
|
||||||
|
flid4 = copy_bone_simple(obj.data, definitions[5], "MCH-"+base_names[definitions[5]]).name
|
||||||
|
flid5 = copy_bone_simple(obj.data, definitions[6], "MCH-"+base_names[definitions[6]]).name
|
||||||
|
flid6 = copy_bone_simple(obj.data, definitions[7], "MCH-"+base_names[definitions[7]]).name
|
||||||
|
flid7 = copy_bone_simple(obj.data, definitions[8], "MCH-"+base_names[definitions[8]]).name
|
||||||
|
flid8 = copy_bone_simple(obj.data, definitions[9], "MCH-"+base_names[definitions[9]]).name
|
||||||
|
|
||||||
|
eb[flid1].parent = eb[flo1]
|
||||||
|
eb[flid2].parent = eb[flo2]
|
||||||
|
eb[flid3].parent = eb[flo3]
|
||||||
|
eb[flid4].parent = eb[flo4]
|
||||||
|
eb[flid5].parent = eb[flo5]
|
||||||
|
eb[flid6].parent = eb[flo6]
|
||||||
|
eb[flid7].parent = eb[flo7]
|
||||||
|
eb[flid8].parent = eb[flo8]
|
||||||
|
|
||||||
|
|
||||||
|
# Make eye lid controls
|
||||||
|
lid1 = copy_bone_simple(obj.data, definitions[2], base_names[definitions[2]]).name
|
||||||
|
lid2 = copy_bone_simple(obj.data, definitions[3], base_names[definitions[3]]).name
|
||||||
|
lid3 = copy_bone_simple(obj.data, definitions[4], base_names[definitions[4]]).name
|
||||||
|
lid4 = copy_bone_simple(obj.data, definitions[5], base_names[definitions[5]]).name
|
||||||
|
lid5 = copy_bone_simple(obj.data, definitions[6], base_names[definitions[6]]).name
|
||||||
|
lid6 = copy_bone_simple(obj.data, definitions[7], base_names[definitions[7]]).name
|
||||||
|
lid7 = copy_bone_simple(obj.data, definitions[8], base_names[definitions[8]]).name
|
||||||
|
lid8 = copy_bone_simple(obj.data, definitions[9], base_names[definitions[9]]).name
|
||||||
|
|
||||||
|
size = eb[lid1].length
|
||||||
|
eb[lid1].tail = eb[lid1].head + Vector(0,size,0)
|
||||||
|
eb[lid2].tail = eb[lid2].head + Vector(0,size,0)
|
||||||
|
eb[lid3].tail = eb[lid3].head + Vector(0,size,0)
|
||||||
|
eb[lid4].tail = eb[lid4].head + Vector(0,size,0)
|
||||||
|
eb[lid5].tail = eb[lid5].head + Vector(0,size,0)
|
||||||
|
eb[lid6].tail = eb[lid6].head + Vector(0,size,0)
|
||||||
|
eb[lid7].tail = eb[lid7].head + Vector(0,size,0)
|
||||||
|
eb[lid8].tail = eb[lid8].head + Vector(0,size,0)
|
||||||
|
|
||||||
|
eb[lid1].roll = 0
|
||||||
|
eb[lid2].roll = 0
|
||||||
|
eb[lid3].roll = 0
|
||||||
|
eb[lid4].roll = 0
|
||||||
|
eb[lid5].roll = 0
|
||||||
|
eb[lid6].roll = 0
|
||||||
|
eb[lid7].roll = 0
|
||||||
|
eb[lid8].roll = 0
|
||||||
|
|
||||||
|
eb[lid1].parent = head_e
|
||||||
|
eb[lid2].parent = head_e
|
||||||
|
eb[lid3].parent = head_e
|
||||||
|
eb[lid4].parent = head_e
|
||||||
|
eb[lid5].parent = head_e
|
||||||
|
eb[lid6].parent = head_e
|
||||||
|
eb[lid7].parent = head_e
|
||||||
|
eb[lid8].parent = head_e
|
||||||
|
|
||||||
|
lower_lid_ctrl = copy_bone_simple(obj.data, definitions[10], base_names[definitions[10]]).name
|
||||||
|
upper_lid_ctrl = copy_bone_simple(obj.data, definitions[11], base_names[definitions[11]]).name
|
||||||
|
eb[lower_lid_ctrl].parent = head_e
|
||||||
|
eb[upper_lid_ctrl].parent = head_e
|
||||||
|
distance = (eb[lower_lid_ctrl].head - eb[upper_lid_ctrl].head).length
|
||||||
|
|
||||||
|
|
||||||
|
bpy.ops.object.mode_set(mode='OBJECT')
|
||||||
|
|
||||||
|
# Axis locks
|
||||||
|
pb[lower_lid_ctrl].lock_location = True, False, True
|
||||||
|
pb[upper_lid_ctrl].lock_location = True, False, True
|
||||||
|
|
||||||
|
# Add eye close action if it doesn't already exist
|
||||||
|
action_name = "eye_close"
|
||||||
|
if action_name in bpy.data.actions:
|
||||||
|
close_action = bpy.data.actions[action_name]
|
||||||
|
else:
|
||||||
|
close_action = add_action(name=action_name)
|
||||||
|
|
||||||
|
# Add close property (useful when making the animation in the action)
|
||||||
|
prop_name = "close_action"
|
||||||
|
prop = rna_idprop_ui_prop_get(pb[upper_lid_ctrl], prop_name, create=True)
|
||||||
|
pb[upper_lid_ctrl][prop_name] = 1.0
|
||||||
|
prop["soft_min"] = 0.0
|
||||||
|
prop["soft_max"] = 1.0
|
||||||
|
prop["min"] = 0.0
|
||||||
|
prop["max"] = 1.0
|
||||||
|
|
||||||
|
close_driver_path = pb[upper_lid_ctrl].path_to_id() + '["close_action"]'
|
||||||
|
|
||||||
|
# Constraints
|
||||||
|
|
||||||
|
# Flowers track lid controls
|
||||||
|
con = pb[flo1].constraints.new('DAMPED_TRACK')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = lid1
|
||||||
|
|
||||||
|
con = pb[flo2].constraints.new('DAMPED_TRACK')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = lid2
|
||||||
|
|
||||||
|
con = pb[flo3].constraints.new('DAMPED_TRACK')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = lid3
|
||||||
|
|
||||||
|
con = pb[flo4].constraints.new('DAMPED_TRACK')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = lid4
|
||||||
|
|
||||||
|
con = pb[flo5].constraints.new('DAMPED_TRACK')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = lid5
|
||||||
|
|
||||||
|
con = pb[flo6].constraints.new('DAMPED_TRACK')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = lid6
|
||||||
|
|
||||||
|
con = pb[flo7].constraints.new('DAMPED_TRACK')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = lid7
|
||||||
|
|
||||||
|
con = pb[flo8].constraints.new('DAMPED_TRACK')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = lid8
|
||||||
|
|
||||||
|
|
||||||
|
# ORG bones to flower lids
|
||||||
|
con = pb[definitions[2]].constraints.new('COPY_TRANSFORMS')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = flid1
|
||||||
|
|
||||||
|
con = pb[definitions[3]].constraints.new('COPY_TRANSFORMS')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = flid2
|
||||||
|
|
||||||
|
con = pb[definitions[4]].constraints.new('COPY_TRANSFORMS')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = flid3
|
||||||
|
|
||||||
|
con = pb[definitions[5]].constraints.new('COPY_TRANSFORMS')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = flid4
|
||||||
|
|
||||||
|
con = pb[definitions[6]].constraints.new('COPY_TRANSFORMS')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = flid5
|
||||||
|
|
||||||
|
con = pb[definitions[7]].constraints.new('COPY_TRANSFORMS')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = flid6
|
||||||
|
|
||||||
|
con = pb[definitions[8]].constraints.new('COPY_TRANSFORMS')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = flid7
|
||||||
|
|
||||||
|
con = pb[definitions[9]].constraints.new('COPY_TRANSFORMS')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = flid8
|
||||||
|
|
||||||
|
|
||||||
|
# Action constraints, upper lid
|
||||||
|
con = pb[lid1].constraints.new('ACTION')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = upper_lid_ctrl
|
||||||
|
con.action = close_action
|
||||||
|
con.transform_channel = 'LOCATION_Y'
|
||||||
|
con.start_frame = -30
|
||||||
|
con.end_frame = 30
|
||||||
|
con.minimum = -distance*2
|
||||||
|
con.maximum = distance
|
||||||
|
con.target_space = 'LOCAL'
|
||||||
|
fcurve = con.driver_add("influence", 0)
|
||||||
|
driver = fcurve.driver
|
||||||
|
driver.type = 'AVERAGE'
|
||||||
|
var = driver.variables.new()
|
||||||
|
var.targets[0].id_type = 'OBJECT'
|
||||||
|
var.targets[0].id = obj
|
||||||
|
var.targets[0].data_path = close_driver_path
|
||||||
|
|
||||||
|
|
||||||
|
con = pb[lid2].constraints.new('ACTION')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = upper_lid_ctrl
|
||||||
|
con.action = close_action
|
||||||
|
con.transform_channel = 'LOCATION_Y'
|
||||||
|
con.start_frame = -30
|
||||||
|
con.end_frame = 30
|
||||||
|
con.minimum = -distance*2
|
||||||
|
con.maximum = distance
|
||||||
|
con.target_space = 'LOCAL'
|
||||||
|
fcurve = con.driver_add("influence", 0)
|
||||||
|
driver = fcurve.driver
|
||||||
|
driver.type = 'AVERAGE'
|
||||||
|
var = driver.variables.new()
|
||||||
|
var.targets[0].id_type = 'OBJECT'
|
||||||
|
var.targets[0].id = obj
|
||||||
|
var.targets[0].data_path = close_driver_path
|
||||||
|
|
||||||
|
con = pb[lid3].constraints.new('ACTION')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = upper_lid_ctrl
|
||||||
|
con.action = close_action
|
||||||
|
con.transform_channel = 'LOCATION_Y'
|
||||||
|
con.start_frame = -30
|
||||||
|
con.end_frame = 30
|
||||||
|
con.minimum = -distance*2
|
||||||
|
con.maximum = distance
|
||||||
|
con.target_space = 'LOCAL'
|
||||||
|
fcurve = con.driver_add("influence", 0)
|
||||||
|
driver = fcurve.driver
|
||||||
|
driver.type = 'AVERAGE'
|
||||||
|
var = driver.variables.new()
|
||||||
|
var.targets[0].id_type = 'OBJECT'
|
||||||
|
var.targets[0].id = obj
|
||||||
|
var.targets[0].data_path = close_driver_path
|
||||||
|
|
||||||
|
con = pb[lid4].constraints.new('ACTION')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = upper_lid_ctrl
|
||||||
|
con.action = close_action
|
||||||
|
con.transform_channel = 'LOCATION_Y'
|
||||||
|
con.start_frame = -30
|
||||||
|
con.end_frame = 30
|
||||||
|
con.minimum = -distance*2
|
||||||
|
con.maximum = distance
|
||||||
|
con.target_space = 'LOCAL'
|
||||||
|
fcurve = con.driver_add("influence", 0)
|
||||||
|
driver = fcurve.driver
|
||||||
|
driver.type = 'AVERAGE'
|
||||||
|
var = driver.variables.new()
|
||||||
|
var.targets[0].id_type = 'OBJECT'
|
||||||
|
var.targets[0].id = obj
|
||||||
|
var.targets[0].data_path = close_driver_path
|
||||||
|
|
||||||
|
con = pb[lid5].constraints.new('ACTION')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = upper_lid_ctrl
|
||||||
|
con.action = close_action
|
||||||
|
con.transform_channel = 'LOCATION_Y'
|
||||||
|
con.start_frame = -30
|
||||||
|
con.end_frame = 30
|
||||||
|
con.minimum = -distance*2
|
||||||
|
con.maximum = distance
|
||||||
|
con.target_space = 'LOCAL'
|
||||||
|
fcurve = con.driver_add("influence", 0)
|
||||||
|
driver = fcurve.driver
|
||||||
|
driver.type = 'AVERAGE'
|
||||||
|
var = driver.variables.new()
|
||||||
|
var.targets[0].id_type = 'OBJECT'
|
||||||
|
var.targets[0].id = obj
|
||||||
|
var.targets[0].data_path = close_driver_path
|
||||||
|
|
||||||
|
# Action constraints, lower lid
|
||||||
|
con = pb[lid5].constraints.new('ACTION')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = lower_lid_ctrl
|
||||||
|
con.action = close_action
|
||||||
|
con.transform_channel = 'LOCATION_Y'
|
||||||
|
con.start_frame = -30
|
||||||
|
con.end_frame = 30
|
||||||
|
con.minimum = -distance
|
||||||
|
con.maximum = distance*2
|
||||||
|
con.target_space = 'LOCAL'
|
||||||
|
fcurve = con.driver_add("influence", 0)
|
||||||
|
driver = fcurve.driver
|
||||||
|
driver.type = 'AVERAGE'
|
||||||
|
var = driver.variables.new()
|
||||||
|
var.targets[0].id_type = 'OBJECT'
|
||||||
|
var.targets[0].id = obj
|
||||||
|
var.targets[0].data_path = close_driver_path
|
||||||
|
|
||||||
|
con = pb[lid6].constraints.new('ACTION')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = lower_lid_ctrl
|
||||||
|
con.action = close_action
|
||||||
|
con.transform_channel = 'LOCATION_Y'
|
||||||
|
con.start_frame = -30
|
||||||
|
con.end_frame = 30
|
||||||
|
con.minimum = -distance
|
||||||
|
con.maximum = distance*2
|
||||||
|
con.target_space = 'LOCAL'
|
||||||
|
fcurve = con.driver_add("influence", 0)
|
||||||
|
driver = fcurve.driver
|
||||||
|
driver.type = 'AVERAGE'
|
||||||
|
var = driver.variables.new()
|
||||||
|
var.targets[0].id_type = 'OBJECT'
|
||||||
|
var.targets[0].id = obj
|
||||||
|
var.targets[0].data_path = close_driver_path
|
||||||
|
|
||||||
|
con = pb[lid7].constraints.new('ACTION')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = lower_lid_ctrl
|
||||||
|
con.action = close_action
|
||||||
|
con.transform_channel = 'LOCATION_Y'
|
||||||
|
con.start_frame = -30
|
||||||
|
con.end_frame = 30
|
||||||
|
con.minimum = -distance
|
||||||
|
con.maximum = distance*2
|
||||||
|
con.target_space = 'LOCAL'
|
||||||
|
fcurve = con.driver_add("influence", 0)
|
||||||
|
driver = fcurve.driver
|
||||||
|
driver.type = 'AVERAGE'
|
||||||
|
var = driver.variables.new()
|
||||||
|
var.targets[0].id_type = 'OBJECT'
|
||||||
|
var.targets[0].id = obj
|
||||||
|
var.targets[0].data_path = close_driver_path
|
||||||
|
|
||||||
|
con = pb[lid8].constraints.new('ACTION')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = lower_lid_ctrl
|
||||||
|
con.action = close_action
|
||||||
|
con.transform_channel = 'LOCATION_Y'
|
||||||
|
con.start_frame = -30
|
||||||
|
con.end_frame = 30
|
||||||
|
con.minimum = -distance
|
||||||
|
con.maximum = distance*2
|
||||||
|
con.target_space = 'LOCAL'
|
||||||
|
fcurve = con.driver_add("influence", 0)
|
||||||
|
driver = fcurve.driver
|
||||||
|
driver.type = 'AVERAGE'
|
||||||
|
var = driver.variables.new()
|
||||||
|
var.targets[0].id_type = 'OBJECT'
|
||||||
|
var.targets[0].id = obj
|
||||||
|
var.targets[0].data_path = close_driver_path
|
||||||
|
|
||||||
|
con = pb[lid1].constraints.new('ACTION')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = lower_lid_ctrl
|
||||||
|
con.action = close_action
|
||||||
|
con.transform_channel = 'LOCATION_Y'
|
||||||
|
con.start_frame = -30
|
||||||
|
con.end_frame = 30
|
||||||
|
con.minimum = -distance
|
||||||
|
con.maximum = distance*2
|
||||||
|
con.target_space = 'LOCAL'
|
||||||
|
fcurve = con.driver_add("influence", 0)
|
||||||
|
driver = fcurve.driver
|
||||||
|
driver.type = 'AVERAGE'
|
||||||
|
var = driver.variables.new()
|
||||||
|
var.targets[0].id_type = 'OBJECT'
|
||||||
|
var.targets[0].id = obj
|
||||||
|
var.targets[0].data_path = close_driver_path
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Set layers
|
||||||
|
layer = list(bb[definitions[2]].layer)
|
||||||
|
bb[lid1].layer = layer
|
||||||
|
bb[lid2].layer = layer
|
||||||
|
bb[lid3].layer = layer
|
||||||
|
bb[lid4].layer = layer
|
||||||
|
bb[lid5].layer = layer
|
||||||
|
bb[lid6].layer = layer
|
||||||
|
bb[lid7].layer = layer
|
||||||
|
bb[lid8].layer = layer
|
||||||
|
|
||||||
|
|
||||||
|
return (None,)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def main(obj, bone_definition, base_names, options):
|
||||||
|
# Create control rig
|
||||||
|
control(obj, bone_definition, base_names, options)
|
||||||
|
# Create deform rig
|
||||||
|
deform(obj, bone_definition, base_names, options)
|
||||||
|
|
||||||
|
return (None,)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def make_lid_stretch_bone(obj, name, bone1, bone2, roll_alpha):
|
||||||
|
eb = obj.data.edit_bones
|
||||||
|
pb = obj.pose.bones
|
||||||
|
|
||||||
|
# Create the bone, pointing from bone1 to bone2
|
||||||
|
bone_e = copy_bone_simple(obj.data, bone1, name, parent=True)
|
||||||
|
bone_e.connected = False
|
||||||
|
bone_e.tail = eb[bone2].head
|
||||||
|
bone = bone_e.name
|
||||||
|
|
||||||
|
# Align the bone roll with the average direction of bone1 and bone2
|
||||||
|
vec = bone_e.y_axis.cross(((1.0-roll_alpha)*eb[bone1].y_axis) + (roll_alpha*eb[bone2].y_axis)).normalize()
|
||||||
|
|
||||||
|
ang = acos(vec * bone_e.x_axis)
|
||||||
|
|
||||||
|
bone_e.roll += ang
|
||||||
|
c1 = vec * bone_e.x_axis
|
||||||
|
bone_e.roll -= (ang*2)
|
||||||
|
c2 = vec * bone_e.x_axis
|
||||||
|
|
||||||
|
if c1 > c2:
|
||||||
|
bone_e.roll += (ang*2)
|
||||||
|
|
||||||
|
bpy.ops.object.mode_set(mode='OBJECT')
|
||||||
|
bone_p = pb[bone]
|
||||||
|
|
||||||
|
# Constrains
|
||||||
|
con = bone_p.constraints.new('COPY_LOCATION')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = bone1
|
||||||
|
|
||||||
|
con = bone_p.constraints.new('DAMPED_TRACK')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = bone2
|
||||||
|
|
||||||
|
con = bone_p.constraints.new('STRETCH_TO')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = bone2
|
||||||
|
con.volume = 'NO_VOLUME'
|
||||||
|
|
||||||
|
bpy.ops.object.mode_set(mode='EDIT')
|
||||||
|
|
||||||
|
return bone
|
||||||
@@ -150,103 +150,171 @@ def deform(obj, definitions, base_names, options):
|
|||||||
|
|
||||||
def main(obj, bone_definition, base_names, options):
|
def main(obj, bone_definition, base_names, options):
|
||||||
# *** EDITMODE
|
# *** EDITMODE
|
||||||
|
bpy.ops.object.mode_set(mode='EDIT')
|
||||||
|
|
||||||
# get assosiated data
|
# get assosiated data
|
||||||
arm = obj.data
|
arm = obj.data
|
||||||
orig_ebone = arm.edit_bones[bone_definition[0]]
|
bb = obj.data.bones
|
||||||
|
eb = obj.data.edit_bones
|
||||||
|
pb = obj.pose.bones
|
||||||
|
|
||||||
|
org_f1 = bone_definition[0] # Original finger bone 01
|
||||||
|
org_f2 = bone_definition[1] # Original finger bone 02
|
||||||
|
org_f3 = bone_definition[2] # Original finger bone 03
|
||||||
|
|
||||||
|
# Check options
|
||||||
|
if "bend_ratio" in options:
|
||||||
|
bend_ratio = options["bend_ratio"]
|
||||||
|
else:
|
||||||
|
bend_ratio = 0.4
|
||||||
|
|
||||||
|
yes = [1, 1.0, True, "True", "true", "Yes", "yes"]
|
||||||
|
make_hinge = False
|
||||||
|
if ("hinge" in options) and (eb[org_f1].parent is not None):
|
||||||
|
if options["hinge"] in yes:
|
||||||
|
make_hinge = True
|
||||||
|
|
||||||
obj.animation_data_create() # needed if its a new armature with no keys
|
|
||||||
|
# Needed if its a new armature with no keys
|
||||||
children = orig_ebone.children_recursive
|
obj.animation_data_create()
|
||||||
tot_len = reduce(lambda f, ebone: f + ebone.length, children, orig_ebone.length)
|
|
||||||
|
|
||||||
# FIXME, the line below is far too arbitrary
|
|
||||||
base_name = base_names[bone_definition[0]].rsplit(".", 2)[0]
|
|
||||||
|
|
||||||
# first make a new bone at the location of the finger
|
|
||||||
#control_ebone = arm.edit_bones.new(base_name)
|
|
||||||
control_ebone = copy_bone_simple(arm, bone_definition[0], base_name + get_side_name(base_names[bone_definition[0]]), parent=True)
|
|
||||||
control_bone_name = control_ebone.name # we dont know if we get the name requested
|
|
||||||
|
|
||||||
control_ebone.connected = orig_ebone.connected
|
|
||||||
control_ebone.parent = orig_ebone.parent
|
|
||||||
control_ebone.length = tot_len
|
|
||||||
|
|
||||||
# now add bones inbetween this and its children recursively
|
|
||||||
|
|
||||||
# switching modes so store names only!
|
|
||||||
children = [ebone.name for ebone in children]
|
|
||||||
|
|
||||||
driver_bone_pairs = []
|
|
||||||
|
|
||||||
for child_bone_name in children:
|
|
||||||
child_ebone = arm.edit_bones[child_bone_name]
|
|
||||||
|
|
||||||
# finger.02 --> finger_driver.02
|
|
||||||
driver_bone_name = child_bone_name.split('.')
|
|
||||||
driver_bone_name = driver_bone_name[0] + "_driver." + ".".join(driver_bone_name[1:])
|
|
||||||
|
|
||||||
driver_ebone = copy_bone_simple(arm, child_ebone.name, driver_bone_name)
|
|
||||||
driver_ebone.length *= 0.5
|
|
||||||
|
|
||||||
# Insert driver_ebone in the chain without connected parents
|
|
||||||
driver_ebone.connected = False
|
|
||||||
driver_ebone.parent = child_ebone.parent
|
|
||||||
|
|
||||||
child_ebone.connected = False
|
|
||||||
child_ebone.parent = driver_ebone
|
|
||||||
|
|
||||||
# Add the drivers to these when in posemode.
|
|
||||||
driver_bone_pairs.append((child_bone_name, driver_bone_name))
|
|
||||||
|
|
||||||
del control_ebone
|
|
||||||
|
|
||||||
|
# Create the control bone
|
||||||
|
base_name = base_names[bone_definition[0]].split(".", 1)[0]
|
||||||
|
tot_len = eb[org_f1].length + eb[org_f2].length + eb[org_f3].length
|
||||||
|
control = copy_bone_simple(arm, bone_definition[0], base_name + get_side_name(base_names[bone_definition[0]]), parent=True).name
|
||||||
|
eb[control].connected = eb[org_f1].connected
|
||||||
|
eb[control].parent = eb[org_f1].parent
|
||||||
|
eb[control].length = tot_len
|
||||||
|
|
||||||
|
# Create secondary control bones
|
||||||
|
f1 = copy_bone_simple(arm, bone_definition[0], base_names[bone_definition[0]]).name
|
||||||
|
f2 = copy_bone_simple(arm, bone_definition[1], base_names[bone_definition[1]]).name
|
||||||
|
f3 = copy_bone_simple(arm, bone_definition[2], base_names[bone_definition[2]]).name
|
||||||
|
|
||||||
|
# Create driver bones
|
||||||
|
df1 = copy_bone_simple(arm, bone_definition[0], "MCH-" + base_names[bone_definition[0]]).name
|
||||||
|
eb[df1].length /= 2
|
||||||
|
df2 = copy_bone_simple(arm, bone_definition[1], "MCH-" + base_names[bone_definition[1]]).name
|
||||||
|
eb[df2].length /= 2
|
||||||
|
df3 = copy_bone_simple(arm, bone_definition[2], "MCH-" + base_names[bone_definition[2]]).name
|
||||||
|
eb[df3].length /= 2
|
||||||
|
|
||||||
|
# Set parents of the bones, interleaving the driver bones with the secondary control bones
|
||||||
|
eb[f3].connected = False
|
||||||
|
eb[df3].connected = False
|
||||||
|
eb[f2].connected = False
|
||||||
|
eb[df2].connected = False
|
||||||
|
eb[f1].connected = False
|
||||||
|
eb[df1].connected = eb[org_f1].connected
|
||||||
|
|
||||||
|
eb[f3].parent = eb[df3]
|
||||||
|
eb[df3].parent = eb[f2]
|
||||||
|
eb[f2].parent = eb[df2]
|
||||||
|
eb[df2].parent = eb[f1]
|
||||||
|
eb[f1].parent = eb[df1]
|
||||||
|
eb[df1].parent = eb[org_f1].parent
|
||||||
|
|
||||||
|
# Set up bones for hinge
|
||||||
|
if make_hinge:
|
||||||
|
socket = copy_bone_simple(arm, org_f1, "MCH-socket_"+control, parent=True).name
|
||||||
|
hinge = copy_bone_simple(arm, eb[org_f1].parent.name, "MCH-hinge_"+control).name
|
||||||
|
|
||||||
|
eb[control].connected = False
|
||||||
|
eb[control].parent = eb[hinge]
|
||||||
|
|
||||||
|
# Create the deform rig while we're still in edit mode
|
||||||
deform(obj, bone_definition, base_names, options)
|
deform(obj, bone_definition, base_names, options)
|
||||||
|
|
||||||
|
|
||||||
# *** POSEMODE
|
# *** POSEMODE
|
||||||
bpy.ops.object.mode_set(mode='OBJECT')
|
bpy.ops.object.mode_set(mode='OBJECT')
|
||||||
|
|
||||||
|
# Set rotation modes and axis locks
|
||||||
orig_pbone = obj.pose.bones[bone_definition[0]]
|
pb[control].rotation_mode = obj.pose.bones[bone_definition[0]].rotation_mode
|
||||||
control_pbone = obj.pose.bones[control_bone_name]
|
pb[control].lock_location = True, True, True
|
||||||
control_bbone = arm.bones[control_bone_name]
|
pb[control].lock_scale = True, False, True
|
||||||
control_pbone.rotation_mode = obj.pose.bones[bone_definition[0]].rotation_mode
|
pb[f1].rotation_mode = 'YZX'
|
||||||
|
pb[f2].rotation_mode = 'YZX'
|
||||||
|
pb[f3].rotation_mode = 'YZX'
|
||||||
# only allow Y scale
|
pb[f1].lock_location = True, True, True
|
||||||
control_pbone.lock_scale = (True, False, True)
|
pb[f2].lock_location = True, True, True
|
||||||
|
pb[f3].lock_location = True, True, True
|
||||||
control_pbone["bend_ratio"] = 0.4
|
pb[df2].rotation_mode = 'YZX'
|
||||||
prop = rna_idprop_ui_prop_get(control_pbone, "bend_ratio", create=True)
|
pb[df3].rotation_mode = 'YZX'
|
||||||
|
|
||||||
|
# Add the bend_ratio property to the control bone
|
||||||
|
pb[control]["bend_ratio"] = bend_ratio
|
||||||
|
prop = rna_idprop_ui_prop_get(pb[control], "bend_ratio", create=True)
|
||||||
prop["soft_min"] = 0.0
|
prop["soft_min"] = 0.0
|
||||||
prop["soft_max"] = 1.0
|
prop["soft_max"] = 1.0
|
||||||
|
|
||||||
con = orig_pbone.constraints.new('COPY_LOCATION')
|
# Add hinge property to the control bone
|
||||||
|
if make_hinge:
|
||||||
|
pb[control]["hinge"] = 0.0
|
||||||
|
prop = rna_idprop_ui_prop_get(pb[control], "hinge", create=True)
|
||||||
|
prop["soft_min"] = 0.0
|
||||||
|
prop["soft_max"] = 1.0
|
||||||
|
|
||||||
|
# Constraints
|
||||||
|
con = pb[df1].constraints.new('COPY_LOCATION')
|
||||||
con.target = obj
|
con.target = obj
|
||||||
con.subtarget = control_bone_name
|
con.subtarget = control
|
||||||
|
|
||||||
con = orig_pbone.constraints.new('COPY_ROTATION')
|
con = pb[df1].constraints.new('COPY_ROTATION')
|
||||||
con.target = obj
|
con.target = obj
|
||||||
con.subtarget = control_bone_name
|
con.subtarget = control
|
||||||
|
|
||||||
|
con = pb[org_f1].constraints.new('COPY_TRANSFORMS')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = f1
|
||||||
|
|
||||||
|
con = pb[org_f2].constraints.new('COPY_TRANSFORMS')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = f2
|
||||||
|
|
||||||
|
con = pb[org_f3].constraints.new('COPY_TRANSFORMS')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = f3
|
||||||
|
|
||||||
|
if make_hinge:
|
||||||
|
con = pb[hinge].constraints.new('COPY_TRANSFORMS')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = bb[org_f1].parent.name
|
||||||
|
|
||||||
|
hinge_driver_path = pb[control].path_to_id() + '["hinge"]'
|
||||||
|
|
||||||
|
fcurve = con.driver_add("influence", 0)
|
||||||
|
driver = fcurve.driver
|
||||||
|
var = driver.variables.new()
|
||||||
|
driver.type = 'AVERAGE'
|
||||||
|
var.name = "var"
|
||||||
|
var.targets[0].id_type = 'OBJECT'
|
||||||
|
var.targets[0].id = obj
|
||||||
|
var.targets[0].data_path = hinge_driver_path
|
||||||
|
|
||||||
|
mod = fcurve.modifiers[0]
|
||||||
# setup child drivers on each new smaller bone added. assume 2 for now.
|
mod.poly_order = 1
|
||||||
|
mod.coefficients[0] = 1.0
|
||||||
# drives the bones
|
mod.coefficients[1] = -1.0
|
||||||
controller_path = control_pbone.path_to_id() # 'pose.bones["%s"]' % control_bone_name
|
|
||||||
|
con = pb[control].constraints.new('COPY_LOCATION')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = socket
|
||||||
|
|
||||||
|
# Create the drivers for the driver bones (control bone scale rotates driver bones)
|
||||||
|
controller_path = pb[control].path_to_id() # 'pose.bones["%s"]' % control_bone_name
|
||||||
|
|
||||||
i = 0
|
i = 0
|
||||||
for child_bone_name, driver_bone_name in driver_bone_pairs:
|
for bone in [df2, df3]:
|
||||||
|
|
||||||
# XXX - todo, any number
|
# XXX - todo, any number
|
||||||
if i == 2:
|
if i == 2:
|
||||||
break
|
break
|
||||||
|
|
||||||
driver_pbone = obj.pose.bones[driver_bone_name]
|
pbone = pb[bone]
|
||||||
|
|
||||||
driver_pbone.rotation_mode = 'YZX'
|
pbone.rotation_mode = 'YZX'
|
||||||
fcurve_driver = driver_pbone.driver_add("rotation_euler", 0)
|
fcurve_driver = pbone.driver_add("rotation_euler", 0)
|
||||||
|
|
||||||
#obj.driver_add('pose.bones["%s"].scale', 1)
|
#obj.driver_add('pose.bones["%s"].scale', 1)
|
||||||
#obj.animation_data.drivers[-1] # XXX, WATCH THIS
|
#obj.animation_data.drivers[-1] # XXX, WATCH THIS
|
||||||
@@ -272,24 +340,18 @@ def main(obj, bone_definition, base_names, options):
|
|||||||
elif i == 1:
|
elif i == 1:
|
||||||
driver.expression = '(-scale+1.0)*pi*2.0*br'
|
driver.expression = '(-scale+1.0)*pi*2.0*br'
|
||||||
|
|
||||||
child_pbone = obj.pose.bones[child_bone_name]
|
|
||||||
|
|
||||||
# only allow X rotation
|
|
||||||
driver_pbone.lock_rotation = child_pbone.lock_rotation = (False, True, True)
|
|
||||||
|
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
|
# Last step setup layers
|
||||||
# last step setup layers
|
|
||||||
if "ex_layer" in options:
|
if "ex_layer" in options:
|
||||||
layer = [n==options["ex_layer"] for n in range(0,32)]
|
layer = [n==options["ex_layer"] for n in range(0,32)]
|
||||||
else:
|
else:
|
||||||
layer = list(arm.bones[bone_definition[0]].layer)
|
layer = list(arm.bones[bone_definition[0]].layer)
|
||||||
for child_bone_name, driver_bone_name in driver_bone_pairs:
|
for bone_name in [f1, f2, f3]:
|
||||||
arm.bones[driver_bone_name].layer = layer
|
arm.bones[bone_name].layer = layer
|
||||||
|
|
||||||
layer = list(arm.bones[bone_definition[0]].layer)
|
layer = list(arm.bones[bone_definition[0]].layer)
|
||||||
control_bbone.layer = layer
|
bb[control].layer = layer
|
||||||
|
|
||||||
# no blending the result of this
|
# no blending the result of this
|
||||||
return None
|
return None
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
# <pep8 compliant>
|
# <pep8 compliant>
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
|
from math import pi
|
||||||
from rigify import RigifyError, get_layer_dict
|
from rigify import RigifyError, get_layer_dict
|
||||||
from rigify_utils import bone_class_instance, copy_bone_simple, blend_bone_list, get_side_name, get_base_name
|
from rigify_utils import bone_class_instance, copy_bone_simple, blend_bone_list, get_side_name, get_base_name
|
||||||
from rna_prop_ui import rna_idprop_ui_prop_get
|
from rna_prop_ui import rna_idprop_ui_prop_get
|
||||||
@@ -219,12 +220,14 @@ def ik(obj, bone_definition, base_names, options):
|
|||||||
ik.foot_roll_p.lock_rotation = False, True, True
|
ik.foot_roll_p.lock_rotation = False, True, True
|
||||||
ik_chain.toe_p.rotation_mode = 'YXZ'
|
ik_chain.toe_p.rotation_mode = 'YXZ'
|
||||||
ik_chain.toe_p.lock_rotation = False, True, True
|
ik_chain.toe_p.lock_rotation = False, True, True
|
||||||
|
ik_chain.toe_p.lock_location = True, True, True
|
||||||
|
ik.foot_roll_p.lock_location = True, True, True
|
||||||
|
|
||||||
# IK
|
# IK
|
||||||
con = ik_chain.shin_p.constraints.new('IK')
|
con = ik_chain.shin_p.constraints.new('IK')
|
||||||
con.chain_length = 2
|
con.chain_length = 2
|
||||||
con.iterations = 500
|
con.iterations = 500
|
||||||
con.pole_angle = -90.0 # XXX - in deg!
|
con.pole_angle = -pi/2
|
||||||
con.use_tail = True
|
con.use_tail = True
|
||||||
con.use_stretch = True
|
con.use_stretch = True
|
||||||
con.use_target = True
|
con.use_target = True
|
||||||
@@ -329,6 +332,7 @@ def fk(obj, bone_definition, base_names, options):
|
|||||||
foot_p.rotation_mode = 'YXZ'
|
foot_p.rotation_mode = 'YXZ'
|
||||||
fk_chain.toe_p.rotation_mode = 'YXZ'
|
fk_chain.toe_p.rotation_mode = 'YXZ'
|
||||||
fk_chain.toe_p.lock_rotation = False, True, True
|
fk_chain.toe_p.lock_rotation = False, True, True
|
||||||
|
fk_chain.thigh_p.lock_location = True, True, True
|
||||||
|
|
||||||
con = fk_chain.thigh_p.constraints.new('COPY_LOCATION')
|
con = fk_chain.thigh_p.constraints.new('COPY_LOCATION')
|
||||||
con.target = obj
|
con.target = obj
|
||||||
@@ -336,7 +340,7 @@ def fk(obj, bone_definition, base_names, options):
|
|||||||
|
|
||||||
# hinge
|
# hinge
|
||||||
prop = rna_idprop_ui_prop_get(fk_chain.thigh_p, "hinge", create=True)
|
prop = rna_idprop_ui_prop_get(fk_chain.thigh_p, "hinge", create=True)
|
||||||
fk_chain.thigh_p["hinge"] = 0.5
|
fk_chain.thigh_p["hinge"] = 0.0
|
||||||
prop["soft_min"] = 0.0
|
prop["soft_min"] = 0.0
|
||||||
prop["soft_max"] = 1.0
|
prop["soft_max"] = 1.0
|
||||||
|
|
||||||
@@ -441,6 +445,11 @@ def deform(obj, definitions, base_names, options):
|
|||||||
con.target = obj
|
con.target = obj
|
||||||
con.subtarget = definitions[2]
|
con.subtarget = definitions[2]
|
||||||
|
|
||||||
|
con = uleg1.constraints.new('COPY_SCALE')
|
||||||
|
con.name = "scale"
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = definitions[1]
|
||||||
|
|
||||||
con = uleg2.constraints.new('COPY_ROTATION')
|
con = uleg2.constraints.new('COPY_ROTATION')
|
||||||
con.name = "copy_rot"
|
con.name = "copy_rot"
|
||||||
con.target = obj
|
con.target = obj
|
||||||
@@ -452,6 +461,11 @@ def deform(obj, definitions, base_names, options):
|
|||||||
con.target = obj
|
con.target = obj
|
||||||
con.subtarget = definitions[2]
|
con.subtarget = definitions[2]
|
||||||
|
|
||||||
|
con = lleg1.constraints.new('COPY_SCALE')
|
||||||
|
con.name = "copy_rot"
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = definitions[2]
|
||||||
|
|
||||||
con = lleg2.constraints.new('COPY_ROTATION')
|
con = lleg2.constraints.new('COPY_ROTATION')
|
||||||
con.name = "copy_rot"
|
con.name = "copy_rot"
|
||||||
con.target = obj
|
con.target = obj
|
||||||
@@ -484,5 +498,5 @@ def main(obj, bone_definition, base_names, options):
|
|||||||
deform(obj, bone_definition, base_names, options)
|
deform(obj, bone_definition, base_names, options)
|
||||||
|
|
||||||
bpy.ops.object.mode_set(mode='OBJECT')
|
bpy.ops.object.mode_set(mode='OBJECT')
|
||||||
blend_bone_list(obj, bone_definition + [None], bones_fk, bones_ik, target_bone=bones_ik[6], target_prop="ik", blend_default=0.0)
|
blend_bone_list(obj, bone_definition + [None], bones_fk, bones_ik, target_bone=bones_ik[6], target_prop="ik", blend_default=1.0)
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,8 @@
|
|||||||
# <pep8 compliant>
|
# <pep8 compliant>
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
|
from rna_prop_ui import rna_idprop_ui_prop_get
|
||||||
|
from math import pi
|
||||||
from rigify import RigifyError
|
from rigify import RigifyError
|
||||||
from rigify_utils import bone_class_instance, copy_bone_simple, add_pole_target_bone, get_side_name, get_base_name
|
from rigify_utils import bone_class_instance, copy_bone_simple, add_pole_target_bone, get_side_name, get_base_name
|
||||||
from Mathutils import Vector
|
from Mathutils import Vector
|
||||||
@@ -104,6 +106,8 @@ def metarig_definition(obj, orig_bone_name):
|
|||||||
|
|
||||||
|
|
||||||
def ik(obj, bone_definition, base_names, options):
|
def ik(obj, bone_definition, base_names, options):
|
||||||
|
eb = obj.data.edit_bones
|
||||||
|
pb = obj.pose.bones
|
||||||
arm = obj.data
|
arm = obj.data
|
||||||
bpy.ops.object.mode_set(mode='EDIT')
|
bpy.ops.object.mode_set(mode='EDIT')
|
||||||
|
|
||||||
@@ -114,13 +118,14 @@ def ik(obj, bone_definition, base_names, options):
|
|||||||
mt.attr_initialize(METARIG_NAMES, bone_definition)
|
mt.attr_initialize(METARIG_NAMES, bone_definition)
|
||||||
mt_chain.attr_initialize(METARIG_NAMES, bone_definition)
|
mt_chain.attr_initialize(METARIG_NAMES, bone_definition)
|
||||||
|
|
||||||
ik_chain = mt_chain.copy(to_fmt="%s", base_names=base_names)
|
ik_chain = mt_chain.copy(to_fmt="MCH-%s.ik", base_names=base_names)
|
||||||
|
|
||||||
ik_chain.thigh_e.connected = False
|
ik_chain.thigh_e.connected = False
|
||||||
ik_chain.thigh_e.parent = mt.hips_e
|
ik_chain.thigh_e.parent = mt.hips_e
|
||||||
|
|
||||||
ik_chain.foot_e.parent = None
|
ik_chain.foot_e.parent = None
|
||||||
ik_chain.rename("foot", get_base_name(ik_chain.foot) + "_ik" + get_side_name(ik_chain.foot))
|
ik_chain.rename("foot", get_base_name(base_names[bone_definition[3]]) + "_ik" + get_side_name(base_names[bone_definition[3]]))
|
||||||
|
ik_chain.rename("toe", get_base_name(base_names[bone_definition[4]]) + "_ik" + get_side_name(base_names[bone_definition[4]]))
|
||||||
|
|
||||||
# keep the foot_ik as the parent
|
# keep the foot_ik as the parent
|
||||||
ik_chain.toe_e.connected = False
|
ik_chain.toe_e.connected = False
|
||||||
@@ -129,22 +134,30 @@ def ik(obj, bone_definition, base_names, options):
|
|||||||
ik_chain.foot_e.align_orientation(mt_chain.toe_e)
|
ik_chain.foot_e.align_orientation(mt_chain.toe_e)
|
||||||
|
|
||||||
# children of ik_foot
|
# children of ik_foot
|
||||||
ik = bone_class_instance(obj, ["foot_roll", "foot_roll_01", "foot_roll_02", "knee_target", "foot_target"])
|
ik = bone_class_instance(obj, ["foot_roll", "foot_roll_01", "foot_roll_02", "foot_target"])
|
||||||
|
|
||||||
ik.knee_target = add_pole_target_bone(obj, mt_chain.shin, "knee_target" + get_side_name(base_names[mt_chain.foot])) #XXX - pick a better name
|
# knee rotator
|
||||||
ik.update()
|
knee_rotator = copy_bone_simple(arm, mt_chain.toe, "knee_rotator" + get_side_name(base_names[mt_chain.foot]), parent=True).name
|
||||||
ik.knee_target_e.parent = mt.hips_e
|
eb[knee_rotator].connected = False
|
||||||
|
eb[knee_rotator].parent = eb[mt.hips]
|
||||||
|
eb[knee_rotator].head = eb[ik_chain.thigh].head
|
||||||
|
eb[knee_rotator].tail = eb[knee_rotator].head + eb[mt_chain.toe].vector
|
||||||
|
eb[knee_rotator].length = eb[ik_chain.thigh].length / 2
|
||||||
|
eb[knee_rotator].roll += pi/2
|
||||||
|
|
||||||
|
# parent ik leg to the knee rotator
|
||||||
|
eb[ik_chain.thigh].parent = eb[knee_rotator]
|
||||||
|
|
||||||
# foot roll is an interesting one!
|
# foot roll is an interesting one!
|
||||||
# plot a vector from the toe bones head, bactwards to the length of the foot
|
# plot a vector from the toe bones head, bactwards to the length of the foot
|
||||||
# then align it with the foot but reverse direction.
|
# then align it with the foot but reverse direction.
|
||||||
ik.foot_roll_e = copy_bone_simple(arm, mt_chain.toe, get_base_name(base_names[mt_chain.foot]) + "_roll" + get_side_name(base_names[mt_chain.foot]))
|
ik.foot_roll_e = copy_bone_simple(arm, mt_chain.toe, get_base_name(base_names[mt_chain.foot]) + "_roll" + get_side_name(base_names[mt_chain.foot]))
|
||||||
ik.foot_roll = ik.foot_roll_e.name
|
ik.foot_roll = ik.foot_roll_e.name
|
||||||
|
ik.foot_roll_e.connected = False
|
||||||
ik.foot_roll_e.parent = ik_chain.foot_e
|
ik.foot_roll_e.parent = ik_chain.foot_e
|
||||||
ik.foot_roll_e.translate(- (mt_chain.toe_e.vector.normalize() * mt_chain.foot_e.length))
|
ik.foot_roll_e.head -= mt_chain.toe_e.vector.normalize() * mt_chain.foot_e.length
|
||||||
ik.foot_roll_e.align_orientation(mt_chain.foot_e)
|
ik.foot_roll_e.tail = ik.foot_roll_e.head - (mt_chain.foot_e.vector.normalize() * mt_chain.toe_e.length)
|
||||||
ik.foot_roll_e.tail = ik.foot_roll_e.head - ik.foot_roll_e.vector # flip
|
ik.foot_roll_e.align_roll(mt_chain.foot_e.matrix.rotation_part() * Vector(0.0, 0.0, -1.0))
|
||||||
ik.foot_roll_e.align_roll(mt_chain.foot_e.matrix.rotationPart() * Vector(0.0, 0.0, -1.0))
|
|
||||||
|
|
||||||
# MCH-foot
|
# MCH-foot
|
||||||
ik.foot_roll_01_e = copy_bone_simple(arm, mt_chain.foot, "MCH-" + base_names[mt_chain.foot])
|
ik.foot_roll_01_e = copy_bone_simple(arm, mt_chain.foot, "MCH-" + base_names[mt_chain.foot])
|
||||||
@@ -173,23 +186,74 @@ def ik(obj, bone_definition, base_names, options):
|
|||||||
mt_chain.update()
|
mt_chain.update()
|
||||||
ik.update()
|
ik.update()
|
||||||
ik_chain.update()
|
ik_chain.update()
|
||||||
|
|
||||||
|
# Set rotation modes and axis locks
|
||||||
|
#pb[knee_rotator].rotation_mode = 'YXZ'
|
||||||
|
#pb[knee_rotator].lock_rotation = False, True, False
|
||||||
|
pb[knee_rotator].lock_location = True, True, True
|
||||||
|
pb[ik.foot_roll].rotation_mode = 'XYZ'
|
||||||
|
pb[ik.foot_roll].lock_rotation = False, True, True
|
||||||
|
pb[ik_chain.toe].rotation_mode = 'XYZ'
|
||||||
|
pb[ik_chain.toe].lock_rotation = False, True, True
|
||||||
|
|
||||||
|
# IK switch property
|
||||||
|
prop = rna_idprop_ui_prop_get(pb[ik_chain.foot], "ik", create=True)
|
||||||
|
pb[ik_chain.foot]["ik"] = 1.0
|
||||||
|
prop["soft_min"] = 0.0
|
||||||
|
prop["soft_max"] = 1.0
|
||||||
|
prop["min"] = 0.0
|
||||||
|
prop["max"] = 1.0
|
||||||
|
|
||||||
|
ik_driver_path = pb[ik_chain.foot].path_to_id() + '["ik"]'
|
||||||
|
|
||||||
# simple constraining of orig bones
|
# simple constraining of orig bones
|
||||||
con = mt_chain.thigh_p.constraints.new('COPY_TRANSFORMS')
|
con = mt_chain.thigh_p.constraints.new('COPY_TRANSFORMS')
|
||||||
con.target = obj
|
con.target = obj
|
||||||
con.subtarget = ik_chain.thigh
|
con.subtarget = ik_chain.thigh
|
||||||
|
fcurve = con.driver_add("influence", 0)
|
||||||
|
driver = fcurve.driver
|
||||||
|
var = driver.variables.new()
|
||||||
|
driver.type = 'AVERAGE'
|
||||||
|
var.name = "var"
|
||||||
|
var.targets[0].id_type = 'OBJECT'
|
||||||
|
var.targets[0].id = obj
|
||||||
|
var.targets[0].data_path = ik_driver_path
|
||||||
|
|
||||||
con = mt_chain.shin_p.constraints.new('COPY_TRANSFORMS')
|
con = mt_chain.shin_p.constraints.new('COPY_TRANSFORMS')
|
||||||
con.target = obj
|
con.target = obj
|
||||||
con.subtarget = ik_chain.shin
|
con.subtarget = ik_chain.shin
|
||||||
|
fcurve = con.driver_add("influence", 0)
|
||||||
|
driver = fcurve.driver
|
||||||
|
var = driver.variables.new()
|
||||||
|
driver.type = 'AVERAGE'
|
||||||
|
var.name = "var"
|
||||||
|
var.targets[0].id_type = 'OBJECT'
|
||||||
|
var.targets[0].id = obj
|
||||||
|
var.targets[0].data_path = ik_driver_path
|
||||||
|
|
||||||
con = mt_chain.foot_p.constraints.new('COPY_TRANSFORMS')
|
con = mt_chain.foot_p.constraints.new('COPY_TRANSFORMS')
|
||||||
con.target = obj
|
con.target = obj
|
||||||
con.subtarget = ik.foot_roll_02
|
con.subtarget = ik.foot_roll_02
|
||||||
|
fcurve = con.driver_add("influence", 0)
|
||||||
|
driver = fcurve.driver
|
||||||
|
var = driver.variables.new()
|
||||||
|
driver.type = 'AVERAGE'
|
||||||
|
var.name = "var"
|
||||||
|
var.targets[0].id_type = 'OBJECT'
|
||||||
|
var.targets[0].id = obj
|
||||||
|
var.targets[0].data_path = ik_driver_path
|
||||||
|
|
||||||
con = mt_chain.toe_p.constraints.new('COPY_TRANSFORMS')
|
con = mt_chain.toe_p.constraints.new('COPY_TRANSFORMS')
|
||||||
con.target = obj
|
con.target = obj
|
||||||
con.subtarget = ik_chain.toe
|
con.subtarget = ik_chain.toe
|
||||||
|
fcurve = con.driver_add("influence", 0)
|
||||||
|
driver = fcurve.driver
|
||||||
|
var = driver.variables.new()
|
||||||
|
driver.type = 'AVERAGE'
|
||||||
|
var.name = "var"
|
||||||
|
var.targets[0].id_type = 'OBJECT'
|
||||||
|
var.targets[0].id = obj
|
||||||
|
var.targets[0].data_path = ik_driver_path
|
||||||
|
|
||||||
# others...
|
# others...
|
||||||
con = ik.foot_roll_01_p.constraints.new('COPY_ROTATION')
|
con = ik.foot_roll_01_p.constraints.new('COPY_ROTATION')
|
||||||
@@ -211,8 +275,7 @@ def ik(obj, bone_definition, base_names, options):
|
|||||||
con.target = obj
|
con.target = obj
|
||||||
con.subtarget = ik.foot_target
|
con.subtarget = ik.foot_target
|
||||||
|
|
||||||
con.pole_target = obj
|
con.pole_target = None
|
||||||
con.pole_subtarget = ik.knee_target
|
|
||||||
|
|
||||||
ik.update()
|
ik.update()
|
||||||
ik_chain.update()
|
ik_chain.update()
|
||||||
@@ -226,12 +289,204 @@ def ik(obj, bone_definition, base_names, options):
|
|||||||
obj.data.bones[getattr(ik_chain, attr)].layer = layer
|
obj.data.bones[getattr(ik_chain, attr)].layer = layer
|
||||||
for attr in ik.attr_names:
|
for attr in ik.attr_names:
|
||||||
obj.data.bones[getattr(ik, attr)].layer = layer
|
obj.data.bones[getattr(ik, attr)].layer = layer
|
||||||
|
obj.data.bones[knee_rotator].layer = layer
|
||||||
|
|
||||||
|
return None, ik_chain.thigh, ik_chain.shin, ik_chain.foot, ik_chain.toe
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return None, ik_chain.thigh, ik_chain.shin, ik_chain.foot, ik_chain.toe
|
def fk(obj, bone_definition, base_names, options):
|
||||||
|
eb = obj.data.edit_bones
|
||||||
|
pb = obj.pose.bones
|
||||||
|
arm = obj.data
|
||||||
|
bpy.ops.object.mode_set(mode='EDIT')
|
||||||
|
|
||||||
|
# setup the existing bones, use names from METARIG_NAMES
|
||||||
|
mt = bone_class_instance(obj, ["hips"])
|
||||||
|
mt_chain = bone_class_instance(obj, ["thigh", "shin", "foot", "toe"])
|
||||||
|
|
||||||
|
mt.attr_initialize(METARIG_NAMES, bone_definition)
|
||||||
|
mt_chain.attr_initialize(METARIG_NAMES, bone_definition)
|
||||||
|
|
||||||
|
fk_chain = mt_chain.copy(to_fmt="%s", base_names=base_names)
|
||||||
|
|
||||||
|
# Create the socket
|
||||||
|
socket = copy_bone_simple(arm, mt_chain.thigh, "MCH-leg_socket").name
|
||||||
|
eb[socket].parent = eb[mt.hips]
|
||||||
|
eb[socket].length = eb[mt_chain.thigh].length / 4
|
||||||
|
|
||||||
|
# Create the hinge
|
||||||
|
hinge = copy_bone_simple(arm, mt.hips, "MCH-leg_hinge").name
|
||||||
|
eb[hinge].length = eb[mt.hips].length / 2
|
||||||
|
|
||||||
|
# Make leg child of hinge
|
||||||
|
eb[fk_chain.thigh].connected = False
|
||||||
|
eb[fk_chain.thigh].parent = eb[hinge]
|
||||||
|
|
||||||
|
|
||||||
|
bpy.ops.object.mode_set(mode='OBJECT')
|
||||||
|
|
||||||
|
# Set rotation modes and axis locks
|
||||||
|
pb[fk_chain.shin].rotation_mode = 'XYZ'
|
||||||
|
pb[fk_chain.shin].lock_rotation = False, True, True
|
||||||
|
|
||||||
|
# Constrain original bones to control bones
|
||||||
|
con = mt_chain.thigh_p.constraints.new('COPY_TRANSFORMS')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = fk_chain.thigh
|
||||||
|
|
||||||
|
con = mt_chain.shin_p.constraints.new('COPY_TRANSFORMS')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = fk_chain.shin
|
||||||
|
|
||||||
|
con = mt_chain.foot_p.constraints.new('COPY_TRANSFORMS')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = fk_chain.foot
|
||||||
|
|
||||||
|
con = mt_chain.toe_p.constraints.new('COPY_TRANSFORMS')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = fk_chain.toe
|
||||||
|
|
||||||
|
# Socket constraint
|
||||||
|
con = pb[fk_chain.thigh].constraints.new('COPY_LOCATION')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = socket
|
||||||
|
|
||||||
|
# Hinge constraint
|
||||||
|
con = pb[hinge].constraints.new('COPY_TRANSFORMS')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = mt.hips
|
||||||
|
|
||||||
|
prop = rna_idprop_ui_prop_get(pb[fk_chain.thigh], "hinge", create=True)
|
||||||
|
pb[fk_chain.thigh]["hinge"] = 0.0
|
||||||
|
prop["soft_min"] = 0.0
|
||||||
|
prop["soft_max"] = 1.0
|
||||||
|
prop["min"] = 0.0
|
||||||
|
prop["max"] = 1.0
|
||||||
|
|
||||||
|
hinge_driver_path = pb[fk_chain.thigh].path_to_id() + '["hinge"]'
|
||||||
|
|
||||||
|
fcurve = con.driver_add("influence", 0)
|
||||||
|
driver = fcurve.driver
|
||||||
|
var = driver.variables.new()
|
||||||
|
driver.type = 'AVERAGE'
|
||||||
|
var.name = "var"
|
||||||
|
var.targets[0].id_type = 'OBJECT'
|
||||||
|
var.targets[0].id = obj
|
||||||
|
var.targets[0].data_path = hinge_driver_path
|
||||||
|
|
||||||
|
mod = fcurve.modifiers[0]
|
||||||
|
mod.poly_order = 1
|
||||||
|
mod.coefficients[0] = 1.0
|
||||||
|
mod.coefficients[1] = -1.0
|
||||||
|
|
||||||
|
return None, fk_chain.thigh, fk_chain.shin, fk_chain.foot, fk_chain.toe
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def deform(obj, definitions, base_names, options):
|
||||||
|
bpy.ops.object.mode_set(mode='EDIT')
|
||||||
|
|
||||||
|
# Create upper leg bones: two bones, each half of the upper leg.
|
||||||
|
uleg1 = copy_bone_simple(obj.data, definitions[1], "DEF-%s.01" % base_names[definitions[1]], parent=True)
|
||||||
|
uleg2 = copy_bone_simple(obj.data, definitions[1], "DEF-%s.02" % base_names[definitions[1]], parent=True)
|
||||||
|
uleg1.connected = False
|
||||||
|
uleg2.connected = False
|
||||||
|
uleg2.parent = uleg1
|
||||||
|
center = uleg1.center
|
||||||
|
uleg1.tail = center
|
||||||
|
uleg2.head = center
|
||||||
|
|
||||||
|
# Create lower leg bones: two bones, each half of the lower leg.
|
||||||
|
lleg1 = copy_bone_simple(obj.data, definitions[2], "DEF-%s.01" % base_names[definitions[2]], parent=True)
|
||||||
|
lleg2 = copy_bone_simple(obj.data, definitions[2], "DEF-%s.02" % base_names[definitions[2]], parent=True)
|
||||||
|
lleg1.connected = False
|
||||||
|
lleg2.connected = False
|
||||||
|
lleg2.parent = lleg1
|
||||||
|
center = lleg1.center
|
||||||
|
lleg1.tail = center
|
||||||
|
lleg2.head = center
|
||||||
|
|
||||||
|
# Create a bone for the second lower leg deform bone to twist with
|
||||||
|
twist = copy_bone_simple(obj.data, lleg2.name, "MCH-leg_twist")
|
||||||
|
twist.length /= 4
|
||||||
|
twist.connected = False
|
||||||
|
twist.parent = obj.data.edit_bones[definitions[3]]
|
||||||
|
|
||||||
|
# Create foot bone
|
||||||
|
foot = copy_bone_simple(obj.data, definitions[3], "DEF-%s" % base_names[definitions[3]], parent=True)
|
||||||
|
|
||||||
|
# Create toe bone
|
||||||
|
toe = copy_bone_simple(obj.data, definitions[4], "DEF-%s" % base_names[definitions[4]], parent=True)
|
||||||
|
|
||||||
|
# Store names before leaving edit mode
|
||||||
|
uleg1_name = uleg1.name
|
||||||
|
uleg2_name = uleg2.name
|
||||||
|
lleg1_name = lleg1.name
|
||||||
|
lleg2_name = lleg2.name
|
||||||
|
twist_name = twist.name
|
||||||
|
foot_name = foot.name
|
||||||
|
toe_name = toe.name
|
||||||
|
|
||||||
|
# Leave edit mode
|
||||||
|
bpy.ops.object.mode_set(mode='OBJECT')
|
||||||
|
|
||||||
|
# Get the pose bones
|
||||||
|
uleg1 = obj.pose.bones[uleg1_name]
|
||||||
|
uleg2 = obj.pose.bones[uleg2_name]
|
||||||
|
lleg1 = obj.pose.bones[lleg1_name]
|
||||||
|
lleg2 = obj.pose.bones[lleg2_name]
|
||||||
|
foot = obj.pose.bones[foot_name]
|
||||||
|
toe = obj.pose.bones[toe_name]
|
||||||
|
|
||||||
|
# Upper leg constraints
|
||||||
|
con = uleg1.constraints.new('DAMPED_TRACK')
|
||||||
|
con.name = "trackto"
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = definitions[2]
|
||||||
|
|
||||||
|
con = uleg2.constraints.new('COPY_ROTATION')
|
||||||
|
con.name = "copy_rot"
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = definitions[1]
|
||||||
|
|
||||||
|
# Lower leg constraints
|
||||||
|
con = lleg1.constraints.new('COPY_ROTATION')
|
||||||
|
con.name = "copy_rot"
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = definitions[2]
|
||||||
|
|
||||||
|
con = lleg2.constraints.new('COPY_ROTATION')
|
||||||
|
con.name = "copy_rot"
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = twist_name
|
||||||
|
|
||||||
|
con = lleg2.constraints.new('DAMPED_TRACK')
|
||||||
|
con.name = "trackto"
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = definitions[3]
|
||||||
|
|
||||||
|
# Foot constraint
|
||||||
|
con = foot.constraints.new('COPY_ROTATION')
|
||||||
|
con.name = "copy_rot"
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = definitions[3]
|
||||||
|
|
||||||
|
# Toe constraint
|
||||||
|
con = toe.constraints.new('COPY_ROTATION')
|
||||||
|
con.name = "copy_rot"
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = definitions[4]
|
||||||
|
|
||||||
|
bpy.ops.object.mode_set(mode='EDIT')
|
||||||
|
return (uleg1_name, uleg2_name, lleg1_name, lleg2_name, foot_name, toe_name, None)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def main(obj, bone_definition, base_names, options):
|
def main(obj, bone_definition, base_names, options):
|
||||||
|
bones_fk = fk(obj, bone_definition, base_names, options)
|
||||||
bones_ik = ik(obj, bone_definition, base_names, options)
|
bones_ik = ik(obj, bone_definition, base_names, options)
|
||||||
|
deform(obj, bone_definition, base_names, options)
|
||||||
return bones_ik
|
return bones_ik
|
||||||
|
|||||||
@@ -19,15 +19,69 @@
|
|||||||
# <pep8 compliant>
|
# <pep8 compliant>
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
from math import acos
|
from rna_prop_ui import rna_idprop_ui_prop_get
|
||||||
|
from math import acos, pi
|
||||||
from Mathutils import Vector
|
from Mathutils import Vector
|
||||||
from rigify import get_layer_dict
|
from rigify import get_layer_dict, RigifyError
|
||||||
from rigify_utils import bone_class_instance, copy_bone_simple
|
from rigify_utils import bone_class_instance, copy_bone_simple
|
||||||
|
|
||||||
#METARIG_NAMES = ("cpy",)
|
#METARIG_NAMES = ("cpy",)
|
||||||
RIG_TYPE = "mouth"
|
RIG_TYPE = "mouth"
|
||||||
|
|
||||||
|
|
||||||
|
def mark_actions():
|
||||||
|
for action in bpy.data.actions:
|
||||||
|
action.tag = True
|
||||||
|
|
||||||
|
def get_unmarked_action():
|
||||||
|
for action in bpy.data.actions:
|
||||||
|
if action.tag != True:
|
||||||
|
return action
|
||||||
|
return None
|
||||||
|
|
||||||
|
def add_action(name=None):
|
||||||
|
mark_actions()
|
||||||
|
bpy.ops.action.new()
|
||||||
|
action = get_unmarked_action()
|
||||||
|
if name is not None:
|
||||||
|
action.name = name
|
||||||
|
return action
|
||||||
|
|
||||||
|
def addget_shape_key(obj, name="Key"):
|
||||||
|
""" Fetches a shape key, or creates it if it doesn't exist
|
||||||
|
"""
|
||||||
|
# Create a shapekey set if it doesn't already exist
|
||||||
|
if obj.data.shape_keys is None:
|
||||||
|
shape = obj.add_shape_key(name="Basis", from_mix=False)
|
||||||
|
obj.active_shape_key_index = 0
|
||||||
|
|
||||||
|
# Get the shapekey, or create it if it doesn't already exist
|
||||||
|
if name in obj.data.shape_keys.keys:
|
||||||
|
shape_key = obj.data.shape_keys.keys[name]
|
||||||
|
else:
|
||||||
|
shape_key = obj.add_shape_key(name=name, from_mix=False)
|
||||||
|
|
||||||
|
return shape_key
|
||||||
|
|
||||||
|
|
||||||
|
def addget_shape_key_driver(obj, name="Key"):
|
||||||
|
""" Fetches the driver for the shape key, or creates it if it doesn't
|
||||||
|
already exist.
|
||||||
|
"""
|
||||||
|
driver_path = 'keys["' + name + '"].value'
|
||||||
|
fcurve = None
|
||||||
|
driver = None
|
||||||
|
if obj.data.shape_keys.animation_data is not None:
|
||||||
|
for driver_s in obj.data.shape_keys.animation_data.drivers:
|
||||||
|
if driver_s.data_path == driver_path:
|
||||||
|
fcurve = driver_s
|
||||||
|
if fcurve == None:
|
||||||
|
fcurve = obj.data.shape_keys.keys[name].driver_add("value", 0)
|
||||||
|
fcurve.driver.type = 'AVERAGE'
|
||||||
|
|
||||||
|
return fcurve
|
||||||
|
|
||||||
|
|
||||||
def metarig_template():
|
def metarig_template():
|
||||||
# generated by rigify.write_meta_rig
|
# generated by rigify.write_meta_rig
|
||||||
bpy.ops.object.mode_set(mode='EDIT')
|
bpy.ops.object.mode_set(mode='EDIT')
|
||||||
@@ -49,7 +103,7 @@ def metarig_definition(obj, orig_bone_name):
|
|||||||
chain = []
|
chain = []
|
||||||
|
|
||||||
try:
|
try:
|
||||||
chain += [bone.parent.name, bone.parent.parent.name, bone.name]
|
chain += [bone.parent.parent.name, bone.parent.name, bone.name]
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
raise RigifyError("'%s' rig type requires a chain of two parents (bone: %s)" % (RIG_TYPE, base_names[0]))
|
raise RigifyError("'%s' rig type requires a chain of two parents (bone: %s)" % (RIG_TYPE, base_names[0]))
|
||||||
|
|
||||||
@@ -67,62 +121,66 @@ def deform(obj, definitions, base_names, options):
|
|||||||
eb = obj.data.edit_bones
|
eb = obj.data.edit_bones
|
||||||
pb = obj.pose.bones
|
pb = obj.pose.bones
|
||||||
|
|
||||||
|
# Options
|
||||||
|
req_options = ["mesh"]
|
||||||
|
for option in req_options:
|
||||||
|
if option not in options:
|
||||||
|
raise RigifyError("'%s' rig type requires a '%s' option (bone: %s)" % (RIG_TYPE, option, base_names[definitions[0]]))
|
||||||
|
|
||||||
|
meshes = options["mesh"].replace(" ", "").split(",")
|
||||||
|
|
||||||
# Upper lip MCH
|
# Upper lip MCH
|
||||||
lip1 = make_lip_stretch_bone(obj, "MCH-lip", definitions[2], definitions[3], 1.0)
|
lip1 = make_lip_stretch_bone(obj, "MCH-lip", definitions[3], definitions[2], 0.0)
|
||||||
lip2 = make_lip_stretch_bone(obj, "MCH-lip", definitions[3], definitions[4], 1.0)
|
lip2 = make_lip_stretch_bone(obj, "MCH-lip", definitions[4], definitions[3], 0.0)
|
||||||
lip22 = make_lip_stretch_bone(obj, "MCH-lip", definitions[4], definitions[5], 1.0)
|
lip22 = make_lip_stretch_bone(obj, "MCH-lip", definitions[5], definitions[4], 0.0)
|
||||||
lip33 = make_lip_stretch_bone(obj, "MCH-lip", definitions[4], definitions[3], 1.0)
|
lip33 = make_lip_stretch_bone(obj, "MCH-lip", definitions[3], definitions[4], 0.0)
|
||||||
lip3 = make_lip_stretch_bone(obj, "MCH-lip", definitions[5], definitions[4], 1.0)
|
lip3 = make_lip_stretch_bone(obj, "MCH-lip", definitions[4], definitions[5], 0.0)
|
||||||
lip4 = make_lip_stretch_bone(obj, "MCH-lip", definitions[6], definitions[5], 1.0)
|
lip4 = make_lip_stretch_bone(obj, "MCH-lip", definitions[5], definitions[6], 0.0)
|
||||||
|
|
||||||
dlip22 = copy_bone_simple(obj.data, lip22, "MCH-lip", parent=True).name
|
eb[lip1].parent = eb[definitions[3]]
|
||||||
dlip33 = copy_bone_simple(obj.data, lip33, "MCH-lip", parent=True).name
|
eb[lip2].parent = eb[definitions[4]]
|
||||||
eb[dlip22].bbone_segments = 8
|
eb[lip22].parent = eb[definitions[5]]
|
||||||
eb[dlip33].bbone_segments = 8
|
eb[lip33].parent = eb[definitions[3]]
|
||||||
|
eb[lip3].parent = eb[definitions[4]]
|
||||||
|
eb[lip4].parent = eb[definitions[5]]
|
||||||
|
|
||||||
eb[lip1].parent = eb[definitions[2]]
|
eb[lip22].bbone_segments = 8
|
||||||
eb[lip2].parent = eb[definitions[3]]
|
eb[lip33].bbone_segments = 8
|
||||||
eb[lip22].parent = eb[definitions[4]]
|
|
||||||
eb[lip33].parent = eb[definitions[4]]
|
|
||||||
eb[lip3].parent = eb[definitions[5]]
|
|
||||||
eb[lip4].parent = eb[definitions[6]]
|
|
||||||
|
|
||||||
# Lower lip MCH
|
# Lower lip MCH
|
||||||
lip5 = make_lip_stretch_bone(obj, "MCH-lip", definitions[6], definitions[7], 1.0)
|
lip5 = make_lip_stretch_bone(obj, "MCH-lip", definitions[7], definitions[6], 0.0)
|
||||||
lip6 = make_lip_stretch_bone(obj, "MCH-lip", definitions[7], definitions[8], 1.0)
|
lip6 = make_lip_stretch_bone(obj, "MCH-lip", definitions[8], definitions[7], 0.0)
|
||||||
lip66 = make_lip_stretch_bone(obj, "MCH-lip", definitions[8], definitions[9], 1.0)
|
lip66 = make_lip_stretch_bone(obj, "MCH-lip", definitions[9], definitions[8], 0.0)
|
||||||
lip77 = make_lip_stretch_bone(obj, "MCH-lip", definitions[8], definitions[7], 1.0)
|
lip77 = make_lip_stretch_bone(obj, "MCH-lip", definitions[7], definitions[8], 0.0)
|
||||||
lip7 = make_lip_stretch_bone(obj, "MCH-lip", definitions[9], definitions[8], 1.0)
|
lip7 = make_lip_stretch_bone(obj, "MCH-lip", definitions[8], definitions[9], 0.0)
|
||||||
lip8 = make_lip_stretch_bone(obj, "MCH-lip", definitions[2], definitions[9], 1.0)
|
lip8 = make_lip_stretch_bone(obj, "MCH-lip", definitions[9], definitions[2], 0.0)
|
||||||
|
|
||||||
dlip66 = copy_bone_simple(obj.data, lip66, "MCH-lip", parent=True).name
|
eb[lip5].parent = eb[definitions[7]]
|
||||||
dlip77 = copy_bone_simple(obj.data, lip77, "MCH-lip", parent=True).name
|
eb[lip6].parent = eb[definitions[8]]
|
||||||
eb[dlip66].bbone_segments = 8
|
eb[lip66].parent = eb[definitions[9]]
|
||||||
eb[dlip77].bbone_segments = 8
|
eb[lip77].parent = eb[definitions[7]]
|
||||||
|
eb[lip7].parent = eb[definitions[8]]
|
||||||
|
eb[lip8].parent = eb[definitions[9]]
|
||||||
|
|
||||||
eb[lip5].parent = eb[definitions[6]]
|
eb[lip66].bbone_segments = 8
|
||||||
eb[lip6].parent = eb[definitions[7]]
|
eb[lip77].bbone_segments = 8
|
||||||
eb[lip66].parent = eb[definitions[8]]
|
|
||||||
eb[lip77].parent = eb[definitions[8]]
|
|
||||||
eb[lip7].parent = eb[definitions[9]]
|
|
||||||
eb[lip8].parent = eb[definitions[2]]
|
|
||||||
|
|
||||||
# Upper lip DEF
|
# Upper lip DEF
|
||||||
dlip1 = copy_bone_simple(obj.data, lip1, "DEF-lip", parent=True).name
|
dlip1 = copy_bone_simple(obj.data, lip1, "DEF-" + base_names[definitions[4]] + ".01.R", parent=True).name
|
||||||
dlip2 = copy_bone_simple(obj.data, lip2, "DEF-lip", parent=True).name
|
dlip2 = copy_bone_simple(obj.data, lip2, "DEF-" + base_names[definitions[4]] + ".02.R", parent=True).name
|
||||||
dlip3 = copy_bone_simple(obj.data, lip3, "DEF-lip", parent=True).name
|
dlip3 = copy_bone_simple(obj.data, lip3, "DEF-" + base_names[definitions[4]] + ".02.L", parent=True).name
|
||||||
dlip4 = copy_bone_simple(obj.data, lip4, "DEF-lip", parent=True).name
|
dlip4 = copy_bone_simple(obj.data, lip4, "DEF-" + base_names[definitions[4]] + ".01.L", parent=True).name
|
||||||
|
|
||||||
eb[dlip2].parent = eb[dlip1]
|
eb[dlip1].parent = eb[dlip2]
|
||||||
eb[dlip22].parent = eb[dlip2]
|
eb[dlip2].parent = eb[lip22]
|
||||||
|
|
||||||
eb[dlip3].parent = eb[dlip4]
|
eb[dlip4].parent = eb[dlip3]
|
||||||
eb[dlip33].parent = eb[dlip3]
|
eb[dlip3].parent = eb[lip33]
|
||||||
|
|
||||||
eb[dlip2].connected = True
|
eb[dlip1].connected = True
|
||||||
eb[dlip22].connected = True
|
eb[dlip2].connected = True
|
||||||
eb[dlip3].connected = True
|
eb[dlip4].connected = True
|
||||||
eb[dlip33].connected = True
|
eb[dlip3].connected = True
|
||||||
|
|
||||||
eb[dlip1].bbone_segments = 8
|
eb[dlip1].bbone_segments = 8
|
||||||
eb[dlip2].bbone_segments = 8
|
eb[dlip2].bbone_segments = 8
|
||||||
@@ -130,28 +188,28 @@ def deform(obj, definitions, base_names, options):
|
|||||||
eb[dlip4].bbone_segments = 8
|
eb[dlip4].bbone_segments = 8
|
||||||
|
|
||||||
# Lower lip DEF
|
# Lower lip DEF
|
||||||
dlip5 = copy_bone_simple(obj.data, lip5, "DEF-lip", parent=True).name
|
dlip8 = copy_bone_simple(obj.data, lip8, "DEF-" + base_names[definitions[8]] + ".01.R", parent=True).name
|
||||||
dlip6 = copy_bone_simple(obj.data, lip6, "DEF-lip", parent=True).name
|
dlip7 = copy_bone_simple(obj.data, lip7, "DEF-" + base_names[definitions[8]] + ".02.R", parent=True).name
|
||||||
dlip7 = copy_bone_simple(obj.data, lip7, "DEF-lip", parent=True).name
|
dlip6 = copy_bone_simple(obj.data, lip6, "DEF-" + base_names[definitions[8]] + ".02.L", parent=True).name
|
||||||
dlip8 = copy_bone_simple(obj.data, lip8, "DEF-lip", parent=True).name
|
dlip5 = copy_bone_simple(obj.data, lip5, "DEF-" + base_names[definitions[8]] + ".01.L", parent=True).name
|
||||||
|
|
||||||
eb[dlip6].parent = eb[dlip5]
|
|
||||||
eb[dlip66].parent = eb[dlip6]
|
|
||||||
|
|
||||||
eb[dlip7].parent = eb[dlip8]
|
eb[dlip5].parent = eb[dlip6]
|
||||||
eb[dlip77].parent = eb[dlip7]
|
eb[dlip6].parent = eb[lip66]
|
||||||
|
|
||||||
|
eb[dlip8].parent = eb[dlip7]
|
||||||
|
eb[dlip7].parent = eb[lip77]
|
||||||
|
|
||||||
|
eb[dlip5].connected = True
|
||||||
eb[dlip6].connected = True
|
eb[dlip6].connected = True
|
||||||
eb[dlip66].connected = True
|
eb[dlip8].connected = True
|
||||||
eb[dlip7].connected = True
|
eb[dlip7].connected = True
|
||||||
eb[dlip77].connected = True
|
|
||||||
|
|
||||||
eb[dlip5].bbone_segments = 8
|
eb[dlip5].bbone_segments = 8
|
||||||
eb[dlip6].bbone_segments = 8
|
eb[dlip6].bbone_segments = 8
|
||||||
eb[dlip7].bbone_segments = 8
|
eb[dlip7].bbone_segments = 8
|
||||||
eb[dlip8].bbone_segments = 8
|
eb[dlip8].bbone_segments = 8
|
||||||
|
|
||||||
|
|
||||||
bpy.ops.object.mode_set(mode='OBJECT')
|
bpy.ops.object.mode_set(mode='OBJECT')
|
||||||
|
|
||||||
# Constraints
|
# Constraints
|
||||||
@@ -159,14 +217,6 @@ def deform(obj, definitions, base_names, options):
|
|||||||
con.target = obj
|
con.target = obj
|
||||||
con.subtarget = lip1
|
con.subtarget = lip1
|
||||||
|
|
||||||
con = pb[dlip22].constraints.new('COPY_TRANSFORMS')
|
|
||||||
con.target = obj
|
|
||||||
con.subtarget = lip22
|
|
||||||
|
|
||||||
con = pb[dlip33].constraints.new('COPY_TRANSFORMS')
|
|
||||||
con.target = obj
|
|
||||||
con.subtarget = lip33
|
|
||||||
|
|
||||||
con = pb[dlip2].constraints.new('COPY_TRANSFORMS')
|
con = pb[dlip2].constraints.new('COPY_TRANSFORMS')
|
||||||
con.target = obj
|
con.target = obj
|
||||||
con.subtarget = lip2
|
con.subtarget = lip2
|
||||||
@@ -187,14 +237,6 @@ def deform(obj, definitions, base_names, options):
|
|||||||
con.target = obj
|
con.target = obj
|
||||||
con.subtarget = lip6
|
con.subtarget = lip6
|
||||||
|
|
||||||
con = pb[dlip66].constraints.new('COPY_TRANSFORMS')
|
|
||||||
con.target = obj
|
|
||||||
con.subtarget = lip66
|
|
||||||
|
|
||||||
con = pb[dlip77].constraints.new('COPY_TRANSFORMS')
|
|
||||||
con.target = obj
|
|
||||||
con.subtarget = lip77
|
|
||||||
|
|
||||||
con = pb[dlip7].constraints.new('COPY_TRANSFORMS')
|
con = pb[dlip7].constraints.new('COPY_TRANSFORMS')
|
||||||
con.target = obj
|
con.target = obj
|
||||||
con.subtarget = lip7
|
con.subtarget = lip7
|
||||||
@@ -203,6 +245,88 @@ def deform(obj, definitions, base_names, options):
|
|||||||
con.target = obj
|
con.target = obj
|
||||||
con.subtarget = lip8
|
con.subtarget = lip8
|
||||||
|
|
||||||
|
# Corrective shape keys for the corners of the mouth.
|
||||||
|
bpy.ops.object.mode_set(mode='EDIT')
|
||||||
|
|
||||||
|
# Calculate the rotation difference between the bones
|
||||||
|
rotdiff_r = acos(eb[lip1].matrix.to_quat() * eb[lip8].matrix.to_quat()) * 2
|
||||||
|
rotdiff_l = acos(eb[lip4].matrix.to_quat() * eb[lip5].matrix.to_quat()) * 2
|
||||||
|
|
||||||
|
bpy.ops.object.mode_set(mode='OBJECT')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Left side
|
||||||
|
for mesh_name in meshes:
|
||||||
|
mesh_obj = bpy.data.objects[mesh_name]
|
||||||
|
shape_key_name = "COR-" + base_names[definitions[4]] + ".L.spread"
|
||||||
|
|
||||||
|
# Add/get the shape key
|
||||||
|
shape_key = addget_shape_key(mesh_obj, name=shape_key_name)
|
||||||
|
|
||||||
|
# Add/get the shape key driver
|
||||||
|
fcurve = addget_shape_key_driver(mesh_obj, name=shape_key_name)
|
||||||
|
driver = fcurve.driver
|
||||||
|
|
||||||
|
# Get the variable, or create it if it doesn't already exist
|
||||||
|
var_name = base_names[definitions[6]]
|
||||||
|
if var_name in driver.variables:
|
||||||
|
var = driver.variables[var_name]
|
||||||
|
else:
|
||||||
|
var = driver.variables.new()
|
||||||
|
var.name = var_name
|
||||||
|
|
||||||
|
# Set up the variable
|
||||||
|
var.type = "ROTATION_DIFF"
|
||||||
|
#var.targets[0].id_type = 'OBJECT'
|
||||||
|
var.targets[0].id = obj
|
||||||
|
var.targets[0].bone_target = lip4
|
||||||
|
#var.targets[1].id_type = 'OBJECT'
|
||||||
|
var.targets[1].id = obj
|
||||||
|
var.targets[1].bone_target = lip5
|
||||||
|
|
||||||
|
# Set fcurve offset
|
||||||
|
mod = fcurve.modifiers[0]
|
||||||
|
if rotdiff_l != pi:
|
||||||
|
mod.coefficients[0] = -rotdiff_l / (pi-rotdiff_l)
|
||||||
|
mod.coefficients[1] = 1 / (pi-rotdiff_l)
|
||||||
|
|
||||||
|
# Right side
|
||||||
|
for mesh_name in meshes:
|
||||||
|
mesh_obj = bpy.data.objects[mesh_name]
|
||||||
|
shape_key_name = "COR-" + base_names[definitions[4]] + ".R.spread"
|
||||||
|
|
||||||
|
# Add/get the shape key
|
||||||
|
shape_key = addget_shape_key(mesh_obj, name=shape_key_name)
|
||||||
|
|
||||||
|
# Add/get the shape key driver
|
||||||
|
fcurve = addget_shape_key_driver(mesh_obj, name=shape_key_name)
|
||||||
|
driver = fcurve.driver
|
||||||
|
|
||||||
|
# Get the variable, or create it if it doesn't already exist
|
||||||
|
var_name = base_names[definitions[2]]
|
||||||
|
if var_name in driver.variables:
|
||||||
|
var = driver.variables[var_name]
|
||||||
|
else:
|
||||||
|
var = driver.variables.new()
|
||||||
|
var.name = var_name
|
||||||
|
|
||||||
|
# Set up the variable
|
||||||
|
var.type = "ROTATION_DIFF"
|
||||||
|
#var.targets[0].id_type = 'OBJECT'
|
||||||
|
var.targets[0].id = obj
|
||||||
|
var.targets[0].bone_target = lip1
|
||||||
|
#var.targets[1].id_type = 'OBJECT'
|
||||||
|
var.targets[1].id = obj
|
||||||
|
var.targets[1].bone_target = lip8
|
||||||
|
|
||||||
|
# Set fcurve offset
|
||||||
|
mod = fcurve.modifiers[0]
|
||||||
|
if rotdiff_r != pi:
|
||||||
|
mod.coefficients[0] = -rotdiff_r / (pi-rotdiff_r)
|
||||||
|
mod.coefficients[1] = 1 / (pi-rotdiff_r)
|
||||||
|
|
||||||
|
|
||||||
return (None,)
|
return (None,)
|
||||||
|
|
||||||
|
|
||||||
@@ -217,6 +341,7 @@ def control(obj, definitions, base_names, options):
|
|||||||
|
|
||||||
head_e = eb[definitions[0]]
|
head_e = eb[definitions[0]]
|
||||||
jaw_e = eb[definitions[1]]
|
jaw_e = eb[definitions[1]]
|
||||||
|
jaw = definitions[1]
|
||||||
|
|
||||||
# Head lips
|
# Head lips
|
||||||
hlip1 = copy_bone_simple(obj.data, definitions[2], "MCH-"+base_names[definitions[2]]+".head").name
|
hlip1 = copy_bone_simple(obj.data, definitions[2], "MCH-"+base_names[definitions[2]]+".head").name
|
||||||
@@ -285,14 +410,14 @@ def control(obj, definitions, base_names, options):
|
|||||||
eb[lip7].roll = 0
|
eb[lip7].roll = 0
|
||||||
eb[lip8].roll = 0
|
eb[lip8].roll = 0
|
||||||
|
|
||||||
eb[lip1].parent = eb[jlip1]
|
eb[lip1].parent = eb[hlip1]
|
||||||
eb[lip2].parent = eb[jlip2]
|
eb[lip2].parent = eb[hlip2]
|
||||||
eb[lip3].parent = eb[jlip3]
|
eb[lip3].parent = eb[hlip3]
|
||||||
eb[lip4].parent = eb[jlip4]
|
eb[lip4].parent = eb[hlip4]
|
||||||
eb[lip5].parent = eb[jlip5]
|
eb[lip5].parent = eb[hlip5]
|
||||||
eb[lip6].parent = eb[jlip6]
|
eb[lip6].parent = eb[hlip6]
|
||||||
eb[lip7].parent = eb[jlip7]
|
eb[lip7].parent = eb[hlip7]
|
||||||
eb[lip8].parent = eb[jlip8]
|
eb[lip8].parent = eb[hlip8]
|
||||||
|
|
||||||
# Link lips
|
# Link lips
|
||||||
llip1 = copy_bone_simple(obj.data, definitions[2], "MCH-"+base_names[definitions[2]]+".link").name
|
llip1 = copy_bone_simple(obj.data, definitions[2], "MCH-"+base_names[definitions[2]]+".link").name
|
||||||
@@ -313,53 +438,84 @@ def control(obj, definitions, base_names, options):
|
|||||||
eb[llip7].parent = eb[lip7]
|
eb[llip7].parent = eb[lip7]
|
||||||
eb[llip8].parent = eb[lip8]
|
eb[llip8].parent = eb[lip8]
|
||||||
|
|
||||||
|
# Jaw open tracker
|
||||||
|
jopent = copy_bone_simple(obj.data, jaw_e.name, "MCH-"+base_names[jaw_e.name]+".track", parent=True).name
|
||||||
|
eb[jopent].connected = False
|
||||||
|
eb[jopent].tail = jaw_e.tail + Vector(0,0,jaw_e.length)
|
||||||
|
eb[jopent].head = jaw_e.tail
|
||||||
|
|
||||||
bpy.ops.object.mode_set(mode='OBJECT')
|
bpy.ops.object.mode_set(mode='OBJECT')
|
||||||
|
|
||||||
|
# Add eye close action if it doesn't already exist
|
||||||
|
action_name = "mouth_open"
|
||||||
|
if action_name in bpy.data.actions:
|
||||||
|
open_action = bpy.data.actions[action_name]
|
||||||
|
else:
|
||||||
|
open_action = add_action(name=action_name)
|
||||||
|
|
||||||
|
# Add close property (useful when making the animation in the action)
|
||||||
|
prop_name = "open_action"
|
||||||
|
prop = rna_idprop_ui_prop_get(pb[lip1], prop_name, create=True)
|
||||||
|
pb[lip1][prop_name] = 1.0
|
||||||
|
prop["soft_min"] = 0.0
|
||||||
|
prop["soft_max"] = 1.0
|
||||||
|
prop["min"] = 0.0
|
||||||
|
prop["max"] = 1.0
|
||||||
|
|
||||||
|
open_driver_path = pb[lip1].path_to_id() + '["open_action"]'
|
||||||
|
|
||||||
# Constraints
|
# Constraints
|
||||||
|
|
||||||
# Jaw lips to head lips
|
# Jaw open tracker stretches to jaw tip
|
||||||
influence = [0.0, 0.1, 0.5]
|
con = pb[jopent].constraints.new('STRETCH_TO')
|
||||||
|
|
||||||
con = pb[jlip1].constraints.new('COPY_TRANSFORMS')
|
|
||||||
con.target = obj
|
con.target = obj
|
||||||
con.subtarget = hlip1
|
con.subtarget = jaw
|
||||||
|
con.head_tail = 1.0
|
||||||
|
con.original_length = bb[jopent].length
|
||||||
|
con.volume = 'NO_VOLUME'
|
||||||
|
|
||||||
|
# Head lips to jaw lips
|
||||||
|
influence = [0.0, 0.1, 0.5, 0.25, 0.0]
|
||||||
|
|
||||||
|
con = pb[hlip1].constraints.new('COPY_TRANSFORMS')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = jlip1
|
||||||
con.influence = influence[2]
|
con.influence = influence[2]
|
||||||
|
|
||||||
con = pb[jlip2].constraints.new('COPY_TRANSFORMS')
|
con = pb[hlip2].constraints.new('COPY_TRANSFORMS')
|
||||||
con.target = obj
|
con.target = obj
|
||||||
con.subtarget = hlip2
|
con.subtarget = jlip2
|
||||||
con.influence = influence[1]
|
con.influence = influence[1]
|
||||||
|
|
||||||
con = pb[jlip3].constraints.new('COPY_TRANSFORMS')
|
con = pb[hlip3].constraints.new('COPY_TRANSFORMS')
|
||||||
con.target = obj
|
con.target = obj
|
||||||
con.subtarget = hlip3
|
con.subtarget = jlip3
|
||||||
con.influence = influence[0]
|
con.influence = influence[0]
|
||||||
|
|
||||||
con = pb[jlip4].constraints.new('COPY_TRANSFORMS')
|
con = pb[hlip4].constraints.new('COPY_TRANSFORMS')
|
||||||
con.target = obj
|
con.target = obj
|
||||||
con.subtarget = hlip4
|
con.subtarget = jlip4
|
||||||
con.influence = influence[1]
|
con.influence = influence[1]
|
||||||
|
|
||||||
con = pb[jlip5].constraints.new('COPY_TRANSFORMS')
|
con = pb[hlip5].constraints.new('COPY_TRANSFORMS')
|
||||||
con.target = obj
|
con.target = obj
|
||||||
con.subtarget = hlip5
|
con.subtarget = jlip5
|
||||||
con.influence = influence[2]
|
con.influence = influence[2]
|
||||||
|
|
||||||
con = pb[jlip6].constraints.new('COPY_TRANSFORMS')
|
con = pb[hlip6].constraints.new('COPY_TRANSFORMS')
|
||||||
con.target = obj
|
con.target = obj
|
||||||
con.subtarget = hlip6
|
con.subtarget = jlip6
|
||||||
con.influence = 1.0 - influence[1]
|
con.influence = 1.0 - influence[3]
|
||||||
|
|
||||||
con = pb[jlip7].constraints.new('COPY_TRANSFORMS')
|
con = pb[hlip7].constraints.new('COPY_TRANSFORMS')
|
||||||
con.target = obj
|
con.target = obj
|
||||||
con.subtarget = hlip7
|
con.subtarget = jlip7
|
||||||
con.influence = 1.0 - influence[0]
|
con.influence = 1.0 - influence[4]
|
||||||
|
|
||||||
con = pb[jlip8].constraints.new('COPY_TRANSFORMS')
|
con = pb[hlip8].constraints.new('COPY_TRANSFORMS')
|
||||||
con.target = obj
|
con.target = obj
|
||||||
con.subtarget = hlip8
|
con.subtarget = jlip8
|
||||||
con.influence = 1.0 - influence[1]
|
con.influence = 1.0 - influence[3]
|
||||||
|
|
||||||
# ORG bones to link lips
|
# ORG bones to link lips
|
||||||
con = pb[definitions[2]].constraints.new('COPY_TRANSFORMS')
|
con = pb[definitions[2]].constraints.new('COPY_TRANSFORMS')
|
||||||
@@ -394,6 +550,151 @@ def control(obj, definitions, base_names, options):
|
|||||||
con.target = obj
|
con.target = obj
|
||||||
con.subtarget = llip8
|
con.subtarget = llip8
|
||||||
|
|
||||||
|
# Action constraints for open mouth
|
||||||
|
con = pb[lip1].constraints.new('ACTION')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = jopent
|
||||||
|
con.action = open_action
|
||||||
|
con.transform_channel = 'SCALE_Y'
|
||||||
|
con.start_frame = 0
|
||||||
|
con.end_frame = 60
|
||||||
|
con.minimum = 0.0
|
||||||
|
con.maximum = 1.0
|
||||||
|
con.target_space = 'LOCAL'
|
||||||
|
fcurve = con.driver_add("influence", 0)
|
||||||
|
driver = fcurve.driver
|
||||||
|
driver.type = 'AVERAGE'
|
||||||
|
var = driver.variables.new()
|
||||||
|
var.targets[0].id_type = 'OBJECT'
|
||||||
|
var.targets[0].id = obj
|
||||||
|
var.targets[0].data_path = open_driver_path
|
||||||
|
|
||||||
|
con = pb[lip2].constraints.new('ACTION')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = jopent
|
||||||
|
con.action = open_action
|
||||||
|
con.transform_channel = 'SCALE_Y'
|
||||||
|
con.start_frame = 0
|
||||||
|
con.end_frame = 60
|
||||||
|
con.minimum = 0.0
|
||||||
|
con.maximum = 1.0
|
||||||
|
con.target_space = 'LOCAL'
|
||||||
|
fcurve = con.driver_add("influence", 0)
|
||||||
|
driver = fcurve.driver
|
||||||
|
driver.type = 'AVERAGE'
|
||||||
|
var = driver.variables.new()
|
||||||
|
var.targets[0].id_type = 'OBJECT'
|
||||||
|
var.targets[0].id = obj
|
||||||
|
var.targets[0].data_path = open_driver_path
|
||||||
|
|
||||||
|
con = pb[lip3].constraints.new('ACTION')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = jopent
|
||||||
|
con.action = open_action
|
||||||
|
con.transform_channel = 'SCALE_Y'
|
||||||
|
con.start_frame = 0
|
||||||
|
con.end_frame = 60
|
||||||
|
con.minimum = 0.0
|
||||||
|
con.maximum = 1.0
|
||||||
|
con.target_space = 'LOCAL'
|
||||||
|
fcurve = con.driver_add("influence", 0)
|
||||||
|
driver = fcurve.driver
|
||||||
|
driver.type = 'AVERAGE'
|
||||||
|
var = driver.variables.new()
|
||||||
|
var.targets[0].id_type = 'OBJECT'
|
||||||
|
var.targets[0].id = obj
|
||||||
|
var.targets[0].data_path = open_driver_path
|
||||||
|
|
||||||
|
con = pb[lip4].constraints.new('ACTION')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = jopent
|
||||||
|
con.action = open_action
|
||||||
|
con.transform_channel = 'SCALE_Y'
|
||||||
|
con.start_frame = 0
|
||||||
|
con.end_frame = 60
|
||||||
|
con.minimum = 0.0
|
||||||
|
con.maximum = 1.0
|
||||||
|
con.target_space = 'LOCAL'
|
||||||
|
fcurve = con.driver_add("influence", 0)
|
||||||
|
driver = fcurve.driver
|
||||||
|
driver.type = 'AVERAGE'
|
||||||
|
var = driver.variables.new()
|
||||||
|
var.targets[0].id_type = 'OBJECT'
|
||||||
|
var.targets[0].id = obj
|
||||||
|
var.targets[0].data_path = open_driver_path
|
||||||
|
|
||||||
|
con = pb[lip5].constraints.new('ACTION')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = jopent
|
||||||
|
con.action = open_action
|
||||||
|
con.transform_channel = 'SCALE_Y'
|
||||||
|
con.start_frame = 0
|
||||||
|
con.end_frame = 60
|
||||||
|
con.minimum = 0.0
|
||||||
|
con.maximum = 1.0
|
||||||
|
con.target_space = 'LOCAL'
|
||||||
|
fcurve = con.driver_add("influence", 0)
|
||||||
|
driver = fcurve.driver
|
||||||
|
driver.type = 'AVERAGE'
|
||||||
|
var = driver.variables.new()
|
||||||
|
var.targets[0].id_type = 'OBJECT'
|
||||||
|
var.targets[0].id = obj
|
||||||
|
var.targets[0].data_path = open_driver_path
|
||||||
|
|
||||||
|
con = pb[lip6].constraints.new('ACTION')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = jopent
|
||||||
|
con.action = open_action
|
||||||
|
con.transform_channel = 'SCALE_Y'
|
||||||
|
con.start_frame = 0
|
||||||
|
con.end_frame = 60
|
||||||
|
con.minimum = 0.0
|
||||||
|
con.maximum = 1.0
|
||||||
|
con.target_space = 'LOCAL'
|
||||||
|
fcurve = con.driver_add("influence", 0)
|
||||||
|
driver = fcurve.driver
|
||||||
|
driver.type = 'AVERAGE'
|
||||||
|
var = driver.variables.new()
|
||||||
|
var.targets[0].id_type = 'OBJECT'
|
||||||
|
var.targets[0].id = obj
|
||||||
|
var.targets[0].data_path = open_driver_path
|
||||||
|
|
||||||
|
con = pb[lip7].constraints.new('ACTION')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = jopent
|
||||||
|
con.action = open_action
|
||||||
|
con.transform_channel = 'SCALE_Y'
|
||||||
|
con.start_frame = 0
|
||||||
|
con.end_frame = 60
|
||||||
|
con.minimum = 0.0
|
||||||
|
con.maximum = 1.0
|
||||||
|
con.target_space = 'LOCAL'
|
||||||
|
fcurve = con.driver_add("influence", 0)
|
||||||
|
driver = fcurve.driver
|
||||||
|
driver.type = 'AVERAGE'
|
||||||
|
var = driver.variables.new()
|
||||||
|
var.targets[0].id_type = 'OBJECT'
|
||||||
|
var.targets[0].id = obj
|
||||||
|
var.targets[0].data_path = open_driver_path
|
||||||
|
|
||||||
|
con = pb[lip8].constraints.new('ACTION')
|
||||||
|
con.target = obj
|
||||||
|
con.subtarget = jopent
|
||||||
|
con.action = open_action
|
||||||
|
con.transform_channel = 'SCALE_Y'
|
||||||
|
con.start_frame = 0
|
||||||
|
con.end_frame = 60
|
||||||
|
con.minimum = 0.0
|
||||||
|
con.maximum = 1.0
|
||||||
|
con.target_space = 'LOCAL'
|
||||||
|
fcurve = con.driver_add("influence", 0)
|
||||||
|
driver = fcurve.driver
|
||||||
|
driver.type = 'AVERAGE'
|
||||||
|
var = driver.variables.new()
|
||||||
|
var.targets[0].id_type = 'OBJECT'
|
||||||
|
var.targets[0].id = obj
|
||||||
|
var.targets[0].data_path = open_driver_path
|
||||||
|
|
||||||
|
|
||||||
# Set layers
|
# Set layers
|
||||||
layer = list(bb[definitions[2]].layer)
|
layer = list(bb[definitions[2]].layer)
|
||||||
|
|||||||
@@ -213,6 +213,9 @@ def main(obj, bone_definition, base_names, options):
|
|||||||
ex_chain.update()
|
ex_chain.update()
|
||||||
ex.update()
|
ex.update()
|
||||||
|
|
||||||
|
# Axis locks
|
||||||
|
ex.head_ctrl_p.lock_location = True, True, True
|
||||||
|
|
||||||
# Simple one off constraints, no drivers
|
# Simple one off constraints, no drivers
|
||||||
con = ex.head_ctrl_p.constraints.new('COPY_LOCATION')
|
con = ex.head_ctrl_p.constraints.new('COPY_LOCATION')
|
||||||
con.target = obj
|
con.target = obj
|
||||||
|
|||||||
@@ -152,6 +152,7 @@ def main(obj, bone_definition, base_names, options):
|
|||||||
|
|
||||||
control_pbone.rotation_mode = 'YZX'
|
control_pbone.rotation_mode = 'YZX'
|
||||||
control_pbone.lock_rotation = False, True, True
|
control_pbone.lock_rotation = False, True, True
|
||||||
|
control_pbone.lock_location = True, True, True
|
||||||
|
|
||||||
driver_fcurves = pinky_pbone.driver_add("rotation_euler")
|
driver_fcurves = pinky_pbone.driver_add("rotation_euler")
|
||||||
|
|
||||||
@@ -163,6 +164,8 @@ def main(obj, bone_definition, base_names, options):
|
|||||||
prop = rna_idprop_ui_prop_get(control_pbone, "spread", create=True)
|
prop = rna_idprop_ui_prop_get(control_pbone, "spread", create=True)
|
||||||
prop["soft_min"] = -1.0
|
prop["soft_min"] = -1.0
|
||||||
prop["soft_max"] = 1.0
|
prop["soft_max"] = 1.0
|
||||||
|
prop["min"] = -1.0
|
||||||
|
prop["max"] = 1.0
|
||||||
|
|
||||||
|
|
||||||
# *****
|
# *****
|
||||||
@@ -246,15 +249,15 @@ def main(obj, bone_definition, base_names, options):
|
|||||||
# NOTE: the direction of the Z rotation depends on which side the palm is on.
|
# NOTE: the direction of the Z rotation depends on which side the palm is on.
|
||||||
# we could do a simple side-of-x test but better to work out the direction
|
# we could do a simple side-of-x test but better to work out the direction
|
||||||
# the hand is facing.
|
# the hand is facing.
|
||||||
from Mathutils import Vector, AngleBetweenVecs
|
from Mathutils import Vector
|
||||||
from math import degrees
|
from math import degrees
|
||||||
child_pbone_01 = obj.pose.bones[children[0]].bone
|
child_pbone_01 = obj.pose.bones[children[0]].bone
|
||||||
child_pbone_02 = obj.pose.bones[children[1]].bone
|
child_pbone_02 = obj.pose.bones[children[1]].bone
|
||||||
|
|
||||||
rel_vec = child_pbone_01.head - child_pbone_02.head
|
rel_vec = child_pbone_01.head - child_pbone_02.head
|
||||||
x_vec = child_pbone_01.matrix.rotationPart() * Vector(1.0, 0.0, 0.0)
|
x_vec = child_pbone_01.matrix.rotation_part() * Vector(1.0, 0.0, 0.0)
|
||||||
|
|
||||||
return degrees(AngleBetweenVecs(rel_vec, x_vec)) > 90.0
|
return degrees(rel_vec.angle(x_vec)) > 90.0
|
||||||
|
|
||||||
if x_direction(): # flip
|
if x_direction(): # flip
|
||||||
driver.expression = "-(%s)" % driver.expression
|
driver.expression = "-(%s)" % driver.expression
|
||||||
|
|||||||
176
release/scripts/modules/rigify/shape_key_distance.py
Normal file
176
release/scripts/modules/rigify/shape_key_distance.py
Normal file
@@ -0,0 +1,176 @@
|
|||||||
|
# ##### 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
|
||||||
|
from rna_prop_ui import rna_idprop_ui_prop_get
|
||||||
|
from math import acos
|
||||||
|
from Mathutils import Vector
|
||||||
|
from rigify import get_layer_dict
|
||||||
|
from rigify_utils import bone_class_instance, copy_bone_simple
|
||||||
|
|
||||||
|
#METARIG_NAMES = ("cpy",)
|
||||||
|
RIG_TYPE = "shape_key_distance"
|
||||||
|
|
||||||
|
|
||||||
|
def addget_shape_key(obj, name="Key"):
|
||||||
|
""" Fetches a shape key, or creates it if it doesn't exist
|
||||||
|
"""
|
||||||
|
# Create a shapekey set if it doesn't already exist
|
||||||
|
if obj.data.shape_keys is None:
|
||||||
|
shape = obj.add_shape_key(name="Basis", from_mix=False)
|
||||||
|
obj.active_shape_key_index = 0
|
||||||
|
|
||||||
|
# Get the shapekey, or create it if it doesn't already exist
|
||||||
|
if name in obj.data.shape_keys.keys:
|
||||||
|
shape_key = obj.data.shape_keys.keys[name]
|
||||||
|
else:
|
||||||
|
shape_key = obj.add_shape_key(name=name, from_mix=False)
|
||||||
|
|
||||||
|
return shape_key
|
||||||
|
|
||||||
|
|
||||||
|
def addget_shape_key_driver(obj, name="Key"):
|
||||||
|
""" Fetches the driver for the shape key, or creates it if it doesn't
|
||||||
|
already exist.
|
||||||
|
"""
|
||||||
|
driver_path = 'keys["' + name + '"].value'
|
||||||
|
fcurve = None
|
||||||
|
driver = None
|
||||||
|
if obj.data.shape_keys.animation_data is not None:
|
||||||
|
for driver_s in obj.data.shape_keys.animation_data.drivers:
|
||||||
|
if driver_s.data_path == driver_path:
|
||||||
|
fcurve = driver_s
|
||||||
|
if fcurve == None:
|
||||||
|
fcurve = obj.data.shape_keys.keys[name].driver_add("value", 0)
|
||||||
|
fcurve.driver.type = 'AVERAGE'
|
||||||
|
|
||||||
|
return fcurve
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def metarig_template():
|
||||||
|
# generated by rigify.write_meta_rig
|
||||||
|
bpy.ops.object.mode_set(mode='EDIT')
|
||||||
|
obj = bpy.context.active_object
|
||||||
|
arm = obj.data
|
||||||
|
bone = arm.edit_bones.new('Bone')
|
||||||
|
bone.head[:] = 0.0000, 0.0000, 0.0000
|
||||||
|
bone.tail[:] = 0.0000, 0.0000, 1.0000
|
||||||
|
bone.roll = 0.0000
|
||||||
|
bone.connected = False
|
||||||
|
|
||||||
|
bpy.ops.object.mode_set(mode='OBJECT')
|
||||||
|
pbone = obj.pose.bones['Bone']
|
||||||
|
pbone['type'] = 'copy'
|
||||||
|
|
||||||
|
|
||||||
|
def metarig_definition(obj, orig_bone_name):
|
||||||
|
bone = obj.data.bones[orig_bone_name]
|
||||||
|
return [bone.name]
|
||||||
|
|
||||||
|
|
||||||
|
def deform(obj, definitions, base_names, options):
|
||||||
|
bpy.ops.object.mode_set(mode='EDIT')
|
||||||
|
eb = obj.data.edit_bones
|
||||||
|
|
||||||
|
bone_from = definitions[0]
|
||||||
|
|
||||||
|
|
||||||
|
# Options
|
||||||
|
req_options = ["to", "mesh", "shape_key"]
|
||||||
|
for option in req_options:
|
||||||
|
if option not in options:
|
||||||
|
raise RigifyError("'%s' rig type requires a '%s' option (bone: %s)" % (RIG_TYPE, option, base_names[definitions[0]]))
|
||||||
|
|
||||||
|
bone_to = "ORG-" + options["to"]
|
||||||
|
meshes = options["mesh"].replace(" ", "").split(",")
|
||||||
|
shape_key_name = options["shape_key"]
|
||||||
|
|
||||||
|
if "dmul" in options:
|
||||||
|
shape_blend_fac = options["dmul"]
|
||||||
|
else:
|
||||||
|
shape_blend_fac = 1.0
|
||||||
|
|
||||||
|
|
||||||
|
# Calculate the distance between the bones
|
||||||
|
distance = (eb[bone_from].head - eb[bone_to].head).length
|
||||||
|
|
||||||
|
bpy.ops.object.mode_set(mode='OBJECT')
|
||||||
|
|
||||||
|
# For every listed mesh object
|
||||||
|
for mesh_name in meshes:
|
||||||
|
mesh_obj = bpy.data.objects[mesh_name]
|
||||||
|
|
||||||
|
# Add/get the shape key
|
||||||
|
shape_key = addget_shape_key(mesh_obj, name=shape_key_name)
|
||||||
|
|
||||||
|
# Add/get the shape key driver
|
||||||
|
fcurve = addget_shape_key_driver(mesh_obj, name=shape_key_name)
|
||||||
|
driver = fcurve.driver
|
||||||
|
|
||||||
|
# Get the variable, or create it if it doesn't already exist
|
||||||
|
var_name = base_names[bone_from]
|
||||||
|
if var_name in driver.variables:
|
||||||
|
var = driver.variables[var_name]
|
||||||
|
else:
|
||||||
|
var = driver.variables.new()
|
||||||
|
var.name = var_name
|
||||||
|
|
||||||
|
# Set up the variable
|
||||||
|
var.type = "LOC_DIFF"
|
||||||
|
var.targets[0].id_type = 'OBJECT'
|
||||||
|
var.targets[0].id = obj
|
||||||
|
var.targets[0].bone_target = bone_from
|
||||||
|
var.targets[1].id_type = 'OBJECT'
|
||||||
|
var.targets[1].id = obj
|
||||||
|
var.targets[1].bone_target = bone_to
|
||||||
|
|
||||||
|
# Set fcurve offset, so zero is at the rest distance
|
||||||
|
|
||||||
|
mod = fcurve.modifiers[0]
|
||||||
|
if distance > 0.00001:
|
||||||
|
mod.coefficients[0] = -shape_blend_fac
|
||||||
|
mod.coefficients[1] = shape_blend_fac / distance
|
||||||
|
|
||||||
|
return (None,)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def control(obj, definitions, base_names, options):
|
||||||
|
""" options:
|
||||||
|
mesh: name of mesh object with the shape key
|
||||||
|
shape_key: name of shape key
|
||||||
|
to: name of bone to measure distance from
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def main(obj, bone_definition, base_names, options):
|
||||||
|
# Create control rig
|
||||||
|
#control(obj, bone_definition, base_names, options)
|
||||||
|
# Create deform rig
|
||||||
|
deform(obj, bone_definition, base_names, options)
|
||||||
|
|
||||||
|
return (None,)
|
||||||
|
|
||||||
176
release/scripts/modules/rigify/shape_key_rotdiff.py
Normal file
176
release/scripts/modules/rigify/shape_key_rotdiff.py
Normal file
@@ -0,0 +1,176 @@
|
|||||||
|
# ##### 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
|
||||||
|
from rna_prop_ui import rna_idprop_ui_prop_get
|
||||||
|
from math import acos
|
||||||
|
from Mathutils import Vector
|
||||||
|
from rigify import get_layer_dict
|
||||||
|
from rigify_utils import bone_class_instance, copy_bone_simple
|
||||||
|
|
||||||
|
#METARIG_NAMES = ("cpy",)
|
||||||
|
RIG_TYPE = "shape_key_rotdiff"
|
||||||
|
|
||||||
|
|
||||||
|
def addget_shape_key(obj, name="Key"):
|
||||||
|
""" Fetches a shape key, or creates it if it doesn't exist
|
||||||
|
"""
|
||||||
|
# Create a shapekey set if it doesn't already exist
|
||||||
|
if obj.data.shape_keys is None:
|
||||||
|
shape = obj.add_shape_key(name="Basis", from_mix=False)
|
||||||
|
obj.active_shape_key_index = 0
|
||||||
|
|
||||||
|
# Get the shapekey, or create it if it doesn't already exist
|
||||||
|
if name in obj.data.shape_keys.keys:
|
||||||
|
shape_key = obj.data.shape_keys.keys[name]
|
||||||
|
else:
|
||||||
|
shape_key = obj.add_shape_key(name=name, from_mix=False)
|
||||||
|
|
||||||
|
return shape_key
|
||||||
|
|
||||||
|
|
||||||
|
def addget_shape_key_driver(obj, name="Key"):
|
||||||
|
""" Fetches the driver for the shape key, or creates it if it doesn't
|
||||||
|
already exist.
|
||||||
|
"""
|
||||||
|
driver_path = 'keys["' + name + '"].value'
|
||||||
|
fcurve = None
|
||||||
|
driver = None
|
||||||
|
if obj.data.shape_keys.animation_data is not None:
|
||||||
|
for driver_s in obj.data.shape_keys.animation_data.drivers:
|
||||||
|
if driver_s.data_path == driver_path:
|
||||||
|
fcurve = driver_s
|
||||||
|
if fcurve == None:
|
||||||
|
fcurve = obj.data.shape_keys.keys[name].driver_add("value", 0)
|
||||||
|
fcurve.driver.type = 'AVERAGE'
|
||||||
|
|
||||||
|
return fcurve
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def metarig_template():
|
||||||
|
# generated by rigify.write_meta_rig
|
||||||
|
bpy.ops.object.mode_set(mode='EDIT')
|
||||||
|
obj = bpy.context.active_object
|
||||||
|
arm = obj.data
|
||||||
|
bone = arm.edit_bones.new('Bone')
|
||||||
|
bone.head[:] = 0.0000, 0.0000, 0.0000
|
||||||
|
bone.tail[:] = 0.0000, 0.0000, 1.0000
|
||||||
|
bone.roll = 0.0000
|
||||||
|
bone.connected = False
|
||||||
|
|
||||||
|
bpy.ops.object.mode_set(mode='OBJECT')
|
||||||
|
pbone = obj.pose.bones['Bone']
|
||||||
|
pbone['type'] = 'copy'
|
||||||
|
|
||||||
|
|
||||||
|
def metarig_definition(obj, orig_bone_name):
|
||||||
|
bone = obj.data.bones[orig_bone_name]
|
||||||
|
return [bone.name]
|
||||||
|
|
||||||
|
|
||||||
|
def deform(obj, definitions, base_names, options):
|
||||||
|
bpy.ops.object.mode_set(mode='EDIT')
|
||||||
|
eb = obj.data.edit_bones
|
||||||
|
|
||||||
|
bone_from = definitions[0]
|
||||||
|
|
||||||
|
|
||||||
|
# Options
|
||||||
|
req_options = ["to", "mesh", "shape_key"]
|
||||||
|
for option in req_options:
|
||||||
|
if option not in options:
|
||||||
|
raise RigifyError("'%s' rig type requires a '%s' option (bone: %s)" % (RIG_TYPE, option, base_names[definitions[0]]))
|
||||||
|
|
||||||
|
bone_to = "ORG-" + options["to"]
|
||||||
|
meshes = options["mesh"].replace(" ", "").split(",")
|
||||||
|
shape_key_name = options["shape_key"]
|
||||||
|
|
||||||
|
if "dmul" in options:
|
||||||
|
shape_blend_fac = options["dmul"]
|
||||||
|
else:
|
||||||
|
shape_blend_fac = 1.0
|
||||||
|
|
||||||
|
|
||||||
|
# Calculate the rotation difference between the bones
|
||||||
|
rotdiff = (eb[bone_from].matrix.to_quat() * eb[bone_to].matrix.to_quat()) * 2
|
||||||
|
|
||||||
|
bpy.ops.object.mode_set(mode='OBJECT')
|
||||||
|
|
||||||
|
# For every listed mesh object
|
||||||
|
for mesh_name in meshes:
|
||||||
|
mesh_obj = bpy.data.objects[mesh_name]
|
||||||
|
|
||||||
|
# Add/get the shape key
|
||||||
|
shape_key = addget_shape_key(mesh_obj, name=shape_key_name)
|
||||||
|
|
||||||
|
# Add/get the shape key driver
|
||||||
|
fcurve = addget_shape_key_driver(mesh_obj, name=shape_key_name)
|
||||||
|
driver = fcurve.driver
|
||||||
|
|
||||||
|
# Get the variable, or create it if it doesn't already exist
|
||||||
|
var_name = base_names[bone_from]
|
||||||
|
if var_name in driver.variables:
|
||||||
|
var = driver.variables[var_name]
|
||||||
|
else:
|
||||||
|
var = driver.variables.new()
|
||||||
|
var.name = var_name
|
||||||
|
|
||||||
|
# Set up the variable
|
||||||
|
var.type = "ROTATION_DIFF"
|
||||||
|
var.targets[0].id_type = 'OBJECT'
|
||||||
|
var.targets[0].id = obj
|
||||||
|
var.targets[0].bone_target = bone_from
|
||||||
|
var.targets[1].id_type = 'OBJECT'
|
||||||
|
var.targets[1].id = obj
|
||||||
|
var.targets[1].bone_target = bone_to
|
||||||
|
|
||||||
|
# Set fcurve offset, so zero is at the rest distance
|
||||||
|
|
||||||
|
mod = fcurve.modifiers[0]
|
||||||
|
if rotdiff > 0.00001:
|
||||||
|
mod.coefficients[0] = -shape_blend_fac
|
||||||
|
mod.coefficients[1] = shape_blend_fac / rotdiff
|
||||||
|
|
||||||
|
return (None,)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def control(obj, definitions, base_names, options):
|
||||||
|
""" options:
|
||||||
|
mesh: name of mesh object with the shape key
|
||||||
|
shape_key: name of shape key
|
||||||
|
to: name of bone to measure distance from
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def main(obj, bone_definition, base_names, options):
|
||||||
|
# Create control rig
|
||||||
|
#control(obj, bone_definition, base_names, options)
|
||||||
|
# Create deform rig
|
||||||
|
deform(obj, bone_definition, base_names, options)
|
||||||
|
|
||||||
|
return (None,)
|
||||||
|
|
||||||
@@ -304,6 +304,9 @@ def main(obj, bone_definition, base_names, options):
|
|||||||
mt_chain.update()
|
mt_chain.update()
|
||||||
ex_chain.update()
|
ex_chain.update()
|
||||||
rv_chain.update()
|
rv_chain.update()
|
||||||
|
|
||||||
|
# Axis locks
|
||||||
|
ex.ribcage_copy_p.lock_location = True, True, True
|
||||||
|
|
||||||
# df.pelvis_p / DEF-wgt_pelvis
|
# df.pelvis_p / DEF-wgt_pelvis
|
||||||
con = df.pelvis_p.constraints.new('COPY_LOCATION')
|
con = df.pelvis_p.constraints.new('COPY_LOCATION')
|
||||||
@@ -437,7 +440,10 @@ def main(obj, bone_definition, base_names, options):
|
|||||||
# Add bend prop
|
# Add bend prop
|
||||||
prop_name = "bend_%.2d" % i
|
prop_name = "bend_%.2d" % i
|
||||||
prop = rna_idprop_ui_prop_get(ex.ribcage_copy_p, prop_name, create=True)
|
prop = rna_idprop_ui_prop_get(ex.ribcage_copy_p, prop_name, create=True)
|
||||||
ex.ribcage_copy_p[prop_name] = 1.0
|
if ("bend_%.2d" % i) in options:
|
||||||
|
ex.ribcage_copy_p[prop_name] = options["bend_%.2d" % i]
|
||||||
|
else:
|
||||||
|
ex.ribcage_copy_p[prop_name] = 1.0
|
||||||
prop["soft_min"] = 0.0
|
prop["soft_min"] = 0.0
|
||||||
prop["soft_max"] = 1.0
|
prop["soft_max"] = 1.0
|
||||||
|
|
||||||
|
|||||||
@@ -145,28 +145,12 @@ def blend_bone_list(obj, apply_bones, from_bones, to_bones, target_bone=None, ta
|
|||||||
var.targets[0].id = obj
|
var.targets[0].id = obj
|
||||||
var.targets[0].data_path = driver_path
|
var.targets[0].data_path = driver_path
|
||||||
|
|
||||||
def blend_location(new_pbone, from_bone_name, to_bone_name):
|
def blend_transforms(new_pbone, from_bone_name, to_bone_name):
|
||||||
con = new_pbone.constraints.new('COPY_LOCATION')
|
con = new_pbone.constraints.new('COPY_TRANSFORMS')
|
||||||
con.target = obj
|
con.target = obj
|
||||||
con.subtarget = from_bone_name
|
con.subtarget = from_bone_name
|
||||||
|
|
||||||
con = new_pbone.constraints.new('COPY_LOCATION')
|
con = new_pbone.constraints.new('COPY_TRANSFORMS')
|
||||||
con.target = obj
|
|
||||||
con.subtarget = to_bone_name
|
|
||||||
|
|
||||||
fcurve = con.driver_add("influence", 0)
|
|
||||||
driver = fcurve.driver
|
|
||||||
driver.type = 'AVERAGE'
|
|
||||||
fcurve.modifiers.remove(0) # grr dont need a modifier
|
|
||||||
|
|
||||||
blend_target(driver)
|
|
||||||
|
|
||||||
def blend_rotation(new_pbone, from_bone_name, to_bone_name):
|
|
||||||
con = new_pbone.constraints.new('COPY_ROTATION')
|
|
||||||
con.target = obj
|
|
||||||
con.subtarget = from_bone_name
|
|
||||||
|
|
||||||
con = new_pbone.constraints.new('COPY_ROTATION')
|
|
||||||
con.target = obj
|
con.target = obj
|
||||||
con.subtarget = to_bone_name
|
con.subtarget = to_bone_name
|
||||||
|
|
||||||
@@ -187,12 +171,8 @@ def blend_bone_list(obj, apply_bones, from_bones, to_bones, target_bone=None, ta
|
|||||||
|
|
||||||
new_pbone = obj.pose.bones[new_bone_name]
|
new_pbone = obj.pose.bones[new_bone_name]
|
||||||
|
|
||||||
# if the bone is connected or its location is totally locked then dont add location blending.
|
blend_transforms(new_pbone, from_bone_name, to_bone_name)
|
||||||
if not (new_pbone.bone.connected or (False not in new_pbone.lock_location)):
|
|
||||||
blend_location(new_pbone, from_bone_name, to_bone_name)
|
|
||||||
|
|
||||||
if not (False not in new_pbone.lock_rotation): # TODO. 4D chech?
|
|
||||||
blend_rotation(new_pbone, from_bone_name, to_bone_name)
|
|
||||||
|
|
||||||
|
|
||||||
def add_pole_target_bone(obj, base_bone_name, name, mode='CROSS'):
|
def add_pole_target_bone(obj, base_bone_name, name, mode='CROSS'):
|
||||||
@@ -225,8 +205,8 @@ def add_pole_target_bone(obj, base_bone_name, name, mode='CROSS'):
|
|||||||
offset.length = distance
|
offset.length = distance
|
||||||
elif mode == 'ZAVERAGE':
|
elif mode == 'ZAVERAGE':
|
||||||
# between both bones Z axis
|
# between both bones Z axis
|
||||||
z_axis_a = base_ebone.matrix.copy().rotationPart() * Vector(0.0, 0.0, -1.0)
|
z_axis_a = base_ebone.matrix.copy().rotation_part() * Vector(0.0, 0.0, -1.0)
|
||||||
z_axis_b = parent_ebone.matrix.copy().rotationPart() * Vector(0.0, 0.0, -1.0)
|
z_axis_b = parent_ebone.matrix.copy().rotation_part() * Vector(0.0, 0.0, -1.0)
|
||||||
offset = (z_axis_a + z_axis_b).normalize() * distance
|
offset = (z_axis_a + z_axis_b).normalize() * distance
|
||||||
else:
|
else:
|
||||||
# preset axis
|
# preset axis
|
||||||
@@ -294,8 +274,8 @@ def write_meta_rig(obj, func_name="metarig_template"):
|
|||||||
for bone_name in bones:
|
for bone_name in bones:
|
||||||
bone = arm.edit_bones[bone_name]
|
bone = arm.edit_bones[bone_name]
|
||||||
code.append(" bone = arm.edit_bones.new('%s')" % bone.name)
|
code.append(" bone = arm.edit_bones.new('%s')" % bone.name)
|
||||||
code.append(" bone.head[:] = %.4f, %.4f, %.4f" % bone.head.toTuple(4))
|
code.append(" bone.head[:] = %.4f, %.4f, %.4f" % bone.head.to_tuple(4))
|
||||||
code.append(" bone.tail[:] = %.4f, %.4f, %.4f" % bone.tail.toTuple(4))
|
code.append(" bone.tail[:] = %.4f, %.4f, %.4f" % bone.tail.to_tuple(4))
|
||||||
code.append(" bone.roll = %.4f" % bone.roll)
|
code.append(" bone.roll = %.4f" % bone.roll)
|
||||||
code.append(" bone.connected = %s" % str(bone.connected))
|
code.append(" bone.connected = %s" % str(bone.connected))
|
||||||
if bone.parent:
|
if bone.parent:
|
||||||
|
|||||||
@@ -263,7 +263,7 @@ class InfoFunctionRNA:
|
|||||||
|
|
||||||
for rna_prop in rna_func.parameters.values():
|
for rna_prop in rna_func.parameters.values():
|
||||||
prop = GetInfoPropertyRNA(rna_prop, parent_id)
|
prop = GetInfoPropertyRNA(rna_prop, parent_id)
|
||||||
if rna_prop.use_return:
|
if rna_prop.use_output:
|
||||||
self.return_values.append(prop)
|
self.return_values.append(prop)
|
||||||
else:
|
else:
|
||||||
self.args.append(prop)
|
self.args.append(prop)
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ class MeshMirrorUV(bpy.types.Operator):
|
|||||||
mirror_gt = {}
|
mirror_gt = {}
|
||||||
mirror_lt = {}
|
mirror_lt = {}
|
||||||
|
|
||||||
vcos = [v.co.toTuple(5) for v in mesh.verts]
|
vcos = [v.co.to_tuple(5) for v in mesh.verts]
|
||||||
|
|
||||||
for i, co in enumerate(vcos):
|
for i, co in enumerate(vcos):
|
||||||
if co[0] > 0.0:
|
if co[0] > 0.0:
|
||||||
|
|||||||
@@ -22,8 +22,7 @@
|
|||||||
import time, functools
|
import time, functools
|
||||||
import bpy
|
import bpy
|
||||||
# from Blender import Window
|
# from Blender import Window
|
||||||
from Mathutils import MidpointVecs, Vector
|
from Mathutils import Vector
|
||||||
from Mathutils import AngleBetweenVecs as _AngleBetweenVecs_
|
|
||||||
# import BPyMessages
|
# import BPyMessages
|
||||||
|
|
||||||
# from Blender.Draw import PupMenu
|
# from Blender.Draw import PupMenu
|
||||||
@@ -36,7 +35,7 @@ CULL_METHOD = 0
|
|||||||
def AngleBetweenVecs(a1,a2):
|
def AngleBetweenVecs(a1,a2):
|
||||||
import math
|
import math
|
||||||
try:
|
try:
|
||||||
return math.degrees(_AngleBetweenVecs_(a1,a2))
|
return math.degrees(a1.angle(a2))
|
||||||
except:
|
except:
|
||||||
return 180.0
|
return 180.0
|
||||||
|
|
||||||
@@ -54,7 +53,7 @@ class edge(object):
|
|||||||
self.removed = 0 # Have we been culled from the eloop
|
self.removed = 0 # Have we been culled from the eloop
|
||||||
self.match = None # The other edge were making a face with
|
self.match = None # The other edge were making a face with
|
||||||
|
|
||||||
self.cent= MidpointVecs(co1, co2)
|
self.cent= co1.lerp(co2, 0.5)
|
||||||
self.angle= 0.0
|
self.angle= 0.0
|
||||||
self.fake= False
|
self.fake= False
|
||||||
|
|
||||||
@@ -501,7 +500,7 @@ def skin2EdgeLoops(eloop1, eloop2, me, ob, MODE):
|
|||||||
|
|
||||||
return new_faces
|
return new_faces
|
||||||
|
|
||||||
def main(context):
|
def main(self, context):
|
||||||
global CULL_METHOD
|
global CULL_METHOD
|
||||||
|
|
||||||
ob = context.object
|
ob = context.object
|
||||||
@@ -509,7 +508,7 @@ def main(context):
|
|||||||
is_editmode = (ob.mode=='EDIT')
|
is_editmode = (ob.mode=='EDIT')
|
||||||
if is_editmode: bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
|
if is_editmode: bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
|
||||||
if ob == None or ob.type != 'MESH':
|
if ob == None or ob.type != 'MESH':
|
||||||
raise Exception("BPyMessages.Error_NoMeshActive()")
|
self.report({'ERROR'}, "No active mesh selected\n")
|
||||||
return
|
return
|
||||||
|
|
||||||
me = ob.data
|
me = ob.data
|
||||||
@@ -518,7 +517,7 @@ def main(context):
|
|||||||
selEdges = getSelectedEdges(context, me, ob)
|
selEdges = getSelectedEdges(context, me, ob)
|
||||||
vertLoops = getVertLoops(selEdges, me) # list of lists of edges.
|
vertLoops = getVertLoops(selEdges, me) # list of lists of edges.
|
||||||
if vertLoops == None:
|
if vertLoops == None:
|
||||||
raise Exception('Error%t|Selection includes verts that are a part of more then 1 loop')
|
self.report({'ERROR'}, "Selection includes verts that are a part of more then 1 loop\n")
|
||||||
if is_editmode: bpy.ops.object.mode_set(mode='EDIT', toggle=False)
|
if is_editmode: bpy.ops.object.mode_set(mode='EDIT', toggle=False)
|
||||||
return
|
return
|
||||||
# print len(vertLoops)
|
# print len(vertLoops)
|
||||||
@@ -531,7 +530,7 @@ def main(context):
|
|||||||
return
|
return
|
||||||
|
|
||||||
elif len(vertLoops) < 2:
|
elif len(vertLoops) < 2:
|
||||||
raise Exception('Error%t|No Vertloops found!')
|
self.report({'ERROR'}, "No Vertloops found\n")
|
||||||
if is_editmode: bpy.ops.object.mode_set(mode='EDIT', toggle=False)
|
if is_editmode: bpy.ops.object.mode_set(mode='EDIT', toggle=False)
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
@@ -642,7 +641,7 @@ class MESH_OT_skin(bpy.types.Operator):
|
|||||||
'''
|
'''
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
main(context)
|
main(self, context)
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
146
release/scripts/op/object_randomize_transform.py
Normal file
146
release/scripts/op/object_randomize_transform.py
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
# ##### 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
|
||||||
|
|
||||||
|
|
||||||
|
def randomize_selected(seed, loc, rot, scale, scale_even, scale_min):
|
||||||
|
|
||||||
|
import random
|
||||||
|
from random import uniform
|
||||||
|
from Mathutils import Vector
|
||||||
|
|
||||||
|
random.seed(seed)
|
||||||
|
|
||||||
|
def rand_vec(vec_range):
|
||||||
|
return Vector([uniform(- val, val) for val in vec_range])
|
||||||
|
|
||||||
|
for obj in bpy.context.selected_objects:
|
||||||
|
|
||||||
|
if loc:
|
||||||
|
obj.location += rand_vec(loc)
|
||||||
|
else: # otherwise the values change under us
|
||||||
|
uniform(0.0, 0.0), uniform(0.0, 0.0), uniform(0.0, 0.0)
|
||||||
|
|
||||||
|
if rot: # TODO, non euler's
|
||||||
|
vec = rand_vec(rot)
|
||||||
|
obj.rotation_euler[0] += vec[0]
|
||||||
|
obj.rotation_euler[1] += vec[1]
|
||||||
|
obj.rotation_euler[2] += vec[2]
|
||||||
|
else:
|
||||||
|
uniform(0.0, 0.0), uniform(0.0, 0.0), uniform(0.0, 0.0)
|
||||||
|
|
||||||
|
if scale:
|
||||||
|
org_sca_x, org_sca_y, org_sca_z = obj.scale
|
||||||
|
|
||||||
|
if scale_even:
|
||||||
|
sca_x = sca_y = sca_z = uniform(scale[0], - scale[0])
|
||||||
|
uniform(0.0, 0.0), uniform(0.0, 0.0)
|
||||||
|
else:
|
||||||
|
sca_x, sca_y, sca_z = rand_vec(scale)
|
||||||
|
|
||||||
|
aX = sca_x + org_sca_x
|
||||||
|
bX = org_sca_x * scale_min
|
||||||
|
|
||||||
|
aY = sca_y + org_sca_y
|
||||||
|
bY = org_sca_y * scale_min
|
||||||
|
|
||||||
|
aZ = sca_z + org_sca_z
|
||||||
|
bZ = org_sca_z * scale_min
|
||||||
|
|
||||||
|
if aX < bX:
|
||||||
|
aX = bX
|
||||||
|
if aY < bY:
|
||||||
|
aY = bY
|
||||||
|
if aZ < bZ:
|
||||||
|
aZ = bZ
|
||||||
|
|
||||||
|
obj.scale = aX, aY, aZ
|
||||||
|
else:
|
||||||
|
uniform(0.0, 0.0), uniform(0.0, 0.0), uniform(0.0, 0.0)
|
||||||
|
|
||||||
|
from bpy.props import *
|
||||||
|
|
||||||
|
|
||||||
|
class RandomizeLocRotSize(bpy.types.Operator):
|
||||||
|
'''Randomize objects loc/rot/scale.'''
|
||||||
|
bl_idname = "object.randomize_locrotsize"
|
||||||
|
bl_label = "Randomize Loc Rot Size"
|
||||||
|
bl_register = True
|
||||||
|
bl_undo = True
|
||||||
|
|
||||||
|
random_seed = IntProperty(name="Random Seed",
|
||||||
|
description="Seed value for the random generator",
|
||||||
|
default=0, min=0, max=1000)
|
||||||
|
|
||||||
|
use_loc = BoolProperty(name="Randomize Location",
|
||||||
|
description="Randomize the scale values", default=True)
|
||||||
|
|
||||||
|
loc = FloatVectorProperty(name="Location",
|
||||||
|
description="Maximun distance the objects can spread over each axis",
|
||||||
|
default=(0.0, 0.0, 0.0), min=-100.0, max=100.0)
|
||||||
|
|
||||||
|
use_rot = BoolProperty(name="Randomize Rotation",
|
||||||
|
description="Randomize the rotation values", default=True)
|
||||||
|
|
||||||
|
rot = FloatVectorProperty(name="Rotation",
|
||||||
|
description="Maximun rotation over each axis",
|
||||||
|
default=(0.0, 0.0, 0.0), min=-180.0, max=180.0)
|
||||||
|
|
||||||
|
use_scale = BoolProperty(name="Randomize Scale",
|
||||||
|
description="Randomize the scale values", default=True)
|
||||||
|
|
||||||
|
scale_even = BoolProperty(name="Scale Even",
|
||||||
|
description="Use the same scale value for all axis", default=False)
|
||||||
|
|
||||||
|
scale_min = FloatProperty(name="Minimun Scale Factor",
|
||||||
|
description="Lowest scale percentage possible",
|
||||||
|
default=0.15, min=-1.0, max=1.0, precision=3)
|
||||||
|
|
||||||
|
scale = FloatVectorProperty(name="Scale",
|
||||||
|
description="Maximum scale randomization over each axis",
|
||||||
|
default=(0.0, 0.0, 0.0), min=-100.0, max=100.0)
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
from math import radians
|
||||||
|
seed = self.properties.random_seed
|
||||||
|
|
||||||
|
loc = None if not self.properties.use_loc else self.properties.loc
|
||||||
|
rot = None if not self.properties.use_rot else self.properties.rot * radians(1.0)
|
||||||
|
scale = None if not self.properties.use_scale else self.properties.scale
|
||||||
|
|
||||||
|
scale_even = self.properties.scale_even
|
||||||
|
scale_min = self.properties.scale_min
|
||||||
|
|
||||||
|
randomize_selected(seed, loc, rot, scale, scale_even, scale_min)
|
||||||
|
|
||||||
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
|
# Register the operator
|
||||||
|
bpy.types.register(RandomizeLocRotSize)
|
||||||
|
|
||||||
|
|
||||||
|
def menu_func(self, context):
|
||||||
|
if context.mode == 'OBJECT':
|
||||||
|
self.layout.operator(RandomizeLocRotSize.bl_idname,
|
||||||
|
text="Randomize Loc Rot Size")
|
||||||
|
|
||||||
|
bpy.types.VIEW3D_MT_transform.append(menu_func)
|
||||||
@@ -52,6 +52,10 @@ class ExportUVLayout(bpy.types.Operator):
|
|||||||
return image_width, image_height
|
return image_width, image_height
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
|
# for making an XML compatible string
|
||||||
|
from xml.sax.saxutils import escape
|
||||||
|
from os.path import basename
|
||||||
|
|
||||||
ob = context.active_object
|
ob = context.active_object
|
||||||
is_editmode = (ob.mode == 'EDIT')
|
is_editmode = (ob.mode == 'EDIT')
|
||||||
if is_editmode:
|
if is_editmode:
|
||||||
@@ -84,15 +88,17 @@ class ExportUVLayout(bpy.types.Operator):
|
|||||||
fw('<svg width="%dpx" height="%dpx" viewBox="0px 0px %dpx %dpx"\n' % (image_width, image_height, image_width, image_height))
|
fw('<svg width="%dpx" height="%dpx" viewBox="0px 0px %dpx %dpx"\n' % (image_width, image_height, image_width, image_height))
|
||||||
fw(' xmlns="http://www.w3.org/2000/svg" version="1.1">\n')
|
fw(' xmlns="http://www.w3.org/2000/svg" version="1.1">\n')
|
||||||
|
|
||||||
fw('<desc>%s, %s, %s (Blender %s)</desc>\n' % (bpy.data.filename, ob.name, mesh.name, bpy.app.version_string))
|
desc = "%s, %s, %s (Blender %s)" % (basename(bpy.data.filename), ob.name, mesh.name, bpy.app.version_string)
|
||||||
|
fw('<desc>%s</desc>\n' % escape(desc))
|
||||||
|
|
||||||
# svg colors
|
# svg colors
|
||||||
fill_settings = []
|
fill_settings = []
|
||||||
|
fill_default = 'fill="grey"'
|
||||||
for mat in mesh.materials if mesh.materials else [None]:
|
for mat in mesh.materials if mesh.materials else [None]:
|
||||||
if mat:
|
if mat:
|
||||||
fill_settings.append('fill="rgb(%d, %d, %d)"' % tuple(int(c*255) for c in mat.diffuse_color))
|
fill_settings.append('fill="rgb(%d, %d, %d)"' % tuple(int(c*255) for c in mat.diffuse_color))
|
||||||
else:
|
else:
|
||||||
fill_settings.append('fill="grey"')
|
fill_settings.append(fill_default)
|
||||||
|
|
||||||
only_selected = self.properties.only_selected
|
only_selected = self.properties.only_selected
|
||||||
|
|
||||||
@@ -105,8 +111,13 @@ class ExportUVLayout(bpy.types.Operator):
|
|||||||
uvs = uv.uv1, uv.uv2, uv.uv3
|
uvs = uv.uv1, uv.uv2, uv.uv3
|
||||||
else:
|
else:
|
||||||
uvs = uv.uv1, uv.uv2, uv.uv3, uv.uv4
|
uvs = uv.uv1, uv.uv2, uv.uv3, uv.uv4
|
||||||
|
|
||||||
|
try: # rare cases material index is invalid.
|
||||||
|
fill = fill_settings[faces[i].material_index]
|
||||||
|
except IndexError:
|
||||||
|
fill = fill_default
|
||||||
|
|
||||||
fw('<polygon %s fill-opacity="0.5" stroke="black" stroke-width="1px" \n' % fill_settings[faces[i].material_index])
|
fw('<polygon %s fill-opacity="0.5" stroke="black" stroke-width="1px" \n' % fill)
|
||||||
fw(' points="')
|
fw(' points="')
|
||||||
|
|
||||||
for j, uv in enumerate(uvs):
|
for j, uv in enumerate(uvs):
|
||||||
|
|||||||
@@ -936,7 +936,7 @@ def main(context, island_margin, projection_limit):
|
|||||||
# Initialize projectVecs
|
# Initialize projectVecs
|
||||||
if USER_VIEW_INIT:
|
if USER_VIEW_INIT:
|
||||||
# Generate Projection
|
# Generate Projection
|
||||||
projectVecs = [Vector(Window.GetViewVector()) * ob.matrixWorld.copy().invert().rotationPart()] # We add to this allong the way
|
projectVecs = [Vector(Window.GetViewVector()) * ob.matrixWorld.copy().invert().rotation_part()] # We add to this allong the way
|
||||||
else:
|
else:
|
||||||
projectVecs = []
|
projectVecs = []
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
# for keyboard event comparison
|
# for keyboard event comparison
|
||||||
# import GameKeys
|
# import GameKeys
|
||||||
|
|
||||||
# support for Vector(), Matrix() types and advanced functions like AngleBetweenVecs(v1,v2) and RotationMatrix(...)
|
# support for Vector(), Matrix() types and advanced functions like ScaleMatrix(...) and RotationMatrix(...)
|
||||||
# import Mathutils
|
# import Mathutils
|
||||||
|
|
||||||
# for functions like getWindowWidth(), getWindowHeight()
|
# for functions like getWindowWidth(), getWindowHeight()
|
||||||
|
|||||||
22
release/scripts/templates/panel_simple.py
Normal file
22
release/scripts/templates/panel_simple.py
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import bpy
|
||||||
|
|
||||||
|
class OBJECT_PT_hello(bpy.types.Panel):
|
||||||
|
bl_label = "Hello World Panel"
|
||||||
|
bl_space_type = "PROPERTIES"
|
||||||
|
bl_region_type = "WINDOW"
|
||||||
|
bl_context = "object"
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
|
||||||
|
obj = context.object
|
||||||
|
|
||||||
|
row = layout.row()
|
||||||
|
row.label(text="Hello world!", icon='WORLD_DATA')
|
||||||
|
|
||||||
|
row = layout.row()
|
||||||
|
row.label(text="Active object is: " + obj.name)
|
||||||
|
row = layout.row()
|
||||||
|
row.prop(obj, "name")
|
||||||
|
|
||||||
|
bpy.types.register(OBJECT_PT_hello)
|
||||||
160
release/scripts/ui/properties_animviz.py
Normal file
160
release/scripts/ui/properties_animviz.py
Normal file
@@ -0,0 +1,160 @@
|
|||||||
|
# ##### 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
|
||||||
|
|
||||||
|
narrowui = 180
|
||||||
|
|
||||||
|
################################################
|
||||||
|
# Generic Panels (Independent of DataType)
|
||||||
|
|
||||||
|
class MotionPathButtonsPanel(bpy.types.Panel):
|
||||||
|
bl_space_type = 'PROPERTIES'
|
||||||
|
bl_region_type = 'WINDOW'
|
||||||
|
bl_label = "Motion Paths"
|
||||||
|
|
||||||
|
def draw_settings(self, context, avs, wide_ui, bones=False):
|
||||||
|
layout = self.layout
|
||||||
|
|
||||||
|
mps = avs.motion_paths
|
||||||
|
|
||||||
|
if wide_ui:
|
||||||
|
layout.prop(mps, "type", expand=True)
|
||||||
|
else:
|
||||||
|
layout.prop(mps, "type", text="")
|
||||||
|
|
||||||
|
split = layout.split()
|
||||||
|
|
||||||
|
col = split.column()
|
||||||
|
sub = col.column(align=True)
|
||||||
|
if (mps.type == 'CURRENT_FRAME'):
|
||||||
|
sub.prop(mps, "before_current", text="Before")
|
||||||
|
sub.prop(mps, "after_current", text="After")
|
||||||
|
elif (mps.type == 'RANGE'):
|
||||||
|
sub.prop(mps, "start_frame", text="Start")
|
||||||
|
sub.prop(mps, "end_frame", text="End")
|
||||||
|
|
||||||
|
sub.prop(mps, "frame_step", text="Step")
|
||||||
|
if bones:
|
||||||
|
col.row().prop(mps, "bake_location", expand=True)
|
||||||
|
|
||||||
|
if wide_ui:
|
||||||
|
col = split.column()
|
||||||
|
col.label(text="Display:")
|
||||||
|
col.prop(mps, "show_frame_numbers", text="Frame Numbers")
|
||||||
|
col.prop(mps, "highlight_keyframes", text="Keyframes")
|
||||||
|
col.prop(mps, "show_keyframe_numbers", text="Keyframe Numbers")
|
||||||
|
|
||||||
|
# FIXME: this panel still needs to be ported so that it will work correctly with animviz
|
||||||
|
class OnionSkinButtonsPanel(bpy.types.Panel):
|
||||||
|
bl_space_type = 'PROPERTIES'
|
||||||
|
bl_region_type = 'WINDOW'
|
||||||
|
bl_label = "Onion Skinning"
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
|
||||||
|
arm = context.armature
|
||||||
|
wide_ui = context.region.width > narrowui
|
||||||
|
|
||||||
|
if wide_ui:
|
||||||
|
layout.prop(arm, "ghost_type", expand=True)
|
||||||
|
else:
|
||||||
|
layout.prop(arm, "ghost_type", text="")
|
||||||
|
|
||||||
|
split = layout.split()
|
||||||
|
|
||||||
|
col = split.column()
|
||||||
|
|
||||||
|
sub = col.column(align=True)
|
||||||
|
if arm.ghost_type == 'RANGE':
|
||||||
|
sub.prop(arm, "ghost_start_frame", text="Start")
|
||||||
|
sub.prop(arm, "ghost_end_frame", text="End")
|
||||||
|
sub.prop(arm, "ghost_size", text="Step")
|
||||||
|
elif arm.ghost_type == 'CURRENT_FRAME':
|
||||||
|
sub.prop(arm, "ghost_step", text="Range")
|
||||||
|
sub.prop(arm, "ghost_size", text="Step")
|
||||||
|
|
||||||
|
if wide_ui:
|
||||||
|
col = split.column()
|
||||||
|
col.label(text="Display:")
|
||||||
|
col.prop(arm, "ghost_only_selected", text="Selected Only")
|
||||||
|
|
||||||
|
################################################
|
||||||
|
# Specific Panels for DataTypes
|
||||||
|
|
||||||
|
class OBJECT_PT_motion_paths(MotionPathButtonsPanel):
|
||||||
|
#bl_label = "Object Motion Paths"
|
||||||
|
bl_context = "object"
|
||||||
|
|
||||||
|
def poll(self, context):
|
||||||
|
return (context.object)
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
|
||||||
|
ob = context.object
|
||||||
|
wide_ui = context.region.width > narrowui
|
||||||
|
|
||||||
|
self.draw_settings(context, ob.animation_visualisation, wide_ui)
|
||||||
|
|
||||||
|
layout.separator()
|
||||||
|
|
||||||
|
split = layout.split()
|
||||||
|
|
||||||
|
col = split.column()
|
||||||
|
col.operator("object.paths_calculate", text="Calculate Paths")
|
||||||
|
|
||||||
|
if wide_ui:
|
||||||
|
col = split.column()
|
||||||
|
col.operator("object.paths_clear", text="Clear Paths")
|
||||||
|
|
||||||
|
class DATA_PT_motion_paths(MotionPathButtonsPanel):
|
||||||
|
#bl_label = "Bone Motion Paths"
|
||||||
|
bl_context = "data"
|
||||||
|
|
||||||
|
def poll(self, context):
|
||||||
|
# XXX: include posemode check?
|
||||||
|
return (context.object) and (context.armature)
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
|
||||||
|
ob = context.object
|
||||||
|
wide_ui = context.region.width > narrowui
|
||||||
|
|
||||||
|
self.draw_settings(context, ob.pose.animation_visualisation, wide_ui, bones=True)
|
||||||
|
|
||||||
|
layout.separator()
|
||||||
|
|
||||||
|
split = layout.split()
|
||||||
|
|
||||||
|
col = split.column()
|
||||||
|
col.operator("pose.paths_calculate", text="Calculate Paths")
|
||||||
|
|
||||||
|
if wide_ui:
|
||||||
|
col = split.column()
|
||||||
|
col.operator("pose.paths_clear", text="Clear Paths")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#bpy.types.register(OBJECT_PT_onion_skinning)
|
||||||
|
#bpy.types.register(DATA_PT_onion_skinning)
|
||||||
|
bpy.types.register(OBJECT_PT_motion_paths)
|
||||||
|
bpy.types.register(DATA_PT_motion_paths)
|
||||||
@@ -158,58 +158,11 @@ class DATA_PT_bone_groups(DataButtonsPanel):
|
|||||||
row.active = (ob.proxy is None)
|
row.active = (ob.proxy is None)
|
||||||
|
|
||||||
row.operator("pose.group_assign", text="Assign")
|
row.operator("pose.group_assign", text="Assign")
|
||||||
row.operator("pose.group_remove", text="Remove") #row.operator("pose.bone_group_remove_from", text="Remove")
|
row.operator("pose.group_unassign", text="Remove") #row.operator("pose.bone_group_remove_from", text="Remove")
|
||||||
#row.operator("object.bone_group_select", text="Select")
|
#row.operator("object.bone_group_select", text="Select")
|
||||||
#row.operator("object.bone_group_deselect", text="Deselect")
|
#row.operator("object.bone_group_deselect", text="Deselect")
|
||||||
|
|
||||||
|
# TODO: this panel will soon be depreceated too
|
||||||
class DATA_PT_paths(DataButtonsPanel):
|
|
||||||
bl_label = "Paths"
|
|
||||||
|
|
||||||
def draw(self, context):
|
|
||||||
layout = self.layout
|
|
||||||
|
|
||||||
arm = context.armature
|
|
||||||
wide_ui = context.region.width > narrowui
|
|
||||||
|
|
||||||
if wide_ui:
|
|
||||||
layout.prop(arm, "paths_type", expand=True)
|
|
||||||
else:
|
|
||||||
layout.prop(arm, "paths_type", text="")
|
|
||||||
|
|
||||||
split = layout.split()
|
|
||||||
|
|
||||||
col = split.column()
|
|
||||||
sub = col.column(align=True)
|
|
||||||
if (arm.paths_type == 'CURRENT_FRAME'):
|
|
||||||
sub.prop(arm, "path_before_current", text="Before")
|
|
||||||
sub.prop(arm, "path_after_current", text="After")
|
|
||||||
elif (arm.paths_type == 'RANGE'):
|
|
||||||
sub.prop(arm, "path_start_frame", text="Start")
|
|
||||||
sub.prop(arm, "path_end_frame", text="End")
|
|
||||||
|
|
||||||
sub.prop(arm, "path_size", text="Step")
|
|
||||||
col.row().prop(arm, "paths_location", expand=True)
|
|
||||||
|
|
||||||
if wide_ui:
|
|
||||||
col = split.column()
|
|
||||||
col.label(text="Display:")
|
|
||||||
col.prop(arm, "paths_show_frame_numbers", text="Frame Numbers")
|
|
||||||
col.prop(arm, "paths_highlight_keyframes", text="Keyframes")
|
|
||||||
col.prop(arm, "paths_show_keyframe_numbers", text="Keyframe Numbers")
|
|
||||||
|
|
||||||
layout.separator()
|
|
||||||
|
|
||||||
split = layout.split()
|
|
||||||
|
|
||||||
col = split.column()
|
|
||||||
col.operator("pose.paths_calculate", text="Calculate Paths")
|
|
||||||
|
|
||||||
if wide_ui:
|
|
||||||
col = split.column()
|
|
||||||
col.operator("pose.paths_clear", text="Clear Paths")
|
|
||||||
|
|
||||||
|
|
||||||
class DATA_PT_ghost(DataButtonsPanel):
|
class DATA_PT_ghost(DataButtonsPanel):
|
||||||
bl_label = "Ghost"
|
bl_label = "Ghost"
|
||||||
|
|
||||||
@@ -302,7 +255,6 @@ bpy.types.register(DATA_PT_context_arm)
|
|||||||
bpy.types.register(DATA_PT_skeleton)
|
bpy.types.register(DATA_PT_skeleton)
|
||||||
bpy.types.register(DATA_PT_display)
|
bpy.types.register(DATA_PT_display)
|
||||||
bpy.types.register(DATA_PT_bone_groups)
|
bpy.types.register(DATA_PT_bone_groups)
|
||||||
bpy.types.register(DATA_PT_paths)
|
|
||||||
bpy.types.register(DATA_PT_ghost)
|
bpy.types.register(DATA_PT_ghost)
|
||||||
bpy.types.register(DATA_PT_iksolver_itasc)
|
bpy.types.register(DATA_PT_iksolver_itasc)
|
||||||
|
|
||||||
|
|||||||
@@ -352,6 +352,7 @@ class DATA_PT_spot(DataButtonsPanel):
|
|||||||
sub.prop(lamp, "spot_size", text="Size")
|
sub.prop(lamp, "spot_size", text="Size")
|
||||||
sub.prop(lamp, "spot_blend", text="Blend", slider=True)
|
sub.prop(lamp, "spot_blend", text="Blend", slider=True)
|
||||||
col.prop(lamp, "square")
|
col.prop(lamp, "square")
|
||||||
|
col.prop(lamp, "show_cone")
|
||||||
|
|
||||||
if wide_ui:
|
if wide_ui:
|
||||||
col = split.column()
|
col = split.column()
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
import bpy
|
import bpy
|
||||||
|
|
||||||
narrowui = 180
|
narrowui = 180
|
||||||
|
narrowmod = 260
|
||||||
|
|
||||||
class DataButtonsPanel(bpy.types.Panel):
|
class DataButtonsPanel(bpy.types.Panel):
|
||||||
bl_space_type = 'PROPERTIES'
|
bl_space_type = 'PROPERTIES'
|
||||||
@@ -36,14 +36,13 @@ class DATA_PT_modifiers(DataButtonsPanel):
|
|||||||
|
|
||||||
ob = context.object
|
ob = context.object
|
||||||
wide_ui = context.region.width > narrowui
|
wide_ui = context.region.width > narrowui
|
||||||
|
compact_mod = context.region.width < narrowmod
|
||||||
|
|
||||||
row = layout.row()
|
row = layout.row()
|
||||||
row.operator_menu_enum("object.modifier_add", "type")
|
row.operator_menu_enum("object.modifier_add", "type")
|
||||||
if wide_ui:
|
|
||||||
row.label()
|
|
||||||
|
|
||||||
for md in ob.modifiers:
|
for md in ob.modifiers:
|
||||||
box = layout.template_modifier(md)
|
box = layout.template_modifier(md, compact=compact_mod)
|
||||||
if box:
|
if box:
|
||||||
# match enum type to our functions, avoids a lookup table.
|
# match enum type to our functions, avoids a lookup table.
|
||||||
getattr(self, md.type)(box, ob, md, wide_ui)
|
getattr(self, md.type)(box, ob, md, wide_ui)
|
||||||
@@ -352,10 +351,11 @@ class DATA_PT_modifiers(DataButtonsPanel):
|
|||||||
col.prop(md, "mode", text="")
|
col.prop(md, "mode", text="")
|
||||||
if wide_ui:
|
if wide_ui:
|
||||||
col = split.column()
|
col = split.column()
|
||||||
col.label(text="Vertex Group:")
|
|
||||||
if md.mode == 'ARMATURE':
|
if md.mode == 'ARMATURE':
|
||||||
|
col.label(text="Armature:")
|
||||||
col.prop(md, "armature", text="")
|
col.prop(md, "armature", text="")
|
||||||
elif md.mode == 'VERTEX_GROUP':
|
elif md.mode == 'VERTEX_GROUP':
|
||||||
|
col.label(text="Vertex Group:")
|
||||||
col.prop_object(md, "vertex_group", ob, "vertex_groups", text="")
|
col.prop_object(md, "vertex_group", ob, "vertex_groups", text="")
|
||||||
|
|
||||||
sub = col.column()
|
sub = col.column()
|
||||||
|
|||||||
@@ -80,6 +80,8 @@ class PHYSICS_PT_smoke(PhysicButtonsPanel):
|
|||||||
col = split.column()
|
col = split.column()
|
||||||
col.label(text="Resolution:")
|
col.label(text="Resolution:")
|
||||||
col.prop(domain, "maxres", text="Divisions")
|
col.prop(domain, "maxres", text="Divisions")
|
||||||
|
col.label(text="Particle:")
|
||||||
|
col.prop(domain, "initial_velocity", text="Initial Velocity")
|
||||||
|
|
||||||
if wide_ui:
|
if wide_ui:
|
||||||
col = split.column()
|
col = split.column()
|
||||||
@@ -155,6 +157,13 @@ class PHYSICS_PT_smoke_cache(PhysicButtonsPanel):
|
|||||||
return md and (md.smoke_type == 'TYPE_DOMAIN')
|
return md and (md.smoke_type == 'TYPE_DOMAIN')
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
|
||||||
|
domain = context.smoke.domain_settings
|
||||||
|
|
||||||
|
layout.label(text="Compression:")
|
||||||
|
layout.prop(domain, "smoke_cache_comp", expand=True)
|
||||||
|
|
||||||
md = context.smoke.domain_settings
|
md = context.smoke.domain_settings
|
||||||
cache = md.point_cache_low
|
cache = md.point_cache_low
|
||||||
|
|
||||||
@@ -203,6 +212,14 @@ class PHYSICS_PT_smoke_cache_highres(PhysicButtonsPanel):
|
|||||||
return md and (md.smoke_type == 'TYPE_DOMAIN') and md.domain_settings.highres
|
return md and (md.smoke_type == 'TYPE_DOMAIN') and md.domain_settings.highres
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
|
||||||
|
domain = context.smoke.domain_settings
|
||||||
|
|
||||||
|
layout.label(text="Compression:")
|
||||||
|
layout.prop(domain, "smoke_cache_high_comp", expand=True)
|
||||||
|
|
||||||
|
|
||||||
md = context.smoke.domain_settings
|
md = context.smoke.domain_settings
|
||||||
cache = md.point_cache_high
|
cache = md.point_cache_high
|
||||||
|
|
||||||
|
|||||||
@@ -74,6 +74,8 @@ class SCENE_PT_unit(SceneButtonsPanel):
|
|||||||
if wide_ui:
|
if wide_ui:
|
||||||
col = split.column()
|
col = split.column()
|
||||||
col.prop(unit, "use_separate")
|
col.prop(unit, "use_separate")
|
||||||
|
|
||||||
|
layout.column().prop(unit, "rotation_units")
|
||||||
|
|
||||||
|
|
||||||
class SCENE_PT_keying_sets(SceneButtonsPanel):
|
class SCENE_PT_keying_sets(SceneButtonsPanel):
|
||||||
@@ -178,11 +180,40 @@ class SCENE_PT_physics(SceneButtonsPanel):
|
|||||||
else:
|
else:
|
||||||
layout.column().prop(scene, "gravity", text="")
|
layout.column().prop(scene, "gravity", text="")
|
||||||
|
|
||||||
|
class SCENE_PT_simplify(SceneButtonsPanel):
|
||||||
|
bl_label = "Simplify"
|
||||||
|
COMPAT_ENGINES = {'BLENDER_RENDER'}
|
||||||
|
|
||||||
|
def draw_header(self, context):
|
||||||
|
scene = context.scene
|
||||||
|
rd = scene.render_data
|
||||||
|
self.layout.prop(rd, "use_simplify", text="")
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
scene = context.scene
|
||||||
|
rd = scene.render_data
|
||||||
|
wide_ui = context.region.width > narrowui
|
||||||
|
|
||||||
|
layout.active = rd.use_simplify
|
||||||
|
|
||||||
|
split = layout.split()
|
||||||
|
|
||||||
|
col = split.column()
|
||||||
|
col.prop(rd, "simplify_subdivision", text="Subdivision")
|
||||||
|
col.prop(rd, "simplify_child_particles", text="Child Particles")
|
||||||
|
|
||||||
|
if wide_ui:
|
||||||
|
col = split.column()
|
||||||
|
col.prop(rd, "simplify_shadow_samples", text="Shadow Samples")
|
||||||
|
col.prop(rd, "simplify_ao_sss", text="AO and SSS")
|
||||||
|
|
||||||
bpy.types.register(SCENE_PT_scene)
|
bpy.types.register(SCENE_PT_scene)
|
||||||
bpy.types.register(SCENE_PT_unit)
|
bpy.types.register(SCENE_PT_unit)
|
||||||
bpy.types.register(SCENE_PT_keying_sets)
|
bpy.types.register(SCENE_PT_keying_sets)
|
||||||
bpy.types.register(SCENE_PT_keying_set_paths)
|
bpy.types.register(SCENE_PT_keying_set_paths)
|
||||||
bpy.types.register(SCENE_PT_physics)
|
bpy.types.register(SCENE_PT_physics)
|
||||||
|
bpy.types.register(SCENE_PT_simplify)
|
||||||
|
|
||||||
bpy.types.register(SCENE_PT_custom_props)
|
bpy.types.register(SCENE_PT_custom_props)
|
||||||
|
|
||||||
|
|||||||
@@ -851,6 +851,7 @@ class TEXTURE_PT_voxeldata(TextureButtonsPanel):
|
|||||||
layout.prop(vd, "resolution")
|
layout.prop(vd, "resolution")
|
||||||
elif vd.file_format == 'SMOKE':
|
elif vd.file_format == 'SMOKE':
|
||||||
layout.prop(vd, "domain_object")
|
layout.prop(vd, "domain_object")
|
||||||
|
layout.prop(vd, "smoke_data_type")
|
||||||
elif vd.file_format == 'IMAGE_SEQUENCE':
|
elif vd.file_format == 'IMAGE_SEQUENCE':
|
||||||
layout.template_image(tex, "image", tex.image_user)
|
layout.template_image(tex, "image", tex.image_user)
|
||||||
|
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ class DOPESHEET_MT_view(bpy.types.Menu):
|
|||||||
|
|
||||||
layout.column()
|
layout.column()
|
||||||
|
|
||||||
|
layout.prop(st, "realtime_updates")
|
||||||
layout.prop(st, "show_cframe_indicator")
|
layout.prop(st, "show_cframe_indicator")
|
||||||
layout.prop(st, "show_sliders")
|
layout.prop(st, "show_sliders")
|
||||||
layout.prop(st, "automerge_keyframes")
|
layout.prop(st, "automerge_keyframes")
|
||||||
|
|||||||
@@ -68,9 +68,10 @@ class GRAPH_MT_view(bpy.types.Menu):
|
|||||||
|
|
||||||
layout.column()
|
layout.column()
|
||||||
|
|
||||||
layout.separator()
|
|
||||||
layout.operator("graph.properties", icon='MENU_PANEL')
|
layout.operator("graph.properties", icon='MENU_PANEL')
|
||||||
|
layout.separator()
|
||||||
|
|
||||||
|
layout.prop(st, "realtime_updates")
|
||||||
layout.prop(st, "show_cframe_indicator")
|
layout.prop(st, "show_cframe_indicator")
|
||||||
layout.prop(st, "show_cursor")
|
layout.prop(st, "show_cursor")
|
||||||
layout.prop(st, "show_sliders")
|
layout.prop(st, "show_sliders")
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ class IMAGE_MT_view(bpy.types.Menu):
|
|||||||
show_uvedit = sima.show_uvedit
|
show_uvedit = sima.show_uvedit
|
||||||
|
|
||||||
layout.operator("image.properties", icon='MENU_PANEL')
|
layout.operator("image.properties", icon='MENU_PANEL')
|
||||||
|
layout.operator("image.scopes", icon='MENU_PANEL')
|
||||||
|
|
||||||
layout.separator()
|
layout.separator()
|
||||||
|
|
||||||
@@ -386,6 +387,21 @@ class IMAGE_PT_game_properties(bpy.types.Panel):
|
|||||||
col.separator()
|
col.separator()
|
||||||
col.prop(ima, "mapping", expand=True)
|
col.prop(ima, "mapping", expand=True)
|
||||||
|
|
||||||
|
class IMAGE_PT_view_histogram(bpy.types.Panel):
|
||||||
|
bl_space_type = 'IMAGE_EDITOR'
|
||||||
|
bl_region_type = 'PREVIEW'
|
||||||
|
bl_label = "Histogram"
|
||||||
|
|
||||||
|
def poll(self, context):
|
||||||
|
sima = context.space_data
|
||||||
|
return (sima and sima.image)
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
|
||||||
|
sima = context.space_data
|
||||||
|
|
||||||
|
layout.template_histogram(sima, "histogram")
|
||||||
|
|
||||||
class IMAGE_PT_view_properties(bpy.types.Panel):
|
class IMAGE_PT_view_properties(bpy.types.Panel):
|
||||||
bl_space_type = 'IMAGE_EDITOR'
|
bl_space_type = 'IMAGE_EDITOR'
|
||||||
@@ -417,6 +433,7 @@ class IMAGE_PT_view_properties(bpy.types.Panel):
|
|||||||
col.prop(sima, "draw_repeated", text="Repeat")
|
col.prop(sima, "draw_repeated", text="Repeat")
|
||||||
if show_uvedit:
|
if show_uvedit:
|
||||||
col.prop(uvedit, "normalized_coordinates", text="Normalized")
|
col.prop(uvedit, "normalized_coordinates", text="Normalized")
|
||||||
|
|
||||||
elif show_uvedit:
|
elif show_uvedit:
|
||||||
col.label(text="Coordinates:")
|
col.label(text="Coordinates:")
|
||||||
col.prop(uvedit, "normalized_coordinates", text="Normalized")
|
col.prop(uvedit, "normalized_coordinates", text="Normalized")
|
||||||
@@ -562,3 +579,4 @@ bpy.types.register(IMAGE_PT_paint_stroke)
|
|||||||
bpy.types.register(IMAGE_PT_paint_curve)
|
bpy.types.register(IMAGE_PT_paint_curve)
|
||||||
bpy.types.register(IMAGE_PT_game_properties)
|
bpy.types.register(IMAGE_PT_game_properties)
|
||||||
bpy.types.register(IMAGE_PT_view_properties)
|
bpy.types.register(IMAGE_PT_view_properties)
|
||||||
|
bpy.types.register(IMAGE_PT_view_histogram)
|
||||||
|
|||||||
@@ -90,6 +90,8 @@ class INFO_MT_file(bpy.types.Menu):
|
|||||||
layout.separator()
|
layout.separator()
|
||||||
|
|
||||||
layout.operator("screen.userpref_show", text="User Preferences...", icon='PREFERENCES')
|
layout.operator("screen.userpref_show", text="User Preferences...", icon='PREFERENCES')
|
||||||
|
|
||||||
|
layout.operator_context = 'EXEC_AREA'
|
||||||
layout.operator("wm.read_homefile", text="Load Factory Settings").factory = True
|
layout.operator("wm.read_homefile", text="Load Factory Settings").factory = True
|
||||||
|
|
||||||
layout.separator()
|
layout.separator()
|
||||||
@@ -222,7 +224,11 @@ class INFO_MT_add(bpy.types.Menu):
|
|||||||
layout.operator_menu_enum("object.effector_add", "type", 'EMPTY', text="Force Field", icon='OUTLINER_OB_EMPTY')
|
layout.operator_menu_enum("object.effector_add", "type", 'EMPTY', text="Force Field", icon='OUTLINER_OB_EMPTY')
|
||||||
layout.separator()
|
layout.separator()
|
||||||
|
|
||||||
layout.operator_menu_enum("object.group_instance_add", "type", text="Group Instance", icon='OUTLINER_OB_EMPTY')
|
if(len(bpy.data.groups) > 10):
|
||||||
|
layout.operator_context = 'INVOKE_DEFAULT'
|
||||||
|
layout.operator("object.group_instance_add", "type", text="Group Instance...", icon='OUTLINER_OB_EMPTY')
|
||||||
|
else:
|
||||||
|
layout.operator_menu_enum("object.group_instance_add", "type", text="Group Instance", icon='OUTLINER_OB_EMPTY')
|
||||||
|
|
||||||
|
|
||||||
class INFO_MT_game(bpy.types.Menu):
|
class INFO_MT_game(bpy.types.Menu):
|
||||||
|
|||||||
@@ -58,6 +58,8 @@ class NLA_MT_view(bpy.types.Menu):
|
|||||||
layout.operator("nla.properties", icon='MENU_PANEL')
|
layout.operator("nla.properties", icon='MENU_PANEL')
|
||||||
|
|
||||||
layout.separator()
|
layout.separator()
|
||||||
|
|
||||||
|
layout.prop(st, "realtime_updates")
|
||||||
layout.prop(st, "show_cframe_indicator")
|
layout.prop(st, "show_cframe_indicator")
|
||||||
|
|
||||||
layout.operator("anim.time_toggle", text="Show Frames" if st.show_seconds else "Show Seconds")
|
layout.operator("anim.time_toggle", text="Show Frames" if st.show_seconds else "Show Seconds")
|
||||||
|
|||||||
@@ -78,7 +78,6 @@ class TEXT_PT_properties(bpy.types.Panel):
|
|||||||
layout = self.layout
|
layout = self.layout
|
||||||
|
|
||||||
st = context.space_data
|
st = context.space_data
|
||||||
text = st.text
|
|
||||||
|
|
||||||
flow = layout.column_flow()
|
flow = layout.column_flow()
|
||||||
flow.prop(st, "line_numbers")
|
flow.prop(st, "line_numbers")
|
||||||
@@ -89,7 +88,10 @@ class TEXT_PT_properties(bpy.types.Panel):
|
|||||||
flow = layout.column_flow()
|
flow = layout.column_flow()
|
||||||
flow.prop(st, "font_size")
|
flow.prop(st, "font_size")
|
||||||
flow.prop(st, "tab_width")
|
flow.prop(st, "tab_width")
|
||||||
flow.prop(text, "tabs_as_spaces")
|
|
||||||
|
text = st.text
|
||||||
|
if text:
|
||||||
|
flow.prop(text, "tabs_as_spaces")
|
||||||
|
|
||||||
|
|
||||||
class TEXT_PT_find(bpy.types.Panel):
|
class TEXT_PT_find(bpy.types.Panel):
|
||||||
|
|||||||
@@ -114,7 +114,13 @@ class TIME_MT_frame(bpy.types.Menu):
|
|||||||
layout.operator("marker.duplicate", text="Duplicate Marker")
|
layout.operator("marker.duplicate", text="Duplicate Marker")
|
||||||
layout.operator("marker.move", text="Grab/Move Marker")
|
layout.operator("marker.move", text="Grab/Move Marker")
|
||||||
layout.operator("marker.delete", text="Delete Marker")
|
layout.operator("marker.delete", text="Delete Marker")
|
||||||
layout.label(text="ToDo: Name Marker")
|
|
||||||
|
# it was ok for riscos... ok TODO, operator
|
||||||
|
for marker in context.scene.timeline_markers:
|
||||||
|
if marker.selected:
|
||||||
|
layout.separator()
|
||||||
|
layout.prop(marker, "name", text="", icon='MARKER_HLT')
|
||||||
|
break
|
||||||
|
|
||||||
layout.separator()
|
layout.separator()
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
# <pep8 compliant>
|
# <pep8 compliant>
|
||||||
import bpy
|
import bpy
|
||||||
|
import os.path
|
||||||
|
|
||||||
# General UI Theme Settings (User Interface)
|
# General UI Theme Settings (User Interface)
|
||||||
def ui_items_general(col, context):
|
def ui_items_general(col, context):
|
||||||
@@ -161,7 +162,8 @@ class USERPREF_HT_header(bpy.types.Header):
|
|||||||
|
|
||||||
if userpref.active_section == 'INPUT':
|
if userpref.active_section == 'INPUT':
|
||||||
layout.operator_context = 'INVOKE_DEFAULT'
|
layout.operator_context = 'INVOKE_DEFAULT'
|
||||||
layout.operator("wm.keyconfig_export", "Export Key Configuration...").path = "keymap.py"
|
op = layout.operator("wm.keyconfig_export", "Export Key Configuration...")
|
||||||
|
op.path = "keymap.py"
|
||||||
|
|
||||||
|
|
||||||
class USERPREF_PT_tabs(bpy.types.Panel):
|
class USERPREF_PT_tabs(bpy.types.Panel):
|
||||||
@@ -416,6 +418,13 @@ class USERPREF_PT_system(bpy.types.Panel):
|
|||||||
col.separator()
|
col.separator()
|
||||||
col.separator()
|
col.separator()
|
||||||
col.separator()
|
col.separator()
|
||||||
|
|
||||||
|
col.label(text="Screencast:")
|
||||||
|
col.prop(system, "screencast_fps")
|
||||||
|
col.prop(system, "screencast_wait_time")
|
||||||
|
col.separator()
|
||||||
|
col.separator()
|
||||||
|
col.separator()
|
||||||
|
|
||||||
#column = split.column()
|
#column = split.column()
|
||||||
#colsplit = column.split(percentage=0.85)
|
#colsplit = column.split(percentage=0.85)
|
||||||
@@ -735,6 +744,7 @@ class USERPREF_PT_theme(bpy.types.Panel):
|
|||||||
|
|
||||||
col = split.column()
|
col = split.column()
|
||||||
col.prop(image, "back")
|
col.prop(image, "back")
|
||||||
|
col.prop(image, "scope_back")
|
||||||
col.prop(image, "button")
|
col.prop(image, "button")
|
||||||
|
|
||||||
col = split.column()
|
col = split.column()
|
||||||
@@ -1043,10 +1053,12 @@ class USERPREF_PT_input(bpy.types.Panel):
|
|||||||
row = col.row()
|
row = col.row()
|
||||||
row.prop(km, "children_expanded", text="", no_bg=True)
|
row.prop(km, "children_expanded", text="", no_bg=True)
|
||||||
row.label(text=km.name)
|
row.label(text=km.name)
|
||||||
|
|
||||||
row.label()
|
row.label()
|
||||||
row.label()
|
row.label()
|
||||||
|
|
||||||
|
if km.modal:
|
||||||
|
row.label(text="", icon='LINKED')
|
||||||
if km.user_defined:
|
if km.user_defined:
|
||||||
row.operator("wm.keymap_restore", text="Restore")
|
row.operator("wm.keymap_restore", text="Restore")
|
||||||
else:
|
else:
|
||||||
@@ -1158,15 +1170,24 @@ class USERPREF_PT_input(bpy.types.Panel):
|
|||||||
subrow.prop(kmi, "alt")
|
subrow.prop(kmi, "alt")
|
||||||
subrow.prop(kmi, "oskey", text="Cmd")
|
subrow.prop(kmi, "oskey", text="Cmd")
|
||||||
subrow.prop(kmi, "key_modifier", text="", event=True)
|
subrow.prop(kmi, "key_modifier", text="", event=True)
|
||||||
|
|
||||||
|
def display_properties(properties, title = None):
|
||||||
|
box.separator()
|
||||||
|
if title:
|
||||||
|
box.label(text=title)
|
||||||
|
flow = box.column_flow(columns=2)
|
||||||
|
for pname in dir(properties):
|
||||||
|
if not properties.is_property_hidden(pname):
|
||||||
|
value = eval("properties." + pname)
|
||||||
|
if isinstance(value, bpy.types.OperatorProperties):
|
||||||
|
display_properties(value, title = pname)
|
||||||
|
else:
|
||||||
|
flow.prop(properties, pname)
|
||||||
|
|
||||||
# Operator properties
|
# Operator properties
|
||||||
props = kmi.properties
|
props = kmi.properties
|
||||||
if props is not None:
|
if props is not None:
|
||||||
box.separator()
|
display_properties(props)
|
||||||
flow = box.column_flow(columns=2)
|
|
||||||
for pname in dir(props):
|
|
||||||
if not props.is_property_hidden(pname):
|
|
||||||
flow.prop(props, pname)
|
|
||||||
|
|
||||||
# Modal key maps attached to this operator
|
# Modal key maps attached to this operator
|
||||||
if not km.modal:
|
if not km.modal:
|
||||||
@@ -1336,16 +1357,22 @@ class WM_OT_keyconfig_test(bpy.types.Operator):
|
|||||||
s.append(", key_modifier=\'%s\'" % kmi.key_modifier)
|
s.append(", key_modifier=\'%s\'" % kmi.key_modifier)
|
||||||
|
|
||||||
s.append(")\n")
|
s.append(")\n")
|
||||||
|
|
||||||
|
def export_properties(prefix, properties):
|
||||||
|
for pname in dir(properties):
|
||||||
|
if not properties.is_property_hidden(pname):
|
||||||
|
value = eval("properties.%s" % pname)
|
||||||
|
if isinstance(value, bpy.types.OperatorProperties):
|
||||||
|
export_properties(prefix + "." + pname, value)
|
||||||
|
elif properties.is_property_set(pname):
|
||||||
|
value = _string_value(value)
|
||||||
|
if value != "":
|
||||||
|
s.append(prefix + ".%s = %s\n" % (pname, value))
|
||||||
|
|
||||||
props = kmi.properties
|
props = kmi.properties
|
||||||
|
|
||||||
if props is not None:
|
if props is not None:
|
||||||
for pname in dir(props):
|
export_properties("kmi.properties", props)
|
||||||
if props.is_property_set(pname) and not props.is_property_hidden(pname):
|
|
||||||
value = eval("props.%s" % pname)
|
|
||||||
value = _string_value(value)
|
|
||||||
if value != "":
|
|
||||||
s.append("kmi.properties.%s = %s\n" % (pname, value))
|
|
||||||
|
|
||||||
return "".join(s).strip()
|
return "".join(s).strip()
|
||||||
|
|
||||||
@@ -1443,6 +1470,9 @@ class WM_OT_keyconfig_export(bpy.types.Operator):
|
|||||||
bl_label = "Export Key Configuration..."
|
bl_label = "Export Key Configuration..."
|
||||||
|
|
||||||
path = bpy.props.StringProperty(name="File Path", description="File path to write file to.")
|
path = bpy.props.StringProperty(name="File Path", description="File path to write file to.")
|
||||||
|
filter_folder = bpy.props.BoolProperty(name="Filter folders", description="", default=True)
|
||||||
|
filter_text = bpy.props.BoolProperty(name="Filter text", description="", default=True)
|
||||||
|
filter_python = bpy.props.BoolProperty(name="Filter python", description="", default=True)
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
if not self.properties.path:
|
if not self.properties.path:
|
||||||
@@ -1455,10 +1485,15 @@ class WM_OT_keyconfig_export(bpy.types.Operator):
|
|||||||
wm = context.manager
|
wm = context.manager
|
||||||
kc = wm.active_keyconfig
|
kc = wm.active_keyconfig
|
||||||
|
|
||||||
f.write('# Configuration %s\n' % kc.name)
|
if kc.name == 'Blender':
|
||||||
|
name = os.path.splitext(os.path.basename(self.properties.path))[0]
|
||||||
|
else:
|
||||||
|
name = kc.name
|
||||||
|
|
||||||
f.write("wm = bpy.data.windowmanagers[0]\n")
|
f.write('# Configuration %s\n' % name)
|
||||||
f.write("kc = wm.add_keyconfig(\'%s\')\n\n" % kc.name)
|
|
||||||
|
f.write("wm = bpy.data.window_managers[0]\n")
|
||||||
|
f.write("kc = wm.add_keyconfig(\'%s\')\n\n" % name)
|
||||||
|
|
||||||
for km in kc.keymaps:
|
for km in kc.keymaps:
|
||||||
km = km.active()
|
km = km.active()
|
||||||
@@ -1484,18 +1519,25 @@ class WM_OT_keyconfig_export(bpy.types.Operator):
|
|||||||
f.write(", key_modifier=\'%s\'" % kmi.key_modifier)
|
f.write(", key_modifier=\'%s\'" % kmi.key_modifier)
|
||||||
f.write(")\n")
|
f.write(")\n")
|
||||||
|
|
||||||
|
def export_properties(prefix, properties):
|
||||||
|
for pname in dir(properties):
|
||||||
|
if not properties.is_property_hidden(pname):
|
||||||
|
value = eval("properties.%s" % pname)
|
||||||
|
if isinstance(value, bpy.types.OperatorProperties):
|
||||||
|
export_properties(prefix + "." + pname, value)
|
||||||
|
elif properties.is_property_set(pname):
|
||||||
|
value = _string_value(value)
|
||||||
|
if value != "":
|
||||||
|
f.write(prefix + ".%s = %s\n" % (pname, value))
|
||||||
|
|
||||||
props = kmi.properties
|
props = kmi.properties
|
||||||
|
|
||||||
if props is not None:
|
if props is not None:
|
||||||
for pname in dir(props):
|
export_properties("kmi.properties", props)
|
||||||
if props.is_property_set(pname) and not props.is_property_hidden(pname):
|
|
||||||
value = eval("props.%s" % pname)
|
|
||||||
value = _string_value(value)
|
|
||||||
if value != "":
|
|
||||||
f.write("kmi.properties.%s = %s\n" % (pname, value))
|
|
||||||
|
|
||||||
f.write("\n")
|
f.write("\n")
|
||||||
|
|
||||||
|
f.write("wm.active_keyconfig = wm.keyconfigs[\'%s\']\n" % name)
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|||||||
@@ -419,6 +419,9 @@ class VIEW3D_MT_select_pose(bpy.types.Menu):
|
|||||||
props.extend = True
|
props.extend = True
|
||||||
props.direction = 'CHILD'
|
props.direction = 'CHILD'
|
||||||
|
|
||||||
|
layout.separator()
|
||||||
|
|
||||||
|
layout.operator_menu_enum("pose.select_grouped", "type", text="Grouped")
|
||||||
layout.operator("object.select_pattern", text="Select Pattern...")
|
layout.operator("object.select_pattern", text="Select Pattern...")
|
||||||
|
|
||||||
|
|
||||||
@@ -987,6 +990,8 @@ class VIEW3D_MT_pose(bpy.types.Menu):
|
|||||||
layout.operator("pose.autoside_names", text="AutoName Top/Bottom").axis = 'ZAXIS'
|
layout.operator("pose.autoside_names", text="AutoName Top/Bottom").axis = 'ZAXIS'
|
||||||
|
|
||||||
layout.operator("pose.flip_names")
|
layout.operator("pose.flip_names")
|
||||||
|
|
||||||
|
layout.operator("pose.quaternions_flip")
|
||||||
|
|
||||||
layout.separator()
|
layout.separator()
|
||||||
|
|
||||||
@@ -1783,7 +1788,7 @@ class VIEW3D_PT_3dview_curvedisplay(bpy.types.Panel):
|
|||||||
class VIEW3D_PT_background_image(bpy.types.Panel):
|
class VIEW3D_PT_background_image(bpy.types.Panel):
|
||||||
bl_space_type = 'VIEW_3D'
|
bl_space_type = 'VIEW_3D'
|
||||||
bl_region_type = 'UI'
|
bl_region_type = 'UI'
|
||||||
bl_label = "Background Image"
|
bl_label = "Background Images"
|
||||||
bl_default_closed = True
|
bl_default_closed = True
|
||||||
|
|
||||||
def poll(self, context):
|
def poll(self, context):
|
||||||
@@ -1795,34 +1800,38 @@ class VIEW3D_PT_background_image(bpy.types.Panel):
|
|||||||
layout = self.layout
|
layout = self.layout
|
||||||
view = context.space_data
|
view = context.space_data
|
||||||
|
|
||||||
layout.prop(view, "display_background_image", text="")
|
layout.prop(view, "display_background_images", text="")
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
layout = self.layout
|
layout = self.layout
|
||||||
|
|
||||||
view = context.space_data
|
view = context.space_data
|
||||||
bg = view.background_image
|
|
||||||
|
col = layout.column()
|
||||||
|
col.operator("view3d.add_background_image", text="Add Image")
|
||||||
|
|
||||||
if bg:
|
for i, bg in enumerate(view.background_images):
|
||||||
layout.active = view.display_background_image
|
layout.active = view.display_background_images
|
||||||
box = layout.box()
|
box = layout.box()
|
||||||
if (bg.image):
|
row = box.row(align=True)
|
||||||
box.template_ID(bg, "image", open="image.open")
|
row.prop(bg, "show_expanded", text="", no_bg=True)
|
||||||
box.template_image(bg, "image", bg.image_user, compact=True)
|
row.label(text=getattr(bg.image, "name", "Not Set"))
|
||||||
else:
|
row.operator("view3d.remove_background_image", text="", icon='X').index = i
|
||||||
box.template_ID(bg, "image", open="image.open")
|
|
||||||
|
|
||||||
col = layout.column()
|
box.prop(bg, "view_axis", text="Axis")
|
||||||
col.label(text="Display Settings")
|
|
||||||
|
|
||||||
col = layout.column()
|
if bg.show_expanded:
|
||||||
col.prop(bg, "size")
|
row = box.row()
|
||||||
col.prop(bg, "transparency", slider=True)
|
row.template_ID(bg, "image", open="image.open")
|
||||||
|
if (bg.image):
|
||||||
|
box.template_image(bg, "image", bg.image_user, compact=True)
|
||||||
|
|
||||||
col = layout.column()
|
box.prop(bg, "transparency", slider=True)
|
||||||
col.label(text="Offset")
|
box.prop(bg, "size")
|
||||||
col.prop(bg, "offset_x", text="X")
|
row = box.row(align=True)
|
||||||
col.prop(bg, "offset_y", text="Y")
|
row.prop(bg, "offset_x", text="X")
|
||||||
|
row.prop(bg, "offset_y", text="Y")
|
||||||
|
|
||||||
|
|
||||||
class VIEW3D_PT_transform_orientations(bpy.types.Panel):
|
class VIEW3D_PT_transform_orientations(bpy.types.Panel):
|
||||||
bl_space_type = 'VIEW_3D'
|
bl_space_type = 'VIEW_3D'
|
||||||
|
|||||||
@@ -500,13 +500,13 @@ class VIEW3D_PT_tools_brush(PaintPanel):
|
|||||||
row = col.row()
|
row = col.row()
|
||||||
|
|
||||||
if context.sculpt_object and brush:
|
if context.sculpt_object and brush:
|
||||||
defaulttools = 8
|
defaultbrushes = 8
|
||||||
elif context.texture_paint_object and brush:
|
elif context.texture_paint_object and brush:
|
||||||
defaulttools = 4
|
defaultbrushes = 4
|
||||||
else:
|
else:
|
||||||
defaulttools = 2
|
defaultbrushes = 7
|
||||||
|
|
||||||
row.template_list(settings, "brushes", settings, "active_brush_index", rows=2, maxrows=defaulttools)
|
row.template_list(settings, "brushes", settings, "active_brush_index", rows=2, maxrows=defaultbrushes)
|
||||||
|
|
||||||
col.template_ID(settings, "brush", new="brush.add")
|
col.template_ID(settings, "brush", new="brush.add")
|
||||||
|
|
||||||
@@ -657,8 +657,9 @@ class VIEW3D_PT_tools_brush_tool(PaintPanel):
|
|||||||
|
|
||||||
def poll(self, context):
|
def poll(self, context):
|
||||||
settings = self.paint_settings(context)
|
settings = self.paint_settings(context)
|
||||||
return (settings and settings.brush and (context.sculpt_object or
|
return (settings and settings.brush and
|
||||||
context.texture_paint_object))
|
(context.sculpt_object or context.texture_paint_object or
|
||||||
|
context.vertex_paint_object or context.weight_paint_object))
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
layout = self.layout
|
layout = self.layout
|
||||||
@@ -673,10 +674,13 @@ class VIEW3D_PT_tools_brush_tool(PaintPanel):
|
|||||||
if context.sculpt_object:
|
if context.sculpt_object:
|
||||||
col.prop(brush, "sculpt_tool", expand=True)
|
col.prop(brush, "sculpt_tool", expand=True)
|
||||||
elif context.texture_paint_object:
|
elif context.texture_paint_object:
|
||||||
col.prop_enum(settings, "tool", 'DRAW')
|
col.prop(brush, "imagepaint_tool", expand=True)
|
||||||
col.prop_enum(settings, "tool", 'SOFTEN')
|
#col.prop_enum(settings, "tool", 'DRAW')
|
||||||
col.prop_enum(settings, "tool", 'CLONE')
|
#col.prop_enum(settings, "tool", 'SOFTEN')
|
||||||
col.prop_enum(settings, "tool", 'SMEAR')
|
#col.prop_enum(settings, "tool", 'CLONE')
|
||||||
|
#col.prop_enum(settings, "tool", 'SMEAR')
|
||||||
|
elif context.vertex_paint_object or context.weight_paint_object:
|
||||||
|
col.prop(brush, "vertexpaint_tool", expand=True)
|
||||||
|
|
||||||
|
|
||||||
class VIEW3D_PT_tools_brush_stroke(PaintPanel):
|
class VIEW3D_PT_tools_brush_stroke(PaintPanel):
|
||||||
@@ -780,7 +784,6 @@ class VIEW3D_PT_tools_weightpaint(View3DPanel):
|
|||||||
layout = self.layout
|
layout = self.layout
|
||||||
|
|
||||||
col = layout.column()
|
col = layout.column()
|
||||||
# col.label(text="Blend:")
|
|
||||||
col.operator("object.vertex_group_normalize_all", text="Normalize All")
|
col.operator("object.vertex_group_normalize_all", text="Normalize All")
|
||||||
col.operator("object.vertex_group_normalize", text="Normalize")
|
col.operator("object.vertex_group_normalize", text="Normalize")
|
||||||
col.operator("object.vertex_group_invert", text="Invert")
|
col.operator("object.vertex_group_invert", text="Invert")
|
||||||
@@ -798,8 +801,6 @@ class VIEW3D_PT_tools_weightpaint_options(View3DPanel):
|
|||||||
wpaint = context.tool_settings.weight_paint
|
wpaint = context.tool_settings.weight_paint
|
||||||
|
|
||||||
col = layout.column()
|
col = layout.column()
|
||||||
col.label(text="Blend:")
|
|
||||||
col.prop(wpaint, "mode", text="")
|
|
||||||
col.prop(wpaint, "all_faces")
|
col.prop(wpaint, "all_faces")
|
||||||
col.prop(wpaint, "normals")
|
col.prop(wpaint, "normals")
|
||||||
col.prop(wpaint, "spray")
|
col.prop(wpaint, "spray")
|
||||||
@@ -830,8 +831,7 @@ class VIEW3D_PT_tools_vertexpaint(View3DPanel):
|
|||||||
vpaint = context.tool_settings.vertex_paint
|
vpaint = context.tool_settings.vertex_paint
|
||||||
|
|
||||||
col = layout.column()
|
col = layout.column()
|
||||||
col.label(text="Blend:")
|
#col.prop(vpaint, "mode", text="")
|
||||||
col.prop(vpaint, "mode", text="")
|
|
||||||
col.prop(vpaint, "all_faces")
|
col.prop(vpaint, "all_faces")
|
||||||
col.prop(vpaint, "normals")
|
col.prop(vpaint, "normals")
|
||||||
col.prop(vpaint, "spray")
|
col.prop(vpaint, "spray")
|
||||||
@@ -850,7 +850,7 @@ class VIEW3D_PT_tools_projectpaint(View3DPanel):
|
|||||||
bl_label = "Project Paint"
|
bl_label = "Project Paint"
|
||||||
|
|
||||||
def poll(self, context):
|
def poll(self, context):
|
||||||
return context.tool_settings.image_paint.tool != 'SMEAR'
|
return context.tool_settings.image_paint.brush.imagepaint_tool != 'SMEAR'
|
||||||
|
|
||||||
def draw_header(self, context):
|
def draw_header(self, context):
|
||||||
ipaint = context.tool_settings.image_paint
|
ipaint = context.tool_settings.image_paint
|
||||||
@@ -893,7 +893,7 @@ class VIEW3D_PT_tools_projectpaint(View3DPanel):
|
|||||||
col = layout.column()
|
col = layout.column()
|
||||||
sub = col.column()
|
sub = col.column()
|
||||||
row = sub.row()
|
row = sub.row()
|
||||||
row.active = (settings.tool == 'CLONE')
|
row.active = (settings.brush.imagepaint_tool == 'CLONE')
|
||||||
|
|
||||||
row.prop(ipaint, "use_clone_layer", text="Clone")
|
row.prop(ipaint, "use_clone_layer", text="Clone")
|
||||||
row.menu("VIEW3D_MT_tools_projectpaint_clone", text=context.active_object.data.uv_texture_clone.name)
|
row.menu("VIEW3D_MT_tools_projectpaint_clone", text=context.active_object.data.uv_texture_clone.name)
|
||||||
|
|||||||
@@ -96,7 +96,6 @@ COMLIB += $(OCGDIR)/blender/nodes_cmp/$(DEBUG_DIR)libnodes_cmp.a
|
|||||||
COMLIB += $(OCGDIR)/blender/nodes_tex/$(DEBUG_DIR)libnodes_tex.a
|
COMLIB += $(OCGDIR)/blender/nodes_tex/$(DEBUG_DIR)libnodes_tex.a
|
||||||
COMLIB += $(OCGDIR)/blender/nodes/$(DEBUG_DIR)libnodes.a
|
COMLIB += $(OCGDIR)/blender/nodes/$(DEBUG_DIR)libnodes.a
|
||||||
COMLIB += $(OCGDIR)/blender/imbuf/$(DEBUG_DIR)libimbuf.a
|
COMLIB += $(OCGDIR)/blender/imbuf/$(DEBUG_DIR)libimbuf.a
|
||||||
COMLIB += $(OCGDIR)/blender/blenlib/$(DEBUG_DIR)libblenlib.a
|
|
||||||
COMLIB += $(OCGDIR)/blender/ikplugin/$(DEBUG_DIR)libikplugin.a
|
COMLIB += $(OCGDIR)/blender/ikplugin/$(DEBUG_DIR)libikplugin.a
|
||||||
COMLIB += $(NAN_IKSOLVER)/lib/$(DEBUG_DIR)libiksolver.a
|
COMLIB += $(NAN_IKSOLVER)/lib/$(DEBUG_DIR)libiksolver.a
|
||||||
COMLIB += $(NAN_ITASC)/lib/$(DEBUG_DIR)libitasc.a
|
COMLIB += $(NAN_ITASC)/lib/$(DEBUG_DIR)libitasc.a
|
||||||
@@ -184,6 +183,8 @@ COMLIB += $(NAN_MEMUTIL)/lib/libmemutil.a
|
|||||||
COMLIB += $(NAN_PNG)/lib/libpng.a
|
COMLIB += $(NAN_PNG)/lib/libpng.a
|
||||||
COMLIB += $(OCGDIR)/blender/python/$(DEBUG_DIR)libpython.a # This was a PULIB up to circa r25248
|
COMLIB += $(OCGDIR)/blender/python/$(DEBUG_DIR)libpython.a # This was a PULIB up to circa r25248
|
||||||
COMLIB += $(OCGDIR)/blender/gen_python/$(DEBUG_DIR)libgen_python.a
|
COMLIB += $(OCGDIR)/blender/gen_python/$(DEBUG_DIR)libgen_python.a
|
||||||
|
COMLIB += $(OCGDIR)/blender/blenlib/$(DEBUG_DIR)libblenlib.a
|
||||||
|
|
||||||
|
|
||||||
ifeq ($(WITH_QUICKTIME), true)
|
ifeq ($(WITH_QUICKTIME), true)
|
||||||
COMLIB += $(OCGDIR)/blender/blenderqt/$(DEBUG_DIR)libblenderqt.a
|
COMLIB += $(OCGDIR)/blender/blenderqt/$(DEBUG_DIR)libblenderqt.a
|
||||||
|
|||||||
@@ -502,8 +502,8 @@ void makeDerivedMesh(struct Scene *scene, struct Object *ob, struct EditMesh *em
|
|||||||
|
|
||||||
/* returns an array of deform matrices for crazyspace correction, and the
|
/* returns an array of deform matrices for crazyspace correction, and the
|
||||||
number of modifiers left */
|
number of modifiers left */
|
||||||
int editmesh_get_first_deform_matrices(struct Object *, struct EditMesh *em, float (**deformmats)[3][3],
|
int editmesh_get_first_deform_matrices(struct Scene *, struct Object *, struct EditMesh *em,
|
||||||
float (**deformcos)[3]);
|
float (**deformmats)[3][3], float (**deformcos)[3]);
|
||||||
|
|
||||||
void weight_to_rgb(float input, float *fr, float *fg, float *fb);
|
void weight_to_rgb(float input, float *fr, float *fg, float *fb);
|
||||||
|
|
||||||
|
|||||||
@@ -53,7 +53,9 @@ void animviz_free_motionpath_cache(struct bMotionPath *mpath);
|
|||||||
void animviz_free_motionpath(struct bMotionPath *mpath);
|
void animviz_free_motionpath(struct bMotionPath *mpath);
|
||||||
|
|
||||||
struct bMotionPath *animviz_verify_motionpaths(struct Scene *scene, struct Object *ob, struct bPoseChannel *pchan);
|
struct bMotionPath *animviz_verify_motionpaths(struct Scene *scene, struct Object *ob, struct bPoseChannel *pchan);
|
||||||
void animviz_calc_motionpaths(struct Scene *scene, struct Object *ob);
|
|
||||||
|
void animviz_get_object_motionpaths(Object *ob, ListBase *targets);
|
||||||
|
void animviz_calc_motionpaths(struct Scene *scene, ListBase *targets);
|
||||||
|
|
||||||
/* ---------------------------------------------------- */
|
/* ---------------------------------------------------- */
|
||||||
/* Curve Paths */
|
/* Curve Paths */
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ struct bContext;
|
|||||||
struct ReportList;
|
struct ReportList;
|
||||||
|
|
||||||
#define BLENDER_VERSION 250
|
#define BLENDER_VERSION 250
|
||||||
#define BLENDER_SUBVERSION 11
|
#define BLENDER_SUBVERSION 13
|
||||||
|
|
||||||
#define BLENDER_MINVERSION 250
|
#define BLENDER_MINVERSION 250
|
||||||
#define BLENDER_MINSUBVERSION 0
|
#define BLENDER_MINSUBVERSION 0
|
||||||
@@ -62,12 +62,6 @@ void BKE_userdef_free(void);
|
|||||||
void set_blender_test_break_cb(void (*func)(void) );
|
void set_blender_test_break_cb(void (*func)(void) );
|
||||||
int blender_test_break(void);
|
int blender_test_break(void);
|
||||||
|
|
||||||
void pushdata(void *data, int len);
|
|
||||||
void popfirst(void *data);
|
|
||||||
void poplast(void *data);
|
|
||||||
void free_pushpop(void);
|
|
||||||
void pushpop_test(void);
|
|
||||||
|
|
||||||
/* global undo */
|
/* global undo */
|
||||||
extern void BKE_write_undo(struct bContext *C, char *name);
|
extern void BKE_write_undo(struct bContext *C, char *name);
|
||||||
extern void BKE_undo_step(struct bContext *C, int step);
|
extern void BKE_undo_step(struct bContext *C, int step);
|
||||||
|
|||||||
@@ -31,9 +31,20 @@
|
|||||||
|
|
||||||
struct CurveMapping;
|
struct CurveMapping;
|
||||||
struct CurveMap;
|
struct CurveMap;
|
||||||
|
struct Histogram;
|
||||||
struct ImBuf;
|
struct ImBuf;
|
||||||
struct rctf;
|
struct rctf;
|
||||||
|
|
||||||
|
#if defined _WIN32
|
||||||
|
# define DO_INLINE __inline
|
||||||
|
#elif defined (__sgi)
|
||||||
|
# define DO_INLINE
|
||||||
|
#elif defined (__sun) || defined (__sun__)
|
||||||
|
# define DO_INLINE
|
||||||
|
#else
|
||||||
|
# define DO_INLINE static inline
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef enum CurveMappingPreset {
|
typedef enum CurveMappingPreset {
|
||||||
CURVE_PRESET_LINE,
|
CURVE_PRESET_LINE,
|
||||||
CURVE_PRESET_SHARP,
|
CURVE_PRESET_SHARP,
|
||||||
@@ -70,6 +81,7 @@ void curvemapping_initialize(struct CurveMapping *cumap);
|
|||||||
void curvemapping_table_RGBA(struct CurveMapping *cumap, float **array, int *size);
|
void curvemapping_table_RGBA(struct CurveMapping *cumap, float **array, int *size);
|
||||||
void colorcorrection_do_ibuf(struct ImBuf *ibuf, const char *profile);
|
void colorcorrection_do_ibuf(struct ImBuf *ibuf, const char *profile);
|
||||||
|
|
||||||
|
void histogram_update(struct Histogram *hist, struct ImBuf *ibuf);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ struct Image *BKE_image_verify_viewer(int type, const char *name);
|
|||||||
void BKE_image_assign_ibuf(struct Image *ima, struct ImBuf *ibuf);
|
void BKE_image_assign_ibuf(struct Image *ima, struct ImBuf *ibuf);
|
||||||
|
|
||||||
/* called on frame change or before render */
|
/* called on frame change or before render */
|
||||||
void BKE_image_user_calc_imanr(struct ImageUser *iuser, int cfra, int fieldnr);
|
void BKE_image_user_calc_frame(struct ImageUser *iuser, int cfra, int fieldnr);
|
||||||
|
|
||||||
/* produce image export path */
|
/* produce image export path */
|
||||||
int BKE_get_image_export_path(struct Image *im, const char *dest_dir, char *abs, int abs_size, char *rel, int rel_size);
|
int BKE_get_image_export_path(struct Image *im, const char *dest_dir, char *abs, int abs_size, char *rel, int rel_size);
|
||||||
|
|||||||
@@ -279,10 +279,10 @@ void modifier_unique_name(struct ListBase *modifiers, struct ModifierData *m
|
|||||||
void modifier_copyData(struct ModifierData *md, struct ModifierData *target);
|
void modifier_copyData(struct ModifierData *md, struct ModifierData *target);
|
||||||
int modifier_dependsOnTime(struct ModifierData *md);
|
int modifier_dependsOnTime(struct ModifierData *md);
|
||||||
int modifier_supportsMapping(struct ModifierData *md);
|
int modifier_supportsMapping(struct ModifierData *md);
|
||||||
int modifier_couldBeCage(struct ModifierData *md);
|
int modifier_couldBeCage(struct Scene *scene, struct ModifierData *md);
|
||||||
int modifier_isCorrectableDeformed(struct ModifierData *md);
|
int modifier_isCorrectableDeformed(struct ModifierData *md);
|
||||||
int modifier_sameTopology(ModifierData *md);
|
int modifier_sameTopology(ModifierData *md);
|
||||||
int modifier_isEnabled(struct ModifierData *md, int required_mode);
|
int modifier_isEnabled(struct Scene *scene, struct ModifierData *md, int required_mode);
|
||||||
void modifier_setError(struct ModifierData *md, char *format, ...);
|
void modifier_setError(struct ModifierData *md, char *format, ...);
|
||||||
|
|
||||||
void modifiers_foreachObjectLink(struct Object *ob,
|
void modifiers_foreachObjectLink(struct Object *ob,
|
||||||
@@ -293,7 +293,7 @@ void modifiers_foreachIDLink(struct Object *ob,
|
|||||||
void *userData);
|
void *userData);
|
||||||
struct ModifierData *modifiers_findByType(struct Object *ob, ModifierType type);
|
struct ModifierData *modifiers_findByType(struct Object *ob, ModifierType type);
|
||||||
void modifiers_clearErrors(struct Object *ob);
|
void modifiers_clearErrors(struct Object *ob);
|
||||||
int modifiers_getCageIndex(struct Object *ob,
|
int modifiers_getCageIndex(struct Scene *scene, struct Object *ob,
|
||||||
int *lastPossibleCageIndex_r, int virtual_);
|
int *lastPossibleCageIndex_r, int virtual_);
|
||||||
|
|
||||||
int modifiers_isSoftbodyEnabled(struct Object *ob);
|
int modifiers_isSoftbodyEnabled(struct Object *ob);
|
||||||
@@ -313,7 +313,8 @@ int modifiers_indexInObject(struct Object *ob, struct ModifierData *md
|
|||||||
* evaluation, assuming the data indicated by dataMask is required at the
|
* evaluation, assuming the data indicated by dataMask is required at the
|
||||||
* end of the stack.
|
* end of the stack.
|
||||||
*/
|
*/
|
||||||
struct LinkNode *modifiers_calcDataMasks(struct Object *ob,
|
struct LinkNode *modifiers_calcDataMasks(struct Scene *scene,
|
||||||
|
struct Object *ob,
|
||||||
struct ModifierData *md,
|
struct ModifierData *md,
|
||||||
CustomDataMask dataMask,
|
CustomDataMask dataMask,
|
||||||
int required_mode);
|
int required_mode);
|
||||||
|
|||||||
@@ -83,6 +83,7 @@ struct NlaStrip *BKE_nlastrip_find_active(struct NlaTrack *nlt);
|
|||||||
void BKE_nlastrip_set_active(struct AnimData *adt, struct NlaStrip *strip);
|
void BKE_nlastrip_set_active(struct AnimData *adt, struct NlaStrip *strip);
|
||||||
|
|
||||||
short BKE_nlastrip_within_bounds(struct NlaStrip *strip, float min, float max);
|
short BKE_nlastrip_within_bounds(struct NlaStrip *strip, float min, float max);
|
||||||
|
void BKE_nlastrip_recalculate_bounds(struct NlaStrip *strip);
|
||||||
|
|
||||||
void BKE_nlastrip_validate_name(struct AnimData *adt, struct NlaStrip *strip);
|
void BKE_nlastrip_validate_name(struct AnimData *adt, struct NlaStrip *strip);
|
||||||
|
|
||||||
|
|||||||
@@ -354,6 +354,8 @@ void ntreeGPUMaterialNodes(struct bNodeTree *ntree, struct GPUMaterial *mat);
|
|||||||
#define CMP_NODE_DIST_MATTE 257
|
#define CMP_NODE_DIST_MATTE 257
|
||||||
#define CMP_NODE_VIEW_LEVELS 258
|
#define CMP_NODE_VIEW_LEVELS 258
|
||||||
#define CMP_NODE_COLOR_MATTE 259
|
#define CMP_NODE_COLOR_MATTE 259
|
||||||
|
#define CMP_NODE_COLORBALANCE 260
|
||||||
|
#define CMP_NODE_HUECORRECT 261
|
||||||
|
|
||||||
#define CMP_NODE_GLARE 301
|
#define CMP_NODE_GLARE 301
|
||||||
#define CMP_NODE_TONEMAP 302
|
#define CMP_NODE_TONEMAP 302
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ void object_link_modifiers(struct Object *ob, struct Object *from);
|
|||||||
void object_free_modifiers(struct Object *ob);
|
void object_free_modifiers(struct Object *ob);
|
||||||
|
|
||||||
void object_make_proxy(struct Object *ob, struct Object *target, struct Object *gob);
|
void object_make_proxy(struct Object *ob, struct Object *target, struct Object *gob);
|
||||||
|
void object_copy_proxy_drivers(struct Object *ob, struct Object *target);
|
||||||
|
|
||||||
void unlink_object(struct Scene *scene, struct Object *ob);
|
void unlink_object(struct Scene *scene, struct Object *ob);
|
||||||
int exist_object(struct Object *obtest);
|
int exist_object(struct Object *obtest);
|
||||||
|
|||||||
@@ -28,8 +28,8 @@
|
|||||||
* ***** END GPL LICENSE BLOCK *****
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef BKE_SEQUENCE_H
|
#ifndef BKE_SEQUENCER_H
|
||||||
#define BKE_SEQUENCE_H
|
#define BKE_SEQUENCER_H
|
||||||
|
|
||||||
struct Editing;
|
struct Editing;
|
||||||
struct Sequence;
|
struct Sequence;
|
||||||
@@ -77,8 +77,6 @@ void seq_array(struct Editing *ed, struct Sequence ***seqarray, int *tot, int us
|
|||||||
seq_end(&iter); \
|
seq_end(&iter); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* Wipe effect */
|
/* Wipe effect */
|
||||||
enum {DO_SINGLE_WIPE, DO_DOUBLE_WIPE, DO_BOX_WIPE, DO_CROSS_WIPE,
|
enum {DO_SINGLE_WIPE, DO_DOUBLE_WIPE, DO_BOX_WIPE, DO_CROSS_WIPE,
|
||||||
@@ -238,3 +236,5 @@ struct Sequence *sequencer_add_movie_strip(struct bContext *C, ListBase *seqbase
|
|||||||
/* copy/paste */
|
/* copy/paste */
|
||||||
extern ListBase seqbase_clipboard;
|
extern ListBase seqbase_clipboard;
|
||||||
extern int seqbase_clipboard_frame;
|
extern int seqbase_clipboard_frame;
|
||||||
|
|
||||||
|
#endif // BKE_SEQUENCER_H
|
||||||
|
|||||||
@@ -262,3 +262,11 @@ behaviour, though it may not be the best in practice.
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*little macro so inline keyword works*/
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#define BM_INLINE static __forceinline
|
||||||
|
#else
|
||||||
|
#define BM_INLINE static inline __attribute((always_inline))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define BMEMSET(mem, val, size) {unsigned int _i; char *_c = (char*) mem; for (_i=0; _i<size; _i++) *_c++ = val;}
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ void BME_CD_Create(BME_CustomData *data, BME_CustomDataInit *init, int initalloc
|
|||||||
if(data->totlayer){
|
if(data->totlayer){
|
||||||
/*alloc memory*/
|
/*alloc memory*/
|
||||||
data->layers = MEM_callocN(sizeof(BME_CustomDataLayer)*data->totlayer, "BMesh Custom Data Layers");
|
data->layers = MEM_callocN(sizeof(BME_CustomDataLayer)*data->totlayer, "BMesh Custom Data Layers");
|
||||||
data->pool = BLI_mempool_create(data->totsize, initalloc, initalloc);
|
data->pool = BLI_mempool_create(data->totsize, initalloc, initalloc, 0);
|
||||||
/*initialize layer data*/
|
/*initialize layer data*/
|
||||||
for(i=0; i < BME_CD_NUMTYPES; i++){
|
for(i=0; i < BME_CD_NUMTYPES; i++){
|
||||||
if(init->layout[i]){
|
if(init->layout[i]){
|
||||||
|
|||||||
@@ -55,10 +55,10 @@ BME_Mesh *BME_make_mesh(int allocsize[4])
|
|||||||
/*allocate the structure*/
|
/*allocate the structure*/
|
||||||
BME_Mesh *bm = MEM_callocN(sizeof(BME_Mesh),"BMesh");
|
BME_Mesh *bm = MEM_callocN(sizeof(BME_Mesh),"BMesh");
|
||||||
/*allocate the memory pools for the mesh elements*/
|
/*allocate the memory pools for the mesh elements*/
|
||||||
bm->vpool = BLI_mempool_create(sizeof(BME_Vert), allocsize[0], allocsize[0]);
|
bm->vpool = BLI_mempool_create(sizeof(BME_Vert), allocsize[0], allocsize[0], 0);
|
||||||
bm->epool = BLI_mempool_create(sizeof(BME_Edge), allocsize[1], allocsize[1]);
|
bm->epool = BLI_mempool_create(sizeof(BME_Edge), allocsize[1], allocsize[1], 0);
|
||||||
bm->lpool = BLI_mempool_create(sizeof(BME_Loop), allocsize[2], allocsize[2]);
|
bm->lpool = BLI_mempool_create(sizeof(BME_Loop), allocsize[2], allocsize[2], 0);
|
||||||
bm->ppool = BLI_mempool_create(sizeof(BME_Poly), allocsize[3], allocsize[3]);
|
bm->ppool = BLI_mempool_create(sizeof(BME_Poly), allocsize[3], allocsize[3], 0);
|
||||||
return bm;
|
return bm;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -1643,7 +1643,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
|
|||||||
/* we always want to keep original indices */
|
/* we always want to keep original indices */
|
||||||
dataMask |= CD_MASK_ORIGINDEX;
|
dataMask |= CD_MASK_ORIGINDEX;
|
||||||
|
|
||||||
datamasks = modifiers_calcDataMasks(ob, md, dataMask, required_mode);
|
datamasks = modifiers_calcDataMasks(scene, ob, md, dataMask, required_mode);
|
||||||
curr = datamasks;
|
curr = datamasks;
|
||||||
|
|
||||||
if(deform_r) *deform_r = NULL;
|
if(deform_r) *deform_r = NULL;
|
||||||
@@ -1659,7 +1659,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
|
|||||||
|
|
||||||
md->scene= scene;
|
md->scene= scene;
|
||||||
|
|
||||||
if(!modifier_isEnabled(md, required_mode)) continue;
|
if(!modifier_isEnabled(scene, md, required_mode)) continue;
|
||||||
if(useDeform < 0 && mti->dependsOnTime && mti->dependsOnTime(md)) continue;
|
if(useDeform < 0 && mti->dependsOnTime && mti->dependsOnTime(md)) continue;
|
||||||
|
|
||||||
if(mti->type == eModifierTypeType_OnlyDeform) {
|
if(mti->type == eModifierTypeType_OnlyDeform) {
|
||||||
@@ -1708,7 +1708,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
|
|||||||
|
|
||||||
md->scene= scene;
|
md->scene= scene;
|
||||||
|
|
||||||
if(!modifier_isEnabled(md, required_mode)) continue;
|
if(!modifier_isEnabled(scene, md, required_mode)) continue;
|
||||||
if(mti->type == eModifierTypeType_OnlyDeform && !useDeform) continue;
|
if(mti->type == eModifierTypeType_OnlyDeform && !useDeform) continue;
|
||||||
if((mti->flags & eModifierTypeFlag_RequiresOriginalData) && dm) {
|
if((mti->flags & eModifierTypeFlag_RequiresOriginalData) && dm) {
|
||||||
modifier_setError(md, "Modifier requires original data, bad stack position.");
|
modifier_setError(md, "Modifier requires original data, bad stack position.");
|
||||||
@@ -1884,12 +1884,12 @@ static float (*editmesh_getVertexCos(EditMesh *em, int *numVerts_r))[3]
|
|||||||
return cos;
|
return cos;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int editmesh_modifier_is_enabled(ModifierData *md, DerivedMesh *dm)
|
static int editmesh_modifier_is_enabled(Scene *scene, ModifierData *md, DerivedMesh *dm)
|
||||||
{
|
{
|
||||||
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
|
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
|
||||||
int required_mode = eModifierMode_Realtime | eModifierMode_Editmode;
|
int required_mode = eModifierMode_Realtime | eModifierMode_Editmode;
|
||||||
|
|
||||||
if(!modifier_isEnabled(md, required_mode)) return 0;
|
if(!modifier_isEnabled(scene, md, required_mode)) return 0;
|
||||||
if((mti->flags & eModifierTypeFlag_RequiresOriginalData) && dm) {
|
if((mti->flags & eModifierTypeFlag_RequiresOriginalData) && dm) {
|
||||||
modifier_setError(md, "Modifier requires original data, bad stack position.");
|
modifier_setError(md, "Modifier requires original data, bad stack position.");
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1906,7 +1906,7 @@ static void editmesh_calc_modifiers(Scene *scene, Object *ob, EditMesh *em, Deri
|
|||||||
float (*deformedVerts)[3] = NULL;
|
float (*deformedVerts)[3] = NULL;
|
||||||
CustomDataMask mask;
|
CustomDataMask mask;
|
||||||
DerivedMesh *dm, *orcodm = NULL;
|
DerivedMesh *dm, *orcodm = NULL;
|
||||||
int i, numVerts = 0, cageIndex = modifiers_getCageIndex(ob, NULL, 1);
|
int i, numVerts = 0, cageIndex = modifiers_getCageIndex(scene, ob, NULL, 1);
|
||||||
LinkNode *datamasks, *curr;
|
LinkNode *datamasks, *curr;
|
||||||
int required_mode = eModifierMode_Realtime | eModifierMode_Editmode;
|
int required_mode = eModifierMode_Realtime | eModifierMode_Editmode;
|
||||||
|
|
||||||
@@ -1922,7 +1922,7 @@ static void editmesh_calc_modifiers(Scene *scene, Object *ob, EditMesh *em, Deri
|
|||||||
/* we always want to keep original indices */
|
/* we always want to keep original indices */
|
||||||
dataMask |= CD_MASK_ORIGINDEX;
|
dataMask |= CD_MASK_ORIGINDEX;
|
||||||
|
|
||||||
datamasks = modifiers_calcDataMasks(ob, md, dataMask, required_mode);
|
datamasks = modifiers_calcDataMasks(scene, ob, md, dataMask, required_mode);
|
||||||
|
|
||||||
curr = datamasks;
|
curr = datamasks;
|
||||||
for(i = 0; md; i++, md = md->next, curr = curr->next) {
|
for(i = 0; md; i++, md = md->next, curr = curr->next) {
|
||||||
@@ -1930,7 +1930,7 @@ static void editmesh_calc_modifiers(Scene *scene, Object *ob, EditMesh *em, Deri
|
|||||||
|
|
||||||
md->scene= scene;
|
md->scene= scene;
|
||||||
|
|
||||||
if(!editmesh_modifier_is_enabled(md, dm))
|
if(!editmesh_modifier_is_enabled(scene, md, dm))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* add an orco layer if needed by this modifier */
|
/* add an orco layer if needed by this modifier */
|
||||||
@@ -2108,7 +2108,8 @@ static void mesh_build_data(Scene *scene, Object *ob, CustomDataMask dataMask)
|
|||||||
{
|
{
|
||||||
Object *obact = scene->basact?scene->basact->object:NULL;
|
Object *obact = scene->basact?scene->basact->object:NULL;
|
||||||
int editing = paint_facesel_test(ob);
|
int editing = paint_facesel_test(ob);
|
||||||
int needMapping = editing && (ob==obact);
|
/* weight paint and face select need original indicies because of selection buffer drawing */
|
||||||
|
int needMapping = (ob==obact) && (editing || (ob->mode & OB_MODE_WEIGHT_PAINT) || paint_facesel_test(ob));
|
||||||
float min[3], max[3];
|
float min[3], max[3];
|
||||||
|
|
||||||
clear_mesh_caches(ob);
|
clear_mesh_caches(ob);
|
||||||
@@ -2348,12 +2349,12 @@ float *mesh_get_mapped_verts_nors(Scene *scene, Object *ob)
|
|||||||
|
|
||||||
/* ********* crazyspace *************** */
|
/* ********* crazyspace *************** */
|
||||||
|
|
||||||
int editmesh_get_first_deform_matrices(Object *ob, EditMesh *em, float (**deformmats)[3][3], float (**deformcos)[3])
|
int editmesh_get_first_deform_matrices(Scene *scene, Object *ob, EditMesh *em, float (**deformmats)[3][3], float (**deformcos)[3])
|
||||||
{
|
{
|
||||||
ModifierData *md;
|
ModifierData *md;
|
||||||
DerivedMesh *dm;
|
DerivedMesh *dm;
|
||||||
int i, a, numleft = 0, numVerts = 0;
|
int i, a, numleft = 0, numVerts = 0;
|
||||||
int cageIndex = modifiers_getCageIndex(ob, NULL, 1);
|
int cageIndex = modifiers_getCageIndex(scene, ob, NULL, 1);
|
||||||
float (*defmats)[3][3] = NULL, (*deformedVerts)[3] = NULL;
|
float (*defmats)[3][3] = NULL, (*deformedVerts)[3] = NULL;
|
||||||
|
|
||||||
modifiers_clearErrors(ob);
|
modifiers_clearErrors(ob);
|
||||||
@@ -2367,7 +2368,7 @@ int editmesh_get_first_deform_matrices(Object *ob, EditMesh *em, float (**deform
|
|||||||
for(i = 0; md && i <= cageIndex; i++, md = md->next) {
|
for(i = 0; md && i <= cageIndex; i++, md = md->next) {
|
||||||
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
|
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
|
||||||
|
|
||||||
if(!editmesh_modifier_is_enabled(md, dm))
|
if(!editmesh_modifier_is_enabled(scene, md, dm))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(mti->type==eModifierTypeType_OnlyDeform && mti->deformMatricesEM) {
|
if(mti->type==eModifierTypeType_OnlyDeform && mti->deformMatricesEM) {
|
||||||
@@ -2388,7 +2389,7 @@ int editmesh_get_first_deform_matrices(Object *ob, EditMesh *em, float (**deform
|
|||||||
}
|
}
|
||||||
|
|
||||||
for(; md && i <= cageIndex; md = md->next, i++)
|
for(; md && i <= cageIndex; md = md->next, i++)
|
||||||
if(editmesh_modifier_is_enabled(md, dm) && modifier_isCorrectableDeformed(md))
|
if(editmesh_modifier_is_enabled(scene, md, dm) && modifier_isCorrectableDeformed(md))
|
||||||
numleft++;
|
numleft++;
|
||||||
|
|
||||||
if(dm)
|
if(dm)
|
||||||
|
|||||||
@@ -154,7 +154,7 @@ void animviz_free_motionpath(bMotionPath *mpath)
|
|||||||
|
|
||||||
/* ------------------- */
|
/* ------------------- */
|
||||||
|
|
||||||
/* Setup motion paths for the given data
|
/* Setup motion paths for the given data
|
||||||
* - scene: current scene (for frame ranges, etc.)
|
* - scene: current scene (for frame ranges, etc.)
|
||||||
* - ob: object to add paths for (must be provided)
|
* - ob: object to add paths for (must be provided)
|
||||||
* - pchan: posechannel to add paths for (optional; if not provided, object-paths are assumed)
|
* - pchan: posechannel to add paths for (optional; if not provided, object-paths are assumed)
|
||||||
@@ -226,8 +226,10 @@ typedef struct MPathTarget {
|
|||||||
|
|
||||||
/* ........ */
|
/* ........ */
|
||||||
|
|
||||||
/* get list of motion paths to be baked (assumes the list is ready to be used) */
|
/* get list of motion paths to be baked for the given object
|
||||||
static void motionpaths_get_bake_targets(Object *ob, ListBase *targets)
|
* - assumes the given list is ready to be used
|
||||||
|
*/
|
||||||
|
void animviz_get_object_motionpaths(Object *ob, ListBase *targets)
|
||||||
{
|
{
|
||||||
MPathTarget *mpt;
|
MPathTarget *mpt;
|
||||||
|
|
||||||
@@ -260,6 +262,8 @@ static void motionpaths_get_bake_targets(Object *ob, ListBase *targets)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ........ */
|
||||||
|
|
||||||
/* perform baking for the targets on the current frame */
|
/* perform baking for the targets on the current frame */
|
||||||
static void motionpaths_calc_bake_targets(Scene *scene, ListBase *targets)
|
static void motionpaths_calc_bake_targets(Scene *scene, ListBase *targets)
|
||||||
{
|
{
|
||||||
@@ -270,8 +274,10 @@ static void motionpaths_calc_bake_targets(Scene *scene, ListBase *targets)
|
|||||||
bMotionPath *mpath= mpt->mpath;
|
bMotionPath *mpath= mpt->mpath;
|
||||||
bMotionPathVert *mpv;
|
bMotionPathVert *mpv;
|
||||||
|
|
||||||
/* current frame must be within the range the cache works for */
|
/* current frame must be within the range the cache works for
|
||||||
if (IN_RANGE(CFRA, mpath->start_frame, mpath->end_frame) == 0)
|
* - is inclusive of the first frame, but not the last otherwise we get buffer overruns
|
||||||
|
*/
|
||||||
|
if ((CFRA < mpath->start_frame) || (CFRA >= mpath->end_frame))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* get the relevant cache vert to write to */
|
/* get the relevant cache vert to write to */
|
||||||
@@ -297,36 +303,30 @@ static void motionpaths_calc_bake_targets(Scene *scene, ListBase *targets)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ........ */
|
|
||||||
|
|
||||||
/* Perform baking of the given object's and/or its bones' transforms to motion paths
|
/* Perform baking of the given object's and/or its bones' transforms to motion paths
|
||||||
* - scene: current scene
|
* - scene: current scene
|
||||||
* - ob: object whose flagged motionpaths should get calculated
|
* - ob: object whose flagged motionpaths should get calculated
|
||||||
* - recalc: whether we need to
|
* - recalc: whether we need to
|
||||||
*/
|
*/
|
||||||
// TODO: include reports pointer?
|
// TODO: include reports pointer?
|
||||||
void animviz_calc_motionpaths(Scene *scene, Object *ob)
|
void animviz_calc_motionpaths(Scene *scene, ListBase *targets)
|
||||||
{
|
{
|
||||||
ListBase targets = {NULL, NULL};
|
|
||||||
MPathTarget *mpt;
|
MPathTarget *mpt;
|
||||||
int sfra, efra;
|
int sfra, efra;
|
||||||
int cfra;
|
int cfra;
|
||||||
|
|
||||||
/* sanity checks */
|
/* sanity check */
|
||||||
if (ob == NULL)
|
if (ELEM(NULL, targets, targets->first))
|
||||||
return;
|
|
||||||
|
|
||||||
/* get motion paths to affect */
|
|
||||||
motionpaths_get_bake_targets(ob, &targets);
|
|
||||||
|
|
||||||
if (targets.first == NULL)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* set frame values */
|
/* set frame values */
|
||||||
cfra = CFRA;
|
cfra = CFRA;
|
||||||
sfra = efra = cfra;
|
sfra = efra = cfra;
|
||||||
|
|
||||||
for (mpt= targets.first; mpt; mpt= mpt->next) {
|
// TODO: this method could be improved...
|
||||||
|
// 1) max range for standard baking
|
||||||
|
// 2) minimum range for recalc baking (i.e. between keyfames, but how?)
|
||||||
|
for (mpt= targets->first; mpt; mpt= mpt->next) {
|
||||||
/* try to increase area to do (only as much as needed) */
|
/* try to increase area to do (only as much as needed) */
|
||||||
sfra= MIN2(sfra, mpt->mpath->start_frame);
|
sfra= MIN2(sfra, mpt->mpath->start_frame);
|
||||||
efra= MAX2(efra, mpt->mpath->end_frame);
|
efra= MAX2(efra, mpt->mpath->end_frame);
|
||||||
@@ -340,23 +340,29 @@ void animviz_calc_motionpaths(Scene *scene, Object *ob)
|
|||||||
* that doesn't force complete update, but for now, this is the
|
* that doesn't force complete update, but for now, this is the
|
||||||
* most accurate way!
|
* most accurate way!
|
||||||
*/
|
*/
|
||||||
scene_update_for_newframe(scene, ob->lay); // XXX is the layer flag too restrictive?
|
scene_update_for_newframe(scene, scene->lay); // XXX this is the best way we can get anything moving
|
||||||
|
|
||||||
/* perform baking for targets */
|
/* perform baking for targets */
|
||||||
motionpaths_calc_bake_targets(scene, &targets);
|
motionpaths_calc_bake_targets(scene, targets);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* reset original environment */
|
/* reset original environment */
|
||||||
CFRA= cfra;
|
CFRA= cfra;
|
||||||
scene_update_for_newframe(scene, ob->lay); // XXX is the layer flag too restrictive?
|
scene_update_for_newframe(scene, scene->lay); // XXX this is the best way we can get anything moving
|
||||||
|
|
||||||
// TODO: make an API call for this too?
|
/* clear recalc flags from targets */
|
||||||
ob->avs.recalc &= ~ANIMVIZ_RECALC_PATHS;
|
for (mpt= targets->first; mpt; mpt= mpt->next) {
|
||||||
if (ob->pose)
|
bAnimVizSettings *avs;
|
||||||
ob->pose->avs.recalc &= ~ANIMVIZ_RECALC_PATHS;
|
|
||||||
|
/* get pointer to animviz settings for each target */
|
||||||
/* free temp data */
|
if (mpt->pchan)
|
||||||
BLI_freelistN(&targets);
|
avs= &mpt->ob->pose->avs;
|
||||||
|
else
|
||||||
|
avs= &mpt->ob->avs;
|
||||||
|
|
||||||
|
/* clear the flag requesting recalculation of targets */
|
||||||
|
avs->recalc &= ~ANIMVIZ_RECALC_PATHS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ******************************************************************** */
|
/* ******************************************************************** */
|
||||||
|
|||||||
@@ -730,6 +730,11 @@ static short animsys_write_rna_setting (PointerRNA *ptr, char *path, int array_i
|
|||||||
/* set value - only for animatable numerical values */
|
/* set value - only for animatable numerical values */
|
||||||
if (RNA_property_animateable(&new_ptr, prop))
|
if (RNA_property_animateable(&new_ptr, prop))
|
||||||
{
|
{
|
||||||
|
/* convert to radians */
|
||||||
|
if (RNA_SUBTYPE_UNIT(RNA_property_subtype(prop)) == PROP_UNIT_ROTATION) {
|
||||||
|
value *= M_PI/180.0;
|
||||||
|
}
|
||||||
|
|
||||||
switch (RNA_property_type(prop))
|
switch (RNA_property_type(prop))
|
||||||
{
|
{
|
||||||
case PROP_BOOLEAN:
|
case PROP_BOOLEAN:
|
||||||
@@ -1466,6 +1471,11 @@ void nladata_flush_channels (ListBase *channels)
|
|||||||
int array_index= nec->index;
|
int array_index= nec->index;
|
||||||
float value= nec->value;
|
float value= nec->value;
|
||||||
|
|
||||||
|
/* convert to radians */
|
||||||
|
if (RNA_SUBTYPE_UNIT(RNA_property_subtype(prop)) == PROP_UNIT_ROTATION) {
|
||||||
|
value *= M_PI/180.0;
|
||||||
|
}
|
||||||
|
|
||||||
/* write values - see animsys_write_rna_setting() to sync the code */
|
/* write values - see animsys_write_rna_setting() to sync the code */
|
||||||
switch (RNA_property_type(prop))
|
switch (RNA_property_type(prop))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1602,7 +1602,13 @@ void armature_rebuild_pose(Object *ob, bArmature *arm)
|
|||||||
int counter=0;
|
int counter=0;
|
||||||
|
|
||||||
/* only done here */
|
/* only done here */
|
||||||
if(ob->pose==NULL) ob->pose= MEM_callocN(sizeof(bPose), "new pose");
|
if(ob->pose==NULL) {
|
||||||
|
/* create new pose */
|
||||||
|
ob->pose= MEM_callocN(sizeof(bPose), "new pose");
|
||||||
|
|
||||||
|
/* set default settings for animviz */
|
||||||
|
animviz_settings_init(&ob->pose->avs);
|
||||||
|
}
|
||||||
pose= ob->pose;
|
pose= ob->pose;
|
||||||
|
|
||||||
/* clear */
|
/* clear */
|
||||||
@@ -1627,8 +1633,10 @@ void armature_rebuild_pose(Object *ob, bArmature *arm)
|
|||||||
// printf("rebuild pose %s, %d bones\n", ob->id.name, counter);
|
// printf("rebuild pose %s, %d bones\n", ob->id.name, counter);
|
||||||
|
|
||||||
/* synchronize protected layers with proxy */
|
/* synchronize protected layers with proxy */
|
||||||
if(ob->proxy)
|
if(ob->proxy) {
|
||||||
|
object_copy_proxy_drivers(ob, ob->proxy);
|
||||||
pose_proxy_synchronize(ob, ob->proxy, arm->layer_protected);
|
pose_proxy_synchronize(ob, ob->proxy, arm->layer_protected);
|
||||||
|
}
|
||||||
|
|
||||||
update_pose_constraint_flags(ob->pose); // for IK detection for example
|
update_pose_constraint_flags(ob->pose); // for IK detection for example
|
||||||
|
|
||||||
|
|||||||
@@ -103,76 +103,6 @@ short ENDIAN_ORDER;
|
|||||||
|
|
||||||
char versionstr[48]= "";
|
char versionstr[48]= "";
|
||||||
|
|
||||||
/* ************************************************ */
|
|
||||||
/* pushpop facility: to store data temporally, FIFO! */
|
|
||||||
|
|
||||||
ListBase ppmain={0, 0};
|
|
||||||
|
|
||||||
typedef struct PushPop {
|
|
||||||
struct PushPop *next, *prev;
|
|
||||||
void *data;
|
|
||||||
int len;
|
|
||||||
} PushPop;
|
|
||||||
|
|
||||||
void pushdata(void *data, int len)
|
|
||||||
{
|
|
||||||
PushPop *pp;
|
|
||||||
|
|
||||||
pp= MEM_mallocN(sizeof(PushPop), "pushpop");
|
|
||||||
BLI_addtail(&ppmain, pp);
|
|
||||||
pp->data= MEM_mallocN(len, "pushpop");
|
|
||||||
pp->len= len;
|
|
||||||
memcpy(pp->data, data, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
void popfirst(void *data)
|
|
||||||
{
|
|
||||||
PushPop *pp;
|
|
||||||
|
|
||||||
pp= ppmain.first;
|
|
||||||
if(pp) {
|
|
||||||
memcpy(data, pp->data, pp->len);
|
|
||||||
BLI_remlink(&ppmain, pp);
|
|
||||||
MEM_freeN(pp->data);
|
|
||||||
MEM_freeN(pp);
|
|
||||||
}
|
|
||||||
else printf("error in popfirst\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void poplast(void *data)
|
|
||||||
{
|
|
||||||
PushPop *pp;
|
|
||||||
|
|
||||||
pp= ppmain.last;
|
|
||||||
if(pp) {
|
|
||||||
memcpy(data, pp->data, pp->len);
|
|
||||||
BLI_remlink(&ppmain, pp);
|
|
||||||
MEM_freeN(pp->data);
|
|
||||||
MEM_freeN(pp);
|
|
||||||
}
|
|
||||||
else printf("error in poplast\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void free_pushpop()
|
|
||||||
{
|
|
||||||
PushPop *pp;
|
|
||||||
|
|
||||||
pp= ppmain.first;
|
|
||||||
while(pp) {
|
|
||||||
BLI_remlink(&ppmain, pp);
|
|
||||||
MEM_freeN(pp->data);
|
|
||||||
MEM_freeN(pp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void pushpop_test()
|
|
||||||
{
|
|
||||||
if(ppmain.first) printf("pushpop not empty\n");
|
|
||||||
free_pushpop();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ********** free ********** */
|
/* ********** free ********** */
|
||||||
|
|
||||||
/* only to be called on exit blender */
|
/* only to be called on exit blender */
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ static int rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val,
|
|||||||
EffectedPoint epoint;
|
EffectedPoint epoint;
|
||||||
ListBase *effectors = bbd->sim->psys->effectors;
|
ListBase *effectors = bbd->sim->psys->effectors;
|
||||||
EffectorCache *cur, *eff = NULL;
|
EffectorCache *cur, *eff = NULL;
|
||||||
|
EffectorCache temp_eff;
|
||||||
EffectorData efd, cur_efd;
|
EffectorData efd, cur_efd;
|
||||||
float mul = (rule->type == eBoidRuleType_Avoid ? 1.0 : -1.0);
|
float mul = (rule->type == eBoidRuleType_Avoid ? 1.0 : -1.0);
|
||||||
float priority = 0.0f, len = 0.0f;
|
float priority = 0.0f, len = 0.0f;
|
||||||
@@ -91,7 +92,7 @@ static int rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val,
|
|||||||
|
|
||||||
if(gabr->ob && (rule->type != eBoidRuleType_Goal || gabr->ob != bpa->ground)) {
|
if(gabr->ob && (rule->type != eBoidRuleType_Goal || gabr->ob != bpa->ground)) {
|
||||||
if(gabr->ob == eob) {
|
if(gabr->ob == eob) {
|
||||||
/* TODO: objects without any effector and effectors with multiple points */
|
/* TODO: effectors with multiple points */
|
||||||
if(get_effector_data(cur, &efd, &epoint, 0)) {
|
if(get_effector_data(cur, &efd, &epoint, 0)) {
|
||||||
if(cur->pd && cur->pd->forcefield == PFIELD_BOID)
|
if(cur->pd && cur->pd->forcefield == PFIELD_BOID)
|
||||||
priority = mul * pd->f_strength * effector_falloff(cur, &efd, &epoint, bbd->part->effector_weights);
|
priority = mul * pd->f_strength * effector_falloff(cur, &efd, &epoint, bbd->part->effector_weights);
|
||||||
@@ -105,7 +106,7 @@ static int rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val,
|
|||||||
}
|
}
|
||||||
else if(rule->type == eBoidRuleType_Goal && eob == bpa->ground)
|
else if(rule->type == eBoidRuleType_Goal && eob == bpa->ground)
|
||||||
; /* skip current object */
|
; /* skip current object */
|
||||||
else if(pd->forcefield == PFIELD_BOID && mul * pd->f_strength > 0.0f && get_effector_data(eff, &efd, &epoint, 0)) {
|
else if(pd->forcefield == PFIELD_BOID && mul * pd->f_strength > 0.0f && get_effector_data(cur, &cur_efd, &epoint, 0)) {
|
||||||
float temp = mul * pd->f_strength * effector_falloff(cur, &cur_efd, &epoint, bbd->part->effector_weights);
|
float temp = mul * pd->f_strength * effector_falloff(cur, &cur_efd, &epoint, bbd->part->effector_weights);
|
||||||
|
|
||||||
if(temp == 0.0f)
|
if(temp == 0.0f)
|
||||||
@@ -125,11 +126,21 @@ static int rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* if the object doesn't have effector data we have to fake it */
|
||||||
|
if(eff == NULL && gabr->ob) {
|
||||||
|
memset(&temp_eff, 0, sizeof(EffectorCache));
|
||||||
|
temp_eff.ob = gabr->ob;
|
||||||
|
temp_eff.scene = bbd->sim->scene;
|
||||||
|
eff = &temp_eff;
|
||||||
|
get_effector_data(eff, &efd, &epoint, 0);
|
||||||
|
priority = 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
/* then use that effector */
|
/* then use that effector */
|
||||||
if(priority > (rule->type==eBoidRuleType_Avoid ? gabr->fear_factor : 0.0f)) { /* with avoid, factor is "fear factor" */
|
if(priority > (rule->type==eBoidRuleType_Avoid ? gabr->fear_factor : 0.0f)) { /* with avoid, factor is "fear factor" */
|
||||||
Object *eob = eff->ob;
|
Object *eob = eff->ob;
|
||||||
PartDeflect *pd = eob->pd;
|
PartDeflect *pd = eff->pd;
|
||||||
float surface = pd->shape == PFIELD_SHAPE_SURFACE ? 1.0f : 0.0f;
|
float surface = (pd && pd->shape == PFIELD_SHAPE_SURFACE) ? 1.0f : 0.0f;
|
||||||
|
|
||||||
if(gabr->options & BRULE_GOAL_AVOID_PREDICT) {
|
if(gabr->options & BRULE_GOAL_AVOID_PREDICT) {
|
||||||
/* estimate future location of target */
|
/* estimate future location of target */
|
||||||
@@ -219,10 +230,19 @@ static int rule_avoid_collision(BoidRule *rule, BoidBrainData *bbd, BoidValues *
|
|||||||
}
|
}
|
||||||
/* then avoid that object */
|
/* then avoid that object */
|
||||||
if(hit.index>=0) {
|
if(hit.index>=0) {
|
||||||
/* TODO: not totally happy with this part */
|
|
||||||
t = hit.dist/col.ray_len;
|
t = hit.dist/col.ray_len;
|
||||||
|
|
||||||
VECCOPY(bbd->wanted_co, col.nor);
|
/* avoid head-on collision */
|
||||||
|
if(dot_v3v3(col.nor, pa->prev_state.ave) < -0.99) {
|
||||||
|
/* don't know why, but uneven range [0.0,1.0] */
|
||||||
|
/* works much better than even [-1.0,1.0] */
|
||||||
|
bbd->wanted_co[0] = BLI_frand();
|
||||||
|
bbd->wanted_co[1] = BLI_frand();
|
||||||
|
bbd->wanted_co[2] = BLI_frand();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
VECCOPY(bbd->wanted_co, col.nor);
|
||||||
|
}
|
||||||
|
|
||||||
mul_v3_fl(bbd->wanted_co, (1.0f - t) * val->personal_space * pa->size);
|
mul_v3_fl(bbd->wanted_co, (1.0f - t) * val->personal_space * pa->size);
|
||||||
|
|
||||||
|
|||||||
@@ -89,6 +89,8 @@ Brush *add_brush(const char *name)
|
|||||||
brush->flag |= BRUSH_SPACE;
|
brush->flag |= BRUSH_SPACE;
|
||||||
|
|
||||||
brush_curve_preset(brush, CURVE_PRESET_SMOOTH);
|
brush_curve_preset(brush, CURVE_PRESET_SMOOTH);
|
||||||
|
|
||||||
|
default_mtex(&brush->mtex);
|
||||||
|
|
||||||
/* enable fake user by default */
|
/* enable fake user by default */
|
||||||
brush->id.flag |= LIB_FAKEUSER;
|
brush->id.flag |= LIB_FAKEUSER;
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user