Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt54
-rw-r--r--SConstruct13
-rw-r--r--build_files/buildbot/slave_compile.py7
-rw-r--r--build_files/buildbot/slave_pack.py2
-rw-r--r--build_files/cmake/Modules/FindOpenEXR.cmake7
-rw-r--r--build_files/cmake/macros.cmake11
-rw-r--r--build_files/scons/config/win32-vc-config.py56
-rw-r--r--build_files/scons/config/win64-vc-config.py59
-rw-r--r--build_files/scons/tools/btools.py7
-rw-r--r--intern/cycles/CMakeLists.txt13
-rw-r--r--intern/cycles/SConscript11
-rw-r--r--intern/cycles/blender/addon/__init__.py2
-rw-r--r--intern/cycles/blender/addon/properties.py6
-rw-r--r--intern/cycles/blender/addon/ui.py9
-rw-r--r--intern/cycles/blender/blender_shader.cpp3
-rw-r--r--intern/cycles/bvh/bvh.cpp8
-rw-r--r--intern/cycles/device/device_cuda.cpp50
-rw-r--r--intern/cycles/device/device_opencl.cpp2
-rw-r--r--intern/cycles/kernel/CMakeLists.txt54
-rw-r--r--intern/cycles/kernel/SConscript41
-rw-r--r--intern/cycles/kernel/kernel_bvh.h116
-rw-r--r--intern/cycles/kernel/kernel_bvh_traversal.h222
-rw-r--r--intern/cycles/kernel/kernel_emission.h4
-rw-r--r--intern/cycles/kernel/kernel_jitter.h8
-rw-r--r--intern/cycles/kernel/kernel_shader.h23
-rw-r--r--intern/cycles/kernel/kernel_sse3.cpp5
-rw-r--r--intern/cycles/kernel/kernel_types.h4
-rw-r--r--intern/cycles/render/light.cpp12
-rw-r--r--intern/cycles/render/object.cpp2
-rw-r--r--intern/cycles/render/osl.cpp2
-rw-r--r--intern/cycles/render/shader.cpp13
-rw-r--r--intern/cycles/render/shader.h3
-rw-r--r--intern/cycles/render/svm.cpp2
-rw-r--r--intern/cycles/util/util_cuda.cpp58
-rw-r--r--intern/cycles/util/util_cuda.h1
-rw-r--r--intern/cycles/util/util_math.h2
-rw-r--r--intern/cycles/util/util_system.cpp2
-rw-r--r--intern/cycles/util/util_types.h89
-rw-r--r--release/scripts/modules/addon_utils.py20
-rw-r--r--release/scripts/modules/bl_i18n_utils/settings.py2
-rw-r--r--release/scripts/modules/bl_i18n_utils/utils_spell_check.py2
-rw-r--r--release/scripts/modules/bpy_extras/object_utils.py10
-rw-r--r--release/scripts/startup/bl_operators/wm.py26
-rw-r--r--release/scripts/startup/bl_ui/__init__.py1
-rw-r--r--release/scripts/startup/bl_ui/properties_paint_common.py2
-rw-r--r--release/scripts/startup/bl_ui/space_properties.py46
-rw-r--r--release/scripts/startup/bl_ui/space_userpref.py23
-rw-r--r--release/scripts/startup/bl_ui/space_view3d.py20
-rw-r--r--source/blender/blenkernel/BKE_autoexec.h31
-rw-r--r--source/blender/blenkernel/BKE_modifier.h25
-rw-r--r--source/blender/blenkernel/CMakeLists.txt2
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c65
-rw-r--r--source/blender/blenkernel/intern/autoexec.c70
-rw-r--r--source/blender/blenkernel/intern/blender.c2
-rw-r--r--source/blender/blenkernel/intern/displist.c23
-rw-r--r--source/blender/blenkernel/intern/editmesh_bvh.c8
-rw-r--r--source/blender/blenkernel/intern/mball.c649
-rw-r--r--source/blender/blenkernel/intern/modifier.c65
-rw-r--r--source/blender/blenlib/BLI_path_util.h2
-rw-r--r--source/blender/blenlib/BLI_utildefines.h16
-rw-r--r--source/blender/blenlib/intern/BLI_heap.c3
-rw-r--r--source/blender/blenloader/intern/readfile.c1
-rw-r--r--source/blender/blenloader/intern/writefile.c5
-rw-r--r--source/blender/bmesh/bmesh_class.h2
-rw-r--r--source/blender/bmesh/intern/bmesh_marking.c6
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh.c2
-rw-r--r--source/blender/bmesh/tools/bmesh_path.c9
-rw-r--r--source/blender/editors/include/ED_mesh.h2
-rw-r--r--source/blender/editors/include/UI_interface.h4
-rw-r--r--source/blender/editors/interface/interface.c20
-rw-r--r--source/blender/editors/interface/interface_handlers.c47
-rw-r--r--source/blender/editors/interface/interface_intern.h2
-rw-r--r--source/blender/editors/interface/interface_layout.c2
-rw-r--r--source/blender/editors/interface/interface_regions.c6
-rw-r--r--source/blender/editors/interface/interface_widgets.c30
-rw-r--r--source/blender/editors/mesh/editmesh_utils.c83
-rw-r--r--source/blender/editors/object/object_vgroup.c4
-rw-r--r--source/blender/editors/screen/screendump.c2
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex.c6
-rw-r--r--source/blender/editors/sound/sound_ops.c2
-rw-r--r--source/blender/editors/space_buttons/CMakeLists.txt1
-rw-r--r--source/blender/editors/space_buttons/buttons_header.c189
-rw-r--r--source/blender/editors/space_buttons/buttons_intern.h4
-rw-r--r--source/blender/editors/space_buttons/buttons_texture.c31
-rw-r--r--source/blender/editors/space_buttons/space_buttons.c19
-rw-r--r--source/blender/editors/space_clip/space_clip.c2
-rw-r--r--source/blender/editors/space_file/file_intern.h4
-rw-r--r--source/blender/editors/space_file/filesel.c26
-rw-r--r--source/blender/editors/space_image/image_ops.c2
-rw-r--r--source/blender/editors/space_nla/nla_edit.c3
-rw-r--r--source/blender/editors/space_view3d/view3d_buttons.c86
-rw-r--r--source/blender/editors/space_view3d/view3d_iterators.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c67
-rw-r--r--source/blender/editors/transform/transform_conversions.c198
-rw-r--r--source/blender/editors/uvedit/uvedit_ops.c4
-rw-r--r--source/blender/freestyle/intern/application/AppCanvas.cpp4
-rw-r--r--source/blender/makesdna/DNA_userdef_types.h14
-rw-r--r--source/blender/makesrna/intern/rna_space.c109
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c76
-rw-r--r--source/blender/makesrna/intern/rna_wm.c6
-rw-r--r--source/blender/modifiers/intern/MOD_edgesplit.c22
-rw-r--r--source/blender/windowmanager/WM_api.h3
-rw-r--r--source/blender/windowmanager/WM_types.h2
-rw-r--r--source/blender/windowmanager/intern/wm_files.c16
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c135
-rw-r--r--source/creator/CMakeLists.txt6
-rw-r--r--source/creator/creator.c1
-rw-r--r--source/gameengine/Ketsji/KX_KetsjiEngine.cpp44
-rw-r--r--source/gameengine/Ketsji/KX_KetsjiEngine.h9
109 files changed, 2208 insertions, 1208 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 39b75d9a32b..e2dda8553d6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -562,12 +562,12 @@ set(PLATFORM_LINKFLAGS_DEBUG "")
if(UNIX AND NOT APPLE)
macro(find_package_wrapper)
string(TOUPPER ${ARGV0} _NAME_UPPER)
- if(${WITH_STATIC_LIBS})
+ if(WITH_STATIC_LIBS)
set(_cmake_find_library_suffixes_back ${CMAKE_FIND_LIBRARY_SUFFIXES})
set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
endif()
find_package(${ARGV})
- if(${WITH_STATIC_LIBS})
+ if(WITH_STATIC_LIBS)
set(CMAKE_FIND_LIBRARY_SUFFIXES ${_cmake_find_library_suffixes_back})
unset(_cmake_find_library_suffixes_back)
endif()
@@ -707,7 +707,7 @@ if(UNIX AND NOT APPLE)
if(WITH_BOOST)
# uses in build instructions to override include and library variables
if(NOT BOOST_CUSTOM)
- if(${WITH_STATIC_LIBS})
+ if(WITH_STATIC_LIBS)
set(Boost_USE_STATIC_LIBS ON)
endif()
set(Boost_USE_MULTITHREADED ON)
@@ -1124,26 +1124,22 @@ elseif(WIN32)
${OPENCOLLADA}/include/opencollada/COLLADASaxFrameworkLoader
${OPENCOLLADA}/include/opencollada/GeneratedSaxParser
)
- set_lib_path(OPENCOLLADA_LIBPATH "opencollada")
set(OPENCOLLADA_LIBRARIES
- ${OPENCOLLADA_LIBPATH}/lib/opencollada/OpenCOLLADASaxFrameworkLoader.lib
- ${OPENCOLLADA_LIBPATH}/lib/opencollada/OpenCOLLADAFramework.lib
- ${OPENCOLLADA_LIBPATH}/lib/opencollada/OpenCOLLADABaseUtils.lib
- ${OPENCOLLADA_LIBPATH}/lib/opencollada/OpenCOLLADAStreamWriter.lib
- ${OPENCOLLADA_LIBPATH}/lib/opencollada/MathMLSolver.lib
- ${OPENCOLLADA_LIBPATH}/lib/opencollada/GeneratedSaxParser.lib
- ${OPENCOLLADA_LIBPATH}/lib/opencollada/xml.lib
- ${OPENCOLLADA_LIBPATH}/lib/opencollada/buffer.lib
- ${OPENCOLLADA_LIBPATH}/lib/opencollada/ftoa.lib
- ${OPENCOLLADA_LIBPATH}/lib/opencollada/UTF.lib
+ ${OPENCOLLADA}/lib/opencollada/OpenCOLLADASaxFrameworkLoader.lib
+ ${OPENCOLLADA}/lib/opencollada/OpenCOLLADAFramework.lib
+ ${OPENCOLLADA}/lib/opencollada/OpenCOLLADABaseUtils.lib
+ ${OPENCOLLADA}/lib/opencollada/OpenCOLLADAStreamWriter.lib
+ ${OPENCOLLADA}/lib/opencollada/MathMLSolver.lib
+ ${OPENCOLLADA}/lib/opencollada/GeneratedSaxParser.lib
+ ${OPENCOLLADA}/lib/opencollada/xml.lib
+ ${OPENCOLLADA}/lib/opencollada/buffer.lib
+ ${OPENCOLLADA}/lib/opencollada/ftoa.lib
+ ${OPENCOLLADA}/lib/opencollada/UTF.lib
)
set(PCRE_LIBRARIES
- ${OPENCOLLADA_LIBPATH}/lib/opencollada/pcre.lib
+ ${OPENCOLLADA}/lib/opencollada/pcre.lib
)
-
- unset(OPENCOLLADA_LIBPATH)
-
endif()
if(WITH_CODEC_FFMPEG)
@@ -1172,7 +1168,7 @@ elseif(WIN32)
endif()
if(WITH_IMAGE_OPENEXR)
- set_lib_path(OPENEXR "openexr")
+ set(OPENEXR ${LIBDIR}/openexr)
set(OPENEXR_INCLUDE_DIR ${OPENEXR}/include)
set(OPENEXR_INCLUDE_DIRS ${OPENEXR}/include/OpenEXR)
set(OPENEXR_LIBPATH ${OPENEXR}/lib)
@@ -1199,18 +1195,11 @@ elseif(WIN32)
endif()
if(WITH_PYTHON)
- # normally cached but not since we include them with blender
- if(MSVC10)
- set(PYTHON_VERSION 3.3) # CACHE STRING)
- else()
- set(PYTHON_VERSION 3.3) # CACHE STRING)
- endif()
+ set(PYTHON_VERSION 3.3) # CACHE STRING)
- set_lib_path(PYTHON "python")
string(REPLACE "." "" _PYTHON_VERSION_NO_DOTS ${PYTHON_VERSION})
# Use shared libs for vc2008 and vc2010 until we actually have vc2010 libs
set(PYTHON_LIBRARY ${LIBDIR}/python/lib/python${_PYTHON_VERSION_NO_DOTS}.lib)
- # 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
@@ -1228,10 +1217,6 @@ elseif(WIN32)
set(BOOST_LIBPATH ${BOOST}/lib)
set(BOOST_POSTFIX "vc110-mt-s-1_53.lib")
set(BOOST_DEBUG_POSTFIX "vc110-mt-sgd-1_53.lib")
- elseif(MSVC10)
- set(BOOST_LIBPATH ${BOOST}/vc2010/lib)
- set(BOOST_POSTFIX "vc100-mt-s-1_49.lib")
- set(BOOST_DEBUG_POSTFIX "vc100-mt-sgd-1_49.lib")
else()
set(BOOST_LIBPATH ${BOOST}/lib)
set(BOOST_POSTFIX "vc90-mt-s-1_49.lib")
@@ -2084,13 +2069,6 @@ elseif(CMAKE_C_COMPILER_ID MATCHES "Intel")
endif()
-# MSVC2010 fails to links C++ libs right
-if(MSVC10)
- if(WITH_OPENCOLLADA)
- message(WARNING "MSVC 2010 does not support OpenCollada, disabling WITH_OPENCOLLADA. To enable support use Use MSVC 2008")
- endif()
-endif()
-
# ensure python header is found since detection can fail, this could happen
# with _any_ library but since we used a fixed python version this tends to
# be most problematic.
diff --git a/SConstruct b/SConstruct
index 94acdbbab92..0a7fa2aec9e 100644
--- a/SConstruct
+++ b/SConstruct
@@ -137,6 +137,8 @@ else:
B.quickie=[]
toolset = B.arguments.get('BF_TOOLSET', None)
+vcver = B.arguments.get('MSVS_VERSION', '9.0')
+
if toolset:
print "Using " + toolset
if toolset=='mstoolkit':
@@ -148,9 +150,9 @@ if toolset:
btools.SetupSpawn(env)
else:
if bitness==64 and platform=='win32':
- env = BlenderEnvironment(ENV = os.environ, MSVS_ARCH='amd64')
+ env = BlenderEnvironment(ENV = os.environ, MSVS_ARCH='amd64', TARGET_ARCH='x86_64', MSVC_VERSION=vcver)
else:
- env = BlenderEnvironment(ENV = os.environ)
+ env = BlenderEnvironment(ENV = os.environ, TARGET_ARCH='x86', MSVC_VERSION=vcver)
if not env:
print "Could not create a build environment"
@@ -384,6 +386,8 @@ else:
env['CPPFLAGS'].append('-DWITH_AUDASPACE')
env['CPPFLAGS'].append('-DWITH_AVI')
env['CPPFLAGS'].append('-DWITH_BOOL_COMPAT')
+if env['OURPLATFORM'] in ('win32-vc', 'win64-vc') and env['MSVC_VERSION'] == '11.0':
+ env['CPPFLAGS'].append('-D_ALLOW_KEYWORD_MACROS')
if env['OURPLATFORM'] not in ('win32-vc', 'win64-vc'):
env['CPPFLAGS'].append('-DHAVE_STDBOOL_H')
@@ -940,7 +944,10 @@ if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'win64-vc', 'linuxcross'):
if env['WITH_BF_OPENAL']:
dllsources.append('${LCGDIR}/openal/lib/OpenAL32.dll')
- dllsources.append('${LCGDIR}/openal/lib/wrap_oal.dll')
+ if env['OURPLATFORM'] in ('win32-vc', 'win64-vc') and env['MSVC_VERSION'] == '11.0':
+ pass
+ else:
+ dllsources.append('${LCGDIR}/openal/lib/wrap_oal.dll')
if env['WITH_BF_SNDFILE']:
dllsources.append('${LCGDIR}/sndfile/lib/libsndfile-1.dll')
diff --git a/build_files/buildbot/slave_compile.py b/build_files/buildbot/slave_compile.py
index 7e50798b33f..33879ccff17 100644
--- a/build_files/buildbot/slave_compile.py
+++ b/build_files/buildbot/slave_compile.py
@@ -143,6 +143,8 @@ else:
scons_options.append('BF_CYCLES_CUDA_NVCC=nvcc.exe')
if builder.find('mingw') != -1:
scons_options.append('BF_TOOLSET=mingw')
+ if builder.endswith('vc2012'):
+ scons_options.append('MSVS_VERSION=11.0')
scons_options.append('BF_NUMJOBS=1')
elif builder.find('mac') != -1:
@@ -156,7 +158,10 @@ else:
retcode = subprocess.call(['python', 'scons/scons.py'] + scons_options)
if builder.find('win') != -1:
- dlls = ('msvcm90.dll', 'msvcp90.dll', 'msvcr90.dll', 'vcomp90.dll', 'Microsoft.VC90.CRT.manifest', 'Microsoft.VC90.OpenMP.manifest')
+ if builder.endswith('vc2012'):
+ dlls = ('msvcp110.dll', 'msvcr110.dll', 'vcomp110.dll')
+ else:
+ dlls = ('msvcm90.dll', 'msvcp90.dll', 'msvcr90.dll', 'vcomp90.dll', 'Microsoft.VC90.CRT.manifest', 'Microsoft.VC90.OpenMP.manifest')
if builder.find('win64') == -1:
dlls_path = '..\\..\\..\\redist\\x86'
else:
diff --git a/build_files/buildbot/slave_pack.py b/build_files/buildbot/slave_pack.py
index 3c2569e4a69..3e8ae939dd5 100644
--- a/build_files/buildbot/slave_pack.py
+++ b/build_files/buildbot/slave_pack.py
@@ -99,6 +99,8 @@ if builder.find('scons') != -1:
scons_options.append('BF_CYCLES_CUDA_NVCC=nvcc.exe')
if builder.find('mingw') != -1:
scons_options.append('BF_TOOLSET=mingw')
+ if builder.endswith('vc2012'):
+ scons_options.append('MSVS_VERSION=11.0')
elif builder.find('mac') != -1:
if builder.find('x86_64') != -1:
diff --git a/build_files/cmake/Modules/FindOpenEXR.cmake b/build_files/cmake/Modules/FindOpenEXR.cmake
index 9f1d6571ef5..9ea0f6c9efd 100644
--- a/build_files/cmake/Modules/FindOpenEXR.cmake
+++ b/build_files/cmake/Modules/FindOpenEXR.cmake
@@ -52,11 +52,11 @@ SET(_openexr_SEARCH_DIRS
FIND_PATH(OPENEXR_INCLUDE_DIR
NAMES
- ImfXdr.h
+ OpenEXR/ImfXdr.h
HINTS
${_openexr_SEARCH_DIRS}
PATH_SUFFIXES
- include/OpenEXR
+ include
)
SET(_openexr_LIBRARIES)
@@ -82,7 +82,8 @@ FIND_PACKAGE_HANDLE_STANDARD_ARGS(OpenEXR DEFAULT_MSG
IF(OPENEXR_FOUND)
SET(OPENEXR_LIBRARIES ${_openexr_LIBRARIES})
- SET(OPENEXR_INCLUDE_DIRS ${OPENEXR_INCLUDE_DIR})
+ # Both include paths are needed because of dummy OSL headers mixing #include <OpenEXR/foo.h> and #include <foo.h> :(
+ SET(OPENEXR_INCLUDE_DIRS ${OPENEXR_INCLUDE_DIR} ${OPENEXR_INCLUDE_DIR}/OpenEXR)
ENDIF()
MARK_AS_ADVANCED(OPENEXR_INCLUDE_DIR)
diff --git a/build_files/cmake/macros.cmake b/build_files/cmake/macros.cmake
index 2b5cfbc31cc..b1dd76fbd14 100644
--- a/build_files/cmake/macros.cmake
+++ b/build_files/cmake/macros.cmake
@@ -751,17 +751,6 @@ function(delayed_do_install
endif()
endfunction()
-macro(set_lib_path
- lvar
- lproj)
-
- if(MSVC10)
- set(${lvar} ${LIBDIR}/${lproj}/vc2010)
- else()
- set(${lvar} ${LIBDIR}/${lproj})
- endif()
-endmacro()
-
macro(data_to_c
file_from file_to
diff --git a/build_files/scons/config/win32-vc-config.py b/build_files/scons/config/win32-vc-config.py
index e43bb5336b8..bceab628b47 100644
--- a/build_files/scons/config/win32-vc-config.py
+++ b/build_files/scons/config/win32-vc-config.py
@@ -1,12 +1,28 @@
-LCGDIR = '#../lib/windows'
+import subprocess
+
+CL_OUT = subprocess.Popen(["cl.exe"],stdout=subprocess.PIPE,stderr=subprocess.PIPE)
+CL_STDOUT, CL_STDERR = CL_OUT.communicate()
+
+if CL_STDERR.find("Version 15.00.") == -1:
+ VC_VERSION = '11.0'
+ LCGDIR = '#../lib/windows_vc11'
+
+else:
+ VC_VERSION = '9.0'
+ LCGDIR = '#../lib/windows'
+
LIBDIR = '${LCGDIR}'
WITH_BF_FFMPEG = True
BF_FFMPEG = LIBDIR +'/ffmpeg'
BF_FFMPEG_INC = '${BF_FFMPEG}/include ${BF_FFMPEG}/include/msvc'
BF_FFMPEG_LIBPATH='${BF_FFMPEG}/lib'
-BF_FFMPEG_LIB = 'avformat-53.lib avcodec-53.lib avdevice-53.lib avutil-51.lib swscale-2.lib'
-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'
+if VC_VERSION == '11.0':
+ BF_FFMPEG_LIB = 'avformat-54.lib avcodec-54.lib avdevice-54.lib avutil-52.lib avfilter-3.lib swscale-2.lib swresample-0.lib'
+ BF_FFMPEG_DLL = '${BF_FFMPEG_LIBPATH}/avformat-54.dll ${BF_FFMPEG_LIBPATH}/avcodec-54.dll ${BF_FFMPEG_LIBPATH}/avdevice-54.dll ${BF_FFMPEG_LIBPATH}/avutil-52.dll ${BF_FFMPEG_LIBPATH}/avfilter-3.dll ${BF_FFMPEG_LIBPATH}/swscale-2.dll ${BF_FFMPEG_LIBPATH}/swresample-0.dll'
+else:
+ BF_FFMPEG_LIB = 'avformat-53.lib avcodec-53.lib avdevice-53.lib avutil-51.lib swscale-2.lib'
+ 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.3'
@@ -19,7 +35,10 @@ BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib'
WITH_BF_OPENAL = True
BF_OPENAL = LIBDIR + '/openal'
BF_OPENAL_INC = '${BF_OPENAL}/include '
-BF_OPENAL_LIB = 'wrap_oal'
+if VC_VERSION == '11.0':
+ BF_OPENAL_LIB = 'OpenAL32'
+else:
+ BF_OPENAL_LIB = 'wrap_oal'
BF_OPENAL_LIBPATH = '${BF_OPENAL}/lib'
WITH_BF_ICONV = True
@@ -43,7 +62,10 @@ BF_SNDFILE_LIBPATH = '${BF_SNDFILE}/lib'
WITH_BF_SDL = True
BF_SDL = LIBDIR + '/sdl'
BF_SDL_INC = '${BF_SDL}/include'
-BF_SDL_LIB = 'SDL.lib'
+if VC_VERSION == '11.0':
+ BF_SDL_LIB = 'SDL.lib dxguid.lib'
+else:
+ BF_SDL_LIB = 'SDL.lib'
BF_SDL_LIBPATH = '${BF_SDL}/lib'
BF_PTHREADS = LIBDIR + '/pthreads'
@@ -182,8 +204,12 @@ WITH_BF_STATICOCIO = True
WITH_BF_BOOST = True
BF_BOOST = '${LIBDIR}/boost'
BF_BOOST_INC = '${BF_BOOST}/include'
-BF_BOOST_LIB = 'libboost_date_time-vc90-mt-s-1_49 libboost_filesystem-vc90-mt-s-1_49 libboost_regex-vc90-mt-s-1_49 libboost_system-vc90-mt-s-1_49 libboost_thread-vc90-mt-s-1_49 libboost_wave-vc90-mt-s-1_49'
-BF_BOOST_LIB_INTERNATIONAL = 'libboost_locale-vc90-mt-s-1_49'
+if VC_VERSION == '11.0':
+ BF_BOOST_LIB = 'libboost_date_time-vc110-mt-s-1_53 libboost_filesystem-vc110-mt-s-1_53 libboost_regex-vc110-mt-s-1_53 libboost_system-vc110-mt-s-1_53 libboost_thread-vc110-mt-s-1_53 libboost_wave-vc110-mt-s-1_53'
+ BF_BOOST_LIB_INTERNATIONAL = ' libboost_locale-vc110-mt-s-1_53'
+else:
+ BF_BOOST_LIB = 'libboost_date_time-vc90-mt-s-1_49 libboost_filesystem-vc90-mt-s-1_49 libboost_regex-vc90-mt-s-1_49 libboost_system-vc90-mt-s-1_49 libboost_thread-vc90-mt-s-1_49 libboost_wave-vc90-mt-s-1_49'
+ BF_BOOST_LIB_INTERNATIONAL = 'libboost_locale-vc90-mt-s-1_49'
BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
#CUDA
@@ -209,16 +235,16 @@ BF_OPENGL_LIB_STATIC = [ '${BF_OPENGL}/lib/libGL.a', '${BF_OPENGL}/lib/libGLU.a'
CC = 'cl.exe'
CXX = 'cl.exe'
-CCFLAGS = ['/nologo', '/Ob1', '/J', '/W1', '/Gd', '/wd4018', '/wd4244', '/wd4305', '/wd4800', '/wd4065', '/wd4267', '/we4013']
+CCFLAGS = ['/nologo', '/J', '/W1', '/Gd', '/wd4018', '/wd4244', '/wd4305', '/wd4800', '/wd4065', '/wd4267', '/we4013']
CXXFLAGS = ['/EHsc']
-BGE_CXXFLAGS = ['/O2', '/EHsc', '/GR', '/fp:fast', '/arch:SSE']
+BGE_CXXFLAGS = ['/O2', '/Ob2', '/EHsc', '/GR', '/fp:fast', '/arch:SSE']
-BF_DEBUG_CCFLAGS = ['/Zi', '/FR${TARGET}.sbr']
+BF_DEBUG_CCFLAGS = ['/Zi', '/Ob0', '/Od', '/FR${TARGET}.sbr']
CPPFLAGS = ['-DWIN32','-D_CONSOLE', '-D_LIB', '-D_CRT_SECURE_NO_DEPRECATE', '-DOPJ_STATIC']
REL_CFLAGS = []
REL_CXXFLAGS = []
-REL_CCFLAGS = ['-O2', '-DNDEBUG']
+REL_CCFLAGS = ['-O2', '/Ob2', '-DNDEBUG']
C_WARN = []
CC_WARN = []
@@ -235,5 +261,9 @@ PLATFORM_LINKFLAGS = ['/SUBSYSTEM:CONSOLE','/MACHINE:IX86','/STACK:2097152','/IN
BF_BSC=False
-BF_BUILDDIR = '..\\build\\win32-vc'
-BF_INSTALLDIR='..\\install\\win32-vc'
+if VC_VERSION == '11.0':
+ BF_BUILDDIR = '..\\build\\win32-vc11'
+ BF_INSTALLDIR='..\\install\\win32-vc11'
+else:
+ BF_BUILDDIR = '..\\build\\win32-vc'
+ BF_INSTALLDIR='..\\install\\win32-vc'
diff --git a/build_files/scons/config/win64-vc-config.py b/build_files/scons/config/win64-vc-config.py
index eb3533cdb8b..c7bf2fa0bd2 100644
--- a/build_files/scons/config/win64-vc-config.py
+++ b/build_files/scons/config/win64-vc-config.py
@@ -1,12 +1,29 @@
-LCGDIR = '#../lib/win64'
+import subprocess
+
+CL_OUT = subprocess.Popen(["cl.exe"],stdout=subprocess.PIPE,stderr=subprocess.PIPE)
+CL_STDOUT, CL_STDERR = CL_OUT.communicate()
+
+if CL_STDERR.find("Version 15.00.") == -1:
+ VC_VERSION = '11.0'
+ LCGDIR = '#../lib/win64_vc11'
+
+else:
+ VC_VERSION = '9.0'
+ LCGDIR = '#../lib/win64'
+
LIBDIR = '${LCGDIR}'
WITH_BF_FFMPEG = True
BF_FFMPEG = LIBDIR +'/ffmpeg'
BF_FFMPEG_INC = '${BF_FFMPEG}/include ${BF_FFMPEG}/include/msvc '
BF_FFMPEG_LIBPATH='${BF_FFMPEG}/lib'
-BF_FFMPEG_LIB = 'avformat-53.lib avcodec-53.lib avdevice-53.lib avutil-51.lib swscale-2.lib'
-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'
+if VC_VERSION == '11.0':
+ BF_FFMPEG_LIB = 'avformat-54.lib avcodec-54.lib avdevice-54.lib avutil-52.lib avfilter-3.lib swscale-2.lib swresample-0.lib'
+ BF_FFMPEG_DLL = '${BF_FFMPEG_LIBPATH}/avformat-54.dll ${BF_FFMPEG_LIBPATH}/avcodec-54.dll ${BF_FFMPEG_LIBPATH}/avdevice-54.dll ${BF_FFMPEG_LIBPATH}/avutil-52.dll ${BF_FFMPEG_LIBPATH}/avfilter-3.dll ${BF_FFMPEG_LIBPATH}/swscale-2.dll ${BF_FFMPEG_LIBPATH}/swresample-0.dll'
+else:
+ BF_FFMPEG_LIB = 'avformat-53.lib avcodec-53.lib avdevice-53.lib avutil-51.lib swscale-2.lib'
+ 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.3'
@@ -19,7 +36,10 @@ BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib'
WITH_BF_OPENAL = True
BF_OPENAL = LIBDIR + '/openal'
BF_OPENAL_INC = '${BF_OPENAL}/include '
-BF_OPENAL_LIB = 'wrap_oal'
+if VC_VERSION == '11.0':
+ BF_OPENAL_LIB = 'OpenAL32'
+else:
+ BF_OPENAL_LIB = 'wrap_oal'
BF_OPENAL_LIBPATH = '${BF_OPENAL}/lib'
WITH_BF_SNDFILE = True
@@ -37,7 +57,10 @@ BF_ICONV_LIBPATH = '${BF_ICONV}/lib'
WITH_BF_SDL = True
BF_SDL = LIBDIR + '/sdl'
BF_SDL_INC = '${BF_SDL}/include'
-BF_SDL_LIB = 'SDL.lib'
+if VC_VERSION == '11.0':
+ BF_SDL_LIB = 'SDL.lib dxguid.lib'
+else:
+ BF_SDL_LIB = 'SDL.lib'
BF_SDL_LIBPATH = '${BF_SDL}/lib'
WITH_BF_JACK = False
@@ -178,8 +201,12 @@ WITH_BF_STATICOCIO = True
WITH_BF_BOOST = True
BF_BOOST = '${LIBDIR}/boost'
BF_BOOST_INC = '${BF_BOOST}/include'
-BF_BOOST_LIB = 'libboost_date_time-vc90-mt-s-1_49 libboost_filesystem-vc90-mt-s-1_49 libboost_regex-vc90-mt-s-1_49 libboost_system-vc90-mt-s-1_49 libboost_thread-vc90-mt-s-1_49 libboost_wave-vc90-mt-s-1_49'
-BF_BOOST_LIB_INTERNATIONAL = ' libboost_locale-vc90-mt-s-1_49'
+if VC_VERSION == '11.0':
+ BF_BOOST_LIB = 'libboost_date_time-vc110-mt-s-1_53 libboost_filesystem-vc110-mt-s-1_53 libboost_regex-vc110-mt-s-1_53 libboost_system-vc110-mt-s-1_53 libboost_thread-vc110-mt-s-1_53 libboost_wave-vc110-mt-s-1_53'
+ BF_BOOST_LIB_INTERNATIONAL = ' libboost_locale-vc110-mt-s-1_53'
+else:
+ BF_BOOST_LIB = 'libboost_date_time-vc90-mt-s-1_49 libboost_filesystem-vc90-mt-s-1_49 libboost_regex-vc90-mt-s-1_49 libboost_system-vc90-mt-s-1_49 libboost_thread-vc90-mt-s-1_49 libboost_wave-vc90-mt-s-1_49'
+ BF_BOOST_LIB_INTERNATIONAL = ' libboost_locale-vc90-mt-s-1_49'
BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
#CUDA
@@ -206,16 +233,16 @@ CC = 'cl.exe'
CXX = 'cl.exe'
CFLAGS = []
-CCFLAGS = ['/nologo', '/Ob1', '/J', '/W1', '/Gd', '/we4013', '/wd4018', '/wd4244', '/wd4305', '/wd4800', '/wd4065', '/wd4267']
+CCFLAGS = ['/nologo', '/J', '/W1', '/Gd', '/we4013', '/wd4018', '/wd4244', '/wd4305', '/wd4800', '/wd4065', '/wd4267']
CXXFLAGS = ['/EHsc']
-BGE_CXXFLAGS = ['/O2', '/EHsc', '/GR', '/fp:fast']
+BGE_CXXFLAGS = ['/O2', '/Ob2', '/EHsc', '/GR', '/fp:fast']
-BF_DEBUG_CCFLAGS = ['/Zi', '/FR${TARGET}.sbr', '/Od']
+BF_DEBUG_CCFLAGS = ['/Zi', '/FR${TARGET}.sbr', '/Od', '/Ob0']
CPPFLAGS = ['-DWIN32', '-D_CONSOLE', '-D_LIB', '-D_CRT_SECURE_NO_DEPRECATE', '-DOPJ_STATIC']
REL_CFLAGS = []
REL_CXXFLAGS = []
-REL_CCFLAGS = ['-O2', '-DNDEBUG']
+REL_CCFLAGS = ['-O2', '/Ob2', '-DNDEBUG']
C_WARN = []
CC_WARN = []
@@ -224,7 +251,9 @@ CXX_WARN = []
LLIBS = ['ws2_32', 'vfw32', 'winmm', 'kernel32', 'user32', 'gdi32', 'comdlg32', 'advapi32', 'shfolder', 'shell32', 'ole32', 'oleaut32', 'uuid', 'psapi']
PLATFORM_LINKFLAGS = ['/SUBSYSTEM:CONSOLE','/MACHINE:X64','/STACK:2097152','/OPT:NOREF','/INCREMENTAL:NO', '/NODEFAULTLIB:msvcrt.lib', '/NODEFAULTLIB:msvcmrt.lib', '/NODEFAULTLIB:msvcurt.lib', '/NODEFAULTLIB:msvcrtd.lib']
-
-BF_BUILDDIR = '..\\build\\win64-vc'
-BF_INSTALLDIR='..\\install\\win64-vc'
-
+if VC_VERSION == '11.0':
+ BF_BUILDDIR = '..\\build\\win64-vc11'
+ BF_INSTALLDIR='..\\install\\win64-vc11'
+else:
+ BF_BUILDDIR = '..\\build\\win64-vc'
+ BF_INSTALLDIR='..\\install\\win64-vc'
diff --git a/build_files/scons/tools/btools.py b/build_files/scons/tools/btools.py
index f98e9a28c44..90674113f47 100644
--- a/build_files/scons/tools/btools.py
+++ b/build_files/scons/tools/btools.py
@@ -190,7 +190,7 @@ def validate_arguments(args, bc):
'BF_BSC', 'BF_CONFIG',
'BF_PRIORITYLIST', 'BF_BUILDINFO','CC', 'CXX', 'BF_QUICKDEBUG',
'BF_LISTDEBUG', 'LCGDIR', 'BF_X264_CONFIG', 'BF_XVIDCORE_CONFIG',
- 'BF_UNIT_TEST', 'BF_BITNESS']
+ 'BF_UNIT_TEST', 'BF_BITNESS', 'MSVS_VERSION']
okdict = {}
@@ -233,8 +233,6 @@ class OurSpawn:
stderr=subprocess.PIPE, startupinfo=startupinfo, shell = False, env=env)
data, err = proc.communicate()
rv = proc.wait()
- if data:
- print(data)
if err:
print(err)
return rv
@@ -689,6 +687,9 @@ def buildslave(target=None, source=None, env=None):
if platform == 'darwin':
platform = 'OSX-' + env['MACOSX_DEPLOYMENT_TARGET'] + '-' + env['MACOSX_ARCHITECTURE']
+ if env['MSVC_VERSION'] == '11.0':
+ platform = env['OURPLATFORM'] + '11'
+
branch = env['BUILDBOT_BRANCH']
outdir = os.path.abspath(env['BF_INSTALLDIR'])
diff --git a/intern/cycles/CMakeLists.txt b/intern/cycles/CMakeLists.txt
index 226218ae512..cc132a2c3b2 100644
--- a/intern/cycles/CMakeLists.txt
+++ b/intern/cycles/CMakeLists.txt
@@ -13,12 +13,17 @@ if(WITH_RAYOPTIMIZATION AND SUPPORT_SSE_BUILD)
endif()
if(WIN32 AND MSVC)
- set(CYCLES_SSE2_KERNEL_FLAGS "/arch:SSE2 -D_CRT_SECURE_NO_WARNINGS /fp:fast /EHsc")
- set(CYCLES_SSE3_KERNEL_FLAGS "/arch:SSE2 -D_CRT_SECURE_NO_WARNINGS /fp:fast /EHsc")
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /fp:fast -D_CRT_SECURE_NO_WARNINGS /EHsc")
+ # there is no /arch:SSE3, but intrinsics are available anyway
+ set(CYCLES_SSE2_KERNEL_FLAGS "/arch:SSE2 /fp:fast -D_CRT_SECURE_NO_WARNINGS /Gs-")
+ set(CYCLES_SSE3_KERNEL_FLAGS "/arch:SSE2 /fp:fast -D_CRT_SECURE_NO_WARNINGS /Gs-")
+
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /fp:fast -D_CRT_SECURE_NO_WARNINGS /Gs-")
+ set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Ox")
+ set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELEASE} /Ox")
+ set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_RELEASE} /Ox")
elseif(CMAKE_COMPILER_IS_GNUCC)
set(CYCLES_SSE2_KERNEL_FLAGS "-ffast-math -msse -msse2 -mfpmath=sse")
- set(CYCLES_SSE3_KERNEL_FLAGS "-ffast-math -msse -msse2 -msse3 -mfpmath=sse")
+ set(CYCLES_SSE3_KERNEL_FLAGS "-ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ffast-math")
endif()
diff --git a/intern/cycles/SConscript b/intern/cycles/SConscript
index a7a4bc22dea..d1f1b287e00 100644
--- a/intern/cycles/SConscript
+++ b/intern/cycles/SConscript
@@ -79,14 +79,15 @@ if env['WITH_BF_RAYOPTIMIZATION']:
sse3_cxxflags = Split(env['CXXFLAGS'])
if env['OURPLATFORM'] == 'win32-vc':
- sse2_cxxflags.append('/arch:SSE2 -D_CRT_SECURE_NO_WARNINGS /fp:fast /EHsc'.split())
- sse3_cxxflags.append('/arch:SSE2 -D_CRT_SECURE_NO_WARNINGS /fp:fast /EHsc'.split())
+ # there is no /arch:SSE3, but intrinsics are available anyway
+ sse2_cxxflags.append('/arch:SSE /arch:SSE2 -D_CRT_SECURE_NO_WARNINGS /fp:fast /Ox /Gs-'.split())
+ sse3_cxxflags.append('/arch:SSE /arch:SSE2 -D_CRT_SECURE_NO_WARNINGS /fp:fast /Ox /Gs-'.split())
elif env['OURPLATFORM'] == 'win64-vc':
- sse2_cxxflags.append('-D_CRT_SECURE_NO_WARNINGS /fp:fast /EHsc'.split())
- sse3_cxxflags.append('-D_CRT_SECURE_NO_WARNINGS /fp:fast /EHsc'.split())
+ sse2_cxxflags.append('-D_CRT_SECURE_NO_WARNINGS /fp:fast /Ox /Gs-'.split())
+ sse3_cxxflags.append('-D_CRT_SECURE_NO_WARNINGS /fp:fast /Ox /Gs-'.split())
else:
sse2_cxxflags.append('-ffast-math -msse -msse2 -mfpmath=sse'.split())
- sse3_cxxflags.append('-ffast-math -msse -msse2 -msse3 -mfpmath=sse'.split())
+ sse3_cxxflags.append('-ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse'.split())
defs.append('WITH_OPTIMIZED_KERNEL')
optim_defs = defs[:]
diff --git a/intern/cycles/blender/addon/__init__.py b/intern/cycles/blender/addon/__init__.py
index e1015fa3cee..b451b8ef3bf 100644
--- a/intern/cycles/blender/addon/__init__.py
+++ b/intern/cycles/blender/addon/__init__.py
@@ -21,7 +21,7 @@
bl_info = {
"name": "Cycles Render Engine",
"author": "",
- "blender": (2, 66, 0),
+ "blender": (2, 67, 0),
"location": "Info header, render engine menu",
"description": "Cycles Render Engine integration",
"warning": "",
diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py
index 0c6cf9f513a..ca49ffccd2a 100644
--- a/intern/cycles/blender/addon/properties.py
+++ b/intern/cycles/blender/addon/properties.py
@@ -504,6 +504,12 @@ class CyclesMaterialSettings(bpy.types.PropertyGroup):
"objects that emit little light compared to other light sources",
default=True,
)
+ cls.use_transparent_shadow = BoolProperty(
+ name="Transparent Shadows",
+ description="Use transparent shadows for this material if it contains a Transparent BSDF, "
+ "disabling will render faster but not give accurate shadows",
+ default=True,
+ )
cls.homogeneous_volume = BoolProperty(
name="Homogeneous Volume",
description="When using volume rendering, assume volume has the same density everywhere, "
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py
index c8d41250754..f90881b9338 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -912,10 +912,13 @@ class CyclesMaterial_PT_settings(CyclesButtonsPanel, Panel):
col = split.column()
col.prop(mat, "diffuse_color", text="Viewport Color")
- col = split.column()
+ col = split.column(align=True)
+ col.label()
col.prop(mat, "pass_index")
-
- layout.prop(cmat, "sample_as_light")
+
+ col = layout.column()
+ col.prop(cmat, "sample_as_light")
+ col.prop(cmat, "use_transparent_shadow")
class CyclesTexture_PT_context(CyclesButtonsPanel, Panel):
diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp
index f2671185301..ee6a0887d45 100644
--- a/intern/cycles/blender/blender_shader.cpp
+++ b/intern/cycles/blender/blender_shader.cpp
@@ -863,7 +863,8 @@ void BlenderSync::sync_materials(bool update_all)
/* settings */
PointerRNA cmat = RNA_pointer_get(&b_mat->ptr, "cycles");
- shader->sample_as_light = get_boolean(cmat, "sample_as_light");
+ shader->use_mis = get_boolean(cmat, "sample_as_light");
+ shader->use_transparent_shadow = get_boolean(cmat, "use_transparent_shadow");
shader->homogeneous_volume = get_boolean(cmat, "homogeneous_volume");
shader->set_graph(graph);
diff --git a/intern/cycles/bvh/bvh.cpp b/intern/cycles/bvh/bvh.cpp
index 82a444bda76..dd647fec2d3 100644
--- a/intern/cycles/bvh/bvh.cpp
+++ b/intern/cycles/bvh/bvh.cpp
@@ -552,9 +552,9 @@ void RegularBVH::pack_node(int idx, const BoundBox& b0, const BoundBox& b1, int
{
int4 data[BVH_NODE_SIZE] =
{
- make_int4(__float_as_int(b0.min.x), __float_as_int(b0.max.x), __float_as_int(b0.min.y), __float_as_int(b0.max.y)),
- make_int4(__float_as_int(b1.min.x), __float_as_int(b1.max.x), __float_as_int(b1.min.y), __float_as_int(b1.max.y)),
- make_int4(__float_as_int(b0.min.z), __float_as_int(b0.max.z), __float_as_int(b1.min.z), __float_as_int(b1.max.z)),
+ make_int4(__float_as_int(b0.min.x), __float_as_int(b1.min.x), __float_as_int(b0.max.x), __float_as_int(b1.max.x)),
+ make_int4(__float_as_int(b0.min.y), __float_as_int(b1.min.y), __float_as_int(b0.max.y), __float_as_int(b1.max.y)),
+ make_int4(__float_as_int(b0.min.z), __float_as_int(b1.min.z), __float_as_int(b0.max.z), __float_as_int(b1.max.z)),
make_int4(c0, c1, visibility0, visibility1)
};
@@ -579,6 +579,7 @@ void RegularBVH::pack_nodes(const array<int>& prims, const BVHNode *root)
int nextNodeIdx = 0;
vector<BVHStackEntry> stack;
+ stack.reserve(BVHParams::MAX_DEPTH*2);
stack.push_back(BVHStackEntry(root, nextNodeIdx++));
while(stack.size()) {
@@ -776,6 +777,7 @@ void QBVH::pack_nodes(const array<int>& prims, const BVHNode *root)
int nextNodeIdx = 0;
vector<BVHStackEntry> stack;
+ stack.reserve(BVHParams::MAX_DEPTH*2);
stack.push_back(BVHStackEntry(root, nextNodeIdx++));
while(stack.size()) {
diff --git a/intern/cycles/device/device_cuda.cpp b/intern/cycles/device/device_cuda.cpp
index f32c6dde639..1f96ed0ae83 100644
--- a/intern/cycles/device/device_cuda.cpp
+++ b/intern/cycles/device/device_cuda.cpp
@@ -271,11 +271,53 @@ public:
return "";
}
+ int cuda_version = cuCompilerVersion();
+
+ if(cuda_version == 0) {
+ cuda_error_message("CUDA nvcc compiler version could not be parsed.");
+ return "";
+ }
+
+ if(cuda_version != 50)
+ printf("CUDA version %d.%d detected, build may succeed but only CUDA 5.0 is officially supported.\n", cuda_version/10, cuda_version%10);
+
/* compile */
string kernel = path_join(kernel_path, "kernel.cu");
string include = kernel_path;
const int machine = system_cpu_bits();
- const int maxreg = 24;
+ string arch_flags;
+
+ /* build flags depending on CUDA version and arch */
+ if(cuda_version < 50) {
+ /* CUDA 4.x */
+ if(major == 1) {
+ /* sm_1x */
+ arch_flags = "--maxrregcount=24 --opencc-options -OPT:Olimit=0";
+ }
+ else if(major == 2) {
+ /* sm_2x */
+ arch_flags = "--maxrregcount=24";
+ }
+ else {
+ /* sm_3x */
+ arch_flags = "--maxrregcount=32";
+ }
+ }
+ else {
+ /* CUDA 4.x */
+ if(major == 1) {
+ /* sm_1x */
+ arch_flags = "--maxrregcount=24 --opencc-options -OPT:Olimit=0 --use_fast_math";
+ }
+ else if(major == 2) {
+ /* sm_2x */
+ arch_flags = "--maxrregcount=32 --use_fast_math";
+ }
+ else {
+ /* sm_3x */
+ arch_flags = "--maxrregcount=32 --use_fast_math";
+ }
+ }
double starttime = time_dt();
printf("Compiling CUDA kernel ...\n");
@@ -283,8 +325,10 @@ public:
path_create_directories(cubin);
string command = string_printf("\"%s\" -arch=sm_%d%d -m%d --cubin \"%s\" "
- "-o \"%s\" --ptxas-options=\"-v\" --maxrregcount=%d --opencc-options -OPT:Olimit=0 -I\"%s\" -DNVCC",
- nvcc.c_str(), major, minor, machine, kernel.c_str(), cubin.c_str(), maxreg, include.c_str());
+ "-o \"%s\" --ptxas-options=\"-v\" %s -I\"%s\" -DNVCC -D__KERNEL_CUDA_VERSION__=%d",
+ nvcc.c_str(), major, minor, machine, kernel.c_str(), cubin.c_str(), arch_flags.c_str(), include.c_str(), cuda_version);
+
+ printf("%s\n", command.c_str());
if(system(command.c_str()) == -1) {
cuda_error_message("Failed to execute compilation command, see console for details.");
diff --git a/intern/cycles/device/device_opencl.cpp b/intern/cycles/device/device_opencl.cpp
index 0fb5c7abafb..2ee4ffaca17 100644
--- a/intern/cycles/device/device_opencl.cpp
+++ b/intern/cycles/device/device_opencl.cpp
@@ -85,7 +85,7 @@ static string opencl_kernel_build_options(const string& platform, const string *
string build_options = " -cl-fast-relaxed-math ";
if(platform == "NVIDIA CUDA")
- build_options += "-D__KERNEL_OPENCL_NVIDIA__ -cl-nv-maxrregcount=24 -cl-nv-verbose ";
+ build_options += "-D__KERNEL_OPENCL_NVIDIA__ -cl-nv-maxrregcount=32 -cl-nv-verbose ";
else if(platform == "Apple")
build_options += "-D__KERNEL_OPENCL_APPLE__ -Wno-missing-prototypes ";
diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt
index 1dcf63f9e47..753d32f5182 100644
--- a/intern/cycles/kernel/CMakeLists.txt
+++ b/intern/cycles/kernel/CMakeLists.txt
@@ -118,32 +118,68 @@ set(SRC_UTIL_HEADERS
# CUDA module
if(WITH_CYCLES_CUDA_BINARIES)
+ # 32 bit or 64 bit
if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
set(CUDA_BITS 64)
else()
set(CUDA_BITS 32)
endif()
+ # CUDA version
+ execute_process (COMMAND ${CUDA_NVCC_EXECUTABLE} "--version" OUTPUT_VARIABLE NVCC_OUT)
+ string(REGEX REPLACE ".*release ([0-9]+)\\.([0-9]+).*" "\\1" CUDA_VERSION_MAJOR ${NVCC_OUT})
+ string(REGEX REPLACE ".*release ([0-9]+)\\.([0-9]+).*" "\\2" CUDA_VERSION_MINOR ${NVCC_OUT})
+ set(CUDA_VERSION "${CUDA_VERSION_MAJOR}${CUDA_VERSION_MINOR}")
+
+ # build for each arch
set(cuda_sources kernel.cu ${SRC_HEADERS} ${SRC_SVM_HEADERS} ${SRC_CLOSURE_HEADERS} ${SRC_UTIL_HEADERS})
set(cuda_cubins)
foreach(arch ${CYCLES_CUDA_BINARIES_ARCH})
set(cuda_cubin kernel_${arch}.cubin)
- if(${arch} MATCHES "sm_1[0-9]")
- # sm_1x
- set(cuda_arch_flags "--maxrregcount=24 --opencc-options -OPT:Olimit=0")
- elseif(${arch} MATCHES "sm_2[0-9]")
- # sm_2x
- set(cuda_arch_flags "--maxrregcount=24")
+ set(cuda_version_flags "-D__KERNEL_CUDA_VERSION__=${CUDA_VERSION}")
+
+ # warn for other versions
+ if(CUDA_VERSION MATCHES "50")
+ else()
+ message(STATUS "CUDA version ${CUDA_VERSION_MAJOR}.${CUDA_VERSION_MINOR} detected, build may succeed but only CUDA 5.0 is officially supported")
+ endif()
+
+ # build flags depending on CUDA version and arch
+ if(CUDA_VERSION LESS 50)
+ # CUDA 4.x
+ if(${arch} MATCHES "sm_1[0-9]")
+ # sm_1x
+ set(cuda_arch_flags "--maxrregcount=24 --opencc-options -OPT:Olimit=0")
+ elseif(${arch} MATCHES "sm_2[0-9]")
+ # sm_2x
+ set(cuda_arch_flags "--maxrregcount=24")
+ else()
+ # sm_3x
+ set(cuda_arch_flags "--maxrregcount=32")
+ endif()
+
+ set(cuda_math_flags "")
else()
- # sm_3x
- set(cuda_arch_flags "--maxrregcount=32")
+ # CUDA 5.x
+ if(${arch} MATCHES "sm_1[0-9]")
+ # sm_1x
+ set(cuda_arch_flags "--maxrregcount=24 --opencc-options -OPT:Olimit=0")
+ elseif(${arch} MATCHES "sm_2[0-9]")
+ # sm_2x
+ set(cuda_arch_flags "--maxrregcount=32")
+ else()
+ # sm_3x
+ set(cuda_arch_flags "--maxrregcount=32")
+ endif()
+
+ set(cuda_math_flags "--use_fast_math")
endif()
add_custom_command(
OUTPUT ${cuda_cubin}
- COMMAND ${CUDA_NVCC_EXECUTABLE} -arch=${arch} -m${CUDA_BITS} --cubin ${CMAKE_CURRENT_SOURCE_DIR}/kernel.cu -o ${CMAKE_CURRENT_BINARY_DIR}/${cuda_cubin} --ptxas-options="-v" ${cuda_arch_flags} -I${CMAKE_CURRENT_SOURCE_DIR}/../util -I${CMAKE_CURRENT_SOURCE_DIR}/svm -DCCL_NAMESPACE_BEGIN= -DCCL_NAMESPACE_END= -DNVCC
+ COMMAND ${CUDA_NVCC_EXECUTABLE} -arch=${arch} -m${CUDA_BITS} --cubin ${CMAKE_CURRENT_SOURCE_DIR}/kernel.cu -o ${CMAKE_CURRENT_BINARY_DIR}/${cuda_cubin} --ptxas-options="-v" ${cuda_arch_flags} ${cuda_version_flags} ${cuda_math_flags} -I${CMAKE_CURRENT_SOURCE_DIR}/../util -I${CMAKE_CURRENT_SOURCE_DIR}/svm -DCCL_NAMESPACE_BEGIN= -DCCL_NAMESPACE_END= -DNVCC
DEPENDS ${cuda_sources})
delayed_install("${CMAKE_CURRENT_BINARY_DIR}" "${cuda_cubin}" ${CYCLES_INSTALL_PATH}/lib)
diff --git a/intern/cycles/kernel/SConscript b/intern/cycles/kernel/SConscript
index 3a46d10dee1..353ec1ce9d8 100644
--- a/intern/cycles/kernel/SConscript
+++ b/intern/cycles/kernel/SConscript
@@ -25,6 +25,8 @@
#
# ***** END GPL LICENSE BLOCK *****
+import re
+import subprocess
import sys
import os
import Blender as B
@@ -60,10 +62,19 @@ if env['WITH_BF_CYCLES_CUDA_BINARIES']:
svm_dir = os.path.join(source_dir, "../svm")
closure_dir = os.path.join(source_dir, "../closure")
+ # get CUDA version
+ nvcc_pipe = subprocess.Popen([nvcc, "--version"],stdout=subprocess.PIPE,stderr=subprocess.PIPE)
+ output, erroroutput = nvcc_pipe.communicate()
+ cuda_major_minor = re.findall(r'release (\d+).(\d+)', output)[0]
+ cuda_version = int(cuda_major_minor[0])*10 + int(cuda_major_minor[1])
+
+ if cuda_version != 50:
+ print("CUDA version %d.%d detected, build may succeed but only CUDA 5.0 is officially supported." % (cuda_version/10, cuda_version%10))
+
# nvcc flags
nvcc_flags = "-m%s" % (bits)
- nvcc_flags += " --cubin --ptxas-options=\"-v\" --maxrregcount=24"
- nvcc_flags += " --opencc-options -OPT:Olimit=0"
+ nvcc_flags += " --cubin --ptxas-options=\"-v\""
+ nvcc_flags += " -D__KERNEL_CUDA_VERSION__=%d" % (cuda_version)
nvcc_flags += " -DCCL_NAMESPACE_BEGIN= -DCCL_NAMESPACE_END= -DNVCC"
nvcc_flags += " -I \"%s\" -I \"%s\" -I \"%s\"" % (util_dir, svm_dir, closure_dir)
@@ -75,7 +86,31 @@ if env['WITH_BF_CYCLES_CUDA_BINARIES']:
for arch in cuda_archs:
cubin_file = os.path.join(build_dir, "kernel_%s.cubin" % arch)
- command = "\"%s\" -arch=%s %s \"%s\" -o \"%s\"" % (nvcc, arch, nvcc_flags, kernel_file, cubin_file)
+ # build flags depending on CUDA version and arch
+ if cuda_version < 50:
+ # CUDA 4.x
+ if arch.startswith("sm_1"):
+ # sm_1x
+ cuda_arch_flags = "--maxrregcount=24 --opencc-options -OPT:Olimit=0"
+ elif arch.startswith("sm_2"):
+ # sm_2x
+ cuda_arch_flags = "--maxrregcount=24"
+ else:
+ # sm_3x
+ cuda_arch_flags = "--maxrregcount=32"
+ else:
+ # CUDA 5.x
+ if arch.startswith("sm_1"):
+ # sm_1x
+ cuda_arch_flags = "--maxrregcount=24 --opencc-options -OPT:Olimit=0 --use_fast_math"
+ elif arch.startswith("sm_2"):
+ # sm_2x
+ cuda_arch_flags = "--maxrregcount=32 --use_fast_math"
+ else:
+ # sm_3x
+ cuda_arch_flags = "--maxrregcount=32 --use_fast_math"
+
+ command = "\"%s\" -arch=%s %s %s \"%s\" -o \"%s\"" % (nvcc, arch, nvcc_flags, cuda_arch_flags, kernel_file, cubin_file)
kernel.Command(cubin_file, 'kernel.cu', command)
kernel.Depends(cubin_file, dependencies)
diff --git a/intern/cycles/kernel/kernel_bvh.h b/intern/cycles/kernel/kernel_bvh.h
index ae9677ed5cb..9f6d79e13fb 100644
--- a/intern/cycles/kernel/kernel_bvh.h
+++ b/intern/cycles/kernel/kernel_bvh.h
@@ -112,80 +112,8 @@ __device_inline void bvh_instance_motion_pop(KernelGlobals *kg, int object, cons
}
#endif
-/* intersect two bounding boxes */
-#ifdef __HAIR__
-__device_inline void bvh_node_intersect(KernelGlobals *kg,
- bool *traverseChild0, bool *traverseChild1,
- bool *closestChild1, int *nodeAddr0, int *nodeAddr1,
- float3 P, float3 idir, float t, uint visibility, int nodeAddr, float difl, float extmax)
-{
-#else
-__device_inline void bvh_node_intersect(KernelGlobals *kg,
- bool *traverseChild0, bool *traverseChild1,
- bool *closestChild1, int *nodeAddr0, int *nodeAddr1,
- float3 P, float3 idir, float t, uint visibility, int nodeAddr)
-{
-#endif
-
- /* fetch node data */
- float4 n0xy = kernel_tex_fetch(__bvh_nodes, nodeAddr*BVH_NODE_SIZE+0);
- float4 n1xy = kernel_tex_fetch(__bvh_nodes, nodeAddr*BVH_NODE_SIZE+1);
- float4 nz = kernel_tex_fetch(__bvh_nodes, nodeAddr*BVH_NODE_SIZE+2);
- float4 cnodes = kernel_tex_fetch(__bvh_nodes, nodeAddr*BVH_NODE_SIZE+3);
-
- /* intersect ray against child nodes */
- float3 ood = P * idir;
- NO_EXTENDED_PRECISION float c0lox = n0xy.x * idir.x - ood.x;
- NO_EXTENDED_PRECISION float c0hix = n0xy.y * idir.x - ood.x;
- NO_EXTENDED_PRECISION float c0loy = n0xy.z * idir.y - ood.y;
- NO_EXTENDED_PRECISION float c0hiy = n0xy.w * idir.y - ood.y;
- NO_EXTENDED_PRECISION float c0loz = nz.x * idir.z - ood.z;
- NO_EXTENDED_PRECISION float c0hiz = nz.y * idir.z - ood.z;
- NO_EXTENDED_PRECISION float c0min = max4(min(c0lox, c0hix), min(c0loy, c0hiy), min(c0loz, c0hiz), 0.0f);
- NO_EXTENDED_PRECISION float c0max = min4(max(c0lox, c0hix), max(c0loy, c0hiy), max(c0loz, c0hiz), t);
-
- NO_EXTENDED_PRECISION float c1loz = nz.z * idir.z - ood.z;
- NO_EXTENDED_PRECISION float c1hiz = nz.w * idir.z - ood.z;
- NO_EXTENDED_PRECISION float c1lox = n1xy.x * idir.x - ood.x;
- NO_EXTENDED_PRECISION float c1hix = n1xy.y * idir.x - ood.x;
- NO_EXTENDED_PRECISION float c1loy = n1xy.z * idir.y - ood.y;
- NO_EXTENDED_PRECISION float c1hiy = n1xy.w * idir.y - ood.y;
- NO_EXTENDED_PRECISION float c1min = max4(min(c1lox, c1hix), min(c1loy, c1hiy), min(c1loz, c1hiz), 0.0f);
- NO_EXTENDED_PRECISION float c1max = min4(max(c1lox, c1hix), max(c1loy, c1hiy), max(c1loz, c1hiz), t);
-
-#ifdef __HAIR__
- if(difl != 0.0f) {
- float hdiff = 1.0f + difl;
- float ldiff = 1.0f - difl;
- if(__float_as_int(cnodes.z) & PATH_RAY_CURVE) {
- c0min = max(ldiff * c0min, c0min - extmax);
- c0max = min(hdiff * c0max, c0max + extmax);
- }
- if(__float_as_int(cnodes.w) & PATH_RAY_CURVE) {
- c1min = max(ldiff * c1min, c1min - extmax);
- c1max = min(hdiff * c1max, c1max + extmax);
- }
- }
-#endif
-
- /* decide which nodes to traverse next */
-#ifdef __VISIBILITY_FLAG__
- /* this visibility test gives a 5% performance hit, how to solve? */
- *traverseChild0 = (c0max >= c0min) && (__float_as_uint(cnodes.z) & visibility);
- *traverseChild1 = (c1max >= c1min) && (__float_as_uint(cnodes.w) & visibility);
-#else
- *traverseChild0 = (c0max >= c0min);
- *traverseChild1 = (c1max >= c1min);
-#endif
-
- *nodeAddr0 = __float_as_int(cnodes.x);
- *nodeAddr1 = __float_as_int(cnodes.y);
-
- *closestChild1 = (c1min < c0min);
-}
-
/* Sven Woop's algorithm */
-__device_inline void bvh_triangle_intersect(KernelGlobals *kg, Intersection *isect,
+__device_inline bool bvh_triangle_intersect(KernelGlobals *kg, Intersection *isect,
float3 P, float3 idir, uint visibility, int object, int triAddr)
{
/* compute and check intersection t-value */
@@ -223,10 +151,13 @@ __device_inline void bvh_triangle_intersect(KernelGlobals *kg, Intersection *ise
isect->u = u;
isect->v = v;
isect->t = t;
+ return true;
}
}
}
}
+
+ return false;
}
#ifdef __HAIR__
@@ -280,7 +211,7 @@ __device_inline void curvebounds(float *lower, float *upper, float *extremta, fl
}
}
-__device_inline void bvh_cardinal_curve_intersect(KernelGlobals *kg, Intersection *isect,
+__device_inline bool bvh_cardinal_curve_intersect(KernelGlobals *kg, Intersection *isect,
float3 P, float3 idir, uint visibility, int object, int curveAddr, int segment, uint *lcg_state, float difl, float extmax)
{
float epsilon = 0.0f;
@@ -346,7 +277,7 @@ __device_inline void bvh_cardinal_curve_intersect(KernelGlobals *kg, Intersectio
float zextrem[4];
curvebounds(&lower, &upper, &zextrem[0], &zextrem[1], &zextrem[2], &zextrem[3], curve_coef[0].z, curve_coef[1].z, curve_coef[2].z, curve_coef[3].z);
if(lower - r_curr > isect->t || upper + r_curr < epsilon)
- return;
+ return false;
/*minimum width extension*/
float mw_extension = min(difl * fabsf(upper), extmax);
@@ -355,17 +286,18 @@ __device_inline void bvh_cardinal_curve_intersect(KernelGlobals *kg, Intersectio
float xextrem[4];
curvebounds(&lower, &upper, &xextrem[0], &xextrem[1], &xextrem[2], &xextrem[3], curve_coef[0].x, curve_coef[1].x, curve_coef[2].x, curve_coef[3].x);
if(lower > r_ext || upper < -r_ext)
- return;
+ return false;
float yextrem[4];
curvebounds(&lower, &upper, &yextrem[0], &yextrem[1], &yextrem[2], &yextrem[3], curve_coef[0].y, curve_coef[1].y, curve_coef[2].y, curve_coef[3].y);
if(lower > r_ext || upper < -r_ext)
- return;
+ return false;
/*setup recurrent loop*/
int level = 1 << depth;
int tree = 0;
float resol = 1.0f / (float)level;
+ bool hit = false;
/*begin loop*/
while(!(tree >> (depth))) {
@@ -557,7 +489,7 @@ __device_inline void bvh_cardinal_curve_intersect(KernelGlobals *kg, Intersectio
/*stochastic fade from minimum width*/
if(lcg_state && coverage != 1.0f) {
if(lcg_step(lcg_state) > coverage)
- return;
+ return hit;
}
#ifdef __VISIBILITY_FLAG__
@@ -574,6 +506,7 @@ __device_inline void bvh_cardinal_curve_intersect(KernelGlobals *kg, Intersectio
isect->v = 0.0f;
/*isect->v = 1.0f - coverage; */
isect->t = t;
+ hit = true;
}
tree++;
@@ -584,9 +517,11 @@ __device_inline void bvh_cardinal_curve_intersect(KernelGlobals *kg, Intersectio
level = level >> 1;
}
}
+
+ return hit;
}
-__device_inline void bvh_curve_intersect(KernelGlobals *kg, Intersection *isect,
+__device_inline bool bvh_curve_intersect(KernelGlobals *kg, Intersection *isect,
float3 P, float3 idir, uint visibility, int object, int curveAddr, int segment, uint *lcg_state, float difl, float extmax)
{
/* curve Intersection check */
@@ -630,7 +565,7 @@ __device_inline void bvh_curve_intersect(KernelGlobals *kg, Intersection *isect,
sphere_b = dot(dir,sphere_dif);
float sdisc = sphere_b * sphere_b - len_squared(sphere_dif) + sp_r * sp_r;
if(sdisc < 0.0f)
- return;
+ return false;
/* obtain parameters and test midpoint distance for suitable modes*/
float3 tg = (p2 - p1) / l;
@@ -645,9 +580,9 @@ __device_inline void bvh_curve_intersect(KernelGlobals *kg, Intersection *isect,
float zcentre = difz + (dirz * tcentre);
if((tcentre > isect->t) && !(flags & CURVE_KN_ACCURATE))
- return;
+ return false;
if((zcentre < 0 || zcentre > l) && !(flags & CURVE_KN_ACCURATE) && !(flags & CURVE_KN_INTERSECTCORRECTION))
- return;
+ return false;
/* test minimum separation*/
float3 cprod = cross(tg, dir);
@@ -662,7 +597,7 @@ __device_inline void bvh_curve_intersect(KernelGlobals *kg, Intersection *isect,
distscaled = (distscaled*distscaled)/cprodsq;
if(distscaled > mr*mr)
- return;
+ return false;
/* calculate true intersection*/
float3 tdif = P - p1 + tcentre * dir;
@@ -672,7 +607,7 @@ __device_inline void bvh_curve_intersect(KernelGlobals *kg, Intersection *isect,
float td = tb*tb - 4*a*tc;
if (td < 0.0f)
- return;
+ return false;
float rootd = 0.0f;
float correction = 0.0f;
@@ -706,7 +641,7 @@ __device_inline void bvh_curve_intersect(KernelGlobals *kg, Intersection *isect,
adjradius = adjradius / (r1 + z * gd);
if(lcg_state && adjradius != 1.0f) {
if(lcg_step(lcg_state) > adjradius)
- return;
+ return false;
}
/* --- */
@@ -719,7 +654,7 @@ __device_inline void bvh_curve_intersect(KernelGlobals *kg, Intersection *isect,
float a2 = 1.0f - (dirz*dirz*(1 + gd*gd*enc_ratio*enc_ratio));
float c2 = dot(dif,dif) - difz * difz * (1 + gd*gd*enc_ratio*enc_ratio) - r1*r1*enc_ratio*enc_ratio - 2*r1*difz*gd*enc_ratio;
if(a2*c2 < 0.0f)
- return;
+ return false;
}
}
@@ -740,9 +675,13 @@ __device_inline void bvh_curve_intersect(KernelGlobals *kg, Intersection *isect,
if(backface)
isect->u = -isect->u;
+
+ return true;
}
}
}
+
+ return false;
}
#endif
@@ -751,7 +690,7 @@ __device_inline void bvh_curve_intersect(KernelGlobals *kg, Intersection *isect,
* only want to intersect with primitives in the same object, and if case of
* multiple hits we pick a single random primitive as the intersection point. */
-__device_inline void bvh_triangle_intersect_subsurface(KernelGlobals *kg, Intersection *isect,
+__device_inline bool bvh_triangle_intersect_subsurface(KernelGlobals *kg, Intersection *isect,
float3 P, float3 idir, int object, int triAddr, float tmax, int *num_hits, float subsurface_random)
{
/* compute and check intersection t-value */
@@ -786,10 +725,13 @@ __device_inline void bvh_triangle_intersect_subsurface(KernelGlobals *kg, Inters
isect->u = u;
isect->v = v;
isect->t = t;
+ return true;
}
}
}
}
+
+ return false;
}
#endif
diff --git a/intern/cycles/kernel/kernel_bvh_traversal.h b/intern/cycles/kernel/kernel_bvh_traversal.h
index 2d75af32abd..8d423b7e7ce 100644
--- a/intern/cycles/kernel/kernel_bvh_traversal.h
+++ b/intern/cycles/kernel/kernel_bvh_traversal.h
@@ -1,6 +1,8 @@
/*
- * Adapted from code Copyright 2009-2010 NVIDIA Corporation
- * Modifications Copyright 2011, Blender Foundation.
+ * Adapted from code Copyright 2009-2010 NVIDIA Corporation,
+ * and code copyright 2009-2012 Intel Corporation
+ *
+ * Modifications Copyright 2011-2013, Blender Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -41,6 +43,14 @@ __device bool BVH_FUNCTION_NAME
#endif
)
{
+ /* todo:
+ * - test if pushing distance on the stack helps (for non shadow rays)
+ * - separate version for shadow rays
+ * - likely and unlikely for if() statements
+ * - SSE for hair
+ * - test restrict attribute for pointers
+ */
+
/* traversal stack in CUDA thread-local memory */
int traversalStack[BVH_STACK_SIZE];
traversalStack[0] = ENTRYPOINT_SENTINEL;
@@ -70,6 +80,28 @@ __device bool BVH_FUNCTION_NAME
isect->u = 0.0f;
isect->v = 0.0f;
+#if defined(__KERNEL_SSE2__) && !FEATURE(BVH_HAIR_MINIMUM_WIDTH)
+ const shuffle_swap_t shuf_identity = shuffle_swap_identity();
+ const shuffle_swap_t shuf_swap = shuffle_swap_swap();
+
+ const __m128i pn = _mm_set_epi32(0x80000000, 0x80000000, 0x00000000, 0x00000000);
+ __m128 Psplat[3], idirsplat[3];
+
+ Psplat[0] = _mm_set_ps1(P.x);
+ Psplat[1] = _mm_set_ps1(P.y);
+ Psplat[2] = _mm_set_ps1(P.z);
+
+ idirsplat[0] = _mm_xor_ps(_mm_set_ps1(idir.x), _mm_castsi128_ps(pn));
+ idirsplat[1] = _mm_xor_ps(_mm_set_ps1(idir.y), _mm_castsi128_ps(pn));
+ idirsplat[2] = _mm_xor_ps(_mm_set_ps1(idir.z), _mm_castsi128_ps(pn));
+
+ __m128 tsplat = _mm_set_ps(-isect->t, -isect->t, 0.0f, 0.0f);
+
+ shuffle_swap_t shufflex = (idir.x >= 0)? shuf_identity: shuf_swap;
+ shuffle_swap_t shuffley = (idir.y >= 0)? shuf_identity: shuf_swap;
+ shuffle_swap_t shufflez = (idir.z >= 0)? shuf_identity: shuf_swap;
+#endif
+
/* traversal loop */
do {
do
@@ -77,46 +109,121 @@ __device bool BVH_FUNCTION_NAME
/* traverse internal nodes */
while(nodeAddr >= 0 && nodeAddr != ENTRYPOINT_SENTINEL)
{
- bool traverseChild0, traverseChild1, closestChild1;
+ bool traverseChild0, traverseChild1;
int nodeAddrChild1;
+#if !defined(__KERNEL_SSE2__) || FEATURE(BVH_HAIR_MINIMUM_WIDTH)
+ /* Intersect two child bounding boxes, non-SSE version */
+ float t = isect->t;
+
+ /* fetch node data */
+ float4 node0 = kernel_tex_fetch(__bvh_nodes, nodeAddr*BVH_NODE_SIZE+0);
+ float4 node1 = kernel_tex_fetch(__bvh_nodes, nodeAddr*BVH_NODE_SIZE+1);
+ float4 node2 = kernel_tex_fetch(__bvh_nodes, nodeAddr*BVH_NODE_SIZE+2);
+ float4 cnodes = kernel_tex_fetch(__bvh_nodes, nodeAddr*BVH_NODE_SIZE+3);
+
+ /* intersect ray against child nodes */
+ NO_EXTENDED_PRECISION float c0lox = (node0.x - P.x) * idir.x;
+ NO_EXTENDED_PRECISION float c0hix = (node0.z - P.x) * idir.x;
+ NO_EXTENDED_PRECISION float c0loy = (node1.x - P.y) * idir.y;
+ NO_EXTENDED_PRECISION float c0hiy = (node1.z - P.y) * idir.y;
+ NO_EXTENDED_PRECISION float c0loz = (node2.x - P.z) * idir.z;
+ NO_EXTENDED_PRECISION float c0hiz = (node2.z - P.z) * idir.z;
+ NO_EXTENDED_PRECISION float c0min = max4(min(c0lox, c0hix), min(c0loy, c0hiy), min(c0loz, c0hiz), 0.0f);
+ NO_EXTENDED_PRECISION float c0max = min4(max(c0lox, c0hix), max(c0loy, c0hiy), max(c0loz, c0hiz), t);
+
+ NO_EXTENDED_PRECISION float c1lox = (node0.y - P.x) * idir.x;
+ NO_EXTENDED_PRECISION float c1hix = (node0.w - P.x) * idir.x;
+ NO_EXTENDED_PRECISION float c1loy = (node1.y - P.y) * idir.y;
+ NO_EXTENDED_PRECISION float c1hiy = (node1.w - P.y) * idir.y;
+ NO_EXTENDED_PRECISION float c1loz = (node2.y - P.z) * idir.z;
+ NO_EXTENDED_PRECISION float c1hiz = (node2.w - P.z) * idir.z;
+ NO_EXTENDED_PRECISION float c1min = max4(min(c1lox, c1hix), min(c1loy, c1hiy), min(c1loz, c1hiz), 0.0f);
+ NO_EXTENDED_PRECISION float c1max = min4(max(c1lox, c1hix), max(c1loy, c1hiy), max(c1loz, c1hiz), t);
+
#if FEATURE(BVH_HAIR_MINIMUM_WIDTH) && !FEATURE(BVH_SUBSURFACE)
- bvh_node_intersect(kg, &traverseChild0, &traverseChild1,
- &closestChild1, &nodeAddr, &nodeAddrChild1,
- P, idir, isect->t, visibility, nodeAddr, difl, extmax);
+ if(difl != 0.0f) {
+ float hdiff = 1.0f + difl;
+ float ldiff = 1.0f - difl;
+ if(__float_as_int(cnodes.z) & PATH_RAY_CURVE) {
+ c0min = max(ldiff * c0min, c0min - extmax);
+ c0max = min(hdiff * c0max, c0max + extmax);
+ }
+ if(__float_as_int(cnodes.w) & PATH_RAY_CURVE) {
+ c1min = max(ldiff * c1min, c1min - extmax);
+ c1max = min(hdiff * c1max, c1max + extmax);
+ }
+ }
+#endif
+
+ /* decide which nodes to traverse next */
+#ifdef __VISIBILITY_FLAG__
+ /* this visibility test gives a 5% performance hit, how to solve? */
+ traverseChild0 = (c0max >= c0min) && (__float_as_uint(cnodes.z) & visibility);
+ traverseChild1 = (c1max >= c1min) && (__float_as_uint(cnodes.w) & visibility);
#else
- bvh_node_intersect(kg, &traverseChild0, &traverseChild1,
- &closestChild1, &nodeAddr, &nodeAddrChild1,
-#ifdef __HAIR__
- P, idir, isect->t, visibility, nodeAddr, 0.0f, 0.0f);
+ traverseChild0 = (c0max >= c0min);
+ traverseChild1 = (c1max >= c1min);
+#endif
+
+#else // __KERNEL_SSE2__
+ /* Intersect two child bounding boxes, SSE3 version adapted from Embree */
+
+ /* fetch node data */
+ __m128 *bvh_nodes = (__m128*)kg->__bvh_nodes.data + nodeAddr*BVH_NODE_SIZE;
+ float4 cnodes = ((float4*)bvh_nodes)[3];
+
+ /* intersect ray against child nodes */
+ const __m128 tminmaxx = _mm_mul_ps(_mm_sub_ps(shuffle_swap(bvh_nodes[0], shufflex), Psplat[0]), idirsplat[0]);
+ const __m128 tminmaxy = _mm_mul_ps(_mm_sub_ps(shuffle_swap(bvh_nodes[1], shuffley), Psplat[1]), idirsplat[1]);
+ const __m128 tminmaxz = _mm_mul_ps(_mm_sub_ps(shuffle_swap(bvh_nodes[2], shufflez), Psplat[2]), idirsplat[2]);
+
+ const __m128 tminmax = _mm_xor_ps(_mm_max_ps(_mm_max_ps(tminmaxx, tminmaxy), _mm_max_ps(tminmaxz, tsplat)), _mm_castsi128_ps(pn));
+ const __m128 lrhit = _mm_cmple_ps(tminmax, shuffle_swap(tminmax, shuf_swap));
+
+ /* decide which nodes to traverse next */
+#ifdef __VISIBILITY_FLAG__
+ /* this visibility test gives a 5% performance hit, how to solve? */
+ traverseChild0 = (_mm_movemask_ps(lrhit) & 1) && (__float_as_uint(cnodes.z) & visibility);
+ traverseChild1 = (_mm_movemask_ps(lrhit) & 2) && (__float_as_uint(cnodes.w) & visibility);
#else
- P, idir, isect->t, visibility, nodeAddr);
+ traverseChild0 = (_mm_movemask_ps(lrhit) & 1);
+ traverseChild1 = (_mm_movemask_ps(lrhit) & 2);
#endif
+#endif // __KERNEL_SSE2__
+
+ nodeAddr = __float_as_int(cnodes.x);
+ nodeAddrChild1 = __float_as_int(cnodes.y);
+
+ if(traverseChild0 && traverseChild1) {
+ /* both children were intersected, push the farther one */
+#if !defined(__KERNEL_SSE2__) || FEATURE(BVH_HAIR_MINIMUM_WIDTH)
+ bool closestChild1 = (c1min < c0min);
+#else
+ union { __m128 m128; float v[4]; } uminmax;
+ uminmax.m128 = tminmax;
+ bool closestChild1 = uminmax.v[1] < uminmax.v[0];
#endif
- if(traverseChild0 != traverseChild1) {
- /* one child was intersected */
- if(traverseChild1) {
+ if(closestChild1) {
+ int tmp = nodeAddr;
nodeAddr = nodeAddrChild1;
+ nodeAddrChild1 = tmp;
}
+
+ ++stackPtr;
+ traversalStack[stackPtr] = nodeAddrChild1;
}
else {
- if(!traverseChild0) {
+ /* one child was intersected */
+ if(traverseChild1) {
+ nodeAddr = nodeAddrChild1;
+ }
+ else if(!traverseChild0) {
/* neither child was intersected */
nodeAddr = traversalStack[stackPtr];
--stackPtr;
}
- else {
- /* both children were intersected, push the farther one */
- if(closestChild1) {
- int tmp = nodeAddr;
- nodeAddr = nodeAddrChild1;
- nodeAddrChild1 = tmp;
- }
-
- ++stackPtr;
- traversalStack[stackPtr] = nodeAddrChild1;
- }
}
}
@@ -136,6 +243,8 @@ __device bool BVH_FUNCTION_NAME
/* primitive intersection */
while(primAddr < primAddr2) {
+ bool hit;
+
#if FEATURE(BVH_SUBSURFACE)
/* only primitives from the same object */
uint tri_object = (object == ~0)? kernel_tex_fetch(__prim_object, primAddr): object;
@@ -148,15 +257,16 @@ __device bool BVH_FUNCTION_NAME
uint segment = kernel_tex_fetch(__prim_segment, primAddr);
#if !FEATURE(BVH_SUBSURFACE)
if(segment != ~0) {
+
if(kernel_data.curve_kernel_data.curveflags & CURVE_KN_INTERPOLATE)
#if FEATURE(BVH_HAIR_MINIMUM_WIDTH)
- bvh_cardinal_curve_intersect(kg, isect, P, idir, visibility, object, primAddr, segment, lcg_state, difl, extmax);
+ hit = bvh_cardinal_curve_intersect(kg, isect, P, idir, visibility, object, primAddr, segment, lcg_state, difl, extmax);
else
- bvh_curve_intersect(kg, isect, P, idir, visibility, object, primAddr, segment, lcg_state, difl, extmax);
+ hit = bvh_curve_intersect(kg, isect, P, idir, visibility, object, primAddr, segment, lcg_state, difl, extmax);
#else
- bvh_cardinal_curve_intersect(kg, isect, P, idir, visibility, object, primAddr, segment);
+ hit = bvh_cardinal_curve_intersect(kg, isect, P, idir, visibility, object, primAddr, segment);
else
- bvh_curve_intersect(kg, isect, P, idir, visibility, object, primAddr, segment);
+ hit = bvh_curve_intersect(kg, isect, P, idir, visibility, object, primAddr, segment);
#endif
}
else
@@ -166,17 +276,30 @@ __device bool BVH_FUNCTION_NAME
#if FEATURE(BVH_HAIR)
if(segment == ~0)
#endif
- bvh_triangle_intersect_subsurface(kg, isect, P, idir, object, primAddr, tmax, &num_hits, subsurface_random);
+ {
+ hit = bvh_triangle_intersect_subsurface(kg, isect, P, idir, object, primAddr, tmax, &num_hits, subsurface_random);
+ (void)hit;
+ }
}
#else
- bvh_triangle_intersect(kg, isect, P, idir, visibility, object, primAddr);
+ hit = bvh_triangle_intersect(kg, isect, P, idir, visibility, object, primAddr);
/* shadow ray early termination */
- if(visibility == PATH_RAY_SHADOW_OPAQUE && isect->prim != ~0)
+#if defined(__KERNEL_SSE2__) && !FEATURE(BVH_HAIR_MINIMUM_WIDTH)
+ if(hit) {
+ if(visibility == PATH_RAY_SHADOW_OPAQUE)
+ return true;
+
+ tsplat = _mm_set_ps(-isect->t, -isect->t, 0.0f, 0.0f);
+ }
+#else
+ if(hit && visibility == PATH_RAY_SHADOW_OPAQUE)
return true;
#endif
+#endif
+
primAddr++;
}
}
@@ -196,6 +319,22 @@ __device bool BVH_FUNCTION_NAME
bvh_instance_push(kg, object, ray, &P, &idir, &isect->t, tmax);
#endif
+#if defined(__KERNEL_SSE2__) && !FEATURE(BVH_HAIR_MINIMUM_WIDTH)
+ Psplat[0] = _mm_set_ps1(P.x);
+ Psplat[1] = _mm_set_ps1(P.y);
+ Psplat[2] = _mm_set_ps1(P.z);
+
+ idirsplat[0] = _mm_xor_ps(_mm_set_ps1(idir.x), _mm_castsi128_ps(pn));
+ idirsplat[1] = _mm_xor_ps(_mm_set_ps1(idir.y), _mm_castsi128_ps(pn));
+ idirsplat[2] = _mm_xor_ps(_mm_set_ps1(idir.z), _mm_castsi128_ps(pn));
+
+ tsplat = _mm_set_ps(-isect->t, -isect->t, 0.0f, 0.0f);
+
+ shufflex = (idir.x >= 0)? shuf_identity: shuf_swap;
+ shuffley = (idir.y >= 0)? shuf_identity: shuf_swap;
+ shufflez = (idir.z >= 0)? shuf_identity: shuf_swap;
+#endif
+
++stackPtr;
traversalStack[stackPtr] = ENTRYPOINT_SENTINEL;
@@ -223,6 +362,23 @@ __device bool BVH_FUNCTION_NAME
#else
bvh_instance_pop(kg, object, ray, &P, &idir, &isect->t, tmax);
#endif
+
+#if defined(__KERNEL_SSE2__) && !FEATURE(BVH_HAIR_MINIMUM_WIDTH)
+ Psplat[0] = _mm_set_ps1(P.x);
+ Psplat[1] = _mm_set_ps1(P.y);
+ Psplat[2] = _mm_set_ps1(P.z);
+
+ idirsplat[0] = _mm_xor_ps(_mm_set_ps1(idir.x), _mm_castsi128_ps(pn));
+ idirsplat[1] = _mm_xor_ps(_mm_set_ps1(idir.y), _mm_castsi128_ps(pn));
+ idirsplat[2] = _mm_xor_ps(_mm_set_ps1(idir.z), _mm_castsi128_ps(pn));
+
+ tsplat = _mm_set_ps(-isect->t, -isect->t, 0.0f, 0.0f);
+
+ shufflex = (idir.x >= 0)? shuf_identity: shuf_swap;
+ shuffley = (idir.y >= 0)? shuf_identity: shuf_swap;
+ shufflez = (idir.z >= 0)? shuf_identity: shuf_swap;
+#endif
+
object = ~0;
nodeAddr = traversalStack[stackPtr];
--stackPtr;
diff --git a/intern/cycles/kernel/kernel_emission.h b/intern/cycles/kernel/kernel_emission.h
index c430a40d814..77dc59d2691 100644
--- a/intern/cycles/kernel/kernel_emission.h
+++ b/intern/cycles/kernel/kernel_emission.h
@@ -168,9 +168,9 @@ __device_noinline float3 indirect_primitive_emission(KernelGlobals *kg, ShaderDa
float3 L = shader_emissive_eval(kg, sd);
#ifdef __HAIR__
- if(!(path_flag & PATH_RAY_MIS_SKIP) && (sd->flag & SD_SAMPLE_AS_LIGHT) && (sd->segment == ~0)) {
+ if(!(path_flag & PATH_RAY_MIS_SKIP) && (sd->flag & SD_USE_MIS) && (sd->segment == ~0)) {
#else
- if(!(path_flag & PATH_RAY_MIS_SKIP) && (sd->flag & SD_SAMPLE_AS_LIGHT)) {
+ if(!(path_flag & PATH_RAY_MIS_SKIP) && (sd->flag & SD_USE_MIS)) {
#endif
/* multiple importance sampling, get triangle light pdf,
* and compute weight with respect to BSDF pdf */
diff --git a/intern/cycles/kernel/kernel_jitter.h b/intern/cycles/kernel/kernel_jitter.h
index 15d2151228f..3e1a18ab469 100644
--- a/intern/cycles/kernel/kernel_jitter.h
+++ b/intern/cycles/kernel/kernel_jitter.h
@@ -37,7 +37,7 @@ __device_inline int cmj_fast_mod_pow2(int a, int b)
/* a must be > 0 and b must be > 1 */
__device_inline int cmj_fast_div_pow2(int a, int b)
{
-#ifdef __KERNEL_SSE2__
+#if defined(__KERNEL_SSE2__) && !defined(_MSC_VER)
return a >> __builtin_ctz(b);
#else
return a/b;
@@ -46,7 +46,7 @@ __device_inline int cmj_fast_div_pow2(int a, int b)
__device_inline uint cmj_w_mask(uint w)
{
-#ifdef __KERNEL_SSE2__
+#if defined(__KERNEL_SSE2__) && !defined(_MSC_VER)
return ((1 << (32 - __builtin_clz(w))) - 1);
#else
w |= w >> 1;
@@ -137,7 +137,7 @@ __device_inline float cmj_randfloat(uint i, uint p)
}
#ifdef __CMJ__
-__device_noinline float cmj_sample_1D(int s, int N, int p)
+__device float cmj_sample_1D(int s, int N, int p)
{
uint x = cmj_permute(s, N, p * 0x68bc21eb);
float jx = cmj_randfloat(s, p * 0x967a889b);
@@ -146,7 +146,7 @@ __device_noinline float cmj_sample_1D(int s, int N, int p)
return (x + jx)*invN;
}
-__device_noinline void cmj_sample_2D(int s, int N, int p, float *fx, float *fy)
+__device void cmj_sample_2D(int s, int N, int p, float *fx, float *fy)
{
int m = float_to_int(sqrtf(N));
int n = (N + m - 1)/m;
diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h
index f0ac8e7bbc9..ca4d878daa0 100644
--- a/intern/cycles/kernel/kernel_shader.h
+++ b/intern/cycles/kernel/kernel_shader.h
@@ -38,7 +38,12 @@ CCL_NAMESPACE_BEGIN
/* ShaderData setup from incoming ray */
#ifdef __OBJECT_MOTION__
-__device_noinline void shader_setup_object_transforms(KernelGlobals *kg, ShaderData *sd, float time)
+#if defined(__KERNEL_CUDA_VERSION__) && __KERNEL_CUDA_VERSION__ <= 42
+__device_noinline
+#else
+__device
+#endif
+void shader_setup_object_transforms(KernelGlobals *kg, ShaderData *sd, float time)
{
/* note that this is a separate non-inlined function to work around crash
* on CUDA sm 2.0, otherwise kernel execution crashes (compiler bug?) */
@@ -53,7 +58,12 @@ __device_noinline void shader_setup_object_transforms(KernelGlobals *kg, ShaderD
}
#endif
-__device_noinline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
+#if defined(__KERNEL_CUDA_VERSION__) && __KERNEL_CUDA_VERSION__ <= 42
+__device_noinline
+#else
+__device
+#endif
+void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
const Intersection *isect, const Ray *ray)
{
#ifdef __INSTANCING__
@@ -260,7 +270,12 @@ __device_inline void shader_setup_from_subsurface(KernelGlobals *kg, ShaderData
/* ShaderData setup from position sampled on mesh */
-__device_noinline void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
+#if defined(__KERNEL_CUDA_VERSION__) && __KERNEL_CUDA_VERSION__ <= 42
+__device_noinline
+#else
+__device
+#endif
+void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
const float3 P, const float3 Ng, const float3 I,
int shader, int object, int prim, float u, float v, float t, float time, int segment)
{
@@ -891,7 +906,7 @@ __device bool shader_transparent_shadow(KernelGlobals *kg, Intersection *isect)
#endif
int flag = kernel_tex_fetch(__shader_flag, (shader & SHADER_MASK)*2);
- return (flag & SD_HAS_SURFACE_TRANSPARENT) != 0;
+ return (flag & SD_HAS_TRANSPARENT_SHADOW) != 0;
}
#endif
diff --git a/intern/cycles/kernel/kernel_sse3.cpp b/intern/cycles/kernel/kernel_sse3.cpp
index 6982570c59b..ff6bb412d5b 100644
--- a/intern/cycles/kernel/kernel_sse3.cpp
+++ b/intern/cycles/kernel/kernel_sse3.cpp
@@ -16,12 +16,15 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-/* Optimized CPU kernel entry points. This file is compiled with SSE3
+/* Optimized CPU kernel entry points. This file is compiled with SSE3/SSSE3
* optimization flags and nearly all functions inlined, while kernel.cpp
* is compiled without for other CPU's. */
#ifdef WITH_OPTIMIZED_KERNEL
+#define __KERNEL_SSE3__
+#define __KERNEL_SSSE3__
+
#include "kernel.h"
#include "kernel_compat_cpu.h"
#include "kernel_math.h"
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index 70a3e82896b..c6b1e29ba26 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -499,8 +499,8 @@ enum ShaderDataFlag {
SD_CLOSURE_FLAGS = (SD_EMISSION|SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY|SD_BSSRDF|SD_HOLDOUT|SD_VOLUME|SD_AO),
/* shader flags */
- SD_SAMPLE_AS_LIGHT = 512, /* direct light sample */
- SD_HAS_SURFACE_TRANSPARENT = 1024, /* has surface transparency */
+ SD_USE_MIS = 512, /* direct light sample */
+ SD_HAS_TRANSPARENT_SHADOW = 1024, /* has transparent shadow */
SD_HAS_VOLUME = 2048, /* has volume shader */
SD_HOMOGENEOUS_VOLUME = 4096, /* has homogeneous volume */
diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp
index 1d48ae8f87d..2f92b957929 100644
--- a/intern/cycles/render/light.cpp
+++ b/intern/cycles/render/light.cpp
@@ -164,7 +164,7 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
foreach(uint sindex, mesh->used_shaders) {
Shader *shader = scene->shaders[sindex];
- if(shader->sample_as_light && shader->has_surface_emission) {
+ if(shader->use_mis && shader->has_surface_emission) {
have_emission = true;
break;
}
@@ -175,7 +175,7 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
for(size_t i = 0; i < mesh->triangles.size(); i++) {
Shader *shader = scene->shaders[mesh->shader[i]];
- if(shader->sample_as_light && shader->has_surface_emission)
+ if(shader->use_mis && shader->has_surface_emission)
num_triangles++;
}
@@ -184,7 +184,7 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
foreach(Mesh::Curve& curve, mesh->curves) {
Shader *shader = scene->shaders[curve.shader];
- if(shader->sample_as_light && shader->has_surface_emission)
+ if(shader->use_mis && shader->has_surface_emission)
num_curve_segments += curve.num_segments();
#endif
}
@@ -215,7 +215,7 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
foreach(uint sindex, mesh->used_shaders) {
Shader *shader = scene->shaders[sindex];
- if(shader->sample_as_light && shader->has_surface_emission) {
+ if(shader->use_mis && shader->has_surface_emission) {
have_emission = true;
break;
}
@@ -247,7 +247,7 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
for(size_t i = 0; i < mesh->triangles.size(); i++) {
Shader *shader = scene->shaders[mesh->shader[i]];
- if(shader->sample_as_light && shader->has_surface_emission) {
+ if(shader->use_mis && shader->has_surface_emission) {
distribution[offset].x = totarea;
distribution[offset].y = __int_as_float(i + mesh->tri_offset);
distribution[offset].z = __int_as_float(shader_id);
@@ -277,7 +277,7 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
Shader *shader = scene->shaders[curve.shader];
int first_key = curve.first_key;
- if(shader->sample_as_light && shader->has_surface_emission) {
+ if(shader->use_mis && shader->has_surface_emission) {
for(int j = 0; j < curve.num_segments(); j++) {
distribution[offset].x = totarea;
distribution[offset].y = __int_as_float(i + mesh->curve_offset); // XXX fix kernel code
diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp
index 1a2780995e3..7931a51b99d 100644
--- a/intern/cycles/render/object.cpp
+++ b/intern/cycles/render/object.cpp
@@ -127,7 +127,7 @@ void Object::tag_update(Scene *scene)
foreach(uint sindex, mesh->used_shaders) {
Shader *shader = scene->shaders[sindex];
- if(shader->sample_as_light && shader->has_surface_emission)
+ if(shader->use_mis && shader->has_surface_emission)
scene->light_manager->need_update = true;
}
}
diff --git a/intern/cycles/render/osl.cpp b/intern/cycles/render/osl.cpp
index 8efc6b553e0..52e4c697ba8 100644
--- a/intern/cycles/render/osl.cpp
+++ b/intern/cycles/render/osl.cpp
@@ -100,7 +100,7 @@ void OSLShaderManager::device_update(Device *device, DeviceScene *dscene, Scene
compiler.background = (shader == scene->shaders[scene->default_background]);
compiler.compile(og, shader);
- if(shader->sample_as_light && shader->has_surface_emission)
+ if(shader->use_mis && shader->has_surface_emission)
scene->light_manager->need_update = true;
}
diff --git a/intern/cycles/render/shader.cpp b/intern/cycles/render/shader.cpp
index 46c174b773d..76b5b2baaa6 100644
--- a/intern/cycles/render/shader.cpp
+++ b/intern/cycles/render/shader.cpp
@@ -43,7 +43,8 @@ Shader::Shader()
graph = NULL;
graph_bump = NULL;
- sample_as_light = true;
+ use_mis = true;
+ use_transparent_shadow = true;
homogeneous_volume = false;
has_surface = false;
@@ -90,7 +91,7 @@ void Shader::tag_update(Scene *scene)
/* if the shader previously was emissive, update light distribution,
* if the new shader is emissive, a light manager update tag will be
* done in the shader manager device update. */
- if(sample_as_light && has_surface_emission)
+ if(use_mis && has_surface_emission)
scene->light_manager->need_update = true;
/* get requested attributes. this could be optimized by pruning unused
@@ -224,10 +225,10 @@ void ShaderManager::device_update_common(Device *device, DeviceScene *dscene, Sc
foreach(Shader *shader, scene->shaders) {
uint flag = 0;
- if(shader->sample_as_light)
- flag |= SD_SAMPLE_AS_LIGHT;
- if(shader->has_surface_transparent)
- flag |= SD_HAS_SURFACE_TRANSPARENT;
+ if(shader->use_mis)
+ flag |= SD_USE_MIS;
+ if(shader->has_surface_transparent && shader->use_transparent_shadow)
+ flag |= SD_HAS_TRANSPARENT_SHADOW;
if(shader->has_volume)
flag |= SD_HAS_VOLUME;
if(shader->homogeneous_volume)
diff --git a/intern/cycles/render/shader.h b/intern/cycles/render/shader.h
index 0b7b4b3ab42..d7eac603fa6 100644
--- a/intern/cycles/render/shader.h
+++ b/intern/cycles/render/shader.h
@@ -62,7 +62,8 @@ public:
ShaderGraph *graph_bump;
/* sampling */
- bool sample_as_light;
+ bool use_mis;
+ bool use_transparent_shadow;
bool homogeneous_volume;
/* synchronization */
diff --git a/intern/cycles/render/svm.cpp b/intern/cycles/render/svm.cpp
index 8b662cbf7c1..30105af2910 100644
--- a/intern/cycles/render/svm.cpp
+++ b/intern/cycles/render/svm.cpp
@@ -74,7 +74,7 @@ void SVMShaderManager::device_update(Device *device, DeviceScene *dscene, Scene
assert(shader->graph);
- if(shader->sample_as_light && shader->has_surface_emission)
+ if(shader->use_mis && shader->has_surface_emission)
scene->light_manager->need_update = true;
SVMCompiler compiler(scene->shader_manager, scene->image_manager,
diff --git a/intern/cycles/util/util_cuda.cpp b/intern/cycles/util/util_cuda.cpp
index 6c9ee7c548f..42ffb04a793 100644
--- a/intern/cycles/util/util_cuda.cpp
+++ b/intern/cycles/util/util_cuda.cpp
@@ -16,6 +16,8 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+#include <iostream>
+
#include <stdlib.h>
#include <stdio.h>
@@ -25,6 +27,11 @@
#include "util_path.h"
#include "util_string.h"
+#ifdef _WIN32
+#define popen _popen
+#define pclose _pclose
+#endif
+
/* function defininitions */
tcuInit *cuInit;
@@ -399,7 +406,15 @@ string cuCompilerPath()
const char *defaultpaths[] = {"C:/CUDA/bin", NULL};
const char *executable = "nvcc.exe";
#else
- const char *defaultpaths[] = {"/Developer/NVIDIA/CUDA-4.2/bin", "/usr/local/cuda-4.2/bin", "/usr/local/cuda/bin", NULL};
+ const char *defaultpaths[] = {
+ "/Developer/NVIDIA/CUDA-5.0/bin",
+ "/usr/local/cuda-5.0/bin",
+ "/usr/local/cuda/bin",
+ "/Developer/NVIDIA/CUDA-4.2/bin",
+ "/usr/local/cuda-4.2/bin",
+ "/Developer/NVIDIA/CUDA-5.5/bin",
+ "/usr/local/cuda-5.5/bin",
+ NULL};
const char *executable = "nvcc";
#endif
@@ -437,5 +452,46 @@ string cuCompilerPath()
return "";
}
+int cuCompilerVersion()
+{
+ string path = cuCompilerPath();
+ if(path == "")
+ return 0;
+
+ /* get --version output */
+ FILE *pipe = popen((path + " --version").c_str(), "r");
+ if(!pipe) {
+ fprintf(stderr, "CUDA: failed to run compiler to retrieve version");
+ return 0;
+ }
+
+ char buf[128];
+ string output = "";
+
+ while(!feof(pipe))
+ if(fgets(buf, 128, pipe) != NULL)
+ output += buf;
+
+ pclose(pipe);
+
+ /* parse version number */
+ string marker = "Cuda compilation tools, release ";
+ size_t offset = output.find(marker);
+ if(offset == string::npos) {
+ fprintf(stderr, "CUDA: failed to find version number in:\n\n%s\n", output.c_str());
+ return 0;
+ }
+
+ string versionstr = output.substr(offset + marker.size(), string::npos);
+ int major, minor;
+
+ if(sscanf(versionstr.c_str(), "%d.%d", &major, &minor) < 2) {
+ fprintf(stderr, "CUDA: failed to parse version number from:\n\n%s\n", output.c_str());
+ return 0;
+ }
+
+ return 10*major + minor;
+}
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/util/util_cuda.h b/intern/cycles/util/util_cuda.h
index 55feb3f84cb..ba4df0de90a 100644
--- a/intern/cycles/util/util_cuda.h
+++ b/intern/cycles/util/util_cuda.h
@@ -32,6 +32,7 @@ CCL_NAMESPACE_BEGIN
bool cuLibraryInit();
bool cuHavePrecompiledKernels();
string cuCompilerPath();
+int cuCompilerVersion();
CCL_NAMESPACE_END
diff --git a/intern/cycles/util/util_math.h b/intern/cycles/util/util_math.h
index 68668d88d44..05ed8a2d3f6 100644
--- a/intern/cycles/util/util_math.h
+++ b/intern/cycles/util/util_math.h
@@ -165,7 +165,7 @@ __device_inline float clamp(float a, float mn, float mx)
__device_inline int float_to_int(float f)
{
-#ifdef __KERNEL_SSE2__
+#if defined(__KERNEL_SSE2__) && !defined(_MSC_VER)
return _mm_cvtt_ss2si(_mm_load_ss(&f));
#else
return (int)f;
diff --git a/intern/cycles/util/util_system.cpp b/intern/cycles/util/util_system.cpp
index c3ecc303a34..7ba749f4287 100644
--- a/intern/cycles/util/util_system.cpp
+++ b/intern/cycles/util/util_system.cpp
@@ -194,7 +194,7 @@ bool system_cpu_support_sse2()
bool system_cpu_support_sse3()
{
CPUCapabilities& caps = system_cpu_capabilities();
- return caps.sse && caps.sse2 && caps.sse3;
+ return caps.sse && caps.sse2 && caps.sse3 && caps.ssse3;
}
#else
diff --git a/intern/cycles/util/util_types.h b/intern/cycles/util/util_types.h
index 472a707d8fd..4fd1e9d8807 100644
--- a/intern/cycles/util/util_types.h
+++ b/intern/cycles/util/util_types.h
@@ -69,16 +69,28 @@
#include <xmmintrin.h> /* SSE 1 */
#include <emmintrin.h> /* SSE 2 */
#include <pmmintrin.h> /* SSE 3 */
-#include <tmmintrin.h> /* SSE 3 */
+#include <tmmintrin.h> /* SSSE 3 */
#include <smmintrin.h> /* SSE 4 */
+#ifndef __KERNEL_SSE2__
#define __KERNEL_SSE2__
+#endif
+
+#ifndef __KERNEL_SSE3__
#define __KERNEL_SSE3__
+#endif
+
+#ifndef __KERNEL_SSSE3__
+#define __KERNEL_SSSE3__
+#endif
+
+#ifndef __KERNEL_SSE4__
#define __KERNEL_SSE4__
+#endif
#else
-#ifdef __x86_64__
+#if defined(__x86_64__) || defined(__KERNEL_SSSE3__)
/* MinGW64 has conflicting declarations for these SSE headers in <windows.h>.
* Since we can't avoid including <windows.h>, better only include that */
@@ -87,18 +99,26 @@
#else
#include <xmmintrin.h> /* SSE 1 */
#include <emmintrin.h> /* SSE 2 */
+
+#ifdef __KERNEL_SSE3__
+#include <pmmintrin.h> /* SSE 3 */
+#endif
+#ifdef __KERNEL_SSSE3__
+#include <tmmintrin.h> /* SSSE 3 */
+#endif
#endif
+#ifndef __KERNEL_SSE2__
#define __KERNEL_SSE2__
+#endif
#endif
#endif
+/* int8_t, uint16_t, and friends */
#ifndef _WIN32
-
#include <stdint.h>
-
#endif
#endif
@@ -471,6 +491,67 @@ __device_inline int4 make_int4(const float3& f)
#endif
+#ifdef __KERNEL_SSE2__
+
+/* SSE shuffle utility functions */
+
+#ifdef __KERNEL_SSSE3__
+
+/* faster version for SSSE3 */
+typedef __m128i shuffle_swap_t;
+
+__device_inline const shuffle_swap_t shuffle_swap_identity(void)
+{
+ return _mm_set_epi8(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+}
+
+__device_inline const shuffle_swap_t shuffle_swap_swap(void)
+{
+ return _mm_set_epi8(7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8);
+}
+
+__device_inline const __m128 shuffle_swap(const __m128& a, const shuffle_swap_t& shuf)
+{
+ return _mm_castsi128_ps(_mm_shuffle_epi8(_mm_castps_si128(a), shuf));
+}
+
+#else
+
+/* somewhat slower version for SSE3 */
+typedef int shuffle_swap_t;
+
+__device_inline const shuffle_swap_t shuffle_swap_identity(void)
+{
+ return 0;
+}
+
+__device_inline const shuffle_swap_t shuffle_swap_swap(void)
+{
+ return 1;
+}
+
+__device_inline const __m128 shuffle_swap(const __m128& a, shuffle_swap_t shuf)
+{
+ /* shuffle value must be a constant, so we need to branch */
+ if(shuf)
+ return _mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 0, 3, 2));
+ else
+ return _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 2, 1, 0));
+}
+
+#endif
+
+template<size_t i0, size_t i1, size_t i2, size_t i3> __device_inline const __m128 shuffle(const __m128& a, const __m128& b)
+{
+ return _mm_shuffle_ps(a, b, _MM_SHUFFLE(i3, i2, i1, i0));
+}
+
+template<size_t i0, size_t i1, size_t i2, size_t i3> __device_inline const __m128 shuffle(const __m128& b)
+{
+ return _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(b), _MM_SHUFFLE(i3, i2, i1, i0)));
+}
+#endif
+
CCL_NAMESPACE_END
#endif /* __UTIL_TYPES_H__ */
diff --git a/release/scripts/modules/addon_utils.py b/release/scripts/modules/addon_utils.py
index 7e7612e56d8..a197c20fdab 100644
--- a/release/scripts/modules/addon_utils.py
+++ b/release/scripts/modules/addon_utils.py
@@ -239,7 +239,7 @@ def _addon_remove(module_name):
addons.remove(addon)
-def enable(module_name, default_set=True, persistent=False):
+def enable(module_name, default_set=True, persistent=False, handle_error=None):
"""
Enables an addon by name.
@@ -253,9 +253,10 @@ def enable(module_name, default_set=True, persistent=False):
import sys
from bpy_restrict_state import RestrictBlend
- def handle_error():
- import traceback
- traceback.print_exc()
+ if handle_error is None:
+ def handle_error():
+ import traceback
+ traceback.print_exc()
# reload if the mtime changes
mod = sys.modules.get(module_name)
@@ -322,7 +323,7 @@ def enable(module_name, default_set=True, persistent=False):
return mod
-def disable(module_name, default_set=True):
+def disable(module_name, default_set=True, handle_error=None):
"""
Disables an addon by name.
@@ -330,6 +331,12 @@ def disable(module_name, default_set=True):
:type module_name: string
"""
import sys
+
+ if handle_error is None:
+ def handle_error():
+ import traceback
+ traceback.print_exc()
+
mod = sys.modules.get(module_name)
# possible this addon is from a previous session and didn't load a
@@ -344,8 +351,7 @@ def disable(module_name, default_set=True):
except:
print("Exception in module unregister(): %r" %
getattr(mod, "__file__", module_name))
- import traceback
- traceback.print_exc()
+ handle_error()
else:
print("addon_utils.disable: %s not %s." %
(module_name, "disabled" if mod is None else "loaded"))
diff --git a/release/scripts/modules/bl_i18n_utils/settings.py b/release/scripts/modules/bl_i18n_utils/settings.py
index 4ca4c18cc7b..001f044f1c4 100644
--- a/release/scripts/modules/bl_i18n_utils/settings.py
+++ b/release/scripts/modules/bl_i18n_utils/settings.py
@@ -101,7 +101,7 @@ IMPORT_MIN_LEVEL = 0.0
# Languages in /branches we do not want to import in /trunk currently...
IMPORT_LANGUAGES_SKIP = {
- 'am_ET', 'bg_BG', 'fi_FI', 'el_GR', 'et_EE', 'ne_NP', 'nl_NL', 'pl_PL', 'ro_RO', 'uz_UZ', 'uz_UZ@cyrillic',
+ 'am_ET', 'bg_BG', 'fi_FI', 'el_GR', 'et_EE', 'ne_NP', 'pl_PL', 'ro_RO', 'uz_UZ', 'uz_UZ@cyrillic',
}
# Languages that need RTL pre-processing.
diff --git a/release/scripts/modules/bl_i18n_utils/utils_spell_check.py b/release/scripts/modules/bl_i18n_utils/utils_spell_check.py
index 99f311bad11..8c237840d96 100644
--- a/release/scripts/modules/bl_i18n_utils/utils_spell_check.py
+++ b/release/scripts/modules/bl_i18n_utils/utils_spell_check.py
@@ -58,6 +58,7 @@ class SpellChecker():
"arcsine", "arccosine", "arctangent",
"autoclip",
"autocomplete",
+ "autoexec",
"autoname",
"autosave",
"autoscale",
@@ -437,6 +438,7 @@ class SpellChecker():
"oren",
"prewitt",
"runge",
+ "sobol",
"verlet",
"worley",
diff --git a/release/scripts/modules/bpy_extras/object_utils.py b/release/scripts/modules/bpy_extras/object_utils.py
index 7412d34940f..7d8caf449ca 100644
--- a/release/scripts/modules/bpy_extras/object_utils.py
+++ b/release/scripts/modules/bpy_extras/object_utils.py
@@ -25,7 +25,7 @@ __all__ = (
"object_add_grid_scale",
"object_add_grid_scale_apply_operator",
"object_image_guess",
- "world_to_camera",
+ "world_to_camera_view",
)
@@ -268,12 +268,14 @@ def object_image_guess(obj, bm=None):
return None
-def world_to_camera(scene, obj, coord):
+def world_to_camera_view(scene, obj, coord):
"""
- Returns the 2d camera space coords for a 3d point.
+ Returns the camera space coords for a 3d point.
+ (also known as: normalized device coordinates - NDC).
Where (0, 0) is the bottom left and (1, 1) is the top right of the camera frame.
values outside 0-1 are also supported.
+ A negative 'z' value means the point is behind the camera.
Takes shift-x/y, lens angle and sensor size into account
as well as perspective/ortho projections.
@@ -284,7 +286,7 @@ def world_to_camera(scene, obj, coord):
:type obj: :class:`bpy.types.Object`
:arg coord: World space location.
:type coord: :class:`mathutils.Vector`
- :return: normalized 2d vector.
+ :return: a vector where X and Y map to the view plane and Z is the depth on the view axis.
:rtype: :class:`mathutils.Vector`
"""
from mathutils import Vector
diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py
index fd1f538efd3..fba7672e846 100644
--- a/release/scripts/startup/bl_operators/wm.py
+++ b/release/scripts/startup/bl_operators/wm.py
@@ -1574,8 +1574,15 @@ class WM_OT_addon_enable(Operator):
def execute(self, context):
import addon_utils
+
+ err_str = ""
+ def err_cb():
+ import traceback
+ nonlocal err_str
+ err_str = traceback.format_exc()
+ print(err_str)
- mod = addon_utils.enable(self.module)
+ mod = addon_utils.enable(self.module, handle_error=err_cb)
if mod:
info = addon_utils.module_bl_info(mod)
@@ -1590,6 +1597,10 @@ class WM_OT_addon_enable(Operator):
info_ver)
return {'FINISHED'}
else:
+
+ if err_str:
+ self.report({'ERROR'}, err_str)
+
return {'CANCELLED'}
@@ -1606,7 +1617,18 @@ class WM_OT_addon_disable(Operator):
def execute(self, context):
import addon_utils
- addon_utils.disable(self.module)
+ err_str = ""
+ def err_cb():
+ import traceback
+ nonlocal err_str
+ err_str = traceback.format_exc()
+ print(err_str)
+
+ addon_utils.disable(self.module, handle_error=err_cb)
+
+ if err_str:
+ self.report({'ERROR'}, err_str)
+
return {'FINISHED'}
diff --git a/release/scripts/startup/bl_ui/__init__.py b/release/scripts/startup/bl_ui/__init__.py
index 868fa2a311c..594f724c6e3 100644
--- a/release/scripts/startup/bl_ui/__init__.py
+++ b/release/scripts/startup/bl_ui/__init__.py
@@ -68,6 +68,7 @@ _modules = [
"space_nla",
"space_node",
"space_outliner",
+ "space_properties",
"space_sequencer",
"space_text",
"space_time",
diff --git a/release/scripts/startup/bl_ui/properties_paint_common.py b/release/scripts/startup/bl_ui/properties_paint_common.py
index 65ab1246c19..b3335f32231 100644
--- a/release/scripts/startup/bl_ui/properties_paint_common.py
+++ b/release/scripts/startup/bl_ui/properties_paint_common.py
@@ -134,8 +134,8 @@ def brush_mask_texture_settings(layout, brush):
layout.operator("brush.stencil_reset_transform").mask = True
if brush.mask_texture:
- layout.label(text="Mask Mapping:")
col = layout.column()
+ col.label(text="Angle:")
col.active = brush.brush_capabilities.has_texture_angle
col.prop(mask_tex_slot, "angle", text="")
diff --git a/release/scripts/startup/bl_ui/space_properties.py b/release/scripts/startup/bl_ui/space_properties.py
new file mode 100644
index 00000000000..758713b5cc4
--- /dev/null
+++ b/release/scripts/startup/bl_ui/space_properties.py
@@ -0,0 +1,46 @@
+# ##### 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>
+import bpy
+from bpy.types import Header
+
+
+class PROPERTIES_HT_header(Header):
+ bl_space_type = 'PROPERTIES'
+
+ def draw(self, context):
+ layout = self.layout
+
+ view = context.space_data
+
+ row = layout.row()
+ row.template_header(menus=False)
+ row.prop(view, "context", expand=True, icon_only=True)
+
+
+def register():
+ bpy.utils.register_module(__name__)
+
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+
+
+if __name__ == "__main__":
+ register()
diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py
index ef4e5468194..a497ecfb927 100644
--- a/release/scripts/startup/bl_ui/space_userpref.py
+++ b/release/scripts/startup/bl_ui/space_userpref.py
@@ -867,8 +867,21 @@ class USERPREF_PT_file(Panel):
colsplit = col.split(percentage=0.95)
sub = colsplit.column()
- sub.label(text="Author:")
- sub.prop(system, "author", text="")
+
+ row = sub.split(percentage=0.3)
+ row.label(text="Auto Execution:")
+ row.prop(system, "use_scripts_auto_execute")
+
+ if system.use_scripts_auto_execute:
+ box = sub.box()
+ row = box.row()
+ row.label(text="Excluded Paths:")
+ row.operator("wm.userpref_autoexec_path_add", text="", icon='ZOOMIN', emboss=False)
+ for i, path_cmp in enumerate(userpref.autoexec_paths):
+ row = box.row()
+ row.prop(path_cmp, "path", text="")
+ row.prop(path_cmp, "use_glob", text="", icon='FILTER')
+ row.operator("wm.userpref_autoexec_path_remove", text="", icon='X', emboss=False).index = i
col = split.column()
col.label(text="Save & Load:")
@@ -896,10 +909,12 @@ class USERPREF_PT_file(Panel):
col.separator()
- col.label(text="Scripts:")
- col.prop(system, "use_scripts_auto_execute")
+ col.label(text="Text Editor:")
col.prop(system, "use_tabs_as_spaces")
+ col.label(text="Author:")
+ col.prop(system, "author", text="")
+
from bl_ui.space_userpref_keymap import InputKeyMapPanel
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index b8cbd058063..e0449931fc9 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -966,26 +966,30 @@ class VIEW3D_MT_object_specials(Menu):
if scene.render.use_shading_nodes:
try:
value = lamp.node_tree.nodes["Emission"].inputs["Strength"].default_value
+ except AttributeError:
+ value = None
+ if value is not None:
props = layout.operator("wm.context_modal_mouse", text="Strength")
props.data_path_iter = "selected_editable_objects"
props.data_path_item = "data.node_tree.nodes[\"Emission\"].inputs[\"Strength\"].default_value"
props.header_text = "Lamp Strength: %.3f"
props.input_scale = 0.1
- except AttributeError:
- pass
+ del value
- if lamp.type == 'AREA' and lamp.shape == 'RECTANGLE':
+ if lamp.type == 'AREA':
props = layout.operator("wm.context_modal_mouse", text="Size X")
props.data_path_iter = "selected_editable_objects"
props.data_path_item = "data.size"
props.header_text = "Lamp Size X: %.3f"
- props = layout.operator("wm.context_modal_mouse", text="Size Y")
- props.data_path_iter = "selected_editable_objects"
- props.data_path_item = "data.size"
- props.header_text = "Lamp Size Y: %.3f"
- elif lamp.type in {'SPOT', 'AREA', 'POINT', 'SUN'}:
+ if lamp.shape == 'RECTANGLE':
+ props = layout.operator("wm.context_modal_mouse", text="Size Y")
+ props.data_path_iter = "selected_editable_objects"
+ props.data_path_item = "data.size_y"
+ props.header_text = "Lamp Size Y: %.3f"
+
+ elif lamp.type in {'SPOT', 'POINT', 'SUN'}:
props = layout.operator("wm.context_modal_mouse", text="Size")
props.data_path_iter = "selected_editable_objects"
props.data_path_item = "data.shadow_soft_size"
diff --git a/source/blender/blenkernel/BKE_autoexec.h b/source/blender/blenkernel/BKE_autoexec.h
new file mode 100644
index 00000000000..7dc1e76ed5c
--- /dev/null
+++ b/source/blender/blenkernel/BKE_autoexec.h
@@ -0,0 +1,31 @@
+/*
+ * ***** 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.
+ *
+ * Contributor(s): Blender Foundation 2013
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+#ifndef __BKE_AUTOEXEC_H__
+#define __BKE_AUTOEXEC_H__
+
+/** \file BKE_autoexec.h
+ * \ingroup bke
+ */
+
+bool BKE_autoexec_match(const char *path);
+
+#endif /* __BKE_AUTOEXEC_H__ */
diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h
index 6b9392a4169..3f3a5739d55 100644
--- a/source/blender/blenkernel/BKE_modifier.h
+++ b/source/blender/blenkernel/BKE_modifier.h
@@ -391,5 +391,30 @@ void modifier_mdef_compact_influences(struct ModifierData *md);
void modifier_path_init(char *path, int path_maxlen, const char *name);
const char *modifier_path_relbase(struct Object *ob);
+
+/* wrappers for modifier callbacks */
+
+struct DerivedMesh *modwrap_applyModifier(
+ ModifierData *md, struct Object *ob,
+ struct DerivedMesh *dm,
+ ModifierApplyFlag flag);
+
+struct DerivedMesh *modwrap_applyModifierEM(
+ ModifierData *md, struct Object *ob,
+ struct BMEditMesh *em,
+ struct DerivedMesh *dm,
+ ModifierApplyFlag flag);
+
+void modwrap_deformVerts(
+ ModifierData *md, struct Object *ob,
+ struct DerivedMesh *dm,
+ float (*vertexCos)[3], int numVerts,
+ ModifierApplyFlag flag);
+
+void modwrap_deformVertsEM(
+ ModifierData *md, struct Object *ob,
+ struct BMEditMesh *em, struct DerivedMesh *dm,
+ float (*vertexCos)[3], int numVerts);
+
#endif
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index 3864fe3b350..7e1355b5421 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -63,6 +63,7 @@ set(SRC
intern/anim.c
intern/anim_sys.c
intern/armature.c
+ intern/autoexec.c
intern/blender.c
intern/bmfont.c
intern/boids.c
@@ -163,6 +164,7 @@ set(SRC
BKE_anim.h
BKE_animsys.h
BKE_armature.h
+ BKE_autoexec.h
BKE_blender.h
BKE_bmesh.h
BKE_bmfont.h
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index 6a21f33ac15..96ccc5be8e0 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -845,69 +845,6 @@ DerivedMesh *mesh_create_derived(Mesh *me, Object *ob, float (*vertCos)[3])
return dm;
}
-/***/
-
-/* wrapper around ModifierTypeInfo.applyModifier that ensures valid normals */
-
-static DerivedMesh *modwrap_applyModifier(
- ModifierData *md, Object *ob,
- DerivedMesh *dm,
- ModifierApplyFlag flag)
-{
- ModifierTypeInfo *mti = modifierType_getInfo(md->type);
- BLI_assert(CustomData_has_layer(&dm->polyData, CD_NORMAL) == false);
-
- if (mti->dependsOnNormals && mti->dependsOnNormals(md)) {
- DM_ensure_normals(dm);
- }
- return mti->applyModifier(md, ob, dm, flag);
-}
-
-static DerivedMesh *modwrap_applyModifierEM(
- ModifierData *md, Object *ob,
- BMEditMesh *em,
- DerivedMesh *dm,
- ModifierApplyFlag flag)
-{
- ModifierTypeInfo *mti = modifierType_getInfo(md->type);
- BLI_assert(CustomData_has_layer(&dm->polyData, CD_NORMAL) == false);
-
- if (mti->dependsOnNormals && mti->dependsOnNormals(md)) {
- DM_ensure_normals(dm);
- }
- return mti->applyModifierEM(md, ob, em, dm, flag);
-}
-
-static void modwrap_deformVerts(
- ModifierData *md, Object *ob,
- DerivedMesh *dm,
- float (*vertexCos)[3], int numVerts,
- ModifierApplyFlag flag)
-{
- ModifierTypeInfo *mti = modifierType_getInfo(md->type);
- BLI_assert(!dm || CustomData_has_layer(&dm->polyData, CD_NORMAL) == false);
-
- if (dm && mti->dependsOnNormals && mti->dependsOnNormals(md)) {
- DM_ensure_normals(dm);
- }
- mti->deformVerts(md, ob, dm, vertexCos, numVerts, flag);
-}
-
-static void modwrap_deformVertsEM(
- ModifierData *md, Object *ob,
- BMEditMesh *em, DerivedMesh *dm,
- float (*vertexCos)[3], int numVerts)
-{
- ModifierTypeInfo *mti = modifierType_getInfo(md->type);
- BLI_assert(!dm || CustomData_has_layer(&dm->polyData, CD_NORMAL) == false);
-
- if (dm && mti->dependsOnNormals && mti->dependsOnNormals(md)) {
- DM_ensure_normals(dm);
- }
- mti->deformVertsEM(md, ob, em, dm, vertexCos, numVerts);
-}
-/* end modifier callback wrappers */
-
DerivedMesh *mesh_create_derived_for_modifier(Scene *scene, Object *ob,
ModifierData *md, int build_shapekey_layers)
{
@@ -2148,7 +2085,7 @@ static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, D
if (mti->applyModifierEM)
ndm = modwrap_applyModifierEM(md, ob, em, dm, MOD_APPLY_USECACHE);
else
- ndm = mti->applyModifier(md, ob, dm, MOD_APPLY_USECACHE);
+ ndm = modwrap_applyModifier(md, ob, dm, MOD_APPLY_USECACHE);
if (ndm) {
if (dm && dm != ndm)
diff --git a/source/blender/blenkernel/intern/autoexec.c b/source/blender/blenkernel/intern/autoexec.c
new file mode 100644
index 00000000000..c27343bf80a
--- /dev/null
+++ b/source/blender/blenkernel/intern/autoexec.c
@@ -0,0 +1,70 @@
+/*
+ * ***** 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.
+ *
+ * Contributor(s): Blender Foundation 2013
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/blenkernel/intern/armature.c
+ * \ingroup bke
+ *
+ * Currently just checks if a blend file can be trusted to autoexec,
+ * may add signing here later.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "DNA_userdef_types.h"
+
+#include "BLI_utildefines.h"
+#include "BLI_fnmatch.h"
+#include "BLI_string.h"
+#include "BLI_path_util.h"
+
+#include "BKE_autoexec.h" /* own include */
+
+/**
+ * \param path The path to check against.
+ * \return Success
+ */
+bool BKE_autoexec_match(const char *path)
+{
+ bPathCompare *path_cmp;
+
+#ifdef WIN32
+ const int fnmatch_flags = FNM_CASEFOLD;
+#else
+ const int fnmatch_flags = 0;
+#endif
+
+ BLI_assert((U.flag & USER_SCRIPT_AUTOEXEC_DISABLE) == 0);
+
+ for (path_cmp = U.autoexec_paths.first; path_cmp; path_cmp = path_cmp->next) {
+ if ((path_cmp->flag & USER_PATHCMP_GLOB)) {
+ if (fnmatch(path_cmp->path, path, fnmatch_flags) == 0) {
+ return true;
+ }
+ }
+ else if (BLI_path_ncmp(path_cmp->path, path, strlen(path_cmp->path)) == 0) {
+ return true;
+ }
+ }
+
+ return false;
+}
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index 87a8def52bf..1e7aba6d25b 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -416,6 +416,8 @@ void BKE_userdef_free(void)
MEM_freeN(addon);
}
+ BLI_freelistN(&U.autoexec_paths);
+
BLI_freelistN(&U.uistyles);
BLI_freelistN(&U.uifonts);
BLI_freelistN(&U.themes);
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c
index f3de4001dea..e1ecf00104a 100644
--- a/source/blender/blenkernel/intern/displist.c
+++ b/source/blender/blenkernel/intern/displist.c
@@ -976,7 +976,6 @@ static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *dispba
dm = tdm;
CDDM_apply_vert_coords(dm, vertCos);
- CDDM_calc_normals_mapping(dm);
}
}
else {
@@ -989,8 +988,6 @@ static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *dispba
}
dm = CDDM_from_curve_displist(ob, dispbase);
-
- CDDM_calc_normals_mapping(dm);
}
if (vertCos) {
@@ -1001,7 +998,8 @@ static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *dispba
if (useCache)
appf |= MOD_APPLY_USECACHE;
- ndm = mti->applyModifier(md, ob, dm, appf);
+
+ ndm = modwrap_applyModifier(md, ob, dm, appf);
if (ndm) {
/* Modifier returned a new derived mesh */
@@ -1031,8 +1029,19 @@ static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *dispba
}
if (derivedFinal) {
- if (dm)
- DM_ensure_tessface(dm); /* needed for drawing */
+ if (dm) {
+ /* see: mesh_calc_modifiers */
+ if (dm->getNumTessFaces(dm) == 0) {
+ dm->recalcTessellation(dm);
+ }
+ /* Even if tessellation is not needed, some modifiers might have modified CD layers
+ * (like mloopcol or mloopuv), hence we have to update those. */
+ else if (dm->dirty & DM_DIRTY_TESS_CDLAYERS) {
+ DM_update_tessface_data(dm);
+ }
+
+ CDDM_calc_normals_mapping_ex(dm, (dm->dirty & DM_DIRTY_NORMALS) ? false : true);
+ }
(*derivedFinal) = dm;
}
@@ -1169,7 +1178,7 @@ static void curve_calc_orcodm(Scene *scene, Object *ob, DerivedMesh *derivedFina
if (!orcodm)
orcodm = create_orco_dm(scene, ob);
- ndm = mti->applyModifier(md, ob, orcodm, app_flag);
+ ndm = modwrap_applyModifier(md, ob, orcodm, app_flag);
if (ndm) {
/* if the modifier returned a new dm, release the old one */
diff --git a/source/blender/blenkernel/intern/editmesh_bvh.c b/source/blender/blenkernel/intern/editmesh_bvh.c
index 979a38f0346..160972889fd 100644
--- a/source/blender/blenkernel/intern/editmesh_bvh.c
+++ b/source/blender/blenkernel/intern/editmesh_bvh.c
@@ -382,7 +382,7 @@ static void bmbvh_find_vert_closest_cb(void *userdata, int index, const float *U
bmbvh_tri_from_face(tri_cos, ltri, bmcb_data->cos_cage);
for (i = 0; i < 3; i++) {
- dist = len_v3v3(hit->co, tri_cos[i]);
+ dist = len_squared_v3v3(hit->co, tri_cos[i]);
if (dist < hit->dist && dist < maxdist) {
copy_v3_v3(hit->co, tri_cos[i]);
/* XXX, normal ignores cage */
@@ -398,17 +398,17 @@ BMVert *BKE_bmbvh_find_vert_closest(BMBVHTree *bmtree, const float co[3], const
{
BVHTreeNearest hit;
struct VertSearchUserData bmcb_data;
+ const float maxdist_sq = maxdist * maxdist;
if (bmtree->cos_cage) BLI_assert(!(bmtree->em->bm->elem_index_dirty & BM_VERT));
copy_v3_v3(hit.co, co);
- /* XXX, why x5, scampbell */
- hit.dist = maxdist * 5;
+ hit.dist = maxdist_sq;
hit.index = -1;
bmcb_data.looptris = (const BMLoop *(*)[3])bmtree->em->looptris;
bmcb_data.cos_cage = (const float (*)[3])bmtree->cos_cage;
- bmcb_data.maxdist = maxdist;
+ bmcb_data.maxdist = maxdist_sq;
BLI_bvhtree_find_nearest(bmtree->tree, co, &hit, bmbvh_find_vert_closest_cb, &bmcb_data);
if (hit.dist != FLT_MAX && hit.index != -1) {
diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c
index 43819e1e80e..0546c85db67 100644
--- a/source/blender/blenkernel/intern/mball.c
+++ b/source/blender/blenkernel/intern/mball.c
@@ -112,19 +112,6 @@ typedef struct intlists { /* list of list of integers */
struct intlists *next; /* remaining elements */
} INTLISTS;
-typedef struct process { /* parameters, function, storage */
- /* what happens here? floats, I think. */
- /* float (*function)(void); */ /* implicit surface function */
- float (*function)(float, float, float);
- float size, delta; /* cube size, normal delta */
- int bounds; /* cube range within lattice */
- CUBES *cubes; /* active cubes */
- VERTICES vertices; /* surface vertices */
- CENTERLIST **centers; /* cube center hash table */
- CORNER **corners; /* corner value hash table */
- EDGELIST **edges; /* edge and vertex id hash table */
-} PROCESS;
-
/* dividing scene using octal tree makes polygonisation faster */
typedef struct ml_pointer {
struct ml_pointer *next, *prev;
@@ -153,20 +140,41 @@ struct pgn_elements {
char *data;
};
-/* Forward declarations */
-static int vertid(const CORNER *c1, const CORNER *c2, PROCESS *p, MetaBall *mb);
-static int setcenter(CENTERLIST *table[], const int i, const int j, const int k);
-static CORNER *setcorner(PROCESS *p, int i, int j, int k);
-static void converge(const float p1[3], const float p2[3], float v1, float v2,
- float (*function)(float, float, float), float p[3], MetaBall *mb, int f);
-
-/* Global variables */
-static struct {
+typedef struct process { /* parameters, function, storage */
+ /* ** old G_mb contents ** */
float thresh;
int totelem;
MetaElem **mainb;
octal_tree *metaball_tree;
-} G_mb = {0};
+
+ /* ** old process contents ** */
+
+ /* what happens here? floats, I think. */
+ /* float (*function)(void); */ /* implicit surface function */
+ float (*function)(struct process*, float, float, float);
+ float size, delta; /* cube size, normal delta */
+ int bounds; /* cube range within lattice */
+ CUBES *cubes; /* active cubes */
+ VERTICES vertices; /* surface vertices */
+ CENTERLIST **centers; /* cube center hash table */
+ CORNER **corners; /* corner value hash table */
+ EDGELIST **edges; /* edge and vertex id hash table */
+
+ /* Runtime things */
+ int *indices;
+ int totindex, curindex;
+
+ int pgn_offset;
+ struct pgn_elements *pgn_current;
+ ListBase pgn_list;
+} PROCESS;
+
+/* Forward declarations */
+static int vertid(PROCESS *process, const CORNER *c1, const CORNER *c2, MetaBall *mb);
+static int setcenter(PROCESS *process, CENTERLIST *table[], const int i, const int j, const int k);
+static CORNER *setcorner(PROCESS *process, int i, int j, int k);
+static void converge(PROCESS *process, const float p1[3], const float p2[3], float v1, float v2,
+ float p[3], MetaBall *mb, int f);
/* Functions */
@@ -519,43 +527,23 @@ Object *BKE_mball_basis_find(Scene *scene, Object *basis)
Scene *sce_iter = scene;
Base *base;
Object *ob, *bob = basis;
- MetaElem *ml = NULL;
int basisnr, obnr;
char basisname[MAX_ID_NAME], obname[MAX_ID_NAME];
BLI_split_name_num(basisname, &basisnr, basis->id.name + 2, '.');
- G_mb.totelem = 0;
/* XXX recursion check, see scene.c, just too simple code this BKE_scene_base_iter_next() */
if (F_ERROR == BKE_scene_base_iter_next(&sce_iter, 0, NULL, NULL))
return NULL;
-
+
while (BKE_scene_base_iter_next(&sce_iter, 1, &base, &ob)) {
-
if (ob->type == OB_MBALL) {
- if (ob == bob) {
- MetaBall *mb = ob->data;
-
- /* if bob object is in edit mode, then dynamic list of all MetaElems
- * is stored in editelems */
- if (mb->editelems) ml = mb->editelems->first;
- /* if bob object is in object mode */
- else ml = mb->elems.first;
- }
- else {
+ if (ob != bob) {
BLI_split_name_num(obname, &obnr, ob->id.name + 2, '.');
/* object ob has to be in same "group" ... it means, that it has to have
* same base of its name */
if (strcmp(obname, basisname) == 0) {
- MetaBall *mb = ob->data;
-
- /* if object is in edit mode, then dynamic list of all MetaElems
- * is stored in editelems */
- if (mb->editelems) ml = mb->editelems->first;
- /* if bob object is in object mode */
- else ml = mb->elems.first;
-
if (obnr < basisnr) {
if (!(ob->flag & OB_FROMDUPLI)) {
basis = ob;
@@ -564,12 +552,6 @@ Object *BKE_mball_basis_find(Scene *scene, Object *basis)
}
}
}
-
- for ( ; ml; ml = ml->next) {
- if (!(ml->flag & MB_HIDE)) {
- G_mb.totelem++;
- }
- }
}
}
@@ -768,60 +750,57 @@ static octal_node *find_metaball_octal_node(octal_node *node, float x, float y,
return node;
}
-static float metaball(float x, float y, float z)
+static float metaball(PROCESS *process, float x, float y, float z)
/* float x, y, z; */
{
+ octal_tree *metaball_tree = process->metaball_tree;
struct octal_node *node;
struct ml_pointer *ml_p;
float dens = 0;
int a;
- if (G_mb.totelem > 1) {
- node = find_metaball_octal_node(G_mb.metaball_tree->first, x, y, z, G_mb.metaball_tree->depth);
+ if (process->totelem > 1) {
+ node = find_metaball_octal_node(metaball_tree->first, x, y, z, metaball_tree->depth);
if (node) {
for (ml_p = node->elems.first; ml_p; ml_p = ml_p->next) {
dens += densfunc(ml_p->ml, x, y, z);
}
- dens += -0.5f * (G_mb.metaball_tree->pos - node->pos);
- dens += 0.5f * (G_mb.metaball_tree->neg - node->neg);
+ dens += -0.5f * (metaball_tree->pos - node->pos);
+ dens += 0.5f * (metaball_tree->neg - node->neg);
}
else {
- for (a = 0; a < G_mb.totelem; a++) {
- dens += densfunc(G_mb.mainb[a], x, y, z);
+ for (a = 0; a < process->totelem; a++) {
+ dens += densfunc(process->mainb[a], x, y, z);
}
}
}
else {
- dens += densfunc(G_mb.mainb[0], x, y, z);
+ dens += densfunc(process->mainb[0], x, y, z);
}
- return G_mb.thresh - dens;
+ return process->thresh - dens;
}
/* ******************************************** */
-static int *indices = NULL;
-static int totindex, curindex;
-
-
-static void accum_mballfaces(int i1, int i2, int i3, int i4)
+static void accum_mballfaces(PROCESS *process, int i1, int i2, int i3, int i4)
{
int *newi, *cur;
/* static int i = 0; I would like to delete altogether, but I don't dare to, yet */
- if (totindex == curindex) {
- totindex += 256;
- newi = MEM_mallocN(4 * sizeof(int) * totindex, "vertindex");
+ if (process->totindex == process->curindex) {
+ process->totindex += 256;
+ newi = MEM_mallocN(4 * sizeof(int) * process->totindex, "vertindex");
- if (indices) {
- memcpy(newi, indices, 4 * sizeof(int) * (totindex - 256));
- MEM_freeN(indices);
+ if (process->indices) {
+ memcpy(newi, process->indices, 4 * sizeof(int) * (process->totindex - 256));
+ MEM_freeN(process->indices);
}
- indices = newi;
+ process->indices = newi;
}
- cur = indices + 4 * curindex;
+ cur = process->indices + 4 * process->curindex;
/* displists now support array drawing, we treat tri's as fake quad */
@@ -833,63 +812,62 @@ static void accum_mballfaces(int i1, int i2, int i3, int i4)
else
cur[3] = i4;
- curindex++;
+ process->curindex++;
}
/* ******************* MEMORY MANAGEMENT *********************** */
-static void *new_pgn_element(int size)
+static void *new_pgn_element(PROCESS *process, int size)
{
/* during polygonize 1000s of elements are allocated
* and never freed in between. Freeing only done at the end.
*/
int blocksize = 16384;
- static int offs = 0; /* the current free address */
- static struct pgn_elements *cur = NULL;
- static ListBase lb = {NULL, NULL};
void *adr;
if (size > 10000 || size == 0) {
printf("incorrect use of new_pgn_element\n");
}
else if (size == -1) {
- cur = lb.first;
+ struct pgn_elements *cur = process->pgn_list.first;
while (cur) {
MEM_freeN(cur->data);
cur = cur->next;
}
- BLI_freelistN(&lb);
+ BLI_freelistN(&process->pgn_list);
return NULL;
}
size = 4 * ( (size + 3) / 4);
- if (cur) {
- if (size + offs < blocksize) {
- adr = (void *) (cur->data + offs);
- offs += size;
+ if (process->pgn_current) {
+ if (size + process->pgn_offset < blocksize) {
+ adr = (void *) (process->pgn_current->data + process->pgn_offset);
+ process->pgn_offset += size;
return adr;
}
}
- cur = MEM_callocN(sizeof(struct pgn_elements), "newpgn");
- cur->data = MEM_callocN(blocksize, "newpgn");
- BLI_addtail(&lb, cur);
+ process->pgn_current = MEM_callocN(sizeof(struct pgn_elements), "newpgn");
+ process->pgn_current->data = MEM_callocN(blocksize, "newpgn");
+ BLI_addtail(&process->pgn_list, process->pgn_current);
- offs = size;
- return cur->data;
+ process->pgn_offset = size;
+ return process->pgn_current->data;
}
-static void freepolygonize(PROCESS *p)
+static void freepolygonize(PROCESS *process)
{
- MEM_freeN(p->corners);
- MEM_freeN(p->edges);
- MEM_freeN(p->centers);
+ MEM_freeN(process->corners);
+ MEM_freeN(process->edges);
+ MEM_freeN(process->centers);
- new_pgn_element(-1);
-
- if (p->vertices.ptr) MEM_freeN(p->vertices.ptr);
+ new_pgn_element(process, -1);
+
+ if (process->vertices.ptr) {
+ MEM_freeN(process->vertices.ptr);
+ }
}
/**** Cubical Polygonization (optional) ****/
@@ -928,7 +906,7 @@ static int rightface[12] = {
/* docube: triangulate the cube directly, without decomposition */
-static void docube(CUBE *cube, PROCESS *p, MetaBall *mb)
+static void docube(PROCESS *process, CUBE *cube, MetaBall *mb)
{
INTLISTS *polys;
CORNER *c1, *c2;
@@ -945,45 +923,45 @@ static void docube(CUBE *cube, PROCESS *p, MetaBall *mb)
c1 = cube->corners[corner1[edges->i]];
c2 = cube->corners[corner2[edges->i]];
- indexar[count] = vertid(c1, c2, p, mb);
+ indexar[count] = vertid(process, c1, c2, mb);
count++;
}
if (count > 2) {
switch (count) {
case 3:
- accum_mballfaces(indexar[2], indexar[1], indexar[0], 0);
+ accum_mballfaces(process, indexar[2], indexar[1], indexar[0], 0);
break;
case 4:
- if (indexar[0] == 0) accum_mballfaces(indexar[0], indexar[3], indexar[2], indexar[1]);
- else accum_mballfaces(indexar[3], indexar[2], indexar[1], indexar[0]);
+ if (indexar[0] == 0) accum_mballfaces(process, indexar[0], indexar[3], indexar[2], indexar[1]);
+ else accum_mballfaces(process, indexar[3], indexar[2], indexar[1], indexar[0]);
break;
case 5:
- if (indexar[0] == 0) accum_mballfaces(indexar[0], indexar[3], indexar[2], indexar[1]);
- else accum_mballfaces(indexar[3], indexar[2], indexar[1], indexar[0]);
+ if (indexar[0] == 0) accum_mballfaces(process, indexar[0], indexar[3], indexar[2], indexar[1]);
+ else accum_mballfaces(process, indexar[3], indexar[2], indexar[1], indexar[0]);
- accum_mballfaces(indexar[4], indexar[3], indexar[0], 0);
+ accum_mballfaces(process, indexar[4], indexar[3], indexar[0], 0);
break;
case 6:
if (indexar[0] == 0) {
- accum_mballfaces(indexar[0], indexar[3], indexar[2], indexar[1]);
- accum_mballfaces(indexar[0], indexar[5], indexar[4], indexar[3]);
+ accum_mballfaces(process, indexar[0], indexar[3], indexar[2], indexar[1]);
+ accum_mballfaces(process, indexar[0], indexar[5], indexar[4], indexar[3]);
}
else {
- accum_mballfaces(indexar[3], indexar[2], indexar[1], indexar[0]);
- accum_mballfaces(indexar[5], indexar[4], indexar[3], indexar[0]);
+ accum_mballfaces(process, indexar[3], indexar[2], indexar[1], indexar[0]);
+ accum_mballfaces(process, indexar[5], indexar[4], indexar[3], indexar[0]);
}
break;
case 7:
if (indexar[0] == 0) {
- accum_mballfaces(indexar[0], indexar[3], indexar[2], indexar[1]);
- accum_mballfaces(indexar[0], indexar[5], indexar[4], indexar[3]);
+ accum_mballfaces(process, indexar[0], indexar[3], indexar[2], indexar[1]);
+ accum_mballfaces(process, indexar[0], indexar[5], indexar[4], indexar[3]);
}
else {
- accum_mballfaces(indexar[3], indexar[2], indexar[1], indexar[0]);
- accum_mballfaces(indexar[5], indexar[4], indexar[3], indexar[0]);
+ accum_mballfaces(process, indexar[3], indexar[2], indexar[1], indexar[0]);
+ accum_mballfaces(process, indexar[5], indexar[4], indexar[3], indexar[0]);
}
- accum_mballfaces(indexar[6], indexar[5], indexar[0], 0);
+ accum_mballfaces(process, indexar[6], indexar[5], indexar[0], 0);
break;
}
@@ -996,10 +974,10 @@ static void docube(CUBE *cube, PROCESS *p, MetaBall *mb)
* if surface crosses face, compute other four corners of adjacent cube
* and add new cube to cube stack */
-static void testface(int i, int j, int k, CUBE *old, int bit, int c1, int c2, int c3, int c4, PROCESS *p)
+static void testface(PROCESS *process, int i, int j, int k, CUBE *old, int bit, int c1, int c2, int c3, int c4)
{
CUBE newc;
- CUBES *oldcubes = p->cubes;
+ CUBES *oldcubes = process->cubes;
CORNER *corn1, *corn2, *corn3, *corn4;
int n, pos;
@@ -1015,12 +993,13 @@ static void testface(int i, int j, int k, CUBE *old, int bit, int c1, int c2, in
/* test if cube out of bounds */
/*if ( abs(i) > p->bounds || abs(j) > p->bounds || abs(k) > p->bounds) return;*/
/* test if already visited (always as last) */
- if (setcenter(p->centers, i, j, k)) return;
-
+ if (setcenter(process, process->centers, i, j, k)) {
+ return;
+ }
/* create new cube and add cube to top of stack: */
- p->cubes = (CUBES *) new_pgn_element(sizeof(CUBES));
- p->cubes->next = oldcubes;
+ process->cubes = (CUBES *) new_pgn_element(process, sizeof(CUBES));
+ process->cubes->next = oldcubes;
newc.i = i;
newc.j = j;
@@ -1032,22 +1011,22 @@ static void testface(int i, int j, int k, CUBE *old, int bit, int c1, int c2, in
newc.corners[FLIP(c3, bit)] = corn3;
newc.corners[FLIP(c4, bit)] = corn4;
- if (newc.corners[0] == NULL) newc.corners[0] = setcorner(p, i, j, k);
- if (newc.corners[1] == NULL) newc.corners[1] = setcorner(p, i, j, k + 1);
- if (newc.corners[2] == NULL) newc.corners[2] = setcorner(p, i, j + 1, k);
- if (newc.corners[3] == NULL) newc.corners[3] = setcorner(p, i, j + 1, k + 1);
- if (newc.corners[4] == NULL) newc.corners[4] = setcorner(p, i + 1, j, k);
- if (newc.corners[5] == NULL) newc.corners[5] = setcorner(p, i + 1, j, k + 1);
- if (newc.corners[6] == NULL) newc.corners[6] = setcorner(p, i + 1, j + 1, k);
- if (newc.corners[7] == NULL) newc.corners[7] = setcorner(p, i + 1, j + 1, k + 1);
+ if (newc.corners[0] == NULL) newc.corners[0] = setcorner(process, i, j, k);
+ if (newc.corners[1] == NULL) newc.corners[1] = setcorner(process, i, j, k + 1);
+ if (newc.corners[2] == NULL) newc.corners[2] = setcorner(process, i, j + 1, k);
+ if (newc.corners[3] == NULL) newc.corners[3] = setcorner(process, i, j + 1, k + 1);
+ if (newc.corners[4] == NULL) newc.corners[4] = setcorner(process, i + 1, j, k);
+ if (newc.corners[5] == NULL) newc.corners[5] = setcorner(process, i + 1, j, k + 1);
+ if (newc.corners[6] == NULL) newc.corners[6] = setcorner(process, i + 1, j + 1, k);
+ if (newc.corners[7] == NULL) newc.corners[7] = setcorner(process, i + 1, j + 1, k + 1);
- p->cubes->cube = newc;
+ process->cubes->cube = newc;
}
/* setcorner: return corner with the given lattice location
* set (and cache) its function value */
-static CORNER *setcorner(PROCESS *p, int i, int j, int k)
+static CORNER *setcorner(PROCESS *process, int i, int j, int k)
{
/* for speed, do corner value caching here */
CORNER *c;
@@ -1055,7 +1034,7 @@ static CORNER *setcorner(PROCESS *p, int i, int j, int k)
/* does corner exist? */
index = HASH(i, j, k);
- c = p->corners[index];
+ c = process->corners[index];
for (; c != NULL; c = c->next) {
if (c->i == i && c->j == j && c->k == k) {
@@ -1063,18 +1042,18 @@ static CORNER *setcorner(PROCESS *p, int i, int j, int k)
}
}
- c = (CORNER *) new_pgn_element(sizeof(CORNER));
+ c = (CORNER *) new_pgn_element(process, sizeof(CORNER));
c->i = i;
- c->co[0] = ((float)i - 0.5f) * p->size;
+ c->co[0] = ((float)i - 0.5f) * process->size;
c->j = j;
- c->co[1] = ((float)j - 0.5f) * p->size;
+ c->co[1] = ((float)j - 0.5f) * process->size;
c->k = k;
- c->co[2] = ((float)k - 0.5f) * p->size;
- c->value = p->function(c->co[0], c->co[1], c->co[2]);
+ c->co[2] = ((float)k - 0.5f) * process->size;
+ c->value = process->function(process, c->co[0], c->co[1], c->co[2]);
- c->next = p->corners[index];
- p->corners[index] = c;
+ c->next = process->corners[index];
+ process->corners[index] = c;
return c;
}
@@ -1196,7 +1175,7 @@ void BKE_mball_cubeTable_free(void)
/* setcenter: set (i, j, k) entry of table[]
* return 1 if already set; otherwise, set and return 0 */
-static int setcenter(CENTERLIST *table[], const int i, const int j, const int k)
+static int setcenter(PROCESS *process, CENTERLIST *table[], const int i, const int j, const int k)
{
int index;
CENTERLIST *newc, *l, *q;
@@ -1208,7 +1187,7 @@ static int setcenter(CENTERLIST *table[], const int i, const int j, const int k)
if (l->i == i && l->j == j && l->k == k) return 1;
}
- newc = (CENTERLIST *) new_pgn_element(sizeof(CENTERLIST));
+ newc = (CENTERLIST *) new_pgn_element(process, sizeof(CENTERLIST));
newc->i = i;
newc->j = j;
newc->k = k;
@@ -1221,7 +1200,8 @@ static int setcenter(CENTERLIST *table[], const int i, const int j, const int k)
/* setedge: set vertex id for edge */
-static void setedge(EDGELIST *table[],
+static void setedge(PROCESS *process,
+ EDGELIST *table[],
int i1, int j1,
int k1, int i2,
int j2, int k2,
@@ -1242,7 +1222,7 @@ static void setedge(EDGELIST *table[],
k2 = t;
}
index = HASH(i1, j1, k1) + HASH(i2, j2, k2);
- newe = (EDGELIST *) new_pgn_element(sizeof(EDGELIST));
+ newe = (EDGELIST *) new_pgn_element(process, sizeof(EDGELIST));
newe->i1 = i1;
newe->j1 = j1;
newe->k1 = k1;
@@ -1316,14 +1296,14 @@ static void addtovertices(VERTICES *vertices, VERTEX v)
/* vnormal: compute unit length surface normal at point */
-static void vnormal(const float point[3], PROCESS *p, float r_no[3])
+static void vnormal(PROCESS *process, const float point[3], float r_no[3])
{
- const float delta = 0.2f * p->delta;
- const float f = p->function(point[0], point[1], point[2]);
+ const float delta = 0.2f * process->delta;
+ const float f = process->function(process, point[0], point[1], point[2]);
- r_no[0] = p->function(point[0] + delta, point[1], point[2]) - f;
- r_no[1] = p->function(point[0], point[1] + delta, point[2]) - f;
- r_no[2] = p->function(point[0], point[1], point[2] + delta) - f;
+ r_no[0] = process->function(process, point[0] + delta, point[1], point[2]) - f;
+ r_no[1] = process->function(process, point[0], point[1] + delta, point[2]) - f;
+ r_no[2] = process->function(process, point[0], point[1], point[2] + delta) - f;
#if 1
normalize_v3(r_no);
@@ -1335,11 +1315,11 @@ static void vnormal(const float point[3], PROCESS *p, float r_no[3])
delta *= 2.0f;
- f = p->function(point[0], point[1], point[2]);
+ f = process->function(process, point[0], point[1], point[2]);
- tvec[0] = p->function(point[0] + delta, point[1], point[2]) - f;
- tvec[1] = p->function(point[0], point[1] + delta, point[2]) - f;
- tvec[2] = p->function(point[0], point[1], point[2] + delta) - f;
+ tvec[0] = process->function(process, point[0] + delta, point[1], point[2]) - f;
+ tvec[1] = process->function(process, point[0], point[1] + delta, point[2]) - f;
+ tvec[2] = process->function(process, point[0], point[1], point[2] + delta) - f;
if (normalize_v3(tvec) != 0.0f) {
add_v3_v3(r_no, tvec);
@@ -1350,32 +1330,30 @@ static void vnormal(const float point[3], PROCESS *p, float r_no[3])
}
-static int vertid(const CORNER *c1, const CORNER *c2, PROCESS *p, MetaBall *mb)
+static int vertid(PROCESS *process, const CORNER *c1, const CORNER *c2, MetaBall *mb)
{
VERTEX v;
- int vid = getedge(p->edges, c1->i, c1->j, c1->k, c2->i, c2->j, c2->k);
+ int vid = getedge(process->edges, c1->i, c1->j, c1->k, c2->i, c2->j, c2->k);
if (vid != -1) {
return vid; /* previously computed */
}
- converge(c1->co, c2->co, c1->value, c2->value, p->function, v.co, mb, 1); /* position */
- vnormal(v.co, p, v.no);
+ converge(process, c1->co, c2->co, c1->value, c2->value, v.co, mb, 1); /* position */
+ vnormal(process, v.co, v.no);
- addtovertices(&p->vertices, v); /* save vertex */
- vid = p->vertices.count - 1;
- setedge(p->edges, c1->i, c1->j, c1->k, c2->i, c2->j, c2->k, vid);
+ addtovertices(&process->vertices, v); /* save vertex */
+ vid = process->vertices.count - 1;
+ setedge(process, process->edges, c1->i, c1->j, c1->k, c2->i, c2->j, c2->k, vid);
return vid;
}
-
-
/* converge: from two points of differing sign, converge to zero crossing */
/* watch it: p1 and p2 are used to calculate */
-static void converge(const float p1[3], const float p2[3], float v1, float v2,
- float (*function)(float, float, float), float p[3], MetaBall *mb, int f)
+static void converge(PROCESS *process, const float p1[3], const float p2[3], float v1, float v2,
+ float p[3], MetaBall *mb, int f)
{
int i = 0;
float pos[3], neg[3];
@@ -1426,8 +1404,8 @@ static void converge(const float p1[3], const float p2[3], float v1, float v2,
while (1) {
if (i++ == RES) return;
p[0] = 0.5f * (pos[0] + neg[0]);
- if ((function(p[0], p[1], p[2])) > 0.0f) pos[0] = p[0];
- else neg[0] = p[0];
+ if ((process->function(process, p[0], p[1], p[2])) > 0.0f) pos[0] = p[0];
+ else neg[0] = p[0];
}
}
@@ -1437,8 +1415,8 @@ static void converge(const float p1[3], const float p2[3], float v1, float v2,
while (1) {
if (i++ == RES) return;
p[1] = 0.5f * (pos[1] + neg[1]);
- if ((function(p[0], p[1], p[2])) > 0.0f) pos[1] = p[1];
- else neg[1] = p[1];
+ if ((process->function(process, p[0], p[1], p[2])) > 0.0f) pos[1] = p[1];
+ else neg[1] = p[1];
}
}
@@ -1448,8 +1426,8 @@ static void converge(const float p1[3], const float p2[3], float v1, float v2,
while (1) {
if (i++ == RES) return;
p[2] = 0.5f * (pos[2] + neg[2]);
- if ((function(p[0], p[1], p[2])) > 0.0f) pos[2] = p[2];
- else neg[2] = p[2];
+ if ((process->function(process, p[0], p[1], p[2])) > 0.0f) pos[2] = p[2];
+ else neg[2] = p[2];
}
}
@@ -1461,7 +1439,7 @@ static void converge(const float p1[3], const float p2[3], float v1, float v2,
return;
}
- if ((function(p[0], p[1], p[2])) > 0.0f) {
+ if ((process->function(process, p[0], p[1], p[2])) > 0.0f) {
copy_v3_v3(pos, &p[0]);
}
else {
@@ -1471,7 +1449,7 @@ static void converge(const float p1[3], const float p2[3], float v1, float v2,
}
/* ************************************** */
-static void add_cube(PROCESS *mbproc, int i, int j, int k, int count)
+static void add_cube(PROCESS *process, int i, int j, int k, int count)
{
CUBES *ncube;
int n;
@@ -1483,11 +1461,11 @@ static void add_cube(PROCESS *mbproc, int i, int j, int k, int count)
for (b = j - 1; b < j + count; b++)
for (c = k - 1; c < k + count; c++) {
/* test if cube has been found before */
- if (setcenter(mbproc->centers, a, b, c) == 0) {
+ if (setcenter(process, process->centers, a, b, c) == 0) {
/* push cube on stack: */
- ncube = (CUBES *) new_pgn_element(sizeof(CUBES));
- ncube->next = mbproc->cubes;
- mbproc->cubes = ncube;
+ ncube = (CUBES *) new_pgn_element(process, sizeof(CUBES));
+ ncube->next = process->cubes;
+ process->cubes = ncube;
ncube->cube.i = a;
ncube->cube.j = b;
@@ -1495,18 +1473,18 @@ static void add_cube(PROCESS *mbproc, int i, int j, int k, int count)
/* set corners of initial cube: */
for (n = 0; n < 8; n++)
- ncube->cube.corners[n] = setcorner(mbproc, a + MB_BIT(n, 2), b + MB_BIT(n, 1), c + MB_BIT(n, 0));
+ ncube->cube.corners[n] = setcorner(process, a + MB_BIT(n, 2), b + MB_BIT(n, 1), c + MB_BIT(n, 0));
}
}
}
-static void find_first_points(PROCESS *mbproc, MetaBall *mb, int a)
+static void find_first_points(PROCESS *process, MetaBall *mb, int a)
{
MetaElem *ml;
float f;
- ml = G_mb.mainb[a];
+ ml = process->mainb[a];
f = 1.0f - (mb->thresh / ml->s);
/* Skip, when Stiffness of MetaElement is too small ... MetaElement can't be
@@ -1521,7 +1499,7 @@ static void find_first_points(PROCESS *mbproc, MetaBall *mb, int a)
float tmp_v, workp_v, max_len, nx, ny, nz, max_dim;
calc_mballco(ml, in);
- in_v = mbproc->function(in[0], in[1], in[2]);
+ in_v = process->function(process, in[0], in[1], in[2]);
for (i = 0; i < 3; i++) {
switch (ml->type) {
@@ -1566,16 +1544,16 @@ static void find_first_points(PROCESS *mbproc, MetaBall *mb, int a)
calc_mballco(ml, out);
- /*out_v = mbproc->function(out[0], out[1], out[2]);*/ /*UNUSED*/
+ /*out_v = process->function(out[0], out[1], out[2]);*/ /*UNUSED*/
/* find "first points" on Implicit Surface of MetaElemnt ml */
copy_v3_v3(workp, in);
workp_v = in_v;
max_len = len_v3v3(out, in);
- nx = abs((out[0] - in[0]) / mbproc->size);
- ny = abs((out[1] - in[1]) / mbproc->size);
- nz = abs((out[2] - in[2]) / mbproc->size);
+ nx = abs((out[0] - in[0]) / process->size);
+ ny = abs((out[1] - in[1]) / process->size);
+ nz = abs((out[2] - in[2]) / process->size);
max_dim = max_fff(nx, ny, nz);
if (max_dim != 0.0f) {
@@ -1589,22 +1567,22 @@ static void find_first_points(PROCESS *mbproc, MetaBall *mb, int a)
add_v3_v3(workp, dvec);
/* compute value of implicite function */
- tmp_v = mbproc->function(workp[0], workp[1], workp[2]);
+ tmp_v = process->function(process, workp[0], workp[1], workp[2]);
/* add cube to the stack, when value of implicite function crosses zero value */
if ((tmp_v < 0.0f && workp_v >= 0.0f) || (tmp_v > 0.0f && workp_v <= 0.0f)) {
/* indexes of CUBE, which includes "first point" */
- c_i = (int)floor(workp[0] / mbproc->size);
- c_j = (int)floor(workp[1] / mbproc->size);
- c_k = (int)floor(workp[2] / mbproc->size);
+ c_i = (int)floor(workp[0] / process->size);
+ c_j = (int)floor(workp[1] / process->size);
+ c_k = (int)floor(workp[2] / process->size);
/* add CUBE (with indexes c_i, c_j, c_k) to the stack,
* this cube includes found point of Implicit Surface */
if ((ml->flag & MB_NEGATIVE) == 0) {
- add_cube(mbproc, c_i, c_j, c_k, 1);
+ add_cube(process, c_i, c_j, c_k, 1);
}
else {
- add_cube(mbproc, c_i, c_j, c_k, 2);
+ add_cube(process, c_i, c_j, c_k, 2);
}
}
len = len_v3v3(workp, in);
@@ -1618,43 +1596,43 @@ static void find_first_points(PROCESS *mbproc, MetaBall *mb, int a)
}
}
-static void polygonize(PROCESS *mbproc, MetaBall *mb)
+static void polygonize(PROCESS *process, MetaBall *mb)
{
CUBE c;
int a;
- mbproc->vertices.count = mbproc->vertices.max = 0;
- mbproc->vertices.ptr = NULL;
+ process->vertices.count = process->vertices.max = 0;
+ process->vertices.ptr = NULL;
/* allocate hash tables and build cube polygon table: */
- mbproc->centers = MEM_callocN(HASHSIZE * sizeof(CENTERLIST *), "mbproc->centers");
- mbproc->corners = MEM_callocN(HASHSIZE * sizeof(CORNER *), "mbproc->corners");
- mbproc->edges = MEM_callocN(2 * HASHSIZE * sizeof(EDGELIST *), "mbproc->edges");
+ process->centers = MEM_callocN(HASHSIZE * sizeof(CENTERLIST *), "mbproc->centers");
+ process->corners = MEM_callocN(HASHSIZE * sizeof(CORNER *), "mbproc->corners");
+ process->edges = MEM_callocN(2 * HASHSIZE * sizeof(EDGELIST *), "mbproc->edges");
makecubetable();
- for (a = 0; a < G_mb.totelem; a++) {
+ for (a = 0; a < process->totelem; a++) {
/* try to find 8 points on the surface for each MetaElem */
- find_first_points(mbproc, mb, a);
+ find_first_points(process, mb, a);
}
/* polygonize all MetaElems of current MetaBall */
- while (mbproc->cubes != NULL) { /* process active cubes till none left */
- c = mbproc->cubes->cube;
+ while (process->cubes != NULL) { /* process active cubes till none left */
+ c = process->cubes->cube;
/* polygonize the cube directly: */
- docube(&c, mbproc, mb);
+ docube(process, &c, mb);
/* pop current cube from stack */
- mbproc->cubes = mbproc->cubes->next;
+ process->cubes = process->cubes->next;
/* test six face directions, maybe add to stack: */
- testface(c.i - 1, c.j, c.k, &c, 2, LBN, LBF, LTN, LTF, mbproc);
- testface(c.i + 1, c.j, c.k, &c, 2, RBN, RBF, RTN, RTF, mbproc);
- testface(c.i, c.j - 1, c.k, &c, 1, LBN, LBF, RBN, RBF, mbproc);
- testface(c.i, c.j + 1, c.k, &c, 1, LTN, LTF, RTN, RTF, mbproc);
- testface(c.i, c.j, c.k - 1, &c, 0, LBN, LTN, RBN, RTN, mbproc);
- testface(c.i, c.j, c.k + 1, &c, 0, LBF, LTF, RBF, RTF, mbproc);
+ testface(process, c.i - 1, c.j, c.k, &c, 2, LBN, LBF, LTN, LTF);
+ testface(process, c.i + 1, c.j, c.k, &c, 2, RBN, RBF, RTN, RTF);
+ testface(process, c.i, c.j - 1, c.k, &c, 1, LBN, LBF, RBN, RBF);
+ testface(process, c.i, c.j + 1, c.k, &c, 1, LTN, LTF, RTN, RTF);
+ testface(process, c.i, c.j, c.k - 1, &c, 0, LBN, LTN, RBN, RTN);
+ testface(process, c.i, c.j, c.k + 1, &c, 0, LBF, LTF, RBF, RTF);
}
}
@@ -1666,7 +1644,7 @@ BLI_INLINE void copy_v3_fl3(float v[3], float x, float y, float z)
v[2] = z;
}
-static float init_meta(Scene *scene, Object *ob) /* return totsize */
+static float init_meta(PROCESS *process, Scene *scene, Object *ob) /* return totsize */
{
Scene *sce_iter = scene;
Base *base;
@@ -1733,7 +1711,7 @@ static float init_meta(Scene *scene, Object *ob) /* return totsize */
ml_count++;
ml = ml->next;
}
- G_mb.totelem -= ml_count;
+ process->totelem -= ml_count;
}
else {
while (ml) {
@@ -1763,12 +1741,12 @@ static float init_meta(Scene *scene, Object *ob) /* return totsize */
mul_m4_m4m4(temp1, temp2, temp3);
/* make a copy because of duplicates */
- G_mb.mainb[a] = new_pgn_element(sizeof(MetaElem));
- *(G_mb.mainb[a]) = *ml;
- G_mb.mainb[a]->bb = new_pgn_element(sizeof(BoundBox));
+ process->mainb[a] = new_pgn_element(process, sizeof(MetaElem));
+ *(process->mainb[a]) = *ml;
+ process->mainb[a]->bb = new_pgn_element(process, sizeof(BoundBox));
- mat = new_pgn_element(4 * 4 * sizeof(float));
- imat = new_pgn_element(4 * 4 * sizeof(float));
+ mat = new_pgn_element(process, 4 * 4 * sizeof(float));
+ imat = new_pgn_element(process, 4 * 4 * sizeof(float));
/* mat is the matrix to transform from mball into the basis-mball */
invert_m4_m4(obinv, obmat);
@@ -1778,10 +1756,10 @@ static float init_meta(Scene *scene, Object *ob) /* return totsize */
invert_m4_m4(imat, mat);
- G_mb.mainb[a]->rad2 = ml->rad * ml->rad;
+ process->mainb[a]->rad2 = ml->rad * ml->rad;
- G_mb.mainb[a]->mat = (float *) mat;
- G_mb.mainb[a]->imat = (float *) imat;
+ process->mainb[a]->mat = (float *) mat;
+ process->mainb[a]->imat = (float *) imat;
if (!MB_TYPE_SIZE_SQUARED(ml->type)) {
expx = ml->expx;
@@ -1796,40 +1774,40 @@ static float init_meta(Scene *scene, Object *ob) /* return totsize */
/* untransformed Bounding Box of MetaElem */
/* TODO, its possible the elem type has been changed and the exp* values can use a fallback */
- copy_v3_fl3(G_mb.mainb[a]->bb->vec[0], -expx, -expy, -expz); /* 0 */
- copy_v3_fl3(G_mb.mainb[a]->bb->vec[1], +expx, -expy, -expz); /* 1 */
- copy_v3_fl3(G_mb.mainb[a]->bb->vec[2], +expx, +expy, -expz); /* 2 */
- copy_v3_fl3(G_mb.mainb[a]->bb->vec[3], -expx, +expy, -expz); /* 3 */
- copy_v3_fl3(G_mb.mainb[a]->bb->vec[4], -expx, -expy, +expz); /* 4 */
- copy_v3_fl3(G_mb.mainb[a]->bb->vec[5], +expx, -expy, +expz); /* 5 */
- copy_v3_fl3(G_mb.mainb[a]->bb->vec[6], +expx, +expy, +expz); /* 6 */
- copy_v3_fl3(G_mb.mainb[a]->bb->vec[7], -expx, +expy, +expz); /* 7 */
+ copy_v3_fl3(process->mainb[a]->bb->vec[0], -expx, -expy, -expz); /* 0 */
+ copy_v3_fl3(process->mainb[a]->bb->vec[1], +expx, -expy, -expz); /* 1 */
+ copy_v3_fl3(process->mainb[a]->bb->vec[2], +expx, +expy, -expz); /* 2 */
+ copy_v3_fl3(process->mainb[a]->bb->vec[3], -expx, +expy, -expz); /* 3 */
+ copy_v3_fl3(process->mainb[a]->bb->vec[4], -expx, -expy, +expz); /* 4 */
+ copy_v3_fl3(process->mainb[a]->bb->vec[5], +expx, -expy, +expz); /* 5 */
+ copy_v3_fl3(process->mainb[a]->bb->vec[6], +expx, +expy, +expz); /* 6 */
+ copy_v3_fl3(process->mainb[a]->bb->vec[7], -expx, +expy, +expz); /* 7 */
/* transformation of Metalem bb */
for (i = 0; i < 8; i++)
- mul_m4_v3((float (*)[4])mat, G_mb.mainb[a]->bb->vec[i]);
+ mul_m4_v3((float (*)[4])mat, process->mainb[a]->bb->vec[i]);
/* find max and min of transformed bb */
for (i = 0; i < 8; i++) {
/* find maximums */
- if (G_mb.mainb[a]->bb->vec[i][0] > max_x) max_x = G_mb.mainb[a]->bb->vec[i][0];
- if (G_mb.mainb[a]->bb->vec[i][1] > max_y) max_y = G_mb.mainb[a]->bb->vec[i][1];
- if (G_mb.mainb[a]->bb->vec[i][2] > max_z) max_z = G_mb.mainb[a]->bb->vec[i][2];
+ if (process->mainb[a]->bb->vec[i][0] > max_x) max_x = process->mainb[a]->bb->vec[i][0];
+ if (process->mainb[a]->bb->vec[i][1] > max_y) max_y = process->mainb[a]->bb->vec[i][1];
+ if (process->mainb[a]->bb->vec[i][2] > max_z) max_z = process->mainb[a]->bb->vec[i][2];
/* find minimums */
- if (G_mb.mainb[a]->bb->vec[i][0] < min_x) min_x = G_mb.mainb[a]->bb->vec[i][0];
- if (G_mb.mainb[a]->bb->vec[i][1] < min_y) min_y = G_mb.mainb[a]->bb->vec[i][1];
- if (G_mb.mainb[a]->bb->vec[i][2] < min_z) min_z = G_mb.mainb[a]->bb->vec[i][2];
+ if (process->mainb[a]->bb->vec[i][0] < min_x) min_x = process->mainb[a]->bb->vec[i][0];
+ if (process->mainb[a]->bb->vec[i][1] < min_y) min_y = process->mainb[a]->bb->vec[i][1];
+ if (process->mainb[a]->bb->vec[i][2] < min_z) min_z = process->mainb[a]->bb->vec[i][2];
}
/* create "new" bb, only point 0 and 6, which are
* necessary for octal tree filling */
- G_mb.mainb[a]->bb->vec[0][0] = min_x - ml->rad;
- G_mb.mainb[a]->bb->vec[0][1] = min_y - ml->rad;
- G_mb.mainb[a]->bb->vec[0][2] = min_z - ml->rad;
+ process->mainb[a]->bb->vec[0][0] = min_x - ml->rad;
+ process->mainb[a]->bb->vec[0][1] = min_y - ml->rad;
+ process->mainb[a]->bb->vec[0][2] = min_z - ml->rad;
- G_mb.mainb[a]->bb->vec[6][0] = max_x + ml->rad;
- G_mb.mainb[a]->bb->vec[6][1] = max_y + ml->rad;
- G_mb.mainb[a]->bb->vec[6][2] = max_z + ml->rad;
+ process->mainb[a]->bb->vec[6][0] = max_x + ml->rad;
+ process->mainb[a]->bb->vec[6][1] = max_y + ml->rad;
+ process->mainb[a]->bb->vec[6][2] = max_z + ml->rad;
a++;
}
@@ -1842,13 +1820,13 @@ static float init_meta(Scene *scene, Object *ob) /* return totsize */
/* totsize (= 'manhattan' radius) */
totsize = 0.0;
- for (a = 0; a < G_mb.totelem; a++) {
+ for (a = 0; a < process->totelem; a++) {
- vec[0] = G_mb.mainb[a]->x + G_mb.mainb[a]->rad + G_mb.mainb[a]->expx;
- vec[1] = G_mb.mainb[a]->y + G_mb.mainb[a]->rad + G_mb.mainb[a]->expy;
- vec[2] = G_mb.mainb[a]->z + G_mb.mainb[a]->rad + G_mb.mainb[a]->expz;
+ vec[0] = process->mainb[a]->x + process->mainb[a]->rad + process->mainb[a]->expx;
+ vec[1] = process->mainb[a]->y + process->mainb[a]->rad + process->mainb[a]->expy;
+ vec[2] = process->mainb[a]->z + process->mainb[a]->rad + process->mainb[a]->expz;
- calc_mballco(G_mb.mainb[a], vec);
+ calc_mballco(process->mainb[a], vec);
size = fabsf(vec[0]);
if (size > totsize) totsize = size;
@@ -1857,11 +1835,11 @@ static float init_meta(Scene *scene, Object *ob) /* return totsize */
size = fabsf(vec[2]);
if (size > totsize) totsize = size;
- vec[0] = G_mb.mainb[a]->x - G_mb.mainb[a]->rad;
- vec[1] = G_mb.mainb[a]->y - G_mb.mainb[a]->rad;
- vec[2] = G_mb.mainb[a]->z - G_mb.mainb[a]->rad;
+ vec[0] = process->mainb[a]->x - process->mainb[a]->rad;
+ vec[1] = process->mainb[a]->y - process->mainb[a]->rad;
+ vec[2] = process->mainb[a]->z - process->mainb[a]->rad;
- calc_mballco(G_mb.mainb[a], vec);
+ calc_mballco(process->mainb[a], vec);
size = fabsf(vec[0]);
if (size > totsize) totsize = size;
@@ -1871,8 +1849,8 @@ static float init_meta(Scene *scene, Object *ob) /* return totsize */
if (size > totsize) totsize = size;
}
- for (a = 0; a < G_mb.totelem; a++) {
- G_mb.thresh += densfunc(G_mb.mainb[a], 2.0f * totsize, 2.0f * totsize, 2.0f * totsize);
+ for (a = 0; a < process->totelem; a++) {
+ process->thresh += densfunc(process->mainb[a], 2.0f * totsize, 2.0f * totsize, 2.0f * totsize);
}
return totsize;
@@ -2181,20 +2159,20 @@ static void free_metaball_octal_node(octal_node *node)
}
/* If scene include more than one MetaElem, then octree is used */
-static void init_metaball_octal_tree(int depth)
+static void init_metaball_octal_tree(PROCESS *process, int depth)
{
struct octal_node *node;
ml_pointer *ml_p;
float size[3];
int a;
- G_mb.metaball_tree = MEM_mallocN(sizeof(octal_tree), "metaball_octal_tree");
- G_mb.metaball_tree->first = node = MEM_mallocN(sizeof(octal_node), "metaball_octal_node");
+ process->metaball_tree = MEM_mallocN(sizeof(octal_tree), "metaball_octal_tree");
+ process->metaball_tree->first = node = MEM_mallocN(sizeof(octal_node), "metaball_octal_node");
/* maximal depth of octree */
- G_mb.metaball_tree->depth = depth;
+ process->metaball_tree->depth = depth;
- G_mb.metaball_tree->neg = node->neg = 0;
- G_mb.metaball_tree->pos = node->pos = 0;
+ process->metaball_tree->neg = node->neg = 0;
+ process->metaball_tree->pos = node->pos = 0;
node->elems.first = NULL;
node->elems.last = NULL;
@@ -2207,26 +2185,26 @@ static void init_metaball_octal_tree(int depth)
node->x_max = node->y_max = node->z_max = -FLT_MAX;
/* size of octal tree scene */
- for (a = 0; a < G_mb.totelem; a++) {
- if (G_mb.mainb[a]->bb->vec[0][0] < node->x_min) node->x_min = G_mb.mainb[a]->bb->vec[0][0];
- if (G_mb.mainb[a]->bb->vec[0][1] < node->y_min) node->y_min = G_mb.mainb[a]->bb->vec[0][1];
- if (G_mb.mainb[a]->bb->vec[0][2] < node->z_min) node->z_min = G_mb.mainb[a]->bb->vec[0][2];
+ for (a = 0; a < process->totelem; a++) {
+ if (process->mainb[a]->bb->vec[0][0] < node->x_min) node->x_min = process->mainb[a]->bb->vec[0][0];
+ if (process->mainb[a]->bb->vec[0][1] < node->y_min) node->y_min = process->mainb[a]->bb->vec[0][1];
+ if (process->mainb[a]->bb->vec[0][2] < node->z_min) node->z_min = process->mainb[a]->bb->vec[0][2];
- if (G_mb.mainb[a]->bb->vec[6][0] > node->x_max) node->x_max = G_mb.mainb[a]->bb->vec[6][0];
- if (G_mb.mainb[a]->bb->vec[6][1] > node->y_max) node->y_max = G_mb.mainb[a]->bb->vec[6][1];
- if (G_mb.mainb[a]->bb->vec[6][2] > node->z_max) node->z_max = G_mb.mainb[a]->bb->vec[6][2];
+ if (process->mainb[a]->bb->vec[6][0] > node->x_max) node->x_max = process->mainb[a]->bb->vec[6][0];
+ if (process->mainb[a]->bb->vec[6][1] > node->y_max) node->y_max = process->mainb[a]->bb->vec[6][1];
+ if (process->mainb[a]->bb->vec[6][2] > node->z_max) node->z_max = process->mainb[a]->bb->vec[6][2];
ml_p = MEM_mallocN(sizeof(ml_pointer), "ml_pointer");
- ml_p->ml = G_mb.mainb[a];
+ ml_p->ml = process->mainb[a];
BLI_addtail(&node->elems, ml_p);
- if ((G_mb.mainb[a]->flag & MB_NEGATIVE) == 0) {
+ if ((process->mainb[a]->flag & MB_NEGATIVE) == 0) {
/* number of positive MetaElem in scene */
- G_mb.metaball_tree->pos++;
+ process->metaball_tree->pos++;
}
else {
/* number of negative MetaElem in scene */
- G_mb.metaball_tree->neg++;
+ process->metaball_tree->neg++;
}
}
@@ -2236,61 +2214,106 @@ static void init_metaball_octal_tree(int depth)
size[2] = node->z_max - node->z_min;
/* first node is subdivided recursively */
- subdivide_metaball_octal_node(node, size[0], size[1], size[2], G_mb.metaball_tree->depth);
+ subdivide_metaball_octal_node(node, size[0], size[1], size[2], process->metaball_tree->depth);
+}
+
+static void mball_count(PROCESS *process, Scene *scene, Object *basis)
+{
+ Scene *sce_iter = scene;
+ Base *base;
+ Object *ob, *bob = basis;
+ MetaElem *ml = NULL;
+ int basisnr, obnr;
+ char basisname[MAX_ID_NAME], obname[MAX_ID_NAME];
+
+ BLI_split_name_num(basisname, &basisnr, basis->id.name + 2, '.');
+ process->totelem = 0;
+
+ /* XXX recursion check, see scene.c, just too simple code this BKE_scene_base_iter_next() */
+ if (F_ERROR == BKE_scene_base_iter_next(&sce_iter, 0, NULL, NULL))
+ return;
+
+ while (BKE_scene_base_iter_next(&sce_iter, 1, &base, &ob)) {
+ if (ob->type == OB_MBALL) {
+ if (ob == bob) {
+ MetaBall *mb = ob->data;
+
+ /* if bob object is in edit mode, then dynamic list of all MetaElems
+ * is stored in editelems */
+ if (mb->editelems) ml = mb->editelems->first;
+ /* if bob object is in object mode */
+ else ml = mb->elems.first;
+ }
+ else {
+ BLI_split_name_num(obname, &obnr, ob->id.name + 2, '.');
+
+ /* object ob has to be in same "group" ... it means, that it has to have
+ * same base of its name */
+ if (strcmp(obname, basisname) == 0) {
+ MetaBall *mb = ob->data;
+
+ /* if object is in edit mode, then dynamic list of all MetaElems
+ * is stored in editelems */
+ if (mb->editelems) ml = mb->editelems->first;
+ /* if bob object is in object mode */
+ else ml = mb->elems.first;
+ }
+ }
+
+ for ( ; ml; ml = ml->next) {
+ if (!(ml->flag & MB_HIDE)) {
+ process->totelem++;
+ }
+ }
+ }
+ }
}
void BKE_mball_polygonize(Scene *scene, Object *ob, ListBase *dispbase)
{
- PROCESS mbproc;
MetaBall *mb;
DispList *dl;
int a, nr_cubes;
float *co, *no, totsize, width;
+ PROCESS process = {0};
mb = ob->data;
- if (G_mb.totelem == 0) return;
+ mball_count(&process, scene, ob);
+
+ if (process.totelem == 0) return;
if ((G.is_rendering == FALSE) && (mb->flag == MB_UPDATE_NEVER)) return;
if (G.moving && mb->flag == MB_UPDATE_FAST) return;
- curindex = totindex = 0;
- indices = NULL;
- G_mb.thresh = mb->thresh;
+ process.thresh = mb->thresh;
/* total number of MetaElems (totelem) is precomputed in find_basis_mball() function */
- G_mb.mainb = MEM_mallocN(sizeof(void *) * G_mb.totelem, "mainb");
+ process.mainb = MEM_mallocN(sizeof(void *) * process.totelem, "mainb");
/* initialize all mainb (MetaElems) */
- totsize = init_meta(scene, ob);
-
- if (G_mb.metaball_tree) {
- free_metaball_octal_node(G_mb.metaball_tree->first);
- MEM_freeN(G_mb.metaball_tree);
- G_mb.metaball_tree = NULL;
- }
+ totsize = init_meta(&process, scene, ob);
/* if scene includes more than one MetaElem, then octal tree optimization is used */
- if ((G_mb.totelem > 1) && (G_mb.totelem <= 64)) init_metaball_octal_tree(1);
- if ((G_mb.totelem > 64) && (G_mb.totelem <= 128)) init_metaball_octal_tree(2);
- if ((G_mb.totelem > 128) && (G_mb.totelem <= 512)) init_metaball_octal_tree(3);
- if ((G_mb.totelem > 512) && (G_mb.totelem <= 1024)) init_metaball_octal_tree(4);
- if (G_mb.totelem > 1024) init_metaball_octal_tree(5);
+ if ((process.totelem > 1) && (process.totelem <= 64)) init_metaball_octal_tree(&process, 1);
+ if ((process.totelem > 64) && (process.totelem <= 128)) init_metaball_octal_tree(&process, 2);
+ if ((process.totelem > 128) && (process.totelem <= 512)) init_metaball_octal_tree(&process, 3);
+ if ((process.totelem > 512) && (process.totelem <= 1024)) init_metaball_octal_tree(&process, 4);
+ if (process.totelem > 1024) init_metaball_octal_tree(&process, 5);
/* don't polygonize metaballs with too high resolution (base mball to small)
* note: Eps was 0.0001f but this was giving problems for blood animation for durian, using 0.00001f */
- if (G_mb.metaball_tree) {
- if (ob->size[0] <= 0.00001f * (G_mb.metaball_tree->first->x_max - G_mb.metaball_tree->first->x_min) ||
- ob->size[1] <= 0.00001f * (G_mb.metaball_tree->first->y_max - G_mb.metaball_tree->first->y_min) ||
- ob->size[2] <= 0.00001f * (G_mb.metaball_tree->first->z_max - G_mb.metaball_tree->first->z_min))
+ if (process.metaball_tree) {
+ if (ob->size[0] <= 0.00001f * (process.metaball_tree->first->x_max - process.metaball_tree->first->x_min) ||
+ ob->size[1] <= 0.00001f * (process.metaball_tree->first->y_max - process.metaball_tree->first->y_min) ||
+ ob->size[2] <= 0.00001f * (process.metaball_tree->first->z_max - process.metaball_tree->first->z_min))
{
- new_pgn_element(-1); /* free values created by init_meta */
+ new_pgn_element(&process, -1); /* free values created by init_meta */
- MEM_freeN(G_mb.mainb);
+ MEM_freeN(process.mainb);
/* free tree */
- free_metaball_octal_node(G_mb.metaball_tree->first);
- MEM_freeN(G_mb.metaball_tree);
- G_mb.metaball_tree = NULL;
+ free_metaball_octal_node(process.metaball_tree->first);
+ MEM_freeN(process.metaball_tree);
return;
}
@@ -2308,46 +2331,46 @@ void BKE_mball_polygonize(Scene *scene, Object *ob, ListBase *dispbase)
nr_cubes = (int)(0.5f + totsize / width);
/* init process */
- mbproc.function = metaball;
- mbproc.size = width;
- mbproc.bounds = nr_cubes;
- mbproc.cubes = NULL;
- mbproc.delta = width / (float)(RES * RES);
+ process.function = metaball;
+ process.size = width;
+ process.bounds = nr_cubes;
+ process.cubes = NULL;
+ process.delta = width / (float)(RES * RES);
- polygonize(&mbproc, mb);
+ polygonize(&process, mb);
- MEM_freeN(G_mb.mainb);
+ MEM_freeN(process.mainb);
/* free octal tree */
- if (G_mb.totelem > 1) {
- free_metaball_octal_node(G_mb.metaball_tree->first);
- MEM_freeN(G_mb.metaball_tree);
- G_mb.metaball_tree = NULL;
+ if (process.totelem > 1) {
+ free_metaball_octal_node(process.metaball_tree->first);
+ MEM_freeN(process.metaball_tree);
+ process.metaball_tree = NULL;
}
- if (curindex) {
- VERTEX *ptr = mbproc.vertices.ptr;
+ if (process.curindex) {
+ VERTEX *ptr = process.vertices.ptr;
dl = MEM_callocN(sizeof(DispList), "mbaldisp");
BLI_addtail(dispbase, dl);
dl->type = DL_INDEX4;
- dl->nr = mbproc.vertices.count;
- dl->parts = curindex;
+ dl->nr = process.vertices.count;
+ dl->parts = process.curindex;
- dl->index = indices;
- indices = NULL;
+ dl->index = process.indices;
+ process.indices = NULL;
- a = mbproc.vertices.count;
+ a = process.vertices.count;
dl->verts = co = MEM_mallocN(sizeof(float) * 3 * a, "mballverts");
dl->nors = no = MEM_mallocN(sizeof(float) * 3 * a, "mballnors");
- for (a = 0; a < mbproc.vertices.count; ptr++, a++, no += 3, co += 3) {
+ for (a = 0; a < process.vertices.count; ptr++, a++, no += 3, co += 3) {
copy_v3_v3(co, ptr->co);
copy_v3_v3(no, ptr->no);
}
}
- freepolygonize(&mbproc);
+ freepolygonize(&process);
}
/* basic vertex data functions */
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index c17830639e4..a0fa3317297 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -36,7 +36,7 @@
* \ingroup bke
*/
-
+#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <stdarg.h>
@@ -60,6 +60,7 @@
#include "BKE_cloth.h"
#include "BKE_key.h"
#include "BKE_multires.h"
+#include "BKE_DerivedMesh.h"
/* may move these, only for modifier_path_relbase */
#include "BKE_global.h" /* ugh, G.main->name only */
@@ -693,3 +694,65 @@ void modifier_path_init(char *path, int path_maxlen, const char *name)
G.relbase_valid ? "//" : BLI_temporary_dir(),
name);
}
+
+
+/* wrapper around ModifierTypeInfo.applyModifier that ensures valid normals */
+
+struct DerivedMesh *modwrap_applyModifier(
+ ModifierData *md, Object *ob,
+ struct DerivedMesh *dm,
+ ModifierApplyFlag flag)
+{
+ ModifierTypeInfo *mti = modifierType_getInfo(md->type);
+ BLI_assert(CustomData_has_layer(&dm->polyData, CD_NORMAL) == false);
+
+ if (mti->dependsOnNormals && mti->dependsOnNormals(md)) {
+ DM_ensure_normals(dm);
+ }
+ return mti->applyModifier(md, ob, dm, flag);
+}
+
+struct DerivedMesh *modwrap_applyModifierEM(
+ ModifierData *md, Object *ob,
+ struct BMEditMesh *em,
+ DerivedMesh *dm,
+ ModifierApplyFlag flag)
+{
+ ModifierTypeInfo *mti = modifierType_getInfo(md->type);
+ BLI_assert(CustomData_has_layer(&dm->polyData, CD_NORMAL) == false);
+
+ if (mti->dependsOnNormals && mti->dependsOnNormals(md)) {
+ DM_ensure_normals(dm);
+ }
+ return mti->applyModifierEM(md, ob, em, dm, flag);
+}
+
+void modwrap_deformVerts(
+ ModifierData *md, Object *ob,
+ DerivedMesh *dm,
+ float (*vertexCos)[3], int numVerts,
+ ModifierApplyFlag flag)
+{
+ ModifierTypeInfo *mti = modifierType_getInfo(md->type);
+ BLI_assert(!dm || CustomData_has_layer(&dm->polyData, CD_NORMAL) == false);
+
+ if (dm && mti->dependsOnNormals && mti->dependsOnNormals(md)) {
+ DM_ensure_normals(dm);
+ }
+ mti->deformVerts(md, ob, dm, vertexCos, numVerts, flag);
+}
+
+void modwrap_deformVertsEM(
+ ModifierData *md, Object *ob,
+ struct BMEditMesh *em, DerivedMesh *dm,
+ float (*vertexCos)[3], int numVerts)
+{
+ ModifierTypeInfo *mti = modifierType_getInfo(md->type);
+ BLI_assert(!dm || CustomData_has_layer(&dm->polyData, CD_NORMAL) == false);
+
+ if (dm && mti->dependsOnNormals && mti->dependsOnNormals(md)) {
+ DM_ensure_normals(dm);
+ }
+ mti->deformVertsEM(md, ob, em, dm, vertexCos, numVerts);
+}
+/* end modifier callback wrappers */
diff --git a/source/blender/blenlib/BLI_path_util.h b/source/blender/blenlib/BLI_path_util.h
index a36627bd903..e0a34e35acc 100644
--- a/source/blender/blenlib/BLI_path_util.h
+++ b/source/blender/blenlib/BLI_path_util.h
@@ -162,7 +162,7 @@ void BLI_path_rel(char *file, const char *relfile);
bool BLI_path_is_rel(const char *path);
/* path string comparisons: case-insensitive for Windows, case-sensitive otherwise */
-#ifdef WIN32
+#if defined(WIN32)
# define BLI_path_cmp BLI_strcasecmp
# define BLI_path_ncmp BLI_strncasecmp
#else
diff --git a/source/blender/blenlib/BLI_utildefines.h b/source/blender/blenlib/BLI_utildefines.h
index 224d02163cb..4d80080ed86 100644
--- a/source/blender/blenlib/BLI_utildefines.h
+++ b/source/blender/blenlib/BLI_utildefines.h
@@ -263,9 +263,21 @@
#define STACK_PUSH(stack, val) (void)((stack)[(_##stack##_index)++] = val)
#define STACK_PUSH_RET(stack) ((void)stack, ((stack)[(_##stack##_index)++]))
#define STACK_PUSH_RET_PTR(stack) ((void)stack, &((stack)[(_##stack##_index)++]))
-#define STACK_POP(stack) ((_##stack##_index) ? ((stack)[--(_##stack##_index)]) : NULL)
-#define STACK_POP_ELSE(stack, r) ((_##stack##_index) ? ((stack)[--(_##stack##_index)]) : r)
+#define STACK_POP(stack) ((_##stack##_index) ? ((stack)[--(_##stack##_index)]) : NULL)
+#define STACK_POP_PTR(stack) ((_##stack##_index) ? &((stack)[--(_##stack##_index)]) : NULL)
+#define STACK_POP_ELSE(stack, r) ((_##stack##_index) ? ((stack)[--(_##stack##_index)]) : r)
#define STACK_FREE(stack) ((void)stack)
+#ifdef __GNUC__
+#define STACK_SWAP(stack_a, stack_b) { \
+ SWAP(typeof(stack_a), stack_a, stack_b); \
+ SWAP(unsigned int, _##stack_a##_index, _##stack_b##_index); \
+ } (void)0
+#else
+#define STACK_SWAP(stack_a, stack_b) { \
+ SWAP(void *, stack_a, stack_b); \
+ SWAP(unsigned int, _##stack_a##_index, _##stack_b##_index); \
+ } (void)0
+#endif
/* array helpers */
#define ARRAY_LAST_ITEM(arr_start, arr_dtype, elem_size, tot) \
diff --git a/source/blender/blenlib/intern/BLI_heap.c b/source/blender/blenlib/intern/BLI_heap.c
index a8fdcd56abb..2da36377e55 100644
--- a/source/blender/blenlib/intern/BLI_heap.c
+++ b/source/blender/blenlib/intern/BLI_heap.c
@@ -30,6 +30,7 @@
* \ingroup bli
*/
+#include <stdlib.h>
#include <string.h>
#include "MEM_guardedalloc.h"
@@ -207,6 +208,8 @@ void *BLI_heap_popmin(Heap *heap)
{
void *ptr = heap->tree[0]->ptr;
+ BLI_assert(heap->size == 0);
+
heap->tree[0]->ptr = heap->freenodes;
heap->freenodes = heap->tree[0];
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index d44e3fd4948..07ed2f18111 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -9605,6 +9605,7 @@ static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead)
link_list(fd, &user->themes);
link_list(fd, &user->user_keymaps);
link_list(fd, &user->addons);
+ link_list(fd, &user->autoexec_paths);
for (keymap=user->user_keymaps.first; keymap; keymap=keymap->next) {
keymap->modal_items= NULL;
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index d8bf1a5e4c4..9b6699f3f21 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -860,6 +860,7 @@ static void write_userdef(WriteData *wd)
wmKeyMapItem *kmi;
wmKeyMapDiffItem *kmdi;
bAddon *bext;
+ bPathCompare *path_cmp;
uiStyle *style;
writestruct(wd, USER, "UserDef", 1, &U);
@@ -888,6 +889,10 @@ static void write_userdef(WriteData *wd)
IDP_WriteProperty(bext->prop, wd);
}
}
+
+ for (path_cmp = U.autoexec_paths.first; path_cmp; path_cmp = path_cmp->next) {
+ writestruct(wd, DATA, "bPathCompare", 1, path_cmp);
+ }
for (style= U.uistyles.first; style; style= style->next) {
writestruct(wd, DATA, "uiStyle", 1, style);
diff --git a/source/blender/bmesh/bmesh_class.h b/source/blender/bmesh/bmesh_class.h
index 8d95ab85df8..c92b049eafb 100644
--- a/source/blender/bmesh/bmesh_class.h
+++ b/source/blender/bmesh/bmesh_class.h
@@ -290,6 +290,6 @@ extern void bpy_bm_generic_invalidate(struct BPy_BMGeneric *self);
* but should not error on valid cases */
#define BM_LOOP_RADIAL_MAX 10000
#define BM_NGON_MAX 100000
-#define BM_OMP_LIMIT 10000 /* setting zero so we can catch bugs in OpenMP/BMesh */
+#define BM_OMP_LIMIT 0 /* 10000 */ /* setting zero so we can catch bugs in OpenMP/BMesh */
#endif /* __BMESH_CLASS_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_marking.c b/source/blender/bmesh/intern/bmesh_marking.c
index 2608a79d455..313d76721fa 100644
--- a/source/blender/bmesh/intern/bmesh_marking.c
+++ b/source/blender/bmesh/intern/bmesh_marking.c
@@ -498,6 +498,8 @@ static int bm_mesh_flag_count(BMesh *bm, const char htype, const char hflag,
BMIter iter;
int tot = 0;
+ BLI_assert((htype & ~BM_ALL_NOLOOP) == 0);
+
if (htype & BM_VERT) {
for (ele = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL); ele; ele = BM_iter_step(&iter)) {
if (respecthide && BM_elem_flag_test(ele, BM_ELEM_HIDDEN)) continue;
@@ -803,6 +805,8 @@ void BM_mesh_elem_hflag_disable_test(BMesh *bm, const char htype, const char hfl
int i;
+ BLI_assert((htype & ~BM_ALL_NOLOOP) == 0);
+
if (hflag & BM_ELEM_SELECT) {
BM_select_history_clear(bm);
}
@@ -872,6 +876,8 @@ void BM_mesh_elem_hflag_enable_test(BMesh *bm, const char htype, const char hfla
BMElem *ele;
int i;
+ BLI_assert((htype & ~BM_ALL_NOLOOP) == 0);
+
if (hflag & BM_ELEM_SELECT) {
BM_select_history_clear(bm);
}
diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c
index 79dacaad2fa..4027d4b2c19 100644
--- a/source/blender/bmesh/intern/bmesh_mesh.c
+++ b/source/blender/bmesh/intern/bmesh_mesh.c
@@ -628,6 +628,8 @@ void BM_mesh_elem_index_validate(BMesh *bm, const char *location, const char *fu
*/
int BM_mesh_elem_count(BMesh *bm, const char htype)
{
+ BLI_assert((htype & ~BM_ALL_NOLOOP) == 0);
+
switch (htype) {
case BM_VERT: return bm->totvert;
case BM_EDGE: return bm->totedge;
diff --git a/source/blender/bmesh/tools/bmesh_path.c b/source/blender/bmesh/tools/bmesh_path.c
index eda252f18f5..9fc1996e51a 100644
--- a/source/blender/bmesh/tools/bmesh_path.c
+++ b/source/blender/bmesh/tools/bmesh_path.c
@@ -144,7 +144,8 @@ LinkNode *BM_mesh_calc_path_vert(
BLI_heap_insert(heap, 0.0f, v_src);
cost[BM_elem_index_get(v_src)] = 0.0f;
- while ((v = BLI_heap_popmin(heap))) {
+ while (!BLI_heap_is_empty(heap)) {
+ v = BLI_heap_popmin(heap);
if (v == v_dst)
break;
@@ -261,7 +262,8 @@ LinkNode *BM_mesh_calc_path_edge(
BLI_heap_insert(heap, 0.0f, e_src);
cost[BM_elem_index_get(e_src)] = 0.0f;
- while ((e = BLI_heap_popmin(heap))) {
+ while (!BLI_heap_is_empty(heap)) {
+ e = BLI_heap_popmin(heap);
if (e == e_dst)
break;
@@ -386,7 +388,8 @@ LinkNode *BM_mesh_calc_path_face(
BLI_heap_insert(heap, 0.0f, f_src);
cost[BM_elem_index_get(f_src)] = 0.0f;
- while ((f = BLI_heap_popmin(heap))) {
+ while (!BLI_heap_is_empty(heap)) {
+ f = BLI_heap_popmin(heap);
if (f == f_dst)
break;
diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h
index 097ea477501..f35edb70251 100644
--- a/source/blender/editors/include/ED_mesh.h
+++ b/source/blender/editors/include/ED_mesh.h
@@ -76,6 +76,8 @@ struct MeshStatVis;
/* editmesh_utils.c */
+void EDBM_verts_mirror_cache_begin_ex(struct BMEditMesh *em, const bool use_self, const bool use_select,
+ const bool is_topo, float maxdist, int *r_index);
void EDBM_verts_mirror_cache_begin(struct BMEditMesh *em, const bool use_self, const bool use_select);
void EDBM_verts_mirror_apply(struct BMEditMesh *em, const int sel_from, const int sel_to);
struct BMVert *EDBM_verts_mirror_get(struct BMEditMesh *em, struct BMVert *v);
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index cb2f3e3286e..86e51b201d9 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -304,7 +304,7 @@ typedef struct uiSearchItems uiSearchItems;
typedef void (*uiButHandleFunc)(struct bContext *C, void *arg1, void *arg2);
typedef void (*uiButHandleRenameFunc)(struct bContext *C, void *arg, char *origstr);
typedef void (*uiButHandleNFunc)(struct bContext *C, void *argN, void *arg2);
-typedef void (*uiButCompleteFunc)(struct bContext *C, char *str, void *arg);
+typedef bool (*uiButCompleteFunc)(struct bContext *C, char *str, void *arg);
typedef void (*uiButSearchFunc)(const struct bContext *C, void *arg, const char *str, uiSearchItems *items);
typedef void (*uiBlockHandleFunc)(struct bContext *C, void *arg, int event);
@@ -644,7 +644,7 @@ typedef struct AutoComplete AutoComplete;
AutoComplete *autocomplete_begin(const char *startname, size_t maxlen);
void autocomplete_do_name(AutoComplete *autocpl, const char *name);
-void autocomplete_end(AutoComplete *autocpl, char *autoname);
+bool autocomplete_end(AutoComplete *autocpl, char *autoname);
/* Panels
*
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index 5a1ba8f31f0..19eb978a01e 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -443,17 +443,24 @@ void uiExplicitBoundsBlock(uiBlock *block, int minx, int miny, int maxx, int max
static int ui_but_float_precision(uiBut *but, double value)
{
int prec;
+ const double pow10_neg[PRECISION_FLOAT_MAX + 1] = {1.0, 0.1, 0.01, 0.001, 0.0001, 0.00001, 0.000001};
/* first check if prec is 0 and fallback to a simple default */
if ((prec = (int)but->a2) == -1) {
prec = (but->hardmax < 10.001f) ? 3 : 2;
}
+ BLI_assert(prec <= PRECISION_FLOAT_MAX);
+ BLI_assert(pow10_neg[prec] == pow(10, -prec));
+
/* check on the number of decimal places need to display
* the number, this is so 0.00001 is not displayed as 0.00,
* _but_, this is only for small values si 10.0001 will not get
* the same treatment */
- if (value != 0.0 && (value = ABS(value)) < 0.1) {
+ value = ABS(value);
+ if ((value < pow10_neg[prec]) &&
+ (value > (1.0 / PRECISION_FLOAT_MAX_POW)))
+ {
int value_i = (int)((value * PRECISION_FLOAT_MAX_POW) + 0.5);
if (value_i != 0) {
const int prec_span = 3; /* show: 0.01001, 5 would allow 0.0100001 for eg. */
@@ -3086,16 +3093,21 @@ void autocomplete_do_name(AutoComplete *autocpl, const char *name)
}
}
-void autocomplete_end(AutoComplete *autocpl, char *autoname)
+bool autocomplete_end(AutoComplete *autocpl, char *autoname)
{
- if (autocpl->truncate[0])
+ bool change = false;
+ if (autocpl->truncate[0]) {
BLI_strncpy(autoname, autocpl->truncate, autocpl->maxlen);
+ change = true;
+ }
else {
- if (autoname != autocpl->startname) /* don't copy a string over its self */
+ if (autoname != autocpl->startname) { /* don't copy a string over its self */
BLI_strncpy(autoname, autocpl->startname, autocpl->maxlen);
+ }
}
MEM_freeN(autocpl->truncate);
MEM_freeN(autocpl);
+ return change;
}
static void ui_check_but_and_iconize(uiBut *but, int icon)
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index a9378d11cc3..7aee228ddaa 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -1828,20 +1828,19 @@ static bool ui_textedit_delete(uiBut *but, uiHandleButtonData *data, int directi
static bool ui_textedit_autocomplete(bContext *C, uiBut *but, uiHandleButtonData *data)
{
char *str;
- /* TODO, should return false if it cant autocomp. */
- bool changed = true;
+ bool change = true;
str = data->str;
if (data->searchbox)
- ui_searchbox_autocomplete(C, data->searchbox, but, data->str);
+ change = ui_searchbox_autocomplete(C, data->searchbox, but, data->str);
else
- but->autocomplete_func(C, str, but->autofunc_arg);
+ change = but->autocomplete_func(C, str, but->autofunc_arg);
but->pos = strlen(str);
but->selsta = but->selend = but->pos;
- return changed;
+ return change;
}
/* mode for ui_textedit_copypaste() */
@@ -6581,7 +6580,8 @@ static void ui_mouse_motion_towards_reinit(uiPopupBlockHandle *menu, const int x
ui_mouse_motion_towards_init_ex(menu, xy, true);
}
-static bool ui_mouse_motion_towards_check(uiBlock *block, uiPopupBlockHandle *menu, const int xy[2])
+static bool ui_mouse_motion_towards_check(uiBlock *block, uiPopupBlockHandle *menu, const int xy[2],
+ const bool use_wiggle_room)
{
float p1[2], p2[2], p3[2], p4[2];
float oldp[2] = {menu->towards_xy[0], menu->towards_xy[1]};
@@ -6615,8 +6615,8 @@ static bool ui_mouse_motion_towards_check(uiBlock *block, uiPopupBlockHandle *me
p4[1] = rect_px.ymax + margin;
/* allow for some wiggle room, if the user moves a few pixels away,
- * don't immediately quit */
- {
+ * don't immediately quit (only for top level menus) */
+ if (use_wiggle_room) {
const float cent[2] = {
BLI_rctf_cent_x(&rect_px),
BLI_rctf_cent_y(&rect_px)};
@@ -6789,7 +6789,8 @@ static int ui_handle_menu_button(bContext *C, const wmEvent *event, uiPopupBlock
return retval;
}
-static int ui_handle_menu_event(bContext *C, const wmEvent *event, uiPopupBlockHandle *menu, int level)
+static int ui_handle_menu_event(bContext *C, const wmEvent *event, uiPopupBlockHandle *menu,
+ int level, const bool is_parent_inside)
{
ARegion *ar;
uiBlock *block;
@@ -7130,7 +7131,7 @@ static int ui_handle_menu_event(bContext *C, const wmEvent *event, uiPopupBlockH
menu->menuretval = UI_RETURN_CANCEL | UI_RETURN_POPUP_OK;
}
else {
- ui_mouse_motion_towards_check(block, menu, &event->x);
+ ui_mouse_motion_towards_check(block, menu, &event->x, is_parent_inside == false);
/* check mouse moving outside of the menu */
if (inside == 0 && (block->flag & UI_BLOCK_MOVEMOUSE_QUIT)) {
@@ -7233,7 +7234,8 @@ static int ui_handle_menu_return_submenu(bContext *C, const wmEvent *event, uiPo
return WM_UI_HANDLER_BREAK;
}
-static int ui_handle_menus_recursive(bContext *C, const wmEvent *event, uiPopupBlockHandle *menu, int level)
+static int ui_handle_menus_recursive(bContext *C, const wmEvent *event, uiPopupBlockHandle *menu,
+ int level, const bool is_parent_inside)
{
uiBut *but;
uiHandleButtonData *data;
@@ -7246,8 +7248,21 @@ static int ui_handle_menus_recursive(bContext *C, const wmEvent *event, uiPopupB
data = (but) ? but->active : NULL;
submenu = (data) ? data->menu : NULL;
- if (submenu)
- retval = ui_handle_menus_recursive(C, event, submenu, level + 1);
+ if (submenu) {
+ bool inside = false;
+
+ if (is_parent_inside == false) {
+ int mx, my;
+ uiBlock *block = menu->region->uiblocks.first;
+
+ mx = event->x;
+ my = event->y;
+ ui_window_to_block(menu->region, block, &mx, &my);
+ inside = BLI_rctf_isect_pt(&block->rect, mx, my);
+ }
+
+ retval = ui_handle_menus_recursive(C, event, submenu, level + 1, is_parent_inside || inside);
+ }
/* now handle events for our own menu */
if (retval == WM_UI_HANDLER_CONTINUE || event->type == TIMER) {
@@ -7275,7 +7290,7 @@ static int ui_handle_menus_recursive(bContext *C, const wmEvent *event, uiPopupB
}
}
else {
- retval = ui_handle_menu_event(C, event, menu, level);
+ retval = ui_handle_menu_event(C, event, menu, level, is_parent_inside);
}
}
@@ -7371,7 +7386,7 @@ static int ui_handler_region_menu(bContext *C, const wmEvent *event, void *UNUSE
/* handle events for menus and their buttons recursively,
* this will handle events from the top to the bottom menu */
if (data->menu)
- retval = ui_handle_menus_recursive(C, event, data->menu, 0);
+ retval = ui_handle_menus_recursive(C, event, data->menu, 0, false);
/* handle events for the activated button */
if ((data->menu && (retval == WM_UI_HANDLER_CONTINUE)) ||
@@ -7417,7 +7432,7 @@ static int ui_handler_popup(bContext *C, const wmEvent *event, void *userdata)
retval = WM_UI_HANDLER_CONTINUE;
}
- ui_handle_menus_recursive(C, event, menu, 0);
+ ui_handle_menus_recursive(C, event, menu, 0, false);
/* free if done, does not free handle itself */
if (menu->menuretval) {
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 9de608f2730..a6076b8df78 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -471,7 +471,7 @@ ARegion *ui_searchbox_create(struct bContext *C, struct ARegion *butregion, uiBu
bool ui_searchbox_inside(struct ARegion *ar, int x, int y);
int ui_searchbox_find_index(struct ARegion *ar, const char *name);
void ui_searchbox_update(struct bContext *C, struct ARegion *ar, uiBut *but, const bool reset);
-void ui_searchbox_autocomplete(struct bContext *C, struct ARegion *ar, uiBut *but, char *str);
+bool ui_searchbox_autocomplete(struct bContext *C, struct ARegion *ar, uiBut *but, char *str);
void ui_searchbox_event(struct bContext *C, struct ARegion *ar, uiBut *but, const struct wmEvent *event);
bool ui_searchbox_apply(uiBut *but, struct ARegion *ar);
void ui_searchbox_free(struct bContext *C, struct ARegion *ar);
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index b6575f4eca0..ef839f1d143 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -525,7 +525,7 @@ static void ui_item_enum_expand(uiLayout *layout, uiBlock *block, PointerRNA *pt
name = (!uiname || uiname[0]) ? item->name : "";
icon = item->icon;
value = item->value;
- itemw = ui_text_icon_width(block->curlayout, name, icon, 0);
+ itemw = ui_text_icon_width(block->curlayout, icon_only ? "" : name, icon, 0);
if (icon && name[0] && !icon_only)
but = uiDefIconTextButR_prop(block, ROW, 0, icon, name, 0, 0, itemw, h, ptr, prop, -1, 0, value, -1, -1, NULL);
diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c
index b764c70b111..1ff46004bdf 100644
--- a/source/blender/editors/interface/interface_regions.c
+++ b/source/blender/editors/interface/interface_regions.c
@@ -1039,18 +1039,20 @@ void ui_searchbox_update(bContext *C, ARegion *ar, uiBut *but, const bool reset)
ED_region_tag_redraw(ar);
}
-void ui_searchbox_autocomplete(bContext *C, ARegion *ar, uiBut *but, char *str)
+bool ui_searchbox_autocomplete(bContext *C, ARegion *ar, uiBut *but, char *str)
{
uiSearchboxData *data = ar->regiondata;
+ bool changed = false;
if (str[0]) {
data->items.autocpl = autocomplete_begin(str, ui_get_but_string_max_length(but));
but->search_func(C, but->search_arg, but->editstr, &data->items);
- autocomplete_end(data->items.autocpl, str);
+ changed = autocomplete_end(data->items.autocpl, str);
data->items.autocpl = NULL;
}
+ return changed;
}
static void ui_searchbox_region_draw_cb(const bContext *UNUSED(C), ARegion *ar)
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index 00eabad729e..d8efb972ce9 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -2286,8 +2286,7 @@ static void ui_draw_separator(const rcti *rect, uiWidgetColors *wcol)
}
/* ************ button callbacks, draw ***************** */
-
-static void widget_numbut(uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign)
+static void widget_numbut_draw(uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign, bool emboss)
{
uiWidgetBase wtb;
const float rad = 0.5f * BLI_rcti_size_y(rect);
@@ -2298,9 +2297,10 @@ static void widget_numbut(uiWidgetColors *wcol, rcti *rect, int state, int round
widget_init(&wtb);
- /* fully rounded */
- round_box_edges(&wtb, roundboxalign, rect, rad);
-
+ if (!emboss) {
+ round_box_edges(&wtb, roundboxalign, rect, rad);
+ }
+
/* decoration */
if (!(state & UI_TEXTINPUT)) {
widget_num_tria(&wtb.tria1, rect, 0.6f, 'l');
@@ -2314,6 +2314,19 @@ static void widget_numbut(uiWidgetColors *wcol, rcti *rect, int state, int round
rect->xmax -= textofs;
}
+static void widget_numbut(uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign)
+{
+ widget_numbut_draw(wcol, rect, state, roundboxalign, false);
+}
+
+/*
+ * Draw number buttons still with triangles when field is not embossed
+*/
+static void widget_numbut_embossn(uiBut *UNUSED(but), uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign)
+{
+ widget_numbut_draw(wcol, rect, state, roundboxalign, true);
+}
+
int ui_link_bezier_points(const rcti *rect, float coord_array[][2], int resol)
{
float dist, vec[4][2];
@@ -2671,7 +2684,7 @@ static void widget_normal(uiBut *but, uiWidgetColors *wcol, rcti *rect, int UNUS
ui_draw_but_NORMAL(but, wcol, rect);
}
-static void widget_icon_has_anim(uiBut *UNUSED(but), uiWidgetColors *wcol, rcti *rect, int state, int UNUSED(roundboxalign))
+static void widget_icon_has_anim(uiBut *but, uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign)
{
if (state & (UI_BUT_ANIMATED | UI_BUT_ANIMATED_KEY | UI_BUT_DRIVEN | UI_BUT_REDALERT)) {
uiWidgetBase wtb;
@@ -2685,6 +2698,11 @@ static void widget_icon_has_anim(uiBut *UNUSED(but), uiWidgetColors *wcol, rcti
round_box_edges(&wtb, UI_CNR_ALL, rect, rad);
widgetbase_draw(&wtb, wcol);
}
+ else if (but->type == NUM) {
+ /* Draw number buttons still with left/right
+ * triangles when field is not embossed */
+ widget_numbut_embossn(but, wcol, rect, state, roundboxalign);
+ }
}
diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c
index fa857edb6fc..963b9cf134b 100644
--- a/source/blender/editors/mesh/editmesh_utils.c
+++ b/source/blender/editors/mesh/editmesh_utils.c
@@ -507,17 +507,20 @@ bool EDBM_index_arrays_check(BMEditMesh *em)
BMVert *EDBM_vert_at_index(BMEditMesh *em, int index)
{
- return em->vert_index && index < em->bm->totvert ? em->vert_index[index] : NULL;
+ BLI_assert((index >= 0) && (index < em->bm->totvert));
+ return em->vert_index[index];
}
BMEdge *EDBM_edge_at_index(BMEditMesh *em, int index)
{
- return em->edge_index && index < em->bm->totedge ? em->edge_index[index] : NULL;
+ BLI_assert((index >= 0) && (index < em->bm->totedge));
+ return em->edge_index[index];
}
BMFace *EDBM_face_at_index(BMEditMesh *em, int index)
{
- return (em->face_index && index < em->bm->totface && index >= 0) ? em->face_index[index] : NULL;
+ BLI_assert((index >= 0) && (index < em->bm->totface));
+ return em->face_index[index];
}
void EDBM_selectmode_flush_ex(BMEditMesh *em, const short selectmode)
@@ -1144,46 +1147,58 @@ static BMVert *cache_mirr_intptr_as_bmvert(intptr_t *index_lookup, int index)
* preference */
#define BM_SEARCH_MAXDIST_MIRR 0.00002f
#define BM_CD_LAYER_ID "__mirror_index"
-void EDBM_verts_mirror_cache_begin(BMEditMesh *em, const bool use_self, const bool use_select)
+/**
+ * \param em Editmesh.
+ * \param use_self Allow a vertex to point to its self (middle verts).
+ * \param use_select Restrict to selected verts.
+ * \param is_topo Use topology mirror.
+ * \param maxdist Distance for close point test.
+ * \param r_index Optional array to write into, as an alternative to a customdata layer (length of total verts).
+ */
+void EDBM_verts_mirror_cache_begin_ex(BMEditMesh *em, const bool use_self, const bool use_select,
+ /* extra args */
+ const bool is_topo, float maxdist, int *r_index)
{
Mesh *me = (Mesh *)em->ob->data;
BMesh *bm = em->bm;
BMIter iter;
BMVert *v;
- bool topo = false;
int cd_vmirr_offset;
+ int i;
/* one or the other is used depending if topo is enabled */
struct BMBVHTree *tree = NULL;
MirrTopoStore_t mesh_topo_store = {NULL, -1, -1, -1};
- if (me && (me->editflag & ME_EDIT_MIRROR_TOPO)) {
- topo = 1;
- }
-
EDBM_index_arrays_ensure(em, BM_VERT);
- em->mirror_cdlayer = CustomData_get_named_layer_index(&bm->vdata, CD_PROP_INT, BM_CD_LAYER_ID);
- if (em->mirror_cdlayer == -1) {
- BM_data_layer_add_named(bm, &bm->vdata, CD_PROP_INT, BM_CD_LAYER_ID);
- em->mirror_cdlayer = CustomData_get_named_layer_index(&bm->vdata, CD_PROP_INT, BM_CD_LAYER_ID);
- }
+ if (r_index == NULL) {
+ const char *layer_id = BM_CD_LAYER_ID;
+ em->mirror_cdlayer = CustomData_get_named_layer_index(&bm->vdata, CD_PROP_INT, layer_id);
+ if (em->mirror_cdlayer == -1) {
+ BM_data_layer_add_named(bm, &bm->vdata, CD_PROP_INT, layer_id);
+ em->mirror_cdlayer = CustomData_get_named_layer_index(&bm->vdata, CD_PROP_INT, layer_id);
+ }
- cd_vmirr_offset = CustomData_get_n_offset(&bm->vdata, CD_PROP_INT,
- em->mirror_cdlayer - CustomData_get_layer_index(&bm->vdata, CD_PROP_INT));
+ cd_vmirr_offset = CustomData_get_n_offset(&bm->vdata, CD_PROP_INT,
+ em->mirror_cdlayer - CustomData_get_layer_index(&bm->vdata, CD_PROP_INT));
- bm->vdata.layers[em->mirror_cdlayer].flag |= CD_FLAG_TEMPORARY;
+ bm->vdata.layers[em->mirror_cdlayer].flag |= CD_FLAG_TEMPORARY;
+ }
BM_mesh_elem_index_ensure(bm, BM_VERT);
- if (topo) {
+ if (is_topo) {
ED_mesh_mirrtopo_init(me, -1, &mesh_topo_store, true);
}
else {
tree = BKE_bmbvh_new(em, 0, NULL, false);
}
- BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
+#define VERT_INTPTR(_v, _i) r_index ? &r_index[_i] : BM_ELEM_CD_GET_VOID_P(_v, cd_vmirr_offset);
+
+ BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) {
+ BLI_assert(BM_elem_index_get(v) == i);
/* temporary for testing, check for selection */
if (use_select && !BM_elem_flag_test(v, BM_ELEM_SELECT)) {
@@ -1191,20 +1206,21 @@ void EDBM_verts_mirror_cache_begin(BMEditMesh *em, const bool use_self, const bo
}
else {
BMVert *v_mirr;
- int *idx = BM_ELEM_CD_GET_VOID_P(v, cd_vmirr_offset);
+ int *idx = VERT_INTPTR(v, i);
- if (topo) {
- v_mirr = cache_mirr_intptr_as_bmvert(mesh_topo_store.index_lookup, BM_elem_index_get(v));
+ if (is_topo) {
+ v_mirr = cache_mirr_intptr_as_bmvert(mesh_topo_store.index_lookup, i);
}
else {
float co[3] = {-v->co[0], v->co[1], v->co[2]};
- v_mirr = BKE_bmbvh_find_vert_closest(tree, co, BM_SEARCH_MAXDIST_MIRR);
+ v_mirr = BKE_bmbvh_find_vert_closest(tree, co, maxdist);
}
if (v_mirr && (use_self || (v_mirr != v))) {
- *idx = BM_elem_index_get(v_mirr);
- idx = BM_ELEM_CD_GET_VOID_P(v_mirr, cd_vmirr_offset);
- *idx = BM_elem_index_get(v);
+ const int i_mirr = BM_elem_index_get(v_mirr);
+ *idx = i_mirr;
+ idx = VERT_INTPTR(v_mirr, i_mirr);
+ *idx = i;
}
else {
*idx = -1;
@@ -1213,8 +1229,9 @@ void EDBM_verts_mirror_cache_begin(BMEditMesh *em, const bool use_self, const bo
}
+#undef VERT_INTPTR
- if (topo) {
+ if (is_topo) {
ED_mesh_mirrtopo_free(&mesh_topo_store);
}
else {
@@ -1222,6 +1239,18 @@ void EDBM_verts_mirror_cache_begin(BMEditMesh *em, const bool use_self, const bo
}
}
+void EDBM_verts_mirror_cache_begin(BMEditMesh *em, const bool use_self, const bool use_select)
+{
+ Mesh *me = (Mesh *)em->ob->data;
+ bool is_topo;
+
+ is_topo = (me && (me->editflag & ME_EDIT_MIRROR_TOPO));
+
+ EDBM_verts_mirror_cache_begin_ex(em, use_self, use_select,
+ /* extra args */
+ is_topo, BM_SEARCH_MAXDIST_MIRR, NULL);
+}
+
BMVert *EDBM_verts_mirror_get(BMEditMesh *em, BMVert *v)
{
int *mirr = CustomData_bmesh_get_layer_n(&em->bm->vdata, v->head.data, em->mirror_cdlayer);
diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c
index 74f1515fe74..8da953c4f84 100644
--- a/source/blender/editors/object/object_vgroup.c
+++ b/source/blender/editors/object/object_vgroup.c
@@ -2905,9 +2905,9 @@ void OBJECT_OT_vertex_group_remove_from(wmOperatorType *ot)
ot->flag = /*OPTYPE_REGISTER|*/ OPTYPE_UNDO;
/* properties */
- prop = RNA_def_boolean(ot->srna, "use_all_groups", 0, "All Groups", "Remove from all Groups");
+ prop = RNA_def_boolean(ot->srna, "use_all_groups", 0, "All Groups", "Remove from all groups");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
- prop = RNA_def_boolean(ot->srna, "use_all_verts", 0, "All verts", "Clear Active Group");
+ prop = RNA_def_boolean(ot->srna, "use_all_verts", 0, "All Verts", "Clear the active group");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
diff --git a/source/blender/editors/screen/screendump.c b/source/blender/editors/screen/screendump.c
index 20edd3d32e7..527715cdbd3 100644
--- a/source/blender/editors/screen/screendump.c
+++ b/source/blender/editors/screen/screendump.c
@@ -220,7 +220,7 @@ static int screenshot_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(
return OPERATOR_CANCELLED;
}
-static int screenshot_check(bContext *UNUSED(C), wmOperator *op)
+static bool screenshot_check(bContext *UNUSED(C), wmOperator *op)
{
ScreenshotData *scd = op->customdata;
return WM_operator_filesel_ensure_ext_imtype(op, &scd->im_format);
diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c
index 1ff7df3b041..181b32d58fc 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex.c
@@ -2145,7 +2145,7 @@ struct WPaintData {
};
/* ensure we have data on wpaint start, add if needed */
-static int wpaint_ensure_data(bContext *C, wmOperator *op)
+static bool wpaint_ensure_data(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
Object *ob = CTX_data_active_object(C);
@@ -3390,6 +3390,10 @@ static int paint_weight_gradient_exec(bContext *C, wmOperator *op)
vert_cache = gesture->userdata;
}
else {
+ if (wpaint_ensure_data(C, op) == FALSE) {
+ return OPERATOR_CANCELLED;
+ }
+
data.is_init = true;
vert_cache = MEM_mallocN(sizeof(DMGradient_vertStore) * me->totvert, __func__);
}
diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c
index 0cb0a3d6e5c..a2189f6237c 100644
--- a/source/blender/editors/sound/sound_ops.c
+++ b/source/blender/editors/sound/sound_ops.c
@@ -391,7 +391,7 @@ static const char *snd_ext_sound[] = {
NULL
};
-static int sound_mixdown_check(bContext *UNUSED(C), wmOperator *op)
+static bool sound_mixdown_check(bContext *UNUSED(C), wmOperator *op)
{
AUD_Container container = RNA_enum_get(op->ptr, "container");
diff --git a/source/blender/editors/space_buttons/CMakeLists.txt b/source/blender/editors/space_buttons/CMakeLists.txt
index b20301cfc3b..9e045a39a0c 100644
--- a/source/blender/editors/space_buttons/CMakeLists.txt
+++ b/source/blender/editors/space_buttons/CMakeLists.txt
@@ -35,7 +35,6 @@ set(INC_SYS
set(SRC
buttons_context.c
- buttons_header.c
buttons_ops.c
buttons_texture.c
space_buttons.c
diff --git a/source/blender/editors/space_buttons/buttons_header.c b/source/blender/editors/space_buttons/buttons_header.c
deleted file mode 100644
index f9742121e99..00000000000
--- a/source/blender/editors/space_buttons/buttons_header.c
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * ***** 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.
- *
- * The Original Code is Copyright (C) 2008 Blender Foundation.
- * All rights reserved.
- *
- *
- * Contributor(s): Blender Foundation
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file blender/editors/space_buttons/buttons_header.c
- * \ingroup spbuttons
- */
-
-
-#include <string.h>
-#include <stdio.h>
-
-#include "BLI_blenlib.h"
-#include "BLI_utildefines.h"
-
-#include "BLF_translation.h"
-
-#include "BKE_context.h"
-#include "BKE_modifier.h"
-#include "BKE_paint.h"
-#include "BKE_scene.h"
-
-#include "ED_buttons.h"
-#include "ED_screen.h"
-#include "ED_types.h"
-
-#include "DNA_brush_types.h"
-#include "DNA_object_force.h"
-#include "DNA_object_types.h"
-
-#include "UI_interface.h"
-#include "UI_resources.h"
-#include "UI_view2d.h"
-
-#include "buttons_intern.h"
-
-
-#define B_CONTEXT_SWITCH 101
-
-static void set_texture_context(const bContext *C, SpaceButs *sbuts)
-{
- Scene *scene = CTX_data_scene(C);
-
- if (BKE_scene_use_new_shading_nodes(scene)) {
- return; /* No texture context in new shading mode */
- }
-
- if ((sbuts->mainb == BCONTEXT_WORLD) && ED_texture_context_check_world(C)) {
- sbuts->texture_context = SB_TEXC_WORLD;
- }
- else if ((sbuts->mainb == BCONTEXT_MATERIAL) && ED_texture_context_check_material(C)) {
- sbuts->texture_context = SB_TEXC_MATERIAL;
- }
- else if ((sbuts->mainb == BCONTEXT_DATA) && ED_texture_context_check_lamp(C)) {
- sbuts->texture_context = SB_TEXC_LAMP;
- }
- else if ((sbuts->mainb == BCONTEXT_PARTICLE) && ED_texture_context_check_particles(C)) {
- sbuts->texture_context = SB_TEXC_PARTICLES;
- }
- else if ((ELEM(sbuts->mainb, BCONTEXT_MODIFIER, BCONTEXT_PHYSICS)) && ED_texture_context_check_others(C)) {
- sbuts->texture_context = SB_TEXC_OTHER;
- }
- /* Second pass: sbuts->mainbuser still contains the previous button context.
- * Useful e.g. when we switch to material, no material present, add a material, switch to texture.
- * See #35741. */
- else if ((sbuts->mainbuser == BCONTEXT_WORLD) && ED_texture_context_check_world(C)) {
- sbuts->texture_context = SB_TEXC_WORLD;
- }
- else if ((sbuts->mainbuser == BCONTEXT_MATERIAL) && ED_texture_context_check_material(C)) {
- sbuts->texture_context = SB_TEXC_MATERIAL;
- }
- else if ((sbuts->mainbuser == BCONTEXT_DATA) && ED_texture_context_check_lamp(C)) {
- sbuts->texture_context = SB_TEXC_LAMP;
- }
- else if ((sbuts->mainbuser == BCONTEXT_PARTICLE) && ED_texture_context_check_particles(C)) {
- sbuts->texture_context = SB_TEXC_PARTICLES;
- }
- else if ((ELEM(sbuts->mainbuser, BCONTEXT_MODIFIER, BCONTEXT_PHYSICS)) && ED_texture_context_check_others(C)) {
- sbuts->texture_context = SB_TEXC_OTHER;
- }
- /* Else, just be sure that current context is valid! */
- else {
- buttons_check_texture_context(C, sbuts);
- }
-}
-
-static void do_buttons_buttons(bContext *C, void *UNUSED(arg), int event)
-{
- SpaceButs *sbuts = CTX_wm_space_buts(C);
-
- if (!sbuts) /* editor type switch */
- return;
-
- switch (event) {
- case B_CONTEXT_SWITCH:
- ED_area_tag_redraw(CTX_wm_area(C));
-
- set_texture_context(C, sbuts);
-
- sbuts->preview = 1;
- break;
- }
-
- sbuts->mainbuser = sbuts->mainb;
-}
-
-#define BUT_UNIT_X (UI_UNIT_X + 2 * U.pixelsize)
-
-void buttons_header_buttons(const bContext *C, ARegion *ar)
-{
- SpaceButs *sbuts = CTX_wm_space_buts(C);
- uiBlock *block;
- uiBut *but;
- int headery = ED_area_headersize();
- int xco, yco = 0.5f * (headery - UI_UNIT_Y);
-
- buttons_context_compute(C, sbuts);
-
- block = uiBeginBlock(C, ar, __func__, UI_EMBOSS);
- uiBlockSetHandleFunc(block, do_buttons_buttons, NULL);
-
- xco = ED_area_header_switchbutton(C, block, yco);
-
- uiBlockSetEmboss(block, UI_EMBOSS);
-
- xco -= UI_UNIT_X;
-
- /* Default panels */
-
- uiBlockBeginAlign(block);
-
-#define BUTTON_HEADER_CTX(_ctx, _icon, _tip) \
- if (sbuts->pathflag & (1 << _ctx)) { \
- but = uiDefIconButS(block, ROW, B_CONTEXT_SWITCH, _icon, xco += BUT_UNIT_X, yco, BUT_UNIT_X, UI_UNIT_Y, \
- &(sbuts->mainb), 0.0, (float)_ctx, 0, 0, TIP_(_tip)); \
- uiButClearFlag(but, UI_BUT_UNDO); \
- } (void)0
-
- BUTTON_HEADER_CTX(BCONTEXT_RENDER, ICON_SCENE, N_("Render"));
- BUTTON_HEADER_CTX(BCONTEXT_RENDER_LAYER, ICON_RENDERLAYERS, N_("Render Layers"));
- BUTTON_HEADER_CTX(BCONTEXT_SCENE, ICON_SCENE_DATA, N_("Scene"));
- BUTTON_HEADER_CTX(BCONTEXT_WORLD, ICON_WORLD, N_("World"));
- BUTTON_HEADER_CTX(BCONTEXT_OBJECT, ICON_OBJECT_DATA, N_("Object"));
- BUTTON_HEADER_CTX(BCONTEXT_CONSTRAINT, ICON_CONSTRAINT, N_("Object Constraints"));
- BUTTON_HEADER_CTX(BCONTEXT_MODIFIER, ICON_MODIFIER, N_("Object Modifiers"));
- BUTTON_HEADER_CTX(BCONTEXT_DATA, sbuts->dataicon, N_("Object Data"));
- BUTTON_HEADER_CTX(BCONTEXT_BONE, ICON_BONE_DATA, N_("Bone"));
- BUTTON_HEADER_CTX(BCONTEXT_BONE_CONSTRAINT, ICON_CONSTRAINT_BONE, N_("Bone Constraints"));
- BUTTON_HEADER_CTX(BCONTEXT_MATERIAL, ICON_MATERIAL, N_("Material"));
- BUTTON_HEADER_CTX(BCONTEXT_TEXTURE, ICON_TEXTURE, N_("Textures"));
- BUTTON_HEADER_CTX(BCONTEXT_PARTICLE, ICON_PARTICLES, N_("Particles"));
- BUTTON_HEADER_CTX(BCONTEXT_PHYSICS, ICON_PHYSICS, N_("Physics"));
-
-#undef BUTTON_HEADER_CTX
-
- xco += BUT_UNIT_X;
-
- uiBlockEndAlign(block);
-
- /* always as last */
- UI_view2d_totRect_set(&ar->v2d, xco + (UI_UNIT_X / 2), BLI_rctf_size_y(&ar->v2d.tot));
-
- uiEndBlock(C, block);
- uiDrawBlock(C, block);
-}
-
-
diff --git a/source/blender/editors/space_buttons/buttons_intern.h b/source/blender/editors/space_buttons/buttons_intern.h
index 55c9bf0dffd..f294729ae97 100644
--- a/source/blender/editors/space_buttons/buttons_intern.h
+++ b/source/blender/editors/space_buttons/buttons_intern.h
@@ -97,9 +97,6 @@ typedef struct ButsContextTexture {
/* internal exports only */
-/* buttons_header.c */
-void buttons_header_buttons(const struct bContext *C, struct ARegion *ar);
-
/* buttons_context.c */
void buttons_context_compute(const struct bContext *C, struct SpaceButs *sbuts);
int buttons_context(const struct bContext *C, const char *member, struct bContextDataResult *result);
@@ -111,7 +108,6 @@ extern const char *buttons_context_dir[]; /* doc access */
/* buttons_texture.c */
void buttons_texture_context_compute(const struct bContext *C, struct SpaceButs *sbuts);
-void buttons_check_texture_context(const struct bContext *C, struct SpaceButs *sbuts);
/* buttons_ops.c */
void BUTTONS_OT_file_browse(struct wmOperatorType *ot);
diff --git a/source/blender/editors/space_buttons/buttons_texture.c b/source/blender/editors/space_buttons/buttons_texture.c
index 0b1f244a1b5..51e740e539f 100644
--- a/source/blender/editors/space_buttons/buttons_texture.c
+++ b/source/blender/editors/space_buttons/buttons_texture.c
@@ -135,8 +135,7 @@ bool ED_texture_context_check_others(const bContext *C)
return false;
}
-/* Only change texture context if current one is invalid! */
-void buttons_check_texture_context(const bContext *C, SpaceButs *sbuts)
+static void set_texture_context(const bContext *C, SpaceButs *sbuts)
{
Scene *scene = CTX_data_scene(C);
@@ -151,11 +150,27 @@ void buttons_check_texture_context(const bContext *C, SpaceButs *sbuts)
bool valid_particles = ED_texture_context_check_particles(C);
bool valid_others = ED_texture_context_check_others(C);
- if (((sbuts->texture_context == SB_TEXC_WORLD) && !valid_world) ||
- ((sbuts->texture_context == SB_TEXC_MATERIAL) && !valid_material) ||
- ((sbuts->texture_context == SB_TEXC_LAMP) && !valid_lamp) ||
- ((sbuts->texture_context == SB_TEXC_PARTICLES) && !valid_particles) ||
- ((sbuts->texture_context == SB_TEXC_OTHER) && !valid_others))
+ if ((sbuts->mainb == BCONTEXT_WORLD) && valid_world) {
+ sbuts->texture_context = SB_TEXC_WORLD;
+ }
+ else if ((sbuts->mainb == BCONTEXT_MATERIAL) && valid_material) {
+ sbuts->texture_context = SB_TEXC_MATERIAL;
+ }
+ else if ((sbuts->mainb == BCONTEXT_DATA) && valid_lamp) {
+ sbuts->texture_context = SB_TEXC_LAMP;
+ }
+ else if ((sbuts->mainb == BCONTEXT_PARTICLE) && valid_particles) {
+ sbuts->texture_context = SB_TEXC_PARTICLES;
+ }
+ else if ((ELEM(sbuts->mainb, BCONTEXT_MODIFIER, BCONTEXT_PHYSICS)) && valid_others) {
+ sbuts->texture_context = SB_TEXC_OTHER;
+ }
+ /* Else, just be sure that current context is valid! */
+ else if (((sbuts->texture_context == SB_TEXC_WORLD) && !valid_world) ||
+ ((sbuts->texture_context == SB_TEXC_MATERIAL) && !valid_material) ||
+ ((sbuts->texture_context == SB_TEXC_LAMP) && !valid_lamp) ||
+ ((sbuts->texture_context == SB_TEXC_PARTICLES) && !valid_particles) ||
+ ((sbuts->texture_context == SB_TEXC_OTHER) && !valid_others))
{
if (valid_others) {
sbuts->texture_context = SB_TEXC_OTHER;
@@ -368,7 +383,7 @@ void buttons_texture_context_compute(const bContext *C, SpaceButs *sbuts)
Scene *scene = CTX_data_scene(C);
ID *pinid = sbuts->pinid;
- buttons_check_texture_context(C, sbuts);
+ set_texture_context(C, sbuts);
if (!(BKE_scene_use_new_shading_nodes(scene) || (sbuts->texture_context == SB_TEXC_OTHER))) {
if (ct) {
diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c
index 02b06e08eed..e6c6df416bf 100644
--- a/source/blender/editors/space_buttons/space_buttons.c
+++ b/source/blender/editors/space_buttons/space_buttons.c
@@ -87,7 +87,7 @@ static SpaceLink *buttons_new(const bContext *UNUSED(C))
BLI_addtail(&sbuts->regionbase, ar);
ar->regiontype = RGN_TYPE_WINDOW;
-
+
return (SpaceLink *)sbuts;
}
@@ -200,22 +200,17 @@ static void buttons_keymap(struct wmKeyConfig *keyconf)
/* add handlers, stuff you only do once or on area/region changes */
static void buttons_header_area_init(wmWindowManager *UNUSED(wm), ARegion *ar)
{
- UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_HEADER, ar->winx, ar->winy);
+ ED_region_header_init(ar);
}
static void buttons_header_area_draw(const bContext *C, ARegion *ar)
{
- /* clear */
- UI_ThemeClearColor(ED_screen_area_active(C) ? TH_HEADER : TH_HEADERDESEL);
- glClear(GL_COLOR_BUFFER_BIT);
-
- /* set view2d view matrix for scrolling (without scrollers) */
- UI_view2d_view_ortho(&ar->v2d);
-
- buttons_header_buttons(C, ar);
+ SpaceButs *sbuts = CTX_wm_space_buts(C);
+
+ /* Needed for RNA to get the good values! */
+ buttons_context_compute(C, sbuts);
- /* restore view matrix? */
- UI_view2d_view_restore(C);
+ ED_region_header(C, ar);
}
/* draw a certain button set only if properties area is currently
diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c
index 60420649093..986b71abc8a 100644
--- a/source/blender/editors/space_clip/space_clip.c
+++ b/source/blender/editors/space_clip/space_clip.c
@@ -807,7 +807,7 @@ static int clip_context(const bContext *C, const char *member, bContextDataResul
static int clip_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
{
if (drag->type == WM_DRAG_PATH)
- if (ELEM3(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_BLANK)) /* rule might not work? */
+ if (ELEM4(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_MOVIE, ICON_FILE_BLANK)) /* rule might not work? */
return TRUE;
return FALSE;
diff --git a/source/blender/editors/space_file/file_intern.h b/source/blender/editors/space_file/file_intern.h
index e5c6a839380..240106d37d5 100644
--- a/source/blender/editors/space_file/file_intern.h
+++ b/source/blender/editors/space_file/file_intern.h
@@ -105,8 +105,8 @@ float file_string_width(const char *str);
float file_font_pointsize(void);
void file_change_dir(bContext *C, int checkdir);
int file_select_match(struct SpaceFile *sfile, const char *pattern, char *matched_file);
-void autocomplete_directory(struct bContext *C, char *str, void *arg_v);
-void autocomplete_file(struct bContext *C, char *str, void *arg_v);
+bool autocomplete_directory(struct bContext *C, char *str, void *arg_v);
+bool autocomplete_file(struct bContext *C, char *str, void *arg_v);
/* file_panels.c */
void file_panels_register(struct ARegionType *art);
diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c
index 25d865d857b..a31af851575 100644
--- a/source/blender/editors/space_file/filesel.c
+++ b/source/blender/editors/space_file/filesel.c
@@ -609,6 +609,7 @@ void file_change_dir(bContext *C, int checkdir)
folderlist_pushdir(sfile->folders_prev, sfile->params->dir);
+ file_draw_check_cb(C, NULL, NULL);
}
}
@@ -637,9 +638,10 @@ int file_select_match(struct SpaceFile *sfile, const char *pattern, char *matche
return match;
}
-void autocomplete_directory(struct bContext *C, char *str, void *UNUSED(arg_v))
+bool autocomplete_directory(struct bContext *C, char *str, void *UNUSED(arg_v))
{
SpaceFile *sfile = CTX_wm_space_file(C);
+ bool change = false;
/* search if str matches the beginning of name */
if (str[0] && sfile->files) {
@@ -674,20 +676,25 @@ void autocomplete_directory(struct bContext *C, char *str, void *UNUSED(arg_v))
}
closedir(dir);
- autocomplete_end(autocpl, str);
- if (BLI_exists(str)) {
- BLI_add_slash(str);
- }
- else {
- BLI_strncpy(sfile->params->dir, str, sizeof(sfile->params->dir));
+ change = autocomplete_end(autocpl, str);
+ if (change) {
+ if (BLI_exists(str)) {
+ BLI_add_slash(str);
+ }
+ else {
+ BLI_strncpy(sfile->params->dir, str, sizeof(sfile->params->dir));
+ }
}
}
}
+
+ return change;
}
-void autocomplete_file(struct bContext *C, char *str, void *UNUSED(arg_v))
+bool autocomplete_file(struct bContext *C, char *str, void *UNUSED(arg_v))
{
SpaceFile *sfile = CTX_wm_space_file(C);
+ bool change = false;
/* search if str matches the beginning of name */
if (str[0] && sfile->files) {
@@ -701,8 +708,9 @@ void autocomplete_file(struct bContext *C, char *str, void *UNUSED(arg_v))
autocomplete_do_name(autocpl, file->relname);
}
}
- autocomplete_end(autocpl, str);
+ change = autocomplete_end(autocpl, str);
}
+ return change;
}
void ED_fileselect_clear(struct wmWindowManager *wm, struct SpaceFile *sfile)
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index 8272222e4c2..0a2bd2aad81 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -1441,7 +1441,7 @@ static int image_save_as_exec(bContext *C, wmOperator *op)
}
-static int image_save_as_check(bContext *UNUSED(C), wmOperator *op)
+static bool image_save_as_check(bContext *UNUSED(C), wmOperator *op)
{
ImageFormatData *imf = op->customdata;
return WM_operator_filesel_ensure_ext_imtype(op, imf);
diff --git a/source/blender/editors/space_nla/nla_edit.c b/source/blender/editors/space_nla/nla_edit.c
index 164382c300d..159cc74af56 100644
--- a/source/blender/editors/space_nla/nla_edit.c
+++ b/source/blender/editors/space_nla/nla_edit.c
@@ -425,8 +425,7 @@ static int nlaedit_add_actionclip_exec(bContext *C, wmOperator *op)
if (items == 0) {
BKE_report(op->reports, RPT_ERROR,
- "No active track(s) to add strip to. "
- "Select an existing track or add one before trying again");
+ "No active track(s) to add strip to, select an existing track or add one before trying again");
return OPERATOR_CANCELLED;
}
diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c
index 0d875acb040..2fa901a2f28 100644
--- a/source/blender/editors/space_view3d/view3d_buttons.c
+++ b/source/blender/editors/space_view3d/view3d_buttons.c
@@ -773,8 +773,12 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
#define B_VGRP_PNL_COPY 1
#define B_VGRP_PNL_NORMALIZE 2
-#define B_VGRP_PNL_EDIT_SINGLE 8 /* or greater */
-#define B_VGRP_PNL_COPY_SINGLE 16384 /* or greater */
+#define B_VGRP_PNL_TOGGLE_USE_ALL 4
+#define B_VGRP_PNL_EDIT_SINGLE 8 /* or greater */
+#define B_VGRP_PNL_DELETE_SINGLE 4096 /* or greater */
+#define B_VGRP_PNL_COPY_SINGLE 8192 /* or greater */
+#define B_VGRP_PNL_ACTIVE 16384 /* or greater */
+
static MDeformVert *ED_mesh_active_dvert_get_ob(Object *ob, int *r_index)
{
@@ -904,6 +908,18 @@ static void vgroup_adjust_active(Object *ob, int def_nr)
}
}
+static void vgroup_remove_weight(Object *ob, const int def_nr)
+{
+ MDeformVert *dvert_act;
+ MDeformWeight *dw;
+
+ dvert_act = ED_mesh_active_dvert_get_only(ob);
+
+ dw = defvert_find_index(dvert_act, def_nr);
+ defvert_remove_group(dvert_act, dw);
+
+}
+
static void vgroup_copy_active_to_sel(Object *ob)
{
Mesh *me = ob->data;
@@ -1064,9 +1080,15 @@ static void do_view3d_vgroup_buttons(bContext *C, void *UNUSED(arg), int event)
else if (event == B_VGRP_PNL_COPY) {
vgroup_copy_active_to_sel(ob);
}
+ else if (event >= B_VGRP_PNL_ACTIVE) {
+ ob->actdef = event - B_VGRP_PNL_ACTIVE + 1;
+ }
else if (event >= B_VGRP_PNL_COPY_SINGLE) {
vgroup_copy_active_to_sel_single(ob, event - B_VGRP_PNL_COPY_SINGLE);
}
+ else if (event >= B_VGRP_PNL_DELETE_SINGLE) {
+ vgroup_remove_weight(ob, event - B_VGRP_PNL_DELETE_SINGLE);
+ }
else if (event >= B_VGRP_PNL_EDIT_SINGLE) {
vgroup_adjust_active(ob, event - B_VGRP_PNL_EDIT_SINGLE);
}
@@ -1111,6 +1133,9 @@ static void view3d_panel_vgroup(const bContext *C, Panel *pa)
if (dv && dv->totweight) {
uiLayout *col;
+ uiLayout *row;
+ uiLayout *box;
+ uiBut *but;
bDeformGroup *dg;
unsigned int i;
int subset_count, vgroup_tot;
@@ -1119,22 +1144,50 @@ static void view3d_panel_vgroup(const bContext *C, Panel *pa)
int yco = 0;
uiBlockSetHandleFunc(block, do_view3d_vgroup_buttons, NULL);
+ box = uiLayoutBox(pa->layout);
- col = uiLayoutColumn(pa->layout, FALSE);
- block = uiLayoutAbsoluteBlock(col);
-
- uiBlockBeginAlign(block);
+ col = uiLayoutColumn(box, true);
vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count);
for (i = 0, dg = ob->defbase.first; dg; i++, dg = dg->next) {
if (vgroup_validmap[i]) {
MDeformWeight *dw = defvert_find_index(dv, i);
if (dw) {
- uiDefButF(block, NUM, B_VGRP_PNL_EDIT_SINGLE + i, dg->name, 0, yco, 180, 20,
+ int x, xco = 0;
+ row = uiLayoutRow(col, true);
+ (void)row;
+
+ uiBlockSetEmboss(block, UI_EMBOSSN);
+ but = uiDefBut(block, BUT, B_VGRP_PNL_ACTIVE + i, dg->name,
+ xco, yco, (x = UI_UNIT_X * 5), UI_UNIT_Y,
+ NULL, 0.0, 1.0, 1, 3, "");
+ uiButSetFlag(but, UI_TEXT_LEFT);
+
+ if (ob->actdef != i + 1) {
+ uiButSetFlag(but, UI_BUT_INACTIVE);
+ }
+ xco += x;
+
+ //uiBlockSetEmboss(block, UI_EMBOSS);
+
+ but = uiDefButF(block, NUM, B_VGRP_PNL_EDIT_SINGLE + i, "",
+ xco, yco, (x = UI_UNIT_X * 4), UI_UNIT_Y,
&dw->weight, 0.0, 1.0, 1, 3, "");
- uiDefBut(block, BUT, B_VGRP_PNL_COPY_SINGLE + i, "C", 180, yco, 20, 20,
- NULL, 0, 0, 0, 0, TIP_("Copy this group's weight to other selected verts"));
- yco -= 20;
+ uiButSetFlag(but, UI_TEXT_LEFT);
+ xco += x;
+
+ uiDefIconBut(block, BUT, B_VGRP_PNL_COPY_SINGLE + i, ICON_PASTEDOWN,
+ xco, yco, (x = UI_UNIT_X), UI_UNIT_Y,
+ NULL, 0, 0, 0, 0, TIP_("Copy this group's weight to other selected verts"));
+ xco += x;
+
+ uiDefIconBut(block, BUT, B_VGRP_PNL_DELETE_SINGLE + i, ICON_X,
+ xco, yco, (x = UI_UNIT_X), UI_UNIT_Y,
+ NULL, 0, 0, 0, 0, TIP_("Delete this weight from the vertex"));
+ xco += x;
+
+ yco -= UI_UNIT_Y;
+ (void)xco;
}
}
}
@@ -1142,13 +1195,16 @@ static void view3d_panel_vgroup(const bContext *C, Panel *pa)
yco -= 2;
- uiBlockEndAlign(block);
- uiBlockBeginAlign(block);
- uiDefBut(block, BUT, B_VGRP_PNL_NORMALIZE, IFACE_("Normalize"), 0, yco, 100, 20,
+ uiBlockSetEmboss(block, UI_EMBOSS);
+ col = uiLayoutColumn(pa->layout, true);
+ row = uiLayoutRow(col, true);
+
+ uiDefBut(block, BUT, B_VGRP_PNL_NORMALIZE, IFACE_("Normalize"),
+ 0, yco, UI_UNIT_X * 5, UI_UNIT_Y,
NULL, 0, 0, 0, 0, TIP_("Normalize active vertex weights"));
- uiDefBut(block, BUT, B_VGRP_PNL_COPY, IFACE_("Copy"), 100, yco, 100, 20,
+ uiDefBut(block, BUT, B_VGRP_PNL_COPY, IFACE_("Copy"),
+ UI_UNIT_X * 5, yco, UI_UNIT_X * 5, UI_UNIT_Y,
NULL, 0, 0, 0, 0, TIP_("Copy active vertex to other selected verts"));
- uiBlockEndAlign(block);
}
}
diff --git a/source/blender/editors/space_view3d/view3d_iterators.c b/source/blender/editors/space_view3d/view3d_iterators.c
index 9e310c84bd0..180686b4b82 100644
--- a/source/blender/editors/space_view3d/view3d_iterators.c
+++ b/source/blender/editors/space_view3d/view3d_iterators.c
@@ -237,7 +237,7 @@ static void mesh_foreachScreenFace__mapFunc(void *userData, int index, const flo
foreachScreenFace_userData *data = userData;
BMFace *efa = EDBM_face_at_index(data->vc.em, index);
- if (efa && !BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
+ if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
float screen_co[2];
if (ED_view3d_project_float_object(data->vc.ar, cent, screen_co, data->clip_flag) == V3D_PROJ_RET_OK) {
data->func(data->userData, efa, screen_co, index);
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index bba151f1a5e..c119fe24210 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -1166,6 +1166,26 @@ static bool selectbuffer_has_bones(const unsigned int *buffer, const unsigned in
return false;
}
+/* utility function for mixed_bones_object_selectbuffer */
+static short selectbuffer_ret_hits_15(unsigned int *UNUSED(buffer), const short hits15)
+{
+ return hits15;
+}
+
+static short selectbuffer_ret_hits_9(unsigned int *buffer, const short hits15, const short hits9)
+{
+ const int offs = 4 * hits15;
+ memcpy(buffer, buffer + offs, 4 * offs);
+ return hits9;
+}
+
+static short selectbuffer_ret_hits_5(unsigned int *buffer, const short hits15, const short hits9, const short hits5)
+{
+ const int offs = 4 * hits15 + 4 * hits9;
+ memcpy(buffer, buffer + offs, 4 * offs);
+ return hits5;
+}
+
/* we want a select buffer with bones, if there are... */
/* so check three selection levels and compare */
static short mixed_bones_object_selectbuffer(ViewContext *vc, unsigned int *buffer, const int mval[2])
@@ -1177,48 +1197,39 @@ static short mixed_bones_object_selectbuffer(ViewContext *vc, unsigned int *buff
BLI_rcti_init(&rect, mval[0] - 14, mval[0] + 14, mval[1] - 14, mval[1] + 14);
hits15 = view3d_opengl_select(vc, buffer, MAXPICKBUF, &rect);
- if (hits15 > 0) {
+ if (hits15 == 1) {
+ return selectbuffer_ret_hits_15(buffer, hits15);
+ }
+ else if (hits15 > 0) {
has_bones15 = selectbuffer_has_bones(buffer, hits15);
offs = 4 * hits15;
BLI_rcti_init(&rect, mval[0] - 9, mval[0] + 9, mval[1] - 9, mval[1] + 9);
hits9 = view3d_opengl_select(vc, buffer + offs, MAXPICKBUF - offs, &rect);
- if (hits9 > 0) {
+ if (hits9 == 1) {
+ return selectbuffer_ret_hits_9(buffer, hits15, hits9);
+ }
+ else if (hits9 > 0) {
has_bones9 = selectbuffer_has_bones(buffer + offs, hits9);
offs += 4 * hits9;
BLI_rcti_init(&rect, mval[0] - 5, mval[0] + 5, mval[1] - 5, mval[1] + 5);
hits5 = view3d_opengl_select(vc, buffer + offs, MAXPICKBUF - offs, &rect);
- if (hits5 > 0) {
+ if (hits5 == 1) {
+ return selectbuffer_ret_hits_5(buffer, hits15, hits9, hits5);
+ }
+ else if (hits5 > 0) {
has_bones5 = selectbuffer_has_bones(buffer + offs, hits5);
}
}
+
+ if (has_bones5) return selectbuffer_ret_hits_5(buffer, hits15, hits9, hits5);
+ else if (has_bones9) return selectbuffer_ret_hits_9(buffer, hits15, hits9);
+ else if (has_bones15) return selectbuffer_ret_hits_15(buffer, hits15);
- if (has_bones5) {
- offs = 4 * hits15 + 4 * hits9;
- memcpy(buffer, buffer + offs, 4 * offs);
- return hits5;
- }
- if (has_bones9) {
- offs = 4 * hits15;
- memcpy(buffer, buffer + offs, 4 * offs);
- return hits9;
- }
- if (has_bones15) {
- return hits15;
- }
-
- if (hits5 > 0) {
- offs = 4 * hits15 + 4 * hits9;
- memcpy(buffer, buffer + offs, 4 * offs);
- return hits5;
- }
- if (hits9 > 0) {
- offs = 4 * hits15;
- memcpy(buffer, buffer + offs, 4 * offs);
- return hits9;
- }
- return hits15;
+ if (hits5 > 0) return selectbuffer_ret_hits_5(buffer, hits15, hits9, hits5);
+ else if (hits9 > 0) return selectbuffer_ret_hits_9(buffer, hits15, hits9);
+ else return selectbuffer_ret_hits_15(buffer, hits15);
}
return 0;
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index d8f763c6a54..ac5727a116c 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -196,7 +196,7 @@ static void sort_trans_data(TransInfo *t)
/* distance calculated from not-selected vertex to nearest selected vertex
* warning; this is loops inside loop, has minor N^2 issues, but by sorting list it is OK */
-static void set_prop_dist(TransInfo *t, short with_dist)
+static void set_prop_dist(TransInfo *t, const bool with_dist)
{
TransData *tob;
int a;
@@ -216,12 +216,9 @@ static void set_prop_dist(TransInfo *t, short with_dist)
if (td->flag & TD_SELECTED) {
sub_v3_v3v3(vec, tob->center, td->center);
mul_m3_v3(tob->mtx, vec);
- dist = normalize_v3(vec);
- if (tob->rdist == -1.0f) {
- tob->rdist = dist;
- }
- else if (dist < tob->rdist) {
- tob->rdist = dist;
+ dist = len_squared_v3(vec);
+ if ((tob->rdist == -1.0f) || (dist < (tob->rdist * tob->rdist))) {
+ tob->rdist = sqrtf(dist);
}
}
else {
@@ -1778,90 +1775,125 @@ void flushTransParticles(TransInfo *t)
/* ********************* mesh ****************** */
-/* I did this wrong, it should be a breadth-first search
- * but instead it's a depth-first search, fudged
- * to report shortest distances. I have no idea how fast
- * or slow this is. */
-static void editmesh_set_connectivity_distance(BMEditMesh *em, float mtx[3][3], float *dists)
+static bool bmesh_test_dist_add(BMVert *v, BMVert *v_other,
+ float *dists, const float *dists_prev,
+ float mtx[3][3])
{
- BMVert **queue = NULL;
- float *dqueue = NULL;
- int *tots = MEM_callocN(sizeof(int) * em->bm->totvert, "tots editmesh_set_connectivity_distance");
- BLI_array_declare(queue);
- BLI_array_declare(dqueue);
- SmallHash svisit, *visit = &svisit;
- BMVert *v;
- BMIter viter;
- int i, start;
-
- fill_vn_fl(dists, em->bm->totvert, FLT_MAX);
+ if ((BM_elem_flag_test(v_other, BM_ELEM_SELECT) == 0) &&
+ (BM_elem_flag_test(v_other, BM_ELEM_HIDDEN) == 0))
+ {
+ const int i = BM_elem_index_get(v);
+ const int i_other = BM_elem_index_get(v_other);
+ float vec[3];
+ float dist_other;
+ sub_v3_v3v3(vec, v->co, v_other->co);
+ mul_m3_v3(mtx, vec);
+
+ dist_other = dists_prev[i] + len_v3(vec);
+ if (dist_other < dists[i_other]) {
+ dists[i_other] = dist_other;
+ return true;
+ }
+ }
- BM_mesh_elem_index_ensure(em->bm, BM_VERT);
+ return false;
+}
- BLI_smallhash_init(visit);
+static void editmesh_set_connectivity_distance(BMesh *bm, float mtx[3][3], float *dists)
+{
+ /* need to be very careful of feedback loops here, store previous dist's to avoid feedback */
+ float *dists_prev = MEM_mallocN(bm->totvert * sizeof(float), __func__);
- BM_ITER_MESH (v, &viter, em->bm, BM_VERTS_OF_MESH) {
- if (BM_elem_flag_test(v, BM_ELEM_SELECT) == 0 || BM_elem_flag_test(v, BM_ELEM_HIDDEN))
- continue;
-
-
- BLI_smallhash_insert(visit, (uintptr_t)v, NULL);
- BLI_array_append(queue, v);
- BLI_array_append(dqueue, 0.0f);
- dists[BM_elem_index_get(v)] = 0.0f;
+ BMVert **queue = MEM_mallocN(bm->totvert * sizeof(BMVert *), __func__);
+ STACK_DECLARE(queue);
+
+ /* any BM_ELEM_TAG'd vertex is in 'queue_next', so we don't add in twice */
+ BMVert **queue_next = MEM_mallocN(bm->totvert * sizeof(BMVert *), __func__);
+ STACK_DECLARE(queue_next);
+
+ STACK_INIT(queue);
+ STACK_INIT(queue_next);
+
+ {
+ BMIter viter;
+ BMVert *v;
+ int i;
+
+ BM_ITER_MESH_INDEX (v, &viter, bm, BM_VERTS_OF_MESH, i) {
+ BM_elem_index_set(v, i); /* set_inline */
+ BM_elem_flag_disable(v, BM_ELEM_TAG);
+
+ if (BM_elem_flag_test(v, BM_ELEM_SELECT) == 0 || BM_elem_flag_test(v, BM_ELEM_HIDDEN)) {
+ dists[i] = FLT_MAX;
+ }
+ else {
+ STACK_PUSH(queue, v);
+
+ dists[i] = 0.0f;
+ }
+ }
}
-
- start = 0;
- while (start < BLI_array_count(queue)) {
- BMIter eiter;
- BMEdge *e;
- BMVert *v3, *v2;
- float d, vec[3];
-
- v2 = queue[start];
- d = dqueue[start];
-
- BM_ITER_ELEM (e, &eiter, v2, BM_EDGES_OF_VERT) {
- float d2;
- v3 = BM_edge_other_vert(e, v2);
-
- if (BM_elem_flag_test(v3, BM_ELEM_SELECT) || BM_elem_flag_test(v3, BM_ELEM_HIDDEN))
- continue;
-
- sub_v3_v3v3(vec, v2->co, v3->co);
- mul_m3_v3(mtx, vec);
-
- d2 = d + len_v3(vec);
-
- if (dists[BM_elem_index_get(v3)] != FLT_MAX)
- dists[BM_elem_index_get(v3)] = min_ff(d2, dists[BM_elem_index_get(v3)]);
- else
- dists[BM_elem_index_get(v3)] = d2;
-
- tots[BM_elem_index_get(v3)] = 1;
- if (BLI_smallhash_haskey(visit, (uintptr_t)v3))
- continue;
-
- BLI_smallhash_insert(visit, (uintptr_t)v3, NULL);
+ do {
+ BMVert *v;
+ unsigned int i;
+
+ memcpy(dists_prev, dists, sizeof(float) * bm->totvert);
+
+ while ((v = STACK_POP(queue))) {
+ BMIter iter;
+ BMEdge *e;
+ BMLoop *l;
+
+ /* connected edge-verts */
+ BM_ITER_ELEM (e, &iter, v, BM_EDGES_OF_VERT) {
+ if (BM_elem_flag_test(e, BM_ELEM_HIDDEN) == 0) {
+ BMVert *v_other = BM_edge_other_vert(e, v);
+ if (bmesh_test_dist_add(v, v_other, dists, dists_prev, mtx)) {
+ if (BM_elem_flag_test(v_other, BM_ELEM_TAG) == 0) {
+ BM_elem_flag_enable(v_other, BM_ELEM_TAG);
+ STACK_PUSH(queue_next, v_other);
+ }
+ }
+ }
+ }
- BLI_array_append(queue, v3);
- BLI_array_append(dqueue, d2);
+ /* connected face-verts (excluding adjacent verts) */
+ BM_ITER_ELEM (l, &iter, v, BM_LOOPS_OF_VERT) {
+ if ((BM_elem_flag_test(l->f, BM_ELEM_HIDDEN) == 0) && (l->f->len > 3)) {
+ BMLoop *l_end = l->prev;
+ l = l->next->next;
+ do {
+ BMVert *v_other = l->v;
+ if (bmesh_test_dist_add(v, v_other, dists, dists_prev, mtx)) {
+ if (BM_elem_flag_test(v_other, BM_ELEM_TAG) == 0) {
+ BM_elem_flag_enable(v_other, BM_ELEM_TAG);
+ STACK_PUSH(queue_next, v_other);
+ }
+ }
+ } while ((l = l->next) != l_end);
+ }
+ }
}
-
- start++;
- }
- BLI_smallhash_release(visit);
-
- for (i = 0; i < em->bm->totvert; i++) {
- if (tots[i])
- dists[i] /= (float)tots[i];
- }
-
- BLI_array_free(queue);
- BLI_array_free(dqueue);
- MEM_freeN(tots);
+ /* clear for the next loop */
+ for (i = 0; i < STACK_SIZE(queue_next); i++) {
+ BM_elem_flag_disable(queue_next[i], BM_ELEM_TAG);
+ }
+
+ STACK_SWAP(queue, queue_next);
+
+ /* none should be tagged now since 'queue_next' is empty */
+ BLI_assert(BM_iter_mesh_count_flag(BM_VERTS_OF_MESH, bm, BM_ELEM_TAG, true) == 0);
+
+ } while (STACK_SIZE(queue));
+
+ STACK_FREE(queue);
+ STACK_FREE(queue_next);
+
+ MEM_freeN(queue);
+ MEM_freeN(queue_next);
+ MEM_freeN(dists_prev);
}
static BMElem *bm_vert_single_select_face(BMVert *eve)
@@ -2099,7 +2131,7 @@ static void createTransEditVerts(TransInfo *t)
pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
if (propmode & T_PROP_CONNECTED) {
- editmesh_set_connectivity_distance(em, mtx, dists);
+ editmesh_set_connectivity_distance(em->bm, mtx, dists);
}
/* detect CrazySpace [tm] */
diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c
index 917335e2068..386eda7dd38 100644
--- a/source/blender/editors/uvedit/uvedit_ops.c
+++ b/source/blender/editors/uvedit/uvedit_ops.c
@@ -2113,7 +2113,7 @@ static int uv_mouse_select(bContext *C, const float co[2], bool extend, bool loo
hitlen = hit.efa->len;
}
else if (selectmode == UV_SELECT_ISLAND) {
- uv_find_nearest_vert(scene, ima, em, co, NULL, &hit);
+ uv_find_nearest_edge(scene, ima, em, co, &hit);
if (hit.efa == NULL) {
return OPERATOR_CANCELLED;
@@ -2378,7 +2378,7 @@ static int uv_select_linked_internal(bContext *C, wmOperator *op, const wmEvent
RNA_float_get_array(op->ptr, "location", co);
}
- uv_find_nearest_vert(scene, ima, em, co, NULL, &hit);
+ uv_find_nearest_edge(scene, ima, em, co, &hit);
hit_p = &hit;
}
diff --git a/source/blender/freestyle/intern/application/AppCanvas.cpp b/source/blender/freestyle/intern/application/AppCanvas.cpp
index e1f300b3ce0..f621f45ff77 100644
--- a/source/blender/freestyle/intern/application/AppCanvas.cpp
+++ b/source/blender/freestyle/intern/application/AppCanvas.cpp
@@ -136,8 +136,8 @@ void AppCanvas::readColorPixels(int x, int y, int w, int h, RGBImage& oImage) co
int ymin = border().getMin().y();
int xmax = border().getMax().x();
int ymax = border().getMax().y();
- int rectx = _pass_z.width;
- int recty = _pass_z.height;
+ int rectx = _pass_diffuse.width;
+ int recty = _pass_diffuse.height;
float xfac = ((float)rectx) / ((float)(xmax - xmin));
float yfac = ((float)recty) / ((float)(ymax - ymin));
#if 0
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index a846ac697f0..e0c5cd5608e 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -360,6 +360,12 @@ typedef struct bAddon {
IDProperty *prop; /* User-Defined Properties on this Addon (for storing preferences) */
} bAddon;
+typedef struct bPathCompare {
+ struct bPathCompare *next, *prev;
+ char path[768]; /* FILE_MAXDIR */
+ char flag, pad[7];
+} bPathCompare;
+
typedef struct SolidLight {
int flag, pad;
float col[4], spec[4], vec[4];
@@ -412,6 +418,7 @@ typedef struct UserDef {
struct ListBase keymaps DNA_DEPRECATED; /* deprecated in favor of user_keymaps */
struct ListBase user_keymaps;
struct ListBase addons;
+ struct ListBase autoexec_paths;
char keyconfigstr[64];
short undosteps;
@@ -522,7 +529,12 @@ typedef enum eUserPref_Flag {
USER_TXT_TABSTOSPACES_DISABLE = (1 << 25),
USER_TOOLTIPS_PYTHON = (1 << 26),
} eUserPref_Flag;
-
+
+/* flag */
+typedef enum ePathCompare_Flag {
+ USER_PATHCMP_GLOB = (1 << 0),
+} ePathCompare_Flag;
+
/* helper macro for checking frame clamping */
#define FRAMENUMBER_MIN_CLAMP(cfra) { \
if ((U.flag & USER_NONEGFRAMES) && (cfra < 0)) \
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index 36da4e3508c..4513694e59d 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -138,6 +138,25 @@ EnumPropertyItem clip_editor_mode_items[] = {
};
/* Actually populated dynamically trough a function, but helps for context-less access (e.g. doc, i18n...). */
+static EnumPropertyItem buttons_context_items[] = {
+ {BCONTEXT_SCENE, "SCENE", ICON_SCENE_DATA, "Scene", "Scene"},
+ {BCONTEXT_RENDER, "RENDER", ICON_SCENE, "Render", "Render"},
+ {BCONTEXT_RENDER_LAYER, "RENDER_LAYER", ICON_RENDERLAYERS, "Render Layers", "Render layers"},
+ {BCONTEXT_WORLD, "WORLD", ICON_WORLD, "World", "World"},
+ {BCONTEXT_OBJECT, "OBJECT", ICON_OBJECT_DATA, "Object", "Object"},
+ {BCONTEXT_CONSTRAINT, "CONSTRAINT", ICON_CONSTRAINT, "Constraints", "Object constraints"},
+ {BCONTEXT_MODIFIER, "MODIFIER", ICON_MODIFIER, "Modifiers", "Object modifiers"},
+ {BCONTEXT_DATA, "DATA", ICON_NONE, "Data", "Object data"},
+ {BCONTEXT_BONE, "BONE", ICON_BONE_DATA, "Bone", "Bone"},
+ {BCONTEXT_BONE_CONSTRAINT, "BONE_CONSTRAINT", ICON_CONSTRAINT, "Bone Constraints", "Bone constraints"},
+ {BCONTEXT_MATERIAL, "MATERIAL", ICON_MATERIAL, "Material", "Material"},
+ {BCONTEXT_TEXTURE, "TEXTURE", ICON_TEXTURE, "Texture", "Texture"},
+ {BCONTEXT_PARTICLE, "PARTICLES", ICON_PARTICLES, "Particles", "Particle"},
+ {BCONTEXT_PHYSICS, "PHYSICS", ICON_PHYSICS, "Physics", "Physics"},
+ {0, NULL, 0, NULL, NULL}
+};
+
+/* Actually populated dynamically trough a function, but helps for context-less access (e.g. doc, i18n...). */
static EnumPropertyItem buttons_texture_context_items[] = {
{SB_TEXC_MATERIAL, "MATERIAL", ICON_MATERIAL, "", "Show material textures"},
{SB_TEXC_WORLD, "WORLD", ICON_WORLD, "", "Show world textures"},
@@ -831,6 +850,76 @@ static void rna_SpaceProperties_context_set(PointerRNA *ptr, int value)
sbuts->mainbuser = value;
}
+static EnumPropertyItem *rna_SpaceProperties_context_itemf(bContext *C, PointerRNA *ptr,
+ PropertyRNA *UNUSED(prop), int *free)
+{
+ SpaceButs *sbuts = (SpaceButs *)(ptr->data);
+ EnumPropertyItem *item = NULL;
+ int totitem = 0;
+
+ if (sbuts->pathflag & (1 << BCONTEXT_RENDER)) {
+ RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_RENDER);
+ }
+
+ if (sbuts->pathflag & (1 << BCONTEXT_RENDER_LAYER)) {
+ RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_RENDER_LAYER);
+ }
+
+ if (sbuts->pathflag & (1 << BCONTEXT_SCENE)) {
+ RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_SCENE);
+ }
+
+ if (sbuts->pathflag & (1 << BCONTEXT_WORLD)) {
+ RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_WORLD);
+ }
+
+ if (sbuts->pathflag & (1 << BCONTEXT_OBJECT)) {
+ RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_OBJECT);
+ }
+
+ if (sbuts->pathflag & (1 << BCONTEXT_CONSTRAINT)) {
+ RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_CONSTRAINT);
+ }
+
+ if (sbuts->pathflag & (1 << BCONTEXT_MODIFIER)) {
+ RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_MODIFIER);
+ }
+
+ if (sbuts->pathflag & (1 << BCONTEXT_DATA)) {
+ RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_DATA);
+ (item + totitem - 1)->icon = sbuts->dataicon;
+ }
+
+ if (sbuts->pathflag & (1 << BCONTEXT_BONE)) {
+ RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_BONE);
+ }
+
+ if (sbuts->pathflag & (1 << BCONTEXT_BONE_CONSTRAINT)) {
+ RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_BONE_CONSTRAINT);
+ }
+
+ if (sbuts->pathflag & (1 << BCONTEXT_MATERIAL)) {
+ RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_MATERIAL);
+ }
+
+ if (sbuts->pathflag & (1 << BCONTEXT_TEXTURE)) {
+ RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_TEXTURE);
+ }
+
+ if (sbuts->pathflag & (1 << BCONTEXT_PARTICLE)) {
+ RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_PARTICLE);
+ }
+
+ if (sbuts->pathflag & (1 << BCONTEXT_PHYSICS)) {
+ RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_PHYSICS);
+ }
+
+ RNA_enum_item_end(&item, &totitem);
+ *free = 1;
+
+ return item;
+}
+
static void rna_SpaceProperties_align_set(PointerRNA *ptr, int value)
{
SpaceButs *sbuts = (SpaceButs *)(ptr->data);
@@ -2068,24 +2157,6 @@ static void rna_def_space_buttons(BlenderRNA *brna)
StructRNA *srna;
PropertyRNA *prop;
- static EnumPropertyItem buttons_context_items[] = {
- {BCONTEXT_SCENE, "SCENE", ICON_SCENE, "Scene", "Scene"},
- {BCONTEXT_RENDER, "RENDER", ICON_SCENE_DATA, "Render", "Render"},
- {BCONTEXT_RENDER_LAYER, "RENDER_LAYER", ICON_RENDERLAYERS, "Render Layers", "Render Layers"},
- {BCONTEXT_WORLD, "WORLD", ICON_WORLD, "World", "World"},
- {BCONTEXT_OBJECT, "OBJECT", ICON_OBJECT_DATA, "Object", "Object"},
- {BCONTEXT_CONSTRAINT, "CONSTRAINT", ICON_CONSTRAINT, "Constraints", "Constraints"},
- {BCONTEXT_MODIFIER, "MODIFIER", ICON_MODIFIER, "Modifiers", "Modifiers"},
- {BCONTEXT_DATA, "DATA", 0, "Data", "Data"},
- {BCONTEXT_BONE, "BONE", ICON_BONE_DATA, "Bone", "Bone"},
- {BCONTEXT_BONE_CONSTRAINT, "BONE_CONSTRAINT", ICON_CONSTRAINT, "Bone Constraints", "Bone Constraints"},
- {BCONTEXT_MATERIAL, "MATERIAL", ICON_MATERIAL, "Material", "Material"},
- {BCONTEXT_TEXTURE, "TEXTURE", ICON_TEXTURE, "Texture", "Texture"},
- {BCONTEXT_PARTICLE, "PARTICLES", ICON_PARTICLES, "Particles", "Particle"},
- {BCONTEXT_PHYSICS, "PHYSICS", ICON_PHYSICS, "Physics", "Physics"},
- {0, NULL, 0, NULL, NULL}
- };
-
static EnumPropertyItem align_items[] = {
{BUT_HORIZONTAL, "HORIZONTAL", 0, "Horizontal", ""},
{BUT_VERTICAL, "VERTICAL", 0, "Vertical", ""},
@@ -2099,7 +2170,7 @@ static void rna_def_space_buttons(BlenderRNA *brna)
prop = RNA_def_property(srna, "context", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "mainb");
RNA_def_property_enum_items(prop, buttons_context_items);
- RNA_def_property_enum_funcs(prop, NULL, "rna_SpaceProperties_context_set", NULL);
+ RNA_def_property_enum_funcs(prop, NULL, "rna_SpaceProperties_context_set", "rna_SpaceProperties_context_itemf");
RNA_def_property_ui_text(prop, "Context", "Type of active data to display and edit");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_PROPERTIES, NULL);
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index 347c57f9044..f34366a23c7 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -339,9 +339,9 @@ static bAddon *rna_userdef_addon_new(void)
return bext;
}
-static void rna_userdef_addon_remove(ReportList *reports, PointerRNA *bext_ptr)
+static void rna_userdef_addon_remove(ReportList *reports, PointerRNA *path_cmp_ptr)
{
- bAddon *bext = bext_ptr->data;
+ bAddon *bext = path_cmp_ptr->data;
if (BLI_findindex(&U.addons, bext) == -1) {
BKE_report(reports, RPT_ERROR, "Addon is no longer valid");
return;
@@ -353,7 +353,26 @@ static void rna_userdef_addon_remove(ReportList *reports, PointerRNA *bext_ptr)
}
BLI_freelinkN(&U.addons, bext);
- RNA_POINTER_INVALIDATE(bext_ptr);
+ RNA_POINTER_INVALIDATE(path_cmp_ptr);
+}
+
+static bPathCompare *rna_userdef_pathcompare_new(void)
+{
+ bPathCompare *path_cmp = MEM_callocN(sizeof(bPathCompare), "bPathCompare");
+ BLI_addtail(&U.autoexec_paths, path_cmp);
+ return path_cmp;
+}
+
+static void rna_userdef_pathcompare_remove(ReportList *reports, PointerRNA *path_cmp_ptr)
+{
+ bPathCompare *path_cmp = path_cmp_ptr->data;
+ if (BLI_findindex(&U.autoexec_paths, path_cmp) == -1) {
+ BKE_report(reports, RPT_ERROR, "Addon is no longer valid");
+ return;
+ }
+
+ BLI_freelinkN(&U.autoexec_paths, path_cmp);
+ RNA_POINTER_INVALIDATE(path_cmp_ptr);
}
static void rna_userdef_temp_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *UNUSED(ptr))
@@ -2733,6 +2752,25 @@ static void rna_def_userdef_addon(BlenderRNA *brna)
RNA_def_property_pointer_funcs(prop, "rna_Addon_preferences_get", NULL, NULL, NULL);
}
+static void rna_def_userdef_pathcompare(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna = RNA_def_struct(brna, "PathCompare", NULL);
+ RNA_def_struct_sdna(srna, "bPathCompare");
+ RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
+ RNA_def_struct_ui_text(srna, "Path Compare", "Match paths against this value");
+
+ prop = RNA_def_property(srna, "path", PROP_STRING, PROP_DIRPATH);
+ RNA_def_property_ui_text(prop, "Path", "");
+ RNA_def_struct_name_property(srna, prop);
+
+ prop = RNA_def_property(srna, "use_glob", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", USER_PATHCMP_GLOB);
+ RNA_def_property_ui_text(prop, "Use Wildcard", "Enable wildcard globbing");
+}
+
static void rna_def_userdef_addon_pref(BlenderRNA *brna)
{
StructRNA *srna;
@@ -4027,6 +4065,32 @@ static void rna_def_userdef_addon_collection(BlenderRNA *brna, PropertyRNA *cpro
RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
}
+static void rna_def_userdef_autoexec_path_collection(BlenderRNA *brna, PropertyRNA *cprop)
+{
+ StructRNA *srna;
+ FunctionRNA *func;
+ PropertyRNA *parm;
+
+ RNA_def_property_srna(cprop, "PathCompareCollection");
+ srna = RNA_def_struct(brna, "PathCompareCollection", NULL);
+ RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
+ RNA_def_struct_ui_text(srna, "Paths Compare", "Collection of paths");
+
+ func = RNA_def_function(srna, "new", "rna_userdef_pathcompare_new");
+ RNA_def_function_flag(func, FUNC_NO_SELF);
+ RNA_def_function_ui_description(func, "Add a new addon");
+ /* return type */
+ parm = RNA_def_pointer(func, "pathcmp", "PathCompare", "", "");
+ RNA_def_function_return(func, parm);
+
+ func = RNA_def_function(srna, "remove", "rna_userdef_pathcompare_remove");
+ RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_USE_REPORTS);
+ RNA_def_function_ui_description(func, "Remove path");
+ parm = RNA_def_pointer(func, "pathcmp", "PathCompare", "", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
+ RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
+}
+
void RNA_def_userdef(BlenderRNA *brna)
{
StructRNA *srna;
@@ -4074,6 +4138,11 @@ void RNA_def_userdef(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Addon", "");
rna_def_userdef_addon_collection(brna, prop);
+ prop = RNA_def_property(srna, "autoexec_paths", PROP_COLLECTION, PROP_NONE);
+ RNA_def_property_collection_sdna(prop, NULL, "autoexec_paths", NULL);
+ RNA_def_property_struct_type(prop, "PathCompare");
+ RNA_def_property_ui_text(prop, "Autoexec Paths", "");
+ rna_def_userdef_autoexec_path_collection(brna, prop);
/* nested structs */
prop = RNA_def_property(srna, "view", PROP_POINTER, PROP_NONE);
@@ -4113,6 +4182,7 @@ void RNA_def_userdef(BlenderRNA *brna)
rna_def_userdef_system(brna);
rna_def_userdef_addon(brna);
rna_def_userdef_addon_pref(brna);
+ rna_def_userdef_pathcompare(brna);
}
diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c
index 6bf3beec57b..b70ab7c15f2 100644
--- a/source/blender/makesrna/intern/rna_wm.c
+++ b/source/blender/makesrna/intern/rna_wm.c
@@ -955,7 +955,7 @@ static int operator_execute(bContext *C, wmOperator *op)
}
/* same as execute() but no return value */
-static int operator_check(bContext *C, wmOperator *op)
+static bool operator_check(bContext *C, wmOperator *op)
{
extern FunctionRNA rna_Operator_check_func;
@@ -963,7 +963,7 @@ static int operator_check(bContext *C, wmOperator *op)
ParameterList list;
FunctionRNA *func;
void *ret;
- int result;
+ bool result;
RNA_pointer_create(NULL, op->type->ext.srna, op, &opr);
func = &rna_Operator_check_func; /* RNA_struct_find_function(&opr, "check"); */
@@ -973,7 +973,7 @@ static int operator_check(bContext *C, wmOperator *op)
op->type->ext.call(C, &opr, func, &list);
RNA_parameter_get_lookup(&list, "result", &ret);
- result = *(int *)ret;
+ result = (*(int *)ret) != 0;
RNA_parameter_list_free(&list);
diff --git a/source/blender/modifiers/intern/MOD_edgesplit.c b/source/blender/modifiers/intern/MOD_edgesplit.c
index d877932b81d..e37fc56d08c 100644
--- a/source/blender/modifiers/intern/MOD_edgesplit.c
+++ b/source/blender/modifiers/intern/MOD_edgesplit.c
@@ -49,7 +49,7 @@
#include "DNA_object_types.h"
-static DerivedMesh *doEdgeSplit(DerivedMesh *dm, EdgeSplitModifierData *emd, Object *UNUSED(ob))
+static DerivedMesh *doEdgeSplit(DerivedMesh *dm, EdgeSplitModifierData *emd)
{
DerivedMesh *result;
BMesh *bm;
@@ -97,7 +97,8 @@ static DerivedMesh *doEdgeSplit(DerivedMesh *dm, EdgeSplitModifierData *emd, Obj
result = CDDM_from_bmesh(bm, TRUE);
BM_mesh_free(bm);
-
+
+ result->dirty |= DM_DIRTY_NORMALS;
return result;
}
@@ -119,25 +120,16 @@ static void copyData(ModifierData *md, ModifierData *target)
temd->flags = emd->flags;
}
-static DerivedMesh *edgesplitModifier_do(EdgeSplitModifierData *emd,
- Object *ob, DerivedMesh *dm)
-{
- if (!(emd->flags & (MOD_EDGESPLIT_FROMANGLE | MOD_EDGESPLIT_FROMFLAG)))
- return dm;
-
- return doEdgeSplit(dm, emd, ob);
-}
-
-static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *derivedData,
+static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), DerivedMesh *dm,
ModifierApplyFlag UNUSED(flag))
{
DerivedMesh *result;
EdgeSplitModifierData *emd = (EdgeSplitModifierData *) md;
- result = edgesplitModifier_do(emd, ob, derivedData);
+ if (!(emd->flags & (MOD_EDGESPLIT_FROMANGLE | MOD_EDGESPLIT_FROMFLAG)))
+ return dm;
- if (result != derivedData)
- result->dirty |= DM_DIRTY_NORMALS;
+ result = doEdgeSplit(dm, emd);
return result;
}
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 189c30b02e8..72b54e2f1f7 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -112,6 +112,7 @@ bool WM_is_draw_triple(struct wmWindow *win);
/* files */
+void WM_file_autoexec_init(const char *filepath);
void WM_file_read(struct bContext *C, const char *filepath, struct ReportList *reports);
void WM_autosave_init(struct wmWindowManager *wm);
void WM_recover_last_session(struct bContext *C, struct ReportList *reports);
@@ -193,7 +194,7 @@ int WM_enum_search_invoke(struct bContext *C, struct wmOperator *op, const str
int WM_operator_confirm (struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
/* invoke callback, file selector "filepath" unset + exec */
int WM_operator_filesel (struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
-int WM_operator_filesel_ensure_ext_imtype(wmOperator *op, const struct ImageFormatData *im_format);
+bool WM_operator_filesel_ensure_ext_imtype(wmOperator *op, const struct ImageFormatData *im_format);
/* poll callback, context checks */
int WM_operator_winactive (struct bContext *C);
/* invoke callback, exec + redo popup */
diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h
index cb060077166..cd3899897a1 100644
--- a/source/blender/windowmanager/WM_types.h
+++ b/source/blender/windowmanager/WM_types.h
@@ -531,7 +531,7 @@ typedef struct wmOperatorType {
* is changed. It can correct its own properties or report errors for
* invalid settings in exceptional cases.
* Boolean return value, True denotes a change has been made and to redraw */
- int (*check)(struct bContext *, struct wmOperator *);
+ bool (*check)(struct bContext *, struct wmOperator *);
/* for modal temporary operators, initially invoke is called. then
* any further events are handled in modal. if the operation is
diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c
index b6aecf120cc..f4b50667b2f 100644
--- a/source/blender/windowmanager/intern/wm_files.c
+++ b/source/blender/windowmanager/intern/wm_files.c
@@ -70,6 +70,7 @@
#include "DNA_screen_types.h"
#include "DNA_windowmanager_types.h"
+#include "BKE_autoexec.h"
#include "BKE_blender.h"
#include "BKE_context.h"
#include "BKE_depsgraph.h"
@@ -364,6 +365,21 @@ static int wm_read_exotic(Scene *UNUSED(scene), const char *name)
return retval;
}
+void WM_file_autoexec_init(const char *filepath)
+{
+ if (G.f & G_SCRIPT_OVERRIDE_PREF) {
+ return;
+ }
+
+ if (G.f & G_SCRIPT_AUTOEXEC) {
+ char path[FILE_MAX];
+ BLI_split_dir_part(filepath, path, sizeof(path));
+ if (BKE_autoexec_match(path)) {
+ G.f &= ~G_SCRIPT_AUTOEXEC;
+ }
+ }
+}
+
void WM_file_read(bContext *C, const char *filepath, ReportList *reports)
{
int retval;
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 3d4bd2a1bc6..e71be6052d0 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -60,6 +60,7 @@
#include "BLO_readfile.h"
+#include "BKE_autoexec.h"
#include "BKE_blender.h"
#include "BKE_brush.h"
#include "BKE_context.h"
@@ -1038,7 +1039,7 @@ int WM_operator_filesel(bContext *C, wmOperator *op, const wmEvent *UNUSED(event
}
}
-int WM_operator_filesel_ensure_ext_imtype(wmOperator *op, const struct ImageFormatData *im_format)
+bool WM_operator_filesel_ensure_ext_imtype(wmOperator *op, const struct ImageFormatData *im_format)
{
PropertyRNA *prop;
char filepath[FILE_MAX];
@@ -1868,6 +1869,47 @@ static void WM_OT_save_homefile(wmOperatorType *ot)
ot->poll = WM_operator_winactive;
}
+static int wm_userpref_autoexec_add_exec(bContext *UNUSED(C), wmOperator *UNUSED(op))
+{
+ bPathCompare *path_cmp = MEM_callocN(sizeof(bPathCompare), "bPathCompare");
+ BLI_addtail(&U.autoexec_paths, path_cmp);
+ return OPERATOR_FINISHED;
+}
+
+static void WM_OT_userpref_autoexec_path_add(wmOperatorType *ot)
+{
+ ot->name = "Add Autoexec Path";
+ ot->idname = "WM_OT_userpref_autoexec_path_add";
+
+ ot->exec = wm_userpref_autoexec_add_exec;
+ ot->poll = WM_operator_winactive;
+
+ ot->flag = OPTYPE_INTERNAL;
+}
+
+static int wm_userpref_autoexec_remove_exec(bContext *UNUSED(C), wmOperator *op)
+{
+ const int index = RNA_int_get(op->ptr, "index");
+ bPathCompare *path_cmp = BLI_findlink(&U.autoexec_paths, index);
+ if (path_cmp) {
+ BLI_freelinkN(&U.autoexec_paths, path_cmp);
+ }
+ return OPERATOR_FINISHED;
+}
+
+static void WM_OT_userpref_autoexec_path_remove(wmOperatorType *ot)
+{
+ ot->name = "Remove Autoexec Path";
+ ot->idname = "WM_OT_userpref_autoexec_path_remove";
+
+ ot->exec = wm_userpref_autoexec_remove_exec;
+ ot->poll = WM_operator_winactive;
+
+ ot->flag = OPTYPE_INTERNAL;
+
+ RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "", 0, 1000);
+}
+
static void WM_OT_save_userpref(wmOperatorType *ot)
{
ot->name = "Save User Settings";
@@ -1916,6 +1958,12 @@ static void WM_OT_read_factory_settings(wmOperatorType *ot)
/* *************** open file **************** */
+/* currently fits in a pointer */
+struct FileRuntime {
+ bool is_untrusted;
+};
+
+
static void open_set_load_ui(wmOperator *op, bool use_prefs)
{
PropertyRNA *prop = RNA_struct_find_property(op->ptr, "load_ui");
@@ -1960,6 +2008,7 @@ static int wm_open_mainfile_invoke(bContext *C, wmOperator *op, const wmEvent *U
RNA_string_set(op->ptr, "filepath", openname);
open_set_load_ui(op, true);
open_set_use_scripts(op, true);
+ op->customdata = NULL;
WM_event_add_fileselect(C, op);
@@ -1990,11 +2039,65 @@ static int wm_open_mainfile_exec(bContext *C, wmOperator *op)
/* do it before for now, but is this correct with multiple windows? */
WM_event_add_notifier(C, NC_WINDOW, NULL);
+ /* autoexec is already set correctly for invoke() for exec() though we need to initialize */
+ if (!RNA_struct_property_is_set(op->ptr, "use_scripts")) {
+ WM_file_autoexec_init(path);
+ }
WM_file_read(C, path, op->reports);
-
+
return OPERATOR_FINISHED;
}
+static bool wm_open_mainfile_check(bContext *UNUSED(C), wmOperator *op)
+{
+ struct FileRuntime *file_info = (struct FileRuntime *)&op->customdata;
+ PropertyRNA *prop = RNA_struct_find_property(op->ptr, "use_scripts");
+ bool is_untrusted = false;
+ char path[FILE_MAX];
+ char *lslash;
+
+ RNA_string_get(op->ptr, "filepath", path);
+
+ /* get the dir */
+ lslash = (char *)BLI_last_slash(path);
+ if (lslash) *(lslash + 1) = '\0';
+
+ if ((U.flag & USER_SCRIPT_AUTOEXEC_DISABLE) == 0) {
+ if (BKE_autoexec_match(path) == true) {
+ RNA_property_boolean_set(op->ptr, prop, false);
+ is_untrusted = true;
+ }
+ }
+
+ if (file_info) {
+ file_info->is_untrusted = is_untrusted;
+ }
+
+ return is_untrusted;
+}
+
+static void wm_open_mainfile_ui(bContext *UNUSED(C), wmOperator *op)
+{
+ struct FileRuntime *file_info = (struct FileRuntime *)&op->customdata;
+ uiLayout *layout = op->layout;
+ uiLayout *col = op->layout;
+ const char *autoexec_text = NULL;
+
+ uiItemR(layout, op->ptr, "load_ui", 0, NULL, ICON_NONE);
+
+ col = uiLayoutColumn(layout, false);
+ if (file_info->is_untrusted) {
+ autoexec_text = "Trusted Source [Untrusted Path]";
+ uiLayoutSetActive(col, false);
+ uiLayoutSetEnabled(col, false);
+ }
+ else {
+ autoexec_text = "Trusted Source";
+ }
+
+ uiItemR(col, op->ptr, "use_scripts", 0, autoexec_text, ICON_NONE);
+}
+
static void WM_OT_open_mainfile(wmOperatorType *ot)
{
ot->name = "Open Blender File";
@@ -2003,6 +2106,8 @@ static void WM_OT_open_mainfile(wmOperatorType *ot)
ot->invoke = wm_open_mainfile_invoke;
ot->exec = wm_open_mainfile_exec;
+ ot->check = wm_open_mainfile_check;
+ ot->ui = wm_open_mainfile_ui;
/* ommit window poll so this can work in background mode */
WM_operator_properties_filesel(ot, FOLDERFILE | BLENDERFILE, FILE_BLENDER, FILE_OPENFILE,
@@ -2233,6 +2338,7 @@ void WM_recover_last_session(bContext *C, ReportList *reports)
WM_event_add_notifier(C, NC_WINDOW, NULL);
/* load file */
+ WM_file_autoexec_init(filename);
WM_file_read(C, filename, reports);
G.fileflags &= ~G_FILE_RECOVER;
@@ -2279,6 +2385,7 @@ static int wm_recover_auto_save_exec(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_WINDOW, NULL);
/* load file */
+ WM_file_autoexec_init(path);
WM_file_read(C, path, op->reports);
G.fileflags &= ~G_FILE_RECOVER;
@@ -2400,7 +2507,7 @@ static int wm_save_as_mainfile_exec(bContext *C, wmOperator *op)
}
/* function used for WM_OT_save_mainfile too */
-static int blend_save_check(bContext *UNUSED(C), wmOperator *op)
+static bool blend_save_check(bContext *UNUSED(C), wmOperator *op)
{
char filepath[FILE_MAX];
RNA_string_get(op->ptr, "filepath", filepath);
@@ -4044,6 +4151,8 @@ void wm_operatortype_init(void)
WM_operatortype_append(WM_OT_read_factory_settings);
WM_operatortype_append(WM_OT_save_homefile);
WM_operatortype_append(WM_OT_save_userpref);
+ WM_operatortype_append(WM_OT_userpref_autoexec_path_add);
+ WM_operatortype_append(WM_OT_userpref_autoexec_path_remove);
WM_operatortype_append(WM_OT_window_fullscreen_toggle);
WM_operatortype_append(WM_OT_quit_blender);
WM_operatortype_append(WM_OT_open_mainfile);
@@ -4101,13 +4210,12 @@ static void gesture_circle_modal_keymap(wmKeyConfig *keyconf)
WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, 0, 0, GESTURE_MODAL_SELECT);
-#if 0 /* Durien guys like this :S */
+ /* left mouse shift for deselect too */
WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, KM_SHIFT, 0, GESTURE_MODAL_DESELECT);
WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_RELEASE, KM_SHIFT, 0, GESTURE_MODAL_NOP);
-#else
+
WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_PRESS, 0, 0, GESTURE_MODAL_DESELECT); // default 2.4x
WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, 0, 0, GESTURE_MODAL_NOP); // default 2.4x
-#endif
WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_RELEASE, 0, 0, GESTURE_MODAL_NOP);
@@ -4175,21 +4283,22 @@ static void gesture_border_modal_keymap(wmKeyConfig *keyconf)
/* items for modal map */
WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, GESTURE_MODAL_CANCEL);
+
/* Note: cancel only on press otherwise you cannot map this to RMB-gesture */
WM_modalkeymap_add_item(keymap, RIGHTMOUSE, KM_PRESS, KM_ANY, 0, GESTURE_MODAL_CANCEL);
-
- WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, 0, 0, GESTURE_MODAL_BEGIN);
- WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_RELEASE, KM_ANY, 0, GESTURE_MODAL_SELECT);
WM_modalkeymap_add_item(keymap, RIGHTMOUSE, KM_RELEASE, KM_ANY, 0, GESTURE_MODAL_SELECT);
-#if 0 /* Durian guys like this */
+ /* allow shift leftclick for deselect too */
WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, KM_SHIFT, 0, GESTURE_MODAL_BEGIN);
WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_RELEASE, KM_SHIFT, 0, GESTURE_MODAL_DESELECT);
-#else
+
+ /* any unhandled leftclick release handles select */
+ WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, 0, 0, GESTURE_MODAL_BEGIN);
+ WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_RELEASE, KM_ANY, 0, GESTURE_MODAL_SELECT);
+
WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_PRESS, 0, 0, GESTURE_MODAL_BEGIN);
WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, 0, 0, GESTURE_MODAL_DESELECT);
-#endif
-
+
/* assign map to operators */
WM_modalkeymap_assign(keymap, "ACTION_OT_select_border");
WM_modalkeymap_assign(keymap, "ANIM_OT_channels_select_border");
diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt
index 7c744d10d63..8ff4ec445ea 100644
--- a/source/creator/CMakeLists.txt
+++ b/source/creator/CMakeLists.txt
@@ -488,18 +488,16 @@ elseif(WIN32)
)
if(WITH_PYTHON)
- set_lib_path(PYLIB "python")
-
string(REPLACE "." "" _PYTHON_VERSION_NO_DOTS ${PYTHON_VERSION})
install(
- FILES ${PYLIB}/lib/python${_PYTHON_VERSION_NO_DOTS}.dll
+ FILES ${LIBDIR}/python/lib/python${_PYTHON_VERSION_NO_DOTS}.dll
DESTINATION ${TARGETDIR}
CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel
)
install(
- FILES ${PYLIB}/lib/python${_PYTHON_VERSION_NO_DOTS}_d.dll
+ FILES ${LIBDIR}/python/lib/python${_PYTHON_VERSION_NO_DOTS}_d.dll
DESTINATION ${TARGETDIR}
CONFIGURATIONS Debug
)
diff --git a/source/creator/creator.c b/source/creator/creator.c
index 302467c6b3d..817bc4fcf60 100644
--- a/source/creator/creator.c
+++ b/source/creator/creator.c
@@ -1262,6 +1262,7 @@ static int load_file(int UNUSED(argc), const char **argv, void *data)
* a file - this should do everything a 'load file' does */
ReportList reports;
BKE_reports_init(&reports, RPT_PRINT);
+ WM_file_autoexec_init(filename);
WM_file_read(C, filename, &reports);
BKE_reports_clear(&reports);
}
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
index 3abc129521e..f02e842ad2e 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
@@ -521,10 +521,23 @@ void KX_KetsjiEngine::EndFrame()
RenderDebugProperties();
}
- m_average_framerate = m_logger->GetAverage();
- if (m_average_framerate < 1e-6)
- m_average_framerate = 1e-6;
- m_average_framerate = 1.0/m_average_framerate;
+ double tottime = m_logger->GetAverage(), time;
+ if (tottime < 1e-6)
+ tottime = 1e-6;
+
+#ifdef WITH_PYTHON
+ for (int i = tc_first; i < tc_numCategories; ++i) {
+ time = m_logger->GetAverage((KX_TimeCategory)i);
+ PyObject *val = PyTuple_New(2);
+ PyTuple_SetItem(val, 0, PyFloat_FromDouble(time*1000.f));
+ PyTuple_SetItem(val, 1, PyFloat_FromDouble(time/tottime * 100.f));
+
+ PyDict_SetItemString(m_pyprofiledict, m_profileLabels[i], val);
+ Py_DECREF(val);
+ }
+#endif
+
+ m_average_framerate = 1.0/tottime;
// Go to next profiling measurement, time spend after this call is shown in the next frame.
m_logger->NextMeasurement(m_kxsystem->GetTimeInSeconds());
@@ -1526,15 +1539,6 @@ void KX_KetsjiEngine::RenderDebugProperties()
m_rendertools->RenderBox2D(xcoord + (int)(2.2 * profile_indent), ycoord, m_canvas->GetWidth(), m_canvas->GetHeight(), time/tottime);
ycoord += const_ysize;
-
-#ifdef WITH_PYTHON
- PyObject *val = PyTuple_New(2);
- PyTuple_SetItem(val, 0, PyFloat_FromDouble(time*1000.f));
- PyTuple_SetItem(val, 1, PyFloat_FromDouble(time/tottime * 100.f));
-
- PyDict_SetItemString(m_pyprofiledict, m_profileLabels[j], val);
- Py_DECREF(val);
-#endif
}
}
// Add the ymargin for titles below the other section of debug info
@@ -1645,10 +1649,10 @@ void KX_KetsjiEngine::ConvertAndAddScene(const STR_String& scenename,bool overla
}
else {
if (overlay) {
- m_addingOverlayScenes.insert(scenename);
+ m_addingOverlayScenes.push_back(scenename);
}
else {
- m_addingBackgroundScenes.insert(scenename);
+ m_addingBackgroundScenes.push_back(scenename);
}
}
}
@@ -1660,7 +1664,7 @@ void KX_KetsjiEngine::RemoveScene(const STR_String& scenename)
{
if (FindScene(scenename))
{
- m_removingScenes.insert(scenename);
+ m_removingScenes.push_back(scenename);
}
else
{
@@ -1675,7 +1679,7 @@ void KX_KetsjiEngine::RemoveScheduledScenes()
{
if (m_removingScenes.size())
{
- set<STR_String>::iterator scenenameit;
+ vector<STR_String>::iterator scenenameit;
for (scenenameit=m_removingScenes.begin();scenenameit != m_removingScenes.end();scenenameit++)
{
STR_String scenename = *scenenameit;
@@ -1721,7 +1725,7 @@ KX_Scene* KX_KetsjiEngine::CreateScene(const STR_String& scenename)
void KX_KetsjiEngine::AddScheduledScenes()
{
- set<STR_String>::iterator scenenameit;
+ vector<STR_String>::iterator scenenameit;
if (m_addingOverlayScenes.size())
{
@@ -1757,7 +1761,7 @@ void KX_KetsjiEngine::AddScheduledScenes()
void KX_KetsjiEngine::ReplaceScene(const STR_String& oldscene,const STR_String& newscene)
{
- m_replace_scenes.insert(std::make_pair(oldscene,newscene));
+ m_replace_scenes.push_back(std::make_pair(oldscene,newscene));
}
// replace scene is not the same as removing and adding because the
@@ -1768,7 +1772,7 @@ void KX_KetsjiEngine::ReplaceScheduledScenes()
{
if (m_replace_scenes.size())
{
- set<pair<STR_String,STR_String> >::iterator scenenameit;
+ vector<pair<STR_String,STR_String> >::iterator scenenameit;
for (scenenameit = m_replace_scenes.begin();
scenenameit != m_replace_scenes.end();
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.h b/source/gameengine/Ketsji/KX_KetsjiEngine.h
index 0d7e41d7568..3cba3558db3 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.h
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.h
@@ -41,7 +41,6 @@
#include "KX_Python.h"
#include "KX_WorldInfo.h"
#include <vector>
-#include <set>
class KX_TimeCategoryLogger;
@@ -88,13 +87,13 @@ private:
class KX_Dome* m_dome; // dome stereo mode
/** Lists of scenes scheduled to be removed at the end of the frame. */
- std::set<STR_String> m_removingScenes;
+ std::vector<STR_String> m_removingScenes;
/** Lists of overley scenes scheduled to be added at the end of the frame. */
- std::set<STR_String> m_addingOverlayScenes;
+ std::vector<STR_String> m_addingOverlayScenes;
/** Lists of background scenes scheduled to be added at the end of the frame. */
- std::set<STR_String> m_addingBackgroundScenes;
+ std::vector<STR_String> m_addingBackgroundScenes;
/** Lists of scenes scheduled to be replaced at the end of the frame. */
- std::set<std::pair<STR_String,STR_String> > m_replace_scenes;
+ std::vector<std::pair<STR_String,STR_String> > m_replace_scenes;
/* The current list of scenes. */
KX_SceneList m_scenes;