Merged changes in the trunk up to revision 52690.

Conflicts resolved:
release/datafiles/startup.blend
source/blender/blenlib/intern/bpath.c
This commit is contained in:
Tamito Kajiyama 2012-12-01 02:47:59 +00:00
commit ed0e2fbd9f
259 changed files with 4507 additions and 2592 deletions

@ -190,8 +190,8 @@ option(WITH_MOD_FLUID "Enable Elbeem Modifier (Fluid Simulation)" ON)
option(WITH_MOD_SMOKE "Enable Smoke Modifier (Smoke Simulation)" ON)
option(WITH_MOD_BOOLEAN "Enable Boolean Modifier" ON)
option(WITH_MOD_REMESH "Enable Remesh Modifier" ON)
option(WITH_MOD_CLOTH_ELTOPO "Enable Experimental cloth solver" OFF)
mark_as_advanced(WITH_MOD_CLOTH_ELTOPO)
# option(WITH_MOD_CLOTH_ELTOPO "Enable Experimental cloth solver" OFF) # this is now only available in a branch
# mark_as_advanced(WITH_MOD_CLOTH_ELTOPO)
option(WITH_MOD_OCEANSIM "Enable Ocean Modifier" OFF)
# Image format support
@ -271,6 +271,9 @@ mark_as_advanced(WITH_ASSERT_ABORT)
if(APPLE)
cmake_minimum_required(VERSION 2.8.8)
cmake_policy(VERSION 2.8.8)
if(NOT CMAKE_OSX_ARCHITECTURES)
set(CMAKE_OSX_ARCHITECTURES x86_64 CACHE STRING
"Choose the architecture you want to build Blender for: i386, x86_64 or ppc"
@ -487,14 +490,14 @@ set(PLATFORM_LINKFLAGS_DEBUG "")
# For alternate Python locations the commandline can be used to override detected/default cache settings, e.g:
# On Unix:
# cmake ../blender \
# -D PYTHON_VERSION=3.2 \
# -D PYTHON_INCLUDE_DIR=/opt/py32/include/python3.2d \
# -D PYTHON_LIBRARY=/opt/py32/lib/libpython3.2d.so
# -D PYTHON_VERSION=3.3 \
# -D PYTHON_INCLUDE_DIR=/opt/py33/include/python3.3d \
# -D PYTHON_LIBRARY=/opt/py33/lib/libpython3.3d.so
#
# On Macs:
# cmake ../blender \
# -D PYTHON_INCLUDE_DIR=/System/Library/Frameworks/Python.framework/Versions/3.2/include/python3.2 \
# -D PYTHON_LIBPATH=/System/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/config \
# -D PYTHON_INCLUDE_DIR=/System/Library/Frameworks/Python.framework/Versions/3.3/include/python3.3 \
# -D PYTHON_LIBPATH=/System/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/config \
# -G Xcode
#
# When changing any of this remember to update the notes in doc/build_systems/cmake.txt
@ -522,7 +525,7 @@ if(UNIX AND NOT APPLE)
find_package_wrapper(Freetype REQUIRED)
if(WITH_PYTHON)
# No way to set py32. remove for now.
# No way to set py33. remove for now.
# find_package(PythonLibs)
# Use our own instead, since wothout py is such a rare case,
@ -755,7 +758,6 @@ if(UNIX AND NOT APPLE)
OUTPUT_STRIP_TRAILING_WHITESPACE)
string(REPLACE " " ";" LLVM_LIBRARY ${LLVM_LIBRARY})
endif()
message(STATUS "LLVM library = ${LLVM_LIBRARY}")
else()
message(FATAL_ERROR "LLVM not found.")
endif()
@ -872,7 +874,7 @@ elseif(WIN32)
# Setup 64bit and 64bit windows systems
if(WITH_MINGW64)
message("Set 64 bit compiler for MinGW.")
message("Compiling for 64 bit with MinGW-w64.")
set(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/mingw64)
endif()
else()
@ -928,8 +930,6 @@ elseif(WIN32)
if(WITH_CYCLES_OSL)
set(CYCLES_OSL ${LIBDIR}/osl CACHE PATH "Path to OpenShadingLanguage installation")
message(STATUS "CYCLES_OSL = ${CYCLES_OSL}")
find_library(OSL_LIB_EXEC NAMES oslexec PATHS ${CYCLES_OSL}/lib)
find_library(OSL_LIB_COMP NAMES oslcomp PATHS ${CYCLES_OSL}/lib)
find_library(OSL_LIB_QUERY NAMES oslquery PATHS ${CYCLES_OSL}/lib)
@ -939,9 +939,6 @@ elseif(WIN32)
if(OSL_INCLUDES AND OSL_LIBRARIES AND OSL_COMPILER)
set(OSL_FOUND TRUE)
message(STATUS "OSL includes = ${OSL_INCLUDES}")
message(STATUS "OSL library = ${OSL_LIBRARIES}")
message(STATUS "OSL compiler = ${OSL_COMPILER}")
else()
message(STATUS "OSL not found")
endif()
@ -1102,9 +1099,17 @@ elseif(WIN32)
if(WITH_PYTHON)
# normally cached but not since we include them with blender
set(PYTHON_VERSION 3.2) # CACHE STRING)
if(MSVC10)
set(PYTHON_VERSION 3.2) # CACHE STRING)
else()
set(PYTHON_VERSION 3.3) # CACHE STRING)
endif()
set_lib_path(PYTHON "python")
set(PYTHON_LIBRARY ${PYTHON}/lib/python32.lib) #CACHE FILEPATH
STRING(REPLACE "." "" _PYTHON_VERSION_NO_DOTS ${PYTHON_VERSION})
set(PYTHON_LIBRARY ${PYTHON}/lib/python${_PYTHON_VERSION_NO_DOTS}.lib) #CACHE FILEPATH
unset(_PYTHON_VERSION_NO_DOTS)
#Shared includes for both vc2008 and vc2010
set(PYTHON_INCLUDE_DIR ${LIBDIR}/python/include/python${PYTHON_VERSION})
@ -1212,7 +1217,7 @@ elseif(WIN32)
#comes with own pthread library
if(NOT WITH_MINGW64)
set(PTHREADS ${LIBDIR}/pthreads)
set(PTHREADS_INCLUDE_DIRS ${PTHREADS}/include)
#set(PTHREADS_INCLUDE_DIRS ${PTHREADS}/include)
set(PTHREADS_LIBPATH ${PTHREADS}/lib)
set(PTHREADS_LIBRARIES pthreadGC2)
endif()
@ -1284,9 +1289,9 @@ elseif(WIN32)
if(WITH_PYTHON)
# normally cached but not since we include them with blender
set(PYTHON_VERSION 3.2) # CACHE STRING)
set(PYTHON_VERSION 3.3) # CACHE STRING)
set(PYTHON_INCLUDE_DIR "${LIBDIR}/python/include/python${PYTHON_VERSION}") # CACHE PATH)
set(PYTHON_LIBRARY "${LIBDIR}/python/lib/python32mw.lib") # CACHE FILEPATH)
set(PYTHON_LIBRARY "${LIBDIR}/python/lib/python33mw.lib") # CACHE FILEPATH)
# uncached vars
set(PYTHON_INCLUDE_DIRS "${PYTHON_INCLUDE_DIR}")
@ -1605,9 +1610,6 @@ elseif(APPLE)
find_library(LLVM_LIBRARY
NAMES LLVMAnalysis # first of a whole bunch of libs to get
PATHS ${LLVM_LIB_DIR})
message(STATUS "LLVM version = ${LLVM_VERSION}")
message(STATUS "LLVM dir = ${LLVM_DIRECTORY}")
message(STATUS "LLVM lib dir = ${LLVM_LIB_DIR}")
if(LLVM_LIBRARY AND LLVM_DIRECTORY AND LLVM_LIB_DIR)
if(LLVM_STATIC)
@ -1619,7 +1621,6 @@ elseif(APPLE)
OUTPUT_STRIP_TRAILING_WHITESPACE)
string(REPLACE " " ";" LLVM_LIBRARY ${LLVM_LIBRARY})
endif()
message(STATUS "LLVM library = ${LLVM_LIBRARY}")
else()
message(FATAL_ERROR "LLVM not found.")
endif()
@ -1628,8 +1629,6 @@ elseif(APPLE)
if(WITH_CYCLES_OSL)
set(CYCLES_OSL ${LIBDIR}/osl CACHE PATH "Path to OpenShadingLanguage installation")
message(STATUS "CYCLES_OSL = ${CYCLES_OSL}")
find_library(OSL_LIB_EXEC NAMES oslexec PATHS ${CYCLES_OSL}/lib)
find_library(OSL_LIB_COMP NAMES oslcomp PATHS ${CYCLES_OSL}/lib)
find_library(OSL_LIB_QUERY NAMES oslquery PATHS ${CYCLES_OSL}/lib)
@ -1640,9 +1639,6 @@ elseif(APPLE)
if(OSL_INCLUDES AND OSL_LIBRARIES AND OSL_COMPILER)
set(OSL_FOUND TRUE)
message(STATUS "OSL includes = ${OSL_INCLUDES}")
message(STATUS "OSL library = ${OSL_LIBRARIES}")
message(STATUS "OSL compiler = ${OSL_COMPILER}")
else()
message(STATUS "OSL not found")
endif()

@ -312,6 +312,9 @@ if env['OURPLATFORM']=='darwin':
env.Append(LINKFLAGS=['-L'+OSX_OSL_LIBPATH,'-loslcomp','-force_load '+ OSX_OSL_LIBPATH +'/liboslexec.a','-loslquery'])
env.Append(BF_PROGRAM_LINKFLAGS=['-Xlinker','-force_load','-Xlinker',OSX_OSL_LIBPATH +'/liboslexec.a'])
# Trying to get rid of eventually clashes, we export some explicite as local symbols
env.Append(LINKFLAGS=['-Xlinker','-unexported_symbols_list','-Xlinker','./source/creator/osx_locals.map'])
if env['WITH_BF_OPENMP'] == 1:
if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
env['CCFLAGS'].append('/openmp')

@ -188,9 +188,14 @@ detect_distro() {
prepare_opt() {
INFO "Ensuring $INST exists and is writable by us"
sudo mkdir -p $INST
sudo chown $USER $INST
sudo chmod 775 $INST
if [ ! -d $INST ]; then
sudo mkdir -p $INST
fi
if [ ! -w $INST ]; then
sudo chown $USER $INST
sudo chmod 775 $INST
fi
}
# Check whether the current package needs to be recompiled, based on a dummy file containing a magic number in its name...
@ -407,6 +412,7 @@ compile_OIIO() {
prepare_opt
if [ ! -d $_src ]; then
mkdir -p $SRC
wget -c $OIIO_SOURCE -O "$_src.tar.gz"
INFO "Unpacking OpenImageIO-$OIIO_VERSION"
@ -450,12 +456,16 @@ EOF
cmake_d="$cmake_d -D CMAKE_PREFIX_PATH=$_inst"
cmake_d="$cmake_d -D CMAKE_INSTALL_PREFIX=$_inst"
cmake_d="$cmake_d -D BUILDSTATIC=ON"
cmake_d="$cmake_d -D LINKSTATIC=ON"
# linking statically could give issues on Debian/Ubuntu (and probably other distros
# which doesn't like static linking) when linking shared oiio library due to missing
# text symbols (static libs should be compiled with -fPIC)
# cmake_d="$cmake_d -D LINKSTATIC=ON"
if [ -d $INST/boost ]; then
cmake_d="$cmake_d -D BOOST_ROOT=$INST/boost -D Boost_NO_SYSTEM_PATHS=ON"
if $ALL_STATIC; then
cmake_d="$cmake_d -D Boost_USE_STATIC_LIBS=ON"
cmake_d="$cmake_d -D Boost_USE_STATIC_LIBS=ON"
fi
fi
@ -513,6 +523,7 @@ compile_LLVM() {
prepare_opt
if [ ! -d $_src -o true ]; then
mkdir -p $SRC
wget -c $LLVM_SOURCE -O "$_src.tar.gz"
wget -c $LLVM_CLANG_SOURCE -O "$_src_clang.tar.gz"
@ -603,6 +614,8 @@ compile_OSL() {
prepare_opt
if [ ! -d $_src ]; then
mkdir -p $SRC
# XXX Using git on my own repo for now, looks like archives are not updated immediately... :/
# wget -c $OSL_SOURCE -O "$_src.tar.gz"
@ -692,6 +705,7 @@ compile_FFmpeg() {
if [ ! -d $_src ]; then
INFO "Downloading ffmpeg-$FFMPEG_VERSION"
mkdir -p $SRC
wget -c $FFMPEG_SOURCE -O "$_src.tar.bz2"
INFO "Unpacking ffmpeg-$FFMPEG_VERSION"
@ -811,6 +825,29 @@ install_DEB() {
INFO "$COMMON_INFO"
INFO ""
if [ ! -z "`cat /etc/debian_version | grep ^6`" ]; then
if [ -z "`cat /etc/apt/sources.list | grep backports.debian.org`" ]; then
INFO "Looks like you're using Debian Squeeze which does have broken CMake"
INFO "It is highly recommended to install cmake from backports, otherwise"
INFO "compilation of some libraries could fail"
INFO ""
INFO "You could install newer CMake from debian-backports repository"
INFO "Add this this line to your /etc/apt/sources.lixt:"
INFO ""
INFO "deb http://backports.debian.org/debian-backports squeeze-backports main"
INFO ""
INFO "and then run:"
INFO ""
INFO "sudo apt-get update && sudo apt-get install cmake=2.8.7-4~bpo60+1 sudo apt-get install cmake=2.8.7-4~bpo60+1"
INFO ""
INFO "(you could also add this reporisotry using GUI like synaptic)"
INFO ""
INFO "Hit Enter to continue running the script, or hit Ctrl-C to abort the script"
read
fi
fi
sudo apt-get update
# XXX Why in hell? Let's let this stuff to the user's responsability!!!
# sudo apt-get -y upgrade
@ -825,7 +862,7 @@ install_DEB() {
libfreetype6-dev libx11-dev libxi-dev wget libsqlite3-dev libbz2-dev libncurses5-dev \
libssl-dev liblzma-dev libreadline-dev $OPENJPEG_DEV libopenexr-dev libopenal-dev \
libglew-dev yasm $SCHRO_DEV $THEORA_DEV $VORBIS_DEV libsdl1.2-dev \
libfftw3-dev libjack-dev python-dev patch
libfftw3-dev libjack-dev python-dev patch bzip2
OPENJPEG_USE=true
SCHRO_USE=true

@ -110,8 +110,7 @@ BF_JACK_LIB_STATIC = '${BF_ZLIB}/lib/libjack.a'
# Cycles
WITH_BF_CYCLES = True
WITH_BF_CYCLES_CUDA_BINARIES = True
#BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_13', 'sm_20', 'sm_21', 'sm_30']
BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30']
BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_13', 'sm_20', 'sm_21', 'sm_30']
WITH_BF_OIIO = True
WITH_BF_STATICOIIO = True
@ -160,6 +159,6 @@ WITH_BF_OCEANSIM = True
# Compilation and optimization
BF_DEBUG = False
REL_CCFLAGS = ['-O2', '-msse', '-msse2'] # C & C++
REL_CCFLAGS = ['-DNDEBUG', '-O2', '-msse', '-msse2'] # C & C++
PLATFORM_LINKFLAGS = ['-lrt']
BF_PROGRAM_LINKFLAGS = ['-Wl,--whole-archive', '-loslexec', '-Wl,--no-whole-archive', '-Wl,--version-script=source/creator/blender.map']

@ -159,6 +159,6 @@ WITH_BF_OCEANSIM = True
# Compilation and optimization
BF_DEBUG = False
REL_CCFLAGS = ['-O2', '-msse', '-msse2'] # C & C++
REL_CCFLAGS = ['-DNDEBUG', '-O2', '-msse', '-msse2'] # C & C++
PLATFORM_LINKFLAGS = ['-lrt']
BF_PROGRAM_LINKFLAGS = ['-Wl,--whole-archive', '-loslexec', '-Wl,--no-whole-archive', '-Wl,--version-script=source/creator/blender.map']

@ -97,8 +97,7 @@ WITH_BF_JACK = True
# Cycles
WITH_BF_CYCLES = True
WITH_BF_CYCLES_CUDA_BINARIES = True
#BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_13', 'sm_20', 'sm_21', 'sm_30']
BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30']
BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_13', 'sm_20', 'sm_21', 'sm_30']
WITH_BF_OIIO = True
WITH_BF_STATICOIIO = True
@ -145,6 +144,6 @@ WITH_BF_OCEANSIM = True
# Compilation and optimization
BF_DEBUG = False
REL_CCFLAGS = ['-O2'] # C & C++
REL_CCFLAGS = ['-DNDEBUG', '-DNDEBUG', '-O2'] # C & C++
PLATFORM_LINKFLAGS = ['-L/home/sources/staticlibs/lib32']
BF_PROGRAM_LINKFLAGS = ['-Wl,--whole-archive', '-loslexec', '-Wl,--no-whole-archive', '-Wl,--version-script=source/creator/blender.map']

@ -144,6 +144,6 @@ WITH_BF_OCEANSIM = True
# Compilation and optimization
BF_DEBUG = False
REL_CCFLAGS = ['-O2', '-msse', '-msse2'] # C & C++
REL_CCFLAGS = ['-DNDEBUG', '-O2', '-msse', '-msse2'] # C & C++
PLATFORM_LINKFLAGS = ['-L/home/sources/staticlibs/lib64']
BF_PROGRAM_LINKFLAGS = ['-Wl,--whole-archive', '-loslexec', '-Wl,--no-whole-archive', '-Wl,--version-script=source/creator/blender.map']

@ -117,5 +117,5 @@ WITH_BF_OCEANSIM = True
# Compilation and optimization
BF_DEBUG = False
REL_CCFLAGS = ['-O2', '-msse', '-msse2'] # C & C++
REL_CCFLAGS = ['-DNDEBUG', '-O2', '-msse', '-msse2'] # C & C++
PLATFORM_LINKFLAGS = ['-lrt']

@ -117,5 +117,5 @@ WITH_BF_OCEANSIM = True
# Compilation and optimization
BF_DEBUG = False
REL_CCFLAGS = ['-O2', '-msse', '-msse2'] # C & C++
REL_CCFLAGS = ['-DNDEBUG', '-O2', '-msse', '-msse2'] # C & C++
PLATFORM_LINKFLAGS = ['-lrt']

@ -110,5 +110,5 @@ WITH_BF_OCEANSIM = True
# Compilation and optimization
BF_DEBUG = False
REL_CCFLAGS = ['-O2'] # C & C++
REL_CCFLAGS = ['-DNDEBUG', '-O2'] # C & C++
PLATFORM_LINKFLAGS = ['-L/home/sources/staticlibs/lib32']

@ -110,5 +110,5 @@ WITH_BF_OCEANSIM = True
# Compilation and optimization
BF_DEBUG = False
REL_CCFLAGS = ['-O2', '-msse', '-msse2'] # C & C++
REL_CCFLAGS = ['-DNDEBUG', '-O2', '-msse', '-msse2'] # C & C++
PLATFORM_LINKFLAGS = ['-L/home/sources/staticlibs/lib64']

@ -1,4 +1,4 @@
#!/usr/bin/env python3.2
#!/usr/bin/env python3
# ***** BEGIN GPL LICENSE BLOCK *****
#

@ -1,4 +1,4 @@
#!/usr/bin/env python3.2
#!/usr/bin/env python3
# ***** BEGIN GPL LICENSE BLOCK *****
#

@ -1,4 +1,4 @@
#!/usr/bin/env python3.2
#!/usr/bin/env python3
# ***** BEGIN GPL LICENSE BLOCK *****
#

@ -1,4 +1,4 @@
#!/usr/bin/env python3.2
#!/usr/bin/env python3
# ***** BEGIN GPL LICENSE BLOCK *****
#

@ -1,4 +1,4 @@
#!/usr/bin/env python3.2
#!/usr/bin/env python3
# ***** BEGIN GPL LICENSE BLOCK *****
#

@ -1,4 +1,4 @@
#!/usr/bin/env python3.2
#!/usr/bin/env python3
# ***** BEGIN GPL LICENSE BLOCK *****
#

@ -1,4 +1,4 @@
#!/usr/bin/env python3.2
#!/usr/bin/env python3
# ***** BEGIN GPL LICENSE BLOCK *****
#

@ -1,4 +1,4 @@
#!/usr/bin/env python3.2
#!/usr/bin/env python3
# ***** BEGIN GPL LICENSE BLOCK *****
#

@ -1,4 +1,4 @@
#!/usr/bin/env python3.2
#!/usr/bin/env python3
# ##### BEGIN GPL LICENSE BLOCK #####
#

@ -1,4 +1,4 @@
#!/usr/bin/env python3.2
#!/usr/bin/env python3
# ***** BEGIN GPL LICENSE BLOCK *****
#

@ -7,7 +7,7 @@ LIBDIR = "${LCGDIR}"
BF_PYTHON_ABI_FLAGS = ''
BF_PYTHON = '/usr/local'
BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib'
BF_PYTHON_VERSION = '3.2'
BF_PYTHON_VERSION = '3.3'
WITH_BF_STATICPYTHON = False
BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}${BF_PYTHON_ABI_FLAGS}'
BF_PYTHON_BINARY = '${BF_PYTHON}/bin/python${BF_PYTHON_VERSION}'

@ -7,7 +7,7 @@ LIBDIR = "${LCGDIR}"
BF_PYTHON_ABI_FLAGS = ''
BF_PYTHON = '/usr/local'
BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib'
BF_PYTHON_VERSION = '3.2'
BF_PYTHON_VERSION = '3.3'
WITH_BF_STATICPYTHON = False
BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}${BF_PYTHON_ABI_FLAGS}'
BF_PYTHON_BINARY = '${BF_PYTHON}/bin/python${BF_PYTHON_VERSION}'

@ -7,7 +7,7 @@ LIBDIR = "${LCGDIR}"
BF_PYTHON_ABI_FLAGS = ''
BF_PYTHON = '/usr/local'
BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib'
BF_PYTHON_VERSION = '3.2'
BF_PYTHON_VERSION = '3.3'
WITH_BF_STATICPYTHON = False
BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}${BF_PYTHON_ABI_FLAGS}'
BF_PYTHON_BINARY = '${BF_PYTHON}/bin/python${BF_PYTHON_VERSION}'

@ -2,7 +2,7 @@ LCGDIR = '#../lib/windows'
LIBDIR = '${LCGDIR}'
BF_PYTHON = LIBDIR + '/python'
BF_PYTHON_VERSION = '3.2'
BF_PYTHON_VERSION = '3.3'
BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}'
BF_PYTHON_BINARY = 'python'
BF_PYTHON_LIB = 'python${BF_PYTHON_VERSION[0]}${BF_PYTHON_VERSION[2]}mw'

@ -2,12 +2,12 @@ LCGDIR = '#../lib/mingw32'
LIBDIR = "${LCGDIR}"
BF_PYTHON = LIBDIR + '/python'
BF_PYTHON_VERSION = '3.2'
BF_PYTHON_VERSION = '3.3'
WITH_BF_STATICPYTHON = False
BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}'
BF_PYTHON_BINARY = 'python'
BF_PYTHON_LIB = 'python${BF_PYTHON_VERSION[0]}${BF_PYTHON_VERSION[2]}mw'
BF_PYTHON_DLL = 'python32'
BF_PYTHON_DLL = 'python33'
BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib'
BF_PYTHON_LIB_STATIC = '${BF_PYTHON}/lib/libpython${BF_PYTHON_VERSION[0]}${BF_PYTHON_VERSION[2]}.a'

@ -9,10 +9,10 @@ BF_FFMPEG_LIB = 'avformat-53.lib avcodec-53.lib avdevice-53.lib avutil-51.lib sw
BF_FFMPEG_DLL = '${BF_FFMPEG_LIBPATH}/avformat-53.dll ${BF_FFMPEG_LIBPATH}/avcodec-53.dll ${BF_FFMPEG_LIBPATH}/avdevice-53.dll ${BF_FFMPEG_LIBPATH}/avutil-51.dll ${BF_FFMPEG_LIBPATH}/swscale-2.dll'
BF_PYTHON = LIBDIR + '/python'
BF_PYTHON_VERSION = '3.2'
BF_PYTHON_VERSION = '3.3'
BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}'
BF_PYTHON_BINARY = 'python'
BF_PYTHON_LIB = 'python32'
BF_PYTHON_LIB = 'python33'
BF_PYTHON_DLL = '${BF_PYTHON_LIB}'
BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib'

@ -2,12 +2,12 @@ LCGDIR = '#../lib/mingw64'
LIBDIR = "${LCGDIR}"
BF_PYTHON = LIBDIR + '/python'
BF_PYTHON_VERSION = '3.2'
BF_PYTHON_VERSION = '3.3'
WITH_BF_STATICPYTHON = False
BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}'
BF_PYTHON_BINARY = 'python'
BF_PYTHON_LIB = 'python${BF_PYTHON_VERSION[0]}${BF_PYTHON_VERSION[2]}mw'
BF_PYTHON_DLL = 'python32'
BF_PYTHON_DLL = 'python33'
BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib'
WITH_BF_OPENAL = True

@ -9,10 +9,10 @@ BF_FFMPEG_LIB = 'avformat-53.lib avcodec-53.lib avdevice-53.lib avutil-51.lib sw
BF_FFMPEG_DLL = '${BF_FFMPEG_LIBPATH}/avformat-53.dll ${BF_FFMPEG_LIBPATH}/avcodec-53.dll ${BF_FFMPEG_LIBPATH}/avdevice-53.dll ${BF_FFMPEG_LIBPATH}/avutil-51.dll ${BF_FFMPEG_LIBPATH}/swscale-2.dll'
BF_PYTHON = LIBDIR + '/python'
BF_PYTHON_VERSION = '3.2'
BF_PYTHON_VERSION = '3.3'
BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}'
BF_PYTHON_BINARY = 'python'
BF_PYTHON_LIB = 'python32'
BF_PYTHON_LIB = 'python33'
BF_PYTHON_DLL = '${BF_PYTHON_LIB}'
BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib'

@ -166,10 +166,12 @@ def setup_staticlibs(lenv):
libincs += Split(lenv['BF_FFTW3_LIBPATH'])
if lenv['WITH_BF_STATICFFTW3']:
statlibs += Split(lenv['BF_FFTW3_LIB_STATIC'])
'''
if lenv['WITH_BF_ELTOPO']:
libincs += Split(lenv['BF_LAPACK_LIBPATH'])
if lenv['WITH_BF_STATICLAPACK']:
statlibs += Split(lenv['BF_LAPACK_LIB_STATIC'])
statlibs += Split(lenv['BF_LAPACK_LIB_STATIC'])
'''
if lenv['WITH_BF_FFMPEG'] and lenv['WITH_BF_STATICFFMPEG']:
statlibs += Split(lenv['BF_FFMPEG_LIB_STATIC'])
if lenv['WITH_BF_INTERNATIONAL']:
@ -293,8 +295,10 @@ def setup_syslibs(lenv):
syslibs += Split(lenv['BF_SNDFILE_LIB'])
if lenv['WITH_BF_FFTW3'] and not lenv['WITH_BF_STATICFFTW3']:
syslibs += Split(lenv['BF_FFTW3_LIB'])
'''
if lenv['WITH_BF_ELTOPO']:
syslibs += Split(lenv['BF_LAPACK_LIB'])
'''
if lenv['WITH_BF_SDL']:
syslibs += Split(lenv['BF_SDL_LIB'])
if not lenv['WITH_BF_STATICOPENGL']:

@ -119,7 +119,8 @@ def validate_arguments(args, bc):
'WITH_BF_ICONV', 'BF_ICONV', 'BF_ICONV_INC', 'BF_ICONV_LIB', 'BF_ICONV_LIBPATH',
'WITH_BF_GAMEENGINE',
'WITH_BF_BULLET', 'BF_BULLET', 'BF_BULLET_INC', 'BF_BULLET_LIB',
'WITH_BF_ELTOPO', 'BF_LAPACK', 'BF_LAPACK_LIB', 'BF_LAPACK_LIBPATH', 'BF_LAPACK_LIB_STATIC',
# 'WITH_BF_ELTOPO', # now only available in a branch
'BF_LAPACK', 'BF_LAPACK_LIB', 'BF_LAPACK_LIBPATH', 'BF_LAPACK_LIB_STATIC',
'BF_WINTAB', 'BF_WINTAB_INC',
'BF_FREETYPE', 'BF_FREETYPE_INC', 'BF_FREETYPE_LIB', 'BF_FREETYPE_LIBPATH', 'BF_FREETYPE_LIB_STATIC', 'WITH_BF_FREETYPE_STATIC',
'WITH_BF_QUICKTIME', 'BF_QUICKTIME', 'BF_QUICKTIME_INC', 'BF_QUICKTIME_LIB', 'BF_QUICKTIME_LIBPATH',
@ -393,8 +394,7 @@ def read_opts(env, cfg, args):
(BoolVariable('WITH_BF_GAMEENGINE', 'Build with gameengine' , False)),
(BoolVariable('WITH_BF_BULLET', 'Use Bullet if true', True)),
(BoolVariable('WITH_BF_ELTOPO', 'Use Eltopo collision library if true', False)),
# (BoolVariable('WITH_BF_ELTOPO', 'Use Eltopo collision library if true', False)), # this is now only available in a branch
('BF_LAPACK', 'LAPACK base path', ''),
('BF_LAPACK_LIB', 'LAPACK library', ''),
('BF_LAPACK_LIB_STATIC', 'LAPACK library', ''),

@ -1,4 +1,4 @@
#!/usr/bin/env python3.2
#!/usr/bin/env python3
# ***** BEGIN GPL LICENSE BLOCK *****
#

@ -1,4 +1,4 @@
#!/usr/bin/env python3.2
#!/usr/bin/env python3
# ***** BEGIN GPL LICENSE BLOCK *****
#

@ -0,0 +1,106 @@
# This script uses bmesh operators to make 2 links of a chain.
import bpy
import bmesh
import math
import mathutils
# Make a new BMesh
bm = bmesh.new()
# Add a circle XXX, should return all geometry created, not just verts.
bmesh.ops.create_circle(
bm,
cap_ends=False,
diameter=0.2,
segments=8)
# Spin and deal with geometry on side 'a'
edges_start_a = bm.edges[:]
geom_start_a = bm.verts[:] + edges_start_a
ret = bmesh.ops.spin(
bm,
geom=geom_start_a,
angle=math.radians(180.0),
steps=8,
axis=(1.0, 0.0, 0.0),
cent=(0.0, 1.0, 0.0))
edges_end_a = [ele for ele in ret["geom_last"]
if isinstance(ele, bmesh.types.BMEdge)]
del ret
# Extrude and create geometry on side 'b'
ret = bmesh.ops.extrude_edge_only(
bm,
edges=edges_start_a)
geom_extrude_mid = ret["geom"]
del ret
# Collect the edges to spin XXX, 'extrude_edge_only' could return this.
verts_extrude_b = [ele for ele in geom_extrude_mid
if isinstance(ele, bmesh.types.BMVert)]
edges_extrude_b = [ele for ele in geom_extrude_mid
if isinstance(ele, bmesh.types.BMEdge) and ele.is_boundary]
bmesh.ops.translate(
bm,
verts=verts_extrude_b,
vec=(0.0, 0.0, 1.0))
# Create the circle on side 'b'
ret = bmesh.ops.spin(
bm,
geom=verts_extrude_b + edges_extrude_b,
angle=-math.radians(180.0),
steps=8,
axis=(1.0, 0.0, 0.0),
cent=(0.0, 1.0, 1.0))
edges_end_b = [ele for ele in ret["geom_last"]
if isinstance(ele, bmesh.types.BMEdge)]
del ret
# Bridge the resulting edge loops of both spins 'a & b'
bmesh.ops.bridge_loops(
bm,
edges=edges_end_a + edges_end_b)
# Now we have made a links of the chain, make a copy and rotate it
# (so this looks something like a chain)
ret = bmesh.ops.duplicate(
bm,
geom=bm.verts[:] + bm.edges[:] + bm.faces[:])
geom_dupe = ret["geom"]
verts_dupe = [ele for ele in geom_dupe if isinstance(ele, bmesh.types.BMVert)]
del ret
# position the new link
bmesh.ops.translate(
bm,
verts=verts_dupe,
vec=(0.0, 0.0, 2.0))
bmesh.ops.rotate(
bm,
verts=verts_dupe,
cent=(0.0, 1.0, 0.0),
matrix=mathutils.Matrix.Rotation(math.radians(90.0), 3, 'Z'))
# Done with creating the mesh, simply link it into the scene so we can see it
# Finish up, write the bmesh into a new mesh
me = bpy.data.meshes.new("Mesh")
bm.to_mesh(me)
# Add the mesh to the scene
scene = bpy.context.scene
obj = bpy.data.objects.new("Object", me)
scene.objects.link(obj)
# Select and make active
scene.objects.active = obj
obj.select = True

@ -416,9 +416,9 @@ Sensor Status
.. data:: KX_SENSOR_ACTIVE
.. data:: KX_SENSOR_JUST_DEACTIVATED
-------------
---------------
Armature Sensor
-------------
---------------
.. _armaturesensor-type:
@ -537,9 +537,9 @@ See :class:`bge.types.BL_ActionActuator`
.. data:: KX_ACTIONACT_LOOPEND
.. data:: KX_ACTIONACT_PROPERTY
---------------
-----------------
Armature Actuator
---------------
-----------------
.. _armatureactuator-constants-type:
@ -556,13 +556,13 @@ See :class:`bge.types.BL_ArmatureActuator.type`
.. data:: KX_ACT_ARMATURE_ENABLE
Enable the constraint.
:value: 1
.. data:: KX_ACT_ARMATURE_DISABLE
Disable the constraint (runtime constraint values are not updated).
:value: 2
.. data:: KX_ACT_ARMATURE_SETTARGET
@ -809,9 +809,9 @@ See :class:`bge.types.KX_SoundActuator`
:value: 6
--------------
-----------------
Steering Actuator
--------------
-----------------
.. _logic-steering-actuator:
@ -961,9 +961,9 @@ See :class:`bge.types.BL_ArmatureChannel.rotation_mode`
:value: 6
----------------
-------------------
Armature Constraint
----------------
-------------------
.. _armatureconstraint-constants-type:
See :class:`bge.types.BL_ArmatureConstraint.type`
@ -1075,9 +1075,9 @@ See :class:`bge.types.SCA_PythonKeyboard`, :class:`bge.types.SCA_PythonMouse`, :
.. data:: KX_INPUT_ACTIVE
.. data:: KX_INPUT_JUST_RELEASED
------------
-------------
KX_GameObject
-----------
-------------
.. _gameobject-playaction-mode:
See :class:`bge.types.KX_GameObject.playAction`
@ -1111,9 +1111,9 @@ See :class:`bge.types.SCA_MouseSensor`
.. data:: KX_MOUSE_BUT_MIDDLE
.. data:: KX_MOUSE_BUT_RIGHT
------------
--------------------------
Navigation Mesh Draw Modes
------------
--------------------------
.. _navmesh-draw-mode:
@ -1199,25 +1199,25 @@ See :class:`bge.types.KX_StateActuator.operation`
.. data:: KX_STATE_OP_CLR
Substract bits to state mask
:value: 0
.. data:: KX_STATE_OP_CPY
Copy state mask
:value: 1
.. data:: KX_STATE_OP_NEG
Invert bits to state mask
:value: 2
.. data:: KX_STATE_OP_SET
Add bits to state mask
:value: 3
.. _Two-D-FilterActuator-mode:

@ -759,6 +759,10 @@ Types
The id is derived from a memory location and will be different each time the game engine starts.
.. warning::
The id can't be stored as an integer in game object properties, as those only have a limited range that the id may not be contained in. Instead an id can be stored as a string game property and converted back to an integer for use in from_id lookups.
.. class:: KX_BlenderMaterial(PyObjectPlus)
KX_BlenderMaterial

@ -0,0 +1,380 @@
# ##### BEGIN GPL LICENSE BLOCK #####
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####
# <pep8 compliant>
# This is a quite stupid script which extracts bmesh api docs from
# 'bmesh_opdefines.c' in order to avoid having to add a lot of introspection
# data access into the api.
#
# The script is stupid becase it makes assumptions about formatting...
# that each arg has its own line, that comments above or directly after will be __doc__ etc...
#
# We may want to replace this script with something else one day but for now its good enough.
# if it needs large updates it may be better to rewrite using a real parser or
# add introspection into bmesh.ops.
# - campbell
import os
CURRENT_DIR = os.path.abspath(os.path.dirname(__file__))
SOURCE_DIR = os.path.normpath(os.path.abspath(os.path.normpath(os.path.join(CURRENT_DIR, "..", ".."))))
FILE_OP_DEFINES_C = os.path.join(SOURCE_DIR, "source", "blender", "bmesh", "intern", "bmesh_opdefines.c")
OUT_RST = os.path.join(CURRENT_DIR, "rst", "bmesh.ops.rst")
HEADER = r"""
BMesh Operators (bmesh.ops)
===========================
.. module:: bmesh.ops
This module gives access to low level bmesh operations.
Most operators take input and return output, they can be chained together
to perform useful operations.
.. note::
This API us new in 2.65 and not yet well tested.
Operator Example
++++++++++++++++
This script shows how operators can be used to model a link of a chain.
.. literalinclude:: ../examples/bmesh.ops.1.py
"""
def main():
fsrc = open(FILE_OP_DEFINES_C, 'r', encoding="utf-8")
blocks = []
is_block = False
is_comment = False # /* global comments only */
comment_ctx = None
block_ctx = None
for l in fsrc:
l = l[:-1]
# weak but ok
if ("BMOpDefine" in l and l.split()[1] == "BMOpDefine") and not "bmo_opdefines[]" in l:
is_block = True
block_ctx = []
blocks.append((comment_ctx, block_ctx))
elif l.strip().startswith("/*"):
is_comment = True
comment_ctx = []
if is_block:
if l.strip().startswith("//"):
pass
else:
# remove c++ comment if we have one
cpp_comment = l.find("//")
if cpp_comment != -1:
l = l[:cpp_comment]
block_ctx.append(l)
if l.strip() == "};":
is_block = False
comment_ctx = None
if is_comment:
c_comment_start = l.find("/*")
if c_comment_start != -1:
l = l[c_comment_start + 2:]
c_comment_end = l.find("*/")
if c_comment_end != -1:
l = l[:c_comment_end]
is_comment = False
comment_ctx.append(l)
fsrc.close()
del fsrc
# namespace hack
vars = (
"BMO_OP_SLOT_ELEMENT_BUF",
"BMO_OP_SLOT_BOOL",
"BMO_OP_SLOT_FLT",
"BMO_OP_SLOT_INT",
"BMO_OP_SLOT_MAT",
"BMO_OP_SLOT_VEC",
"BMO_OP_SLOT_PTR",
"BMO_OP_SLOT_MAPPING",
"BMO_OP_SLOT_SUBTYPE_MAP_ELEM",
"BMO_OP_SLOT_SUBTYPE_MAP_BOOL",
"BMO_OP_SLOT_SUBTYPE_MAP_INT",
"BMO_OP_SLOT_SUBTYPE_MAP_FLT",
"BMO_OP_SLOT_SUBTYPE_MAP_EMPTY",
"BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL",
"BMO_OP_SLOT_SUBTYPE_PTR_SCENE",
"BMO_OP_SLOT_SUBTYPE_PTR_OBJECT",
"BMO_OP_SLOT_SUBTYPE_PTR_MESH",
"BMO_OP_SLOT_SUBTYPE_PTR_BMESH",
"BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE",
"BM_VERT",
"BM_EDGE",
"BM_FACE",
"BMO_OP_FLAG_UNTAN_MULTIRES",
)
vars_dict = {}
for i, v in enumerate(vars):
vars_dict[v] = (1 << i)
globals().update(vars_dict)
# reverse lookup
vars_dict_reverse = {v: k for k, v in vars_dict.items()}
# end namespace hack
blocks_py = []
for comment, b in blocks:
# magic, translate into python
b[0] = b[0].replace("static BMOpDefine ", "")
for i, l in enumerate(b):
l = l.strip()
l = l.replace("{", "(")
l = l.replace("}", ")")
if l.startswith("/*"):
l = l.replace("/*", "'''own <")
else:
l = l.replace("/*", "'''inline <")
l = l.replace("*/", ">''',")
# exec func. eg: bmo_rotate_edges_exec,
if l.startswith("bmo_") and l.endswith("_exec,"):
l = "None,"
b[i] = l
#for l in b:
# print(l)
text = "\n".join(b)
global_namespace = {
"__file__": "generated",
"__name__": "__main__",
}
global_namespace.update(vars_dict)
text_a, text_b = text.split("=", 1)
text = "result = " + text_b
exec(compile(text, "generated", 'exec'), global_namespace)
# print(global_namespace["result"])
blocks_py.append((comment, global_namespace["result"]))
# ---------------------
# Now convert into rst.
fout = open(OUT_RST, 'w', encoding="utf-8")
fw = fout.write
fw(HEADER)
for comment, b in blocks_py:
args_in = None
args_out = None
for member in b[1:]:
if type(member) == tuple:
if args_in is None:
args_in = member
elif args_out is None:
args_out = member
break
args_in_index = []
args_out_index = []
if args_in is not None:
args_in_index[:] = [i for (i, a) in enumerate(args_in) if type(a) == tuple]
if args_out is not None:
args_out_index[:] = [i for (i, a) in enumerate(args_out) if type(a) == tuple]
fw(".. function:: %s(bm, %s)\n\n" % (b[0], ", ".join([args_in[i][0] for i in args_in_index])))
# -- wash the comment
comment_washed = []
for i, l in enumerate(comment):
assert((l.strip() == "") or
(l in {"/*", " *"}) or
(l.startswith(("/* ", " * "))))
l = l[3:]
if i == 0 and not l.strip():
continue
if l.strip():
l = " " + l
comment_washed.append(l)
fw("\n".join(comment_washed))
fw("\n")
# -- done
# get the args
def get_args_wash(args, args_index, is_ret):
args_wash = []
for i in args_index:
arg = args[i]
if len(arg) == 3:
name, tp, tp_sub = arg
elif len(arg) == 2:
name, tp = arg
tp_sub = None
else:
print(arg)
assert(0)
tp_str = ""
comment_prev = ""
comment_next = ""
if i != 0:
comment_prev = args[i + 1]
if type(comment_prev) == str and comment_prev.startswith("our <"):
comment_prev = comment_next[5:-1] # strip inline <...>
else:
comment_prev = ""
if i + 1 < len(args):
comment_next = args[i + 1]
if type(comment_next) == str and comment_next.startswith("inline <"):
comment_next = comment_next[8:-1] # strip inline <...>
else:
comment_next = ""
comment = ""
if comment_prev:
comment += comment_prev.strip()
if comment_next:
comment += ("\n" if comment_prev else "") + comment_next.strip()
if tp == BMO_OP_SLOT_FLT:
tp_str = "float"
elif tp == BMO_OP_SLOT_INT:
tp_str = "int"
elif tp == BMO_OP_SLOT_BOOL:
tp_str = "bool"
elif tp == BMO_OP_SLOT_MAT:
tp_str = ":class:`mathutils.Matrix`"
elif tp == BMO_OP_SLOT_VEC:
tp_str = ":class:`mathutils.Vector`"
if not is_ret:
tp_str += " or any sequence of 3 floats"
elif tp == BMO_OP_SLOT_PTR:
tp_str = "dict"
assert(tp_sub is not None)
if tp_sub == BMO_OP_SLOT_SUBTYPE_PTR_BMESH:
tp_str = ":class:`bmesh.types.BMesh`"
elif tp_sub == BMO_OP_SLOT_SUBTYPE_PTR_SCENE:
tp_str = ":class:`bpy.types.Scene`"
elif tp_sub == BMO_OP_SLOT_SUBTYPE_PTR_OBJECT:
tp_str = ":class:`bpy.types.Object`"
elif tp_sub == BMO_OP_SLOT_SUBTYPE_PTR_MESH:
tp_str = ":class:`bpy.types.Mesh`"
else:
print("Cant find", vars_dict_reverse[tp_sub])
assert(0)
elif tp == BMO_OP_SLOT_ELEMENT_BUF:
assert(tp_sub is not None)
ls = []
if tp_sub & BM_VERT: ls.append(":class:`bmesh.types.BMVert`")
if tp_sub & BM_EDGE: ls.append(":class:`bmesh.types.BMEdge`")
if tp_sub & BM_FACE: ls.append(":class:`bmesh.types.BMFace`")
assert(ls) # must be at least one
if tp_sub & BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE:
tp_str = "/".join(ls)
else:
tp_str = ("list of (%s)" % ", ".join(ls))
del ls
elif tp == BMO_OP_SLOT_MAPPING:
if tp_sub & BMO_OP_SLOT_SUBTYPE_MAP_EMPTY:
tp_str = "set of vert/edge/face type"
else:
tp_str = "dict mapping vert/edge/face types to "
if tp_sub == BMO_OP_SLOT_SUBTYPE_MAP_BOOL:
tp_str += "bool"
elif tp_sub == BMO_OP_SLOT_SUBTYPE_MAP_INT:
tp_str += "int"
elif tp_sub == BMO_OP_SLOT_SUBTYPE_MAP_FLT:
tp_str += "float"
elif tp_sub == BMO_OP_SLOT_SUBTYPE_MAP_ELEM:
tp_str += ":class:`bmesh.types.BMVert`/:class:`bmesh.types.BMEdge`/:class:`bmesh.types.BMFace`"
elif tp_sub == BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL:
tp_str += "unknown internal data, not compatible with python"
else:
print("Cant find", vars_dict_reverse[tp_sub])
assert(0)
else:
print("Cant find", vars_dict_reverse[tp])
assert(0)
args_wash.append((name, tp_str, comment))
return args_wash
# end get_args_wash
# all ops get this arg
fw(" :arg bm: The bmesh to operate on.\n")
fw(" :type bm: :class:`bmesh.types.BMesh`\n")
args_in_wash = get_args_wash(args_in, args_in_index, False)
args_out_wash = get_args_wash(args_out, args_out_index, True)
for (name, tp, comment) in args_in_wash:
if comment == "":
comment = "Undocumented."
fw(" :arg %s: %s\n" % (name, comment))
fw(" :type %s: %s\n" % (name, tp))
if args_out_wash:
fw(" :return:\n\n")
for (name, tp, comment) in args_out_wash:
assert(name.endswith(".out"))
name = name[:-4]
fw(" - ``%s``: %s\n\n" % (name, comment))
fw(" **type** %s\n" % tp)
fw("\n")
fw(" :rtype: dict with string keys\n")
fw("\n\n")
fout.close()
del fout
print(OUT_RST)
if __name__ == "__main__":
main()

@ -35,7 +35,7 @@ API dump in RST files
./blender.bin --background --python doc/python_api/sphinx_doc_gen.py -- --output ../python_api
For quick builds:
./blender.bin --background --python doc/python_api/sphinx_doc_gen.py -- --partial
./blender.bin --background --python doc/python_api/sphinx_doc_gen.py -- --partial bmesh.*
Sphinx: HTML generation
@ -245,6 +245,7 @@ else:
"bgl",
"blf",
"bmesh",
"bmesh.ops",
"bmesh.types",
"bmesh.utils",
"bpy.app",
@ -298,7 +299,7 @@ try:
__import__("aud")
except ImportError:
BPY_LOGGER.debug("Warning: Built without 'aud' module, docs incomplete...")
EXCLUDE_MODULES = EXCLUDE_MODULES + ("aud", )
EXCLUDE_MODULES = list(EXCLUDE_MODULES) + ["aud"]
# examples
EXAMPLES_DIR = os.path.abspath(os.path.join(SCRIPT_DIR, "examples"))
@ -1480,6 +1481,11 @@ def write_sphinx_conf_py(basepath):
file.close()
def execfile(filepath):
global_namespace = {"__file__": filepath, "__name__": "__main__"}
exec(compile(open(filepath).read(), filepath, 'exec'), global_namespace)
def write_rst_contents(basepath):
'''
Write the rst file of the main page, needed for sphinx (index.html)
@ -1541,13 +1547,17 @@ def write_rst_contents(basepath):
# misc
"Freestyle", "bgl", "blf", "gpu", "aud", "bpy_extras",
# bmesh
"bmesh", "bmesh.types", "bmesh.utils",
"bmesh", "bmesh.types", "bmesh.utils", "bmesh.ops",
)
for mod in standalone_modules:
if mod not in EXCLUDE_MODULES:
fw(" %s\n\n" % mod)
# special case, this 'bmesh.ops.rst' is extracted from C source
if "bmesh.ops" not in EXCLUDE_MODULES:
execfile(os.path.join(SCRIPT_DIR, "rst_from_bmesh_opdefines.py"))
# game engine
if "bge" not in EXCLUDE_MODULES:
fw(title_string("Game Engine Modules", "=", double=True))
@ -1710,6 +1720,8 @@ def copy_handwritten_rsts(basepath):
"bgl", # "Blender OpenGl wrapper"
"gpu", # "GPU Shader Module"
"bmesh.ops", # generated by rst_from_bmesh_opdefines.py
# includes...
"include__bmesh",
]

@ -32,9 +32,10 @@ if(WITH_BULLET)
add_subdirectory(bullet2)
endif()
if(WITH_MOD_CLOTH_ELTOPO)
add_subdirectory(eltopo)
endif()
# now only available in a branch
#if(WITH_MOD_CLOTH_ELTOPO)
# add_subdirectory(eltopo)
#endif()
if(WITH_BINRELOC)
add_subdirectory(binreloc)

3
extern/SConscript vendored

@ -8,8 +8,11 @@ SConscript(['colamd/SConscript'])
if env['WITH_BF_GAMEENGINE']:
SConscript(['recastnavigation/SConscript'])
# now only available in a branch
'''
if env['WITH_BF_ELTOPO']:
SConscript(['eltopo/SConscript'])
'''
if env['WITH_BF_BULLET']:
SConscript(['bullet2/src/SConscript'])

@ -21,8 +21,11 @@ elseif(CMAKE_COMPILER_IS_GNUCC)
endif()
# for OSL
set(RTTI_DISABLE_FLAGS "-fno-rtti -DBOOST_NO_RTTI -DBOOST_NO_TYPEID")
# set(RTTI_DISABLE_FLAGS "/GR- -DBOOST_NO_RTTI -DBOOST_NO_TYPEID")
if(WIN32 AND MSVC)
set(RTTI_DISABLE_FLAGS "/GR- -DBOOST_NO_RTTI -DBOOST_NO_TYPEID")
elseif(CMAKE_COMPILER_IS_GNUCC OR (CMAKE_C_COMPILER_ID MATCHES "Clang"))
set(RTTI_DISABLE_FLAGS "-fno-rtti -DBOOST_NO_RTTI -DBOOST_NO_TYPEID")
endif()
# Definitions and Includes

@ -49,7 +49,7 @@ if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', '
# optimized kernel
if env['WITH_BF_RAYOPTIMIZATION']:
optim_cxxflags = []
optim_cxxflags = Split(env['CXXFLAGS'])
if env['OURPLATFORM'] == 'win32-vc':
optim_cxxflags.append('/arch:SSE2 -D_CRT_SECURE_NO_WARNINGS /fp:fast /EHsc'.split())

@ -360,8 +360,9 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, int motion)
bool emitter_hide = false;
if(b_dup_ob.is_duplicator()) {
/* duplicators hidden by default */
emitter_hide = true;
/* duplicators hidden by default, except dupliframes which duplicate self */
if(b_dup_ob.dupli_type() != BL::Object::dupli_type_FRAMES)
emitter_hide = true;
/* check if we should render or hide particle emitter */
BL::Object::particle_systems_iterator b_psys;

@ -131,7 +131,7 @@ __device int bsdf_phong_ramp_sample(const ShaderClosure *sc, const float3 colors
}
}
}
return LABEL_REFLECT;
return LABEL_REFLECT|LABEL_GLOSSY;
}

@ -65,7 +65,7 @@ __device void camera_sample_perspective(KernelGlobals *kg, float raster_x, float
#ifdef __CAMERA_MOTION__
if(kernel_data.cam.have_motion)
transform_motion_interpolate(&cameratoworld, &kernel_data.cam.motion, ray->time);
transform_motion_interpolate(&cameratoworld, (const DecompMotionTransform*)&kernel_data.cam.motion, ray->time);
#endif
ray->P = transform_point(&cameratoworld, ray->P);
@ -108,7 +108,7 @@ __device void camera_sample_orthographic(KernelGlobals *kg, float raster_x, floa
#ifdef __CAMERA_MOTION__
if(kernel_data.cam.have_motion)
transform_motion_interpolate(&cameratoworld, &kernel_data.cam.motion, ray->time);
transform_motion_interpolate(&cameratoworld, (const DecompMotionTransform*)&kernel_data.cam.motion, ray->time);
#endif
ray->P = transform_point(&cameratoworld, ray->P);
@ -182,7 +182,7 @@ __device void camera_sample_panorama(KernelGlobals *kg, float raster_x, float ra
#ifdef __CAMERA_MOTION__
if(kernel_data.cam.have_motion)
transform_motion_interpolate(&cameratoworld, &kernel_data.cam.motion, ray->time);
transform_motion_interpolate(&cameratoworld, (const DecompMotionTransform*)&kernel_data.cam.motion, ray->time);
#endif
ray->P = transform_point(&cameratoworld, ray->P);

@ -350,10 +350,9 @@ __device int light_distribution_sample(KernelGlobals *kg, float randt)
}
}
first = max(0, first-1);
kernel_assert(first >= 0 && first < kernel_data.integrator.num_distribution);
return first;
/* clamping should not be needed but float rounding errors seem to
* make this fail on rare occasions */
return clamp(first-1, 0, kernel_data.integrator.num_distribution-1);
}
/* Generic Light */

@ -23,9 +23,8 @@ enum ObjectTransform {
OBJECT_INVERSE_TRANSFORM = 3,
OBJECT_PROPERTIES = 6,
OBJECT_TRANSFORM_MOTION_PRE = 8,
OBJECT_TRANSFORM_MOTION_MID = 12,
OBJECT_TRANSFORM_MOTION_POST = 16,
OBJECT_DUPLI = 20
OBJECT_TRANSFORM_MOTION_POST = 12,
OBJECT_DUPLI = 16
};
__device_inline Transform object_fetch_transform(KernelGlobals *kg, int object, enum ObjectTransform type)
@ -44,24 +43,19 @@ __device_inline Transform object_fetch_transform(KernelGlobals *kg, int object,
#ifdef __OBJECT_MOTION__
__device_inline Transform object_fetch_transform_motion(KernelGlobals *kg, int object, float time)
{
MotionTransform motion;
DecompMotionTransform motion;
int offset = object*OBJECT_SIZE + (int)OBJECT_TRANSFORM_MOTION_PRE;
motion.pre.x = kernel_tex_fetch(__objects, offset + 0);
motion.pre.y = kernel_tex_fetch(__objects, offset + 1);
motion.pre.z = kernel_tex_fetch(__objects, offset + 2);
motion.pre.w = kernel_tex_fetch(__objects, offset + 3);
motion.mid.x = kernel_tex_fetch(__objects, offset + 0);
motion.mid.y = kernel_tex_fetch(__objects, offset + 1);
motion.mid.z = kernel_tex_fetch(__objects, offset + 2);
motion.mid.w = kernel_tex_fetch(__objects, offset + 3);
motion.mid.x = kernel_tex_fetch(__objects, offset + 4);
motion.mid.y = kernel_tex_fetch(__objects, offset + 5);
motion.mid.z = kernel_tex_fetch(__objects, offset + 6);
motion.mid.w = kernel_tex_fetch(__objects, offset + 7);
motion.post.x = kernel_tex_fetch(__objects, offset + 8);
motion.post.y = kernel_tex_fetch(__objects, offset + 9);
motion.post.z = kernel_tex_fetch(__objects, offset + 10);
motion.post.w = kernel_tex_fetch(__objects, offset + 11);
motion.pre_x = kernel_tex_fetch(__objects, offset + 4);
motion.pre_y = kernel_tex_fetch(__objects, offset + 5);
motion.post_x = kernel_tex_fetch(__objects, offset + 6);
motion.post_y = kernel_tex_fetch(__objects, offset + 7);
Transform tfm;
transform_motion_interpolate(&tfm, &motion, time);

@ -29,7 +29,7 @@
CCL_NAMESPACE_BEGIN
/* constants */
#define OBJECT_SIZE 22
#define OBJECT_SIZE 18
#define LIGHT_SIZE 4
#define FILTER_TABLE_SIZE 256
#define RAMP_TABLE_SIZE 256
@ -102,6 +102,7 @@ CCL_NAMESPACE_BEGIN
#define __IMAGE_TEXTURES__
#define __EXTRA_NODES__
#define __HOLDOUT__
#define __NORMAL_MAP__
#endif
#ifdef __KERNEL_ADV_SHADING__
@ -112,13 +113,9 @@ CCL_NAMESPACE_BEGIN
#define __AO__
#define __CAMERA_MOTION__
#define __ANISOTROPIC__
#ifndef __KERNEL_CUDA__
#define __OBJECT_MOTION__
#endif
#endif
//#define __SOBOL_FULL_SCREEN__
/* Shader Evaluation */

@ -80,7 +80,12 @@ bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, OSL::TransformationPtr
if (object != ~0) {
#ifdef __OBJECT_MOTION__
Transform tfm = object_fetch_transform_motion_test(kg, object, time, NULL);
Transform tfm;
if(time == sd->time)
tfm = sd->ob_tfm;
else
tfm = object_fetch_transform_motion_test(kg, object, time, NULL);
#else
Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
#endif
@ -106,7 +111,11 @@ bool OSLRenderServices::get_inverse_matrix(OSL::Matrix44 &result, OSL::Transform
if (object != ~0) {
#ifdef __OBJECT_MOTION__
Transform itfm;
object_fetch_transform_motion_test(kg, object, time, &itfm);
if(time == sd->time)
itfm = sd->ob_itfm;
else
object_fetch_transform_motion_test(kg, object, time, &itfm);
#else
Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
#endif

@ -106,6 +106,7 @@ static void shaderdata_to_shaderglobals(KernelGlobals *kg, ShaderData *sd,
globals->dPdu = TO_VEC3(sd->dPdu);
globals->dPdv = TO_VEC3(sd->dPdv);
globals->surfacearea = (sd->object == ~0) ? 1.0f : object_surface_area(kg, sd->object);
globals->time = sd->time;
/* booleans */
globals->raytype = path_flag; /* todo: add our own ray types */

@ -20,6 +20,7 @@
shader node_convert_from_color(
color Color = color(0.0, 0.0, 0.0),
output string String = "",
output float Val = 0.0,
output int ValInt = 0,
output vector Vector = vector(0.0, 0.0, 0.0),

@ -20,6 +20,7 @@
shader node_convert_from_float(
float Val = 0.0,
output string String = "",
output int ValInt = 0,
output color Color = color(0.0, 0.0, 0.0),
output vector Vector = vector(0.0, 0.0, 0.0),

@ -20,6 +20,7 @@
shader node_convert_from_int(
int ValInt = 0,
output string String = "",
output float Val = 0.0,
output color Color = color(0.0, 0.0, 0.0),
output vector Vector = vector(0.0, 0.0, 0.0),

@ -20,6 +20,7 @@
shader node_convert_from_normal(
normal Normal = normal(0.0, 0.0, 0.0),
output string String = "",
output float Val = 0.0,
output int ValInt = 0,
output vector Vector = vector(0.0, 0.0, 0.0),

@ -20,6 +20,7 @@
shader node_convert_from_point(
point Point = point(0.0, 0.0, 0.0),
output string String = "",
output float Val = 0.0,
output int ValInt = 0,
output vector Vector = vector(0.0, 0.0, 0.0),

@ -0,0 +1,31 @@
/*
* Copyright 2011, Blender Foundation.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "stdosl.h"
shader node_convert_from_string(
string String = "",
output color Color = color(0.0, 0.0, 0.0),
output float Val = 0.0,
output int ValInt = 0,
output vector Vector = vector(0.0, 0.0, 0.0),
output point Point = point(0.0, 0.0, 0.0),
output normal Normal = normal(0.0, 0.0, 0.0))
{
}

@ -20,6 +20,7 @@
shader node_convert_from_vector(
vector Vector = vector(0.0, 0.0, 0.0),
output string String = "",
output float Val = 0.0,
output int ValInt = 0,
output color Color = color(0.0, 0.0, 0.0),

@ -401,9 +401,13 @@ __device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ShaderT
case NODE_LIGHT_FALLOFF:
svm_node_light_falloff(sd, stack, node);
break;
#endif
#ifdef __ANISOTROPIC__
case NODE_TANGENT:
svm_node_tangent(kg, sd, stack, node);
break;
#endif
#ifdef __NORMAL_MAP__
case NODE_NORMAL_MAP:
svm_node_normal_map(kg, sd, stack, node);
break;

@ -28,9 +28,9 @@ __device_noinline float brick_noise(int n) /* fast integer noise */
return 0.5f * ((float)nn / 1073741824.0f);
}
__device_noinline float svm_brick(float3 p, float scale, float mortar_size, float bias,
__device_noinline float2 svm_brick(float3 p, float scale, float mortar_size, float bias,
float brick_width, float row_height, float offset_amount, int offset_frequency,
float squash_amount, int squash_frequency, float *tint)
float squash_amount, int squash_frequency)
{
p *= scale;
@ -50,11 +50,12 @@ __device_noinline float svm_brick(float3 p, float scale, float mortar_size, floa
x = (p.x+offset) - brick_width*bricknum;
y = p.y - row_height*rownum;
*tint = clamp((brick_noise((rownum << 16) + (bricknum & 0xFFFF)) + bias), 0.0f, 1.0f);
return make_float2(
clamp((brick_noise((rownum << 16) + (bricknum & 0xFFFF)) + bias), 0.0f, 1.0f),
return (x < mortar_size || y < mortar_size ||
(x < mortar_size || y < mortar_size ||
x > (brick_width - mortar_size) ||
y > (row_height - mortar_size)) ? 1.0f : 0.0f;
y > (row_height - mortar_size)) ? 1.0f : 0.0f);
}
__device void svm_node_tex_brick(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset)
@ -70,8 +71,6 @@ __device void svm_node_tex_brick(KernelGlobals *kg, ShaderData *sd, float *stack
/* RNA properties */
uint offset_frequency, squash_frequency;
float tint = 0.0f;
decode_node_uchar4(node.y, &co_offset, &color1_offset, &color2_offset, &mortar_offset);
decode_node_uchar4(node.z, &scale_offset, &mortar_size_offset, &bias_offset, &brick_width_offset);
decode_node_uchar4(node.w, &row_height_offset, &color_offset, &fac_offset, NULL);
@ -92,9 +91,11 @@ __device void svm_node_tex_brick(KernelGlobals *kg, ShaderData *sd, float *stack
float offset_amount = __int_as_float(node3.z);
float squash_amount = __int_as_float(node3.w);
float f = svm_brick(co, scale, mortar_size, bias, brick_width, row_height,
offset_amount, offset_frequency, squash_amount, squash_frequency,
&tint);
float2 f2 = svm_brick(co, scale, mortar_size, bias, brick_width, row_height,
offset_amount, offset_frequency, squash_amount, squash_frequency);
float tint = f2.x;
float f = f2.y;
if(f != 1.0f) {
float facm = 1.0f - tint;

@ -50,25 +50,41 @@ __device void svm_node_glass_setup(ShaderData *sd, ShaderClosure *sc, int type,
}
}
__device_inline ShaderClosure *svm_node_closure_get(ShaderData *sd)
__device_inline ShaderClosure *svm_node_closure_get_non_bsdf(ShaderData *sd, ClosureType type, float mix_weight)
{
#ifdef __MULTI_CLOSURE__
ShaderClosure *sc = &sd->closure[sd->num_closure];
if(sd->num_closure < MAX_CLOSURE)
if(sd->num_closure < MAX_CLOSURE) {
sc->weight *= mix_weight;
sc->type = type;
sd->num_closure++;
return sc;
}
return sc;
return NULL;
#else
return &sd->closure;
#endif
}
__device_inline void svm_node_closure_set_mix_weight(ShaderClosure *sc, float mix_weight)
__device_inline ShaderClosure *svm_node_closure_get_bsdf(ShaderData *sd, float mix_weight)
{
#ifdef __MULTI_CLOSURE__
sc->weight *= mix_weight;
sc->sample_weight = fabsf(average(sc->weight));
ShaderClosure *sc = &sd->closure[sd->num_closure];
float3 weight = sc->weight * mix_weight;
float sample_weight = fabsf(average(sc->weight));
if(sample_weight > 1e-5f && sd->num_closure < MAX_CLOSURE) {
sc->weight = weight;
sc->sample_weight = sample_weight;
sd->num_closure++;
return sc;
}
return NULL;
#else
return &sd->closure;
#endif
}
@ -101,33 +117,39 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st
switch(type) {
case CLOSURE_BSDF_DIFFUSE_ID: {
ShaderClosure *sc = svm_node_closure_get(sd);
sc->N = N;
svm_node_closure_set_mix_weight(sc, mix_weight);
ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight);
float roughness = param1;
if(sc) {
sc->N = N;
if(roughness == 0.0f) {
sd->flag |= bsdf_diffuse_setup(sc);
}
else {
sc->data0 = roughness;
sd->flag |= bsdf_oren_nayar_setup(sc);
float roughness = param1;
if(roughness == 0.0f) {
sd->flag |= bsdf_diffuse_setup(sc);
}
else {
sc->data0 = roughness;
sd->flag |= bsdf_oren_nayar_setup(sc);
}
}
break;
}
case CLOSURE_BSDF_TRANSLUCENT_ID: {
ShaderClosure *sc = svm_node_closure_get(sd);
sc->N = N;
svm_node_closure_set_mix_weight(sc, mix_weight);
sd->flag |= bsdf_translucent_setup(sc);
ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight);
if(sc) {
sc->N = N;
sd->flag |= bsdf_translucent_setup(sc);
}
break;
}
case CLOSURE_BSDF_TRANSPARENT_ID: {
ShaderClosure *sc = svm_node_closure_get(sd);
sc->N = N;
svm_node_closure_set_mix_weight(sc, mix_weight);
sd->flag |= bsdf_transparent_setup(sc);
ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight);
if(sc) {
sc->N = N;
sd->flag |= bsdf_transparent_setup(sc);
}
break;
}
case CLOSURE_BSDF_REFLECTION_ID:
@ -137,18 +159,20 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st
if(kernel_data.integrator.no_caustics && (path_flag & PATH_RAY_DIFFUSE))
break;
#endif
ShaderClosure *sc = svm_node_closure_get(sd);
sc->N = N;
sc->data0 = param1;
svm_node_closure_set_mix_weight(sc, mix_weight);
ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight);
/* setup bsdf */
if(type == CLOSURE_BSDF_REFLECTION_ID)
sd->flag |= bsdf_reflection_setup(sc);
else if(type == CLOSURE_BSDF_MICROFACET_BECKMANN_ID)
sd->flag |= bsdf_microfacet_beckmann_setup(sc);
else
sd->flag |= bsdf_microfacet_ggx_setup(sc);
if(sc) {
sc->N = N;
sc->data0 = param1;
/* setup bsdf */
if(type == CLOSURE_BSDF_REFLECTION_ID)
sd->flag |= bsdf_reflection_setup(sc);
else if(type == CLOSURE_BSDF_MICROFACET_BECKMANN_ID)
sd->flag |= bsdf_microfacet_beckmann_setup(sc);
else
sd->flag |= bsdf_microfacet_ggx_setup(sc);
}
break;
}
@ -159,21 +183,23 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st
if(kernel_data.integrator.no_caustics && (path_flag & PATH_RAY_DIFFUSE))
break;
#endif
ShaderClosure *sc = svm_node_closure_get(sd);
sc->N = N;
sc->data0 = param1;
svm_node_closure_set_mix_weight(sc, mix_weight);
ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight);
float eta = fmaxf(param2, 1.0f + 1e-5f);
sc->data1 = (sd->flag & SD_BACKFACING)? 1.0f/eta: eta;
if(sc) {
sc->N = N;
sc->data0 = param1;
/* setup bsdf */
if(type == CLOSURE_BSDF_REFRACTION_ID)
sd->flag |= bsdf_refraction_setup(sc);
else if(type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID)
sd->flag |= bsdf_microfacet_beckmann_refraction_setup(sc);
else
sd->flag |= bsdf_microfacet_ggx_refraction_setup(sc);
float eta = fmaxf(param2, 1.0f + 1e-5f);
sc->data1 = (sd->flag & SD_BACKFACING)? 1.0f/eta: eta;
/* setup bsdf */
if(type == CLOSURE_BSDF_REFRACTION_ID)
sd->flag |= bsdf_refraction_setup(sc);
else if(type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID)
sd->flag |= bsdf_microfacet_beckmann_refraction_setup(sc);
else
sd->flag |= bsdf_microfacet_ggx_refraction_setup(sc);
}
break;
}
@ -195,32 +221,36 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st
#ifdef __MULTI_CLOSURE__
/* reflection */
ShaderClosure *sc = svm_node_closure_get(sd);
sc->N = N;
ShaderClosure *sc = &sd->closure[sd->num_closure];
float3 weight = sc->weight;
float sample_weight = sc->sample_weight;
svm_node_closure_set_mix_weight(sc, mix_weight*fresnel);
svm_node_glass_setup(sd, sc, type, eta, roughness, false);
sc = svm_node_closure_get_bsdf(sd, mix_weight*fresnel);
if(sc) {
sc->N = N;
svm_node_glass_setup(sd, sc, type, eta, roughness, false);
}
/* refraction */
sc = svm_node_closure_get(sd);
sc->N = N;
sc = &sd->closure[sd->num_closure];
sc->weight = weight;
sc->sample_weight = sample_weight;
svm_node_closure_set_mix_weight(sc, mix_weight*(1.0f - fresnel));
svm_node_glass_setup(sd, sc, type, eta, roughness, true);
sc = svm_node_closure_get_bsdf(sd, mix_weight*(1.0f - fresnel));
if(sc) {
sc->N = N;
svm_node_glass_setup(sd, sc, type, eta, roughness, true);
}
#else
ShaderClosure *sc = svm_node_closure_get(sd);
sc->N = N;
ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight);
bool refract = (randb > fresnel);
svm_node_closure_set_mix_weight(sc, mix_weight);
svm_node_glass_setup(sd, sc, type, eta, roughness, refract);
if(sc) {
sc->N = N;
bool refract = (randb > fresnel);
svm_node_glass_setup(sd, sc, type, eta, roughness, refract);
}
#endif
break;
@ -230,46 +260,50 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st
if(kernel_data.integrator.no_caustics && (path_flag & PATH_RAY_DIFFUSE))
break;
#endif
ShaderClosure *sc = svm_node_closure_get(sd);
sc->N = N;
svm_node_closure_set_mix_weight(sc, mix_weight);
ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight);
if(sc) {
sc->N = N;
#ifdef __ANISOTROPIC__
sc->T = stack_load_float3(stack, data_node.z);
sc->T = stack_load_float3(stack, data_node.z);
/* rotate tangent */
float rotation = stack_load_float(stack, data_node.w);
/* rotate tangent */
float rotation = stack_load_float(stack, data_node.w);
if(rotation != 0.0f)
sc->T = rotate_around_axis(sc->T, sc->N, rotation * 2.0f * M_PI_F);
if(rotation != 0.0f)
sc->T = rotate_around_axis(sc->T, sc->N, rotation * 2.0f * M_PI_F);
/* compute roughness */
float roughness = param1;
float anisotropy = clamp(param2, -0.99f, 0.99f);
/* compute roughness */
float roughness = param1;
float anisotropy = clamp(param2, -0.99f, 0.99f);
if(anisotropy < 0.0f) {
sc->data0 = roughness/(1.0f + anisotropy);
sc->data1 = roughness*(1.0f + anisotropy);
}
else {
sc->data0 = roughness*(1.0f - anisotropy);
sc->data1 = roughness/(1.0f - anisotropy);
}
if(anisotropy < 0.0f) {
sc->data0 = roughness/(1.0f + anisotropy);
sc->data1 = roughness*(1.0f + anisotropy);
}
else {
sc->data0 = roughness*(1.0f - anisotropy);
sc->data1 = roughness/(1.0f - anisotropy);
}
sd->flag |= bsdf_ward_setup(sc);
sd->flag |= bsdf_ward_setup(sc);
#else
sd->flag |= bsdf_diffuse_setup(sc);
sd->flag |= bsdf_diffuse_setup(sc);
#endif
}
break;
}
case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: {
ShaderClosure *sc = svm_node_closure_get(sd);
sc->N = N;
svm_node_closure_set_mix_weight(sc, mix_weight);
ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight);
/* sigma */
sc->data0 = clamp(param1, 0.0f, 1.0f);
sd->flag |= bsdf_ashikhmin_velvet_setup(sc);
if(sc) {
sc->N = N;
/* sigma */
sc->data0 = clamp(param1, 0.0f, 1.0f);
sd->flag |= bsdf_ashikhmin_velvet_setup(sc);
}
break;
}
default:
@ -298,19 +332,21 @@ __device void svm_node_closure_volume(KernelGlobals *kg, ShaderData *sd, float *
switch(type) {
case CLOSURE_VOLUME_TRANSPARENT_ID: {
ShaderClosure *sc = svm_node_closure_get(sd);
svm_node_closure_set_mix_weight(sc, mix_weight);
ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight);
float density = param1;
sd->flag |= volume_transparent_setup(sc, density);
if(sc) {
float density = param1;
sd->flag |= volume_transparent_setup(sc, density);
}
break;
}
case CLOSURE_VOLUME_ISOTROPIC_ID: {
ShaderClosure *sc = svm_node_closure_get(sd);
svm_node_closure_set_mix_weight(sc, mix_weight);
ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight);
float density = param1;
sd->flag |= volume_isotropic_setup(sc, density);
if(sc) {
float density = param1;
sd->flag |= volume_isotropic_setup(sc, density);
}
break;
}
default:
@ -329,15 +365,10 @@ __device void svm_node_closure_emission(ShaderData *sd, float *stack, uint4 node
if(mix_weight == 0.0f)
return;
ShaderClosure *sc = svm_node_closure_get(sd);
sc->weight *= mix_weight;
sc->type = CLOSURE_EMISSION_ID;
svm_node_closure_get_non_bsdf(sd, CLOSURE_EMISSION_ID, mix_weight);
}
else {
ShaderClosure *sc = svm_node_closure_get(sd);
sc->type = CLOSURE_EMISSION_ID;
}
else
svm_node_closure_get_non_bsdf(sd, CLOSURE_EMISSION_ID, 1.0f);
#else
ShaderClosure *sc = &sd->closure;
sc->type = CLOSURE_EMISSION_ID;
@ -357,15 +388,10 @@ __device void svm_node_closure_background(ShaderData *sd, float *stack, uint4 no
if(mix_weight == 0.0f)
return;
ShaderClosure *sc = svm_node_closure_get(sd);
sc->weight *= mix_weight;
sc->type = CLOSURE_BACKGROUND_ID;
svm_node_closure_get_non_bsdf(sd, CLOSURE_BACKGROUND_ID, mix_weight);
}
else {
ShaderClosure *sc = svm_node_closure_get(sd);
sc->type = CLOSURE_BACKGROUND_ID;
}
else
svm_node_closure_get_non_bsdf(sd, CLOSURE_BACKGROUND_ID, 1.0f);
#else
ShaderClosure *sc = &sd->closure;
sc->type = CLOSURE_BACKGROUND_ID;
@ -383,15 +409,10 @@ __device void svm_node_closure_holdout(ShaderData *sd, float *stack, uint4 node)
if(mix_weight == 0.0f)
return;
ShaderClosure *sc = svm_node_closure_get(sd);
sc->weight = make_float3(mix_weight, mix_weight, mix_weight);
sc->type = CLOSURE_HOLDOUT_ID;
}
else {
ShaderClosure *sc = svm_node_closure_get(sd);
sc->weight = make_float3(1.0f, 1.0f, 1.0f);
sc->type = CLOSURE_HOLDOUT_ID;
svm_node_closure_get_non_bsdf(sd, CLOSURE_HOLDOUT_ID, mix_weight);
}
else
svm_node_closure_get_non_bsdf(sd, CLOSURE_HOLDOUT_ID, 1.0f);
#else
ShaderClosure *sc = &sd->closure;
sc->type = CLOSURE_HOLDOUT_ID;
@ -411,15 +432,10 @@ __device void svm_node_closure_ambient_occlusion(ShaderData *sd, float *stack, u
if(mix_weight == 0.0f)
return;
ShaderClosure *sc = svm_node_closure_get(sd);
sc->weight *= mix_weight;
sc->type = CLOSURE_AMBIENT_OCCLUSION_ID;
svm_node_closure_get_non_bsdf(sd, CLOSURE_AMBIENT_OCCLUSION_ID, mix_weight);
}
else {
ShaderClosure *sc = svm_node_closure_get(sd);
sc->type = CLOSURE_AMBIENT_OCCLUSION_ID;
}
else
svm_node_closure_get_non_bsdf(sd, CLOSURE_AMBIENT_OCCLUSION_ID, 1.0f);
#else
ShaderClosure *sc = &sd->closure;
sc->type = CLOSURE_AMBIENT_OCCLUSION_ID;
@ -433,7 +449,8 @@ __device void svm_node_closure_ambient_occlusion(ShaderData *sd, float *stack, u
__device_inline void svm_node_closure_store_weight(ShaderData *sd, float3 weight)
{
#ifdef __MULTI_CLOSURE__
sd->closure[sd->num_closure].weight = weight;
if(sd->num_closure < MAX_CLOSURE)
sd->closure[sd->num_closure].weight = weight;
#else
sd->closure.weight = weight;
#endif

@ -42,8 +42,12 @@ __device float voronoi_distance(NodeDistanceMetric distance_metric, float3 d, fl
/* Voronoi / Worley like */
__device_noinline void voronoi(float3 p, NodeDistanceMetric distance_metric, float e, float da[4], float3 pa[4])
__device_noinline float4 voronoi_Fn(float3 p, float e, int n1, int n2)
{
float da[4];
float3 pa[4];
NodeDistanceMetric distance_metric = NODE_VORONOI_DISTANCE_SQUARED;
/* returns distances in da and point coords in pa */
int xx, yy, zz, xi, yi, zi;
@ -105,33 +109,20 @@ __device_noinline void voronoi(float3 p, NodeDistanceMetric distance_metric, flo
}
}
}
float4 result = make_float4(pa[n1].x, pa[n1].y, pa[n1].z, da[n1]);
if(n2 != -1)
result = make_float4(pa[n2].x, pa[n2].y, pa[n2].z, da[n2]) - result;
return result;
}
__device float voronoi_Fn(float3 p, int n)
{
float da[4];
float3 pa[4];
voronoi(p, NODE_VORONOI_DISTANCE_SQUARED, 0, da, pa);
return da[n];
}
__device float voronoi_FnFn(float3 p, int n1, int n2)
{
float da[4];
float3 pa[4];
voronoi(p, NODE_VORONOI_DISTANCE_SQUARED, 0, da, pa);
return da[n2] - da[n1];
}
__device float voronoi_F1(float3 p) { return voronoi_Fn(p, 0); }
__device float voronoi_F2(float3 p) { return voronoi_Fn(p, 1); }
__device float voronoi_F3(float3 p) { return voronoi_Fn(p, 2); }
__device float voronoi_F4(float3 p) { return voronoi_Fn(p, 3); }
__device float voronoi_F1F2(float3 p) { return voronoi_FnFn(p, 0, 1); }
__device float voronoi_F1(float3 p) { return voronoi_Fn(p, 0.0f, 0, -1).w; }
__device float voronoi_F2(float3 p) { return voronoi_Fn(p, 0.0f, 1, -1).w; }
__device float voronoi_F3(float3 p) { return voronoi_Fn(p, 0.0f, 2, -1).w; }
__device float voronoi_F4(float3 p) { return voronoi_Fn(p, 0.0f, 3, -1).w; }
__device float voronoi_F1F2(float3 p) { return voronoi_Fn(p, 0.0f, 0, 1).w; }
__device float voronoi_Cr(float3 p)
{

@ -23,21 +23,18 @@ CCL_NAMESPACE_BEGIN
__device_noinline float4 svm_voronoi(NodeVoronoiColoring coloring, float scale, float3 p)
{
/* compute distance and point coordinate of 4 nearest neighbours */
float da[4];
float3 pa[4];
voronoi(p*scale, NODE_VORONOI_DISTANCE_SQUARED, 1.0f, da, pa);
float4 dpa0 = voronoi_Fn(p*scale, 1.0f, 0, -1);
/* output */
float fac;
float3 color;
if(coloring == NODE_VORONOI_INTENSITY) {
fac = fabsf(da[0]);
fac = fabsf(dpa0.w);
color = make_float3(fac, fac, fac);
}
else {
color = cellnoise_color(pa[0]);
color = cellnoise_color(float4_to_float3(dpa0));
fac = average(color);
}

@ -202,7 +202,7 @@ void Camera::device_update(Device *device, DeviceScene *dscene, Scene *scene)
#ifdef __CAMERA_MOTION__
else if(need_motion == Scene::MOTION_BLUR) {
if(use_motion) {
transform_motion_decompose(&kcam->motion, &motion, &matrix);
transform_motion_decompose((DecompMotionTransform*)&kcam->motion, &motion, &matrix);
kcam->have_motion = 1;
}
}

@ -37,7 +37,7 @@ ShaderInput::ShaderInput(ShaderNode *parent_, const char *name_, ShaderSocketTyp
value = make_float3(0, 0, 0);
stack_offset = SVM_STACK_INVALID;
default_value = NONE;
osl_only = false;
usage = USE_ALL;
}
ShaderOutput::ShaderOutput(ShaderNode *parent_, const char *name_, ShaderSocketType type_)
@ -85,27 +85,29 @@ ShaderOutput *ShaderNode::output(const char *name)
return NULL;
}
ShaderInput *ShaderNode::add_input(const char *name, ShaderSocketType type, float value)
ShaderInput *ShaderNode::add_input(const char *name, ShaderSocketType type, float value, int usage)
{
ShaderInput *input = new ShaderInput(this, name, type);
input->value.x = value;
input->usage = usage;
inputs.push_back(input);
return input;
}
ShaderInput *ShaderNode::add_input(const char *name, ShaderSocketType type, float3 value)
ShaderInput *ShaderNode::add_input(const char *name, ShaderSocketType type, float3 value, int usage)
{
ShaderInput *input = new ShaderInput(this, name, type);
input->value = value;
input->usage = usage;
inputs.push_back(input);
return input;
}
ShaderInput *ShaderNode::add_input(const char *name, ShaderSocketType type, ShaderInput::DefaultValue value, bool osl_only)
ShaderInput *ShaderNode::add_input(const char *name, ShaderSocketType type, ShaderInput::DefaultValue value, int usage)
{
ShaderInput *input = add_input(name, type);
input->default_value = value;
input->osl_only = osl_only;
input->usage = usage;
return input;
}
@ -219,7 +221,7 @@ void ShaderGraph::disconnect(ShaderInput *to)
from->links.erase(remove(from->links.begin(), from->links.end(), to), from->links.end());
}
void ShaderGraph::finalize(bool do_bump, bool do_osl)
void ShaderGraph::finalize(bool do_bump, bool do_osl, bool do_multi_transform)
{
/* before compiling, the shader graph may undergo a number of modifications.
* currently we set default geometry shader inputs, and create automatic bump
@ -234,6 +236,18 @@ void ShaderGraph::finalize(bool do_bump, bool do_osl)
if(do_bump)
bump_from_displacement();
if(do_multi_transform) {
ShaderInput *surface_in = output()->input("Surface");
ShaderInput *volume_in = output()->input("Volume");
/* todo: make this work when surface and volume closures are tangled up */
if(surface_in->link)
transform_multi_closure(surface_in->link->parent, NULL, false);
if(volume_in->link)
transform_multi_closure(volume_in->link->parent, NULL, true);
}
finalized = true;
}
}
@ -440,7 +454,7 @@ void ShaderGraph::default_inputs(bool do_osl)
foreach(ShaderNode *node, nodes) {
foreach(ShaderInput *input, node->inputs) {
if(!input->link && !(input->osl_only && !do_osl)) {
if(!input->link && ((input->usage & ShaderInput::USE_SVM) || do_osl)) {
if(input->default_value == ShaderInput::TEXTURE_GENERATED) {
if(!texco)
texco = new TextureCoordinateNode();
@ -629,5 +643,81 @@ void ShaderGraph::bump_from_displacement()
add(pair.second);
}
void ShaderGraph::transform_multi_closure(ShaderNode *node, ShaderOutput *weight_out, bool volume)
{
/* for SVM in multi closure mode, this transforms the shader mix/add part of
* the graph into nodes that feed weights into closure nodes. this is too
* avoid building a closure tree and then flattening it, and instead write it
* directly to an array */
if(node->name == ustring("mix_closure") || node->name == ustring("add_closure")) {
ShaderInput *fin = node->input("Fac");
ShaderInput *cl1in = node->input("Closure1");
ShaderInput *cl2in = node->input("Closure2");
ShaderOutput *weight1_out, *weight2_out;
if(fin) {
/* mix closure: add node to mix closure weights */
ShaderNode *mix_node = add(new MixClosureWeightNode());
ShaderInput *fac_in = mix_node->input("Fac");
ShaderInput *weight_in = mix_node->input("Weight");
if(fin->link)
connect(fin->link, fac_in);
else
fac_in->value = fin->value;
if(weight_out)
connect(weight_out, weight_in);
weight1_out = mix_node->output("Weight1");
weight2_out = mix_node->output("Weight2");
}
else {
/* add closure: just pass on any weights */
weight1_out = weight_out;
weight2_out = weight_out;
}
if(cl1in->link)
transform_multi_closure(cl1in->link->parent, weight1_out, volume);
if(cl2in->link)
transform_multi_closure(cl2in->link->parent, weight2_out, volume);
}
else {
ShaderInput *weight_in = node->input((volume)? "VolumeMixWeight": "SurfaceMixWeight");
/* not a closure node? */
if(!weight_in)
return;
/* already has a weight connected to it? add weights */
if(weight_in->link || weight_in->value.x != 0.0f) {
ShaderNode *math_node = add(new MathNode());
ShaderInput *value1_in = math_node->input("Value1");
ShaderInput *value2_in = math_node->input("Value2");
if(weight_in->link)
connect(weight_in->link, value1_in);
else
value1_in->value = weight_in->value;
if(weight_out)
connect(weight_out, value2_in);
else
value2_in->value.x = 1.0f;
weight_out = math_node->output("Value");
disconnect(weight_in);
}
/* connected to closure mix weight */
if(weight_out)
connect(weight_out, weight_in);
else
weight_in->value.x += 1.0f;
}
}
CCL_NAMESPACE_END

@ -118,6 +118,12 @@ public:
NONE
};
enum Usage {
USE_SVM = 1,
USE_OSL = 2,
USE_ALL = USE_SVM|USE_OSL
};
ShaderInput(ShaderNode *parent, const char *name, ShaderSocketType type);
void set(const float3& v) { value = v; }
void set(float f) { value = make_float3(f, 0, 0); }
@ -134,7 +140,7 @@ public:
ustring value_string;
int stack_offset; /* for SVM compiler */
bool osl_only;
int usage;
};
/* Output
@ -167,9 +173,9 @@ public:
ShaderInput *input(const char *name);
ShaderOutput *output(const char *name);
ShaderInput *add_input(const char *name, ShaderSocketType type, float value=0.0f);
ShaderInput *add_input(const char *name, ShaderSocketType type, float3 value);
ShaderInput *add_input(const char *name, ShaderSocketType type, ShaderInput::DefaultValue value, bool osl_only=false);
ShaderInput *add_input(const char *name, ShaderSocketType type, float value=0.0f, int usage=ShaderInput::USE_ALL);
ShaderInput *add_input(const char *name, ShaderSocketType type, float3 value, int usage=ShaderInput::USE_ALL);
ShaderInput *add_input(const char *name, ShaderSocketType type, ShaderInput::DefaultValue value, int usage=ShaderInput::USE_ALL);
ShaderOutput *add_output(const char *name, ShaderSocketType type);
virtual ShaderNode *clone() const = 0;
@ -227,7 +233,7 @@ public:
void connect(ShaderOutput *from, ShaderInput *to);
void disconnect(ShaderInput *to);
void finalize(bool do_bump = false, bool do_osl = false);
void finalize(bool do_bump = false, bool do_osl = false, bool do_multi_closure = false);
protected:
typedef pair<ShaderNode* const, ShaderNode*> NodePair;
@ -241,6 +247,7 @@ protected:
void bump_from_displacement();
void refine_bump_nodes();
void default_inputs(bool do_osl);
void transform_multi_closure(ShaderNode *node, ShaderOutput *weight_out, bool volume);
};
CCL_NAMESPACE_END

@ -1124,6 +1124,8 @@ ConvertNode::ConvertNode(ShaderSocketType from_, ShaderSocketType to_)
add_input("Point", SHADER_SOCKET_POINT);
else if(from == SHADER_SOCKET_NORMAL)
add_input("Normal", SHADER_SOCKET_NORMAL);
else if(from == SHADER_SOCKET_STRING)
add_input("String", SHADER_SOCKET_STRING);
else
assert(0);
@ -1139,6 +1141,8 @@ ConvertNode::ConvertNode(ShaderSocketType from_, ShaderSocketType to_)
add_output("Point", SHADER_SOCKET_POINT);
else if(to == SHADER_SOCKET_NORMAL)
add_output("Normal", SHADER_SOCKET_NORMAL);
else if(to == SHADER_SOCKET_STRING)
add_output("String", SHADER_SOCKET_STRING);
else
assert(0);
}
@ -1257,6 +1261,7 @@ BsdfNode::BsdfNode()
add_input("Color", SHADER_SOCKET_COLOR, make_float3(0.8f, 0.8f, 0.8f));
add_input("Normal", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL);
add_input("SurfaceMixWeight", SHADER_SOCKET_FLOAT, 0.0f, ShaderInput::USE_SVM);
add_output("BSDF", SHADER_SOCKET_CLOSURE);
}
@ -1544,6 +1549,8 @@ EmissionNode::EmissionNode()
add_input("Color", SHADER_SOCKET_COLOR, make_float3(0.8f, 0.8f, 0.8f));
add_input("Strength", SHADER_SOCKET_FLOAT, 10.0f);
add_input("SurfaceMixWeight", SHADER_SOCKET_FLOAT, 0.0f, ShaderInput::USE_SVM);
add_output("Emission", SHADER_SOCKET_CLOSURE);
}
@ -1578,6 +1585,8 @@ BackgroundNode::BackgroundNode()
{
add_input("Color", SHADER_SOCKET_COLOR, make_float3(0.8f, 0.8f, 0.8f));
add_input("Strength", SHADER_SOCKET_FLOAT, 1.0f);
add_input("SurfaceMixWeight", SHADER_SOCKET_FLOAT, 0.0f, ShaderInput::USE_SVM);
add_output("Background", SHADER_SOCKET_CLOSURE);
}
@ -1607,11 +1616,17 @@ void BackgroundNode::compile(OSLCompiler& compiler)
HoldoutNode::HoldoutNode()
: ShaderNode("holdout")
{
add_input("SurfaceMixWeight", SHADER_SOCKET_FLOAT, 0.0f, ShaderInput::USE_SVM);
add_input("VolumeMixWeight", SHADER_SOCKET_FLOAT, 0.0f, ShaderInput::USE_SVM);
add_output("Holdout", SHADER_SOCKET_CLOSURE);
}
void HoldoutNode::compile(SVMCompiler& compiler)
{
float3 value = make_float3(1.0f, 1.0f, 1.0f);
compiler.add_node(NODE_CLOSURE_SET_WEIGHT, value);
compiler.add_node(NODE_CLOSURE_HOLDOUT, compiler.closure_mix_weight_offset());
}
@ -1625,9 +1640,10 @@ void HoldoutNode::compile(OSLCompiler& compiler)
AmbientOcclusionNode::AmbientOcclusionNode()
: ShaderNode("ambient_occlusion")
{
add_input("NormalIn", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, true);
add_input("NormalIn", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, ShaderInput::USE_OSL);
add_input("Color", SHADER_SOCKET_COLOR, make_float3(0.8f, 0.8f, 0.8f));
add_input("SurfaceMixWeight", SHADER_SOCKET_FLOAT, 0.0f, ShaderInput::USE_SVM);
add_output("AO", SHADER_SOCKET_CLOSURE);
}
@ -1659,6 +1675,7 @@ VolumeNode::VolumeNode()
add_input("Color", SHADER_SOCKET_COLOR, make_float3(0.8f, 0.8f, 0.8f));
add_input("Density", SHADER_SOCKET_FLOAT, 1.0f);
add_input("VolumeMixWeight", SHADER_SOCKET_FLOAT, 0.0f, ShaderInput::USE_SVM);
add_output("Volume", SHADER_SOCKET_CLOSURE);
}
@ -1737,7 +1754,7 @@ void IsotropicVolumeNode::compile(OSLCompiler& compiler)
GeometryNode::GeometryNode()
: ShaderNode("geometry")
{
add_input("NormalIn", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, true);
add_input("NormalIn", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, ShaderInput::USE_OSL);
add_output("Position", SHADER_SOCKET_POINT);
add_output("Normal", SHADER_SOCKET_NORMAL);
add_output("Tangent", SHADER_SOCKET_NORMAL);
@ -1825,7 +1842,7 @@ void GeometryNode::compile(OSLCompiler& compiler)
TextureCoordinateNode::TextureCoordinateNode()
: ShaderNode("texture_coordinate")
{
add_input("NormalIn", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, true);
add_input("NormalIn", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, ShaderInput::USE_OSL);
add_output("Generated", SHADER_SOCKET_POINT);
add_output("Normal", SHADER_SOCKET_NORMAL);
add_output("UV", SHADER_SOCKET_POINT);
@ -2315,6 +2332,39 @@ void MixClosureNode::compile(OSLCompiler& compiler)
compiler.add(this, "node_mix_closure");
}
/* Mix Closure */
MixClosureWeightNode::MixClosureWeightNode()
: ShaderNode("mix_closure_weight")
{
add_input("Weight", SHADER_SOCKET_FLOAT, 1.0f);
add_input("Fac", SHADER_SOCKET_FLOAT, 1.0f);
add_output("Weight1", SHADER_SOCKET_FLOAT);
add_output("Weight2", SHADER_SOCKET_FLOAT);
}
void MixClosureWeightNode::compile(SVMCompiler& compiler)
{
ShaderInput *weight_in = input("Weight");
ShaderInput *fac_in = input("Fac");
ShaderOutput *weight1_out = output("Weight1");
ShaderOutput *weight2_out = output("Weight2");
compiler.stack_assign(weight_in);
compiler.stack_assign(fac_in);
compiler.stack_assign(weight1_out);
compiler.stack_assign(weight2_out);
compiler.add_node(NODE_MIX_CLOSURE,
compiler.encode_uchar4(fac_in->stack_offset, weight_in->stack_offset,
weight1_out->stack_offset, weight2_out->stack_offset));
}
void MixClosureWeightNode::compile(OSLCompiler& compiler)
{
assert(0);
}
/* Invert */
InvertNode::InvertNode()
@ -2680,7 +2730,7 @@ void CameraNode::compile(OSLCompiler& compiler)
FresnelNode::FresnelNode()
: ShaderNode("Fresnel")
{
add_input("Normal", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, true);
add_input("Normal", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, ShaderInput::USE_OSL);
add_input("IOR", SHADER_SOCKET_FLOAT, 1.45f);
add_output("Fac", SHADER_SOCKET_FLOAT);
}
@ -2705,7 +2755,7 @@ void FresnelNode::compile(OSLCompiler& compiler)
LayerWeightNode::LayerWeightNode()
: ShaderNode("LayerWeight")
{
add_input("Normal", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, true);
add_input("Normal", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, ShaderInput::USE_OSL);
add_input("Blend", SHADER_SOCKET_FLOAT, 0.5f);
add_output("Fresnel", SHADER_SOCKET_FLOAT);
@ -3080,7 +3130,7 @@ NormalMapNode::NormalMapNode()
space = ustring("Tangent");
attribute = ustring("");
add_input("NormalIn", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, true);
add_input("NormalIn", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, ShaderInput::USE_OSL);
add_input("Strength", SHADER_SOCKET_FLOAT, 1.0f);
add_input("Color", SHADER_SOCKET_COLOR);
@ -3185,7 +3235,7 @@ TangentNode::TangentNode()
axis = ustring("X");
attribute = ustring("");
add_input("NormalIn", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, true);
add_input("NormalIn", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, ShaderInput::USE_OSL);
add_output("Tangent", SHADER_SOCKET_NORMAL);
}

@ -351,6 +351,11 @@ public:
SHADER_NODE_CLASS(MixClosureNode)
};
class MixClosureWeightNode : public ShaderNode {
public:
SHADER_NODE_CLASS(MixClosureWeightNode);
};
class InvertNode : public ShaderNode {
public:
SHADER_NODE_CLASS(InvertNode)

@ -56,7 +56,7 @@ void Object::compute_bounds(bool motion_blur, float shuttertime)
BoundBox mbounds = mesh->bounds;
if(motion_blur && use_motion) {
MotionTransform decomp;
DecompMotionTransform decomp;
transform_motion_decompose(&decomp, &motion, &tfm);
bounds = BoundBox::empty;
@ -222,29 +222,29 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene
mtfm_post = mtfm_post * itfm;
memcpy(&objects[offset+8], &mtfm_pre, sizeof(float4)*4);
memcpy(&objects[offset+16], &mtfm_post, sizeof(float4)*4);
memcpy(&objects[offset+12], &mtfm_post, sizeof(float4)*4);
}
#ifdef __OBJECT_MOTION__
else if(need_motion == Scene::MOTION_BLUR) {
if(ob->use_motion) {
/* decompose transformations for interpolation */
MotionTransform decomp;
DecompMotionTransform decomp;
transform_motion_decompose(&decomp, &ob->motion, &ob->tfm);
memcpy(&objects[offset+8], &decomp, sizeof(float4)*12);
memcpy(&objects[offset+8], &decomp, sizeof(float4)*8);
flag |= SD_OBJECT_MOTION;
have_motion = true;
}
else {
float4 no_motion = make_float4(FLT_MAX);
memcpy(&objects[offset+8], &no_motion, sizeof(float4)*12);
memcpy(&objects[offset+8], &no_motion, sizeof(float4)*8);
}
}
#endif
/* dupli object coords */
objects[offset+20] = make_float4(ob->dupli_generated[0], ob->dupli_generated[1], ob->dupli_generated[2], 0.0f);
objects[offset+21] = make_float4(ob->dupli_uv[0], ob->dupli_uv[1], 0.0f, 0.0f);
objects[offset+16] = make_float4(ob->dupli_generated[0], ob->dupli_generated[1], ob->dupli_generated[2], 0.0f);
objects[offset+17] = make_float4(ob->dupli_uv[0], ob->dupli_uv[1], 0.0f, 0.0f);
/* object flag */
if(ob->use_holdout)

@ -138,6 +138,7 @@ void OSLShaderManager::texture_system_init()
ts = TextureSystem::create(true);
ts->attribute("automip", 1);
ts->attribute("autotile", 64);
ts->attribute("gray_to_rgb", 1);
/* effectively unlimited for now, until we support proper mipmap lookups */
ts->attribute("max_memory_MB", 16384);
@ -351,6 +352,9 @@ bool OSLCompiler::node_skip_input(ShaderNode *node, ShaderInput *input)
{
/* exception for output node, only one input is actually used
* depending on the current shader type */
if(!(input->usage & ShaderInput::USE_OSL))
return true;
if(node->name == ustring("output")) {
if(strcmp(input->name, "Surface") == 0 && current_type != SHADER_TYPE_SURFACE)

@ -637,6 +637,15 @@ void Session::reset(BufferParams& buffer_params, int samples)
reset_gpu(buffer_params, samples);
else
reset_cpu(buffer_params, samples);
if(params.progressive_refine) {
thread_scoped_lock buffers_lock(buffers_mutex);
foreach(RenderBuffers *buffers, tile_buffers)
delete buffers;
tile_buffers.clear();
}
}
void Session::set_samples(int samples)

@ -487,106 +487,30 @@ void SVMCompiler::generate_closure(ShaderNode *node, set<ShaderNode*>& done)
}
}
void SVMCompiler::count_closure_users(ShaderNode *node, map<ShaderNode*, MultiClosureData>& closure_data)
{
/* here we count the number of times each closure node is used, so that
* the last time we encounter it we can run the actually code with the
* weights from all other places added together */
if(node->name == ustring("mix_closure") || node->name == ustring("add_closure")) {
ShaderInput *cl1in = node->input("Closure1");
ShaderInput *cl2in = node->input("Closure2");
if(cl1in->link)
count_closure_users(cl1in->link->parent, closure_data);
if(cl2in->link)
count_closure_users(cl2in->link->parent, closure_data);
}
else {
MultiClosureData data;
if(closure_data.find(node) == closure_data.end()) {
data.stack_offset = SVM_STACK_INVALID;
data.users = 1;
}
else {
data = closure_data[node];
data.users++;
}
closure_data[node] = data;
}
}
void SVMCompiler::generate_multi_closure(ShaderNode *node, set<ShaderNode*>& done,
map<ShaderNode*, MultiClosureData>& closure_data, uint in_offset)
void SVMCompiler::generate_multi_closure(ShaderNode *node, set<ShaderNode*>& done, set<ShaderNode*>& closure_done)
{
/* todo: the weaks point here is that unlike the single closure sampling
* we will evaluate all nodes even if they are used as input for closures
* that are unused. it's not clear what would be the best way to skip such
* nodes at runtime, especially if they are tangled up */
/* only generate once */
if(closure_done.find(node) != closure_done.end())
return;
closure_done.insert(node);
if(node->name == ustring("mix_closure") || node->name == ustring("add_closure")) {
ShaderInput *fin = node->input("Fac");
/* weighting is already taken care of in ShaderGraph::transform_multi_closure */
ShaderInput *cl1in = node->input("Closure1");
ShaderInput *cl2in = node->input("Closure2");
uint out1_offset = SVM_STACK_INVALID;
uint out2_offset = SVM_STACK_INVALID;
if(fin) {
/* mix closure */
set<ShaderNode*> dependencies;
find_dependencies(dependencies, done, fin);
generate_svm_nodes(dependencies, done);
stack_assign(fin);
if(cl1in->link)
out1_offset = stack_find_offset(SHADER_SOCKET_FLOAT);
if(cl2in->link)
out2_offset = stack_find_offset(SHADER_SOCKET_FLOAT);
add_node(NODE_MIX_CLOSURE,
encode_uchar4(fin->stack_offset, in_offset, out1_offset, out2_offset));
}
else {
/* add closure */
out1_offset = in_offset;
out2_offset = in_offset;
}
if(cl1in->link)
generate_multi_closure(cl1in->link->parent, done, closure_data, out1_offset);
generate_multi_closure(cl1in->link->parent, done, closure_done);
if(cl2in->link)
generate_multi_closure(cl2in->link->parent, done, closure_data, out2_offset);
if(in_offset != SVM_STACK_INVALID)
stack_clear_offset(SHADER_SOCKET_FLOAT, in_offset);
generate_multi_closure(cl2in->link->parent, done, closure_done);
}
else {
MultiClosureData data = closure_data[node];
if(data.stack_offset == SVM_STACK_INVALID) {
/* first time using closure, use stack position for weight */
data.stack_offset = in_offset;
}
else {
/* not first time using, add weights together */
add_node(NODE_MATH, NODE_MATH_ADD, data.stack_offset, in_offset);
add_node(NODE_MATH, data.stack_offset);
stack_clear_offset(SHADER_SOCKET_FLOAT, in_offset);
}
data.users--;
closure_data[node] = data;
/* still users coming? skip generating closure code */
if(data.users > 0)
return;
/* execute dependencies for closure */
foreach(ShaderInput *in, node->inputs) {
if(!node_skip_input(node, in) && in->link) {
@ -596,7 +520,16 @@ void SVMCompiler::generate_multi_closure(ShaderNode *node, set<ShaderNode*>& don
}
}
mix_weight_offset = data.stack_offset;
/* closure mix weight */
const char *weight_name = (current_type == SHADER_TYPE_VOLUME)? "VolumeMixWeight": "SurfaceMixWeight";
ShaderInput *weight_in = node->input(weight_name);
if(weight_in && (weight_in->link || weight_in->value.x != 1.0f)) {
stack_assign(weight_in);
mix_weight_offset = weight_in->stack_offset;
}
else
mix_weight_offset = SVM_STACK_INVALID;
/* compile closure itself */
node->compile(*this);
@ -609,12 +542,9 @@ void SVMCompiler::generate_multi_closure(ShaderNode *node, set<ShaderNode*>& don
current_shader->has_surface_emission = true;
if(node->name == ustring("transparent"))
current_shader->has_surface_transparent = true;
/* end node is added outside of this */
if(data.stack_offset != SVM_STACK_INVALID)
stack_clear_offset(SHADER_SOCKET_FLOAT, data.stack_offset);
}
done.insert(node);
}
@ -686,10 +616,8 @@ void SVMCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType ty
set<ShaderNode*> done;
if(use_multi_closure) {
map<ShaderNode*, MultiClosureData> closure_data;
count_closure_users(clin->link->parent, closure_data);
generate_multi_closure(clin->link->parent, done, closure_data, SVM_STACK_INVALID);
set<ShaderNode*> closure_done;
generate_multi_closure(clin->link->parent, done, closure_done);
}
else
generate_closure(clin->link->parent, done);
@ -713,9 +641,9 @@ void SVMCompiler::compile(Shader *shader, vector<int4>& global_svm_nodes, int in
shader->graph_bump = shader->graph->copy();
/* finalize */
shader->graph->finalize(false, false);
shader->graph->finalize(false, false, use_multi_closure);
if(shader->graph_bump)
shader->graph_bump->finalize(true, false);
shader->graph_bump->finalize(true, false, use_multi_closure);
current_shader = shader;

@ -130,14 +130,7 @@ protected:
void generate_closure(ShaderNode *node, set<ShaderNode*>& done);
/* multi closure */
struct MultiClosureData {
int stack_offset;
int users;
};
void generate_multi_closure(ShaderNode *node, set<ShaderNode*>& done,
map<ShaderNode*,MultiClosureData>& closure_data, uint in_offset);
void count_closure_users(ShaderNode *node, map<ShaderNode*, MultiClosureData>& closure_data);
void generate_multi_closure(ShaderNode *node, set<ShaderNode*>& done, set<ShaderNode*>& closure_done);
/* compile */
void compile_type(Shader *shader, ShaderGraph *graph, ShaderType type);

@ -246,18 +246,30 @@ static void transform_decompose(Transform *decomp, const Transform *tfm)
decomp->w = make_float4(scale.y.z, scale.z.x, scale.z.y, scale.z.z);
}
void transform_motion_decompose(MotionTransform *decomp, const MotionTransform *motion, const Transform *mid)
void transform_motion_decompose(DecompMotionTransform *decomp, const MotionTransform *motion, const Transform *mid)
{
transform_decompose(&decomp->pre, &motion->pre);
Transform pre, post;
transform_decompose(&pre, &motion->pre);
transform_decompose(&decomp->mid, mid);
transform_decompose(&decomp->post, &motion->post);
transform_decompose(&post, &motion->post);
/* ensure rotation around shortest angle, negated quaternions are the same
* but this means we don't have to do the check in quat_interpolate */
if(dot(decomp->mid.x, decomp->post.x) < 0.0f)
if(dot(decomp->mid.x, post.x) < 0.0f)
decomp->mid.x = -decomp->mid.x;
if(dot(decomp->pre.x, decomp->mid.x) < 0.0f)
decomp->pre.x = -decomp->pre.x;
if(dot(pre.x, decomp->mid.x) < 0.0f)
pre.x = -pre.x;
/* drop scale of pre/post */
pre.y.w = decomp->mid.y.w;
post.y.w = decomp->mid.y.w;
/* store translation/rotation part of pre/post */
decomp->pre_x = pre.x;
decomp->pre_y = pre.y;
decomp->post_x = post.x;
decomp->post_y = post.y;
}
CCL_NAMESPACE_END

@ -41,7 +41,9 @@ typedef struct Transform {
/* transform decomposed in rotation/translation/scale. we use the same data
* structure as Transform, and tightly pack decomposition into it. first the
* rotation (4), then translation (3), then 3x3 scale matrix (9) */
* rotation (4), then translation (3), then 3x3 scale matrix (9).
*
* For the DecompMotionTransform we drop scale from pre/post. */
typedef struct MotionTransform {
Transform pre;
@ -49,6 +51,12 @@ typedef struct MotionTransform {
Transform post;
} MotionTransform;
typedef struct DecompMotionTransform {
Transform mid;
float4 pre_x, pre_y;
float4 post_x, post_y;
} DecompMotionTransform;
/* Functions */
__device_inline float3 transform_perspective(const Transform *t, const float3 a)
@ -303,6 +311,10 @@ __device_inline Transform transform_clear_scale(const Transform& tfm)
__device_inline float4 quat_interpolate(float4 q1, float4 q2, float t)
{
/* use simpe nlerp instead of slerp. it's faster and almost the same */
return normalize((1.0f - t)*q1 + t*q2);
#if 0
/* note: this does not ensure rotation around shortest angle, q1 and q2
* are assumed to be matched already in transform_motion_decompose */
float costheta = dot(q1, q2);
@ -320,6 +332,7 @@ __device_inline float4 quat_interpolate(float4 q1, float4 q2, float t)
float thetap = theta * t;
return q1 * cosf(thetap) + qperp * sinf(thetap);
}
#endif
}
__device_inline Transform transform_quick_inverse(Transform M)
@ -384,7 +397,7 @@ __device_inline void transform_compose(Transform *tfm, const Transform *decomp)
/* Disabled for now, need arc-length parametrization for constant speed motion.
* #define CURVED_MOTION_INTERPOLATE */
__device void transform_motion_interpolate(Transform *tfm, const MotionTransform *motion, float t)
__device void transform_motion_interpolate(Transform *tfm, const DecompMotionTransform *motion, float t)
{
/* possible optimization: is it worth it adding a check to skip scaling?
* it's probably quite uncommon to have scaling objects. or can we skip
@ -393,9 +406,9 @@ __device void transform_motion_interpolate(Transform *tfm, const MotionTransform
#ifdef CURVED_MOTION_INTERPOLATE
/* 3 point bezier curve interpolation for position */
float3 Ppre = float4_to_float3(motion->pre.y);
float3 Ppre = float4_to_float3(motion->pre_y);
float3 Pmid = float4_to_float3(motion->mid.y);
float3 Ppost = float4_to_float3(motion->post.y);
float3 Ppost = float4_to_float3(motion->post_y);
float3 Pcontrol = 2.0f*Pmid - 0.5f*(Ppre + Ppost);
float3 P = Ppre*t*t + Pcontrol*2.0f*t*(1.0f - t) + Ppost*(1.0f - t)*(1.0f - t);
@ -409,28 +422,27 @@ __device void transform_motion_interpolate(Transform *tfm, const MotionTransform
if(t < 0.5f) {
t *= 2.0f;
decomp.x = quat_interpolate(motion->pre.x, motion->mid.x, t);
decomp.x = quat_interpolate(motion->pre_x, motion->mid.x, t);
#ifdef CURVED_MOTION_INTERPOLATE
decomp.y.w = (1.0f - t)*motion->pre.y.w + t*motion->mid.y.w;
decomp.y.w = (1.0f - t)*motion->pre_y.w + t*motion->mid.y.w;
#else
decomp.y = (1.0f - t)*motion->pre.y + t*motion->mid.y;
decomp.y = (1.0f - t)*motion->pre_y + t*motion->mid.y;
#endif
decomp.z = (1.0f - t)*motion->pre.z + t*motion->mid.z;
decomp.w = (1.0f - t)*motion->pre.w + t*motion->mid.w;
}
else {
t = (t - 0.5f)*2.0f;
decomp.x = quat_interpolate(motion->mid.x, motion->post.x, t);
decomp.x = quat_interpolate(motion->mid.x, motion->post_x, t);
#ifdef CURVED_MOTION_INTERPOLATE
decomp.y.w = (1.0f - t)*motion->mid.y.w + t*motion->post.y.w;
decomp.y.w = (1.0f - t)*motion->mid.y.w + t*motion->post_y.w;
#else
decomp.y = (1.0f - t)*motion->mid.y + t*motion->post.y;
decomp.y = (1.0f - t)*motion->mid.y + t*motion->post_y;
#endif
decomp.z = (1.0f - t)*motion->mid.z + t*motion->post.z;
decomp.w = (1.0f - t)*motion->mid.w + t*motion->post.w;
}
decomp.z = motion->mid.z;
decomp.w = motion->mid.w;
/* compose rotation, translation, scale into matrix */
transform_compose(tfm, &decomp);
}
@ -442,7 +454,7 @@ __device_inline bool operator==(const MotionTransform& A, const MotionTransform&
return (A.pre == B.pre && A.post == B.post);
}
void transform_motion_decompose(MotionTransform *decomp, const MotionTransform *motion, const Transform *mid);
void transform_motion_decompose(DecompMotionTransform *decomp, const MotionTransform *motion, const Transform *mid);
#endif

@ -120,7 +120,7 @@ extern GHOST_TimerTaskHandle GHOST_InstallTimer(GHOST_SystemHandle systemhandle,
/**
* Removes a timer.
* \param systemhandle The handle to the system
* \param timerTask Timer task to be removed.
* \param timertaskhandle Timer task to be removed.
* \return Indication of success.
*/
extern GHOST_TSuccess GHOST_RemoveTimer(GHOST_SystemHandle systemhandle,
@ -185,7 +185,7 @@ extern GHOST_TUserDataPtr GHOST_GetWindowUserData(GHOST_WindowHandle windowhandl
/**
* Changes the window user data.
* \param windowhandle The handle to the window
* \param data The window user data.
* \param userdata The window user data.
*/
extern void GHOST_SetWindowUserData(GHOST_WindowHandle windowhandle,
GHOST_TUserDataPtr userdata);
@ -212,6 +212,7 @@ extern int GHOST_ValidWindow(GHOST_SystemHandle systemhandle,
* Begins full screen mode.
* \param systemhandle The handle to the system
* \param setting The new setting of the display.
* \param stereoVisual Option for stereo display.
* \return A handle to the window displayed in full screen.
* This window is invalid after full screen has been ended.
*/
@ -302,7 +303,7 @@ extern GHOST_TStandardCursor GHOST_GetCursorShape(GHOST_WindowHandle windowhandl
/**
* Set the shape of the cursor.
* \param windowhandle The handle to the window
* \param cursor The new cursor shape type id.
* \param cursorshape The new cursor shape type id.
* \return Indication of success.
*/
extern GHOST_TSuccess GHOST_SetCursorShape(GHOST_WindowHandle windowhandle,
@ -484,10 +485,10 @@ extern GHOST_TUserDataPtr GHOST_GetTimerTaskUserData(GHOST_TimerTaskHandle timer
/**
* Changes the time user data.
* \param timertaskhandle The handle to the timertask
* \param data The timer user data.
* \param userdata The timer user data.
*/
extern void GHOST_SetTimerTaskUserData(GHOST_TimerTaskHandle timertaskhandle,
GHOST_TUserDataPtr userData);
GHOST_TUserDataPtr userdata);
/**
* Returns indication as to whether the window is valid.
@ -825,7 +826,8 @@ extern GHOST_TUns8 *GHOST_getClipboard(int selection);
/**
* Put data to the Clipboard
* \param set the selection instead, X11 only feature
* \param buffer the string buffer to set.
* \param selection Set the selection instead, X11 only feature.
*/
extern void GHOST_putClipboard(GHOST_TInt8 *buffer, int selection);

@ -58,7 +58,7 @@
* store original buffer's name when doing MEM_dupallocN
* helpful to profile issues with non-freed "dup_alloc" buffers,
* but this introduces some overhead to memory header and makes
* things slower a bit, so betterto keep disabled by default
* things slower a bit, so better to keep disabled by default
*/
//#define DEBUG_MEMDUPLINAME

@ -57,18 +57,18 @@ size_t count_utf_16_from_8(const char *string8);
/**
* Converts utf-16 string to allocated utf-8 string
* @params in16 utf-16 string to convert
* @params out8 utf-8 string to string the conversion
* @params size8 the allocated size in bytes of out8
* @param in16 utf-16 string to convert
* @param out8 utf-8 string to string the conversion
* @param size8 the allocated size in bytes of out8
* @return Returns any errors occured during conversion. See the block above,
*/
int conv_utf_16_to_8(const wchar_t *in16, char *out8, size_t size8);
/**
* Converts utf-8 string to allocated utf-16 string
* @params in8 utf-8 string to convert
* @params out16 utf-16 string to string the conversion
* @params size16 the allocated size in wchar_t (two byte) of out16
* @param in8 utf-8 string to convert
* @param out16 utf-16 string to string the conversion
* @param size16 the allocated size in wchar_t (two byte) of out16
* @return Returns any errors occured during conversion. See the block above,
*/
int conv_utf_8_to_16(const char *in8, wchar_t *out16, size_t size16);
@ -76,16 +76,16 @@ int conv_utf_8_to_16(const char *in8, wchar_t *out16, size_t size16);
/**
* Allocates and converts the utf-8 string from utf-16
* @params in16 utf-16 string to convert
* @params add any additional size which will be allocated for new utf-8 string in bytes
* @param in16 utf-16 string to convert
* @param add any additional size which will be allocated for new utf-8 string in bytes
* @return New allocated and converted utf-8 string or NULL if in16 is 0.
*/
char *alloc_utf_8_from_16(const wchar_t *in16, size_t add);
/**
* Allocates and converts the utf-16 string from utf-8
* @params in8 utf-8 string to convert
* @params add any additional size which will be allocated for new utf-16 string in wchar_t (two bytes)
* @param in8 utf-8 string to convert
* @param add any additional size which will be allocated for new utf-16 string in wchar_t (two bytes)
* @return New allocated and converted utf-16 string or NULL if in8 is 0.
*/
wchar_t *alloc_utf16_from_8(const char *in8, size_t add);

Binary file not shown.

@ -426,12 +426,14 @@ dict_uimsgs = {
"fh",
"fov",
"fft",
"futura",
"gfx",
"gl",
"glsl",
"gpl",
"gpu", "gpus",
"hc",
"hdc",
"hdr",
"hh", "mm", "ss", "ff", # hh:mm:ss:ff timecode
"hsv", "hsva",
@ -442,6 +444,7 @@ dict_uimsgs = {
"mux",
"ndof",
"ppc",
"precisa",
"px",
"qmc",
"rgb", "rgba",

@ -115,7 +115,7 @@ def main():
if not os.path.exists(os.path.join(TRUNK_PO_DIR, ".".join((lang, "po")))):
failed.add(lang)
# Check and compile each po separatly, to keep track of those failing.
# Check and compile each po separately, to keep track of those failing.
# XXX There should not be any failing at this stage, import step is
# supposed to have already filtered them out!
for po in os.listdir(TRUNK_PO_DIR):

@ -325,10 +325,12 @@ def ngon_tessellate(from_data, indices, fix_loops=True):
fgon to create from existing verts.
from_data: either a mesh, or a list/tuple of vectors.
indices: a list of indices to use this list is the ordered closed polyline
:arg indices: a list of indices to use this list is the ordered closed polyline
to fill, and can be a subset of the data given.
fix_loops: If this is enabled polylines that use loops to make multiple
:type indices: list
:arg fix_loops: If this is enabled polylines that use loops to make multiple
polylines are delt with correctly.
:type fix_loops: bool
"""
from mathutils.geometry import tessellate_polygon

@ -394,7 +394,7 @@ class Mesh(bpy_types.ID):
p.vertices = f
loop_index += loop_len
# if no edges - calculae them
# if no edges - calculate them
if faces and (not edges):
self.update(calc_edges=True)

@ -178,7 +178,7 @@ def rna2xml(fw=print_ln,
fw("%s</%s>\n" % (ident, value_type_name))
# -------------------------------------------------------------------------
# needs re-workign to be generic
# needs re-working to be generic
if root_node:
fw("%s<%s>\n" % (root_ident, root_node))

@ -26,195 +26,124 @@ from bpy.types import Operator
def extend(obj, operator, EXTEND_MODE):
from bpy_extras import mesh_utils
import bmesh
me = obj.data
me_verts = me.vertices
# script will fail without UVs
if not me.uv_textures:
me.uv_textures.new()
# Toggle Edit mode
is_editmode = (obj.mode == 'EDIT')
if is_editmode:
bpy.ops.object.mode_set(mode='OBJECT')
#t = sys.time()
edge_average_lengths = {}
OTHER_INDEX = 2, 3, 0, 1
def extend_uvs(face_source, face_target, edge_key):
"""
Takes 2 faces,
Projects its extends its UV coords onto the face next to it.
Both faces must share an edge
"""
def face_edge_vs(vi):
vlen = len(vi)
return [(vi[i], vi[(i + 1) % vlen]) for i in range(vlen)]
vidx_source = face_source.vertices
vidx_target = face_target.vertices
uv_layer = me.uv_layers.active.data
uvs_source = [uv_layer[i].uv for i in face_source.loop_indices]
uvs_target = [uv_layer[i].uv for i in face_target.loop_indices]
# vertex index is the key, uv is the value
uvs_vhash_source = {vindex: uvs_source[i] for i, vindex in enumerate(vidx_source)}
uvs_vhash_target = {vindex: uvs_target[i] for i, vindex in enumerate(vidx_target)}
edge_idxs_source = face_edge_vs(vidx_source)
edge_idxs_target = face_edge_vs(vidx_target)
source_matching_edge = -1
target_matching_edge = -1
edge_key_swap = edge_key[1], edge_key[0]
try:
source_matching_edge = edge_idxs_source.index(edge_key)
except:
source_matching_edge = edge_idxs_source.index(edge_key_swap)
try:
target_matching_edge = edge_idxs_target.index(edge_key)
except:
target_matching_edge = edge_idxs_target.index(edge_key_swap)
edgepair_inner_source = edge_idxs_source[source_matching_edge]
edgepair_inner_target = edge_idxs_target[target_matching_edge]
edgepair_outer_source = edge_idxs_source[OTHER_INDEX[source_matching_edge]]
edgepair_outer_target = edge_idxs_target[OTHER_INDEX[target_matching_edge]]
if edge_idxs_source[source_matching_edge] == edge_idxs_target[target_matching_edge]:
iA = 0 # Flipped, most common
iB = 1
else: # The normals of these faces must be different
iA = 1
iB = 0
# Set the target UV's touching source face, no tricky calculations needed,
uvs_vhash_target[edgepair_inner_target[0]][:] = uvs_vhash_source[edgepair_inner_source[iA]]
uvs_vhash_target[edgepair_inner_target[1]][:] = uvs_vhash_source[edgepair_inner_source[iB]]
# Set the 2 UV's on the target face that are not touching
# for this we need to do basic expanding on the source faces UV's
if EXTEND_MODE == 'LENGTH':
try: # divide by zero is possible
'''
measure the length of each face from the middle of each edge to the opposite
along the axis we are copying, use this
'''
i1a = edgepair_outer_target[iB]
i2a = edgepair_inner_target[iA]
if i1a > i2a:
i1a, i2a = i2a, i1a
i1b = edgepair_outer_source[iB]
i2b = edgepair_inner_source[iA]
if i1b > i2b:
i1b, i2b = i2b, i1b
# print edge_average_lengths
factor = edge_average_lengths[i1a, i2a][0] / edge_average_lengths[i1b, i2b][0]
except:
# Div By Zero?
factor = 1.0
uvs_vhash_target[edgepair_outer_target[iB]][:] = uvs_vhash_source[edgepair_inner_source[0]] + factor * (uvs_vhash_source[edgepair_inner_source[0]] - uvs_vhash_source[edgepair_outer_source[1]])
uvs_vhash_target[edgepair_outer_target[iA]][:] = uvs_vhash_source[edgepair_inner_source[1]] + factor * (uvs_vhash_source[edgepair_inner_source[1]] - uvs_vhash_source[edgepair_outer_source[0]])
else:
# same as above but with no factors
uvs_vhash_target[edgepair_outer_target[iB]][:] = uvs_vhash_source[edgepair_inner_source[0]] + (uvs_vhash_source[edgepair_inner_source[0]] - uvs_vhash_source[edgepair_outer_source[1]])
uvs_vhash_target[edgepair_outer_target[iA]][:] = uvs_vhash_source[edgepair_inner_source[1]] + (uvs_vhash_source[edgepair_inner_source[1]] - uvs_vhash_source[edgepair_outer_source[0]])
face_act = me.polygons.active
if face_act == -1:
bm = bmesh.from_edit_mesh(me)
f_act = bm.faces.active
uv_act = bm.loops.layers.uv.active
if f_act is None:
operator.report({'ERROR'}, "No active face")
return
face_sel = [f for f in me.polygons if len(f.vertices) == 4 and f.select]
face_act_local_index = -1
for i, f in enumerate(face_sel):
if f.index == face_act:
face_act_local_index = i
break
if face_act_local_index == -1:
operator.report({'ERROR'}, "Active face not selected")
elif len(f_act.verts) != 4:
operator.report({'ERROR'}, "Active face must be a quad")
return
# Modes
# 0 not yet searched for.
# 1:mapped, use search from this face - removed!
# 2:all siblings have been searched. don't search again.
face_modes = [0] * len(face_sel)
face_modes[face_act_local_index] = 1 # extend UV's from this face.
faces = [f for f in bm.faces if f.select and len(f.verts) == 4]
# Edge connectivity
edge_faces = {}
for i, f in enumerate(face_sel):
for edkey in f.edge_keys:
for f in faces:
f.tag = False
f_act.tag = True
# our own local walker
def walk_face(f):
# all faces in this list must be tagged
f.tag = True
faces_a = [f]
faces_b = []
while faces_a:
for f in faces_a:
for l in f.loops:
l_edge = l.edge
if (l_edge.is_manifold is True) and (l_edge.seam is False):
l_other = l.link_loop_radial_next
f_other = l_other.face
if not f_other.tag:
yield (f, l, f_other)
f_other.tag = True
faces_b.append(f_other)
# swap
faces_a, faces_b = faces_b, faces_a
faces_b.clear()
def extrapolate_uv(fac,
l_a_outer, l_a_inner,
l_b_outer, l_b_inner):
l_b_inner[:] = l_a_inner
l_b_outer[:] = l_a_inner + ((l_a_inner - l_a_outer) * fac)
def apply_uv(f_prev, l_prev, f_next):
l_a = [None, None, None, None]
l_b = [None, None, None, None]
l_a[0] = l_prev
l_a[1] = l_a[0].link_loop_next
l_a[2] = l_a[1].link_loop_next
l_a[3] = l_a[2].link_loop_next
# l_b
# +-----------+
# |(3) |(2)
# | |
# |l_next(0) |(1)
# +-----------+
# ^
# l_a |
# +-----------+
# |l_prev(0) |(1)
# | (f) |
# |(3) |(2)
# +-----------+
# copy from this face to the one above.
# get the other loops
l_next = l_prev.link_loop_radial_next
if l_next.vert != l_prev.vert:
l_b[1] = l_next
l_b[0] = l_b[1].link_loop_next
l_b[3] = l_b[0].link_loop_next
l_b[2] = l_b[3].link_loop_next
else:
l_b[0] = l_next
l_b[1] = l_b[0].link_loop_next
l_b[2] = l_b[1].link_loop_next
l_b[3] = l_b[2].link_loop_next
l_a_uv = [l[uv_act].uv for l in l_a]
l_b_uv = [l[uv_act].uv for l in l_b]
if EXTEND_MODE == 'LENGTH':
a0, b0, c0 = l_a[3].vert.co, l_a[0].vert.co, l_b[3].vert.co
a1, b1, c1 = l_a[2].vert.co, l_a[1].vert.co, l_b[2].vert.co
d1 = (a0 - b0).length + (a1 - b1).length
d2 = (b0 - c0).length + (b1 - c1).length
try:
edge_faces[edkey].append(i)
except:
edge_faces[edkey] = [i]
fac = d2 / d1
except ZeroDivisionError:
fac = 1.0
else:
fac = 1.0
if EXTEND_MODE == 'LENGTH':
edge_loops = mesh_utils.edge_loops_from_tessfaces(me, face_sel, [ed.key for ed in me.edges if ed.use_seam])
me_verts = me.vertices
for loop in edge_loops:
looplen = [0.0]
for ed in loop:
edge_average_lengths[ed] = looplen
looplen[0] += (me_verts[ed[0]].co - me_verts[ed[1]].co).length
looplen[0] = looplen[0] / len(loop)
extrapolate_uv(fac,
l_a_uv[3], l_a_uv[0],
l_b_uv[3], l_b_uv[0])
# remove seams, so we don't map across seams.
for ed in me.edges:
if ed.use_seam:
# remove the edge pair if we can
try:
del edge_faces[ed.key]
except:
pass
# Done finding seams
extrapolate_uv(fac,
l_a_uv[2], l_a_uv[1],
l_b_uv[2], l_b_uv[1])
# face connectivity - faces around each face
# only store a list of indices for each face.
face_faces = [[] for i in range(len(face_sel))]
for f_triple in walk_face(f_act):
apply_uv(*f_triple)
for edge_key, faces in edge_faces.items():
if len(faces) == 2: # Only do edges with 2 face users for now
face_faces[faces[0]].append((faces[1], edge_key))
face_faces[faces[1]].append((faces[0], edge_key))
# Now we know what face is connected to what other face, map them by connectivity
ok = True
while ok:
ok = False
for i in range(len(face_sel)):
if face_modes[i] == 1: # searchable
for f_sibling, edge_key in face_faces[i]:
if face_modes[f_sibling] == 0:
face_modes[f_sibling] = 1 # mapped and search from.
extend_uvs(face_sel[i], face_sel[f_sibling], edge_key)
face_modes[i] = 1 # we can map from this one now.
ok = True # keep searching
face_modes[i] = 2 # don't search again
if is_editmode:
bpy.ops.object.mode_set(mode='EDIT')
else:
me.update_tag()
bmesh.update_edit_mesh(me, False)
def main(context, operator):

@ -552,7 +552,7 @@ class LightMapPack(Operator):
# Disable REGISTER flag for now because this operator might create new
# images. This leads to non-proper operator redo because current undo
# stack is local for edit mode and can not remove images created by this
# oprtator.
# operator.
# Proper solution would be to make undo stack aware of such things,
# but for now just disable redo. Keep undo here so unwanted changes to uv
# coords might be undone.

@ -23,7 +23,7 @@ import bpy
from bpy.types import Operator
DEG_TO_RAD = 0.017453292519943295 # pi/180.0
SMALL_NUM = 0.000000001
SMALL_NUM = 0.0000001 # see bug [#31598] why we dont have smaller values
BIG_NUM = 1e15
global USER_FILL_HOLES
@ -759,7 +759,7 @@ class thickface(object):
self.v = [mesh_verts[i] for i in face.vertices]
self.uv = [uv_layer[i].uv for i in face.loop_indices]
self.no = face.normal
self.no = face.normal.copy()
self.area = face.area
self.edge_keys = face.edge_keys
@ -993,7 +993,7 @@ def main(context,
if mostUniqueAngle < USER_PROJECTION_LIMIT_CONVERTED:
#print 'adding', mostUniqueAngle, USER_PROJECTION_LIMIT, len(newProjectMeshFaces)
# Now weight the vector to all its faces, will give a more direct projection
# if the face its self was not representive of the normal from surrounding faces.
# if the face its self was not representative of the normal from surrounding faces.
newProjectVec = tempMeshFaces[mostUniqueIndex].no
newProjectMeshFaces = [tempMeshFaces.pop(mostUniqueIndex)]

@ -148,7 +148,7 @@ class PARTICLE_PT_context_particles(ParticleButtonsPanel, Panel):
#row.label(text="Render")
if part.is_fluid:
layout.label(text="{} fluid particles for this frame".format(str(part.count)))
layout.label(text="%d fluid particles for this frame" % part.count)
return
row = col.row()

@ -437,7 +437,6 @@ class USERPREF_PT_system(Panel):
col.label(text="OpenGL:")
col.prop(system, "gl_clip_alpha", slider=True)
col.prop(system, "use_mipmaps")
col.prop(system, "use_gpu_mipmap")
col.prop(system, "use_16bit_textures")
col.label(text="Anisotropic Filtering")
col.prop(system, "anisotropic_filter", text="")

@ -0,0 +1,23 @@
# This example assumes we have a mesh object in edit-mode
import bpy
import bmesh
# Get the active mesh
obj = bpy.context.edit_object
me = obj.data
# Get a BMesh representation
bm = bmesh.from_edit_mesh(me)
bm.faces.active = None
# Modify the BMesh, can do anything here...
for v in bm.verts:
v.co.x += 1.0
# Show the updates in the viewport
# and recalculate n-gon tessellation.
bmesh.update_edit_mesh(me, True)

@ -9,4 +9,6 @@ filename = "my_script.py"
filepath = os.path.join(os.path.dirname(bpy.data.filepath), filename)
global_namespace = {"__file__": filepath, "__name__": "__main__"}
exec(compile(open(filepath).read(), filepath, 'exec'), global_namespace)
file = open(filepath, 'rb')
exec(compile(file.read(), filepath, 'exec'), global_namespace)
file.close()

@ -709,10 +709,16 @@ void DM_debug_print(DerivedMesh *dm);
void DM_debug_print_cdlayers(CustomData *cdata);
#endif
#ifdef __GNUC__
BLI_INLINE int DM_origindex_mface_mpoly(const int *index_mf_to_mpoly, const int *index_mp_to_orig, const int i)
__attribute__((nonnull(1)))
;
#endif
BLI_INLINE int DM_origindex_mface_mpoly(const int *index_mf_to_mpoly, const int *index_mp_to_orig, const int i)
{
const int j = index_mf_to_mpoly[i];
return (j != ORIGINDEX_NONE) ? index_mp_to_orig[j] : ORIGINDEX_NONE;
return (j != ORIGINDEX_NONE) ? (index_mp_to_orig ? index_mp_to_orig[j] : j) : ORIGINDEX_NONE;
}
#endif

@ -34,8 +34,6 @@
#include "DNA_listBase.h"
#include "RNA_types.h"
/* not very important, but the stack solver likes to know a maximum */
#define MAX_SOCKET 64
@ -82,7 +80,7 @@ typedef struct bNodeSocketTemplate {
char name[64]; /* MAX_NAME */
float val1, val2, val3, val4; /* default alloc value for inputs */
float min, max;
PropertySubType subtype;
int subtype; /* would use PropertySubType but this is a bad level include to use RNA */
int flag;
/* after this line is used internal only */

@ -41,11 +41,12 @@ if env['WITH_BF_PYTHON']:
if env['BF_DEBUG']:
defs.append('DEBUG')
'''
if env['WITH_BF_ELTOPO']:
incs += ' #/extern/eltopo'
incs += ' #/extern/eltopo/eltopo3d'
defs.append('WITH_ELTOPO')
'''
if env['WITH_BF_QUICKTIME']:
incs += ' ../quicktime'

@ -268,7 +268,7 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath
G.winpos = bfd->winpos;
G.displaymode = bfd->displaymode;
G.fileflags = bfd->fileflags;
CTX_wm_manager_set(C, bfd->main->wm.first);
CTX_wm_manager_set(C, G.main->wm.first);
CTX_wm_screen_set(C, bfd->curscreen);
CTX_data_scene_set(C, bfd->curscreen->scene);
CTX_wm_area_set(C, NULL);
@ -278,7 +278,11 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath
/* this can happen when active scene was lib-linked, and doesn't exist anymore */
if (CTX_data_scene(C) == NULL) {
CTX_data_scene_set(C, bfd->main->scene.first);
/* in case we don't even have a local scene, add one */
if(!G.main->scene.first)
BKE_scene_add("Scene");
CTX_data_scene_set(C, G.main->scene.first);
CTX_wm_screen(C)->scene = CTX_data_scene(C);
curscene = CTX_data_scene(C);
}

@ -267,6 +267,7 @@ void BKE_camera_params_from_view3d(CameraParams *params, View3D *v3d, RegionView
params->clipsta = -params->clipend;
params->is_ortho = TRUE;
/* make sure any changes to this match ED_view3d_radius_to_ortho_dist() */
params->ortho_scale = rv3d->dist * sensor_size / v3d->lens;
params->zoom = 2.0f;
}

@ -623,8 +623,8 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm,
/* double lookup */
const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX);
if ((index_mf_to_mpoly && index_mp_to_orig) == FALSE) {
index_mf_to_mpoly = index_mp_to_orig = NULL;
if (index_mf_to_mpoly == NULL) {
index_mp_to_orig = NULL;
}
colType = CD_TEXTURE_MCOL;
@ -812,8 +812,8 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm,
/* double lookup */
const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX);
if ((index_mf_to_mpoly && index_mp_to_orig) == FALSE) {
index_mf_to_mpoly = index_mp_to_orig = NULL;
if (index_mf_to_mpoly == NULL) {
index_mp_to_orig = NULL;
}
@ -1048,8 +1048,8 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm,
/* double lookup */
const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX);
if ((index_mf_to_mpoly && index_mp_to_orig) == FALSE) {
index_mf_to_mpoly = index_mp_to_orig = NULL;
if (index_mf_to_mpoly == NULL) {
index_mp_to_orig = NULL;
}
cdDM_update_normals_from_pbvh(dm);
@ -1349,8 +1349,8 @@ static void cdDM_drawMappedFacesMat(DerivedMesh *dm,
/* double lookup */
const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX);
if ((index_mf_to_mpoly && index_mp_to_orig) == FALSE) {
index_mf_to_mpoly = index_mp_to_orig = NULL;
if (index_mf_to_mpoly == NULL) {
index_mp_to_orig = NULL;
}
cdDM_update_normals_from_pbvh(dm);

@ -487,7 +487,7 @@ void BKE_displist_fill(ListBase *dispbase, ListBase *to, int flipnormal)
}
/* XXX (obedit && obedit->actcol)?(obedit->actcol-1):0)) { */
if (totvert && (tot = BLI_scanfill_calc(&sf_ctx, FALSE))) {
if (totvert && (tot = BLI_scanfill_calc(&sf_ctx, BLI_SCANFILL_CALC_REMOVE_DOUBLES))) {
if (tot) {
dlnew = MEM_callocN(sizeof(DispList), "filldisplist");
dlnew->type = DL_INDEX3;

@ -215,7 +215,7 @@ static void BMEdit_RecalcTessellation_intern(BMEditMesh *tm)
/* complete the loop */
BLI_scanfill_edge_add(&sf_ctx, sf_vert_first, sf_vert);
totfilltri = BLI_scanfill_calc_ex(&sf_ctx, FALSE, efa->no);
totfilltri = BLI_scanfill_calc_ex(&sf_ctx, 0, efa->no);
BLI_array_grow_items(looptris, totfilltri);
for (sf_tri = sf_ctx.fillfacebase.first; sf_tri; sf_tri = sf_tri->next) {

@ -663,6 +663,13 @@ static ImBuf *add_ibuf_size(unsigned int width, unsigned int height, const char
BKE_image_buf_fill_color(rect, rect_float, width, height, color);
}
if (rect_float) {
/* both byte and float buffers are filling in sRGB space, need to linearize float buffer after BKE_image_buf_fill* functions */
IMB_buffer_float_from_float(rect_float, rect_float, ibuf->channels, IB_PROFILE_LINEAR_RGB, IB_PROFILE_SRGB,
ibuf->flags & IB_cm_predivide, ibuf->x, ibuf->y, ibuf->x, ibuf->x);
}
return ibuf;
}

@ -1416,7 +1416,7 @@ void BKE_mask_layer_evaluate(MaskLayer *masklay, const float ctime, const int do
for (spline = masklay->splines.first; spline; spline = spline->next) {
int i;
int has_auto = FALSE;
int need_handle_recalc = FALSE;
BKE_mask_spline_ensure_deform(spline);
@ -1436,16 +1436,16 @@ void BKE_mask_layer_evaluate(MaskLayer *masklay, const float ctime, const int do
add_v2_v2(point_deform->bezt.vec[2], delta);
}
if (point->bezt.h1 == HD_AUTO) {
has_auto = TRUE;
if (ELEM(point->bezt.h1, HD_AUTO, HD_VECT)) {
need_handle_recalc = TRUE;
}
}
/* if the spline has auto handles, these need to be recalculated after deformation */
if (has_auto) {
/* if the spline has auto or vector handles, these need to be recalculated after deformation */
if (need_handle_recalc) {
for (i = 0; i < spline->tot_point; i++) {
MaskSplinePoint *point_deform = &spline->points_deform[i];
if (point_deform->bezt.h1 == HD_AUTO) {
if (ELEM(point_deform->bezt.h1, HD_AUTO, HD_VECT)) {
BKE_mask_calc_handle_point(spline, point_deform);
}
}

Some files were not shown because too many files have changed in this diff Show More