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--SConstruct3
-rwxr-xr-xbuild_files/build_environment/install_deps.sh49
-rw-r--r--build_files/buildbot/config/user-config-glibc211-i686.py5
-rw-r--r--build_files/buildbot/config/user-config-glibc211-x86_64.py2
-rw-r--r--build_files/buildbot/config/user-config-glibc27-i686.py5
-rw-r--r--build_files/buildbot/config/user-config-glibc27-x86_64.py2
-rw-r--r--build_files/buildbot/config/user-config-player-glibc211-i686.py2
-rw-r--r--build_files/buildbot/config/user-config-player-glibc211-x86_64.py2
-rw-r--r--build_files/buildbot/config/user-config-player-glibc27-i686.py2
-rw-r--r--build_files/buildbot/config/user-config-player-glibc27-x86_64.py2
-rwxr-xr-xbuild_files/cmake/cmake_consistency_check.py2
-rwxr-xr-xbuild_files/cmake/cmake_netbeans_project.py2
-rwxr-xr-xbuild_files/cmake/cmake_qtcreator_project.py2
-rw-r--r--build_files/cmake/cmake_static_check_clang_array.py2
-rw-r--r--build_files/cmake/cmake_static_check_cppcheck.py2
-rw-r--r--build_files/cmake/cmake_static_check_smatch.py2
-rw-r--r--build_files/cmake/cmake_static_check_sparse.py2
-rw-r--r--build_files/cmake/cmake_static_check_splint.py2
-rwxr-xr-xbuild_files/cmake/example_scripts/make_quicky.py2
-rwxr-xr-xbuild_files/cmake/project_info.py2
-rw-r--r--build_files/scons/config/freebsd7-config.py2
-rw-r--r--build_files/scons/config/freebsd8-config.py2
-rw-r--r--build_files/scons/config/freebsd9-config.py2
-rw-r--r--build_files/scons/config/linuxcross-config.py2
-rw-r--r--build_files/scons/config/win32-mingw-config.py4
-rw-r--r--build_files/scons/config/win32-vc-config.py4
-rw-r--r--build_files/scons/config/win64-mingw-config.py4
-rw-r--r--build_files/scons/config/win64-vc-config.py4
-rw-r--r--build_files/scons/tools/Blender.py6
-rw-r--r--build_files/scons/tools/btools.py6
-rwxr-xr-xdoc/blender_file_format/BlendFileDnaExporter_25.py2
-rw-r--r--doc/blender_file_format/BlendFileReader.py2
-rw-r--r--doc/python_api/examples/bmesh.ops.1.py106
-rw-r--r--doc/python_api/rst/bge.logic.rst40
-rw-r--r--doc/python_api/rst/bge.types.rst4
-rw-r--r--doc/python_api/rst_from_bmesh_opdefines.py380
-rw-r--r--doc/python_api/sphinx_doc_gen.py18
-rw-r--r--extern/CMakeLists.txt7
-rw-r--r--extern/SConscript3
-rw-r--r--intern/cycles/CMakeLists.txt7
-rw-r--r--intern/cycles/SConscript2
-rw-r--r--intern/cycles/blender/blender_object.cpp5
-rw-r--r--intern/cycles/kernel/closure/bsdf_phong_ramp.h2
-rw-r--r--intern/cycles/kernel/kernel_camera.h6
-rw-r--r--intern/cycles/kernel/kernel_light.h7
-rw-r--r--intern/cycles/kernel/kernel_object.h28
-rw-r--r--intern/cycles/kernel/kernel_types.h7
-rw-r--r--intern/cycles/kernel/osl/osl_services.cpp13
-rw-r--r--intern/cycles/kernel/osl/osl_shader.cpp1
-rw-r--r--intern/cycles/kernel/shaders/node_convert_from_color.osl1
-rw-r--r--intern/cycles/kernel/shaders/node_convert_from_float.osl1
-rw-r--r--intern/cycles/kernel/shaders/node_convert_from_int.osl1
-rw-r--r--intern/cycles/kernel/shaders/node_convert_from_normal.osl1
-rw-r--r--intern/cycles/kernel/shaders/node_convert_from_point.osl1
-rw-r--r--intern/cycles/kernel/shaders/node_convert_from_string.osl31
-rw-r--r--intern/cycles/kernel/shaders/node_convert_from_vector.osl1
-rw-r--r--intern/cycles/kernel/svm/svm.h4
-rw-r--r--intern/cycles/kernel/svm/svm_brick.h21
-rw-r--r--intern/cycles/kernel/svm/svm_closure.h287
-rw-r--r--intern/cycles/kernel/svm/svm_texture.h37
-rw-r--r--intern/cycles/kernel/svm/svm_voronoi.h9
-rw-r--r--intern/cycles/render/camera.cpp2
-rw-r--r--intern/cycles/render/graph.cpp104
-rw-r--r--intern/cycles/render/graph.h17
-rw-r--r--intern/cycles/render/nodes.cpp66
-rw-r--r--intern/cycles/render/nodes.h5
-rw-r--r--intern/cycles/render/object.cpp14
-rw-r--r--intern/cycles/render/osl.cpp4
-rw-r--r--intern/cycles/render/session.cpp9
-rw-r--r--intern/cycles/render/svm.cpp124
-rw-r--r--intern/cycles/render/svm.h9
-rw-r--r--intern/cycles/util/util_transform.cpp24
-rw-r--r--intern/cycles/util/util_transform.h42
-rw-r--r--intern/ghost/GHOST_C-api.h14
-rw-r--r--intern/guardedalloc/intern/mallocn.c2
-rw-r--r--intern/utfconv/utfconv.h20
-rw-r--r--release/datafiles/startup.blendbin417000 -> 425168 bytes
-rw-r--r--release/scripts/modules/bl_i18n_utils/spell_check_utils.py3
-rwxr-xr-xrelease/scripts/modules/bl_i18n_utils/update_trunk.py2
-rw-r--r--release/scripts/modules/bpy_extras/mesh_utils.py6
-rw-r--r--release/scripts/modules/bpy_types.py2
-rw-r--r--release/scripts/modules/rna_xml.py2
-rw-r--r--release/scripts/startup/bl_operators/uvcalc_follow_active.py279
-rw-r--r--release/scripts/startup/bl_operators/uvcalc_lightmap.py2
-rw-r--r--release/scripts/startup/bl_operators/uvcalc_smart_project.py6
-rw-r--r--release/scripts/startup/bl_ui/properties_particle.py2
-rw-r--r--release/scripts/startup/bl_ui/space_userpref.py1
-rw-r--r--release/scripts/templates/bmesh_simple_editmode.py23
-rw-r--r--release/scripts/templates/script_stub.py4
-rw-r--r--source/blender/blenkernel/BKE_DerivedMesh.h8
-rw-r--r--source/blender/blenkernel/BKE_node.h4
-rw-r--r--source/blender/blenkernel/SConscript3
-rw-r--r--source/blender/blenkernel/intern/blender.c8
-rw-r--r--source/blender/blenkernel/intern/camera.c1
-rw-r--r--source/blender/blenkernel/intern/cdderivedmesh.c16
-rw-r--r--source/blender/blenkernel/intern/displist.c2
-rw-r--r--source/blender/blenkernel/intern/editderivedmesh.c2
-rw-r--r--source/blender/blenkernel/intern/image.c7
-rw-r--r--source/blender/blenkernel/intern/mask.c12
-rw-r--r--source/blender/blenkernel/intern/mask_rasterize.c2
-rw-r--r--source/blender/blenkernel/intern/mesh.c2
-rw-r--r--source/blender/blenkernel/intern/modifiers_bmesh.c6
-rw-r--r--source/blender/blenkernel/intern/node.c11
-rw-r--r--source/blender/blenkernel/intern/particle.c8
-rw-r--r--source/blender/blenkernel/intern/pointcache.c3
-rw-r--r--source/blender/blenkernel/intern/seqmodifier.c8
-rw-r--r--source/blender/blenkernel/intern/sequencer.c17
-rw-r--r--source/blender/blenkernel/intern/smoke.c2
-rw-r--r--source/blender/blenlib/BLI_array.h27
-rw-r--r--source/blender/blenlib/BLI_endian_switch.h3
-rw-r--r--source/blender/blenlib/BLI_rect.h14
-rw-r--r--source/blender/blenlib/BLI_scanfill.h13
-rw-r--r--source/blender/blenlib/BLI_utildefines.h10
-rw-r--r--source/blender/blenlib/intern/bpath.c67
-rw-r--r--source/blender/blenlib/intern/scanfill.c145
-rw-r--r--source/blender/blenlib/intern/string.c6
-rw-r--r--source/blender/blenlib/intern/string_utf8.c32
-rw-r--r--source/blender/bmesh/bmesh_class.h1
-rw-r--r--source/blender/bmesh/intern/bmesh_construct.c28
-rw-r--r--source/blender/bmesh/intern/bmesh_construct.h4
-rw-r--r--source/blender/bmesh/intern/bmesh_core.c106
-rw-r--r--source/blender/bmesh/intern/bmesh_core.h15
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh_conv.c31
-rw-r--r--source/blender/bmesh/intern/bmesh_mods.c7
-rw-r--r--source/blender/bmesh/intern/bmesh_opdefines.c1145
-rw-r--r--source/blender/bmesh/intern/bmesh_operator_api.h100
-rw-r--r--source/blender/bmesh/intern/bmesh_operator_api_inline.h63
-rw-r--r--source/blender/bmesh/intern/bmesh_operators.c219
-rw-r--r--source/blender/bmesh/intern/bmesh_operators.h15
-rw-r--r--source/blender/bmesh/intern/bmesh_operators_private.h2
-rw-r--r--source/blender/bmesh/intern/bmesh_queries.c23
-rw-r--r--source/blender/bmesh/intern/bmesh_queries.h1
-rw-r--r--source/blender/bmesh/operators/bmo_connect.c2
-rw-r--r--source/blender/bmesh/operators/bmo_create.c26
-rw-r--r--source/blender/bmesh/operators/bmo_dupe.c51
-rw-r--r--source/blender/bmesh/operators/bmo_extrude.c26
-rw-r--r--source/blender/bmesh/operators/bmo_hull.c14
-rw-r--r--source/blender/bmesh/operators/bmo_inset.c4
-rw-r--r--source/blender/bmesh/operators/bmo_mirror.c12
-rw-r--r--source/blender/bmesh/operators/bmo_primitive.c64
-rw-r--r--source/blender/bmesh/operators/bmo_removedoubles.c44
-rw-r--r--source/blender/bmesh/operators/bmo_slide.c21
-rw-r--r--source/blender/bmesh/operators/bmo_smooth_laplacian.c1
-rw-r--r--source/blender/bmesh/operators/bmo_subdivide.c48
-rw-r--r--source/blender/bmesh/operators/bmo_subdivide.h4
-rw-r--r--source/blender/bmesh/operators/bmo_symmetrize.c37
-rw-r--r--source/blender/bmesh/operators/bmo_triangulate.c8
-rw-r--r--source/blender/bmesh/operators/bmo_utils.c26
-rw-r--r--source/blender/bmesh/operators/bmo_wireframe.c8
-rw-r--r--source/blender/bmesh/tools/bmesh_bevel.c111
-rw-r--r--source/blender/bmesh/tools/bmesh_decimate.h3
-rw-r--r--source/blender/bmesh/tools/bmesh_decimate_collapse.c15
-rw-r--r--source/blender/bmesh/tools/bmesh_decimate_dissolve.c3
-rw-r--r--source/blender/collada/MaterialExporter.cpp2
-rw-r--r--source/blender/compositor/intern/COM_ExecutionGroup.cpp3
-rw-r--r--source/blender/compositor/intern/COM_ExecutionGroup.h6
-rw-r--r--source/blender/compositor/intern/COM_NodeOperation.h6
-rw-r--r--source/blender/compositor/intern/COM_WorkPackage.h2
-rw-r--r--source/blender/compositor/operations/COM_MapRangeOperation.cpp15
-rw-r--r--source/blender/compositor/operations/COM_NormalizeOperation.cpp6
-rw-r--r--source/blender/compositor/operations/COM_ViewerBaseOperation.cpp2
-rw-r--r--source/blender/editors/animation/anim_markers.c23
-rw-r--r--source/blender/editors/include/ED_view3d.h9
-rw-r--r--source/blender/editors/include/UI_interface.h3
-rw-r--r--source/blender/editors/interface/interface.c1
-rw-r--r--source/blender/editors/interface/interface_regions.c15
-rw-r--r--source/blender/editors/interface/interface_templates.c8
-rw-r--r--source/blender/editors/mesh/editmesh_add.c21
-rw-r--r--source/blender/editors/mesh/editmesh_knife.c4
-rw-r--r--source/blender/editors/mesh/editmesh_loopcut.c14
-rw-r--r--source/blender/editors/mesh/editmesh_rip.c2
-rw-r--r--source/blender/editors/mesh/editmesh_select.c12
-rw-r--r--source/blender/editors/mesh/editmesh_slide.c18
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c72
-rw-r--r--source/blender/editors/mesh/editmesh_utils.c11
-rw-r--r--source/blender/editors/mesh/mesh_navmesh.c4
-rw-r--r--source/blender/editors/object/object_add.c2
-rw-r--r--source/blender/editors/object/object_relations.c6
-rw-r--r--source/blender/editors/object/object_vgroup.c16
-rw-r--r--source/blender/editors/physics/particle_edit.c2
-rw-r--r--source/blender/editors/render/render_internal.c17
-rw-r--r--source/blender/editors/render/render_shading.c4
-rw-r--r--source/blender/editors/render/render_update.c11
-rw-r--r--source/blender/editors/sculpt_paint/paint_image.c2
-rw-r--r--source/blender/editors/sculpt_paint/paint_utils.c4
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c9
-rw-r--r--source/blender/editors/space_buttons/space_buttons.c2
-rw-r--r--source/blender/editors/space_clip/tracking_ops.c2
-rw-r--r--source/blender/editors/space_node/node_edit.c31
-rw-r--r--source/blender/editors/space_node/space_node.c2
-rw-r--r--source/blender/editors/space_outliner/outliner_draw.c2
-rw-r--r--source/blender/editors/space_outliner/outliner_edit.c7
-rw-r--r--source/blender/editors/space_outliner/outliner_select.c2
-rw-r--r--source/blender/editors/space_outliner/outliner_tree.c2
-rw-r--r--source/blender/editors/space_outliner/space_outliner.c6
-rw-r--r--source/blender/editors/space_sequencer/sequencer_draw.c2
-rw-r--r--source/blender/editors/space_sequencer/sequencer_edit.c1
-rw-r--r--source/blender/editors/space_view3d/drawmesh.c7
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c1
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c22
-rw-r--r--source/blender/editors/space_view3d/view3d_iterators.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_toolbar.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c55
-rw-r--r--source/blender/editors/transform/CMakeLists.txt1
-rw-r--r--source/blender/editors/transform/SConscript2
-rw-r--r--source/blender/editors/transform/transform.c12
-rw-r--r--source/blender/editors/transform/transform_conversions.c10
-rw-r--r--source/blender/editors/util/numinput.c3
-rw-r--r--source/blender/editors/uvedit/uvedit_ops.c104
-rw-r--r--source/blender/editors/uvedit/uvedit_smart_stitch.c12
-rw-r--r--source/blender/editors/uvedit/uvedit_unwrap_ops.c2
-rw-r--r--source/blender/gpu/GPU_draw.h2
-rw-r--r--source/blender/gpu/intern/gpu_draw.c12
-rw-r--r--source/blender/ikplugin/intern/ikplugin_api.c2
-rw-r--r--source/blender/imbuf/intern/openexr/CMakeLists.txt2
-rw-r--r--source/blender/makesdna/DNA_node_types.h3
-rw-r--r--source/blender/makesrna/intern/rna_material.c4
-rw-r--r--source/blender/makesrna/intern/rna_object.c2
-rw-r--r--source/blender/makesrna/intern/rna_scene_api.c16
-rw-r--r--source/blender/makesrna/intern/rna_texture.c8
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c11
-rwxr-xr-xsource/blender/makesrna/rna_cleanup/rna_cleaner.py2
-rwxr-xr-xsource/blender/makesrna/rna_cleanup/rna_cleaner_merge.py2
-rw-r--r--source/blender/modifiers/intern/MOD_array.c10
-rw-r--r--source/blender/modifiers/intern/MOD_decimate.c6
-rw-r--r--source/blender/modifiers/intern/MOD_skin.c21
-rw-r--r--source/blender/nodes/NOD_composite.h2
-rw-r--r--source/blender/nodes/NOD_shader.h2
-rw-r--r--source/blender/nodes/NOD_texture.h2
-rw-r--r--source/blender/nodes/intern/node_socket.c57
-rw-r--r--source/blender/python/bmesh/CMakeLists.txt2
-rw-r--r--source/blender/python/bmesh/bmesh_py_api.c50
-rw-r--r--source/blender/python/bmesh/bmesh_py_ops.c379
-rw-r--r--source/blender/python/bmesh/bmesh_py_ops_call.c783
-rw-r--r--source/blender/python/bmesh/bmesh_py_ops_call.h41
-rw-r--r--source/blender/python/bmesh/bmesh_py_types.c148
-rw-r--r--source/blender/python/bmesh/bmesh_py_types.h22
-rw-r--r--source/blender/python/bmesh/bmesh_py_types_customdata.c12
-rw-r--r--source/blender/python/bmesh/bmesh_py_types_select.c14
-rw-r--r--source/blender/python/bmesh/bmesh_py_utils.c10
-rw-r--r--source/blender/render/intern/source/convertblender.c4
-rw-r--r--source/blender/windowmanager/WM_api.h5
-rw-r--r--source/blender/windowmanager/WM_types.h1
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c6
-rw-r--r--source/blender/windowmanager/intern/wm_gesture.c2
-rw-r--r--source/blender/windowmanager/intern/wm_init_exit.c2
-rw-r--r--source/blender/windowmanager/intern/wm_jobs.c12
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c43
-rw-r--r--source/creator/CMakeLists.txt13
-rw-r--r--source/creator/blender.map7
-rw-r--r--source/creator/creator.c2
-rw-r--r--source/creator/osx_locals.map3
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.cpp2
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderMouseDevice.cpp2
-rw-r--r--source/gameengine/GamePlayer/ghost/GPG_ghost.cpp1
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsController.cpp8
-rw-r--r--source/tests/bl_run_operators.py5
259 files changed, 4511 insertions, 2596 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 751c2dd548e..0954d5ce878 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -190,8 +190,8 @@ option(WITH_MOD_FLUID "Enable Elbeem Modifier (Fluid Simulation)" ON)
option(WITH_MOD_SMOKE "Enable Smoke Modifier (Smoke Simulation)" ON)
option(WITH_MOD_BOOLEAN "Enable Boolean Modifier" ON)
option(WITH_MOD_REMESH "Enable Remesh Modifier" ON)
-option(WITH_MOD_CLOTH_ELTOPO "Enable Experimental cloth solver" OFF)
-mark_as_advanced(WITH_MOD_CLOTH_ELTOPO)
+# option(WITH_MOD_CLOTH_ELTOPO "Enable Experimental cloth solver" OFF) # this is now only available in a branch
+# mark_as_advanced(WITH_MOD_CLOTH_ELTOPO)
option(WITH_MOD_OCEANSIM "Enable Ocean Modifier" OFF)
# Image format support
@@ -271,6 +271,9 @@ mark_as_advanced(WITH_ASSERT_ABORT)
if(APPLE)
+ cmake_minimum_required(VERSION 2.8.8)
+ cmake_policy(VERSION 2.8.8)
+
if(NOT CMAKE_OSX_ARCHITECTURES)
set(CMAKE_OSX_ARCHITECTURES x86_64 CACHE STRING
"Choose the architecture you want to build Blender for: i386, x86_64 or ppc"
@@ -487,14 +490,14 @@ set(PLATFORM_LINKFLAGS_DEBUG "")
# For alternate Python locations the commandline can be used to override detected/default cache settings, e.g:
# On Unix:
# cmake ../blender \
-# -D PYTHON_VERSION=3.2 \
-# -D PYTHON_INCLUDE_DIR=/opt/py32/include/python3.2d \
-# -D PYTHON_LIBRARY=/opt/py32/lib/libpython3.2d.so
+# -D PYTHON_VERSION=3.3 \
+# -D PYTHON_INCLUDE_DIR=/opt/py33/include/python3.3d \
+# -D PYTHON_LIBRARY=/opt/py33/lib/libpython3.3d.so
#
# On Macs:
# cmake ../blender \
-# -D PYTHON_INCLUDE_DIR=/System/Library/Frameworks/Python.framework/Versions/3.2/include/python3.2 \
-# -D PYTHON_LIBPATH=/System/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/config \
+# -D PYTHON_INCLUDE_DIR=/System/Library/Frameworks/Python.framework/Versions/3.3/include/python3.3 \
+# -D PYTHON_LIBPATH=/System/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/config \
# -G Xcode
#
# When changing any of this remember to update the notes in doc/build_systems/cmake.txt
@@ -522,7 +525,7 @@ if(UNIX AND NOT APPLE)
find_package_wrapper(Freetype REQUIRED)
if(WITH_PYTHON)
- # No way to set py32. remove for now.
+ # No way to set py33. remove for now.
# find_package(PythonLibs)
# Use our own instead, since wothout py is such a rare case,
@@ -755,7 +758,6 @@ if(UNIX AND NOT APPLE)
OUTPUT_STRIP_TRAILING_WHITESPACE)
string(REPLACE " " ";" LLVM_LIBRARY ${LLVM_LIBRARY})
endif()
- message(STATUS "LLVM library = ${LLVM_LIBRARY}")
else()
message(FATAL_ERROR "LLVM not found.")
endif()
@@ -872,7 +874,7 @@ elseif(WIN32)
# Setup 64bit and 64bit windows systems
if(WITH_MINGW64)
- message("Set 64 bit compiler for MinGW.")
+ message("Compiling for 64 bit with MinGW-w64.")
set(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/mingw64)
endif()
else()
@@ -928,8 +930,6 @@ elseif(WIN32)
if(WITH_CYCLES_OSL)
set(CYCLES_OSL ${LIBDIR}/osl CACHE PATH "Path to OpenShadingLanguage installation")
- message(STATUS "CYCLES_OSL = ${CYCLES_OSL}")
-
find_library(OSL_LIB_EXEC NAMES oslexec PATHS ${CYCLES_OSL}/lib)
find_library(OSL_LIB_COMP NAMES oslcomp PATHS ${CYCLES_OSL}/lib)
find_library(OSL_LIB_QUERY NAMES oslquery PATHS ${CYCLES_OSL}/lib)
@@ -939,9 +939,6 @@ elseif(WIN32)
if(OSL_INCLUDES AND OSL_LIBRARIES AND OSL_COMPILER)
set(OSL_FOUND TRUE)
- message(STATUS "OSL includes = ${OSL_INCLUDES}")
- message(STATUS "OSL library = ${OSL_LIBRARIES}")
- message(STATUS "OSL compiler = ${OSL_COMPILER}")
else()
message(STATUS "OSL not found")
endif()
@@ -1102,9 +1099,17 @@ elseif(WIN32)
if(WITH_PYTHON)
# normally cached but not since we include them with blender
- set(PYTHON_VERSION 3.2) # CACHE STRING)
+ if(MSVC10)
+ set(PYTHON_VERSION 3.2) # CACHE STRING)
+ else()
+ set(PYTHON_VERSION 3.3) # CACHE STRING)
+ endif()
+
set_lib_path(PYTHON "python")
- set(PYTHON_LIBRARY ${PYTHON}/lib/python32.lib) #CACHE FILEPATH
+ STRING(REPLACE "." "" _PYTHON_VERSION_NO_DOTS ${PYTHON_VERSION})
+ set(PYTHON_LIBRARY ${PYTHON}/lib/python${_PYTHON_VERSION_NO_DOTS}.lib) #CACHE FILEPATH
+ unset(_PYTHON_VERSION_NO_DOTS)
+
#Shared includes for both vc2008 and vc2010
set(PYTHON_INCLUDE_DIR ${LIBDIR}/python/include/python${PYTHON_VERSION})
@@ -1212,7 +1217,7 @@ elseif(WIN32)
#comes with own pthread library
if(NOT WITH_MINGW64)
set(PTHREADS ${LIBDIR}/pthreads)
- set(PTHREADS_INCLUDE_DIRS ${PTHREADS}/include)
+ #set(PTHREADS_INCLUDE_DIRS ${PTHREADS}/include)
set(PTHREADS_LIBPATH ${PTHREADS}/lib)
set(PTHREADS_LIBRARIES pthreadGC2)
endif()
@@ -1284,9 +1289,9 @@ elseif(WIN32)
if(WITH_PYTHON)
# normally cached but not since we include them with blender
- set(PYTHON_VERSION 3.2) # CACHE STRING)
+ set(PYTHON_VERSION 3.3) # CACHE STRING)
set(PYTHON_INCLUDE_DIR "${LIBDIR}/python/include/python${PYTHON_VERSION}") # CACHE PATH)
- set(PYTHON_LIBRARY "${LIBDIR}/python/lib/python32mw.lib") # CACHE FILEPATH)
+ set(PYTHON_LIBRARY "${LIBDIR}/python/lib/python33mw.lib") # CACHE FILEPATH)
# uncached vars
set(PYTHON_INCLUDE_DIRS "${PYTHON_INCLUDE_DIR}")
@@ -1605,9 +1610,6 @@ elseif(APPLE)
find_library(LLVM_LIBRARY
NAMES LLVMAnalysis # first of a whole bunch of libs to get
PATHS ${LLVM_LIB_DIR})
- message(STATUS "LLVM version = ${LLVM_VERSION}")
- message(STATUS "LLVM dir = ${LLVM_DIRECTORY}")
- message(STATUS "LLVM lib dir = ${LLVM_LIB_DIR}")
if(LLVM_LIBRARY AND LLVM_DIRECTORY AND LLVM_LIB_DIR)
if(LLVM_STATIC)
@@ -1619,7 +1621,6 @@ elseif(APPLE)
OUTPUT_STRIP_TRAILING_WHITESPACE)
string(REPLACE " " ";" LLVM_LIBRARY ${LLVM_LIBRARY})
endif()
- message(STATUS "LLVM library = ${LLVM_LIBRARY}")
else()
message(FATAL_ERROR "LLVM not found.")
endif()
@@ -1628,8 +1629,6 @@ elseif(APPLE)
if(WITH_CYCLES_OSL)
set(CYCLES_OSL ${LIBDIR}/osl CACHE PATH "Path to OpenShadingLanguage installation")
- message(STATUS "CYCLES_OSL = ${CYCLES_OSL}")
-
find_library(OSL_LIB_EXEC NAMES oslexec PATHS ${CYCLES_OSL}/lib)
find_library(OSL_LIB_COMP NAMES oslcomp PATHS ${CYCLES_OSL}/lib)
find_library(OSL_LIB_QUERY NAMES oslquery PATHS ${CYCLES_OSL}/lib)
@@ -1640,9 +1639,6 @@ elseif(APPLE)
if(OSL_INCLUDES AND OSL_LIBRARIES AND OSL_COMPILER)
set(OSL_FOUND TRUE)
- message(STATUS "OSL includes = ${OSL_INCLUDES}")
- message(STATUS "OSL library = ${OSL_LIBRARIES}")
- message(STATUS "OSL compiler = ${OSL_COMPILER}")
else()
message(STATUS "OSL not found")
endif()
diff --git a/SConstruct b/SConstruct
index 5a1797ec1dc..d6972de8cab 100644
--- a/SConstruct
+++ b/SConstruct
@@ -312,6 +312,9 @@ if env['OURPLATFORM']=='darwin':
env.Append(LINKFLAGS=['-L'+OSX_OSL_LIBPATH,'-loslcomp','-force_load '+ OSX_OSL_LIBPATH +'/liboslexec.a','-loslquery'])
env.Append(BF_PROGRAM_LINKFLAGS=['-Xlinker','-force_load','-Xlinker',OSX_OSL_LIBPATH +'/liboslexec.a'])
+ # Trying to get rid of eventually clashes, we export some explicite as local symbols
+ env.Append(LINKFLAGS=['-Xlinker','-unexported_symbols_list','-Xlinker','./source/creator/osx_locals.map'])
+
if env['WITH_BF_OPENMP'] == 1:
if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
env['CCFLAGS'].append('/openmp')
diff --git a/build_files/build_environment/install_deps.sh b/build_files/build_environment/install_deps.sh
index 935f37b53da..f8cef63f301 100755
--- a/build_files/build_environment/install_deps.sh
+++ b/build_files/build_environment/install_deps.sh
@@ -188,9 +188,14 @@ detect_distro() {
prepare_opt() {
INFO "Ensuring $INST exists and is writable by us"
- sudo mkdir -p $INST
- sudo chown $USER $INST
- sudo chmod 775 $INST
+ if [ ! -d $INST ]; then
+ sudo mkdir -p $INST
+ fi
+
+ if [ ! -w $INST ]; then
+ sudo chown $USER $INST
+ sudo chmod 775 $INST
+ fi
}
# Check whether the current package needs to be recompiled, based on a dummy file containing a magic number in its name...
@@ -407,6 +412,7 @@ compile_OIIO() {
prepare_opt
if [ ! -d $_src ]; then
+ mkdir -p $SRC
wget -c $OIIO_SOURCE -O "$_src.tar.gz"
INFO "Unpacking OpenImageIO-$OIIO_VERSION"
@@ -450,12 +456,16 @@ EOF
cmake_d="$cmake_d -D CMAKE_PREFIX_PATH=$_inst"
cmake_d="$cmake_d -D CMAKE_INSTALL_PREFIX=$_inst"
cmake_d="$cmake_d -D BUILDSTATIC=ON"
- cmake_d="$cmake_d -D LINKSTATIC=ON"
+
+ # linking statically could give issues on Debian/Ubuntu (and probably other distros
+ # which doesn't like static linking) when linking shared oiio library due to missing
+ # text symbols (static libs should be compiled with -fPIC)
+ # cmake_d="$cmake_d -D LINKSTATIC=ON"
if [ -d $INST/boost ]; then
cmake_d="$cmake_d -D BOOST_ROOT=$INST/boost -D Boost_NO_SYSTEM_PATHS=ON"
if $ALL_STATIC; then
- cmake_d="$cmake_d -D Boost_USE_STATIC_LIBS=ON"
+ cmake_d="$cmake_d -D Boost_USE_STATIC_LIBS=ON"
fi
fi
@@ -513,6 +523,7 @@ compile_LLVM() {
prepare_opt
if [ ! -d $_src -o true ]; then
+ mkdir -p $SRC
wget -c $LLVM_SOURCE -O "$_src.tar.gz"
wget -c $LLVM_CLANG_SOURCE -O "$_src_clang.tar.gz"
@@ -603,6 +614,8 @@ compile_OSL() {
prepare_opt
if [ ! -d $_src ]; then
+ mkdir -p $SRC
+
# XXX Using git on my own repo for now, looks like archives are not updated immediately... :/
# wget -c $OSL_SOURCE -O "$_src.tar.gz"
@@ -692,6 +705,7 @@ compile_FFmpeg() {
if [ ! -d $_src ]; then
INFO "Downloading ffmpeg-$FFMPEG_VERSION"
+ mkdir -p $SRC
wget -c $FFMPEG_SOURCE -O "$_src.tar.bz2"
INFO "Unpacking ffmpeg-$FFMPEG_VERSION"
@@ -811,6 +825,29 @@ install_DEB() {
INFO "$COMMON_INFO"
INFO ""
+ if [ ! -z "`cat /etc/debian_version | grep ^6`" ]; then
+ if [ -z "`cat /etc/apt/sources.list | grep backports.debian.org`" ]; then
+ INFO "Looks like you're using Debian Squeeze which does have broken CMake"
+ INFO "It is highly recommended to install cmake from backports, otherwise"
+ INFO "compilation of some libraries could fail"
+ INFO ""
+ INFO "You could install newer CMake from debian-backports repository"
+ INFO "Add this this line to your /etc/apt/sources.lixt:"
+ INFO ""
+ INFO "deb http://backports.debian.org/debian-backports squeeze-backports main"
+ INFO ""
+ INFO "and then run:"
+ INFO ""
+ INFO "sudo apt-get update && sudo apt-get install cmake=2.8.7-4~bpo60+1 sudo apt-get install cmake=2.8.7-4~bpo60+1"
+ INFO ""
+ INFO "(you could also add this reporisotry using GUI like synaptic)"
+ INFO ""
+ INFO "Hit Enter to continue running the script, or hit Ctrl-C to abort the script"
+
+ read
+ fi
+ fi
+
sudo apt-get update
# XXX Why in hell? Let's let this stuff to the user's responsability!!!
# sudo apt-get -y upgrade
@@ -825,7 +862,7 @@ install_DEB() {
libfreetype6-dev libx11-dev libxi-dev wget libsqlite3-dev libbz2-dev libncurses5-dev \
libssl-dev liblzma-dev libreadline-dev $OPENJPEG_DEV libopenexr-dev libopenal-dev \
libglew-dev yasm $SCHRO_DEV $THEORA_DEV $VORBIS_DEV libsdl1.2-dev \
- libfftw3-dev libjack-dev python-dev patch
+ libfftw3-dev libjack-dev python-dev patch bzip2
OPENJPEG_USE=true
SCHRO_USE=true
diff --git a/build_files/buildbot/config/user-config-glibc211-i686.py b/build_files/buildbot/config/user-config-glibc211-i686.py
index e5afa2afe13..e665657d91e 100644
--- a/build_files/buildbot/config/user-config-glibc211-i686.py
+++ b/build_files/buildbot/config/user-config-glibc211-i686.py
@@ -110,8 +110,7 @@ BF_JACK_LIB_STATIC = '${BF_ZLIB}/lib/libjack.a'
# Cycles
WITH_BF_CYCLES = True
WITH_BF_CYCLES_CUDA_BINARIES = True
-#BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_13', 'sm_20', 'sm_21', 'sm_30']
-BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30']
+BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_13', 'sm_20', 'sm_21', 'sm_30']
WITH_BF_OIIO = True
WITH_BF_STATICOIIO = True
@@ -160,6 +159,6 @@ WITH_BF_OCEANSIM = True
# Compilation and optimization
BF_DEBUG = False
-REL_CCFLAGS = ['-O2', '-msse', '-msse2'] # C & C++
+REL_CCFLAGS = ['-DNDEBUG', '-O2', '-msse', '-msse2'] # C & C++
PLATFORM_LINKFLAGS = ['-lrt']
BF_PROGRAM_LINKFLAGS = ['-Wl,--whole-archive', '-loslexec', '-Wl,--no-whole-archive', '-Wl,--version-script=source/creator/blender.map']
diff --git a/build_files/buildbot/config/user-config-glibc211-x86_64.py b/build_files/buildbot/config/user-config-glibc211-x86_64.py
index dc901d25a92..420d9ed4db9 100644
--- a/build_files/buildbot/config/user-config-glibc211-x86_64.py
+++ b/build_files/buildbot/config/user-config-glibc211-x86_64.py
@@ -159,6 +159,6 @@ WITH_BF_OCEANSIM = True
# Compilation and optimization
BF_DEBUG = False
-REL_CCFLAGS = ['-O2', '-msse', '-msse2'] # C & C++
+REL_CCFLAGS = ['-DNDEBUG', '-O2', '-msse', '-msse2'] # C & C++
PLATFORM_LINKFLAGS = ['-lrt']
BF_PROGRAM_LINKFLAGS = ['-Wl,--whole-archive', '-loslexec', '-Wl,--no-whole-archive', '-Wl,--version-script=source/creator/blender.map']
diff --git a/build_files/buildbot/config/user-config-glibc27-i686.py b/build_files/buildbot/config/user-config-glibc27-i686.py
index dd3a63d0fd7..b36196fd835 100644
--- a/build_files/buildbot/config/user-config-glibc27-i686.py
+++ b/build_files/buildbot/config/user-config-glibc27-i686.py
@@ -97,8 +97,7 @@ WITH_BF_JACK = True
# Cycles
WITH_BF_CYCLES = True
WITH_BF_CYCLES_CUDA_BINARIES = True
-#BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_13', 'sm_20', 'sm_21', 'sm_30']
-BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30']
+BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_13', 'sm_20', 'sm_21', 'sm_30']
WITH_BF_OIIO = True
WITH_BF_STATICOIIO = True
@@ -145,6 +144,6 @@ WITH_BF_OCEANSIM = True
# Compilation and optimization
BF_DEBUG = False
-REL_CCFLAGS = ['-O2'] # C & C++
+REL_CCFLAGS = ['-DNDEBUG', '-DNDEBUG', '-O2'] # C & C++
PLATFORM_LINKFLAGS = ['-L/home/sources/staticlibs/lib32']
BF_PROGRAM_LINKFLAGS = ['-Wl,--whole-archive', '-loslexec', '-Wl,--no-whole-archive', '-Wl,--version-script=source/creator/blender.map']
diff --git a/build_files/buildbot/config/user-config-glibc27-x86_64.py b/build_files/buildbot/config/user-config-glibc27-x86_64.py
index d9e50d258bc..7359e155586 100644
--- a/build_files/buildbot/config/user-config-glibc27-x86_64.py
+++ b/build_files/buildbot/config/user-config-glibc27-x86_64.py
@@ -144,6 +144,6 @@ WITH_BF_OCEANSIM = True
# Compilation and optimization
BF_DEBUG = False
-REL_CCFLAGS = ['-O2', '-msse', '-msse2'] # C & C++
+REL_CCFLAGS = ['-DNDEBUG', '-O2', '-msse', '-msse2'] # C & C++
PLATFORM_LINKFLAGS = ['-L/home/sources/staticlibs/lib64']
BF_PROGRAM_LINKFLAGS = ['-Wl,--whole-archive', '-loslexec', '-Wl,--no-whole-archive', '-Wl,--version-script=source/creator/blender.map']
diff --git a/build_files/buildbot/config/user-config-player-glibc211-i686.py b/build_files/buildbot/config/user-config-player-glibc211-i686.py
index 00bfdbb16f2..96f201235c4 100644
--- a/build_files/buildbot/config/user-config-player-glibc211-i686.py
+++ b/build_files/buildbot/config/user-config-player-glibc211-i686.py
@@ -117,5 +117,5 @@ WITH_BF_OCEANSIM = True
# Compilation and optimization
BF_DEBUG = False
-REL_CCFLAGS = ['-O2', '-msse', '-msse2'] # C & C++
+REL_CCFLAGS = ['-DNDEBUG', '-O2', '-msse', '-msse2'] # C & C++
PLATFORM_LINKFLAGS = ['-lrt']
diff --git a/build_files/buildbot/config/user-config-player-glibc211-x86_64.py b/build_files/buildbot/config/user-config-player-glibc211-x86_64.py
index f6eef4f89d9..75979d0bcfe 100644
--- a/build_files/buildbot/config/user-config-player-glibc211-x86_64.py
+++ b/build_files/buildbot/config/user-config-player-glibc211-x86_64.py
@@ -117,5 +117,5 @@ WITH_BF_OCEANSIM = True
# Compilation and optimization
BF_DEBUG = False
-REL_CCFLAGS = ['-O2', '-msse', '-msse2'] # C & C++
+REL_CCFLAGS = ['-DNDEBUG', '-O2', '-msse', '-msse2'] # C & C++
PLATFORM_LINKFLAGS = ['-lrt']
diff --git a/build_files/buildbot/config/user-config-player-glibc27-i686.py b/build_files/buildbot/config/user-config-player-glibc27-i686.py
index 1e834c0c8d2..82b105c4527 100644
--- a/build_files/buildbot/config/user-config-player-glibc27-i686.py
+++ b/build_files/buildbot/config/user-config-player-glibc27-i686.py
@@ -110,5 +110,5 @@ WITH_BF_OCEANSIM = True
# Compilation and optimization
BF_DEBUG = False
-REL_CCFLAGS = ['-O2'] # C & C++
+REL_CCFLAGS = ['-DNDEBUG', '-O2'] # C & C++
PLATFORM_LINKFLAGS = ['-L/home/sources/staticlibs/lib32']
diff --git a/build_files/buildbot/config/user-config-player-glibc27-x86_64.py b/build_files/buildbot/config/user-config-player-glibc27-x86_64.py
index aa0a69c44d8..1e6aa4af802 100644
--- a/build_files/buildbot/config/user-config-player-glibc27-x86_64.py
+++ b/build_files/buildbot/config/user-config-player-glibc27-x86_64.py
@@ -110,5 +110,5 @@ WITH_BF_OCEANSIM = True
# Compilation and optimization
BF_DEBUG = False
-REL_CCFLAGS = ['-O2', '-msse', '-msse2'] # C & C++
+REL_CCFLAGS = ['-DNDEBUG', '-O2', '-msse', '-msse2'] # C & C++
PLATFORM_LINKFLAGS = ['-L/home/sources/staticlibs/lib64']
diff --git a/build_files/cmake/cmake_consistency_check.py b/build_files/cmake/cmake_consistency_check.py
index 83ebf927b3c..b13b0ddb424 100755
--- a/build_files/cmake/cmake_consistency_check.py
+++ b/build_files/cmake/cmake_consistency_check.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python3.2
+#!/usr/bin/env python3
# ***** BEGIN GPL LICENSE BLOCK *****
#
diff --git a/build_files/cmake/cmake_netbeans_project.py b/build_files/cmake/cmake_netbeans_project.py
index 8f3835c3401..2f36cad4d24 100755
--- a/build_files/cmake/cmake_netbeans_project.py
+++ b/build_files/cmake/cmake_netbeans_project.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python3.2
+#!/usr/bin/env python3
# ***** BEGIN GPL LICENSE BLOCK *****
#
diff --git a/build_files/cmake/cmake_qtcreator_project.py b/build_files/cmake/cmake_qtcreator_project.py
index 83ea761e2d1..86201da23de 100755
--- a/build_files/cmake/cmake_qtcreator_project.py
+++ b/build_files/cmake/cmake_qtcreator_project.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python3.2
+#!/usr/bin/env python3
# ***** BEGIN GPL LICENSE BLOCK *****
#
diff --git a/build_files/cmake/cmake_static_check_clang_array.py b/build_files/cmake/cmake_static_check_clang_array.py
index db4e762932e..7f45cc6aadc 100644
--- a/build_files/cmake/cmake_static_check_clang_array.py
+++ b/build_files/cmake/cmake_static_check_clang_array.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python3.2
+#!/usr/bin/env python3
# ***** BEGIN GPL LICENSE BLOCK *****
#
diff --git a/build_files/cmake/cmake_static_check_cppcheck.py b/build_files/cmake/cmake_static_check_cppcheck.py
index 518b94d74a5..12369a5e8cd 100644
--- a/build_files/cmake/cmake_static_check_cppcheck.py
+++ b/build_files/cmake/cmake_static_check_cppcheck.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python3.2
+#!/usr/bin/env python3
# ***** BEGIN GPL LICENSE BLOCK *****
#
diff --git a/build_files/cmake/cmake_static_check_smatch.py b/build_files/cmake/cmake_static_check_smatch.py
index 8f7bd37d4c3..7535f1cc55a 100644
--- a/build_files/cmake/cmake_static_check_smatch.py
+++ b/build_files/cmake/cmake_static_check_smatch.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python3.2
+#!/usr/bin/env python3
# ***** BEGIN GPL LICENSE BLOCK *****
#
diff --git a/build_files/cmake/cmake_static_check_sparse.py b/build_files/cmake/cmake_static_check_sparse.py
index 92d590e52ac..06bef1a1327 100644
--- a/build_files/cmake/cmake_static_check_sparse.py
+++ b/build_files/cmake/cmake_static_check_sparse.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python3.2
+#!/usr/bin/env python3
# ***** BEGIN GPL LICENSE BLOCK *****
#
diff --git a/build_files/cmake/cmake_static_check_splint.py b/build_files/cmake/cmake_static_check_splint.py
index d3f22191021..5b1207543f5 100644
--- a/build_files/cmake/cmake_static_check_splint.py
+++ b/build_files/cmake/cmake_static_check_splint.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python3.2
+#!/usr/bin/env python3
# ***** BEGIN GPL LICENSE BLOCK *****
#
diff --git a/build_files/cmake/example_scripts/make_quicky.py b/build_files/cmake/example_scripts/make_quicky.py
index 9b853fc01d4..76d4df32f86 100755
--- a/build_files/cmake/example_scripts/make_quicky.py
+++ b/build_files/cmake/example_scripts/make_quicky.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python3.2
+#!/usr/bin/env python3
# ##### BEGIN GPL LICENSE BLOCK #####
#
diff --git a/build_files/cmake/project_info.py b/build_files/cmake/project_info.py
index b154d578144..34f378a58dd 100755
--- a/build_files/cmake/project_info.py
+++ b/build_files/cmake/project_info.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python3.2
+#!/usr/bin/env python3
# ***** BEGIN GPL LICENSE BLOCK *****
#
diff --git a/build_files/scons/config/freebsd7-config.py b/build_files/scons/config/freebsd7-config.py
index 61358de12b4..02c9093567a 100644
--- a/build_files/scons/config/freebsd7-config.py
+++ b/build_files/scons/config/freebsd7-config.py
@@ -7,7 +7,7 @@ LIBDIR = "${LCGDIR}"
BF_PYTHON_ABI_FLAGS = ''
BF_PYTHON = '/usr/local'
BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib'
-BF_PYTHON_VERSION = '3.2'
+BF_PYTHON_VERSION = '3.3'
WITH_BF_STATICPYTHON = False
BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}${BF_PYTHON_ABI_FLAGS}'
BF_PYTHON_BINARY = '${BF_PYTHON}/bin/python${BF_PYTHON_VERSION}'
diff --git a/build_files/scons/config/freebsd8-config.py b/build_files/scons/config/freebsd8-config.py
index 0f6c7f64786..5d3308c50d4 100644
--- a/build_files/scons/config/freebsd8-config.py
+++ b/build_files/scons/config/freebsd8-config.py
@@ -7,7 +7,7 @@ LIBDIR = "${LCGDIR}"
BF_PYTHON_ABI_FLAGS = ''
BF_PYTHON = '/usr/local'
BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib'
-BF_PYTHON_VERSION = '3.2'
+BF_PYTHON_VERSION = '3.3'
WITH_BF_STATICPYTHON = False
BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}${BF_PYTHON_ABI_FLAGS}'
BF_PYTHON_BINARY = '${BF_PYTHON}/bin/python${BF_PYTHON_VERSION}'
diff --git a/build_files/scons/config/freebsd9-config.py b/build_files/scons/config/freebsd9-config.py
index c0df68f99ad..98c2c8fa500 100644
--- a/build_files/scons/config/freebsd9-config.py
+++ b/build_files/scons/config/freebsd9-config.py
@@ -7,7 +7,7 @@ LIBDIR = "${LCGDIR}"
BF_PYTHON_ABI_FLAGS = ''
BF_PYTHON = '/usr/local'
BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib'
-BF_PYTHON_VERSION = '3.2'
+BF_PYTHON_VERSION = '3.3'
WITH_BF_STATICPYTHON = False
BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}${BF_PYTHON_ABI_FLAGS}'
BF_PYTHON_BINARY = '${BF_PYTHON}/bin/python${BF_PYTHON_VERSION}'
diff --git a/build_files/scons/config/linuxcross-config.py b/build_files/scons/config/linuxcross-config.py
index 63264807720..54faf59b2a4 100644
--- a/build_files/scons/config/linuxcross-config.py
+++ b/build_files/scons/config/linuxcross-config.py
@@ -2,7 +2,7 @@ LCGDIR = '#../lib/windows'
LIBDIR = '${LCGDIR}'
BF_PYTHON = LIBDIR + '/python'
-BF_PYTHON_VERSION = '3.2'
+BF_PYTHON_VERSION = '3.3'
BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}'
BF_PYTHON_BINARY = 'python'
BF_PYTHON_LIB = 'python${BF_PYTHON_VERSION[0]}${BF_PYTHON_VERSION[2]}mw'
diff --git a/build_files/scons/config/win32-mingw-config.py b/build_files/scons/config/win32-mingw-config.py
index 80e3592c71e..391421609d2 100644
--- a/build_files/scons/config/win32-mingw-config.py
+++ b/build_files/scons/config/win32-mingw-config.py
@@ -2,12 +2,12 @@ LCGDIR = '#../lib/mingw32'
LIBDIR = "${LCGDIR}"
BF_PYTHON = LIBDIR + '/python'
-BF_PYTHON_VERSION = '3.2'
+BF_PYTHON_VERSION = '3.3'
WITH_BF_STATICPYTHON = False
BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}'
BF_PYTHON_BINARY = 'python'
BF_PYTHON_LIB = 'python${BF_PYTHON_VERSION[0]}${BF_PYTHON_VERSION[2]}mw'
-BF_PYTHON_DLL = 'python32'
+BF_PYTHON_DLL = 'python33'
BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib'
BF_PYTHON_LIB_STATIC = '${BF_PYTHON}/lib/libpython${BF_PYTHON_VERSION[0]}${BF_PYTHON_VERSION[2]}.a'
diff --git a/build_files/scons/config/win32-vc-config.py b/build_files/scons/config/win32-vc-config.py
index 2120938ec71..21488e75f7e 100644
--- a/build_files/scons/config/win32-vc-config.py
+++ b/build_files/scons/config/win32-vc-config.py
@@ -9,10 +9,10 @@ BF_FFMPEG_LIB = 'avformat-53.lib avcodec-53.lib avdevice-53.lib avutil-51.lib sw
BF_FFMPEG_DLL = '${BF_FFMPEG_LIBPATH}/avformat-53.dll ${BF_FFMPEG_LIBPATH}/avcodec-53.dll ${BF_FFMPEG_LIBPATH}/avdevice-53.dll ${BF_FFMPEG_LIBPATH}/avutil-51.dll ${BF_FFMPEG_LIBPATH}/swscale-2.dll'
BF_PYTHON = LIBDIR + '/python'
-BF_PYTHON_VERSION = '3.2'
+BF_PYTHON_VERSION = '3.3'
BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}'
BF_PYTHON_BINARY = 'python'
-BF_PYTHON_LIB = 'python32'
+BF_PYTHON_LIB = 'python33'
BF_PYTHON_DLL = '${BF_PYTHON_LIB}'
BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib'
diff --git a/build_files/scons/config/win64-mingw-config.py b/build_files/scons/config/win64-mingw-config.py
index fdfd792f180..d00e7a3ffa7 100644
--- a/build_files/scons/config/win64-mingw-config.py
+++ b/build_files/scons/config/win64-mingw-config.py
@@ -2,12 +2,12 @@ LCGDIR = '#../lib/mingw64'
LIBDIR = "${LCGDIR}"
BF_PYTHON = LIBDIR + '/python'
-BF_PYTHON_VERSION = '3.2'
+BF_PYTHON_VERSION = '3.3'
WITH_BF_STATICPYTHON = False
BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}'
BF_PYTHON_BINARY = 'python'
BF_PYTHON_LIB = 'python${BF_PYTHON_VERSION[0]}${BF_PYTHON_VERSION[2]}mw'
-BF_PYTHON_DLL = 'python32'
+BF_PYTHON_DLL = 'python33'
BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib'
WITH_BF_OPENAL = True
diff --git a/build_files/scons/config/win64-vc-config.py b/build_files/scons/config/win64-vc-config.py
index 15bcdf999bd..c0ea7972aeb 100644
--- a/build_files/scons/config/win64-vc-config.py
+++ b/build_files/scons/config/win64-vc-config.py
@@ -9,10 +9,10 @@ BF_FFMPEG_LIB = 'avformat-53.lib avcodec-53.lib avdevice-53.lib avutil-51.lib sw
BF_FFMPEG_DLL = '${BF_FFMPEG_LIBPATH}/avformat-53.dll ${BF_FFMPEG_LIBPATH}/avcodec-53.dll ${BF_FFMPEG_LIBPATH}/avdevice-53.dll ${BF_FFMPEG_LIBPATH}/avutil-51.dll ${BF_FFMPEG_LIBPATH}/swscale-2.dll'
BF_PYTHON = LIBDIR + '/python'
-BF_PYTHON_VERSION = '3.2'
+BF_PYTHON_VERSION = '3.3'
BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}'
BF_PYTHON_BINARY = 'python'
-BF_PYTHON_LIB = 'python32'
+BF_PYTHON_LIB = 'python33'
BF_PYTHON_DLL = '${BF_PYTHON_LIB}'
BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib'
diff --git a/build_files/scons/tools/Blender.py b/build_files/scons/tools/Blender.py
index 2e0c81126b4..6f6308867b6 100644
--- a/build_files/scons/tools/Blender.py
+++ b/build_files/scons/tools/Blender.py
@@ -166,10 +166,12 @@ def setup_staticlibs(lenv):
libincs += Split(lenv['BF_FFTW3_LIBPATH'])
if lenv['WITH_BF_STATICFFTW3']:
statlibs += Split(lenv['BF_FFTW3_LIB_STATIC'])
+ '''
if lenv['WITH_BF_ELTOPO']:
libincs += Split(lenv['BF_LAPACK_LIBPATH'])
if lenv['WITH_BF_STATICLAPACK']:
- statlibs += Split(lenv['BF_LAPACK_LIB_STATIC'])
+ statlibs += Split(lenv['BF_LAPACK_LIB_STATIC'])
+ '''
if lenv['WITH_BF_FFMPEG'] and lenv['WITH_BF_STATICFFMPEG']:
statlibs += Split(lenv['BF_FFMPEG_LIB_STATIC'])
if lenv['WITH_BF_INTERNATIONAL']:
@@ -293,8 +295,10 @@ def setup_syslibs(lenv):
syslibs += Split(lenv['BF_SNDFILE_LIB'])
if lenv['WITH_BF_FFTW3'] and not lenv['WITH_BF_STATICFFTW3']:
syslibs += Split(lenv['BF_FFTW3_LIB'])
+ '''
if lenv['WITH_BF_ELTOPO']:
syslibs += Split(lenv['BF_LAPACK_LIB'])
+ '''
if lenv['WITH_BF_SDL']:
syslibs += Split(lenv['BF_SDL_LIB'])
if not lenv['WITH_BF_STATICOPENGL']:
diff --git a/build_files/scons/tools/btools.py b/build_files/scons/tools/btools.py
index ab963d4543c..19f4ac9a1de 100644
--- a/build_files/scons/tools/btools.py
+++ b/build_files/scons/tools/btools.py
@@ -119,7 +119,8 @@ def validate_arguments(args, bc):
'WITH_BF_ICONV', 'BF_ICONV', 'BF_ICONV_INC', 'BF_ICONV_LIB', 'BF_ICONV_LIBPATH',
'WITH_BF_GAMEENGINE',
'WITH_BF_BULLET', 'BF_BULLET', 'BF_BULLET_INC', 'BF_BULLET_LIB',
- 'WITH_BF_ELTOPO', 'BF_LAPACK', 'BF_LAPACK_LIB', 'BF_LAPACK_LIBPATH', 'BF_LAPACK_LIB_STATIC',
+ # 'WITH_BF_ELTOPO', # now only available in a branch
+ 'BF_LAPACK', 'BF_LAPACK_LIB', 'BF_LAPACK_LIBPATH', 'BF_LAPACK_LIB_STATIC',
'BF_WINTAB', 'BF_WINTAB_INC',
'BF_FREETYPE', 'BF_FREETYPE_INC', 'BF_FREETYPE_LIB', 'BF_FREETYPE_LIBPATH', 'BF_FREETYPE_LIB_STATIC', 'WITH_BF_FREETYPE_STATIC',
'WITH_BF_QUICKTIME', 'BF_QUICKTIME', 'BF_QUICKTIME_INC', 'BF_QUICKTIME_LIB', 'BF_QUICKTIME_LIBPATH',
@@ -393,8 +394,7 @@ def read_opts(env, cfg, args):
(BoolVariable('WITH_BF_GAMEENGINE', 'Build with gameengine' , False)),
(BoolVariable('WITH_BF_BULLET', 'Use Bullet if true', True)),
-
- (BoolVariable('WITH_BF_ELTOPO', 'Use Eltopo collision library if true', False)),
+ # (BoolVariable('WITH_BF_ELTOPO', 'Use Eltopo collision library if true', False)), # this is now only available in a branch
('BF_LAPACK', 'LAPACK base path', ''),
('BF_LAPACK_LIB', 'LAPACK library', ''),
('BF_LAPACK_LIB_STATIC', 'LAPACK library', ''),
diff --git a/doc/blender_file_format/BlendFileDnaExporter_25.py b/doc/blender_file_format/BlendFileDnaExporter_25.py
index b7b89c89268..837b67c6eed 100755
--- a/doc/blender_file_format/BlendFileDnaExporter_25.py
+++ b/doc/blender_file_format/BlendFileDnaExporter_25.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python3.2
+#!/usr/bin/env python3
# ***** BEGIN GPL LICENSE BLOCK *****
#
diff --git a/doc/blender_file_format/BlendFileReader.py b/doc/blender_file_format/BlendFileReader.py
index b7091ad8ff5..a4d2f494c5b 100644
--- a/doc/blender_file_format/BlendFileReader.py
+++ b/doc/blender_file_format/BlendFileReader.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python3.2
+#!/usr/bin/env python3
# ***** BEGIN GPL LICENSE BLOCK *****
#
diff --git a/doc/python_api/examples/bmesh.ops.1.py b/doc/python_api/examples/bmesh.ops.1.py
new file mode 100644
index 00000000000..2eefb63a23d
--- /dev/null
+++ b/doc/python_api/examples/bmesh.ops.1.py
@@ -0,0 +1,106 @@
+# This script uses bmesh operators to make 2 links of a chain.
+
+import bpy
+import bmesh
+import math
+import mathutils
+
+# Make a new BMesh
+bm = bmesh.new()
+
+# Add a circle XXX, should return all geometry created, not just verts.
+bmesh.ops.create_circle(
+ bm,
+ cap_ends=False,
+ diameter=0.2,
+ segments=8)
+
+
+# Spin and deal with geometry on side 'a'
+edges_start_a = bm.edges[:]
+geom_start_a = bm.verts[:] + edges_start_a
+ret = bmesh.ops.spin(
+ bm,
+ geom=geom_start_a,
+ angle=math.radians(180.0),
+ steps=8,
+ axis=(1.0, 0.0, 0.0),
+ cent=(0.0, 1.0, 0.0))
+edges_end_a = [ele for ele in ret["geom_last"]
+ if isinstance(ele, bmesh.types.BMEdge)]
+del ret
+
+
+# Extrude and create geometry on side 'b'
+ret = bmesh.ops.extrude_edge_only(
+ bm,
+ edges=edges_start_a)
+geom_extrude_mid = ret["geom"]
+del ret
+
+
+# Collect the edges to spin XXX, 'extrude_edge_only' could return this.
+verts_extrude_b = [ele for ele in geom_extrude_mid
+ if isinstance(ele, bmesh.types.BMVert)]
+edges_extrude_b = [ele for ele in geom_extrude_mid
+ if isinstance(ele, bmesh.types.BMEdge) and ele.is_boundary]
+bmesh.ops.translate(
+ bm,
+ verts=verts_extrude_b,
+ vec=(0.0, 0.0, 1.0))
+
+
+# Create the circle on side 'b'
+ret = bmesh.ops.spin(
+ bm,
+ geom=verts_extrude_b + edges_extrude_b,
+ angle=-math.radians(180.0),
+ steps=8,
+ axis=(1.0, 0.0, 0.0),
+ cent=(0.0, 1.0, 1.0))
+edges_end_b = [ele for ele in ret["geom_last"]
+ if isinstance(ele, bmesh.types.BMEdge)]
+del ret
+
+
+# Bridge the resulting edge loops of both spins 'a & b'
+bmesh.ops.bridge_loops(
+ bm,
+ edges=edges_end_a + edges_end_b)
+
+
+# Now we have made a links of the chain, make a copy and rotate it
+# (so this looks something like a chain)
+
+ret = bmesh.ops.duplicate(
+ bm,
+ geom=bm.verts[:] + bm.edges[:] + bm.faces[:])
+geom_dupe = ret["geom"]
+verts_dupe = [ele for ele in geom_dupe if isinstance(ele, bmesh.types.BMVert)]
+del ret
+
+# position the new link
+bmesh.ops.translate(
+ bm,
+ verts=verts_dupe,
+ vec=(0.0, 0.0, 2.0))
+bmesh.ops.rotate(
+ bm,
+ verts=verts_dupe,
+ cent=(0.0, 1.0, 0.0),
+ matrix=mathutils.Matrix.Rotation(math.radians(90.0), 3, 'Z'))
+
+# Done with creating the mesh, simply link it into the scene so we can see it
+
+# Finish up, write the bmesh into a new mesh
+me = bpy.data.meshes.new("Mesh")
+bm.to_mesh(me)
+
+# Add the mesh to the scene
+scene = bpy.context.scene
+obj = bpy.data.objects.new("Object", me)
+scene.objects.link(obj)
+
+# Select and make active
+scene.objects.active = obj
+obj.select = True
diff --git a/doc/python_api/rst/bge.logic.rst b/doc/python_api/rst/bge.logic.rst
index acf28706709..7d20aa31a36 100644
--- a/doc/python_api/rst/bge.logic.rst
+++ b/doc/python_api/rst/bge.logic.rst
@@ -416,9 +416,9 @@ Sensor Status
.. data:: KX_SENSOR_ACTIVE
.. data:: KX_SENSOR_JUST_DEACTIVATED
--------------
+---------------
Armature Sensor
--------------
+---------------
.. _armaturesensor-type:
@@ -537,9 +537,9 @@ See :class:`bge.types.BL_ActionActuator`
.. data:: KX_ACTIONACT_LOOPEND
.. data:: KX_ACTIONACT_PROPERTY
----------------
+-----------------
Armature Actuator
----------------
+-----------------
.. _armatureactuator-constants-type:
@@ -556,13 +556,13 @@ See :class:`bge.types.BL_ArmatureActuator.type`
.. data:: KX_ACT_ARMATURE_ENABLE
Enable the constraint.
-
+
:value: 1
.. data:: KX_ACT_ARMATURE_DISABLE
Disable the constraint (runtime constraint values are not updated).
-
+
:value: 2
.. data:: KX_ACT_ARMATURE_SETTARGET
@@ -809,9 +809,9 @@ See :class:`bge.types.KX_SoundActuator`
:value: 6
---------------
+-----------------
Steering Actuator
---------------
+-----------------
.. _logic-steering-actuator:
@@ -961,9 +961,9 @@ See :class:`bge.types.BL_ArmatureChannel.rotation_mode`
:value: 6
-----------------
+-------------------
Armature Constraint
-----------------
+-------------------
.. _armatureconstraint-constants-type:
See :class:`bge.types.BL_ArmatureConstraint.type`
@@ -1075,9 +1075,9 @@ See :class:`bge.types.SCA_PythonKeyboard`, :class:`bge.types.SCA_PythonMouse`, :
.. data:: KX_INPUT_ACTIVE
.. data:: KX_INPUT_JUST_RELEASED
-------------
+-------------
KX_GameObject
------------
+-------------
.. _gameobject-playaction-mode:
See :class:`bge.types.KX_GameObject.playAction`
@@ -1111,9 +1111,9 @@ See :class:`bge.types.SCA_MouseSensor`
.. data:: KX_MOUSE_BUT_MIDDLE
.. data:: KX_MOUSE_BUT_RIGHT
-------------
+--------------------------
Navigation Mesh Draw Modes
-------------
+--------------------------
.. _navmesh-draw-mode:
@@ -1199,25 +1199,25 @@ See :class:`bge.types.KX_StateActuator.operation`
.. data:: KX_STATE_OP_CLR
Substract bits to state mask
-
+
:value: 0
.. data:: KX_STATE_OP_CPY
Copy state mask
-
+
:value: 1
.. data:: KX_STATE_OP_NEG
Invert bits to state mask
-
+
:value: 2
-
+
.. data:: KX_STATE_OP_SET
Add bits to state mask
-
+
:value: 3
-
+
.. _Two-D-FilterActuator-mode:
diff --git a/doc/python_api/rst/bge.types.rst b/doc/python_api/rst/bge.types.rst
index f7a63b48f61..8cf9ccb794c 100644
--- a/doc/python_api/rst/bge.types.rst
+++ b/doc/python_api/rst/bge.types.rst
@@ -759,6 +759,10 @@ Types
The id is derived from a memory location and will be different each time the game engine starts.
+ .. warning::
+
+ The id can't be stored as an integer in game object properties, as those only have a limited range that the id may not be contained in. Instead an id can be stored as a string game property and converted back to an integer for use in from_id lookups.
+
.. class:: KX_BlenderMaterial(PyObjectPlus)
KX_BlenderMaterial
diff --git a/doc/python_api/rst_from_bmesh_opdefines.py b/doc/python_api/rst_from_bmesh_opdefines.py
new file mode 100644
index 00000000000..c1b6643389d
--- /dev/null
+++ b/doc/python_api/rst_from_bmesh_opdefines.py
@@ -0,0 +1,380 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+# This is a quite stupid script which extracts bmesh api docs from
+# 'bmesh_opdefines.c' in order to avoid having to add a lot of introspection
+# data access into the api.
+#
+# The script is stupid becase it makes assumptions about formatting...
+# that each arg has its own line, that comments above or directly after will be __doc__ etc...
+#
+# We may want to replace this script with something else one day but for now its good enough.
+# if it needs large updates it may be better to rewrite using a real parser or
+# add introspection into bmesh.ops.
+# - campbell
+
+import os
+
+CURRENT_DIR = os.path.abspath(os.path.dirname(__file__))
+SOURCE_DIR = os.path.normpath(os.path.abspath(os.path.normpath(os.path.join(CURRENT_DIR, "..", ".."))))
+FILE_OP_DEFINES_C = os.path.join(SOURCE_DIR, "source", "blender", "bmesh", "intern", "bmesh_opdefines.c")
+OUT_RST = os.path.join(CURRENT_DIR, "rst", "bmesh.ops.rst")
+
+HEADER = r"""
+BMesh Operators (bmesh.ops)
+===========================
+
+.. module:: bmesh.ops
+
+This module gives access to low level bmesh operations.
+
+Most operators take input and return output, they can be chained together
+to perform useful operations.
+
+.. note::
+
+ This API us new in 2.65 and not yet well tested.
+
+
+Operator Example
+++++++++++++++++
+This script shows how operators can be used to model a link of a chain.
+
+.. literalinclude:: ../examples/bmesh.ops.1.py
+"""
+
+
+def main():
+ fsrc = open(FILE_OP_DEFINES_C, 'r', encoding="utf-8")
+
+ blocks = []
+
+ is_block = False
+ is_comment = False # /* global comments only */
+
+ comment_ctx = None
+ block_ctx = None
+
+ for l in fsrc:
+ l = l[:-1]
+ # weak but ok
+ if ("BMOpDefine" in l and l.split()[1] == "BMOpDefine") and not "bmo_opdefines[]" in l:
+ is_block = True
+ block_ctx = []
+ blocks.append((comment_ctx, block_ctx))
+ elif l.strip().startswith("/*"):
+ is_comment = True
+ comment_ctx = []
+
+ if is_block:
+ if l.strip().startswith("//"):
+ pass
+ else:
+ # remove c++ comment if we have one
+ cpp_comment = l.find("//")
+ if cpp_comment != -1:
+ l = l[:cpp_comment]
+
+ block_ctx.append(l)
+
+ if l.strip() == "};":
+ is_block = False
+ comment_ctx = None
+
+ if is_comment:
+ c_comment_start = l.find("/*")
+ if c_comment_start != -1:
+ l = l[c_comment_start + 2:]
+
+ c_comment_end = l.find("*/")
+ if c_comment_end != -1:
+ l = l[:c_comment_end]
+
+ is_comment = False
+ comment_ctx.append(l)
+
+ fsrc.close()
+ del fsrc
+
+
+ # namespace hack
+ vars = (
+ "BMO_OP_SLOT_ELEMENT_BUF",
+ "BMO_OP_SLOT_BOOL",
+ "BMO_OP_SLOT_FLT",
+ "BMO_OP_SLOT_INT",
+ "BMO_OP_SLOT_MAT",
+ "BMO_OP_SLOT_VEC",
+ "BMO_OP_SLOT_PTR",
+ "BMO_OP_SLOT_MAPPING",
+
+ "BMO_OP_SLOT_SUBTYPE_MAP_ELEM",
+ "BMO_OP_SLOT_SUBTYPE_MAP_BOOL",
+ "BMO_OP_SLOT_SUBTYPE_MAP_INT",
+ "BMO_OP_SLOT_SUBTYPE_MAP_FLT",
+ "BMO_OP_SLOT_SUBTYPE_MAP_EMPTY",
+ "BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL",
+
+ "BMO_OP_SLOT_SUBTYPE_PTR_SCENE",
+ "BMO_OP_SLOT_SUBTYPE_PTR_OBJECT",
+ "BMO_OP_SLOT_SUBTYPE_PTR_MESH",
+ "BMO_OP_SLOT_SUBTYPE_PTR_BMESH",
+
+ "BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE",
+
+ "BM_VERT",
+ "BM_EDGE",
+ "BM_FACE",
+
+ "BMO_OP_FLAG_UNTAN_MULTIRES",
+ )
+ vars_dict = {}
+ for i, v in enumerate(vars):
+ vars_dict[v] = (1 << i)
+ globals().update(vars_dict)
+ # reverse lookup
+ vars_dict_reverse = {v: k for k, v in vars_dict.items()}
+ # end namespace hack
+
+ blocks_py = []
+ for comment, b in blocks:
+ # magic, translate into python
+ b[0] = b[0].replace("static BMOpDefine ", "")
+
+ for i, l in enumerate(b):
+ l = l.strip()
+ l = l.replace("{", "(")
+ l = l.replace("}", ")")
+
+ if l.startswith("/*"):
+ l = l.replace("/*", "'''own <")
+ else:
+ l = l.replace("/*", "'''inline <")
+ l = l.replace("*/", ">''',")
+
+ # exec func. eg: bmo_rotate_edges_exec,
+ if l.startswith("bmo_") and l.endswith("_exec,"):
+ l = "None,"
+ b[i] = l
+
+ #for l in b:
+ # print(l)
+
+ text = "\n".join(b)
+ global_namespace = {
+ "__file__": "generated",
+ "__name__": "__main__",
+ }
+
+ global_namespace.update(vars_dict)
+
+ text_a, text_b = text.split("=", 1)
+ text = "result = " + text_b
+ exec(compile(text, "generated", 'exec'), global_namespace)
+ # print(global_namespace["result"])
+ blocks_py.append((comment, global_namespace["result"]))
+
+
+ # ---------------------
+ # Now convert into rst.
+ fout = open(OUT_RST, 'w', encoding="utf-8")
+ fw = fout.write
+ fw(HEADER)
+ for comment, b in blocks_py:
+ args_in = None
+ args_out = None
+ for member in b[1:]:
+ if type(member) == tuple:
+ if args_in is None:
+ args_in = member
+ elif args_out is None:
+ args_out = member
+ break
+
+ args_in_index = []
+ args_out_index = []
+
+ if args_in is not None:
+ args_in_index[:] = [i for (i, a) in enumerate(args_in) if type(a) == tuple]
+ if args_out is not None:
+ args_out_index[:] = [i for (i, a) in enumerate(args_out) if type(a) == tuple]
+
+ fw(".. function:: %s(bm, %s)\n\n" % (b[0], ", ".join([args_in[i][0] for i in args_in_index])))
+
+ # -- wash the comment
+ comment_washed = []
+ for i, l in enumerate(comment):
+ assert((l.strip() == "") or
+ (l in {"/*", " *"}) or
+ (l.startswith(("/* ", " * "))))
+
+ l = l[3:]
+ if i == 0 and not l.strip():
+ continue
+ if l.strip():
+ l = " " + l
+ comment_washed.append(l)
+
+ fw("\n".join(comment_washed))
+ fw("\n")
+ # -- done
+
+
+ # get the args
+ def get_args_wash(args, args_index, is_ret):
+ args_wash = []
+ for i in args_index:
+ arg = args[i]
+ if len(arg) == 3:
+ name, tp, tp_sub = arg
+ elif len(arg) == 2:
+ name, tp = arg
+ tp_sub = None
+ else:
+ print(arg)
+ assert(0)
+
+ tp_str = ""
+
+ comment_prev = ""
+ comment_next = ""
+ if i != 0:
+ comment_prev = args[i + 1]
+ if type(comment_prev) == str and comment_prev.startswith("our <"):
+ comment_prev = comment_next[5:-1] # strip inline <...>
+ else:
+ comment_prev = ""
+
+ if i + 1 < len(args):
+ comment_next = args[i + 1]
+ if type(comment_next) == str and comment_next.startswith("inline <"):
+ comment_next = comment_next[8:-1] # strip inline <...>
+ else:
+ comment_next = ""
+
+ comment = ""
+ if comment_prev:
+ comment += comment_prev.strip()
+ if comment_next:
+ comment += ("\n" if comment_prev else "") + comment_next.strip()
+
+ if tp == BMO_OP_SLOT_FLT:
+ tp_str = "float"
+ elif tp == BMO_OP_SLOT_INT:
+ tp_str = "int"
+ elif tp == BMO_OP_SLOT_BOOL:
+ tp_str = "bool"
+ elif tp == BMO_OP_SLOT_MAT:
+ tp_str = ":class:`mathutils.Matrix`"
+ elif tp == BMO_OP_SLOT_VEC:
+ tp_str = ":class:`mathutils.Vector`"
+ if not is_ret:
+ tp_str += " or any sequence of 3 floats"
+ elif tp == BMO_OP_SLOT_PTR:
+ tp_str = "dict"
+ assert(tp_sub is not None)
+ if tp_sub == BMO_OP_SLOT_SUBTYPE_PTR_BMESH:
+ tp_str = ":class:`bmesh.types.BMesh`"
+ elif tp_sub == BMO_OP_SLOT_SUBTYPE_PTR_SCENE:
+ tp_str = ":class:`bpy.types.Scene`"
+ elif tp_sub == BMO_OP_SLOT_SUBTYPE_PTR_OBJECT:
+ tp_str = ":class:`bpy.types.Object`"
+ elif tp_sub == BMO_OP_SLOT_SUBTYPE_PTR_MESH:
+ tp_str = ":class:`bpy.types.Mesh`"
+ else:
+ print("Cant find", vars_dict_reverse[tp_sub])
+ assert(0)
+
+ elif tp == BMO_OP_SLOT_ELEMENT_BUF:
+ assert(tp_sub is not None)
+
+ ls = []
+ if tp_sub & BM_VERT: ls.append(":class:`bmesh.types.BMVert`")
+ if tp_sub & BM_EDGE: ls.append(":class:`bmesh.types.BMEdge`")
+ if tp_sub & BM_FACE: ls.append(":class:`bmesh.types.BMFace`")
+ assert(ls) # must be at least one
+
+ if tp_sub & BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE:
+ tp_str = "/".join(ls)
+ else:
+ tp_str = ("list of (%s)" % ", ".join(ls))
+
+ del ls
+ elif tp == BMO_OP_SLOT_MAPPING:
+ if tp_sub & BMO_OP_SLOT_SUBTYPE_MAP_EMPTY:
+ tp_str = "set of vert/edge/face type"
+ else:
+ tp_str = "dict mapping vert/edge/face types to "
+ if tp_sub == BMO_OP_SLOT_SUBTYPE_MAP_BOOL:
+ tp_str += "bool"
+ elif tp_sub == BMO_OP_SLOT_SUBTYPE_MAP_INT:
+ tp_str += "int"
+ elif tp_sub == BMO_OP_SLOT_SUBTYPE_MAP_FLT:
+ tp_str += "float"
+ elif tp_sub == BMO_OP_SLOT_SUBTYPE_MAP_ELEM:
+ tp_str += ":class:`bmesh.types.BMVert`/:class:`bmesh.types.BMEdge`/:class:`bmesh.types.BMFace`"
+ elif tp_sub == BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL:
+ tp_str += "unknown internal data, not compatible with python"
+ else:
+ print("Cant find", vars_dict_reverse[tp_sub])
+ assert(0)
+ else:
+ print("Cant find", vars_dict_reverse[tp])
+ assert(0)
+
+ args_wash.append((name, tp_str, comment))
+ return args_wash
+ # end get_args_wash
+
+ # all ops get this arg
+ fw(" :arg bm: The bmesh to operate on.\n")
+ fw(" :type bm: :class:`bmesh.types.BMesh`\n")
+
+ args_in_wash = get_args_wash(args_in, args_in_index, False)
+ args_out_wash = get_args_wash(args_out, args_out_index, True)
+
+ for (name, tp, comment) in args_in_wash:
+ if comment == "":
+ comment = "Undocumented."
+
+ fw(" :arg %s: %s\n" % (name, comment))
+ fw(" :type %s: %s\n" % (name, tp))
+
+ if args_out_wash:
+ fw(" :return:\n\n")
+
+ for (name, tp, comment) in args_out_wash:
+ assert(name.endswith(".out"))
+ name = name[:-4]
+ fw(" - ``%s``: %s\n\n" % (name, comment))
+ fw(" **type** %s\n" % tp)
+
+ fw("\n")
+ fw(" :rtype: dict with string keys\n")
+
+ fw("\n\n")
+
+ fout.close()
+ del fout
+ print(OUT_RST)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/doc/python_api/sphinx_doc_gen.py b/doc/python_api/sphinx_doc_gen.py
index 782e0c6daaa..dd7019d43a3 100644
--- a/doc/python_api/sphinx_doc_gen.py
+++ b/doc/python_api/sphinx_doc_gen.py
@@ -35,7 +35,7 @@ API dump in RST files
./blender.bin --background --python doc/python_api/sphinx_doc_gen.py -- --output ../python_api
For quick builds:
- ./blender.bin --background --python doc/python_api/sphinx_doc_gen.py -- --partial
+ ./blender.bin --background --python doc/python_api/sphinx_doc_gen.py -- --partial bmesh.*
Sphinx: HTML generation
@@ -245,6 +245,7 @@ else:
"bgl",
"blf",
"bmesh",
+ "bmesh.ops",
"bmesh.types",
"bmesh.utils",
"bpy.app",
@@ -298,7 +299,7 @@ try:
__import__("aud")
except ImportError:
BPY_LOGGER.debug("Warning: Built without 'aud' module, docs incomplete...")
- EXCLUDE_MODULES = EXCLUDE_MODULES + ("aud", )
+ EXCLUDE_MODULES = list(EXCLUDE_MODULES) + ["aud"]
# examples
EXAMPLES_DIR = os.path.abspath(os.path.join(SCRIPT_DIR, "examples"))
@@ -1480,6 +1481,11 @@ def write_sphinx_conf_py(basepath):
file.close()
+def execfile(filepath):
+ global_namespace = {"__file__": filepath, "__name__": "__main__"}
+ exec(compile(open(filepath).read(), filepath, 'exec'), global_namespace)
+
+
def write_rst_contents(basepath):
'''
Write the rst file of the main page, needed for sphinx (index.html)
@@ -1541,13 +1547,17 @@ def write_rst_contents(basepath):
# misc
"Freestyle", "bgl", "blf", "gpu", "aud", "bpy_extras",
# bmesh
- "bmesh", "bmesh.types", "bmesh.utils",
+ "bmesh", "bmesh.types", "bmesh.utils", "bmesh.ops",
)
for mod in standalone_modules:
if mod not in EXCLUDE_MODULES:
fw(" %s\n\n" % mod)
+ # special case, this 'bmesh.ops.rst' is extracted from C source
+ if "bmesh.ops" not in EXCLUDE_MODULES:
+ execfile(os.path.join(SCRIPT_DIR, "rst_from_bmesh_opdefines.py"))
+
# game engine
if "bge" not in EXCLUDE_MODULES:
fw(title_string("Game Engine Modules", "=", double=True))
@@ -1710,6 +1720,8 @@ def copy_handwritten_rsts(basepath):
"bgl", # "Blender OpenGl wrapper"
"gpu", # "GPU Shader Module"
+ "bmesh.ops", # generated by rst_from_bmesh_opdefines.py
+
# includes...
"include__bmesh",
]
diff --git a/extern/CMakeLists.txt b/extern/CMakeLists.txt
index 151df493062..2640c528c94 100644
--- a/extern/CMakeLists.txt
+++ b/extern/CMakeLists.txt
@@ -32,9 +32,10 @@ if(WITH_BULLET)
add_subdirectory(bullet2)
endif()
-if(WITH_MOD_CLOTH_ELTOPO)
- add_subdirectory(eltopo)
-endif()
+# now only available in a branch
+#if(WITH_MOD_CLOTH_ELTOPO)
+# add_subdirectory(eltopo)
+#endif()
if(WITH_BINRELOC)
add_subdirectory(binreloc)
diff --git a/extern/SConscript b/extern/SConscript
index ce366deb38a..71998ee072c 100644
--- a/extern/SConscript
+++ b/extern/SConscript
@@ -8,8 +8,11 @@ SConscript(['colamd/SConscript'])
if env['WITH_BF_GAMEENGINE']:
SConscript(['recastnavigation/SConscript'])
+# now only available in a branch
+'''
if env['WITH_BF_ELTOPO']:
SConscript(['eltopo/SConscript'])
+'''
if env['WITH_BF_BULLET']:
SConscript(['bullet2/src/SConscript'])
diff --git a/intern/cycles/CMakeLists.txt b/intern/cycles/CMakeLists.txt
index 7495a98aed1..12829f15aed 100644
--- a/intern/cycles/CMakeLists.txt
+++ b/intern/cycles/CMakeLists.txt
@@ -21,8 +21,11 @@ elseif(CMAKE_COMPILER_IS_GNUCC)
endif()
# for OSL
-set(RTTI_DISABLE_FLAGS "-fno-rtti -DBOOST_NO_RTTI -DBOOST_NO_TYPEID")
-# set(RTTI_DISABLE_FLAGS "/GR- -DBOOST_NO_RTTI -DBOOST_NO_TYPEID")
+if(WIN32 AND MSVC)
+ set(RTTI_DISABLE_FLAGS "/GR- -DBOOST_NO_RTTI -DBOOST_NO_TYPEID")
+elseif(CMAKE_COMPILER_IS_GNUCC OR (CMAKE_C_COMPILER_ID MATCHES "Clang"))
+ set(RTTI_DISABLE_FLAGS "-fno-rtti -DBOOST_NO_RTTI -DBOOST_NO_TYPEID")
+endif()
# Definitions and Includes
diff --git a/intern/cycles/SConscript b/intern/cycles/SConscript
index 1a127e364fe..a0e2650ddc6 100644
--- a/intern/cycles/SConscript
+++ b/intern/cycles/SConscript
@@ -49,7 +49,7 @@ if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', '
# optimized kernel
if env['WITH_BF_RAYOPTIMIZATION']:
- optim_cxxflags = []
+ optim_cxxflags = Split(env['CXXFLAGS'])
if env['OURPLATFORM'] == 'win32-vc':
optim_cxxflags.append('/arch:SSE2 -D_CRT_SECURE_NO_WARNINGS /fp:fast /EHsc'.split())
diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp
index e8fa5c0ff3d..95263ebe463 100644
--- a/intern/cycles/blender/blender_object.cpp
+++ b/intern/cycles/blender/blender_object.cpp
@@ -360,8 +360,9 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, int motion)
bool emitter_hide = false;
if(b_dup_ob.is_duplicator()) {
- /* duplicators hidden by default */
- emitter_hide = true;
+ /* duplicators hidden by default, except dupliframes which duplicate self */
+ if(b_dup_ob.dupli_type() != BL::Object::dupli_type_FRAMES)
+ emitter_hide = true;
/* check if we should render or hide particle emitter */
BL::Object::particle_systems_iterator b_psys;
diff --git a/intern/cycles/kernel/closure/bsdf_phong_ramp.h b/intern/cycles/kernel/closure/bsdf_phong_ramp.h
index a2df77c2d2b..575a798aed4 100644
--- a/intern/cycles/kernel/closure/bsdf_phong_ramp.h
+++ b/intern/cycles/kernel/closure/bsdf_phong_ramp.h
@@ -131,7 +131,7 @@ __device int bsdf_phong_ramp_sample(const ShaderClosure *sc, const float3 colors
}
}
}
- return LABEL_REFLECT;
+ return LABEL_REFLECT|LABEL_GLOSSY;
}
diff --git a/intern/cycles/kernel/kernel_camera.h b/intern/cycles/kernel/kernel_camera.h
index abc63d99c74..97d37a8b3f4 100644
--- a/intern/cycles/kernel/kernel_camera.h
+++ b/intern/cycles/kernel/kernel_camera.h
@@ -65,7 +65,7 @@ __device void camera_sample_perspective(KernelGlobals *kg, float raster_x, float
#ifdef __CAMERA_MOTION__
if(kernel_data.cam.have_motion)
- transform_motion_interpolate(&cameratoworld, &kernel_data.cam.motion, ray->time);
+ transform_motion_interpolate(&cameratoworld, (const DecompMotionTransform*)&kernel_data.cam.motion, ray->time);
#endif
ray->P = transform_point(&cameratoworld, ray->P);
@@ -108,7 +108,7 @@ __device void camera_sample_orthographic(KernelGlobals *kg, float raster_x, floa
#ifdef __CAMERA_MOTION__
if(kernel_data.cam.have_motion)
- transform_motion_interpolate(&cameratoworld, &kernel_data.cam.motion, ray->time);
+ transform_motion_interpolate(&cameratoworld, (const DecompMotionTransform*)&kernel_data.cam.motion, ray->time);
#endif
ray->P = transform_point(&cameratoworld, ray->P);
@@ -182,7 +182,7 @@ __device void camera_sample_panorama(KernelGlobals *kg, float raster_x, float ra
#ifdef __CAMERA_MOTION__
if(kernel_data.cam.have_motion)
- transform_motion_interpolate(&cameratoworld, &kernel_data.cam.motion, ray->time);
+ transform_motion_interpolate(&cameratoworld, (const DecompMotionTransform*)&kernel_data.cam.motion, ray->time);
#endif
ray->P = transform_point(&cameratoworld, ray->P);
diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h
index 2791b3abbb6..97ae2d3db87 100644
--- a/intern/cycles/kernel/kernel_light.h
+++ b/intern/cycles/kernel/kernel_light.h
@@ -350,10 +350,9 @@ __device int light_distribution_sample(KernelGlobals *kg, float randt)
}
}
- first = max(0, first-1);
- kernel_assert(first >= 0 && first < kernel_data.integrator.num_distribution);
-
- return first;
+ /* clamping should not be needed but float rounding errors seem to
+ * make this fail on rare occasions */
+ return clamp(first-1, 0, kernel_data.integrator.num_distribution-1);
}
/* Generic Light */
diff --git a/intern/cycles/kernel/kernel_object.h b/intern/cycles/kernel/kernel_object.h
index 112bfbb86b5..2b38544e527 100644
--- a/intern/cycles/kernel/kernel_object.h
+++ b/intern/cycles/kernel/kernel_object.h
@@ -23,9 +23,8 @@ enum ObjectTransform {
OBJECT_INVERSE_TRANSFORM = 3,
OBJECT_PROPERTIES = 6,
OBJECT_TRANSFORM_MOTION_PRE = 8,
- OBJECT_TRANSFORM_MOTION_MID = 12,
- OBJECT_TRANSFORM_MOTION_POST = 16,
- OBJECT_DUPLI = 20
+ OBJECT_TRANSFORM_MOTION_POST = 12,
+ OBJECT_DUPLI = 16
};
__device_inline Transform object_fetch_transform(KernelGlobals *kg, int object, enum ObjectTransform type)
@@ -44,24 +43,19 @@ __device_inline Transform object_fetch_transform(KernelGlobals *kg, int object,
#ifdef __OBJECT_MOTION__
__device_inline Transform object_fetch_transform_motion(KernelGlobals *kg, int object, float time)
{
- MotionTransform motion;
+ DecompMotionTransform motion;
int offset = object*OBJECT_SIZE + (int)OBJECT_TRANSFORM_MOTION_PRE;
- motion.pre.x = kernel_tex_fetch(__objects, offset + 0);
- motion.pre.y = kernel_tex_fetch(__objects, offset + 1);
- motion.pre.z = kernel_tex_fetch(__objects, offset + 2);
- motion.pre.w = kernel_tex_fetch(__objects, offset + 3);
+ motion.mid.x = kernel_tex_fetch(__objects, offset + 0);
+ motion.mid.y = kernel_tex_fetch(__objects, offset + 1);
+ motion.mid.z = kernel_tex_fetch(__objects, offset + 2);
+ motion.mid.w = kernel_tex_fetch(__objects, offset + 3);
- motion.mid.x = kernel_tex_fetch(__objects, offset + 4);
- motion.mid.y = kernel_tex_fetch(__objects, offset + 5);
- motion.mid.z = kernel_tex_fetch(__objects, offset + 6);
- motion.mid.w = kernel_tex_fetch(__objects, offset + 7);
-
- motion.post.x = kernel_tex_fetch(__objects, offset + 8);
- motion.post.y = kernel_tex_fetch(__objects, offset + 9);
- motion.post.z = kernel_tex_fetch(__objects, offset + 10);
- motion.post.w = kernel_tex_fetch(__objects, offset + 11);
+ motion.pre_x = kernel_tex_fetch(__objects, offset + 4);
+ motion.pre_y = kernel_tex_fetch(__objects, offset + 5);
+ motion.post_x = kernel_tex_fetch(__objects, offset + 6);
+ motion.post_y = kernel_tex_fetch(__objects, offset + 7);
Transform tfm;
transform_motion_interpolate(&tfm, &motion, time);
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index 977fb8c4fd4..f519fd989fa 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -29,7 +29,7 @@
CCL_NAMESPACE_BEGIN
/* constants */
-#define OBJECT_SIZE 22
+#define OBJECT_SIZE 18
#define LIGHT_SIZE 4
#define FILTER_TABLE_SIZE 256
#define RAMP_TABLE_SIZE 256
@@ -102,6 +102,7 @@ CCL_NAMESPACE_BEGIN
#define __IMAGE_TEXTURES__
#define __EXTRA_NODES__
#define __HOLDOUT__
+#define __NORMAL_MAP__
#endif
#ifdef __KERNEL_ADV_SHADING__
@@ -112,13 +113,9 @@ CCL_NAMESPACE_BEGIN
#define __AO__
#define __CAMERA_MOTION__
#define __ANISOTROPIC__
-
-#ifndef __KERNEL_CUDA__
#define __OBJECT_MOTION__
#endif
-#endif
-
//#define __SOBOL_FULL_SCREEN__
/* Shader Evaluation */
diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp
index e79c509b144..e593387093c 100644
--- a/intern/cycles/kernel/osl/osl_services.cpp
+++ b/intern/cycles/kernel/osl/osl_services.cpp
@@ -80,7 +80,12 @@ bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, OSL::TransformationPtr
if (object != ~0) {
#ifdef __OBJECT_MOTION__
- Transform tfm = object_fetch_transform_motion_test(kg, object, time, NULL);
+ Transform tfm;
+
+ if(time == sd->time)
+ tfm = sd->ob_tfm;
+ else
+ tfm = object_fetch_transform_motion_test(kg, object, time, NULL);
#else
Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
#endif
@@ -106,7 +111,11 @@ bool OSLRenderServices::get_inverse_matrix(OSL::Matrix44 &result, OSL::Transform
if (object != ~0) {
#ifdef __OBJECT_MOTION__
Transform itfm;
- object_fetch_transform_motion_test(kg, object, time, &itfm);
+
+ if(time == sd->time)
+ itfm = sd->ob_itfm;
+ else
+ object_fetch_transform_motion_test(kg, object, time, &itfm);
#else
Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
#endif
diff --git a/intern/cycles/kernel/osl/osl_shader.cpp b/intern/cycles/kernel/osl/osl_shader.cpp
index abf7c041cb3..2d025f12055 100644
--- a/intern/cycles/kernel/osl/osl_shader.cpp
+++ b/intern/cycles/kernel/osl/osl_shader.cpp
@@ -106,6 +106,7 @@ static void shaderdata_to_shaderglobals(KernelGlobals *kg, ShaderData *sd,
globals->dPdu = TO_VEC3(sd->dPdu);
globals->dPdv = TO_VEC3(sd->dPdv);
globals->surfacearea = (sd->object == ~0) ? 1.0f : object_surface_area(kg, sd->object);
+ globals->time = sd->time;
/* booleans */
globals->raytype = path_flag; /* todo: add our own ray types */
diff --git a/intern/cycles/kernel/shaders/node_convert_from_color.osl b/intern/cycles/kernel/shaders/node_convert_from_color.osl
index 2884c772414..e4982975c20 100644
--- a/intern/cycles/kernel/shaders/node_convert_from_color.osl
+++ b/intern/cycles/kernel/shaders/node_convert_from_color.osl
@@ -20,6 +20,7 @@
shader node_convert_from_color(
color Color = color(0.0, 0.0, 0.0),
+ output string String = "",
output float Val = 0.0,
output int ValInt = 0,
output vector Vector = vector(0.0, 0.0, 0.0),
diff --git a/intern/cycles/kernel/shaders/node_convert_from_float.osl b/intern/cycles/kernel/shaders/node_convert_from_float.osl
index 4466fbae3a6..a20b491c91d 100644
--- a/intern/cycles/kernel/shaders/node_convert_from_float.osl
+++ b/intern/cycles/kernel/shaders/node_convert_from_float.osl
@@ -20,6 +20,7 @@
shader node_convert_from_float(
float Val = 0.0,
+ output string String = "",
output int ValInt = 0,
output color Color = color(0.0, 0.0, 0.0),
output vector Vector = vector(0.0, 0.0, 0.0),
diff --git a/intern/cycles/kernel/shaders/node_convert_from_int.osl b/intern/cycles/kernel/shaders/node_convert_from_int.osl
index 060d4184fa6..911b4928db8 100644
--- a/intern/cycles/kernel/shaders/node_convert_from_int.osl
+++ b/intern/cycles/kernel/shaders/node_convert_from_int.osl
@@ -20,6 +20,7 @@
shader node_convert_from_int(
int ValInt = 0,
+ output string String = "",
output float Val = 0.0,
output color Color = color(0.0, 0.0, 0.0),
output vector Vector = vector(0.0, 0.0, 0.0),
diff --git a/intern/cycles/kernel/shaders/node_convert_from_normal.osl b/intern/cycles/kernel/shaders/node_convert_from_normal.osl
index 32ef430d93b..1add7400a22 100644
--- a/intern/cycles/kernel/shaders/node_convert_from_normal.osl
+++ b/intern/cycles/kernel/shaders/node_convert_from_normal.osl
@@ -20,6 +20,7 @@
shader node_convert_from_normal(
normal Normal = normal(0.0, 0.0, 0.0),
+ output string String = "",
output float Val = 0.0,
output int ValInt = 0,
output vector Vector = vector(0.0, 0.0, 0.0),
diff --git a/intern/cycles/kernel/shaders/node_convert_from_point.osl b/intern/cycles/kernel/shaders/node_convert_from_point.osl
index a9435c8abf4..8a315828c55 100644
--- a/intern/cycles/kernel/shaders/node_convert_from_point.osl
+++ b/intern/cycles/kernel/shaders/node_convert_from_point.osl
@@ -20,6 +20,7 @@
shader node_convert_from_point(
point Point = point(0.0, 0.0, 0.0),
+ output string String = "",
output float Val = 0.0,
output int ValInt = 0,
output vector Vector = vector(0.0, 0.0, 0.0),
diff --git a/intern/cycles/kernel/shaders/node_convert_from_string.osl b/intern/cycles/kernel/shaders/node_convert_from_string.osl
new file mode 100644
index 00000000000..f40535ac7a3
--- /dev/null
+++ b/intern/cycles/kernel/shaders/node_convert_from_string.osl
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2011, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "stdosl.h"
+
+shader node_convert_from_string(
+ string String = "",
+ output color Color = color(0.0, 0.0, 0.0),
+ output float Val = 0.0,
+ output int ValInt = 0,
+ output vector Vector = vector(0.0, 0.0, 0.0),
+ output point Point = point(0.0, 0.0, 0.0),
+ output normal Normal = normal(0.0, 0.0, 0.0))
+{
+}
+
diff --git a/intern/cycles/kernel/shaders/node_convert_from_vector.osl b/intern/cycles/kernel/shaders/node_convert_from_vector.osl
index 4516f92c753..ae9f97414d5 100644
--- a/intern/cycles/kernel/shaders/node_convert_from_vector.osl
+++ b/intern/cycles/kernel/shaders/node_convert_from_vector.osl
@@ -20,6 +20,7 @@
shader node_convert_from_vector(
vector Vector = vector(0.0, 0.0, 0.0),
+ output string String = "",
output float Val = 0.0,
output int ValInt = 0,
output color Color = color(0.0, 0.0, 0.0),
diff --git a/intern/cycles/kernel/svm/svm.h b/intern/cycles/kernel/svm/svm.h
index 886fce63fd4..9c79886fdca 100644
--- a/intern/cycles/kernel/svm/svm.h
+++ b/intern/cycles/kernel/svm/svm.h
@@ -401,9 +401,13 @@ __device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ShaderT
case NODE_LIGHT_FALLOFF:
svm_node_light_falloff(sd, stack, node);
break;
+#endif
+#ifdef __ANISOTROPIC__
case NODE_TANGENT:
svm_node_tangent(kg, sd, stack, node);
break;
+#endif
+#ifdef __NORMAL_MAP__
case NODE_NORMAL_MAP:
svm_node_normal_map(kg, sd, stack, node);
break;
diff --git a/intern/cycles/kernel/svm/svm_brick.h b/intern/cycles/kernel/svm/svm_brick.h
index 7e38ac84bf1..49466c07a97 100644
--- a/intern/cycles/kernel/svm/svm_brick.h
+++ b/intern/cycles/kernel/svm/svm_brick.h
@@ -28,9 +28,9 @@ __device_noinline float brick_noise(int n) /* fast integer noise */
return 0.5f * ((float)nn / 1073741824.0f);
}
-__device_noinline float svm_brick(float3 p, float scale, float mortar_size, float bias,
+__device_noinline float2 svm_brick(float3 p, float scale, float mortar_size, float bias,
float brick_width, float row_height, float offset_amount, int offset_frequency,
- float squash_amount, int squash_frequency, float *tint)
+ float squash_amount, int squash_frequency)
{
p *= scale;
@@ -50,11 +50,12 @@ __device_noinline float svm_brick(float3 p, float scale, float mortar_size, floa
x = (p.x+offset) - brick_width*bricknum;
y = p.y - row_height*rownum;
- *tint = clamp((brick_noise((rownum << 16) + (bricknum & 0xFFFF)) + bias), 0.0f, 1.0f);
+ return make_float2(
+ clamp((brick_noise((rownum << 16) + (bricknum & 0xFFFF)) + bias), 0.0f, 1.0f),
- return (x < mortar_size || y < mortar_size ||
+ (x < mortar_size || y < mortar_size ||
x > (brick_width - mortar_size) ||
- y > (row_height - mortar_size)) ? 1.0f : 0.0f;
+ y > (row_height - mortar_size)) ? 1.0f : 0.0f);
}
__device void svm_node_tex_brick(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset)
@@ -70,8 +71,6 @@ __device void svm_node_tex_brick(KernelGlobals *kg, ShaderData *sd, float *stack
/* RNA properties */
uint offset_frequency, squash_frequency;
- float tint = 0.0f;
-
decode_node_uchar4(node.y, &co_offset, &color1_offset, &color2_offset, &mortar_offset);
decode_node_uchar4(node.z, &scale_offset, &mortar_size_offset, &bias_offset, &brick_width_offset);
decode_node_uchar4(node.w, &row_height_offset, &color_offset, &fac_offset, NULL);
@@ -92,9 +91,11 @@ __device void svm_node_tex_brick(KernelGlobals *kg, ShaderData *sd, float *stack
float offset_amount = __int_as_float(node3.z);
float squash_amount = __int_as_float(node3.w);
- float f = svm_brick(co, scale, mortar_size, bias, brick_width, row_height,
- offset_amount, offset_frequency, squash_amount, squash_frequency,
- &tint);
+ float2 f2 = svm_brick(co, scale, mortar_size, bias, brick_width, row_height,
+ offset_amount, offset_frequency, squash_amount, squash_frequency);
+
+ float tint = f2.x;
+ float f = f2.y;
if(f != 1.0f) {
float facm = 1.0f - tint;
diff --git a/intern/cycles/kernel/svm/svm_closure.h b/intern/cycles/kernel/svm/svm_closure.h
index a4f8546f62b..564c0957c68 100644
--- a/intern/cycles/kernel/svm/svm_closure.h
+++ b/intern/cycles/kernel/svm/svm_closure.h
@@ -50,25 +50,41 @@ __device void svm_node_glass_setup(ShaderData *sd, ShaderClosure *sc, int type,
}
}
-__device_inline ShaderClosure *svm_node_closure_get(ShaderData *sd)
+__device_inline ShaderClosure *svm_node_closure_get_non_bsdf(ShaderData *sd, ClosureType type, float mix_weight)
{
#ifdef __MULTI_CLOSURE__
ShaderClosure *sc = &sd->closure[sd->num_closure];
- if(sd->num_closure < MAX_CLOSURE)
+ if(sd->num_closure < MAX_CLOSURE) {
+ sc->weight *= mix_weight;
+ sc->type = type;
sd->num_closure++;
+ return sc;
+ }
- return sc;
+ return NULL;
#else
return &sd->closure;
#endif
}
-__device_inline void svm_node_closure_set_mix_weight(ShaderClosure *sc, float mix_weight)
+__device_inline ShaderClosure *svm_node_closure_get_bsdf(ShaderData *sd, float mix_weight)
{
#ifdef __MULTI_CLOSURE__
- sc->weight *= mix_weight;
- sc->sample_weight = fabsf(average(sc->weight));
+ ShaderClosure *sc = &sd->closure[sd->num_closure];
+ float3 weight = sc->weight * mix_weight;
+ float sample_weight = fabsf(average(sc->weight));
+
+ if(sample_weight > 1e-5f && sd->num_closure < MAX_CLOSURE) {
+ sc->weight = weight;
+ sc->sample_weight = sample_weight;
+ sd->num_closure++;
+ return sc;
+ }
+
+ return NULL;
+#else
+ return &sd->closure;
#endif
}
@@ -101,33 +117,39 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st
switch(type) {
case CLOSURE_BSDF_DIFFUSE_ID: {
- ShaderClosure *sc = svm_node_closure_get(sd);
- sc->N = N;
- svm_node_closure_set_mix_weight(sc, mix_weight);
+ ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight);
- float roughness = param1;
+ if(sc) {
+ sc->N = N;
- if(roughness == 0.0f) {
- sd->flag |= bsdf_diffuse_setup(sc);
- }
- else {
- sc->data0 = roughness;
- sd->flag |= bsdf_oren_nayar_setup(sc);
+ float roughness = param1;
+
+ if(roughness == 0.0f) {
+ sd->flag |= bsdf_diffuse_setup(sc);
+ }
+ else {
+ sc->data0 = roughness;
+ sd->flag |= bsdf_oren_nayar_setup(sc);
+ }
}
break;
}
case CLOSURE_BSDF_TRANSLUCENT_ID: {
- ShaderClosure *sc = svm_node_closure_get(sd);
- sc->N = N;
- svm_node_closure_set_mix_weight(sc, mix_weight);
- sd->flag |= bsdf_translucent_setup(sc);
+ ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight);
+
+ if(sc) {
+ sc->N = N;
+ sd->flag |= bsdf_translucent_setup(sc);
+ }
break;
}
case CLOSURE_BSDF_TRANSPARENT_ID: {
- ShaderClosure *sc = svm_node_closure_get(sd);
- sc->N = N;
- svm_node_closure_set_mix_weight(sc, mix_weight);
- sd->flag |= bsdf_transparent_setup(sc);
+ ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight);
+
+ if(sc) {
+ sc->N = N;
+ sd->flag |= bsdf_transparent_setup(sc);
+ }
break;
}
case CLOSURE_BSDF_REFLECTION_ID:
@@ -137,18 +159,20 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st
if(kernel_data.integrator.no_caustics && (path_flag & PATH_RAY_DIFFUSE))
break;
#endif
- ShaderClosure *sc = svm_node_closure_get(sd);
- sc->N = N;
- sc->data0 = param1;
- svm_node_closure_set_mix_weight(sc, mix_weight);
-
- /* setup bsdf */
- if(type == CLOSURE_BSDF_REFLECTION_ID)
- sd->flag |= bsdf_reflection_setup(sc);
- else if(type == CLOSURE_BSDF_MICROFACET_BECKMANN_ID)
- sd->flag |= bsdf_microfacet_beckmann_setup(sc);
- else
- sd->flag |= bsdf_microfacet_ggx_setup(sc);
+ ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight);
+
+ if(sc) {
+ sc->N = N;
+ sc->data0 = param1;
+
+ /* setup bsdf */
+ if(type == CLOSURE_BSDF_REFLECTION_ID)
+ sd->flag |= bsdf_reflection_setup(sc);
+ else if(type == CLOSURE_BSDF_MICROFACET_BECKMANN_ID)
+ sd->flag |= bsdf_microfacet_beckmann_setup(sc);
+ else
+ sd->flag |= bsdf_microfacet_ggx_setup(sc);
+ }
break;
}
@@ -159,21 +183,23 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st
if(kernel_data.integrator.no_caustics && (path_flag & PATH_RAY_DIFFUSE))
break;
#endif
- ShaderClosure *sc = svm_node_closure_get(sd);
- sc->N = N;
- sc->data0 = param1;
- svm_node_closure_set_mix_weight(sc, mix_weight);
-
- float eta = fmaxf(param2, 1.0f + 1e-5f);
- sc->data1 = (sd->flag & SD_BACKFACING)? 1.0f/eta: eta;
-
- /* setup bsdf */
- if(type == CLOSURE_BSDF_REFRACTION_ID)
- sd->flag |= bsdf_refraction_setup(sc);
- else if(type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID)
- sd->flag |= bsdf_microfacet_beckmann_refraction_setup(sc);
- else
- sd->flag |= bsdf_microfacet_ggx_refraction_setup(sc);
+ ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight);
+
+ if(sc) {
+ sc->N = N;
+ sc->data0 = param1;
+
+ float eta = fmaxf(param2, 1.0f + 1e-5f);
+ sc->data1 = (sd->flag & SD_BACKFACING)? 1.0f/eta: eta;
+
+ /* setup bsdf */
+ if(type == CLOSURE_BSDF_REFRACTION_ID)
+ sd->flag |= bsdf_refraction_setup(sc);
+ else if(type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID)
+ sd->flag |= bsdf_microfacet_beckmann_refraction_setup(sc);
+ else
+ sd->flag |= bsdf_microfacet_ggx_refraction_setup(sc);
+ }
break;
}
@@ -195,32 +221,36 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st
#ifdef __MULTI_CLOSURE__
/* reflection */
- ShaderClosure *sc = svm_node_closure_get(sd);
- sc->N = N;
-
+ ShaderClosure *sc = &sd->closure[sd->num_closure];
float3 weight = sc->weight;
float sample_weight = sc->sample_weight;
- svm_node_closure_set_mix_weight(sc, mix_weight*fresnel);
- svm_node_glass_setup(sd, sc, type, eta, roughness, false);
+ sc = svm_node_closure_get_bsdf(sd, mix_weight*fresnel);
- /* refraction */
- sc = svm_node_closure_get(sd);
- sc->N = N;
+ if(sc) {
+ sc->N = N;
+ svm_node_glass_setup(sd, sc, type, eta, roughness, false);
+ }
+ /* refraction */
+ sc = &sd->closure[sd->num_closure];
sc->weight = weight;
sc->sample_weight = sample_weight;
- svm_node_closure_set_mix_weight(sc, mix_weight*(1.0f - fresnel));
- svm_node_glass_setup(sd, sc, type, eta, roughness, true);
-#else
- ShaderClosure *sc = svm_node_closure_get(sd);
- sc->N = N;
+ sc = svm_node_closure_get_bsdf(sd, mix_weight*(1.0f - fresnel));
- bool refract = (randb > fresnel);
+ if(sc) {
+ sc->N = N;
+ svm_node_glass_setup(sd, sc, type, eta, roughness, true);
+ }
+#else
+ ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight);
- svm_node_closure_set_mix_weight(sc, mix_weight);
- svm_node_glass_setup(sd, sc, type, eta, roughness, refract);
+ if(sc) {
+ sc->N = N;
+ bool refract = (randb > fresnel);
+ svm_node_glass_setup(sd, sc, type, eta, roughness, refract);
+ }
#endif
break;
@@ -230,46 +260,50 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st
if(kernel_data.integrator.no_caustics && (path_flag & PATH_RAY_DIFFUSE))
break;
#endif
- ShaderClosure *sc = svm_node_closure_get(sd);
- sc->N = N;
- svm_node_closure_set_mix_weight(sc, mix_weight);
+ ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight);
+
+ if(sc) {
+ sc->N = N;
#ifdef __ANISOTROPIC__
- sc->T = stack_load_float3(stack, data_node.z);
+ sc->T = stack_load_float3(stack, data_node.z);
- /* rotate tangent */
- float rotation = stack_load_float(stack, data_node.w);
+ /* rotate tangent */
+ float rotation = stack_load_float(stack, data_node.w);
- if(rotation != 0.0f)
- sc->T = rotate_around_axis(sc->T, sc->N, rotation * 2.0f * M_PI_F);
+ if(rotation != 0.0f)
+ sc->T = rotate_around_axis(sc->T, sc->N, rotation * 2.0f * M_PI_F);
- /* compute roughness */
- float roughness = param1;
- float anisotropy = clamp(param2, -0.99f, 0.99f);
+ /* compute roughness */
+ float roughness = param1;
+ float anisotropy = clamp(param2, -0.99f, 0.99f);
- if(anisotropy < 0.0f) {
- sc->data0 = roughness/(1.0f + anisotropy);
- sc->data1 = roughness*(1.0f + anisotropy);
- }
- else {
- sc->data0 = roughness*(1.0f - anisotropy);
- sc->data1 = roughness/(1.0f - anisotropy);
- }
+ if(anisotropy < 0.0f) {
+ sc->data0 = roughness/(1.0f + anisotropy);
+ sc->data1 = roughness*(1.0f + anisotropy);
+ }
+ else {
+ sc->data0 = roughness*(1.0f - anisotropy);
+ sc->data1 = roughness/(1.0f - anisotropy);
+ }
- sd->flag |= bsdf_ward_setup(sc);
+ sd->flag |= bsdf_ward_setup(sc);
#else
- sd->flag |= bsdf_diffuse_setup(sc);
+ sd->flag |= bsdf_diffuse_setup(sc);
#endif
+ }
break;
}
case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: {
- ShaderClosure *sc = svm_node_closure_get(sd);
- sc->N = N;
- svm_node_closure_set_mix_weight(sc, mix_weight);
+ ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight);
+
+ if(sc) {
+ sc->N = N;
- /* sigma */
- sc->data0 = clamp(param1, 0.0f, 1.0f);
- sd->flag |= bsdf_ashikhmin_velvet_setup(sc);
+ /* sigma */
+ sc->data0 = clamp(param1, 0.0f, 1.0f);
+ sd->flag |= bsdf_ashikhmin_velvet_setup(sc);
+ }
break;
}
default:
@@ -298,19 +332,21 @@ __device void svm_node_closure_volume(KernelGlobals *kg, ShaderData *sd, float *
switch(type) {
case CLOSURE_VOLUME_TRANSPARENT_ID: {
- ShaderClosure *sc = svm_node_closure_get(sd);
- svm_node_closure_set_mix_weight(sc, mix_weight);
+ ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight);
- float density = param1;
- sd->flag |= volume_transparent_setup(sc, density);
+ if(sc) {
+ float density = param1;
+ sd->flag |= volume_transparent_setup(sc, density);
+ }
break;
}
case CLOSURE_VOLUME_ISOTROPIC_ID: {
- ShaderClosure *sc = svm_node_closure_get(sd);
- svm_node_closure_set_mix_weight(sc, mix_weight);
+ ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight);
- float density = param1;
- sd->flag |= volume_isotropic_setup(sc, density);
+ if(sc) {
+ float density = param1;
+ sd->flag |= volume_isotropic_setup(sc, density);
+ }
break;
}
default:
@@ -329,15 +365,10 @@ __device void svm_node_closure_emission(ShaderData *sd, float *stack, uint4 node
if(mix_weight == 0.0f)
return;
- ShaderClosure *sc = svm_node_closure_get(sd);
- sc->weight *= mix_weight;
- sc->type = CLOSURE_EMISSION_ID;
+ svm_node_closure_get_non_bsdf(sd, CLOSURE_EMISSION_ID, mix_weight);
}
- else {
- ShaderClosure *sc = svm_node_closure_get(sd);
- sc->type = CLOSURE_EMISSION_ID;
- }
-
+ else
+ svm_node_closure_get_non_bsdf(sd, CLOSURE_EMISSION_ID, 1.0f);
#else
ShaderClosure *sc = &sd->closure;
sc->type = CLOSURE_EMISSION_ID;
@@ -357,15 +388,10 @@ __device void svm_node_closure_background(ShaderData *sd, float *stack, uint4 no
if(mix_weight == 0.0f)
return;
- ShaderClosure *sc = svm_node_closure_get(sd);
- sc->weight *= mix_weight;
- sc->type = CLOSURE_BACKGROUND_ID;
- }
- else {
- ShaderClosure *sc = svm_node_closure_get(sd);
- sc->type = CLOSURE_BACKGROUND_ID;
+ svm_node_closure_get_non_bsdf(sd, CLOSURE_BACKGROUND_ID, mix_weight);
}
-
+ else
+ svm_node_closure_get_non_bsdf(sd, CLOSURE_BACKGROUND_ID, 1.0f);
#else
ShaderClosure *sc = &sd->closure;
sc->type = CLOSURE_BACKGROUND_ID;
@@ -383,15 +409,10 @@ __device void svm_node_closure_holdout(ShaderData *sd, float *stack, uint4 node)
if(mix_weight == 0.0f)
return;
- ShaderClosure *sc = svm_node_closure_get(sd);
- sc->weight = make_float3(mix_weight, mix_weight, mix_weight);
- sc->type = CLOSURE_HOLDOUT_ID;
- }
- else {
- ShaderClosure *sc = svm_node_closure_get(sd);
- sc->weight = make_float3(1.0f, 1.0f, 1.0f);
- sc->type = CLOSURE_HOLDOUT_ID;
+ svm_node_closure_get_non_bsdf(sd, CLOSURE_HOLDOUT_ID, mix_weight);
}
+ else
+ svm_node_closure_get_non_bsdf(sd, CLOSURE_HOLDOUT_ID, 1.0f);
#else
ShaderClosure *sc = &sd->closure;
sc->type = CLOSURE_HOLDOUT_ID;
@@ -411,15 +432,10 @@ __device void svm_node_closure_ambient_occlusion(ShaderData *sd, float *stack, u
if(mix_weight == 0.0f)
return;
- ShaderClosure *sc = svm_node_closure_get(sd);
- sc->weight *= mix_weight;
- sc->type = CLOSURE_AMBIENT_OCCLUSION_ID;
- }
- else {
- ShaderClosure *sc = svm_node_closure_get(sd);
- sc->type = CLOSURE_AMBIENT_OCCLUSION_ID;
+ svm_node_closure_get_non_bsdf(sd, CLOSURE_AMBIENT_OCCLUSION_ID, mix_weight);
}
-
+ else
+ svm_node_closure_get_non_bsdf(sd, CLOSURE_AMBIENT_OCCLUSION_ID, 1.0f);
#else
ShaderClosure *sc = &sd->closure;
sc->type = CLOSURE_AMBIENT_OCCLUSION_ID;
@@ -433,7 +449,8 @@ __device void svm_node_closure_ambient_occlusion(ShaderData *sd, float *stack, u
__device_inline void svm_node_closure_store_weight(ShaderData *sd, float3 weight)
{
#ifdef __MULTI_CLOSURE__
- sd->closure[sd->num_closure].weight = weight;
+ if(sd->num_closure < MAX_CLOSURE)
+ sd->closure[sd->num_closure].weight = weight;
#else
sd->closure.weight = weight;
#endif
diff --git a/intern/cycles/kernel/svm/svm_texture.h b/intern/cycles/kernel/svm/svm_texture.h
index 6c22d98e0df..a4f6691435c 100644
--- a/intern/cycles/kernel/svm/svm_texture.h
+++ b/intern/cycles/kernel/svm/svm_texture.h
@@ -42,8 +42,12 @@ __device float voronoi_distance(NodeDistanceMetric distance_metric, float3 d, fl
/* Voronoi / Worley like */
-__device_noinline void voronoi(float3 p, NodeDistanceMetric distance_metric, float e, float da[4], float3 pa[4])
+__device_noinline float4 voronoi_Fn(float3 p, float e, int n1, int n2)
{
+ float da[4];
+ float3 pa[4];
+ NodeDistanceMetric distance_metric = NODE_VORONOI_DISTANCE_SQUARED;
+
/* returns distances in da and point coords in pa */
int xx, yy, zz, xi, yi, zi;
@@ -105,33 +109,20 @@ __device_noinline void voronoi(float3 p, NodeDistanceMetric distance_metric, flo
}
}
}
-}
-
-__device float voronoi_Fn(float3 p, int n)
-{
- float da[4];
- float3 pa[4];
-
- voronoi(p, NODE_VORONOI_DISTANCE_SQUARED, 0, da, pa);
-
- return da[n];
-}
-__device float voronoi_FnFn(float3 p, int n1, int n2)
-{
- float da[4];
- float3 pa[4];
+ float4 result = make_float4(pa[n1].x, pa[n1].y, pa[n1].z, da[n1]);
- voronoi(p, NODE_VORONOI_DISTANCE_SQUARED, 0, da, pa);
+ if(n2 != -1)
+ result = make_float4(pa[n2].x, pa[n2].y, pa[n2].z, da[n2]) - result;
- return da[n2] - da[n1];
+ return result;
}
-__device float voronoi_F1(float3 p) { return voronoi_Fn(p, 0); }
-__device float voronoi_F2(float3 p) { return voronoi_Fn(p, 1); }
-__device float voronoi_F3(float3 p) { return voronoi_Fn(p, 2); }
-__device float voronoi_F4(float3 p) { return voronoi_Fn(p, 3); }
-__device float voronoi_F1F2(float3 p) { return voronoi_FnFn(p, 0, 1); }
+__device float voronoi_F1(float3 p) { return voronoi_Fn(p, 0.0f, 0, -1).w; }
+__device float voronoi_F2(float3 p) { return voronoi_Fn(p, 0.0f, 1, -1).w; }
+__device float voronoi_F3(float3 p) { return voronoi_Fn(p, 0.0f, 2, -1).w; }
+__device float voronoi_F4(float3 p) { return voronoi_Fn(p, 0.0f, 3, -1).w; }
+__device float voronoi_F1F2(float3 p) { return voronoi_Fn(p, 0.0f, 0, 1).w; }
__device float voronoi_Cr(float3 p)
{
diff --git a/intern/cycles/kernel/svm/svm_voronoi.h b/intern/cycles/kernel/svm/svm_voronoi.h
index 7e7bd970320..55110d06f22 100644
--- a/intern/cycles/kernel/svm/svm_voronoi.h
+++ b/intern/cycles/kernel/svm/svm_voronoi.h
@@ -23,21 +23,18 @@ CCL_NAMESPACE_BEGIN
__device_noinline float4 svm_voronoi(NodeVoronoiColoring coloring, float scale, float3 p)
{
/* compute distance and point coordinate of 4 nearest neighbours */
- float da[4];
- float3 pa[4];
-
- voronoi(p*scale, NODE_VORONOI_DISTANCE_SQUARED, 1.0f, da, pa);
+ float4 dpa0 = voronoi_Fn(p*scale, 1.0f, 0, -1);
/* output */
float fac;
float3 color;
if(coloring == NODE_VORONOI_INTENSITY) {
- fac = fabsf(da[0]);
+ fac = fabsf(dpa0.w);
color = make_float3(fac, fac, fac);
}
else {
- color = cellnoise_color(pa[0]);
+ color = cellnoise_color(float4_to_float3(dpa0));
fac = average(color);
}
diff --git a/intern/cycles/render/camera.cpp b/intern/cycles/render/camera.cpp
index 32c273c1248..a78ede979b2 100644
--- a/intern/cycles/render/camera.cpp
+++ b/intern/cycles/render/camera.cpp
@@ -202,7 +202,7 @@ void Camera::device_update(Device *device, DeviceScene *dscene, Scene *scene)
#ifdef __CAMERA_MOTION__
else if(need_motion == Scene::MOTION_BLUR) {
if(use_motion) {
- transform_motion_decompose(&kcam->motion, &motion, &matrix);
+ transform_motion_decompose((DecompMotionTransform*)&kcam->motion, &motion, &matrix);
kcam->have_motion = 1;
}
}
diff --git a/intern/cycles/render/graph.cpp b/intern/cycles/render/graph.cpp
index f71675dbda3..14b219383d0 100644
--- a/intern/cycles/render/graph.cpp
+++ b/intern/cycles/render/graph.cpp
@@ -37,7 +37,7 @@ ShaderInput::ShaderInput(ShaderNode *parent_, const char *name_, ShaderSocketTyp
value = make_float3(0, 0, 0);
stack_offset = SVM_STACK_INVALID;
default_value = NONE;
- osl_only = false;
+ usage = USE_ALL;
}
ShaderOutput::ShaderOutput(ShaderNode *parent_, const char *name_, ShaderSocketType type_)
@@ -85,27 +85,29 @@ ShaderOutput *ShaderNode::output(const char *name)
return NULL;
}
-ShaderInput *ShaderNode::add_input(const char *name, ShaderSocketType type, float value)
+ShaderInput *ShaderNode::add_input(const char *name, ShaderSocketType type, float value, int usage)
{
ShaderInput *input = new ShaderInput(this, name, type);
input->value.x = value;
+ input->usage = usage;
inputs.push_back(input);
return input;
}
-ShaderInput *ShaderNode::add_input(const char *name, ShaderSocketType type, float3 value)
+ShaderInput *ShaderNode::add_input(const char *name, ShaderSocketType type, float3 value, int usage)
{
ShaderInput *input = new ShaderInput(this, name, type);
input->value = value;
+ input->usage = usage;
inputs.push_back(input);
return input;
}
-ShaderInput *ShaderNode::add_input(const char *name, ShaderSocketType type, ShaderInput::DefaultValue value, bool osl_only)
+ShaderInput *ShaderNode::add_input(const char *name, ShaderSocketType type, ShaderInput::DefaultValue value, int usage)
{
ShaderInput *input = add_input(name, type);
input->default_value = value;
- input->osl_only = osl_only;
+ input->usage = usage;
return input;
}
@@ -219,7 +221,7 @@ void ShaderGraph::disconnect(ShaderInput *to)
from->links.erase(remove(from->links.begin(), from->links.end(), to), from->links.end());
}
-void ShaderGraph::finalize(bool do_bump, bool do_osl)
+void ShaderGraph::finalize(bool do_bump, bool do_osl, bool do_multi_transform)
{
/* before compiling, the shader graph may undergo a number of modifications.
* currently we set default geometry shader inputs, and create automatic bump
@@ -234,6 +236,18 @@ void ShaderGraph::finalize(bool do_bump, bool do_osl)
if(do_bump)
bump_from_displacement();
+ if(do_multi_transform) {
+ ShaderInput *surface_in = output()->input("Surface");
+ ShaderInput *volume_in = output()->input("Volume");
+
+ /* todo: make this work when surface and volume closures are tangled up */
+
+ if(surface_in->link)
+ transform_multi_closure(surface_in->link->parent, NULL, false);
+ if(volume_in->link)
+ transform_multi_closure(volume_in->link->parent, NULL, true);
+ }
+
finalized = true;
}
}
@@ -440,7 +454,7 @@ void ShaderGraph::default_inputs(bool do_osl)
foreach(ShaderNode *node, nodes) {
foreach(ShaderInput *input, node->inputs) {
- if(!input->link && !(input->osl_only && !do_osl)) {
+ if(!input->link && ((input->usage & ShaderInput::USE_SVM) || do_osl)) {
if(input->default_value == ShaderInput::TEXTURE_GENERATED) {
if(!texco)
texco = new TextureCoordinateNode();
@@ -629,5 +643,81 @@ void ShaderGraph::bump_from_displacement()
add(pair.second);
}
+void ShaderGraph::transform_multi_closure(ShaderNode *node, ShaderOutput *weight_out, bool volume)
+{
+ /* for SVM in multi closure mode, this transforms the shader mix/add part of
+ * the graph into nodes that feed weights into closure nodes. this is too
+ * avoid building a closure tree and then flattening it, and instead write it
+ * directly to an array */
+
+ if(node->name == ustring("mix_closure") || node->name == ustring("add_closure")) {
+ ShaderInput *fin = node->input("Fac");
+ ShaderInput *cl1in = node->input("Closure1");
+ ShaderInput *cl2in = node->input("Closure2");
+ ShaderOutput *weight1_out, *weight2_out;
+
+ if(fin) {
+ /* mix closure: add node to mix closure weights */
+ ShaderNode *mix_node = add(new MixClosureWeightNode());
+ ShaderInput *fac_in = mix_node->input("Fac");
+ ShaderInput *weight_in = mix_node->input("Weight");
+
+ if(fin->link)
+ connect(fin->link, fac_in);
+ else
+ fac_in->value = fin->value;
+
+ if(weight_out)
+ connect(weight_out, weight_in);
+
+ weight1_out = mix_node->output("Weight1");
+ weight2_out = mix_node->output("Weight2");
+ }
+ else {
+ /* add closure: just pass on any weights */
+ weight1_out = weight_out;
+ weight2_out = weight_out;
+ }
+
+ if(cl1in->link)
+ transform_multi_closure(cl1in->link->parent, weight1_out, volume);
+ if(cl2in->link)
+ transform_multi_closure(cl2in->link->parent, weight2_out, volume);
+ }
+ else {
+ ShaderInput *weight_in = node->input((volume)? "VolumeMixWeight": "SurfaceMixWeight");
+
+ /* not a closure node? */
+ if(!weight_in)
+ return;
+
+ /* already has a weight connected to it? add weights */
+ if(weight_in->link || weight_in->value.x != 0.0f) {
+ ShaderNode *math_node = add(new MathNode());
+ ShaderInput *value1_in = math_node->input("Value1");
+ ShaderInput *value2_in = math_node->input("Value2");
+
+ if(weight_in->link)
+ connect(weight_in->link, value1_in);
+ else
+ value1_in->value = weight_in->value;
+
+ if(weight_out)
+ connect(weight_out, value2_in);
+ else
+ value2_in->value.x = 1.0f;
+
+ weight_out = math_node->output("Value");
+ disconnect(weight_in);
+ }
+
+ /* connected to closure mix weight */
+ if(weight_out)
+ connect(weight_out, weight_in);
+ else
+ weight_in->value.x += 1.0f;
+ }
+}
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/graph.h b/intern/cycles/render/graph.h
index 373c7e0eaab..b79167839ab 100644
--- a/intern/cycles/render/graph.h
+++ b/intern/cycles/render/graph.h
@@ -118,6 +118,12 @@ public:
NONE
};
+ enum Usage {
+ USE_SVM = 1,
+ USE_OSL = 2,
+ USE_ALL = USE_SVM|USE_OSL
+ };
+
ShaderInput(ShaderNode *parent, const char *name, ShaderSocketType type);
void set(const float3& v) { value = v; }
void set(float f) { value = make_float3(f, 0, 0); }
@@ -134,7 +140,7 @@ public:
ustring value_string;
int stack_offset; /* for SVM compiler */
- bool osl_only;
+ int usage;
};
/* Output
@@ -167,9 +173,9 @@ public:
ShaderInput *input(const char *name);
ShaderOutput *output(const char *name);
- ShaderInput *add_input(const char *name, ShaderSocketType type, float value=0.0f);
- ShaderInput *add_input(const char *name, ShaderSocketType type, float3 value);
- ShaderInput *add_input(const char *name, ShaderSocketType type, ShaderInput::DefaultValue value, bool osl_only=false);
+ ShaderInput *add_input(const char *name, ShaderSocketType type, float value=0.0f, int usage=ShaderInput::USE_ALL);
+ ShaderInput *add_input(const char *name, ShaderSocketType type, float3 value, int usage=ShaderInput::USE_ALL);
+ ShaderInput *add_input(const char *name, ShaderSocketType type, ShaderInput::DefaultValue value, int usage=ShaderInput::USE_ALL);
ShaderOutput *add_output(const char *name, ShaderSocketType type);
virtual ShaderNode *clone() const = 0;
@@ -227,7 +233,7 @@ public:
void connect(ShaderOutput *from, ShaderInput *to);
void disconnect(ShaderInput *to);
- void finalize(bool do_bump = false, bool do_osl = false);
+ void finalize(bool do_bump = false, bool do_osl = false, bool do_multi_closure = false);
protected:
typedef pair<ShaderNode* const, ShaderNode*> NodePair;
@@ -241,6 +247,7 @@ protected:
void bump_from_displacement();
void refine_bump_nodes();
void default_inputs(bool do_osl);
+ void transform_multi_closure(ShaderNode *node, ShaderOutput *weight_out, bool volume);
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index 48a8565ed98..55fb9bf8a7e 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -1124,6 +1124,8 @@ ConvertNode::ConvertNode(ShaderSocketType from_, ShaderSocketType to_)
add_input("Point", SHADER_SOCKET_POINT);
else if(from == SHADER_SOCKET_NORMAL)
add_input("Normal", SHADER_SOCKET_NORMAL);
+ else if(from == SHADER_SOCKET_STRING)
+ add_input("String", SHADER_SOCKET_STRING);
else
assert(0);
@@ -1139,6 +1141,8 @@ ConvertNode::ConvertNode(ShaderSocketType from_, ShaderSocketType to_)
add_output("Point", SHADER_SOCKET_POINT);
else if(to == SHADER_SOCKET_NORMAL)
add_output("Normal", SHADER_SOCKET_NORMAL);
+ else if(to == SHADER_SOCKET_STRING)
+ add_output("String", SHADER_SOCKET_STRING);
else
assert(0);
}
@@ -1257,6 +1261,7 @@ BsdfNode::BsdfNode()
add_input("Color", SHADER_SOCKET_COLOR, make_float3(0.8f, 0.8f, 0.8f));
add_input("Normal", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL);
+ add_input("SurfaceMixWeight", SHADER_SOCKET_FLOAT, 0.0f, ShaderInput::USE_SVM);
add_output("BSDF", SHADER_SOCKET_CLOSURE);
}
@@ -1544,6 +1549,8 @@ EmissionNode::EmissionNode()
add_input("Color", SHADER_SOCKET_COLOR, make_float3(0.8f, 0.8f, 0.8f));
add_input("Strength", SHADER_SOCKET_FLOAT, 10.0f);
+ add_input("SurfaceMixWeight", SHADER_SOCKET_FLOAT, 0.0f, ShaderInput::USE_SVM);
+
add_output("Emission", SHADER_SOCKET_CLOSURE);
}
@@ -1578,6 +1585,8 @@ BackgroundNode::BackgroundNode()
{
add_input("Color", SHADER_SOCKET_COLOR, make_float3(0.8f, 0.8f, 0.8f));
add_input("Strength", SHADER_SOCKET_FLOAT, 1.0f);
+ add_input("SurfaceMixWeight", SHADER_SOCKET_FLOAT, 0.0f, ShaderInput::USE_SVM);
+
add_output("Background", SHADER_SOCKET_CLOSURE);
}
@@ -1607,11 +1616,17 @@ void BackgroundNode::compile(OSLCompiler& compiler)
HoldoutNode::HoldoutNode()
: ShaderNode("holdout")
{
+ add_input("SurfaceMixWeight", SHADER_SOCKET_FLOAT, 0.0f, ShaderInput::USE_SVM);
+ add_input("VolumeMixWeight", SHADER_SOCKET_FLOAT, 0.0f, ShaderInput::USE_SVM);
+
add_output("Holdout", SHADER_SOCKET_CLOSURE);
}
void HoldoutNode::compile(SVMCompiler& compiler)
{
+ float3 value = make_float3(1.0f, 1.0f, 1.0f);
+
+ compiler.add_node(NODE_CLOSURE_SET_WEIGHT, value);
compiler.add_node(NODE_CLOSURE_HOLDOUT, compiler.closure_mix_weight_offset());
}
@@ -1625,9 +1640,10 @@ void HoldoutNode::compile(OSLCompiler& compiler)
AmbientOcclusionNode::AmbientOcclusionNode()
: ShaderNode("ambient_occlusion")
{
- add_input("NormalIn", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, true);
-
+ add_input("NormalIn", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, ShaderInput::USE_OSL);
add_input("Color", SHADER_SOCKET_COLOR, make_float3(0.8f, 0.8f, 0.8f));
+ add_input("SurfaceMixWeight", SHADER_SOCKET_FLOAT, 0.0f, ShaderInput::USE_SVM);
+
add_output("AO", SHADER_SOCKET_CLOSURE);
}
@@ -1659,6 +1675,7 @@ VolumeNode::VolumeNode()
add_input("Color", SHADER_SOCKET_COLOR, make_float3(0.8f, 0.8f, 0.8f));
add_input("Density", SHADER_SOCKET_FLOAT, 1.0f);
+ add_input("VolumeMixWeight", SHADER_SOCKET_FLOAT, 0.0f, ShaderInput::USE_SVM);
add_output("Volume", SHADER_SOCKET_CLOSURE);
}
@@ -1737,7 +1754,7 @@ void IsotropicVolumeNode::compile(OSLCompiler& compiler)
GeometryNode::GeometryNode()
: ShaderNode("geometry")
{
- add_input("NormalIn", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, true);
+ add_input("NormalIn", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, ShaderInput::USE_OSL);
add_output("Position", SHADER_SOCKET_POINT);
add_output("Normal", SHADER_SOCKET_NORMAL);
add_output("Tangent", SHADER_SOCKET_NORMAL);
@@ -1825,7 +1842,7 @@ void GeometryNode::compile(OSLCompiler& compiler)
TextureCoordinateNode::TextureCoordinateNode()
: ShaderNode("texture_coordinate")
{
- add_input("NormalIn", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, true);
+ add_input("NormalIn", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, ShaderInput::USE_OSL);
add_output("Generated", SHADER_SOCKET_POINT);
add_output("Normal", SHADER_SOCKET_NORMAL);
add_output("UV", SHADER_SOCKET_POINT);
@@ -2315,6 +2332,39 @@ void MixClosureNode::compile(OSLCompiler& compiler)
compiler.add(this, "node_mix_closure");
}
+/* Mix Closure */
+
+MixClosureWeightNode::MixClosureWeightNode()
+: ShaderNode("mix_closure_weight")
+{
+ add_input("Weight", SHADER_SOCKET_FLOAT, 1.0f);
+ add_input("Fac", SHADER_SOCKET_FLOAT, 1.0f);
+ add_output("Weight1", SHADER_SOCKET_FLOAT);
+ add_output("Weight2", SHADER_SOCKET_FLOAT);
+}
+
+void MixClosureWeightNode::compile(SVMCompiler& compiler)
+{
+ ShaderInput *weight_in = input("Weight");
+ ShaderInput *fac_in = input("Fac");
+ ShaderOutput *weight1_out = output("Weight1");
+ ShaderOutput *weight2_out = output("Weight2");
+
+ compiler.stack_assign(weight_in);
+ compiler.stack_assign(fac_in);
+ compiler.stack_assign(weight1_out);
+ compiler.stack_assign(weight2_out);
+
+ compiler.add_node(NODE_MIX_CLOSURE,
+ compiler.encode_uchar4(fac_in->stack_offset, weight_in->stack_offset,
+ weight1_out->stack_offset, weight2_out->stack_offset));
+}
+
+void MixClosureWeightNode::compile(OSLCompiler& compiler)
+{
+ assert(0);
+}
+
/* Invert */
InvertNode::InvertNode()
@@ -2680,7 +2730,7 @@ void CameraNode::compile(OSLCompiler& compiler)
FresnelNode::FresnelNode()
: ShaderNode("Fresnel")
{
- add_input("Normal", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, true);
+ add_input("Normal", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, ShaderInput::USE_OSL);
add_input("IOR", SHADER_SOCKET_FLOAT, 1.45f);
add_output("Fac", SHADER_SOCKET_FLOAT);
}
@@ -2705,7 +2755,7 @@ void FresnelNode::compile(OSLCompiler& compiler)
LayerWeightNode::LayerWeightNode()
: ShaderNode("LayerWeight")
{
- add_input("Normal", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, true);
+ add_input("Normal", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, ShaderInput::USE_OSL);
add_input("Blend", SHADER_SOCKET_FLOAT, 0.5f);
add_output("Fresnel", SHADER_SOCKET_FLOAT);
@@ -3080,7 +3130,7 @@ NormalMapNode::NormalMapNode()
space = ustring("Tangent");
attribute = ustring("");
- add_input("NormalIn", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, true);
+ add_input("NormalIn", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, ShaderInput::USE_OSL);
add_input("Strength", SHADER_SOCKET_FLOAT, 1.0f);
add_input("Color", SHADER_SOCKET_COLOR);
@@ -3185,7 +3235,7 @@ TangentNode::TangentNode()
axis = ustring("X");
attribute = ustring("");
- add_input("NormalIn", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, true);
+ add_input("NormalIn", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, ShaderInput::USE_OSL);
add_output("Tangent", SHADER_SOCKET_NORMAL);
}
diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h
index 3e89c2286ad..67733142dd1 100644
--- a/intern/cycles/render/nodes.h
+++ b/intern/cycles/render/nodes.h
@@ -351,6 +351,11 @@ public:
SHADER_NODE_CLASS(MixClosureNode)
};
+class MixClosureWeightNode : public ShaderNode {
+public:
+ SHADER_NODE_CLASS(MixClosureWeightNode);
+};
+
class InvertNode : public ShaderNode {
public:
SHADER_NODE_CLASS(InvertNode)
diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp
index 25b4d1f08cc..d08cb07fc3c 100644
--- a/intern/cycles/render/object.cpp
+++ b/intern/cycles/render/object.cpp
@@ -56,7 +56,7 @@ void Object::compute_bounds(bool motion_blur, float shuttertime)
BoundBox mbounds = mesh->bounds;
if(motion_blur && use_motion) {
- MotionTransform decomp;
+ DecompMotionTransform decomp;
transform_motion_decompose(&decomp, &motion, &tfm);
bounds = BoundBox::empty;
@@ -222,29 +222,29 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene
mtfm_post = mtfm_post * itfm;
memcpy(&objects[offset+8], &mtfm_pre, sizeof(float4)*4);
- memcpy(&objects[offset+16], &mtfm_post, sizeof(float4)*4);
+ memcpy(&objects[offset+12], &mtfm_post, sizeof(float4)*4);
}
#ifdef __OBJECT_MOTION__
else if(need_motion == Scene::MOTION_BLUR) {
if(ob->use_motion) {
/* decompose transformations for interpolation */
- MotionTransform decomp;
+ DecompMotionTransform decomp;
transform_motion_decompose(&decomp, &ob->motion, &ob->tfm);
- memcpy(&objects[offset+8], &decomp, sizeof(float4)*12);
+ memcpy(&objects[offset+8], &decomp, sizeof(float4)*8);
flag |= SD_OBJECT_MOTION;
have_motion = true;
}
else {
float4 no_motion = make_float4(FLT_MAX);
- memcpy(&objects[offset+8], &no_motion, sizeof(float4)*12);
+ memcpy(&objects[offset+8], &no_motion, sizeof(float4)*8);
}
}
#endif
/* dupli object coords */
- objects[offset+20] = make_float4(ob->dupli_generated[0], ob->dupli_generated[1], ob->dupli_generated[2], 0.0f);
- objects[offset+21] = make_float4(ob->dupli_uv[0], ob->dupli_uv[1], 0.0f, 0.0f);
+ objects[offset+16] = make_float4(ob->dupli_generated[0], ob->dupli_generated[1], ob->dupli_generated[2], 0.0f);
+ objects[offset+17] = make_float4(ob->dupli_uv[0], ob->dupli_uv[1], 0.0f, 0.0f);
/* object flag */
if(ob->use_holdout)
diff --git a/intern/cycles/render/osl.cpp b/intern/cycles/render/osl.cpp
index c5ecddcfc15..2ec7e3d3775 100644
--- a/intern/cycles/render/osl.cpp
+++ b/intern/cycles/render/osl.cpp
@@ -138,6 +138,7 @@ void OSLShaderManager::texture_system_init()
ts = TextureSystem::create(true);
ts->attribute("automip", 1);
ts->attribute("autotile", 64);
+ ts->attribute("gray_to_rgb", 1);
/* effectively unlimited for now, until we support proper mipmap lookups */
ts->attribute("max_memory_MB", 16384);
@@ -351,6 +352,9 @@ bool OSLCompiler::node_skip_input(ShaderNode *node, ShaderInput *input)
{
/* exception for output node, only one input is actually used
* depending on the current shader type */
+
+ if(!(input->usage & ShaderInput::USE_OSL))
+ return true;
if(node->name == ustring("output")) {
if(strcmp(input->name, "Surface") == 0 && current_type != SHADER_TYPE_SURFACE)
diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp
index 003b722b5a5..1d1a3d54893 100644
--- a/intern/cycles/render/session.cpp
+++ b/intern/cycles/render/session.cpp
@@ -637,6 +637,15 @@ void Session::reset(BufferParams& buffer_params, int samples)
reset_gpu(buffer_params, samples);
else
reset_cpu(buffer_params, samples);
+
+ if(params.progressive_refine) {
+ thread_scoped_lock buffers_lock(buffers_mutex);
+
+ foreach(RenderBuffers *buffers, tile_buffers)
+ delete buffers;
+
+ tile_buffers.clear();
+ }
}
void Session::set_samples(int samples)
diff --git a/intern/cycles/render/svm.cpp b/intern/cycles/render/svm.cpp
index 73904eac41d..4acd174e60f 100644
--- a/intern/cycles/render/svm.cpp
+++ b/intern/cycles/render/svm.cpp
@@ -487,106 +487,30 @@ void SVMCompiler::generate_closure(ShaderNode *node, set<ShaderNode*>& done)
}
}
-void SVMCompiler::count_closure_users(ShaderNode *node, map<ShaderNode*, MultiClosureData>& closure_data)
-{
- /* here we count the number of times each closure node is used, so that
- * the last time we encounter it we can run the actually code with the
- * weights from all other places added together */
-
- if(node->name == ustring("mix_closure") || node->name == ustring("add_closure")) {
- ShaderInput *cl1in = node->input("Closure1");
- ShaderInput *cl2in = node->input("Closure2");
-
- if(cl1in->link)
- count_closure_users(cl1in->link->parent, closure_data);
- if(cl2in->link)
- count_closure_users(cl2in->link->parent, closure_data);
- }
- else {
- MultiClosureData data;
-
- if(closure_data.find(node) == closure_data.end()) {
- data.stack_offset = SVM_STACK_INVALID;
- data.users = 1;
- }
- else {
- data = closure_data[node];
- data.users++;
- }
-
- closure_data[node] = data;
- }
-}
-
-void SVMCompiler::generate_multi_closure(ShaderNode *node, set<ShaderNode*>& done,
- map<ShaderNode*, MultiClosureData>& closure_data, uint in_offset)
+void SVMCompiler::generate_multi_closure(ShaderNode *node, set<ShaderNode*>& done, set<ShaderNode*>& closure_done)
{
/* todo: the weaks point here is that unlike the single closure sampling
* we will evaluate all nodes even if they are used as input for closures
* that are unused. it's not clear what would be the best way to skip such
* nodes at runtime, especially if they are tangled up */
+
+ /* only generate once */
+ if(closure_done.find(node) != closure_done.end())
+ return;
+
+ closure_done.insert(node);
if(node->name == ustring("mix_closure") || node->name == ustring("add_closure")) {
- ShaderInput *fin = node->input("Fac");
+ /* weighting is already taken care of in ShaderGraph::transform_multi_closure */
ShaderInput *cl1in = node->input("Closure1");
ShaderInput *cl2in = node->input("Closure2");
- uint out1_offset = SVM_STACK_INVALID;
- uint out2_offset = SVM_STACK_INVALID;
-
- if(fin) {
- /* mix closure */
- set<ShaderNode*> dependencies;
- find_dependencies(dependencies, done, fin);
- generate_svm_nodes(dependencies, done);
-
- stack_assign(fin);
-
- if(cl1in->link)
- out1_offset = stack_find_offset(SHADER_SOCKET_FLOAT);
- if(cl2in->link)
- out2_offset = stack_find_offset(SHADER_SOCKET_FLOAT);
-
- add_node(NODE_MIX_CLOSURE,
- encode_uchar4(fin->stack_offset, in_offset, out1_offset, out2_offset));
- }
- else {
- /* add closure */
- out1_offset = in_offset;
- out2_offset = in_offset;
- }
-
if(cl1in->link)
- generate_multi_closure(cl1in->link->parent, done, closure_data, out1_offset);
-
+ generate_multi_closure(cl1in->link->parent, done, closure_done);
if(cl2in->link)
- generate_multi_closure(cl2in->link->parent, done, closure_data, out2_offset);
-
- if(in_offset != SVM_STACK_INVALID)
- stack_clear_offset(SHADER_SOCKET_FLOAT, in_offset);
+ generate_multi_closure(cl2in->link->parent, done, closure_done);
}
else {
- MultiClosureData data = closure_data[node];
-
- if(data.stack_offset == SVM_STACK_INVALID) {
- /* first time using closure, use stack position for weight */
- data.stack_offset = in_offset;
- }
- else {
- /* not first time using, add weights together */
- add_node(NODE_MATH, NODE_MATH_ADD, data.stack_offset, in_offset);
- add_node(NODE_MATH, data.stack_offset);
-
- stack_clear_offset(SHADER_SOCKET_FLOAT, in_offset);
- }
-
- data.users--;
- closure_data[node] = data;
-
- /* still users coming? skip generating closure code */
- if(data.users > 0)
- return;
-
/* execute dependencies for closure */
foreach(ShaderInput *in, node->inputs) {
if(!node_skip_input(node, in) && in->link) {
@@ -596,7 +520,16 @@ void SVMCompiler::generate_multi_closure(ShaderNode *node, set<ShaderNode*>& don
}
}
- mix_weight_offset = data.stack_offset;
+ /* closure mix weight */
+ const char *weight_name = (current_type == SHADER_TYPE_VOLUME)? "VolumeMixWeight": "SurfaceMixWeight";
+ ShaderInput *weight_in = node->input(weight_name);
+
+ if(weight_in && (weight_in->link || weight_in->value.x != 1.0f)) {
+ stack_assign(weight_in);
+ mix_weight_offset = weight_in->stack_offset;
+ }
+ else
+ mix_weight_offset = SVM_STACK_INVALID;
/* compile closure itself */
node->compile(*this);
@@ -609,12 +542,9 @@ void SVMCompiler::generate_multi_closure(ShaderNode *node, set<ShaderNode*>& don
current_shader->has_surface_emission = true;
if(node->name == ustring("transparent"))
current_shader->has_surface_transparent = true;
-
- /* end node is added outside of this */
-
- if(data.stack_offset != SVM_STACK_INVALID)
- stack_clear_offset(SHADER_SOCKET_FLOAT, data.stack_offset);
}
+
+ done.insert(node);
}
@@ -686,10 +616,8 @@ void SVMCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType ty
set<ShaderNode*> done;
if(use_multi_closure) {
- map<ShaderNode*, MultiClosureData> closure_data;
-
- count_closure_users(clin->link->parent, closure_data);
- generate_multi_closure(clin->link->parent, done, closure_data, SVM_STACK_INVALID);
+ set<ShaderNode*> closure_done;
+ generate_multi_closure(clin->link->parent, done, closure_done);
}
else
generate_closure(clin->link->parent, done);
@@ -713,9 +641,9 @@ void SVMCompiler::compile(Shader *shader, vector<int4>& global_svm_nodes, int in
shader->graph_bump = shader->graph->copy();
/* finalize */
- shader->graph->finalize(false, false);
+ shader->graph->finalize(false, false, use_multi_closure);
if(shader->graph_bump)
- shader->graph_bump->finalize(true, false);
+ shader->graph_bump->finalize(true, false, use_multi_closure);
current_shader = shader;
diff --git a/intern/cycles/render/svm.h b/intern/cycles/render/svm.h
index c7b66d97289..0b15c5aaa1e 100644
--- a/intern/cycles/render/svm.h
+++ b/intern/cycles/render/svm.h
@@ -130,14 +130,7 @@ protected:
void generate_closure(ShaderNode *node, set<ShaderNode*>& done);
/* multi closure */
- struct MultiClosureData {
- int stack_offset;
- int users;
- };
-
- void generate_multi_closure(ShaderNode *node, set<ShaderNode*>& done,
- map<ShaderNode*,MultiClosureData>& closure_data, uint in_offset);
- void count_closure_users(ShaderNode *node, map<ShaderNode*, MultiClosureData>& closure_data);
+ void generate_multi_closure(ShaderNode *node, set<ShaderNode*>& done, set<ShaderNode*>& closure_done);
/* compile */
void compile_type(Shader *shader, ShaderGraph *graph, ShaderType type);
diff --git a/intern/cycles/util/util_transform.cpp b/intern/cycles/util/util_transform.cpp
index 4eee024990f..ca19146e125 100644
--- a/intern/cycles/util/util_transform.cpp
+++ b/intern/cycles/util/util_transform.cpp
@@ -246,18 +246,30 @@ static void transform_decompose(Transform *decomp, const Transform *tfm)
decomp->w = make_float4(scale.y.z, scale.z.x, scale.z.y, scale.z.z);
}
-void transform_motion_decompose(MotionTransform *decomp, const MotionTransform *motion, const Transform *mid)
+void transform_motion_decompose(DecompMotionTransform *decomp, const MotionTransform *motion, const Transform *mid)
{
- transform_decompose(&decomp->pre, &motion->pre);
+ Transform pre, post;
+
+ transform_decompose(&pre, &motion->pre);
transform_decompose(&decomp->mid, mid);
- transform_decompose(&decomp->post, &motion->post);
+ transform_decompose(&post, &motion->post);
/* ensure rotation around shortest angle, negated quaternions are the same
* but this means we don't have to do the check in quat_interpolate */
- if(dot(decomp->mid.x, decomp->post.x) < 0.0f)
+ if(dot(decomp->mid.x, post.x) < 0.0f)
decomp->mid.x = -decomp->mid.x;
- if(dot(decomp->pre.x, decomp->mid.x) < 0.0f)
- decomp->pre.x = -decomp->pre.x;
+ if(dot(pre.x, decomp->mid.x) < 0.0f)
+ pre.x = -pre.x;
+
+ /* drop scale of pre/post */
+ pre.y.w = decomp->mid.y.w;
+ post.y.w = decomp->mid.y.w;
+
+ /* store translation/rotation part of pre/post */
+ decomp->pre_x = pre.x;
+ decomp->pre_y = pre.y;
+ decomp->post_x = post.x;
+ decomp->post_y = post.y;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/util/util_transform.h b/intern/cycles/util/util_transform.h
index 65162ebf4e6..a1c12ddf0e1 100644
--- a/intern/cycles/util/util_transform.h
+++ b/intern/cycles/util/util_transform.h
@@ -41,7 +41,9 @@ typedef struct Transform {
/* transform decomposed in rotation/translation/scale. we use the same data
* structure as Transform, and tightly pack decomposition into it. first the
- * rotation (4), then translation (3), then 3x3 scale matrix (9) */
+ * rotation (4), then translation (3), then 3x3 scale matrix (9).
+ *
+ * For the DecompMotionTransform we drop scale from pre/post. */
typedef struct MotionTransform {
Transform pre;
@@ -49,6 +51,12 @@ typedef struct MotionTransform {
Transform post;
} MotionTransform;
+typedef struct DecompMotionTransform {
+ Transform mid;
+ float4 pre_x, pre_y;
+ float4 post_x, post_y;
+} DecompMotionTransform;
+
/* Functions */
__device_inline float3 transform_perspective(const Transform *t, const float3 a)
@@ -303,6 +311,10 @@ __device_inline Transform transform_clear_scale(const Transform& tfm)
__device_inline float4 quat_interpolate(float4 q1, float4 q2, float t)
{
+ /* use simpe nlerp instead of slerp. it's faster and almost the same */
+ return normalize((1.0f - t)*q1 + t*q2);
+
+#if 0
/* note: this does not ensure rotation around shortest angle, q1 and q2
* are assumed to be matched already in transform_motion_decompose */
float costheta = dot(q1, q2);
@@ -320,6 +332,7 @@ __device_inline float4 quat_interpolate(float4 q1, float4 q2, float t)
float thetap = theta * t;
return q1 * cosf(thetap) + qperp * sinf(thetap);
}
+#endif
}
__device_inline Transform transform_quick_inverse(Transform M)
@@ -384,7 +397,7 @@ __device_inline void transform_compose(Transform *tfm, const Transform *decomp)
/* Disabled for now, need arc-length parametrization for constant speed motion.
* #define CURVED_MOTION_INTERPOLATE */
-__device void transform_motion_interpolate(Transform *tfm, const MotionTransform *motion, float t)
+__device void transform_motion_interpolate(Transform *tfm, const DecompMotionTransform *motion, float t)
{
/* possible optimization: is it worth it adding a check to skip scaling?
* it's probably quite uncommon to have scaling objects. or can we skip
@@ -393,9 +406,9 @@ __device void transform_motion_interpolate(Transform *tfm, const MotionTransform
#ifdef CURVED_MOTION_INTERPOLATE
/* 3 point bezier curve interpolation for position */
- float3 Ppre = float4_to_float3(motion->pre.y);
+ float3 Ppre = float4_to_float3(motion->pre_y);
float3 Pmid = float4_to_float3(motion->mid.y);
- float3 Ppost = float4_to_float3(motion->post.y);
+ float3 Ppost = float4_to_float3(motion->post_y);
float3 Pcontrol = 2.0f*Pmid - 0.5f*(Ppre + Ppost);
float3 P = Ppre*t*t + Pcontrol*2.0f*t*(1.0f - t) + Ppost*(1.0f - t)*(1.0f - t);
@@ -409,28 +422,27 @@ __device void transform_motion_interpolate(Transform *tfm, const MotionTransform
if(t < 0.5f) {
t *= 2.0f;
- decomp.x = quat_interpolate(motion->pre.x, motion->mid.x, t);
+ decomp.x = quat_interpolate(motion->pre_x, motion->mid.x, t);
#ifdef CURVED_MOTION_INTERPOLATE
- decomp.y.w = (1.0f - t)*motion->pre.y.w + t*motion->mid.y.w;
+ decomp.y.w = (1.0f - t)*motion->pre_y.w + t*motion->mid.y.w;
#else
- decomp.y = (1.0f - t)*motion->pre.y + t*motion->mid.y;
+ decomp.y = (1.0f - t)*motion->pre_y + t*motion->mid.y;
#endif
- decomp.z = (1.0f - t)*motion->pre.z + t*motion->mid.z;
- decomp.w = (1.0f - t)*motion->pre.w + t*motion->mid.w;
}
else {
t = (t - 0.5f)*2.0f;
- decomp.x = quat_interpolate(motion->mid.x, motion->post.x, t);
+ decomp.x = quat_interpolate(motion->mid.x, motion->post_x, t);
#ifdef CURVED_MOTION_INTERPOLATE
- decomp.y.w = (1.0f - t)*motion->mid.y.w + t*motion->post.y.w;
+ decomp.y.w = (1.0f - t)*motion->mid.y.w + t*motion->post_y.w;
#else
- decomp.y = (1.0f - t)*motion->mid.y + t*motion->post.y;
+ decomp.y = (1.0f - t)*motion->mid.y + t*motion->post_y;
#endif
- decomp.z = (1.0f - t)*motion->mid.z + t*motion->post.z;
- decomp.w = (1.0f - t)*motion->mid.w + t*motion->post.w;
}
+ decomp.z = motion->mid.z;
+ decomp.w = motion->mid.w;
+
/* compose rotation, translation, scale into matrix */
transform_compose(tfm, &decomp);
}
@@ -442,7 +454,7 @@ __device_inline bool operator==(const MotionTransform& A, const MotionTransform&
return (A.pre == B.pre && A.post == B.post);
}
-void transform_motion_decompose(MotionTransform *decomp, const MotionTransform *motion, const Transform *mid);
+void transform_motion_decompose(DecompMotionTransform *decomp, const MotionTransform *motion, const Transform *mid);
#endif
diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h
index 87ab3c013c6..f886dfd9d7d 100644
--- a/intern/ghost/GHOST_C-api.h
+++ b/intern/ghost/GHOST_C-api.h
@@ -120,7 +120,7 @@ extern GHOST_TimerTaskHandle GHOST_InstallTimer(GHOST_SystemHandle systemhandle,
/**
* Removes a timer.
* \param systemhandle The handle to the system
- * \param timerTask Timer task to be removed.
+ * \param timertaskhandle Timer task to be removed.
* \return Indication of success.
*/
extern GHOST_TSuccess GHOST_RemoveTimer(GHOST_SystemHandle systemhandle,
@@ -185,7 +185,7 @@ extern GHOST_TUserDataPtr GHOST_GetWindowUserData(GHOST_WindowHandle windowhandl
/**
* Changes the window user data.
* \param windowhandle The handle to the window
- * \param data The window user data.
+ * \param userdata The window user data.
*/
extern void GHOST_SetWindowUserData(GHOST_WindowHandle windowhandle,
GHOST_TUserDataPtr userdata);
@@ -212,6 +212,7 @@ extern int GHOST_ValidWindow(GHOST_SystemHandle systemhandle,
* Begins full screen mode.
* \param systemhandle The handle to the system
* \param setting The new setting of the display.
+ * \param stereoVisual Option for stereo display.
* \return A handle to the window displayed in full screen.
* This window is invalid after full screen has been ended.
*/
@@ -302,7 +303,7 @@ extern GHOST_TStandardCursor GHOST_GetCursorShape(GHOST_WindowHandle windowhandl
/**
* Set the shape of the cursor.
* \param windowhandle The handle to the window
- * \param cursor The new cursor shape type id.
+ * \param cursorshape The new cursor shape type id.
* \return Indication of success.
*/
extern GHOST_TSuccess GHOST_SetCursorShape(GHOST_WindowHandle windowhandle,
@@ -484,10 +485,10 @@ extern GHOST_TUserDataPtr GHOST_GetTimerTaskUserData(GHOST_TimerTaskHandle timer
/**
* Changes the time user data.
* \param timertaskhandle The handle to the timertask
- * \param data The timer user data.
+ * \param userdata The timer user data.
*/
extern void GHOST_SetTimerTaskUserData(GHOST_TimerTaskHandle timertaskhandle,
- GHOST_TUserDataPtr userData);
+ GHOST_TUserDataPtr userdata);
/**
* Returns indication as to whether the window is valid.
@@ -825,7 +826,8 @@ extern GHOST_TUns8 *GHOST_getClipboard(int selection);
/**
* Put data to the Clipboard
- * \param set the selection instead, X11 only feature
+ * \param buffer the string buffer to set.
+ * \param selection Set the selection instead, X11 only feature.
*/
extern void GHOST_putClipboard(GHOST_TInt8 *buffer, int selection);
diff --git a/intern/guardedalloc/intern/mallocn.c b/intern/guardedalloc/intern/mallocn.c
index a65871f4410..4a79f5d0de1 100644
--- a/intern/guardedalloc/intern/mallocn.c
+++ b/intern/guardedalloc/intern/mallocn.c
@@ -58,7 +58,7 @@
* store original buffer's name when doing MEM_dupallocN
* helpful to profile issues with non-freed "dup_alloc" buffers,
* but this introduces some overhead to memory header and makes
- * things slower a bit, so betterto keep disabled by default
+ * things slower a bit, so better to keep disabled by default
*/
//#define DEBUG_MEMDUPLINAME
diff --git a/intern/utfconv/utfconv.h b/intern/utfconv/utfconv.h
index cf0e69170a2..ada85e274e3 100644
--- a/intern/utfconv/utfconv.h
+++ b/intern/utfconv/utfconv.h
@@ -57,18 +57,18 @@ size_t count_utf_16_from_8(const char *string8);
/**
* Converts utf-16 string to allocated utf-8 string
- * @params in16 utf-16 string to convert
- * @params out8 utf-8 string to string the conversion
- * @params size8 the allocated size in bytes of out8
+ * @param in16 utf-16 string to convert
+ * @param out8 utf-8 string to string the conversion
+ * @param size8 the allocated size in bytes of out8
* @return Returns any errors occured during conversion. See the block above,
*/
int conv_utf_16_to_8(const wchar_t *in16, char *out8, size_t size8);
/**
* Converts utf-8 string to allocated utf-16 string
- * @params in8 utf-8 string to convert
- * @params out16 utf-16 string to string the conversion
- * @params size16 the allocated size in wchar_t (two byte) of out16
+ * @param in8 utf-8 string to convert
+ * @param out16 utf-16 string to string the conversion
+ * @param size16 the allocated size in wchar_t (two byte) of out16
* @return Returns any errors occured during conversion. See the block above,
*/
int conv_utf_8_to_16(const char *in8, wchar_t *out16, size_t size16);
@@ -76,16 +76,16 @@ int conv_utf_8_to_16(const char *in8, wchar_t *out16, size_t size16);
/**
* Allocates and converts the utf-8 string from utf-16
- * @params in16 utf-16 string to convert
- * @params add any additional size which will be allocated for new utf-8 string in bytes
+ * @param in16 utf-16 string to convert
+ * @param add any additional size which will be allocated for new utf-8 string in bytes
* @return New allocated and converted utf-8 string or NULL if in16 is 0.
*/
char *alloc_utf_8_from_16(const wchar_t *in16, size_t add);
/**
* Allocates and converts the utf-16 string from utf-8
- * @params in8 utf-8 string to convert
- * @params add any additional size which will be allocated for new utf-16 string in wchar_t (two bytes)
+ * @param in8 utf-8 string to convert
+ * @param add any additional size which will be allocated for new utf-16 string in wchar_t (two bytes)
* @return New allocated and converted utf-16 string or NULL if in8 is 0.
*/
wchar_t *alloc_utf16_from_8(const char *in8, size_t add);
diff --git a/release/datafiles/startup.blend b/release/datafiles/startup.blend
index 3d31f9cb758..49212f6f9cb 100644
--- a/release/datafiles/startup.blend
+++ b/release/datafiles/startup.blend
Binary files differ
diff --git a/release/scripts/modules/bl_i18n_utils/spell_check_utils.py b/release/scripts/modules/bl_i18n_utils/spell_check_utils.py
index 34eab11f9d4..fbe405a61c6 100644
--- a/release/scripts/modules/bl_i18n_utils/spell_check_utils.py
+++ b/release/scripts/modules/bl_i18n_utils/spell_check_utils.py
@@ -426,12 +426,14 @@ dict_uimsgs = {
"fh",
"fov",
"fft",
+ "futura",
"gfx",
"gl",
"glsl",
"gpl",
"gpu", "gpus",
"hc",
+ "hdc",
"hdr",
"hh", "mm", "ss", "ff", # hh:mm:ss:ff timecode
"hsv", "hsva",
@@ -442,6 +444,7 @@ dict_uimsgs = {
"mux",
"ndof",
"ppc",
+ "precisa",
"px",
"qmc",
"rgb", "rgba",
diff --git a/release/scripts/modules/bl_i18n_utils/update_trunk.py b/release/scripts/modules/bl_i18n_utils/update_trunk.py
index 9b904ec861a..b84a227ae0a 100755
--- a/release/scripts/modules/bl_i18n_utils/update_trunk.py
+++ b/release/scripts/modules/bl_i18n_utils/update_trunk.py
@@ -115,7 +115,7 @@ def main():
if not os.path.exists(os.path.join(TRUNK_PO_DIR, ".".join((lang, "po")))):
failed.add(lang)
- # Check and compile each po separatly, to keep track of those failing.
+ # Check and compile each po separately, to keep track of those failing.
# XXX There should not be any failing at this stage, import step is
# supposed to have already filtered them out!
for po in os.listdir(TRUNK_PO_DIR):
diff --git a/release/scripts/modules/bpy_extras/mesh_utils.py b/release/scripts/modules/bpy_extras/mesh_utils.py
index 2042cc1c8a1..0166f954dc9 100644
--- a/release/scripts/modules/bpy_extras/mesh_utils.py
+++ b/release/scripts/modules/bpy_extras/mesh_utils.py
@@ -325,10 +325,12 @@ def ngon_tessellate(from_data, indices, fix_loops=True):
fgon to create from existing verts.
from_data: either a mesh, or a list/tuple of vectors.
- indices: a list of indices to use this list is the ordered closed polyline
+ :arg indices: a list of indices to use this list is the ordered closed polyline
to fill, and can be a subset of the data given.
- fix_loops: If this is enabled polylines that use loops to make multiple
+ :type indices: list
+ :arg fix_loops: If this is enabled polylines that use loops to make multiple
polylines are delt with correctly.
+ :type fix_loops: bool
"""
from mathutils.geometry import tessellate_polygon
diff --git a/release/scripts/modules/bpy_types.py b/release/scripts/modules/bpy_types.py
index 4cd823d9184..e42ae43aed6 100644
--- a/release/scripts/modules/bpy_types.py
+++ b/release/scripts/modules/bpy_types.py
@@ -394,7 +394,7 @@ class Mesh(bpy_types.ID):
p.vertices = f
loop_index += loop_len
- # if no edges - calculae them
+ # if no edges - calculate them
if faces and (not edges):
self.update(calc_edges=True)
diff --git a/release/scripts/modules/rna_xml.py b/release/scripts/modules/rna_xml.py
index fc8e3125228..e21ccd08a35 100644
--- a/release/scripts/modules/rna_xml.py
+++ b/release/scripts/modules/rna_xml.py
@@ -178,7 +178,7 @@ def rna2xml(fw=print_ln,
fw("%s</%s>\n" % (ident, value_type_name))
# -------------------------------------------------------------------------
- # needs re-workign to be generic
+ # needs re-working to be generic
if root_node:
fw("%s<%s>\n" % (root_ident, root_node))
diff --git a/release/scripts/startup/bl_operators/uvcalc_follow_active.py b/release/scripts/startup/bl_operators/uvcalc_follow_active.py
index b60b5257984..727c4ad739f 100644
--- a/release/scripts/startup/bl_operators/uvcalc_follow_active.py
+++ b/release/scripts/startup/bl_operators/uvcalc_follow_active.py
@@ -26,195 +26,124 @@ from bpy.types import Operator
def extend(obj, operator, EXTEND_MODE):
- from bpy_extras import mesh_utils
-
+ import bmesh
me = obj.data
- me_verts = me.vertices
-
# script will fail without UVs
if not me.uv_textures:
me.uv_textures.new()
+
+ bm = bmesh.from_edit_mesh(me)
+
+ f_act = bm.faces.active
+ uv_act = bm.loops.layers.uv.active
+
+ if f_act is None:
+ operator.report({'ERROR'}, "No active face")
+ return
+ elif len(f_act.verts) != 4:
+ operator.report({'ERROR'}, "Active face must be a quad")
+ return
- # Toggle Edit mode
- is_editmode = (obj.mode == 'EDIT')
- if is_editmode:
- bpy.ops.object.mode_set(mode='OBJECT')
-
- #t = sys.time()
- edge_average_lengths = {}
-
- OTHER_INDEX = 2, 3, 0, 1
-
- def extend_uvs(face_source, face_target, edge_key):
- """
- Takes 2 faces,
- Projects its extends its UV coords onto the face next to it.
- Both faces must share an edge
- """
-
- def face_edge_vs(vi):
- vlen = len(vi)
- return [(vi[i], vi[(i + 1) % vlen]) for i in range(vlen)]
-
- vidx_source = face_source.vertices
- vidx_target = face_target.vertices
-
- uv_layer = me.uv_layers.active.data
- uvs_source = [uv_layer[i].uv for i in face_source.loop_indices]
- uvs_target = [uv_layer[i].uv for i in face_target.loop_indices]
-
- # vertex index is the key, uv is the value
-
- uvs_vhash_source = {vindex: uvs_source[i] for i, vindex in enumerate(vidx_source)}
-
- uvs_vhash_target = {vindex: uvs_target[i] for i, vindex in enumerate(vidx_target)}
-
- edge_idxs_source = face_edge_vs(vidx_source)
- edge_idxs_target = face_edge_vs(vidx_target)
-
- source_matching_edge = -1
- target_matching_edge = -1
-
- edge_key_swap = edge_key[1], edge_key[0]
-
- try:
- source_matching_edge = edge_idxs_source.index(edge_key)
- except:
- source_matching_edge = edge_idxs_source.index(edge_key_swap)
- try:
- target_matching_edge = edge_idxs_target.index(edge_key)
- except:
- target_matching_edge = edge_idxs_target.index(edge_key_swap)
-
- edgepair_inner_source = edge_idxs_source[source_matching_edge]
- edgepair_inner_target = edge_idxs_target[target_matching_edge]
- edgepair_outer_source = edge_idxs_source[OTHER_INDEX[source_matching_edge]]
- edgepair_outer_target = edge_idxs_target[OTHER_INDEX[target_matching_edge]]
-
- if edge_idxs_source[source_matching_edge] == edge_idxs_target[target_matching_edge]:
- iA = 0 # Flipped, most common
- iB = 1
- else: # The normals of these faces must be different
- iA = 1
- iB = 0
+ faces = [f for f in bm.faces if f.select and len(f.verts) == 4]
+
+ for f in faces:
+ f.tag = False
+ f_act.tag = True
+
+
+ # our own local walker
+ def walk_face(f):
+ # all faces in this list must be tagged
+ f.tag = True
+ faces_a = [f]
+ faces_b = []
+
+ while faces_a:
+ for f in faces_a:
+ for l in f.loops:
+ l_edge = l.edge
+ if (l_edge.is_manifold is True) and (l_edge.seam is False):
+ l_other = l.link_loop_radial_next
+ f_other = l_other.face
+ if not f_other.tag:
+ yield (f, l, f_other)
+ f_other.tag = True
+ faces_b.append(f_other)
+ # swap
+ faces_a, faces_b = faces_b, faces_a
+ faces_b.clear()
+
+ def extrapolate_uv(fac,
+ l_a_outer, l_a_inner,
+ l_b_outer, l_b_inner):
+ l_b_inner[:] = l_a_inner
+ l_b_outer[:] = l_a_inner + ((l_a_inner - l_a_outer) * fac)
+
+ def apply_uv(f_prev, l_prev, f_next):
+ l_a = [None, None, None, None]
+ l_b = [None, None, None, None]
+
+ l_a[0] = l_prev
+ l_a[1] = l_a[0].link_loop_next
+ l_a[2] = l_a[1].link_loop_next
+ l_a[3] = l_a[2].link_loop_next
+
+ # l_b
+ # +-----------+
+ # |(3) |(2)
+ # | |
+ # |l_next(0) |(1)
+ # +-----------+
+ # ^
+ # l_a |
+ # +-----------+
+ # |l_prev(0) |(1)
+ # | (f) |
+ # |(3) |(2)
+ # +-----------+
+ # copy from this face to the one above.
+
+ # get the other loops
+ l_next = l_prev.link_loop_radial_next
+ if l_next.vert != l_prev.vert:
+ l_b[1] = l_next
+ l_b[0] = l_b[1].link_loop_next
+ l_b[3] = l_b[0].link_loop_next
+ l_b[2] = l_b[3].link_loop_next
+ else:
+ l_b[0] = l_next
+ l_b[1] = l_b[0].link_loop_next
+ l_b[2] = l_b[1].link_loop_next
+ l_b[3] = l_b[2].link_loop_next
- # Set the target UV's touching source face, no tricky calculations needed,
- uvs_vhash_target[edgepair_inner_target[0]][:] = uvs_vhash_source[edgepair_inner_source[iA]]
- uvs_vhash_target[edgepair_inner_target[1]][:] = uvs_vhash_source[edgepair_inner_source[iB]]
+ l_a_uv = [l[uv_act].uv for l in l_a]
+ l_b_uv = [l[uv_act].uv for l in l_b]
- # Set the 2 UV's on the target face that are not touching
- # for this we need to do basic expanding on the source faces UV's
if EXTEND_MODE == 'LENGTH':
+ a0, b0, c0 = l_a[3].vert.co, l_a[0].vert.co, l_b[3].vert.co
+ a1, b1, c1 = l_a[2].vert.co, l_a[1].vert.co, l_b[2].vert.co
- try: # divide by zero is possible
- '''
- measure the length of each face from the middle of each edge to the opposite
- along the axis we are copying, use this
- '''
- i1a = edgepair_outer_target[iB]
- i2a = edgepair_inner_target[iA]
- if i1a > i2a:
- i1a, i2a = i2a, i1a
-
- i1b = edgepair_outer_source[iB]
- i2b = edgepair_inner_source[iA]
- if i1b > i2b:
- i1b, i2b = i2b, i1b
- # print edge_average_lengths
- factor = edge_average_lengths[i1a, i2a][0] / edge_average_lengths[i1b, i2b][0]
- except:
- # Div By Zero?
- factor = 1.0
-
- uvs_vhash_target[edgepair_outer_target[iB]][:] = uvs_vhash_source[edgepair_inner_source[0]] + factor * (uvs_vhash_source[edgepair_inner_source[0]] - uvs_vhash_source[edgepair_outer_source[1]])
- uvs_vhash_target[edgepair_outer_target[iA]][:] = uvs_vhash_source[edgepair_inner_source[1]] + factor * (uvs_vhash_source[edgepair_inner_source[1]] - uvs_vhash_source[edgepair_outer_source[0]])
-
+ d1 = (a0 - b0).length + (a1 - b1).length
+ d2 = (b0 - c0).length + (b1 - c1).length
+ try:
+ fac = d2 / d1
+ except ZeroDivisionError:
+ fac = 1.0
else:
- # same as above but with no factors
- uvs_vhash_target[edgepair_outer_target[iB]][:] = uvs_vhash_source[edgepair_inner_source[0]] + (uvs_vhash_source[edgepair_inner_source[0]] - uvs_vhash_source[edgepair_outer_source[1]])
- uvs_vhash_target[edgepair_outer_target[iA]][:] = uvs_vhash_source[edgepair_inner_source[1]] + (uvs_vhash_source[edgepair_inner_source[1]] - uvs_vhash_source[edgepair_outer_source[0]])
+ fac = 1.0
- face_act = me.polygons.active
- if face_act == -1:
- operator.report({'ERROR'}, "No active face")
- return
+ extrapolate_uv(fac,
+ l_a_uv[3], l_a_uv[0],
+ l_b_uv[3], l_b_uv[0])
- face_sel = [f for f in me.polygons if len(f.vertices) == 4 and f.select]
+ extrapolate_uv(fac,
+ l_a_uv[2], l_a_uv[1],
+ l_b_uv[2], l_b_uv[1])
- face_act_local_index = -1
- for i, f in enumerate(face_sel):
- if f.index == face_act:
- face_act_local_index = i
- break
+ for f_triple in walk_face(f_act):
+ apply_uv(*f_triple)
- if face_act_local_index == -1:
- operator.report({'ERROR'}, "Active face not selected")
- return
-
- # Modes
- # 0 not yet searched for.
- # 1:mapped, use search from this face - removed!
- # 2:all siblings have been searched. don't search again.
- face_modes = [0] * len(face_sel)
- face_modes[face_act_local_index] = 1 # extend UV's from this face.
-
- # Edge connectivity
- edge_faces = {}
- for i, f in enumerate(face_sel):
- for edkey in f.edge_keys:
- try:
- edge_faces[edkey].append(i)
- except:
- edge_faces[edkey] = [i]
-
- if EXTEND_MODE == 'LENGTH':
- edge_loops = mesh_utils.edge_loops_from_tessfaces(me, face_sel, [ed.key for ed in me.edges if ed.use_seam])
- me_verts = me.vertices
- for loop in edge_loops:
- looplen = [0.0]
- for ed in loop:
- edge_average_lengths[ed] = looplen
- looplen[0] += (me_verts[ed[0]].co - me_verts[ed[1]].co).length
- looplen[0] = looplen[0] / len(loop)
-
- # remove seams, so we don't map across seams.
- for ed in me.edges:
- if ed.use_seam:
- # remove the edge pair if we can
- try:
- del edge_faces[ed.key]
- except:
- pass
- # Done finding seams
-
- # face connectivity - faces around each face
- # only store a list of indices for each face.
- face_faces = [[] for i in range(len(face_sel))]
-
- for edge_key, faces in edge_faces.items():
- if len(faces) == 2: # Only do edges with 2 face users for now
- face_faces[faces[0]].append((faces[1], edge_key))
- face_faces[faces[1]].append((faces[0], edge_key))
-
- # Now we know what face is connected to what other face, map them by connectivity
- ok = True
- while ok:
- ok = False
- for i in range(len(face_sel)):
- if face_modes[i] == 1: # searchable
- for f_sibling, edge_key in face_faces[i]:
- if face_modes[f_sibling] == 0:
- face_modes[f_sibling] = 1 # mapped and search from.
- extend_uvs(face_sel[i], face_sel[f_sibling], edge_key)
- face_modes[i] = 1 # we can map from this one now.
- ok = True # keep searching
-
- face_modes[i] = 2 # don't search again
-
- if is_editmode:
- bpy.ops.object.mode_set(mode='EDIT')
- else:
- me.update_tag()
+ bmesh.update_edit_mesh(me, False)
def main(context, operator):
diff --git a/release/scripts/startup/bl_operators/uvcalc_lightmap.py b/release/scripts/startup/bl_operators/uvcalc_lightmap.py
index 526d78c4c11..198b3660ff8 100644
--- a/release/scripts/startup/bl_operators/uvcalc_lightmap.py
+++ b/release/scripts/startup/bl_operators/uvcalc_lightmap.py
@@ -552,7 +552,7 @@ class LightMapPack(Operator):
# Disable REGISTER flag for now because this operator might create new
# images. This leads to non-proper operator redo because current undo
# stack is local for edit mode and can not remove images created by this
- # oprtator.
+ # operator.
# Proper solution would be to make undo stack aware of such things,
# but for now just disable redo. Keep undo here so unwanted changes to uv
# coords might be undone.
diff --git a/release/scripts/startup/bl_operators/uvcalc_smart_project.py b/release/scripts/startup/bl_operators/uvcalc_smart_project.py
index eb05057de3d..160ca5c6977 100644
--- a/release/scripts/startup/bl_operators/uvcalc_smart_project.py
+++ b/release/scripts/startup/bl_operators/uvcalc_smart_project.py
@@ -23,7 +23,7 @@ import bpy
from bpy.types import Operator
DEG_TO_RAD = 0.017453292519943295 # pi/180.0
-SMALL_NUM = 0.000000001
+SMALL_NUM = 0.0000001 # see bug [#31598] why we dont have smaller values
BIG_NUM = 1e15
global USER_FILL_HOLES
@@ -759,7 +759,7 @@ class thickface(object):
self.v = [mesh_verts[i] for i in face.vertices]
self.uv = [uv_layer[i].uv for i in face.loop_indices]
- self.no = face.normal
+ self.no = face.normal.copy()
self.area = face.area
self.edge_keys = face.edge_keys
@@ -993,7 +993,7 @@ def main(context,
if mostUniqueAngle < USER_PROJECTION_LIMIT_CONVERTED:
#print 'adding', mostUniqueAngle, USER_PROJECTION_LIMIT, len(newProjectMeshFaces)
# Now weight the vector to all its faces, will give a more direct projection
- # if the face its self was not representive of the normal from surrounding faces.
+ # if the face its self was not representative of the normal from surrounding faces.
newProjectVec = tempMeshFaces[mostUniqueIndex].no
newProjectMeshFaces = [tempMeshFaces.pop(mostUniqueIndex)]
diff --git a/release/scripts/startup/bl_ui/properties_particle.py b/release/scripts/startup/bl_ui/properties_particle.py
index 6fcd56fb99e..3f672d2a977 100644
--- a/release/scripts/startup/bl_ui/properties_particle.py
+++ b/release/scripts/startup/bl_ui/properties_particle.py
@@ -148,7 +148,7 @@ class PARTICLE_PT_context_particles(ParticleButtonsPanel, Panel):
#row.label(text="Render")
if part.is_fluid:
- layout.label(text="{} fluid particles for this frame".format(str(part.count)))
+ layout.label(text="%d fluid particles for this frame" % part.count)
return
row = col.row()
diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py
index 0bb25e98456..f6eaf421a7a 100644
--- a/release/scripts/startup/bl_ui/space_userpref.py
+++ b/release/scripts/startup/bl_ui/space_userpref.py
@@ -437,7 +437,6 @@ class USERPREF_PT_system(Panel):
col.label(text="OpenGL:")
col.prop(system, "gl_clip_alpha", slider=True)
col.prop(system, "use_mipmaps")
- col.prop(system, "use_gpu_mipmap")
col.prop(system, "use_16bit_textures")
col.label(text="Anisotropic Filtering")
col.prop(system, "anisotropic_filter", text="")
diff --git a/release/scripts/templates/bmesh_simple_editmode.py b/release/scripts/templates/bmesh_simple_editmode.py
new file mode 100644
index 00000000000..d79ba02c2cb
--- /dev/null
+++ b/release/scripts/templates/bmesh_simple_editmode.py
@@ -0,0 +1,23 @@
+# This example assumes we have a mesh object in edit-mode
+
+import bpy
+import bmesh
+
+# Get the active mesh
+obj = bpy.context.edit_object
+me = obj.data
+
+
+# Get a BMesh representation
+bm = bmesh.from_edit_mesh(me)
+
+bm.faces.active = None
+
+# Modify the BMesh, can do anything here...
+for v in bm.verts:
+ v.co.x += 1.0
+
+
+# Show the updates in the viewport
+# and recalculate n-gon tessellation.
+bmesh.update_edit_mesh(me, True)
diff --git a/release/scripts/templates/script_stub.py b/release/scripts/templates/script_stub.py
index 143c7c5104a..44c7b802e2c 100644
--- a/release/scripts/templates/script_stub.py
+++ b/release/scripts/templates/script_stub.py
@@ -9,4 +9,6 @@ filename = "my_script.py"
filepath = os.path.join(os.path.dirname(bpy.data.filepath), filename)
global_namespace = {"__file__": filepath, "__name__": "__main__"}
-exec(compile(open(filepath).read(), filepath, 'exec'), global_namespace)
+file = open(filepath, 'rb')
+exec(compile(file.read(), filepath, 'exec'), global_namespace)
+file.close()
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h
index c6c54cc6e8a..617c4cd2bc8 100644
--- a/source/blender/blenkernel/BKE_DerivedMesh.h
+++ b/source/blender/blenkernel/BKE_DerivedMesh.h
@@ -709,10 +709,16 @@ void DM_debug_print(DerivedMesh *dm);
void DM_debug_print_cdlayers(CustomData *cdata);
#endif
+#ifdef __GNUC__
+BLI_INLINE int DM_origindex_mface_mpoly(const int *index_mf_to_mpoly, const int *index_mp_to_orig, const int i)
+ __attribute__((nonnull(1)))
+;
+#endif
+
BLI_INLINE int DM_origindex_mface_mpoly(const int *index_mf_to_mpoly, const int *index_mp_to_orig, const int i)
{
const int j = index_mf_to_mpoly[i];
- return (j != ORIGINDEX_NONE) ? index_mp_to_orig[j] : ORIGINDEX_NONE;
+ return (j != ORIGINDEX_NONE) ? (index_mp_to_orig ? index_mp_to_orig[j] : j) : ORIGINDEX_NONE;
}
#endif
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 65610b5c989..515bb37b249 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -34,8 +34,6 @@
#include "DNA_listBase.h"
-#include "RNA_types.h"
-
/* not very important, but the stack solver likes to know a maximum */
#define MAX_SOCKET 64
@@ -82,7 +80,7 @@ typedef struct bNodeSocketTemplate {
char name[64]; /* MAX_NAME */
float val1, val2, val3, val4; /* default alloc value for inputs */
float min, max;
- PropertySubType subtype;
+ int subtype; /* would use PropertySubType but this is a bad level include to use RNA */
int flag;
/* after this line is used internal only */
diff --git a/source/blender/blenkernel/SConscript b/source/blender/blenkernel/SConscript
index 1f04f4adba3..dc1c9b5a1a2 100644
--- a/source/blender/blenkernel/SConscript
+++ b/source/blender/blenkernel/SConscript
@@ -41,11 +41,12 @@ if env['WITH_BF_PYTHON']:
if env['BF_DEBUG']:
defs.append('DEBUG')
+'''
if env['WITH_BF_ELTOPO']:
incs += ' #/extern/eltopo'
incs += ' #/extern/eltopo/eltopo3d'
defs.append('WITH_ELTOPO')
-
+'''
if env['WITH_BF_QUICKTIME']:
incs += ' ../quicktime'
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index 40cd5b3d403..03698736459 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -268,7 +268,7 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath
G.winpos = bfd->winpos;
G.displaymode = bfd->displaymode;
G.fileflags = bfd->fileflags;
- CTX_wm_manager_set(C, bfd->main->wm.first);
+ CTX_wm_manager_set(C, G.main->wm.first);
CTX_wm_screen_set(C, bfd->curscreen);
CTX_data_scene_set(C, bfd->curscreen->scene);
CTX_wm_area_set(C, NULL);
@@ -278,7 +278,11 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath
/* this can happen when active scene was lib-linked, and doesn't exist anymore */
if (CTX_data_scene(C) == NULL) {
- CTX_data_scene_set(C, bfd->main->scene.first);
+ /* in case we don't even have a local scene, add one */
+ if(!G.main->scene.first)
+ BKE_scene_add("Scene");
+
+ CTX_data_scene_set(C, G.main->scene.first);
CTX_wm_screen(C)->scene = CTX_data_scene(C);
curscene = CTX_data_scene(C);
}
diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c
index 9118baeae6f..57c88919021 100644
--- a/source/blender/blenkernel/intern/camera.c
+++ b/source/blender/blenkernel/intern/camera.c
@@ -267,6 +267,7 @@ void BKE_camera_params_from_view3d(CameraParams *params, View3D *v3d, RegionView
params->clipsta = -params->clipend;
params->is_ortho = TRUE;
+ /* make sure any changes to this match ED_view3d_radius_to_ortho_dist() */
params->ortho_scale = rv3d->dist * sensor_size / v3d->lens;
params->zoom = 2.0f;
}
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index 9b1720787ed..54f69a49e70 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -623,8 +623,8 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm,
/* double lookup */
const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX);
- if ((index_mf_to_mpoly && index_mp_to_orig) == FALSE) {
- index_mf_to_mpoly = index_mp_to_orig = NULL;
+ if (index_mf_to_mpoly == NULL) {
+ index_mp_to_orig = NULL;
}
colType = CD_TEXTURE_MCOL;
@@ -812,8 +812,8 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm,
/* double lookup */
const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX);
- if ((index_mf_to_mpoly && index_mp_to_orig) == FALSE) {
- index_mf_to_mpoly = index_mp_to_orig = NULL;
+ if (index_mf_to_mpoly == NULL) {
+ index_mp_to_orig = NULL;
}
@@ -1048,8 +1048,8 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm,
/* double lookup */
const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX);
- if ((index_mf_to_mpoly && index_mp_to_orig) == FALSE) {
- index_mf_to_mpoly = index_mp_to_orig = NULL;
+ if (index_mf_to_mpoly == NULL) {
+ index_mp_to_orig = NULL;
}
cdDM_update_normals_from_pbvh(dm);
@@ -1349,8 +1349,8 @@ static void cdDM_drawMappedFacesMat(DerivedMesh *dm,
/* double lookup */
const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX);
- if ((index_mf_to_mpoly && index_mp_to_orig) == FALSE) {
- index_mf_to_mpoly = index_mp_to_orig = NULL;
+ if (index_mf_to_mpoly == NULL) {
+ index_mp_to_orig = NULL;
}
cdDM_update_normals_from_pbvh(dm);
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c
index a78a9af54ae..083cb02fd3d 100644
--- a/source/blender/blenkernel/intern/displist.c
+++ b/source/blender/blenkernel/intern/displist.c
@@ -487,7 +487,7 @@ void BKE_displist_fill(ListBase *dispbase, ListBase *to, int flipnormal)
}
/* XXX (obedit && obedit->actcol)?(obedit->actcol-1):0)) { */
- if (totvert && (tot = BLI_scanfill_calc(&sf_ctx, FALSE))) {
+ if (totvert && (tot = BLI_scanfill_calc(&sf_ctx, BLI_SCANFILL_CALC_REMOVE_DOUBLES))) {
if (tot) {
dlnew = MEM_callocN(sizeof(DispList), "filldisplist");
dlnew->type = DL_INDEX3;
diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c
index 8d430eb58b5..321a61ce238 100644
--- a/source/blender/blenkernel/intern/editderivedmesh.c
+++ b/source/blender/blenkernel/intern/editderivedmesh.c
@@ -215,7 +215,7 @@ static void BMEdit_RecalcTessellation_intern(BMEditMesh *tm)
/* complete the loop */
BLI_scanfill_edge_add(&sf_ctx, sf_vert_first, sf_vert);
- totfilltri = BLI_scanfill_calc_ex(&sf_ctx, FALSE, efa->no);
+ totfilltri = BLI_scanfill_calc_ex(&sf_ctx, 0, efa->no);
BLI_array_grow_items(looptris, totfilltri);
for (sf_tri = sf_ctx.fillfacebase.first; sf_tri; sf_tri = sf_tri->next) {
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index e4b9edacc7e..f09f128e874 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -663,6 +663,13 @@ static ImBuf *add_ibuf_size(unsigned int width, unsigned int height, const char
BKE_image_buf_fill_color(rect, rect_float, width, height, color);
}
+ if (rect_float) {
+ /* both byte and float buffers are filling in sRGB space, need to linearize float buffer after BKE_image_buf_fill* functions */
+
+ IMB_buffer_float_from_float(rect_float, rect_float, ibuf->channels, IB_PROFILE_LINEAR_RGB, IB_PROFILE_SRGB,
+ ibuf->flags & IB_cm_predivide, ibuf->x, ibuf->y, ibuf->x, ibuf->x);
+ }
+
return ibuf;
}
diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c
index b7f4c4bd61e..bda924060d5 100644
--- a/source/blender/blenkernel/intern/mask.c
+++ b/source/blender/blenkernel/intern/mask.c
@@ -1416,7 +1416,7 @@ void BKE_mask_layer_evaluate(MaskLayer *masklay, const float ctime, const int do
for (spline = masklay->splines.first; spline; spline = spline->next) {
int i;
- int has_auto = FALSE;
+ int need_handle_recalc = FALSE;
BKE_mask_spline_ensure_deform(spline);
@@ -1436,16 +1436,16 @@ void BKE_mask_layer_evaluate(MaskLayer *masklay, const float ctime, const int do
add_v2_v2(point_deform->bezt.vec[2], delta);
}
- if (point->bezt.h1 == HD_AUTO) {
- has_auto = TRUE;
+ if (ELEM(point->bezt.h1, HD_AUTO, HD_VECT)) {
+ need_handle_recalc = TRUE;
}
}
- /* if the spline has auto handles, these need to be recalculated after deformation */
- if (has_auto) {
+ /* if the spline has auto or vector handles, these need to be recalculated after deformation */
+ if (need_handle_recalc) {
for (i = 0; i < spline->tot_point; i++) {
MaskSplinePoint *point_deform = &spline->points_deform[i];
- if (point_deform->bezt.h1 == HD_AUTO) {
+ if (ELEM(point_deform->bezt.h1, HD_AUTO, HD_VECT)) {
BKE_mask_calc_handle_point(spline, point_deform);
}
}
diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c
index 88393fab79c..2fa928e7c07 100644
--- a/source/blender/blenkernel/intern/mask_rasterize.c
+++ b/source/blender/blenkernel/intern/mask_rasterize.c
@@ -933,7 +933,7 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
}
/* main scan-fill */
- sf_tri_tot = BLI_scanfill_calc_ex(&sf_ctx, FALSE, zvec);
+ sf_tri_tot = BLI_scanfill_calc_ex(&sf_ctx, 0, zvec);
face_array = MEM_mallocN(sizeof(*face_array) * (sf_tri_tot + tot_feather_quads), "maskrast_face_index");
face_index = 0;
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index fd5af6a20bb..036f8f5e673 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -2607,7 +2607,7 @@ int BKE_mesh_recalc_tessellation(CustomData *fdata,
}
BLI_scanfill_edge_add(&sf_ctx, sf_vert_last, sf_vert_first);
- totfilltri = BLI_scanfill_calc(&sf_ctx, FALSE);
+ totfilltri = BLI_scanfill_calc(&sf_ctx, 0);
if (totfilltri) {
BLI_array_grow_items(mface_to_poly_map, totfilltri);
BLI_array_grow_items(mface, totfilltri);
diff --git a/source/blender/blenkernel/intern/modifiers_bmesh.c b/source/blender/blenkernel/intern/modifiers_bmesh.c
index 98eac9b95af..381e4350391 100644
--- a/source/blender/blenkernel/intern/modifiers_bmesh.c
+++ b/source/blender/blenkernel/intern/modifiers_bmesh.c
@@ -79,7 +79,7 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm)
/*do verts*/
mv = mvert = dm->dupVertArray(dm);
for (i = 0; i < totvert; i++, mv++) {
- v = BM_vert_create(bm, mv->co, NULL);
+ v = BM_vert_create(bm, mv->co, NULL, BM_CREATE_SKIP_CD);
normal_short_to_float_v3(v->no, mv->no);
v->head.hflag = BM_vert_flag_from_mflag(mv->flag);
BM_elem_index_set(v, i); /* set_inline */
@@ -97,7 +97,7 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm)
me = medge = dm->dupEdgeArray(dm);
for (i = 0; i < totedge; i++, me++) {
//BLI_assert(BM_edge_exists(vtable[me->v1], vtable[me->v2]) == NULL);
- e = BM_edge_create(bm, vtable[me->v1], vtable[me->v2], NULL, FALSE);
+ e = BM_edge_create(bm, vtable[me->v1], vtable[me->v2], NULL, BM_CREATE_SKIP_CD);
e->head.hflag = BM_edge_flag_from_mflag(me->flag);
BM_elem_index_set(e, i); /* set_inline */
@@ -134,7 +134,7 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm)
edges[j] = etable[ml->e];
}
- f = BM_face_create_ngon(bm, verts[0], verts[1], edges, mp->totloop, FALSE);
+ f = BM_face_create_ngon(bm, verts[0], verts[1], edges, mp->totloop, BM_CREATE_SKIP_CD);
if (UNLIKELY(f == NULL)) {
continue;
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index 06b846a6df9..70867a45fd7 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -406,13 +406,14 @@ bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node)
/* only shader nodes get pleasant preview updating this way, compo uses own system */
if (node->preview) {
- if (ntree->type == NTREE_SHADER) {
+ if (ntree && (ntree->type == NTREE_SHADER)) {
nnode->preview = MEM_dupallocN(node->preview);
if (node->preview->rect)
nnode->preview->rect = MEM_dupallocN(node->preview->rect);
}
- else
+ else {
nnode->preview = NULL;
+ }
}
if (ntree)
@@ -2153,8 +2154,6 @@ static void registerCompositNodes(bNodeTreeType *ttype)
register_node_type_reroute(ttype);
register_node_type_cmp_group(ttype);
-// register_node_type_cmp_forloop(ttype);
-// register_node_type_cmp_whileloop(ttype);
register_node_type_cmp_rlayers(ttype);
register_node_type_cmp_image(ttype);
@@ -2255,8 +2254,6 @@ static void registerShaderNodes(bNodeTreeType *ttype)
register_node_type_reroute(ttype);
register_node_type_sh_group(ttype);
- //register_node_type_sh_forloop(ttype);
- //register_node_type_sh_whileloop(ttype);
register_node_type_sh_output(ttype);
register_node_type_sh_material(ttype);
@@ -2337,8 +2334,6 @@ static void registerTextureNodes(bNodeTreeType *ttype)
register_node_type_reroute(ttype);
register_node_type_tex_group(ttype);
-// register_node_type_tex_forloop(ttype);
-// register_node_type_tex_whileloop(ttype);
register_node_type_tex_math(ttype);
register_node_type_tex_mix_rgb(ttype);
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 93bf5a5c0b4..5f5a713064d 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -822,8 +822,8 @@ int psys_render_simplify_distribution(ParticleThreadContext *ctx, int tot)
index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX);
- if ((index_mf_to_mpoly && index_mp_to_orig) == FALSE) {
- index_mf_to_mpoly = index_mp_to_orig = NULL;
+ if (index_mf_to_mpoly == NULL) {
+ index_mp_to_orig = NULL;
}
facearea = MEM_callocN(sizeof(float) * totorigface, "SimplifyFaceArea");
@@ -1645,8 +1645,8 @@ int psys_particle_dm_face_lookup(Object *ob, DerivedMesh *dm, int index, const f
/* double lookup */
const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX);
- if ((index_mf_to_mpoly && index_mp_to_orig) == FALSE) {
- index_mf_to_mpoly = index_mp_to_orig = NULL;
+ if (index_mf_to_mpoly == NULL) {
+ index_mp_to_orig = NULL;
}
mpoly = dm->getPolyArray(dm);
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index 3f2eb32f61c..965a1e2b4a6 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -686,7 +686,7 @@ static int ptcache_smoke_read(PTCacheFile *pf, void *smoke_v)
/* reallocate fluid if needed*/
if (reallocate) {
- sds->active_fields = active_fields;
+ sds->active_fields = active_fields | cache_fields;
smoke_reallocate_fluid(sds, ch_dx, ch_res, 1);
sds->dx = ch_dx;
VECCOPY(sds->res, ch_res);
@@ -755,6 +755,7 @@ static int ptcache_smoke_read(PTCacheFile *pf, void *smoke_v)
if (cache_fields & SM_ACTIVE_FIRE) {
ptcache_file_compressed_read(pf, (unsigned char *)flame, out_len_big);
ptcache_file_compressed_read(pf, (unsigned char *)fuel, out_len_big);
+ ptcache_file_compressed_read(pf, (unsigned char *)react, out_len_big);
}
if (cache_fields & SM_ACTIVE_COLORS) {
ptcache_file_compressed_read(pf, (unsigned char *)r, out_len_big);
diff --git a/source/blender/blenkernel/intern/seqmodifier.c b/source/blender/blenkernel/intern/seqmodifier.c
index 609724e802f..5b2e9f2bf23 100644
--- a/source/blender/blenkernel/intern/seqmodifier.c
+++ b/source/blender/blenkernel/intern/seqmodifier.c
@@ -427,17 +427,17 @@ static void brightcontrast_apply_threaded(int width, int height, unsigned char *
unsigned char *pixel = rect + pixel_index;
for (c = 0; c < 3; c++) {
- i = pixel[c];
+ i = (float) pixel[c] / 255.0f;
v = a * i + b;
if (mask_rect) {
unsigned char *m = mask_rect + pixel_index;
float t = (float) m[c] / 255.0f;
- pixel[c] = pixel[c] * (1.0f - t) + v * t;
+ v = (float) pixel[c] * (1.0f - t) + v * t;
}
- else
- pixel[c] = v;
+
+ pixel[c] = FTOCHAR(v);
}
}
else if (rect_float) {
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index e023a3e20ae..acce3740c98 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -1835,6 +1835,8 @@ static ImBuf *input_preprocess(SeqRenderData context, Sequence *seq, float cfra,
StripCrop c = {0};
StripTransform t = {0};
int sx, sy, dx, dy;
+ double xscale = 1.0;
+ double yscale = 1.0;
if (is_proxy_image) {
double f = seq_rendersize_to_scale_factor(context.preview_render_size);
@@ -1851,6 +1853,17 @@ static ImBuf *input_preprocess(SeqRenderData context, Sequence *seq, float cfra,
t = *seq->strip->transform;
}
+ xscale = context.scene->r.xsch ? ((double)context.rectx / (double)context.scene->r.xsch) : 1.0;
+ yscale = context.scene->r.ysch ? ((double)context.recty / (double)context.scene->r.ysch) : 1.0;
+
+ xscale /= (double)context.rectx / (double)ibuf->x;
+ yscale /= (double)context.recty / (double)ibuf->y;
+
+ c.left *= xscale; c.right *= xscale;
+ c.top *= yscale; c.bottom *= yscale;
+
+ t.xofs *= xscale; t.yofs *= yscale;
+
sx = ibuf->x - c.left - c.right;
sy = ibuf->y - c.top - c.bottom;
dx = sx;
@@ -2343,7 +2356,7 @@ static ImBuf *seq_render_scene_strip(SeqRenderData context, Sequence *seq, float
0 /* (context.scene->r.seq_flag & R_SEQ_GL_REND) */ :
(context.scene->r.seq_flag & R_SEQ_GL_PREV);
int do_seq;
- int have_seq = FALSE;
+ // int have_seq = FALSE; /* UNUSED */
int have_comp = FALSE;
Scene *scene;
int is_thread_main = BLI_thread_is_main();
@@ -2356,7 +2369,7 @@ static ImBuf *seq_render_scene_strip(SeqRenderData context, Sequence *seq, float
scene = seq->scene;
frame = scene->r.sfra + nr + seq->anim_startofs;
- have_seq = (scene->r.scemode & R_DOSEQ) && scene->ed && scene->ed->seqbase.first;
+ // have_seq = (scene->r.scemode & R_DOSEQ) && scene->ed && scene->ed->seqbase.first; /* UNUSED */
have_comp = (scene->r.scemode & R_DOCOMP) && scene->use_nodes && scene->nodetree;
oldcfra = scene->r.cfra;
diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c
index d96bece2b11..53dfbdcfb85 100644
--- a/source/blender/blenkernel/intern/smoke.c
+++ b/source/blender/blenkernel/intern/smoke.c
@@ -165,7 +165,7 @@ void flame_get_spectrum(unsigned char *UNUSED(spec), int UNUSED(width), float UN
void smoke_reallocate_fluid(SmokeDomainSettings *sds, float dx, int res[3], int free_old)
{
int use_heat = (sds->active_fields & SM_ACTIVE_HEAT);
- int use_fire = (sds->active_fields & (SM_ACTIVE_HEAT | SM_ACTIVE_FIRE));
+ int use_fire = (sds->active_fields & SM_ACTIVE_FIRE);
int use_colors = (sds->active_fields & SM_ACTIVE_COLORS);
if (free_old && sds->fluid)
diff --git a/source/blender/blenlib/BLI_array.h b/source/blender/blenlib/BLI_array.h
index 84cfe89f1b8..a21778307c1 100644
--- a/source/blender/blenlib/BLI_array.h
+++ b/source/blender/blenlib/BLI_array.h
@@ -77,11 +77,13 @@
MEM_allocN_len(arr) / sizeof(*arr) \
)
+#define _bli_array_totalsize_static(arr) \
+ (sizeof(_##arr##_static) / sizeof(*arr))
#define BLI_array_totalsize(arr) ( \
(size_t) \
(((void *)(arr) == (void *)_##arr##_static && (void *)(arr) != NULL) ? \
- (sizeof(_##arr##_static) / sizeof(*arr)) : \
+ _bli_array_totalsize_static(arr) : \
BLI_array_totalsize_dyn(arr)) \
)
@@ -93,8 +95,18 @@
*
* Allow for a large 'num' value when the new size is more then double
* to allocate the exact sized array. */
-#define _bli_array_grow_items(arr, num) ( \
- (BLI_array_totalsize(arr) >= _##arr##_count + num) ? \
+
+/* grow an array by a specified number of items */
+#define BLI_array_grow_items(arr, num) ( \
+ (((void *)(arr) == NULL) && \
+ ((void *)(_##arr##_static) != NULL) && \
+ /* dont add _##arr##_count below because it must be zero */ \
+ (_bli_array_totalsize_static(arr) >= _##arr##_count + num)) ? \
+ /* we have an empty array and a static var big enough */ \
+ ((arr = (void *)_##arr##_static), (_##arr##_count += (num))) \
+ : \
+ /* use existing static array or allocate */ \
+ ((BLI_array_totalsize(arr) >= _##arr##_count + num) ? \
(_##arr##_count += num) : \
( \
(void) (_##arr##_tmp = MEM_callocN( \
@@ -115,14 +127,7 @@
(void) (arr = _##arr##_tmp \
), \
(_##arr##_count += num) \
- ) \
-)
-
-/* grow an array by a specified number of items */
-#define BLI_array_grow_items(arr, num) ( \
- ((void *)(arr) == NULL && (void *)(_##arr##_static) != NULL) ? \
- ((arr = (void *)_##arr##_static), (_##arr##_count += num)) : \
- _bli_array_grow_items(arr, num) \
+ )) \
)
/* returns length of array */
diff --git a/source/blender/blenlib/BLI_endian_switch.h b/source/blender/blenlib/BLI_endian_switch.h
index 7cb2790525d..f48b1b072c3 100644
--- a/source/blender/blenlib/BLI_endian_switch.h
+++ b/source/blender/blenlib/BLI_endian_switch.h
@@ -29,8 +29,7 @@
#ifdef __GNUC__
# define ATTR_ENDIAN_SWITCH \
- __attribute__((nonnull(1))) \
- __attribute__((pure))
+ __attribute__((nonnull(1)))
#else
# define ATTR_ENDIAN_SWITCH
#endif
diff --git a/source/blender/blenlib/BLI_rect.h b/source/blender/blenlib/BLI_rect.h
index f84820e94f3..f2e26093711 100644
--- a/source/blender/blenlib/BLI_rect.h
+++ b/source/blender/blenlib/BLI_rect.h
@@ -33,6 +33,9 @@
* \ingroup bli
*/
+#include "DNA_vec_types.h"
+#include "BLI_utildefines.h"
+
struct rctf;
struct rcti;
@@ -75,17 +78,6 @@ void BLI_rctf_rcti_copy(struct rctf *dst, const struct rcti *src);
void print_rctf(const char *str, const struct rctf *rect);
void print_rcti(const char *str, const struct rcti *rect);
-/* hrmf, we need to work out this inline stuff */
-#if defined(_MSC_VER)
-# define BLI_INLINE static __forceinline
-#elif defined(__GNUC__)
-# define BLI_INLINE static inline __attribute((always_inline))
-#else
-/* #warning "MSC/GNUC defines not found, inline non-functional" */
-# define BLI_INLINE static
-#endif
-
-#include "DNA_vec_types.h"
BLI_INLINE float BLI_rcti_cent_x_fl(const struct rcti *rct) { return (float)(rct->xmin + rct->xmax) / 2.0f; }
BLI_INLINE float BLI_rcti_cent_y_fl(const struct rcti *rct) { return (float)(rct->ymin + rct->ymax) / 2.0f; }
BLI_INLINE int BLI_rcti_cent_x(const struct rcti *rct) { return (rct->xmin + rct->xmax) / 2; }
diff --git a/source/blender/blenlib/BLI_scanfill.h b/source/blender/blenlib/BLI_scanfill.h
index 892afdd0b27..c8fd72bbbd2 100644
--- a/source/blender/blenlib/BLI_scanfill.h
+++ b/source/blender/blenlib/BLI_scanfill.h
@@ -94,9 +94,18 @@ typedef struct ScanFillFace {
struct ScanFillVert *BLI_scanfill_vert_add(ScanFillContext *sf_ctx, const float vec[3]);
struct ScanFillEdge *BLI_scanfill_edge_add(ScanFillContext *sf_ctx, struct ScanFillVert *v1, struct ScanFillVert *v2);
+enum {
+ BLI_SCANFILL_CALC_QUADTRI_FASTPATH = (1 << 0),
+
+ /* note: using BLI_SCANFILL_CALC_REMOVE_DOUBLES
+ * Assumes ordered edges, otherwise we risk an eternal loop
+ * removing double verts. - campbell */
+ BLI_SCANFILL_CALC_REMOVE_DOUBLES = (1 << 1),
+};
+
int BLI_scanfill_begin(ScanFillContext *sf_ctx);
-int BLI_scanfill_calc(ScanFillContext *sf_ctx, const short do_quad_tri_speedup);
-int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const short do_quad_tri_speedup,
+int BLI_scanfill_calc(ScanFillContext *sf_ctx, const int flag);
+int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag,
const float nor_proj[3]);
void BLI_scanfill_end(ScanFillContext *sf_ctx);
diff --git a/source/blender/blenlib/BLI_utildefines.h b/source/blender/blenlib/BLI_utildefines.h
index a22aa0c13d7..7c3b70545d6 100644
--- a/source/blender/blenlib/BLI_utildefines.h
+++ b/source/blender/blenlib/BLI_utildefines.h
@@ -324,11 +324,13 @@
/*little macro so inline keyword works*/
#if defined(_MSC_VER)
# define BLI_INLINE static __forceinline
-#elif defined(__GNUC__)
-# define BLI_INLINE static inline __attribute((always_inline))
#else
-/* #warning "MSC/GNUC defines not found, inline non-functional" */
-# define BLI_INLINE static
+# if (defined(__APPLE__) && defined(__ppc__))
+/* static inline __attribute__ here breaks osx ppc gcc42 build */
+# define BLI_INLINE static __attribute__((always_inline))
+# else
+# define BLI_INLINE static inline __attribute__((always_inline))
+# endif
#endif
diff --git a/source/blender/blenlib/intern/bpath.c b/source/blender/blenlib/intern/bpath.c
index d725a0a9417..8b63a94951d 100644
--- a/source/blender/blenlib/intern/bpath.c
+++ b/source/blender/blenlib/intern/bpath.c
@@ -64,6 +64,8 @@
#include "DNA_sequence_types.h"
#include "DNA_sound_types.h"
#include "DNA_text_types.h"
+#include "DNA_material_types.h"
+#include "DNA_node_types.h"
#include "DNA_texture_types.h"
#include "DNA_vfont_types.h"
#include "DNA_scene_types.h"
@@ -77,6 +79,7 @@
#include "BKE_font.h"
#include "BKE_library.h"
#include "BKE_main.h"
+#include "BKE_node.h"
#include "BKE_report.h"
#include "BKE_sequencer.h"
#include "BKE_image.h" /* so we can check the image's type */
@@ -383,7 +386,6 @@ static int rewrite_path_alloc(char **path, BPathVisitor visit_cb, const char *ab
/* Run visitor function 'visit' on all paths contained in 'id'. */
void BLI_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int flag, void *bpath_user_data)
{
- Image *ima;
const char *absbase = (flag & BLI_BPATH_TRAVERSE_ABS) ? ID_BLEND_PATH(bmain, id) : NULL;
if ((flag & BLI_BPATH_TRAVERSE_SKIP_LIBRARY) && id->lib) {
@@ -392,6 +394,8 @@ void BLI_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int
switch (GS(id->name)) {
case ID_IM:
+ {
+ Image *ima;
ima = (Image *)id;
if (ima->packedfile == NULL || (flag & BLI_BPATH_TRAVERSE_SKIP_PACKED) == 0) {
if (ELEM3(ima->source, IMA_SRC_FILE, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) {
@@ -399,15 +403,20 @@ void BLI_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int
}
}
break;
+ }
case ID_BR:
{
Brush *brush = (Brush *)id;
if (brush->icon_filepath[0]) {
rewrite_path_fixed(brush->icon_filepath, visit_cb, absbase, bpath_user_data);
}
+ break;
}
- break;
case ID_OB:
+ {
+ Object *ob = (Object *)id;
+ ModifierData *md;
+ ParticleSystem *psys;
#define BPATH_TRAVERSE_POINTCACHE(ptcaches) \
{ \
@@ -422,12 +431,6 @@ void BLI_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int
} \
} (void)0
-
- {
- Object *ob = (Object *)id;
- ModifierData *md;
- ParticleSystem *psys;
-
/* do via modifiers instead */
#if 0
if (ob->fluidsimSettings) {
@@ -465,19 +468,19 @@ void BLI_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int
for (psys = ob->particlesystem.first; psys; psys = psys->next) {
BPATH_TRAVERSE_POINTCACHE(psys->ptcaches);
}
- }
#undef BPATH_TRAVERSE_POINTCACHE
break;
+ }
case ID_SO:
{
bSound *sound = (bSound *)id;
if (sound->packedfile == NULL || (flag & BLI_BPATH_TRAVERSE_SKIP_PACKED) == 0) {
rewrite_path_fixed(sound->name, visit_cb, absbase, bpath_user_data);
}
+ break;
}
- break;
case ID_TXT:
if (((Text *)id)->name) {
rewrite_path_alloc(&((Text *)id)->name, visit_cb, absbase, bpath_user_data);
@@ -491,17 +494,49 @@ void BLI_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int
rewrite_path_fixed(((VFont *)id)->name, visit_cb, absbase, bpath_user_data);
}
}
+ break;
}
+ case ID_MA:
+ {
+ Material *ma = (Material *)id;
+ bNodeTree *ntree = ma->nodetree;
+
+ if(ntree) {
+ bNode *node;
+
+ for (node = ntree->nodes.first; node; node = node->next) {
+ if (node->type == SH_NODE_SCRIPT) {
+ NodeShaderScript *nss = (NodeShaderScript *)node->storage;
+ rewrite_path_fixed(nss->filepath, visit_cb, absbase, bpath_user_data);
+ }
+ }
+ }
break;
+ }
+ case ID_NT:
+ {
+ bNodeTree *ntree = (bNodeTree *)id;
+ bNode *node;
+
+ if (ntree->type == NTREE_SHADER) {
+ /* same as lines above */
+ for (node = ntree->nodes.first; node; node = node->next) {
+ if (node->type == SH_NODE_SCRIPT) {
+ NodeShaderScript *nss = (NodeShaderScript *)node->storage;
+ rewrite_path_fixed(nss->filepath, visit_cb, absbase, bpath_user_data);
+ }
+ }
+ }
+ break;
+ }
case ID_TE:
{
Tex *tex = (Tex *)id;
if (tex->type == TEX_VOXELDATA && TEX_VD_IS_SOURCE_PATH(tex->vd->file_format)) {
rewrite_path_fixed(tex->vd->source_path, visit_cb, absbase, bpath_user_data);
}
+ break;
}
- break;
-
case ID_SCE:
{
Scene *scene = (Scene *)id;
@@ -547,30 +582,30 @@ void BLI_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int
rewrite_path_fixed(module->module_path, visit_cb, absbase, bpath_user_data);
}
}
+ break;
}
- break;
case ID_ME:
{
Mesh *me = (Mesh *)id;
if (me->ldata.external) {
rewrite_path_fixed(me->ldata.external->filename, visit_cb, absbase, bpath_user_data);
}
+ break;
}
- break;
case ID_LI:
{
Library *lib = (Library *)id;
if (rewrite_path_fixed(lib->name, visit_cb, absbase, bpath_user_data)) {
BKE_library_filepath_set(lib, lib->name);
}
+ break;
}
- break;
case ID_MC:
{
MovieClip *clip = (MovieClip *)id;
rewrite_path_fixed(clip->name, visit_cb, absbase, bpath_user_data);
+ break;
}
- break;
default:
/* Nothing to do for other IDs that don't contain file paths. */
break;
diff --git a/source/blender/blenlib/intern/scanfill.c b/source/blender/blenlib/intern/scanfill.c
index 1b7858f7f88..defe500cb21 100644
--- a/source/blender/blenlib/intern/scanfill.c
+++ b/source/blender/blenlib/intern/scanfill.c
@@ -503,8 +503,7 @@ static void splitlist(ScanFillContext *sf_ctx, ListBase *tempve, ListBase *tempe
}
}
-
-static int scanfill(ScanFillContext *sf_ctx, PolyFill *pf)
+static int scanfill(ScanFillContext *sf_ctx, PolyFill *pf, const int flag)
{
ScanFillVertLink *sc = NULL, *sc1;
ScanFillVert *eve, *v1, *v2, *v3;
@@ -530,26 +529,28 @@ static int scanfill(ScanFillContext *sf_ctx, PolyFill *pf)
#endif
/* STEP 0: remove zero sized edges */
- eed = sf_ctx->filledgebase.first;
- while (eed) {
- if (equals_v2v2(eed->v1->xy, eed->v2->xy)) {
- if (eed->v1->f == SF_VERT_ZERO_LEN && eed->v2->f != SF_VERT_ZERO_LEN) {
- eed->v2->f = SF_VERT_ZERO_LEN;
- eed->v2->tmp.v = eed->v1->tmp.v;
- }
- else if (eed->v2->f == SF_VERT_ZERO_LEN && eed->v1->f != SF_VERT_ZERO_LEN) {
- eed->v1->f = SF_VERT_ZERO_LEN;
- eed->v1->tmp.v = eed->v2->tmp.v;
- }
- else if (eed->v2->f == SF_VERT_ZERO_LEN && eed->v1->f == SF_VERT_ZERO_LEN) {
- eed->v1->tmp.v = eed->v2->tmp.v;
- }
- else {
- eed->v2->f = SF_VERT_ZERO_LEN;
- eed->v2->tmp.v = eed->v1;
+ if (flag & BLI_SCANFILL_CALC_REMOVE_DOUBLES) {
+ eed = sf_ctx->filledgebase.first;
+ while (eed) {
+ if (equals_v2v2(eed->v1->xy, eed->v2->xy)) {
+ if (eed->v1->f == SF_VERT_ZERO_LEN && eed->v2->f != SF_VERT_ZERO_LEN) {
+ eed->v2->f = SF_VERT_ZERO_LEN;
+ eed->v2->tmp.v = eed->v1->tmp.v;
+ }
+ else if (eed->v2->f == SF_VERT_ZERO_LEN && eed->v1->f != SF_VERT_ZERO_LEN) {
+ eed->v1->f = SF_VERT_ZERO_LEN;
+ eed->v1->tmp.v = eed->v2->tmp.v;
+ }
+ else if (eed->v2->f == SF_VERT_ZERO_LEN && eed->v1->f == SF_VERT_ZERO_LEN) {
+ eed->v1->tmp.v = eed->v2->tmp.v;
+ }
+ else {
+ eed->v2->f = SF_VERT_ZERO_LEN;
+ eed->v2->tmp.v = eed->v1;
+ }
}
+ eed = eed->next;
}
- eed = eed->next;
}
/* STEP 1: make using FillVert and FillEdge lists a sorted
@@ -572,28 +573,42 @@ static int scanfill(ScanFillContext *sf_ctx, PolyFill *pf)
qsort(sf_ctx->_scdata, verts, sizeof(ScanFillVertLink), vergscdata);
- eed = sf_ctx->filledgebase.first;
- while (eed) {
- nexted = eed->next;
- BLI_remlink(&sf_ctx->filledgebase, eed);
- /* This code is for handling zero-length edges that get
- * collapsed in step 0. It was removed for some time to
- * fix trunk bug #4544, so if that comes back, this code
- * may need some work, or there will have to be a better
- * fix to #4544. */
- if (eed->v1->f == SF_VERT_ZERO_LEN) {
- v1 = eed->v1;
- while ((eed->v1->f == SF_VERT_ZERO_LEN) && (eed->v1->tmp.v != v1) && (eed->v1 != eed->v1->tmp.v))
- eed->v1 = eed->v1->tmp.v;
+ if (flag & BLI_SCANFILL_CALC_REMOVE_DOUBLES) {
+ for (eed = sf_ctx->filledgebase.first; eed; eed = nexted) {
+ nexted = eed->next;
+ BLI_remlink(&sf_ctx->filledgebase, eed);
+ /* This code is for handling zero-length edges that get
+ * collapsed in step 0. It was removed for some time to
+ * fix trunk bug #4544, so if that comes back, this code
+ * may need some work, or there will have to be a better
+ * fix to #4544.
+ *
+ * warning, this can hang on un-ordered edges, see: [#33281]
+ * for now disable 'BLI_SCANFILL_CALC_REMOVE_DOUBLES' for ngons.
+ */
+ if (eed->v1->f == SF_VERT_ZERO_LEN) {
+ v1 = eed->v1;
+ while ((eed->v1->f == SF_VERT_ZERO_LEN) && (eed->v1->tmp.v != v1) && (eed->v1 != eed->v1->tmp.v))
+ eed->v1 = eed->v1->tmp.v;
+ }
+ if (eed->v2->f == SF_VERT_ZERO_LEN) {
+ v2 = eed->v2;
+ while ((eed->v2->f == SF_VERT_ZERO_LEN) && (eed->v2->tmp.v != v2) && (eed->v2 != eed->v2->tmp.v))
+ eed->v2 = eed->v2->tmp.v;
+ }
+ if (eed->v1 != eed->v2) {
+ addedgetoscanlist(sf_ctx, eed, verts);
+ }
}
- if (eed->v2->f == SF_VERT_ZERO_LEN) {
- v2 = eed->v2;
- while ((eed->v2->f == SF_VERT_ZERO_LEN) && (eed->v2->tmp.v != v2) && (eed->v2 != eed->v2->tmp.v))
- eed->v2 = eed->v2->tmp.v;
+ }
+ else {
+ for (eed = sf_ctx->filledgebase.first; eed; eed = nexted) {
+ nexted = eed->next;
+ BLI_remlink(&sf_ctx->filledgebase, eed);
+ if (eed->v1 != eed->v2) {
+ addedgetoscanlist(sf_ctx, eed, verts);
+ }
}
- if (eed->v1 != eed->v2) addedgetoscanlist(sf_ctx, eed, verts);
-
- eed = nexted;
}
#if 0
sc = scdata;
@@ -775,12 +790,12 @@ int BLI_scanfill_begin(ScanFillContext *sf_ctx)
return 1;
}
-int BLI_scanfill_calc(ScanFillContext *sf_ctx, const short do_quad_tri_speedup)
+int BLI_scanfill_calc(ScanFillContext *sf_ctx, const int flag)
{
- return BLI_scanfill_calc_ex(sf_ctx, do_quad_tri_speedup, NULL);
+ return BLI_scanfill_calc_ex(sf_ctx, flag, NULL);
}
-int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const short do_quad_tri_speedup, const float nor_proj[3])
+int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const float nor_proj[3])
{
/*
* - fill works with its own lists, so create that first (no faces!)
@@ -810,30 +825,32 @@ int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const short do_quad_tri_speedu
a += 1;
}
- if (do_quad_tri_speedup && (a == 3)) {
- eve = sf_ctx->fillvertbase.first;
+ if (flag & BLI_SCANFILL_CALC_QUADTRI_FASTPATH) {
+ if (a == 3) {
+ eve = sf_ctx->fillvertbase.first;
- addfillface(sf_ctx, eve, eve->next, eve->next->next);
- return 1;
- }
- else if (do_quad_tri_speedup && (a == 4)) {
- float vec1[3], vec2[3];
-
- eve = sf_ctx->fillvertbase.first;
- /* no need to check 'eve->next->next->next' is valid, already counted */
- /* use shortest diagonal for quad */
- sub_v3_v3v3(vec1, eve->co, eve->next->next->co);
- sub_v3_v3v3(vec2, eve->next->co, eve->next->next->next->co);
-
- if (dot_v3v3(vec1, vec1) < dot_v3v3(vec2, vec2)) {
addfillface(sf_ctx, eve, eve->next, eve->next->next);
- addfillface(sf_ctx, eve->next->next, eve->next->next->next, eve);
+ return 1;
}
- else {
- addfillface(sf_ctx, eve->next, eve->next->next, eve->next->next->next);
- addfillface(sf_ctx, eve->next->next->next, eve, eve->next);
+ else if (a == 4) {
+ float vec1[3], vec2[3];
+
+ eve = sf_ctx->fillvertbase.first;
+ /* no need to check 'eve->next->next->next' is valid, already counted */
+ /* use shortest diagonal for quad */
+ sub_v3_v3v3(vec1, eve->co, eve->next->next->co);
+ sub_v3_v3v3(vec2, eve->next->co, eve->next->next->next->co);
+
+ if (dot_v3v3(vec1, vec1) < dot_v3v3(vec2, vec2)) {
+ addfillface(sf_ctx, eve, eve->next, eve->next->next);
+ addfillface(sf_ctx, eve->next->next, eve->next->next->next, eve);
+ }
+ else {
+ addfillface(sf_ctx, eve->next, eve->next->next, eve->next->next->next);
+ addfillface(sf_ctx, eve->next->next->next, eve, eve->next);
+ }
+ return 2;
}
- return 2;
}
/* first test vertices if they are in edges */
@@ -1091,7 +1108,7 @@ int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const short do_quad_tri_speedu
for (a = 0; a < poly; a++) {
if (pf->edges > 1) {
splitlist(sf_ctx, &tempve, &temped, pf->nr);
- totfaces += scanfill(sf_ctx, pf);
+ totfaces += scanfill(sf_ctx, pf, flag);
}
pf++;
}
diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c
index 14e0dc2f049..f23f75f69d9 100644
--- a/source/blender/blenlib/intern/string.c
+++ b/source/blender/blenlib/intern/string.c
@@ -85,6 +85,10 @@ size_t BLI_vsnprintf(char *__restrict buffer, size_t count, const char *__restri
{
size_t n;
+ BLI_assert(buffer != NULL);
+ BLI_assert(count > 0);
+ BLI_assert(format != NULL);
+
n = vsnprintf(buffer, count, format, arg);
if (n != -1 && n < count) {
@@ -115,6 +119,8 @@ char *BLI_sprintfN(const char *__restrict format, ...)
va_list arg;
char *n;
+ BLI_assert(format != NULL);
+
va_start(arg, format);
ds = BLI_dynstr_new();
diff --git a/source/blender/blenlib/intern/string_utf8.c b/source/blender/blenlib/intern/string_utf8.c
index 16a5f03095d..bf98f2ae77c 100644
--- a/source/blender/blenlib/intern/string_utf8.c
+++ b/source/blender/blenlib/intern/string_utf8.c
@@ -394,10 +394,10 @@ int BLI_str_utf8_size_safe(const char *p)
/* was g_utf8_get_char */
/**
* BLI_str_utf8_as_unicode:
- * @p a pointer to Unicode character encoded as UTF-8
+ * \param p a pointer to Unicode character encoded as UTF-8
*
* Converts a sequence of bytes encoded as UTF-8 to a Unicode character.
- * If @p does not point to a valid UTF-8 encoded character, results are
+ * If \a p does not point to a valid UTF-8 encoded character, results are
* undefined. If you are not sure that the bytes are complete
* valid Unicode characters, you should use g_utf8_get_char_validated()
* instead.
@@ -536,14 +536,14 @@ size_t BLI_str_utf8_from_unicode(unsigned int c, char *outbuf)
/* was g_utf8_find_prev_char */
/**
* BLI_str_find_prev_char_utf8:
- * @str: pointer to the beginning of a UTF-8 encoded string
- * @p pointer to some position within @str
+ * \param str pointer to the beginning of a UTF-8 encoded string
+ * \param p pointer to some position within \a str
*
- * Given a position @p with a UTF-8 encoded string @str, find the start
- * of the previous UTF-8 character starting before. @p Returns %NULL if no
- * UTF-8 characters are present in @str before @p
+ * Given a position \a p with a UTF-8 encoded string \a str, find the start
+ * of the previous UTF-8 character starting before. \a p Returns %NULL if no
+ * UTF-8 characters are present in \a str before \a p
*
- * @p does not have to be at the beginning of a UTF-8 character. No check
+ * \a p does not have to be at the beginning of a UTF-8 character. No check
* is made to see if the character found is actually valid other than
* it starts with an appropriate byte.
*
@@ -562,13 +562,13 @@ char * BLI_str_find_prev_char_utf8(const char *str, const char *p)
/* was g_utf8_find_next_char */
/**
* BLI_str_find_next_char_utf8:
- * @p a pointer to a position within a UTF-8 encoded string
- * @end a pointer to the byte following the end of the string,
+ * \param p a pointer to a position within a UTF-8 encoded string
+ * \param end a pointer to the byte following the end of the string,
* or %NULL to indicate that the string is nul-terminated.
*
- * Finds the start of the next UTF-8 character in the string after @p
+ * Finds the start of the next UTF-8 character in the string after \a p
*
- * @p does not have to be at the beginning of a UTF-8 character. No check
+ * \a p does not have to be at the beginning of a UTF-8 character. No check
* is made to see if the character found is actually valid other than
* it starts with an appropriate byte.
*
@@ -594,13 +594,13 @@ char *BLI_str_find_next_char_utf8(const char *p, const char *end)
/* was g_utf8_prev_char */
/**
* BLI_str_prev_char_utf8:
- * @p a pointer to a position within a UTF-8 encoded string
+ * \param p a pointer to a position within a UTF-8 encoded string
*
- * Finds the previous UTF-8 character in the string before @p
+ * Finds the previous UTF-8 character in the string before \a p
*
- * @p does not have to be at the beginning of a UTF-8 character. No check
+ * \a p does not have to be at the beginning of a UTF-8 character. No check
* is made to see if the character found is actually valid other than
- * it starts with an appropriate byte. If @p might be the first
+ * it starts with an appropriate byte. If \a p might be the first
* character of the string, you must use g_utf8_find_prev_char() instead.
*
* Return value: a pointer to the found character.
diff --git a/source/blender/bmesh/bmesh_class.h b/source/blender/bmesh/bmesh_class.h
index f686e96cb7d..bcd6780b675 100644
--- a/source/blender/bmesh/bmesh_class.h
+++ b/source/blender/bmesh/bmesh_class.h
@@ -226,6 +226,7 @@ enum {
};
#define BM_ALL (BM_VERT | BM_EDGE | BM_LOOP | BM_FACE)
+#define BM_ALL_NOLOOP (BM_VERT | BM_EDGE | BM_FACE)
/* BMHeader->hflag (char) */
enum {
diff --git a/source/blender/bmesh/intern/bmesh_construct.c b/source/blender/bmesh/intern/bmesh_construct.c
index eabbf6f87cd..c805a91ff22 100644
--- a/source/blender/bmesh/intern/bmesh_construct.c
+++ b/source/blender/bmesh/intern/bmesh_construct.c
@@ -105,17 +105,17 @@ BMFace *BM_face_create_quad_tri_v(BMesh *bm, BMVert **verts, int len, const BMFa
/* make new face */
if ((f == NULL) && (!is_overlap)) {
BMEdge *edar[4] = {NULL};
- edar[0] = BM_edge_create(bm, verts[0], verts[1], NULL, TRUE);
- edar[1] = BM_edge_create(bm, verts[1], verts[2], NULL, TRUE);
+ edar[0] = BM_edge_create(bm, verts[0], verts[1], NULL, BM_CREATE_NO_DOUBLE);
+ edar[1] = BM_edge_create(bm, verts[1], verts[2], NULL, BM_CREATE_NO_DOUBLE);
if (len == 4) {
- edar[2] = BM_edge_create(bm, verts[2], verts[3], NULL, TRUE);
- edar[3] = BM_edge_create(bm, verts[3], verts[0], NULL, TRUE);
+ edar[2] = BM_edge_create(bm, verts[2], verts[3], NULL, BM_CREATE_NO_DOUBLE);
+ edar[3] = BM_edge_create(bm, verts[3], verts[0], NULL, BM_CREATE_NO_DOUBLE);
}
else {
- edar[2] = BM_edge_create(bm, verts[2], verts[0], NULL, TRUE);
+ edar[2] = BM_edge_create(bm, verts[2], verts[0], NULL, BM_CREATE_NO_DOUBLE);
}
- f = BM_face_create(bm, verts, edar, len, FALSE);
+ f = BM_face_create(bm, verts, edar, len, 0);
if (example && f) {
BM_elem_attrs_copy(bm, bm, example, f);
@@ -171,7 +171,7 @@ void BM_face_copy_shared(BMesh *bm, BMFace *f)
* #BM_face_create should be considered over this function as it
* avoids some unnecessary work.
*/
-BMFace *BM_face_create_ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, int len, int nodouble)
+BMFace *BM_face_create_ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, int len, const int create_flag)
{
BMEdge **edges2 = NULL;
BLI_array_staticdeclare(edges2, BM_DEFAULT_NGON_STACK_SIZE);
@@ -282,7 +282,7 @@ BMFace *BM_face_create_ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, i
BM_ELEM_API_FLAG_DISABLE(verts[i], _FLAG_MV);
}
- f = BM_face_create(bm, verts, edges2, len, nodouble);
+ f = BM_face_create(bm, verts, edges2, len, create_flag);
/* clean up flags */
for (i = 0; i < len; i++) {
@@ -338,7 +338,7 @@ static int angle_index_pair_cmp(const void *e1, const void *e2)
*
* \note Since this is a vcloud there is no direction.
*/
-BMFace *BM_face_create_ngon_vcloud(BMesh *bm, BMVert **vert_arr, int totv, int nodouble)
+BMFace *BM_face_create_ngon_vcloud(BMesh *bm, BMVert **vert_arr, int totv, const int create_flag)
{
BMFace *f;
@@ -464,7 +464,7 @@ BMFace *BM_face_create_ngon_vcloud(BMesh *bm, BMVert **vert_arr, int totv, int n
i_prev = totv - 1;
for (i = 0; i < totv; i++) {
- edge_arr[i] = BM_edge_create(bm, vert_arr_map[i_prev], vert_arr_map[i], NULL, TRUE);
+ edge_arr[i] = BM_edge_create(bm, vert_arr_map[i_prev], vert_arr_map[i], NULL, BM_CREATE_NO_DOUBLE);
/* the edge may exist already and be attached to a face
* in this case we can find the best winding to use for the new face */
@@ -493,7 +493,7 @@ BMFace *BM_face_create_ngon_vcloud(BMesh *bm, BMVert **vert_arr, int totv, int n
/* --- */
/* create the face */
- f = BM_face_create_ngon(bm, vert_arr_map[winding[0]], vert_arr_map[winding[1]], edge_arr, totv, nodouble);
+ f = BM_face_create_ngon(bm, vert_arr_map[winding[0]], vert_arr_map[winding[1]], edge_arr, totv, create_flag);
MEM_freeN(edge_arr);
MEM_freeN(vert_arr_map);
@@ -856,7 +856,7 @@ BMesh *BM_mesh_copy(BMesh *bm_old)
v = BM_iter_new(&iter, bm_old, BM_VERTS_OF_MESH, NULL);
for (i = 0; v; v = BM_iter_step(&iter), i++) {
- v2 = BM_vert_create(bm_new, v->co, NULL); /* copy between meshes so cant use 'example' argument */
+ v2 = BM_vert_create(bm_new, v->co, NULL, BM_CREATE_SKIP_CD); /* copy between meshes so cant use 'example' argument */
BM_elem_attrs_copy(bm_old, bm_new, v, v2);
vtable[i] = v2;
BM_elem_index_set(v, i); /* set_inline */
@@ -873,7 +873,7 @@ BMesh *BM_mesh_copy(BMesh *bm_old)
e2 = BM_edge_create(bm_new,
vtable[BM_elem_index_get(e->v1)],
vtable[BM_elem_index_get(e->v2)],
- e, FALSE);
+ e, BM_CREATE_SKIP_CD);
BM_elem_attrs_copy(bm_old, bm_new, e, e2);
etable[i] = e2;
@@ -909,7 +909,7 @@ BMesh *BM_mesh_copy(BMesh *bm_old)
v2 = vtable[BM_elem_index_get(loops[0]->v)];
}
- f2 = BM_face_create_ngon(bm_new, v, v2, edges, f->len, FALSE);
+ f2 = BM_face_create_ngon(bm_new, v, v2, edges, f->len, BM_CREATE_SKIP_CD);
if (UNLIKELY(f2 == NULL)) {
continue;
}
diff --git a/source/blender/bmesh/intern/bmesh_construct.h b/source/blender/bmesh/intern/bmesh_construct.h
index 29b84046884..60c465e5f5a 100644
--- a/source/blender/bmesh/intern/bmesh_construct.h
+++ b/source/blender/bmesh/intern/bmesh_construct.h
@@ -36,9 +36,9 @@ BMFace *BM_face_create_quad_tri(BMesh *bm, BMVert *v1, BMVert *v2, BMVert *v3, B
void BM_face_copy_shared(BMesh *bm, BMFace *f);
-BMFace *BM_face_create_ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, int len, int nodouble);
+BMFace *BM_face_create_ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, int len, const int create_flag);
-BMFace *BM_face_create_ngon_vcloud(BMesh *bm, BMVert **vert_arr, int len, int nodouble);
+BMFace *BM_face_create_ngon_vcloud(BMesh *bm, BMVert **vert_arr, int len, const int create_flag);
void BMO_remove_tagged_faces(BMesh *bm, const short oflag);
void BMO_remove_tagged_edges(BMesh *bm, const short oflag);
diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c
index 03094873e25..14fab7abdc9 100644
--- a/source/blender/bmesh/intern/bmesh_core.c
+++ b/source/blender/bmesh/intern/bmesh_core.c
@@ -54,7 +54,7 @@
/**
* \brief Main function for creating a new vertex.
*/
-BMVert *BM_vert_create(BMesh *bm, const float co[3], const BMVert *example)
+BMVert *BM_vert_create(BMesh *bm, const float co[3], const BMVert *example, const eBMCreateFlag create_flag)
{
BMVert *v = BLI_mempool_calloc(bm->vpool);
@@ -64,6 +64,9 @@ BMVert *BM_vert_create(BMesh *bm, const float co[3], const BMVert *example)
BM_elem_index_set(v, -1); /* set_ok_invalid */
#endif
+ /* disallow this flag for verts - its meaningless */
+ BLI_assert((create_flag & BM_CREATE_NO_DOUBLE) == 0);
+
bm->elem_index_dirty |= BM_VERT; /* may add to middle of the pool */
bm->totvert++;
@@ -80,17 +83,20 @@ BMVert *BM_vert_create(BMesh *bm, const float co[3], const BMVert *example)
v->oflags = BLI_mempool_calloc(bm->toolflagpool);
}
- CustomData_bmesh_set_default(&bm->vdata, &v->head.data);
-
- if (example) {
- int *keyi;
+ if (!(create_flag & BM_CREATE_SKIP_CD)) {
+ if (example) {
+ int *keyi;
- BM_elem_attrs_copy(bm, bm, example, v);
+ BM_elem_attrs_copy(bm, bm, example, v);
- /* exception: don't copy the original shapekey index */
- keyi = CustomData_bmesh_get(&bm->vdata, v->head.data, CD_SHAPE_KEYINDEX);
- if (keyi) {
- *keyi = ORIGINDEX_NONE;
+ /* exception: don't copy the original shapekey index */
+ keyi = CustomData_bmesh_get(&bm->vdata, v->head.data, CD_SHAPE_KEYINDEX);
+ if (keyi) {
+ *keyi = ORIGINDEX_NONE;
+ }
+ }
+ else {
+ CustomData_bmesh_set_default(&bm->vdata, &v->head.data);
}
}
@@ -105,11 +111,11 @@ BMVert *BM_vert_create(BMesh *bm, const float co[3], const BMVert *example)
* \note Duplicate edges are supported by the API however users should _never_ see them.
* so unless you need a unique edge or know the edge won't exist, you should call with \a nodouble = TRUE
*/
-BMEdge *BM_edge_create(BMesh *bm, BMVert *v1, BMVert *v2, const BMEdge *example, int nodouble)
+BMEdge *BM_edge_create(BMesh *bm, BMVert *v1, BMVert *v2, const BMEdge *example, const eBMCreateFlag create_flag)
{
BMEdge *e;
- if (nodouble && (e = BM_edge_exists(v1, v2)))
+ if ((create_flag & BM_CREATE_NO_DOUBLE) && (e = BM_edge_exists(v1, v2)))
return e;
e = BLI_mempool_calloc(bm->epool);
@@ -136,20 +142,26 @@ BMEdge *BM_edge_create(BMesh *bm, BMVert *v1, BMVert *v2, const BMEdge *example,
BM_elem_flag_enable(e, BM_ELEM_SMOOTH | BM_ELEM_DRAW);
- CustomData_bmesh_set_default(&bm->edata, &e->head.data);
-
bmesh_disk_edge_append(e, e->v1);
bmesh_disk_edge_append(e, e->v2);
- if (example)
- BM_elem_attrs_copy(bm, bm, example, e);
+ if (!(create_flag & BM_CREATE_SKIP_CD)) {
+ if (example) {
+ BM_elem_attrs_copy(bm, bm, example, e);
+ }
+ else {
+ CustomData_bmesh_set_default(&bm->edata, &e->head.data);
+ }
+ }
+
BM_CHECK_ELEMENT(e);
return e;
}
-static BMLoop *bm_loop_create(BMesh *bm, BMVert *v, BMEdge *e, BMFace *f, const BMLoop *example)
+static BMLoop *bm_loop_create(BMesh *bm, BMVert *v, BMEdge *e, BMFace *f,
+ const BMLoop *example, const eBMCreateFlag create_flag)
{
BMLoop *l = NULL;
@@ -164,22 +176,24 @@ static BMLoop *bm_loop_create(BMesh *bm, BMVert *v, BMEdge *e, BMFace *f, const
bm->totloop++;
- if (example) {
- CustomData_bmesh_copy_data(&bm->ldata, &bm->ldata, example->head.data, &l->head.data);
- }
- else {
- CustomData_bmesh_set_default(&bm->ldata, &l->head.data);
+ if (!(create_flag & BM_CREATE_SKIP_CD)) {
+ if (example) {
+ CustomData_bmesh_copy_data(&bm->ldata, &bm->ldata, example->head.data, &l->head.data);
+ }
+ else {
+ CustomData_bmesh_set_default(&bm->ldata, &l->head.data);
+ }
}
return l;
}
-static BMLoop *bm_face_boundary_add(BMesh *bm, BMFace *f, BMVert *startv, BMEdge *starte)
+static BMLoop *bm_face_boundary_add(BMesh *bm, BMFace *f, BMVert *startv, BMEdge *starte, const int create_flag)
{
#ifdef USE_BMESH_HOLES
BMLoopList *lst = BLI_mempool_calloc(bm->looplistpool);
#endif
- BMLoop *l = bm_loop_create(bm, startv, starte, f, NULL);
+ BMLoop *l = bm_loop_create(bm, startv, starte, f, starte->l, create_flag);
bmesh_radial_append(starte, l);
@@ -211,7 +225,7 @@ BMFace *BM_face_copy(BMesh *bm, BMFace *f, const short copyverts, const short co
i = 0;
do {
if (copyverts) {
- verts[i] = BM_vert_create(bm, l_iter->v->co, l_iter->v);
+ verts[i] = BM_vert_create(bm, l_iter->v->co, l_iter->v, 0);
}
else {
verts[i] = l_iter->v;
@@ -234,7 +248,7 @@ BMFace *BM_face_copy(BMesh *bm, BMFace *f, const short copyverts, const short co
v1 = verts[(i + 1) % f->len];
}
- edges[i] = BM_edge_create(bm, v1, v2, l_iter->e, FALSE);
+ edges[i] = BM_edge_create(bm, v1, v2, l_iter->e, 0);
}
else {
edges[i] = l_iter->e;
@@ -242,7 +256,7 @@ BMFace *BM_face_copy(BMesh *bm, BMFace *f, const short copyverts, const short co
i++;
} while ((l_iter = l_iter->next) != l_first);
- f_copy = BM_face_create(bm, verts, edges, f->len, FALSE);
+ f_copy = BM_face_create(bm, verts, edges, f->len, BM_CREATE_SKIP_CD);
BM_elem_attrs_copy(bm, bm, f, f_copy);
@@ -263,7 +277,7 @@ BMFace *BM_face_copy(BMesh *bm, BMFace *f, const short copyverts, const short co
* only create the face, since this calloc's the length is initialized to 0,
* leave adding loops to the caller.
*/
-BLI_INLINE BMFace *bm_face_create__internal(BMesh *bm)
+BLI_INLINE BMFace *bm_face_create__internal(BMesh *bm, const eBMCreateFlag create_flag)
{
BMFace *f;
@@ -286,7 +300,9 @@ BLI_INLINE BMFace *bm_face_create__internal(BMesh *bm)
f->oflags = BLI_mempool_calloc(bm->toolflagpool);
}
- CustomData_bmesh_set_default(&bm->pdata, &f->head.data);
+ if (!(create_flag & BM_CREATE_SKIP_CD)) {
+ CustomData_bmesh_set_default(&bm->pdata, &f->head.data);
+ }
#ifdef USE_BMESH_HOLES
f->totbounds = 0;
@@ -298,7 +314,7 @@ BLI_INLINE BMFace *bm_face_create__internal(BMesh *bm)
/**
* \brief Main face creation function
*/
-BMFace *BM_face_create(BMesh *bm, BMVert **verts, BMEdge **edges, const int len, int nodouble)
+BMFace *BM_face_create(BMesh *bm, BMVert **verts, BMEdge **edges, const int len, const eBMCreateFlag create_flag)
{
BMFace *f = NULL;
BMLoop *l, *startl, *lastl;
@@ -309,7 +325,7 @@ BMFace *BM_face_create(BMesh *bm, BMVert **verts, BMEdge **edges, const int len,
return NULL;
}
- if (nodouble) {
+ if (create_flag & BM_CREATE_NO_DOUBLE) {
/* Check if face already exists */
overlap = BM_face_exists(verts, len, &f);
if (overlap) {
@@ -320,14 +336,14 @@ BMFace *BM_face_create(BMesh *bm, BMVert **verts, BMEdge **edges, const int len,
}
}
- f = bm_face_create__internal(bm);
+ f = bm_face_create__internal(bm, create_flag);
- startl = lastl = bm_face_boundary_add(bm, f, verts[0], edges[0]);
+ startl = lastl = bm_face_boundary_add(bm, f, verts[0], edges[0], create_flag);
startl->v = verts[0];
startl->e = edges[0];
for (i = 1; i < len; i++) {
- l = bm_loop_create(bm, verts[i], edges[i], f, edges[i]->l);
+ l = bm_loop_create(bm, verts[i], edges[i], f, edges[i]->l, create_flag);
l->f = f;
bmesh_radial_append(edges[i], l);
@@ -1033,7 +1049,7 @@ BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface, const short do_del
}
/* create region face */
- newf = BM_face_create_ngon(bm, v1, v2, edges, tote, FALSE);
+ newf = tote ? BM_face_create_ngon(bm, v1, v2, edges, tote, 0) : NULL;
if (UNLIKELY(!newf || BMO_error_occurred(bm))) {
if (!BMO_error_occurred(bm))
err = N_("Invalid boundary region to join faces");
@@ -1139,7 +1155,7 @@ static BMFace *bm_face_create__sfme(BMesh *bm, BMFace *UNUSED(example))
BMLoopList *lst;
#endif
- f = bm_face_create__internal(bm);
+ f = bm_face_create__internal(bm, 0);
#ifdef USE_BMESH_HOLES
lst = BLI_mempool_calloc(bm->looplistpool);
@@ -1223,11 +1239,11 @@ BMFace *bmesh_sfme(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2,
}
/* allocate new edge between v1 and v2 */
- e = BM_edge_create(bm, v1, v2, example, nodouble);
+ e = BM_edge_create(bm, v1, v2, example, nodouble ? BM_CREATE_NO_DOUBLE : 0);
f2 = bm_face_create__sfme(bm, f);
- f1loop = bm_loop_create(bm, v2, e, f, v2loop);
- f2loop = bm_loop_create(bm, v1, e, f2, v1loop);
+ f1loop = bm_loop_create(bm, v2, e, f, v2loop, 0);
+ f2loop = bm_loop_create(bm, v1, e, f2, v1loop, 0);
f1loop->prev = v2loop->prev;
f2loop->prev = v1loop->prev;
@@ -1334,10 +1350,10 @@ BMFace *bmesh_sfme(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2,
* will be attached to that end and is returned in \a r_e.
*
* \par Examples:
+ *
* <pre>
* E
* Before: OV-------------TV
- *
* E RE
* After: OV------NV-----TV
* </pre>
@@ -1359,8 +1375,8 @@ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e)
valence2 = bmesh_disk_count(tv);
- nv = BM_vert_create(bm, tv->co, tv);
- ne = BM_edge_create(bm, nv, tv, e, FALSE);
+ nv = BM_vert_create(bm, tv->co, tv, 0);
+ ne = BM_edge_create(bm, nv, tv, e, 0);
bmesh_disk_edge_remove(ne, tv);
bmesh_disk_edge_remove(ne, nv);
@@ -1403,7 +1419,7 @@ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e)
nextl = nextl != nextl->radial_next ? nextl->radial_next : NULL;
bmesh_radial_loop_remove(l, NULL);
- nl = bm_loop_create(bm, NULL, NULL, l->f, l);
+ nl = bm_loop_create(bm, NULL, NULL, l->f, l, 0);
nl->prev = l;
nl->next = (l->next);
nl->prev->next = nl;
@@ -1919,7 +1935,7 @@ int bmesh_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len)
verts = MEM_callocN(sizeof(BMVert *) * maxindex, __func__);
verts[0] = v;
for (i = 1; i < maxindex; i++) {
- verts[i] = BM_vert_create(bm, v->co, v);
+ verts[i] = BM_vert_create(bm, v->co, v, 0);
}
/* Replace v with the new verts in each group */
@@ -2085,7 +2101,7 @@ int bmesh_edge_separate(BMesh *bm, BMEdge *e, BMLoop *l_sep)
e->l = l_sep->radial_next;
}
- ne = BM_edge_create(bm, e->v1, e->v2, e, FALSE);
+ ne = BM_edge_create(bm, e->v1, e->v2, e, 0);
bmesh_radial_loop_remove(l_sep, e);
bmesh_radial_append(ne, l_sep);
l_sep->e = ne;
diff --git a/source/blender/bmesh/intern/bmesh_core.h b/source/blender/bmesh/intern/bmesh_core.h
index 0667ed9ea1c..5fd4a6ec7df 100644
--- a/source/blender/bmesh/intern/bmesh_core.h
+++ b/source/blender/bmesh/intern/bmesh_core.h
@@ -29,9 +29,18 @@
BMFace *BM_face_copy(BMesh *bm, BMFace *f, const short copyverts, const short copyedges);
-BMVert *BM_vert_create(BMesh *bm, const float co[3], const BMVert *example);
-BMEdge *BM_edge_create(BMesh *bm, BMVert *v1, BMVert *v2, const BMEdge *example, int nodouble);
-BMFace *BM_face_create(BMesh *bm, BMVert **verts, BMEdge **edges, const int len, int nodouble);
+typedef enum eBMCreateFlag {
+ /* faces and edges only */
+ BM_CREATE_NO_DOUBLE = (1 << 1),
+ /* Skip CustomData - for all element types data,
+ * use if we immediately write customdata into the element so this skips copying from 'example'
+ * args or setting defaults, speeds up conversion when data is converted all at once. */
+ BM_CREATE_SKIP_CD = (1 << 2),
+} eBMCreateFlag;
+
+BMVert *BM_vert_create(BMesh *bm, const float co[3], const BMVert *example, const eBMCreateFlag create_flag);
+BMEdge *BM_edge_create(BMesh *bm, BMVert *v1, BMVert *v2, const BMEdge *example, const eBMCreateFlag create_flag);
+BMFace *BM_face_create(BMesh *bm, BMVert **verts, BMEdge **edges, const int len, const eBMCreateFlag create_flag);
void BM_face_edges_kill(BMesh *bm, BMFace *f);
void BM_face_verts_kill(BMesh *bm, BMFace *f);
diff --git a/source/blender/bmesh/intern/bmesh_mesh_conv.c b/source/blender/bmesh/intern/bmesh_mesh_conv.c
index 62abf43829b..388d148377a 100644
--- a/source/blender/bmesh/intern/bmesh_mesh_conv.c
+++ b/source/blender/bmesh/intern/bmesh_mesh_conv.c
@@ -206,7 +206,7 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr)
CustomData_bmesh_init_pool(&bm->pdata, me->totpoly, BM_FACE);
for (i = 0, mvert = me->mvert; i < me->totvert; i++, mvert++) {
- v = BM_vert_create(bm, keyco && set_key ? keyco[i] : mvert->co, NULL);
+ v = BM_vert_create(bm, keyco && set_key ? keyco[i] : mvert->co, NULL, BM_CREATE_SKIP_CD);
BM_elem_index_set(v, i); /* set_ok */
vt[i] = v;
@@ -220,11 +220,11 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr)
normal_short_to_float_v3(v->no, mvert->no);
- BM_elem_float_data_set(&bm->vdata, v, CD_BWEIGHT, (float)mvert->bweight / 255.0f);
-
- /* Copy Custom Dat */
+ /* Copy Custom Data */
CustomData_to_bmesh_block(&me->vdata, &bm->vdata, i, &v->head.data);
+ BM_elem_float_data_set(&bm->vdata, v, CD_BWEIGHT, (float)mvert->bweight / 255.0f);
+
/* set shapekey data */
if (me->key) {
/* set shape key original index */
@@ -254,7 +254,7 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr)
medge = me->medge;
for (i = 0; i < me->totedge; i++, medge++) {
- e = BM_edge_create(bm, vt[medge->v1], vt[medge->v2], NULL, FALSE);
+ e = BM_edge_create(bm, vt[medge->v1], vt[medge->v2], NULL, BM_CREATE_SKIP_CD);
BM_elem_index_set(e, i); /* set_ok */
et[i] = e;
@@ -312,7 +312,7 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr)
}
#endif
- f = BM_face_create(bm, verts, fedges, mpoly->totloop, FALSE);
+ f = BM_face_create(bm, verts, fedges, mpoly->totloop, BM_CREATE_SKIP_CD);
if (UNLIKELY(f == NULL)) {
printf("%s: Warning! Bad face in mesh"
@@ -338,7 +338,7 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr)
j = 0;
BM_ITER_ELEM_INDEX (l, &iter, f, BM_LOOPS_OF_FACE, j) {
/* Save index of correspsonding MLoop */
- BM_elem_index_set(l, mpoly->loopstart + j); /* set_loop */
+ CustomData_to_bmesh_block(&me->ldata, &bm->ldata, mpoly->loopstart + j, &l->head.data);
}
/* Copy Custom Data */
@@ -347,23 +347,6 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr)
bm->elem_index_dirty &= ~BM_FACE; /* added in order, clear dirty flag */
- {
- BMIter fiter;
- BMIter liter;
-
- /* Copy over loop CustomData. Doing this in a separate loop isn't necessary
- * but is an optimization, to avoid copying a bunch of interpolated customdata
- * for each BMLoop (from previous BMLoops using the same edge), always followed
- * by freeing the interpolated data and overwriting it with data from the Mesh. */
- BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
- BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
- int li = BM_elem_index_get(l);
- CustomData_to_bmesh_block(&me->ldata, &bm->ldata, li, &l->head.data);
- BM_elem_index_set(l, 0); /* set_loop */
- }
- }
- }
-
if (me->mselect && me->totselect != 0) {
BMVert **vert_array = MEM_callocN(sizeof(BMVert *) * bm->totvert,
diff --git a/source/blender/bmesh/intern/bmesh_mods.c b/source/blender/bmesh/intern/bmesh_mods.c
index dc8b52423ab..89516061f91 100644
--- a/source/blender/bmesh/intern/bmesh_mods.c
+++ b/source/blender/bmesh/intern/bmesh_mods.c
@@ -142,9 +142,10 @@ int BM_disk_dissolve(BMesh *bm, BMVert *v)
return FALSE;
}
#else
- BM_faces_join_pair(bm, e->l->f, e->l->radial_next->f, e, TRUE);
-
- if (!BM_vert_collapse_faces(bm, v->e, v, 1.0, FALSE, TRUE)) {
+ if (UNLIKELY(!BM_faces_join_pair(bm, e->l->f, e->l->radial_next->f, e, TRUE))) {
+ return FALSE;
+ }
+ else if (UNLIKELY(!BM_vert_collapse_faces(bm, v->e, v, 1.0, FALSE, TRUE))) {
return FALSE;
}
#endif
diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c
index ec07eb5d9f7..58c6e051e48 100644
--- a/source/blender/bmesh/intern/bmesh_opdefines.c
+++ b/source/blender/bmesh/intern/bmesh_opdefines.c
@@ -59,8 +59,10 @@
#include "bmesh.h"
#include "intern/bmesh_private.h"
-/* ok, I'm going to write a little docgen script. so all
- * bmop comments must conform to the following template/rules:
+/* The formatting of these bmesh operators is parsed by
+ * 'doc/python_api/rst_from_bmesh_opdefines.py'
+ * for use in python docs, so reStructuredText may be used
+ * rather then doxygen syntax.
*
* template (py quotes used because nested comments don't work
* on all C compilers):
@@ -79,148 +81,149 @@
* so the first line is the "title" of the bmop.
* subsequent line blocks separated by blank lines
* are paragraphs. individual descriptions of slots
- * would be extracted from comments
- * next to them, e.g.
+ * are extracted from comments next to them.
*
- * {BMO_OP_SLOT_ELEMENT_BUF, "geom.out"}, //output slot, boundary region
+ * eg:
+ * {BMO_OP_SLOT_ELEMENT_BUF, "geom.out"}, """ output slot, boundary region """
*
- * the doc generator would automatically detect the presence of "output slot"
- * and flag the slot as an output. the same happens for "input slot". also
- * note that "edges", "faces", "verts", "loops", and "geometry" are valid
- * substitutions for "slot".
+ * ... or:
*
- * note that slots default to being input slots.
+ * """ output slot, boundary region """
+ * {BMO_OP_SLOT_ELEMENT_BUF, "geom.out"},
+ *
+ * Both are acceptable.
+ * note that '//' comments are ignored.
*/
/*
- * Vertex Smooth
+ * Vertex Smooth.
*
* Smooths vertices by using a basic vertex averaging scheme.
*/
static BMOpDefine bmo_smooth_vert_def = {
"smooth_vert",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertices */
- {BMO_OP_SLOT_BOOL, "mirror_clip_x"}, /* set vertices close to the x axis before the operation to 0 */
- {BMO_OP_SLOT_BOOL, "mirror_clip_y"}, /* set vertices close to the y axis before the operation to 0 */
- {BMO_OP_SLOT_BOOL, "mirror_clip_z"}, /* set vertices close to the z axis before the operation to 0 */
- {BMO_OP_SLOT_FLT, "clip_dist"}, /* clipping threshod for the above three slots */
- {BMO_OP_SLOT_BOOL, "use_axis_x"}, /* smooth vertices along X axis */
- {BMO_OP_SLOT_BOOL, "use_axis_y"}, /* smooth vertices along Y axis */
- {BMO_OP_SLOT_BOOL, "use_axis_z"}, /* smooth vertices along Z axis */
- {0},
- },
- {{0}}, /* no output */
+ {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
+ {"mirror_clip_x", BMO_OP_SLOT_BOOL}, /* set vertices close to the x axis before the operation to 0 */
+ {"mirror_clip_y", BMO_OP_SLOT_BOOL}, /* set vertices close to the y axis before the operation to 0 */
+ {"mirror_clip_z", BMO_OP_SLOT_BOOL}, /* set vertices close to the z axis before the operation to 0 */
+ {"clip_dist", BMO_OP_SLOT_FLT}, /* clipping threshold for the above three slots */
+ {"use_axis_x", BMO_OP_SLOT_BOOL}, /* smooth vertices along X axis */
+ {"use_axis_y", BMO_OP_SLOT_BOOL}, /* smooth vertices along Y axis */
+ {"use_axis_z", BMO_OP_SLOT_BOOL}, /* smooth vertices along Z axis */
+ {{'\0'}},
+ },
+ {{{'\0'}}}, /* no output */
bmo_smooth_vert_exec,
0
};
/*
- * Vertext Smooth Laplacian
+ * Vertext Smooth Laplacian.
+ *
* Smooths vertices by using Laplacian smoothing propose by.
- * Desbrun, et al. Implicit Fairing of Irregular Meshes using Diffusion and Curvature Flow
+ * Desbrun, et al. Implicit Fairing of Irregular Meshes using Diffusion and Curvature Flow.
*/
static BMOpDefine bmo_smooth_laplacian_vert_def = {
"smooth_laplacian_vert",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertices */
- {BMO_OP_SLOT_FLT, "lambda"}, /* lambda param */
- {BMO_OP_SLOT_FLT, "lambda_border"}, /* lambda param in border */
- {BMO_OP_SLOT_BOOL, "use_x"}, /* Smooth object along X axis */
- {BMO_OP_SLOT_BOOL, "use_y"}, /* Smooth object along Y axis */
- {BMO_OP_SLOT_BOOL, "use_z"}, /* Smooth object along Z axis */
- {BMO_OP_SLOT_BOOL, "preserve_volume"}, /* Apply volume preservation after smooth */
- {0},
+ {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
+ {"lambda", BMO_OP_SLOT_FLT}, /* lambda param */
+ {"lambda_border", BMO_OP_SLOT_FLT}, /* lambda param in border */
+ {"use_x", BMO_OP_SLOT_BOOL}, /* Smooth object along X axis */
+ {"use_y", BMO_OP_SLOT_BOOL}, /* Smooth object along Y axis */
+ {"use_z", BMO_OP_SLOT_BOOL}, /* Smooth object along Z axis */
+ {"preserve_volume", BMO_OP_SLOT_BOOL}, /* Apply volume preservation after smooth */
+ {{'\0'}},
},
- {{0}}, /* no output */
+ {{{'\0'}}}, /* no output */
bmo_smooth_laplacian_vert_exec,
0
};
/*
- * Right-Hand Faces
+ * Right-Hand Faces.
*
* Computes an "outside" normal for the specified input faces.
*/
-
static BMOpDefine bmo_recalc_face_normals_def = {
"recalc_face_normals",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "faces"},
- {BMO_OP_SLOT_BOOL, "use_flip"}, /* internal flag, used by bmesh_rationalize_normals */
- {0},
+ {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
+ {"use_flip", BMO_OP_SLOT_BOOL}, /* Reverse the result */
+ {{'\0'}},
},
- {{0}}, /* no output */
+ {{{'\0'}}}, /* no output */
bmo_recalc_face_normals_exec,
BMO_OP_FLAG_UNTAN_MULTIRES,
};
/*
- * Region Extend
+ * Region Extend.
*
* used to implement the select more/less tools.
* this puts some geometry surrounding regions of
* geometry in geom into geom.out.
*
- * if usefaces is 0 then geom.out spits out verts and edges,
+ * if use_faces is 0 then geom.out spits out verts and edges,
* otherwise it spits out faces.
*/
static BMOpDefine bmo_region_extend_def = {
"region_extend",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "geom"}, /* input geometry */
- {BMO_OP_SLOT_BOOL, "use_constrict"}, /* find boundary inside the regions, not outside. */
- {BMO_OP_SLOT_BOOL, "use_faces"}, /* extend from faces instead of edges */
- {0},
+ {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* input geometry */
+ {"use_constrict", BMO_OP_SLOT_BOOL}, /* find boundary inside the regions, not outside. */
+ {"use_faces", BMO_OP_SLOT_BOOL}, /* extend from faces instead of edges */
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "geom.out"}, /* output slot, computed boundary geometry. */
- {0},
+ {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* output slot, computed boundary geometry. */
+ {{'\0'}},
},
bmo_region_extend_exec,
0
};
/*
- * Edge Rotate
+ * Edge Rotate.
*
* Rotates edges topologically. Also known as "spin edge" to some people.
- * Simple example: [/] becomes [|] then [\].
+ * Simple example: ``[/] becomes [|] then [\]``.
*/
static BMOpDefine bmo_rotate_edges_def = {
"rotate_edges",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edges */
- {BMO_OP_SLOT_BOOL, "use_ccw"}, /* rotate edge counter-clockwise if true, othewise clockwise */
- {0},
+ {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
+ {"use_ccw", BMO_OP_SLOT_BOOL}, /* rotate edge counter-clockwise if true, otherwise clockwise */
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "edges.out"}, /* newly spun edges */
- {0},
+ {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* newly spun edges */
+ {{'\0'}},
},
bmo_rotate_edges_exec,
BMO_OP_FLAG_UNTAN_MULTIRES
};
/*
- * Reverse Faces
+ * Reverse Faces.
*
- * Reverses the winding (vertex order) of faces. This has the effect of
- * flipping the normal.
+ * Reverses the winding (vertex order) of faces.
+ * This has the effect of flipping the normal.
*/
static BMOpDefine bmo_reverse_faces_def = {
"reverse_faces",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
- {0},
+ {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
+ {{'\0'}},
},
- {{0}}, /* no output */
+ {{{'\0'}}}, /* no output */
bmo_reverse_faces_exec,
BMO_OP_FLAG_UNTAN_MULTIRES,
};
/*
- * Edge Bisect
+ * Edge Bisect.
*
* Splits input edges (but doesn't do anything else).
* This creates a 2-valence vert.
@@ -228,50 +231,49 @@ static BMOpDefine bmo_reverse_faces_def = {
static BMOpDefine bmo_bisect_edges_def = {
"bisect_edges",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edges */
- {BMO_OP_SLOT_INT, "cuts"}, /* number of cuts */
- {0},
+ {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
+ {"cuts", BMO_OP_SLOT_INT}, /* number of cuts */
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "geom_split.out"}, /* newly created vertices and edges */
- {0},
+ {{"geom_split.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* newly created vertices and edges */
+ {{'\0'}},
},
bmo_bisect_edges_exec,
BMO_OP_FLAG_UNTAN_MULTIRES
};
/*
- * Mirror
+ * Mirror.
*
* Mirrors geometry along an axis. The resulting geometry is welded on using
* merge_dist. Pairs of original/mirrored vertices are welded using the merge_dist
* parameter (which defines the minimum distance for welding to happen).
*/
-
static BMOpDefine bmo_mirror_def = {
"mirror",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "geom"}, /* input geometry */
- {BMO_OP_SLOT_MAT, "mat"}, /* matrix defining the mirror transformation */
- {BMO_OP_SLOT_FLT, "merge_dist"}, /* maximum distance for merging. does no merging if 0. */
- {BMO_OP_SLOT_INT, "axis"}, /* the axis to use, 0, 1, or 2 for x, y, z */
- {BMO_OP_SLOT_BOOL, "mirror_u"}, /* mirror UVs across the u axis */
- {BMO_OP_SLOT_BOOL, "mirror_v"}, /* mirror UVs across the v axis */
- {0},
+ {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* input geometry */
+ {"matrix", BMO_OP_SLOT_MAT}, /* matrix defining the mirror transformation */
+ {"merge_dist", BMO_OP_SLOT_FLT}, /* maximum distance for merging. does no merging if 0. */
+ {"axis", BMO_OP_SLOT_INT}, /* the axis to use, 0, 1, or 2 for x, y, z */
+ {"mirror_u", BMO_OP_SLOT_BOOL}, /* mirror UVs across the u axis */
+ {"mirror_v", BMO_OP_SLOT_BOOL}, /* mirror UVs across the v axis */
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "geom.out"}, /* output geometry, mirrored */
- {0},
+ {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* output geometry, mirrored */
+ {{'\0'}},
},
bmo_mirror_exec,
0,
};
/*
- * Find Doubles
+ * Find Doubles.
*
- * Takes input verts and find vertices they should weld to. Outputs a
- * mapping slot suitable for use with the weld verts bmop.
+ * Takes input verts and find vertices they should weld to.
+ * Outputs a mapping slot suitable for use with the weld verts bmop.
*
* If keep_verts is used, vertices outside that set can only be merged
* with vertices in that set.
@@ -279,21 +281,21 @@ static BMOpDefine bmo_mirror_def = {
static BMOpDefine bmo_find_doubles_def = {
"find_doubles",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertices */
- {BMO_OP_SLOT_ELEMENT_BUF, "keep_verts"}, /* list of verts to keep */
- {BMO_OP_SLOT_FLT, "dist"}, /* minimum distance */
- {0},
+ {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
+ {"keep_verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* list of verts to keep */
+ {"dist", BMO_OP_SLOT_FLT}, /* minimum distance */
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_MAPPING, "targetmap.out"},
- {0},
+ {{"targetmap.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
+ {{'\0'}},
},
bmo_find_doubles_exec,
0,
};
/*
- * Remove Doubles
+ * Remove Doubles.
*
* Finds groups of vertices closer then dist and merges them together,
* using the weld verts bmop.
@@ -301,70 +303,69 @@ static BMOpDefine bmo_find_doubles_def = {
static BMOpDefine bmo_remove_doubles_def = {
"remove_doubles",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input verts */
- {BMO_OP_SLOT_FLT, "dist"}, /* minimum distance */
- {0},
+ {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input verts */
+ {"dist", BMO_OP_SLOT_FLT}, /* minimum distance */
+ {{'\0'}},
},
- {{0}}, /* no output */
+ {{{'\0'}}}, /* no output */
bmo_remove_doubles_exec,
BMO_OP_FLAG_UNTAN_MULTIRES,
};
/*
- * Auto Merge
+ * Auto Merge.
*
- * Finds groups of vertices closer then dist and merges them together,
+ * Finds groups of vertices closer then **dist** and merges them together,
* using the weld verts bmop. The merges must go from a vert not in
- * verts to one in verts.
+ * **verts** to one in **verts**.
*/
static BMOpDefine bmo_automerge_def = {
"automerge",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input verts */
- {BMO_OP_SLOT_FLT, "dist"}, /* minimum distance */
- {0},
+ {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input verts */
+ {"dist", BMO_OP_SLOT_FLT}, /* minimum distance */
+ {{'\0'}},
},
- {{0}}, /* no output */
+ {{{'\0'}}}, /* no output */
bmo_automerge_exec,
BMO_OP_FLAG_UNTAN_MULTIRES,
};
/*
- * Collapse Connected
+ * Collapse Connected.
*
* Collapses connected vertices
*/
static BMOpDefine bmo_collapse_def = {
"collapse",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edge */
- {0},
+ {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edge */
+ {{'\0'}},
},
- {{0}}, /* no output */
+ {{{'\0'}}}, /* no output */
bmo_collapse_exec,
BMO_OP_FLAG_UNTAN_MULTIRES,
};
-
/*
- * Facedata point Merge
+ * Face-Data Point Merge.
*
* Merge uv/vcols at a specific vertex.
*/
static BMOpDefine bmo_pointmerge_facedata_def = {
"pointmerge_facedata",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertices */
- {BMO_OP_SLOT_ELEMENT_BUF, "snapv"}, /* snap vertex */
- {0},
+ {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
+ {"vert_snap", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE}}, /* snap vertex */
+ {{'\0'}},
},
- {{0}}, /* no output */
+ {{{'\0'}}}, /* no output */
bmo_pointmerge_facedata_exec,
0,
};
/*
- * Average Vertices Facevert Data
+ * Average Vertices Facevert Data.
*
* Merge uv/vcols associated with the input vertices at
* the bounding box center. (I know, it's not averaging but
@@ -373,67 +374,68 @@ static BMOpDefine bmo_pointmerge_facedata_def = {
static BMOpDefine bmo_average_vert_facedata_def = {
"average_vert_facedata",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertice */
- {0},
+ {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertice */
+ {{'\0'}},
},
- {{0}}, /* no output */
+ {{{'\0'}}}, /* no output */
bmo_average_vert_facedata_exec,
0,
};
/*
- * Point Merge
+ * Point Merge.
*
* Merge verts together at a point.
*/
static BMOpDefine bmo_pointmerge_def = {
"pointmerge",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertice */
- {BMO_OP_SLOT_VEC, "merge_co"},
- {0},
+ {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertice */
+ {"merge_co", BMO_OP_SLOT_VEC},
+ {{'\0'}},
},
- {{0}}, /* no output */
+ {{{'\0'}}}, /* no output */
bmo_pointmerge_exec,
BMO_OP_FLAG_UNTAN_MULTIRES,
};
/*
- * Collapse Connected UVs
+ * Collapse Connected UV's.
*
* Collapses connected UV vertices.
*/
static BMOpDefine bmo_collapse_uvs_def = {
"collapse_uvs",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edge */
- {0},
+ {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edge */
+ {{'\0'}},
},
- {{0}}, /* no output */
+ {{{'\0'}}}, /* no output */
bmo_collapse_uvs_exec,
0,
};
/*
- * Weld Verts
+ * Weld Verts.
*
- * Welds verts together (kindof like remove doubles, merge, etc, all of which
+ * Welds verts together (kind-of like remove doubles, merge, etc, all of which
* use or will use this bmop). You pass in mappings from vertices to the vertices
* they weld with.
*/
static BMOpDefine bmo_weld_verts_def = {
"weld_verts",
/* slots_in */
- {{BMO_OP_SLOT_MAPPING, "targetmap"}, /* maps welded vertices to verts they should weld to */
- {0},
+ /* maps welded vertices to verts they should weld to */
+ {{"targetmap", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
+ {{'\0'}},
},
- {{0}}, /* no output */
+ {{{'\0'}}}, /* no output */
bmo_weld_verts_exec,
BMO_OP_FLAG_UNTAN_MULTIRES,
};
/*
- * Make Vertex
+ * Make Vertex.
*
* Creates a single vertex; this bmop was necessary
* for click-create-vertex.
@@ -441,19 +443,19 @@ static BMOpDefine bmo_weld_verts_def = {
static BMOpDefine bmo_create_vert_def = {
"create_vert",
/* slots_in */
- {{BMO_OP_SLOT_VEC, "co"}, /* the coordinate of the new vert */
- {0},
+ {{"co", BMO_OP_SLOT_VEC}, /* the coordinate of the new vert */
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "vert.out"}, /* the new vert */
- {0},
+ {{"vert.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* the new vert */
+ {{'\0'}},
},
bmo_create_vert_exec,
0,
};
/*
- * Join Triangles
+ * Join Triangles.
*
* Tries to intelligently join triangles according
* to various settings and stuff.
@@ -461,29 +463,28 @@ static BMOpDefine bmo_create_vert_def = {
static BMOpDefine bmo_join_triangles_def = {
"join_triangles",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input geometry. */
- {BMO_OP_SLOT_BOOL, "cmp_sharp"},
- {BMO_OP_SLOT_BOOL, "cmp_uvs"},
- {BMO_OP_SLOT_BOOL, "cmp_vcols"},
- {BMO_OP_SLOT_BOOL, "cmp_materials"},
- {BMO_OP_SLOT_FLT, "limit"},
- {0},
+ {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input geometry. */
+ {"cmp_sharp", BMO_OP_SLOT_BOOL},
+ {"cmp_uvs", BMO_OP_SLOT_BOOL},
+ {"cmp_vcols", BMO_OP_SLOT_BOOL},
+ {"cmp_materials", BMO_OP_SLOT_BOOL},
+ {"limit", BMO_OP_SLOT_FLT},
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "faces.out"}, /* joined faces */
- {0},
+ {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* joined faces */
+ {{'\0'}},
},
bmo_join_triangles_exec,
BMO_OP_FLAG_UNTAN_MULTIRES,
};
/*
- * Contextual Create
+ * Contextual Create.
*
- * This is basically fkey, it creates
+ * This is basically F-key, it creates
* new faces from vertices, makes stuff from edge nets,
- * makes wire edges, etc. It also dissolves
- * faces.
+ * makes wire edges, etc. It also dissolves faces.
*
* Three verts become a triangle, four become a quad. Two
* become a wire edge.
@@ -491,63 +492,70 @@ static BMOpDefine bmo_join_triangles_def = {
static BMOpDefine bmo_contextual_create_def = {
"contextual_create",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "geom"}, /* input geometry. */
- {BMO_OP_SLOT_INT, "mat_nr"}, /* material to use */
- {BMO_OP_SLOT_BOOL, "use_smooth"}, /* smooth to use */
- {0},
+ {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* input geometry. */
+ {"mat_nr", BMO_OP_SLOT_INT}, /* material to use */
+ {"use_smooth", BMO_OP_SLOT_BOOL}, /* smooth to use */
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "faces.out"}, /* newly-made face(s) */
+ {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* newly-made face(s) */
/* note, this is for stand-alone edges only, not edges which are apart of newly created faces */
- {BMO_OP_SLOT_ELEMENT_BUF, "edges.out"}, /* newly-made edge(s) */
- {0},
+ {"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* newly-made edge(s) */
+ {{'\0'}},
},
bmo_contextual_create_exec,
BMO_OP_FLAG_UNTAN_MULTIRES,
};
/*
- * Bridge edge loops with faces
+ * Bridge edge loops with faces.
*/
static BMOpDefine bmo_bridge_loops_def = {
"bridge_loops",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edge */
- {BMO_OP_SLOT_BOOL, "use_merge"},
- {BMO_OP_SLOT_FLT, "merge_factor"},
- {0},
+ {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edge */
+ {"use_merge", BMO_OP_SLOT_BOOL},
+ {"merge_factor", BMO_OP_SLOT_FLT},
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "faces.out"}, /* new faces */
- {0},
+ {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* new faces */
+ {{'\0'}},
},
bmo_bridge_loops_exec,
0,
};
+/*
+ * Edge Net Fill.
+ *
+ * Create faces defined by enclosed edges.
+ */
static BMOpDefine bmo_edgenet_fill_def = {
"edgenet_fill",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edge */
- {BMO_OP_SLOT_MAPPING, "restrict"}, /* restricts edges to groups. maps edges to integer */
- {BMO_OP_SLOT_BOOL, "use_restrict"},
- {BMO_OP_SLOT_BOOL, "use_fill_check"},
- {BMO_OP_SLOT_ELEMENT_BUF, "exclude_faces"}, /* list of faces to ignore for manifold check */
- {BMO_OP_SLOT_INT, "mat_nr"}, /* material to use */
- {BMO_OP_SLOT_BOOL, "use_smooth"}, /* material to use */
- {0},
+ {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edge */
+ /* restricts edges to groups. maps edges to integer */
+ {"restrict", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_BOOL}},
+ {"use_restrict", BMO_OP_SLOT_BOOL},
+ {"use_fill_check", BMO_OP_SLOT_BOOL},
+ {"exclude_faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* list of faces to ignore for manifold check */
+ {"mat_nr", BMO_OP_SLOT_INT}, /* material to use */
+ {"use_smooth", BMO_OP_SLOT_BOOL}, /* material to use */
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_MAPPING, "face_groupmap.out"}, /* maps new faces to the group numbers they came from */
- {BMO_OP_SLOT_ELEMENT_BUF, "faces.out"}, /* new face */
- {0},
+ /* maps new faces to the group numbers they came from */
+ {{"face_groupmap.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
+ {"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* new face */
+ {{'\0'}},
},
bmo_edgenet_fill_exec,
0,
};
/*
- * Edgenet Prepare
+ * Edgenet Prepare.
*
* Identifies several useful edge loop cases and modifies them so
* they'll become a face when edgenet_fill is called. The cases covered are:
@@ -559,74 +567,72 @@ static BMOpDefine bmo_edgenet_fill_def = {
static BMOpDefine bmo_edgenet_prepare_def = {
"edgenet_prepare",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edges */
- {0},
+ {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "edges.out"}, /* new edges */
- {0},
+ {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* new edges */
+ {{'\0'}},
},
- bmo_edgenet_prepare,
+ bmo_edgenet_prepare_exec,
0,
};
/*
- * Rotate
+ * Rotate.
*
- * Rotate vertices around a center, using a 3x3 rotation
- * matrix. Equivalent of the old rotateflag function.
+ * Rotate vertices around a center, using a 3x3 rotation matrix.
*/
static BMOpDefine bmo_rotate_def = {
"rotate",
/* slots_in */
- {{BMO_OP_SLOT_VEC, "cent"}, /* center of rotation */
- {BMO_OP_SLOT_MAT, "mat"}, /* matrix defining rotation */
- {BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertices */
- {0},
+ {{"cent", BMO_OP_SLOT_VEC}, /* center of rotation */
+ {"matrix", BMO_OP_SLOT_MAT}, /* matrix defining rotation */
+ {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
+ {{'\0'}},
},
- {{0}}, /* no output */
+ {{{'\0'}}}, /* no output */
bmo_rotate_exec,
0,
};
/*
- * Translate
+ * Translate.
*
- * Translate vertices by an offset. Equivalent of the
- * old translateflag function.
+ * Translate vertices by an offset.
*/
static BMOpDefine bmo_translate_def = {
"translate",
/* slots_in */
- {{BMO_OP_SLOT_VEC, "vec"}, /* translation offset */
- {BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertices */
- {0},
+ {{"vec", BMO_OP_SLOT_VEC}, /* translation offset */
+ {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
+ {{'\0'}},
},
- {{0}}, /* no output */
+ {{{'\0'}}}, /* no output */
bmo_translate_exec,
0,
};
/*
- * Scale
+ * Scale.
*
* Scales vertices by an offset.
*/
static BMOpDefine bmo_scale_def = {
"scale",
/* slots_in */
- {{BMO_OP_SLOT_VEC, "vec"}, /* scale factor */
- {BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertices */
- {0},
+ {{"vec", BMO_OP_SLOT_VEC}, /* scale factor */
+ {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
+ {{'\0'}},
},
- {{0}}, /* no output */
+ {{{'\0'}}}, /* no output */
bmo_scale_exec,
0,
};
/*
- * Transform
+ * Transform.
*
* Transforms a set of vertices by a matrix. Multiplies
* the vertex coordinates with the matrix.
@@ -634,17 +640,17 @@ static BMOpDefine bmo_scale_def = {
static BMOpDefine bmo_transform_def = {
"transform",
/* slots_in */
- {{BMO_OP_SLOT_MAT, "mat"}, /* transform matrix */
- {BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertices */
- {0},
+ {{"matrix", BMO_OP_SLOT_MAT}, /* transform matrix */
+ {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
+ {{'\0'}},
},
- {{0}}, /* no output */
+ {{{'\0'}}}, /* no output */
bmo_transform_exec,
0,
};
/*
- * Object Load BMesh
+ * Object Load BMesh.
*
* Loads a bmesh into an object/mesh. This is a "private"
* bmop.
@@ -652,36 +658,39 @@ static BMOpDefine bmo_transform_def = {
static BMOpDefine bmo_object_load_bmesh_def = {
"object_load_bmesh",
/* slots_in */
- {{BMO_OP_SLOT_PTR, "scene"},
- {BMO_OP_SLOT_PTR, "object"},
- {0},
+ {{"scene", BMO_OP_SLOT_PTR, {BMO_OP_SLOT_SUBTYPE_PTR_SCENE}},
+ {"object", BMO_OP_SLOT_PTR, {BMO_OP_SLOT_SUBTYPE_PTR_OBJECT}},
+ {{'\0'}},
},
- {{0}}, /* no output */
+ {{{'\0'}}}, /* no output */
bmo_object_load_bmesh_exec,
0,
};
/*
- * BMesh to Mesh
+ * BMesh to Mesh.
*
* Converts a bmesh to a Mesh. This is reserved for exiting editmode.
*/
static BMOpDefine bmo_bmesh_to_mesh_def = {
"bmesh_to_mesh",
/* slots_in */
- {{BMO_OP_SLOT_PTR, "mesh"}, /* pointer to a mesh structure to fill in */
- {BMO_OP_SLOT_PTR, "object"}, /* pointer to an object structure */
- {BMO_OP_SLOT_BOOL, "skip_tessface"}, /* don't calculate mfaces */
- {0},
+ {
+ /* pointer to a mesh structure to fill in */
+ {"mesh", BMO_OP_SLOT_PTR, {BMO_OP_SLOT_SUBTYPE_PTR_MESH}},
+ /* pointer to an object structure */
+ {"object", BMO_OP_SLOT_PTR, {BMO_OP_SLOT_SUBTYPE_PTR_OBJECT}},
+ {"skip_tessface", BMO_OP_SLOT_BOOL}, /* don't calculate mfaces */
+ {{'\0'}},
},
- {{0}}, /* no output */
+ {{{'\0'}}}, /* no output */
bmo_bmesh_to_mesh_exec,
0,
};
/*
- * Mesh to BMesh
+ * Mesh to BMesh.
*
* Load the contents of a mesh into the bmesh. this bmop is private, it's
* reserved exclusively for entering editmode.
@@ -689,38 +698,40 @@ static BMOpDefine bmo_bmesh_to_mesh_def = {
static BMOpDefine bmo_mesh_to_bmesh_def = {
"mesh_to_bmesh",
/* slots_in */
- {{BMO_OP_SLOT_PTR, "mesh"}, /* pointer to a Mesh structure */
- {BMO_OP_SLOT_PTR, "object"}, /* pointer to an Object structure */
- {BMO_OP_SLOT_BOOL, "use_shapekey"}, /* load active shapekey coordinates into verts */
- {0},
+ {
+ /* pointer to a Mesh structure */
+ {"mesh", BMO_OP_SLOT_PTR, {BMO_OP_SLOT_SUBTYPE_PTR_MESH}},
+ /* pointer to an Object structure */
+ {"object", BMO_OP_SLOT_PTR, {BMO_OP_SLOT_SUBTYPE_PTR_OBJECT}},
+ {"use_shapekey", BMO_OP_SLOT_BOOL}, /* load active shapekey coordinates into verts */
+ {{'\0'}},
},
- {{0}}, /* no output */
+ {{{'\0'}}}, /* no output */
bmo_mesh_to_bmesh_exec,
0
};
/*
- * Individual Face Extrude
+ * Individual Face Extrude.
*
* Extrudes faces individually.
*/
static BMOpDefine bmo_extrude_discrete_faces_def = {
"extrude_discrete_faces",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
- {0},
+ {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "faces.out"}, /* output faces */
- {BMO_OP_SLOT_ELEMENT_BUF, "geom_skirt.out"}, /* output skirt geometry, faces and edges */
- {0},
+ {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
+ {{'\0'}},
},
bmo_extrude_discrete_faces_exec,
0
};
/*
- * Extrude Only Edges
+ * Extrude Only Edges.
*
* Extrudes Edges into faces, note that this is very simple, there's no fancy
* winged extrusion.
@@ -728,247 +739,308 @@ static BMOpDefine bmo_extrude_discrete_faces_def = {
static BMOpDefine bmo_extrude_edge_only_def = {
"extrude_edge_only",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input vertices */
- {0},
+ {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input vertices */
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "geom.out"}, /* output geometry */
- {0},
+ {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* output geometry */
+ {{'\0'}},
},
bmo_extrude_edge_only_exec,
0
};
/*
- * Individual Vertex Extrude
+ * Individual Vertex Extrude.
*
* Extrudes wire edges from vertices.
*/
static BMOpDefine bmo_extrude_vert_indiv_def = {
"extrude_vert_indiv",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertices */
- {0},
+ {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "edges.out"}, /* output wire edges */
- {BMO_OP_SLOT_ELEMENT_BUF, "verts.out"}, /* output vertices */
- {0},
+ {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* output wire edges */
+ {"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output vertices */
+ {{'\0'}},
},
bmo_extrude_vert_indiv_exec,
0
};
+/*
+ * Connect Verts.
+ *
+ * Split faces by adding edges that connect **verts**.
+ */
static BMOpDefine bmo_connect_verts_def = {
"connect_verts",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "verts"},
- {0},
+ {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "edges.out"},
- {0},
+ {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
+ {{'\0'}},
},
bmo_connect_verts_exec,
BMO_OP_FLAG_UNTAN_MULTIRES
};
+/*
+ * Extrude Faces.
+ *
+ * Extrude operator (does not transform)
+ */
static BMOpDefine bmo_extrude_face_region_def = {
"extrude_face_region",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "geom"}, /* edges and faces */
- {BMO_OP_SLOT_MAPPING, "edges_exclude"},
- {BMO_OP_SLOT_BOOL, "use_keep_orig"}, /* keep original geometry */
- {0},
+ {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* edges and faces */
+ {"edges_exclude", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_EMPTY}},
+ {"use_keep_orig", BMO_OP_SLOT_BOOL}, /* keep original geometry */
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "geom.out"},
- {0},
+ {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+ {{'\0'}},
},
bmo_extrude_face_region_exec,
0
};
+/*
+ * Dissolve Verts.
+ */
static BMOpDefine bmo_dissolve_verts_def = {
"dissolve_verts",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "verts"},
- {0},
+ {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},
+ {{'\0'}},
},
- {{0}}, /* no output */
+ {{{'\0'}}}, /* no output */
bmo_dissolve_verts_exec,
BMO_OP_FLAG_UNTAN_MULTIRES
};
+/*
+ * Dissolve Edges.
+ */
static BMOpDefine bmo_dissolve_edges_def = {
"dissolve_edges",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "edges"},
- {BMO_OP_SLOT_BOOL, "use_verts"}, /* dissolve verts left between only 2 edges. */
- {0},
+ {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
+ {"use_verts", BMO_OP_SLOT_BOOL}, /* dissolve verts left between only 2 edges. */
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "region.out"},
- {0},
+ {{"region.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
+ {{'\0'}},
},
bmo_dissolve_edges_exec,
BMO_OP_FLAG_UNTAN_MULTIRES
};
+/*
+ * Dissolve Edge Loop.
+ */
static BMOpDefine bmo_dissolve_edge_loop_def = {
"dissolve_edge_loop",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "edges"},
- {0},
+ {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "region.out"},
- {0},
+ {{"region.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
+ {{'\0'}},
},
bmo_dissolve_edgeloop_exec,
BMO_OP_FLAG_UNTAN_MULTIRES
};
+/*
+ * Dissolve Faces.
+ */
static BMOpDefine bmo_dissolve_faces_def = {
"dissolve_faces",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "faces"},
- {BMO_OP_SLOT_BOOL, "use_verts"}, /* dissolve verts left between only 2 edges. */
- {0},
+ {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
+ {"use_verts", BMO_OP_SLOT_BOOL}, /* dissolve verts left between only 2 edges. */
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "region.out"},
- {0},
+ {{"region.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
+ {{'\0'}},
},
bmo_dissolve_faces_exec,
BMO_OP_FLAG_UNTAN_MULTIRES
};
+/*
+ * Limited Dissolve.
+ *
+ * Dissolve planar faces and co-linear edges.
+ */
static BMOpDefine bmo_dissolve_limit_def = {
"dissolve_limit",
/* slots_in */
- {{BMO_OP_SLOT_FLT, "angle_limit"}, /* total rotation angle (degrees) */
- {BMO_OP_SLOT_BOOL, "use_dissolve_boundaries"},
- {BMO_OP_SLOT_ELEMENT_BUF, "verts"},
- {BMO_OP_SLOT_ELEMENT_BUF, "edges"},
- {0},
+ {{"angle_limit", BMO_OP_SLOT_FLT}, /* total rotation angle (radians) */
+ {"use_dissolve_boundaries", BMO_OP_SLOT_BOOL},
+ {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},
+ {"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
+ {{'\0'}},
},
- {{0}}, /* no output */
+ {{{'\0'}}}, /* no output */
bmo_dissolve_limit_exec,
BMO_OP_FLAG_UNTAN_MULTIRES
};
+/*
+ * Triangulate.
+ */
static BMOpDefine bmo_triangulate_def = {
"triangulate",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "faces"},
- {BMO_OP_SLOT_BOOL, "use_beauty"},
- {0},
+ {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
+ {"use_beauty", BMO_OP_SLOT_BOOL},
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "edges.out"},
- {BMO_OP_SLOT_ELEMENT_BUF, "faces.out"},
- {BMO_OP_SLOT_MAPPING, "facemap.out"},
- {0},
+ {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
+ {"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
+ {"face_map.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
+ {{'\0'}},
},
bmo_triangulate_exec,
BMO_OP_FLAG_UNTAN_MULTIRES
};
+/*
+ * Un-Subdivide.
+ *
+ * Reduce detail in geometry containing grids.
+ */
static BMOpDefine bmo_unsubdivide_def = {
"unsubdivide",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertices */
- {BMO_OP_SLOT_INT, "iterations"},
- {0},
+ {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
+ {"iterations", BMO_OP_SLOT_INT},
+ {{'\0'}},
},
- {{0}}, /* no output */
+ {{{'\0'}}}, /* no output */
bmo_unsubdivide_exec,
BMO_OP_FLAG_UNTAN_MULTIRES
};
+/*
+ * Subdivide Edges.
+ *
+ * Advanced operator for subdividing edges
+ * with options for face patterns, smoothing and randomization.
+ */
static BMOpDefine bmo_subdivide_edges_def = {
"subdivide_edges",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "edges"},
- {BMO_OP_SLOT_FLT, "smooth"},
- {BMO_OP_SLOT_FLT, "fractal"},
- {BMO_OP_SLOT_FLT, "along_normal"},
- {BMO_OP_SLOT_INT, "cuts"},
- {BMO_OP_SLOT_INT, "seed"},
- {BMO_OP_SLOT_MAPPING, "custompatterns"},
- {BMO_OP_SLOT_MAPPING, "edgepercents"},
-
- {BMO_OP_SLOT_INT, "quad_corner_type"}, /* quad corner type, see bmesh_operators.h */
- {BMO_OP_SLOT_BOOL, "use_gridfill"}, /* fill in fully-selected faces with a grid */
- {BMO_OP_SLOT_BOOL, "use_singleedge"}, /* tessellate the case of one edge selected in a quad or triangle */
- {BMO_OP_SLOT_BOOL, "use_sphere"}, /* for making new primitives only */
- {0},
+ {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
+ {"smooth", BMO_OP_SLOT_FLT},
+ {"fractal", BMO_OP_SLOT_FLT},
+ {"along_normal", BMO_OP_SLOT_FLT},
+ {"cuts", BMO_OP_SLOT_INT},
+ {"seed", BMO_OP_SLOT_INT},
+ {"custom_patterns", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL}}, /* uses custom pointers */
+ {"edge_percents", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_FLT}},
+
+ {"quad_corner_type", BMO_OP_SLOT_INT}, /* quad corner type, see bmesh_operators.h */
+ {"use_grid_fill", BMO_OP_SLOT_BOOL}, /* fill in fully-selected faces with a grid */
+ {"use_single_edge", BMO_OP_SLOT_BOOL}, /* tessellate the case of one edge selected in a quad or triangle */
+ {"use_only_quads", BMO_OP_SLOT_BOOL}, /* only subdivide quads (for loopcut) */
+ {"use_sphere", BMO_OP_SLOT_BOOL}, /* for making new primitives only */
+ {{'\0'}},
},
/* slots_out */
{/* these next three can have multiple types of elements in them */
- {BMO_OP_SLOT_ELEMENT_BUF, "geom_inner.out"},
- {BMO_OP_SLOT_ELEMENT_BUF, "geom_split.out"},
- {BMO_OP_SLOT_ELEMENT_BUF, "geom.out"}, /* contains all output geometr */
- {0},
+ {"geom_inner.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+ {"geom_split.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+ {"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* contains all output geometr */
+ {{'\0'}},
},
bmo_subdivide_edges_exec,
BMO_OP_FLAG_UNTAN_MULTIRES
};
+/*
+ * Delete Geometry.
+ *
+ * Utility operator to delete geometry.
+ */
static BMOpDefine bmo_delete_def = {
"delete",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "geom"},
- {BMO_OP_SLOT_INT, "context"},
- {0},
+ {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+ {"context", BMO_OP_SLOT_INT}, /* enum DEL_VERTS ... */
+ {{'\0'}},
},
- {{0}}, /* no output */
+ {{{'\0'}}}, /* no output */
bmo_delete_exec,
0
};
+/*
+ * Duplicate Geometry.
+ *
+ * Utility operator to duplicate geometry,
+ * optionally into a destination mesh.
+ */
static BMOpDefine bmo_duplicate_def = {
"duplicate",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "geom"},
- {BMO_OP_SLOT_PTR, "dest"}, /* destination bmesh, if NULL will use current on */
- {0},
+ {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+ /* destination bmesh, if NULL will use current on */
+ {"dest", BMO_OP_SLOT_PTR, {BMO_OP_SLOT_SUBTYPE_PTR_BMESH}},
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "geom_orig.out"},
- {BMO_OP_SLOT_ELEMENT_BUF, "geom.out"},
+ {{"geom_orig.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+ {"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
/* facemap maps from source faces to dupe
* faces, and from dupe faces to source faces */
- {BMO_OP_SLOT_MAPPING, "facemap.out"},
- {BMO_OP_SLOT_MAPPING, "boundarymap.out"},
- {BMO_OP_SLOT_MAPPING, "isovertmap.out"},
- {0},
+ {"face_map.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
+ {"boundary_map.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
+ {"isovert_map.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
+ {{'\0'}},
},
bmo_duplicate_exec,
0
};
+/*
+ * Split Off Geometry.
+ *
+ * Disconnect geometry from adjacent edges and faces,
+ * optionally into a destination mesh.
+ */
static BMOpDefine bmo_split_def = {
"split",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "geom"},
- {BMO_OP_SLOT_PTR, "dest"}, /* destination bmesh, if NULL will use current one */
- {BMO_OP_SLOT_BOOL, "use_only_faces"}, /* when enabled. don't duplicate loose verts/edges */
- {0},
+ {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+ /* destination bmesh, if NULL will use current one */
+ {"dest", BMO_OP_SLOT_PTR, {BMO_OP_SLOT_SUBTYPE_PTR_BMESH}},
+ {"use_only_faces", BMO_OP_SLOT_BOOL}, /* when enabled. don't duplicate loose verts/edges */
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "geom.out"},
- {BMO_OP_SLOT_MAPPING, "boundarymap.out"},
- {BMO_OP_SLOT_MAPPING, "isovertmap.out"},
- {0},
+ {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+ {"boundary_map.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
+ {"isovert_map.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
+ {{'\0'}},
},
bmo_split_exec,
0
};
/*
- * Spin
+ * Spin.
*
* Extrude or duplicate geometry a number of times,
* rotating and possibly translating after each step
@@ -976,18 +1048,18 @@ static BMOpDefine bmo_split_def = {
static BMOpDefine bmo_spin_def = {
"spin",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "geom"},
- {BMO_OP_SLOT_VEC, "cent"}, /* rotation center */
- {BMO_OP_SLOT_VEC, "axis"}, /* rotation axis */
- {BMO_OP_SLOT_VEC, "dvec"}, /* translation delta per step */
- {BMO_OP_SLOT_FLT, "angle"}, /* total rotation angle (degrees) */
- {BMO_OP_SLOT_INT, "steps"}, /* number of steps */
- {BMO_OP_SLOT_BOOL, "use_duplicate"}, /* duplicate or extrude? */
- {0},
+ {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+ {"cent", BMO_OP_SLOT_VEC}, /* rotation center */
+ {"axis", BMO_OP_SLOT_VEC}, /* rotation axis */
+ {"dvec", BMO_OP_SLOT_VEC}, /* translation delta per step */
+ {"angle", BMO_OP_SLOT_FLT}, /* total rotation angle (radians) */
+ {"steps", BMO_OP_SLOT_INT}, /* number of steps */
+ {"use_duplicate", BMO_OP_SLOT_BOOL}, /* duplicate or extrude? */
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "geom_last.out"}, /* result of last step */
- {0},
+ {{"geom_last.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* result of last step */
+ {{'\0'}},
},
bmo_spin_exec,
0
@@ -995,486 +1067,490 @@ static BMOpDefine bmo_spin_def = {
/*
- * Similar faces search
+ * Similar Faces Search.
*
* Find similar faces (area/material/perimeter, ...).
*/
static BMOpDefine bmo_similar_faces_def = {
"similar_faces",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
- {BMO_OP_SLOT_INT, "type"}, /* type of selection */
- {BMO_OP_SLOT_FLT, "thresh"}, /* threshold of selection */
- {BMO_OP_SLOT_INT, "compare"}, /* comparison method */
- {0},
+ {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
+ {"type", BMO_OP_SLOT_INT}, /* type of selection */
+ {"thresh", BMO_OP_SLOT_FLT}, /* threshold of selection */
+ {"compare", BMO_OP_SLOT_INT}, /* comparison method */
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "faces.out"}, /* output faces */
- {0},
+ {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
+ {{'\0'}},
},
bmo_similar_faces_exec,
0
};
/*
- * Similar edges search
+ * Similar Edges Search.
*
* Find similar edges (length, direction, edge, seam, ...).
*/
static BMOpDefine bmo_similar_edges_def = {
"similar_edges",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edges */
- {BMO_OP_SLOT_INT, "type"}, /* type of selection */
- {BMO_OP_SLOT_FLT, "thresh"}, /* threshold of selection */
- {BMO_OP_SLOT_INT, "compare"}, /* comparison method */
- {0},
+ {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
+ {"type", BMO_OP_SLOT_INT}, /* type of selection */
+ {"thresh", BMO_OP_SLOT_FLT}, /* threshold of selection */
+ {"compare", BMO_OP_SLOT_INT}, /* comparison method */
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "edges.out"}, /* output edges */
- {0},
+ {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* output edges */
+ {{'\0'}},
},
bmo_similar_edges_exec,
0
};
/*
- * Similar vertices search
+ * Similar Verts Search.
*
* Find similar vertices (normal, face, vertex group, ...).
*/
static BMOpDefine bmo_similar_verts_def = {
"similar_verts",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertices */
- {BMO_OP_SLOT_INT, "type"}, /* type of selection */
- {BMO_OP_SLOT_FLT, "thresh"}, /* threshold of selection */
- {BMO_OP_SLOT_INT, "compare"}, /* comparison method */
- {0},
+ {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
+ {"type", BMO_OP_SLOT_INT}, /* type of selection */
+ {"thresh", BMO_OP_SLOT_FLT}, /* threshold of selection */
+ {"compare", BMO_OP_SLOT_INT}, /* comparison method */
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "verts.out"}, /* output vertices */
- {0},
+ {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output vertices */
+ {{'\0'}},
},
bmo_similar_verts_exec,
0
};
/*
- * uv rotation
- * cycle the uvs
+ * UV Rotation.
+ *
+ * Cycle the loop UV's
*/
static BMOpDefine bmo_rotate_uvs_def = {
"rotate_uvs",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
- {BMO_OP_SLOT_BOOL, "use_ccw"}, /* rotate counter-clockwise if true, othewise clockwise */
- {0},
+ {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
+ {"use_ccw", BMO_OP_SLOT_BOOL}, /* rotate counter-clockwise if true, otherwise clockwise */
+ {{'\0'}},
},
/* slots_out */
- {{0}}, /* no output */
+ {{{'\0'}}}, /* no output */
bmo_rotate_uvs_exec,
0
};
/*
- * uv reverse
- * reverse the uvs
+ * UV Reverse.
+ *
+ * Reverse the UV's
*/
static BMOpDefine bmo_reverse_uvs_def = {
"reverse_uvs",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
- {0},
+ {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
+ {{'\0'}},
},
- {{0}}, /* no output */
+ {{{'\0'}}}, /* no output */
bmo_reverse_uvs_exec,
0
};
/*
- * color rotation
- * cycle the colors
+ * Color Rotation.
+ *
+ * Cycle the loop colors
*/
static BMOpDefine bmo_rotate_colors_def = {
"rotate_colors",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
- {BMO_OP_SLOT_BOOL, "use_ccw"}, /* rotate counter-clockwise if true, othewise clockwise */
- {0},
+ {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
+ {"use_ccw", BMO_OP_SLOT_BOOL}, /* rotate counter-clockwise if true, otherwise clockwise */
+ {{'\0'}},
},
- {{0}}, /* no output */
+ {{{'\0'}}}, /* no output */
bmo_rotate_colors_exec,
0
};
/*
- * color reverse
- * reverse the colors
+ * Color Reverse
+ *
+ * Reverse the loop colors.
*/
static BMOpDefine bmo_reverse_colors_def = {
"reverse_colors",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
- {0},
+ {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
+ {{'\0'}},
},
- {{0}}, /* no output */
+ {{{'\0'}}}, /* no output */
bmo_reverse_colors_exec,
0
};
/*
- * Similar vertices search
+ * Shortest Path.
*
- * Find similar vertices (normal, face, vertex group, ...).
+ * Select the shortest path between 2 verts.
*/
static BMOpDefine bmo_shortest_path_def = {
"shortest_path",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "startv"}, /* start vertex */
- {BMO_OP_SLOT_ELEMENT_BUF, "endv"}, /* end vertex */
- {BMO_OP_SLOT_INT, "type"}, /* type of selection */
- {0},
+ {{"vert_start", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE}}, /* start vertex */
+ {"vert_end", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE}}, /* end vertex */
+ {"type", BMO_OP_SLOT_INT}, /* type of selection */
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "verts.out"}, /* output vertices */
- {0},
+ {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output vertices */
+ {{'\0'}},
},
bmo_shortest_path_exec,
0
};
/*
- * Edge Split
+ * Edge Split.
*
* Disconnects faces along input edges.
*/
static BMOpDefine bmo_split_edges_def = {
"split_edges",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edges */
+ {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
/* needed for vertex rip so we can rip only half an edge at a boundary wich would otherwise split off */
- {BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* optional tag verts, use to have greater control of splits */
- {BMO_OP_SLOT_BOOL, "use_verts"}, /* use 'verts' for splitting, else just find verts to split from edges */
- {0},
+ {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* optional tag verts, use to have greater control of splits */
+ {"use_verts", BMO_OP_SLOT_BOOL}, /* use 'verts' for splitting, else just find verts to split from edges */
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "edges.out"}, /* old output disconnected edges */
- {0},
+ {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* old output disconnected edges */
+ {{'\0'}},
},
bmo_split_edges_exec,
BMO_OP_FLAG_UNTAN_MULTIRES
};
/*
- * Create Grid
+ * Create Grid.
*
* Creates a grid with a variable number of subdivisions
*/
static BMOpDefine bmo_create_grid_def = {
"create_grid",
/* slots_in */
- {{BMO_OP_SLOT_INT, "x_segments"}, /* number of x segments */
- {BMO_OP_SLOT_INT, "y_segments"}, /* number of y segments */
- {BMO_OP_SLOT_FLT, "size"}, /* size of the grid */
- {BMO_OP_SLOT_MAT, "mat"}, /* matrix to multiply the new geometry with */
- {0},
+ {{"x_segments", BMO_OP_SLOT_INT}, /* number of x segments */
+ {"y_segments", BMO_OP_SLOT_INT}, /* number of y segments */
+ {"size", BMO_OP_SLOT_FLT}, /* size of the grid */
+ {"matrix", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "verts.out"}, /* output verts */
- {0},
+ {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
+ {{'\0'}},
},
bmo_create_grid_exec,
0,
};
/*
- * Create UV Sphere
+ * Create UV Sphere.
*
* Creates a grid with a variable number of subdivisions
*/
static BMOpDefine bmo_create_uvsphere_def = {
"create_uvsphere",
/* slots_in */
- {{BMO_OP_SLOT_INT, "u_segments"}, /* number of u segments */
- {BMO_OP_SLOT_INT, "v_segments"}, /* number of v segment */
- {BMO_OP_SLOT_FLT, "diameter"}, /* diameter */
- {BMO_OP_SLOT_MAT, "mat"}, /* matrix to multiply the new geometry with */
- {0},
+ {{"u_segments", BMO_OP_SLOT_INT}, /* number of u segments */
+ {"v_segments", BMO_OP_SLOT_INT}, /* number of v segment */
+ {"diameter", BMO_OP_SLOT_FLT}, /* diameter */
+ {"matrix", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "verts.out"}, /* output verts */
- {0},
+ {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
+ {{'\0'}},
},
bmo_create_uvsphere_exec,
0,
};
/*
- * Create Ico Sphere
+ * Create Ico-Sphere.
*
* Creates a grid with a variable number of subdivisions
*/
static BMOpDefine bmo_create_icosphere_def = {
"create_icosphere",
/* slots_in */
- {{BMO_OP_SLOT_INT, "subdivisions"}, /* how many times to recursively subdivide the sphere */
- {BMO_OP_SLOT_FLT, "diameter"}, /* diameter */
- {BMO_OP_SLOT_MAT, "mat"}, /* matrix to multiply the new geometry with */
- {0},
+ {{"subdivisions", BMO_OP_SLOT_INT}, /* how many times to recursively subdivide the sphere */
+ {"diameter", BMO_OP_SLOT_FLT}, /* diameter */
+ {"matrix", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "verts.out"}, /* output verts */
- {0},
+ {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
+ {{'\0'}},
},
bmo_create_icosphere_exec,
0,
};
/*
- * Create Suzanne
+ * Create Suzanne.
*
- * Creates a monkey. Be wary.
+ * Creates a monkey (standard blender primitive).
*/
static BMOpDefine bmo_create_monkey_def = {
"create_monkey",
/* slots_in */
- {{BMO_OP_SLOT_MAT, "mat"}, /* matrix to multiply the new geometry with */
- {0},
+ {{"matrix", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "verts.out"}, /* output verts */
- {0},
+ {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
+ {{'\0'}},
},
bmo_create_monkey_exec,
0,
};
/*
- * Create Cone
+ * Create Cone.
*
* Creates a cone with variable depth at both ends
*/
static BMOpDefine bmo_create_cone_def = {
"create_cone",
/* slots_in */
- {{BMO_OP_SLOT_BOOL, "cap_ends"}, /* wheter or not to fill in the ends with faces */
- {BMO_OP_SLOT_BOOL, "cap_tris"}, /* fill ends with triangles instead of ngons */
- {BMO_OP_SLOT_INT, "segments"},
- {BMO_OP_SLOT_FLT, "diameter1"}, /* diameter of one end */
- {BMO_OP_SLOT_FLT, "diameter2"}, /* diameter of the opposite */
- {BMO_OP_SLOT_FLT, "depth"}, /* distance between ends */
- {BMO_OP_SLOT_MAT, "mat"}, /* matrix to multiply the new geometry with */
- {0},
+ {{"cap_ends", BMO_OP_SLOT_BOOL}, /* whether or not to fill in the ends with faces */
+ {"cap_tris", BMO_OP_SLOT_BOOL}, /* fill ends with triangles instead of ngons */
+ {"segments", BMO_OP_SLOT_INT},
+ {"diameter1", BMO_OP_SLOT_FLT}, /* diameter of one end */
+ {"diameter2", BMO_OP_SLOT_FLT}, /* diameter of the opposite */
+ {"depth", BMO_OP_SLOT_FLT}, /* distance between ends */
+ {"matrix", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "verts.out"}, /* output verts */
- {0},
+ {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
+ {{'\0'}},
},
bmo_create_cone_exec,
0,
};
/*
- * Creates a circle
+ * Creates a Circle.
*/
static BMOpDefine bmo_create_circle_def = {
"create_circle",
/* slots_in */
- {{BMO_OP_SLOT_BOOL, "cap_ends"}, /* wheter or not to fill in the ends with faces */
- {BMO_OP_SLOT_BOOL, "cap_tris"}, /* fill ends with triangles instead of ngons */
- {BMO_OP_SLOT_INT, "segments"},
- {BMO_OP_SLOT_FLT, "diameter"}, /* diameter of one end */
- {BMO_OP_SLOT_MAT, "mat"}, /* matrix to multiply the new geometry with */
- {0},
+ {{"cap_ends", BMO_OP_SLOT_BOOL}, /* whether or not to fill in the ends with faces */
+ {"cap_tris", BMO_OP_SLOT_BOOL}, /* fill ends with triangles instead of ngons */
+ {"segments", BMO_OP_SLOT_INT},
+ {"diameter", BMO_OP_SLOT_FLT}, /* diameter of one end */
+ {"matrix", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "verts.out"}, /* output verts */
- {0},
+ {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
+ {{'\0'}},
},
bmo_create_circle_exec,
0,
};
/*
- * Create Cone
+ * Create Cube
*
- * Creates a cone with variable depth at both ends
+ * Creates a cube.
*/
static BMOpDefine bmo_create_cube_def = {
"create_cube",
/* slots_in */
- {{BMO_OP_SLOT_FLT, "size"}, /* size of the cube */
- {BMO_OP_SLOT_MAT, "mat"}, /* matrix to multiply the new geometry with */
- {0},
+ {{"size", BMO_OP_SLOT_FLT}, /* size of the cube */
+ {"matrix", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "verts.out"}, /* output verts */
- {0},
+ {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
+ {{'\0'}},
},
bmo_create_cube_exec,
0,
};
/*
- * Bevel
+ * Bevel.
*
* Bevels edges and vertices
*/
static BMOpDefine bmo_bevel_def = {
"bevel",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "geom"}, /* input edges and vertices */
- {BMO_OP_SLOT_FLT, "offset"}, /* amount to offset beveled edge */
- {BMO_OP_SLOT_INT, "segments"}, /* number of segments in bevel */
- {0},
+ {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* input edges and vertices */
+ {"offset", BMO_OP_SLOT_FLT}, /* amount to offset beveled edge */
+ {"segments", BMO_OP_SLOT_INT}, /* number of segments in bevel */
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "faces.out"}, /* output faces */
- {0},
- },
-#if 0 /* old bevel*/
- {{BMO_OP_SLOT_ELEMENT_BUF, "geom"}, /* input edges and vertices */
- {BMO_OP_SLOT_ELEMENT_BUF, "face_spans"}, /* new geometry */
- {BMO_OP_SLOT_ELEMENT_BUF, "face_holes"}, /* new geometry */
- {BMO_OP_SLOT_BOOL, "use_lengths"}, /* grab edge lengths from a PROP_FLT customdata layer */
- {BMO_OP_SLOT_BOOL, "use_even"}, /* corner vert placement: use shell/angle calculations */
- {BMO_OP_SLOT_BOOL, "use_dist"}, /* corner vert placement: evaluate percent as a distance,
- * modifier uses this. We could do this as another float setting */
- {BMO_OP_SLOT_INT, "lengthlayer"}, /* which PROP_FLT layer to us */
- {BMO_OP_SLOT_FLT, "percent"}, /* percentage to expand beveled edge */
- {0},
- },
-#endif
+ {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
+ {{'\0'}},
+ },
+/* old bevel*/
+// {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* input edges and vertices */
+// {"face_spans", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* new geometry */
+// {"face_holes", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* new geometry */
+// {"use_lengths", BMO_OP_SLOT_BOOL}, /* grab edge lengths from a PROP_FLT customdata layer */
+// {"use_even", BMO_OP_SLOT_BOOL}, /* corner vert placement: use shell/angle calculations */
+// {"use_dist", BMO_OP_SLOT_BOOL}, /* corner vert placement: evaluate percent as a distance,
+// * modifier uses this. We could do this as another float setting */
+// {"lengthlayer", BMO_OP_SLOT_INT}, /* which PROP_FLT layer to us */
+// {"percent", BMO_OP_SLOT_FLT}, /* percentage to expand beveled edge */
+// {{'\0'}},
+// },
+
bmo_bevel_exec,
BMO_OP_FLAG_UNTAN_MULTIRES
};
/*
- * Beautify Fill
+ * Beautify Fill.
*
- * Makes triangle a bit nicer
+ * Rotate edges to create more evenly spaced triangles.
*/
static BMOpDefine bmo_beautify_fill_def = {
"beautify_fill",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
- {BMO_OP_SLOT_ELEMENT_BUF, "constrain_edges"}, /* edges that can't be flipped */
- {0},
+ {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
+ {"constrain_edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* edges that can't be flipped */
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "geom.out"}, /* new flipped faces and edges */
- {0},
+ {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* new flipped faces and edges */
+ {{'\0'}},
},
bmo_beautify_fill_exec,
BMO_OP_FLAG_UNTAN_MULTIRES
};
/*
- * Triangle Fill
+ * Triangle Fill.
*
* Fill edges with triangles
*/
static BMOpDefine bmo_triangle_fill_def = {
"triangle_fill",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edges */
- {0},
+ {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "geom.out"}, /* new faces and edges */
- {0},
+ {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* new faces and edges */
+ {{'\0'}},
},
bmo_triangle_fill_exec,
BMO_OP_FLAG_UNTAN_MULTIRES
};
/*
- * Solidify
+ * Solidify.
*
* Turns a mesh into a shell with thickness
*/
static BMOpDefine bmo_solidify_def = {
"solidify",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "geom"},
- {BMO_OP_SLOT_FLT, "thickness"},
- {0},
+ {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+ {"thickness", BMO_OP_SLOT_FLT},
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "geom.out"},
- {0},
+ {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+ {{'\0'}},
},
bmo_solidify_face_region_exec,
0
};
/*
- * Face Inset
+ * Face Inset.
*
- * Extrudes faces individually.
+ * Inset or outset faces.
*/
static BMOpDefine bmo_inset_def = {
"inset",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
- {BMO_OP_SLOT_BOOL, "use_boundary"},
- {BMO_OP_SLOT_BOOL, "use_even_offset"},
- {BMO_OP_SLOT_BOOL, "use_relative_offset"},
- {BMO_OP_SLOT_FLT, "thickness"},
- {BMO_OP_SLOT_FLT, "depth"},
- {BMO_OP_SLOT_BOOL, "use_outset"},
- {0},
+ {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
+ {"use_boundary", BMO_OP_SLOT_BOOL},
+ {"use_even_offset", BMO_OP_SLOT_BOOL},
+ {"use_relative_offset", BMO_OP_SLOT_BOOL},
+ {"thickness", BMO_OP_SLOT_FLT},
+ {"depth", BMO_OP_SLOT_FLT},
+ {"use_outset", BMO_OP_SLOT_BOOL},
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "faces.out"}, /* output faces */
- {0},
+ {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
+ {{'\0'}},
},
bmo_inset_exec,
0
};
/*
- * Wire Frame
+ * Wire Frame.
*
- * Makes a wire copy of faces.
+ * Makes a wire-frame copy of faces.
*/
static BMOpDefine bmo_wireframe_def = {
"wireframe",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
- {BMO_OP_SLOT_BOOL, "use_boundary"},
- {BMO_OP_SLOT_BOOL, "use_even_offset"},
- {BMO_OP_SLOT_BOOL, "use_crease"},
- {BMO_OP_SLOT_FLT, "thickness"},
- {BMO_OP_SLOT_BOOL, "use_relative_offset"},
- {BMO_OP_SLOT_FLT, "depth"},
- {0},
+ {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
+ {"use_boundary", BMO_OP_SLOT_BOOL},
+ {"use_even_offset", BMO_OP_SLOT_BOOL},
+ {"use_crease", BMO_OP_SLOT_BOOL},
+ {"thickness", BMO_OP_SLOT_FLT},
+ {"use_relative_offset", BMO_OP_SLOT_BOOL},
+ {"depth", BMO_OP_SLOT_FLT},
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "faces.out"}, /* output faces */
- {0},
+ {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
+ {{'\0'}},
},
bmo_wireframe_exec,
0
};
/*
- * Vertex Slide
+ * Vertex Slide.
*
- * Translates vertes along an edge
+ * Translates verts along an edge
*/
static BMOpDefine bmo_slide_vert_def = {
"slide_vert",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "vert"},
- {BMO_OP_SLOT_ELEMENT_BUF, "edge"},
- {BMO_OP_SLOT_FLT, "distance_t"},
- {0},
+ {{"vert", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE}},
+ {"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
+ {"factor", BMO_OP_SLOT_FLT},
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "verts.out"},
- {0},
+ {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},
+ {{'\0'}},
},
bmo_slide_vert_exec,
BMO_OP_FLAG_UNTAN_MULTIRES
@@ -1499,16 +1575,16 @@ static BMOpDefine bmo_slide_vert_def = {
static BMOpDefine bmo_convex_hull_def = {
"convex_hull",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "input"},
- {BMO_OP_SLOT_BOOL, "use_existing_faces"},
- {0},
+ {{"input", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+ {"use_existing_faces", BMO_OP_SLOT_BOOL},
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "geom.out"},
- {BMO_OP_SLOT_ELEMENT_BUF, "geom_interior.out"},
- {BMO_OP_SLOT_ELEMENT_BUF, "geom_unused.out"},
- {BMO_OP_SLOT_ELEMENT_BUF, "geom_holes.out"},
- {0},
+ {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+ {"geom_interior.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+ {"geom_unused.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+ {"geom_holes.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+ {{'\0'}},
},
bmo_convex_hull_exec,
0
@@ -1516,9 +1592,9 @@ static BMOpDefine bmo_convex_hull_def = {
#endif
/*
- * Symmetrize
+ * Symmetrize.
*
- * Mekes the mesh elements in the "input" slot symmetrical. Unlike
+ * Makes the mesh elements in the "input" slot symmetrical. Unlike
* normal mirroring, it only copies in one direction, as specified by
* the "direction" slot. The edges and faces that cross the plane of
* symmetry are split as needed to enforce symmetry.
@@ -1528,19 +1604,19 @@ static BMOpDefine bmo_convex_hull_def = {
static BMOpDefine bmo_symmetrize_def = {
"symmetrize",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "input"},
- {BMO_OP_SLOT_INT, "direction"},
- {0},
+ {{"input", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+ {"direction", BMO_OP_SLOT_INT},
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "geom.out"},
- {0},
+ {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+ {{'\0'}},
},
bmo_symmetrize_exec,
0
};
-BMOpDefine *opdefines[] = {
+const BMOpDefine *bmo_opdefines[] = {
&bmo_automerge_def,
&bmo_average_vert_facedata_def,
&bmo_beautify_fill_def,
@@ -1615,7 +1691,6 @@ BMOpDefine *opdefines[] = {
&bmo_unsubdivide_def,
&bmo_weld_verts_def,
&bmo_wireframe_def,
-
};
-int bmesh_total_ops = (sizeof(opdefines) / sizeof(void *));
+const int bmo_opdefines_total = (sizeof(bmo_opdefines) / sizeof(void *));
diff --git a/source/blender/bmesh/intern/bmesh_operator_api.h b/source/blender/bmesh/intern/bmesh_operator_api.h
index b87e023e63a..7df9c94a2f1 100644
--- a/source/blender/bmesh/intern/bmesh_operator_api.h
+++ b/source/blender/bmesh/intern/bmesh_operator_api.h
@@ -91,15 +91,15 @@ BLI_INLINE void _bmo_elem_flag_toggle( BMesh *bm, BMFlagLayer *oflags, const
/* slot type arrays are terminated by the last member
* having a slot type of 0 */
-enum {
- BMO_OP_SLOT_SENTINEL = 0,
+typedef enum eBMOpSlotType {
+ /* BMO_OP_SLOT_SENTINEL = 0, */
BMO_OP_SLOT_BOOL = 1,
BMO_OP_SLOT_INT = 2,
BMO_OP_SLOT_FLT = 3,
/* normally store pointers to object, scene,
* _never_ store arrays corresponding to mesh elements with this */
- BMO_OP_SLOT_PTR = 4,
+ BMO_OP_SLOT_PTR = 4, /* requres subtype BMO_OP_SLOT_SUBTYPE_PTR_xxx */
BMO_OP_SLOT_MAT = 5,
BMO_OP_SLOT_VEC = 8,
@@ -108,16 +108,47 @@ enum {
*
* it's very important this remain a power of two */
BMO_OP_SLOT_ELEMENT_BUF = 9, /* list of verts/edges/faces */
- BMO_OP_SLOT_MAPPING = 10 /* simple hash map */
-};
+ BMO_OP_SLOT_MAPPING = 10 /* simple hash map, requres subtype BMO_OP_SLOT_SUBTYPE_MAP_xxx */
+} eBMOpSlotType;
#define BMO_OP_SLOT_TOTAL_TYPES 11
+/* don't overlap values to avoid confusion */
+typedef enum eBMOpSlotSubType_Elem {
+ /* use as flags */
+ BMO_OP_SLOT_SUBTYPE_ELEM_VERT = BM_VERT,
+ BMO_OP_SLOT_SUBTYPE_ELEM_EDGE = BM_EDGE,
+ BMO_OP_SLOT_SUBTYPE_ELEM_FACE = BM_FACE,
+ BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE = (BM_FACE << 1),
+} eBMOpSlotSubType_Elem;
+typedef enum eBMOpSlotSubType_Map {
+ BMO_OP_SLOT_SUBTYPE_MAP_EMPTY = 64, /* use as a set(), unused value */
+ BMO_OP_SLOT_SUBTYPE_MAP_ELEM = 65,
+ BMO_OP_SLOT_SUBTYPE_MAP_FLT = 66,
+ BMO_OP_SLOT_SUBTYPE_MAP_INT = 67,
+ BMO_OP_SLOT_SUBTYPE_MAP_BOOL = 68,
+ BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL = 69, /* python can't convert these */
+} eBMOpSlotSubType_Map;
+typedef enum eBMOpSlotSubType_Ptr {
+ BMO_OP_SLOT_SUBTYPE_PTR_BMESH = 100,
+ BMO_OP_SLOT_SUBTYPE_PTR_SCENE = 101,
+ BMO_OP_SLOT_SUBTYPE_PTR_OBJECT = 102,
+ BMO_OP_SLOT_SUBTYPE_PTR_MESH = 103,
+} eBMOpSlotSubType_Ptr;
+
+typedef union eBMOpSlotSubType_Union {
+ eBMOpSlotSubType_Elem elem;
+ eBMOpSlotSubType_Ptr ptr;
+ eBMOpSlotSubType_Map map;
+} eBMOpSlotSubType_Union;
+
/* please ignore all these structures, don't touch them in tool code, except
* for when your defining an operator with BMOpDefine.*/
typedef struct BMOpSlot {
const char *slot_name; /* pointer to BMOpDefine.slot_args */
- int slot_type;
+ eBMOpSlotType slot_type;
+ eBMOpSlotSubType_Union slot_subtype;
+
int len;
// int flag; /* UNUSED */
// int index; /* index within slot array */ /* UNUSED */
@@ -166,8 +197,9 @@ enum {
#define MAX_SLOTNAME 32
typedef struct BMOSlotType {
- int type;
char name[MAX_SLOTNAME];
+ eBMOpSlotType type;
+ eBMOpSlotSubType_Union subtype;
} BMOSlotType;
typedef struct BMOpDefine {
@@ -208,43 +240,6 @@ int BMO_mesh_enabled_flag_count(BMesh *bm, const char htype, const short oflag);
int BMO_mesh_disabled_flag_count(BMesh *bm, const char htype, const short oflag);
/*---------formatted operator initialization/execution-----------*/
-/*
- * this system is used to execute or initialize an operator,
- * using a formatted-string system.
- *
- * for example, BMO_op_callf(bm, BMO_FLAG_DEFAULTS, "delete geom=%hf context=%i", BM_ELEM_SELECT, DEL_FACES);
- * . . .will execute the delete operator, feeding in selected faces, deleting them.
- *
- * the basic format for the format string is:
- * [operatorname] [slot_name]=%[code] [slot_name]=%[code]
- *
- * as in printf, you pass in one additional argument to the function
- * for every code.
- *
- * the formatting codes are:
- * %d - put int in slot
- * %f - put float in slot
- * %p - put pointer in slot
- * %h[f/e/v] - put elements with a header flag in slot.
- * the letters after %h define which element types to use,
- * so e.g. %hf will do faces, %hfe will do faces and edges,
- * %hv will do verts, etc. must pass in at least one
- * element type letter.
- * %H[f/e/v] - same as %h, but tests if the flag is disabled
- * %f[f/e/v] - same as %h, except it deals with tool flags instead of
- * header flags.
- * %F[f/e/v] - same as %f, but tests if the flag is disabled
- * %a[f/e/v] - pass all elements (of types specified by f/e/v) to the
- * slot.
- * %e - pass in a single element.
- * %v - pointer to a float vector of length 3.
- * %m[3/4] - matrix, 3/4 refers to the matrix size, 3 or 4. the
- * corresponding argument must be a pointer to
- * a float matrix.
- * %s - copy a slot from another op, instead of mapping to one
- * argument, it maps to two, a pointer to an operator and
- * a slot name.
- */
void BMO_push(BMesh *bm, BMOperator *op);
void BMO_pop(BMesh *bm);
@@ -385,12 +380,16 @@ void BMO_slot_buffer_from_disabled_hflag(BMesh *bm, BMOperator *op,
BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
const char htype, const char hflag);
+void BMO_slot_buffer_from_single(BMOperator *op, BMOpSlot *slot, BMHeader *ele);
+void *BMO_slot_buffer_get_single(BMOpSlot *slot);
+
+
/* counts number of elements inside a slot array. */
int BMO_slot_buffer_count(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name);
int BMO_slot_map_count(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name);
void BMO_slot_map_insert(BMOperator *op, BMOpSlot *slot,
- const void *element, void *data, int len);
+ const void *element, const void *data, const int len);
/* Counts the number of edges with tool flag toolflag around
*/
@@ -407,15 +406,18 @@ void *BMO_slot_buffer_alloc(BMOperator *op, BMOpSlot slot_args[BMO_OP_MAX_SLOTS]
void BMO_slot_buffer_from_all(BMesh *bm, BMOperator *op, BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
const char *slot_name, const char htype);
-/* this part of the API is used to iterate over element buffer or
+/**
+ * This part of the API is used to iterate over element buffer or
* mapping slots.
*
* for example, iterating over the faces in a slot is:
*
+ * \code{.c}
+ *
* BMOIter oiter;
* BMFace *f;
*
- * f = BMO_iter_new(&oiter, bm, some_operator, "slot_name", BM_FACE);
+ * f = BMO_iter_new(&oiter, some_operator, "slot_name", BM_FACE);
* for (; f; f = BMO_iter_step(&oiter)) {
* /do something with the face
* }
@@ -436,6 +438,7 @@ void BMO_slot_buffer_from_all(BMesh *bm, BMOperator *op, BMOpSlot slot_args[BMO_
* // *((void**)BMO_iter_map_value(&oiter));
* //or something like that.
* }
+ * \endcode
*/
/* contents of this structure are private,
@@ -478,6 +481,9 @@ typedef struct BMOElemMapping {
int len;
} BMOElemMapping;
+/* pointer after BMOElemMapping */
+#define BMO_OP_SLOT_MAPPING_DATA(var) (void *)(((BMOElemMapping *)var) + 1)
+
extern const int BMO_OPSLOT_TYPEINFO[BMO_OP_SLOT_TOTAL_TYPES];
#ifdef __cplusplus
diff --git a/source/blender/bmesh/intern/bmesh_operator_api_inline.h b/source/blender/bmesh/intern/bmesh_operator_api_inline.h
index b405ecc1841..ad116011421 100644
--- a/source/blender/bmesh/intern/bmesh_operator_api_inline.h
+++ b/source/blender/bmesh/intern/bmesh_operator_api_inline.h
@@ -70,14 +70,24 @@ BLI_INLINE void _bmo_elem_flag_toggle(BMesh *bm, BMFlagLayer *oflags, const shor
}
BLI_INLINE void BMO_slot_map_int_insert(BMOperator *op, BMOpSlot *slot,
- void *element, int val)
+ void *element, const int val)
{
+ BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_INT);
+ BMO_slot_map_insert(op, slot, element, &val, sizeof(int));
+}
+
+BLI_INLINE void BMO_slot_map_bool_insert(BMOperator *op, BMOpSlot *slot,
+ void *element, const int val)
+{
+ BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_BOOL);
+ BLI_assert(val == FALSE || val == TRUE);
BMO_slot_map_insert(op, slot, element, &val, sizeof(int));
}
BLI_INLINE void BMO_slot_map_float_insert(BMOperator *op, BMOpSlot *slot,
- void *element, float val)
+ void *element, const float val)
{
+ BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_FLT);
BMO_slot_map_insert(op, slot, element, &val, sizeof(float));
}
@@ -90,9 +100,26 @@ BLI_INLINE void BMO_slot_map_float_insert(BMOperator *op, BMOpSlot *slot,
BLI_INLINE void BMO_slot_map_ptr_insert(BMOperator *op, BMOpSlot *slot,
const void *element, void *val)
{
+ BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL);
BMO_slot_map_insert(op, slot, element, &val, sizeof(void *));
}
+BLI_INLINE void BMO_slot_map_elem_insert(BMOperator *op, BMOpSlot *slot,
+ const void *element, void *val)
+{
+ BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_ELEM);
+ BMO_slot_map_insert(op, slot, element, &val, sizeof(void *));
+}
+
+
+/* no values */
+BLI_INLINE void BMO_slot_map_empty_insert(BMOperator *op, BMOpSlot *slot,
+ const void *element)
+{
+ BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_EMPTY);
+ BMO_slot_map_insert(op, slot, element, NULL, 0);
+}
+
BLI_INLINE int BMO_slot_map_contains(BMOpSlot *slot, const void *element)
{
BLI_assert(slot->slot_type == BMO_OP_SLOT_MAPPING);
@@ -126,7 +153,10 @@ BLI_INLINE void *BMO_slot_map_data_get(BMOpSlot *slot, const void *element)
BLI_INLINE float BMO_slot_map_float_get(BMOpSlot *slot, const void *element)
{
- float *val = (float *) BMO_slot_map_data_get(slot, element);
+ float *val;
+ BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_FLT);
+
+ val = (float *) BMO_slot_map_data_get(slot, element);
if (val) return *val;
return 0.0f;
@@ -134,7 +164,22 @@ BLI_INLINE float BMO_slot_map_float_get(BMOpSlot *slot, const void *element)
BLI_INLINE int BMO_slot_map_int_get(BMOpSlot *slot, const void *element)
{
- int *val = (int *) BMO_slot_map_data_get(slot, element);
+ int *val;
+ BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_INT);
+
+ val = (int *) BMO_slot_map_data_get(slot, element);
+ if (val) return *val;
+
+ return 0;
+}
+
+BLI_INLINE int BMO_slot_map_bool_get(BMOpSlot *slot, const void *element)
+{
+ int *val;
+ BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_BOOL);
+
+ val = (int *) BMO_slot_map_data_get(slot, element);
+ BLI_assert(val == NULL || *val == FALSE || *val == TRUE);
if (val) return *val;
return 0;
@@ -143,6 +188,16 @@ BLI_INLINE int BMO_slot_map_int_get(BMOpSlot *slot, const void *element)
BLI_INLINE void *BMO_slot_map_ptr_get(BMOpSlot *slot, const void *element)
{
void **val = (void **) BMO_slot_map_data_get(slot, element);
+ BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL);
+ if (val) return *val;
+
+ return NULL;
+}
+
+BLI_INLINE void *BMO_slot_map_elem_get(BMOpSlot *slot, const void *element)
+{
+ void **val = (void **) BMO_slot_map_data_get(slot, element);
+ BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_ELEM);
if (val) return *val;
return NULL;
diff --git a/source/blender/bmesh/intern/bmesh_operators.c b/source/blender/bmesh/intern/bmesh_operators.c
index 157837a13c0..ba38f230f0b 100644
--- a/source/blender/bmesh/intern/bmesh_operators.c
+++ b/source/blender/bmesh/intern/bmesh_operators.c
@@ -127,12 +127,13 @@ void BMO_pop(BMesh *bm)
/* use for both slot_types_in and slot_types_out */
-static void bmo_op_slots_init(BMOSlotType *slot_types, BMOpSlot *slot_args)
+static void bmo_op_slots_init(const BMOSlotType *slot_types, BMOpSlot *slot_args)
{
unsigned int i;
for (i = 0; slot_types[i].type; i++) {
- slot_args[i].slot_name = slot_types[i].name;
- slot_args[i].slot_type = slot_types[i].type;
+ slot_args[i].slot_name = slot_types[i].name;
+ slot_args[i].slot_type = slot_types[i].type;
+ slot_args[i].slot_subtype = slot_types[i].subtype;
// slot_args[i].index = i; // UNUSED
}
}
@@ -158,15 +159,15 @@ void BMO_op_init(BMesh *bm, BMOperator *op, const int flag, const char *opname)
memset(op, 0, sizeof(BMOperator));
op->type = opcode;
- op->type_flag = opdefines[opcode]->type_flag;
+ op->type_flag = bmo_opdefines[opcode]->type_flag;
op->flag = flag;
/* initialize the operator slot types */
- bmo_op_slots_init(opdefines[opcode]->slot_types_in, op->slots_in);
- bmo_op_slots_init(opdefines[opcode]->slot_types_out, op->slots_out);
+ bmo_op_slots_init(bmo_opdefines[opcode]->slot_types_in, op->slots_in);
+ bmo_op_slots_init(bmo_opdefines[opcode]->slot_types_out, op->slots_out);
/* callback */
- op->exec = opdefines[opcode]->exec;
+ op->exec = bmo_opdefines[opcode]->exec;
/* memarena, used for operator's slot buffers */
op->arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
@@ -199,7 +200,7 @@ void BMO_op_exec(BMesh *bm, BMOperator *op)
BMO_pop(bm);
}
-static void bmo_op_slots_free(BMOSlotType *slot_types, BMOpSlot *slot_args)
+static void bmo_op_slots_free(const BMOSlotType *slot_types, BMOpSlot *slot_args)
{
BMOpSlot *slot;
unsigned int i;
@@ -220,13 +221,13 @@ static void bmo_op_slots_free(BMOSlotType *slot_types, BMOpSlot *slot_args)
*/
void BMO_op_finish(BMesh *bm, BMOperator *op)
{
- bmo_op_slots_free(opdefines[op->type]->slot_types_in, op->slots_in);
- bmo_op_slots_free(opdefines[op->type]->slot_types_out, op->slots_out);
+ bmo_op_slots_free(bmo_opdefines[op->type]->slot_types_in, op->slots_in);
+ bmo_op_slots_free(bmo_opdefines[op->type]->slot_types_out, op->slots_out);
BLI_memarena_free(op->arena);
#ifdef DEBUG
- BM_ELEM_INDEX_VALIDATE(bm, "post bmo", opdefines[op->type]->opname);
+ BM_ELEM_INDEX_VALIDATE(bm, "post bmo", bmo_opdefines[op->type]->opname);
#else
(void)bm;
#endif
@@ -287,9 +288,49 @@ void _bmo_slot_copy(BMOpSlot slot_args_src[BMO_OP_MAX_SLOTS], const char *slot_n
slot_dst->data.buf = NULL;
slot_dst->len = slot_src->len;
if (slot_dst->len) {
- const int slot_alloc_size = BMO_OPSLOT_TYPEINFO[slot_dst->slot_type] * slot_dst->len;
- slot_dst->data.buf = BLI_memarena_alloc(arena_dst, slot_alloc_size);
- memcpy(slot_dst->data.buf, slot_src->data.buf, slot_alloc_size);
+ /* check dest has all flags enabled that the source has */
+ const eBMOpSlotSubType_Elem src_elem_flag = (slot_src->slot_subtype.elem & BM_ALL_NOLOOP);
+ const eBMOpSlotSubType_Elem dst_elem_flag = (slot_dst->slot_subtype.elem & BM_ALL_NOLOOP);
+
+ if ((src_elem_flag | dst_elem_flag) == dst_elem_flag) {
+ /* pass */
+ }
+ else {
+ /* check types */
+ const unsigned int tot = slot_src->len;
+ unsigned int i;
+ unsigned int out = 0;
+ BMElem **ele_src = (BMElem **)slot_src->data.buf;
+ for (i = 0; i < tot; i++, ele_src++) {
+ if ((*ele_src)->head.htype & dst_elem_flag) {
+ out++;
+ }
+ }
+ if (out != tot) {
+ slot_dst->len = out;
+ }
+ }
+
+ if (slot_dst->len) {
+ const int slot_alloc_size = BMO_OPSLOT_TYPEINFO[slot_dst->slot_type] * slot_dst->len;
+ slot_dst->data.buf = BLI_memarena_alloc(arena_dst, slot_alloc_size);
+ if (slot_src->len == slot_dst->len) {
+ memcpy(slot_dst->data.buf, slot_src->data.buf, slot_alloc_size);
+ }
+ else {
+ /* only copy compatible elements */
+ const unsigned int tot = slot_src->len;
+ unsigned int i;
+ BMElem **ele_src = (BMElem **)slot_src->data.buf;
+ BMElem **ele_dst = (BMElem **)slot_dst->data.buf;
+ for (i = 0; i < tot; i++, ele_src++) {
+ if ((*ele_src)->head.htype & dst_elem_flag) {
+ *ele_dst = *ele_src;
+ ele_dst++;
+ }
+ }
+ }
+ }
}
}
else if (slot_dst->slot_type == BMO_OP_SLOT_MAPPING) {
@@ -313,7 +354,7 @@ void _bmo_slot_copy(BMOpSlot slot_args_src[BMO_OP_MAX_SLOTS], const char *slot_n
dstmap->element = srcmap->element;
dstmap->len = srcmap->len;
- memcpy(dstmap + 1, srcmap + 1, srcmap->len);
+ memcpy(BMO_OP_SLOT_MAPPING_DATA(dstmap), BMO_OP_SLOT_MAPPING_DATA(srcmap), srcmap->len);
BLI_ghash_insert(slot_dst->data.ghash, dstmap->element, dstmap);
}
@@ -595,7 +636,7 @@ int BMO_slot_map_count(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_na
* value, it doesn't store a reference to it. */
void BMO_slot_map_insert(BMOperator *op, BMOpSlot *slot,
- const void *element, void *data, int len)
+ const void *element, const void *data, const int len)
{
BMOElemMapping *mapping;
BLI_assert(slot->slot_type == BMO_OP_SLOT_MAPPING);
@@ -605,11 +646,14 @@ void BMO_slot_map_insert(BMOperator *op, BMOpSlot *slot,
mapping->element = (BMHeader *) element;
mapping->len = len;
- memcpy(mapping + 1, data, len);
+ memcpy(BMO_OP_SLOT_MAPPING_DATA(mapping), data, len);
if (!slot->data.ghash) {
slot->data.ghash = BLI_ghash_ptr_new("bmesh slot map hash");
}
+ else {
+ BLI_assert(slot->data.ghash);
+ }
BLI_ghash_insert(slot->data.ghash, (void *)element, mapping);
}
@@ -631,7 +675,7 @@ void *bmo_slot_buffer_grow(BMesh *bm, BMOperator *op, int slot_code, int totadd)
if (slot->len >= slot->size) {
slot->size = (slot->size + 1 + totadd) * 2;
- allocsize = BMO_OPSLOT_TYPEINFO[opdefines[op->type]->slot_types[slot_code].type] * slot->size;
+ allocsize = BMO_OPSLOT_TYPEINFO[bmo_opdefines[op->type]->slot_types[slot_code].type] * slot->size;
tmp = slot->data.buf;
slot->data.buf = MEM_callocN(allocsize, "opslot dynamic array");
@@ -646,7 +690,7 @@ void *bmo_slot_buffer_grow(BMesh *bm, BMOperator *op, int slot_code, int totadd)
slot->len += totadd;
slot->size = slot->len + 2;
- allocsize = BMO_OPSLOT_TYPEINFO[opdefines[op->type]->slot_types[slot_code].type] * slot->len;
+ allocsize = BMO_OPSLOT_TYPEINFO[bmo_opdefines[op->type]->slot_types[slot_code].type] * slot->len;
tmp = slot->data.buf;
slot->data.buf = MEM_callocN(allocsize, "opslot dynamic array");
@@ -823,6 +867,29 @@ void BMO_slot_buffer_from_disabled_hflag(BMesh *bm, BMOperator *op,
bmo_slot_buffer_from_hflag(bm, op, slot_args, slot_name, htype, hflag, FALSE);
}
+void BMO_slot_buffer_from_single(BMOperator *op, BMOpSlot *slot, BMHeader *ele)
+{
+ BMO_ASSERT_SLOT_IN_OP(slot, op);
+ BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF);
+ BLI_assert(slot->slot_subtype.elem & BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE);
+ BLI_assert(slot->len == 0 || slot->len == 1);
+
+ BLI_assert(slot->slot_subtype.elem & ele->htype);
+
+ slot->data.buf = BLI_memarena_alloc(op->arena, sizeof(void *) * 4); /* XXX, why 'x4' ? */
+ slot->len = 1;
+ *slot->data.buf = ele;
+}
+
+void *BMO_slot_buffer_get_single(BMOpSlot *slot)
+{
+ BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF);
+ BLI_assert(slot->slot_subtype.elem & BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE);
+ BLI_assert(slot->len == 0 || slot->len == 1);
+
+ return slot->len ? (BMHeader *)slot->data.buf[0] : NULL;
+}
+
/**
* Copies the values from another slot to the end of the output slot.
*/
@@ -880,6 +947,7 @@ static void bmo_slot_buffer_from_flag(BMesh *bm, BMOperator *op,
totelement = BMO_mesh_disabled_flag_count(bm, htype, oflag);
BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF);
+ BLI_assert(((slot->slot_subtype.elem & BM_ALL_NOLOOP) & htype) == htype);
if (totelement) {
BMIter iter;
@@ -955,6 +1023,7 @@ void BMO_slot_buffer_hflag_enable(BMesh *bm,
const char do_flush_hide = (do_flush && (hflag & BM_ELEM_HIDDEN));
BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF);
+ BLI_assert(((slot->slot_subtype.elem & BM_ALL_NOLOOP) & htype) == htype);
for (i = 0; i < slot->len; i++, data++) {
if (!(htype & (*data)->head.htype))
@@ -989,6 +1058,7 @@ void BMO_slot_buffer_hflag_disable(BMesh *bm,
const char do_flush_hide = (do_flush && (hflag & BM_ELEM_HIDDEN));
BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF);
+ BLI_assert(((slot->slot_subtype.elem & BM_ALL_NOLOOP) & htype) == htype);
for (i = 0; i < slot->len; i++, data++) {
if (!(htype & (*data)->head.htype))
@@ -1039,6 +1109,7 @@ void BMO_slot_buffer_flag_enable(BMesh *bm,
int i;
BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF);
+ BLI_assert(((slot->slot_subtype.elem & BM_ALL_NOLOOP) & htype) == htype);
for (i = 0; i < slot->len; i++) {
if (!(htype & data[i]->htype))
@@ -1062,6 +1133,7 @@ void BMO_slot_buffer_flag_disable(BMesh *bm,
int i;
BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF);
+ BLI_assert(((slot->slot_subtype.elem & BM_ALL_NOLOOP) & htype) == htype);
for (i = 0; i < slot->len; i++) {
if (!(htype & data[i]->htype))
@@ -1252,35 +1324,42 @@ void *BMO_iter_new(BMOIter *iter,
void *BMO_iter_step(BMOIter *iter)
{
- if (iter->slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF) {
- BMHeader *h;
+ BMOpSlot *slot = iter->slot;
+ if (slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF) {
+ BMHeader *ele;
- if (iter->cur >= iter->slot->len) {
+ if (iter->cur >= slot->len) {
return NULL;
}
- h = iter->slot->data.buf[iter->cur++];
- while (!(iter->restrictmask & h->htype)) {
- if (iter->cur >= iter->slot->len) {
+ ele = slot->data.buf[iter->cur++];
+ while (!(iter->restrictmask & ele->htype)) {
+ if (iter->cur >= slot->len) {
return NULL;
}
- h = iter->slot->data.buf[iter->cur++];
+ ele = slot->data.buf[iter->cur++];
+ BLI_assert((ele == NULL) || (slot->slot_subtype.elem & ele->htype));
}
- return h;
+ BLI_assert((ele == NULL) || (slot->slot_subtype.elem & ele->htype));
+
+ return ele;
}
- else if (iter->slot->slot_type == BMO_OP_SLOT_MAPPING) {
+ else if (slot->slot_type == BMO_OP_SLOT_MAPPING) {
BMOElemMapping *map;
void *ret = BLI_ghashIterator_getKey(&iter->giter);
map = BLI_ghashIterator_getValue(&iter->giter);
- iter->val = map + 1;
+ iter->val = BMO_OP_SLOT_MAPPING_DATA(map);
BLI_ghashIterator_step(&iter->giter);
return ret;
}
+ else {
+ BLI_assert(0);
+ }
return NULL;
}
@@ -1393,8 +1472,8 @@ static int bmo_opname_to_opcode(const char *opname)
{
int i;
- for (i = 0; i < bmesh_total_ops; i++) {
- if (!strcmp(opname, opdefines[i]->opname)) {
+ for (i = 0; i < bmo_opdefines_total; i++) {
+ if (!strcmp(opname, bmo_opdefines[i]->opname)) {
return i;
}
}
@@ -1403,23 +1482,63 @@ static int bmo_opname_to_opcode(const char *opname)
return -1;
}
-/* Example:
- * BMO_op_callf(bm, BMO_FLAG_DEFAULTS, "delete %i %hv", DEL_ONLYFACES, BM_ELEM_SELECT);
+/**
+ * \brief Format Strings for #BMOperator Initialization.
+ *
+ * This system is used to execute or initialize an operator,
+ * using a formatted-string system.
+ *
+ * The basic format for the format string is:
+ * `[operatorname] [slot_name]=%[code] [slot_name]=%[code]`
+ *
+ * Example:
+ *
+ * \code{.c}
+ * BMO_op_callf(bm, BMO_FLAG_DEFAULTS,
+ * "delete context=%i geom=%hv",
+ * DEL_ONLYFACES, BM_ELEM_SELECT);
+ * \endcode
+ *
+ *
+ * **Primitive Types**
+ * - `b` - boolean (same as int but 1/0 only). #BMO_OP_SLOT_BOOL
+ * - `i` - int. #BMO_OP_SLOT_INT
+ * - `f` - float. #BMO_OP_SLOT_FLT
+ * - `p` - pointer (normally to a Scene/Mesh/Object/BMesh). #BMO_OP_SLOT_PTR
+ * - `m3` - 3x3 matrix of floats. #BMO_OP_SLOT_MAT
+ * - `m4` - 4x4 matrix of floats. #BMO_OP_SLOT_MAT
+ * - `v` - 3D vector of floats. #BMO_OP_SLOT_VEC
+ *
+ *
+ * **Utility**
+ *
+ * Pass an existing slot which is copied to either an input or output slot.
+ * Taking the operator and slot-name pair of args.
+ * - `s` - slot_in (lower case)
+ * - `S` - slot_out (upper case)
+ *
*
- * i - int
- * b - boolean (same as int but 1/0 only)
- * f - float
- * s - slot_in
- * S - slot_out
- * hv - header flagged verts (hflag)
- * he - header flagged edges (hflag)
- * hf - header flagged faces (hflag)
- * fv - flagged verts (oflag)
- * fe - flagged edges (oflag)
- * ff - flagged faces (oflag)
+ * **Element Buffer** (#BMO_OP_SLOT_ELEMENT_BUF)
+ * - `e` - single element vert/edge/face (use with #BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE).
+ * - `av` - all verts
+ * - `ae` - all edges
+ * - `af` - all faces
+ * - `hv` - header flagged verts (hflag)
+ * - `he` - header flagged edges (hflag)
+ * - `hf` - header flagged faces (hflag)
+ * - `Hv` - header flagged verts (hflag off)
+ * - `He` - header flagged edges (hflag off)
+ * - `Hf` - header flagged faces (hflag off)
+ * - `fv` - flagged verts (oflag)
+ * - `fe` - flagged edges (oflag)
+ * - `ff` - flagged faces (oflag)
+ * - `Fv` - flagged verts (oflag off)
+ * - `Fe` - flagged edges (oflag off)
+ * - `Ff` - flagged faces (oflag off)
*
- * capitals - H, F to use the flag flipped (when the flag is off)
- * Hv, He, Hf, Fv, Fe, Ff,
+ * \note The common v/e/f suffix can be mixed,
+ * so `avef` is can be used for all verts, edges and faces.
+ * Order is not important so `Hfev` is also valid (all unflagged verts, edges and faces).
*/
int BMO_op_vinitf(BMesh *bm, BMOperator *op, const int flag, const char *_fmt, va_list vlist)
@@ -1463,7 +1582,7 @@ int BMO_op_vinitf(BMesh *bm, BMOperator *op, const int flag, const char *_fmt, v
}
BMO_op_init(bm, op, flag, opname);
-// def = opdefines[i];
+// def = bmo_opdefines[i];
i = 0;
state = 1; /* 0: not inside slot_code name, 1: inside slot_code name */
@@ -1522,14 +1641,12 @@ int BMO_op_vinitf(BMesh *bm, BMOperator *op, const int flag, const char *_fmt, v
state = 1;
break;
}
- case 'e':
+ case 'e': /* single vert/edge/face */
{
BMHeader *ele = va_arg(vlist, void *);
BMOpSlot *slot = BMO_slot_get(op->slots_in, slot_name);
- slot->data.buf = BLI_memarena_alloc(op->arena, sizeof(void *) * 4);
- slot->len = 1;
- *slot->data.buf = ele;
+ BMO_slot_buffer_from_single(op, slot, ele);
state = 1;
break;
diff --git a/source/blender/bmesh/intern/bmesh_operators.h b/source/blender/bmesh/intern/bmesh_operators.h
index 1c62a038f34..c98c3eae50b 100644
--- a/source/blender/bmesh/intern/bmesh_operators.h
+++ b/source/blender/bmesh/intern/bmesh_operators.h
@@ -85,29 +85,22 @@ enum {
SIMVERT_EDGE
};
-enum {
- OPUVC_AXIS_X = 1,
- OPUVC_AXIS_Y
-};
-
/* vertex path selection values */
enum {
VPATH_SELECT_EDGE_LENGTH = 0,
VPATH_SELECT_TOPOLOGICAL
};
-extern BMOpDefine *opdefines[];
-extern int bmesh_total_ops;
+extern const BMOpDefine *bmo_opdefines[];
+extern const int bmo_opdefines_total;
/*------specific operator helper functions-------*/
-
-struct Object;
-
void BM_mesh_esubdivide(BMesh *bm, const char edge_hflag,
float smooth, float fractal, float along_normal,
int numcuts,
int seltype, int cornertype,
- const short use_singleedge, const short use_gridfill,
+ const short use_single_edge, const short use_grid_fill,
+ const short use_only_quads,
int seed);
#include "intern/bmesh_operator_api_inline.h"
diff --git a/source/blender/bmesh/intern/bmesh_operators_private.h b/source/blender/bmesh/intern/bmesh_operators_private.h
index 65c9cf0c421..9175af1c822 100644
--- a/source/blender/bmesh/intern/bmesh_operators_private.h
+++ b/source/blender/bmesh/intern/bmesh_operators_private.h
@@ -61,7 +61,7 @@ void bmo_dissolve_limit_exec(BMesh *bm, BMOperator *op);
void bmo_dissolve_verts_exec(BMesh *bm, BMOperator *op);
void bmo_duplicate_exec(BMesh *bm, BMOperator *op);
void bmo_edgenet_fill_exec(BMesh *bm, BMOperator *op);
-void bmo_edgenet_prepare(BMesh *bm, BMOperator *op);
+void bmo_edgenet_prepare_exec(BMesh *bm, BMOperator *op);
void bmo_extrude_discrete_faces_exec(BMesh *bm, BMOperator *op);
void bmo_extrude_edge_only_exec(BMesh *bm, BMOperator *op);
void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op);
diff --git a/source/blender/bmesh/intern/bmesh_queries.c b/source/blender/bmesh/intern/bmesh_queries.c
index ec2e90591cc..195c60c5a9c 100644
--- a/source/blender/bmesh/intern/bmesh_queries.c
+++ b/source/blender/bmesh/intern/bmesh_queries.c
@@ -824,6 +824,29 @@ int BM_edge_share_face_check(BMEdge *e1, BMEdge *e2)
}
/**
+ * Test if e1 shares any quad faces with e2
+ */
+int BM_edge_share_quad_check(BMEdge *e1, BMEdge *e2)
+{
+ BMLoop *l;
+ BMFace *f;
+
+ if (e1->l && e2->l) {
+ l = e1->l;
+ do {
+ f = l->f;
+ if (f->len == 4) {
+ if (bmesh_radial_face_find(e2, f)) {
+ return TRUE;
+ }
+ }
+ l = l->radial_next;
+ } while (l != e1->l);
+ }
+ return FALSE;
+}
+
+/**
* Tests to see if e1 shares a vertex with e2
*/
int BM_edge_share_vert_check(BMEdge *e1, BMEdge *e2)
diff --git a/source/blender/bmesh/intern/bmesh_queries.h b/source/blender/bmesh/intern/bmesh_queries.h
index d97faebf021..7a18f69371e 100644
--- a/source/blender/bmesh/intern/bmesh_queries.h
+++ b/source/blender/bmesh/intern/bmesh_queries.h
@@ -90,6 +90,7 @@ int BM_face_share_edge_count(BMFace *f1, BMFace *f2);
int BM_face_share_face_check(BMFace *f1, BMFace *f2);
int BM_face_share_edge_check(BMFace *f1, BMFace *f2);
int BM_edge_share_face_check(BMEdge *e1, BMEdge *e2);
+int BM_edge_share_quad_check(BMEdge *e1, BMEdge *e2);
int BM_edge_share_vert_check(BMEdge *e1, BMEdge *e2);
BMVert *BM_edge_share_vert(BMEdge *e1, BMEdge *e2);
diff --git a/source/blender/bmesh/operators/bmo_connect.c b/source/blender/bmesh/operators/bmo_connect.c
index b7bb57bb19d..12edffec213 100644
--- a/source/blender/bmesh/operators/bmo_connect.c
+++ b/source/blender/bmesh/operators/bmo_connect.c
@@ -54,6 +54,8 @@ void bmo_connect_verts_exec(BMesh *bm, BMOperator *op)
BMO_slot_buffer_flag_enable(bm, op->slots_in, "verts", BM_VERT, VERT_INPUT);
+ /* BMESH_TODO, loop over vert faces:
+ * faster then looping over all faces, then searching each for flagged verts*/
for (f = BM_iter_new(&iter, bm, BM_FACES_OF_MESH, NULL); f; f = BM_iter_step(&iter)) {
BLI_array_empty(loops_split);
BLI_array_empty(verts_pair);
diff --git a/source/blender/bmesh/operators/bmo_create.c b/source/blender/bmesh/operators/bmo_create.c
index 987aa8cdf99..aa69806fb37 100644
--- a/source/blender/bmesh/operators/bmo_create.c
+++ b/source/blender/bmesh/operators/bmo_create.c
@@ -274,7 +274,7 @@ static int UNUSED_FUNCTION(rotsys_fill_faces)(BMesh *bm, EdgeData *edata, VertDa
if (!ok || BLI_array_count(edges) < 3)
continue;
- f = BM_face_create_ngon(bm, verts[0], verts[1], edges, BLI_array_count(edges), TRUE);
+ f = BM_face_create_ngon(bm, verts[0], verts[1], edges, BLI_array_count(edges), BM_CREATE_NO_DOUBLE);
if (UNLIKELY(f == NULL)) {
continue;
}
@@ -611,11 +611,11 @@ static void init_rotsys(BMesh *bm, EdgeData *edata, VertData *vdata)
v2 = BM_vert_create(bm, co, NULL);
BM_elem_index_set(v2, -1); /* set_dirty! */
- //BM_edge_create(bm, cv, v2, NULL, FALSE);
+ //BM_edge_create(bm, cv, v2, NULL, 0);
BM_vert_select_set(bm, v2, TRUE);
if (lastv) {
- e2 = BM_edge_create(bm, lastv, v2, NULL, FALSE);
+ e2 = BM_edge_create(bm, lastv, v2, NULL, 0);
BM_edge_select_set(bm, e2, TRUE);
}
@@ -1051,7 +1051,7 @@ void bmo_edgenet_fill_exec(BMesh *bm, BMOperator *op)
/* fairly expensive check - see if there are already faces filling this area */
(BM_face_exists_multi_edge(edges, i) == FALSE))
{
- f = BM_face_create_ngon(bm, v1, v2, edges, i, TRUE);
+ f = BM_face_create_ngon(bm, v1, v2, edges, i, BM_CREATE_NO_DOUBLE);
if (f && !BMO_elem_flag_test(bm, f, ELE_ORIG)) {
BMO_elem_flag_enable(bm, f, FACE_NEW);
f->mat_nr = mat_nr;
@@ -1098,7 +1098,7 @@ static BMEdge *edge_next(BMesh *bm, BMEdge *e)
return NULL;
}
-void bmo_edgenet_prepare(BMesh *bm, BMOperator *op)
+void bmo_edgenet_prepare_exec(BMesh *bm, BMOperator *op)
{
BMOIter siter;
BMEdge *e;
@@ -1249,9 +1249,9 @@ void bmo_edgenet_prepare(BMesh *bm, BMOperator *op)
SWAP(BMVert *, v3, v4);
}
- e = BM_edge_create(bm, v1, v3, NULL, TRUE);
+ e = BM_edge_create(bm, v1, v3, NULL, BM_CREATE_NO_DOUBLE);
BMO_elem_flag_enable(bm, e, ELE_NEW);
- e = BM_edge_create(bm, v2, v4, NULL, TRUE);
+ e = BM_edge_create(bm, v2, v4, NULL, BM_CREATE_NO_DOUBLE);
BMO_elem_flag_enable(bm, e, ELE_NEW);
}
else if (edges1) {
@@ -1261,7 +1261,7 @@ void bmo_edgenet_prepare(BMesh *bm, BMOperator *op)
v1 = BM_vert_in_edge(edges1[1], edges1[0]->v1) ? edges1[0]->v2 : edges1[0]->v1;
i = BLI_array_count(edges1) - 1;
v2 = BM_vert_in_edge(edges1[i - 1], edges1[i]->v1) ? edges1[i]->v2 : edges1[i]->v1;
- e = BM_edge_create(bm, v1, v2, NULL, TRUE);
+ e = BM_edge_create(bm, v1, v2, NULL, BM_CREATE_NO_DOUBLE);
BMO_elem_flag_enable(bm, e, ELE_NEW);
}
}
@@ -1359,10 +1359,10 @@ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op)
}
if (ok == TRUE && v_free && v_a && v_b) {
- e = BM_edge_create(bm, v_free, v_a, NULL, TRUE);
+ e = BM_edge_create(bm, v_free, v_a, NULL, BM_CREATE_NO_DOUBLE);
BMO_elem_flag_enable(bm, e, ELE_NEW);
- e = BM_edge_create(bm, v_free, v_b, NULL, TRUE);
+ e = BM_edge_create(bm, v_free, v_b, NULL, BM_CREATE_NO_DOUBLE);
BMO_elem_flag_enable(bm, e, ELE_NEW);
}
}
@@ -1420,7 +1420,7 @@ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op)
if (amount == 2) {
/* create edge */
- e = BM_edge_create(bm, verts[0], verts[1], NULL, TRUE);
+ e = BM_edge_create(bm, verts[0], verts[1], NULL, BM_CREATE_NO_DOUBLE);
BMO_elem_flag_enable(bm, e, ELE_OUT);
BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "edges.out", BM_EDGE, ELE_OUT);
}
@@ -1461,7 +1461,7 @@ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op)
if (ese->htype == BM_VERT) {
v = (BMVert *)ese->ele;
if (v_prev) {
- e = BM_edge_create(bm, v, v_prev, NULL, TRUE);
+ e = BM_edge_create(bm, v, v_prev, NULL, BM_CREATE_NO_DOUBLE);
BMO_elem_flag_enable(bm, e, ELE_OUT);
}
v_prev = v;
@@ -1483,7 +1483,7 @@ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op)
i++;
}
- f = BM_face_create_ngon_vcloud(bm, vert_arr, totv, TRUE);
+ f = BM_face_create_ngon_vcloud(bm, vert_arr, totv, BM_CREATE_NO_DOUBLE);
if (f) {
BMO_elem_flag_enable(bm, f, ELE_OUT);
diff --git a/source/blender/bmesh/operators/bmo_dupe.c b/source/blender/bmesh/operators/bmo_dupe.c
index c4f6c821320..9a58d7acfb9 100644
--- a/source/blender/bmesh/operators/bmo_dupe.c
+++ b/source/blender/bmesh/operators/bmo_dupe.c
@@ -49,7 +49,7 @@ static BMVert *copy_vertex(BMesh *source_mesh, BMVert *source_vertex, BMesh *tar
BMVert *target_vertex = NULL;
/* Create a new vertex */
- target_vertex = BM_vert_create(target_mesh, source_vertex->co, NULL);
+ target_vertex = BM_vert_create(target_mesh, source_vertex->co, NULL, BM_CREATE_SKIP_CD);
/* Insert new vertex into the vert hash */
BLI_ghash_insert(vhash, source_vertex, target_vertex);
@@ -98,14 +98,13 @@ static BMEdge *copy_edge(BMOperator *op,
target_vert2 = BLI_ghash_lookup(vhash, source_edge->v2);
/* Create a new edge */
- target_edge = BM_edge_create(target_mesh, target_vert1, target_vert2, NULL, FALSE);
+ target_edge = BM_edge_create(target_mesh, target_vert1, target_vert2, NULL, BM_CREATE_SKIP_CD);
/* add to new/old edge map if necassary */
if (rlen < 2) {
/* not sure what non-manifold cases of greater then three
* radial should do. */
- BMO_slot_map_ptr_insert(op, slot_boundarymap_out,
- source_edge, target_edge);
+ BMO_slot_map_elem_insert(op, slot_boundarymap_out, source_edge, target_edge);
}
/* Insert new edge into the edge hash */
@@ -157,9 +156,9 @@ static BMFace *copy_face(BMOperator *op,
}
/* create new face */
- target_face = BM_face_create(target_mesh, vtar, edar, source_face->len, FALSE);
- BMO_slot_map_ptr_insert(op, slot_facemap_out, source_face, target_face);
- BMO_slot_map_ptr_insert(op, slot_facemap_out, target_face, source_face);
+ target_face = BM_face_create(target_mesh, vtar, edar, source_face->len, BM_CREATE_SKIP_CD);
+ BMO_slot_map_elem_insert(op, slot_facemap_out, source_face, target_face);
+ BMO_slot_map_elem_insert(op, slot_facemap_out, target_face, source_face);
BM_elem_attrs_copy(source_mesh, target_mesh, source_face, target_face);
@@ -200,9 +199,9 @@ static void bmo_mesh_copy(BMOperator *op, BMesh *bm_src, BMesh *bm_dst)
BMIter viter, eiter, fiter;
GHash *vhash, *ehash;
- BMOpSlot *slot_boundarymap_out = BMO_slot_get(op->slots_out, "boundarymap.out");
- BMOpSlot *slot_facemap_out = BMO_slot_get(op->slots_out, "facemap.out");
- BMOpSlot *slot_isovertmap_out = BMO_slot_get(op->slots_out, "isovertmap.out");
+ BMOpSlot *slot_boundary_map_out = BMO_slot_get(op->slots_out, "boundary_map.out");
+ BMOpSlot *slot_face_map_out = BMO_slot_get(op->slots_out, "face_map.out");
+ BMOpSlot *slot_isovert_map_out = BMO_slot_get(op->slots_out, "isovert_map.out");
/* initialize pointer hashes */
vhash = BLI_ghash_ptr_new("bmesh dupeops v");
@@ -235,7 +234,7 @@ static void bmo_mesh_copy(BMOperator *op, BMesh *bm_src, BMesh *bm_dst)
}
if (isolated) {
- BMO_slot_map_ptr_insert(op, slot_isovertmap_out, v, v2);
+ BMO_slot_map_elem_insert(op, slot_isovert_map_out, v, v2);
}
BMO_elem_flag_enable(bm_src, v, DUPE_DONE);
@@ -257,7 +256,7 @@ static void bmo_mesh_copy(BMOperator *op, BMesh *bm_src, BMesh *bm_dst)
BMO_elem_flag_enable(bm_src, e->v2, DUPE_DONE);
}
/* now copy the actual edge */
- copy_edge(op, slot_boundarymap_out, bm_src, e, bm_dst, vhash, ehash);
+ copy_edge(op, slot_boundary_map_out, bm_src, e, bm_dst, vhash, ehash);
BMO_elem_flag_enable(bm_src, e, DUPE_DONE);
}
}
@@ -276,7 +275,7 @@ static void bmo_mesh_copy(BMOperator *op, BMesh *bm_src, BMesh *bm_dst)
/* edge pass */
BM_ITER_ELEM (e, &eiter, f, BM_EDGES_OF_FACE) {
if (!BMO_elem_flag_test(bm_src, e, DUPE_DONE)) {
- copy_edge(op, slot_boundarymap_out, bm_src, e, bm_dst, vhash, ehash);
+ copy_edge(op, slot_boundary_map_out, bm_src, e, bm_dst, vhash, ehash);
BMO_elem_flag_enable(bm_src, e, DUPE_DONE);
}
}
@@ -288,7 +287,7 @@ static void bmo_mesh_copy(BMOperator *op, BMesh *bm_src, BMesh *bm_dst)
BLI_array_grow_items(vtar, f->len);
BLI_array_grow_items(edar, f->len);
- copy_face(op, slot_facemap_out, bm_src, f, bm_dst, vtar, edar, vhash, ehash);
+ copy_face(op, slot_face_map_out, bm_src, f, bm_dst, vtar, edar, vhash, ehash);
BMO_elem_flag_enable(bm_src, f, DUPE_DONE);
}
}
@@ -331,7 +330,7 @@ void bmo_duplicate_exec(BMesh *bm, BMOperator *op)
bm2 = bm;
/* flag input */
- BMO_slot_buffer_flag_enable(bm, dupeop->slots_in, "geom", BM_ALL, DUPE_INPUT);
+ BMO_slot_buffer_flag_enable(bm, dupeop->slots_in, "geom", BM_ALL_NOLOOP, DUPE_INPUT);
/* use the internal copy function */
bmo_mesh_copy(dupeop, bm, bm2);
@@ -342,7 +341,7 @@ void bmo_duplicate_exec(BMesh *bm, BMOperator *op)
dupeop, slots_out, "geom_orig.out");
/* Now alloc the new output buffers */
- BMO_slot_buffer_from_enabled_flag(bm, dupeop, dupeop->slots_out, "geom.out", BM_ALL, DUPE_NEW);
+ BMO_slot_buffer_from_enabled_flag(bm, dupeop, dupeop->slots_out, "geom.out", BM_ALL_NOLOOP, DUPE_NEW);
}
#if 0 /* UNUSED */
@@ -397,7 +396,7 @@ void bmo_split_exec(BMesh *bm, BMOperator *op)
&dupeop, slots_in, "geom");
BMO_op_exec(bm, &dupeop);
- BMO_slot_buffer_flag_enable(bm, splitop->slots_in, "geom", BM_ALL, SPLIT_INPUT);
+ BMO_slot_buffer_flag_enable(bm, splitop->slots_in, "geom", BM_ALL_NOLOOP, SPLIT_INPUT);
if (use_only_faces) {
BMVert *v;
@@ -438,7 +437,7 @@ void bmo_split_exec(BMesh *bm, BMOperator *op)
/* connect outputs of dupe to delete, exluding keep geometry */
BMO_slot_int_set(delop.slots_in, "context", DEL_FACES);
- BMO_slot_buffer_from_enabled_flag(bm, &delop, delop.slots_in, "geom", BM_ALL, SPLIT_INPUT);
+ BMO_slot_buffer_from_enabled_flag(bm, &delop, delop.slots_in, "geom", BM_ALL_NOLOOP, SPLIT_INPUT);
BMO_op_exec(bm, &delop);
@@ -446,11 +445,11 @@ void bmo_split_exec(BMesh *bm, BMOperator *op)
BMO_slot_copy(&dupeop, slots_out, "geom.out",
splitop, slots_out, "geom.out");
- BMO_slot_copy(&dupeop, slots_out, "boundarymap.out",
- splitop, slots_out, "boundarymap.out");
+ BMO_slot_copy(&dupeop, slots_out, "boundary_map.out",
+ splitop, slots_out, "boundary_map.out");
- BMO_slot_copy(&dupeop, slots_out, "isovertmap.out",
- splitop, slots_out, "isovertmap.out");
+ BMO_slot_copy(&dupeop, slots_out, "isovert_map.out",
+ splitop, slots_out, "isovert_map.out");
/* cleanup */
@@ -466,7 +465,7 @@ void bmo_delete_exec(BMesh *bm, BMOperator *op)
BMOperator *delop = op;
/* Mark Buffer */
- BMO_slot_buffer_flag_enable(bm, delop->slots_in, "geom", BM_ALL, DEL_INPUT);
+ BMO_slot_buffer_flag_enable(bm, delop->slots_in, "geom", BM_ALL_NOLOOP, DEL_INPUT);
BMO_remove_tagged_context(bm, DEL_INPUT, BMO_slot_int_get(op->slots_in, "context"));
@@ -495,7 +494,7 @@ void bmo_spin_exec(BMesh *bm, BMOperator *op)
BMO_slot_vec_get(op->slots_in, "dvec", dvec);
usedvec = !is_zero_v3(dvec);
steps = BMO_slot_int_get(op->slots_in, "steps");
- phi = BMO_slot_float_get(op->slots_in, "angle") * DEG2RADF(1.0f) / steps;
+ phi = BMO_slot_float_get(op->slots_in, "angle") / steps;
do_dupli = BMO_slot_bool_get(op->slots_in, "use_duplicate");
axis_angle_to_mat3(rmat, axis, phi);
@@ -507,7 +506,7 @@ void bmo_spin_exec(BMesh *bm, BMOperator *op)
BMO_op_initf(bm, &dupop, op->flag, "duplicate geom=%S", op, "geom_last.out");
BMO_op_exec(bm, &dupop);
BMO_op_callf(bm, op->flag,
- "rotate cent=%v mat=%m3 verts=%S",
+ "rotate cent=%v matrix=%m3 verts=%S",
cent, rmat, &dupop, "geom.out");
BMO_slot_copy(&dupop, slots_out, "geom.out",
op, slots_out, "geom_last.out");
@@ -518,7 +517,7 @@ void bmo_spin_exec(BMesh *bm, BMOperator *op)
op, "geom_last.out");
BMO_op_exec(bm, &extop);
BMO_op_callf(bm, op->flag,
- "rotate cent=%v mat=%m3 verts=%S",
+ "rotate cent=%v matrix=%m3 verts=%S",
cent, rmat, &extop, "geom.out");
BMO_slot_copy(&extop, slots_out, "geom.out",
op, slots_out, "geom_last.out");
diff --git a/source/blender/bmesh/operators/bmo_extrude.c b/source/blender/bmesh/operators/bmo_extrude.c
index 6a9d9c1e48b..065a1b57737 100644
--- a/source/blender/bmesh/operators/bmo_extrude.c
+++ b/source/blender/bmesh/operators/bmo_extrude.c
@@ -67,11 +67,11 @@ void bmo_extrude_discrete_faces_exec(BMesh *bm, BMOperator *op)
i = 0;
firstv = lastv = NULL;
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
- v = BM_vert_create(bm, l->v->co, l->v);
+ v = BM_vert_create(bm, l->v->co, l->v, 0);
/* skip on the first iteration */
if (lastv) {
- e = BM_edge_create(bm, lastv, v, l->e, FALSE);
+ e = BM_edge_create(bm, lastv, v, l->e, 0);
edges[i++] = e;
}
@@ -81,12 +81,12 @@ void bmo_extrude_discrete_faces_exec(BMesh *bm, BMOperator *op)
}
/* this fits in the array because we skip one in the loop above */
- e = BM_edge_create(bm, v, firstv, laste, FALSE);
+ e = BM_edge_create(bm, v, firstv, laste, 0);
edges[i++] = e;
BMO_elem_flag_enable(bm, f, EXT_DEL);
- f2 = BM_face_create_ngon(bm, firstv, BM_edge_other_vert(edges[0], firstv), edges, f->len, FALSE);
+ f2 = BM_face_create_ngon(bm, firstv, BM_edge_other_vert(edges[0], firstv), edges, f->len, 0);
if (UNLIKELY(f2 == NULL)) {
BMO_error_raise(bm, op, BMERR_MESH_ERROR, "Extrude failed: could not create face");
BLI_array_free(edges);
@@ -198,7 +198,7 @@ void bmo_extrude_edge_only_exec(BMesh *bm, BMOperator *op)
}
}
- for (e = BMO_iter_new(&siter, dupeop.slots_out, "boundarymap.out", 0); e; e = BMO_iter_step(&siter)) {
+ for (e = BMO_iter_new(&siter, dupeop.slots_out, "boundary_map.out", 0); e; e = BMO_iter_step(&siter)) {
BMVert *f_verts[4];
e_new = *(BMEdge **)BMO_iter_map_value(&siter);
@@ -230,7 +230,7 @@ void bmo_extrude_edge_only_exec(BMesh *bm, BMOperator *op)
BMO_op_finish(bm, &dupeop);
- BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom.out", BM_ALL, EXT_KEEP);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom.out", BM_ALL_NOLOOP, EXT_KEEP);
}
void bmo_extrude_vert_indiv_exec(BMesh *bm, BMOperator *op)
@@ -241,11 +241,11 @@ void bmo_extrude_vert_indiv_exec(BMesh *bm, BMOperator *op)
const int has_vskin = CustomData_has_layer(&bm->vdata, CD_MVERT_SKIN);
for (v = BMO_iter_new(&siter, op->slots_in, "verts", BM_VERT); v; v = BMO_iter_step(&siter)) {
- dupev = BM_vert_create(bm, v->co, v);
+ dupev = BM_vert_create(bm, v->co, v, 0);
if (has_vskin)
bm_extrude_disable_skin_root(bm, v);
- e = BM_edge_create(bm, v, dupev, NULL, FALSE);
+ e = BM_edge_create(bm, v, dupev, NULL, 0);
BMO_elem_flag_enable(bm, e, EXT_KEEP);
BMO_elem_flag_enable(bm, dupev, EXT_KEEP);
@@ -352,9 +352,9 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op)
}
}
- slot_facemap_out = BMO_slot_get(dupeop.slots_out, "facemap.out");
+ slot_facemap_out = BMO_slot_get(dupeop.slots_out, "face_map.out");
if (bm->act_face && BMO_elem_flag_test(bm, bm->act_face, EXT_INPUT)) {
- bm->act_face = BMO_slot_map_ptr_get(slot_facemap_out, bm->act_face);
+ bm->act_face = BMO_slot_map_elem_get(slot_facemap_out, bm->act_face);
}
if (delorig) {
@@ -374,7 +374,7 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op)
op, slots_out, "geom.out");
slot_edges_exclude = BMO_slot_get(op->slots_in, "edges_exclude");
- for (e = BMO_iter_new(&siter, dupeop.slots_out, "boundarymap.out", 0); e; e = BMO_iter_step(&siter)) {
+ for (e = BMO_iter_new(&siter, dupeop.slots_out, "boundary_map.out", 0); e; e = BMO_iter_step(&siter)) {
BMVert *f_verts[4];
/* this should always be wire, so this is mainly a speedup to avoid map lookup */
@@ -428,9 +428,9 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op)
}
/* link isolated vert */
- for (v = BMO_iter_new(&siter, dupeop.slots_out, "isovertmap.out", 0); v; v = BMO_iter_step(&siter)) {
+ for (v = BMO_iter_new(&siter, dupeop.slots_out, "isovert_map.out", 0); v; v = BMO_iter_step(&siter)) {
v2 = *((void **)BMO_iter_map_value(&siter));
- BM_edge_create(bm, v, v2, v->e, TRUE);
+ BM_edge_create(bm, v, v2, v->e, BM_CREATE_NO_DOUBLE);
}
/* cleanup */
diff --git a/source/blender/bmesh/operators/bmo_hull.c b/source/blender/bmesh/operators/bmo_hull.c
index 117f65ae4ea..e2da4f4f89c 100644
--- a/source/blender/bmesh/operators/bmo_hull.c
+++ b/source/blender/bmesh/operators/bmo_hull.c
@@ -113,9 +113,9 @@ static void hull_output_triangles(BMesh *bm, GHash *hull_triangles)
if (!t->skip) {
BMEdge *edges[3] = {
- BM_edge_create(bm, t->v[0], t->v[1], NULL, TRUE),
- BM_edge_create(bm, t->v[1], t->v[2], NULL, TRUE),
- BM_edge_create(bm, t->v[2], t->v[0], NULL, TRUE)
+ BM_edge_create(bm, t->v[0], t->v[1], NULL, BM_CREATE_NO_DOUBLE),
+ BM_edge_create(bm, t->v[1], t->v[2], NULL, BM_CREATE_NO_DOUBLE),
+ BM_edge_create(bm, t->v[2], t->v[0], NULL, BM_CREATE_NO_DOUBLE)
};
BMFace *f, *example = NULL;
@@ -604,22 +604,22 @@ void bmo_convex_hull_exec(BMesh *bm, BMOperator *op)
/* Output slot of input elements that ended up inside the hull
* rather than part of it */
BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom_interior.out",
- BM_ALL, HULL_FLAG_INTERIOR_ELE);
+ BM_ALL_NOLOOP, HULL_FLAG_INTERIOR_ELE);
/* Output slot of input elements that ended up inside the hull and
* are are unused by other geometry. */
BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom_unused.out",
- BM_ALL, HULL_FLAG_DEL);
+ BM_ALL_NOLOOP, HULL_FLAG_DEL);
/* Output slot of faces and edges that were in the input and on
* the hull (useful for cases like bridging where you want to
* delete some input geometry) */
BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom_holes.out",
- BM_ALL, HULL_FLAG_HOLE);
+ BM_ALL_NOLOOP, HULL_FLAG_HOLE);
/* Output slot of all hull vertices, faces, and edges */
BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom.out",
- BM_ALL, HULL_FLAG_OUTPUT_GEOM);
+ BM_ALL_NOLOOP, HULL_FLAG_OUTPUT_GEOM);
}
#endif /* WITH_BULLET */
diff --git a/source/blender/bmesh/operators/bmo_inset.c b/source/blender/bmesh/operators/bmo_inset.c
index 9abf129a529..cef1181f63b 100644
--- a/source/blender/bmesh/operators/bmo_inset.c
+++ b/source/blender/bmesh/operators/bmo_inset.c
@@ -181,7 +181,7 @@ void bmo_inset_exec(BMesh *bm, BMOperator *op)
if (es->e_new == es->e_old) { /* happens on boundary edges */
/* take care here, we're creating this double edge which _must_ have its verts replaced later on */
- es->e_old = BM_edge_create(bm, es->e_new->v1, es->e_new->v2, es->e_new, FALSE);
+ es->e_old = BM_edge_create(bm, es->e_new->v1, es->e_new->v2, es->e_new, 0);
}
/* store index back to original in 'edge_info' */
@@ -205,7 +205,7 @@ void bmo_inset_exec(BMesh *bm, BMOperator *op)
v1 = BM_vert_create(bm, tvec, NULL);
v2 = BM_vert_create(bm, tvec, NULL);
madd_v3_v3fl(v2->co, es->no, 0.1f);
- BM_edge_create(bm, v1, v2, NULL, FALSE);
+ BM_edge_create(bm, v1, v2, NULL, 0);
}
#endif
diff --git a/source/blender/bmesh/operators/bmo_mirror.c b/source/blender/bmesh/operators/bmo_mirror.c
index 01bce976ec0..61b061dd21f 100644
--- a/source/blender/bmesh/operators/bmo_mirror.c
+++ b/source/blender/bmesh/operators/bmo_mirror.c
@@ -60,13 +60,13 @@ void bmo_mirror_exec(BMesh *bm, BMOperator *op)
ototvert = bm->totvert;
/* ototedge = bm->totedge; */ /* UNUSED */
- BMO_slot_mat4_get(op->slots_in, "mat", mtx);
+ BMO_slot_mat4_get(op->slots_in, "matrix", mtx);
invert_m4_m4(imtx, mtx);
BMO_op_initf(bm, &dupeop, op->flag, "duplicate geom=%s", op, "geom");
BMO_op_exec(bm, &dupeop);
- BMO_slot_buffer_flag_enable(bm, dupeop.slots_out, "geom.out", BM_ALL, ELE_NEW);
+ BMO_slot_buffer_flag_enable(bm, dupeop.slots_out, "geom.out", BM_ALL_NOLOOP, ELE_NEW);
/* create old -> new mappin */
i = 0;
@@ -81,9 +81,9 @@ void bmo_mirror_exec(BMesh *bm, BMOperator *op)
/* feed old data to transform bmo */
scale[axis] = -1.0f;
- BMO_op_callf(bm, op->flag, "transform verts=%fv mat=%m4", ELE_NEW, mtx);
+ BMO_op_callf(bm, op->flag, "transform verts=%fv matrix=%m4", ELE_NEW, mtx);
BMO_op_callf(bm, op->flag, "scale verts=%fv vec=%v", ELE_NEW, scale);
- BMO_op_callf(bm, op->flag, "transform verts=%fv mat=%m4", ELE_NEW, imtx);
+ BMO_op_callf(bm, op->flag, "transform verts=%fv matrix=%m4", ELE_NEW, imtx);
BMO_op_init(bm, &weldop, op->flag, "weld_verts");
@@ -92,7 +92,7 @@ void bmo_mirror_exec(BMesh *bm, BMOperator *op)
v = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL);
for (i = 0; i < ototvert; i++) {
if (fabsf(v->co[axis]) <= dist) {
- BMO_slot_map_ptr_insert(&weldop, slot_targetmap, vmap[i], v);
+ BMO_slot_map_elem_insert(&weldop, slot_targetmap, vmap[i], v);
}
v = BM_iter_step(&iter);
}
@@ -123,7 +123,7 @@ void bmo_mirror_exec(BMesh *bm, BMOperator *op)
BMO_op_finish(bm, &weldop);
BMO_op_finish(bm, &dupeop);
- BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom.out", BM_ALL, ELE_NEW);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom.out", BM_ALL_NOLOOP, ELE_NEW);
BLI_array_free(vmap);
BLI_array_free(emap);
diff --git a/source/blender/bmesh/operators/bmo_primitive.c b/source/blender/bmesh/operators/bmo_primitive.c
index 71f63bbaf28..c582f710f43 100644
--- a/source/blender/bmesh/operators/bmo_primitive.c
+++ b/source/blender/bmesh/operators/bmo_primitive.c
@@ -237,7 +237,7 @@ void bmo_create_grid_exec(BMesh *bm, BMOperator *op)
float vec[3], mat[4][4], phi, phid;
int a;
- BMO_slot_mat4_get(op->slots_in, "mat", mat);
+ BMO_slot_mat4_get(op->slots_in, "matrix", mat);
/* one segment first: the X axis */
phi = 1.0f;
@@ -248,11 +248,11 @@ void bmo_create_grid_exec(BMesh *bm, BMOperator *op)
vec[2] = 0.0f;
mul_m4_v3(mat, vec);
- eve = BM_vert_create(bm, vec, NULL);
+ eve = BM_vert_create(bm, vec, NULL, 0);
BMO_elem_flag_enable(bm, eve, VERT_MARK);
if (a != 0) {
- e = BM_edge_create(bm, preveve, eve, NULL, TRUE);
+ e = BM_edge_create(bm, preveve, eve, NULL, BM_CREATE_NO_DOUBLE);
BMO_elem_flag_enable(bm, e, EDGE_ORIG);
}
@@ -304,7 +304,7 @@ void bmo_create_uvsphere_exec(BMesh *bm, BMOperator *op)
float phid;
int a;
- BMO_slot_mat4_get(op->slots_in, "mat", mat);
+ BMO_slot_mat4_get(op->slots_in, "matrix", mat);
phid = 2.0f * (float)M_PI / tot;
/* phi = 0.25f * (float)M_PI; */ /* UNUSED */
@@ -317,11 +317,11 @@ void bmo_create_uvsphere_exec(BMesh *bm, BMOperator *op)
vec[0] = -dia * sinf(phi);
vec[1] = 0.0;
vec[2] = dia * cosf(phi);
- eve = BM_vert_create(bm, vec, NULL);
+ eve = BM_vert_create(bm, vec, NULL, 0);
BMO_elem_flag_enable(bm, eve, VERT_MARK);
if (a != 0) {
- e = BM_edge_create(bm, preveve, eve, NULL, FALSE);
+ e = BM_edge_create(bm, preveve, eve, NULL, 0);
BMO_elem_flag_enable(bm, e, EDGE_ORIG);
}
@@ -348,7 +348,7 @@ void bmo_create_uvsphere_exec(BMesh *bm, BMOperator *op)
}
BMO_slot_buffer_flag_enable(bm, bmop.slots_out, "geom.out", BM_VERT, VERT_MARK);
- BMO_op_callf(bm, op->flag, "rotate cent=%v mat=%m3 verts=%S", vec, cmat, &bmop, "geom.out");
+ BMO_op_callf(bm, op->flag, "rotate cent=%v matrix=%m3 verts=%S", vec, cmat, &bmop, "geom.out");
prevop = bmop;
}
@@ -397,7 +397,7 @@ void bmo_create_icosphere_exec(BMesh *bm, BMOperator *op)
float vec[3], mat[4][4] /* , phi, phid */;
int a;
- BMO_slot_mat4_get(op->slots_in, "mat", mat);
+ BMO_slot_mat4_get(op->slots_in, "matrix", mat);
/* phid = 2.0f * (float)M_PI / subdiv; */ /* UNUSED */
/* phi = 0.25f * (float)M_PI; */ /* UNUSED */
@@ -407,7 +407,7 @@ void bmo_create_icosphere_exec(BMesh *bm, BMOperator *op)
vec[0] = dia_div * icovert[a][0];
vec[1] = dia_div * icovert[a][1];
vec[2] = dia_div * icovert[a][2];
- eva[a] = BM_vert_create(bm, vec, NULL);
+ eva[a] = BM_vert_create(bm, vec, NULL, 0);
BMO_elem_flag_enable(bm, eva[a], VERT_MARK);
}
@@ -436,7 +436,7 @@ void bmo_create_icosphere_exec(BMesh *bm, BMOperator *op)
"subdivide_edges edges=%fe "
"smooth=%f "
"cuts=%i "
- "use_gridfill=%b use_sphere=%b",
+ "use_grid_fill=%b use_sphere=%b",
EDGE_MARK, dia, (1 << (subdiv - 1)) - 1,
TRUE, TRUE);
@@ -463,19 +463,19 @@ void bmo_create_monkey_exec(BMesh *bm, BMOperator *op)
float mat[4][4];
int i;
- BMO_slot_mat4_get(op->slots_in, "mat", mat);
+ BMO_slot_mat4_get(op->slots_in, "matrix", mat);
for (i = 0; i < monkeynv; i++) {
float v[3];
v[0] = (monkeyv[i][0] + 127) / 128.0, v[1] = monkeyv[i][1] / 128.0, v[2] = monkeyv[i][2] / 128.0;
- tv[i] = BM_vert_create(bm, v, NULL);
+ tv[i] = BM_vert_create(bm, v, NULL, 0);
BMO_elem_flag_enable(bm, tv[i], VERT_MARK);
tv[monkeynv + i] = (fabsf(v[0] = -v[0]) < 0.001f) ?
tv[i] :
- (eve = BM_vert_create(bm, v, NULL), mul_m4_v3(mat, eve->co), eve);
+ (eve = BM_vert_create(bm, v, NULL, 0), mul_m4_v3(mat, eve->co), eve);
BMO_elem_flag_enable(bm, tv[monkeynv + i], VERT_MARK);
@@ -518,7 +518,7 @@ void bmo_create_circle_exec(BMesh *bm, BMOperator *op)
if (!segs)
return;
- BMO_slot_mat4_get(op->slots_in, "mat", mat);
+ BMO_slot_mat4_get(op->slots_in, "matrix", mat);
phid = 2.0f * (float)M_PI / segs;
phi = 0;
@@ -527,7 +527,7 @@ void bmo_create_circle_exec(BMesh *bm, BMOperator *op)
zero_v3(vec);
mul_m4_v3(mat, vec);
- cent1 = BM_vert_create(bm, vec, NULL);
+ cent1 = BM_vert_create(bm, vec, NULL, 0);
BMO_elem_flag_enable(bm, cent1, VERT_MARK);
}
@@ -537,12 +537,12 @@ void bmo_create_circle_exec(BMesh *bm, BMOperator *op)
vec[1] = dia * cosf(phi);
vec[2] = 0.0f;
mul_m4_v3(mat, vec);
- v1 = BM_vert_create(bm, vec, NULL);
+ v1 = BM_vert_create(bm, vec, NULL, 0);
BMO_elem_flag_enable(bm, v1, VERT_MARK);
if (lastv1)
- BM_edge_create(bm, v1, lastv1, NULL, FALSE);
+ BM_edge_create(bm, v1, lastv1, NULL, 0);
if (a && cap_ends) {
BMFace *f;
@@ -560,7 +560,7 @@ void bmo_create_circle_exec(BMesh *bm, BMOperator *op)
if (!a)
return;
- BM_edge_create(bm, lastv1, firstv1, NULL, FALSE);
+ BM_edge_create(bm, firstv1, lastv1, NULL, 0);
if (cap_ends) {
BMFace *f;
@@ -591,7 +591,7 @@ void bmo_create_cone_exec(BMesh *bm, BMOperator *op)
if (!segs)
return;
- BMO_slot_mat4_get(op->slots_in, "mat", mat);
+ BMO_slot_mat4_get(op->slots_in, "matrix", mat);
phid = 2.0f * (float)M_PI / segs;
phi = 0;
@@ -602,13 +602,13 @@ void bmo_create_cone_exec(BMesh *bm, BMOperator *op)
vec[2] = -depth;
mul_m4_v3(mat, vec);
- cent1 = BM_vert_create(bm, vec, NULL);
+ cent1 = BM_vert_create(bm, vec, NULL, 0);
vec[0] = vec[1] = 0.0f;
vec[2] = depth;
mul_m4_v3(mat, vec);
- cent2 = BM_vert_create(bm, vec, NULL);
+ cent2 = BM_vert_create(bm, vec, NULL, 0);
BMO_elem_flag_enable(bm, cent1, VERT_MARK);
BMO_elem_flag_enable(bm, cent2, VERT_MARK);
@@ -619,13 +619,13 @@ void bmo_create_cone_exec(BMesh *bm, BMOperator *op)
vec[1] = dia1 * cosf(phi);
vec[2] = -depth;
mul_m4_v3(mat, vec);
- v1 = BM_vert_create(bm, vec, NULL);
+ v1 = BM_vert_create(bm, vec, NULL, 0);
vec[0] = dia2 * sinf(phi);
vec[1] = dia2 * cosf(phi);
vec[2] = depth;
mul_m4_v3(mat, vec);
- v2 = BM_vert_create(bm, vec, NULL);
+ v2 = BM_vert_create(bm, vec, NULL, 0);
BMO_elem_flag_enable(bm, v1, VERT_MARK);
BMO_elem_flag_enable(bm, v2, VERT_MARK);
@@ -677,7 +677,7 @@ void bmo_create_cube_exec(BMesh *bm, BMOperator *op)
BMVert *v1, *v2, *v3, *v4, *v5, *v6, *v7, *v8;
float vec[3], mat[4][4], off = BMO_slot_float_get(op->slots_in, "size") / 2.0f;
- BMO_slot_mat4_get(op->slots_in, "mat", mat);
+ BMO_slot_mat4_get(op->slots_in, "matrix", mat);
if (!off) off = 0.5f;
@@ -685,56 +685,56 @@ void bmo_create_cube_exec(BMesh *bm, BMOperator *op)
vec[1] = -off;
vec[2] = -off;
mul_m4_v3(mat, vec);
- v1 = BM_vert_create(bm, vec, NULL);
+ v1 = BM_vert_create(bm, vec, NULL, 0);
BMO_elem_flag_enable(bm, v1, VERT_MARK);
vec[0] = -off;
vec[1] = off;
vec[2] = -off;
mul_m4_v3(mat, vec);
- v2 = BM_vert_create(bm, vec, NULL);
+ v2 = BM_vert_create(bm, vec, NULL, 0);
BMO_elem_flag_enable(bm, v2, VERT_MARK);
vec[0] = off;
vec[1] = off;
vec[2] = -off;
mul_m4_v3(mat, vec);
- v3 = BM_vert_create(bm, vec, NULL);
+ v3 = BM_vert_create(bm, vec, NULL, 0);
BMO_elem_flag_enable(bm, v3, VERT_MARK);
vec[0] = off;
vec[1] = -off;
vec[2] = -off;
mul_m4_v3(mat, vec);
- v4 = BM_vert_create(bm, vec, NULL);
+ v4 = BM_vert_create(bm, vec, NULL, 0);
BMO_elem_flag_enable(bm, v4, VERT_MARK);
vec[0] = -off;
vec[1] = -off;
vec[2] = off;
mul_m4_v3(mat, vec);
- v5 = BM_vert_create(bm, vec, NULL);
+ v5 = BM_vert_create(bm, vec, NULL, 0);
BMO_elem_flag_enable(bm, v5, VERT_MARK);
vec[0] = -off;
vec[1] = off;
vec[2] = off;
mul_m4_v3(mat, vec);
- v6 = BM_vert_create(bm, vec, NULL);
+ v6 = BM_vert_create(bm, vec, NULL, 0);
BMO_elem_flag_enable(bm, v6, VERT_MARK);
vec[0] = off;
vec[1] = off;
vec[2] = off;
mul_m4_v3(mat, vec);
- v7 = BM_vert_create(bm, vec, NULL);
+ v7 = BM_vert_create(bm, vec, NULL, 0);
BMO_elem_flag_enable(bm, v7, VERT_MARK);
vec[0] = off;
vec[1] = -off;
vec[2] = off;
mul_m4_v3(mat, vec);
- v8 = BM_vert_create(bm, vec, NULL);
+ v8 = BM_vert_create(bm, vec, NULL, 0);
BMO_elem_flag_enable(bm, v8, VERT_MARK);
/* the four sides */
diff --git a/source/blender/bmesh/operators/bmo_removedoubles.c b/source/blender/bmesh/operators/bmo_removedoubles.c
index 45e678b96bb..87e26f11d4b 100644
--- a/source/blender/bmesh/operators/bmo_removedoubles.c
+++ b/source/blender/bmesh/operators/bmo_removedoubles.c
@@ -44,7 +44,7 @@ static void remdoubles_splitface(BMFace *f, BMesh *bm, BMOperator *op, BMOpSlot
int split = FALSE;
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
- v2 = BMO_slot_map_ptr_get(slot_targetmap, l->v);
+ v2 = BMO_slot_map_elem_get(slot_targetmap, l->v);
/* ok: if v2 is NULL (e.g. not in the map) then it's
* a target vert, otherwise it's a double */
if ((v2 && BM_vert_in_face(f, v2)) &&
@@ -110,7 +110,7 @@ void bmo_weld_verts_exec(BMesh *bm, BMOperator *op)
/* mark merge verts for deletion */
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
- if ((v2 = BMO_slot_map_ptr_get(slot_targetmap, v))) {
+ if ((v2 = BMO_slot_map_elem_get(slot_targetmap, v))) {
BMO_elem_flag_enable(bm, v, ELE_DEL);
/* merge the vertex flags, else we get randomly selected/unselected verts */
@@ -126,8 +126,8 @@ void bmo_weld_verts_exec(BMesh *bm, BMOperator *op)
BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
if (BMO_elem_flag_test(bm, e->v1, ELE_DEL) || BMO_elem_flag_test(bm, e->v2, ELE_DEL)) {
- v = BMO_slot_map_ptr_get(slot_targetmap, e->v1);
- v2 = BMO_slot_map_ptr_get(slot_targetmap, e->v2);
+ v = BMO_slot_map_elem_get(slot_targetmap, e->v1);
+ v2 = BMO_slot_map_elem_get(slot_targetmap, e->v2);
if (!v) v = e->v1;
if (!v2) v2 = e->v2;
@@ -136,7 +136,7 @@ void bmo_weld_verts_exec(BMesh *bm, BMOperator *op)
BMO_elem_flag_enable(bm, e, EDGE_COL);
}
else if (!BM_edge_exists(v, v2)) {
- BM_edge_create(bm, v, v2, e, TRUE);
+ BM_edge_create(bm, v, v2, e, BM_CREATE_NO_DOUBLE);
}
BMO_elem_flag_enable(bm, e, ELE_DEL);
@@ -175,10 +175,10 @@ void bmo_weld_verts_exec(BMesh *bm, BMOperator *op)
v = l->v;
v2 = l->next->v;
if (BMO_elem_flag_test(bm, v, ELE_DEL)) {
- v = BMO_slot_map_ptr_get(slot_targetmap, v);
+ v = BMO_slot_map_elem_get(slot_targetmap, v);
}
if (BMO_elem_flag_test(bm, v2, ELE_DEL)) {
- v2 = BMO_slot_map_ptr_get(slot_targetmap, v2);
+ v2 = BMO_slot_map_elem_get(slot_targetmap, v2);
}
e2 = v != v2 ? BM_edge_exists(v, v2) : NULL;
@@ -208,13 +208,13 @@ void bmo_weld_verts_exec(BMesh *bm, BMOperator *op)
v2 = loops[1]->v;
if (BMO_elem_flag_test(bm, v, ELE_DEL)) {
- v = BMO_slot_map_ptr_get(slot_targetmap, v);
+ v = BMO_slot_map_elem_get(slot_targetmap, v);
}
if (BMO_elem_flag_test(bm, v2, ELE_DEL)) {
- v2 = BMO_slot_map_ptr_get(slot_targetmap, v2);
+ v2 = BMO_slot_map_elem_get(slot_targetmap, v2);
}
- f2 = BM_face_create_ngon(bm, v, v2, edges, a, TRUE);
+ f2 = BM_face_create_ngon(bm, v, v2, edges, a, BM_CREATE_NO_DOUBLE);
if (f2 && (f2 != f)) {
BM_elem_attrs_copy(bm, bm, f, f2);
@@ -258,19 +258,19 @@ void bmo_pointmerge_facedata_exec(BMesh *bm, BMOperator *op)
{
BMOIter siter;
BMIter iter;
- BMVert *v, *snapv;
+ BMVert *v, *vert_snap;
BMLoop *l, *firstl = NULL;
float fac;
int i, tot;
- snapv = BMO_iter_new(&siter, op->slots_in, "snapv", BM_VERT);
- tot = BM_vert_face_count(snapv);
+ vert_snap = BMO_slot_buffer_get_single(BMO_slot_get(op->slots_in, "vert_snap"));
+ tot = BM_vert_face_count(vert_snap);
if (!tot)
return;
fac = 1.0f / tot;
- BM_ITER_ELEM (l, &iter, snapv, BM_LOOPS_OF_VERT) {
+ BM_ITER_ELEM (l, &iter, vert_snap, BM_LOOPS_OF_VERT) {
if (!firstl) {
firstl = l;
}
@@ -343,7 +343,7 @@ void bmo_pointmerge_exec(BMesh *bm, BMOperator *op)
{
BMOperator weldop;
BMOIter siter;
- BMVert *v, *snapv = NULL;
+ BMVert *v, *vert_snap = NULL;
float vec[3];
BMOpSlot *slot_targetmap;
@@ -355,12 +355,12 @@ void bmo_pointmerge_exec(BMesh *bm, BMOperator *op)
slot_targetmap = BMO_slot_get(weldop.slots_in, "targetmap");
BMO_ITER (v, &siter, op->slots_in, "verts", BM_VERT) {
- if (!snapv) {
- snapv = v;
- copy_v3_v3(snapv->co, vec);
+ if (!vert_snap) {
+ vert_snap = v;
+ copy_v3_v3(vert_snap->co, vec);
}
else {
- BMO_slot_map_ptr_insert(&weldop, slot_targetmap, v, snapv);
+ BMO_slot_map_elem_insert(&weldop, slot_targetmap, v, vert_snap);
}
}
@@ -414,9 +414,9 @@ void bmo_collapse_exec(BMesh *bm, BMOperator *op)
copy_v3_v3(edges[i]->v2->co, center);
if (edges[i]->v1 != edges[0]->v1)
- BMO_slot_map_ptr_insert(&weldop, slot_targetmap, edges[i]->v1, edges[0]->v1);
+ BMO_slot_map_elem_insert(&weldop, slot_targetmap, edges[i]->v1, edges[0]->v1);
if (edges[i]->v2 != edges[0]->v1)
- BMO_slot_map_ptr_insert(&weldop, slot_targetmap, edges[i]->v2, edges[0]->v1);
+ BMO_slot_map_elem_insert(&weldop, slot_targetmap, edges[i]->v2, edges[0]->v1);
}
}
@@ -554,7 +554,7 @@ static void bmesh_find_doubles_common(BMesh *bm, BMOperator *op,
BMO_elem_flag_enable(bm, v_other, VERT_DOUBLE);
BMO_elem_flag_enable(bm, v_check, VERT_TARGET);
- BMO_slot_map_ptr_insert(optarget, optarget_slot, v_other, v_check);
+ BMO_slot_map_elem_insert(optarget, optarget_slot, v_other, v_check);
}
}
}
diff --git a/source/blender/bmesh/operators/bmo_slide.c b/source/blender/bmesh/operators/bmo_slide.c
index 9dde2461364..ea9f9bf9eba 100644
--- a/source/blender/bmesh/operators/bmo_slide.c
+++ b/source/blender/bmesh/operators/bmo_slide.c
@@ -53,11 +53,10 @@ void bmo_slide_vert_exec(BMesh *bm, BMOperator *op)
int selected_edges = 0;
/* Get slide amount */
- const float distance_t = BMO_slot_float_get(op->slots_in, "distance_t");
+ const float factor = BMO_slot_float_get(op->slots_in, "factor");
/* Get start vertex */
- vertex = BMO_iter_new(&oiter, op->slots_in, "vert", BM_VERT);
-
+ vertex = BMO_slot_buffer_get_single(BMO_slot_get(op->slots_in, "vert"));
if (!vertex) {
if (G.debug & G_DEBUG) {
@@ -67,15 +66,13 @@ void bmo_slide_vert_exec(BMesh *bm, BMOperator *op)
return;
}
+ /* BMESH_TODO - this is odd, it only uses one edge, why take a list at all? */
/* Count selected edges */
- BMO_ITER (h, &oiter, op->slots_in, "edge", BM_VERT | BM_EDGE) {
- switch (h->htype) {
- case BM_EDGE:
- selected_edges++;
- /* Mark all selected edges (cast BMHeader->BMEdge) */
- BMO_elem_flag_enable(bm, (BMElemF *)h, EDGE_MARK);
- break;
- }
+ BMO_ITER (h, &oiter, op->slots_in, "edges", BM_EDGE) {
+ selected_edges++;
+ /* Mark all selected edges (cast BMHeader->BMEdge) */
+ BMO_elem_flag_enable(bm, (BMElemF *)h, EDGE_MARK);
+ break;
}
/* Only allow sliding if an edge is selected */
@@ -104,7 +101,7 @@ void bmo_slide_vert_exec(BMesh *bm, BMOperator *op)
BMO_elem_flag_enable(bm, vertex, VERT_MARK);
/* Interpolate */
- interp_v3_v3v3(vertex->co, vertex->co, other->co, distance_t);
+ interp_v3_v3v3(vertex->co, vertex->co, other->co, factor);
}
/* Return the new edge. The same previously marked with VERT_MARK */
diff --git a/source/blender/bmesh/operators/bmo_smooth_laplacian.c b/source/blender/bmesh/operators/bmo_smooth_laplacian.c
index 4137c31961c..4a367a8fd6f 100644
--- a/source/blender/bmesh/operators/bmo_smooth_laplacian.c
+++ b/source/blender/bmesh/operators/bmo_smooth_laplacian.c
@@ -544,6 +544,7 @@ void bmo_smooth_laplacian_vert_exec(BMesh *bm, BMOperator *op)
BMVert *v;
LaplacianSystem *sys;
+ if (bm->totface == 0) return;
sys = init_laplacian_system(bm->totedge, bm->totface, bm->totvert);
if (!sys) return;
sys->bm = bm;
diff --git a/source/blender/bmesh/operators/bmo_subdivide.c b/source/blender/bmesh/operators/bmo_subdivide.c
index f9b6611c88b..7407eb4423a 100644
--- a/source/blender/bmesh/operators/bmo_subdivide.c
+++ b/source/blender/bmesh/operators/bmo_subdivide.c
@@ -226,7 +226,7 @@ static BMVert *subdivideedgenum(BMesh *bm, BMEdge *edge, BMEdge *oedge,
float percent, percent2 = 0.0f;
if (BMO_elem_flag_test(bm, edge, EDGE_PERCENT) && totpoint == 1) {
- percent = BMO_slot_map_float_get(params->slot_edgepercents, edge);
+ percent = BMO_slot_map_float_get(params->slot_edge_percents, edge);
}
else {
percent = 1.0f / (float)(totpoint + 1 - curpoint);
@@ -715,7 +715,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
BMFace *face;
BLI_array_declare(verts);
float smooth, fractal, along_normal;
- int use_sphere, cornertype, use_singleedge, use_gridfill;
+ int use_sphere, cornertype, use_single_edge, use_grid_fill, use_only_quads;
int skey, seed, i, j, matched, a, b, numcuts, totesel;
BMO_slot_buffer_flag_enable(bm, op->slots_in, "edges", BM_EDGE, SUBD_SPLIT);
@@ -727,9 +727,10 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
along_normal = BMO_slot_float_get(op->slots_in, "along_normal");
cornertype = BMO_slot_int_get(op->slots_in, "quad_corner_type");
- use_singleedge = BMO_slot_bool_get(op->slots_in, "use_singleedge");
- use_gridfill = BMO_slot_bool_get(op->slots_in, "use_gridfill");
- use_sphere = BMO_slot_bool_get(op->slots_in, "use_sphere");
+ use_single_edge = BMO_slot_bool_get(op->slots_in, "use_single_edge");
+ use_grid_fill = BMO_slot_bool_get(op->slots_in, "use_grid_fill");
+ use_only_quads = BMO_slot_bool_get(op->slots_in, "use_only_quads");
+ use_sphere = BMO_slot_bool_get(op->slots_in, "use_sphere");
BLI_srandom(seed);
@@ -747,7 +748,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
break;
}
- if (use_singleedge) {
+ if (use_single_edge) {
patterns[0] = &quad_1edge;
patterns[2] = &tri_1edge;
}
@@ -756,7 +757,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
patterns[2] = NULL;
}
- if (use_gridfill) {
+ if (use_grid_fill) {
patterns[3] = &quad_4edge;
patterns[5] = &tri_3edge;
}
@@ -779,8 +780,8 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
params.numcuts = numcuts;
params.op = op;
- params.slot_edgepercents = BMO_slot_get(op->slots_in, "edgepercents");
- params.slot_custompatterns = BMO_slot_get(op->slots_in, "custompatterns");
+ params.slot_edge_percents = BMO_slot_get(op->slots_in, "edge_percents");
+ params.slot_custom_patterns = BMO_slot_get(op->slots_in, "custom_patterns");
params.smooth = smooth;
params.seed = seed;
params.fractal = fractal;
@@ -793,10 +794,10 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
params.off[1] = (float)BLI_drand() * 200.0f;
params.off[2] = (float)BLI_drand() * 200.0f;
- BMO_slot_map_to_flag(bm, op->slots_in, "custompatterns",
+ BMO_slot_map_to_flag(bm, op->slots_in, "custom_patterns",
BM_FACE, FACE_CUSTOMFILL);
- BMO_slot_map_to_flag(bm, op->slots_in, "edgepercents",
+ BMO_slot_map_to_flag(bm, op->slots_in, "edge_percents",
BM_EDGE, EDGE_PERCENT);
@@ -804,6 +805,10 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
BMEdge *e1 = NULL, *e2 = NULL;
float vec1[3], vec2[3];
+ /* skip non-quads if requested */
+ if (use_only_quads && face->len != 4)
+ continue;
+
/* figure out which pattern to use */
BLI_array_empty(edges);
@@ -840,7 +845,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
}
if (BMO_elem_flag_test(bm, face, FACE_CUSTOMFILL)) {
- pat = BMO_slot_map_data_get(params.slot_custompatterns, face);
+ pat = BMO_slot_map_data_get(params.slot_custom_patterns, face);
for (i = 0; i < pat->len; i++) {
matched = 1;
for (j = 0; j < pat->len; j++) {
@@ -1077,10 +1082,10 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
BLI_array_free(loops_split);
BLI_array_free(loops);
- BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom_inner.out", BM_ALL, ELE_INNER);
- BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom_split.out", BM_ALL, ELE_SPLIT);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom_inner.out", BM_ALL_NOLOOP, ELE_INNER);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom_split.out", BM_ALL_NOLOOP, ELE_SPLIT);
- BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom.out", BM_ALL, ELE_INNER | ELE_SPLIT | SUBD_SPLIT);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom.out", BM_ALL_NOLOOP, ELE_INNER | ELE_SPLIT | SUBD_SPLIT);
}
/* editmesh-emulating function */
@@ -1088,7 +1093,8 @@ void BM_mesh_esubdivide(BMesh *bm, const char edge_hflag,
float smooth, float fractal, float along_normal,
int numcuts,
int seltype, int cornertype,
- const short use_singleedge, const short use_gridfill,
+ const short use_single_edge, const short use_grid_fill,
+ const short use_only_quads,
int seed)
{
BMOperator op;
@@ -1099,13 +1105,15 @@ void BM_mesh_esubdivide(BMesh *bm, const char edge_hflag,
"smooth=%f fractal=%f along_normal=%f "
"cuts=%i "
"quad_corner_type=%i "
- "use_singleedge=%b use_gridfill=%b "
+ "use_single_edge=%b use_grid_fill=%b "
+ "use_only_quads=%b "
"seed=%i",
edge_hflag,
smooth, fractal, along_normal,
numcuts,
cornertype,
- use_singleedge, use_gridfill,
+ use_single_edge, use_grid_fill,
+ use_only_quads,
seed);
BMO_op_exec(bm, &op);
@@ -1162,7 +1170,7 @@ void bmo_bisect_edges_exec(BMesh *bm, BMOperator *op)
params.numcuts = BMO_slot_int_get(op->slots_in, "cuts");
params.op = op;
- params.slot_edgepercents = BMO_slot_get(op->slots_in, "edgepercents");
+ params.slot_edge_percents = BMO_slot_get(op->slots_in, "edge_percents");
BM_data_layer_add(bm, &bm->vdata, CD_SHAPEKEY);
skey = CustomData_number_of_layers(&bm->vdata, CD_SHAPEKEY) - 1;
@@ -1174,7 +1182,7 @@ void bmo_bisect_edges_exec(BMesh *bm, BMOperator *op)
bm_subdivide_multicut(bm, e, &params, e->v1, e->v2);
}
- BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom_split.out", BM_ALL, ELE_SPLIT);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom_split.out", BM_ALL_NOLOOP, ELE_SPLIT);
BM_data_layer_free_n(bm, &bm->vdata, CD_SHAPEKEY, skey);
}
diff --git a/source/blender/bmesh/operators/bmo_subdivide.h b/source/blender/bmesh/operators/bmo_subdivide.h
index d0676508917..529075aab02 100644
--- a/source/blender/bmesh/operators/bmo_subdivide.h
+++ b/source/blender/bmesh/operators/bmo_subdivide.h
@@ -39,8 +39,8 @@ typedef struct SubDParams {
int seed;
int origkey; /* shapekey holding displaced vertex coordinates for current geometry */
BMOperator *op;
- BMOpSlot *slot_edgepercents; /* BMO_slot_get(params->op->slots_in, "edgepercents"); */
- BMOpSlot *slot_custompatterns; /* BMO_slot_get(params->op->slots_in, "custompatterns"); */
+ BMOpSlot *slot_edge_percents; /* BMO_slot_get(params->op->slots_in, "edge_percents"); */
+ BMOpSlot *slot_custom_patterns; /* BMO_slot_get(params->op->slots_in, "custom_patterns"); */
float off[3];
} SubDParams;
diff --git a/source/blender/bmesh/operators/bmo_symmetrize.c b/source/blender/bmesh/operators/bmo_symmetrize.c
index 8c440cae83e..248c7268ac6 100644
--- a/source/blender/bmesh/operators/bmo_symmetrize.c
+++ b/source/blender/bmesh/operators/bmo_symmetrize.c
@@ -106,7 +106,7 @@ static void symm_verts_mirror(Symm *symm)
copy_v3_v3(co, src_v->co);
co[symm->axis] = -co[symm->axis];
- dst_v = BM_vert_create(symm->bm, co, src_v);
+ dst_v = BM_vert_create(symm->bm, co, src_v, 0);
BMO_elem_flag_enable(symm->bm, dst_v, SYMM_OUTPUT_GEOM);
BLI_ghash_insert(symm->vert_symm_map, src_v, dst_v);
break;
@@ -183,7 +183,7 @@ static void symm_split_asymmetric_edges(Symm *symm)
co[symm->axis] = 0;
/* Edge is asymmetric, split it with a new vertex */
- v = BM_vert_create(symm->bm, co, e->v1);
+ v = BM_vert_create(symm->bm, co, e->v1, 0);
BMO_elem_flag_enable(symm->bm, v, SYMM_OUTPUT_GEOM);
BLI_ghash_insert(symm->edge_split_map, e, v);
}
@@ -203,7 +203,7 @@ static void symm_mirror_edges(Symm *symm)
v2 = BLI_ghash_lookup(symm->vert_symm_map, e->v2);
if (v1 && v2) {
- e_new = BM_edge_create(symm->bm, v1, v2, e, TRUE);
+ e_new = BM_edge_create(symm->bm, v1, v2, e, BM_CREATE_NO_DOUBLE);
BMO_elem_flag_enable(symm->bm, e_new, SYMM_OUTPUT_GEOM);
}
else if (v1 || v2) {
@@ -212,18 +212,18 @@ static void symm_mirror_edges(Symm *symm)
/* Output the keep side of the split edge */
if (!v1) {
- e_new = BM_edge_create(symm->bm, v_split, e->v2, e, TRUE);
+ e_new = BM_edge_create(symm->bm, v_split, e->v2, e, BM_CREATE_NO_DOUBLE);
BMO_elem_flag_enable(symm->bm, e_new, SYMM_OUTPUT_GEOM);
v1 = v_split;
}
else {
- e_new = BM_edge_create(symm->bm, e->v1, v_split, e, TRUE);
+ e_new = BM_edge_create(symm->bm, e->v1, v_split, e, BM_CREATE_NO_DOUBLE);
BMO_elem_flag_enable(symm->bm, e_new, SYMM_OUTPUT_GEOM);
v2 = v_split;
}
/* Output the kill side of the split edge */
- e_new = BM_edge_create(symm->bm, v1, v2, e, TRUE);
+ e_new = BM_edge_create(symm->bm, v1, v2, e, BM_CREATE_NO_DOUBLE);
BMO_elem_flag_enable(symm->bm, e_new, SYMM_OUTPUT_GEOM);
}
}
@@ -245,6 +245,8 @@ typedef struct {
/* True only if none of the polygon's edges were split */
int already_symmetric;
+
+ BMFace *src_face;
} SymmPoly;
static void symm_poly_with_splits(const Symm *symm,
@@ -255,6 +257,8 @@ static void symm_poly_with_splits(const Symm *symm,
BMLoop *l;
int i;
+ out->src_face = f;
+
/* Count vertices and check for edge splits */
out->len = f->len;
out->already_symmetric = TRUE;
@@ -351,7 +355,8 @@ static int symm_poly_next_crossing(const Symm *symm,
return FALSE;
}
-static BMFace *symm_face_create_v(BMesh *bm, BMVert **fv, BMEdge **fe, int len)
+static BMFace *symm_face_create_v(BMesh *bm, BMFace *example,
+ BMVert **fv, BMEdge **fe, int len)
{
BMFace *f_new;
int i;
@@ -360,11 +365,13 @@ static BMFace *symm_face_create_v(BMesh *bm, BMVert **fv, BMEdge **fe, int len)
int j = (i + 1) % len;
fe[i] = BM_edge_exists(fv[i], fv[j]);
if (!fe[i]) {
- fe[i] = BM_edge_create(bm, fv[i], fv[j], NULL, FALSE);
+ fe[i] = BM_edge_create(bm, fv[i], fv[j], NULL, 0);
BMO_elem_flag_enable(bm, fe[i], SYMM_OUTPUT_GEOM);
}
}
- f_new = BM_face_create(bm, fv, fe, len, TRUE);
+ f_new = BM_face_create(bm, fv, fe, len, BM_CREATE_NO_DOUBLE);
+ if (example)
+ BM_elem_attrs_copy(bm, bm, example, f_new);
BM_face_select_set(bm, f_new, TRUE);
BMO_elem_flag_enable(bm, f_new, SYMM_OUTPUT_GEOM);
return f_new;
@@ -399,7 +406,7 @@ static void symm_mesh_output_poly_zero_splits(Symm *symm,
}
}
- symm_face_create_v(symm->bm, fv, fe, j);
+ symm_face_create_v(symm->bm, sp->src_face, fv, fe, j);
}
static void symm_mesh_output_poly_with_splits(Symm *symm,
@@ -422,7 +429,7 @@ static void symm_mesh_output_poly_with_splits(Symm *symm,
fv[i] = v;
}
- symm_face_create_v(symm->bm, fv, fe, segment_len);
+ symm_face_create_v(symm->bm, sp->src_face, fv, fe, segment_len);
/* Output the kill side of the input polygon */
@@ -434,7 +441,7 @@ static void symm_mesh_output_poly_with_splits(Symm *symm,
}
- symm_face_create_v(symm->bm, fv, fe, segment_len);
+ symm_face_create_v(symm->bm, sp->src_face, fv, fe, segment_len);
}
static void symm_mirror_polygons(Symm *symm)
@@ -482,7 +489,7 @@ static void symm_mirror_polygons(Symm *symm)
fv[i] = l->v;
}
- symm_face_create_v(symm->bm, fv, fe, f->len);
+ symm_face_create_v(symm->bm, f, fv, fe, f->len);
}
else if (ignore_all) {
BM_face_kill(symm->bm, f);
@@ -589,7 +596,7 @@ static void symm_mirror_polygons(Symm *symm)
BLI_assert(fv[0] && fv[1] && fv[2]);
- symm_face_create_v(symm->bm, fv, fe, 3);
+ symm_face_create_v(symm->bm, NULL, fv, fe, 3);
}
}
}
@@ -659,5 +666,5 @@ void bmo_symmetrize_exec(BMesh *bm, BMOperator *op)
BLI_ghash_free(symm.edge_split_map, NULL, NULL);
BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom.out",
- BM_ALL, SYMM_OUTPUT_GEOM);
+ BM_ALL_NOLOOP, SYMM_OUTPUT_GEOM);
}
diff --git a/source/blender/bmesh/operators/bmo_triangulate.c b/source/blender/bmesh/operators/bmo_triangulate.c
index 775fa0cb60d..d20d01af114 100644
--- a/source/blender/bmesh/operators/bmo_triangulate.c
+++ b/source/blender/bmesh/operators/bmo_triangulate.c
@@ -53,7 +53,7 @@ void bmo_triangulate_exec(BMesh *bm, BMOperator *op)
BLI_array_declare(projectverts);
int i;
const int use_beauty = BMO_slot_bool_get(op->slots_in, "use_beauty");
- BMOpSlot *slot_facemap_out = BMO_slot_get(op->slots_out, "facemap.out");
+ BMOpSlot *slot_facemap_out = BMO_slot_get(op->slots_out, "face_map.out");
for (face = BMO_iter_new(&siter, op->slots_in, "faces", BM_FACE); face; face = BMO_iter_step(&siter)) {
@@ -65,9 +65,9 @@ void bmo_triangulate_exec(BMesh *bm, BMOperator *op)
BM_face_triangulate(bm, face, projectverts, EDGE_NEW, FACE_NEW, newfaces, use_beauty);
- BMO_slot_map_ptr_insert(op, slot_facemap_out, face, face);
+ BMO_slot_map_elem_insert(op, slot_facemap_out, face, face);
for (i = 0; newfaces[i]; i++) {
- BMO_slot_map_ptr_insert(op, slot_facemap_out, newfaces[i], face);
+ BMO_slot_map_elem_insert(op, slot_facemap_out, newfaces[i], face);
}
}
@@ -190,7 +190,7 @@ void bmo_triangle_fill_exec(BMesh *bm, BMOperator *op)
/* sf_edge->tmp.p = e; */ /* UNUSED */
}
- BLI_scanfill_calc(&sf_ctx, FALSE);
+ BLI_scanfill_calc(&sf_ctx, 0);
for (sf_tri = sf_ctx.fillfacebase.first; sf_tri; sf_tri = sf_tri->next) {
BMFace *f = BM_face_create_quad_tri(bm,
diff --git a/source/blender/bmesh/operators/bmo_utils.c b/source/blender/bmesh/operators/bmo_utils.c
index d56b2ca0d73..64dbf0cc0e7 100644
--- a/source/blender/bmesh/operators/bmo_utils.c
+++ b/source/blender/bmesh/operators/bmo_utils.c
@@ -47,7 +47,7 @@ void bmo_create_vert_exec(BMesh *bm, BMOperator *op)
BMO_slot_vec_get(op->slots_in, "co", vec);
- BMO_elem_flag_enable(bm, BM_vert_create(bm, vec, NULL), 1);
+ BMO_elem_flag_enable(bm, BM_vert_create(bm, vec, NULL, 0), 1);
BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "vert.out", BM_VERT, 1);
}
@@ -57,7 +57,7 @@ void bmo_transform_exec(BMesh *UNUSED(bm), BMOperator *op)
BMVert *v;
float mat[4][4];
- BMO_slot_mat4_get(op->slots_in, "mat", mat);
+ BMO_slot_mat4_get(op->slots_in, "matrix", mat);
BMO_ITER (v, &iter, op->slots_in, "verts", BM_VERT) {
mul_m4_v3(mat, v->co);
@@ -73,7 +73,7 @@ void bmo_translate_exec(BMesh *bm, BMOperator *op)
unit_m4(mat);
copy_v3_v3(mat[3], vec);
- BMO_op_callf(bm, op->flag, "transform mat=%m4 verts=%s", mat, op, "verts");
+ BMO_op_callf(bm, op->flag, "transform matrix=%m4 verts=%s", mat, op, "verts");
}
void bmo_scale_exec(BMesh *bm, BMOperator *op)
@@ -87,7 +87,7 @@ void bmo_scale_exec(BMesh *bm, BMOperator *op)
mat[1][1] = vec[1];
mat[2][2] = vec[2];
- BMO_op_callf(bm, op->flag, "transform mat=%m3 verts=%s", mat, op, "verts");
+ BMO_op_callf(bm, op->flag, "transform matrix=%m3 verts=%s", mat, op, "verts");
}
void bmo_rotate_exec(BMesh *bm, BMOperator *op)
@@ -102,7 +102,7 @@ void bmo_rotate_exec(BMesh *bm, BMOperator *op)
mul_v3_fl(vec, -1.0f);
BMO_op_callf(bm, op->flag, "translate verts=%s vec=%v", op, "verts", vec);
- BMO_op_callf(bm, op->flag, "transform mat=%s verts=%s", op, "mat", op, "verts");
+ BMO_op_callf(bm, op->flag, "transform matrix=%s verts=%s", op, "matrix", op, "verts");
mul_v3_fl(vec, -1.0f);
BMO_op_callf(bm, op->flag, "translate verts=%s vec=%v", op, "verts", vec);
@@ -268,14 +268,14 @@ void bmo_region_extend_exec(BMesh *bm, BMOperator *op)
int use_faces = BMO_slot_bool_get(op->slots_in, "use_faces");
int constrict = BMO_slot_bool_get(op->slots_in, "use_constrict");
- BMO_slot_buffer_flag_enable(bm, op->slots_in, "geom", BM_ALL, SEL_ORIG);
+ BMO_slot_buffer_flag_enable(bm, op->slots_in, "geom", BM_ALL_NOLOOP, SEL_ORIG);
if (constrict)
bmo_region_extend_constrict(bm, op, use_faces);
else
bmo_region_extend_extend(bm, op, use_faces);
- BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom.out", BM_ALL, SEL_FLAG);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom.out", BM_ALL_NOLOOP, SEL_FLAG);
}
/********* righthand faces implementation ****** */
@@ -701,9 +701,8 @@ typedef struct ElemNode {
void bmo_shortest_path_exec(BMesh *bm, BMOperator *op)
{
- BMOIter vs_iter /* , vs2_iter */; /* selected verts iterator */
BMIter v_iter; /* mesh verts iterator */
- BMVert *vs, *sv, *ev; /* starting vertex, ending vertex */
+ BMVert *sv, *ev; /* starting vertex, ending vertex */
BMVert *v; /* mesh vertex */
Heap *h = NULL;
@@ -712,13 +711,8 @@ void bmo_shortest_path_exec(BMesh *bm, BMOperator *op)
int num_total = 0 /*, num_sels = 0 */, i = 0;
const int type = BMO_slot_int_get(op->slots_in, "type");
- /* BMESH_TODO use BMO_slot_buffer_elem_first here? */
- BMO_ITER (vs, &vs_iter, op->slots_in, "startv", BM_VERT) {
- sv = vs;
- }
- BMO_ITER (vs, &vs_iter, op->slots_in, "endv", BM_VERT) {
- ev = vs;
- }
+ sv = BMO_slot_buffer_get_single(BMO_slot_get(op->slots_in, "vert_start"));
+ ev = BMO_slot_buffer_get_single(BMO_slot_get(op->slots_in, "vert_end"));
num_total = BM_mesh_elem_count(bm, BM_VERT);
diff --git a/source/blender/bmesh/operators/bmo_wireframe.c b/source/blender/bmesh/operators/bmo_wireframe.c
index 532145ab129..7401704310f 100644
--- a/source/blender/bmesh/operators/bmo_wireframe.c
+++ b/source/blender/bmesh/operators/bmo_wireframe.c
@@ -227,9 +227,9 @@ void bmo_wireframe_exec(BMesh *bm, BMOperator *op)
}
madd_v3_v3v3fl(tvec, v_src->co, v_src->no, -fac);
- verts_neg[i] = BM_vert_create(bm, tvec, v_src);
+ verts_neg[i] = BM_vert_create(bm, tvec, v_src, 0);
madd_v3_v3v3fl(tvec, v_src->co, v_src->no, fac);
- verts_pos[i] = BM_vert_create(bm, tvec, v_src);
+ verts_pos[i] = BM_vert_create(bm, tvec, v_src, 0);
}
else {
/* could skip this */
@@ -267,7 +267,7 @@ void bmo_wireframe_exec(BMesh *bm, BMOperator *op)
}
madd_v3_v3v3fl(tvec, l->v->co, tvec, fac);
- verts_loop[verts_loop_tot] = BM_vert_create(bm, tvec, l->v);
+ verts_loop[verts_loop_tot] = BM_vert_create(bm, tvec, l->v, 0);
if (use_boundary) {
@@ -301,7 +301,7 @@ void bmo_wireframe_exec(BMesh *bm, BMOperator *op)
fac *= verts_relfac[BM_elem_index_get(l_pair[i]->v)];
}
madd_v3_v3v3fl(tvec, l_pair[i]->v->co, tvec, fac);
- verts_boundary[BM_elem_index_get(l_pair[i]->v)] = BM_vert_create(bm, tvec, l_pair[i]->v);
+ verts_boundary[BM_elem_index_get(l_pair[i]->v)] = BM_vert_create(bm, tvec, l_pair[i]->v, 0);
}
}
}
diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c
index 75e74155f66..cb35616a1f7 100644
--- a/source/blender/bmesh/tools/bmesh_bevel.c
+++ b/source/blender/bmesh/tools/bmesh_bevel.c
@@ -164,7 +164,7 @@ static NewVert *mesh_vert(VMesh *vm, int i, int j, int k)
static void create_mesh_bmvert(BMesh *bm, VMesh *vm, int i, int j, int k, BMVert *eg)
{
NewVert *nv = mesh_vert(vm, i, j, k);
- nv->v = BM_vert_create(bm, nv->co, eg);
+ nv->v = BM_vert_create(bm, nv->co, eg, 0);
}
static void copy_mesh_vert(VMesh *vm, int ito, int jto, int kto,
@@ -264,14 +264,13 @@ static BMFace *bev_create_ngon(BMesh *bm, BMVert **vert_arr, const int totv, BMF
else {
int i;
BMEdge **ee = NULL;
- BLI_array_staticdeclare(ee, BM_DEFAULT_NGON_STACK_SIZE);
+ BLI_array_fixedstack_declare(ee, BM_DEFAULT_NGON_STACK_SIZE, totv, __func__);
- BLI_array_grow_items(ee, totv);
for (i = 0; i < totv; i++) {
- ee[i] = BM_edge_create(bm, vert_arr[i], vert_arr[(i + 1) % totv], NULL, TRUE);
+ ee[i] = BM_edge_create(bm, vert_arr[i], vert_arr[(i + 1) % totv], NULL, BM_CREATE_NO_DOUBLE);
}
- f = BM_face_create_ngon(bm, vert_arr[0], vert_arr[1], ee, totv, FALSE);
- BLI_array_free(ee);
+ f = BM_face_create_ngon(bm, vert_arr[0], vert_arr[1], ee, totv, 0);
+ BLI_array_fixedstack_free(ee);
}
if (facerep && f) {
int has_mdisps = CustomData_has_layer(&bm->ldata, CD_MDISPS);
@@ -366,13 +365,19 @@ static void offset_meet(EdgeHalf *e1, EdgeHalf *e2, BMVert *v, BMFace *f,
}
/* Like offset_meet, but here f1 and f2 must not be NULL and give the
- * planes in which to run the offset lines. They may not meet exactly,
- * but the line intersection routine will find the closest approach point. */
-static void offset_in_two_planes(EdgeHalf *e1, EdgeHalf *e2, BMVert *v,
- BMFace *f1, BMFace *f2, float meetco[3])
+ * planes in which to run the offset lines.
+ * They may not meet exactly: the offsets for the edges may be different
+ * or both the planes and the lines may be angled so that they can't meet.
+ * In that case, pick a close point on emid, which should be the dividing
+ * edge between the two planes.
+ * TODO: should have a global 'offset consistency' prepass to adjust offset
+ * widths so that all edges have the same offset at both ends. */
+static void offset_in_two_planes(EdgeHalf *e1, EdgeHalf *e2, EdgeHalf *emid,
+ BMVert *v, BMFace *f1, BMFace *f2, float meetco[3])
{
float dir1[3], dir2[3], norm_perp1[3], norm_perp2[3],
- off1a[3], off1b[3], off2a[3], off2b[3], isect2[3];
+ off1a[3], off1b[3], off2a[3], off2b[3], isect2[3], co[3];
+ int iret;
BLI_assert(f1 != NULL && f2 != NULL);
@@ -398,9 +403,21 @@ static void offset_in_two_planes(EdgeHalf *e1, EdgeHalf *e2, BMVert *v,
/* lines are parallel; off1a is a good meet point */
copy_v3_v3(meetco, off1a);
}
- else if (!isect_line_line_v3(off1a, off1b, off2a, off2b, meetco, isect2)) {
- /* another test says they are parallel */
- copy_v3_v3(meetco, off1a);
+ else {
+ iret =isect_line_line_v3(off1a, off1b, off2a, off2b, meetco, isect2);
+ if (iret == 0) {
+ /* lines colinear: another test says they are parallel. so shouldn't happen */
+ copy_v3_v3(meetco, off1a);
+ }
+ else if (iret == 2) {
+ /* lines are not coplanar; meetco and isect2 are nearest to first and second lines */
+ if (len_v3v3(meetco, isect2) > 100.0f * (float)BEVEL_EPSILON) {
+ /* offset lines don't meet: project average onto emid; this is not ideal (see TODO above) */
+ mid_v3_v3v3(co, meetco, isect2);
+ closest_to_line_v3(meetco, co, v->co, BM_edge_other_vert(emid->e, v)->co);
+ }
+ }
+ /* else iret == 1 and the lines are coplanar so meetco has the intersection */
}
}
@@ -546,6 +563,7 @@ static void get_point_on_round_edge(const float uv[2],
#else /* USE_ALTERNATE_ADJ */
+#ifdef OLD_ROUND_EDGE
/*
* calculation of points on the round profile
* r - result, coordinate of point on round profile
@@ -633,6 +651,66 @@ static void get_point_on_round_edge(EdgeHalf *e, int k,
interp_v3_v3v3(r_co, va, vb, (float)k / (float)n);
}
}
+#else
+
+/*
+ * Find the point (/n) of the way around the round profile for e,
+ * where start point is va, midarc point is vmid, and end point is vb.
+ * Return the answer in profileco.
+ * Method:
+ * Find vo, the origin of the parallelogram with other three points va, vmid, vb.
+ * Also find vd, which is in direction normal to parallelogram and 1 unit away
+ * from the origin.
+ * The quarter circle in first quadrant of unit square will be mapped to the
+ * quadrant of a sheared ellipse in the parallelgram, using a matrix.
+ * The matrix mat is calculated to map:
+ * (0,1,0) -> va
+ * (1,1,0) -> vmid
+ * (1,0,0) -> vb
+ * (0,1,1) -> vd
+ * However if va -- vmid -- vb is approximately a straight line, just
+ * interpolate along the line.
+ */
+static void get_point_on_round_edge(EdgeHalf *e, int k,
+ const float va[3], const float vmid[3], const float vb[3],
+ float r_co[3])
+{
+ float vo[3], vd[3], vb_vmid[3], va_vmid[3], vddir[3], p[3], angle;
+ float m[4][4] = MAT4_UNITY;
+ int n = e->seg;
+
+ sub_v3_v3v3(va_vmid, vmid, va);
+ sub_v3_v3v3(vb_vmid, vmid, vb);
+ if (fabsf(angle_v3v3(va_vmid, vb_vmid) - (float)M_PI) > 100.f *(float)BEVEL_EPSILON) {
+ sub_v3_v3v3(vo, va, vb_vmid);
+ cross_v3_v3v3(vddir, vb_vmid, va_vmid);
+ normalize_v3(vddir);
+ add_v3_v3v3(vd, vo, vddir);
+
+ /* The cols of m are: {vmid - va, vmid - vb, vmid + vd - va -vb, va + vb - vmid;
+ * blender transform matrices are stored such that m[i][*] is ith column;
+ * the last elements of each col remain as they are in unity matrix */
+ sub_v3_v3v3(&m[0][0], vmid, va);
+ sub_v3_v3v3(&m[1][0], vmid, vb);
+ add_v3_v3v3(&m[2][0], vmid, vd);
+ sub_v3_v3(&m[2][0], va);
+ sub_v3_v3(&m[2][0], vb);
+ add_v3_v3v3(&m[3][0], va, vb);
+ sub_v3_v3(&m[3][0], vmid);
+
+ /* Now find point k/(e->seg) along quarter circle from (0,1,0) to (1,0,0) */
+ angle = (float)M_PI * (float)k / (2.0f * (float)n); /* angle from y axis */
+ p[0] = sinf(angle);
+ p[1] = cosf(angle);
+ p[2] = 0.0f;
+ mul_v3_m4v3(r_co, m, p);
+ }
+ else {
+ /* planar case */
+ interp_v3_v3v3(r_co, va, vb, (float)k / (float)n);
+ }
+}
+#endif /* ! OLD_ROUND_EDGE */
#endif /* !USE_ALTERNATE_ADJ */
@@ -693,8 +771,7 @@ static void build_boundary(MemArena *mem_arena, BevVert *bv)
if (e->prev->prev->is_bev) {
BLI_assert(e->prev->prev != e); /* see: edgecount 2, selcount 1 case */
/* find meet point between e->prev->prev and e and attach e->prev there */
- /* TODO: fix case when one or both faces in following are NULL */
- offset_in_two_planes(e->prev->prev, e, bv->v,
+ offset_in_two_planes(e->prev->prev, e, e->prev, bv->v,
e->prev->prev->fnext, e->fprev, co);
v = add_new_bound_vert(mem_arena, vm, co);
v->efirst = e->prev->prev;
@@ -987,7 +1064,7 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv)
}
} while ((v = v->next) != vm->boundstart);
mul_v3_fl(midco, 1.0f / nn);
- bmv = BM_vert_create(bm, midco, NULL);
+ bmv = BM_vert_create(bm, midco, NULL, 0);
v = vm->boundstart;
do {
i = v->index;
diff --git a/source/blender/bmesh/tools/bmesh_decimate.h b/source/blender/bmesh/tools/bmesh_decimate.h
index 4d382d65659..4a557c20ae3 100644
--- a/source/blender/bmesh/tools/bmesh_decimate.h
+++ b/source/blender/bmesh/tools/bmesh_decimate.h
@@ -37,5 +37,8 @@ void BM_mesh_decimate_dissolve_ex(BMesh *bm, const float angle_limit, const int
BMEdge **einput_arr, const int einput_len);
void BM_mesh_decimate_dissolve(BMesh *bm, const float angle_limit, const int do_dissolve_boundaries);
+/* these weights are accumulated so too high values may reach 'inf' too quickly */
+#define BM_MESH_DECIM_WEIGHT_MAX 100000.0f
+#define BM_MESH_DECIM_WEIGHT_EPS (1.0f / BM_MESH_DECIM_WEIGHT_MAX)
#endif /* __BMESH_DECIMATE_H__ */
diff --git a/source/blender/bmesh/tools/bmesh_decimate_collapse.c b/source/blender/bmesh/tools/bmesh_decimate_collapse.c
index 781001508f2..7c054d84405 100644
--- a/source/blender/bmesh/tools/bmesh_decimate_collapse.c
+++ b/source/blender/bmesh/tools/bmesh_decimate_collapse.c
@@ -223,8 +223,8 @@ static void bm_decim_build_edge_cost_single(BMEdge *e,
}
if (vweights) {
- if ((vweights[BM_elem_index_get(e->v1)] < FLT_EPSILON) &&
- (vweights[BM_elem_index_get(e->v2)] < FLT_EPSILON))
+ if ((vweights[BM_elem_index_get(e->v1)] >= BM_MESH_DECIM_WEIGHT_MAX) &&
+ (vweights[BM_elem_index_get(e->v2)] >= BM_MESH_DECIM_WEIGHT_MAX))
{
/* skip collapsing this edge */
eheap_table[BM_elem_index_get(e)] = NULL;
@@ -244,8 +244,9 @@ static void bm_decim_build_edge_cost_single(BMEdge *e,
BLI_quadric_evaluate(q2, optimize_co));
}
else {
- cost = ((BLI_quadric_evaluate(q1, optimize_co) * vweights[BM_elem_index_get(e->v1)]) +
- (BLI_quadric_evaluate(q2, optimize_co) * vweights[BM_elem_index_get(e->v2)]));
+ /* add 1.0 so planar edges are still weighted against */
+ cost = (((BLI_quadric_evaluate(q1, optimize_co) + 1.0f) * vweights[BM_elem_index_get(e->v1)]) +
+ ((BLI_quadric_evaluate(q2, optimize_co) + 1.0f) * vweights[BM_elem_index_get(e->v2)]));
}
// print("COST %.12f\n");
@@ -877,9 +878,7 @@ static void bm_decim_edge_collapse(BMesh *bm, BMEdge *e,
int i;
if (vweights) {
- const int fac = CLAMPIS(customdata_fac, 0.0f, 1.0f);
- vweights[BM_elem_index_get(v_other)] = (vweights[v_clear_index] * (1.0f - fac)) +
- (vweights[BM_elem_index_get(v_other)] * fac);
+ vweights[BM_elem_index_get(v_other)] += vweights[v_clear_index];
}
e = NULL; /* paranoid safety check */
@@ -960,7 +959,7 @@ static void bm_decim_edge_collapse(BMesh *bm, BMEdge *e,
* \brief BM_mesh_decimate
* \param bm The mesh
* \param factor face count multiplier [0 - 1]
- * \param vertex_weights Optional array of vertex aligned weights [0 - 1],
+ * \param vweights Optional array of vertex aligned weights [0 - 1],
* a vertex group is the usual source for this.
*/
void BM_mesh_decimate_collapse(BMesh *bm, const float factor, float *vweights, const int do_triangulate)
diff --git a/source/blender/bmesh/tools/bmesh_decimate_dissolve.c b/source/blender/bmesh/tools/bmesh_decimate_dissolve.c
index d2a5c580ae6..f67f01e4585 100644
--- a/source/blender/bmesh/tools/bmesh_decimate_dissolve.c
+++ b/source/blender/bmesh/tools/bmesh_decimate_dissolve.c
@@ -69,9 +69,6 @@ static int dissolve_elem_cmp(const void *a1, const void *a2)
return 0;
}
-/**
- * \param do_all_verts Collapse all verts between 2 faces - don't check their edge angle.
- */
void BM_mesh_decimate_dissolve_ex(BMesh *bm, const float angle_limit, const int do_dissolve_boundaries,
BMVert **vinput_arr, const int vinput_len,
BMEdge **einput_arr, const int einput_len)
diff --git a/source/blender/collada/MaterialExporter.cpp b/source/blender/collada/MaterialExporter.cpp
index 5a1d8b7602a..4aece997f72 100644
--- a/source/blender/collada/MaterialExporter.cpp
+++ b/source/blender/collada/MaterialExporter.cpp
@@ -70,7 +70,7 @@ void MaterialsExporter::operator()(Material *ma, Object *ob)
{
std::string name(id_name(ma));
- openMaterial(get_material_id(ma), get_material_id(ma));
+ openMaterial(get_material_id(ma), translate_id(name));
std::string efid = translate_id(name) + "-effect";
addInstanceEffect(COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, efid));
diff --git a/source/blender/compositor/intern/COM_ExecutionGroup.cpp b/source/blender/compositor/intern/COM_ExecutionGroup.cpp
index 0553aebbba6..ffc36281874 100644
--- a/source/blender/compositor/intern/COM_ExecutionGroup.cpp
+++ b/source/blender/compositor/intern/COM_ExecutionGroup.cpp
@@ -352,7 +352,8 @@ void ExecutionGroup::execute(ExecutionSystem *graph)
startEvaluated = true;
numberEvaluated++;
- WM_main_add_notifier(NC_WINDOW | ND_DRAW, NULL);
+ if (bTree->update_draw)
+ bTree->update_draw(bTree->udh);
}
else if (state == COM_ES_SCHEDULED) {
finished = false;
diff --git a/source/blender/compositor/intern/COM_ExecutionGroup.h b/source/blender/compositor/intern/COM_ExecutionGroup.h
index c7a7d06134e..00104c24194 100644
--- a/source/blender/compositor/intern/COM_ExecutionGroup.h
+++ b/source/blender/compositor/intern/COM_ExecutionGroup.h
@@ -193,7 +193,7 @@ private:
/**
* @brief try to schedule a specific chunk.
- * @note scheduling succeeds when all input requirements are met and the chunks hasen't been scheduled yet.
+ * @note scheduling succeeds when all input requirements are met and the chunks hasn't been scheduled yet.
* @param graph
* @param xChunk
* @param yChunk
@@ -245,7 +245,7 @@ public:
/**
* @brief add an operation to this ExecutionGroup
- * @note this method will add input of the operations recursivly
+ * @note this method will add input of the operations recursively
* @note this method can create multiple ExecutionGroup's
* @param system
* @param operation
@@ -369,7 +369,7 @@ public:
/**
* @brief this method determines the MemoryProxy's where this execution group depends on.
* @note After this method determineDependingAreaOfInterest can be called to determine
- * @note the area of the MemoryProxy.creator thas has to be executed.
+ * @note the area of the MemoryProxy.creator that has to be executed.
* @param memoryProxies result
*/
void determineDependingMemoryProxies(vector<MemoryProxy *> *memoryProxies);
diff --git a/source/blender/compositor/intern/COM_NodeOperation.h b/source/blender/compositor/intern/COM_NodeOperation.h
index 42d90eca38f..f856d8e6a11 100644
--- a/source/blender/compositor/intern/COM_NodeOperation.h
+++ b/source/blender/compositor/intern/COM_NodeOperation.h
@@ -77,7 +77,7 @@ private:
ThreadMutex m_mutex;
/**
- * @brief reference to the editing bNodeTree only used for break callback
+ * @brief reference to the editing bNodeTree, used for break and update callback
*/
const bNodeTree *m_btree;
@@ -247,6 +247,10 @@ public:
return this->m_btree->test_break(this->m_btree->tbh);
}
+ inline void updateDraw() {
+ if (this->m_btree->update_draw)
+ this->m_btree->update_draw(this->m_btree->udh);
+ }
protected:
NodeOperation();
diff --git a/source/blender/compositor/intern/COM_WorkPackage.h b/source/blender/compositor/intern/COM_WorkPackage.h
index 953a164e95e..2bb124a1c84 100644
--- a/source/blender/compositor/intern/COM_WorkPackage.h
+++ b/source/blender/compositor/intern/COM_WorkPackage.h
@@ -44,7 +44,7 @@ private:
unsigned int m_chunkNumber;
public:
/**
- * @constructor
+ * constructor
* @param group the ExecutionGroup
* @param chunkNumber the number of the chunk
*/
diff --git a/source/blender/compositor/operations/COM_MapRangeOperation.cpp b/source/blender/compositor/operations/COM_MapRangeOperation.cpp
index a18f418e48e..1fe74ade0fc 100644
--- a/source/blender/compositor/operations/COM_MapRangeOperation.cpp
+++ b/source/blender/compositor/operations/COM_MapRangeOperation.cpp
@@ -43,6 +43,9 @@ void MapRangeOperation::initExecution()
this->m_destMaxOperation = this->getInputSocketReader(4);
}
+/* The code below assumes all data is inside range +- this, and that input buffer is single channel */
+#define BLENDER_ZMAX 10000.0f
+
void MapRangeOperation::executePixel(float output[4], float x, float y, PixelSampler sampler)
{
float inputs[8]; /* includes the 5 inputs + 3 pads */
@@ -61,9 +64,15 @@ void MapRangeOperation::executePixel(float output[4], float x, float y, PixelSam
source_max = inputs[2];
dest_min = inputs[3];
dest_max = inputs[4];
-
- value = (value - source_min) / (source_max - source_min);
- value = dest_min + value * (dest_max - dest_min);
+
+ if (value >= -BLENDER_ZMAX && value <= BLENDER_ZMAX) {
+ value = (value - source_min) / (source_max - source_min);
+ value = dest_min + value * (dest_max - dest_min);
+ }
+ else if (value > BLENDER_ZMAX)
+ value = dest_max;
+ else
+ value = dest_min;
if (this->m_useClamp) {
if (dest_max > dest_min) {
diff --git a/source/blender/compositor/operations/COM_NormalizeOperation.cpp b/source/blender/compositor/operations/COM_NormalizeOperation.cpp
index 5f7ac6bb9ca..f81b50e6836 100644
--- a/source/blender/compositor/operations/COM_NormalizeOperation.cpp
+++ b/source/blender/compositor/operations/COM_NormalizeOperation.cpp
@@ -43,6 +43,12 @@ void NormalizeOperation::executePixel(float output[4], int x, int y, void *data)
this->m_imageReader->read(output, x, y, NULL);
output[0] = (output[0] - minmult->x) * minmult->y;
+
+ /* clamp infinities */
+ if (output[0] > 1.0f)
+ output[0] = 1.0f;
+ else if (output[0] < 0.0f)
+ output[0] = 0.0f;
}
void NormalizeOperation::deinitExecution()
diff --git a/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp b/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp
index cc313512316..d5f2c283c72 100644
--- a/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp
+++ b/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp
@@ -103,7 +103,7 @@ void ViewerBaseOperation:: updateImage(rcti *rect)
this->m_viewSettings, this->m_displaySettings,
rect->xmin, rect->ymin, rect->xmax, rect->ymax, FALSE);
- WM_main_add_notifier(NC_WINDOW | ND_DRAW, NULL);
+ this->updateDraw();
}
void ViewerBaseOperation::deinitExecution()
diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c
index 4ac7b61fccb..62ffdc7fd3a 100644
--- a/source/blender/editors/animation/anim_markers.c
+++ b/source/blender/editors/animation/anim_markers.c
@@ -732,7 +732,7 @@ static void ed_marker_move_apply(bContext *C, wmOperator *op)
/* so we get view3d redraws */
BKE_scene_camera_switch_update(scene);
- if(camera != scene->camera) {
+ if (camera != scene->camera) {
BKE_screen_view3d_scene_sync(sc);
WM_event_add_notifier(C, NC_SCENE | NA_EDITED, scene);
}
@@ -860,16 +860,21 @@ static int ed_marker_move_modal(bContext *C, wmOperator *op, wmEvent *evt)
}
if (evt->val == KM_PRESS) {
- float vec;
- char str_tx[NUM_STR_REP_LEN];
-
if (handleNumInput(&mm->num, evt)) {
- applyNumInput(&mm->num, &vec);
- outputNumInput(&mm->num, str_tx);
-
- RNA_int_set(op->ptr, "frames", vec);
+ char str_tx[NUM_STR_REP_LEN];
+ float value = RNA_int_get(op->ptr, "frames");
+ applyNumInput(&mm->num, &value);
+
+ if (hasNumInput(&mm->num)) {
+ outputNumInput(&mm->num, str_tx);
+ }
+ else {
+ BLI_snprintf(str_tx, sizeof(str_tx), "%d", (int)value);
+ }
+
+ RNA_int_set(op->ptr, "frames", value);
ed_marker_move_apply(C, op);
- // ed_marker_header_update(C, op, str, (int)vec[0]);
+ // ed_marker_header_update(C, op, str, (int)value);
// strcat(str, str_tx);
BLI_snprintf(str, sizeof(str), "Marker offset %s", str_tx);
ED_area_headerprint(CTX_wm_area(C), str);
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index bd85e93f1af..d5c9b9ef01a 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -100,11 +100,6 @@ void ED_view3d_depth_tag_update(struct RegionView3D *rv3d);
/* Projection */
#define IS_CLIPPED 12000
-/* TODO, these functions work quite differently, we should make them behave in a uniform way
- * otherwise we can't be sure bugs are not added when we need to move from short->float types for eg
- * - Campbell */
-
-
/* return values for ED_view3d_project_...() */
typedef enum {
V3D_PROJ_RET_OK = 0,
@@ -220,6 +215,9 @@ void ED_view3d_clipping_disable(void);
float ED_view3d_pixel_size(struct RegionView3D *rv3d, const float co[3]);
+float ED_view3d_radius_to_persp_dist(const float angle, const float radius);
+float ED_view3d_radius_to_ortho_dist(const float lens, const float radius);
+
void drawcircball(int mode, const float cent[3], float rad, float tmat[][4]);
/* backbuffer select and draw support */
@@ -295,6 +293,7 @@ struct BGpic *ED_view3D_background_image_new(struct View3D *v3d);
void ED_view3D_background_image_remove(struct View3D *v3d, struct BGpic *bgpic);
void ED_view3D_background_image_clear(struct View3D *v3d);
+#define VIEW3D_MARGIN 1.4f
float ED_view3d_offset_distance(float mat[4][4], float ofs[3]);
float ED_view3d_grid_scale(struct Scene *scene, struct View3D *v3d, const char **grid_unit);
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 3645f13f27a..f5c943fbb87 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -615,7 +615,8 @@ int uiSearchItemAdd(uiSearchItems *items, const char *name, void *poin, int
/* bfunc gets search item *poin as arg2, or if NULL the old string */
void uiButSetSearchFunc(uiBut *but, uiButSearchFunc sfunc, void *arg1, uiButHandleFunc bfunc, void *active);
/* height in pixels, it's using hardcoded values still */
-int uiSearchBoxhHeight(void);
+int uiSearchBoxHeight(void);
+int uiSearchBoxWidth(void);
void uiBlockSetHandleFunc(uiBlock *block, uiBlockHandleFunc func, void *arg);
void uiBlockSetButmFunc(uiBlock *block, uiMenuHandleFunc func, void *arg);
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index 535239cd462..9037afc472a 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -2826,6 +2826,7 @@ static uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, const char *s
EnumPropertyItem *item;
int i, totitem, free;
+ /* TODO, translate after getting the item, saves many lookups */
RNA_property_enum_items_gettexted(block->evil_C, ptr, prop, &item, &totitem, &free);
for (i = 0; i < totitem; i++) {
if (item[i].identifier[0] && item[i].value == (int)max) {
diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c
index c1547593f96..7c099de9c1e 100644
--- a/source/blender/editors/interface/interface_regions.c
+++ b/source/blender/editors/interface/interface_regions.c
@@ -826,11 +826,17 @@ int uiSearchItemAdd(uiSearchItems *items, const char *name, void *poin, int icon
return 1;
}
-int uiSearchBoxhHeight(void)
+int uiSearchBoxHeight(void)
{
return SEARCH_ITEMS * UI_UNIT_Y + 2 * MENU_TOP;
}
+int uiSearchBoxWidth(void)
+{
+ /* was hardcoded at 150 */
+ return 9 * UI_UNIT_X;
+}
+
/* ar is the search box itself */
static void ui_searchbox_select(bContext *C, ARegion *ar, uiBut *but, int step)
{
@@ -1191,10 +1197,11 @@ ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but)
}
}
else {
+ const int searchbox_width = uiSearchBoxWidth();
rect_fl.xmin = but->rect.xmin - 5; /* align text with button */
rect_fl.xmax = but->rect.xmax + 5; /* symmetrical */
rect_fl.ymax = but->rect.ymin;
- rect_fl.ymin = rect_fl.ymax - uiSearchBoxhHeight();
+ rect_fl.ymin = rect_fl.ymax - uiSearchBoxHeight();
ofsx = (but->block->panel) ? but->block->panel->ofsx : 0;
ofsy = (but->block->panel) ? but->block->panel->ofsy : 0;
@@ -1202,8 +1209,8 @@ ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but)
BLI_rctf_translate(&rect_fl, ofsx, ofsy);
/* minimal width */
- if (BLI_rctf_size_x(&rect_fl) < 150) {
- rect_fl.xmax = rect_fl.xmin + 150; /* XXX arbitrary */
+ if (BLI_rctf_size_x(&rect_fl) < searchbox_width) {
+ rect_fl.xmax = rect_fl.xmin + searchbox_width;
}
/* copy to int, gets projected if possible too */
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index 4dbdb977d36..e90fc1d4695 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -191,10 +191,12 @@ static uiBlock *id_search_menu(bContext *C, ARegion *ar, void *arg_litem)
}
/* list view */
else {
+ const int searchbox_width = uiSearchBoxWidth();
+ const int searchbox_height = uiSearchBoxHeight();
/* fake button, it holds space for search items */
- uiDefBut(block, LABEL, 0, "", 10, 15, 150, uiSearchBoxhHeight(), NULL, 0, 0, 0, 0, NULL);
+ uiDefBut(block, LABEL, 0, "", 10, 15, searchbox_width, searchbox_height, NULL, 0, 0, 0, 0, NULL);
- but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 0, 150, 19, 0, 0, "");
+ but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 0, searchbox_width, UI_UNIT_Y - 1, 0, 0, "");
uiButSetSearchFunc(but, id_search_cb, &template, id_search_call_cb, idptr.data);
}
@@ -787,7 +789,7 @@ static int modifier_can_delete(ModifierData *md)
return 1;
}
-/* Check wheter Modifier is a simulation or not, this is used for switching to the physics/particles context tab */
+/* Check whether Modifier is a simulation or not, this is used for switching to the physics/particles context tab */
static int modifier_is_simulation(ModifierData *md)
{
/* Physic Tab */
diff --git a/source/blender/editors/mesh/editmesh_add.c b/source/blender/editors/mesh/editmesh_add.c
index 65d70e231a4..cd6063b12d0 100644
--- a/source/blender/editors/mesh/editmesh_add.c
+++ b/source/blender/editors/mesh/editmesh_add.c
@@ -86,7 +86,8 @@ static void make_prim_finish(bContext *C, Object *obedit, int *state, int enter_
* to push this up to edges & faces. */
EDBM_selectmode_flush_ex(em, SCE_SELECT_VERTEX);
- EDBM_update_generic(C, em, TRUE);
+ /* only recalc editmode tessface if we are staying in editmode */
+ EDBM_update_generic(C, em, enter_editmode);
/* userdef */
if (*state && !enter_editmode) {
@@ -109,7 +110,7 @@ static int add_primitive_plane_exec(bContext *C, wmOperator *op)
em = BMEdit_FromObject(obedit);
if (!EDBM_op_call_and_selectf(em, op, "verts.out",
- "create_grid x_segments=%i y_segments=%i size=%f mat=%m4", 1, 1, dia, mat))
+ "create_grid x_segments=%i y_segments=%i size=%f matrix=%m4", 1, 1, dia, mat))
{
return OPERATOR_CANCELLED;
}
@@ -149,7 +150,7 @@ static int add_primitive_cube_exec(bContext *C, wmOperator *op)
obedit = make_prim_init(C, "Cube", &dia, mat, &state, loc, rot, layer);
em = BMEdit_FromObject(obedit);
- if (!EDBM_op_call_and_selectf(em, op, "verts.out", "create_cube mat=%m4 size=%f", mat, dia * 2.0f)) {
+ if (!EDBM_op_call_and_selectf(em, op, "verts.out", "create_cube matrix=%m4 size=%f", mat, dia * 2.0f)) {
return OPERATOR_CANCELLED;
}
@@ -199,7 +200,7 @@ static int add_primitive_circle_exec(bContext *C, wmOperator *op)
em = BMEdit_FromObject(obedit);
if (!EDBM_op_call_and_selectf(em, op, "verts.out",
- "create_circle segments=%i diameter=%f cap_ends=%b cap_tris=%b mat=%m4",
+ "create_circle segments=%i diameter=%f cap_ends=%b cap_tris=%b matrix=%m4",
RNA_int_get(op->ptr, "vertices"), RNA_float_get(op->ptr, "radius") * dia,
cap_end, cap_tri, mat))
{
@@ -254,7 +255,7 @@ static int add_primitive_cylinder_exec(bContext *C, wmOperator *op)
if (!EDBM_op_call_and_selectf(
em, op, "verts.out",
- "create_cone segments=%i diameter1=%f diameter2=%f cap_ends=%b cap_tris=%b depth=%f mat=%m4",
+ "create_cone segments=%i diameter1=%f diameter2=%f cap_ends=%b cap_tris=%b depth=%f matrix=%m4",
RNA_int_get(op->ptr, "vertices"),
RNA_float_get(op->ptr, "radius") * dia,
RNA_float_get(op->ptr, "radius") * dia,
@@ -314,7 +315,7 @@ static int add_primitive_cone_exec(bContext *C, wmOperator *op)
if (!EDBM_op_call_and_selectf(
em, op, "verts.out",
- "create_cone segments=%i diameter1=%f diameter2=%f cap_ends=%b cap_tris=%b depth=%f mat=%m4",
+ "create_cone segments=%i diameter1=%f diameter2=%f cap_ends=%b cap_tris=%b depth=%f matrix=%m4",
RNA_int_get(op->ptr, "vertices"), RNA_float_get(op->ptr, "radius1") * dia,
RNA_float_get(op->ptr, "radius2") * dia, cap_end, cap_tri, RNA_float_get(op->ptr, "depth") * dia, mat))
{
@@ -369,7 +370,7 @@ static int add_primitive_grid_exec(bContext *C, wmOperator *op)
em = BMEdit_FromObject(obedit);
if (!EDBM_op_call_and_selectf(em, op, "verts.out",
- "create_grid x_segments=%i y_segments=%i size=%f mat=%m4",
+ "create_grid x_segments=%i y_segments=%i size=%f matrix=%m4",
RNA_int_get(op->ptr, "x_subdivisions"),
RNA_int_get(op->ptr, "y_subdivisions"),
RNA_float_get(op->ptr, "size") * dia, mat))
@@ -427,7 +428,7 @@ static int add_primitive_monkey_exec(bContext *C, wmOperator *op)
em = BMEdit_FromObject(obedit);
- if (!EDBM_op_call_and_selectf(em, op, "verts.out", "create_monkey mat=%m4", mat)) {
+ if (!EDBM_op_call_and_selectf(em, op, "verts.out", "create_monkey matrix=%m4", mat)) {
return OPERATOR_CANCELLED;
}
@@ -467,7 +468,7 @@ static int add_primitive_uvsphere_exec(bContext *C, wmOperator *op)
em = BMEdit_FromObject(obedit);
if (!EDBM_op_call_and_selectf(em, op, "verts.out",
- "create_uvsphere u_segments=%i v_segments=%i diameter=%f mat=%m4",
+ "create_uvsphere u_segments=%i v_segments=%i diameter=%f matrix=%m4",
RNA_int_get(op->ptr, "segments"), RNA_int_get(op->ptr, "ring_count"),
RNA_float_get(op->ptr, "size") * dia, mat))
{
@@ -519,7 +520,7 @@ static int add_primitive_icosphere_exec(bContext *C, wmOperator *op)
if (!EDBM_op_call_and_selectf(
em, op, "verts.out",
- "create_icosphere subdivisions=%i diameter=%f mat=%m4",
+ "create_icosphere subdivisions=%i diameter=%f matrix=%m4",
RNA_int_get(op->ptr, "subdivisions"),
RNA_float_get(op->ptr, "size") * dia, mat))
{
diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c
index aed16be5b73..9dc68848c69 100644
--- a/source/blender/editors/mesh/editmesh_knife.c
+++ b/source/blender/editors/mesh/editmesh_knife.c
@@ -1965,7 +1965,7 @@ static void knifenet_fill_faces(KnifeTool_OpData *kcd)
kfe->e = NULL;
}
- kfe->e = BM_edge_create(bm, kfe->v1->v, kfe->v2->v, NULL, TRUE);
+ kfe->e = BM_edge_create(bm, kfe->v1->v, kfe->v2->v, NULL, BM_CREATE_NO_DOUBLE);
BMO_elem_flag_enable(bm, kfe->e, BOUNDARY);
for (ref = kfe->faces.first; ref; ref = ref->next) {
@@ -2067,7 +2067,7 @@ static void knifenet_fill_faces(KnifeTool_OpData *kcd)
}
}
- BLI_scanfill_calc(&sf_ctx, FALSE);
+ BLI_scanfill_calc(&sf_ctx, 0);
for (sf_tri = sf_ctx.fillfacebase.first; sf_tri; sf_tri = sf_tri->next) {
BMVert *v1 = sf_tri->v3->tmp.p, *v2 = sf_tri->v2->tmp.p, *v3 = sf_tri->v1->tmp.p;
diff --git a/source/blender/editors/mesh/editmesh_loopcut.c b/source/blender/editors/mesh/editmesh_loopcut.c
index f951073155d..dec45b7f326 100644
--- a/source/blender/editors/mesh/editmesh_loopcut.c
+++ b/source/blender/editors/mesh/editmesh_loopcut.c
@@ -261,7 +261,11 @@ static void edgering_sel(RingSelOpData *lcd, int previewlines, int select)
lasteed = eed;
}
+#ifdef BMW_EDGERING_NGON
if (lasteed != startedge && BM_edge_share_face_check(lasteed, startedge)) {
+#else
+ if (lasteed != startedge && BM_edge_share_quad_check(lasteed, startedge)) {
+#endif
v[1][0] = v[0][0];
v[1][1] = v[0][1];
@@ -309,6 +313,11 @@ static void ringsel_finish(bContext *C, wmOperator *op)
RingSelOpData *lcd = op->customdata;
const int cuts = RNA_int_get(op->ptr, "number_cuts");
const float smoothness = 0.292f * RNA_float_get(op->ptr, "smoothness");
+#ifdef BMW_EDGERING_NGON
+ const int use_only_quads = FALSE;
+#else
+ const int use_only_quads = TRUE;
+#endif
if (lcd->eed) {
BMEditMesh *em = lcd->em;
@@ -322,7 +331,8 @@ static void ringsel_finish(bContext *C, wmOperator *op)
BM_mesh_esubdivide(em->bm, BM_ELEM_SELECT,
smoothness, 0.0f, 0.0f,
cuts,
- SUBDIV_SELECT_LOOPCUT, SUBD_PATH, 0, TRUE, 0);
+ SUBDIV_SELECT_LOOPCUT, SUBD_PATH, 0, TRUE,
+ use_only_quads, 0);
/* force edge slide to edge select mode in in face select mode */
if (em->selectmode & SCE_SELECT_FACE) {
@@ -552,9 +562,9 @@ static int loopcut_modal(bContext *C, wmOperator *op, wmEvent *event)
/* using the keyboard to input the number of cuts */
if (event->val == KM_PRESS) {
/* init as zero so backspace clears */
- float value = 0.0f;
if (handleNumInput(&lcd->num, event)) {
+ float value = RNA_int_get(op->ptr, "number_cuts");
applyNumInput(&lcd->num, &value);
/* allow zero so you can backspace and type in a value
diff --git a/source/blender/editors/mesh/editmesh_rip.c b/source/blender/editors/mesh/editmesh_rip.c
index d3a4c951e06..2ecc20b2ddb 100644
--- a/source/blender/editors/mesh/editmesh_rip.c
+++ b/source/blender/editors/mesh/editmesh_rip.c
@@ -60,7 +60,7 @@
*
* \param inset is used so we get some useful distance
* when comparing multiple edges that meet at the same
- * point and would result in teh same distance.
+ * point and would result in the same distance.
*/
#define INSET_DEFAULT 0.00001f
static float edbm_rip_edgedist(ARegion *ar, float mat[][4],
diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c
index 2f40d281505..cb1b4ebba72 100644
--- a/source/blender/editors/mesh/editmesh_select.c
+++ b/source/blender/editors/mesh/editmesh_select.c
@@ -734,7 +734,7 @@ static int similar_face_select_exec(bContext *C, wmOperator *op)
EDBM_flag_disable_all(em, BM_ELEM_SELECT);
/* select the output */
- BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "faces.out", BM_ALL, BM_ELEM_SELECT, TRUE);
+ BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "faces.out", BM_FACE, BM_ELEM_SELECT, TRUE);
/* finish the operator */
if (!EDBM_op_finish(em, &bmop, op, TRUE)) {
@@ -775,7 +775,7 @@ static int similar_edge_select_exec(bContext *C, wmOperator *op)
EDBM_flag_disable_all(em, BM_ELEM_SELECT);
/* select the output */
- BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "edges.out", BM_ALL, BM_ELEM_SELECT, TRUE);
+ BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "edges.out", BM_EDGE, BM_ELEM_SELECT, TRUE);
EDBM_selectmode_flush(em);
/* finish the operator */
@@ -819,7 +819,7 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op)
EDBM_flag_disable_all(em, BM_ELEM_SELECT);
/* select the output */
- BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "verts.out", BM_ALL, BM_ELEM_SELECT, TRUE);
+ BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "verts.out", BM_VERT, BM_ELEM_SELECT, TRUE);
/* finish the operator */
if (!EDBM_op_finish(em, &bmop, op, TRUE)) {
@@ -1269,12 +1269,12 @@ static float step_cost_3_v3(const float v1[3], const float v2[3], const float v3
/* The cost is based on the simple sum of the length of the two edgees... */
sub_v3_v3v3(d1, v2, v1);
sub_v3_v3v3(d2, v3, v2);
- cost = len_v3(d1) + len_v3(d2);
+ cost = normalize_v3(d1) + normalize_v3(d2);
/* but is biased to give higher values to sharp turns, so that it will take
* paths with fewer "turns" when selecting between equal-weighted paths between
* the two edges */
- cost = cost + 0.5f * cost * (2.0f - sqrtf(fabsf(dot_v3v3(d1, d2))));
+ cost = cost * (1.0f + 0.5f * (2.0f - sqrtf(fabsf(dot_v3v3(d1, d2)))));
return cost;
}
@@ -1881,7 +1881,7 @@ int EDBM_select_pick(bContext *C, const int mval[2], short extend, short deselec
vc.obedit->actcol = efa->mat_nr + 1;
vc.em->mat_nr = efa->mat_nr;
- WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING, NULL);
+ WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_LINKS, NULL);
}
diff --git a/source/blender/editors/mesh/editmesh_slide.c b/source/blender/editors/mesh/editmesh_slide.c
index c32033054e0..4fbe9c2534f 100644
--- a/source/blender/editors/mesh/editmesh_slide.c
+++ b/source/blender/editors/mesh/editmesh_slide.c
@@ -695,7 +695,7 @@ static int edbm_vertex_slide_exec_ex(bContext *C, wmOperator *op, const int do_u
BMOperator bmop;
BMEditSelection *ese = (BMEditSelection *)em->bm->selected.last;
- float distance_t = 0.0f;
+ float factor = 0.0f;
/* Invoked modally? */
if (op->type->modal == edbm_vertex_slide_modal && op->customdata) {
@@ -711,12 +711,12 @@ static int edbm_vertex_slide_exec_ex(bContext *C, wmOperator *op, const int do_u
BM_select_history_store(em->bm, vso->start_vtx);
ese = (BMEditSelection *)em->bm->selected.last;
}
- distance_t = vso->distance;
- RNA_float_set(op->ptr, "distance_t", distance_t);
+ factor = vso->distance;
+ RNA_float_set(op->ptr, "factor", factor);
}
else {
/* Get Properties */
- distance_t = RNA_float_get(op->ptr, "distance_t");
+ factor = RNA_float_get(op->ptr, "factor");
}
/* Is there a starting vertex ? */
@@ -729,8 +729,8 @@ static int edbm_vertex_slide_exec_ex(bContext *C, wmOperator *op, const int do_u
/* Prepare operator */
if (!EDBM_op_init(em, &bmop, op,
- "slide_vert vert=%e edge=%hev distance_t=%f",
- start_vert, BM_ELEM_SELECT, distance_t))
+ "slide_vert vert=%e edges=%he factor=%f",
+ start_vert, BM_ELEM_SELECT, factor))
{
return OPERATOR_CANCELLED;
}
@@ -738,10 +738,10 @@ static int edbm_vertex_slide_exec_ex(bContext *C, wmOperator *op, const int do_u
BMO_op_exec(bm, &bmop);
/* Deselect the input edges */
- BMO_slot_buffer_hflag_disable(bm, bmop.slots_in, "edge", BM_ALL, BM_ELEM_SELECT, TRUE);
+ BMO_slot_buffer_hflag_disable(bm, bmop.slots_in, "edges", BM_EDGE, BM_ELEM_SELECT, TRUE);
/* Select the output vert */
- BMO_slot_buffer_hflag_enable(bm, bmop.slots_out, "verts.out", BM_ALL, BM_ELEM_SELECT, TRUE);
+ BMO_slot_buffer_hflag_enable(bm, bmop.slots_out, "verts.out", BM_VERT, BM_ELEM_SELECT, TRUE);
/* Flush the select buffers */
EDBM_selectmode_flush(em);
@@ -787,7 +787,7 @@ void MESH_OT_vert_slide(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* Properties for vertex slide */
- prop = RNA_def_float(ot->srna, "distance_t", 0.0f, -FLT_MAX, FLT_MAX, "Distance", "Distance", -5.0f, 5.0f);
+ prop = RNA_def_float(ot->srna, "factor", 0.0f, -FLT_MAX, FLT_MAX, "Distance", "Distance", -5.0f, 5.0f);
RNA_def_property_ui_range(prop, -5.0f, 5.0f, 0.1, 4);
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index eb98efdfea3..3ff33b79f55 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -109,7 +109,7 @@ static int edbm_subdivide_exec(bContext *C, wmOperator *op)
smooth, fractal, along_normal,
cuts,
SUBDIV_SELECT_ORIG, RNA_enum_get(op->ptr, "quadcorner"),
- RNA_boolean_get(op->ptr, "quadtri"), TRUE,
+ RNA_boolean_get(op->ptr, "quadtri"), TRUE, FALSE,
RNA_int_get(op->ptr, "seed"));
EDBM_update_generic(C, em, TRUE);
@@ -354,21 +354,21 @@ static short edbm_extrude_edge(Object *obedit, BMEditMesh *em, const char hflag,
if ((fabsf(co1[0]) < mmd->tolerance) &&
(fabsf(co2[0]) < mmd->tolerance))
{
- BMO_slot_map_ptr_insert(&extop, slot_edges_exclude, edge, NULL);
+ BMO_slot_map_empty_insert(&extop, slot_edges_exclude, edge);
}
}
if (mmd->flag & MOD_MIR_AXIS_Y) {
if ((fabsf(co1[1]) < mmd->tolerance) &&
(fabsf(co2[1]) < mmd->tolerance))
{
- BMO_slot_map_ptr_insert(&extop, slot_edges_exclude, edge, NULL);
+ BMO_slot_map_empty_insert(&extop, slot_edges_exclude, edge);
}
}
if (mmd->flag & MOD_MIR_AXIS_Z) {
if ((fabsf(co1[2]) < mmd->tolerance) &&
(fabsf(co2[2]) < mmd->tolerance))
{
- BMO_slot_map_ptr_insert(&extop, slot_edges_exclude, edge, NULL);
+ BMO_slot_map_empty_insert(&extop, slot_edges_exclude, edge);
}
}
}
@@ -891,7 +891,7 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, wmEvent
}
if (rot_src) {
- EDBM_op_callf(vc.em, op, "rotate verts=%hv cent=%v mat=%m3",
+ EDBM_op_callf(vc.em, op, "rotate verts=%hv cent=%v matrix=%m3",
BM_ELEM_SELECT, cent, mat);
/* also project the source, for retopo workflow */
@@ -900,7 +900,7 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, wmEvent
}
edbm_extrude_edge(vc.obedit, vc.em, BM_ELEM_SELECT, nor);
- EDBM_op_callf(vc.em, op, "rotate verts=%hv cent=%v mat=%m3",
+ EDBM_op_callf(vc.em, op, "rotate verts=%hv cent=%v matrix=%m3",
BM_ELEM_SELECT, cent, mat);
EDBM_op_callf(vc.em, op, "translate verts=%hv vec=%v",
BM_ELEM_SELECT, min);
@@ -1343,7 +1343,7 @@ static int edbm_duplicate_exec(bContext *C, wmOperator *op)
BMO_op_exec(em->bm, &bmop);
EDBM_flag_disable_all(em, BM_ELEM_SELECT);
- BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "geom.out", BM_ALL, BM_ELEM_SELECT, TRUE);
+ BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "geom.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, TRUE);
if (!EDBM_op_finish(em, &bmop, op, TRUE)) {
return OPERATOR_CANCELLED;
@@ -2018,7 +2018,7 @@ static int merge_firstlast(BMEditMesh *em, int first, int uvmerge, wmOperator *w
return OPERATOR_CANCELLED;
if (uvmerge) {
- if (!EDBM_op_callf(em, wmop, "pointmerge_facedata verts=%hv snapv=%e", BM_ELEM_SELECT, mergevert))
+ if (!EDBM_op_callf(em, wmop, "pointmerge_facedata verts=%hv vert_snap=%e", BM_ELEM_SELECT, mergevert))
return OPERATOR_CANCELLED;
}
@@ -2308,7 +2308,9 @@ static int edbm_select_vertex_path_exec(bContext *C, wmOperator *op)
}
/* initialize the bmop using EDBM api, which does various ui error reporting and other stuff */
- EDBM_op_init(em, &bmop, op, "shortest_path startv=%e endv=%e type=%i", svert, evert, type);
+ EDBM_op_init(em, &bmop, op,
+ "shortest_path vert_start=%e vert_end=%e type=%i",
+ svert, evert, type);
/* execute the operator */
BMO_op_exec(em->bm, &bmop);
@@ -2317,7 +2319,7 @@ static int edbm_select_vertex_path_exec(bContext *C, wmOperator *op)
/* EDBM_flag_disable_all(em, BM_ELEM_SELECT); */
/* select the output */
- BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "verts.out", BM_ALL, BM_ELEM_SELECT, TRUE);
+ BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "verts.out", BM_VERT, BM_ELEM_SELECT, TRUE);
/* finish the operator */
if (!EDBM_op_finish(em, &bmop, op, TRUE)) {
@@ -2889,7 +2891,7 @@ static int edbm_knife_cut_exec(bContext *C, wmOperator *op)
float isect = 0.0f;
int len = 0, isected, i;
short numcuts = 1, mode = RNA_int_get(op->ptr, "type");
- BMOpSlot *slot_edgepercents;
+ BMOpSlot *slot_edge_percents;
/* allocd vars */
float (*screen_vert_coords)[2], (*sco)[2], (*mouse_path)[2];
@@ -2944,7 +2946,7 @@ static int edbm_knife_cut_exec(bContext *C, wmOperator *op)
}
/* store percentage of edge cut for KNIFE_EXACT here.*/
- slot_edgepercents = BMO_slot_get(bmop.slots_in, "edgepercents");
+ slot_edge_percents = BMO_slot_get(bmop.slots_in, "edge_percents");
for (be = BM_iter_new(&iter, bm, BM_EDGES_OF_MESH, NULL); be; be = BM_iter_step(&iter)) {
int is_cut = FALSE;
if (BM_elem_flag_test(be, BM_ELEM_SELECT)) {
@@ -2957,7 +2959,7 @@ static int edbm_knife_cut_exec(bContext *C, wmOperator *op)
if (isect != 0.0f) {
if (mode != KNIFE_MULTICUT && mode != KNIFE_MIDPOINT) {
- BMO_slot_map_float_insert(&bmop, slot_edgepercents, be, isect);
+ BMO_slot_map_float_insert(&bmop, slot_edge_percents, be, isect);
}
}
}
@@ -2978,8 +2980,8 @@ static int edbm_knife_cut_exec(bContext *C, wmOperator *op)
BMO_slot_int_set(bmop.slots_in, "cuts", numcuts);
BMO_slot_int_set(bmop.slots_in, "quad_corner_type", SUBD_STRAIGHT_CUT);
- BMO_slot_bool_set(bmop.slots_in, "use_singleedge", FALSE);
- BMO_slot_bool_set(bmop.slots_in, "use_gridfill", FALSE);
+ BMO_slot_bool_set(bmop.slots_in, "use_single_edge", FALSE);
+ BMO_slot_bool_set(bmop.slots_in, "use_grid_fill", FALSE);
BMO_slot_float_set(bmop.slots_in, "radius", 0);
@@ -3596,7 +3598,7 @@ static int edbm_split_exec(bContext *C, wmOperator *op)
EDBM_op_init(em, &bmop, op, "split geom=%hvef use_only_faces=%b", BM_ELEM_SELECT, FALSE);
BMO_op_exec(em->bm, &bmop);
BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_SELECT, FALSE);
- BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "geom.out", BM_ALL, BM_ELEM_SELECT, TRUE);
+ BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "geom.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, TRUE);
if (!EDBM_op_finish(em, &bmop, op, TRUE)) {
return OPERATOR_CANCELLED;
}
@@ -3634,14 +3636,14 @@ static int edbm_spin_exec(bContext *C, wmOperator *op)
float cent[3], axis[3], imat[3][3];
float d[3] = {0.0f, 0.0f, 0.0f};
int steps, dupli;
- float degr;
+ float angle;
RNA_float_get_array(op->ptr, "center", cent);
RNA_float_get_array(op->ptr, "axis", axis);
steps = RNA_int_get(op->ptr, "steps");
- degr = RNA_float_get(op->ptr, "degrees");
+ angle = RNA_float_get(op->ptr, "angle");
//if (ts->editbutflag & B_CLOCKWISE)
- degr = -degr;
+ angle = -angle;
dupli = RNA_boolean_get(op->ptr, "dupli");
/* undo object transformation */
@@ -3652,13 +3654,13 @@ static int edbm_spin_exec(bContext *C, wmOperator *op)
if (!EDBM_op_init(em, &spinop, op,
"spin geom=%hvef cent=%v axis=%v dvec=%v steps=%i angle=%f use_duplicate=%b",
- BM_ELEM_SELECT, cent, axis, d, steps, degr, dupli))
+ BM_ELEM_SELECT, cent, axis, d, steps, angle, dupli))
{
return OPERATOR_CANCELLED;
}
BMO_op_exec(bm, &spinop);
EDBM_flag_disable_all(em, BM_ELEM_SELECT);
- BMO_slot_buffer_hflag_enable(bm, spinop.slots_out, "geom_last.out", BM_ALL, BM_ELEM_SELECT, TRUE);
+ BMO_slot_buffer_hflag_enable(bm, spinop.slots_out, "geom_last.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, TRUE);
if (!EDBM_op_finish(em, &spinop, op, TRUE)) {
return OPERATOR_CANCELLED;
}
@@ -3683,6 +3685,8 @@ static int edbm_spin_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
void MESH_OT_spin(wmOperatorType *ot)
{
+ PropertyRNA *prop;
+
/* identifiers */
ot->name = "Spin";
ot->description = "Extrude selected vertices in a circle around the cursor in indicated viewport";
@@ -3699,7 +3703,8 @@ void MESH_OT_spin(wmOperatorType *ot)
/* props */
RNA_def_int(ot->srna, "steps", 9, 0, INT_MAX, "Steps", "Steps", 0, INT_MAX);
RNA_def_boolean(ot->srna, "dupli", 0, "Dupli", "Make Duplicates");
- RNA_def_float(ot->srna, "degrees", 90.0f, -FLT_MAX, FLT_MAX, "Degrees", "Degrees", -360.0f, 360.0f);
+ prop = RNA_def_float(ot->srna, "angle", DEG2RADF(90.0f), -FLT_MAX, FLT_MAX, "Angle", "Angle", DEG2RADF(-360.0f), DEG2RADF(360.0f));
+ RNA_def_property_subtype(prop, PROP_ANGLE);
RNA_def_float_vector(ot->srna, "center", 3, NULL, -FLT_MAX, FLT_MAX, "Center", "Center in global view space", -FLT_MAX, FLT_MAX);
RNA_def_float_vector(ot->srna, "axis", 3, NULL, -FLT_MAX, FLT_MAX, "Axis", "Axis in global view space", -1.0f, 1.0f);
@@ -3737,15 +3742,11 @@ static int edbm_screw_exec(bContext *C, wmOperator *op)
v1 = NULL;
v2 = NULL;
for (eve = BM_iter_new(&iter, em->bm, BM_VERTS_OF_MESH, NULL); eve; eve = BM_iter_step(&iter)) {
-
valence = 0;
-
for (eed = BM_iter_new(&eiter, em->bm, BM_EDGES_OF_VERT, eve); eed; eed = BM_iter_step(&eiter)) {
-
if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) {
valence++;
}
-
}
if (valence == 1) {
@@ -3782,7 +3783,7 @@ static int edbm_screw_exec(bContext *C, wmOperator *op)
}
BMO_op_exec(bm, &spinop);
EDBM_flag_disable_all(em, BM_ELEM_SELECT);
- BMO_slot_buffer_hflag_enable(bm, spinop.slots_out, "geom_last.out", BM_ALL, BM_ELEM_SELECT, TRUE);
+ BMO_slot_buffer_hflag_enable(bm, spinop.slots_out, "geom_last.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, TRUE);
if (!EDBM_op_finish(em, &spinop, op, TRUE)) {
return OPERATOR_CANCELLED;
}
@@ -4947,8 +4948,13 @@ static float edbm_bevel_mval_factor(wmOperator *op, wmEvent *event)
/* Fake shift-transform... */
if (event->shift) {
- if (opdata->shift_factor < 0.0f)
+ if (opdata->shift_factor < 0.0f) {
+#ifdef NEW_BEVEL
+ opdata->shift_factor = RNA_float_get(op->ptr, "factor");
+#else
opdata->shift_factor = RNA_float_get(op->ptr, "percent");
+#endif
+ }
factor = (factor - opdata->shift_factor) * 0.1f + opdata->shift_factor;
}
else if (opdata->shift_factor >= 0.0f)
@@ -4973,9 +4979,9 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, wmEvent *event)
if (event->val == KM_PRESS) {
/* Try to handle numeric inputs... */
#ifdef NEW_BEVEL
- float value;
if (handleNumInput(&opdata->num_input, event)) {
+ float value = RNA_float_get(op->ptr, "offset");
applyNumInput(&opdata->num_input, &value);
RNA_float_set(op->ptr, "offset", value);
edbm_bevel_calc(C, op);
@@ -4983,9 +4989,8 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
#else
- float factor;
-
if (handleNumInput(&opdata->num_input, event)) {
+ float factor = RNA_float_get(op->ptr, "percent");
applyNumInput(&opdata->num_input, &factor);
CLAMP(factor, 0.0f, 1.0f);
RNA_float_set(op->ptr, "percent", factor);
@@ -5026,6 +5031,7 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, wmEvent *event)
#ifdef NEW_BEVEL
case WHEELUPMOUSE: /* change number of segments */
+ case PAGEUPKEY:
if (event->val == KM_RELEASE)
break;
@@ -5036,6 +5042,7 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, wmEvent *event)
break;
case WHEELDOWNMOUSE: /* change number of segments */
+ case PAGEDOWNKEY:
if (event->val == KM_RELEASE)
break;
@@ -5365,9 +5372,10 @@ static int edbm_inset_modal(bContext *C, wmOperator *op, wmEvent *event)
if (event->val == KM_PRESS) {
/* Try to handle numeric inputs... */
- float amounts[2];
if (handleNumInput(&opdata->num_input, event)) {
+ float amounts[2] = {RNA_float_get(op->ptr, "thickness"),
+ RNA_float_get(op->ptr, "depth")};
applyNumInput(&opdata->num_input, amounts);
amounts[0] = max_ff(amounts[0], 0.0f);
RNA_float_set(op->ptr, "thickness", amounts[0]);
diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c
index 22c71d5d3ca..2cf63586142 100644
--- a/source/blender/editors/mesh/editmesh_utils.c
+++ b/source/blender/editors/mesh/editmesh_utils.c
@@ -265,9 +265,11 @@ int EDBM_op_callf(BMEditMesh *em, wmOperator *op, const char *fmt, ...)
int EDBM_op_call_and_selectf(BMEditMesh *em, wmOperator *op, const char *select_slot_out, const char *fmt, ...)
{
+ BMOpSlot *slot_select_out;
BMesh *bm = em->bm;
BMOperator bmop;
va_list list;
+ char hflag;
va_start(list, fmt);
@@ -283,9 +285,12 @@ int EDBM_op_call_and_selectf(BMEditMesh *em, wmOperator *op, const char *select_
BMO_op_exec(bm, &bmop);
+ slot_select_out = BMO_slot_get(bmop.slots_out, select_slot_out);
+ hflag = slot_select_out->slot_subtype.elem & BM_ALL_NOLOOP;
+
BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_SELECT, FALSE);
- BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, select_slot_out, BM_ALL, BM_ELEM_SELECT, TRUE);
+ BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, select_slot_out, hflag, BM_ELEM_SELECT, TRUE);
va_end(list);
return EDBM_op_finish(em, &bmop, op, TRUE);
@@ -498,7 +503,7 @@ void EDBM_select_more(BMEditMesh *em)
BM_ELEM_SELECT, FALSE, use_faces);
BMO_op_exec(em->bm, &bmop);
/* don't flush selection in edge/vertex mode */
- BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "geom.out", BM_ALL, BM_ELEM_SELECT, use_faces ? TRUE : FALSE);
+ BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "geom.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, use_faces ? TRUE : FALSE);
BMO_op_finish(em->bm, &bmop);
EDBM_select_flush(em);
@@ -514,7 +519,7 @@ void EDBM_select_less(BMEditMesh *em)
BM_ELEM_SELECT, TRUE, use_faces);
BMO_op_exec(em->bm, &bmop);
/* don't flush selection in edge/vertex mode */
- BMO_slot_buffer_hflag_disable(em->bm, bmop.slots_out, "geom.out", BM_ALL, BM_ELEM_SELECT, use_faces ? TRUE : FALSE);
+ BMO_slot_buffer_hflag_disable(em->bm, bmop.slots_out, "geom.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, use_faces ? TRUE : FALSE);
BMO_op_finish(em->bm, &bmop);
EDBM_selectmode_flush(em);
diff --git a/source/blender/editors/mesh/mesh_navmesh.c b/source/blender/editors/mesh/mesh_navmesh.c
index f6f8eee0a69..83a1261e981 100644
--- a/source/blender/editors/mesh/mesh_navmesh.c
+++ b/source/blender/editors/mesh/mesh_navmesh.c
@@ -341,7 +341,7 @@ static Object *createRepresentation(bContext *C, struct recast_polyMesh *pmesh,
co[1] = bmin[1] + v[1] * ch;
co[2] = bmin[2] + v[2] * cs;
SWAP(float, co[1], co[2]);
- BM_vert_create(em->bm, co, NULL);
+ BM_vert_create(em->bm, co, NULL, 0);
}
/* create custom data layer to save polygon idx */
@@ -372,7 +372,7 @@ static Object *createRepresentation(bContext *C, struct recast_polyMesh *pmesh,
for (j = nv; j < ndv; j++) {
copy_v3_v3(co, &dverts[3 * (vbase + j)]);
SWAP(float, co[1], co[2]);
- BM_vert_create(em->bm, co, NULL);
+ BM_vert_create(em->bm, co, NULL, 0);
}
EDBM_index_arrays_init(em, 1, 0, 0);
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index 4d1f2bbc4e9..ad1e2816c10 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -271,7 +271,7 @@ int ED_object_add_generic_get_opts(bContext *C, wmOperator *op, float loc[3], fl
if (RNA_struct_property_is_set(op->ptr, "enter_editmode") && enter_editmode)
*enter_editmode = RNA_boolean_get(op->ptr, "enter_editmode");
else {
- *enter_editmode = U.flag & USER_ADD_EDITMODE;
+ *enter_editmode = (U.flag & USER_ADD_EDITMODE) != 0;
RNA_boolean_set(op->ptr, "enter_editmode", *enter_editmode);
}
}
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
index e7f09b4055a..f886b52e2ce 100644
--- a/source/blender/editors/object/object_relations.c
+++ b/source/blender/editors/object/object_relations.c
@@ -1225,7 +1225,7 @@ static unsigned int move_to_layer_init(bContext *C, wmOperator *op)
return lay;
}
-static int move_to_layer_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int move_to_layer_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
View3D *v3d = CTX_wm_view3d(C);
if (v3d && v3d->localvd) {
@@ -1233,7 +1233,7 @@ static int move_to_layer_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(eve
}
else {
move_to_layer_init(C, op);
- return WM_operator_props_dialog_popup(C, op, 260, 30);
+ return WM_operator_props_popup(C, op, event);
}
}
@@ -2148,7 +2148,7 @@ static int drop_named_material_invoke(bContext *C, wmOperator *op, wmEvent *even
DAG_ids_flush_update(bmain, 0);
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, CTX_wm_view3d(C));
- WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING, ma);
+ WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_LINKS, ma);
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c
index d7c7d4c04ef..1b135c0686e 100644
--- a/source/blender/editors/object/object_vgroup.c
+++ b/source/blender/editors/object/object_vgroup.c
@@ -400,22 +400,22 @@ typedef enum WT_ReplaceMode {
} WT_ReplaceMode;
static EnumPropertyItem WT_vertex_group_mode_item[] = {
- {WT_REPLACE_ACTIVE_VERTEX_GROUP, "WT_REPLACE_ACTIVE_VERTEX_GROUP", 1, "Active", "Transfer active vertex group from selected to active mesh"},
- {WT_REPLACE_ALL_VERTEX_GROUPS, "WT_REPLACE_ALL_VERTEX_GROUPS", 1, "All", "Transfer all vertex groups from selected to active mesh"},
+ {WT_REPLACE_ACTIVE_VERTEX_GROUP, "WT_REPLACE_ACTIVE_VERTEX_GROUP", 0, "Active", "Transfer active vertex group from selected to active mesh"},
+ {WT_REPLACE_ALL_VERTEX_GROUPS, "WT_REPLACE_ALL_VERTEX_GROUPS", 0, "All", "Transfer all vertex groups from selected to active mesh"},
{0, NULL, 0, NULL, NULL}
};
static EnumPropertyItem WT_method_item[] = {
- {WT_BY_INDEX, "WT_BY_INDEX", 1, "Vertex index", "Copy for identical meshes"},
- {WT_BY_NEAREST_VERTEX, "WT_BY_NEAREST_VERTEX", 1, "Nearest vertex", "Copy weight from closest vertex"},
- {WT_BY_NEAREST_FACE, "WT_BY_NEAREST_FACE", 1, "Nearest face", "Barycentric interpolation from nearest face"},
- {WT_BY_NEAREST_VERTEX_IN_FACE, "WT_BY_NEAREST_VERTEX_IN_FACE", 1, "Nearest vertex in face", "Copy weight from closest vertex in nearest face"},
+ {WT_BY_INDEX, "WT_BY_INDEX", 0, "Vertex index", "Copy for identical meshes"},
+ {WT_BY_NEAREST_VERTEX, "WT_BY_NEAREST_VERTEX", 0, "Nearest vertex", "Copy weight from closest vertex"},
+ {WT_BY_NEAREST_FACE, "WT_BY_NEAREST_FACE", 0, "Nearest face", "Barycentric interpolation from nearest face"},
+ {WT_BY_NEAREST_VERTEX_IN_FACE, "WT_BY_NEAREST_VERTEX_IN_FACE", 0, "Nearest vertex in face", "Copy weight from closest vertex in nearest face"},
{0, NULL, 0, NULL, NULL}
};
static EnumPropertyItem WT_replace_mode_item[] = {
- {WT_REPLACE_ALL_WEIGHTS, "WT_REPLACE_ALL_WEIGHTS", 1, "All", "Overwrite all weights"},
- {WT_REPLACE_EMPTY_WEIGHTS, "WT_REPLACE_EMPTY_WEIGHTS", 1, "Empty", "Add weights to vertices with no weight"},
+ {WT_REPLACE_ALL_WEIGHTS, "WT_REPLACE_ALL_WEIGHTS", 0, "All", "Overwrite all weights"},
+ {WT_REPLACE_EMPTY_WEIGHTS, "WT_REPLACE_EMPTY_WEIGHTS", 0, "Empty", "Add weights to vertices with no weight"},
{0, NULL, 0, NULL, NULL}
};
diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c
index 2ac5f98927c..f5754297e9f 100644
--- a/source/blender/editors/physics/particle_edit.c
+++ b/source/blender/editors/physics/particle_edit.c
@@ -431,7 +431,7 @@ static int key_test_depth(PEData *data, const float co[3], const int screen_co[2
#else /* faster to use depths, these are calculated in PE_set_view3d_data */
/* check if screen_co is within bounds because brush_cut uses out of screen coords */
- if(screen_co[0] >= 0 && screen_co[0] < vd->w && screen_co[1] >= 0 && screen_co[1] < vd->h) {
+ if (screen_co[0] >= 0 && screen_co[0] < vd->w && screen_co[1] >= 0 && screen_co[1] < vd->h) {
BLI_assert(vd && vd->depths);
/* we know its not clipped */
depth = vd->depths[screen_co[1] * vd->w + screen_co[0]];
diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c
index 7b67f63c646..9a49a1970a0 100644
--- a/source/blender/editors/render/render_internal.c
+++ b/source/blender/editors/render/render_internal.c
@@ -553,13 +553,20 @@ static int screen_render_invoke(bContext *C, wmOperator *op, wmEvent *event)
rj->win = CTX_wm_window(C);
rj->srl = srl;
rj->camera_override = camera_override;
- rj->lay = (v3d) ? v3d->lay : scene->lay;
+ rj->lay = scene->lay;
rj->anim = is_animation;
rj->write_still = is_write_still && !is_animation;
rj->iuser.scene = scene;
rj->iuser.ok = 1;
rj->reports = op->reports;
+ if(v3d) {
+ rj->lay = v3d->lay;
+
+ if(v3d->localvd)
+ rj->lay |= v3d->localvd->lay;
+ }
+
/* setup job */
if (RE_seq_render_active(scene, &scene->r)) name = "Sequence Render";
else name = "Render";
@@ -611,6 +618,8 @@ static int screen_render_invoke(bContext *C, wmOperator *op, wmEvent *event)
/* contextual render, using current scene, view3d? */
void RENDER_OT_render(wmOperatorType *ot)
{
+ PropertyRNA *prop;
+
/* identifiers */
ot->name = "Render";
ot->description = "Render active scene";
@@ -625,7 +634,9 @@ void RENDER_OT_render(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "animation", 0, "Animation", "Render files from the animation range of this scene");
RNA_def_boolean(ot->srna, "write_still", 0, "Write Image", "Save rendered the image to the output path (used only when animation is disabled)");
- RNA_def_string(ot->srna, "layer", "", RE_MAXNAME, "Render Layer", "Single render layer to re-render (used only when animation is disabled)");
- RNA_def_string(ot->srna, "scene", "", MAX_ID_NAME - 2, "Scene", "Scene to render, current scene if not specified");
+ prop = RNA_def_string(ot->srna, "layer", "", RE_MAXNAME, "Render Layer", "Single render layer to re-render (used only when animation is disabled)");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ prop = RNA_def_string(ot->srna, "scene", "", MAX_ID_NAME - 2, "Scene", "Scene to render, current scene if not specified");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c
index ebbdc90ab04..34677650f80 100644
--- a/source/blender/editors/render/render_shading.c
+++ b/source/blender/editors/render/render_shading.c
@@ -1480,7 +1480,7 @@ static int paste_material_exec(bContext *C, wmOperator *UNUSED(op))
paste_matcopybuf(ma);
- WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_DRAW, ma);
+ WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_LINKS, ma);
return OPERATOR_FINISHED;
}
@@ -1642,7 +1642,7 @@ static int paste_mtex_exec(bContext *C, wmOperator *UNUSED(op))
paste_mtex_copybuf(id);
- WM_event_add_notifier(C, NC_TEXTURE | ND_SHADING_DRAW, NULL);
+ WM_event_add_notifier(C, NC_TEXTURE | ND_SHADING_LINKS, NULL);
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c
index 3f438c5948e..e9fbb3a0885 100644
--- a/source/blender/editors/render/render_update.c
+++ b/source/blender/editors/render/render_update.c
@@ -65,6 +65,8 @@
#include "render_intern.h" // own include
+extern Material defmaterial;
+
/***************************** Render Engines ********************************/
void ED_render_scene_update(Main *bmain, Scene *scene, int updated)
@@ -266,6 +268,9 @@ static void lamp_changed(Main *bmain, Lamp *la)
for (ma = bmain->mat.first; ma; ma = ma->id.next)
if (ma->gpumaterial.first)
GPU_material_free(ma);
+
+ if (defmaterial.gpumaterial.first)
+ GPU_material_free(&defmaterial);
}
static void texture_changed(Main *bmain, Tex *tex)
@@ -347,6 +352,9 @@ static void world_changed(Main *bmain, World *wo)
for (ma = bmain->mat.first; ma; ma = ma->id.next)
if (ma->gpumaterial.first)
GPU_material_free(ma);
+
+ if (defmaterial.gpumaterial.first)
+ GPU_material_free(&defmaterial);
}
static void image_changed(Main *bmain, Image *ima)
@@ -375,6 +383,9 @@ static void scene_changed(Main *bmain, Scene *UNUSED(scene))
for (ma = bmain->mat.first; ma; ma = ma->id.next)
if (ma->gpumaterial.first)
GPU_material_free(ma);
+
+ if (defmaterial.gpumaterial.first)
+ GPU_material_free(&defmaterial);
}
void ED_render_id_flush_update(Main *bmain, ID *id)
diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c
index 676f033af32..a929c3ef585 100644
--- a/source/blender/editors/sculpt_paint/paint_image.c
+++ b/source/blender/editors/sculpt_paint/paint_image.c
@@ -656,7 +656,7 @@ static float VecZDepthPersp(const float pt[2],
* barycentric_weights_v2 would return, in this case its easiest just to
* undo the 4th axis division and make it unit-sum
*
- * don't call barycentric_weights_v2() becaue our callers expect 'w'
+ * don't call barycentric_weights_v2() because our callers expect 'w'
* to be weighted from the perspective */
w_tmp[0] = w[0] * v1[3];
w_tmp[1] = w[1] * v2[3];
diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c
index c5eff1a1f0e..cb4b6346c2a 100644
--- a/source/blender/editors/sculpt_paint/paint_utils.c
+++ b/source/blender/editors/sculpt_paint/paint_utils.c
@@ -257,8 +257,8 @@ void imapaint_pick_uv(Scene *scene, Object *ob, unsigned int faceindex, const in
/* double lookup */
const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX);
- if ((index_mf_to_mpoly && index_mp_to_orig) == FALSE) {
- index_mf_to_mpoly = index_mp_to_orig = NULL;
+ if (index_mf_to_mpoly == NULL) {
+ index_mp_to_orig = NULL;
}
minabsw = 1e10;
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 38dbdcd8337..25ea08a4bb1 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -3356,7 +3356,10 @@ static void sculpt_update_cache_invariants(bContext *C, Sculpt *sd, SculptSessio
sculpt_init_mirror_clipping(ob, ss);
/* Initial mouse location */
- copy_v2_v2(ss->cache->initial_mouse, mouse);
+ if (mouse)
+ copy_v2_v2(ss->cache->initial_mouse, mouse);
+ else
+ zero_v2(ss->cache->initial_mouse);
mode = RNA_enum_get(op->ptr, "mode");
cache->invert = mode == BRUSH_STROKE_INVERT;
@@ -3890,8 +3893,8 @@ static int sculpt_stroke_test_start(bContext *C, struct wmOperator *op,
const float mouse[2])
{
/* Don't start the stroke until mouse goes over the mesh.
- * note: event will only be null when re-executing the saved stroke. */
- if (over_mesh(C, op, mouse[0], mouse[1])) {
+ * note: mouse will only be null when re-executing the saved stroke. */
+ if (!mouse || over_mesh(C, op, mouse[0], mouse[1])) {
Object *ob = CTX_data_active_object(C);
SculptSession *ss = ob->sculpt;
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c
index 7d2374738ef..95a5bbdf5c8 100644
--- a/source/blender/editors/space_buttons/space_buttons.c
+++ b/source/blender/editors/space_buttons/space_buttons.c
@@ -300,6 +300,7 @@ static void buttons_area_listener(ScrArea *sa, wmNotifier *wmn)
buttons_area_redraw(sa, BCONTEXT_PHYSICS);
case ND_SHADING:
case ND_SHADING_DRAW:
+ case ND_SHADING_LINKS:
/* currently works by redraws... if preview is set, it (re)starts job */
sbuts->preview = 1;
break;
@@ -322,6 +323,7 @@ static void buttons_area_listener(ScrArea *sa, wmNotifier *wmn)
switch (wmn->data) {
case ND_SHADING:
case ND_SHADING_DRAW:
+ case ND_SHADING_LINKS:
case ND_NODES:
/* currently works by redraws... if preview is set, it (re)starts job */
sbuts->preview = 1;
diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c
index d97b112e95d..a29524de36d 100644
--- a/source/blender/editors/space_clip/tracking_ops.c
+++ b/source/blender/editors/space_clip/tracking_ops.c
@@ -1409,7 +1409,7 @@ static void solve_camera_freejob(void *scv)
id_us_plus(&clip->id);
/* set blender camera focal length so result would look fine there */
- if (scene->camera && GS(scene->camera->id.name) == ID_CA) {
+ if (scene->camera && scene->camera->data && GS(((ID *) scene->camera->data)->name) == ID_CA) {
Camera *camera = (Camera *)scene->camera->data;
int width, height;
diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c
index 62e941d3148..f757345bdcb 100644
--- a/source/blender/editors/space_node/node_edit.c
+++ b/source/blender/editors/space_node/node_edit.c
@@ -86,6 +86,7 @@ typedef struct CompoJob {
short *stop;
short *do_update;
float *progress;
+ short need_sync;
} CompoJob;
/* called by compo, only to check job 'stop' value */
@@ -102,8 +103,17 @@ static int compo_breakjob(void *cjv)
);
}
+/* called by compo, wmJob sends notifier, old compositor system only */
+static void compo_statsdrawjob(void *cjv, char *UNUSED(str))
+{
+ CompoJob *cj = cjv;
+
+ *(cj->do_update) = TRUE;
+ cj->need_sync = TRUE;
+}
+
/* called by compo, wmJob sends notifier */
-static void compo_redrawjob(void *cjv, char *UNUSED(str))
+static void compo_redrawjob(void *cjv)
{
CompoJob *cj = cjv;
@@ -133,8 +143,15 @@ static void compo_initjob(void *cjv)
static void compo_updatejob(void *cjv)
{
CompoJob *cj = cjv;
-
- ntreeLocalSync(cj->localtree, cj->ntree);
+
+ if (cj->need_sync) {
+ /* was used by old compositor system only */
+ ntreeLocalSync(cj->localtree, cj->ntree);
+
+ cj->need_sync = FALSE;
+ }
+
+ WM_main_add_notifier(NC_WINDOW | ND_DRAW, NULL);
}
static void compo_progressjob(void *cjv, float progress)
@@ -161,11 +178,13 @@ static void compo_startjob(void *cjv, short *stop, short *do_update, float *prog
ntree->test_break = compo_breakjob;
ntree->tbh = cj;
- ntree->stats_draw = compo_redrawjob;
+ ntree->stats_draw = compo_statsdrawjob;
ntree->sdh = cj;
ntree->progress = compo_progressjob;
ntree->prh = cj;
-
+ ntree->update_draw = compo_redrawjob;
+ ntree->udh = cj;
+
// XXX BIF_store_spare();
ntreeCompositExecTree(ntree, &cj->scene->r, 0, 1, &scene->view_settings, &scene->display_settings); /* 1 is do_previews */
@@ -177,7 +196,7 @@ static void compo_startjob(void *cjv, short *stop, short *do_update, float *prog
}
/**
- * \param sa_owner is the owner of the job,
+ * \param scene_owner is the owner of the job,
* we don't use it for anything else currently so could also be a void pointer,
* but for now keep it an 'Scene' for consistency.
*
diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c
index 4d2512cdc93..f7e0d51ea03 100644
--- a/source/blender/editors/space_node/space_node.c
+++ b/source/blender/editors/space_node/space_node.c
@@ -193,6 +193,8 @@ static void node_area_listener(ScrArea *sa, wmNotifier *wmn)
ED_area_tag_refresh(sa);
else if (wmn->data == ND_SHADING_DRAW)
ED_area_tag_refresh(sa);
+ else if (wmn->data == ND_SHADING_LINKS)
+ ED_area_tag_refresh(sa);
else if (wmn->action == NA_ADDED && snode->edittree)
nodeSetActiveID(snode->edittree, ID_MA, wmn->reference);
diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c
index 61d513929ad..d37cb4be8fa 100644
--- a/source/blender/editors/space_outliner/outliner_draw.c
+++ b/source/blender/editors/space_outliner/outliner_draw.c
@@ -631,7 +631,7 @@ static uiBlock *operator_search_menu(bContext *C, ARegion *ar, void *arg_kmi)
uiBlockSetFlag(block, UI_BLOCK_LOOP | UI_BLOCK_REDRAW | UI_BLOCK_SEARCH_MENU);
/* fake button, it holds space for search items */
- uiDefBut(block, LABEL, 0, "", 10, 15, 150, uiSearchBoxhHeight(), NULL, 0, 0, 0, 0, NULL);
+ uiDefBut(block, LABEL, 0, "", 10, 15, uiSearchBoxWidth(), uiSearchBoxHeight(), NULL, 0, 0, 0, 0, NULL);
but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 0, 150, UI_UNIT_Y, 0, 0, "");
uiButSetSearchFunc(but, operator_search_cb, arg_kmi, operator_call_cb, ot);
diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c
index 23766d6a6fe..d11a8ed6369 100644
--- a/source/blender/editors/space_outliner/outliner_edit.c
+++ b/source/blender/editors/space_outliner/outliner_edit.c
@@ -836,6 +836,8 @@ static int outliner_one_level_exec(bContext *C, wmOperator *op)
void OUTLINER_OT_show_one_level(wmOperatorType *ot)
{
+ PropertyRNA *prop;
+
/* identifiers */
ot->name = "Show/Hide One Level";
ot->idname = "OUTLINER_OT_show_one_level";
@@ -848,7 +850,8 @@ void OUTLINER_OT_show_one_level(wmOperatorType *ot)
/* no undo or registry, UI option */
/* properties */
- RNA_def_boolean(ot->srna, "open", 1, "Open", "Expand all entries one level deep");
+ prop = RNA_def_boolean(ot->srna, "open", 1, "Open", "Expand all entries one level deep");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
/* Show Hierarchy ----------------------------------------------- */
@@ -1859,7 +1862,7 @@ static int material_drop_invoke(bContext *C, wmOperator *op, wmEvent *event)
DAG_ids_flush_update(bmain, 0);
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, CTX_wm_view3d(C));
- WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING, ma);
+ WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_LINKS, ma);
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c
index 4668dfa1386..0b585e1272b 100644
--- a/source/blender/editors/space_outliner/outliner_select.c
+++ b/source/blender/editors/space_outliner/outliner_select.c
@@ -222,7 +222,7 @@ static int tree_element_active_material(bContext *C, Scene *scene, SpaceOops *so
}
}
if (set) {
- WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING, NULL);
+ WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_LINKS, NULL);
}
return 0;
}
diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c
index af890a81ad6..e6910280da4 100644
--- a/source/blender/editors/space_outliner/outliner_tree.c
+++ b/source/blender/editors/space_outliner/outliner_tree.c
@@ -133,7 +133,7 @@ static void outliner_storage_cleanup(SpaceOops *soops)
}
/* XXX - THIS FUNCTION IS INCREDIBLY SLOW
- * ... it can bring blenders tools and viewport to a grinding halt becuase of searching
+ * ... it can bring blenders tools and viewport to a grinding halt because of searching
* for duplicate items every times they are added.
*
* TODO (possible speedups)
diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c
index f8856cb9646..ecc09a35670 100644
--- a/source/blender/editors/space_outliner/space_outliner.c
+++ b/source/blender/editors/space_outliner/space_outliner.c
@@ -326,15 +326,11 @@ static void outliner_main_area_listener(ARegion *ar, wmNotifier *wmn)
break;
case NC_MATERIAL:
switch (wmn->data) {
- case ND_SHADING:
- case ND_SHADING_DRAW:
+ case ND_SHADING_LINKS:
ED_region_tag_redraw(ar);
break;
}
break;
- case NC_TEXTURE:
- ED_region_tag_redraw(ar);
- break;
case NC_GEOM:
switch (wmn->data) {
case ND_VERTEX_GROUP:
diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c
index 5fefafaa54a..1a84efa0b50 100644
--- a/source/blender/editors/space_sequencer/sequencer_draw.c
+++ b/source/blender/editors/space_sequencer/sequencer_draw.c
@@ -926,7 +926,7 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
/* stop all running jobs, except screen one. currently previews frustrate Render
* needed to make so sequencer's rendering doesn't conflict with compositor
*/
- WM_jobs_kill_all_except(CTX_wm_manager(C), CTX_wm_screen(C));
+ WM_jobs_kill_type(CTX_wm_manager(C), WM_JOB_TYPE_COMPOSITE);
}
render_size = sseq->render_size;
diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c
index 00d4a943626..4e2bf982ff3 100644
--- a/source/blender/editors/space_sequencer/sequencer_edit.c
+++ b/source/blender/editors/space_sequencer/sequencer_edit.c
@@ -1850,6 +1850,7 @@ void SEQUENCER_OT_images_separate(wmOperatorType *ot)
/* api callbacks */
ot->exec = sequencer_separate_images_exec;
+ ot->invoke = WM_operator_props_popup;
ot->poll = sequencer_edit_poll;
/* flags */
diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c
index f35a844afc9..0ecde350b00 100644
--- a/source/blender/editors/space_view3d/drawmesh.c
+++ b/source/blender/editors/space_view3d/drawmesh.c
@@ -51,6 +51,7 @@
#include "BKE_DerivedMesh.h"
#include "BKE_effect.h"
+#include "BKE_global.h"
#include "BKE_image.h"
#include "BKE_material.h"
#include "BKE_paint.h"
@@ -965,7 +966,7 @@ void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d,
Mesh *me = ob->data;
TexMatCallback data = {scene, ob, me, dm};
int (*set_face_cb)(void *, int);
- int glsl;
+ int glsl, picking = (G.f & G_PICKSEL);
/* face hiding callback depending on mode */
if (ob == scene->obedit)
@@ -976,11 +977,11 @@ void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d,
set_face_cb = NULL;
/* test if we can use glsl */
- glsl = (v3d->drawtype == OB_MATERIAL) && GPU_glsl_support();
+ glsl = (v3d->drawtype == OB_MATERIAL) && GPU_glsl_support() && !picking;
GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl, NULL);
- if (glsl) {
+ if (glsl || picking) {
/* draw glsl */
dm->drawMappedFacesMat(dm,
tex_mat_set_material_cb,
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index 726fd26b11d..1c31cd23e33 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -724,6 +724,7 @@ static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn)
case NC_MATERIAL:
switch (wmn->data) {
case ND_SHADING_DRAW:
+ case ND_SHADING_LINKS:
ED_region_tag_redraw(ar);
break;
}
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index fcd92cd5639..6c23635da90 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -1940,7 +1940,7 @@ static void draw_dupli_objects_color(Scene *scene, ARegion *ar, View3D *v3d, Bas
* is intended to speed up drawing, and drawing extra (especially wire) can
* slow it down too much */
dtx = tbase.object->dtx;
- if(tbase.object->dt != OB_BOUNDBOX)
+ if (tbase.object->dt != OB_BOUNDBOX)
tbase.object->dtx = base->object->dtx;
/* negative scale flag has to propagate */
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index 0d8567b256d..d45013c40d9 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -2224,10 +2224,24 @@ static void view3d_from_minmax(bContext *C, View3D *v3d, ARegion *ar,
/* fix up zoom distance if needed */
if (rv3d->is_persp) {
- if (size <= v3d->near * 1.5f) {
- /* do not zoom closer than the near clipping plane */
- size = v3d->near * 1.5f;
+ float lens, sensor_size;
+ /* offset the view based on the lens */
+ if (rv3d->persp == RV3D_CAMOB && ED_view3d_camera_lock_check(v3d, rv3d)) {
+ CameraParams params;
+ BKE_camera_params_init(&params);
+ BKE_camera_params_from_object(&params, v3d->camera);
+
+ lens = params.lens;
+ sensor_size = BKE_camera_sensor_size(params.sensor_fit, params.sensor_x, params.sensor_y);
}
+ else {
+ lens = v3d->lens;
+ sensor_size = DEFAULT_SENSOR_WIDTH;
+ }
+ size = ED_view3d_radius_to_persp_dist(focallength_to_fov(lens, sensor_size), size / 2.0f) * VIEW3D_MARGIN;
+
+ /* do not zoom closer than the near clipping plane */
+ size = max_ff(size, v3d->near * 1.5f);
}
else { /* ortho */
if (size < 0.0001f) {
@@ -2236,7 +2250,7 @@ static void view3d_from_minmax(bContext *C, View3D *v3d, ARegion *ar,
}
else {
/* adjust zoom so it looks nicer */
- size *= 0.7f;
+ size = ED_view3d_radius_to_ortho_dist(v3d->lens, size / 2.0f) * VIEW3D_MARGIN;
}
}
}
diff --git a/source/blender/editors/space_view3d/view3d_iterators.c b/source/blender/editors/space_view3d/view3d_iterators.c
index b928e060ca0..37607729d0d 100644
--- a/source/blender/editors/space_view3d/view3d_iterators.c
+++ b/source/blender/editors/space_view3d/view3d_iterators.c
@@ -20,7 +20,7 @@
* ***** END GPL LICENSE BLOCK *****
*/
-/** \file blender/editors/object/view3d_iterators.c
+/** \file blender/editors/space_view3d/view3d_iterators.c
* \ingroup spview3d
*/
diff --git a/source/blender/editors/space_view3d/view3d_toolbar.c b/source/blender/editors/space_view3d/view3d_toolbar.c
index d36b0085acb..bfeb56036e6 100644
--- a/source/blender/editors/space_view3d/view3d_toolbar.c
+++ b/source/blender/editors/space_view3d/view3d_toolbar.c
@@ -176,7 +176,7 @@ static uiBlock *tool_search_menu(bContext *C, ARegion *ar, void *arg_listbase)
uiBlockSetFlag(block, UI_BLOCK_LOOP | UI_BLOCK_REDRAW | UI_BLOCK_SEARCH_MENU);
/* fake button, it holds space for search items */
- uiDefBut(block, LABEL, 0, "", 10, 15, 150, uiSearchBoxhHeight(), NULL, 0, 0, 0, 0, NULL);
+ uiDefBut(block, LABEL, 0, "", 10, 15, uiSearchBoxWidth(), uiSearchBoxHeight(), NULL, 0, 0, 0, 0, NULL);
but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 0, 150, 19, 0, 0, "");
uiButSetSearchFunc(but, operator_search_cb, arg_listbase, operator_call_cb, NULL);
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index 714898fed21..ef15c1e734e 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -323,8 +323,14 @@ static int view3d_smoothview_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent
if (rv3d->viewlock & RV3D_BOXVIEW)
view3d_boxview_copy(CTX_wm_area(C), CTX_wm_region(C));
-
+
+ /* note: this doesn't work right because the v3d->lens is now used in ortho mode r51636,
+ * when switching camera in quad-view the other ortho views would zoom & reset. */
+#if 0
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
+#else
+ ED_region_tag_redraw(CTX_wm_region(C));
+#endif
return OPERATOR_FINISHED;
}
@@ -1028,7 +1034,8 @@ static int view3d_localview_init(Main *bmain, Scene *scene, ScrArea *sa, ReportL
{
View3D *v3d = sa->spacedata.first;
Base *base;
- float size = 0.0, min[3], max[3], box[3];
+ float min[3], max[3], box[3];
+ float size = 0.0f, size_persp = 0.0f, size_ortho = 0.0f;
unsigned int locallay;
int ok = FALSE;
@@ -1068,7 +1075,13 @@ static int view3d_localview_init(Main *bmain, Scene *scene, ScrArea *sa, ReportL
box[1] = (max[1] - min[1]);
box[2] = (max[2] - min[2]);
size = MAX3(box[0], box[1], box[2]);
- if (size <= 0.01f) size = 0.01f;
+
+ /* do not zoom closer than the near clipping plane */
+ size = max_ff(size, v3d->near * 1.5f);
+
+ /* perspective size (we always switch out of camera view so no need to use its lens size) */
+ size_persp = ED_view3d_radius_to_persp_dist(focallength_to_fov(v3d->lens, DEFAULT_SENSOR_WIDTH), size / 2.0f) * VIEW3D_MARGIN;
+ size_ortho = ED_view3d_radius_to_ortho_dist(v3d->lens, size / 2.0f) * VIEW3D_MARGIN;
}
if (ok == TRUE) {
@@ -1085,14 +1098,20 @@ static int view3d_localview_init(Main *bmain, Scene *scene, ScrArea *sa, ReportL
rv3d->localvd = MEM_mallocN(sizeof(RegionView3D), "localview region");
memcpy(rv3d->localvd, rv3d, sizeof(RegionView3D));
- rv3d->ofs[0] = -(min[0] + max[0]) / 2.0f;
- rv3d->ofs[1] = -(min[1] + max[1]) / 2.0f;
- rv3d->ofs[2] = -(min[2] + max[2]) / 2.0f;
+ mid_v3_v3v3(v3d->cursor, min, max);
+ negate_v3_v3(rv3d->ofs, v3d->cursor);
+
+ if (rv3d->persp == RV3D_CAMOB) {
+ rv3d->persp = RV3D_PERSP;
+ }
- rv3d->dist = size;
/* perspective should be a bit farther away to look nice */
- if (rv3d->persp == RV3D_ORTHO)
- rv3d->dist *= 0.7f;
+ if (rv3d->persp != RV3D_ORTHO) {
+ rv3d->dist = size_persp;
+ }
+ else {
+ rv3d->dist = size_ortho;
+ }
/* correction for window aspect ratio */
if (ar->winy > 2 && ar->winx > 2) {
@@ -1100,12 +1119,6 @@ static int view3d_localview_init(Main *bmain, Scene *scene, ScrArea *sa, ReportL
if (asp < 1.0f) asp = 1.0f / asp;
rv3d->dist *= asp;
}
-
- if (rv3d->persp == RV3D_CAMOB) rv3d->persp = RV3D_PERSP;
-
- v3d->cursor[0] = -rv3d->ofs[0];
- v3d->cursor[1] = -rv3d->ofs[1];
- v3d->cursor[2] = -rv3d->ofs[2];
}
}
@@ -1511,7 +1524,7 @@ static void UNUSED_FUNCTION(view3d_align_axis_to_vector)(View3D *v3d, RegionView
}
}
-float ED_view3d_pixel_size(struct RegionView3D *rv3d, const float co[3])
+float ED_view3d_pixel_size(RegionView3D *rv3d, const float co[3])
{
return (rv3d->persmat[3][3] + (
rv3d->persmat[0][3] * co[0] +
@@ -1520,6 +1533,16 @@ float ED_view3d_pixel_size(struct RegionView3D *rv3d, const float co[3])
) * rv3d->pixsize;
}
+float ED_view3d_radius_to_persp_dist(const float angle, const float radius)
+{
+ return (radius / 2.0f) * fabsf(1.0f / cosf((((float)M_PI) - angle) / 2.0f));
+}
+
+float ED_view3d_radius_to_ortho_dist(const float lens, const float radius)
+{
+ return radius / (DEFAULT_SENSOR_WIDTH / lens);
+}
+
/* view matrix properties utilities */
/* unused */
diff --git a/source/blender/editors/transform/CMakeLists.txt b/source/blender/editors/transform/CMakeLists.txt
index 05a4f6f4ce5..ec114bc3019 100644
--- a/source/blender/editors/transform/CMakeLists.txt
+++ b/source/blender/editors/transform/CMakeLists.txt
@@ -25,6 +25,7 @@ set(INC
../../blenlib
../../blenloader
../../bmesh
+ ../../ikplugin
../../makesdna
../../makesrna
../../windowmanager
diff --git a/source/blender/editors/transform/SConscript b/source/blender/editors/transform/SConscript
index dbf6179035c..9cf36a2d970 100644
--- a/source/blender/editors/transform/SConscript
+++ b/source/blender/editors/transform/SConscript
@@ -6,7 +6,7 @@ sources = env.Glob('*.c')
incs = '../include ../../blenfont ../../blenlib ../../blenkernel ../../makesdna ../../imbuf'
incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include'
incs += ' ../../render/extern/include'
-incs += ' ../../gpu ../../makesrna ../../blenloader ../../bmesh'
+incs += ' ../../gpu ../../makesrna ../../blenloader ../../bmesh ../../ikplugin'
defs = []
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index b26718bb516..f93cfa25120 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -2427,6 +2427,8 @@ static void constraintSizeLim(TransInfo *t, TransData *td)
bConstraintTypeInfo *cti = get_constraint_typeinfo(CONSTRAINT_TYPE_SIZELIMIT);
bConstraintOb cob = {NULL};
bConstraint *con;
+ float size_sign[3], size_abs[3];
+ int i;
/* Make a temporary bConstraintOb for using these limit constraints
* - they only care that cob->matrix is correctly set ;-)
@@ -2440,8 +2442,14 @@ static void constraintSizeLim(TransInfo *t, TransData *td)
/* Reset val if SINGLESIZE but using a constraint */
if (td->flag & TD_SINGLESIZE)
return;
+
+ /* separate out sign to apply back later */
+ for (i = 0; i < 3; i++) {
+ size_sign[i] = signf(td->ext->size[i]);
+ size_abs[i] = fabsf(td->ext->size[i]);
+ }
- size_to_mat4(cob.matrix, td->ext->size);
+ size_to_mat4(cob.matrix, size_abs);
}
/* Evaluate valid constraints */
@@ -2489,7 +2497,9 @@ static void constraintSizeLim(TransInfo *t, TransData *td)
if (td->flag & TD_SINGLESIZE)
return;
+ /* extrace scale from matrix and apply back sign */
mat4_to_size(td->ext->size, cob.matrix);
+ mul_v3_v3(td->ext->size, size_sign);
}
}
}
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index 5b79b69f7ec..51efa2b0e40 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -91,6 +91,7 @@
#include "BKE_tracking.h"
#include "BKE_mask.h"
+#include "BIK_api.h"
#include "ED_anim_api.h"
#include "ED_armature.h"
@@ -773,6 +774,9 @@ static void pose_grab_with_ik_clear(Object *ob)
if (con->type == CONSTRAINT_TYPE_KINEMATIC) {
data = con->data;
if (data->flag & CONSTRAINT_IK_TEMP) {
+ /* iTaSC needs clear for removed constraints */
+ BIK_clear_data(ob->pose);
+
BLI_remlink(&pchan->constraints, con);
MEM_freeN(con->data);
MEM_freeN(con);
@@ -839,7 +843,7 @@ static short pose_grab_with_ik_add(bPoseChannel *pchan)
}
else
data->flag = CONSTRAINT_IK_TIP;
- data->flag |= CONSTRAINT_IK_TEMP | CONSTRAINT_IK_AUTO;
+ data->flag |= CONSTRAINT_IK_TEMP | CONSTRAINT_IK_AUTO | CONSTRAINT_IK_POS;
copy_v3_v3(data->grabtarget, pchan->pose_tail);
data->rootbone = 0; /* watch-it! has to be 0 here, since we're still on the same bone for the first time through the loop [#25885] */
@@ -933,6 +937,10 @@ static short pose_grab_with_ik(Object *ob)
}
}
+ /* iTaSC needs clear for new IK constraints */
+ if (tot_ik)
+ BIK_clear_data(ob->pose);
+
return (tot_ik) ? 1 : 0;
}
diff --git a/source/blender/editors/util/numinput.c b/source/blender/editors/util/numinput.c
index b73f5fa0869..0ec16ead35d 100644
--- a/source/blender/editors/util/numinput.c
+++ b/source/blender/editors/util/numinput.c
@@ -130,6 +130,9 @@ short hasNumInput(NumInput *n)
return 0;
}
+/**
+ * \warning \a vec must be set beforehand otherwise we risk uninitialized vars.
+ */
void applyNumInput(NumInput *n, float *vec)
{
short i, j;
diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c
index 0feaec514d2..a384c777aab 100644
--- a/source/blender/editors/uvedit/uvedit_ops.c
+++ b/source/blender/editors/uvedit/uvedit_ops.c
@@ -224,7 +224,9 @@ void ED_uvedit_assign_image(Main *bmain, Scene *scene, Object *obedit, Image *im
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
- if (uvedit_face_visible_test(scene, previma, efa, tf)) {
+ if (uvedit_face_visible_test(scene, previma, efa, tf) &&
+ (selected == TRUE || uvedit_face_select_test(scene, em, efa)))
+ {
if (ima) {
tf->tpage = ima;
@@ -2667,10 +2669,12 @@ static void uv_faces_do_sticky(SpaceImage *sima, Scene *scene, Object *obedit, s
else { /* SI_STICKY_DISABLE or ts->uv_flag & UV_SYNC_SELECTION */
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
if (BM_elem_flag_test(efa, BM_ELEM_TAG)) {
- if (select)
+ if (select) {
uvedit_face_select_enable(scene, em, efa, FALSE);
- else
+ }
+ else {
uvedit_face_select_disable(scene, em, efa);
+ }
}
}
}
@@ -2692,7 +2696,10 @@ static int border_select_exec(bContext *C, wmOperator *op)
MLoopUV *luv;
rcti rect;
rctf rectf;
- int change, pinned, select, faces, extend;
+ int change, pinned, select, extend;
+ const int use_face_center = (ts->uv_flag & UV_SYNC_SELECTION) ?
+ (ts->selectmode == SCE_SELECT_FACE) :
+ (ts->uv_selectmode == UV_SELECT_FACE);
/* get rectangle from operator */
WM_operator_properties_border_to_rcti(op, &rect);
@@ -2707,14 +2714,9 @@ static int border_select_exec(bContext *C, wmOperator *op)
if (!extend)
select_all_perform(scene, ima, em, SEL_DESELECT);
-
- if (ts->uv_flag & UV_SYNC_SELECTION)
- faces = (ts->selectmode == SCE_SELECT_FACE);
- else
- faces = (ts->uv_selectmode == UV_SELECT_FACE);
/* do actual selection */
- if (faces && !pinned) {
+ if (use_face_center && !pinned) {
/* handle face selection mode */
float cent[2];
@@ -2735,8 +2737,9 @@ static int border_select_exec(bContext *C, wmOperator *op)
}
/* (de)selects all tagged faces and deals with sticky modes */
- if (change)
+ if (change) {
uv_faces_do_sticky(sima, scene, obedit, select);
+ }
}
else {
/* other selection modes */
@@ -2805,19 +2808,19 @@ static void UV_OT_select_border(wmOperatorType *ot)
/* ******************** circle select operator **************** */
-static int select_uv_inside_ellipse(BMEditMesh *em, SpaceImage *UNUSED(sima), Scene *scene, int select,
- float *offset, float *ell, BMLoop *l, MLoopUV *luv)
+static int uv_inside_circle(const float uv[2], const float offset[2], const float ellipse[2])
{
/* normalized ellipse: ell[0] = scaleX, ell[1] = scaleY */
- float x, y, r2, *uv;
-
- uv = luv->uv;
-
- x = (uv[0] - offset[0]) * ell[0];
- y = (uv[1] - offset[1]) * ell[1];
+ float x, y;
+ x = (uv[0] - offset[0]) * ellipse[0];
+ y = (uv[1] - offset[1]) * ellipse[1];
+ return ((x * x + y * y) < 1.0f);
+}
- r2 = x * x + y * y;
- if (r2 < 1.0f) {
+static int select_uv_inside_ellipse(BMEditMesh *em, Scene *scene, const int select,
+ const float offset[2], const float ellipse[2], BMLoop *l, MLoopUV *luv)
+{
+ if (uv_inside_circle(luv->uv, offset, ellipse)) {
if (select) uvedit_uv_select_enable(em, scene, l, FALSE);
else uvedit_uv_select_disable(em, scene, l);
return TRUE;
@@ -2843,6 +2846,9 @@ static int circle_select_exec(bContext *C, wmOperator *op)
float zoomx, zoomy, offset[2], ellipse[2];
int gesture_mode = RNA_int_get(op->ptr, "gesture_mode");
int change = FALSE;
+ const int use_face_center = (ts->uv_flag & UV_SYNC_SELECTION) ?
+ (ts->selectmode == SCE_SELECT_FACE) :
+ (ts->uv_selectmode == UV_SELECT_FACE);
/* get operator properties */
select = (gesture_mode == GESTURE_MODAL_SELECT);
@@ -2861,10 +2867,32 @@ static int circle_select_exec(bContext *C, wmOperator *op)
UI_view2d_region_to_view(&ar->v2d, x, y, &offset[0], &offset[1]);
/* do selection */
- BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
- change |= select_uv_inside_ellipse(em, sima, scene, select, offset, ellipse, l, luv);
+ if (use_face_center) {
+ change = FALSE;
+ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+ BM_elem_flag_disable(efa, BM_ELEM_TAG);
+ /* assume not touched */
+ if ((select) != (uvedit_face_select_test(scene, em, efa))) {
+ float cent[2];
+ uv_poly_center(em, efa, cent);
+ if (uv_inside_circle(cent, offset, ellipse)) {
+ BM_elem_flag_enable(efa, BM_ELEM_TAG);
+ change = TRUE;
+ }
+ }
+ }
+
+ /* (de)selects all tagged faces and deals with sticky modes */
+ if (change) {
+ uv_faces_do_sticky(sima, scene, obedit, select);
+ }
+ }
+ else {
+ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+ BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
+ luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ change |= select_uv_inside_ellipse(em, scene, select, offset, ellipse, l, luv);
+ }
}
}
@@ -2906,12 +2934,16 @@ static void UV_OT_circle_select(wmOperatorType *ot)
static int do_lasso_select_mesh_uv(bContext *C, const int mcords[][2], short moves, short select)
{
+ SpaceImage *sima = CTX_wm_space_image(C);
Image *ima = CTX_data_edit_image(C);
ARegion *ar = CTX_wm_region(C);
Object *obedit = CTX_data_edit_object(C);
Scene *scene = CTX_data_scene(C);
ToolSettings *ts = scene->toolsettings;
BMEditMesh *em = BMEdit_FromObject(obedit);
+ const int use_face_center = (ts->uv_flag & UV_SYNC_SELECTION) ?
+ (ts->selectmode == SCE_SELECT_FACE) :
+ (ts->uv_selectmode == UV_SELECT_FACE);
BMIter iter, liter;
@@ -2923,9 +2955,10 @@ static int do_lasso_select_mesh_uv(bContext *C, const int mcords[][2], short mov
BLI_lasso_boundbox(&rect, mcords, moves);
- if (ts->uv_selectmode == UV_SELECT_FACE) { /* Face Center Sel */
+ if (use_face_center) { /* Face Center Sel */
change = FALSE;
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+ BM_elem_flag_disable(efa, BM_ELEM_TAG);
/* assume not touched */
if ((select) != (uvedit_face_select_test(scene, em, efa))) {
float cent[2];
@@ -2934,11 +2967,16 @@ static int do_lasso_select_mesh_uv(bContext *C, const int mcords[][2], short mov
if (BLI_rcti_isect_pt_v(&rect, screen_uv) &&
BLI_lasso_is_point_inside(mcords, moves, screen_uv[0], screen_uv[1], V2D_IS_CLIPPED))
{
- uvedit_face_select_enable(scene, em, efa, FALSE);
+ BM_elem_flag_enable(efa, BM_ELEM_TAG);
change = TRUE;
}
}
}
+
+ /* (de)selects all tagged faces and deals with sticky modes */
+ if (change) {
+ uv_faces_do_sticky(sima, scene, obedit, select);
+ }
}
else { /* Vert Sel */
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
@@ -3395,7 +3433,7 @@ static int hide_exec(bContext *C, wmOperator *op)
MTexPoly *tf;
int swap = RNA_boolean_get(op->ptr, "unselected");
Image *ima = sima ? sima->image : NULL;
- int facemode = (ts->uv_selectmode == UV_SELECT_FACE);
+ const int use_face_center = (ts->uv_selectmode == UV_SELECT_FACE);
if (ts->uv_flag & UV_SYNC_SELECTION) {
EDBM_mesh_hide(em, swap);
@@ -3425,7 +3463,7 @@ static int hide_exec(bContext *C, wmOperator *op)
if (hide) {
/* note, a special case for edges could be used,
* for now edges act like verts and get flushed */
- if (facemode) {
+ if (use_face_center) {
if (em->selectmode == SCE_SELECT_FACE) {
/* check that every UV is selected */
if (bm_face_is_all_uv_sel(em->bm, efa, TRUE) == !swap) {
@@ -3443,8 +3481,6 @@ static int hide_exec(bContext *C, wmOperator *op)
}
}
if (!swap) uvedit_face_select_disable(scene, em, efa);
-
-
}
}
else if (em->selectmode == SCE_SELECT_FACE) {
@@ -3507,8 +3543,8 @@ static int reveal_exec(bContext *C, wmOperator *UNUSED(op))
BMLoop *l;
BMIter iter, liter;
MLoopUV *luv;
- int facemode = (ts->uv_selectmode == UV_SELECT_FACE);
- int stickymode = sima ? (sima->sticky != SI_STICKY_DISABLE) : 1;
+ const int use_face_center = (ts->uv_selectmode == UV_SELECT_FACE);
+ const int stickymode = sima ? (sima->sticky != SI_STICKY_DISABLE) : 1;
/* note on tagging, selecting faces needs to be delayed so it doesn't select the verts and
* confuse our checks on selected verts. */
@@ -3520,7 +3556,7 @@ static int reveal_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
- if (facemode) {
+ if (use_face_center) {
if (em->selectmode == SCE_SELECT_FACE) {
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
BM_elem_flag_disable(efa, BM_ELEM_TAG);
diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c
index e10d70d48d1..4ca642690c4 100644
--- a/source/blender/editors/uvedit/uvedit_smart_stitch.c
+++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c
@@ -1072,17 +1072,23 @@ static int stitch_init(bContext *C, wmOperator *op)
BMEditMesh *em;
GHashIterator *ghi;
UvEdge *all_edges;
- StitchState *state = MEM_mallocN(sizeof(StitchState), "stitch state");
+ StitchState *state;
Scene *scene = CTX_data_scene(C);
ToolSettings *ts = scene->toolsettings;
+ ARegion *ar = CTX_wm_region(C);
Object *obedit = CTX_data_edit_object(C);
- op->customdata = state;
+ if (!ar)
+ return 0;
+
+ state = MEM_mallocN(sizeof(StitchState), "stitch state");
if (!state)
return 0;
+ op->customdata = state;
+
/* initialize state */
state->use_limit = RNA_boolean_get(op->ptr, "use_limit");
state->limit_dist = RNA_float_get(op->ptr, "limit");
@@ -1091,7 +1097,7 @@ static int stitch_init(bContext *C, wmOperator *op)
state->static_island = RNA_int_get(op->ptr, "static_island");
state->midpoints = RNA_boolean_get(op->ptr, "midpoint_snap");
state->clear_seams = RNA_boolean_get(op->ptr, "clear_seams");
- state->draw_handle = ED_region_draw_cb_activate(CTX_wm_region(C)->type, stitch_draw, NULL, REGION_DRAW_POST_VIEW);
+ state->draw_handle = ED_region_draw_cb_activate(ar->type, stitch_draw, NULL, REGION_DRAW_POST_VIEW);
/* in uv synch selection, all uv's are visible */
if (ts->uv_flag & UV_SYNC_SELECTION) {
state->element_map = EDBM_uv_element_map_create(state->em, 0, 1);
diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
index efe9d1fedfe..1eec06eee75 100644
--- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c
+++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
@@ -306,7 +306,7 @@ static ParamHandle *construct_param_handle(Scene *scene, Object *ob, BMEditMesh
BLI_scanfill_edge_add(&sf_ctx, sf_vert_first, sf_vert);
- BLI_scanfill_calc_ex(&sf_ctx, TRUE, efa->no);
+ BLI_scanfill_calc_ex(&sf_ctx, 0, efa->no);
for (sf_tri = sf_ctx.fillfacebase.first; sf_tri; sf_tri = sf_tri->next) {
int i;
ls[0] = sf_tri->v1->tmp.p;
diff --git a/source/blender/gpu/GPU_draw.h b/source/blender/gpu/GPU_draw.h
index b26c25558c3..5f6eb45ad70 100644
--- a/source/blender/gpu/GPU_draw.h
+++ b/source/blender/gpu/GPU_draw.h
@@ -116,7 +116,7 @@ void GPU_set_anisotropic(float value);
float GPU_get_anisotropic(void);
/* enable gpu mipmapping */
-void GPU_set_gpu_mipmapping(int gpu_mipmap);
+void GPU_set_gpu_mipmapping(void);
/* Image updates and free
* - these deal with images bound as opengl textures */
diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c
index e3ba4cb1f95..f2ddedcd76c 100644
--- a/source/blender/gpu/intern/gpu_draw.c
+++ b/source/blender/gpu/intern/gpu_draw.c
@@ -240,16 +240,10 @@ static struct GPUTextureState {
/* Mipmap settings */
-void GPU_set_gpu_mipmapping(int gpu_mipmap)
+void GPU_set_gpu_mipmapping()
{
- int old_value = GTS.gpu_mipmap;
-
- /* only actually enable if it's supported */
- GTS.gpu_mipmap = gpu_mipmap && GLEW_EXT_framebuffer_object;
-
- if (old_value != GTS.gpu_mipmap) {
- GPU_free_images();
- }
+ /* always enable if it's supported */
+ GTS.gpu_mipmap = GLEW_EXT_framebuffer_object;
}
void GPU_set_mipmap(int mipmap)
diff --git a/source/blender/ikplugin/intern/ikplugin_api.c b/source/blender/ikplugin/intern/ikplugin_api.c
index efe07b2c48c..507d54d7526 100644
--- a/source/blender/ikplugin/intern/ikplugin_api.c
+++ b/source/blender/ikplugin/intern/ikplugin_api.c
@@ -86,7 +86,7 @@ static IKPlugin ikplugin_tab[] = {
static IKPlugin *get_plugin(bPose *pose)
{
- if (!pose || pose->iksolver < 0 || pose->iksolver > (sizeof(ikplugin_tab)/sizeof(IKPlugin) - 2))
+ if (!pose || pose->iksolver < 0 || pose->iksolver > (sizeof(ikplugin_tab) / sizeof(IKPlugin) - 2))
return NULL;
return &ikplugin_tab[pose->iksolver];
diff --git a/source/blender/imbuf/intern/openexr/CMakeLists.txt b/source/blender/imbuf/intern/openexr/CMakeLists.txt
index 6c428afe535..d5cb8e8a3b6 100644
--- a/source/blender/imbuf/intern/openexr/CMakeLists.txt
+++ b/source/blender/imbuf/intern/openexr/CMakeLists.txt
@@ -52,6 +52,4 @@ if(WITH_IMAGE_OPENEXR)
add_definitions(-DWITH_OPENEXR)
endif()
-message(STATUS "EXR ${INC_SYS}")
-
blender_add_lib(bf_imbuf_openexr "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index 1684cf28b3c..a05ff66e683 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -294,7 +294,8 @@ typedef struct bNodeTree {
void (*progress)(void *, float progress);
void (*stats_draw)(void *, char *str);
int (*test_break)(void *);
- void *tbh, *prh, *sdh;
+ void (*update_draw)(void *);
+ void *tbh, *prh, *sdh, *udh;
} bNodeTree;
diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c
index 9232ae098ea..1221b84372c 100644
--- a/source/blender/makesrna/intern/rna_material.c
+++ b/source/blender/makesrna/intern/rna_material.c
@@ -2121,13 +2121,13 @@ void rna_def_mtex_common(BlenderRNA *brna, StructRNA *srna, const char *begin,
RNA_def_property_editable_func(prop, activeeditable);
RNA_def_property_pointer_funcs(prop, activeget, activeset, NULL, NULL);
RNA_def_property_ui_text(prop, "Active Texture", "Active texture slot being displayed");
- RNA_def_property_update(prop, 0, update);
+ RNA_def_property_update(prop, NC_MATERIAL | ND_SHADING_LINKS, update);
prop = RNA_def_property(srna, "active_texture_index", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "texact");
RNA_def_property_range(prop, 0, MAX_MTEX - 1);
RNA_def_property_ui_text(prop, "Active Texture Index", "Index of active texture slot");
- RNA_def_property_update(prop, 0, update);
+ RNA_def_property_update(prop, NC_MATERIAL | ND_SHADING_LINKS, update);
}
#endif
diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c
index a669cb2558a..bd51af77b34 100644
--- a/source/blender/makesrna/intern/rna_object.c
+++ b/source/blender/makesrna/intern/rna_object.c
@@ -2174,7 +2174,7 @@ static void rna_def_object(BlenderRNA *brna)
RNA_def_property_int_funcs(prop, "rna_Object_active_material_index_get", "rna_Object_active_material_index_set",
"rna_Object_active_material_index_range");
RNA_def_property_ui_text(prop, "Active Material Index", "Index of active material slot");
- RNA_def_property_update(prop, NC_MATERIAL | ND_SHADING, NULL);
+ RNA_def_property_update(prop, NC_MATERIAL | ND_SHADING_LINKS, NULL);
/* transform */
prop = RNA_def_property(srna, "location", PROP_FLOAT, PROP_TRANSLATION);
diff --git a/source/blender/makesrna/intern/rna_scene_api.c b/source/blender/makesrna/intern/rna_scene_api.c
index 63253153699..012767b5845 100644
--- a/source/blender/makesrna/intern/rna_scene_api.c
+++ b/source/blender/makesrna/intern/rna_scene_api.c
@@ -62,12 +62,16 @@ static void rna_Scene_frame_set(Scene *scene, int frame, float subframe)
BKE_scene_update_for_newframe(G.main, scene, (1 << 20) - 1);
BKE_scene_camera_switch_update(scene);
- /* cant use NC_SCENE|ND_FRAME because this causes wm_event_do_notifiers to call
- * BKE_scene_update_for_newframe which will loose any un-keyed changes [#24690] */
- /* WM_main_add_notifier(NC_SCENE|ND_FRAME, scene); */
-
- /* instead just redraw the views */
- WM_main_add_notifier(NC_WINDOW, NULL);
+ /* don't do notifier when we're rendering, avoid some viewport crashes
+ * redrawing while the data is being modified for render */
+ if (!G.is_rendering) {
+ /* cant use NC_SCENE|ND_FRAME because this causes wm_event_do_notifiers to call
+ * BKE_scene_update_for_newframe which will loose any un-keyed changes [#24690] */
+ /* WM_main_add_notifier(NC_SCENE|ND_FRAME, scene); */
+
+ /* instead just redraw the views */
+ WM_main_add_notifier(NC_WINDOW, NULL);
+ }
}
static void rna_Scene_update_tagged(Scene *scene)
diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c
index e67985f68c5..b212879512e 100644
--- a/source/blender/makesrna/intern/rna_texture.c
+++ b/source/blender/makesrna/intern/rna_texture.c
@@ -46,6 +46,9 @@
#include "BKE_node.h"
+#include "WM_api.h"
+#include "WM_types.h"
+
EnumPropertyItem texture_filter_items[] = {
{TXF_BOX, "BOX", 0, "Box", ""},
{TXF_EWA, "EWA", 0, "EWA", ""},
@@ -110,9 +113,6 @@ EnumPropertyItem blend_type_items[] = {
#include "ED_node.h"
-#include "WM_api.h"
-#include "WM_types.h"
-
static StructRNA *rna_Texture_refine(struct PointerRNA *ptr)
{
Tex *tex = (Tex *)ptr->data;
@@ -603,7 +603,7 @@ static void rna_def_mtex(BlenderRNA *brna)
RNA_def_property_struct_type(prop, "Texture");
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Texture", "Texture datablock used by this texture slot");
- RNA_def_property_update(prop, 0, "rna_TextureSlot_update");
+ RNA_def_property_update(prop, NC_MATERIAL | ND_SHADING_LINKS, "rna_TextureSlot_update");
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
RNA_def_property_string_funcs(prop, "rna_TextureSlot_name_get", "rna_TextureSlot_name_length", NULL);
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index 59a3a8c2522..50341c84b8f 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -144,12 +144,6 @@ static void rna_userdef_anisotropic_update(Main *bmain, Scene *scene, PointerRNA
rna_userdef_update(bmain, scene, ptr);
}
-static void rna_userdef_gl_gpu_mipmaps(Main *bmain, Scene *scene, PointerRNA *ptr)
-{
- GPU_set_gpu_mipmapping(U.use_gpu_mipmap);
- rna_userdef_update(bmain, scene, ptr);
-}
-
static void rna_userdef_gl_texture_limit_update(Main *bmain, Scene *scene, PointerRNA *ptr)
{
GPU_free_images();
@@ -3234,11 +3228,6 @@ static void rna_def_userdef_system(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "16 Bit Float Textures", "Use 16 bit per component texture for float images");
RNA_def_property_update(prop, 0, "rna_userdef_gl_use_16bit_textures");
- prop = RNA_def_property(srna, "use_gpu_mipmap", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "use_gpu_mipmap", 1);
- RNA_def_property_ui_text(prop, "GPU Mipmap Generation", "Generate Image Mipmaps on the GPU");
- RNA_def_property_update(prop, 0, "rna_userdef_gl_gpu_mipmaps");
-
prop = RNA_def_property(srna, "use_vertex_buffer_objects", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "gameflags", USER_DISABLE_VBO);
RNA_def_property_ui_text(prop, "VBOs",
diff --git a/source/blender/makesrna/rna_cleanup/rna_cleaner.py b/source/blender/makesrna/rna_cleanup/rna_cleaner.py
index 0231e57fcfd..8b4b10c490e 100755
--- a/source/blender/makesrna/rna_cleanup/rna_cleaner.py
+++ b/source/blender/makesrna/rna_cleanup/rna_cleaner.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python3.2
+#!/usr/bin/env python3
"""
This script is used to help cleaning RNA api.
diff --git a/source/blender/makesrna/rna_cleanup/rna_cleaner_merge.py b/source/blender/makesrna/rna_cleanup/rna_cleaner_merge.py
index 75851105991..17ea5f9b0bd 100755
--- a/source/blender/makesrna/rna_cleanup/rna_cleaner_merge.py
+++ b/source/blender/makesrna/rna_cleanup/rna_cleaner_merge.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python3.2
+#!/usr/bin/env python3
import sys
diff --git a/source/blender/modifiers/intern/MOD_array.c b/source/blender/modifiers/intern/MOD_array.c
index d4463098f07..3ca2c364345 100644
--- a/source/blender/modifiers/intern/MOD_array.c
+++ b/source/blender/modifiers/intern/MOD_array.c
@@ -274,10 +274,10 @@ static void bm_merge_dm_transform(BMesh *bm, DerivedMesh *dm, float mat[4][4],
v2 = BMO_iter_map_value_p(&oiter);
/* check in case the target vertex (v2) is already marked
* for merging */
- while ((v3 = BMO_slot_map_ptr_get(slot_targetmap, v2))) {
+ while ((v3 = BMO_slot_map_elem_get(slot_targetmap, v2))) {
v2 = v3;
}
- BMO_slot_map_ptr_insert(weld_op, slot_targetmap, v, v2);
+ BMO_slot_map_elem_insert(weld_op, slot_targetmap, v, v2);
}
BMO_op_finish(bm, &find_op);
@@ -319,7 +319,7 @@ static void merge_first_last(BMesh *bm,
slot_targetmap = BMO_slot_get(weld_op->slots_in, "targetmap");
BMO_ITER (v, &oiter, find_op.slots_out, "targetmap.out", 0) {
v2 = BMO_iter_map_value_p(&oiter);
- BMO_slot_map_ptr_insert(weld_op, slot_targetmap, v, v2);
+ BMO_slot_map_elem_insert(weld_op, slot_targetmap, v, v2);
}
BMO_op_finish(bm, &find_op);
@@ -494,11 +494,11 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
/* check in case the target vertex (v2) is already marked
* for merging */
- while ((v3 = BMO_slot_map_ptr_get(slot_targetmap, v2))) {
+ while ((v3 = BMO_slot_map_elem_get(slot_targetmap, v2))) {
v2 = v3;
}
- BMO_slot_map_ptr_insert(&weld_op, slot_targetmap, v, v2);
+ BMO_slot_map_elem_insert(&weld_op, slot_targetmap, v, v2);
}
#undef _E
diff --git a/source/blender/modifiers/intern/MOD_decimate.c b/source/blender/modifiers/intern/MOD_decimate.c
index 3f8eaa438c9..28cdfa810fa 100644
--- a/source/blender/modifiers/intern/MOD_decimate.c
+++ b/source/blender/modifiers/intern/MOD_decimate.c
@@ -145,12 +145,14 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
if (dmd->flag & MOD_DECIM_FLAG_INVERT_VGROUP) {
for (i = 0; i < vert_tot; i++) {
- vweights[i] = 1.0f - defvert_find_weight(&dvert[i], defgrp_index);
+ const float f = 1.0f - defvert_find_weight(&dvert[i], defgrp_index);
+ vweights[i] = f > BM_MESH_DECIM_WEIGHT_EPS ? (1.0f / f) : BM_MESH_DECIM_WEIGHT_MAX;
}
}
else {
for (i = 0; i < vert_tot; i++) {
- vweights[i] = defvert_find_weight(&dvert[i], defgrp_index);
+ const float f = defvert_find_weight(&dvert[i], defgrp_index);
+ vweights[i] = f > BM_MESH_DECIM_WEIGHT_EPS ? (1.0f / f) : BM_MESH_DECIM_WEIGHT_MAX;
}
}
}
diff --git a/source/blender/modifiers/intern/MOD_skin.c b/source/blender/modifiers/intern/MOD_skin.c
index 9f702957fa5..a73d52a0a63 100644
--- a/source/blender/modifiers/intern/MOD_skin.c
+++ b/source/blender/modifiers/intern/MOD_skin.c
@@ -941,18 +941,18 @@ static void add_poly(SkinOutput *so,
BLI_assert(v3 != v4);
BLI_assert(v1 && v2 && v3);
- edges[0] = BM_edge_create(so->bm, v1, v2, NULL, TRUE);
- edges[1] = BM_edge_create(so->bm, v2, v3, NULL, TRUE);
+ edges[0] = BM_edge_create(so->bm, v1, v2, NULL, BM_CREATE_NO_DOUBLE);
+ edges[1] = BM_edge_create(so->bm, v2, v3, NULL, BM_CREATE_NO_DOUBLE);
if (v4) {
- edges[2] = BM_edge_create(so->bm, v3, v4, NULL, TRUE);
- edges[3] = BM_edge_create(so->bm, v4, v1, NULL, TRUE);
+ edges[2] = BM_edge_create(so->bm, v3, v4, NULL, BM_CREATE_NO_DOUBLE);
+ edges[3] = BM_edge_create(so->bm, v4, v1, NULL, BM_CREATE_NO_DOUBLE);
}
else {
- edges[2] = BM_edge_create(so->bm, v3, v1, NULL, TRUE);
+ edges[2] = BM_edge_create(so->bm, v3, v1, NULL, BM_CREATE_NO_DOUBLE);
edges[3] = NULL;
}
- f = BM_face_create(so->bm, verts, edges, v4 ? 4 : 3, TRUE);
+ f = BM_face_create(so->bm, verts, edges, v4 ? 4 : 3, BM_CREATE_NO_DOUBLE);
if (so->smd->flag & MOD_SKIN_SMOOTH_SHADING)
BM_elem_flag_enable(f, BM_ELEM_SMOOTH);
f->mat_nr = so->mat_nr;
@@ -996,7 +996,7 @@ static void output_frames(BMesh *bm,
f = &sn->frames[i];
for (j = 0; j < 4; j++) {
if (!f->merge[j].frame) {
- BMVert *v = f->verts[j] = BM_vert_create(bm, f->co[j], NULL);
+ BMVert *v = f->verts[j] = BM_vert_create(bm, f->co[j], NULL, 0);
if (input_dvert) {
MDeformVert *dv;
@@ -1093,7 +1093,7 @@ static BMFace *collapse_face_corners(BMesh *bm, BMFace *f, int n,
v_safe = shortest_edge->v1;
v_merge = shortest_edge->v2;
mid_v3_v3v3(v_safe->co, v_safe->co, v_merge->co);
- BMO_slot_map_ptr_insert(&op, slot_targetmap, v_merge, v_safe);
+ BMO_slot_map_elem_insert(&op, slot_targetmap, v_merge, v_safe);
BMO_op_exec(bm, &op);
BMO_op_finish(bm, &op);
@@ -1287,8 +1287,7 @@ static void skin_fix_hole_no_good_verts(BMesh *bm, Frame *frame, BMFace *split_f
"weld_verts");
slot_targetmap = BMO_slot_get(op.slots_in, "targetmap");
for (i = 0; i < 4; i++) {
- BMO_slot_map_ptr_insert(&op, slot_targetmap,
- verts[i], frame->verts[best_order[i]]);
+ BMO_slot_map_elem_insert(&op, slot_targetmap, verts[i], frame->verts[best_order[i]]);
}
BMO_op_exec(bm, &op);
BMO_op_finish(bm, &op);
@@ -1310,7 +1309,7 @@ static void skin_hole_detach_partially_attached_frame(BMesh *bm, Frame *frame)
/* Detach everything */
for (i = 0; i < totattached; i++) {
BMVert **av = &frame->verts[attached[i]];
- (*av) = BM_vert_create(bm, (*av)->co, *av);
+ (*av) = BM_vert_create(bm, (*av)->co, *av, 0);
}
}
diff --git a/source/blender/nodes/NOD_composite.h b/source/blender/nodes/NOD_composite.h
index eecc1e46827..6d60ac0bb58 100644
--- a/source/blender/nodes/NOD_composite.h
+++ b/source/blender/nodes/NOD_composite.h
@@ -40,8 +40,6 @@ extern bNodeTreeType ntreeType_Composite;
/* ****************** types array for all composite nodes ****************** */
void register_node_type_cmp_group(struct bNodeTreeType *ttype);
-void register_node_type_cmp_forloop(struct bNodeTreeType *ttype);
-void register_node_type_cmp_whileloop(struct bNodeTreeType *ttype);
void register_node_type_cmp_rlayers(struct bNodeTreeType *ttype);
void register_node_type_cmp_image(struct bNodeTreeType *ttype);
diff --git a/source/blender/nodes/NOD_shader.h b/source/blender/nodes/NOD_shader.h
index e402924c04f..74135776c9c 100644
--- a/source/blender/nodes/NOD_shader.h
+++ b/source/blender/nodes/NOD_shader.h
@@ -41,8 +41,6 @@ extern struct bNodeTreeType ntreeType_Shader;
/* ****************** types array for all shaders ****************** */
void register_node_type_sh_group(struct bNodeTreeType *ttype);
-void register_node_type_sh_forloop(struct bNodeTreeType *ttype);
-void register_node_type_sh_whileloop(struct bNodeTreeType *ttype);
void register_node_type_sh_output(struct bNodeTreeType *ttype);
void register_node_type_sh_material(struct bNodeTreeType *ttype);
diff --git a/source/blender/nodes/NOD_texture.h b/source/blender/nodes/NOD_texture.h
index 7722580d136..a1be9963b8a 100644
--- a/source/blender/nodes/NOD_texture.h
+++ b/source/blender/nodes/NOD_texture.h
@@ -40,8 +40,6 @@ extern bNodeTreeType ntreeType_Texture;
/* ****************** types array for all texture nodes ****************** */
void register_node_type_tex_group(struct bNodeTreeType *ttype);
-void register_node_type_tex_forloop(struct bNodeTreeType *ttype);
-void register_node_type_tex_whileloop(struct bNodeTreeType *ttype);
void register_node_type_tex_math(struct bNodeTreeType *ttype);
void register_node_type_tex_mix_rgb(struct bNodeTreeType *ttype);
diff --git a/source/blender/nodes/intern/node_socket.c b/source/blender/nodes/intern/node_socket.c
index 0335d295fba..69256fafc3d 100644
--- a/source/blender/nodes/intern/node_socket.c
+++ b/source/blender/nodes/intern/node_socket.c
@@ -473,6 +473,35 @@ void node_socket_convert_default_value(int to_type, void *to_default_value, int
}
}
+static void node_socket_set_minmax_subtype(bNodeSocket *sock, struct bNodeSocketTemplate *stemp)
+{
+ switch (sock->type) {
+ case SOCK_FLOAT:
+ {
+ bNodeSocketValueFloat *dval= sock->default_value;
+ dval->min = stemp->min;
+ dval->max = stemp->max;
+ dval->subtype = stemp->subtype;
+ break;
+ }
+ case SOCK_INT:
+ {
+ bNodeSocketValueInt *dval= sock->default_value;
+ dval->min = stemp->min;
+ dval->max = stemp->max;
+ dval->subtype = stemp->subtype;
+ break;
+ }
+ case SOCK_VECTOR:
+ {
+ bNodeSocketValueVector *dval= sock->default_value;
+ dval->min = stemp->min;
+ dval->max = stemp->max;
+ dval->subtype = stemp->subtype;
+ break;
+ }
+ }
+}
struct bNodeSocket *node_add_input_from_template(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocketTemplate *stemp)
{
@@ -512,6 +541,7 @@ struct bNodeSocket *node_add_input_from_template(struct bNodeTree *ntree, struct
struct bNodeSocket *node_add_output_from_template(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocketTemplate *stemp)
{
bNodeSocket *sock = nodeAddSocket(ntree, node, SOCK_OUT, stemp->name, stemp->type);
+ node_socket_set_minmax_subtype(sock, stemp);
return sock;
}
@@ -532,32 +562,7 @@ static bNodeSocket *verify_socket_template(bNodeTree *ntree, bNode *node, int in
/* Copy the property range and subtype parameters in case the template changed.
* NOT copying the actual value here, only button behavior changes!
*/
- switch (sock->type) {
- case SOCK_FLOAT:
- {
- bNodeSocketValueFloat *dval= sock->default_value;
- dval->min = stemp->min;
- dval->max = stemp->max;
- dval->subtype = stemp->subtype;
- break;
- }
- case SOCK_INT:
- {
- bNodeSocketValueInt *dval= sock->default_value;
- dval->min = stemp->min;
- dval->max = stemp->max;
- dval->subtype = stemp->subtype;
- break;
- }
- case SOCK_VECTOR:
- {
- bNodeSocketValueVector *dval= sock->default_value;
- dval->min = stemp->min;
- dval->max = stemp->max;
- dval->subtype = stemp->subtype;
- break;
- }
- }
+ node_socket_set_minmax_subtype(sock, stemp);
BLI_remlink(socklist, sock);
diff --git a/source/blender/python/bmesh/CMakeLists.txt b/source/blender/python/bmesh/CMakeLists.txt
index 032a914fb70..ccabe572ce5 100644
--- a/source/blender/python/bmesh/CMakeLists.txt
+++ b/source/blender/python/bmesh/CMakeLists.txt
@@ -34,6 +34,7 @@ set(INC_SYS
set(SRC
bmesh_py_api.c
bmesh_py_ops.c
+ bmesh_py_ops_call.c
bmesh_py_types.c
bmesh_py_types_customdata.c
bmesh_py_types_meshdata.c
@@ -42,6 +43,7 @@ set(SRC
bmesh_py_api.h
bmesh_py_ops.h
+ bmesh_py_ops_call.h
bmesh_py_types.h
bmesh_py_types_customdata.h
bmesh_py_types_meshdata.h
diff --git a/source/blender/python/bmesh/bmesh_py_api.c b/source/blender/python/bmesh/bmesh_py_api.c
index e02efc79da0..697a9259b37 100644
--- a/source/blender/python/bmesh/bmesh_py_api.c
+++ b/source/blender/python/bmesh/bmesh_py_api.c
@@ -51,7 +51,6 @@
#include "bmesh_py_api.h" /* own include */
-
PyDoc_STRVAR(bpy_bm_new_doc,
".. method:: new()\n"
"\n"
@@ -73,6 +72,8 @@ PyDoc_STRVAR(bpy_bm_from_edit_mesh_doc,
"\n"
" Return a BMesh from this mesh, currently the mesh must already be in editmode.\n"
"\n"
+" :arg mesh: The editmode mesh.\n"
+" :type mesh: :class:`bpy.types.Mesh`\n"
" :return: the BMesh associated with this mesh.\n"
" :rtype: :class:`bmesh.types.BMesh`\n"
);
@@ -96,9 +97,56 @@ static PyObject *bpy_bm_from_edit_mesh(PyObject *UNUSED(self), PyObject *value)
return BPy_BMesh_CreatePyObject(bm, BPY_BMFLAG_IS_WRAPPED);
}
+PyDoc_STRVAR(bpy_bm_update_edit_mesh_doc,
+".. method:: update_edit_mesh(mesh, tessface=True)\n"
+"\n"
+" Update the mesh after changes to the BMesh in editmode, \n"
+" optionally recalculating n-gon tessellation.\n"
+"\n"
+" :arg mesh: The editmode mesh.\n"
+" :type mesh: :class:`bpy.types.Mesh`\n"
+" :arg tessface: Option to recalculate n-gon tessellation.\n"
+" :type tessface: boolean\n"
+);
+static PyObject *bpy_bm_update_edit_mesh(PyObject *UNUSED(self), PyObject *args)
+{
+ PyObject *py_me;
+ Mesh *me;
+ int do_tessface = TRUE;
+
+ if (!PyArg_ParseTuple(args, "O|i:update_edit_mesh", &py_me, &do_tessface)) {
+ return NULL;
+ }
+
+ me = PyC_RNA_AsPointer(py_me, "Mesh");
+
+ if (me == NULL) {
+ return NULL;
+ }
+
+ if (me->edit_btmesh == NULL) {
+ PyErr_SetString(PyExc_ValueError,
+ "The mesh must be in editmode");
+ return NULL;
+ }
+
+ {
+ /* XXX, not great - infact this function could just not use the context at all
+ * postpone that change until after release: BMESH_TODO - campbell */
+ extern struct bContext *BPy_GetContext(void);
+ extern void EDBM_update_generic(struct bContext *C, BMEditMesh *em, const short do_tessface);
+
+ struct bContext *C = BPy_GetContext();
+ EDBM_update_generic(C, me->edit_btmesh, do_tessface);
+ }
+
+ Py_RETURN_NONE;
+}
+
static struct PyMethodDef BPy_BM_methods[] = {
{"new", (PyCFunction)bpy_bm_new, METH_NOARGS, bpy_bm_new_doc},
{"from_edit_mesh", (PyCFunction)bpy_bm_from_edit_mesh, METH_O, bpy_bm_from_edit_mesh_doc},
+ {"update_edit_mesh", (PyCFunction)bpy_bm_update_edit_mesh, METH_VARARGS, bpy_bm_update_edit_mesh_doc},
{NULL, NULL, 0, NULL}
};
diff --git a/source/blender/python/bmesh/bmesh_py_ops.c b/source/blender/python/bmesh/bmesh_py_ops.c
index 2b82826eb04..0a2091af5df 100644
--- a/source/blender/python/bmesh/bmesh_py_ops.c
+++ b/source/blender/python/bmesh/bmesh_py_ops.c
@@ -38,39 +38,19 @@
#include "../generic/py_capi_utils.h"
-#include "../mathutils/mathutils.h"
-
#include "bmesh.h"
+#include "bmesh_py_ops_call.h"
#include "bmesh_py_ops.h" /* own include */
#include "bmesh_py_types.h"
-#include "bmesh_py_utils.h" /* own include */
-
-static int bpy_bm_op_as_py_error(BMesh *bm)
-{
- if (BMO_error_occurred(bm)) {
- const char *errmsg;
- if (BMO_error_get(bm, &errmsg, NULL)) {
- PyErr_Format(PyExc_RuntimeError,
- "bmesh operator: %.200s",
- errmsg);
- return -1;
- }
- }
- return 0;
-}
+#include "bmesh_py_utils.h"
/* bmesh operator 'bmesh.ops.*' callable types
* ******************************************* */
PyTypeObject bmesh_op_Type;
-typedef struct {
- PyObject_HEAD /* required python macro */
- const char *opname;
-} BPy_BMeshOpFunc;
-
static PyObject *bpy_bmesh_op_CreatePyObject(const char *opname)
{
BPy_BMeshOpFunc *self = PyObject_New(BPy_BMeshOpFunc, &bmesh_op_Type);
@@ -88,335 +68,6 @@ static PyObject *bpy_bmesh_op_repr(BPy_BMeshOpFunc *self)
}
-static PyObject *pyrna_op_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject *kw)
-{
- PyObject *ret;
- BPy_BMesh *py_bm;
- BMesh *bm;
-
- BMOperator bmop;
-
- if ((PyTuple_GET_SIZE(args) == 1) &&
- (py_bm = (BPy_BMesh *)PyTuple_GET_ITEM(args, 0)) &&
- (BPy_BMesh_Check(py_bm))
- )
- {
- BPY_BM_CHECK_OBJ(py_bm);
- bm = py_bm->bm;
- }
- else {
- PyErr_SetString(PyExc_TypeError,
- "calling a bmesh operator expects a single BMesh (non keyword) "
- "as the first argument");
- return NULL;
- }
-
- /* TODO - error check this!, though we do the error check on attribute access */
- /* TODO - make flags optional */
- BMO_op_init(bm, &bmop, BMO_FLAG_DEFAULTS, self->opname);
-
- if (kw && PyDict_Size(kw) > 0) {
- /* setup properties, see bpy_rna.c: pyrna_py_to_prop()
- * which shares this logic for parsing properties */
-
- PyObject *key, *value;
- Py_ssize_t pos = 0;
- while (PyDict_Next(kw, &pos, &key, &value)) {
- const char *slot_name = _PyUnicode_AsString(key);
- BMOpSlot *slot = BMO_slot_get(bmop.slots_in, slot_name);
-
- if (slot == NULL) {
- PyErr_Format(PyExc_TypeError,
- "%.200s: keyword \"%.200s\" is invalid for this operator",
- self->opname, slot_name);
- return NULL;
- }
-
- /* now assign the value */
- switch (slot->slot_type) {
- case BMO_OP_SLOT_BOOL:
- {
- int param;
-
- param = PyLong_AsLong(value);
-
- if (param < 0) {
- PyErr_Format(PyExc_TypeError,
- "%.200s: keyword \"%.200s\" expected True/False or 0/1, not %.200s",
- self->opname, slot_name, Py_TYPE(value)->tp_name);
- return NULL;
- }
- else {
- BMO_SLOT_AS_BOOL(slot) = param;
- }
-
- break;
- }
- case BMO_OP_SLOT_INT:
- {
- int overflow;
- long param = PyLong_AsLongAndOverflow(value, &overflow);
- if (overflow || (param > INT_MAX) || (param < INT_MIN)) {
- PyErr_Format(PyExc_ValueError,
- "%.200s: keyword \"%.200s\" value not in 'int' range "
- "(" STRINGIFY(INT_MIN) ", " STRINGIFY(INT_MAX) ")",
- self->opname, slot_name, Py_TYPE(value)->tp_name);
- return NULL;
- }
- else if (param == -1 && PyErr_Occurred()) {
- PyErr_Format(PyExc_TypeError,
- "%.200s: keyword \"%.200s\" expected an int, not %.200s",
- self->opname, slot_name, Py_TYPE(value)->tp_name);
- return NULL;
- }
- else {
- BMO_SLOT_AS_INT(slot) = (int)param;
- }
- break;
- }
- case BMO_OP_SLOT_FLT:
- {
- float param = PyFloat_AsDouble(value);
- if (param == -1 && PyErr_Occurred()) {
- PyErr_Format(PyExc_TypeError,
- "%.200s: keyword \"%.200s\" expected a float, not %.200s",
- self->opname, slot_name, Py_TYPE(value)->tp_name);
- return NULL;
- }
- else {
- BMO_SLOT_AS_FLOAT(slot) = param;
- }
- break;
- }
- case BMO_OP_SLOT_MAT:
- {
- /* XXX - BMesh operator design is crappy here, operator slot should define matrix size,
- * not the caller! */
- unsigned short size;
- if (!MatrixObject_Check(value)) {
- PyErr_Format(PyExc_TypeError,
- "%.200s: keyword \"%.200s\" expected a Matrix, not %.200s",
- self->opname, slot_name, Py_TYPE(value)->tp_name);
- return NULL;
- }
- else if (BaseMath_ReadCallback((MatrixObject *)value) == -1) {
- return NULL;
- }
- else if (((size = ((MatrixObject *)value)->num_col) != ((MatrixObject *)value)->num_row) ||
- (ELEM(size, 3, 4) == FALSE))
- {
- PyErr_Format(PyExc_TypeError,
- "%.200s: keyword \"%.200s\" expected a 3x3 or 4x4 matrix Matrix",
- self->opname, slot_name);
- return NULL;
- }
-
- BMO_slot_mat_set(&bmop, bmop.slots_in, slot_name, ((MatrixObject *)value)->matrix, size);
- break;
- }
- case BMO_OP_SLOT_VEC:
- {
- /* passing slot name here is a bit non-descriptive */
- if (mathutils_array_parse(BMO_SLOT_AS_VECTOR(slot), 3, 3, value, slot_name) == -1) {
- return NULL;
- }
- break;
- }
- case BMO_OP_SLOT_ELEMENT_BUF:
- {
- /* there are many ways we could interpret arguments, for now...
- * - verts/edges/faces from the mesh direct,
- * this way the operator takes every item.
- * - `TODO` a plain python sequence (list) of elements.
- * - `TODO` an iterator. eg.
- * face.verts
- * - `TODO` (type, flag) pair, eg.
- * ('VERT', {'TAG'})
- */
-
-#define BPY_BM_GENERIC_MESH_TEST(type_string) \
- if (((BPy_BMGeneric *)value)->bm != bm) { \
- PyErr_Format(PyExc_NotImplementedError, \
- "%.200s: keyword \"%.200s\" " type_string " are from another bmesh", \
- self->opname, slot_name, slot->slot_type); \
- return NULL; \
- } (void)0
-
- if (BPy_BMVertSeq_Check(value)) {
- BPY_BM_GENERIC_MESH_TEST("verts");
- BMO_slot_buffer_from_all(bm, &bmop, bmop.slots_in, slot_name, BM_VERT);
- }
- else if (BPy_BMEdgeSeq_Check(value)) {
- BPY_BM_GENERIC_MESH_TEST("edges");
- BMO_slot_buffer_from_all(bm, &bmop, bmop.slots_in, slot_name, BM_EDGE);
- }
- else if (BPy_BMFaceSeq_Check(value)) {
- BPY_BM_GENERIC_MESH_TEST("faces");
- BMO_slot_buffer_from_all(bm, &bmop, bmop.slots_in, slot_name, BM_FACE);
- }
- else if (BPy_BMElemSeq_Check(value)) {
- BMIter iter;
- BMHeader *ele;
- int tot;
- unsigned int i;
-
- BPY_BM_GENERIC_MESH_TEST("elements");
-
- /* this will loop over all elements which is a shame but
- * we need to know this before alloc */
- /* calls bpy_bmelemseq_length() */
- tot = Py_TYPE(value)->tp_as_sequence->sq_length((PyObject *)self);
-
- BMO_slot_buffer_alloc(&bmop, bmop.slots_in, slot_name, tot);
-
- i = 0;
- BM_ITER_BPY_BM_SEQ (ele, &iter, ((BPy_BMElemSeq *)value)) {
- slot->data.buf[i] = ele;
- i++;
- }
- }
- /* keep this last */
- else if (PySequence_Check(value)) {
- BMElem **elem_array = NULL;
- Py_ssize_t elem_array_len;
-
- elem_array = BPy_BMElem_PySeq_As_Array(&bm, value, 0, PY_SSIZE_T_MAX,
- &elem_array_len, BM_VERT | BM_EDGE | BM_FACE,
- TRUE, TRUE, slot_name);
-
- /* error is set above */
- if (elem_array == NULL) {
- return NULL;
- }
-
- BMO_slot_buffer_alloc(&bmop, bmop.slots_in, slot_name, elem_array_len);
- memcpy(slot->data.buf, elem_array, sizeof(void *) * elem_array_len);
- PyMem_FREE(elem_array);
- }
- else {
- PyErr_Format(PyExc_TypeError,
- "%.200s: keyword \"%.200s\" expected "
- "a bmesh sequence, list, (htype, flag) pair, not %.200s",
- self->opname, slot_name, Py_TYPE(value)->tp_name);
- return NULL;
- }
-
-#undef BPY_BM_GENERIC_MESH_TEST
-
- break;
- }
- default:
- /* TODO --- many others */
- PyErr_Format(PyExc_NotImplementedError,
- "%.200s: keyword \"%.200s\" type %d not working yet!",
- self->opname, slot_name, slot->slot_type);
- return NULL;
- break;
- }
- }
- }
-
- BMO_op_exec(bm, &bmop);
-
- /* from here until the end of the function, no returns, just set 'ret' */
- if (UNLIKELY(bpy_bm_op_as_py_error(bm) == -1)) {
- ret = NULL; /* exception raised above */
- }
- else if (bmop.slots_out[0].slot_name == NULL) {
- ret = (Py_INCREF(Py_None), Py_None);
- }
- else {
- /* build return value */
- int i;
- ret = PyDict_New();
-
- for (i = 0; bmop.slots_out[i].slot_name; i++) {
- // BMOpDefine *op_def = opdefines[bmop.type];
- // BMOSlotType *slot_type = op_def->slot_types_out[i];
- BMOpSlot *slot = &bmop.slots_out[i];
- PyObject *item = NULL;
-
- /* keep switch in same order as above */
- switch (slot->slot_type) {
- case BMO_OP_SLOT_BOOL:
- item = PyBool_FromLong((BMO_SLOT_AS_BOOL(slot)));
- break;
- case BMO_OP_SLOT_INT:
- item = PyLong_FromLong(BMO_SLOT_AS_INT(slot));
- break;
- case BMO_OP_SLOT_FLT:
- item = PyFloat_FromDouble((double)BMO_SLOT_AS_FLOAT(slot));
- break;
- case BMO_OP_SLOT_MAT:
- item = Matrix_CreatePyObject((float *)BMO_SLOT_AS_MATRIX(slot), 4, 4, Py_NEW, NULL);
- break;
- case BMO_OP_SLOT_VEC:
- item = Vector_CreatePyObject(BMO_SLOT_AS_VECTOR(slot), slot->len, Py_NEW, NULL);
- break;
- case BMO_OP_SLOT_ELEMENT_BUF:
- {
- const int size = slot->len;
- void **buffer = BMO_SLOT_AS_BUFFER(slot);
- int j;
-
- item = PyList_New(size);
- for (j = 0; j < size; j++) {
- BMHeader *ele = buffer[i];
- PyList_SET_ITEM(item, j, ele ? BPy_BMElem_CreatePyObject(bm, ele) : (Py_INCREF(Py_None), Py_None));
- }
- break;
- }
- case BMO_OP_SLOT_MAPPING:
- {
- GHash *slot_hash = BMO_SLOT_AS_GHASH(slot);
- GHashIterator *hash_iter;
- item = PyDict_New();
-
- for (hash_iter = BLI_ghashIterator_new(slot_hash);
- !BLI_ghashIterator_isDone(hash_iter);
- BLI_ghashIterator_step(hash_iter) )
- {
- BMHeader *ele_key = BLI_ghashIterator_getKey(hash_iter);
- BMHeader **ele_val = BLI_ghashIterator_getValue(hash_iter);
-
- PyObject *py_key = ele_key ? BPy_BMElem_CreatePyObject(bm, ele_key) : (Py_INCREF(Py_None), Py_None);
- PyObject *py_val = *ele_val ? BPy_BMElem_CreatePyObject(bm, *ele_val) : (Py_INCREF(Py_None), Py_None);
-
- PyDict_SetItem(ret, py_key, py_val);
- Py_DECREF(py_key);
- Py_DECREF(py_val);
- }
- BLI_ghashIterator_free(hash_iter);
- break;
- }
- }
- BLI_assert(item != NULL);
- if (item == NULL) {
- item = (Py_INCREF(Py_None), Py_None);
- }
-
-#if 1
- /* temp code, strip off '.out' while we keep this convention */
- {
- char slot_name_strip[MAX_SLOTNAME];
- char *ch = strchr(slot->slot_name, '.'); /* can't fail! */
- int tot = ch - slot->slot_name;
- BLI_assert(ch != NULL);
- memcpy(slot_name_strip, slot->slot_name, tot);
- slot_name_strip[tot] = '\0';
- PyDict_SetItemString(ret, slot_name_strip, item);
- }
-#else
- PyDict_SetItemString(ret, slot->slot_name, item);
-#endif
- Py_DECREF(item);
- }
- }
-
- BMO_op_finish(bm, &bmop);
- return ret;
-}
-
PyTypeObject bmesh_op_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
@@ -440,7 +91,7 @@ PyTypeObject bmesh_op_Type = {
/* More standard operations (here for binary compatibility) */
NULL, /* hashfunc tp_hash; */
- (ternaryfunc)pyrna_op_call, /* ternaryfunc tp_call; */
+ (ternaryfunc)BPy_BMO_call, /* ternaryfunc tp_call; */
NULL, /* reprfunc tp_str; */
/* will only use these if this is a subtype of a py class */
@@ -501,15 +152,15 @@ PyTypeObject bmesh_op_Type = {
/* bmesh fake module 'bmesh.ops'
* ***************************** */
-static PyObject *bpy_bmesh_fmod_getattro(PyObject *UNUSED(self), PyObject *pyname)
+static PyObject *bpy_bmesh_ops_fakemod_getattro(PyObject *UNUSED(self), PyObject *pyname)
{
- const unsigned int tot = bmesh_total_ops;
+ const unsigned int tot = bmo_opdefines_total;
unsigned int i;
const char *opname = _PyUnicode_AsString(pyname);
for (i = 0; i < tot; i++) {
- if (strcmp(opdefines[i]->opname, opname) == 0) {
- return bpy_bmesh_op_CreatePyObject(opdefines[i]->opname);
+ if (strcmp(bmo_opdefines[i]->opname, opname) == 0) {
+ return bpy_bmesh_op_CreatePyObject(opname);
}
}
@@ -519,23 +170,23 @@ static PyObject *bpy_bmesh_fmod_getattro(PyObject *UNUSED(self), PyObject *pynam
return NULL;
}
-static PyObject *bpy_bmesh_fmod_dir(PyObject *UNUSED(self))
+static PyObject *bpy_bmesh_ops_fakemod_dir(PyObject *UNUSED(self))
{
- const unsigned int tot = bmesh_total_ops;
+ const unsigned int tot = bmo_opdefines_total;
unsigned int i;
PyObject *ret;
- ret = PyList_New(bmesh_total_ops);
+ ret = PyList_New(bmo_opdefines_total);
for (i = 0; i < tot; i++) {
- PyList_SET_ITEM(ret, i, PyUnicode_FromString(opdefines[i]->opname));
+ PyList_SET_ITEM(ret, i, PyUnicode_FromString(bmo_opdefines[i]->opname));
}
return ret;
}
-static struct PyMethodDef bpy_bmesh_fmod_methods[] = {
- {"__dir__", (PyCFunction)bpy_bmesh_fmod_dir, METH_NOARGS, NULL},
+static struct PyMethodDef bpy_bmesh_ops_fakemod_methods[] = {
+ {"__dir__", (PyCFunction)bpy_bmesh_ops_fakemod_dir, METH_NOARGS, NULL},
{NULL, NULL, 0, NULL}
};
@@ -565,7 +216,7 @@ static PyTypeObject bmesh_ops_fakemod_Type = {
NULL, /* reprfunc tp_str; */
/* will only use these if this is a subtype of a py class */
- bpy_bmesh_fmod_getattro, /* getattrofunc tp_getattro; */
+ bpy_bmesh_ops_fakemod_getattro, /* getattrofunc tp_getattro; */
NULL, /* setattrofunc tp_setattro; */
/* Functions to access object as input/output buffer */
@@ -594,7 +245,7 @@ static PyTypeObject bmesh_ops_fakemod_Type = {
NULL, /* iternextfunc tp_iternext; */
/*** Attribute descriptor and subclassing stuff ***/
- bpy_bmesh_fmod_methods, /* struct PyMethodDef *tp_methods; */
+ bpy_bmesh_ops_fakemod_methods, /* struct PyMethodDef *tp_methods; */
NULL, /* struct PyMemberDef *tp_members; */
NULL, /* struct PyGetSetDef *tp_getset; */
NULL, /* struct _typeobject *tp_base; */
diff --git a/source/blender/python/bmesh/bmesh_py_ops_call.c b/source/blender/python/bmesh/bmesh_py_ops_call.c
new file mode 100644
index 00000000000..ded35363287
--- /dev/null
+++ b/source/blender/python/bmesh/bmesh_py_ops_call.c
@@ -0,0 +1,783 @@
+/*
+ * ***** 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) 2012 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/python/bmesh/bmesh_py_ops_call.c
+ * \ingroup pybmesh
+ *
+ * This file provides __call__ aka BPy_BMO_call for
+ * the bmesh operatorand has been given its own file
+ * because argument conversion is involved.
+ */
+
+#include <Python.h>
+
+#include "BLI_utildefines.h"
+
+#include "../mathutils/mathutils.h"
+
+#include "bmesh.h"
+
+#include "bmesh_py_ops.h"
+#include "bmesh_py_ops_call.h" /* own include */
+
+#include "bmesh_py_types.h"
+#include "bmesh_py_utils.h"
+
+static int bpy_bm_op_as_py_error(BMesh *bm)
+{
+ if (BMO_error_occurred(bm)) {
+ const char *errmsg;
+ if (BMO_error_get(bm, &errmsg, NULL)) {
+ PyErr_Format(PyExc_RuntimeError,
+ "bmesh operator: %.200s",
+ errmsg);
+ return -1;
+ }
+ }
+ return 0;
+}
+
+/**
+ * \brief Utility function to check BMVert/BMEdge/BMFace's
+ *
+ * \param value
+ * \param bm Check the \a value against this.
+ * \param htype Test \a value matches this type.
+ * \param descr Description text.
+ */
+static int bpy_slot_from_py_elem_check(BPy_BMElem *value, BMesh *bm, const char htype,
+ /* for error messages */
+ const char *opname, const char *slot_name, const char *descr)
+{
+ if (!BPy_BMElem_Check(value) ||
+ !(value->ele->head.htype & htype))
+ {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s: keyword \"%.200s\" %.200s, expected a %.200s not *.200s",
+ opname, slot_name, descr,
+ BPy_BMElem_StringFromHType(htype),
+ Py_TYPE(value)->tp_name);
+ return -1;
+ }
+ else if (value->bm == NULL) {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s: keyword \"%.200s\" %.200s invalidated element",
+ opname, slot_name, descr);
+ return -1;
+ }
+ else if (value->bm != bm) { /* we may want to make this check optional by setting 'bm' to NULL */
+ PyErr_Format(PyExc_TypeError,
+ "%.200s: keyword \"%.200s\" %.200s invalidated element",
+ opname, slot_name, descr);
+ return -1;
+ }
+ return 0;
+}
+
+/**
+ * \brief Utility function to check BMVertSeq/BMEdgeSeq/BMFaceSeq's
+ *
+ * \param value Caller must check its a BMeshSeq
+ * \param bm Check the \a value against this.
+ * \param htype_py The type(s) of \a value.
+ * \param htype_bmo The type(s) supported by the target slot.
+ * \param descr Description text.
+ */
+static int bpy_slot_from_py_elemseq_check(BPy_BMGeneric *value, BMesh *bm,
+ const char htype_py, const char htype_bmo,
+ /* for error messages */
+ const char *opname, const char *slot_name, const char *descr)
+{
+ if (value->bm == NULL) {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s: keyword \"%.200s\" %.200s, invalidated sequence",
+ opname, slot_name, descr);
+ return -1;
+ }
+ else if (value->bm != bm) { /* we may want to make this check optional by setting 'bm' to NULL */
+ PyErr_Format(PyExc_TypeError,
+ "%.200s: keyword \"%.200s\" %.200s, invalidated sequence",
+ opname, slot_name, descr);
+ return -1;
+ }
+ else if ((htype_py & htype_bmo) == 0) {
+ char str_bmo[32];
+ char str_py[32];
+ PyErr_Format(PyExc_TypeError,
+ "%.200s: keyword \"%.200s\" %.200s, expected "
+ "a sequence of %.200s not %.200s",
+ opname, slot_name, descr,
+ BPy_BMElem_StringFromHType_ex(htype_bmo, str_bmo),
+ BPy_BMElem_StringFromHType_ex(htype_py, str_py));
+ return -1;
+ }
+
+ return 0;
+}
+
+/**
+ * Use for giving py args to an operator.
+ */
+static int bpy_slot_from_py(BMesh *bm, BMOperator *bmop, BMOpSlot *slot, PyObject *value,
+ /* the are just for exception messages */
+ const char *opname, const char *slot_name)
+{
+ switch (slot->slot_type) {
+ case BMO_OP_SLOT_BOOL:
+ {
+ int param;
+
+ param = PyLong_AsLong(value);
+
+ if (param < 0) {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s: keyword \"%.200s\" expected True/False or 0/1, not %.200s",
+ opname, slot_name, Py_TYPE(value)->tp_name);
+ return -1;
+ }
+ else {
+ BMO_SLOT_AS_BOOL(slot) = param;
+ }
+
+ break;
+ }
+ case BMO_OP_SLOT_INT:
+ {
+ int overflow;
+ long param = PyLong_AsLongAndOverflow(value, &overflow);
+ if (overflow || (param > INT_MAX) || (param < INT_MIN)) {
+ PyErr_Format(PyExc_ValueError,
+ "%.200s: keyword \"%.200s\" value not in 'int' range "
+ "(" STRINGIFY(INT_MIN) ", " STRINGIFY(INT_MAX) ")",
+ opname, slot_name, Py_TYPE(value)->tp_name);
+ return -1;
+ }
+ else if (param == -1 && PyErr_Occurred()) {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s: keyword \"%.200s\" expected an int, not %.200s",
+ opname, slot_name, Py_TYPE(value)->tp_name);
+ return -1;
+ }
+ else {
+ BMO_SLOT_AS_INT(slot) = (int)param;
+ }
+ break;
+ }
+ case BMO_OP_SLOT_FLT:
+ {
+ float param = PyFloat_AsDouble(value);
+ if (param == -1 && PyErr_Occurred()) {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s: keyword \"%.200s\" expected a float, not %.200s",
+ opname, slot_name, Py_TYPE(value)->tp_name);
+ return -1;
+ }
+ else {
+ BMO_SLOT_AS_FLOAT(slot) = param;
+ }
+ break;
+ }
+ case BMO_OP_SLOT_MAT:
+ {
+ /* XXX - BMesh operator design is crappy here, operator slot should define matrix size,
+ * not the caller! */
+ unsigned short size;
+ if (!MatrixObject_Check(value)) {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s: keyword \"%.200s\" expected a Matrix, not %.200s",
+ opname, slot_name, Py_TYPE(value)->tp_name);
+ return -1;
+ }
+ else if (BaseMath_ReadCallback((MatrixObject *)value) == -1) {
+ return -1;
+ }
+ else if (((size = ((MatrixObject *)value)->num_col) != ((MatrixObject *)value)->num_row) ||
+ (ELEM(size, 3, 4) == FALSE))
+ {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s: keyword \"%.200s\" expected a 3x3 or 4x4 matrix Matrix",
+ opname, slot_name);
+ return -1;
+ }
+
+ BMO_slot_mat_set(bmop, bmop->slots_in, slot_name, ((MatrixObject *)value)->matrix, size);
+ break;
+ }
+ case BMO_OP_SLOT_VEC:
+ {
+ /* passing slot name here is a bit non-descriptive */
+ if (mathutils_array_parse(BMO_SLOT_AS_VECTOR(slot), 3, 3, value, slot_name) == -1) {
+ return -1;
+ }
+ break;
+ }
+ case BMO_OP_SLOT_ELEMENT_BUF:
+ {
+ if (slot->slot_subtype.elem & BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE) {
+ if (bpy_slot_from_py_elem_check((BPy_BMElem *)value, bm, (slot->slot_subtype.elem & BM_ALL_NOLOOP),
+ opname, slot_name, "single element") == -1)
+ {
+ return -1; /* error is set in bpy_slot_from_py_elem_check() */
+ }
+
+ BMO_slot_buffer_from_single(bmop, slot, &((BPy_BMElem *)value)->ele->head);
+ }
+ else {
+ /* there are many ways we could interpret arguments, for now...
+ * - verts/edges/faces from the mesh direct,
+ * this way the operator takes every item.
+ * - `TODO` a plain python sequence (list) of elements.
+ * - `TODO` an iterator. eg.
+ * face.verts
+ * - `TODO` (type, flag) pair, eg.
+ * ('VERT', {'TAG'})
+ */
+
+ if (BPy_BMVertSeq_Check(value)) {
+ if (bpy_slot_from_py_elemseq_check((BPy_BMGeneric *)value, bm,
+ BM_VERT, (slot->slot_subtype.elem & BM_ALL_NOLOOP),
+ opname, slot_name, "element buffer") == -1)
+ {
+ return -1; /* error is set in bpy_slot_from_py_elem_check() */
+ }
+
+ BMO_slot_buffer_from_all(bm, bmop, bmop->slots_in, slot_name, BM_VERT);
+ }
+ else if (BPy_BMEdgeSeq_Check(value)) {
+ if (bpy_slot_from_py_elemseq_check((BPy_BMGeneric *)value, bm,
+ BM_EDGE, (slot->slot_subtype.elem & BM_ALL_NOLOOP),
+ opname, slot_name, "element buffer") == -1)
+ {
+ return -1; /* error is set in bpy_slot_from_py_elem_check() */
+ }
+
+ BMO_slot_buffer_from_all(bm, bmop, bmop->slots_in, slot_name, BM_EDGE);
+ }
+ else if (BPy_BMFaceSeq_Check(value)) {
+ if (bpy_slot_from_py_elemseq_check((BPy_BMGeneric *)value, bm,
+ BM_FACE, (slot->slot_subtype.elem & BM_ALL_NOLOOP),
+ opname, slot_name, "element buffer") == -1)
+ {
+ return -1; /* error is set in bpy_slot_from_py_elem_check() */
+ }
+ BMO_slot_buffer_from_all(bm, bmop, bmop->slots_in, slot_name, BM_FACE);
+ }
+
+ else if (BPy_BMElemSeq_Check(value)) {
+ BMIter iter;
+ BMHeader *ele;
+ int tot;
+ unsigned int i;
+
+ if (bpy_slot_from_py_elemseq_check((BPy_BMGeneric *)value, bm,
+ bm_iter_itype_htype_map[((BPy_BMElemSeq *)value)->itype],
+ (slot->slot_subtype.elem & BM_ALL_NOLOOP),
+ opname, slot_name, "element buffer") == -1)
+ {
+ return -1; /* error is set in bpy_slot_from_py_elem_check() */
+ }
+
+ /* this will loop over all elements which is a shame but
+ * we need to know this before alloc */
+ /* calls bpy_bmelemseq_length() */
+ tot = Py_TYPE(value)->tp_as_sequence->sq_length(value);
+
+ BMO_slot_buffer_alloc(bmop, bmop->slots_in, slot_name, tot);
+
+ i = 0;
+ BM_ITER_BPY_BM_SEQ (ele, &iter, ((BPy_BMElemSeq *)value)) {
+ slot->data.buf[i] = ele;
+ i++;
+ }
+ }
+ /* keep this last */
+ else if (PySequence_Check(value)) {
+ BMElem **elem_array = NULL;
+ Py_ssize_t elem_array_len;
+
+ elem_array = BPy_BMElem_PySeq_As_Array(&bm, value, 0, PY_SSIZE_T_MAX,
+ &elem_array_len, (slot->slot_subtype.elem & BM_ALL_NOLOOP),
+ TRUE, TRUE, slot_name);
+
+ /* error is set above */
+ if (elem_array == NULL) {
+ return -1;
+ }
+
+ BMO_slot_buffer_alloc(bmop, bmop->slots_in, slot_name, elem_array_len);
+ memcpy(slot->data.buf, elem_array, sizeof(void *) * elem_array_len);
+ PyMem_FREE(elem_array);
+ }
+ else {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s: keyword \"%.200s\" expected "
+ "a bmesh sequence, list, (htype, flag) pair, not %.200s",
+ opname, slot_name, Py_TYPE(value)->tp_name);
+ return -1;
+ }
+ }
+ break;
+ }
+ case BMO_OP_SLOT_MAPPING:
+ {
+ /* first check types */
+ if (slot->slot_subtype.map != BMO_OP_SLOT_SUBTYPE_MAP_EMPTY) {
+ if (!PyDict_Check(value)) {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s: keyword \"%.200s\" expected "
+ "a dict, not %.200s",
+ opname, slot_name, Py_TYPE(value)->tp_name);
+ return -1;
+ }
+ }
+ else {
+ if (!PySet_Check(value)) {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s: keyword \"%.200s\" expected "
+ "a set, not %.200s",
+ opname, slot_name, Py_TYPE(value)->tp_name);
+ return -1;
+ }
+ }
+
+ switch (slot->slot_subtype.map) {
+ case BMO_OP_SLOT_SUBTYPE_MAP_ELEM:
+ {
+ if (PyDict_Size(value) > 0) {
+ PyObject *arg_key, *arg_value;
+ Py_ssize_t arg_pos = 0;
+ while (PyDict_Next(value, &arg_pos, &arg_key, &arg_value)) {
+ if (bpy_slot_from_py_elem_check((BPy_BMElem *)arg_key, bm, BM_ALL_NOLOOP,
+ opname, slot_name, "invalid key in dict") == -1)
+ {
+ return -1; /* error is set in bpy_slot_from_py_elem_check() */
+ }
+
+ if (bpy_slot_from_py_elem_check((BPy_BMElem *)arg_value, bm, BM_ALL_NOLOOP,
+ opname, slot_name, "invalid value in dict") == -1)
+ {
+ return -1; /* error is set in bpy_slot_from_py_elem_check() */
+ }
+
+ BMO_slot_map_elem_insert(bmop, slot,
+ ((BPy_BMElem *)arg_key)->ele, ((BPy_BMElem *)arg_value)->ele);
+ }
+ }
+ break;
+ }
+ case BMO_OP_SLOT_SUBTYPE_MAP_FLT:
+ {
+ if (PyDict_Size(value) > 0) {
+ PyObject *arg_key, *arg_value;
+ Py_ssize_t arg_pos = 0;
+ while (PyDict_Next(value, &arg_pos, &arg_key, &arg_value)) {
+ float value_f;
+
+ if (bpy_slot_from_py_elem_check((BPy_BMElem *)arg_key, bm, BM_ALL_NOLOOP,
+ opname, slot_name, "invalid key in dict") == -1)
+ {
+ return -1; /* error is set in bpy_slot_from_py_elem_check() */
+ }
+
+ value_f = PyFloat_AsDouble(arg_value);
+
+ if (value_f == -1.0f && PyErr_Occurred()) {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s: keyword \"%.200s\" expected "
+ "a dict with float values, not %.200s",
+ opname, slot_name, Py_TYPE(arg_value)->tp_name);
+ return -1;
+ }
+
+ BMO_slot_map_float_insert(bmop, slot,
+ ((BPy_BMElem *)arg_key)->ele, value_f);
+ }
+ }
+ break;
+ }
+ case BMO_OP_SLOT_SUBTYPE_MAP_INT:
+ {
+ if (PyDict_Size(value) > 0) {
+ PyObject *arg_key, *arg_value;
+ Py_ssize_t arg_pos = 0;
+ while (PyDict_Next(value, &arg_pos, &arg_key, &arg_value)) {
+ int value_i;
+
+ if (bpy_slot_from_py_elem_check((BPy_BMElem *)arg_key, bm, BM_ALL_NOLOOP,
+ opname, slot_name, "invalid key in dict") == -1)
+ {
+ return -1; /* error is set in bpy_slot_from_py_elem_check() */
+ }
+
+ value_i = PyLong_AsLong(arg_value);
+
+ if (value_i == -1 && PyErr_Occurred()) {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s: keyword \"%.200s\" expected "
+ "a dict with int values, not %.200s",
+ opname, slot_name, Py_TYPE(arg_value)->tp_name);
+ return -1;
+ }
+
+ BMO_slot_map_int_insert(bmop, slot,
+ ((BPy_BMElem *)arg_key)->ele, value_i);
+ }
+ }
+ break;
+ }
+ case BMO_OP_SLOT_SUBTYPE_MAP_BOOL:
+ {
+ if (PyDict_Size(value) > 0) {
+ PyObject *arg_key, *arg_value;
+ Py_ssize_t arg_pos = 0;
+ while (PyDict_Next(value, &arg_pos, &arg_key, &arg_value)) {
+ int value_i;
+
+ if (bpy_slot_from_py_elem_check((BPy_BMElem *)arg_key, bm, BM_ALL_NOLOOP,
+ opname, slot_name, "invalid key in dict") == -1)
+ {
+ return -1; /* error is set in bpy_slot_from_py_elem_check() */
+ }
+
+ value_i = PyLong_AsLong(arg_value);
+
+ if (value_i == -1 && PyErr_Occurred()) {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s: keyword \"%.200s\" expected "
+ "a dict with bool values, not %.200s",
+ opname, slot_name, Py_TYPE(arg_value)->tp_name);
+ return -1;
+ }
+
+ BMO_slot_map_bool_insert(bmop, slot,
+ ((BPy_BMElem *)arg_key)->ele, value_i != 0);
+ }
+ }
+ break;
+ }
+ case BMO_OP_SLOT_SUBTYPE_MAP_EMPTY:
+ {
+ if (PySet_Size(value) > 0) {
+ PyObject *arg_key;
+ Py_ssize_t arg_pos = 0;
+ Py_ssize_t arg_hash = 0;
+ while (_PySet_NextEntry(value, &arg_pos, &arg_key, &arg_hash)) {
+
+ if (bpy_slot_from_py_elem_check((BPy_BMElem *)arg_key, bm, BM_ALL_NOLOOP,
+ opname, slot_name, "invalid key in set") == -1)
+ {
+ return -1; /* error is set in bpy_slot_from_py_elem_check() */
+ }
+
+ BMO_slot_map_empty_insert(bmop, slot,
+ ((BPy_BMElem *)arg_key)->ele);
+ }
+ }
+ break;
+ }
+ case BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL:
+ {
+ /* can't convert from these */
+ PyErr_Format(PyExc_NotImplementedError,
+ "This arguments mapping subtype %d is not supported", slot->slot_subtype);
+ return -1;
+ }
+ }
+ }
+ default:
+ /* TODO --- many others */
+ PyErr_Format(PyExc_NotImplementedError,
+ "%.200s: keyword \"%.200s\" type %d not working yet!",
+ opname, slot_name, slot->slot_type);
+ return -1;
+ }
+
+ /* all is well */
+ return 0;
+}
+
+/**
+ * Use for getting return values from an operator thats already executed.
+ *
+ * \note Don't throw any exceptions and should always return a valid (PyObject *).
+ */
+static PyObject* bpy_slot_to_py(BMesh *bm, BMOpSlot *slot)
+{
+ PyObject *item = NULL;
+
+ /* keep switch in same order as above */
+ switch (slot->slot_type) {
+ case BMO_OP_SLOT_BOOL:
+ item = PyBool_FromLong((BMO_SLOT_AS_BOOL(slot)));
+ break;
+ case BMO_OP_SLOT_INT:
+ item = PyLong_FromLong(BMO_SLOT_AS_INT(slot));
+ break;
+ case BMO_OP_SLOT_FLT:
+ item = PyFloat_FromDouble((double)BMO_SLOT_AS_FLOAT(slot));
+ break;
+ case BMO_OP_SLOT_MAT:
+ item = Matrix_CreatePyObject((float *)BMO_SLOT_AS_MATRIX(slot), 4, 4, Py_NEW, NULL);
+ break;
+ case BMO_OP_SLOT_VEC:
+ item = Vector_CreatePyObject(BMO_SLOT_AS_VECTOR(slot), slot->len, Py_NEW, NULL);
+ break;
+ case BMO_OP_SLOT_PTR:
+ BLI_assert(0); /* currently we don't have any pointer return values in use */
+ item = (Py_INCREF(Py_None), Py_None);
+ break;
+ case BMO_OP_SLOT_ELEMENT_BUF:
+ {
+ if (slot->slot_subtype.elem & BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE) {
+ BMHeader *ele = BMO_slot_buffer_get_single(slot);
+ item = ele ? BPy_BMElem_CreatePyObject(bm, ele) : (Py_INCREF(Py_None), Py_None);
+ }
+ else {
+ const int size = slot->len;
+ void **buffer = BMO_SLOT_AS_BUFFER(slot);
+ int j;
+
+ item = PyList_New(size);
+ for (j = 0; j < size; j++) {
+ BMHeader *ele = buffer[j];
+ PyList_SET_ITEM(item, j, BPy_BMElem_CreatePyObject(bm, ele));
+ }
+ }
+ break;
+ }
+ case BMO_OP_SLOT_MAPPING:
+ {
+ GHash *slot_hash = BMO_SLOT_AS_GHASH(slot);
+ GHashIterator hash_iter;
+
+ switch (slot->slot_subtype.map) {
+ case BMO_OP_SLOT_SUBTYPE_MAP_ELEM:
+ {
+ item = PyDict_New();
+ if (slot_hash) {
+ GHASH_ITER (hash_iter, slot_hash) {
+ BMHeader *ele_key = BLI_ghashIterator_getKey(&hash_iter);
+ BMOElemMapping *ele_val = BLI_ghashIterator_getValue(&hash_iter);
+
+ PyObject *py_key = BPy_BMElem_CreatePyObject(bm, ele_key);
+ PyObject *py_val = BPy_BMElem_CreatePyObject(bm, *(void **)BMO_OP_SLOT_MAPPING_DATA(ele_val));
+
+ PyDict_SetItem(item, py_key, py_val);
+ Py_DECREF(py_key);
+ Py_DECREF(py_val);
+ }
+ }
+ break;
+ }
+ case BMO_OP_SLOT_SUBTYPE_MAP_FLT:
+ {
+ item = PyDict_New();
+ if (slot_hash) {
+ GHASH_ITER (hash_iter, slot_hash) {
+ BMHeader *ele_key = BLI_ghashIterator_getKey(&hash_iter);
+ BMOElemMapping *ele_val = BLI_ghashIterator_getValue(&hash_iter);
+
+ PyObject *py_key = BPy_BMElem_CreatePyObject(bm, ele_key);
+ PyObject *py_val = PyFloat_FromDouble(*(float *)BMO_OP_SLOT_MAPPING_DATA(ele_val));
+
+ PyDict_SetItem(item, py_key, py_val);
+ Py_DECREF(py_key);
+ Py_DECREF(py_val);
+ }
+ }
+ break;
+ }
+ case BMO_OP_SLOT_SUBTYPE_MAP_INT:
+ {
+ item = PyDict_New();
+ if (slot_hash) {
+ GHASH_ITER (hash_iter, slot_hash) {
+ BMHeader *ele_key = BLI_ghashIterator_getKey(&hash_iter);
+ BMOElemMapping *ele_val = BLI_ghashIterator_getValue(&hash_iter);
+
+ PyObject *py_key = BPy_BMElem_CreatePyObject(bm, ele_key);
+ PyObject *py_val = PyLong_FromLong(*(int *)BMO_OP_SLOT_MAPPING_DATA(ele_val));
+
+ PyDict_SetItem(item, py_key, py_val);
+ Py_DECREF(py_key);
+ Py_DECREF(py_val);
+ }
+ }
+ break;
+ }
+ case BMO_OP_SLOT_SUBTYPE_MAP_BOOL:
+ {
+ item = PyDict_New();
+ if (slot_hash) {
+ GHASH_ITER (hash_iter, slot_hash) {
+ BMHeader *ele_key = BLI_ghashIterator_getKey(&hash_iter);
+ BMOElemMapping *ele_val = BLI_ghashIterator_getValue(&hash_iter);
+
+ PyObject *py_key = BPy_BMElem_CreatePyObject(bm, ele_key);
+ PyObject *py_val = PyBool_FromLong(*(int *)BMO_OP_SLOT_MAPPING_DATA(ele_val));
+
+ PyDict_SetItem(item, py_key, py_val);
+ Py_DECREF(py_key);
+ Py_DECREF(py_val);
+ }
+ }
+ break;
+ }
+ case BMO_OP_SLOT_SUBTYPE_MAP_EMPTY:
+ {
+ item = PySet_New(NULL);
+ if (slot_hash) {
+ GHASH_ITER (hash_iter, slot_hash) {
+ BMHeader *ele_key = BLI_ghashIterator_getKey(&hash_iter);
+
+ PyObject *py_key = BPy_BMElem_CreatePyObject(bm, ele_key);
+
+ PySet_Add(item, py_key);
+
+ Py_DECREF(py_key);
+ }
+ }
+ break;
+ }
+ case BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL:
+ /* can't convert from these */
+ item = (Py_INCREF(Py_None), Py_None);
+ break;
+ }
+ break;
+ }
+ }
+ BLI_assert(item != NULL);
+
+ return item;
+}
+
+/**
+ * This is the __call__ for bmesh.ops.xxx()
+ */
+PyObject *BPy_BMO_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject *kw)
+{
+ PyObject *ret;
+ BPy_BMesh *py_bm;
+ BMesh *bm;
+
+ BMOperator bmop;
+
+ if ((PyTuple_GET_SIZE(args) == 1) &&
+ (py_bm = (BPy_BMesh *)PyTuple_GET_ITEM(args, 0)) &&
+ (BPy_BMesh_Check(py_bm))
+ )
+ {
+ BPY_BM_CHECK_OBJ(py_bm);
+ bm = py_bm->bm;
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError,
+ "calling a bmesh operator expects a single BMesh (non keyword) "
+ "as the first argument");
+ return NULL;
+ }
+
+ /* TODO - error check this!, though we do the error check on attribute access */
+ /* TODO - make flags optional */
+ BMO_op_init(bm, &bmop, BMO_FLAG_DEFAULTS, self->opname);
+
+ if (kw && PyDict_Size(kw) > 0) {
+ /* setup properties, see bpy_rna.c: pyrna_py_to_prop()
+ * which shares this logic for parsing properties */
+
+ PyObject *key, *value;
+ Py_ssize_t pos = 0;
+ while (PyDict_Next(kw, &pos, &key, &value)) {
+ const char *slot_name = _PyUnicode_AsString(key);
+ BMOpSlot *slot;
+
+ if (!BMO_slot_exists(bmop.slots_in, slot_name)) {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s: keyword \"%.200s\" is invalid for this operator",
+ self->opname, slot_name);
+ BMO_op_finish(bm, &bmop);
+ return NULL;
+ }
+
+ slot = BMO_slot_get(bmop.slots_in, slot_name);
+
+ /* now assign the value */
+ if (bpy_slot_from_py(bm, &bmop, slot, value,
+ self->opname, slot_name) == -1)
+ {
+ BMO_op_finish(bm, &bmop);
+ return NULL;
+ }
+ }
+ }
+
+ BMO_op_exec(bm, &bmop);
+
+ /* from here until the end of the function, no returns, just set 'ret' */
+ if (UNLIKELY(bpy_bm_op_as_py_error(bm) == -1)) {
+ ret = NULL; /* exception raised above */
+ }
+ else if (bmop.slots_out[0].slot_name == NULL) {
+ ret = (Py_INCREF(Py_None), Py_None);
+ }
+ else {
+ /* build return value */
+ int i;
+ ret = PyDict_New();
+
+ for (i = 0; bmop.slots_out[i].slot_name; i++) {
+ // BMOpDefine *op_def = opdefines[bmop.type];
+ // BMOSlotType *slot_type = op_def->slot_types_out[i];
+ BMOpSlot *slot = &bmop.slots_out[i];
+ PyObject *item;
+
+ /* this function doesn't throw exceptions */
+ item = bpy_slot_to_py(bm, slot);
+ if (item == NULL) {
+ item = (Py_INCREF(Py_None), Py_None);
+ }
+
+#if 1
+ /* temp code, strip off '.out' while we keep this convention */
+ {
+ char slot_name_strip[MAX_SLOTNAME];
+ char *ch = strchr(slot->slot_name, '.'); /* can't fail! */
+ int tot = ch - slot->slot_name;
+ BLI_assert(ch != NULL);
+ memcpy(slot_name_strip, slot->slot_name, tot);
+ slot_name_strip[tot] = '\0';
+ PyDict_SetItemString(ret, slot_name_strip, item);
+ }
+#else
+ PyDict_SetItemString(ret, slot->slot_name, item);
+#endif
+ Py_DECREF(item);
+ }
+ }
+
+ BMO_op_finish(bm, &bmop);
+ return ret;
+}
diff --git a/source/blender/python/bmesh/bmesh_py_ops_call.h b/source/blender/python/bmesh/bmesh_py_ops_call.h
new file mode 100644
index 00000000000..d350aec8f7f
--- /dev/null
+++ b/source/blender/python/bmesh/bmesh_py_ops_call.h
@@ -0,0 +1,41 @@
+/*
+ * ***** 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) 2012 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/python/bmesh/bmesh_py_ops_call.h
+ * \ingroup pybmesh
+ */
+
+#ifndef __BMESH_PY_OPS_CALL_H__
+#define __BMESH_PY_OPS_CALL_H__
+
+typedef struct {
+ PyObject_HEAD /* required python macro */
+ const char *opname;
+} BPy_BMeshOpFunc;
+
+
+PyObject *BPy_BMO_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject *kw);
+
+#endif /* __BMESH_PY_OPS_CALL_H__ */
diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c
index ee4528df50d..5db9962e690 100644
--- a/source/blender/python/bmesh/bmesh_py_types.c
+++ b/source/blender/python/bmesh/bmesh_py_types.c
@@ -541,12 +541,30 @@ static PyObject *bpy_bmloop_link_loop_prev_get(BPy_BMLoop *self)
return BPy_BMLoop_CreatePyObject(self->bm, self->l->prev);
}
+PyDoc_STRVAR(bpy_bmloop_link_loop_radial_next_doc,
+"The next loop around the edge (read-only).\n\n:type: :class:`BMLoop`"
+);
+static PyObject *bpy_bmloop_link_loop_radial_next_get(BPy_BMLoop *self)
+{
+ BPY_BM_CHECK_OBJ(self);
+ return BPy_BMLoop_CreatePyObject(self->bm, self->l->radial_next);
+}
+
+PyDoc_STRVAR(bpy_bmloop_link_loop_radial_prev_doc,
+"The previous loop around the edge (read-only).\n\n:type: :class:`BMLoop`"
+);
+static PyObject *bpy_bmloop_link_loop_radial_prev_get(BPy_BMLoop *self)
+{
+ BPY_BM_CHECK_OBJ(self);
+ return BPy_BMLoop_CreatePyObject(self->bm, self->l->radial_prev);
+}
+
/* ElemSeq
* ^^^^^^^ */
/* note: use for bmvert/edge/face/loop seq's use these, not bmelemseq directly */
PyDoc_STRVAR(bpy_bmelemseq_layers_doc,
-"blah blah (read-only).\n\n:type: :class:`BMLayerAccess`"
+"custom-data layers (read-only).\n\n:type: :class:`BMLayerAccess`"
);
static PyObject *bpy_bmelemseq_layers_get(BPy_BMElemSeq *self, void *htype)
{
@@ -555,6 +573,46 @@ static PyObject *bpy_bmelemseq_layers_get(BPy_BMElemSeq *self, void *htype)
return BPy_BMLayerAccess_CreatePyObject(self->bm, GET_INT_FROM_POINTER(htype));
}
+/* FaceSeq
+ * ^^^^^^^ */
+
+PyDoc_STRVAR(bpy_bmfaceseq_active_doc,
+"active face.\n\n:type: :class:`BMFace` or None"
+);
+static PyObject *bpy_bmfaceseq_active_get(BPy_BMElemSeq *self, void *UNUSED(closure))
+{
+ BMesh *bm = self->bm;
+ BPY_BM_CHECK_OBJ(self);
+
+ if (bm->act_face) {
+ return BPy_BMElem_CreatePyObject(bm, (BMHeader *)bm->act_face);
+ }
+ else {
+ Py_RETURN_NONE;
+ }
+}
+
+static int bpy_bmfaceseq_active_set(BPy_BMElem *self, PyObject *value, void *UNUSED(closure))
+{
+ BMesh *bm = self->bm;
+ if (value == Py_None) {
+ bm->act_face = NULL;
+ return 0;
+ }
+ else if (BPy_BMFace_Check(value)) {
+ BPY_BM_CHECK_SOURCE_INT(value, bm, "faces.active = f");
+
+ bm->act_face = ((BPy_BMFace *)value)->f;
+ return 0;
+ }
+ else {
+ PyErr_Format(PyExc_TypeError,
+ "faces.active = f: expected BMFace or None, not %.200s",
+ Py_TYPE(value)->tp_name);
+ return -1;
+ }
+}
+
static PyGetSetDef bpy_bmesh_getseters[] = {
{(char *)"verts", (getter)bpy_bmvertseq_get, (setter)NULL, (char *)bpy_bmvertseq_doc, NULL},
{(char *)"edges", (getter)bpy_bmedgeseq_get, (setter)NULL, (char *)bpy_bmedgeseq_doc, NULL},
@@ -659,6 +717,8 @@ static PyGetSetDef bpy_bmloop_getseters[] = {
{(char *)"link_loops", (getter)bpy_bmelemseq_elem_get, (setter)NULL, (char *)bpy_bmloops_link_loops_doc, (void *)BM_LOOPS_OF_LOOP},
{(char *)"link_loop_next", (getter)bpy_bmloop_link_loop_next_get, (setter)NULL, (char *)bpy_bmloop_link_loop_next_doc, NULL},
{(char *)"link_loop_prev", (getter)bpy_bmloop_link_loop_prev_get, (setter)NULL, (char *)bpy_bmloop_link_loop_prev_doc, NULL},
+ {(char *)"link_loop_radial_next", (getter)bpy_bmloop_link_loop_radial_next_get, (setter)NULL, (char *)bpy_bmloop_link_loop_radial_next_doc, NULL},
+ {(char *)"link_loop_radial_prev", (getter)bpy_bmloop_link_loop_radial_prev_get, (setter)NULL, (char *)bpy_bmloop_link_loop_radial_prev_doc, NULL},
/* readonly checks */
{(char *)"is_valid", (getter)bpy_bm_is_valid_get, (setter)NULL, (char *)bpy_bm_is_valid_doc, NULL},
@@ -668,7 +728,7 @@ static PyGetSetDef bpy_bmloop_getseters[] = {
static PyGetSetDef bpy_bmvertseq_getseters[] = {
{(char *)"layers", (getter)bpy_bmelemseq_layers_get, (setter)NULL, (char *)bpy_bmelemseq_layers_doc, (void *)BM_VERT},
- {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
+ {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
};
static PyGetSetDef bpy_bmedgeseq_getseters[] = {
{(char *)"layers", (getter)bpy_bmelemseq_layers_get, (setter)NULL, (char *)bpy_bmelemseq_layers_doc, (void *)BM_EDGE},
@@ -676,6 +736,8 @@ static PyGetSetDef bpy_bmedgeseq_getseters[] = {
};
static PyGetSetDef bpy_bmfaceseq_getseters[] = {
{(char *)"layers", (getter)bpy_bmelemseq_layers_get, (setter)NULL, (char *)bpy_bmelemseq_layers_doc, (void *)BM_FACE},
+ /* face only */
+ {(char *)"active", (getter)bpy_bmfaceseq_active_get, (setter)bpy_bmfaceseq_active_set, (char *)bpy_bmfaceseq_active_doc, NULL},
{NULL, NULL, NULL, NULL, NULL} /* Sentinel */
};
static PyGetSetDef bpy_bmloopseq_getseters[] = {
@@ -1232,13 +1294,7 @@ static PyObject *bpy_bmvert_copy_from_face_interp(BPy_BMVert *self, PyObject *ar
else {
BMesh *bm = self->bm;
- BPY_BM_CHECK_OBJ(py_face);
-
- if (py_face->bm != bm) {
- PyErr_SetString(PyExc_ValueError,
- "BMVert.copy_from_face_interp(face): face is from another mesh");
- return NULL;
- }
+ BPY_BM_CHECK_SOURCE_OBJ(py_face, bm, "copy_from_face_interp()");
BM_vert_interp_from_face(bm, self->v, py_face->f);
@@ -1372,13 +1428,7 @@ static PyObject *bpy_bmedge_other_vert(BPy_BMEdge *self, BPy_BMVert *value)
return NULL;
}
- BPY_BM_CHECK_OBJ(value);
-
- if (self->bm != value->bm) {
- PyErr_SetString(PyExc_ValueError,
- "BMEdge.other_vert(vert): vert is from another mesh");
- return NULL;
- }
+ BPY_BM_CHECK_SOURCE_OBJ(value, self->bm, "BMEdge.other_vert(vert)");
other = BM_edge_other_vert(self->e, value->v);
@@ -1432,13 +1482,7 @@ static PyObject *bpy_bmface_copy_from_face_interp(BPy_BMFace *self, PyObject *ar
else {
BMesh *bm = self->bm;
- BPY_BM_CHECK_OBJ(py_face);
-
- if (py_face->bm != bm) {
- PyErr_SetString(PyExc_ValueError,
- "BMFace.copy_from_face_interp(face): face is from another mesh");
- return NULL;
- }
+ BPY_BM_CHECK_SOURCE_OBJ(py_face, bm, "BMFace.copy_from_face_interp(face)");
BM_face_interp_from_face(bm, self->f, py_face->f);
@@ -1604,13 +1648,7 @@ static PyObject *bpy_bmloop_copy_from_face_interp(BPy_BMLoop *self, PyObject *ar
else {
BMesh *bm = self->bm;
- BPY_BM_CHECK_OBJ(py_face);
-
- if (py_face->bm != bm) {
- PyErr_SetString(PyExc_ValueError,
- "BMLoop.copy_from_face_interp(face): face is from another mesh");
- return NULL;
- }
+ BPY_BM_CHECK_SOURCE_OBJ(py_face, bm, "BMLoop.copy_from_face_interp(face)");
BM_loop_interp_from_face(bm, self->l, py_face->f, do_vertex, do_multires);
@@ -1708,7 +1746,7 @@ static PyObject *bpy_bmvertseq_new(BPy_BMElemSeq *self, PyObject *args)
return NULL;
}
- v = BM_vert_create(bm, co, NULL);
+ v = BM_vert_create(bm, co, NULL, 0);
if (v == NULL) {
PyErr_SetString(PyExc_ValueError,
@@ -1777,7 +1815,7 @@ static PyObject *bpy_bmedgeseq_new(BPy_BMElemSeq *self, PyObject *args)
goto cleanup;
}
- e = BM_edge_create(bm, vert_array[0], vert_array[1], NULL, FALSE);
+ e = BM_edge_create(bm, vert_array[0], vert_array[1], NULL, 0);
if (e == NULL) {
PyErr_SetString(PyExc_ValueError,
@@ -1863,10 +1901,10 @@ static PyObject *bpy_bmfaceseq_new(BPy_BMElemSeq *self, PyObject *args)
/* ensure edges */
for (i = vert_seq_len - 1, i_next = 0; i_next < vert_seq_len; (i = i_next++)) {
- edge_array[i] = BM_edge_create(bm, vert_array[i], vert_array[i_next], NULL, TRUE);
+ edge_array[i] = BM_edge_create(bm, vert_array[i], vert_array[i_next], NULL, BM_CREATE_NO_DOUBLE);
}
- f_new = BM_face_create(bm, vert_array, edge_array, vert_seq_len, FALSE);
+ f_new = BM_face_create(bm, vert_array, edge_array, vert_seq_len, 0);
if (UNLIKELY(f_new == NULL)) {
PyErr_SetString(PyExc_ValueError,
@@ -1906,13 +1944,7 @@ static PyObject *bpy_bmvertseq_remove(BPy_BMElemSeq *self, BPy_BMVert *value)
else {
BMesh *bm = self->bm;
- BPY_BM_CHECK_OBJ(value);
-
- if (value->bm != bm) {
- PyErr_SetString(PyExc_ValueError,
- "verts.remove(vert): vert is from another mesh");
- return NULL;
- }
+ BPY_BM_CHECK_SOURCE_OBJ(value, bm, "verts.remove(vert)");
BM_vert_kill(bm, value->v);
bpy_bm_generic_invalidate((BPy_BMGeneric *)value);
@@ -1936,13 +1968,7 @@ static PyObject *bpy_bmedgeseq_remove(BPy_BMElemSeq *self, BPy_BMEdge *value)
else {
BMesh *bm = self->bm;
- BPY_BM_CHECK_OBJ(value);
-
- if (value->bm != bm) {
- PyErr_SetString(PyExc_ValueError,
- "edges.remove(edge): edge is from another mesh");
- return NULL;
- }
+ BPY_BM_CHECK_SOURCE_OBJ(value, bm, "edges.remove(edges)");
BM_edge_kill(bm, value->e);
bpy_bm_generic_invalidate((BPy_BMGeneric *)value);
@@ -1966,13 +1992,7 @@ static PyObject *bpy_bmfaceseq_remove(BPy_BMElemSeq *self, BPy_BMFace *value)
else {
BMesh *bm = self->bm;
- BPY_BM_CHECK_OBJ(value);
-
- if (value->bm != bm) {
- PyErr_SetString(PyExc_ValueError,
- "faces.remove(face): face is from another mesh");
- return NULL;
- }
+ BPY_BM_CHECK_SOURCE_OBJ(value, bm, "faces.remove(face)");
BM_face_kill(bm, value->f);
bpy_bm_generic_invalidate((BPy_BMGeneric *)value);
@@ -3032,7 +3052,8 @@ void BPy_BM_init_types(void)
BPy_BMLoopSeq_Type.tp_methods = bpy_bmloopseq_methods;
BPy_BMIter_Type.tp_methods = NULL;
-
+ /*BPy_BMElem_Check() uses bpy_bm_elem_hash() to check types.
+ * if this changes update the macro */
BPy_BMesh_Type.tp_hash = bpy_bm_hash;
BPy_BMVert_Type.tp_hash = bpy_bm_elem_hash;
BPy_BMEdge_Type.tp_hash = bpy_bm_elem_hash;
@@ -3400,6 +3421,21 @@ int bpy_bm_generic_valid_check(BPy_BMGeneric *self)
}
}
+int bpy_bm_generic_valid_check_source(BPy_BMGeneric *self, BMesh *bm_source, const char *error_prefix)
+{
+ int ret = bpy_bm_generic_valid_check(self);
+ if (LIKELY(ret == 0)) {
+ if (UNLIKELY(self->bm != bm_source)) {
+ /* could give more info here */
+ PyErr_Format(PyExc_ValueError,
+ "%.200s: BMesh data of type %.200s is from another mesh",
+ error_prefix, Py_TYPE(self)->tp_name);
+ ret = -1;
+ }
+ }
+ return ret;
+}
+
void bpy_bm_generic_invalidate(BPy_BMGeneric *self)
{
self->bm = NULL;
diff --git a/source/blender/python/bmesh/bmesh_py_types.h b/source/blender/python/bmesh/bmesh_py_types.h
index df5231a4b1b..d15918a3c11 100644
--- a/source/blender/python/bmesh/bmesh_py_types.h
+++ b/source/blender/python/bmesh/bmesh_py_types.h
@@ -55,6 +55,8 @@ extern PyTypeObject BPy_BMIter_Type;
#define BPy_BMFaceSeq_Check(v) (Py_TYPE(v) == &BPy_BMFaceSeq_Type)
#define BPy_BMLoopSeq_Check(v) (Py_TYPE(v) == &BPy_BMLoopSeq_Type)
#define BPy_BMIter_Check(v) (Py_TYPE(v) == &BPy_BMIter_Type)
+/* trick since we know they share a hash function */
+#define BPy_BMElem_Check(v) (Py_TYPE(v)->tp_hash == BPy_BMVert_Type.tp_hash)
/* cast from _any_ bmesh type - they all have BMesh first */
typedef struct BPy_BMGeneric {
@@ -156,9 +158,6 @@ PyObject *BPy_BMIter_CreatePyObject(BMesh *bm);
PyObject *BPy_BMElem_CreatePyObject(BMesh *bm, BMHeader *ele); /* just checks type and creates v/e/f/l */
-int bpy_bm_generic_valid_check(BPy_BMGeneric *self);
-void bpy_bm_generic_invalidate(BPy_BMGeneric *self);
-
void *BPy_BMElem_PySeq_As_Array(BMesh **r_bm, PyObject *seq, Py_ssize_t min, Py_ssize_t max, Py_ssize_t *r_size,
const char htype,
const char do_unique_check, const char do_bm_check,
@@ -169,9 +168,20 @@ int BPy_BMElem_CheckHType(PyTypeObject *type, const char htype);
char *BPy_BMElem_StringFromHType_ex(const char htype, char ret[32]);
char *BPy_BMElem_StringFromHType(const char htype);
-
-#define BPY_BM_CHECK_OBJ(obj) if (UNLIKELY(bpy_bm_generic_valid_check((BPy_BMGeneric *)obj) == -1)) { return NULL; } (void)0
-#define BPY_BM_CHECK_INT(obj) if (UNLIKELY(bpy_bm_generic_valid_check((BPy_BMGeneric *)obj) == -1)) { return -1; } (void)0
+void bpy_bm_generic_invalidate(BPy_BMGeneric *self);
+int bpy_bm_generic_valid_check(BPy_BMGeneric *self);
+int bpy_bm_generic_valid_check_source(BPy_BMGeneric *self, BMesh *bm_source, const char *error_prefix);
+
+#define BPY_BM_CHECK_OBJ(obj) \
+ if (UNLIKELY(bpy_bm_generic_valid_check((BPy_BMGeneric *)obj) == -1)) { return NULL; } (void)0
+#define BPY_BM_CHECK_INT(obj) \
+ if (UNLIKELY(bpy_bm_generic_valid_check((BPy_BMGeneric *)obj) == -1)) { return -1; } (void)0
+
+/* macros like BPY_BM_CHECK_OBJ/BPY_BM_CHECK_INT that ensure we're from the right BMesh */
+#define BPY_BM_CHECK_SOURCE_OBJ(obj, bm, errmsg) \
+ if (UNLIKELY(bpy_bm_generic_valid_check_source((BPy_BMGeneric *)obj, bm, errmsg) == -1)) { return NULL; } (void)0
+#define BPY_BM_CHECK_SOURCE_INT(obj, bm, errmsg) \
+ if (UNLIKELY(bpy_bm_generic_valid_check_source((BPy_BMGeneric *)obj, bm, errmsg) == -1)) { return -1; } (void)0
#define BPY_BM_IS_VALID(obj) (LIKELY((obj)->bm != NULL))
diff --git a/source/blender/python/bmesh/bmesh_py_types_customdata.c b/source/blender/python/bmesh/bmesh_py_types_customdata.c
index 14132d08fe6..fd31f3c40cc 100644
--- a/source/blender/python/bmesh/bmesh_py_types_customdata.c
+++ b/source/blender/python/bmesh/bmesh_py_types_customdata.c
@@ -262,16 +262,10 @@ static PyObject *bpy_bmlayeritem_copy_from(BPy_BMLayerItem *self, BPy_BMLayerIte
}
BPY_BM_CHECK_OBJ(self);
- BPY_BM_CHECK_OBJ(value);
-
- if (self->bm != value->bm) {
- PyErr_SetString(PyExc_ValueError,
- "layer.copy_from(): layer is from another mesh");
- return NULL;
- }
+ BPY_BM_CHECK_SOURCE_OBJ(value, self->bm, "layer.copy_from()");
- else if ((self->htype != value->htype) ||
- (self->type != value->type))
+ if ((self->htype != value->htype) ||
+ (self->type != value->type))
{
PyErr_SetString(PyExc_ValueError,
"layer.copy_from(other): layer type mismatch");
diff --git a/source/blender/python/bmesh/bmesh_py_types_select.c b/source/blender/python/bmesh/bmesh_py_types_select.c
index 2ff731559d1..dfcfbeb0ab5 100644
--- a/source/blender/python/bmesh/bmesh_py_types_select.c
+++ b/source/blender/python/bmesh/bmesh_py_types_select.c
@@ -114,13 +114,7 @@ static PyObject *bpy_bmeditselseq_add(BPy_BMEditSelSeq *self, BPy_BMElem *value)
return NULL;
}
- BPY_BM_CHECK_OBJ(value);
-
- if (self->bm != value->bm) {
- PyErr_SetString(PyExc_ValueError,
- "Element is not from this mesh");
- return NULL;
- }
+ BPY_BM_CHECK_SOURCE_OBJ(value, self->bm, "select_history.add()");
BM_select_history_store(self->bm, value->ele);
@@ -145,11 +139,9 @@ static PyObject *bpy_bmeditselseq_remove(BPy_BMEditSelSeq *self, BPy_BMElem *val
return NULL;
}
- BPY_BM_CHECK_OBJ(value);
+ BPY_BM_CHECK_SOURCE_OBJ(value, self->bm, "select_history.remove()");
- if ((self->bm != value->bm) ||
- (BM_select_history_remove(self->bm, value->ele) == FALSE))
- {
+ if (BM_select_history_remove(self->bm, value->ele) == FALSE) {
PyErr_SetString(PyExc_ValueError,
"Element not found in selection history");
return NULL;
diff --git a/source/blender/python/bmesh/bmesh_py_utils.c b/source/blender/python/bmesh/bmesh_py_utils.c
index b70df53aff0..f85c3347104 100644
--- a/source/blender/python/bmesh/bmesh_py_utils.c
+++ b/source/blender/python/bmesh/bmesh_py_utils.c
@@ -557,16 +557,10 @@ static PyObject *bpy_bm_utils_face_vert_separate(PyObject *UNUSED(self), PyObjec
return NULL;
}
- BPY_BM_CHECK_OBJ(py_face);
- BPY_BM_CHECK_OBJ(py_vert);
-
bm = py_face->bm;
- if (bm != py_vert->bm) {
- PyErr_SetString(PyExc_ValueError,
- "mesh elements are from different meshes");
- return NULL;
- }
+ BPY_BM_CHECK_OBJ(py_face);
+ BPY_BM_CHECK_SOURCE_OBJ(py_vert, bm, "face_vert_separate()");
l = BM_face_vert_share_loop(py_face->f, py_vert->v);
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index 6993e1baab4..f87478bb663 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -1708,8 +1708,8 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
totface= psmd->dm->getNumTessFaces(psmd->dm);
index_mf_to_mpoly = psmd->dm->getTessFaceDataArray(psmd->dm, CD_ORIGINDEX);
index_mp_to_orig = psmd->dm->getPolyDataArray(psmd->dm, CD_ORIGINDEX);
- if ((index_mf_to_mpoly && index_mp_to_orig) == FALSE) {
- index_mf_to_mpoly = index_mp_to_orig = NULL;
+ if (index_mf_to_mpoly == NULL) {
+ index_mp_to_orig = NULL;
}
for (a=0; a<totface; a++)
strandbuf->totbound = max_ii(strandbuf->totbound, (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, a): a);
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index e35e3edfa33..1037542759f 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -360,8 +360,9 @@ void WM_jobs_start(struct wmWindowManager *wm, struct wmJob *);
void WM_jobs_stop(struct wmWindowManager *wm, void *owner, void *startjob);
void WM_jobs_kill(struct wmWindowManager *wm, void *owner, void (*)(void *, short int *, short int *, float *));
void WM_jobs_kill_all(struct wmWindowManager *wm);
- void WM_jobs_kill_all_except(struct wmWindowManager *wm, void *owner);
-
+void WM_jobs_kill_all_except(struct wmWindowManager *wm, void *owner);
+void WM_jobs_kill_type(struct wmWindowManager *wm, int job_type);
+
int WM_jobs_has_running(struct wmWindowManager *wm);
/* clipboard */
diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h
index 1d8949292ce..c88011aab13 100644
--- a/source/blender/windowmanager/WM_types.h
+++ b/source/blender/windowmanager/WM_types.h
@@ -301,6 +301,7 @@ typedef struct wmNotifier {
/* NC_MATERIAL Material */
#define ND_SHADING (30<<16)
#define ND_SHADING_DRAW (31<<16)
+#define ND_SHADING_LINKS (32<<16)
/* NC_LAMP Lamp */
#define ND_LIGHTING (40<<16)
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index b3c9cfbc79e..c0e3b19c716 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -135,6 +135,7 @@ static int wm_test_duplicate_notifier(wmWindowManager *wm, unsigned int type, vo
/* XXX: in future, which notifiers to send to other windows? */
void WM_event_add_notifier(const bContext *C, unsigned int type, void *reference)
{
+ ARegion *ar;
wmNotifier *note = MEM_callocN(sizeof(wmNotifier), "notifier");
note->wm = CTX_wm_manager(C);
@@ -142,8 +143,9 @@ void WM_event_add_notifier(const bContext *C, unsigned int type, void *reference
note->window = CTX_wm_window(C);
- if (CTX_wm_region(C))
- note->swinid = CTX_wm_region(C)->swinid;
+ ar = CTX_wm_region(C);
+ if (ar)
+ note->swinid = ar->swinid;
note->category = type & NOTE_CATEGORY;
note->data = type & NOTE_DATA;
diff --git a/source/blender/windowmanager/intern/wm_gesture.c b/source/blender/windowmanager/intern/wm_gesture.c
index b3ffb80243a..a80386e9860 100644
--- a/source/blender/windowmanager/intern/wm_gesture.c
+++ b/source/blender/windowmanager/intern/wm_gesture.c
@@ -255,7 +255,7 @@ static void draw_filled_lasso(wmGesture *gt)
if (sf_vert_first) {
const float zvec[3] = {0.0f, 0.0f, 1.0f};
BLI_scanfill_edge_add(&sf_ctx, sf_vert_first, sf_vert);
- BLI_scanfill_calc_ex(&sf_ctx, FALSE, zvec);
+ BLI_scanfill_calc_ex(&sf_ctx, BLI_SCANFILL_CALC_REMOVE_DOUBLES, zvec);
glEnable(GL_BLEND);
glColor4f(1.0, 1.0, 1.0, 0.05);
diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c
index c9f0bbffc63..1b8bcd51564 100644
--- a/source/blender/windowmanager/intern/wm_init_exit.c
+++ b/source/blender/windowmanager/intern/wm_init_exit.c
@@ -183,7 +183,7 @@ void WM_init(bContext *C, int argc, const char **argv)
GPU_extensions_init();
GPU_set_mipmap(!(U.gameflags & USER_DISABLE_MIPMAP));
GPU_set_anisotropic(U.anisotropic_filter);
- GPU_set_gpu_mipmapping(U.use_gpu_mipmap);
+ GPU_set_gpu_mipmapping();
UI_init();
}
diff --git a/source/blender/windowmanager/intern/wm_jobs.c b/source/blender/windowmanager/intern/wm_jobs.c
index 7481c01d72b..3c3e2c0feaa 100644
--- a/source/blender/windowmanager/intern/wm_jobs.c
+++ b/source/blender/windowmanager/intern/wm_jobs.c
@@ -416,6 +416,18 @@ void WM_jobs_kill_all_except(wmWindowManager *wm, void *owner)
}
+void WM_jobs_kill_type(struct wmWindowManager *wm, int job_type)
+{
+ wmJob *wm_job, *next_job;
+
+ for (wm_job = wm->jobs.first; wm_job; wm_job = next_job) {
+ next_job = wm_job->next;
+
+ if (wm_job->job_type == job_type)
+ wm_jobs_kill_job(wm, wm_job);
+ }
+}
+
/* signal job(s) from this owner or callback to stop, timer is required to get handled */
void WM_jobs_stop(wmWindowManager *wm, void *owner, void *startjob)
{
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 84cfe791bce..80ceb5700e5 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -793,7 +793,7 @@ static uiBlock *wm_enum_search_menu(bContext *C, ARegion *ar, void *arg_op)
uiButSetSearchFunc(but, operator_enum_search_cb, op->type, operator_enum_call_cb, NULL);
/* fake button, it holds space for search items */
- uiDefBut(block, LABEL, 0, "", 10, 10 - uiSearchBoxhHeight(), 9 * UI_UNIT_X, uiSearchBoxhHeight(), NULL, 0, 0, 0, 0, NULL);
+ uiDefBut(block, LABEL, 0, "", 10, 10 - uiSearchBoxHeight(), uiSearchBoxWidth(), uiSearchBoxHeight(), NULL, 0, 0, 0, 0, NULL);
uiPopupBoundsBlock(block, 6, 0, -UI_UNIT_Y); /* move it downwards, mouse over button */
uiEndBlock(C, block);
@@ -1025,6 +1025,23 @@ wmOperator *WM_operator_last_redo(const bContext *C)
return op;
}
+static void wm_block_redo_cb(bContext *C, void *arg_op, int UNUSED(arg_event))
+{
+ wmOperator *op = arg_op;
+
+ if (op == WM_operator_last_redo(C)) {
+ /* operator was already executed once? undo & repeat */
+ ED_undo_operator_repeat(C, op);
+ }
+ else {
+ /* operator not executed yet, call it */
+ ED_undo_push_op(C, op);
+ wm_operator_register(C, op);
+
+ WM_operator_repeat(C, op);
+ }
+}
+
static uiBlock *wm_block_create_redo(bContext *C, ARegion *ar, void *arg_op)
{
wmOperator *op = arg_op;
@@ -1032,7 +1049,6 @@ static uiBlock *wm_block_create_redo(bContext *C, ARegion *ar, void *arg_op)
uiLayout *layout;
uiStyle *style = UI_GetStyle();
int width = 300;
-
block = uiBeginBlock(C, ar, __func__, UI_EMBOSS);
uiBlockClearFlag(block, UI_BLOCK_LOOP);
@@ -1042,11 +1058,12 @@ static uiBlock *wm_block_create_redo(bContext *C, ARegion *ar, void *arg_op)
* ui_apply_but_funcs_after calls ED_undo_operator_repeate_cb and crashes */
assert(op->type->flag & OPTYPE_REGISTER);
- uiBlockSetHandleFunc(block, ED_undo_operator_repeat_cb_evt, arg_op);
+ uiBlockSetHandleFunc(block, wm_block_redo_cb, arg_op);
layout = uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, width, UI_UNIT_Y, style);
- if (!WM_operator_check_ui_enabled(C, op->type->name))
- uiLayoutSetEnabled(layout, FALSE);
+ if (op == WM_operator_last_redo(C))
+ if (!WM_operator_check_ui_enabled(C, op->type->name))
+ uiLayoutSetEnabled(layout, FALSE);
if (op->type->flag & OPTYPE_MACRO) {
for (op = op->macro.first; op; op = op->next) {
@@ -1058,7 +1075,6 @@ static uiBlock *wm_block_create_redo(bContext *C, ARegion *ar, void *arg_op)
uiLayoutOperatorButs(C, layout, op, NULL, 'H', UI_LAYOUT_OP_SHOW_TITLE);
}
-
uiPopupBoundsBlock(block, 4, 0, 0);
uiEndBlock(C, block);
@@ -1207,22 +1223,21 @@ int WM_operator_ui_popup(bContext *C, wmOperator *op, int width, int height)
* \note operator menu needs undo flag enabled , for redo callback */
static int wm_operator_props_popup_ex(bContext *C, wmOperator *op, const int do_call)
{
-
if ((op->type->flag & OPTYPE_REGISTER) == 0) {
BKE_reportf(op->reports, RPT_ERROR,
"Operator '%s' does not have register enabled, incorrect invoke function", op->type->idname);
return OPERATOR_CANCELLED;
}
- ED_undo_push_op(C, op);
-
- wm_operator_register(C, op);
+ /* if we don't have global undo, we can't do undo push for automatic redo,
+ * so we require manual OK clicking in this popup */
+ if (!(U.uiflag & USER_GLOBALUNDO))
+ return WM_operator_props_dialog_popup(C, op, 300, UI_UNIT_Y);
uiPupBlock(C, wm_block_create_redo, op);
- if (do_call) {
- WM_operator_repeat(C, op);
- }
+ if (do_call)
+ wm_block_redo_cb(C, op, 0);
return OPERATOR_RUNNING_MODAL;
}
@@ -1566,7 +1581,7 @@ static uiBlock *wm_block_search_menu(bContext *C, ARegion *ar, void *UNUSED(arg_
uiButSetSearchFunc(but, operator_search_cb, NULL, operator_call_cb, NULL);
/* fake button, it holds space for search items */
- uiDefBut(block, LABEL, 0, "", 10, 10 - uiSearchBoxhHeight(), 9 * UI_UNIT_X, uiSearchBoxhHeight(), NULL, 0, 0, 0, 0, NULL);
+ uiDefBut(block, LABEL, 0, "", 10, 10 - uiSearchBoxHeight(), uiSearchBoxWidth(), uiSearchBoxHeight(), NULL, 0, 0, 0, 0, NULL);
uiPopupBoundsBlock(block, 6, 0, -UI_UNIT_Y); /* move it downwards, mouse over button */
uiEndBlock(C, block);
diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt
index 8e86ecbff93..67bf9599baf 100644
--- a/source/creator/CMakeLists.txt
+++ b/source/creator/CMakeLists.txt
@@ -472,14 +472,17 @@ elseif(WIN32)
if(WITH_PYTHON)
set_lib_path(PYLIB "python")
+
+ STRING(REPLACE "." "" _PYTHON_VERSION_NO_DOTS ${PYTHON_VERSION})
+
install(
- FILES ${PYLIB}/lib/python32.dll
+ FILES ${PYLIB}/lib/python${_PYTHON_VERSION_NO_DOTS}.dll
DESTINATION ${TARGETDIR}
CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel
)
install(
- FILES ${PYLIB}/lib/python32_d.dll
+ FILES ${PYLIB}/lib/python${_PYTHON_VERSION_NO_DOTS}_d.dll
DESTINATION ${TARGETDIR}
CONFIGURATIONS Debug
)
@@ -503,10 +506,10 @@ elseif(WIN32)
"
if(\"\${CMAKE_INSTALL_CONFIG_NAME}\" STREQUAL \"Debug\")
execute_process(COMMAND \"${CMAKE_COMMAND}\" -E chdir \"${TARGETDIR_VER}/python/lib\"
- \"${CMAKE_COMMAND}\" -E tar xzfv \"${LIBDIR}/release/python32_d.tar.gz\")
+ \"${CMAKE_COMMAND}\" -E tar xzfv \"${LIBDIR}/release/python${_PYTHON_VERSION_NO_DOTS}_d.tar.gz\")
else()
execute_process(COMMAND \"${CMAKE_COMMAND}\" -E chdir \"${TARGETDIR_VER}/python/lib\"
- \"${CMAKE_COMMAND}\" -E tar xzfv \"${LIBDIR}/release/python32.tar.gz\")
+ \"${CMAKE_COMMAND}\" -E tar xzfv \"${LIBDIR}/release/python${_PYTHON_VERSION_NO_DOTS}.tar.gz\")
endif()
"
)
@@ -514,6 +517,8 @@ elseif(WIN32)
# doesnt work, todo
# install(CODE "execute_process(COMMAND find ${TARGETDIR}/${BLENDER_VERSION}/python/lib/ -name '*.so' -exec strip -s {} '\;')")
endif()
+
+ unset(_PYTHON_VERSION_NO_DOTS)
endif()
if(CMAKE_CL_64)
diff --git a/source/creator/blender.map b/source/creator/blender.map
index dc7bc3151e8..928d0c2d904 100644
--- a/source/creator/blender.map
+++ b/source/creator/blender.map
@@ -1,11 +1,16 @@
-/* on Linux we exclude LLVM symbols, they conflict with Mesa llvmpipe */
+/* on Linux we exclude LLVM symbols, they conflict with Mesa llvmpipe
+ * we also keep boost's symbols local, since some python modules could
+ * be using boost as well (mainly that's for lux render)
+ */
{
global:
*;
+ *_boost*;
local:
*llvm*;
*LLVM*;
+ *boost*;
};
diff --git a/source/creator/creator.c b/source/creator/creator.c
index 26162051147..80b9ca89420 100644
--- a/source/creator/creator.c
+++ b/source/creator/creator.c
@@ -1081,7 +1081,7 @@ static void setupArguments(bContext *C, bArgs *ba, SYS_SystemHandle *syshandle)
"\n\t\t-f <fps> <fps-base>\t\tSpecify FPS to start with"
"\n\t\t-j <frame>\tSet frame step to <frame>"
"\n\t\t-s <frame>\tPlay from <frame>"
- "\n\t\t-j <frame>\tPlay until <frame>";
+ "\n\t\t-e <frame>\tPlay until <frame>";
static char game_doc[] = "Game Engine specific options"
"\n\t-g fixedtime\t\tRun on 50 hertz without dropping frames"
diff --git a/source/creator/osx_locals.map b/source/creator/osx_locals.map
new file mode 100644
index 00000000000..c3dd8b62792
--- /dev/null
+++ b/source/creator/osx_locals.map
@@ -0,0 +1,3 @@
+## The symbols will be treated as if they were marked as __private_extern__
+## (aka visibility=hidden) and will not be global in the output file
+*boost*
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.cpp b/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.cpp
index f4e325eabb8..19ba46ed6d7 100644
--- a/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.cpp
+++ b/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.cpp
@@ -105,7 +105,7 @@ bool KX_BlenderKeyboardDevice::ConvertBlenderEvent(unsigned short incode,short v
{
int previousTable = 1-m_currentTable;
- if (val == KM_PRESS)
+ if (val == KM_PRESS || val == KM_DBL_CLICK)
{
if (kxevent == KX_KetsjiEngine::GetExitKey() && val != 0 && !m_hookesc)
result = true;
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderMouseDevice.cpp b/source/gameengine/BlenderRoutines/KX_BlenderMouseDevice.cpp
index aa2392ded08..8d90eacd27f 100644
--- a/source/gameengine/BlenderRoutines/KX_BlenderMouseDevice.cpp
+++ b/source/gameengine/BlenderRoutines/KX_BlenderMouseDevice.cpp
@@ -121,7 +121,7 @@ bool KX_BlenderMouseDevice::ConvertBlenderEvent(unsigned short incode,short val)
// only process it, if it's a key
if (kxevent > KX_BEGINMOUSE && kxevent < KX_ENDMOUSEBUTTONS)
{
- if (val == KM_PRESS)
+ if (val == KM_PRESS || val == KM_DBL_CLICK)
{
m_eventStatusTables[m_currentTable][kxevent].m_eventval = val ; //???
diff --git a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
index 4451c78b99c..475e139bfcc 100644
--- a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
+++ b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
@@ -756,6 +756,7 @@ int main(int argc, char** argv)
}
GPU_set_anisotropic(U.anisotropic_filter);
+ GPU_set_gpu_mipmapping();
// Create the system
if (GHOST_ISystem::createSystem() == GHOST_kSuccess)
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
index 8d587cf39f6..6c6ce94d8d5 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
@@ -1507,8 +1507,8 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, DerivedMesh* dm,
/* double lookup */
const int *index_mf_to_mpoly = (const int *)dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
const int *index_mp_to_orig = (const int *)dm->getPolyDataArray(dm, CD_ORIGINDEX);
- if ((index_mf_to_mpoly && index_mp_to_orig) == false) {
- index_mf_to_mpoly = index_mp_to_orig = NULL;
+ if (index_mf_to_mpoly == NULL) {
+ index_mp_to_orig = NULL;
}
m_shapeType = (polytope) ? PHY_SHAPE_POLYTOPE : PHY_SHAPE_MESH;
@@ -1816,8 +1816,8 @@ bool CcdShapeConstructionInfo::UpdateMesh(class KX_GameObject* gameobj, class RA
/* double lookup */
const int *index_mf_to_mpoly = (const int *)dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
const int *index_mp_to_orig = (const int *)dm->getPolyDataArray(dm, CD_ORIGINDEX);
- if ((index_mf_to_mpoly && index_mp_to_orig) == false) {
- index_mf_to_mpoly = index_mp_to_orig = NULL;
+ if (index_mf_to_mpoly == NULL) {
+ index_mp_to_orig = NULL;
}
MFace *mf;
diff --git a/source/tests/bl_run_operators.py b/source/tests/bl_run_operators.py
index f792b83a8cd..5bb25537458 100644
--- a/source/tests/bl_run_operators.py
+++ b/source/tests/bl_run_operators.py
@@ -35,13 +35,16 @@ op_blacklist = (
"*.open_*",
"*.link_append",
"render.render",
+ "render.play_rendered_anim",
"*.*_export",
"*.*_import",
"wm.blenderplayer_start",
"wm.url_open",
"wm.doc_view",
"wm.path_open",
- "help.operator_cheat_sheet",
+ "wm.theme_install",
+ "wm.context_*",
+ "wm.operator_cheat_sheet",
"wm.keyconfig_test", # just annoying - but harmless
"wm.memory_statistics", # another annoying one
"console.*", # just annoying - but harmless