forked from bartvdbraak/blender
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:
commit
ed0e2fbd9f
@ -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 *****
|
||||
#
|
||||
|
106
doc/python_api/examples/bmesh.ops.1.py
Normal file
106
doc/python_api/examples/bmesh.ops.1.py
Normal file
@ -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
|
||||
|
380
doc/python_api/rst_from_bmesh_opdefines.py
Normal file
380
doc/python_api/rst_from_bmesh_opdefines.py
Normal file
@ -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",
|
||||
]
|
||||
|
7
extern/CMakeLists.txt
vendored
7
extern/CMakeLists.txt
vendored
@ -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
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),
|
||||
|
31
intern/cycles/kernel/shaders/node_convert_from_string.osl
Normal file
31
intern/cycles/kernel/shaders/node_convert_from_string.osl
Normal file
@ -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="")
|
||||
|
23
release/scripts/templates/bmesh_simple_editmode.py
Normal file
23
release/scripts/templates/bmesh_simple_editmode.py
Normal file
@ -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
Loading…
Reference in New Issue
Block a user