svn merge -r 21508:22111 https://svn.blender.org/svnroot/bf-blender/branches/blender2.5/blender
This commit is contained in:
@@ -63,6 +63,7 @@ OPTION(WITH_OPENEXR "Enable OpenEXR Support (http://www.openexr.com)" ON)
|
|||||||
OPTION(WITH_DDS "Enable DDS Support" ON)
|
OPTION(WITH_DDS "Enable DDS Support" ON)
|
||||||
OPTION(WITH_FFMPEG "Enable FFMPeg Support (http://ffmpeg.mplayerhq.hu/)" OFF)
|
OPTION(WITH_FFMPEG "Enable FFMPeg Support (http://ffmpeg.mplayerhq.hu/)" OFF)
|
||||||
OPTION(WITH_PYTHON "Enable Embedded Python API" ON)
|
OPTION(WITH_PYTHON "Enable Embedded Python API" ON)
|
||||||
|
OPTION(WITH_SDL "Enable SDL for sound and joystick support" ON)
|
||||||
OPTION(WITH_OPENJPEG "Enable OpenJpeg Support (http://www.openjpeg.org/)" OFF)
|
OPTION(WITH_OPENJPEG "Enable OpenJpeg Support (http://www.openjpeg.org/)" OFF)
|
||||||
OPTION(WITH_OPENAL "Enable OpenAL Support (http://www.openal.org)" ON)
|
OPTION(WITH_OPENAL "Enable OpenAL Support (http://www.openal.org)" ON)
|
||||||
OPTION(WITH_OPENMP "Enable OpenMP (has to be supported by the compiler)" OFF)
|
OPTION(WITH_OPENMP "Enable OpenMP (has to be supported by the compiler)" OFF)
|
||||||
@@ -133,9 +134,11 @@ IF(UNIX AND NOT APPLE)
|
|||||||
SET(PYTHON_BINARY ${PYTHON_EXECUTABLE} CACHE STRING "")
|
SET(PYTHON_BINARY ${PYTHON_EXECUTABLE} CACHE STRING "")
|
||||||
SET(PYTHON_LINKFLAGS "-Xlinker -export-dynamic")
|
SET(PYTHON_LINKFLAGS "-Xlinker -export-dynamic")
|
||||||
|
|
||||||
|
IF(WITH_SDL)
|
||||||
FIND_PACKAGE(SDL)
|
FIND_PACKAGE(SDL)
|
||||||
SET(SDL_INC ${SDL_INCLUDE_DIR})
|
SET(SDL_INC ${SDL_INCLUDE_DIR})
|
||||||
SET(SDL_LIB ${SDL_LIBRARY})
|
SET(SDL_LIB ${SDL_LIBRARY})
|
||||||
|
ENDIF(WITH_SDL)
|
||||||
|
|
||||||
FIND_PATH(OPENEXR_INC
|
FIND_PATH(OPENEXR_INC
|
||||||
ImfXdr.h
|
ImfXdr.h
|
||||||
@@ -336,17 +339,29 @@ IF(APPLE)
|
|||||||
ENDIF(OPENAL_FOUND)
|
ENDIF(OPENAL_FOUND)
|
||||||
ENDIF(WITH_OPENAL)
|
ENDIF(WITH_OPENAL)
|
||||||
|
|
||||||
|
|
||||||
|
SET(PYTHON_VERSION 3.1)
|
||||||
|
|
||||||
|
IF(PYTHON_VERSION MATCHES 3.1)
|
||||||
|
# we use precompiled libraries for py 3.1 and up by default
|
||||||
|
|
||||||
|
SET(PYTHON ${LIBDIR}/python)
|
||||||
|
SET(PYTHON_INC "${PYTHON}/include/python${PYTHON_VERSION}" CACHE STRING "")
|
||||||
|
SET(PYTHON_BINARY "${PYTHON}/bin/python${PYTHON_VERSION}" CACHE STRING "")
|
||||||
|
SET(PYTHON_LIB python${PYTHON_VERSION})
|
||||||
|
SET(PYTHON_LIBPATH "${PYTHON}/lib/python${PYTHON_VERSION}" CACHE STRING "")
|
||||||
|
# SET(PYTHON_LINKFLAGS "-u _PyMac_Error") # won't build with this enabled
|
||||||
|
ELSE(PYTHON_VERSION MATCHES 3.1)
|
||||||
|
# otherwise, use custom system framework
|
||||||
|
|
||||||
SET(PYTHON /System/Library/Frameworks/Python.framework/Versions/)
|
SET(PYTHON /System/Library/Frameworks/Python.framework/Versions/)
|
||||||
SET(PYTHON_VERSION 2.5)
|
SET(PYTHON_VERSION 2.5)
|
||||||
SET(PYTHON_INC "${PYTHON}${PYTHON_VERSION}/include/python${PYTHON_VERSION}" CACHE STRING "")
|
SET(PYTHON_INC "${PYTHON}${PYTHON_VERSION}/include/python${PYTHON_VERSION}" CACHE STRING "")
|
||||||
SET(PYTHON_BINARY ${PYTHON}${PYTHON_VERSION}/bin/python${PYTHON_VERSION} CACHE STRING "")
|
SET(PYTHON_BINARY ${PYTHON}${PYTHON_VERSION}/bin/python${PYTHON_VERSION} CACHE STRING "")
|
||||||
SET(PYTHON_LIB "")
|
SET(PYTHON_LIB "")
|
||||||
SET(PYTHON_LIBPATH ${PYTHON}${PYTHON_VERSION}/lib/python${PYTHON_VERSION}/config CACHE STRING "")
|
SET(PYTHON_LIBPATH ${PYTHON}${PYTHON_VERSION}/lib/python${PYTHON_VERSION}/config CACHE STRING "")
|
||||||
IF(CMAKE_SYSTEM_VERSION GREATER 10.4)
|
|
||||||
SET(PYTHON_LINKFLAGS "-u _PyMac_Error -framework System -framework Python")
|
SET(PYTHON_LINKFLAGS "-u _PyMac_Error -framework System -framework Python")
|
||||||
ELSE(CMAKE_SYSTEM_VERSION GREATER 10.4)
|
ENDIF(PYTHON_VERSION MATCHES 3.1)
|
||||||
SET(PYTHON_LINKFLAGS "-u _PyMac_Error -framework System -framework Python")
|
|
||||||
ENDIF(CMAKE_SYSTEM_VERSION GREATER 10.4)
|
|
||||||
|
|
||||||
SET(GETTEXT ${LIBDIR}/gettext)
|
SET(GETTEXT ${LIBDIR}/gettext)
|
||||||
SET(GETTEXT_INC "${GETTEXT}/include")
|
SET(GETTEXT_INC "${GETTEXT}/include")
|
||||||
@@ -367,11 +382,7 @@ IF(APPLE)
|
|||||||
|
|
||||||
SET(OPENEXR ${LIBDIR}/openexr)
|
SET(OPENEXR ${LIBDIR}/openexr)
|
||||||
SET(OPENEXR_INC ${OPENEXR}/include/OpenEXR ${OPENEXR}/include)
|
SET(OPENEXR_INC ${OPENEXR}/include/OpenEXR ${OPENEXR}/include)
|
||||||
IF(CMAKE_OSX_ARCHITECTURES MATCHES i386)
|
|
||||||
SET(OPENEXR_LIB Iex Half IlmImf Imath IlmThread)
|
SET(OPENEXR_LIB Iex Half IlmImf Imath IlmThread)
|
||||||
ELSE(CMAKE_OSX_ARCHITECTURES MATCHES i386)
|
|
||||||
SET(OPENEXR_LIB Iex Half IlmImf Imath)
|
|
||||||
ENDIF(CMAKE_OSX_ARCHITECTURES MATCHES i386)
|
|
||||||
SET(OPENEXR_LIBPATH ${OPENEXR}/lib)
|
SET(OPENEXR_LIBPATH ${OPENEXR}/lib)
|
||||||
|
|
||||||
SET(LLIBS stdc++ SystemStubs)
|
SET(LLIBS stdc++ SystemStubs)
|
||||||
|
|||||||
@@ -32,10 +32,10 @@ IF(WITH_QUICKTIME)
|
|||||||
ADD_DEFINITIONS(-DWITH_QUICKTIME)
|
ADD_DEFINITIONS(-DWITH_QUICKTIME)
|
||||||
ENDIF(WITH_QUICKTIME)
|
ENDIF(WITH_QUICKTIME)
|
||||||
|
|
||||||
IF(LINUX)
|
IF(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||||
ADD_DEFINITIONS(-DWITH_BINRELOC)
|
ADD_DEFINITIONS(-DWITH_BINRELOC)
|
||||||
INCLUDE_DIRECTORIES(${BINRELOC_INC})
|
INCLUDE_DIRECTORIES(${BINRELOC_INC})
|
||||||
endif(LINUX)
|
ENDIF(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||||
|
|
||||||
ADD_CUSTOM_COMMAND(
|
ADD_CUSTOM_COMMAND(
|
||||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/dna.c
|
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/dna.c
|
||||||
@@ -69,7 +69,6 @@ IF(UNIX)
|
|||||||
bf_blenkernel
|
bf_blenkernel
|
||||||
verse
|
verse
|
||||||
bf_blenkernel
|
bf_blenkernel
|
||||||
bf_decimation
|
|
||||||
bf_blenloader
|
bf_blenloader
|
||||||
bf_blenpluginapi
|
bf_blenpluginapi
|
||||||
bf_blroutines
|
bf_blroutines
|
||||||
|
|||||||
@@ -10,8 +10,6 @@ import commands
|
|||||||
# IMPORTANT NOTE : OFFICIAL BUILDS SHOULD BE DONE WITH SDKs
|
# IMPORTANT NOTE : OFFICIAL BUILDS SHOULD BE DONE WITH SDKs
|
||||||
USE_SDK=True
|
USE_SDK=True
|
||||||
|
|
||||||
BF_PYTHON_VERSION = '2.3'
|
|
||||||
|
|
||||||
cmd = 'uname -p'
|
cmd = 'uname -p'
|
||||||
MAC_PROC=commands.getoutput(cmd)
|
MAC_PROC=commands.getoutput(cmd)
|
||||||
cmd = 'uname -r'
|
cmd = 'uname -r'
|
||||||
@@ -32,9 +30,12 @@ LIBDIR = '${LCGDIR}'
|
|||||||
if MAC_PROC== 'powerpc' and BF_PYTHON_VERSION == '2.3':
|
if MAC_PROC== 'powerpc' and BF_PYTHON_VERSION == '2.3':
|
||||||
MAC_MIN_VERS = '10.3'
|
MAC_MIN_VERS = '10.3'
|
||||||
MACOSX_SDK='/Developer/SDKs/MacOSX10.3.9.sdk'
|
MACOSX_SDK='/Developer/SDKs/MacOSX10.3.9.sdk'
|
||||||
else:
|
elif MAC_CUR_VER=='10.4':
|
||||||
MAC_MIN_VERS = '10.4'
|
MAC_MIN_VERS = '10.4'
|
||||||
MACOSX_SDK='/Developer/SDKs/MacOSX10.4u.sdk'
|
MACOSX_SDK='/Developer/SDKs/MacOSX10.4u.sdk'
|
||||||
|
else:
|
||||||
|
MAC_MIN_VERS = '10.5'
|
||||||
|
MACOSX_SDK='/Developer/SDKs/MacOSX10.5.sdk'
|
||||||
|
|
||||||
|
|
||||||
# enable ffmpeg support
|
# enable ffmpeg support
|
||||||
@@ -46,23 +47,34 @@ if USE_SDK==True:
|
|||||||
#BF_FFMPEG_LIBPATH='${BF_FFMPEG}/lib'
|
#BF_FFMPEG_LIBPATH='${BF_FFMPEG}/lib'
|
||||||
#BF_FFMPEG_LIB = 'avformat.a avcodec.a avutil.a'
|
#BF_FFMPEG_LIB = 'avformat.a avcodec.a avutil.a'
|
||||||
|
|
||||||
# python.org libs install in /library we want to use that for 2.5
|
BF_PYTHON_VERSION = '3.1'
|
||||||
#
|
|
||||||
# if you want py2.5 on leopard without installing
|
|
||||||
# change value to BF_PYTHON = '/Library/Frameworks/Python.framework/Versions/'
|
|
||||||
# BEWARE: in that case it will work only on leopard
|
|
||||||
|
|
||||||
if BF_PYTHON_VERSION=='2.3':
|
if BF_PYTHON_VERSION=='3.1':
|
||||||
BF_PYTHON = '/System/Library/Frameworks/Python.framework/Versions/'
|
# python 3.1 uses precompiled libraries in bf svn /lib by default
|
||||||
|
|
||||||
|
BF_PYTHON = LIBDIR + '/python'
|
||||||
|
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_LIBPATH = '${BF_PYTHON}/lib/python${BF_PYTHON_VERSION}'
|
||||||
|
# BF_PYTHON_LINKFLAGS = '-u _PyMac_Error -framework System'
|
||||||
else:
|
else:
|
||||||
BF_PYTHON = '/Library/Frameworks/Python.framework/Versions/'
|
# python 2.5 etc. uses built-in framework
|
||||||
|
|
||||||
BF_PYTHON_INC = '${BF_PYTHON}${BF_PYTHON_VERSION}/include/python${BF_PYTHON_VERSION}'
|
# python.org libs install in /library we want to use that for 2.5
|
||||||
BF_PYTHON_BINARY = '${BF_PYTHON}${BF_PYTHON_VERSION}/bin/python${BF_PYTHON_VERSION}'
|
#
|
||||||
BF_PYTHON_LIB = ''
|
# if you want py2.5 on leopard without installing
|
||||||
BF_PYTHON_LIBPATH = '${BF_PYTHON}${BF_PYTHON_VERSION}/lib/python${BF_PYTHON_VERSION}/config'
|
# change value to BF_PYTHON = '/Library/Frameworks/Python.framework/Versions/'
|
||||||
BF_PYTHON_LINKFLAGS = '-u _PyMac_Error -framework System -framework Python'
|
# BEWARE: in that case it will work only on leopard
|
||||||
if MAC_CUR_VER=='10.3' or MAC_CUR_VER=='10.4':
|
|
||||||
|
BF_PYTHON = '/System/Library/Frameworks/Python.framework/Versions/'
|
||||||
|
|
||||||
|
BF_PYTHON_INC = '${BF_PYTHON}${BF_PYTHON_VERSION}/include/python${BF_PYTHON_VERSION}'
|
||||||
|
BF_PYTHON_BINARY = '${BF_PYTHON}${BF_PYTHON_VERSION}/bin/python${BF_PYTHON_VERSION}'
|
||||||
|
BF_PYTHON_LIB = ''
|
||||||
|
BF_PYTHON_LIBPATH = '${BF_PYTHON}${BF_PYTHON_VERSION}/lib/python${BF_PYTHON_VERSION}/config'
|
||||||
|
BF_PYTHON_LINKFLAGS = '-u _PyMac_Error -framework System -framework Python'
|
||||||
|
if MAC_CUR_VER=='10.3' or MAC_CUR_VER=='10.4':
|
||||||
BF_PYTHON_LINKFLAGS ='-u __dummy '+BF_PYTHON_LINKFLAGS
|
BF_PYTHON_LINKFLAGS ='-u __dummy '+BF_PYTHON_LINKFLAGS
|
||||||
|
|
||||||
BF_QUIET = '1'
|
BF_QUIET = '1'
|
||||||
@@ -139,7 +151,7 @@ BF_GETTEXT_LIB = 'intl'
|
|||||||
BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib'
|
BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib'
|
||||||
|
|
||||||
WITH_BF_GAMEENGINE=True
|
WITH_BF_GAMEENGINE=True
|
||||||
WITH_BF_PLAYER=True
|
WITH_BF_PLAYER = False
|
||||||
|
|
||||||
WITH_BF_BULLET = True
|
WITH_BF_BULLET = True
|
||||||
BF_BULLET = '#extern/bullet2/src'
|
BF_BULLET = '#extern/bullet2/src'
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ BF_GETTEXT_LIB = 'gettextpo intl'
|
|||||||
BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib'
|
BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib'
|
||||||
|
|
||||||
WITH_BF_GAMEENGINE='false'
|
WITH_BF_GAMEENGINE='false'
|
||||||
|
WITH_BF_PLAYER = 'false'
|
||||||
|
|
||||||
WITH_BF_BULLET = 'true'
|
WITH_BF_BULLET = 'true'
|
||||||
BF_BULLET = '#extern/bullet2/src'
|
BF_BULLET = '#extern/bullet2/src'
|
||||||
|
|||||||
@@ -1,17 +1,9 @@
|
|||||||
LCGDIR = '../lib/linux2'
|
LCGDIR = '../lib/linux2'
|
||||||
LIBDIR = "${LCGDIR}"
|
LIBDIR = "${LCGDIR}"
|
||||||
|
|
||||||
def py_version_string():
|
|
||||||
'''
|
|
||||||
returns py version - "2.5", "2.6" etc
|
|
||||||
'''
|
|
||||||
import platform
|
|
||||||
ver = platform.python_version_tuple()
|
|
||||||
return '%d.%d' % (int(ver[0]), int(ver[1])) # py2.5 uses strings, 2.6 ints
|
|
||||||
|
|
||||||
BF_PYTHON = '/usr'
|
BF_PYTHON = '/usr'
|
||||||
BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib'
|
BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib'
|
||||||
BF_PYTHON_VERSION = py_version_string()
|
BF_PYTHON_VERSION = '3.1'
|
||||||
WITH_BF_STATICPYTHON = False
|
WITH_BF_STATICPYTHON = False
|
||||||
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}'
|
||||||
@@ -75,7 +67,7 @@ BF_GETTEXT_LIB = 'gettextlib'
|
|||||||
BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib'
|
BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib'
|
||||||
|
|
||||||
WITH_BF_GAMEENGINE = True
|
WITH_BF_GAMEENGINE = True
|
||||||
WITH_BF_PLAYER = True
|
WITH_BF_PLAYER = False
|
||||||
|
|
||||||
WITH_BF_BULLET = True
|
WITH_BF_BULLET = True
|
||||||
BF_BULLET = '#extern/bullet2/src'
|
BF_BULLET = '#extern/bullet2/src'
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ BF_GETTEXT_LIB = 'gnu_gettext'
|
|||||||
BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib'
|
BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib'
|
||||||
|
|
||||||
WITH_BF_GAMEENGINE = False
|
WITH_BF_GAMEENGINE = False
|
||||||
|
WITH_BF_PLAYER = False
|
||||||
|
|
||||||
WITH_BF_BULLET = True
|
WITH_BF_BULLET = True
|
||||||
BF_BULLET = '#extern/bullet2/src'
|
BF_BULLET = '#extern/bullet2/src'
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ BF_GETTEXT_LIB = 'intl iconv'
|
|||||||
BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib'
|
BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib'
|
||||||
|
|
||||||
WITH_BF_GAMEENGINE=False
|
WITH_BF_GAMEENGINE=False
|
||||||
|
WITH_BF_PLAYER = False
|
||||||
|
|
||||||
WITH_BF_BULLET = True
|
WITH_BF_BULLET = True
|
||||||
BF_BULLET = '#extern/bullet2/src'
|
BF_BULLET = '#extern/bullet2/src'
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ BF_GETTEXT_LIB = 'gettextlib'
|
|||||||
BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib'
|
BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib'
|
||||||
|
|
||||||
WITH_BF_GAMEENGINE=False
|
WITH_BF_GAMEENGINE=False
|
||||||
|
WITH_BF_PLAYER = False
|
||||||
|
|
||||||
WITH_BF_BULLET = True
|
WITH_BF_BULLET = True
|
||||||
BF_BULLET = '#extern/bullet2/src'
|
BF_BULLET = '#extern/bullet2/src'
|
||||||
|
|||||||
@@ -2,7 +2,8 @@ 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_VERSION = '2.6'
|
||||||
#BF_PYTHON_VERSION = '2.6'
|
#BF_PYTHON_VERSION = '2.6'
|
||||||
WITH_BF_STATICPYTHON = False
|
WITH_BF_STATICPYTHON = False
|
||||||
BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}'
|
BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}'
|
||||||
@@ -80,6 +81,7 @@ BF_GETTEXT_LIB = 'gnu_gettext'
|
|||||||
BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib'
|
BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib'
|
||||||
|
|
||||||
WITH_BF_GAMEENGINE = False
|
WITH_BF_GAMEENGINE = False
|
||||||
|
WITH_BF_PLAYER = False
|
||||||
|
|
||||||
WITH_BF_BULLET = True
|
WITH_BF_BULLET = True
|
||||||
BF_BULLET = '#extern/bullet2/src'
|
BF_BULLET = '#extern/bullet2/src'
|
||||||
@@ -148,7 +150,7 @@ LLIBS = ['-lshell32', '-lshfolder', '-lgdi32', '-lmsvcrt', '-lwinmm', '-lmingw32
|
|||||||
BF_DEBUG = False
|
BF_DEBUG = False
|
||||||
BF_DEBUG_CCFLAGS= ['-g']
|
BF_DEBUG_CCFLAGS= ['-g']
|
||||||
|
|
||||||
BF_PROFILE_CCFLAGS = ['-pg', '-g ']
|
BF_PROFILE_CCFLAGS = ['-pg', '-g']
|
||||||
BF_PROFILE_LINKFLAGS = ['-pg']
|
BF_PROFILE_LINKFLAGS = ['-pg']
|
||||||
BF_PROFILE_FLAGS = BF_PROFILE_CCFLAGS
|
BF_PROFILE_FLAGS = BF_PROFILE_CCFLAGS
|
||||||
BF_PROFILE = False
|
BF_PROFILE = False
|
||||||
|
|||||||
@@ -9,10 +9,10 @@ BF_FFMPEG_LIBPATH='${BF_FFMPEG}/lib'
|
|||||||
BF_FFMPEG_LIB = 'avformat-52.lib avcodec-52.lib avdevice-52.lib avutil-50.lib swscale-0.lib'
|
BF_FFMPEG_LIB = 'avformat-52.lib avcodec-52.lib avdevice-52.lib avutil-50.lib swscale-0.lib'
|
||||||
|
|
||||||
BF_PYTHON = LIBDIR + '/python'
|
BF_PYTHON = LIBDIR + '/python'
|
||||||
BF_PYTHON_VERSION = '2.6'
|
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 = 'python26'
|
BF_PYTHON_LIB = 'python31'
|
||||||
BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib'
|
BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib'
|
||||||
|
|
||||||
WITH_BF_OPENAL = True
|
WITH_BF_OPENAL = True
|
||||||
@@ -88,7 +88,7 @@ BF_GETTEXT_LIB = 'gnu_gettext'
|
|||||||
BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib'
|
BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib'
|
||||||
|
|
||||||
WITH_BF_GAMEENGINE = True
|
WITH_BF_GAMEENGINE = True
|
||||||
WITH_BF_PLAYER = True
|
WITH_BF_PLAYER = False
|
||||||
|
|
||||||
WITH_BF_BULLET = True
|
WITH_BF_BULLET = True
|
||||||
BF_BULLET = '#extern/bullet2/src'
|
BF_BULLET = '#extern/bullet2/src'
|
||||||
@@ -149,7 +149,7 @@ BF_OPENGL_LIB_STATIC = [ '${BF_OPENGL}/lib/libGL.a', '${BF_OPENGL}/lib/libGLU.a'
|
|||||||
CC = 'cl.exe'
|
CC = 'cl.exe'
|
||||||
CXX = 'cl.exe'
|
CXX = 'cl.exe'
|
||||||
|
|
||||||
CCFLAGS = ['/nologo', '/Ob1', '/J', '/W3', '/Gd', '/MT']
|
CCFLAGS = ['/nologo', '/Ob1', '/J', '/W3', '/Gd', '/wd4244', '/wd4305', '/wd4800', '/wd4065', '/wd4267']
|
||||||
CXXFLAGS = ['/EHsc']
|
CXXFLAGS = ['/EHsc']
|
||||||
|
|
||||||
BF_DEBUG_CCFLAGS = ['/Zi', '/FR${TARGET}.sbr']
|
BF_DEBUG_CCFLAGS = ['/Zi', '/FR${TARGET}.sbr']
|
||||||
@@ -165,7 +165,7 @@ CXX_WARN = []
|
|||||||
|
|
||||||
LLIBS = ['ws2_32', 'vfw32', 'winmm', 'kernel32', 'user32', 'gdi32', 'comdlg32', 'advapi32', 'shfolder', 'shell32', 'ole32', 'oleaut32', 'uuid']
|
LLIBS = ['ws2_32', 'vfw32', 'winmm', 'kernel32', 'user32', 'gdi32', 'comdlg32', 'advapi32', 'shfolder', 'shell32', 'ole32', 'oleaut32', 'uuid']
|
||||||
|
|
||||||
PLATFORM_LINKFLAGS = ['/SUBSYSTEM:CONSOLE','/MACHINE:IX86','/ENTRY:mainCRTStartup','/INCREMENTAL:NO','/NODEFAULTLIB:"msvcprt.lib"','/NODEFAULTLIB:"glut32.lib"','/NODEFAULTLIB:"libc.lib"','/NODEFAULTLIB:"libcd.lib"','/NODEFAULTLIB:"libcpd.lib"','/NODEFAULTLIB:"libcp.lib"','/LARGEADDRESSAWARE']
|
PLATFORM_LINKFLAGS = ['/SUBSYSTEM:CONSOLE','/MACHINE:IX86','/INCREMENTAL:NO','/NODEFAULTLIB:"msvcprt.lib"','/NODEFAULTLIB:"msvcprtd.lib"','/NODEFAULTLIB:"glut32.lib"','/NODEFAULTLIB:"libc.lib"','/NODEFAULTLIB:"libcd.lib"','/NODEFAULTLIB:"libcpd.lib"','/NODEFAULTLIB:"libcp.lib"','/NODEFAULTLIB:"msvcrt.lib"', '/NODEFAULTLIB:"msvcrtd.lib"', '/NODEFAULTLIB:"msvcmrt.lib"', '/NODEFAULTLIB:"msvcurt.lib"', '/LARGEADDRESSAWARE']
|
||||||
|
|
||||||
# # Todo
|
# # Todo
|
||||||
# BF_PROFILE_CCFLAGS = ['-pg', '-g ']
|
# BF_PROFILE_CCFLAGS = ['-pg', '-g ']
|
||||||
|
|||||||
@@ -9,10 +9,10 @@ BF_FFMPEG_LIBPATH='${BF_FFMPEG}/lib'
|
|||||||
BF_FFMPEG_LIB = 'avformat-52.lib avcodec-51.lib avdevice-52.lib avutil-49.lib swscale-0.lib'
|
BF_FFMPEG_LIB = 'avformat-52.lib avcodec-51.lib avdevice-52.lib avutil-49.lib swscale-0.lib'
|
||||||
|
|
||||||
BF_PYTHON = LIBDIR + '/python'
|
BF_PYTHON = LIBDIR + '/python'
|
||||||
BF_PYTHON_VERSION = '3.0'
|
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 = 'python30'
|
BF_PYTHON_LIB = 'python31'
|
||||||
BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib'
|
BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib'
|
||||||
|
|
||||||
WITH_BF_OPENAL = False
|
WITH_BF_OPENAL = False
|
||||||
@@ -152,7 +152,8 @@ BF_OPENGL_LIB_STATIC = [ '${BF_OPENGL}/lib/libGL.a', '${BF_OPENGL}/lib/libGLU.a'
|
|||||||
CC = 'cl.exe'
|
CC = 'cl.exe'
|
||||||
CXX = 'cl.exe'
|
CXX = 'cl.exe'
|
||||||
|
|
||||||
CCFLAGS = ['/nologo', '/Ob1', '/J', '/W3', '/Gd', '/MT']
|
CFLAGS = []
|
||||||
|
CCFLAGS = ['/nologo', '/Ob1', '/J', '/W3', '/Gd', '/wd4244', '/wd4305', '/wd4800', '/wd4065', '/wd4267']
|
||||||
CXXFLAGS = ['/EHsc']
|
CXXFLAGS = ['/EHsc']
|
||||||
|
|
||||||
BF_DEBUG_CCFLAGS = ['/Zi', '/FR${TARGET}.sbr']
|
BF_DEBUG_CCFLAGS = ['/Zi', '/FR${TARGET}.sbr']
|
||||||
@@ -172,16 +173,13 @@ WITH_BF_DOCS=False
|
|||||||
|
|
||||||
BF_DEBUG=False
|
BF_DEBUG=False
|
||||||
BF_BSC=False
|
BF_BSC=False
|
||||||
CFLAGS = []
|
|
||||||
CCFLAGS = ['/nologo', '/Ob1', '/J', '/W3', '/Gd', '/MT']
|
|
||||||
CXXFLAGS = ['/EHsc']
|
|
||||||
|
|
||||||
if BF_DEBUG:
|
if BF_DEBUG:
|
||||||
BF_NUMJOBS=1
|
BF_NUMJOBS=1
|
||||||
else:
|
else:
|
||||||
BF_NUMJOBS=6
|
BF_NUMJOBS=6
|
||||||
|
|
||||||
PLATFORM_LINKFLAGS = ['/SUBSYSTEM:CONSOLE','/MACHINE:X64','/ENTRY:mainCRTStartup','/INCREMENTAL:NO','/NODEFAULTLIB:"msvcprt.lib"','/NODEFAULTLIB:"glut32.lib"','/NODEFAULTLIB:"libc.lib"','/NODEFAULTLIB:"libcd.lib"','/NODEFAULTLIB:"libcpd.lib"','/NODEFAULTLIB:"libcp.lib"']
|
PLATFORM_LINKFLAGS = ['/SUBSYSTEM:CONSOLE','/MACHINE:X64','/INCREMENTAL:NO','/NODEFAULTLIB:"msvcprt.lib"','/NODEFAULTLIB:"msvcprtd.lib"','/NODEFAULTLIB:"glut32.lib"','/NODEFAULTLIB:"libc.lib"','/NODEFAULTLIB:"libcd.lib"','/NODEFAULTLIB:"libcpd.lib"','/NODEFAULTLIB:"libcp.lib"','/NODEFAULTLIB:"msvcrt.lib"', '/NODEFAULTLIB:"msvcrtd.lib"', '/NODEFAULTLIB:"msvcmrt.lib"', '/NODEFAULTLIB:"msvcurt.lib"']
|
||||||
|
|
||||||
BF_BUILDDIR = '..\\build\\blender25-win64-vc'
|
BF_BUILDDIR = '..\\build\\blender25-win64-vc'
|
||||||
BF_INSTALLDIR='..\\install\\blender25-win64-vc'
|
BF_INSTALLDIR='..\\install\\blender25-win64-vc'
|
||||||
|
|||||||
4
extern/binreloc/CMakeLists.txt
vendored
4
extern/binreloc/CMakeLists.txt
vendored
@@ -18,8 +18,8 @@
|
|||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
|
|
||||||
SET(INC ./include ${WINTAB_INC})
|
SET(INC ./include )
|
||||||
ADD_DEFINITIONS(-DWITH_BINRELOC)
|
ADD_DEFINITIONS(-DENABLE_BINRELOC)
|
||||||
FILE(GLOB SRC *.c)
|
FILE(GLOB SRC *.c)
|
||||||
|
|
||||||
BLENDERLIB(extern_binreloc "${SRC}" "${INC}")
|
BLENDERLIB(extern_binreloc "${SRC}" "${INC}")
|
||||||
|
|||||||
2
extern/binreloc/Makefile
vendored
2
extern/binreloc/Makefile
vendored
@@ -27,7 +27,7 @@ DIR = $(OCGDIR)/extern/$(LIBNAME)
|
|||||||
|
|
||||||
include nan_definitions.mk
|
include nan_definitions.mk
|
||||||
|
|
||||||
CPPFLAGS += -I./include
|
CPPFLAGS += -DENABLE_BINRELOC -I./include
|
||||||
|
|
||||||
|
|
||||||
include nan_compile.mk
|
include nan_compile.mk
|
||||||
|
|||||||
2
extern/bullet2/src/SConscript
vendored
2
extern/bullet2/src/SConscript
vendored
@@ -10,7 +10,7 @@ cflags = []
|
|||||||
if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
|
if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
|
||||||
defs += ' WIN32 NDEBUG _WINDOWS _LIB'
|
defs += ' WIN32 NDEBUG _WINDOWS _LIB'
|
||||||
#cflags += ['/MT', '/W3', '/GX', '/O2', '/Op']
|
#cflags += ['/MT', '/W3', '/GX', '/O2', '/Op']
|
||||||
cflags += ['/MT', '/W3', '/GX', '/Og', '/Ot', '/Ob1', '/Op', '/G6', '/O3']
|
cflags += ['/MT', '/W3', '/GX', '/Og', '/Ot', '/Ob1', '/Op', '/G6', '/O3', '/EHcs']
|
||||||
elif env['OURPLATFORM']=='win32-mingw':
|
elif env['OURPLATFORM']=='win32-mingw':
|
||||||
defs += ' NDEBUG'
|
defs += ' NDEBUG'
|
||||||
cflags += ['-O2']
|
cflags += ['-O2']
|
||||||
|
|||||||
4
extern/libopenjpeg/SConscript
vendored
4
extern/libopenjpeg/SConscript
vendored
@@ -10,14 +10,14 @@ incs = '.'
|
|||||||
flags = []
|
flags = []
|
||||||
defs = []
|
defs = []
|
||||||
|
|
||||||
if env['OURPLATFORM'] == 'win32-vc':
|
if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
|
||||||
flags = []
|
flags = []
|
||||||
defs.append('OPJ_STATIC')
|
defs.append('OPJ_STATIC')
|
||||||
else:
|
else:
|
||||||
flags = ['-Wall', '-O3', '-ffast-math', '-std=c99']
|
flags = ['-Wall', '-O3', '-ffast-math', '-std=c99']
|
||||||
|
|
||||||
oj_env = env.Clone()
|
oj_env = env.Clone()
|
||||||
if not env['OURPLATFORM'] == 'win32-vc':
|
if not env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
|
||||||
oj_env.Replace(CCFLAGS = '')
|
oj_env.Replace(CCFLAGS = '')
|
||||||
oj_env.Replace(BF_DEBUG_FLAGS = '')
|
oj_env.Replace(BF_DEBUG_FLAGS = '')
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ ADD_SUBDIRECTORY(decimation)
|
|||||||
ADD_SUBDIRECTORY(iksolver)
|
ADD_SUBDIRECTORY(iksolver)
|
||||||
ADD_SUBDIRECTORY(boolop)
|
ADD_SUBDIRECTORY(boolop)
|
||||||
ADD_SUBDIRECTORY(opennl)
|
ADD_SUBDIRECTORY(opennl)
|
||||||
|
ADD_SUBDIRECTORY(smoke)
|
||||||
|
|
||||||
IF(WITH_ELBEEM)
|
IF(WITH_ELBEEM)
|
||||||
ADD_SUBDIRECTORY(elbeem)
|
ADD_SUBDIRECTORY(elbeem)
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ SOURCEDIR = intern
|
|||||||
# include nan_subdirs.mk
|
# include nan_subdirs.mk
|
||||||
|
|
||||||
ALLDIRS = string ghost guardedalloc moto container memutil
|
ALLDIRS = string ghost guardedalloc moto container memutil
|
||||||
ALLDIRS += decimation iksolver bsp SoundSystem opennl elbeem boolop
|
ALLDIRS += decimation iksolver bsp SoundSystem opennl elbeem boolop smoke
|
||||||
|
|
||||||
all::
|
all::
|
||||||
@for i in $(ALLDIRS); do \
|
@for i in $(ALLDIRS); do \
|
||||||
|
|||||||
@@ -11,7 +11,8 @@ SConscript(['SoundSystem/SConscript',
|
|||||||
'decimation/SConscript',
|
'decimation/SConscript',
|
||||||
'iksolver/SConscript',
|
'iksolver/SConscript',
|
||||||
'boolop/SConscript',
|
'boolop/SConscript',
|
||||||
'opennl/SConscript'])
|
'opennl/SConscript',
|
||||||
|
'smoke/SConscript'])
|
||||||
|
|
||||||
# NEW_CSG was intended for intern/csg, but
|
# NEW_CSG was intended for intern/csg, but
|
||||||
# getting it to compile is difficult
|
# getting it to compile is difficult
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ defs = 'NOGUI ELBEEM_BLENDER=1'
|
|||||||
if env['WITH_BF_OPENMP']:
|
if env['WITH_BF_OPENMP']:
|
||||||
defs += ' PARALLEL'
|
defs += ' PARALLEL'
|
||||||
|
|
||||||
if env['OURPLATFORM']=='win32-vc':
|
if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
|
||||||
defs += ' USE_MSVC6FIXES'
|
defs += ' USE_MSVC6FIXES'
|
||||||
incs = env['BF_PNG_INC'] + ' ' + env['BF_ZLIB_INC']
|
incs = env['BF_PNG_INC'] + ' ' + env['BF_ZLIB_INC']
|
||||||
incs += ' extern '
|
incs += ' extern '
|
||||||
|
|||||||
@@ -1464,7 +1464,7 @@ void LbmFsgrSolver::initMovingObstacles(bool staticInit) {
|
|||||||
obj->applyTransformation(targetTime, &mMOIVertices,NULL /* no old normals needed */, 0, mMOIVertices.size(), false );
|
obj->applyTransformation(targetTime, &mMOIVertices,NULL /* no old normals needed */, 0, mMOIVertices.size(), false );
|
||||||
} else {
|
} else {
|
||||||
// only do transform update
|
// only do transform update
|
||||||
obj->getMovingPoints(mMOIVertices,pNormals);
|
obj->getMovingPoints(mMOIVertices,pNormals); // mMOIVertices = mCachedMovPoints
|
||||||
mMOIVerticesOld = mMOIVertices;
|
mMOIVerticesOld = mMOIVertices;
|
||||||
// WARNING - assumes mSimulationTime is global!?
|
// WARNING - assumes mSimulationTime is global!?
|
||||||
obj->applyTransformation(targetTime, &mMOIVertices,pNormals, 0, mMOIVertices.size(), false );
|
obj->applyTransformation(targetTime, &mMOIVertices,pNormals, 0, mMOIVertices.size(), false );
|
||||||
|
|||||||
@@ -534,11 +534,28 @@ GHOST_SystemX11::processEvent(XEvent *xe)
|
|||||||
window, data);
|
window, data);
|
||||||
}
|
}
|
||||||
} else if (((Atom)xcme.data.l[0]) == m_wm_take_focus) {
|
} else if (((Atom)xcme.data.l[0]) == m_wm_take_focus) {
|
||||||
|
XWindowAttributes attr;
|
||||||
|
Window fwin;
|
||||||
|
int revert_to;
|
||||||
|
|
||||||
/* as ICCCM say, we need reply this event
|
/* as ICCCM say, we need reply this event
|
||||||
* with a SetInputFocus, the data[1] have
|
* with a SetInputFocus, the data[1] have
|
||||||
* the valid timestamp (send by the wm).
|
* the valid timestamp (send by the wm).
|
||||||
|
*
|
||||||
|
* Some WM send this event before the
|
||||||
|
* window is really mapped (for example
|
||||||
|
* change from virtual desktop), so we need
|
||||||
|
* to be sure that our windows is mapped
|
||||||
|
* or this call fail and close blender.
|
||||||
*/
|
*/
|
||||||
|
if (XGetWindowAttributes(m_display, xcme.window, &attr) == True) {
|
||||||
|
if (XGetInputFocus(m_display, &fwin, &revert_to) == True) {
|
||||||
|
if (attr.map_state == IsViewable) {
|
||||||
|
if (fwin != xcme.window)
|
||||||
XSetInputFocus(m_display, xcme.window, RevertToParent, xcme.data.l[1]);
|
XSetInputFocus(m_display, xcme.window, RevertToParent, xcme.data.l[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Unknown client message, ignore */
|
/* Unknown client message, ignore */
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -117,18 +117,34 @@ GHOST_WindowWin32::GHOST_WindowWin32(
|
|||||||
m_maxPressure(0)
|
m_maxPressure(0)
|
||||||
{
|
{
|
||||||
if (state != GHOST_kWindowStateFullScreen) {
|
if (state != GHOST_kWindowStateFullScreen) {
|
||||||
// take taskbar into account
|
|
||||||
RECT rect;
|
RECT rect;
|
||||||
|
GHOST_TUns32 tw, th;
|
||||||
|
|
||||||
|
width += GetSystemMetrics(SM_CXSIZEFRAME)*2;
|
||||||
|
height += GetSystemMetrics(SM_CYSIZEFRAME)*2 + GetSystemMetrics(SM_CYCAPTION);
|
||||||
|
|
||||||
|
// take taskbar into account
|
||||||
SystemParametersInfo(SPI_GETWORKAREA,0,&rect,0);
|
SystemParametersInfo(SPI_GETWORKAREA,0,&rect,0);
|
||||||
height = rect.bottom - rect.top;
|
th = rect.bottom - rect.top;
|
||||||
width = rect.right - rect.left;
|
tw = rect.right - rect.left;
|
||||||
|
|
||||||
|
if(tw < width)
|
||||||
|
{
|
||||||
|
width = tw;
|
||||||
|
left = rect.left;
|
||||||
|
}
|
||||||
|
if(th < height)
|
||||||
|
{
|
||||||
|
height = th;
|
||||||
|
top = rect.top;
|
||||||
|
}
|
||||||
|
|
||||||
m_hWnd = ::CreateWindow(
|
m_hWnd = ::CreateWindow(
|
||||||
s_windowClassName, // pointer to registered class name
|
s_windowClassName, // pointer to registered class name
|
||||||
title, // pointer to window name
|
title, // pointer to window name
|
||||||
WS_OVERLAPPEDWINDOW, // window style
|
WS_OVERLAPPEDWINDOW, // window style
|
||||||
rect.left, // horizontal position of window
|
left, // horizontal position of window
|
||||||
rect.top, // vertical position of window
|
top, // vertical position of window
|
||||||
width, // window width
|
width, // window width
|
||||||
height, // window height
|
height, // window height
|
||||||
0, // handle to parent or owner window
|
0, // handle to parent or owner window
|
||||||
|
|||||||
24
release/beos-5.0-i386/specific.sh → intern/smoke/CMakeLists.txt
Executable file → Normal file
24
release/beos-5.0-i386/specific.sh → intern/smoke/CMakeLists.txt
Executable file → Normal file
@@ -1,7 +1,4 @@
|
|||||||
#!/bin/sh
|
|
||||||
#
|
|
||||||
# $Id$
|
# $Id$
|
||||||
#
|
|
||||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or
|
# This program is free software; you can redistribute it and/or
|
||||||
@@ -18,19 +15,24 @@
|
|||||||
# along with this program; if not, write to the Free Software Foundation,
|
# along with this program; if not, write to the Free Software Foundation,
|
||||||
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
#
|
#
|
||||||
# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
# The Original Code is Copyright (C) 2006, Blender Foundation
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
# The Original Code is: all of this file.
|
# The Original Code is: all of this file.
|
||||||
#
|
#
|
||||||
# Contributor(s): none yet.
|
# Contributor(s): Daniel Genrich
|
||||||
#
|
#
|
||||||
# ***** END GPL LICENSE BLOCK *****
|
# ***** END GPL LICENSE BLOCK *****
|
||||||
#
|
|
||||||
# OS specific stuff for the package, only to be executed by ../Makefile
|
|
||||||
|
|
||||||
# Add Python .so to package
|
SET(INC ${PNG_INC} ${ZLIB_INC} intern ../../extern/bullet2/src ../memutil ../guardealloc)
|
||||||
cp -f $NAN_PYTHON/lib/libpython$NAN_PYTHON_VERSION.so $DISTDIR/
|
# ${FFTW3_INC}
|
||||||
|
|
||||||
# And create a drag'n'drop symlink for it
|
FILE(GLOB SRC intern/*.cpp)
|
||||||
cd $DISTDIR && ln -s /boot/home/config/lib Drag_libpython$NAN_PYTHON_VERSION.so_here
|
|
||||||
|
IF(WITH_OPENMP)
|
||||||
|
ADD_DEFINITIONS(-DPARALLEL=1)
|
||||||
|
ENDIF(WITH_OPENMP)
|
||||||
|
|
||||||
|
|
||||||
|
BLENDERLIB(bf_smoke "${SRC}" "${INC}")
|
||||||
|
#, libtype='blender', priority = 0 )
|
||||||
54
intern/smoke/Makefile
Normal file
54
intern/smoke/Makefile
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
# -*- mode: gnumakefile; tab-width: 8; indent-tabs-mode: t; -*-
|
||||||
|
# vim: tabstop=8
|
||||||
|
#
|
||||||
|
# $Id$
|
||||||
|
#
|
||||||
|
# ***** 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.
|
||||||
|
#
|
||||||
|
# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# The Original Code is: all of this file.
|
||||||
|
#
|
||||||
|
# Contributor(s): Hans Lambermont, GSR
|
||||||
|
#
|
||||||
|
# ***** END GPL LICENSE BLOCK *****
|
||||||
|
# smoke main makefile.
|
||||||
|
#
|
||||||
|
|
||||||
|
include nan_definitions.mk
|
||||||
|
|
||||||
|
unexport NAN_QUIET
|
||||||
|
|
||||||
|
LIBNAME = smoke
|
||||||
|
SOURCEDIR = intern/$(LIBNAME)
|
||||||
|
DIR = $(OCGDIR)/$(SOURCEDIR)
|
||||||
|
DIRS = intern
|
||||||
|
#not ready yet TESTDIRS = test
|
||||||
|
|
||||||
|
include nan_subdirs.mk
|
||||||
|
|
||||||
|
install: $(ALL_OR_DEBUG)
|
||||||
|
@[ -d $(NAN_SMOKE) ] || mkdir $(NAN_SMOKE)
|
||||||
|
@[ -d $(NAN_SMOKE)/include ] || mkdir $(NAN_SMOKE)/include
|
||||||
|
@[ -d $(NAN_SMOKE)/lib/$(DEBUG_DIR) ] || mkdir $(NAN_SMOKE)/lib/$(DEBUG_DIR)
|
||||||
|
@../tools/cpifdiff.sh $(DIR)/$(DEBUG_DIR)lib$(LIBNAME).a $(NAN_SMOKE)/lib/$(DEBUG_DIR)
|
||||||
|
ifeq ($(OS),darwin)
|
||||||
|
ranlib $(NAN_SMOKE)/lib/$(DEBUG_DIR)lib$(LIBNAME).a
|
||||||
|
endif
|
||||||
|
@../tools/cpifdiff.sh extern/*.h $(NAN_SMOKE)/include/
|
||||||
|
|
||||||
15
intern/smoke/SConscript
Normal file
15
intern/smoke/SConscript
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
Import ('env')
|
||||||
|
|
||||||
|
sources = env.Glob('intern/*.cpp')
|
||||||
|
|
||||||
|
defs = ''
|
||||||
|
|
||||||
|
if env['WITH_BF_OPENMP']:
|
||||||
|
defs += ' PARALLEL=1'
|
||||||
|
|
||||||
|
incs = env['BF_PNG_INC'] + ' ' + env['BF_ZLIB_INC']
|
||||||
|
incs += ' intern ../../extern/bullet2/src ../memutil ../guardealloc '
|
||||||
|
# incs += env['BF_FFTW3_INC']
|
||||||
|
|
||||||
|
env.BlenderLib ('bf_smoke', sources, Split(incs), Split(defs), libtype=['intern'], priority=[40] )
|
||||||
62
intern/smoke/extern/smoke_API.h
vendored
Normal file
62
intern/smoke/extern/smoke_API.h
vendored
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
/**
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* ***** 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.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2009 by Daniel Genrich
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s): None
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SMOKE_API_H_
|
||||||
|
#define SMOKE_API_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct FLUID_3D *smoke_init(int *res, int amplify, float *p0, float *p1, float dt);
|
||||||
|
void smoke_free(struct FLUID_3D *fluid);
|
||||||
|
|
||||||
|
void smoke_initBlenderRNA(struct FLUID_3D *fluid, float *alpha, float *beta);
|
||||||
|
|
||||||
|
void smoke_step(struct FLUID_3D *fluid);
|
||||||
|
|
||||||
|
float *smoke_get_density(struct FLUID_3D *fluid);
|
||||||
|
float *smoke_get_bigdensity(struct FLUID_3D *fluid);
|
||||||
|
float *smoke_get_heat(struct FLUID_3D *fluid);
|
||||||
|
float *smoke_get_velocity_x(struct FLUID_3D *fluid);
|
||||||
|
float *smoke_get_velocity_y(struct FLUID_3D *fluid);
|
||||||
|
float *smoke_get_velocity_z(struct FLUID_3D *fluid);
|
||||||
|
|
||||||
|
unsigned char *smoke_get_obstacle(struct FLUID_3D *fluid);
|
||||||
|
|
||||||
|
size_t smoke_get_index(int x, int max_x, int y, int max_y, int z);
|
||||||
|
size_t smoke_get_index2d(int x, int max_x, int y);
|
||||||
|
|
||||||
|
void smoke_set_noise(struct FLUID_3D *fluid, int type);
|
||||||
|
|
||||||
|
void smoke_get_bigres(struct FLUID_3D *fluid, int *res);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* SMOKE_API_H_ */
|
||||||
47
intern/smoke/intern/EIGENVALUE_HELPER.h
Normal file
47
intern/smoke/intern/EIGENVALUE_HELPER.h
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// This file is part of Wavelet Turbulence.
|
||||||
|
//
|
||||||
|
// Wavelet Turbulence 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 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Wavelet Turbulence 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 Wavelet Turbulence. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// Copyright 2008 Theodore Kim and Nils Thuerey
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// Helper function, compute eigenvalues of 3x3 matrix
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "tnt/jama_eig.h"
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// eigenvalues of 3x3 non-symmetric matrix
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
int inline 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);
|
||||||
|
jeig.getRealEigenvalues(eig);
|
||||||
|
|
||||||
|
// complex ones
|
||||||
|
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
|
||||||
|
#undef ROT
|
||||||
178
intern/smoke/intern/FFT_NOISE.h
Normal file
178
intern/smoke/intern/FFT_NOISE.h
Normal file
@@ -0,0 +1,178 @@
|
|||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// This file is part of Wavelet Turbulence.
|
||||||
|
//
|
||||||
|
// Wavelet Turbulence 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 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Wavelet Turbulence 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 Wavelet Turbulence. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// Copyright 2008 Theodore Kim and Nils Thuerey
|
||||||
|
//
|
||||||
|
/////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef FFT_NOISE_H_
|
||||||
|
#define FFT_NOISE_H_
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
#include <iostream>
|
||||||
|
#include <fftw3.h>
|
||||||
|
#include <MERSENNETWISTER.h>
|
||||||
|
|
||||||
|
#include "WAVELET_NOISE.h"
|
||||||
|
|
||||||
|
#ifndef M_PI
|
||||||
|
#define M_PI 3.14159265
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////
|
||||||
|
// shift spectrum to the format that FFTW expects
|
||||||
|
/////////////////////////////////////////////////////////////////////////
|
||||||
|
static void shift3D(float*& field, int xRes, int yRes, int zRes)
|
||||||
|
{
|
||||||
|
int xHalf = xRes / 2;
|
||||||
|
int yHalf = yRes / 2;
|
||||||
|
int zHalf = zRes / 2;
|
||||||
|
int slabSize = xRes * yRes;
|
||||||
|
for (int z = 0; z < zHalf; z++)
|
||||||
|
for (int y = 0; y < yHalf; y++)
|
||||||
|
for (int x = 0; x < xHalf; x++)
|
||||||
|
{
|
||||||
|
int index = x + y * xRes + z * xRes * yRes;
|
||||||
|
float temp;
|
||||||
|
int xSwap = xHalf;
|
||||||
|
int ySwap = yHalf * xRes;
|
||||||
|
int zSwap = zHalf * xRes * yRes;
|
||||||
|
|
||||||
|
// [0,0,0] to [1,1,1]
|
||||||
|
temp = field[index];
|
||||||
|
field[index] = field[index + xSwap + ySwap + zSwap];
|
||||||
|
field[index + xSwap + ySwap + zSwap] = temp;
|
||||||
|
|
||||||
|
// [1,0,0] to [0,1,1]
|
||||||
|
temp = field[index + xSwap];
|
||||||
|
field[index + xSwap] = field[index + ySwap + zSwap];
|
||||||
|
field[index + ySwap + zSwap] = temp;
|
||||||
|
|
||||||
|
// [0,1,0] to [1,0,1]
|
||||||
|
temp = field[index + ySwap];
|
||||||
|
field[index + ySwap] = field[index + xSwap + zSwap];
|
||||||
|
field[index + xSwap + zSwap] = temp;
|
||||||
|
|
||||||
|
// [0,0,1] to [1,1,0]
|
||||||
|
temp = field[index + zSwap];
|
||||||
|
field[index + zSwap] = field[index + xSwap + ySwap];
|
||||||
|
field[index + xSwap + ySwap] = temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void generatTile_FFT(float* const noiseTileData, std::string filename)
|
||||||
|
{
|
||||||
|
if (loadTile(noiseTileData, filename)) return;
|
||||||
|
|
||||||
|
int res = NOISE_TILE_SIZE;
|
||||||
|
int xRes = res;
|
||||||
|
int yRes = res;
|
||||||
|
int zRes = res;
|
||||||
|
int totalCells = xRes * yRes * zRes;
|
||||||
|
|
||||||
|
// create and shift the filter
|
||||||
|
float* filter = new float[totalCells];
|
||||||
|
for (int z = 0; z < zRes; z++)
|
||||||
|
for (int y = 0; y < yRes; y++)
|
||||||
|
for (int x = 0; x < xRes; x++)
|
||||||
|
{
|
||||||
|
int index = x + y * xRes + z * xRes * yRes;
|
||||||
|
float diff[] = {abs(x - xRes/2),
|
||||||
|
abs(y - yRes/2),
|
||||||
|
abs(z - zRes/2)};
|
||||||
|
float radius = sqrtf(diff[0] * diff[0] +
|
||||||
|
diff[1] * diff[1] +
|
||||||
|
diff[2] * diff[2]) / (xRes / 2);
|
||||||
|
radius *= M_PI;
|
||||||
|
float H = cos((M_PI / 2.0f) * log(4.0f * radius / M_PI) / log(2.0f));
|
||||||
|
H = H * H;
|
||||||
|
float filtered = H;
|
||||||
|
|
||||||
|
// clamp everything outside the wanted band
|
||||||
|
if (radius >= M_PI / 2.0f)
|
||||||
|
filtered = 0.0f;
|
||||||
|
|
||||||
|
// make sure to capture all low frequencies
|
||||||
|
if (radius <= M_PI / 4.0f)
|
||||||
|
filtered = 1.0f;
|
||||||
|
|
||||||
|
filter[index] = filtered;
|
||||||
|
}
|
||||||
|
shift3D(filter, xRes, yRes, zRes);
|
||||||
|
|
||||||
|
// create the noise
|
||||||
|
float* noise = new float[totalCells];
|
||||||
|
int index = 0;
|
||||||
|
MTRand twister;
|
||||||
|
for (int z = 0; z < zRes; z++)
|
||||||
|
for (int y = 0; y < yRes; y++)
|
||||||
|
for (int x = 0; x < xRes; x++, index++)
|
||||||
|
noise[index] = twister.randNorm();
|
||||||
|
|
||||||
|
// create padded field
|
||||||
|
fftw_complex* forward = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * totalCells);
|
||||||
|
|
||||||
|
// init padded field
|
||||||
|
index = 0;
|
||||||
|
for (int z = 0; z < zRes; z++)
|
||||||
|
for (int y = 0; y < yRes; y++)
|
||||||
|
for (int x = 0; x < xRes; x++, index++)
|
||||||
|
{
|
||||||
|
forward[index][0] = noise[index];
|
||||||
|
forward[index][1] = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// forward FFT
|
||||||
|
fftw_complex* backward = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * totalCells);
|
||||||
|
fftw_plan forwardPlan = fftw_plan_dft_3d(xRes, yRes, zRes, forward, backward, FFTW_FORWARD, FFTW_ESTIMATE);
|
||||||
|
fftw_execute(forwardPlan);
|
||||||
|
fftw_destroy_plan(forwardPlan);
|
||||||
|
|
||||||
|
// apply filter
|
||||||
|
index = 0;
|
||||||
|
for (int z = 0; z < zRes; z++)
|
||||||
|
for (int y = 0; y < yRes; y++)
|
||||||
|
for (int x = 0; x < xRes; x++, index++)
|
||||||
|
{
|
||||||
|
backward[index][0] *= filter[index];
|
||||||
|
backward[index][1] *= filter[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
// backward FFT
|
||||||
|
fftw_plan backwardPlan = fftw_plan_dft_3d(xRes, yRes, zRes, backward, forward, FFTW_BACKWARD, FFTW_ESTIMATE);
|
||||||
|
fftw_execute(backwardPlan);
|
||||||
|
fftw_destroy_plan(backwardPlan);
|
||||||
|
|
||||||
|
// subtract out the low frequency components
|
||||||
|
index = 0;
|
||||||
|
for (int z = 0; z < zRes; z++)
|
||||||
|
for (int y = 0; y < yRes; y++)
|
||||||
|
for (int x = 0; x < xRes; x++, index++)
|
||||||
|
noise[index] -= forward[index][0] / totalCells;
|
||||||
|
|
||||||
|
// save out the noise tile
|
||||||
|
saveTile(noise, filename);
|
||||||
|
|
||||||
|
fftw_free(forward);
|
||||||
|
fftw_free(backward);
|
||||||
|
delete[] filter;
|
||||||
|
delete[] noise;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* FFT_NOISE_H_ */
|
||||||
672
intern/smoke/intern/FLUID_3D.cpp
Normal file
672
intern/smoke/intern/FLUID_3D.cpp
Normal file
@@ -0,0 +1,672 @@
|
|||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// This file is part of Wavelet Turbulence.
|
||||||
|
//
|
||||||
|
// Wavelet Turbulence 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 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Wavelet Turbulence 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 Wavelet Turbulence. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// Copyright 2008 Theodore Kim and Nils Thuerey
|
||||||
|
//
|
||||||
|
// FLUID_3D.cpp: implementation of the FLUID_3D class.
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "FLUID_3D.h"
|
||||||
|
#include "IMAGE.h"
|
||||||
|
#include <INTERPOLATE.h>
|
||||||
|
#include "SPHERE.h"
|
||||||
|
#include <zlib.h>
|
||||||
|
|
||||||
|
// boundary conditions of the fluid domain
|
||||||
|
#define DOMAIN_BC_FRONT 1
|
||||||
|
#define DOMAIN_BC_TOP 0
|
||||||
|
#define DOMAIN_BC_LEFT 1
|
||||||
|
#define DOMAIN_BC_BACK DOMAIN_BC_FRONT
|
||||||
|
#define DOMAIN_BC_BOTTOM DOMAIN_BC_TOP
|
||||||
|
#define DOMAIN_BC_RIGHT DOMAIN_BC_LEFT
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// Construction/Destruction
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
FLUID_3D::FLUID_3D(int *res, int amplify, float *p0, float dt) :
|
||||||
|
_xRes(res[0]), _yRes(res[1]), _zRes(res[2]), _res(0.0f), _dt(dt)
|
||||||
|
{
|
||||||
|
// set simulation consts
|
||||||
|
// _dt = dt; // 0.10
|
||||||
|
|
||||||
|
// start point of array
|
||||||
|
_p0[0] = p0[0];
|
||||||
|
_p0[1] = p0[1];
|
||||||
|
_p0[2] = p0[2];
|
||||||
|
|
||||||
|
_iterations = 100;
|
||||||
|
_tempAmb = 0;
|
||||||
|
_heatDiffusion = 1e-3;
|
||||||
|
_vorticityEps = 2.0;
|
||||||
|
_totalTime = 0.0f;
|
||||||
|
_totalSteps = 0;
|
||||||
|
_res = Vec3Int(_xRes,_yRes,_zRes);
|
||||||
|
_maxRes = MAX3(_xRes, _yRes, _zRes);
|
||||||
|
|
||||||
|
// initialize wavelet turbulence
|
||||||
|
_wTurbulence = new WTURBULENCE(_res[0],_res[1],_res[2], amplify);
|
||||||
|
|
||||||
|
// scale the constants according to the refinement of the grid
|
||||||
|
_dx = 1.0f / (float)_maxRes;
|
||||||
|
float scaling = 64.0f / _maxRes;
|
||||||
|
scaling = (scaling < 1.0f) ? 1.0f : scaling;
|
||||||
|
_vorticityEps /= scaling;
|
||||||
|
|
||||||
|
// allocate arrays
|
||||||
|
_totalCells = _xRes * _yRes * _zRes;
|
||||||
|
_slabSize = _xRes * _yRes;
|
||||||
|
_divergence = new float[_totalCells];
|
||||||
|
_pressure = new float[_totalCells];
|
||||||
|
_xVelocity = new float[_totalCells];
|
||||||
|
_yVelocity = new float[_totalCells];
|
||||||
|
_zVelocity = new float[_totalCells];
|
||||||
|
_xVelocityOld = new float[_totalCells];
|
||||||
|
_yVelocityOld = new float[_totalCells];
|
||||||
|
_zVelocityOld = new float[_totalCells];
|
||||||
|
_xForce = new float[_totalCells];
|
||||||
|
_yForce = new float[_totalCells];
|
||||||
|
_zForce = new float[_totalCells];
|
||||||
|
_vorticity = new float[_totalCells];
|
||||||
|
_density = new float[_totalCells];
|
||||||
|
_densityOld = new float[_totalCells];
|
||||||
|
_heat = new float[_totalCells];
|
||||||
|
_heatOld = new float[_totalCells];
|
||||||
|
_residual = new float[_totalCells];
|
||||||
|
_direction = new float[_totalCells];
|
||||||
|
_q = new float[_totalCells];
|
||||||
|
_obstacles = new unsigned char[_totalCells];
|
||||||
|
_xVorticity = new float[_totalCells];
|
||||||
|
_yVorticity = new float[_totalCells];
|
||||||
|
_zVorticity = new float[_totalCells];
|
||||||
|
|
||||||
|
for (int x = 0; x < _totalCells; x++)
|
||||||
|
{
|
||||||
|
_density[x] = 0.0f;
|
||||||
|
_densityOld[x] = 0.0f;
|
||||||
|
_heat[x] = 0.0f;
|
||||||
|
_heatOld[x] = 0.0f;
|
||||||
|
_divergence[x] = 0.0f;
|
||||||
|
_pressure[x] = 0.0f;
|
||||||
|
_xVelocity[x] = 0.0f;
|
||||||
|
_yVelocity[x] = 0.0f;
|
||||||
|
_zVelocity[x] = 0.0f;
|
||||||
|
_xVelocityOld[x] = 0.0f;
|
||||||
|
_yVelocityOld[x] = 0.0f;
|
||||||
|
_zVelocityOld[x] = 0.0f;
|
||||||
|
_xForce[x] = 0.0f;
|
||||||
|
_yForce[x] = 0.0f;
|
||||||
|
_zForce[x] = 0.0f;
|
||||||
|
_xVorticity[x] = 0.0f;
|
||||||
|
_yVorticity[x] = 0.0f;
|
||||||
|
_zVorticity[x] = 0.0f;
|
||||||
|
_residual[x] = 0.0f;
|
||||||
|
_obstacles[x] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set side obstacles
|
||||||
|
int index;
|
||||||
|
for (int y = 0; y < _yRes; y++)
|
||||||
|
for (int x = 0; x < _xRes; x++)
|
||||||
|
{
|
||||||
|
// front slab
|
||||||
|
index = x + y * _xRes;
|
||||||
|
if(DOMAIN_BC_FRONT==1) _obstacles[index] = 1;
|
||||||
|
|
||||||
|
// back slab
|
||||||
|
index += _totalCells - _slabSize;
|
||||||
|
if(DOMAIN_BC_BACK==1) _obstacles[index] = 1;
|
||||||
|
}
|
||||||
|
for (int z = 0; z < _zRes; z++)
|
||||||
|
for (int x = 0; x < _xRes; x++)
|
||||||
|
{
|
||||||
|
// bottom slab
|
||||||
|
index = x + z * _slabSize;
|
||||||
|
if(DOMAIN_BC_BOTTOM==1) _obstacles[index] = 1;
|
||||||
|
|
||||||
|
// top slab
|
||||||
|
index += _slabSize - _xRes;
|
||||||
|
if(DOMAIN_BC_TOP==1) _obstacles[index] = 1;
|
||||||
|
}
|
||||||
|
for (int z = 0; z < _zRes; z++)
|
||||||
|
for (int y = 0; y < _yRes; y++)
|
||||||
|
{
|
||||||
|
// left slab
|
||||||
|
index = y * _xRes + z * _slabSize;
|
||||||
|
if(DOMAIN_BC_LEFT==1) _obstacles[index] = 1;
|
||||||
|
|
||||||
|
// right slab
|
||||||
|
index += _xRes - 1;
|
||||||
|
if(DOMAIN_BC_RIGHT==1) _obstacles[index] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
SPHERE *obsSphere = NULL;
|
||||||
|
obsSphere = new SPHERE(0.375,0.5,0.375, 0.1); // for 4 to 3 domain
|
||||||
|
addObstacle(obsSphere);
|
||||||
|
delete obsSphere;
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
FLUID_3D::~FLUID_3D()
|
||||||
|
{
|
||||||
|
if (_divergence) delete[] _divergence;
|
||||||
|
if (_pressure) delete[] _pressure;
|
||||||
|
if (_xVelocity) delete[] _xVelocity;
|
||||||
|
if (_yVelocity) delete[] _yVelocity;
|
||||||
|
if (_zVelocity) delete[] _zVelocity;
|
||||||
|
if (_xVelocityOld) delete[] _xVelocityOld;
|
||||||
|
if (_yVelocityOld) delete[] _yVelocityOld;
|
||||||
|
if (_zVelocityOld) delete[] _zVelocityOld;
|
||||||
|
if (_xForce) delete[] _xForce;
|
||||||
|
if (_yForce) delete[] _yForce;
|
||||||
|
if (_zForce) delete[] _zForce;
|
||||||
|
if (_residual) delete[] _residual;
|
||||||
|
if (_direction) delete[] _direction;
|
||||||
|
if (_q) delete[] _q;
|
||||||
|
if (_density) delete[] _density;
|
||||||
|
if (_densityOld) delete[] _densityOld;
|
||||||
|
if (_heat) delete[] _heat;
|
||||||
|
if (_heatOld) delete[] _heatOld;
|
||||||
|
if (_xVorticity) delete[] _xVorticity;
|
||||||
|
if (_yVorticity) delete[] _yVorticity;
|
||||||
|
if (_zVorticity) delete[] _zVorticity;
|
||||||
|
if (_vorticity) delete[] _vorticity;
|
||||||
|
if (_obstacles) delete[] _obstacles;
|
||||||
|
if (_wTurbulence) delete _wTurbulence;
|
||||||
|
|
||||||
|
printf("deleted fluid\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// init direct access functions from blender
|
||||||
|
void FLUID_3D::initBlenderRNA(float *alpha, float *beta)
|
||||||
|
{
|
||||||
|
_alpha = alpha;
|
||||||
|
_beta = beta;
|
||||||
|
|
||||||
|
// XXX TODO DEBUG
|
||||||
|
// *_alpha = 0;
|
||||||
|
// *_beta = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// step simulation once
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
void FLUID_3D::step()
|
||||||
|
{
|
||||||
|
// wipe forces
|
||||||
|
for (int i = 0; i < _totalCells; i++)
|
||||||
|
_xForce[i] = _yForce[i] = _zForce[i] = 0.0f;
|
||||||
|
|
||||||
|
wipeBoundaries();
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
_totalSteps++;
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// helper function to dampen co-located grid artifacts of given arrays in intervals
|
||||||
|
// (only needed for velocity, strength (w) depends on testcase...
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
void FLUID_3D::artificialDamping(float* field) {
|
||||||
|
const float w = 0.9;
|
||||||
|
if(_totalSteps % 4 == 1) {
|
||||||
|
for (int z = 1; z < _res[2]-1; z++)
|
||||||
|
for (int y = 1; y < _res[1]-1; y++)
|
||||||
|
for (int x = 1+(y+z)%2; x < _res[0]-1; x+=2) {
|
||||||
|
const int index = x + y*_res[0] + z * _slabSize;
|
||||||
|
field[index] = (1-w)*field[index] + 1./6. * w*(
|
||||||
|
field[index+1] + field[index-1] +
|
||||||
|
field[index+_res[0]] + field[index-_res[0]] +
|
||||||
|
field[index+_slabSize] + field[index-_slabSize] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(_totalSteps % 4 == 3) {
|
||||||
|
for (int z = 1; z < _res[2]-1; z++)
|
||||||
|
for (int y = 1; y < _res[1]-1; y++)
|
||||||
|
for (int x = 1+(y+z+1)%2; x < _res[0]-1; x+=2) {
|
||||||
|
const int index = x + y*_res[0] + z * _slabSize;
|
||||||
|
field[index] = (1-w)*field[index] + 1./6. * w*(
|
||||||
|
field[index+1] + field[index-1] +
|
||||||
|
field[index+_res[0]] + field[index-_res[0]] +
|
||||||
|
field[index+_slabSize] + field[index-_slabSize] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// copy out the boundary in all directions
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
void FLUID_3D::copyBorderAll(float* field)
|
||||||
|
{
|
||||||
|
int index;
|
||||||
|
for (int y = 0; y < _yRes; y++)
|
||||||
|
for (int x = 0; x < _xRes; x++)
|
||||||
|
{
|
||||||
|
// front slab
|
||||||
|
index = x + y * _xRes;
|
||||||
|
field[index] = field[index + _slabSize];
|
||||||
|
|
||||||
|
// back slab
|
||||||
|
index += _totalCells - _slabSize;
|
||||||
|
field[index] = field[index - _slabSize];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int z = 0; z < _zRes; z++)
|
||||||
|
for (int x = 0; x < _xRes; x++)
|
||||||
|
{
|
||||||
|
// bottom slab
|
||||||
|
index = x + z * _slabSize;
|
||||||
|
field[index] = field[index + _xRes];
|
||||||
|
|
||||||
|
// top slab
|
||||||
|
index += _slabSize - _xRes;
|
||||||
|
field[index] = field[index - _xRes];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int z = 0; z < _zRes; z++)
|
||||||
|
for (int y = 0; y < _yRes; y++)
|
||||||
|
{
|
||||||
|
// left slab
|
||||||
|
index = y * _xRes + z * _slabSize;
|
||||||
|
field[index] = field[index + 1];
|
||||||
|
|
||||||
|
// right slab
|
||||||
|
index += _xRes - 1;
|
||||||
|
field[index] = field[index - 1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// wipe boundaries of velocity and density
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
void FLUID_3D::wipeBoundaries()
|
||||||
|
{
|
||||||
|
setZeroBorder(_xVelocity, _res);
|
||||||
|
setZeroBorder(_yVelocity, _res);
|
||||||
|
setZeroBorder(_zVelocity, _res);
|
||||||
|
setZeroBorder(_density, _res);
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// add forces to velocity field
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
void FLUID_3D::addForce()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < _totalCells; i++)
|
||||||
|
{
|
||||||
|
_xVelocity[i] += _dt * _xForce[i];
|
||||||
|
_yVelocity[i] += _dt * _yForce[i];
|
||||||
|
_zVelocity[i] += _dt * _zForce[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// project into divergence free field
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
void FLUID_3D::project()
|
||||||
|
{
|
||||||
|
int index, x, y, z;
|
||||||
|
setObstacleBoundaries();
|
||||||
|
|
||||||
|
// copy out the boundaries
|
||||||
|
if(DOMAIN_BC_LEFT == 0) setNeumannX(_xVelocity, _res);
|
||||||
|
else setZeroX(_xVelocity, _res);
|
||||||
|
|
||||||
|
if(DOMAIN_BC_TOP == 0) setNeumannY(_yVelocity, _res);
|
||||||
|
else setZeroY(_yVelocity, _res);
|
||||||
|
|
||||||
|
if(DOMAIN_BC_FRONT == 0) setNeumannZ(_zVelocity, _res);
|
||||||
|
else setZeroZ(_zVelocity, _res);
|
||||||
|
|
||||||
|
// calculate divergence
|
||||||
|
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++)
|
||||||
|
{
|
||||||
|
float xright = _xVelocity[index + 1];
|
||||||
|
float xleft = _xVelocity[index - 1];
|
||||||
|
float yup = _yVelocity[index + _xRes];
|
||||||
|
float ydown = _yVelocity[index - _xRes];
|
||||||
|
float ztop = _zVelocity[index + _slabSize];
|
||||||
|
float zbottom = _zVelocity[index - _slabSize];
|
||||||
|
|
||||||
|
if(_obstacles[index+1]) xright = - _xVelocity[index];
|
||||||
|
if(_obstacles[index-1]) xleft = - _xVelocity[index];
|
||||||
|
if(_obstacles[index+_xRes]) yup = - _yVelocity[index];
|
||||||
|
if(_obstacles[index-_xRes]) ydown = - _yVelocity[index];
|
||||||
|
if(_obstacles[index+_slabSize]) ztop = - _zVelocity[index];
|
||||||
|
if(_obstacles[index-_slabSize]) zbottom = - _zVelocity[index];
|
||||||
|
|
||||||
|
_divergence[index] = -_dx * 0.5f * (
|
||||||
|
xright - xleft +
|
||||||
|
yup - ydown +
|
||||||
|
ztop - zbottom );
|
||||||
|
_pressure[index] = 0.0f;
|
||||||
|
}
|
||||||
|
copyBorderAll(_pressure);
|
||||||
|
|
||||||
|
// solve Poisson equation
|
||||||
|
solvePressure(_pressure, _divergence, _obstacles);
|
||||||
|
|
||||||
|
// project out solution
|
||||||
|
float invDx = 1.0f / _dx;
|
||||||
|
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++)
|
||||||
|
{
|
||||||
|
_xVelocity[index] -= 0.5f * (_pressure[index + 1] - _pressure[index - 1]) * invDx;
|
||||||
|
_yVelocity[index] -= 0.5f * (_pressure[index + _xRes] - _pressure[index - _xRes]) * invDx;
|
||||||
|
_zVelocity[index] -= 0.5f * (_pressure[index + _slabSize] - _pressure[index - _slabSize]) * invDx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// diffuse heat
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
void FLUID_3D::diffuseHeat()
|
||||||
|
{
|
||||||
|
SWAP_POINTERS(_heat, _heatOld);
|
||||||
|
|
||||||
|
copyBorderAll(_heatOld);
|
||||||
|
solveHeat(_heat, _heatOld, _obstacles);
|
||||||
|
|
||||||
|
// zero out inside obstacles
|
||||||
|
for (int x = 0; x < _totalCells; x++)
|
||||||
|
if (_obstacles[x])
|
||||||
|
_heat[x] = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// stamp an obstacle in the _obstacles field
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
void FLUID_3D::addObstacle(OBSTACLE* obstacle)
|
||||||
|
{
|
||||||
|
int index = 0;
|
||||||
|
for (int z = 0; z < _zRes; z++)
|
||||||
|
for (int y = 0; y < _yRes; y++)
|
||||||
|
for (int x = 0; x < _xRes; x++, index++)
|
||||||
|
if (obstacle->inside(x * _dx, y * _dx, z * _dx)) {
|
||||||
|
_obstacles[index] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// calculate the obstacle directional types
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
void FLUID_3D::setObstacleBoundaries()
|
||||||
|
{
|
||||||
|
// cull degenerate obstacles , move to addObstacle?
|
||||||
|
for (int z = 1, index = _slabSize + _xRes + 1;
|
||||||
|
z < _zRes - 1; z++, index += 2 * _xRes)
|
||||||
|
for (int y = 1; y < _yRes - 1; y++, index += 2)
|
||||||
|
for (int x = 1; x < _xRes - 1; x++, index++)
|
||||||
|
if (_obstacles[index] != EMPTY)
|
||||||
|
{
|
||||||
|
const int top = _obstacles[index + _slabSize];
|
||||||
|
const int bottom= _obstacles[index - _slabSize];
|
||||||
|
const int up = _obstacles[index + _xRes];
|
||||||
|
const int down = _obstacles[index - _xRes];
|
||||||
|
const int left = _obstacles[index - 1];
|
||||||
|
const int right = _obstacles[index + 1];
|
||||||
|
|
||||||
|
int counter = 0;
|
||||||
|
if (up) counter++;
|
||||||
|
if (down) counter++;
|
||||||
|
if (left) counter++;
|
||||||
|
if (right) counter++;
|
||||||
|
if (top) counter++;
|
||||||
|
if (bottom) counter++;
|
||||||
|
|
||||||
|
if (counter < 3)
|
||||||
|
_obstacles[index] = EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
// tag remaining obstacle blocks
|
||||||
|
for (int z = 1, index = _slabSize + _xRes + 1;
|
||||||
|
z < _zRes - 1; z++, index += 2 * _xRes)
|
||||||
|
for (int y = 1; y < _yRes - 1; y++, index += 2)
|
||||||
|
for (int x = 1; x < _xRes - 1; x++, index++)
|
||||||
|
{
|
||||||
|
// could do cascade of ifs, but they are a pain
|
||||||
|
if (_obstacles[index] != EMPTY)
|
||||||
|
{
|
||||||
|
const int top = _obstacles[index + _slabSize];
|
||||||
|
const int bottom= _obstacles[index - _slabSize];
|
||||||
|
const int up = _obstacles[index + _xRes];
|
||||||
|
const int down = _obstacles[index - _xRes];
|
||||||
|
const int left = _obstacles[index - 1];
|
||||||
|
const int right = _obstacles[index + 1];
|
||||||
|
|
||||||
|
// unused
|
||||||
|
// const bool fullz = (top && bottom);
|
||||||
|
// const bool fully = (up && down);
|
||||||
|
//const bool fullx = (left && right);
|
||||||
|
|
||||||
|
_xVelocity[index] =
|
||||||
|
_yVelocity[index] =
|
||||||
|
_zVelocity[index] = 0.0f;
|
||||||
|
_pressure[index] = 0.0f;
|
||||||
|
|
||||||
|
// average pressure neighbors
|
||||||
|
float pcnt = 0.;
|
||||||
|
if (left && !right) {
|
||||||
|
_pressure[index] += _pressure[index + 1];
|
||||||
|
pcnt += 1.;
|
||||||
|
}
|
||||||
|
if (!left && right) {
|
||||||
|
_pressure[index] += _pressure[index - 1];
|
||||||
|
pcnt += 1.;
|
||||||
|
}
|
||||||
|
if (up && !down) {
|
||||||
|
_pressure[index] += _pressure[index - _xRes];
|
||||||
|
pcnt += 1.;
|
||||||
|
}
|
||||||
|
if (!up && down) {
|
||||||
|
_pressure[index] += _pressure[index + _xRes];
|
||||||
|
pcnt += 1.;
|
||||||
|
}
|
||||||
|
if (top && !bottom) {
|
||||||
|
_pressure[index] += _pressure[index - _xRes];
|
||||||
|
pcnt += 1.;
|
||||||
|
}
|
||||||
|
if (!top && bottom) {
|
||||||
|
_pressure[index] += _pressure[index + _xRes];
|
||||||
|
pcnt += 1.;
|
||||||
|
}
|
||||||
|
_pressure[index] /= pcnt;
|
||||||
|
|
||||||
|
// TODO? set correct velocity bc's
|
||||||
|
// velocities are only set to zero right now
|
||||||
|
// this means it's not a full no-slip boundary condition
|
||||||
|
// but a "half-slip" - still looks ok right now
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// add buoyancy forces
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
void FLUID_3D::addBuoyancy(float *heat, float *density)
|
||||||
|
{
|
||||||
|
int index = 0;
|
||||||
|
|
||||||
|
for (int z = 0; z < _zRes; z++)
|
||||||
|
for (int y = 0; y < _yRes; y++)
|
||||||
|
for (int x = 0; x < _xRes; x++, index++)
|
||||||
|
{
|
||||||
|
_zForce[index] += *_alpha * density[index] + (*_beta * (heat[index] - _tempAmb)); // DG: was _yForce, changed for Blender
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// add vorticity to the force field
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
void FLUID_3D::addVorticity()
|
||||||
|
{
|
||||||
|
int x,y,z,index;
|
||||||
|
if(_vorticityEps<=0.) return;
|
||||||
|
|
||||||
|
// calculate vorticity
|
||||||
|
float gridSize = 0.5f / _dx;
|
||||||
|
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++)
|
||||||
|
{
|
||||||
|
int up = _obstacles[index + _xRes] ? index : index + _xRes;
|
||||||
|
int down = _obstacles[index - _xRes] ? index : index - _xRes;
|
||||||
|
float dy = (up == index || down == index) ? 1.0f / _dx : gridSize;
|
||||||
|
int out = _obstacles[index + _slabSize] ? index : index + _slabSize;
|
||||||
|
int in = _obstacles[index - _slabSize] ? index : index - _slabSize;
|
||||||
|
float dz = (out == index || in == index) ? 1.0f / _dx : gridSize;
|
||||||
|
int right = _obstacles[index + 1] ? index : index + 1;
|
||||||
|
int left = _obstacles[index - 1] ? index : index - 1;
|
||||||
|
float dx = (right == index || right == index) ? 1.0f / _dx : gridSize;
|
||||||
|
|
||||||
|
_xVorticity[index] = (_zVelocity[up] - _zVelocity[down]) * dy + (-_yVelocity[out] + _yVelocity[in]) * dz;
|
||||||
|
_yVorticity[index] = (_xVelocity[out] - _xVelocity[in]) * dz + (-_zVelocity[right] + _zVelocity[left]) * dx;
|
||||||
|
_zVorticity[index] = (_yVelocity[right] - _yVelocity[left]) * dx + (-_xVelocity[up] + _xVelocity[down])* dy;
|
||||||
|
|
||||||
|
_vorticity[index] = sqrtf(_xVorticity[index] * _xVorticity[index] +
|
||||||
|
_yVorticity[index] * _yVorticity[index] +
|
||||||
|
_zVorticity[index] * _zVorticity[index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculate normalized vorticity vectors
|
||||||
|
float eps = _vorticityEps;
|
||||||
|
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 (!_obstacles[index])
|
||||||
|
{
|
||||||
|
float N[3];
|
||||||
|
|
||||||
|
int up = _obstacles[index + _xRes] ? index : index + _xRes;
|
||||||
|
int down = _obstacles[index - _xRes] ? index : index - _xRes;
|
||||||
|
float dy = (up == index || down == index) ? 1.0f / _dx : gridSize;
|
||||||
|
int out = _obstacles[index + _slabSize] ? index : index + _slabSize;
|
||||||
|
int in = _obstacles[index - _slabSize] ? index : index - _slabSize;
|
||||||
|
float dz = (out == index || in == index) ? 1.0f / _dx : gridSize;
|
||||||
|
int right = _obstacles[index + 1] ? index : index + 1;
|
||||||
|
int left = _obstacles[index - 1] ? index : index - 1;
|
||||||
|
float dx = (right == index || right == index) ? 1.0f / _dx : gridSize;
|
||||||
|
N[0] = (_vorticity[right] - _vorticity[left]) * dx;
|
||||||
|
N[1] = (_vorticity[up] - _vorticity[down]) * dy;
|
||||||
|
N[2] = (_vorticity[out] - _vorticity[in]) * dz;
|
||||||
|
|
||||||
|
float magnitude = sqrtf(N[0] * N[0] + N[1] * N[1] + N[2] * N[2]);
|
||||||
|
if (magnitude > 0.0f)
|
||||||
|
{
|
||||||
|
magnitude = 1.0f / magnitude;
|
||||||
|
N[0] *= magnitude;
|
||||||
|
N[1] *= magnitude;
|
||||||
|
N[2] *= magnitude;
|
||||||
|
|
||||||
|
_xForce[index] += (N[1] * _zVorticity[index] - N[2] * _yVorticity[index]) * _dx * eps;
|
||||||
|
_yForce[index] -= (N[0] * _zVorticity[index] - N[2] * _xVorticity[index]) * _dx * eps;
|
||||||
|
_zForce[index] += (N[0] * _yVorticity[index] - N[1] * _xVorticity[index]) * _dx * eps;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// Advect using the MacCormack method from the Selle paper
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
void FLUID_3D::advectMacCormack()
|
||||||
|
{
|
||||||
|
Vec3Int res = Vec3Int(_xRes,_yRes,_zRes);
|
||||||
|
|
||||||
|
if(DOMAIN_BC_LEFT == 0) copyBorderX(_xVelocity, res);
|
||||||
|
else setZeroX(_xVelocity, res);
|
||||||
|
|
||||||
|
if(DOMAIN_BC_TOP == 0) copyBorderY(_yVelocity, res);
|
||||||
|
else setZeroY(_yVelocity, res);
|
||||||
|
|
||||||
|
if(DOMAIN_BC_FRONT == 0) copyBorderZ(_zVelocity, res);
|
||||||
|
else setZeroZ(_zVelocity, res);
|
||||||
|
|
||||||
|
SWAP_POINTERS(_xVelocity, _xVelocityOld);
|
||||||
|
SWAP_POINTERS(_yVelocity, _yVelocityOld);
|
||||||
|
SWAP_POINTERS(_zVelocity, _zVelocityOld);
|
||||||
|
SWAP_POINTERS(_density, _densityOld);
|
||||||
|
SWAP_POINTERS(_heat, _heatOld);
|
||||||
|
|
||||||
|
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;
|
||||||
|
float* t2 = _yForce;
|
||||||
|
|
||||||
|
advectFieldMacCormack(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _densityOld, _density, t1,t2, res, NULL);
|
||||||
|
advectFieldMacCormack(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _heatOld, _heat, t1,t2, res, NULL);
|
||||||
|
advectFieldMacCormack(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _xVelocityOld, _xVelocity, t1,t2, res, NULL);
|
||||||
|
advectFieldMacCormack(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _yVelocityOld, _yVelocity, t1,t2, res, NULL);
|
||||||
|
advectFieldMacCormack(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _zVelocityOld, _zVelocity, t1,t2, res, NULL);
|
||||||
|
|
||||||
|
if(DOMAIN_BC_LEFT == 0) copyBorderX(_xVelocity, res);
|
||||||
|
else setZeroX(_xVelocity, res);
|
||||||
|
|
||||||
|
if(DOMAIN_BC_TOP == 0) copyBorderY(_yVelocity, res);
|
||||||
|
else setZeroY(_yVelocity, res);
|
||||||
|
|
||||||
|
if(DOMAIN_BC_FRONT == 0) copyBorderZ(_zVelocity, res);
|
||||||
|
else setZeroZ(_zVelocity, res);
|
||||||
|
|
||||||
|
setZeroBorder(_density, res);
|
||||||
|
setZeroBorder(_heat, res);
|
||||||
|
|
||||||
|
for (int x = 0; x < _totalCells; x++)
|
||||||
|
t1[x] = t2[x] = 0.0;
|
||||||
|
}
|
||||||
175
intern/smoke/intern/FLUID_3D.h
Normal file
175
intern/smoke/intern/FLUID_3D.h
Normal file
@@ -0,0 +1,175 @@
|
|||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// This file is part of Wavelet Turbulence.
|
||||||
|
//
|
||||||
|
// Wavelet Turbulence 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 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Wavelet Turbulence 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 Wavelet Turbulence. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// Copyright 2008 Theodore Kim and Nils Thuerey
|
||||||
|
//
|
||||||
|
// FLUID_3D.h: interface for the FLUID_3D class.
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef FLUID_3D_H
|
||||||
|
#define FLUID_3D_H
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cmath>
|
||||||
|
#include <iostream>
|
||||||
|
#include "OBSTACLE.h"
|
||||||
|
#include "WTURBULENCE.h"
|
||||||
|
#include "VEC3.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace BasicVector;
|
||||||
|
class WTURBULENCE;
|
||||||
|
|
||||||
|
class FLUID_3D
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FLUID_3D(int *res, int amplify, float *p0, float dt);
|
||||||
|
FLUID_3D() {};
|
||||||
|
virtual ~FLUID_3D();
|
||||||
|
|
||||||
|
void initBlenderRNA(float *alpha, float *beta);
|
||||||
|
|
||||||
|
// create & allocate vector noise advection
|
||||||
|
void initVectorNoise(int amplify);
|
||||||
|
|
||||||
|
void addSmokeColumn();
|
||||||
|
static void addSmokeTestCase(float* field, Vec3Int res, float value);
|
||||||
|
|
||||||
|
void step();
|
||||||
|
void addObstacle(OBSTACLE* obstacle);
|
||||||
|
|
||||||
|
const float* xVelocity() { return _xVelocity; };
|
||||||
|
const float* yVelocity() { return _yVelocity; };
|
||||||
|
const float* zVelocity() { return _zVelocity; };
|
||||||
|
|
||||||
|
int xRes() const { return _xRes; };
|
||||||
|
int yRes() const { return _yRes; };
|
||||||
|
int zRes() const { return _zRes; };
|
||||||
|
|
||||||
|
public:
|
||||||
|
// dimensions
|
||||||
|
int _xRes, _yRes, _zRes, _maxRes;
|
||||||
|
Vec3Int _res;
|
||||||
|
int _totalCells;
|
||||||
|
int _slabSize;
|
||||||
|
float _dx;
|
||||||
|
float _p0[3];
|
||||||
|
float _p1[3];
|
||||||
|
float _totalTime;
|
||||||
|
int _totalSteps;
|
||||||
|
int _totalImgDumps;
|
||||||
|
int _totalVelDumps;
|
||||||
|
|
||||||
|
void artificialDamping(float* field);
|
||||||
|
|
||||||
|
// fields
|
||||||
|
float* _density;
|
||||||
|
float* _densityOld;
|
||||||
|
float* _heat;
|
||||||
|
float* _heatOld;
|
||||||
|
float* _pressure;
|
||||||
|
float* _xVelocity;
|
||||||
|
float* _yVelocity;
|
||||||
|
float* _zVelocity;
|
||||||
|
float* _xVelocityOld;
|
||||||
|
float* _yVelocityOld;
|
||||||
|
float* _zVelocityOld;
|
||||||
|
float* _xForce;
|
||||||
|
float* _yForce;
|
||||||
|
float* _zForce;
|
||||||
|
float* _divergence;
|
||||||
|
float* _xVorticity;
|
||||||
|
float* _yVorticity;
|
||||||
|
float* _zVorticity;
|
||||||
|
float* _vorticity;
|
||||||
|
unsigned char* _obstacles;
|
||||||
|
|
||||||
|
// CG fields
|
||||||
|
float* _residual;
|
||||||
|
float* _direction;
|
||||||
|
float* _q;
|
||||||
|
int _iterations;
|
||||||
|
|
||||||
|
// simulation constants
|
||||||
|
float _dt;
|
||||||
|
float _vorticityEps;
|
||||||
|
float _heatDiffusion;
|
||||||
|
float *_alpha; // for the buoyancy density term <-- as pointer to get blender RNA in here
|
||||||
|
float *_beta; // was _buoyancy <-- as pointer to get blender RNA in here
|
||||||
|
float _tempAmb; /* ambient temperature */
|
||||||
|
|
||||||
|
// WTURBULENCE object, if active
|
||||||
|
WTURBULENCE* _wTurbulence;
|
||||||
|
|
||||||
|
// boundary setting functions
|
||||||
|
void copyBorderAll(float* field);
|
||||||
|
|
||||||
|
// timestepping functions
|
||||||
|
void wipeBoundaries();
|
||||||
|
void addForce();
|
||||||
|
void addVorticity();
|
||||||
|
void addBuoyancy(float *heat, float *density);
|
||||||
|
|
||||||
|
// solver stuff
|
||||||
|
void project();
|
||||||
|
void diffuseHeat();
|
||||||
|
void solvePressure(float* field, float* b, unsigned char* skip);
|
||||||
|
void solveHeat(float* field, float* b, unsigned char* skip);
|
||||||
|
|
||||||
|
// handle obstacle boundaries
|
||||||
|
void setObstacleBoundaries();
|
||||||
|
|
||||||
|
public:
|
||||||
|
// advection, accessed e.g. by WTURBULENCE class
|
||||||
|
void advectMacCormack();
|
||||||
|
|
||||||
|
// boundary setting functions
|
||||||
|
static void copyBorderX(float* field, Vec3Int res);
|
||||||
|
static void copyBorderY(float* field, Vec3Int res);
|
||||||
|
static void copyBorderZ(float* field, Vec3Int res);
|
||||||
|
static void setNeumannX(float* field, Vec3Int res);
|
||||||
|
static void setNeumannY(float* field, Vec3Int res);
|
||||||
|
static void setNeumannZ(float* field, Vec3Int res);
|
||||||
|
static void setZeroX(float* field, Vec3Int res);
|
||||||
|
static void setZeroY(float* field, Vec3Int res);
|
||||||
|
static void setZeroZ(float* field, Vec3Int res);
|
||||||
|
static void setZeroBorder(float* field, Vec3Int res) {
|
||||||
|
setZeroX(field, res);
|
||||||
|
setZeroY(field, res);
|
||||||
|
setZeroZ(field, res);
|
||||||
|
};
|
||||||
|
|
||||||
|
// static advection functions, also used by WTURBULENCE
|
||||||
|
static void advectFieldSemiLagrange(const float dt, const float* velx, const float* vely, const float* velz,
|
||||||
|
float* oldField, float* newField, Vec3Int res);
|
||||||
|
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 float* obstacles);
|
||||||
|
|
||||||
|
// maccormack helper functions
|
||||||
|
static void clampExtrema(const float dt, const float* xVelocity, const float* yVelocity, const float* zVelocity,
|
||||||
|
float* oldField, float* newField, Vec3Int res);
|
||||||
|
static void clampOutsideRays(const float dt, const float* xVelocity, const float* yVelocity, const float* zVelocity,
|
||||||
|
float* oldField, float* newField, Vec3Int res, const float* obstacles, const float *oldAdvection);
|
||||||
|
|
||||||
|
// output helper functions
|
||||||
|
// static void writeImageSliceXY(const float *field, Vec3Int res, int slice, string prefix, int picCnt, float scale=1.);
|
||||||
|
// static void writeImageSliceYZ(const float *field, Vec3Int res, int slice, string prefix, int picCnt, float scale=1.);
|
||||||
|
// static void writeImageSliceXZ(const float *field, Vec3Int res, int slice, string prefix, int picCnt, float scale=1.);
|
||||||
|
// static void writeProjectedIntern(const float *field, Vec3Int res, int dir1, int dir2, string prefix, int picCnt, float scale=1.);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
319
intern/smoke/intern/FLUID_3D_SOLVERS.cpp
Normal file
319
intern/smoke/intern/FLUID_3D_SOLVERS.cpp
Normal file
@@ -0,0 +1,319 @@
|
|||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// This file is part of Wavelet Turbulence.
|
||||||
|
//
|
||||||
|
// Wavelet Turbulence 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 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Wavelet Turbulence 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 Wavelet Turbulence. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// Copyright 2008 Theodore Kim and Nils Thuerey
|
||||||
|
//
|
||||||
|
// FLUID_3D.cpp: implementation of the FLUID_3D class.
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "FLUID_3D.h"
|
||||||
|
#define SOLVER_ACCURACY 1e-06
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// solve the poisson equation with CG
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
void FLUID_3D::solvePressure(float* field, float* b, unsigned char* skip)
|
||||||
|
{
|
||||||
|
int x, y, z, index;
|
||||||
|
|
||||||
|
// i = 0
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// solve the heat equation with CG
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
void FLUID_3D::solveHeat(float* field, float* b, unsigned char* skip)
|
||||||
|
{
|
||||||
|
int x, y, z, index;
|
||||||
|
const float heatConst = _dt * _heatDiffusion / (_dx * _dx);
|
||||||
|
|
||||||
|
// i = 0
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
657
intern/smoke/intern/FLUID_3D_STATIC.cpp
Normal file
657
intern/smoke/intern/FLUID_3D_STATIC.cpp
Normal file
@@ -0,0 +1,657 @@
|
|||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// This file is part of Wavelet Turbulence.
|
||||||
|
//
|
||||||
|
// Wavelet Turbulence 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 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Wavelet Turbulence 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 Wavelet Turbulence. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// Copyright 2008 Theodore Kim and Nils Thuerey
|
||||||
|
//
|
||||||
|
// FLUID_3D.cpp: implementation of the static functions of the FLUID_3D class.
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include <zlib.h>
|
||||||
|
#include "FLUID_3D.h"
|
||||||
|
#include "IMAGE.h"
|
||||||
|
#include "WTURBULENCE.h"
|
||||||
|
#include "INTERPOLATE.h"
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// add a test cube of density to the center
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
void FLUID_3D::addSmokeColumn() {
|
||||||
|
addSmokeTestCase(_density, _res, 1.0);
|
||||||
|
// addSmokeTestCase(_zVelocity, _res, 1.0);
|
||||||
|
addSmokeTestCase(_heat, _res, 1.0);
|
||||||
|
if (_wTurbulence) {
|
||||||
|
addSmokeTestCase(_wTurbulence->getDensityBig(), _wTurbulence->getResBig(), 1.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// generic static version, so that it can be applied to the
|
||||||
|
// WTURBULENCE grid as well
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
void FLUID_3D::addSmokeTestCase(float* field, Vec3Int res, float value)
|
||||||
|
{
|
||||||
|
const int slabSize = res[0]*res[1]; int maxRes = (int)MAX3V(res);
|
||||||
|
float dx = 1.0f / (float)maxRes;
|
||||||
|
|
||||||
|
float xTotal = dx * res[0];
|
||||||
|
float yTotal = dx * res[1];
|
||||||
|
float zTotal = dx * res[2];
|
||||||
|
|
||||||
|
float heighMin = 0.05;
|
||||||
|
float heighMax = 0.10;
|
||||||
|
|
||||||
|
for (int y = 0; y < res[1]; y++)
|
||||||
|
for (int z = (int)(heighMin*res[2]); z <= (int)(heighMax * res[1]); z++)
|
||||||
|
for (int x = 0; x < res[0]; x++)
|
||||||
|
{
|
||||||
|
float xLength = x * dx - xTotal * 0.4f;
|
||||||
|
float yLength = y * dx - zTotal * 0.5f;
|
||||||
|
float radius = sqrtf(xLength * xLength + yLength * yLength);
|
||||||
|
|
||||||
|
if (radius < 0.075f * xTotal)
|
||||||
|
{
|
||||||
|
int index = x + y * res[0] + z * slabSize;
|
||||||
|
field[index] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// set x direction to Neumann boundary conditions
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
void FLUID_3D::setNeumannX(float* field, Vec3Int res)
|
||||||
|
{
|
||||||
|
const int slabSize = res[0] * res[1];
|
||||||
|
int index;
|
||||||
|
for (int z = 0; z < res[2]; z++)
|
||||||
|
for (int y = 0; y < res[1]; y++)
|
||||||
|
{
|
||||||
|
// left slab
|
||||||
|
index = y * res[0] + z * slabSize;
|
||||||
|
field[index] = field[index + 2];
|
||||||
|
|
||||||
|
// right slab
|
||||||
|
index += res[0] - 1;
|
||||||
|
field[index] = field[index - 2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// set y direction to Neumann boundary conditions
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
void FLUID_3D::setNeumannY(float* field, Vec3Int res)
|
||||||
|
{
|
||||||
|
const int slabSize = res[0] * res[1];
|
||||||
|
int index;
|
||||||
|
for (int z = 0; z < res[2]; z++)
|
||||||
|
for (int x = 0; x < res[0]; x++)
|
||||||
|
{
|
||||||
|
// bottom slab
|
||||||
|
index = x + z * slabSize;
|
||||||
|
field[index] = field[index + 2 * res[0]];
|
||||||
|
|
||||||
|
// top slab
|
||||||
|
index += slabSize - res[0];
|
||||||
|
field[index] = field[index - 2 * res[0]];
|
||||||
|
}
|
||||||
|
|
||||||
|
// fix, force top slab to only allow outwards flux
|
||||||
|
for (int z = 0; z < res[2]; z++)
|
||||||
|
for (int x = 0; x < res[0]; x++)
|
||||||
|
{
|
||||||
|
// top slab
|
||||||
|
index = x + z * slabSize;
|
||||||
|
index += slabSize - res[0];
|
||||||
|
if(field[index]<0.) field[index] = 0.;
|
||||||
|
index -= res[0];
|
||||||
|
if(field[index]<0.) field[index] = 0.;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// set z direction to Neumann boundary conditions
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
void FLUID_3D::setNeumannZ(float* field, Vec3Int res)
|
||||||
|
{
|
||||||
|
const int slabSize = res[0] * res[1];
|
||||||
|
const int totalCells = res[0] * res[1] * res[2];
|
||||||
|
int index;
|
||||||
|
for (int y = 0; y < res[1]; y++)
|
||||||
|
for (int x = 0; x < res[0]; x++)
|
||||||
|
{
|
||||||
|
// front slab
|
||||||
|
index = x + y * res[0];
|
||||||
|
field[index] = field[index + 2 * slabSize];
|
||||||
|
|
||||||
|
// back slab
|
||||||
|
index += totalCells - slabSize;
|
||||||
|
field[index] = field[index - 2 * slabSize];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// set x direction to zero
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
void FLUID_3D::setZeroX(float* field, Vec3Int res)
|
||||||
|
{
|
||||||
|
const int slabSize = res[0] * res[1];
|
||||||
|
int index;
|
||||||
|
for (int z = 0; z < res[2]; z++)
|
||||||
|
for (int y = 0; y < res[1]; y++)
|
||||||
|
{
|
||||||
|
// left slab
|
||||||
|
index = y * res[0] + z * slabSize;
|
||||||
|
field[index] = 0.0f;
|
||||||
|
|
||||||
|
// right slab
|
||||||
|
index += res[0] - 1;
|
||||||
|
field[index] = 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// set y direction to zero
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
void FLUID_3D::setZeroY(float* field, Vec3Int res)
|
||||||
|
{
|
||||||
|
const int slabSize = res[0] * res[1];
|
||||||
|
int index;
|
||||||
|
for (int z = 0; z < res[2]; z++)
|
||||||
|
for (int x = 0; x < res[0]; x++)
|
||||||
|
{
|
||||||
|
// bottom slab
|
||||||
|
index = x + z * slabSize;
|
||||||
|
field[index] = 0.0f;
|
||||||
|
|
||||||
|
// top slab
|
||||||
|
index += slabSize - res[0];
|
||||||
|
field[index] = 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// set z direction to zero
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
void FLUID_3D::setZeroZ(float* field, Vec3Int res)
|
||||||
|
{
|
||||||
|
const int slabSize = res[0] * res[1];
|
||||||
|
const int totalCells = res[0] * res[1] * res[2];
|
||||||
|
int index;
|
||||||
|
for (int y = 0; y < res[1]; y++)
|
||||||
|
for (int x = 0; x < res[0]; x++)
|
||||||
|
{
|
||||||
|
// front slab
|
||||||
|
index = x + y * res[0];
|
||||||
|
field[index] = 0.0f;
|
||||||
|
|
||||||
|
// back slab
|
||||||
|
index += totalCells - slabSize;
|
||||||
|
field[index] = 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// copy grid boundary
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
void FLUID_3D::copyBorderX(float* field, Vec3Int res)
|
||||||
|
{
|
||||||
|
const int slabSize = res[0] * res[1];
|
||||||
|
int index;
|
||||||
|
for (int z = 0; z < res[2]; z++)
|
||||||
|
for (int y = 0; y < res[1]; y++)
|
||||||
|
{
|
||||||
|
// left slab
|
||||||
|
index = y * res[0] + z * slabSize;
|
||||||
|
field[index] = field[index + 1];
|
||||||
|
|
||||||
|
// right slab
|
||||||
|
index += res[0] - 1;
|
||||||
|
field[index] = field[index - 1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void FLUID_3D::copyBorderY(float* field, Vec3Int res)
|
||||||
|
{
|
||||||
|
const int slabSize = res[0] * res[1];
|
||||||
|
int index;
|
||||||
|
for (int z = 0; z < res[2]; z++)
|
||||||
|
for (int x = 0; x < res[0]; x++)
|
||||||
|
{
|
||||||
|
// bottom slab
|
||||||
|
index = x + z * slabSize;
|
||||||
|
field[index] = field[index + res[0]];
|
||||||
|
// top slab
|
||||||
|
index += slabSize - res[0];
|
||||||
|
field[index] = field[index - res[0]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void FLUID_3D::copyBorderZ(float* field, Vec3Int res)
|
||||||
|
{
|
||||||
|
const int slabSize = res[0] * res[1];
|
||||||
|
const int totalCells = res[0] * res[1] * res[2];
|
||||||
|
int index;
|
||||||
|
for (int y = 0; y < res[1]; y++)
|
||||||
|
for (int x = 0; x < res[0]; x++)
|
||||||
|
{
|
||||||
|
// front slab
|
||||||
|
index = x + y * res[0];
|
||||||
|
field[index] = field[index + slabSize];
|
||||||
|
// back slab
|
||||||
|
index += totalCells - slabSize;
|
||||||
|
field[index] = field[index - slabSize];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
// advect field with the semi lagrangian method
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
void FLUID_3D::advectFieldSemiLagrange(const float dt, const float* velx, const float* vely, const float* velz,
|
||||||
|
float* oldField, float* newField, Vec3Int res)
|
||||||
|
{
|
||||||
|
const int xres = res[0];
|
||||||
|
const int yres = res[1];
|
||||||
|
const int zres = res[2];
|
||||||
|
const int slabSize = res[0] * res[1];
|
||||||
|
|
||||||
|
// scale dt up to grid resolution
|
||||||
|
#if PARALLEL==1
|
||||||
|
#pragma omp parallel for schedule(static)
|
||||||
|
#endif
|
||||||
|
for (int z = 0; z < zres; z++)
|
||||||
|
for (int y = 0; y < yres; y++)
|
||||||
|
for (int x = 0; x < xres; x++)
|
||||||
|
{
|
||||||
|
const int index = x + y * xres + z * xres*yres;
|
||||||
|
|
||||||
|
// backtrace
|
||||||
|
float xTrace = x - dt * velx[index];
|
||||||
|
float yTrace = y - dt * vely[index];
|
||||||
|
float zTrace = z - dt * velz[index];
|
||||||
|
|
||||||
|
// clamp backtrace to grid boundaries
|
||||||
|
if (xTrace < 0.5) xTrace = 0.5;
|
||||||
|
if (xTrace > xres - 1.5) xTrace = xres - 1.5;
|
||||||
|
if (yTrace < 0.5) yTrace = 0.5;
|
||||||
|
if (yTrace > yres - 1.5) yTrace = yres - 1.5;
|
||||||
|
if (zTrace < 0.5) zTrace = 0.5;
|
||||||
|
if (zTrace > zres - 1.5) zTrace = zres - 1.5;
|
||||||
|
|
||||||
|
// locate neighbors to interpolate
|
||||||
|
const int x0 = (int)xTrace;
|
||||||
|
const int x1 = x0 + 1;
|
||||||
|
const int y0 = (int)yTrace;
|
||||||
|
const int y1 = y0 + 1;
|
||||||
|
const int z0 = (int)zTrace;
|
||||||
|
const int z1 = z0 + 1;
|
||||||
|
|
||||||
|
// get interpolation weights
|
||||||
|
const float s1 = xTrace - x0;
|
||||||
|
const float s0 = 1.0f - s1;
|
||||||
|
const float t1 = yTrace - y0;
|
||||||
|
const float t0 = 1.0f - t1;
|
||||||
|
const float u1 = zTrace - z0;
|
||||||
|
const float u0 = 1.0f - u1;
|
||||||
|
|
||||||
|
const int i000 = x0 + y0 * xres + z0 * slabSize;
|
||||||
|
const int i010 = x0 + y1 * xres + z0 * slabSize;
|
||||||
|
const int i100 = x1 + y0 * xres + z0 * slabSize;
|
||||||
|
const int i110 = x1 + y1 * xres + z0 * slabSize;
|
||||||
|
const int i001 = x0 + y0 * xres + z1 * slabSize;
|
||||||
|
const int i011 = x0 + y1 * xres + z1 * slabSize;
|
||||||
|
const int i101 = x1 + y0 * xres + z1 * slabSize;
|
||||||
|
const int i111 = x1 + y1 * xres + z1 * slabSize;
|
||||||
|
|
||||||
|
// interpolate
|
||||||
|
// (indices could be computed once)
|
||||||
|
newField[index] = u0 * (s0 * (t0 * oldField[i000] +
|
||||||
|
t1 * oldField[i010]) +
|
||||||
|
s1 * (t0 * oldField[i100] +
|
||||||
|
t1 * oldField[i110])) +
|
||||||
|
u1 * (s0 * (t0 * oldField[i001] +
|
||||||
|
t1 * oldField[i011]) +
|
||||||
|
s1 * (t0 * oldField[i101] +
|
||||||
|
t1 * oldField[i111]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
// advect field with the maccormack method
|
||||||
|
//
|
||||||
|
// comments are the pseudocode from selle's paper
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
void FLUID_3D::advectFieldMacCormack(const float dt, const float* xVelocity, const float* yVelocity, const float* zVelocity,
|
||||||
|
float* oldField, float* newField, float* temp1, float* temp2, Vec3Int res, const float* obstacles)
|
||||||
|
{
|
||||||
|
float* phiHatN = temp1;
|
||||||
|
float* phiHatN1 = temp2;
|
||||||
|
const int sx= res[0];
|
||||||
|
const int sy= res[1];
|
||||||
|
const int sz= res[2];
|
||||||
|
|
||||||
|
for (int x = 0; x < sx * sy * sz; x++)
|
||||||
|
phiHatN[x] = phiHatN1[x] = oldField[x];
|
||||||
|
|
||||||
|
float*& phiN = oldField;
|
||||||
|
float*& phiN1 = newField;
|
||||||
|
|
||||||
|
// phiHatN1 = A(phiN)
|
||||||
|
advectFieldSemiLagrange( dt, xVelocity, yVelocity, zVelocity, phiN, phiHatN1, res);
|
||||||
|
|
||||||
|
// phiHatN = A^R(phiHatN1)
|
||||||
|
advectFieldSemiLagrange( -1.0*dt, xVelocity, yVelocity, zVelocity, phiHatN1, phiHatN, res);
|
||||||
|
|
||||||
|
// phiN1 = phiHatN1 + (phiN - phiHatN) / 2
|
||||||
|
const int border = 0;
|
||||||
|
for (int z = border; z < sz-border; z++)
|
||||||
|
for (int y = border; y < sy-border; y++)
|
||||||
|
for (int x = border; x < sx-border; x++) {
|
||||||
|
int index = x + y * sx + z * sx*sy;
|
||||||
|
phiN1[index] = phiHatN1[index] + (phiN[index] - phiHatN[index]) * 0.50f;
|
||||||
|
//phiN1[index] = phiHatN1[index]; // debug, correction off
|
||||||
|
}
|
||||||
|
copyBorderX(phiN1, res);
|
||||||
|
copyBorderY(phiN1, res);
|
||||||
|
copyBorderZ(phiN1, res);
|
||||||
|
|
||||||
|
// clamp any newly created extrema
|
||||||
|
clampExtrema(dt, xVelocity, yVelocity, zVelocity, oldField, newField, res);
|
||||||
|
|
||||||
|
// if the error estimate was bad, revert to first order
|
||||||
|
clampOutsideRays(dt, xVelocity, yVelocity, zVelocity, oldField, newField, res, obstacles, phiHatN1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// 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,
|
||||||
|
float* oldField, float* newField, Vec3Int res)
|
||||||
|
{
|
||||||
|
const int xres= res[0];
|
||||||
|
const int yres= res[1];
|
||||||
|
const int zres= res[2];
|
||||||
|
const int slabSize = res[0] * res[1];
|
||||||
|
for (int z = 1; z < zres-1; z++)
|
||||||
|
for (int y = 1; y < yres-1; y++)
|
||||||
|
for (int x = 1; x < xres-1; x++)
|
||||||
|
{
|
||||||
|
const int index = x + y * xres+ z * xres*yres;
|
||||||
|
// backtrace
|
||||||
|
float xTrace = x - dt * velx[index];
|
||||||
|
float yTrace = y - dt * vely[index];
|
||||||
|
float zTrace = z - dt * velz[index];
|
||||||
|
|
||||||
|
// clamp backtrace to grid boundaries
|
||||||
|
if (xTrace < 0.5) xTrace = 0.5;
|
||||||
|
if (xTrace > xres - 1.5) xTrace = xres - 1.5;
|
||||||
|
if (yTrace < 0.5) yTrace = 0.5;
|
||||||
|
if (yTrace > yres - 1.5) yTrace = yres - 1.5;
|
||||||
|
if (zTrace < 0.5) zTrace = 0.5;
|
||||||
|
if (zTrace > zres - 1.5) zTrace = zres - 1.5;
|
||||||
|
|
||||||
|
// locate neighbors to interpolate
|
||||||
|
const int x0 = (int)xTrace;
|
||||||
|
const int x1 = x0 + 1;
|
||||||
|
const int y0 = (int)yTrace;
|
||||||
|
const int y1 = y0 + 1;
|
||||||
|
const int z0 = (int)zTrace;
|
||||||
|
const int z1 = z0 + 1;
|
||||||
|
|
||||||
|
const int i000 = x0 + y0 * xres + z0 * slabSize;
|
||||||
|
const int i010 = x0 + y1 * xres + z0 * slabSize;
|
||||||
|
const int i100 = x1 + y0 * xres + z0 * slabSize;
|
||||||
|
const int i110 = x1 + y1 * xres + z0 * slabSize;
|
||||||
|
const int i001 = x0 + y0 * xres + z1 * slabSize;
|
||||||
|
const int i011 = x0 + y1 * xres + z1 * slabSize;
|
||||||
|
const int i101 = x1 + y0 * xres + z1 * slabSize;
|
||||||
|
const int i111 = x1 + y1 * xres + z1 * slabSize;
|
||||||
|
|
||||||
|
float minField = oldField[i000];
|
||||||
|
float maxField = oldField[i000];
|
||||||
|
|
||||||
|
minField = (oldField[i010] < minField) ? oldField[i010] : minField;
|
||||||
|
maxField = (oldField[i010] > maxField) ? oldField[i010] : maxField;
|
||||||
|
|
||||||
|
minField = (oldField[i100] < minField) ? oldField[i100] : minField;
|
||||||
|
maxField = (oldField[i100] > maxField) ? oldField[i100] : maxField;
|
||||||
|
|
||||||
|
minField = (oldField[i110] < minField) ? oldField[i110] : minField;
|
||||||
|
maxField = (oldField[i110] > maxField) ? oldField[i110] : maxField;
|
||||||
|
|
||||||
|
minField = (oldField[i001] < minField) ? oldField[i001] : minField;
|
||||||
|
maxField = (oldField[i001] > maxField) ? oldField[i001] : maxField;
|
||||||
|
|
||||||
|
minField = (oldField[i011] < minField) ? oldField[i011] : minField;
|
||||||
|
maxField = (oldField[i011] > maxField) ? oldField[i011] : maxField;
|
||||||
|
|
||||||
|
minField = (oldField[i101] < minField) ? oldField[i101] : minField;
|
||||||
|
maxField = (oldField[i101] > maxField) ? oldField[i101] : maxField;
|
||||||
|
|
||||||
|
minField = (oldField[i111] < minField) ? oldField[i111] : minField;
|
||||||
|
maxField = (oldField[i111] > maxField) ? oldField[i111] : maxField;
|
||||||
|
|
||||||
|
newField[index] = (newField[index] > maxField) ? maxField : newField[index];
|
||||||
|
newField[index] = (newField[index] < minField) ? minField : newField[index];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// Reverts any backtraces that go into boundaries back to first
|
||||||
|
// order -- in this case the error correction term was totally
|
||||||
|
// incorrect
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
void FLUID_3D::clampOutsideRays(const float dt, const float* velx, const float* vely, const float* velz,
|
||||||
|
float* oldField, float* newField, Vec3Int res, const float* obstacles, const float *oldAdvection)
|
||||||
|
{
|
||||||
|
const int sx= res[0];
|
||||||
|
const int sy= res[1];
|
||||||
|
const int sz= res[2];
|
||||||
|
const int slabSize = res[0] * res[1];
|
||||||
|
for (int z = 1; z < sz-1; z++)
|
||||||
|
for (int y = 1; y < sy-1; y++)
|
||||||
|
for (int x = 1; x < sx-1; x++)
|
||||||
|
{
|
||||||
|
const int index = x + y * sx+ z * slabSize;
|
||||||
|
// backtrace
|
||||||
|
float xBackward = x + dt * velx[index];
|
||||||
|
float yBackward = y + dt * vely[index];
|
||||||
|
float zBackward = z + dt * velz[index];
|
||||||
|
float xTrace = x - dt * velx[index];
|
||||||
|
float yTrace = y - dt * vely[index];
|
||||||
|
float zTrace = z - dt * velz[index];
|
||||||
|
|
||||||
|
// see if it goes outside the boundaries
|
||||||
|
bool hasObstacle =
|
||||||
|
(zTrace < 1.0f) || (zTrace > sz - 2.0f) ||
|
||||||
|
(yTrace < 1.0f) || (yTrace > sy - 2.0f) ||
|
||||||
|
(xTrace < 1.0f) || (xTrace > sx - 2.0f) ||
|
||||||
|
(zBackward < 1.0f) || (zBackward > sz - 2.0f) ||
|
||||||
|
(yBackward < 1.0f) || (yBackward > sy - 2.0f) ||
|
||||||
|
(xBackward < 1.0f) || (xBackward > sx - 2.0f);
|
||||||
|
// reuse old advection instead of doing another one...
|
||||||
|
if(hasObstacle) { newField[index] = oldAdvection[index]; continue; }
|
||||||
|
|
||||||
|
// clamp to prevent an out of bounds access when looking into
|
||||||
|
// the _obstacles array
|
||||||
|
zTrace = (zTrace < 0.5f) ? 0.5f : zTrace;
|
||||||
|
zTrace = (zTrace > sz - 1.5f) ? sz - 1.5f : zTrace;
|
||||||
|
yTrace = (yTrace < 0.5f) ? 0.5f : yTrace;
|
||||||
|
yTrace = (yTrace > sy - 1.5f) ? sy - 1.5f : yTrace;
|
||||||
|
xTrace = (xTrace < 0.5f) ? 0.5f : xTrace;
|
||||||
|
xTrace = (xTrace > sx - 1.5f) ? sx - 1.5f : xTrace;
|
||||||
|
|
||||||
|
// locate neighbors to interpolate,
|
||||||
|
// do backward first since we will use the forward indices if a
|
||||||
|
// reversion is actually necessary
|
||||||
|
zBackward = (zBackward < 0.5f) ? 0.5f : zBackward;
|
||||||
|
zBackward = (zBackward > sz - 1.5f) ? sz - 1.5f : zBackward;
|
||||||
|
yBackward = (yBackward < 0.5f) ? 0.5f : yBackward;
|
||||||
|
yBackward = (yBackward > sy - 1.5f) ? sy - 1.5f : yBackward;
|
||||||
|
xBackward = (xBackward < 0.5f) ? 0.5f : xBackward;
|
||||||
|
xBackward = (xBackward > sx - 1.5f) ? sx - 1.5f : xBackward;
|
||||||
|
|
||||||
|
int x0 = (int)xBackward;
|
||||||
|
int x1 = x0 + 1;
|
||||||
|
int y0 = (int)yBackward;
|
||||||
|
int y1 = y0 + 1;
|
||||||
|
int z0 = (int)zBackward;
|
||||||
|
int z1 = z0 + 1;
|
||||||
|
if(obstacles && !hasObstacle) {
|
||||||
|
hasObstacle = hasObstacle ||
|
||||||
|
obstacles[x0 + y0 * sx + z0*slabSize] ||
|
||||||
|
obstacles[x0 + y1 * sx + z0*slabSize] ||
|
||||||
|
obstacles[x1 + y0 * sx + z0*slabSize] ||
|
||||||
|
obstacles[x1 + y1 * sx + z0*slabSize] ||
|
||||||
|
obstacles[x0 + y0 * sx + z1*slabSize] ||
|
||||||
|
obstacles[x0 + y1 * sx + z1*slabSize] ||
|
||||||
|
obstacles[x1 + y0 * sx + z1*slabSize] ||
|
||||||
|
obstacles[x1 + y1 * sx + z1*slabSize] ;
|
||||||
|
}
|
||||||
|
// reuse old advection instead of doing another one...
|
||||||
|
if(hasObstacle) { newField[index] = oldAdvection[index]; continue; }
|
||||||
|
|
||||||
|
x0 = (int)xTrace;
|
||||||
|
x1 = x0 + 1;
|
||||||
|
y0 = (int)yTrace;
|
||||||
|
y1 = y0 + 1;
|
||||||
|
z0 = (int)zTrace;
|
||||||
|
z1 = z0 + 1;
|
||||||
|
if(obstacles && !hasObstacle) {
|
||||||
|
hasObstacle = hasObstacle ||
|
||||||
|
obstacles[x0 + y0 * sx + z0*slabSize] ||
|
||||||
|
obstacles[x0 + y1 * sx + z0*slabSize] ||
|
||||||
|
obstacles[x1 + y0 * sx + z0*slabSize] ||
|
||||||
|
obstacles[x1 + y1 * sx + z0*slabSize] ||
|
||||||
|
obstacles[x0 + y0 * sx + z1*slabSize] ||
|
||||||
|
obstacles[x0 + y1 * sx + z1*slabSize] ||
|
||||||
|
obstacles[x1 + y0 * sx + z1*slabSize] ||
|
||||||
|
obstacles[x1 + y1 * sx + z1*slabSize] ;
|
||||||
|
} // obstacle array
|
||||||
|
// reuse old advection instead of doing another one...
|
||||||
|
if(hasObstacle) { newField[index] = oldAdvection[index]; continue; }
|
||||||
|
|
||||||
|
// see if either the forward or backward ray went into
|
||||||
|
// a boundary
|
||||||
|
if (hasObstacle) {
|
||||||
|
// get interpolation weights
|
||||||
|
float s1 = xTrace - x0;
|
||||||
|
float s0 = 1.0f - s1;
|
||||||
|
float t1 = yTrace - y0;
|
||||||
|
float t0 = 1.0f - t1;
|
||||||
|
float u1 = zTrace - z0;
|
||||||
|
float u0 = 1.0f - u1;
|
||||||
|
|
||||||
|
const int i000 = x0 + y0 * sx + z0 * slabSize;
|
||||||
|
const int i010 = x0 + y1 * sx + z0 * slabSize;
|
||||||
|
const int i100 = x1 + y0 * sx + z0 * slabSize;
|
||||||
|
const int i110 = x1 + y1 * sx + z0 * slabSize;
|
||||||
|
const int i001 = x0 + y0 * sx + z1 * slabSize;
|
||||||
|
const int i011 = x0 + y1 * sx + z1 * slabSize;
|
||||||
|
const int i101 = x1 + y0 * sx + z1 * slabSize;
|
||||||
|
const int i111 = x1 + y1 * sx + z1 * slabSize;
|
||||||
|
|
||||||
|
// interpolate, (indices could be computed once)
|
||||||
|
newField[index] = u0 * (s0 * (
|
||||||
|
t0 * oldField[i000] +
|
||||||
|
t1 * oldField[i010]) +
|
||||||
|
s1 * (t0 * oldField[i100] +
|
||||||
|
t1 * oldField[i110])) +
|
||||||
|
u1 * (s0 * (t0 * oldField[i001] +
|
||||||
|
t1 * oldField[i011]) +
|
||||||
|
s1 * (t0 * oldField[i101] +
|
||||||
|
t1 * oldField[i111]));
|
||||||
|
}
|
||||||
|
} // xyz
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// image output
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
void FLUID_3D::writeImageSliceXY(const float *field, Vec3Int res, int slice, string prefix, int picCnt, float scale) {
|
||||||
|
writeProjectedIntern(field, res, 0,1, prefix, picCnt, scale);
|
||||||
|
}
|
||||||
|
void FLUID_3D::writeImageSliceYZ(const float *field, Vec3Int res, int slice, string prefix, int picCnt, float scale) {
|
||||||
|
writeProjectedIntern(field, res, 1,2, prefix, picCnt, scale);
|
||||||
|
}
|
||||||
|
void FLUID_3D::writeImageSliceXZ(const float *field, Vec3Int res, int slice, string prefix, int picCnt, float scale) {
|
||||||
|
writeProjectedIntern(field, res, 0,2, prefix, picCnt, scale);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// Helper function for projecting densities along a dimension
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
static int getOtherDir(int dir1, int dir2) {
|
||||||
|
switch(dir1) {
|
||||||
|
case 0:
|
||||||
|
switch(dir2) {
|
||||||
|
case 1: return 2;
|
||||||
|
case 2: return 1; }
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
switch(dir2) {
|
||||||
|
case 0: return 2;
|
||||||
|
case 2: return 0; }
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
switch(dir2) {
|
||||||
|
case 0: return 1;
|
||||||
|
case 1: return 0; }
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// average densities along third spatial direction
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
void FLUID_3D::writeProjectedIntern(const float *field, Vec3Int res,
|
||||||
|
int dir1, int dir2, string prefix, int picCnt, float scale) {
|
||||||
|
const int nitems = res[dir1]*res[dir2];
|
||||||
|
const int otherDir = getOtherDir(dir1,dir2);
|
||||||
|
float *buf = new float[nitems];
|
||||||
|
Vec3Int min = Vec3Int(0);
|
||||||
|
Vec3Int max = res;
|
||||||
|
|
||||||
|
min[otherDir] = 0;
|
||||||
|
max[otherDir] = res[otherDir];
|
||||||
|
float div = 1./(float)MIN3V(res); // normalize for shorter sides, old: res[otherDir];
|
||||||
|
div *= 4.; //slightly increase contrast
|
||||||
|
for(int i=0; i<nitems; i++) buf[i] = 0.;
|
||||||
|
|
||||||
|
Vec3Int cnt = 0;
|
||||||
|
for (cnt[2] = min[2]; cnt[2] < max[2]; cnt[2]++) {
|
||||||
|
for (cnt[1] = min[1]; cnt[1] < max[1]; cnt[1]++)
|
||||||
|
for (cnt[0] = min[0]; cnt[0] < max[0]; cnt[0]++)
|
||||||
|
{
|
||||||
|
const int index = cnt[0] + cnt[1] * res[0] + cnt[2] * res[0]*res[1];
|
||||||
|
const int bufindex = cnt[dir1] + cnt[dir2] * res[dir1];
|
||||||
|
buf[bufindex] += field[index] * scale *div;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// IMAGE::dumpNumberedPNG(picCnt, prefix, buf, res[dir1], res[dir2]);
|
||||||
|
delete[] buf;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
277
intern/smoke/intern/IMAGE.h
Normal file
277
intern/smoke/intern/IMAGE.h
Normal file
@@ -0,0 +1,277 @@
|
|||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// This file is part of Wavelet Turbulence.
|
||||||
|
//
|
||||||
|
// Wavelet Turbulence 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 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Wavelet Turbulence 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 Wavelet Turbulence. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// Copyright 2008 Theodore Kim and Nils Thuerey
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
#ifndef IMAGE_H
|
||||||
|
#define IMAGE_H
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string>
|
||||||
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <zlib.h>
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// NT helper functions
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
template < class T > inline T ABS( T a ) {
|
||||||
|
return (0 < a) ? a : -a ;
|
||||||
|
}
|
||||||
|
|
||||||
|
template < class T > inline void SWAP_POINTERS( T &a, T &b ) {
|
||||||
|
T temp = a;
|
||||||
|
a = b;
|
||||||
|
b = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
template < class T > inline void CLAMP( T &a, T b=0., T c=1.) {
|
||||||
|
if(a<b) { a=b; return; }
|
||||||
|
if(a>c) { a=c; return; }
|
||||||
|
}
|
||||||
|
|
||||||
|
template < class T > inline T MIN( T a, T b) {
|
||||||
|
return (a < b) ? a : b;
|
||||||
|
}
|
||||||
|
|
||||||
|
template < class T > inline T MAX( T a, T b) {
|
||||||
|
return (a > b) ? a : b;
|
||||||
|
}
|
||||||
|
|
||||||
|
template < class T > inline T MAX3( T a, T b, T c) {
|
||||||
|
T max = (a > b) ? a : b;
|
||||||
|
max = (max > c) ? max : c;
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
|
||||||
|
template < class T > inline float MAX3V( T vec) {
|
||||||
|
float max = (vec[0] > vec[1]) ? vec[0] : vec[1];
|
||||||
|
max = (max > vec[2]) ? max : vec[2];
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
|
||||||
|
template < class T > inline float MIN3V( T vec) {
|
||||||
|
float min = (vec[0] < vec[1]) ? vec[0] : vec[1];
|
||||||
|
min = (min < vec[2]) ? min : vec[2];
|
||||||
|
return min;
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// PNG, POV-Ray, and PBRT output functions
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
#include <png.h>
|
||||||
|
|
||||||
|
namespace IMAGE {
|
||||||
|
/*
|
||||||
|
static int writePng(const char *fileName, unsigned char **rowsp, int w, int h)
|
||||||
|
{
|
||||||
|
// defaults
|
||||||
|
const int colortype = PNG_COLOR_TYPE_RGBA;
|
||||||
|
const int bitdepth = 8;
|
||||||
|
png_structp png_ptr = NULL;
|
||||||
|
png_infop info_ptr = NULL;
|
||||||
|
png_bytep *rows = rowsp;
|
||||||
|
|
||||||
|
FILE *fp = NULL;
|
||||||
|
std::string doing = "open for writing";
|
||||||
|
if (!(fp = fopen(fileName, "wb"))) goto fail;
|
||||||
|
|
||||||
|
if(!png_ptr) {
|
||||||
|
doing = "create png write struct";
|
||||||
|
if (!(png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL))) goto fail;
|
||||||
|
}
|
||||||
|
if(!info_ptr) {
|
||||||
|
doing = "create png info struct";
|
||||||
|
if (!(info_ptr = png_create_info_struct(png_ptr))) goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (setjmp(png_jmpbuf(png_ptr))) goto fail;
|
||||||
|
doing = "init IO";
|
||||||
|
png_init_io(png_ptr, fp);
|
||||||
|
doing = "write header";
|
||||||
|
png_set_IHDR(png_ptr, info_ptr, w, h, bitdepth, colortype, PNG_INTERLACE_NONE,
|
||||||
|
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
|
||||||
|
doing = "write info";
|
||||||
|
png_write_info(png_ptr, info_ptr);
|
||||||
|
doing = "write image";
|
||||||
|
png_write_image(png_ptr, rows);
|
||||||
|
doing = "write end";
|
||||||
|
png_write_end(png_ptr, NULL);
|
||||||
|
doing = "write destroy structs";
|
||||||
|
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||||
|
|
||||||
|
fclose( fp );
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
std::cerr << "writePng: could not "<<doing<<" !\n";
|
||||||
|
if(fp) fclose( fp );
|
||||||
|
if(png_ptr || info_ptr) png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// write a numbered PNG file out, padded with zeros up to three zeros
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
static void dumpNumberedPNG(int counter, std::string prefix, float* field, int xRes, int yRes)
|
||||||
|
{
|
||||||
|
char buffer[256];
|
||||||
|
sprintf(buffer,"%04i", counter);
|
||||||
|
std::string number = std::string(buffer);
|
||||||
|
|
||||||
|
unsigned char pngbuf[xRes*yRes*4];
|
||||||
|
unsigned char *rows[yRes];
|
||||||
|
float *pfield = field;
|
||||||
|
for (int j=0; j<yRes; j++) {
|
||||||
|
for (int i=0; i<xRes; i++) {
|
||||||
|
float val = *pfield;
|
||||||
|
if(val>1.) val=1.;
|
||||||
|
if(val<0.) val=0.;
|
||||||
|
pngbuf[(j*xRes+i)*4+0] = (unsigned char)(val*255.);
|
||||||
|
pngbuf[(j*xRes+i)*4+1] = (unsigned char)(val*255.);
|
||||||
|
pngbuf[(j*xRes+i)*4+2] = (unsigned char)(val*255.);
|
||||||
|
pfield++;
|
||||||
|
pngbuf[(j*xRes+i)*4+3] = 255;
|
||||||
|
}
|
||||||
|
rows[j] = &pngbuf[(yRes-j-1)*xRes*4];
|
||||||
|
}
|
||||||
|
std::string filenamePNG = prefix + number + std::string(".png");
|
||||||
|
writePng(filenamePNG.c_str(), rows, xRes, yRes, false);
|
||||||
|
printf("Writing %s\n", filenamePNG.c_str());
|
||||||
|
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// export pbrt volumegrid geometry object
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
static void dumpPBRT(int counter, std::string prefix, float* fieldOrg, int xRes, int yRes, int zRes)
|
||||||
|
{
|
||||||
|
char buffer[256];
|
||||||
|
sprintf(buffer,"%04i", counter);
|
||||||
|
std::string number = std::string(buffer);
|
||||||
|
|
||||||
|
std::string filenamePbrt = prefix + number + std::string(".pbrt.gz");
|
||||||
|
printf("Writing PBRT %s\n", filenamePbrt.c_str());
|
||||||
|
|
||||||
|
float *field = new float[xRes*yRes*zRes];
|
||||||
|
// normalize values
|
||||||
|
float maxDensVal = ABS(fieldOrg[0]);
|
||||||
|
float targetNorm = 0.5;
|
||||||
|
for (int i = 0; i < xRes * yRes * zRes; i++) {
|
||||||
|
if(ABS(fieldOrg[i])>maxDensVal) maxDensVal = ABS(fieldOrg[i]);
|
||||||
|
field[i] = 0.;
|
||||||
|
}
|
||||||
|
if(maxDensVal>0.) {
|
||||||
|
for (int i = 0; i < xRes * yRes * zRes; i++) {
|
||||||
|
field[i] = ABS(fieldOrg[i]) / maxDensVal * targetNorm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::fstream fout;
|
||||||
|
fout.open(filenamePbrt.c_str(), std::ios::out);
|
||||||
|
|
||||||
|
int maxRes = (xRes > yRes) ? xRes : yRes;
|
||||||
|
maxRes = (maxRes > zRes) ? maxRes : zRes;
|
||||||
|
|
||||||
|
const float xSize = 1.0 / (float)maxRes * (float)xRes;
|
||||||
|
const float ySize = 1.0 / (float)maxRes * (float)yRes;
|
||||||
|
const float zSize = 1.0 / (float)maxRes * (float)zRes;
|
||||||
|
|
||||||
|
gzFile file;
|
||||||
|
file = gzopen(filenamePbrt.c_str(), "wb1");
|
||||||
|
if (file == NULL) {
|
||||||
|
std::cerr << " Couldn't write file " << filenamePbrt << "!!!" << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// dimensions
|
||||||
|
gzprintf(file, "Volume \"volumegrid\" \n");
|
||||||
|
gzprintf(file, " \"integer nx\" %i\n", xRes);
|
||||||
|
gzprintf(file, " \"integer ny\" %i\n", yRes);
|
||||||
|
gzprintf(file, " \"integer nz\" %i\n", zRes);
|
||||||
|
gzprintf(file, " \"point p0\" [ 0.0 0.0 0.0 ] \"point p1\" [%f %f %f ] \n", xSize, ySize, zSize);
|
||||||
|
gzprintf(file, " \"float density\" [ \n");
|
||||||
|
for (int i = 0; i < xRes * yRes * zRes; i++)
|
||||||
|
gzprintf(file, "%f ", field[i]);
|
||||||
|
gzprintf(file, "] \n \n");
|
||||||
|
|
||||||
|
gzclose(file);
|
||||||
|
delete[] field;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// 3D df3 export
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
static void dumpDF3(int counter, std::string prefix, float* fieldOrg, int xRes, int yRes, int zRes)
|
||||||
|
{
|
||||||
|
char buffer[256];
|
||||||
|
|
||||||
|
// do deferred copying to final directory, better for network directories
|
||||||
|
sprintf(buffer,"%04i", counter);
|
||||||
|
std::string number = std::string(buffer);
|
||||||
|
std::string filenameDf3 = prefix + number + std::string(".df3.gz");
|
||||||
|
printf("Writing DF3 %s\n", filenameDf3.c_str());
|
||||||
|
|
||||||
|
gzFile file;
|
||||||
|
file = gzopen(filenameDf3.c_str(), "wb1");
|
||||||
|
if (file == NULL) {
|
||||||
|
std::cerr << " Couldn't write file " << filenameDf3 << "!!!" << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// dimensions
|
||||||
|
const int byteSize = 2;
|
||||||
|
const unsigned short int onx=xRes,ony=yRes,onz=zRes;
|
||||||
|
unsigned short int nx,ny,nz;
|
||||||
|
nx = onx >> 8;
|
||||||
|
ny = ony >> 8;
|
||||||
|
nz = onz >> 8;
|
||||||
|
nx += (onx << 8);
|
||||||
|
ny += (ony << 8);
|
||||||
|
nz += (onz << 8);
|
||||||
|
gzwrite(file, (void*)&nx, sizeof(short));
|
||||||
|
gzwrite(file, (void*)&ny, sizeof(short));
|
||||||
|
gzwrite(file, (void*)&nz, sizeof(short));
|
||||||
|
const int nitems = onx*ony*onz;
|
||||||
|
const float mul = (float)( (1<<(8*byteSize))-1);
|
||||||
|
|
||||||
|
unsigned short int *buf = new unsigned short int[nitems];
|
||||||
|
for (int k = 0; k < onz; k++)
|
||||||
|
for (int j = 0; j < ony; j++)
|
||||||
|
for (int i = 0; i < onx; i++) {
|
||||||
|
float val = fieldOrg[k*(onx*ony)+j*onx+i] ;
|
||||||
|
CLAMP(val);
|
||||||
|
buf[k*(onx*ony)+j*onx+i] = (short int)(val*mul);
|
||||||
|
}
|
||||||
|
gzwrite(file, (void*)buf, sizeof(unsigned short int)* nitems);
|
||||||
|
|
||||||
|
gzclose(file);
|
||||||
|
delete[] buf;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
227
intern/smoke/intern/INTERPOLATE.h
Normal file
227
intern/smoke/intern/INTERPOLATE.h
Normal file
@@ -0,0 +1,227 @@
|
|||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// This file is part of Wavelet Turbulence.
|
||||||
|
//
|
||||||
|
// Wavelet Turbulence 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 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Wavelet Turbulence 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 Wavelet Turbulence. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// Copyright 2008 Theodore Kim and Nils Thuerey
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
#ifndef INTERPOLATE_H
|
||||||
|
#define INTERPOLATE_H
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <VEC3.h>
|
||||||
|
|
||||||
|
namespace INTERPOLATE {
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// linear interpolators
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
static inline float lerp(float t, float a, float b) {
|
||||||
|
return ( a + t * (b - a) );
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline float lerp(float* field, float x, float y, int res) {
|
||||||
|
// clamp backtrace to grid boundaries
|
||||||
|
if (x < 0.5f) x = 0.5f;
|
||||||
|
if (x > res - 1.5f) x = res - 1.5f;
|
||||||
|
if (y < 0.5f) y = 0.5f;
|
||||||
|
if (y > res - 1.5f) y = res - 1.5f;
|
||||||
|
|
||||||
|
const int x0 = (int)x;
|
||||||
|
const int y0 = (int)y;
|
||||||
|
x -= x0;
|
||||||
|
y -= y0;
|
||||||
|
float d00, d10, d01, d11;
|
||||||
|
|
||||||
|
// lerp the velocities
|
||||||
|
d00 = field[x0 + y0 * res];
|
||||||
|
d10 = field[(x0 + 1) + y0 * res];
|
||||||
|
d01 = field[x0 + (y0 + 1) * res];
|
||||||
|
d11 = field[(x0 + 1) + (y0 + 1) * res];
|
||||||
|
return lerp(y, lerp(x, d00, d10),
|
||||||
|
lerp(x, d01, d11));
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// 3d linear interpolation
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
static inline float lerp3d(float* field, float x, float y, float z, int xres, int yres, int zres) {
|
||||||
|
// clamp pos to grid boundaries
|
||||||
|
if (x < 0.5) x = 0.5;
|
||||||
|
if (x > xres - 1.5) x = xres - 1.5;
|
||||||
|
if (y < 0.5) y = 0.5;
|
||||||
|
if (y > yres - 1.5) y = yres - 1.5;
|
||||||
|
if (z < 0.5) z = 0.5;
|
||||||
|
if (z > zres - 1.5) z = zres - 1.5;
|
||||||
|
|
||||||
|
// locate neighbors to interpolate
|
||||||
|
const int x0 = (int)x;
|
||||||
|
const int x1 = x0 + 1;
|
||||||
|
const int y0 = (int)y;
|
||||||
|
const int y1 = y0 + 1;
|
||||||
|
const int z0 = (int)z;
|
||||||
|
const int z1 = z0 + 1;
|
||||||
|
|
||||||
|
// get interpolation weights
|
||||||
|
const float s1 = x - (float)x0;
|
||||||
|
const float s0 = 1.0f - s1;
|
||||||
|
const float t1 = y - (float)y0;
|
||||||
|
const float t0 = 1.0f - t1;
|
||||||
|
const float u1 = z - (float)z0;
|
||||||
|
const float u0 = 1.0f - u1;
|
||||||
|
|
||||||
|
const int slabSize = xres*yres;
|
||||||
|
const int i000 = x0 + y0 * xres + z0 * slabSize;
|
||||||
|
const int i010 = x0 + y1 * xres + z0 * slabSize;
|
||||||
|
const int i100 = x1 + y0 * xres + z0 * slabSize;
|
||||||
|
const int i110 = x1 + y1 * xres + z0 * slabSize;
|
||||||
|
const int i001 = x0 + y0 * xres + z1 * slabSize;
|
||||||
|
const int i011 = x0 + y1 * xres + z1 * slabSize;
|
||||||
|
const int i101 = x1 + y0 * xres + z1 * slabSize;
|
||||||
|
const int i111 = x1 + y1 * xres + z1 * slabSize;
|
||||||
|
|
||||||
|
// interpolate (indices could be computed once)
|
||||||
|
return ( u0 * (s0 * (t0 * field[i000] +
|
||||||
|
t1 * field[i010]) +
|
||||||
|
s1 * (t0 * field[i100] +
|
||||||
|
t1 * field[i110])) +
|
||||||
|
u1 * (s0 * (t0 * field[i001] +
|
||||||
|
t1 * field[i011]) +
|
||||||
|
s1 * (t0 * field[i101] +
|
||||||
|
t1 * field[i111])) );
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// convert field entries of type T to floats, then interpolate
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
template <class T>
|
||||||
|
static inline float lerp3dToFloat(T* field1,
|
||||||
|
float x, float y, float z, int xres, int yres, int zres) {
|
||||||
|
// clamp pos to grid boundaries
|
||||||
|
if (x < 0.5) x = 0.5;
|
||||||
|
if (x > xres - 1.5) x = xres - 1.5;
|
||||||
|
if (y < 0.5) y = 0.5;
|
||||||
|
if (y > yres - 1.5) y = yres - 1.5;
|
||||||
|
if (z < 0.5) z = 0.5;
|
||||||
|
if (z > zres - 1.5) z = zres - 1.5;
|
||||||
|
|
||||||
|
// locate neighbors to interpolate
|
||||||
|
const int x0 = (int)x;
|
||||||
|
const int x1 = x0 + 1;
|
||||||
|
const int y0 = (int)y;
|
||||||
|
const int y1 = y0 + 1;
|
||||||
|
const int z0 = (int)z;
|
||||||
|
const int z1 = z0 + 1;
|
||||||
|
|
||||||
|
// get interpolation weights
|
||||||
|
const float s1 = x - (float)x0;
|
||||||
|
const float s0 = 1.0f - s1;
|
||||||
|
const float t1 = y - (float)y0;
|
||||||
|
const float t0 = 1.0f - t1;
|
||||||
|
const float u1 = z - (float)z0;
|
||||||
|
const float u0 = 1.0f - u1;
|
||||||
|
|
||||||
|
const int slabSize = xres*yres;
|
||||||
|
const int i000 = x0 + y0 * xres + z0 * slabSize;
|
||||||
|
const int i010 = x0 + y1 * xres + z0 * slabSize;
|
||||||
|
const int i100 = x1 + y0 * xres + z0 * slabSize;
|
||||||
|
const int i110 = x1 + y1 * xres + z0 * slabSize;
|
||||||
|
const int i001 = x0 + y0 * xres + z1 * slabSize;
|
||||||
|
const int i011 = x0 + y1 * xres + z1 * slabSize;
|
||||||
|
const int i101 = x1 + y0 * xres + z1 * slabSize;
|
||||||
|
const int i111 = x1 + y1 * xres + z1 * slabSize;
|
||||||
|
|
||||||
|
// interpolate (indices could be computed once)
|
||||||
|
return (float)(
|
||||||
|
( u0 * (s0 * (t0 * (float)field1[i000] +
|
||||||
|
t1 * (float)field1[i010]) +
|
||||||
|
s1 * (t0 * (float)field1[i100] +
|
||||||
|
t1 * (float)field1[i110])) +
|
||||||
|
u1 * (s0 * (t0 * (float)field1[i001] +
|
||||||
|
t1 * (float)field1[i011]) +
|
||||||
|
s1 * (t0 * (float)field1[i101] +
|
||||||
|
t1 * (float)field1[i111])) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// interpolate a vector from 3 fields
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
static inline Vec3 lerp3dVec(float* field1, float* field2, float* field3,
|
||||||
|
float x, float y, float z, int xres, int yres, int zres) {
|
||||||
|
// clamp pos to grid boundaries
|
||||||
|
if (x < 0.5) x = 0.5;
|
||||||
|
if (x > xres - 1.5) x = xres - 1.5;
|
||||||
|
if (y < 0.5) y = 0.5;
|
||||||
|
if (y > yres - 1.5) y = yres - 1.5;
|
||||||
|
if (z < 0.5) z = 0.5;
|
||||||
|
if (z > zres - 1.5) z = zres - 1.5;
|
||||||
|
|
||||||
|
// locate neighbors to interpolate
|
||||||
|
const int x0 = (int)x;
|
||||||
|
const int x1 = x0 + 1;
|
||||||
|
const int y0 = (int)y;
|
||||||
|
const int y1 = y0 + 1;
|
||||||
|
const int z0 = (int)z;
|
||||||
|
const int z1 = z0 + 1;
|
||||||
|
|
||||||
|
// get interpolation weights
|
||||||
|
const float s1 = x - (float)x0;
|
||||||
|
const float s0 = 1.0f - s1;
|
||||||
|
const float t1 = y - (float)y0;
|
||||||
|
const float t0 = 1.0f - t1;
|
||||||
|
const float u1 = z - (float)z0;
|
||||||
|
const float u0 = 1.0f - u1;
|
||||||
|
|
||||||
|
const int slabSize = xres*yres;
|
||||||
|
const int i000 = x0 + y0 * xres + z0 * slabSize;
|
||||||
|
const int i010 = x0 + y1 * xres + z0 * slabSize;
|
||||||
|
const int i100 = x1 + y0 * xres + z0 * slabSize;
|
||||||
|
const int i110 = x1 + y1 * xres + z0 * slabSize;
|
||||||
|
const int i001 = x0 + y0 * xres + z1 * slabSize;
|
||||||
|
const int i011 = x0 + y1 * xres + z1 * slabSize;
|
||||||
|
const int i101 = x1 + y0 * xres + z1 * slabSize;
|
||||||
|
const int i111 = x1 + y1 * xres + z1 * slabSize;
|
||||||
|
|
||||||
|
// interpolate (indices could be computed once)
|
||||||
|
return Vec3(
|
||||||
|
( u0 * (s0 * (t0 * field1[i000] +
|
||||||
|
t1 * field1[i010]) +
|
||||||
|
s1 * (t0 * field1[i100] +
|
||||||
|
t1 * field1[i110])) +
|
||||||
|
u1 * (s0 * (t0 * field1[i001] +
|
||||||
|
t1 * field1[i011]) +
|
||||||
|
s1 * (t0 * field1[i101] +
|
||||||
|
t1 * field1[i111])) ) ,
|
||||||
|
( u0 * (s0 * (t0 * field2[i000] +
|
||||||
|
t1 * field2[i010]) +
|
||||||
|
s1 * (t0 * field2[i100] +
|
||||||
|
t1 * field2[i110])) +
|
||||||
|
u1 * (s0 * (t0 * field2[i001] +
|
||||||
|
t1 * field2[i011]) +
|
||||||
|
s1 * (t0 * field2[i101] +
|
||||||
|
t1 * field2[i111])) ) ,
|
||||||
|
( u0 * (s0 * (t0 * field3[i000] +
|
||||||
|
t1 * field3[i010]) +
|
||||||
|
s1 * (t0 * field3[i100] +
|
||||||
|
t1 * field3[i110])) +
|
||||||
|
u1 * (s0 * (t0 * field3[i001] +
|
||||||
|
t1 * field3[i011]) +
|
||||||
|
s1 * (t0 * field3[i101] +
|
||||||
|
t1 * field3[i111])) )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
#endif
|
||||||
674
intern/smoke/intern/LICENSE.txt
Normal file
674
intern/smoke/intern/LICENSE.txt
Normal file
@@ -0,0 +1,674 @@
|
|||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 3, 29 June 2007
|
||||||
|
|
||||||
|
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The GNU General Public License is a free, copyleft license for
|
||||||
|
software and other kinds of works.
|
||||||
|
|
||||||
|
The licenses for most software and other practical works are designed
|
||||||
|
to take away your freedom to share and change the works. By contrast,
|
||||||
|
the GNU General Public License is intended to guarantee your freedom to
|
||||||
|
share and change all versions of a program--to make sure it remains free
|
||||||
|
software for all its users. We, the Free Software Foundation, use the
|
||||||
|
GNU General Public License for most of our software; it applies also to
|
||||||
|
any other work released this way by its authors. You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
them if you wish), that you receive source code or can get it if you
|
||||||
|
want it, that you can change the software or use pieces of it in new
|
||||||
|
free programs, and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to prevent others from denying you
|
||||||
|
these rights or asking you to surrender the rights. Therefore, you have
|
||||||
|
certain responsibilities if you distribute copies of the software, or if
|
||||||
|
you modify it: responsibilities to respect the freedom of others.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must pass on to the recipients the same
|
||||||
|
freedoms that you received. You must make sure that they, too, receive
|
||||||
|
or can get the source code. And you must show them these terms so they
|
||||||
|
know their rights.
|
||||||
|
|
||||||
|
Developers that use the GNU GPL protect your rights with two steps:
|
||||||
|
(1) assert copyright on the software, and (2) offer you this License
|
||||||
|
giving you legal permission to copy, distribute and/or modify it.
|
||||||
|
|
||||||
|
For the developers' and authors' protection, the GPL clearly explains
|
||||||
|
that there is no warranty for this free software. For both users' and
|
||||||
|
authors' sake, the GPL requires that modified versions be marked as
|
||||||
|
changed, so that their problems will not be attributed erroneously to
|
||||||
|
authors of previous versions.
|
||||||
|
|
||||||
|
Some devices are designed to deny users access to install or run
|
||||||
|
modified versions of the software inside them, although the manufacturer
|
||||||
|
can do so. This is fundamentally incompatible with the aim of
|
||||||
|
protecting users' freedom to change the software. The systematic
|
||||||
|
pattern of such abuse occurs in the area of products for individuals to
|
||||||
|
use, which is precisely where it is most unacceptable. Therefore, we
|
||||||
|
have designed this version of the GPL to prohibit the practice for those
|
||||||
|
products. If such problems arise substantially in other domains, we
|
||||||
|
stand ready to extend this provision to those domains in future versions
|
||||||
|
of the GPL, as needed to protect the freedom of users.
|
||||||
|
|
||||||
|
Finally, every program is threatened constantly by software patents.
|
||||||
|
States should not allow patents to restrict development and use of
|
||||||
|
software on general-purpose computers, but in those that do, we wish to
|
||||||
|
avoid the special danger that patents applied to a free program could
|
||||||
|
make it effectively proprietary. To prevent this, the GPL assures that
|
||||||
|
patents cannot be used to render the program non-free.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
0. Definitions.
|
||||||
|
|
||||||
|
"This License" refers to version 3 of the GNU General Public License.
|
||||||
|
|
||||||
|
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||||
|
works, such as semiconductor masks.
|
||||||
|
|
||||||
|
"The Program" refers to any copyrightable work licensed under this
|
||||||
|
License. Each licensee is addressed as "you". "Licensees" and
|
||||||
|
"recipients" may be individuals or organizations.
|
||||||
|
|
||||||
|
To "modify" a work means to copy from or adapt all or part of the work
|
||||||
|
in a fashion requiring copyright permission, other than the making of an
|
||||||
|
exact copy. The resulting work is called a "modified version" of the
|
||||||
|
earlier work or a work "based on" the earlier work.
|
||||||
|
|
||||||
|
A "covered work" means either the unmodified Program or a work based
|
||||||
|
on the Program.
|
||||||
|
|
||||||
|
To "propagate" a work means to do anything with it that, without
|
||||||
|
permission, would make you directly or secondarily liable for
|
||||||
|
infringement under applicable copyright law, except executing it on a
|
||||||
|
computer or modifying a private copy. Propagation includes copying,
|
||||||
|
distribution (with or without modification), making available to the
|
||||||
|
public, and in some countries other activities as well.
|
||||||
|
|
||||||
|
To "convey" a work means any kind of propagation that enables other
|
||||||
|
parties to make or receive copies. Mere interaction with a user through
|
||||||
|
a computer network, with no transfer of a copy, is not conveying.
|
||||||
|
|
||||||
|
An interactive user interface displays "Appropriate Legal Notices"
|
||||||
|
to the extent that it includes a convenient and prominently visible
|
||||||
|
feature that (1) displays an appropriate copyright notice, and (2)
|
||||||
|
tells the user that there is no warranty for the work (except to the
|
||||||
|
extent that warranties are provided), that licensees may convey the
|
||||||
|
work under this License, and how to view a copy of this License. If
|
||||||
|
the interface presents a list of user commands or options, such as a
|
||||||
|
menu, a prominent item in the list meets this criterion.
|
||||||
|
|
||||||
|
1. Source Code.
|
||||||
|
|
||||||
|
The "source code" for a work means the preferred form of the work
|
||||||
|
for making modifications to it. "Object code" means any non-source
|
||||||
|
form of a work.
|
||||||
|
|
||||||
|
A "Standard Interface" means an interface that either is an official
|
||||||
|
standard defined by a recognized standards body, or, in the case of
|
||||||
|
interfaces specified for a particular programming language, one that
|
||||||
|
is widely used among developers working in that language.
|
||||||
|
|
||||||
|
The "System Libraries" of an executable work include anything, other
|
||||||
|
than the work as a whole, that (a) is included in the normal form of
|
||||||
|
packaging a Major Component, but which is not part of that Major
|
||||||
|
Component, and (b) serves only to enable use of the work with that
|
||||||
|
Major Component, or to implement a Standard Interface for which an
|
||||||
|
implementation is available to the public in source code form. A
|
||||||
|
"Major Component", in this context, means a major essential component
|
||||||
|
(kernel, window system, and so on) of the specific operating system
|
||||||
|
(if any) on which the executable work runs, or a compiler used to
|
||||||
|
produce the work, or an object code interpreter used to run it.
|
||||||
|
|
||||||
|
The "Corresponding Source" for a work in object code form means all
|
||||||
|
the source code needed to generate, install, and (for an executable
|
||||||
|
work) run the object code and to modify the work, including scripts to
|
||||||
|
control those activities. However, it does not include the work's
|
||||||
|
System Libraries, or general-purpose tools or generally available free
|
||||||
|
programs which are used unmodified in performing those activities but
|
||||||
|
which are not part of the work. For example, Corresponding Source
|
||||||
|
includes interface definition files associated with source files for
|
||||||
|
the work, and the source code for shared libraries and dynamically
|
||||||
|
linked subprograms that the work is specifically designed to require,
|
||||||
|
such as by intimate data communication or control flow between those
|
||||||
|
subprograms and other parts of the work.
|
||||||
|
|
||||||
|
The Corresponding Source need not include anything that users
|
||||||
|
can regenerate automatically from other parts of the Corresponding
|
||||||
|
Source.
|
||||||
|
|
||||||
|
The Corresponding Source for a work in source code form is that
|
||||||
|
same work.
|
||||||
|
|
||||||
|
2. Basic Permissions.
|
||||||
|
|
||||||
|
All rights granted under this License are granted for the term of
|
||||||
|
copyright on the Program, and are irrevocable provided the stated
|
||||||
|
conditions are met. This License explicitly affirms your unlimited
|
||||||
|
permission to run the unmodified Program. The output from running a
|
||||||
|
covered work is covered by this License only if the output, given its
|
||||||
|
content, constitutes a covered work. This License acknowledges your
|
||||||
|
rights of fair use or other equivalent, as provided by copyright law.
|
||||||
|
|
||||||
|
You may make, run and propagate covered works that you do not
|
||||||
|
convey, without conditions so long as your license otherwise remains
|
||||||
|
in force. You may convey covered works to others for the sole purpose
|
||||||
|
of having them make modifications exclusively for you, or provide you
|
||||||
|
with facilities for running those works, provided that you comply with
|
||||||
|
the terms of this License in conveying all material for which you do
|
||||||
|
not control copyright. Those thus making or running the covered works
|
||||||
|
for you must do so exclusively on your behalf, under your direction
|
||||||
|
and control, on terms that prohibit them from making any copies of
|
||||||
|
your copyrighted material outside their relationship with you.
|
||||||
|
|
||||||
|
Conveying under any other circumstances is permitted solely under
|
||||||
|
the conditions stated below. Sublicensing is not allowed; section 10
|
||||||
|
makes it unnecessary.
|
||||||
|
|
||||||
|
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||||
|
|
||||||
|
No covered work shall be deemed part of an effective technological
|
||||||
|
measure under any applicable law fulfilling obligations under article
|
||||||
|
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||||
|
similar laws prohibiting or restricting circumvention of such
|
||||||
|
measures.
|
||||||
|
|
||||||
|
When you convey a covered work, you waive any legal power to forbid
|
||||||
|
circumvention of technological measures to the extent such circumvention
|
||||||
|
is effected by exercising rights under this License with respect to
|
||||||
|
the covered work, and you disclaim any intention to limit operation or
|
||||||
|
modification of the work as a means of enforcing, against the work's
|
||||||
|
users, your or third parties' legal rights to forbid circumvention of
|
||||||
|
technological measures.
|
||||||
|
|
||||||
|
4. Conveying Verbatim Copies.
|
||||||
|
|
||||||
|
You may convey verbatim copies of the Program's source code as you
|
||||||
|
receive it, in any medium, provided that you conspicuously and
|
||||||
|
appropriately publish on each copy an appropriate copyright notice;
|
||||||
|
keep intact all notices stating that this License and any
|
||||||
|
non-permissive terms added in accord with section 7 apply to the code;
|
||||||
|
keep intact all notices of the absence of any warranty; and give all
|
||||||
|
recipients a copy of this License along with the Program.
|
||||||
|
|
||||||
|
You may charge any price or no price for each copy that you convey,
|
||||||
|
and you may offer support or warranty protection for a fee.
|
||||||
|
|
||||||
|
5. Conveying Modified Source Versions.
|
||||||
|
|
||||||
|
You may convey a work based on the Program, or the modifications to
|
||||||
|
produce it from the Program, in the form of source code under the
|
||||||
|
terms of section 4, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) The work must carry prominent notices stating that you modified
|
||||||
|
it, and giving a relevant date.
|
||||||
|
|
||||||
|
b) The work must carry prominent notices stating that it is
|
||||||
|
released under this License and any conditions added under section
|
||||||
|
7. This requirement modifies the requirement in section 4 to
|
||||||
|
"keep intact all notices".
|
||||||
|
|
||||||
|
c) You must license the entire work, as a whole, under this
|
||||||
|
License to anyone who comes into possession of a copy. This
|
||||||
|
License will therefore apply, along with any applicable section 7
|
||||||
|
additional terms, to the whole of the work, and all its parts,
|
||||||
|
regardless of how they are packaged. This License gives no
|
||||||
|
permission to license the work in any other way, but it does not
|
||||||
|
invalidate such permission if you have separately received it.
|
||||||
|
|
||||||
|
d) If the work has interactive user interfaces, each must display
|
||||||
|
Appropriate Legal Notices; however, if the Program has interactive
|
||||||
|
interfaces that do not display Appropriate Legal Notices, your
|
||||||
|
work need not make them do so.
|
||||||
|
|
||||||
|
A compilation of a covered work with other separate and independent
|
||||||
|
works, which are not by their nature extensions of the covered work,
|
||||||
|
and which are not combined with it such as to form a larger program,
|
||||||
|
in or on a volume of a storage or distribution medium, is called an
|
||||||
|
"aggregate" if the compilation and its resulting copyright are not
|
||||||
|
used to limit the access or legal rights of the compilation's users
|
||||||
|
beyond what the individual works permit. Inclusion of a covered work
|
||||||
|
in an aggregate does not cause this License to apply to the other
|
||||||
|
parts of the aggregate.
|
||||||
|
|
||||||
|
6. Conveying Non-Source Forms.
|
||||||
|
|
||||||
|
You may convey a covered work in object code form under the terms
|
||||||
|
of sections 4 and 5, provided that you also convey the
|
||||||
|
machine-readable Corresponding Source under the terms of this License,
|
||||||
|
in one of these ways:
|
||||||
|
|
||||||
|
a) Convey the object code in, or embodied in, a physical product
|
||||||
|
(including a physical distribution medium), accompanied by the
|
||||||
|
Corresponding Source fixed on a durable physical medium
|
||||||
|
customarily used for software interchange.
|
||||||
|
|
||||||
|
b) Convey the object code in, or embodied in, a physical product
|
||||||
|
(including a physical distribution medium), accompanied by a
|
||||||
|
written offer, valid for at least three years and valid for as
|
||||||
|
long as you offer spare parts or customer support for that product
|
||||||
|
model, to give anyone who possesses the object code either (1) a
|
||||||
|
copy of the Corresponding Source for all the software in the
|
||||||
|
product that is covered by this License, on a durable physical
|
||||||
|
medium customarily used for software interchange, for a price no
|
||||||
|
more than your reasonable cost of physically performing this
|
||||||
|
conveying of source, or (2) access to copy the
|
||||||
|
Corresponding Source from a network server at no charge.
|
||||||
|
|
||||||
|
c) Convey individual copies of the object code with a copy of the
|
||||||
|
written offer to provide the Corresponding Source. This
|
||||||
|
alternative is allowed only occasionally and noncommercially, and
|
||||||
|
only if you received the object code with such an offer, in accord
|
||||||
|
with subsection 6b.
|
||||||
|
|
||||||
|
d) Convey the object code by offering access from a designated
|
||||||
|
place (gratis or for a charge), and offer equivalent access to the
|
||||||
|
Corresponding Source in the same way through the same place at no
|
||||||
|
further charge. You need not require recipients to copy the
|
||||||
|
Corresponding Source along with the object code. If the place to
|
||||||
|
copy the object code is a network server, the Corresponding Source
|
||||||
|
may be on a different server (operated by you or a third party)
|
||||||
|
that supports equivalent copying facilities, provided you maintain
|
||||||
|
clear directions next to the object code saying where to find the
|
||||||
|
Corresponding Source. Regardless of what server hosts the
|
||||||
|
Corresponding Source, you remain obligated to ensure that it is
|
||||||
|
available for as long as needed to satisfy these requirements.
|
||||||
|
|
||||||
|
e) Convey the object code using peer-to-peer transmission, provided
|
||||||
|
you inform other peers where the object code and Corresponding
|
||||||
|
Source of the work are being offered to the general public at no
|
||||||
|
charge under subsection 6d.
|
||||||
|
|
||||||
|
A separable portion of the object code, whose source code is excluded
|
||||||
|
from the Corresponding Source as a System Library, need not be
|
||||||
|
included in conveying the object code work.
|
||||||
|
|
||||||
|
A "User Product" is either (1) a "consumer product", which means any
|
||||||
|
tangible personal property which is normally used for personal, family,
|
||||||
|
or household purposes, or (2) anything designed or sold for incorporation
|
||||||
|
into a dwelling. In determining whether a product is a consumer product,
|
||||||
|
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||||
|
product received by a particular user, "normally used" refers to a
|
||||||
|
typical or common use of that class of product, regardless of the status
|
||||||
|
of the particular user or of the way in which the particular user
|
||||||
|
actually uses, or expects or is expected to use, the product. A product
|
||||||
|
is a consumer product regardless of whether the product has substantial
|
||||||
|
commercial, industrial or non-consumer uses, unless such uses represent
|
||||||
|
the only significant mode of use of the product.
|
||||||
|
|
||||||
|
"Installation Information" for a User Product means any methods,
|
||||||
|
procedures, authorization keys, or other information required to install
|
||||||
|
and execute modified versions of a covered work in that User Product from
|
||||||
|
a modified version of its Corresponding Source. The information must
|
||||||
|
suffice to ensure that the continued functioning of the modified object
|
||||||
|
code is in no case prevented or interfered with solely because
|
||||||
|
modification has been made.
|
||||||
|
|
||||||
|
If you convey an object code work under this section in, or with, or
|
||||||
|
specifically for use in, a User Product, and the conveying occurs as
|
||||||
|
part of a transaction in which the right of possession and use of the
|
||||||
|
User Product is transferred to the recipient in perpetuity or for a
|
||||||
|
fixed term (regardless of how the transaction is characterized), the
|
||||||
|
Corresponding Source conveyed under this section must be accompanied
|
||||||
|
by the Installation Information. But this requirement does not apply
|
||||||
|
if neither you nor any third party retains the ability to install
|
||||||
|
modified object code on the User Product (for example, the work has
|
||||||
|
been installed in ROM).
|
||||||
|
|
||||||
|
The requirement to provide Installation Information does not include a
|
||||||
|
requirement to continue to provide support service, warranty, or updates
|
||||||
|
for a work that has been modified or installed by the recipient, or for
|
||||||
|
the User Product in which it has been modified or installed. Access to a
|
||||||
|
network may be denied when the modification itself materially and
|
||||||
|
adversely affects the operation of the network or violates the rules and
|
||||||
|
protocols for communication across the network.
|
||||||
|
|
||||||
|
Corresponding Source conveyed, and Installation Information provided,
|
||||||
|
in accord with this section must be in a format that is publicly
|
||||||
|
documented (and with an implementation available to the public in
|
||||||
|
source code form), and must require no special password or key for
|
||||||
|
unpacking, reading or copying.
|
||||||
|
|
||||||
|
7. Additional Terms.
|
||||||
|
|
||||||
|
"Additional permissions" are terms that supplement the terms of this
|
||||||
|
License by making exceptions from one or more of its conditions.
|
||||||
|
Additional permissions that are applicable to the entire Program shall
|
||||||
|
be treated as though they were included in this License, to the extent
|
||||||
|
that they are valid under applicable law. If additional permissions
|
||||||
|
apply only to part of the Program, that part may be used separately
|
||||||
|
under those permissions, but the entire Program remains governed by
|
||||||
|
this License without regard to the additional permissions.
|
||||||
|
|
||||||
|
When you convey a copy of a covered work, you may at your option
|
||||||
|
remove any additional permissions from that copy, or from any part of
|
||||||
|
it. (Additional permissions may be written to require their own
|
||||||
|
removal in certain cases when you modify the work.) You may place
|
||||||
|
additional permissions on material, added by you to a covered work,
|
||||||
|
for which you have or can give appropriate copyright permission.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, for material you
|
||||||
|
add to a covered work, you may (if authorized by the copyright holders of
|
||||||
|
that material) supplement the terms of this License with terms:
|
||||||
|
|
||||||
|
a) Disclaiming warranty or limiting liability differently from the
|
||||||
|
terms of sections 15 and 16 of this License; or
|
||||||
|
|
||||||
|
b) Requiring preservation of specified reasonable legal notices or
|
||||||
|
author attributions in that material or in the Appropriate Legal
|
||||||
|
Notices displayed by works containing it; or
|
||||||
|
|
||||||
|
c) Prohibiting misrepresentation of the origin of that material, or
|
||||||
|
requiring that modified versions of such material be marked in
|
||||||
|
reasonable ways as different from the original version; or
|
||||||
|
|
||||||
|
d) Limiting the use for publicity purposes of names of licensors or
|
||||||
|
authors of the material; or
|
||||||
|
|
||||||
|
e) Declining to grant rights under trademark law for use of some
|
||||||
|
trade names, trademarks, or service marks; or
|
||||||
|
|
||||||
|
f) Requiring indemnification of licensors and authors of that
|
||||||
|
material by anyone who conveys the material (or modified versions of
|
||||||
|
it) with contractual assumptions of liability to the recipient, for
|
||||||
|
any liability that these contractual assumptions directly impose on
|
||||||
|
those licensors and authors.
|
||||||
|
|
||||||
|
All other non-permissive additional terms are considered "further
|
||||||
|
restrictions" within the meaning of section 10. If the Program as you
|
||||||
|
received it, or any part of it, contains a notice stating that it is
|
||||||
|
governed by this License along with a term that is a further
|
||||||
|
restriction, you may remove that term. If a license document contains
|
||||||
|
a further restriction but permits relicensing or conveying under this
|
||||||
|
License, you may add to a covered work material governed by the terms
|
||||||
|
of that license document, provided that the further restriction does
|
||||||
|
not survive such relicensing or conveying.
|
||||||
|
|
||||||
|
If you add terms to a covered work in accord with this section, you
|
||||||
|
must place, in the relevant source files, a statement of the
|
||||||
|
additional terms that apply to those files, or a notice indicating
|
||||||
|
where to find the applicable terms.
|
||||||
|
|
||||||
|
Additional terms, permissive or non-permissive, may be stated in the
|
||||||
|
form of a separately written license, or stated as exceptions;
|
||||||
|
the above requirements apply either way.
|
||||||
|
|
||||||
|
8. Termination.
|
||||||
|
|
||||||
|
You may not propagate or modify a covered work except as expressly
|
||||||
|
provided under this License. Any attempt otherwise to propagate or
|
||||||
|
modify it is void, and will automatically terminate your rights under
|
||||||
|
this License (including any patent licenses granted under the third
|
||||||
|
paragraph of section 11).
|
||||||
|
|
||||||
|
However, if you cease all violation of this License, then your
|
||||||
|
license from a particular copyright holder is reinstated (a)
|
||||||
|
provisionally, unless and until the copyright holder explicitly and
|
||||||
|
finally terminates your license, and (b) permanently, if the copyright
|
||||||
|
holder fails to notify you of the violation by some reasonable means
|
||||||
|
prior to 60 days after the cessation.
|
||||||
|
|
||||||
|
Moreover, your license from a particular copyright holder is
|
||||||
|
reinstated permanently if the copyright holder notifies you of the
|
||||||
|
violation by some reasonable means, this is the first time you have
|
||||||
|
received notice of violation of this License (for any work) from that
|
||||||
|
copyright holder, and you cure the violation prior to 30 days after
|
||||||
|
your receipt of the notice.
|
||||||
|
|
||||||
|
Termination of your rights under this section does not terminate the
|
||||||
|
licenses of parties who have received copies or rights from you under
|
||||||
|
this License. If your rights have been terminated and not permanently
|
||||||
|
reinstated, you do not qualify to receive new licenses for the same
|
||||||
|
material under section 10.
|
||||||
|
|
||||||
|
9. Acceptance Not Required for Having Copies.
|
||||||
|
|
||||||
|
You are not required to accept this License in order to receive or
|
||||||
|
run a copy of the Program. Ancillary propagation of a covered work
|
||||||
|
occurring solely as a consequence of using peer-to-peer transmission
|
||||||
|
to receive a copy likewise does not require acceptance. However,
|
||||||
|
nothing other than this License grants you permission to propagate or
|
||||||
|
modify any covered work. These actions infringe copyright if you do
|
||||||
|
not accept this License. Therefore, by modifying or propagating a
|
||||||
|
covered work, you indicate your acceptance of this License to do so.
|
||||||
|
|
||||||
|
10. Automatic Licensing of Downstream Recipients.
|
||||||
|
|
||||||
|
Each time you convey a covered work, the recipient automatically
|
||||||
|
receives a license from the original licensors, to run, modify and
|
||||||
|
propagate that work, subject to this License. You are not responsible
|
||||||
|
for enforcing compliance by third parties with this License.
|
||||||
|
|
||||||
|
An "entity transaction" is a transaction transferring control of an
|
||||||
|
organization, or substantially all assets of one, or subdividing an
|
||||||
|
organization, or merging organizations. If propagation of a covered
|
||||||
|
work results from an entity transaction, each party to that
|
||||||
|
transaction who receives a copy of the work also receives whatever
|
||||||
|
licenses to the work the party's predecessor in interest had or could
|
||||||
|
give under the previous paragraph, plus a right to possession of the
|
||||||
|
Corresponding Source of the work from the predecessor in interest, if
|
||||||
|
the predecessor has it or can get it with reasonable efforts.
|
||||||
|
|
||||||
|
You may not impose any further restrictions on the exercise of the
|
||||||
|
rights granted or affirmed under this License. For example, you may
|
||||||
|
not impose a license fee, royalty, or other charge for exercise of
|
||||||
|
rights granted under this License, and you may not initiate litigation
|
||||||
|
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||||
|
any patent claim is infringed by making, using, selling, offering for
|
||||||
|
sale, or importing the Program or any portion of it.
|
||||||
|
|
||||||
|
11. Patents.
|
||||||
|
|
||||||
|
A "contributor" is a copyright holder who authorizes use under this
|
||||||
|
License of the Program or a work on which the Program is based. The
|
||||||
|
work thus licensed is called the contributor's "contributor version".
|
||||||
|
|
||||||
|
A contributor's "essential patent claims" are all patent claims
|
||||||
|
owned or controlled by the contributor, whether already acquired or
|
||||||
|
hereafter acquired, that would be infringed by some manner, permitted
|
||||||
|
by this License, of making, using, or selling its contributor version,
|
||||||
|
but do not include claims that would be infringed only as a
|
||||||
|
consequence of further modification of the contributor version. For
|
||||||
|
purposes of this definition, "control" includes the right to grant
|
||||||
|
patent sublicenses in a manner consistent with the requirements of
|
||||||
|
this License.
|
||||||
|
|
||||||
|
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||||
|
patent license under the contributor's essential patent claims, to
|
||||||
|
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||||
|
propagate the contents of its contributor version.
|
||||||
|
|
||||||
|
In the following three paragraphs, a "patent license" is any express
|
||||||
|
agreement or commitment, however denominated, not to enforce a patent
|
||||||
|
(such as an express permission to practice a patent or covenant not to
|
||||||
|
sue for patent infringement). To "grant" such a patent license to a
|
||||||
|
party means to make such an agreement or commitment not to enforce a
|
||||||
|
patent against the party.
|
||||||
|
|
||||||
|
If you convey a covered work, knowingly relying on a patent license,
|
||||||
|
and the Corresponding Source of the work is not available for anyone
|
||||||
|
to copy, free of charge and under the terms of this License, through a
|
||||||
|
publicly available network server or other readily accessible means,
|
||||||
|
then you must either (1) cause the Corresponding Source to be so
|
||||||
|
available, or (2) arrange to deprive yourself of the benefit of the
|
||||||
|
patent license for this particular work, or (3) arrange, in a manner
|
||||||
|
consistent with the requirements of this License, to extend the patent
|
||||||
|
license to downstream recipients. "Knowingly relying" means you have
|
||||||
|
actual knowledge that, but for the patent license, your conveying the
|
||||||
|
covered work in a country, or your recipient's use of the covered work
|
||||||
|
in a country, would infringe one or more identifiable patents in that
|
||||||
|
country that you have reason to believe are valid.
|
||||||
|
|
||||||
|
If, pursuant to or in connection with a single transaction or
|
||||||
|
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||||
|
covered work, and grant a patent license to some of the parties
|
||||||
|
receiving the covered work authorizing them to use, propagate, modify
|
||||||
|
or convey a specific copy of the covered work, then the patent license
|
||||||
|
you grant is automatically extended to all recipients of the covered
|
||||||
|
work and works based on it.
|
||||||
|
|
||||||
|
A patent license is "discriminatory" if it does not include within
|
||||||
|
the scope of its coverage, prohibits the exercise of, or is
|
||||||
|
conditioned on the non-exercise of one or more of the rights that are
|
||||||
|
specifically granted under this License. You may not convey a covered
|
||||||
|
work if you are a party to an arrangement with a third party that is
|
||||||
|
in the business of distributing software, under which you make payment
|
||||||
|
to the third party based on the extent of your activity of conveying
|
||||||
|
the work, and under which the third party grants, to any of the
|
||||||
|
parties who would receive the covered work from you, a discriminatory
|
||||||
|
patent license (a) in connection with copies of the covered work
|
||||||
|
conveyed by you (or copies made from those copies), or (b) primarily
|
||||||
|
for and in connection with specific products or compilations that
|
||||||
|
contain the covered work, unless you entered into that arrangement,
|
||||||
|
or that patent license was granted, prior to 28 March 2007.
|
||||||
|
|
||||||
|
Nothing in this License shall be construed as excluding or limiting
|
||||||
|
any implied license or other defenses to infringement that may
|
||||||
|
otherwise be available to you under applicable patent law.
|
||||||
|
|
||||||
|
12. No Surrender of Others' Freedom.
|
||||||
|
|
||||||
|
If conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot convey a
|
||||||
|
covered work so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you may
|
||||||
|
not convey it at all. For example, if you agree to terms that obligate you
|
||||||
|
to collect a royalty for further conveying from those to whom you convey
|
||||||
|
the Program, the only way you could satisfy both those terms and this
|
||||||
|
License would be to refrain entirely from conveying the Program.
|
||||||
|
|
||||||
|
13. Use with the GNU Affero General Public License.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, you have
|
||||||
|
permission to link or combine any covered work with a work licensed
|
||||||
|
under version 3 of the GNU Affero General Public License into a single
|
||||||
|
combined work, and to convey the resulting work. The terms of this
|
||||||
|
License will continue to apply to the part which is the covered work,
|
||||||
|
but the special requirements of the GNU Affero General Public License,
|
||||||
|
section 13, concerning interaction through a network will apply to the
|
||||||
|
combination as such.
|
||||||
|
|
||||||
|
14. Revised Versions of this License.
|
||||||
|
|
||||||
|
The Free Software Foundation may publish revised and/or new versions of
|
||||||
|
the GNU General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the
|
||||||
|
Program specifies that a certain numbered version of the GNU General
|
||||||
|
Public License "or any later version" applies to it, you have the
|
||||||
|
option of following the terms and conditions either of that numbered
|
||||||
|
version or of any later version published by the Free Software
|
||||||
|
Foundation. If the Program does not specify a version number of the
|
||||||
|
GNU General Public License, you may choose any version ever published
|
||||||
|
by the Free Software Foundation.
|
||||||
|
|
||||||
|
If the Program specifies that a proxy can decide which future
|
||||||
|
versions of the GNU General Public License can be used, that proxy's
|
||||||
|
public statement of acceptance of a version permanently authorizes you
|
||||||
|
to choose that version for the Program.
|
||||||
|
|
||||||
|
Later license versions may give you additional or different
|
||||||
|
permissions. However, no additional obligations are imposed on any
|
||||||
|
author or copyright holder as a result of your choosing to follow a
|
||||||
|
later version.
|
||||||
|
|
||||||
|
15. Disclaimer of Warranty.
|
||||||
|
|
||||||
|
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||||
|
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||||
|
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||||
|
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||||
|
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||||
|
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
16. Limitation of Liability.
|
||||||
|
|
||||||
|
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||||
|
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||||
|
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||||
|
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||||
|
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||||
|
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||||
|
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||||
|
SUCH DAMAGES.
|
||||||
|
|
||||||
|
17. Interpretation of Sections 15 and 16.
|
||||||
|
|
||||||
|
If the disclaimer of warranty and limitation of liability provided
|
||||||
|
above cannot be given local legal effect according to their terms,
|
||||||
|
reviewing courts shall apply local law that most closely approximates
|
||||||
|
an absolute waiver of all civil liability in connection with the
|
||||||
|
Program, unless a warranty or assumption of liability accompanies a
|
||||||
|
copy of the Program in return for a fee.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
state the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
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 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If the program does terminal interaction, make it output a short
|
||||||
|
notice like this when it starts in an interactive mode:
|
||||||
|
|
||||||
|
<program> Copyright (C) <year> <name of author>
|
||||||
|
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
|
This is free software, and you are welcome to redistribute it
|
||||||
|
under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||||
|
parts of the General Public License. Of course, your program's commands
|
||||||
|
might be different; for a GUI interface, you would use an "about box".
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or school,
|
||||||
|
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||||
|
For more information on this, and how to apply and follow the GNU GPL, see
|
||||||
|
<http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
The GNU General Public License does not permit incorporating your program
|
||||||
|
into proprietary programs. If your program is a subroutine library, you
|
||||||
|
may consider it more useful to permit linking proprietary applications with
|
||||||
|
the library. If this is what you want to do, use the GNU Lesser General
|
||||||
|
Public License instead of this License. But first, please read
|
||||||
|
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||||
56
intern/smoke/intern/LU_HELPER.h
Normal file
56
intern/smoke/intern/LU_HELPER.h
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// This file is part of Wavelet Turbulence.
|
||||||
|
//
|
||||||
|
// Wavelet Turbulence 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 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Wavelet Turbulence 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 Wavelet Turbulence. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// Copyright 2008 Theodore Kim and Nils Thuerey
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef LU_HELPER_H
|
||||||
|
#define LU_HELPER_H
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// Helper function, compute eigenvalues of 3x3 matrix
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "tnt/jama_lu.h"
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// 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]);
|
||||||
|
JAMA::LU<float> jLU= JAMA::LU<float>(A);
|
||||||
|
return jLU;
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// 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
|
||||||
429
intern/smoke/intern/MERSENNETWISTER.h
Normal file
429
intern/smoke/intern/MERSENNETWISTER.h
Normal file
@@ -0,0 +1,429 @@
|
|||||||
|
// MersenneTwister.h
|
||||||
|
// Mersenne Twister random number generator -- a C++ class MTRand
|
||||||
|
// Based on code by Makoto Matsumoto, Takuji Nishimura, and Shawn Cokus
|
||||||
|
// Richard J. Wagner v1.0 15 May 2003 rjwagner@writeme.com
|
||||||
|
|
||||||
|
// The Mersenne Twister is an algorithm for generating random numbers. It
|
||||||
|
// was designed with consideration of the flaws in various other generators.
|
||||||
|
// The period, 2^19937-1, and the order of equidistribution, 623 dimensions,
|
||||||
|
// are far greater. The generator is also fast; it avoids multiplication and
|
||||||
|
// division, and it benefits from caches and pipelines. For more information
|
||||||
|
// see the inventors' web page at http://www.math.keio.ac.jp/~matumoto/emt.html
|
||||||
|
|
||||||
|
// Reference
|
||||||
|
// M. Matsumoto and T. Nishimura, "Mersenne Twister: A 623-Dimensionally
|
||||||
|
// Equidistributed Uniform Pseudo-Random Number Generator", ACM Transactions on
|
||||||
|
// Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3-30.
|
||||||
|
|
||||||
|
// Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
|
||||||
|
// Copyright (C) 2000 - 2003, Richard J. Wagner
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions
|
||||||
|
// are met:
|
||||||
|
//
|
||||||
|
// 1. Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer in the
|
||||||
|
// documentation and/or other materials provided with the distribution.
|
||||||
|
//
|
||||||
|
// 3. The names of its contributors may not be used to endorse or promote
|
||||||
|
// products derived from this software without specific prior written
|
||||||
|
// permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// The original code included the following notice:
|
||||||
|
//
|
||||||
|
// When you use this, send an email to: matumoto@math.keio.ac.jp
|
||||||
|
// with an appropriate reference to your work.
|
||||||
|
//
|
||||||
|
// It would be nice to CC: rjwagner@writeme.com and Cokus@math.washington.edu
|
||||||
|
// when you write.
|
||||||
|
|
||||||
|
#ifndef MERSENNETWISTER_H
|
||||||
|
#define MERSENNETWISTER_H
|
||||||
|
|
||||||
|
// Not thread safe (unless auto-initialization is avoided and each thread has
|
||||||
|
// its own MTRand object)
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
class MTRand {
|
||||||
|
// Data
|
||||||
|
public:
|
||||||
|
typedef unsigned long uint32; // unsigned integer type, at least 32 bits
|
||||||
|
|
||||||
|
enum { N = 624 }; // length of state vector
|
||||||
|
enum { SAVE = N + 1 }; // length of array for save()
|
||||||
|
|
||||||
|
protected:
|
||||||
|
enum { M = 397 }; // period parameter
|
||||||
|
|
||||||
|
uint32 state[N]; // internal state
|
||||||
|
uint32 *pNext; // next value to get from state
|
||||||
|
int left; // number of values left before reload needed
|
||||||
|
|
||||||
|
|
||||||
|
//Methods
|
||||||
|
public:
|
||||||
|
MTRand( const uint32& oneSeed ); // initialize with a simple uint32
|
||||||
|
MTRand( uint32 *const bigSeed, uint32 const seedLength = N ); // or an array
|
||||||
|
MTRand(); // auto-initialize with /dev/urandom or time() and clock()
|
||||||
|
|
||||||
|
// Do NOT use for CRYPTOGRAPHY without securely hashing several returned
|
||||||
|
// values together, otherwise the generator state can be learned after
|
||||||
|
// reading 624 consecutive values.
|
||||||
|
|
||||||
|
// Access to 32-bit random numbers
|
||||||
|
double rand(); // real number in [0,1]
|
||||||
|
double rand( const double& n ); // real number in [0,n]
|
||||||
|
double randExc(); // real number in [0,1)
|
||||||
|
double randExc( const double& n ); // real number in [0,n)
|
||||||
|
double randDblExc(); // real number in (0,1)
|
||||||
|
double randDblExc( const double& n ); // real number in (0,n)
|
||||||
|
uint32 randInt(); // integer in [0,2^32-1]
|
||||||
|
uint32 randInt( const uint32& n ); // integer in [0,n] for n < 2^32
|
||||||
|
double operator()() { return rand(); } // same as rand()
|
||||||
|
|
||||||
|
// Access to 53-bit random numbers (capacity of IEEE double precision)
|
||||||
|
double rand53(); // real number in [0,1)
|
||||||
|
|
||||||
|
// Access to nonuniform random number distributions
|
||||||
|
double randNorm( const double& mean = 0.0, const double& variance = 1.0 );
|
||||||
|
|
||||||
|
// Re-seeding functions with same behavior as initializers
|
||||||
|
void seed( const uint32 oneSeed );
|
||||||
|
void seed( uint32 *const bigSeed, const uint32 seedLength = N );
|
||||||
|
void seed();
|
||||||
|
|
||||||
|
// Saving and loading generator state
|
||||||
|
void save( uint32* saveArray ) const; // to array of size SAVE
|
||||||
|
void load( uint32 *const loadArray ); // from such array
|
||||||
|
friend std::ostream& operator<<( std::ostream& os, const MTRand& mtrand );
|
||||||
|
friend std::istream& operator>>( std::istream& is, MTRand& mtrand );
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void initialize( const uint32 oneSeed );
|
||||||
|
void reload();
|
||||||
|
uint32 hiBit( const uint32& u ) const { return u & 0x80000000UL; }
|
||||||
|
uint32 loBit( const uint32& u ) const { return u & 0x00000001UL; }
|
||||||
|
uint32 loBits( const uint32& u ) const { return u & 0x7fffffffUL; }
|
||||||
|
uint32 mixBits( const uint32& u, const uint32& v ) const
|
||||||
|
{ return hiBit(u) | loBits(v); }
|
||||||
|
uint32 twist( const uint32& m, const uint32& s0, const uint32& s1 ) const
|
||||||
|
{ return m ^ (mixBits(s0,s1)>>1) ^ (-loBit(s1) & 0x9908b0dfUL); }
|
||||||
|
static uint32 hash( time_t t, clock_t c );
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
inline MTRand::MTRand( const uint32& oneSeed )
|
||||||
|
{ seed(oneSeed); }
|
||||||
|
|
||||||
|
inline MTRand::MTRand( uint32 *const bigSeed, const uint32 seedLength )
|
||||||
|
{ seed(bigSeed,seedLength); }
|
||||||
|
|
||||||
|
inline MTRand::MTRand()
|
||||||
|
{ seed(); }
|
||||||
|
|
||||||
|
inline double MTRand::rand()
|
||||||
|
{ return double(randInt()) * (1.0/4294967295.0); }
|
||||||
|
|
||||||
|
inline double MTRand::rand( const double& n )
|
||||||
|
{ return rand() * n; }
|
||||||
|
|
||||||
|
inline double MTRand::randExc()
|
||||||
|
{ return double(randInt()) * (1.0/4294967296.0); }
|
||||||
|
|
||||||
|
inline double MTRand::randExc( const double& n )
|
||||||
|
{ return randExc() * n; }
|
||||||
|
|
||||||
|
inline double MTRand::randDblExc()
|
||||||
|
{ return ( double(randInt()) + 0.5 ) * (1.0/4294967296.0); }
|
||||||
|
|
||||||
|
inline double MTRand::randDblExc( const double& n )
|
||||||
|
{ return randDblExc() * n; }
|
||||||
|
|
||||||
|
inline double MTRand::rand53()
|
||||||
|
{
|
||||||
|
uint32 a = randInt() >> 5, b = randInt() >> 6;
|
||||||
|
return ( a * 67108864.0 + b ) * (1.0/9007199254740992.0); // by Isaku Wada
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double MTRand::randNorm( const double& mean, const double& variance )
|
||||||
|
{
|
||||||
|
// Return a real number from a normal (Gaussian) distribution with given
|
||||||
|
// mean and variance by Box-Muller method
|
||||||
|
double r = sqrt( -2.0 * log( 1.0-randDblExc()) ) * variance;
|
||||||
|
double phi = 2.0 * 3.14159265358979323846264338328 * randExc();
|
||||||
|
return mean + r * cos(phi);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline MTRand::uint32 MTRand::randInt()
|
||||||
|
{
|
||||||
|
// Pull a 32-bit integer from the generator state
|
||||||
|
// Every other access function simply transforms the numbers extracted here
|
||||||
|
|
||||||
|
if( left == 0 ) reload();
|
||||||
|
--left;
|
||||||
|
|
||||||
|
register uint32 s1;
|
||||||
|
s1 = *pNext++;
|
||||||
|
s1 ^= (s1 >> 11);
|
||||||
|
s1 ^= (s1 << 7) & 0x9d2c5680UL;
|
||||||
|
s1 ^= (s1 << 15) & 0xefc60000UL;
|
||||||
|
return ( s1 ^ (s1 >> 18) );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline MTRand::uint32 MTRand::randInt( const uint32& n )
|
||||||
|
{
|
||||||
|
// Find which bits are used in n
|
||||||
|
// Optimized by Magnus Jonsson (magnus@smartelectronix.com)
|
||||||
|
uint32 used = n;
|
||||||
|
used |= used >> 1;
|
||||||
|
used |= used >> 2;
|
||||||
|
used |= used >> 4;
|
||||||
|
used |= used >> 8;
|
||||||
|
used |= used >> 16;
|
||||||
|
|
||||||
|
// Draw numbers until one is found in [0,n]
|
||||||
|
uint32 i;
|
||||||
|
do
|
||||||
|
i = randInt() & used; // toss unused bits to shorten search
|
||||||
|
while( i > n );
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void MTRand::seed( const uint32 oneSeed )
|
||||||
|
{
|
||||||
|
// Seed the generator with a simple uint32
|
||||||
|
initialize(oneSeed);
|
||||||
|
reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void MTRand::seed( uint32 *const bigSeed, const uint32 seedLength )
|
||||||
|
{
|
||||||
|
// Seed the generator with an array of uint32's
|
||||||
|
// There are 2^19937-1 possible initial states. This function allows
|
||||||
|
// all of those to be accessed by providing at least 19937 bits (with a
|
||||||
|
// default seed length of N = 624 uint32's). Any bits above the lower 32
|
||||||
|
// in each element are discarded.
|
||||||
|
// Just call seed() if you want to get array from /dev/urandom
|
||||||
|
initialize(19650218UL);
|
||||||
|
register int i = 1;
|
||||||
|
register uint32 j = 0;
|
||||||
|
register int k = ( N > seedLength ? N : seedLength );
|
||||||
|
for( ; k; --k )
|
||||||
|
{
|
||||||
|
state[i] =
|
||||||
|
state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1664525UL );
|
||||||
|
state[i] += ( bigSeed[j] & 0xffffffffUL ) + j;
|
||||||
|
state[i] &= 0xffffffffUL;
|
||||||
|
++i; ++j;
|
||||||
|
if( i >= N ) { state[0] = state[N-1]; i = 1; }
|
||||||
|
if( j >= seedLength ) j = 0;
|
||||||
|
}
|
||||||
|
for( k = N - 1; k; --k )
|
||||||
|
{
|
||||||
|
state[i] =
|
||||||
|
state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1566083941UL );
|
||||||
|
state[i] -= i;
|
||||||
|
state[i] &= 0xffffffffUL;
|
||||||
|
++i;
|
||||||
|
if( i >= N ) { state[0] = state[N-1]; i = 1; }
|
||||||
|
}
|
||||||
|
state[0] = 0x80000000UL; // MSB is 1, assuring non-zero initial array
|
||||||
|
reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void MTRand::seed()
|
||||||
|
{
|
||||||
|
// seed deterministically to produce reproducible runs
|
||||||
|
seed(123456);
|
||||||
|
|
||||||
|
/*
|
||||||
|
// Seed the generator with an array from /dev/urandom if available
|
||||||
|
// Otherwise use a hash of time() and clock() values
|
||||||
|
|
||||||
|
// First try getting an array from /dev/urandom
|
||||||
|
FILE* urandom = fopen( "/dev/urandom", "rb" );
|
||||||
|
if( urandom )
|
||||||
|
{
|
||||||
|
uint32 bigSeed[N];
|
||||||
|
register uint32 *s = bigSeed;
|
||||||
|
register int i = N;
|
||||||
|
register bool success = true;
|
||||||
|
while( success && i-- )
|
||||||
|
success = fread( s++, sizeof(uint32), 1, urandom );
|
||||||
|
fclose(urandom);
|
||||||
|
if( success ) { seed( bigSeed, N ); return; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Was not successful, so use time() and clock() instead
|
||||||
|
seed( hash( time(NULL), clock() ) );
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void MTRand::initialize( const uint32 seed )
|
||||||
|
{
|
||||||
|
// Initialize generator state with seed
|
||||||
|
// See Knuth TAOCP Vol 2, 3rd Ed, p.106 for multiplier.
|
||||||
|
// In previous versions, most significant bits (MSBs) of the seed affect
|
||||||
|
// only MSBs of the state array. Modified 9 Jan 2002 by Makoto Matsumoto.
|
||||||
|
register uint32 *s = state;
|
||||||
|
register uint32 *r = state;
|
||||||
|
register int i = 1;
|
||||||
|
*s++ = seed & 0xffffffffUL;
|
||||||
|
for( ; i < N; ++i )
|
||||||
|
{
|
||||||
|
*s++ = ( 1812433253UL * ( *r ^ (*r >> 30) ) + i ) & 0xffffffffUL;
|
||||||
|
r++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void MTRand::reload()
|
||||||
|
{
|
||||||
|
// Generate N new values in state
|
||||||
|
// Made clearer and faster by Matthew Bellew (matthew.bellew@home.com)
|
||||||
|
register uint32 *p = state;
|
||||||
|
register int i;
|
||||||
|
for( i = N - M; i--; ++p )
|
||||||
|
*p = twist( p[M], p[0], p[1] );
|
||||||
|
for( i = M; --i; ++p )
|
||||||
|
*p = twist( p[M-N], p[0], p[1] );
|
||||||
|
*p = twist( p[M-N], p[0], state[0] );
|
||||||
|
|
||||||
|
left = N, pNext = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline MTRand::uint32 MTRand::hash( time_t t, clock_t c )
|
||||||
|
{
|
||||||
|
// Get a uint32 from t and c
|
||||||
|
// Better than uint32(x) in case x is floating point in [0,1]
|
||||||
|
// Based on code by Lawrence Kirby (fred@genesis.demon.co.uk)
|
||||||
|
|
||||||
|
static uint32 differ = 0; // guarantee time-based seeds will change
|
||||||
|
|
||||||
|
uint32 h1 = 0;
|
||||||
|
unsigned char *p = (unsigned char *) &t;
|
||||||
|
for( size_t i = 0; i < sizeof(t); ++i )
|
||||||
|
{
|
||||||
|
h1 *= UCHAR_MAX + 2U;
|
||||||
|
h1 += p[i];
|
||||||
|
}
|
||||||
|
uint32 h2 = 0;
|
||||||
|
p = (unsigned char *) &c;
|
||||||
|
for( size_t j = 0; j < sizeof(c); ++j )
|
||||||
|
{
|
||||||
|
h2 *= UCHAR_MAX + 2U;
|
||||||
|
h2 += p[j];
|
||||||
|
}
|
||||||
|
return ( h1 + differ++ ) ^ h2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void MTRand::save( uint32* saveArray ) const
|
||||||
|
{
|
||||||
|
register uint32 *sa = saveArray;
|
||||||
|
register const uint32 *s = state;
|
||||||
|
register int i = N;
|
||||||
|
for( ; i--; *sa++ = *s++ ) {}
|
||||||
|
*sa = left;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void MTRand::load( uint32 *const loadArray )
|
||||||
|
{
|
||||||
|
register uint32 *s = state;
|
||||||
|
register uint32 *la = loadArray;
|
||||||
|
register int i = N;
|
||||||
|
for( ; i--; *s++ = *la++ ) {}
|
||||||
|
left = *la;
|
||||||
|
pNext = &state[N-left];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline std::ostream& operator<<( std::ostream& os, const MTRand& mtrand )
|
||||||
|
{
|
||||||
|
register const MTRand::uint32 *s = mtrand.state;
|
||||||
|
register int i = mtrand.N;
|
||||||
|
for( ; i--; os << *s++ << "\t" ) {}
|
||||||
|
return os << mtrand.left;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline std::istream& operator>>( std::istream& is, MTRand& mtrand )
|
||||||
|
{
|
||||||
|
register MTRand::uint32 *s = mtrand.state;
|
||||||
|
register int i = mtrand.N;
|
||||||
|
for( ; i--; is >> *s++ ) {}
|
||||||
|
is >> mtrand.left;
|
||||||
|
mtrand.pNext = &mtrand.state[mtrand.N-mtrand.left];
|
||||||
|
return is;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // MERSENNETWISTER_H
|
||||||
|
|
||||||
|
// Change log:
|
||||||
|
//
|
||||||
|
// v0.1 - First release on 15 May 2000
|
||||||
|
// - Based on code by Makoto Matsumoto, Takuji Nishimura, and Shawn Cokus
|
||||||
|
// - Translated from C to C++
|
||||||
|
// - Made completely ANSI compliant
|
||||||
|
// - Designed convenient interface for initialization, seeding, and
|
||||||
|
// obtaining numbers in default or user-defined ranges
|
||||||
|
// - Added automatic seeding from /dev/urandom or time() and clock()
|
||||||
|
// - Provided functions for saving and loading generator state
|
||||||
|
//
|
||||||
|
// v0.2 - Fixed bug which reloaded generator one step too late
|
||||||
|
//
|
||||||
|
// v0.3 - Switched to clearer, faster reload() code from Matthew Bellew
|
||||||
|
//
|
||||||
|
// v0.4 - Removed trailing newline in saved generator format to be consistent
|
||||||
|
// with output format of built-in types
|
||||||
|
//
|
||||||
|
// v0.5 - Improved portability by replacing static const int's with enum's and
|
||||||
|
// clarifying return values in seed(); suggested by Eric Heimburg
|
||||||
|
// - Removed MAXINT constant; use 0xffffffffUL instead
|
||||||
|
//
|
||||||
|
// v0.6 - Eliminated seed overflow when uint32 is larger than 32 bits
|
||||||
|
// - Changed integer [0,n] generator to give better uniformity
|
||||||
|
//
|
||||||
|
// v0.7 - Fixed operator precedence ambiguity in reload()
|
||||||
|
// - Added access for real numbers in (0,1) and (0,n)
|
||||||
|
//
|
||||||
|
// v0.8 - Included time.h header to properly support time_t and clock_t
|
||||||
|
//
|
||||||
|
// v1.0 - Revised seeding to match 26 Jan 2002 update of Nishimura and Matsumoto
|
||||||
|
// - Allowed for seeding with arrays of any length
|
||||||
|
// - Added access for real numbers in [0,1) with 53-bit resolution
|
||||||
|
// - Added access for real numbers from normal (Gaussian) distributions
|
||||||
|
// - Increased overall speed by optimizing twist()
|
||||||
|
// - Doubled speed of integer [0,n] generation
|
||||||
|
// - Fixed out-of-range number generation on 64-bit machines
|
||||||
|
// - Improved portability by substituting literal constants for long enum's
|
||||||
|
// - Changed license from GNU LGPL to BSD
|
||||||
|
|
||||||
28
release/beos-4.5-i386/specific.sh → intern/smoke/intern/Makefile
Executable file → Normal file
28
release/beos-4.5-i386/specific.sh → intern/smoke/intern/Makefile
Executable file → Normal file
@@ -1,4 +1,3 @@
|
|||||||
#!/bin/sh
|
|
||||||
#
|
#
|
||||||
# $Id$
|
# $Id$
|
||||||
#
|
#
|
||||||
@@ -26,11 +25,28 @@
|
|||||||
# Contributor(s): none yet.
|
# Contributor(s): none yet.
|
||||||
#
|
#
|
||||||
# ***** END GPL LICENSE BLOCK *****
|
# ***** END GPL LICENSE BLOCK *****
|
||||||
|
# smoke intern Makefile
|
||||||
#
|
#
|
||||||
# OS specific stuff for the package, only to be executed by ../Makefile
|
|
||||||
|
|
||||||
# Add Python .so to package
|
LIBNAME = smoke
|
||||||
cp -f $NAN_PYTHON/lib/libpython$NAN_PYTHON_VERSION.so $DISTDIR/
|
DIR = $(OCGDIR)/intern/$(LIBNAME)
|
||||||
|
|
||||||
# And create a drag'n'drop symlink for it
|
include nan_compile.mk
|
||||||
cd $DISTDIR && ln -s /boot/home/config/lib Drag_libpython$NAN_PYTHON_VERSION.so_here
|
|
||||||
|
unexport NAN_QUIET
|
||||||
|
|
||||||
|
CCFLAGS += $(LEVEL_2_CPP_WARNINGS)
|
||||||
|
|
||||||
|
ifeq ($(WITH_BF_OPENMP),true)
|
||||||
|
CPPFLAGS += -DPARALLEL
|
||||||
|
endif
|
||||||
|
|
||||||
|
CPPFLAGS += -I.
|
||||||
|
CPPFLAGS += -I../extern
|
||||||
|
CPPFLAGS += -I$(NAN_PNG)/include
|
||||||
|
CPPFLAGS += -I$(NAN_PNG)/include/libpng
|
||||||
|
|
||||||
|
# zlib
|
||||||
|
ifeq ($(OS),$(findstring $(OS), "solaris windows"))
|
||||||
|
CPPFLAGS += -I$(NAN_ZLIB)/include
|
||||||
|
endif
|
||||||
22
intern/smoke/intern/Makefile.FFT
Normal file
22
intern/smoke/intern/Makefile.FFT
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
# common stuff
|
||||||
|
LDFLAGS_COMMON = -lfftw3 #-lglut -lglu32 -lopengl32 -lz -lpng
|
||||||
|
CFLAGS_COMMON = -c -Wall -I./ #-I/cygdrive/c/lib/glvu/include -D_WIN32
|
||||||
|
|
||||||
|
CC = g++
|
||||||
|
CFLAGS = ${CFLAGS_COMMON} -O3 -Wno-unused
|
||||||
|
LDFLAGS = ${LDFLAGS_COMMON}
|
||||||
|
EXECUTABLE = noiseFFT
|
||||||
|
|
||||||
|
SOURCES = noiseFFT.cpp
|
||||||
|
OBJECTS = $(SOURCES:.cpp=.o)
|
||||||
|
|
||||||
|
all: $(SOURCES) $(EXECUTABLE)
|
||||||
|
|
||||||
|
$(EXECUTABLE): $(OBJECTS)
|
||||||
|
$(CC) $(OBJECTS) $(LDFLAGS) -o $@
|
||||||
|
|
||||||
|
.cpp.o:
|
||||||
|
$(CC) $(CFLAGS) $< -o $@
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.o $(EXECUTABLE_LOADER) $(EXECUTABLE)
|
||||||
23
intern/smoke/intern/Makefile.cygwin
Normal file
23
intern/smoke/intern/Makefile.cygwin
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
CC = g++
|
||||||
|
LDFLAGS = -lz -lpng
|
||||||
|
CFLAGS = -O3 -Wno-unused -c -Wall -I./ -D_WIN32
|
||||||
|
EXECUTABLE = FLUID_3D
|
||||||
|
|
||||||
|
SOURCES = main.cpp FLUID_3D.cpp FLUID_3D_SOLVERS.cpp FLUID_3D_STATIC.cpp SPHERE.cpp WTURBULENCE.cpp
|
||||||
|
OBJECTS = $(SOURCES:.cpp=.o)
|
||||||
|
|
||||||
|
all: $(SOURCES) $(EXECUTABLE)
|
||||||
|
|
||||||
|
$(EXECUTABLE): $(OBJECTS)
|
||||||
|
$(CC) $(OBJECTS) $(LDFLAGS) -o $@
|
||||||
|
|
||||||
|
.cpp.o:
|
||||||
|
$(CC) $(CFLAGS) $< -o $@
|
||||||
|
|
||||||
|
SPHERE.o: SPHERE.h
|
||||||
|
FLUID_3D.o: FLUID_3D.h FLUID_3D.cpp
|
||||||
|
FLUID_3D_SOLVERS.o: FLUID_3D.h FLUID_3D_SOLVERS.cpp
|
||||||
|
main.o: FLUID_3D.h FLUID_3D.cpp FLUID_3D_SOLVERS.cpp
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.o $(EXECUTABLE_LOADER) $(EXECUTABLE)
|
||||||
23
intern/smoke/intern/Makefile.linux
Normal file
23
intern/smoke/intern/Makefile.linux
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
CC = g++
|
||||||
|
LDFLAGS = -lz -lpng -fopenmp -lgomp
|
||||||
|
CFLAGS = -c -Wall -I./ -fopenmp -DPARALLEL=1 -O3 -Wno-unused
|
||||||
|
EXECUTABLE = FLUID_3D
|
||||||
|
|
||||||
|
SOURCES = main.cpp FLUID_3D.cpp FLUID_3D_SOLVERS.cpp FLUID_3D_STATIC.cpp SPHERE.cpp WTURBULENCE.cpp
|
||||||
|
OBJECTS = $(SOURCES:.cpp=.o)
|
||||||
|
|
||||||
|
all: $(SOURCES) $(EXECUTABLE)
|
||||||
|
|
||||||
|
$(EXECUTABLE): $(OBJECTS)
|
||||||
|
$(CC) $(OBJECTS) $(LDFLAGS) -o $@
|
||||||
|
|
||||||
|
.cpp.o:
|
||||||
|
$(CC) $(CFLAGS) $< -o $@
|
||||||
|
|
||||||
|
SPHERE.o: SPHERE.h
|
||||||
|
FLUID_3D.o: FLUID_3D.h FLUID_3D.cpp
|
||||||
|
FLUID_3D_SOLVERS.o: FLUID_3D.h FLUID_3D_SOLVERS.cpp
|
||||||
|
main.o: FLUID_3D.h FLUID_3D.cpp FLUID_3D_SOLVERS.cpp
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.o $(EXECUTABLE_LOADER) $(EXECUTABLE)
|
||||||
35
intern/smoke/intern/Makefile.mac
Normal file
35
intern/smoke/intern/Makefile.mac
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
CC = g++
|
||||||
|
|
||||||
|
# uncomment the other two OPENMP_... lines, if your gcc supports OpenMP
|
||||||
|
#OPENMP_FLAGS = -fopenmp -DPARALLEL=1 -I/opt/gcc-4.3/usr/local/include
|
||||||
|
#OPENMPLD_FLAGS = -fopenmp -lgomp -I/opt/gcc-4.3/usr/local/lib
|
||||||
|
OPENMP_FLAGS =
|
||||||
|
OPENMPLD_FLAGS =
|
||||||
|
|
||||||
|
# assumes MacPorts libpng installation
|
||||||
|
PNG_INCLUDE = -I/opt/local/include
|
||||||
|
PNG_LIBS = -I/opt/local/lib
|
||||||
|
|
||||||
|
LDFLAGS = $(PNG_LIBS)-lz -lpng $(OPENMPLD_FLAGS)
|
||||||
|
CFLAGS = -c -Wall -I./ $(PNG_INCLUDE) $(OPENMP_FLAGS) -O3 -Wno-unused
|
||||||
|
EXECUTABLE = FLUID_3D
|
||||||
|
|
||||||
|
SOURCES = main.cpp FLUID_3D.cpp FLUID_3D_SOLVERS.cpp FLUID_3D_STATIC.cpp SPHERE.cpp WTURBULENCE.cpp
|
||||||
|
OBJECTS = $(SOURCES:.cpp=.o)
|
||||||
|
|
||||||
|
all: $(SOURCES) $(EXECUTABLE)
|
||||||
|
|
||||||
|
$(EXECUTABLE): $(OBJECTS)
|
||||||
|
$(CC) $(OBJECTS) $(LDFLAGS) -o $@
|
||||||
|
|
||||||
|
.cpp.o:
|
||||||
|
$(CC) $(CFLAGS) $< -o $@
|
||||||
|
|
||||||
|
SPHERE.o: SPHERE.h
|
||||||
|
FLUID_3D.o: FLUID_3D.h FLUID_3D.cpp
|
||||||
|
FLUID_3D_SOLVERS.o: FLUID_3D.h FLUID_3D_SOLVERS.cpp
|
||||||
|
main.o: FLUID_3D.h FLUID_3D.cpp FLUID_3D_SOLVERS.cpp
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.o $(EXECUTABLE_LOADER) $(EXECUTABLE)
|
||||||
|
|
||||||
41
intern/smoke/intern/OBSTACLE.h
Normal file
41
intern/smoke/intern/OBSTACLE.h
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// This file is part of Wavelet Turbulence.
|
||||||
|
//
|
||||||
|
// Wavelet Turbulence 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 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Wavelet Turbulence 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 Wavelet Turbulence. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// Copyright 2008 Theodore Kim and Nils Thuerey
|
||||||
|
//
|
||||||
|
// OBSTACLE.h: interface for the OBSTACLE class.
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef OBSTACLE_H
|
||||||
|
#define OBSTACLE_H
|
||||||
|
|
||||||
|
enum OBSTACLE_FLAGS {
|
||||||
|
EMPTY = 0,
|
||||||
|
MARCHED = 2,
|
||||||
|
RETIRED = 4
|
||||||
|
};
|
||||||
|
|
||||||
|
class OBSTACLE
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
OBSTACLE() {};
|
||||||
|
virtual ~OBSTACLE() {};
|
||||||
|
|
||||||
|
virtual bool inside(float x, float y, float z) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
50
intern/smoke/intern/SPHERE.cpp
Normal file
50
intern/smoke/intern/SPHERE.cpp
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// This file is part of Wavelet Turbulence.
|
||||||
|
//
|
||||||
|
// Wavelet Turbulence 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 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Wavelet Turbulence 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 Wavelet Turbulence. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// Copyright 2008 Theodore Kim and Nils Thuerey
|
||||||
|
//
|
||||||
|
// SPHERE.cpp: implementation of the SPHERE class.
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "SPHERE.h"
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// Construction/Destruction
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
SPHERE::SPHERE(float x, float y, float z, float radius) :
|
||||||
|
_radius(radius)
|
||||||
|
{
|
||||||
|
_center[0] = x;
|
||||||
|
_center[1] = y;
|
||||||
|
_center[2] = z;
|
||||||
|
}
|
||||||
|
|
||||||
|
SPHERE::~SPHERE()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SPHERE::inside(float x, float y, float z)
|
||||||
|
{
|
||||||
|
float translate[] = {x - _center[0], y - _center[1], z - _center[2]};
|
||||||
|
float magnitude = translate[0] * translate[0] +
|
||||||
|
translate[1] * translate[1] +
|
||||||
|
translate[2] * translate[2];
|
||||||
|
|
||||||
|
return (magnitude < _radius * _radius) ? true : false;
|
||||||
|
}
|
||||||
41
intern/smoke/intern/SPHERE.h
Normal file
41
intern/smoke/intern/SPHERE.h
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// This file is part of Wavelet Turbulence.
|
||||||
|
//
|
||||||
|
// Wavelet Turbulence 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 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Wavelet Turbulence 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 Wavelet Turbulence. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// Copyright 2008 Theodore Kim and Nils Thuerey
|
||||||
|
//
|
||||||
|
// SPHERE.h: interface for the SPHERE class.
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef SPHERE_H
|
||||||
|
#define SPHERE_H
|
||||||
|
|
||||||
|
#include "OBSTACLE.h"
|
||||||
|
|
||||||
|
class SPHERE : public OBSTACLE
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SPHERE(float x, float y, float z, float radius);
|
||||||
|
virtual ~SPHERE();
|
||||||
|
|
||||||
|
bool inside(float x, float y, float z);
|
||||||
|
|
||||||
|
private:
|
||||||
|
float _center[3];
|
||||||
|
float _radius;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
984
intern/smoke/intern/VEC3.h
Normal file
984
intern/smoke/intern/VEC3.h
Normal file
@@ -0,0 +1,984 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright 2007 Nils Thuerey
|
||||||
|
* Basic vector class
|
||||||
|
*****************************************************************************/
|
||||||
|
#ifndef BASICVECTOR_H
|
||||||
|
#define BASICVECTOR_H
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
// use which fp-precision? 1=float, 2=double
|
||||||
|
#ifndef FLOATINGPOINT_PRECISION
|
||||||
|
#if DDF_DEBUG==1
|
||||||
|
#define FLOATINGPOINT_PRECISION 2
|
||||||
|
#else // DDF_DEBUG==1
|
||||||
|
#define FLOATINGPOINT_PRECISION 1
|
||||||
|
#endif // DDF_DEBUG==1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// VECTOR_EPSILON is the minimal vector length
|
||||||
|
// In order to be able to discriminate floating point values near zero, and
|
||||||
|
// to be sure not to fail a comparison because of roundoff errors, use this
|
||||||
|
// value as a threshold.
|
||||||
|
|
||||||
|
#if FLOATINGPOINT_PRECISION==1
|
||||||
|
typedef float Real;
|
||||||
|
#define FP_REAL_MAX __FLT_MAX__
|
||||||
|
#define VECTOR_EPSILON (1e-5f)
|
||||||
|
#else
|
||||||
|
typedef double Real;
|
||||||
|
#define FP_REAL_MAX __DBL_MAX__
|
||||||
|
#define VECTOR_EPSILON (1e-10)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// hardcoded limits for now...
|
||||||
|
// for e.g. MSVC compiler...
|
||||||
|
// some of these defines can be needed
|
||||||
|
// for linux systems as well (e.g. FLT_MAX)
|
||||||
|
#ifndef __FLT_MAX__
|
||||||
|
# ifdef FLT_MAX // try to use it instead
|
||||||
|
# define __FLT_MAX__ FLT_MAX
|
||||||
|
# else // FLT_MAX
|
||||||
|
# define __FLT_MAX__ 3.402823466e+38f
|
||||||
|
# endif // FLT_MAX
|
||||||
|
#endif // __FLT_MAX__
|
||||||
|
#ifndef __DBL_MAX__
|
||||||
|
# ifdef DBL_MAX // try to use it instead
|
||||||
|
# define __DBL_MAX__ DBL_MAX
|
||||||
|
# else // DBL_MAX
|
||||||
|
# define __DBL_MAX__ 1.7976931348623158e+308
|
||||||
|
# endif // DBL_MAX
|
||||||
|
#endif // __DBL_MAX__
|
||||||
|
|
||||||
|
#ifndef FLT_MAX
|
||||||
|
#define FLT_MAX __FLT_MAX__
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef DBL_MAX
|
||||||
|
#define DBL_MAX __DBL_MAX__
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef M_PI
|
||||||
|
# define M_PI 3.1415926536
|
||||||
|
# define M_E 2.7182818284
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace BasicVector {
|
||||||
|
|
||||||
|
|
||||||
|
// basic inlined vector class
|
||||||
|
template<class Scalar>
|
||||||
|
class Vector3Dim
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// Constructor
|
||||||
|
inline Vector3Dim();
|
||||||
|
// Copy-Constructor
|
||||||
|
inline Vector3Dim(const Vector3Dim<Scalar> &v );
|
||||||
|
inline Vector3Dim(const float *);
|
||||||
|
inline Vector3Dim(const double *);
|
||||||
|
// construct a vector from one Scalar
|
||||||
|
inline Vector3Dim(Scalar);
|
||||||
|
// construct a vector from three Scalars
|
||||||
|
inline Vector3Dim(Scalar, Scalar, Scalar);
|
||||||
|
|
||||||
|
// get address of array for OpenGL
|
||||||
|
Scalar *getAddress() { return value; }
|
||||||
|
|
||||||
|
// Assignment operator
|
||||||
|
inline const Vector3Dim<Scalar>& operator= (const Vector3Dim<Scalar>& v);
|
||||||
|
// Assignment operator
|
||||||
|
inline const Vector3Dim<Scalar>& operator= (Scalar s);
|
||||||
|
// Assign and add operator
|
||||||
|
inline const Vector3Dim<Scalar>& operator+= (const Vector3Dim<Scalar>& v);
|
||||||
|
// Assign and add operator
|
||||||
|
inline const Vector3Dim<Scalar>& operator+= (Scalar s);
|
||||||
|
// Assign and sub operator
|
||||||
|
inline const Vector3Dim<Scalar>& operator-= (const Vector3Dim<Scalar>& v);
|
||||||
|
// Assign and sub operator
|
||||||
|
inline const Vector3Dim<Scalar>& operator-= (Scalar s);
|
||||||
|
// Assign and mult operator
|
||||||
|
inline const Vector3Dim<Scalar>& operator*= (const Vector3Dim<Scalar>& v);
|
||||||
|
// Assign and mult operator
|
||||||
|
inline const Vector3Dim<Scalar>& operator*= (Scalar s);
|
||||||
|
// Assign and div operator
|
||||||
|
inline const Vector3Dim<Scalar>& operator/= (const Vector3Dim<Scalar>& v);
|
||||||
|
// Assign and div operator
|
||||||
|
inline const Vector3Dim<Scalar>& operator/= (Scalar s);
|
||||||
|
|
||||||
|
|
||||||
|
// unary operator
|
||||||
|
inline Vector3Dim<Scalar> operator- () const;
|
||||||
|
|
||||||
|
// binary operator add
|
||||||
|
inline Vector3Dim<Scalar> operator+ (const Vector3Dim<Scalar>&) const;
|
||||||
|
// binary operator add
|
||||||
|
inline Vector3Dim<Scalar> operator+ (Scalar) const;
|
||||||
|
// binary operator sub
|
||||||
|
inline Vector3Dim<Scalar> operator- (const Vector3Dim<Scalar>&) const;
|
||||||
|
// binary operator sub
|
||||||
|
inline Vector3Dim<Scalar> operator- (Scalar) const;
|
||||||
|
// binary operator mult
|
||||||
|
inline Vector3Dim<Scalar> operator* (const Vector3Dim<Scalar>&) const;
|
||||||
|
// binary operator mult
|
||||||
|
inline Vector3Dim<Scalar> operator* (Scalar) const;
|
||||||
|
// binary operator div
|
||||||
|
inline Vector3Dim<Scalar> operator/ (const Vector3Dim<Scalar>&) const;
|
||||||
|
// binary operator div
|
||||||
|
inline Vector3Dim<Scalar> operator/ (Scalar) const;
|
||||||
|
|
||||||
|
// Projection normal to a vector
|
||||||
|
inline Vector3Dim<Scalar> getOrthogonalntlVector3Dim() const;
|
||||||
|
// Project into a plane
|
||||||
|
inline const Vector3Dim<Scalar>& projectNormalTo(const Vector3Dim<Scalar> &v);
|
||||||
|
|
||||||
|
// minimize
|
||||||
|
inline const Vector3Dim<Scalar> &minimize(const Vector3Dim<Scalar> &);
|
||||||
|
// maximize
|
||||||
|
inline const Vector3Dim<Scalar> &maximize(const Vector3Dim<Scalar> &);
|
||||||
|
|
||||||
|
// access operator
|
||||||
|
inline Scalar& operator[](unsigned int i);
|
||||||
|
// access operator
|
||||||
|
inline const Scalar& operator[](unsigned int i) const;
|
||||||
|
|
||||||
|
//! actual values
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
Scalar value[3];
|
||||||
|
};
|
||||||
|
struct {
|
||||||
|
Scalar x;
|
||||||
|
Scalar y;
|
||||||
|
Scalar z;
|
||||||
|
};
|
||||||
|
struct {
|
||||||
|
Scalar X;
|
||||||
|
Scalar Y;
|
||||||
|
Scalar Z;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
protected:
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// VECTOR inline FUNCTIONS
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
Constructor.
|
||||||
|
*/
|
||||||
|
template<class Scalar>
|
||||||
|
inline Vector3Dim<Scalar>::Vector3Dim( void )
|
||||||
|
{
|
||||||
|
value[0] = value[1] = value[2] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
Copy-Constructor.
|
||||||
|
*/
|
||||||
|
template<class Scalar>
|
||||||
|
inline Vector3Dim<Scalar>::Vector3Dim( const Vector3Dim<Scalar> &v )
|
||||||
|
{
|
||||||
|
value[0] = v.value[0];
|
||||||
|
value[1] = v.value[1];
|
||||||
|
value[2] = v.value[2];
|
||||||
|
}
|
||||||
|
template<class Scalar>
|
||||||
|
inline Vector3Dim<Scalar>::Vector3Dim( const float *fvalue)
|
||||||
|
{
|
||||||
|
value[0] = (Scalar)fvalue[0];
|
||||||
|
value[1] = (Scalar)fvalue[1];
|
||||||
|
value[2] = (Scalar)fvalue[2];
|
||||||
|
}
|
||||||
|
template<class Scalar>
|
||||||
|
inline Vector3Dim<Scalar>::Vector3Dim( const double *fvalue)
|
||||||
|
{
|
||||||
|
value[0] = (Scalar)fvalue[0];
|
||||||
|
value[1] = (Scalar)fvalue[1];
|
||||||
|
value[2] = (Scalar)fvalue[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
Constructor for a vector from a single Scalar. All components of
|
||||||
|
the vector get the same value.
|
||||||
|
\param s The value to set
|
||||||
|
\return The new vector
|
||||||
|
*/
|
||||||
|
template<class Scalar>
|
||||||
|
inline Vector3Dim<Scalar>::Vector3Dim(Scalar s )
|
||||||
|
{
|
||||||
|
value[0]= s;
|
||||||
|
value[1]= s;
|
||||||
|
value[2]= s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
Constructor for a vector from three Scalars.
|
||||||
|
\param s1 The value for the first vector component
|
||||||
|
\param s2 The value for the second vector component
|
||||||
|
\param s3 The value for the third vector component
|
||||||
|
\return The new vector
|
||||||
|
*/
|
||||||
|
template<class Scalar>
|
||||||
|
inline Vector3Dim<Scalar>::Vector3Dim(Scalar s1, Scalar s2, Scalar s3)
|
||||||
|
{
|
||||||
|
value[0]= s1;
|
||||||
|
value[1]= s2;
|
||||||
|
value[2]= s3;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
Copy a Vector3Dim componentwise.
|
||||||
|
\param v vector with values to be copied
|
||||||
|
\return Reference to self
|
||||||
|
*/
|
||||||
|
template<class Scalar>
|
||||||
|
inline const Vector3Dim<Scalar>&
|
||||||
|
Vector3Dim<Scalar>::operator=( const Vector3Dim<Scalar> &v )
|
||||||
|
{
|
||||||
|
value[0] = v.value[0];
|
||||||
|
value[1] = v.value[1];
|
||||||
|
value[2] = v.value[2];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
Copy a Scalar to each component.
|
||||||
|
\param s The value to copy
|
||||||
|
\return Reference to self
|
||||||
|
*/
|
||||||
|
template<class Scalar>
|
||||||
|
inline const Vector3Dim<Scalar>&
|
||||||
|
Vector3Dim<Scalar>::operator=(Scalar s)
|
||||||
|
{
|
||||||
|
value[0] = s;
|
||||||
|
value[1] = s;
|
||||||
|
value[2] = s;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
Add another Vector3Dim componentwise.
|
||||||
|
\param v vector with values to be added
|
||||||
|
\return Reference to self
|
||||||
|
*/
|
||||||
|
template<class Scalar>
|
||||||
|
inline const Vector3Dim<Scalar>&
|
||||||
|
Vector3Dim<Scalar>::operator+=( const Vector3Dim<Scalar> &v )
|
||||||
|
{
|
||||||
|
value[0] += v.value[0];
|
||||||
|
value[1] += v.value[1];
|
||||||
|
value[2] += v.value[2];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
Add a Scalar value to each component.
|
||||||
|
\param s Value to add
|
||||||
|
\return Reference to self
|
||||||
|
*/
|
||||||
|
template<class Scalar>
|
||||||
|
inline const Vector3Dim<Scalar>&
|
||||||
|
Vector3Dim<Scalar>::operator+=(Scalar s)
|
||||||
|
{
|
||||||
|
value[0] += s;
|
||||||
|
value[1] += s;
|
||||||
|
value[2] += s;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
Subtract another vector componentwise.
|
||||||
|
\param v vector of values to subtract
|
||||||
|
\return Reference to self
|
||||||
|
*/
|
||||||
|
template<class Scalar>
|
||||||
|
inline const Vector3Dim<Scalar>&
|
||||||
|
Vector3Dim<Scalar>::operator-=( const Vector3Dim<Scalar> &v )
|
||||||
|
{
|
||||||
|
value[0] -= v.value[0];
|
||||||
|
value[1] -= v.value[1];
|
||||||
|
value[2] -= v.value[2];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
Subtract a Scalar value from each component.
|
||||||
|
\param s Value to subtract
|
||||||
|
\return Reference to self
|
||||||
|
*/
|
||||||
|
template<class Scalar>
|
||||||
|
inline const Vector3Dim<Scalar>&
|
||||||
|
Vector3Dim<Scalar>::operator-=(Scalar s)
|
||||||
|
{
|
||||||
|
value[0]-= s;
|
||||||
|
value[1]-= s;
|
||||||
|
value[2]-= s;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
Multiply with another vector componentwise.
|
||||||
|
\param v vector of values to multiply with
|
||||||
|
\return Reference to self
|
||||||
|
*/
|
||||||
|
template<class Scalar>
|
||||||
|
inline const Vector3Dim<Scalar>&
|
||||||
|
Vector3Dim<Scalar>::operator*=( const Vector3Dim<Scalar> &v )
|
||||||
|
{
|
||||||
|
value[0] *= v.value[0];
|
||||||
|
value[1] *= v.value[1];
|
||||||
|
value[2] *= v.value[2];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
Multiply each component with a Scalar value.
|
||||||
|
\param s Value to multiply with
|
||||||
|
\return Reference to self
|
||||||
|
*/
|
||||||
|
template<class Scalar>
|
||||||
|
inline const Vector3Dim<Scalar>&
|
||||||
|
Vector3Dim<Scalar>::operator*=(Scalar s)
|
||||||
|
{
|
||||||
|
value[0] *= s;
|
||||||
|
value[1] *= s;
|
||||||
|
value[2] *= s;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
Divide by another Vector3Dim componentwise.
|
||||||
|
\param v vector of values to divide by
|
||||||
|
\return Reference to self
|
||||||
|
*/
|
||||||
|
template<class Scalar>
|
||||||
|
inline const Vector3Dim<Scalar>&
|
||||||
|
Vector3Dim<Scalar>::operator/=( const Vector3Dim<Scalar> &v )
|
||||||
|
{
|
||||||
|
value[0] /= v.value[0];
|
||||||
|
value[1] /= v.value[1];
|
||||||
|
value[2] /= v.value[2];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
Divide each component by a Scalar value.
|
||||||
|
\param s Value to divide by
|
||||||
|
\return Reference to self
|
||||||
|
*/
|
||||||
|
template<class Scalar>
|
||||||
|
inline const Vector3Dim<Scalar>&
|
||||||
|
Vector3Dim<Scalar>::operator/=(Scalar s)
|
||||||
|
{
|
||||||
|
value[0] /= s;
|
||||||
|
value[1] /= s;
|
||||||
|
value[2] /= s;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// unary operators
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
Build componentwise the negative this vector.
|
||||||
|
\return The new (negative) vector
|
||||||
|
*/
|
||||||
|
template<class Scalar>
|
||||||
|
inline Vector3Dim<Scalar>
|
||||||
|
Vector3Dim<Scalar>::operator-() const
|
||||||
|
{
|
||||||
|
return Vector3Dim<Scalar>(-value[0], -value[1], -value[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// binary operators
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
Build a vector with another vector added componentwise.
|
||||||
|
\param v The second vector to add
|
||||||
|
\return The sum vector
|
||||||
|
*/
|
||||||
|
template<class Scalar>
|
||||||
|
inline Vector3Dim<Scalar>
|
||||||
|
Vector3Dim<Scalar>::operator+( const Vector3Dim<Scalar> &v ) const
|
||||||
|
{
|
||||||
|
return Vector3Dim<Scalar>(value[0]+v.value[0],
|
||||||
|
value[1]+v.value[1],
|
||||||
|
value[2]+v.value[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
Build a vector with a Scalar value added to each component.
|
||||||
|
\param s The Scalar value to add
|
||||||
|
\return The sum vector
|
||||||
|
*/
|
||||||
|
template<class Scalar>
|
||||||
|
inline Vector3Dim<Scalar>
|
||||||
|
Vector3Dim<Scalar>::operator+(Scalar s) const
|
||||||
|
{
|
||||||
|
return Vector3Dim<Scalar>(value[0]+s,
|
||||||
|
value[1]+s,
|
||||||
|
value[2]+s);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
Build a vector with another vector subtracted componentwise.
|
||||||
|
\param v The second vector to subtract
|
||||||
|
\return The difference vector
|
||||||
|
*/
|
||||||
|
template<class Scalar>
|
||||||
|
inline Vector3Dim<Scalar>
|
||||||
|
Vector3Dim<Scalar>::operator-( const Vector3Dim<Scalar> &v ) const
|
||||||
|
{
|
||||||
|
return Vector3Dim<Scalar>(value[0]-v.value[0],
|
||||||
|
value[1]-v.value[1],
|
||||||
|
value[2]-v.value[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
Build a vector with a Scalar value subtracted componentwise.
|
||||||
|
\param s The Scalar value to subtract
|
||||||
|
\return The difference vector
|
||||||
|
*/
|
||||||
|
template<class Scalar>
|
||||||
|
inline Vector3Dim<Scalar>
|
||||||
|
Vector3Dim<Scalar>::operator-(Scalar s ) const
|
||||||
|
{
|
||||||
|
return Vector3Dim<Scalar>(value[0]-s,
|
||||||
|
value[1]-s,
|
||||||
|
value[2]-s);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
Build a vector with another vector multiplied by componentwise.
|
||||||
|
\param v The second vector to muliply with
|
||||||
|
\return The product vector
|
||||||
|
*/
|
||||||
|
template<class Scalar>
|
||||||
|
inline Vector3Dim<Scalar>
|
||||||
|
Vector3Dim<Scalar>::operator*( const Vector3Dim<Scalar>& v) const
|
||||||
|
{
|
||||||
|
return Vector3Dim<Scalar>(value[0]*v.value[0],
|
||||||
|
value[1]*v.value[1],
|
||||||
|
value[2]*v.value[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
Build a Vector3Dim with a Scalar value multiplied to each component.
|
||||||
|
\param s The Scalar value to multiply with
|
||||||
|
\return The product vector
|
||||||
|
*/
|
||||||
|
template<class Scalar>
|
||||||
|
inline Vector3Dim<Scalar>
|
||||||
|
Vector3Dim<Scalar>::operator*(Scalar s) const
|
||||||
|
{
|
||||||
|
return Vector3Dim<Scalar>(value[0]*s, value[1]*s, value[2]*s);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
Build a vector divided componentwise by another vector.
|
||||||
|
\param v The second vector to divide by
|
||||||
|
\return The ratio vector
|
||||||
|
*/
|
||||||
|
template<class Scalar>
|
||||||
|
inline Vector3Dim<Scalar>
|
||||||
|
Vector3Dim<Scalar>::operator/(const Vector3Dim<Scalar>& v) const
|
||||||
|
{
|
||||||
|
return Vector3Dim<Scalar>(value[0]/v.value[0],
|
||||||
|
value[1]/v.value[1],
|
||||||
|
value[2]/v.value[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
Build a vector divided componentwise by a Scalar value.
|
||||||
|
\param s The Scalar value to divide by
|
||||||
|
\return The ratio vector
|
||||||
|
*/
|
||||||
|
template<class Scalar>
|
||||||
|
inline Vector3Dim<Scalar>
|
||||||
|
Vector3Dim<Scalar>::operator/(Scalar s) const
|
||||||
|
{
|
||||||
|
return Vector3Dim<Scalar>(value[0]/s,
|
||||||
|
value[1]/s,
|
||||||
|
value[2]/s);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
Get a particular component of the vector.
|
||||||
|
\param i Number of Scalar to get
|
||||||
|
\return Reference to the component
|
||||||
|
*/
|
||||||
|
template<class Scalar>
|
||||||
|
inline Scalar&
|
||||||
|
Vector3Dim<Scalar>::operator[]( unsigned int i )
|
||||||
|
{
|
||||||
|
return value[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
Get a particular component of a constant vector.
|
||||||
|
\param i Number of Scalar to get
|
||||||
|
\return Reference to the component
|
||||||
|
*/
|
||||||
|
template<class Scalar>
|
||||||
|
inline const Scalar&
|
||||||
|
Vector3Dim<Scalar>::operator[]( unsigned int i ) const
|
||||||
|
{
|
||||||
|
return value[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// BLITZ compatibility functions
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
Compute the scalar product with another vector.
|
||||||
|
\param v The second vector to work with
|
||||||
|
\return The value of the scalar product
|
||||||
|
*/
|
||||||
|
template<class Scalar>
|
||||||
|
inline Scalar dot(const Vector3Dim<Scalar> &t, const Vector3Dim<Scalar> &v )
|
||||||
|
{
|
||||||
|
//return t.value[0]*v.value[0] + t.value[1]*v.value[1] + t.value[2]*v.value[2];
|
||||||
|
return ((t[0]*v[0]) + (t[1]*v[1]) + (t[2]*v[2]));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
Calculate the cross product of this and another vector
|
||||||
|
*/
|
||||||
|
template<class Scalar>
|
||||||
|
inline Vector3Dim<Scalar> cross(const Vector3Dim<Scalar> &t, const Vector3Dim<Scalar> &v)
|
||||||
|
{
|
||||||
|
Vector3Dim<Scalar> cp(
|
||||||
|
((t[1]*v[2]) - (t[2]*v[1])),
|
||||||
|
((t[2]*v[0]) - (t[0]*v[2])),
|
||||||
|
((t[0]*v[1]) - (t[1]*v[0])) );
|
||||||
|
return cp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
Compute a vector that is orthonormal to self. Nothing else can be assumed
|
||||||
|
for the direction of the new vector.
|
||||||
|
\return The orthonormal vector
|
||||||
|
*/
|
||||||
|
template<class Scalar>
|
||||||
|
Vector3Dim<Scalar>
|
||||||
|
Vector3Dim<Scalar>::getOrthogonalntlVector3Dim() const
|
||||||
|
{
|
||||||
|
// Determine the component with max. absolute value
|
||||||
|
int max= (fabs(value[0]) > fabs(value[1])) ? 0 : 1;
|
||||||
|
max= (fabs(value[max]) > fabs(value[2])) ? max : 2;
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
Choose another axis than the one with max. component and project
|
||||||
|
orthogonal to self
|
||||||
|
*/
|
||||||
|
Vector3Dim<Scalar> vec(0.0);
|
||||||
|
vec[(max+1)%3]= 1;
|
||||||
|
vec.normalize();
|
||||||
|
vec.projectNormalTo(this->getNormalized());
|
||||||
|
return vec;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
Projects the vector into a plane normal to the given vector, which must
|
||||||
|
have unit length. Self is modified.
|
||||||
|
\param v The plane normal
|
||||||
|
\return The projected vector
|
||||||
|
*/
|
||||||
|
template<class Scalar>
|
||||||
|
inline const Vector3Dim<Scalar>&
|
||||||
|
Vector3Dim<Scalar>::projectNormalTo(const Vector3Dim<Scalar> &v)
|
||||||
|
{
|
||||||
|
Scalar sprod = dot(*this,v);
|
||||||
|
value[0]= value[0] - v.value[0] * sprod;
|
||||||
|
value[1]= value[1] - v.value[1] * sprod;
|
||||||
|
value[2]= value[2] - v.value[2] * sprod;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Other helper functions
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
Minimize the vector, i.e. set each entry of the vector to the minimum
|
||||||
|
of both values.
|
||||||
|
\param pnt The second vector to compare with
|
||||||
|
\return Reference to the modified self
|
||||||
|
*/
|
||||||
|
template<class Scalar>
|
||||||
|
inline const Vector3Dim<Scalar> &
|
||||||
|
Vector3Dim<Scalar>::minimize(const Vector3Dim<Scalar> &pnt)
|
||||||
|
{
|
||||||
|
for (unsigned int i = 0; i < 3; i++)
|
||||||
|
value[i] = MIN(value[i],pnt[i]);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
Maximize the vector, i.e. set each entry of the vector to the maximum
|
||||||
|
of both values.
|
||||||
|
\param pnt The second vector to compare with
|
||||||
|
\return Reference to the modified self
|
||||||
|
*/
|
||||||
|
template<class Scalar>
|
||||||
|
inline const Vector3Dim<Scalar> &
|
||||||
|
Vector3Dim<Scalar>::maximize(const Vector3Dim<Scalar> &pnt)
|
||||||
|
{
|
||||||
|
for (unsigned int i = 0; i < 3; i++)
|
||||||
|
value[i] = MAX(value[i],pnt[i]);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/************************************************************************/
|
||||||
|
// HELPER FUNCTIONS, independent of implementation
|
||||||
|
/************************************************************************/
|
||||||
|
|
||||||
|
#define VECTOR_TYPE Vector3Dim<Scalar>
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
Compute the length (norm) of the vector.
|
||||||
|
\return The value of the norm
|
||||||
|
*/
|
||||||
|
template<class Scalar>
|
||||||
|
inline Scalar norm( const VECTOR_TYPE &v)
|
||||||
|
{
|
||||||
|
Scalar l = v[0]*v[0] + v[1]*v[1] + v[2]*v[2];
|
||||||
|
return (fabs(l-1.) < VECTOR_EPSILON*VECTOR_EPSILON) ? 1. : sqrt(l);
|
||||||
|
}
|
||||||
|
|
||||||
|
// for e.g. min max operator
|
||||||
|
inline Real normHelper(const Vector3Dim<Real> &v) {
|
||||||
|
return norm(v);
|
||||||
|
}
|
||||||
|
inline Real normHelper(const Real &v) {
|
||||||
|
return (0. < v) ? v : -v ;
|
||||||
|
}
|
||||||
|
inline Real normHelper(const int &v) {
|
||||||
|
return (0 < v) ? (Real)(v) : (Real)(-v) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
Same as getNorm but doesnt sqrt
|
||||||
|
*/
|
||||||
|
template<class Scalar>
|
||||||
|
inline Scalar normNoSqrt( const VECTOR_TYPE &v)
|
||||||
|
{
|
||||||
|
return v[0]*v[0] + v[1]*v[1] + v[2]*v[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
Compute a normalized vector based on this vector.
|
||||||
|
\return The new normalized vector
|
||||||
|
*/
|
||||||
|
template<class Scalar>
|
||||||
|
inline VECTOR_TYPE getNormalized( const VECTOR_TYPE &v)
|
||||||
|
{
|
||||||
|
Scalar l = v[0]*v[0] + v[1]*v[1] + v[2]*v[2];
|
||||||
|
if (fabs(l-1.) < VECTOR_EPSILON*VECTOR_EPSILON)
|
||||||
|
return v; /* normalized "enough"... */
|
||||||
|
else if (l > VECTOR_EPSILON*VECTOR_EPSILON)
|
||||||
|
{
|
||||||
|
Scalar fac = 1./sqrt(l);
|
||||||
|
return VECTOR_TYPE(v[0]*fac, v[1]*fac, v[2]*fac);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return VECTOR_TYPE((Scalar)0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
Compute the norm of the vector and normalize it.
|
||||||
|
\return The value of the norm
|
||||||
|
*/
|
||||||
|
template<class Scalar>
|
||||||
|
inline Scalar normalize( VECTOR_TYPE &v)
|
||||||
|
{
|
||||||
|
Scalar norm;
|
||||||
|
Scalar l = v[0]*v[0] + v[1]*v[1] + v[2]*v[2];
|
||||||
|
if (fabs(l-1.) < VECTOR_EPSILON*VECTOR_EPSILON) {
|
||||||
|
norm = 1.;
|
||||||
|
} else if (l > VECTOR_EPSILON*VECTOR_EPSILON) {
|
||||||
|
norm = sqrt(l);
|
||||||
|
Scalar fac = 1./norm;
|
||||||
|
v[0] *= fac;
|
||||||
|
v[1] *= fac;
|
||||||
|
v[2] *= fac;
|
||||||
|
} else {
|
||||||
|
v[0]= v[1]= v[2]= 0;
|
||||||
|
norm = 0.;
|
||||||
|
}
|
||||||
|
return (Scalar)norm;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
Compute a vector, that is self (as an incoming
|
||||||
|
vector) reflected at a surface with a distinct normal vector. Note
|
||||||
|
that the normal is reversed, if the scalar product with it is positive.
|
||||||
|
\param n The surface normal
|
||||||
|
\return The new reflected vector
|
||||||
|
*/
|
||||||
|
template<class Scalar>
|
||||||
|
inline VECTOR_TYPE reflectVector(const VECTOR_TYPE &t, const VECTOR_TYPE &n)
|
||||||
|
{
|
||||||
|
VECTOR_TYPE nn= (dot(t, n) > 0.0) ? (n*-1.0) : n;
|
||||||
|
return ( t - nn * (2.0 * dot(nn, t)) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
* My own refraction calculation
|
||||||
|
* Taken from Glassner's book, section 5.2 (Heckberts method)
|
||||||
|
*/
|
||||||
|
template<class Scalar>
|
||||||
|
inline VECTOR_TYPE refractVector(const VECTOR_TYPE &t, const VECTOR_TYPE &normal, Scalar nt, Scalar nair, int &refRefl)
|
||||||
|
{
|
||||||
|
Scalar eta = nair / nt;
|
||||||
|
Scalar n = -dot(t, normal);
|
||||||
|
Scalar tt = 1.0 + eta*eta* (n*n-1.0);
|
||||||
|
if(tt<0.0) {
|
||||||
|
// we have total reflection!
|
||||||
|
refRefl = 1;
|
||||||
|
} else {
|
||||||
|
// normal reflection
|
||||||
|
tt = eta*n - sqrt(tt);
|
||||||
|
return( t*eta + normal*tt );
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
Test two ntlVector3Dims for equality based on the equality of their
|
||||||
|
values within a small threshold.
|
||||||
|
\param c The second vector to compare
|
||||||
|
\return TRUE if both are equal
|
||||||
|
\sa getEpsilon()
|
||||||
|
*/
|
||||||
|
template<class Scalar>
|
||||||
|
inline bool equal(const VECTOR_TYPE &v, const VECTOR_TYPE &c)
|
||||||
|
{
|
||||||
|
return (ABS(v[0]-c[0]) +
|
||||||
|
ABS(v[1]-c[1]) +
|
||||||
|
ABS(v[2]-c[2]) < VECTOR_EPSILON);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
* Assume this vector is an RGB color, and convert it to HSV
|
||||||
|
*/
|
||||||
|
template<class Scalar>
|
||||||
|
inline void rgbToHsv( VECTOR_TYPE &V )
|
||||||
|
{
|
||||||
|
Scalar h=0,s=0,v=0;
|
||||||
|
Scalar maxrgb, minrgb, delta;
|
||||||
|
// convert to hsv...
|
||||||
|
maxrgb = V[0];
|
||||||
|
int maxindex = 1;
|
||||||
|
if(V[2] > maxrgb){ maxrgb = V[2]; maxindex = 2; }
|
||||||
|
if(V[1] > maxrgb){ maxrgb = V[1]; maxindex = 3; }
|
||||||
|
minrgb = V[0];
|
||||||
|
if(V[2] < minrgb) minrgb = V[2];
|
||||||
|
if(V[1] < minrgb) minrgb = V[1];
|
||||||
|
|
||||||
|
v = maxrgb;
|
||||||
|
delta = maxrgb-minrgb;
|
||||||
|
|
||||||
|
if(maxrgb > 0) s = delta/maxrgb;
|
||||||
|
else s = 0;
|
||||||
|
|
||||||
|
h = 0;
|
||||||
|
if(s > 0) {
|
||||||
|
if(maxindex == 1) {
|
||||||
|
h = ((V[1]-V[2])/delta) + 0.0; }
|
||||||
|
if(maxindex == 2) {
|
||||||
|
h = ((V[2]-V[0])/delta) + 2.0; }
|
||||||
|
if(maxindex == 3) {
|
||||||
|
h = ((V[0]-V[1])/delta) + 4.0; }
|
||||||
|
h *= 60.0;
|
||||||
|
if(h < 0.0) h += 360.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
V[0] = h;
|
||||||
|
V[1] = s;
|
||||||
|
V[2] = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
* Assume this vector is HSV and convert to RGB
|
||||||
|
*/
|
||||||
|
template<class Scalar>
|
||||||
|
inline void hsvToRgb( VECTOR_TYPE &V )
|
||||||
|
{
|
||||||
|
Scalar h = V[0], s = V[1], v = V[2];
|
||||||
|
Scalar r=0,g=0,b=0;
|
||||||
|
Scalar p,q,t, fracth;
|
||||||
|
int floorh;
|
||||||
|
// ...and back to rgb
|
||||||
|
if(s == 0) {
|
||||||
|
r = g = b = v; }
|
||||||
|
else {
|
||||||
|
h /= 60.0;
|
||||||
|
floorh = (int)h;
|
||||||
|
fracth = h - floorh;
|
||||||
|
p = v * (1.0 - s);
|
||||||
|
q = v * (1.0 - (s * fracth));
|
||||||
|
t = v * (1.0 - (s * (1.0 - fracth)));
|
||||||
|
switch (floorh) {
|
||||||
|
case 0: r = v; g = t; b = p; break;
|
||||||
|
case 1: r = q; g = v; b = p; break;
|
||||||
|
case 2: r = p; g = v; b = t; break;
|
||||||
|
case 3: r = p; g = q; b = v; break;
|
||||||
|
case 4: r = t; g = p; b = v; break;
|
||||||
|
case 5: r = v; g = p; b = q; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
V[0] = r;
|
||||||
|
V[1] = g;
|
||||||
|
V[2] = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// STREAM FUNCTIONS
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//! global string for formatting vector output in utilities.cpp
|
||||||
|
//extern const char *globVecFormatStr;
|
||||||
|
static const char *globVecFormatStr = "[%6.4f,%6.4f,%6.4f]";
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
Outputs the object in human readable form using the format
|
||||||
|
[x,y,z]
|
||||||
|
*/
|
||||||
|
template<class Scalar>
|
||||||
|
std::ostream&
|
||||||
|
operator<<( std::ostream& os, const BasicVector::Vector3Dim<Scalar>& i )
|
||||||
|
{
|
||||||
|
char buf[256];
|
||||||
|
#if 0
|
||||||
|
#if _WIN32
|
||||||
|
sprintf(buf,globVecFormatStr, (double)i[0],(double)i[1],(double)i[2]);
|
||||||
|
#else
|
||||||
|
snprintf(buf,256,globVecFormatStr, (double)i[0],(double)i[1],(double)i[2]);
|
||||||
|
#endif
|
||||||
|
os << std::string(buf);
|
||||||
|
#endif
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
Reads the contents of the object from a stream using the same format
|
||||||
|
as the output operator.
|
||||||
|
*/
|
||||||
|
template<class Scalar>
|
||||||
|
std::istream&
|
||||||
|
operator>>( std::istream& is, BasicVector::Vector3Dim<Scalar>& i )
|
||||||
|
{
|
||||||
|
char c;
|
||||||
|
char dummy[3];
|
||||||
|
is >> c >> i[0] >> dummy >> i[1] >> dummy >> i[2] >> c;
|
||||||
|
return is;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************/
|
||||||
|
// typedefs!
|
||||||
|
/**************************************************************************/
|
||||||
|
|
||||||
|
/* get minimal vector length value that can be discriminated. */
|
||||||
|
inline Real getVecEpsilon() { return (Real)VECTOR_EPSILON; }
|
||||||
|
|
||||||
|
// a 3D integer vector
|
||||||
|
typedef Vector3Dim<int> Vec3Int;
|
||||||
|
|
||||||
|
// a 3D vector
|
||||||
|
typedef Vector3Dim<Real> Vec3;
|
||||||
|
|
||||||
|
|
||||||
|
}; // namespace
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* BASICVECTOR_H */
|
||||||
457
intern/smoke/intern/WAVELET_NOISE.h
Normal file
457
intern/smoke/intern/WAVELET_NOISE.h
Normal file
@@ -0,0 +1,457 @@
|
|||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// This file is part of Wavelet Turbulence.
|
||||||
|
//
|
||||||
|
// Wavelet Turbulence 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 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Wavelet Turbulence 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 Wavelet Turbulence. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// Copyright 2008 Theodore Kim and Nils Thuerey
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Wavelet noise functions
|
||||||
|
//
|
||||||
|
// This code is based on the C code provided in the appendices of:
|
||||||
|
//
|
||||||
|
// @article{1073264,
|
||||||
|
// author = {Robert L. Cook and Tony DeRose},
|
||||||
|
// title = {Wavelet noise},
|
||||||
|
// journal = {ACM Trans. Graph.},
|
||||||
|
// volume = {24},
|
||||||
|
// number = {3},
|
||||||
|
// year = {2005},
|
||||||
|
// issn = {0730-0301},
|
||||||
|
// pages = {803--811},
|
||||||
|
// doi = {http://doi.acm.org/10.1145/1073204.1073264},
|
||||||
|
// publisher = {ACM},
|
||||||
|
// address = {New York, NY, USA},
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef WAVELET_NOISE_H
|
||||||
|
#define WAVELET_NOISE_H
|
||||||
|
|
||||||
|
#include <MERSENNETWISTER.h>
|
||||||
|
|
||||||
|
#define NOISE_TILE_SIZE 128
|
||||||
|
static const int noiseTileSize = NOISE_TILE_SIZE;
|
||||||
|
|
||||||
|
// warning - noiseTileSize has to be 128^3!
|
||||||
|
#define modFast128(x) ((x) & 127)
|
||||||
|
#define modFast64(x) ((x) & 63)
|
||||||
|
#define DOWNCOEFFS 0.000334f,-0.001528f, 0.000410f, 0.003545f,-0.000938f,-0.008233f, 0.002172f, 0.019120f, \
|
||||||
|
-0.005040f,-0.044412f, 0.011655f, 0.103311f,-0.025936f,-0.243780f, 0.033979f, 0.655340f, \
|
||||||
|
0.655340f, 0.033979f,-0.243780f,-0.025936f, 0.103311f, 0.011655f,-0.044412f,-0.005040f, \
|
||||||
|
0.019120f, 0.002172f,-0.008233f,-0.000938f, 0.003546f, 0.000410f,-0.001528f, 0.000334f
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Wavelet downsampling -- periodic boundary conditions
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
static void downsampleX(float *from, float *to, int n){
|
||||||
|
// if these values are not local incorrect results are generated
|
||||||
|
float downCoeffs[32] = { DOWNCOEFFS };
|
||||||
|
const float *a = &downCoeffs[16];
|
||||||
|
for (int i = 0; i < n / 2; i++) {
|
||||||
|
to[i] = 0;
|
||||||
|
for (int k = 2 * i - 16; k <= 2 * i + 16; k++)
|
||||||
|
to[i] += a[k - 2 * i] * from[modFast128(k)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void downsampleY(float *from, float *to, int n){
|
||||||
|
// if these values are not local incorrect results are generated
|
||||||
|
float downCoeffs[32] = { DOWNCOEFFS };
|
||||||
|
const float *a = &downCoeffs[16];
|
||||||
|
for (int i = 0; i < n / 2; i++) {
|
||||||
|
to[i * n] = 0;
|
||||||
|
for (int k = 2 * i - 16; k <= 2 * i + 16; k++)
|
||||||
|
to[i * n] += a[k - 2 * i] * from[modFast128(k) * n];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void downsampleZ(float *from, float *to, int n){
|
||||||
|
// if these values are not local incorrect results are generated
|
||||||
|
float downCoeffs[32] = { DOWNCOEFFS };
|
||||||
|
const float *a = &downCoeffs[16];
|
||||||
|
for (int i = 0; i < n / 2; i++) {
|
||||||
|
to[i * n * n] = 0;
|
||||||
|
for (int k = 2 * i - 16; k <= 2 * i + 16; k++)
|
||||||
|
to[i * n * n] += a[k - 2 * i] * from[modFast128(k) * n * n];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Wavelet downsampling -- Neumann boundary conditions
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
static void downsampleNeumann(const float *from, float *to, int n, int stride)
|
||||||
|
{
|
||||||
|
// if these values are not local incorrect results are generated
|
||||||
|
float downCoeffs[32] = { DOWNCOEFFS };
|
||||||
|
static const float *const aCoCenter= &downCoeffs[16];
|
||||||
|
for (int i = 0; i < n / 2; i++) {
|
||||||
|
to[i * stride] = 0;
|
||||||
|
for (int k = 2 * i - 16; k < 2 * i + 16; k++) {
|
||||||
|
// handle boundary
|
||||||
|
float fromval;
|
||||||
|
if (k < 0) {
|
||||||
|
fromval = from[0];
|
||||||
|
} else if(k > n - 1) {
|
||||||
|
fromval = from[(n - 1) * stride];
|
||||||
|
} else {
|
||||||
|
fromval = from[k * stride];
|
||||||
|
}
|
||||||
|
to[i * stride] += aCoCenter[k - 2 * i] * fromval;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void downsampleXNeumann(float* to, const float* from, int sx,int sy, int sz) {
|
||||||
|
for (int iy = 0; iy < sy; iy++)
|
||||||
|
for (int iz = 0; iz < sz; iz++) {
|
||||||
|
const int i = iy * sx + iz*sx*sy;
|
||||||
|
downsampleNeumann(&from[i], &to[i], sx, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void downsampleYNeumann(float* to, const float* from, int sx,int sy, int sz) {
|
||||||
|
for (int ix = 0; ix < sx; ix++)
|
||||||
|
for (int iz = 0; iz < sz; iz++) {
|
||||||
|
const int i = ix + iz*sx*sy;
|
||||||
|
downsampleNeumann(&from[i], &to[i], sy, sx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void downsampleZNeumann(float* to, const float* from, int sx,int sy, int sz) {
|
||||||
|
for (int ix = 0; ix < sx; ix++)
|
||||||
|
for (int iy = 0; iy < sy; iy++) {
|
||||||
|
const int i = ix + iy*sx;
|
||||||
|
downsampleNeumann(&from[i], &to[i], sz, sx*sy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Wavelet upsampling - periodic boundary conditions
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
static float _upCoeffs[4] = {0.25f, 0.75f, 0.75f, 0.25f};
|
||||||
|
static void upsampleX(float *from, float *to, int n) {
|
||||||
|
const float *p = &_upCoeffs[2];
|
||||||
|
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
to[i] = 0;
|
||||||
|
for (int k = i / 2; k <= i / 2 + 1; k++)
|
||||||
|
to[i] += p[i - 2 * k] * from[modFast64(k)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void upsampleY(float *from, float *to, int n) {
|
||||||
|
const float *p = &_upCoeffs[2];
|
||||||
|
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
to[i * n] = 0;
|
||||||
|
for (int k = i / 2; k <= i / 2 + 1; k++)
|
||||||
|
to[i * n] += p[i - 2 * k] * from[modFast64(k) * n];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void upsampleZ(float *from, float *to, int n) {
|
||||||
|
const float *p = &_upCoeffs[2];
|
||||||
|
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
to[i * n * n] = 0;
|
||||||
|
for (int k = i / 2; k <= i / 2 + 1; k++)
|
||||||
|
to[i * n * n] += p[i - 2 * k] * from[modFast64(k) * n * n];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Wavelet upsampling - Neumann boundary conditions
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
static void upsampleNeumann(const float *from, float *to, int n, int stride) {
|
||||||
|
static const float *const pCoCenter = &_upCoeffs[2];
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
to[i * stride] = 0;
|
||||||
|
for (int k = i / 2; k <= i / 2 + 1; k++) {
|
||||||
|
float fromval;
|
||||||
|
if(k>n/2) {
|
||||||
|
fromval = from[(n/2) * stride];
|
||||||
|
} else {
|
||||||
|
fromval = from[k * stride];
|
||||||
|
}
|
||||||
|
to[i * stride] += pCoCenter[i - 2 * k] * fromval;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void upsampleXNeumann(float* to, const float* from, int sx, int sy, int sz) {
|
||||||
|
for (int iy = 0; iy < sy; iy++)
|
||||||
|
for (int iz = 0; iz < sz; iz++) {
|
||||||
|
const int i = iy * sx + iz*sx*sy;
|
||||||
|
upsampleNeumann(&from[i], &to[i], sx, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void upsampleYNeumann(float* to, const float* from, int sx, int sy, int sz) {
|
||||||
|
for (int ix = 0; ix < sx; ix++)
|
||||||
|
for (int iz = 0; iz < sz; iz++) {
|
||||||
|
const int i = ix + iz*sx*sy;
|
||||||
|
upsampleNeumann(&from[i], &to[i], sy, sx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void upsampleZNeumann(float* to, const float* from, int sx, int sy, int sz) {
|
||||||
|
for (int ix = 0; ix < sx; ix++)
|
||||||
|
for (int iy = 0; iy < sy; iy++) {
|
||||||
|
const int i = ix + iy*sx;
|
||||||
|
upsampleNeumann(&from[i], &to[i], sz, sx*sy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// load in an existing noise tile
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
static bool loadTile(float* const noiseTileData, std::string filename)
|
||||||
|
{
|
||||||
|
FILE* file;
|
||||||
|
file = fopen(filename.c_str(), "rb");
|
||||||
|
|
||||||
|
if (file == NULL) {
|
||||||
|
printf("loadTile: No noise tile '%s' found.\n", filename.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// dimensions
|
||||||
|
int gridSize = noiseTileSize * noiseTileSize * noiseTileSize;
|
||||||
|
|
||||||
|
// noiseTileData memory is managed by caller
|
||||||
|
size_t bread = fread((void*)noiseTileData, sizeof(float), gridSize, file);
|
||||||
|
fclose(file);
|
||||||
|
printf("Noise tile file '%s' loaded.\n", filename.c_str());
|
||||||
|
|
||||||
|
if (bread != gridSize) {
|
||||||
|
printf("loadTile: Noise tile '%s' is wrong size %d.\n", filename.c_str(), bread);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// write out an existing noise tile
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
static void saveTile(float* const noiseTileData, std::string filename)
|
||||||
|
{
|
||||||
|
FILE* file;
|
||||||
|
file = fopen(filename.c_str(), "wb");
|
||||||
|
|
||||||
|
if (file == NULL) {
|
||||||
|
printf("saveTile: Noise tile '%s' could not be saved.\n", filename.c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fwrite((void*)noiseTileData, sizeof(float), noiseTileSize * noiseTileSize * noiseTileSize, file);
|
||||||
|
fclose(file);
|
||||||
|
|
||||||
|
printf("saveTile: Noise tile file '%s' saved.\n", filename.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// create a new noise tile if necessary
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
static void generateTile_WAVELET(float* const noiseTileData, std::string filename) {
|
||||||
|
// if a tile already exists, just use that
|
||||||
|
if (loadTile(noiseTileData, filename)) return;
|
||||||
|
|
||||||
|
const int n = noiseTileSize;
|
||||||
|
const int n3 = n*n*n;
|
||||||
|
std::cout <<"Generating new 3d noise tile size="<<n<<"^3 \n";
|
||||||
|
MTRand twister;
|
||||||
|
|
||||||
|
float *temp13 = new float[n3];
|
||||||
|
float *temp23 = new float[n3];
|
||||||
|
float *noise3 = new float[n3];
|
||||||
|
|
||||||
|
// initialize
|
||||||
|
for (int i = 0; i < n3; i++) {
|
||||||
|
temp13[i] = temp23[i] = noise3[i] = 0.;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 1. Fill the tile with random numbers in the range -1 to 1.
|
||||||
|
for (int i = 0; i < n3; i++)
|
||||||
|
noise3[i] = twister.randNorm();
|
||||||
|
|
||||||
|
// Steps 2 and 3. Downsample and upsample the tile
|
||||||
|
for (int iy = 0; iy < n; iy++)
|
||||||
|
for (int iz = 0; iz < n; iz++) {
|
||||||
|
const int i = iy * n + iz*n*n;
|
||||||
|
downsampleX(&noise3[i], &temp13[i], n);
|
||||||
|
upsampleX (&temp13[i], &temp23[i], n);
|
||||||
|
}
|
||||||
|
for (int ix = 0; ix < n; ix++)
|
||||||
|
for (int iz = 0; iz < n; iz++) {
|
||||||
|
const int i = ix + iz*n*n;
|
||||||
|
downsampleY(&temp23[i], &temp13[i], n);
|
||||||
|
upsampleY (&temp13[i], &temp23[i], n);
|
||||||
|
}
|
||||||
|
for (int ix = 0; ix < n; ix++)
|
||||||
|
for (int iy = 0; iy < n; iy++) {
|
||||||
|
const int i = ix + iy*n;
|
||||||
|
downsampleZ(&temp23[i], &temp13[i], n);
|
||||||
|
upsampleZ (&temp13[i], &temp23[i], n);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 4. Subtract out the coarse-scale contribution
|
||||||
|
for (int i = 0; i < n3; i++)
|
||||||
|
noise3[i] -= temp23[i];
|
||||||
|
|
||||||
|
// Avoid even/odd variance difference by adding odd-offset version of noise to itself.
|
||||||
|
int offset = n / 2;
|
||||||
|
if (offset % 2 == 0) offset++;
|
||||||
|
|
||||||
|
int icnt=0;
|
||||||
|
for (int ix = 0; ix < n; ix++)
|
||||||
|
for (int iy = 0; iy < n; iy++)
|
||||||
|
for (int iz = 0; iz < n; iz++) {
|
||||||
|
temp13[icnt] = noise3[modFast128(ix+offset) + modFast128(iy+offset)*n + modFast128(iz+offset)*n*n];
|
||||||
|
icnt++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < n3; i++)
|
||||||
|
noise3[i] += temp13[i];
|
||||||
|
|
||||||
|
for (int i = 0; i < n3; i++)
|
||||||
|
noiseTileData[i] = noise3[i];
|
||||||
|
|
||||||
|
saveTile(noise3, filename);
|
||||||
|
delete[] temp13;
|
||||||
|
delete[] temp23;
|
||||||
|
std::cout <<"Generating new 3d noise done\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// x derivative of noise
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
static inline float WNoiseDx(Vec3 p, float* data) {
|
||||||
|
int c[3], mid[3], n = noiseTileSize;
|
||||||
|
float w[3][3], t, result = 0;
|
||||||
|
|
||||||
|
mid[0] = (int)ceil(p[0] - 0.5);
|
||||||
|
t = mid[0] - (p[0] - 0.5);
|
||||||
|
w[0][0] = -t;
|
||||||
|
w[0][2] = (1.f - t);
|
||||||
|
w[0][1] = 2.0f * t - 1.0f;
|
||||||
|
|
||||||
|
mid[1] = (int)ceil(p[1] - 0.5);
|
||||||
|
t = mid[1] - (p[1] - 0.5);
|
||||||
|
w[1][0] = t * t / 2;
|
||||||
|
w[1][2] = (1 - t) * (1 - t) / 2;
|
||||||
|
w[1][1] = 1 - w[1][0] - w[1][2];
|
||||||
|
|
||||||
|
mid[2] = (int)ceil(p[2] - 0.5);
|
||||||
|
t = mid[2] - (p[2] - 0.5);
|
||||||
|
w[2][0] = t * t / 2;
|
||||||
|
w[2][2] = (1 - t) * (1 - t)/2;
|
||||||
|
w[2][1] = 1 - w[2][0] - w[2][2];
|
||||||
|
|
||||||
|
// to optimize, explicitly unroll this loop
|
||||||
|
for (int z = -1; z <=1; z++)
|
||||||
|
for (int y = -1; y <=1; y++)
|
||||||
|
for (int x = -1; x <=1; x++)
|
||||||
|
{
|
||||||
|
float weight = 1.0f;
|
||||||
|
c[0] = modFast128(mid[0] + x);
|
||||||
|
weight *= w[0][x+1];
|
||||||
|
c[1] = modFast128(mid[1] + y);
|
||||||
|
weight *= w[1][y+1];
|
||||||
|
c[2] = modFast128(mid[2] + z);
|
||||||
|
weight *= w[2][z+1];
|
||||||
|
result += weight * data[c[2]*n*n+c[1]*n+c[0]];
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// y derivative of noise
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
static inline float WNoiseDy(Vec3 p, float* data) {
|
||||||
|
int c[3], mid[3], n=noiseTileSize;
|
||||||
|
float w[3][3], t, result =0;
|
||||||
|
|
||||||
|
mid[0] = (int)ceil(p[0] - 0.5);
|
||||||
|
t = mid[0]-(p[0] - 0.5);
|
||||||
|
w[0][0] = t * t / 2;
|
||||||
|
w[0][2] = (1 - t) * (1 - t) / 2;
|
||||||
|
w[0][1] = 1 - w[0][0] - w[0][2];
|
||||||
|
|
||||||
|
mid[1] = (int)ceil(p[1] - 0.5);
|
||||||
|
t = mid[1]-(p[1] - 0.5);
|
||||||
|
w[1][0] = -t;
|
||||||
|
w[1][2] = (1.f - t);
|
||||||
|
w[1][1] = 2.0f * t - 1.0f;
|
||||||
|
|
||||||
|
mid[2] = (int)ceil(p[2] - 0.5);
|
||||||
|
t = mid[2] - (p[2] - 0.5);
|
||||||
|
w[2][0] = t * t / 2;
|
||||||
|
w[2][2] = (1 - t) * (1 - t)/2;
|
||||||
|
w[2][1] = 1 - w[2][0] - w[2][2];
|
||||||
|
|
||||||
|
// to optimize, explicitly unroll this loop
|
||||||
|
for (int z = -1; z <=1; z++)
|
||||||
|
for (int y = -1; y <=1; y++)
|
||||||
|
for (int x = -1; x <=1; x++)
|
||||||
|
{
|
||||||
|
float weight = 1.0f;
|
||||||
|
c[0] = modFast128(mid[0] + x);
|
||||||
|
weight *= w[0][x+1];
|
||||||
|
c[1] = modFast128(mid[1] + y);
|
||||||
|
weight *= w[1][y+1];
|
||||||
|
c[2] = modFast128(mid[2] + z);
|
||||||
|
weight *= w[2][z+1];
|
||||||
|
result += weight * data[c[2]*n*n+c[1]*n+c[0]];
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// z derivative of noise
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
static inline float WNoiseDz(Vec3 p, float* data) {
|
||||||
|
int c[3], mid[3], n=noiseTileSize;
|
||||||
|
float w[3][3], t, result =0;
|
||||||
|
|
||||||
|
mid[0] = (int)ceil(p[0] - 0.5);
|
||||||
|
t = mid[0]-(p[0] - 0.5);
|
||||||
|
w[0][0] = t * t / 2;
|
||||||
|
w[0][2] = (1 - t) * (1 - t) / 2;
|
||||||
|
w[0][1] = 1 - w[0][0] - w[0][2];
|
||||||
|
|
||||||
|
mid[1] = (int)ceil(p[1] - 0.5);
|
||||||
|
t = mid[1]-(p[1] - 0.5);
|
||||||
|
w[1][0] = t * t / 2;
|
||||||
|
w[1][2] = (1 - t) * (1 - t) / 2;
|
||||||
|
w[1][1] = 1 - w[1][0] - w[1][2];
|
||||||
|
|
||||||
|
mid[2] = (int)ceil(p[2] - 0.5);
|
||||||
|
t = mid[2] - (p[2] - 0.5);
|
||||||
|
w[2][0] = -t;
|
||||||
|
w[2][2] = (1.f - t);
|
||||||
|
w[2][1] = 2.0f * t - 1.0f;
|
||||||
|
|
||||||
|
// to optimize, explicitly unroll this loop
|
||||||
|
for (int z = -1; z <=1; z++)
|
||||||
|
for (int y = -1; y <=1; y++)
|
||||||
|
for (int x = -1; x <=1; x++)
|
||||||
|
{
|
||||||
|
float weight = 1.0f;
|
||||||
|
c[0] = modFast128(mid[0] + x);
|
||||||
|
weight *= w[0][x+1];
|
||||||
|
c[1] = modFast128(mid[1] + y);
|
||||||
|
weight *= w[1][y+1];
|
||||||
|
c[2] = modFast128(mid[2] + z);
|
||||||
|
weight *= w[2][z+1];
|
||||||
|
result += weight * data[c[2]*n*n+c[1]*n+c[0]];
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
965
intern/smoke/intern/WTURBULENCE.cpp
Normal file
965
intern/smoke/intern/WTURBULENCE.cpp
Normal file
@@ -0,0 +1,965 @@
|
|||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// This file is part of Wavelet Turbulence.
|
||||||
|
//
|
||||||
|
// Wavelet Turbulence 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 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Wavelet Turbulence 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 Wavelet Turbulence. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// Copyright 2008 Theodore Kim and Nils Thuerey
|
||||||
|
//
|
||||||
|
// WTURBULENCE handling
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "WTURBULENCE.h"
|
||||||
|
#include "INTERPOLATE.h"
|
||||||
|
#include "IMAGE.h"
|
||||||
|
#include <MERSENNETWISTER.h>
|
||||||
|
#include "WAVELET_NOISE.h"
|
||||||
|
#include "FFT_NOISE.h"
|
||||||
|
#include "EIGENVALUE_HELPER.h"
|
||||||
|
#include "LU_HELPER.h"
|
||||||
|
#include "SPHERE.h"
|
||||||
|
#include <zlib.h>
|
||||||
|
|
||||||
|
// needed to access static advection functions
|
||||||
|
#include "FLUID_3D.h"
|
||||||
|
|
||||||
|
#if PARALLEL==1
|
||||||
|
#include <omp.h>
|
||||||
|
#endif // PARALLEL
|
||||||
|
|
||||||
|
// 2^ {-5/6}
|
||||||
|
static const float persistence = 0.56123f;
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// constructor
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
WTURBULENCE::WTURBULENCE(int xResSm, int yResSm, int zResSm, int amplify)
|
||||||
|
{
|
||||||
|
// if noise magnitude is below this threshold, its contribution
|
||||||
|
// is negilgible, so stop evaluating new octaves
|
||||||
|
_cullingThreshold = 1e-3;
|
||||||
|
|
||||||
|
// factor by which to increase the simulation resolution
|
||||||
|
_amplify = amplify;
|
||||||
|
|
||||||
|
// manually adjust the overall amount of turbulence
|
||||||
|
_strength = 2.;
|
||||||
|
|
||||||
|
// add the corresponding octaves of noise
|
||||||
|
_octaves = (int)log((float)_amplify) / log(2.0f); // XXX DEBUG/ TODO: int casting correct? - dg
|
||||||
|
|
||||||
|
// noise resolution
|
||||||
|
_xResBig = _amplify * xResSm;
|
||||||
|
_yResBig = _amplify * yResSm;
|
||||||
|
_zResBig = _amplify * zResSm;
|
||||||
|
_resBig = Vec3Int(_xResBig, _yResBig, _zResBig);
|
||||||
|
_invResBig = Vec3(1./(float)_resBig[0], 1./(float)_resBig[1], 1./(float)_resBig[2]);
|
||||||
|
_slabSizeBig = _xResBig*_yResBig;
|
||||||
|
_totalCellsBig = _slabSizeBig * _zResBig;
|
||||||
|
|
||||||
|
// original / small resolution
|
||||||
|
_xResSm = xResSm;
|
||||||
|
_yResSm = yResSm;
|
||||||
|
_zResSm = zResSm;
|
||||||
|
_resSm = Vec3Int(xResSm, yResSm, zResSm);
|
||||||
|
_invResSm = Vec3(1./(float)_resSm[0], 1./(float)_resSm[1], 1./(float)_resSm[2] );
|
||||||
|
_slabSizeSm = _xResSm*_yResSm;
|
||||||
|
_totalCellsSm = _slabSizeSm * _zResSm;
|
||||||
|
|
||||||
|
// allocate high resolution density field
|
||||||
|
_totalStepsBig = 0;
|
||||||
|
_densityBig = new float[_totalCellsBig];
|
||||||
|
_densityBigOld = new float[_totalCellsBig];
|
||||||
|
|
||||||
|
// allocate high resolution velocity field. Note that this is only
|
||||||
|
// necessary because we use MacCormack advection. For semi-Lagrangian
|
||||||
|
// advection, these arrays are not necessary.
|
||||||
|
_tempBig1 = _tempBig2 =
|
||||||
|
_bigUx = _bigUy = _bigUz = NULL;
|
||||||
|
_tempBig1 = new float[_totalCellsBig];
|
||||||
|
_tempBig2 = new float[_totalCellsBig];
|
||||||
|
_bigUx = new float[_totalCellsBig];
|
||||||
|
_bigUy = new float[_totalCellsBig];
|
||||||
|
_bigUz = new float[_totalCellsBig];
|
||||||
|
|
||||||
|
for(int i = 0; i < _totalCellsBig; i++) {
|
||||||
|
_densityBig[i] =
|
||||||
|
_densityBigOld[i] =
|
||||||
|
_bigUx[i] =
|
||||||
|
_bigUy[i] =
|
||||||
|
_bigUz[i] =
|
||||||
|
_tempBig1[i] =
|
||||||
|
_tempBig2[i] = 0.;
|
||||||
|
}
|
||||||
|
|
||||||
|
// allocate & init texture coordinates
|
||||||
|
_tcU = new float[_totalCellsSm];
|
||||||
|
_tcV = new float[_totalCellsSm];
|
||||||
|
_tcW = new float[_totalCellsSm];
|
||||||
|
_tcTemp = new float[_totalCellsSm];
|
||||||
|
|
||||||
|
// allocate & init energy terms
|
||||||
|
_energy = new float[_totalCellsSm];
|
||||||
|
_highFreqEnergy = new float[_totalCellsSm];
|
||||||
|
|
||||||
|
// map all
|
||||||
|
const float dx = 1./(float)(_resSm[0]);
|
||||||
|
const float dy = 1./(float)(_resSm[1]);
|
||||||
|
const float dz = 1./(float)(_resSm[2]);
|
||||||
|
int index = 0;
|
||||||
|
for (int z = 0; z < _zResSm; z++)
|
||||||
|
for (int y = 0; y < _yResSm; y++)
|
||||||
|
for (int x = 0; x < _xResSm; x++, index++)
|
||||||
|
{
|
||||||
|
_tcU[index] = x*dx;
|
||||||
|
_tcV[index] = y*dy;
|
||||||
|
_tcW[index] = z*dz;
|
||||||
|
_tcTemp[index] = 0.;
|
||||||
|
_energy[index] = 0.;
|
||||||
|
}
|
||||||
|
|
||||||
|
// allocate eigenvalue arrays
|
||||||
|
_eigMin = new float[_totalCellsSm];
|
||||||
|
_eigMax = new float[_totalCellsSm];
|
||||||
|
for(int i=0; i < _totalCellsSm; i++)
|
||||||
|
_eigMin[i] = _eigMax[i] = 0.;
|
||||||
|
|
||||||
|
// noise tiles
|
||||||
|
_noiseTile = new float[noiseTileSize * noiseTileSize * noiseTileSize];
|
||||||
|
std::string noiseTileFilename = std::string("noise.wavelets");
|
||||||
|
generateTile_WAVELET(_noiseTile, noiseTileFilename);
|
||||||
|
/*
|
||||||
|
std::string noiseTileFilename = std::string("noise.fft");
|
||||||
|
generatTile_FFT(_noiseTile, noiseTileFilename);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// destructor
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
WTURBULENCE::~WTURBULENCE() {
|
||||||
|
delete[] _densityBig;
|
||||||
|
delete[] _densityBigOld;
|
||||||
|
|
||||||
|
delete[] _bigUx;
|
||||||
|
delete[] _bigUy;
|
||||||
|
delete[] _bigUz;
|
||||||
|
delete[] _tempBig1;
|
||||||
|
delete[] _tempBig2;
|
||||||
|
|
||||||
|
delete[] _tcU;
|
||||||
|
delete[] _tcV;
|
||||||
|
delete[] _tcW;
|
||||||
|
delete[] _tcTemp;
|
||||||
|
|
||||||
|
delete[] _eigMin;
|
||||||
|
delete[] _eigMax;
|
||||||
|
delete[] _noiseTile;
|
||||||
|
|
||||||
|
delete[] _energy;
|
||||||
|
delete[] _highFreqEnergy;
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// Change noise type
|
||||||
|
//
|
||||||
|
// type (1<<1) = wavelet / 2
|
||||||
|
// type (1<<2) = FFT / 4
|
||||||
|
// type (1<<3) = curl / 8
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
void WTURBULENCE::setNoise(int type)
|
||||||
|
{
|
||||||
|
if(type == 4) // FFT
|
||||||
|
{
|
||||||
|
// needs fft
|
||||||
|
// std::string noiseTileFilename = std::string("noise.fft");
|
||||||
|
// generatTile_FFT(_noiseTile, noiseTileFilename);
|
||||||
|
}
|
||||||
|
else if(type == 8) // curl
|
||||||
|
{
|
||||||
|
// TODO: not supported yet
|
||||||
|
}
|
||||||
|
else // standard - wavelet
|
||||||
|
{
|
||||||
|
std::string noiseTileFilename = std::string("noise.wavelets");
|
||||||
|
generateTile_WAVELET(_noiseTile, noiseTileFilename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// Get the smallest valid x derivative
|
||||||
|
//
|
||||||
|
// Takes the one-sided finite difference in both directions and
|
||||||
|
// selects the smaller of the two
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
static float minDx(int x, int y, int z, float* input, Vec3Int res)
|
||||||
|
{
|
||||||
|
const int index = x + y * res[0] + z * res[0] * res[1];
|
||||||
|
const int maxx = res[0]-2;
|
||||||
|
|
||||||
|
// get grid values
|
||||||
|
float center = input[index];
|
||||||
|
float left = (x <= 1) ? FLT_MAX : input[index - 1];
|
||||||
|
float right = (x >= maxx) ? FLT_MAX : input[index + 1];
|
||||||
|
|
||||||
|
const float dx = res[0];
|
||||||
|
|
||||||
|
// get all the derivative estimates
|
||||||
|
float dLeft = (x <= 1) ? FLT_MAX : (center - left) * dx;
|
||||||
|
float dRight = (x >= maxx) ? FLT_MAX : (right - center) * dx;
|
||||||
|
float dCenter = (x <= 1 || x >= maxx) ? FLT_MAX : (right - left) * dx * 0.5f;
|
||||||
|
|
||||||
|
// if it's on a boundary, only one estimate is valid
|
||||||
|
if (x <= 1) return dRight;
|
||||||
|
if (x >= maxx) return dLeft;
|
||||||
|
|
||||||
|
// if it's not on a boundary, get the smallest one
|
||||||
|
float finalD;
|
||||||
|
finalD = (fabs(dCenter) < fabs(dRight)) ? dCenter : dRight;
|
||||||
|
finalD = (fabs(finalD) < fabs(dLeft)) ? finalD : dLeft;
|
||||||
|
|
||||||
|
return finalD;
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// get the smallest valid y derivative
|
||||||
|
//
|
||||||
|
// Takes the one-sided finite difference in both directions and
|
||||||
|
// selects the smaller of the two
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
static float minDy(int x, int y, int z, float* input, Vec3Int res)
|
||||||
|
{
|
||||||
|
const int index = x + y * res[0] + z * res[0] * res[1];
|
||||||
|
const int maxy = res[1]-2;
|
||||||
|
|
||||||
|
// get grid values
|
||||||
|
float center = input[index];
|
||||||
|
float down = (y <= 1) ? FLT_MAX : input[index - res[0]];
|
||||||
|
float up = (y >= maxy) ? FLT_MAX : input[index + res[0]];
|
||||||
|
|
||||||
|
const float dx = res[1]; // only for square domains
|
||||||
|
|
||||||
|
// get all the derivative estimates
|
||||||
|
float dDown = (y <= 1) ? FLT_MAX : (center - down) * dx;
|
||||||
|
float dUp = (y >= maxy) ? FLT_MAX : (up - center) * dx;
|
||||||
|
float dCenter = (y <= 1 || y >= maxy) ? FLT_MAX : (up - down) * dx * 0.5f;
|
||||||
|
|
||||||
|
// if it's on a boundary, only one estimate is valid
|
||||||
|
if (y <= 1) return dUp;
|
||||||
|
if (y >= maxy) return dDown;
|
||||||
|
|
||||||
|
// if it's not on a boundary, get the smallest one
|
||||||
|
float finalD = (fabs(dCenter) < fabs(dUp)) ? dCenter : dUp;
|
||||||
|
finalD = (fabs(finalD) < fabs(dDown)) ? finalD : dDown;
|
||||||
|
|
||||||
|
return finalD;
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// get the smallest valid z derivative
|
||||||
|
//
|
||||||
|
// Takes the one-sided finite difference in both directions and
|
||||||
|
// selects the smaller of the two
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
static float minDz(int x, int y, int z, float* input, Vec3Int res)
|
||||||
|
{
|
||||||
|
const int slab = res[0]*res[1];
|
||||||
|
const int index = x + y * res[0] + z * slab;
|
||||||
|
const int maxz = res[2]-2;
|
||||||
|
|
||||||
|
// get grid values
|
||||||
|
float center = input[index];
|
||||||
|
float front = (z <= 1) ? FLT_MAX : input[index - slab];
|
||||||
|
float back = (z >= maxz) ? FLT_MAX : input[index + slab];
|
||||||
|
|
||||||
|
const float dx = res[2]; // only for square domains
|
||||||
|
|
||||||
|
// get all the derivative estimates
|
||||||
|
float dfront = (z <= 1) ? FLT_MAX : (center - front) * dx;
|
||||||
|
float dback = (z >= maxz) ? FLT_MAX : (back - center) * dx;
|
||||||
|
float dCenter = (z <= 1 || z >= maxz) ? FLT_MAX : (back - front) * dx * 0.5f;
|
||||||
|
|
||||||
|
// if it's on a boundary, only one estimate is valid
|
||||||
|
if (z <= 1) return dback;
|
||||||
|
if (z >= maxz) return dfront;
|
||||||
|
|
||||||
|
// if it's not on a boundary, get the smallest one
|
||||||
|
float finalD = (fabs(dCenter) < fabs(dback)) ? dCenter : dback;
|
||||||
|
finalD = (fabs(finalD) < fabs(dfront)) ? finalD : dfront;
|
||||||
|
|
||||||
|
return finalD;
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// handle texture coordinates (advection, reset, eigenvalues),
|
||||||
|
// Beware -- uses big density maccormack as temporary arrays
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
void WTURBULENCE::advectTextureCoordinates (float dtOrg, float* xvel, float* yvel, float* zvel) {
|
||||||
|
// advection
|
||||||
|
SWAP_POINTERS(_tcTemp, _tcU);
|
||||||
|
FLUID_3D::copyBorderX(_tcTemp, _resSm);
|
||||||
|
FLUID_3D::copyBorderY(_tcTemp, _resSm);
|
||||||
|
FLUID_3D::copyBorderZ(_tcTemp, _resSm);
|
||||||
|
FLUID_3D::advectFieldMacCormack(dtOrg, xvel, yvel, zvel,
|
||||||
|
_tcTemp, _tcU, _tempBig1, _tempBig2, _resSm, NULL);
|
||||||
|
|
||||||
|
SWAP_POINTERS(_tcTemp, _tcV);
|
||||||
|
FLUID_3D::copyBorderX(_tcTemp, _resSm);
|
||||||
|
FLUID_3D::copyBorderY(_tcTemp, _resSm);
|
||||||
|
FLUID_3D::copyBorderZ(_tcTemp, _resSm);
|
||||||
|
FLUID_3D::advectFieldMacCormack(dtOrg, xvel, yvel, zvel,
|
||||||
|
_tcTemp, _tcV, _tempBig1, _tempBig2, _resSm, NULL);
|
||||||
|
|
||||||
|
SWAP_POINTERS(_tcTemp, _tcW);
|
||||||
|
FLUID_3D::copyBorderX(_tcTemp, _resSm);
|
||||||
|
FLUID_3D::copyBorderY(_tcTemp, _resSm);
|
||||||
|
FLUID_3D::copyBorderZ(_tcTemp, _resSm);
|
||||||
|
FLUID_3D::advectFieldMacCormack(dtOrg, xvel, yvel, zvel,
|
||||||
|
_tcTemp, _tcW, _tempBig1, _tempBig2, _resSm, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// Compute the eigenvalues of the advected texture
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
void WTURBULENCE::computeEigenvalues() {
|
||||||
|
// stats
|
||||||
|
float maxeig = -1.;
|
||||||
|
float mineig = 10.;
|
||||||
|
|
||||||
|
// texture coordinate eigenvalues
|
||||||
|
for (int z = 1; z < _zResSm-1; z++) {
|
||||||
|
for (int y = 1; y < _yResSm-1; y++)
|
||||||
|
for (int x = 1; x < _xResSm-1; x++)
|
||||||
|
{
|
||||||
|
const int index = x+ y *_resSm[0] + z*_slabSizeSm;
|
||||||
|
|
||||||
|
// compute jacobian
|
||||||
|
float jacobian[3][3] = {
|
||||||
|
{ minDx(x, y, z, _tcU, _resSm), minDx(x, y, z, _tcV, _resSm), minDx(x, y, z, _tcW, _resSm) } ,
|
||||||
|
{ minDy(x, y, z, _tcU, _resSm), minDy(x, y, z, _tcV, _resSm), minDy(x, y, z, _tcW, _resSm) } ,
|
||||||
|
{ minDz(x, y, z, _tcU, _resSm), minDz(x, y, z, _tcV, _resSm), minDz(x, y, z, _tcW, _resSm) }
|
||||||
|
};
|
||||||
|
|
||||||
|
// ONLY compute the eigenvalues after checking that the matrix
|
||||||
|
// is nonsingular
|
||||||
|
JAMA::LU<float> LU = computeLU3x3(jacobian);
|
||||||
|
|
||||||
|
if (LU.isNonsingular())
|
||||||
|
{
|
||||||
|
// get the analytic eigenvalues, quite slow right now...
|
||||||
|
Vec3 eigenvalues = Vec3(1.);
|
||||||
|
computeEigenvalues3x3( &eigenvalues[0], jacobian);
|
||||||
|
_eigMax[index] = MAX3V(eigenvalues);
|
||||||
|
_eigMin[index] = MIN3V(eigenvalues);
|
||||||
|
maxeig = MAX(_eigMax[index],maxeig);
|
||||||
|
mineig = MIN(_eigMin[index],mineig);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_eigMax[index] = 10.0f;
|
||||||
|
_eigMin[index] = 0.1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// advect & reset texture coordinates based on eigenvalues
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
void WTURBULENCE::resetTextureCoordinates()
|
||||||
|
{
|
||||||
|
// allowed deformation of the textures
|
||||||
|
const float limit = 2.f;
|
||||||
|
const float limitInv = 1./limit;
|
||||||
|
|
||||||
|
// standard reset
|
||||||
|
int resets = 0;
|
||||||
|
const float dx = 1./(float)(_resSm[0]);
|
||||||
|
const float dy = 1./(float)(_resSm[1]);
|
||||||
|
const float dz = 1./(float)(_resSm[2]);
|
||||||
|
|
||||||
|
for (int z = 1; z < _zResSm-1; z++)
|
||||||
|
for (int y = 1; y < _yResSm-1; y++)
|
||||||
|
for (int x = 1; x < _xResSm-1; x++)
|
||||||
|
{
|
||||||
|
const int index = x+ y *_resSm[0] + z*_slabSizeSm;
|
||||||
|
if (_eigMax[index] > limit || _eigMin[index] < limitInv)
|
||||||
|
{
|
||||||
|
_tcU[index] = (float)x * dx;
|
||||||
|
_tcV[index] = (float)y * dy;
|
||||||
|
_tcW[index] = (float)z * dz;
|
||||||
|
resets++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// Compute the highest frequency component of the wavelet
|
||||||
|
// decomposition
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
void WTURBULENCE::decomposeEnergy()
|
||||||
|
{
|
||||||
|
// do the decomposition -- the goal here is to have
|
||||||
|
// the energy with the high frequency component stomped out
|
||||||
|
// stored in _tcTemp when it is done. _highFreqEnergy is only used
|
||||||
|
// as an additional temp array
|
||||||
|
|
||||||
|
// downsample input
|
||||||
|
downsampleXNeumann(_highFreqEnergy, _energy, _xResSm, _yResSm, _zResSm);
|
||||||
|
downsampleYNeumann(_tcTemp, _highFreqEnergy, _xResSm, _yResSm, _zResSm);
|
||||||
|
downsampleZNeumann(_highFreqEnergy, _tcTemp, _xResSm, _yResSm, _zResSm);
|
||||||
|
|
||||||
|
// upsample input
|
||||||
|
upsampleZNeumann(_tcTemp, _highFreqEnergy, _xResSm, _yResSm, _zResSm);
|
||||||
|
upsampleYNeumann(_highFreqEnergy, _tcTemp, _xResSm, _yResSm, _zResSm);
|
||||||
|
upsampleXNeumann(_tcTemp, _highFreqEnergy, _xResSm, _yResSm, _zResSm);
|
||||||
|
|
||||||
|
// subtract the down and upsampled field from the original field --
|
||||||
|
// what should be left over is solely the high frequency component
|
||||||
|
int index = 0;
|
||||||
|
for (int z = 0; z < _zResSm; z++)
|
||||||
|
for (int y = 0; y < _yResSm; y++) {
|
||||||
|
for (int x = 0; x < _xResSm; x++, index++) {
|
||||||
|
// brute force reset of boundaries
|
||||||
|
if(z >= _zResSm - 1 || x >= _xResSm - 1 || y >= _yResSm - 1 || z <= 0 || y <= 0 || x <= 0)
|
||||||
|
_highFreqEnergy[index] = 0.;
|
||||||
|
else
|
||||||
|
_highFreqEnergy[index] = _energy[index] - _tcTemp[index];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// compute velocity from energies and march into obstacles
|
||||||
|
// for wavelet decomposition
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
void WTURBULENCE::computeEnergy(float* xvel, float* yvel, float* zvel, unsigned char *obstacles)
|
||||||
|
{
|
||||||
|
// compute everywhere
|
||||||
|
for (int x = 0; x < _totalCellsSm; x++)
|
||||||
|
_energy[x] = 0.5f * (xvel[x] * xvel[x] + yvel[x] * yvel[x] + zvel[x] * zvel[x]);
|
||||||
|
|
||||||
|
FLUID_3D::copyBorderX(_energy, _resSm);
|
||||||
|
FLUID_3D::copyBorderY(_energy, _resSm);
|
||||||
|
FLUID_3D::copyBorderZ(_energy, _resSm);
|
||||||
|
|
||||||
|
// pseudo-march the values into the obstacles
|
||||||
|
// the wavelet upsampler only uses a 3x3 support neighborhood, so
|
||||||
|
// propagating the values in by 4 should be sufficient
|
||||||
|
int index;
|
||||||
|
|
||||||
|
// iterate
|
||||||
|
for (int iter = 0; iter < 4; iter++)
|
||||||
|
{
|
||||||
|
index = _slabSizeSm + _xResSm + 1;
|
||||||
|
for (int z = 1; z < _zResSm - 1; z++, index += 2 * _xResSm)
|
||||||
|
for (int y = 1; y < _yResSm - 1; y++, index += 2)
|
||||||
|
for (int x = 1; x < _xResSm - 1; x++, index++)
|
||||||
|
if (obstacles[index] && obstacles[index] != RETIRED)
|
||||||
|
{
|
||||||
|
float sum = 0.0f;
|
||||||
|
int valid = 0;
|
||||||
|
|
||||||
|
if (!obstacles[index + 1] || obstacles[index + 1] == RETIRED)
|
||||||
|
{
|
||||||
|
sum += _energy[index + 1];
|
||||||
|
valid++;
|
||||||
|
}
|
||||||
|
if (!obstacles[index - 1] || obstacles[index - 1] == RETIRED)
|
||||||
|
{
|
||||||
|
sum += _energy[index - 1];
|
||||||
|
valid++;
|
||||||
|
}
|
||||||
|
if (!obstacles[index + _xResSm] || obstacles[index + _xResSm] == RETIRED)
|
||||||
|
{
|
||||||
|
sum += _energy[index + _xResSm];
|
||||||
|
valid++;
|
||||||
|
}
|
||||||
|
if (!obstacles[index - _xResSm] || obstacles[index - _xResSm] == RETIRED)
|
||||||
|
{
|
||||||
|
sum += _energy[index - _xResSm];
|
||||||
|
valid++;
|
||||||
|
}
|
||||||
|
if (!obstacles[index + _slabSizeSm] || obstacles[index + _slabSizeSm] == RETIRED)
|
||||||
|
{
|
||||||
|
sum += _energy[index + _slabSizeSm];
|
||||||
|
valid++;
|
||||||
|
}
|
||||||
|
if (!obstacles[index - _slabSizeSm] || obstacles[index - _slabSizeSm] == RETIRED)
|
||||||
|
{
|
||||||
|
sum += _energy[index - _slabSizeSm];
|
||||||
|
valid++;
|
||||||
|
}
|
||||||
|
if (valid > 0)
|
||||||
|
{
|
||||||
|
_energy[index] = sum / valid;
|
||||||
|
obstacles[index] = MARCHED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
index = _slabSizeSm + _xResSm + 1;
|
||||||
|
for (int z = 1; z < _zResSm - 1; z++, index += 2 * _xResSm)
|
||||||
|
for (int y = 1; y < _yResSm - 1; y++, index += 2)
|
||||||
|
for (int x = 1; x < _xResSm - 1; x++, index++)
|
||||||
|
if (obstacles[index] == MARCHED)
|
||||||
|
obstacles[index] = RETIRED;
|
||||||
|
}
|
||||||
|
index = _slabSizeSm + _xResSm + 1;
|
||||||
|
for (int z = 1; z < _zResSm - 1; z++, index += 2 * _xResSm)
|
||||||
|
for (int y = 1; y < _yResSm - 1; y++, index += 2)
|
||||||
|
for (int x = 1; x < _xResSm - 1; x++, index++)
|
||||||
|
if (obstacles[index])
|
||||||
|
obstacles[index] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Evaluate derivatives
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
Vec3 WTURBULENCE::WVelocity(Vec3 orgPos)
|
||||||
|
{
|
||||||
|
// arbitrarily offset evaluation points
|
||||||
|
const Vec3 p1 = orgPos + Vec3(NOISE_TILE_SIZE/2,0,0);
|
||||||
|
const Vec3 p2 = orgPos + Vec3(0,NOISE_TILE_SIZE/2,0);
|
||||||
|
const Vec3 p3 = orgPos + Vec3(0,0,NOISE_TILE_SIZE/2);
|
||||||
|
|
||||||
|
const float f1y = WNoiseDy(p1, _noiseTile);
|
||||||
|
const float f1z = WNoiseDz(p1, _noiseTile);
|
||||||
|
|
||||||
|
const float f2x = WNoiseDx(p2, _noiseTile);
|
||||||
|
const float f2z = WNoiseDz(p2, _noiseTile);
|
||||||
|
|
||||||
|
const float f3x = WNoiseDx(p3, _noiseTile);
|
||||||
|
const float f3y = WNoiseDy(p3, _noiseTile);
|
||||||
|
|
||||||
|
Vec3 ret = Vec3(
|
||||||
|
f3y - f2z,
|
||||||
|
f1z - f3x,
|
||||||
|
f2x - f1y );
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Evaluate derivatives with Jacobian
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
Vec3 WTURBULENCE::WVelocityWithJacobian(Vec3 orgPos, float* xUnwarped, float* yUnwarped, float* zUnwarped)
|
||||||
|
{
|
||||||
|
// arbitrarily offset evaluation points
|
||||||
|
const Vec3 p1 = orgPos + Vec3(NOISE_TILE_SIZE/2,0,0);
|
||||||
|
const Vec3 p2 = orgPos + Vec3(0,NOISE_TILE_SIZE/2,0);
|
||||||
|
const Vec3 p3 = orgPos + Vec3(0,0,NOISE_TILE_SIZE/2);
|
||||||
|
|
||||||
|
Vec3 final;
|
||||||
|
final[0] = WNoiseDx(p1, _noiseTile);
|
||||||
|
final[1] = WNoiseDy(p1, _noiseTile);
|
||||||
|
final[2] = WNoiseDz(p1, _noiseTile);
|
||||||
|
// UNUSED const float f1x = xUnwarped[0] * final[0] + xUnwarped[1] * final[1] + xUnwarped[2] * final[2];
|
||||||
|
const float f1y = yUnwarped[0] * final[0] + yUnwarped[1] * final[1] + yUnwarped[2] * final[2];
|
||||||
|
const float f1z = zUnwarped[0] * final[0] + zUnwarped[1] * final[1] + zUnwarped[2] * final[2];
|
||||||
|
|
||||||
|
final[0] = WNoiseDx(p2, _noiseTile);
|
||||||
|
final[1] = WNoiseDy(p2, _noiseTile);
|
||||||
|
final[2] = WNoiseDz(p2, _noiseTile);
|
||||||
|
const float f2x = xUnwarped[0] * final[0] + xUnwarped[1] * final[1] + xUnwarped[2] * final[2];
|
||||||
|
// UNUSED const float f2y = yUnwarped[0] * final[0] + yUnwarped[1] * final[1] + yUnwarped[2] * final[2];
|
||||||
|
const float f2z = zUnwarped[0] * final[0] + zUnwarped[1] * final[1] + zUnwarped[2] * final[2];
|
||||||
|
|
||||||
|
final[0] = WNoiseDx(p3, _noiseTile);
|
||||||
|
final[1] = WNoiseDy(p3, _noiseTile);
|
||||||
|
final[2] = WNoiseDz(p3, _noiseTile);
|
||||||
|
const float f3x = xUnwarped[0] * final[0] + xUnwarped[1] * final[1] + xUnwarped[2] * final[2];
|
||||||
|
const float f3y = yUnwarped[0] * final[0] + yUnwarped[1] * final[1] + yUnwarped[2] * final[2];
|
||||||
|
// UNUSED const float f3z = zUnwarped[0] * final[0] + zUnwarped[1] * final[1] + zUnwarped[2] * final[2];
|
||||||
|
|
||||||
|
Vec3 ret = Vec3(
|
||||||
|
f3y - f2z,
|
||||||
|
f1z - f3x,
|
||||||
|
f2x - f1y );
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// perform an actual noise advection step
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
void WTURBULENCE::stepTurbulenceReadable(float dtOrg, float* xvel, float* yvel, float* zvel, unsigned char *obstacles)
|
||||||
|
{
|
||||||
|
// enlarge timestep to match grid
|
||||||
|
const float dt = dtOrg * _amplify;
|
||||||
|
const float invAmp = 1.0f / _amplify;
|
||||||
|
|
||||||
|
// prepare textures
|
||||||
|
advectTextureCoordinates(dtOrg, xvel,yvel,zvel);
|
||||||
|
|
||||||
|
// compute eigenvalues of the texture coordinates
|
||||||
|
computeEigenvalues();
|
||||||
|
|
||||||
|
// do wavelet decomposition of energy
|
||||||
|
computeEnergy(xvel, yvel, zvel, obstacles);
|
||||||
|
decomposeEnergy();
|
||||||
|
|
||||||
|
// zero out coefficients inside of the obstacle
|
||||||
|
for (int x = 0; x < _totalCellsSm; x++)
|
||||||
|
if (obstacles[x]) _energy[x] = 0.f;
|
||||||
|
|
||||||
|
float maxVelocity = 0.;
|
||||||
|
for (int z = 1; z < _zResBig - 1; z++)
|
||||||
|
for (int y = 1; y < _yResBig - 1; y++)
|
||||||
|
for (int x = 1; x < _xResBig - 1; x++)
|
||||||
|
{
|
||||||
|
// get unit position for both fine and coarse grid
|
||||||
|
const Vec3 pos = Vec3(x,y,z);
|
||||||
|
const Vec3 posSm = pos * invAmp;
|
||||||
|
|
||||||
|
// get grid index for both fine and coarse grid
|
||||||
|
const int index = x + y *_xResBig + z *_slabSizeBig;
|
||||||
|
const int indexSmall = (int)posSm[0] + (int)posSm[1] * _xResSm + (int)posSm[2] * _slabSizeSm;
|
||||||
|
|
||||||
|
// get a linearly interpolated velocity and texcoords
|
||||||
|
// from the coarse grid
|
||||||
|
Vec3 vel = INTERPOLATE::lerp3dVec( xvel,yvel,zvel,
|
||||||
|
posSm[0], posSm[1], posSm[2], _xResSm,_yResSm,_zResSm);
|
||||||
|
Vec3 uvw = INTERPOLATE::lerp3dVec( _tcU,_tcV,_tcW,
|
||||||
|
posSm[0], posSm[1], posSm[2], _xResSm,_yResSm,_zResSm);
|
||||||
|
|
||||||
|
// multiply the texture coordinate by _resSm so that turbulence
|
||||||
|
// synthesis begins at the first octave that the coarse grid
|
||||||
|
// cannot capture
|
||||||
|
Vec3 texCoord = Vec3(uvw[0] * _resSm[0],
|
||||||
|
uvw[1] * _resSm[1],
|
||||||
|
uvw[2] * _resSm[2]);
|
||||||
|
|
||||||
|
// retrieve wavelet energy at highest frequency
|
||||||
|
float energy = INTERPOLATE::lerp3d(
|
||||||
|
_highFreqEnergy, posSm[0],posSm[1],posSm[2], _xResSm, _yResSm, _zResSm);
|
||||||
|
|
||||||
|
// base amplitude for octave 0
|
||||||
|
float coefficient = sqrtf(2.0f * fabs(energy));
|
||||||
|
const float amplitude = _strength * fabs(0.5 * coefficient) * persistence;
|
||||||
|
|
||||||
|
// add noise to velocity, but only if the turbulence is
|
||||||
|
// sufficiently undeformed, and the energy is large enough
|
||||||
|
// to make a difference
|
||||||
|
const bool addNoise = _eigMax[indexSmall] < 2. &&
|
||||||
|
_eigMin[indexSmall] > 0.5;
|
||||||
|
if (addNoise && amplitude > _cullingThreshold) {
|
||||||
|
// base amplitude for octave 0
|
||||||
|
float amplitudeScaled = amplitude;
|
||||||
|
|
||||||
|
for (int octave = 0; octave < _octaves; octave++)
|
||||||
|
{
|
||||||
|
// multiply the vector noise times the maximum allowed
|
||||||
|
// noise amplitude at this octave, and add it to the total
|
||||||
|
vel += WVelocity(texCoord) * amplitudeScaled;
|
||||||
|
|
||||||
|
// scale coefficient for next octave
|
||||||
|
amplitudeScaled *= persistence;
|
||||||
|
texCoord *= 2.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store velocity + turbulence in big grid for maccormack step
|
||||||
|
//
|
||||||
|
// If you wanted to save memory, you would instead perform a
|
||||||
|
// semi-Lagrangian backtrace for the current grid cell here. Then
|
||||||
|
// you could just throw the velocity away.
|
||||||
|
_bigUx[index] = vel[0];
|
||||||
|
_bigUy[index] = vel[1];
|
||||||
|
_bigUz[index] = vel[2];
|
||||||
|
|
||||||
|
// compute the velocity magnitude for substepping later
|
||||||
|
const float velMag = _bigUx[index] * _bigUx[index] +
|
||||||
|
_bigUy[index] * _bigUy[index] +
|
||||||
|
_bigUz[index] * _bigUz[index];
|
||||||
|
if (velMag > maxVelocity) maxVelocity = velMag;
|
||||||
|
|
||||||
|
// zero out velocity inside obstacles
|
||||||
|
float obsCheck = INTERPOLATE::lerp3dToFloat(
|
||||||
|
obstacles, posSm[0], posSm[1], posSm[2], _xResSm, _yResSm, _zResSm);
|
||||||
|
if (obsCheck > 0.95)
|
||||||
|
_bigUx[index] = _bigUy[index] = _bigUz[index] = 0.;
|
||||||
|
}
|
||||||
|
|
||||||
|
// prepare density for an advection
|
||||||
|
SWAP_POINTERS(_densityBig, _densityBigOld);
|
||||||
|
|
||||||
|
// based on the maximum velocity present, see if we need to substep,
|
||||||
|
// but cap the maximum number of substeps to 5
|
||||||
|
const int maxSubSteps = 25;
|
||||||
|
const int maxVel = 5;
|
||||||
|
maxVelocity = sqrt(maxVelocity) * dt;
|
||||||
|
int totalSubsteps = (int)(maxVelocity / (float)maxVel);
|
||||||
|
totalSubsteps = (totalSubsteps < 1) ? 1 : totalSubsteps;
|
||||||
|
totalSubsteps = (totalSubsteps > maxSubSteps) ? maxSubSteps : totalSubsteps;
|
||||||
|
const float dtSubdiv = dt / (float)totalSubsteps;
|
||||||
|
|
||||||
|
// set boundaries of big velocity grid
|
||||||
|
FLUID_3D::setZeroX(_bigUx, _resBig);
|
||||||
|
FLUID_3D::setZeroY(_bigUy, _resBig);
|
||||||
|
FLUID_3D::setZeroZ(_bigUz, _resBig);
|
||||||
|
|
||||||
|
// do the MacCormack advection, with substepping if necessary
|
||||||
|
for(int substep = 0; substep < totalSubsteps; substep++)
|
||||||
|
{
|
||||||
|
FLUID_3D::advectFieldMacCormack(dtSubdiv, _bigUx, _bigUy, _bigUz,
|
||||||
|
_densityBigOld, _densityBig, _tempBig1, _tempBig2, _resBig, NULL);
|
||||||
|
|
||||||
|
if (substep < totalSubsteps - 1)
|
||||||
|
SWAP_POINTERS(_densityBig, _densityBigOld);
|
||||||
|
} // substep
|
||||||
|
|
||||||
|
// wipe the density borders
|
||||||
|
FLUID_3D::setZeroBorder(_densityBig, _resBig);
|
||||||
|
|
||||||
|
// reset texture coordinates now in preparation for next timestep
|
||||||
|
// Shouldn't do this before generating the noise because then the
|
||||||
|
// eigenvalues stored do not reflect the underlying texture coordinates
|
||||||
|
resetTextureCoordinates();
|
||||||
|
|
||||||
|
// output files
|
||||||
|
/*
|
||||||
|
string prefix = string("./amplified.preview/density_bigxy_");
|
||||||
|
FLUID_3D::writeImageSliceXY(_densityBig, _resBig, _resBig[2]/2, prefix, _totalStepsBig, 1.0f);
|
||||||
|
//string df3Prefix = string("./df3/density_big_");
|
||||||
|
//IMAGE::dumpDF3(_totalStepsBig, df3Prefix, _densityBig, _resBig[0],_resBig[1],_resBig[2]);
|
||||||
|
string pbrtPrefix = string("./pbrt/density_big_");
|
||||||
|
IMAGE::dumpPBRT(_totalStepsBig, pbrtPrefix, _densityBig, _resBig[0],_resBig[1],_resBig[2]);
|
||||||
|
*/
|
||||||
|
_totalStepsBig++;
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// perform the full turbulence algorithm, including OpenMP
|
||||||
|
// if available
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
void WTURBULENCE::stepTurbulenceFull(float dtOrg, float* xvel, float* yvel, float* zvel, unsigned char *obstacles)
|
||||||
|
{
|
||||||
|
// enlarge timestep to match grid
|
||||||
|
const float dt = dtOrg * _amplify;
|
||||||
|
const float invAmp = 1.0f / _amplify;
|
||||||
|
|
||||||
|
// prepare textures
|
||||||
|
advectTextureCoordinates(dtOrg, xvel,yvel,zvel);
|
||||||
|
|
||||||
|
// do wavelet decomposition of energy
|
||||||
|
computeEnergy(xvel, yvel, zvel, obstacles);
|
||||||
|
decomposeEnergy();
|
||||||
|
|
||||||
|
// zero out coefficients inside of the obstacle
|
||||||
|
for (int x = 0; x < _totalCellsSm; x++)
|
||||||
|
if (obstacles[x]) _energy[x] = 0.f;
|
||||||
|
|
||||||
|
// parallel region setup
|
||||||
|
float maxVelMagThreads[8] = { -1., -1., -1., -1., -1., -1., -1., -1. };
|
||||||
|
#if PARALLEL==1
|
||||||
|
#pragma omp parallel
|
||||||
|
#endif
|
||||||
|
{ float maxVelMag1 = 0.;
|
||||||
|
#if PARALLEL==1
|
||||||
|
const int id = omp_get_thread_num(), num = omp_get_num_threads();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// vector noise main loop
|
||||||
|
#if PARALLEL==1
|
||||||
|
#pragma omp for schedule(static)
|
||||||
|
#endif
|
||||||
|
for (int zSmall = 0; zSmall < _zResSm; zSmall++)
|
||||||
|
for (int ySmall = 0; ySmall < _yResSm; ySmall++)
|
||||||
|
for (int xSmall = 0; xSmall < _xResSm; xSmall++)
|
||||||
|
{
|
||||||
|
const int indexSmall = xSmall + ySmall * _xResSm + zSmall * _slabSizeSm;
|
||||||
|
|
||||||
|
// compute jacobian
|
||||||
|
float jacobian[3][3] = {
|
||||||
|
{ minDx(xSmall, ySmall, zSmall, _tcU, _resSm), minDx(xSmall, ySmall, zSmall, _tcV, _resSm), minDx(xSmall, ySmall, zSmall, _tcW, _resSm) } ,
|
||||||
|
{ minDy(xSmall, ySmall, zSmall, _tcU, _resSm), minDy(xSmall, ySmall, zSmall, _tcV, _resSm), minDy(xSmall, ySmall, zSmall, _tcW, _resSm) } ,
|
||||||
|
{ minDz(xSmall, ySmall, zSmall, _tcU, _resSm), minDz(xSmall, ySmall, zSmall, _tcV, _resSm), minDz(xSmall, ySmall, zSmall, _tcW, _resSm) }
|
||||||
|
};
|
||||||
|
|
||||||
|
// get LU factorization of texture jacobian and apply
|
||||||
|
// it to unit vectors
|
||||||
|
JAMA::LU<float> LU = computeLU3x3(jacobian);
|
||||||
|
float xUnwarped[] = {1.0f, 0.0f, 0.0f};
|
||||||
|
float yUnwarped[] = {0.0f, 1.0f, 0.0f};
|
||||||
|
float zUnwarped[] = {0.0f, 0.0f, 1.0f};
|
||||||
|
float xWarped[] = {1.0f, 0.0f, 0.0f};
|
||||||
|
float yWarped[] = {0.0f, 1.0f, 0.0f};
|
||||||
|
float zWarped[] = {0.0f, 0.0f, 1.0f};
|
||||||
|
bool nonSingular = LU.isNonsingular();
|
||||||
|
#if 0
|
||||||
|
// UNUSED
|
||||||
|
float eigMax = 10.0f;
|
||||||
|
float eigMin = 0.1f;
|
||||||
|
#endif
|
||||||
|
if (nonSingular)
|
||||||
|
{
|
||||||
|
solveLU3x3(LU, xUnwarped, xWarped);
|
||||||
|
solveLU3x3(LU, yUnwarped, yWarped);
|
||||||
|
solveLU3x3(LU, zUnwarped, zWarped);
|
||||||
|
|
||||||
|
// compute the eigenvalues while we have the Jacobian available
|
||||||
|
Vec3 eigenvalues = Vec3(1.);
|
||||||
|
computeEigenvalues3x3( &eigenvalues[0], jacobian);
|
||||||
|
_eigMax[indexSmall] = MAX3V(eigenvalues);
|
||||||
|
_eigMin[indexSmall] = MIN3V(eigenvalues);
|
||||||
|
}
|
||||||
|
|
||||||
|
// make sure to skip one on the beginning and end
|
||||||
|
int xStart = (xSmall == 0) ? 1 : 0;
|
||||||
|
int xEnd = (xSmall == _xResSm - 1) ? _amplify - 1 : _amplify;
|
||||||
|
int yStart = (ySmall == 0) ? 1 : 0;
|
||||||
|
int yEnd = (ySmall == _yResSm - 1) ? _amplify - 1 : _amplify;
|
||||||
|
int zStart = (zSmall == 0) ? 1 : 0;
|
||||||
|
int zEnd = (zSmall == _zResSm - 1) ? _amplify - 1 : _amplify;
|
||||||
|
|
||||||
|
for (int zBig = zStart; zBig < zEnd; zBig++)
|
||||||
|
for (int yBig = yStart; yBig < yEnd; yBig++)
|
||||||
|
for (int xBig = xStart; xBig < xEnd; xBig++)
|
||||||
|
{
|
||||||
|
const int x = xSmall * _amplify + xBig;
|
||||||
|
const int y = ySmall * _amplify + yBig;
|
||||||
|
const int z = zSmall * _amplify + zBig;
|
||||||
|
|
||||||
|
// get unit position for both fine and coarse grid
|
||||||
|
const Vec3 pos = Vec3(x,y,z);
|
||||||
|
const Vec3 posSm = pos * invAmp;
|
||||||
|
|
||||||
|
// get grid index for both fine and coarse grid
|
||||||
|
const int index = x + y *_xResBig + z *_slabSizeBig;
|
||||||
|
|
||||||
|
// get a linearly interpolated velocity and texcoords
|
||||||
|
// from the coarse grid
|
||||||
|
Vec3 vel = INTERPOLATE::lerp3dVec( xvel,yvel,zvel,
|
||||||
|
posSm[0], posSm[1], posSm[2], _xResSm,_yResSm,_zResSm);
|
||||||
|
Vec3 uvw = INTERPOLATE::lerp3dVec( _tcU,_tcV,_tcW,
|
||||||
|
posSm[0], posSm[1], posSm[2], _xResSm,_yResSm,_zResSm);
|
||||||
|
|
||||||
|
// multiply the texture coordinate by _resSm so that turbulence
|
||||||
|
// synthesis begins at the first octave that the coarse grid
|
||||||
|
// cannot capture
|
||||||
|
Vec3 texCoord = Vec3(uvw[0] * _resSm[0],
|
||||||
|
uvw[1] * _resSm[1],
|
||||||
|
uvw[2] * _resSm[2]);
|
||||||
|
|
||||||
|
// retrieve wavelet energy at highest frequency
|
||||||
|
float energy = INTERPOLATE::lerp3d(
|
||||||
|
_highFreqEnergy, posSm[0],posSm[1],posSm[2], _xResSm, _yResSm, _zResSm);
|
||||||
|
|
||||||
|
// base amplitude for octave 0
|
||||||
|
float coefficient = sqrtf(2.0f * fabs(energy));
|
||||||
|
const float amplitude = _strength * fabs(0.5 * coefficient) * persistence;
|
||||||
|
|
||||||
|
// add noise to velocity, but only if the turbulence is
|
||||||
|
// sufficiently undeformed, and the energy is large enough
|
||||||
|
// to make a difference
|
||||||
|
const bool addNoise = _eigMax[indexSmall] < 2. &&
|
||||||
|
_eigMin[indexSmall] > 0.5;
|
||||||
|
if (addNoise && amplitude > _cullingThreshold) {
|
||||||
|
// base amplitude for octave 0
|
||||||
|
float amplitudeScaled = amplitude;
|
||||||
|
|
||||||
|
for (int octave = 0; octave < _octaves; octave++)
|
||||||
|
{
|
||||||
|
// multiply the vector noise times the maximum allowed
|
||||||
|
// noise amplitude at this octave, and add it to the total
|
||||||
|
vel += WVelocityWithJacobian(texCoord, &xUnwarped[0], &yUnwarped[0], &zUnwarped[0]) * amplitudeScaled;
|
||||||
|
|
||||||
|
// scale coefficient for next octave
|
||||||
|
amplitudeScaled *= persistence;
|
||||||
|
texCoord *= 2.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store velocity + turbulence in big grid for maccormack step
|
||||||
|
//
|
||||||
|
// If you wanted to save memory, you would instead perform a
|
||||||
|
// semi-Lagrangian backtrace for the current grid cell here. Then
|
||||||
|
// you could just throw the velocity away.
|
||||||
|
_bigUx[index] = vel[0];
|
||||||
|
_bigUy[index] = vel[1];
|
||||||
|
_bigUz[index] = vel[2];
|
||||||
|
|
||||||
|
// compute the velocity magnitude for substepping later
|
||||||
|
const float velMag = _bigUx[index] * _bigUx[index] +
|
||||||
|
_bigUy[index] * _bigUy[index] +
|
||||||
|
_bigUz[index] * _bigUz[index];
|
||||||
|
if (velMag > maxVelMag1) maxVelMag1 = velMag;
|
||||||
|
|
||||||
|
// zero out velocity inside obstacles
|
||||||
|
float obsCheck = INTERPOLATE::lerp3dToFloat(
|
||||||
|
obstacles, posSm[0], posSm[1], posSm[2], _xResSm, _yResSm, _zResSm);
|
||||||
|
if (obsCheck > 0.95)
|
||||||
|
_bigUx[index] = _bigUy[index] = _bigUz[index] = 0.;
|
||||||
|
} // xyz
|
||||||
|
|
||||||
|
#if PARALLEL==1
|
||||||
|
maxVelMagThreads[id] = maxVelMag1;
|
||||||
|
#else
|
||||||
|
maxVelMagThreads[0] = maxVelMag1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
} // omp
|
||||||
|
|
||||||
|
// compute maximum over threads
|
||||||
|
float maxVelMag = maxVelMagThreads[0];
|
||||||
|
#if PARALLEL==1
|
||||||
|
for (int i = 1; i < 8; i++)
|
||||||
|
if (maxVelMag < maxVelMagThreads[i])
|
||||||
|
maxVelMag = maxVelMagThreads[i];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// prepare density for an advection
|
||||||
|
SWAP_POINTERS(_densityBig, _densityBigOld);
|
||||||
|
|
||||||
|
// based on the maximum velocity present, see if we need to substep,
|
||||||
|
// but cap the maximum number of substeps to 5
|
||||||
|
const int maxSubSteps = 25;
|
||||||
|
const int maxVel = 5;
|
||||||
|
maxVelMag = sqrt(maxVelMag) * dt;
|
||||||
|
int totalSubsteps = (int)(maxVelMag / (float)maxVel);
|
||||||
|
totalSubsteps = (totalSubsteps < 1) ? 1 : totalSubsteps;
|
||||||
|
|
||||||
|
totalSubsteps = (totalSubsteps > maxSubSteps) ? maxSubSteps : totalSubsteps;
|
||||||
|
const float dtSubdiv = dt / (float)totalSubsteps;
|
||||||
|
|
||||||
|
// set boundaries of big velocity grid
|
||||||
|
FLUID_3D::setZeroX(_bigUx, _resBig);
|
||||||
|
FLUID_3D::setZeroY(_bigUy, _resBig);
|
||||||
|
FLUID_3D::setZeroZ(_bigUz, _resBig);
|
||||||
|
|
||||||
|
// do the MacCormack advection, with substepping if necessary
|
||||||
|
for(int substep = 0; substep < totalSubsteps; substep++)
|
||||||
|
{
|
||||||
|
FLUID_3D::advectFieldMacCormack(dtSubdiv, _bigUx, _bigUy, _bigUz,
|
||||||
|
_densityBigOld, _densityBig, _tempBig1, _tempBig2, _resBig, NULL);
|
||||||
|
|
||||||
|
if (substep < totalSubsteps - 1)
|
||||||
|
SWAP_POINTERS(_densityBig, _densityBigOld);
|
||||||
|
} // substep
|
||||||
|
|
||||||
|
// wipe the density borders
|
||||||
|
FLUID_3D::setZeroBorder(_densityBig, _resBig);
|
||||||
|
|
||||||
|
// reset texture coordinates now in preparation for next timestep
|
||||||
|
// Shouldn't do this before generating the noise because then the
|
||||||
|
// eigenvalues stored do not reflect the underlying texture coordinates
|
||||||
|
resetTextureCoordinates();
|
||||||
|
|
||||||
|
// output files
|
||||||
|
// string prefix = string("./amplified.preview/density_bigxy_");
|
||||||
|
// FLUID_3D::writeImageSliceXY(_densityBig, _resBig, _resBig[2]/2, prefix, _totalStepsBig, 1.0f);
|
||||||
|
//string df3prefix = string("./df3/density_big_");
|
||||||
|
//IMAGE::dumpDF3(_totalStepsBig, df3prefix, _densityBig, _resBig[0],_resBig[1],_resBig[2]);
|
||||||
|
// string pbrtPrefix = string("./pbrt/density_big_");
|
||||||
|
// IMAGE::dumpPBRT(_totalStepsBig, pbrtPrefix, _densityBig, _resBig[0],_resBig[1],_resBig[2]);
|
||||||
|
|
||||||
|
_totalStepsBig++;
|
||||||
|
}
|
||||||
|
|
||||||
147
intern/smoke/intern/WTURBULENCE.h
Normal file
147
intern/smoke/intern/WTURBULENCE.h
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// This file is part of Wavelet Turbulence.
|
||||||
|
//
|
||||||
|
// Wavelet Turbulence 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 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Wavelet Turbulence 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 Wavelet Turbulence. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// Copyright 2008 Theodore Kim and Nils Thuerey
|
||||||
|
//
|
||||||
|
// WTURBULENCE handling
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef WTURBULENCE_H
|
||||||
|
#define WTURBULENCE_H
|
||||||
|
|
||||||
|
#include "VEC3.h"
|
||||||
|
using namespace BasicVector;
|
||||||
|
class SIMPLE_PARSER;
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Main WTURBULENCE class, stores large density array etc.
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
class WTURBULENCE
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// both config files can be NULL, altCfg might override values from noiseCfg
|
||||||
|
WTURBULENCE(int xResSm, int yResSm, int zResSm, int amplify);
|
||||||
|
|
||||||
|
/// destructor
|
||||||
|
virtual ~WTURBULENCE();
|
||||||
|
|
||||||
|
void setNoise(int type);
|
||||||
|
|
||||||
|
// step more readable version -- no rotation correction
|
||||||
|
void stepTurbulenceReadable(float dt, float* xvel, float* yvel, float* zvel, unsigned char *obstacles);
|
||||||
|
|
||||||
|
// step more complete version -- include rotation correction
|
||||||
|
// and use OpenMP if available
|
||||||
|
void stepTurbulenceFull(float dt, float* xvel, float* yvel, float* zvel, unsigned char *obstacles);
|
||||||
|
|
||||||
|
// texcoord functions
|
||||||
|
void advectTextureCoordinates(float dtOrg, float* xvel, float* yvel, float* zvel);
|
||||||
|
void resetTextureCoordinates();
|
||||||
|
|
||||||
|
void computeEnergy(float* xvel, float* yvel, float* zvel, unsigned char *obstacles);
|
||||||
|
|
||||||
|
// evaluate wavelet noise function
|
||||||
|
Vec3 WVelocity(Vec3 p);
|
||||||
|
Vec3 WVelocityWithJacobian(Vec3 p, float* xUnwarped, float* yUnwarped, float* zUnwarped);
|
||||||
|
|
||||||
|
// access functions
|
||||||
|
inline float* getDensityBig() { return _densityBig; }
|
||||||
|
inline float* getArrayTcU() { return _tcU; }
|
||||||
|
inline float* getArrayTcV() { return _tcV; }
|
||||||
|
inline float* getArrayTcW() { return _tcW; }
|
||||||
|
inline float* getArrayEigMin() { return _eigMin; }
|
||||||
|
inline float* getArrayEigMax() { return _eigMax; }
|
||||||
|
|
||||||
|
inline Vec3Int getResSm() { return _resSm; } // small resolution
|
||||||
|
inline Vec3Int getResBig() { return _resBig; }
|
||||||
|
inline int getOctaves() { return _octaves; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// enlargement factor from original velocity field / simulation
|
||||||
|
// _Big = _amplify * _Sm
|
||||||
|
int _amplify;
|
||||||
|
int _octaves;
|
||||||
|
float _strength;
|
||||||
|
|
||||||
|
// noise settings
|
||||||
|
float _cullingThreshold;
|
||||||
|
float _noiseStrength;
|
||||||
|
float _noiseSizeScale;
|
||||||
|
bool _uvwAdvection;
|
||||||
|
bool _uvwReset;
|
||||||
|
float _noiseTimeanimSpeed;
|
||||||
|
int _dumpInterval;
|
||||||
|
int _noiseControlType;
|
||||||
|
// debug, scale density for projections output images
|
||||||
|
float _outputScale;
|
||||||
|
|
||||||
|
// noise resolution
|
||||||
|
int _xResBig;
|
||||||
|
int _yResBig;
|
||||||
|
int _zResBig;
|
||||||
|
Vec3Int _resBig;
|
||||||
|
Vec3 _invResBig;
|
||||||
|
int _totalCellsBig;
|
||||||
|
int _slabSizeBig;
|
||||||
|
// original / small resolution
|
||||||
|
int _xResSm;
|
||||||
|
int _yResSm;
|
||||||
|
int _zResSm;
|
||||||
|
Vec3Int _resSm;
|
||||||
|
Vec3 _invResSm;
|
||||||
|
int _totalCellsSm;
|
||||||
|
int _slabSizeSm;
|
||||||
|
|
||||||
|
float* _densityBig;
|
||||||
|
float* _densityBigOld;
|
||||||
|
|
||||||
|
// big velocity macCormack fields
|
||||||
|
float* _bigUx;
|
||||||
|
float* _bigUy;
|
||||||
|
float* _bigUz;
|
||||||
|
// temp arrays for BFECC and MacCormack - they have more convenient
|
||||||
|
// names in the actual implementations
|
||||||
|
float* _tempBig1;
|
||||||
|
float* _tempBig2;
|
||||||
|
|
||||||
|
// texture coordinates for noise
|
||||||
|
float* _tcU;
|
||||||
|
float* _tcV;
|
||||||
|
float* _tcW;
|
||||||
|
float* _tcTemp;
|
||||||
|
|
||||||
|
float* _eigMin;
|
||||||
|
float* _eigMax;
|
||||||
|
|
||||||
|
// wavelet decomposition of velocity energies
|
||||||
|
float* _energy;
|
||||||
|
|
||||||
|
// noise data
|
||||||
|
float* _noiseTile;
|
||||||
|
//float* _noiseTileExt;
|
||||||
|
|
||||||
|
// step counter
|
||||||
|
int _totalStepsBig;
|
||||||
|
|
||||||
|
// highest frequency component of wavelet decomposition
|
||||||
|
float* _highFreqEnergy;
|
||||||
|
|
||||||
|
void computeEigenvalues();
|
||||||
|
void decomposeEnergy();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // WTURBULENCE_H
|
||||||
|
|
||||||
121
intern/smoke/intern/smoke_API.cpp
Normal file
121
intern/smoke/intern/smoke_API.cpp
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
/**
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* ***** 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.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2009 by Daniel Genrich
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s): None
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "FLUID_3D.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
// y in smoke is z in blender
|
||||||
|
extern "C" FLUID_3D *smoke_init(int *res, int amplify, float *p0, float *p1, float dt)
|
||||||
|
{
|
||||||
|
// smoke lib uses y as top-bottom/vertical axis where blender uses z
|
||||||
|
FLUID_3D *fluid = new FLUID_3D(res, amplify, p0, dt);
|
||||||
|
|
||||||
|
// printf("xres: %d, yres: %d, zres: %d\n", res[0], res[1], res[2]);
|
||||||
|
|
||||||
|
return fluid;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void smoke_free(FLUID_3D *fluid)
|
||||||
|
{
|
||||||
|
delete fluid;
|
||||||
|
fluid = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void smoke_step(FLUID_3D *fluid)
|
||||||
|
{
|
||||||
|
fluid->step();
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void smoke_initBlenderRNA(FLUID_3D *fluid, float *alpha, float *beta)
|
||||||
|
{
|
||||||
|
fluid->initBlenderRNA(alpha, beta);
|
||||||
|
}
|
||||||
|
|
||||||
|
template < class T > inline T ABS( T a ) {
|
||||||
|
return (0 < a) ? a : -a ;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" float *smoke_get_density(FLUID_3D *fluid)
|
||||||
|
{
|
||||||
|
return fluid->_density;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" float *smoke_get_heat(FLUID_3D *fluid)
|
||||||
|
{
|
||||||
|
return fluid->_heat;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" float *smoke_get_velocity_x(FLUID_3D *fluid)
|
||||||
|
{
|
||||||
|
return fluid->_xVorticity;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" float *smoke_get_velocity_y(FLUID_3D *fluid)
|
||||||
|
{
|
||||||
|
return fluid->_yVorticity;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" float *smoke_get_velocity_z(FLUID_3D *fluid)
|
||||||
|
{
|
||||||
|
return fluid->_zVorticity;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" float *smoke_get_bigdensity(FLUID_3D *fluid)
|
||||||
|
{
|
||||||
|
return fluid->_wTurbulence->getDensityBig();
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void smoke_get_bigres(FLUID_3D *fluid, int *res)
|
||||||
|
{
|
||||||
|
Vec3Int r = fluid->_wTurbulence->getResBig();
|
||||||
|
res[0] = r[0];
|
||||||
|
res[1] = r[1];
|
||||||
|
res[2] = r[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" unsigned char *smoke_get_obstacle(FLUID_3D *fluid)
|
||||||
|
{
|
||||||
|
return fluid->_obstacles;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" size_t smoke_get_index(int x, int max_x, int y, int max_y, int z /*, int max_z */)
|
||||||
|
{
|
||||||
|
// // const int index = x + y * smd->res[0] + z * smd->res[0]*smd->res[1];
|
||||||
|
return x + y * max_x + z * max_x*max_y;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" size_t smoke_get_index2d(int x, int max_x, int y /*, int max_y, int z, int max_z */)
|
||||||
|
{
|
||||||
|
return x + y * max_x;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void smoke_set_noise(FLUID_3D *fluid, int type)
|
||||||
|
{
|
||||||
|
fluid->_wTurbulence->setNoise(type);
|
||||||
|
}
|
||||||
1050
intern/smoke/intern/tnt/jama_eig.h
Normal file
1050
intern/smoke/intern/tnt/jama_eig.h
Normal file
File diff suppressed because it is too large
Load Diff
319
intern/smoke/intern/tnt/jama_lu.h
Normal file
319
intern/smoke/intern/tnt/jama_lu.h
Normal file
@@ -0,0 +1,319 @@
|
|||||||
|
#ifndef JAMA_LU_H
|
||||||
|
#define JAMA_LU_H
|
||||||
|
|
||||||
|
#include "tnt.h"
|
||||||
|
#include <algorithm>
|
||||||
|
//for min(), max() below
|
||||||
|
|
||||||
|
using namespace TNT;
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
namespace JAMA
|
||||||
|
{
|
||||||
|
|
||||||
|
/** LU Decomposition.
|
||||||
|
<P>
|
||||||
|
For an m-by-n matrix A with m >= n, the LU decomposition is an m-by-n
|
||||||
|
unit lower triangular matrix L, an n-by-n upper triangular matrix U,
|
||||||
|
and a permutation vector piv of length m so that A(piv,:) = L*U.
|
||||||
|
If m < n, then L is m-by-m and U is m-by-n.
|
||||||
|
<P>
|
||||||
|
The LU decompostion with pivoting always exists, even if the matrix is
|
||||||
|
singular, so the constructor will never fail. The primary use of the
|
||||||
|
LU decomposition is in the solution of square systems of simultaneous
|
||||||
|
linear equations. This will fail if isNonsingular() returns false.
|
||||||
|
*/
|
||||||
|
template <class Real>
|
||||||
|
class LU
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Array for internal storage of decomposition. */
|
||||||
|
Array2D<Real> LU_;
|
||||||
|
int m, n, pivsign;
|
||||||
|
Array1D<int> piv;
|
||||||
|
|
||||||
|
|
||||||
|
Array2D<Real> permute_copy(const Array2D<Real> &A,
|
||||||
|
const Array1D<int> &piv, int j0, int j1)
|
||||||
|
{
|
||||||
|
int piv_length = piv.dim();
|
||||||
|
|
||||||
|
Array2D<Real> X(piv_length, j1-j0+1);
|
||||||
|
|
||||||
|
|
||||||
|
for (int i = 0; i < piv_length; i++)
|
||||||
|
for (int j = j0; j <= j1; j++)
|
||||||
|
X[i][j-j0] = A[piv[i]][j];
|
||||||
|
|
||||||
|
return X;
|
||||||
|
}
|
||||||
|
|
||||||
|
Array1D<Real> permute_copy(const Array1D<Real> &A,
|
||||||
|
const Array1D<int> &piv)
|
||||||
|
{
|
||||||
|
int piv_length = piv.dim();
|
||||||
|
if (piv_length != A.dim())
|
||||||
|
return Array1D<Real>();
|
||||||
|
|
||||||
|
Array1D<Real> x(piv_length);
|
||||||
|
|
||||||
|
|
||||||
|
for (int i = 0; i < piv_length; i++)
|
||||||
|
x[i] = A[piv[i]];
|
||||||
|
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public :
|
||||||
|
|
||||||
|
/** LU Decomposition
|
||||||
|
@param A Rectangular matrix
|
||||||
|
@return LU Decomposition object to access L, U and piv.
|
||||||
|
*/
|
||||||
|
|
||||||
|
LU (const Array2D<Real> &A) : LU_(A.copy()), m(A.dim1()), n(A.dim2()),
|
||||||
|
piv(A.dim1())
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
// Use a "left-looking", dot-product, Crout/Doolittle algorithm.
|
||||||
|
|
||||||
|
|
||||||
|
for (int i = 0; i < m; i++) {
|
||||||
|
piv[i] = i;
|
||||||
|
}
|
||||||
|
pivsign = 1;
|
||||||
|
Real *LUrowi = 0;;
|
||||||
|
Array1D<Real> LUcolj(m);
|
||||||
|
|
||||||
|
// 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] = LU_[i][j];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply previous transformations.
|
||||||
|
|
||||||
|
for (int i = 0; i < m; i++) {
|
||||||
|
LUrowi = LU_[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 += LUrowi[k]*LUcolj[k];
|
||||||
|
}
|
||||||
|
|
||||||
|
LUrowi[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 = LU_[p][k];
|
||||||
|
LU_[p][k] = LU_[j][k];
|
||||||
|
LU_[j][k] = t;
|
||||||
|
}
|
||||||
|
k = piv[p];
|
||||||
|
piv[p] = piv[j];
|
||||||
|
piv[j] = k;
|
||||||
|
pivsign = -pivsign;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute multipliers.
|
||||||
|
|
||||||
|
if ((j < m) && (LU_[j][j] != 0.0)) {
|
||||||
|
for (int i = j+1; i < m; i++) {
|
||||||
|
LU_[i][j] /= LU_[j][j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Is the matrix nonsingular?
|
||||||
|
@return 1 (true) if upper triangular factor U (and hence A)
|
||||||
|
is nonsingular, 0 otherwise.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int isNonsingular () {
|
||||||
|
for (int j = 0; j < n; j++) {
|
||||||
|
if (LU_[j][j] == 0)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Return lower triangular factor
|
||||||
|
@return L
|
||||||
|
*/
|
||||||
|
|
||||||
|
Array2D<Real> getL () {
|
||||||
|
Array2D<Real> L_(m,n);
|
||||||
|
for (int i = 0; i < m; i++) {
|
||||||
|
for (int j = 0; j < n; j++) {
|
||||||
|
if (i > j) {
|
||||||
|
L_[i][j] = LU_[i][j];
|
||||||
|
} else if (i == j) {
|
||||||
|
L_[i][j] = 1.0;
|
||||||
|
} else {
|
||||||
|
L_[i][j] = 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return L_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Return upper triangular factor
|
||||||
|
@return U portion of LU factorization.
|
||||||
|
*/
|
||||||
|
|
||||||
|
Array2D<Real> getU () {
|
||||||
|
Array2D<Real> U_(n,n);
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
for (int j = 0; j < n; j++) {
|
||||||
|
if (i <= j) {
|
||||||
|
U_[i][j] = LU_[i][j];
|
||||||
|
} else {
|
||||||
|
U_[i][j] = 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return U_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Return pivot permutation vector
|
||||||
|
@return piv
|
||||||
|
*/
|
||||||
|
|
||||||
|
Array1D<int> getPivot () {
|
||||||
|
return piv;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Compute determinant using LU factors.
|
||||||
|
@return determinant of A, or 0 if A is not square.
|
||||||
|
*/
|
||||||
|
|
||||||
|
Real det () {
|
||||||
|
if (m != n) {
|
||||||
|
return Real(0);
|
||||||
|
}
|
||||||
|
Real d = Real(pivsign);
|
||||||
|
for (int j = 0; j < n; j++) {
|
||||||
|
d *= LU_[j][j];
|
||||||
|
}
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Solve A*X = B
|
||||||
|
@param B A Matrix with as many rows as A and any number of columns.
|
||||||
|
@return X so that L*U*X = B(piv,:), if B is nonconformant, returns
|
||||||
|
0x0 (null) array.
|
||||||
|
*/
|
||||||
|
|
||||||
|
Array2D<Real> solve (const Array2D<Real> &B)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* Dimensions: A is mxn, X is nxk, B is mxk */
|
||||||
|
|
||||||
|
if (B.dim1() != m) {
|
||||||
|
return Array2D<Real>(0,0);
|
||||||
|
}
|
||||||
|
if (!isNonsingular()) {
|
||||||
|
return Array2D<Real>(0,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy right hand side with pivoting
|
||||||
|
int nx = B.dim2();
|
||||||
|
|
||||||
|
|
||||||
|
Array2D<Real> X = permute_copy(B, piv, 0, nx-1);
|
||||||
|
|
||||||
|
// Solve L*Y = B(piv,:)
|
||||||
|
for (int k = 0; k < n; k++) {
|
||||||
|
for (int i = k+1; i < n; i++) {
|
||||||
|
for (int j = 0; j < nx; j++) {
|
||||||
|
X[i][j] -= X[k][j]*LU_[i][k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Solve U*X = Y;
|
||||||
|
for (int k = n-1; k >= 0; k--) {
|
||||||
|
for (int j = 0; j < nx; j++) {
|
||||||
|
X[k][j] /= LU_[k][k];
|
||||||
|
}
|
||||||
|
for (int i = 0; i < k; i++) {
|
||||||
|
for (int j = 0; j < nx; j++) {
|
||||||
|
X[i][j] -= X[k][j]*LU_[i][k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return X;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Solve A*x = b, where x and b are vectors of length equal
|
||||||
|
to the number of rows in A.
|
||||||
|
|
||||||
|
@param b a vector (Array1D> of length equal to the first dimension
|
||||||
|
of A.
|
||||||
|
@return x a vector (Array1D> so that L*U*x = b(piv), if B is nonconformant,
|
||||||
|
returns 0x0 (null) array.
|
||||||
|
*/
|
||||||
|
|
||||||
|
Array1D<Real> solve (const Array1D<Real> &b)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* Dimensions: A is mxn, X is nxk, B is mxk */
|
||||||
|
|
||||||
|
if (b.dim1() != m) {
|
||||||
|
return Array1D<Real>();
|
||||||
|
}
|
||||||
|
if (!isNonsingular()) {
|
||||||
|
return Array1D<Real>();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Array1D<Real> x = permute_copy(b, piv);
|
||||||
|
|
||||||
|
// Solve L*Y = B(piv)
|
||||||
|
for (int k = 0; k < n; k++) {
|
||||||
|
for (int i = k+1; i < n; i++) {
|
||||||
|
x[i] -= x[k]*LU_[i][k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Solve U*X = Y;
|
||||||
|
for (int k = n-1; k >= 0; k--) {
|
||||||
|
x[k] /= LU_[k][k];
|
||||||
|
for (int i = 0; i < k; i++)
|
||||||
|
x[i] -= x[k]*LU_[i][k];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
}; /* class LU */
|
||||||
|
|
||||||
|
} /* namespace JAMA */
|
||||||
|
|
||||||
|
#endif
|
||||||
|
/* JAMA_LU_H */
|
||||||
64
intern/smoke/intern/tnt/tnt.h
Normal file
64
intern/smoke/intern/tnt/tnt.h
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Template Numerical Toolkit (TNT): Linear Algebra Module
|
||||||
|
*
|
||||||
|
* Mathematical and Computational Sciences Division
|
||||||
|
* National Institute of Technology,
|
||||||
|
* Gaithersburg, MD USA
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* This software was developed at the National Institute of Standards and
|
||||||
|
* Technology (NIST) by employees of the Federal Government in the course
|
||||||
|
* of their official duties. Pursuant to title 17 Section 105 of the
|
||||||
|
* United States Code, this software is not subject to copyright protection
|
||||||
|
* and is in the public domain. NIST assumes no responsibility whatsoever for
|
||||||
|
* its use by other parties, and makes no guarantees, expressed or implied,
|
||||||
|
* about its quality, reliability, or any other characteristic.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TNT_H
|
||||||
|
#define TNT_H
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// Define this macro if you want TNT to track some of the out-of-bounds
|
||||||
|
// indexing. This can encur a small run-time overhead, but is recommended
|
||||||
|
// while developing code. It can be turned off for production runs.
|
||||||
|
//
|
||||||
|
// #define TNT_BOUNDS_CHECK
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
|
||||||
|
//#define TNT_BOUNDS_CHECK
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include "tnt_version.h"
|
||||||
|
#include "tnt_math_utils.h"
|
||||||
|
#include "tnt_array1d.h"
|
||||||
|
#include "tnt_array2d.h"
|
||||||
|
#include "tnt_array3d.h"
|
||||||
|
#include "tnt_array1d_utils.h"
|
||||||
|
#include "tnt_array2d_utils.h"
|
||||||
|
#include "tnt_array3d_utils.h"
|
||||||
|
|
||||||
|
#include "tnt_fortran_array1d.h"
|
||||||
|
#include "tnt_fortran_array2d.h"
|
||||||
|
#include "tnt_fortran_array3d.h"
|
||||||
|
#include "tnt_fortran_array1d_utils.h"
|
||||||
|
#include "tnt_fortran_array2d_utils.h"
|
||||||
|
#include "tnt_fortran_array3d_utils.h"
|
||||||
|
|
||||||
|
#include "tnt_sparse_matrix_csr.h"
|
||||||
|
|
||||||
|
#include "tnt_stopwatch.h"
|
||||||
|
#include "tnt_subscript.h"
|
||||||
|
#include "tnt_vec.h"
|
||||||
|
#include "tnt_cmat.h"
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
// TNT_H
|
||||||
278
intern/smoke/intern/tnt/tnt_array1d.h
Normal file
278
intern/smoke/intern/tnt/tnt_array1d.h
Normal file
@@ -0,0 +1,278 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Template Numerical Toolkit (TNT)
|
||||||
|
*
|
||||||
|
* Mathematical and Computational Sciences Division
|
||||||
|
* National Institute of Technology,
|
||||||
|
* Gaithersburg, MD USA
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* This software was developed at the National Institute of Standards and
|
||||||
|
* Technology (NIST) by employees of the Federal Government in the course
|
||||||
|
* of their official duties. Pursuant to title 17 Section 105 of the
|
||||||
|
* United States Code, this software is not subject to copyright protection
|
||||||
|
* and is in the public domain. NIST assumes no responsibility whatsoever for
|
||||||
|
* its use by other parties, and makes no guarantees, expressed or implied,
|
||||||
|
* about its quality, reliability, or any other characteristic.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TNT_ARRAY1D_H
|
||||||
|
#define TNT_ARRAY1D_H
|
||||||
|
|
||||||
|
//#include <cstdlib>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#ifdef TNT_BOUNDS_CHECK
|
||||||
|
#include <assert.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#include "tnt_i_refvec.h"
|
||||||
|
|
||||||
|
namespace TNT
|
||||||
|
{
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
class Array1D
|
||||||
|
{
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
/* ... */
|
||||||
|
i_refvec<T> v_;
|
||||||
|
int n_;
|
||||||
|
T* data_; /* this normally points to v_.begin(), but
|
||||||
|
* could also point to a portion (subvector)
|
||||||
|
* of v_.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void copy_(T* p, const T* q, int len) const;
|
||||||
|
void set_(T* begin, T* end, const T& val);
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef T value_type;
|
||||||
|
|
||||||
|
|
||||||
|
Array1D();
|
||||||
|
explicit Array1D(int n);
|
||||||
|
Array1D(int n, const T &a);
|
||||||
|
Array1D(int n, T *a);
|
||||||
|
inline Array1D(const Array1D &A);
|
||||||
|
inline operator T*();
|
||||||
|
inline operator const T*();
|
||||||
|
inline Array1D & operator=(const T &a);
|
||||||
|
inline Array1D & operator=(const Array1D &A);
|
||||||
|
inline Array1D & ref(const Array1D &A);
|
||||||
|
Array1D copy() const;
|
||||||
|
Array1D & inject(const Array1D & A);
|
||||||
|
inline T& operator[](int i);
|
||||||
|
inline const T& operator[](int i) const;
|
||||||
|
inline int dim1() const;
|
||||||
|
inline int dim() const;
|
||||||
|
~Array1D();
|
||||||
|
|
||||||
|
|
||||||
|
/* ... extended interface ... */
|
||||||
|
|
||||||
|
inline int ref_count() const;
|
||||||
|
inline Array1D<T> subarray(int i0, int i1);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array1D<T>::Array1D() : v_(), n_(0), data_(0) {}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array1D<T>::Array1D(const Array1D<T> &A) : v_(A.v_), n_(A.n_),
|
||||||
|
data_(A.data_)
|
||||||
|
{
|
||||||
|
#ifdef TNT_DEBUG
|
||||||
|
std::cout << "Created Array1D(const Array1D<T> &A) \n";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array1D<T>::Array1D(int n) : v_(n), n_(n), data_(v_.begin())
|
||||||
|
{
|
||||||
|
#ifdef TNT_DEBUG
|
||||||
|
std::cout << "Created Array1D(int n) \n";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array1D<T>::Array1D(int n, const T &val) : v_(n), n_(n), data_(v_.begin())
|
||||||
|
{
|
||||||
|
#ifdef TNT_DEBUG
|
||||||
|
std::cout << "Created Array1D(int n, const T& val) \n";
|
||||||
|
#endif
|
||||||
|
set_(data_, data_+ n, val);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array1D<T>::Array1D(int n, T *a) : v_(a), n_(n) , data_(v_.begin())
|
||||||
|
{
|
||||||
|
#ifdef TNT_DEBUG
|
||||||
|
std::cout << "Created Array1D(int n, T* a) \n";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline Array1D<T>::operator T*()
|
||||||
|
{
|
||||||
|
return &(v_[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline Array1D<T>::operator const T*()
|
||||||
|
{
|
||||||
|
return &(v_[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline T& Array1D<T>::operator[](int i)
|
||||||
|
{
|
||||||
|
#ifdef TNT_BOUNDS_CHECK
|
||||||
|
assert(i>= 0);
|
||||||
|
assert(i < n_);
|
||||||
|
#endif
|
||||||
|
return data_[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline const T& Array1D<T>::operator[](int i) const
|
||||||
|
{
|
||||||
|
#ifdef TNT_BOUNDS_CHECK
|
||||||
|
assert(i>= 0);
|
||||||
|
assert(i < n_);
|
||||||
|
#endif
|
||||||
|
return data_[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array1D<T> & Array1D<T>::operator=(const T &a)
|
||||||
|
{
|
||||||
|
set_(data_, data_+n_, a);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array1D<T> Array1D<T>::copy() const
|
||||||
|
{
|
||||||
|
Array1D A( n_);
|
||||||
|
copy_(A.data_, data_, n_);
|
||||||
|
|
||||||
|
return A;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array1D<T> & Array1D<T>::inject(const Array1D &A)
|
||||||
|
{
|
||||||
|
if (A.n_ == n_)
|
||||||
|
copy_(data_, A.data_, n_);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array1D<T> & Array1D<T>::ref(const Array1D<T> &A)
|
||||||
|
{
|
||||||
|
if (this != &A)
|
||||||
|
{
|
||||||
|
v_ = A.v_; /* operator= handles the reference counting. */
|
||||||
|
n_ = A.n_;
|
||||||
|
data_ = A.data_;
|
||||||
|
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array1D<T> & Array1D<T>::operator=(const Array1D<T> &A)
|
||||||
|
{
|
||||||
|
return ref(A);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline int Array1D<T>::dim1() const { return n_; }
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline int Array1D<T>::dim() const { return n_; }
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array1D<T>::~Array1D() {}
|
||||||
|
|
||||||
|
|
||||||
|
/* ............................ exented interface ......................*/
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline int Array1D<T>::ref_count() const
|
||||||
|
{
|
||||||
|
return v_.ref_count();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline Array1D<T> Array1D<T>::subarray(int i0, int i1)
|
||||||
|
{
|
||||||
|
if ((i0 > 0) && (i1 < n_) || (i0 <= i1))
|
||||||
|
{
|
||||||
|
Array1D<T> X(*this); /* create a new instance of this array. */
|
||||||
|
X.n_ = i1-i0+1;
|
||||||
|
X.data_ += i0;
|
||||||
|
|
||||||
|
return X;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return Array1D<T>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* private internal functions */
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void Array1D<T>::set_(T* begin, T* end, const T& a)
|
||||||
|
{
|
||||||
|
for (T* p=begin; p<end; p++)
|
||||||
|
*p = a;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void Array1D<T>::copy_(T* p, const T* q, int len) const
|
||||||
|
{
|
||||||
|
T *end = p + len;
|
||||||
|
while (p<end )
|
||||||
|
*p++ = *q++;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} /* namespace TNT */
|
||||||
|
|
||||||
|
#endif
|
||||||
|
/* TNT_ARRAY1D_H */
|
||||||
|
|
||||||
230
intern/smoke/intern/tnt/tnt_array1d_utils.h
Normal file
230
intern/smoke/intern/tnt/tnt_array1d_utils.h
Normal file
@@ -0,0 +1,230 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Template Numerical Toolkit (TNT)
|
||||||
|
*
|
||||||
|
* Mathematical and Computational Sciences Division
|
||||||
|
* National Institute of Technology,
|
||||||
|
* Gaithersburg, MD USA
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* This software was developed at the National Institute of Standards and
|
||||||
|
* Technology (NIST) by employees of the Federal Government in the course
|
||||||
|
* of their official duties. Pursuant to title 17 Section 105 of the
|
||||||
|
* United States Code, this software is not subject to copyright protection
|
||||||
|
* and is in the public domain. NIST assumes no responsibility whatsoever for
|
||||||
|
* its use by other parties, and makes no guarantees, expressed or implied,
|
||||||
|
* about its quality, reliability, or any other characteristic.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef TNT_ARRAY1D_UTILS_H
|
||||||
|
#define TNT_ARRAY1D_UTILS_H
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
namespace TNT
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
std::ostream& operator<<(std::ostream &s, const Array1D<T> &A)
|
||||||
|
{
|
||||||
|
int N=A.dim1();
|
||||||
|
|
||||||
|
#ifdef TNT_DEBUG
|
||||||
|
s << "addr: " << (void *) &A[0] << "\n";
|
||||||
|
#endif
|
||||||
|
s << N << "\n";
|
||||||
|
for (int j=0; j<N; j++)
|
||||||
|
{
|
||||||
|
s << A[j] << "\n";
|
||||||
|
}
|
||||||
|
s << "\n";
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
std::istream& operator>>(std::istream &s, Array1D<T> &A)
|
||||||
|
{
|
||||||
|
int N;
|
||||||
|
s >> N;
|
||||||
|
|
||||||
|
Array1D<T> B(N);
|
||||||
|
for (int i=0; i<N; i++)
|
||||||
|
s >> B[i];
|
||||||
|
A = B;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array1D<T> operator+(const Array1D<T> &A, const Array1D<T> &B)
|
||||||
|
{
|
||||||
|
int n = A.dim1();
|
||||||
|
|
||||||
|
if (B.dim1() != n )
|
||||||
|
return Array1D<T>();
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Array1D<T> C(n);
|
||||||
|
|
||||||
|
for (int i=0; i<n; i++)
|
||||||
|
{
|
||||||
|
C[i] = A[i] + B[i];
|
||||||
|
}
|
||||||
|
return C;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array1D<T> operator-(const Array1D<T> &A, const Array1D<T> &B)
|
||||||
|
{
|
||||||
|
int n = A.dim1();
|
||||||
|
|
||||||
|
if (B.dim1() != n )
|
||||||
|
return Array1D<T>();
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Array1D<T> C(n);
|
||||||
|
|
||||||
|
for (int i=0; i<n; i++)
|
||||||
|
{
|
||||||
|
C[i] = A[i] - B[i];
|
||||||
|
}
|
||||||
|
return C;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array1D<T> operator*(const Array1D<T> &A, const Array1D<T> &B)
|
||||||
|
{
|
||||||
|
int n = A.dim1();
|
||||||
|
|
||||||
|
if (B.dim1() != n )
|
||||||
|
return Array1D<T>();
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Array1D<T> C(n);
|
||||||
|
|
||||||
|
for (int i=0; i<n; i++)
|
||||||
|
{
|
||||||
|
C[i] = A[i] * B[i];
|
||||||
|
}
|
||||||
|
return C;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array1D<T> operator/(const Array1D<T> &A, const Array1D<T> &B)
|
||||||
|
{
|
||||||
|
int n = A.dim1();
|
||||||
|
|
||||||
|
if (B.dim1() != n )
|
||||||
|
return Array1D<T>();
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Array1D<T> C(n);
|
||||||
|
|
||||||
|
for (int i=0; i<n; i++)
|
||||||
|
{
|
||||||
|
C[i] = A[i] / B[i];
|
||||||
|
}
|
||||||
|
return C;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array1D<T>& operator+=(Array1D<T> &A, const Array1D<T> &B)
|
||||||
|
{
|
||||||
|
int n = A.dim1();
|
||||||
|
|
||||||
|
if (B.dim1() == n)
|
||||||
|
{
|
||||||
|
for (int i=0; i<n; i++)
|
||||||
|
{
|
||||||
|
A[i] += B[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return A;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array1D<T>& operator-=(Array1D<T> &A, const Array1D<T> &B)
|
||||||
|
{
|
||||||
|
int n = A.dim1();
|
||||||
|
|
||||||
|
if (B.dim1() == n)
|
||||||
|
{
|
||||||
|
for (int i=0; i<n; i++)
|
||||||
|
{
|
||||||
|
A[i] -= B[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return A;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array1D<T>& operator*=(Array1D<T> &A, const Array1D<T> &B)
|
||||||
|
{
|
||||||
|
int n = A.dim1();
|
||||||
|
|
||||||
|
if (B.dim1() == n)
|
||||||
|
{
|
||||||
|
for (int i=0; i<n; i++)
|
||||||
|
{
|
||||||
|
A[i] *= B[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return A;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array1D<T>& operator/=(Array1D<T> &A, const Array1D<T> &B)
|
||||||
|
{
|
||||||
|
int n = A.dim1();
|
||||||
|
|
||||||
|
if (B.dim1() == n)
|
||||||
|
{
|
||||||
|
for (int i=0; i<n; i++)
|
||||||
|
{
|
||||||
|
A[i] /= B[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return A;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace TNT
|
||||||
|
|
||||||
|
#endif
|
||||||
315
intern/smoke/intern/tnt/tnt_array2d.h
Normal file
315
intern/smoke/intern/tnt/tnt_array2d.h
Normal file
@@ -0,0 +1,315 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Template Numerical Toolkit (TNT)
|
||||||
|
*
|
||||||
|
* Mathematical and Computational Sciences Division
|
||||||
|
* National Institute of Technology,
|
||||||
|
* Gaithersburg, MD USA
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* This software was developed at the National Institute of Standards and
|
||||||
|
* Technology (NIST) by employees of the Federal Government in the course
|
||||||
|
* of their official duties. Pursuant to title 17 Section 105 of the
|
||||||
|
* United States Code, this software is not subject to copyright protection
|
||||||
|
* and is in the public domain. NIST assumes no responsibility whatsoever for
|
||||||
|
* its use by other parties, and makes no guarantees, expressed or implied,
|
||||||
|
* about its quality, reliability, or any other characteristic.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TNT_ARRAY2D_H
|
||||||
|
#define TNT_ARRAY2D_H
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <iostream>
|
||||||
|
#ifdef TNT_BOUNDS_CHECK
|
||||||
|
#include <assert.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "tnt_array1d.h"
|
||||||
|
|
||||||
|
namespace TNT
|
||||||
|
{
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
class Array2D
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Array1D<T> data_;
|
||||||
|
Array1D<T*> v_;
|
||||||
|
int m_;
|
||||||
|
int n_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef T value_type;
|
||||||
|
Array2D();
|
||||||
|
Array2D(int m, int n);
|
||||||
|
Array2D(int m, int n, T *a);
|
||||||
|
Array2D(int m, int n, const T &a);
|
||||||
|
inline Array2D(const Array2D &A);
|
||||||
|
inline operator T**();
|
||||||
|
inline operator const T**();
|
||||||
|
inline Array2D & operator=(const T &a);
|
||||||
|
inline Array2D & operator=(const Array2D &A);
|
||||||
|
inline Array2D & ref(const Array2D &A);
|
||||||
|
Array2D copy() const;
|
||||||
|
Array2D & inject(const Array2D & A);
|
||||||
|
inline T* operator[](int i);
|
||||||
|
inline const T* operator[](int i) const;
|
||||||
|
inline int dim1() const;
|
||||||
|
inline int dim2() const;
|
||||||
|
~Array2D();
|
||||||
|
|
||||||
|
/* extended interface (not part of the standard) */
|
||||||
|
|
||||||
|
|
||||||
|
inline int ref_count();
|
||||||
|
inline int ref_count_data();
|
||||||
|
inline int ref_count_dim1();
|
||||||
|
Array2D subarray(int i0, int i1, int j0, int j1);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array2D<T>::Array2D() : data_(), v_(), m_(0), n_(0) {}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array2D<T>::Array2D(const Array2D<T> &A) : data_(A.data_), v_(A.v_),
|
||||||
|
m_(A.m_), n_(A.n_) {}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array2D<T>::Array2D(int m, int n) : data_(m*n), v_(m), m_(m), n_(n)
|
||||||
|
{
|
||||||
|
if (m>0 && n>0)
|
||||||
|
{
|
||||||
|
T* p = &(data_[0]);
|
||||||
|
for (int i=0; i<m; i++)
|
||||||
|
{
|
||||||
|
v_[i] = p;
|
||||||
|
p += n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array2D<T>::Array2D(int m, int n, const T &val) : data_(m*n), v_(m),
|
||||||
|
m_(m), n_(n)
|
||||||
|
{
|
||||||
|
if (m>0 && n>0)
|
||||||
|
{
|
||||||
|
data_ = val;
|
||||||
|
T* p = &(data_[0]);
|
||||||
|
for (int i=0; i<m; i++)
|
||||||
|
{
|
||||||
|
v_[i] = p;
|
||||||
|
p += n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array2D<T>::Array2D(int m, int n, T *a) : data_(m*n, a), v_(m), m_(m), n_(n)
|
||||||
|
{
|
||||||
|
if (m>0 && n>0)
|
||||||
|
{
|
||||||
|
T* p = &(data_[0]);
|
||||||
|
|
||||||
|
for (int i=0; i<m; i++)
|
||||||
|
{
|
||||||
|
v_[i] = p;
|
||||||
|
p += n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline T* Array2D<T>::operator[](int i)
|
||||||
|
{
|
||||||
|
#ifdef TNT_BOUNDS_CHECK
|
||||||
|
assert(i >= 0);
|
||||||
|
assert(i < m_);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return v_[i];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline const T* Array2D<T>::operator[](int i) const
|
||||||
|
{
|
||||||
|
#ifdef TNT_BOUNDS_CHECK
|
||||||
|
assert(i >= 0);
|
||||||
|
assert(i < m_);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return v_[i];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array2D<T> & Array2D<T>::operator=(const T &a)
|
||||||
|
{
|
||||||
|
/* non-optimzied, but will work with subarrays in future verions */
|
||||||
|
|
||||||
|
for (int i=0; i<m_; i++)
|
||||||
|
for (int j=0; j<n_; j++)
|
||||||
|
v_[i][j] = a;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array2D<T> Array2D<T>::copy() const
|
||||||
|
{
|
||||||
|
Array2D A(m_, n_);
|
||||||
|
|
||||||
|
for (int i=0; i<m_; i++)
|
||||||
|
for (int j=0; j<n_; j++)
|
||||||
|
A[i][j] = v_[i][j];
|
||||||
|
|
||||||
|
|
||||||
|
return A;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array2D<T> & Array2D<T>::inject(const Array2D &A)
|
||||||
|
{
|
||||||
|
if (A.m_ == m_ && A.n_ == n_)
|
||||||
|
{
|
||||||
|
for (int i=0; i<m_; i++)
|
||||||
|
for (int j=0; j<n_; j++)
|
||||||
|
v_[i][j] = A[i][j];
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array2D<T> & Array2D<T>::ref(const Array2D<T> &A)
|
||||||
|
{
|
||||||
|
if (this != &A)
|
||||||
|
{
|
||||||
|
v_ = A.v_;
|
||||||
|
data_ = A.data_;
|
||||||
|
m_ = A.m_;
|
||||||
|
n_ = A.n_;
|
||||||
|
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array2D<T> & Array2D<T>::operator=(const Array2D<T> &A)
|
||||||
|
{
|
||||||
|
return ref(A);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline int Array2D<T>::dim1() const { return m_; }
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline int Array2D<T>::dim2() const { return n_; }
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array2D<T>::~Array2D() {}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline Array2D<T>::operator T**()
|
||||||
|
{
|
||||||
|
return &(v_[0]);
|
||||||
|
}
|
||||||
|
template <class T>
|
||||||
|
inline Array2D<T>::operator const T**()
|
||||||
|
{
|
||||||
|
return &(v_[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ............... extended interface ............... */
|
||||||
|
/**
|
||||||
|
Create a new view to a subarray defined by the boundaries
|
||||||
|
[i0][i0] and [i1][j1]. The size of the subarray is
|
||||||
|
(i1-i0) by (j1-j0). If either of these lengths are zero
|
||||||
|
or negative, the subarray view is null.
|
||||||
|
|
||||||
|
*/
|
||||||
|
template <class T>
|
||||||
|
Array2D<T> Array2D<T>::subarray(int i0, int i1, int j0, int j1)
|
||||||
|
{
|
||||||
|
Array2D<T> A;
|
||||||
|
int m = i1-i0+1;
|
||||||
|
int n = j1-j0+1;
|
||||||
|
|
||||||
|
/* if either length is zero or negative, this is an invalide
|
||||||
|
subarray. return a null view.
|
||||||
|
*/
|
||||||
|
if (m<1 || n<1)
|
||||||
|
return A;
|
||||||
|
|
||||||
|
A.data_ = data_;
|
||||||
|
A.m_ = m;
|
||||||
|
A.n_ = n;
|
||||||
|
A.v_ = Array1D<T*>(m);
|
||||||
|
T* p = &(data_[0]) + i0 * n_ + j0;
|
||||||
|
for (int i=0; i<m; i++)
|
||||||
|
{
|
||||||
|
A.v_[i] = p + i*n_;
|
||||||
|
|
||||||
|
}
|
||||||
|
return A;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline int Array2D<T>::ref_count()
|
||||||
|
{
|
||||||
|
return ref_count_data();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline int Array2D<T>::ref_count_data()
|
||||||
|
{
|
||||||
|
return data_.ref_count();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline int Array2D<T>::ref_count_dim1()
|
||||||
|
{
|
||||||
|
return v_.ref_count();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} /* namespace TNT */
|
||||||
|
|
||||||
|
#endif
|
||||||
|
/* TNT_ARRAY2D_H */
|
||||||
|
|
||||||
287
intern/smoke/intern/tnt/tnt_array2d_utils.h
Normal file
287
intern/smoke/intern/tnt/tnt_array2d_utils.h
Normal file
@@ -0,0 +1,287 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Template Numerical Toolkit (TNT)
|
||||||
|
*
|
||||||
|
* Mathematical and Computational Sciences Division
|
||||||
|
* National Institute of Technology,
|
||||||
|
* Gaithersburg, MD USA
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* This software was developed at the National Institute of Standards and
|
||||||
|
* Technology (NIST) by employees of the Federal Government in the course
|
||||||
|
* of their official duties. Pursuant to title 17 Section 105 of the
|
||||||
|
* United States Code, this software is not subject to copyright protection
|
||||||
|
* and is in the public domain. NIST assumes no responsibility whatsoever for
|
||||||
|
* its use by other parties, and makes no guarantees, expressed or implied,
|
||||||
|
* about its quality, reliability, or any other characteristic.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TNT_ARRAY2D_UTILS_H
|
||||||
|
#define TNT_ARRAY2D_UTILS_H
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
namespace TNT
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
std::ostream& operator<<(std::ostream &s, const Array2D<T> &A)
|
||||||
|
{
|
||||||
|
int M=A.dim1();
|
||||||
|
int N=A.dim2();
|
||||||
|
|
||||||
|
s << M << " " << N << "\n";
|
||||||
|
|
||||||
|
for (int i=0; i<M; i++)
|
||||||
|
{
|
||||||
|
for (int j=0; j<N; j++)
|
||||||
|
{
|
||||||
|
s << A[i][j] << " ";
|
||||||
|
}
|
||||||
|
s << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
std::istream& operator>>(std::istream &s, Array2D<T> &A)
|
||||||
|
{
|
||||||
|
|
||||||
|
int M, N;
|
||||||
|
|
||||||
|
s >> M >> N;
|
||||||
|
|
||||||
|
Array2D<T> B(M,N);
|
||||||
|
|
||||||
|
for (int i=0; i<M; i++)
|
||||||
|
for (int j=0; j<N; j++)
|
||||||
|
{
|
||||||
|
s >> B[i][j];
|
||||||
|
}
|
||||||
|
|
||||||
|
A = B;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array2D<T> operator+(const Array2D<T> &A, const Array2D<T> &B)
|
||||||
|
{
|
||||||
|
int m = A.dim1();
|
||||||
|
int n = A.dim2();
|
||||||
|
|
||||||
|
if (B.dim1() != m || B.dim2() != n )
|
||||||
|
return Array2D<T>();
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Array2D<T> C(m,n);
|
||||||
|
|
||||||
|
for (int i=0; i<m; i++)
|
||||||
|
{
|
||||||
|
for (int j=0; j<n; j++)
|
||||||
|
C[i][j] = A[i][j] + B[i][j];
|
||||||
|
}
|
||||||
|
return C;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array2D<T> operator-(const Array2D<T> &A, const Array2D<T> &B)
|
||||||
|
{
|
||||||
|
int m = A.dim1();
|
||||||
|
int n = A.dim2();
|
||||||
|
|
||||||
|
if (B.dim1() != m || B.dim2() != n )
|
||||||
|
return Array2D<T>();
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Array2D<T> C(m,n);
|
||||||
|
|
||||||
|
for (int i=0; i<m; i++)
|
||||||
|
{
|
||||||
|
for (int j=0; j<n; j++)
|
||||||
|
C[i][j] = A[i][j] - B[i][j];
|
||||||
|
}
|
||||||
|
return C;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array2D<T> operator*(const Array2D<T> &A, const Array2D<T> &B)
|
||||||
|
{
|
||||||
|
int m = A.dim1();
|
||||||
|
int n = A.dim2();
|
||||||
|
|
||||||
|
if (B.dim1() != m || B.dim2() != n )
|
||||||
|
return Array2D<T>();
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Array2D<T> C(m,n);
|
||||||
|
|
||||||
|
for (int i=0; i<m; i++)
|
||||||
|
{
|
||||||
|
for (int j=0; j<n; j++)
|
||||||
|
C[i][j] = A[i][j] * B[i][j];
|
||||||
|
}
|
||||||
|
return C;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array2D<T> operator/(const Array2D<T> &A, const Array2D<T> &B)
|
||||||
|
{
|
||||||
|
int m = A.dim1();
|
||||||
|
int n = A.dim2();
|
||||||
|
|
||||||
|
if (B.dim1() != m || B.dim2() != n )
|
||||||
|
return Array2D<T>();
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Array2D<T> C(m,n);
|
||||||
|
|
||||||
|
for (int i=0; i<m; i++)
|
||||||
|
{
|
||||||
|
for (int j=0; j<n; j++)
|
||||||
|
C[i][j] = A[i][j] / B[i][j];
|
||||||
|
}
|
||||||
|
return C;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array2D<T>& operator+=(Array2D<T> &A, const Array2D<T> &B)
|
||||||
|
{
|
||||||
|
int m = A.dim1();
|
||||||
|
int n = A.dim2();
|
||||||
|
|
||||||
|
if (B.dim1() == m || B.dim2() == n )
|
||||||
|
{
|
||||||
|
for (int i=0; i<m; i++)
|
||||||
|
{
|
||||||
|
for (int j=0; j<n; j++)
|
||||||
|
A[i][j] += B[i][j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return A;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array2D<T>& operator-=(Array2D<T> &A, const Array2D<T> &B)
|
||||||
|
{
|
||||||
|
int m = A.dim1();
|
||||||
|
int n = A.dim2();
|
||||||
|
|
||||||
|
if (B.dim1() == m || B.dim2() == n )
|
||||||
|
{
|
||||||
|
for (int i=0; i<m; i++)
|
||||||
|
{
|
||||||
|
for (int j=0; j<n; j++)
|
||||||
|
A[i][j] -= B[i][j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return A;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array2D<T>& operator*=(Array2D<T> &A, const Array2D<T> &B)
|
||||||
|
{
|
||||||
|
int m = A.dim1();
|
||||||
|
int n = A.dim2();
|
||||||
|
|
||||||
|
if (B.dim1() == m || B.dim2() == n )
|
||||||
|
{
|
||||||
|
for (int i=0; i<m; i++)
|
||||||
|
{
|
||||||
|
for (int j=0; j<n; j++)
|
||||||
|
A[i][j] *= B[i][j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return A;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array2D<T>& operator/=(Array2D<T> &A, const Array2D<T> &B)
|
||||||
|
{
|
||||||
|
int m = A.dim1();
|
||||||
|
int n = A.dim2();
|
||||||
|
|
||||||
|
if (B.dim1() == m || B.dim2() == n )
|
||||||
|
{
|
||||||
|
for (int i=0; i<m; i++)
|
||||||
|
{
|
||||||
|
for (int j=0; j<n; j++)
|
||||||
|
A[i][j] /= B[i][j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return A;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Matrix Multiply: compute C = A*B, where C[i][j]
|
||||||
|
is the dot-product of row i of A and column j of B.
|
||||||
|
|
||||||
|
|
||||||
|
@param A an (m x n) array
|
||||||
|
@param B an (n x k) array
|
||||||
|
@return the (m x k) array A*B, or a null array (0x0)
|
||||||
|
if the matrices are non-conformant (i.e. the number
|
||||||
|
of columns of A are different than the number of rows of B.)
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
|
template <class T>
|
||||||
|
Array2D<T> matmult(const Array2D<T> &A, const Array2D<T> &B)
|
||||||
|
{
|
||||||
|
if (A.dim2() != B.dim1())
|
||||||
|
return Array2D<T>();
|
||||||
|
|
||||||
|
int M = A.dim1();
|
||||||
|
int N = A.dim2();
|
||||||
|
int K = B.dim2();
|
||||||
|
|
||||||
|
Array2D<T> C(M,K);
|
||||||
|
|
||||||
|
for (int i=0; i<M; i++)
|
||||||
|
for (int j=0; j<K; j++)
|
||||||
|
{
|
||||||
|
T sum = 0;
|
||||||
|
|
||||||
|
for (int k=0; k<N; k++)
|
||||||
|
sum += A[i][k] * B [k][j];
|
||||||
|
|
||||||
|
C[i][j] = sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
return C;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace TNT
|
||||||
|
|
||||||
|
#endif
|
||||||
296
intern/smoke/intern/tnt/tnt_array3d.h
Normal file
296
intern/smoke/intern/tnt/tnt_array3d.h
Normal file
@@ -0,0 +1,296 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Template Numerical Toolkit (TNT)
|
||||||
|
*
|
||||||
|
* Mathematical and Computational Sciences Division
|
||||||
|
* National Institute of Technology,
|
||||||
|
* Gaithersburg, MD USA
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* This software was developed at the National Institute of Standards and
|
||||||
|
* Technology (NIST) by employees of the Federal Government in the course
|
||||||
|
* of their official duties. Pursuant to title 17 Section 105 of the
|
||||||
|
* United States Code, this software is not subject to copyright protection
|
||||||
|
* and is in the public domain. NIST assumes no responsibility whatsoever for
|
||||||
|
* its use by other parties, and makes no guarantees, expressed or implied,
|
||||||
|
* about its quality, reliability, or any other characteristic.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TNT_ARRAY3D_H
|
||||||
|
#define TNT_ARRAY3D_H
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <iostream>
|
||||||
|
#ifdef TNT_BOUNDS_CHECK
|
||||||
|
#include <assert.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "tnt_array1d.h"
|
||||||
|
#include "tnt_array2d.h"
|
||||||
|
|
||||||
|
namespace TNT
|
||||||
|
{
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
class Array3D
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
Array1D<T> data_;
|
||||||
|
Array2D<T*> v_;
|
||||||
|
int m_;
|
||||||
|
int n_;
|
||||||
|
int g_;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef T value_type;
|
||||||
|
|
||||||
|
Array3D();
|
||||||
|
Array3D(int m, int n, int g);
|
||||||
|
Array3D(int m, int n, int g, T val);
|
||||||
|
Array3D(int m, int n, int g, T *a);
|
||||||
|
|
||||||
|
inline operator T***();
|
||||||
|
inline operator const T***();
|
||||||
|
inline Array3D(const Array3D &A);
|
||||||
|
inline Array3D & operator=(const T &a);
|
||||||
|
inline Array3D & operator=(const Array3D &A);
|
||||||
|
inline Array3D & ref(const Array3D &A);
|
||||||
|
Array3D copy() const;
|
||||||
|
Array3D & inject(const Array3D & A);
|
||||||
|
|
||||||
|
inline T** operator[](int i);
|
||||||
|
inline const T* const * operator[](int i) const;
|
||||||
|
inline int dim1() const;
|
||||||
|
inline int dim2() const;
|
||||||
|
inline int dim3() const;
|
||||||
|
~Array3D();
|
||||||
|
|
||||||
|
/* extended interface */
|
||||||
|
|
||||||
|
inline int ref_count(){ return data_.ref_count(); }
|
||||||
|
Array3D subarray(int i0, int i1, int j0, int j1,
|
||||||
|
int k0, int k1);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array3D<T>::Array3D() : data_(), v_(), m_(0), n_(0) {}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array3D<T>::Array3D(const Array3D<T> &A) : data_(A.data_),
|
||||||
|
v_(A.v_), m_(A.m_), n_(A.n_), g_(A.g_)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array3D<T>::Array3D(int m, int n, int g) : data_(m*n*g), v_(m,n),
|
||||||
|
m_(m), n_(n), g_(g)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (m>0 && n>0 && g>0)
|
||||||
|
{
|
||||||
|
T* p = & (data_[0]);
|
||||||
|
int ng = n_*g_;
|
||||||
|
|
||||||
|
for (int i=0; i<m_; i++)
|
||||||
|
{
|
||||||
|
T* ping = p+ i*ng;
|
||||||
|
for (int j=0; j<n; j++)
|
||||||
|
v_[i][j] = ping + j*g_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array3D<T>::Array3D(int m, int n, int g, T val) : data_(m*n*g, val),
|
||||||
|
v_(m,n), m_(m), n_(n), g_(g)
|
||||||
|
{
|
||||||
|
if (m>0 && n>0 && g>0)
|
||||||
|
{
|
||||||
|
|
||||||
|
T* p = & (data_[0]);
|
||||||
|
int ng = n_*g_;
|
||||||
|
|
||||||
|
for (int i=0; i<m_; i++)
|
||||||
|
{
|
||||||
|
T* ping = p+ i*ng;
|
||||||
|
for (int j=0; j<n; j++)
|
||||||
|
v_[i][j] = ping + j*g_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array3D<T>::Array3D(int m, int n, int g, T* a) :
|
||||||
|
data_(m*n*g, a), v_(m,n), m_(m), n_(n), g_(g)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (m>0 && n>0 && g>0)
|
||||||
|
{
|
||||||
|
T* p = & (data_[0]);
|
||||||
|
int ng = n_*g_;
|
||||||
|
|
||||||
|
for (int i=0; i<m_; i++)
|
||||||
|
{
|
||||||
|
T* ping = p+ i*ng;
|
||||||
|
for (int j=0; j<n; j++)
|
||||||
|
v_[i][j] = ping + j*g_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline T** Array3D<T>::operator[](int i)
|
||||||
|
{
|
||||||
|
#ifdef TNT_BOUNDS_CHECK
|
||||||
|
assert(i >= 0);
|
||||||
|
assert(i < m_);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return v_[i];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline const T* const * Array3D<T>::operator[](int i) const
|
||||||
|
{ return v_[i]; }
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array3D<T> & Array3D<T>::operator=(const T &a)
|
||||||
|
{
|
||||||
|
for (int i=0; i<m_; i++)
|
||||||
|
for (int j=0; j<n_; j++)
|
||||||
|
for (int k=0; k<g_; k++)
|
||||||
|
v_[i][j][k] = a;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array3D<T> Array3D<T>::copy() const
|
||||||
|
{
|
||||||
|
Array3D A(m_, n_, g_);
|
||||||
|
for (int i=0; i<m_; i++)
|
||||||
|
for (int j=0; j<n_; j++)
|
||||||
|
for (int k=0; k<g_; k++)
|
||||||
|
A.v_[i][j][k] = v_[i][j][k];
|
||||||
|
|
||||||
|
return A;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array3D<T> & Array3D<T>::inject(const Array3D &A)
|
||||||
|
{
|
||||||
|
if (A.m_ == m_ && A.n_ == n_ && A.g_ == g_)
|
||||||
|
|
||||||
|
for (int i=0; i<m_; i++)
|
||||||
|
for (int j=0; j<n_; j++)
|
||||||
|
for (int k=0; k<g_; k++)
|
||||||
|
v_[i][j][k] = A.v_[i][j][k];
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array3D<T> & Array3D<T>::ref(const Array3D<T> &A)
|
||||||
|
{
|
||||||
|
if (this != &A)
|
||||||
|
{
|
||||||
|
m_ = A.m_;
|
||||||
|
n_ = A.n_;
|
||||||
|
g_ = A.g_;
|
||||||
|
v_ = A.v_;
|
||||||
|
data_ = A.data_;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array3D<T> & Array3D<T>::operator=(const Array3D<T> &A)
|
||||||
|
{
|
||||||
|
return ref(A);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline int Array3D<T>::dim1() const { return m_; }
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline int Array3D<T>::dim2() const { return n_; }
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline int Array3D<T>::dim3() const { return g_; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array3D<T>::~Array3D() {}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline Array3D<T>::operator T***()
|
||||||
|
{
|
||||||
|
return v_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline Array3D<T>::operator const T***()
|
||||||
|
{
|
||||||
|
return v_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* extended interface */
|
||||||
|
template <class T>
|
||||||
|
Array3D<T> Array3D<T>::subarray(int i0, int i1, int j0,
|
||||||
|
int j1, int k0, int k1)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* check that ranges are valid. */
|
||||||
|
if (!( 0 <= i0 && i0 <= i1 && i1 < m_ &&
|
||||||
|
0 <= j0 && j0 <= j1 && j1 < n_ &&
|
||||||
|
0 <= k0 && k0 <= k1 && k1 < g_))
|
||||||
|
return Array3D<T>(); /* null array */
|
||||||
|
|
||||||
|
|
||||||
|
Array3D<T> A;
|
||||||
|
A.data_ = data_;
|
||||||
|
A.m_ = i1-i0+1;
|
||||||
|
A.n_ = j1-j0+1;
|
||||||
|
A.g_ = k1-k0+1;
|
||||||
|
A.v_ = Array2D<T*>(A.m_,A.n_);
|
||||||
|
T* p = &(data_[0]) + i0*n_*g_ + j0*g_ + k0;
|
||||||
|
|
||||||
|
for (int i=0; i<A.m_; i++)
|
||||||
|
{
|
||||||
|
T* ping = p + i*n_*g_;
|
||||||
|
for (int j=0; j<A.n_; j++)
|
||||||
|
A.v_[i][j] = ping + j*g_ ;
|
||||||
|
}
|
||||||
|
|
||||||
|
return A;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} /* namespace TNT */
|
||||||
|
|
||||||
|
#endif
|
||||||
|
/* TNT_ARRAY3D_H */
|
||||||
|
|
||||||
236
intern/smoke/intern/tnt/tnt_array3d_utils.h
Normal file
236
intern/smoke/intern/tnt/tnt_array3d_utils.h
Normal file
@@ -0,0 +1,236 @@
|
|||||||
|
|
||||||
|
|
||||||
|
#ifndef TNT_ARRAY3D_UTILS_H
|
||||||
|
#define TNT_ARRAY3D_UTILS_H
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
namespace TNT
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
std::ostream& operator<<(std::ostream &s, const Array3D<T> &A)
|
||||||
|
{
|
||||||
|
int M=A.dim1();
|
||||||
|
int N=A.dim2();
|
||||||
|
int K=A.dim3();
|
||||||
|
|
||||||
|
s << M << " " << N << " " << K << "\n";
|
||||||
|
|
||||||
|
for (int i=0; i<M; i++)
|
||||||
|
{
|
||||||
|
for (int j=0; j<N; j++)
|
||||||
|
{
|
||||||
|
for (int k=0; k<K; k++)
|
||||||
|
s << A[i][j][k] << " ";
|
||||||
|
s << "\n";
|
||||||
|
}
|
||||||
|
s << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
std::istream& operator>>(std::istream &s, Array3D<T> &A)
|
||||||
|
{
|
||||||
|
|
||||||
|
int M, N, K;
|
||||||
|
|
||||||
|
s >> M >> N >> K;
|
||||||
|
|
||||||
|
Array3D<T> B(M,N,K);
|
||||||
|
|
||||||
|
for (int i=0; i<M; i++)
|
||||||
|
for (int j=0; j<N; j++)
|
||||||
|
for (int k=0; k<K; k++)
|
||||||
|
s >> B[i][j][k];
|
||||||
|
|
||||||
|
A = B;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array3D<T> operator+(const Array3D<T> &A, const Array3D<T> &B)
|
||||||
|
{
|
||||||
|
int m = A.dim1();
|
||||||
|
int n = A.dim2();
|
||||||
|
int p = A.dim3();
|
||||||
|
|
||||||
|
if (B.dim1() != m || B.dim2() != n || B.dim3() != p )
|
||||||
|
return Array3D<T>();
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Array3D<T> C(m,n,p);
|
||||||
|
|
||||||
|
for (int i=0; i<m; i++)
|
||||||
|
for (int j=0; j<n; j++)
|
||||||
|
for (int k=0; k<p; k++)
|
||||||
|
C[i][j][k] = A[i][j][k] + B[i][j][k];
|
||||||
|
|
||||||
|
return C;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array3D<T> operator-(const Array3D<T> &A, const Array3D<T> &B)
|
||||||
|
{
|
||||||
|
int m = A.dim1();
|
||||||
|
int n = A.dim2();
|
||||||
|
int p = A.dim3();
|
||||||
|
|
||||||
|
if (B.dim1() != m || B.dim2() != n || B.dim3() != p )
|
||||||
|
return Array3D<T>();
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Array3D<T> C(m,n,p);
|
||||||
|
|
||||||
|
for (int i=0; i<m; i++)
|
||||||
|
for (int j=0; j<n; j++)
|
||||||
|
for (int k=0; k<p; k++)
|
||||||
|
C[i][j][k] = A[i][j][k] - B[i][j][k];
|
||||||
|
|
||||||
|
return C;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array3D<T> operator*(const Array3D<T> &A, const Array3D<T> &B)
|
||||||
|
{
|
||||||
|
int m = A.dim1();
|
||||||
|
int n = A.dim2();
|
||||||
|
int p = A.dim3();
|
||||||
|
|
||||||
|
if (B.dim1() != m || B.dim2() != n || B.dim3() != p )
|
||||||
|
return Array3D<T>();
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Array3D<T> C(m,n,p);
|
||||||
|
|
||||||
|
for (int i=0; i<m; i++)
|
||||||
|
for (int j=0; j<n; j++)
|
||||||
|
for (int k=0; k<p; k++)
|
||||||
|
C[i][j][k] = A[i][j][k] * B[i][j][k];
|
||||||
|
|
||||||
|
return C;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array3D<T> operator/(const Array3D<T> &A, const Array3D<T> &B)
|
||||||
|
{
|
||||||
|
int m = A.dim1();
|
||||||
|
int n = A.dim2();
|
||||||
|
int p = A.dim3();
|
||||||
|
|
||||||
|
if (B.dim1() != m || B.dim2() != n || B.dim3() != p )
|
||||||
|
return Array3D<T>();
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Array3D<T> C(m,n,p);
|
||||||
|
|
||||||
|
for (int i=0; i<m; i++)
|
||||||
|
for (int j=0; j<n; j++)
|
||||||
|
for (int k=0; k<p; k++)
|
||||||
|
C[i][j][k] = A[i][j][k] / B[i][j][k];
|
||||||
|
|
||||||
|
return C;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array3D<T>& operator+=(Array3D<T> &A, const Array3D<T> &B)
|
||||||
|
{
|
||||||
|
int m = A.dim1();
|
||||||
|
int n = A.dim2();
|
||||||
|
int p = A.dim3();
|
||||||
|
|
||||||
|
if (B.dim1() == m && B.dim2() == n && B.dim3() == p )
|
||||||
|
{
|
||||||
|
for (int i=0; i<m; i++)
|
||||||
|
for (int j=0; j<n; j++)
|
||||||
|
for (int k=0; k<p; k++)
|
||||||
|
A[i][j][k] += B[i][j][k];
|
||||||
|
}
|
||||||
|
|
||||||
|
return A;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array3D<T>& operator-=(Array3D<T> &A, const Array3D<T> &B)
|
||||||
|
{
|
||||||
|
int m = A.dim1();
|
||||||
|
int n = A.dim2();
|
||||||
|
int p = A.dim3();
|
||||||
|
|
||||||
|
if (B.dim1() == m && B.dim2() == n && B.dim3() == p )
|
||||||
|
{
|
||||||
|
for (int i=0; i<m; i++)
|
||||||
|
for (int j=0; j<n; j++)
|
||||||
|
for (int k=0; k<p; k++)
|
||||||
|
A[i][j][k] -= B[i][j][k];
|
||||||
|
}
|
||||||
|
|
||||||
|
return A;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array3D<T>& operator*=(Array3D<T> &A, const Array3D<T> &B)
|
||||||
|
{
|
||||||
|
int m = A.dim1();
|
||||||
|
int n = A.dim2();
|
||||||
|
int p = A.dim3();
|
||||||
|
|
||||||
|
if (B.dim1() == m && B.dim2() == n && B.dim3() == p )
|
||||||
|
{
|
||||||
|
for (int i=0; i<m; i++)
|
||||||
|
for (int j=0; j<n; j++)
|
||||||
|
for (int k=0; k<p; k++)
|
||||||
|
A[i][j][k] *= B[i][j][k];
|
||||||
|
}
|
||||||
|
|
||||||
|
return A;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Array3D<T>& operator/=(Array3D<T> &A, const Array3D<T> &B)
|
||||||
|
{
|
||||||
|
int m = A.dim1();
|
||||||
|
int n = A.dim2();
|
||||||
|
int p = A.dim3();
|
||||||
|
|
||||||
|
if (B.dim1() == m && B.dim2() == n && B.dim3() == p )
|
||||||
|
{
|
||||||
|
for (int i=0; i<m; i++)
|
||||||
|
for (int j=0; j<n; j++)
|
||||||
|
for (int k=0; k<p; k++)
|
||||||
|
A[i][j][k] /= B[i][j][k];
|
||||||
|
}
|
||||||
|
|
||||||
|
return A;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace TNT
|
||||||
|
|
||||||
|
#endif
|
||||||
580
intern/smoke/intern/tnt/tnt_cmat.h
Normal file
580
intern/smoke/intern/tnt/tnt_cmat.h
Normal file
@@ -0,0 +1,580 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Template Numerical Toolkit (TNT)
|
||||||
|
*
|
||||||
|
* Mathematical and Computational Sciences Division
|
||||||
|
* National Institute of Technology,
|
||||||
|
* Gaithersburg, MD USA
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* This software was developed at the National Institute of Standards and
|
||||||
|
* Technology (NIST) by employees of the Federal Government in the course
|
||||||
|
* of their official duties. Pursuant to title 17 Section 105 of the
|
||||||
|
* United States Code, this software is not subject to copyright protection
|
||||||
|
* and is in the public domain. NIST assumes no responsibility whatsoever for
|
||||||
|
* its use by other parties, and makes no guarantees, expressed or implied,
|
||||||
|
* about its quality, reliability, or any other characteristic.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
// C compatible matrix: row-oriented, 0-based [i][j] and 1-based (i,j) indexing
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef TNT_CMAT_H
|
||||||
|
#define TNT_CMAT_H
|
||||||
|
|
||||||
|
#include "tnt_subscript.h"
|
||||||
|
#include "tnt_vec.h"
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cassert>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
namespace TNT
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
class Matrix
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef Subscript size_type;
|
||||||
|
typedef T value_type;
|
||||||
|
typedef T element_type;
|
||||||
|
typedef T* pointer;
|
||||||
|
typedef T* iterator;
|
||||||
|
typedef T& reference;
|
||||||
|
typedef const T* const_iterator;
|
||||||
|
typedef const T& const_reference;
|
||||||
|
|
||||||
|
Subscript lbound() const { return 1;}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Subscript m_;
|
||||||
|
Subscript n_;
|
||||||
|
Subscript mn_; // total size
|
||||||
|
T* v_;
|
||||||
|
T** row_;
|
||||||
|
T* vm1_ ; // these point to the same data, but are 1-based
|
||||||
|
T** rowm1_;
|
||||||
|
|
||||||
|
// internal helper function to create the array
|
||||||
|
// of row pointers
|
||||||
|
|
||||||
|
void initialize(Subscript M, Subscript N)
|
||||||
|
{
|
||||||
|
mn_ = M*N;
|
||||||
|
m_ = M;
|
||||||
|
n_ = N;
|
||||||
|
|
||||||
|
v_ = new T[mn_];
|
||||||
|
row_ = new T*[M];
|
||||||
|
rowm1_ = new T*[M];
|
||||||
|
|
||||||
|
assert(v_ != NULL);
|
||||||
|
assert(row_ != NULL);
|
||||||
|
assert(rowm1_ != NULL);
|
||||||
|
|
||||||
|
T* p = v_;
|
||||||
|
vm1_ = v_ - 1;
|
||||||
|
for (Subscript i=0; i<M; i++)
|
||||||
|
{
|
||||||
|
row_[i] = p;
|
||||||
|
rowm1_[i] = p-1;
|
||||||
|
p += N ;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
rowm1_ -- ; // compensate for 1-based offset
|
||||||
|
}
|
||||||
|
|
||||||
|
void copy(const T* v)
|
||||||
|
{
|
||||||
|
Subscript N = m_ * n_;
|
||||||
|
Subscript i;
|
||||||
|
|
||||||
|
#ifdef TNT_UNROLL_LOOPS
|
||||||
|
Subscript Nmod4 = N & 3;
|
||||||
|
Subscript N4 = N - Nmod4;
|
||||||
|
|
||||||
|
for (i=0; i<N4; i+=4)
|
||||||
|
{
|
||||||
|
v_[i] = v[i];
|
||||||
|
v_[i+1] = v[i+1];
|
||||||
|
v_[i+2] = v[i+2];
|
||||||
|
v_[i+3] = v[i+3];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=N4; i< N; i++)
|
||||||
|
v_[i] = v[i];
|
||||||
|
#else
|
||||||
|
|
||||||
|
for (i=0; i< N; i++)
|
||||||
|
v_[i] = v[i];
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void set(const T& val)
|
||||||
|
{
|
||||||
|
Subscript N = m_ * n_;
|
||||||
|
Subscript i;
|
||||||
|
|
||||||
|
#ifdef TNT_UNROLL_LOOPS
|
||||||
|
Subscript Nmod4 = N & 3;
|
||||||
|
Subscript N4 = N - Nmod4;
|
||||||
|
|
||||||
|
for (i=0; i<N4; i+=4)
|
||||||
|
{
|
||||||
|
v_[i] = val;
|
||||||
|
v_[i+1] = val;
|
||||||
|
v_[i+2] = val;
|
||||||
|
v_[i+3] = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=N4; i< N; i++)
|
||||||
|
v_[i] = val;
|
||||||
|
#else
|
||||||
|
|
||||||
|
for (i=0; i< N; i++)
|
||||||
|
v_[i] = val;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void destroy()
|
||||||
|
{
|
||||||
|
/* do nothing, if no memory has been previously allocated */
|
||||||
|
if (v_ == NULL) return ;
|
||||||
|
|
||||||
|
/* if we are here, then matrix was previously allocated */
|
||||||
|
if (v_ != NULL) delete [] (v_);
|
||||||
|
if (row_ != NULL) delete [] (row_);
|
||||||
|
|
||||||
|
/* return rowm1_ back to original value */
|
||||||
|
rowm1_ ++;
|
||||||
|
if (rowm1_ != NULL ) delete [] (rowm1_);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
operator T**(){ return row_; }
|
||||||
|
operator T**() const { return row_; }
|
||||||
|
|
||||||
|
|
||||||
|
Subscript size() const { return mn_; }
|
||||||
|
|
||||||
|
// constructors
|
||||||
|
|
||||||
|
Matrix() : m_(0), n_(0), mn_(0), v_(0), row_(0), vm1_(0), rowm1_(0) {};
|
||||||
|
|
||||||
|
Matrix(const Matrix<T> &A)
|
||||||
|
{
|
||||||
|
initialize(A.m_, A.n_);
|
||||||
|
copy(A.v_);
|
||||||
|
}
|
||||||
|
|
||||||
|
Matrix(Subscript M, Subscript N, const T& value = T())
|
||||||
|
{
|
||||||
|
initialize(M,N);
|
||||||
|
set(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
Matrix(Subscript M, Subscript N, const T* v)
|
||||||
|
{
|
||||||
|
initialize(M,N);
|
||||||
|
copy(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
Matrix(Subscript M, Subscript N, const char *s)
|
||||||
|
{
|
||||||
|
initialize(M,N);
|
||||||
|
//std::istrstream ins(s);
|
||||||
|
std::istringstream ins(s);
|
||||||
|
|
||||||
|
Subscript i, j;
|
||||||
|
|
||||||
|
for (i=0; i<M; i++)
|
||||||
|
for (j=0; j<N; j++)
|
||||||
|
ins >> row_[i][j];
|
||||||
|
}
|
||||||
|
|
||||||
|
// destructor
|
||||||
|
//
|
||||||
|
~Matrix()
|
||||||
|
{
|
||||||
|
destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// reallocating
|
||||||
|
//
|
||||||
|
Matrix<T>& newsize(Subscript M, Subscript N)
|
||||||
|
{
|
||||||
|
if (num_rows() == M && num_cols() == N)
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
destroy();
|
||||||
|
initialize(M,N);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// assignments
|
||||||
|
//
|
||||||
|
Matrix<T>& operator=(const Matrix<T> &A)
|
||||||
|
{
|
||||||
|
if (v_ == A.v_)
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
if (m_ == A.m_ && n_ == A.n_) // no need to re-alloc
|
||||||
|
copy(A.v_);
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
destroy();
|
||||||
|
initialize(A.m_, A.n_);
|
||||||
|
copy(A.v_);
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Matrix<T>& operator=(const T& scalar)
|
||||||
|
{
|
||||||
|
set(scalar);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Subscript dim(Subscript d) const
|
||||||
|
{
|
||||||
|
#ifdef TNT_BOUNDS_CHECK
|
||||||
|
assert( d >= 1);
|
||||||
|
assert( d <= 2);
|
||||||
|
#endif
|
||||||
|
return (d==1) ? m_ : ((d==2) ? n_ : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Subscript num_rows() const { return m_; }
|
||||||
|
Subscript num_cols() const { return n_; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline T* operator[](Subscript i)
|
||||||
|
{
|
||||||
|
#ifdef TNT_BOUNDS_CHECK
|
||||||
|
assert(0<=i);
|
||||||
|
assert(i < m_) ;
|
||||||
|
#endif
|
||||||
|
return row_[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const T* operator[](Subscript i) const
|
||||||
|
{
|
||||||
|
#ifdef TNT_BOUNDS_CHECK
|
||||||
|
assert(0<=i);
|
||||||
|
assert(i < m_) ;
|
||||||
|
#endif
|
||||||
|
return row_[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline reference operator()(Subscript i)
|
||||||
|
{
|
||||||
|
#ifdef TNT_BOUNDS_CHECK
|
||||||
|
assert(1<=i);
|
||||||
|
assert(i <= mn_) ;
|
||||||
|
#endif
|
||||||
|
return vm1_[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const_reference operator()(Subscript i) const
|
||||||
|
{
|
||||||
|
#ifdef TNT_BOUNDS_CHECK
|
||||||
|
assert(1<=i);
|
||||||
|
assert(i <= mn_) ;
|
||||||
|
#endif
|
||||||
|
return vm1_[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline reference operator()(Subscript i, Subscript j)
|
||||||
|
{
|
||||||
|
#ifdef TNT_BOUNDS_CHECK
|
||||||
|
assert(1<=i);
|
||||||
|
assert(i <= m_) ;
|
||||||
|
assert(1<=j);
|
||||||
|
assert(j <= n_);
|
||||||
|
#endif
|
||||||
|
return rowm1_[i][j];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline const_reference operator() (Subscript i, Subscript j) const
|
||||||
|
{
|
||||||
|
#ifdef TNT_BOUNDS_CHECK
|
||||||
|
assert(1<=i);
|
||||||
|
assert(i <= m_) ;
|
||||||
|
assert(1<=j);
|
||||||
|
assert(j <= n_);
|
||||||
|
#endif
|
||||||
|
return rowm1_[i][j];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* *************************** I/O ********************************/
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
std::ostream& operator<<(std::ostream &s, const Matrix<T> &A)
|
||||||
|
{
|
||||||
|
Subscript M=A.num_rows();
|
||||||
|
Subscript N=A.num_cols();
|
||||||
|
|
||||||
|
s << M << " " << N << "\n";
|
||||||
|
|
||||||
|
for (Subscript i=0; i<M; i++)
|
||||||
|
{
|
||||||
|
for (Subscript j=0; j<N; j++)
|
||||||
|
{
|
||||||
|
s << A[i][j] << " ";
|
||||||
|
}
|
||||||
|
s << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
std::istream& operator>>(std::istream &s, Matrix<T> &A)
|
||||||
|
{
|
||||||
|
|
||||||
|
Subscript M, N;
|
||||||
|
|
||||||
|
s >> M >> N;
|
||||||
|
|
||||||
|
if ( !(M == A.num_rows() && N == A.num_cols() ))
|
||||||
|
{
|
||||||
|
A.newsize(M,N);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (Subscript i=0; i<M; i++)
|
||||||
|
for (Subscript j=0; j<N; j++)
|
||||||
|
{
|
||||||
|
s >> A[i][j];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
// *******************[ basic matrix algorithms ]***************************
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Matrix<T> operator+(const Matrix<T> &A,
|
||||||
|
const Matrix<T> &B)
|
||||||
|
{
|
||||||
|
Subscript M = A.num_rows();
|
||||||
|
Subscript N = A.num_cols();
|
||||||
|
|
||||||
|
assert(M==B.num_rows());
|
||||||
|
assert(N==B.num_cols());
|
||||||
|
|
||||||
|
Matrix<T> tmp(M,N);
|
||||||
|
Subscript i,j;
|
||||||
|
|
||||||
|
for (i=0; i<M; i++)
|
||||||
|
for (j=0; j<N; j++)
|
||||||
|
tmp[i][j] = A[i][j] + B[i][j];
|
||||||
|
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Matrix<T> operator-(const Matrix<T> &A,
|
||||||
|
const Matrix<T> &B)
|
||||||
|
{
|
||||||
|
Subscript M = A.num_rows();
|
||||||
|
Subscript N = A.num_cols();
|
||||||
|
|
||||||
|
assert(M==B.num_rows());
|
||||||
|
assert(N==B.num_cols());
|
||||||
|
|
||||||
|
Matrix<T> tmp(M,N);
|
||||||
|
Subscript i,j;
|
||||||
|
|
||||||
|
for (i=0; i<M; i++)
|
||||||
|
for (j=0; j<N; j++)
|
||||||
|
tmp[i][j] = A[i][j] - B[i][j];
|
||||||
|
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Matrix<T> mult_element(const Matrix<T> &A,
|
||||||
|
const Matrix<T> &B)
|
||||||
|
{
|
||||||
|
Subscript M = A.num_rows();
|
||||||
|
Subscript N = A.num_cols();
|
||||||
|
|
||||||
|
assert(M==B.num_rows());
|
||||||
|
assert(N==B.num_cols());
|
||||||
|
|
||||||
|
Matrix<T> tmp(M,N);
|
||||||
|
Subscript i,j;
|
||||||
|
|
||||||
|
for (i=0; i<M; i++)
|
||||||
|
for (j=0; j<N; j++)
|
||||||
|
tmp[i][j] = A[i][j] * B[i][j];
|
||||||
|
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Matrix<T> transpose(const Matrix<T> &A)
|
||||||
|
{
|
||||||
|
Subscript M = A.num_rows();
|
||||||
|
Subscript N = A.num_cols();
|
||||||
|
|
||||||
|
Matrix<T> S(N,M);
|
||||||
|
Subscript i, j;
|
||||||
|
|
||||||
|
for (i=0; i<M; i++)
|
||||||
|
for (j=0; j<N; j++)
|
||||||
|
S[j][i] = A[i][j];
|
||||||
|
|
||||||
|
return S;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline Matrix<T> matmult(const Matrix<T> &A,
|
||||||
|
const Matrix<T> &B)
|
||||||
|
{
|
||||||
|
|
||||||
|
#ifdef TNT_BOUNDS_CHECK
|
||||||
|
assert(A.num_cols() == B.num_rows());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Subscript M = A.num_rows();
|
||||||
|
Subscript N = A.num_cols();
|
||||||
|
Subscript K = B.num_cols();
|
||||||
|
|
||||||
|
Matrix<T> tmp(M,K);
|
||||||
|
T sum;
|
||||||
|
|
||||||
|
for (Subscript i=0; i<M; i++)
|
||||||
|
for (Subscript k=0; k<K; k++)
|
||||||
|
{
|
||||||
|
sum = 0;
|
||||||
|
for (Subscript j=0; j<N; j++)
|
||||||
|
sum = sum + A[i][j] * B[j][k];
|
||||||
|
|
||||||
|
tmp[i][k] = sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline Matrix<T> operator*(const Matrix<T> &A,
|
||||||
|
const Matrix<T> &B)
|
||||||
|
{
|
||||||
|
return matmult(A,B);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline int matmult(Matrix<T>& C, const Matrix<T> &A,
|
||||||
|
const Matrix<T> &B)
|
||||||
|
{
|
||||||
|
|
||||||
|
assert(A.num_cols() == B.num_rows());
|
||||||
|
|
||||||
|
Subscript M = A.num_rows();
|
||||||
|
Subscript N = A.num_cols();
|
||||||
|
Subscript K = B.num_cols();
|
||||||
|
|
||||||
|
C.newsize(M,K);
|
||||||
|
|
||||||
|
T sum;
|
||||||
|
|
||||||
|
const T* row_i;
|
||||||
|
const T* col_k;
|
||||||
|
|
||||||
|
for (Subscript i=0; i<M; i++)
|
||||||
|
for (Subscript k=0; k<K; k++)
|
||||||
|
{
|
||||||
|
row_i = &(A[i][0]);
|
||||||
|
col_k = &(B[0][k]);
|
||||||
|
sum = 0;
|
||||||
|
for (Subscript j=0; j<N; j++)
|
||||||
|
{
|
||||||
|
sum += *row_i * *col_k;
|
||||||
|
row_i++;
|
||||||
|
col_k += K;
|
||||||
|
}
|
||||||
|
C[i][k] = sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Vector<T> matmult(const Matrix<T> &A, const Vector<T> &x)
|
||||||
|
{
|
||||||
|
|
||||||
|
#ifdef TNT_BOUNDS_CHECK
|
||||||
|
assert(A.num_cols() == x.dim());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Subscript M = A.num_rows();
|
||||||
|
Subscript N = A.num_cols();
|
||||||
|
|
||||||
|
Vector<T> tmp(M);
|
||||||
|
T sum;
|
||||||
|
|
||||||
|
for (Subscript i=0; i<M; i++)
|
||||||
|
{
|
||||||
|
sum = 0;
|
||||||
|
const T* rowi = A[i];
|
||||||
|
for (Subscript j=0; j<N; j++)
|
||||||
|
sum = sum + rowi[j] * x[j];
|
||||||
|
|
||||||
|
tmp[i] = sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline Vector<T> operator*(const Matrix<T> &A, const Vector<T> &x)
|
||||||
|
{
|
||||||
|
return matmult(A,x);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace TNT
|
||||||
|
|
||||||
|
#endif
|
||||||
|
// CMAT_H
|
||||||
267
intern/smoke/intern/tnt/tnt_fortran_array1d.h
Normal file
267
intern/smoke/intern/tnt/tnt_fortran_array1d.h
Normal file
@@ -0,0 +1,267 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Template Numerical Toolkit (TNT)
|
||||||
|
*
|
||||||
|
* Mathematical and Computational Sciences Division
|
||||||
|
* National Institute of Technology,
|
||||||
|
* Gaithersburg, MD USA
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* This software was developed at the National Institute of Standards and
|
||||||
|
* Technology (NIST) by employees of the Federal Government in the course
|
||||||
|
* of their official duties. Pursuant to title 17 Section 105 of the
|
||||||
|
* United States Code, this software is not subject to copyright protection
|
||||||
|
* and is in the public domain. NIST assumes no responsibility whatsoever for
|
||||||
|
* its use by other parties, and makes no guarantees, expressed or implied,
|
||||||
|
* about its quality, reliability, or any other characteristic.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TNT_FORTRAN_ARRAY1D_H
|
||||||
|
#define TNT_FORTRAN_ARRAY1D_H
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#ifdef TNT_BOUNDS_CHECK
|
||||||
|
#include <assert.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#include "tnt_i_refvec.h"
|
||||||
|
|
||||||
|
namespace TNT
|
||||||
|
{
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
class Fortran_Array1D
|
||||||
|
{
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
i_refvec<T> v_;
|
||||||
|
int n_;
|
||||||
|
T* data_; /* this normally points to v_.begin(), but
|
||||||
|
* could also point to a portion (subvector)
|
||||||
|
* of v_.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void initialize_(int n);
|
||||||
|
void copy_(T* p, const T* q, int len) const;
|
||||||
|
void set_(T* begin, T* end, const T& val);
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef T value_type;
|
||||||
|
|
||||||
|
|
||||||
|
Fortran_Array1D();
|
||||||
|
explicit Fortran_Array1D(int n);
|
||||||
|
Fortran_Array1D(int n, const T &a);
|
||||||
|
Fortran_Array1D(int n, T *a);
|
||||||
|
inline Fortran_Array1D(const Fortran_Array1D &A);
|
||||||
|
inline Fortran_Array1D & operator=(const T &a);
|
||||||
|
inline Fortran_Array1D & operator=(const Fortran_Array1D &A);
|
||||||
|
inline Fortran_Array1D & ref(const Fortran_Array1D &A);
|
||||||
|
Fortran_Array1D copy() const;
|
||||||
|
Fortran_Array1D & inject(const Fortran_Array1D & A);
|
||||||
|
inline T& operator()(int i);
|
||||||
|
inline const T& operator()(int i) const;
|
||||||
|
inline int dim1() const;
|
||||||
|
inline int dim() const;
|
||||||
|
~Fortran_Array1D();
|
||||||
|
|
||||||
|
|
||||||
|
/* ... extended interface ... */
|
||||||
|
|
||||||
|
inline int ref_count() const;
|
||||||
|
inline Fortran_Array1D<T> subarray(int i0, int i1);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array1D<T>::Fortran_Array1D() : v_(), n_(0), data_(0) {}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array1D<T>::Fortran_Array1D(const Fortran_Array1D<T> &A) : v_(A.v_), n_(A.n_),
|
||||||
|
data_(A.data_)
|
||||||
|
{
|
||||||
|
#ifdef TNT_DEBUG
|
||||||
|
std::cout << "Created Fortran_Array1D(const Fortran_Array1D<T> &A) \n";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array1D<T>::Fortran_Array1D(int n) : v_(n), n_(n), data_(v_.begin())
|
||||||
|
{
|
||||||
|
#ifdef TNT_DEBUG
|
||||||
|
std::cout << "Created Fortran_Array1D(int n) \n";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array1D<T>::Fortran_Array1D(int n, const T &val) : v_(n), n_(n), data_(v_.begin())
|
||||||
|
{
|
||||||
|
#ifdef TNT_DEBUG
|
||||||
|
std::cout << "Created Fortran_Array1D(int n, const T& val) \n";
|
||||||
|
#endif
|
||||||
|
set_(data_, data_+ n, val);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array1D<T>::Fortran_Array1D(int n, T *a) : v_(a), n_(n) , data_(v_.begin())
|
||||||
|
{
|
||||||
|
#ifdef TNT_DEBUG
|
||||||
|
std::cout << "Created Fortran_Array1D(int n, T* a) \n";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline T& Fortran_Array1D<T>::operator()(int i)
|
||||||
|
{
|
||||||
|
#ifdef TNT_BOUNDS_CHECK
|
||||||
|
assert(i>= 1);
|
||||||
|
assert(i <= n_);
|
||||||
|
#endif
|
||||||
|
return data_[i-1];
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline const T& Fortran_Array1D<T>::operator()(int i) const
|
||||||
|
{
|
||||||
|
#ifdef TNT_BOUNDS_CHECK
|
||||||
|
assert(i>= 1);
|
||||||
|
assert(i <= n_);
|
||||||
|
#endif
|
||||||
|
return data_[i-1];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array1D<T> & Fortran_Array1D<T>::operator=(const T &a)
|
||||||
|
{
|
||||||
|
set_(data_, data_+n_, a);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array1D<T> Fortran_Array1D<T>::copy() const
|
||||||
|
{
|
||||||
|
Fortran_Array1D A( n_);
|
||||||
|
copy_(A.data_, data_, n_);
|
||||||
|
|
||||||
|
return A;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array1D<T> & Fortran_Array1D<T>::inject(const Fortran_Array1D &A)
|
||||||
|
{
|
||||||
|
if (A.n_ == n_)
|
||||||
|
copy_(data_, A.data_, n_);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array1D<T> & Fortran_Array1D<T>::ref(const Fortran_Array1D<T> &A)
|
||||||
|
{
|
||||||
|
if (this != &A)
|
||||||
|
{
|
||||||
|
v_ = A.v_; /* operator= handles the reference counting. */
|
||||||
|
n_ = A.n_;
|
||||||
|
data_ = A.data_;
|
||||||
|
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array1D<T> & Fortran_Array1D<T>::operator=(const Fortran_Array1D<T> &A)
|
||||||
|
{
|
||||||
|
return ref(A);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline int Fortran_Array1D<T>::dim1() const { return n_; }
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline int Fortran_Array1D<T>::dim() const { return n_; }
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array1D<T>::~Fortran_Array1D() {}
|
||||||
|
|
||||||
|
|
||||||
|
/* ............................ exented interface ......................*/
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline int Fortran_Array1D<T>::ref_count() const
|
||||||
|
{
|
||||||
|
return v_.ref_count();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline Fortran_Array1D<T> Fortran_Array1D<T>::subarray(int i0, int i1)
|
||||||
|
{
|
||||||
|
#ifdef TNT_DEBUG
|
||||||
|
std::cout << "entered subarray. \n";
|
||||||
|
#endif
|
||||||
|
if ((i0 > 0) && (i1 < n_) || (i0 <= i1))
|
||||||
|
{
|
||||||
|
Fortran_Array1D<T> X(*this); /* create a new instance of this array. */
|
||||||
|
X.n_ = i1-i0+1;
|
||||||
|
X.data_ += i0;
|
||||||
|
|
||||||
|
return X;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifdef TNT_DEBUG
|
||||||
|
std::cout << "subarray: null return.\n";
|
||||||
|
#endif
|
||||||
|
return Fortran_Array1D<T>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* private internal functions */
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void Fortran_Array1D<T>::set_(T* begin, T* end, const T& a)
|
||||||
|
{
|
||||||
|
for (T* p=begin; p<end; p++)
|
||||||
|
*p = a;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void Fortran_Array1D<T>::copy_(T* p, const T* q, int len) const
|
||||||
|
{
|
||||||
|
T *end = p + len;
|
||||||
|
while (p<end )
|
||||||
|
*p++ = *q++;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} /* namespace TNT */
|
||||||
|
|
||||||
|
#endif
|
||||||
|
/* TNT_FORTRAN_ARRAY1D_H */
|
||||||
|
|
||||||
242
intern/smoke/intern/tnt/tnt_fortran_array1d_utils.h
Normal file
242
intern/smoke/intern/tnt/tnt_fortran_array1d_utils.h
Normal file
@@ -0,0 +1,242 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Template Numerical Toolkit (TNT)
|
||||||
|
*
|
||||||
|
* Mathematical and Computational Sciences Division
|
||||||
|
* National Institute of Technology,
|
||||||
|
* Gaithersburg, MD USA
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* This software was developed at the National Institute of Standards and
|
||||||
|
* Technology (NIST) by employees of the Federal Government in the course
|
||||||
|
* of their official duties. Pursuant to title 17 Section 105 of the
|
||||||
|
* United States Code, this software is not subject to copyright protection
|
||||||
|
* and is in the public domain. NIST assumes no responsibility whatsoever for
|
||||||
|
* its use by other parties, and makes no guarantees, expressed or implied,
|
||||||
|
* about its quality, reliability, or any other characteristic.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef TNT_FORTRAN_ARRAY1D_UTILS_H
|
||||||
|
#define TNT_FORTRAN_ARRAY1D_UTILS_H
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace TNT
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Write an array to a character outstream. Output format is one that can
|
||||||
|
be read back in via the in-stream operator: one integer
|
||||||
|
denoting the array dimension (n), followed by n elements,
|
||||||
|
one per line.
|
||||||
|
|
||||||
|
*/
|
||||||
|
template <class T>
|
||||||
|
std::ostream& operator<<(std::ostream &s, const Fortran_Array1D<T> &A)
|
||||||
|
{
|
||||||
|
int N=A.dim1();
|
||||||
|
|
||||||
|
s << N << "\n";
|
||||||
|
for (int j=1; j<=N; j++)
|
||||||
|
{
|
||||||
|
s << A(j) << "\n";
|
||||||
|
}
|
||||||
|
s << "\n";
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Read an array from a character stream. Input format
|
||||||
|
is one integer, denoting the dimension (n), followed
|
||||||
|
by n whitespace-separated elments. Newlines are ignored
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Note: the array being read into references new memory
|
||||||
|
storage. If the intent is to fill an existing conformant
|
||||||
|
array, use <code> cin >> B; A.inject(B) ); </code>
|
||||||
|
instead or read the elements in one-a-time by hand.
|
||||||
|
|
||||||
|
@param s the charater to read from (typically <code>std::in</code>)
|
||||||
|
@param A the array to read into.
|
||||||
|
*/
|
||||||
|
template <class T>
|
||||||
|
std::istream& operator>>(std::istream &s, Fortran_Array1D<T> &A)
|
||||||
|
{
|
||||||
|
int N;
|
||||||
|
s >> N;
|
||||||
|
|
||||||
|
Fortran_Array1D<T> B(N);
|
||||||
|
for (int i=1; i<=N; i++)
|
||||||
|
s >> B(i);
|
||||||
|
A = B;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array1D<T> operator+(const Fortran_Array1D<T> &A, const Fortran_Array1D<T> &B)
|
||||||
|
{
|
||||||
|
int n = A.dim1();
|
||||||
|
|
||||||
|
if (B.dim1() != n )
|
||||||
|
return Fortran_Array1D<T>();
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Fortran_Array1D<T> C(n);
|
||||||
|
|
||||||
|
for (int i=1; i<=n; i++)
|
||||||
|
{
|
||||||
|
C(i) = A(i) + B(i);
|
||||||
|
}
|
||||||
|
return C;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array1D<T> operator-(const Fortran_Array1D<T> &A, const Fortran_Array1D<T> &B)
|
||||||
|
{
|
||||||
|
int n = A.dim1();
|
||||||
|
|
||||||
|
if (B.dim1() != n )
|
||||||
|
return Fortran_Array1D<T>();
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Fortran_Array1D<T> C(n);
|
||||||
|
|
||||||
|
for (int i=1; i<=n; i++)
|
||||||
|
{
|
||||||
|
C(i) = A(i) - B(i);
|
||||||
|
}
|
||||||
|
return C;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array1D<T> operator*(const Fortran_Array1D<T> &A, const Fortran_Array1D<T> &B)
|
||||||
|
{
|
||||||
|
int n = A.dim1();
|
||||||
|
|
||||||
|
if (B.dim1() != n )
|
||||||
|
return Fortran_Array1D<T>();
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Fortran_Array1D<T> C(n);
|
||||||
|
|
||||||
|
for (int i=1; i<=n; i++)
|
||||||
|
{
|
||||||
|
C(i) = A(i) * B(i);
|
||||||
|
}
|
||||||
|
return C;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array1D<T> operator/(const Fortran_Array1D<T> &A, const Fortran_Array1D<T> &B)
|
||||||
|
{
|
||||||
|
int n = A.dim1();
|
||||||
|
|
||||||
|
if (B.dim1() != n )
|
||||||
|
return Fortran_Array1D<T>();
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Fortran_Array1D<T> C(n);
|
||||||
|
|
||||||
|
for (int i=1; i<=n; i++)
|
||||||
|
{
|
||||||
|
C(i) = A(i) / B(i);
|
||||||
|
}
|
||||||
|
return C;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array1D<T>& operator+=(Fortran_Array1D<T> &A, const Fortran_Array1D<T> &B)
|
||||||
|
{
|
||||||
|
int n = A.dim1();
|
||||||
|
|
||||||
|
if (B.dim1() == n)
|
||||||
|
{
|
||||||
|
for (int i=1; i<=n; i++)
|
||||||
|
{
|
||||||
|
A(i) += B(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return A;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array1D<T>& operator-=(Fortran_Array1D<T> &A, const Fortran_Array1D<T> &B)
|
||||||
|
{
|
||||||
|
int n = A.dim1();
|
||||||
|
|
||||||
|
if (B.dim1() == n)
|
||||||
|
{
|
||||||
|
for (int i=1; i<=n; i++)
|
||||||
|
{
|
||||||
|
A(i) -= B(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return A;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array1D<T>& operator*=(Fortran_Array1D<T> &A, const Fortran_Array1D<T> &B)
|
||||||
|
{
|
||||||
|
int n = A.dim1();
|
||||||
|
|
||||||
|
if (B.dim1() == n)
|
||||||
|
{
|
||||||
|
for (int i=1; i<=n; i++)
|
||||||
|
{
|
||||||
|
A(i) *= B(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return A;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array1D<T>& operator/=(Fortran_Array1D<T> &A, const Fortran_Array1D<T> &B)
|
||||||
|
{
|
||||||
|
int n = A.dim1();
|
||||||
|
|
||||||
|
if (B.dim1() == n)
|
||||||
|
{
|
||||||
|
for (int i=1; i<=n; i++)
|
||||||
|
{
|
||||||
|
A(i) /= B(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return A;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace TNT
|
||||||
|
|
||||||
|
#endif
|
||||||
225
intern/smoke/intern/tnt/tnt_fortran_array2d.h
Normal file
225
intern/smoke/intern/tnt/tnt_fortran_array2d.h
Normal file
@@ -0,0 +1,225 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Template Numerical Toolkit (TNT): Two-dimensional Fortran numerical array
|
||||||
|
*
|
||||||
|
* Mathematical and Computational Sciences Division
|
||||||
|
* National Institute of Technology,
|
||||||
|
* Gaithersburg, MD USA
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* This software was developed at the National Institute of Standards and
|
||||||
|
* Technology (NIST) by employees of the Federal Government in the course
|
||||||
|
* of their official duties. Pursuant to title 17 Section 105 of the
|
||||||
|
* United States Code, this software is not subject to copyright protection
|
||||||
|
* and is in the public domain. NIST assumes no responsibility whatsoever for
|
||||||
|
* its use by other parties, and makes no guarantees, expressed or implied,
|
||||||
|
* about its quality, reliability, or any other characteristic.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TNT_FORTRAN_ARRAY2D_H
|
||||||
|
#define TNT_FORTRAN_ARRAY2D_H
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#ifdef TNT_BOUNDS_CHECK
|
||||||
|
#include <assert.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "tnt_i_refvec.h"
|
||||||
|
|
||||||
|
namespace TNT
|
||||||
|
{
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
class Fortran_Array2D
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
i_refvec<T> v_;
|
||||||
|
int m_;
|
||||||
|
int n_;
|
||||||
|
T* data_;
|
||||||
|
|
||||||
|
|
||||||
|
void initialize_(int n);
|
||||||
|
void copy_(T* p, const T* q, int len);
|
||||||
|
void set_(T* begin, T* end, const T& val);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef T value_type;
|
||||||
|
|
||||||
|
Fortran_Array2D();
|
||||||
|
Fortran_Array2D(int m, int n);
|
||||||
|
Fortran_Array2D(int m, int n, T *a);
|
||||||
|
Fortran_Array2D(int m, int n, const T &a);
|
||||||
|
inline Fortran_Array2D(const Fortran_Array2D &A);
|
||||||
|
inline Fortran_Array2D & operator=(const T &a);
|
||||||
|
inline Fortran_Array2D & operator=(const Fortran_Array2D &A);
|
||||||
|
inline Fortran_Array2D & ref(const Fortran_Array2D &A);
|
||||||
|
Fortran_Array2D copy() const;
|
||||||
|
Fortran_Array2D & inject(const Fortran_Array2D & A);
|
||||||
|
inline T& operator()(int i, int j);
|
||||||
|
inline const T& operator()(int i, int j) const ;
|
||||||
|
inline int dim1() const;
|
||||||
|
inline int dim2() const;
|
||||||
|
~Fortran_Array2D();
|
||||||
|
|
||||||
|
/* extended interface */
|
||||||
|
|
||||||
|
inline int ref_count() const;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array2D<T>::Fortran_Array2D() : v_(), m_(0), n_(0), data_(0) {}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array2D<T>::Fortran_Array2D(const Fortran_Array2D<T> &A) : v_(A.v_),
|
||||||
|
m_(A.m_), n_(A.n_), data_(A.data_) {}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array2D<T>::Fortran_Array2D(int m, int n) : v_(m*n), m_(m), n_(n),
|
||||||
|
data_(v_.begin()) {}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array2D<T>::Fortran_Array2D(int m, int n, const T &val) :
|
||||||
|
v_(m*n), m_(m), n_(n), data_(v_.begin())
|
||||||
|
{
|
||||||
|
set_(data_, data_+m*n, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array2D<T>::Fortran_Array2D(int m, int n, T *a) : v_(a),
|
||||||
|
m_(m), n_(n), data_(v_.begin()) {}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline T& Fortran_Array2D<T>::operator()(int i, int j)
|
||||||
|
{
|
||||||
|
#ifdef TNT_BOUNDS_CHECK
|
||||||
|
assert(i >= 1);
|
||||||
|
assert(i <= m_);
|
||||||
|
assert(j >= 1);
|
||||||
|
assert(j <= n_);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return v_[ (j-1)*m_ + (i-1) ];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline const T& Fortran_Array2D<T>::operator()(int i, int j) const
|
||||||
|
{
|
||||||
|
#ifdef TNT_BOUNDS_CHECK
|
||||||
|
assert(i >= 1);
|
||||||
|
assert(i <= m_);
|
||||||
|
assert(j >= 1);
|
||||||
|
assert(j <= n_);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return v_[ (j-1)*m_ + (i-1) ];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array2D<T> & Fortran_Array2D<T>::operator=(const T &a)
|
||||||
|
{
|
||||||
|
set_(data_, data_+m_*n_, a);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array2D<T> Fortran_Array2D<T>::copy() const
|
||||||
|
{
|
||||||
|
|
||||||
|
Fortran_Array2D B(m_,n_);
|
||||||
|
|
||||||
|
B.inject(*this);
|
||||||
|
return B;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array2D<T> & Fortran_Array2D<T>::inject(const Fortran_Array2D &A)
|
||||||
|
{
|
||||||
|
if (m_ == A.m_ && n_ == A.n_)
|
||||||
|
copy_(data_, A.data_, m_*n_);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array2D<T> & Fortran_Array2D<T>::ref(const Fortran_Array2D<T> &A)
|
||||||
|
{
|
||||||
|
if (this != &A)
|
||||||
|
{
|
||||||
|
v_ = A.v_;
|
||||||
|
m_ = A.m_;
|
||||||
|
n_ = A.n_;
|
||||||
|
data_ = A.data_;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array2D<T> & Fortran_Array2D<T>::operator=(const Fortran_Array2D<T> &A)
|
||||||
|
{
|
||||||
|
return ref(A);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline int Fortran_Array2D<T>::dim1() const { return m_; }
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline int Fortran_Array2D<T>::dim2() const { return n_; }
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array2D<T>::~Fortran_Array2D()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline int Fortran_Array2D<T>::ref_count() const { return v_.ref_count(); }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void Fortran_Array2D<T>::set_(T* begin, T* end, const T& a)
|
||||||
|
{
|
||||||
|
for (T* p=begin; p<end; p++)
|
||||||
|
*p = a;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void Fortran_Array2D<T>::copy_(T* p, const T* q, int len)
|
||||||
|
{
|
||||||
|
T *end = p + len;
|
||||||
|
while (p<end )
|
||||||
|
*p++ = *q++;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} /* namespace TNT */
|
||||||
|
|
||||||
|
#endif
|
||||||
|
/* TNT_FORTRAN_ARRAY2D_H */
|
||||||
|
|
||||||
236
intern/smoke/intern/tnt/tnt_fortran_array2d_utils.h
Normal file
236
intern/smoke/intern/tnt/tnt_fortran_array2d_utils.h
Normal file
@@ -0,0 +1,236 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Template Numerical Toolkit (TNT)
|
||||||
|
*
|
||||||
|
* Mathematical and Computational Sciences Division
|
||||||
|
* National Institute of Technology,
|
||||||
|
* Gaithersburg, MD USA
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* This software was developed at the National Institute of Standards and
|
||||||
|
* Technology (NIST) by employees of the Federal Government in the course
|
||||||
|
* of their official duties. Pursuant to title 17 Section 105 of the
|
||||||
|
* United States Code, this software is not subject to copyright protection
|
||||||
|
* and is in the public domain. NIST assumes no responsibility whatsoever for
|
||||||
|
* its use by other parties, and makes no guarantees, expressed or implied,
|
||||||
|
* about its quality, reliability, or any other characteristic.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TNT_FORTRAN_ARRAY2D_UTILS_H
|
||||||
|
#define TNT_FORTRAN_ARRAY2D_UTILS_H
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace TNT
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
std::ostream& operator<<(std::ostream &s, const Fortran_Array2D<T> &A)
|
||||||
|
{
|
||||||
|
int M=A.dim1();
|
||||||
|
int N=A.dim2();
|
||||||
|
|
||||||
|
s << M << " " << N << "\n";
|
||||||
|
|
||||||
|
for (int i=1; i<=M; i++)
|
||||||
|
{
|
||||||
|
for (int j=1; j<=N; j++)
|
||||||
|
{
|
||||||
|
s << A(i,j) << " ";
|
||||||
|
}
|
||||||
|
s << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
std::istream& operator>>(std::istream &s, Fortran_Array2D<T> &A)
|
||||||
|
{
|
||||||
|
|
||||||
|
int M, N;
|
||||||
|
|
||||||
|
s >> M >> N;
|
||||||
|
|
||||||
|
Fortran_Array2D<T> B(M,N);
|
||||||
|
|
||||||
|
for (int i=1; i<=M; i++)
|
||||||
|
for (int j=1; j<=N; j++)
|
||||||
|
{
|
||||||
|
s >> B(i,j);
|
||||||
|
}
|
||||||
|
|
||||||
|
A = B;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array2D<T> operator+(const Fortran_Array2D<T> &A, const Fortran_Array2D<T> &B)
|
||||||
|
{
|
||||||
|
int m = A.dim1();
|
||||||
|
int n = A.dim2();
|
||||||
|
|
||||||
|
if (B.dim1() != m || B.dim2() != n )
|
||||||
|
return Fortran_Array2D<T>();
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Fortran_Array2D<T> C(m,n);
|
||||||
|
|
||||||
|
for (int i=1; i<=m; i++)
|
||||||
|
{
|
||||||
|
for (int j=1; j<=n; j++)
|
||||||
|
C(i,j) = A(i,j) + B(i,j);
|
||||||
|
}
|
||||||
|
return C;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array2D<T> operator-(const Fortran_Array2D<T> &A, const Fortran_Array2D<T> &B)
|
||||||
|
{
|
||||||
|
int m = A.dim1();
|
||||||
|
int n = A.dim2();
|
||||||
|
|
||||||
|
if (B.dim1() != m || B.dim2() != n )
|
||||||
|
return Fortran_Array2D<T>();
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Fortran_Array2D<T> C(m,n);
|
||||||
|
|
||||||
|
for (int i=1; i<=m; i++)
|
||||||
|
{
|
||||||
|
for (int j=1; j<=n; j++)
|
||||||
|
C(i,j) = A(i,j) - B(i,j);
|
||||||
|
}
|
||||||
|
return C;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array2D<T> operator*(const Fortran_Array2D<T> &A, const Fortran_Array2D<T> &B)
|
||||||
|
{
|
||||||
|
int m = A.dim1();
|
||||||
|
int n = A.dim2();
|
||||||
|
|
||||||
|
if (B.dim1() != m || B.dim2() != n )
|
||||||
|
return Fortran_Array2D<T>();
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Fortran_Array2D<T> C(m,n);
|
||||||
|
|
||||||
|
for (int i=1; i<=m; i++)
|
||||||
|
{
|
||||||
|
for (int j=1; j<=n; j++)
|
||||||
|
C(i,j) = A(i,j) * B(i,j);
|
||||||
|
}
|
||||||
|
return C;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array2D<T> operator/(const Fortran_Array2D<T> &A, const Fortran_Array2D<T> &B)
|
||||||
|
{
|
||||||
|
int m = A.dim1();
|
||||||
|
int n = A.dim2();
|
||||||
|
|
||||||
|
if (B.dim1() != m || B.dim2() != n )
|
||||||
|
return Fortran_Array2D<T>();
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Fortran_Array2D<T> C(m,n);
|
||||||
|
|
||||||
|
for (int i=1; i<=m; i++)
|
||||||
|
{
|
||||||
|
for (int j=1; j<=n; j++)
|
||||||
|
C(i,j) = A(i,j) / B(i,j);
|
||||||
|
}
|
||||||
|
return C;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array2D<T>& operator+=(Fortran_Array2D<T> &A, const Fortran_Array2D<T> &B)
|
||||||
|
{
|
||||||
|
int m = A.dim1();
|
||||||
|
int n = A.dim2();
|
||||||
|
|
||||||
|
if (B.dim1() == m || B.dim2() == n )
|
||||||
|
{
|
||||||
|
for (int i=1; i<=m; i++)
|
||||||
|
{
|
||||||
|
for (int j=1; j<=n; j++)
|
||||||
|
A(i,j) += B(i,j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return A;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array2D<T>& operator-=(Fortran_Array2D<T> &A, const Fortran_Array2D<T> &B)
|
||||||
|
{
|
||||||
|
int m = A.dim1();
|
||||||
|
int n = A.dim2();
|
||||||
|
|
||||||
|
if (B.dim1() == m || B.dim2() == n )
|
||||||
|
{
|
||||||
|
for (int i=1; i<=m; i++)
|
||||||
|
{
|
||||||
|
for (int j=1; j<=n; j++)
|
||||||
|
A(i,j) -= B(i,j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return A;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array2D<T>& operator*=(Fortran_Array2D<T> &A, const Fortran_Array2D<T> &B)
|
||||||
|
{
|
||||||
|
int m = A.dim1();
|
||||||
|
int n = A.dim2();
|
||||||
|
|
||||||
|
if (B.dim1() == m || B.dim2() == n )
|
||||||
|
{
|
||||||
|
for (int i=1; i<=m; i++)
|
||||||
|
{
|
||||||
|
for (int j=1; j<=n; j++)
|
||||||
|
A(i,j) *= B(i,j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return A;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array2D<T>& operator/=(Fortran_Array2D<T> &A, const Fortran_Array2D<T> &B)
|
||||||
|
{
|
||||||
|
int m = A.dim1();
|
||||||
|
int n = A.dim2();
|
||||||
|
|
||||||
|
if (B.dim1() == m || B.dim2() == n )
|
||||||
|
{
|
||||||
|
for (int i=1; i<=m; i++)
|
||||||
|
{
|
||||||
|
for (int j=1; j<=n; j++)
|
||||||
|
A(i,j) /= B(i,j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return A;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace TNT
|
||||||
|
|
||||||
|
#endif
|
||||||
223
intern/smoke/intern/tnt/tnt_fortran_array3d.h
Normal file
223
intern/smoke/intern/tnt/tnt_fortran_array3d.h
Normal file
@@ -0,0 +1,223 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Template Numerical Toolkit (TNT): Three-dimensional Fortran numerical array
|
||||||
|
*
|
||||||
|
* Mathematical and Computational Sciences Division
|
||||||
|
* National Institute of Technology,
|
||||||
|
* Gaithersburg, MD USA
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* This software was developed at the National Institute of Standards and
|
||||||
|
* Technology (NIST) by employees of the Federal Government in the course
|
||||||
|
* of their official duties. Pursuant to title 17 Section 105 of the
|
||||||
|
* United States Code, this software is not subject to copyright protection
|
||||||
|
* and is in the public domain. NIST assumes no responsibility whatsoever for
|
||||||
|
* its use by other parties, and makes no guarantees, expressed or implied,
|
||||||
|
* about its quality, reliability, or any other characteristic.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TNT_FORTRAN_ARRAY3D_H
|
||||||
|
#define TNT_FORTRAN_ARRAY3D_H
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <iostream>
|
||||||
|
#ifdef TNT_BOUNDS_CHECK
|
||||||
|
#include <assert.h>
|
||||||
|
#endif
|
||||||
|
#include "tnt_i_refvec.h"
|
||||||
|
|
||||||
|
namespace TNT
|
||||||
|
{
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
class Fortran_Array3D
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
|
||||||
|
i_refvec<T> v_;
|
||||||
|
int m_;
|
||||||
|
int n_;
|
||||||
|
int k_;
|
||||||
|
T* data_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef T value_type;
|
||||||
|
|
||||||
|
Fortran_Array3D();
|
||||||
|
Fortran_Array3D(int m, int n, int k);
|
||||||
|
Fortran_Array3D(int m, int n, int k, T *a);
|
||||||
|
Fortran_Array3D(int m, int n, int k, const T &a);
|
||||||
|
inline Fortran_Array3D(const Fortran_Array3D &A);
|
||||||
|
inline Fortran_Array3D & operator=(const T &a);
|
||||||
|
inline Fortran_Array3D & operator=(const Fortran_Array3D &A);
|
||||||
|
inline Fortran_Array3D & ref(const Fortran_Array3D &A);
|
||||||
|
Fortran_Array3D copy() const;
|
||||||
|
Fortran_Array3D & inject(const Fortran_Array3D & A);
|
||||||
|
inline T& operator()(int i, int j, int k);
|
||||||
|
inline const T& operator()(int i, int j, int k) const ;
|
||||||
|
inline int dim1() const;
|
||||||
|
inline int dim2() const;
|
||||||
|
inline int dim3() const;
|
||||||
|
inline int ref_count() const;
|
||||||
|
~Fortran_Array3D();
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array3D<T>::Fortran_Array3D() : v_(), m_(0), n_(0), k_(0), data_(0) {}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array3D<T>::Fortran_Array3D(const Fortran_Array3D<T> &A) :
|
||||||
|
v_(A.v_), m_(A.m_), n_(A.n_), k_(A.k_), data_(A.data_) {}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array3D<T>::Fortran_Array3D(int m, int n, int k) :
|
||||||
|
v_(m*n*k), m_(m), n_(n), k_(k), data_(v_.begin()) {}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array3D<T>::Fortran_Array3D(int m, int n, int k, const T &val) :
|
||||||
|
v_(m*n*k), m_(m), n_(n), k_(k), data_(v_.begin())
|
||||||
|
{
|
||||||
|
for (T* p = data_; p < data_ + m*n*k; p++)
|
||||||
|
*p = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array3D<T>::Fortran_Array3D(int m, int n, int k, T *a) :
|
||||||
|
v_(a), m_(m), n_(n), k_(k), data_(v_.begin()) {}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline T& Fortran_Array3D<T>::operator()(int i, int j, int k)
|
||||||
|
{
|
||||||
|
#ifdef TNT_BOUNDS_CHECK
|
||||||
|
assert(i >= 1);
|
||||||
|
assert(i <= m_);
|
||||||
|
assert(j >= 1);
|
||||||
|
assert(j <= n_);
|
||||||
|
assert(k >= 1);
|
||||||
|
assert(k <= k_);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return data_[(k-1)*m_*n_ + (j-1) * m_ + i-1];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline const T& Fortran_Array3D<T>::operator()(int i, int j, int k) const
|
||||||
|
{
|
||||||
|
#ifdef TNT_BOUNDS_CHECK
|
||||||
|
assert(i >= 1);
|
||||||
|
assert(i <= m_);
|
||||||
|
assert(j >= 1);
|
||||||
|
assert(j <= n_);
|
||||||
|
assert(k >= 1);
|
||||||
|
assert(k <= k_);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return data_[(k-1)*m_*n_ + (j-1) * m_ + i-1];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array3D<T> & Fortran_Array3D<T>::operator=(const T &a)
|
||||||
|
{
|
||||||
|
|
||||||
|
T *end = data_ + m_*n_*k_;
|
||||||
|
|
||||||
|
for (T *p=data_; p != end; *p++ = a);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array3D<T> Fortran_Array3D<T>::copy() const
|
||||||
|
{
|
||||||
|
|
||||||
|
Fortran_Array3D B(m_, n_, k_);
|
||||||
|
B.inject(*this);
|
||||||
|
return B;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array3D<T> & Fortran_Array3D<T>::inject(const Fortran_Array3D &A)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (m_ == A.m_ && n_ == A.n_ && k_ == A.k_)
|
||||||
|
{
|
||||||
|
T *p = data_;
|
||||||
|
T *end = data_ + m_*n_*k_;
|
||||||
|
const T* q = A.data_;
|
||||||
|
for (; p < end; *p++ = *q++);
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array3D<T> & Fortran_Array3D<T>::ref(const Fortran_Array3D<T> &A)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (this != &A)
|
||||||
|
{
|
||||||
|
v_ = A.v_;
|
||||||
|
m_ = A.m_;
|
||||||
|
n_ = A.n_;
|
||||||
|
k_ = A.k_;
|
||||||
|
data_ = A.data_;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array3D<T> & Fortran_Array3D<T>::operator=(const Fortran_Array3D<T> &A)
|
||||||
|
{
|
||||||
|
return ref(A);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline int Fortran_Array3D<T>::dim1() const { return m_; }
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline int Fortran_Array3D<T>::dim2() const { return n_; }
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline int Fortran_Array3D<T>::dim3() const { return k_; }
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline int Fortran_Array3D<T>::ref_count() const
|
||||||
|
{
|
||||||
|
return v_.ref_count();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array3D<T>::~Fortran_Array3D()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} /* namespace TNT */
|
||||||
|
|
||||||
|
#endif
|
||||||
|
/* TNT_FORTRAN_ARRAY3D_H */
|
||||||
|
|
||||||
249
intern/smoke/intern/tnt/tnt_fortran_array3d_utils.h
Normal file
249
intern/smoke/intern/tnt/tnt_fortran_array3d_utils.h
Normal file
@@ -0,0 +1,249 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Template Numerical Toolkit (TNT)
|
||||||
|
*
|
||||||
|
* Mathematical and Computational Sciences Division
|
||||||
|
* National Institute of Technology,
|
||||||
|
* Gaithersburg, MD USA
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* This software was developed at the National Institute of Standards and
|
||||||
|
* Technology (NIST) by employees of the Federal Government in the course
|
||||||
|
* of their official duties. Pursuant to title 17 Section 105 of the
|
||||||
|
* United States Code, this software is not subject to copyright protection
|
||||||
|
* and is in the public domain. NIST assumes no responsibility whatsoever for
|
||||||
|
* its use by other parties, and makes no guarantees, expressed or implied,
|
||||||
|
* about its quality, reliability, or any other characteristic.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TNT_FORTRAN_ARRAY3D_UTILS_H
|
||||||
|
#define TNT_FORTRAN_ARRAY3D_UTILS_H
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
namespace TNT
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
std::ostream& operator<<(std::ostream &s, const Fortran_Array3D<T> &A)
|
||||||
|
{
|
||||||
|
int M=A.dim1();
|
||||||
|
int N=A.dim2();
|
||||||
|
int K=A.dim3();
|
||||||
|
|
||||||
|
s << M << " " << N << " " << K << "\n";
|
||||||
|
|
||||||
|
for (int i=1; i<=M; i++)
|
||||||
|
{
|
||||||
|
for (int j=1; j<=N; j++)
|
||||||
|
{
|
||||||
|
for (int k=1; k<=K; k++)
|
||||||
|
s << A(i,j,k) << " ";
|
||||||
|
s << "\n";
|
||||||
|
}
|
||||||
|
s << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
std::istream& operator>>(std::istream &s, Fortran_Array3D<T> &A)
|
||||||
|
{
|
||||||
|
|
||||||
|
int M, N, K;
|
||||||
|
|
||||||
|
s >> M >> N >> K;
|
||||||
|
|
||||||
|
Fortran_Array3D<T> B(M,N,K);
|
||||||
|
|
||||||
|
for (int i=1; i<=M; i++)
|
||||||
|
for (int j=1; j<=N; j++)
|
||||||
|
for (int k=1; k<=K; k++)
|
||||||
|
s >> B(i,j,k);
|
||||||
|
|
||||||
|
A = B;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array3D<T> operator+(const Fortran_Array3D<T> &A, const Fortran_Array3D<T> &B)
|
||||||
|
{
|
||||||
|
int m = A.dim1();
|
||||||
|
int n = A.dim2();
|
||||||
|
int p = A.dim3();
|
||||||
|
|
||||||
|
if (B.dim1() != m || B.dim2() != n || B.dim3() != p )
|
||||||
|
return Fortran_Array3D<T>();
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Fortran_Array3D<T> C(m,n,p);
|
||||||
|
|
||||||
|
for (int i=1; i<=m; i++)
|
||||||
|
for (int j=1; j<=n; j++)
|
||||||
|
for (int k=1; k<=p; k++)
|
||||||
|
C(i,j,k) = A(i,j,k)+ B(i,j,k);
|
||||||
|
|
||||||
|
return C;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array3D<T> operator-(const Fortran_Array3D<T> &A, const Fortran_Array3D<T> &B)
|
||||||
|
{
|
||||||
|
int m = A.dim1();
|
||||||
|
int n = A.dim2();
|
||||||
|
int p = A.dim3();
|
||||||
|
|
||||||
|
if (B.dim1() != m || B.dim2() != n || B.dim3() != p )
|
||||||
|
return Fortran_Array3D<T>();
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Fortran_Array3D<T> C(m,n,p);
|
||||||
|
|
||||||
|
for (int i=1; i<=m; i++)
|
||||||
|
for (int j=1; j<=n; j++)
|
||||||
|
for (int k=1; k<=p; k++)
|
||||||
|
C(i,j,k) = A(i,j,k)- B(i,j,k);
|
||||||
|
|
||||||
|
return C;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array3D<T> operator*(const Fortran_Array3D<T> &A, const Fortran_Array3D<T> &B)
|
||||||
|
{
|
||||||
|
int m = A.dim1();
|
||||||
|
int n = A.dim2();
|
||||||
|
int p = A.dim3();
|
||||||
|
|
||||||
|
if (B.dim1() != m || B.dim2() != n || B.dim3() != p )
|
||||||
|
return Fortran_Array3D<T>();
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Fortran_Array3D<T> C(m,n,p);
|
||||||
|
|
||||||
|
for (int i=1; i<=m; i++)
|
||||||
|
for (int j=1; j<=n; j++)
|
||||||
|
for (int k=1; k<=p; k++)
|
||||||
|
C(i,j,k) = A(i,j,k)* B(i,j,k);
|
||||||
|
|
||||||
|
return C;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array3D<T> operator/(const Fortran_Array3D<T> &A, const Fortran_Array3D<T> &B)
|
||||||
|
{
|
||||||
|
int m = A.dim1();
|
||||||
|
int n = A.dim2();
|
||||||
|
int p = A.dim3();
|
||||||
|
|
||||||
|
if (B.dim1() != m || B.dim2() != n || B.dim3() != p )
|
||||||
|
return Fortran_Array3D<T>();
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Fortran_Array3D<T> C(m,n,p);
|
||||||
|
|
||||||
|
for (int i=1; i<=m; i++)
|
||||||
|
for (int j=1; j<=n; j++)
|
||||||
|
for (int k=1; k<=p; k++)
|
||||||
|
C(i,j,k) = A(i,j,k)/ B(i,j,k);
|
||||||
|
|
||||||
|
return C;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array3D<T>& operator+=(Fortran_Array3D<T> &A, const Fortran_Array3D<T> &B)
|
||||||
|
{
|
||||||
|
int m = A.dim1();
|
||||||
|
int n = A.dim2();
|
||||||
|
int p = A.dim3();
|
||||||
|
|
||||||
|
if (B.dim1() == m && B.dim2() == n && B.dim3() == p )
|
||||||
|
{
|
||||||
|
for (int i=1; i<=m; i++)
|
||||||
|
for (int j=1; j<=n; j++)
|
||||||
|
for (int k=1; k<=p; k++)
|
||||||
|
A(i,j,k) += B(i,j,k);
|
||||||
|
}
|
||||||
|
|
||||||
|
return A;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array3D<T>& operator-=(Fortran_Array3D<T> &A, const Fortran_Array3D<T> &B)
|
||||||
|
{
|
||||||
|
int m = A.dim1();
|
||||||
|
int n = A.dim2();
|
||||||
|
int p = A.dim3();
|
||||||
|
|
||||||
|
if (B.dim1() == m && B.dim2() == n && B.dim3() == p )
|
||||||
|
{
|
||||||
|
for (int i=1; i<=m; i++)
|
||||||
|
for (int j=1; j<=n; j++)
|
||||||
|
for (int k=1; k<=p; k++)
|
||||||
|
A(i,j,k) -= B(i,j,k);
|
||||||
|
}
|
||||||
|
|
||||||
|
return A;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array3D<T>& operator*=(Fortran_Array3D<T> &A, const Fortran_Array3D<T> &B)
|
||||||
|
{
|
||||||
|
int m = A.dim1();
|
||||||
|
int n = A.dim2();
|
||||||
|
int p = A.dim3();
|
||||||
|
|
||||||
|
if (B.dim1() == m && B.dim2() == n && B.dim3() == p )
|
||||||
|
{
|
||||||
|
for (int i=1; i<=m; i++)
|
||||||
|
for (int j=1; j<=n; j++)
|
||||||
|
for (int k=1; k<=p; k++)
|
||||||
|
A(i,j,k) *= B(i,j,k);
|
||||||
|
}
|
||||||
|
|
||||||
|
return A;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Fortran_Array3D<T>& operator/=(Fortran_Array3D<T> &A, const Fortran_Array3D<T> &B)
|
||||||
|
{
|
||||||
|
int m = A.dim1();
|
||||||
|
int n = A.dim2();
|
||||||
|
int p = A.dim3();
|
||||||
|
|
||||||
|
if (B.dim1() == m && B.dim2() == n && B.dim3() == p )
|
||||||
|
{
|
||||||
|
for (int i=1; i<=m; i++)
|
||||||
|
for (int j=1; j<=n; j++)
|
||||||
|
for (int k=1; k<=p; k++)
|
||||||
|
A(i,j,k) /= B(i,j,k);
|
||||||
|
}
|
||||||
|
|
||||||
|
return A;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace TNT
|
||||||
|
|
||||||
|
#endif
|
||||||
243
intern/smoke/intern/tnt/tnt_i_refvec.h
Normal file
243
intern/smoke/intern/tnt/tnt_i_refvec.h
Normal file
@@ -0,0 +1,243 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Template Numerical Toolkit (TNT)
|
||||||
|
*
|
||||||
|
* Mathematical and Computational Sciences Division
|
||||||
|
* National Institute of Technology,
|
||||||
|
* Gaithersburg, MD USA
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* This software was developed at the National Institute of Standards and
|
||||||
|
* Technology (NIST) by employees of the Federal Government in the course
|
||||||
|
* of their official duties. Pursuant to title 17 Section 105 of the
|
||||||
|
* United States Code, this software is not subject to copyright protection
|
||||||
|
* and is in the public domain. NIST assumes no responsibility whatsoever for
|
||||||
|
* its use by other parties, and makes no guarantees, expressed or implied,
|
||||||
|
* about its quality, reliability, or any other characteristic.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TNT_I_REFVEC_H
|
||||||
|
#define TNT_I_REFVEC_H
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#ifdef TNT_BOUNDS_CHECK
|
||||||
|
#include <assert.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NULL
|
||||||
|
#define NULL 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace TNT
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Internal representation of ref-counted array. The TNT
|
||||||
|
arrays all use this building block.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
If an array block is created by TNT, then every time
|
||||||
|
an assignment is made, the left-hand-side reference
|
||||||
|
is decreased by one, and the right-hand-side refernce
|
||||||
|
count is increased by one. If the array block was
|
||||||
|
external to TNT, the refernce count is a NULL pointer
|
||||||
|
regardless of how many references are made, since the
|
||||||
|
memory is not freed by TNT.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
|
template <class T>
|
||||||
|
class i_refvec
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
T* data_;
|
||||||
|
int *ref_count_;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
i_refvec();
|
||||||
|
explicit i_refvec(int n);
|
||||||
|
inline i_refvec(T* data);
|
||||||
|
inline i_refvec(const i_refvec &v);
|
||||||
|
inline T* begin();
|
||||||
|
inline const T* begin() const;
|
||||||
|
inline T& operator[](int i);
|
||||||
|
inline const T& operator[](int i) const;
|
||||||
|
inline i_refvec<T> & operator=(const i_refvec<T> &V);
|
||||||
|
void copy_(T* p, const T* q, const T* e);
|
||||||
|
void set_(T* p, const T* b, const T* e);
|
||||||
|
inline int ref_count() const;
|
||||||
|
inline int is_null() const;
|
||||||
|
inline void destroy();
|
||||||
|
~i_refvec();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void i_refvec<T>::copy_(T* p, const T* q, const T* e)
|
||||||
|
{
|
||||||
|
for (T* t=p; q<e; t++, q++)
|
||||||
|
*t= *q;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
i_refvec<T>::i_refvec() : data_(NULL), ref_count_(NULL) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
In case n is 0 or negative, it does NOT call new.
|
||||||
|
*/
|
||||||
|
template <class T>
|
||||||
|
i_refvec<T>::i_refvec(int n) : data_(NULL), ref_count_(NULL)
|
||||||
|
{
|
||||||
|
if (n >= 1)
|
||||||
|
{
|
||||||
|
#ifdef TNT_DEBUG
|
||||||
|
std::cout << "new data storage.\n";
|
||||||
|
#endif
|
||||||
|
data_ = new T[n];
|
||||||
|
ref_count_ = new int;
|
||||||
|
*ref_count_ = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline i_refvec<T>::i_refvec(const i_refvec<T> &V): data_(V.data_),
|
||||||
|
ref_count_(V.ref_count_)
|
||||||
|
{
|
||||||
|
if (V.ref_count_ != NULL)
|
||||||
|
(*(V.ref_count_))++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
i_refvec<T>::i_refvec(T* data) : data_(data), ref_count_(NULL) {}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline T* i_refvec<T>::begin()
|
||||||
|
{
|
||||||
|
return data_;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline const T& i_refvec<T>::operator[](int i) const
|
||||||
|
{
|
||||||
|
return data_[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline T& i_refvec<T>::operator[](int i)
|
||||||
|
{
|
||||||
|
return data_[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline const T* i_refvec<T>::begin() const
|
||||||
|
{
|
||||||
|
return data_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
i_refvec<T> & i_refvec<T>::operator=(const i_refvec<T> &V)
|
||||||
|
{
|
||||||
|
if (this == &V)
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
|
||||||
|
if (ref_count_ != NULL)
|
||||||
|
{
|
||||||
|
(*ref_count_) --;
|
||||||
|
if ((*ref_count_) == 0)
|
||||||
|
destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
data_ = V.data_;
|
||||||
|
ref_count_ = V.ref_count_;
|
||||||
|
|
||||||
|
if (V.ref_count_ != NULL)
|
||||||
|
(*(V.ref_count_))++;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void i_refvec<T>::destroy()
|
||||||
|
{
|
||||||
|
if (ref_count_ != NULL)
|
||||||
|
{
|
||||||
|
#ifdef TNT_DEBUG
|
||||||
|
std::cout << "destorying data... \n";
|
||||||
|
#endif
|
||||||
|
delete ref_count_;
|
||||||
|
|
||||||
|
#ifdef TNT_DEBUG
|
||||||
|
std::cout << "deleted ref_count_ ...\n";
|
||||||
|
#endif
|
||||||
|
if (data_ != NULL)
|
||||||
|
delete []data_;
|
||||||
|
#ifdef TNT_DEBUG
|
||||||
|
std::cout << "deleted data_[] ...\n";
|
||||||
|
#endif
|
||||||
|
data_ = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* return 1 is vector is empty, 0 otherwise
|
||||||
|
*
|
||||||
|
* if is_null() is false and ref_count() is 0, then
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
template<class T>
|
||||||
|
int i_refvec<T>::is_null() const
|
||||||
|
{
|
||||||
|
return (data_ == NULL ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* returns -1 if data is external,
|
||||||
|
* returns 0 if a is NULL array,
|
||||||
|
* otherwise returns the positive number of vectors sharing
|
||||||
|
* this data space.
|
||||||
|
*/
|
||||||
|
template <class T>
|
||||||
|
int i_refvec<T>::ref_count() const
|
||||||
|
{
|
||||||
|
if (data_ == NULL)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return (ref_count_ != NULL ? *ref_count_ : -1) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
i_refvec<T>::~i_refvec()
|
||||||
|
{
|
||||||
|
if (ref_count_ != NULL)
|
||||||
|
{
|
||||||
|
(*ref_count_)--;
|
||||||
|
|
||||||
|
if (*ref_count_ == 0)
|
||||||
|
destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} /* namespace TNT */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
/* TNT_I_REFVEC_H */
|
||||||
|
|
||||||
34
intern/smoke/intern/tnt/tnt_math_utils.h
Normal file
34
intern/smoke/intern/tnt/tnt_math_utils.h
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
#ifndef MATH_UTILS_H
|
||||||
|
#define MATH_UTILS_H
|
||||||
|
|
||||||
|
/* needed for fabs, sqrt() below */
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace TNT
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
@returns hypotenuse of real (non-complex) scalars a and b by
|
||||||
|
avoiding underflow/overflow
|
||||||
|
using (a * sqrt( 1 + (b/a) * (b/a))), rather than
|
||||||
|
sqrt(a*a + b*b).
|
||||||
|
*/
|
||||||
|
template <class Real>
|
||||||
|
Real hypot(const Real &a, const Real &b)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (a== 0)
|
||||||
|
return fabs(b);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Real c = b/a;
|
||||||
|
return fabs(a) * sqrt(1 + c*c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} /* TNT namespace */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
/* MATH_UTILS_H */
|
||||||
103
intern/smoke/intern/tnt/tnt_sparse_matrix_csr.h
Normal file
103
intern/smoke/intern/tnt/tnt_sparse_matrix_csr.h
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Template Numerical Toolkit (TNT)
|
||||||
|
*
|
||||||
|
* Mathematical and Computational Sciences Division
|
||||||
|
* National Institute of Technology,
|
||||||
|
* Gaithersburg, MD USA
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* This software was developed at the National Institute of Standards and
|
||||||
|
* Technology (NIST) by employees of the Federal Government in the course
|
||||||
|
* of their official duties. Pursuant to title 17 Section 105 of the
|
||||||
|
* United States Code, this software is not subject to copyright protection
|
||||||
|
* and is in the public domain. NIST assumes no responsibility whatsoever for
|
||||||
|
* its use by other parties, and makes no guarantees, expressed or implied,
|
||||||
|
* about its quality, reliability, or any other characteristic.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TNT_SPARSE_MATRIX_CSR_H
|
||||||
|
#define TNT_SPARSE_MATRIX_CSR_H
|
||||||
|
|
||||||
|
#include "tnt_array1d.h"
|
||||||
|
|
||||||
|
namespace TNT
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Read-only view of a sparse matrix in compressed-row storage
|
||||||
|
format. Neither array elements (nonzeros) nor sparsity
|
||||||
|
structure can be modified. If modifications are required,
|
||||||
|
create a new view.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Index values begin at 0.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<b>Storage requirements:</b> An (m x n) matrix with
|
||||||
|
nz nonzeros requires no more than ((T+I)*nz + M*I)
|
||||||
|
bytes, where T is the size of data elements and
|
||||||
|
I is the size of integers.
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
|
template <class T>
|
||||||
|
class Sparse_Matrix_CompRow {
|
||||||
|
|
||||||
|
private:
|
||||||
|
Array1D<T> val_; // data values (nz_ elements)
|
||||||
|
Array1D<int> rowptr_; // row_ptr (dim_[0]+1 elements)
|
||||||
|
Array1D<int> colind_; // col_ind (nz_ elements)
|
||||||
|
|
||||||
|
int dim1_; // number of rows
|
||||||
|
int dim2_; // number of cols
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Sparse_Matrix_CompRow(const Sparse_Matrix_CompRow &S);
|
||||||
|
Sparse_Matrix_CompRow(int M, int N, int nz, const T *val,
|
||||||
|
const int *r, const int *c);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline const T& val(int i) const { return val_[i]; }
|
||||||
|
inline const int& row_ptr(int i) const { return rowptr_[i]; }
|
||||||
|
inline const int& col_ind(int i) const { return colind_[i];}
|
||||||
|
|
||||||
|
inline int dim1() const {return dim1_;}
|
||||||
|
inline int dim2() const {return dim2_;}
|
||||||
|
int NumNonzeros() const {return val_.dim1();}
|
||||||
|
|
||||||
|
|
||||||
|
Sparse_Matrix_CompRow& operator=(
|
||||||
|
const Sparse_Matrix_CompRow &R);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Construct a read-only view of existing sparse matrix in
|
||||||
|
compressed-row storage format.
|
||||||
|
|
||||||
|
@param M the number of rows of sparse matrix
|
||||||
|
@param N the number of columns of sparse matrix
|
||||||
|
@param nz the number of nonzeros
|
||||||
|
@param val a contiguous list of nonzero values
|
||||||
|
@param r row-pointers: r[i] denotes the begining position of row i
|
||||||
|
(i.e. the ith row begins at val[row[i]]).
|
||||||
|
@param c column-indices: c[i] denotes the column location of val[i]
|
||||||
|
*/
|
||||||
|
template <class T>
|
||||||
|
Sparse_Matrix_CompRow<T>::Sparse_Matrix_CompRow(int M, int N, int nz,
|
||||||
|
const T *val, const int *r, const int *c) : val_(nz,val),
|
||||||
|
rowptr_(M, r), colind_(nz, c), dim1_(M), dim2_(N) {}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
// namespace TNT
|
||||||
|
|
||||||
|
#endif
|
||||||
95
intern/smoke/intern/tnt/tnt_stopwatch.h
Normal file
95
intern/smoke/intern/tnt/tnt_stopwatch.h
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Mathematical and Computational Sciences Division
|
||||||
|
* National Institute of Technology,
|
||||||
|
* Gaithersburg, MD USA
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* This software was developed at the National Institute of Standards and
|
||||||
|
* Technology (NIST) by employees of the Federal Government in the course
|
||||||
|
* of their official duties. Pursuant to title 17 Section 105 of the
|
||||||
|
* United States Code, this software is not subject to copyright protection
|
||||||
|
* and is in the public domain. NIST assumes no responsibility whatsoever for
|
||||||
|
* its use by other parties, and makes no guarantees, expressed or implied,
|
||||||
|
* about its quality, reliability, or any other characteristic.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef STOPWATCH_H
|
||||||
|
#define STOPWATCH_H
|
||||||
|
|
||||||
|
// for clock() and CLOCKS_PER_SEC
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace TNT
|
||||||
|
{
|
||||||
|
|
||||||
|
inline static double seconds(void)
|
||||||
|
{
|
||||||
|
const double secs_per_tick = 1.0 / CLOCKS_PER_SEC;
|
||||||
|
return ( (double) clock() ) * secs_per_tick;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Stopwatch {
|
||||||
|
private:
|
||||||
|
int running_;
|
||||||
|
double start_time_;
|
||||||
|
double total_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
inline Stopwatch();
|
||||||
|
inline void start();
|
||||||
|
inline double stop();
|
||||||
|
inline double read();
|
||||||
|
inline void resume();
|
||||||
|
inline int running();
|
||||||
|
};
|
||||||
|
|
||||||
|
inline Stopwatch::Stopwatch() : running_(0), start_time_(0.0), total_(0.0) {}
|
||||||
|
|
||||||
|
void Stopwatch::start()
|
||||||
|
{
|
||||||
|
running_ = 1;
|
||||||
|
total_ = 0.0;
|
||||||
|
start_time_ = seconds();
|
||||||
|
}
|
||||||
|
|
||||||
|
double Stopwatch::stop()
|
||||||
|
{
|
||||||
|
if (running_)
|
||||||
|
{
|
||||||
|
total_ += (seconds() - start_time_);
|
||||||
|
running_ = 0;
|
||||||
|
}
|
||||||
|
return total_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Stopwatch::resume()
|
||||||
|
{
|
||||||
|
if (!running_)
|
||||||
|
{
|
||||||
|
start_time_ = seconds();
|
||||||
|
running_ = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline double Stopwatch::read()
|
||||||
|
{
|
||||||
|
if (running_)
|
||||||
|
{
|
||||||
|
stop();
|
||||||
|
resume();
|
||||||
|
}
|
||||||
|
return total_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} /* TNT namespace */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
54
intern/smoke/intern/tnt/tnt_subscript.h
Normal file
54
intern/smoke/intern/tnt/tnt_subscript.h
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Template Numerical Toolkit (TNT)
|
||||||
|
*
|
||||||
|
* Mathematical and Computational Sciences Division
|
||||||
|
* National Institute of Technology,
|
||||||
|
* Gaithersburg, MD USA
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* This software was developed at the National Institute of Standards and
|
||||||
|
* Technology (NIST) by employees of the Federal Government in the course
|
||||||
|
* of their official duties. Pursuant to title 17 Section 105 of the
|
||||||
|
* United States Code, this software is not subject to copyright protection
|
||||||
|
* and is in the public domain. NIST assumes no responsibility whatsoever for
|
||||||
|
* its use by other parties, and makes no guarantees, expressed or implied,
|
||||||
|
* about its quality, reliability, or any other characteristic.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TNT_SUBSCRPT_H
|
||||||
|
#define TNT_SUBSCRPT_H
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// This definition describes the default TNT data type used for
|
||||||
|
// indexing into TNT matrices and vectors. The data type should
|
||||||
|
// be wide enough to index into large arrays. It defaults to an
|
||||||
|
// "int", but can be overriden at compile time redefining TNT_SUBSCRIPT_TYPE,
|
||||||
|
// e.g.
|
||||||
|
//
|
||||||
|
// c++ -DTNT_SUBSCRIPT_TYPE='unsigned int' ...
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef TNT_SUBSCRIPT_TYPE
|
||||||
|
#define TNT_SUBSCRIPT_TYPE int
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace TNT
|
||||||
|
{
|
||||||
|
typedef TNT_SUBSCRIPT_TYPE Subscript;
|
||||||
|
} /* namespace TNT */
|
||||||
|
|
||||||
|
|
||||||
|
// () indexing in TNT means 1-offset, i.e. x(1) and A(1,1) are the
|
||||||
|
// first elements. This offset is left as a macro for future
|
||||||
|
// purposes, but should not be changed in the current release.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
#define TNT_BASE_OFFSET (1)
|
||||||
|
|
||||||
|
#endif
|
||||||
404
intern/smoke/intern/tnt/tnt_vec.h
Normal file
404
intern/smoke/intern/tnt/tnt_vec.h
Normal file
@@ -0,0 +1,404 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Template Numerical Toolkit (TNT)
|
||||||
|
*
|
||||||
|
* Mathematical and Computational Sciences Division
|
||||||
|
* National Institute of Technology,
|
||||||
|
* Gaithersburg, MD USA
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* This software was developed at the National Institute of Standards and
|
||||||
|
* Technology (NIST) by employees of the Federal Government in the course
|
||||||
|
* of their official duties. Pursuant to title 17 Section 105 of the
|
||||||
|
* United States Code, this software is not subject to copyright protection
|
||||||
|
* and is in the public domain. NIST assumes no responsibility whatsoever for
|
||||||
|
* its use by other parties, and makes no guarantees, expressed or implied,
|
||||||
|
* about its quality, reliability, or any other characteristic.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TNT_VEC_H
|
||||||
|
#define TNT_VEC_H
|
||||||
|
|
||||||
|
#include "tnt_subscript.h"
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cassert>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
namespace TNT
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
<b>[Deprecatred]</b> Value-based vector class from pre-1.0
|
||||||
|
TNT version. Kept here for backward compatiblity, but should
|
||||||
|
use the newer TNT::Array1D classes instead.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
class Vector
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef Subscript size_type;
|
||||||
|
typedef T value_type;
|
||||||
|
typedef T element_type;
|
||||||
|
typedef T* pointer;
|
||||||
|
typedef T* iterator;
|
||||||
|
typedef T& reference;
|
||||||
|
typedef const T* const_iterator;
|
||||||
|
typedef const T& const_reference;
|
||||||
|
|
||||||
|
Subscript lbound() const { return 1;}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
T* v_;
|
||||||
|
T* vm1_; // pointer adjustment for optimzied 1-offset indexing
|
||||||
|
Subscript n_;
|
||||||
|
|
||||||
|
// internal helper function to create the array
|
||||||
|
// of row pointers
|
||||||
|
|
||||||
|
void initialize(Subscript N)
|
||||||
|
{
|
||||||
|
// adjust pointers so that they are 1-offset:
|
||||||
|
// v_[] is the internal contiguous array, it is still 0-offset
|
||||||
|
//
|
||||||
|
assert(v_ == NULL);
|
||||||
|
v_ = new T[N];
|
||||||
|
assert(v_ != NULL);
|
||||||
|
vm1_ = v_-1;
|
||||||
|
n_ = N;
|
||||||
|
}
|
||||||
|
|
||||||
|
void copy(const T* v)
|
||||||
|
{
|
||||||
|
Subscript N = n_;
|
||||||
|
Subscript i;
|
||||||
|
|
||||||
|
#ifdef TNT_UNROLL_LOOPS
|
||||||
|
Subscript Nmod4 = N & 3;
|
||||||
|
Subscript N4 = N - Nmod4;
|
||||||
|
|
||||||
|
for (i=0; i<N4; i+=4)
|
||||||
|
{
|
||||||
|
v_[i] = v[i];
|
||||||
|
v_[i+1] = v[i+1];
|
||||||
|
v_[i+2] = v[i+2];
|
||||||
|
v_[i+3] = v[i+3];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=N4; i< N; i++)
|
||||||
|
v_[i] = v[i];
|
||||||
|
#else
|
||||||
|
|
||||||
|
for (i=0; i< N; i++)
|
||||||
|
v_[i] = v[i];
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void set(const T& val)
|
||||||
|
{
|
||||||
|
Subscript N = n_;
|
||||||
|
Subscript i;
|
||||||
|
|
||||||
|
#ifdef TNT_UNROLL_LOOPS
|
||||||
|
Subscript Nmod4 = N & 3;
|
||||||
|
Subscript N4 = N - Nmod4;
|
||||||
|
|
||||||
|
for (i=0; i<N4; i+=4)
|
||||||
|
{
|
||||||
|
v_[i] = val;
|
||||||
|
v_[i+1] = val;
|
||||||
|
v_[i+2] = val;
|
||||||
|
v_[i+3] = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=N4; i< N; i++)
|
||||||
|
v_[i] = val;
|
||||||
|
#else
|
||||||
|
|
||||||
|
for (i=0; i< N; i++)
|
||||||
|
v_[i] = val;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void destroy()
|
||||||
|
{
|
||||||
|
/* do nothing, if no memory has been previously allocated */
|
||||||
|
if (v_ == NULL) return ;
|
||||||
|
|
||||||
|
/* if we are here, then matrix was previously allocated */
|
||||||
|
delete [] (v_);
|
||||||
|
|
||||||
|
v_ = NULL;
|
||||||
|
vm1_ = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// access
|
||||||
|
|
||||||
|
iterator begin() { return v_;}
|
||||||
|
iterator end() { return v_ + n_; }
|
||||||
|
iterator begin() const { return v_;}
|
||||||
|
iterator end() const { return v_ + n_; }
|
||||||
|
|
||||||
|
// destructor
|
||||||
|
|
||||||
|
~Vector()
|
||||||
|
{
|
||||||
|
destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
// constructors
|
||||||
|
|
||||||
|
Vector() : v_(0), vm1_(0), n_(0) {};
|
||||||
|
|
||||||
|
Vector(const Vector<T> &A) : v_(0), vm1_(0), n_(0)
|
||||||
|
{
|
||||||
|
initialize(A.n_);
|
||||||
|
copy(A.v_);
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector(Subscript N, const T& value = T()) : v_(0), vm1_(0), n_(0)
|
||||||
|
{
|
||||||
|
initialize(N);
|
||||||
|
set(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector(Subscript N, const T* v) : v_(0), vm1_(0), n_(0)
|
||||||
|
{
|
||||||
|
initialize(N);
|
||||||
|
copy(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector(Subscript N, char *s) : v_(0), vm1_(0), n_(0)
|
||||||
|
{
|
||||||
|
initialize(N);
|
||||||
|
std::istringstream ins(s);
|
||||||
|
|
||||||
|
Subscript i;
|
||||||
|
|
||||||
|
for (i=0; i<N; i++)
|
||||||
|
ins >> v_[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// methods
|
||||||
|
//
|
||||||
|
Vector<T>& newsize(Subscript N)
|
||||||
|
{
|
||||||
|
if (n_ == N) return *this;
|
||||||
|
|
||||||
|
destroy();
|
||||||
|
initialize(N);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// assignments
|
||||||
|
//
|
||||||
|
Vector<T>& operator=(const Vector<T> &A)
|
||||||
|
{
|
||||||
|
if (v_ == A.v_)
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
if (n_ == A.n_) // no need to re-alloc
|
||||||
|
copy(A.v_);
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
destroy();
|
||||||
|
initialize(A.n_);
|
||||||
|
copy(A.v_);
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector<T>& operator=(const T& scalar)
|
||||||
|
{
|
||||||
|
set(scalar);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Subscript dim() const
|
||||||
|
{
|
||||||
|
return n_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Subscript size() const
|
||||||
|
{
|
||||||
|
return n_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline reference operator()(Subscript i)
|
||||||
|
{
|
||||||
|
#ifdef TNT_BOUNDS_CHECK
|
||||||
|
assert(1<=i);
|
||||||
|
assert(i <= n_) ;
|
||||||
|
#endif
|
||||||
|
return vm1_[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const_reference operator() (Subscript i) const
|
||||||
|
{
|
||||||
|
#ifdef TNT_BOUNDS_CHECK
|
||||||
|
assert(1<=i);
|
||||||
|
assert(i <= n_) ;
|
||||||
|
#endif
|
||||||
|
return vm1_[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline reference operator[](Subscript i)
|
||||||
|
{
|
||||||
|
#ifdef TNT_BOUNDS_CHECK
|
||||||
|
assert(0<=i);
|
||||||
|
assert(i < n_) ;
|
||||||
|
#endif
|
||||||
|
return v_[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const_reference operator[](Subscript i) const
|
||||||
|
{
|
||||||
|
#ifdef TNT_BOUNDS_CHECK
|
||||||
|
assert(0<=i);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
assert(i < n_) ;
|
||||||
|
#endif
|
||||||
|
return v_[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* *************************** I/O ********************************/
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
std::ostream& operator<<(std::ostream &s, const Vector<T> &A)
|
||||||
|
{
|
||||||
|
Subscript N=A.dim();
|
||||||
|
|
||||||
|
s << N << "\n";
|
||||||
|
|
||||||
|
for (Subscript i=0; i<N; i++)
|
||||||
|
s << A[i] << " " << "\n";
|
||||||
|
s << "\n";
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
std::istream & operator>>(std::istream &s, Vector<T> &A)
|
||||||
|
{
|
||||||
|
|
||||||
|
Subscript N;
|
||||||
|
|
||||||
|
s >> N;
|
||||||
|
|
||||||
|
if ( !(N == A.size() ))
|
||||||
|
{
|
||||||
|
A.newsize(N);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (Subscript i=0; i<N; i++)
|
||||||
|
s >> A[i];
|
||||||
|
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
// *******************[ basic matrix algorithms ]***************************
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Vector<T> operator+(const Vector<T> &A,
|
||||||
|
const Vector<T> &B)
|
||||||
|
{
|
||||||
|
Subscript N = A.dim();
|
||||||
|
|
||||||
|
assert(N==B.dim());
|
||||||
|
|
||||||
|
Vector<T> tmp(N);
|
||||||
|
Subscript i;
|
||||||
|
|
||||||
|
for (i=0; i<N; i++)
|
||||||
|
tmp[i] = A[i] + B[i];
|
||||||
|
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Vector<T> operator-(const Vector<T> &A,
|
||||||
|
const Vector<T> &B)
|
||||||
|
{
|
||||||
|
Subscript N = A.dim();
|
||||||
|
|
||||||
|
assert(N==B.dim());
|
||||||
|
|
||||||
|
Vector<T> tmp(N);
|
||||||
|
Subscript i;
|
||||||
|
|
||||||
|
for (i=0; i<N; i++)
|
||||||
|
tmp[i] = A[i] - B[i];
|
||||||
|
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Vector<T> operator*(const Vector<T> &A,
|
||||||
|
const Vector<T> &B)
|
||||||
|
{
|
||||||
|
Subscript N = A.dim();
|
||||||
|
|
||||||
|
assert(N==B.dim());
|
||||||
|
|
||||||
|
Vector<T> tmp(N);
|
||||||
|
Subscript i;
|
||||||
|
|
||||||
|
for (i=0; i<N; i++)
|
||||||
|
tmp[i] = A[i] * B[i];
|
||||||
|
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
T dot_prod(const Vector<T> &A, const Vector<T> &B)
|
||||||
|
{
|
||||||
|
Subscript N = A.dim();
|
||||||
|
assert(N == B.dim());
|
||||||
|
|
||||||
|
Subscript i;
|
||||||
|
T sum = 0;
|
||||||
|
|
||||||
|
for (i=0; i<N; i++)
|
||||||
|
sum += A[i] * B[i];
|
||||||
|
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace TNT */
|
||||||
|
|
||||||
|
#endif
|
||||||
|
// TNT_VEC_H
|
||||||
39
intern/smoke/intern/tnt/tnt_version.h
Normal file
39
intern/smoke/intern/tnt/tnt_version.h
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Template Numerical Toolkit (TNT)
|
||||||
|
*
|
||||||
|
* Mathematical and Computational Sciences Division
|
||||||
|
* National Institute of Technology,
|
||||||
|
* Gaithersburg, MD USA
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* This software was developed at the National Institute of Standards and
|
||||||
|
* Technology (NIST) by employees of the Federal Government in the course
|
||||||
|
* of their official duties. Pursuant to title 17 Section 105 of the
|
||||||
|
* United States Code, this software is not subject to copyright protection
|
||||||
|
* and is in the public domain. NIST assumes no responsibility whatsoever for
|
||||||
|
* its use by other parties, and makes no guarantees, expressed or implied,
|
||||||
|
* about its quality, reliability, or any other characteristic.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef TNT_VERSION_H
|
||||||
|
#define TNT_VERSION_H
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// current version
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
#define TNT_MAJOR_VERSION '1'
|
||||||
|
#define TNT_MINOR_VERSION '2'
|
||||||
|
#define TNT_SUBMINOR_VERSION '6'
|
||||||
|
#define TNT_VERSION_STRING "1.2.6"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
// TNT_VERSION_H
|
||||||
@@ -350,10 +350,6 @@
|
|||||||
RelativePath="..\..\..\source\blender\python\intern\bpy_rna.c"
|
RelativePath="..\..\..\source\blender\python\intern\bpy_rna.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath="..\..\..\source\blender\python\intern\bpy_scriptlink.c"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\source\blender\python\intern\bpy_ui.c"
|
RelativePath="..\..\..\source\blender\python\intern\bpy_ui.c"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -207,6 +207,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PHY_Bullet", "..\gameengine
|
|||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BL_nodes", "nodes\nodes.vcproj", "{4C3AB78A-52CA-4276-A041-39776E52D8C8}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BL_nodes", "nodes\nodes.vcproj", "{4C3AB78A-52CA-4276-A041-39776E52D8C8}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{7495FE37-933A-4AC1-BB2A-B3FDB4DE4284} = {7495FE37-933A-4AC1-BB2A-B3FDB4DE4284}
|
||||||
|
{DFE7F3E3-E62A-4677-B666-DF0DDF70C359} = {DFE7F3E3-E62A-4677-B666-DF0DDF70C359}
|
||||||
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BL_gpu", "gpu\BL_gpu.vcproj", "{138DD16C-CC78-4F6C-A898-C8DA68D89067}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BL_gpu", "gpu\BL_gpu.vcproj", "{138DD16C-CC78-4F6C-A898-C8DA68D89067}"
|
||||||
EndProject
|
EndProject
|
||||||
|
|||||||
@@ -208,6 +208,18 @@
|
|||||||
<References>
|
<References>
|
||||||
</References>
|
</References>
|
||||||
<Files>
|
<Files>
|
||||||
|
<Filter
|
||||||
|
Name="Resource Files"
|
||||||
|
Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\source\icons\winblender.ico"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\source\icons\winblenderfile.ico"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<Filter
|
<Filter
|
||||||
Name="Source Files"
|
Name="Source Files"
|
||||||
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||||
@@ -241,18 +253,6 @@
|
|||||||
</FileConfiguration>
|
</FileConfiguration>
|
||||||
</File>
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
|
||||||
Name="Resource Files"
|
|
||||||
Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
|
||||||
>
|
|
||||||
<File
|
|
||||||
RelativePath="..\..\source\icons\winblender.ico"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\..\source\icons\winblenderfile.ico"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
<Filter
|
||||||
Name="Header Files"
|
Name="Header Files"
|
||||||
|
|||||||
@@ -521,6 +521,10 @@
|
|||||||
RelativePath="..\..\..\source\blender\blenkernel\intern\bmfont.c"
|
RelativePath="..\..\..\source\blender\blenkernel\intern\bmfont.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\source\blender\blenkernel\intern\boids.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\source\blender\blenkernel\intern\booleanops.c"
|
RelativePath="..\..\..\source\blender\blenkernel\intern\booleanops.c"
|
||||||
>
|
>
|
||||||
@@ -609,6 +613,10 @@
|
|||||||
RelativePath="..\..\..\source\blender\blenkernel\intern\fluidsim.c"
|
RelativePath="..\..\..\source\blender\blenkernel\intern\fluidsim.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\source\blender\blenkernel\intern\fmodifier.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\source\blender\blenkernel\intern\font.c"
|
RelativePath="..\..\..\source\blender\blenkernel\intern\font.c"
|
||||||
>
|
>
|
||||||
@@ -826,6 +834,10 @@
|
|||||||
RelativePath="..\..\..\source\blender\blenkernel\BKE_bmfont_types.h"
|
RelativePath="..\..\..\source\blender\blenkernel\BKE_bmfont_types.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\source\blender\blenkernel\BKE_boids.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\source\blender\blenkernel\BKE_booleanops.h"
|
RelativePath="..\..\..\source\blender\blenkernel\BKE_booleanops.h"
|
||||||
>
|
>
|
||||||
@@ -1098,6 +1110,14 @@
|
|||||||
RelativePath="..\..\..\source\blender\blenkernel\depsgraph_private.h"
|
RelativePath="..\..\..\source\blender\blenkernel\depsgraph_private.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\source\blender\blenkernel\Makefile"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\source\blender\blenkernel\nla_private.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
</Files>
|
</Files>
|
||||||
<Globals>
|
<Globals>
|
||||||
|
|||||||
@@ -522,6 +522,10 @@
|
|||||||
RelativePath="..\..\..\source\blender\blenlib\intern\bpath.c"
|
RelativePath="..\..\..\source\blender\blenlib\intern\bpath.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\source\blender\blenlib\intern\DLRB_tree.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\source\blender\blenlib\intern\dynamiclist.c"
|
RelativePath="..\..\..\source\blender\blenlib\intern\dynamiclist.c"
|
||||||
>
|
>
|
||||||
@@ -639,6 +643,10 @@
|
|||||||
RelativePath="..\..\..\source\blender\blenlib\intern\BLI_callbacks.h"
|
RelativePath="..\..\..\source\blender\blenlib\intern\BLI_callbacks.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\source\blender\blenlib\BLI_dlrbTree.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\source\blender\blenlib\BLI_dynamiclist.h"
|
RelativePath="..\..\..\source\blender\blenlib\BLI_dynamiclist.h"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -638,6 +638,10 @@
|
|||||||
RelativePath="..\..\..\source\blender\editors\space_graph\graph_select.c"
|
RelativePath="..\..\..\source\blender\editors\space_graph\graph_select.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\source\blender\editors\space_graph\graph_utils.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\source\blender\editors\space_graph\space_graph.c"
|
RelativePath="..\..\..\source\blender\editors\space_graph\space_graph.c"
|
||||||
>
|
>
|
||||||
@@ -838,6 +842,22 @@
|
|||||||
<Filter
|
<Filter
|
||||||
Name="space_nla"
|
Name="space_nla"
|
||||||
>
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\source\blender\editors\space_nla\nla_buttons.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\source\blender\editors\space_nla\nla_channels.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\source\blender\editors\space_nla\nla_draw.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\source\blender\editors\space_nla\nla_edit.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\source\blender\editors\space_nla\nla_header.c"
|
RelativePath="..\..\..\source\blender\editors\space_nla\nla_header.c"
|
||||||
>
|
>
|
||||||
@@ -846,6 +866,14 @@
|
|||||||
RelativePath="..\..\..\source\blender\editors\space_nla\nla_intern.h"
|
RelativePath="..\..\..\source\blender\editors\space_nla\nla_intern.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\source\blender\editors\space_nla\nla_ops.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\source\blender\editors\space_nla\nla_select.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\source\blender\editors\space_nla\space_nla.c"
|
RelativePath="..\..\..\source\blender\editors\space_nla\space_nla.c"
|
||||||
>
|
>
|
||||||
@@ -998,6 +1026,10 @@
|
|||||||
RelativePath="..\..\..\source\blender\editors\animation\drivers.c"
|
RelativePath="..\..\..\source\blender\editors\animation\drivers.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\source\blender\editors\animation\fmodifier_ui.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\source\blender\editors\animation\keyframes_draw.c"
|
RelativePath="..\..\..\source\blender\editors\animation\keyframes_draw.c"
|
||||||
>
|
>
|
||||||
@@ -1354,6 +1386,10 @@
|
|||||||
RelativePath="..\..\..\source\blender\editors\physics\editparticle.c"
|
RelativePath="..\..\..\source\blender\editors\physics\editparticle.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\source\blender\editors\physics\physics_boids.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\source\blender\editors\physics\physics_intern.h"
|
RelativePath="..\..\..\source\blender\editors\physics\physics_intern.h"
|
||||||
>
|
>
|
||||||
@@ -1383,6 +1419,30 @@
|
|||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="space_console"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\source\blender\editors\space_console\console_draw.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\source\blender\editors\space_console\console_intern.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\source\blender\editors\space_console\console_ops.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\source\blender\editors\space_console\console_report.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\source\blender\editors\space_console\space_console.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
</Files>
|
</Files>
|
||||||
<Globals>
|
<Globals>
|
||||||
</Globals>
|
</Globals>
|
||||||
|
|||||||
@@ -43,7 +43,7 @@
|
|||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\lib\windows\zlib\include;..\..\..\source\blender\inflate;..\..\..\source\blender\deflate;..\..\..\source\blender\include;..\..\..\source\blender\python;..\..\..\source\blender\blenlib;..\..\..\source\blender\makesdna;..\..\..\source\blender\blenkernel;..\..\..\source\blender\blenloader;..\..\..\source\blender\streamglue;..\..\..\source\blender\readblenfile;..\..\..\source\blender\writeblenfile;..\..\..\source\blender\readstreamglue;..\..\..\source\blender\writestreamglue;..\..\..\source\blender\render\extern\include;..\..\..\source\kernel\gen_messaging;..\..\..\..\build\msvc_9\extern\verse\include"
|
AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\lib\windows\zlib\include;..\..\..\source\blender\inflate;..\..\..\source\blender\deflate;..\..\..\source\blender\include;..\..\..\source\blender\python;..\..\..\source\blender\blenlib;..\..\..\source\blender\makesrna;..\..\..\source\blender\makesdna;..\..\..\source\blender\blenkernel;..\..\..\source\blender\blenloader;..\..\..\source\blender\streamglue;..\..\..\source\blender\readblenfile;..\..\..\source\blender\writeblenfile;..\..\..\source\blender\readstreamglue;..\..\..\source\blender\writestreamglue;..\..\..\source\blender\render\extern\include;..\..\..\source\kernel\gen_messaging;..\..\..\..\build\msvc_9\extern\verse\include"
|
||||||
PreprocessorDefinitions="_DEBUG;WIN32;_LIB"
|
PreprocessorDefinitions="_DEBUG;WIN32;_LIB"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
RuntimeLibrary="1"
|
RuntimeLibrary="1"
|
||||||
@@ -268,7 +268,7 @@
|
|||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
InlineFunctionExpansion="1"
|
InlineFunctionExpansion="1"
|
||||||
AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\lib\windows\zlib\include;..\..\..\source\blender\inflate;..\..\..\source\blender\deflate;..\..\..\source\blender\include;..\..\..\source\blender\python;..\..\..\source\blender\blenlib;..\..\..\source\blender\makesdna;..\..\..\source\blender\blenkernel;..\..\..\source\blender\blenloader;..\..\..\source\blender\streamglue;..\..\..\source\blender\readblenfile;..\..\..\source\blender\writeblenfile;..\..\..\source\blender\readstreamglue;..\..\..\source\blender\writestreamglue;..\..\..\source\blender\render\extern\include;..\..\..\source\kernel\gen_messaging;..\..\..\..\build\msvc_9\extern\verse\include"
|
AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\lib\windows\zlib\include;..\..\..\source\blender\inflate;..\..\..\source\blender\deflate;..\..\..\source\blender\include;..\..\..\source\blender\python;..\..\..\source\blender\blenlib;..\..\..\source\blender\makesrna;..\..\..\source\blender\makesdna;..\..\..\source\blender\blenkernel;..\..\..\source\blender\blenloader;..\..\..\source\blender\streamglue;..\..\..\source\blender\readblenfile;..\..\..\source\blender\writeblenfile;..\..\..\source\blender\readstreamglue;..\..\..\source\blender\writestreamglue;..\..\..\source\blender\render\extern\include;..\..\..\source\kernel\gen_messaging;..\..\..\..\build\msvc_9\extern\verse\include"
|
||||||
PreprocessorDefinitions="NDEBUG;WIN32;_LIB"
|
PreprocessorDefinitions="NDEBUG;WIN32;_LIB"
|
||||||
StringPooling="true"
|
StringPooling="true"
|
||||||
RuntimeLibrary="0"
|
RuntimeLibrary="0"
|
||||||
|
|||||||
@@ -613,6 +613,10 @@
|
|||||||
RelativePath="..\..\..\source\blender\makesdna\DNA_armature_types.h"
|
RelativePath="..\..\..\source\blender\makesdna\DNA_armature_types.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\source\blender\makesdna\DNA_boid_types.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\source\blender\makesdna\DNA_brush_types.h"
|
RelativePath="..\..\..\source\blender\makesdna\DNA_brush_types.h"
|
||||||
>
|
>
|
||||||
@@ -761,10 +765,6 @@
|
|||||||
RelativePath="..\..\..\source\blender\makesdna\DNA_script_types.h"
|
RelativePath="..\..\..\source\blender\makesdna\DNA_script_types.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath="..\..\..\source\blender\makesdna\DNA_scriptlink_types.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\source\blender\makesdna\DNA_sdna_types.h"
|
RelativePath="..\..\..\source\blender\makesdna\DNA_sdna_types.h"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -45,7 +45,7 @@
|
|||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\source\blender;..\..\..\source\blender\blenlib;..\..\..\source\blender\makesrna;..\..\..\source\blender\editors\include;..\..\..\source\blender\blenkernel;..\..\..\..\lib\windows\pthreads\include;..\..\..\source\blender\makesdna;..\..\..\source\blender\windowmanager"
|
AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\source\blender;..\..\..\source\blender\blenlib;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\editors\include;..\..\..\source\blender\blenkernel;..\..\..\..\lib\windows\pthreads\include;..\..\..\source\blender\render\extern\include;..\..\..\source\blender\windowmanager"
|
||||||
PreprocessorDefinitions="_DEBUG,WIN32,_CONSOLE"
|
PreprocessorDefinitions="_DEBUG,WIN32,_CONSOLE"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
RuntimeLibrary="3"
|
RuntimeLibrary="3"
|
||||||
@@ -140,7 +140,7 @@
|
|||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
InlineFunctionExpansion="1"
|
InlineFunctionExpansion="1"
|
||||||
AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\source\blender;..\..\..\source\blender\blenlib;..\..\..\source\blender\makesrna;..\..\..\source\blender\editors\include;..\..\..\source\blender\blenkernel;..\..\..\..\lib\windows\pthreads\include;..\..\..\source\blender\makesdna;..\..\..\source\blender\windowmanager"
|
AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\source\blender;..\..\..\source\blender\blenlib;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\editors\include;..\..\..\source\blender\blenkernel;..\..\..\..\lib\windows\pthreads\include;..\..\..\source\blender\render\extern\include;..\..\..\source\blender\windowmanager"
|
||||||
PreprocessorDefinitions="NDEBUG,WIN32,_CONSOLE"
|
PreprocessorDefinitions="NDEBUG,WIN32,_CONSOLE"
|
||||||
StringPooling="true"
|
StringPooling="true"
|
||||||
RuntimeLibrary="0"
|
RuntimeLibrary="0"
|
||||||
@@ -234,7 +234,7 @@
|
|||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
InlineFunctionExpansion="1"
|
InlineFunctionExpansion="1"
|
||||||
AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\source\blender;..\..\..\source\blender\blenlib;..\..\..\source\blender\makesrna;..\..\..\source\blender\editors\include;..\..\..\source\blender\blenkernel;..\..\..\..\lib\windows\pthreads\include;..\..\..\source\blender\makesdna;..\..\..\source\blender\windowmanager"
|
AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\source\blender;..\..\..\source\blender\blenlib;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\editors\include;..\..\..\source\blender\blenkernel;..\..\..\..\lib\windows\pthreads\include;..\..\..\source\blender\render\extern\include;..\..\..\source\blender\windowmanager"
|
||||||
PreprocessorDefinitions="NDEBUG,WIN32,_CONSOLE"
|
PreprocessorDefinitions="NDEBUG,WIN32,_CONSOLE"
|
||||||
StringPooling="true"
|
StringPooling="true"
|
||||||
RuntimeLibrary="2"
|
RuntimeLibrary="2"
|
||||||
@@ -328,7 +328,7 @@
|
|||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\source\blender;..\..\..\source\blender\blenlib;..\..\..\source\blender\makesrna;..\..\..\source\blender\editors\include;..\..\..\source\blender\blenkernel;..\..\..\..\lib\windows\pthreads\include;..\..\..\source\blender\makesdna;..\..\..\source\blender\windowmanager"
|
AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\source\blender;..\..\..\source\blender\blenlib;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\editors\include;..\..\..\source\blender\blenkernel;..\..\..\..\lib\windows\pthreads\include;..\..\..\source\blender\render\extern\include;..\..\..\source\blender\windowmanager"
|
||||||
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE"
|
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
RuntimeLibrary="1"
|
RuntimeLibrary="1"
|
||||||
@@ -425,7 +425,7 @@
|
|||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\source\blender;..\..\..\source\blender\blenlib;..\..\..\source\blender\makesrna;..\..\..\source\blender\editors\include;..\..\..\source\blender\blenkernel;..\..\..\..\lib\windows\pthreads\include;..\..\..\source\blender\makesdna;..\..\..\source\blender\windowmanager"
|
AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\source\blender;..\..\..\source\blender\blenlib;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\editors\include;..\..\..\source\blender\blenkernel;..\..\..\..\lib\windows\pthreads\include;..\..\..\source\blender\render\extern\include;..\..\..\source\blender\windowmanager"
|
||||||
PreprocessorDefinitions="_DEBUG,WIN32,_CONSOLE"
|
PreprocessorDefinitions="_DEBUG,WIN32,_CONSOLE"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
RuntimeLibrary="1"
|
RuntimeLibrary="1"
|
||||||
@@ -522,7 +522,7 @@
|
|||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
InlineFunctionExpansion="1"
|
InlineFunctionExpansion="1"
|
||||||
AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\source\blender;..\..\..\source\blender\blenlib;..\..\..\source\blender\makesrna;..\..\..\source\blender\editors\include;..\..\..\source\blender\blenkernel;..\..\..\..\lib\windows\pthreads\include;..\..\..\source\blender\makesdna;..\..\..\source\blender\windowmanager"
|
AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\source\blender;..\..\..\source\blender\blenlib;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\editors\include;..\..\..\source\blender\blenkernel;..\..\..\..\lib\windows\pthreads\include;..\..\..\source\blender\render\extern\include;..\..\..\source\blender\windowmanager"
|
||||||
PreprocessorDefinitions="NDEBUG,WIN32,_CONSOLE"
|
PreprocessorDefinitions="NDEBUG,WIN32,_CONSOLE"
|
||||||
StringPooling="true"
|
StringPooling="true"
|
||||||
RuntimeLibrary="0"
|
RuntimeLibrary="0"
|
||||||
@@ -614,6 +614,10 @@
|
|||||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_armature.c"
|
RelativePath="..\..\..\source\blender\makesrna\intern\rna_armature.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\source\blender\makesrna\intern\rna_boid.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_brush.c"
|
RelativePath="..\..\..\source\blender\makesrna\intern\rna_brush.c"
|
||||||
>
|
>
|
||||||
@@ -710,6 +714,10 @@
|
|||||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_modifier.c"
|
RelativePath="..\..\..\source\blender\makesrna\intern\rna_modifier.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\source\blender\makesrna\intern\rna_nla.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_nodetree.c"
|
RelativePath="..\..\..\source\blender\makesrna\intern\rna_nodetree.c"
|
||||||
>
|
>
|
||||||
@@ -742,6 +750,10 @@
|
|||||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_property.c"
|
RelativePath="..\..\..\source\blender\makesrna\intern\rna_property.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\source\blender\makesrna\intern\rna_render.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_rna.c"
|
RelativePath="..\..\..\source\blender\makesrna\intern\rna_rna.c"
|
||||||
>
|
>
|
||||||
@@ -755,7 +767,7 @@
|
|||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_scriptlink.c"
|
RelativePath="..\..\..\source\blender\makesrna\intern\rna_sculpt_paint.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
@@ -802,10 +814,6 @@
|
|||||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_vfont.c"
|
RelativePath="..\..\..\source\blender\makesrna\intern\rna_vfont.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_vpaint.c"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_wm.c"
|
RelativePath="..\..\..\source\blender\makesrna\intern\rna_wm.c"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -43,7 +43,7 @@
|
|||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\source\blender\imbuf;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\windowmanager;..\..\..\source\blender\editors\include"
|
AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\source\blender\imbuf;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\windowmanager;..\..\..\source\blender\editors\include;..\..\..\source\blender\render\extern\include"
|
||||||
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
|
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
|
||||||
MinimalRebuild="true"
|
MinimalRebuild="true"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
@@ -114,7 +114,7 @@
|
|||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="2"
|
Optimization="2"
|
||||||
EnableIntrinsicFunctions="true"
|
EnableIntrinsicFunctions="true"
|
||||||
AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\source\blender\imbuf;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\windowmanager;..\..\..\source\blender\editors\include"
|
AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\source\blender\imbuf;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\windowmanager;..\..\..\source\blender\editors\include;..\..\..\source\blender\render\extern\include"
|
||||||
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
|
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
|
||||||
MinimalRebuild="true"
|
MinimalRebuild="true"
|
||||||
RuntimeLibrary="0"
|
RuntimeLibrary="0"
|
||||||
@@ -186,6 +186,10 @@
|
|||||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_armature_gen.c"
|
RelativePath="..\..\..\source\blender\makesrna\intern\rna_armature_gen.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\source\blender\makesrna\intern\rna_boid_gen.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_brush_gen.c"
|
RelativePath="..\..\..\source\blender\makesrna\intern\rna_brush_gen.c"
|
||||||
>
|
>
|
||||||
@@ -270,6 +274,10 @@
|
|||||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_modifier_gen.c"
|
RelativePath="..\..\..\source\blender\makesrna\intern\rna_modifier_gen.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\source\blender\makesrna\intern\rna_nla_gen.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_nodetree_gen.c"
|
RelativePath="..\..\..\source\blender\makesrna\intern\rna_nodetree_gen.c"
|
||||||
>
|
>
|
||||||
@@ -298,6 +306,10 @@
|
|||||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_property_gen.c"
|
RelativePath="..\..\..\source\blender\makesrna\intern\rna_property_gen.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\source\blender\makesrna\intern\rna_render_gen.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_rna_gen.c"
|
RelativePath="..\..\..\source\blender\makesrna\intern\rna_rna_gen.c"
|
||||||
>
|
>
|
||||||
@@ -311,7 +323,7 @@
|
|||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_scriptlink_gen.c"
|
RelativePath="..\..\..\source\blender\makesrna\intern\rna_sculpt_paint_gen.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
@@ -354,10 +366,6 @@
|
|||||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_vfont_gen.c"
|
RelativePath="..\..\..\source\blender\makesrna\intern\rna_vfont_gen.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_vpaint_gen.c"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_wm_gen.c"
|
RelativePath="..\..\..\source\blender\makesrna\intern\rna_wm_gen.c"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -42,7 +42,7 @@
|
|||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories="..\..\..\..\lib\windows\python\include\python2.6;..\..\..\..\lib\windows\zlib\include;..\..\..\..\build\msvc_9\intern\bsp\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\decimation\include;..\..\..\..\build\msvc_9\intern\elbeem\include;..\..\..\..\build\msvc_9\intern\iksolver\include;..\..\..\source\blender;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\editors\include;..\..\..\source\blender\python;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\nodes;..\..\..\source\blender\blenloader;..\..\..\source\kernel\gen_system;..\..\..\source\blender\renderconverter;..\..\..\source\blender\render\extern\include;..\..\..\source\gameengine\SoundSystem;..\..\..\..\build\msvc_9\extern\verse\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\blender\gpu"
|
AdditionalIncludeDirectories="..\..\..\..\lib\windows\python\include\python2.6;..\..\..\..\lib\windows\zlib\include;..\..\..\..\build\msvc_9\intern\bsp\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\decimation\include;..\..\..\..\build\msvc_9\intern\elbeem\include;..\..\..\..\build\msvc_9\intern\iksolver\include;..\..\..\source\blender;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\editors\include;..\..\..\source\blender\python;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\nodes;..\..\..\source\blender\blenloader;..\..\..\source\kernel\gen_system;..\..\..\source\blender\renderconverter;..\..\..\source\blender\render\extern\include;..\..\..\source\gameengine\SoundSystem;..\..\..\..\build\msvc_9\extern\verse\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\blender\gpu;..\..\..\source\blender\makesrna"
|
||||||
PreprocessorDefinitions="_DEBUG;WIN32;_LIB"
|
PreprocessorDefinitions="_DEBUG;WIN32;_LIB"
|
||||||
MinimalRebuild="false"
|
MinimalRebuild="false"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
@@ -112,7 +112,7 @@
|
|||||||
/>
|
/>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
AdditionalIncludeDirectories="..\..\..\..\lib\windows\python\include\python2.6;..\..\..\..\lib\windows\zlib\include;..\..\..\..\build\msvc_9\intern\bsp\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\decimation\include;..\..\..\..\build\msvc_9\intern\elbeem\include;..\..\..\..\build\msvc_9\intern\iksolver\include;..\..\..\source\blender;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\editors\include;..\..\..\source\blender\python;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\nodes;..\..\..\source\blender\blenloader;..\..\..\source\kernel\gen_system;..\..\..\source\blender\renderconverter;..\..\..\source\blender\render\extern\include;..\..\..\source\gameengine\SoundSystem;..\..\..\..\build\msvc_9\extern\verse\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\blender\gpu"
|
AdditionalIncludeDirectories="..\..\..\..\lib\windows\python\include\python2.6;..\..\..\..\lib\windows\zlib\include;..\..\..\..\build\msvc_9\intern\bsp\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\decimation\include;..\..\..\..\build\msvc_9\intern\elbeem\include;..\..\..\..\build\msvc_9\intern\iksolver\include;..\..\..\source\blender;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\editors\include;..\..\..\source\blender\python;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\nodes;..\..\..\source\blender\blenloader;..\..\..\source\kernel\gen_system;..\..\..\source\blender\renderconverter;..\..\..\source\blender\render\extern\include;..\..\..\source\gameengine\SoundSystem;..\..\..\..\build\msvc_9\extern\verse\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\blender\gpu;..\..\..\source\blender\makesrna"
|
||||||
PreprocessorDefinitions="_DEBUG;WIN32;_LIB"
|
PreprocessorDefinitions="_DEBUG;WIN32;_LIB"
|
||||||
BasicRuntimeChecks="0"
|
BasicRuntimeChecks="0"
|
||||||
RuntimeLibrary="0"
|
RuntimeLibrary="0"
|
||||||
@@ -182,7 +182,7 @@
|
|||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories="..\..\..\..\lib\windows\python\include\python2.6;..\..\..\..\lib\windows\zlib\include;..\..\..\..\build\msvc_9\intern\bsp\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\decimation\include;..\..\..\..\build\msvc_9\intern\elbeem\include;..\..\..\..\build\msvc_9\intern\iksolver\include;..\..\..\source\blender;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\editors\include;..\..\..\source\blender\python;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\nodes;..\..\..\source\blender\blenloader;..\..\..\source\kernel\gen_system;..\..\..\source\blender\renderconverter;..\..\..\source\blender\render\extern\include;..\..\..\source\gameengine\SoundSystem;..\..\..\..\build\msvc_9\extern\verse\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\blender\gpu"
|
AdditionalIncludeDirectories="..\..\..\..\lib\windows\python\include\python2.6;..\..\..\..\lib\windows\zlib\include;..\..\..\..\build\msvc_9\intern\bsp\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\decimation\include;..\..\..\..\build\msvc_9\intern\elbeem\include;..\..\..\..\build\msvc_9\intern\iksolver\include;..\..\..\source\blender;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\editors\include;..\..\..\source\blender\python;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\nodes;..\..\..\source\blender\blenloader;..\..\..\source\kernel\gen_system;..\..\..\source\blender\renderconverter;..\..\..\source\blender\render\extern\include;..\..\..\source\gameengine\SoundSystem;..\..\..\..\build\msvc_9\extern\verse\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\blender\gpu;..\..\..\source\blender\makesrna"
|
||||||
PreprocessorDefinitions="_DEBUG;WIN32;_LIB;WITH_OPENEXR"
|
PreprocessorDefinitions="_DEBUG;WIN32;_LIB;WITH_OPENEXR"
|
||||||
MinimalRebuild="false"
|
MinimalRebuild="false"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
@@ -252,7 +252,7 @@
|
|||||||
/>
|
/>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
AdditionalIncludeDirectories="..\..\..\..\lib\windows\python\include\python2.6;..\..\..\..\lib\windows\zlib\include;..\..\..\..\build\msvc_9\intern\bsp\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\decimation\include;..\..\..\..\build\msvc_9\intern\elbeem\include;..\..\..\..\build\msvc_9\intern\iksolver\include;..\..\..\source\blender;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\editors\include;..\..\..\source\blender\python;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\nodes;..\..\..\source\blender\blenloader;..\..\..\source\kernel\gen_system;..\..\..\source\blender\renderconverter;..\..\..\source\blender\render\extern\include;..\..\..\source\gameengine\SoundSystem;..\..\..\..\build\msvc_9\extern\verse\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\blender\gpu"
|
AdditionalIncludeDirectories="..\..\..\..\lib\windows\python\include\python2.6;..\..\..\..\lib\windows\zlib\include;..\..\..\..\build\msvc_9\intern\bsp\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\intern\decimation\include;..\..\..\..\build\msvc_9\intern\elbeem\include;..\..\..\..\build\msvc_9\intern\iksolver\include;..\..\..\source\blender;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\editors\include;..\..\..\source\blender\python;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\nodes;..\..\..\source\blender\blenloader;..\..\..\source\kernel\gen_system;..\..\..\source\blender\renderconverter;..\..\..\source\blender\render\extern\include;..\..\..\source\gameengine\SoundSystem;..\..\..\..\build\msvc_9\extern\verse\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\blender\gpu;..\..\..\source\blender\makesrna"
|
||||||
PreprocessorDefinitions="NDEBUG;WIN32;_LIB;WITH_OPENEXR"
|
PreprocessorDefinitions="NDEBUG;WIN32;_LIB;WITH_OPENEXR"
|
||||||
BasicRuntimeChecks="0"
|
BasicRuntimeChecks="0"
|
||||||
RuntimeLibrary="0"
|
RuntimeLibrary="0"
|
||||||
|
|||||||
@@ -42,7 +42,7 @@
|
|||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
InlineFunctionExpansion="1"
|
InlineFunctionExpansion="1"
|
||||||
AdditionalIncludeDirectories="..\..\..\..\lib\windows\sdl\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\source\blender;..\..\..\source\blender\misc;..\..\..\source\blender\imbuf;..\..\..\source\blender\yafray;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\python;..\..\..\source\blender\blenkernel;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenloader;..\..\..\source\blender\makesdna;..\..\..\source\blender\radiosity\extern\include;..\..\..\source\blender\render\intern\include;..\..\..\source\blender\render\extern\include;..\..\..\source\kernel;..\..\..\source\kernel\gen_messaging"
|
AdditionalIncludeDirectories="..\..\..\..\lib\windows\sdl\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\source\blender;..\..\..\source\blender\misc;..\..\..\source\blender\imbuf;..\..\..\source\blender\yafray;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\python;..\..\..\source\blender\blenkernel;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenloader;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\radiosity\extern\include;..\..\..\source\blender\render\intern\include;..\..\..\source\blender\render\extern\include;..\..\..\source\kernel;..\..\..\source\kernel\gen_messaging"
|
||||||
PreprocessorDefinitions="NDEBUG;WIN32;_LIB;WITH_QUICKTIME;WITH_OPENEXR"
|
PreprocessorDefinitions="NDEBUG;WIN32;_LIB;WITH_QUICKTIME;WITH_OPENEXR"
|
||||||
StringPooling="true"
|
StringPooling="true"
|
||||||
RuntimeLibrary="0"
|
RuntimeLibrary="0"
|
||||||
@@ -117,7 +117,7 @@
|
|||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories="..\..\..\..\lib\windows\sdl\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\source\blender;..\..\..\source\blender\misc;..\..\..\source\blender\imbuf;..\..\..\source\blender\yafray;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\python;..\..\..\source\blender\blenkernel;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenloader;..\..\..\source\blender\makesdna;..\..\..\source\blender\radiosity\extern\include;..\..\..\source\blender\render\intern\include;..\..\..\source\blender\render\extern\include;..\..\..\source\kernel;..\..\..\source\kernel\gen_messaging"
|
AdditionalIncludeDirectories="..\..\..\..\lib\windows\sdl\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\source\blender;..\..\..\source\blender\misc;..\..\..\source\blender\imbuf;..\..\..\source\blender\yafray;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\python;..\..\..\source\blender\blenkernel;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenloader;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\radiosity\extern\include;..\..\..\source\blender\render\intern\include;..\..\..\source\blender\render\extern\include;..\..\..\source\kernel;..\..\..\source\kernel\gen_messaging"
|
||||||
PreprocessorDefinitions="_DEBUG;WIN32;_LIB;WITH_QUICKTIME;WITH_OPENEXR;_USE_MATH_DEFINES"
|
PreprocessorDefinitions="_DEBUG;WIN32;_LIB;WITH_QUICKTIME;WITH_OPENEXR;_USE_MATH_DEFINES"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
RuntimeLibrary="1"
|
RuntimeLibrary="1"
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 172 KiB After Width: | Height: | Size: 175 KiB |
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 192 KiB After Width: | Height: | Size: 192 KiB |
780
release/io/engine_render_pov.py
Normal file
780
release/io/engine_render_pov.py
Normal file
@@ -0,0 +1,780 @@
|
|||||||
|
import bpy
|
||||||
|
|
||||||
|
from math import atan, pi, degrees
|
||||||
|
import subprocess
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
|
||||||
|
import platform as pltfrm
|
||||||
|
|
||||||
|
if pltfrm.architecture()[0] == '64bit':
|
||||||
|
bitness = 64
|
||||||
|
else:
|
||||||
|
bitness = 32
|
||||||
|
|
||||||
|
def write_pov(filename, scene=None, info_callback = None):
|
||||||
|
file = open(filename, 'w')
|
||||||
|
|
||||||
|
# Only for testing
|
||||||
|
if not scene:
|
||||||
|
scene = bpy.data.scenes[0]
|
||||||
|
|
||||||
|
render = scene.render_data
|
||||||
|
materialTable = {}
|
||||||
|
|
||||||
|
def saneName(name):
|
||||||
|
name = name.lower()
|
||||||
|
for ch in ' /\\+=-[]{}().,<>\'":;~!@#$%^&*|?':
|
||||||
|
name = name.replace(ch, '_')
|
||||||
|
return name
|
||||||
|
|
||||||
|
def writeMatrix(matrix):
|
||||||
|
file.write('\tmatrix <%.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f>\n' %\
|
||||||
|
(matrix[0][0], matrix[0][1], matrix[0][2], matrix[1][0], matrix[1][1], matrix[1][2], matrix[2][0], matrix[2][1], matrix[2][2], matrix[3][0], matrix[3][1], matrix[3][2]) )
|
||||||
|
|
||||||
|
def exportCamera():
|
||||||
|
camera = scene.camera
|
||||||
|
matrix = camera.matrix
|
||||||
|
|
||||||
|
# compute resolution
|
||||||
|
Qsize=float(render.resolution_x)/float(render.resolution_y)
|
||||||
|
|
||||||
|
file.write('camera {\n')
|
||||||
|
file.write('\tlocation <0, 0, 0>\n')
|
||||||
|
file.write('\tlook_at <0, 0, -1>\n')
|
||||||
|
file.write('\tright <%s, 0, 0>\n' % -Qsize)
|
||||||
|
file.write('\tup <0, 1, 0>\n')
|
||||||
|
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('\ttranslate <%.6f, %.6f, %.6f>\n' % (matrix[3][0], matrix[3][1], matrix[3][2]))
|
||||||
|
file.write('}\n')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def exportLamps(lamps):
|
||||||
|
# Get all lamps
|
||||||
|
for ob in lamps:
|
||||||
|
lamp = ob.data
|
||||||
|
|
||||||
|
matrix = ob.matrix
|
||||||
|
|
||||||
|
color = tuple([c * lamp.energy for c in lamp.color]) # Colour is modified by energy
|
||||||
|
|
||||||
|
file.write('light_source {\n')
|
||||||
|
file.write('\t< 0,0,0 >\n')
|
||||||
|
file.write('\tcolor rgb<%.3g, %.3g, %.3g>\n' % color)
|
||||||
|
|
||||||
|
if lamp.type == 'POINT': # Point Lamp
|
||||||
|
pass
|
||||||
|
elif lamp.type == 'SPOT': # Spot
|
||||||
|
file.write('\tspotlight\n')
|
||||||
|
|
||||||
|
# Falloff is the main radius from the centre line
|
||||||
|
file.write('\tfalloff %.2f\n' % (lamp.spot_size/2.0) ) # 1 TO 179 FOR BOTH
|
||||||
|
file.write('\tradius %.6f\n' % ((lamp.spot_size/2.0) * (1-lamp.spot_blend)) )
|
||||||
|
|
||||||
|
# Blender does not have a tightness equivilent, 0 is most like blender default.
|
||||||
|
file.write('\ttightness 0\n') # 0:10f
|
||||||
|
|
||||||
|
file.write('\tpoint_at <0, 0, -1>\n')
|
||||||
|
elif lamp.type == 'AREA':
|
||||||
|
|
||||||
|
size_x = lamp.size
|
||||||
|
samples_x = lamp.shadow_ray_samples_x
|
||||||
|
if lamp.shape == 'SQUARE':
|
||||||
|
size_y = size_x
|
||||||
|
samples_y = samples_x
|
||||||
|
else:
|
||||||
|
size_y = lamp.size_y
|
||||||
|
samples_y = lamp.shadow_ray_samples_y
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
file.write('\tarea_light <%d,0,0>,<0,0,%d> %d, %d\n' % (size_x, size_y, samples_x, samples_y))
|
||||||
|
if lamp.shadow_ray_sampling_method == 'CONSTANT_JITTERED':
|
||||||
|
if lamp.jitter:
|
||||||
|
file.write('\tjitter\n')
|
||||||
|
else:
|
||||||
|
file.write('\tadaptive 1\n')
|
||||||
|
file.write('\tjitter\n')
|
||||||
|
|
||||||
|
if lamp.shadow_method == 'NOSHADOW':
|
||||||
|
file.write('\tshadowless\n')
|
||||||
|
|
||||||
|
file.write('\tfade_distance %.6f\n' % lamp.distance)
|
||||||
|
file.write('\tfade_power %d\n' % 1) # Could use blenders lamp quad?
|
||||||
|
writeMatrix(matrix)
|
||||||
|
|
||||||
|
file.write('}\n')
|
||||||
|
|
||||||
|
def exportMeshs(sel):
|
||||||
|
def bMat2PovString(material):
|
||||||
|
povstring = 'finish {'
|
||||||
|
if world != None:
|
||||||
|
povstring += 'ambient <%.6f, %.6f, %.6f> ' % tuple([c*material.ambient for c in world.ambient_color])
|
||||||
|
|
||||||
|
povstring += 'diffuse %.6f ' % material.diffuse_reflection
|
||||||
|
povstring += 'specular %.6f ' % material.specular_reflection
|
||||||
|
|
||||||
|
|
||||||
|
if material.raytrace_mirror.enabled:
|
||||||
|
#povstring += 'interior { ior %.6f } ' % material.IOR
|
||||||
|
raytrace_mirror= material.raytrace_mirror
|
||||||
|
if raytrace_mirror.reflect:
|
||||||
|
povstring += 'reflection {'
|
||||||
|
povstring += '<%.6f, %.6f, %.6f>' % tuple(material.mirror_color) # Should ask for ray mirror flag
|
||||||
|
povstring += 'fresnel 1 falloff %.6f exponent %.6f metallic %.6f} ' % (raytrace_mirror.fresnel, raytrace_mirror.fresnel_fac, raytrace_mirror.reflect)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if material.raytrace_transparency.enabled:
|
||||||
|
#povstring += 'interior { ior %.6f } ' % material.IOR
|
||||||
|
pass
|
||||||
|
|
||||||
|
#file.write('\t\troughness %.6f\n' % (material.hard*0.5))
|
||||||
|
#file.write('\t\t\tcrand 0.0\n') # Sand granyness
|
||||||
|
#file.write('\t\t\tmetallic %.6f\n' % material.spec)
|
||||||
|
#file.write('\t\t\tphong %.6f\n' % material.spec)
|
||||||
|
#file.write('\t\t\tphong_size %.6f\n' % material.spec)
|
||||||
|
povstring += 'brilliance %.6f ' % (material.specular_hardness/256.0) # Like hardness
|
||||||
|
povstring += '}'
|
||||||
|
#file.write('\t}\n')
|
||||||
|
return povstring
|
||||||
|
|
||||||
|
|
||||||
|
world = scene.world
|
||||||
|
|
||||||
|
# Convert all materials to strings we can access directly per vertex.
|
||||||
|
for material in bpy.data.materials:
|
||||||
|
materialTable[material.name] = bMat2PovString(material)
|
||||||
|
|
||||||
|
|
||||||
|
ob_num = 0
|
||||||
|
|
||||||
|
for ob in sel:
|
||||||
|
ob_num+= 1
|
||||||
|
|
||||||
|
if ob.type in ('LAMP', 'CAMERA', 'EMPTY'):
|
||||||
|
continue
|
||||||
|
|
||||||
|
me = ob.data
|
||||||
|
me_materials= me.materials
|
||||||
|
|
||||||
|
me = ob.create_render_mesh(scene)
|
||||||
|
|
||||||
|
if not me:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if info_callback:
|
||||||
|
info_callback('Object %2.d of %2.d (%s)' % (ob_num, len(sel), ob.name))
|
||||||
|
|
||||||
|
#if ob.type!='MESH':
|
||||||
|
# continue
|
||||||
|
# me = ob.data
|
||||||
|
|
||||||
|
matrix = ob.matrix
|
||||||
|
try: uv_layer = me.active_uv_texture.data
|
||||||
|
except:uv_layer = None
|
||||||
|
|
||||||
|
try: vcol_layer = me.active_vertex_color.data
|
||||||
|
except:vcol_layer = None
|
||||||
|
|
||||||
|
|
||||||
|
def regular_face(f):
|
||||||
|
fv = f.verts
|
||||||
|
if fv[3]== 0:
|
||||||
|
return fv[0], fv[1], fv[2]
|
||||||
|
return fv[0], fv[1], fv[2], fv[3]
|
||||||
|
|
||||||
|
faces_verts = [regular_face(f) for f in me.faces]
|
||||||
|
faces_normals = [tuple(f.normal) for f in me.faces]
|
||||||
|
verts_normals = [tuple(v.normal) for v in me.verts]
|
||||||
|
|
||||||
|
# quads incur an extra face
|
||||||
|
quadCount = len([f for f in faces_verts if len(f)==4])
|
||||||
|
|
||||||
|
file.write('mesh2 {\n')
|
||||||
|
file.write('\tvertex_vectors {\n')
|
||||||
|
file.write('\t\t%s' % (len(me.verts))) # vert count
|
||||||
|
for v in me.verts:
|
||||||
|
file.write(',\n\t\t<%.6f, %.6f, %.6f>' % tuple(v.co)) # vert count
|
||||||
|
file.write('\n }\n')
|
||||||
|
|
||||||
|
|
||||||
|
# Build unique Normal list
|
||||||
|
uniqueNormals = {}
|
||||||
|
for fi, f in enumerate(me.faces):
|
||||||
|
fv = faces_verts[fi]
|
||||||
|
# [-1] is a dummy index, use a list so we can modify in place
|
||||||
|
if f.smooth: # Use vertex normals
|
||||||
|
for v in fv:
|
||||||
|
key = verts_normals[v]
|
||||||
|
uniqueNormals[key] = [-1]
|
||||||
|
else: # Use face normal
|
||||||
|
key = faces_normals[fi]
|
||||||
|
uniqueNormals[key] = [-1]
|
||||||
|
|
||||||
|
file.write('\tnormal_vectors {\n')
|
||||||
|
file.write('\t\t%d' % len(uniqueNormals)) # vert count
|
||||||
|
idx = 0
|
||||||
|
for no, index in uniqueNormals.items():
|
||||||
|
file.write(',\n\t\t<%.6f, %.6f, %.6f>' % no) # vert count
|
||||||
|
index[0] = idx
|
||||||
|
idx +=1
|
||||||
|
file.write('\n }\n')
|
||||||
|
|
||||||
|
|
||||||
|
# Vertex colours
|
||||||
|
vertCols = {} # Use for material colours also.
|
||||||
|
|
||||||
|
if uv_layer:
|
||||||
|
# Generate unique UV's
|
||||||
|
uniqueUVs = {}
|
||||||
|
|
||||||
|
for fi, uv in enumerate(uv_layer):
|
||||||
|
|
||||||
|
if len(faces_verts[fi])==4:
|
||||||
|
uvs = uv.uv1, uv.uv2, uv.uv3, uv.uv4
|
||||||
|
else:
|
||||||
|
uvs = uv.uv1, uv.uv2, uv.uv3
|
||||||
|
|
||||||
|
for uv in uvs:
|
||||||
|
uniqueUVs[tuple(uv)] = [-1]
|
||||||
|
|
||||||
|
file.write('\tuv_vectors {\n')
|
||||||
|
#print unique_uvs
|
||||||
|
file.write('\t\t%s' % (len(uniqueUVs))) # vert count
|
||||||
|
idx = 0
|
||||||
|
for uv, index in uniqueUVs.items():
|
||||||
|
file.write(',\n\t\t<%.6f, %.6f>' % uv)
|
||||||
|
index[0] = idx
|
||||||
|
idx +=1
|
||||||
|
'''
|
||||||
|
else:
|
||||||
|
# Just add 1 dummy vector, no real UV's
|
||||||
|
file.write('\t\t1') # vert count
|
||||||
|
file.write(',\n\t\t<0.0, 0.0>')
|
||||||
|
'''
|
||||||
|
file.write('\n }\n')
|
||||||
|
|
||||||
|
|
||||||
|
if me.vertex_colors:
|
||||||
|
|
||||||
|
for fi, f in enumerate(me.faces):
|
||||||
|
material_index = f.material_index
|
||||||
|
material = me_materials[material_index]
|
||||||
|
|
||||||
|
if material and material.vertex_color_paint:
|
||||||
|
|
||||||
|
col = vcol_layer[fi]
|
||||||
|
|
||||||
|
if len(faces_verts[fi])==4:
|
||||||
|
cols = col.color1, col.color2, col.color3, col.color4
|
||||||
|
else:
|
||||||
|
cols = col.color1, col.color2, col.color3
|
||||||
|
|
||||||
|
for col in cols:
|
||||||
|
key = col[0], col[1], col[2], material_index # Material index!
|
||||||
|
vertCols[key] = [-1]
|
||||||
|
|
||||||
|
else:
|
||||||
|
if material:
|
||||||
|
diffuse_color = tuple(material.diffuse_color)
|
||||||
|
key = diffuse_color[0], diffuse_color[1], diffuse_color[2], material_index
|
||||||
|
vertCols[key] = [-1]
|
||||||
|
|
||||||
|
|
||||||
|
else:
|
||||||
|
# No vertex colours, so write material colours as vertex colours
|
||||||
|
for i, material in enumerate(me_materials):
|
||||||
|
|
||||||
|
if material:
|
||||||
|
diffuse_color = tuple(material.diffuse_color)
|
||||||
|
key = diffuse_color[0], diffuse_color[1], diffuse_color[2], i # i == f.mat
|
||||||
|
vertCols[key] = [-1]
|
||||||
|
|
||||||
|
|
||||||
|
# Vert Colours
|
||||||
|
file.write('\ttexture_list {\n')
|
||||||
|
file.write('\t\t%s' % (len(vertCols))) # vert count
|
||||||
|
idx=0
|
||||||
|
for col, index in vertCols.items():
|
||||||
|
|
||||||
|
if me_materials:
|
||||||
|
material = me_materials[col[3]]
|
||||||
|
materialString = materialTable[material.name]
|
||||||
|
else:
|
||||||
|
materialString = '' # Dont write anything
|
||||||
|
|
||||||
|
float_col = col[0], col[1], col[2], 1-material.alpha, materialString
|
||||||
|
#print material.apl
|
||||||
|
file.write(',\n\t\ttexture { pigment {rgbf<%.3g, %.3g, %.3g, %.3g>}%s}' % float_col)
|
||||||
|
index[0] = idx
|
||||||
|
idx+=1
|
||||||
|
|
||||||
|
file.write( '\n }\n' )
|
||||||
|
|
||||||
|
# Face indicies
|
||||||
|
file.write('\tface_indices {\n')
|
||||||
|
file.write('\t\t%d' % (len(me.faces) + quadCount)) # faces count
|
||||||
|
for fi, f in enumerate(me.faces):
|
||||||
|
fv = faces_verts[fi]
|
||||||
|
material_index= f.material_index
|
||||||
|
if len(fv) == 4: indicies = (0,1,2), (0,2,3)
|
||||||
|
else: indicies = ((0,1,2),)
|
||||||
|
|
||||||
|
if vcol_layer:
|
||||||
|
col = vcol_layer[fi]
|
||||||
|
|
||||||
|
if len(fv) == 4:
|
||||||
|
cols = col.color1, col.color2, col.color3, col.color4
|
||||||
|
else:
|
||||||
|
cols = col.color1, col.color2, col.color3
|
||||||
|
|
||||||
|
|
||||||
|
if not me_materials or me_materials[material_index] == None: # No materials
|
||||||
|
for i1, i2, i3 in indicies:
|
||||||
|
file.write(',\n\t\t<%d,%d,%d>' % (fv[i1], fv[i2], fv[i3])) # vert count
|
||||||
|
else:
|
||||||
|
material = me_materials[material_index]
|
||||||
|
for i1, i2, i3 in indicies:
|
||||||
|
if me.vertex_colors and material.vertex_color_paint:
|
||||||
|
# Colour per vertex - vertex colour
|
||||||
|
|
||||||
|
col1 = cols[i1]
|
||||||
|
col2 = cols[i2]
|
||||||
|
col3 = cols[i3]
|
||||||
|
|
||||||
|
ci1 = vertCols[col1[0], col1[1], col1[2], material_index][0]
|
||||||
|
ci2 = vertCols[col2[0], col2[1], col2[2], material_index][0]
|
||||||
|
ci3 = vertCols[col3[0], col3[1], col3[2], material_index][0]
|
||||||
|
else:
|
||||||
|
# Colour per material - flat material colour
|
||||||
|
diffuse_color= material.diffuse_color
|
||||||
|
ci1 = ci2 = ci3 = vertCols[diffuse_color[0], diffuse_color[1], diffuse_color[2], f.material_index][0]
|
||||||
|
|
||||||
|
file.write(',\n\t\t<%d,%d,%d>, %d,%d,%d' % (fv[i1], fv[i2], fv[i3], ci1, ci2, ci3)) # vert count
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
file.write('\n }\n')
|
||||||
|
|
||||||
|
# normal_indices indicies
|
||||||
|
file.write('\tnormal_indices {\n')
|
||||||
|
file.write('\t\t%d' % (len(me.faces) + quadCount)) # faces count
|
||||||
|
for fi, fv in enumerate(faces_verts):
|
||||||
|
|
||||||
|
if len(fv) == 4: indicies = (0,1,2), (0,2,3)
|
||||||
|
else: indicies = ((0,1,2),)
|
||||||
|
|
||||||
|
for i1, i2, i3 in indicies:
|
||||||
|
if f.smooth:
|
||||||
|
file.write(',\n\t\t<%d,%d,%d>' %\
|
||||||
|
(uniqueNormals[verts_normals[fv[i1]]][0],\
|
||||||
|
uniqueNormals[verts_normals[fv[i2]]][0],\
|
||||||
|
uniqueNormals[verts_normals[fv[i3]]][0])) # vert count
|
||||||
|
else:
|
||||||
|
idx = uniqueNormals[faces_normals[fi]][0]
|
||||||
|
file.write(',\n\t\t<%d,%d,%d>' % (idx, idx, idx)) # vert count
|
||||||
|
|
||||||
|
file.write('\n }\n')
|
||||||
|
|
||||||
|
if uv_layer:
|
||||||
|
file.write('\tuv_indices {\n')
|
||||||
|
file.write('\t\t%d' % (len(me.faces) + quadCount)) # faces count
|
||||||
|
for fi, fv in enumerate(faces_verts):
|
||||||
|
|
||||||
|
if len(fv) == 4: indicies = (0,1,2), (0,2,3)
|
||||||
|
else: indicies = ((0,1,2),)
|
||||||
|
|
||||||
|
uv = uv_layer[fi]
|
||||||
|
if len(faces_verts[fi])==4:
|
||||||
|
uvs = tuple(uv.uv1), tuple(uv.uv2), tuple(uv.uv3), tuple(uv.uv4)
|
||||||
|
else:
|
||||||
|
uvs = tuple(uv.uv1), tuple(uv.uv2), tuple(uv.uv3)
|
||||||
|
|
||||||
|
for i1, i2, i3 in indicies:
|
||||||
|
file.write(',\n\t\t<%d,%d,%d>' %\
|
||||||
|
(uniqueUVs[uvs[i1]][0],\
|
||||||
|
uniqueUVs[uvs[i2]][0],\
|
||||||
|
uniqueUVs[uvs[i2]][0])) # vert count
|
||||||
|
file.write('\n }\n')
|
||||||
|
|
||||||
|
if me.materials:
|
||||||
|
material = me.materials[0] # dodgy
|
||||||
|
if material and material.raytrace_transparency.enabled:
|
||||||
|
file.write('\tinterior { ior %.6f }\n' % material.raytrace_transparency.ior)
|
||||||
|
|
||||||
|
writeMatrix(matrix)
|
||||||
|
file.write('}\n')
|
||||||
|
|
||||||
|
bpy.data.remove_mesh(me)
|
||||||
|
|
||||||
|
def exportWorld(world):
|
||||||
|
if not world:
|
||||||
|
return
|
||||||
|
|
||||||
|
mist = world.mist
|
||||||
|
|
||||||
|
if mist.enabled:
|
||||||
|
file.write('fog {\n')
|
||||||
|
file.write('\tdistance %.6f\n' % mist.depth)
|
||||||
|
file.write('\tcolor rgbt<%.3g, %.3g, %.3g, %.3g>\n' % (tuple(world.horizon_color) + (1-mist.intensity,)))
|
||||||
|
#file.write('\tfog_offset %.6f\n' % mist.start)
|
||||||
|
#file.write('\tfog_alt 5\n')
|
||||||
|
#file.write('\tturbulence 0.2\n')
|
||||||
|
#file.write('\tturb_depth 0.3\n')
|
||||||
|
file.write('\tfog_type 1\n')
|
||||||
|
file.write('}\n')
|
||||||
|
|
||||||
|
def exportGlobalSettings(scene):
|
||||||
|
|
||||||
|
file.write('global_settings {\n')
|
||||||
|
|
||||||
|
if scene.pov_radio_enable:
|
||||||
|
file.write('\tradiosity {\n')
|
||||||
|
file.write("\t\tadc_bailout %.4g\n" % scene.pov_radio_adc_bailout)
|
||||||
|
file.write("\t\talways_sample %d\n" % scene.pov_radio_always_sample)
|
||||||
|
file.write("\t\tbrightness %.4g\n" % scene.pov_radio_brightness)
|
||||||
|
file.write("\t\tcount %d\n" % scene.pov_radio_count)
|
||||||
|
file.write("\t\terror_bound %.4g\n" % scene.pov_radio_error_bound)
|
||||||
|
file.write("\t\tgray_threshold %.4g\n" % scene.pov_radio_gray_threshold)
|
||||||
|
file.write("\t\tlow_error_factor %.4g\n" % scene.pov_radio_low_error_factor)
|
||||||
|
file.write("\t\tminimum_reuse %.4g\n" % scene.pov_radio_minimum_reuse)
|
||||||
|
file.write("\t\tnearest_count %d\n" % scene.pov_radio_nearest_count)
|
||||||
|
file.write("\t\tnormal %d\n" % scene.pov_radio_normal)
|
||||||
|
file.write("\t\trecursion_limit %d\n" % scene.pov_radio_recursion_limit)
|
||||||
|
file.write('\t}\n')
|
||||||
|
|
||||||
|
file.write('}\n')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
exportCamera()
|
||||||
|
#exportMaterials()
|
||||||
|
sel = scene.objects
|
||||||
|
lamps = [l for l in sel if l.type == 'LAMP']
|
||||||
|
exportLamps(lamps)
|
||||||
|
exportMeshs(sel)
|
||||||
|
exportWorld(scene.world)
|
||||||
|
exportGlobalSettings(scene)
|
||||||
|
|
||||||
|
file.close()
|
||||||
|
|
||||||
|
|
||||||
|
def write_pov_ini(filename_ini, filename_pov, filename_image):
|
||||||
|
scene = bpy.data.scenes[0]
|
||||||
|
render = scene.render_data
|
||||||
|
|
||||||
|
x= int(render.resolution_x*render.resolution_percentage*0.01)
|
||||||
|
y= int(render.resolution_y*render.resolution_percentage*0.01)
|
||||||
|
|
||||||
|
file = open(filename_ini, 'w')
|
||||||
|
|
||||||
|
file.write('Input_File_Name="%s"\n' % filename_pov)
|
||||||
|
file.write('Output_File_Name="%s"\n' % filename_image)
|
||||||
|
|
||||||
|
file.write('Width=%d\n' % x)
|
||||||
|
file.write('Height=%d\n' % y)
|
||||||
|
|
||||||
|
# Needed for border render.
|
||||||
|
'''
|
||||||
|
file.write('Start_Column=%d\n' % part.x)
|
||||||
|
file.write('End_Column=%d\n' % (part.x+part.w))
|
||||||
|
|
||||||
|
file.write('Start_Row=%d\n' % (part.y))
|
||||||
|
file.write('End_Row=%d\n' % (part.y+part.h))
|
||||||
|
'''
|
||||||
|
|
||||||
|
file.write('Display=0\n')
|
||||||
|
file.write('Pause_When_Done=0\n')
|
||||||
|
file.write('Output_File_Type=C\n') # TGA, best progressive loading
|
||||||
|
file.write('Output_Alpha=1\n')
|
||||||
|
|
||||||
|
if render.antialiasing:
|
||||||
|
aa_mapping = {'OVERSAMPLE_5':2, 'OVERSAMPLE_8':3, 'OVERSAMPLE_11':4, 'OVERSAMPLE_16':5} # method 1 assumed
|
||||||
|
file.write('Antialias=1\n')
|
||||||
|
file.write('Antialias_Depth=%d\n' % aa_mapping[render.antialiasing_samples])
|
||||||
|
else:
|
||||||
|
file.write('Antialias=0\n')
|
||||||
|
|
||||||
|
file.close()
|
||||||
|
|
||||||
|
|
||||||
|
class PovrayRender(bpy.types.RenderEngine):
|
||||||
|
__idname__ = 'POVRAY_RENDER'
|
||||||
|
__label__ = "Povray"
|
||||||
|
DELAY = 0.02
|
||||||
|
def _export(self, scene):
|
||||||
|
import tempfile
|
||||||
|
|
||||||
|
self.temp_file_in = tempfile.mktemp(suffix='.pov')
|
||||||
|
self.temp_file_out = tempfile.mktemp(suffix='.tga')
|
||||||
|
self.temp_file_ini = tempfile.mktemp(suffix='.ini')
|
||||||
|
'''
|
||||||
|
self.temp_file_in = '/test.pov'
|
||||||
|
self.temp_file_out = '/test.tga'
|
||||||
|
self.temp_file_ini = '/test.ini'
|
||||||
|
'''
|
||||||
|
|
||||||
|
def info_callback(txt):
|
||||||
|
self.update_stats("", "POVRAY: " + txt)
|
||||||
|
|
||||||
|
write_pov(self.temp_file_in, scene, info_callback)
|
||||||
|
|
||||||
|
def _render(self):
|
||||||
|
|
||||||
|
try: os.remove(self.temp_file_out) # so as not to load the old file
|
||||||
|
except: pass
|
||||||
|
|
||||||
|
write_pov_ini(self.temp_file_ini, self.temp_file_in, self.temp_file_out)
|
||||||
|
|
||||||
|
print ("***-STARTING-***")
|
||||||
|
# This works too but means we have to wait until its done
|
||||||
|
# os.system('povray %s' % self.temp_file_ini)
|
||||||
|
|
||||||
|
pov_binary = "povray"
|
||||||
|
|
||||||
|
if sys.platform=='win32':
|
||||||
|
if bitness == 64:
|
||||||
|
pov_binary = "pvengine64"
|
||||||
|
else:
|
||||||
|
pov_binary = "pvengine"
|
||||||
|
|
||||||
|
self.process = subprocess.Popen([pov_binary, self.temp_file_ini]) # stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||||
|
|
||||||
|
print ("***-DONE-***")
|
||||||
|
|
||||||
|
def _cleanup(self):
|
||||||
|
for f in (self.temp_file_in, self.temp_file_ini, self.temp_file_out):
|
||||||
|
try: os.remove(f)
|
||||||
|
except: pass
|
||||||
|
|
||||||
|
self.update_stats("", "")
|
||||||
|
|
||||||
|
def render(self, scene):
|
||||||
|
|
||||||
|
self.update_stats("", "POVRAY: Exporting data from Blender")
|
||||||
|
self._export(scene)
|
||||||
|
self.update_stats("", "POVRAY: Parsing File")
|
||||||
|
self._render()
|
||||||
|
|
||||||
|
r = scene.render_data
|
||||||
|
|
||||||
|
# compute resolution
|
||||||
|
x= int(r.resolution_x*r.resolution_percentage*0.01)
|
||||||
|
y= int(r.resolution_y*r.resolution_percentage*0.01)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Wait for the file to be created
|
||||||
|
while not os.path.exists(self.temp_file_out):
|
||||||
|
if self.test_break():
|
||||||
|
try: self.process.terminate()
|
||||||
|
except: pass
|
||||||
|
break
|
||||||
|
|
||||||
|
if self.process.poll() != None:
|
||||||
|
self.update_stats("", "POVRAY: Failed")
|
||||||
|
break
|
||||||
|
|
||||||
|
time.sleep(self.DELAY)
|
||||||
|
|
||||||
|
if os.path.exists(self.temp_file_out):
|
||||||
|
|
||||||
|
self.update_stats("", "POVRAY: Rendering")
|
||||||
|
|
||||||
|
prev_size = -1
|
||||||
|
|
||||||
|
def update_image():
|
||||||
|
result = self.begin_result(0, 0, x, y)
|
||||||
|
lay = result.layers[0]
|
||||||
|
# possible the image wont load early on.
|
||||||
|
try: lay.rect_from_file(self.temp_file_out, 0, 0)
|
||||||
|
except: pass
|
||||||
|
self.end_result(result)
|
||||||
|
|
||||||
|
# Update while povray renders
|
||||||
|
while True:
|
||||||
|
|
||||||
|
# test if povray exists
|
||||||
|
if self.process.poll() != None:
|
||||||
|
update_image();
|
||||||
|
break
|
||||||
|
|
||||||
|
# user exit
|
||||||
|
if self.test_break():
|
||||||
|
try: self.process.terminate()
|
||||||
|
except: pass
|
||||||
|
|
||||||
|
break
|
||||||
|
|
||||||
|
# Would be nice to redirect the output
|
||||||
|
# stdout_value, stderr_value = self.process.communicate() # locks
|
||||||
|
|
||||||
|
|
||||||
|
# check if the file updated
|
||||||
|
new_size = os.path.getsize(self.temp_file_out)
|
||||||
|
|
||||||
|
if new_size != prev_size:
|
||||||
|
update_image()
|
||||||
|
prev_size = new_size
|
||||||
|
|
||||||
|
time.sleep(self.DELAY)
|
||||||
|
|
||||||
|
self._cleanup()
|
||||||
|
|
||||||
|
|
||||||
|
bpy.types.register(PovrayRender)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Use some of the existing buttons.
|
||||||
|
import buttons_scene
|
||||||
|
buttons_scene.SCENE_PT_render.COMPAT_ENGINES.add('POVRAY_RENDER')
|
||||||
|
buttons_scene.SCENE_PT_dimensions.COMPAT_ENGINES.add('POVRAY_RENDER')
|
||||||
|
buttons_scene.SCENE_PT_antialiasing.COMPAT_ENGINES.add('POVRAY_RENDER')
|
||||||
|
buttons_scene.SCENE_PT_output.COMPAT_ENGINES.add('POVRAY_RENDER')
|
||||||
|
del buttons_scene
|
||||||
|
|
||||||
|
# Use only a subset of the world panels
|
||||||
|
import buttons_world
|
||||||
|
buttons_world.WORLD_PT_preview.COMPAT_ENGINES.add('POVRAY_RENDER')
|
||||||
|
buttons_world.WORLD_PT_context_world.COMPAT_ENGINES.add('POVRAY_RENDER')
|
||||||
|
buttons_world.WORLD_PT_world.COMPAT_ENGINES.add('POVRAY_RENDER')
|
||||||
|
buttons_world.WORLD_PT_mist.COMPAT_ENGINES.add('POVRAY_RENDER')
|
||||||
|
del buttons_world
|
||||||
|
|
||||||
|
# Example of wrapping every class 'as is'
|
||||||
|
import buttons_material
|
||||||
|
for member in dir(buttons_material):
|
||||||
|
subclass = getattr(buttons_material, member)
|
||||||
|
try: subclass.COMPAT_ENGINES.add('POVRAY_RENDER')
|
||||||
|
except: pass
|
||||||
|
del buttons_material
|
||||||
|
|
||||||
|
class RenderButtonsPanel(bpy.types.Panel):
|
||||||
|
__space_type__ = "BUTTONS_WINDOW"
|
||||||
|
__region_type__ = "WINDOW"
|
||||||
|
__context__ = "scene"
|
||||||
|
# COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here
|
||||||
|
|
||||||
|
def poll(self, context):
|
||||||
|
rd = context.scene.render_data
|
||||||
|
return (rd.use_game_engine==False) and (rd.engine in self.COMPAT_ENGINES)
|
||||||
|
|
||||||
|
# Radiosity panel, use in the scene for now.
|
||||||
|
class SCENE_PT_povray_radiosity(RenderButtonsPanel):
|
||||||
|
__label__ = "Radiosity"
|
||||||
|
COMPAT_ENGINES = set(['POVRAY_RENDER'])
|
||||||
|
|
||||||
|
def draw_header(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
scene = context.scene
|
||||||
|
layout.itemR(scene, "pov_radio_enable", text="")
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
scene = context.scene
|
||||||
|
rd = scene.render_data
|
||||||
|
|
||||||
|
layout.active = scene.pov_radio_enable
|
||||||
|
|
||||||
|
split = layout.split()
|
||||||
|
|
||||||
|
col = split.column()
|
||||||
|
|
||||||
|
col.itemR(scene, "pov_radio_count")
|
||||||
|
col.itemR(scene, "pov_radio_recursion_limit")
|
||||||
|
col.itemR(scene, "pov_radio_error_bound")
|
||||||
|
|
||||||
|
col.itemR(scene, "pov_radio_display_advanced")
|
||||||
|
|
||||||
|
if scene.pov_radio_display_advanced:
|
||||||
|
col.itemR(scene, "pov_radio_adc_bailout")
|
||||||
|
col.itemR(scene, "pov_radio_brightness")
|
||||||
|
col.itemR(scene, "pov_radio_gray_threshold")
|
||||||
|
col.itemR(scene, "pov_radio_low_error_factor")
|
||||||
|
col.itemR(scene, "pov_radio_minimum_reuse")
|
||||||
|
col.itemR(scene, "pov_radio_nearest_count")
|
||||||
|
col.itemR(scene, "pov_radio_normal")
|
||||||
|
col.itemR(scene, "pov_radio_always_sample")
|
||||||
|
|
||||||
|
|
||||||
|
bpy.types.register(SCENE_PT_povray_radiosity)
|
||||||
|
|
||||||
|
|
||||||
|
FloatProperty= bpy.types.Scene.FloatProperty
|
||||||
|
IntProperty= bpy.types.Scene.IntProperty
|
||||||
|
BoolProperty= bpy.types.Scene.BoolProperty
|
||||||
|
|
||||||
|
# Not a real pov option, just to know if we should write
|
||||||
|
BoolProperty( attr="pov_radio_enable",
|
||||||
|
name="Enable Radiosity",
|
||||||
|
description="Enable povrays radiosity calculation.",
|
||||||
|
default= False)
|
||||||
|
BoolProperty( attr="pov_radio_display_advanced",
|
||||||
|
name="Advanced Options",
|
||||||
|
description="Show advanced options.",
|
||||||
|
default= False)
|
||||||
|
|
||||||
|
# Real pov options
|
||||||
|
FloatProperty( attr="pov_radio_adc_bailout",
|
||||||
|
name="ADC Bailout",
|
||||||
|
description="The adc_bailout for radiosity rays. Use adc_bailout = 0.01 / brightest_ambient_object for good results.",
|
||||||
|
min=0.0, max=1000.0, soft_min=0.0, soft_max=1.0, default= 0.01)
|
||||||
|
|
||||||
|
BoolProperty( attr="pov_radio_always_sample",
|
||||||
|
name="Always Sample",
|
||||||
|
description="Only use the data from the pretrace step and not gather any new samples during the final radiosity pass..",
|
||||||
|
default= True)
|
||||||
|
|
||||||
|
FloatProperty( attr="pov_radio_brightness",
|
||||||
|
name="Brightness",
|
||||||
|
description="Ammount objects are brightened before being returned upwards to the rest of the system.",
|
||||||
|
min=0.0, max=1000.0, soft_min=0.0, soft_max=10.0, default= 1.0)
|
||||||
|
|
||||||
|
IntProperty( attr="pov_radio_count",
|
||||||
|
name="Ray Count",
|
||||||
|
description="number of rays that are sent out whenever a new radiosity value has to be calculated.",
|
||||||
|
min=1, max=1600, default= 35)
|
||||||
|
|
||||||
|
FloatProperty( attr="pov_radio_error_bound",
|
||||||
|
name="Error Bound",
|
||||||
|
description="one of the two main speed/quality tuning values, lower values are more accurate.",
|
||||||
|
min=0.0, max=1000.0, soft_min=0.1, soft_max=10.0, default= 1.8)
|
||||||
|
|
||||||
|
FloatProperty( attr="pov_radio_gray_threshold",
|
||||||
|
name="Gray Threshold",
|
||||||
|
description="one of the two main speed/quality tuning values, lower values are more accurate.",
|
||||||
|
min=0.0, max=1.0, default= 0.0)
|
||||||
|
|
||||||
|
FloatProperty( attr="pov_radio_low_error_factor",
|
||||||
|
name="Low Error Factor",
|
||||||
|
description="If you calculate just enough samples, but no more, you will get an image which has slightly blotchy lighting.",
|
||||||
|
min=0.0, max=1.0, default= 0.5)
|
||||||
|
|
||||||
|
# max_sample - not available yet
|
||||||
|
|
||||||
|
FloatProperty( attr="pov_radio_minimum_reuse",
|
||||||
|
name="Minimum Reuse",
|
||||||
|
description="Fraction of the screen width which sets the minimum radius of reuse for each sample point (At values higher than 2% expect errors).",
|
||||||
|
min=0.0, max=1.0, soft_min=0.1, soft_max=0.1, default= 0.015)
|
||||||
|
|
||||||
|
IntProperty( attr="pov_radio_nearest_count",
|
||||||
|
name="Nearest Count",
|
||||||
|
description="Number of old ambient values blended together to create a new interpolated value.",
|
||||||
|
min=1, max=20, default= 5)
|
||||||
|
|
||||||
|
BoolProperty( attr="pov_radio_normal",
|
||||||
|
name="Normals",
|
||||||
|
description="Radiosity estimation can be affected by normals.",
|
||||||
|
default= False)
|
||||||
|
|
||||||
|
IntProperty( attr="pov_radio_recursion_limit",
|
||||||
|
name="Recursion Limit",
|
||||||
|
description="how many recursion levels are used to calculate the diffuse inter-reflection.",
|
||||||
|
min=1, max=20, default= 3)
|
||||||
@@ -130,12 +130,10 @@ def write(filename, scene, ob, \
|
|||||||
|
|
||||||
|
|
||||||
smooth = f.smooth
|
smooth = f.smooth
|
||||||
# XXX need face normals
|
|
||||||
"""
|
|
||||||
if not smooth:
|
if not smooth:
|
||||||
normal = tuple(f.no)
|
normal = tuple(f.normal)
|
||||||
normal_key = rvec3d(normal)
|
normal_key = rvec3d(normal)
|
||||||
"""
|
|
||||||
if faceUV:
|
if faceUV:
|
||||||
uv = active_uv_layer[i]
|
uv = active_uv_layer[i]
|
||||||
uv = uv.uv1, uv.uv2, uv.uv3, uv.uv4 # XXX - crufty :/
|
uv = uv.uv1, uv.uv2, uv.uv3, uv.uv4 # XXX - crufty :/
|
||||||
@@ -149,12 +147,10 @@ def write(filename, scene, ob, \
|
|||||||
pf= ply_faces[i]
|
pf= ply_faces[i]
|
||||||
for j, vidx in enumerate(f_verts):
|
for j, vidx in enumerate(f_verts):
|
||||||
v = mesh_verts[vidx]
|
v = mesh_verts[vidx]
|
||||||
"""
|
|
||||||
if smooth:
|
if smooth:
|
||||||
normal= tuple(v.no)
|
normal= tuple(v.normal)
|
||||||
normal_key = rvec3d(normal)
|
normal_key = rvec3d(normal)
|
||||||
"""
|
|
||||||
normal_key = None # XXX
|
|
||||||
|
|
||||||
if faceUV:
|
if faceUV:
|
||||||
uvcoord= uv[j][0], 1.0-uv[j][1]
|
uvcoord= uv[j][0], 1.0-uv[j][1]
|
||||||
@@ -240,6 +236,7 @@ class EXPORT_OT_ply(bpy.types.Operator):
|
|||||||
'''
|
'''
|
||||||
Operator documentatuon text, will be used for the operator tooltip and python docs.
|
Operator documentatuon text, will be used for the operator tooltip and python docs.
|
||||||
'''
|
'''
|
||||||
|
__idname__ = "export.ply"
|
||||||
__label__ = "Export PLY"
|
__label__ = "Export PLY"
|
||||||
|
|
||||||
# List of operator properties, the attributes will be assigned
|
# List of operator properties, the attributes will be assigned
|
||||||
|
|||||||
@@ -277,12 +277,17 @@ def read_bvh(file_path, GLOBAL_SCALE=1.0):
|
|||||||
for bvh_node in bvh_nodes.itervalues():
|
for bvh_node in bvh_nodes.itervalues():
|
||||||
|
|
||||||
if not bvh_node.rest_tail_world:
|
if not bvh_node.rest_tail_world:
|
||||||
if len(bvh_node.children)==1:
|
if len(bvh_node.children)==0:
|
||||||
|
# could just fail here, but rare BVH files have childless nodes
|
||||||
|
bvh_node.rest_tail_world = Vector(bvh_node.rest_head_world)
|
||||||
|
bvh_node.rest_tail_local = Vector(bvh_node.rest_head_local)
|
||||||
|
elif len(bvh_node.children)==1:
|
||||||
bvh_node.rest_tail_world= Vector(bvh_node.children[0].rest_head_world)
|
bvh_node.rest_tail_world= Vector(bvh_node.children[0].rest_head_world)
|
||||||
bvh_node.rest_tail_local= Vector(bvh_node.children[0].rest_head_local)
|
bvh_node.rest_tail_local= Vector(bvh_node.children[0].rest_head_local)
|
||||||
else:
|
else:
|
||||||
if not bvh_node.children:
|
# allow this, see above
|
||||||
raise 'error, bvh node has no end and no children. bad file'
|
#if not bvh_node.children:
|
||||||
|
# raise 'error, bvh node has no end and no children. bad file'
|
||||||
|
|
||||||
# Removed temp for now
|
# Removed temp for now
|
||||||
rest_tail_world= Vector(0,0,0)
|
rest_tail_world= Vector(0,0,0)
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
#!BPY
|
#!BPY
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Name: 'Autodesk DXF (.dxf)'
|
Name: 'Autodesk DXF (.dxf/dwg)'
|
||||||
Blender: 249
|
Blender: 249
|
||||||
Group: 'Export'
|
Group: 'Export'
|
||||||
Tooltip: 'Export geometry to DXF/DWG-r12 (Drawing eXchange Format).'
|
Tooltip: 'Export geometry to DXF/DWG-r12 (Drawing eXchange Format).'
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__version__ = "1.34 - 2009.06.08"
|
__version__ = "1.35 - 2009.06.18"
|
||||||
__author__ = "Remigiusz Fiedler (AKA migius)"
|
__author__ = "Remigiusz Fiedler (AKA migius)"
|
||||||
__license__ = "GPL"
|
__license__ = "GPL"
|
||||||
__url__ = "http://wiki.blender.org/index.php/Scripts/Manual/Export/autodesk_dxf"
|
__url__ = "http://wiki.blender.org/index.php/Scripts/Manual/Export/autodesk_dxf"
|
||||||
@@ -31,19 +31,27 @@ IDEAs:
|
|||||||
- HPGL output, usefull for correct scaled printing of 2d drawings
|
- HPGL output, usefull for correct scaled printing of 2d drawings
|
||||||
|
|
||||||
TODO:
|
TODO:
|
||||||
- export dupligroups and dupliverts as blocks (option for the user to decide)
|
- export dupligroups and dupliverts as blocks (as option)
|
||||||
- optimize POLYFACE routine: remove double-vertices
|
- optimize POLYFACE routine: remove double-vertices
|
||||||
- more stable support for X,Y-rotated curves(to POLYLINEs): fix blender negative-matrix.invert()
|
- fix support for X,Y-rotated curves(to POLYLINEs): fix blender negative-matrix.invert()
|
||||||
- support hierarchies: groups, instances, parented structures
|
- support hierarchies: groups, instances, parented structures
|
||||||
- support n/f-gons as POLYFACEs with invisible edges
|
- support n/f-gons as POLYFACEs with invisible edges
|
||||||
- mapping materials to DXF-styles
|
- mapping materials to DXF-styles
|
||||||
- ProgressBar
|
- ProgressBar
|
||||||
|
- export rotation of Camera to VIEW/VPORT
|
||||||
|
- export parented Cameras to VIEW/VPORT
|
||||||
- wip: write drawing extends for automatic view positioning in CAD
|
- wip: write drawing extends for automatic view positioning in CAD
|
||||||
- wip: correct text-objects in persp-projection
|
- wip: fix text-objects in persp-projection
|
||||||
- wip: translate Camera to VPORT/VIEW
|
|
||||||
- wip: translate current 3D-View to *ACTIVE-VPORT
|
- wip: translate current 3D-View to *ACTIVE-VPORT
|
||||||
|
- wip: fix support Include-Duplis, cause not conform with INSERT-method
|
||||||
|
|
||||||
History
|
History
|
||||||
|
v1.35 - 2009.06.18 by migius
|
||||||
|
- export multiple-instances of Curve-Objects as BLOCK/INSERTs
|
||||||
|
- added export Cameras (ortho and persp) to VPORTs, incl. clipping
|
||||||
|
- added export Cameras (ortho and persp) to VIEWs, incl. clipping
|
||||||
|
- export multiple-instances of Mesh-Objects as BLOCK/INSERTs
|
||||||
|
- on start prints dxfLibrary version
|
||||||
v1.34 - 2009.06.08 by migius
|
v1.34 - 2009.06.08 by migius
|
||||||
- export Lamps and Cameras as POINTs
|
- export Lamps and Cameras as POINTs
|
||||||
- export passepartout for perspective projection
|
- export passepartout for perspective projection
|
||||||
@@ -55,7 +63,7 @@ v1.34 - 2009.06.08 by migius
|
|||||||
- support XYmirrored 2d-curves to 2dPOLYLINEs
|
- support XYmirrored 2d-curves to 2dPOLYLINEs
|
||||||
- support thickness and elevation for curve-objects
|
- support thickness and elevation for curve-objects
|
||||||
- fix extrusion 210-code (3d orientation vector)
|
- fix extrusion 210-code (3d orientation vector)
|
||||||
- fix POLYFACE export, synchronized with dxfLibrary.py
|
- fix POLYFACE export, synchronized also dxfLibrary.py
|
||||||
- changed to the new 2.49 method Vector.cross()
|
- changed to the new 2.49 method Vector.cross()
|
||||||
- output style manager (first try)
|
- output style manager (first try)
|
||||||
v1.33 - 2009.05.25 by migius
|
v1.33 - 2009.05.25 by migius
|
||||||
@@ -139,10 +147,16 @@ from Blender import Registry, Object, Mesh, Curve
|
|||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
import dxfLibrary as DXF
|
try:
|
||||||
#reload(DXF)
|
import dxfLibrary as DXF
|
||||||
#reload(dxfLibrary)
|
#reload(DXF)
|
||||||
#from dxfLibrary import *
|
#reload(dxfLibrary)
|
||||||
|
#from dxfLibrary import *
|
||||||
|
except:
|
||||||
|
DXF=None
|
||||||
|
print "DXF-Exporter: error! found no dxfLibrary.py module in Blender script folder"
|
||||||
|
Draw.PupMenu("Error%t|found no dxfLibrary.py module in script folder")
|
||||||
|
|
||||||
|
|
||||||
import math
|
import math
|
||||||
from math import atan, atan2, log10, sin, cos
|
from math import atan, atan2, log10, sin, cos
|
||||||
@@ -152,9 +166,8 @@ from math import atan, atan2, log10, sin, cos
|
|||||||
r2d = 180.0 / math.pi
|
r2d = 180.0 / math.pi
|
||||||
d2r = math.pi / 180.0
|
d2r = math.pi / 180.0
|
||||||
#note: d2r * angle == math.radians(angle)
|
#note: d2r * angle == math.radians(angle)
|
||||||
|
#note: r2d * angle == math.degrees(angle)
|
||||||
|
|
||||||
print '\n\n\n'
|
|
||||||
print 'DXF-Exporter v%s *** start ***' %(__version__) #---------------------
|
|
||||||
|
|
||||||
#DEBUG = True #activates debug mode
|
#DEBUG = True #activates debug mode
|
||||||
|
|
||||||
@@ -170,6 +183,7 @@ SHADOWS = 0 # sun/shadows simulation
|
|||||||
CAMERA = 1 # selected camera index
|
CAMERA = 1 # selected camera index
|
||||||
PERSPECTIVE = 0 # projection (camera) type: perspective, opposite to orthographic
|
PERSPECTIVE = 0 # projection (camera) type: perspective, opposite to orthographic
|
||||||
CAMERAVIEW = 0 # use camera for projection, opposite is 3d-view
|
CAMERAVIEW = 0 # use camera for projection, opposite is 3d-view
|
||||||
|
INSTANCES = 1 # Export instances of Mesh/Curve as BLOCK/INSERTs on/off
|
||||||
APPLY_MODIFIERS = 1
|
APPLY_MODIFIERS = 1
|
||||||
INCLUDE_DUPLIS = 0
|
INCLUDE_DUPLIS = 0
|
||||||
OUTPUT_DWG = 0 #optional save to DWG with extern converter
|
OUTPUT_DWG = 0 #optional save to DWG with extern converter
|
||||||
@@ -187,6 +201,7 @@ LAYERLTYPE_DEF = 0 #'CONTINUOUS' - default layer lineType
|
|||||||
ENTITYLAYER_DEF = LAYERNAME_DEF #default entity color index
|
ENTITYLAYER_DEF = LAYERNAME_DEF #default entity color index
|
||||||
ENTITYCOLOR_DEF = BYLAYER #default entity color index
|
ENTITYCOLOR_DEF = BYLAYER #default entity color index
|
||||||
ENTITYLTYPE_DEF = BYLAYER #default entity lineType
|
ENTITYLTYPE_DEF = BYLAYER #default entity lineType
|
||||||
|
|
||||||
E_M = 0
|
E_M = 0
|
||||||
LAB = "scroll MMB/WHEEL . wip .. todo" #"*) parts under construction"
|
LAB = "scroll MMB/WHEEL . wip .. todo" #"*) parts under construction"
|
||||||
M_OBJ = 0
|
M_OBJ = 0
|
||||||
@@ -198,6 +213,7 @@ INIFILE_EXTENSION = '.ini'
|
|||||||
INIFILE_HEADER = '#ExportDXF.py ver.1.0 config data'
|
INIFILE_HEADER = '#ExportDXF.py ver.1.0 config data'
|
||||||
INFFILE_HEADER = '#ExportDXF.py ver.1.0 analyze of DXF-data'
|
INFFILE_HEADER = '#ExportDXF.py ver.1.0 analyze of DXF-data'
|
||||||
|
|
||||||
|
BLOCKREGISTRY = {} # registry and map for BLOCKs
|
||||||
SCENE = None
|
SCENE = None
|
||||||
WORLDX = Mathutils.Vector((1,0,0))
|
WORLDX = Mathutils.Vector((1,0,0))
|
||||||
WORLDY = Mathutils.Vector((0,1,0))
|
WORLDY = Mathutils.Vector((0,1,0))
|
||||||
@@ -496,22 +512,55 @@ def isLeftHand(matrix):
|
|||||||
def exportMesh(ob, mx, mx_n, me=None, **common):
|
def exportMesh(ob, mx, mx_n, me=None, **common):
|
||||||
"""converts Mesh-Object to desired projection and representation(DXF-Entity type)
|
"""converts Mesh-Object to desired projection and representation(DXF-Entity type)
|
||||||
"""
|
"""
|
||||||
|
global BLOCKREGISTRY
|
||||||
entities = []
|
entities = []
|
||||||
#print 'deb:exportMesh() common=', common #---------
|
block = None
|
||||||
|
#print 'deb:exportMesh() given common=', common #---------
|
||||||
if me==None:
|
if me==None:
|
||||||
me = ob.getData(mesh=1)
|
me = ob.getData(mesh=1)
|
||||||
else:
|
else:
|
||||||
me.getFromObject(ob)
|
me.getFromObject(ob)
|
||||||
# me.transform(mx); get verts data; me.transform(mx_inv)= back to the origin state
|
# idea: me.transform(mx); get verts data; me.transform(mx_inv)= back to the origin state
|
||||||
# above .transform method is faster, but bad, cause invasive:
|
# the .transform-method is fast, but bad, cause invasive:
|
||||||
# it manipulates original geometry and by retransformation lefts back rounding-errors
|
# it manipulates original geometry and by retransformation lefts back rounding-errors
|
||||||
# we dont want to manipulate original data!
|
# we dont want to manipulate original data!
|
||||||
#temp_verts = me.verts[:] #doesn't work on ubuntu(Yorik), bug?
|
#temp_verts = me.verts[:] #doesn't work on ubuntu(Yorik), bug?
|
||||||
if me.verts:
|
if me.verts:
|
||||||
#print 'deb:exportMesh() started' #---------
|
#print 'deb:exportMesh() started' #---------
|
||||||
|
|
||||||
|
#print 'deb:exportMesh() ob.name=', ob.name #---------
|
||||||
|
#print 'deb:exportMesh() me.name=', me.name #---------
|
||||||
|
#print 'deb:exportMesh() me.users=', me.users #---------
|
||||||
|
# check if there are more instances of this mesh (if used by other objects), then write to BLOCK/INSERT
|
||||||
|
if GUI_A['instances_on'].val and me.users>1 and not PROJECTION:
|
||||||
|
if me.name in BLOCKREGISTRY.keys():
|
||||||
|
insert_name = BLOCKREGISTRY[me.name]
|
||||||
|
# write INSERT to entities
|
||||||
|
entities = exportInsert(ob, mx,insert_name, **common)
|
||||||
|
else:
|
||||||
|
# generate geom_output in ObjectCS
|
||||||
|
allpoints = [v.co for v in me.verts]
|
||||||
|
identity_matrix = Mathutils.Matrix().identity()
|
||||||
|
allpoints = projected_co(allpoints, identity_matrix)
|
||||||
|
#allpoints = toGlobalOrigin(allpoints)
|
||||||
|
faces=[]
|
||||||
|
edges=[]
|
||||||
|
for e in me.edges: edges.append(e.key)
|
||||||
|
faces = [[v.index for v in f.verts] for f in me.faces]
|
||||||
|
entities = writeMeshEntities(allpoints, edges, faces, **common)
|
||||||
|
if entities: # if not empty block
|
||||||
|
# write BLOCK definition and INSERT entity
|
||||||
|
# BLOCKREGISTRY = dictionary 'blender_name':'dxf_name'.append(me.name)
|
||||||
|
BLOCKREGISTRY[me.name]=validDXFr12name(('ME_'+ me.name))
|
||||||
|
insert_name = BLOCKREGISTRY[me.name]
|
||||||
|
block = DXF.Block(insert_name,flag=0,base=(0,0,0),entities=entities)
|
||||||
|
# write INSERT as entity
|
||||||
|
entities = exportInsert(ob, mx, insert_name, **common)
|
||||||
|
|
||||||
|
else: # no other instances, so go the standard way
|
||||||
allpoints = [v.co for v in me.verts]
|
allpoints = [v.co for v in me.verts]
|
||||||
allpoints = projected_co(allpoints, mx)
|
allpoints = projected_co(allpoints, mx)
|
||||||
allpoints = toNewOrigin(allpoints)
|
allpoints = toGlobalOrigin(allpoints)
|
||||||
faces=[]
|
faces=[]
|
||||||
edges=[]
|
edges=[]
|
||||||
if me.faces and PROJECTION and HIDDEN_LINES:
|
if me.faces and PROJECTION and HIDDEN_LINES:
|
||||||
@@ -532,6 +581,16 @@ def exportMesh(ob, mx, mx_n, me=None, **common):
|
|||||||
f.reverse()
|
f.reverse()
|
||||||
#f = [f[-1]] + f[:-1] #TODO: might be needed
|
#f = [f[-1]] + f[:-1] #TODO: might be needed
|
||||||
#print 'deb: faces=\n', faces #---------
|
#print 'deb: faces=\n', faces #---------
|
||||||
|
entities = writeMeshEntities(allpoints, edges, faces, **common)
|
||||||
|
|
||||||
|
return entities, block
|
||||||
|
|
||||||
|
|
||||||
|
#-------------------------------------------------
|
||||||
|
def writeMeshEntities(allpoints, edges, faces, **common):
|
||||||
|
"""help routine for exportMesh()
|
||||||
|
"""
|
||||||
|
entities = []
|
||||||
|
|
||||||
c = mesh_as_list[GUI_A['mesh_as'].val]
|
c = mesh_as_list[GUI_A['mesh_as'].val]
|
||||||
if 'POINTs'==c: # export Mesh as multiple POINTs
|
if 'POINTs'==c: # export Mesh as multiple POINTs
|
||||||
@@ -582,6 +641,7 @@ def exportMesh(ob, mx, mx_n, me=None, **common):
|
|||||||
|
|
||||||
return entities
|
return entities
|
||||||
|
|
||||||
|
|
||||||
#-----------------------------------------------------
|
#-----------------------------------------------------
|
||||||
def mesh_drawBlender(vertList, edgeList, faceList, name="dxfMesh", flatten=False, AT_CUR=True, link=True):
|
def mesh_drawBlender(vertList, edgeList, faceList, name="dxfMesh", flatten=False, AT_CUR=True, link=True):
|
||||||
#print 'deb:mesh_drawBlender started XXXXXXXXXXXXXXXXXX' #---------
|
#print 'deb:mesh_drawBlender started XXXXXXXXXXXXXXXXXX' #---------
|
||||||
@@ -640,7 +700,7 @@ def curve_drawBlender(vertList, org_point=[0.0,0.0,0.0], closed=0, name="dxfCurv
|
|||||||
|
|
||||||
|
|
||||||
#-----------------------------------------------------
|
#-----------------------------------------------------
|
||||||
def toNewOrigin(points):
|
def toGlobalOrigin(points):
|
||||||
"""relocates points to the new location
|
"""relocates points to the new location
|
||||||
needs a list of points [x,y,z]
|
needs a list of points [x,y,z]
|
||||||
"""
|
"""
|
||||||
@@ -658,7 +718,7 @@ def exportEmpty(ob, mx, mw, **common):
|
|||||||
"""
|
"""
|
||||||
p = Mathutils.Vector(ob.loc)
|
p = Mathutils.Vector(ob.loc)
|
||||||
[p] = projected_co([p], mx)
|
[p] = projected_co([p], mx)
|
||||||
[p] = toNewOrigin([p])
|
[p] = toGlobalOrigin([p])
|
||||||
|
|
||||||
entities = []
|
entities = []
|
||||||
c = empty_as_list[GUI_A['empty_as'].val]
|
c = empty_as_list[GUI_A['empty_as'].val]
|
||||||
@@ -671,16 +731,50 @@ def exportEmpty(ob, mx, mw, **common):
|
|||||||
def exportCamera(ob, mx, mw, **common):
|
def exportCamera(ob, mx, mw, **common):
|
||||||
"""converts Camera-Object to desired projection and representation(DXF-Entity type)
|
"""converts Camera-Object to desired projection and representation(DXF-Entity type)
|
||||||
"""
|
"""
|
||||||
p = Mathutils.Vector(ob.loc)
|
location = Mathutils.Vector(ob.loc)
|
||||||
[p] = projected_co([p], mx)
|
[location] = projected_co([location], mx)
|
||||||
[p] = toNewOrigin([p])
|
[location] = toGlobalOrigin([location])
|
||||||
|
view_name=validDXFr12name(('CAM_'+ ob.name))
|
||||||
|
|
||||||
entities = []
|
camera = Camera.Get(ob.getData(name_only=True))
|
||||||
|
#print 'deb: camera=', dir(camera) #------------------
|
||||||
|
if camera.type=='persp':
|
||||||
|
mode = 1+2+4+16
|
||||||
|
# mode flags: 1=persp, 2=frontclip, 4=backclip,16=FrontZ
|
||||||
|
elif camera.type=='ortho':
|
||||||
|
mode = 0+2+4+16
|
||||||
|
|
||||||
|
leftBottom=(0.0,0.0) # default
|
||||||
|
rightTop=(1.0,1.0) # default
|
||||||
|
center=(0.0,0.0) # default
|
||||||
|
|
||||||
|
direction = Mathutils.Vector(0.0,0.0,1.0) * mx.rotationPart() # in W-C-S
|
||||||
|
direction.normalize()
|
||||||
|
target=Mathutils.Vector(ob.loc) - direction # in W-C-S
|
||||||
|
#ratio=1.0
|
||||||
|
width=height= camera.scale # for ortho-camera
|
||||||
|
lens = camera.lens # for persp-camera
|
||||||
|
frontClipping = -(camera.clipStart - 1.0)
|
||||||
|
backClipping = -(camera.clipEnd - 1.0)
|
||||||
|
|
||||||
|
entities, vport, view = [], None, None
|
||||||
c = camera_as_list[GUI_A['camera_as'].val]
|
c = camera_as_list[GUI_A['camera_as'].val]
|
||||||
if c=="POINT": # export as POINT
|
if c=="POINT": # export as POINT
|
||||||
dxfPOINT = DXF.Point(points=[p],**common)
|
dxfPOINT = DXF.Point(points=[location],**common)
|
||||||
entities.append(dxfPOINT)
|
entities.append(dxfPOINT)
|
||||||
return entities
|
elif c=="VIEW": # export as VIEW
|
||||||
|
view = DXF.View(name=view_name,
|
||||||
|
center=center, width=width, height=height,
|
||||||
|
frontClipping=frontClipping,backClipping=backClipping,
|
||||||
|
direction=direction,target=target,lens=lens,mode=mode
|
||||||
|
)
|
||||||
|
elif c=="VPORT": # export as VPORT
|
||||||
|
vport = DXF.VPort(name=view_name,
|
||||||
|
center=center, ratio=1.0, height=height,
|
||||||
|
frontClipping=frontClipping,backClipping=backClipping,
|
||||||
|
direction=direction,target=target,lens=lens,mode=mode
|
||||||
|
)
|
||||||
|
return entities, vport, view
|
||||||
|
|
||||||
#-----------------------------------------------------
|
#-----------------------------------------------------
|
||||||
def exportLamp(ob, mx, mw, **common):
|
def exportLamp(ob, mx, mw, **common):
|
||||||
@@ -688,7 +782,7 @@ def exportLamp(ob, mx, mw, **common):
|
|||||||
"""
|
"""
|
||||||
p = Mathutils.Vector(ob.loc)
|
p = Mathutils.Vector(ob.loc)
|
||||||
[p] = projected_co([p], mx)
|
[p] = projected_co([p], mx)
|
||||||
[p] = toNewOrigin([p])
|
[p] = toGlobalOrigin([p])
|
||||||
|
|
||||||
entities = []
|
entities = []
|
||||||
c = lamp_as_list[GUI_A['lamp_as'].val]
|
c = lamp_as_list[GUI_A['lamp_as'].val]
|
||||||
@@ -697,6 +791,75 @@ def exportLamp(ob, mx, mw, **common):
|
|||||||
entities.append(dxfPOINT)
|
entities.append(dxfPOINT)
|
||||||
return entities
|
return entities
|
||||||
|
|
||||||
|
#-----------------------------------------------------
|
||||||
|
def exportInsert(ob, mx, insert_name, **common):
|
||||||
|
"""converts Object to DXF-INSERT in given orientation
|
||||||
|
"""
|
||||||
|
WCS_loc = ob.loc # WCS_loc is object location in WorldCoordSystem
|
||||||
|
sizeX = ob.SizeX
|
||||||
|
sizeY = ob.SizeY
|
||||||
|
sizeZ = ob.SizeZ
|
||||||
|
rotX = ob.RotX
|
||||||
|
rotY = ob.RotY
|
||||||
|
rotZ = ob.RotZ
|
||||||
|
#print 'deb: sizeX=%s, sizeY=%s' %(sizeX, sizeY) #---------
|
||||||
|
|
||||||
|
Thickness,Extrusion,ZRotation,Elevation = None,None,None,None
|
||||||
|
|
||||||
|
AXaxis = mx[0].copy().resize3D() # = ArbitraryXvector
|
||||||
|
if not PROJECTION:
|
||||||
|
#Extrusion, ZRotation, Elevation = getExtrusion(mx)
|
||||||
|
Extrusion, AXaxis = getExtrusion(mx)
|
||||||
|
|
||||||
|
entities = []
|
||||||
|
|
||||||
|
if 1:
|
||||||
|
if not PROJECTION:
|
||||||
|
ZRotation,Zrotmatrix,OCS_origin,ECS_origin = getTargetOrientation(mx,Extrusion,\
|
||||||
|
AXaxis,WCS_loc,sizeX,sizeY,sizeZ,rotX,rotY,rotZ)
|
||||||
|
ZRotation *= r2d
|
||||||
|
point = ECS_origin
|
||||||
|
else: #TODO: fails correct location
|
||||||
|
point1 = Mathutils.Vector(ob.loc)
|
||||||
|
[point] = projected_co([point1], mx)
|
||||||
|
if PERSPECTIVE:
|
||||||
|
clipStart = 10.0
|
||||||
|
coef = -clipStart / (point1*mx)[2]
|
||||||
|
#print 'deb: coef=', coef #--------------
|
||||||
|
#TODO: ? sizeX *= coef
|
||||||
|
#sizeY *= coef
|
||||||
|
#sizeZ *= coef
|
||||||
|
|
||||||
|
#print 'deb: point=', point #--------------
|
||||||
|
[point] = toGlobalOrigin([point])
|
||||||
|
|
||||||
|
#if DEBUG: text_drawBlender(textstr,points,OCS_origin) #deb: draw to scene
|
||||||
|
common['extrusion']= Extrusion
|
||||||
|
#common['elevation']= Elevation
|
||||||
|
#print 'deb: common=', common #------------------
|
||||||
|
if 0: #DEBUG
|
||||||
|
#linepoints = [[0,0,0], [AXaxis[0],AXaxis[1],AXaxis[2]]]
|
||||||
|
linepoints = [[0,0,0], point]
|
||||||
|
dxfLINE = DXF.Line(linepoints,**common)
|
||||||
|
entities.append(dxfLINE)
|
||||||
|
|
||||||
|
xscale=sizeX
|
||||||
|
yscale=sizeY
|
||||||
|
zscale=sizeZ
|
||||||
|
cols=None
|
||||||
|
colspacing=None
|
||||||
|
rows=None
|
||||||
|
rowspacing=None
|
||||||
|
|
||||||
|
dxfINSERT = DXF.Insert(insert_name,point=point,rotation=ZRotation,\
|
||||||
|
xscale=xscale,yscale=yscale,zscale=zscale,\
|
||||||
|
cols=cols,colspacing=colspacing,rows=rows,rowspacing=rowspacing,\
|
||||||
|
**common)
|
||||||
|
entities.append(dxfINSERT)
|
||||||
|
|
||||||
|
return entities
|
||||||
|
|
||||||
|
|
||||||
#-----------------------------------------------------
|
#-----------------------------------------------------
|
||||||
def exportText(ob, mx, mw, **common):
|
def exportText(ob, mx, mw, **common):
|
||||||
"""converts Text-Object to desired projection and representation(DXF-Entity type)
|
"""converts Text-Object to desired projection and representation(DXF-Entity type)
|
||||||
@@ -755,7 +918,7 @@ def exportText(ob, mx, mw, **common):
|
|||||||
#print 'deb: coef=', coef #--------------
|
#print 'deb: coef=', coef #--------------
|
||||||
|
|
||||||
#print 'deb: point=', point #--------------
|
#print 'deb: point=', point #--------------
|
||||||
[point] = toNewOrigin([point])
|
[point] = toGlobalOrigin([point])
|
||||||
point2 = point
|
point2 = point
|
||||||
|
|
||||||
#if DEBUG: text_drawBlender(textstr,points,OCS_origin) #deb: draw to scene
|
#if DEBUG: text_drawBlender(textstr,points,OCS_origin) #deb: draw to scene
|
||||||
@@ -835,9 +998,55 @@ def exportCurve(ob, mx, mw, **common):
|
|||||||
"""converts Curve-Object to desired projection and representation(DXF-Entity type)
|
"""converts Curve-Object to desired projection and representation(DXF-Entity type)
|
||||||
"""
|
"""
|
||||||
entities = []
|
entities = []
|
||||||
|
block = None
|
||||||
curve = ob.getData()
|
curve = ob.getData()
|
||||||
|
#print 'deb: curve=', dir(curve) #---------
|
||||||
|
# TODO: should be: if curve.users>1 and not (PERSPECTIVE or (PROJECTION and HIDDEN_MODE):
|
||||||
|
if GUI_A['instances_on'].val and curve.users>1 and not PROJECTION:
|
||||||
|
if curve.name in BLOCKREGISTRY.keys():
|
||||||
|
insert_name = BLOCKREGISTRY[curve.name]
|
||||||
|
# write INSERT to entities
|
||||||
|
entities = exportInsert(ob, mx,insert_name, **common)
|
||||||
|
else:
|
||||||
|
# generate geom_output in ObjectCS
|
||||||
|
imx = Mathutils.Matrix().identity()
|
||||||
|
WCS_loc = [0,0,0] # WCS_loc is object location in WorldCoordSystem
|
||||||
|
#print 'deb: WCS_loc=', WCS_loc #---------
|
||||||
|
sizeX = sizeY = sizeZ = 1.0
|
||||||
|
rotX = rotY = rotZ = 0.0
|
||||||
|
Thickness,Extrusion,ZRotation,Elevation = None,None,None,None
|
||||||
|
ZRotation,Zrotmatrix,OCS_origin,ECS_origin = None,None,None,None
|
||||||
|
AXaxis = imx[0].copy().resize3D() # = ArbitraryXvector
|
||||||
|
OCS_origin = [0,0,0]
|
||||||
|
if not PROJECTION:
|
||||||
|
#Extrusion, ZRotation, Elevation = getExtrusion(mx)
|
||||||
|
Extrusion, AXaxis = getExtrusion(imx)
|
||||||
|
|
||||||
|
# no thickness/width for POLYLINEs converted into Screen-C-S
|
||||||
|
#print 'deb: curve.ext1=', curve.ext1 #---------
|
||||||
|
if curve.ext1: Thickness = curve.ext1 * sizeZ
|
||||||
|
if curve.ext2 and sizeX==sizeY:
|
||||||
|
Width = curve.ext2 * sizeX
|
||||||
|
if "POLYLINE"==curve_as_list[GUI_A['curve_as'].val]: # export as POLYLINE
|
||||||
|
ZRotation,Zrotmatrix,OCS_origin,ECS_origin = getTargetOrientation(imx,Extrusion,\
|
||||||
|
AXaxis,WCS_loc,sizeX,sizeY,sizeZ,rotX,rotY,rotZ)
|
||||||
|
|
||||||
|
entities = writeCurveEntities(curve, imx,
|
||||||
|
Thickness,Extrusion,ZRotation,Elevation,AXaxis,Zrotmatrix,
|
||||||
|
WCS_loc,OCS_origin,ECS_origin,sizeX,sizeY,sizeZ,
|
||||||
|
**common)
|
||||||
|
|
||||||
|
if entities: # if not empty block
|
||||||
|
# write BLOCK definition and INSERT entity
|
||||||
|
# BLOCKREGISTRY = dictionary 'blender_name':'dxf_name'.append(me.name)
|
||||||
|
BLOCKREGISTRY[curve.name]=validDXFr12name(('CU_'+ curve.name))
|
||||||
|
insert_name = BLOCKREGISTRY[curve.name]
|
||||||
|
block = DXF.Block(insert_name,flag=0,base=(0,0,0),entities=entities)
|
||||||
|
# write INSERT as entity
|
||||||
|
entities = exportInsert(ob, mx, insert_name, **common)
|
||||||
|
|
||||||
|
else: # no other instances, so go the standard way
|
||||||
WCS_loc = ob.loc # WCS_loc is object location in WorldCoordSystem
|
WCS_loc = ob.loc # WCS_loc is object location in WorldCoordSystem
|
||||||
#WCS_loc = [0.0,0.0,0.0]
|
|
||||||
#print 'deb: WCS_loc=', WCS_loc #---------
|
#print 'deb: WCS_loc=', WCS_loc #---------
|
||||||
sizeX = ob.SizeX
|
sizeX = ob.SizeX
|
||||||
sizeY = ob.SizeY
|
sizeY = ob.SizeY
|
||||||
@@ -848,13 +1057,14 @@ def exportCurve(ob, mx, mw, **common):
|
|||||||
#print 'deb: sizeX=%s, sizeY=%s' %(sizeX, sizeY) #---------
|
#print 'deb: sizeX=%s, sizeY=%s' %(sizeX, sizeY) #---------
|
||||||
|
|
||||||
Thickness,Extrusion,ZRotation,Elevation = None,None,None,None
|
Thickness,Extrusion,ZRotation,Elevation = None,None,None,None
|
||||||
|
ZRotation,Zrotmatrix,OCS_origin,ECS_origin = None,None,None,None
|
||||||
AXaxis = mx[0].copy().resize3D() # = ArbitraryXvector
|
AXaxis = mx[0].copy().resize3D() # = ArbitraryXvector
|
||||||
OCS_origin = [0,0,0]
|
OCS_origin = [0,0,0]
|
||||||
if not PROJECTION:
|
if not PROJECTION:
|
||||||
#Extrusion, ZRotation, Elevation = getExtrusion(mx)
|
#Extrusion, ZRotation, Elevation = getExtrusion(mx)
|
||||||
Extrusion, AXaxis = getExtrusion(mx)
|
Extrusion, AXaxis = getExtrusion(mx)
|
||||||
|
|
||||||
# no thickness/width for POLYLINEs converted into ScreenCS
|
# no thickness/width for POLYLINEs converted into Screen-C-S
|
||||||
#print 'deb: curve.ext1=', curve.ext1 #---------
|
#print 'deb: curve.ext1=', curve.ext1 #---------
|
||||||
if curve.ext1: Thickness = curve.ext1 * sizeZ
|
if curve.ext1: Thickness = curve.ext1 * sizeZ
|
||||||
if curve.ext2 and sizeX==sizeY:
|
if curve.ext2 and sizeX==sizeY:
|
||||||
@@ -862,7 +1072,24 @@ def exportCurve(ob, mx, mw, **common):
|
|||||||
if "POLYLINE"==curve_as_list[GUI_A['curve_as'].val]: # export as POLYLINE
|
if "POLYLINE"==curve_as_list[GUI_A['curve_as'].val]: # export as POLYLINE
|
||||||
ZRotation,Zrotmatrix,OCS_origin,ECS_origin = getTargetOrientation(mx,Extrusion,\
|
ZRotation,Zrotmatrix,OCS_origin,ECS_origin = getTargetOrientation(mx,Extrusion,\
|
||||||
AXaxis,WCS_loc,sizeX,sizeY,sizeZ,rotX,rotY,rotZ)
|
AXaxis,WCS_loc,sizeX,sizeY,sizeZ,rotX,rotY,rotZ)
|
||||||
|
entities = writeCurveEntities(curve, mx,
|
||||||
|
Thickness,Extrusion,ZRotation,Elevation,AXaxis,Zrotmatrix,
|
||||||
|
WCS_loc,OCS_origin,ECS_origin,sizeX,sizeY,sizeZ,
|
||||||
|
**common)
|
||||||
|
|
||||||
|
return entities, block
|
||||||
|
|
||||||
|
|
||||||
|
#-------------------------------------------------
|
||||||
|
def writeCurveEntities(curve, mx,
|
||||||
|
Thickness,Extrusion,ZRotation,Elevation,AXaxis,Zrotmatrix,
|
||||||
|
WCS_loc,OCS_origin,ECS_origin,sizeX,sizeY,sizeZ,
|
||||||
|
**common):
|
||||||
|
"""help routine for exportCurve()
|
||||||
|
"""
|
||||||
|
entities = []
|
||||||
|
|
||||||
|
if 1:
|
||||||
for cur in curve:
|
for cur in curve:
|
||||||
#print 'deb: START cur=', cur #--------------
|
#print 'deb: START cur=', cur #--------------
|
||||||
points = []
|
points = []
|
||||||
@@ -903,9 +1130,10 @@ def exportCurve(ob, mx, mw, **common):
|
|||||||
|
|
||||||
if cur.isCyclic(): closed = 1
|
if cur.isCyclic(): closed = 1
|
||||||
else: closed = 0
|
else: closed = 0
|
||||||
points = toNewOrigin(points)
|
points = toGlobalOrigin(points)
|
||||||
|
|
||||||
if DEBUG: curve_drawBlender(points,OCS_origin,closed) #deb: draw to scene
|
if DEBUG: curve_drawBlender(points,OCS_origin,closed) #deb: draw to scene
|
||||||
|
|
||||||
common['extrusion']= Extrusion
|
common['extrusion']= Extrusion
|
||||||
##common['rotation']= ZRotation
|
##common['rotation']= ZRotation
|
||||||
##common['elevation']= Elevation
|
##common['elevation']= Elevation
|
||||||
@@ -935,7 +1163,7 @@ def exportCurve(ob, mx, mw, **common):
|
|||||||
points = projected_co(points, mx)
|
points = projected_co(points, mx)
|
||||||
if cur.isCyclic(): points.append(points[0])
|
if cur.isCyclic(): points.append(points[0])
|
||||||
#print 'deb: points', points #--------------
|
#print 'deb: points', points #--------------
|
||||||
points = toNewOrigin(points)
|
points = toGlobalOrigin(points)
|
||||||
|
|
||||||
if DEBUG: curve_drawBlender(points,WCS_loc,closed) #deb: draw to scene
|
if DEBUG: curve_drawBlender(points,WCS_loc,closed) #deb: draw to scene
|
||||||
common['extrusion']= Extrusion
|
common['extrusion']= Extrusion
|
||||||
@@ -958,9 +1186,9 @@ def exportCurve(ob, mx, mw, **common):
|
|||||||
for p in points:
|
for p in points:
|
||||||
dxfPOINT = DXF.Point(points=[p],**common)
|
dxfPOINT = DXF.Point(points=[p],**common)
|
||||||
entities.append(dxfPOINT)
|
entities.append(dxfPOINT)
|
||||||
|
|
||||||
return entities
|
return entities
|
||||||
|
|
||||||
|
|
||||||
#-----------------------------------------------------
|
#-----------------------------------------------------
|
||||||
def getClipBox(camera):
|
def getClipBox(camera):
|
||||||
"""calculates Field-of-View-Clipping-Box of given Camera
|
"""calculates Field-of-View-Clipping-Box of given Camera
|
||||||
@@ -1075,12 +1303,12 @@ def drawClipBox(clip_box):
|
|||||||
verts.append([max_X2, max_Y2, max_Z])
|
verts.append([max_X2, max_Y2, max_Z])
|
||||||
verts.append([min_X2, max_Y2, max_Z])
|
verts.append([min_X2, max_Y2, max_Z])
|
||||||
faces = [[0,1,2,3],[4,5,6,7]]
|
faces = [[0,1,2,3],[4,5,6,7]]
|
||||||
nme = Mesh.New()
|
newmesh = Mesh.New()
|
||||||
nme.verts.extend(verts)
|
newmesh.verts.extend(verts)
|
||||||
nme.faces.extend(faces)
|
newmesh.faces.extend(faces)
|
||||||
|
|
||||||
plan = Object.New('Mesh','clip_box')
|
plan = Object.New('Mesh','clip_box')
|
||||||
plan.link(nme)
|
plan.link(newmesh)
|
||||||
sce = Scene.GetCurrent()
|
sce = Scene.GetCurrent()
|
||||||
sce.objects.link(plan)
|
sce.objects.link(plan)
|
||||||
plan.setMatrix(sce.objects.camera.matrix)
|
plan.setMatrix(sce.objects.camera.matrix)
|
||||||
@@ -1170,19 +1398,35 @@ def getCommons(ob):
|
|||||||
|
|
||||||
#-----------------------------------------------------
|
#-----------------------------------------------------
|
||||||
def do_export(export_list, filepath):
|
def do_export(export_list, filepath):
|
||||||
global PERSPECTIVE, CAMERAVIEW
|
global PERSPECTIVE, CAMERAVIEW, BLOCKREGISTRY
|
||||||
Window.WaitCursor(1)
|
Window.WaitCursor(1)
|
||||||
t = Blender.sys.time()
|
t = Blender.sys.time()
|
||||||
|
|
||||||
# init Drawing ---------------------
|
# init Drawing ---------------------
|
||||||
d=DXF.Drawing()
|
d=DXF.Drawing()
|
||||||
# add Tables -----------------
|
# add Tables -----------------
|
||||||
#d.blocks.append(b) #table blocks
|
# initialized automatic: d.blocks.append(b) #section BLOCKS
|
||||||
#goes automatic: d.styles.append(DXF.Style()) #table styles
|
# initialized automatic: d.styles.append(DXF.Style()) #table STYLE
|
||||||
|
|
||||||
|
#table LTYPE ---------------
|
||||||
|
#d.linetypes.append(DXF.LineType(name='CONTINUOUS',description='--------',elements=[0.0]))
|
||||||
|
d.linetypes.append(DXF.LineType(name='DOT',description='. . . . . . .',elements=[0.25, 0.0, -0.25]))
|
||||||
|
d.linetypes.append(DXF.LineType(name='DASHED',description='__ __ __ __ __',elements=[0.8, 0.5, -0.3]))
|
||||||
|
d.linetypes.append(DXF.LineType(name='DASHDOT',description='__ . __ . __ .',elements=[1.0, 0.5, -0.25, 0.0, -0.25]))
|
||||||
|
d.linetypes.append(DXF.LineType(name='DIVIDE',description='____ . . ____ . . ',elements=[1.25, 0.5, -0.25, 0.0, -0.25, 0.0, -0.25]))
|
||||||
|
d.linetypes.append(DXF.LineType(name='BORDER',description='__ __ . __ __ . ',elements=[1.75, 0.5, -0.25, 0.5, -0.25, 0.0, -0.25]))
|
||||||
|
d.linetypes.append(DXF.LineType(name='HIDDEN',description='__ __ __ __ __',elements=[0.4, 0.25, -0.25]))
|
||||||
|
d.linetypes.append(DXF.LineType(name='CENTER',description='____ _ ____ _ __',elements=[2.0, 1.25, -0.25, 0.25, -0.25]))
|
||||||
|
|
||||||
|
#d.vports.append(DXF.VPort('*ACTIVE'))
|
||||||
|
d.vports.append(DXF.VPort('*ACTIVE',center=(-5.0,1.0),height=10.0))
|
||||||
|
#d.vports.append(DXF.VPort('*ACTIVE',leftBottom=(-100.0,-60.0),rightTop=(100.0,60.0)))
|
||||||
#d.views.append(DXF.View('Normal')) #table view
|
#d.views.append(DXF.View('Normal')) #table view
|
||||||
d.views.append(DXF.ViewByWindow('BF_TOPVIEW',leftBottom=(-100,-60),rightTop=(100,60))) #idem
|
d.views.append(DXF.ViewByWindow('BF_TOPVIEW',leftBottom=(-100,-60),rightTop=(100,60))) #idem
|
||||||
|
|
||||||
# add Entities --------------------
|
# add Entities --------------------
|
||||||
|
BLOCKREGISTRY = {} # registry and map for BLOCKs
|
||||||
|
PERSPECTIVE = 0
|
||||||
something_ready = 0
|
something_ready = 0
|
||||||
selected_len = len(export_list)
|
selected_len = len(export_list)
|
||||||
sce = Scene.GetCurrent()
|
sce = Scene.GetCurrent()
|
||||||
@@ -1246,9 +1490,10 @@ def do_export(export_list, filepath):
|
|||||||
layernames = []
|
layernames = []
|
||||||
for ob,mx in export_list:
|
for ob,mx in export_list:
|
||||||
entities = []
|
entities = []
|
||||||
|
block = None
|
||||||
#mx = ob.matrix.copy()
|
#mx = ob.matrix.copy()
|
||||||
#print 'deb: ob =', ob #---------
|
#print 'deb: ob =', ob #---------
|
||||||
print 'deb: ob.type =', ob.type #---------
|
#print 'deb: ob.type =', ob.type #---------
|
||||||
#print 'deb: mx =\n', mx #---------
|
#print 'deb: mx =\n', mx #---------
|
||||||
#print 'deb: mw0 =\n', mw0 #---------
|
#print 'deb: mw0 =\n', mw0 #---------
|
||||||
#mx_n is trans-matrix for normal_vectors for front-side faces
|
#mx_n is trans-matrix for normal_vectors for front-side faces
|
||||||
@@ -1274,10 +1519,10 @@ def do_export(export_list, filepath):
|
|||||||
d.layers.append(DXF.Layer(color=tempcolor, name=elayer))
|
d.layers.append(DXF.Layer(color=tempcolor, name=elayer))
|
||||||
|
|
||||||
if (ob.type == 'Mesh') and GUI_B['bmesh'].val:
|
if (ob.type == 'Mesh') and GUI_B['bmesh'].val:
|
||||||
entities = exportMesh(ob, mx, mx_n, tmp_me,\
|
entities, block = exportMesh(ob, mx, mx_n, tmp_me,\
|
||||||
paperspace=espace, color=ecolor, layer=elayer, lineType=eltype)
|
paperspace=espace, color=ecolor, layer=elayer, lineType=eltype)
|
||||||
elif (ob.type == 'Curve') and GUI_B['bcurve'].val:
|
elif (ob.type == 'Curve') and GUI_B['bcurve'].val:
|
||||||
entities = exportCurve(ob, mx, mw, \
|
entities, block = exportCurve(ob, mx, mw, \
|
||||||
paperspace=espace, color=ecolor, layer=elayer, lineType=eltype)
|
paperspace=espace, color=ecolor, layer=elayer, lineType=eltype)
|
||||||
elif (ob.type == 'Empty') and GUI_B['empty'].val:
|
elif (ob.type == 'Empty') and GUI_B['empty'].val:
|
||||||
entities = exportEmpty(ob, mx, mw, \
|
entities = exportEmpty(ob, mx, mw, \
|
||||||
@@ -1286,8 +1531,10 @@ def do_export(export_list, filepath):
|
|||||||
entities = exportText(ob, mx, mw, \
|
entities = exportText(ob, mx, mw, \
|
||||||
paperspace=espace, color=ecolor, layer=elayer, lineType=eltype)
|
paperspace=espace, color=ecolor, layer=elayer, lineType=eltype)
|
||||||
elif (ob.type == 'Camera') and GUI_B['camera'].val:
|
elif (ob.type == 'Camera') and GUI_B['camera'].val:
|
||||||
entities = exportCamera(ob, mx, mw, \
|
entities, vport, view = exportCamera(ob, mx, mw, \
|
||||||
paperspace=espace, color=ecolor, layer=elayer, lineType=eltype)
|
paperspace=espace, color=ecolor, layer=elayer, lineType=eltype)
|
||||||
|
if vport: d.vports.append(vport)
|
||||||
|
if view: d.views.append(view)
|
||||||
elif (ob.type == 'Lamp') and GUI_B['lamp'].val:
|
elif (ob.type == 'Lamp') and GUI_B['lamp'].val:
|
||||||
entities = exportLamp(ob, mx, mw, \
|
entities = exportLamp(ob, mx, mw, \
|
||||||
paperspace=espace, color=ecolor, layer=elayer, lineType=eltype)
|
paperspace=espace, color=ecolor, layer=elayer, lineType=eltype)
|
||||||
@@ -1297,13 +1544,23 @@ def do_export(export_list, filepath):
|
|||||||
for e in entities:
|
for e in entities:
|
||||||
d.append(e)
|
d.append(e)
|
||||||
|
|
||||||
if something_ready:
|
if block:
|
||||||
if PERSPECTIVE: # draw view border
|
d.blocks.append(block) #add to BLOCK-section
|
||||||
mw2 = Mathutils.Matrix().identity()
|
|
||||||
points = projected_co(border, mw2)
|
|
||||||
closed = 1
|
|
||||||
points = toNewOrigin(points)
|
|
||||||
|
|
||||||
|
|
||||||
|
if something_ready:
|
||||||
|
if PERSPECTIVE: # generate view border - passepartout
|
||||||
|
identity_matrix = Mathutils.Matrix().identity()
|
||||||
|
points = projected_co(border, identity_matrix)
|
||||||
|
closed = 1
|
||||||
|
points = toGlobalOrigin(points)
|
||||||
|
c = curve_as_list[GUI_A['curve_as'].val]
|
||||||
|
if c=="LINEs": # export Curve as multiple LINEs
|
||||||
|
for i in range(len(points)-1):
|
||||||
|
linepoints = [points[i], points[i+1]]
|
||||||
|
dxfLINE = DXF.Line(linepoints,paperspace=espace,color=LAYERCOLOR_DEF)
|
||||||
|
entities.append(dxfLINE)
|
||||||
|
else:
|
||||||
dxfPLINE = DXF.PolyLine(points,points[0],closed,\
|
dxfPLINE = DXF.PolyLine(points,points[0],closed,\
|
||||||
paperspace=espace, color=LAYERCOLOR_DEF)
|
paperspace=espace, color=LAYERCOLOR_DEF)
|
||||||
d.append(dxfPLINE)
|
d.append(dxfPLINE)
|
||||||
@@ -1573,7 +1830,7 @@ parent_as_menu = prepareMenu("export to: %t", parent_as_list)
|
|||||||
proxy_as_list = ["..BLOCK","..XREF","..ungroup","..POINT"]
|
proxy_as_list = ["..BLOCK","..XREF","..ungroup","..POINT"]
|
||||||
proxy_as_menu = prepareMenu("export to: %t", proxy_as_list)
|
proxy_as_menu = prepareMenu("export to: %t", proxy_as_list)
|
||||||
|
|
||||||
camera_as_list = ["..BLOCK","..A_CAMERA","..VPORT","..VIEW","POINT"]
|
camera_as_list = ["..BLOCK","..A_CAMERA","VPORT","VIEW","POINT"]
|
||||||
camera_as_menu = prepareMenu("export to: %t", camera_as_list)
|
camera_as_menu = prepareMenu("export to: %t", camera_as_list)
|
||||||
|
|
||||||
lamp_as_list = ["..BLOCK","..A_LAMP","POINT"]
|
lamp_as_list = ["..BLOCK","..A_LAMP","POINT"]
|
||||||
@@ -1655,6 +1912,7 @@ keywords_org = {
|
|||||||
'outputDWG_on' : OUTPUT_DWG,
|
'outputDWG_on' : OUTPUT_DWG,
|
||||||
'to_polyline_on': POLYLINES,
|
'to_polyline_on': POLYLINES,
|
||||||
'to_polyface_on': POLYFACES,
|
'to_polyface_on': POLYFACES,
|
||||||
|
'instances_on': INSTANCES,
|
||||||
'apply_modifiers_on': APPLY_MODIFIERS,
|
'apply_modifiers_on': APPLY_MODIFIERS,
|
||||||
'include_duplis_on': INCLUDE_DUPLIS,
|
'include_duplis_on': INCLUDE_DUPLIS,
|
||||||
'camera_selected': CAMERA,
|
'camera_selected': CAMERA,
|
||||||
@@ -1691,7 +1949,7 @@ keywords_org = {
|
|||||||
'group_as' : 0,
|
'group_as' : 0,
|
||||||
'parent_as' : 0,
|
'parent_as' : 0,
|
||||||
'proxy_as' : 0,
|
'proxy_as' : 0,
|
||||||
'camera_as': 4,
|
'camera_as': 3,
|
||||||
'lamp_as' : 2,
|
'lamp_as' : 2,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2066,7 +2324,7 @@ def draw_UI(): #---------------------------------------------------------------
|
|||||||
but_3c = common_column #button 3.column
|
but_3c = common_column #button 3.column
|
||||||
menu_w = (3 * butt_margin) + but_0c + but_1c + but_2c + but_3c #menu width
|
menu_w = (3 * butt_margin) + but_0c + but_1c + but_2c + but_3c #menu width
|
||||||
|
|
||||||
simple_menu_h = 240
|
simple_menu_h = 260
|
||||||
extend_menu_h = 345
|
extend_menu_h = 345
|
||||||
menu_h = simple_menu_h # y is menu upper.y
|
menu_h = simple_menu_h # y is menu upper.y
|
||||||
if config_UI.val:
|
if config_UI.val:
|
||||||
@@ -2359,6 +2617,11 @@ def draw_UI(): #---------------------------------------------------------------
|
|||||||
GUI_A['to_polyline_on'] = Draw.Toggle('POLYLINE-Mode', EVENT_PRESETPLINE, b0, y, b0_, 20, GUI_A['to_polyline_on'].val, "Export to POLYLINE/POLYFACEs, otherwise to LINEs/3DFACEs on/off")
|
GUI_A['to_polyline_on'] = Draw.Toggle('POLYLINE-Mode', EVENT_PRESETPLINE, b0, y, b0_, 20, GUI_A['to_polyline_on'].val, "Export to POLYLINE/POLYFACEs, otherwise to LINEs/3DFACEs on/off")
|
||||||
#b0, b0_ = but2c, but_2c + butt_margin + but_3c
|
#b0, b0_ = but2c, but_2c + butt_margin + but_3c
|
||||||
|
|
||||||
|
y -= 20
|
||||||
|
b0, b0_ = but0c, but_0c + butt_margin +but_1c
|
||||||
|
GUI_A['instances_on'] = Draw.Toggle('Instances as BLOCKs', EVENT_NONE, b0, y, b0_, 20, GUI_A['instances_on'].val, "Export instances (multi-users) of Mesh/Curve as BLOCK/INSERTs on/off")
|
||||||
|
#b0, b0_ = but2c, but_2c + butt_margin + but_3c
|
||||||
|
|
||||||
y -= 20
|
y -= 20
|
||||||
b0, b0_ = but0c, but_0c + butt_margin +but_1c
|
b0, b0_ = but0c, but_0c + butt_margin +but_1c
|
||||||
GUI_A['apply_modifiers_on'] = Draw.Toggle('Apply Modifiers', EVENT_NONE, b0, y, b0_, 20, GUI_A['apply_modifiers_on'].val, "Apply modifier stack to mesh objects before export on/off")
|
GUI_A['apply_modifiers_on'] = Draw.Toggle('Apply Modifiers', EVENT_NONE, b0, y, b0_, 20, GUI_A['apply_modifiers_on'].val, "Apply modifier stack to mesh objects before export on/off")
|
||||||
@@ -2750,8 +3013,14 @@ def multi_export(DIR): #TODO:
|
|||||||
#-----------------------------------------------------
|
#-----------------------------------------------------
|
||||||
if __name__=='__main__':
|
if __name__=='__main__':
|
||||||
|
|
||||||
|
if DXF:
|
||||||
|
print '\n\n\n'
|
||||||
|
print 'DXF-Exporter v%s *** start ***' %(__version__) #---------------------
|
||||||
|
print 'with Library %s' %(DXF.__version__) #---------------------
|
||||||
if not DXF.copy:
|
if not DXF.copy:
|
||||||
Draw.PupMenu('Error%t|The dxfLibrary.py script requires a full python install')
|
print "DXF-Exporter: dxfLibrary.py script requires a full Python install"
|
||||||
|
Draw.PupMenu('Error%t|The dxfLibrary.py script requires a full Python install')
|
||||||
|
else:
|
||||||
#Window.FileSelector(dxf_export_ui, 'EXPORT DXF', Blender.sys.makename(ext='.dxf'))
|
#Window.FileSelector(dxf_export_ui, 'EXPORT DXF', Blender.sys.makename(ext='.dxf'))
|
||||||
# recall last used DXF-file and INI-file names
|
# recall last used DXF-file and INI-file names
|
||||||
dxffilename = check_RegistryKey('dxfFileName')
|
dxffilename = check_RegistryKey('dxfFileName')
|
||||||
|
|||||||
@@ -1464,7 +1464,7 @@ def write(filename, batch_objects = None, \
|
|||||||
|
|
||||||
# Write Edge Smoothing
|
# Write Edge Smoothing
|
||||||
file.write('''
|
file.write('''
|
||||||
LayerElementSmoothing: 0 {
|
LayerElementSmoothing: 1 {
|
||||||
Version: 101
|
Version: 101
|
||||||
Name: ""
|
Name: ""
|
||||||
MappingInformationType: "ByEdge"
|
MappingInformationType: "ByEdge"
|
||||||
|
|||||||
@@ -2,14 +2,14 @@
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
Name: 'Quake 3 (.map)'
|
Name: 'Quake 3 (.map)'
|
||||||
Blender: 243
|
Blender: 249
|
||||||
Group: 'Export'
|
Group: 'Export'
|
||||||
Tooltip: 'Export to Quake map format'
|
Tooltip: 'Export to Quake map format'
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__author__ = 'Campbell Barton'
|
__author__ = 'Campbell Barton'
|
||||||
__version__ = '0.1'
|
__version__ = '0.1a'
|
||||||
__email__ = "cbarton@metavr.com"
|
__email__ = "ideasman42@gmail.com"
|
||||||
__bpydoc__ = """\
|
__bpydoc__ = """\
|
||||||
This script Exports a Quake 3 map format.
|
This script Exports a Quake 3 map format.
|
||||||
|
|
||||||
@@ -234,7 +234,7 @@ def write_node_map(file, ob):
|
|||||||
as a MAP node as long as it has the property name - classname
|
as a MAP node as long as it has the property name - classname
|
||||||
returns True/False based on weather a node was written
|
returns True/False based on weather a node was written
|
||||||
'''
|
'''
|
||||||
props= [(p.name, p.data) for p in ob.properties]
|
props= [(p.name, p.data) for p in ob.game_properties]
|
||||||
|
|
||||||
IS_MAP_NODE= False
|
IS_MAP_NODE= False
|
||||||
for name, value in props:
|
for name, value in props:
|
||||||
@@ -287,7 +287,7 @@ def export_map(filepath):
|
|||||||
TOTBRUSH= TOTLAMP= TOTNODE= 0
|
TOTBRUSH= TOTLAMP= TOTNODE= 0
|
||||||
|
|
||||||
for ob in Object.GetSelected():
|
for ob in Object.GetSelected():
|
||||||
type= ob.getType()
|
type= ob.type
|
||||||
if type == 'Mesh': obs_mesh.append(ob)
|
if type == 'Mesh': obs_mesh.append(ob)
|
||||||
elif type == 'Surf': obs_surf.append(ob)
|
elif type == 'Surf': obs_surf.append(ob)
|
||||||
elif type == 'Lamp': obs_lamp.append(ob)
|
elif type == 'Lamp': obs_lamp.append(ob)
|
||||||
@@ -408,6 +408,7 @@ NULL
|
|||||||
print "NOT EXPORTING PATCH", surf_name, u,v, 'Unsupported'
|
print "NOT EXPORTING PATCH", surf_name, u,v, 'Unsupported'
|
||||||
|
|
||||||
|
|
||||||
|
if obs_mesh or obs_surf:
|
||||||
file.write('}\n') # end worldspan
|
file.write('}\n') # end worldspan
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2,14 +2,14 @@
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
Name: 'Wavefront (.obj)...'
|
Name: 'Wavefront (.obj)...'
|
||||||
Blender: 248
|
Blender: 249
|
||||||
Group: 'Export'
|
Group: 'Export'
|
||||||
Tooltip: 'Save a Wavefront OBJ File'
|
Tooltip: 'Save a Wavefront OBJ File'
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__author__ = "Campbell Barton, Jiri Hnidek, Paolo Ciccone"
|
__author__ = "Campbell Barton, Jiri Hnidek, Paolo Ciccone"
|
||||||
__url__ = ['http://wiki.blender.org/index.php/Scripts/Manual/Export/wavefront_obj', 'www.blender.org', 'blenderartists.org']
|
__url__ = ['http://wiki.blender.org/index.php/Scripts/Manual/Export/wavefront_obj', 'www.blender.org', 'blenderartists.org']
|
||||||
__version__ = "1.21"
|
__version__ = "1.22"
|
||||||
|
|
||||||
__bpydoc__ = """\
|
__bpydoc__ = """\
|
||||||
This script is an exporter to OBJ file format.
|
This script is an exporter to OBJ file format.
|
||||||
@@ -23,11 +23,11 @@ will be exported as mesh data.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------------
|
|
||||||
# OBJ Export v1.1 by Campbell Barton (AKA Ideasman)
|
|
||||||
# --------------------------------------------------------------------------
|
|
||||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
#
|
#
|
||||||
|
# Script copyright (C) Campbell J Barton 2007-2009
|
||||||
|
# - V1.22- bspline import/export added (funded by PolyDimensions GmbH)
|
||||||
|
#
|
||||||
# This program is free software; you can redistribute it and/or
|
# This program is free software; you can redistribute it and/or
|
||||||
# modify it under the terms of the GNU General Public License
|
# modify it under the terms of the GNU General Public License
|
||||||
# as published by the Free Software Foundation; either version 2
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ Group: 'Import'
|
|||||||
Tooltip: 'Import for DWG/DXF geometry data.'
|
Tooltip: 'Import for DWG/DXF geometry data.'
|
||||||
"""
|
"""
|
||||||
__author__ = 'Kitsu(Ed Blake) & migius(Remigiusz Fiedler)'
|
__author__ = 'Kitsu(Ed Blake) & migius(Remigiusz Fiedler)'
|
||||||
__version__ = '1.12 - 2009.05.27 by migius'
|
__version__ = '1.12 - 2009.06.16 by migius'
|
||||||
__url__ = ["http://blenderartists.org/forum/showthread.php?t=84319",
|
__url__ = ["http://blenderartists.org/forum/showthread.php?t=84319",
|
||||||
"http://wiki.blender.org/index.php/Scripts/Manual/Import/DXF-3D"]
|
"http://wiki.blender.org/index.php/Scripts/Manual/Import/DXF-3D"]
|
||||||
__email__ = ["migius(at)4d-vectors.de","Kitsune_e(at)yahoo.com"]
|
__email__ = ["migius(at)4d-vectors.de","Kitsune_e(at)yahoo.com"]
|
||||||
@@ -100,7 +100,7 @@ History:
|
|||||||
-- better support for long dxf-layer-names
|
-- better support for long dxf-layer-names
|
||||||
-- add configuration file.ini handles multiple material setups
|
-- add configuration file.ini handles multiple material setups
|
||||||
-- added f_layerFilter
|
-- added f_layerFilter
|
||||||
-- to-check: obj/mat/group/_mapping-idea from ideasman42:
|
-- to-check: obj/mat/group/_mapping-idea from ideasman42
|
||||||
-- curves: added "fill/non-fill" option for closed curves: CIRCLEs,ELLIPSEs,POLYLINEs
|
-- curves: added "fill/non-fill" option for closed curves: CIRCLEs,ELLIPSEs,POLYLINEs
|
||||||
-- "normalize Z" option to correct non-planar figures
|
-- "normalize Z" option to correct non-planar figures
|
||||||
-- LINEs need "width" in 3d-space incl vGroups
|
-- LINEs need "width" in 3d-space incl vGroups
|
||||||
@@ -108,11 +108,13 @@ History:
|
|||||||
-- add better support for color_index BYLAYER=256, BYBLOCK=0
|
-- add better support for color_index BYLAYER=256, BYBLOCK=0
|
||||||
-- bug: "oneMesh" produces irregularly errors
|
-- bug: "oneMesh" produces irregularly errors
|
||||||
-- bug: Registry recall from hd_cache ?? only win32 bug??
|
-- bug: Registry recall from hd_cache ?? only win32 bug??
|
||||||
-- support DXF-definitions of scene, lights and cameras
|
-- support DXF-definitions of autoshade: scene, lights and cameras
|
||||||
-- support ortho mode for VIEWs and VPORTs as cameras
|
-- support ortho mode for VIEWs and VPORTs as cameras
|
||||||
|
|
||||||
|
v1.12 - 2009.06.16 by migius
|
||||||
|
d7 fix for ignored BLOCKs (e.g. *X) which are members of other BLOCKs
|
||||||
v1.12 - 2009.05.27 by migius
|
v1.12 - 2009.05.27 by migius
|
||||||
d6 todo: bugfix negative scaled INSERTs - isLeftHand(Matrix) check
|
d6 bugfix negative scaled INSERTs - isLeftHand(Matrix) check
|
||||||
v1.12 - 2009.05.26 by migius
|
v1.12 - 2009.05.26 by migius
|
||||||
d5 changed to the new 2.49 method Vector.cross()
|
d5 changed to the new 2.49 method Vector.cross()
|
||||||
d5 bugfix WORLDY(1,1,0) to (0,1,0)
|
d5 bugfix WORLDY(1,1,0) to (0,1,0)
|
||||||
@@ -161,7 +163,7 @@ History:
|
|||||||
a4 added to analyzeTool: report about VIEWs, VPORTs, unused/xref BLOCKs
|
a4 added to analyzeTool: report about VIEWs, VPORTs, unused/xref BLOCKs
|
||||||
a4 bugfix: individual support for 2D/3DPOLYLINE/POLYMESH
|
a4 bugfix: individual support for 2D/3DPOLYLINE/POLYMESH
|
||||||
a4 added to UI: (*wip)BLOCK-(F): name filtering for BLOCKs
|
a4 added to UI: (*wip)BLOCK-(F): name filtering for BLOCKs
|
||||||
a4 added to UI: BLOCK-(n): filter anoname/hatch BLOCKs *X...
|
a4 added to UI: BLOCK-(n): filter noname/hatch BLOCKs *X...
|
||||||
a2 g_scale_as is no more GUI_A-variable
|
a2 g_scale_as is no more GUI_A-variable
|
||||||
a2 bugfix "material": negative sign color_index
|
a2 bugfix "material": negative sign color_index
|
||||||
a2 added support for BLOCKs defined with origin !=(0,0,0)
|
a2 added support for BLOCKs defined with origin !=(0,0,0)
|
||||||
@@ -4520,7 +4522,7 @@ def getBlocksmap(drawing, layersmap, layFrozen_on=False): #--------------------
|
|||||||
item2str = [item2.name, item2.layer]
|
item2str = [item2.name, item2.layer]
|
||||||
childList.append(item2str)
|
childList.append(item2str)
|
||||||
try: usedblocks[item.name] = [used, childList]
|
try: usedblocks[item.name] = [used, childList]
|
||||||
except KeyError: print 'Cannot map "%s" - "%s" as Block!' %(item.name, item)
|
except KeyError: print 'Cannot find "%s" Block!' %(item.name)
|
||||||
#print 'deb:getBlocksmap: usedblocks=' , usedblocks #-------------
|
#print 'deb:getBlocksmap: usedblocks=' , usedblocks #-------------
|
||||||
#print 'deb:getBlocksmap: layersmap=' , layersmap #-------------
|
#print 'deb:getBlocksmap: layersmap=' , layersmap #-------------
|
||||||
|
|
||||||
@@ -4528,7 +4530,7 @@ def getBlocksmap(drawing, layersmap, layFrozen_on=False): #--------------------
|
|||||||
if type(item) != list and item.type == 'insert':
|
if type(item) != list and item.type == 'insert':
|
||||||
if not layersmap or (not layersmap[item.layer].frozen or layFrozen_on): #if insert_layer is not frozen
|
if not layersmap or (not layersmap[item.layer].frozen or layFrozen_on): #if insert_layer is not frozen
|
||||||
try: usedblocks[item.name][0] = True
|
try: usedblocks[item.name][0] = True
|
||||||
except: pass
|
except KeyError: print 'Cannot find "%s" Block!' %(item.name)
|
||||||
|
|
||||||
key_list = usedblocks.keys()
|
key_list = usedblocks.keys()
|
||||||
key_list.reverse()
|
key_list.reverse()
|
||||||
@@ -4536,7 +4538,8 @@ def getBlocksmap(drawing, layersmap, layFrozen_on=False): #--------------------
|
|||||||
if usedblocks[key][0]: #if parent used, then set used also all child blocks
|
if usedblocks[key][0]: #if parent used, then set used also all child blocks
|
||||||
for child in usedblocks[key][1]:
|
for child in usedblocks[key][1]:
|
||||||
if not layersmap or (layersmap and not layersmap[child[1]].frozen): #if insert_layer is not frozen
|
if not layersmap or (layersmap and not layersmap[child[1]].frozen): #if insert_layer is not frozen
|
||||||
usedblocks[child[0]][0] = True # marked as used BLOCK
|
try: usedblocks[child[0]][0] = True # marked as used BLOCK
|
||||||
|
except KeyError: print 'Cannot find "%s" Block!' %(child[0])
|
||||||
|
|
||||||
usedblocks = [i for i in usedblocks.keys() if usedblocks[i][0]]
|
usedblocks = [i for i in usedblocks.keys() if usedblocks[i][0]]
|
||||||
#print 'deb:getBlocksmap: usedblocks=' , usedblocks #-------------
|
#print 'deb:getBlocksmap: usedblocks=' , usedblocks #-------------
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ Tooltip: 'Load a Wavefront OBJ File, Shift: batch import all dir.'
|
|||||||
|
|
||||||
__author__= "Campbell Barton", "Jiri Hnidek", "Paolo Ciccone"
|
__author__= "Campbell Barton", "Jiri Hnidek", "Paolo Ciccone"
|
||||||
__url__= ['http://wiki.blender.org/index.php/Scripts/Manual/Import/wavefront_obj', 'blender.org', 'blenderartists.org']
|
__url__= ['http://wiki.blender.org/index.php/Scripts/Manual/Import/wavefront_obj', 'blender.org', 'blenderartists.org']
|
||||||
__version__= "2.11"
|
__version__= "2.13"
|
||||||
|
|
||||||
__bpydoc__= """\
|
__bpydoc__= """\
|
||||||
This script imports a Wavefront OBJ files to Blender.
|
This script imports a Wavefront OBJ files to Blender.
|
||||||
@@ -21,7 +21,8 @@ Note, This loads mesh objects and materials only, nurbs and curves are not suppo
|
|||||||
|
|
||||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
#
|
#
|
||||||
# Script copyright (C) Campbell J Barton 2007
|
# Script copyright (C) Campbell J Barton 2007-2009
|
||||||
|
# - V2.12- bspline import/export added (funded by PolyDimensions GmbH)
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or
|
# This program is free software; you can redistribute it and/or
|
||||||
# modify it under the terms of the GNU General Public License
|
# modify it under the terms of the GNU General Public License
|
||||||
@@ -125,6 +126,16 @@ def create_materials(filepath, material_libs, unique_materials, unique_material_
|
|||||||
has_data = image.has_data
|
has_data = image.has_data
|
||||||
texture.image = image
|
texture.image = image
|
||||||
|
|
||||||
|
if not has_data:
|
||||||
|
try:
|
||||||
|
# first time using this image. We need to load it first
|
||||||
|
image.glLoad()
|
||||||
|
except:
|
||||||
|
# probably the image is crashed
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
has_data = image.has_data
|
||||||
|
|
||||||
# Adds textures for materials (rendering)
|
# Adds textures for materials (rendering)
|
||||||
if type == 'Kd':
|
if type == 'Kd':
|
||||||
if has_data and image.depth == 32:
|
if has_data and image.depth == 32:
|
||||||
@@ -207,6 +218,7 @@ def create_materials(filepath, material_libs, unique_materials, unique_material_
|
|||||||
context_material.setIOR( max(1, min(float(line_split[1]), 3))) # Between 1 and 3
|
context_material.setIOR( max(1, min(float(line_split[1]), 3))) # Between 1 and 3
|
||||||
elif line_lower.startswith('d') or line_lower.startswith('tr'):
|
elif line_lower.startswith('d') or line_lower.startswith('tr'):
|
||||||
context_material.setAlpha(float(line_split[1]))
|
context_material.setAlpha(float(line_split[1]))
|
||||||
|
context_material.mode |= Material.Modes.ZTRANSP
|
||||||
elif line_lower.startswith('map_ka'):
|
elif line_lower.startswith('map_ka'):
|
||||||
img_filepath= line_value(line.split())
|
img_filepath= line_value(line.split())
|
||||||
if img_filepath:
|
if img_filepath:
|
||||||
|
|||||||
@@ -38,13 +38,13 @@ def my_object_util(sce):
|
|||||||
Draw.PupMenu('Error%t|No active object selected')
|
Draw.PupMenu('Error%t|No active object selected')
|
||||||
return
|
return
|
||||||
|
|
||||||
mats = [ob.matrixWorld for ob in sce.objects.context if ob != ob_act]
|
mats = [(ob, ob.matrixWorld) for ob in sce.objects.context if ob != ob_act]
|
||||||
|
|
||||||
for m in mats:
|
for ob, m in mats:
|
||||||
ob_copy = ob_act.copy()
|
ob_copy = ob_act.copy()
|
||||||
sce.objects.link(ob_copy)
|
sce.objects.link(ob_copy)
|
||||||
ob_copy.setMatrix(m)
|
ob_copy.setMatrix(m)
|
||||||
ob_copy.Layers = ob.Layers
|
ob_copy.Layers = ob.Layers & (1<<20)-1
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ import bpy
|
|||||||
import BPyMesh
|
import BPyMesh
|
||||||
|
|
||||||
|
|
||||||
def vertexFakeAO(me, PREF_BLUR_ITERATIONS, PREF_BLUR_RADIUS, PREF_MIN_EDLEN, PREF_CLAMP_CONCAVE, PREF_CLAMP_CONVEX, PREF_SHADOW_ONLY, PREF_SEL_ONLY):
|
def vertexFakeAO(me, PREF_BLUR_ITERATIONS, PREF_BLUR_STRENGTH, PREF_CLAMP_CONCAVE, PREF_CLAMP_CONVEX, PREF_SHADOW_ONLY, PREF_SEL_ONLY):
|
||||||
Window.WaitCursor(1)
|
Window.WaitCursor(1)
|
||||||
Ang= Mathutils.AngleBetweenVecs
|
Ang= Mathutils.AngleBetweenVecs
|
||||||
|
|
||||||
@@ -84,31 +84,33 @@ def vertexFakeAO(me, PREF_BLUR_ITERATIONS, PREF_BLUR_RADIUS, PREF_MIN_EDLEN, PRE
|
|||||||
vert_tone[i] = vert_tone[i] / vert_tone_count[i]
|
vert_tone[i] = vert_tone[i] / vert_tone_count[i]
|
||||||
|
|
||||||
|
|
||||||
# BLUR TONE
|
# Below we use edges to blur along so the edges need counting, not the faces
|
||||||
edge_lengths= [ ed.length for ed in me.edges]
|
vert_tone_count= [0] * len(me.verts)
|
||||||
|
for ed in me.edges:
|
||||||
|
vert_tone_count[ed.v1.index] += 1
|
||||||
|
vert_tone_count[ed.v2.index] += 1
|
||||||
|
|
||||||
|
|
||||||
|
# Blur tone
|
||||||
|
blur = PREF_BLUR_STRENGTH
|
||||||
|
blur_inv = 1.0 - PREF_BLUR_STRENGTH
|
||||||
|
|
||||||
for i in xrange(PREF_BLUR_ITERATIONS):
|
for i in xrange(PREF_BLUR_ITERATIONS):
|
||||||
|
|
||||||
|
# backup the original tones
|
||||||
orig_vert_tone= list(vert_tone)
|
orig_vert_tone= list(vert_tone)
|
||||||
for ii, ed in enumerate(me.edges):
|
|
||||||
|
for ed in me.edges:
|
||||||
|
|
||||||
i1= ed.v1.index
|
i1= ed.v1.index
|
||||||
i2= ed.v2.index
|
i2= ed.v2.index
|
||||||
l= edge_lengths[ii]
|
|
||||||
|
|
||||||
f=1.0
|
val1= (orig_vert_tone[i2]*blur) + (orig_vert_tone[i1]*blur_inv)
|
||||||
if l > PREF_MIN_EDLEN and l < PREF_BLUR_RADIUS:
|
val2= (orig_vert_tone[i1]*blur) + (orig_vert_tone[i2]*blur_inv)
|
||||||
f= l/PREF_BLUR_RADIUS
|
|
||||||
|
|
||||||
len_vert_tone_list_i1 = vert_tone_count[i1]
|
# Apply the ton divided by the number of faces connected
|
||||||
len_vert_tone_list_i2 = vert_tone_count[i2]
|
vert_tone[i1]+= val1 / max(vert_tone_count[i1], 1)
|
||||||
|
vert_tone[i2]+= val2 / max(vert_tone_count[i2], 1)
|
||||||
if not len_vert_tone_list_i1: len_vert_tone_list_i1=1
|
|
||||||
if not len_vert_tone_list_i2: len_vert_tone_list_i2=1
|
|
||||||
|
|
||||||
val1= (orig_vert_tone[i2]/len_vert_tone_list_i1)/ f
|
|
||||||
val2= (orig_vert_tone[i1]/len_vert_tone_list_i2)/ f
|
|
||||||
|
|
||||||
vert_tone[i1]+= val1
|
|
||||||
vert_tone[i2]+= val2
|
|
||||||
|
|
||||||
|
|
||||||
min_tone= min(vert_tone)
|
min_tone= min(vert_tone)
|
||||||
@@ -145,20 +147,18 @@ def main():
|
|||||||
me= ob.getData(mesh=1)
|
me= ob.getData(mesh=1)
|
||||||
|
|
||||||
PREF_BLUR_ITERATIONS= Draw.Create(1)
|
PREF_BLUR_ITERATIONS= Draw.Create(1)
|
||||||
PREF_BLUR_RADIUS= Draw.Create(0.05)
|
PREF_BLUR_STRENGTH= Draw.Create(0.5)
|
||||||
PREF_MIN_EDLEN= Draw.Create(0.01)
|
|
||||||
PREF_CLAMP_CONCAVE= Draw.Create(90)
|
PREF_CLAMP_CONCAVE= Draw.Create(90)
|
||||||
PREF_CLAMP_CONVEX= Draw.Create(20)
|
PREF_CLAMP_CONVEX= Draw.Create(20)
|
||||||
PREF_SHADOW_ONLY= Draw.Create(0)
|
PREF_SHADOW_ONLY= Draw.Create(0)
|
||||||
PREF_SEL_ONLY= Draw.Create(0)
|
PREF_SEL_ONLY= Draw.Create(0)
|
||||||
pup_block= [\
|
pup_block= [\
|
||||||
'Post AO Blur',\
|
'Post AO Blur',\
|
||||||
(' Iterations:', PREF_BLUR_ITERATIONS, 0, 40, 'Number times to blur the colors. (higher blurs more)'),\
|
('Strength:', PREF_BLUR_STRENGTH, 0, 1, 'Blur strength per iteration'),\
|
||||||
(' Blur Radius:', PREF_BLUR_RADIUS, 0.01, 40.0, 'How much distance effects blur transfur (higher blurs more).'),\
|
('Iterations:', PREF_BLUR_ITERATIONS, 0, 40, 'Number times to blur the colors. (higher blurs more)'),\
|
||||||
(' Min EdgeLen:', PREF_MIN_EDLEN, 0.00001, 1.0, 'Minimim edge length to blur (very low values can cause errors).'),\
|
|
||||||
'Angle Clipping',\
|
'Angle Clipping',\
|
||||||
(' Highlight Angle:', PREF_CLAMP_CONVEX, 0, 180, 'Less then 180 limits the angle used in the tonal range.'),\
|
('Highlight Angle:', PREF_CLAMP_CONVEX, 0, 180, 'Less then 180 limits the angle used in the tonal range.'),\
|
||||||
(' Shadow Angle:', PREF_CLAMP_CONCAVE, 0, 180, 'Less then 180 limits the angle used in the tonal range.'),\
|
('Shadow Angle:', PREF_CLAMP_CONCAVE, 0, 180, 'Less then 180 limits the angle used in the tonal range.'),\
|
||||||
('Shadow Only', PREF_SHADOW_ONLY, 'Dont calculate highlights for convex areas.'),\
|
('Shadow Only', PREF_SHADOW_ONLY, 'Dont calculate highlights for convex areas.'),\
|
||||||
('Sel Faces Only', PREF_SEL_ONLY, 'Only apply to UV/Face selected faces (mix vpain/uvface select).'),\
|
('Sel Faces Only', PREF_SEL_ONLY, 'Only apply to UV/Face selected faces (mix vpain/uvface select).'),\
|
||||||
]
|
]
|
||||||
@@ -166,19 +166,16 @@ def main():
|
|||||||
if not Draw.PupBlock('SelfShadow...', pup_block):
|
if not Draw.PupBlock('SelfShadow...', pup_block):
|
||||||
return
|
return
|
||||||
|
|
||||||
PREF_BLUR_ITERATIONS= PREF_BLUR_ITERATIONS.val
|
|
||||||
PREF_BLUR_RADIUS= PREF_BLUR_RADIUS.val
|
|
||||||
PREF_MIN_EDLEN= PREF_MIN_EDLEN.val
|
|
||||||
PREF_CLAMP_CONCAVE= PREF_CLAMP_CONCAVE.val
|
|
||||||
PREF_CLAMP_CONVEX= PREF_CLAMP_CONVEX.val
|
|
||||||
PREF_SHADOW_ONLY= PREF_SHADOW_ONLY.val
|
|
||||||
PREF_SEL_ONLY= PREF_SEL_ONLY.val
|
|
||||||
|
|
||||||
if not me.vertexColors:
|
if not me.vertexColors:
|
||||||
me.vertexColors= 1
|
me.vertexColors= 1
|
||||||
|
|
||||||
t= sys.time()
|
t= sys.time()
|
||||||
vertexFakeAO(me, PREF_BLUR_ITERATIONS, PREF_BLUR_RADIUS, PREF_MIN_EDLEN, PREF_CLAMP_CONCAVE, PREF_CLAMP_CONVEX, PREF_SHADOW_ONLY, PREF_SEL_ONLY)
|
vertexFakeAO(me, PREF_BLUR_ITERATIONS.val, \
|
||||||
|
PREF_BLUR_STRENGTH.val, \
|
||||||
|
PREF_CLAMP_CONCAVE.val, \
|
||||||
|
PREF_CLAMP_CONVEX.val, \
|
||||||
|
PREF_SHADOW_ONLY.val, \
|
||||||
|
PREF_SEL_ONLY.val)
|
||||||
|
|
||||||
if ob.modifiers:
|
if ob.modifiers:
|
||||||
me.update()
|
me.update()
|
||||||
|
|||||||
113
release/ui/bpy_ops.py
Normal file
113
release/ui/bpy_ops.py
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
# for slightly faster access
|
||||||
|
from bpy.__ops__ import add as op_add
|
||||||
|
from bpy.__ops__ import remove as op_remove
|
||||||
|
from bpy.__ops__ import dir as op_dir
|
||||||
|
from bpy.__ops__ import call as op_call
|
||||||
|
from bpy.__ops__ import get_rna as op_get_rna
|
||||||
|
|
||||||
|
class bpy_ops(object):
|
||||||
|
'''
|
||||||
|
Fake module like class.
|
||||||
|
|
||||||
|
bpy.ops
|
||||||
|
'''
|
||||||
|
def add(self, pyop):
|
||||||
|
op_add(pyop)
|
||||||
|
|
||||||
|
def remove(self, pyop):
|
||||||
|
op_remove(pyop)
|
||||||
|
|
||||||
|
def __getattr__(self, module):
|
||||||
|
'''
|
||||||
|
gets a bpy.ops submodule
|
||||||
|
'''
|
||||||
|
return bpy_ops_submodule(module)
|
||||||
|
|
||||||
|
def __dir__(self):
|
||||||
|
|
||||||
|
submodules = set()
|
||||||
|
|
||||||
|
# add this classes functions
|
||||||
|
for id_name in dir(self.__class__):
|
||||||
|
if not id_name.startswith('__'):
|
||||||
|
submodules.add(id_name)
|
||||||
|
|
||||||
|
for id_name in op_dir():
|
||||||
|
id_split = id_name.split('_OT_', 1)
|
||||||
|
|
||||||
|
if len(id_split) == 2:
|
||||||
|
submodules.add(id_split[0].lower())
|
||||||
|
else:
|
||||||
|
submodules.add(id_split[0])
|
||||||
|
|
||||||
|
return list(submodules)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return "<module like class 'bpy.ops'>"
|
||||||
|
|
||||||
|
|
||||||
|
class bpy_ops_submodule(object):
|
||||||
|
'''
|
||||||
|
Utility class to fake submodules.
|
||||||
|
|
||||||
|
eg. bpy.ops.object
|
||||||
|
'''
|
||||||
|
__keys__ = ('module',)
|
||||||
|
|
||||||
|
def __init__(self, module):
|
||||||
|
self.module = module
|
||||||
|
|
||||||
|
def __getattr__(self, func):
|
||||||
|
'''
|
||||||
|
gets a bpy.ops.submodule function
|
||||||
|
'''
|
||||||
|
return bpy_ops_submodule_op(self.module, func)
|
||||||
|
|
||||||
|
def __dir__(self):
|
||||||
|
|
||||||
|
functions = set()
|
||||||
|
|
||||||
|
module_upper = self.module.upper()
|
||||||
|
|
||||||
|
for id_name in op_dir():
|
||||||
|
id_split = id_name.split('_OT_', 1)
|
||||||
|
if len(id_split) == 2 and module_upper == id_split[0]:
|
||||||
|
functions.add(id_split[1])
|
||||||
|
|
||||||
|
return list(functions)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return "<module like class 'bpy.ops.%s'>" % self.module
|
||||||
|
|
||||||
|
class bpy_ops_submodule_op(object):
|
||||||
|
'''
|
||||||
|
Utility class to fake submodule operators.
|
||||||
|
|
||||||
|
eg. bpy.ops.object.somefunc
|
||||||
|
'''
|
||||||
|
__keys__ = ('module', 'func')
|
||||||
|
def __init__(self, module, func):
|
||||||
|
self.module = module
|
||||||
|
self.func = func
|
||||||
|
|
||||||
|
def idname(self):
|
||||||
|
# submod.foo -> SUBMOD_OT_foo
|
||||||
|
return self.module.upper() + '_OT_' + self.func
|
||||||
|
|
||||||
|
def __call__(self, **kw):
|
||||||
|
|
||||||
|
# Get the operator from blender
|
||||||
|
return op_call(self.idname(), kw)
|
||||||
|
|
||||||
|
def get_rna(self):
|
||||||
|
'''
|
||||||
|
currently only used for '__rna__'
|
||||||
|
'''
|
||||||
|
return op_get_rna(self.idname())
|
||||||
|
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return "<function bpy.ops.%s.%s at 0x%x'>" % (self.module, self.func, id(self))
|
||||||
|
|
||||||
|
import bpy
|
||||||
|
bpy.ops = bpy_ops()
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user