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:
authorJason Wilkins <Jason.A.Wilkins@gmail.com>2012-11-27 05:18:54 +0400
committerJason Wilkins <Jason.A.Wilkins@gmail.com>2012-11-27 05:18:54 +0400
commitff7c690e4064bbb1d6180668625d7b414000e9ea (patch)
tree4ac96ca8ed5a4e6a7ab1104d0271aba02266ace6
parent6b65102c20e9bdafd90f55f60c2a2084d873e809 (diff)
parent9b32776be349f5e738b449ca1298e65ce1b69d33 (diff)
Merge w/ trunk: r52086-r52534 (As with last time, the game engine was not merged)soc-2012-swiss_cheese
-rw-r--r--CMakeLists.txt315
-rw-r--r--GNUmakefile49
-rw-r--r--SConstruct55
-rwxr-xr-xbuild_files/build_environment/install_deps.sh1415
-rw-r--r--build_files/buildbot/config/user-config-glibc211-i686.py22
-rw-r--r--build_files/buildbot/config/user-config-glibc211-x86_64.py22
-rw-r--r--build_files/buildbot/config/user-config-glibc27-i686.py21
-rw-r--r--build_files/buildbot/config/user-config-glibc27-x86_64.py21
-rw-r--r--build_files/buildbot/config/user-config-player-glibc211-i686.py3
-rw-r--r--build_files/buildbot/config/user-config-player-glibc211-x86_64.py3
-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
-rw-r--r--build_files/buildbot/master.cfg14
-rw-r--r--build_files/buildbot/slave_rsync.py45
-rw-r--r--build_files/cmake/Modules/FindIcuLinux.cmake146
-rw-r--r--build_files/cmake/Modules/FindOpenColorIO.cmake1
-rw-r--r--build_files/cmake/Modules/FindOpenImageIO.cmake1
-rw-r--r--build_files/cmake/Modules/FindPythonLibsUnix.cmake1
-rwxr-xr-xbuild_files/cmake/cmake_consistency_check.py4
-rw-r--r--build_files/cmake/macros.cmake21
-rw-r--r--build_files/scons/config/darwin-config.py46
-rw-r--r--build_files/scons/config/freebsd7-config.py5
-rw-r--r--build_files/scons/config/freebsd8-config.py5
-rw-r--r--build_files/scons/config/freebsd9-config.py5
-rw-r--r--build_files/scons/config/linux-config.py24
-rw-r--r--build_files/scons/config/linuxcross-config.py5
-rw-r--r--build_files/scons/config/win32-mingw-config.py18
-rw-r--r--build_files/scons/config/win32-vc-config.py31
-rw-r--r--build_files/scons/config/win64-mingw-config.py12
-rw-r--r--build_files/scons/config/win64-vc-config.py33
-rw-r--r--build_files/scons/tools/Blender.py53
-rw-r--r--build_files/scons/tools/btools.py46
-rw-r--r--doc/python_api/rst/bge.logic.rst536
-rw-r--r--doc/python_api/rst/bge.types.rst580
-rw-r--r--doc/python_api/rst/bgl.rst253
-rw-r--r--doc/python_api/rst/gpu.rst8
-rw-r--r--doc/python_api/rst/info_gotcha.rst57
-rw-r--r--doc/python_api/sphinx_doc_gen.py6
-rw-r--r--extern/libmv/libmv-capi.cpp5
-rw-r--r--extern/xdnd/xdnd.c2
-rw-r--r--intern/CMakeLists.txt4
-rw-r--r--intern/SConscript3
-rw-r--r--intern/audaspace/intern/AUD_FileWriter.h8
-rw-r--r--intern/cycles/CMakeLists.txt7
-rw-r--r--intern/cycles/SConscript13
-rw-r--r--intern/cycles/blender/addon/osl.py7
-rw-r--r--intern/cycles/blender/blender_camera.cpp61
-rw-r--r--intern/cycles/blender/blender_session.cpp4
-rw-r--r--intern/cycles/blender/blender_shader.cpp35
-rw-r--r--intern/cycles/blender/blender_sync.cpp12
-rw-r--r--intern/cycles/blender/blender_sync.h6
-rw-r--r--intern/cycles/device/device.cpp13
-rw-r--r--intern/cycles/device/device_cuda.cpp15
-rw-r--r--intern/cycles/kernel/kernel_accumulate.h4
-rw-r--r--intern/cycles/kernel/kernel_camera.h15
-rw-r--r--intern/cycles/kernel/kernel_passes.h4
-rw-r--r--intern/cycles/kernel/kernel_path.h37
-rw-r--r--intern/cycles/kernel/kernel_shader.h23
-rw-r--r--intern/cycles/kernel/kernel_types.h3
-rw-r--r--intern/cycles/kernel/osl/SConscript27
-rw-r--r--intern/cycles/kernel/osl/osl_closures.h34
-rw-r--r--intern/cycles/kernel/osl/osl_globals.h6
-rw-r--r--intern/cycles/kernel/osl/osl_services.cpp74
-rw-r--r--intern/cycles/kernel/osl/osl_services.h17
-rw-r--r--intern/cycles/kernel/shaders/CMakeLists.txt2
-rw-r--r--intern/cycles/kernel/shaders/SConscript42
-rw-r--r--intern/cycles/kernel/shaders/node_ambient_occlusion.osl1
-rw-r--r--intern/cycles/kernel/shaders/node_brick_texture.osl9
-rw-r--r--intern/cycles/kernel/shaders/node_brightness.osl29
-rw-r--r--intern/cycles/kernel/shaders/node_checker_texture.osl9
-rw-r--r--intern/cycles/kernel/shaders/node_environment_texture.osl40
-rw-r--r--intern/cycles/kernel/shaders/node_gradient_texture.osl9
-rw-r--r--intern/cycles/kernel/shaders/node_hsv.osl3
-rw-r--r--intern/cycles/kernel/shaders/node_image_texture.osl15
-rw-r--r--intern/cycles/kernel/shaders/node_magic_texture.osl9
-rw-r--r--intern/cycles/kernel/shaders/node_musgrave_texture.osl9
-rw-r--r--intern/cycles/kernel/shaders/node_noise_texture.osl9
-rw-r--r--intern/cycles/kernel/shaders/node_sky_texture.osl15
-rw-r--r--intern/cycles/kernel/shaders/node_texture_coordinate.osl4
-rw-r--r--intern/cycles/kernel/shaders/node_voronoi_texture.osl9
-rw-r--r--intern/cycles/kernel/shaders/node_ward_bsdf.osl12
-rw-r--r--intern/cycles/kernel/shaders/node_wave_texture.osl9
-rw-r--r--intern/cycles/kernel/svm/svm_bsdf.h10
-rw-r--r--intern/cycles/kernel/svm/svm_closure.h9
-rw-r--r--intern/cycles/kernel/svm/svm_hsv.h2
-rw-r--r--intern/cycles/kernel/svm/svm_math.h17
-rw-r--r--intern/cycles/kernel/svm/svm_tex_coord.h19
-rw-r--r--intern/cycles/render/camera.cpp27
-rw-r--r--intern/cycles/render/camera.h8
-rw-r--r--intern/cycles/render/image.cpp24
-rw-r--r--intern/cycles/render/image.h7
-rw-r--r--intern/cycles/render/nodes.cpp65
-rw-r--r--intern/cycles/render/nodes.h7
-rw-r--r--intern/cycles/render/osl.cpp9
-rw-r--r--intern/cycles/render/osl.h3
-rw-r--r--intern/cycles/render/session.cpp2
-rw-r--r--intern/cycles/render/svm.cpp85
-rw-r--r--intern/cycles/render/svm.h14
-rw-r--r--intern/cycles/util/util_boundbox.h10
-rw-r--r--intern/cycles/util/util_thread.h6
-rw-r--r--intern/cycles/util/util_transform.cpp7
-rw-r--r--intern/cycles/util/util_transform.h37
-rw-r--r--intern/elbeem/intern/ntl_geometryobject.cpp2
-rw-r--r--intern/elbeem/intern/ntl_world.cpp11
-rw-r--r--intern/elbeem/intern/ntl_world.h3
-rw-r--r--intern/ghost/intern/GHOST_SystemCocoa.h3
-rw-r--r--intern/ghost/intern/GHOST_SystemCocoa.mm33
-rw-r--r--intern/ghost/intern/GHOST_SystemX11.cpp2
-rw-r--r--intern/ghost/intern/GHOST_WindowX11.cpp4
-rw-r--r--intern/iksolver/intern/IK_QJacobianSolver.cpp2
-rw-r--r--intern/locale/CMakeLists.txt45
-rw-r--r--intern/locale/SConscript14
-rw-r--r--intern/locale/boost_locale_wrapper.cpp114
-rw-r--r--intern/locale/boost_locale_wrapper.h49
-rw-r--r--intern/memutil/MEM_CacheLimiter.h6
-rw-r--r--intern/memutil/MEM_SmartPtr.h2
-rw-r--r--intern/opencolorio/ocio_impl.cc5
-rw-r--r--intern/opennl/CMakeLists.txt6
-rw-r--r--release/darwin/blender.app/Contents/Info.plist (renamed from source/darwin/blender.app/Contents/Info.plist)0
-rw-r--r--release/darwin/blender.app/Contents/MacOS/blender (renamed from source/darwin/blender.app/Contents/MacOS/blender)0
-rw-r--r--release/darwin/blender.app/Contents/PkgInfo (renamed from source/darwin/blender.app/Contents/PkgInfo)0
-rw-r--r--release/darwin/blender.app/Contents/Resources/blender file icon.icns (renamed from source/darwin/blender.app/Contents/Resources/blender file icon.icns)bin145836 -> 145836 bytes
-rw-r--r--release/darwin/blender.app/Contents/Resources/blender icon.icns (renamed from source/darwin/blender.app/Contents/Resources/blender icon.icns)bin189097 -> 189097 bytes
-rw-r--r--release/darwin/blenderplayer.app/Contents/Info.plist (renamed from source/darwin/blenderplayer.app/Contents/Info.plist)0
-rw-r--r--release/darwin/blenderplayer.app/Contents/MacOS/blenderplayer (renamed from source/darwin/blenderplayer.app/Contents/MacOS/blenderplayer)0
-rw-r--r--release/darwin/blenderplayer.app/Contents/PkgInfo (renamed from source/darwin/blenderplayer.app/Contents/PkgInfo)0
-rw-r--r--release/darwin/blenderplayer.app/Contents/Resources/blender file icon.icns (renamed from source/darwin/blenderplayer.app/Contents/Resources/blender file icon.icns)bin145836 -> 145836 bytes
-rw-r--r--release/darwin/blenderplayer.app/Contents/Resources/blender player icon.icns (renamed from source/darwin/blenderplayer.app/Contents/Resources/blender player icon.icns)bin189097 -> 189097 bytes
-rw-r--r--release/darwin/set_simulation_threads.app/Contents/Info.plist (renamed from source/darwin/set_simulation_threads.app/Contents/Info.plist)0
-rwxr-xr-xrelease/darwin/set_simulation_threads.app/Contents/MacOS/applet (renamed from source/darwin/set_simulation_threads.app/Contents/MacOS/applet)bin34480 -> 34480 bytes
-rw-r--r--release/darwin/set_simulation_threads.app/Contents/PkgInfo (renamed from source/darwin/set_simulation_threads.app/Contents/PkgInfo)0
-rw-r--r--release/darwin/set_simulation_threads.app/Contents/Resources/Scripts/main.scpt (renamed from source/darwin/set_simulation_threads.app/Contents/Resources/Scripts/main.scpt)bin7664 -> 7664 bytes
-rw-r--r--release/darwin/set_simulation_threads.app/Contents/Resources/applet.icns (renamed from source/darwin/set_simulation_threads.app/Contents/Resources/applet.icns)bin40291 -> 40291 bytes
-rw-r--r--release/darwin/set_simulation_threads.app/Contents/Resources/applet.rsrc (renamed from source/darwin/set_simulation_threads.app/Contents/Resources/applet.rsrc)bin362 -> 362 bytes
-rw-r--r--release/darwin/set_simulation_threads.app/Contents/Resources/description.rtfd/TXT.rtf (renamed from source/darwin/set_simulation_threads.app/Contents/Resources/description.rtfd/TXT.rtf)0
-rw-r--r--release/datafiles/blender_icons.pngbin228237 -> 229017 bytes
-rw-r--r--release/datafiles/startup.blendbin408072 -> 410796 bytes
-rw-r--r--release/scripts/modules/addon_utils.py2
-rw-r--r--release/scripts/modules/bl_i18n_utils/settings.py88
-rwxr-xr-xrelease/scripts/modules/bl_i18n_utils/update_languages_menu.py20
-rwxr-xr-xrelease/scripts/modules/bl_i18n_utils/update_pot.py77
-rw-r--r--release/scripts/modules/bpy/utils.py2
-rw-r--r--release/scripts/modules/bpy_extras/mesh_utils.py12
-rw-r--r--release/scripts/startup/bl_operators/object.py49
-rw-r--r--release/scripts/startup/bl_operators/presets.py6
-rw-r--r--release/scripts/startup/bl_operators/screen_play_rendered_anim.py8
-rw-r--r--release/scripts/startup/bl_operators/uvcalc_smart_project.py6
-rw-r--r--release/scripts/startup/bl_operators/wm.py11
-rw-r--r--release/scripts/startup/bl_ui/properties_data_armature.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_data_bone.py1
-rw-r--r--release/scripts/startup/bl_ui/properties_data_camera.py8
-rw-r--r--release/scripts/startup/bl_ui/properties_data_modifier.py3
-rw-r--r--release/scripts/startup/bl_ui/properties_object_constraint.py28
-rw-r--r--release/scripts/startup/bl_ui/space_dopesheet.py6
-rw-r--r--release/scripts/startup/bl_ui/space_graph.py6
-rw-r--r--release/scripts/startup/bl_ui/space_image.py1
-rw-r--r--release/scripts/startup/bl_ui/space_info.py2
-rw-r--r--release/scripts/startup/bl_ui/space_sequencer.py2
-rw-r--r--release/scripts/startup/bl_ui/space_text.py15
-rw-r--r--release/scripts/startup/bl_ui/space_userpref.py4
-rw-r--r--release/scripts/startup/bl_ui/space_view3d.py25
-rw-r--r--release/scripts/templates/script_stub.py3
-rw-r--r--release/text/readme.html10
-rw-r--r--source/blender/avi/intern/avi_rgb.c2
-rw-r--r--source/blender/blenfont/BLF_translation.h75
-rw-r--r--source/blender/blenfont/CMakeLists.txt4
-rw-r--r--source/blender/blenfont/SConscript3
-rw-r--r--source/blender/blenfont/intern/blf.c1
-rw-r--r--source/blender/blenfont/intern/blf_lang.c240
-rw-r--r--source/blender/blenfont/intern/blf_translation.c86
-rw-r--r--source/blender/blenkernel/BKE_DerivedMesh.h2
-rw-r--r--source/blender/blenkernel/BKE_image.h10
-rw-r--r--source/blender/blenkernel/BKE_modifier.h4
-rw-r--r--source/blender/blenkernel/BKE_node.h2
-rw-r--r--source/blender/blenkernel/BKE_sequencer.h2
-rw-r--r--source/blender/blenkernel/BKE_text.h34
-rw-r--r--source/blender/blenkernel/SConscript1
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c2
-rw-r--r--source/blender/blenkernel/intern/action.c4
-rw-r--r--source/blender/blenkernel/intern/armature.c9
-rw-r--r--source/blender/blenkernel/intern/blender.c2
-rw-r--r--source/blender/blenkernel/intern/brush.c2
-rw-r--r--source/blender/blenkernel/intern/cdderivedmesh.c49
-rw-r--r--source/blender/blenkernel/intern/collision.c10
-rw-r--r--source/blender/blenkernel/intern/colortools.c39
-rw-r--r--source/blender/blenkernel/intern/context.c10
-rw-r--r--source/blender/blenkernel/intern/curve.c2
-rw-r--r--source/blender/blenkernel/intern/customdata.c4
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c3
-rw-r--r--source/blender/blenkernel/intern/dynamicpaint.c6
-rw-r--r--source/blender/blenkernel/intern/idcode.c65
-rw-r--r--source/blender/blenkernel/intern/image.c276
-rw-r--r--source/blender/blenkernel/intern/library.c4
-rw-r--r--source/blender/blenkernel/intern/mask_evaluate.c6
-rw-r--r--source/blender/blenkernel/intern/mesh.c2
-rw-r--r--source/blender/blenkernel/intern/modifier.c4
-rw-r--r--source/blender/blenkernel/intern/node.c1
-rw-r--r--source/blender/blenkernel/intern/object.c18
-rw-r--r--source/blender/blenkernel/intern/particle.c28
-rw-r--r--source/blender/blenkernel/intern/pointcache.c6
-rw-r--r--source/blender/blenkernel/intern/scene.c2
-rw-r--r--source/blender/blenkernel/intern/seqeffects.c3
-rw-r--r--source/blender/blenkernel/intern/sequencer.c14
-rw-r--r--source/blender/blenkernel/intern/suggestions.c10
-rw-r--r--source/blender/blenkernel/intern/text.c1003
-rw-r--r--source/blender/blenkernel/intern/tracking.c10
-rw-r--r--source/blender/blenkernel/intern/writeffmpeg.c35
-rw-r--r--source/blender/blenlib/BLI_endian_switch_inline.h34
-rw-r--r--source/blender/blenlib/BLI_ghash.h2
-rw-r--r--source/blender/blenlib/BLI_math_base.h4
-rw-r--r--source/blender/blenlib/BLI_math_color.h2
-rw-r--r--source/blender/blenlib/BLI_math_geom.h6
-rw-r--r--source/blender/blenlib/BLI_math_inline.h5
-rw-r--r--source/blender/blenlib/BLI_math_interp.h13
-rw-r--r--source/blender/blenlib/BLI_math_vector.h3
-rw-r--r--source/blender/blenlib/BLI_threads.h17
-rw-r--r--source/blender/blenlib/BLI_utildefines.h9
-rw-r--r--source/blender/blenlib/CMakeLists.txt6
-rw-r--r--source/blender/blenlib/intern/BLI_ghash.c2
-rw-r--r--source/blender/blenlib/intern/BLI_kdopbvh.c2
-rw-r--r--source/blender/blenlib/intern/math_base_inline.c24
-rw-r--r--source/blender/blenlib/intern/math_geom.c27
-rw-r--r--source/blender/blenlib/intern/math_geom_inline.c5
-rw-r--r--source/blender/blenlib/intern/math_interp.c230
-rw-r--r--source/blender/blenlib/intern/math_rotation.c2
-rw-r--r--source/blender/blenlib/intern/math_vector.c27
-rw-r--r--source/blender/blenlib/intern/math_vector_inline.c5
-rw-r--r--source/blender/blenlib/intern/noise.c60
-rw-r--r--source/blender/blenlib/intern/pbvh.c11
-rw-r--r--source/blender/blenlib/intern/scanfill.c2
-rw-r--r--source/blender/blenlib/intern/string.c16
-rw-r--r--source/blender/blenlib/intern/string_utf8.c12
-rw-r--r--source/blender/blenlib/intern/threads.c36
-rw-r--r--source/blender/blenloader/intern/readfile.c32
-rw-r--r--source/blender/blenloader/intern/versioning_250.c2
-rw-r--r--source/blender/blenloader/intern/writefile.c8
-rw-r--r--source/blender/bmesh/CMakeLists.txt10
-rw-r--r--source/blender/bmesh/bmesh.h4
-rw-r--r--source/blender/bmesh/bmesh_class.h43
-rw-r--r--source/blender/bmesh/intern/bmesh_construct.c10
-rw-r--r--source/blender/bmesh/intern/bmesh_core.c69
-rw-r--r--source/blender/bmesh/intern/bmesh_interp.c20
-rw-r--r--source/blender/bmesh/intern/bmesh_iterators.c10
-rw-r--r--source/blender/bmesh/intern/bmesh_iterators.h7
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh.c44
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh.h6
-rw-r--r--source/blender/bmesh/intern/bmesh_opdefines.c774
-rw-r--r--source/blender/bmesh/intern/bmesh_operator_api.h141
-rw-r--r--source/blender/bmesh/intern/bmesh_operator_api_inline.h48
-rw-r--r--source/blender/bmesh/intern/bmesh_operators.c434
-rw-r--r--source/blender/bmesh/intern/bmesh_operators.h5
-rw-r--r--source/blender/bmesh/intern/bmesh_polygon.c9
-rw-r--r--source/blender/bmesh/intern/bmesh_private.h20
-rw-r--r--source/blender/bmesh/intern/bmesh_queries.c57
-rw-r--r--source/blender/bmesh/intern/bmesh_queries.h10
-rw-r--r--source/blender/bmesh/operators/bmo_bevel.c2209
-rw-r--r--source/blender/bmesh/operators/bmo_connect.c14
-rw-r--r--source/blender/bmesh/operators/bmo_create.c86
-rw-r--r--source/blender/bmesh/operators/bmo_dissolve.c30
-rw-r--r--source/blender/bmesh/operators/bmo_dupe.c159
-rw-r--r--source/blender/bmesh/operators/bmo_edgesplit.c20
-rw-r--r--source/blender/bmesh/operators/bmo_extrude.c64
-rw-r--r--source/blender/bmesh/operators/bmo_hull.c64
-rw-r--r--source/blender/bmesh/operators/bmo_inset.c57
-rw-r--r--source/blender/bmesh/operators/bmo_join_triangles.c12
-rw-r--r--source/blender/bmesh/operators/bmo_mesh_conv.c14
-rw-r--r--source/blender/bmesh/operators/bmo_mirror.c23
-rw-r--r--source/blender/bmesh/operators/bmo_primitive.c107
-rw-r--r--source/blender/bmesh/operators/bmo_removedoubles.c87
-rw-r--r--source/blender/bmesh/operators/bmo_similar.c30
-rw-r--r--source/blender/bmesh/operators/bmo_slide.c8
-rw-r--r--source/blender/bmesh/operators/bmo_smooth_laplacian.c40
-rw-r--r--source/blender/bmesh/operators/bmo_subdivide.c65
-rw-r--r--source/blender/bmesh/operators/bmo_subdivide.h2
-rw-r--r--source/blender/bmesh/operators/bmo_symmetrize.c20
-rw-r--r--source/blender/bmesh/operators/bmo_triangulate.c27
-rw-r--r--source/blender/bmesh/operators/bmo_unsubdivide.c6
-rw-r--r--source/blender/bmesh/operators/bmo_utils.c107
-rw-r--r--source/blender/bmesh/operators/bmo_wireframe.c87
-rw-r--r--source/blender/bmesh/tools/BME_bevel.c5
-rw-r--r--source/blender/bmesh/tools/bmesh_bevel.c1749
-rw-r--r--source/blender/bmesh/tools/bmesh_bevel.h32
-rw-r--r--source/blender/bmesh/tools/bmesh_decimate.h (renamed from source/blender/bmesh/intern/bmesh_decimate.h)2
-rw-r--r--source/blender/bmesh/tools/bmesh_decimate_collapse.c (renamed from source/blender/bmesh/intern/bmesh_decimate_collapse.c)5
-rw-r--r--source/blender/bmesh/tools/bmesh_decimate_dissolve.c (renamed from source/blender/bmesh/intern/bmesh_decimate_dissolve.c)6
-rw-r--r--source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c (renamed from source/blender/bmesh/intern/bmesh_decimate_unsubdivide.c)2
-rw-r--r--source/blender/collada/AnimationImporter.cpp2
-rw-r--r--source/blender/collada/DocumentImporter.cpp4
-rw-r--r--source/blender/collada/DocumentImporter.h4
-rw-r--r--source/blender/collada/ImageExporter.cpp4
-rw-r--r--source/blender/compositor/CMakeLists.txt4
-rw-r--r--source/blender/compositor/intern/COM_Converter.cpp4
-rw-r--r--source/blender/compositor/intern/COM_ExecutionSystem.cpp5
-rw-r--r--source/blender/compositor/nodes/COM_BlurNode.cpp48
-rw-r--r--source/blender/compositor/nodes/COM_ImageNode.cpp3
-rw-r--r--source/blender/compositor/nodes/COM_MapRangeNode.cpp54
-rw-r--r--source/blender/compositor/nodes/COM_MapRangeNode.h38
-rw-r--r--source/blender/compositor/nodes/COM_MuteNode.cpp4
-rw-r--r--source/blender/compositor/nodes/COM_NormalNode.cpp11
-rw-r--r--source/blender/compositor/nodes/COM_OutputFileNode.cpp6
-rw-r--r--source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp5
-rw-r--r--source/blender/compositor/operations/COM_GammaCorrectOperation.cpp28
-rw-r--r--source/blender/compositor/operations/COM_ImageOperation.cpp6
-rw-r--r--source/blender/compositor/operations/COM_KeyingScreenOperation.cpp6
-rw-r--r--source/blender/compositor/operations/COM_MapRangeOperation.cpp87
-rw-r--r--source/blender/compositor/operations/COM_MapRangeOperation.h71
-rw-r--r--source/blender/compositor/operations/COM_PixelateOperation.h2
-rw-r--r--source/blender/compositor/operations/COM_RenderLayersBaseProg.cpp4
-rw-r--r--source/blender/compositor/operations/COM_ViewerBaseOperation.cpp10
-rw-r--r--source/blender/editors/animation/anim_channels_edit.c20
-rw-r--r--source/blender/editors/armature/editarmature.c6
-rw-r--r--source/blender/editors/curve/editcurve.c32
-rw-r--r--source/blender/editors/curve/editfont.c7
-rw-r--r--source/blender/editors/gpencil/gpencil_edit.c1107
-rw-r--r--source/blender/editors/gpencil/gpencil_paint.c285
-rw-r--r--source/blender/editors/include/ED_gpencil.h1
-rw-r--r--source/blender/editors/include/ED_image.h2
-rw-r--r--source/blender/editors/include/ED_mesh.h7
-rw-r--r--source/blender/editors/include/UI_icons.h2
-rw-r--r--source/blender/editors/interface/interface.c26
-rw-r--r--source/blender/editors/interface/interface_intern.h2
-rw-r--r--source/blender/editors/interface/interface_layout.c27
-rw-r--r--source/blender/editors/interface/interface_regions.c4
-rw-r--r--source/blender/editors/interface/interface_templates.c366
-rw-r--r--source/blender/editors/interface/interface_widgets.c8
-rw-r--r--source/blender/editors/mesh/editmesh_add.c26
-rw-r--r--source/blender/editors/mesh/editmesh_bvh.c4
-rw-r--r--source/blender/editors/mesh/editmesh_knife.c6
-rw-r--r--source/blender/editors/mesh/editmesh_loopcut.c48
-rw-r--r--source/blender/editors/mesh/editmesh_rip.c2
-rw-r--r--source/blender/editors/mesh/editmesh_select.c259
-rw-r--r--source/blender/editors/mesh/editmesh_slide.c4
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c197
-rw-r--r--source/blender/editors/mesh/editmesh_utils.c12
-rw-r--r--source/blender/editors/mesh/mesh_intern.h1
-rw-r--r--source/blender/editors/mesh/mesh_ops.c13
-rw-r--r--source/blender/editors/object/object_bake.c76
-rw-r--r--source/blender/editors/object/object_edit.c7
-rw-r--r--source/blender/editors/object/object_modifier.c11
-rw-r--r--source/blender/editors/object/object_relations.c4
-rw-r--r--source/blender/editors/object/object_vgroup.c15
-rw-r--r--source/blender/editors/physics/particle_edit.c13
-rw-r--r--source/blender/editors/physics/physics_fluid.c8
-rw-r--r--source/blender/editors/render/render_internal.c2
-rw-r--r--source/blender/editors/render/render_opengl.c4
-rw-r--r--source/blender/editors/render/render_preview.c4
-rw-r--r--source/blender/editors/render/render_update.c42
-rw-r--r--source/blender/editors/screen/screen_ops.c14
-rw-r--r--source/blender/editors/screen/screendump.c61
-rw-r--r--source/blender/editors/sculpt_paint/paint_image.c88
-rw-r--r--source/blender/editors/space_buttons/buttons_texture.c2
-rw-r--r--source/blender/editors/space_clip/clip_draw.c4
-rw-r--r--source/blender/editors/space_clip/clip_editor.c2
-rw-r--r--source/blender/editors/space_clip/space_clip.c11
-rw-r--r--source/blender/editors/space_console/console_ops.c20
-rw-r--r--source/blender/editors/space_graph/graph_buttons.c12
-rw-r--r--source/blender/editors/space_image/image_buttons.c5
-rw-r--r--source/blender/editors/space_image/image_draw.c11
-rw-r--r--source/blender/editors/space_image/image_edit.c16
-rw-r--r--source/blender/editors/space_image/image_ops.c55
-rw-r--r--source/blender/editors/space_image/space_image.c2
-rw-r--r--source/blender/editors/space_info/info_ops.c8
-rw-r--r--source/blender/editors/space_node/drawnode.c48
-rw-r--r--source/blender/editors/space_node/node_group.c9
-rw-r--r--source/blender/editors/space_node/node_view.c29
-rw-r--r--source/blender/editors/space_outliner/outliner_draw.c2
-rw-r--r--source/blender/editors/space_sequencer/SConscript2
-rw-r--r--source/blender/editors/space_sequencer/sequencer_draw.c9
-rw-r--r--source/blender/editors/space_sequencer/sequencer_edit.c2
-rw-r--r--source/blender/editors/space_text/space_text.c5
-rw-r--r--source/blender/editors/space_text/text_draw.c170
-rw-r--r--source/blender/editors/space_text/text_intern.h9
-rw-r--r--source/blender/editors/space_text/text_ops.c301
-rw-r--r--source/blender/editors/space_text/text_python.c174
-rw-r--r--source/blender/editors/space_view3d/drawmesh.c2
-rw-r--r--source/blender/editors/space_view3d/drawobject.c65
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c15
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c90
-rw-r--r--source/blender/editors/space_view3d/view3d_header.c54
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c14
-rw-r--r--source/blender/editors/transform/transform.c22
-rw-r--r--source/blender/editors/transform/transform_constraints.c2
-rw-r--r--source/blender/editors/transform/transform_conversions.c2
-rw-r--r--source/blender/editors/uvedit/uvedit_buttons.c7
-rw-r--r--source/blender/editors/uvedit/uvedit_ops.c168
-rw-r--r--source/blender/editors/uvedit/uvedit_parametrizer.c8
-rw-r--r--source/blender/editors/uvedit/uvedit_smart_stitch.c18
-rw-r--r--source/blender/editors/uvedit/uvedit_unwrap_ops.c4
-rw-r--r--source/blender/gpu/SConscript1
-rw-r--r--source/blender/gpu/intern/gpu_draw.c14
-rw-r--r--source/blender/gpu/intern/gpu_material.c3
-rw-r--r--source/blender/gpu/shaders/gpu_shader_vertex.glsl8
-rw-r--r--source/blender/ikplugin/intern/ikplugin_api.c4
-rw-r--r--source/blender/ikplugin/intern/iksolver_plugin.c3
-rw-r--r--source/blender/imbuf/intern/cineon/cineon_dpx.c16
-rw-r--r--source/blender/imbuf/intern/cineon/cineonlib.c2
-rw-r--r--source/blender/imbuf/intern/cineon/dpxlib.c2
-rw-r--r--source/blender/imbuf/intern/colormanagement.c5
-rw-r--r--source/blender/imbuf/intern/dds/BlockDXT.h4
-rw-r--r--source/blender/imbuf/intern/dds/SConscript9
-rw-r--r--source/blender/imbuf/intern/imageprocess.c197
-rw-r--r--source/blender/imbuf/intern/jp2.c4
-rw-r--r--source/blender/imbuf/intern/jpeg.c25
-rw-r--r--source/blender/imbuf/intern/openexr/CMakeLists.txt2
-rw-r--r--source/blender/imbuf/intern/openexr/openexr_api.cpp20
-rw-r--r--source/blender/imbuf/intern/openexr/openexr_multi.h8
-rw-r--r--source/blender/imbuf/intern/scaling.c8
-rw-r--r--source/blender/imbuf/intern/util.c21
-rw-r--r--source/blender/makesdna/DNA_action_types.h2
-rw-r--r--source/blender/makesdna/DNA_gpencil_types.h5
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h15
-rw-r--r--source/blender/makesdna/DNA_scene_types.h9
-rw-r--r--source/blender/makesdna/DNA_text_types.h11
-rw-r--r--source/blender/makesdna/DNA_tracking_types.h4
-rw-r--r--source/blender/makesdna/DNA_userdef_types.h2
-rw-r--r--source/blender/makesrna/RNA_access.h7
-rw-r--r--source/blender/makesrna/intern/makesrna.c88
-rw-r--r--source/blender/makesrna/intern/rna_access.c150
-rw-r--r--source/blender/makesrna/intern/rna_actuator.c4
-rw-r--r--source/blender/makesrna/intern/rna_constraint.c2
-rw-r--r--source/blender/makesrna/intern/rna_curve.c2
-rw-r--r--source/blender/makesrna/intern/rna_image.c27
-rw-r--r--source/blender/makesrna/intern/rna_image_api.c19
-rw-r--r--source/blender/makesrna/intern/rna_lamp.c2
-rw-r--r--source/blender/makesrna/intern/rna_modifier.c22
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c16
-rw-r--r--source/blender/makesrna/intern/rna_nodetree_types.h1
-rw-r--r--source/blender/makesrna/intern/rna_object.c6
-rw-r--r--source/blender/makesrna/intern/rna_pose.c10
-rw-r--r--source/blender/makesrna/intern/rna_scene.c12
-rw-r--r--source/blender/makesrna/intern/rna_sequencer.c4
-rw-r--r--source/blender/makesrna/intern/rna_space.c4
-rw-r--r--source/blender/makesrna/intern/rna_speaker.c4
-rw-r--r--source/blender/makesrna/intern/rna_text.c48
-rw-r--r--source/blender/makesrna/intern/rna_texture.c1
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c14
-rw-r--r--source/blender/makesrna/intern/rna_wm.c6
-rw-r--r--source/blender/modifiers/CMakeLists.txt1
-rw-r--r--source/blender/modifiers/MOD_modifiertypes.h1
-rw-r--r--source/blender/modifiers/intern/MOD_armature.c2
-rw-r--r--source/blender/modifiers/intern/MOD_array.c75
-rw-r--r--source/blender/modifiers/intern/MOD_bevel.c44
-rw-r--r--source/blender/modifiers/intern/MOD_decimate.c1
-rw-r--r--source/blender/modifiers/intern/MOD_edgesplit.c5
-rw-r--r--source/blender/modifiers/intern/MOD_fluidsim_util.c6
-rw-r--r--source/blender/modifiers/intern/MOD_laplaciansmooth.c6
-rw-r--r--source/blender/modifiers/intern/MOD_skin.c20
-rw-r--r--source/blender/modifiers/intern/MOD_triangulate.c144
-rw-r--r--source/blender/modifiers/intern/MOD_util.c1
-rw-r--r--source/blender/nodes/CMakeLists.txt10
-rw-r--r--source/blender/nodes/NOD_composite.h1
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_colorbalance.c16
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_image.c22
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_mapRange.c58
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_normal.c2
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_splitViewer.c4
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_viewer.c4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_normal_map.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_environment.c3
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_image.c3
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_texture.c3
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_image.c4
-rw-r--r--source/blender/python/bmesh/bmesh_py_ops.c134
-rw-r--r--source/blender/python/bmesh/bmesh_py_types.c83
-rw-r--r--source/blender/python/bmesh/bmesh_py_types_customdata.c4
-rw-r--r--source/blender/python/bmesh/bmesh_py_types_meshdata.c4
-rw-r--r--source/blender/python/generic/bgl.c22
-rw-r--r--source/blender/python/generic/bpy_internal_import.c13
-rw-r--r--source/blender/python/generic/idprop_py_api.c8
-rw-r--r--source/blender/python/generic/py_capi_utils.c6
-rw-r--r--source/blender/python/intern/bpy_app.c4
-rw-r--r--source/blender/python/intern/bpy_intern_string.c6
-rw-r--r--source/blender/python/intern/bpy_intern_string.h2
-rw-r--r--source/blender/python/intern/bpy_rna.c36
-rw-r--r--source/blender/python/intern/bpy_rna_array.c6
-rw-r--r--source/blender/python/mathutils/mathutils_Vector.c2
-rw-r--r--source/blender/render/extern/include/RE_engine.h1
-rw-r--r--source/blender/render/intern/include/initrender.h5
-rw-r--r--source/blender/render/intern/raytrace/rayobject_internal.h2
-rw-r--r--source/blender/render/intern/raytrace/rayobject_octree.cpp2
-rw-r--r--source/blender/render/intern/raytrace/rayobject_rtbuild.cpp2
-rw-r--r--source/blender/render/intern/source/convertblender.c4
-rw-r--r--source/blender/render/intern/source/envmap.c3
-rw-r--r--source/blender/render/intern/source/external_engine.c32
-rw-r--r--source/blender/render/intern/source/imagetexture.c81
-rw-r--r--source/blender/render/intern/source/initrender.c24
-rw-r--r--source/blender/render/intern/source/pipeline.c13
-rw-r--r--source/blender/render/intern/source/render_texture.c30
-rw-r--r--source/blender/render/intern/source/rendercore.c28
-rw-r--r--source/blender/render/intern/source/renderdatabase.c34
-rw-r--r--source/blender/render/intern/source/shadeoutput.c4
-rw-r--r--source/blender/render/intern/source/sunsky.c4
-rw-r--r--source/blender/render/intern/source/voxeldata.c11
-rw-r--r--source/blender/render/intern/source/zbuf.c4
-rw-r--r--source/blender/windowmanager/WM_api.h1
-rw-r--r--source/blender/windowmanager/intern/wm_draw.c13
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c156
-rw-r--r--source/blender/windowmanager/intern/wm_jobs.c6
-rw-r--r--source/blender/windowmanager/intern/wm_keymap.c7
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c60
-rw-r--r--source/blender/windowmanager/intern/wm_playanim.c194
-rw-r--r--source/blender/windowmanager/intern/wm_window.c13
-rw-r--r--source/blender/windowmanager/wm_event_types.h6
-rw-r--r--source/blenderplayer/CMakeLists.txt6
-rw-r--r--source/creator/CMakeLists.txt37
-rw-r--r--source/creator/blender.map11
-rw-r--r--source/creator/creator.c5
-rw-r--r--source/tests/bl_rst_completeness.py159
-rw-r--r--source/tests/rst_to_doctree_mini.py91
509 files changed, 14255 insertions, 8212 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1df39d226a1..8c8f572df6e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -237,6 +237,7 @@ endif()
option(WITH_RAYOPTIMIZATION "Enable use of SIMD (SSE) optimizations for the raytracer" ON)
if(UNIX AND NOT APPLE)
option(WITH_INSTALL_PORTABLE "Install redistributeable runtime, otherwise install into CMAKE_INSTALL_PREFIX" ON)
+ option(WITH_STATIC_LIBS "Try to link with static libraries, as much as possible, to make blender more portable across distributions" OFF)
endif()
option(WITH_PYTHON_INSTALL "Copy system python into the blender install folder" ON)
option(WITH_PYTHON_INSTALL_NUMPY "Copy system numpy into the blender install folder" ON)
@@ -303,18 +304,14 @@ if(APPLE)
set(OSX_SYSTEM unsupported)
endif()
message(STATUS "Detected system-version: " ${OSX_SYSTEM})
-
- if(NOT CMAKE_OSX_DEPLOYMENT_TARGET)
- set(CMAKE_OSX_DEPLOYMENT_TARGET "10.6" CACHE STRING "" FORCE) # 10.6 is our min. target, if you use higher sdk, weak linking happens - with 10.5 we have still not solved problems, build those with 10.5.sdk for now !!!
- endif()
if(${CMAKE_GENERATOR} MATCHES "Xcode")
- ##### workaround for actual official cmake incompatibility with xcode 4.3 #####
+ ##### cmake incompatibility with xcode 4.3 and higher #####
if(${XCODE_VERSION} MATCHES '') # cmake fails due looking for xcode in the wrong path, thus will be empty var
- message("Official cmake does not yet support Xcode 4.3, get a patched version here: http://www.jensverwiebe.de/Blender/CMake%202.8-7patched.zip")
+ message(FATAL_ERROR "Xcode 4.3 and higher must be used with cmake 2.8-8 or higher")
endif()
- ### end workaround for actual official cmake incompatibility with xcode 4.3 ###
+ ### end cmake incompatibility with xcode 4.3 and higher ###
if(${XCODE_VERSION} VERSION_EQUAL 4 OR ${XCODE_VERSION} VERSION_GREATER 4 AND ${XCODE_VERSION} VERSION_LESS 4.3)
# Xcode 4 defaults to the Apple LLVM Compiler.
@@ -326,14 +323,31 @@ if(APPLE)
execute_process(COMMAND xcodebuild -version OUTPUT_VARIABLE XCODE_VERS_BUILD_NR)
string(SUBSTRING "${XCODE_VERS_BUILD_NR}" 6 3 XCODE_VERSION) # truncate away build-nr
unset(XCODE_VERS_BUILD_NR)
+ endif()
+
+ message(STATUS "Detected Xcode-version: " ${XCODE_VERSION})
+
+ if(${XCODE_VERSION} VERSION_LESS 4.3)
+ set(CMAKE_OSX_SYSROOT /Developer/SDKs/MacOSX${OSX_SYSTEM}.sdk CACHE PATH "" FORCE) # use guaranteed existing sdk
+ else()
+ # note: i don't use xcode-select path on purpose, cause also /Applications/Xcode.app would be allowed
+ # absolute pathes are more foolproof here !
+ set(OSX_SYSROOT_PREFIX /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform)
+ set(OSX_DEVELOPER_PREFIX /Developer/SDKs/MacOSX${OSX_SYSTEM}.sdk) # use guaranteed existing sdk
+ set(CMAKE_OSX_SYSROOT ${OSX_SYSROOT_PREFIX}/${OSX_DEVELOPER_PREFIX} CACHE PATH "" FORCE)
+ endif()
+
+ if(NOT CMAKE_OSX_DEPLOYMENT_TARGET)
+ set(CMAKE_OSX_DEPLOYMENT_TARGET "10.5" CACHE STRING "" FORCE) # 10.5 is our min. target, if you use higher sdk, weak linking happens
+ endif()
+
+ if(NOT ${CMAKE_GENERATOR} MATCHES "Xcode")
# force CMAKE_OSX_DEPLOYMENT_TARGET for makefiles, will not work else ( cmake bug ? )
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}")
add_definitions ("-DMACOSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET}")
endif()
-
- message(STATUS "Detected Xcode-version: " ${XCODE_VERSION})
-
+
option(WITH_COCOA "Use Cocoa framework instead of deprecated Carbon" ON)
option(USE_QTKIT "Use QtKit instead of Carbon quicktime (needed for having partial quicktime for 64bit)" OFF)
option(WITH_LIBS10.5 "Use 10.5 libs (needed for 64bit builds)" OFF)
@@ -354,12 +368,20 @@ if(NOT WITH_GAMEENGINE AND WITH_PLAYER)
message(FATAL_ERROR "WITH_PLAYER requires WITH_GAMEENGINE")
endif()
-if(NOT WITH_AUDASPACE AND (WITH_OPENAL OR WITH_JACK OR WITH_GAMEENGINE))
- message(FATAL_ERROR "WITH_OPENAL/WITH_JACK/WITH_CODEC_FFMPEG/WITH_GAMEENGINE require WITH_AUDASPACE")
+if(NOT WITH_AUDASPACE)
+ if(WITH_OPENAL)
+ message(FATAL_ERROR "WITH_OPENAL requires WITH_AUDASPACE")
+ endif()
+ if(WITH_JACK)
+ message(FATAL_ERROR "WITH_JACK requires WITH_AUDASPACE")
+ endif()
+ if(WITH_GAMEENGINE)
+ message(FATAL_ERROR "WITH_GAMEENGINE requires WITH_AUDASPACE")
+ endif()
endif()
if(NOT WITH_SDL AND WITH_GHOST_SDL)
- message(FATAL_ERROR "WITH_GHOST_SDL requires WITH_SDL to be ON")
+ message(FATAL_ERROR "WITH_GHOST_SDL requires WITH_SDL")
endif()
if(WITH_IMAGE_REDCODE AND ((NOT WITH_IMAGE_OPENJPEG) OR (NOT WITH_CODEC_FFMPEG)))
@@ -390,8 +412,8 @@ if(WITH_CYCLES)
set(WITH_OPENIMAGEIO ON)
endif()
-# auto enable boost for cycles, booleans or audaspace
-if(WITH_CYCLES OR WITH_MOD_BOOLEAN OR WITH_AUDASPACE)
+# auto enable boost for cycles, booleans, audaspace or i18n
+if(WITH_CYCLES OR WITH_MOD_BOOLEAN OR WITH_AUDASPACE OR WITH_INTERNATIONAL)
set(WITH_BOOST ON)
endif()
@@ -520,8 +542,6 @@ endif()
if(UNIX AND NOT APPLE)
-
- # set lib directory if it exists
if(WITH_ANDROID)
set(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/android/${ANDROID_TARGET})
@@ -533,27 +553,12 @@ if(UNIX AND NOT APPLE)
else()
set(ANDROID_PROJ ${LIBDIR}/aghosty-sdl CACHE STRING "Android Project Path")
endif()
- elseif(CMAKE_SYSTEM_NAME MATCHES "Linux")
- if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
- set(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/linux64)
- else()
- set(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/linux)
- endif()
-
- if(NOT EXISTS ${LIBDIR})
- unset(LIBDIR)
- endif()
- endif()
-
-
- if(WITH_ANDROID)
-
-
- set(JPEG "${LIBDIR}/jpeg")
- set(JPEG_INCLUDE_DIR "${JPEG}/include")
- set(JPEG_LIBPATH ${JPEG}/lib)
- set(JPEG_LIBRARIES ${JPEG_LIBPATH}/libjpeg.so)
+
+ set(JPEG "${LIBDIR}/jpeg")
+ set(JPEG_INCLUDE_DIR "${JPEG}/include")
+ set(JPEG_LIBPATH ${JPEG}/lib)
+ set(JPEG_LIBRARIES ${JPEG_LIBPATH}/libjpeg.so)
set(PNG "${LIBDIR}/png")
@@ -592,10 +597,25 @@ if(UNIX AND NOT APPLE)
else()
- find_package(JPEG REQUIRED)
- find_package(PNG REQUIRED)
- find_package(ZLIB REQUIRED)
- find_package(Freetype REQUIRED)
+ macro(find_package_wrapper)
+ STRING(TOUPPER ${ARGV0} _NAME_UPPER)
+ if(${WITH_STATIC_LIBS})
+ set(_cmake_find_library_suffixes_back ${CMAKE_FIND_LIBRARY_SUFFIXES})
+ set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
+
+
+ endif()
+ find_package(${ARGV})
+ if(${WITH_STATIC_LIBS})
+ set(CMAKE_FIND_LIBRARY_SUFFIXES ${_cmake_find_library_suffixes_back})
+ unset(_cmake_find_library_suffixes_back)
+ endif()
+ endmacro()
+
+ find_package_wrapper(JPEG REQUIRED)
+ find_package_wrapper(PNG REQUIRED)
+ find_package_wrapper(ZLIB REQUIRED)
+ find_package_wrapper(Freetype REQUIRED)
endif()
if(WITH_PYTHON AND NOT WITH_ANDROID)
@@ -604,25 +624,28 @@ if(UNIX AND NOT APPLE)
# Use our own instead, since wothout py is such a rare case,
# require this package
+ # XXX Linking errors with debian static python :/
+# find_package_wrapper(PythonLibsUnix REQUIRED)
find_package(PythonLibsUnix REQUIRED)
endif()
-
if(WITH_IMAGE_OPENEXR)
- find_package(OpenEXR) # our own module
+ find_package_wrapper(OpenEXR) # our own module
if(NOT OPENEXR_FOUND)
set(WITH_IMAGE_OPENEXR OFF)
endif()
endif()
if(WITH_IMAGE_OPENJPEG)
- find_package(OpenJPEG)
+ find_package_wrapper(OpenJPEG)
if(NOT OPENJPEG_FOUND)
set(WITH_IMAGE_OPENJPEG OFF)
endif()
endif()
if(WITH_IMAGE_TIFF)
+ # XXX Linking errors with debian static tiff :/
+# find_package_wrapper(TIFF)
find_package(TIFF)
if(NOT TIFF_FOUND)
set(WITH_IMAGE_TIFF OFF)
@@ -631,14 +654,14 @@ if(UNIX AND NOT APPLE)
# Audio IO
if(WITH_OPENAL)
- find_package(OpenAL)
+ find_package_wrapper(OpenAL)
if(NOT OPENAL_FOUND)
set(WITH_OPENAL OFF)
endif()
endif()
if(WITH_SDL AND NOT WITH_ANDROID)
- find_package(SDL)
+ find_package_wrapper(SDL)
mark_as_advanced(
SDLMAIN_LIBRARY
SDL_INCLUDE_DIR
@@ -652,7 +675,7 @@ if(UNIX AND NOT APPLE)
endif()
if(WITH_JACK)
- find_package(Jack)
+ find_package_wrapper(Jack)
if(NOT JACK_FOUND)
set(WITH_JACK OFF)
endif()
@@ -660,22 +683,15 @@ if(UNIX AND NOT APPLE)
# Codecs
if(WITH_CODEC_SNDFILE)
- find_package(SndFile)
+ find_package_wrapper(SndFile)
if(NOT SNDFILE_FOUND)
set(WITH_CODEC_SNDFILE OFF)
endif()
endif()
if(WITH_CODEC_FFMPEG)
- # use lib dir if available and nothing else specified
- if(LIBDIR AND NOT FFMPEG)
- set(FFMPEG ${LIBDIR}/ffmpeg CACHE PATH "FFMPEG Directory")
- # XXX, some distros might need 'theoraenc theoradec' too
- set(FFMPEG_LIBRARIES avformat avcodec avutil avdevice swscale dirac_encoder mp3lame ogg orc-0.4 schroedinger-1.0 theora vorbis vorbisenc vpx x264 xvidcore faad asound CACHE STRING "FFMPEG Libraries")
- else()
- set(FFMPEG /usr CACHE PATH "FFMPEG Directory")
- set(FFMPEG_LIBRARIES avformat avcodec avutil avdevice swscale CACHE STRING "FFMPEG Libraries")
- endif()
+ set(FFMPEG /usr CACHE PATH "FFMPEG Directory")
+ set(FFMPEG_LIBRARIES avformat avcodec avutil avdevice swscale CACHE STRING "FFMPEG Libraries")
mark_as_advanced(FFMPEG)
@@ -691,54 +707,32 @@ if(UNIX AND NOT APPLE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D__STDC_CONSTANT_MACROS")
endif()
- if(WITH_INTERNATIONAL)
- find_library(INTL_LIBRARY
- NAMES intl
- PATHS
- /sw/lib
- )
-
- find_library(ICONV_LIBRARY
- NAMES iconv
- PATHS
- /sw/lib
- )
- mark_as_advanced(
- ICONV_LIBRARY
- INTL_LIBRARY
- )
-
- if(INTL_LIBRARY AND ICONV_LIBRARY)
- set(GETTEXT_LIBRARIES ${INTL_LIBRARY} ${ICONV_LIBRARY})
- endif()
- endif()
-
if(WITH_FFTW3)
- find_package(Fftw3)
+ find_package_wrapper(Fftw3)
if(NOT FFTW3_FOUND)
set(WITH_FFTW3 OFF)
endif()
endif()
if(WITH_OPENCOLLADA)
- find_package(OpenCOLLADA)
+ find_package_wrapper(OpenCOLLADA)
if(OPENCOLLADA_FOUND)
- find_package(XML2)
- find_package(PCRE)
+ find_package_wrapper(XML2)
+ find_package_wrapper(PCRE)
else()
set(WITH_OPENCOLLADA OFF)
endif()
endif()
if(WITH_MEM_JEMALLOC)
- find_package(JeMalloc)
+ find_package_wrapper(JeMalloc)
if(NOT JEMALLOC_FOUND)
set(WITH_MEM_JEMALLOC OFF)
endif()
endif()
if (WITH_INPUT_NDOF)
- find_package(Spacenav)
+ find_package_wrapper(Spacenav)
if(NOT SPACENAV_FOUND)
set(WITH_INPUT_NDOF OFF)
endif()
@@ -753,14 +747,23 @@ if(UNIX AND NOT APPLE)
if(WITH_BOOST)
# uses in build instructions to override include and library variables
if(NOT BOOST_CUSTOM)
- # use lib dir if available and nothing else specified
- if(LIBDIR AND NOT BOOST_ROOT)
- set(BOOST_ROOT ${LIBDIR}/boost)
+ # XXX No more lib dir, is this multithread stuff still needed?
+ if(${WITH_STATIC_LIBS})
+ set(Boost_USE_STATIC_LIBS ON)
+ endif()
+ if(NOT BOOST_ROOT)
set(Boost_USE_MULTITHREADED OFF)
else()
set(Boost_USE_MULTITHREADED ON)
endif()
- find_package(Boost 1.34 COMPONENTS filesystem regex system thread)
+ set(__boost_packages filesystem regex system thread date_time)
+ if (WITH_INTERNATIONAL)
+ list(APPEND __boost_packages locale)
+ endif()
+ find_package(Boost 1.34 COMPONENTS ${__boost_packages})
+ if(Boost_USE_STATIC_LIBS AND Boost_USE_ICU)
+ find_package(IcuLinux)
+ endif()
mark_as_advanced(Boost_DIR) # why doesnt boost do this?
endif()
@@ -771,12 +774,7 @@ if(UNIX AND NOT APPLE)
endif()
if(WITH_OPENIMAGEIO)
- # use lib dir if available and nothing else specified
- if(LIBDIR AND NOT OPENIMAGEIO_ROOT_DIR)
- set(OPENIMAGEIO_ROOT_DIR ${LIBDIR}/oiio)
- endif()
-
- find_package(OpenImageIO)
+ find_package_wrapper(OpenImageIO)
set(OPENIMAGEIO_LIBRARIES ${OPENIMAGEIO_LIBRARIES} ${PNG_LIBRARIES} ${JPEG_LIBRARIES} ${ZLIB_LIBRARIES} ${BOOST_LIBRARIES})
set(OPENIMAGEIO_LIBPATH) # TODO, remove and reference the absolute path everywhere
@@ -796,12 +794,7 @@ if(UNIX AND NOT APPLE)
endif()
if(WITH_OPENCOLORIO)
- # use lib dir if available and nothing else specified
- if(LIBDIR AND NOT OPENCOLORIO_ROOT_DIR)
- set(OPENCOLORIO_ROOT_DIR ${LIBDIR}/ocio)
- endif()
-
- find_package(OpenColorIO)
+ find_package_wrapper(OpenColorIO)
set(OPENCOLORIO_LIBRARIES ${OPENCOLORIO_LIBRARIES})
set(OPENCOLORIO_LIBPATH) # TODO, remove and reference the absolute path everywhere
@@ -813,14 +806,23 @@ if(UNIX AND NOT APPLE)
endif()
endif()
+ # XXX Maybe most of this section should go into an llvm module?
if(WITH_LLVM)
- set(LLVM_DIRECTORY ${LIBDIR}/llvm CACHE PATH "Path to the LLVM installation")
- set(LLVM_VERSION "3.0" CACHE STRING "Version of LLVM to use")
+ # Set llvm version if not specified
+ if(NOT LLVM_VERSION)
+ set(LLVM_VERSION "3.0")
+ endif()
set(LLVM_STATIC YES)
- if(EXISTS "${LLVM_DIRECTORY}/bin/llvm-config")
- set(LLVM_CONFIG "${LLVM_DIRECTORY}/bin/llvm-config")
+ if(LLVM_DIRECTORY)
+ FIND_PROGRAM(LLVM_CONFIG llvm-config-${LLVM_VERSION} HINTS ${LLVM_DIRECTORY}/bin NO_CMAKE_PATH)
+ if(NOT LLVM_CONFIG)
+ FIND_PROGRAM(LLVM_CONFIG llvm-config HINTS ${LLVM_DIRECTORY}/bin NO_CMAKE_PATH)
+ endif()
else()
- set(LLVM_CONFIG llvm-config)
+ FIND_PROGRAM(LLVM_CONFIG llvm-config-${LLVM_VERSION})
+ if(NOT LLVM_CONFIG)
+ FIND_PROGRAM(LLVM_CONFIG llvm-config)
+ endif()
endif()
execute_process(COMMAND ${LLVM_CONFIG} --version
OUTPUT_VARIABLE LLVM_VERSION
@@ -837,6 +839,8 @@ if(UNIX AND NOT APPLE)
message(STATUS "LLVM version = ${LLVM_VERSION}")
message(STATUS "LLVM dir = ${LLVM_DIRECTORY}")
message(STATUS "LLVM lib dir = ${LLVM_LIB_DIR}")
+ set(LLVM_VERSION ${LLVM_VERSION} CACHE STRING "Version of LLVM to use")
+ set(LLVM_DIRECTORY ${LLVM_DIRECTORY} CACHE PATH "Path to the LLVM installation")
if(LLVM_LIBRARY AND LLVM_DIRECTORY AND LLVM_LIB_DIR)
if(LLVM_STATIC)
@@ -852,6 +856,9 @@ if(UNIX AND NOT APPLE)
else()
message(FATAL_ERROR "LLVM not found.")
endif()
+
+ # Fix for conflict with Mesa llvmpipe
+ set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -Wl,--version-script=${CMAKE_SOURCE_DIR}/source/creator/blender.map")
endif()
if(WITH_CYCLES_OSL)
@@ -924,7 +931,7 @@ if(UNIX AND NOT APPLE)
if(WITH_ANDROID)
set(PLATFORM_LINKFLAGS "-lGLESv1_CM")
else()
- set(PLATFORM_LINKFLAGS "-pthread")
+ set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -pthread")
endif()
@@ -990,13 +997,6 @@ elseif(WIN32)
add_definitions(-DWIN32)
- if(WITH_INTERNATIONAL)
- set(ICONV ${LIBDIR}/iconv)
- set(ICONV_INCLUDE_DIRS ${ICONV}/include)
- set(ICONV_LIBRARIES iconv)
- set(ICONV_LIBPATH ${ICONV}/lib)
- endif()
-
set(JPEG "${LIBDIR}/jpeg")
set(JPEG_INCLUDE_DIR "${JPEG}/include")
set(JPEG_LIBPATH ${JPEG}/lib) # not cmake defined
@@ -1043,7 +1043,6 @@ elseif(WIN32)
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)
- # WARNING! depends on correct order of OSL libs linking
list(APPEND OSL_LIBRARIES ${OSL_LIB_COMP} ${OSL_LIB_EXEC} ${OSL_LIB_QUERY})
find_path(OSL_INCLUDES OSL/oslclosure.h PATHS ${CYCLES_OSL}/include)
find_program(OSL_COMPILER NAMES oslc PATHS ${CYCLES_OSL}/bin)
@@ -1058,8 +1057,15 @@ elseif(WIN32)
endif()
endif()
+ if(WITH_LLVM)
+ set(LLVM_DIRECTORY ${LIBDIR}/llvm CACHE PATH "Path to the LLVM installation")
+ file(GLOB LLVM_LIBRARY ${LLVM_DIRECTORY}/lib/*.lib)
+ set(LLVM_STATIC YES)
+ endif()
+
+
if(MSVC)
- set(PLATFORM_LINKLIBS ws2_32 vfw32 winmm kernel32 user32 gdi32 comdlg32 advapi32 shfolder shell32 ole32 oleaut32 uuid)
+ set(PLATFORM_LINKLIBS ws2_32 vfw32 winmm kernel32 user32 gdi32 comdlg32 advapi32 shfolder shell32 ole32 oleaut32 uuid psapi)
add_definitions(/D_CRT_NONSTDC_NO_DEPRECATE /D_CRT_SECURE_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /D_CONSOLE /D_LIB)
@@ -1089,13 +1095,6 @@ elseif(WIN32)
set(CXX_WARNINGS "${_WARNINGS}")
unset(_WARNINGS)
- if(WITH_INTERNATIONAL)
- set(GETTEXT ${LIBDIR}/gettext)
- set(GETTEXT_INCLUDE_DIRS ${GETTEXT}/include)
- set(GETTEXT_LIBPATH ${GETTEXT}/lib)
- set(GETTEXT_LIBRARIES gnu_gettext)
- endif()
-
if(WITH_MOD_CLOTH_ELTOPO)
set(LAPACK ${LIBDIR}/lapack)
# set(LAPACK_INCLUDE_DIR ${LAPACK}/include)
@@ -1187,6 +1186,7 @@ elseif(WIN32)
if(WITH_IMAGE_OPENEXR)
set_lib_path(OPENEXR "openexr")
set(OPENEXR_INCLUDE_DIR ${OPENEXR}/include)
+ set(OPENEXR_INCLUDE_DIRS ${OPENEXR}/include/OpenEXR)
set(OPENEXR_LIBPATH ${OPENEXR}/lib)
set(OPENEXR_LIBRARIES
${OPENEXR_LIBPATH}/Iex.lib
@@ -1195,12 +1195,6 @@ elseif(WIN32)
${OPENEXR_LIBPATH}/Imath.lib
${OPENEXR_LIBPATH}/IlmThread.lib
)
- set(OPENEXR_INCLUDE_DIRS
- ${OPENEXR_INCLUDE_DIR}
- ${OPENEXR_INCLUDE_DIR}/IlmImf
- ${OPENEXR_INCLUDE_DIR}/Iex
- ${OPENEXR_INCLUDE_DIR}/Imath
- )
endif()
if(WITH_IMAGE_TIFF)
@@ -1248,15 +1242,20 @@ elseif(WIN32)
debug libboost_date_time-${BOOST_DEBUG_POSTFIX} debug libboost_filesystem-${BOOST_DEBUG_POSTFIX}
debug libboost_regex-${BOOST_DEBUG_POSTFIX}
debug libboost_system-${BOOST_DEBUG_POSTFIX} debug libboost_thread-${BOOST_DEBUG_POSTFIX})
+ if(WITH_INTERNATIONAL)
+ set(BOOST_LIBRARIES ${BOOST_LIBRARIES}
+ optimized libboost_locale-${BOOST_POSTFIX}
+ debug libboost_locale-${BOOST_DEBUG_POSTFIX})
+ endif(WITH_INTERNATIONAL)
set(BOOST_DEFINITIONS "-DBOOST_ALL_NO_LIB")
endif()
if(WITH_OPENIMAGEIO)
set(OPENIMAGEIO ${LIBDIR}/openimageio)
set(OPENIMAGEIO_INCLUDE_DIRS ${OPENIMAGEIO}/include)
- set(OPENIMAGEIO_LIBRARIES OpenImageIO)
+ set(OPENIMAGEIO_LIBRARIES optimized OpenImageIO debug OpenImageIO_d)
set(OPENIMAGEIO_LIBPATH ${OPENIMAGEIO}/lib)
- set(OPENIMAGEIO_DEFINITIONS)
+ set(OPENIMAGEIO_DEFINITIONS "-DUSE_TBB=0")
endif()
if(WITH_OPENCOLORIO)
@@ -1267,6 +1266,7 @@ elseif(WIN32)
set(OPENCOLORIO_DEFINITIONS)
endif()
+
set(PLATFORM_LINKFLAGS "/SUBSYSTEM:CONSOLE /STACK:2097152 /INCREMENTAL:NO /NODEFAULTLIB:msvcrt.lib /NODEFAULTLIB:msvcmrt.lib /NODEFAULTLIB:msvcurt.lib /NODEFAULTLIB:msvcrtd.lib")
# MSVC only, Mingw doesnt need
@@ -1301,16 +1301,8 @@ elseif(WIN32)
add_definitions(-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE)
-
add_definitions(-DFREE_WINDOWS)
- if(WITH_INTERNATIONAL)
- set(GETTEXT ${LIBDIR}/gettext)
- set(GETTEXT_INCLUDE_DIRS ${GETTEXT}/include)
- set(GETTEXT_LIBPATH ${GETTEXT}/lib)
- set(GETTEXT_LIBRARIES intl)
- endif()
-
set(PNG "${LIBDIR}/png")
set(PNG_INCLUDE_DIR "${PNG}/include")
set(PNG_LIBPATH ${PNG}/lib) # not cmake defined
@@ -1428,6 +1420,11 @@ elseif(WIN32)
debug boost_date_time-${BOOST_DEBUG_POSTFIX} boost_filesystem-${BOOST_DEBUG_POSTFIX}
boost_regex-${BOOST_DEBUG_POSTFIX}
boost_system-${BOOST_DEBUG_POSTFIX} boost_thread-${BOOST_DEBUG_POSTFIX})
+ if(WITH_INTERNATIONAL)
+ set(BOOST_LIBRARIES ${BOOST_LIBRARIES}
+ optimized boost_locale-${BOOST_POSTFIX}
+ debug boost_locale-${BOOST_DEBUG_POSTFIX})
+ endif()
set(BOOST_LIBPATH ${BOOST}/lib)
set(BOOST_DEFINITIONS "-DBOOST_ALL_NO_LIB -DBOOST_THREAD_USE_LIB ")
endif()
@@ -1462,16 +1459,6 @@ elseif(APPLE)
set(WITH_LIBS10.5 ON CACHE BOOL "Use 10.5 libs" FORCE) # valid also for 10.6/10.7
endif()
- if(${XCODE_VERSION} VERSION_LESS 4.3)
- set(CMAKE_OSX_SYSROOT /Developer/SDKs/MacOSX${OSX_SYSTEM}.sdk CACHE PATH "" FORCE) # use guaranteed existing sdk
- else()
- # note: i don't use xcode-select path on purpose, cause also /Applications/Xcode.app would be allowed
- # absolute pathes are more foolproof here !
- set(OSX_SYSROOT_PREFIX /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform)
- set(OSX_DEVELOPER_PREFIX /Developer/SDKs/MacOSX${OSX_SYSTEM}.sdk) # use guaranteed existing sdk
- set(CMAKE_OSX_SYSROOT ${OSX_SYSROOT_PREFIX}/${OSX_DEVELOPER_PREFIX} CACHE PATH "" FORCE)
- endif()
-
if(WITH_LIBS10.5)
set(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/darwin-9.x.universal)
else()
@@ -1512,13 +1499,13 @@ elseif(APPLE)
if(WITH_PYTHON)
if(NOT WITH_PYTHON_MODULE)
- # we use precompiled libraries for py 3.2 and up by default
+ # we use precompiled libraries for py 3.3 and up by default
# normally cached but not since we include them with blender
- set(PYTHON_VERSION 3.2)
- set(PYTHON_INCLUDE_DIR "${LIBDIR}/python/include/python${PYTHON_VERSION}")
+ set(PYTHON_VERSION 3.3)
+ set(PYTHON_INCLUDE_DIR "${LIBDIR}/python/include/python${PYTHON_VERSION}m")
# set(PYTHON_BINARY "${LIBDIR}/python/bin/python${PYTHON_VERSION}") # not used yet
- set(PYTHON_LIBRARY python${PYTHON_VERSION})
+ set(PYTHON_LIBRARY python${PYTHON_VERSION}m)
set(PYTHON_LIBPATH "${LIBDIR}/python/lib/python${PYTHON_VERSION}")
# set(PYTHON_LINKFLAGS "-u _PyMac_Error") # won't build with this enabled
else()
@@ -1538,13 +1525,6 @@ elseif(APPLE)
set(PYTHON_LIBRARIES "${PYTHON_LIBRARY}")
endif()
- if(WITH_INTERNATIONAL)
- set(GETTEXT ${LIBDIR}/gettext)
- set(GETTEXT_INCLUDE_DIRS "${GETTEXT}/include")
- set(GETTEXT_LIBRARIES intl iconv)
- set(GETTEXT_LIBPATH ${GETTEXT}/lib)
- endif()
-
if(WITH_FFTW3)
set(FFTW3 ${LIBDIR}/fftw3)
set(FFTW3_INCLUDE_DIRS ${FFTW3}/include)
@@ -1622,11 +1602,11 @@ elseif(APPLE)
set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -weak_framework 3DconnexionClient")
endif()
endif()
-
+
if(WITH_JACK)
set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -weak_framework jackmp")
endif()
-
+
else()
set(PLATFORM_CFLAGS "-pipe -funsigned-char")
set(PLATFORM_LINKFLAGS "-fexceptions -framework CoreServices -framework Foundation -framework IOKit -framework AppKit -framework Carbon -framework AGL -framework AudioUnit -framework AudioToolbox -framework CoreAudio -framework QuickTime")
@@ -1689,7 +1669,11 @@ elseif(APPLE)
if(WITH_BOOST)
set(BOOST ${LIBDIR}/boost)
set(BOOST_INCLUDE_DIR ${BOOST}/include)
- set(BOOST_LIBRARIES boost_date_time-mt boost_filesystem-mt boost_regex-mt boost_system-mt boost_thread-mt)
+ set(BOOST_LIBRARIES boost_date_time-mt boost_filesystem-mt boost_regex-mt boost_system-mt boost_thread-mt boost_wave-mt)
+ if (WITH_INTERNATIONAL)
+ list(APPEND BOOST_LIBRARIES boost_locale-mt)
+ set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -liconv") # boost_locale needs it !
+ endif()
set(BOOST_LIBPATH ${BOOST}/lib)
set(BOOST_DEFINITIONS)
endif()
@@ -1815,6 +1799,11 @@ if(WITH_CYCLES)
endif()
endif()
+if(WITH_INTERNATIONAL)
+ if(NOT WITH_BOOST)
+ message(FATAL_ERROR "Internationalization reqires WITH_BOOST, the library may not have been found. Configure BOOST or disable WITH_INTERNATIONAL")
+ endif()
+endif()
# See TEST_SSE_SUPPORT() for how this is defined.
diff --git a/GNUmakefile b/GNUmakefile
index f8207787cbe..c1b67c86ed2 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -173,14 +173,15 @@ help:
@echo " * test_style_osl_qtc - checks OpenShadingLanguage conforms with blenders style guide: http://wiki.blender.org/index.php/Dev:Doc/CodeStyle"
@echo ""
@echo "Static Source Code Checking (not associated with building blender)"
- @echo " * check_cppcheck - run blender source through cppcheck (C & C++)"
- @echo " * check_clang_array - run blender source through clang array checking script (C & C++)"
- @echo " * check_splint - run blenders source through splint (C only)"
- @echo " * check_sparse - run blenders source through sparse (C only)"
- @echo " * check_smatch - run blenders source through smatch (C only)"
- @echo " * check_spelling_c - check for spelling errors (OSL only)"
- @echo " * check_spelling_osl - check for spelling errors (C/C++ only)"
- @echo " * check_spelling_py - check for spelling errors (Python only)"
+ @echo " * check_cppcheck - run blender source through cppcheck (C & C++)"
+ @echo " * check_clang_array - run blender source through clang array checking script (C & C++)"
+ @echo " * check_splint - run blenders source through splint (C only)"
+ @echo " * check_sparse - run blenders source through sparse (C only)"
+ @echo " * check_smatch - run blenders source through smatch (C only)"
+ @echo " * check_spelling_c - check for spelling errors (OSL only)"
+ @echo " * check_spelling_c_qtc - same as check_spelling_c but outputs QtCreator tasks format"
+ @echo " * check_spelling_osl - check for spelling errors (C/C++ only)"
+ @echo " * check_spelling_py - check for spelling errors (Python only)"
@echo ""
@echo "Utilities (not associated with building blender)"
@echo " * tbz - create a compressed svn export 'blender_archive.tar.bz2'"
@@ -240,13 +241,13 @@ test_style_c_qtc:
test_style_osl:
# run our own checks on C/C++ style
- PYTHONIOENCODING=utf_8 python3 $(BLENDER_DIR)/source/tools/check_style_c.py $(BLENDER_DIR)/intern/cycles/kernel/osl
+ PYTHONIOENCODING=utf_8 python3 $(BLENDER_DIR)/source/tools/check_style_c.py $(BLENDER_DIR)/intern/cycles/kernel/shaders
test_style_osl_qtc:
# run our own checks on C/C++ style
USE_QTC_TASK=1 \
- PYTHONIOENCODING=utf_8 python3 $(BLENDER_DIR)/source/tools/check_style_c.py $(BLENDER_DIR)/intern/cycles/kernel/osl > \
+ PYTHONIOENCODING=utf_8 python3 $(BLENDER_DIR)/source/tools/check_style_c.py $(BLENDER_DIR)/intern/cycles/kernel/shaders > \
test_style.tasks
@echo "written: test_style.tasks"
@@ -270,32 +271,44 @@ project_eclipse:
check_cppcheck:
$(CMAKE_CONFIG)
- cd $(BUILD_DIR) ; python3 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_cppcheck.py
+ cd $(BUILD_DIR) ; \
+ python3 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_cppcheck.py
check_clang_array:
$(CMAKE_CONFIG)
- cd $(BUILD_DIR) ; python3 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_clang_array.py
+ cd $(BUILD_DIR) ; \
+ python3 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_clang_array.py
check_splint:
$(CMAKE_CONFIG)
- cd $(BUILD_DIR) ; python3 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_splint.py
+ cd $(BUILD_DIR) ; \
+ python3 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_splint.py
check_sparse:
$(CMAKE_CONFIG)
- cd $(BUILD_DIR) ; python3 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_sparse.py
+ cd $(BUILD_DIR) ; \
+ python3 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_sparse.py
check_smatch:
$(CMAKE_CONFIG)
- cd $(BUILD_DIR) ; python3 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_smatch.py
+ cd $(BUILD_DIR) ; \
+ python3 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_smatch.py
check_spelling_py:
- cd $(BUILD_DIR) ; PYTHONIOENCODING=utf_8 python3 $(BLENDER_DIR)/source/tools/spell_check_source.py $(BLENDER_DIR)/release/scripts
+ cd $(BUILD_DIR) ; \
+ PYTHONIOENCODING=utf_8 python3 $(BLENDER_DIR)/source/tools/spell_check_source.py $(BLENDER_DIR)/release/scripts
check_spelling_c:
- cd $(BUILD_DIR) ; PYTHONIOENCODING=utf_8 python3 $(BLENDER_DIR)/source/tools/spell_check_source.py $(BLENDER_DIR)/source
+ cd $(BUILD_DIR) ; \
+ PYTHONIOENCODING=utf_8 python3 $(BLENDER_DIR)/source/tools/spell_check_source.py $(BLENDER_DIR)/source
+
+check_spelling_c_qtc:
+ cd $(BUILD_DIR) ; USE_QTC_TASK=1 \
+ PYTHONIOENCODING=utf_8 python3 $(BLENDER_DIR)/source/tools/spell_check_source.py $(BLENDER_DIR)/source > \
+ $(BLENDER_DIR)/check_spelling_c.tasks
check_spelling_osl:
- cd $(BUILD_DIR) ; PYTHONIOENCODING=utf_8 python3 $(BLENDER_DIR)/source/tools/spell_check_source.py $(BLENDER_DIR)/intern/cycles/kernel/osl
+ cd $(BUILD_DIR) ; PYTHONIOENCODING=utf_8 python3 $(BLENDER_DIR)/source/tools/spell_check_source.py $(BLENDER_DIR)/intern/cycles/kernel/shaders
# -----------------------------------------------------------------------------
# Utilities
diff --git a/SConstruct b/SConstruct
index 064ae0bc0b5..5a1797ec1dc 100644
--- a/SConstruct
+++ b/SConstruct
@@ -306,6 +306,12 @@ if env['OURPLATFORM']=='darwin':
else:
env.Append(LINKFLAGS=['-Xlinker','-weak_framework','-Xlinker','Jackmp'])
+ if env['WITH_BF_CYCLES_OSL'] == 1:
+ OSX_OSL_LIBPATH = Dir(env.subst(env['BF_OSL_LIBPATH'])).abspath
+ # we need 2 variants of passing the oslexec with the force_load option, string and list type atm
+ 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'])
+
if env['WITH_BF_OPENMP'] == 1:
if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
env['CCFLAGS'].append('/openmp')
@@ -422,16 +428,22 @@ if not quickie and do_clean:
# with _any_ library but since we used a fixed python version this tends to
# be most problematic.
if env['WITH_BF_PYTHON']:
- py_h = os.path.join(Dir(env.subst('${BF_PYTHON_INC}')).abspath, "Python.h")
-
- if not os.path.exists(py_h):
- print("\nMissing: \"" + env.subst('${BF_PYTHON_INC}') + os.sep + "Python.h\",\n"
+ found_python_h = found_pyconfig_h = False
+ for bf_python_inc in env.subst('${BF_PYTHON_INC}').split():
+ py_h = os.path.join(Dir(bf_python_inc).abspath, "Python.h")
+ if os.path.exists(py_h):
+ found_python_h = True
+ py_h = os.path.join(Dir(bf_python_inc).abspath, "pyconfig.h")
+ if os.path.exists(py_h):
+ found_pyconfig_h = True
+
+ if not (found_python_h and found_pyconfig_h):
+ print("\nMissing: Python.h and/or pyconfig.h in\"" + env.subst('${BF_PYTHON_INC}') + "\",\n"
" Set 'BF_PYTHON_INC' to point "
- "to a valid python include path.\n Containing "
- "Python.h for python version \"" + env.subst('${BF_PYTHON_VERSION}') + "\"")
+ "to valid python include path(s).\n Containing "
+ "Python.h and pyconfig.h for python version \"" + env.subst('${BF_PYTHON_VERSION}') + "\"")
Exit()
- del py_h
if not os.path.isdir ( B.root_build_dir):
@@ -571,11 +583,11 @@ B.init_lib_dict()
Export('env')
-BuildDir(B.root_build_dir+'/source', 'source', duplicate=0)
+VariantDir(B.root_build_dir+'/source', 'source', duplicate=0)
SConscript(B.root_build_dir+'/source/SConscript')
-BuildDir(B.root_build_dir+'/intern', 'intern', duplicate=0)
+VariantDir(B.root_build_dir+'/intern', 'intern', duplicate=0)
SConscript(B.root_build_dir+'/intern/SConscript')
-BuildDir(B.root_build_dir+'/extern', 'extern', duplicate=0)
+VariantDir(B.root_build_dir+'/extern', 'extern', duplicate=0)
SConscript(B.root_build_dir+'/extern/SConscript')
# now that we have read all SConscripts, we know what
@@ -719,6 +731,22 @@ if env['OURPLATFORM']!='darwin':
cubin_file = os.path.join(kernel_build_dir, "kernel_%s.cubin" % arch)
scriptinstall.append(env.Install(dir=dir,source=cubin_file))
+ # osl shaders
+ if env['WITH_BF_CYCLES_OSL']:
+ dir=os.path.join(env['BF_INSTALLDIR'], VERSION, 'scripts', 'addons','cycles', 'shader')
+
+ osl_source_dir = Dir('./intern/cycles/kernel/shaders').srcnode().path
+ oso_build_dir = os.path.join(B.root_build_dir, 'intern/cycles/kernel/shaders')
+
+ headers='node_color.h node_fresnel.h node_texture.h oslutil.h stdosl.h'.split()
+ source=['intern/cycles/kernel/shaders/'+s for s in headers]
+ scriptinstall.append(env.Install(dir=dir,source=source))
+
+ for f in os.listdir(osl_source_dir):
+ if f.endswith('.osl'):
+ oso_file = os.path.join(oso_build_dir, f.replace('.osl', '.oso'))
+ scriptinstall.append(env.Install(dir=dir,source=oso_file))
+
if env['WITH_BF_OCIO']:
colormanagement = os.path.join('release', 'datafiles', 'colormanagement')
@@ -819,10 +847,6 @@ else:
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'win64-vc', 'linuxcross'):
dllsources = []
- if not env['OURPLATFORM'] in ('win32-mingw', 'linuxcross'):
- # For MinGW and linuxcross static linking will be used
- dllsources += ['${LCGDIR}/gettext/lib/gnu_gettext.dll']
-
dllsources += ['${BF_ZLIB_LIBPATH}/zlib.dll']
# Used when linking to libtiff was dynamic
# keep it here until compilation on all platform would be ok
@@ -868,9 +892,6 @@ if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'win64-vc', 'linuxcross'):
dllsources.append('${LCGDIR}/thumbhandler/lib/BlendThumb.dll')
dllsources.append('${LCGDIR}/thumbhandler/lib/BlendThumb64.dll')
- if env['WITH_BF_OIIO'] and env['OURPLATFORM'] != 'win32-mingw':
- dllsources.append('${LCGDIR}/openimageio/bin/OpenImageIO.dll')
-
if env['WITH_BF_OCIO']:
if not env['OURPLATFORM'] in ('win32-mingw', 'linuxcross'):
dllsources.append('${LCGDIR}/opencolorio/bin/OpenColorIO.dll')
diff --git a/build_files/build_environment/install_deps.sh b/build_files/build_environment/install_deps.sh
new file mode 100755
index 00000000000..935f37b53da
--- /dev/null
+++ b/build_files/build_environment/install_deps.sh
@@ -0,0 +1,1415 @@
+#!/bin/bash
+
+DISTRO=""
+SRC="$HOME/src/blender-deps"
+INST="/opt/lib"
+CWD=$PWD
+
+# OSL is horror for manual building even
+# i would want it to be setteled for manual build first,
+# and only then do it automatically
+BUILD_OSL=false
+
+# Try to link everything statically. Use this to produce protable versions of blender.
+ALL_STATIC=false
+
+THREADS=`cat /proc/cpuinfo | grep cores | uniq | sed -e "s/.*: *\(.*\)/\\1/"`
+if [ -z "$THREADS" ]; then
+ THREADS=1
+fi
+
+COMMON_INFO="Source code of dependencies needed to be compiled will be downloaded and extracted into '$SRC'.
+Built libs of dependencies needed to be compiled will be installed into '$INST'.
+Please edit \$SRC and/or \$INST variables at the begining of this script if you want to use other paths!
+
+Number of threads for building: $THREADS.
+Building OSL: $BUILD_OSL (edit \$BUILD_OSL var to change this).
+All static linking: $ALL_STATIC (edit \$ALL_STATIC var to change this)."
+
+
+PYTHON_VERSION="3.3.0"
+PYTHON_VERSION_MIN="3.3"
+PYTHON_SOURCE="http://python.org/ftp/python/$PYTHON_VERSION/Python-$PYTHON_VERSION.tar.bz2"
+
+BOOST_VERSION="1.51.0"
+_boost_version_nodots=`echo "$BOOST_VERSION" | sed -r 's/\./_/g'`
+BOOST_SOURCE="http://sourceforge.net/projects/boost/files/boost/$BOOST_VERSION/boost_$_boost_version_nodots.tar.bz2/download"
+BOOST_VERSION_MIN="1.49"
+
+OCIO_VERSION="1.0.7"
+OCIO_SOURCE="https://github.com/imageworks/OpenColorIO/tarball/v$OCIO_VERSION"
+OCIO_VERSION_MIN="1.0"
+
+OIIO_VERSION="1.1.1"
+OIIO_SOURCE="https://github.com/OpenImageIO/oiio/tarball/Release-$OIIO_VERSION"
+OIIO_VERSION_MIN="1.1"
+
+LLVM_VERSION="3.1"
+LLVM_VERSION_MIN="3.0"
+LLVM_VERSION_FOUND=""
+LLVM_SOURCE="http://llvm.org/releases/$LLVM_VERSION/llvm-$LLVM_VERSION.src.tar.gz"
+LLVM_CLANG_SOURCE="http://llvm.org/releases/$LLVM_VERSION/clang-$LLVM_VERSION.src.tar.gz"
+
+# OSL needs to be compiled for now!
+OSL_VERSION="1.2.0"
+OSL_SOURCE="https://github.com/mont29/OpenShadingLanguage/archive/blender-fixes.tar.gz"
+
+FFMPEG_VERSION="1.0"
+FFMPEG_SOURCE="http://ffmpeg.org/releases/ffmpeg-$FFMPEG_VERSION.tar.bz2"
+FFMPEG_VERSION_MIN="0.7.6"
+_ffmpeg_list_sep=";"
+
+# FFMPEG optional libs.
+VORBIS_USE=false
+VORBIS_DEV=""
+SCHRO_USE=false
+SCRHO_DEV=""
+THEORA_USE=false
+THEORA_DEV=""
+XVID_USE=false
+XVID_DEV=""
+X264_USE=false
+X264_DEV=""
+X264_VERSION_MIN=0.118
+VPX_USE=false
+VPX_VERSION_MIN=0.9.7
+VPX_DEV=""
+MP3LAME_USE=false
+MP3LAME_DEV=""
+OPENJPEG_USE=false
+OPENJPEG_DEV=""
+
+# Switch to english language, else some things (like check_package_DEB()) won't work!
+LANG_BACK=$LANG
+LANG=""
+export LANG
+
+ERROR() {
+ echo "${@}"
+}
+
+INFO() {
+ echo "${@}"
+}
+
+# Return 0 if $1 = $2 (i.e. 1.01.0 = 1.1, but 1.1.1 != 1.1), else 1.
+# $1 and $2 should be version numbers made of numbers only.
+version_eq() {
+ backIFS=$IFS
+ IFS='.'
+
+ # Split both version numbers into their numeric elements.
+ arr1=( $1 )
+ arr2=( $2 )
+
+ ret=1
+
+ count1=${#arr1[@]}
+ count2=${#arr2[@]}
+ if [ $count2 -ge $count1 ]; then
+ _t=$count1
+ count1=$count2
+ count2=$_t
+ arr1=( $2 )
+ arr2=( $1 )
+ fi
+
+ ret=0
+ for (( i=0; $i < $count2; i++ ))
+ do
+ if [ $(( 10#${arr1[$i]} )) -ne $(( 10#${arr2[$i]} )) ]; then
+ ret=1
+ break
+ fi
+ done
+
+ for (( i=$count2; $i < $count1; i++ ))
+ do
+ if [ $(( 10#${arr1[$i]} )) -ne 0 ]; then
+ ret=1
+ break
+ fi
+ done
+
+ IFS=$backIFS
+ return $ret
+}
+
+# Return 0 if $1 >= $2, else 1.
+# $1 and $2 should be version numbers made of numbers only.
+version_ge() {
+ version_eq $1 $2
+ if [ $? -eq 1 -a $(echo -e "$1\n$2" | sort --version-sort | head --lines=1) = "$1" ]; then
+ return 1
+ else
+ return 0
+ fi
+}
+
+# Return 0 if $1 is into $2 (e.g. 3.3.2 is into 3.3, but not 3.3.0 or 3.3.5), else 1.
+# $1 and $2 should be version numbers made of numbers only.
+# $1 should be at least as long as $2!
+version_match() {
+ backIFS=$IFS
+ IFS='.'
+
+ # Split both version numbers into their numeric elements.
+ arr1=( $1 )
+ arr2=( $2 )
+
+ ret=1
+
+ count1=${#arr1[@]}
+ count2=${#arr2[@]}
+ if [ $count1 -ge $count2 ]; then
+ ret=0
+ for (( i=0; $i < $count2; i++ ))
+ do
+ if [ $(( 10#${arr1[$i]} )) -ne $(( 10#${arr2[$i]} )) ]; then
+ ret=1
+ break
+ fi
+ done
+ fi
+
+ IFS=$backIFS
+ return $ret
+}
+
+detect_distro() {
+ if [ -f /etc/debian_version ]; then
+ DISTRO="DEB"
+ elif [ -f /etc/redhat-release ]; then
+ DISTRO="RPM"
+ elif [ -f /etc/SuSE-release ]; then
+ DISTRO="SUSE"
+ fi
+}
+
+prepare_opt() {
+ INFO "Ensuring $INST exists and is writable by us"
+ sudo mkdir -p $INST
+ sudo chown $USER $INST
+ sudo chmod 775 $INST
+}
+
+# Check whether the current package needs to be recompiled, based on a dummy file containing a magic number in its name...
+magic_compile_check() {
+ if [ -f $INST/.$1-magiccheck-$2 ]; then
+ return 0
+ else
+ return 1
+ fi
+}
+
+magic_compile_set() {
+ rm -f $INST/.$1-magiccheck-*
+ touch $INST/.$1-magiccheck-$2
+}
+
+compile_Python() {
+ # To be changed each time we make edits that would modify the compiled result!
+ py_magic=0
+
+ _src=$SRC/Python-$PYTHON_VERSION
+ _inst=$INST/python-$PYTHON_VERSION
+
+ # Clean install if needed!
+ magic_compile_check python-$PYTHON_VERSION $py_magic
+ if [ $? -eq 1 ]; then
+ rm -rf $_inst
+ fi
+
+ if [ ! -d $_inst ]; then
+ INFO "Building Python-$PYTHON_VERSION"
+
+ prepare_opt
+
+ if [ ! -d $_src ]; then
+ mkdir -p $SRC
+ wget -c $PYTHON_SOURCE -O $_src.tar.bz2
+
+ INFO "Unpacking Python-$PYTHON_VERSION"
+ tar -C $SRC -xf $_src.tar.bz2
+ fi
+
+ cd $_src
+
+ ./configure --prefix=$_inst --enable-ipv6 \
+ --enable-loadable-sqlite-extensions --with-dbmliborder=bdb \
+ --with-computed-gotos --with-pymalloc
+
+ make -j$THREADS && make install
+ make clean
+
+ if [ -d $_inst ]; then
+ rm -f $INST/python-3.3
+ ln -s python-$PYTHON_VERSION $INST/python-3.3
+ else
+ ERROR "Python--$PYTHON_VERSION failed to compile, exiting"
+ exit 1
+ fi
+
+ magic_compile_set python-$PYTHON_VERSION $py_magic
+
+ cd $CWD
+ else
+ INFO "Own Python-$PYTHON_VERSION is up to date, nothing to do!"
+ INFO "If you want to force rebuild of this lib, delete the '$_src' and '$_inst' directories."
+ fi
+}
+
+compile_Boost() {
+ # To be changed each time we make edits that would modify the compiled result!
+ boost_magic=7
+
+ _src=$SRC/boost-$BOOST_VERSION
+ _inst=$INST/boost-$BOOST_VERSION
+
+ # Clean install if needed!
+ magic_compile_check boost-$BOOST_VERSION $boost_magic
+ if [ $? -eq 1 ]; then
+ rm -rf $_inst
+ fi
+
+ if [ ! -d $_inst ]; then
+ INFO "Building Boost-$BOOST_VERSION"
+
+ prepare_opt
+
+ if [ ! -d $_src ]; then
+ INFO "Downloading Boost-$BOOST_VERSION"
+ mkdir -p $SRC
+ wget -c $BOOST_SOURCE -O $_src.tar.bz2
+ tar -C $SRC --transform "s,(.*/?)boost_1_[^/]+(.*),\1boost-$BOOST_VERSION\2,x" -xf $_src.tar.bz2
+ fi
+
+ cd $_src
+ if [ ! -f $_src/b2 ]; then
+ ./bootstrap.sh
+ fi
+ ./b2 -j$THREADS -a --with-system --with-filesystem --with-thread --with-regex --with-locale --with-date_time \
+ --prefix=$_inst --disable-icu boost.locale.icu=off install
+ ./b2 --clean
+
+ if [ -d $_inst ]; then
+ rm -f $INST/boost
+ ln -s boost-$BOOST_VERSION $INST/boost
+ else
+ ERROR "Boost-$BOOST_VERSION failed to compile, exiting"
+ exit 1
+ fi
+
+ magic_compile_set boost-$BOOST_VERSION $boost_magic
+
+ cd $CWD
+ else
+ INFO "Own Boost-$BOOST_VERSION is up to date, nothing to do!"
+ INFO "If you want to force rebuild of this lib, delete the '$_src' and '$_inst' directories."
+ fi
+}
+
+compile_OCIO() {
+ # To be changed each time we make edits that would modify the compiled result!
+ ocio_magic=1
+
+ _src=$SRC/OpenColorIO-$OCIO_VERSION
+ _inst=$INST/ocio-$OCIO_VERSION
+
+ # Clean install if needed!
+ magic_compile_check ocio-$OCIO_VERSION $ocio_magic
+ if [ $? -eq 1 ]; then
+ rm -rf $_inst
+ fi
+
+ if [ ! -d $_inst ]; then
+ INFO "Building OpenColorIO-$OCIO_VERSION"
+
+ prepare_opt
+
+ if [ ! -d $_src ]; then
+ INFO "Downloading OpenColorIO-$OCIO_VERSION"
+ mkdir -p $SRC
+ wget -c $OCIO_SOURCE -O $_src.tar.gz
+
+ INFO "Unpacking OpenColorIO-$OCIO_VERSION"
+ tar -C $SRC --transform "s,(.*/?)imageworks-OpenColorIO[^/]*(.*),\1OpenColorIO-$OCIO_VERSION\2,x" \
+ -xf $_src.tar.gz
+ fi
+
+ cd $_src
+ # Always refresh the whole build!
+ if [ -d build ]; then
+ rm -rf build
+ fi
+ mkdir build
+ cd build
+
+ if file /bin/cp | grep -q '32-bit'; then
+ cflags="-fPIC -m32 -march=i686"
+ else
+ cflags="-fPIC"
+ fi
+
+ cmake -D CMAKE_BUILD_TYPE=Release \
+ -D CMAKE_PREFIX_PATH=$_inst \
+ -D CMAKE_INSTALL_PREFIX=$_inst \
+ -D CMAKE_CXX_FLAGS="$cflags" \
+ -D CMAKE_EXE_LINKER_FLAGS="-lgcc_s -lgcc" \
+ -D OCIO_BUILD_APPS=OFF \
+ -D OCIO_BUILD_PYGLUE=OFF \
+ ..
+
+ make -j$THREADS && make install
+
+ # Force linking against static libs
+ rm -f $_inst/lib/*.so*
+
+ # Additional depencencies
+ cp ext/dist/lib/libtinyxml.a $_inst/lib
+ cp ext/dist/lib/libyaml-cpp.a $_inst/lib
+
+ make clean
+
+ if [ -d $_inst ]; then
+ rm -f $INST/ocio
+ ln -s ocio-$OCIO_VERSION $INST/ocio
+ else
+ ERROR "OpenColorIO-$OCIO_VERSION failed to compile, exiting"
+ exit 1
+ fi
+
+ magic_compile_set ocio-$OCIO_VERSION $ocio_magic
+
+ cd $CWD
+ else
+ INFO "Own OpenColorIO-$OCIO_VERSION is up to date, nothing to do!"
+ INFO "If you want to force rebuild of this lib, delete the '$_src' and '$_inst' directories."
+ fi
+}
+
+compile_OIIO() {
+ # To be changed each time we make edits that would modify the compiled result!
+ oiio_magic=6
+
+ _src=$SRC/OpenImageIO-$OIIO_VERSION
+ _inst=$INST/oiio-$OIIO_VERSION
+
+ # Clean install if needed!
+ magic_compile_check oiio-$OIIO_VERSION $oiio_magic
+ if [ $? -eq 1 ]; then
+ rm -rf $_inst
+ fi
+
+ if [ ! -d $_inst ]; then
+ INFO "Building OpenImageIO-$OIIO_VERSION"
+
+ prepare_opt
+
+ if [ ! -d $_src ]; then
+ wget -c $OIIO_SOURCE -O "$_src.tar.gz"
+
+ INFO "Unpacking OpenImageIO-$OIIO_VERSION"
+ tar -C $SRC --transform "s,(.*/?)OpenImageIO-oiio[^/]*(.*),\1OpenImageIO-$OIIO_VERSION\2,x" \
+ -xf $_src.tar.gz
+
+ cd $_src
+
+ # XXX Ugly patching hack!
+ cat << EOF | patch -p1
+diff --git a/src/libutil/SHA1.cpp b/src/libutil/SHA1.cpp
+index b9e6c8b..c761185 100644
+--- a/src/libutil/SHA1.cpp
++++ b/src/libutil/SHA1.cpp
+@@ -8,9 +8,9 @@
+
+ // If compiling with MFC, you might want to add #include "StdAfx.h"
+
++#include "SHA1.h"
+ #include "hash.h"
+ #include "dassert.h"
+-#include "SHA1.h"
+
+ #ifdef SHA1_UTILITY_FUNCTIONS
+ #define SHA1_MAX_FILE_BUFFER 8000
+EOF
+
+ cd $CWD
+
+ fi
+
+ cd $_src
+ # Always refresh the whole build!
+ if [ -d build ]; then
+ rm -rf build
+ fi
+ mkdir build
+ cd build
+
+ cmake_d="-D CMAKE_BUILD_TYPE=Release"
+ 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"
+
+ 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"
+ fi
+ fi
+
+ # Looks like we do not need ocio in oiio for now...
+# if [ -d $INST/ocio ]; then
+# cmake_d="$cmake_d -D OCIO_PATH=$INST/ocio"
+# fi
+
+ if file /bin/cp | grep -q '32-bit'; then
+ cflags="-fPIC -m32 -march=i686"
+ else
+ cflags="-fPIC"
+ fi
+
+ cmake $cmake_d -D CMAKE_CXX_FLAGS="$cflags" -D CMAKE_EXE_LINKER_FLAGS="-lgcc_s -lgcc" ../src
+
+ make -j$THREADS && make install
+ make clean
+
+ if [ -d $_inst ]; then
+ rm -f $INST/oiio
+ ln -s oiio-$OIIO_VERSION $INST/oiio
+ else
+ ERROR "OpenImageIO-$OIIO_VERSION failed to compile, exiting"
+ exit 1
+ fi
+
+ magic_compile_set oiio-$OIIO_VERSION $oiio_magic
+
+ cd $CWD
+ else
+ INFO "Own OpenImageIO-$OIIO_VERSION is up to date, nothing to do!"
+ INFO "If you want to force rebuild of this lib, delete the '$_src' and '$_inst' directories."
+ fi
+}
+
+compile_LLVM() {
+ # To be changed each time we make edits that would modify the compiled result!
+ llvm_magic=1
+
+ _src=$SRC/LLVM-$LLVM_VERSION
+ _inst=$INST/llvm-$LLVM_VERSION
+ _src_clang=$SRC/CLANG-$LLVM_VERSION
+
+ # Clean install if needed!
+ magic_compile_check llvm-$LLVM_VERSION $llvm_magic
+ if [ $? -eq 1 ]; then
+ rm -rf $_inst
+ rm -rf $_inst_clang
+ fi
+
+ if [ ! -d $_inst ]; then
+ INFO "Building LLVM-$LLVM_VERSION (CLANG included!)"
+
+ prepare_opt
+
+ if [ ! -d $_src -o true ]; then
+ wget -c $LLVM_SOURCE -O "$_src.tar.gz"
+ wget -c $LLVM_CLANG_SOURCE -O "$_src_clang.tar.gz"
+
+ INFO "Unpacking LLVM-$LLVM_VERSION"
+ tar -C $SRC --transform "s,([^/]*/?)llvm-[^/]*(.*),\1LLVM-$LLVM_VERSION\2,x" \
+ -xf $_src.tar.gz
+ INFO "Unpacking CLANG-$LLVM_VERSION to $_src/tools/clang"
+ tar -C $_src/tools \
+ --transform "s,([^/]*/?)clang-[^/]*(.*),\1clang\2,x" \
+ -xf $_src_clang.tar.gz
+
+ cd $_src
+
+ # XXX Ugly patching hack!
+ cat << EOF | patch -p1
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -13,7 +13,7 @@
+ set(LLVM_VERSION_MAJOR 3)
+ set(LLVM_VERSION_MINOR 1)
+
+-set(PACKAGE_VERSION "\${LLVM_VERSION_MAJOR}.\${LLVM_VERSION_MINOR}svn")
++set(PACKAGE_VERSION "\${LLVM_VERSION_MAJOR}.\${LLVM_VERSION_MINOR}")
+
+ set_property(GLOBAL PROPERTY USE_FOLDERS ON)
+
+EOF
+
+ cd $CWD
+
+ fi
+
+ cd $_src
+
+ # Always refresh the whole build!
+ if [ -d build ]; then
+ rm -rf build
+ fi
+ mkdir build
+ cd build
+
+ cmake_d="-D CMAKE_BUILD_TYPE=Release"
+ cmake_d="$cmake_d -D CMAKE_INSTALL_PREFIX=$_inst"
+ cmake_d="$cmake_d -D LLVM_ENABLE_FFI=ON"
+
+ if [ -d $_FFI_INCLUDE_DIR ]; then
+ cmake_d="$cmake_d -D FFI_INCLUDE_DIR=$_FFI_INCLUDE_DIR"
+ fi
+
+ cmake $cmake_d ..
+
+ make -j$THREADS && make install
+ make clean
+
+ if [ -d $_inst ]; then
+ rm -f $INST/llvm
+ ln -s llvm-$LLVM_VERSION $INST/llvm
+ else
+ ERROR "LLVM-$LLVM_VERSION failed to compile, exiting"
+ exit 1
+ fi
+
+ magic_compile_set llvm-$LLVM_VERSION $llvm_magic
+
+ cd $CWD
+ else
+ INFO "Own LLVM-$LLVM_VERSION (CLANG included) is up to date, nothing to do!"
+ INFO "If you want to force rebuild of this lib, delete the '$_src' and '$_inst' directories."
+ fi
+}
+
+compile_OSL() {
+ # To be changed each time we make edits that would modify the compiled result!
+ osl_magic=7
+
+ _src=$SRC/OpenShadingLanguage-$OSL_VERSION
+ _inst=$INST/osl-$OSL_VERSION
+
+ # Clean install if needed!
+ magic_compile_check osl-$OSL_VERSION $osl_magic
+ if [ $? -eq 1 ]; then
+ rm -rf $_inst
+ fi
+
+ if [ ! -d $_inst ]; then
+ INFO "Building OpenShadingLanguage-$OSL_VERSION"
+
+ prepare_opt
+
+ if [ ! -d $_src ]; then
+ # XXX Using git on my own repo for now, looks like archives are not updated immediately... :/
+# wget -c $OSL_SOURCE -O "$_src.tar.gz"
+
+# INFO "Unpacking OpenShadingLanguage-$OSL_VERSION"
+# tar -C $SRC --transform "s,(.*/?)OpenShadingLanguage-[^/]*(.*),\1OpenShadingLanguage-$OSL_VERSION\2,x" \
+# -xf $_src.tar.gz
+ git clone https://github.com/mont29/OpenShadingLanguage.git $_src
+ cd $_src
+ git checkout blender-fixes
+ cd $CWD
+ fi
+
+ cd $_src
+ # XXX For now, always update from latest repo...
+ git pull origin
+
+ # Always refresh the whole build!
+ if [ -d build ]; then
+ rm -rf build
+ fi
+ mkdir build
+ cd build
+
+ cmake_d="-D CMAKE_BUILD_TYPE=Release"
+ cmake_d="$cmake_d -D CMAKE_INSTALL_PREFIX=$_inst"
+ cmake_d="$cmake_d -D BUILDSTATIC=ON"
+ cmake_d="$cmake_d -D BUILD_TESTING=OFF"
+
+ 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"
+ fi
+ fi
+
+ if [ -d $INST/oiio ]; then
+ cmake_d="$cmake_d -D OPENIMAGEIOHOME=$INST/oiio"
+ fi
+
+ if [ ! -z $LLVM_VERSION_FOUND ]; then
+ cmake_d="$cmake_d -D LLVM_VERSION=$LLVM_VERSION_FOUND"
+ if [ -d $INST/llvm ]; then
+ cmake_d="$cmake_d -D LLVM_DIRECTORY=$INST/llvm"
+ cmake_d="$cmake_d -D LLVM_STATIC=ON"
+ fi
+ fi
+
+ cmake $cmake_d ../src
+
+ make -j$THREADS && make install
+ make clean
+
+ if [ -d $_inst ]; then
+ rm -f $INST/osl
+ ln -s osl-$OSL_VERSION $INST/osl
+ else
+ ERROR "OpenShadingLanguage-$OSL_VERSION failed to compile, exiting"
+ exit 1
+ fi
+
+ magic_compile_set osl-$OSL_VERSION $osl_magic
+
+ cd $CWD
+ else
+ INFO "Own OpenShadingLanguage-$OSL_VERSION is up to date, nothing to do!"
+ INFO "If you want to force rebuild of this lib, delete the '$_src' and '$_inst' directories."
+ fi
+}
+
+compile_FFmpeg() {
+ # To be changed each time we make edits that would modify the compiled result!
+ ffmpeg_magic=3
+
+ _src=$SRC/ffmpeg-$FFMPEG_VERSION
+ _inst=$INST/ffmpeg-$FFMPEG_VERSION
+
+ # Clean install if needed!
+ magic_compile_check ffmpeg-$FFMPEG_VERSION $ffmpeg_magic
+ if [ $? -eq 1 ]; then
+ rm -rf $_inst
+ fi
+
+ if [ ! -d $_inst ]; then
+ INFO "Building ffmpeg-$FFMPEG_VERSION"
+
+ prepare_opt
+
+ if [ ! -d $_src ]; then
+ INFO "Downloading ffmpeg-$FFMPEG_VERSION"
+ wget -c $FFMPEG_SOURCE -O "$_src.tar.bz2"
+
+ INFO "Unpacking ffmpeg-$FFMPEG_VERSION"
+ tar -C $SRC -xf $_src.tar.bz2
+ fi
+
+ cd $_src
+
+ extra=""
+
+ if $VORBIS_USE; then
+ extra="$extra --enable-libvorbis"
+ fi
+
+ if $THEORA_USE; then
+ extra="$extra --enable-libtheora"
+ fi
+
+ # XXX At least under Debian, static schro gives problem at blender linking time... :/
+ if $SCHRO_USE && ! $ALL_STATIC; then
+ extra="$extra --enable-libschroedinger"
+ fi
+
+ if $XVID_USE; then
+ extra="$extra --enable-libxvid"
+ fi
+
+ if $X264_USE; then
+ extra="$extra --enable-libx264"
+ fi
+
+ if $VPX_USE; then
+ extra="$extra --enable-libvpx"
+ fi
+
+ if $MP3LAME_USE; then
+ extra="$extra --enable-libmp3lame"
+ fi
+
+ if $OPENJPEG_USE; then
+ extra="$extra --enable-libopenjpeg"
+ fi
+
+ ./configure --cc="gcc -Wl,--as-needed" \
+ --extra-ldflags="-pthread -static-libgcc" \
+ --prefix=$_inst --enable-static \
+ --disable-ffplay --disable-ffserver --disable-doc \
+ --enable-gray \
+ --enable-avfilter --disable-vdpau \
+ --disable-bzlib --disable-libgsm --disable-libspeex \
+ --enable-pthreads --enable-zlib --enable-stripping --enable-runtime-cpudetect \
+ --disable-vaapi --disable-libfaac --disable-nonfree --enable-gpl \
+ --disable-postproc --disable-x11grab --disable-librtmp --disable-libopencore-amrnb \
+ --disable-libopencore-amrwb --disable-libdc1394 --disable-version3 --disable-outdev=sdl \
+ --disable-outdev=alsa --disable-indev=sdl --disable-indev=alsa --disable-indev=jack \
+ --disable-indev=lavfi $extra
+
+ make -j$THREADS && make install
+ make clean
+
+ if [ -d $_inst ]; then
+ rm -f $INST/ffmpeg
+ ln -s ffmpeg-$FFMPEG_VERSION $INST/ffmpeg
+ else
+ ERROR "FFmpeg-$FFMPEG_VERSION failed to compile, exiting"
+ exit 1
+ fi
+
+ magic_compile_set ffmpeg-$FFMPEG_VERSION $ffmpeg_magic
+
+ cd $CWD
+ else
+ INFO "Own ffmpeg-$FFMPEG_VERSION is up to date, nothing to do!"
+ INFO "If you want to force rebuild of this lib, delete the '$_src' and '$_inst' directories."
+ fi
+}
+
+get_package_version_DEB() {
+ dpkg-query -W -f '${Version}' $1 | sed -r 's/.*:\s*([0-9]+:)(([0-9]+\.?)+).*/\2/'
+}
+
+check_package_DEB() {
+ r=`apt-cache policy $1 | grep -c 'Candidate:'`
+
+ if [ $r -ge 1 ]; then
+ return 0
+ else
+ return 1
+ fi
+}
+
+check_package_version_match_DEB() {
+ v=`apt-cache policy $1 | grep 'Candidate:' | sed -r 's/.*:\s*([0-9]+:)(([0-9]+\.?)+).*/\2/'`
+
+ if [ -z "$v" ]; then
+ return 1
+ fi
+
+ version_match $v $2
+ return $?
+}
+
+check_package_version_ge_DEB() {
+ v=`apt-cache policy $1 | grep 'Candidate:' | sed -r 's/.*:\s*([0-9]+:)?(([0-9]+\.?)+).*/\2/'`
+
+ if [ -z "$v" ]; then
+ return 1
+ fi
+
+ version_ge $v $2
+ return $?
+}
+
+install_DEB() {
+ INFO ""
+ INFO "Installing dependencies for DEB-based distribution"
+ INFO "$COMMON_INFO"
+ INFO ""
+
+ sudo apt-get update
+# XXX Why in hell? Let's let this stuff to the user's responsability!!!
+# sudo apt-get -y upgrade
+
+ # These libs should always be available in debian/ubuntu official repository...
+ OPENJPEG_DEV="libopenjpeg-dev"
+ SCHRO_DEV="libschroedinger-dev"
+ VORBIS_DEV="libvorbis-dev"
+ THEORA_DEV="libtheora-dev"
+
+ sudo apt-get install -y gawk cmake scons gcc g++ libjpeg-dev libpng-dev libtiff-dev \
+ 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
+
+ OPENJPEG_USE=true
+ SCHRO_USE=true
+ VORBIS_USE=true
+ THEORA_USE=true
+
+ # Grmpf, debian is libxvidcore-dev and ubuntu libxvidcore4-dev!
+ XVID_DEV="libxvidcore-dev"
+ check_package_DEB $XVID_DEV
+ if [ $? -eq 0 ]; then
+ sudo apt-get install -y $XVID_DEV
+ XVID_USE=true
+ else
+ XVID_DEV="libxvidcore4-dev"
+ check_package_DEB $XVID_DEV
+ if [ $? -eq 0 ]; then
+ sudo apt-get install -y $XVID_DEV
+ XVID_USE=true
+ fi
+ fi
+
+ MP3LAME_DEV="libmp3lame-dev"
+ check_package_DEB $MP3LAME_DEV
+ if [ $? -eq 0 ]; then
+ sudo apt-get install -y $MP3LAME_DEV
+ MP3LAME_USE=true
+ fi
+
+ X264_DEV="libx264-dev"
+ check_package_version_ge_DEB $X264_DEV $X264_VERSION_MIN
+ if [ $? -eq 0 ]; then
+ sudo apt-get install -y $X264_DEV
+ X264_USE=true
+ fi
+
+ VPX_DEV="libvpx-dev"
+ check_package_version_ge_DEB $VPX_DEV $VPX_VERSION_MIN
+ if [ $? -eq 0 ]; then
+ sudo apt-get install -y $VPX_DEV
+ VPX_USE=true
+ fi
+
+ check_package_DEB libspnav-dev
+ if [ $? -eq 0 ]; then
+ sudo apt-get install -y libspnav-dev
+ fi
+
+ check_package_DEB python3.3-dev
+ if [ $? -eq 0 ]; then
+ sudo apt-get install -y python3.3-dev
+ else
+ compile_Python
+ fi
+
+ check_package_version_ge_DEB libboost-dev $BOOST_VERSION_MIN
+ if [ $? -eq 0 ]; then
+ sudo apt-get install -y libboost-dev
+
+ boost_version=$(echo `get_package_version_DEB libboost-dev` | sed -r 's/^([0-9]+\.[0-9]+).*/\1/')
+
+ check_package_DEB libboost-locale$boost_version-dev
+ if [ $? -eq 0 ]; then
+ sudo apt-get install -y libboost-locale$boost_version-dev libboost-filesystem$boost_version-dev \
+ libboost-regex$boost_version-dev libboost-system$boost_version-dev \
+ libboost-thread$boost_version-dev
+ else
+ compile_Boost
+ fi
+ else
+ compile_Boost
+ fi
+
+ check_package_version_ge_DEB libopencolorio-dev $OCIO_VERSION_MIN
+ if [ $? -eq 0 ]; then
+ sudo apt-get install -y libopencolorio-dev
+ else
+ compile_OCIO
+ fi
+
+ check_package_version_ge_DEB libopenimageio-dev $OIIO_VERSION_MIN
+ if [ $? -eq 0 ]; then
+ sudo apt-get install -y libopenimageio-dev
+ else
+ compile_OIIO
+ fi
+
+ if $BUILD_OSL; then
+ have_llvm=false
+
+ check_package_DEB llvm-$LLVM_VERSION-dev
+ if [ $? -eq 0 ]; then
+ sudo apt-get install -y llvm-$LLVM_VERSION-dev
+ have_llvm=true
+ LLVM_VERSION_FOUND=$LLVM_VERSION
+ else
+ check_package_DEB llvm-$LLVM_VERSION_MIN-dev
+ if [ $? -eq 0 ]; then
+ sudo apt-get install -y llvm-$LLVM_VERSION_MIN-dev
+ have_llvm=true
+ LLVM_VERSION_FOUND=$LLVM_VERSION_MIN
+ fi
+ fi
+
+ if $have_llvm; then
+ sudo apt-get install -y clang flex bison libtbb-dev git
+ # No package currently!
+ compile_OSL
+ fi
+ fi
+
+# XXX Debian features libav packages as ffmpeg, those are not really compatible with blender code currently :/
+# So for now, always build our own ffmpeg.
+# check_package_DEB ffmpeg
+# if [ $? -eq 0 ]; then
+# sudo apt-get install -y ffmpeg
+# ffmpeg_version=`get_package_version_DEB ffmpeg`
+# INFO "ffmpeg version: $ffmpeg_version"
+# if [ ! -z "$ffmpeg_version" ]; then
+# if dpkg --compare-versions $ffmpeg_version gt 0.7.2; then
+# sudo apt-get install -y libavfilter-dev libavcodec-dev libavdevice-dev libavformat-dev libavutil-dev libswscale-dev
+# else
+# compile_FFmpeg
+# fi
+# fi
+# fi
+ compile_FFmpeg
+}
+
+get_package_version_RPM() {
+ yum info $1 | grep Version | tail -n 1 | sed -r 's/.*:\s+(([0-9]+\.?)+).*/\1/'
+}
+
+check_package_RPM() {
+ r=`yum info $1 | grep -c 'Summary'`
+
+ if [ $r -ge 1 ]; then
+ return 0
+ else
+ return 1
+ fi
+}
+
+check_package_version_match_RPM() {
+ v=`get_package_version_RPM $1`
+
+ if [ -z "$v" ]; then
+ return 1
+ fi
+
+ version_match $v $2
+ return $?
+}
+
+check_package_version_ge_RPM() {
+ v=`get_package_version_RPM $1`
+
+ if [ -z "$v" ]; then
+ return 1
+ fi
+
+ version_ge $v $2
+ return $?
+}
+
+install_RPM() {
+ INFO ""
+ INFO "Installing dependencies for RPM-based distribution"
+ INFO "$COMMON_INFO"
+ INFO ""
+
+ sudo yum -y update
+
+ # These libs should always be available in debian/ubuntu official repository...
+ OPENJPEG_DEV="openjpeg-devel"
+ SCHRO_DEV="schroedinger-devel"
+ VORBIS_DEV="libvorbis-devel"
+ THEORA_DEV="libtheora-devel"
+
+ sudo yum -y install gawk gcc gcc-c++ cmake scons libpng-devel libtiff-devel \
+ freetype-devel libX11-devel libXi-devel wget libsqlite3x-devel ncurses-devel \
+ readline-devel $OPENJPEG_DEV openexr-devel openal-soft-devel \
+ glew-devel yasm $SCHRO_DEV $THEORA_DEV $VORBIS_DEV SDL-devel \
+ fftw-devel lame-libs jack-audio-connection-kit-devel libspnav-devel \
+ libjpeg-devel patch python-devel
+
+ OPENJPEG_USE=true
+ SCHRO_USE=true
+ VORBIS_USE=true
+ THEORA_USE=true
+
+ X264_DEV="x264-devel"
+ check_package_version_ge_RPM $X264_DEV $X264_VERSION_MIN
+ if [ $? -eq 0 ]; then
+ sudo yum install -y $X264_DEV
+ X264_USE=true
+ fi
+
+ XVID_DEV="xvidcore-devel"
+ check_package_RPM $XVID_DEV
+ if [ $? -eq 0 ]; then
+ sudo yum install -y $XVID_DEV
+ XVID_USE=true
+ fi
+
+ VPX_DEV="libvpx-devel"
+ check_package_version_ge_RPM $VPX_DEV $VPX_VERSION_MIN
+ if [ $? -eq 0 ]; then
+ sudo yum install -y $VPX_DEV
+ VPX_USE=true
+ fi
+
+ MP3LAME_DEV="lame-devel"
+ check_package_RPM $MP3LAME_DEV
+ if [ $? -eq 0 ]; then
+ sudo yum install -y $MP3LAME_DEV
+ MP3LAME_USE=true
+ fi
+
+ check_package_version_match_RPM python3-devel $PYTHON_VERSION_MIN
+ if [ $? -eq 0 ]; then
+ sudo yum install -y python3-devel
+ else
+ compile_Python
+ fi
+
+ check_package_version_ge_RPM boost-devel $BOOST_VERSION_MIN
+ if [ $? -eq 0 ]; then
+ sudo yum install -y boost-devel
+ else
+ compile_Boost
+ fi
+
+ check_package_version_ge_RPM OpenColorIO-devel $OCIO_VERSION_MIN
+ if [ $? -eq 0 ]; then
+ sudo yum install -y OpenColorIO-devel
+ else
+ compile_OCIO
+ fi
+
+ check_package_version_ge_RPM OpenImageIO-devel $OIIO_VERSION_MIN
+ if [ $? -eq 0 ]; then
+ sudo yum install -y OpenImageIO-devel
+ else
+ compile_OIIO
+ fi
+
+ if $BUILD_OSL; then
+ have_llvm=false
+
+ check_package_RPM llvm-$LLVM_VERSION-devel
+ if [ $? -eq 0 ]; then
+ sudo yum install -y llvm-$LLVM_VERSION-devel
+ have_llvm=true
+ LLVM_VERSION_FOUND=$LLVM_VERSION
+ else
+# check_package_RPM llvm-$LLVM_VERSION_MIN-devel
+# if [ $? -eq 0 ]; then
+# sudo yum install -y llvm-$LLVM_VERSION_MIN-devel
+# have_llvm=true
+# LLVM_VERSION_FOUND=$LLVM_VERSION_MIN
+# else
+# check_package_version_ge_RPM llvm-devel $LLVM_VERSION_MIN
+# if [ $? -eq 0 ]; then
+# sudo yum install -y llvm-devel
+# have_llvm=true
+# LLVM_VERSION_FOUND=`get_package_version_RPM llvm-devel`
+# fi
+# fi
+ sudo yum install -y libffi-devel
+ # XXX Stupid fedora puts ffi header into a darn stupid dir!
+ _FFI_INCLUDE_DIR=`rpm -ql libffi-devel | grep -e ".*/ffi.h" | sed -r 's/(.*)\/ffi.h/\1/'`
+ compile_LLVM
+ have_llvm=true
+ LLVM_VERSION_FOUND=$LLVM_VERSION
+ fi
+
+ if $have_llvm; then
+ sudo yum install -y flex bison clang tbb-devel git
+ # No package currently!
+ compile_OSL
+ fi
+ fi
+
+ # Always for now, not sure which packages should be installed
+ compile_FFmpeg
+}
+
+get_package_version_SUSE() {
+ zypper info $1 | grep Version | tail -n 1 | sed -r 's/.*:\s+(([0-9]+\.?)+).*/\1/'
+}
+
+check_package_SUSE() {
+ r=`zypper info $1 | grep -c 'Summary'`
+
+ if [ $r -ge 1 ]; then
+ return 0
+ else
+ return 1
+ fi
+}
+
+check_package_version_match_SUSE() {
+ v=`get_package_version_SUSE $1`
+
+ if [ -z "$v" ]; then
+ return 1
+ fi
+
+ version_match $v $2
+ return $?
+}
+
+check_package_version_ge_SUSE() {
+ v=`get_package_version_SUSE $1`
+
+ if [ -z "$v" ]; then
+ return 1
+ fi
+
+ version_ge $v $2
+ return $?
+}
+
+install_SUSE() {
+ INFO ""
+ INFO "Installing dependencies for SuSE-based distribution"
+ INFO "$COMMON_INFO"
+ INFO ""
+
+ sudo zypper --non-interactive update --auto-agree-with-licenses
+
+ # These libs should always be available in debian/ubuntu official repository...
+ OPENJPEG_DEV="openjpeg-devel"
+ SCHRO_DEV="schroedinger-devel"
+ VORBIS_DEV="libvorbis-devel"
+ THEORA_DEV="libtheora-devel"
+
+ sudo zypper --non-interactive install --auto-agree-with-licenses \
+ gawk gcc gcc-c++ cmake scons libpng12-devel libtiff-devel \
+ freetype-devel libX11-devel libXi-devel wget sqlite3-devel ncurses-devel \
+ readline-devel $OPENJPEG_DEV libopenexr-devel openal-soft-devel \
+ glew-devel yasm $SCHRO_DEV $THEORA_DEV $VORBIS_DEV libSDL-devel \
+ fftw3-devel libjack-devel libspnav-devel \
+ libjpeg62-devel patch python-devel
+
+ OPENJPEG_USE=true
+ SCHRO_USE=true
+ VORBIS_USE=true
+ THEORA_USE=true
+
+ X264_DEV="x264-devel"
+ check_package_version_ge_SUSE $X264_DEV $X264_VERSION_MIN
+ if [ $? -eq 0 ]; then
+ sudo zypper --non-interactive install --auto-agree-with-licenses $X264_DEV
+ X264_USE=true
+ fi
+
+ XVID_DEV="xvidcore-devel"
+ check_package_SUSE $XVID_DEV
+ if [ $? -eq 0 ]; then
+ sudo zypper --non-interactive install --auto-agree-with-licenses $XVID_DEV
+ XVID_USE=true
+ fi
+
+ VPX_DEV="libvpx-devel"
+ check_package_version_ge_SUSE $VPX_DEV $VPX_VERSION_MIN
+ if [ $? -eq 0 ]; then
+ sudo zypper --non-interactive install --auto-agree-with-licenses $VPX_DEV
+ VPX_USE=true
+ fi
+
+ # No mp3 in suse, it seems.
+ MP3LAME_DEV="lame-devel"
+ check_package_SUSE $MP3LAME_DEV
+ if [ $? -eq 0 ]; then
+ sudo zypper --non-interactive install --auto-agree-with-licenses $MP3LAME_DEV
+ MP3LAME_USE=true
+ fi
+
+ check_package_version_match_SUSE python3-devel 3.3.
+ if [ $? -eq 0 ]; then
+ sudo zypper --non-interactive install --auto-agree-with-licenses python3-devel
+ else
+ compile_Python
+ fi
+
+ # No boost_locale currently available, so let's build own boost.
+ compile_Boost
+
+ # No ocio currently available, so let's build own boost.
+ compile_OCIO
+
+ # No oiio currently available, so let's build own boost.
+ compile_OIIO
+
+ if $BUILD_OSL; then
+ have_llvm=false
+
+ # Suse llvm package *_$SUCKS$_* (tm) !!!
+# check_package_version_ge_SUSE llvm-devel $LLVM_VERSION_MIN
+# if [ $? -eq 0 ]; then
+# sudo zypper --non-interactive install --auto-agree-with-licenses llvm-devel
+# have_llvm=true
+# LLVM_VERSION_FOUND=`get_package_version_SUSE llvm-devel`
+# fi
+
+ sudo zypper --non-interactive install --auto-agree-with-licenses libffi47-devel
+ compile_LLVM
+ have_llvm=true
+ LLVM_VERSION_FOUND=$LLVM_VERSION
+
+ if $have_llvm; then
+ # XXX No tbb lib!
+ sudo zypper --non-interactive install --auto-agree-with-licenses flex bison git
+ # No package currently!
+ compile_OSL
+ fi
+ fi
+
+ # No ffmpeg currently available, so let's build own boost.
+ compile_FFmpeg
+}
+
+print_info_ffmpeglink_DEB() {
+ if $ALL_STATIC; then
+ dpkg -L $_packages | grep -e ".*\/lib[^\/]\+\.a" | gawk '{ printf(nlines ? "'"$_ffmpeg_list_sep"'%s" : "%s", $0); nlines++ }'
+ else
+ dpkg -L $_packages | grep -e ".*\/lib[^\/]\+\.so" | gawk '{ printf(nlines ? "'"$_ffmpeg_list_sep"'%s" : "%s", gensub(/.*lib([^\/]+)\.so/, "\\1", "g", $0)); nlines++ }'
+ fi
+}
+
+print_info_ffmpeglink_RPM() {
+ if $ALL_STATIC; then
+ rpm -ql $_packages | grep -e ".*\/lib[^\/]\+\.a" | gawk '{ printf(nlines ? "'"$_ffmpeg_list_sep"'%s" : "%s", $0); nlines++ }'
+ else
+ rpm -ql $_packages | grep -e ".*\/lib[^\/]\+\.so" | gawk '{ printf(nlines ? "'"$_ffmpeg_list_sep"'%s" : "%s", gensub(/.*lib([^\/]+)\.so/, "\\1", "g", $0)); nlines++ }'
+ fi
+}
+
+print_info_ffmpeglink_SUSE() {
+ if $ALL_STATIC; then
+ rpm -ql $_packages | grep -e ".*\/lib[^\/]\+\.a" | gawk '{ printf(nlines ? "'"$_ffmpeg_list_sep"'%s" : "%s", $0); nlines++ }'
+ else
+ rpm -ql $_packages | grep -e ".*\/lib[^\/]\+\.so" | gawk '{ printf(nlines ? "'"$_ffmpeg_list_sep"'%s" : "%s", gensub(/.*lib([^\/]+)\.so/, "\\1", "g", $0)); nlines++ }'
+ fi
+}
+
+print_info_ffmpeglink() {
+ # This func must only print a ';'-separated list of libs...
+ if [ -z "$DISTRO" ]; then
+ ERROR "Failed to detect distribution type"
+ exit 1
+ fi
+
+ # Create list of packages from which to get libs names...
+ _packages=""
+
+ if $THEORA_USE; then
+ _packages="$_packages $THEORA_DEV"
+ fi
+
+ if $VORBIS_USE; then
+ _packages="$_packages $VORBIS_DEV"
+ fi
+
+ if $XVID_USE; then
+ _packages="$_packages $XVID_DEV"
+ fi
+
+ if $VPX_USE; then
+ _packages="$_packages $VPX_DEV"
+ fi
+
+ if $MP3LAME_USE; then
+ _packages="$_packages $MP3LAME_DEV"
+ fi
+
+ if $X264_USE; then
+ _packages="$_packages $X264_DEV"
+ fi
+
+ if $OPENJPEG_USE; then
+ _packages="$_packages $OPENJPEG_DEV"
+ fi
+
+ # XXX At least under Debian, static schro give problem at blender linking time... :/
+ if $SCHRO_USE && ! $ALL_STATIC; then
+ _packages="$_packages $SCHRO_DEV"
+ fi
+
+ if [ "$DISTRO" = "DEB" ]; then
+ print_info_ffmpeglink_DEB
+ elif [ "$DISTRO" = "RPM" ]; then
+ print_info_ffmpeglink_RPM
+ elif [ "$DISTRO" = "SUSE" ]; then
+ print_info_ffmpeglink_SUSE
+ # XXX TODO!
+ else INFO "<Could not determine additional link libraries needed for ffmpeg, replace this by valid list of libs...>"
+ fi
+}
+
+print_info() {
+ INFO ""
+ INFO "If you're using CMake add this to your configuration flags:"
+
+ if $ALL_STATIC; then
+ INFO " -D WITH_STATIC_LIBS=ON"
+ fi
+
+ if [ -d $INST/boost ]; then
+ INFO " -D BOOST_ROOT=$INST/boost"
+ INFO " -D Boost_NO_SYSTEM_PATHS=ON"
+ elif $ALL_STATIC; then
+ INFO " -D Boost_USE_ICU=ON"
+ fi
+
+ if [ -d $INST/osl ]; then
+ INFO " -D CYCLES_OSL=$INST/osl"
+ INFO " -D WITH_CYCLES_OSL=ON"
+ INFO " -D LLVM_VERSION=$LLVM_VERSION_FOUND"
+ if [ -d $INST/llvm ]; then
+ INFO " -D LLVM_DIRECTORY=$INST/llvm"
+ INFO " -D LLVM_STATIC=ON"
+ fi
+ fi
+
+ if [ -d $INST/ffmpeg ]; then
+ INFO " -D WITH_CODEC_FFMPEG=ON"
+ INFO " -D FFMPEG=$INST/ffmpeg"
+ INFO " -D FFMPEG_LIBRARIES='avformat;avcodec;avutil;avdevice;swscale;rt;`print_info_ffmpeglink`'"
+ fi
+
+ INFO ""
+ INFO "If you're using SCons add this to your user-config:"
+
+ if [ -d $INST/python-3.3 ]; then
+ INFO "BF_PYTHON = '$INST/python-3.3'"
+ INFO "BF_PYTHON_ABI_FLAGS = 'm'"
+ fi
+
+ if [ -d $INST/ocio ]; then
+ INFO "BF_OCIO = '$INST/ocio'"
+ fi
+
+ if [ -d $INST/oiio ]; then
+ INFO "BF_OIIO = '$INST/oiio'"
+ fi
+
+ if [ -d $INST/boost ]; then
+ INFO "BF_BOOST = '$INST/boost'"
+ fi
+
+ if [ -d $INST/ffmpeg ]; then
+ INFO "BF_FFMPEG = '$INST/ffmpeg'"
+ _ffmpeg_list_sep=" "
+ INFO "BF_FFMPEG_LIB = 'avformat avcodec swscale avutil avdevice `print_info_ffmpeglink`'"
+ fi
+
+ INFO ""
+ INFO ""
+ INFO "WARNING: If this script had to build boost into $INST, and you are dynamically linking "
+ INFO " blender against it, you will have to run those commands as root user:"
+ INFO ""
+ INFO " echo \"$INST/boost/lib\" > /etc/ld.so.conf.d/boost.conf"
+ INFO " ldconfig"
+ INFO ""
+}
+
+# Detect distributive type used on this machine
+detect_distro
+
+if [ -z "$DISTRO" ]; then
+ ERROR "Failed to detect distribution type"
+ exit 1
+elif [ "$DISTRO" = "DEB" ]; then
+ install_DEB
+elif [ "$DISTRO" = "RPM" ]; then
+ install_RPM
+elif [ "$DISTRO" = "SUSE" ]; then
+ install_SUSE
+fi
+
+print_info
+
+# Switch back to user language.
+LANG=LANG_BACK
+export LANG
diff --git a/build_files/buildbot/config/user-config-glibc211-i686.py b/build_files/buildbot/config/user-config-glibc211-i686.py
index 23ab87a6ba3..e5afa2afe13 100644
--- a/build_files/buildbot/config/user-config-glibc211-i686.py
+++ b/build_files/buildbot/config/user-config-glibc211-i686.py
@@ -120,6 +120,24 @@ BF_OIIO_INC = '${BF_OIIO}/include'
BF_OIIO_LIB_STATIC = '${BF_OIIO_LIBPATH}/libOpenImageIO.a ${BF_OPENEXR}/lib/libIlmImf.a ${BF_JPEG}/lib/libjpeg.a'
BF_OIIO_LIBPATH = '${BF_OIIO}/lib'
+WITH_BF_CYCLES_OSL = True
+WITH_BF_STATICOSL = False
+BF_OSL = '/opt/lib/osl'
+BF_OSL_INC = '${BF_OSL}/include'
+# note oslexec would passed via program linkflags, which is needed to
+# make llvm happy with osl_allocate_closure_component
+BF_OSL_LIB = 'oslcomp oslexec oslquery'
+BF_OSL_LIBPATH = '${BF_OSL}/lib'
+BF_OSL_COMPILER = '${BF_OSL}/bin/oslc'
+
+WITH_BF_LLVM = True
+WITH_BF_STATICLLVM = False
+BF_LLVM = '/opt/lib/llvm-3.1'
+BF_LLVM_LIB = 'LLVMBitReader LLVMJIT LLVMipo LLVMVectorize LLVMBitWriter LLVMX86CodeGen LLVMX86Desc LLVMX86Info LLVMX86AsmPrinter ' + \
+ 'LLVMX86Utils LLVMSelectionDAG LLVMCodeGen LLVMScalarOpts LLVMInstCombine LLVMTransformUtils LLVMipa LLVMAnalysis LLVMExecutionEngine ' + \
+ 'LLVMTarget LLVMMC LLVMCore LLVMSupport'
+BF_LLVM_LIBPATH = '${BF_LLVM}/lib'
+
# Color management
WITH_BF_OCIO = True
WITH_BF_STATICOCIO = True
@@ -133,7 +151,8 @@ WITH_BF_STATICBOOST = True
BF_BOOST = '/opt/lib/boost'
BF_BOOST_INC = '${BF_BOOST}/include'
BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBPATH}/libboost_date_time.a ' + \
- '${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_system.a ${BF_BOOST_LIBPATH}/libboost_thread.a'
+ '${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_locale.a ${BF_BOOST_LIBPATH}/libboost_system.a \
+ ${BF_BOOST_LIBPATH}/libboost_thread.a'
BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
# Ocean Simulation
@@ -143,3 +162,4 @@ WITH_BF_OCEANSIM = True
BF_DEBUG = False
REL_CCFLAGS = ['-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 84899cc3848..dc901d25a92 100644
--- a/build_files/buildbot/config/user-config-glibc211-x86_64.py
+++ b/build_files/buildbot/config/user-config-glibc211-x86_64.py
@@ -119,6 +119,24 @@ BF_OIIO_INC = '${BF_OIIO}/include'
BF_OIIO_LIB_STATIC = '${BF_OIIO_LIBPATH}/libOpenImageIO.a ${BF_OPENEXR}/lib/libIlmImf.a ${BF_JPEG}/lib/libjpeg.a'
BF_OIIO_LIBPATH = '${BF_OIIO}/lib'
+WITH_BF_CYCLES_OSL = True
+WITH_BF_STATICOSL = False
+BF_OSL = '/opt/lib/osl'
+BF_OSL_INC = '${BF_OSL}/include'
+# note oslexec would passed via program linkflags, which is needed to
+# make llvm happy with osl_allocate_closure_component
+BF_OSL_LIB = 'oslcomp oslexec oslquery'
+BF_OSL_LIBPATH = '${BF_OSL}/lib'
+BF_OSL_COMPILER = '${BF_OSL}/bin/oslc'
+
+WITH_BF_LLVM = True
+WITH_BF_STATICLLVM = False
+BF_LLVM = '/opt/lib/llvm-3.1'
+BF_LLVM_LIB = 'LLVMBitReader LLVMJIT LLVMipo LLVMVectorize LLVMBitWriter LLVMX86CodeGen LLVMX86Desc LLVMX86Info LLVMX86AsmPrinter ' + \
+ 'LLVMX86Utils LLVMSelectionDAG LLVMCodeGen LLVMScalarOpts LLVMInstCombine LLVMTransformUtils LLVMipa LLVMAnalysis LLVMExecutionEngine ' + \
+ 'LLVMTarget LLVMMC LLVMCore LLVMSupport'
+BF_LLVM_LIBPATH = '${BF_LLVM}/lib'
+
# Color management
WITH_BF_OCIO = True
WITH_BF_STATICOCIO = True
@@ -132,7 +150,8 @@ WITH_BF_STATICBOOST = True
BF_BOOST = '/opt/lib/boost'
BF_BOOST_INC = '${BF_BOOST}/include'
BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBPATH}/libboost_date_time.a ' + \
- '${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_system.a ${BF_BOOST_LIBPATH}/libboost_thread.a'
+ '${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_locale.a ${BF_BOOST_LIBPATH}/libboost_system.a \
+ ${BF_BOOST_LIBPATH}/libboost_thread.a'
BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
# Ocean Simulation
@@ -142,3 +161,4 @@ WITH_BF_OCEANSIM = True
BF_DEBUG = False
REL_CCFLAGS = ['-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 c1e72662f89..dd3a63d0fd7 100644
--- a/build_files/buildbot/config/user-config-glibc27-i686.py
+++ b/build_files/buildbot/config/user-config-glibc27-i686.py
@@ -107,6 +107,24 @@ BF_OIIO_INC = '${BF_OIIO}/include'
BF_OIIO_LIB_STATIC = '${BF_OIIO_LIBPATH}/libOpenImageIO.a ${BF_OPENEXR}/lib/libIlmImf.a'
BF_OIIO_LIBPATH = '${BF_OIIO}/lib'
+WITH_BF_CYCLES_OSL = True
+WITH_BF_STATICOSL = False
+BF_OSL = '/opt/osl'
+BF_OSL_INC = '${BF_OSL}/include'
+# note oslexec would passed via program linkflags, which is needed to
+# make llvm happy with osl_allocate_closure_component
+BF_OSL_LIB = 'oslcomp oslexec oslquery'
+BF_OSL_LIBPATH = '${BF_OSL}/lib'
+BF_OSL_COMPILER = '${BF_OSL}/bin/oslc'
+
+WITH_BF_LLVM = True
+WITH_BF_STATICLLVM = False
+BF_LLVM = '/opt/llvm-3.1'
+BF_LLVM_LIB = 'LLVMBitReader LLVMJIT LLVMipo LLVMVectorize LLVMBitWriter LLVMX86CodeGen LLVMX86Desc LLVMX86Info LLVMX86AsmPrinter ' + \
+ 'LLVMX86Utils LLVMSelectionDAG LLVMCodeGen LLVMScalarOpts LLVMInstCombine LLVMTransformUtils LLVMipa LLVMAnalysis LLVMExecutionEngine ' + \
+ 'LLVMTarget LLVMMC LLVMCore LLVMSupport'
+BF_LLVM_LIBPATH = '${BF_LLVM}/lib'
+
# Color management
WITH_BF_OCIO = True
WITH_BF_STATICOCIO = True
@@ -119,7 +137,7 @@ WITH_BF_BOOST = True
WITH_BF_STATICBOOST = True
BF_BOOST = '/opt/boost'
BF_BOOST_INC = '${BF_BOOST}/include'
-BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBPATH}/libboost_date_time.a ${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_system.a ${BF_BOOST_LIBPATH}/libboost_thread.a'
+BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBPATH}/libboost_date_time.a ${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_locale.a ${BF_BOOST_LIBPATH}/libboost_system.a ${BF_BOOST_LIBPATH}/libboost_thread.a'
BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
# Ocean Simulation
@@ -129,3 +147,4 @@ WITH_BF_OCEANSIM = True
BF_DEBUG = False
REL_CCFLAGS = ['-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 4380b404ac3..d9e50d258bc 100644
--- a/build_files/buildbot/config/user-config-glibc27-x86_64.py
+++ b/build_files/buildbot/config/user-config-glibc27-x86_64.py
@@ -106,6 +106,24 @@ BF_OIIO_INC = '${BF_OIIO}/include'
BF_OIIO_LIB_STATIC = '${BF_OIIO_LIBPATH}/libOpenImageIO.a ${BF_OPENEXR}/lib/libIlmImf.a'
BF_OIIO_LIBPATH = '${BF_OIIO}/lib'
+WITH_BF_CYCLES_OSL = True
+WITH_BF_STATICOSL = False
+BF_OSL = '/opt/osl'
+BF_OSL_INC = '${BF_OSL}/include'
+# note oslexec would passed via program linkflags, which is needed to
+# make llvm happy with osl_allocate_closure_component
+BF_OSL_LIB = 'oslcomp oslexec oslquery'
+BF_OSL_LIBPATH = '${BF_OSL}/lib'
+BF_OSL_COMPILER = '${BF_OSL}/bin/oslc'
+
+WITH_BF_LLVM = True
+WITH_BF_STATICLLVM = False
+BF_LLVM = '/opt/llvm-3.1'
+BF_LLVM_LIB = 'LLVMBitReader LLVMJIT LLVMipo LLVMVectorize LLVMBitWriter LLVMX86CodeGen LLVMX86Desc LLVMX86Info LLVMX86AsmPrinter ' + \
+ 'LLVMX86Utils LLVMSelectionDAG LLVMCodeGen LLVMScalarOpts LLVMInstCombine LLVMTransformUtils LLVMipa LLVMAnalysis LLVMExecutionEngine ' + \
+ 'LLVMTarget LLVMMC LLVMCore LLVMSupport'
+BF_LLVM_LIBPATH = '${BF_LLVM}/lib'
+
# Color management
WITH_BF_OCIO = True
WITH_BF_STATICOCIO = True
@@ -118,7 +136,7 @@ WITH_BF_BOOST = True
WITH_BF_STATICBOOST = True
BF_BOOST = '/opt/boost'
BF_BOOST_INC = '${BF_BOOST}/include'
-BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBPATH}/libboost_date_time.a ${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_system.a ${BF_BOOST_LIBPATH}/libboost_thread.a'
+BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBPATH}/libboost_date_time.a ${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_locale.a ${BF_BOOST_LIBPATH}/libboost_system.a ${BF_BOOST_LIBPATH}/libboost_thread.a'
BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
# Ocean Simulation
@@ -128,3 +146,4 @@ WITH_BF_OCEANSIM = True
BF_DEBUG = False
REL_CCFLAGS = ['-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 1b387445390..00bfdbb16f2 100644
--- a/build_files/buildbot/config/user-config-player-glibc211-i686.py
+++ b/build_files/buildbot/config/user-config-player-glibc211-i686.py
@@ -98,7 +98,8 @@ WITH_BF_STATICBOOST = True
BF_BOOST = '/opt/lib/boost'
BF_BOOST_INC = '${BF_BOOST}/include'
BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBPATH}/libboost_date_time.a ' + \
- '${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_system.a ${BF_BOOST_LIBPATH}/libboost_thread.a'
+ '${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_locale.a ${BF_BOOST_LIBPATH}/libboost_system.a \
+ ${BF_BOOST_LIBPATH}/libboost_thread.a'
BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
# JACK
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 83540150c33..f6eef4f89d9 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
@@ -98,7 +98,8 @@ WITH_BF_STATICBOOST = True
BF_BOOST = '/opt/lib/boost'
BF_BOOST_INC = '${BF_BOOST}/include'
BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBPATH}/libboost_date_time.a ' + \
- '${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_system.a ${BF_BOOST_LIBPATH}/libboost_thread.a'
+ '${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_locale.a ${BF_BOOST_LIBPATH}/libboost_system.a \
+ ${BF_BOOST_LIBPATH}/libboost_thread.a'
BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
# JACK
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 e200e0fccf4..1e834c0c8d2 100644
--- a/build_files/buildbot/config/user-config-player-glibc27-i686.py
+++ b/build_files/buildbot/config/user-config-player-glibc27-i686.py
@@ -94,7 +94,7 @@ WITH_BF_BOOST = True
WITH_BF_STATICBOOST = True
BF_BOOST = '/opt/boost'
BF_BOOST_INC = '${BF_BOOST}/include'
-BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBPATH}/libboost_date_time.a ${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_system.a ${BF_BOOST_LIBPATH}/libboost_thread.a'
+BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBPATH}/libboost_date_time.a ${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_locale.a ${BF_BOOST_LIBPATH}/libboost_system.a ${BF_BOOST_LIBPATH}/libboost_thread.a'
BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
# JACK
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 2ee177960cd..aa0a69c44d8 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
@@ -94,7 +94,7 @@ WITH_BF_BOOST = True
WITH_BF_STATICBOOST = True
BF_BOOST = '/opt/boost'
BF_BOOST_INC = '${BF_BOOST}/include'
-BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBPATH}/libboost_date_time.a ${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_system.a ${BF_BOOST_LIBPATH}/libboost_thread.a'
+BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBPATH}/libboost_date_time.a ${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_locale.a ${BF_BOOST_LIBPATH}/libboost_system.a ${BF_BOOST_LIBPATH}/libboost_thread.a'
BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
# JACK
diff --git a/build_files/buildbot/master.cfg b/build_files/buildbot/master.cfg
index e9deade6e99..90f0c805f58 100644
--- a/build_files/buildbot/master.cfg
+++ b/build_files/buildbot/master.cfg
@@ -77,17 +77,18 @@ def svn_step(branch=''):
def lib_svn_step(dir):
return SVN(name='lib svn', baseURL='https://svn.blender.org/svnroot/bf-blender/%%BRANCH%%/lib/' + dir, mode='update', defaultBranch='trunk', workdir='lib/' + dir)
-def rsync_step(file_from, file_to):
- return ShellCommand(name='rsync', command=['rsync', '-v', '-P', file_from, 'brecht@builder.blender.org:/data/buildbot-master/' + file_to], haltOnFailure=True, description=['rsync'])
+def rsync_step(id, branch, rsync_script):
+ return ShellCommand(name='rsync', command=['python', rsync_script, id, branch], description='uploading', descriptionDone='uploaded', workdir='install')
# generic builder
def generic_builder(id, libdir='', branch='', rsync=False):
- filename = 'buildbot_upload_' + id + '.zip'
+ filename = 'uploaded/buildbot_upload_' + id + '.zip'
compile_script = '../blender/build_files/buildbot/slave_compile.py'
test_script = '../blender/build_files/buildbot/slave_test.py'
pack_script = '../blender/build_files/buildbot/slave_pack.py'
+ rsync_script = '../blender/build_files/buildbot/slave_rsync.py'
unpack_script = 'master_unpack.py'
f = BuildFactory()
@@ -95,11 +96,11 @@ def generic_builder(id, libdir='', branch='', rsync=False):
if libdir != '':
f.addStep(lib_svn_step(libdir))
- f.addStep(Compile(command=['python', compile_script, id]))
+ f.addStep(Compile(command=['python', compile_script, id], timeout=3600))
f.addStep(Test(command=['python', test_script, id]))
f.addStep(ShellCommand(name='package', command=['python', pack_script, id, branch], description='packaging', descriptionDone='packaged'))
if rsync:
- f.addStep(rsync_step('../install/buildbot_upload.zip', filename))
+ f.addStep(rsync_step(id, branch, rsync_script))
elif id.find('cmake') != -1:
f.addStep(FileUpload(name='upload', slavesrc='buildbot_upload.zip', masterdest=filename, maxsize=100 * 1024 * 1024))
else:
@@ -109,7 +110,8 @@ def generic_builder(id, libdir='', branch='', rsync=False):
# builders
-add_builder(c, 'mac_x86_64_scons', '', generic_builder)
+add_builder(c, 'mac_x86_64_10_6_scons', 'darwin-9.x.universal', generic_builder, '', True)
+add_builder(c, 'mac_x86_64_10_5_scons', '', generic_builder, '', True)
#add_builder(c, 'salad_mac_x86_64_scons', 'darwin-9.x.universal', generic_builder, 'soc-2011-salad')
add_builder(c, 'mac_i386_scons', 'darwin-9.x.universal', generic_builder)
add_builder(c, 'mac_ppc_scons', 'darwin-9.x.universal', generic_builder)
diff --git a/build_files/buildbot/slave_rsync.py b/build_files/buildbot/slave_rsync.py
new file mode 100644
index 00000000000..aea1b65e333
--- /dev/null
+++ b/build_files/buildbot/slave_rsync.py
@@ -0,0 +1,45 @@
+# ##### 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>
+
+# Runs on buildbot slave, rsync zip directly to buildbot server rather
+# than using upload which is much slower
+
+import os
+import sys
+
+# get builder name
+if len(sys.argv) < 2:
+ sys.stderr.write("Not enough arguments, expecting builder name\n")
+ sys.exit(1)
+
+builder = sys.argv[1]
+
+# rsync, this assumes ssh keys are setup so no password is needed
+local_zip = "buildbot_upload.zip"
+remote_folder = "builder.blender.org:/data/buildbot-master/uploaded/"
+remote_zip = remote_folder + "buildbot_upload_" + builder + ".zip"
+command = "rsync -avz %s %s" % (local_zip, remote_zip)
+
+print(command)
+
+ret = os.system(command)
+sys.exit(ret)
+
+
diff --git a/build_files/cmake/Modules/FindIcuLinux.cmake b/build_files/cmake/Modules/FindIcuLinux.cmake
new file mode 100644
index 00000000000..e0e5873a4eb
--- /dev/null
+++ b/build_files/cmake/Modules/FindIcuLinux.cmake
@@ -0,0 +1,146 @@
+# - Find static icu libraries
+# Find the native static icu libraries (needed for static boost_locale :/ ).
+# This module defines
+# ICU_LIBRARIES, libraries to link against to use icu.
+# ICU_ROOT_DIR, The base directory to search for icu.
+# This can also be an environment variable.
+# ICU_FOUND, If false, do not try to use icu.
+#
+# also defined, but not for general use are
+# ICU_LIBRARY_xxx, where to find the icu libraries.
+
+#=============================================================================
+# Copyright 2012 Blender Foundation.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+
+# If ICU_ROOT_DIR was defined in the environment, use it.
+IF(NOT ICU_ROOT_DIR AND NOT $ENV{ICU_ROOT_DIR} STREQUAL "")
+ SET(ICU_ROOT_DIR $ENV{ICU_ROOT_DIR})
+ENDIF()
+
+if(Boost_USE_STATIC_LIBS)
+ set(_icu_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
+ set(CMAKE_FIND_LIBRARY_SUFFIXES .a)
+endif()
+
+SET(_icu_SEARCH_DIRS
+ ${ICU_ROOT_DIR}
+ /usr/local
+ /sw # Fink
+ /opt/local # DarwinPorts
+ /opt/csw # Blastwave
+)
+
+# We don't need includes, only libs to link against...
+#FIND_PATH(ICU_INCLUDE_DIR
+# NAMES
+# utf.h
+# HINTS
+# ${_icu_SEARCH_DIRS}
+# PATH_SUFFIXES
+# include/unicode
+#)
+
+FIND_LIBRARY(ICU_LIBRARY_DATA
+ NAMES
+ icudata
+ HINTS
+ ${_icu_SEARCH_DIRS}
+ PATH_SUFFIXES
+ lib64 lib
+ )
+
+FIND_LIBRARY(ICU_LIBRARY_I18N
+ NAMES
+ icui18n
+ HINTS
+ ${_icu_SEARCH_DIRS}
+ PATH_SUFFIXES
+ lib64 lib
+ )
+
+FIND_LIBRARY(ICU_LIBRARY_IO
+ NAMES
+ icuio
+ HINTS
+ ${_icu_SEARCH_DIRS}
+ PATH_SUFFIXES
+ lib64 lib
+ )
+
+FIND_LIBRARY(ICU_LIBRARY_LE
+ NAMES
+ icule
+ HINTS
+ ${_icu_SEARCH_DIRS}
+ PATH_SUFFIXES
+ lib64 lib
+ )
+
+FIND_LIBRARY(ICU_LIBRARY_LX
+ NAMES
+ iculx
+ HINTS
+ ${_icu_SEARCH_DIRS}
+ PATH_SUFFIXES
+ lib64 lib
+ )
+
+FIND_LIBRARY(ICU_LIBRARY_TU
+ NAMES
+ icutu
+ HINTS
+ ${_icu_SEARCH_DIRS}
+ PATH_SUFFIXES
+ lib64 lib
+ )
+
+FIND_LIBRARY(ICU_LIBRARY_UC
+ NAMES
+ icuuc
+ HINTS
+ ${_icu_SEARCH_DIRS}
+ PATH_SUFFIXES
+ lib64 lib
+ )
+
+# Restore the original find library ordering
+if(Boost_USE_STATIC_LIBS)
+ set(CMAKE_FIND_LIBRARY_SUFFIXES ${_icu_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES})
+endif()
+
+# handle the QUIETLY and REQUIRED arguments and set ICU_FOUND to TRUE if
+# all listed variables are TRUE
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(Icu DEFAULT_MSG
+ ICU_LIBRARY_DATA
+ ICU_LIBRARY_I18N
+ ICU_LIBRARY_IO
+ ICU_LIBRARY_LE
+ ICU_LIBRARY_LX
+ ICU_LIBRARY_TU
+ ICU_LIBRARY_UC
+)
+
+IF(ICU_FOUND)
+ SET(ICU_LIBRARIES ${ICU_LIBRARY_DATA} ${ICU_LIBRARY_I18N} ${ICU_LIBRARY_IO} ${ICU_LIBRARY_LE} ${ICU_LIBRARY_LX} ${ICU_LIBRARY_TU} ${ICU_LIBRARY_UC})
+ SET(ICU_INCLUDE_DIRS ${ICU_INCLUDE_DIR})
+ENDIF(ICU_FOUND)
+
+MARK_AS_ADVANCED(
+ ICU_INCLUDE_DIR
+ ICU_LIBRARY_DATA
+ ICU_LIBRARY_I18N
+ ICU_LIBRARY_IO
+ ICU_LIBRARY_LE
+ ICU_LIBRARY_LX
+ ICU_LIBRARY_TU
+ ICU_LIBRARY_UC
+)
diff --git a/build_files/cmake/Modules/FindOpenColorIO.cmake b/build_files/cmake/Modules/FindOpenColorIO.cmake
index 79bc0127674..e152f0f81d9 100644
--- a/build_files/cmake/Modules/FindOpenColorIO.cmake
+++ b/build_files/cmake/Modules/FindOpenColorIO.cmake
@@ -39,6 +39,7 @@ SET(_opencolorio_SEARCH_DIRS
/sw # Fink
/opt/local # DarwinPorts
/opt/csw # Blastwave
+ /opt/lib/ocio
)
FIND_PATH(OPENCOLORIO_INCLUDE_DIR
diff --git a/build_files/cmake/Modules/FindOpenImageIO.cmake b/build_files/cmake/Modules/FindOpenImageIO.cmake
index 7512b93e09e..9b8c8b075b1 100644
--- a/build_files/cmake/Modules/FindOpenImageIO.cmake
+++ b/build_files/cmake/Modules/FindOpenImageIO.cmake
@@ -33,6 +33,7 @@ SET(_openimageio_SEARCH_DIRS
/sw # Fink
/opt/local # DarwinPorts
/opt/csw # Blastwave
+ /opt/lib/oiio
)
FIND_PATH(OPENIMAGEIO_INCLUDE_DIR
diff --git a/build_files/cmake/Modules/FindPythonLibsUnix.cmake b/build_files/cmake/Modules/FindPythonLibsUnix.cmake
index 7f272ee5b14..1dffd54fed1 100644
--- a/build_files/cmake/Modules/FindPythonLibsUnix.cmake
+++ b/build_files/cmake/Modules/FindPythonLibsUnix.cmake
@@ -78,6 +78,7 @@ IF((NOT _IS_INC_DEF) OR (NOT _IS_INC_CONF_DEF) OR (NOT _IS_LIB_DEF) OR (NOT _IS_
${PYTHON_ROOT_DIR}
"$ENV{HOME}/py${_PYTHON_VERSION_NO_DOTS}"
"/opt/py${_PYTHON_VERSION_NO_DOTS}"
+ "/opt/lib/python-${PYTHON_VERSION}"
)
FOREACH(_CURRENT_ABI_FLAGS ${_python_ABI_FLAGS})
diff --git a/build_files/cmake/cmake_consistency_check.py b/build_files/cmake/cmake_consistency_check.py
index 072bbb12fb3..83ebf927b3c 100755
--- a/build_files/cmake/cmake_consistency_check.py
+++ b/build_files/cmake/cmake_consistency_check.py
@@ -222,8 +222,8 @@ def cmake_get_src(f):
'''
# reset
- sources_h[:] = []
- sources_c[:] = []
+ del sources_h[:]
+ del sources_c[:]
filen.close()
diff --git a/build_files/cmake/macros.cmake b/build_files/cmake/macros.cmake
index f2d9449c2d0..27699a9c029 100644
--- a/build_files/cmake/macros.cmake
+++ b/build_files/cmake/macros.cmake
@@ -196,10 +196,6 @@ macro(SETUP_LIBDIRS)
if(WITH_PYTHON) # AND NOT WITH_PYTHON_MODULE # WIN32 needs
link_directories(${PYTHON_LIBPATH})
endif()
- if(WITH_INTERNATIONAL)
- link_directories(${ICONV_LIBPATH})
- link_directories(${GETTEXT_LIBPATH})
- endif()
if(WITH_SDL)
link_directories(${SDL_LIBPATH})
endif()
@@ -291,14 +287,6 @@ macro(setup_liblinks
target_link_libraries(${target} ${GLEW_LIBRARY})
endif()
- if(WITH_INTERNATIONAL)
- target_link_libraries(${target} ${GETTEXT_LIBRARIES})
-
- if(WIN32 AND NOT UNIX)
- target_link_libraries(${target} ${ICONV_LIBRARIES})
- endif()
- endif()
-
if(WITH_OPENAL)
target_link_libraries(${target} ${OPENAL_LIBRARY})
endif()
@@ -328,6 +316,9 @@ macro(setup_liblinks
endif()
if(WITH_BOOST)
target_link_libraries(${target} ${BOOST_LIBRARIES})
+ if(Boost_USE_STATIC_LIBS AND Boost_USE_ICU)
+ target_link_libraries(${target} ${ICU_LIBRARIES})
+ endif()
endif()
target_link_libraries(${target} ${JPEG_LIBRARIES})
if(WITH_IMAGE_OPENEXR)
@@ -720,7 +711,11 @@ macro(delayed_install
destination)
foreach(f ${files})
- set_property(GLOBAL APPEND PROPERTY DELAYED_INSTALL_FILES ${base}/${f})
+ if(IS_ABSOLUTE ${f})
+ set_property(GLOBAL APPEND PROPERTY DELAYED_INSTALL_FILES ${f})
+ else()
+ set_property(GLOBAL APPEND PROPERTY DELAYED_INSTALL_FILES ${base}/${f})
+ endif()
set_property(GLOBAL APPEND PROPERTY DELAYED_INSTALL_DESTINATIONS ${destination})
endforeach()
endmacro()
diff --git a/build_files/scons/config/darwin-config.py b/build_files/scons/config/darwin-config.py
index afab4131de8..252a1b1b37e 100644
--- a/build_files/scons/config/darwin-config.py
+++ b/build_files/scons/config/darwin-config.py
@@ -118,16 +118,16 @@ BF_FFMPEG_LIBPATH='${BF_FFMPEG}/lib'
BF_FFMPEG_LIB = 'avcodec avdevice avformat avutil mp3lame swscale x264 xvidcore theora theoradec theoraenc vorbis vorbisenc vorbisfile ogg bz2'
#bz2 is a standard osx dynlib
-BF_PYTHON_VERSION = '3.2'
+BF_PYTHON_VERSION = '3.3'
WITH_OSX_STATICPYTHON = True
if WITH_OSX_STATICPYTHON:
- # python 3.2 uses precompiled libraries in bf svn /lib by default
+ # python 3.3 uses precompiled libraries in bf svn /lib by default
BF_PYTHON = LIBDIR + '/python'
- BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}'
+ BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}m'
# BF_PYTHON_BINARY = '${BF_PYTHON}/bin/python${BF_PYTHON_VERSION}'
- BF_PYTHON_LIB = 'python${BF_PYTHON_VERSION}'
+ BF_PYTHON_LIB = 'python${BF_PYTHON_VERSION}m'
BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib/python${BF_PYTHON_VERSION}'
# BF_PYTHON_LINKFLAGS = ['-u', '_PyMac_Error', '-framework', 'System']
else:
@@ -223,11 +223,6 @@ BF_ZLIB_LIB = 'z'
WITH_BF_INTERNATIONAL = True
-BF_GETTEXT = LIBDIR + '/gettext'
-BF_GETTEXT_INC = '${BF_GETTEXT}/include'
-BF_GETTEXT_LIB = 'intl'
-BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib'
-
WITH_BF_GAMEENGINE = True
WITH_BF_PLAYER = True
WITH_BF_OCEANSIM = True
@@ -281,23 +276,42 @@ BF_PCRE_LIBPATH = '${BF_PCRE}/lib'
# Cycles
WITH_BF_CYCLES = True
+#OSL
+
+WITH_BF_CYCLES_OSL = True
+BF_OSL = LIBDIR + '/osl'
+BF_OSL_INC = '${BF_OSL}/include'
+# note oslexec would passed via program linkflags, which is needed to
+# make llvm happy with osl_allocate_closure_component
+#BF_OSL_LIB = 'oslcomp oslquery'
+BF_OSL_LIBPATH = '${BF_OSL}/lib'
+BF_OSL_COMPILER = '${BF_OSL}/bin/oslc'
+
+WITH_BF_LLVM = True
+BF_LLVM = LIBDIR + '/llvm'
+BF_LLVM_LIB = 'LLVMBitReader LLVMJIT LLVMipo LLVMVectorize LLVMBitWriter LLVMX86CodeGen LLVMX86Desc LLVMX86Info LLVMX86AsmPrinter ' + \
+ 'LLVMX86Utils LLVMSelectionDAG LLVMCodeGen LLVMScalarOpts LLVMInstCombine LLVMTransformUtils LLVMipa LLVMAnalysis LLVMExecutionEngine ' + \
+ 'LLVMTarget LLVMMC LLVMCore LLVMSupport'
+BF_LLVM_LIBPATH = '${BF_LLVM}/lib'
+
WITH_BF_OIIO = True
BF_OIIO = LIBDIR + '/openimageio'
-BF_OIIO_INC = BF_OIIO + '/include'
+BF_OIIO_INC = '${BF_OIIO}/include'
BF_OIIO_LIB = 'OpenImageIO'
-BF_OIIO_LIBPATH = BF_OIIO + '/lib'
+BF_OIIO_LIBPATH = '${BF_OIIO}/lib'
WITH_BF_OCIO = True
BF_OCIO = LIBDIR + '/opencolorio'
-BF_OCIO_INC = BF_OCIO + '/include'
+BF_OCIO_INC = '${BF_OCIO}/include'
BF_OCIO_LIB = 'OpenColorIO tinyxml yaml-cpp'
-BF_OCIO_LIBPATH = BF_OCIO + '/lib'
+BF_OCIO_LIBPATH = '${BF_OCIO}/lib'
WITH_BF_BOOST = True
BF_BOOST = LIBDIR + '/boost'
-BF_BOOST_INC = BF_BOOST + '/include'
-BF_BOOST_LIB = 'boost_date_time-mt boost_filesystem-mt boost_regex-mt boost_system-mt boost_thread-mt'
-BF_BOOST_LIBPATH = BF_BOOST + '/lib'
+BF_BOOST_INC = '${BF_BOOST}/include'
+BF_BOOST_LIB = 'boost_date_time-mt boost_filesystem-mt boost_regex-mt boost_system-mt boost_thread-mt boost_wave-mt'
+BF_BOOST_LIB_INTERNATIONAL = 'boost_locale-mt'
+BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
WITH_BF_CYCLES_CUDA_BINARIES = False
BF_CYCLES_CUDA_NVCC = '/usr/local/cuda/bin/nvcc'
diff --git a/build_files/scons/config/freebsd7-config.py b/build_files/scons/config/freebsd7-config.py
index 412b08d895b..61358de12b4 100644
--- a/build_files/scons/config/freebsd7-config.py
+++ b/build_files/scons/config/freebsd7-config.py
@@ -77,11 +77,6 @@ BF_ZLIB_LIB = 'z'
WITH_BF_INTERNATIONAL = True
-BF_GETTEXT = '/usr/local'
-BF_GETTEXT_INC = '${BF_GETTEXT}/include'
-BF_GETTEXT_LIB = 'gettextlib'
-BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib'
-
WITH_BF_GAMEENGINE = False
WITH_BF_PLAYER = True
WITH_BF_OCEANSIM = True
diff --git a/build_files/scons/config/freebsd8-config.py b/build_files/scons/config/freebsd8-config.py
index ece86f799c3..0f6c7f64786 100644
--- a/build_files/scons/config/freebsd8-config.py
+++ b/build_files/scons/config/freebsd8-config.py
@@ -77,11 +77,6 @@ BF_ZLIB_LIB = 'z'
WITH_BF_INTERNATIONAL = True
-BF_GETTEXT = '/usr/local'
-BF_GETTEXT_INC = '${BF_GETTEXT}/include'
-BF_GETTEXT_LIB = 'gettextlib'
-BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib'
-
WITH_BF_GAMEENGINE = False
WITH_BF_PLAYER = True
WITH_BF_OCEANSIM = True
diff --git a/build_files/scons/config/freebsd9-config.py b/build_files/scons/config/freebsd9-config.py
index a31c6da90f0..c0df68f99ad 100644
--- a/build_files/scons/config/freebsd9-config.py
+++ b/build_files/scons/config/freebsd9-config.py
@@ -77,11 +77,6 @@ BF_ZLIB_LIB = 'z'
WITH_BF_INTERNATIONAL = True
-BF_GETTEXT = '/usr/local'
-BF_GETTEXT_INC = '${BF_GETTEXT}/include'
-BF_GETTEXT_LIB = 'gettextlib'
-BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib'
-
WITH_BF_GAMEENGINE = False
WITH_BF_PLAYER = True
WITH_BF_OCEANSIM = True
diff --git a/build_files/scons/config/linux-config.py b/build_files/scons/config/linux-config.py
index 45f6602e4dd..038a9bc421d 100644
--- a/build_files/scons/config/linux-config.py
+++ b/build_files/scons/config/linux-config.py
@@ -89,13 +89,6 @@ BF_ZLIB_LIB = 'z'
WITH_BF_INTERNATIONAL = True
-BF_GETTEXT = '/usr'
-BF_GETTEXT_INC = '${BF_GETTEXT}/include'
-BF_GETTEXT_LIB = 'gettextlib'
-BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib'
-#WITH_BF_GETTEXT_STATIC = True
-#BF_GETTEXT_LIB_STATIC = '${BF_GETTEXT}/lib/libgettextlib.a'
-
WITH_BF_GAMEENGINE = True
WITH_BF_PLAYER = True
WITH_BF_OCEANSIM = True
@@ -211,9 +204,9 @@ BF_OIIO = LIBDIR + '/oiio'
if not os.path.exists(LCGDIR + '/oiio'):
WITH_BF_OIIO = False
BF_OIIO = '/usr'
-BF_OIIO_INC = BF_OIIO + '/include'
+BF_OIIO_INC = '${BF_OIIO}/include'
BF_OIIO_LIB = 'OpenImageIO'
-BF_OIIO_LIBPATH = BF_OIIO + '/lib'
+BF_OIIO_LIBPATH = '${BF_OIIO}/lib'
WITH_BF_OCIO = True
WITH_BF_STATICOCIO = False
@@ -221,9 +214,9 @@ BF_OCIO = LIBDIR + '/ocio'
if not os.path.exists(LCGDIR + '/ocio'):
WITH_BF_OCIO = False
BF_OCIO = '/usr'
-BF_OCIO_INC = BF_OCIO + '/include'
+BF_OCIO_INC = '${BF_OCIO}/include'
BF_OCIO_LIB = 'OpenColorIO yaml-cpp tinyxml'
-BF_OCIO_LIBPATH = BF_OCIO + '/lib'
+BF_OCIO_LIBPATH = '${BF_OCIO}/lib'
WITH_BF_BOOST = True
WITH_BF_STATICBOOST = False
@@ -231,9 +224,10 @@ BF_BOOST = LIBDIR + '/boost'
if not os.path.exists(LCGDIR + '/boost'):
WITH_BF_BOOST = False
BF_BOOST = '/usr'
-BF_BOOST_INC = BF_BOOST + '/include'
+BF_BOOST_INC = '${BF_BOOST}/include'
BF_BOOST_LIB = 'boost_date_time boost_filesystem boost_regex boost_system boost_thread'
-BF_BOOST_LIBPATH = BF_BOOST + '/lib'
+BF_BOOST_LIB_INTERNATIONAL = 'boost_locale'
+BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
WITH_BF_CYCLES = WITH_BF_OIIO and WITH_BF_BOOST
@@ -304,3 +298,7 @@ BF_INSTALLDIR='../install/linux'
#Link against pthread
PLATFORM_LINKFLAGS = ['-pthread']
+#Fix for LLVM conflict with Mesa llvmpipe
+if WITH_BF_LLVM:
+ PLATFORM_LINKFLAGS += ['-Wl,--version-script=source/creator/blender.map']
+
diff --git a/build_files/scons/config/linuxcross-config.py b/build_files/scons/config/linuxcross-config.py
index 6866241793b..63264807720 100644
--- a/build_files/scons/config/linuxcross-config.py
+++ b/build_files/scons/config/linuxcross-config.py
@@ -83,11 +83,6 @@ BF_ZLIB_LIBPATH = '${BF_ZLIB}/lib'
WITH_BF_INTERNATIONAL = True
-BF_GETTEXT = LIBDIR + '/gcc/gettext'
-BF_GETTEXT_INC = '${BF_GETTEXT}/include'
-BF_GETTEXT_LIB = 'intl'
-BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib'
-
WITH_BF_GAMEENGINE = True
WITH_BF_PLAYER = False
WITH_BF_OCEANSIM = True
diff --git a/build_files/scons/config/win32-mingw-config.py b/build_files/scons/config/win32-mingw-config.py
index 0a72d87bb2a..80e3592c71e 100644
--- a/build_files/scons/config/win32-mingw-config.py
+++ b/build_files/scons/config/win32-mingw-config.py
@@ -83,11 +83,6 @@ BF_ZLIB_LIBPATH = '${BF_ZLIB}/lib'
WITH_BF_INTERNATIONAL = True
-BF_GETTEXT = LIBDIR + '/gettext'
-BF_GETTEXT_INC = '${BF_GETTEXT}/include'
-BF_GETTEXT_LIB = 'intl'
-BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib'
-
WITH_BF_OPENJPEG = True
BF_OPENJPEG = '#extern/libopenjpeg'
BF_OPENJPEG_LIB = ''
@@ -155,21 +150,22 @@ WITH_BF_CYCLES = True
WITH_BF_OIIO = True
BF_OIIO = LIBDIR + '/openimageio'
-BF_OIIO_INC = BF_OIIO + '/include'
+BF_OIIO_INC = '${BF_OIIO}/include'
BF_OIIO_LIB = 'OpenImageIO'
-BF_OIIO_LIBPATH = BF_OIIO + '/lib'
+BF_OIIO_LIBPATH = '${BF_OIIO}/lib'
WITH_BF_OCIO = True
BF_OCIO = LIBDIR + '/opencolorio'
-BF_OCIO_INC = BF_OCIO + '/include'
+BF_OCIO_INC = '${BF_OCIO}/include'
BF_OCIO_LIB = 'OpenColorIO'
-BF_OCIO_LIBPATH = BF_OCIO + '/lib'
+BF_OCIO_LIBPATH = '${BF_OCIO}/lib'
WITH_BF_BOOST = True
BF_BOOST = LIBDIR + '/boost'
-BF_BOOST_INC = BF_BOOST + '/include'
+BF_BOOST_INC = '${BF_BOOST}/include'
BF_BOOST_LIB = 'boost_date_time-mgw46-mt-s-1_49 boost_filesystem-mgw46-mt-s-1_49 boost_regex-mgw46-mt-s-1_49 boost_system-mgw46-mt-s-1_49 boost_thread-mgw46-mt-s-1_49'
-BF_BOOST_LIBPATH = BF_BOOST + '/lib'
+BF_BOOST_LIB_INTERNATIONAL = 'boost_locale-mgw46-mt-s-1_49'
+BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
#Ray trace optimization
WITH_BF_RAYOPTIMIZATION = True
diff --git a/build_files/scons/config/win32-vc-config.py b/build_files/scons/config/win32-vc-config.py
index b77ff8e70e0..2120938ec71 100644
--- a/build_files/scons/config/win32-vc-config.py
+++ b/build_files/scons/config/win32-vc-config.py
@@ -54,7 +54,7 @@ BF_PTHREADS_LIBPATH = '${BF_PTHREADS}/lib'
WITH_BF_OPENEXR = True
WITH_BF_STATICOPENEXR = False
BF_OPENEXR = LIBDIR + '/openexr'
-BF_OPENEXR_INC = '${BF_OPENEXR}/include ${BF_OPENEXR}/include/IlmImf ${BF_OPENEXR}/include/Iex ${BF_OPENEXR}/include/Imath '
+BF_OPENEXR_INC = '${BF_OPENEXR}/include ${BF_OPENEXR}/include/OpenEXR '
BF_OPENEXR_LIB = ' Iex Half IlmImf Imath IlmThread '
BF_OPENEXR_LIBPATH = '${BF_OPENEXR}/lib'
BF_OPENEXR_LIB_STATIC = '${BF_OPENEXR}/lib/libHalf.a ${BF_OPENEXR}/lib/libIlmImf.a ${BF_OPENEXR}/lib/libIex.a ${BF_OPENEXR}/lib/libImath.a ${BF_OPENEXR}/lib/libIlmThread.a'
@@ -87,11 +87,6 @@ BF_ZLIB_LIBPATH = '${BF_ZLIB}/lib'
WITH_BF_INTERNATIONAL = True
-BF_GETTEXT = LIBDIR + '/gettext'
-BF_GETTEXT_INC = '${BF_GETTEXT}/include'
-BF_GETTEXT_LIB = 'gnu_gettext'
-BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib'
-
WITH_BF_GAMEENGINE = True
WITH_BF_PLAYER = True
WITH_BF_OCEANSIM = True
@@ -155,22 +150,40 @@ WITH_BF_OPENMP = True
#Cycles
WITH_BF_CYCLES = True
+WITH_BF_CYCLES_OSL = True
+WITH_BF_STATICOSL = True
+BF_OSL = '${LIBDIR}/osl'
+BF_OSL_INC = '${BF_OSL}/include'
+BF_OSL_LIBPATH = '${BF_OSL}/lib'
+BF_OSL_LIB_STATIC = '${BF_OSL_LIBPATH}/oslcomp.lib ${BF_OSL_LIBPATH}/oslexec.lib ${BF_OSL_LIBPATH}/oslquery.lib '
+BF_OSL_COMPILER = '${BF_OSL}/bin/oslc'
+
+WITH_BF_LLVM = True
+BF_LLVM = LIBDIR + '/llvm'
+BF_LLVM_LIB = 'LLVMBitReader LLVMJIT LLVMipo LLVMVectorize LLVMBitWriter LLVMX86CodeGen LLVMX86Desc LLVMX86Info LLVMX86AsmPrinter ' + \
+ 'LLVMX86Utils LLVMSelectionDAG LLVMCodeGen LLVMScalarOpts LLVMInstCombine LLVMTransformUtils LLVMipa LLVMAnalysis LLVMExecutionEngine ' + \
+ 'LLVMTarget LLVMMC LLVMCore LLVMSupport'
+BF_LLVM_LIBPATH = '${BF_LLVM}/lib'
+
WITH_BF_OIIO = True
BF_OIIO = '${LIBDIR}/openimageio'
BF_OIIO_INC = '${BF_OIIO}/include'
-BF_OIIO_LIB = 'OpenImageIO'
BF_OIIO_LIBPATH = '${BF_OIIO}/lib'
+BF_OIIO_LIB_STATIC = '${BF_OIIO_LIBPATH}/OpenImageIO.lib'
+WITH_BF_STATICOIIO = True
WITH_BF_OCIO = True
BF_OCIO = '${LIBDIR}/opencolorio'
BF_OCIO_INC = '${BF_OCIO}/include'
-BF_OCIO_LIB = 'OpenColorIO'
BF_OCIO_LIBPATH = '${BF_OCIO}/lib'
+BF_OCIO_LIB_STATIC = '${BF_OCIO_LIBPATH}/OpenColorIO.lib'
+WITH_BF_STATICOCIO = True
WITH_BF_BOOST = True
BF_BOOST = '${LIBDIR}/boost'
BF_BOOST_INC = '${BF_BOOST}/include'
BF_BOOST_LIB = 'libboost_date_time-vc90-mt-s-1_49 libboost_filesystem-vc90-mt-s-1_49 libboost_regex-vc90-mt-s-1_49 libboost_system-vc90-mt-s-1_49 libboost_thread-vc90-mt-s-1_49'
+BF_BOOST_LIB_INTERNATIONAL = 'libboost_locale-vc90-mt-s-1_49'
BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
#CUDA
@@ -208,7 +221,7 @@ C_WARN = []
CC_WARN = []
CXX_WARN = []
-LLIBS = ['ws2_32', 'vfw32', 'winmm', 'kernel32', 'user32', 'gdi32', 'comdlg32', 'advapi32', 'shfolder', 'shell32', 'ole32', 'oleaut32', 'uuid']
+LLIBS = ['ws2_32', 'vfw32', 'winmm', 'kernel32', 'user32', 'gdi32', 'comdlg32', 'advapi32', 'shfolder', 'shell32', 'ole32', 'oleaut32', 'uuid', 'psapi']
PLATFORM_LINKFLAGS = ['/SUBSYSTEM:CONSOLE','/MACHINE:IX86','/STACK:2097152','/INCREMENTAL:NO', '/LARGEADDRESSAWARE', '/NODEFAULTLIB:msvcrt.lib', '/NODEFAULTLIB:msvcmrt.lib', '/NODEFAULTLIB:msvcurt.lib', '/NODEFAULTLIB:msvcrtd.lib']
diff --git a/build_files/scons/config/win64-mingw-config.py b/build_files/scons/config/win64-mingw-config.py
index 838822bbbcb..fdfd792f180 100644
--- a/build_files/scons/config/win64-mingw-config.py
+++ b/build_files/scons/config/win64-mingw-config.py
@@ -80,11 +80,6 @@ BF_ZLIB_LIBPATH = '${BF_ZLIB}/lib'
WITH_BF_INTERNATIONAL = True
-BF_GETTEXT = LIBDIR + '/gettext'
-BF_GETTEXT_INC = '${BF_GETTEXT}/include'
-BF_GETTEXT_LIB = 'intl'
-BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib'
-
WITH_BF_OPENJPEG = True
BF_OPENJPEG = '#extern/libopenjpeg'
BF_OPENJPEG_LIB = ''
@@ -118,7 +113,7 @@ BF_FREETYPE_LIBPATH = '${BF_FREETYPE}/lib'
WITH_BF_QUICKTIME = False
-WITH_BF_ICONV = True
+WITH_BF_ICONV = False
BF_ICONV = LIBDIR + "/iconv"
BF_ICONV_INC = '${BF_ICONV}/include'
BF_ICONV_LIB = 'iconv'
@@ -167,9 +162,10 @@ BF_OCIO_LIBPATH = '${BF_OCIO}/lib'
WITH_BF_BOOST = True
BF_BOOST = LIBDIR + '/boost'
-BF_BOOST_INC = BF_BOOST + '/include'
+BF_BOOST_INC = '${BF_BOOST}/include'
BF_BOOST_LIB = 'boost_date_time-mgw47-mt-s-1_49 boost_date_time-mgw47-mt-sd-1_49 boost_filesystem-mgw47-mt-s-1_49 boost_filesystem-mgw47-mt-sd-1_49 boost_regex-mgw47-mt-s-1_49 boost_regex-mgw47-mt-sd-1_49 boost_system-mgw47-mt-s-1_49 boost_system-mgw47-mt-sd-1_49 boost_thread-mgw47-mt-s-1_49 boost_thread-mgw47-mt-sd-1_49'
-BF_BOOST_LIBPATH = BF_BOOST + '/lib'
+BF_BOOST_LIB_INTERNATIONAL = ' boost_locale-mgw47-mt-s-1_49 boost_locale-mgw47-mt-sd-1_49'
+BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
#Ray trace optimization
WITH_BF_RAYOPTIMIZATION = True
diff --git a/build_files/scons/config/win64-vc-config.py b/build_files/scons/config/win64-vc-config.py
index 4b719469c39..15bcdf999bd 100644
--- a/build_files/scons/config/win64-vc-config.py
+++ b/build_files/scons/config/win64-vc-config.py
@@ -50,7 +50,7 @@ BF_PTHREADS_LIBPATH = '${BF_PTHREADS}/lib'
WITH_BF_OPENEXR = True
WITH_BF_STATICOPENEXR = False
BF_OPENEXR = LIBDIR + '/openexr'
-BF_OPENEXR_INC = '${BF_OPENEXR}/include ${BF_OPENEXR}/include/IlmImf ${BF_OPENEXR}/include/Iex ${BF_OPENEXR}/include/Imath '
+BF_OPENEXR_INC = '${BF_OPENEXR}/include ${BF_OPENEXR}/include/OpenEXR '
BF_OPENEXR_LIB = ' Iex Half IlmImf Imath IlmThread '
BF_OPENEXR_LIBPATH = '${BF_OPENEXR}/lib'
BF_OPENEXR_LIB_STATIC = '${BF_OPENEXR}/lib/libHalf.a ${BF_OPENEXR}/lib/libIlmImf.a ${BF_OPENEXR}/lib/libIex.a ${BF_OPENEXR}/lib/libImath.a ${BF_OPENEXR}/lib/libIlmThread.a'
@@ -83,11 +83,6 @@ BF_ZLIB_LIBPATH = '${BF_ZLIB}/lib'
WITH_BF_INTERNATIONAL = True
-BF_GETTEXT = LIBDIR + '/gettext'
-BF_GETTEXT_INC = '${BF_GETTEXT}/include'
-BF_GETTEXT_LIB = 'gnu_gettext'
-BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib'
-
WITH_BF_GAMEENGINE = True
WITH_BF_PLAYER = True
WITH_BF_OCEANSIM = True
@@ -151,24 +146,40 @@ WITH_BF_OPENMP = True
#Cycles
WITH_BF_CYCLES = True
+WITH_BF_CYCLES_OSL = True
+WITH_BF_STATICOSL = True
+BF_OSL = '${LIBDIR}/osl'
+BF_OSL_INC = '${BF_OSL}/include'
+BF_OSL_LIBPATH = '${BF_OSL}/lib'
+BF_OSL_LIB_STATIC = '${BF_OSL_LIBPATH}/oslcomp.lib ${BF_OSL_LIBPATH}/oslexec.lib ${BF_OSL_LIBPATH}/oslquery.lib '
+BF_OSL_COMPILER = '${BF_OSL}/bin/oslc'
+
+WITH_BF_LLVM = True
+BF_LLVM = LIBDIR + '/llvm'
+BF_LLVM_LIB = 'LLVMBitReader LLVMJIT LLVMipo LLVMVectorize LLVMBitWriter LLVMX86CodeGen LLVMX86Desc LLVMX86Info LLVMX86AsmPrinter ' + \
+ 'LLVMX86Utils LLVMSelectionDAG LLVMCodeGen LLVMScalarOpts LLVMInstCombine LLVMTransformUtils LLVMipa LLVMAnalysis LLVMExecutionEngine ' + \
+ 'LLVMTarget LLVMMC LLVMCore LLVMSupport'
+BF_LLVM_LIBPATH = '${BF_LLVM}/lib'
+
WITH_BF_OIIO = True
BF_OIIO = '${LIBDIR}/openimageio'
BF_OIIO_INC = '${BF_OIIO}/include'
-BF_OIIO_LIB = 'OpenImageIO'
-BF_OIIO_LIBPATH = '${BF_OIIO}/lib'
BF_OIIO_LIBPATH = '${BF_OIIO}/lib'
+BF_OIIO_LIB_STATIC = '${BF_OIIO_LIBPATH}/OpenImageIO.lib'
+WITH_BF_STATICOIIO = True
WITH_BF_OCIO = True
BF_OCIO = '${LIBDIR}/opencolorio'
BF_OCIO_INC = '${BF_OCIO}/include'
-BF_OCIO_LIB = 'OpenColorIO'
-BF_OCIO_LIBPATH = '${BF_OCIO}/lib'
BF_OCIO_LIBPATH = '${BF_OCIO}/lib'
+BF_OCIO_LIB_STATIC = '${BF_OCIO_LIBPATH}/OpenColorIO.lib'
+WITH_BF_STATICOCIO = True
WITH_BF_BOOST = True
BF_BOOST = '${LIBDIR}/boost'
BF_BOOST_INC = '${BF_BOOST}/include'
BF_BOOST_LIB = 'libboost_date_time-vc90-mt-s-1_49 libboost_filesystem-vc90-mt-s-1_49 libboost_regex-vc90-mt-s-1_49 libboost_system-vc90-mt-s-1_49 libboost_thread-vc90-mt-s-1_49'
+BF_BOOST_LIB_INTERNATIONAL = ' libboost_locale-vc90-mt-s-1_49'
BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
#CUDA
@@ -207,7 +218,7 @@ C_WARN = []
CC_WARN = []
CXX_WARN = []
-LLIBS = ['ws2_32', 'vfw32', 'winmm', 'kernel32', 'user32', 'gdi32', 'comdlg32', 'advapi32', 'shfolder', 'shell32', 'ole32', 'oleaut32', 'uuid']
+LLIBS = ['ws2_32', 'vfw32', 'winmm', 'kernel32', 'user32', 'gdi32', 'comdlg32', 'advapi32', 'shfolder', 'shell32', 'ole32', 'oleaut32', 'uuid', 'psapi']
PLATFORM_LINKFLAGS = ['/SUBSYSTEM:CONSOLE','/MACHINE:X64','/STACK:2097152','/OPT:NOREF','/INCREMENTAL:NO', '/NODEFAULTLIB:msvcrt.lib', '/NODEFAULTLIB:msvcmrt.lib', '/NODEFAULTLIB:msvcurt.lib', '/NODEFAULTLIB:msvcrtd.lib']
diff --git a/build_files/scons/tools/Blender.py b/build_files/scons/tools/Blender.py
index 044b678e878..72a31598360 100644
--- a/build_files/scons/tools/Blender.py
+++ b/build_files/scons/tools/Blender.py
@@ -173,9 +173,6 @@ def setup_staticlibs(lenv):
if lenv['WITH_BF_FFMPEG'] and lenv['WITH_BF_STATICFFMPEG']:
statlibs += Split(lenv['BF_FFMPEG_LIB_STATIC'])
if lenv['WITH_BF_INTERNATIONAL']:
- libincs += Split(lenv['BF_GETTEXT_LIBPATH'])
- if lenv['WITH_BF_GETTEXT_STATIC']:
- statlibs += Split(lenv['BF_GETTEXT_LIB_STATIC'])
if lenv['WITH_BF_FREETYPE_STATIC']:
statlibs += Split(lenv['BF_FREETYPE_LIB_STATIC'])
if lenv['WITH_BF_OPENAL']:
@@ -225,6 +222,16 @@ def setup_staticlibs(lenv):
if lenv['WITH_BF_STATICBOOST']:
statlibs += Split(lenv['BF_BOOST_LIB_STATIC'])
+ if lenv['WITH_BF_CYCLES_OSL']:
+ libincs += Split(lenv['BF_OSL_LIBPATH'])
+ if lenv['WITH_BF_STATICOSL']:
+ statlibs += Split(lenv['BF_OSL_LIB_STATIC'])
+
+ if lenv['WITH_BF_LLVM']:
+ libincs += Split(lenv['BF_LLVM_LIBPATH'])
+ if lenv['WITH_BF_STATICLLVM']:
+ statlibs += Split(lenv['BF_LLVM_LIB_STATIC'])
+
# setting this last so any overriding of manually libs could be handled
if lenv['OURPLATFORM'] not in ('win32-vc', 'win32-mingw', 'win64-vc', 'linuxcross', 'win64-mingw'):
libincs.append('/usr/lib')
@@ -252,8 +259,6 @@ def setup_syslibs(lenv):
syslibs.append(lenv['BF_PYTHON_LIB']+'_d')
else:
syslibs.append(lenv['BF_PYTHON_LIB'])
- if lenv['WITH_BF_INTERNATIONAL'] and not lenv['WITH_BF_GETTEXT_STATIC']:
- syslibs += Split(lenv['BF_GETTEXT_LIB'])
if lenv['WITH_BF_OPENAL']:
if not lenv['WITH_BF_STATICOPENAL']:
syslibs += Split(lenv['BF_OPENAL_LIB'])
@@ -315,6 +320,15 @@ def setup_syslibs(lenv):
if lenv['WITH_BF_BOOST'] and not lenv['WITH_BF_STATICBOOST']:
syslibs += Split(lenv['BF_BOOST_LIB'])
+
+ if lenv['WITH_BF_INTERNATIONAL']:
+ syslibs += Split(lenv['BF_BOOST_LIB_INTERNATIONAL'])
+
+ if lenv['WITH_BF_CYCLES_OSL'] and not lenv['WITH_BF_STATICOSL']:
+ syslibs += Split(lenv['BF_OSL_LIB'])
+
+ if lenv['WITH_BF_LLVM'] and not lenv['WITH_BF_STATICLLVM']:
+ syslibs += Split(lenv['BF_LLVM_LIB'])
if not lenv['WITH_BF_STATICJPEG']:
syslibs += Split(lenv['BF_JPEG_LIB'])
@@ -582,8 +596,8 @@ def AppIt(target=None, source=None, env=None):
bldroot = env.Dir('.').abspath
binary = env['BINARYKIND']
- sourcedir = bldroot + '/source/darwin/%s.app'%binary
- sourceinfo = bldroot + "/source/darwin/%s.app/Contents/Info.plist"%binary
+ sourcedir = bldroot + '/release/darwin/%s.app' % binary
+ sourceinfo = bldroot + "/release/darwin/%s.app/Contents/Info.plist"%binary
targetinfo = installdir +'/' + "%s.app/Contents/Info.plist"%binary
cmd = installdir + '/' +'%s.app'%binary
@@ -638,6 +652,14 @@ def AppIt(target=None, source=None, env=None):
cmd = 'cp -R %s/../intern/cycles/kernel/*.cubin %s/lib/' % (builddir, cinstalldir)
commands.getoutput(cmd)
+ if env['WITH_BF_CYCLES_OSL']:
+ cmd = 'mkdir %s/shader' % (cinstalldir)
+ commands.getoutput(cmd)
+ cmd = 'cp -R %s/kernel/shaders/*.h %s/shader' % (croot, cinstalldir)
+ commands.getoutput(cmd)
+ cmd = 'cp -R %s/../intern/cycles/kernel/shaders/*.oso %s/shader' % (builddir, cinstalldir)
+ commands.getoutput(cmd)
+
if env['WITH_OSX_STATICPYTHON']:
cmd = 'mkdir %s/%s.app/Contents/MacOS/%s/python/'%(installdir,binary, VERSION)
commands.getoutput(cmd)
@@ -664,7 +686,7 @@ def AppIt(target=None, source=None, env=None):
commands.getoutput(cmd)
cmd = 'rm -rf %s/set_simulation_threads.app'%(installdir) # first clear omp_num_threads applescript
commands.getoutput(cmd)
- cmd = 'cp -R %s/source/darwin/set_simulation_threads.app %s/'%(bldroot, installdir) # copy the omp_num_threads applescript
+ cmd = 'cp -R %s/release/darwin/set_simulation_threads.app %s/'%(bldroot, installdir) # copy the omp_num_threads applescript
commands.getoutput(cmd)
# extract copy system python, be sure to update other build systems
@@ -792,6 +814,20 @@ class BlenderEnvironment(SConsEnvironment):
def BlenderLib(self=None, libname=None, sources=None, includes=[], defines=[], libtype='common', priority = 100, compileflags=None, cc_compileflags=None, cxx_compileflags=None, cc_compilerchange=None, cxx_compilerchange=None):
global vcp
+
+ # sanity check
+ # run once in a while to check we dont have duplicates
+ if 0:
+ for name, dirs in (("source", sources), ("include", includes)):
+ files_clean = [os.path.normpath(f) for f in dirs]
+ files_clean_set = set(files_clean)
+ if len(files_clean) != len(files_clean_set):
+ for f in sorted(files_clean_set):
+ if f != '.' and files_clean.count(f) > 1:
+ raise Exception("Found duplicate %s %r" % (name, f))
+ del name, dirs, files_clean, files_clean_set, f
+ # end sanity check
+
if not self or not libname or not sources:
print bc.FAIL+'Cannot continue. Missing argument for BuildBlenderLib '+libname+bc.ENDC
self.Exit()
@@ -874,6 +910,7 @@ class BlenderEnvironment(SConsEnvironment):
print bc.HEADER+'Configuring program '+bc.ENDC+bc.OKGREEN+progname+bc.ENDC
lenv = self.Clone()
lenv.Append(LINKFLAGS = lenv['PLATFORM_LINKFLAGS'])
+ lenv.Append(LINKFLAGS = lenv['BF_PROGRAM_LINKFLAGS'])
if lenv['OURPLATFORM'] in ('win32-mingw', 'win64-mingw', 'linuxcross', 'cygwin', 'linux'):
lenv.Replace(LINK = '$CXX')
if lenv['OURPLATFORM'] in ('win32-vc', 'cygwin', 'win64-vc'):
diff --git a/build_files/scons/tools/btools.py b/build_files/scons/tools/btools.py
index 19652bb7851..ab963d4543c 100644
--- a/build_files/scons/tools/btools.py
+++ b/build_files/scons/tools/btools.py
@@ -116,7 +116,6 @@ def validate_arguments(args, bc):
'WITH_BF_TIFF', 'BF_TIFF', 'BF_TIFF_INC', 'BF_TIFF_LIB', 'BF_TIFF_LIBPATH', 'WITH_BF_STATICTIFF', 'BF_TIFF_LIB_STATIC',
'WITH_BF_ZLIB', 'BF_ZLIB', 'BF_ZLIB_INC', 'BF_ZLIB_LIB', 'BF_ZLIB_LIBPATH', 'WITH_BF_STATICZLIB', 'BF_ZLIB_LIB_STATIC',
'WITH_BF_INTERNATIONAL',
- 'BF_GETTEXT', 'BF_GETTEXT_INC', 'BF_GETTEXT_LIB', 'WITH_BF_GETTEXT_STATIC', 'BF_GETTEXT_LIB_STATIC', 'BF_GETTEXT_LIBPATH',
'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',
@@ -164,8 +163,10 @@ def validate_arguments(args, bc):
'WITH_BF_CYCLES', 'WITH_BF_CYCLES_CUDA_BINARIES', 'BF_CYCLES_CUDA_NVCC', 'BF_CYCLES_CUDA_NVCC', 'WITH_BF_CYCLES_CUDA_THREADED_COMPILE',
'WITH_BF_OIIO', 'WITH_BF_STATICOIIO', 'BF_OIIO', 'BF_OIIO_INC', 'BF_OIIO_LIB', 'BF_OIIO_LIB_STATIC', 'BF_OIIO_LIBPATH',
'WITH_BF_OCIO', 'WITH_BF_STATICOCIO', 'BF_OCIO', 'BF_OCIO_INC', 'BF_OCIO_LIB', 'BF_OCIO_LIB_STATIC', 'BF_OCIO_LIBPATH',
- 'WITH_BF_BOOST', 'WITH_BF_STATICBOOST', 'BF_BOOST', 'BF_BOOST_INC', 'BF_BOOST_LIB', 'BF_BOOST_LIB_STATIC', 'BF_BOOST_LIBPATH',
- 'WITH_BF_LIBMV'
+ 'WITH_BF_BOOST', 'WITH_BF_STATICBOOST', 'BF_BOOST', 'BF_BOOST_INC', 'BF_BOOST_LIB', 'BF_BOOST_LIB_INTERNATIONAL', 'BF_BOOST_LIB_STATIC', 'BF_BOOST_LIBPATH',
+ 'WITH_BF_LIBMV',
+ 'WITH_BF_CYCLES_OSL', 'WITH_BF_STATICOSL', 'BF_OSL', 'BF_OSL_INC', 'BF_OSL_LIB', 'BF_OSL_LIBPATH', 'BF_OSL_LIB_STATIC', 'BF_OSL_COMPILER',
+ 'WITH_BF_LLVM', 'WITH_BF_STATICLLVM', 'BF_LLVM', 'BF_LLVM_LIB', 'BF_LLVM_LIBPATH', 'BF_LLVM_LIB_STATIC', 'BF_PROGRAM_LINKFLAGS'
]
# Have options here that scons expects to be lists
@@ -179,7 +180,7 @@ def validate_arguments(args, bc):
'BF_DEBUG_CFLAGS', 'BF_DEBUG_CCFLAGS', 'BF_DEBUG_CXXFLAGS',
'C_WARN', 'CC_WARN', 'CXX_WARN',
'LLIBS', 'PLATFORM_LINKFLAGS','MACOSX_ARCHITECTURE', 'MACOSX_SDK_CHECK', 'XCODE_CUR_VER',
- 'BF_CYCLES_CUDA_BINARIES_ARCH',
+ 'BF_CYCLES_CUDA_BINARIES_ARCH', 'BF_PROGRAM_LINKFLAGS', 'MACOSX_DEPLOYMENT_TARGET'
]
@@ -381,15 +382,8 @@ def read_opts(env, cfg, args):
('BF_ZLIB_LIBPATH', 'ZLib library path', ''),
('BF_ZLIB_LIB_STATIC', 'ZLib static library', ''),
- (BoolVariable('WITH_BF_INTERNATIONAL', 'Use Gettext if true', True)),
+ (BoolVariable('WITH_BF_INTERNATIONAL', 'Use Boost::locale if true', True)),
- ('BF_GETTEXT', 'gettext base path', ''),
- ('BF_GETTEXT_INC', 'gettext include path', ''),
- ('BF_GETTEXT_LIB', 'gettext library', ''),
- (BoolVariable('WITH_BF_GETTEXT_STATIC', 'Use static gettext library if true', False)),
- ('BF_GETTEXT_LIB_STATIC', 'static gettext library', ''),
- ('BF_GETTEXT_LIBPATH', 'gettext library path', ''),
-
(BoolVariable('WITH_BF_ICONV', 'Use iconv if true', True)),
('BF_ICONV', 'iconv base path', ''),
('BF_ICONV_INC', 'iconv include path', ''),
@@ -508,8 +502,9 @@ def read_opts(env, cfg, args):
('LLIBS', 'Platform libs', []),
('PLATFORM_LINKFLAGS', 'Platform linkflags', []),
('MACOSX_ARCHITECTURE', 'python_arch.zip select', ''),
- ('MACOSX_SDK_CHECK', 'detect available OSX sdk`s', ''),
- ('XCODE_CUR_VER', 'detect XCode version', ''),
+ ('MACOSX_SDK_CHECK', 'Detect available OS X SDK`s', ''),
+ ('XCODE_CUR_VER', 'Detect XCode version', ''),
+ ('MACOSX_DEPLOYMENT_TARGET', 'Detect OS X target version', ''),
(BoolVariable('BF_PROFILE', 'Add profiling information if true', False)),
('BF_PROFILE_CFLAGS', 'C only profiling flags', []),
@@ -598,11 +593,30 @@ def read_opts(env, cfg, args):
('BF_BOOST', 'Boost root path', ''),
('BF_BOOST_INC', 'Boost include path', ''),
('BF_BOOST_LIB', 'Boost library', ''),
+ ('BF_BOOST_LIB_INTERNATIONAL', 'Boost library', ''),
('BF_BOOST_LIBPATH', 'Boost library path', ''),
('BF_BOOST_LIB_STATIC', 'Boost static library', ''),
(BoolVariable('WITH_GHOST_XDND', 'Build with drag-n-drop support on Linux platforms using XDND protocol', True)),
- (BoolVariable('WITH_BF_COMPOSITOR_LEGACY', 'Enable the legacy compositor', False))
+ (BoolVariable('WITH_BF_COMPOSITOR_LEGACY', 'Enable the legacy compositor', False)),
+
+ (BoolVariable('WITH_BF_CYCLES_OSL', 'Build with OSL sypport in Cycles', False)),
+ (BoolVariable('WITH_BF_STATICOSL', 'Staticly link to OSL', False)),
+ ('BF_OSL', 'OSL root path', ''),
+ ('BF_OSL_INC', 'OSL include path', ''),
+ ('BF_OSL_LIB', 'OSL library', ''),
+ ('BF_OSL_LIBPATH', 'OSL library path', ''),
+ ('BF_OSL_LIB_STATIC', 'OSL static library', ''),
+ ('BF_OSL_COMPILER', 'OSL compiler', ''),
+
+ (BoolVariable('WITH_BF_LLVM', 'Build with LLVM sypport (required for OSL)', False)),
+ (BoolVariable('WITH_BF_STATICLLVM', 'Staticly link to LLVM', False)),
+ ('BF_LLVM', 'LLVM root path', ''),
+ ('BF_LLVM_LIB', 'LLVM library', ''),
+ ('BF_LLVM_LIBPATH', 'LLVM library path', ''),
+ ('BF_LLVM_LIB_STATIC', 'LLVM static library', ''),
+
+ ('BF_PROGRAM_LINKFLAGS', 'Link flags applied only to final binaries (blender and blenderplayer, not makesrna/makesdna)', '')
) # end of opts.AddOptions()
return localopts
@@ -673,7 +687,7 @@ def buildslave(target=None, source=None, env=None):
elif bitness == '32bit':
platform = 'linux-' + glibc + '-i686'
if platform == 'darwin':
- platform = 'OSX-' + env['MACOSX_ARCHITECTURE']
+ platform = 'OSX-' + env['MACOSX_DEPLOYMENT_TARGET'] + '-' + env['MACOSX_ARCHITECTURE']
branch = env['BUILDBOT_BRANCH']
diff --git a/doc/python_api/rst/bge.logic.rst b/doc/python_api/rst/bge.logic.rst
index 616ee12bba0..76e28c6d04b 100644
--- a/doc/python_api/rst/bge.logic.rst
+++ b/doc/python_api/rst/bge.logic.rst
@@ -260,13 +260,6 @@ General functions
:rtype: list [float], len(getSpectrum()) == 512
-.. function:: stopDSP()
-
- Stops the sound driver using DSP effects.
-
- Only the fmod sound driver supports this.
- DSP can be computationally expensive.
-
.. function:: getMaxLogicFrame()
Gets the maximum number of logic frames per render frame.
@@ -337,6 +330,24 @@ General functions
.. warning: Not implimented yet
+.. function:: getExitKey()
+
+ Gets the key used to exit the game engine
+
+ :return: The key (defaults to :mod:`bge.events.ESCKEY`)
+ :rtype: int
+
+.. function:: setExitKey(key)
+
+ Sets the key used to exit the game engine
+
+ :arg key: A key constant from :mod:`bge.events`
+ :type key: int
+
+.. function:: NextFrame()
+
+ Render next frame (if Python has control)
+
*****************
Utility functions
*****************
@@ -379,6 +390,10 @@ Utility functions
.. function:: PrintGLInfo()
Prints GL Extension Info into the console
+
+.. function:: PrintMemInfo()
+
+ Prints engine statistics into the console
*********
Constants
@@ -407,6 +422,45 @@ Sensor Status
.. data:: KX_SENSOR_ACTIVE
.. data:: KX_SENSOR_JUST_DEACTIVATED
+-------------
+Armature Sensor
+-------------
+
+.. _armaturesensor-type:
+
+See :class:`bge.types.KX_ArmatureSensor.type`
+
+.. data:: KX_ARMSENSOR_STATE_CHANGED
+
+ Detect that the constraint is changing state (active/inactive)
+
+ :value: 0
+
+.. data:: KX_ARMSENSOR_LIN_ERROR_BELOW
+
+ Detect that the constraint linear error is above a threshold
+
+ :value: 1
+
+.. data:: KX_ARMSENSOR_LIN_ERROR_ABOVE
+
+ Detect that the constraint linear error is below a threshold
+
+ :value: 2
+
+.. data:: KX_ARMSENSOR_ROT_ERROR_BELOW
+
+ Detect that the constraint rotation error is above a threshold
+
+ :value: 3
+
+.. data:: KX_ARMSENSOR_ROT_ERROR_ABOVE
+
+ Detect that the constraint rotation error is below a threshold
+
+ :value: 4
+
+
.. _logic-property-sensor:
---------------
@@ -489,6 +543,52 @@ See :class:`bge.types.BL_ActionActuator`
.. data:: KX_ACTIONACT_LOOPEND
.. data:: KX_ACTIONACT_PROPERTY
+---------------
+Armature Actuator
+---------------
+
+ .. _armatureactuator-constants-type:
+
+See :class:`bge.types.BL_ArmatureActuator.type`
+
+.. data:: KX_ACT_ARMATURE_RUN
+
+ Just make sure the armature will be updated on the next graphic frame.
+ This is the only persistent mode of the actuator:
+ it executes automatically once per frame until stopped by a controller
+
+ :value: 0
+
+.. 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
+
+ Change target and subtarget of constraint.
+
+ :value: 3
+
+.. data:: KX_ACT_ARMATURE_SETWEIGHT
+
+ Change weight of constraint (IK only).
+
+ :value: 4
+
+.. data:: KX_ACT_ARMATURE_SETINFLUENCE
+
+ Change influence of constraint.
+
+ :value: 5
+
-------------------
Constraint Actuator
-------------------
@@ -499,31 +599,31 @@ See :class:`bge.types.KX_ConstraintActuator.option`
* Applicable to Distance constraint:
- .. data:: KX_ACT_CONSTRAINT_NORMAL
+.. data:: KX_CONSTRAINTACT_NORMAL
Activate alignment to surface
- .. data:: KX_ACT_CONSTRAINT_DISTANCE
+.. data:: KX_CONSTRAINTACT_DISTANCE
Activate distance control
- .. data:: KX_ACT_CONSTRAINT_LOCAL
+.. data:: KX_CONSTRAINTACT_LOCAL
Direction of the ray is along the local axis
* Applicable to Force field constraint:
- .. data:: KX_ACT_CONSTRAINT_DOROTFH
+.. data:: KX_CONSTRAINTACT_DOROTFH
Force field act on rotation as well
* Applicable to both:
- .. data:: KX_ACT_CONSTRAINT_MATERIAL
+.. data:: KX_CONSTRAINTACT_MATERIAL
Detect material rather than property
- .. data:: KX_ACT_CONSTRAINT_PERMANENT
+.. data:: KX_CONSTRAINTACT_PERMANENT
No deactivation if ray does not hit target
@@ -591,27 +691,27 @@ See :class:`bge.types.KX_ConstraintActuator.limit`
Set orientation of Z axis
-.. data:: KX_ACT_CONSTRAINT_FHNX
+.. data:: KX_CONSTRAINTACT_FHNX
Set force field along negative X axis
-.. data:: KX_ACT_CONSTRAINT_FHNY
+.. data:: KX_CONSTRAINTACT_FHNY
Set force field along negative Y axis
-.. data:: KX_ACT_CONSTRAINT_FHNZ
+.. data:: KX_CONSTRAINTACT_FHNZ
Set force field along negative Z axis
-.. data:: KX_ACT_CONSTRAINT_FHPX
+.. data:: KX_CONSTRAINTACT_FHPX
Set force field along positive X axis
-.. data:: KX_ACT_CONSTRAINT_FHPY
+.. data:: KX_CONSTRAINTACT_FHPY
Set force field along positive Y axis
-.. data:: KX_ACT_CONSTRAINT_FHPZ
+.. data:: KX_CONSTRAINTACT_FHPZ
Set force field along positive Z axis
@@ -714,101 +814,31 @@ See :class:`bge.types.KX_SoundActuator`
.. data:: KX_SOUNDACT_LOOPBIDIRECTIONAL_STOP
:value: 6
-
-
-=======
-Various
-=======
-
-.. _input-status:
-
-------------
-Input Status
-------------
-
-See :class:`bge.types.SCA_PythonKeyboard`, :class:`bge.types.SCA_PythonMouse`, :class:`bge.types.SCA_MouseSensor`, :class:`bge.types.SCA_KeyboardSensor`
-
-.. data:: KX_INPUT_NONE
-.. data:: KX_INPUT_JUST_ACTIVATED
-.. data:: KX_INPUT_ACTIVE
-.. data:: KX_INPUT_JUST_RELEASED
-
--------------
-Mouse Buttons
--------------
-
-See :class:`bge.types.SCA_MouseSensor`
-.. data:: KX_MOUSE_BUT_LEFT
-.. data:: KX_MOUSE_BUT_MIDDLE
-.. data:: KX_MOUSE_BUT_RIGHT
-
-------
-States
-------
+--------------
+Steering Actuator
+--------------
-See :class:`bge.types.KX_StateActuator`
+.. _logic-steering-actuator:
-.. data:: KX_STATE1
-.. data:: KX_STATE2
-.. data:: KX_STATE3
-.. data:: KX_STATE4
-.. data:: KX_STATE5
-.. data:: KX_STATE6
-.. data:: KX_STATE7
-.. data:: KX_STATE8
-.. data:: KX_STATE9
-.. data:: KX_STATE10
-.. data:: KX_STATE11
-.. data:: KX_STATE12
-.. data:: KX_STATE13
-.. data:: KX_STATE14
-.. data:: KX_STATE15
-.. data:: KX_STATE16
-.. data:: KX_STATE17
-.. data:: KX_STATE18
-.. data:: KX_STATE19
-.. data:: KX_STATE20
-.. data:: KX_STATE21
-.. data:: KX_STATE22
-.. data:: KX_STATE23
-.. data:: KX_STATE24
-.. data:: KX_STATE25
-.. data:: KX_STATE26
-.. data:: KX_STATE27
-.. data:: KX_STATE28
-.. data:: KX_STATE29
-.. data:: KX_STATE30
+See :class:`bge.types.KX_SteeringActuator.behavior`
-.. _state-actuator-operation:
+.. data:: KX_STEERING_SEEK
-See :class:`bge.types.KX_StateActuator.operation`
+ :value: 1
-.. data:: KX_STATE_OP_CLR
+.. data:: KX_STEERING_FLEE
- Substract bits to state mask
-
- :value: 0
+ :value: 2
-.. data:: KX_STATE_OP_CPY
+.. data:: KX_STEERING_PATHFOLLOWING
- Copy state mask
-
- :value: 1
-
-.. data:: KX_STATE_OP_NEG
+ :value: 3
- Invert bits to state mask
-
- :value: 2
-
-.. data:: KX_STATE_OP_SET
- Add bits to state mask
-
- :value: 3
-
-.. _Two-D-FilterActuator-mode:
+=======
+Various
+=======
---------
2D Filter
@@ -883,6 +913,227 @@ See :class:`bge.types.KX_StateActuator.operation`
.. data:: RAS_2DFILTER_SOBEL
:value: 7
+
+----------------
+Armature Channel
+----------------
+.. _armaturechannel-constants-rotation-mode:
+
+See :class:`bge.types.BL_ArmatureChannel.rotation_mode`
+
+.. note:
+ euler mode are named as in Blender UI but the actual axis order is reversed
+
+.. data:: ROT_MODE_QUAT
+
+ Use quaternion in rotation attribute to update bone rotation.
+
+ :value: 0
+
+.. data:: ROT_MODE_XYZ
+
+ Use euler_rotation and apply angles on bone's Z, Y, X axis successively.
+
+ :value: 1
+
+.. data:: ROT_MODE_XZY
+
+ Use euler_rotation and apply angles on bone's Y, Z, X axis successively.
+
+ :value: 2
+
+.. data:: ROT_MODE_YXZ
+
+ Use euler_rotation and apply angles on bone's Z, X, Y axis successively.
+
+ :value: 3
+
+.. data:: ROT_MODE_YZX
+
+ Use euler_rotation and apply angles on bone's X, Z, Y axis successively.
+
+ :value: 4
+
+.. data:: ROT_MODE_ZXY
+
+ Use euler_rotation and apply angles on bone's Y, X, Z axis successively.
+
+ :value: 5
+
+.. data:: ROT_MODE_ZYX
+
+ Use euler_rotation and apply angles on bone's X, Y, Z axis successively.
+
+ :value: 6
+
+
+----------------
+Armature Constraint
+----------------
+.. _armatureconstraint-constants-type:
+
+See :class:`bge.types.BL_ArmatureConstraint.type`
+
+.. data:: CONSTRAINT_TYPE_TRACKTO
+.. data:: CONSTRAINT_TYPE_KINEMATIC
+.. data:: CONSTRAINT_TYPE_ROTLIKE
+.. data:: CONSTRAINT_TYPE_LOCLIKE
+.. data:: CONSTRAINT_TYPE_MINMAX
+.. data:: CONSTRAINT_TYPE_SIZELIKE
+.. data:: CONSTRAINT_TYPE_LOCKTRACK
+.. data:: CONSTRAINT_TYPE_STRETCHTO
+.. data:: CONSTRAINT_TYPE_CLAMPTO
+.. data:: CONSTRAINT_TYPE_TRANSFORM
+.. data:: CONSTRAINT_TYPE_DISTLIMIT
+
+.. _armatureconstraint-constants-ik-type:
+
+See :class:`bge.types.BL_ArmatureConstraint.ik_type`
+
+.. data:: CONSTRAINT_IK_COPYPOSE
+
+ constraint is trying to match the position and eventually the rotation of the target.
+
+ :value: 0
+
+.. data:: CONSTRAINT_IK_DISTANCE
+
+ Constraint is maintaining a certain distance to target subject to ik_mode
+
+ :value: 1
+
+.. _armatureconstraint-constants-ik-flag:
+
+See :class:`bge.types.BL_ArmatureConstraint.ik_flag`
+
+.. data:: CONSTRAINT_IK_FLAG_TIP
+
+ Set when the constraint operates on the head of the bone and not the tail
+
+ :value: 1
+
+.. data:: CONSTRAINT_IK_FLAG_ROT
+
+ Set when the constraint tries to match the orientation of the target
+
+ :value: 2
+
+.. data:: CONSTRAINT_IK_FLAG_STRETCH
+
+ Set when the armature is allowed to stretch (only the bones with stretch factor > 0.0)
+
+ :value: 16
+
+.. data:: CONSTRAINT_IK_FLAG_POS
+
+ Set when the constraint tries to match the position of the target.
+
+ :value: 32
+
+.. _armatureconstraint-constants-ik-mode:
+
+See :class:`bge.types.BL_ArmatureConstraint.ik_mode`
+
+.. data:: CONSTRAINT_IK_MODE_INSIDE
+
+ The constraint tries to keep the bone within ik_dist of target
+
+ :value: 0
+
+.. data:: CONSTRAINT_IK_MODE_OUTSIDE
+
+ The constraint tries to keep the bone outside ik_dist of the target
+
+ :value: 1
+
+.. data:: CONSTRAINT_IK_MODE_ONSURFACE
+
+ The constraint tries to keep the bone exactly at ik_dist of the target.
+
+ :value: 2
+
+.. _input-status:
+
+----------------
+Blender Material
+----------------
+
+.. data:: BL_DST_ALPHA
+.. data:: BL_DST_COLOR
+.. data:: BL_ONE
+.. data:: BL_ONE_MINUS_DST_ALPHA
+.. data:: BL_ONE_MINUS_DST_COLOR
+.. data:: BL_ONE_MINUS_SRC_ALPHA
+.. data:: BL_ONE_MINUS_SRC_COLOR
+.. data:: BL_SRC_ALPHA
+.. data:: BL_SRC_ALPHA_SATURATE
+.. data:: BL_SRC_COLOR
+.. data:: BL_ZERO
+
+------------
+Input Status
+------------
+
+See :class:`bge.types.SCA_PythonKeyboard`, :class:`bge.types.SCA_PythonMouse`, :class:`bge.types.SCA_MouseSensor`, :class:`bge.types.SCA_KeyboardSensor`
+
+.. data:: KX_INPUT_NONE
+.. data:: KX_INPUT_JUST_ACTIVATED
+.. data:: KX_INPUT_ACTIVE
+.. data:: KX_INPUT_JUST_RELEASED
+
+------------
+KX_GameObject
+-----------
+.. _gameobject-playaction-mode:
+
+See :class:`bge.types.KX_GameObject.playAction`
+
+.. data:: KX_ACTION_MODE_PLAY
+
+ Play the action once.
+
+ :value: 0
+
+.. data:: KX_ACTION_MODE_LOOP
+
+ Loop the action (repeat it).
+
+ :value: 1
+
+.. data:: KX_ACTION_MODE_PING_PONG
+
+ Play the action one direct then back the other way when it has completed.
+
+ :value: 2
+
+
+-------------
+Mouse Buttons
+-------------
+
+See :class:`bge.types.SCA_MouseSensor`
+
+.. data:: KX_MOUSE_BUT_LEFT
+.. data:: KX_MOUSE_BUT_MIDDLE
+.. data:: KX_MOUSE_BUT_RIGHT
+
+------------
+Navigation Mesh Draw Modes
+------------
+
+.. _navmesh-draw-mode:
+
+.. data:: RM_WALLS
+
+ Draw only the walls.
+
+.. data:: RM_POLYS
+
+ Draw only polygons.
+
+.. data:: RM_TRIS
+
+ Draw triangle mesh.
------
Shader
@@ -910,18 +1161,69 @@ Shader
.. data:: SHD_TANGENT
-----------------
-Blender Material
-----------------
+------
+States
+------
-.. data:: BL_DST_ALPHA
-.. data:: BL_DST_COLOR
-.. data:: BL_ONE
-.. data:: BL_ONE_MINUS_DST_ALPHA
-.. data:: BL_ONE_MINUS_DST_COLOR
-.. data:: BL_ONE_MINUS_SRC_ALPHA
-.. data:: BL_ONE_MINUS_SRC_COLOR
-.. data:: BL_SRC_ALPHA
-.. data:: BL_SRC_ALPHA_SATURATE
-.. data:: BL_SRC_COLOR
-.. data:: BL_ZERO
+See :class:`bge.types.KX_StateActuator`
+
+.. data:: KX_STATE1
+.. data:: KX_STATE2
+.. data:: KX_STATE3
+.. data:: KX_STATE4
+.. data:: KX_STATE5
+.. data:: KX_STATE6
+.. data:: KX_STATE7
+.. data:: KX_STATE8
+.. data:: KX_STATE9
+.. data:: KX_STATE10
+.. data:: KX_STATE11
+.. data:: KX_STATE12
+.. data:: KX_STATE13
+.. data:: KX_STATE14
+.. data:: KX_STATE15
+.. data:: KX_STATE16
+.. data:: KX_STATE17
+.. data:: KX_STATE18
+.. data:: KX_STATE19
+.. data:: KX_STATE20
+.. data:: KX_STATE21
+.. data:: KX_STATE22
+.. data:: KX_STATE23
+.. data:: KX_STATE24
+.. data:: KX_STATE25
+.. data:: KX_STATE26
+.. data:: KX_STATE27
+.. data:: KX_STATE28
+.. data:: KX_STATE29
+.. data:: KX_STATE30
+
+.. _state-actuator-operation:
+
+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 94729dd7d4f..bfe1dc785ab 100644
--- a/doc/python_api/rst/bge.types.rst
+++ b/doc/python_api/rst/bge.types.rst
@@ -205,6 +205,18 @@ Types
:type: boolean
+ .. attribute:: pos_ticks
+
+ The number of ticks since the last positive pulse (read-only).
+
+ :type: int
+
+ .. attribute:: neg_ticks
+
+ The number of ticks since the last negative pulse (read-only).
+
+ :type: int
+
.. attribute:: status
The status of the sensor (read-only): can be one of :ref:`these constants<sensor-status>`.
@@ -621,6 +633,71 @@ Types
:type: string
+
+.. class:: KX_SteeringActuator(SCA_IActuator)
+
+ Steering Actuator for navigation.
+
+ .. attribute:: behavior
+
+ The steering behavior to use.
+
+ :type: one of :ref:`these constants <logic-steering-actuator>`
+
+ .. attribute:: velocity
+
+ Velocity magnitude
+
+ :type: float
+
+ .. attribute:: acceleration
+
+ Max acceleration
+
+ :type: float
+
+ .. attribute:: turnspeed
+
+ Max turn speed
+
+ :type: float
+
+ .. attribute:: distance
+
+ Relax distance
+
+ :type: float
+
+ .. attribute:: target
+
+ Target object
+
+ :type: :class:`KX_GameObject`
+
+ .. attribute:: navmesh
+
+ Navigation mesh
+
+ :type: :class:`KX_GameObject`
+
+ .. attribute:: selfterminated
+
+ Terminate when target is reached
+
+ :type: boolean
+
+ .. attribute:: enableVisualization
+
+ Enable debug visualization
+
+ :type: boolean
+
+ .. attribute:: pathUpdatePeriod
+
+ Path update period
+
+ :type: int
+
.. class:: CListValue(CPropValue)
This is a list like object used in the game engine internally that behaves similar to a python list in most ways.
@@ -686,6 +763,24 @@ Types
KX_BlenderMaterial
+ .. attribute:: shader
+
+ The materials shader.
+
+ :type: :class:`BL_Shader`
+
+ .. attribute:: blending
+
+ Ints used for pixel blending, (src, dst), matching the setBlending method.
+
+ :type: (integer, integer)
+
+ .. attribute:: material_index
+
+ The material's index.
+
+ :type: integer
+
.. method:: getShader()
Returns the material's shader.
@@ -743,7 +838,13 @@ Types
strength of of the camera following movement.
:type: float
-
+
+ .. attribute:: axis
+
+ The camera axis (0, 1, 2) for positive ``XYZ``, (3, 4, 5) for negative ``XYZ``.
+
+ :type: int
+
.. attribute:: min
minimum distance to the target object maintained by the actuator.
@@ -762,12 +863,6 @@ Types
:type: float
- .. attribute:: useXY
-
- axis this actuator is tracking, True=X, False=Y.
-
- :type: boolean
-
.. attribute:: object
the object this actuator tracks.
@@ -988,14 +1083,14 @@ Types
The object's parent object. (read-only).
:type: :class:`KX_GameObject` or None
-
- .. attribute:: group_children
+
+ .. attribute:: groupMembers
Returns the list of group members if the object is a group object, otherwise None is returned.
:type: :class:`CListValue` of :class:`KX_GameObject` or None
- .. attribute:: group_parent
+ .. attribute:: groupObject
Returns the group object that the object belongs to or None if the object is not part of a group.
@@ -1100,30 +1195,30 @@ Types
The object's world space transform matrix. 4x4 Matrix.
:type: :class:`mathutils.Matrix`
-
+
.. attribute:: localLinearVelocity
- The object's local linear velocity. [x, y, z]
-
- :type: :class:`mathutils.Vector`
-
+ The object's local linear velocity. [x, y, z]
+
+ :type: :class:`mathutils.Vector`
+
.. attribute:: worldLinearVelocity
The object's world linear velocity. [x, y, z]
-
- :type: :class:`mathutils.Vector`
-
+
+ :type: :class:`mathutils.Vector`
+
.. attribute:: localAngularVelocity
The object's local angular velocity. [x, y, z]
-
- :type: :class:`mathutils.Vector`
-
+
+ :type: :class:`mathutils.Vector`
+
.. attribute:: worldAngularVelocity
The object's world angular velocity. [x, y, z]
-
- :type: :class:`mathutils.Vector`
+
+ :type: :class:`mathutils.Vector`
.. attribute:: timeOffset
@@ -1211,6 +1306,13 @@ Types
:type: :class:`CListValue` of :class:`KX_GameObject`'s
+ .. attribute:: life
+
+ The number of seconds until the object ends, assumes 50fps.
+ (when added with an add object actuator), (read-only).
+
+ :type: float
+
.. method:: endObject()
Delete this object, can be used in place of the EndObject Actuator.
@@ -1653,7 +1755,7 @@ Types
:arg blendin: the amount of blending between this animation and the previous one on this layer
:type blendin: float
:arg play_mode: the play mode
- :type play_mode: KX_ACTION_MODE_PLAY, KX_ACTION_MODE_LOOP, or KX_ACTION_MODE_PING_PONG
+ :type play_mode: one of :ref:`these constants <gameobject-playaction-mode>`
:arg layer_weight: how much of the previous layer to use for blending (0 = add)
:type layer_weight: float
:arg ipo_flags: flags for the old IPO behaviors (force, etc)
@@ -1854,10 +1956,6 @@ Types
:type: list [r, g, b]
- .. attribute:: colour
-
- Synonym for color.
-
.. attribute:: lin_attenuation
The linear component of this light's attenuation. (SPOT and NORMAL lights only).
@@ -1942,11 +2040,6 @@ Types
:type: integer
- .. method:: getNumMaterials()
-
- :return: number of materials associated with this object
- :rtype: integer
-
.. method:: getMaterialName(matid)
Gets the name of the specified material.
@@ -1987,11 +2080,6 @@ Types
:return: a vertex object.
:rtype: :class:`KX_VertexProxy`
- .. method:: getNumPolygons()
-
- :return: The number of polygon in the mesh.
- :rtype: integer
-
.. method:: getPolygon(index)
Gets the specified polygon from the mesh.
@@ -2010,7 +2098,7 @@ Types
:arg matrix: transformation matrix.
:type matrix: 4x4 matrix [[float]]
- .. method:: transform_uv(matid, matrix, uv_index=-1, uv_index_from=-1)
+ .. method:: transformUV(matid, matrix, uv_index=-1, uv_index_from=-1)
Transforms the vertices UV's of a mesh.
@@ -2222,6 +2310,52 @@ Types
:type: list of strings
+
+.. class:: KX_FontObject(KX_GameObject)
+
+ TODO.
+
+
+.. class:: KX_NavMeshObject(KX_GameObject)
+
+ Python interface for using and controlling navigation meshes.
+
+ .. method:: findPath(start, goal)
+
+ Finds the path from start to goal points.
+
+ :arg start: the start point
+ :arg start: 3D Vector
+ :arg goal: the goal point
+ :arg start: 3D Vector
+ :return: a path as a list of points
+ :rtype: list of points
+
+ .. method:: raycast(start, goal)
+
+ Raycast from start to goal points.
+
+ :arg start: the start point
+ :arg start: 3D Vector
+ :arg goal: the goal point
+ :arg start: 3D Vector
+ :return: the hit factor
+ :rtype: float
+
+ .. method:: draw(mode)
+
+ Draws a debug mesh for the navigation mesh.
+
+ :arg mode: the drawing mode (one of :ref:`these constants <navmesh-draw-mode>`)
+ :arg mode: integer
+ :return: None
+
+ .. method:: rebuild()
+
+ Rebuild the navigation mesh.
+
+ :return: None
+
.. class:: KX_ObjectActuator(SCA_IActuator)
The object actuator ("Motion Actuator") applies force, torque, displacement, angular displacement,
@@ -2375,49 +2509,6 @@ Types
:type: boolean
-.. class:: KX_PhysicsObjectWrapper(PyObjectPlus)
-
- KX_PhysicsObjectWrapper
-
- .. method:: setActive(active)
-
- Set the object to be active.
-
- :arg active: set to True to be active
- :type active: boolean
-
- .. method:: setAngularVelocity(x, y, z, local)
-
- Set the angular velocity of the object.
-
- :arg x: angular velocity for the x-axis
- :type x: float
-
- :arg y: angular velocity for the y-axis
- :type y: float
-
- :arg z: angular velocity for the z-axis
- :type z: float
-
- :arg local: set to True for local axis
- :type local: boolean
-
- .. method:: setLinearVelocity(x, y, z, local)
-
- Set the linear velocity of the object.
-
- :arg x: linear velocity for the x-axis
- :type x: float
-
- :arg y: linear velocity for the y-axis
- :type y: float
-
- :arg z: linear velocity for the z-axis
- :type z: float
-
- :arg local: set to True for local axis
- :type local: boolean
-
.. class:: KX_PolyProxy(SCA_IObject)
A polygon holds the index of the vertex forming the poylgon.
@@ -2426,7 +2517,7 @@ Types
The polygon attributes are read-only, you need to retrieve the vertex proxy if you want
to change the vertex settings.
- .. attribute:: matname
+ .. attribute:: material_name
The name of polygon material, empty if no material.
@@ -2438,13 +2529,13 @@ Types
:type: :class:`KX_PolygonMaterial` or :class:`KX_BlenderMaterial`
- .. attribute:: texture
+ .. attribute:: texture_name
The texture name of the polygon.
:type: string
- .. attribute:: matid
+ .. attribute:: material_id
The material index of the polygon, use this to retrieve vertex proxy from mesh proxy.
@@ -2675,18 +2766,6 @@ Types
:type: boolean
- .. attribute:: lightlayer
-
- Light layers this material affects.
-
- :type: bitfield.
-
- .. attribute:: triangle
-
- Mesh data with this material is triangles. It's probably not safe to change this.
-
- :type: boolean
-
.. attribute:: diffuse
The diffuse color of the material. black = [0.0, 0.0, 0.0] white = [1.0, 1.0, 1.0].
@@ -2952,8 +3031,8 @@ Types
.. method:: instantAddObject()
adds the object without needing to calling SCA_PythonController.activate()
-
- .. note:: Use objectLastCreated to get the newly created object.
+
+ .. note:: Use objectLastCreated to get the newly created object.
.. class:: KX_SCA_DynamicActuator(SCA_IActuator)
@@ -3226,6 +3305,10 @@ Types
Return the value matching key, or the default value if its not found.
:return: The key value or a default.
+ .. method:: drawObstacleSimulation()
+
+ Draw debug visualization of obstacle simulation.
+
.. class:: KX_SceneActuator(SCA_IActuator)
Scene Actuator logic brick.
@@ -3272,17 +3355,17 @@ Types
Sound Actuator.
- The :data:`startSound`, :data:`pauseSound` and :data:`stopSound` do not requirethe actuator to be activated - they act instantly provided that the actuator has been activated once at least.
+ The :data:`startSound`, :data:`pauseSound` and :data:`stopSound` do not require the actuator to be activated - they act instantly provided that the actuator has been activated once at least.
- .. attribute:: fileName
+ .. attribute:: volume
- The filename of the sound this actuator plays.
+ The volume (gain) of the sound.
- :type: string
+ :type: float
- .. attribute:: volume
+ .. attribute:: time
- The volume (gain) of the sound.
+ The current position in the audio stream (in seconds).
:type: float
@@ -3292,41 +3375,89 @@ Types
:type: float
- .. attribute:: rollOffFactor
+ .. attribute:: mode
+
+ The operation mode of the actuator. Can be one of :ref:`these constants<logic-sound-actuator>`
+
+ :type: integer
- The roll off factor. Rolloff defines the rate of attenuation as the sound gets further away.
+ .. attribute:: sound
+
+ The sound the actuator should play.
+
+ :type: Audaspace factory
+
+ .. attribute:: is3D
+
+ Whether or not the actuator should be using 3D sound. (read-only)
+
+ :type: boolean
+
+ .. attribute:: volume_maximum
+
+ The maximum gain of the sound, no matter how near it is.
:type: float
- .. attribute:: looping
+ .. attribute:: volume_minimum
- The loop mode of the actuator.
+ The minimum gain of the sound, no matter how far it is away.
- :type: integer
+ :type: float
- .. attribute:: position
+ .. attribute:: distance_reference
+
+ The distance where the sound has a gain of 1.0.
- The position of the sound as a list: [x, y, z].
+ :type: float
- :type: float array
+ .. attribute:: distance_maximum
- .. attribute:: velocity
+ The maximum distance at which you can hear the sound.
- The velocity of the emitter as a list: [x, y, z]. The relative velocity to the observer determines the pitch. List of 3 floats: [x, y, z].
+ :type: float
- :type: float array
+ .. attribute:: attenuation
- .. attribute:: orientation
+ The influence factor on volume depending on distance.
- The orientation of the sound. When setting the orientation you can also use quaternion [float, float, float, float] or euler angles [float, float, float].
+ :type: float
- :type: 3x3 matrix [[float]]
+ .. attribute:: cone_angle_inner
- .. attribute:: mode
+ The angle of the inner cone.
- The operation mode of the actuator. Can be one of :ref:`these constants<logic-sound-actuator>`
+ :type: float
- :type: integer
+ .. attribute:: cone_angle_outer
+
+ The angle of the outer cone.
+
+ :type: float
+
+ .. attribute:: cone_volume_outer
+
+ The gain outside the outer cone (the gain in the outer cone will be interpolated between this value and the normal gain in the inner cone).
+
+ :type: float
+
+ .. method:: startSound()
+
+ Starts the sound.
+
+ :return: None
+
+ .. method:: pauseSound()
+
+ Pauses the sound.
+
+ :return: None
+
+ .. method:: stopSound()
+
+ Stops the sound.
+
+ :return: None
.. class:: KX_StateActuator(SCA_IActuator)
@@ -3544,7 +3675,7 @@ Types
Whether or not the character is on the ground. (read-only)
- :type: boolean
+ :type: boolean
.. attribute:: gravity
@@ -3590,10 +3721,6 @@ Types
Black = [0.0, 0.0, 0.0, 1.0], White = [1.0, 1.0, 1.0, 1.0]
- .. attribute:: colour
-
- Synonym for color.
-
.. attribute:: x
The x coordinate of the vertex.
@@ -4320,24 +4447,6 @@ Types
:type: integer
- .. method:: setSeed(seed)
-
- Sets the seed of the random number generator.
-
- If the seed is 0, the generator will produce the same value on every call.
-
- :type seed: integer
-
- .. method:: getSeed()
-
- :return: The initial seed of the generator. Equal seeds produce equal random series.
- :rtype: integer
-
- .. method:: getLastDraw()
-
- :return: The last random number generated.
- :rtype: integer
-
.. class:: SCA_XNORController(SCA_IController)
An XNOR controller activates when all linked sensors are the same (activated or inative).
@@ -4405,7 +4514,7 @@ Types
.. attribute:: projection_matrix
This camera's 4x4 projection matrix.
-
+
.. note::
This is the identity matrix prior to rendering the first frame (any Python done on frame 1).
@@ -4658,48 +4767,6 @@ Types
Armature Actuators change constraint condition on armatures.
- .. _armatureactuator-constants-type:
-
- Constants related to :data:`~bge.types.BL_ArmatureActuator.type`
-
- .. data:: KX_ACT_ARMATURE_RUN
-
- Just make sure the armature will be updated on the next graphic frame.
- This is the only persistent mode of the actuator:
- it executes automatically once per frame until stopped by a controller
-
- :value: 0
-
- .. 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
-
- Change target and subtarget of constraint.
-
- :value: 3
-
- .. data:: KX_ACT_ARMATURE_SETWEIGHT
-
- Change weight of constraint (IK only).
-
- :value: 4
-
- .. data:: KX_ACT_ARMATURE_SETINFLUENCE
-
- Change influence of constraint.
-
- :value: 5
-
.. attribute:: type
The type of action that the actuator executes when it is active.
@@ -4754,40 +4821,6 @@ Types
Armature sensor detect conditions on armatures.
- .. _armaturesensor-type:
-
- Constants related to :data:`type`
-
- .. data:: KX_ARMSENSOR_STATE_CHANGED
-
- Detect that the constraint is changing state (active/inactive)
-
- :value: 0
-
- .. data:: KX_ARMSENSOR_LIN_ERROR_BELOW
-
- Detect that the constraint linear error is above a threshold
-
- :value: 1
-
- .. data:: KX_ARMSENSOR_LIN_ERROR_ABOVE
-
- Detect that the constraint linear error is below a threshold
-
- :value: 2
-
- .. data:: KX_ARMSENSOR_ROT_ERROR_BELOW
-
- Detect that the constraint rotation error is above a threshold
-
- :value: 3
-
- .. data:: KX_ARMSENSOR_ROT_ERROR_ABOVE
-
- Detect that the constraint rotation error is below a threshold
-
- :value: 4
-
.. attribute:: type
The type of measurement that the sensor make when it is active.
@@ -4822,87 +4855,6 @@ Types
Not all armature constraints are supported in the GE.
- .. _armatureconstraint-constants-type:
-
- Constants related to :data:`type`
-
- .. data:: CONSTRAINT_TYPE_TRACKTO
- .. data:: CONSTRAINT_TYPE_KINEMATIC
- .. data:: CONSTRAINT_TYPE_ROTLIKE
- .. data:: CONSTRAINT_TYPE_LOCLIKE
- .. data:: CONSTRAINT_TYPE_MINMAX
- .. data:: CONSTRAINT_TYPE_SIZELIKE
- .. data:: CONSTRAINT_TYPE_LOCKTRACK
- .. data:: CONSTRAINT_TYPE_STRETCHTO
- .. data:: CONSTRAINT_TYPE_CLAMPTO
- .. data:: CONSTRAINT_TYPE_TRANSFORM
- .. data:: CONSTRAINT_TYPE_DISTLIMIT
-
- .. _armatureconstraint-constants-ik-type:
-
- Constants related to :data:`ik_type`
-
- .. data:: CONSTRAINT_IK_COPYPOSE
-
- constraint is trying to match the position and eventually the rotation of the target.
-
- :value: 0
-
- .. data:: CONSTRAINT_IK_DISTANCE
-
- Constraint is maintaining a certain distance to target subject to ik_mode
-
- :value: 1
-
- .. _armatureconstraint-constants-ik-flag:
-
- Constants related to :data:`ik_flag`
-
- .. data:: CONSTRAINT_IK_FLAG_TIP
-
- Set when the constraint operates on the head of the bone and not the tail
-
- :value: 1
-
- .. data:: CONSTRAINT_IK_FLAG_ROT
-
- Set when the constraint tries to match the orientation of the target
-
- :value: 2
-
- .. data:: CONSTRAINT_IK_FLAG_STRETCH
-
- Set when the armature is allowed to stretch (only the bones with stretch factor > 0.0)
-
- :value: 16
-
- .. data:: CONSTRAINT_IK_FLAG_POS
-
- Set when the constraint tries to match the position of the target.
-
- :value: 32
-
- .. _armatureconstraint-constants-ik-mode:
-
- Constants related to :data:`ik_mode`
-
- .. data:: CONSTRAINT_IK_MODE_INSIDE
-
- The constraint tries to keep the bone within ik_dist of target
-
- :value: 0
-
- .. data:: CONSTRAINT_IK_MODE_OUTSIDE
-
- The constraint tries to keep the bone outside ik_dist of the target
-
- :value: 1
-
- .. data:: CONSTRAINT_IK_MODE_ONSURFACE
-
- The constraint tries to keep the bone exactly at ik_dist of the target.
-
- :value: 2
.. attribute:: type
@@ -5021,16 +4973,6 @@ Types
Proxy to armature pose channel. Allows to read and set armature pose.
The attributes are identical to RNA attributes, but mostly in read-only mode.
- See :data:`rotation_mode`
-
- .. data:: PCHAN_ROT_QUAT
- .. data:: PCHAN_ROT_XYZ
- .. data:: PCHAN_ROT_XZY
- .. data:: PCHAN_ROT_YXZ
- .. data:: PCHAN_ROT_YZX
- .. data:: PCHAN_ROT_ZXY
- .. data:: PCHAN_ROT_ZYX
-
.. attribute:: name
channel name (=bone name), read-only.
@@ -5164,17 +5106,7 @@ Types
Method of updating the bone rotation, read-write.
- :type: integer
-
- Use the following constants (euler mode are named as in Blender UI but the actual axis order is reversed).
-
- * PCHAN_ROT_QUAT(0) : use quaternioin in rotation attribute to update bone rotation
- * PCHAN_ROT_XYZ(1) : use euler_rotation and apply angles on bone's Z, Y, X axis successively
- * PCHAN_ROT_XZY(2) : use euler_rotation and apply angles on bone's Y, Z, X axis successively
- * PCHAN_ROT_YXZ(3) : use euler_rotation and apply angles on bone's Z, X, Y axis successively
- * PCHAN_ROT_YZX(4) : use euler_rotation and apply angles on bone's X, Z, Y axis successively
- * PCHAN_ROT_ZXY(5) : use euler_rotation and apply angles on bone's Y, X, Z axis successively
- * PCHAN_ROT_ZYX(6) : use euler_rotation and apply angles on bone's X, Y, Z axis successively
+ :type: integer (one of :ref:`these constants <armaturechannel-constants-rotation-mode>`)
.. attribute:: channel_matrix
diff --git a/doc/python_api/rst/bgl.rst b/doc/python_api/rst/bgl.rst
index 9f7817c6fa2..fc4524b1213 100644
--- a/doc/python_api/rst/bgl.rst
+++ b/doc/python_api/rst/bgl.rst
@@ -689,7 +689,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
Return the specified pixel map
- .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glGetPixelMap.xml>`_
+ .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man2/xhtml/glGetPixelMap.xml>`_
:type map: Enumerated constant
:arg map: Specifies the name of the pixel map to return.
@@ -701,7 +701,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
Return the polygon stipple pattern
- .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glGetPolygonStipple.xml>`_
+ .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man2/xhtml/glGetPolygonStipple.xml>`_
:type mask: :class:`bgl.Buffer` object I{type GL_BYTE}
:arg mask: Returns the stipple pattern. The initial value is all 1's.
@@ -824,13 +824,25 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
Set the current color index
- .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glIndex.xml>`_
+ .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man2/xhtml/glIndex.xml>`_
:type c: :class:`bgl.Buffer` object. Depends on function prototype.
:arg c: Specifies a pointer to a one element array that contains the new value for
the current color index.
+.. function:: glIndexMask(mask):
+
+ Control the writing of individual bits in the color index buffers
+
+ .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man2/xhtml/glIndexMask.xml>`_
+
+ :type mask: int
+ :arg mask: Specifies a bit mask to enable and disable the writing of individual bits
+ in the color index buffers.
+ Initially, the mask is all 1's.
+
+
.. function:: glInitNames():
Initialize the name stack
@@ -1510,7 +1522,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
:arg mode: Specifies a symbolic value representing a shading technique.
-.. function:: glStencilFuc(func, ref, mask):
+.. function:: glStencilFunc(func, ref, mask):
Set function and reference value for stencil testing
@@ -1835,7 +1847,238 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
:arg objx, objy, objz: Return the computed object coordinates.
-class Buffer:
+.. function:: glUseProgram(program):
+
+ Installs a program object as part of current rendering state
+
+ .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glUseProgram.xml>`_
+
+ :type program: int
+ :arg program: Specifies the handle of the program object whose executables are to be used as part of current rendering state.
+
+
+.. function:: glValidateProgram(program):
+
+ Validates a program object
+
+ .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glValidateProgram.xml>`_
+
+ :type program: int
+ :arg program: Specifies the handle of the program object to be validated.
+
+
+.. function:: glLinkProgram(program):
+
+ Links a program object.
+
+ .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glLinkProgram.xml>`_
+
+ :type program: int
+ :arg program: Specifies the handle of the program object to be linked.
+
+
+.. function:: glActiveTexture(texture):
+
+ Select active texture unit.
+
+ .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glActiveTexture.xml>`_
+
+ :type texture: int
+ :arg texture: Constant in ``GL_TEXTURE0`` 0 - 8
+
+
+.. function:: glAttachShader(program, shader):
+
+ Attaches a shader object to a program object.
+
+ .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glAttachShader.xml>`_
+
+ :type program: int
+ :arg program: Specifies the program object to which a shader object will be attached.
+ :type shader: int
+ :arg shader: Specifies the shader object that is to be attached.
+
+
+.. function:: glCompileShader(shader):
+
+ Compiles a shader object.
+
+ .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glCompileShader.xml>`_
+
+ :type shader: int
+ :arg shader: Specifies the shader object to be compiled.
+
+
+.. function:: glCreateProgram():
+
+ Creates a program object
+
+ .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glCreateProgram.xml>`_
+
+ :rtype: int
+ :return: The new program or zero if an error occurs.
+
+
+.. function:: glCreateShader(shaderType):
+
+ Creates a shader object.
+
+ .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glCreateShader.xml>`_
+
+ :type shaderType: Specifies the type of shader to be created.
+ Must be one of ``GL_VERTEX_SHADER``,
+ ``GL_TESS_CONTROL_SHADER``,
+ ``GL_TESS_EVALUATION_SHADER``,
+ ``GL_GEOMETRY_SHADER``,
+ or ``GL_FRAGMENT_SHADER``.
+ :arg shaderType:
+ :rtype: int
+ :return: 0 if an error occurs.
+
+
+.. function:: glDeleteProgram(program):
+
+ Deletes a program object.
+
+ .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glDeleteProgram.xml>`_
+
+ :type program: int
+ :arg program: Specifies the program object to be deleted.
+
+
+.. function:: glDeleteShader(shader):
+
+ Deletes a shader object.
+
+ .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glDeleteShader.xml>`_
+
+ :type shader: int
+ :arg shader: Specifies the shader object to be deleted.
+
+
+.. function:: glDetachShader(program, shader):
+
+ Detaches a shader object from a program object to which it is attached.
+
+ .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glDetachShader.xml>`_
+
+ :type program: int
+ :arg program: Specifies the program object from which to detach the shader object.
+ :type shader: int
+ :arg shader: pecifies the program object from which to detach the shader object.
+
+
+.. function:: glGetAttachedShaders(program, maxCount, count, shaders):
+
+ Returns the handles of the shader objects attached to a program object.
+
+ .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glGetAttachedShaders.xml>`_
+
+ :type program: int
+ :arg program: Specifies the program object to be queried.
+ :type maxCount: int
+ :arg maxCount: Specifies the size of the array for storing the returned object names.
+ :type count: :class:`bgl.Buffer` int buffer.
+ :arg count: Returns the number of names actually returned in objects.
+ :type shaders: :class:`bgl.Buffer` int buffer.
+ :arg shaders: Specifies an array that is used to return the names of attached shader objects.
+
+
+.. function:: glGetProgramInfoLog(program, maxLength, length, infoLog):
+
+ Returns the information log for a program object.
+
+ .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glGetProgramInfoLog.xml>`_
+
+ :type program: int
+ :arg program: Specifies the program object whose information log is to be queried.
+ :type maxLength: int
+ :arg maxLength: Specifies the size of the character buffer for storing the returned information log.
+ :type length: :class:`bgl.Buffer` int buffer.
+ :arg length: Returns the length of the string returned in **infoLog** (excluding the null terminator).
+ :type infoLog: :class:`bgl.Buffer` char buffer.
+ :arg infoLog: Specifies an array of characters that is used to return the information log.
+
+
+.. function:: glGetShaderInfoLog(program, maxLength, length, infoLog):
+
+ Returns the information log for a shader object.
+
+ .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glGetShaderInfoLog.xml>`_
+
+ :type shader: int
+ :arg shader: Specifies the shader object whose information log is to be queried.
+ :type maxLength: int
+ :arg maxLength: Specifies the size of the character buffer for storing the returned information log.
+ :type length: :class:`bgl.Buffer` int buffer.
+ :arg length: Returns the length of the string returned in **infoLog** (excluding the null terminator).
+ :type infoLog: :class:`bgl.Buffer` char buffer.
+ :arg infoLog: Specifies an array of characters that is used to return the information log.
+
+
+.. function:: glGetProgramiv(program, pname, params):
+
+ Returns a parameter from a program object.
+
+ .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glGetProgram.xml>`_
+
+ :type program: int
+ :arg program: Specifies the program object to be queried.
+ :type pname: int
+ :arg pname: Specifies the object parameter.
+ :type params: :class:`bgl.Buffer` int buffer.
+ :arg params: Returns the requested object parameter.
+
+
+.. function:: glIsShader(shader):
+
+ Determines if a name corresponds to a shader object.
+
+ .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glIsShader.xml>`_
+
+ :type shader: int
+ :arg shader: Specifies a potential shader object.
+
+
+.. function:: glIsProgram(program):
+
+ Determines if a name corresponds to a program object
+
+ .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glIsProgram.xml>`_
+
+ :type program: int
+ :arg program: Specifies a potential program object.
+
+
+.. function:: glGetShaderSource(shader, bufSize, length, source):
+
+ Returns the source code string from a shader object
+
+ .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glGetShaderSource.xml>`_
+
+ :type shader: int
+ :arg shader: Specifies the shader object to be queried.
+ :type bufSize: int
+ :arg bufSize: Specifies the size of the character buffer for storing the returned source code string.
+ :type length: :class:`bgl.Buffer` int buffer.
+ :arg length: Returns the length of the string returned in source (excluding the null terminator).
+ :type source: :class:`bgl.Buffer` char.
+ :arg source: Specifies an array of characters that is used to return the source code string.
+
+
+.. function:: glShaderSource(shader, shader_string):
+
+ Replaces the source code in a shader object.
+
+ .. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glShaderSource.xml>`_
+
+ :type shader: int
+ :arg shader: Specifies the handle of the shader object whose source code is to be replaced.
+ :type shader_string: string
+ :arg shader_string: The shader string.
+
+
+.. class:: Buffer
The Buffer object is simply a block of memory that is delineated and initialized by the
user. Many OpenGL functions return data to a C-style pointer, however, because this
diff --git a/doc/python_api/rst/gpu.rst b/doc/python_api/rst/gpu.rst
index 68dc30b6143..a225829b3e8 100644
--- a/doc/python_api/rst/gpu.rst
+++ b/doc/python_api/rst/gpu.rst
@@ -262,10 +262,16 @@ The calculation of some of the uniforms is based on matrices available in the sc
.. data:: GPU_DYNAMIC_SAMPLER_2DSHADOW
+ The uniform is an float representing the bumpmap scaling.
+
+ :value: 14
+
+.. data:: GPU_DYNAMIC_OBJECT_AUTOBUMPSCALE
+
The uniform is an integer representing a shadow buffer corresponding to a lamp
casting shadow.
- :value: 14
+ :value: 15
GLSL attribute type
diff --git a/doc/python_api/rst/info_gotcha.rst b/doc/python_api/rst/info_gotcha.rst
index 1d561216b52..e60f1e256cd 100644
--- a/doc/python_api/rst/info_gotcha.rst
+++ b/doc/python_api/rst/info_gotcha.rst
@@ -118,18 +118,19 @@ If you insist - yes its possible, but scripts that use this hack wont be conside
bpy.ops.wm.redraw_timer(type='DRAW_WIN_SWAP', iterations=1)
-I can't edit the mesh in edit-mode!
-===================================
+Modes and Mesh Access
+=====================
-Blender's EditMesh is an internal data structure (not saved and not exposed to python), this gives the main annoyance that you need to exit edit-mode to edit the mesh from python.
+When working with mesh data you may run into the problem where a script fails to run as expected in edit-mode. This is caused by edit-mode having its own data which is only written back to the mesh when exiting edit-mode.
-The reason we have not made much attempt to fix this yet is because we
-will likely move to BMesh mesh API eventually, so any work on the API now will be wasted effort.
+A common example is that exporters may access a mesh through ``obj.data`` (a :class:`bpy.types.Mesh`) but the user is in edit-mode, where the mesh data is available but out of sync with the edit mesh.
-With the BMesh API we may expose mesh data to python so we can
-write useful tools in python which are also fast to execute while in edit-mode.
+In this situation you can...
-For the time being this limitation just has to be worked around but we're aware its frustrating needs to be addressed.
+* Exit edit-mode before running the tool.
+* Explicitly update the mesh by calling :class:`bmesh.types.BMesh.to_mesh`.
+* Modify the script to support working on the edit-mode data directly, see: :mod:`bmesh.from_edit_mesh`.
+* Report the context as incorrect and only allow the script to run outside edit-mode.
.. _info_gotcha_mesh_faces:
@@ -311,7 +312,7 @@ Naming Limitations
A common mistake is to assume newly created data is given the requested name.
-This can cause bugs when you add some data (normally imported) and then reference it later by name.
+This can cause bugs when you add some data (normally imported) then reference it later by name.
.. code-block:: python
@@ -557,6 +558,21 @@ This example shows how you can tell undo changes the memory locations.
As suggested above, simply not holding references to data when Blender is used interactively by the user is the only way to ensure the script doesn't become unstable.
+Undo & Library Data
+^^^^^^^^^^^^^^^^^^^
+
+One of the advantages with Blenders library linking system that undo can skip checking changes in library data since it is assumed to be static.
+
+Tools in Blender are not allowed to modify library data.
+
+Python however does not enforce this restriction.
+
+This can be useful in some cases, using a script to adjust material values for example.
+But its also possible to use a script to make library data point to newly created local data, which is not supported since a call to undo will remove the local data but leave the library referencing it and likely crash.
+
+So it's best to consider modifying library data an advanced usage of the API and only to use it when you know what you're doing.
+
+
Edit Mode / Memory Access
-------------------------
@@ -616,7 +632,28 @@ Removing Data
**Any** data that you remove shouldn't be modified or accessed afterwards, this includes f-curves, drivers, render layers, timeline markers, modifiers, constraints along with objects, scenes, groups, bones.. etc.
-This is a problem in the API at the moment that we should eventually solve.
+The ``remove()`` api calls will invalidate the data they free to prevent common mistakes.
+
+The following example shows how this precortion works.
+
+.. code-block:: python
+
+ mesh = bpy.data.meshes.new(name="MyMesh")
+ # normally the script would use the mesh here...
+ bpy.data.meshes.remove(mesh)
+ print(mesh.name) # <- give an exception rather then crashing:
+
+ # ReferenceError: StructRNA of type Mesh has been removed
+
+
+But take care because this is limited to scripts accessing the variable which is removed, the next example will still crash.
+
+.. code-block:: python
+
+ mesh = bpy.data.meshes.new(name="MyMesh")
+ vertices = mesh.vertices
+ bpy.data.meshes.remove(mesh)
+ print(vertices) # <- this may crash
sys.exit
diff --git a/doc/python_api/sphinx_doc_gen.py b/doc/python_api/sphinx_doc_gen.py
index 6f7d4f3582a..410612fabd5 100644
--- a/doc/python_api/sphinx_doc_gen.py
+++ b/doc/python_api/sphinx_doc_gen.py
@@ -1251,7 +1251,7 @@ def pyrna2sphinx(basepath):
bases = list(reversed(struct.get_bases()))
# props
- lines[:] = []
+ del lines[:]
if _BPY_STRUCT_FAKE:
descr_items = [(key, descr) for key, descr in sorted(bpy.types.Struct.__bases__[0].__dict__.items()) if not key.startswith("__")]
@@ -1282,7 +1282,7 @@ def pyrna2sphinx(basepath):
fw("\n")
# funcs
- lines[:] = []
+ del lines[:]
if _BPY_STRUCT_FAKE:
for key, descr in descr_items:
@@ -1305,7 +1305,7 @@ def pyrna2sphinx(basepath):
fw(line)
fw("\n")
- lines[:] = []
+ del lines[:]
if struct.references:
# use this otherwise it gets in the index for a normal heading.
diff --git a/extern/libmv/libmv-capi.cpp b/extern/libmv/libmv-capi.cpp
index a15927f881d..c1788cc9422 100644
--- a/extern/libmv/libmv-capi.cpp
+++ b/extern/libmv/libmv-capi.cpp
@@ -192,7 +192,7 @@ static void imageToFloatBuf(const libmv::FloatImage *image, int channels, float
}
#if defined(DUMP_FAILURE) || defined (DUMP_ALWAYS)
-void savePNGImage(png_bytep *row_pointers, int width, int height, int depth, int color_type, char *file_name)
+static void savePNGImage(png_bytep *row_pointers, int width, int height, int depth, int color_type, char *file_name)
{
png_infop info_ptr;
png_structp png_ptr;
@@ -437,6 +437,9 @@ int libmv_trackRegion(const struct libmv_trackRegionOptions *options,
#endif
saveImage("old_patch", old_patch, x1[4], y1[4]);
saveImage("new_patch", new_patch, x2[4], y2[4]);
+
+ if (options->image1_mask)
+ saveImage("mask", image1_mask, x2[4], y2[4]);
}
#endif
diff --git a/extern/xdnd/xdnd.c b/extern/xdnd/xdnd.c
index 9bdee89c1ce..50d1fec4969 100644
--- a/extern/xdnd/xdnd.c
+++ b/extern/xdnd/xdnd.c
@@ -347,7 +347,7 @@ void xdnd_set_dnd_aware (DndClass * dnd, Window window, Atom * typelist)
&nchildren_return);
if (children_return)
XFree (children_return);
- if (r)
+ if (r && parent != root_return)
xdnd_set_dnd_aware (dnd, parent, typelist);
}
diff --git a/intern/CMakeLists.txt b/intern/CMakeLists.txt
index 576c048288e..8d4045b1ff4 100644
--- a/intern/CMakeLists.txt
+++ b/intern/CMakeLists.txt
@@ -65,6 +65,10 @@ if(WITH_CYCLES)
add_subdirectory(cycles)
endif()
+if(WITH_INTERNATIONAL)
+ add_subdirectory(locale)
+endif()
+
if(WITH_INPUT_TOUCH)
add_subdirectory(touch)
endif()
diff --git a/intern/SConscript b/intern/SConscript
index 59e412333b0..5360ce4ea88 100644
--- a/intern/SConscript
+++ b/intern/SConscript
@@ -30,6 +30,9 @@ if env['WITH_BF_CYCLES']:
if env['WITH_BF_BOOLEAN']:
SConscript(['bsp/SConscript'])
+if env['WITH_BF_INTERNATIONAL']:
+ SConscript(['locale/SConscript'])
+
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'win64-mingw', 'linuxcross', 'win64-vc'):
SConscript(['utfconv/SConscript'])
diff --git a/intern/audaspace/intern/AUD_FileWriter.h b/intern/audaspace/intern/AUD_FileWriter.h
index da52c7e0fb2..3291c1ad03a 100644
--- a/intern/audaspace/intern/AUD_FileWriter.h
+++ b/intern/audaspace/intern/AUD_FileWriter.h
@@ -64,8 +64,8 @@ public:
* Writes a reader to a writer.
* \param reader The reader to read from.
* \param writer The writer to write to.
- * \param length How many samples should be transfered.
- * \param buffersize How many samples should be transfered at once.
+ * \param length How many samples should be transferred.
+ * \param buffersize How many samples should be transferred at once.
*/
static void writeReader(boost::shared_ptr<AUD_IReader> reader, boost::shared_ptr<AUD_IWriter> writer, unsigned int length, unsigned int buffersize);
@@ -73,8 +73,8 @@ public:
* Writes a reader to several writers.
* \param reader The reader to read from.
* \param writers The writers to write to.
- * \param length How many samples should be transfered.
- * \param buffersize How many samples should be transfered at once.
+ * \param length How many samples should be transferred.
+ * \param buffersize How many samples should be transferred at once.
*/
static void writeReader(boost::shared_ptr<AUD_IReader> reader, std::vector<boost::shared_ptr<AUD_IWriter> >& writers, unsigned int length, unsigned int buffersize);
};
diff --git a/intern/cycles/CMakeLists.txt b/intern/cycles/CMakeLists.txt
index 7495a98aed1..2a1eddcec27 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)
+ 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 c0e0353d37d..1a127e364fe 100644
--- a/intern/cycles/SConscript
+++ b/intern/cycles/SConscript
@@ -23,6 +23,10 @@ defs.append('WITH_OPENCL')
defs.append('WITH_MULTI')
defs.append('WITH_CUDA')
+if env['WITH_BF_CYCLES_OSL']:
+ defs.append('WITH_OSL')
+ incs.append(cycles['BF_OSL_INC'])
+
if env['WITH_BF_CYCLES_CUDA_BINARIES']:
defs.append('WITH_CUDA_BINARIES')
@@ -32,7 +36,8 @@ incs.extend('#source/blender/blenloader ../../source/blender/makesrna/intern'.sp
incs.extend('#extern/glew/include #intern/mikktspace'.split())
incs.append(cycles['BF_OIIO_INC'])
incs.append(cycles['BF_BOOST_INC'])
-incs.append(cycles['BF_PYTHON_INC'])
+incs.append(cycles['BF_OPENEXR_INC'].split())
+incs.extend(cycles['BF_PYTHON_INC'].split())
if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
cxxflags.append('-D_CRT_SECURE_NO_WARNINGS /fp:fast /EHsc'.split())
@@ -62,6 +67,12 @@ if env['WITH_BF_RAYOPTIMIZATION']:
cycles.BlenderLib('bf_intern_cycles', sources, incs, defs, libtype=['intern'], priority=[0], cxx_compileflags=cxxflags)
+if env['WITH_BF_CYCLES_OSL']:
+ oso_files = SConscript(['kernel/shaders/SConscript'])
+ cycles.Depends("kernel/osl/osl_shader.o", oso_files)
+
+ SConscript(['kernel/osl/SConscript'])
+
# cuda kernel binaries
if env['WITH_BF_CYCLES_CUDA_BINARIES']:
kernel_binaries = SConscript(['kernel/SConscript'])
diff --git a/intern/cycles/blender/addon/osl.py b/intern/cycles/blender/addon/osl.py
index aac1e2422b9..79ce3df20c3 100644
--- a/intern/cycles/blender/addon/osl.py
+++ b/intern/cycles/blender/addon/osl.py
@@ -79,12 +79,13 @@ def update_script_node(node, report):
if script.is_in_memory or script.is_dirty or script.is_modified or not os.path.exists(osl_path):
# write text datablock contents to temporary file
- osl_file = tempfile.NamedTemporaryFile(mode='w', suffix=".osl", delete=True)
+ osl_file = tempfile.NamedTemporaryFile(mode='w', suffix=".osl", delete=False)
osl_file.write(script.as_string())
- osl_file.flush()
+ osl_file.close()
+
ok, oso_path = osl_compile(osl_file.name, report)
oso_file_remove = False
- osl_file.close()
+ os.remove(osl_file.name)
else:
# compile text datablock from disk directly
ok, oso_path = osl_compile(osl_path, report)
diff --git a/intern/cycles/blender/blender_camera.cpp b/intern/cycles/blender/blender_camera.cpp
index 61fe7cf254d..0cbd2a0291f 100644
--- a/intern/cycles/blender/blender_camera.cpp
+++ b/intern/cycles/blender/blender_camera.cpp
@@ -56,13 +56,16 @@ struct BlenderCamera {
float sensor_width;
float sensor_height;
+ int full_width;
+ int full_height;
+
BoundBox2D border;
BoundBox2D pano_viewplane;
Transform matrix;
};
-static void blender_camera_init(BlenderCamera *bcam)
+static void blender_camera_init(BlenderCamera *bcam, BL::Scene b_scene)
{
memset(bcam, 0, sizeof(BlenderCamera));
@@ -77,6 +80,12 @@ static void blender_camera_init(BlenderCamera *bcam)
bcam->border.top = 1.0f;
bcam->pano_viewplane.right = 1.0f;
bcam->pano_viewplane.top = 1.0f;
+
+ /* render resolution */
+ BL::RenderSettings r = b_scene.render();
+
+ bcam->full_width = (int)(r.resolution_x()*r.resolution_percentage()/100);
+ bcam->full_height = (int)(r.resolution_y()*r.resolution_percentage()/100);
}
static float blender_camera_focal_distance(BL::Object b_ob, BL::Camera b_camera)
@@ -207,10 +216,9 @@ static void blender_camera_viewplane(BlenderCamera *bcam, int width, int height,
/* compute x/y aspect and ratio */
float xaspect, yaspect;
-
- /* sensor fitting */
bool horizontal_fit;
+ /* sensor fitting */
if(bcam->sensor_fit == BlenderCamera::AUTO) {
horizontal_fit = (xratio > yratio);
*sensor_size = bcam->sensor_width;
@@ -277,9 +285,35 @@ static void blender_camera_sync(Camera *cam, BlenderCamera *bcam, int width, int
blender_camera_viewplane(bcam, width, height,
&cam->viewplane, &aspectratio, &sensor_size);
- /* sensor */
- cam->sensorwidth = bcam->sensor_width;
- cam->sensorheight = bcam->sensor_height;
+ /* panorama sensor */
+ if (bcam->type == CAMERA_PANORAMA && bcam->panorama_type == PANORAMA_FISHEYE_EQUISOLID) {
+ float fit_xratio = bcam->full_width*bcam->pixelaspect.x;
+ float fit_yratio = bcam->full_height*bcam->pixelaspect.y;
+ bool horizontal_fit;
+ float sensor_size;
+
+ if(bcam->sensor_fit == BlenderCamera::AUTO) {
+ horizontal_fit = (fit_xratio > fit_yratio);
+ sensor_size = bcam->sensor_width;
+ }
+ else if(bcam->sensor_fit == BlenderCamera::HORIZONTAL) {
+ horizontal_fit = true;
+ sensor_size = bcam->sensor_width;
+ }
+ else { /* vertical */
+ horizontal_fit = false;
+ sensor_size = bcam->sensor_height;
+ }
+
+ if(horizontal_fit) {
+ cam->sensorwidth = sensor_size;
+ cam->sensorheight = sensor_size * fit_yratio / fit_xratio;
+ }
+ else {
+ cam->sensorwidth = sensor_size * fit_xratio / fit_yratio;
+ cam->sensorheight = sensor_size;
+ }
+ }
/* clipping distances */
cam->nearclip = bcam->nearclip;
@@ -320,7 +354,7 @@ static void blender_camera_sync(Camera *cam, BlenderCamera *bcam, int width, int
void BlenderSync::sync_camera(BL::Object b_override, int width, int height)
{
BlenderCamera bcam;
- blender_camera_init(&bcam);
+ blender_camera_init(&bcam, b_scene);
/* pixel aspect */
BL::RenderSettings r = b_scene.render();
@@ -435,13 +469,13 @@ static void blender_camera_from_view(BlenderCamera *bcam, BL::Scene b_scene, BL:
static void blender_camera_view_subset(BL::Scene b_scene, BL::Object b_ob, BL::SpaceView3D b_v3d,
BL::RegionView3D b_rv3d, int width, int height, BoundBox2D *view_box, BoundBox2D *cam_box)
{
- BL::RenderSettings r = b_scene.render();
+// BL::RenderSettings r = b_scene.render(); /* UNUSED */
BoundBox2D cam, view;
float view_aspect, cam_aspect, sensor_size;
/* get viewport viewplane */
BlenderCamera view_bcam;
- blender_camera_init(&view_bcam);
+ blender_camera_init(&view_bcam, b_scene);
blender_camera_from_view(&view_bcam, b_scene, b_v3d, b_rv3d, width, height, true);
blender_camera_viewplane(&view_bcam, width, height,
@@ -449,13 +483,10 @@ static void blender_camera_view_subset(BL::Scene b_scene, BL::Object b_ob, BL::S
/* get camera viewplane */
BlenderCamera cam_bcam;
- blender_camera_init(&cam_bcam);
+ blender_camera_init(&cam_bcam, b_scene);
blender_camera_from_object(&cam_bcam, b_ob, true);
- width = (int)(r.resolution_x()*r.resolution_percentage()/100);
- height = (int)(r.resolution_y()*r.resolution_percentage()/100);
-
- blender_camera_viewplane(&cam_bcam, width, height,
+ blender_camera_viewplane(&cam_bcam, cam_bcam.full_width, cam_bcam.full_height,
&cam, &cam_aspect, &sensor_size);
/* return */
@@ -513,7 +544,7 @@ static void blender_camera_border(BlenderCamera *bcam, BL::Scene b_scene, BL::Sp
void BlenderSync::sync_view(BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, int width, int height)
{
BlenderCamera bcam;
- blender_camera_init(&bcam);
+ blender_camera_init(&bcam, b_scene);
blender_camera_from_view(&bcam, b_scene, b_v3d, b_rv3d, width, height);
blender_camera_border(&bcam, b_scene, b_v3d, b_rv3d, width, height);
diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp
index ad43c39469c..b8ed942f5b6 100644
--- a/intern/cycles/blender/blender_session.cpp
+++ b/intern/cycles/blender/blender_session.cpp
@@ -518,8 +518,8 @@ void BlenderSession::get_progress(float& progress, double& total_time)
sample = session->progress.get_sample();
samples_per_tile = session->params.samples;
- if(samples_per_tile)
- progress = ((float)sample/(float)(tile_total * samples_per_tile));
+ if(samples_per_tile && tile_total)
+ progress = ((float)sample / (float)(tile_total * samples_per_tile));
else
progress = 0.0;
}
diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp
index 63cf719d010..da06f1d0a38 100644
--- a/intern/cycles/blender/blender_shader.cpp
+++ b/intern/cycles/blender/blender_shader.cpp
@@ -500,8 +500,10 @@ static ShaderNode *add_node(Scene *scene, BL::BlendData b_data, BL::Scene b_scen
BL::Image b_image(b_image_node.image());
ImageTextureNode *image = new ImageTextureNode();
/* todo: handle generated/builtin images */
- if(b_image && b_image.source() != BL::Image::source_MOVIE)
+ if(b_image && b_image.source() != BL::Image::source_MOVIE) {
image->filename = image_user_file_path(b_image_node.image_user(), b_image, b_scene.frame_current());
+ image->animated = b_image_node.image_user().use_auto_refresh();
+ }
image->color_space = ImageTextureNode::color_space_enum[(int)b_image_node.color_space()];
image->projection = ImageTextureNode::projection_enum[(int)b_image_node.projection()];
image->projection_blend = b_image_node.projection_blend();
@@ -513,8 +515,10 @@ static ShaderNode *add_node(Scene *scene, BL::BlendData b_data, BL::Scene b_scen
BL::ShaderNodeTexEnvironment b_env_node(b_node);
BL::Image b_image(b_env_node.image());
EnvironmentTextureNode *env = new EnvironmentTextureNode();
- if(b_image && b_image.source() != BL::Image::source_MOVIE)
+ if(b_image && b_image.source() != BL::Image::source_MOVIE) {
env->filename = image_user_file_path(b_env_node.image_user(), b_image, b_scene.frame_current());
+ env->animated = b_env_node.image_user().use_auto_refresh();
+ }
env->color_space = EnvironmentTextureNode::color_space_enum[(int)b_env_node.color_space()];
env->projection = EnvironmentTextureNode::projection_enum[(int)b_env_node.projection()];
get_tex_mapping(&env->tex_mapping, b_env_node.texture_mapping());
@@ -821,7 +825,7 @@ static void add_nodes(Scene *scene, BL::BlendData b_data, BL::Scene b_scene, Sha
/* Sync Materials */
-void BlenderSync::sync_materials()
+void BlenderSync::sync_materials(bool update_all)
{
shader_map.set_default(scene->shaders[scene->default_surface]);
@@ -832,7 +836,7 @@ void BlenderSync::sync_materials()
Shader *shader;
/* test if we need to sync */
- if(shader_map.sync(&shader, *b_mat)) {
+ if(shader_map.sync(&shader, *b_mat) || update_all) {
ShaderGraph *graph = new ShaderGraph();
shader->name = b_mat->name().c_str();
@@ -868,14 +872,14 @@ void BlenderSync::sync_materials()
/* Sync World */
-void BlenderSync::sync_world()
+void BlenderSync::sync_world(bool update_all)
{
Background *background = scene->background;
Background prevbackground = *background;
BL::World b_world = b_scene.world();
- if(world_recalc || b_world.ptr.data != world_map) {
+ if(world_recalc || update_all || b_world.ptr.data != world_map) {
Shader *shader = scene->shaders[scene->default_background];
ShaderGraph *graph = new ShaderGraph();
@@ -922,7 +926,7 @@ void BlenderSync::sync_world()
/* Sync Lamps */
-void BlenderSync::sync_lamps()
+void BlenderSync::sync_lamps(bool update_all)
{
shader_map.set_default(scene->shaders[scene->default_light]);
@@ -933,7 +937,7 @@ void BlenderSync::sync_lamps()
Shader *shader;
/* test if we need to sync */
- if(shader_map.sync(&shader, *b_lamp)) {
+ if(shader_map.sync(&shader, *b_lamp) || update_all) {
ShaderGraph *graph = new ShaderGraph();
/* create nodes */
@@ -972,11 +976,20 @@ void BlenderSync::sync_lamps()
void BlenderSync::sync_shaders()
{
+ /* for auto refresh images */
+ bool auto_refresh_update = false;
+
+ if(preview) {
+ ImageManager *image_manager = scene->image_manager;
+ int frame = b_scene.frame_current();
+ auto_refresh_update = image_manager->set_animation_frame_update(frame);
+ }
+
shader_map.pre_sync();
- sync_world();
- sync_lamps();
- sync_materials();
+ sync_world(auto_refresh_update);
+ sync_lamps(auto_refresh_update);
+ sync_materials(auto_refresh_update);
/* false = don't delete unused shaders, not supported */
shader_map.post_sync(false);
diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp
index 9ebdcfd04bd..d0e8b508df6 100644
--- a/intern/cycles/blender/blender_sync.cpp
+++ b/intern/cycles/blender/blender_sync.cpp
@@ -179,12 +179,14 @@ void BlenderSync::sync_integrator()
integrator->sample_clamp = get_float(cscene, "sample_clamp");
#ifdef __CAMERA_MOTION__
- if(integrator->motion_blur != r.use_motion_blur()) {
- scene->object_manager->tag_update(scene);
- scene->camera->tag_update();
- }
+ if(!preview) {
+ if(integrator->motion_blur != r.use_motion_blur()) {
+ scene->object_manager->tag_update(scene);
+ scene->camera->tag_update();
+ }
- integrator->motion_blur = (!preview && r.use_motion_blur());
+ integrator->motion_blur = r.use_motion_blur();
+ }
#endif
integrator->diffuse_samples = get_int(cscene, "diffuse_samples");
diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h
index 71781bc5459..d3d21fbdf72 100644
--- a/intern/cycles/blender/blender_sync.h
+++ b/intern/cycles/blender/blender_sync.h
@@ -68,14 +68,14 @@ public:
private:
/* sync */
- void sync_lamps();
- void sync_materials();
+ void sync_lamps(bool update_all);
+ void sync_materials(bool update_all);
void sync_objects(BL::SpaceView3D b_v3d, int motion = 0);
void sync_motion(BL::SpaceView3D b_v3d, BL::Object b_override);
void sync_film();
void sync_integrator();
void sync_view();
- void sync_world();
+ void sync_world(bool update_all);
void sync_render_layers(BL::SpaceView3D b_v3d, const char *layer);
void sync_shaders();
diff --git a/intern/cycles/device/device.cpp b/intern/cycles/device/device.cpp
index 721c262f094..ee160b275ce 100644
--- a/intern/cycles/device/device.cpp
+++ b/intern/cycles/device/device.cpp
@@ -191,18 +191,6 @@ vector<DeviceInfo>& Device::available_devices()
{
static vector<DeviceInfo> devices;
static bool devices_init = false;
- static double device_update_time = 0.0;
-
- /* only update device list if we're not actively rendering already, things
- * could go very wrong if a device suddenly becomes (un)available. also do
- * it only every 5 seconds. it not super cpu intensive but don't want to do
- * it on every redraw. */
- if(devices_init) {
- if(!TaskScheduler::active() && (time_dt() > device_update_time + 5.0)) {
- devices.clear();
- devices_init = false;
- }
- }
if(!devices_init) {
#ifdef WITH_CUDA
@@ -226,7 +214,6 @@ vector<DeviceInfo>& Device::available_devices()
#endif
devices_init = true;
- device_update_time = time_dt();
}
return devices;
diff --git a/intern/cycles/device/device_cuda.cpp b/intern/cycles/device/device_cuda.cpp
index 440971e2663..58c590a8de5 100644
--- a/intern/cycles/device/device_cuda.cpp
+++ b/intern/cycles/device/device_cuda.cpp
@@ -60,7 +60,7 @@ public:
return (CUdeviceptr)mem;
}
- const char *cuda_error_string(CUresult result)
+ static const char *cuda_error_string(CUresult result)
{
switch(result) {
case CUDA_SUCCESS: return "No errors";
@@ -917,12 +917,21 @@ Device *device_cuda_create(DeviceInfo& info, Stats &stats, bool background)
void device_cuda_info(vector<DeviceInfo>& devices)
{
+ CUresult result;
int count = 0;
- if(cuInit(0) != CUDA_SUCCESS)
+ result = cuInit(0);
+ if(result != CUDA_SUCCESS) {
+ if(result != CUDA_ERROR_NO_DEVICE)
+ fprintf(stderr, "CUDA cuInit: %s\n", CUDADevice::cuda_error_string(result));
return;
- if(cuDeviceGetCount(&count) != CUDA_SUCCESS)
+ }
+
+ result = cuDeviceGetCount(&count);
+ if(result != CUDA_SUCCESS) {
+ fprintf(stderr, "CUDA cuDeviceGetCount: %s\n", CUDADevice::cuda_error_string(result));
return;
+ }
vector<DeviceInfo> display_devices;
diff --git a/intern/cycles/kernel/kernel_accumulate.h b/intern/cycles/kernel/kernel_accumulate.h
index 2f2314c9a8b..d99beb8905a 100644
--- a/intern/cycles/kernel/kernel_accumulate.h
+++ b/intern/cycles/kernel/kernel_accumulate.h
@@ -301,10 +301,6 @@ __device_inline float3 path_radiance_sum(KernelGlobals *kg, PathRadiance *L)
__device_inline void path_radiance_clamp(PathRadiance *L, float3 *L_sum, float clamp)
{
- #ifdef __OSL__
- using std::isfinite;
- #endif
-
float sum = fabsf((*L_sum).x) + fabsf((*L_sum).y) + fabsf((*L_sum).z);
if(!isfinite(sum)) {
diff --git a/intern/cycles/kernel/kernel_camera.h b/intern/cycles/kernel/kernel_camera.h
index 1b2fe8c56ee..abc63d99c74 100644
--- a/intern/cycles/kernel/kernel_camera.h
+++ b/intern/cycles/kernel/kernel_camera.h
@@ -229,5 +229,20 @@ __device void camera_sample(KernelGlobals *kg, int x, int y, float filter_u, flo
camera_sample_panorama(kg, raster_x, raster_y, lens_u, lens_v, ray);
}
+/* Utilities */
+
+__device_inline float camera_distance(KernelGlobals *kg, float3 P)
+{
+ Transform cameratoworld = kernel_data.cam.cameratoworld;
+ float3 camP = make_float3(cameratoworld.x.w, cameratoworld.y.w, cameratoworld.z.w);
+
+ if(kernel_data.cam.type == CAMERA_ORTHOGRAPHIC) {
+ float3 camD = make_float3(cameratoworld.x.z, cameratoworld.y.z, cameratoworld.z.z);
+ return fabsf(dot((P - camP), camD));
+ }
+ else
+ return len(P - camP);
+}
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/kernel_passes.h b/intern/cycles/kernel/kernel_passes.h
index 42733d691e0..7f8b611ba14 100644
--- a/intern/cycles/kernel/kernel_passes.h
+++ b/intern/cycles/kernel/kernel_passes.h
@@ -52,9 +52,7 @@ __device_inline void kernel_write_data_passes(KernelGlobals *kg, __global float
if(!(path_flag & PATH_RAY_TRANSPARENT)) {
if(sample == 0) {
if(flag & PASS_DEPTH) {
- Transform tfm = kernel_data.cam.worldtocamera;
- float depth = len(transform_point(&tfm, sd->P));
-
+ float depth = camera_distance(kg, sd->P);
kernel_write_pass_float(buffer + kernel_data.film.pass_depth, sample, depth);
}
if(flag & PASS_OBJECT_ID) {
diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h
index 585068ce8e2..195291898c6 100644
--- a/intern/cycles/kernel/kernel_path.h
+++ b/intern/cycles/kernel/kernel_path.h
@@ -331,10 +331,13 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample,
float bsdf_u = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF_U);
float bsdf_v = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF_V);
+ float ao_factor = kernel_data.background.ao_factor;
+ float3 ao_N;
+ float3 ao_bsdf = shader_bsdf_ao(kg, &sd, ao_factor, &ao_N);
float3 ao_D;
float ao_pdf;
- sample_cos_hemisphere(sd.N, bsdf_u, bsdf_v, &ao_D, &ao_pdf);
+ sample_cos_hemisphere(ao_N, bsdf_u, bsdf_v, &ao_D, &ao_pdf);
if(dot(sd.Ng, ao_D) > 0.0f && ao_pdf != 0.0f) {
Ray light_ray;
@@ -347,11 +350,8 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample,
light_ray.time = sd.time;
#endif
- if(!shadow_blocked(kg, &state, &light_ray, &ao_shadow)) {
- float3 ao_bsdf = shader_bsdf_diffuse(kg, &sd)*kernel_data.background.ao_factor;
- ao_bsdf += shader_bsdf_ao(kg, &sd);
+ if(!shadow_blocked(kg, &state, &light_ray, &ao_shadow))
path_radiance_accum_ao(&L, throughput, ao_bsdf, ao_shadow, state.bounce);
- }
}
}
#endif
@@ -424,7 +424,12 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample,
/* setup ray */
ray.P = ray_offset(sd.P, (label & LABEL_TRANSMIT)? -sd.Ng: sd.Ng);
ray.D = bsdf_omega_in;
- ray.t = FLT_MAX;
+
+ if(state.bounce == 0)
+ ray.t -= sd.ray_length; /* clipping works through transparent */
+ else
+ ray.t = FLT_MAX;
+
#ifdef __RAY_DIFFERENTIALS__
ray.dP = sd.dP;
ray.dD = bsdf_domega_in;
@@ -509,10 +514,13 @@ __device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray
float bsdf_u = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF_U);
float bsdf_v = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF_V);
+ float ao_factor = kernel_data.background.ao_factor;
+ float3 ao_N;
+ float3 ao_bsdf = shader_bsdf_ao(kg, &sd, ao_factor, &ao_N);
float3 ao_D;
float ao_pdf;
- sample_cos_hemisphere(sd.N, bsdf_u, bsdf_v, &ao_D, &ao_pdf);
+ sample_cos_hemisphere(ao_N, bsdf_u, bsdf_v, &ao_D, &ao_pdf);
if(dot(sd.Ng, ao_D) > 0.0f && ao_pdf != 0.0f) {
Ray light_ray;
@@ -525,11 +533,8 @@ __device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray
light_ray.time = sd.time;
#endif
- if(!shadow_blocked(kg, &state, &light_ray, &ao_shadow)) {
- float3 ao_bsdf = shader_bsdf_diffuse(kg, &sd)*kernel_data.background.ao_factor;
- ao_bsdf += shader_bsdf_ao(kg, &sd);
+ if(!shadow_blocked(kg, &state, &light_ray, &ao_shadow))
path_radiance_accum_ao(L, throughput, ao_bsdf, ao_shadow, state.bounce);
- }
}
}
#endif
@@ -712,6 +717,8 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam
int num_samples = kernel_data.integrator.ao_samples;
float num_samples_inv = 1.0f/num_samples;
float ao_factor = kernel_data.background.ao_factor;
+ float3 ao_N;
+ float3 ao_bsdf = shader_bsdf_ao(kg, &sd, ao_factor, &ao_N);
for(int j = 0; j < num_samples; j++) {
/* todo: solve correlation */
@@ -721,7 +728,7 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam
float3 ao_D;
float ao_pdf;
- sample_cos_hemisphere(sd.N, bsdf_u, bsdf_v, &ao_D, &ao_pdf);
+ sample_cos_hemisphere(ao_N, bsdf_u, bsdf_v, &ao_D, &ao_pdf);
if(dot(sd.Ng, ao_D) > 0.0f && ao_pdf != 0.0f) {
Ray light_ray;
@@ -734,11 +741,8 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam
light_ray.time = sd.time;
#endif
- if(!shadow_blocked(kg, &state, &light_ray, &ao_shadow)) {
- float3 ao_bsdf = shader_bsdf_diffuse(kg, &sd)*ao_factor;
- ao_bsdf += shader_bsdf_ao(kg, &sd);
+ if(!shadow_blocked(kg, &state, &light_ray, &ao_shadow))
path_radiance_accum_ao(&L, throughput*num_samples_inv, ao_bsdf, ao_shadow, state.bounce);
- }
}
}
}
@@ -888,6 +892,7 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam
path_state_next(kg, &state, LABEL_TRANSPARENT);
ray.P = ray_offset(sd.P, -sd.Ng);
+ ray.t -= sd.ray_length; /* clipping works through transparent */
}
float3 L_sum = path_radiance_sum(kg, &L);
diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h
index 1af5e048ad9..879160312cf 100644
--- a/intern/cycles/kernel/kernel_shader.h
+++ b/intern/cycles/kernel/kernel_shader.h
@@ -599,21 +599,38 @@ __device float3 shader_bsdf_transmission(KernelGlobals *kg, ShaderData *sd)
#endif
}
-__device float3 shader_bsdf_ao(KernelGlobals *kg, ShaderData *sd)
+__device float3 shader_bsdf_ao(KernelGlobals *kg, ShaderData *sd, float ao_factor, float3 *N)
{
#ifdef __MULTI_CLOSURE__
float3 eval = make_float3(0.0f, 0.0f, 0.0f);
+ *N = make_float3(0.0f, 0.0f, 0.0f);
+
for(int i = 0; i< sd->num_closure; i++) {
ShaderClosure *sc = &sd->closure[i];
- if(CLOSURE_IS_AMBIENT_OCCLUSION(sc->type))
+ if(CLOSURE_IS_BSDF_DIFFUSE(sc->type)) {
+ eval += sc->weight*ao_factor;
+ *N += sc->N*average(sc->weight);
+ }
+ if(CLOSURE_IS_AMBIENT_OCCLUSION(sc->type)) {
eval += sc->weight;
+ *N += sd->N*average(sc->weight);
+ }
}
+ if(is_zero(*N))
+ *N = sd->N;
+ else
+ *N = normalize(*N);
+
return eval;
#else
- if(CLOSURE_IS_AMBIENT_OCCLUSION(sd->closure.type))
+ *N = sd->N;
+
+ if(CLOSURE_IS_BSDF_DIFFUSE(sd->closure.type))
+ return sd->closure.weight*ao_factor;
+ else if(CLOSURE_IS_AMBIENT_OCCLUSION(sd->closure.type))
return sd->closure.weight;
else
return make_float3(0.0f, 0.0f, 0.0f);
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index d4d88466688..977fb8c4fd4 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -111,6 +111,7 @@ CCL_NAMESPACE_BEGIN
#define __BACKGROUND_MIS__
#define __AO__
#define __CAMERA_MOTION__
+#define __ANISOTROPIC__
#ifndef __KERNEL_CUDA__
#define __OBJECT_MOTION__
@@ -375,7 +376,9 @@ typedef struct ShaderClosure {
float data1;
float3 N;
+#ifdef __ANISOTROPIC__
float3 T;
+#endif
} ShaderClosure;
diff --git a/intern/cycles/kernel/osl/SConscript b/intern/cycles/kernel/osl/SConscript
new file mode 100644
index 00000000000..d4b42d2becb
--- /dev/null
+++ b/intern/cycles/kernel/osl/SConscript
@@ -0,0 +1,27 @@
+#!/usr/bin/python
+
+Import('env')
+
+defs = []
+incs = []
+cxxflags = Split(env['CXXFLAGS'])
+
+sources = env.Glob('*.cpp')
+
+incs.extend('. .. ../svm ../../render ../../util ../../device'.split())
+incs.append(env['BF_OIIO_INC'])
+incs.append(env['BF_BOOST_INC'])
+incs.append(env['BF_OSL_INC'])
+incs.append(env['BF_OPENEXR_INC'].split())
+
+defs.append('CCL_NAMESPACE_BEGIN=namespace ccl {')
+defs.append('CCL_NAMESPACE_END=}')
+defs.append('WITH_OSL')
+
+if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
+ cxxflags.append('-DBOOST_NO_RTTI -DBOOST_NO_TYPEID'.split())
+ incs.append(env['BF_PTHREADS_INC'])
+else:
+ cxxflags.append('-fno-rtti -DBOOST_NO_RTTI -DBOOST_NO_TYPEID'.split())
+
+env.BlenderLib ('cycles_kernel_osl', sources, incs, defs, libtype=['intern'], priority=[10], cxx_compileflags=cxxflags)
diff --git a/intern/cycles/kernel/osl/osl_closures.h b/intern/cycles/kernel/osl/osl_closures.h
index 71e9e5ae4fd..2d91b37be7e 100644
--- a/intern/cycles/kernel/osl/osl_closures.h
+++ b/intern/cycles/kernel/osl/osl_closures.h
@@ -66,6 +66,8 @@ void name(RendererServices *, int id, void *data) \
new (data) classname(); \
}
+#define CLOSURE_PREPARE_STATIC(name, classname) static CLOSURE_PREPARE(name, classname)
+
#define TO_VEC3(v) (*(OSL::Vec3 *)&(v))
#define TO_COLOR3(v) (*(OSL::Color3 *)&(v))
#define TO_FLOAT3(v) make_float3(v[0], v[1], v[2])
@@ -77,26 +79,26 @@ public:
ShaderClosure sc;
OSL::Vec3 N, T;
- CBSDFClosure(int scattering) : OSL::ClosurePrimitive(BSDF),
- m_scattering_label(scattering), m_shaderdata_flag(0) { }
- ~CBSDFClosure() { }
+ CBSDFClosure(int scattering) : OSL::ClosurePrimitive(BSDF),
+ m_scattering_label(scattering), m_shaderdata_flag(0) { }
+ ~CBSDFClosure() { }
- int scattering() const { return m_scattering_label; }
- int shaderdata_flag() const { return m_shaderdata_flag; }
+ int scattering() const { return m_scattering_label; }
+ int shaderdata_flag() const { return m_shaderdata_flag; }
ClosureType shaderclosure_type() const { return sc.type; }
- virtual void blur(float roughness) = 0;
- virtual float3 eval_reflect(const float3 &omega_out, const float3 &omega_in, float &pdf) const = 0;
- virtual float3 eval_transmit(const float3 &omega_out, const float3 &omega_in, float &pdf) const = 0;
+ virtual void blur(float roughness) = 0;
+ virtual float3 eval_reflect(const float3 &omega_out, const float3 &omega_in, float &pdf) const = 0;
+ virtual float3 eval_transmit(const float3 &omega_out, const float3 &omega_in, float &pdf) const = 0;
- virtual int sample(const float3 &Ng,
- const float3 &omega_out, const float3 &domega_out_dx, const float3 &domega_out_dy,
- float randu, float randv,
- float3 &omega_in, float3 &domega_in_dx, float3 &domega_in_dy,
- float &pdf, float3 &eval) const = 0;
+ virtual int sample(const float3 &Ng,
+ const float3 &omega_out, const float3 &domega_out_dx, const float3 &domega_out_dy,
+ float randu, float randv,
+ float3 &omega_in, float3 &domega_in_dx, float3 &domega_in_dy,
+ float &pdf, float3 &eval) const = 0;
protected:
- int m_scattering_label;
+ int m_scattering_label;
int m_shaderdata_flag;
};
@@ -151,7 +153,7 @@ public: \
} \
}; \
\
-ClosureParam *bsdf_##lower##_params() \
+static ClosureParam *bsdf_##lower##_params() \
{ \
static ClosureParam params[] = {
@@ -164,7 +166,7 @@ ClosureParam *bsdf_##lower##_params() \
return params; \
} \
\
-CLOSURE_PREPARE(bsdf_##lower##_prepare, Upper##Closure)
+CLOSURE_PREPARE_STATIC(bsdf_##lower##_prepare, Upper##Closure)
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/osl/osl_globals.h b/intern/cycles/kernel/osl/osl_globals.h
index 80ced9dfd62..ce283023c5c 100644
--- a/intern/cycles/kernel/osl/osl_globals.h
+++ b/intern/cycles/kernel/osl/osl_globals.h
@@ -22,12 +22,17 @@
#ifdef WITH_OSL
#include <OSL/oslexec.h>
+#include <cmath>
#include "util_map.h"
#include "util_param.h"
#include "util_thread.h"
#include "util_vector.h"
+#ifndef WIN32
+using std::isfinite;
+#endif
+
CCL_NAMESPACE_BEGIN
class OSLRenderServices;
@@ -38,6 +43,7 @@ struct OSLGlobals {
/* shading system */
OSL::ShadingSystem *ss;
+ OSL::TextureSystem *ts;
OSLRenderServices *services;
/* shader states */
diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp
index 54cbf49704f..e79c509b144 100644
--- a/intern/cycles/kernel/osl/osl_services.cpp
+++ b/intern/cycles/kernel/osl/osl_services.cpp
@@ -649,6 +649,80 @@ bool OSLRenderServices::has_userdata(ustring name, TypeDesc type, void *renderst
return false; /* never called by OSL */
}
+bool OSLRenderServices::texture(ustring filename, TextureOpt &options,
+ OSL::ShaderGlobals *sg,
+ float s, float t, float dsdx, float dtdx,
+ float dsdy, float dtdy, float *result)
+{
+ OSL::TextureSystem *ts = kernel_globals->osl.ts;
+ bool status = ts->texture(filename, options, s, t, dsdx, dtdx, dsdy, dtdy, result);
+
+ if(!status) {
+ if(options.nchannels == 3 || options.nchannels == 4) {
+ result[0] = 1.0f;
+ result[1] = 0.0f;
+ result[2] = 1.0f;
+
+ if(options.nchannels == 4)
+ result[3] = 1.0f;
+ }
+ }
+
+ return status;
+}
+
+bool OSLRenderServices::texture3d(ustring filename, TextureOpt &options,
+ OSL::ShaderGlobals *sg, const OSL::Vec3 &P,
+ const OSL::Vec3 &dPdx, const OSL::Vec3 &dPdy,
+ const OSL::Vec3 &dPdz, float *result)
+{
+ OSL::TextureSystem *ts = kernel_globals->osl.ts;
+ bool status = ts->texture3d(filename, options, P, dPdx, dPdy, dPdz, result);
+
+ if(!status) {
+ if(options.nchannels == 3 || options.nchannels == 4) {
+ result[0] = 1.0f;
+ result[1] = 0.0f;
+ result[2] = 1.0f;
+
+ if(options.nchannels == 4)
+ result[3] = 1.0f;
+ }
+
+ }
+
+ return status;
+}
+
+bool OSLRenderServices::environment(ustring filename, TextureOpt &options,
+ OSL::ShaderGlobals *sg, const OSL::Vec3 &R,
+ const OSL::Vec3 &dRdx, const OSL::Vec3 &dRdy, float *result)
+{
+ OSL::TextureSystem *ts = kernel_globals->osl.ts;
+ bool status = ts->environment(filename, options, R, dRdx, dRdy, result);
+
+ if(!status) {
+ if(options.nchannels == 3 || options.nchannels == 4) {
+ result[0] = 1.0f;
+ result[1] = 0.0f;
+ result[2] = 1.0f;
+
+ if(options.nchannels == 4)
+ result[3] = 1.0f;
+ }
+ }
+
+ return status;
+}
+
+bool OSLRenderServices::get_texture_info(ustring filename, int subimage,
+ ustring dataname,
+ TypeDesc datatype, void *data)
+{
+ OSL::TextureSystem *ts = kernel_globals->osl.ts;
+ return ts->get_texture_info(filename, subimage, dataname, datatype, data);
+}
+
int OSLRenderServices::pointcloud_search(OSL::ShaderGlobals *sg, ustring filename, const OSL::Vec3 &center,
float radius, int max_points, bool sort,
size_t *out_indices, float *out_distances, int derivs_offset)
diff --git a/intern/cycles/kernel/osl/osl_services.h b/intern/cycles/kernel/osl/osl_services.h
index ce62eaf8994..b5a7bbae7e5 100644
--- a/intern/cycles/kernel/osl/osl_services.h
+++ b/intern/cycles/kernel/osl/osl_services.h
@@ -84,6 +84,23 @@ public:
bool getmessage(OSL::ShaderGlobals *sg, ustring source, ustring name,
TypeDesc type, void *val, bool derivatives);
+ bool texture(ustring filename, TextureOpt &options,
+ OSL::ShaderGlobals *sg,
+ float s, float t, float dsdx, float dtdx,
+ float dsdy, float dtdy, float *result);
+
+ bool texture3d(ustring filename, TextureOpt &options,
+ OSL::ShaderGlobals *sg, const OSL::Vec3 &P,
+ const OSL::Vec3 &dPdx, const OSL::Vec3 &dPdy,
+ const OSL::Vec3 &dPdz, float *result);
+
+ bool environment(ustring filename, TextureOpt &options,
+ OSL::ShaderGlobals *sg, const OSL::Vec3 &R,
+ const OSL::Vec3 &dRdx, const OSL::Vec3 &dRdy, float *result);
+
+ bool get_texture_info(ustring filename, int subimage,
+ ustring dataname, TypeDesc datatype, void *data);
+
struct TraceData {
Ray ray;
Intersection isect;
diff --git a/intern/cycles/kernel/shaders/CMakeLists.txt b/intern/cycles/kernel/shaders/CMakeLists.txt
index 4f5a97c1bb6..f7fec62fd6d 100644
--- a/intern/cycles/kernel/shaders/CMakeLists.txt
+++ b/intern/cycles/kernel/shaders/CMakeLists.txt
@@ -89,7 +89,7 @@ foreach(_file ${SRC_OSL})
list(APPEND SRC_OSO
${_OSO_FILE}
)
-
+
unset(_OSL_FILE)
unset(_OSO_FILE)
endforeach()
diff --git a/intern/cycles/kernel/shaders/SConscript b/intern/cycles/kernel/shaders/SConscript
new file mode 100644
index 00000000000..36b86d7b4f6
--- /dev/null
+++ b/intern/cycles/kernel/shaders/SConscript
@@ -0,0 +1,42 @@
+#!/usr/bin/python
+import sys
+import os
+import Blender as B
+
+def normpath(path):
+ return os.path.abspath(os.path.normpath(path))
+
+Import ('env')
+
+oso_files = []
+
+if env['WITH_BF_CYCLES_OSL']:
+ shaders = env.Clone()
+
+ # osl compiler
+ osl_compiler = File(env.subst(env['BF_OSL_COMPILER'])).abspath
+
+ # build directory
+ root_build_dir = normpath(env['BF_BUILDDIR'])
+ build_dir = os.path.join(root_build_dir, 'intern/cycles/kernel/shaders')
+
+ # source directories and files
+ source_dir = Dir('.').srcnode().path
+
+ # dependencies
+ dependencies = shaders.Glob('*.h')
+
+ for f in os.listdir(source_dir):
+ if f.endswith('.osl'):
+ osl_file = os.path.join(source_dir, f)
+ oso_file = os.path.join(build_dir, f.replace('.osl', '.oso'))
+
+ command = "%s -O2 -I%s -o %s %s" % (osl_compiler, source_dir, oso_file, osl_file)
+
+ shaders.Command(oso_file, f, command)
+ shaders.Depends(oso_file, [f] + dependencies)
+
+ oso_files.append(oso_file)
+
+
+Return('oso_files')
diff --git a/intern/cycles/kernel/shaders/node_ambient_occlusion.osl b/intern/cycles/kernel/shaders/node_ambient_occlusion.osl
index 57a06f35461..b9423344e73 100644
--- a/intern/cycles/kernel/shaders/node_ambient_occlusion.osl
+++ b/intern/cycles/kernel/shaders/node_ambient_occlusion.osl
@@ -19,6 +19,7 @@
#include "stdosl.h"
shader node_ambient_occlusion(
+ normal NormalIn = N,
color Color = color(0.8, 0.8, 0.8),
output closure color AO = ambient_occlusion())
{
diff --git a/intern/cycles/kernel/shaders/node_brick_texture.osl b/intern/cycles/kernel/shaders/node_brick_texture.osl
index 478d9457001..b1f2a35789f 100644
--- a/intern/cycles/kernel/shaders/node_brick_texture.osl
+++ b/intern/cycles/kernel/shaders/node_brick_texture.osl
@@ -58,6 +58,8 @@ float brick(point p, float mortar_size, float bias,
}
shader node_brick_texture(
+ int use_mapping = 0,
+ matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
float Offset = 0.5,
int OffsetFrequency = 2,
float Squash = 1.0,
@@ -74,10 +76,15 @@ shader node_brick_texture(
output float Fac = 0.0,
output color Color = color(0.2, 0.2, 0.2))
{
+ point p = Vector;
+
+ if (use_mapping)
+ p = transform(mapping, p);
+
float tint = 0.0;
color Col = Color1;
- Fac = brick(Vector * Scale, MortarSize, Bias, BrickWidth, RowHeight,
+ Fac = brick(p * Scale, MortarSize, Bias, BrickWidth, RowHeight,
Offset, OffsetFrequency, Squash, SquashFrequency, tint);
if (Fac != 1.0) {
diff --git a/intern/cycles/kernel/shaders/node_brightness.osl b/intern/cycles/kernel/shaders/node_brightness.osl
index 8e9f5c9c796..b263d815566 100644
--- a/intern/cycles/kernel/shaders/node_brightness.osl
+++ b/intern/cycles/kernel/shaders/node_brightness.osl
@@ -20,32 +20,15 @@
shader node_brightness(
color ColorIn = color(0.8, 0.8, 0.8),
- float Brightness = 0.0,
+ float Bright = 0.0,
float Contrast = 0.0,
output color ColorOut = color(0.8, 0.8, 0.8))
{
- float delta = Contrast * (1.0 / 200.0);
- float a = 1.0 - delta * 2.0;
- float b;
+ float a = 1.0 + Contrast;
+ float b = Bright - Contrast*0.5;
- /* input value is a percentage */
- float bright_factor = Brightness / 100.0;
-
- /*
- * The algorithm is by Werner D. Streidt
- * (http://visca.com/ffactory/archives/5-99/msg00021.html)
- * Extracted of OpenCV demhist.c
- */
-
- if (Contrast > 0.0) {
- a = (a < 0.0 ? 1.0 / a : 0.0);
- b = a * (bright_factor - delta);
- }
- else {
- delta *= -1.0;
- b = a * (bright_factor + delta);
- }
-
- ColorOut = a * ColorIn + b;
+ ColorOut[0] = max(a*ColorIn[0] + b, 0.0);
+ ColorOut[1] = max(a*ColorIn[1] + b, 0.0);
+ ColorOut[2] = max(a*ColorIn[2] + b, 0.0);
}
diff --git a/intern/cycles/kernel/shaders/node_checker_texture.osl b/intern/cycles/kernel/shaders/node_checker_texture.osl
index 577caf308ff..eed56f4453a 100644
--- a/intern/cycles/kernel/shaders/node_checker_texture.osl
+++ b/intern/cycles/kernel/shaders/node_checker_texture.osl
@@ -40,6 +40,8 @@ float checker(point p)
}
shader node_checker_texture(
+ int use_mapping = 0,
+ matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
float Scale = 5.0,
point Vector = P,
color Color1 = color(0.8, 0.8, 0.8),
@@ -47,7 +49,12 @@ shader node_checker_texture(
output float Fac = 0.0,
output color Color = color(0.0, 0.0, 0.0))
{
- Fac = checker(Vector * Scale);
+ point p = Vector;
+
+ if (use_mapping)
+ p = transform(mapping, p);
+
+ Fac = checker(p * Scale);
if (Fac == 1.0) {
Color = Color1;
}
diff --git a/intern/cycles/kernel/shaders/node_environment_texture.osl b/intern/cycles/kernel/shaders/node_environment_texture.osl
index bad62e56ab4..4367f7f4994 100644
--- a/intern/cycles/kernel/shaders/node_environment_texture.osl
+++ b/intern/cycles/kernel/shaders/node_environment_texture.osl
@@ -19,14 +19,52 @@
#include "stdosl.h"
#include "node_color.h"
+vector environment_texture_direction_to_equirectangular(vector dir)
+{
+ float u = -atan2(dir[1], dir[0])/(2.0*M_PI) + 0.5;
+ float v = atan2(dir[2], hypot(dir[0], dir[1]))/M_PI + 0.5;
+
+ return vector(u, v, 0.0);
+}
+
+vector environment_texture_direction_to_mirrorball(vector dir)
+{
+ dir[1] -= 1.0;
+
+ float div = 2.0*sqrt(max(-0.5*dir[1], 0.0));
+ if(div > 0.0)
+ dir /= div;
+
+ float u = 0.5*(dir[0] + 1.0);
+ float v = 0.5*(dir[2] + 1.0);
+
+ return vector(u, v, 0.0);
+}
+
shader node_environment_texture(
+ int use_mapping = 0,
+ matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
vector Vector = P,
string filename = "",
+ string projection = "Equirectangular",
string color_space = "sRGB",
output color Color = color(0.0, 0.0, 0.0),
output float Alpha = 1.0)
{
- Color = (color)environment(filename, Vector, "alpha", Alpha);
+ vector p = Vector;
+
+ if (use_mapping)
+ p = transform(mapping, p);
+
+ p = normalize(p);
+
+ if (projection == "Equirectangular")
+ p = environment_texture_direction_to_equirectangular(p);
+ else
+ p = environment_texture_direction_to_mirrorball(p);
+
+ /* todo: use environment for better texture filtering of equirectangular */
+ Color = (color)texture(filename, p[0], 1.0 - p[1], "wrap", "periodic", "alpha", Alpha);
if (color_space == "sRGB")
Color = color_srgb_to_scene_linear(Color);
diff --git a/intern/cycles/kernel/shaders/node_gradient_texture.osl b/intern/cycles/kernel/shaders/node_gradient_texture.osl
index ae7cfa51f59..8d862dbad67 100644
--- a/intern/cycles/kernel/shaders/node_gradient_texture.osl
+++ b/intern/cycles/kernel/shaders/node_gradient_texture.osl
@@ -63,12 +63,19 @@ float gradient(point p, string type)
}
shader node_gradient_texture(
+ int use_mapping = 0,
+ matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
string Type = "Linear",
point Vector = P,
output float Fac = 0.0,
output color Color = color(0.0, 0.0, 0.0))
{
- Fac = gradient(Vector, Type);
+ point p = Vector;
+
+ if (use_mapping)
+ p = transform(mapping, p);
+
+ Fac = gradient(p, Type);
Color = color(Fac, Fac, Fac);
}
diff --git a/intern/cycles/kernel/shaders/node_hsv.osl b/intern/cycles/kernel/shaders/node_hsv.osl
index 8fd7a1612e8..0f4bedfb0f8 100644
--- a/intern/cycles/kernel/shaders/node_hsv.osl
+++ b/intern/cycles/kernel/shaders/node_hsv.osl
@@ -27,7 +27,6 @@ shader node_hsv(
color ColorIn = color(0.0, 0.0, 0.0),
output color ColorOut = color(0.0, 0.0, 0.0))
{
- float t = clamp(Fac, 0.0, 1.0);
color Color = rgb_to_hsv(ColorIn);
// remember: fmod doesn't work for negative numbers
@@ -38,6 +37,6 @@ shader node_hsv(
Color = hsv_to_rgb(Color);
- ColorOut = mix(Color, ColorIn, t);
+ ColorOut = mix(ColorIn, Color, Fac);
}
diff --git a/intern/cycles/kernel/shaders/node_image_texture.osl b/intern/cycles/kernel/shaders/node_image_texture.osl
index 6393605e6b5..53c4aeaeb5f 100644
--- a/intern/cycles/kernel/shaders/node_image_texture.osl
+++ b/intern/cycles/kernel/shaders/node_image_texture.osl
@@ -30,6 +30,8 @@ color image_texture_lookup(string filename, string color_space, float u, float v
}
shader node_image_texture(
+ int use_mapping = 0,
+ matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
point Vector = P,
string filename = "",
string color_space = "sRGB",
@@ -38,8 +40,13 @@ shader node_image_texture(
output color Color = color(0.0, 0.0, 0.0),
output float Alpha = 1.0)
{
+ point p = Vector;
+
+ if (use_mapping)
+ p = transform(mapping, p);
+
if (projection == "Flat") {
- Color = image_texture_lookup(filename, color_space, Vector[0], Vector[1], Alpha);
+ Color = image_texture_lookup(filename, color_space, p[0], p[1], Alpha);
}
else if (projection == "Box") {
/* object space normal */
@@ -104,15 +111,15 @@ shader node_image_texture(
float tmp_alpha;
if (weight[0] > 0.0) {
- Color += weight[0]*image_texture_lookup(filename, color_space, Vector[1], Vector[2], tmp_alpha);
+ Color += weight[0]*image_texture_lookup(filename, color_space, p[1], p[2], tmp_alpha);
Alpha += weight[0]*tmp_alpha;
}
if (weight[1] > 0.0) {
- Color += weight[1]*image_texture_lookup(filename, color_space, Vector[0], Vector[2], tmp_alpha);
+ Color += weight[1]*image_texture_lookup(filename, color_space, p[0], p[2], tmp_alpha);
Alpha += weight[1]*tmp_alpha;
}
if (weight[2] > 0.0) {
- Color += weight[2]*image_texture_lookup(filename, color_space, Vector[1], Vector[0], tmp_alpha);
+ Color += weight[2]*image_texture_lookup(filename, color_space, p[1], p[0], tmp_alpha);
Alpha += weight[2]*tmp_alpha;
}
}
diff --git a/intern/cycles/kernel/shaders/node_magic_texture.osl b/intern/cycles/kernel/shaders/node_magic_texture.osl
index e464b83bc9e..b81a30499b2 100644
--- a/intern/cycles/kernel/shaders/node_magic_texture.osl
+++ b/intern/cycles/kernel/shaders/node_magic_texture.osl
@@ -93,12 +93,19 @@ color magic(point p, int n, float distortion)
}
shader node_magic_texture(
+ int use_mapping = 0,
+ matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
int Depth = 2,
float Distortion = 5.0,
float Scale = 5.0,
point Vector = P,
output color Color = color(0.0, 0.0, 0.0))
{
- Color = magic(Vector * Scale, Depth, Distortion);
+ point p = Vector;
+
+ if (use_mapping)
+ p = transform(mapping, p);
+
+ Color = magic(p * Scale, Depth, Distortion);
}
diff --git a/intern/cycles/kernel/shaders/node_musgrave_texture.osl b/intern/cycles/kernel/shaders/node_musgrave_texture.osl
index 71461b8fd79..afdbca27a3f 100644
--- a/intern/cycles/kernel/shaders/node_musgrave_texture.osl
+++ b/intern/cycles/kernel/shaders/node_musgrave_texture.osl
@@ -187,6 +187,8 @@ float noise_musgrave_ridged_multi_fractal(point p, string basis, float H,
/* Shader */
shader node_musgrave_texture(
+ int use_mapping = 0,
+ matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
string Type = "fBM",
float Dimension = 2.0,
float Lacunarity = 1.0,
@@ -204,7 +206,12 @@ shader node_musgrave_texture(
string Basis = "Perlin";
float intensity = 1.0;
- point p = Vector * Scale;
+ point p = Vector;
+
+ if (use_mapping)
+ p = transform(mapping, p);
+
+ p = p * Scale;
if (Type == "Multifractal")
Fac = intensity * noise_musgrave_multi_fractal(p, Basis, dimension, lacunarity, octaves);
diff --git a/intern/cycles/kernel/shaders/node_noise_texture.osl b/intern/cycles/kernel/shaders/node_noise_texture.osl
index 227b2bf8cea..0a379491781 100644
--- a/intern/cycles/kernel/shaders/node_noise_texture.osl
+++ b/intern/cycles/kernel/shaders/node_noise_texture.osl
@@ -43,6 +43,8 @@ float noise(point p, string basis, float distortion, float detail, float fac, co
}
shader node_noise_texture(
+ int use_mapping = 0,
+ matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
float Distortion = 0.0,
float Scale = 5.0,
float Detail = 2.0,
@@ -50,7 +52,12 @@ shader node_noise_texture(
output float Fac = 0.0,
output color Color = color(0.2, 0.2, 0.2))
{
+ point p = Vector;
+
+ if (use_mapping)
+ p = transform(mapping, p);
+
string Basis = "Perlin";
- Fac = noise(Vector * Scale, Basis, Distortion, Detail, Fac, Color);
+ Fac = noise(p * Scale, Basis, Distortion, Detail, Fac, Color);
}
diff --git a/intern/cycles/kernel/shaders/node_sky_texture.osl b/intern/cycles/kernel/shaders/node_sky_texture.osl
index 932fb1e2f17..24a63c78458 100644
--- a/intern/cycles/kernel/shaders/node_sky_texture.osl
+++ b/intern/cycles/kernel/shaders/node_sky_texture.osl
@@ -43,9 +43,9 @@ color xyY_to_xyz(float x, float y, float Y)
color xyz_to_rgb(float x, float y, float z)
{
- return color(3.240479 * x + -1.537150 * y + -0.498535 * z,
- -0.969256 * x + 1.875991 * y + 0.041556 * z,
- 0.055648 * x + -0.204043 * y + 1.057311 * z);
+ return color( 3.240479 * x + -1.537150 * y + -0.498535 * z,
+ -0.969256 * x + 1.875991 * y + 0.041556 * z,
+ 0.055648 * x + -0.204043 * y + 1.057311 * z);
}
float sky_angle_between(float thetav, float phiv, float theta, float phi)
@@ -149,14 +149,21 @@ void precompute_sunsky(vector dir, float turbidity, output KernelSunSky sunsky)
}
shader node_sky_texture(
+ int use_mapping = 0,
+ matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
vector Vector = P,
vector sun_direction = vector(0, 0, 1),
float turbidity = 2.2,
output color Color = color(0.0, 0.0, 0.0))
{
+ vector p = Vector;
+
+ if (use_mapping)
+ p = transform(mapping, p);
+
KernelSunSky sunsky;
precompute_sunsky(sun_direction, turbidity, sunsky);
- Color = sky_xyz_radiance(sunsky, Vector);
+ Color = sky_xyz_radiance(sunsky, p);
}
diff --git a/intern/cycles/kernel/shaders/node_texture_coordinate.osl b/intern/cycles/kernel/shaders/node_texture_coordinate.osl
index 791838dfffe..37460bcfc98 100644
--- a/intern/cycles/kernel/shaders/node_texture_coordinate.osl
+++ b/intern/cycles/kernel/shaders/node_texture_coordinate.osl
@@ -56,7 +56,7 @@ shader node_texture_coordinate(
Camera = transform("camera", P);
Window = transform("NDC", P);
Normal = transform("world", "object", NormalIn);
- Reflection = reflect(I, NormalIn);
+ Reflection = -reflect(I, NormalIn);
}
if (bump_offset == "dx") {
@@ -77,5 +77,7 @@ shader node_texture_coordinate(
Camera += Dy(Camera);
Window += Dy(Window);
}
+
+ Window[2] = 0.0;
}
diff --git a/intern/cycles/kernel/shaders/node_voronoi_texture.osl b/intern/cycles/kernel/shaders/node_voronoi_texture.osl
index a44df00a267..43f8ecc666a 100644
--- a/intern/cycles/kernel/shaders/node_voronoi_texture.osl
+++ b/intern/cycles/kernel/shaders/node_voronoi_texture.osl
@@ -22,17 +22,24 @@
/* Voronoi */
shader node_voronoi_texture(
+ int use_mapping = 0,
+ matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
string Coloring = "Intensity",
float Scale = 5.0,
point Vector = P,
output float Fac = 0.0,
output color Color = color(0.0, 0.0, 0.0))
{
+ point p = Vector;
+
+ if (use_mapping)
+ p = transform(mapping, p);
+
/* compute distance and point coordinate of 4 nearest neighbours */
float da[4];
point pa[4];
- voronoi(Vector * Scale, "Distance Squared", 1.0, da, pa);
+ voronoi(p * Scale, "Distance Squared", 1.0, da, pa);
/* Colored output */
if (Coloring == "Intensity") {
diff --git a/intern/cycles/kernel/shaders/node_ward_bsdf.osl b/intern/cycles/kernel/shaders/node_ward_bsdf.osl
index e5c6f0ad705..82ce15ab9b6 100644
--- a/intern/cycles/kernel/shaders/node_ward_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_ward_bsdf.osl
@@ -30,20 +30,20 @@ shader node_ward_bsdf(
/* rotate tangent around normal */
vector T = Tangent;
- if(Rotation != 0.0)
+ if (Rotation != 0.0)
T = rotate(T, Rotation*2.0*M_PI, point(0.0, 0.0, 0.0), Normal);
/* compute roughness */
float RoughnessU, RoughnessV;
float aniso = clamp(Anisotropy, -0.99, 0.99);
- if(aniso < 0.0) {
- RoughnessU = Roughness/(1.0 + aniso);
- RoughnessV = Roughness*(1.0 + aniso);
+ if (aniso < 0.0) {
+ RoughnessU = Roughness / (1.0 + aniso);
+ RoughnessV = Roughness * (1.0 + aniso);
}
else {
- RoughnessU = Roughness*(1.0 - aniso);
- RoughnessV = Roughness/(1.0 - aniso);
+ RoughnessU = Roughness * (1.0 - aniso);
+ RoughnessV = Roughness / (1.0 - aniso);
}
BSDF = Color * ward(Normal, T, RoughnessU, RoughnessV);
diff --git a/intern/cycles/kernel/shaders/node_wave_texture.osl b/intern/cycles/kernel/shaders/node_wave_texture.osl
index 79b8a8885d1..6648cd06278 100644
--- a/intern/cycles/kernel/shaders/node_wave_texture.osl
+++ b/intern/cycles/kernel/shaders/node_wave_texture.osl
@@ -46,6 +46,8 @@ float wave(point p, float scale, string type, float detail, float distortion, fl
}
shader node_wave_texture(
+ int use_mapping = 0,
+ matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
string Type = "Bands",
float Scale = 5.0,
float Distortion = 0.0,
@@ -55,7 +57,12 @@ shader node_wave_texture(
output float Fac = 0.0,
output color Color = color (0.0, 0.0, 0.0))
{
- Fac = wave(Vector, Scale, Type, Detail, Distortion, DetailScale);
+ point p = Vector;
+
+ if (use_mapping)
+ p = transform(mapping, p);
+
+ Fac = wave(p, Scale, Type, Detail, Distortion, DetailScale);
Color = color(Fac, Fac, Fac);
}
diff --git a/intern/cycles/kernel/svm/svm_bsdf.h b/intern/cycles/kernel/svm/svm_bsdf.h
index 373710446e5..07927fe5691 100644
--- a/intern/cycles/kernel/svm/svm_bsdf.h
+++ b/intern/cycles/kernel/svm/svm_bsdf.h
@@ -24,7 +24,7 @@
#include "../closure/bsdf_reflection.h"
#include "../closure/bsdf_refraction.h"
#include "../closure/bsdf_transparent.h"
-#ifdef __DPDU__
+#ifdef __ANISOTROPIC__
#include "../closure/bsdf_ward.h"
#endif
#include "../closure/bsdf_westin.h"
@@ -75,7 +75,7 @@ __device int svm_bsdf_sample(const ShaderData *sd, const ShaderClosure *sc, floa
label = bsdf_microfacet_beckmann_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
break;
-#ifdef __DPDU__
+#ifdef __ANISOTROPIC__
case CLOSURE_BSDF_WARD_ID:
label = bsdf_ward_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
@@ -138,7 +138,7 @@ __device float3 svm_bsdf_eval(const ShaderData *sd, const ShaderClosure *sc, con
case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
eval = bsdf_microfacet_beckmann_eval_reflect(sc, sd->I, omega_in, pdf);
break;
-#ifdef __DPDU__
+#ifdef __ANISOTROPIC__
case CLOSURE_BSDF_WARD_ID:
eval = bsdf_ward_eval_reflect(sc, sd->I, omega_in, pdf);
break;
@@ -187,7 +187,7 @@ __device float3 svm_bsdf_eval(const ShaderData *sd, const ShaderClosure *sc, con
case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
eval = bsdf_microfacet_beckmann_eval_transmit(sc, sd->I, omega_in, pdf);
break;
-#ifdef __DPDU__
+#ifdef __ANISOTROPIC__
case CLOSURE_BSDF_WARD_ID:
eval = bsdf_ward_eval_transmit(sc, sd->I, omega_in, pdf);
break;
@@ -244,7 +244,7 @@ __device void svm_bsdf_blur(ShaderClosure *sc, float roughness)
case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
bsdf_microfacet_beckmann_blur(sc, roughness);
break;
-#ifdef __DPDU__
+#ifdef __ANISOTROPIC__
case CLOSURE_BSDF_WARD_ID:
bsdf_ward_blur(sc, roughness);
break;
diff --git a/intern/cycles/kernel/svm/svm_closure.h b/intern/cycles/kernel/svm/svm_closure.h
index f378d24463d..a4f8546f62b 100644
--- a/intern/cycles/kernel/svm/svm_closure.h
+++ b/intern/cycles/kernel/svm/svm_closure.h
@@ -225,7 +225,6 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st
break;
}
-#ifdef __DPDU__
case CLOSURE_BSDF_WARD_ID: {
#ifdef __CAUSTICS_TRICKS__
if(kernel_data.integrator.no_caustics && (path_flag & PATH_RAY_DIFFUSE))
@@ -233,9 +232,11 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st
#endif
ShaderClosure *sc = svm_node_closure_get(sd);
sc->N = N;
- sc->T = stack_load_float3(stack, data_node.z);
svm_node_closure_set_mix_weight(sc, mix_weight);
+#ifdef __ANISOTROPIC__
+ sc->T = stack_load_float3(stack, data_node.z);
+
/* rotate tangent */
float rotation = stack_load_float(stack, data_node.w);
@@ -256,9 +257,11 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st
}
sd->flag |= bsdf_ward_setup(sc);
+#else
+ sd->flag |= bsdf_diffuse_setup(sc);
+#endif
break;
}
-#endif
case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: {
ShaderClosure *sc = svm_node_closure_get(sd);
sc->N = N;
diff --git a/intern/cycles/kernel/svm/svm_hsv.h b/intern/cycles/kernel/svm/svm_hsv.h
index bce11d62923..26b6141ee3f 100644
--- a/intern/cycles/kernel/svm/svm_hsv.h
+++ b/intern/cycles/kernel/svm/svm_hsv.h
@@ -110,7 +110,7 @@ __device void svm_node_hsv(KernelGlobals *kg, ShaderData *sd, float *stack, uint
color = rgb_to_hsv(color);
- // remember: fmod doesn't work for negative numbers
+ /* remember: fmod doesn't work for negative numbers here */
color.x += hue + 0.5f;
color.x = fmod(color.x, 1.0f);
color.y *= sat;
diff --git a/intern/cycles/kernel/svm/svm_math.h b/intern/cycles/kernel/svm/svm_math.h
index e39c7a4ba6c..db3b8d3f763 100644
--- a/intern/cycles/kernel/svm/svm_math.h
+++ b/intern/cycles/kernel/svm/svm_math.h
@@ -38,6 +38,21 @@ __device float safe_acosf(float a)
return acosf(a);
}
+__device float compatible_powf(float x, float y)
+{
+ /* GPU pow doesn't accept negative x, do manual checks here */
+ if(x < 0.0f) {
+ if(fmod(-y, 2.0f) == 0.0f)
+ return powf(-x, y);
+ else
+ return -powf(-x, y);
+ }
+ else if(x == 0.0f)
+ return 0.0f;
+
+ return powf(x, y);
+}
+
__device float safe_powf(float a, float b)
{
if(b == 0.0f)
@@ -47,7 +62,7 @@ __device float safe_powf(float a, float b)
if(a < 0.0f && b != (int)b)
return 0.0f;
- return powf(a, b);
+ return compatible_powf(a, b);
}
__device float safe_logf(float a, float b)
diff --git a/intern/cycles/kernel/svm/svm_tex_coord.h b/intern/cycles/kernel/svm/svm_tex_coord.h
index 8ca7dff3970..9f2d3367420 100644
--- a/intern/cycles/kernel/svm/svm_tex_coord.h
+++ b/intern/cycles/kernel/svm/svm_tex_coord.h
@@ -20,17 +20,19 @@ CCL_NAMESPACE_BEGIN
/* Texture Coordinate Node */
-__device_inline float3 svm_background_offset(KernelGlobals *kg)
+__device_inline float3 svm_background_position(KernelGlobals *kg, float3 P)
{
Transform cameratoworld = kernel_data.cam.cameratoworld;
- return make_float3(cameratoworld.x.w, cameratoworld.y.w, cameratoworld.z.w);
+ float3 camP = make_float3(cameratoworld.x.w, cameratoworld.y.w, cameratoworld.z.w);
+
+ return camP + P;
}
__device_inline float3 svm_world_to_ndc(KernelGlobals *kg, ShaderData *sd, float3 P)
{
if(kernel_data.cam.type != CAMERA_PANORAMA) {
if(sd->object == ~0)
- P += svm_background_offset(kg);
+ P = svm_background_position(kg, P);
Transform tfm = kernel_data.cam.worldtondc;
return transform_perspective(&tfm, P);
@@ -78,11 +80,12 @@ __device void svm_node_tex_coord(KernelGlobals *kg, ShaderData *sd, float *stack
if(sd->object != ~0)
data = transform_point(&tfm, sd->P);
else
- data = transform_point(&tfm, sd->P + svm_background_offset(kg));
+ data = transform_point(&tfm, svm_background_position(kg, sd->P));
break;
}
case NODE_TEXCO_WINDOW: {
data = svm_world_to_ndc(kg, sd, sd->P);
+ data.z = 0.0f;
break;
}
case NODE_TEXCO_REFLECTION: {
@@ -135,11 +138,12 @@ __device void svm_node_tex_coord_bump_dx(KernelGlobals *kg, ShaderData *sd, floa
if(sd->object != ~0)
data = transform_point(&tfm, sd->P + sd->dP.dx);
else
- data = transform_point(&tfm, sd->P + sd->dP.dx + svm_background_offset(kg));
+ data = transform_point(&tfm, svm_background_position(kg, sd->P + sd->dP.dx));
break;
}
case NODE_TEXCO_WINDOW: {
data = svm_world_to_ndc(kg, sd, sd->P + sd->dP.dx);
+ data.z = 0.0f;
break;
}
case NODE_TEXCO_REFLECTION: {
@@ -195,11 +199,12 @@ __device void svm_node_tex_coord_bump_dy(KernelGlobals *kg, ShaderData *sd, floa
if(sd->object != ~0)
data = transform_point(&tfm, sd->P + sd->dP.dy);
else
- data = transform_point(&tfm, sd->P + sd->dP.dy + svm_background_offset(kg));
+ data = transform_point(&tfm, svm_background_position(kg, sd->P + sd->dP.dy));
break;
}
case NODE_TEXCO_WINDOW: {
data = svm_world_to_ndc(kg, sd, sd->P + sd->dP.dy);
+ data.z = 0.0f;
break;
}
case NODE_TEXCO_REFLECTION: {
@@ -278,7 +283,7 @@ __device void svm_node_normal_map(KernelGlobals *kg, ShaderData *sd, float *stac
N = normalize(sd->N + (N - sd->N)*strength);
}
- stack_store_float3(stack, normal_offset, normalize(N));
+ stack_store_float3(stack, normal_offset, N);
}
__device void svm_node_tangent(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node)
diff --git a/intern/cycles/render/camera.cpp b/intern/cycles/render/camera.cpp
index 308ebd0794a..32c273c1248 100644
--- a/intern/cycles/render/camera.cpp
+++ b/intern/cycles/render/camera.cpp
@@ -89,13 +89,12 @@ void Camera::update()
Transform ndctoraster = transform_scale(width, height, 1.0f);
/* raster to screen */
- Transform screentoraster = ndctoraster;
-
- screentoraster = ndctoraster *
+ Transform screentondc =
transform_scale(1.0f/(viewplane.right - viewplane.left),
1.0f/(viewplane.top - viewplane.bottom), 1.0f) *
transform_translate(-viewplane.left, -viewplane.bottom, 0.0f);
+ Transform screentoraster = ndctoraster * screentondc;
Transform rastertoscreen = transform_inverse(screentoraster);
/* screen to camera */
@@ -105,14 +104,24 @@ void Camera::update()
screentocamera = transform_inverse(transform_orthographic(nearclip, farclip));
else
screentocamera = transform_identity();
+
+ Transform cameratoscreen = transform_inverse(screentocamera);
rastertocamera = screentocamera * rastertoscreen;
+ cameratoraster = screentoraster * cameratoscreen;
cameratoworld = matrix;
screentoworld = cameratoworld * screentocamera;
rastertoworld = cameratoworld * rastertocamera;
ndctoworld = rastertoworld * ndctoraster;
- worldtoraster = transform_inverse(rastertoworld);
+
+ /* note we recompose matrices instead of taking inverses of the above, this
+ * is needed to avoid inverting near degenerate matrices that happen due to
+ * precision issues with large scenes */
+ worldtocamera = transform_inverse(matrix);
+ worldtoscreen = cameratoscreen * worldtocamera;
+ worldtondc = screentondc * worldtoscreen;
+ worldtoraster = ndctoraster * worldtondc;
/* differentials */
if(type == CAMERA_ORTHOGRAPHIC) {
@@ -160,10 +169,10 @@ void Camera::device_update(Device *device, DeviceScene *dscene, Scene *scene)
kcam->rastertoworld = rastertoworld;
kcam->rastertocamera = rastertocamera;
kcam->cameratoworld = cameratoworld;
- kcam->worldtoscreen = transform_inverse(screentoworld);
+ kcam->worldtocamera = worldtocamera;
+ kcam->worldtoscreen = worldtoscreen;
kcam->worldtoraster = worldtoraster;
- kcam->worldtondc = transform_inverse(ndctoworld);
- kcam->worldtocamera = transform_inverse(cameratoworld);
+ kcam->worldtondc = worldtondc;
/* camera motion */
kcam->have_motion = 0;
@@ -181,8 +190,8 @@ void Camera::device_update(Device *device, DeviceScene *dscene, Scene *scene)
}
else {
if(use_motion) {
- kcam->motion.pre = transform_inverse(motion.pre * rastertocamera);
- kcam->motion.post = transform_inverse(motion.post * rastertocamera);
+ kcam->motion.pre = cameratoraster * transform_inverse(motion.pre);
+ kcam->motion.post = cameratoraster * transform_inverse(motion.post);
}
else {
kcam->motion.pre = worldtoraster;
diff --git a/intern/cycles/render/camera.h b/intern/cycles/render/camera.h
index 4c2de7b50b8..9696161180d 100644
--- a/intern/cycles/render/camera.h
+++ b/intern/cycles/render/camera.h
@@ -82,9 +82,15 @@ public:
Transform screentoworld;
Transform rastertoworld;
Transform ndctoworld;
- Transform rastertocamera;
Transform cameratoworld;
+
Transform worldtoraster;
+ Transform worldtoscreen;
+ Transform worldtondc;
+ Transform worldtocamera;
+
+ Transform rastertocamera;
+ Transform cameratoraster;;
float3 dx;
float3 dy;
diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp
index f136f08dc2c..230a12f9ff2 100644
--- a/intern/cycles/render/image.cpp
+++ b/intern/cycles/render/image.cpp
@@ -36,6 +36,7 @@ ImageManager::ImageManager()
need_update = true;
pack_images = false;
osl_texture_system = NULL;
+ animation_frame = 0;
tex_num_images = TEX_NUM_IMAGES;
tex_num_float_images = TEX_NUM_FLOAT_IMAGES;
@@ -67,7 +68,24 @@ void ImageManager::set_extended_image_limits(void)
tex_image_byte_start = TEX_EXTENDED_IMAGE_BYTE_START;
}
-static bool is_float_image(const string& filename)
+bool ImageManager::set_animation_frame_update(int frame)
+{
+ if(frame != animation_frame) {
+ animation_frame = frame;
+
+ for(size_t slot = 0; slot < images.size(); slot++)
+ if(images[slot] && images[slot]->animated)
+ return true;
+
+ for(size_t slot = 0; slot < float_images.size(); slot++)
+ if(float_images[slot] && float_images[slot]->animated)
+ return true;
+ }
+
+ return false;
+}
+
+bool ImageManager::is_float_image(const string& filename)
{
ImageInput *in = ImageInput::create(filename);
bool is_float = false;
@@ -95,7 +113,7 @@ static bool is_float_image(const string& filename)
return is_float;
}
-int ImageManager::add_image(const string& filename, bool& is_float)
+int ImageManager::add_image(const string& filename, bool animated, bool& is_float)
{
Image *img;
size_t slot;
@@ -133,6 +151,7 @@ int ImageManager::add_image(const string& filename, bool& is_float)
img = new Image();
img->filename = filename;
img->need_load = true;
+ img->animated = animated;
img->users = 1;
float_images[slot] = img;
@@ -166,6 +185,7 @@ int ImageManager::add_image(const string& filename, bool& is_float)
img = new Image();
img->filename = filename;
img->need_load = true;
+ img->animated = animated;
img->users = 1;
images[slot] = img;
diff --git a/intern/cycles/render/image.h b/intern/cycles/render/image.h
index 485bfc5cbf5..4d177174971 100644
--- a/intern/cycles/render/image.h
+++ b/intern/cycles/render/image.h
@@ -51,16 +51,17 @@ public:
ImageManager();
~ImageManager();
- int add_image(const string& filename, bool& is_float);
+ int add_image(const string& filename, bool animated, bool& is_float);
void remove_image(const string& filename);
+ bool is_float_image(const string& filename);
void device_update(Device *device, DeviceScene *dscene, Progress& progress);
void device_free(Device *device, DeviceScene *dscene);
void set_osl_texture_system(void *texture_system);
void set_pack_images(bool pack_images_);
-
void set_extended_image_limits(void);
+ bool set_animation_frame_update(int frame);
bool need_update;
@@ -69,11 +70,13 @@ private:
int tex_num_float_images;
int tex_image_byte_start;
thread_mutex device_mutex;
+ int animation_frame;
struct Image {
string filename;
bool need_load;
+ bool animated;
int users;
};
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index 82afab4dc1a..48a8565ed98 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -100,6 +100,16 @@ void TextureMapping::compile(SVMCompiler& compiler, int offset_in, int offset_ou
}
}
+void TextureMapping::compile(OSLCompiler &compiler)
+{
+ if(!skip()) {
+ Transform tfm = transform_transpose(compute_transform());
+
+ compiler.parameter("mapping", tfm);
+ compiler.parameter("use_mapping", 1);
+ }
+}
+
/* Image Texture */
static ShaderEnum color_space_init()
@@ -130,11 +140,12 @@ ImageTextureNode::ImageTextureNode()
{
image_manager = NULL;
slot = -1;
- is_float = false;
+ is_float = -1;
filename = "";
color_space = ustring("Color");
projection = ustring("Flat");;
projection_blend = 0.0f;
+ animated = false;
add_input("Vector", SHADER_SOCKET_POINT, ShaderInput::TEXTURE_UV);
add_output("Color", SHADER_SOCKET_COLOR);
@@ -152,7 +163,7 @@ ShaderNode *ImageTextureNode::clone() const
ImageTextureNode *node = new ImageTextureNode(*this);
node->image_manager = NULL;
node->slot = -1;
- node->is_float = false;
+ node->is_float = -1;
return node;
}
@@ -163,8 +174,11 @@ void ImageTextureNode::compile(SVMCompiler& compiler)
ShaderOutput *alpha_out = output("Alpha");
image_manager = compiler.image_manager;
- if(slot == -1)
- slot = image_manager->add_image(filename, is_float);
+ if(is_float == -1) {
+ bool is_float_bool;
+ slot = image_manager->add_image(filename, animated, is_float_bool);
+ is_float = (int)is_float_bool;
+ }
if(!color_out->links.empty())
compiler.stack_assign(color_out);
@@ -220,6 +234,11 @@ void ImageTextureNode::compile(SVMCompiler& compiler)
void ImageTextureNode::compile(OSLCompiler& compiler)
{
+ tex_mapping.compile(compiler);
+
+ if(is_float == -1)
+ is_float = (int)image_manager->is_float_image(filename);
+
compiler.parameter("filename", filename.c_str());
if(is_float || color_space != "Color")
compiler.parameter("color_space", "Linear");
@@ -250,10 +269,11 @@ EnvironmentTextureNode::EnvironmentTextureNode()
{
image_manager = NULL;
slot = -1;
- is_float = false;
+ is_float = -1;
filename = "";
color_space = ustring("Color");
projection = ustring("Equirectangular");
+ animated = false;
add_input("Vector", SHADER_SOCKET_VECTOR, ShaderInput::POSITION);
add_output("Color", SHADER_SOCKET_COLOR);
@@ -271,7 +291,7 @@ ShaderNode *EnvironmentTextureNode::clone() const
EnvironmentTextureNode *node = new EnvironmentTextureNode(*this);
node->image_manager = NULL;
node->slot = -1;
- node->is_float = false;
+ node->is_float = -1;
return node;
}
@@ -282,8 +302,11 @@ void EnvironmentTextureNode::compile(SVMCompiler& compiler)
ShaderOutput *alpha_out = output("Alpha");
image_manager = compiler.image_manager;
- if(slot == -1)
- slot = image_manager->add_image(filename, is_float);
+ if(slot == -1) {
+ bool is_float_bool;
+ slot = image_manager->add_image(filename, animated, is_float_bool);
+ is_float = (int)is_float_bool;
+ }
if(!color_out->links.empty())
compiler.stack_assign(color_out);
@@ -328,7 +351,13 @@ void EnvironmentTextureNode::compile(SVMCompiler& compiler)
void EnvironmentTextureNode::compile(OSLCompiler& compiler)
{
+ tex_mapping.compile(compiler);
+
+ if(is_float == -1)
+ is_float = (int)image_manager->is_float_image(filename);
+
compiler.parameter("filename", filename.c_str());
+ compiler.parameter("projection", projection);
if(is_float || color_space != "Color")
compiler.parameter("color_space", "Linear");
else
@@ -438,6 +467,8 @@ void SkyTextureNode::compile(SVMCompiler& compiler)
void SkyTextureNode::compile(OSLCompiler& compiler)
{
+ tex_mapping.compile(compiler);
+
compiler.parameter_vector("sun_direction", sun_direction);
compiler.parameter("turbidity", turbidity);
compiler.add(this, "node_sky_texture");
@@ -501,6 +532,8 @@ void GradientTextureNode::compile(SVMCompiler& compiler)
void GradientTextureNode::compile(OSLCompiler& compiler)
{
+ tex_mapping.compile(compiler);
+
compiler.parameter("Type", type);
compiler.add(this, "node_gradient_texture");
}
@@ -559,6 +592,8 @@ void NoiseTextureNode::compile(SVMCompiler& compiler)
void NoiseTextureNode::compile(OSLCompiler& compiler)
{
+ tex_mapping.compile(compiler);
+
compiler.add(this, "node_noise_texture");
}
@@ -619,6 +654,8 @@ void VoronoiTextureNode::compile(SVMCompiler& compiler)
void VoronoiTextureNode::compile(OSLCompiler& compiler)
{
+ tex_mapping.compile(compiler);
+
compiler.parameter("Coloring", coloring);
compiler.add(this, "node_voronoi_texture");
}
@@ -706,6 +743,8 @@ void MusgraveTextureNode::compile(SVMCompiler& compiler)
void MusgraveTextureNode::compile(OSLCompiler& compiler)
{
+ tex_mapping.compile(compiler);
+
compiler.parameter("Type", type);
compiler.add(this, "node_musgrave_texture");
@@ -784,6 +823,8 @@ void WaveTextureNode::compile(SVMCompiler& compiler)
void WaveTextureNode::compile(OSLCompiler& compiler)
{
+ tex_mapping.compile(compiler);
+
compiler.parameter("Type", type);
compiler.add(this, "node_wave_texture");
@@ -841,6 +882,8 @@ void MagicTextureNode::compile(SVMCompiler& compiler)
void MagicTextureNode::compile(OSLCompiler& compiler)
{
+ tex_mapping.compile(compiler);
+
compiler.parameter("Depth", depth);
compiler.add(this, "node_magic_texture");
}
@@ -897,6 +940,8 @@ void CheckerTextureNode::compile(SVMCompiler& compiler)
void CheckerTextureNode::compile(OSLCompiler& compiler)
{
+ tex_mapping.compile(compiler);
+
compiler.add(this, "node_checker_texture");
}
@@ -985,6 +1030,8 @@ void BrickTextureNode::compile(SVMCompiler& compiler)
void BrickTextureNode::compile(OSLCompiler& compiler)
{
+ tex_mapping.compile(compiler);
+
compiler.parameter("Offset", offset);
compiler.parameter("OffsetFrequency", offset_frequency);
compiler.parameter("Squash", squash);
@@ -1578,6 +1625,8 @@ void HoldoutNode::compile(OSLCompiler& compiler)
AmbientOcclusionNode::AmbientOcclusionNode()
: ShaderNode("ambient_occlusion")
{
+ add_input("NormalIn", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, true);
+
add_input("Color", SHADER_SOCKET_COLOR, make_float3(0.8f, 0.8f, 0.8f));
add_output("AO", SHADER_SOCKET_CLOSURE);
}
diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h
index 27b07769e28..3e89c2286ad 100644
--- a/intern/cycles/render/nodes.h
+++ b/intern/cycles/render/nodes.h
@@ -36,6 +36,7 @@ public:
Transform compute_transform();
bool skip();
void compile(SVMCompiler& compiler, int offset_in, int offset_out);
+ void compile(OSLCompiler &compiler);
float3 translation;
float3 rotation;
@@ -67,11 +68,12 @@ public:
ImageManager *image_manager;
int slot;
- bool is_float;
+ int is_float;
string filename;
ustring color_space;
ustring projection;
float projection_blend;
+ bool animated;
static ShaderEnum color_space_enum;
static ShaderEnum projection_enum;
@@ -85,10 +87,11 @@ public:
ImageManager *image_manager;
int slot;
- bool is_float;
+ int is_float;
string filename;
ustring color_space;
ustring projection;
+ bool animated;
static ShaderEnum color_space_enum;
static ShaderEnum projection_enum;
diff --git a/intern/cycles/render/osl.cpp b/intern/cycles/render/osl.cpp
index 5fbc7932849..c5ecddcfc15 100644
--- a/intern/cycles/render/osl.cpp
+++ b/intern/cycles/render/osl.cpp
@@ -81,13 +81,14 @@ void OSLShaderManager::device_update(Device *device, DeviceScene *dscene, Scene
if(shader->sample_as_light && shader->has_surface_emission)
scene->light_manager->need_update = true;
- OSLCompiler compiler((void*)this, (void*)ss);
+ OSLCompiler compiler((void*)this, (void*)ss, scene->image_manager);
compiler.background = (shader == scene->shaders[scene->default_background]);
compiler.compile(og, shader);
}
/* setup shader engine */
og->ss = ss;
+ og->ts = ts;
og->services = services;
int background_id = scene->shader_manager->get_shader_id(scene->default_background);
og->background_state = og->surface_state[background_id & SHADER_MASK];
@@ -118,6 +119,7 @@ void OSLShaderManager::device_free(Device *device, DeviceScene *dscene)
/* clear shader engine */
og->use = false;
og->ss = NULL;
+ og->ts = NULL;
og->surface_state.clear();
og->volume_state.clear();
@@ -286,10 +288,11 @@ const char *OSLShaderManager::shader_load_bytecode(const string& hash, const str
/* Graph Compiler */
-OSLCompiler::OSLCompiler(void *manager_, void *shadingsys_)
+OSLCompiler::OSLCompiler(void *manager_, void *shadingsys_, ImageManager *image_manager_)
{
manager = manager_;
shadingsys = shadingsys_;
+ image_manager = image_manager_;
current_type = SHADER_TYPE_SURFACE;
current_shader = NULL;
background = false;
@@ -333,7 +336,7 @@ string OSLCompiler::compatible_name(ShaderNode *node, ShaderOutput *output)
while((i = sname.find(" ")) != string::npos)
sname.replace(i, 1, "");
- /* if output exists with the same name, add "In" suffix */
+ /* if input exists with the same name, add "Out" suffix */
foreach(ShaderInput *input, node->inputs) {
if (strcmp(input->name, output->name)==0) {
sname += "Out";
diff --git a/intern/cycles/render/osl.h b/intern/cycles/render/osl.h
index b4b3f59e02a..17934765155 100644
--- a/intern/cycles/render/osl.h
+++ b/intern/cycles/render/osl.h
@@ -83,7 +83,7 @@ protected:
class OSLCompiler {
public:
- OSLCompiler(void *manager, void *shadingsys);
+ OSLCompiler(void *manager, void *shadingsys, ImageManager *image_manager);
void compile(OSLGlobals *og, Shader *shader);
void add(ShaderNode *node, const char *name, bool isfilepath = false);
@@ -110,6 +110,7 @@ public:
ShaderType output_type() { return current_type; }
bool background;
+ ImageManager *image_manager;
private:
string id(ShaderNode *node);
diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp
index 41212c2db84..003b722b5a5 100644
--- a/intern/cycles/render/session.cpp
+++ b/intern/cycles/render/session.cpp
@@ -757,7 +757,7 @@ void Session::update_status_time(bool show_pause, bool show_done)
if(preview_time == 0.0 && resolution == 1)
preview_time = time_dt();
- double tile_time = (tile == 0)? 0.0: (time_dt() - preview_time - paused_time)/(sample);
+ double tile_time = (tile == 0 || sample == 0)? 0.0: (time_dt() - preview_time - paused_time) / sample;
/* negative can happen when we pause a bit before rendering, can discard that */
if(preview_time < 0.0) preview_time = 0.0;
diff --git a/intern/cycles/render/svm.cpp b/intern/cycles/render/svm.cpp
index dc249984499..73904eac41d 100644
--- a/intern/cycles/render/svm.cpp
+++ b/intern/cycles/render/svm.cpp
@@ -487,7 +487,39 @@ void SVMCompiler::generate_closure(ShaderNode *node, set<ShaderNode*>& done)
}
}
-void SVMCompiler::generate_multi_closure(ShaderNode *node, set<ShaderNode*>& done, uint in_offset)
+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)
{
/* 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
@@ -524,21 +556,37 @@ void SVMCompiler::generate_multi_closure(ShaderNode *node, set<ShaderNode*>& don
out2_offset = in_offset;
}
- if(cl1in->link) {
- generate_multi_closure(cl1in->link->parent, done, out1_offset);
-
- if(fin)
- stack_clear_offset(SHADER_SOCKET_FLOAT, out1_offset);
- }
+ if(cl1in->link)
+ generate_multi_closure(cl1in->link->parent, done, closure_data, out1_offset);
- if(cl2in->link) {
- generate_multi_closure(cl2in->link->parent, done, out2_offset);
+ if(cl2in->link)
+ generate_multi_closure(cl2in->link->parent, done, closure_data, out2_offset);
- if(fin)
- stack_clear_offset(SHADER_SOCKET_FLOAT, out2_offset);
- }
+ if(in_offset != SVM_STACK_INVALID)
+ stack_clear_offset(SHADER_SOCKET_FLOAT, in_offset);
}
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) {
@@ -548,7 +596,7 @@ void SVMCompiler::generate_multi_closure(ShaderNode *node, set<ShaderNode*>& don
}
}
- mix_weight_offset = in_offset;
+ mix_weight_offset = data.stack_offset;
/* compile closure itself */
node->compile(*this);
@@ -563,6 +611,9 @@ void SVMCompiler::generate_multi_closure(ShaderNode *node, set<ShaderNode*>& don
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);
}
}
@@ -634,8 +685,12 @@ void SVMCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType ty
if(generate) {
set<ShaderNode*> done;
- if(use_multi_closure)
- generate_multi_closure(clin->link->parent, done, SVM_STACK_INVALID);
+ 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);
+ }
else
generate_closure(clin->link->parent, done);
}
diff --git a/intern/cycles/render/svm.h b/intern/cycles/render/svm.h
index 0db68f400fc..c7b66d97289 100644
--- a/intern/cycles/render/svm.h
+++ b/intern/cycles/render/svm.h
@@ -81,6 +81,7 @@ public:
bool background;
protected:
+ /* stack */
struct Stack {
Stack() { memset(users, 0, sizeof(users)); }
Stack(const Stack& other) { memcpy(users, other.users, sizeof(users)); }
@@ -123,11 +124,22 @@ protected:
bool node_skip_input(ShaderNode *node, ShaderInput *input);
+ /* single closure */
void find_dependencies(set<ShaderNode*>& dependencies, const set<ShaderNode*>& done, ShaderInput *input);
void generate_svm_nodes(const set<ShaderNode*>& nodes, set<ShaderNode*>& done);
void generate_closure(ShaderNode *node, set<ShaderNode*>& done);
- void generate_multi_closure(ShaderNode *node, set<ShaderNode*>& done, uint in_offset);
+ /* 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);
+
+ /* compile */
void compile_type(Shader *shader, ShaderGraph *graph, ShaderType type);
vector<int4> svm_nodes;
diff --git a/intern/cycles/util/util_boundbox.h b/intern/cycles/util/util_boundbox.h
index a0cdf1761ad..6dd1c6c71e8 100644
--- a/intern/cycles/util/util_boundbox.h
+++ b/intern/cycles/util/util_boundbox.h
@@ -182,6 +182,16 @@ public:
bottom == other.bottom && top == other.top);
}
+ float width()
+ {
+ return right - left;
+ }
+
+ float height()
+ {
+ return top - bottom;
+ }
+
BoundBox2D operator*(float f) const
{
BoundBox2D result;
diff --git a/intern/cycles/util/util_thread.h b/intern/cycles/util/util_thread.h
index 843764ca9d6..751d22b2f63 100644
--- a/intern/cycles/util/util_thread.h
+++ b/intern/cycles/util/util_thread.h
@@ -75,7 +75,7 @@ protected:
* Boost implementation is a bit slow, and Mac OS X __thread is not supported
* but the pthreads implementation is optimized, so we use these macros. */
-#ifdef __APPLE__
+#if defined(__APPLE__) || defined(_WIN32)
#define tls_ptr(type, name) \
pthread_key_t name
@@ -90,10 +90,6 @@ protected:
#else
-#ifdef __WIN32
-#define __thread __declspec(thread)
-#endif
-
#define tls_ptr(type, name) \
__thread type *name
#define tls_set(name, value) \
diff --git a/intern/cycles/util/util_transform.cpp b/intern/cycles/util/util_transform.cpp
index 70ee13d96d7..4eee024990f 100644
--- a/intern/cycles/util/util_transform.cpp
+++ b/intern/cycles/util/util_transform.cpp
@@ -251,6 +251,13 @@ void transform_motion_decompose(MotionTransform *decomp, const MotionTransform *
transform_decompose(&decomp->pre, &motion->pre);
transform_decompose(&decomp->mid, mid);
transform_decompose(&decomp->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)
+ decomp->mid.x = -decomp->mid.x;
+ if(dot(decomp->pre.x, decomp->mid.x) < 0.0f)
+ decomp->pre.x = -decomp->pre.x;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/util/util_transform.h b/intern/cycles/util/util_transform.h
index df525542207..65162ebf4e6 100644
--- a/intern/cycles/util/util_transform.h
+++ b/intern/cycles/util/util_transform.h
@@ -39,16 +39,16 @@ typedef struct Transform {
#endif
} 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) */
+
typedef struct MotionTransform {
Transform pre;
Transform mid;
Transform post;
} MotionTransform;
-/* 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) */
-
/* Functions */
__device_inline float3 transform_perspective(const Transform *t, const float3 a)
@@ -303,13 +303,11 @@ __device_inline Transform transform_clear_scale(const Transform& tfm)
__device_inline float4 quat_interpolate(float4 q1, float4 q2, float t)
{
+ /* 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);
- /* rotate around shortest angle */
- if(costheta < 0.0f) {
- costheta = -costheta;
- q1 = -q1;
- }
+ /* possible optimization: it might be possible to precompute theta/qperp */
if(costheta > 0.9995f) {
/* linear interpolation in degenerate case */
@@ -318,14 +316,17 @@ __device_inline float4 quat_interpolate(float4 q1, float4 q2, float t)
else {
/* slerp */
float theta = acosf(clamp(costheta, -1.0f, 1.0f));
- float thetap = theta * t;
float4 qperp = normalize(q2 - q1 * costheta);
+ float thetap = theta * t;
return q1 * cosf(thetap) + qperp * sinf(thetap);
}
}
__device_inline Transform transform_quick_inverse(Transform M)
{
+ /* possible optimization: can we avoid doing this altogether and construct
+ * the inverse matrix directly from negated translation, transposed rotation,
+ * scale can be inverted but what about shearing? */
Transform R;
float det = M.x.x*(M.z.z*M.y.y - M.z.y*M.y.z) - M.y.x*(M.z.z*M.x.y - M.z.y*M.x.z) + M.z.x*(M.y.z*M.x.y - M.y.y*M.x.z);
@@ -380,10 +381,17 @@ __device_inline void transform_compose(Transform *tfm, const Transform *decomp)
tfm->w = make_float4(0.0f, 0.0f, 0.0f, 1.0f);
}
+/* 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)
{
+ /* 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
+ * just shearing perhaps? */
Transform decomp;
+#ifdef CURVED_MOTION_INTERPOLATE
/* 3 point bezier curve interpolation for position */
float3 Ppre = float4_to_float3(motion->pre.y);
float3 Pmid = float4_to_float3(motion->mid.y);
@@ -395,13 +403,18 @@ __device void transform_motion_interpolate(Transform *tfm, const MotionTransform
decomp.y.x = P.x;
decomp.y.y = P.y;
decomp.y.z = P.z;
+#endif
/* linear interpolation for rotation and scale */
if(t < 0.5f) {
t *= 2.0f;
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;
+#else
+ 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;
}
@@ -409,7 +422,11 @@ __device void transform_motion_interpolate(Transform *tfm, const MotionTransform
t = (t - 0.5f)*2.0f;
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;
+#else
+ 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;
}
diff --git a/intern/elbeem/intern/ntl_geometryobject.cpp b/intern/elbeem/intern/ntl_geometryobject.cpp
index 4f640253f0f..1e08cb96a95 100644
--- a/intern/elbeem/intern/ntl_geometryobject.cpp
+++ b/intern/elbeem/intern/ntl_geometryobject.cpp
@@ -787,7 +787,7 @@ ntlVec3Gfx ntlGeometryObject::getTranslation(double t) {
}
/*! get active flag time t*/
float ntlGeometryObject::getGeoActive(double t) {
- float act = mcGeoActive.get(t); // if <= 0.0 -> off
+ float act = (mcGeoActive.get(t) >= 1.) ? 1.0 : 0.0;
return act;
}
diff --git a/intern/elbeem/intern/ntl_world.cpp b/intern/elbeem/intern/ntl_world.cpp
index 0b36f724985..dcc81dbe5cb 100644
--- a/intern/elbeem/intern/ntl_world.cpp
+++ b/intern/elbeem/intern/ntl_world.cpp
@@ -143,6 +143,7 @@ void ntlWorld::initDefaults()
mFirstSim = 1;
mSingleStepDebug = false;
mFrameCnt = 0;
+ mSimFrameCnt = 0;
mpOpenGLRenderer = NULL;
/* create scene storage */
@@ -406,7 +407,6 @@ int ntlWorld::advanceSims(int framenum)
}
for(size_t i=0;i<mpSims->size();i++) { (*mpSims)[i]->setFrameNum(framenum); }
- double targetTime = mSimulationTime + (*mpSims)[mFirstSim]->getFrameTime(framenum);
// time stopped? nothing else to do...
if( (*mpSims)[mFirstSim]->getFrameTime(framenum) <= 0.0 ){
@@ -416,6 +416,13 @@ int ntlWorld::advanceSims(int framenum)
(*mpSims)[mFirstSim]->checkCallerStatus(FLUIDSIM_CBSTATUS_STEP, 0);
}
+ // Prevent bug [#29186] Object contribute to fluid sim animation start earlier than keyframe
+ // Was: double targetTime = mSimulationTime + (*mpSims)[mFirstSim]->getFrameTime(framenum); - DG
+ double totalTime = 0.0, targetTime = 0.0;
+ for(size_t i = 0; i < mSimFrameCnt; i++)
+ totalTime += (*mpSims)[mFirstSim]->getFrameTime(framenum);
+ targetTime = totalTime + (*mpSims)[mFirstSim]->getFrameTime(framenum);
+
int gstate = 0;
myTime_t advsstart = getTime();
@@ -461,6 +468,8 @@ int ntlWorld::advanceSims(int framenum)
sim->prepareVisualization();
}
+ mSimFrameCnt++;
+
return 0;
}
diff --git a/intern/elbeem/intern/ntl_world.h b/intern/elbeem/intern/ntl_world.h
index 3c5958477d4..c207904cf75 100644
--- a/intern/elbeem/intern/ntl_world.h
+++ b/intern/elbeem/intern/ntl_world.h
@@ -115,6 +115,9 @@ class ntlWorld
/*! count no. of frame for viz render */
int mFrameCnt;
+
+ /*! count no. of frame for correct sim time */
+ int mSimFrameCnt;
};
diff --git a/intern/ghost/intern/GHOST_SystemCocoa.h b/intern/ghost/intern/GHOST_SystemCocoa.h
index 08f982ffd3f..9162b7ce4e0 100644
--- a/intern/ghost/intern/GHOST_SystemCocoa.h
+++ b/intern/ghost/intern/GHOST_SystemCocoa.h
@@ -282,9 +282,6 @@ protected:
/** Raised window is not yet known by the window manager, so delay application become active event handling */
bool m_needDelayedApplicationBecomeActiveEventProcessing;
- /** Mouse buttons state */
- GHOST_TUns32 m_pressedMouseButtons;
-
/** State of the modifiers. */
GHOST_TUns32 m_modifierMask;
diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm
index 475ad2bdcb3..16edb4af575 100644
--- a/intern/ghost/intern/GHOST_SystemCocoa.mm
+++ b/intern/ghost/intern/GHOST_SystemCocoa.mm
@@ -551,7 +551,6 @@ GHOST_SystemCocoa::GHOST_SystemCocoa()
char *rstring = NULL;
m_modifierMask =0;
- m_pressedMouseButtons =0;
m_isGestureInProgress = false;
m_cursorDelta_x=0;
m_cursorDelta_y=0;
@@ -577,8 +576,10 @@ GHOST_SystemCocoa::GHOST_SystemCocoa()
sysctl( mib, 2, rstring, &len, NULL, 0 );
//Hack on MacBook revision, as multitouch avail. function missing
+ //MacbookAir or MacBook version >= 5 (retina is MacBookPro10,1)
if (strstr(rstring,"MacBookAir") ||
- (strstr(rstring,"MacBook") && (rstring[strlen(rstring)-3]>='5') && (rstring[strlen(rstring)-3]<='9')))
+ (strstr(rstring,"MacBook") && (rstring[strlen(rstring)-3]>='5') && (rstring[strlen(rstring)-3]<='9')) ||
+ (strstr(rstring,"MacBook") && (rstring[strlen(rstring)-4]>='1') && (rstring[strlen(rstring)-4]<='9')))
m_hasMultiTouchTrackpad = true;
else m_hasMultiTouchTrackpad = false;
@@ -848,12 +849,14 @@ GHOST_TSuccess GHOST_SystemCocoa::getModifierKeys(GHOST_ModifierKeys& keys) cons
GHOST_TSuccess GHOST_SystemCocoa::getButtons(GHOST_Buttons& buttons) const
{
+ UInt32 button_state = GetCurrentEventButtonState();
+
buttons.clear();
- buttons.set(GHOST_kButtonMaskLeft, m_pressedMouseButtons & GHOST_kButtonMaskLeft);
- buttons.set(GHOST_kButtonMaskRight, m_pressedMouseButtons & GHOST_kButtonMaskRight);
- buttons.set(GHOST_kButtonMaskMiddle, m_pressedMouseButtons & GHOST_kButtonMaskMiddle);
- buttons.set(GHOST_kButtonMaskButton4, m_pressedMouseButtons & GHOST_kButtonMaskButton4);
- buttons.set(GHOST_kButtonMaskButton5, m_pressedMouseButtons & GHOST_kButtonMaskButton5);
+ buttons.set(GHOST_kButtonMaskLeft, button_state & (1 << 0));
+ buttons.set(GHOST_kButtonMaskRight, button_state & (1 << 1));
+ buttons.set(GHOST_kButtonMaskMiddle, button_state & (1 << 2));
+ buttons.set(GHOST_kButtonMaskButton4, button_state & (1 << 3));
+ buttons.set(GHOST_kButtonMaskButton5, button_state & (1 << 4));
return GHOST_kSuccess;
}
@@ -1591,13 +1594,17 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
if ((dx == 0) && (dy == 0)) break;
/* Quadratic acceleration */
- dx = dx*(fabs(dx)+0.5);
- if (dx<0.0) dx-=0.5; else dx+=0.5;
- if (dx< -deltaMax) dx= -deltaMax; else if (dx>deltaMax) dx=deltaMax;
+ dx = dx*(fabs(dx) + 0.5);
+ if (dx < 0.0) dx -= 0.5;
+ else dx += 0.5;
+ if (dx < -deltaMax) dx = -deltaMax;
+ else if (dx > deltaMax) dx = deltaMax;
- dy = dy*(fabs(dy)+0.5);
- if (dy<0.0) dy-=0.5; else dy+=0.5;
- if (dy< -deltaMax) dy= -deltaMax; else if (dy>deltaMax) dy=deltaMax;
+ dy = dy*(fabs(dy) + 0.5);
+ if (dy < 0.0) dy -= 0.5;
+ else dy += 0.5;
+ if (dy < -deltaMax) dy= -deltaMax;
+ else if (dy > deltaMax) dy= deltaMax;
window->clientToScreenIntern(mousePos.x, mousePos.y, x, y);
dy = -dy;
diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp
index c9953c80a52..2d3cc4f88dc 100644
--- a/intern/ghost/intern/GHOST_SystemX11.cpp
+++ b/intern/ghost/intern/GHOST_SystemX11.cpp
@@ -256,7 +256,7 @@ createWindow(
window = new GHOST_WindowX11(this, m_display, title,
left, top, width, height,
- state, parentWindow, type, stereoVisual);
+ state, parentWindow, type, stereoVisual, numOfAASamples);
if (window) {
/* Both are now handle in GHOST_WindowX11.cpp
diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp
index fa9e00f82a1..820f59def14 100644
--- a/intern/ghost/intern/GHOST_WindowX11.cpp
+++ b/intern/ghost/intern/GHOST_WindowX11.cpp
@@ -1285,6 +1285,10 @@ activateDrawingContext()
#else
glXMakeCurrent(m_display, m_window, m_context);
#endif
+ /* Disable AA by default */
+ if (m_numOfAASamples > 0) {
+ glDisable(GL_MULTISAMPLE_ARB);
+ }
return GHOST_kSuccess;
}
return GHOST_kFailure;
diff --git a/intern/iksolver/intern/IK_QJacobianSolver.cpp b/intern/iksolver/intern/IK_QJacobianSolver.cpp
index 43d177d0651..75f51f566c9 100644
--- a/intern/iksolver/intern/IK_QJacobianSolver.cpp
+++ b/intern/iksolver/intern/IK_QJacobianSolver.cpp
@@ -377,7 +377,7 @@ bool IK_QJacobianSolver::Solve(
norm = maxnorm;
// check for convergence
- if (norm < 1e-3) {
+ if (norm < 1e-3 && iterations > 10) {
solved = true;
break;
}
diff --git a/intern/locale/CMakeLists.txt b/intern/locale/CMakeLists.txt
new file mode 100644
index 00000000000..3187639c844
--- /dev/null
+++ b/intern/locale/CMakeLists.txt
@@ -0,0 +1,45 @@
+# ***** 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.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Bastien Montagne.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+set(INC
+ .
+)
+
+set(INC_SYS
+)
+
+set(SRC
+ boost_locale_wrapper.cpp
+)
+
+if(WITH_INTERNATIONAL)
+ list(APPEND INC_SYS
+ ${BOOST_INCLUDE_DIR}
+ )
+ add_definitions(-DWITH_INTERNATIONAL)
+ add_definitions(${BOOST_DEFINITIONS})
+endif()
+
+blender_add_lib(bf_intern_locale "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/intern/locale/SConscript b/intern/locale/SConscript
new file mode 100644
index 00000000000..df745f093ea
--- /dev/null
+++ b/intern/locale/SConscript
@@ -0,0 +1,14 @@
+#!/usr/bin/python
+
+Import('env')
+
+sources = env.Glob('*.cpp')
+
+incs = '.'
+defs = []
+
+if env['WITH_BF_INTERNATIONAL']:
+ defs.append('WITH_INTERNATIONAL')
+ incs += ' ' + env['BF_BOOST_INC']
+
+env.BlenderLib( 'bf_intern_locale', sources, Split(incs), defs, libtype=['intern','player'], priority=[10, 185])
diff --git a/intern/locale/boost_locale_wrapper.cpp b/intern/locale/boost_locale_wrapper.cpp
new file mode 100644
index 00000000000..939c66bad13
--- /dev/null
+++ b/intern/locale/boost_locale_wrapper.cpp
@@ -0,0 +1,114 @@
+/*
+ * ***** 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.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Bastien Montagne.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ */
+
+#include <stdio.h>
+#include <boost/locale.hpp>
+
+#include "boost_locale_wrapper.h"
+
+static std::string messages_path;
+static std::string default_domain;
+
+void bl_locale_init(const char *_messages_path, const char *_default_domain)
+{
+ // Avoid using ICU backend, we do not need its power and it's rather heavy!
+ boost::locale::localization_backend_manager lman = boost::locale::localization_backend_manager::global();
+#if defined (_WIN32)
+ lman.select("winapi");
+#else
+ lman.select("posix");
+#endif
+ boost::locale::localization_backend_manager::global(lman);
+
+ messages_path = _messages_path;
+ default_domain = _default_domain;
+}
+
+void bl_locale_set(const char *locale)
+{
+ boost::locale::generator gen;
+ // Specify location of dictionaries.
+ gen.add_messages_path(messages_path);
+ gen.add_messages_domain(default_domain);
+ //gen.set_default_messages_domain(default_domain);
+
+ if (locale && locale[0]) {
+ std::locale::global(gen(locale));
+ }
+ else {
+#if defined (__APPLE__)
+ // workaround to get osx system locale from user defaults
+ FILE* fp;
+ std::string locale_osx = "";
+ char result[16];
+ int result_len = 0;
+
+ fp = popen("defaults read .GlobalPreferences AppleLocale", "r");
+
+ if(fp) {
+ result_len = fread(result, 1, sizeof(result) - 1, fp);
+
+ if(result_len > 0) {
+ result[result_len-1] = '\0'; // \0 terminate and remove \n
+ locale_osx = std::string(result) + std::string(".UTF-8");
+ }
+
+ pclose(fp);
+ }
+
+ if(locale_osx == "")
+ fprintf(stderr, "Locale set: failed to read AppleLocale read from defaults\n");
+
+ std::locale::global(gen(locale_osx.c_str()));
+#else
+ std::locale::global(gen(""));
+#endif
+ }
+ // Note: boost always uses "C" LC_NUMERIC by default!
+}
+
+const char* bl_locale_pgettext(const char *msgctxt, const char *msgid)
+{
+ // Note: We cannot use short stuff like boost::locale::gettext, because those return
+ // std::basic_string objects, which c_ptr()-returned char* is no more valid
+ // once deleted (which happens as soons they are out of scope of this func).
+ typedef boost::locale::message_format<char> char_message_facet;
+ try {
+ std::locale l;
+ char_message_facet const &facet = std::use_facet<char_message_facet>(l);
+ char const *r = facet.get(0, msgctxt, msgid);
+ if(r)
+ return r;
+ return msgid;
+ }
+ catch(std::exception const &e) {
+// std::cout << "boost_locale_pgettext: " << e.what() << " \n";
+ return msgid;
+ }
+}
+
diff --git a/intern/locale/boost_locale_wrapper.h b/intern/locale/boost_locale_wrapper.h
new file mode 100644
index 00000000000..e7956d216f1
--- /dev/null
+++ b/intern/locale/boost_locale_wrapper.h
@@ -0,0 +1,49 @@
+/*
+ * ***** 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.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Bastien Montagne.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ */
+
+/** \file locale/boost_locale_wrapper.h
+ * \ingroup locale
+ * A thin C wrapper around boost::locale...
+ */
+
+#ifndef __BOOST_LOCALE_WRAPPER_H__
+#define __BOOST_LOCALE_WRAPPER_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void bl_locale_init(const char *messages_path, const char *default_domain);
+void bl_locale_set(const char *locale);
+const char* bl_locale_pgettext(const char *msgctxt, const char *msgid);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __BOOST_LOCALE_WRAPPER_H__ */
diff --git a/intern/memutil/MEM_CacheLimiter.h b/intern/memutil/MEM_CacheLimiter.h
index cfff5d10e4f..daf66dc05b1 100644
--- a/intern/memutil/MEM_CacheLimiter.h
+++ b/intern/memutil/MEM_CacheLimiter.h
@@ -247,8 +247,10 @@ private:
if (!elem->can_destroy())
continue;
- /* by default 0 means higherst priority element */
- int priority = -(queue.size() - i - 1);
+ /* by default 0 means highest priority element */
+ /* casting a size type to int is questionable,
+ but unlikely to cause problems */
+ int priority = -((int)(queue.size()) - i - 1);
priority = getItemPriority(elem->get()->get_data(), priority);
if (priority < best_match_priority || best_match_elem == NULL) {
diff --git a/intern/memutil/MEM_SmartPtr.h b/intern/memutil/MEM_SmartPtr.h
index 09cf5c95854..dd19aae9db9 100644
--- a/intern/memutil/MEM_SmartPtr.h
+++ b/intern/memutil/MEM_SmartPtr.h
@@ -170,7 +170,7 @@ public :
}
/**
- * Assignment operator - ownership is transfered from rhs to lhs.
+ * Assignment operator - ownership is transferred from rhs to lhs.
* There is an intenional side-effect of function of transferring
* ownership from the const parameter rhs. This is to insure
* the 1-1 relationship.
diff --git a/intern/opencolorio/ocio_impl.cc b/intern/opencolorio/ocio_impl.cc
index 49fc44d1e12..2d73d2ff56b 100644
--- a/intern/opencolorio/ocio_impl.cc
+++ b/intern/opencolorio/ocio_impl.cc
@@ -48,7 +48,7 @@ using namespace OCIO_NAMESPACE;
#endif
#define MEM_NEW(type) new(MEM_mallocN(sizeof(type), __func__)) type()
-#define MEM_DELETE(what, type) if(what) { (what)->~type(); MEM_freeN(what); } (void)0
+#define MEM_DELETE(what, type) if(what) { ((type*)(what))->~type(); MEM_freeN(what); } (void)0
static void OCIO_reportError(const char *err)
{
@@ -421,8 +421,7 @@ void OCIOImpl::processorApplyRGBA_predivide(OCIO_ConstProcessorRcPtr *processor,
void OCIOImpl::processorRelease(OCIO_ConstProcessorRcPtr *p)
{
- p->~OCIO_ConstProcessorRcPtr();
- MEM_freeN(p);
+ MEM_DELETE(p, ConstProcessorRcPtr);
}
const char *OCIOImpl::colorSpaceGetName(OCIO_ConstColorSpaceRcPtr *cs)
diff --git a/intern/opennl/CMakeLists.txt b/intern/opennl/CMakeLists.txt
index 2f15bbb907c..754036de101 100644
--- a/intern/opennl/CMakeLists.txt
+++ b/intern/opennl/CMakeLists.txt
@@ -28,7 +28,11 @@ remove_strict_flags()
# remove debug flag here since this is not a blender maintained library
# and debug gives a lot of prints on UV unwrapping. developers can enable if they need to.
-remove_definitions(-DDEBUG)
+if(MSVC)
+ remove_definitions(-DDEBUG)
+else()
+ add_definitions(-UDEBUG)
+endif()
# quiet compiler warnings about undefined defines
diff --git a/source/darwin/blender.app/Contents/Info.plist b/release/darwin/blender.app/Contents/Info.plist
index 064ffe5bc3f..064ffe5bc3f 100644
--- a/source/darwin/blender.app/Contents/Info.plist
+++ b/release/darwin/blender.app/Contents/Info.plist
diff --git a/source/darwin/blender.app/Contents/MacOS/blender b/release/darwin/blender.app/Contents/MacOS/blender
index 5e05e74a307..5e05e74a307 100644
--- a/source/darwin/blender.app/Contents/MacOS/blender
+++ b/release/darwin/blender.app/Contents/MacOS/blender
diff --git a/source/darwin/blender.app/Contents/PkgInfo b/release/darwin/blender.app/Contents/PkgInfo
index bd04210fb49..bd04210fb49 100644
--- a/source/darwin/blender.app/Contents/PkgInfo
+++ b/release/darwin/blender.app/Contents/PkgInfo
diff --git a/source/darwin/blender.app/Contents/Resources/blender file icon.icns b/release/darwin/blender.app/Contents/Resources/blender file icon.icns
index 9065f1b359c..9065f1b359c 100644
--- a/source/darwin/blender.app/Contents/Resources/blender file icon.icns
+++ b/release/darwin/blender.app/Contents/Resources/blender file icon.icns
Binary files differ
diff --git a/source/darwin/blender.app/Contents/Resources/blender icon.icns b/release/darwin/blender.app/Contents/Resources/blender icon.icns
index 5eef94afde9..5eef94afde9 100644
--- a/source/darwin/blender.app/Contents/Resources/blender icon.icns
+++ b/release/darwin/blender.app/Contents/Resources/blender icon.icns
Binary files differ
diff --git a/source/darwin/blenderplayer.app/Contents/Info.plist b/release/darwin/blenderplayer.app/Contents/Info.plist
index c7b9ceb568e..c7b9ceb568e 100644
--- a/source/darwin/blenderplayer.app/Contents/Info.plist
+++ b/release/darwin/blenderplayer.app/Contents/Info.plist
diff --git a/source/darwin/blenderplayer.app/Contents/MacOS/blenderplayer b/release/darwin/blenderplayer.app/Contents/MacOS/blenderplayer
index 5e05e74a307..5e05e74a307 100644
--- a/source/darwin/blenderplayer.app/Contents/MacOS/blenderplayer
+++ b/release/darwin/blenderplayer.app/Contents/MacOS/blenderplayer
diff --git a/source/darwin/blenderplayer.app/Contents/PkgInfo b/release/darwin/blenderplayer.app/Contents/PkgInfo
index bd04210fb49..bd04210fb49 100644
--- a/source/darwin/blenderplayer.app/Contents/PkgInfo
+++ b/release/darwin/blenderplayer.app/Contents/PkgInfo
diff --git a/source/darwin/blenderplayer.app/Contents/Resources/blender file icon.icns b/release/darwin/blenderplayer.app/Contents/Resources/blender file icon.icns
index 9065f1b359c..9065f1b359c 100644
--- a/source/darwin/blenderplayer.app/Contents/Resources/blender file icon.icns
+++ b/release/darwin/blenderplayer.app/Contents/Resources/blender file icon.icns
Binary files differ
diff --git a/source/darwin/blenderplayer.app/Contents/Resources/blender player icon.icns b/release/darwin/blenderplayer.app/Contents/Resources/blender player icon.icns
index 5eef94afde9..5eef94afde9 100644
--- a/source/darwin/blenderplayer.app/Contents/Resources/blender player icon.icns
+++ b/release/darwin/blenderplayer.app/Contents/Resources/blender player icon.icns
Binary files differ
diff --git a/source/darwin/set_simulation_threads.app/Contents/Info.plist b/release/darwin/set_simulation_threads.app/Contents/Info.plist
index eb80955e5a6..eb80955e5a6 100644
--- a/source/darwin/set_simulation_threads.app/Contents/Info.plist
+++ b/release/darwin/set_simulation_threads.app/Contents/Info.plist
diff --git a/source/darwin/set_simulation_threads.app/Contents/MacOS/applet b/release/darwin/set_simulation_threads.app/Contents/MacOS/applet
index 0079f4b19d4..0079f4b19d4 100755
--- a/source/darwin/set_simulation_threads.app/Contents/MacOS/applet
+++ b/release/darwin/set_simulation_threads.app/Contents/MacOS/applet
Binary files differ
diff --git a/source/darwin/set_simulation_threads.app/Contents/PkgInfo b/release/darwin/set_simulation_threads.app/Contents/PkgInfo
index 3253614c402..3253614c402 100644
--- a/source/darwin/set_simulation_threads.app/Contents/PkgInfo
+++ b/release/darwin/set_simulation_threads.app/Contents/PkgInfo
diff --git a/source/darwin/set_simulation_threads.app/Contents/Resources/Scripts/main.scpt b/release/darwin/set_simulation_threads.app/Contents/Resources/Scripts/main.scpt
index fa562578a80..fa562578a80 100644
--- a/source/darwin/set_simulation_threads.app/Contents/Resources/Scripts/main.scpt
+++ b/release/darwin/set_simulation_threads.app/Contents/Resources/Scripts/main.scpt
Binary files differ
diff --git a/source/darwin/set_simulation_threads.app/Contents/Resources/applet.icns b/release/darwin/set_simulation_threads.app/Contents/Resources/applet.icns
index fcc1f09273d..fcc1f09273d 100644
--- a/source/darwin/set_simulation_threads.app/Contents/Resources/applet.icns
+++ b/release/darwin/set_simulation_threads.app/Contents/Resources/applet.icns
Binary files differ
diff --git a/source/darwin/set_simulation_threads.app/Contents/Resources/applet.rsrc b/release/darwin/set_simulation_threads.app/Contents/Resources/applet.rsrc
index 540621d0b9e..540621d0b9e 100644
--- a/source/darwin/set_simulation_threads.app/Contents/Resources/applet.rsrc
+++ b/release/darwin/set_simulation_threads.app/Contents/Resources/applet.rsrc
Binary files differ
diff --git a/source/darwin/set_simulation_threads.app/Contents/Resources/description.rtfd/TXT.rtf b/release/darwin/set_simulation_threads.app/Contents/Resources/description.rtfd/TXT.rtf
index 0d0a60c08b5..0d0a60c08b5 100644
--- a/source/darwin/set_simulation_threads.app/Contents/Resources/description.rtfd/TXT.rtf
+++ b/release/darwin/set_simulation_threads.app/Contents/Resources/description.rtfd/TXT.rtf
diff --git a/release/datafiles/blender_icons.png b/release/datafiles/blender_icons.png
index 257de8ae3c8..e09d7062780 100644
--- a/release/datafiles/blender_icons.png
+++ b/release/datafiles/blender_icons.png
Binary files differ
diff --git a/release/datafiles/startup.blend b/release/datafiles/startup.blend
index 5056246e743..6bb34002977 100644
--- a/release/datafiles/startup.blend
+++ b/release/datafiles/startup.blend
Binary files differ
diff --git a/release/scripts/modules/addon_utils.py b/release/scripts/modules/addon_utils.py
index 7e604c5de4c..6bf81d73f8b 100644
--- a/release/scripts/modules/addon_utils.py
+++ b/release/scripts/modules/addon_utils.py
@@ -232,7 +232,6 @@ def enable(module_name, default_set=True, persistent=False):
import os
import sys
- import imp
def handle_error():
import traceback
@@ -246,6 +245,7 @@ def enable(module_name, default_set=True, persistent=False):
mtime_orig = getattr(mod, "__time__", 0)
mtime_new = os.path.getmtime(mod.__file__)
if mtime_orig != mtime_new:
+ import imp
print("module changed on disk:", mod.__file__, "reloading...")
try:
diff --git a/release/scripts/modules/bl_i18n_utils/settings.py b/release/scripts/modules/bl_i18n_utils/settings.py
index 0db3f85f1ff..c7414e84046 100644
--- a/release/scripts/modules/bl_i18n_utils/settings.py
+++ b/release/scripts/modules/bl_i18n_utils/settings.py
@@ -40,46 +40,46 @@ LANGUAGES_CATEGORIES = (
)
LANGUAGES = (
# ID, UI english label, ISO code.
- ( 0, "Default (Default)", "DEFAULT", ""),
- ( 1, "English (English)", "en_US", "english"),
- ( 2, "Japanese (日本語)", "ja_JP", "japanese"),
- ( 3, "Dutch (Nederlandse taal)", "nl_NL", "dutch"),
- ( 4, "Italian (Italiano)", "it_IT", "italian"),
- ( 5, "German (Deutsch)", "de_DE", "german"),
- ( 6, "Finnish (Suomi)", "fi_FI", "finnish"),
- ( 7, "Swedish (Svenska)", "sv_SE", "swedish"),
- ( 8, "French (Français)", "fr_FR", "french"),
- ( 9, "Spanish (Español)", "es", "spanish"),
- (10, "Catalan (Català)", "ca_AD", "catalan"),
- (11, "Czech (Český)", "cs_CZ", "czech"),
- (12, "Portuguese (Português)", "pt_PT", "portuguese_portugal"),
- (13, "Simplified Chinese (简体中文)", "zh_CN", "Chinese (Simplified)_China.1252"),
- (14, "Traditional Chinese (繁體中文)", "zh_TW", "Chinese (Traditional)_China.1252"),
- (15, "Russian (Русский)", "ru_RU", "russian"),
- (16, "Croatian (Hrvatski)", "hr_HR", "croatian"),
- (17, "Serbian (Српски)", "sr_RS", "serbian"),
- (18, "Ukrainian (Український)", "uk_UA", "ukrainian"),
- (19, "Polish (Polski)", "pl_PL", "polish"),
- (20, "Romanian (Român)", "ro_RO", "romanian"),
+ ( 0, "Default (Default)", "DEFAULT"),
+ ( 1, "English (English)", "en_US"),
+ ( 2, "Japanese (日本語)", "ja_JP"),
+ ( 3, "Dutch (Nederlandse taal)", "nl_NL"),
+ ( 4, "Italian (Italiano)", "it_IT"),
+ ( 5, "German (Deutsch)", "de_DE"),
+ ( 6, "Finnish (Suomi)", "fi_FI"),
+ ( 7, "Swedish (Svenska)", "sv_SE"),
+ ( 8, "French (Français)", "fr_FR"),
+ ( 9, "Spanish (Español)", "es"),
+ (10, "Catalan (Català)", "ca_AD"),
+ (11, "Czech (Český)", "cs_CZ"),
+ (12, "Portuguese (Português)", "pt_PT"),
+ (13, "Simplified Chinese (简体中文)", "zh_CN"),
+ (14, "Traditional Chinese (繁體中文)", "zh_TW"),
+ (15, "Russian (Русский)", "ru_RU"),
+ (16, "Croatian (Hrvatski)", "hr_HR"),
+ (17, "Serbian (Српски)", "sr_RS"),
+ (18, "Ukrainian (Український)", "uk_UA"),
+ (19, "Polish (Polski)", "pl_PL"),
+ (20, "Romanian (Român)", "ro_RO"),
# Using the utf8 flipped form of Arabic (العربية).
- (21, "Arabic (ﺔﻴﺑﺮﻌﻟﺍ)", "ar_EG", "arabic"),
- (22, "Bulgarian (Български)", "bg_BG", "bulgarian"),
- (23, "Greek (Ελληνικά)", "el_GR", "greek"),
- (24, "Korean (한국 언어)", "ko_KR", "korean"),
- (25, "Nepali (नेपाली)", "ne_NP", "nepali"),
+ (21, "Arabic (ﺔﻴﺑﺮﻌﻟﺍ)", "ar_EG"),
+ (22, "Bulgarian (Български)", "bg_BG"),
+ (23, "Greek (Ελληνικά)", "el_GR"),
+ (24, "Korean (한국 언어)", "ko_KR"),
+ (25, "Nepali (नेपाली)", "ne_NP"),
# Using the utf8 flipped form of Persian (فارسی).
- (26, "Persian (ﯽﺳﺭﺎﻓ)", "fa_IR", "farsi"),
- (27, "Indonesian (Bahasa indonesia)", "id_ID", "indonesian"),
- (28, "Serbian Latin (Srpski latinica)", "sr_RS@latin", "serbian (latin)"),
- (29, "Kyrgyz (Кыргыз тили)", "ky_KG", "kyrgyz"),
- (30, "Turkish (Türkçe)", "tr_TR", "turkish"),
- (31, "Hungarian (Magyar)", "hu_HU", "hungarian"),
- (32, "Brazilian Portuguese (Português do Brasil)", "pt_BR", "protuguese_brazil"),
+ (26, "Persian (ﯽﺳﺭﺎﻓ)", "fa_IR"),
+ (27, "Indonesian (Bahasa indonesia)", "id_ID"),
+ (28, "Serbian Latin (Srpski latinica)", "sr_RS@latin"),
+ (29, "Kyrgyz (Кыргыз тили)", "ky_KG"),
+ (30, "Turkish (Türkçe)", "tr_TR"),
+ (31, "Hungarian (Magyar)", "hu_HU"),
+ (32, "Brazilian Portuguese (Português do Brasil)", "pt_BR"),
# Using the utf8 flipped form of Hebrew (עִבְרִית)).
- (33, "Hebrew (תירִבְעִ)", "he_IL", "hebrew"),
- (34, "Estonian (Eestlane)", "et_EE", "estonian"),
- (35, "Esperanto (Esperanto)", "eo", "esperanto"),
- (36, "Spanish from Spain (Español de España)", "es_ES", "spanish_spain"),
+ (33, "Hebrew (תירִבְעִ)", "he_IL"),
+ (34, "Estonian (Eestlane)", "et_EE"),
+ (35, "Esperanto (Esperanto)", "eo"),
+ (36, "Spanish from Spain (Español de España)", "es_ES"),
)
# Name of language file used by Blender to generate translations' menu.
@@ -114,6 +114,9 @@ DOMAIN = "blender"
# File type (ext) to parse.
PYGETTEXT_ALLOWED_EXTS = {".c", ".cpp", ".cxx", ".hpp", ".hxx", ".h"}
+# Max number of contexts into a BLF_I18N_MSGID_MULTI_CTXT macro...
+PYGETTEXT_MAX_MULTI_CTXT = 16
+
# Where to search contexts definitions, relative to SOURCE_DIR (defined below).
PYGETTEXT_CONTEXTS_DEFSRC = os.path.join("source", "blender", "blenfont",
"BLF_translation.h")
@@ -149,7 +152,10 @@ _str_whole_re = (
# End of loop.
"))*"
)
-_ctxt_re = r"(?P<ctxt_raw>(?:" + _str_whole_re.format(_="_ctxt") + r")|(?:[A-Z_0-9]+))"
+_ctxt_re_gen = lambda uid : r"(?P<ctxt_raw{uid}>(?:".format(uid=uid) + \
+ _str_whole_re.format(_="_ctxt{uid}".format(uid=uid)) + \
+ r")|(?:[A-Z_0-9]+))"
+_ctxt_re = _ctxt_re_gen("")
_msg_re = r"(?P<msg_raw>" + _str_whole_re.format(_="_msg") + r")"
PYGETTEXT_KEYWORDS = (() +
tuple((r"{}\(\s*" + _msg_re + r"\s*\)").format(it)
@@ -165,7 +171,11 @@ PYGETTEXT_KEYWORDS = (() +
for it in ("BMO_error_raise",)) +
tuple(("{}\\((?:[^\"',]+,)\\s*" + _msg_re + r"\s*(?:\)|,)").format(it)
- for it in ("modifier_setError",))
+ for it in ("modifier_setError",)) +
+
+ tuple((r"{}\(\s*" + _msg_re + r"\s*,\s*(?:" + \
+ r"\s*,\s*)?(?:".join(_ctxt_re_gen(i) for i in range(PYGETTEXT_MAX_MULTI_CTXT)) + r")?\s*\)").format(it)
+ for it in ("BLF_I18N_MSGID_MULTI_CTXT",))
)
ESCAPE_RE = (
diff --git a/release/scripts/modules/bl_i18n_utils/update_languages_menu.py b/release/scripts/modules/bl_i18n_utils/update_languages_menu.py
index d45a5543220..9b4cb20fadf 100755
--- a/release/scripts/modules/bl_i18n_utils/update_languages_menu.py
+++ b/release/scripts/modules/bl_i18n_utils/update_languages_menu.py
@@ -53,7 +53,7 @@ FLAG_MESSAGES = {
def find_matching_po(languages, stats, forbidden):
"""Match languages defined in LANGUAGES setting to relevant po, if possible!"""
ret = []
- for uid, label, org_key, long_loc in languages:
+ for uid, label, org_key, in languages:
key = org_key
if key not in stats:
# Try to simplify the key (eg from es_ES to es).
@@ -64,11 +64,11 @@ def find_matching_po(languages, stats, forbidden):
key = key + org_key[org_key.index('@'):]
if key in stats:
if key in forbidden:
- ret.append((stats[key], uid, label, org_key, long_loc, FORBIDDEN))
+ ret.append((stats[key], uid, label, org_key, FORBIDDEN))
else:
- ret.append((stats[key], uid, label, org_key, long_loc, OK))
+ ret.append((stats[key], uid, label, org_key, OK))
else:
- ret.append((0.0, uid, label, org_key, long_loc, MISSING))
+ ret.append((0.0, uid, label, org_key, MISSING))
return ret
def main():
@@ -103,14 +103,14 @@ def main():
stats = sorted(stats, key=lambda it: it[0], reverse=True)
langs_cats = [[] for i in range(len(limits))]
highest_uid = 0
- for prop, uid, label, key, long_loc, flag in stats:
+ for prop, uid, label, key, flag in stats:
if prop < limits[idx][0]:
# Sub-sort languages by iso-codes.
langs_cats[idx].sort(key=lambda it: it[2])
idx += 1
if prop < min_trans and flag == OK:
flag = TOOLOW
- langs_cats[idx].append((uid, label, key, long_loc, flag))
+ langs_cats[idx].append((uid, label, key, flag))
if abs(uid) > highest_uid:
highest_uid = abs(uid)
# Sub-sort last group of languages by iso-codes!
@@ -120,7 +120,7 @@ def main():
f.write("# and to generate translation menu.\n")
f.write("#\n")
f.write("# File format:\n")
- f.write("# ID:MENULABEL:ISOCODE:WINCODE\n")
+ f.write("# ID:MENULABEL:ISOCODE\n")
f.write("# ID must be unique, except for 0 value (marks categories for menu).\n")
f.write("# Line starting with a # are comments!\n")
f.write("#\n")
@@ -135,12 +135,12 @@ def main():
# Do not write the category if it has no language!
f.write("# Void category! #0:{}:\n".format(cat[1]))
# ...and all matching language entries!
- for uid, label, key, long_loc, flag in langs_cat:
+ for uid, label, key, flag in langs_cat:
if flag == OK:
- f.write("{}:{}:{}:{}\n".format(uid, label, key, long_loc))
+ f.write("{}:{}:{}\n".format(uid, label, key))
else:
# Non-existing, commented entry!
- f.write("# {} #{}:{}:{}:{}\n".format(FLAG_MESSAGES[flag], uid, label, key, long_loc))
+ f.write("# {} #{}:{}:{}\n".format(FLAG_MESSAGES[flag], uid, label, key))
if __name__ == "__main__":
diff --git a/release/scripts/modules/bl_i18n_utils/update_pot.py b/release/scripts/modules/bl_i18n_utils/update_pot.py
index 51197b86678..ecb5d837a09 100755
--- a/release/scripts/modules/bl_i18n_utils/update_pot.py
+++ b/release/scripts/modules/bl_i18n_utils/update_pot.py
@@ -52,6 +52,7 @@ SRC_POTFILES = settings.FILE_NAME_SRC_POTFILES
CONTEXT_DEFAULT = settings.CONTEXT_DEFAULT
PYGETTEXT_ALLOWED_EXTS = settings.PYGETTEXT_ALLOWED_EXTS
+PYGETTEXT_MAX_MULTI_CTXT = settings.PYGETTEXT_MAX_MULTI_CTXT
SVN_EXECUTABLE = settings.SVN_EXECUTABLE
@@ -79,6 +80,31 @@ clean_str = lambda s: "".join(m.group("clean") for m in _clean_str(s))
def check_file(path, rel_path, messages):
+ def process_entry(ctxt, msg):
+ # Context.
+ if ctxt:
+ if ctxt in CONTEXTS:
+ ctxt = CONTEXTS[ctxt]
+ elif '"' in ctxt or "'" in ctxt:
+ ctxt = clean_str(ctxt)
+ else:
+ print("WARNING: raw context “{}” couldn’t be resolved!"
+ "".format(ctxt))
+ ctxt = CONTEXT_DEFAULT
+ else:
+ ctxt = CONTEXT_DEFAULT
+ # Message.
+ if msg:
+ if '"' in msg or "'" in msg:
+ msg = clean_str(msg)
+ else:
+ print("WARNING: raw message “{}” couldn’t be resolved!"
+ "".format(msg))
+ msg = ""
+ else:
+ msg = ""
+ return (ctxt, msg)
+
with open(path, encoding="utf-8") as f:
f = f.read()
for srch in pygettexts:
@@ -86,34 +112,23 @@ def check_file(path, rel_path, messages):
line = pos = 0
while m:
d = m.groupdict()
- # Context.
- ctxt = d.get("ctxt_raw")
- if ctxt:
- if ctxt in CONTEXTS:
- ctxt = CONTEXTS[ctxt]
- elif '"' in ctxt or "'" in ctxt:
- ctxt = clean_str(ctxt)
- else:
- print("WARNING: raw context “{}” couldn’t be resolved!"
- "".format(ctxt))
- ctxt = CONTEXT_DEFAULT
- else:
- ctxt = CONTEXT_DEFAULT
- # Message.
- msg = d.get("msg_raw")
- if msg:
- if '"' in msg or "'" in msg:
- msg = clean_str(msg)
- else:
- print("WARNING: raw message “{}” couldn’t be resolved!"
- "".format(msg))
- msg = ""
- else:
- msg = ""
# Line.
line += f[pos:m.start()].count('\n')
- # And we are done for this item!
- messages.setdefault((ctxt, msg), []).append(":".join((rel_path, str(line))))
+ msg = d.get("msg_raw")
+ # First, try the "multi-contexts" stuff!
+ ctxts = tuple(d.get("ctxt_raw{}".format(i)) for i in range(PYGETTEXT_MAX_MULTI_CTXT))
+ if ctxts[0]:
+ for ctxt in ctxts:
+ if not ctxt:
+ break
+ ctxt, _msg = process_entry(ctxt, msg)
+ # And we are done for this item!
+ messages.setdefault((ctxt, _msg), []).append(":".join((rel_path, str(line))))
+ else:
+ ctxt = d.get("ctxt_raw")
+ ctxt, msg = process_entry(ctxt, msg)
+ # And we are done for this item!
+ messages.setdefault((ctxt, msg), []).append(":".join((rel_path, str(line))))
pos = m.end()
line += f[m.start():pos].count('\n')
m = srch(f, pos)
@@ -138,12 +153,12 @@ def py_xgettext(messages):
rel_path = os.path.relpath(path, SOURCE_DIR)
if rel_path in forbidden:
continue
- elif rel_path in forced:
- forced.remove(rel_path)
- check_file(path, rel_path, messages)
- for path in forced:
+ elif rel_path not in forced:
+ forced.add(rel_path)
+ for rel_path in sorted(forced):
+ path = os.path.join(SOURCE_DIR, rel_path)
if os.path.exists(path):
- check_file(os.path.join(SOURCE_DIR, path), path, messages)
+ check_file(path, rel_path, messages)
# Spell checking!
diff --git a/release/scripts/modules/bpy/utils.py b/release/scripts/modules/bpy/utils.py
index 573694ff08e..4ad00eb267e 100644
--- a/release/scripts/modules/bpy/utils.py
+++ b/release/scripts/modules/bpy/utils.py
@@ -216,7 +216,7 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
for mod in _global_loaded_modules:
test_reload(mod)
- _global_loaded_modules[:] = []
+ del _global_loaded_modules[:]
for base_path in script_paths():
for path_subdir in _script_module_dirs:
diff --git a/release/scripts/modules/bpy_extras/mesh_utils.py b/release/scripts/modules/bpy_extras/mesh_utils.py
index ad3cf8c08ec..2042cc1c8a1 100644
--- a/release/scripts/modules/bpy_extras/mesh_utils.py
+++ b/release/scripts/modules/bpy_extras/mesh_utils.py
@@ -223,7 +223,7 @@ def edge_loops_from_tessfaces(mesh, tessfaces=None, seams=()):
else:
other_dir = None
- ed_adj[:] = []
+ del ed_adj[:]
flipped = False
@@ -235,22 +235,22 @@ def edge_loops_from_tessfaces(mesh, tessfaces=None, seams=()):
if other_dir and flipped is False:
flipped = True # only flip the list once
context_loop.reverse()
- ed_adj[:] = []
+ del ed_adj[:]
context_loop.append(other_dir) # save 1 look-up
ed_adj = edges[context_loop[-1]]
if len(ed_adj) != 2:
- ed_adj[:] = []
+ del ed_adj[:]
break
else:
- ed_adj[:] = []
+ del ed_adj[:]
break
i = ed_adj.index(context_loop[-2])
context_loop.append(ed_adj[not i])
# Dont look at this again
- ed_adj[:] = []
+ del ed_adj[:]
return edge_loops
@@ -436,7 +436,7 @@ def ngon_tessellate(from_data, indices, fix_loops=True):
if s1[0][1] == s1[-1][1]: # remove endpoints double
s1.pop()
- s2[:] = [] # Empty this segment s2 so we don't use it again.
+ del s2[:] # Empty this segment s2 so we don't use it again.
return True
joining_segments = True
diff --git a/release/scripts/startup/bl_operators/object.py b/release/scripts/startup/bl_operators/object.py
index 4e90f2e8585..9e449f325d6 100644
--- a/release/scripts/startup/bl_operators/object.py
+++ b/release/scripts/startup/bl_operators/object.py
@@ -665,15 +665,60 @@ class TransformsToDeltasAnim(Operator):
return (obs is not None)
def execute(self, context):
+ # map from standard transform paths to "new" transform paths
+ STANDARD_TO_DELTA_PATHS = {
+ "location" : "delta_location",
+ "rotation_euler" : "delta_rotation_euler",
+ "rotation_quaternion" : "delta_rotation_quaternion",
+ #"rotation_axis_angle" : "delta_rotation_axis_angle",
+ "scale" : "delta_scale"
+ }
+ DELTA_PATHS = STANDARD_TO_DELTA_PATHS.values()
+
+ # try to apply on each selected object
+ success = False
for obj in context.selected_editable_objects:
- # get animation data
adt = obj.animation_data
if (adt is None) or (adt.action is None):
self.report({'WARNING'},
"No animation data to convert on object: %r" %
obj.name)
continue
-
+
+ # first pass over F-Curves: ensure that we don't have conflicting
+ # transforms already (e.g. if this was applied already) [#29110]
+ existingFCurves = {}
+ for fcu in adt.action.fcurves:
+ # get "delta" path - i.e. the final paths which may clash
+ path = fcu.data_path
+ if path in STANDARD_TO_DELTA_PATHS:
+ # to be converted - conflicts may exist...
+ dpath = STANDARD_TO_DELTA_PATHS[path]
+ elif path in DELTA_PATHS:
+ # already delta - check for conflicts...
+ dpath = path
+ else:
+ # non-transform - ignore
+ continue
+
+ # a delta path like this for the same index shouldn't
+ # exist already, otherwise we've got a conflict
+ if dpath in existingFCurves:
+ # ensure that this index hasn't occurred before
+ if fcu.array_index in existingFCurves[dpath]:
+ # conflict
+ self.report({'ERROR'},
+ "Object '%r' already has '%r' F-Curve(s). Remove these before trying again" %
+ (obj.name, dpath))
+ return {'CANCELLED'}
+ else:
+ # no conflict here
+ existingFCurves[dpath] += [fcu.array_index]
+ else:
+ # no conflict yet
+ existingFCurves[dpath] = [fcu.array_index]
+
+
# if F-Curve uses standard transform path
# just append "delta_" to this path
for fcu in adt.action.fcurves:
diff --git a/release/scripts/startup/bl_operators/presets.py b/release/scripts/startup/bl_operators/presets.py
index b7adf53dbf1..ee9769d8b43 100644
--- a/release/scripts/startup/bl_operators/presets.py
+++ b/release/scripts/startup/bl_operators/presets.py
@@ -554,6 +554,12 @@ class WM_MT_operator_presets(Menu):
def draw(self, context):
self.operator = context.active_operator.bl_idname
+
+ # dummy 'default' menu item
+ layout = self.layout
+ layout.operator("wm.operator_defaults")
+ layout.separator()
+
Menu.draw_preset(self, context)
@property
diff --git a/release/scripts/startup/bl_operators/screen_play_rendered_anim.py b/release/scripts/startup/bl_operators/screen_play_rendered_anim.py
index 694412e51d7..6d1f35fe937 100644
--- a/release/scripts/startup/bl_operators/screen_play_rendered_anim.py
+++ b/release/scripts/startup/bl_operators/screen_play_rendered_anim.py
@@ -116,8 +116,12 @@ class PlayRenderedAnim(Operator):
cmd = [player_path]
# extra options, fps controls etc.
if preset in {'BLENDER24', 'INTERNAL'}:
- opts = ["-a", "-f", str(rd.fps), str(rd.fps_base),
- "-j", str(scene.frame_step), file]
+ opts = ["-a",
+ "-f", str(rd.fps), str(rd.fps_base),
+ "-s", str(scene.frame_start),
+ "-e", str(scene.frame_end),
+ "-j", str(scene.frame_step),
+ file]
cmd.extend(opts)
elif preset == 'DJV':
opts = [file, "-playback_speed", "%d" % int(rd.fps / rd.fps_base)]
diff --git a/release/scripts/startup/bl_operators/uvcalc_smart_project.py b/release/scripts/startup/bl_operators/uvcalc_smart_project.py
index 9fa44cac812..eb05057de3d 100644
--- a/release/scripts/startup/bl_operators/uvcalc_smart_project.py
+++ b/release/scripts/startup/bl_operators/uvcalc_smart_project.py
@@ -517,7 +517,7 @@ def mergeUvIslands(islandList):
for uv in f.uv:
uv+= offset
- sourceIsland[0][:] = [] # Empty
+ del sourceIsland[0][:] # Empty
# Move edge loop into new and offset.
@@ -527,7 +527,7 @@ def mergeUvIslands(islandList):
(e[0]+offset, e[1]+offset, e[2])\
) for e in sourceIsland[6] ] )
- sourceIsland[6][:] = [] # Empty
+ del sourceIsland[6][:] # Empty
# Sort by edge length, reverse so biggest are first.
@@ -540,7 +540,7 @@ def mergeUvIslands(islandList):
for p in sourceIsland[7]:
p+= offset
- sourceIsland[7][:] = []
+ del sourceIsland[7][:]
# Decrement the efficiency
diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py
index 2bff11a686d..0945098bd1e 100644
--- a/release/scripts/startup/bl_operators/wm.py
+++ b/release/scripts/startup/bl_operators/wm.py
@@ -41,12 +41,17 @@ class MESH_OT_delete_edgeloop(Operator):
return bpy.ops.transform.edge_slide.poll()
def execute(self, context):
+ mesh = context.object.data
+ use_mirror_x = mesh.use_mirror_x
+ mesh.use_mirror_x = False
if 'FINISHED' in bpy.ops.transform.edge_slide(value=1.0):
bpy.ops.mesh.select_more()
bpy.ops.mesh.remove_doubles()
- return {'FINISHED'}
-
- return {'CANCELLED'}
+ ret = {'FINISHED'}
+ else:
+ ret = {'CANCELLED'}
+ mesh.use_mirror_x = use_mirror_x
+ return ret
rna_path_prop = StringProperty(
name="Context Attributes",
diff --git a/release/scripts/startup/bl_ui/properties_data_armature.py b/release/scripts/startup/bl_ui/properties_data_armature.py
index 50c34be1414..845beb0f862 100644
--- a/release/scripts/startup/bl_ui/properties_data_armature.py
+++ b/release/scripts/startup/bl_ui/properties_data_armature.py
@@ -239,7 +239,7 @@ class DATA_PT_ghost(ArmatureButtonsPanel, Panel):
class DATA_PT_iksolver_itasc(ArmatureButtonsPanel, Panel):
- bl_label = "iTaSC parameters"
+ bl_label = "Inverse Kinematics"
bl_options = {'DEFAULT_CLOSED'}
@classmethod
diff --git a/release/scripts/startup/bl_ui/properties_data_bone.py b/release/scripts/startup/bl_ui/properties_data_bone.py
index 1441c642d51..fdaee6b7cde 100644
--- a/release/scripts/startup/bl_ui/properties_data_bone.py
+++ b/release/scripts/startup/bl_ui/properties_data_bone.py
@@ -244,7 +244,6 @@ class BONE_PT_inverse_kinematics(BoneButtonsPanel, Panel):
pchan = ob.pose.bones[bone.name]
row = layout.row()
- row.prop(ob.pose, "ik_solver")
active = pchan.is_in_ik_chain
diff --git a/release/scripts/startup/bl_ui/properties_data_camera.py b/release/scripts/startup/bl_ui/properties_data_camera.py
index 5f6036c8945..25cecc90c70 100644
--- a/release/scripts/startup/bl_ui/properties_data_camera.py
+++ b/release/scripts/startup/bl_ui/properties_data_camera.py
@@ -142,8 +142,12 @@ class DATA_PT_camera(CameraButtonsPanel, Panel):
if cam.sensor_fit == 'AUTO':
col.prop(cam, "sensor_width", text="Size")
else:
- col.prop(cam, "sensor_width", text="Width")
- col.prop(cam, "sensor_height", text="Height")
+ sub = col.column()
+ sub.active = cam.sensor_fit == 'HORIZONTAL'
+ sub.prop(cam, "sensor_width", text="Width")
+ sub = col.column()
+ sub.active = cam.sensor_fit == 'VERTICAL'
+ sub.prop(cam, "sensor_height", text="Height")
col = split.column(align=True)
col.prop(cam, "sensor_fit", text="")
diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py
index ea8ffbe6c9f..62461d800f6 100644
--- a/release/scripts/startup/bl_ui/properties_data_modifier.py
+++ b/release/scripts/startup/bl_ui/properties_data_modifier.py
@@ -1029,5 +1029,8 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
col.prop(md, "use_y_symmetry")
col.prop(md, "use_z_symmetry")
+ def TRIANGULATE(self, layout, ob, md):
+ layout.prop(md, "use_beauty")
+
if __name__ == "__main__": # only for live edit.
bpy.utils.register_module(__name__)
diff --git a/release/scripts/startup/bl_ui/properties_object_constraint.py b/release/scripts/startup/bl_ui/properties_object_constraint.py
index 3fa63bac13c..eb0929895f8 100644
--- a/release/scripts/startup/bl_ui/properties_object_constraint.py
+++ b/release/scripts/startup/bl_ui/properties_object_constraint.py
@@ -134,7 +134,7 @@ class ConstraintButtonsPanel():
layout.prop(con, "ik_type")
getattr(self, 'IK_' + con.ik_type)(context, layout, con)
else:
- # Legacy IK constraint
+ # Standard IK constraint
self.target_template(layout, con)
layout.prop(con, "pole_target")
@@ -151,17 +151,27 @@ class ConstraintButtonsPanel():
col.prop(con, "iterations")
col.prop(con, "chain_count")
- col.label(text="Weight:")
- col.prop(con, "weight", text="Position", slider=True)
- sub = col.column()
- sub.active = con.use_rotation
- sub.prop(con, "orient_weight", text="Rotation", slider=True)
-
col = split.column()
col.prop(con, "use_tail")
col.prop(con, "use_stretch")
- col.separator()
- col.prop(con, "use_rotation")
+
+ layout.label(text="Weight:")
+
+ split = layout.split()
+ col = split.column()
+ row = col.row(align=True)
+ row.prop(con, "use_location", text="")
+ sub = row.row()
+ sub.active = con.use_location
+ sub.prop(con, "weight", text="Position", slider=True)
+
+ col = split.column()
+ row = col.row(align=True)
+ row.prop(con, "use_rotation", text="")
+ sub = row.row()
+ sub.active = con.use_rotation
+ sub.prop(con, "orient_weight", text="Rotation", slider=True)
+
def IK_COPY_POSE(self, context, layout, con):
self.target_template(layout, con)
diff --git a/release/scripts/startup/bl_ui/space_dopesheet.py b/release/scripts/startup/bl_ui/space_dopesheet.py
index a81553a8257..5535070c1c4 100644
--- a/release/scripts/startup/bl_ui/space_dopesheet.py
+++ b/release/scripts/startup/bl_ui/space_dopesheet.py
@@ -241,9 +241,9 @@ class DOPESHEET_MT_channel(Menu):
layout.operator("anim.channels_delete")
layout.separator()
- layout.operator("anim.channels_setting_toggle")
- layout.operator("anim.channels_setting_enable")
- layout.operator("anim.channels_setting_disable")
+ layout.operator_menu_enum("anim.channels_setting_toggle", "type")
+ layout.operator_menu_enum("anim.channels_setting_enable", "type")
+ layout.operator_menu_enum("anim.channels_setting_disable", "type")
layout.separator()
layout.operator("anim.channels_editable_toggle")
diff --git a/release/scripts/startup/bl_ui/space_graph.py b/release/scripts/startup/bl_ui/space_graph.py
index e89bd78a84f..4cb6538458f 100644
--- a/release/scripts/startup/bl_ui/space_graph.py
+++ b/release/scripts/startup/bl_ui/space_graph.py
@@ -161,9 +161,9 @@ class GRAPH_MT_channel(Menu):
layout.operator("anim.channels_delete")
layout.separator()
- layout.operator("anim.channels_setting_toggle")
- layout.operator("anim.channels_setting_enable")
- layout.operator("anim.channels_setting_disable")
+ layout.operator_menu_enum("anim.channels_setting_toggle", "type")
+ layout.operator_menu_enum("anim.channels_setting_enable", "type")
+ layout.operator_menu_enum("anim.channels_setting_disable", "type")
layout.separator()
layout.operator("anim.channels_editable_toggle")
diff --git a/release/scripts/startup/bl_ui/space_image.py b/release/scripts/startup/bl_ui/space_image.py
index 18eb8f8d9dd..358dc016219 100644
--- a/release/scripts/startup/bl_ui/space_image.py
+++ b/release/scripts/startup/bl_ui/space_image.py
@@ -249,6 +249,7 @@ class IMAGE_MT_uvs_weldalign(Menu):
layout = self.layout
layout.operator("uv.weld") # W, 1
+ layout.operator("uv.remove_doubles")
layout.operator_enum("uv.align", "axis") # W, 2/3/4
diff --git a/release/scripts/startup/bl_ui/space_info.py b/release/scripts/startup/bl_ui/space_info.py
index c0f2d3c361b..662d5526a37 100644
--- a/release/scripts/startup/bl_ui/space_info.py
+++ b/release/scripts/startup/bl_ui/space_info.py
@@ -373,7 +373,7 @@ class INFO_MT_help(Menu):
layout = self.layout
layout.operator("wm.url_open", text="Manual", icon='HELP').url = "http://wiki.blender.org/index.php/Doc:2.6/Manual"
- layout.operator("wm.url_open", text="Release Log", icon='URL').url = "http://www.blender.org/development/release-logs/blender-264"
+ layout.operator("wm.url_open", text="Release Log", icon='URL').url = "http://www.blender.org/development/release-logs/blender-265"
layout.separator()
layout.operator("wm.url_open", text="Blender Website", icon='URL').url = "http://www.blender.org"
diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py
index ad4074d9744..fdfd43157c7 100644
--- a/release/scripts/startup/bl_ui/space_sequencer.py
+++ b/release/scripts/startup/bl_ui/space_sequencer.py
@@ -707,8 +707,6 @@ class SEQUENCER_PT_scene(SequencerButtonsPanel, Panel):
layout.template_ID(strip, "scene")
scene = strip.scene
- if scene:
- layout.prop(scene.render, "use_sequencer")
layout.label(text="Camera Override")
layout.template_ID(strip, "scene_camera")
diff --git a/release/scripts/startup/bl_ui/space_text.py b/release/scripts/startup/bl_ui/space_text.py
index a64f8aa4aed..fa8752c21be 100644
--- a/release/scripts/startup/bl_ui/space_text.py
+++ b/release/scripts/startup/bl_ui/space_text.py
@@ -137,9 +137,6 @@ class TEXT_PT_find(Panel):
row.operator("text.replace_set_selected", text="", icon='TEXT')
col.operator("text.replace")
- # mark
- layout.operator("text.mark_all")
-
# settings
layout.prop(st, "use_match_case")
row = layout.row()
@@ -216,17 +213,6 @@ class TEXT_MT_edit_select(Menu):
layout.operator("text.select_line")
-class TEXT_MT_edit_markers(Menu):
- bl_label = "Markers"
-
- def draw(self, context):
- layout = self.layout
-
- layout.operator("text.markers_clear")
- layout.operator("text.next_marker")
- layout.operator("text.previous_marker")
-
-
class TEXT_MT_format(Menu):
bl_label = "Format"
@@ -290,7 +276,6 @@ class TEXT_MT_edit(Menu):
layout.separator()
layout.menu("TEXT_MT_edit_select")
- layout.menu("TEXT_MT_edit_markers")
layout.separator()
diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py
index de55eaba775..0bb25e98456 100644
--- a/release/scripts/startup/bl_ui/space_userpref.py
+++ b/release/scripts/startup/bl_ui/space_userpref.py
@@ -442,11 +442,9 @@ class USERPREF_PT_system(Panel):
col.label(text="Anisotropic Filtering")
col.prop(system, "anisotropic_filter", text="")
col.prop(system, "use_vertex_buffer_objects")
- # Anti-aliasing is disabled as it breaks border/lasso select
- #~ col.prop(system, "use_antialiasing")
col.label(text="Window Draw Method:")
col.prop(system, "window_draw_method", text="")
- col.prop(system, "ogl_multisamples", text="")
+ col.prop(system, "multi_sample", text="")
col.label(text="Text Draw Options:")
col.prop(system, "use_text_antialiasing")
col.label(text="Textures:")
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index b29f51d90a2..b1dfc397ce0 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -1736,18 +1736,9 @@ class VIEW3D_MT_edit_mesh_select_mode(Menu):
layout = self.layout
layout.operator_context = 'INVOKE_REGION_WIN'
-
- props = layout.operator("wm.context_set_value", text="Vertex", icon='VERTEXSEL')
- props.value = "(True, False, False)"
- props.data_path = "tool_settings.mesh_select_mode"
-
- props = layout.operator("wm.context_set_value", text="Edge", icon='EDGESEL')
- props.value = "(False, True, False)"
- props.data_path = "tool_settings.mesh_select_mode"
-
- props = layout.operator("wm.context_set_value", text="Face", icon='FACESEL')
- props.value = "(False, False, True)"
- props.data_path = "tool_settings.mesh_select_mode"
+ layout.operator("mesh.select_mode", text="Vertex", icon='VERTEXSEL').type = 'VERT'
+ layout.operator("mesh.select_mode", text="Edge", icon='EDGESEL').type = 'EDGE'
+ layout.operator("mesh.select_mode", text="Face", icon='FACESEL').type = 'FACE'
class VIEW3D_MT_edit_mesh_extrude(Menu):
@@ -1847,8 +1838,8 @@ class VIEW3D_MT_edit_mesh_edges(Menu):
layout.separator()
- layout.operator("mesh.edge_rotate", text="Rotate Edge CW").direction = 'CW'
- layout.operator("mesh.edge_rotate", text="Rotate Edge CCW").direction = 'CCW'
+ layout.operator("mesh.edge_rotate", text="Rotate Edge CW").use_ccw = False
+ layout.operator("mesh.edge_rotate", text="Rotate Edge CCW").use_ccw = True
layout.separator()
@@ -1897,13 +1888,13 @@ class VIEW3D_MT_edit_mesh_faces(Menu):
layout.separator()
- layout.operator("mesh.edge_rotate", text="Rotate Edge CW").direction = 'CW'
+ layout.operator("mesh.edge_rotate", text="Rotate Edge CW").use_ccw = False
layout.separator()
- layout.operator_menu_enum("mesh.uvs_rotate", "direction")
+ layout.operator("mesh.uvs_rotate")
layout.operator("mesh.uvs_reverse")
- layout.operator_menu_enum("mesh.colors_rotate", "direction")
+ layout.operator("mesh.colors_rotate")
layout.operator("mesh.colors_reverse")
diff --git a/release/scripts/templates/script_stub.py b/release/scripts/templates/script_stub.py
index 3b3212892d5..143c7c5104a 100644
--- a/release/scripts/templates/script_stub.py
+++ b/release/scripts/templates/script_stub.py
@@ -8,4 +8,5 @@ import os
filename = "my_script.py"
filepath = os.path.join(os.path.dirname(bpy.data.filepath), filename)
-exec(compile(open(filepath).read(), filepath, 'exec'))
+global_namespace = {"__file__": filepath, "__name__": "__main__"}
+exec(compile(open(filepath).read(), filepath, 'exec'), global_namespace)
diff --git a/release/text/readme.html b/release/text/readme.html
index 40ea9035835..414a7d8e744 100644
--- a/release/text/readme.html
+++ b/release/text/readme.html
@@ -12,18 +12,18 @@
</style>
</head>
<body>
-<p class="title"><b>Blender 2.64</b></p>
+<p class="title"><b>Blender 2.65</b></p>
<p><br></p>
<p class="header"><b>About</b></p>
<p class="body">Welcome to Blender, the free, open source 3D application for modeling, animation, rendering, compositing, video editing and game creation. Blender is available for Linux, Mac OS X, Windows and FreeBSD and has a large world-wide community.</p>
<p class="body">Blender can be used freely for any purpose, including commercial use and distribution. It's free and open-source software, released under the GNU GPL licence. The entire source code is available on our website.</p>
<p class="body">For more information, visit <a href="http://www.blender.org">blender.org</a>.</p>
<p><br></p>
-<p class="header"><b>2.64</b></p>
-<p class="body">The Blender Foundation and online developer community is proud to present Blender 2.64. This release is the fifth official stable release of the Blender 2.6 series, in which we will refine the 2.5 series and add exciting new features. <a href="http://www.blender.org/development/release-logs/blender-264/">More information about this release</a>.</p>
+<p class="header"><b>2.65</b></p>
+<p class="body">The Blender Foundation and online developer community is proud to present Blender 2.65. This release is the sixth official stable release of the Blender 2.6 series, in which we will refine the 2.5 series and add exciting new features. <a href="http://www.blender.org/development/release-logs/blender-265/">More information about this release</a>.</p>
<p><br></p>
<p class="header"><b>Bugs</b></p>
-<p class="body">Although Blender 2.64 is considered a stable release, you may encounter a bug. If you do, please help us by posting it in the bug tracker or using Help → Report a Bug from inside Blender. If it wasn’t reported yet, please log in (or register) and fill in detailed information about the error. Please post detailed instructions on how to reproduce it or post a .blend file showcasing the bug.</p>
+<p class="body">Although Blender 2.65 is considered a stable release, you may encounter a bug. If you do, please help us by posting it in the bug tracker or using Help → Report a Bug from inside Blender. If it wasn’t reported yet, please log in (or register) and fill in detailed information about the error. Please post detailed instructions on how to reproduce it or post a .blend file showcasing the bug.</p>
<p><br></p>
<p class="header"><b>Package Contents</b></p>
<p class="body">The downloaded Blender package includes:</p>
@@ -47,7 +47,7 @@
<p class="header"><b>Links</b></p>
<p class="body">Users:</p>
<p class="body"> General information <a href="http://www.blender.org">www.blender.org</a> <br>
- Full release log <a href="http://www.blender.org/development/release-logs/blender-264/">www.blender.org/development/release-logs/blender-264/</a><br>
+ Full release log <a href="http://www.blender.org/development/release-logs/blender-265/">www.blender.org/development/release-logs/blender-265/</a><br>
Tutorials <a href="http://www.blender.org/education-help/">www.blender.org/education-help/</a> <br>
Manual <a href="http://wiki.blender.org/index.php/Doc:2.6/Manual">wiki.blender.org/index.php/Doc:2.6/Manual</a><br>
User Forum <a href="http://www.blenderartists.org">www.blenderartists.org</a><br>
diff --git a/source/blender/avi/intern/avi_rgb.c b/source/blender/avi/intern/avi_rgb.c
index 11d9bdf8612..c6a78eccce2 100644
--- a/source/blender/avi/intern/avi_rgb.c
+++ b/source/blender/avi/intern/avi_rgb.c
@@ -98,7 +98,7 @@ void *avi_converter_from_avi_rgb(AviMovie *movie, int stream, unsigned char *buf
buf = MEM_mallocN(movie->header->Height * movie->header->Width * 3, "fromavirgbbuf");
rowstride = movie->header->Width * 3;
- if (bits != 16) if (movie->header->Width % 2) rowstride++;
+ if ((bits != 16) && (movie->header->Width % 2)) rowstride++;
for (y = 0; y < movie->header->Height; y++) {
memcpy(&buf[y * movie->header->Width * 3], &buffer[((movie->header->Height - 1) - y) * rowstride], movie->header->Width * 3);
diff --git a/source/blender/blenfont/BLF_translation.h b/source/blender/blenfont/BLF_translation.h
index b01ce93cb65..159d4b067b6 100644
--- a/source/blender/blenfont/BLF_translation.h
+++ b/source/blender/blenfont/BLF_translation.h
@@ -35,16 +35,6 @@
#define TEXT_DOMAIN_NAME "blender"
-/* blf_translation.c */
-
-#ifdef WITH_INTERNATIONAL
-unsigned char *BLF_get_unifont(int *unifont_size);
-void BLF_free_unifont(void);
-#endif
-
-const char *BLF_gettext(const char *msgid);
-const char *BLF_pgettext(const char *context, const char *message);
-
/* blf_lang.c */
/* Search the path directory to the locale files, this try all
@@ -61,22 +51,29 @@ void BLF_lang_set(const char *);
/* Get the current locale (short code, e.g. es_ES). */
const char *BLF_lang_get(void);
-/* Set the current encoding name. */
-void BLF_lang_encoding(const char *str);
-
/* Get EnumPropertyItem's for translations menu. */
struct EnumPropertyItem *BLF_RNA_lang_enum_properties(void);
+/* blf_translation.c */
+
+#ifdef WITH_INTERNATIONAL
+unsigned char *BLF_get_unifont(int *unifont_size);
+void BLF_free_unifont(void);
+#endif
+
+const char *BLF_pgettext(const char *msgctxt, const char *msgid);
+
/* translation */
int BLF_translate_iface(void);
int BLF_translate_tooltips(void);
-const char *BLF_translate_do_iface(const char *contex, const char *msgid);
-const char *BLF_translate_do_tooltip(const char *contex, const char *msgid);
+const char *BLF_translate_do_iface(const char *msgctxt, const char *msgid);
+const char *BLF_translate_do_tooltip(const char *msgctxt, const char *msgid);
/* The "translation-marker" macro. */
#define N_(msgid) msgid
#define CTX_N_(context, msgid) msgid
+
/* Those macros should be used everywhere in UI code. */
#ifdef WITH_INTERNATIONAL
/* #define _(msgid) BLF_gettext(msgid) */
@@ -88,10 +85,17 @@ const char *BLF_translate_do_tooltip(const char *contex, const char *msgid);
/* #define _(msgid) msgid */
#define IFACE_(msgid) msgid
#define TIP_(msgid) msgid
- #define CTX_IFACE_(context, msgid) msgid
- #define CTX_TIP_(context, msgid) msgid
+ #define CTX_IFACE_(context, msgid) ((void)context, msgid)
+ #define CTX_TIP_(context, msgid) ((void)context, msgid)
#endif
+/* Helper macro, when we want to define a same msgid for multiple msgctxt...
+ * Does nothing in C, but is "parsed" by our i18n py tools.
+ * XXX Currently limited to at most 16 contexts at most
+ * (but you can call it several times with the same msgid, should you need more contexts!).
+ */
+#define BLF_I18N_MSGID_MULTI_CTXT(msgid, ...)
+
/******************************************************************************
* All i18n contexts must be defined here.
* This is a nice way to be sure not to use a context twice for different
@@ -104,8 +108,39 @@ const char *BLF_translate_do_tooltip(const char *contex, const char *msgid);
/* Default context for operator names/labels. */
#define BLF_I18NCONTEXT_OPERATOR_DEFAULT "Operator"
-/* Audio disambiguation context. */
-#define BLF_I18NCONTEXT_AUDIO "Audio"
-
+/* ID-types contexts. */
+/* WARNING! Keep it in sync with idtypes in blenkernel/intern/idcode.c */
+#define BLF_I18NCONTEXT_ID_ACTION "Action"
+#define BLF_I18NCONTEXT_ID_ARMATURE "Armature"
+#define BLF_I18NCONTEXT_ID_BRUSH "Brush"
+#define BLF_I18NCONTEXT_ID_CAMERA "Camera"
+#define BLF_I18NCONTEXT_ID_CURVE "Curve"
+#define BLF_I18NCONTEXT_ID_GPENCIL "GPencil"
+#define BLF_I18NCONTEXT_ID_GROUP "Group"
+#define BLF_I18NCONTEXT_ID_ID "ID"
+#define BLF_I18NCONTEXT_ID_IMAGE "Image"
+/*#define BLF_I18NCONTEXT_ID_IPO "Ipo"*/ /* Deprecated */
+#define BLF_I18NCONTEXT_ID_SHAPEKEY "Key"
+#define BLF_I18NCONTEXT_ID_LAMP "Lamp"
+#define BLF_I18NCONTEXT_ID_LIBRARY "Library"
+#define BLF_I18NCONTEXT_ID_LATTICE "Lattice"
+#define BLF_I18NCONTEXT_ID_MATERIAL "Material"
+#define BLF_I18NCONTEXT_ID_METABALL "Metaball"
+#define BLF_I18NCONTEXT_ID_MESH "Mesh"
+#define BLF_I18NCONTEXT_ID_NODETREE "NodeTree"
+#define BLF_I18NCONTEXT_ID_OBJECT "Object"
+#define BLF_I18NCONTEXT_ID_PARTICLESETTINGS "ParticleSettings"
+#define BLF_I18NCONTEXT_ID_SCENE "Scene"
+#define BLF_I18NCONTEXT_ID_SCREEN "Screen"
+#define BLF_I18NCONTEXT_ID_SEQUENCE "Sequence"
+#define BLF_I18NCONTEXT_ID_SPEAKER "Speaker"
+#define BLF_I18NCONTEXT_ID_SOUND "Sound"
+#define BLF_I18NCONTEXT_ID_TEXTURE "Texture"
+#define BLF_I18NCONTEXT_ID_TEXT "Text"
+#define BLF_I18NCONTEXT_ID_VFONT "VFont"
+#define BLF_I18NCONTEXT_ID_WORLD "World"
+#define BLF_I18NCONTEXT_ID_WINDOWMANAGER "WindowManager"
+#define BLF_I18NCONTEXT_ID_MOVIECLIP "MovieClip"
+#define BLF_I18NCONTEXT_ID_MASK "Mask"
#endif /* __BLF_TRANSLATION_H__ */
diff --git a/source/blender/blenfont/CMakeLists.txt b/source/blender/blenfont/CMakeLists.txt
index 40d5d6c75f2..6daa879db0f 100644
--- a/source/blender/blenfont/CMakeLists.txt
+++ b/source/blender/blenfont/CMakeLists.txt
@@ -31,6 +31,7 @@ set(INC
../makesrna
../imbuf
../../../intern/guardedalloc
+ ../../../intern/locale
../gpu
)
@@ -55,9 +56,6 @@ set(SRC
)
if(WITH_INTERNATIONAL)
- list(APPEND INC_SYS
- ${GETTEXT_INCLUDE_DIRS}
- )
add_definitions(-DWITH_INTERNATIONAL)
endif()
diff --git a/source/blender/blenfont/SConscript b/source/blender/blenfont/SConscript
index 9971adb885b..aaf5f3c0f08 100644
--- a/source/blender/blenfont/SConscript
+++ b/source/blender/blenfont/SConscript
@@ -4,11 +4,10 @@ Import ('env')
sources = env.Glob('intern/*.c')
-incs = '. intern #/intern/guardedalloc ../blenkernel ../blenlib ../blenloader'
+incs = '. intern #/intern/guardedalloc #/intern/locale ../blenkernel ../blenlib ../blenloader'
incs += ' ../makesdna ../makesrna ../imbuf ../editors/include ../gpu'
incs += ' #/extern/glew/include'
incs += ' ' + env['BF_FREETYPE_INC']
-incs += ' ' + env['BF_GETTEXT_INC']
defs = ['GLEW_STATIC']
diff --git a/source/blender/blenfont/intern/blf.c b/source/blender/blenfont/intern/blf.c
index 27db65f87ac..c77118deb45 100644
--- a/source/blender/blenfont/intern/blf.c
+++ b/source/blender/blenfont/intern/blf.c
@@ -28,7 +28,6 @@
* \ingroup blf
*/
-
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
diff --git a/source/blender/blenfont/intern/blf_lang.c b/source/blender/blenfont/intern/blf_lang.c
index f02d4a25554..0ed48623dd5 100644
--- a/source/blender/blenfont/intern/blf_lang.c
+++ b/source/blender/blenfont/intern/blf_lang.c
@@ -28,20 +28,17 @@
*/
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "BKE_global.h"
-
-#include "BLF_api.h"
#include "BLF_translation.h" /* own include */
#ifdef WITH_INTERNATIONAL
-#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
-#include "libintl.h"
+#include "boost_locale_wrapper.h"
+
+#include "BKE_global.h"
#include "DNA_userdef_types.h"
@@ -49,30 +46,20 @@
#include "MEM_guardedalloc.h"
-#include "BLI_string.h"
-#include "BLI_utildefines.h"
-#include "BLI_path_util.h"
#include "BLI_fileops.h"
#include "BLI_linklist.h"
+#include "BLI_path_util.h"
#include "BLI_string.h"
-
-#define SYSTEM_ENCODING_DEFAULT "UTF-8"
-#define FONT_SIZE_DEFAULT 12
+#include "BLI_utildefines.h"
/* Locale options. */
-static char global_messagepath[1024];
-static char global_language[32];
-static char global_encoding_name[32];
-
static const char **locales = NULL;
-static char **long_locales = NULL; /* XXX Temp fix until we get a final solution with modern intl lib under windows! */
static int num_locales = 0;
static EnumPropertyItem *locales_menu = NULL;
static int num_locales_menu = 0;
#define ULANGUAGE ((U.language >= 0 && U.language < num_locales) ? U.language : 0)
#define LOCALE(_id) (locales ? locales[_id] : "")
-#define LONG_LOCALE(_id) (long_locales ? long_locales[_id] : "")
static void free_locales(void)
{
@@ -84,17 +71,8 @@ static void free_locales(void)
MEM_freeN((void *)locales_menu[idx].description); /* Also frees locales's relevant value! */
}
- idx = num_locales;
- while (idx--) {
- if (long_locales[idx]) {
- MEM_freeN(long_locales[idx]);
- }
- }
-
MEM_freeN(locales);
locales = NULL;
- MEM_freeN(long_locales);
- long_locales = NULL;
}
if (locales_menu) {
MEM_freeN(locales_menu);
@@ -140,7 +118,6 @@ static void fill_locales(void)
/* Do not allocate locales with zero-sized mem, as LOCALE macro uses NULL locales as invalid marker! */
if (num_locales > 0) {
locales = MEM_callocN(num_locales * sizeof(char*), __func__);
- long_locales = MEM_callocN(num_locales * sizeof(char*), __func__);
while (line) {
int id;
char *loc, *sep1, *sep2, *sep3;
@@ -163,26 +140,28 @@ static void fill_locales(void)
sep2++;
sep3 = strchr(sep2, ':');
+
if (sep3) {
locales_menu[idx].identifier = loc = BLI_strdupn(sep2, sep3 - sep2);
+ }
+ else {
+ locales_menu[idx].identifier = loc = BLI_strdup(sep2);
+ }
- if (id == 0) {
- /* The DEFAULT item... */
- if (BLI_strnlen(loc, 2)) {
- locales[id] = locales_menu[idx].description = BLI_strdup("");
- long_locales[id] = BLI_strdup("");
- }
- /* Menu "label", not to be stored in locales! */
- else {
- locales_menu[idx].description = BLI_strdup("");
- }
+ if (id == 0) {
+ /* The DEFAULT item... */
+ if (BLI_strnlen(loc, 2)) {
+ locales[id] = locales_menu[idx].description = BLI_strdup("");
}
+ /* Menu "label", not to be stored in locales! */
else {
- locales[id] = locales_menu[idx].description = BLI_strdup(loc);
- long_locales[id] = BLI_strdup(sep3 + 1);
+ locales_menu[idx].description = BLI_strdup("");
}
- idx++;
}
+ else {
+ locales[id] = locales_menu[idx].description = BLI_strdup(loc);
+ }
+ idx++;
}
}
@@ -207,15 +186,12 @@ void BLF_lang_init(void)
{
char *messagepath = BLI_get_folder(BLENDER_DATAFILES, "locale");
- BLI_strncpy(global_encoding_name, SYSTEM_ENCODING_DEFAULT, sizeof(global_encoding_name));
-
if (messagepath) {
- BLI_strncpy(global_messagepath, messagepath, sizeof(global_messagepath));
+ bl_locale_init(messagepath, TEXT_DOMAIN_NAME);
fill_locales();
}
else {
printf("%s: 'locale' data path for translations not found, continuing\n", __func__);
- global_messagepath[0] = '\0';
}
}
@@ -224,159 +200,37 @@ void BLF_lang_free(void)
free_locales();
}
-/* Get LANG/LANGUAGE environment variable. */
-static void get_language_variable(const char *varname, char *var, const size_t maxlen)
-{
- char *env = getenv(varname);
-
- if (env) {
- char *s;
-
- /* Store defaul locale. */
- BLI_strncpy(var, env, maxlen);
-
- /* Use first language as default. */
- s = strchr(var, ':');
- if (s)
- s[0] = 0;
- }
-}
-
-/* Get language to be used based on locale (which might be empty when using default language) and
- * LANG environment variable.
- */
-static void get_language(const char *locale, const char *lang, char *language, const size_t maxlen)
-{
- if (locale[0]) {
- BLI_strncpy(language, locale, maxlen);
- }
- else {
- char *s;
-
- BLI_strncpy(language, lang, maxlen);
-
- s = strchr(language, '.');
- if (s)
- s[0] = 0;
- }
-}
-
-/* XXX WARNING!!! In osx somehow the previous function call jumps in this one??? (ton, ppc) */
void BLF_lang_set(const char *str)
{
- char *locreturn;
- int ok = TRUE;
int ulang = ULANGUAGE;
+ const char *short_locale = str ? str : LOCALE(ulang);
+ const char *short_locale_utf8 = NULL;
if ((U.transopts & USER_DOTRANSLATE) == 0)
return;
-#if defined(_WIN32) && !defined(FREE_WINDOWS)
- {
- const char *long_locale = str ? str : LONG_LOCALE(ulang);
- if (long_locale) {
- char *envStr;
-
- if (ulang)
- envStr = BLI_sprintfN("LANG=%s", long_locale);
- else /* Use system setting. */
- envStr = BLI_sprintfN("LANG=%s", getenv("LANG"));
-
- gettext_putenv(envStr);
- MEM_freeN(envStr);
- }
-
- locreturn = setlocale(LC_ALL, long_locale);
-
- if (locreturn == NULL) {
- if (G.debug & G_DEBUG)
- printf("Could not change locale to %s\n", long_locale);
-
- ok = FALSE;
- }
- }
-#else
- {
- const char *short_locale = str ? str : LOCALE(ulang);
- static char default_lang[64] = "\0";
- static char default_language[64] = "\0";
-
- if (default_lang[0] == 0)
- get_language_variable("LANG", default_lang, sizeof(default_lang));
-
- if (default_language[0] == 0)
- get_language_variable("LANGUAGE", default_language, sizeof(default_language));
-
- if (short_locale[0]) {
- char *short_locale_utf8 = BLI_sprintfN("%s.UTF-8", short_locale);
-
- if (G.debug & G_DEBUG)
- printf("Setting LANG and LANGUAGE to %s\n", short_locale_utf8);
-
- locreturn = setlocale(LC_ALL, short_locale_utf8);
-
- if (locreturn != NULL) {
- BLI_setenv("LANG", short_locale_utf8);
- BLI_setenv("LANGUAGE", short_locale_utf8);
- }
- else {
- if (G.debug & G_DEBUG)
- printf("Setting LANG and LANGUAGE to %s\n", short_locale);
-
- locreturn = setlocale(LC_ALL, short_locale);
-
- if (locreturn != NULL) {
- BLI_setenv("LANG", short_locale);
- BLI_setenv("LANGUAGE", short_locale);
- }
- }
-
- if (G.debug & G_DEBUG && locreturn == NULL)
- printf("Could not change locale to %s nor %s\n", short_locale, short_locale_utf8);
-
- MEM_freeN(short_locale_utf8);
+ /* We want to avoid locales like '.UTF-8'! */
+ if (short_locale[0]) {
+ /* Hurrey! encoding needs to be placed *before* variant! */
+ char *variant = strchr(short_locale, '@');
+ if (variant) {
+ char *locale = BLI_strdupn(short_locale, variant - short_locale);
+ short_locale_utf8 = BLI_sprintfN("%s.UTF-8%s", locale, variant);
+ MEM_freeN(locale);
}
else {
- if (G.debug & G_DEBUG)
- printf("Setting LANG=%s and LANGUAGE=%s\n", default_lang, default_language);
-
- BLI_setenv("LANG", default_lang);
- BLI_setenv("LANGUAGE", default_language);
- locreturn = setlocale(LC_ALL, "");
-
- if (G.debug & G_DEBUG && locreturn == NULL)
- printf("Could not reset locale\n");
- }
-
- if (locreturn == NULL) {
- char language[65];
-
- get_language(short_locale, default_lang, language, sizeof(language));
-
- if (G.debug & G_DEBUG)
- printf("Fallback to LANG=%s and LANGUAGE=%s\n", default_lang, language);
-
- /* Fallback to default settings. */
- BLI_setenv("LANG", default_lang);
- BLI_setenv("LANGUAGE", language);
-
- locreturn = setlocale(LC_ALL, "");
-
- ok = FALSE;
+ short_locale_utf8 = BLI_sprintfN("%s.UTF-8", short_locale);
}
}
-#endif
-
- if (ok) {
- /*printf("Change locale to %s\n", locreturn ); */
- BLI_strncpy(global_language, locreturn, sizeof(global_language));
+ else {
+ short_locale_utf8 = short_locale;
}
- setlocale(LC_NUMERIC, "C");
+ bl_locale_set(short_locale_utf8);
- textdomain(TEXT_DOMAIN_NAME);
- bindtextdomain(TEXT_DOMAIN_NAME, global_messagepath);
- bind_textdomain_codeset(TEXT_DOMAIN_NAME, global_encoding_name);
+ if (short_locale[0]) {
+ MEM_freeN((void*)short_locale_utf8);
+ }
}
const char *BLF_lang_get(void)
@@ -385,12 +239,6 @@ const char *BLF_lang_get(void)
return LOCALE(uilang);
}
-void BLF_lang_encoding(const char *str)
-{
- BLI_strncpy(global_encoding_name, str, sizeof(global_encoding_name));
- /* bind_textdomain_codeset(TEXT_DOMAIN_NAME, encoding_name); */
-}
-
#undef LOCALE
#undef ULANGUAGE
@@ -406,12 +254,6 @@ void BLF_lang_free(void)
return;
}
-void BLF_lang_encoding(const char *str)
-{
- (void)str;
- return;
-}
-
void BLF_lang_set(const char *str)
{
(void)str;
diff --git a/source/blender/blenfont/intern/blf_translation.c b/source/blender/blenfont/intern/blf_translation.c
index 9c863da9eba..5d4b631688a 100644
--- a/source/blender/blenfont/intern/blf_translation.c
+++ b/source/blender/blenfont/intern/blf_translation.c
@@ -31,18 +31,11 @@
#include <stdlib.h>
#include <string.h>
-#ifdef WITH_INTERNATIONAL
-#include <libintl.h>
-#include <locale.h>
-
-#define GETTEXT_CONTEXT_GLUE "\004"
+#include "BLF_translation.h"
-/* needed for windows version of gettext */
-#ifndef LC_MESSAGES
-# define LC_MESSAGES 1729
-#endif
+#ifdef WITH_INTERNATIONAL
-#endif
+#include "boost_locale_wrapper.h"
#include "MEM_guardedalloc.h"
@@ -52,11 +45,8 @@
#include "BLI_path_util.h"
#include "BLI_fileops.h"
-#include "BLF_translation.h"
-
#include "DNA_userdef_types.h" /* For user settings. */
-#ifdef WITH_INTERNATIONAL
static const char unifont_filename[] = "droidsans.ttf.gz";
static unsigned char *unifont_ttf = NULL;
static int unifont_size = 0;
@@ -90,55 +80,19 @@ void BLF_free_unifont(void)
#endif
-const char *BLF_gettext(const char *msgid)
+const char *BLF_pgettext(const char *msgctxt, const char *msgid)
{
#ifdef WITH_INTERNATIONAL
- if (msgid && msgid[0])
- return gettext(msgid);
+ if (msgid && msgid[0]) {
+ return bl_locale_pgettext(msgctxt, msgid);
+ }
return "";
#else
+ (void)msgctxt;
return msgid;
#endif
}
-const char *BLF_pgettext(const char *context, const char *message)
-{
-#ifdef WITH_INTERNATIONAL
- char static_msg_ctxt_id[1024];
- char *dynamic_msg_ctxt_id = NULL;
- char *msg_ctxt_id;
- const char *translation;
-
- size_t overall_length = strlen(context) + strlen(message) + sizeof(GETTEXT_CONTEXT_GLUE) + 1;
-
- if (!message || !context || !message[0])
- return "";
-
- if (overall_length > sizeof(static_msg_ctxt_id)) {
- dynamic_msg_ctxt_id = malloc(overall_length);
- msg_ctxt_id = dynamic_msg_ctxt_id;
- }
- else {
- msg_ctxt_id = static_msg_ctxt_id;
- }
-
- sprintf(msg_ctxt_id, "%s%s%s", context, GETTEXT_CONTEXT_GLUE, message);
-
- translation = (char *)dcgettext(TEXT_DOMAIN_NAME, msg_ctxt_id, LC_MESSAGES);
-
- if (dynamic_msg_ctxt_id)
- free(dynamic_msg_ctxt_id);
-
- if (translation == msg_ctxt_id)
- translation = message;
-
- return translation;
-#else
- (void)context;
- return message;
-#endif
-}
-
int BLF_translate_iface(void)
{
#ifdef WITH_INTERNATIONAL
@@ -157,36 +111,32 @@ int BLF_translate_tooltips(void)
#endif
}
-const char *BLF_translate_do_iface(const char *context, const char *msgid)
+const char *BLF_translate_do_iface(const char *msgctxt, const char *msgid)
{
#ifdef WITH_INTERNATIONAL
if (BLF_translate_iface()) {
- if (context)
- return BLF_pgettext(context, msgid);
- else
- return BLF_gettext(msgid);
+ return BLF_pgettext(msgctxt, msgid);
}
- else
+ else {
return msgid;
+ }
#else
- (void)context;
+ (void)msgctxt;
return msgid;
#endif
}
-const char *BLF_translate_do_tooltip(const char *context, const char *msgid)
+const char *BLF_translate_do_tooltip(const char *msgctxt, const char *msgid)
{
#ifdef WITH_INTERNATIONAL
if (BLF_translate_tooltips()) {
- if (context)
- return BLF_pgettext(context, msgid);
- else
- return BLF_gettext(msgid);
+ return BLF_pgettext(msgctxt, msgid);
}
- else
+ else {
return msgid;
+ }
#else
- (void)context;
+ (void)msgctxt;
return msgid;
#endif
}
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h
index 7733a59b810..32b2274692c 100644
--- a/source/blender/blenkernel/BKE_DerivedMesh.h
+++ b/source/blender/blenkernel/BKE_DerivedMesh.h
@@ -75,6 +75,8 @@
#include "BKE_customdata.h"
#include "BKE_bvhutils.h"
+#include "BLI_utildefines.h"
+
struct CCGElem;
struct CCGKey;
struct MVert;
diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h
index 1875fd66628..1f9630d9fce 100644
--- a/source/blender/blenkernel/BKE_image.h
+++ b/source/blender/blenkernel/BKE_image.h
@@ -48,6 +48,9 @@ struct Main;
#define IMA_MAX_SPACE 64
+void BKE_images_init(void);
+void BKE_images_exit(void);
+
/* call from library */
void BKE_image_free(struct Image *me);
@@ -133,14 +136,13 @@ enum {
#define IMA_CHAN_FLAG_RGB 2
#define IMA_CHAN_FLAG_ALPHA 4
-/* depending Image type, and (optional) ImageUser setting it returns ibuf */
-/* always call to make signals work */
-struct ImBuf *BKE_image_get_ibuf(struct Image *ima, struct ImageUser *iuser);
+/* checks whether there's an image buffer for given image and user */
+int BKE_image_has_ibuf(struct Image *ima, struct ImageUser *iuser);
/* same as above, but can be used to retrieve images being rendered in
* a thread safe way, always call both acquire and release */
struct ImBuf *BKE_image_acquire_ibuf(struct Image *ima, struct ImageUser *iuser, void **lock_r);
-void BKE_image_release_ibuf(struct Image *ima, void *lock);
+void BKE_image_release_ibuf(struct Image *ima, struct ImBuf *ibuf, void *lock);
/* returns a new image or NULL if it can't load */
struct Image *BKE_image_load(const char *filepath);
diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h
index 7ee1c85d0de..2fa78b30835 100644
--- a/source/blender/blenkernel/BKE_modifier.h
+++ b/source/blender/blenkernel/BKE_modifier.h
@@ -319,8 +319,8 @@ int modifier_dependsOnTime(struct ModifierData *md);
int modifier_supportsMapping(struct ModifierData *md);
int modifier_couldBeCage(struct Scene *scene, struct ModifierData *md);
int modifier_isCorrectableDeformed(struct ModifierData *md);
-int modifier_sameTopology(ModifierData *md);
-int modifier_nonGeometrical(ModifierData *md);
+int modifier_isSameTopology(ModifierData *md);
+int modifier_isNonGeometrical(ModifierData *md);
int modifier_isEnabled(struct Scene *scene, struct ModifierData *md, int required_mode);
void modifier_setError(struct ModifierData *md, const char *format, ...)
#ifdef __GNUC__
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index b365d93b246..65610b5c989 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -706,6 +706,8 @@ void ntreeGPUMaterialNodes(struct bNodeTree *ntree, struct GPUMateria
#define CMP_NODE_SWITCH 317
#define CMP_NODE_PIXELATE 318
+#define CMP_NODE_MAP_RANGE 319
+
/* channel toggles */
#define CMP_CHAN_RGB 1
#define CMP_CHAN_A 2
diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h
index ba611817c8f..88294cb30b6 100644
--- a/source/blender/blenkernel/BKE_sequencer.h
+++ b/source/blender/blenkernel/BKE_sequencer.h
@@ -248,7 +248,7 @@ void BKE_sequencer_cache_cleanup(void);
struct ImBuf *BKE_sequencer_cache_get(SeqRenderData context, struct Sequence *seq, float cfra, seq_stripelem_ibuf_t type);
/* passed ImBuf is properly refed, so ownership is *not*
- * transfered to the cache.
+ * transferred to the cache.
* you can pass the same ImBuf multiple times to the cache without problems.
*/
diff --git a/source/blender/blenkernel/BKE_text.h b/source/blender/blenkernel/BKE_text.h
index 875903f2e20..accac8694a9 100644
--- a/source/blender/blenkernel/BKE_text.h
+++ b/source/blender/blenkernel/BKE_text.h
@@ -83,7 +83,7 @@ void txt_sel_line (struct Text *text);
char* txt_sel_to_buf (struct Text *text);
void txt_insert_buf (struct Text *text, const char *in_buffer);
void txt_print_undo (struct Text *text);
-void txt_undo_add_toop (struct Text *text, int op, unsigned int froml, unsigned short fromc, unsigned int tol, unsigned short toc);
+void txt_undo_add_op (struct Text *text, int op);
void txt_do_undo (struct Text *text);
void txt_do_redo (struct Text *text);
void txt_split_curline (struct Text *text);
@@ -100,14 +100,6 @@ void txt_move_lines (struct Text *text, const int direction);
void txt_duplicate_line (struct Text *text);
int setcurr_tab_spaces (struct Text *text, int space);
-void txt_add_marker (struct Text *text, struct TextLine *line, int start, int end, const unsigned char color[4], int group, int flags);
-short txt_clear_marker_region (struct Text *text, struct TextLine *line, int start, int end, int group, int flags);
-short txt_clear_markers (struct Text *text, int group, int flags);
-struct TextMarker *txt_find_marker (struct Text *text, struct TextLine *line, int curs, int group, int flags);
-struct TextMarker *txt_find_marker_region (struct Text *text, struct TextLine *line, int start, int end, int group, int flags);
-struct TextMarker *txt_prev_marker (struct Text *text, struct TextMarker *marker);
-struct TextMarker *txt_next_marker (struct Text *text, struct TextMarker *marker);
-
/* utility functions, could be moved somewhere more generic but are python/text related */
int text_check_bracket(const char ch);
int text_check_delim(const char ch);
@@ -123,24 +115,6 @@ enum {
/* Undo opcodes */
-/* Simple main cursor movement */
-#define UNDO_CLEFT 001
-#define UNDO_CRIGHT 002
-#define UNDO_CUP 003
-#define UNDO_CDOWN 004
-
-/* Simple selection cursor movement */
-#define UNDO_SLEFT 005
-#define UNDO_SRIGHT 006
-#define UNDO_SUP 007
-#define UNDO_SDOWN 010
-
-/* Complex movement (opcode is followed
- * by 4 character line ID + a 2 character
- * position ID and opcode (repeat)) */
-#define UNDO_CTO 011
-#define UNDO_STO 012
-
/* Complex editing */
/* 1 - opcode is followed by 1 byte for ascii character and opcode (repeat)) */
/* 2 - opcode is followed by 2 bytes for utf-8 character and opcode (repeat)) */
@@ -169,8 +143,6 @@ enum {
#define UNDO_IBLOCK 030 /* Insert block */
/* Misc */
-#define UNDO_SWAP 031 /* Swap cursors */
-
#define UNDO_INDENT 032
#define UNDO_UNINDENT 033
#define UNDO_COMMENT 034
@@ -181,10 +153,6 @@ enum {
#define UNDO_DUPLICATE 040
-/* Marker flags */
-#define TMARK_TEMP 0x01 /* Remove on non-editing events, don't save */
-#define TMARK_EDITALL 0x02 /* Edit all markers of the same group as one */
-
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/SConscript b/source/blender/blenkernel/SConscript
index f7b8f59fa57..db06f4104a4 100644
--- a/source/blender/blenkernel/SConscript
+++ b/source/blender/blenkernel/SConscript
@@ -4,6 +4,7 @@ import os
sources = env.Glob('intern/*.c')
sources.remove('intern' + os.sep + 'mask_rasterize.c')
+sources.remove('intern' + os.sep + 'mask_evaluate.c')
sources.remove('intern' + os.sep + 'mask.c')
sources_mask = env.Glob('intern/mask*.c')
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index b329a502c42..db8fb288d87 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -2166,6 +2166,8 @@ static void mesh_build_data(Scene *scene, Object *ob, CustomDataMask dataMask,
/* weight paint and face select need original indices because of selection buffer drawing */
int needMapping = (ob == obact) && (editing || (ob->mode & (OB_MODE_WEIGHT_PAINT | OB_MODE_VERTEX_PAINT | OB_MODE_TEXTURE_PAINT)));
+ BLI_assert(ob->type == OB_MESH);
+
clear_mesh_caches(ob);
mesh_calc_modifiers(scene, ob, NULL, &ob->derivedDeform,
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index e95451252d0..dd27cc70ba3 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -512,7 +512,7 @@ const char *BKE_pose_ikparam_get_name(bPose *pose)
{
if (pose) {
switch (pose->iksolver) {
- case IKSOLVER_LEGACY:
+ case IKSOLVER_STANDARD:
return NULL;
case IKSOLVER_ITASC:
return "bItasc";
@@ -587,7 +587,7 @@ void BKE_pose_ikparam_init(bPose *pose)
BKE_pose_itasc_init(itasc);
pose->ikparam = itasc;
break;
- case IKSOLVER_LEGACY:
+ case IKSOLVER_STANDARD:
default:
pose->ikparam = NULL;
break;
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index b3cbc1f2b16..1970df54339 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -1822,8 +1822,15 @@ static void splineik_init_tree_from_pchan(Scene *scene, Object *UNUSED(ob), bPos
*/
/* only happens on reload file, but violates depsgraph still... fix! */
- if ((cu->path == NULL) || (cu->path->data == NULL))
+ if (ELEM(NULL, cu->path, cu->path->data)) {
BKE_displist_make_curveTypes(scene, ikData->tar, 0);
+
+ /* path building may fail in EditMode after removing verts [#33268]*/
+ if (ELEM(NULL, cu->path, cu->path->data)) {
+ /* BLI_assert(cu->path != NULL); */
+ return;
+ }
+ }
}
/* find the root bone and the chain of bones from the root to the tip
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index e1e868b234e..40cd5b3d403 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -70,6 +70,7 @@
#include "BKE_displist.h"
#include "BKE_global.h"
#include "BKE_idprop.h"
+#include "BKE_image.h"
#include "BKE_ipo.h"
#include "BKE_library.h"
#include "BKE_main.h"
@@ -113,6 +114,7 @@ void free_blender(void)
BKE_spacetypes_free(); /* after free main, it uses space callbacks */
IMB_exit();
+ BKE_images_exit();
BLI_callback_global_finalize();
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index 98b206712d6..f310895f590 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -1287,8 +1287,6 @@ unsigned int *BKE_brush_gen_texture_cache(Brush *br, int half_side)
texcache = MEM_callocN(sizeof(int) * side * side, "Brush texture cache");
- BKE_image_get_ibuf(mtex->tex->ima, NULL);
-
/*do normalized cannonical view coords for texture*/
for (y = -1.0, iy = 0; iy < side; iy++, y += step) {
for (x = -1.0, ix = 0; ix < side; ix++, x += step) {
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index b7ad135fa72..7ac046c092f 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -2408,6 +2408,11 @@ void CDDM_calc_normals_tessface(DerivedMesh *dm)
* this is a really horribly written function. ger. - joeedh
*
* note, CDDM_recalc_tessellation has to run on the returned DM if you want to access tessfaces.
+ *
+ * Note: This function is currently only used by the Mirror modifier, so it
+ * skips any faces that have all vertices merged (to avoid creating pairs
+ * of faces sharing the same set of vertices). If used elsewhere, it may
+ * be necessary to make this functionality optional.
*/
DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap)
{
@@ -2451,14 +2456,11 @@ DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap)
newv[i] = newv[vtargetmap[i]];
}
}
-
- /* find-replace merged vertices with target vertices */
- ml = cddm->mloop;
- for (i = 0; i < totloop; i++, ml++) {
- if (vtargetmap[ml->v] != -1) {
- ml->v = vtargetmap[ml->v];
- }
- }
+
+ /* Don't remap vertices in cddm->mloop, because we need to know the original
+ * indices in order to skip faces with all vertices merged.
+ * The "update loop indices..." section further down remaps vertices in mloop.
+ */
/* now go through and fix edges and faces */
med = cddm->medge;
@@ -2492,6 +2494,24 @@ DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap)
ml = cddm->mloop + mp->loopstart;
+ /* skip faces with all vertices merged */
+ {
+ int all_vertices_merged = TRUE;
+
+ for (j = 0; j < mp->totloop; j++, ml++) {
+ if (vtargetmap[ml->v] == -1) {
+ all_vertices_merged = FALSE;
+ break;
+ }
+ }
+
+ if (UNLIKELY(all_vertices_merged)) {
+ continue;
+ }
+ }
+
+ ml = cddm->mloop + mp->loopstart;
+
c = 0;
for (j = 0; j < mp->totloop; j++, ml++) {
med = cddm->medge + ml->e;
@@ -2650,7 +2670,7 @@ void CDDM_calc_edges(DerivedMesh *dm)
EdgeHashIterator *ehi;
MPoly *mp = cddm->mpoly;
MLoop *ml;
- MEdge *med;
+ MEdge *med, *origmed;
EdgeHash *eh = BLI_edgehash_new();
int v1, v2;
int *eindex;
@@ -2683,6 +2703,7 @@ void CDDM_calc_edges(DerivedMesh *dm)
CustomData_add_layer(&edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
CustomData_add_layer(&edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
+ origmed = cddm->medge;
med = CustomData_get_layer(&edgeData, CD_MEDGE);
index = CustomData_get_layer(&edgeData, CD_ORIGINDEX);
@@ -2693,8 +2714,14 @@ void CDDM_calc_edges(DerivedMesh *dm)
BLI_edgehashIterator_getKey(ehi, &med->v1, &med->v2);
j = GET_INT_FROM_POINTER(BLI_edgehashIterator_getValue(ehi));
- med->flag = ME_EDGEDRAW | ME_EDGERENDER;
- *index = j == 0 ? ORIGINDEX_NONE : eindex[j - 1];
+ if (j == 0) {
+ med->flag = ME_EDGEDRAW | ME_EDGERENDER;
+ *index = ORIGINDEX_NONE;
+ }
+ else {
+ med->flag = ME_EDGEDRAW | ME_EDGERENDER | origmed[j - 1].flag;
+ *index = eindex[j - 1];
+ }
BLI_edgehashIterator_setValue(ehi, SET_INT_IN_POINTER(i));
}
diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c
index b488e683947..4641a02265a 100644
--- a/source/blender/blenkernel/intern/collision.c
+++ b/source/blender/blenkernel/intern/collision.c
@@ -198,8 +198,10 @@ static void collision_compute_barycentric ( float pv[3], float p1[3], float p2[3
w3[0] = 1.0f - w1[0] - w2[0];
}
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wdouble-promotion"
+#ifdef __GNUC__
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wdouble-promotion"
+#endif
DO_INLINE void collision_interpolateOnTriangle ( float to[3], float v1[3], float v2[3], float v3[3], double w1, double w2, double w3 )
{
@@ -371,7 +373,9 @@ static int cloth_collision_response_static ( ClothModifierData *clmd, CollisionM
return result;
}
-#pragma GCC diagnostic pop
+#ifdef __GNUC__
+# pragma GCC diagnostic pop
+#endif
//Determines collisions on overlap, collisions are written to collpair[i] and collision+number_collision_found is returned
static CollPair* cloth_collision(ModifierData *md1, ModifierData *md2,
diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c
index 75276adf518..529fe07cab3 100644
--- a/source/blender/blenkernel/intern/colortools.c
+++ b/source/blender/blenkernel/intern/colortools.c
@@ -1008,8 +1008,8 @@ void scopes_update(Scopes *scopes, ImBuf *ibuf, const ColorManagedViewSettings *
const ColorManagedDisplaySettings *display_settings)
{
int x, y, c;
- unsigned int n, nl;
- double div, divl;
+ unsigned int nl, na, nr, ng, nb;
+ double divl, diva, divr, divg, divb;
float *rf = NULL;
unsigned char *rc = NULL;
unsigned int *bin_lum, *bin_r, *bin_g, *bin_b, *bin_a;
@@ -1149,24 +1149,37 @@ void scopes_update(Scopes *scopes, ImBuf *ibuf, const ColorManagedViewSettings *
savedlines += 1;
}
+ /* test for nicer distribution even - non standard, leave it out for a while */
+#if 0
+ for (x = 0; x < 256; x++) {
+ bin_lum[x] = sqrt (bin_lum[x]);
+ bin_r[x] = sqrt(bin_r[x]);
+ bin_g[x] = sqrt(bin_g[x]);
+ bin_b[x] = sqrt(bin_b[x]);
+ bin_a[x] = sqrt(bin_a[x]);
+ }
+#endif
+
/* convert hist data to float (proportional to max count) */
- n = 0;
- nl = 0;
+ nl = na = nr = nb = ng = 0;
for (x = 0; x < 256; x++) {
if (bin_lum[x] > nl) nl = bin_lum[x];
- if (bin_r[x] > n) n = bin_r[x];
- if (bin_g[x] > n) n = bin_g[x];
- if (bin_b[x] > n) n = bin_b[x];
- if (bin_a[x] > n) n = bin_a[x];
+ if (bin_r[x] > nr) nr = bin_r[x];
+ if (bin_g[x] > ng) ng = bin_g[x];
+ if (bin_b[x] > nb) nb = bin_b[x];
+ if (bin_a[x] > na) na = bin_a[x];
}
- div = 1.0 / (double)n;
divl = 1.0 / (double)nl;
+ diva = 1.0 / (double)na;
+ divr = 1.0 / (double)nr;
+ divg = 1.0 / (double)ng;
+ divb = 1.0 / (double)nb;
for (x = 0; x < 256; x++) {
scopes->hist.data_luma[x] = bin_lum[x] * divl;
- scopes->hist.data_r[x] = bin_r[x] * div;
- scopes->hist.data_g[x] = bin_g[x] * div;
- scopes->hist.data_b[x] = bin_b[x] * div;
- scopes->hist.data_a[x] = bin_a[x] * div;
+ scopes->hist.data_r[x] = bin_r[x] * divr;
+ scopes->hist.data_g[x] = bin_g[x] * divg;
+ scopes->hist.data_b[x] = bin_b[x] * divb;
+ scopes->hist.data_a[x] = bin_a[x] * diva;
}
MEM_freeN(bin_lum);
MEM_freeN(bin_r);
diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c
index 719ae7357b4..ffb93139358 100644
--- a/source/blender/blenkernel/intern/context.c
+++ b/source/blender/blenkernel/intern/context.c
@@ -44,6 +44,7 @@
#include "BLI_listbase.h"
#include "BLI_string.h"
+#include "BLI_threads.h"
#include "BLI_utildefines.h"
#include "BKE_context.h"
@@ -245,6 +246,10 @@ static void *ctx_wm_python_context_get(const bContext *C, const char *member, vo
(void)C, (void)member;
#endif
+ /* don't allow UI context access from non-main threads */
+ if (!BLI_thread_is_main())
+ return NULL;
+
return fall_through;
}
@@ -264,6 +269,11 @@ static int ctx_data_get(bContext *C, const char *member, bContextDataResult *res
// return 1;
}
#endif
+
+ /* don't allow UI context access from non-main threads */
+ if (!BLI_thread_is_main())
+ return done;
+
/* we check recursion to ensure that we do not get infinite
* loops requesting data from ourselfs in a context callback */
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index f2cd695d64a..754a4fbc0c8 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -1116,7 +1116,7 @@ void BKE_nurb_makeCurve(Nurb *nu, float *coord_array, float *tilt_array, float *
*fp = basisu[i] * bp->vec[3];
sumdiv += *fp;
}
- if (sumdiv != 0.0f) if (sumdiv < 0.999f || sumdiv > 1.001f) {
+ if ((sumdiv != 0.0f) && (sumdiv < 0.999f || sumdiv > 1.001f)) {
/* is normalizing needed? */
fp = sum;
for (i = istart; i <= iend; i++, fp++) {
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index 93c776ae30e..b2f8db0dcce 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -761,7 +761,7 @@ static void layerDoMinMax_mloopuv(void *data, void *vmin, void *vmax)
{
MLoopUV *min = vmin, *max = vmax, *luv = data;
- DO_MINMAX2(luv->uv, min->uv, max->uv);
+ minmax_v2v2_v2(min->uv, max->uv, luv->uv);
}
static void layerAdd_mloopuv(void *data1, void *data2)
@@ -833,7 +833,7 @@ static void layerDoMinMax_mloop_origspace(void *data, void *vmin, void *vmax)
{
OrigSpaceLoop *min = vmin, *max = vmax, *luv = data;
- DO_MINMAX2(luv->uv, min->uv, max->uv);
+ minmax_v2v2_v2(min->uv, max->uv, luv->uv);
}
static void layerAdd_mloop_origspace(void *data1, void *data2)
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index 9d3a7ec57cf..d23a608d31f 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -671,8 +671,9 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O
}
}
}
- else if(ob->type == OB_LAMP)
+ else if (ob->type == OB_LAMP) {
dag_add_lamp_driver_relations(dag, node, ob->data);
+ }
/* particles */
psys = ob->particlesystem.first;
diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c
index 89d728c0419..bb3836e3c08 100644
--- a/source/blender/blenkernel/intern/dynamicpaint.c
+++ b/source/blender/blenkernel/intern/dynamicpaint.c
@@ -86,11 +86,13 @@
#include "RE_shader_ext.h"
#ifdef _OPENMP
-#include <omp.h>
+# include <omp.h>
#endif
/* could enable at some point but for now there are far too many conversions */
-#pragma GCC diagnostic ignored "-Wdouble-promotion"
+#ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wdouble-promotion"
+#endif
/* precalculated gaussian factors for 5x super sampling */
static float gaussianFactors[5] = {0.996849f,
diff --git a/source/blender/blenkernel/intern/idcode.c b/source/blender/blenkernel/intern/idcode.c
index 30427a81c4b..c3008d17bd1 100644
--- a/source/blender/blenkernel/intern/idcode.c
+++ b/source/blender/blenkernel/intern/idcode.c
@@ -47,39 +47,40 @@ typedef struct {
} IDType;
/* plural need to match rna_main.c's MainCollectionDef */
+/* WARNING! Keep it in sync with i18n contexts in BLF_translation.h */
static IDType idtypes[] = {
- { ID_AC, "Action", "actions", IDTYPE_FLAGS_ISLINKABLE},
- { ID_AR, "Armature", "armatures", IDTYPE_FLAGS_ISLINKABLE},
- { ID_BR, "Brush", "brushes", IDTYPE_FLAGS_ISLINKABLE},
- { ID_CA, "Camera", "cameras", IDTYPE_FLAGS_ISLINKABLE},
- { ID_CU, "Curve", "curves", IDTYPE_FLAGS_ISLINKABLE},
- { ID_GD, "GPencil", "grease_pencil", IDTYPE_FLAGS_ISLINKABLE}, /* rename gpencil */
- { ID_GR, "Group", "groups", IDTYPE_FLAGS_ISLINKABLE},
- { ID_ID, "ID", "ids", 0}, /* plural is fake */
- { ID_IM, "Image", "images", IDTYPE_FLAGS_ISLINKABLE},
- { ID_IP, "Ipo", "ipos", IDTYPE_FLAGS_ISLINKABLE}, /* deprecated */
- { ID_KE, "Key", "shape_keys", 0},
- { ID_LA, "Lamp", "lamps", IDTYPE_FLAGS_ISLINKABLE},
- { ID_LI, "Library", "libraries", 0},
- { ID_LT, "Lattice", "lattices", IDTYPE_FLAGS_ISLINKABLE},
- { ID_MA, "Material", "materials", IDTYPE_FLAGS_ISLINKABLE},
- { ID_MB, "Metaball", "metaballs", IDTYPE_FLAGS_ISLINKABLE},
- { ID_ME, "Mesh", "meshes", IDTYPE_FLAGS_ISLINKABLE},
- { ID_NT, "NodeTree", "node_groups", IDTYPE_FLAGS_ISLINKABLE},
- { ID_OB, "Object", "objects", IDTYPE_FLAGS_ISLINKABLE},
- { ID_PA, "ParticleSettings", "particles", 0},
- { ID_SCE, "Scene", "scenes", IDTYPE_FLAGS_ISLINKABLE},
- { ID_SCR, "Screen", "screens", 0},
- { ID_SEQ, "Sequence", "sequences", 0}, /* not actually ID data */
- { ID_SPK, "Speaker", "speakers", IDTYPE_FLAGS_ISLINKABLE},
- { ID_SO, "Sound", "sounds", IDTYPE_FLAGS_ISLINKABLE},
- { ID_TE, "Texture", "textures", IDTYPE_FLAGS_ISLINKABLE},
- { ID_TXT, "Text", "texts", IDTYPE_FLAGS_ISLINKABLE},
- { ID_VF, "VFont", "fonts", IDTYPE_FLAGS_ISLINKABLE},
- { ID_WO, "World", "worlds", IDTYPE_FLAGS_ISLINKABLE},
- { ID_WM, "WindowManager", "window_managers", 0},
- { ID_MC, "MovieClip", "movieclips", IDTYPE_FLAGS_ISLINKABLE},
- { ID_MSK, "Mask", "masks", IDTYPE_FLAGS_ISLINKABLE},
+ { ID_AC, "Action", "actions", IDTYPE_FLAGS_ISLINKABLE },
+ { ID_AR, "Armature", "armatures", IDTYPE_FLAGS_ISLINKABLE },
+ { ID_BR, "Brush", "brushes", IDTYPE_FLAGS_ISLINKABLE },
+ { ID_CA, "Camera", "cameras", IDTYPE_FLAGS_ISLINKABLE },
+ { ID_CU, "Curve", "curves", IDTYPE_FLAGS_ISLINKABLE },
+ { ID_GD, "GPencil", "grease_pencil", IDTYPE_FLAGS_ISLINKABLE }, /* rename gpencil */
+ { ID_GR, "Group", "groups", IDTYPE_FLAGS_ISLINKABLE },
+ { ID_ID, "ID", "ids", 0 }, /* plural is fake */
+ { ID_IM, "Image", "images", IDTYPE_FLAGS_ISLINKABLE },
+ { ID_IP, "Ipo", "ipos", IDTYPE_FLAGS_ISLINKABLE }, /* deprecated */
+ { ID_KE, "Key", "shape_keys", 0 },
+ { ID_LA, "Lamp", "lamps", IDTYPE_FLAGS_ISLINKABLE },
+ { ID_LI, "Library", "libraries", 0 },
+ { ID_LT, "Lattice", "lattices", IDTYPE_FLAGS_ISLINKABLE },
+ { ID_MA, "Material", "materials", IDTYPE_FLAGS_ISLINKABLE },
+ { ID_MB, "Metaball", "metaballs", IDTYPE_FLAGS_ISLINKABLE },
+ { ID_MC, "MovieClip", "movieclips", IDTYPE_FLAGS_ISLINKABLE },
+ { ID_ME, "Mesh", "meshes", IDTYPE_FLAGS_ISLINKABLE },
+ { ID_MSK, "Mask", "masks", IDTYPE_FLAGS_ISLINKABLE },
+ { ID_NT, "NodeTree", "node_groups", IDTYPE_FLAGS_ISLINKABLE },
+ { ID_OB, "Object", "objects", IDTYPE_FLAGS_ISLINKABLE },
+ { ID_PA, "ParticleSettings", "particles", 0 },
+ { ID_SCE, "Scene", "scenes", IDTYPE_FLAGS_ISLINKABLE },
+ { ID_SCR, "Screen", "screens", 0 },
+ { ID_SEQ, "Sequence", "sequences", 0 }, /* not actually ID data */
+ { ID_SPK, "Speaker", "speakers", IDTYPE_FLAGS_ISLINKABLE },
+ { ID_SO, "Sound", "sounds", IDTYPE_FLAGS_ISLINKABLE },
+ { ID_TE, "Texture", "textures", IDTYPE_FLAGS_ISLINKABLE },
+ { ID_TXT, "Text", "texts", IDTYPE_FLAGS_ISLINKABLE },
+ { ID_VF, "VFont", "fonts", IDTYPE_FLAGS_ISLINKABLE },
+ { ID_WO, "World", "worlds", IDTYPE_FLAGS_ISLINKABLE },
+ { ID_WM, "WindowManager", "window_managers", 0 },
};
static int nidtypes = sizeof(idtypes) / sizeof(idtypes[0]);
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index 55d37c91859..e4b9edacc7e 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -100,6 +100,8 @@
#include "WM_api.h"
+static SpinLock image_spin;
+
/* max int, to indicate we don't store sequences in ibuf */
#define IMA_NO_INDEX 0x7FEFEFEF
@@ -108,6 +110,16 @@
#define IMA_INDEX_FRAME(index) (index >> 10)
#define IMA_INDEX_PASS(index) (index & ~1023)
+void BKE_images_init(void)
+{
+ BLI_spin_init(&image_spin);
+}
+
+void BKE_images_exit(void)
+{
+ BLI_spin_end(&image_spin);
+}
+
/* ******** IMAGE PROCESSING ************* */
static void de_interlace_ng(struct ImBuf *ibuf) /* neogeo fields */
@@ -168,13 +180,14 @@ static void de_interlace_st(struct ImBuf *ibuf) /* standard fields */
void BKE_image_de_interlace(Image *ima, int odd)
{
- ImBuf *ibuf = BKE_image_get_ibuf(ima, NULL);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
if (ibuf) {
if (odd)
de_interlace_st(ibuf);
else
de_interlace_ng(ibuf);
}
+ BKE_image_release_ibuf(ima, ibuf, NULL);
}
/* ***************** ALLOC & FREE, DATA MANAGING *************** */
@@ -260,8 +273,9 @@ static ImBuf *image_get_ibuf(Image *ima, int index, int frame)
/* this function is intended to be thread safe. with IMA_NO_INDEX this
* should be OK, but when iterating over the list this is more tricky
* */
- if (index == IMA_NO_INDEX)
+ if (index == IMA_NO_INDEX) {
return ima->ibufs.first;
+ }
else {
ImBuf *ibuf;
@@ -269,9 +283,9 @@ static ImBuf *image_get_ibuf(Image *ima, int index, int frame)
for (ibuf = ima->ibufs.first; ibuf; ibuf = ibuf->next)
if (ibuf->index == index)
return ibuf;
-
- return NULL;
}
+
+ return NULL;
}
/* no ima->ibuf anymore, but listbase */
@@ -534,7 +548,7 @@ int BKE_image_scale(Image *image, int width, int height)
ibuf->userflags |= IB_BITMAPDIRTY;
}
- BKE_image_release_ibuf(image, lock);
+ BKE_image_release_ibuf(image, ibuf, lock);
return (ibuf != NULL);
}
@@ -2081,6 +2095,8 @@ void BKE_image_signal(Image *ima, ImageUser *iuser, int signal)
if (ima == NULL)
return;
+ BLI_spin_lock(&image_spin);
+
switch (signal) {
case IMA_SIGNAL_FREE:
image_free_buffers(ima);
@@ -2157,6 +2173,8 @@ void BKE_image_signal(Image *ima, ImageUser *iuser, int signal)
break;
}
+ BLI_spin_unlock(&image_spin);
+
/* don't use notifiers because they are not 100% sure to succeeded
* this also makes sure all scenes are accounted for. */
{
@@ -2320,7 +2338,7 @@ static ImBuf *image_load_sequence_file(Image *ima, ImageUser *iuser, int frame)
if (ibuf) {
#ifdef WITH_OPENEXR
- /* handle multilayer case, don't assign ibuf. will be handled in BKE_image_get_ibuf */
+ /* handle multilayer case, don't assign ibuf. will be handled in BKE_image_acquire_ibuf */
if (ibuf->ftype == OPENEXR && ibuf->userdata) {
image_create_multilayer(ima, ibuf, frame);
ima->type = IMA_TYPE_MULTILAYER;
@@ -2482,7 +2500,7 @@ static ImBuf *image_load_image_file(Image *ima, ImageUser *iuser, int cfra)
}
if (ibuf) {
- /* handle multilayer case, don't assign ibuf. will be handled in BKE_image_get_ibuf */
+ /* handle multilayer case, don't assign ibuf. will be handled in BKE_image_acquire_ibuf */
if (ibuf->ftype == OPENEXR && ibuf->userdata) {
image_create_multilayer(ima, ibuf, cfra);
ima->type = IMA_TYPE_MULTILAYER;
@@ -2751,38 +2769,32 @@ static ImBuf *image_get_ibuf_threadsafe(Image *ima, ImageUser *iuser, int *frame
* a big bottleneck */
}
- *frame_r = frame;
- *index_r = index;
+ if (frame_r)
+ *frame_r = frame;
+
+ if (index_r)
+ *index_r = index;
return ibuf;
}
-/* Checks optional ImageUser and verifies/creates ImBuf. */
-/* use this one if you want to get a render result in progress,
- * if not, use BKE_image_get_ibuf which doesn't require a release */
-ImBuf *BKE_image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r)
+/* Checks optional ImageUser and verifies/creates ImBuf.
+ *
+ * not thread-safe, so callee should worry about thread locks
+ */
+static ImBuf *image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r)
{
ImBuf *ibuf = NULL;
float color[] = {0, 0, 0, 1};
int frame = 0, index = 0;
- /* This function is intended to be thread-safe. It postpones the mutex lock
- * until it needs to load the image, if the image is already there it
- * should just get the pointer and return. The reason is that a lot of mutex
- * locks appears to be very slow on certain multicore macs, causing a render
- * with image textures to actually slow down as more threads are used.
- *
- * Note that all the image loading functions should also make sure they do
- * things in a threadsafe way for image_get_ibuf_threadsafe to work correct.
- * That means, the last two steps must be, 1) add the ibuf to the list and
- * 2) set ima/iuser->ok to 0 to IMA_OK_LOADED */
-
if (lock_r)
*lock_r = NULL;
/* quick reject tests */
if (ima == NULL)
return NULL;
+
if (iuser) {
if (iuser->ok == 0)
return NULL;
@@ -2790,95 +2802,71 @@ ImBuf *BKE_image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r)
else if (ima->ok == 0)
return NULL;
- /* try to get the ibuf without locking */
ibuf = image_get_ibuf_threadsafe(ima, iuser, &frame, &index);
if (ibuf == NULL) {
- /* couldn't get ibuf and image is not ok, so let's lock and try to
- * load the image */
- BLI_lock_thread(LOCK_IMAGE);
-
- /* need to check ok flag and loading ibuf again, because the situation
- * might have changed in the meantime */
- if (iuser) {
- if (iuser->ok == 0) {
- BLI_unlock_thread(LOCK_IMAGE);
- return NULL;
- }
- }
- else if (ima->ok == 0) {
- BLI_unlock_thread(LOCK_IMAGE);
- return NULL;
- }
-
- ibuf = image_get_ibuf_threadsafe(ima, iuser, &frame, &index);
-
- if (ibuf == NULL) {
- /* we are sure we have to load the ibuf, using source and type */
- if (ima->source == IMA_SRC_MOVIE) {
- /* source is from single file, use flipbook to store ibuf */
- ibuf = image_load_movie_file(ima, iuser, frame);
- }
- else if (ima->source == IMA_SRC_SEQUENCE) {
- if (ima->type == IMA_TYPE_IMAGE) {
- /* regular files, ibufs in flipbook, allows saving */
- ibuf = image_load_sequence_file(ima, iuser, frame);
- }
- /* no else; on load the ima type can change */
- if (ima->type == IMA_TYPE_MULTILAYER) {
- /* only 1 layer/pass stored in imbufs, no exrhandle anim storage, no saving */
- ibuf = image_load_sequence_multilayer(ima, iuser, frame);
- }
+ /* we are sure we have to load the ibuf, using source and type */
+ if (ima->source == IMA_SRC_MOVIE) {
+ /* source is from single file, use flipbook to store ibuf */
+ ibuf = image_load_movie_file(ima, iuser, frame);
+ }
+ else if (ima->source == IMA_SRC_SEQUENCE) {
+ if (ima->type == IMA_TYPE_IMAGE) {
+ /* regular files, ibufs in flipbook, allows saving */
+ ibuf = image_load_sequence_file(ima, iuser, frame);
}
- else if (ima->source == IMA_SRC_FILE) {
-
- if (ima->type == IMA_TYPE_IMAGE)
- ibuf = image_load_image_file(ima, iuser, frame); /* cfra only for '#', this global is OK */
- /* no else; on load the ima type can change */
- if (ima->type == IMA_TYPE_MULTILAYER)
- /* keeps render result, stores ibufs in listbase, allows saving */
- ibuf = image_get_ibuf_multilayer(ima, iuser);
-
+ /* no else; on load the ima type can change */
+ if (ima->type == IMA_TYPE_MULTILAYER) {
+ /* only 1 layer/pass stored in imbufs, no exrhandle anim storage, no saving */
+ ibuf = image_load_sequence_multilayer(ima, iuser, frame);
}
- else if (ima->source == IMA_SRC_GENERATED) {
- /* generated is: ibuf is allocated dynamically */
- /* UV testgrid or black or solid etc */
- if (ima->gen_x == 0) ima->gen_x = 1024;
- if (ima->gen_y == 0) ima->gen_y = 1024;
- ibuf = add_ibuf_size(ima->gen_x, ima->gen_y, ima->name, 24, (ima->gen_flag & IMA_GEN_FLOAT) != 0, ima->gen_type,
- color, &ima->colorspace_settings);
- image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0);
- ima->ok = IMA_OK_LOADED;
+ }
+ else if (ima->source == IMA_SRC_FILE) {
+
+ if (ima->type == IMA_TYPE_IMAGE)
+ ibuf = image_load_image_file(ima, iuser, frame); /* cfra only for '#', this global is OK */
+ /* no else; on load the ima type can change */
+ if (ima->type == IMA_TYPE_MULTILAYER)
+ /* keeps render result, stores ibufs in listbase, allows saving */
+ ibuf = image_get_ibuf_multilayer(ima, iuser);
+
+ }
+ else if (ima->source == IMA_SRC_GENERATED) {
+ /* generated is: ibuf is allocated dynamically */
+ /* UV testgrid or black or solid etc */
+ if (ima->gen_x == 0) ima->gen_x = 1024;
+ if (ima->gen_y == 0) ima->gen_y = 1024;
+ ibuf = add_ibuf_size(ima->gen_x, ima->gen_y, ima->name, 24, (ima->gen_flag & IMA_GEN_FLOAT) != 0, ima->gen_type,
+ color, &ima->colorspace_settings);
+ image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0);
+ ima->ok = IMA_OK_LOADED;
+ }
+ else if (ima->source == IMA_SRC_VIEWER) {
+ if (ima->type == IMA_TYPE_R_RESULT) {
+ /* always verify entirely, and potentially
+ * returns pointer to release later */
+ ibuf = image_get_render_result(ima, iuser, lock_r);
}
- else if (ima->source == IMA_SRC_VIEWER) {
- if (ima->type == IMA_TYPE_R_RESULT) {
- /* always verify entirely, and potentially
- * returns pointer to release later */
- ibuf = image_get_render_result(ima, iuser, lock_r);
- }
- else if (ima->type == IMA_TYPE_COMPOSITE) {
- /* requires lock/unlock, otherwise don't return image */
- if (lock_r) {
- /* unlock in BKE_image_release_ibuf */
- BLI_lock_thread(LOCK_VIEWER);
- *lock_r = ima;
-
- /* XXX anim play for viewer nodes not yet supported */
- frame = 0; // XXX iuser?iuser->framenr:0;
- ibuf = image_get_ibuf(ima, 0, frame);
-
- if (!ibuf) {
- /* Composite Viewer, all handled in compositor */
- /* fake ibuf, will be filled in compositor */
- ibuf = IMB_allocImBuf(256, 256, 32, IB_rect);
- image_assign_ibuf(ima, ibuf, 0, frame);
- }
+ else if (ima->type == IMA_TYPE_COMPOSITE) {
+ /* requires lock/unlock, otherwise don't return image */
+ if (lock_r) {
+ /* unlock in BKE_image_release_ibuf */
+ BLI_lock_thread(LOCK_VIEWER);
+ *lock_r = ima;
+
+ /* XXX anim play for viewer nodes not yet supported */
+ frame = 0; // XXX iuser?iuser->framenr:0;
+ ibuf = image_get_ibuf(ima, 0, frame);
+
+ if (!ibuf) {
+ /* Composite Viewer, all handled in compositor */
+ /* fake ibuf, will be filled in compositor */
+ ibuf = IMB_allocImBuf(256, 256, 32, IB_rect);
+ image_assign_ibuf(ima, ibuf, 0, frame);
}
}
}
}
-
- BLI_unlock_thread(LOCK_IMAGE);
}
BKE_image_tag_time(ima);
@@ -2886,23 +2874,79 @@ ImBuf *BKE_image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r)
return ibuf;
}
-void BKE_image_release_ibuf(Image *ima, void *lock)
+/* return image buffer for given image and user
+ *
+ * - will lock render result if image type is render result and lock is not NULL
+ * - will return NULL if image type if render or composite result and lock is NULL
+ *
+ * references the result, BKE_image_release_ibuf should be used to de-reference
+ */
+ImBuf *BKE_image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r)
+{
+ ImBuf *ibuf;
+
+ BLI_spin_lock(&image_spin);
+
+ ibuf = image_acquire_ibuf(ima, iuser, lock_r);
+
+ if (ibuf)
+ IMB_refImBuf(ibuf);
+
+ BLI_spin_unlock(&image_spin);
+
+ return ibuf;
+}
+
+void BKE_image_release_ibuf(Image *ima, ImBuf *ibuf, void *lock)
{
- /* for getting image during threaded render / compositing, need to release */
- if (lock == ima) {
- BLI_unlock_thread(LOCK_VIEWER); /* viewer image */
+ if (lock) {
+ /* for getting image during threaded render / compositing, need to release */
+ if (lock == ima) {
+ BLI_unlock_thread(LOCK_VIEWER); /* viewer image */
+ }
+ else if (lock) {
+ RE_ReleaseResultImage(lock); /* render result */
+ BLI_unlock_thread(LOCK_VIEWER); /* view image imbuf */
+ }
}
- else if (lock) {
- RE_ReleaseResultImage(lock); /* render result */
- BLI_unlock_thread(LOCK_VIEWER); /* view image imbuf */
+
+ if (ibuf) {
+ BLI_spin_lock(&image_spin);
+ IMB_freeImBuf(ibuf);
+ BLI_spin_unlock(&image_spin);
}
}
-/* warning, this can allocate generated images */
-ImBuf *BKE_image_get_ibuf(Image *ima, ImageUser *iuser)
+/* checks whether there's an image buffer for given image and user */
+int BKE_image_has_ibuf(Image *ima, ImageUser *iuser)
{
- /* here (+fie_ima/2-1) makes sure that division happens correctly */
- return BKE_image_acquire_ibuf(ima, iuser, NULL);
+ ImBuf *ibuf;
+
+ /* quick reject tests */
+ if (ima == NULL)
+ return FALSE;
+
+ if (iuser) {
+ if (iuser->ok == 0)
+ return FALSE;
+ }
+ else if (ima->ok == 0)
+ return FALSE;
+
+ ibuf = image_get_ibuf_threadsafe(ima, iuser, NULL, NULL);
+
+ if (!ibuf) {
+ BLI_spin_lock(&image_spin);
+
+ ibuf = image_get_ibuf_threadsafe(ima, iuser, NULL, NULL);
+
+ if (!ibuf)
+ ibuf = image_acquire_ibuf(ima, iuser, NULL);
+
+ BLI_spin_unlock(&image_spin);
+ }
+
+ return ibuf != NULL;
}
int BKE_image_user_frame_get(const ImageUser *iuser, int cfra, int fieldnr, short *r_is_in_range)
@@ -3020,7 +3064,7 @@ int BKE_image_has_alpha(struct Image *image)
ibuf = BKE_image_acquire_ibuf(image, NULL, &lock);
planes = (ibuf ? ibuf->planes : 0);
- BKE_image_release_ibuf(image, lock);
+ BKE_image_release_ibuf(image, ibuf, lock);
if (planes == 32)
return 1;
@@ -3044,7 +3088,7 @@ void BKE_image_get_size(Image *image, ImageUser *iuser, int *width, int *height)
*height = IMG_SIZE_FALLBACK;
}
- BKE_image_release_ibuf(image, lock);
+ BKE_image_release_ibuf(image, ibuf, lock);
}
void BKE_image_get_size_fl(Image *image, ImageUser *iuser, float size[2])
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index 9deff12f124..eb0612a75bd 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -1520,7 +1520,9 @@ void test_idbutton(char *name)
/* search for id */
idtest = BLI_findstring(lb, name, offsetof(ID, name) + 2);
- if (idtest) if (new_id(lb, idtest, name) == 0) id_sort_by_name(lb, idtest);
+ if (idtest && (new_id(lb, idtest, name) == 0)) {
+ id_sort_by_name(lb, idtest);
+ }
}
void text_idbutton(struct ID *id, char *text)
diff --git a/source/blender/blenkernel/intern/mask_evaluate.c b/source/blender/blenkernel/intern/mask_evaluate.c
index 7d89678d36f..a2f6b3c1929 100644
--- a/source/blender/blenkernel/intern/mask_evaluate.c
+++ b/source/blender/blenkernel/intern/mask_evaluate.c
@@ -289,10 +289,10 @@ static void feather_bucket_check_intersect(float (*feather_points)[2], int tot_f
/* collapse loop with smaller AABB */
for (k = 0; k < tot_feather_point; k++) {
if (k >= check_b && k <= cur_a) {
- DO_MINMAX2(feather_points[k], min_a, max_a);
+ minmax_v2v2_v2(min_a, max_a, feather_points[k]);
}
else {
- DO_MINMAX2(feather_points[k], min_b, max_b);
+ minmax_v2v2_v2(min_b, max_b, feather_points[k]);
}
}
@@ -379,7 +379,7 @@ void BKE_mask_spline_feather_collapse_inner_loops(MaskSpline *spline, float (*fe
int next = i + 1;
float delta;
- DO_MINMAX2(feather_points[i], min, max);
+ minmax_v2v2_v2(min, max, feather_points[i]);
if (next == tot_feather_point) {
if (spline->flag & MASK_SPLINE_CYCLIC)
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index 068059dc29a..fd5af6a20bb 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -3011,7 +3011,7 @@ float BKE_mesh_calc_poly_area(MPoly *mpoly, MLoop *loopstart,
MLoop *l_iter = loopstart;
float area, polynorm_local[3], (*vertexcos)[3];
const float *no = polynormal ? polynormal : polynorm_local;
- BLI_array_fixedstack_declare(vertexcos, BM_NGON_STACK_SIZE, mpoly->totloop, __func__);
+ BLI_array_fixedstack_declare(vertexcos, BM_DEFAULT_NGON_STACK_SIZE, mpoly->totloop, __func__);
/* pack vertex cos into an array for area_poly_v3 */
for (i = 0; i < mpoly->totloop; i++, l_iter++) {
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index 9c7cbc42bdd..25b70ce1793 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -249,13 +249,13 @@ int modifier_couldBeCage(struct Scene *scene, ModifierData *md)
modifier_supportsMapping(md));
}
-int modifier_sameTopology(ModifierData *md)
+int modifier_isSameTopology(ModifierData *md)
{
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
return ELEM(mti->type, eModifierTypeType_OnlyDeform, eModifierTypeType_NonGeometrical);
}
-int modifier_nonGeometrical(ModifierData *md)
+int modifier_isNonGeometrical(ModifierData *md)
{
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
return (mti->type == eModifierTypeType_NonGeometrical);
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index 2d76484b60a..06b846a6df9 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -2184,6 +2184,7 @@ static void registerCompositNodes(bNodeTreeType *ttype)
register_node_type_cmp_normal(ttype);
register_node_type_cmp_curve_vec(ttype);
register_node_type_cmp_map_value(ttype);
+ register_node_type_cmp_map_range(ttype);
register_node_type_cmp_normalize(ttype);
register_node_type_cmp_filter(ttype);
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 6ec173a5908..47ca502d247 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -196,18 +196,18 @@ int BKE_object_support_modifier_type_check(Object *ob, int modifier_type)
return TRUE;
}
-void BKE_object_link_modifiers(struct Object *ob, struct Object *from)
+void BKE_object_link_modifiers(struct Object *ob_dst, struct Object *ob_src)
{
ModifierData *md;
- BKE_object_free_modifiers(ob);
+ BKE_object_free_modifiers(ob_dst);
- if (!ELEM5(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_LATTICE)) {
+ if (!ELEM5(ob_dst->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_LATTICE)) {
/* only objects listed above can have modifiers and linking them to objects
* which doesn't have modifiers stack is quite silly */
return;
}
- for (md = from->modifiers.first; md; md = md->next) {
+ for (md = ob_src->modifiers.first; md; md = md->next) {
ModifierData *nmd = NULL;
if (ELEM4(md->type,
@@ -219,16 +219,18 @@ void BKE_object_link_modifiers(struct Object *ob, struct Object *from)
continue;
}
- if (!BKE_object_support_modifier_type_check(ob, md->type))
+ if (!BKE_object_support_modifier_type_check(ob_dst, md->type))
continue;
nmd = modifier_new(md->type);
+ BLI_strncpy(nmd->name, md->name, sizeof(nmd->name));
modifier_copyData(md, nmd);
- BLI_addtail(&ob->modifiers, nmd);
+ BLI_addtail(&ob_dst->modifiers, nmd);
+ modifier_unique_name(&ob_dst->modifiers, nmd);
}
- BKE_object_copy_particlesystems(ob, from);
- BKE_object_copy_softbody(ob, from);
+ BKE_object_copy_particlesystems(ob_dst, ob_src);
+ BKE_object_copy_softbody(ob_dst, ob_src);
/* TODO: smoke?, cloth? */
}
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index d645204d29c..93bf5a5c0b4 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -3786,14 +3786,22 @@ static int get_particle_uv(DerivedMesh *dm, ParticleData *pa, int face_index, co
return 1;
}
-#define SET_PARTICLE_TEXTURE(type, pvalue, texfac) \
- if ((event & mtex->mapto) & type) { pvalue = texture_value_blend(def, pvalue, value, texfac, blend); } (void)0
-
-#define CLAMP_PARTICLE_TEXTURE_POS(type, pvalue) \
- if (event & type) { if (pvalue < 0.0f) pvalue = 1.0f + pvalue; CLAMP(pvalue, 0.0f, 1.0f); } (void)0
-
-#define CLAMP_PARTICLE_TEXTURE_POSNEG(type, pvalue) \
- if (event & type) { CLAMP(pvalue, -1.0f, 1.0f); } (void)0
+#define SET_PARTICLE_TEXTURE(type, pvalue, texfac) \
+ if ((event & mtex->mapto) & type) { \
+ pvalue = texture_value_blend(def, pvalue, value, texfac, blend); \
+ } (void)0
+
+#define CLAMP_PARTICLE_TEXTURE_POS(type, pvalue) \
+ if (event & type) { \
+ if (pvalue < 0.0f) \
+ pvalue = 1.0f + pvalue; \
+ CLAMP(pvalue, 0.0f, 1.0f); \
+ } (void)0
+
+#define CLAMP_PARTICLE_TEXTURE_POSNEG(type, pvalue) \
+ if (event & type) { \
+ CLAMP(pvalue, -1.0f, 1.0f); \
+ } (void)0
static void get_cpa_texture(DerivedMesh *dm, ParticleSystem *psys, ParticleSettings *part, ParticleData *par, int child_index, int face_index, const float fw[4], float *orco, ParticleTexture *ptex, int event, float cfra)
{
@@ -3802,8 +3810,8 @@ static void get_cpa_texture(DerivedMesh *dm, ParticleSystem *psys, ParticleSetti
float value, rgba[4], texvec[3];
ptex->ivel = ptex->life = ptex->exist = ptex->size = ptex->damp =
- ptex->gravity = ptex->field = ptex->time = ptex->clump = ptex->kink =
- ptex->effector = ptex->rough1 = ptex->rough2 = ptex->roughe = 1.f;
+ ptex->gravity = ptex->field = ptex->time = ptex->clump = ptex->kink =
+ ptex->effector = ptex->rough1 = ptex->rough2 = ptex->roughe = 1.0f;
ptex->length = 1.0f - part->randlength * PSYS_FRAND(child_index + 26);
ptex->length *= part->clength_thres < PSYS_FRAND(child_index + 27) ? part->clength : 1.0f;
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index f195b3d71b0..3f2eb32f61c 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -2568,10 +2568,12 @@ int BKE_ptcache_id_reset(Scene *scene, PTCacheID *pid, int mode)
sbFreeSimulation(pid->calldata);
else if (pid->type == PTCACHE_TYPE_PARTICLES)
psys_reset(pid->calldata, PSYS_RESET_DEPSGRAPH);
- /*else if (pid->type == PTCACHE_TYPE_SMOKE_DOMAIN)
+#if 0
+ else if (pid->type == PTCACHE_TYPE_SMOKE_DOMAIN)
smokeModifier_reset(pid->calldata);
else if (pid->type == PTCACHE_TYPE_SMOKE_HIGHRES)
- smokeModifier_reset_turbulence(pid->calldata);*/
+ smokeModifier_reset_turbulence(pid->calldata);
+#endif
else if (pid->type == PTCACHE_TYPE_DYNAMICPAINT)
dynamicPaint_clearSurface((DynamicPaintSurface*)pid->calldata);
}
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 4f62732f5e6..9b1425584a7 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -1045,7 +1045,7 @@ static void scene_update_tagged_recursive(Main *bmain, Scene *scene, Scene *scen
/* always update layer, so that animating layers works (joshua july 2010) */
/* XXX commented out, this has depsgraph issues anyway - and this breaks setting scenes
- (on scene-set, the base-lay is copied to ob-lay (ton nov 2012) */
+ * (on scene-set, the base-lay is copied to ob-lay (ton nov 2012) */
// base->lay = ob->lay;
}
diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c
index 469881020c1..0b7fdaa7c1d 100644
--- a/source/blender/blenkernel/intern/seqeffects.c
+++ b/source/blender/blenkernel/intern/seqeffects.c
@@ -139,6 +139,9 @@ static ImBuf *prepare_effect_imbufs(SeqRenderData context, ImBuf *ibuf1, ImBuf *
IMB_rect_from_float(ibuf3);
}
+ if (out->rect_float)
+ IMB_colormanagement_assign_float_colorspace(out, context.scene->sequencer_colorspace_settings.name);
+
return out;
}
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index a947a48938e..e023a3e20ae 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -2338,11 +2338,13 @@ static ImBuf *seq_render_scene_strip(SeqRenderData context, Sequence *seq, float
*/
const short is_rendering = G.is_rendering;
+ const short is_background = G.background;
const int do_seq_gl = G.is_rendering ?
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_comp = FALSE;
Scene *scene;
int is_thread_main = BLI_thread_is_main();
@@ -2355,6 +2357,7 @@ static ImBuf *seq_render_scene_strip(SeqRenderData context, Sequence *seq, float
frame = scene->r.sfra + nr + seq->anim_startofs;
have_seq = (scene->r.scemode & R_DOSEQ) && scene->ed && scene->ed->seqbase.first;
+ have_comp = (scene->r.scemode & R_DOCOMP) && scene->use_nodes && scene->nodetree;
oldcfra = scene->r.cfra;
scene->r.cfra = frame;
@@ -2367,7 +2370,7 @@ static ImBuf *seq_render_scene_strip(SeqRenderData context, Sequence *seq, float
camera = scene->camera;
}
- if (have_seq == FALSE && camera == NULL) {
+ if (have_comp == FALSE && camera == NULL) {
scene->r.cfra = oldcfra;
return NULL;
}
@@ -2384,8 +2387,7 @@ static ImBuf *seq_render_scene_strip(SeqRenderData context, Sequence *seq, float
(void)oldmarkers;
#endif
- if ((sequencer_view3d_cb && do_seq_gl && camera) && is_thread_main)
- {
+ if ((sequencer_view3d_cb && do_seq_gl && camera) && is_thread_main) {
char err_out[256] = "unknown";
/* for old scened this can be uninitialized,
* should probably be added to do_versions at some point if the functionality stays */
@@ -2408,11 +2410,15 @@ static ImBuf *seq_render_scene_strip(SeqRenderData context, Sequence *seq, float
*
* disable rendered preview for sequencer while rendering -- it's very much possible
* that preview render will went into conflict with final render
+ *
+ * When rendering from command line renderer is called from main thread, in this
+ * case it's always safe to render scene here
*/
- if (!is_thread_main || is_rendering == FALSE) {
+ if (!is_thread_main || is_rendering == FALSE || is_background) {
if (re == NULL)
re = RE_NewRender(scene->id.name);
+ BKE_scene_update_for_newframe(context.bmain, scene, scene->lay);
RE_BlenderFrame(re, context.bmain, scene, NULL, camera, scene->lay, frame, FALSE);
/* restore previous state after it was toggled on & off by RE_BlenderFrame */
diff --git a/source/blender/blenkernel/intern/suggestions.c b/source/blender/blenkernel/intern/suggestions.c
index 99e33594a3e..ff9774f85af 100644
--- a/source/blender/blenkernel/intern/suggestions.c
+++ b/source/blender/blenkernel/intern/suggestions.c
@@ -47,6 +47,7 @@ static SuggList suggestions = {NULL, NULL, NULL, NULL, NULL};
static char *documentation = NULL;
//static int doc_lines = 0;
+/* TODO, replace with BLI_strncasecmp() */
static int txttl_cmp(const char *first, const char *second, int len)
{
int cmp, i;
@@ -113,19 +114,18 @@ short texttool_text_is_active(Text *text)
void texttool_suggest_add(const char *name, char type)
{
+ const int len = strlen(name);
+ int cmp;
SuggItem *newitem, *item;
- int len, cmp;
- newitem = MEM_mallocN(sizeof(SuggItem) + strlen(name) + 1, "SuggestionItem");
+ newitem = MEM_mallocN(sizeof(SuggItem) + len + 1, "SuggItem");
if (!newitem) {
printf("Failed to allocate memory for suggestion.\n");
return;
}
newitem->name = (char *) (newitem + 1);
- len = strlen(name);
- strncpy(newitem->name, name, len);
- newitem->name[len] = '\0';
+ memcpy(newitem->name, name, len + 1);
newitem->type = type;
newitem->prev = newitem->next = NULL;
diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c
index d230cf8f1fe..e6339d07e66 100644
--- a/source/blender/blenkernel/intern/text.c
+++ b/source/blender/blenkernel/intern/text.c
@@ -96,17 +96,6 @@
* If the user moves the cursor the st containing that cursor should
* be popped ... other st's retain their own top location.
*
- * Markers
- * --
- * The mrk->flags define the behavior and relationships between markers. The
- * upper two bytes are used to hold a group ID, the lower two are normal flags. If
- * TMARK_EDITALL is set the group ID defines which other markers should be edited.
- *
- * The mrk->clr field is used to visually group markers where the flags may not
- * match. A template system, for example, may allow editing of repeating tokens
- * (in one group) but include other marked positions (in another group) all in the
- * same template with the same color.
- *
* Undo
* --
* Undo/Redo works by storing
@@ -136,8 +125,7 @@
static void txt_pop_first(Text *text);
static void txt_pop_last(Text *text);
-static void txt_undo_add_op(Text *text, int op);
-static void txt_undo_add_block(Text *text, int op, const char *buf);
+static void txt_undo_add_blockop(Text *text, int op, const char *buf);
static void txt_delete_line(Text *text, TextLine *line);
static void txt_delete_sel(Text *text);
static void txt_make_dirty(Text *text);
@@ -175,7 +163,6 @@ void BKE_text_free(Text *text)
}
BLI_freelistN(&text->lines);
- BLI_freelistN(&text->markers);
if (text->name) MEM_freeN(text->name);
MEM_freeN(text->undo_buf);
@@ -203,7 +190,6 @@ Text *BKE_text_add(const char *name)
ta->flags |= TXT_TABSTOSPACES;
ta->lines.first = ta->lines.last = NULL;
- ta->markers.first = ta->markers.last = NULL;
tmp = (TextLine *) MEM_mallocN(sizeof(TextLine), "textline");
tmp->line = (char *) MEM_mallocN(1, "textline_string");
@@ -399,7 +385,6 @@ Text *BKE_text_load(const char *file, const char *relpath)
ta->id.us = 1;
ta->lines.first = ta->lines.last = NULL;
- ta->markers.first = ta->markers.last = NULL;
ta->curl = ta->sell = NULL;
if ((U.flag & USER_TXT_TABSTOSPACES_DISABLE) == 0)
@@ -496,7 +481,6 @@ Text *BKE_text_copy(Text *ta)
tan->flags = ta->flags | TXT_ISDIRTY;
tan->lines.first = tan->lines.last = NULL;
- tan->markers.first = tan->markers.last = NULL;
tan->curl = tan->sell = NULL;
tan->nlines = ta->nlines;
@@ -785,23 +769,6 @@ static void txt_curs_sel(Text *text, TextLine ***linep, int **charp)
*linep = &text->sell; *charp = &text->selc;
}
-static void txt_curs_first(Text *text, TextLine **linep, int *charp)
-{
- if (text->curl == text->sell) {
- *linep = text->curl;
- if (text->curc < text->selc) *charp = text->curc;
- else *charp = text->selc;
- }
- else if (txt_get_span(text->lines.first, text->curl) < txt_get_span(text->lines.first, text->sell)) {
- *linep = text->curl;
- *charp = text->curc;
- }
- else {
- *linep = text->sell;
- *charp = text->selc;
- }
-}
-
/*****************************/
/* Cursor movement functions */
/*****************************/
@@ -843,13 +810,11 @@ void txt_move_up(Text *text, short sel)
{
TextLine **linep;
int *charp;
- /* int old; */ /* UNUSED */
if (!text) return;
if (sel) txt_curs_sel(text, &linep, &charp);
else { txt_pop_first(text); txt_curs_cur(text, &linep, &charp); }
if (!*linep) return;
- /* old = *charp; */ /* UNUSED */
if ((*linep)->prev) {
int index = txt_utf8_offset_to_index((*linep)->line, *charp);
@@ -857,8 +822,6 @@ void txt_move_up(Text *text, short sel)
if (index > txt_utf8_len((*linep)->line)) *charp = (*linep)->len;
else *charp = txt_utf8_index_to_offset((*linep)->line, index);
- if (!undoing)
- txt_undo_add_op(text, sel ? UNDO_SUP : UNDO_CUP);
}
else {
txt_move_bol(text, sel);
@@ -871,22 +834,17 @@ void txt_move_down(Text *text, short sel)
{
TextLine **linep;
int *charp;
- /* int old; */ /* UNUSED */
if (!text) return;
if (sel) txt_curs_sel(text, &linep, &charp);
else { txt_pop_last(text); txt_curs_cur(text, &linep, &charp); }
if (!*linep) return;
- /* old = *charp; */ /* UNUSED */
if ((*linep)->next) {
int index = txt_utf8_offset_to_index((*linep)->line, *charp);
*linep = (*linep)->next;
if (index > txt_utf8_len((*linep)->line)) *charp = (*linep)->len;
else *charp = txt_utf8_index_to_offset((*linep)->line, index);
-
- if (!undoing)
- txt_undo_add_op(text, sel ? UNDO_SDOWN : UNDO_CDOWN);
}
else {
txt_move_eol(text, sel);
@@ -898,7 +856,7 @@ void txt_move_down(Text *text, short sel)
void txt_move_left(Text *text, short sel)
{
TextLine **linep;
- int *charp, oundoing = undoing;
+ int *charp;
int tabsize = 0, i = 0;
if (!text) return;
@@ -906,8 +864,6 @@ void txt_move_left(Text *text, short sel)
else { txt_pop_first(text); txt_curs_cur(text, &linep, &charp); }
if (!*linep) return;
- undoing = 1;
-
if (*charp == 0) {
if ((*linep)->prev) {
txt_move_up(text, sel);
@@ -939,24 +895,19 @@ void txt_move_left(Text *text, short sel)
}
}
- undoing = oundoing;
- if (!undoing) txt_undo_add_op(text, sel ? UNDO_SLEFT : UNDO_CLEFT);
-
if (!sel) txt_pop_sel(text);
}
void txt_move_right(Text *text, short sel)
{
TextLine **linep;
- int *charp, oundoing = undoing, do_tab = FALSE, i;
+ int *charp, do_tab = FALSE, i;
if (!text) return;
if (sel) txt_curs_sel(text, &linep, &charp);
else { txt_pop_last(text); txt_curs_cur(text, &linep, &charp); }
if (!*linep) return;
- undoing = 1;
-
if (*charp == (*linep)->len) {
if ((*linep)->next) {
txt_move_down(text, sel);
@@ -984,124 +935,103 @@ void txt_move_right(Text *text, short sel)
else (*charp) += BLI_str_utf8_size((*linep)->line + *charp);
}
- undoing = oundoing;
- if (!undoing) txt_undo_add_op(text, sel ? UNDO_SRIGHT : UNDO_CRIGHT);
-
if (!sel) txt_pop_sel(text);
}
void txt_jump_left(Text *text, short sel)
{
TextLine **linep;
- int *charp, oldc;
+ int *charp;
if (!text) return;
if (sel) txt_curs_sel(text, &linep, &charp);
else { txt_pop_first(text); txt_curs_cur(text, &linep, &charp); }
if (!*linep) return;
- oldc = *charp;
BLI_str_cursor_step_utf8((*linep)->line, (*linep)->len,
charp, STRCUR_DIR_PREV,
STRCUR_JUMP_DELIM);
if (!sel) txt_pop_sel(text);
- if (!undoing) {
- int span = txt_get_span(text->lines.first, *linep);
- txt_undo_add_toop(text, sel ? UNDO_STO : UNDO_CTO, span, oldc, span, (unsigned short)*charp);
- }
}
void txt_jump_right(Text *text, short sel)
{
TextLine **linep;
- int *charp, oldc;
+ int *charp;
if (!text) return;
if (sel) txt_curs_sel(text, &linep, &charp);
else { txt_pop_last(text); txt_curs_cur(text, &linep, &charp); }
if (!*linep) return;
- oldc = *charp;
BLI_str_cursor_step_utf8((*linep)->line, (*linep)->len,
charp, STRCUR_DIR_NEXT,
STRCUR_JUMP_DELIM);
if (!sel) txt_pop_sel(text);
- if (!undoing) {
- int span = txt_get_span(text->lines.first, *linep);
- txt_undo_add_toop(text, sel ? UNDO_STO : UNDO_CTO, span, oldc, span, (unsigned short)*charp);
- }
}
void txt_move_bol(Text *text, short sel)
{
TextLine **linep;
- int *charp, old;
+ int *charp;
if (!text) return;
if (sel) txt_curs_sel(text, &linep, &charp);
else txt_curs_cur(text, &linep, &charp);
if (!*linep) return;
- old = *charp;
*charp = 0;
if (!sel) txt_pop_sel(text);
- if (!undoing) txt_undo_add_toop(text, sel ? UNDO_STO : UNDO_CTO, txt_get_span(text->lines.first, *linep), old, txt_get_span(text->lines.first, *linep), (unsigned short)*charp);
}
void txt_move_eol(Text *text, short sel)
{
TextLine **linep;
- int *charp, old;
+ int *charp;
if (!text) return;
if (sel) txt_curs_sel(text, &linep, &charp);
else txt_curs_cur(text, &linep, &charp);
if (!*linep) return;
- old = *charp;
-
+
*charp = (*linep)->len;
if (!sel) txt_pop_sel(text);
- if (!undoing) txt_undo_add_toop(text, sel ? UNDO_STO : UNDO_CTO, txt_get_span(text->lines.first, *linep), old, txt_get_span(text->lines.first, *linep), (unsigned short)*charp);
}
void txt_move_bof(Text *text, short sel)
{
TextLine **linep;
- int *charp, old;
+ int *charp;
if (!text) return;
if (sel) txt_curs_sel(text, &linep, &charp);
else txt_curs_cur(text, &linep, &charp);
if (!*linep) return;
- old = *charp;
*linep = text->lines.first;
*charp = 0;
if (!sel) txt_pop_sel(text);
- if (!undoing) txt_undo_add_toop(text, sel ? UNDO_STO : UNDO_CTO, txt_get_span(text->lines.first, *linep), old, txt_get_span(text->lines.first, *linep), (unsigned short)*charp);
}
void txt_move_eof(Text *text, short sel)
{
TextLine **linep;
- int *charp, old;
+ int *charp;
if (!text) return;
if (sel) txt_curs_sel(text, &linep, &charp);
else txt_curs_cur(text, &linep, &charp);
if (!*linep) return;
- old = *charp;
*linep = text->lines.last;
*charp = (*linep)->len;
if (!sel) txt_pop_sel(text);
- if (!undoing) txt_undo_add_toop(text, sel ? UNDO_STO : UNDO_CTO, txt_get_span(text->lines.first, *linep), old, txt_get_span(text->lines.first, *linep), (unsigned short)*charp);
}
void txt_move_toline(Text *text, unsigned int line, short sel)
@@ -1112,16 +1042,14 @@ void txt_move_toline(Text *text, unsigned int line, short sel)
/* Moves to a certain byte in a line, not a certain utf8-character! */
void txt_move_to(Text *text, unsigned int line, unsigned int ch, short sel)
{
- TextLine **linep, *oldl;
- int *charp, oldc;
+ TextLine **linep;
+ int *charp;
unsigned int i;
if (!text) return;
if (sel) txt_curs_sel(text, &linep, &charp);
else txt_curs_cur(text, &linep, &charp);
if (!*linep) return;
- oldc = *charp;
- oldl = *linep;
*linep = text->lines.first;
for (i = 0; i < line; i++) {
@@ -1133,7 +1061,6 @@ void txt_move_to(Text *text, unsigned int line, unsigned int ch, short sel)
*charp = ch;
if (!sel) txt_pop_sel(text);
- if (!undoing) txt_undo_add_toop(text, sel ? UNDO_STO : UNDO_CTO, txt_get_span(text->lines.first, oldl), oldc, txt_get_span(text->lines.first, *linep), (unsigned short)*charp);
}
/****************************/
@@ -1152,8 +1079,6 @@ static void txt_curs_swap(Text *text)
tmpc = text->curc;
text->curc = text->selc;
text->selc = tmpc;
-
- if (!undoing) txt_undo_add_op(text, UNDO_SWAP);
}
static void txt_pop_first(Text *text)
@@ -1164,12 +1089,6 @@ static void txt_pop_first(Text *text)
{
txt_curs_swap(text);
}
-
- if (!undoing) txt_undo_add_toop(text, UNDO_STO,
- txt_get_span(text->lines.first, text->sell),
- text->selc,
- txt_get_span(text->lines.first, text->curl),
- text->curc);
txt_pop_sel(text);
}
@@ -1181,12 +1100,6 @@ static void txt_pop_last(Text *text)
{
txt_curs_swap(text);
}
-
- if (!undoing) txt_undo_add_toop(text, UNDO_STO,
- txt_get_span(text->lines.first, text->sell),
- text->selc,
- txt_get_span(text->lines.first, text->curl),
- text->curc);
txt_pop_sel(text);
}
@@ -1222,9 +1135,7 @@ int txt_has_sel(Text *text)
static void txt_delete_sel(Text *text)
{
TextLine *tmpl;
- TextMarker *mrk;
char *buf;
- int move, lineno;
if (!text) return;
if (!text->curl) return;
@@ -1236,33 +1147,11 @@ static void txt_delete_sel(Text *text)
if (!undoing) {
buf = txt_sel_to_buf(text);
- txt_undo_add_block(text, UNDO_DBLOCK, buf);
+ txt_undo_add_blockop(text, UNDO_DBLOCK, buf);
MEM_freeN(buf);
}
buf = MEM_mallocN(text->curc + (text->sell->len - text->selc) + 1, "textline_string");
-
- if (text->curl != text->sell) {
- txt_clear_marker_region(text, text->curl, text->curc, text->curl->len, 0, 0);
- move = txt_get_span(text->curl, text->sell);
- }
- else {
- mrk = txt_find_marker_region(text, text->curl, text->curc, text->selc, 0, 0);
- if (mrk && (mrk->start > text->curc || mrk->end < text->selc))
- txt_clear_marker_region(text, text->curl, text->curc, text->selc, 0, 0);
- move = 0;
- }
-
- mrk = txt_find_marker_region(text, text->sell, text->selc - 1, text->sell->len, 0, 0);
- if (mrk) {
- lineno = mrk->lineno;
- do {
- mrk->lineno -= move;
- if (mrk->start > text->curc) mrk->start -= text->selc - text->curc;
- mrk->end -= text->selc - text->curc;
- mrk = mrk->next;
- } while (mrk && mrk->lineno == lineno);
- }
strncpy(buf, text->curl->line, text->curc);
strcpy(buf + text->curc, text->sell->line + text->selc);
@@ -1491,19 +1380,9 @@ char *txt_sel_to_buf(Text *text)
return buf;
}
-static void txt_shift_markers(Text *text, int lineno, int count)
-{
- TextMarker *marker;
-
- for (marker = text->markers.first; marker; marker = marker->next)
- if (marker->lineno >= lineno) {
- marker->lineno += count;
- }
-}
-
void txt_insert_buf(Text *text, const char *in_buffer)
{
- int l = 0, u, len, lineno = -1, count = 0;
+ int l = 0, u, len;
size_t i = 0, j;
TextLine *add;
char *buffer;
@@ -1517,7 +1396,7 @@ void txt_insert_buf(Text *text, const char *in_buffer)
buffer = BLI_strdupn(in_buffer, len);
len += txt_extended_ascii_as_utf8(&buffer);
- if (!undoing) txt_undo_add_block(text, UNDO_IBLOCK, buffer);
+ if (!undoing) txt_undo_add_blockop(text, UNDO_IBLOCK, buffer);
u = undoing;
undoing = 1;
@@ -1530,9 +1409,6 @@ void txt_insert_buf(Text *text, const char *in_buffer)
else { undoing = u; MEM_freeN(buffer); return; }
i++;
- /* Read as many full lines as we can */
- lineno = txt_get_span(text->lines.first, text->curl);
-
while (i < len) {
l = 0;
@@ -1544,14 +1420,8 @@ void txt_insert_buf(Text *text, const char *in_buffer)
add = txt_new_linen(buffer + (i - l), l);
BLI_insertlinkbefore(&text->lines, text->curl, add);
i++;
- count++;
}
else {
- if (count) {
- txt_shift_markers(text, lineno, count);
- count = 0;
- }
-
for (j = i - l; j < i && j < len; )
txt_add_raw_char(text, BLI_str_utf8_as_unicode_step(buffer, &j));
break;
@@ -1560,10 +1430,6 @@ void txt_insert_buf(Text *text, const char *in_buffer)
MEM_freeN(buffer);
- if (count) {
- txt_shift_markers(text, lineno, count);
- }
-
undoing = u;
}
@@ -1599,6 +1465,7 @@ static void dump_buffer(Text *text)
while (i++ < text->undo_pos) printf("%d: %d %c\n", i, text->undo_buf[i], text->undo_buf[i]);
}
+/* Note: this function is outdated and must be updated if needed for future use */
void txt_print_undo(Text *text)
{
int i = 0;
@@ -1615,37 +1482,7 @@ void txt_print_undo(Text *text)
while (i <= text->undo_pos) {
op = text->undo_buf[i];
- if (op == UNDO_CLEFT) {
- ops = "Cursor left";
- }
- else if (op == UNDO_CRIGHT) {
- ops = "Cursor right";
- }
- else if (op == UNDO_CUP) {
- ops = "Cursor up";
- }
- else if (op == UNDO_CDOWN) {
- ops = "Cursor down";
- }
- else if (op == UNDO_SLEFT) {
- ops = "Selection left";
- }
- else if (op == UNDO_SRIGHT) {
- ops = "Selection right";
- }
- else if (op == UNDO_SUP) {
- ops = "Selection up";
- }
- else if (op == UNDO_SDOWN) {
- ops = "Selection down";
- }
- else if (op == UNDO_STO) {
- ops = "Selection ";
- }
- else if (op == UNDO_CTO) {
- ops = "Cursor ";
- }
- else if (op == UNDO_INSERT_1) {
+ if (op == UNDO_INSERT_1) {
ops = "Insert ascii ";
}
else if (op == UNDO_INSERT_2) {
@@ -1681,9 +1518,6 @@ void txt_print_undo(Text *text)
else if (op == UNDO_DEL_4) {
ops = "Delete unicode ";
}
- else if (op == UNDO_SWAP) {
- ops = "Cursor swap";
- }
else if (op == UNDO_DBLOCK) {
ops = "Delete text block";
}
@@ -1738,29 +1572,6 @@ void txt_print_undo(Text *text)
}
}
}
- else if (op == UNDO_STO || op == UNDO_CTO) {
- i++;
-
- charp = text->undo_buf[i]; i++;
- charp = charp + (text->undo_buf[i] << 8); i++;
-
- linep = text->undo_buf[i]; i++;
- linep = linep + (text->undo_buf[i] << 8); i++;
- linep = linep + (text->undo_buf[i] << 16); i++;
- linep = linep + (text->undo_buf[i] << 24); i++;
-
- printf("to <%d, %d> ", linep, charp);
-
- charp = text->undo_buf[i]; i++;
- charp = charp + (text->undo_buf[i] << 8); i++;
-
- linep = text->undo_buf[i]; i++;
- linep = linep + (text->undo_buf[i] << 8); i++;
- linep = linep + (text->undo_buf[i] << 16); i++;
- linep = linep + (text->undo_buf[i] << 24); i++;
-
- printf("from <%d, %d>", linep, charp);
- }
else if (op == UNDO_DBLOCK || op == UNDO_IBLOCK) {
i++;
@@ -1811,16 +1622,6 @@ void txt_print_undo(Text *text)
}
}
-static void txt_undo_add_op(Text *text, int op)
-{
- if (!max_undo_test(text, 2))
- return;
-
- text->undo_pos++;
- text->undo_buf[text->undo_pos] = op;
- text->undo_buf[text->undo_pos + 1] = 0;
-}
-
static void txt_undo_store_uint16(char *undo_buf, int *undo_pos, unsigned short value)
{
undo_buf[*undo_pos] = (value) & 0xff;
@@ -1841,17 +1642,41 @@ static void txt_undo_store_uint32(char *undo_buf, int *undo_pos, unsigned int va
(*undo_pos)++;
}
-static void txt_undo_add_block(Text *text, int op, const char *buf)
+/* store the cur cursor to the undo buffer */
+static void txt_undo_store_cur(Text *text)
+{
+ txt_undo_store_uint16(text->undo_buf, &text->undo_pos, text->curc);
+ txt_undo_store_uint32(text->undo_buf, &text->undo_pos, txt_get_span(text->lines.first, text->curl));
+}
+
+/* store the sel cursor to the undo buffer */
+static void txt_undo_store_sel(Text *text)
+{
+ txt_undo_store_uint16(text->undo_buf, &text->undo_pos, text->selc);
+ txt_undo_store_uint32(text->undo_buf, &text->undo_pos, txt_get_span(text->lines.first, text->sell));
+}
+
+/* store both cursors to the undo buffer */
+static void txt_undo_store_cursors(Text *text)
+{
+ txt_undo_store_cur(text);
+ txt_undo_store_sel(text);
+}
+
+/* store an operator along with a block of data */
+static void txt_undo_add_blockop(Text *text, int op, const char *buf)
{
unsigned int length = strlen(buf);
- if (!max_undo_test(text, length + 11))
+ if (!max_undo_test(text, length + 11 + 12))
return;
text->undo_pos++;
text->undo_buf[text->undo_pos] = op;
text->undo_pos++;
+ txt_undo_store_cursors(text);
+
txt_undo_store_uint32(text->undo_buf, &text->undo_pos, length);
strncpy(text->undo_buf + text->undo_pos, buf, length);
@@ -1863,34 +1688,30 @@ static void txt_undo_add_block(Text *text, int op, const char *buf)
text->undo_buf[text->undo_pos + 1] = 0;
}
-void txt_undo_add_toop(Text *text, int op, unsigned int froml, unsigned short fromc, unsigned int tol, unsigned short toc)
+/* store a regular operator */
+void txt_undo_add_op(Text *text, int op)
{
if (!max_undo_test(text, 15))
return;
- if (froml == tol && fromc == toc) return;
-
text->undo_pos++;
text->undo_buf[text->undo_pos] = op;
text->undo_pos++;
- txt_undo_store_uint16(text->undo_buf, &text->undo_pos, fromc);
- txt_undo_store_uint32(text->undo_buf, &text->undo_pos, froml);
- txt_undo_store_uint16(text->undo_buf, &text->undo_pos, toc);
- txt_undo_store_uint32(text->undo_buf, &text->undo_pos, tol);
+ txt_undo_store_cursors(text);
text->undo_buf[text->undo_pos] = op;
-
text->undo_buf[text->undo_pos + 1] = 0;
}
+/* store an operator for a single character */
static void txt_undo_add_charop(Text *text, int op_start, unsigned int c)
{
char utf8[BLI_UTF8_MAX];
size_t i, utf8_size = BLI_str_utf8_from_unicode(c, utf8);
- if (!max_undo_test(text, 3 + utf8_size))
+ if (!max_undo_test(text, 3 + utf8_size + 12))
return;
text->undo_pos++;
@@ -1899,6 +1720,8 @@ static void txt_undo_add_charop(Text *text, int op_start, unsigned int c)
text->undo_buf[text->undo_pos] = op_start + utf8_size - 1;
text->undo_pos++;
+ txt_undo_store_cur(text);
+
for (i = 0; i < utf8_size; i++) {
text->undo_buf[text->undo_pos] = utf8[i];
text->undo_pos++;
@@ -1909,6 +1732,9 @@ static void txt_undo_add_charop(Text *text, int op_start, unsigned int c)
else {
text->undo_buf[text->undo_pos] = op_start + 3;
text->undo_pos++;
+
+ txt_undo_store_cursors(text);
+
txt_undo_store_uint32(text->undo_buf, &text->undo_pos, c);
text->undo_buf[text->undo_pos] = op_start + 3;
}
@@ -1934,6 +1760,29 @@ static unsigned int txt_undo_read_uint32(const char *undo_buf, int *undo_pos)
return val;
}
+/* read the cur cursor from the undo buffer */
+static void txt_undo_read_cur(const char *undo_buf, int *undo_pos, unsigned int *curln, unsigned short *curc)
+{
+ *curln = txt_undo_read_uint32(undo_buf, undo_pos);
+ *curc = txt_undo_read_uint16(undo_buf, undo_pos);
+}
+
+/* read the sel cursor from the undo buffer */
+static void txt_undo_read_sel(const char *undo_buf, int *undo_pos, unsigned int *selln, unsigned short *selc)
+{
+ *selln = txt_undo_read_uint32(undo_buf, undo_pos);
+ *selc = txt_undo_read_uint16(undo_buf, undo_pos);
+}
+
+/* read both cursors from the undo buffer */
+static void txt_undo_read_cursors(const char *undo_buf, int *undo_pos,
+ unsigned int *curln, unsigned short *curc,
+ unsigned int *selln, unsigned short *selc)
+{
+ txt_undo_read_sel(undo_buf, undo_pos, selln, selc);
+ txt_undo_read_cur(undo_buf, undo_pos, curln, curc);
+}
+
static unsigned int txt_undo_read_unicode(const char *undo_buf, int *undo_pos, short bytes)
{
unsigned int unicode;
@@ -1986,6 +1835,29 @@ static unsigned int txt_redo_read_uint32(const char *undo_buf, int *undo_pos)
return val;
}
+/* redo read cur cursor from the undo buffer */
+static void txt_redo_read_cur(const char *undo_buf, int *undo_pos, unsigned int *curln, unsigned short *curc)
+{
+ *curc = txt_redo_read_uint16(undo_buf, undo_pos);
+ *curln = txt_redo_read_uint32(undo_buf, undo_pos);
+}
+
+/* redo read sel cursor from the undo buffer */
+static void txt_redo_read_sel(const char *undo_buf, int *undo_pos, unsigned int *selln, unsigned short *selc)
+{
+ *selc = txt_redo_read_uint16(undo_buf, undo_pos);
+ *selln = txt_redo_read_uint32(undo_buf, undo_pos);
+}
+
+/* redo read both cursors from the undo buffer */
+static void txt_redo_read_cursors(const char *undo_buf, int *undo_pos,
+ unsigned int *curln, unsigned short *curc,
+ unsigned int *selln, unsigned short *selc)
+{
+ txt_redo_read_cur(undo_buf, undo_pos, curln, curc);
+ txt_redo_read_sel(undo_buf, undo_pos, selln, selc);
+}
+
static unsigned int txt_redo_read_unicode(const char *undo_buf, int *undo_pos, short bytes)
{
unsigned int unicode;
@@ -2024,9 +1896,10 @@ void txt_do_undo(Text *text)
{
int op = text->undo_buf[text->undo_pos];
unsigned int linep, i;
+ unsigned int uchar;
+ unsigned int curln, selln;
+ unsigned short curc, selc;
unsigned short charp;
- TextLine *holdl;
- int holdc, holdln;
char *buf;
if (text->undo_pos < 0) {
@@ -2038,88 +1911,60 @@ void txt_do_undo(Text *text)
undoing = 1;
switch (op) {
- case UNDO_CLEFT:
- txt_move_right(text, 0);
- break;
+ case UNDO_INSERT_1:
+ case UNDO_INSERT_2:
+ case UNDO_INSERT_3:
+ case UNDO_INSERT_4:
+ text->undo_pos -= op - UNDO_INSERT_1 + 1;
- case UNDO_CRIGHT:
- txt_move_left(text, 0);
- break;
+ /* get and restore the cursors */
+ txt_undo_read_cur(text->undo_buf, &text->undo_pos, &curln, &curc);
+ txt_move_to(text, curln, curc, 0);
+ txt_move_to(text, curln, curc, 1);
- case UNDO_CUP:
- txt_move_down(text, 0);
- break;
+ txt_delete_char(text);
- case UNDO_CDOWN:
- txt_move_up(text, 0);
- break;
-
- case UNDO_SLEFT:
- txt_move_right(text, 1);
- break;
-
- case UNDO_SRIGHT:
- txt_move_left(text, 1);
- break;
-
- case UNDO_SUP:
- txt_move_down(text, 1);
+ text->undo_pos--;
break;
- case UNDO_SDOWN:
- txt_move_up(text, 1);
- break;
-
- case UNDO_CTO:
- case UNDO_STO:
- text->undo_pos--;
- text->undo_pos--;
- text->undo_pos--;
- text->undo_pos--;
-
- text->undo_pos--;
- text->undo_pos--;
-
- linep = txt_undo_read_uint32(text->undo_buf, &text->undo_pos);
- charp = txt_undo_read_uint16(text->undo_buf, &text->undo_pos);
-
- if (op == UNDO_CTO) {
- txt_move_toline(text, linep, 0);
- text->curc = charp;
- txt_pop_sel(text);
- }
- else {
- txt_move_toline(text, linep, 1);
- text->selc = charp;
- }
+ case UNDO_BS_1:
+ case UNDO_BS_2:
+ case UNDO_BS_3:
+ case UNDO_BS_4:
+ charp = op - UNDO_BS_1 + 1;
+ uchar = txt_undo_read_unicode(text->undo_buf, &text->undo_pos, charp);
- text->undo_pos--;
- break;
+ /* get and restore the cursors */
+ txt_undo_read_cur(text->undo_buf, &text->undo_pos, &curln, &curc);
+ txt_move_to(text, curln, curc, 0);
+ txt_move_to(text, curln, curc, 1);
- case UNDO_INSERT_1: case UNDO_INSERT_2: case UNDO_INSERT_3: case UNDO_INSERT_4:
- txt_backspace_char(text);
- text->undo_pos -= op - UNDO_INSERT_1 + 1;
- text->undo_pos--;
- break;
+ txt_add_char(text, uchar);
- case UNDO_BS_1: case UNDO_BS_2: case UNDO_BS_3: case UNDO_BS_4:
- charp = op - UNDO_BS_1 + 1;
- txt_add_char(text, txt_undo_read_unicode(text->undo_buf, &text->undo_pos, charp));
text->undo_pos--;
break;
-
- case UNDO_DEL_1: case UNDO_DEL_2: case UNDO_DEL_3: case UNDO_DEL_4:
+
+ case UNDO_DEL_1:
+ case UNDO_DEL_2:
+ case UNDO_DEL_3:
+ case UNDO_DEL_4:
charp = op - UNDO_DEL_1 + 1;
- txt_add_char(text, txt_undo_read_unicode(text->undo_buf, &text->undo_pos, charp));
+ uchar = txt_undo_read_unicode(text->undo_buf, &text->undo_pos, charp);
+
+ /* get and restore the cursors */
+ txt_undo_read_cur(text->undo_buf, &text->undo_pos, &curln, &curc);
+ txt_move_to(text, curln, curc, 0);
+ txt_move_to(text, curln, curc, 1);
+
+ txt_add_char(text, uchar);
+
txt_move_left(text, 0);
- text->undo_pos--;
- break;
- case UNDO_SWAP:
- txt_curs_swap(text);
+ text->undo_pos--;
break;
case UNDO_DBLOCK:
+ /* length of the string in the buffer */
linep = txt_undo_read_uint32(text->undo_buf, &text->undo_pos);
buf = MEM_mallocN(linep + 1, "dblock buffer");
@@ -2128,34 +1973,33 @@ void txt_do_undo(Text *text)
text->undo_pos--;
}
buf[i] = 0;
-
- txt_curs_first(text, &holdl, &holdc);
- holdln = txt_get_span(text->lines.first, holdl);
-
- txt_insert_buf(text, buf);
- MEM_freeN(buf);
-
- text->curl = text->lines.first;
- while (holdln > 0) {
- if (text->curl->next)
- text->curl = text->curl->next;
-
- holdln--;
- }
- text->curc = holdc;
+ /* skip over the length that was stored again */
text->undo_pos--;
text->undo_pos--;
text->undo_pos--;
text->undo_pos--;
+ /* Get the cursor positions */
+ txt_undo_read_cursors(text->undo_buf, &text->undo_pos, &curln, &curc, &selln, &selc);
+
+ /* move cur to location that needs buff inserted */
+ txt_move_to(text, curln, curc, 0);
+
+ txt_insert_buf(text, buf);
+ MEM_freeN(buf);
+
+ /* restore the cursors */
+ txt_move_to(text, curln, curc, 0);
+ txt_move_to(text, selln, selc, 1);
+
text->undo_pos--;
break;
case UNDO_IBLOCK:
+ /* length of the string in the buffer */
linep = txt_undo_read_uint32(text->undo_buf, &text->undo_pos);
- txt_delete_sel(text);
/* txt_backspace_char removes utf8-characters, not bytes */
buf = MEM_mallocN(linep + 1, "iblock buffer");
@@ -2167,47 +2011,32 @@ void txt_do_undo(Text *text)
linep = txt_utf8_len(buf);
MEM_freeN(buf);
- while (linep > 0) {
- txt_backspace_char(text);
- linep--;
- }
-
+ /* skip over the length that was stored again */
text->undo_pos--;
text->undo_pos--;
- text->undo_pos--;
text->undo_pos--;
-
text->undo_pos--;
+
+ /* get and restore the cursors */
+ txt_undo_read_cursors(text->undo_buf, &text->undo_pos, &curln, &curc, &selln, &selc);
+ txt_move_to(text, curln, curc, 0);
+ txt_move_to(text, curln, curc + linep, 1);
+
+ txt_delete_selected(text);
+ text->undo_pos--;
break;
case UNDO_INDENT:
case UNDO_UNINDENT:
case UNDO_COMMENT:
case UNDO_UNCOMMENT:
- linep = txt_undo_read_uint32(text->undo_buf, &text->undo_pos);
- //linep is now the end line of the selection
-
- charp = txt_undo_read_uint16(text->undo_buf, &text->undo_pos);
- //charp is the last char selected or text->line->len
-
- //set the selection for this now
- text->selc = charp;
- text->sell = text->lines.first;
- for (i = 0; i < linep; i++) {
- text->sell = text->sell->next;
- }
-
- linep = txt_undo_read_uint32(text->undo_buf, &text->undo_pos);
- //first line to be selected
-
- charp = txt_undo_read_uint16(text->undo_buf, &text->undo_pos);
- //first postion to be selected
- text->curc = charp;
- text->curl = text->lines.first;
- for (i = 0; i < linep; i++) {
- text->curl = text->curl->next;
- }
-
+ case UNDO_DUPLICATE:
+ case UNDO_MOVE_LINES_UP:
+ case UNDO_MOVE_LINES_DOWN:
+ /* get and restore the cursors */
+ txt_undo_read_cursors(text->undo_buf, &text->undo_pos, &curln, &curc, &selln, &selc);
+ txt_move_to(text, curln, curc, 0);
+ txt_move_to(text, selln, selc, 1);
if (op == UNDO_INDENT) {
txt_unindent(text);
@@ -2221,37 +2050,24 @@ void txt_do_undo(Text *text)
else if (op == UNDO_UNCOMMENT) {
txt_comment(text);
}
+ else if (op == UNDO_DUPLICATE) {
+ txt_delete_line(text, text->curl->next);
+ }
+ else if (op == UNDO_MOVE_LINES_UP) {
+ txt_move_lines(text, TXT_MOVE_LINE_DOWN);
+ }
+ else if (op == UNDO_MOVE_LINES_DOWN) {
+ txt_move_lines(text, TXT_MOVE_LINE_UP);
+ }
text->undo_pos--;
break;
- case UNDO_DUPLICATE:
- txt_delete_line(text, text->curl->next);
- break;
- case UNDO_MOVE_LINES_UP:
- txt_move_lines(text, TXT_MOVE_LINE_DOWN);
- break;
- case UNDO_MOVE_LINES_DOWN:
- txt_move_lines(text, TXT_MOVE_LINE_UP);
- break;
default:
//XXX error("Undo buffer error - resetting");
text->undo_pos = -1;
break;
}
-
- /* next undo step may need evaluating */
- if (text->undo_pos >= 0) {
- switch (text->undo_buf[text->undo_pos]) {
- case UNDO_STO:
- txt_do_undo(text);
- txt_do_redo(text); /* selections need restoring */
- break;
- case UNDO_SWAP:
- txt_do_undo(text); /* swaps should appear transparent */
- break;
- }
- }
undoing = 0;
}
@@ -2259,9 +2075,12 @@ void txt_do_undo(Text *text)
void txt_do_redo(Text *text)
{
char op;
- unsigned int linep, i;
- unsigned short charp;
char *buf;
+ unsigned int linep;
+ unsigned short charp;
+ unsigned int uchar;
+ unsigned int curln, selln;
+ unsigned short curc, selc;
text->undo_pos++;
op = text->undo_buf[text->undo_pos];
@@ -2274,104 +2093,91 @@ void txt_do_redo(Text *text)
undoing = 1;
switch (op) {
- case UNDO_CLEFT:
- txt_move_left(text, 0);
- break;
-
- case UNDO_CRIGHT:
- txt_move_right(text, 0);
- break;
+ case UNDO_INSERT_1:
+ case UNDO_INSERT_2:
+ case UNDO_INSERT_3:
+ case UNDO_INSERT_4:
+ text->undo_pos++;
- case UNDO_CUP:
- txt_move_up(text, 0);
- break;
+ /* get and restore the cursors */
+ txt_redo_read_cur(text->undo_buf, &text->undo_pos, &curln, &curc);
+ txt_move_to(text, curln, curc, 0);
+ txt_move_to(text, curln, curc, 1);
- case UNDO_CDOWN:
- txt_move_down(text, 0);
- break;
-
- case UNDO_SLEFT:
- txt_move_left(text, 1);
- break;
-
- case UNDO_SRIGHT:
- txt_move_right(text, 1);
- break;
-
- case UNDO_SUP:
- txt_move_up(text, 1);
- break;
-
- case UNDO_SDOWN:
- txt_move_down(text, 1);
- break;
-
- case UNDO_INSERT_1: case UNDO_INSERT_2: case UNDO_INSERT_3: case UNDO_INSERT_4:
- text->undo_pos++;
charp = op - UNDO_INSERT_1 + 1;
- txt_add_char(text, txt_redo_read_unicode(text->undo_buf, &text->undo_pos, charp));
- break;
+ uchar = txt_redo_read_unicode(text->undo_buf, &text->undo_pos, charp);
- case UNDO_BS_1: case UNDO_BS_2: case UNDO_BS_3: case UNDO_BS_4:
- text->undo_pos++;
- txt_backspace_char(text);
- text->undo_pos += op - UNDO_BS_1 + 1;
+ txt_add_char(text, uchar);
break;
- case UNDO_DEL_1: case UNDO_DEL_2: case UNDO_DEL_3: case UNDO_DEL_4:
+ case UNDO_BS_1:
+ case UNDO_BS_2:
+ case UNDO_BS_3:
+ case UNDO_BS_4:
text->undo_pos++;
- txt_delete_char(text);
- text->undo_pos += op - UNDO_DEL_1 + 1;
- break;
- case UNDO_SWAP:
- txt_curs_swap(text);
- txt_do_redo(text); /* swaps should appear transparent a*/
- break;
+ /* get and restore the cursors */
+ txt_redo_read_cur(text->undo_buf, &text->undo_pos, &curln, &curc);
+ txt_move_to(text, curln, curc, 0);
+ txt_move_to(text, curln, curc, 1);
+
+ text->undo_pos += op - UNDO_BS_1 + 1;
- case UNDO_CTO:
- case UNDO_STO:
- text->undo_pos++;
- text->undo_pos++;
+ /* move right so we backspace the correct char */
+ txt_move_right(text, 0);
+ txt_backspace_char(text);
- text->undo_pos++;
- text->undo_pos++;
- text->undo_pos++;
- text->undo_pos++;
+ break;
+ case UNDO_DEL_1:
+ case UNDO_DEL_2:
+ case UNDO_DEL_3:
+ case UNDO_DEL_4:
text->undo_pos++;
- charp = txt_redo_read_uint16(text->undo_buf, &text->undo_pos);
- linep = txt_redo_read_uint32(text->undo_buf, &text->undo_pos);
+ /* get and restore the cursors */
+ txt_redo_read_cur(text->undo_buf, &text->undo_pos, &curln, &curc);
+ txt_move_to(text, curln, curc, 0);
+ txt_move_to(text, curln, curc, 1);
- if (op == UNDO_CTO) {
- txt_move_toline(text, linep, 0);
- text->curc = charp;
- txt_pop_sel(text);
- }
- else {
- txt_move_toline(text, linep, 1);
- text->selc = charp;
- }
+ text->undo_pos += op - UNDO_DEL_1 + 1;
+
+ txt_delete_char(text);
break;
case UNDO_DBLOCK:
text->undo_pos++;
+
+ /* get and restore the cursors */
+ txt_redo_read_cursors(text->undo_buf, &text->undo_pos, &curln, &curc, &selln, &selc);
+ txt_move_to(text, curln, curc, 0);
+ txt_move_to(text, selln, selc, 1);
+
+ /* length of the block */
linep = txt_redo_read_uint32(text->undo_buf, &text->undo_pos);
- txt_delete_sel(text);
text->undo_pos += linep;
+ /* skip over the length that was stored again */
text->undo_pos++;
text->undo_pos++;
text->undo_pos++;
text->undo_pos++;
+ txt_delete_sel(text);
+
break;
case UNDO_IBLOCK:
text->undo_pos++;
+
+ /* get and restore the cursors */
+ txt_redo_read_cursors(text->undo_buf, &text->undo_pos, &curln, &curc, &selln, &selc);
+ txt_move_to(text, curln, curc, 0);
+ txt_move_to(text, curln, curc, 1);
+
+ /* length of the block */
linep = txt_redo_read_uint32(text->undo_buf, &text->undo_pos);
buf = MEM_mallocN(linep + 1, "iblock buffer");
@@ -2382,40 +2188,27 @@ void txt_do_redo(Text *text)
txt_insert_buf(text, buf);
MEM_freeN(buf);
+ /* skip over the length that was stored again */
text->undo_pos++;
text->undo_pos++;
text->undo_pos++;
text->undo_pos++;
+
break;
case UNDO_INDENT:
case UNDO_UNINDENT:
case UNDO_COMMENT:
case UNDO_UNCOMMENT:
+ case UNDO_DUPLICATE:
+ case UNDO_MOVE_LINES_UP:
+ case UNDO_MOVE_LINES_DOWN:
text->undo_pos++;
- charp = txt_redo_read_uint16(text->undo_buf, &text->undo_pos);
- //charp is the first char selected or 0
-
- linep = txt_redo_read_uint32(text->undo_buf, &text->undo_pos);
- //linep is now the first line of the selection
- //set the selcetion for this now
- text->curc = charp;
- text->curl = text->lines.first;
- for (i = 0; i < linep; i++) {
- text->curl = text->curl->next;
- }
-
- charp = txt_redo_read_uint16(text->undo_buf, &text->undo_pos);
- //last postion to be selected
-
- linep = txt_redo_read_uint32(text->undo_buf, &text->undo_pos);
- //Last line to be selected
-
- text->selc = charp;
- text->sell = text->lines.first;
- for (i = 0; i < linep; i++) {
- text->sell = text->sell->next;
- }
+
+ /* get and restore the cursors */
+ txt_redo_read_cursors(text->undo_buf, &text->undo_pos, &curln, &curc, &selln, &selc);
+ txt_move_to(text, curln, curc, 0);
+ txt_move_to(text, selln, selc, 1);
if (op == UNDO_INDENT) {
txt_indent(text);
@@ -2429,15 +2222,28 @@ void txt_do_redo(Text *text)
else if (op == UNDO_UNCOMMENT) {
txt_uncomment(text);
}
- break;
- case UNDO_DUPLICATE:
- txt_duplicate_line(text);
- break;
- case UNDO_MOVE_LINES_UP:
- txt_move_lines(text, TXT_MOVE_LINE_UP);
- break;
- case UNDO_MOVE_LINES_DOWN:
- txt_move_lines(text, TXT_MOVE_LINE_DOWN);
+ else if (op == UNDO_DUPLICATE) {
+ txt_duplicate_line(text);
+ }
+ else if (op == UNDO_MOVE_LINES_UP) {
+ /* offset the cursor by + 1 */
+ txt_move_to(text, curln + 1, curc, 0);
+ txt_move_to(text, selln + 1, selc, 1);
+
+ txt_move_lines(text, TXT_MOVE_LINE_UP);
+ }
+ else if (op == UNDO_MOVE_LINES_DOWN) {
+ /* offset the cursor by - 1 */
+ txt_move_to(text, curln - 1, curc, 0);
+ txt_move_to(text, selln - 1, selc, 1);
+
+ txt_move_lines(text, TXT_MOVE_LINE_DOWN);
+ }
+
+ /* re-restore the cursors since they got moved when redoing */
+ txt_move_to(text, curln, curc, 0);
+ txt_move_to(text, selln, selc, 1);
+
break;
default:
//XXX error("Undo buffer error - resetting");
@@ -2456,31 +2262,13 @@ void txt_do_redo(Text *text)
void txt_split_curline(Text *text)
{
TextLine *ins;
- TextMarker *mrk;
char *left, *right;
- int lineno = -1;
if (!text) return;
if (!text->curl) return;
txt_delete_sel(text);
- /* Move markers */
-
- lineno = txt_get_span(text->lines.first, text->curl);
- mrk = text->markers.first;
- while (mrk) {
- if (mrk->lineno == lineno && mrk->start > text->curc) {
- mrk->lineno++;
- mrk->start -= text->curc;
- mrk->end -= text->curc;
- }
- else if (mrk->lineno > lineno) {
- mrk->lineno++;
- }
- mrk = mrk->next;
- }
-
/* Make the two half strings */
left = MEM_mallocN(text->curc + 1, "textline_string");
@@ -2517,23 +2305,9 @@ void txt_split_curline(Text *text)
static void txt_delete_line(Text *text, TextLine *line)
{
- TextMarker *mrk = NULL, *nxt;
- int lineno = -1;
-
if (!text) return;
if (!text->curl) return;
- lineno = txt_get_span(text->lines.first, line);
- mrk = text->markers.first;
- while (mrk) {
- nxt = mrk->next;
- if (mrk->lineno == lineno)
- BLI_freelinkN(&text->markers, mrk);
- else if (mrk->lineno > lineno)
- mrk->lineno--;
- mrk = nxt;
- }
-
BLI_remlink(&text->lines, line);
if (line->line) MEM_freeN(line->line);
@@ -2548,25 +2322,12 @@ static void txt_delete_line(Text *text, TextLine *line)
static void txt_combine_lines(Text *text, TextLine *linea, TextLine *lineb)
{
char *tmp;
- TextMarker *mrk = NULL;
- int lineno = -1;
-
+
if (!text) return;
if (!linea || !lineb) return;
- mrk = txt_find_marker_region(text, lineb, 0, lineb->len, 0, 0);
- if (mrk) {
- lineno = mrk->lineno;
- do {
- mrk->lineno--;
- mrk->start += linea->len;
- mrk->end += linea->len;
- mrk = mrk->next;
- } while (mrk && mrk->lineno == lineno);
- }
- if (lineno == -1) lineno = txt_get_span(text->lines.first, lineb);
-
+
tmp = MEM_mallocN(linea->len + lineb->len + 1, "textline_string");
strcpy(tmp, linea->line);
@@ -2619,27 +2380,7 @@ void txt_delete_char(Text *text)
}
else { /* Just deleting a char */
size_t c_len = 0;
- TextMarker *mrk;
c = BLI_str_utf8_as_unicode_and_size(text->curl->line + text->curc, &c_len);
-
- mrk = txt_find_marker_region(text, text->curl, text->curc - c_len, text->curl->len, 0, 0);
- if (mrk) {
- int lineno = mrk->lineno;
- if (mrk->end == text->curc) {
- if ((mrk->flags & TMARK_TEMP) && !(mrk->flags & TMARK_EDITALL)) {
- txt_clear_markers(text, mrk->group, TMARK_TEMP);
- }
- else {
- BLI_freelinkN(&text->markers, mrk);
- }
- return;
- }
- do {
- if (mrk->start > text->curc) mrk->start -= c_len;
- mrk->end -= c_len;
- mrk = mrk->next;
- } while (mrk && mrk->lineno == lineno);
- }
memmove(text->curl->line + text->curc, text->curl->line + text->curc + c_len, text->curl->len - text->curc - c_len + 1);
@@ -2683,28 +2424,8 @@ void txt_backspace_char(Text *text)
}
else { /* Just backspacing a char */
size_t c_len = 0;
- TextMarker *mrk;
char *prev = BLI_str_prev_char_utf8(text->curl->line + text->curc);
c = BLI_str_utf8_as_unicode_and_size(prev, &c_len);
-
- mrk = txt_find_marker_region(text, text->curl, text->curc - c_len, text->curl->len, 0, 0);
- if (mrk) {
- int lineno = mrk->lineno;
- if (mrk->start == text->curc) {
- if ((mrk->flags & TMARK_TEMP) && !(mrk->flags & TMARK_EDITALL)) {
- txt_clear_markers(text, mrk->group, TMARK_TEMP);
- }
- else {
- BLI_freelinkN(&text->markers, mrk);
- }
- return;
- }
- do {
- if (mrk->start > text->curc - c_len) mrk->start -= c_len;
- mrk->end -= c_len;
- mrk = mrk->next;
- } while (mrk && mrk->lineno == lineno);
- }
/* source and destination overlap, don't use memcpy() */
memmove(text->curl->line + text->curc - c_len,
@@ -2746,9 +2467,7 @@ static void txt_convert_tab_to_spaces(Text *text)
static int txt_add_char_intern(Text *text, unsigned int add, int replace_tabs)
{
- int lineno;
char *tmp, ch[BLI_UTF8_MAX];
- TextMarker *mrk;
size_t add_len;
if (!text) return 0;
@@ -2767,16 +2486,9 @@ static int txt_add_char_intern(Text *text, unsigned int add, int replace_tabs)
txt_delete_sel(text);
+ if (!undoing) txt_undo_add_charop(text, UNDO_INSERT_1, add);
+
add_len = BLI_str_utf8_from_unicode(add, ch);
- mrk = txt_find_marker_region(text, text->curl, text->curc - 1, text->curl->len, 0, 0);
- if (mrk) {
- lineno = mrk->lineno;
- do {
- if (mrk->start > text->curc) mrk->start += add_len;
- mrk->end += add_len;
- mrk = mrk->next;
- } while (mrk && mrk->lineno == lineno);
- }
tmp = MEM_mallocN(text->curl->len + add_len + 1, "textline_string");
@@ -2793,7 +2505,6 @@ static int txt_add_char_intern(Text *text, unsigned int add, int replace_tabs)
txt_make_dirty(text);
txt_clean_text(text);
- if (!undoing) txt_undo_add_charop(text, UNDO_INSERT_1, add);
return 1;
}
@@ -2824,10 +2535,7 @@ int txt_replace_char(Text *text, unsigned int add)
/* If text is selected or we're at the end of the line just use txt_add_char */
if (text->curc == text->curl->len || txt_has_sel(text) || add == '\n') {
- int i = txt_add_char(text, add);
- TextMarker *mrk = txt_find_marker(text, text->curl, text->curc, 0, 0);
- if (mrk) BLI_freelinkN(&text->markers, mrk);
- return i;
+ return txt_add_char(text, add);
}
del = BLI_str_utf8_as_unicode_and_size(text->curl->line + text->curc, &del_size);
@@ -2854,8 +2562,8 @@ int txt_replace_char(Text *text, unsigned int add)
/* Should probably create a new op for this */
if (!undoing) {
- txt_undo_add_charop(text, UNDO_DEL_1, del);
txt_undo_add_charop(text, UNDO_INSERT_1, add);
+ txt_undo_add_charop(text, UNDO_DEL_1, del);
}
return 1;
}
@@ -2924,7 +2632,7 @@ void txt_indent(Text *text)
}
if (!undoing) {
- txt_undo_add_toop(text, UNDO_INDENT, txt_get_span(text->lines.first, text->curl), text->curc, txt_get_span(text->lines.first, text->sell), text->selc);
+ txt_undo_add_op(text, UNDO_INDENT);
}
}
@@ -2982,7 +2690,7 @@ void txt_unindent(Text *text)
}
if (!undoing) {
- txt_undo_add_toop(text, UNDO_UNINDENT, txt_get_span(text->lines.first, text->curl), text->curc, txt_get_span(text->lines.first, text->sell), text->selc);
+ txt_undo_add_op(text, UNDO_UNINDENT);
}
}
@@ -3031,7 +2739,7 @@ void txt_comment(Text *text)
}
if (!undoing) {
- txt_undo_add_toop(text, UNDO_COMMENT, txt_get_span(text->lines.first, text->curl), text->curc, txt_get_span(text->lines.first, text->sell), text->selc);
+ txt_undo_add_op(text, UNDO_COMMENT);
}
}
@@ -3076,7 +2784,7 @@ void txt_uncomment(Text *text)
}
if (!undoing) {
- txt_undo_add_toop(text, UNDO_UNCOMMENT, txt_get_span(text->lines.first, text->curl), text->curc, txt_get_span(text->lines.first, text->sell), text->selc);
+ txt_undo_add_op(text, UNDO_UNCOMMENT);
}
}
@@ -3165,157 +2873,6 @@ int setcurr_tab_spaces(Text *text, int space)
return i;
}
-/*********************************/
-/* Text marker utility functions */
-/*********************************/
-
-/* Creates and adds a marker to the list maintaining sorted order */
-void txt_add_marker(Text *text, TextLine *line, int start, int end, const unsigned char color[4], int group, int flags)
-{
- TextMarker *tmp, *marker;
-
- marker = MEM_mallocN(sizeof(TextMarker), "text_marker");
-
- marker->lineno = txt_get_span(text->lines.first, line);
- marker->start = MIN2(start, end);
- marker->end = MAX2(start, end);
- marker->group = group;
- marker->flags = flags;
-
- marker->color[0] = color[0];
- marker->color[1] = color[1];
- marker->color[2] = color[2];
- marker->color[3] = color[3];
-
- for (tmp = text->markers.last; tmp; tmp = tmp->prev)
- if (tmp->lineno < marker->lineno || (tmp->lineno == marker->lineno && tmp->start < marker->start))
- break;
-
- if (tmp) BLI_insertlinkafter(&text->markers, tmp, marker);
- else BLI_addhead(&text->markers, marker);
-}
-
-/* Returns the first matching marker on the specified line between two points.
- * If the group or flags fields are non-zero the returned flag must be in the
- * specified group and have at least the specified flags set. */
-TextMarker *txt_find_marker_region(Text *text, TextLine *line, int start, int end, int group, int flags)
-{
- TextMarker *marker, *next;
- int lineno = txt_get_span(text->lines.first, line);
-
- for (marker = text->markers.first; marker; marker = next) {
- next = marker->next;
-
- if (group && marker->group != group) continue;
- else if ((marker->flags & flags) != flags) continue;
- else if (marker->lineno < lineno) continue;
- else if (marker->lineno > lineno) break;
-
- if ((marker->start == marker->end && start <= marker->start && marker->start <= end) ||
- (marker->start < end && marker->end > start))
- {
- return marker;
- }
- }
- return NULL;
-}
-
-/* Clears all markers on the specified line between two points. If the group or
- * flags fields are non-zero the returned flag must be in the specified group
- * and have at least the specified flags set. */
-short txt_clear_marker_region(Text *text, TextLine *line, int start, int end, int group, int flags)
-{
- TextMarker *marker, *next;
- int lineno = txt_get_span(text->lines.first, line);
- short cleared = 0;
-
- for (marker = text->markers.first; marker; marker = next) {
- next = marker->next;
-
- if (group && marker->group != group) continue;
- else if ((marker->flags & flags) != flags) continue;
- else if (marker->lineno < lineno) continue;
- else if (marker->lineno > lineno) break;
-
- if ((marker->start == marker->end && start <= marker->start && marker->start <= end) ||
- (marker->start < end && marker->end > start))
- {
- BLI_freelinkN(&text->markers, marker);
- cleared = 1;
- }
- }
- return cleared;
-}
-
-/* Clears all markers in the specified group (if given) with at least the
- * specified flags set. Useful for clearing temporary markers (group = 0,
- * flags = TMARK_TEMP) */
-short txt_clear_markers(Text *text, int group, int flags)
-{
- TextMarker *marker, *next;
- short cleared = 0;
-
- for (marker = text->markers.first; marker; marker = next) {
- next = marker->next;
-
- if ((!group || marker->group == group) &&
- (marker->flags & flags) == flags)
- {
- BLI_freelinkN(&text->markers, marker);
- cleared = 1;
- }
- }
- return cleared;
-}
-
-/* Finds the marker at the specified line and cursor position with at least the
- * specified flags set in the given group (if non-zero). */
-TextMarker *txt_find_marker(Text *text, TextLine *line, int curs, int group, int flags)
-{
- TextMarker *marker;
- int lineno = txt_get_span(text->lines.first, line);
-
- for (marker = text->markers.first; marker; marker = marker->next) {
- if (group && marker->group != group) continue;
- else if ((marker->flags & flags) != flags) continue;
- else if (marker->lineno < lineno) continue;
- else if (marker->lineno > lineno) break;
-
- if (marker->start <= curs && curs <= marker->end)
- return marker;
- }
- return NULL;
-}
-
-/* Finds the previous marker in the same group. If no other is found, the same
- * marker will be returned */
-TextMarker *txt_prev_marker(Text *text, TextMarker *marker)
-{
- TextMarker *tmp = marker;
- while (tmp) {
- if (tmp->prev) tmp = tmp->prev;
- else tmp = text->markers.last;
- if (tmp->group == marker->group)
- return tmp;
- }
- return NULL; /* Only if (marker == NULL) */
-}
-
-/* Finds the next marker in the same group. If no other is found, the same
- * marker will be returned */
-TextMarker *txt_next_marker(Text *text, TextMarker *marker)
-{
- TextMarker *tmp = marker;
- while (tmp) {
- if (tmp->next) tmp = tmp->next;
- else tmp = text->markers.first;
- if (tmp->group == marker->group)
- return tmp;
- }
- return NULL; /* Only if (marker == NULL) */
-}
-
-
/*******************************/
/* Character utility functions */
/*******************************/
diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c
index b174f27b7e1..30b48401046 100644
--- a/source/blender/blenkernel/intern/tracking.c
+++ b/source/blender/blenkernel/intern/tracking.c
@@ -1124,10 +1124,10 @@ void BKE_tracking_marker_pattern_minmax(const MovieTrackingMarker *marker, float
{
INIT_MINMAX2(min, max);
- DO_MINMAX2(marker->pattern_corners[0], min, max);
- DO_MINMAX2(marker->pattern_corners[1], min, max);
- DO_MINMAX2(marker->pattern_corners[2], min, max);
- DO_MINMAX2(marker->pattern_corners[3], min, max);
+ minmax_v2v2_v2(min, max, marker->pattern_corners[0]);
+ minmax_v2v2_v2(min, max, marker->pattern_corners[1]);
+ minmax_v2v2_v2(min, max, marker->pattern_corners[2]);
+ minmax_v2v2_v2(min, max, marker->pattern_corners[3]);
}
void BKE_tracking_marker_get_subframe_position(MovieTrackingTrack *track, float framenr, float pos[2])
@@ -3161,7 +3161,7 @@ static int stabilization_median_point_get(MovieTracking *tracking, int framenr,
if (track->flag & TRACK_USE_2D_STAB) {
MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
- DO_MINMAX2(marker->pos, min, max);
+ minmax_v2v2_v2(min, max, marker->pos);
ok = TRUE;
}
diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c
index da9c919c109..0f861a7ed37 100644
--- a/source/blender/blenkernel/intern/writeffmpeg.c
+++ b/source/blender/blenkernel/intern/writeffmpeg.c
@@ -111,6 +111,11 @@ static void delete_picture(AVFrame *f)
}
}
+static int use_float_audio_buffer(int codec_id)
+{
+ return codec_id == CODEC_ID_AAC || codec_id == CODEC_ID_AC3 || codec_id == CODEC_ID_VORBIS;
+}
+
#ifdef WITH_AUDASPACE
static int write_audio_frame(void)
{
@@ -599,12 +604,14 @@ static AVStream *alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex
/* Prepare an audio stream for the output file */
-static AVStream *alloc_audio_stream(RenderData *rd, int codec_id, AVFormatContext *of)
+static AVStream *alloc_audio_stream(RenderData *rd, int codec_id, AVFormatContext *of, char *error, int error_size)
{
AVStream *st;
AVCodecContext *c;
AVCodec *codec;
+ error[0] = '\0';
+
st = av_new_stream(of, 1);
if (!st) return NULL;
@@ -616,6 +623,10 @@ static AVStream *alloc_audio_stream(RenderData *rd, int codec_id, AVFormatContex
c->bit_rate = ffmpeg_audio_bitrate * 1000;
c->sample_fmt = AV_SAMPLE_FMT_S16;
c->channels = rd->ffcodecdata.audio_channels;
+ if (use_float_audio_buffer(codec_id)) {
+ c->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
+ c->sample_fmt = AV_SAMPLE_FMT_FLT;
+ }
codec = avcodec_find_encoder(c->codec_id);
if (!codec) {
//XXX error("Couldn't find a valid audio codec");
@@ -626,6 +637,7 @@ static AVStream *alloc_audio_stream(RenderData *rd, int codec_id, AVFormatContex
if (avcodec_open(c, codec) < 0) {
//XXX error("Couldn't initialize audio codec");
+ BLI_strncpy(error, IMB_ffmpeg_last_error(), error_size);
return NULL;
}
@@ -646,7 +658,12 @@ static AVStream *alloc_audio_stream(RenderData *rd, int codec_id, AVFormatContex
audio_output_buffer = (uint8_t *) av_malloc(audio_outbuf_size);
- audio_input_buffer = (uint8_t *) av_malloc(audio_input_samples * c->channels * sizeof(int16_t));
+ if (use_float_audio_buffer(codec_id)) {
+ audio_input_buffer = (uint8_t *) av_malloc(audio_input_samples * c->channels * sizeof(float));
+ }
+ else {
+ audio_input_buffer = (uint8_t *) av_malloc(audio_input_samples * c->channels * sizeof(int16_t));
+ }
audio_time = 0.0f;
@@ -801,9 +818,12 @@ static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, Report
}
if (ffmpeg_audio_codec != CODEC_ID_NONE) {
- audio_stream = alloc_audio_stream(rd, fmt->audio_codec, of);
+ audio_stream = alloc_audio_stream(rd, fmt->audio_codec, of, error, sizeof(error));
if (!audio_stream) {
- BKE_report(reports, RPT_ERROR, "Error initializing audio stream");
+ if (error[0])
+ BKE_report(reports, RPT_ERROR, error);
+ else
+ BKE_report(reports, RPT_ERROR, "Error initializing audio stream");
av_dict_free(&opts);
return 0;
}
@@ -943,7 +963,12 @@ int BKE_ffmpeg_start(struct Scene *scene, RenderData *rd, int rectx, int recty,
AVCodecContext *c = audio_stream->codec;
AUD_DeviceSpecs specs;
specs.channels = c->channels;
- specs.format = AUD_FORMAT_S16;
+ if (use_float_audio_buffer(c->codec_id)) {
+ specs.format = AUD_FORMAT_FLOAT32;
+ }
+ else {
+ specs.format = AUD_FORMAT_S16;
+ }
specs.rate = rd->ffcodecdata.audio_mixrate;
audio_mixdown_device = sound_mixdown(scene, specs, rd->sfra, rd->ffcodecdata.audio_volume);
#ifdef FFMPEG_CODEC_TIME_BASE
diff --git a/source/blender/blenlib/BLI_endian_switch_inline.h b/source/blender/blenlib/BLI_endian_switch_inline.h
index 4bc6d3828b9..358206f1177 100644
--- a/source/blender/blenlib/BLI_endian_switch_inline.h
+++ b/source/blender/blenlib/BLI_endian_switch_inline.h
@@ -38,41 +38,43 @@
/* *** 16 *** */
BLI_INLINE void BLI_endian_switch_int16(short *val)
{
- short tval = *val;
- *val = (tval >> 8) |
- (tval << 8);
-
+ BLI_endian_switch_uint16((unsigned short *)val);
}
BLI_INLINE void BLI_endian_switch_uint16(unsigned short *val)
{
- BLI_endian_switch_int16((short *)val);
+ unsigned short tval = *val;
+ *val = (tval >> 8) |
+ (tval << 8);
}
/* *** 32 *** */
BLI_INLINE void BLI_endian_switch_int32(int *val)
{
- int tval = *val;
+ BLI_endian_switch_uint32((unsigned int *)val);
+}
+BLI_INLINE void BLI_endian_switch_uint32(unsigned int *val)
+{
+ unsigned int tval = *val;
*val = ((tval >> 24)) |
((tval << 8) & 0x00ff0000) |
((tval >> 8) & 0x0000ff00) |
((tval << 24));
-
-}
-BLI_INLINE void BLI_endian_switch_uint32(unsigned int *val)
-{
- BLI_endian_switch_int32((int *)val);
}
BLI_INLINE void BLI_endian_switch_float(float *val)
{
- BLI_endian_switch_int32((int *)val);
+ BLI_endian_switch_uint32((unsigned int *)val);
}
/* *** 64 *** */
BLI_INLINE void BLI_endian_switch_int64(int64_t *val)
{
- int64_t tval = *val;
+ BLI_endian_switch_uint64((uint64_t *)val);
+}
+BLI_INLINE void BLI_endian_switch_uint64(uint64_t *val)
+{
+ uint64_t tval = *val;
*val = ((tval >> 56)) |
((tval << 40) & 0x00ff000000000000ll) |
((tval << 24) & 0x0000ff0000000000ll) |
@@ -82,13 +84,9 @@ BLI_INLINE void BLI_endian_switch_int64(int64_t *val)
((tval >> 40) & 0x000000000000ff00ll) |
((tval << 56));
}
-BLI_INLINE void BLI_endian_switch_uint64(uint64_t *val)
-{
- BLI_endian_switch_int64((int64_t *)val);
-}
BLI_INLINE void BLI_endian_switch_double(double *val)
{
- BLI_endian_switch_int64((int64_t *)val);
+ BLI_endian_switch_uint64((uint64_t *)val);
}
#endif /* __BLI_ENDIAN_SWITCH_INLINE_H__ */
diff --git a/source/blender/blenlib/BLI_ghash.h b/source/blender/blenlib/BLI_ghash.h
index c26e6cd15b3..7eac1425a5c 100644
--- a/source/blender/blenlib/BLI_ghash.h
+++ b/source/blender/blenlib/BLI_ghash.h
@@ -71,7 +71,7 @@ void BLI_ghash_insert(GHash *gh, void *key, void *val);
void *BLI_ghash_lookup(GHash *gh, const void *key);
int BLI_ghash_remove(GHash *gh, void *key, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp);
void *BLI_ghash_pop(GHash *gh, void *key, GHashKeyFreeFP keyfreefp);
-int BLI_ghash_haskey(GHash *gh, void *key);
+int BLI_ghash_haskey(GHash *gh, const void *key);
int BLI_ghash_size(GHash *gh);
/* *** */
diff --git a/source/blender/blenlib/BLI_math_base.h b/source/blender/blenlib/BLI_math_base.h
index 2b513cbec41..69d6478e0e2 100644
--- a/source/blender/blenlib/BLI_math_base.h
+++ b/source/blender/blenlib/BLI_math_base.h
@@ -170,7 +170,7 @@
} (void)0
#endif
-#ifdef __BLI_MATH_INLINE_H__
+#if BLI_MATH_DO_INLINE
#include "intern/math_base_inline.c"
#endif
@@ -203,7 +203,7 @@ MINLINE int is_power_of_2_i(int n);
MINLINE int power_of_2_max_i(int n);
MINLINE int power_of_2_min_i(int n);
-MINLINE float shell_angle_to_dist(float angle);
+MINLINE float shell_angle_to_dist(const float angle);
#if (defined(WIN32) || defined(WIN64)) && !defined(FREE_WINDOWS)
extern double copysign(double x, double y);
diff --git a/source/blender/blenlib/BLI_math_color.h b/source/blender/blenlib/BLI_math_color.h
index 7c8bf88943d..c71463da61d 100644
--- a/source/blender/blenlib/BLI_math_color.h
+++ b/source/blender/blenlib/BLI_math_color.h
@@ -121,7 +121,7 @@ MINLINE int compare_rgb_uchar(const unsigned char a[3], const unsigned char b[3]
void lift_gamma_gain_to_asc_cdl(float *lift, float *gamma, float *gain, float *offset, float *slope, float *power);
-#ifdef __BLI_MATH_INLINE_H__
+#if BLI_MATH_DO_INLINE
#include "intern/math_color_inline.c"
#endif
diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h
index 80169e952bf..cfd163d4e57 100644
--- a/source/blender/blenlib/BLI_math_geom.h
+++ b/source/blender/blenlib/BLI_math_geom.h
@@ -36,7 +36,7 @@ extern "C" {
#include "BLI_math_inline.h"
-#ifdef __BLI_MATH_INLINE_H__
+#if BLI_MATH_DO_INLINE
#include "intern/math_geom_inline.c"
#endif
@@ -187,6 +187,10 @@ int barycentric_inside_triangle_v2(const float w[3]);
void resolve_tri_uv(float r_uv[2], const float st[2], const float st0[2], const float st1[2], const float st2[2]);
void resolve_quad_uv(float uv[2], const float st[2], const float st0[2], const float st1[2], const float st2[2], const float st3[2]);
+/* use to find the point of a UV on a face */
+void interp_bilinear_quad_v3(float data[4][3], float u, float v, float res[3]);
+void interp_barycentric_tri_v3(float data[3][3], float u, float v, float res[3]);
+
/***************************** View & Projection *****************************/
void lookat_m4(float mat[4][4], float vx, float vy,
diff --git a/source/blender/blenlib/BLI_math_inline.h b/source/blender/blenlib/BLI_math_inline.h
index ce43d5fb941..6dad44644f2 100644
--- a/source/blender/blenlib/BLI_math_inline.h
+++ b/source/blender/blenlib/BLI_math_inline.h
@@ -35,9 +35,10 @@ extern "C" {
#endif
/* add platform/compiler checks here if it is not supported */
-#define __BLI_MATH_INLINE_H__
+/* all platforms support forcing inline so this is always enabled */
+#define BLI_MATH_DO_INLINE 1
-#ifdef __BLI_MATH_INLINE_H__
+#if BLI_MATH_DO_INLINE
# ifdef _MSC_VER
# define MINLINE static __forceinline
# define MALWAYS_INLINE MINLINE
diff --git a/source/blender/blenlib/BLI_math_interp.h b/source/blender/blenlib/BLI_math_interp.h
index 3a107be32bd..21975763779 100644
--- a/source/blender/blenlib/BLI_math_interp.h
+++ b/source/blender/blenlib/BLI_math_interp.h
@@ -29,7 +29,16 @@
#ifndef BLI_MATH_INTERP
#define BLI_MATH_INTERP
-void BLI_bicubic_interpolation(const float *buffer, float *output, int width, int height, int components, float u, float v);
-void BLI_bilinear_interpolation(const float *buffer, float *output, int width, int height, int components, float u, float v);
+void BLI_bicubic_interpolation_fl(const float *buffer, float *output, int width, int height,
+ int components, float u, float v);
+
+void BLI_bicubic_interpolation_char(const unsigned char *buffer, unsigned char *output, int width, int height,
+ int components, float u, float v);
+
+void BLI_bilinear_interpolation_fl(const float *buffer, float *output, int width, int height,
+ int components, float u, float v);
+
+void BLI_bilinear_interpolation_char(const unsigned char *buffer, unsigned char *output, int width, int height,
+ int components, float u, float v);
#endif
diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h
index 77c0ec0a88f..f4572afec84 100644
--- a/source/blender/blenlib/BLI_math_vector.h
+++ b/source/blender/blenlib/BLI_math_vector.h
@@ -36,7 +36,7 @@ extern "C" {
#include "BLI_math_inline.h"
-#ifdef __BLI_MATH_INLINE_H__
+#if BLI_MATH_DO_INLINE
#include "intern/math_vector_inline.c"
#endif
@@ -169,6 +169,7 @@ void interp_v4_v4v4v4v4(float p[4], const float v1[4], const float v2[4], const
void mid_v3_v3v3(float r[3], const float a[3], const float b[3]);
void mid_v2_v2v2(float r[2], const float a[2], const float b[2]);
+void mid_v3_v3v3v3(float v[3], const float v1[3], const float v2[3], const float v3[3]);
/********************************* Comparison ********************************/
diff --git a/source/blender/blenlib/BLI_threads.h b/source/blender/blenlib/BLI_threads.h
index 9cd801f819d..ec8e567c0ef 100644
--- a/source/blender/blenlib/BLI_threads.h
+++ b/source/blender/blenlib/BLI_threads.h
@@ -37,6 +37,10 @@ extern "C" {
#include <pthread.h>
+#ifdef __APPLE__
+#include <libkern/OSAtomic.h>
+#endif
+
/* for tables, button in UI, etc */
#define BLENDER_MAX_THREADS 64
@@ -92,6 +96,19 @@ void BLI_mutex_lock(ThreadMutex *mutex);
void BLI_mutex_unlock(ThreadMutex *mutex);
void BLI_mutex_end(ThreadMutex *mutex);
+/* Spin Lock */
+
+#ifdef __APPLE__
+typedef OSSpinLock SpinLock;
+#else
+typedef pthread_spinlock_t SpinLock;
+#endif
+
+void BLI_spin_init(SpinLock *spin);
+void BLI_spin_lock(SpinLock *spin);
+void BLI_spin_unlock(SpinLock *spin);
+void BLI_spin_end(SpinLock *spin);
+
/* Read/Write Mutex Lock */
#define THREAD_LOCK_READ 1
diff --git a/source/blender/blenlib/BLI_utildefines.h b/source/blender/blenlib/BLI_utildefines.h
index fb064b5403f..46bb7d51d13 100644
--- a/source/blender/blenlib/BLI_utildefines.h
+++ b/source/blender/blenlib/BLI_utildefines.h
@@ -263,6 +263,15 @@
#define IN_RANGE(a, b, c) ((b < c) ? ((b < a && a < c) ? 1 : 0) : ((c < a && a < b) ? 1 : 0))
#define IN_RANGE_INCL(a, b, c) ((b < c) ? ((b <= a && a <= c) ? 1 : 0) : ((c <= a && a <= b) ? 1 : 0))
+/* unpack vector for args */
+#define UNPACK2(a) ((a)[0]), ((a)[1])
+#define UNPACK3(a) ((a)[0]), ((a)[1]), ((a)[2])
+#define UNPACK4(a) ((a)[0]), ((a)[1]), ((a)[2]), ((a)[3])
+/* op may be '&' or '*' */
+#define UNPACK2OP(a, op) op((a)[0]), op((a)[1])
+#define UNPACK3OP(a, op) op((a)[0]), op((a)[1]), op((a)[2])
+#define UNPACK4OP(a, op) op((a)[0]), op((a)[1]), op((a)[2]), op((a)[3])
+
/* array helpers */
#define ARRAY_LAST_ITEM(arr_start, arr_dtype, elem_size, tot) \
(arr_dtype *)((char *)arr_start + (elem_size * (tot - 1)))
diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt
index a6435bcbd50..10ae26d3757 100644
--- a/source/blender/blenlib/CMakeLists.txt
+++ b/source/blender/blenlib/CMakeLists.txt
@@ -174,3 +174,9 @@ if(WIN32)
endif()
blender_add_lib(bf_blenlib "${SRC}" "${INC}" "${INC_SYS}")
+
+if(MSVC)
+ # Quiet warning about inline math library files that do not export symbols.
+ # (normally you'd exclude from project, but we still want to see the files in MSVC)
+ set_target_properties(bf_blenlib PROPERTIES STATIC_LIBRARY_FLAGS /ignore:4221)
+endif()
diff --git a/source/blender/blenlib/intern/BLI_ghash.c b/source/blender/blenlib/intern/BLI_ghash.c
index 0cae9bab531..c4094920c2a 100644
--- a/source/blender/blenlib/intern/BLI_ghash.c
+++ b/source/blender/blenlib/intern/BLI_ghash.c
@@ -178,7 +178,7 @@ void *BLI_ghash_pop(GHash *gh, void *key, GHashKeyFreeFP keyfreefp)
return NULL;
}
-int BLI_ghash_haskey(GHash *gh, void *key)
+int BLI_ghash_haskey(GHash *gh, const void *key)
{
unsigned int hash = gh->hashfp(key) % gh->nbuckets;
Entry *e;
diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c
index 7968fcabda6..6cf167b8823 100644
--- a/source/blender/blenlib/intern/BLI_kdopbvh.c
+++ b/source/blender/blenlib/intern/BLI_kdopbvh.c
@@ -1410,7 +1410,7 @@ static float ray_nearest_hit(BVHRayCastData *data, const float bv[6])
* Based on Tactical Optimization of Ray/Box Intersection, by Graham Fyffe
* [http://tog.acm.org/resources/RTNews/html/rtnv21n1.html#art9]
*
- * TODO this doens't has data->ray.radius in consideration */
+ * TODO this doesn't take data->ray.radius into consideration */
static float fast_ray_nearest_hit(const BVHRayCastData *data, const BVHNode *node)
{
const float *bv = node->bv;
diff --git a/source/blender/blenlib/intern/math_base_inline.c b/source/blender/blenlib/intern/math_base_inline.c
index f27da759482..b9866f9c6e6 100644
--- a/source/blender/blenlib/intern/math_base_inline.c
+++ b/source/blender/blenlib/intern/math_base_inline.c
@@ -27,6 +27,8 @@
* \ingroup bli
*/
+#ifndef __MATH_BASE_INLINE_C__
+#define __MATH_BASE_INLINE_C__
#include <float.h>
#include <stdio.h>
@@ -35,9 +37,6 @@
#include "BLI_math.h"
-#ifndef __MATH_BASE_INLINE_C__
-#define __MATH_BASE_INLINE_C__
-
/* A few small defines. Keep'em local! */
#define SMALL_NUMBER 1.e-8f
@@ -139,6 +138,25 @@ MINLINE int power_of_2_min_i(int n)
return n;
}
+MINLINE unsigned int highest_order_bit_i(unsigned int n)
+{
+ n |= (n >> 1);
+ n |= (n >> 2);
+ n |= (n >> 4);
+ n |= (n >> 8);
+ n |= (n >> 16);
+ return n - (n >> 1);
+}
+
+MINLINE unsigned short highest_order_bit_s(unsigned short n)
+{
+ n |= (n >> 1);
+ n |= (n >> 2);
+ n |= (n >> 4);
+ n |= (n >> 8);
+ return n - (n >> 1);
+}
+
MINLINE float min_ff(float a, float b)
{
return (a < b) ? a : b;
diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c
index e10229f11da..cd726179f56 100644
--- a/source/blender/blenlib/intern/math_geom.c
+++ b/source/blender/blenlib/intern/math_geom.c
@@ -2399,6 +2399,33 @@ void resolve_quad_uv(float r_uv[2], const float st[2], const float st0[2], const
#undef IS_ZERO
+/* reverse of the functions above */
+void interp_bilinear_quad_v3(float data[4][3], float u, float v, float res[3])
+{
+ float vec[3];
+
+ copy_v3_v3(res, data[0]);
+ mul_v3_fl(res, (1 - u) * (1 - v));
+ copy_v3_v3(vec, data[1]);
+ mul_v3_fl(vec, u * (1 - v)); add_v3_v3(res, vec);
+ copy_v3_v3(vec, data[2]);
+ mul_v3_fl(vec, u * v); add_v3_v3(res, vec);
+ copy_v3_v3(vec, data[3]);
+ mul_v3_fl(vec, (1 - u) * v); add_v3_v3(res, vec);
+}
+
+void interp_barycentric_tri_v3(float data[3][3], float u, float v, float res[3])
+{
+ float vec[3];
+
+ copy_v3_v3(res, data[0]);
+ mul_v3_fl(res, u);
+ copy_v3_v3(vec, data[1]);
+ mul_v3_fl(vec, v); add_v3_v3(res, vec);
+ copy_v3_v3(vec, data[2]);
+ mul_v3_fl(vec, 1.0f - u - v); add_v3_v3(res, vec);
+}
+
/***************************** View & Projection *****************************/
void orthographic_m4(float matrix[][4], const float left, const float right, const float bottom, const float top,
diff --git a/source/blender/blenlib/intern/math_geom_inline.c b/source/blender/blenlib/intern/math_geom_inline.c
index 01585c93bc8..ba9770e1bd1 100644
--- a/source/blender/blenlib/intern/math_geom_inline.c
+++ b/source/blender/blenlib/intern/math_geom_inline.c
@@ -27,11 +27,12 @@
* \ingroup bli
*/
+#ifndef __MATH_GEOM_INLINE_C__
+#define __MATH_GEOM_INLINE_C__
#include "BLI_math.h"
-#ifndef __MATH_GEOM_INLINE_C__
-#define __MATH_GEOM_INLINE_C__
+#include <string.h>
/****************************** Spherical Harmonics **************************/
diff --git a/source/blender/blenlib/intern/math_interp.c b/source/blender/blenlib/intern/math_interp.c
index 742669354a9..5a9e8244a46 100644
--- a/source/blender/blenlib/intern/math_interp.c
+++ b/source/blender/blenlib/intern/math_interp.c
@@ -60,12 +60,44 @@ static float P(float k)
}
#endif
+static void vector_from_float(const float *data, float vector[4], int components)
+{
+ if (components == 1) {
+ vector[0] = data[0];
+ }
+ else if (components == 3) {
+ copy_v3_v3(vector, data);
+ }
+ else {
+ copy_v4_v4(vector, data);
+ }
+}
+
+static void vector_from_byte(const unsigned char *data, float vector[4], int components)
+{
+ if (components == 1) {
+ vector[0] = data[0];
+ }
+ else if (components == 3) {
+ vector[0] = data[0];
+ vector[1] = data[1];
+ vector[2] = data[2];
+ }
+ else {
+ vector[0] = data[0];
+ vector[1] = data[1];
+ vector[2] = data[2];
+ vector[3] = data[3];
+ }
+}
+
/* BICUBIC INTERPOLATION */
-void BLI_bicubic_interpolation(const float *buffer, float *output, int width, int height, int components, float u, float v)
+BLI_INLINE void bicubic_interpolation(const unsigned char *byte_buffer, const float *float_buffer,
+ unsigned char *byte_output, float *float_output, int width, int height,
+ int components, float u, float v)
{
int i, j, n, m, x1, y1;
float a, b, w, wx, wy[4], out[4];
- const float *data;
/* sample area entirely outside image? */
if (ceil(u) < 0 || floor(u) > width - 1 || ceil(v) < 0 || floor(v) > height - 1) {
@@ -92,6 +124,8 @@ void BLI_bicubic_interpolation(const float *buffer, float *output, int width, in
CLAMP(x1, 0, width - 1);
wx = P(n - a);
for (m = -1; m <= 2; m++) {
+ float data[4];
+
y1 = j + m;
CLAMP(y1, 0, height - 1);
/* normally we could do this */
@@ -99,14 +133,19 @@ void BLI_bicubic_interpolation(const float *buffer, float *output, int width, in
/* except that would call P() 16 times per pixel therefor pow() 64 times, better precalc these */
w = wx * wy[m + 1];
- data = buffer + width * y1 * 4 + 4 * x1;
+ if (float_output) {
+ const float *float_data = float_buffer + width * y1 * components + components * x1;
- if (components == 1) {
- out[0] += data[0] * w;
+ vector_from_float(float_data, data, components);
+ }
+ else {
+ const unsigned char *byte_data = byte_buffer + width * y1 * components + components * x1;
+
+ vector_from_byte(byte_data, data, components);
}
- else if (components == 2) {
+
+ if (components == 1) {
out[0] += data[0] * w;
- out[1] += data[1] * w;
}
else if (components == 3) {
out[0] += data[0] * w;
@@ -131,14 +170,21 @@ void BLI_bicubic_interpolation(const float *buffer, float *output, int width, in
x1 = i + n;
y1 = j + m;
if (x1 > 0 && x1 < width && y1 > 0 && y1 < height) {
- data = in->rect_float + width * y1 * 4 + 4 * x1;
+ float data[4];
- if (components == 1) {
- out[0] += data[0] * P(n - a) * P(b - m);
+ if (float_output) {
+ const float *float_data = float_buffer + width * y1 * components + components * x1;
+
+ vector_from_float(float_data, data, components);
}
- else if (components == 2) {
+ else {
+ const unsigned char *byte_data = byte_buffer + width * y1 * components + components * x1;
+
+ vector_from_byte(byte_data, data, components);
+ }
+
+ if (components == 1) {
out[0] += data[0] * P(n - a) * P(b - m);
- out[1] += data[1] * P(n - a) * P(b - m);
}
else if (components == 3) {
out[0] += data[0] * P(n - a) * P(b - m);
@@ -156,33 +202,54 @@ void BLI_bicubic_interpolation(const float *buffer, float *output, int width, in
}
#endif
- if (components == 1) {
- output[0] = out[0];
- }
- else if (components == 2) {
- output[0] = out[0];
- output[1] = out[1];
- }
- else if (components == 3) {
- output[0] = out[0];
- output[1] = out[1];
- output[2] = out[2];
+ if (float_output) {
+ if (components == 1) {
+ float_output[0] = out[0];
+ }
+ else if (components == 3) {
+ copy_v3_v3(float_output, out);
+ }
+ else {
+ copy_v4_v4(float_output, out);
+ }
}
else {
- output[0] = out[0];
- output[1] = out[1];
- output[2] = out[2];
- output[3] = out[3];
+ if (components == 1) {
+ byte_output[0] = out[0];
+ }
+ else if (components == 3) {
+ byte_output[0] = out[0];
+ byte_output[1] = out[1];
+ byte_output[2] = out[2];
+ }
+ else {
+ byte_output[0] = out[0];
+ byte_output[1] = out[1];
+ byte_output[2] = out[2];
+ byte_output[3] = out[3];
+ }
}
}
+void BLI_bicubic_interpolation_fl(const float *buffer, float *output, int width, int height,
+ int components, float u, float v)
+{
+ bicubic_interpolation(NULL, buffer, NULL, output, width, height, components, u, v);
+}
+
+void BLI_bicubic_interpolation_char(const unsigned char *buffer, unsigned char *output, int width, int height,
+ int components, float u, float v)
+{
+ bicubic_interpolation(buffer, NULL, output, NULL, width, height, components, u, v);
+}
+
/* BILINEAR INTERPOLATION */
-void BLI_bilinear_interpolation(const float *buffer, float *output, int width, int height, int components, float u, float v)
+BLI_INLINE void bilinear_interpolation(const unsigned char *byte_buffer, const float *float_buffer,
+ unsigned char *byte_output, float *float_output, int width, int height,
+ int components, float u, float v)
{
- const float *row1, *row2, *row3, *row4;
float a, b;
float a_b, ma_b, a_mb, ma_mb;
- float empty[4] = {0.0f, 0.0f, 0.0f, 0.0f};
int y1, y2, x1, x2;
/* ImBuf in must have a valid rect or rect_float, assume this is already checked */
@@ -197,39 +264,88 @@ void BLI_bilinear_interpolation(const float *buffer, float *output, int width, i
return;
}
- /* sample including outside of edges of image */
- if (x1 < 0 || y1 < 0) row1 = empty;
- else row1 = buffer + width * y1 * 4 + 4 * x1;
+ if (float_output) {
+ const float *row1, *row2, *row3, *row4;
+ float empty[4] = {0.0f, 0.0f, 0.0f, 0.0f};
- if (x1 < 0 || y2 > height - 1) row2 = empty;
- else row2 = buffer + width * y2 * 4 + 4 * x1;
+ /* sample including outside of edges of image */
+ if (x1 < 0 || y1 < 0) row1 = empty;
+ else row1 = float_buffer + width * y1 * components + components * x1;
- if (x2 > width - 1 || y1 < 0) row3 = empty;
- else row3 = buffer + width * y1 * 4 + 4 * x2;
+ if (x1 < 0 || y2 > height - 1) row2 = empty;
+ else row2 = float_buffer + width * y2 * components + components * x1;
- if (x2 > width - 1 || y2 > height - 1) row4 = empty;
- else row4 = buffer + width * y2 * 4 + 4 * x2;
+ if (x2 > width - 1 || y1 < 0) row3 = empty;
+ else row3 = float_buffer + width * y1 * components + components * x2;
- a = u - floorf(u);
- b = v - floorf(v);
- a_b = a * b; ma_b = (1.0f - a) * b; a_mb = a * (1.0f - b); ma_mb = (1.0f - a) * (1.0f - b);
+ if (x2 > width - 1 || y2 > height - 1) row4 = empty;
+ else row4 = float_buffer + width * y2 * components + components * x2;
- if (components == 1) {
- output[0] = ma_mb * row1[0] + a_mb * row3[0] + ma_b * row2[0] + a_b * row4[0];
- }
- else if (components == 2) {
- output[0] = ma_mb * row1[0] + a_mb * row3[0] + ma_b * row2[0] + a_b * row4[0];
- output[1] = ma_mb * row1[1] + a_mb * row3[1] + ma_b * row2[1] + a_b * row4[1];
- }
- else if (components == 3) {
- output[0] = ma_mb * row1[0] + a_mb * row3[0] + ma_b * row2[0] + a_b * row4[0];
- output[1] = ma_mb * row1[1] + a_mb * row3[1] + ma_b * row2[1] + a_b * row4[1];
- output[2] = ma_mb * row1[2] + a_mb * row3[2] + ma_b * row2[2] + a_b * row4[2];
+ a = u - floorf(u);
+ b = v - floorf(v);
+ a_b = a * b; ma_b = (1.0f - a) * b; a_mb = a * (1.0f - b); ma_mb = (1.0f - a) * (1.0f - b);
+
+ if (components == 1) {
+ float_output[0] = ma_mb * row1[0] + a_mb * row3[0] + ma_b * row2[0] + a_b * row4[0];
+ }
+ else if (components == 3) {
+ float_output[0] = ma_mb * row1[0] + a_mb * row3[0] + ma_b * row2[0] + a_b * row4[0];
+ float_output[1] = ma_mb * row1[1] + a_mb * row3[1] + ma_b * row2[1] + a_b * row4[1];
+ float_output[2] = ma_mb * row1[2] + a_mb * row3[2] + ma_b * row2[2] + a_b * row4[2];
+ }
+ else {
+ float_output[0] = ma_mb * row1[0] + a_mb * row3[0] + ma_b * row2[0] + a_b * row4[0];
+ float_output[1] = ma_mb * row1[1] + a_mb * row3[1] + ma_b * row2[1] + a_b * row4[1];
+ float_output[2] = ma_mb * row1[2] + a_mb * row3[2] + ma_b * row2[2] + a_b * row4[2];
+ float_output[3] = ma_mb * row1[3] + a_mb * row3[3] + ma_b * row2[3] + a_b * row4[3];
+ }
}
else {
- output[0] = ma_mb * row1[0] + a_mb * row3[0] + ma_b * row2[0] + a_b * row4[0];
- output[1] = ma_mb * row1[1] + a_mb * row3[1] + ma_b * row2[1] + a_b * row4[1];
- output[2] = ma_mb * row1[2] + a_mb * row3[2] + ma_b * row2[2] + a_b * row4[2];
- output[3] = ma_mb * row1[3] + a_mb * row3[3] + ma_b * row2[3] + a_b * row4[3];
+ const unsigned char *row1, *row2, *row3, *row4;
+ unsigned char empty[4] = {0, 0, 0, 0};
+
+ /* sample including outside of edges of image */
+ if (x1 < 0 || y1 < 0) row1 = empty;
+ else row1 = byte_buffer + width * y1 * components + components * x1;
+
+ if (x1 < 0 || y2 > height - 1) row2 = empty;
+ else row2 = byte_buffer + width * y2 * components + components * x1;
+
+ if (x2 > width - 1 || y1 < 0) row3 = empty;
+ else row3 = byte_buffer + width * y1 * components + components * x2;
+
+ if (x2 > width - 1 || y2 > height - 1) row4 = empty;
+ else row4 = byte_buffer + width * y2 * components + components * x2;
+
+ a = u - floorf(u);
+ b = v - floorf(v);
+ a_b = a * b; ma_b = (1.0f - a) * b; a_mb = a * (1.0f - b); ma_mb = (1.0f - a) * (1.0f - b);
+
+ if (components == 1) {
+ byte_output[0] = ma_mb * row1[0] + a_mb * row3[0] + ma_b * row2[0] + a_b * row4[0];
+ }
+ else if (components == 3) {
+ byte_output[0] = ma_mb * row1[0] + a_mb * row3[0] + ma_b * row2[0] + a_b * row4[0];
+ byte_output[1] = ma_mb * row1[1] + a_mb * row3[1] + ma_b * row2[1] + a_b * row4[1];
+ byte_output[2] = ma_mb * row1[2] + a_mb * row3[2] + ma_b * row2[2] + a_b * row4[2];
+ }
+ else {
+ byte_output[0] = ma_mb * row1[0] + a_mb * row3[0] + ma_b * row2[0] + a_b * row4[0];
+ byte_output[1] = ma_mb * row1[1] + a_mb * row3[1] + ma_b * row2[1] + a_b * row4[1];
+ byte_output[2] = ma_mb * row1[2] + a_mb * row3[2] + ma_b * row2[2] + a_b * row4[2];
+ byte_output[3] = ma_mb * row1[3] + a_mb * row3[3] + ma_b * row2[3] + a_b * row4[3];
+ }
}
}
+
+void BLI_bilinear_interpolation_fl(const float *buffer, float *output, int width, int height,
+ int components, float u, float v)
+{
+ bilinear_interpolation(NULL, buffer, NULL, output, width, height, components, u, v);
+}
+
+void BLI_bilinear_interpolation_char(const unsigned char *buffer, unsigned char *output, int width, int height,
+ int components, float u, float v)
+{
+ bilinear_interpolation(buffer, NULL, output, NULL, width, height, components, u, v);
+}
diff --git a/source/blender/blenlib/intern/math_rotation.c b/source/blender/blenlib/intern/math_rotation.c
index b0c4724e1ec..3069542107e 100644
--- a/source/blender/blenlib/intern/math_rotation.c
+++ b/source/blender/blenlib/intern/math_rotation.c
@@ -84,7 +84,7 @@ void mul_qt_qtqt(float q[4], const float q1[4], const float q2[4])
* \note:
* Assumes a unit quaternion?
*
- * in fact not, but you may wan't to use a unit quat, read on...
+ * in fact not, but you may want to use a unit quat, read on...
*
* Shortcut for 'q v q*' when \a v is actually a quaternion.
* This removes the need for converting a vector to a quaternion,
diff --git a/source/blender/blenlib/intern/math_vector.c b/source/blender/blenlib/intern/math_vector.c
index 976895fe6fc..812e2b3e63d 100644
--- a/source/blender/blenlib/intern/math_vector.c
+++ b/source/blender/blenlib/intern/math_vector.c
@@ -115,6 +115,13 @@ void mid_v2_v2v2(float v[2], const float v1[2], const float v2[2])
v[1] = 0.5f * (v1[1] + v2[1]);
}
+void mid_v3_v3v3v3(float v[3], const float v1[3], const float v2[3], const float v3[3])
+{
+ v[0] = (v1[0] + v2[0] + v3[0]) / 3.0f;
+ v[1] = (v1[1] + v2[1] + v3[1]) / 3.0f;
+ v[2] = (v1[2] + v2[2] + v3[2]) / 3.0f;
+}
+
/********************************** Angles ***********************************/
/* Return the angle in radians between vecs 1-2 and 2-3 in radians
@@ -201,6 +208,13 @@ float angle_signed_v2v2(const float v1[2], const float v2[2])
float angle_normalized_v3v3(const float v1[3], const float v2[3])
{
+ /* double check they are normalized */
+#ifdef DEBUG
+ float test;
+ BLI_assert(fabsf((test = len_squared_v3(v1)) - 1.0f) < 0.0001f || fabsf(test) < 0.0001f);
+ BLI_assert(fabsf((test = len_squared_v3(v2)) - 1.0f) < 0.0001f || fabsf(test) < 0.0001f);
+#endif
+
/* this is the same as acos(dot_v3v3(v1, v2)), but more accurate */
if (dot_v3v3(v1, v2) < 0.0f) {
float vec[3];
@@ -217,6 +231,13 @@ float angle_normalized_v3v3(const float v1[3], const float v2[3])
float angle_normalized_v2v2(const float v1[2], const float v2[2])
{
+ /* double check they are normalized */
+#ifdef DEBUG
+ float test;
+ BLI_assert(fabsf((test = len_squared_v2(v1)) - 1.0f) < 0.0001f || fabsf(test) < 0.0001f);
+ BLI_assert(fabsf((test = len_squared_v2(v2)) - 1.0f) < 0.0001f || fabsf(test) < 0.0001f);
+#endif
+
/* this is the same as acos(dot_v3v3(v1, v2)), but more accurate */
if (dot_v2v2(v1, v2) < 0.0f) {
float vec[2];
@@ -401,6 +422,12 @@ void rotate_normalized_v3_v3v3fl(float r[3], const float p[3], const float axis[
const float costheta = cos(angle);
const float sintheta = sin(angle);
+ /* double check they are normalized */
+#ifdef DEBUG
+ float test;
+ BLI_assert(fabsf((test = len_squared_v3(axis)) - 1.0f) < 0.0001f || fabsf(test) < 0.0001f);
+#endif
+
r[0] = ((costheta + (1 - costheta) * axis[0] * axis[0]) * p[0]) +
(((1 - costheta) * axis[0] * axis[1] - axis[2] * sintheta) * p[1]) +
(((1 - costheta) * axis[0] * axis[2] + axis[1] * sintheta) * p[2]);
diff --git a/source/blender/blenlib/intern/math_vector_inline.c b/source/blender/blenlib/intern/math_vector_inline.c
index d96beadd63b..84e4c513e12 100644
--- a/source/blender/blenlib/intern/math_vector_inline.c
+++ b/source/blender/blenlib/intern/math_vector_inline.c
@@ -27,12 +27,11 @@
* \ingroup bli
*/
-
-#include "BLI_math.h"
-
#ifndef __MATH_VECTOR_INLINE_C__
#define __MATH_VECTOR_INLINE_C__
+#include "BLI_math.h"
+
/********************************** Init *************************************/
MINLINE void zero_v2(float r[2])
diff --git a/source/blender/blenlib/intern/noise.c b/source/blender/blenlib/intern/noise.c
index fb33d7ce127..f37e1e03f39 100644
--- a/source/blender/blenlib/intern/noise.c
+++ b/source/blender/blenlib/intern/noise.c
@@ -398,7 +398,8 @@ static float orgBlenderNoise(float x, float y, float z)
h = hashvectf + 3 * hash[b21 + b11];
n += i * (h[0] * jx + h[1] * jy + h[2] * jz);
- if (n < 0.0f) n = 0.0f; else if (n > 1.0f) n = 1.0f;
+ if (n < 0.0f) n = 0.0f;
+ else if (n > 1.0f) n = 1.0f;
return n;
}
@@ -456,16 +457,50 @@ float BLI_turbulence1(float noisesize, float x, float y, float z, int nr)
/* ********************* FROM PERLIN HIMSELF: ******************** */
-static char p[512 + 2] = {
- 0xA2, 0xA0, 0x19, 0x3B, 0xF8, 0xEB, 0xAA, 0xEE, 0xF3, 0x1C, 0x67, 0x28, 0x1D, 0xED, 0x0, 0xDE, 0x95, 0x2E, 0xDC, 0x3F, 0x3A, 0x82, 0x35, 0x4D, 0x6C, 0xBA, 0x36, 0xD0, 0xF6, 0xC, 0x79, 0x32, 0xD1, 0x59, 0xF4, 0x8, 0x8B, 0x63, 0x89, 0x2F, 0xB8, 0xB4, 0x97, 0x83, 0xF2, 0x8F, 0x18, 0xC7, 0x51, 0x14, 0x65, 0x87, 0x48, 0x20, 0x42, 0xA8, 0x80, 0xB5, 0x40, 0x13, 0xB2, 0x22, 0x7E, 0x57,
- 0xBC, 0x7F, 0x6B, 0x9D, 0x86, 0x4C, 0xC8, 0xDB, 0x7C, 0xD5, 0x25, 0x4E, 0x5A, 0x55, 0x74, 0x50, 0xCD, 0xB3, 0x7A, 0xBB, 0xC3, 0xCB, 0xB6, 0xE2, 0xE4, 0xEC, 0xFD, 0x98, 0xB, 0x96, 0xD3, 0x9E, 0x5C, 0xA1, 0x64, 0xF1, 0x81, 0x61, 0xE1, 0xC4, 0x24, 0x72, 0x49, 0x8C, 0x90, 0x4B, 0x84, 0x34, 0x38, 0xAB, 0x78, 0xCA, 0x1F, 0x1, 0xD7, 0x93, 0x11, 0xC1, 0x58, 0xA9, 0x31, 0xF9, 0x44, 0x6D,
- 0xBF, 0x33, 0x9C, 0x5F, 0x9, 0x94, 0xA3, 0x85, 0x6, 0xC6, 0x9A, 0x1E, 0x7B, 0x46, 0x15, 0x30, 0x27, 0x2B, 0x1B, 0x71, 0x3C, 0x5B, 0xD6, 0x6F, 0x62, 0xAC, 0x4F, 0xC2, 0xC0, 0xE, 0xB1, 0x23, 0xA7, 0xDF, 0x47, 0xB0, 0x77, 0x69, 0x5, 0xE9, 0xE6, 0xE7, 0x76, 0x73, 0xF, 0xFE, 0x6E, 0x9B, 0x56, 0xEF, 0x12, 0xA5, 0x37, 0xFC, 0xAE, 0xD9, 0x3, 0x8E, 0xDD, 0x10, 0xB9, 0xCE, 0xC9, 0x8D,
- 0xDA, 0x2A, 0xBD, 0x68, 0x17, 0x9F, 0xBE, 0xD4, 0xA, 0xCC, 0xD2, 0xE8, 0x43, 0x3D, 0x70, 0xB7, 0x2, 0x7D, 0x99, 0xD8, 0xD, 0x60, 0x8A, 0x4, 0x2C, 0x3E, 0x92, 0xE5, 0xAF, 0x53, 0x7, 0xE0, 0x29, 0xA6, 0xC5, 0xE3, 0xF5, 0xF7, 0x4A, 0x41, 0x26, 0x6A, 0x16, 0x5E, 0x52, 0x2D, 0x21, 0xAD, 0xF0, 0x91, 0xFF, 0xEA, 0x54, 0xFA, 0x66, 0x1A, 0x45, 0x39, 0xCF, 0x75, 0xA4, 0x88, 0xFB, 0x5D,
- 0xA2, 0xA0, 0x19, 0x3B, 0xF8, 0xEB, 0xAA, 0xEE, 0xF3, 0x1C, 0x67, 0x28, 0x1D, 0xED, 0x0, 0xDE, 0x95, 0x2E, 0xDC, 0x3F, 0x3A, 0x82, 0x35, 0x4D, 0x6C, 0xBA, 0x36, 0xD0, 0xF6, 0xC, 0x79, 0x32, 0xD1, 0x59, 0xF4, 0x8, 0x8B, 0x63, 0x89, 0x2F, 0xB8, 0xB4, 0x97, 0x83, 0xF2, 0x8F, 0x18, 0xC7, 0x51, 0x14, 0x65, 0x87, 0x48, 0x20, 0x42, 0xA8, 0x80, 0xB5, 0x40, 0x13, 0xB2, 0x22, 0x7E, 0x57,
- 0xBC, 0x7F, 0x6B, 0x9D, 0x86, 0x4C, 0xC8, 0xDB, 0x7C, 0xD5, 0x25, 0x4E, 0x5A, 0x55, 0x74, 0x50, 0xCD, 0xB3, 0x7A, 0xBB, 0xC3, 0xCB, 0xB6, 0xE2, 0xE4, 0xEC, 0xFD, 0x98, 0xB, 0x96, 0xD3, 0x9E, 0x5C, 0xA1, 0x64, 0xF1, 0x81, 0x61, 0xE1, 0xC4, 0x24, 0x72, 0x49, 0x8C, 0x90, 0x4B, 0x84, 0x34, 0x38, 0xAB, 0x78, 0xCA, 0x1F, 0x1, 0xD7, 0x93, 0x11, 0xC1, 0x58, 0xA9, 0x31, 0xF9, 0x44, 0x6D,
- 0xBF, 0x33, 0x9C, 0x5F, 0x9, 0x94, 0xA3, 0x85, 0x6, 0xC6, 0x9A, 0x1E, 0x7B, 0x46, 0x15, 0x30, 0x27, 0x2B, 0x1B, 0x71, 0x3C, 0x5B, 0xD6, 0x6F, 0x62, 0xAC, 0x4F, 0xC2, 0xC0, 0xE, 0xB1, 0x23, 0xA7, 0xDF, 0x47, 0xB0, 0x77, 0x69, 0x5, 0xE9, 0xE6, 0xE7, 0x76, 0x73, 0xF, 0xFE, 0x6E, 0x9B, 0x56, 0xEF, 0x12, 0xA5, 0x37, 0xFC, 0xAE, 0xD9, 0x3, 0x8E, 0xDD, 0x10, 0xB9, 0xCE, 0xC9, 0x8D,
- 0xDA, 0x2A, 0xBD, 0x68, 0x17, 0x9F, 0xBE, 0xD4, 0xA, 0xCC, 0xD2, 0xE8, 0x43, 0x3D, 0x70, 0xB7, 0x2, 0x7D, 0x99, 0xD8, 0xD, 0x60, 0x8A, 0x4, 0x2C, 0x3E, 0x92, 0xE5, 0xAF, 0x53, 0x7, 0xE0, 0x29, 0xA6, 0xC5, 0xE3, 0xF5, 0xF7, 0x4A, 0x41, 0x26, 0x6A, 0x16, 0x5E, 0x52, 0x2D, 0x21, 0xAD, 0xF0, 0x91, 0xFF, 0xEA, 0x54, 0xFA, 0x66, 0x1A, 0x45, 0x39, 0xCF, 0x75, 0xA4, 0x88, 0xFB, 0x5D,
- 0xA2, 0xA0
+static const char p[512 + 2] = {
+ 0xA2, 0xA0, 0x19, 0x3B, 0xF8, 0xEB, 0xAA, 0xEE, 0xF3, 0x1C, 0x67, 0x28,
+ 0x1D, 0xED, 0x0, 0xDE, 0x95, 0x2E, 0xDC, 0x3F, 0x3A, 0x82, 0x35, 0x4D,
+ 0x6C, 0xBA, 0x36, 0xD0, 0xF6, 0xC, 0x79, 0x32, 0xD1, 0x59, 0xF4, 0x8,
+ 0x8B, 0x63, 0x89, 0x2F, 0xB8, 0xB4, 0x97, 0x83, 0xF2, 0x8F, 0x18, 0xC7,
+ 0x51, 0x14, 0x65, 0x87, 0x48, 0x20, 0x42, 0xA8, 0x80, 0xB5, 0x40, 0x13,
+ 0xB2, 0x22, 0x7E, 0x57, 0xBC, 0x7F, 0x6B, 0x9D, 0x86, 0x4C, 0xC8, 0xDB,
+ 0x7C, 0xD5, 0x25, 0x4E, 0x5A, 0x55, 0x74, 0x50, 0xCD, 0xB3, 0x7A, 0xBB,
+ 0xC3, 0xCB, 0xB6, 0xE2, 0xE4, 0xEC, 0xFD, 0x98, 0xB, 0x96, 0xD3, 0x9E,
+ 0x5C, 0xA1, 0x64, 0xF1, 0x81, 0x61, 0xE1, 0xC4, 0x24, 0x72, 0x49, 0x8C,
+ 0x90, 0x4B, 0x84, 0x34, 0x38, 0xAB, 0x78, 0xCA, 0x1F, 0x1, 0xD7, 0x93,
+ 0x11, 0xC1, 0x58, 0xA9, 0x31, 0xF9, 0x44, 0x6D, 0xBF, 0x33, 0x9C, 0x5F,
+ 0x9, 0x94, 0xA3, 0x85, 0x6, 0xC6, 0x9A, 0x1E, 0x7B, 0x46, 0x15, 0x30,
+ 0x27, 0x2B, 0x1B, 0x71, 0x3C, 0x5B, 0xD6, 0x6F, 0x62, 0xAC, 0x4F, 0xC2,
+ 0xC0, 0xE, 0xB1, 0x23, 0xA7, 0xDF, 0x47, 0xB0, 0x77, 0x69, 0x5, 0xE9,
+ 0xE6, 0xE7, 0x76, 0x73, 0xF, 0xFE, 0x6E, 0x9B, 0x56, 0xEF, 0x12, 0xA5,
+ 0x37, 0xFC, 0xAE, 0xD9, 0x3, 0x8E, 0xDD, 0x10, 0xB9, 0xCE, 0xC9, 0x8D,
+ 0xDA, 0x2A, 0xBD, 0x68, 0x17, 0x9F, 0xBE, 0xD4, 0xA, 0xCC, 0xD2, 0xE8,
+ 0x43, 0x3D, 0x70, 0xB7, 0x2, 0x7D, 0x99, 0xD8, 0xD, 0x60, 0x8A, 0x4,
+ 0x2C, 0x3E, 0x92, 0xE5, 0xAF, 0x53, 0x7, 0xE0, 0x29, 0xA6, 0xC5, 0xE3,
+ 0xF5, 0xF7, 0x4A, 0x41, 0x26, 0x6A, 0x16, 0x5E, 0x52, 0x2D, 0x21, 0xAD,
+ 0xF0, 0x91, 0xFF, 0xEA, 0x54, 0xFA, 0x66, 0x1A, 0x45, 0x39, 0xCF, 0x75,
+ 0xA4, 0x88, 0xFB, 0x5D, 0xA2, 0xA0, 0x19, 0x3B, 0xF8, 0xEB, 0xAA, 0xEE,
+ 0xF3, 0x1C, 0x67, 0x28, 0x1D, 0xED, 0x0, 0xDE, 0x95, 0x2E, 0xDC, 0x3F,
+ 0x3A, 0x82, 0x35, 0x4D, 0x6C, 0xBA, 0x36, 0xD0, 0xF6, 0xC, 0x79, 0x32,
+ 0xD1, 0x59, 0xF4, 0x8, 0x8B, 0x63, 0x89, 0x2F, 0xB8, 0xB4, 0x97, 0x83,
+ 0xF2, 0x8F, 0x18, 0xC7, 0x51, 0x14, 0x65, 0x87, 0x48, 0x20, 0x42, 0xA8,
+ 0x80, 0xB5, 0x40, 0x13, 0xB2, 0x22, 0x7E, 0x57, 0xBC, 0x7F, 0x6B, 0x9D,
+ 0x86, 0x4C, 0xC8, 0xDB, 0x7C, 0xD5, 0x25, 0x4E, 0x5A, 0x55, 0x74, 0x50,
+ 0xCD, 0xB3, 0x7A, 0xBB, 0xC3, 0xCB, 0xB6, 0xE2, 0xE4, 0xEC, 0xFD, 0x98,
+ 0xB, 0x96, 0xD3, 0x9E, 0x5C, 0xA1, 0x64, 0xF1, 0x81, 0x61, 0xE1, 0xC4,
+ 0x24, 0x72, 0x49, 0x8C, 0x90, 0x4B, 0x84, 0x34, 0x38, 0xAB, 0x78, 0xCA,
+ 0x1F, 0x1, 0xD7, 0x93, 0x11, 0xC1, 0x58, 0xA9, 0x31, 0xF9, 0x44, 0x6D,
+ 0xBF, 0x33, 0x9C, 0x5F, 0x9, 0x94, 0xA3, 0x85, 0x6, 0xC6, 0x9A, 0x1E,
+ 0x7B, 0x46, 0x15, 0x30, 0x27, 0x2B, 0x1B, 0x71, 0x3C, 0x5B, 0xD6, 0x6F,
+ 0x62, 0xAC, 0x4F, 0xC2, 0xC0, 0xE, 0xB1, 0x23, 0xA7, 0xDF, 0x47, 0xB0,
+ 0x77, 0x69, 0x5, 0xE9, 0xE6, 0xE7, 0x76, 0x73, 0xF, 0xFE, 0x6E, 0x9B,
+ 0x56, 0xEF, 0x12, 0xA5, 0x37, 0xFC, 0xAE, 0xD9, 0x3, 0x8E, 0xDD, 0x10,
+ 0xB9, 0xCE, 0xC9, 0x8D, 0xDA, 0x2A, 0xBD, 0x68, 0x17, 0x9F, 0xBE, 0xD4,
+ 0xA, 0xCC, 0xD2, 0xE8, 0x43, 0x3D, 0x70, 0xB7, 0x2, 0x7D, 0x99, 0xD8,
+ 0xD, 0x60, 0x8A, 0x4, 0x2C, 0x3E, 0x92, 0xE5, 0xAF, 0x53, 0x7, 0xE0,
+ 0x29, 0xA6, 0xC5, 0xE3, 0xF5, 0xF7, 0x4A, 0x41, 0x26, 0x6A, 0x16, 0x5E,
+ 0x52, 0x2D, 0x21, 0xAD, 0xF0, 0x91, 0xFF, 0xEA, 0x54, 0xFA, 0x66, 0x1A,
+ 0x45, 0x39, 0xCF, 0x75, 0xA4, 0x88, 0xFB, 0x5D, 0xA2, 0xA0
};
@@ -1856,7 +1891,8 @@ float mg_RidgedMultiFractal(float x, float y, float z, float H, float lacunarity
y *= lacunarity;
z *= lacunarity;
weight = signal * gain;
- if (weight > 1.0f) weight = 1.0f; else if (weight < 0.0f) weight = 0.0f;
+ if (weight > 1.0f) weight = 1.0f;
+ else if (weight < 0.0f) weight = 0.0f;
signal = offset - fabsf(noisefunc(x, y, z));
signal *= signal;
signal *= weight;
diff --git a/source/blender/blenlib/intern/pbvh.c b/source/blender/blenlib/intern/pbvh.c
index 9fd214c0f86..29982fb7744 100644
--- a/source/blender/blenlib/intern/pbvh.c
+++ b/source/blender/blenlib/intern/pbvh.c
@@ -1717,11 +1717,14 @@ void BLI_pbvh_grids_update(PBVH *bvh, CCGElem **grids, DMGridAdjacency *gridadj,
bvh->grids = grids;
bvh->gridadj = gridadj;
bvh->gridfaces = gridfaces;
- bvh->grid_flag_mats = flagmats;
- bvh->grid_hidden = grid_hidden;
- for (a = 0; a < bvh->totnode; ++a)
- BLI_pbvh_node_mark_rebuild_draw(&bvh->nodes[a]);
+ if (flagmats != bvh->grid_flag_mats || bvh->grid_hidden != grid_hidden) {
+ bvh->grid_flag_mats = flagmats;
+ bvh->grid_hidden = grid_hidden;
+
+ for (a = 0; a < bvh->totnode; ++a)
+ BLI_pbvh_node_mark_rebuild_draw(&bvh->nodes[a]);
+ }
}
float (*BLI_pbvh_get_vertCos(PBVH * pbvh))[3]
diff --git a/source/blender/blenlib/intern/scanfill.c b/source/blender/blenlib/intern/scanfill.c
index 362a87782c6..1b7858f7f88 100644
--- a/source/blender/blenlib/intern/scanfill.c
+++ b/source/blender/blenlib/intern/scanfill.c
@@ -985,7 +985,7 @@ int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const short do_quad_tri_speedu
/* CURRENT STATUS:
- * - eve->f :1 = availalble in edges
+ * - eve->f :1 = available in edges
* - eve->xs :polynumber
* - eve->h :amount of edges connected to vertex
* - eve->tmp.v :store! original vertex number
diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c
index ff589764287..14e0dc2f049 100644
--- a/source/blender/blenlib/intern/string.c
+++ b/source/blender/blenlib/intern/string.c
@@ -56,7 +56,7 @@ char *BLI_strdup(const char *str)
return BLI_strdupn(str, strlen(str));
}
-char *BLI_strdupcat(const char *str1, const char *str2)
+char *BLI_strdupcat(const char *__restrict str1, const char *__restrict str2)
{
size_t len;
char *n;
@@ -69,7 +69,7 @@ char *BLI_strdupcat(const char *str1, const char *str2)
return n;
}
-char *BLI_strncpy(char *dst, const char *src, const size_t maxncpy)
+char *BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy)
{
size_t srclen = strlen(src);
size_t cpylen = (srclen > (maxncpy - 1)) ? (maxncpy - 1) : srclen;
@@ -81,7 +81,7 @@ char *BLI_strncpy(char *dst, const char *src, const size_t maxncpy)
return dst;
}
-size_t BLI_vsnprintf(char *buffer, size_t count, const char *format, va_list arg)
+size_t BLI_vsnprintf(char *__restrict buffer, size_t count, const char *__restrict format, va_list arg)
{
size_t n;
@@ -97,7 +97,7 @@ size_t BLI_vsnprintf(char *buffer, size_t count, const char *format, va_list arg
return n;
}
-size_t BLI_snprintf(char *buffer, size_t count, const char *format, ...)
+size_t BLI_snprintf(char *__restrict buffer, size_t count, const char *__restrict format, ...)
{
size_t n;
va_list arg;
@@ -109,7 +109,7 @@ size_t BLI_snprintf(char *buffer, size_t count, const char *format, ...)
return n;
}
-char *BLI_sprintfN(const char *format, ...)
+char *BLI_sprintfN(const char *__restrict format, ...)
{
DynStr *ds;
va_list arg;
@@ -133,7 +133,7 @@ char *BLI_sprintfN(const char *format, ...)
* TODO: support more fancy string escaping. current code is primitive
* this basically is an ascii version of PyUnicode_EncodeUnicodeEscape()
* which is a useful reference. */
-size_t BLI_strescape(char *dst, const char *src, const size_t maxncpy)
+size_t BLI_strescape(char *__restrict dst, const char *__restrict src, const size_t maxncpy)
{
size_t len = 0;
@@ -186,7 +186,7 @@ escape_finish:
*
* TODO, return the offset and a length so as to avoid doing an allocation.
*/
-char *BLI_str_quoted_substrN(const char *str, const char *prefix)
+char *BLI_str_quoted_substrN(const char *__restrict str, const char *__restrict prefix)
{
size_t prefixLen = strlen(prefix);
char *startMatch, *endMatch;
@@ -207,7 +207,7 @@ char *BLI_str_quoted_substrN(const char *str, const char *prefix)
/* A rather wasteful string-replacement utility, though this shall do for now...
* Feel free to replace this with an even safe + nicer alternative */
-char *BLI_replacestr(char *str, const char *oldText, const char *newText)
+char *BLI_replacestr(char *__restrict str, const char *__restrict oldText, const char *__restrict newText)
{
DynStr *ds = NULL;
size_t lenOld = strlen(oldText);
diff --git a/source/blender/blenlib/intern/string_utf8.c b/source/blender/blenlib/intern/string_utf8.c
index e80f96ee0fe..16a5f03095d 100644
--- a/source/blender/blenlib/intern/string_utf8.c
+++ b/source/blender/blenlib/intern/string_utf8.c
@@ -184,7 +184,7 @@ static const size_t utf8_skip_data[256] = {
*dst = '\0'; \
} (void)0
-char *BLI_strncpy_utf8(char *dst, const char *src, size_t maxncpy)
+char *BLI_strncpy_utf8(char *__restrict dst, const char *__restrict src, size_t maxncpy)
{
char *dst_r = dst;
@@ -196,7 +196,7 @@ char *BLI_strncpy_utf8(char *dst, const char *src, size_t maxncpy)
return dst_r;
}
-char *BLI_strncat_utf8(char *dst, const char *src, size_t maxncpy)
+char *BLI_strncat_utf8(char *__restrict dst, const char *__restrict src, size_t maxncpy)
{
while (*dst && maxncpy > 0) {
dst++;
@@ -213,7 +213,7 @@ char *BLI_strncat_utf8(char *dst, const char *src, size_t maxncpy)
/* --------------------------------------------------------------------------*/
/* wchar_t / utf8 functions */
-size_t BLI_strncpy_wchar_as_utf8(char *dst, const wchar_t *src, const size_t maxncpy)
+size_t BLI_strncpy_wchar_as_utf8(char *__restrict dst, const wchar_t *__restrict src, const size_t maxncpy)
{
size_t len = 0;
@@ -289,7 +289,7 @@ size_t BLI_strnlen_utf8(const char *start, const size_t maxlen)
return len;
}
-size_t BLI_strncpy_wchar_from_utf8(wchar_t *dst_w, const char *src_c, const size_t maxncpy)
+size_t BLI_strncpy_wchar_from_utf8(wchar_t *__restrict dst_w, const char *__restrict src_c, const size_t maxncpy)
{
int len = 0;
@@ -419,7 +419,7 @@ unsigned int BLI_str_utf8_as_unicode(const char *p)
}
/* variant that increments the length */
-unsigned int BLI_str_utf8_as_unicode_and_size(const char *p, size_t *index)
+unsigned int BLI_str_utf8_as_unicode_and_size(const char *__restrict p, size_t *__restrict index)
{
int i, mask = 0, len;
unsigned int result;
@@ -435,7 +435,7 @@ unsigned int BLI_str_utf8_as_unicode_and_size(const char *p, size_t *index)
/* another variant that steps over the index,
* note, currently this also falls back to latin1 for text drawing. */
-unsigned int BLI_str_utf8_as_unicode_step(const char *p, size_t *index)
+unsigned int BLI_str_utf8_as_unicode_step(const char *__restrict p, size_t *__restrict index)
{
int i, mask = 0, len;
unsigned int result;
diff --git a/source/blender/blenlib/intern/threads.c b/source/blender/blenlib/intern/threads.c
index 66527b9b92a..146e1d531f1 100644
--- a/source/blender/blenlib/intern/threads.c
+++ b/source/blender/blenlib/intern/threads.c
@@ -400,6 +400,42 @@ void BLI_mutex_end(ThreadMutex *mutex)
pthread_mutex_destroy(mutex);
}
+/* Spin Locks */
+
+void BLI_spin_init(SpinLock *spin)
+{
+#ifdef __APPLE__
+ *spin = OS_SPINLOCK_INIT;
+#else
+ pthread_spin_init(spin, 0);
+#endif
+}
+
+void BLI_spin_lock(SpinLock *spin)
+{
+#ifdef __APPLE__
+ OSSpinLockLock(spin);
+#else
+ pthread_spin_lock(spin);
+#endif
+}
+
+void BLI_spin_unlock(SpinLock *spin)
+{
+#ifdef __APPLE__
+ OSSpinLockUnlock(spin);
+#else
+ pthread_spin_unlock(spin);
+#endif
+}
+
+void BLI_spin_end(SpinLock *spin)
+{
+#ifndef __APPLE__
+ pthread_spin_destroy(spin);
+#endif
+}
+
/* Read/Write Mutex Lock */
void BLI_rw_mutex_init(ThreadRWMutex *mutex)
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 30331713463..bcd67d8bd0b 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -2983,7 +2983,6 @@ static void direct_link_text(FileData *fd, Text *text)
#endif
link_list(fd, &text->lines);
- link_list(fd, &text->markers);
text->curl = newdataadr(fd, text->curl);
text->sell = newdataadr(fd, text->sell);
@@ -3043,7 +3042,7 @@ static void direct_link_image(FileData *fd, Image *ima)
link_ibuf_list(fd, &ima->ibufs);
else
ima->ibufs.first = ima->ibufs.last = NULL;
-
+
/* if not restored, we keep the binded opengl index */
if (ima->ibufs.first == NULL) {
ima->bindcode = 0;
@@ -8313,11 +8312,17 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
for (scene = main->scene.first; scene; scene = scene->id.next) {
if (scene->r.tilex == 0 || scene->r.tiley == 1) {
- /* scene could be set for panoramic rendering, so clamp with the
- * lowest possible tile size value
- */
- scene->r.tilex = max_ii(scene->r.xsch * scene->r.size / scene->r.xparts / 100, 8);
- scene->r.tiley = max_ii(scene->r.ysch * scene->r.size / scene->r.yparts / 100, 8);
+ if (scene->r.xparts && scene->r.yparts) {
+ /* scene could be set for panoramic rendering, so clamp with the
+ * lowest possible tile size value
+ */
+ scene->r.tilex = max_ii(scene->r.xsch * scene->r.size / scene->r.xparts / 100, 8);
+ scene->r.tiley = max_ii(scene->r.ysch * scene->r.size / scene->r.yparts / 100, 8);
+ }
+ else {
+ /* happens when mixing using current trunk and previous release */
+ scene->r.tilex = scene->r.tiley = 64;
+ }
}
}
}
@@ -8339,7 +8344,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
for (clip = main->movieclip.first; clip; clip = clip->id.next) {
if (clip->tracking.settings.reconstruction_success_threshold == 0.0f) {
- clip->tracking.settings.reconstruction_success_threshold = 1e-3;
+ clip->tracking.settings.reconstruction_success_threshold = 1e-3f;
}
}
}
@@ -8364,6 +8369,17 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
}
}
+ {
+ Object *ob;
+ for (ob = main->object.first; ob; ob = ob->id.next) {
+ if (ob->step_height == 0.0f) {
+ ob->step_height = 0.15f;
+ ob->jump_speed = 10.0f;
+ ob->fall_speed = 55.0f;
+ }
+ }
+ }
+
/* WATCH IT!!!: pointers from libdata have not been converted yet here! */
/* WATCH IT 2!: Userdef struct init has to be in editors/interface/resources.c! */
diff --git a/source/blender/blenloader/intern/versioning_250.c b/source/blender/blenloader/intern/versioning_250.c
index d75339252d9..1521739258e 100644
--- a/source/blender/blenloader/intern/versioning_250.c
+++ b/source/blender/blenloader/intern/versioning_250.c
@@ -901,7 +901,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
ob->matbits = MEM_callocN(sizeof(char)*ob->totcol, "ob->matbits");
for (a = 0; a < ob->totcol; a++)
- ob->matbits[a] = ob->colbits & (1<<a);
+ ob->matbits[a] = (ob->colbits & (1<<a)) != 0;
}
}
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index ac5366c26a3..b010cae6893 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -2607,7 +2607,6 @@ static void write_texts(WriteData *wd, ListBase *idbase)
{
Text *text;
TextLine *tmp;
- TextMarker *mrk;
text= idbase->first;
while (text) {
@@ -2631,13 +2630,6 @@ static void write_texts(WriteData *wd, ListBase *idbase)
writedata(wd, DATA, tmp->len+1, tmp->line);
tmp= tmp->next;
}
-
- /* write markers */
- mrk= text->markers.first;
- while (mrk) {
- writestruct(wd, DATA, "TextMarker", 1, mrk);
- mrk= mrk->next;
- }
}
diff --git a/source/blender/bmesh/CMakeLists.txt b/source/blender/bmesh/CMakeLists.txt
index d7858ebbc0d..2a23658f5d0 100644
--- a/source/blender/bmesh/CMakeLists.txt
+++ b/source/blender/bmesh/CMakeLists.txt
@@ -68,10 +68,6 @@ set(SRC
intern/bmesh_construct.h
intern/bmesh_core.c
intern/bmesh_core.h
- intern/bmesh_decimate_collapse.c
- intern/bmesh_decimate_dissolve.c
- intern/bmesh_decimate_unsubdivide.c
- intern/bmesh_decimate.h
intern/bmesh_inline.h
intern/bmesh_interp.c
intern/bmesh_interp.h
@@ -109,6 +105,12 @@ set(SRC
intern/bmesh_error.h
tools/BME_bevel.c
+ tools/bmesh_bevel.c
+ tools/bmesh_bevel.h
+ tools/bmesh_decimate_collapse.c
+ tools/bmesh_decimate_dissolve.c
+ tools/bmesh_decimate_unsubdivide.c
+ tools/bmesh_decimate.h
bmesh.h
bmesh_class.h
diff --git a/source/blender/bmesh/bmesh.h b/source/blender/bmesh/bmesh.h
index a672ec0b6a7..6257aa4bf3e 100644
--- a/source/blender/bmesh/bmesh.h
+++ b/source/blender/bmesh/bmesh.h
@@ -252,7 +252,6 @@ extern "C" {
#include "intern/bmesh_construct.h"
#include "intern/bmesh_core.h"
-#include "intern/bmesh_decimate.h"
#include "intern/bmesh_interp.h"
#include "intern/bmesh_iterators.h"
#include "intern/bmesh_marking.h"
@@ -267,6 +266,9 @@ extern "C" {
#include "intern/bmesh_inline.h"
+#include "tools/bmesh_decimate.h"
+#include "tools/bmesh_bevel.h"
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/bmesh/bmesh_class.h b/source/blender/bmesh/bmesh_class.h
index cff7da78ef2..f9dbf51a629 100644
--- a/source/blender/bmesh/bmesh_class.h
+++ b/source/blender/bmesh/bmesh_class.h
@@ -48,6 +48,8 @@ struct Object;
* hrm. it doesn't but stull works ok, remove the comment above? - campbell.
*/
+// #pragma GCC diagnostic error "-Wpadded"
+
/**
* BMHeader
*
@@ -69,10 +71,19 @@ typedef struct BMHeader {
* this is abused by various tools which set it dirty.
* - For loops this is used for sorting during tessellation. */
- char htype; /* element geometric type (verts/edges/loops/faces) */
- char hflag; /* this would be a CD layer, see below */
+ char htype; /* element geometric type (verts/edges/loops/faces) */
+ char hflag; /* this would be a CD layer, see below */
+
+ /* internal use only!
+ * note,.we are very picky about not bloating this struct
+ * but in this case its padded up to 16 bytes anyway,
+ * so adding a flag here gives no increase in size */
+ char api_flag;
+// char _pad;
} BMHeader;
+BLI_STATIC_ASSERT((sizeof(BMHeader) <= 16), "BMHeader size has grown!");
+
/* note: need some way to specify custom locations for custom data layers. so we can
* make them point directly into structs. and some way to make it only happen to the
* active layer, and properly update when switching active layers.*/
@@ -122,7 +133,10 @@ typedef struct BMLoop {
/* can cast BMFace/BMEdge/BMVert, but NOT BMLoop, since these don't have a flag layer */
typedef struct BMElemF {
BMHeader head;
- struct BMFlagLayer *oflags; /* keep after header, an array of flags, mostly used by the operator stack */
+
+ /* keep directly after header,
+ * optional array of flags, only used by the operator stack */
+ struct BMFlagLayer *oflags;
} BMElemF;
/* can cast anything to this, including BMLoop */
@@ -142,21 +156,24 @@ typedef struct BMFace {
BMHeader head;
struct BMFlagLayer *oflags; /* an array of flags, mostly used by the operator stack */
- int len; /*includes all boundary loops*/
#ifdef USE_BMESH_HOLES
int totbounds; /*total boundaries, is one plus the number of holes in the face*/
ListBase loops;
#else
BMLoop *l_first;
#endif
- float no[3]; /*yes, we do store this here*/
+ int len; /* includes all boundary loops */
+ float no[3]; /* yes, we do store this here */
short mat_nr;
+// short _pad[3];
} BMFace;
typedef struct BMFlagLayer {
- short f, pflag; /* flags */
+ short f; /* flags */
} BMFlagLayer;
+// #pragma GCC diagnostic ignored "-Wpadded"
+
typedef struct BMesh {
int totvert, totedge, totloop, totface;
int totvertsel, totedgesel, totfacesel;
@@ -166,7 +183,7 @@ typedef struct BMesh {
* valid flags are - BM_VERT | BM_EDGE | BM_FACE.
* BM_LOOP isn't handled so far. */
char elem_index_dirty;
-
+
/*element pools*/
struct BLI_mempool *vpool, *epool, *lpool, *fpool;
@@ -192,7 +209,7 @@ typedef struct BMesh {
int walkers, totflags;
ListBase selected, error_stack;
-
+
BMFace *act_face;
ListBase errorstack;
@@ -243,10 +260,16 @@ enum {
# define BM_FACE_FIRST_LOOP(p) ((p)->l_first)
#endif
-/* size to use for static arrays when dealing with NGons,
+/**
+ * size to use for stack arrays when dealing with NGons,
* alloc after this limit is reached.
* this value is rather arbitrary */
-#define BM_NGON_STACK_SIZE 32
+#define BM_DEFAULT_NGON_STACK_SIZE 32
+/**
+ * size to use for stack arrays dealing with connected mesh data
+ * verts of faces, edges of vert - etc.
+ * often used with #BM_iter_as_arrayN() */
+#define BM_DEFAULT_ITER_STACK_SIZE 16
/* avoid inf loop, this value is arbitrary
* but should not error on valid cases */
diff --git a/source/blender/bmesh/intern/bmesh_construct.c b/source/blender/bmesh/intern/bmesh_construct.c
index eae78c6cc25..770196108f0 100644
--- a/source/blender/bmesh/intern/bmesh_construct.c
+++ b/source/blender/bmesh/intern/bmesh_construct.c
@@ -99,7 +99,7 @@ BMFace *BM_face_create_quad_tri_v(BMesh *bm, BMVert **verts, int len, const BMFa
if (nodouble) {
/* check if face exists or overlaps */
- is_overlap = BM_face_exists(bm, verts, len, &f);
+ is_overlap = BM_face_exists(verts, len, &f);
}
/* make new face */
@@ -174,9 +174,9 @@ 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)
{
BMEdge **edges2 = NULL;
- BLI_array_staticdeclare(edges2, BM_NGON_STACK_SIZE);
+ BLI_array_staticdeclare(edges2, BM_DEFAULT_NGON_STACK_SIZE);
BMVert **verts = NULL;
- BLI_array_staticdeclare(verts, BM_NGON_STACK_SIZE);
+ BLI_array_staticdeclare(verts, BM_DEFAULT_NGON_STACK_SIZE);
BMFace *f = NULL;
BMEdge *e;
BMVert *v, *ev1, *ev2;
@@ -187,8 +187,10 @@ BMFace *BM_face_create_ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, i
* _and_ the old bmesh_mf functions, so its kindof smashed together
* - joeedh */
- if (!len || !v1 || !v2 || !edges || !bm)
+ if (!len || !v1 || !v2 || !edges || !bm) {
+ BLI_assert(0);
return NULL;
+ }
/* put edges in correct order */
for (i = 0; i < len; i++) {
diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c
index 0910dd82701..03094873e25 100644
--- a/source/blender/bmesh/intern/bmesh_core.c
+++ b/source/blender/bmesh/intern/bmesh_core.c
@@ -76,7 +76,9 @@ BMVert *BM_vert_create(BMesh *bm, const float co[3], const BMVert *example)
}
/* allocate flag */
- v->oflags = BLI_mempool_calloc(bm->toolflagpool);
+ if (bm->toolflagpool) {
+ v->oflags = BLI_mempool_calloc(bm->toolflagpool);
+ }
CustomData_bmesh_set_default(&bm->vdata, &v->head.data);
@@ -125,12 +127,14 @@ BMEdge *BM_edge_create(BMesh *bm, BMVert *v1, BMVert *v2, const BMEdge *example,
e->head.htype = BM_EDGE;
/* allocate flag */
- e->oflags = BLI_mempool_calloc(bm->toolflagpool);
+ if (bm->toolflagpool) {
+ e->oflags = BLI_mempool_calloc(bm->toolflagpool);
+ }
e->v1 = v1;
e->v2 = v2;
- BM_elem_flag_enable(e, BM_ELEM_SMOOTH);
+ BM_elem_flag_enable(e, BM_ELEM_SMOOTH | BM_ELEM_DRAW);
CustomData_bmesh_set_default(&bm->edata, &e->head.data);
@@ -195,8 +199,8 @@ BMFace *BM_face_copy(BMesh *bm, BMFace *f, const short copyverts, const short co
{
BMVert **verts = NULL;
BMEdge **edges = NULL;
- BLI_array_fixedstack_declare(verts, BM_NGON_STACK_SIZE, f->len, __func__);
- BLI_array_fixedstack_declare(edges, BM_NGON_STACK_SIZE, f->len, __func__);
+ BLI_array_fixedstack_declare(verts, BM_DEFAULT_NGON_STACK_SIZE, f->len, __func__);
+ BLI_array_fixedstack_declare(edges, BM_DEFAULT_NGON_STACK_SIZE, f->len, __func__);
BMLoop *l_iter;
BMLoop *l_first;
BMLoop *l_copy;
@@ -278,7 +282,9 @@ BLI_INLINE BMFace *bm_face_create__internal(BMesh *bm)
f->head.htype = BM_FACE;
/* allocate flag */
- f->oflags = BLI_mempool_calloc(bm->toolflagpool);
+ if (bm->toolflagpool) {
+ f->oflags = BLI_mempool_calloc(bm->toolflagpool);
+ }
CustomData_bmesh_set_default(&bm->pdata, &f->head.data);
@@ -305,7 +311,7 @@ BMFace *BM_face_create(BMesh *bm, BMVert **verts, BMEdge **edges, const int len,
if (nodouble) {
/* Check if face already exists */
- overlap = BM_face_exists(bm, verts, len, &f);
+ overlap = BM_face_exists(verts, len, &f);
if (overlap) {
return f;
}
@@ -495,7 +501,9 @@ static void bm_kill_only_vert(BMesh *bm, BMVert *v)
if (v->head.data)
CustomData_bmesh_free_block(&bm->vdata, &v->head.data);
- BLI_mempool_free(bm->toolflagpool, v->oflags);
+ if (bm->toolflagpool) {
+ BLI_mempool_free(bm->toolflagpool, v->oflags);
+ }
BLI_mempool_free(bm->vpool, v);
}
@@ -513,7 +521,9 @@ static void bm_kill_only_edge(BMesh *bm, BMEdge *e)
if (e->head.data)
CustomData_bmesh_free_block(&bm->edata, &e->head.data);
- BLI_mempool_free(bm->toolflagpool, e->oflags);
+ if (bm->toolflagpool) {
+ BLI_mempool_free(bm->toolflagpool, e->oflags);
+ }
BLI_mempool_free(bm->epool, e);
}
@@ -534,7 +544,9 @@ static void bm_kill_only_face(BMesh *bm, BMFace *f)
if (f->head.data)
CustomData_bmesh_free_block(&bm->pdata, &f->head.data);
- BLI_mempool_free(bm->toolflagpool, f->oflags);
+ if (bm->toolflagpool) {
+ BLI_mempool_free(bm->toolflagpool, f->oflags);
+ }
BLI_mempool_free(bm->fpool, f);
}
@@ -558,7 +570,7 @@ static void bm_kill_only_loop(BMesh *bm, BMLoop *l)
void BM_face_edges_kill(BMesh *bm, BMFace *f)
{
BMEdge **edges = NULL;
- BLI_array_staticdeclare(edges, BM_NGON_STACK_SIZE);
+ BLI_array_staticdeclare(edges, BM_DEFAULT_NGON_STACK_SIZE);
BMLoop *l_iter;
BMLoop *l_first;
int i;
@@ -582,7 +594,7 @@ void BM_face_edges_kill(BMesh *bm, BMFace *f)
void BM_face_verts_kill(BMesh *bm, BMFace *f)
{
BMVert **verts = NULL;
- BLI_array_staticdeclare(verts, BM_NGON_STACK_SIZE);
+ BLI_array_staticdeclare(verts, BM_DEFAULT_NGON_STACK_SIZE);
BMLoop *l_iter;
BMLoop *l_first;
int i;
@@ -734,7 +746,7 @@ static int bm_loop_reverse_loop(BMesh *bm, BMFace *f
const int do_disps = CustomData_has_layer(&bm->ldata, CD_MDISPS);
BMLoop *l_iter, *oldprev, *oldnext;
BMEdge **edar = NULL;
- BLI_array_fixedstack_declare(edar, BM_NGON_STACK_SIZE, len, __func__);
+ BLI_array_fixedstack_declare(edar, BM_DEFAULT_NGON_STACK_SIZE, len, __func__);
int i, j, edok;
for (i = 0, l_iter = l_first; i < len; i++, l_iter = l_iter->next) {
@@ -937,9 +949,9 @@ BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface, const short do_del
BMEdge **edges = NULL;
BMEdge **deledges = NULL;
BMVert **delverts = NULL;
- BLI_array_staticdeclare(edges, BM_NGON_STACK_SIZE);
- BLI_array_staticdeclare(deledges, BM_NGON_STACK_SIZE);
- BLI_array_staticdeclare(delverts, BM_NGON_STACK_SIZE);
+ BLI_array_staticdeclare(edges, BM_DEFAULT_NGON_STACK_SIZE);
+ BLI_array_staticdeclare(deledges, BM_DEFAULT_NGON_STACK_SIZE);
+ BLI_array_staticdeclare(delverts, BM_DEFAULT_NGON_STACK_SIZE);
BMVert *v1 = NULL, *v2 = NULL;
const char *err = NULL;
int i, tote = 0;
@@ -1587,7 +1599,7 @@ BMEdge *bmesh_jekv(BMesh *bm, BMEdge *ke, BMVert *kv, const short check_edge_dou
if (LIKELY(radlen)) {
BMLoop **loops = NULL;
- BLI_array_fixedstack_declare(loops, BM_NGON_STACK_SIZE, radlen, __func__);
+ BLI_array_fixedstack_declare(loops, BM_DEFAULT_NGON_STACK_SIZE, radlen, __func__);
killoop = ke->l;
@@ -1773,14 +1785,18 @@ BMFace *bmesh_jfke(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e)
bmesh_disk_edge_remove(f1loop->e, f1loop->e->v2);
/* deallocate edge and its two loops as well as f2 */
- BLI_mempool_free(bm->toolflagpool, f1loop->e->oflags);
+ if (bm->toolflagpool) {
+ BLI_mempool_free(bm->toolflagpool, f1loop->e->oflags);
+ }
BLI_mempool_free(bm->epool, f1loop->e);
bm->totedge--;
BLI_mempool_free(bm->lpool, f1loop);
bm->totloop--;
BLI_mempool_free(bm->lpool, f2loop);
bm->totloop--;
- BLI_mempool_free(bm->toolflagpool, f2->oflags);
+ if (bm->toolflagpool) {
+ BLI_mempool_free(bm->toolflagpool, f2->oflags);
+ }
BLI_mempool_free(bm->fpool, f2);
bm->totface--;
/* account for both above */
@@ -1808,23 +1824,28 @@ BMFace *bmesh_jfke(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e)
*/
int BM_vert_splice(BMesh *bm, BMVert *v, BMVert *v_target)
{
- BMEdge *e;
-
+ void *loops_stack[BM_DEFAULT_ITER_STACK_SIZE];
BMLoop **loops;
int i, loops_tot;
+ BMEdge *e;
+
/* verts already spliced */
if (v == v_target) {
return FALSE;
}
/* we can't modify the vert while iterating so first allocate an array of loops */
- loops = BM_iter_as_arrayN(bm, BM_LOOPS_OF_VERT, v, &loops_tot);
- if (loops) {
+ loops = BM_iter_as_arrayN(bm, BM_LOOPS_OF_VERT, v, &loops_tot,
+ loops_stack, BM_DEFAULT_ITER_STACK_SIZE);
+
+ if (LIKELY(loops != NULL)) {
for (i = 0; i < loops_tot; i++) {
loops[i]->v = v_target;
}
- MEM_freeN(loops);
+ if (loops != (BMLoop **)loops_stack) {
+ MEM_freeN(loops);
+ }
}
/* move all the edges from v's disk to vtarget's disk */
diff --git a/source/blender/bmesh/intern/bmesh_interp.c b/source/blender/bmesh/intern/bmesh_interp.c
index 508b3b8fcdf..caf9f3c70d5 100644
--- a/source/blender/bmesh/intern/bmesh_interp.c
+++ b/source/blender/bmesh/intern/bmesh_interp.c
@@ -174,9 +174,9 @@ void BM_face_interp_from_face(BMesh *bm, BMFace *target, BMFace *source)
void **blocks = NULL;
float (*cos)[3] = NULL, *w = NULL;
- BLI_array_fixedstack_declare(cos, BM_NGON_STACK_SIZE, source->len, __func__);
- BLI_array_fixedstack_declare(w, BM_NGON_STACK_SIZE, source->len, __func__);
- BLI_array_fixedstack_declare(blocks, BM_NGON_STACK_SIZE, source->len, __func__);
+ BLI_array_fixedstack_declare(cos, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__);
+ BLI_array_fixedstack_declare(w, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__);
+ BLI_array_fixedstack_declare(blocks, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__);
int i;
BM_elem_attrs_copy(bm, bm, source, target);
@@ -613,10 +613,10 @@ void BM_loop_interp_from_face(BMesh *bm, BMLoop *target, BMFace *source,
void **vblocks = NULL;
float (*cos)[3] = NULL, co[3], *w = NULL;
float cent[3] = {0.0f, 0.0f, 0.0f};
- BLI_array_fixedstack_declare(cos, BM_NGON_STACK_SIZE, source->len, __func__);
- BLI_array_fixedstack_declare(w, BM_NGON_STACK_SIZE, source->len, __func__);
- BLI_array_fixedstack_declare(blocks, BM_NGON_STACK_SIZE, source->len, __func__);
- BLI_array_fixedstack_declare(vblocks, BM_NGON_STACK_SIZE, do_vertex ? source->len : 0, __func__);
+ BLI_array_fixedstack_declare(cos, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__);
+ BLI_array_fixedstack_declare(w, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__);
+ BLI_array_fixedstack_declare(blocks, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__);
+ BLI_array_fixedstack_declare(vblocks, BM_DEFAULT_NGON_STACK_SIZE, do_vertex ? source->len : 0, __func__);
int i, ax, ay;
BM_elem_attrs_copy(bm, bm, source, target->f);
@@ -689,9 +689,9 @@ void BM_vert_interp_from_face(BMesh *bm, BMVert *v, BMFace *source)
void **blocks = NULL;
float (*cos)[3] = NULL, *w = NULL;
float cent[3] = {0.0f, 0.0f, 0.0f};
- BLI_array_fixedstack_declare(cos, BM_NGON_STACK_SIZE, source->len, __func__);
- BLI_array_fixedstack_declare(w, BM_NGON_STACK_SIZE, source->len, __func__);
- BLI_array_fixedstack_declare(blocks, BM_NGON_STACK_SIZE, source->len, __func__);
+ BLI_array_fixedstack_declare(cos, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__);
+ BLI_array_fixedstack_declare(w, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__);
+ BLI_array_fixedstack_declare(blocks, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__);
int i;
i = 0;
diff --git a/source/blender/bmesh/intern/bmesh_iterators.c b/source/blender/bmesh/intern/bmesh_iterators.c
index 1cb95d94e9b..c3f33eb95e1 100644
--- a/source/blender/bmesh/intern/bmesh_iterators.c
+++ b/source/blender/bmesh/intern/bmesh_iterators.c
@@ -116,10 +116,14 @@ int BM_iter_as_array(BMesh *bm, const char itype, void *data, void **array, cons
*
* Caller needs to free the array.
*/
-void *BM_iter_as_arrayN(BMesh *bm, const char itype, void *data, int *r_len)
+void *BM_iter_as_arrayN(BMesh *bm, const char itype, void *data, int *r_len,
+ /* optional args to avoid an alloc (normally stack array) */
+ void **stack_array, int stack_array_size)
{
BMIter iter;
+ BLI_assert(stack_array_size == 0 || (stack_array_size && stack_array));
+
/* we can't rely on coun't being set */
switch (itype) {
case BM_VERTS_OF_MESH:
@@ -137,7 +141,9 @@ void *BM_iter_as_arrayN(BMesh *bm, const char itype, void *data, int *r_len)
if (BM_iter_init(&iter, bm, itype, data) && iter.count > 0) {
BMElem *ele;
- BMElem **array = MEM_mallocN(sizeof(ele) * iter.count, __func__);
+ BMElem **array = iter.count > stack_array_size ?
+ MEM_mallocN(sizeof(ele) * iter.count, __func__) :
+ stack_array;
int i = 0;
*r_len = iter.count; /* set before iterating */
diff --git a/source/blender/bmesh/intern/bmesh_iterators.h b/source/blender/bmesh/intern/bmesh_iterators.h
index 3c42b3d610c..7291bca6356 100644
--- a/source/blender/bmesh/intern/bmesh_iterators.h
+++ b/source/blender/bmesh/intern/bmesh_iterators.h
@@ -107,14 +107,14 @@ typedef struct BMIter {
BMesh *bm;
void (*begin)(struct BMIter *iter);
void *(*step)(struct BMIter *iter);
- /*
+#if 0
union {
void *p;
int i;
long l;
float f;
} filter;
- */
+#endif
int count; /* note, only some iterators set this, don't rely on it */
char itype;
} BMIter;
@@ -125,7 +125,8 @@ __attribute__((warn_unused_result))
#endif
;
int BM_iter_as_array(BMesh *bm, const char itype, void *data, void **array, const int len);
-void *BM_iter_as_arrayN(BMesh *bm, const char itype, void *data, int *r_len)
+void *BM_iter_as_arrayN(BMesh *bm, const char itype, void *data, int *r_len,
+ void **stack_array, int stack_array_size)
#ifdef __GNUC__
__attribute__((warn_unused_result))
#endif
diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c
index d3e3bcd3556..ba5e7569c31 100644
--- a/source/blender/bmesh/intern/bmesh_mesh.c
+++ b/source/blender/bmesh/intern/bmesh_mesh.c
@@ -59,9 +59,45 @@ static void bm_mempool_init(BMesh *bm, const BMAllocTemplate *allocsize)
#ifdef USE_BMESH_HOLES
bm->looplistpool = BLI_mempool_create(sizeof(BMLoopList), 512, 512, 0);
#endif
+}
- /* allocate one flag pool that we don't get rid of. */
- bm->toolflagpool = BLI_mempool_create(sizeof(BMFlagLayer), 512, 512, 0);
+void BM_mesh_elem_toolflags_ensure(BMesh *bm)
+{
+ if (bm->toolflagpool == NULL) {
+ const int totflagpool_size = max_ii(512, bm->totvert + bm->totedge + bm->totface);
+ BLI_mempool *toolflagpool;
+
+ BMIter iter;
+ BMElemF *ele;
+ const char iter_types[3] = {BM_VERTS_OF_MESH,
+ BM_EDGES_OF_MESH,
+ BM_FACES_OF_MESH};
+
+ int i;
+
+ BLI_assert(bm->totflags == 0);
+
+ /* allocate one flag pool that we don't get rid of. */
+ toolflagpool = BLI_mempool_create(sizeof(BMFlagLayer), totflagpool_size, 512, 0);
+
+
+ for (i = 0; i < 3; i++) {
+ BM_ITER_MESH (ele, &iter, bm, iter_types[i]) {
+ ele->oflags = BLI_mempool_calloc(toolflagpool);
+ }
+ }
+
+ bm->toolflagpool = toolflagpool;
+ bm->totflags = 1;
+ }
+}
+
+void BM_mesh_elem_toolflags_clear(BMesh *bm)
+{
+ if (bm->toolflagpool) {
+ BLI_mempool_destroy(bm->toolflagpool);
+ bm->toolflagpool = NULL;
+ }
}
/**
@@ -83,7 +119,7 @@ BMesh *BM_mesh_create(BMAllocTemplate *allocsize)
/* allocate one flag pool that we don't get rid of. */
bm->stackdepth = 1;
- bm->totflags = 1;
+ bm->totflags = 0;
CustomData_reset(&bm->vdata);
CustomData_reset(&bm->edata);
@@ -143,7 +179,7 @@ void BM_mesh_data_free(BMesh *bm)
BLI_mempool_destroy(bm->fpool);
/* destroy flag pool */
- BLI_mempool_destroy(bm->toolflagpool);
+ BM_mesh_elem_toolflags_clear(bm);
#ifdef USE_BMESH_HOLES
BLI_mempool_destroy(bm->looplistpool);
diff --git a/source/blender/bmesh/intern/bmesh_mesh.h b/source/blender/bmesh/intern/bmesh_mesh.h
index 8b6ef9aa3e0..b592f863cd1 100644
--- a/source/blender/bmesh/intern/bmesh_mesh.h
+++ b/source/blender/bmesh/intern/bmesh_mesh.h
@@ -29,6 +29,8 @@
struct BMAllocTemplate;
+void BM_mesh_elem_toolflags_ensure(BMesh *bm);
+void BM_mesh_elem_toolflags_clear(BMesh *bm);
BMesh *BM_mesh_create(struct BMAllocTemplate *allocsize);
void BM_mesh_free(BMesh *bm);
@@ -58,4 +60,8 @@ typedef struct BMAllocTemplate {
extern BMAllocTemplate bm_mesh_allocsize_default;
extern BMAllocTemplate bm_mesh_chunksize_default;
+enum {
+ BM_MESH_CREATE_USE_TOOLFLAGS = (1 << 0)
+};
+
#endif /* __BMESH_MESH_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c
index 398e6bbedcf..ec07eb5d9f7 100644
--- a/source/blender/bmesh/intern/bmesh_opdefines.c
+++ b/source/blender/bmesh/intern/bmesh_opdefines.c
@@ -47,9 +47,9 @@
* "in" (e.g. edgefacein). for three-type slots, use geom.
*
* for output slots, for single-type geometry slots, use the type name plus "out",
- * (e.g. vertout), for double-type slots, use the two type names plus "out",
- * (e.g. vertfaceout), for three-type slots, use geom. note that you can also
- * use more esohteric names (e.g. skirtout) so long as the comment next to the
+ * (e.g. verts.out), for double-type slots, use the two type names plus "out",
+ * (e.g. vertfaces.out), for three-type slots, use geom. note that you can also
+ * use more esohteric names (e.g. geom_skirt.out) so long as the comment next to the
* slot definition tells you what types of elements are in it.
*
*/
@@ -82,7 +82,7 @@
* would be extracted from comments
* next to them, e.g.
*
- * {BMO_OP_SLOT_ELEMENT_BUF, "geomout"}, //output slot, boundary region
+ * {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
@@ -99,16 +99,18 @@
*/
static BMOpDefine bmo_smooth_vert_def = {
"smooth_vert",
- {{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, "clipdist"}, /* 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} /* null-terminating sentinel */,
+ /* 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 */
bmo_smooth_vert_exec,
0
};
@@ -117,18 +119,20 @@ static BMOpDefine bmo_smooth_vert_def = {
* Vertext Smooth Laplacian
* Smooths vertices by using Laplacian smoothing propose by.
* Desbrun, et al. Implicit Fairing of Irregular Meshes using Diffusion and Curvature Flow
-*/
+ */
static BMOpDefine bmo_smooth_laplacian_vert_def = {
"smooth_laplacian_vert",
- {{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, "volume_preservation"}, //Apply volume preservation after smooth
- {0} /* null-terminating sentinel */,
+ /* 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},
},
+ {{0}}, /* no output */
bmo_smooth_laplacian_vert_exec,
0
};
@@ -141,10 +145,12 @@ static BMOpDefine bmo_smooth_laplacian_vert_def = {
static BMOpDefine bmo_recalc_face_normals_def = {
"recalc_face_normals",
+ /* slots_in */
{{BMO_OP_SLOT_ELEMENT_BUF, "faces"},
- {BMO_OP_SLOT_BOOL, "do_flip"}, /* internal flag, used by bmesh_rationalize_normals */
- {0} /* null-terminating sentinel */,
+ {BMO_OP_SLOT_BOOL, "use_flip"}, /* internal flag, used by bmesh_rationalize_normals */
+ {0},
},
+ {{0}}, /* no output */
bmo_recalc_face_normals_exec,
BMO_OP_FLAG_UNTAN_MULTIRES,
};
@@ -154,18 +160,22 @@ static BMOpDefine bmo_recalc_face_normals_def = {
*
* used to implement the select more/less tools.
* this puts some geometry surrounding regions of
- * geometry in geom into geomout.
+ * geometry in geom into geom.out.
*
- * if usefaces is 0 then geomout spits out verts and edges,
+ * if usefaces is 0 then geom.out spits out verts and edges,
* otherwise it spits out faces.
*/
static BMOpDefine bmo_region_extend_def = {
"region_extend",
- {{BMO_OP_SLOT_ELEMENT_BUF, "geom"}, /* input geometry */
- {BMO_OP_SLOT_ELEMENT_BUF, "geomout"}, /* output slot, computed boundary geometry. */
- {BMO_OP_SLOT_BOOL, "constrict"}, /* find boundary inside the regions, not outside. */
- {BMO_OP_SLOT_BOOL, "use_faces"}, /* extend from faces instead of edges */
- {0} /* null-terminating sentinel */,
+ /* 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},
+ },
+ /* slots_out */
+ {{BMO_OP_SLOT_ELEMENT_BUF, "geom.out"}, /* output slot, computed boundary geometry. */
+ {0},
},
bmo_region_extend_exec,
0
@@ -179,10 +189,14 @@ static BMOpDefine bmo_region_extend_def = {
*/
static BMOpDefine bmo_rotate_edges_def = {
"rotate_edges",
- {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edges */
- {BMO_OP_SLOT_ELEMENT_BUF, "edgeout"}, /* newly spun edges */
- {BMO_OP_SLOT_BOOL, "ccw"}, /* rotate edge counter-clockwise if true, othewise clockwise */
- {0} /* null-terminating sentinel */,
+ /* 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},
+ },
+ /* slots_out */
+ {{BMO_OP_SLOT_ELEMENT_BUF, "edges.out"}, /* newly spun edges */
+ {0},
},
bmo_rotate_edges_exec,
BMO_OP_FLAG_UNTAN_MULTIRES
@@ -196,9 +210,11 @@ static BMOpDefine bmo_rotate_edges_def = {
*/
static BMOpDefine bmo_reverse_faces_def = {
"reverse_faces",
- {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
- {0} /* null-terminating sentinel */,
+ /* slots_in */
+ {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
+ {0},
},
+ {{0}}, /* no output */
bmo_reverse_faces_exec,
BMO_OP_FLAG_UNTAN_MULTIRES,
};
@@ -211,10 +227,14 @@ 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, "numcuts"}, /* number of cuts */
- {BMO_OP_SLOT_ELEMENT_BUF, "outsplit"}, /* newly created vertices and edges */
- {0} /* null-terminating sentinel */,
+ {BMO_OP_SLOT_INT, "cuts"}, /* number of cuts */
+ {0},
+ },
+ /* slots_out */
+ {{BMO_OP_SLOT_ELEMENT_BUF, "geom_split.out"}, /* newly created vertices and edges */
+ {0},
},
bmo_bisect_edges_exec,
BMO_OP_FLAG_UNTAN_MULTIRES
@@ -224,20 +244,25 @@ static BMOpDefine bmo_bisect_edges_def = {
* Mirror
*
* Mirrors geometry along an axis. The resulting geometry is welded on using
- * mergedist. Pairs of original/mirrored vertices are welded using the mergedist
+ * 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",
- {{BMO_OP_SLOT_ELEMENT_BUF, "geom"}, /* input geometry */
- {BMO_OP_SLOT_MAT, "mat"}, /* matrix defining the mirror transformation */
- {BMO_OP_SLOT_FLT, "mergedist"}, /* maximum distance for merging. does no merging if 0. */
- {BMO_OP_SLOT_ELEMENT_BUF, "newout"}, /* output geometry, mirrored */
- {BMO_OP_SLOT_INT, "axis"}, /* the axis to use, 0, 1, or 2 for x, y, z */
+ /* 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, /* null-terminating sentinel */}},
+ {0},
+ },
+ /* slots_out */
+ {{BMO_OP_SLOT_ELEMENT_BUF, "geom.out"}, /* output geometry, mirrored */
+ {0},
+ },
bmo_mirror_exec,
0,
};
@@ -253,11 +278,16 @@ 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 */
- {BMO_OP_SLOT_MAPPING, "targetmapout"},
- {0, /* null-terminating sentinel */}},
+ {0},
+ },
+ /* slots_out */
+ {{BMO_OP_SLOT_MAPPING, "targetmap.out"},
+ {0},
+ },
bmo_find_doubles_exec,
0,
};
@@ -270,9 +300,12 @@ 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, /* null-terminating sentinel */}},
+ {0},
+ },
+ {{0}}, /* no output */
bmo_remove_doubles_exec,
BMO_OP_FLAG_UNTAN_MULTIRES,
};
@@ -286,9 +319,12 @@ static BMOpDefine bmo_remove_doubles_def = {
*/
static BMOpDefine bmo_automerge_def = {
"automerge",
+ /* slots_in */
{{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input verts */
{BMO_OP_SLOT_FLT, "dist"}, /* minimum distance */
- {0, /* null-terminating sentinel */}},
+ {0},
+ },
+ {{0}}, /* no output */
bmo_automerge_exec,
BMO_OP_FLAG_UNTAN_MULTIRES,
};
@@ -300,8 +336,11 @@ static BMOpDefine bmo_automerge_def = {
*/
static BMOpDefine bmo_collapse_def = {
"collapse",
+ /* slots_in */
{{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edge */
- {0, /* null-terminating sentinel */}},
+ {0},
+ },
+ {{0}}, /* no output */
bmo_collapse_exec,
BMO_OP_FLAG_UNTAN_MULTIRES,
};
@@ -314,9 +353,12 @@ static BMOpDefine bmo_collapse_def = {
*/
static BMOpDefine bmo_pointmerge_facedata_def = {
"pointmerge_facedata",
- {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertice */
- {BMO_OP_SLOT_ELEMENT_BUF, "snapv"}, /* snap verte */
- {0, /* null-terminating sentinel */}},
+ /* slots_in */
+ {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertices */
+ {BMO_OP_SLOT_ELEMENT_BUF, "snapv"}, /* snap vertex */
+ {0},
+ },
+ {{0}}, /* no output */
bmo_pointmerge_facedata_exec,
0,
};
@@ -330,8 +372,11 @@ 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, /* null-terminating sentinel */}},
+ {0},
+ },
+ {{0}}, /* no output */
bmo_average_vert_facedata_exec,
0,
};
@@ -343,9 +388,12 @@ static BMOpDefine bmo_average_vert_facedata_def = {
*/
static BMOpDefine bmo_pointmerge_def = {
"pointmerge",
+ /* slots_in */
{{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertice */
{BMO_OP_SLOT_VEC, "merge_co"},
- {0, /* null-terminating sentinel */}},
+ {0},
+ },
+ {{0}}, /* no output */
bmo_pointmerge_exec,
BMO_OP_FLAG_UNTAN_MULTIRES,
};
@@ -357,8 +405,11 @@ static BMOpDefine bmo_pointmerge_def = {
*/
static BMOpDefine bmo_collapse_uvs_def = {
"collapse_uvs",
+ /* slots_in */
{{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edge */
- {0, /* null-terminating sentinel */}},
+ {0},
+ },
+ {{0}}, /* no output */
bmo_collapse_uvs_exec,
0,
};
@@ -372,8 +423,11 @@ static BMOpDefine bmo_collapse_uvs_def = {
*/
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, /* null-terminating sentinel */}},
+ {0},
+ },
+ {{0}}, /* no output */
bmo_weld_verts_exec,
BMO_OP_FLAG_UNTAN_MULTIRES,
};
@@ -386,9 +440,14 @@ 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 */
- {BMO_OP_SLOT_ELEMENT_BUF, "newvertout"}, /* the new vert */
- {0, /* null-terminating sentinel */}},
+ {0},
+ },
+ /* slots_out */
+ {{BMO_OP_SLOT_ELEMENT_BUF, "vert.out"}, /* the new vert */
+ {0},
+ },
bmo_create_vert_exec,
0,
};
@@ -401,14 +460,19 @@ 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_ELEMENT_BUF, "faceout"}, /* joined faces */
{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, /* null-terminating sentinel */}},
+ {0},
+ },
+ /* slots_out */
+ {{BMO_OP_SLOT_ELEMENT_BUF, "faces.out"}, /* joined faces */
+ {0},
+ },
bmo_join_triangles_exec,
BMO_OP_FLAG_UNTAN_MULTIRES,
};
@@ -426,13 +490,18 @@ static BMOpDefine bmo_join_triangles_def = {
*/
static BMOpDefine bmo_contextual_create_def = {
"contextual_create",
- {{BMO_OP_SLOT_ELEMENT_BUF, "geom"}, /* input geometry. */
- {BMO_OP_SLOT_ELEMENT_BUF, "faceout"}, /* newly-made face(s) */
+ /* 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},
+ },
+ /* slots_out */
+ {{BMO_OP_SLOT_ELEMENT_BUF, "faces.out"}, /* 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, "edgeout"}, /* newly-made edge(s) */
- {BMO_OP_SLOT_INT, "mat_nr"}, /* material to use */
- {BMO_OP_SLOT_BOOL, "use_smooth"}, /* material to use */
- {0, /* null-terminating sentinel */}},
+ {BMO_OP_SLOT_ELEMENT_BUF, "edges.out"}, /* newly-made edge(s) */
+ {0},
+ },
bmo_contextual_create_exec,
BMO_OP_FLAG_UNTAN_MULTIRES,
};
@@ -442,27 +511,37 @@ static BMOpDefine bmo_contextual_create_def = {
*/
static BMOpDefine bmo_bridge_loops_def = {
"bridge_loops",
+ /* slots_in */
{{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edge */
- {BMO_OP_SLOT_ELEMENT_BUF, "faceout"}, /* new face */
{BMO_OP_SLOT_BOOL, "use_merge"},
{BMO_OP_SLOT_FLT, "merge_factor"},
- {0, /* null-terminating sentinel */}},
+ {0},
+ },
+ /* slots_out */
+ {{BMO_OP_SLOT_ELEMENT_BUF, "faces.out"}, /* new faces */
+ {0},
+ },
bmo_bridge_loops_exec,
0,
};
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, "excludefaces"}, /* list of faces to ignore for manifold check */
- {BMO_OP_SLOT_MAPPING, "faceout_groupmap"}, /* maps new faces to the group numbers they came fro */
- {BMO_OP_SLOT_ELEMENT_BUF, "faceout"}, /* new face */
+ {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, /* null-terminating sentinel */}},
+ {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},
+ },
bmo_edgenet_fill_exec,
0,
};
@@ -479,9 +558,14 @@ static BMOpDefine bmo_edgenet_fill_def = {
*/
static BMOpDefine bmo_edgenet_prepare_def = {
"edgenet_prepare",
+ /* slots_in */
{{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edges */
- {BMO_OP_SLOT_ELEMENT_BUF, "edgeout"}, /* new edges */
- {0, /* null-terminating sentinel */}},
+ {0},
+ },
+ /* slots_out */
+ {{BMO_OP_SLOT_ELEMENT_BUF, "edges.out"}, /* new edges */
+ {0},
+ },
bmo_edgenet_prepare,
0,
};
@@ -494,10 +578,13 @@ static BMOpDefine bmo_edgenet_prepare_def = {
*/
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, /* null-terminating sentinel */}},
+ {0},
+ },
+ {{0}}, /* no output */
bmo_rotate_exec,
0,
};
@@ -510,9 +597,12 @@ static BMOpDefine bmo_rotate_def = {
*/
static BMOpDefine bmo_translate_def = {
"translate",
+ /* slots_in */
{{BMO_OP_SLOT_VEC, "vec"}, /* translation offset */
{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertices */
- {0, /* null-terminating sentinel */}},
+ {0},
+ },
+ {{0}}, /* no output */
bmo_translate_exec,
0,
};
@@ -524,9 +614,12 @@ static BMOpDefine bmo_translate_def = {
*/
static BMOpDefine bmo_scale_def = {
"scale",
+ /* slots_in */
{{BMO_OP_SLOT_VEC, "vec"}, /* scale factor */
{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertices */
- {0, /* null-terminating sentinel */}},
+ {0},
+ },
+ {{0}}, /* no output */
bmo_scale_exec,
0,
};
@@ -540,9 +633,12 @@ 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, /* null-terminating sentinel */}},
+ {0},
+ },
+ {{0}}, /* no output */
bmo_transform_exec,
0,
};
@@ -555,9 +651,12 @@ 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, /* null-terminating sentinel */}},
+ {0},
+ },
+ {{0}}, /* no output */
bmo_object_load_bmesh_exec,
0,
};
@@ -570,10 +669,13 @@ static BMOpDefine bmo_object_load_bmesh_def = {
*/
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, "notessellation"}, /* don't calculate mfaces */
- {0, /* null-terminating sentinel */}},
+ {BMO_OP_SLOT_BOOL, "skip_tessface"}, /* don't calculate mfaces */
+ {0},
+ },
+ {{0}}, /* no output */
bmo_bmesh_to_mesh_exec,
0,
};
@@ -586,10 +688,13 @@ 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, "set_shapekey"}, /* load active shapekey coordinates into verts */
- {0, /* null-terminating sentinel */}},
+ {BMO_OP_SLOT_BOOL, "use_shapekey"}, /* load active shapekey coordinates into verts */
+ {0},
+ },
+ {{0}}, /* no output */
bmo_mesh_to_bmesh_exec,
0
};
@@ -601,10 +706,15 @@ static BMOpDefine bmo_mesh_to_bmesh_def = {
*/
static BMOpDefine bmo_extrude_discrete_faces_def = {
"extrude_discrete_faces",
+ /* slots_in */
{{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
- {BMO_OP_SLOT_ELEMENT_BUF, "faceout"}, /* output faces */
- {BMO_OP_SLOT_ELEMENT_BUF, "skirtout"}, /* output skirt geometry, faces and edges */
- {0} /* null-terminating sentinel */},
+ {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},
+ },
bmo_extrude_discrete_faces_exec,
0
};
@@ -617,9 +727,14 @@ 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 */
- {BMO_OP_SLOT_ELEMENT_BUF, "geomout"}, /* output geometry */
- {0} /* null-terminating sentinel */},
+ {0},
+ },
+ /* slots_out */
+ {{BMO_OP_SLOT_ELEMENT_BUF, "geom.out"}, /* output geometry */
+ {0},
+ },
bmo_extrude_edge_only_exec,
0
};
@@ -631,125 +746,171 @@ static BMOpDefine bmo_extrude_edge_only_def = {
*/
static BMOpDefine bmo_extrude_vert_indiv_def = {
"extrude_vert_indiv",
+ /* slots_in */
{{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertices */
- {BMO_OP_SLOT_ELEMENT_BUF, "edgeout"}, /* output wire edges */
- {BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, /* output vertices */
- {0} /* null-terminating sentinel */},
+ {0},
+ },
+ /* slots_out */
+ {{BMO_OP_SLOT_ELEMENT_BUF, "edges.out"}, /* output wire edges */
+ {BMO_OP_SLOT_ELEMENT_BUF, "verts.out"}, /* output vertices */
+ {0},
+ },
bmo_extrude_vert_indiv_exec,
0
};
static BMOpDefine bmo_connect_verts_def = {
"connect_verts",
+ /* slots_in */
{{BMO_OP_SLOT_ELEMENT_BUF, "verts"},
- {BMO_OP_SLOT_ELEMENT_BUF, "edgeout"},
- {0} /* null-terminating sentinel */},
+ {0},
+ },
+ /* slots_out */
+ {{BMO_OP_SLOT_ELEMENT_BUF, "edges.out"},
+ {0},
+ },
bmo_connect_verts_exec,
BMO_OP_FLAG_UNTAN_MULTIRES
};
static BMOpDefine bmo_extrude_face_region_def = {
"extrude_face_region",
- {{BMO_OP_SLOT_ELEMENT_BUF, "edgefacein"},
- {BMO_OP_SLOT_MAPPING, "exclude"},
- {BMO_OP_SLOT_BOOL, "alwayskeeporig"},
- {BMO_OP_SLOT_ELEMENT_BUF, "geomout"},
- {0} /* null-terminating sentinel */},
+ /* 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},
+ },
+ /* slots_out */
+ {{BMO_OP_SLOT_ELEMENT_BUF, "geom.out"},
+ {0},
+ },
bmo_extrude_face_region_exec,
0
};
static BMOpDefine bmo_dissolve_verts_def = {
"dissolve_verts",
+ /* slots_in */
{{BMO_OP_SLOT_ELEMENT_BUF, "verts"},
- {0} /* null-terminating sentinel */},
+ {0},
+ },
+ {{0}}, /* no output */
bmo_dissolve_verts_exec,
BMO_OP_FLAG_UNTAN_MULTIRES
};
static BMOpDefine bmo_dissolve_edges_def = {
"dissolve_edges",
+ /* slots_in */
{{BMO_OP_SLOT_ELEMENT_BUF, "edges"},
- {BMO_OP_SLOT_ELEMENT_BUF, "regionout"},
{BMO_OP_SLOT_BOOL, "use_verts"}, /* dissolve verts left between only 2 edges. */
- {0} /* null-terminating sentinel */},
+ {0},
+ },
+ /* slots_out */
+ {{BMO_OP_SLOT_ELEMENT_BUF, "region.out"},
+ {0},
+ },
bmo_dissolve_edges_exec,
BMO_OP_FLAG_UNTAN_MULTIRES
};
static BMOpDefine bmo_dissolve_edge_loop_def = {
"dissolve_edge_loop",
+ /* slots_in */
{{BMO_OP_SLOT_ELEMENT_BUF, "edges"},
- {BMO_OP_SLOT_ELEMENT_BUF, "regionout"},
- {0} /* null-terminating sentinel */},
+ {0},
+ },
+ /* slots_out */
+ {{BMO_OP_SLOT_ELEMENT_BUF, "region.out"},
+ {0},
+ },
bmo_dissolve_edgeloop_exec,
BMO_OP_FLAG_UNTAN_MULTIRES
};
static BMOpDefine bmo_dissolve_faces_def = {
"dissolve_faces",
+ /* slots_in */
{{BMO_OP_SLOT_ELEMENT_BUF, "faces"},
- {BMO_OP_SLOT_ELEMENT_BUF, "regionout"},
{BMO_OP_SLOT_BOOL, "use_verts"}, /* dissolve verts left between only 2 edges. */
- {0} /* null-terminating sentinel */},
+ {0},
+ },
+ /* slots_out */
+ {{BMO_OP_SLOT_ELEMENT_BUF, "region.out"},
+ {0},
+ },
bmo_dissolve_faces_exec,
BMO_OP_FLAG_UNTAN_MULTIRES
};
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} /* null-terminating sentinel */},
+ {0},
+ },
+ {{0}}, /* no output */
bmo_dissolve_limit_exec,
BMO_OP_FLAG_UNTAN_MULTIRES
};
static BMOpDefine bmo_triangulate_def = {
"triangulate",
+ /* slots_in */
{{BMO_OP_SLOT_ELEMENT_BUF, "faces"},
- {BMO_OP_SLOT_ELEMENT_BUF, "edgeout"},
- {BMO_OP_SLOT_ELEMENT_BUF, "faceout"},
- {BMO_OP_SLOT_MAPPING, "facemap"},
{BMO_OP_SLOT_BOOL, "use_beauty"},
- {0} /* null-terminating sentinel */},
+ {0},
+ },
+ /* slots_out */
+ {{BMO_OP_SLOT_ELEMENT_BUF, "edges.out"},
+ {BMO_OP_SLOT_ELEMENT_BUF, "faces.out"},
+ {BMO_OP_SLOT_MAPPING, "facemap.out"},
+ {0},
+ },
bmo_triangulate_exec,
BMO_OP_FLAG_UNTAN_MULTIRES
};
static BMOpDefine bmo_unsubdivide_def = {
"unsubdivide",
+ /* slots_in */
{{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertices */
{BMO_OP_SLOT_INT, "iterations"},
- {0} /* null-terminating sentinel */},
+ {0},
+ },
+ {{0}}, /* no output */
bmo_unsubdivide_exec,
BMO_OP_FLAG_UNTAN_MULTIRES
};
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, "numcuts"},
+ {BMO_OP_SLOT_INT, "cuts"},
{BMO_OP_SLOT_INT, "seed"},
{BMO_OP_SLOT_MAPPING, "custompatterns"},
{BMO_OP_SLOT_MAPPING, "edgepercents"},
- /* these next three can have multiple types of elements in them */
- {BMO_OP_SLOT_ELEMENT_BUF, "outinner"},
- {BMO_OP_SLOT_ELEMENT_BUF, "outsplit"},
- {BMO_OP_SLOT_ELEMENT_BUF, "geomout"}, /* contains all output geometr */
-
- {BMO_OP_SLOT_INT, "quadcornertype"}, /* quad corner type, see bmesh_operators.h */
+ {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} /* null-terminating sentinel */,
+ {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},
},
bmo_subdivide_edges_exec,
BMO_OP_FLAG_UNTAN_MULTIRES
@@ -757,38 +918,51 @@ static BMOpDefine bmo_subdivide_edges_def = {
static BMOpDefine bmo_delete_def = {
"delete",
+ /* slots_in */
{{BMO_OP_SLOT_ELEMENT_BUF, "geom"},
{BMO_OP_SLOT_INT, "context"},
- {0} /* null-terminating sentinel */},
+ {0},
+ },
+ {{0}}, /* no output */
bmo_delete_exec,
0
};
static BMOpDefine bmo_duplicate_def = {
"duplicate",
+ /* slots_in */
{{BMO_OP_SLOT_ELEMENT_BUF, "geom"},
- {BMO_OP_SLOT_ELEMENT_BUF, "origout"},
- {BMO_OP_SLOT_ELEMENT_BUF, "newout"},
+ {BMO_OP_SLOT_PTR, "dest"}, /* destination bmesh, if NULL will use current on */
+ {0},
+ },
+ /* slots_out */
+ {{BMO_OP_SLOT_ELEMENT_BUF, "geom_orig.out"},
+ {BMO_OP_SLOT_ELEMENT_BUF, "geom.out"},
/* facemap maps from source faces to dupe
* faces, and from dupe faces to source faces */
- {BMO_OP_SLOT_MAPPING, "facemap"},
- {BMO_OP_SLOT_MAPPING, "boundarymap"},
- {BMO_OP_SLOT_MAPPING, "isovertmap"},
- {BMO_OP_SLOT_PTR, "dest"}, /* destination bmesh, if NULL will use current on */
- {0} /* null-terminating sentinel */},
+ {BMO_OP_SLOT_MAPPING, "facemap.out"},
+ {BMO_OP_SLOT_MAPPING, "boundarymap.out"},
+ {BMO_OP_SLOT_MAPPING, "isovertmap.out"},
+ {0},
+ },
bmo_duplicate_exec,
0
};
static BMOpDefine bmo_split_def = {
"split",
+ /* slots_in */
{{BMO_OP_SLOT_ELEMENT_BUF, "geom"},
- {BMO_OP_SLOT_ELEMENT_BUF, "geomout"},
- {BMO_OP_SLOT_MAPPING, "boundarymap"},
- {BMO_OP_SLOT_MAPPING, "isovertmap"},
- {BMO_OP_SLOT_PTR, "dest"}, /* destination bmesh, if NULL will use current on */
- {BMO_OP_SLOT_BOOL, "use_only_faces"}, /* when enabled. don't duplicate loose verts/edges */
- {0} /* null-terminating sentinel */},
+ {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},
+ },
+ /* slots_out */
+ {{BMO_OP_SLOT_ELEMENT_BUF, "geom.out"},
+ {BMO_OP_SLOT_MAPPING, "boundarymap.out"},
+ {BMO_OP_SLOT_MAPPING, "isovertmap.out"},
+ {0},
+ },
bmo_split_exec,
0
};
@@ -801,15 +975,20 @@ static BMOpDefine bmo_split_def = {
*/
static BMOpDefine bmo_spin_def = {
"spin",
+ /* slots_in */
{{BMO_OP_SLOT_ELEMENT_BUF, "geom"},
- {BMO_OP_SLOT_ELEMENT_BUF, "lastout"}, /* result of last step */
- {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, "ang"}, /* total rotation angle (degrees) */
- {BMO_OP_SLOT_INT, "steps"}, /* number of steps */
- {BMO_OP_SLOT_BOOL, "do_dupli"}, /* duplicate or extrude? */
- {0} /* null-terminating sentinel */},
+ {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},
+ },
+ /* slots_out */
+ {{BMO_OP_SLOT_ELEMENT_BUF, "geom_last.out"}, /* result of last step */
+ {0},
+ },
bmo_spin_exec,
0
};
@@ -822,12 +1001,17 @@ static BMOpDefine bmo_spin_def = {
*/
static BMOpDefine bmo_similar_faces_def = {
"similar_faces",
+ /* slots_in */
{{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
- {BMO_OP_SLOT_ELEMENT_BUF, "faceout"}, /* output 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} /* null-terminating sentinel */},
+ {0},
+ },
+ /* slots_out */
+ {{BMO_OP_SLOT_ELEMENT_BUF, "faces.out"}, /* output faces */
+ {0},
+ },
bmo_similar_faces_exec,
0
};
@@ -839,12 +1023,17 @@ static BMOpDefine bmo_similar_faces_def = {
*/
static BMOpDefine bmo_similar_edges_def = {
"similar_edges",
+ /* slots_in */
{{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edges */
- {BMO_OP_SLOT_ELEMENT_BUF, "edgeout"}, /* output 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} /* null-terminating sentinel */},
+ {0},
+ },
+ /* slots_out */
+ {{BMO_OP_SLOT_ELEMENT_BUF, "edges.out"}, /* output edges */
+ {0},
+ },
bmo_similar_edges_exec,
0
};
@@ -856,12 +1045,17 @@ static BMOpDefine bmo_similar_edges_def = {
*/
static BMOpDefine bmo_similar_verts_def = {
"similar_verts",
+ /* slots_in */
{{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertices */
- {BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, /* output 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} /* null-terminating sentinel */},
+ {0},
+ },
+ /* slots_out */
+ {{BMO_OP_SLOT_ELEMENT_BUF, "verts.out"}, /* output vertices */
+ {0},
+ },
bmo_similar_verts_exec,
0
};
@@ -872,9 +1066,13 @@ static BMOpDefine bmo_similar_verts_def = {
*/
static BMOpDefine bmo_rotate_uvs_def = {
"rotate_uvs",
- {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
- {BMO_OP_SLOT_INT, "dir"}, /* direction */
- {0} /* null-terminating sentinel */},
+ /* slots_in */
+ {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
+ {BMO_OP_SLOT_BOOL, "use_ccw"}, /* rotate counter-clockwise if true, othewise clockwise */
+ {0},
+ },
+ /* slots_out */
+ {{0}}, /* no output */
bmo_rotate_uvs_exec,
0
};
@@ -885,8 +1083,11 @@ static BMOpDefine bmo_rotate_uvs_def = {
*/
static BMOpDefine bmo_reverse_uvs_def = {
"reverse_uvs",
- {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
- {0} /* null-terminating sentinel */},
+ /* slots_in */
+ {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
+ {0},
+ },
+ {{0}}, /* no output */
bmo_reverse_uvs_exec,
0
};
@@ -897,9 +1098,12 @@ static BMOpDefine bmo_reverse_uvs_def = {
*/
static BMOpDefine bmo_rotate_colors_def = {
"rotate_colors",
- {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
- {BMO_OP_SLOT_INT, "dir"}, /* direction */
- {0} /* null-terminating sentinel */},
+ /* slots_in */
+ {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
+ {BMO_OP_SLOT_BOOL, "use_ccw"}, /* rotate counter-clockwise if true, othewise clockwise */
+ {0},
+ },
+ {{0}}, /* no output */
bmo_rotate_colors_exec,
0
};
@@ -910,8 +1114,11 @@ static BMOpDefine bmo_rotate_colors_def = {
*/
static BMOpDefine bmo_reverse_colors_def = {
"reverse_colors",
- {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
- {0} /* null-terminating sentinel */},
+ /* slots_in */
+ {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
+ {0},
+ },
+ {{0}}, /* no output */
bmo_reverse_colors_exec,
0
};
@@ -923,11 +1130,16 @@ static BMOpDefine bmo_reverse_colors_def = {
*/
static BMOpDefine bmo_shortest_path_def = {
"shortest_path",
- {{BMO_OP_SLOT_ELEMENT_BUF, "startv"}, /* start vertex */
- {BMO_OP_SLOT_ELEMENT_BUF, "endv"}, /* end vertex */
- {BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, /* output vertices */
- {BMO_OP_SLOT_INT, "type"}, /* type of selection */
- {0} /* null-terminating sentinel */},
+ /* 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},
+ },
+ /* slots_out */
+ {{BMO_OP_SLOT_ELEMENT_BUF, "verts.out"}, /* output vertices */
+ {0},
+ },
bmo_shortest_path_exec,
0
};
@@ -939,12 +1151,17 @@ static BMOpDefine bmo_shortest_path_def = {
*/
static BMOpDefine bmo_split_edges_def = {
"split_edges",
- {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edges */
- {BMO_OP_SLOT_ELEMENT_BUF, "edgeout"}, /* old output disconnected edges */
+ /* slots_in */
+ {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* 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_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} /* null-terminating sentinel */},
+ {0},
+ },
+ /* slots_out */
+ {{BMO_OP_SLOT_ELEMENT_BUF, "edges.out"}, /* old output disconnected edges */
+ {0},
+ },
bmo_split_edges_exec,
BMO_OP_FLAG_UNTAN_MULTIRES
};
@@ -956,12 +1173,17 @@ static BMOpDefine bmo_split_edges_def = {
*/
static BMOpDefine bmo_create_grid_def = {
"create_grid",
- {{BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, /* output verts */
- {BMO_OP_SLOT_INT, "xsegments"}, /* number of x segments */
- {BMO_OP_SLOT_INT, "ysegments"}, /* 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, /* null-terminating sentinel */}},
+ /* 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},
+ },
+ /* slots_out */
+ {{BMO_OP_SLOT_ELEMENT_BUF, "verts.out"}, /* output verts */
+ {0},
+ },
bmo_create_grid_exec,
0,
};
@@ -973,12 +1195,17 @@ static BMOpDefine bmo_create_grid_def = {
*/
static BMOpDefine bmo_create_uvsphere_def = {
"create_uvsphere",
- {{BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, /* output verts */
- {BMO_OP_SLOT_INT, "segments"}, /* number of u segments */
- {BMO_OP_SLOT_INT, "revolutions"}, /* number of v segment */
+ /* 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, /* null-terminating sentinel */}},
+ {BMO_OP_SLOT_MAT, "mat"}, /* matrix to multiply the new geometry with */
+ {0},
+ },
+ /* slots_out */
+ {{BMO_OP_SLOT_ELEMENT_BUF, "verts.out"}, /* output verts */
+ {0},
+ },
bmo_create_uvsphere_exec,
0,
};
@@ -990,11 +1217,16 @@ static BMOpDefine bmo_create_uvsphere_def = {
*/
static BMOpDefine bmo_create_icosphere_def = {
"create_icosphere",
- {{BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, /* output verts */
- {BMO_OP_SLOT_INT, "subdivisions"}, /* how many times to recursively subdivide the sphere */
+ /* 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, /* null-terminating sentinel */}},
+ {0},
+ },
+ /* slots_out */
+ {{BMO_OP_SLOT_ELEMENT_BUF, "verts.out"}, /* output verts */
+ {0},
+ },
bmo_create_icosphere_exec,
0,
};
@@ -1006,9 +1238,14 @@ static BMOpDefine bmo_create_icosphere_def = {
*/
static BMOpDefine bmo_create_monkey_def = {
"create_monkey",
- {{BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, /* output verts */
- {BMO_OP_SLOT_MAT, "mat"}, /* matrix to multiply the new geometry with-- */
- {0, /* null-terminating sentinel */}},
+ /* slots_in */
+ {{BMO_OP_SLOT_MAT, "mat"}, /* matrix to multiply the new geometry with */
+ {0},
+ },
+ /* slots_out */
+ {{BMO_OP_SLOT_ELEMENT_BUF, "verts.out"}, /* output verts */
+ {0},
+ },
bmo_create_monkey_exec,
0,
};
@@ -1020,15 +1257,20 @@ static BMOpDefine bmo_create_monkey_def = {
*/
static BMOpDefine bmo_create_cone_def = {
"create_cone",
- {{BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, /* output verts */
- {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 */
+ /* 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, /* null-terminating sentinel */}},
+ {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},
+ },
+ /* slots_out */
+ {{BMO_OP_SLOT_ELEMENT_BUF, "verts.out"}, /* output verts */
+ {0},
+ },
bmo_create_cone_exec,
0,
};
@@ -1038,13 +1280,18 @@ static BMOpDefine bmo_create_cone_def = {
*/
static BMOpDefine bmo_create_circle_def = {
"create_circle",
- {{BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, /* output verts */
- {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 */
+ /* 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, /* null-terminating sentinel */}},
+ {BMO_OP_SLOT_FLT, "diameter"}, /* diameter of one end */
+ {BMO_OP_SLOT_MAT, "mat"}, /* matrix to multiply the new geometry with */
+ {0},
+ },
+ /* slots_out */
+ {{BMO_OP_SLOT_ELEMENT_BUF, "verts.out"}, /* output verts */
+ {0},
+ },
bmo_create_circle_exec,
0,
};
@@ -1056,15 +1303,19 @@ static BMOpDefine bmo_create_circle_def = {
*/
static BMOpDefine bmo_create_cube_def = {
"create_cube",
- {{BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, /* output verts */
- {BMO_OP_SLOT_FLT, "size"}, /* size of the cube */
- {BMO_OP_SLOT_MAT, "mat"}, /* matrix to multiply the new geometry with-- */
- {0, /* null-terminating sentinel */}},
+ /* slots_in */
+ {{BMO_OP_SLOT_FLT, "size"}, /* size of the cube */
+ {BMO_OP_SLOT_MAT, "mat"}, /* matrix to multiply the new geometry with */
+ {0},
+ },
+ /* slots_out */
+ {{BMO_OP_SLOT_ELEMENT_BUF, "verts.out"}, /* output verts */
+ {0},
+ },
bmo_create_cube_exec,
0,
};
-#define NEW_BEVEL 1
/*
* Bevel
*
@@ -1072,12 +1323,17 @@ static BMOpDefine bmo_create_cube_def = {
*/
static BMOpDefine bmo_bevel_def = {
"bevel",
-#ifdef NEW_BEVEL
- {{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} /* null-terminating sentinel */},
-#else
+ /* 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},
+ },
+ /* 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 */
@@ -1087,7 +1343,8 @@ static BMOpDefine bmo_bevel_def = {
* 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} /* null-terminating sentinel */},
+ {0},
+ },
#endif
bmo_bevel_exec,
BMO_OP_FLAG_UNTAN_MULTIRES
@@ -1100,10 +1357,15 @@ static BMOpDefine bmo_bevel_def = {
*/
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 */
- {BMO_OP_SLOT_ELEMENT_BUF, "geomout"}, /* new flipped faces and edges */
- {0} /* null-terminating sentinel */},
+ {0},
+ },
+ /* slots_out */
+ {{BMO_OP_SLOT_ELEMENT_BUF, "geom.out"}, /* new flipped faces and edges */
+ {0},
+ },
bmo_beautify_fill_exec,
BMO_OP_FLAG_UNTAN_MULTIRES
};
@@ -1115,9 +1377,14 @@ static BMOpDefine bmo_beautify_fill_def = {
*/
static BMOpDefine bmo_triangle_fill_def = {
"triangle_fill",
- {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edges */
- {BMO_OP_SLOT_ELEMENT_BUF, "geomout"}, /* new faces and edges */
- {0} /* null-terminating sentinel */},
+ /* slots_in */
+ {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edges */
+ {0},
+ },
+ /* slots_out */
+ {{BMO_OP_SLOT_ELEMENT_BUF, "geom.out"}, /* new faces and edges */
+ {0},
+ },
bmo_triangle_fill_exec,
BMO_OP_FLAG_UNTAN_MULTIRES
};
@@ -1129,10 +1396,15 @@ static BMOpDefine bmo_triangle_fill_def = {
*/
static BMOpDefine bmo_solidify_def = {
"solidify",
+ /* slots_in */
{{BMO_OP_SLOT_ELEMENT_BUF, "geom"},
{BMO_OP_SLOT_FLT, "thickness"},
- {BMO_OP_SLOT_ELEMENT_BUF, "geomout"},
- {0}},
+ {0},
+ },
+ /* slots_out */
+ {{BMO_OP_SLOT_ELEMENT_BUF, "geom.out"},
+ {0},
+ },
bmo_solidify_face_region_exec,
0
};
@@ -1144,15 +1416,20 @@ static BMOpDefine bmo_solidify_def = {
*/
static BMOpDefine bmo_inset_def = {
"inset",
- {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
- {BMO_OP_SLOT_ELEMENT_BUF, "faceout"}, /* output faces */
+ /* 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} /* null-terminating sentinel */},
+ {0},
+ },
+ /* slots_out */
+ {{BMO_OP_SLOT_ELEMENT_BUF, "faces.out"}, /* output faces */
+ {0},
+ },
bmo_inset_exec,
0
};
@@ -1164,15 +1441,20 @@ static BMOpDefine bmo_inset_def = {
*/
static BMOpDefine bmo_wireframe_def = {
"wireframe",
+ /* slots_in */
{{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
- {BMO_OP_SLOT_ELEMENT_BUF, "faceout"}, /* output 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} /* null-terminating sentinel */},
+ {0},
+ },
+ /* slots_out */
+ {{BMO_OP_SLOT_ELEMENT_BUF, "faces.out"}, /* output faces */
+ {0},
+ },
bmo_wireframe_exec,
0
};
@@ -1184,11 +1466,16 @@ static BMOpDefine bmo_wireframe_def = {
*/
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_ELEMENT_BUF, "vertout"},
{BMO_OP_SLOT_FLT, "distance_t"},
- {0} /* null-terminating sentinel */},
+ {0},
+ },
+ /* slots_out */
+ {{BMO_OP_SLOT_ELEMENT_BUF, "verts.out"},
+ {0},
+ },
bmo_slide_vert_exec,
BMO_OP_FLAG_UNTAN_MULTIRES
};
@@ -1202,7 +1489,7 @@ static BMOpDefine bmo_slide_vert_def = {
* If 'use_existing_faces' is true, the hull will not output triangles
* that are covered by a pre-existing face.
*
- * All hull vertices, faces, and edges are added to 'geomout'. Any
+ * All hull vertices, faces, and edges are added to 'geom.out'. Any
* input elements that end up inside the hull (i.e. are not used by an
* output face) are added to the 'interior_geom' slot. The
* 'unused_geom' slot will contain all interior geometry that is
@@ -1211,15 +1498,18 @@ 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"},
-
- /* Outputs */
- {BMO_OP_SLOT_ELEMENT_BUF, "geomout"},
- {BMO_OP_SLOT_ELEMENT_BUF, "interior_geom"},
- {BMO_OP_SLOT_ELEMENT_BUF, "unused_geom"},
- {BMO_OP_SLOT_ELEMENT_BUF, "holes_geom"},
- {0} /* null-terminating sentinel */},
+ {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},
+ },
bmo_convex_hull_exec,
0
};
@@ -1233,17 +1523,19 @@ static BMOpDefine bmo_convex_hull_def = {
* the "direction" slot. The edges and faces that cross the plane of
* symmetry are split as needed to enforce symmetry.
*
- * All new vertices, edges, and faces are added to the "geomout" slot.
+ * All new vertices, edges, and faces are added to the "geom.out" slot.
*/
static BMOpDefine bmo_symmetrize_def = {
"symmetrize",
+ /* slots_in */
{{BMO_OP_SLOT_ELEMENT_BUF, "input"},
{BMO_OP_SLOT_INT, "direction"},
-
- /* Outputs */
- {BMO_OP_SLOT_ELEMENT_BUF, "geomout"},
-
- {0} /* null-terminating sentinel */},
+ {0},
+ },
+ /* slots_out */
+ {{BMO_OP_SLOT_ELEMENT_BUF, "geom.out"},
+ {0},
+ },
bmo_symmetrize_exec,
0
};
diff --git a/source/blender/bmesh/intern/bmesh_operator_api.h b/source/blender/bmesh/intern/bmesh_operator_api.h
index 671cfbbc55e..b87e023e63a 100644
--- a/source/blender/bmesh/intern/bmesh_operator_api.h
+++ b/source/blender/bmesh/intern/bmesh_operator_api.h
@@ -116,30 +116,45 @@ enum {
* for when your defining an operator with BMOpDefine.*/
typedef struct BMOpSlot {
+ const char *slot_name; /* pointer to BMOpDefine.slot_args */
int slot_type;
int len;
- int flag;
- int index; /* index within slot array */
+// int flag; /* UNUSED */
+// int index; /* index within slot array */ /* UNUSED */
union {
int i;
float f;
void *p;
float vec[3];
- void *buf;
+ void **buf;
GHash *ghash;
} data;
} BMOpSlot;
-#define BMO_OP_MAX_SLOTS 16 /* way more than probably needed */
+/* mainly for use outside bmesh internal code */
+#define BMO_SLOT_AS_BOOL(slot) ((slot)->data.i)
+#define BMO_SLOT_AS_INT(slot) ((slot)->data.i)
+#define BMO_SLOT_AS_FLOAT(slot) ((slot)->data.f)
+#define BMO_SLOT_AS_VECTOR(slot) ((slot)->data.vec)
+#define BMO_SLOT_AS_MATRIX(slot ) ((float (*)[4])((slot)->data.p))
+#define BMO_SLOT_AS_BUFFER(slot ) ((slot)->data.buf)
+#define BMO_SLOT_AS_GHASH(slot ) ((slot)->data.ghash)
+
+#define BMO_ASSERT_SLOT_IN_OP(slot, op) \
+ BLI_assert(((slot >= (op)->slots_in) && (slot < &(op)->slots_in[BMO_OP_MAX_SLOTS])) || \
+ ((slot >= (op)->slots_out) && (slot < &(op)->slots_out[BMO_OP_MAX_SLOTS])))
+
+/* way more than probably needed, compiler complains if limit hit */
+#define BMO_OP_MAX_SLOTS 16
typedef struct BMOperator {
+ struct BMOpSlot slots_in[BMO_OP_MAX_SLOTS];
+ struct BMOpSlot slots_out[BMO_OP_MAX_SLOTS];
+ void (*exec)(BMesh *bm, struct BMOperator *op);
+ struct MemArena *arena;
int type;
- int slot_type;
int type_flag;
int flag; /* runtime options */
- struct BMOpSlot slot_args[BMO_OP_MAX_SLOTS];
- void (*exec)(BMesh *bm, struct BMOperator *op);
- struct MemArena *arena;
} BMOperator;
enum {
@@ -156,8 +171,9 @@ typedef struct BMOSlotType {
} BMOSlotType;
typedef struct BMOpDefine {
- const char *name;
- BMOSlotType slot_types[BMO_OP_MAX_SLOTS];
+ const char *opname;
+ BMOSlotType slot_types_in[BMO_OP_MAX_SLOTS];
+ BMOSlotType slot_types_out[BMO_OP_MAX_SLOTS];
void (*exec)(BMesh *bm, BMOperator *op);
int type_flag;
} BMOpDefine;
@@ -245,15 +261,22 @@ int BMO_op_initf(BMesh *bm, BMOperator *op, const int flag, const char *fmt, ...
int BMO_op_vinitf(BMesh *bm, BMOperator *op, const int flag, const char *fmt, va_list vlist);
/* test whether a named slot exists */
-int BMO_slot_exists(BMOperator *op, const char *slot_name);
+int BMO_slot_exists(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *identifier);
/* get a pointer to a slot. this may be removed layer on from the public API. */
-BMOpSlot *BMO_slot_get(BMOperator *op, const char *slot_name);
+BMOpSlot *BMO_slot_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *identifier);
/* copies the data of a slot from one operator to another. src and dst are the
* source/destination slot codes, respectively. */
-void BMO_slot_copy(BMOperator *source_op, BMOperator *dest_op,
- const char *src, const char *dst);
+#define BMO_slot_copy(op_src, slots_src, slot_name_src, \
+ op_dst, slots_dst, slot_name_dst) \
+ _bmo_slot_copy((op_src)->slots_src, slot_name_src, \
+ (op_dst)->slots_dst, slot_name_dst, \
+ (op_dst)->arena)
+
+void _bmo_slot_copy(BMOpSlot slot_args_src[BMO_OP_MAX_SLOTS], const char *slot_name_src,
+ BMOpSlot slot_args_dst[BMO_OP_MAX_SLOTS], const char *slot_name_dst,
+ struct MemArena *arena_dst);
/* del "context" slot values, used for operator too */
enum {
@@ -279,13 +302,13 @@ typedef enum {
void BMO_op_flag_enable(BMesh *bm, BMOperator *op, const int op_flag);
void BMO_op_flag_disable(BMesh *bm, BMOperator *op, const int op_flag);
-void BMO_slot_float_set(BMOperator *op, const char *slot_name, const float f);
-float BMO_slot_float_get(BMOperator *op, const char *slot_name);
-void BMO_slot_int_set(BMOperator *op, const char *slot_name, const int i);
-int BMO_slot_int_get(BMOperator *op, const char *slot_name);
-void BMO_slot_bool_set(BMOperator *op, const char *slot_name, const int i);
-int BMO_slot_bool_get(BMOperator *op, const char *slot_name);
-void *BMO_slot_as_arrayN(BMOperator *op, const char *slot_name, int *len);
+void BMO_slot_float_set(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const float f);
+float BMO_slot_float_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name);
+void BMO_slot_int_set(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const int i);
+int BMO_slot_int_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name);
+void BMO_slot_bool_set(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const int i);
+int BMO_slot_bool_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name);
+void *BMO_slot_as_arrayN(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, int *len);
/* don't pass in arrays that are supposed to map to elements this way.
@@ -293,69 +316,81 @@ void *BMO_slot_as_arrayN(BMOperator *op, const char *slot_name, int *len);
* so, e.g. passing in list of floats per element in another slot is bad.
* passing in, e.g. pointer to an editmesh for the conversion operator is fine
* though. */
-void BMO_slot_ptr_set(BMOperator *op, const char *slot_name, void *p);
-void *BMO_slot_ptr_get(BMOperator *op, const char *slot_name);
-void BMO_slot_vec_set(BMOperator *op, const char *slot_name, const float vec[3]);
-void BMO_slot_vec_get(BMOperator *op, const char *slot_name, float r_vec[3]);
+void BMO_slot_ptr_set(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, void *p);
+void *BMO_slot_ptr_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name);
+void BMO_slot_vec_set(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const float vec[3]);
+void BMO_slot_vec_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, float r_vec[3]);
/* only supports square mats */
/* size must be 3 or 4; this api is meant only for transformation matrices.
* note that internally the matrix is stored in 4x4 form, and it's safe to
* call whichever BMO_Get_MatXXX function you want. */
-void BMO_slot_mat_set(BMOperator *op, const char *slot_name, const float *mat, int size);
-void BMO_slot_mat4_get(BMOperator *op, const char *slot_name, float r_mat[4][4]);
-void BMO_slot_mat3_set(BMOperator *op, const char *slot_name, float r_mat[3][3]);
+void BMO_slot_mat_set(BMOperator *op, BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const float *mat, int size);
+void BMO_slot_mat4_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, float r_mat[4][4]);
+void BMO_slot_mat3_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, float r_mat[3][3]);
void BMO_mesh_flag_disable_all(BMesh *bm, BMOperator *op, const char htype, const short oflag);
/* copies the values from another slot to the end of the output slot */
-void BMO_slot_buffer_append(BMOperator *output_op, const char *output_op_slot,
- BMOperator *other_op, const char *other_op_slot);
+#define BMO_slot_buffer_append(op_src, slots_src, slot_name_src, \
+ op_dst, slots_dst, slot_name_dst) \
+ _bmo_slot_buffer_append((op_src)->slots_src, slot_name_src, \
+ (op_dst)->slots_dst, slot_name_dst, \
+ (op_dst)->arena)
+void _bmo_slot_buffer_append(BMOpSlot slot_args_dst[BMO_OP_MAX_SLOTS], const char *slot_name_dst,
+ BMOpSlot slot_args_src[BMO_OP_MAX_SLOTS], const char *slot_name_src,
+ struct MemArena *arena_dst);
/* puts every element of type 'type' (which is a bitmask) with tool
* flag 'flag', into a slot. */
-void BMO_slot_buffer_from_enabled_flag(BMesh *bm, BMOperator *op, const char *slot_name,
+void BMO_slot_buffer_from_enabled_flag(BMesh *bm, BMOperator *op,
+ BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
const char htype, const short oflag);
/* puts every element of type 'type' (which is a bitmask) without tool
* flag 'flag', into a slot. */
-void BMO_slot_buffer_from_disabled_flag(BMesh *bm, BMOperator *op, const char *slot_name,
+void BMO_slot_buffer_from_disabled_flag(BMesh *bm, BMOperator *op,
+ BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
const char htype, const short oflag);
/* tool-flags all elements inside an element slot array with flag flag. */
-void BMO_slot_buffer_flag_enable(BMesh *bm, BMOperator *op, const char *slot_name,
+void BMO_slot_buffer_flag_enable(BMesh *bm,
+ BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
const char htype, const short oflag);
/* clears tool-flag flag from all elements inside a slot array. */
-void BMO_slot_buffer_flag_disable(BMesh *bm, BMOperator *op, const char *slot_name,
+void BMO_slot_buffer_flag_disable(BMesh *bm,
+ BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
const char htype, const short oflag);
/* tool-flags all elements inside an element slot array with flag flag. */
-void BMO_slot_buffer_hflag_enable(BMesh *bm, BMOperator *op, const char *slot_name,
+void BMO_slot_buffer_hflag_enable(BMesh *bm,
+ BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
const char htype, const char hflag, const char do_flush);
/* clears tool-flag flag from all elements inside a slot array. */
-void BMO_slot_buffer_hflag_disable(BMesh *bm, BMOperator *op, const char *slot_name,
+void BMO_slot_buffer_hflag_disable(BMesh *bm,
+ BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
const char htype, const char hflag, const char do_flush);
/* puts every element of type 'type' (which is a bitmask) with header
* flag 'flag', into a slot. note: ignores hidden elements
* (e.g. elements with header flag BM_ELEM_HIDDEN set).*/
void BMO_slot_buffer_from_enabled_hflag(BMesh *bm, BMOperator *op,
- const char *slot_name,
+ BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
const char htype, const char hflag);
/* puts every element of type 'type' (which is a bitmask) without
* header flag 'flag', into a slot. note: ignores hidden elements
* (e.g. elements with header flag BM_ELEM_HIDDEN set).*/
void BMO_slot_buffer_from_disabled_hflag(BMesh *bm, BMOperator *op,
- const char *slot_name,
+ BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
const char htype, const char hflag);
/* counts number of elements inside a slot array. */
-int BMO_slot_buffer_count(BMesh *bm, BMOperator *op, const char *slot_name);
-int BMO_slot_map_count(BMesh *bm, BMOperator *op, const char *slot_name);
+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(BMesh *UNUSED(bm), BMOperator *op, const char *slot_name,
- void *element, void *data, int len);
+void BMO_slot_map_insert(BMOperator *op, BMOpSlot *slot,
+ const void *element, void *data, int len);
/* Counts the number of edges with tool flag toolflag around
*/
@@ -363,13 +398,14 @@ int BMO_vert_edge_flags_count(BMesh *bm, BMVert *v, const short oflag);
/* flags all elements in a mapping. note that the mapping must only have
* bmesh elements in it.*/
-void BMO_slot_map_to_flag(BMesh *bm, BMOperator *op, const char *slot_name,
- const char hflag, const short oflag);
+void BMO_slot_map_to_flag(BMesh *bm, BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
+ const char *slot_name, const char hflag, const short oflag);
-void *BMO_slot_buffer_alloc(BMOperator *op, const char *slot_name, const int len);
+void *BMO_slot_buffer_alloc(BMOperator *op, BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
+ const char *slot_name, const int len);
-void BMO_slot_buffer_from_all(BMesh *bm, BMOperator *op, const char *slot_name,
- const char htype);
+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
* mapping slots.
@@ -412,10 +448,11 @@ typedef struct BMOIter {
char restrictmask; /* bitwise '&' with BMHeader.htype */
} BMOIter;
-void *BMO_slot_buffer_elem_first(BMOperator *op, const char *slot_name);
+void *BMO_slot_buffer_elem_first(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name);
-void *BMO_iter_new(BMOIter *iter, BMesh *bm, BMOperator *op,
- const char *slot_name, const char restrictmask);
+void *BMO_iter_new(BMOIter *iter,
+ BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
+ const char restrictmask);
void *BMO_iter_step(BMOIter *iter);
/* returns a pointer to the key value when iterating over mappings.
@@ -428,8 +465,8 @@ void *BMO_iter_map_value_p(BMOIter *iter);
/* use this for float mappings */
float BMO_iter_map_value_f(BMOIter *iter);
-#define BMO_ITER(ele, iter, bm, op, slot_name, restrict) \
- for (ele = BMO_iter_new(iter, bm, op, slot_name, restrict); ele; ele = BMO_iter_step(iter))
+#define BMO_ITER(ele, iter, slot_args, slot_name, restrict_flag) \
+ for (ele = BMO_iter_new(iter, slot_args, slot_name, restrict_flag); ele; ele = BMO_iter_step(iter))
/******************* Inlined Functions********************/
typedef void (*opexec)(BMesh *bm, BMOperator *op);
diff --git a/source/blender/bmesh/intern/bmesh_operator_api_inline.h b/source/blender/bmesh/intern/bmesh_operator_api_inline.h
index 16c2b8b0505..b405ecc1841 100644
--- a/source/blender/bmesh/intern/bmesh_operator_api_inline.h
+++ b/source/blender/bmesh/intern/bmesh_operator_api_inline.h
@@ -69,16 +69,16 @@ BLI_INLINE void _bmo_elem_flag_toggle(BMesh *bm, BMFlagLayer *oflags, const shor
oflags[bm->stackdepth - 1].f ^= oflag;
}
-BLI_INLINE void BMO_slot_map_int_insert(BMesh *bm, BMOperator *op, const char *slot_name,
+BLI_INLINE void BMO_slot_map_int_insert(BMOperator *op, BMOpSlot *slot,
void *element, int val)
{
- BMO_slot_map_insert(bm, op, slot_name, element, &val, sizeof(int));
+ BMO_slot_map_insert(op, slot, element, &val, sizeof(int));
}
-BLI_INLINE void BMO_slot_map_float_insert(BMesh *bm, BMOperator *op, const char *slot_name,
+BLI_INLINE void BMO_slot_map_float_insert(BMOperator *op, BMOpSlot *slot,
void *element, float val)
{
- BMO_slot_map_insert(bm, op, slot_name, element, &val, sizeof(float));
+ BMO_slot_map_insert(op, slot, element, &val, sizeof(float));
}
@@ -87,62 +87,62 @@ BLI_INLINE void BMO_slot_map_float_insert(BMesh *bm, BMOperator *op, const char
* do NOT use these for non-operator-api-allocated memory! instead
* use BMO_slot_map_data_get and BMO_slot_map_insert, which copies the data. */
-BLI_INLINE void BMO_slot_map_ptr_insert(BMesh *bm, BMOperator *op, const char *slot_name,
- void *element, void *val)
+BLI_INLINE void BMO_slot_map_ptr_insert(BMOperator *op, BMOpSlot *slot,
+ const void *element, void *val)
{
- BMO_slot_map_insert(bm, op, slot_name, element, &val, sizeof(void *));
+ BMO_slot_map_insert(op, slot, element, &val, sizeof(void *));
}
-BLI_INLINE int BMO_slot_map_contains(BMesh *UNUSED(bm), BMOperator *op, const char *slot_name, void *element)
+BLI_INLINE int BMO_slot_map_contains(BMOpSlot *slot, const void *element)
{
- BMOpSlot *slot = BMO_slot_get(op, slot_name);
BLI_assert(slot->slot_type == BMO_OP_SLOT_MAPPING);
/* sanity check */
- if (!slot->data.ghash) return 0;
+ if (UNLIKELY(slot->data.ghash == NULL)) {
+ return 0;
+ }
return BLI_ghash_haskey(slot->data.ghash, element);
}
-BLI_INLINE void *BMO_slot_map_data_get(BMesh *UNUSED(bm), BMOperator *op, const char *slot_name,
- void *element)
+BLI_INLINE void *BMO_slot_map_data_get(BMOpSlot *slot, const void *element)
{
BMOElemMapping *mapping;
- BMOpSlot *slot = BMO_slot_get(op, slot_name);
BLI_assert(slot->slot_type == BMO_OP_SLOT_MAPPING);
/* sanity check */
- if (!slot->data.ghash) return NULL;
+ if (UNLIKELY(slot->data.ghash == NULL)) {
+ return NULL;
+ }
mapping = (BMOElemMapping *)BLI_ghash_lookup(slot->data.ghash, element);
- if (!mapping) return NULL;
+ if (!mapping) {
+ return NULL;
+ }
return mapping + 1;
}
-BLI_INLINE float BMO_slot_map_float_get(BMesh *bm, BMOperator *op, const char *slot_name,
- void *element)
+BLI_INLINE float BMO_slot_map_float_get(BMOpSlot *slot, const void *element)
{
- float *val = (float *) BMO_slot_map_data_get(bm, op, slot_name, element);
+ float *val = (float *) BMO_slot_map_data_get(slot, element);
if (val) return *val;
return 0.0f;
}
-BLI_INLINE int BMO_slot_map_int_get(BMesh *bm, BMOperator *op, const char *slot_name,
- void *element)
+BLI_INLINE int BMO_slot_map_int_get(BMOpSlot *slot, const void *element)
{
- int *val = (int *) BMO_slot_map_data_get(bm, op, slot_name, element);
+ int *val = (int *) BMO_slot_map_data_get(slot, element);
if (val) return *val;
return 0;
}
-BLI_INLINE void *BMO_slot_map_ptr_get(BMesh *bm, BMOperator *op, const char *slot_name,
- void *element)
+BLI_INLINE void *BMO_slot_map_ptr_get(BMOpSlot *slot, const void *element)
{
- void **val = (void **) BMO_slot_map_data_get(bm, op, slot_name, element);
+ void **val = (void **) BMO_slot_map_data_get(slot, element);
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 9d1054dc042..157837a13c0 100644
--- a/source/blender/bmesh/intern/bmesh_operators.c
+++ b/source/blender/bmesh/intern/bmesh_operators.c
@@ -45,8 +45,8 @@
static void bmo_flag_layer_alloc(BMesh *bm);
static void bmo_flag_layer_free(BMesh *bm);
static void bmo_flag_layer_clear(BMesh *bm);
-static int bmo_name_to_slotcode(BMOpDefine *def, const char *name);
-static int bmo_name_to_slotcode_check(BMOpDefine *def, const char *name);
+static int bmo_name_to_slotcode(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *identifier);
+static int bmo_name_to_slotcode_check(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *identifier);
static int bmo_opname_to_opcode(const char *opname);
static const char *bmo_error_messages[] = {
@@ -80,7 +80,7 @@ const int BMO_OPSLOT_TYPEINFO[BMO_OP_SLOT_TOTAL_TYPES] = {
};
/* Dummy slot so there is something to return when slot name lookup fails */
-static BMOpSlot BMOpEmptySlot = {0};
+// static BMOpSlot BMOpEmptySlot = {0};
void BMO_op_flag_enable(BMesh *UNUSED(bm), BMOperator *op, const int op_flag)
{
@@ -101,6 +101,8 @@ void BMO_push(BMesh *bm, BMOperator *UNUSED(op))
{
bm->stackdepth++;
+ BLI_assert(bm->totflags > 0);
+
/* add flag layer, if appropriate */
if (bm->stackdepth > 1)
bmo_flag_layer_alloc(bm);
@@ -123,6 +125,18 @@ void BMO_pop(BMesh *bm)
bm->stackdepth--;
}
+
+/* use for both slot_types_in and slot_types_out */
+static void bmo_op_slots_init(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].index = i; // UNUSED
+ }
+}
+
/**
* \brief BMESH OPSTACK INIT OP
*
@@ -130,7 +144,7 @@ void BMO_pop(BMesh *bm)
*/
void BMO_op_init(BMesh *bm, BMOperator *op, const int flag, const char *opname)
{
- int i, opcode = bmo_opname_to_opcode(opname);
+ int opcode = bmo_opname_to_opcode(opname);
#ifdef DEBUG
BM_ELEM_INDEX_VALIDATE(bm, "pre bmo", opname);
@@ -148,10 +162,8 @@ void BMO_op_init(BMesh *bm, BMOperator *op, const int flag, const char *opname)
op->flag = flag;
/* initialize the operator slot types */
- for (i = 0; opdefines[opcode]->slot_types[i].type; i++) {
- op->slot_args[i].slot_type = opdefines[opcode]->slot_types[i].type;
- op->slot_args[i].index = i;
- }
+ bmo_op_slots_init(opdefines[opcode]->slot_types_in, op->slots_in);
+ bmo_op_slots_init(opdefines[opcode]->slot_types_out, op->slots_out);
/* callback */
op->exec = opdefines[opcode]->exec;
@@ -172,7 +184,9 @@ void BMO_op_init(BMesh *bm, BMOperator *op, const int flag, const char *opname)
*/
void BMO_op_exec(BMesh *bm, BMOperator *op)
{
-
+ /* allocate tool flags on demand */
+ BM_mesh_elem_toolflags_ensure(bm);
+
BMO_push(bm, op);
if (bm->stackdepth == 2)
@@ -185,6 +199,20 @@ void BMO_op_exec(BMesh *bm, BMOperator *op)
BMO_pop(bm);
}
+static void bmo_op_slots_free(BMOSlotType *slot_types, BMOpSlot *slot_args)
+{
+ BMOpSlot *slot;
+ unsigned int i;
+ for (i = 0; slot_types[i].type; i++) {
+ slot = &slot_args[i];
+ if (slot->slot_type == BMO_OP_SLOT_MAPPING) {
+ if (slot->data.ghash) {
+ BLI_ghash_free(slot->data.ghash, NULL, NULL);
+ }
+ }
+ }
+}
+
/**
* \brief BMESH OPSTACK FINISH OP
*
@@ -192,21 +220,13 @@ void BMO_op_exec(BMesh *bm, BMOperator *op)
*/
void BMO_op_finish(BMesh *bm, BMOperator *op)
{
- BMOpSlot *slot;
- int i;
-
- for (i = 0; opdefines[op->type]->slot_types[i].type; i++) {
- slot = &op->slot_args[i];
- if (slot->slot_type == BMO_OP_SLOT_MAPPING) {
- if (slot->data.ghash)
- BLI_ghash_free(slot->data.ghash, NULL, NULL);
- }
- }
+ 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);
BLI_memarena_free(op->arena);
#ifdef DEBUG
- BM_ELEM_INDEX_VALIDATE(bm, "post bmo", opdefines[op->type]->name);
+ BM_ELEM_INDEX_VALIDATE(bm, "post bmo", opdefines[op->type]->opname);
#else
(void)bm;
#endif
@@ -217,9 +237,9 @@ void BMO_op_finish(BMesh *bm, BMOperator *op)
*
* \return Success if the slot if found.
*/
-int BMO_slot_exists(BMOperator *op, const char *slot_name)
+int BMO_slot_exists(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *identifier)
{
- int slot_code = bmo_name_to_slotcode(opdefines[op->type], slot_name);
+ int slot_code = bmo_name_to_slotcode(slot_args, identifier);
return (slot_code >= 0);
}
@@ -228,73 +248,78 @@ int BMO_slot_exists(BMOperator *op, const char *slot_name)
*
* Returns a pointer to the slot of type 'slot_code'
*/
-BMOpSlot *BMO_slot_get(BMOperator *op, const char *slot_name)
+BMOpSlot *BMO_slot_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *identifier)
{
- int slot_code = bmo_name_to_slotcode_check(opdefines[op->type], slot_name);
+ int slot_code = bmo_name_to_slotcode_check(slot_args, identifier);
- if (slot_code < 0) {
- return &BMOpEmptySlot;
+ if (UNLIKELY(slot_code < 0)) {
+ //return &BMOpEmptySlot;
+ BLI_assert(0);
+ NULL; /* better crash */
}
- return &(op->slot_args[slot_code]);
+ return &slot_args[slot_code];
}
/**
* \brief BMESH OPSTACK COPY SLOT
*
+ * define used.
* Copies data from one slot to another.
*/
-void BMO_slot_copy(BMOperator *source_op, BMOperator *dest_op, const char *src, const char *dst)
+void _bmo_slot_copy(BMOpSlot slot_args_src[BMO_OP_MAX_SLOTS], const char *slot_name_src,
+ BMOpSlot slot_args_dst[BMO_OP_MAX_SLOTS], const char *slot_name_dst,
+ struct MemArena *arena_dst)
{
- BMOpSlot *source_slot = BMO_slot_get(source_op, src);
- BMOpSlot *dest_slot = BMO_slot_get(dest_op, dst);
+ BMOpSlot *slot_src = BMO_slot_get(slot_args_src, slot_name_src);
+ BMOpSlot *slot_dst = BMO_slot_get(slot_args_dst, slot_name_dst);
- if (source_slot == dest_slot)
+ if (slot_src == slot_dst)
return;
- if (source_slot->slot_type != dest_slot->slot_type) {
- /* possibly assert here? */
+ BLI_assert(slot_src->slot_type == slot_dst->slot_type);
+ if (slot_src->slot_type != slot_dst->slot_type) {
return;
}
- if (dest_slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF) {
+ if (slot_dst->slot_type == BMO_OP_SLOT_ELEMENT_BUF) {
/* do buffer copy */
- dest_slot->data.buf = NULL;
- dest_slot->len = source_slot->len;
- if (dest_slot->len) {
- const int slot_alloc_size = BMO_OPSLOT_TYPEINFO[dest_slot->slot_type] * dest_slot->len;
- dest_slot->data.buf = BLI_memarena_alloc(dest_op->arena, slot_alloc_size);
- memcpy(dest_slot->data.buf, source_slot->data.buf, slot_alloc_size);
+ 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);
}
}
- else if (dest_slot->slot_type == BMO_OP_SLOT_MAPPING) {
+ else if (slot_dst->slot_type == BMO_OP_SLOT_MAPPING) {
GHashIterator it;
BMOElemMapping *srcmap, *dstmap;
/* sanity check */
- if (!source_slot->data.ghash) {
+ if (!slot_src->data.ghash) {
return;
}
- if (!dest_slot->data.ghash) {
- dest_slot->data.ghash = BLI_ghash_ptr_new("bmesh operator 2");
+ if (!slot_dst->data.ghash) {
+ slot_dst->data.ghash = BLI_ghash_ptr_new("bmesh operator 2");
}
- BLI_ghashIterator_init(&it, source_slot->data.ghash);
- for ( ; (srcmap = BLI_ghashIterator_getValue(&it));
- BLI_ghashIterator_step(&it))
+ for (BLI_ghashIterator_init(&it, slot_src->data.ghash);
+ (srcmap = BLI_ghashIterator_getValue(&it));
+ BLI_ghashIterator_step(&it))
{
- dstmap = BLI_memarena_alloc(dest_op->arena, sizeof(*dstmap) + srcmap->len);
+ dstmap = BLI_memarena_alloc(arena_dst, sizeof(*dstmap) + srcmap->len);
dstmap->element = srcmap->element;
dstmap->len = srcmap->len;
memcpy(dstmap + 1, srcmap + 1, srcmap->len);
- BLI_ghash_insert(dest_slot->data.ghash, dstmap->element, dstmap);
+ BLI_ghash_insert(slot_dst->data.ghash, dstmap->element, dstmap);
}
}
else {
- dest_slot->data = source_slot->data;
+ slot_dst->data = slot_src->data;
}
}
@@ -304,9 +329,9 @@ void BMO_slot_copy(BMOperator *source_op, BMOperator *dest_op, const char *src,
* Sets the value of a slot depending on it's type
*/
-void BMO_slot_float_set(BMOperator *op, const char *slot_name, const float f)
+void BMO_slot_float_set(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const float f)
{
- BMOpSlot *slot = BMO_slot_get(op, slot_name);
+ BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
BLI_assert(slot->slot_type == BMO_OP_SLOT_FLT);
if (!(slot->slot_type == BMO_OP_SLOT_FLT))
return;
@@ -314,9 +339,9 @@ void BMO_slot_float_set(BMOperator *op, const char *slot_name, const float f)
slot->data.f = f;
}
-void BMO_slot_int_set(BMOperator *op, const char *slot_name, const int i)
+void BMO_slot_int_set(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const int i)
{
- BMOpSlot *slot = BMO_slot_get(op, slot_name);
+ BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
BLI_assert(slot->slot_type == BMO_OP_SLOT_INT);
if (!(slot->slot_type == BMO_OP_SLOT_INT))
return;
@@ -324,9 +349,9 @@ void BMO_slot_int_set(BMOperator *op, const char *slot_name, const int i)
slot->data.i = i;
}
-void BMO_slot_bool_set(BMOperator *op, const char *slot_name, const int i)
+void BMO_slot_bool_set(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const int i)
{
- BMOpSlot *slot = BMO_slot_get(op, slot_name);
+ BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
BLI_assert(slot->slot_type == BMO_OP_SLOT_BOOL);
if (!(slot->slot_type == BMO_OP_SLOT_BOOL))
return;
@@ -335,9 +360,9 @@ void BMO_slot_bool_set(BMOperator *op, const char *slot_name, const int i)
}
/* only supports square mats */
-void BMO_slot_mat_set(BMOperator *op, const char *slot_name, const float *mat, int size)
+void BMO_slot_mat_set(BMOperator *op, BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const float *mat, int size)
{
- BMOpSlot *slot = BMO_slot_get(op, slot_name);
+ BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
BLI_assert(slot->slot_type == BMO_OP_SLOT_MAT);
if (!(slot->slot_type == BMO_OP_SLOT_MAT))
return;
@@ -358,39 +383,39 @@ void BMO_slot_mat_set(BMOperator *op, const char *slot_name, const float *mat, i
}
}
-void BMO_slot_mat4_get(BMOperator *op, const char *slot_name, float r_mat[4][4])
+void BMO_slot_mat4_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, float r_mat[4][4])
{
- BMOpSlot *slot = BMO_slot_get(op, slot_name);
+ BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
BLI_assert(slot->slot_type == BMO_OP_SLOT_MAT);
if (!(slot->slot_type == BMO_OP_SLOT_MAT))
return;
if (slot->data.p) {
- copy_m4_m4(r_mat, (float (*)[4])slot->data.p);
+ copy_m4_m4(r_mat, BMO_SLOT_AS_MATRIX(slot));
}
else {
unit_m4(r_mat);
}
}
-void BMO_slot_mat3_set(BMOperator *op, const char *slot_name, float r_mat[3][3])
+void BMO_slot_mat3_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, float r_mat[3][3])
{
- BMOpSlot *slot = BMO_slot_get(op, slot_name);
+ BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
BLI_assert(slot->slot_type == BMO_OP_SLOT_MAT);
if (!(slot->slot_type == BMO_OP_SLOT_MAT))
return;
if (slot->data.p) {
- copy_m3_m4(r_mat, slot->data.p);
+ copy_m3_m4(r_mat, BMO_SLOT_AS_MATRIX(slot));
}
else {
unit_m3(r_mat);
}
}
-void BMO_slot_ptr_set(BMOperator *op, const char *slot_name, void *p)
+void BMO_slot_ptr_set(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, void *p)
{
- BMOpSlot *slot = BMO_slot_get(op, slot_name);
+ BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
BLI_assert(slot->slot_type == BMO_OP_SLOT_PTR);
if (!(slot->slot_type == BMO_OP_SLOT_PTR))
return;
@@ -398,9 +423,9 @@ void BMO_slot_ptr_set(BMOperator *op, const char *slot_name, void *p)
slot->data.p = p;
}
-void BMO_slot_vec_set(BMOperator *op, const char *slot_name, const float vec[3])
+void BMO_slot_vec_set(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const float vec[3])
{
- BMOpSlot *slot = BMO_slot_get(op, slot_name);
+ BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
BLI_assert(slot->slot_type == BMO_OP_SLOT_VEC);
if (!(slot->slot_type == BMO_OP_SLOT_VEC))
return;
@@ -409,9 +434,9 @@ void BMO_slot_vec_set(BMOperator *op, const char *slot_name, const float vec[3])
}
-float BMO_slot_float_get(BMOperator *op, const char *slot_name)
+float BMO_slot_float_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name)
{
- BMOpSlot *slot = BMO_slot_get(op, slot_name);
+ BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
BLI_assert(slot->slot_type == BMO_OP_SLOT_FLT);
if (!(slot->slot_type == BMO_OP_SLOT_FLT))
return 0.0f;
@@ -419,9 +444,9 @@ float BMO_slot_float_get(BMOperator *op, const char *slot_name)
return slot->data.f;
}
-int BMO_slot_int_get(BMOperator *op, const char *slot_name)
+int BMO_slot_int_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name)
{
- BMOpSlot *slot = BMO_slot_get(op, slot_name);
+ BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
BLI_assert(slot->slot_type == BMO_OP_SLOT_INT);
if (!(slot->slot_type == BMO_OP_SLOT_INT))
return 0;
@@ -429,9 +454,9 @@ int BMO_slot_int_get(BMOperator *op, const char *slot_name)
return slot->data.i;
}
-int BMO_slot_bool_get(BMOperator *op, const char *slot_name)
+int BMO_slot_bool_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name)
{
- BMOpSlot *slot = BMO_slot_get(op, slot_name);
+ BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
BLI_assert(slot->slot_type == BMO_OP_SLOT_BOOL);
if (!(slot->slot_type == BMO_OP_SLOT_BOOL))
return 0;
@@ -440,23 +465,23 @@ int BMO_slot_bool_get(BMOperator *op, const char *slot_name)
}
/* if you want a copy of the elem buffer */
-void *BMO_slot_as_arrayN(BMOperator *op, const char *slot_name, int *len)
+void *BMO_slot_as_arrayN(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, int *len)
{
- BMOpSlot *slot = BMO_slot_get(op, slot_name);
+ BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
void *ret;
/* could add support for mapping type */
BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF);
- ret = MEM_mallocN(sizeof(void *) * slot->len, __func__);
- memcpy(ret, slot->data.buf, sizeof(void *) * slot->len);
+ ret = MEM_mallocN(sizeof(void **) * slot->len, __func__);
+ memcpy(ret, slot->data.buf, sizeof(void **) * slot->len);
*len = slot->len;
return ret;
}
-void *BMO_slot_ptr_get(BMOperator *op, const char *slot_name)
+void *BMO_slot_ptr_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name)
{
- BMOpSlot *slot = BMO_slot_get(op, slot_name);
+ BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
BLI_assert(slot->slot_type == BMO_OP_SLOT_PTR);
if (!(slot->slot_type == BMO_OP_SLOT_PTR))
return NULL;
@@ -464,9 +489,9 @@ void *BMO_slot_ptr_get(BMOperator *op, const char *slot_name)
return slot->data.p;
}
-void BMO_slot_vec_get(BMOperator *op, const char *slot_name, float r_vec[3])
+void BMO_slot_vec_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, float r_vec[3])
{
- BMOpSlot *slot = BMO_slot_get(op, slot_name);
+ BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
BLI_assert(slot->slot_type == BMO_OP_SLOT_VEC);
if (!(slot->slot_type == BMO_OP_SLOT_VEC))
return;
@@ -542,9 +567,9 @@ void BMO_mesh_flag_disable_all(BMesh *bm, BMOperator *UNUSED(op), const char hty
}
}
-int BMO_slot_buffer_count(BMesh *UNUSED(bm), BMOperator *op, const char *slot_name)
+int BMO_slot_buffer_count(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name)
{
- BMOpSlot *slot = BMO_slot_get(op, slot_name);
+ BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF);
/* check if its actually a buffer */
@@ -554,9 +579,9 @@ int BMO_slot_buffer_count(BMesh *UNUSED(bm), BMOperator *op, const char *slot_na
return slot->len;
}
-int BMO_slot_map_count(BMesh *UNUSED(bm), BMOperator *op, const char *slot_name)
+int BMO_slot_map_count(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name)
{
- BMOpSlot *slot = BMO_slot_get(op, slot_name);
+ BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
BLI_assert(slot->slot_type == BMO_OP_SLOT_MAPPING);
/* check if its actually a buffer */
@@ -569,12 +594,12 @@ int BMO_slot_map_count(BMesh *UNUSED(bm), BMOperator *op, const char *slot_name)
/* inserts a key/value mapping into a mapping slot. note that it copies the
* value, it doesn't store a reference to it. */
-void BMO_slot_map_insert(BMesh *UNUSED(bm), BMOperator *op, const char *slot_name,
- void *element, void *data, int len)
+void BMO_slot_map_insert(BMOperator *op, BMOpSlot *slot,
+ const void *element, void *data, int len)
{
BMOElemMapping *mapping;
- BMOpSlot *slot = BMO_slot_get(op, slot_name);
BLI_assert(slot->slot_type == BMO_OP_SLOT_MAPPING);
+ BMO_ASSERT_SLOT_IN_OP(slot, op);
mapping = (BMOElemMapping *) BLI_memarena_alloc(op->arena, sizeof(*mapping) + len);
@@ -586,7 +611,7 @@ void BMO_slot_map_insert(BMesh *UNUSED(bm), BMOperator *op, const char *slot_nam
slot->data.ghash = BLI_ghash_ptr_new("bmesh slot map hash");
}
- BLI_ghash_insert(slot->data.ghash, element, mapping);
+ BLI_ghash_insert(slot->data.ghash, (void *)element, mapping);
}
#if 0
@@ -632,11 +657,11 @@ void *bmo_slot_buffer_grow(BMesh *bm, BMOperator *op, int slot_code, int totadd)
}
#endif
-void BMO_slot_map_to_flag(BMesh *bm, BMOperator *op, const char *slot_name,
+void BMO_slot_map_to_flag(BMesh *bm, BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
const char htype, const short oflag)
{
GHashIterator it;
- BMOpSlot *slot = BMO_slot_get(op, slot_name);
+ BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
BMElemF *ele_f;
BLI_assert(slot->slot_type == BMO_OP_SLOT_MAPPING);
@@ -652,18 +677,22 @@ void BMO_slot_map_to_flag(BMesh *bm, BMOperator *op, const char *slot_name,
}
}
-void *BMO_slot_buffer_alloc(BMOperator *op, const char *slot_name, const int len)
+void *BMO_slot_buffer_alloc(BMOperator *op, BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const int len)
{
- BMOpSlot *slot = BMO_slot_get(op, slot_name);
- BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF);
+ BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
/* check if its actually a buffer */
if (slot->slot_type != BMO_OP_SLOT_ELEMENT_BUF)
return NULL;
slot->len = len;
- if (len)
+ if (len) {
slot->data.buf = BLI_memarena_alloc(op->arena, BMO_OPSLOT_TYPEINFO[slot->slot_type] * len);
+ }
+ else {
+ slot->data.buf = NULL;
+ }
+
return slot->data.buf;
}
@@ -672,9 +701,10 @@ void *BMO_slot_buffer_alloc(BMOperator *op, const char *slot_name, const int len
*
* Copies all elements of a certain type into an operator slot.
*/
-void BMO_slot_buffer_from_all(BMesh *bm, BMOperator *op, const char *slot_name, const char htype)
+void BMO_slot_buffer_from_all(BMesh *bm, BMOperator *op, BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
+ const char *slot_name, const char htype)
{
- BMOpSlot *output = BMO_slot_get(op, slot_name);
+ BMOpSlot *output = BMO_slot_get(slot_args, slot_name);
int totelement = 0, i = 0;
if (htype & BM_VERT) totelement += bm->totvert;
@@ -685,27 +715,27 @@ void BMO_slot_buffer_from_all(BMesh *bm, BMOperator *op, const char *slot_name,
BMIter iter;
BMHeader *ele;
- BMO_slot_buffer_alloc(op, slot_name, totelement);
+ BMO_slot_buffer_alloc(op, slot_args, slot_name, totelement);
/* TODO - collapse these loops into one */
if (htype & BM_VERT) {
BM_ITER_MESH (ele, &iter, bm, BM_VERTS_OF_MESH) {
- ((BMHeader **)output->data.p)[i] = ele;
+ output->data.buf[i] = ele;
i++;
}
}
if (htype & BM_EDGE) {
BM_ITER_MESH (ele, &iter, bm, BM_EDGES_OF_MESH) {
- ((BMHeader **)output->data.p)[i] = ele;
+ output->data.buf[i] = ele;
i++;
}
}
if (htype & BM_FACE) {
BM_ITER_MESH (ele, &iter, bm, BM_FACES_OF_MESH) {
- ((BMHeader **)output->data.p)[i] = ele;
+ output->data.buf[i] = ele;
i++;
}
}
@@ -718,11 +748,11 @@ void BMO_slot_buffer_from_all(BMesh *bm, BMOperator *op, const char *slot_name,
* Copies elements of a certain type, which have a certain header flag
* enabled/disabled into a slot for an operator.
*/
-static void bmo_slot_buffer_from_hflag(BMesh *bm, BMOperator *op, const char *slot_name,
+static void bmo_slot_buffer_from_hflag(BMesh *bm, BMOperator *op, BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
const char htype, const char hflag,
const short test_for_enabled)
{
- BMOpSlot *output = BMO_slot_get(op, slot_name);
+ BMOpSlot *output = BMO_slot_get(slot_args, slot_name);
int totelement = 0, i = 0;
const int respecthide = (op->flag & BMO_FLAG_RESPECT_HIDE) != 0;
@@ -737,7 +767,7 @@ static void bmo_slot_buffer_from_hflag(BMesh *bm, BMOperator *op, const char *sl
BMIter iter;
BMElem *ele;
- BMO_slot_buffer_alloc(op, slot_name, totelement);
+ BMO_slot_buffer_alloc(op, slot_args, slot_name, totelement);
/* TODO - collapse these loops into one */
@@ -746,7 +776,7 @@ static void bmo_slot_buffer_from_hflag(BMesh *bm, BMOperator *op, const char *sl
if ((!respecthide || !BM_elem_flag_test(ele, BM_ELEM_HIDDEN)) &&
BM_elem_flag_test_bool(ele, hflag) == test_for_enabled)
{
- ((BMElem **)output->data.p)[i] = ele;
+ output->data.buf[i] = ele;
i++;
}
}
@@ -757,7 +787,7 @@ static void bmo_slot_buffer_from_hflag(BMesh *bm, BMOperator *op, const char *sl
if ((!respecthide || !BM_elem_flag_test(ele, BM_ELEM_HIDDEN)) &&
BM_elem_flag_test_bool(ele, hflag) == test_for_enabled)
{
- ((BMElem **)output->data.p)[i] = ele;
+ output->data.buf[i] = ele;
i++;
}
}
@@ -768,7 +798,7 @@ static void bmo_slot_buffer_from_hflag(BMesh *bm, BMOperator *op, const char *sl
if ((!respecthide || !BM_elem_flag_test(ele, BM_ELEM_HIDDEN)) &&
BM_elem_flag_test_bool(ele, hflag) == test_for_enabled)
{
- ((BMElem **)output->data.p)[i] = ele;
+ output->data.buf[i] = ele;
i++;
}
}
@@ -779,46 +809,51 @@ static void bmo_slot_buffer_from_hflag(BMesh *bm, BMOperator *op, const char *sl
}
}
-void BMO_slot_buffer_from_enabled_hflag(BMesh *bm, BMOperator *op, const char *slot_name,
+void BMO_slot_buffer_from_enabled_hflag(BMesh *bm, BMOperator *op,
+ BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
const char htype, const char hflag)
{
- bmo_slot_buffer_from_hflag(bm, op, slot_name, htype, hflag, TRUE);
+ bmo_slot_buffer_from_hflag(bm, op, slot_args, slot_name, htype, hflag, TRUE);
}
-void BMO_slot_buffer_from_disabled_hflag(BMesh *bm, BMOperator *op, const char *slot_name,
+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)
{
- bmo_slot_buffer_from_hflag(bm, op, slot_name, htype, hflag, FALSE);
+ bmo_slot_buffer_from_hflag(bm, op, slot_args, slot_name, htype, hflag, FALSE);
}
/**
* Copies the values from another slot to the end of the output slot.
*/
-void BMO_slot_buffer_append(BMOperator *output_op, const char *output_slot_name,
- BMOperator *other_op, const char *other_slot_name)
+void _bmo_slot_buffer_append(BMOpSlot slot_args_dst[BMO_OP_MAX_SLOTS], const char *slot_name_dst,
+ BMOpSlot slot_args_src[BMO_OP_MAX_SLOTS], const char *slot_name_src,
+ struct MemArena *arena_dst)
{
- BMOpSlot *output_slot = BMO_slot_get(output_op, output_slot_name);
- BMOpSlot *other_slot = BMO_slot_get(other_op, other_slot_name);
+ BMOpSlot *slot_dst = BMO_slot_get(slot_args_dst, slot_name_dst);
+ BMOpSlot *slot_src = BMO_slot_get(slot_args_src, slot_name_src);
- BLI_assert(output_slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF &&
- other_slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF);
+ BLI_assert(slot_dst->slot_type == BMO_OP_SLOT_ELEMENT_BUF &&
+ slot_src->slot_type == BMO_OP_SLOT_ELEMENT_BUF);
- if (output_slot->len == 0) {
+ if (slot_dst->len == 0) {
/* output slot is empty, copy rather than append */
- BMO_slot_copy(other_op, output_op, other_slot_name, output_slot_name);
+ _bmo_slot_copy(slot_args_src, slot_name_src,
+ slot_args_dst, slot_name_dst,
+ arena_dst);
}
- else if (other_slot->len != 0) {
- int elem_size = BMO_OPSLOT_TYPEINFO[output_slot->slot_type];
- int alloc_size = elem_size * (output_slot->len + other_slot->len);
+ else if (slot_src->len != 0) {
+ int elem_size = BMO_OPSLOT_TYPEINFO[slot_dst->slot_type];
+ int alloc_size = elem_size * (slot_dst->len + slot_src->len);
/* allocate new buffer */
- void *buf = BLI_memarena_alloc(output_op->arena, alloc_size);
+ void *buf = BLI_memarena_alloc(arena_dst, alloc_size);
/* copy slot data */
- memcpy(buf, output_slot->data.buf, elem_size * output_slot->len);
- memcpy(((char *)buf) + elem_size * output_slot->len, other_slot->data.buf, elem_size * other_slot->len);
+ memcpy(buf, slot_dst->data.buf, elem_size * slot_dst->len);
+ memcpy(((char *)buf) + elem_size * slot_dst->len, slot_src->data.buf, elem_size * slot_src->len);
- output_slot->data.buf = buf;
- output_slot->len += other_slot->len;
+ slot_dst->data.buf = buf;
+ slot_dst->len += slot_src->len;
}
}
@@ -828,13 +863,15 @@ void BMO_slot_buffer_append(BMOperator *output_op, const char *output_slot_name,
* Copies elements of a certain type, which have a certain flag set
* into an output slot for an operator.
*/
-static void bmo_slot_buffer_from_flag(BMesh *bm, BMOperator *op, const char *slot_name,
+static void bmo_slot_buffer_from_flag(BMesh *bm, BMOperator *op,
+ BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
const char htype, const short oflag,
const short test_for_enabled)
{
- BMOpSlot *slot = BMO_slot_get(op, slot_name);
+ BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
int totelement, i = 0;
+ BLI_assert(op->slots_in == slot_args || op->slots_out == slot_args);
BLI_assert(ELEM(TRUE, FALSE, test_for_enabled));
if (test_for_enabled)
@@ -849,9 +886,9 @@ static void bmo_slot_buffer_from_flag(BMesh *bm, BMOperator *op, const char *slo
BMHeader *ele;
BMHeader **ele_array;
- BMO_slot_buffer_alloc(op, slot_name, totelement);
+ BMO_slot_buffer_alloc(op, slot_args, slot_name, totelement);
- ele_array = (BMHeader **)slot->data.p;
+ ele_array = (BMHeader **)slot->data.buf;
/* TODO - collapse these loops into one */
@@ -887,16 +924,18 @@ static void bmo_slot_buffer_from_flag(BMesh *bm, BMOperator *op, const char *slo
}
}
-void BMO_slot_buffer_from_enabled_flag(BMesh *bm, BMOperator *op, const char *slot_name,
+void BMO_slot_buffer_from_enabled_flag(BMesh *bm, BMOperator *op,
+ BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
const char htype, const short oflag)
{
- bmo_slot_buffer_from_flag(bm, op, slot_name, htype, oflag, TRUE);
+ bmo_slot_buffer_from_flag(bm, op, slot_args, slot_name, htype, oflag, TRUE);
}
-void BMO_slot_buffer_from_disabled_flag(BMesh *bm, BMOperator *op, const char *slot_name,
+void BMO_slot_buffer_from_disabled_flag(BMesh *bm, BMOperator *op,
+ BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
const char htype, const short oflag)
{
- bmo_slot_buffer_from_flag(bm, op, slot_name, htype, oflag, FALSE);
+ bmo_slot_buffer_from_flag(bm, op, slot_args, slot_name, htype, oflag, FALSE);
}
/**
@@ -905,11 +944,12 @@ void BMO_slot_buffer_from_disabled_flag(BMesh *bm, BMOperator *op, const char *s
* Header Flags elements in a slots buffer, automatically
* using the selection API where appropriate.
*/
-void BMO_slot_buffer_hflag_enable(BMesh *bm, BMOperator *op, const char *slot_name,
+void BMO_slot_buffer_hflag_enable(BMesh *bm,
+ BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
const char htype, const char hflag, const char do_flush)
{
- BMOpSlot *slot = BMO_slot_get(op, slot_name);
- BMElem **data = slot->data.p;
+ BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
+ BMElem **data = (BMElem **)slot->data.buf;
int i;
const char do_flush_select = (do_flush && (hflag & BM_ELEM_SELECT));
const char do_flush_hide = (do_flush && (hflag & BM_ELEM_HIDDEN));
@@ -938,11 +978,12 @@ void BMO_slot_buffer_hflag_enable(BMesh *bm, BMOperator *op, const char *slot_na
* Removes flags from elements in a slots buffer, automatically
* using the selection API where appropriate.
*/
-void BMO_slot_buffer_hflag_disable(BMesh *bm, BMOperator *op, const char *slot_name,
+void BMO_slot_buffer_hflag_disable(BMesh *bm,
+ BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
const char htype, const char hflag, const char do_flush)
{
- BMOpSlot *slot = BMO_slot_get(op, slot_name);
- BMElem **data = slot->data.p;
+ BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
+ BMElem **data = (BMElem **)slot->data.buf;
int i;
const char do_flush_select = (do_flush && (hflag & BM_ELEM_SELECT));
const char do_flush_hide = (do_flush && (hflag & BM_ELEM_HIDDEN));
@@ -989,10 +1030,11 @@ int BMO_vert_edge_flags_count(BMesh *bm, BMVert *v, const short oflag)
*
* Flags elements in a slots buffer
*/
-void BMO_slot_buffer_flag_enable(BMesh *bm, BMOperator *op, const char *slot_name,
+void BMO_slot_buffer_flag_enable(BMesh *bm,
+ BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
const char htype, const short oflag)
{
- BMOpSlot *slot = BMO_slot_get(op, slot_name);
+ BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
BMHeader **data = slot->data.p;
int i;
@@ -1011,11 +1053,12 @@ void BMO_slot_buffer_flag_enable(BMesh *bm, BMOperator *op, const char *slot_nam
*
* Removes flags from elements in a slots buffer
*/
-void BMO_slot_buffer_flag_disable(BMesh *bm, BMOperator *op, const char *slot_name,
+void BMO_slot_buffer_flag_disable(BMesh *bm,
+ BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
const char htype, const short oflag)
{
- BMOpSlot *slot = BMO_slot_get(op, slot_name);
- BMHeader **data = slot->data.p;
+ BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
+ BMHeader **data = (BMHeader **)slot->data.buf;
int i;
BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF);
@@ -1056,7 +1099,9 @@ static void bmo_flag_layer_alloc(BMesh *bm)
/* store memcpy size for reuse */
const size_t old_totflags_size = (bm->totflags * sizeof(BMFlagLayer));
-
+
+ BLI_assert(oldpool != NULL);
+
bm->totflags++;
/* allocate new flag poo */
@@ -1068,18 +1113,21 @@ static void bmo_flag_layer_alloc(BMesh *bm)
ele->oflags = BLI_mempool_calloc(newpool);
memcpy(ele->oflags, oldflags, old_totflags_size);
BM_elem_index_set(ele, i); /* set_inline */
+ BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele);
}
BM_ITER_MESH_INDEX (ele, &iter, bm, BM_EDGES_OF_MESH, i) {
oldflags = ele->oflags;
ele->oflags = BLI_mempool_calloc(newpool);
memcpy(ele->oflags, oldflags, old_totflags_size);
BM_elem_index_set(ele, i); /* set_inline */
+ BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele);
}
BM_ITER_MESH_INDEX (ele, &iter, bm, BM_FACES_OF_MESH, i) {
oldflags = ele->oflags;
ele->oflags = BLI_mempool_calloc(newpool);
memcpy(ele->oflags, oldflags, old_totflags_size);
BM_elem_index_set(ele, i); /* set_inline */
+ BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele);
}
bm->elem_index_dirty &= ~(BM_VERT | BM_EDGE | BM_FACE);
@@ -1113,18 +1161,21 @@ static void bmo_flag_layer_free(BMesh *bm)
ele->oflags = BLI_mempool_calloc(newpool);
memcpy(ele->oflags, oldflags, new_totflags_size);
BM_elem_index_set(ele, i); /* set_inline */
+ BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele);
}
BM_ITER_MESH_INDEX (ele, &iter, bm, BM_EDGES_OF_MESH, i) {
oldflags = ele->oflags;
ele->oflags = BLI_mempool_calloc(newpool);
memcpy(ele->oflags, oldflags, new_totflags_size);
BM_elem_index_set(ele, i); /* set_inline */
+ BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele);
}
BM_ITER_MESH_INDEX (ele, &iter, bm, BM_FACES_OF_MESH, i) {
oldflags = ele->oflags;
ele->oflags = BLI_mempool_calloc(newpool);
memcpy(ele->oflags, oldflags, new_totflags_size);
BM_elem_index_set(ele, i); /* set_inline */
+ BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele);
}
bm->elem_index_dirty &= ~(BM_VERT | BM_EDGE | BM_FACE);
@@ -1159,14 +1210,14 @@ static void bmo_flag_layer_clear(BMesh *bm)
bm->elem_index_dirty &= ~(BM_VERT | BM_EDGE | BM_FACE);
}
-void *BMO_slot_buffer_elem_first(BMOperator *op, const char *slot_name)
+void *BMO_slot_buffer_elem_first(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name)
{
- BMOpSlot *slot = BMO_slot_get(op, slot_name);
+ BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
if (slot->slot_type != BMO_OP_SLOT_ELEMENT_BUF)
return NULL;
- return slot->data.buf ? *(void **)slot->data.buf : NULL;
+ return slot->data.buf ? *slot->data.buf : NULL;
}
/**
@@ -1175,10 +1226,11 @@ void *BMO_slot_buffer_elem_first(BMOperator *op, const char *slot_name)
* \param restrictmask restricts the iteration to certain element types
* (e.g. combination of BM_VERT, BM_EDGE, BM_FACE), if iterating
* over an element buffer (not a mapping). */
-void *BMO_iter_new(BMOIter *iter, BMesh *UNUSED(bm), BMOperator *op,
- const char *slot_name, const char restrictmask)
+void *BMO_iter_new(BMOIter *iter,
+ BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
+ const char restrictmask)
{
- BMOpSlot *slot = BMO_slot_get(op, slot_name);
+ BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
memset(iter, 0, sizeof(BMOIter));
@@ -1207,13 +1259,13 @@ void *BMO_iter_step(BMOIter *iter)
return NULL;
}
- h = ((void **)iter->slot->data.buf)[iter->cur++];
+ h = iter->slot->data.buf[iter->cur++];
while (!(iter->restrictmask & h->htype)) {
if (iter->cur >= iter->slot->len) {
return NULL;
}
- h = ((void **)iter->slot->data.buf)[iter->cur++];
+ h = iter->slot->data.buf[iter->cur++];
}
return h;
@@ -1312,24 +1364,26 @@ int BMO_error_pop(BMesh *bm, const char **msg, BMOperator **op)
#define NEXT_CHAR(fmt) ((fmt)[0] != 0 ? (fmt)[1] : 0)
-static int bmo_name_to_slotcode(BMOpDefine *def, const char *name)
+static int bmo_name_to_slotcode(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *identifier)
{
- int i;
+ int i = 0;
- for (i = 0; def->slot_types[i].type; i++) {
- if (!strncmp(name, def->slot_types[i].name, MAX_SLOTNAME)) {
+ while (slot_args->slot_name) {
+ if (strncmp(identifier, slot_args->slot_name, MAX_SLOTNAME) == 0) {
return i;
}
+ slot_args++;
+ i++;
}
return -1;
}
-static int bmo_name_to_slotcode_check(BMOpDefine *def, const char *name)
+static int bmo_name_to_slotcode_check(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *identifier)
{
- int i = bmo_name_to_slotcode(def, name);
+ int i = bmo_name_to_slotcode(slot_args, identifier);
if (i < 0) {
- fprintf(stderr, "%s: ! could not find bmesh slot for name %s! (bmesh internal error)\n", __func__, name);
+ fprintf(stderr, "%s: ! could not find bmesh slot for name %s! (bmesh internal error)\n", __func__, identifier);
}
return i;
@@ -1340,12 +1394,12 @@ static int bmo_opname_to_opcode(const char *opname)
int i;
for (i = 0; i < bmesh_total_ops; i++) {
- if (!strcmp(opname, opdefines[i]->name)) {
+ if (!strcmp(opname, opdefines[i]->opname)) {
return i;
}
}
- fprintf(stderr, "%s: ! could not find bmesh slot for name %s! (bmesh internal error)\n", __func__, opname);
+ fprintf(stderr, "%s: could not find bmesh slot for name %s! (bmesh internal error)\n", __func__, opname);
return -1;
}
@@ -1355,6 +1409,8 @@ static int bmo_opname_to_opcode(const char *opname)
* 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)
@@ -1368,7 +1424,7 @@ static int bmo_opname_to_opcode(const char *opname)
int BMO_op_vinitf(BMesh *bm, BMOperator *op, const int flag, const char *_fmt, va_list vlist)
{
- BMOpDefine *def;
+// BMOpDefine *def;
char *opname, *ofmt, *fmt;
char slot_name[64] = {0};
int i /*, n = strlen(fmt) */, stop /*, slot_code = -1 */, type, state;
@@ -1407,7 +1463,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 = opdefines[i];
i = 0;
state = 1; /* 0: not inside slot_code name, 1: inside slot_code name */
@@ -1430,7 +1486,7 @@ int BMO_op_vinitf(BMesh *bm, BMOperator *op, const int flag, const char *_fmt, v
fmt[i] = 0;
- if (bmo_name_to_slotcode_check(def, fmt) < 0) {
+ if (bmo_name_to_slotcode_check(op->slots_in, fmt) < 0) {
GOTO_ERROR("name to slot code check failed");
}
@@ -1456,47 +1512,57 @@ int BMO_op_vinitf(BMesh *bm, BMOperator *op, const int flag, const char *_fmt, v
else if (c == '4') size = 4;
else GOTO_ERROR("matrix size was not 3 or 4");
- BMO_slot_mat_set(op, slot_name, va_arg(vlist, void *), size);
+ BMO_slot_mat_set(op, op->slots_in, slot_name, va_arg(vlist, void *), size);
state = 1;
break;
}
case 'v':
{
- BMO_slot_vec_set(op, slot_name, va_arg(vlist, float *));
+ BMO_slot_vec_set(op->slots_in, slot_name, va_arg(vlist, float *));
state = 1;
break;
}
case 'e':
{
BMHeader *ele = va_arg(vlist, void *);
- BMOpSlot *slot = BMO_slot_get(op, slot_name);
+ BMOpSlot *slot = BMO_slot_get(op->slots_in, slot_name);
slot->data.buf = BLI_memarena_alloc(op->arena, sizeof(void *) * 4);
slot->len = 1;
- *((void **)slot->data.buf) = ele;
+ *slot->data.buf = ele;
state = 1;
break;
}
case 's':
+ case 'S':
{
- BMOperator *op2 = va_arg(vlist, void *);
- const char *slot_name2 = va_arg(vlist, char *);
+ BMOperator *op_other = va_arg(vlist, void *);
+ const char *slot_name_other = va_arg(vlist, char *);
- BMO_slot_copy(op2, op, slot_name2, slot_name);
+ if (*fmt == 's') {
+ BLI_assert(bmo_name_to_slotcode_check(op_other->slots_in, slot_name_other) != -1);
+ BMO_slot_copy(op_other, slots_in, slot_name_other,
+ op, slots_in, slot_name);
+ }
+ else {
+ BLI_assert(bmo_name_to_slotcode_check(op_other->slots_out, slot_name_other) != -1);
+ BMO_slot_copy(op_other, slots_out, slot_name_other,
+ op, slots_in, slot_name);
+ }
state = 1;
break;
}
case 'i':
- BMO_slot_int_set(op, slot_name, va_arg(vlist, int));
+ BMO_slot_int_set(op->slots_in, slot_name, va_arg(vlist, int));
state = 1;
break;
case 'b':
- BMO_slot_bool_set(op, slot_name, va_arg(vlist, int));
+ BMO_slot_bool_set(op->slots_in, slot_name, va_arg(vlist, int));
state = 1;
break;
case 'p':
- BMO_slot_ptr_set(op, slot_name, va_arg(vlist, void *));
+ BMO_slot_ptr_set(op->slots_in, slot_name, va_arg(vlist, void *));
state = 1;
break;
case 'f':
@@ -1507,7 +1573,7 @@ int BMO_op_vinitf(BMesh *bm, BMOperator *op, const int flag, const char *_fmt, v
type = *fmt;
if (NEXT_CHAR(fmt) == ' ' || NEXT_CHAR(fmt) == '\0') {
- BMO_slot_float_set(op, slot_name, va_arg(vlist, double));
+ BMO_slot_float_set(op->slots_in, slot_name, va_arg(vlist, double));
}
else {
htype = 0;
@@ -1529,19 +1595,19 @@ int BMO_op_vinitf(BMesh *bm, BMOperator *op, const int flag, const char *_fmt, v
}
if (type == 'h') {
- BMO_slot_buffer_from_enabled_hflag(bm, op, slot_name, htype, va_arg(vlist, int));
+ BMO_slot_buffer_from_enabled_hflag(bm, op, op->slots_in, slot_name, htype, va_arg(vlist, int));
}
else if (type == 'H') {
- BMO_slot_buffer_from_disabled_hflag(bm, op, slot_name, htype, va_arg(vlist, int));
+ BMO_slot_buffer_from_disabled_hflag(bm, op, op->slots_in, slot_name, htype, va_arg(vlist, int));
}
else if (type == 'a') {
- BMO_slot_buffer_from_all(bm, op, slot_name, htype);
+ BMO_slot_buffer_from_all(bm, op, op->slots_in, slot_name, htype);
}
else if (type == 'f') {
- BMO_slot_buffer_from_enabled_flag(bm, op, slot_name, htype, va_arg(vlist, int));
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_in, slot_name, htype, va_arg(vlist, int));
}
else if (type == 'F') {
- BMO_slot_buffer_from_disabled_flag(bm, op, slot_name, htype, va_arg(vlist, int));
+ BMO_slot_buffer_from_disabled_flag(bm, op, op->slots_in, slot_name, htype, va_arg(vlist, int));
}
}
diff --git a/source/blender/bmesh/intern/bmesh_operators.h b/source/blender/bmesh/intern/bmesh_operators.h
index 14da93302b9..b74d97c9bb5 100644
--- a/source/blender/bmesh/intern/bmesh_operators.h
+++ b/source/blender/bmesh/intern/bmesh_operators.h
@@ -88,11 +88,6 @@ enum {
OPUVC_AXIS_Y
};
-enum {
- DIRECTION_CW = 1,
- DIRECTION_CCW
-};
-
/* vertex path selection values */
enum {
VPATH_SELECT_EDGE_LENGTH = 0,
diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c
index 98edceb30a2..2e0471863d4 100644
--- a/source/blender/bmesh/intern/bmesh_polygon.c
+++ b/source/blender/bmesh/intern/bmesh_polygon.c
@@ -162,7 +162,7 @@ float BM_face_calc_area(BMFace *f)
float area;
int i;
- BLI_array_fixedstack_declare(verts, BM_NGON_STACK_SIZE, f->len, __func__);
+ BLI_array_fixedstack_declare(verts, BM_DEFAULT_NGON_STACK_SIZE, f->len, __func__);
BM_ITER_ELEM_INDEX (l, &iter, f, BM_LOOPS_OF_FACE, i) {
copy_v3_v3(verts[i], l->v->co);
@@ -677,6 +677,7 @@ static BMLoop *find_ear(BMFace *f, float (*verts)[3], const int use_beauty, floa
BMLoop *l_first;
const float cos_threshold = 0.9f;
+ const float bias = 1.0f + 1e-6f;
if (f->len == 4) {
BMLoop *larr[4];
@@ -691,7 +692,7 @@ static BMLoop *find_ear(BMFace *f, float (*verts)[3], const int use_beauty, floa
/* pick 0/1 based on best lenth */
/* XXX Can't only rely on such test, also must check we do not get (too much) degenerated triangles!!! */
i = (((len_squared_v3v3(larr[0]->v->co, larr[2]->v->co) >
- len_squared_v3v3(larr[1]->v->co, larr[3]->v->co))) != use_beauty);
+ len_squared_v3v3(larr[1]->v->co, larr[3]->v->co) * bias)) != use_beauty);
i4 = (i + 3) % 4;
/* Check produced tris aren’t too flat/narrow...
* Probably not the best test, but is quite efficient and should at least avoid null-area faces! */
@@ -965,8 +966,8 @@ void BM_face_legal_splits(BMesh *bm, BMFace *f, BMLoop *(*loops)[2], int len)
float fac1 = 1.0000001f, fac2 = 0.9f; //9999f; //0.999f;
int i, j, a = 0, clen;
- BLI_array_fixedstack_declare(projverts, BM_NGON_STACK_SIZE, f->len, "projvertsb");
- BLI_array_fixedstack_declare(edgeverts, BM_NGON_STACK_SIZE * 2, len * 2, "edgevertsb");
+ BLI_array_fixedstack_declare(projverts, BM_DEFAULT_NGON_STACK_SIZE, f->len, "projvertsb");
+ BLI_array_fixedstack_declare(edgeverts, BM_DEFAULT_NGON_STACK_SIZE * 2, len * 2, "edgevertsb");
i = 0;
l = BM_iter_new(&iter, bm, BM_LOOPS_OF_FACE, f);
diff --git a/source/blender/bmesh/intern/bmesh_private.h b/source/blender/bmesh/intern/bmesh_private.h
index b3fe3676ab8..850e81ba3ac 100644
--- a/source/blender/bmesh/intern/bmesh_private.h
+++ b/source/blender/bmesh/intern/bmesh_private.h
@@ -56,15 +56,21 @@ int bmesh_elem_check(void *element, const char htype);
int bmesh_radial_length(BMLoop *l);
int bmesh_disk_count(BMVert *v);
-/* NOTE: ensure different parts of the API do not conflict
+/**
+ * Internal BMHeader.api_flag
+ * \note Ensure different parts of the API do not conflict
* on using these internal flags!*/
-#define _FLAG_JF 1 /* join faces */
-#define _FLAG_MF 2 /* make face */
-#define _FLAG_MV 2 /* make face, vertex */
+enum {
+ _FLAG_JF = (1 << 0), /* join faces */
+ _FLAG_MF = (1 << 1), /* make face */
+ _FLAG_MV = (1 << 1), /* make face, vertex */
+ _FLAG_OVERLAP = (1 << 2) /* general overlap flag */
+};
-#define BM_ELEM_API_FLAG_ENABLE(element, f) ((element)->oflags[0].pflag |= (f))
-#define BM_ELEM_API_FLAG_DISABLE(element, f) ((element)->oflags[0].pflag &= ~(f))
-#define BM_ELEM_API_FLAG_TEST(element, f) ((element)->oflags[0].pflag & (f))
+#define BM_ELEM_API_FLAG_ENABLE(element, f) ((element)->head.api_flag |= (f))
+#define BM_ELEM_API_FLAG_DISABLE(element, f) ((element)->head.api_flag &= ~(f))
+#define BM_ELEM_API_FLAG_TEST(element, f) ((element)->head.api_flag & (f))
+#define BM_ELEM_API_FLAG_CLEAR(element) ((element)->head.api_flag = 0)
void calc_poly_plane(float (*verts)[3], const int nverts);
void poly_rotate_plane(const float normal[3], float (*verts)[3], const int nverts);
diff --git a/source/blender/bmesh/intern/bmesh_queries.c b/source/blender/bmesh/intern/bmesh_queries.c
index 1e1d7d1becb..ec2e90591cc 100644
--- a/source/blender/bmesh/intern/bmesh_queries.c
+++ b/source/blender/bmesh/intern/bmesh_queries.c
@@ -39,8 +39,6 @@
#include "bmesh.h"
#include "intern/bmesh_private.h"
-#define BM_OVERLAP (1 << 13)
-
/**
* Returns whether or not a given vertex is
* is part of a given edge.
@@ -240,7 +238,7 @@ int BM_vert_in_face(BMFace *f, BMVert *v)
* Compares the number of vertices in an array
* that appear in a given face
*/
-int BM_verts_in_face(BMesh *bm, BMFace *f, BMVert **varr, int len)
+int BM_verts_in_face(BMFace *f, BMVert **varr, int len)
{
BMLoop *l_iter, *l_first;
@@ -251,7 +249,7 @@ int BM_verts_in_face(BMesh *bm, BMFace *f, BMVert **varr, int len)
int i, count = 0;
for (i = 0; i < len; i++) {
- BMO_elem_flag_enable(bm, varr[i], BM_OVERLAP);
+ BM_ELEM_API_FLAG_ENABLE(varr[i], _FLAG_OVERLAP);
}
#ifdef USE_BMESH_HOLES
@@ -266,14 +264,16 @@ int BM_verts_in_face(BMesh *bm, BMFace *f, BMVert **varr, int len)
#endif
do {
- if (BMO_elem_flag_test(bm, l_iter->v, BM_OVERLAP)) {
+ if (BM_ELEM_API_FLAG_TEST(l_iter->v, _FLAG_OVERLAP)) {
count++;
}
} while ((l_iter = l_iter->next) != l_first);
}
- for (i = 0; i < len; i++) BMO_elem_flag_disable(bm, varr[i], BM_OVERLAP);
+ for (i = 0; i < len; i++) {
+ BM_ELEM_API_FLAG_DISABLE(varr[i], _FLAG_OVERLAP);
+ }
return count;
}
@@ -1217,7 +1217,7 @@ BMEdge *BM_edge_find_double(BMEdge *e)
* \returns TRUE for overlap
*
*/
-int BM_face_exists_overlap(BMesh *bm, BMVert **varr, int len, BMFace **r_overlapface)
+int BM_face_exists_overlap(BMVert **varr, int len, BMFace **r_overlapface)
{
BMIter viter;
BMFace *f;
@@ -1225,7 +1225,7 @@ int BM_face_exists_overlap(BMesh *bm, BMVert **varr, int len, BMFace **r_overlap
for (i = 0; i < len; i++) {
BM_ITER_ELEM (f, &viter, varr[i], BM_FACES_OF_VERT) {
- amount = BM_verts_in_face(bm, f, varr, len);
+ amount = BM_verts_in_face(f, varr, len);
if (amount >= len) {
if (r_overlapface) {
*r_overlapface = f;
@@ -1247,7 +1247,7 @@ int BM_face_exists_overlap(BMesh *bm, BMVert **varr, int len, BMFace **r_overlap
* there is a face with exactly those vertices
* (and only those vertices).
*/
-int BM_face_exists(BMesh *bm, BMVert **varr, int len, BMFace **r_existface)
+int BM_face_exists(BMVert **varr, int len, BMFace **r_existface)
{
BMIter viter;
BMFace *f;
@@ -1255,7 +1255,7 @@ int BM_face_exists(BMesh *bm, BMVert **varr, int len, BMFace **r_existface)
for (i = 0; i < len; i++) {
BM_ITER_ELEM (f, &viter, varr[i], BM_FACES_OF_VERT) {
- amount = BM_verts_in_face(bm, f, varr, len);
+ amount = BM_verts_in_face(f, varr, len);
if (amount == len && amount == f->len) {
if (r_existface) {
*r_existface = f;
@@ -1393,7 +1393,7 @@ int BM_face_exists_multi(BMVert **varr, BMEdge **earr, int len)
int BM_face_exists_multi_edge(BMEdge **earr, int len)
{
BMVert **varr;
- BLI_array_fixedstack_declare(varr, BM_NGON_STACK_SIZE, len, __func__);
+ BLI_array_fixedstack_declare(varr, BM_DEFAULT_NGON_STACK_SIZE, len, __func__);
int ok;
int i, i_next;
@@ -1419,3 +1419,38 @@ int BM_face_exists_multi_edge(BMEdge **earr, int len)
return ok;
}
+
+/* convenience functions for checking flags */
+int BM_edge_is_any_vert_flag_test(BMEdge *e, const char hflag)
+{
+ return (BM_elem_flag_test(e->v1, hflag) ||
+ BM_elem_flag_test(e->v2, hflag));
+}
+
+int BM_face_is_any_vert_flag_test(BMFace *f, const char hflag)
+{
+ BMLoop *l_iter;
+ BMLoop *l_first;
+
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ if (BM_elem_flag_test(l_iter->v, hflag)) {
+ return TRUE;
+ }
+ } while ((l_iter = l_iter->next) != l_first);
+ return FALSE;
+}
+
+int BM_face_is_any_edge_flag_test(BMFace *f, const char hflag)
+{
+ BMLoop *l_iter;
+ BMLoop *l_first;
+
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ if (BM_elem_flag_test(l_iter->e, hflag)) {
+ return TRUE;
+ }
+ } while ((l_iter = l_iter->next) != l_first);
+ return FALSE;
+}
diff --git a/source/blender/bmesh/intern/bmesh_queries.h b/source/blender/bmesh/intern/bmesh_queries.h
index 579a1397b0c..d97faebf021 100644
--- a/source/blender/bmesh/intern/bmesh_queries.h
+++ b/source/blender/bmesh/intern/bmesh_queries.h
@@ -28,7 +28,7 @@
*/
int BM_vert_in_face(BMFace *f, BMVert *v);
-int BM_verts_in_face(BMesh *bm, BMFace *f, BMVert **varr, int len);
+int BM_verts_in_face(BMFace *f, BMVert **varr, int len);
int BM_edge_in_face(BMFace *f, BMEdge *e);
int BM_edge_in_loop(BMEdge *e, BMLoop *l);
@@ -77,9 +77,9 @@ BMLoop *BM_face_find_longest_loop(BMFace *f);
BMEdge *BM_edge_exists(BMVert *v1, BMVert *v2);
BMEdge *BM_edge_find_double(BMEdge *e);
-int BM_face_exists_overlap(BMesh *bm, BMVert **varr, int len, BMFace **r_existface);
+int BM_face_exists_overlap(BMVert **varr, int len, BMFace **r_existface);
-int BM_face_exists(BMesh *bm, BMVert **varr, int len, BMFace **r_existface);
+int BM_face_exists(BMVert **varr, int len, BMFace **r_existface);
int BM_face_exists_multi(BMVert **varr, BMEdge **earr, int len);
int BM_face_exists_multi_edge(BMEdge **earr, int len);
@@ -100,4 +100,8 @@ void BM_edge_ordered_verts(BMEdge *edge, BMVert **r_v1, BMVert **r_v2);
void BM_edge_ordered_verts_ex(BMEdge *edge, BMVert **r_v1, BMVert **r_v2,
BMLoop *edge_loop);
+int BM_edge_is_any_vert_flag_test(BMEdge *e, const char hflag);
+int BM_face_is_any_vert_flag_test(BMFace *f, const char hflag);
+int BM_face_is_any_edge_flag_test(BMFace *f, const char hflag);
+
#endif /* __BMESH_QUERIES_H__ */
diff --git a/source/blender/bmesh/operators/bmo_bevel.c b/source/blender/bmesh/operators/bmo_bevel.c
index 7df5aa8fe9c..126d0f46119 100644
--- a/source/blender/bmesh/operators/bmo_bevel.c
+++ b/source/blender/bmesh/operators/bmo_bevel.c
@@ -15,7 +15,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
- * Contributor(s): Joseph Eagar, Aleksandr Mokhov, Howard Trickey
+ * Contributor(s):
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -24,2211 +24,38 @@
* \ingroup bmesh
*/
-#include "MEM_guardedalloc.h"
-
-#include "BLI_listbase.h"
-#include "BLI_array.h"
-#include "BLI_math.h"
-#include "BLI_smallhash.h"
-
-#include "BKE_customdata.h"
+#include "BLI_utildefines.h"
#include "bmesh.h"
#include "intern/bmesh_operators_private.h" /* own include */
-#define NEW_BEVEL 1
-
-#ifdef NEW_BEVEL
-#define BEVEL_FLAG 1
-#define EDGE_SELECTED 2
-
-#define BEVEL_EPSILON 1e-6
-
-/* Constructed vertex, sometimes later instantiated as BMVert */
-typedef struct NewVert {
- float co[3];
- BMVert *v;
-} NewVert;
-
-struct BoundVert;
-
-/* Data for one end of an edge involved in a bevel */
-typedef struct EdgeHalf {
- struct EdgeHalf *next, *prev; /* in CCW order */
- BMEdge *e; /* original mesh edge */
- int isbev; /* is this edge beveled? */
- int isrev; /* is e->v2 the vertex at this end? */
- int seg; /* how many segments for the bevel */
- float offset; /* offset for this edge */
- BMFace *fprev; /* face between this edge and previous, if any */
- BMFace *fnext; /* face between this edge and next, if any */
- struct BoundVert *leftv; /* left boundary vert (looking along edge to end) */
- struct BoundVert *rightv; /* right boundary vert, if beveled */
-} EdgeHalf;
-
-/* An element in a cyclic boundary of a Vertex Mesh (VMesh) */
-typedef struct BoundVert {
- struct BoundVert *next, *prev; /* in CCW order */
- int index; /* used for vmesh indexing */
- NewVert nv;
- EdgeHalf *efirst; /* first of edges attached here: in CCW order */
- EdgeHalf *elast;
- EdgeHalf *ebev; /* beveled edge whose left side is attached here, if any */
-} BoundVert;
-
-/* Mesh structure replacing a vertex */
-typedef struct VMesh {
- enum {
- M_NONE, /* no polygon mesh needed */
- M_POLY, /* a simple polygon */
- M_ADJ, /* "adjacent edges" mesh pattern */
- M_CROSS, /* "cross edges" mesh pattern */
- } mesh_kind;
- int count; /* number of vertices in the boundary */
- int seg; /* common # of segments for segmented edges */
- BoundVert *boundstart; /* start of boundary double-linked list */
- NewVert *mesh; /* allocated array - size and structure depends on kind */
-} VMesh;
-
-/* Data for a vertex involved in a bevel */
-typedef struct BevVert {
- struct BevVert *next, *prev;
- BMVert *v; /* original mesh vertex */
- int edgecount; /* total number of edges around the vertex */
- int selcount; /* number of selected edges around the vertex */
- EdgeHalf *edges; /* array of size edgecount; CCW order from vertex normal side */
- VMesh *vmesh; /* mesh structure for replacing vertex */
-} BevVert;
-
-/*
- * Bevel parameters and state
- */
-typedef struct BevelParams {
- ListBase vertList; /* list of BevVert for each vertex involved in bevel */
- float offset; /* blender units to offset each side of a beveled edge */
- int seg; /* number of segments in beveled edge profile */
-
- BMOperator *op;
-} BevelParams;
-
-/* Make a new BoundVert of the given kind, insert it at the end of the circular linked
- * list with entry point bv->boundstart, and return it. */
-static BoundVert *add_new_bound_vert(VMesh *vm, float co[3])
-{
- BoundVert *ans = (BoundVert *) MEM_callocN(sizeof(BoundVert), "BoundVert");
- copy_v3_v3(ans->nv.co, co);
- if (!vm->boundstart) {
- ans->index = 0;
- vm->boundstart = ans;
- ans->next = ans->prev = ans;
- }
- else {
- BoundVert *tail = vm->boundstart->prev;
- ans->index = tail->index + 1;
- ans->prev = tail;
- ans->next = vm->boundstart;
- tail->next = ans;
- vm->boundstart->prev = ans;
- }
- vm->count++;
- return ans;
-}
-
-/* Mesh verts are indexed (i, j, k) where
- * i = boundvert index (0 <= i < nv)
- * j = ring index (0 <= j <= ns2)
- * k = segment index (0 <= k <= ns)
- * Not all of these are used, and some will share BMVerts */
-static NewVert *mesh_vert(VMesh *vm, int i, int j, int k)
-{
- int nj = (vm->seg / 2) + 1;
- int nk = vm->seg + 1;
-
- return &vm->mesh[i * nk * nj + j * nk + 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);
-}
-
-static void copy_mesh_vert(VMesh *vm, int ito, int jto, int kto,
- int ifrom, int jfrom, int kfrom)
-{
- NewVert *nvto, *nvfrom;
-
- nvto = mesh_vert(vm, ito, jto, kto);
- nvfrom = mesh_vert(vm, ifrom, jfrom, kfrom);
- nvto->v = nvfrom->v;
- copy_v3_v3(nvto->co, nvfrom->co);
-}
-
-/* find the EdgeHalf in bv's array that has edge bme */
-static EdgeHalf *find_edge_half(BevVert *bv, BMEdge *bme)
-{
- int i;
-
- for (i = 0; i < bv->edgecount; i++) {
- if (bv->edges[i].e == bme)
- return &bv->edges[i];
- }
- return NULL;
-}
-
-/* Return the next EdgeHalf after from_e that is beveled.
- * If from_e is NULL, find the first beveled edge. */
-static EdgeHalf *next_bev(BevVert *bv, EdgeHalf *from_e)
-{
- EdgeHalf *e;
-
- if (from_e == NULL)
- from_e = &bv->edges[bv->edgecount - 1];
- e = from_e;
- do {
- if (e->isbev)
- return e;
- e = e->next;
- } while (e != from_e);
- return NULL;
-}
-
-/* find the BevVert corresponding to BMVert bmv */
-static BevVert *find_bevvert(BevelParams *bp, BMVert *bmv)
-{
- BevVert *bv;
-
- for (bv = bp->vertList.first; bv; bv = bv->next) {
- if (bv->v == bmv)
- return bv;
- }
- return NULL;
-}
-
-/* Return a good respresentative face (for materials, etc.) for faces
- * created around/near BoundVert v */
-static BMFace *boundvert_rep_face(BoundVert *v)
-{
- BMFace *fans = NULL;
- BMFace *firstf = NULL;
- BMEdge *e1, *e2;
- BMFace *f1, *f2;
- BMIter iter1, iter2;
-
- BLI_assert(v->efirst != NULL && v->elast != NULL);
- e1 = v->efirst->e;
- e2 = v->elast->e;
- BM_ITER_ELEM (f1, &iter1, e1, BM_FACES_OF_EDGE) {
- if (!firstf)
- firstf = f1;
- BM_ITER_ELEM (f2, &iter2, e2, BM_FACES_OF_EDGE) {
- if (f1 == f2) {
- fans = f1;
- break;
- }
- }
- }
- if (!fans)
- fans = firstf;
-
- return fans;
-}
-
-/* Make ngon from verts alone.
- * Make sure to properly copy face attributes and do custom data interpolation from
- * example face, facerep. */
-static BMFace *bev_create_ngon(BMesh *bm, BMVert **vert_arr, int totv, BMFace *facerep)
-{
- BMIter iter;
- BMLoop *l;
- BMFace *f;
-
- if (totv == 3) {
- f = BM_face_create_quad_tri(bm,
- vert_arr[0], vert_arr[1], vert_arr[2], NULL, facerep, 0);
- }
- else if (totv == 4) {
- f = BM_face_create_quad_tri(bm,
- vert_arr[0], vert_arr[1], vert_arr[2], vert_arr[3], facerep, 0);
- }
- else {
- int i;
- BMEdge *e;
- BMEdge **ee = NULL;
- BLI_array_staticdeclare(ee, 30);
-
- for (i = 0; i < totv; i++) {
- e = BM_edge_create(bm, vert_arr[i], vert_arr[(i + 1) % totv], NULL, TRUE);
- BLI_array_append(ee, e);
- }
- f = BM_face_create_ngon(bm, vert_arr[0], vert_arr[1], ee, totv, FALSE);
- BLI_array_free(ee);
- }
- if (facerep && f) {
- int has_mdisps = CustomData_has_layer(&bm->ldata, CD_MDISPS);
- BM_elem_attrs_copy(bm, bm, facerep, f);
- BM_ITER_ELEM (l, &iter, f, BM_LOOPS_OF_FACE) {
- BM_loop_interp_from_face(bm, l, facerep, TRUE, TRUE);
- if (has_mdisps)
- BM_loop_interp_multires(bm, l, facerep);
- }
- }
- return f;
-}
-
-static BMFace *bev_create_quad_tri(BMesh *bm, BMVert *v1, BMVert *v2, BMVert *v3, BMVert *v4,
- BMFace *facerep)
-{
- BMVert *varr[4];
-
- varr[0] = v1;
- varr[1] = v2;
- varr[2] = v3;
- varr[3] = v4;
- return bev_create_ngon(bm, varr, v4 ? 4 : 3, facerep);
-}
-
-/*
- * Calculate the meeting point between the offset edges for e1 and e2, putting answer in meetco.
- * e1 and e2 share vertex v and face f (may be NULL) and viewed from the normal side of
- * the bevel vertex, e1 precedes e2 in CCW order.
- * If on_right is true, offset edge is on right of both edges, where e1 enters v and
- * e2 leave it. If on_right is false, then the offset edge is on the left.
- * When offsets are equal, the new point is on the edge bisector, with length offset/sin(angle/2),
- * but if the offsets are not equal (allowing for this, as bevel modifier has edge weights that may
- * lead to different offsets) then meeting point can be found be intersecting offset lines.
- */
-static void offset_meet(EdgeHalf *e1, EdgeHalf *e2, BMVert *v, BMFace *f,
- int on_right, float meetco[3])
-{
- float dir1[3], dir2[3], norm_v[3], norm_perp1[3], norm_perp2[3],
- off1a[3], off1b[3], off2a[3], off2b[3], isect2[3];
-
- /* get direction vectors for two offset lines */
- sub_v3_v3v3(dir1, v->co, BM_edge_other_vert(e1->e, v)->co);
- sub_v3_v3v3(dir2, BM_edge_other_vert(e2->e, v)->co, v->co);
-
- /* get normal to plane where meet point should be */
- cross_v3_v3v3(norm_v, dir2, dir1);
- normalize_v3(norm_v);
- if (!on_right)
- negate_v3(norm_v);
- if (is_zero_v3(norm_v)) {
- /* special case: e1 and e2 are parallel; put offset point perp to both, from v.
- * need to find a suitable plane.
- * if offsets are different, we're out of luck: just use e1->offset */
- if (f)
- copy_v3_v3(norm_v, f->no);
- else
- copy_v3_v3(norm_v, v->no);
- cross_v3_v3v3(norm_perp1, dir1, norm_v);
- normalize_v3(norm_perp1);
- copy_v3_v3(off1a, v->co);
- madd_v3_v3fl(off1a, norm_perp1, e1->offset);
- copy_v3_v3(meetco, off1a);
- }
- else {
- /* get vectors perp to each edge, perp to norm_v, and pointing into face */
- if (f) {
- copy_v3_v3(norm_v, f->no);
- normalize_v3(norm_v);
- }
- cross_v3_v3v3(norm_perp1, dir1, norm_v);
- cross_v3_v3v3(norm_perp2, dir2, norm_v);
- normalize_v3(norm_perp1);
- normalize_v3(norm_perp2);
-
- /* get points that are offset distances from each line, then another point on each line */
- copy_v3_v3(off1a, v->co);
- madd_v3_v3fl(off1a, norm_perp1, e1->offset);
- add_v3_v3v3(off1b, off1a, dir1);
- copy_v3_v3(off2a, v->co);
- madd_v3_v3fl(off2a, norm_perp2, e2->offset);
- add_v3_v3v3(off2b, off2a, dir2);
-
- /* intersect the lines; by construction they should be on the same plane and not parallel */
- if (!isect_line_line_v3(off1a, off1b, off2a, off2b, meetco, isect2)) {
- BLI_assert(!"offset_meet failure");
- copy_v3_v3(meetco, off1a); /* just to do something */
- }
- }
-}
-
-/* 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])
-{
- float dir1[3], dir2[3], norm_perp1[3], norm_perp2[3],
- off1a[3], off1b[3], off2a[3], off2b[3], isect2[3];
-
- BLI_assert(f1 != NULL && f2 != NULL);
-
- /* get direction vectors for two offset lines */
- sub_v3_v3v3(dir1, v->co, BM_edge_other_vert(e1->e, v)->co);
- sub_v3_v3v3(dir2, BM_edge_other_vert(e2->e, v)->co, v->co);
-
- /* get directions into offset planes */
- cross_v3_v3v3(norm_perp1, dir1, f1->no);
- normalize_v3(norm_perp1);
- cross_v3_v3v3(norm_perp2, dir2, f2->no);
- normalize_v3(norm_perp2);
-
- /* get points that are offset distances from each line, then another point on each line */
- copy_v3_v3(off1a, v->co);
- madd_v3_v3fl(off1a, norm_perp1, e1->offset);
- add_v3_v3v3(off1b, off1a, dir1);
- copy_v3_v3(off2a, v->co);
- madd_v3_v3fl(off2a, norm_perp2, e2->offset);
- add_v3_v3v3(off2b, off2a, dir2);
-
- /* intersect the lines; by construction they should be on the same plane and not parallel */
- if (!isect_line_line_v3(off1a, off1b, off2a, off2b, meetco, isect2)) {
- BLI_assert(!"offset_meet failure");
- copy_v3_v3(meetco, off1a); /* just to do something */
- }
-}
-
-/* Offset by e->offset in plane with normal plane_no, on left if left==TRUE,
- * else on right. If no is NULL, choose an arbitrary plane different
- * from eh's direction. */
-static void offset_in_plane(EdgeHalf *e, float plane_no[3], int left, float r[3])
-{
- float dir[3], no[3];
- BMVert *v;
-
- v = e->isrev ? e->e->v1 : e->e->v2;
-
- sub_v3_v3v3(dir, BM_edge_other_vert(e->e, v)->co, v->co);
- normalize_v3(dir);
- if (plane_no) {
- copy_v3_v3(no, plane_no);
- }
- else {
- zero_v3(no);
- if (fabs(dir[0]) < fabs(dir[1]))
- no[0] = 1.0f;
- else
- no[1] = 1.0f;
- }
- if (left)
- cross_v3_v3v3(r, no, dir);
- else
- cross_v3_v3v3(r, dir, no);
- normalize_v3(r);
- mul_v3_fl(r, e->offset);
-}
-
-/* Calculate coordinates of a point a distance d from v on e->e and return it in slideco */
-static void slide_dist(EdgeHalf *e, BMVert *v, float d, float slideco[3])
-{
- float dir[3], len;
-
- sub_v3_v3v3(dir, v->co, BM_edge_other_vert(e->e, v)->co);
- len = len_v3(dir);
- normalize_v3(dir);
- if (d > len)
- d = len - (float)(50 * BEVEL_EPSILON);
- copy_v3_v3(slideco, v->co);
- madd_v3_v3fl(slideco, dir, -d);
-}
-
-/* Calculate the point on e where line (co_a, co_b) comes closest to and return it in projco */
-static void project_to_edge(BMEdge *e, float co_a[3], float co_b[3], float projco[3])
-{
- float otherco[3];
-
- if (!isect_line_line_v3(e->v1->co, e->v2->co, co_a, co_b,
- projco, otherco)) {
- BLI_assert(!"project meet failure");
- copy_v3_v3(projco, e->v1->co);
- }
-}
-
-
-/* return 1 if a and b are in CCW order on the normal side of f,
- * and -1 if they are reversed, and 0 if there is no shared face f */
-static int bev_ccw_test(BMEdge *a, BMEdge *b, BMFace *f)
-{
- BMLoop *la, *lb;
-
- if (!f)
- return 0;
- la = BM_face_edge_share_loop(f, a);
- lb = BM_face_edge_share_loop(f, b);
- if (!la || !lb)
- return 0;
- return lb->next == la ? 1 : -1;
-}
-
-/*
- * calculation of points on the round profile
- * r - result, coordinate of point on round profile
- * method:
- * Inscribe a circle in angle va - v -vb
- * such that it touches the arms at offset from v.
- * Rotate the center-va segment by (i/n) of the
- * angle va - center -vb, and put the endpoint
- * of that segment in r.
- */
-static void get_point_on_round_profile(float r[3], float offset, int i, int count,
- float va[3], float v[3], float vb[3])
-{
- float vva[3], vvb[3], angle, center[3], rv[3], axis[3], co[3];
-
- sub_v3_v3v3(vva, va, v);
- sub_v3_v3v3(vvb, vb, v);
- normalize_v3(vva);
- normalize_v3(vvb);
- angle = angle_v3v3(vva, vvb);
-
- add_v3_v3v3(center, vva, vvb);
- normalize_v3(center);
- mul_v3_fl(center, offset * (1.0f / cosf(0.5f * angle)));
- add_v3_v3(center, v); /* coordinates of the center of the inscribed circle */
-
-
- sub_v3_v3v3(rv, va, center); /* radius vector */
-
-
- sub_v3_v3v3(co, v, center);
- cross_v3_v3v3(axis, rv, co); /* calculate axis */
-
- sub_v3_v3v3(vva, va, center);
- sub_v3_v3v3(vvb, vb, center);
- angle = angle_v3v3(vva, vvb);
-
- rotate_v3_v3v3fl(co, rv, axis, angle * (float)(i) / (float)(count));
-
- add_v3_v3(co, center);
- copy_v3_v3(r, co);
-}
-
-/*
- * Find the point (i/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:
- * Adjust va and vb (along edge direction) so that they are perpendicular
- * to edge at v, then use get_point_on_round_profile, then project
- * back onto original va - vmid - vb plane.
- * If va, vmid, and vb are all on the same plane, just interpolate between va and vb.
- */
-static void get_point_on_round_edge(EdgeHalf *e, int i,
- float va[3], float vmid[3], float vb[3], float profileco[3])
-{
- float vva[3], vvb[3], point[3], dir[3], vaadj[3], vbadj[3], p2[3], pn[3];
- int n = e->seg;
-
- sub_v3_v3v3(vva, va, vmid);
- sub_v3_v3v3(vvb, vb, vmid);
- if (e->isrev)
- sub_v3_v3v3(dir, e->e->v1->co, e->e->v2->co);
- else
- sub_v3_v3v3(dir, e->e->v2->co, e->e->v1->co);
- normalize_v3(dir);
- if (fabsf(angle_v3v3(vva, vvb) - (float)M_PI) > (float)BEVEL_EPSILON) {
- copy_v3_v3(vaadj, va);
- madd_v3_v3fl(vaadj, dir, -len_v3(vva) * cosf(angle_v3v3(vva, dir)));
- copy_v3_v3(vbadj, vb);
- madd_v3_v3fl(vbadj, dir, -len_v3(vvb) * cosf(angle_v3v3(vvb, dir)));
-
- get_point_on_round_profile(point, e->offset, i, n, vaadj, vmid, vbadj);
-
- add_v3_v3v3(p2, profileco, dir);
- cross_v3_v3v3(pn, vva, vvb);
- if (!isect_line_plane_v3(profileco, point, p2, vmid, pn, 0)) {
- BLI_assert(!"bevel: unexpected non-intersection");
- copy_v3_v3(profileco, point);
- }
- }
- else {
- /* planar case */
- interp_v3_v3v3(profileco, va, vb, (float) i / (float) n);
- }
-}
-
-static void mid_v3_v3v3v3(float v[3], const float v1[3], const float v2[3], const float v3[3])
-{
- v[0] = (v1[0] + v2[0] + v3[0]) / 3.0f;
- v[1] = (v1[1] + v2[1] + v3[1]) / 3.0f;
- v[2] = (v1[2] + v2[2] + v3[2]) / 3.0f;
-}
-
-/* Make a circular list of BoundVerts for bv, each of which has the coordinates
- * of a vertex on the the boundary of the beveled vertex bv->v.
- * Also decide on the mesh pattern that will be used inside the boundary.
- * Doesn't make the actual BMVerts */
-static void build_boundary(BevVert *bv)
-{
- EdgeHalf *efirst, *e;
- BoundVert *v;
- VMesh *vm;
- float co[3], *no;
- float lastd;
-
- e = efirst = next_bev(bv, NULL);
- vm = bv->vmesh;
-
- BLI_assert(bv->edgecount >= 2); /* since bevel edges incident to 2 faces */
-
- if (bv->edgecount == 2 && bv->selcount == 1) {
- /* special case: beveled edge meets non-beveled one at valence 2 vert */
- no = e->fprev ? e->fprev->no : (e->fnext ? e->fnext->no : NULL);
- offset_in_plane(e, no, TRUE, co);
- v = add_new_bound_vert(vm, co);
- v->efirst = v->elast = v->ebev = e;
- e->leftv = v;
- no = e->fnext ? e->fnext->no : (e->fprev ? e->fprev->no : NULL);
- offset_in_plane(e, no, FALSE, co);
- v = add_new_bound_vert(vm, co);
- v->efirst = v->elast = e;
- e->rightv = v;
- /* make artifical extra point along unbeveled edge, and form triangle */
- slide_dist(e->next, bv->v, e->offset, co);
- v = add_new_bound_vert(vm, co);
- v->efirst = v->elast = e->next;
- vm->mesh_kind = M_POLY;
- return;
- }
-
- lastd = e->offset;
- vm->boundstart = NULL;
- do {
- if (e->isbev) {
- /* handle only left side of beveled edge e here: next iteration should do right side */
- if (e->prev->isbev) {
- BLI_assert(e->prev != e); /* see: wire edge special case */
- offset_meet(e->prev, e, bv->v, e->fprev, TRUE, co);
- v = add_new_bound_vert(vm, co);
- v->efirst = e->prev;
- v->elast = v->ebev = e;
- e->leftv = v;
- e->prev->rightv = v;
- }
- else {
- /* e->prev is not beveled */
- if (e->prev->prev->isbev) {
- 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,
- e->prev->prev->fnext, e->fprev, co);
- v = add_new_bound_vert(vm, co);
- v->efirst = e->prev->prev;
- v->elast = v->ebev = e;
- e->leftv = v;
- e->prev->leftv = v;
- e->prev->prev->rightv = v;
- }
- else {
- /* neither e->prev nor e->prev->prev are beveled: make on-edge on e->prev */
- offset_meet(e->prev, e, bv->v, e->fprev, TRUE, co);
- v = add_new_bound_vert(vm, co);
- v->efirst = e->prev;
- v->elast = v->ebev = e;
- e->leftv = v;
- e->prev->leftv = v;
- }
- }
- lastd = len_v3v3(bv->v->co, v->nv.co);
- }
- else {
- /* e is not beveled */
- if (e->next->isbev) {
- /* next iteration will place e between beveled previous and next edges */
- e = e->next;
- continue;
- }
- if (e->prev->isbev) {
- /* on-edge meet between e->prev and e */
- offset_meet(e->prev, e, bv->v, e->fprev, TRUE, co);
- v = add_new_bound_vert(vm, co);
- v->efirst = e->prev;
- v->elast = e;
- e->leftv = v;
- e->prev->rightv = v;
- }
- else {
- /* None of e->prev, e, e->next are beveled.
- * could either leave alone or add slide points to make
- * one polygon around bv->v. For now, we choose latter.
- * Could slide to make an even bevel plane but for now will
- * just use last distance a meet point moved from bv->v. */
- slide_dist(e, bv->v, lastd, co);
- v = add_new_bound_vert(vm, co);
- v->efirst = v->elast = e;
- e->leftv = v;
- }
- }
- e = e->next;
- } while (e != efirst);
-
- BLI_assert(vm->count >= 2);
- if (vm->count == 2 && bv->edgecount == 3)
- vm->mesh_kind = M_NONE;
- else if (efirst->seg == 1 || bv->selcount < 3)
- vm->mesh_kind = M_POLY;
- else
- vm->mesh_kind = M_ADJ;
- /* TODO: if vm->count == 4 and bv->selcount == 4, use M_CROSS pattern */
-}
-
-/*
- * Given that the boundary is built and the boundary BMVerts have been made,
- * calculate the positions of the interior mesh points for the M_ADJ pattern,
- * then make the BMVerts and the new faces. */
-static void bevel_build_rings(BMesh *bm, BevVert *bv)
-{
- int k, ring, i, n, ns, ns2, nn;
- VMesh *vm = bv->vmesh;
- BoundVert *v, *vprev, *vnext;
- NewVert *nv, *nvprev, *nvnext;
- BMVert *bmv, *bmv1, *bmv2, *bmv3, *bmv4;
- BMFace *f;
- float co[3], coa[3], cob[3], midco[3];
-
- n = vm->count;
- ns = vm->seg;
- ns2 = ns / 2;
- BLI_assert(n > 2 && ns > 1);
-
- /* Make initial rings, going between points on neighbors */
- for (ring = 1; ring <= ns2; ring++) {
- v = vm->boundstart;
- do {
- i = v->index;
- if (v->ebev) {
- /* get points coords of points a and b, on outer rings
- * of prev and next edges, k away from this edge */
- vprev = v->prev;
- vnext = v->next;
-
- if (vprev->ebev)
- nvprev = mesh_vert(vm, vprev->index, 0, ns - ring);
- else
- nvprev = mesh_vert(vm, vprev->index, 0, ns);
- copy_v3_v3(coa, nvprev->co);
- nv = mesh_vert(vm, i, ring, 0);
- copy_v3_v3(nv->co, coa);
- nv->v = nvprev->v;
-
- if (vnext->ebev)
- nvnext = mesh_vert(vm, vnext->index, 0, ring);
- else
- nvnext = mesh_vert(vm, vnext->index, 0, 0);
- copy_v3_v3(cob, nvnext->co);
- nv = mesh_vert(vm, i, ring, ns);
- copy_v3_v3(nv->co, cob);
- nv->v = nvnext->v;
-
- /* TODO: better calculation of new midarc point? */
- project_to_edge(v->ebev->e, coa, cob, midco);
-
- for (k = 1; k < ns; k++) {
- get_point_on_round_edge(v->ebev, k, coa, midco, cob, co);
- copy_v3_v3(mesh_vert(vm, i, ring, k)->co, co);
- }
- }
- v = v->next;
- } while (v != vm->boundstart);
- }
-
- /* Now make sure cross points of rings share coordinates and vertices */
- v = vm->boundstart;
- do {
- i = v->index;
- if (v->ebev) {
- vprev = v->prev;
- vnext = v->next;
- if (vprev->ebev) {
- for (ring = 1; ring <= ns2; ring++) {
- for (k = 1; k <= ns2; k++) {
- if (ns % 2 == 0 && (k == ns2 || ring == ns2))
- continue; /* center line is special case: do after the rest are done */
- nv = mesh_vert(vm, i, ring, k);
- nvprev = mesh_vert(vm, vprev->index, k, ns - ring);
- mid_v3_v3v3(co, nv->co, nvprev->co);
- copy_v3_v3(nv->co, co);
- BLI_assert(nv->v == NULL && nvprev->v == NULL);
- create_mesh_bmvert(bm, vm, i, ring, k, bv->v);
- copy_mesh_vert(vm, vprev->index, k, ns - ring, i, ring, k);
- }
- }
- if (!vprev->prev->ebev) {
- for (ring = 1; ring <= ns2; ring++) {
- for (k = 1; k <= ns2; k++) {
- if (ns % 2 == 0 && (k == ns2 || ring == ns2))
- continue;
- create_mesh_bmvert(bm, vm, vprev->index, ring, k, bv->v);
- }
- }
- }
- if (!vnext->ebev) {
- for (ring = 1; ring <= ns2; ring++) {
- for (k = ns - ns2; k < ns; k++) {
- if (ns % 2 == 0 && (k == ns2 || ring == ns2))
- continue;
- create_mesh_bmvert(bm, vm, i, ring, k, bv->v);
- }
- }
- }
- }
- }
- v = v->next;
- } while (v != vm->boundstart);
-
- if (ns % 2 == 0) {
- /* do special case center lines */
- v = vm->boundstart;
- do {
- i = v->index;
- if (v->ebev) {
- vprev = v->prev;
- vnext = v->next;
- for (k = 1; k < ns2; k++) {
- nv = mesh_vert(vm, i, k, ns2);
- if (vprev->ebev)
- nvprev = mesh_vert(vm, vprev->index, ns2, ns - k);
- if (vnext->ebev)
- nvnext = mesh_vert(vm, vnext->index, ns2, k);
- if (vprev->ebev && vnext->ebev) {
- mid_v3_v3v3v3(co, nvprev->co, nv->co, nvnext->co);
- copy_v3_v3(nv->co, co);
- create_mesh_bmvert(bm, vm, i, k, ns2, bv->v);
- copy_mesh_vert(vm, vprev->index, ns2, ns - k, i, k, ns2);
- copy_mesh_vert(vm, vnext->index, ns2, k, i, k, ns2);
-
- }
- else if (vprev->ebev) {
- mid_v3_v3v3(co, nvprev->co, nv->co);
- copy_v3_v3(nv->co, co);
- create_mesh_bmvert(bm, vm, i, k, ns2, bv->v);
- copy_mesh_vert(vm, vprev->index, ns2, ns - k, i, k, ns2);
- }
- else if (vnext->ebev) {
- mid_v3_v3v3(co, nv->co, nvnext->co);
- copy_v3_v3(nv->co, co);
- create_mesh_bmvert(bm, vm, i, k, ns2, bv->v);
- copy_mesh_vert(vm, vnext->index, ns2, k, i, k, ns2);
- }
- }
- }
- v = v->next;
- } while (v != vm->boundstart);
-
- /* center point need to be average of all centers of rings */
- /* TODO: this is wrong if not all verts have ebev: could have
- * several disconnected sections of mesh. */
- zero_v3(midco);
- nn = 0;
- v = vm->boundstart;
- do {
- i = v->index;
- if (v->ebev) {
- nv = mesh_vert(vm, i, ns2, ns2);
- add_v3_v3(midco, nv->co);
- nn++;
- }
- v = v->next;
- } while (v != vm->boundstart);
- mul_v3_fl(midco, 1.0f / nn);
- bmv = BM_vert_create(bm, midco, NULL);
- v = vm->boundstart;
- do {
- i = v->index;
- if (v->ebev) {
- nv = mesh_vert(vm, i, ns2, ns2);
- copy_v3_v3(nv->co, midco);
- nv->v = bmv;
- }
- v = v->next;
- } while (v != vm->boundstart);
- }
-
- /* Make the ring quads */
- for (ring = 0; ring < ns2; ring++) {
- v = vm->boundstart;
- do {
- i = v->index;
- f = boundvert_rep_face(v);
- if (v->ebev && (v->prev->ebev || v->next->ebev)) {
- for (k = 0; k < ns2 + (ns % 2); k++) {
- bmv1 = mesh_vert(vm, i, ring, k)->v;
- bmv2 = mesh_vert(vm, i, ring, k + 1)->v;
- bmv3 = mesh_vert(vm, i, ring + 1, k + 1)->v;
- bmv4 = mesh_vert(vm, i, ring + 1, k)->v;
- BLI_assert(bmv1 && bmv2 && bmv3 && bmv4);
- if (bmv3 == bmv4 || bmv1 == bmv4)
- bmv4 = NULL;
- bev_create_quad_tri(bm, bmv1, bmv2, bmv3, bmv4, f);
- }
- }
- else if (v->prev->ebev && v->prev->prev->ebev) {
- /* finish off a sequence of beveled edges */
- i = v->prev->index;
- f = boundvert_rep_face(v->prev);
- for (k = ns2 + (ns % 2); k < ns; k++) {
- bmv1 = mesh_vert(vm, i, ring + 1, k)->v;
- bmv2 = mesh_vert(vm, i, ring, k)->v;
- bmv3 = mesh_vert(vm, i, ring, k + 1)->v;
- BLI_assert(bmv1 && bmv2 && bmv3);
- bev_create_quad_tri(bm, bmv1, bmv2, bmv3, NULL, f);
- }
- }
- v = v->next;
- } while (v != vm->boundstart);
- }
-
- /* Make center ngon if odd number of segments and fully beveled */
- if (ns % 2 == 1 && vm->count == bv->selcount) {
- BMVert **vv = NULL;
- BLI_array_declare(vv);
-
- v = vm->boundstart;
- do {
- i = v->index;
- BLI_assert(v->ebev);
- BLI_array_append(vv, mesh_vert(vm, i, ns2, ns2)->v);
- v = v->next;
- } while (v != vm->boundstart);
- f = boundvert_rep_face(vm->boundstart);
- bev_create_ngon(bm, vv, BLI_array_count(vv), f);
-
- BLI_array_free(vv);
- }
-
- /* Make 'rest-of-vmesh' polygon if not fully beveled */
- if (vm->count > bv->selcount) {
- int j;
- BMVert **vv = NULL;
- BLI_array_declare(vv);
-
- v = vm->boundstart;
- f = boundvert_rep_face(v);
- j = 0;
- do {
- i = v->index;
- if (v->ebev) {
- if (!v->prev->ebev) {
- for (k = 0; k < ns2; k++) {
- bmv1 = mesh_vert(vm, i, ns2, k)->v;
- if (!(j > 0 && bmv1 == vv[j - 1])) {
- BLI_array_append(vv, bmv1);
- j++;
- }
- }
- }
- bmv1 = mesh_vert(vm, i, ns2, ns2)->v;
- if (!(j > 0 && bmv1 == vv[j - 1])) {
- BLI_array_append(vv, bmv1);
- j++;
- }
- if (!v->next->ebev) {
- for (k = ns - ns2; k < ns; k++) {
- bmv1 = mesh_vert(vm, i, ns2, k)->v;
- if (!(j > 0 && bmv1 == vv[j - 1])) {
- BLI_array_append(vv, bmv1);
- j++;
- }
- }
- }
- }
- else {
- BLI_array_append(vv, mesh_vert(vm, i, 0, 0)->v);
- j++;
- }
- v = v->next;
- } while (v != vm->boundstart);
- if (vv[0] == vv[j - 1])
- j--;
- bev_create_ngon(bm, vv, j, f);
-
- BLI_array_free(vv);
- }
-}
-
-static void bevel_build_poly(BMesh *bm, BevVert *bv)
-{
- int n, k;
- VMesh *vm = bv->vmesh;
- BoundVert *v;
- BMVert **vv = NULL;
- BLI_array_declare(vv);
-
- v = vm->boundstart;
- n = 0;
- do {
- /* accumulate vertices for vertex ngon */
- BLI_array_append(vv, v->nv.v);
- n++;
- if (v->ebev && v->ebev->seg > 1) {
- for (k = 1; k < v->ebev->seg; k++) {
- BLI_array_append(vv, mesh_vert(vm, v->index, 0, k)->v);
- n++;
- }
- }
- v = v->next;
- } while (v != vm->boundstart);
- if (n > 2)
- bev_create_ngon(bm, vv, n, boundvert_rep_face(v));
- BLI_array_free(vv);
-}
-
-/* Given that the boundary is built, now make the actual BMVerts
- * for the boundary and the interior of the vertex mesh. */
-static void build_vmesh(BMesh *bm, BevVert *bv)
-{
- VMesh *vm = bv->vmesh;
- BoundVert *v, *weld1, *weld2;
- int n, ns, ns2, i, k, weld;
- float *va, *vb, co[3], midco[3];
-
- n = vm->count;
- ns = vm->seg;
- ns2 = ns / 2;
-
- vm->mesh = (NewVert *)MEM_callocN(n * (ns2 + 1) * (ns + 1) * sizeof(NewVert), "NewVert");
-
- /* special case: two beveled ends welded together */
- weld = (bv->selcount == 2) && (vm->count == 2);
- weld1 = weld2 = NULL; /* will hold two BoundVerts involved in weld */
-
- /* make (i, 0, 0) mesh verts for all i */
- v = vm->boundstart;
- do {
- i = v->index;
- copy_v3_v3(mesh_vert(vm, i, 0, 0)->co, v->nv.co);
- create_mesh_bmvert(bm, vm, i, 0, 0, bv->v);
- v->nv.v = mesh_vert(vm, i, 0, 0)->v;
- if (weld && v->ebev) {
- if (!weld1)
- weld1 = v;
- else
- weld2 = v;
- }
- v = v->next;
- } while (v != vm->boundstart);
-
- /* copy other ends to (i, 0, ns) for all i, and fill in profiles for beveled edges */
- v = vm->boundstart;
- do {
- i = v->index;
- copy_mesh_vert(vm, i, 0, ns, v->next->index, 0, 0);
- if (v->ebev) {
- va = mesh_vert(vm, i, 0, 0)->co;
- vb = mesh_vert(vm, i, 0, ns)->co;
- project_to_edge(v->ebev->e, va, vb, midco);
- for (k = 1; k < ns; k++) {
- get_point_on_round_edge(v->ebev, k, va, midco, vb, co);
- copy_v3_v3(mesh_vert(vm, i, 0, k)->co, co);
- if (!weld)
- create_mesh_bmvert(bm, vm, i, 0, k, bv->v);
- }
- }
- v = v->next;
- } while (v != vm->boundstart);
-
- if (weld) {
- for (k = 1; k < ns; k++) {
- mid_v3_v3v3(co, mesh_vert(vm, weld1->index, 0, k)->co,
- mesh_vert(vm, weld2->index, 0, ns - k)->co);
- copy_v3_v3(mesh_vert(vm, weld1->index, 0, k)->co, co);
- create_mesh_bmvert(bm, vm, weld1->index, 0, k, bv->v);
- }
- for (k = 1; k < ns; k++)
- copy_mesh_vert(vm, weld2->index, 0, ns - k, weld1->index, 0, k);
- }
-
- if (vm->mesh_kind == M_ADJ)
- bevel_build_rings(bm, bv);
- else if (vm->mesh_kind == M_POLY)
- bevel_build_poly(bm, bv);
-}
-
-/*
- * Construction around the vertex
- */
-static void bevel_vert_construct(BMesh *bm, BevelParams *bp, BMOperator *op, BMVert *v)
-{
-
- BMOIter siter;
- BMEdge *bme;
- BevVert *bv;
- BMEdge *bme2, *unflagged_bme;
- BMFace *f;
- BMIter iter, iter2;
- EdgeHalf *e;
- int i, ntot, found_shared_face, ccw_test_sum;
- int nsel = 0;
-
- /* Gather input selected edges.
- * Only bevel selected edges that have exactly two incident faces. */
- BMO_ITER (bme, &siter, bm, op, "geom", BM_EDGE) {
- if ((bme->v1 == v) || (BM_edge_other_vert(bme, bme->v1) == v)) {
- if (BM_edge_face_count(bme) == 2) {
- BMO_elem_flag_enable(bm, bme, EDGE_SELECTED);
- nsel++;
- }
- }
- }
-
- if (nsel == 0)
- return;
-
- ntot = BM_vert_edge_count(v);
- bv = (BevVert *)MEM_callocN(sizeof(BevVert), "BevVert");
- bv->v = v;
- bv->edgecount = ntot;
- bv->selcount = nsel;
- bv->edges = (EdgeHalf *)MEM_callocN(ntot * sizeof(EdgeHalf), "EdgeHalf");
- bv->vmesh = (VMesh *)MEM_callocN(sizeof(VMesh), "VMesh");
- bv->vmesh->seg = bp->seg;
- BLI_addtail(&bp->vertList, bv);
-
- /* add edges to bv->edges in order that keeps adjacent edges sharing
- * a face, if possible */
- i = 0;
- bme = v->e;
- BMO_elem_flag_enable(bm, bme, BEVEL_FLAG);
- e = &bv->edges[0];
- e->e = bme;
- for (i = 0; i < ntot; i++) {
- if (i > 0) {
- /* find an unflagged edge bme2 that shares a face f with previous bme */
- found_shared_face = 0;
- unflagged_bme = NULL;
- BM_ITER_ELEM (bme2, &iter, v, BM_EDGES_OF_VERT) {
- if (BMO_elem_flag_test(bm, bme2, BEVEL_FLAG))
- continue;
- if (!unflagged_bme)
- unflagged_bme = bme2;
- BM_ITER_ELEM (f, &iter2, bme2, BM_FACES_OF_EDGE) {
- if (BM_face_edge_share_loop(f, bme)) {
- found_shared_face = 1;
- break;
- }
- }
- if (found_shared_face)
- break;
- }
- e = &bv->edges[i];
- if (found_shared_face) {
- e->e = bme2;
- e->fprev = f;
- bv->edges[i - 1].fnext = f;
- }
- else {
- e->e = unflagged_bme;
- }
- }
- bme = e->e;
- BMO_elem_flag_enable(bm, bme, BEVEL_FLAG);
- if (BMO_elem_flag_test(bm, bme, EDGE_SELECTED)) {
- e->isbev = 1;
- e->seg = bp->seg;
- }
- else {
- e->isbev = 0;
- e->seg = 0;
- }
- e->isrev = (bme->v2 == v);
- e->offset = e->isbev ? bp->offset : 0.0f;
- }
- /* find wrap-around shared face */
- BM_ITER_ELEM (f, &iter2, bme, BM_FACES_OF_EDGE) {
- if (BM_face_edge_share_loop(f, bv->edges[0].e)) {
- if (bv->edges[0].fnext == f)
- continue; /* if two shared faces, want the other one now */
- bv->edges[ntot - 1].fnext = f;
- bv->edges[0].fprev = f;
- break;
- }
- }
-
- /* remove BEVEL_FLAG now that we are finished with it*/
- for (i = 0; i < ntot; i++)
- BMO_elem_flag_disable(bm, bv->edges[i].e, BEVEL_FLAG);
-
- /* if edge array doesn't go CCW around vertex from average normal side,
- * reverse the array, being careful to reverse face pointers too */
- if (ntot > 1) {
- ccw_test_sum = 0;
- for (i = 0; i < ntot; i++)
- ccw_test_sum += bev_ccw_test(bv->edges[i].e, bv->edges[(i + 1) % ntot].e,
- bv->edges[i].fnext);
- if (ccw_test_sum < 0) {
- for (i = 0; i <= (ntot / 2) - 1; i++) {
- SWAP(EdgeHalf, bv->edges[i], bv->edges[ntot - i - 1]);
- SWAP(BMFace *, bv->edges[i].fprev, bv->edges[i].fnext);
- SWAP(BMFace *, bv->edges[ntot - i - 1].fprev, bv->edges[ntot - i - 1].fnext);
- }
- if (ntot % 2 == 1) {
- i = ntot / 2;
- SWAP(BMFace *, bv->edges[i].fprev, bv->edges[i].fnext);
- }
- }
- }
-
- for (i = 0; i < ntot; i++) {
- e = &bv->edges[i];
- e->next = &bv->edges[(i + 1) % ntot];
- e->prev = &bv->edges[(i + ntot - 1) % ntot];
- }
-
- build_boundary(bv);
- build_vmesh(bm, bv);
-}
-
-/* Face f has at least one beveled vertex. Rebuild f */
-static void rebuild_polygon(BMesh *bm, BevelParams *bp, BMFace *f)
-{
- BMIter liter;
- BMLoop *l, *lprev;
- BevVert *bv;
- BoundVert *v, *vstart, *vend;
- EdgeHalf *e, *eprev;
- VMesh *vm;
- int i, k;
- BMVert *bmv;
- BMVert **vv = NULL;
- BLI_array_declare(vv);
-
- BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
- bv = find_bevvert(bp, l->v);
- if (bv) {
- lprev = l->prev;
- e = find_edge_half(bv, l->e);
- eprev = find_edge_half(bv, lprev->e);
- BLI_assert(e != NULL && eprev != NULL);
- vstart = eprev->leftv;
- if (e->isbev)
- vend = e->rightv;
- else
- vend = e->leftv;
- v = vstart;
- vm = bv->vmesh;
- BLI_array_append(vv, v->nv.v);
- while (v != vend) {
- if (vm->mesh_kind == M_NONE && v->ebev && v->ebev->seg > 1 && v->ebev != e && v->ebev != eprev) {
- /* case of 3rd face opposite a beveled edge, with no vmesh */
- i = v->index;
- e = v->ebev;
- for (k = 1; k < e->seg; k++) {
- bmv = mesh_vert(vm, i, 0, k)->v;
- BLI_array_append(vv, bmv);
- }
- }
- v = v->prev;
- BLI_array_append(vv, v->nv.v);
- }
- }
- else {
- BLI_array_append(vv, l->v);
- }
- }
- bev_create_ngon(bm, vv, BLI_array_count(vv), f);
- BLI_array_free(vv);
-}
-
-/* All polygons touching v need rebuilding because beveling v has made new vertices */
-static void bevel_rebuild_existing_polygons(BMesh *bm, BevelParams *bp, BMVert *v)
-{
- BMFace *f;
- BMIter iter;
-
- /* TODO: don't iterate through all faces, but just local geometry around v */
- BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
- BMLoop *l = f->l_first;
- do {
- if (l->v == v) {
- rebuild_polygon(bm, bp, f);
- BM_face_kill(bm, f);
- }
- l = l->next;
- } while (l != f->l_first);
- }
-}
-
-
-
-/*
- * Build the polygons along the selected Edge
- */
-static void bevel_build_edge_polygons(BMesh *bm, BevelParams *bp, BMEdge *bme)
-{
- BevVert *bv1, *bv2;
- BMVert *bmv1, *bmv2, *bmv3, *bmv4, *bmv1i, *bmv2i, *bmv3i, *bmv4i;
- VMesh *vm1, *vm2;
- EdgeHalf *e1, *e2;
- BMFace *f1, *f2, *f;
- int k, nseg, i1, i2;
-
- if (BM_edge_face_count(bme) != 2)
- return;
-
- bv1 = find_bevvert(bp, bme->v1);
- bv2 = find_bevvert(bp, bme->v2);
-
- BLI_assert(bv1 && bv2);
-
- e1 = find_edge_half(bv1, bme);
- e2 = find_edge_half(bv2, bme);
-
- BLI_assert(e1 && e2);
-
- /* v4 v3
- * \ /
- * e->v1 - e->v2
- * / \
- * v1 v2 */
-
- nseg = e1->seg;
- BLI_assert(nseg > 0 && nseg == e2->seg);
-
- bmv1 = e1->leftv->nv.v;
- bmv4 = e1->rightv->nv.v;
- bmv2 = e2->rightv->nv.v;
- bmv3 = e2->leftv->nv.v;
-
- BLI_assert(bmv1 && bmv2 && bmv3 && bmv4);
-
- f1 = boundvert_rep_face(e1->leftv);
- f2 = boundvert_rep_face(e1->rightv);
-
- if (nseg == 1) {
- bev_create_quad_tri(bm, bmv1, bmv2, bmv3, bmv4, f1);
- }
- else {
- i1 = e1->leftv->index;
- i2 = e2->leftv->index;
- vm1 = bv1->vmesh;
- vm2 = bv2->vmesh;
- bmv1i = bmv1;
- bmv2i = bmv2;
- for (k = 1; k <= nseg; k++) {
- bmv4i = mesh_vert(vm1, i1, 0, k)->v;
- bmv3i = mesh_vert(vm2, i2, 0, nseg - k)->v;
- f = (k <= nseg / 2 + (nseg % 2)) ? f1 : f2;
- bev_create_quad_tri(bm, bmv1i, bmv2i, bmv3i, bmv4i, f);
- bmv1i = bmv4i;
- bmv2i = bmv3i;
- }
- }
-}
-
-
-static void free_bevel_params(BevelParams *bp)
-{
- BevVert *bv;
- VMesh *vm;
- BoundVert *v, *vnext;
-
- for (bv = bp->vertList.first; bv; bv = bv->next) {
- MEM_freeN(bv->edges);
- vm = bv->vmesh;
- v = vm->boundstart;
- if (v) {
- do {
- vnext = v->next;
- MEM_freeN(v);
- v = vnext;
- } while (v != vm->boundstart);
- }
- if (vm->mesh)
- MEM_freeN(vm->mesh);
- MEM_freeN(vm);
- }
- BLI_freelistN(&bp->vertList);
-}
-
void bmo_bevel_exec(BMesh *bm, BMOperator *op)
{
- BMOIter siter;
- BMVert *v;
- BMEdge *e;
- BevelParams bp;
-
- bp.offset = BMO_slot_float_get(op, "offset");
- bp.op = op;
- bp.seg = BMO_slot_int_get(op, "segments");
-
- if (bp.offset > 0) {
- bp.vertList.first = bp.vertList.last = NULL;
-
- /* The analysis of the input vertices and execution additional constructions */
- BMO_ITER (v, &siter, bm, op, "geom", BM_VERT) {
- bevel_vert_construct(bm, &bp, op, v);
- }
- /* Build polygons for edges */
- BMO_ITER (e, &siter, bm, op, "geom", BM_EDGE) {
- bevel_build_edge_polygons(bm, &bp, e);
- }
-
- BMO_ITER (v, &siter, bm, op, "geom", BM_VERT) {
- bevel_rebuild_existing_polygons(bm, &bp, v);
- }
-
- BMO_ITER (v, &siter, bm, op, "geom", BM_VERT) {
- if (find_bevvert(&bp, v))
- BM_vert_kill(bm, v);
- }
- free_bevel_params(&bp);
- }
-
-}
-
-#else
-#define BEVEL_FLAG 1
-#define BEVEL_DEL 2
-#define FACE_NEW 4
-#define EDGE_OLD 8
-#define FACE_OLD 16
-#define VERT_OLD 32
-#define FACE_SPAN 64
-#define FACE_HOLE 128
-
-typedef struct LoopTag {
- BMVert *newv;
-} LoopTag;
-
-typedef struct EdgeTag {
- BMVert *newv1, *newv2;
-} EdgeTag;
-
-static void calc_corner_co(BMLoop *l, const float fac, float r_co[3],
- const short do_dist, const short do_even)
-{
- float no[3], l_vec_prev[3], l_vec_next[3], l_co_prev[3], l_co[3], l_co_next[3], co_ofs[3];
- int is_concave;
-
- /* first get the prev/next verts */
- if (l->f->len > 2) {
- copy_v3_v3(l_co_prev, l->prev->v->co);
- copy_v3_v3(l_co, l->v->co);
- copy_v3_v3(l_co_next, l->next->v->co);
-
- /* calculate normal */
- sub_v3_v3v3(l_vec_prev, l_co_prev, l_co);
- sub_v3_v3v3(l_vec_next, l_co_next, l_co);
-
- cross_v3_v3v3(no, l_vec_prev, l_vec_next);
- is_concave = dot_v3v3(no, l->f->no) > 0.0f;
- }
- else {
- BMIter iter;
- BMLoop *l2;
- float up[3] = {0.0f, 0.0f, 1.0f};
-
- copy_v3_v3(l_co_prev, l->prev->v->co);
- copy_v3_v3(l_co, l->v->co);
-
- BM_ITER_ELEM (l2, &iter, l->v, BM_LOOPS_OF_VERT) {
- if (l2->f != l->f) {
- copy_v3_v3(l_co_next, BM_edge_other_vert(l2->e, l2->next->v)->co);
- break;
- }
- }
-
- sub_v3_v3v3(l_vec_prev, l_co_prev, l_co);
- sub_v3_v3v3(l_vec_next, l_co_next, l_co);
-
- cross_v3_v3v3(no, l_vec_prev, l_vec_next);
- if (dot_v3v3(no, no) == 0.0f) {
- no[0] = no[1] = 0.0f; no[2] = -1.0f;
- }
-
- is_concave = dot_v3v3(no, up) < 0.0f;
- }
-
-
- /* now calculate the new location */
- if (do_dist) { /* treat 'fac' as distance */
-
- normalize_v3(l_vec_prev);
- normalize_v3(l_vec_next);
-
- add_v3_v3v3(co_ofs, l_vec_prev, l_vec_next);
- if (UNLIKELY(normalize_v3(co_ofs) == 0.0f)) { /* edges form a straight line */
- cross_v3_v3v3(co_ofs, l_vec_prev, l->f->no);
- }
+ const float offset = BMO_slot_float_get(op->slots_in, "offset");
+ const int seg = BMO_slot_int_get(op->slots_in, "segments");
- if (do_even) {
- negate_v3(l_vec_next);
- mul_v3_fl(co_ofs, fac * shell_angle_to_dist(0.5f * angle_normalized_v3v3(l_vec_prev, l_vec_next)));
- /* negate_v3(l_vec_next); */ /* no need unless we use again */
- }
- else {
- mul_v3_fl(co_ofs, fac);
- }
- }
- else { /* treat as 'fac' as a factor (0 - 1) */
-
- /* not strictly necessary, balance vectors
- * so the longer edge doesn't skew the result,
- * gives nicer, move even output.
- *
- * Use the minimum rather then the middle value so skinny faces don't flip along the short axis */
- float min_fac = min_ff(normalize_v3(l_vec_prev), normalize_v3(l_vec_next));
- float angle;
-
- if (do_even) {
- negate_v3(l_vec_next);
- angle = angle_normalized_v3v3(l_vec_prev, l_vec_next);
- negate_v3(l_vec_next); /* no need unless we use again */
- }
- else {
- angle = 0.0f;
- }
-
- mul_v3_fl(l_vec_prev, min_fac);
- mul_v3_fl(l_vec_next, min_fac);
-
- add_v3_v3v3(co_ofs, l_vec_prev, l_vec_next);
-
- if (UNLIKELY(is_zero_v3(co_ofs))) {
- cross_v3_v3v3(co_ofs, l_vec_prev, l->f->no);
- normalize_v3(co_ofs);
- mul_v3_fl(co_ofs, min_fac);
- }
-
- /* done */
- if (do_even) {
- mul_v3_fl(co_ofs, (fac * 0.5f) * shell_angle_to_dist(0.5f * angle));
- }
- else {
- mul_v3_fl(co_ofs, fac * 0.5f);
- }
- }
-
- /* apply delta vec */
- if (is_concave)
- negate_v3(co_ofs);
-
- add_v3_v3v3(r_co, co_ofs, l->v->co);
-}
-
-
-#define ETAG_SET(e, v, nv) ( \
- (v) == (e)->v1 ? \
- (etags[BM_elem_index_get((e))].newv1 = (nv)) : \
- (etags[BM_elem_index_get((e))].newv2 = (nv)) \
- )
-
-#define ETAG_GET(e, v) ( \
- (v) == (e)->v1 ? \
- (etags[BM_elem_index_get((e))].newv1) : \
- (etags[BM_elem_index_get((e))].newv2) \
- )
-
-void bmo_bevel_exec(BMesh *bm, BMOperator *op)
-{
- BMOIter siter;
- BMIter iter;
- BMEdge *e;
- BMVert *v;
- BMFace **faces = NULL, *f;
- LoopTag *tags = NULL, *tag;
- EdgeTag *etags = NULL;
- BMVert **verts = NULL;
- BMEdge **edges = NULL;
- BLI_array_declare(faces);
- BLI_array_declare(tags);
- BLI_array_declare(etags);
- BLI_array_declare(verts);
- BLI_array_declare(edges);
- SmallHash hash;
- float fac = BMO_slot_float_get(op, "percent");
- const short do_even = BMO_slot_bool_get(op, "use_even");
- const short do_dist = BMO_slot_bool_get(op, "use_dist");
- int i, li, has_elens, HasMDisps = CustomData_has_layer(&bm->ldata, CD_MDISPS);
-
- has_elens = CustomData_has_layer(&bm->edata, CD_PROP_FLT) && BMO_slot_bool_get(op, "use_lengths");
- if (has_elens) {
- li = BMO_slot_int_get(op, "lengthlayer");
- }
-
- BLI_smallhash_init(&hash);
-
- BMO_ITER (e, &siter, bm, op, "geom", BM_EDGE) {
- BMO_elem_flag_enable(bm, e, BEVEL_FLAG | BEVEL_DEL);
- BMO_elem_flag_enable(bm, e->v1, BEVEL_FLAG | BEVEL_DEL);
- BMO_elem_flag_enable(bm, e->v2, BEVEL_FLAG | BEVEL_DEL);
-
- if (BM_edge_face_count(e) < 2) {
- BMO_elem_flag_disable(bm, e, BEVEL_DEL);
- BMO_elem_flag_disable(bm, e->v1, BEVEL_DEL);
- BMO_elem_flag_disable(bm, e->v2, BEVEL_DEL);
- }
-#if 0
- if (BM_edge_face_count(e) == 0) {
- BMVert *verts[2] = {e->v1, e->v2};
- BMEdge *edges[2] = {e, BM_edge_create(bm, e->v1, e->v2, e, 0)};
-
- BMO_elem_flag_enable(bm, edges[1], BEVEL_FLAG);
- BM_face_create(bm, verts, edges, 2, FALSE);
- }
-#endif
- }
-
- BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
- BMO_elem_flag_enable(bm, v, VERT_OLD);
- }
-
-#if 0
- /* a bit of cleaner code that, alas, doens't work. */
- /* build edge tag */
- BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
- if (BMO_elem_flag_test(bm, e->v1, BEVEL_FLAG) || BMO_elem_flag_test(bm, e->v2, BEVEL_FLAG)) {
- BMIter liter;
- BMLoop *l;
-
- if (!BMO_elem_flag_test(bm, e, EDGE_OLD)) {
- BM_elem_index_set(e, BLI_array_count(etags)); /* set_dirty! */
- BLI_array_grow_one(etags);
-
- BMO_elem_flag_enable(bm, e, EDGE_OLD);
- }
-
- BM_ITER_ELEM (l, &liter, e, BM_LOOPS_OF_EDGE) {
- BMLoop *l2;
- BMIter liter2;
-
- if (BMO_elem_flag_test(bm, l->f, BEVEL_FLAG))
- continue;
-
- BM_ITER_ELEM (l2, &liter2, l->f, BM_LOOPS_OF_FACE) {
- BM_elem_index_set(l2, BLI_array_count(tags)); /* set_loop */
- BLI_array_grow_one(tags);
-
- if (!BMO_elem_flag_test(bm, l2->e, EDGE_OLD)) {
- BM_elem_index_set(l2->e, BLI_array_count(etags)); /* set_dirty! */
- BLI_array_grow_one(etags);
-
- BMO_elem_flag_enable(bm, l2->e, EDGE_OLD);
- }
- }
-
- BMO_elem_flag_enable(bm, l->f, BEVEL_FLAG);
- BLI_array_append(faces, l->f);
- }
- }
- else {
- BM_elem_index_set(e, -1); /* set_dirty! */
- }
- }
-#endif
-
- /* create and assign looptag structure */
- BMO_ITER (e, &siter, bm, op, "geom", BM_EDGE) {
- BMLoop *l;
- BMIter liter;
-
- BMO_elem_flag_enable(bm, e->v1, BEVEL_FLAG | BEVEL_DEL);
- BMO_elem_flag_enable(bm, e->v2, BEVEL_FLAG | BEVEL_DEL);
-
- if (BM_edge_face_count(e) < 2) {
- BMO_elem_flag_disable(bm, e, BEVEL_DEL);
- BMO_elem_flag_disable(bm, e->v1, BEVEL_DEL);
- BMO_elem_flag_disable(bm, e->v2, BEVEL_DEL);
- }
-
- if (!BLI_smallhash_haskey(&hash, (intptr_t)e)) {
- BLI_array_grow_one(etags);
- BM_elem_index_set(e, BLI_array_count(etags) - 1); /* set_dirty! */
- BLI_smallhash_insert(&hash, (intptr_t)e, NULL);
- BMO_elem_flag_enable(bm, e, EDGE_OLD);
- }
-
- /* find all faces surrounding e->v1 and, e->v2 */
- for (i = 0; i < 2; i++) {
- BM_ITER_ELEM (l, &liter, i ? e->v2 : e->v1, BM_LOOPS_OF_VERT) {
- BMLoop *l2;
- BMIter liter2;
-
- /* see if we've already processed this loop's fac */
- if (BLI_smallhash_haskey(&hash, (intptr_t)l->f))
- continue;
-
- /* create tags for all loops in l-> */
- BM_ITER_ELEM (l2, &liter2, l->f, BM_LOOPS_OF_FACE) {
- BLI_array_grow_one(tags);
- BM_elem_index_set(l2, BLI_array_count(tags) - 1); /* set_loop */
-
- if (!BLI_smallhash_haskey(&hash, (intptr_t)l2->e)) {
- BLI_array_grow_one(etags);
- BM_elem_index_set(l2->e, BLI_array_count(etags) - 1); /* set_dirty! */
- BLI_smallhash_insert(&hash, (intptr_t)l2->e, NULL);
- BMO_elem_flag_enable(bm, l2->e, EDGE_OLD);
- }
- }
-
- BLI_smallhash_insert(&hash, (intptr_t)l->f, NULL);
- BMO_elem_flag_enable(bm, l->f, BEVEL_FLAG);
- BLI_array_append(faces, l->f);
- }
- }
- }
-
- bm->elem_index_dirty |= BM_EDGE;
-
- BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
- BMIter eiter;
-
- if (!BMO_elem_flag_test(bm, v, BEVEL_FLAG))
- continue;
-
- BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
- if (!BMO_elem_flag_test(bm, e, BEVEL_FLAG) && !ETAG_GET(e, v)) {
- BMVert *v2;
- float co[3];
-
- v2 = BM_edge_other_vert(e, v);
- sub_v3_v3v3(co, v2->co, v->co);
- if (has_elens) {
- float elen = *(float *)CustomData_bmesh_get_n(&bm->edata, e->head.data, CD_PROP_FLT, li);
-
- normalize_v3(co);
- mul_v3_fl(co, elen);
- }
-
- mul_v3_fl(co, fac);
- add_v3_v3(co, v->co);
-
- v2 = BM_vert_create(bm, co, v);
- ETAG_SET(e, v, v2);
- }
- }
- }
-
- for (i = 0; i < BLI_array_count(faces); i++) {
- BMLoop *l;
- BMIter liter;
-
- BMO_elem_flag_enable(bm, faces[i], FACE_OLD);
-
- BM_ITER_ELEM (l, &liter, faces[i], BM_LOOPS_OF_FACE) {
- float co[3];
-
- if (BMO_elem_flag_test(bm, l->e, BEVEL_FLAG)) {
- if (BMO_elem_flag_test(bm, l->prev->e, BEVEL_FLAG)) {
- tag = tags + BM_elem_index_get(l);
- calc_corner_co(l, fac, co, do_dist, do_even);
- tag->newv = BM_vert_create(bm, co, l->v);
- }
- else {
- tag = tags + BM_elem_index_get(l);
- tag->newv = ETAG_GET(l->prev->e, l->v);
-
- if (!tag->newv) {
- sub_v3_v3v3(co, l->prev->v->co, l->v->co);
- if (has_elens) {
- float elen = *(float *)CustomData_bmesh_get_n(&bm->edata, l->prev->e->head.data,
- CD_PROP_FLT, li);
-
- normalize_v3(co);
- mul_v3_fl(co, elen);
- }
-
- mul_v3_fl(co, fac);
- add_v3_v3(co, l->v->co);
-
- tag->newv = BM_vert_create(bm, co, l->v);
-
- ETAG_SET(l->prev->e, l->v, tag->newv);
- }
- }
- }
- else if (BMO_elem_flag_test(bm, l->v, BEVEL_FLAG)) {
- tag = tags + BM_elem_index_get(l);
- tag->newv = ETAG_GET(l->e, l->v);
-
- if (!tag->newv) {
- sub_v3_v3v3(co, l->next->v->co, l->v->co);
- if (has_elens) {
- float elen = *(float *)CustomData_bmesh_get_n(&bm->edata, l->e->head.data, CD_PROP_FLT, li);
-
- normalize_v3(co);
- mul_v3_fl(co, elen);
- }
-
- mul_v3_fl(co, fac);
- add_v3_v3(co, l->v->co);
-
- tag = tags + BM_elem_index_get(l);
- tag->newv = BM_vert_create(bm, co, l->v);
-
- ETAG_SET(l->e, l->v, tag->newv);
- }
- }
- else {
- tag = tags + BM_elem_index_get(l);
- tag->newv = l->v;
- BMO_elem_flag_disable(bm, l->v, BEVEL_DEL);
- }
- }
- }
-
- /* create new faces inset from original face */
- for (i = 0; i < BLI_array_count(faces); i++) {
- BMLoop *l;
- BMIter liter;
- BMFace *f;
- BMVert *lastv = NULL, *firstv = NULL;
-
- BMO_elem_flag_enable(bm, faces[i], BEVEL_DEL);
-
- BLI_array_empty(verts);
- BLI_array_empty(edges);
-
- BM_ITER_ELEM (l, &liter, faces[i], BM_LOOPS_OF_FACE) {
- BMVert *v2;
-
- tag = tags + BM_elem_index_get(l);
- BLI_array_append(verts, tag->newv);
-
- if (!firstv)
- firstv = tag->newv;
-
- if (lastv) {
- e = BM_edge_create(bm, lastv, tag->newv, l->e, TRUE);
- BM_elem_attrs_copy(bm, bm, l->prev->e, e);
- BLI_array_append(edges, e);
- }
- lastv = tag->newv;
-
- v2 = ETAG_GET(l->e, l->next->v);
-
- tag = &tags[BM_elem_index_get(l->next)];
- if (!BMO_elem_flag_test(bm, l->e, BEVEL_FLAG) && v2 && v2 != tag->newv) {
- BLI_array_append(verts, v2);
-
- e = BM_edge_create(bm, lastv, v2, l->e, TRUE);
- BM_elem_attrs_copy(bm, bm, l->e, e);
-
- BLI_array_append(edges, e);
- lastv = v2;
- }
- }
-
- e = BM_edge_create(bm, firstv, lastv, BM_FACE_FIRST_LOOP(faces[i])->e, TRUE);
- if (BM_FACE_FIRST_LOOP(faces[i])->prev->e != e) {
- BM_elem_attrs_copy(bm, bm, BM_FACE_FIRST_LOOP(faces[i])->prev->e, e);
- }
- BLI_array_append(edges, e);
-
- f = BM_face_create_ngon(bm, verts[0], verts[1], edges, BLI_array_count(edges), FALSE);
- if (UNLIKELY(f == NULL)) {
- printf("%s: could not make face!\n", __func__);
- continue;
- }
-
- BMO_elem_flag_enable(bm, f, FACE_NEW);
- }
-
- for (i = 0; i < BLI_array_count(faces); i++) {
- BMLoop *l;
- BMIter liter;
- int j;
-
- /* create quad spans between split edge */
- BM_ITER_ELEM (l, &liter, faces[i], BM_LOOPS_OF_FACE) {
- BMVert *v1 = NULL, *v2 = NULL, *v3 = NULL, *v4 = NULL;
-
- if (!BMO_elem_flag_test(bm, l->e, BEVEL_FLAG))
- continue;
-
- v1 = tags[BM_elem_index_get(l)].newv;
- v2 = tags[BM_elem_index_get(l->next)].newv;
- if (l->radial_next != l) {
- v3 = tags[BM_elem_index_get(l->radial_next)].newv;
- if (l->radial_next->next->v == l->next->v) {
- v4 = v3;
- v3 = tags[BM_elem_index_get(l->radial_next->next)].newv;
- }
- else {
- v4 = tags[BM_elem_index_get(l->radial_next->next)].newv;
- }
- }
- else {
- /* the loop is on a boundar */
- v3 = l->next->v;
- v4 = l->v;
-
- for (j = 0; j < 2; j++) {
- BMIter eiter;
- BMVert *v = j ? v4 : v3;
-
- BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
- if (!BM_vert_in_edge(e, v3) || !BM_vert_in_edge(e, v4))
- continue;
-
- if (!BMO_elem_flag_test(bm, e, BEVEL_FLAG) && BMO_elem_flag_test(bm, e, EDGE_OLD)) {
- BMVert *vv;
-
- vv = ETAG_GET(e, v);
- if (!vv || BMO_elem_flag_test(bm, vv, BEVEL_FLAG))
- continue;
-
- if (j) {
- v1 = vv;
- }
- else {
- v2 = vv;
- }
- break;
- }
- }
- }
-
- BMO_elem_flag_disable(bm, v3, BEVEL_DEL);
- BMO_elem_flag_disable(bm, v4, BEVEL_DEL);
- }
-
- if (v1 != v2 && v2 != v3 && v3 != v4) {
- BMIter liter2;
- BMLoop *l2, *l3;
- BMEdge *e1, *e2;
- float d1, d2, *d3;
-
- f = BM_face_create_quad_tri(bm, v4, v3, v2, v1, l->f, TRUE);
-
- e1 = BM_edge_exists(v4, v3);
- e2 = BM_edge_exists(v2, v1);
- BM_elem_attrs_copy(bm, bm, l->e, e1);
- BM_elem_attrs_copy(bm, bm, l->e, e2);
-
- /* set edge lengths of cross edges as the average of the cross edges they're based o */
- if (has_elens) {
- /* angle happens not to be used. why? - not sure it just isn't - campbell.
- * leave this in in case we need to use it later */
-#if 0
- float ang;
-#endif
- e1 = BM_edge_exists(v1, v4);
- e2 = BM_edge_exists(v2, v3);
-
- if (l->radial_next->v == l->v) {
- l2 = l->radial_next->prev;
- l3 = l->radial_next->next;
- }
- else {
- l2 = l->radial_next->next;
- l3 = l->radial_next->prev;
- }
-
- d3 = CustomData_bmesh_get_n(&bm->edata, e1->head.data, CD_PROP_FLT, li);
- d1 = *(float *)CustomData_bmesh_get_n(&bm->edata, l->prev->e->head.data, CD_PROP_FLT, li);
- d2 = *(float *)CustomData_bmesh_get_n(&bm->edata, l2->e->head.data, CD_PROP_FLT, li);
-#if 0
- ang = angle_v3v3v3(l->prev->v->co, l->v->co, BM_edge_other_vert(l2->e, l->v)->co);
-#endif
- *d3 = (d1 + d2) * 0.5f;
-
- d3 = CustomData_bmesh_get_n(&bm->edata, e2->head.data, CD_PROP_FLT, li);
- d1 = *(float *)CustomData_bmesh_get_n(&bm->edata, l->next->e->head.data, CD_PROP_FLT, li);
- d2 = *(float *)CustomData_bmesh_get_n(&bm->edata, l3->e->head.data, CD_PROP_FLT, li);
-#if 0
- ang = angle_v3v3v3(BM_edge_other_vert(l->next->e, l->next->v)->co, l->next->v->co,
- BM_edge_other_vert(l3->e, l->next->v)->co);
-#endif
- *d3 = (d1 + d2) * 0.5f;
- }
-
- if (UNLIKELY(f == NULL)) {
- fprintf(stderr, "%s: face index out of range! (bmesh internal error)\n", __func__);
- continue;
- }
-
- BMO_elem_flag_enable(bm, f, FACE_NEW | FACE_SPAN);
-
- /* un-tag edges in f for deletio */
- BM_ITER_ELEM (l2, &liter2, f, BM_LOOPS_OF_FACE) {
- BMO_elem_flag_disable(bm, l2->e, BEVEL_DEL);
- }
- }
- else {
- f = NULL;
- }
- }
- }
-
- /* fill in holes at vertices */
- BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
- BMIter eiter;
- BMVert *vv, *vstart = NULL, *lastv = NULL;
- SmallHash tmphash;
- int rad, insorig = 0, err = 0;
+ if (offset > 0) {
+ BMOIter siter;
+ BMEdge *e;
+ BMVert *v;
- BLI_smallhash_init(&tmphash);
+ /* first flush 'geom' into flags, this makes it possible to check connected data,
+ * BM_FACE is cleared so we can put newly created faces into a bmesh slot. */
+ BM_mesh_elem_hflag_disable_all(bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_TAG, FALSE);
- if (!BMO_elem_flag_test(bm, v, BEVEL_FLAG))
- continue;
-
- BLI_array_empty(verts);
- BLI_array_empty(edges);
-
- BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
- BMIter liter;
- BMVert *v1 = NULL, *v2 = NULL;
- BMLoop *l;
-
- if (BM_edge_face_count(e) < 2)
- insorig = 1;
-
- if (BM_elem_index_get(e) == -1)
- continue;
-
- rad = 0;
- BM_ITER_ELEM (l, &liter, e, BM_LOOPS_OF_EDGE) {
- if (!BMO_elem_flag_test(bm, l->f, FACE_OLD))
- continue;
-
- rad++;
-
- tag = tags + BM_elem_index_get((l->v == v) ? l : l->next);
-
- if (!v1)
- v1 = tag->newv;
- else if (!v2)
- v2 = tag->newv;
- }
-
- if (rad < 2)
- insorig = 1;
-
- if (!v1)
- v1 = ETAG_GET(e, v);
- if (!v2 || v1 == v2)
- v2 = ETAG_GET(e, v);
-
- if (v1) {
- if (!BLI_smallhash_haskey(&tmphash, (intptr_t)v1)) {
- BLI_array_append(verts, v1);
- BLI_smallhash_insert(&tmphash, (intptr_t)v1, NULL);
- }
-
- if (v2 && v1 != v2 && !BLI_smallhash_haskey(&tmphash, (intptr_t)v2)) {
- BLI_array_append(verts, v2);
- BLI_smallhash_insert(&tmphash, (intptr_t)v2, NULL);
- }
- }
- }
-
- if (!BLI_array_count(verts))
- continue;
-
- if (insorig) {
- BLI_array_append(verts, v);
- BLI_smallhash_insert(&tmphash, (intptr_t)v, NULL);
+ BMO_ITER (v, &siter, op->slots_in, "geom", BM_VERT) {
+ BM_elem_flag_enable(v, BM_ELEM_TAG);
}
-
- /* find edges that exist between vertices in verts. this is basically
- * a topological walk of the edges connecting them */
- vstart = vstart ? vstart : verts[0];
- vv = vstart;
- do {
- BM_ITER_ELEM (e, &eiter, vv, BM_EDGES_OF_VERT) {
- BMVert *vv2 = BM_edge_other_vert(e, vv);
-
- if (vv2 != lastv && BLI_smallhash_haskey(&tmphash, (intptr_t)vv2)) {
- /* if we've go over the same vert twice, break out of outer loop */
- if (BLI_smallhash_lookup(&tmphash, (intptr_t)vv2) != NULL) {
- e = NULL;
- err = 1;
- break;
- }
-
- /* use self pointer as ta */
- BLI_smallhash_remove(&tmphash, (intptr_t)vv2);
- BLI_smallhash_insert(&tmphash, (intptr_t)vv2, vv2);
-
- lastv = vv;
- BLI_array_append(edges, e);
- vv = vv2;
- break;
- }
- }
- if (e == NULL) {
- break;
- }
- } while (vv != vstart);
-
- if (err) {
- continue;
- }
-
- /* there may not be a complete loop of edges, so start again and make
- * final edge afterwards. in this case, the previous loop worked to
- * find one of the two edges at the extremes. */
- if (vv != vstart) {
- /* undo previous taggin */
- for (i = 0; i < BLI_array_count(verts); i++) {
- BLI_smallhash_remove(&tmphash, (intptr_t)verts[i]);
- BLI_smallhash_insert(&tmphash, (intptr_t)verts[i], NULL);
- }
-
- vstart = vv;
- lastv = NULL;
- BLI_array_empty(edges);
- do {
- BM_ITER_ELEM (e, &eiter, vv, BM_EDGES_OF_VERT) {
- BMVert *vv2 = BM_edge_other_vert(e, vv);
-
- if (vv2 != lastv && BLI_smallhash_haskey(&tmphash, (intptr_t)vv2)) {
- /* if we've go over the same vert twice, break out of outer loo */
- if (BLI_smallhash_lookup(&tmphash, (intptr_t)vv2) != NULL) {
- e = NULL;
- err = 1;
- break;
- }
-
- /* use self pointer as ta */
- BLI_smallhash_remove(&tmphash, (intptr_t)vv2);
- BLI_smallhash_insert(&tmphash, (intptr_t)vv2, vv2);
-
- lastv = vv;
- BLI_array_append(edges, e);
- vv = vv2;
- break;
- }
- }
- if (e == NULL)
- break;
- } while (vv != vstart);
-
- if (!err) {
- e = BM_edge_create(bm, vv, vstart, NULL, TRUE);
- BLI_array_append(edges, e);
- }
- }
-
- if (err)
- continue;
-
- if (BLI_array_count(edges) >= 3) {
- BMFace *f;
-
- if (BM_face_exists(bm, verts, BLI_array_count(verts), &f))
- continue;
-
- f = BM_face_create_ngon(bm, lastv, vstart, edges, BLI_array_count(edges), FALSE);
- if (UNLIKELY(f == NULL)) {
- fprintf(stderr, "%s: in bevel vert fill! (bmesh internal error)\n", __func__);
- }
- else {
- BMO_elem_flag_enable(bm, f, FACE_NEW | FACE_HOLE);
+ BMO_ITER (e, &siter, op->slots_in, "geom", BM_EDGE) {
+ if (BM_edge_is_manifold(e)) {
+ BM_elem_flag_enable(e, BM_ELEM_TAG);
}
}
- BLI_smallhash_release(&tmphash);
- }
-
- /* copy over customdat */
- for (i = 0; i < BLI_array_count(faces); i++) {
- BMLoop *l;
- BMIter liter;
- BMFace *f = faces[i];
-
- BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
- BMLoop *l2;
- BMIter liter2;
-
- tag = tags + BM_elem_index_get(l);
- if (!tag->newv)
- continue;
-
- BM_ITER_ELEM (l2, &liter2, tag->newv, BM_LOOPS_OF_VERT) {
- if (!BMO_elem_flag_test(bm, l2->f, FACE_NEW) || (l2->v != tag->newv && l2->v != l->v))
- continue;
-
- if (tag->newv != l->v || HasMDisps) {
- BM_elem_attrs_copy(bm, bm, l->f, l2->f);
- BM_loop_interp_from_face(bm, l2, l->f, TRUE, TRUE);
- }
- else {
- BM_elem_attrs_copy(bm, bm, l->f, l2->f);
- BM_elem_attrs_copy(bm, bm, l, l2);
- }
-
- if (HasMDisps) {
- BMLoop *l3;
- BMIter liter3;
-
- BM_ITER_ELEM (l3, &liter3, l2->f, BM_LOOPS_OF_FACE) {
- BM_loop_interp_multires(bm, l3, l->f);
- }
- }
- }
- }
- }
-
- /* handle vertices along boundary edge */
- BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
- if (BMO_elem_flag_test(bm, v, VERT_OLD) &&
- BMO_elem_flag_test(bm, v, BEVEL_FLAG) &&
- !BMO_elem_flag_test(bm, v, BEVEL_DEL))
- {
- BMLoop *l;
- BMLoop *lorig = NULL;
- BMIter liter;
-
- BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) {
- // BMIter liter2;
- // BMLoop *l2 = l->v == v ? l : l->next, *l3;
-
- if (BMO_elem_flag_test(bm, l->f, FACE_OLD)) {
- lorig = l;
- break;
- }
- }
-
- if (!lorig)
- continue;
-
- BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) {
- BMLoop *l2 = l->v == v ? l : l->next;
-
- BM_elem_attrs_copy(bm, bm, lorig->f, l2->f);
- BM_elem_attrs_copy(bm, bm, lorig, l2);
- }
- }
- }
-#if 0
- /* clean up any remaining 2-edged face */
- BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
- if (f->len == 2) {
- BMFace *faces[2] = {f, BM_FACE_FIRST_LOOP(f)->radial_next->f};
-
- if (faces[0] == faces[1])
- BM_face_kill(bm, f);
- else
- BM_faces_join(bm, faces, 2);
- }
- }
-#endif
- BMO_op_callf(bm, op->flag, "delete geom=%fv context=%i", BEVEL_DEL, DEL_VERTS);
+ BM_mesh_bevel(bm, offset, seg);
- /* clean up any edges that might not get properly delete */
- BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
- if (BMO_elem_flag_test(bm, e, EDGE_OLD) && !e->l)
- BMO_elem_flag_enable(bm, e, BEVEL_DEL);
+ BMO_slot_buffer_from_enabled_hflag(bm, op, op->slots_out, "faces.out", BM_FACE, BM_ELEM_TAG);
}
-
- BMO_op_callf(bm, op->flag, "delete geom=%fe context=%i", BEVEL_DEL, DEL_EDGES);
- BMO_op_callf(bm, op->flag, "delete geom=%ff context=%i", BEVEL_DEL, DEL_FACES);
-
- BLI_smallhash_release(&hash);
- BLI_array_free(tags);
- BLI_array_free(etags);
- BLI_array_free(verts);
- BLI_array_free(edges);
- BLI_array_free(faces);
-
- BMO_slot_buffer_from_enabled_flag(bm, op, "face_spans", BM_FACE, FACE_SPAN);
- BMO_slot_buffer_from_enabled_flag(bm, op, "face_holes", BM_FACE, FACE_HOLE);
}
-#endif /* NEW_BEVEL */
diff --git a/source/blender/bmesh/operators/bmo_connect.c b/source/blender/bmesh/operators/bmo_connect.c
index ebd848ff8b2..b7bb57bb19d 100644
--- a/source/blender/bmesh/operators/bmo_connect.c
+++ b/source/blender/bmesh/operators/bmo_connect.c
@@ -52,7 +52,7 @@ void bmo_connect_verts_exec(BMesh *bm, BMOperator *op)
BLI_array_declare(verts_pair);
int i;
- BMO_slot_buffer_flag_enable(bm, op, "verts", BM_VERT, VERT_INPUT);
+ BMO_slot_buffer_flag_enable(bm, op->slots_in, "verts", BM_VERT, VERT_INPUT);
for (f = BM_iter_new(&iter, bm, BM_FACES_OF_MESH, NULL); f; f = BM_iter_step(&iter)) {
BLI_array_empty(loops_split);
@@ -117,7 +117,7 @@ void bmo_connect_verts_exec(BMesh *bm, BMOperator *op)
}
}
- BMO_slot_buffer_from_enabled_flag(bm, op, "edgeout", BM_EDGE, EDGE_OUT);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "edges.out", BM_EDGE, EDGE_OUT);
BLI_array_free(loops_split);
BLI_array_free(verts_pair);
@@ -219,12 +219,12 @@ void bmo_bridge_loops_exec(BMesh *bm, BMOperator *op)
int c = 0, cl1 = 0, cl2 = 0;
/* merge-bridge support */
- const int use_merge = BMO_slot_bool_get(op, "use_merge");
- const float merge_factor = BMO_slot_float_get(op, "merge_factor");
+ const int use_merge = BMO_slot_bool_get(op->slots_in, "use_merge");
+ const float merge_factor = BMO_slot_float_get(op->slots_in, "merge_factor");
- BMO_slot_buffer_flag_enable(bm, op, "edges", BM_EDGE, EDGE_MARK);
+ BMO_slot_buffer_flag_enable(bm, op->slots_in, "edges", BM_EDGE, EDGE_MARK);
- BMO_ITER (e, &siter, bm, op, "edges", BM_EDGE) {
+ BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) {
if (!BMO_elem_flag_test(bm, e, EDGE_DONE)) {
BMVert *v, *ov;
/* BMEdge *e2, *e3, *oe = e; */ /* UNUSED */
@@ -523,7 +523,7 @@ void bmo_bridge_loops_exec(BMesh *bm, BMOperator *op)
}
}
- BMO_slot_buffer_from_enabled_flag(bm, op, "faceout", BM_FACE, FACE_OUT);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "faces.out", BM_FACE, FACE_OUT);
cleanup:
BLI_array_free(ee1);
diff --git a/source/blender/bmesh/operators/bmo_create.c b/source/blender/bmesh/operators/bmo_create.c
index 093f567d995..987aa8cdf99 100644
--- a/source/blender/bmesh/operators/bmo_create.c
+++ b/source/blender/bmesh/operators/bmo_create.c
@@ -168,7 +168,7 @@ static void rotsys_reverse(BMEdge *UNUSED(e), BMVert *v, EdgeData *edata, VertDa
BMEdge **edges = NULL;
BMEdge *e_first;
BMEdge *e;
- BLI_array_staticdeclare(edges, BM_NGON_STACK_SIZE);
+ BLI_array_staticdeclare(edges, BM_DEFAULT_NGON_STACK_SIZE);
int i, totedge;
e = e_first = vdata[BM_elem_index_get(v)].e;
@@ -359,10 +359,10 @@ static void init_rotsys(BMesh *bm, EdgeData *edata, VertData *vdata)
BMIter iter;
BMEdge *e;
BMEdge **edges = NULL;
- BLI_array_staticdeclare(edges, BM_NGON_STACK_SIZE);
+ BLI_array_staticdeclare(edges, BM_DEFAULT_NGON_STACK_SIZE);
BMVert *v;
/* BMVert **verts = NULL; */
- /* BLI_array_staticdeclare(verts, BM_NGON_STACK_SIZE); */ /* UNUSE */
+ /* BLI_array_staticdeclare(verts, BM_DEFAULT_NGON_STACK_SIZE); */ /* UNUSE */
int i;
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
@@ -741,7 +741,10 @@ static EPath *edge_find_shortest_path(BMesh *bm, BMOperator *op, BMEdge *edge, E
BMVert *startv;
BMVert *endv;
EPathNode *node;
- int i, use_restrict = BMO_slot_bool_get(op, "use_restrict");
+ int i;
+ const int use_restrict = BMO_slot_bool_get(op->slots_in, "use_restrict");
+ BMOpSlot *slot_restrict = BMO_slot_get(op->slots_in, "restrict");
+
startv = edata[BM_elem_index_get(edge)].ftag ? edge->v2 : edge->v1;
endv = edata[BM_elem_index_get(edge)].ftag ? edge->v1 : edge->v2;
@@ -769,7 +772,7 @@ static EPath *edge_find_shortest_path(BMesh *bm, BMOperator *op, BMEdge *edge, E
verts[i] = node->v;
}
- if (BM_face_exists(bm, verts, i, &f)) {
+ if (BM_face_exists(verts, i, &f)) {
if (!BMO_elem_flag_test(bm, f, FACE_IGNORE)) {
BLI_ghash_remove(gh, endv, NULL, NULL);
continue;
@@ -806,12 +809,13 @@ static EPath *edge_find_shortest_path(BMesh *bm, BMOperator *op, BMEdge *edge, E
continue;
}
- if (use_restrict && BMO_slot_map_contains(bm, op, "restrict", e)) {
- int group = BMO_slot_map_int_get(bm, op, "restrict", e);
-
- if (!(group & path->group)) {
- v2 = NULL;
- continue;
+ if (use_restrict) {
+ int *group = (int *)BMO_slot_map_data_get(slot_restrict, e);
+ if (group) {
+ if (!(*group & path->group)) {
+ v2 = NULL;
+ continue;
+ }
}
}
@@ -895,12 +899,14 @@ void bmo_edgenet_fill_exec(BMesh *bm, BMOperator *op)
BMEdge **edges = NULL;
PathBase *pathbase;
BLI_array_declare(edges);
- int use_restrict = BMO_slot_bool_get(op, "use_restrict");
- int use_fill_check = BMO_slot_bool_get(op, "use_fill_check");
- const short mat_nr = BMO_slot_int_get(op, "mat_nr");
- const short use_smooth = BMO_slot_bool_get(op, "use_smooth");
+ int use_restrict = BMO_slot_bool_get(op->slots_in, "use_restrict");
+ int use_fill_check = BMO_slot_bool_get(op->slots_in, "use_fill_check");
+ const short mat_nr = BMO_slot_int_get(op->slots_in, "mat_nr");
+ const short use_smooth = BMO_slot_bool_get(op->slots_in, "use_smooth");
int i, j, group = 0;
unsigned int winding[2]; /* accumulte winding directions for each edge which has a face */
+ BMOpSlot *slot_restrict = BMO_slot_get(op->slots_in, "restrict");
+ BMOpSlot *slot_face_groupmap_out = BMO_slot_get(op->slots_out, "face_groupmap.out");
if (!bm->totvert || !bm->totedge)
return;
@@ -910,8 +916,8 @@ void bmo_edgenet_fill_exec(BMesh *bm, BMOperator *op)
edata = MEM_callocN(sizeof(EdgeData) * bm->totedge, "EdgeData");
vdata = MEM_callocN(sizeof(VertData) * bm->totvert, "VertData");
- BMO_slot_buffer_flag_enable(bm, op, "edges", BM_EDGE, EDGE_MARK);
- BMO_slot_buffer_flag_enable(bm, op, "excludefaces", BM_FACE, FACE_IGNORE);
+ BMO_slot_buffer_flag_enable(bm, op->slots_in, "edges", BM_EDGE, EDGE_MARK);
+ BMO_slot_buffer_flag_enable(bm, op->slots_in, "exclude_faces", BM_FACE, FACE_IGNORE);
BM_mesh_elem_index_ensure(bm, BM_VERT);
@@ -932,14 +938,14 @@ void bmo_edgenet_fill_exec(BMesh *bm, BMOperator *op)
bm->elem_index_dirty &= ~BM_EDGE;
init_rotsys(bm, edata, vdata);
-
+
while (1) {
edge = NULL;
group = 0;
- BMO_ITER (e, &siter, bm, op, "edges", BM_EDGE) {
+ BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) {
/* if restrict is on, only start on faces in the restrict map */
- if (use_restrict && !BMO_slot_map_contains(bm, op, "restrict", e))
+ if (use_restrict && !BMO_slot_map_contains(slot_restrict, e))
continue;
if (edata[BM_elem_index_get(e)].tag < 2) {
@@ -948,7 +954,7 @@ void bmo_edgenet_fill_exec(BMesh *bm, BMOperator *op)
if (use_restrict) {
int i = 0, j = 0, gi = 0;
- group = BMO_slot_map_int_get(bm, op, "restrict", e);
+ group = BMO_slot_map_int_get(slot_restrict, e);
for (i = 0; i < 30; i++) {
if (group & (1 << i)) {
@@ -1055,7 +1061,7 @@ void bmo_edgenet_fill_exec(BMesh *bm, BMOperator *op)
}
if (use_restrict) {
- BMO_slot_map_int_insert(bm, op, "faceout_groupmap", f, path->group);
+ BMO_slot_map_int_insert(op, slot_face_groupmap_out, f, path->group);
}
}
}
@@ -1063,7 +1069,7 @@ void bmo_edgenet_fill_exec(BMesh *bm, BMOperator *op)
edge_free_path(pathbase, path);
}
- BMO_slot_buffer_from_enabled_flag(bm, op, "faceout", BM_FACE, FACE_NEW);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "faces.out", BM_FACE, FACE_NEW);
BLI_array_free(edges);
BLI_array_free(verts);
@@ -1103,11 +1109,11 @@ void bmo_edgenet_prepare(BMesh *bm, BMOperator *op)
int ok = 1;
int i, count;
- BMO_slot_buffer_flag_enable(bm, op, "edges", BM_EDGE, EDGE_MARK);
+ BMO_slot_buffer_flag_enable(bm, op->slots_in, "edges", BM_EDGE, EDGE_MARK);
/* validate that each edge has at most one other tagged edge in the
* disk cycle around each of it's vertices */
- BMO_ITER (e, &siter, bm, op, "edges", BM_EDGE) {
+ BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) {
for (i = 0; i < 2; i++) {
count = BMO_vert_edge_flags_count(bm, i ? e->v2 : e->v1, EDGE_MARK);
if (count > 2) {
@@ -1129,7 +1135,7 @@ void bmo_edgenet_prepare(BMesh *bm, BMOperator *op)
/* find connected loops within the input edge */
count = 0;
while (1) {
- BMO_ITER (e, &siter, bm, op, "edges", BM_EDGE) {
+ BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) {
if (!BMO_elem_flag_test(bm, e, EDGE_VIS)) {
if (BMO_vert_edge_flags_count(bm, e->v1, EDGE_MARK) == 1 ||
BMO_vert_edge_flags_count(bm, e->v2, EDGE_MARK) == 1)
@@ -1260,7 +1266,7 @@ void bmo_edgenet_prepare(BMesh *bm, BMOperator *op)
}
}
- BMO_slot_buffer_from_enabled_flag(bm, op, "edgeout", BM_EDGE, ELE_NEW);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "edges.out", BM_EDGE, ELE_NEW);
BLI_array_free(edges1);
BLI_array_free(edges2);
@@ -1280,11 +1286,11 @@ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op)
BMEdge *e;
BMFace *f;
int totv = 0, tote = 0, totf = 0, amount;
- const short mat_nr = BMO_slot_int_get(op, "mat_nr");
- const short use_smooth = BMO_slot_bool_get(op, "use_smooth");
+ const short mat_nr = BMO_slot_int_get(op->slots_in, "mat_nr");
+ const short use_smooth = BMO_slot_bool_get(op->slots_in, "use_smooth");
/* count number of each element type we were passe */
- BMO_ITER (h, &oiter, bm, op, "geom", BM_VERT | BM_EDGE | BM_FACE) {
+ BMO_ITER (h, &oiter, op->slots_in, "geom", BM_VERT | BM_EDGE | BM_FACE) {
switch (h->htype) {
case BM_VERT: totv++; break;
case BM_EDGE: tote++; break;
@@ -1318,7 +1324,7 @@ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op)
int ok = TRUE;
- BMO_ITER (v, &oiter, bm, op, "geom", BM_VERT) {
+ BMO_ITER (v, &oiter, op->slots_in, "geom", BM_VERT) {
/* count how many flagged edges this vertex uses */
int tot_edges = 0;
BM_ITER_ELEM (e, &iter, v, BM_EDGES_OF_VERT) {
@@ -1366,7 +1372,7 @@ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op)
/* call edgenet prepare op so additional face creation cases wore */
BMO_op_initf(bm, &op2, op->flag, "edgenet_prepare edges=%fe", ELE_NEW);
BMO_op_exec(bm, &op2);
- BMO_slot_buffer_flag_enable(bm, &op2, "edgeout", BM_EDGE, ELE_NEW);
+ BMO_slot_buffer_flag_enable(bm, op2.slots_out, "edges.out", BM_EDGE, ELE_NEW);
BMO_op_finish(bm, &op2);
BMO_op_initf(bm, &op2, op->flag,
@@ -1376,8 +1382,9 @@ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op)
BMO_op_exec(bm, &op2);
/* return if edge net create did something */
- if (BMO_slot_buffer_count(bm, &op2, "faceout")) {
- BMO_slot_copy(&op2, op, "faceout", "faceout");
+ if (BMO_slot_buffer_count(op2.slots_out, "faces.out")) {
+ BMO_slot_copy(&op2, slots_out, "faces.out",
+ op, slots_out, "faces.out");
BMO_op_finish(bm, &op2);
return;
}
@@ -1389,8 +1396,9 @@ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op)
BMO_op_exec(bm, &op2);
/* if we dissolved anything, then return */
- if (BMO_slot_buffer_count(bm, &op2, "regionout")) {
- BMO_slot_copy(&op2, op, "regionout", "faceout");
+ if (BMO_slot_buffer_count(op2.slots_out, "region.out")) {
+ BMO_slot_copy(&op2, slots_out, "region.out",
+ op, slots_out, "faces.out");
BMO_op_finish(bm, &op2);
return;
}
@@ -1414,7 +1422,7 @@ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op)
/* create edge */
e = BM_edge_create(bm, verts[0], verts[1], NULL, TRUE);
BMO_elem_flag_enable(bm, e, ELE_OUT);
- BMO_slot_buffer_from_enabled_flag(bm, op, "edgeout", BM_EDGE, ELE_OUT);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "edges.out", BM_EDGE, ELE_OUT);
}
else if (0) { /* nice feature but perhaps it should be a different tool? */
@@ -1460,7 +1468,7 @@ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op)
}
}
}
- BMO_slot_buffer_from_enabled_flag(bm, op, "edgeout", BM_EDGE, ELE_OUT);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "edges.out", BM_EDGE, ELE_OUT);
/* done creating edges */
}
else if (amount > 2) {
@@ -1470,7 +1478,7 @@ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op)
BMVert **vert_arr = MEM_mallocN(sizeof(BMVert **) * totv, __func__);
int i = 0;
- BMO_ITER (v, &oiter, bm, op, "geom", BM_VERT) {
+ BMO_ITER (v, &oiter, op->slots_in, "geom", BM_VERT) {
vert_arr[i] = v;
i++;
}
diff --git a/source/blender/bmesh/operators/bmo_dissolve.c b/source/blender/bmesh/operators/bmo_dissolve.c
index 9addb1b1657..7c3bcd60daa 100644
--- a/source/blender/bmesh/operators/bmo_dissolve.c
+++ b/source/blender/bmesh/operators/bmo_dissolve.c
@@ -85,7 +85,7 @@ void bmo_dissolve_faces_exec(BMesh *bm, BMOperator *op)
BMWalker regwalker;
int i;
- int use_verts = BMO_slot_bool_get(op, "use_verts");
+ int use_verts = BMO_slot_bool_get(op->slots_in, "use_verts");
if (use_verts) {
/* tag verts that start out with only 2 edges,
@@ -98,10 +98,10 @@ void bmo_dissolve_faces_exec(BMesh *bm, BMOperator *op)
}
}
- BMO_slot_buffer_flag_enable(bm, op, "faces", BM_FACE, FACE_MARK);
+ BMO_slot_buffer_flag_enable(bm, op->slots_in, "faces", BM_FACE, FACE_MARK);
/* collect region */
- BMO_ITER (f, &oiter, bm, op, "faces", BM_FACE) {
+ BMO_ITER (f, &oiter, op->slots_in, "faces", BM_FACE) {
if (!BMO_elem_flag_test(bm, f, FACE_MARK)) {
continue;
@@ -184,7 +184,7 @@ void bmo_dissolve_faces_exec(BMesh *bm, BMOperator *op)
goto cleanup;
}
- BMO_slot_buffer_from_enabled_flag(bm, op, "regionout", BM_FACE, FACE_NEW);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "region.out", BM_FACE, FACE_NEW);
cleanup:
/* free/cleanup */
@@ -208,7 +208,7 @@ void bmo_dissolve_edgeloop_exec(BMesh *bm, BMOperator *op)
int i;
- BMO_ITER (e, &oiter, bm, op, "edges", BM_EDGE) {
+ BMO_ITER (e, &oiter, op->slots_in, "edges", BM_EDGE) {
if (BM_edge_face_pair(e, &fa, &fb)) {
BMO_elem_flag_enable(bm, e->v1, VERT_MARK);
BMO_elem_flag_enable(bm, e->v2, VERT_MARK);
@@ -237,7 +237,7 @@ void bmo_dissolve_edgeloop_exec(BMesh *bm, BMOperator *op)
//BMO_op_initf(bm, &fop, "dissolve_faces faces=%ff", FACE_MARK);
//BMO_op_exec(bm, &fop);
- //BMO_slot_copy(op, &fop, "regionout", "regionout");
+ //BMO_slot_copy(op, &fop, "region.out", "region.out");
//BMO_op_finish(bm, &fop);
}
@@ -254,7 +254,7 @@ void bmo_dissolve_edges_exec(BMesh *bm, BMOperator *op)
BMIter viter;
BMVert *v;
- int use_verts = BMO_slot_bool_get(op, "use_verts");
+ int use_verts = BMO_slot_bool_get(op->slots_in, "use_verts");
if (use_verts) {
BM_ITER_MESH (v, &viter, bm, BM_VERTS_OF_MESH) {
@@ -262,7 +262,7 @@ void bmo_dissolve_edges_exec(BMesh *bm, BMOperator *op)
}
}
- BMO_ITER (e, &eiter, bm, op, "edges", BM_EDGE) {
+ BMO_ITER (e, &eiter, op->slots_in, "edges", BM_EDGE) {
BMFace *fa, *fb;
if (BM_edge_face_pair(e, &fa, &fb)) {
@@ -338,7 +338,7 @@ void bmo_dissolve_verts_exec(BMesh *bm, BMOperator *op)
BMFace *f;
/* int i; */
- BMO_slot_buffer_flag_enable(bm, op, "verts", BM_VERT, VERT_MARK);
+ BMO_slot_buffer_flag_enable(bm, op->slots_in, "verts", BM_VERT, VERT_MARK);
for (v = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL); v; v = BM_iter_step(&iter)) {
if (BMO_elem_flag_test(bm, v, VERT_MARK)) {
@@ -479,13 +479,13 @@ void dummy_exec(BMesh *bm, BMOperator *op)
/* Limited Dissolve */
void bmo_dissolve_limit_exec(BMesh *bm, BMOperator *op)
{
- BMOpSlot *einput = BMO_slot_get(op, "edges");
- BMOpSlot *vinput = BMO_slot_get(op, "verts");
+ BMOpSlot *einput = BMO_slot_get(op->slots_in, "edges");
+ BMOpSlot *vinput = BMO_slot_get(op->slots_in, "verts");
const float angle_max = (float)M_PI / 2.0f;
- const float angle_limit = min_ff(angle_max, BMO_slot_float_get(op, "angle_limit"));
- const int do_dissolve_boundaries = BMO_slot_bool_get(op, "use_dissolve_boundaries");
+ const float angle_limit = min_ff(angle_max, BMO_slot_float_get(op->slots_in, "angle_limit"));
+ const int do_dissolve_boundaries = BMO_slot_bool_get(op->slots_in, "use_dissolve_boundaries");
BM_mesh_decimate_dissolve_ex(bm, angle_limit, do_dissolve_boundaries,
- vinput->data.p, vinput->len,
- einput->data.p, einput->len);
+ (BMVert **)BMO_SLOT_AS_BUFFER(vinput), vinput->len,
+ (BMEdge **)BMO_SLOT_AS_BUFFER(einput), einput->len);
}
diff --git a/source/blender/bmesh/operators/bmo_dupe.c b/source/blender/bmesh/operators/bmo_dupe.c
index 32270007a0b..c4f6c821320 100644
--- a/source/blender/bmesh/operators/bmo_dupe.c
+++ b/source/blender/bmesh/operators/bmo_dupe.c
@@ -68,7 +68,9 @@ static BMVert *copy_vertex(BMesh *source_mesh, BMVert *source_vertex, BMesh *tar
*
* Copy an existing edge from one bmesh to another.
*/
-static BMEdge *copy_edge(BMOperator *op, BMesh *source_mesh,
+static BMEdge *copy_edge(BMOperator *op,
+ BMOpSlot *slot_boundarymap_out,
+ BMesh *source_mesh,
BMEdge *source_edge, BMesh *target_mesh,
GHash *vhash, GHash *ehash)
{
@@ -102,7 +104,7 @@ static BMEdge *copy_edge(BMOperator *op, BMesh *source_mesh,
if (rlen < 2) {
/* not sure what non-manifold cases of greater then three
* radial should do. */
- BMO_slot_map_ptr_insert(source_mesh, op, "boundarymap",
+ BMO_slot_map_ptr_insert(op, slot_boundarymap_out,
source_edge, target_edge);
}
@@ -124,7 +126,9 @@ static BMEdge *copy_edge(BMOperator *op, BMesh *source_mesh,
* Copy an existing face from one bmesh to another.
*/
-static BMFace *copy_face(BMOperator *op, BMesh *source_mesh,
+static BMFace *copy_face(BMOperator *op,
+ BMOpSlot *slot_facemap_out,
+ BMesh *source_mesh,
BMFace *source_face, BMesh *target_mesh,
BMVert **vtar, BMEdge **edar, GHash *vhash, GHash *ehash)
{
@@ -151,11 +155,11 @@ static BMFace *copy_face(BMOperator *op, BMesh *source_mesh,
vtar[i] = BLI_ghash_lookup(vhash, source_loop->v);
edar[i] = BLI_ghash_lookup(ehash, source_loop->e);
}
-
+
/* create new face */
target_face = BM_face_create(target_mesh, vtar, edar, source_face->len, FALSE);
- BMO_slot_map_ptr_insert(source_mesh, op, "facemap", source_face, target_face);
- BMO_slot_map_ptr_insert(source_mesh, op, "facemap", target_face, source_face);
+ 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);
BM_elem_attrs_copy(source_mesh, target_mesh, source_face, target_face);
@@ -181,7 +185,7 @@ static BMFace *copy_face(BMOperator *op, BMesh *source_mesh,
* Internal Copy function.
*/
-static void BKE_mesh_copy(BMOperator *op, BMesh *source, BMesh *target)
+static void bmo_mesh_copy(BMOperator *op, BMesh *bm_src, BMesh *bm_dst)
{
BMVert *v = NULL, *v2;
@@ -196,22 +200,26 @@ static void BKE_mesh_copy(BMOperator *op, BMesh *source, BMesh *target)
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");
+
/* initialize pointer hashes */
vhash = BLI_ghash_ptr_new("bmesh dupeops v");
ehash = BLI_ghash_ptr_new("bmesh dupeops e");
/* duplicate flagged vertices */
- BM_ITER_MESH (v, &viter, source, BM_VERTS_OF_MESH) {
- if (BMO_elem_flag_test(source, v, DUPE_INPUT) &&
- !BMO_elem_flag_test(source, v, DUPE_DONE))
+ BM_ITER_MESH (v, &viter, bm_src, BM_VERTS_OF_MESH) {
+ if (BMO_elem_flag_test(bm_src, v, DUPE_INPUT) &&
+ !BMO_elem_flag_test(bm_src, v, DUPE_DONE))
{
BMIter iter;
int isolated = 1;
- v2 = copy_vertex(source, v, target, vhash);
+ v2 = copy_vertex(bm_src, v, bm_dst, vhash);
BM_ITER_ELEM (f, &iter, v, BM_FACES_OF_VERT) {
- if (BMO_elem_flag_test(source, f, DUPE_INPUT)) {
+ if (BMO_elem_flag_test(bm_src, f, DUPE_INPUT)) {
isolated = 0;
break;
}
@@ -219,7 +227,7 @@ static void BKE_mesh_copy(BMOperator *op, BMesh *source, BMesh *target)
if (isolated) {
BM_ITER_ELEM (e, &iter, v, BM_EDGES_OF_VERT) {
- if (BMO_elem_flag_test(source, e, DUPE_INPUT)) {
+ if (BMO_elem_flag_test(bm_src, e, DUPE_INPUT)) {
isolated = 0;
break;
}
@@ -227,49 +235,49 @@ static void BKE_mesh_copy(BMOperator *op, BMesh *source, BMesh *target)
}
if (isolated) {
- BMO_slot_map_ptr_insert(source, op, "isovertmap", v, v2);
+ BMO_slot_map_ptr_insert(op, slot_isovertmap_out, v, v2);
}
- BMO_elem_flag_enable(source, v, DUPE_DONE);
+ BMO_elem_flag_enable(bm_src, v, DUPE_DONE);
}
}
/* now we dupe all the edges */
- BM_ITER_MESH (e, &eiter, source, BM_EDGES_OF_MESH) {
- if (BMO_elem_flag_test(source, e, DUPE_INPUT) &&
- !BMO_elem_flag_test(source, e, DUPE_DONE))
+ BM_ITER_MESH (e, &eiter, bm_src, BM_EDGES_OF_MESH) {
+ if (BMO_elem_flag_test(bm_src, e, DUPE_INPUT) &&
+ !BMO_elem_flag_test(bm_src, e, DUPE_DONE))
{
/* make sure that verts are copied */
- if (!BMO_elem_flag_test(source, e->v1, DUPE_DONE)) {
- copy_vertex(source, e->v1, target, vhash);
- BMO_elem_flag_enable(source, e->v1, DUPE_DONE);
+ if (!BMO_elem_flag_test(bm_src, e->v1, DUPE_DONE)) {
+ copy_vertex(bm_src, e->v1, bm_dst, vhash);
+ BMO_elem_flag_enable(bm_src, e->v1, DUPE_DONE);
}
- if (!BMO_elem_flag_test(source, e->v2, DUPE_DONE)) {
- copy_vertex(source, e->v2, target, vhash);
- BMO_elem_flag_enable(source, e->v2, DUPE_DONE);
+ if (!BMO_elem_flag_test(bm_src, e->v2, DUPE_DONE)) {
+ copy_vertex(bm_src, e->v2, bm_dst, vhash);
+ BMO_elem_flag_enable(bm_src, e->v2, DUPE_DONE);
}
/* now copy the actual edge */
- copy_edge(op, source, e, target, vhash, ehash);
- BMO_elem_flag_enable(source, e, DUPE_DONE);
+ copy_edge(op, slot_boundarymap_out, bm_src, e, bm_dst, vhash, ehash);
+ BMO_elem_flag_enable(bm_src, e, DUPE_DONE);
}
}
/* first we dupe all flagged faces and their elements from source */
- BM_ITER_MESH (f, &fiter, source, BM_FACES_OF_MESH) {
- if (BMO_elem_flag_test(source, f, DUPE_INPUT)) {
+ BM_ITER_MESH (f, &fiter, bm_src, BM_FACES_OF_MESH) {
+ if (BMO_elem_flag_test(bm_src, f, DUPE_INPUT)) {
/* vertex pass */
BM_ITER_ELEM (v, &viter, f, BM_VERTS_OF_FACE) {
- if (!BMO_elem_flag_test(source, v, DUPE_DONE)) {
- copy_vertex(source, v, target, vhash);
- BMO_elem_flag_enable(source, v, DUPE_DONE);
+ if (!BMO_elem_flag_test(bm_src, v, DUPE_DONE)) {
+ copy_vertex(bm_src, v, bm_dst, vhash);
+ BMO_elem_flag_enable(bm_src, v, DUPE_DONE);
}
}
/* edge pass */
BM_ITER_ELEM (e, &eiter, f, BM_EDGES_OF_FACE) {
- if (!BMO_elem_flag_test(source, e, DUPE_DONE)) {
- copy_edge(op, source, e, target, vhash, ehash);
- BMO_elem_flag_enable(source, e, DUPE_DONE);
+ if (!BMO_elem_flag_test(bm_src, e, DUPE_DONE)) {
+ copy_edge(op, slot_boundarymap_out, bm_src, e, bm_dst, vhash, ehash);
+ BMO_elem_flag_enable(bm_src, e, DUPE_DONE);
}
}
@@ -280,8 +288,8 @@ static void BKE_mesh_copy(BMOperator *op, BMesh *source, BMesh *target)
BLI_array_grow_items(vtar, f->len);
BLI_array_grow_items(edar, f->len);
- copy_face(op, source, f, target, vtar, edar, vhash, ehash);
- BMO_elem_flag_enable(source, f, DUPE_DONE);
+ copy_face(op, slot_facemap_out, bm_src, f, bm_dst, vtar, edar, vhash, ehash);
+ BMO_elem_flag_enable(bm_src, f, DUPE_DONE);
}
}
@@ -317,23 +325,24 @@ static void BKE_mesh_copy(BMOperator *op, BMesh *source, BMesh *target)
void bmo_duplicate_exec(BMesh *bm, BMOperator *op)
{
BMOperator *dupeop = op;
- BMesh *bm2 = BMO_slot_ptr_get(op, "dest");
+ BMesh *bm2 = BMO_slot_ptr_get(op->slots_in, "dest");
if (!bm2)
bm2 = bm;
/* flag input */
- BMO_slot_buffer_flag_enable(bm, dupeop, "geom", BM_ALL, DUPE_INPUT);
+ BMO_slot_buffer_flag_enable(bm, dupeop->slots_in, "geom", BM_ALL, DUPE_INPUT);
/* use the internal copy function */
- BKE_mesh_copy(dupeop, bm, bm2);
+ bmo_mesh_copy(dupeop, bm, bm2);
/* Output */
/* First copy the input buffers to output buffers - original data */
- BMO_slot_copy(dupeop, dupeop, "geom", "origout");
+ BMO_slot_copy(dupeop, slots_in, "geom",
+ dupeop, slots_out, "geom_orig.out");
/* Now alloc the new output buffers */
- BMO_slot_buffer_from_enabled_flag(bm, dupeop, "newout", BM_ALL, DUPE_NEW);
+ BMO_slot_buffer_from_enabled_flag(bm, dupeop, dupeop->slots_out, "geom.out", BM_ALL, DUPE_NEW);
}
#if 0 /* UNUSED */
@@ -378,16 +387,17 @@ void bmo_split_exec(BMesh *bm, BMOperator *op)
BMOperator *splitop = op;
BMOperator dupeop;
BMOperator delop;
- const short use_only_faces = BMO_slot_bool_get(op, "use_only_faces");
+ const short use_only_faces = BMO_slot_bool_get(op->slots_in, "use_only_faces");
/* initialize our sub-operator */
BMO_op_init(bm, &dupeop, op->flag, "duplicate");
BMO_op_init(bm, &delop, op->flag, "delete");
- BMO_slot_copy(splitop, &dupeop, "geom", "geom");
+ BMO_slot_copy(splitop, slots_in, "geom",
+ &dupeop, slots_in, "geom");
BMO_op_exec(bm, &dupeop);
- BMO_slot_buffer_flag_enable(bm, splitop, "geom", BM_ALL, SPLIT_INPUT);
+ BMO_slot_buffer_flag_enable(bm, splitop->slots_in, "geom", BM_ALL, SPLIT_INPUT);
if (use_only_faces) {
BMVert *v;
@@ -427,16 +437,22 @@ void bmo_split_exec(BMesh *bm, BMOperator *op)
}
/* connect outputs of dupe to delete, exluding keep geometry */
- BMO_slot_int_set(&delop, "context", DEL_FACES);
- BMO_slot_buffer_from_enabled_flag(bm, &delop, "geom", BM_ALL, SPLIT_INPUT);
+ 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_op_exec(bm, &delop);
/* now we make our outputs by copying the dupe output */
- BMO_slot_copy(&dupeop, splitop, "newout", "geomout");
- BMO_slot_copy(&dupeop, splitop, "boundarymap", "boundarymap");
- BMO_slot_copy(&dupeop, splitop, "isovertmap", "isovertmap");
-
+ 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, "isovertmap.out",
+ splitop, slots_out, "isovertmap.out");
+
+
/* cleanup */
BMO_op_finish(bm, &delop);
BMO_op_finish(bm, &dupeop);
@@ -450,9 +466,9 @@ void bmo_delete_exec(BMesh *bm, BMOperator *op)
BMOperator *delop = op;
/* Mark Buffer */
- BMO_slot_buffer_flag_enable(bm, delop, "geom", BM_ALL, DEL_INPUT);
+ BMO_slot_buffer_flag_enable(bm, delop->slots_in, "geom", BM_ALL, DEL_INPUT);
- BMO_remove_tagged_context(bm, DEL_INPUT, BMO_slot_int_get(op, "context"));
+ BMO_remove_tagged_context(bm, DEL_INPUT, BMO_slot_int_get(op->slots_in, "context"));
#undef DEL_INPUT
}
@@ -473,44 +489,47 @@ void bmo_spin_exec(BMesh *bm, BMOperator *op)
float phi;
int steps, do_dupli, a, usedvec;
- BMO_slot_vec_get(op, "cent", cent);
- BMO_slot_vec_get(op, "axis", axis);
+ BMO_slot_vec_get(op->slots_in, "cent", cent);
+ BMO_slot_vec_get(op->slots_in, "axis", axis);
normalize_v3(axis);
- BMO_slot_vec_get(op, "dvec", dvec);
+ BMO_slot_vec_get(op->slots_in, "dvec", dvec);
usedvec = !is_zero_v3(dvec);
- steps = BMO_slot_int_get(op, "steps");
- phi = BMO_slot_float_get(op, "ang") * DEG2RADF(1.0f) / steps;
- do_dupli = BMO_slot_bool_get(op, "do_dupli");
+ steps = BMO_slot_int_get(op->slots_in, "steps");
+ phi = BMO_slot_float_get(op->slots_in, "angle") * DEG2RADF(1.0f) / steps;
+ do_dupli = BMO_slot_bool_get(op->slots_in, "use_duplicate");
axis_angle_to_mat3(rmat, axis, phi);
- BMO_slot_copy(op, op, "geom", "lastout");
+ BMO_slot_copy(op, slots_in, "geom",
+ op, slots_out, "geom_last.out");
for (a = 0; a < steps; a++) {
if (do_dupli) {
- BMO_op_initf(bm, &dupop, op->flag, "duplicate geom=%s", op, "lastout");
+ 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",
- cent, rmat, &dupop, "newout");
- BMO_slot_copy(&dupop, op, "newout", "lastout");
+ "rotate cent=%v mat=%m3 verts=%S",
+ cent, rmat, &dupop, "geom.out");
+ BMO_slot_copy(&dupop, slots_out, "geom.out",
+ op, slots_out, "geom_last.out");
BMO_op_finish(bm, &dupop);
}
else {
- BMO_op_initf(bm, &extop, op->flag, "extrude_face_region edgefacein=%s",
- op, "lastout");
+ BMO_op_initf(bm, &extop, op->flag, "extrude_face_region geom=%S",
+ op, "geom_last.out");
BMO_op_exec(bm, &extop);
BMO_op_callf(bm, op->flag,
- "rotate cent=%v mat=%m3 verts=%s",
- cent, rmat, &extop, "geomout");
- BMO_slot_copy(&extop, op, "geomout", "lastout");
+ "rotate cent=%v mat=%m3 verts=%S",
+ cent, rmat, &extop, "geom.out");
+ BMO_slot_copy(&extop, slots_out, "geom.out",
+ op, slots_out, "geom_last.out");
BMO_op_finish(bm, &extop);
}
if (usedvec) {
mul_m3_v3(rmat, dvec);
BMO_op_callf(bm, op->flag,
- "translate vec=%v verts=%s",
- dvec, op, "lastout");
+ "translate vec=%v verts=%S",
+ dvec, op, "geom_last.out");
}
}
}
diff --git a/source/blender/bmesh/operators/bmo_edgesplit.c b/source/blender/bmesh/operators/bmo_edgesplit.c
index 1f6689ed06c..9e9e4b8c962 100644
--- a/source/blender/bmesh/operators/bmo_edgesplit.c
+++ b/source/blender/bmesh/operators/bmo_edgesplit.c
@@ -81,14 +81,14 @@ static void bm_edgesplit_validate_seams(BMesh *bm, BMOperator *op)
/* single marked edges unconnected to any other marked edges
* are illegal, go through and unmark them */
- BMO_ITER (e, &siter, bm, op, "edges", BM_EDGE) {
+ BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) {
/* lame, but we don't want the count to exceed 255,
* so just count to 2, its all we need */
unsigned char *vt;
vt = &vtouch[BM_elem_index_get(e->v1)]; if (*vt < 2) (*vt)++;
vt = &vtouch[BM_elem_index_get(e->v2)]; if (*vt < 2) (*vt)++;
}
- BMO_ITER (e, &siter, bm, op, "edges", BM_EDGE) {
+ BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) {
if (vtouch[BM_elem_index_get(e->v1)] == 1 &&
vtouch[BM_elem_index_get(e->v2)] == 1)
{
@@ -104,13 +104,13 @@ void bmo_split_edges_exec(BMesh *bm, BMOperator *op)
{
BMOIter siter;
BMEdge *e;
- const int use_verts = BMO_slot_bool_get(op, "use_verts");
+ const int use_verts = BMO_slot_bool_get(op->slots_in, "use_verts");
- BMO_slot_buffer_flag_enable(bm, op, "edges", BM_EDGE, EDGE_SEAM);
+ BMO_slot_buffer_flag_enable(bm, op->slots_in, "edges", BM_EDGE, EDGE_SEAM);
if (use_verts) {
/* this slows down the operation but its ok because the modifier doesn't use */
- BMO_slot_buffer_flag_enable(bm, op, "verts", BM_VERT, VERT_SEAM);
+ BMO_slot_buffer_flag_enable(bm, op->slots_in, "verts", BM_VERT, VERT_SEAM);
/* prevent one edge having both verts unflagged
* we could alternately disable these edges, either way its a corner case.
@@ -118,7 +118,7 @@ void bmo_split_edges_exec(BMesh *bm, BMOperator *op)
* This is needed so we don't split off the edge but then none of its verts which
* would leave a duplicate edge.
*/
- BMO_ITER (e, &siter, bm, op, "edges", BM_EDGE) {
+ BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) {
if (UNLIKELY((BMO_elem_flag_test(bm, e->v1, VERT_SEAM) == FALSE &&
(BMO_elem_flag_test(bm, e->v2, VERT_SEAM) == FALSE))))
{
@@ -130,7 +130,7 @@ void bmo_split_edges_exec(BMesh *bm, BMOperator *op)
bm_edgesplit_validate_seams(bm, op);
- BMO_ITER (e, &siter, bm, op, "edges", BM_EDGE) {
+ BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) {
if (BMO_elem_flag_test(bm, e, EDGE_SEAM)) {
/* this flag gets copied so we can be sure duplicate edges get it too (important) */
BM_elem_flag_enable(e, BM_ELEM_INTERNAL_TAG);
@@ -146,7 +146,7 @@ void bmo_split_edges_exec(BMesh *bm, BMOperator *op)
}
if (use_verts) {
- BMO_ITER (e, &siter, bm, op, "edges", BM_EDGE) {
+ BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) {
if (BMO_elem_flag_test(bm, e->v1, VERT_SEAM) == FALSE) {
BM_elem_flag_disable(e->v1, BM_ELEM_TAG);
}
@@ -156,7 +156,7 @@ void bmo_split_edges_exec(BMesh *bm, BMOperator *op)
}
}
- BMO_ITER (e, &siter, bm, op, "edges", BM_EDGE) {
+ BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) {
if (BMO_elem_flag_test(bm, e, EDGE_SEAM)) {
if (BM_elem_flag_test(e->v1, BM_ELEM_TAG)) {
BM_elem_flag_disable(e->v1, BM_ELEM_TAG);
@@ -169,5 +169,5 @@ void bmo_split_edges_exec(BMesh *bm, BMOperator *op)
}
}
- BMO_slot_buffer_from_enabled_hflag(bm, op, "edgeout", BM_EDGE, BM_ELEM_INTERNAL_TAG);
+ BMO_slot_buffer_from_enabled_hflag(bm, op, op->slots_out, "edges.out", BM_EDGE, BM_ELEM_INTERNAL_TAG);
}
diff --git a/source/blender/bmesh/operators/bmo_extrude.c b/source/blender/bmesh/operators/bmo_extrude.c
index 627351ead11..6a9d9c1e48b 100644
--- a/source/blender/bmesh/operators/bmo_extrude.c
+++ b/source/blender/bmesh/operators/bmo_extrude.c
@@ -60,7 +60,7 @@ void bmo_extrude_discrete_faces_exec(BMesh *bm, BMOperator *op)
BLI_array_declare(edges);
int i;
- BMO_ITER (f, &siter, bm, op, "faces", BM_FACE) {
+ BMO_ITER (f, &siter, op->slots_in, "faces", BM_FACE) {
BLI_array_empty(edges);
BLI_array_grow_items(edges, f->len);
@@ -122,7 +122,7 @@ void bmo_extrude_discrete_faces_exec(BMesh *bm, BMOperator *op)
BMO_op_callf(bm, op->flag,
"delete geom=%ff context=%i",
EXT_DEL, DEL_ONLYFACES);
- BMO_slot_buffer_from_enabled_flag(bm, op, "faceout", BM_FACE, EXT_KEEP);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "faces.out", BM_FACE, EXT_KEEP);
}
/**
@@ -181,7 +181,7 @@ void bmo_extrude_edge_only_exec(BMesh *bm, BMOperator *op)
BMFace *f;
BMEdge *e, *e_new;
- BMO_ITER (e, &siter, bm, op, "edges", BM_EDGE) {
+ BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) {
BMO_elem_flag_enable(bm, e, EXT_INPUT);
BMO_elem_flag_enable(bm, e->v1, EXT_INPUT);
BMO_elem_flag_enable(bm, e->v2, EXT_INPUT);
@@ -193,12 +193,12 @@ void bmo_extrude_edge_only_exec(BMesh *bm, BMOperator *op)
/* disable root flag on all new skin nodes */
if (CustomData_has_layer(&bm->vdata, CD_MVERT_SKIN)) {
BMVert *v;
- BMO_ITER(v, &siter, bm, &dupeop, "newout", BM_VERT) {
+ BMO_ITER(v, &siter, dupeop.slots_out, "geom.out", BM_VERT) {
bm_extrude_disable_skin_root(bm, v);
}
}
- for (e = BMO_iter_new(&siter, bm, &dupeop, "boundarymap", 0); e; e = BMO_iter_step(&siter)) {
+ for (e = BMO_iter_new(&siter, dupeop.slots_out, "boundarymap.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, "geomout", BM_ALL, EXT_KEEP);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom.out", BM_ALL, EXT_KEEP);
}
void bmo_extrude_vert_indiv_exec(BMesh *bm, BMOperator *op)
@@ -240,7 +240,7 @@ void bmo_extrude_vert_indiv_exec(BMesh *bm, BMOperator *op)
BMEdge *e;
const int has_vskin = CustomData_has_layer(&bm->vdata, CD_MVERT_SKIN);
- for (v = BMO_iter_new(&siter, bm, op, "verts", BM_VERT); v; v = BMO_iter_step(&siter)) {
+ 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);
if (has_vskin)
bm_extrude_disable_skin_root(bm, v);
@@ -251,8 +251,8 @@ void bmo_extrude_vert_indiv_exec(BMesh *bm, BMOperator *op)
BMO_elem_flag_enable(bm, dupev, EXT_KEEP);
}
- BMO_slot_buffer_from_enabled_flag(bm, op, "vertout", BM_VERT, EXT_KEEP);
- BMO_slot_buffer_from_enabled_flag(bm, op, "edgeout", BM_EDGE, EXT_KEEP);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "verts.out", BM_VERT, EXT_KEEP);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "edges.out", BM_EDGE, EXT_KEEP);
}
void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op)
@@ -264,15 +264,17 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op)
BMVert *v, *v2;
BMFace *f;
int found, fwd, delorig = FALSE;
+ BMOpSlot *slot_facemap_out;
+ BMOpSlot *slot_edges_exclude;
/* initialize our sub-operators */
BMO_op_init(bm, &dupeop, op->flag, "duplicate");
- BMO_slot_buffer_flag_enable(bm, op, "edgefacein", BM_EDGE | BM_FACE, EXT_INPUT);
+ BMO_slot_buffer_flag_enable(bm, op->slots_in, "geom", BM_EDGE | BM_FACE, EXT_INPUT);
/* if one flagged face is bordered by an un-flagged face, then we delete
* original geometry unless caller explicitly asked to keep it. */
- if (!BMO_slot_bool_get(op, "alwayskeeporig")) {
+ if (!BMO_slot_bool_get(op->slots_in, "use_keep_orig")) {
BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
int edge_face_tot;
@@ -339,18 +341,21 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op)
EXT_DEL, DEL_ONLYTAGGED);
}
- BMO_slot_copy(op, &dupeop, "edgefacein", "geom");
+ BMO_slot_copy(op, slots_in, "geom",
+ &dupeop, slots_in, "geom");
BMO_op_exec(bm, &dupeop);
/* disable root flag on all new skin nodes */
if (CustomData_has_layer(&bm->vdata, CD_MVERT_SKIN)) {
- BMO_ITER(v, &siter, bm, &dupeop, "newout", BM_VERT) {
+ BMO_ITER(v, &siter, dupeop.slots_out, "geom.out", BM_VERT) {
bm_extrude_disable_skin_root(bm, v);
}
}
- if (bm->act_face && BMO_elem_flag_test(bm, bm->act_face, EXT_INPUT))
- bm->act_face = BMO_slot_map_ptr_get(bm, &dupeop, "facemap", bm->act_face);
+ slot_facemap_out = BMO_slot_get(dupeop.slots_out, "facemap.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);
+ }
if (delorig) {
BMO_op_exec(bm, &delop);
@@ -365,13 +370,15 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op)
}
}
- BMO_slot_copy(&dupeop, op, "newout", "geomout");
+ BMO_slot_copy(&dupeop, slots_out, "geom.out",
+ op, slots_out, "geom.out");
- for (e = BMO_iter_new(&siter, bm, &dupeop, "boundarymap", 0); e; e = BMO_iter_step(&siter)) {
+ 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)) {
BMVert *f_verts[4];
/* this should always be wire, so this is mainly a speedup to avoid map lookup */
- if (BM_edge_is_wire(e) && BMO_slot_map_contains(bm, op, "exclude", e)) {
+ if (BM_edge_is_wire(e) && BMO_slot_map_contains(slot_edges_exclude, e)) {
BMVert *v1 = e->v1, *v2 = e->v2;
/* The original edge was excluded,
@@ -421,7 +428,7 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op)
}
/* link isolated vert */
- for (v = BMO_iter_new(&siter, bm, &dupeop, "isovertmap", 0); v; v = BMO_iter_step(&siter)) {
+ for (v = BMO_iter_new(&siter, dupeop.slots_out, "isovertmap.out", 0); v; v = BMO_iter_step(&siter)) {
v2 = *((void **)BMO_iter_map_value(&siter));
BM_edge_create(bm, v, v2, v->e, TRUE);
}
@@ -595,10 +602,10 @@ static void solidify_add_thickness(BMesh *bm, const float dist)
/* array for passing verts to angle_poly_v3 */
float **verts = NULL;
- BLI_array_staticdeclare(verts, BM_NGON_STACK_SIZE);
+ BLI_array_staticdeclare(verts, BM_DEFAULT_NGON_STACK_SIZE);
/* array for receiving angles from angle_poly_v3 */
float *face_angles = NULL;
- BLI_array_staticdeclare(face_angles, BM_NGON_STACK_SIZE);
+ BLI_array_staticdeclare(face_angles, BM_DEFAULT_NGON_STACK_SIZE);
BM_mesh_elem_index_ensure(bm, BM_VERT);
@@ -647,25 +654,28 @@ void bmo_solidify_face_region_exec(BMesh *bm, BMOperator *op)
BMOperator reverseop;
float thickness;
- thickness = BMO_slot_float_get(op, "thickness");
+ thickness = BMO_slot_float_get(op->slots_in, "thickness");
/* Flip original faces (so the shell is extruded inward) */
BMO_op_init(bm, &reverseop, op->flag, "reverse_faces");
- BMO_slot_copy(op, &reverseop, "geom", "faces");
+ BMO_slot_copy(op, slots_in, "geom",
+ &reverseop, slots_in, "faces");
BMO_op_exec(bm, &reverseop);
BMO_op_finish(bm, &reverseop);
/* Extrude the region */
- BMO_op_initf(bm, &extrudeop, op->flag, "extrude_face_region alwayskeeporig=%b", TRUE);
- BMO_slot_copy(op, &extrudeop, "geom", "edgefacein");
+ BMO_op_initf(bm, &extrudeop, op->flag, "extrude_face_region use_keep_orig=%b", TRUE);
+ BMO_slot_copy(op, slots_in, "geom",
+ &extrudeop, slots_in, "geom");
BMO_op_exec(bm, &extrudeop);
/* Push the verts of the extruded faces inward to create thickness */
- BMO_slot_buffer_flag_enable(bm, &extrudeop, "geomout", BM_FACE, FACE_MARK);
+ BMO_slot_buffer_flag_enable(bm, extrudeop.slots_out, "geom.out", BM_FACE, FACE_MARK);
calc_solidify_normals(bm);
solidify_add_thickness(bm, thickness);
- BMO_slot_copy(&extrudeop, op, "geomout", "geomout");
+ BMO_slot_copy(&extrudeop, slots_out, "geom.out",
+ op, slots_out, "geom.out");
BMO_op_finish(bm, &extrudeop);
}
diff --git a/source/blender/bmesh/operators/bmo_hull.c b/source/blender/bmesh/operators/bmo_hull.c
index b9c9398fbfa..117f65ae4ea 100644
--- a/source/blender/bmesh/operators/bmo_hull.c
+++ b/source/blender/bmesh/operators/bmo_hull.c
@@ -119,7 +119,7 @@ static void hull_output_triangles(BMesh *bm, GHash *hull_triangles)
};
BMFace *f, *example = NULL;
- if (BM_face_exists(bm, t->v, 3, &f)) {
+ if (BM_face_exists(t->v, 3, &f)) {
/* If the operator is run with "use_existing_faces"
* disabled, but an output face in the hull is the
* same as a face in the existing mesh, it should not
@@ -139,17 +139,17 @@ static void hull_output_triangles(BMesh *bm, GHash *hull_triangles)
f = BM_face_create_quad_tri_v(bm, t->v, 3, example, TRUE);
BM_face_copy_shared(bm, f);
}
- /* Mark face for 'geomout' slot and select */
+ /* Mark face for 'geom.out' slot and select */
BMO_elem_flag_enable(bm, f, HULL_FLAG_OUTPUT_GEOM);
BM_face_select_set(bm, f, TRUE);
- /* Mark edges for 'geomout' slot */
+ /* Mark edges for 'geom.out' slot */
for (i = 0; i < 3; i++) {
BMO_elem_flag_enable(bm, edges[i], HULL_FLAG_OUTPUT_GEOM);
}
}
else {
- /* Mark input edges for 'geomout' slot */
+ /* Mark input edges for 'geom.out' slot */
for (i = 0; i < 3; i++) {
const int next = (i == 2 ? 0 : i + 1);
BMEdge *e = BM_edge_exists(t->v[i], t->v[next]);
@@ -161,7 +161,7 @@ static void hull_output_triangles(BMesh *bm, GHash *hull_triangles)
}
}
- /* Mark verts for 'geomout' slot */
+ /* Mark verts for 'geom.out' slot */
for (i = 0; i < 3; i++) {
BMO_elem_flag_enable(bm, t->v[i], HULL_FLAG_OUTPUT_GEOM);
}
@@ -304,14 +304,14 @@ static void hull_mark_interior_elements(BMesh *bm, BMOperator *op,
BMOIter oiter;
/* Check for interior edges too */
- BMO_ITER (e, &oiter, bm, op, "input", BM_EDGE) {
+ BMO_ITER (e, &oiter, op->slots_in, "input", BM_EDGE) {
if (!hull_final_edges_lookup(final_edges, e->v1, e->v2))
BMO_elem_flag_enable(bm, e, HULL_FLAG_INTERIOR_ELE);
}
/* Mark all input faces as interior, some may be unmarked in
* hull_remove_overlapping() */
- BMO_ITER (f, &oiter, bm, op, "input", BM_FACE) {
+ BMO_ITER (f, &oiter, op->slots_in, "input", BM_FACE) {
BMO_elem_flag_enable(bm, f, HULL_FLAG_INTERIOR_ELE);
}
}
@@ -328,7 +328,7 @@ static void hull_tag_unused(BMesh *bm, BMOperator *op)
* interior (i.e. were already part of the input, but not part of
* the hull), but that aren't also used by elements outside the
* input set */
- BMO_ITER (v, &oiter, bm, op, "input", BM_VERT) {
+ BMO_ITER (v, &oiter, op->slots_in, "input", BM_VERT) {
if (BMO_elem_flag_test(bm, v, HULL_FLAG_INTERIOR_ELE)) {
int del = TRUE;
@@ -351,7 +351,7 @@ static void hull_tag_unused(BMesh *bm, BMOperator *op)
}
}
- BMO_ITER (e, &oiter, bm, op, "input", BM_EDGE) {
+ BMO_ITER (e, &oiter, op->slots_in, "input", BM_EDGE) {
if (BMO_elem_flag_test(bm, e, HULL_FLAG_INTERIOR_ELE)) {
int del = TRUE;
@@ -367,7 +367,7 @@ static void hull_tag_unused(BMesh *bm, BMOperator *op)
}
}
- BMO_ITER (f, &oiter, bm, op, "input", BM_FACE) {
+ BMO_ITER (f, &oiter, op->slots_in, "input", BM_FACE) {
if (BMO_elem_flag_test(bm, f, HULL_FLAG_INTERIOR_ELE))
BMO_elem_flag_enable(bm, f, HULL_FLAG_DEL);
}
@@ -382,10 +382,10 @@ static void hull_tag_holes(BMesh *bm, BMOperator *op)
/* Unmark any hole faces if they are isolated or part of a
* border */
- BMO_ITER (f, &oiter, bm, op, "input", BM_FACE) {
+ BMO_ITER (f, &oiter, op->slots_in, "input", BM_FACE) {
if (BMO_elem_flag_test(bm, f, HULL_FLAG_HOLE)) {
BM_ITER_ELEM (e, &iter, f, BM_EDGES_OF_FACE) {
- if (BM_edge_face_count(e) == 1) {
+ if (BM_edge_is_boundary(e)) {
BMO_elem_flag_disable(bm, f, HULL_FLAG_HOLE);
break;
}
@@ -395,7 +395,7 @@ static void hull_tag_holes(BMesh *bm, BMOperator *op)
/* Mark edges too if all adjacent faces are holes and the edge is
* not already isolated */
- BMO_ITER (e, &oiter, bm, op, "input", BM_EDGE) {
+ BMO_ITER (e, &oiter, op->slots_in, "input", BM_EDGE) {
int hole = TRUE;
int any_faces = FALSE;
@@ -412,20 +412,20 @@ static void hull_tag_holes(BMesh *bm, BMOperator *op)
}
}
-static int hull_input_vert_count(BMesh *bm, BMOperator *op)
+static int hull_input_vert_count(BMOperator *op)
{
BMOIter oiter;
BMVert *v;
int count = 0;
- BMO_ITER (v, &oiter, bm, op, "input", BM_VERT) {
+ BMO_ITER (v, &oiter, op->slots_in, "input", BM_VERT) {
count++;
}
return count;
}
-static BMVert **hull_input_verts_copy(BMesh *bm, BMOperator *op,
+static BMVert **hull_input_verts_copy(BMOperator *op,
const int num_input_verts)
{
BMOIter oiter;
@@ -434,7 +434,7 @@ static BMVert **hull_input_verts_copy(BMesh *bm, BMOperator *op,
num_input_verts, AT);
int i = 0;
- BMO_ITER (v, &oiter, bm, op, "input", BM_VERT) {
+ BMO_ITER (v, &oiter, op->slots_in, "input", BM_VERT) {
input_verts[i++] = v;
}
@@ -492,9 +492,9 @@ static void hull_from_bullet(BMesh *bm, BMOperator *op,
plConvexHull hull;
int i, count = 0;
- const int num_input_verts = hull_input_vert_count(bm, op);
+ const int num_input_verts = hull_input_vert_count(op);
- input_verts = hull_input_verts_copy(bm, op, num_input_verts);
+ input_verts = hull_input_verts_copy(op, num_input_verts);
coords = hull_verts_for_bullet(input_verts, num_input_verts);
hull = plConvexHullCompute(coords, num_input_verts);
@@ -535,13 +535,13 @@ static void hull_from_bullet(BMesh *bm, BMOperator *op,
}
/* Check that there are at least three vertices in the input */
-static int hull_num_input_verts_is_ok(BMesh *bm, BMOperator *op)
+static int hull_num_input_verts_is_ok(BMOperator *op)
{
BMOIter oiter;
BMVert *v;
int partial_num_verts = 0;
- BMO_ITER (v, &oiter, bm, op, "input", BM_VERT) {
+ BMO_ITER (v, &oiter, op->slots_in, "input", BM_VERT) {
partial_num_verts++;
if (partial_num_verts >= 3)
break;
@@ -559,14 +559,14 @@ void bmo_convex_hull_exec(BMesh *bm, BMOperator *op)
GHash *hull_triangles;
/* Verify that at least three verts in the input */
- if (!hull_num_input_verts_is_ok(bm, op)) {
+ if (!hull_num_input_verts_is_ok(op)) {
BMO_error_raise(bm, op, BMERR_CONVEX_HULL_FAILED,
"Requires at least three vertices");
return;
}
/* Tag input elements */
- BMO_ITER (ele, &oiter, bm, op, "input", BM_ALL) {
+ BMO_ITER (ele, &oiter, op->slots_in, "input", BM_ALL) {
BMO_elem_flag_enable(bm, ele, HULL_FLAG_INPUT);
/* Mark all vertices as interior to begin with */
@@ -584,7 +584,7 @@ void bmo_convex_hull_exec(BMesh *bm, BMOperator *op)
hull_mark_interior_elements(bm, op, final_edges);
/* Remove hull triangles covered by an existing face */
- if (BMO_slot_bool_get(op, "use_existing_faces")) {
+ if (BMO_slot_bool_get(op->slots_in, "use_existing_faces")) {
hull_remove_overlapping(bm, hull_triangles, final_edges);
hull_tag_holes(bm, op);
@@ -603,23 +603,23 @@ 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, "interior_geom", BM_ALL,
- HULL_FLAG_INTERIOR_ELE);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom_interior.out",
+ BM_ALL, 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, "unused_geom", BM_ALL,
- HULL_FLAG_DEL);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom_unused.out",
+ BM_ALL, 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, "holes_geom", BM_ALL,
- HULL_FLAG_HOLE);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom_holes.out",
+ BM_ALL, HULL_FLAG_HOLE);
/* Output slot of all hull vertices, faces, and edges */
- BMO_slot_buffer_from_enabled_flag(bm, op, "geomout", BM_ALL,
- HULL_FLAG_OUTPUT_GEOM);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom.out",
+ BM_ALL, 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 132d7050b31..9abf129a529 100644
--- a/source/blender/bmesh/operators/bmo_inset.c
+++ b/source/blender/bmesh/operators/bmo_inset.c
@@ -92,13 +92,13 @@ static BMLoop *bm_edge_is_mixed_face_tag(BMLoop *l)
void bmo_inset_exec(BMesh *bm, BMOperator *op)
{
- const int use_outset = BMO_slot_bool_get(op, "use_outset");
- const int use_boundary = BMO_slot_bool_get(op, "use_boundary") && (use_outset == FALSE);
- const int use_even_offset = BMO_slot_bool_get(op, "use_even_offset");
+ const int use_outset = BMO_slot_bool_get(op->slots_in, "use_outset");
+ const int use_boundary = BMO_slot_bool_get(op->slots_in, "use_boundary") && (use_outset == FALSE);
+ const int use_even_offset = BMO_slot_bool_get(op->slots_in, "use_even_offset");
const int use_even_boundry = use_even_offset; /* could make own option */
- const int use_relative_offset = BMO_slot_bool_get(op, "use_relative_offset");
- const float thickness = BMO_slot_float_get(op, "thickness");
- const float depth = BMO_slot_float_get(op, "depth");
+ const int use_relative_offset = BMO_slot_bool_get(op->slots_in, "use_relative_offset");
+ const float thickness = BMO_slot_float_get(op->slots_in, "thickness");
+ const float depth = BMO_slot_float_get(op->slots_in, "depth");
int edge_info_len = 0;
@@ -113,11 +113,11 @@ void bmo_inset_exec(BMesh *bm, BMOperator *op)
if (use_outset == FALSE) {
BM_mesh_elem_hflag_disable_all(bm, BM_FACE, BM_ELEM_TAG, FALSE);
- BMO_slot_buffer_hflag_enable(bm, op, "faces", BM_FACE, BM_ELEM_TAG, FALSE);
+ BMO_slot_buffer_hflag_enable(bm, op->slots_in, "faces", BM_FACE, BM_ELEM_TAG, FALSE);
}
else {
BM_mesh_elem_hflag_enable_all(bm, BM_FACE, BM_ELEM_TAG, FALSE);
- BMO_slot_buffer_hflag_disable(bm, op, "faces", BM_FACE, BM_ELEM_TAG, FALSE);
+ BMO_slot_buffer_hflag_disable(bm, op->slots_in, "faces", BM_FACE, BM_ELEM_TAG, FALSE);
}
/* first count all inset edges we will split */
@@ -477,11 +477,48 @@ void bmo_inset_exec(BMesh *bm, BMOperator *op)
/* copy for loop data, otherwise UV's and vcols are no good.
* tiny speedup here we could be more clever and copy from known adjacent data
* also - we could attempt to interpolate the loop data, this would be much slower but more useful too */
+#if 0
+ /* don't use this because face boundaries have no adjacent loops and won't be filled in.
+ * instead copy from the opposite side with the code below */
BM_face_copy_shared(bm, f);
+#else
+ {
+ /* 2 inner loops on the edge between the new face and the original */
+ BMLoop *l_a;
+ BMLoop *l_b;
+ BMLoop *l_a_other;
+ BMLoop *l_b_other;
+
+ l_a = BM_FACE_FIRST_LOOP(f);
+ l_b = l_a->next;
+
+ /* we know this side has a radial_next because of the order of created verts in the quad */
+ l_a_other = BM_edge_other_loop(l_a->e, l_a);
+ l_b_other = BM_edge_other_loop(l_a->e, l_b);
+ BM_elem_attrs_copy(bm, bm, l_a_other, l_a);
+ BM_elem_attrs_copy(bm, bm, l_b_other, l_b);
+
+ /* step around to the opposite side of the quad - warning, this may have no other edges! */
+ l_a = l_a->next->next;
+ l_b = l_a->next;
+ if (!BM_edge_is_boundary(l_a->e)) {
+ /* same as above */
+ l_a_other = BM_edge_other_loop(l_a->e, l_a);
+ l_b_other = BM_edge_other_loop(l_a->e, l_b);
+ BM_elem_attrs_copy(bm, bm, l_a_other, l_a);
+ BM_elem_attrs_copy(bm, bm, l_b_other, l_b);
+ }
+ else { /* boundary edges have no useful data to copy from, use opposite side of face */
+ /* swap a<->b intentionally */
+ BM_elem_attrs_copy(bm, bm, l_a_other, l_b);
+ BM_elem_attrs_copy(bm, bm, l_b_other, l_a);
+ }
+ }
+#endif
}
/* we could flag new edges/verts too, is it useful? */
- BMO_slot_buffer_from_enabled_flag(bm, op, "faceout", BM_FACE, ELE_NEW);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "faces.out", BM_FACE, ELE_NEW);
/* cheap feature to add depth to the inset */
if (depth != 0.0f) {
@@ -514,7 +551,7 @@ void bmo_inset_exec(BMesh *bm, BMOperator *op)
BM_mesh_elem_hflag_disable_all(bm, BM_VERT, BM_ELEM_TAG, FALSE);
/* tag face verts */
- BMO_ITER (f, &oiter, bm, op, "faces", BM_FACE) {
+ BMO_ITER (f, &oiter, op->slots_in, "faces", BM_FACE) {
BM_ITER_ELEM (v, &iter, f, BM_VERTS_OF_FACE) {
BM_elem_flag_enable(v, BM_ELEM_TAG);
}
diff --git a/source/blender/bmesh/operators/bmo_join_triangles.c b/source/blender/bmesh/operators/bmo_join_triangles.c
index 3dbc0d0a5eb..1e18a83a0a0 100644
--- a/source/blender/bmesh/operators/bmo_join_triangles.c
+++ b/source/blender/bmesh/operators/bmo_join_triangles.c
@@ -204,16 +204,16 @@ void bmo_join_triangles_exec(BMesh *bm, BMOperator *op)
BMEdge *e;
BLI_array_declare(jedges);
JoinEdge *jedges = NULL;
- int do_sharp = BMO_slot_bool_get(op, "cmp_sharp");
- int do_uv = BMO_slot_bool_get(op, "cmp_uvs");
+ int do_sharp = BMO_slot_bool_get(op->slots_in, "cmp_sharp");
+ int do_uv = BMO_slot_bool_get(op->slots_in, "cmp_uvs");
int do_tf = do_uv; /* texture face, make make its own option eventually */
- int do_vcol = BMO_slot_bool_get(op, "cmp_vcols");
- int do_mat = BMO_slot_bool_get(op, "cmp_materials");
- float limit = BMO_slot_float_get(op, "limit");
+ int do_vcol = BMO_slot_bool_get(op->slots_in, "cmp_vcols");
+ int do_mat = BMO_slot_bool_get(op->slots_in, "cmp_materials");
+ float limit = BMO_slot_float_get(op->slots_in, "limit");
int i, totedge;
/* flag all edges of all input face */
- BMO_ITER (f, &siter, bm, op, "faces", BM_FACE) {
+ BMO_ITER (f, &siter, op->slots_in, "faces", BM_FACE) {
BMO_elem_flag_enable(bm, f, FACE_INPUT);
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
BMO_elem_flag_enable(bm, l->e, EDGE_MARK);
diff --git a/source/blender/bmesh/operators/bmo_mesh_conv.c b/source/blender/bmesh/operators/bmo_mesh_conv.c
index c4b988ae82d..4b897a24c8a 100644
--- a/source/blender/bmesh/operators/bmo_mesh_conv.c
+++ b/source/blender/bmesh/operators/bmo_mesh_conv.c
@@ -53,9 +53,9 @@
void bmo_mesh_to_bmesh_exec(BMesh *bm, BMOperator *op)
{
- Object *ob = BMO_slot_ptr_get(op, "object");
- Mesh *me = BMO_slot_ptr_get(op, "mesh");
- int set_key = BMO_slot_bool_get(op, "set_shapekey");
+ Object *ob = BMO_slot_ptr_get(op->slots_in, "object");
+ Mesh *me = BMO_slot_ptr_get(op->slots_in, "mesh");
+ int set_key = BMO_slot_bool_get(op->slots_in, "use_shapekey");
BM_mesh_bm_from_me(bm, me, set_key, ob->shapenr);
@@ -66,20 +66,20 @@ void bmo_mesh_to_bmesh_exec(BMesh *bm, BMOperator *op)
void bmo_object_load_bmesh_exec(BMesh *bm, BMOperator *op)
{
- Object *ob = BMO_slot_ptr_get(op, "object");
+ Object *ob = BMO_slot_ptr_get(op->slots_in, "object");
/* Scene *scene = BMO_slot_ptr_get(op, "scene"); */
Mesh *me = ob->data;
BMO_op_callf(bm, op->flag,
- "bmesh_to_mesh mesh=%p object=%p notessellation=%b",
+ "bmesh_to_mesh mesh=%p object=%p skip_tessface=%b",
me, ob, TRUE);
}
void bmo_bmesh_to_mesh_exec(BMesh *bm, BMOperator *op)
{
- Mesh *me = BMO_slot_ptr_get(op, "mesh");
+ Mesh *me = BMO_slot_ptr_get(op->slots_in, "mesh");
/* Object *ob = BMO_slot_ptr_get(op, "object"); */
- int dotess = !BMO_slot_bool_get(op, "notessellation");
+ int dotess = !BMO_slot_bool_get(op->slots_in, "skip_tessface");
BM_mesh_bm_to_me(bm, me, dotess);
}
diff --git a/source/blender/bmesh/operators/bmo_mirror.c b/source/blender/bmesh/operators/bmo_mirror.c
index 937601712b0..01bce976ec0 100644
--- a/source/blender/bmesh/operators/bmo_mirror.c
+++ b/source/blender/bmesh/operators/bmo_mirror.c
@@ -50,27 +50,28 @@ void bmo_mirror_exec(BMesh *bm, BMOperator *op)
float mtx[4][4];
float imtx[4][4];
float scale[3] = {1.0f, 1.0f, 1.0f};
- float dist = BMO_slot_float_get(op, "mergedist");
+ float dist = BMO_slot_float_get(op->slots_in, "merge_dist");
int i, ototvert /*, ototedge */;
- int axis = BMO_slot_int_get(op, "axis");
- int mirroru = BMO_slot_bool_get(op, "mirror_u");
- int mirrorv = BMO_slot_bool_get(op, "mirror_v");
+ int axis = BMO_slot_int_get(op->slots_in, "axis");
+ int mirroru = BMO_slot_bool_get(op->slots_in, "mirror_u");
+ int mirrorv = BMO_slot_bool_get(op->slots_in, "mirror_v");
+ BMOpSlot *slot_targetmap;
ototvert = bm->totvert;
/* ototedge = bm->totedge; */ /* UNUSED */
- BMO_slot_mat4_get(op, "mat", mtx);
+ BMO_slot_mat4_get(op->slots_in, "mat", 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, "newout", BM_ALL, ELE_NEW);
+ BMO_slot_buffer_flag_enable(bm, dupeop.slots_out, "geom.out", BM_ALL, ELE_NEW);
/* create old -> new mappin */
i = 0;
/* v2 = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL); */ /* UNUSED */
- BMO_ITER (v, &siter, bm, &dupeop, "newout", BM_VERT) {
+ BMO_ITER (v, &siter, dupeop.slots_out, "geom.out", BM_VERT) {
BLI_array_grow_one(vmap);
vmap[i] = v;
/* v2 = BM_iter_step(&iter); */ /* UNUSED */
@@ -86,10 +87,12 @@ void bmo_mirror_exec(BMesh *bm, BMOperator *op)
BMO_op_init(bm, &weldop, op->flag, "weld_verts");
+ slot_targetmap = BMO_slot_get(weldop.slots_in, "targetmap");
+
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(bm, &weldop, "targetmap", vmap[i], v);
+ BMO_slot_map_ptr_insert(&weldop, slot_targetmap, vmap[i], v);
}
v = BM_iter_step(&iter);
}
@@ -101,7 +104,7 @@ void bmo_mirror_exec(BMesh *bm, BMOperator *op)
int totlayer;
BMIter liter;
- BMO_ITER (f, &siter, bm, &dupeop, "newout", BM_FACE) {
+ BMO_ITER (f, &siter, dupeop.slots_out, "geom.out", BM_FACE) {
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
totlayer = CustomData_number_of_layers(&bm->ldata, CD_MLOOPUV);
for (i = 0; i < totlayer; i++) {
@@ -120,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, "newout", BM_ALL, ELE_NEW);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom.out", BM_ALL, 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 d7b163cb760..71f63bbaf28 100644
--- a/source/blender/bmesh/operators/bmo_primitive.c
+++ b/source/blender/bmesh/operators/bmo_primitive.c
@@ -227,16 +227,17 @@ static signed char monkeyf[250][4] = {
void bmo_create_grid_exec(BMesh *bm, BMOperator *op)
{
+ const float dia = BMO_slot_float_get(op->slots_in, "size");
+ const int tot = max_ii(2, BMO_slot_int_get(op->slots_in, "x_segments"));
+ const int seg = max_ii(2, BMO_slot_int_get(op->slots_in, "y_segments"));
+
BMOperator bmop, prevop;
BMVert *eve, *preveve;
BMEdge *e;
- float vec[3], mat[4][4], phi, phid, dia = BMO_slot_float_get(op, "size");
- int a, tot = BMO_slot_int_get(op, "xsegments"), seg = BMO_slot_int_get(op, "ysegments");
-
- if (tot < 2) tot = 2;
- if (seg < 2) seg = 2;
+ float vec[3], mat[4][4], phi, phid;
+ int a;
- BMO_slot_mat4_get(op, "mat", mat);
+ BMO_slot_mat4_get(op->slots_in, "mat", mat);
/* one segment first: the X axis */
phi = 1.0f;
@@ -267,39 +268,43 @@ void bmo_create_grid_exec(BMesh *bm, BMOperator *op)
for (a = 0; a < seg - 1; a++) {
if (a) {
- BMO_op_initf(bm, &bmop, op->flag, "extrude_edge_only edges=%s", &prevop, "geomout");
+ BMO_op_initf(bm, &bmop, op->flag, "extrude_edge_only edges=%S", &prevop, "geom.out");
BMO_op_exec(bm, &bmop);
BMO_op_finish(bm, &prevop);
- BMO_slot_buffer_flag_enable(bm, &bmop, "geomout", BM_VERT, VERT_MARK);
+ BMO_slot_buffer_flag_enable(bm, bmop.slots_out, "geom.out", BM_VERT, VERT_MARK);
}
else {
BMO_op_initf(bm, &bmop, op->flag, "extrude_edge_only edges=%fe", EDGE_ORIG);
BMO_op_exec(bm, &bmop);
- BMO_slot_buffer_flag_enable(bm, &bmop, "geomout", BM_VERT, VERT_MARK);
+ BMO_slot_buffer_flag_enable(bm, bmop.slots_out, "geom.out", BM_VERT, VERT_MARK);
}
- BMO_op_callf(bm, op->flag, "translate vec=%v verts=%s", vec, &bmop, "geomout");
+ BMO_op_callf(bm, op->flag, "translate vec=%v verts=%S", vec, &bmop, "geom.out");
prevop = bmop;
}
if (a)
BMO_op_finish(bm, &bmop);
- BMO_slot_buffer_from_enabled_flag(bm, op, "vertout", BM_VERT, VERT_MARK);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "verts.out", BM_VERT, VERT_MARK);
}
void bmo_create_uvsphere_exec(BMesh *bm, BMOperator *op)
{
+ const float dia = BMO_slot_float_get(op->slots_in, "diameter");
+ const int seg = BMO_slot_int_get(op->slots_in, "u_segments");
+ const int tot = BMO_slot_int_get(op->slots_in, "v_segments");
+
BMOperator bmop, prevop;
BMVert *eve, *preveve;
BMEdge *e;
BMIter iter;
float vec[3], mat[4][4], cmat[3][3], phi, q[4];
- float phid, dia = BMO_slot_float_get(op, "diameter");
- int a, seg = BMO_slot_int_get(op, "segments"), tot = BMO_slot_int_get(op, "revolutions");
+ float phid;
+ int a;
- BMO_slot_mat4_get(op, "mat", mat);
+ BMO_slot_mat4_get(op->slots_in, "mat", mat);
phid = 2.0f * (float)M_PI / tot;
/* phi = 0.25f * (float)M_PI; */ /* UNUSED */
@@ -333,7 +338,7 @@ void bmo_create_uvsphere_exec(BMesh *bm, BMOperator *op)
for (a = 0; a < seg; a++) {
if (a) {
- BMO_op_initf(bm, &bmop, op->flag, "extrude_edge_only edges=%s", &prevop, "geomout");
+ BMO_op_initf(bm, &bmop, op->flag, "extrude_edge_only edges=%S", &prevop, "geom.out");
BMO_op_exec(bm, &bmop);
BMO_op_finish(bm, &prevop);
}
@@ -342,8 +347,8 @@ void bmo_create_uvsphere_exec(BMesh *bm, BMOperator *op)
BMO_op_exec(bm, &bmop);
}
- BMO_slot_buffer_flag_enable(bm, &bmop, "geomout", BM_VERT, VERT_MARK);
- BMO_op_callf(bm, op->flag, "rotate cent=%v mat=%m3 verts=%s", vec, cmat, &bmop, "geomout");
+ 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");
prevop = bmop;
}
@@ -375,30 +380,33 @@ void bmo_create_uvsphere_exec(BMesh *bm, BMOperator *op)
}
}
- BMO_slot_buffer_from_enabled_flag(bm, op, "vertout", BM_VERT, VERT_MARK);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "verts.out", BM_VERT, VERT_MARK);
}
void bmo_create_icosphere_exec(BMesh *bm, BMOperator *op)
{
+ const float dia = BMO_slot_float_get(op->slots_in, "diameter");
+ const float dia_div = dia / 200.0f;
+ const int subdiv = BMO_slot_int_get(op->slots_in, "subdivisions");
+
BMVert *eva[12];
BMVert *v;
BMIter liter;
BMIter viter;
BMLoop *l;
float vec[3], mat[4][4] /* , phi, phid */;
- float dia = BMO_slot_float_get(op, "diameter");
- int a, subdiv = BMO_slot_int_get(op, "subdivisions");
+ int a;
- BMO_slot_mat4_get(op, "mat", mat);
+ BMO_slot_mat4_get(op->slots_in, "mat", mat);
/* phid = 2.0f * (float)M_PI / subdiv; */ /* UNUSED */
/* phi = 0.25f * (float)M_PI; */ /* UNUSED */
- dia /= 200.0f;
+
for (a = 0; a < 12; a++) {
- vec[0] = dia * icovert[a][0];
- vec[1] = dia * icovert[a][1];
- vec[2] = dia * icovert[a][2];
+ 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);
BMO_elem_flag_enable(bm, eva[a], VERT_MARK);
@@ -421,22 +429,20 @@ void bmo_create_icosphere_exec(BMesh *bm, BMOperator *op)
BMO_elem_flag_enable(bm, eftemp, FACE_MARK);
}
- dia *= 200.0f;
-
if (subdiv > 1) {
BMOperator bmop;
BMO_op_initf(bm, &bmop, op->flag,
"subdivide_edges edges=%fe "
"smooth=%f "
- "numcuts=%i "
+ "cuts=%i "
"use_gridfill=%b use_sphere=%b",
EDGE_MARK, dia, (1 << (subdiv - 1)) - 1,
TRUE, TRUE);
BMO_op_exec(bm, &bmop);
- BMO_slot_buffer_flag_enable(bm, &bmop, "geomout", BM_VERT, VERT_MARK);
- BMO_slot_buffer_flag_enable(bm, &bmop, "geomout", BM_EDGE, EDGE_MARK);
+ BMO_slot_buffer_flag_enable(bm, bmop.slots_out, "geom.out", BM_VERT, VERT_MARK);
+ BMO_slot_buffer_flag_enable(bm, bmop.slots_out, "geom.out", BM_EDGE, EDGE_MARK);
BMO_op_finish(bm, &bmop);
}
@@ -447,7 +453,7 @@ void bmo_create_icosphere_exec(BMesh *bm, BMOperator *op)
}
}
- BMO_slot_buffer_from_enabled_flag(bm, op, "vertout", BM_VERT, VERT_MARK);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "verts.out", BM_VERT, VERT_MARK);
}
void bmo_create_monkey_exec(BMesh *bm, BMOperator *op)
@@ -457,7 +463,7 @@ void bmo_create_monkey_exec(BMesh *bm, BMOperator *op)
float mat[4][4];
int i;
- BMO_slot_mat4_get(op, "mat", mat);
+ BMO_slot_mat4_get(op->slots_in, "mat", mat);
for (i = 0; i < monkeynv; i++) {
float v[3];
@@ -494,24 +500,25 @@ void bmo_create_monkey_exec(BMesh *bm, BMOperator *op)
MEM_freeN(tv);
- BMO_slot_buffer_from_enabled_flag(bm, op, "vertout", BM_VERT, VERT_MARK);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "verts.out", BM_VERT, VERT_MARK);
}
void bmo_create_circle_exec(BMesh *bm, BMOperator *op)
{
+ const float dia = BMO_slot_float_get(op->slots_in, "diameter");
+ const int segs = BMO_slot_int_get(op->slots_in, "segments");
+ const int cap_ends = BMO_slot_bool_get(op->slots_in, "cap_ends");
+ const int cap_tris = BMO_slot_bool_get(op->slots_in, "cap_tris");
+
BMVert *v1, *lastv1 = NULL, *cent1, *firstv1 = NULL;
float vec[3], mat[4][4], phi, phid;
- float dia = BMO_slot_float_get(op, "diameter");
- int segs = BMO_slot_int_get(op, "segments");
- int cap_ends = BMO_slot_bool_get(op, "cap_ends");
- int cap_tris = BMO_slot_bool_get(op, "cap_tris");
int a;
if (!segs)
return;
- BMO_slot_mat4_get(op, "mat", mat);
+ BMO_slot_mat4_get(op->slots_in, "mat", mat);
phid = 2.0f * (float)M_PI / segs;
phi = 0;
@@ -566,25 +573,25 @@ void bmo_create_circle_exec(BMesh *bm, BMOperator *op)
BMO_op_callf(bm, op->flag, "dissolve_faces faces=%ff", FACE_NEW);
}
- BMO_slot_buffer_from_enabled_flag(bm, op, "vertout", BM_VERT, VERT_MARK);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "verts.out", BM_VERT, VERT_MARK);
}
void bmo_create_cone_exec(BMesh *bm, BMOperator *op)
{
BMVert *v1, *v2, *lastv1 = NULL, *lastv2 = NULL, *cent1, *cent2, *firstv1, *firstv2;
float vec[3], mat[4][4], phi, phid;
- float dia1 = BMO_slot_float_get(op, "diameter1");
- float dia2 = BMO_slot_float_get(op, "diameter2");
- float depth = BMO_slot_float_get(op, "depth");
- int segs = BMO_slot_int_get(op, "segments");
- int cap_ends = BMO_slot_bool_get(op, "cap_ends");
- int cap_tris = BMO_slot_bool_get(op, "cap_tris");
+ float dia1 = BMO_slot_float_get(op->slots_in, "diameter1");
+ float dia2 = BMO_slot_float_get(op->slots_in, "diameter2");
+ float depth = BMO_slot_float_get(op->slots_in, "depth");
+ int segs = BMO_slot_int_get(op->slots_in, "segments");
+ int cap_ends = BMO_slot_bool_get(op->slots_in, "cap_ends");
+ int cap_tris = BMO_slot_bool_get(op->slots_in, "cap_tris");
int a;
if (!segs)
return;
- BMO_slot_mat4_get(op, "mat", mat);
+ BMO_slot_mat4_get(op->slots_in, "mat", mat);
phid = 2.0f * (float)M_PI / segs;
phi = 0;
@@ -662,15 +669,15 @@ void bmo_create_cone_exec(BMesh *bm, BMOperator *op)
BM_face_create_quad_tri(bm, v1, v2, firstv2, firstv1, NULL, FALSE);
BMO_op_callf(bm, op->flag, "remove_doubles verts=%fv dist=%f", VERT_MARK, 0.000001);
- BMO_slot_buffer_from_enabled_flag(bm, op, "vertout", BM_VERT, VERT_MARK);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "verts.out", BM_VERT, VERT_MARK);
}
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, "size") / 2.0f;
+ float vec[3], mat[4][4], off = BMO_slot_float_get(op->slots_in, "size") / 2.0f;
- BMO_slot_mat4_get(op, "mat", mat);
+ BMO_slot_mat4_get(op->slots_in, "mat", mat);
if (!off) off = 0.5f;
@@ -740,5 +747,5 @@ void bmo_create_cube_exec(BMesh *bm, BMOperator *op)
BM_face_create_quad_tri(bm, v1, v2, v3, v4, NULL, FALSE);
BM_face_create_quad_tri(bm, v8, v7, v6, v5, NULL, FALSE);
- BMO_slot_buffer_from_enabled_flag(bm, op, "vertout", BM_VERT, VERT_MARK);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "verts.out", BM_VERT, VERT_MARK);
}
diff --git a/source/blender/bmesh/operators/bmo_removedoubles.c b/source/blender/bmesh/operators/bmo_removedoubles.c
index ea6cd747037..45e678b96bb 100644
--- a/source/blender/bmesh/operators/bmo_removedoubles.c
+++ b/source/blender/bmesh/operators/bmo_removedoubles.c
@@ -36,7 +36,7 @@
#include "intern/bmesh_operators_private.h" /* own include */
-static void remdoubles_splitface(BMFace *f, BMesh *bm, BMOperator *op)
+static void remdoubles_splitface(BMFace *f, BMesh *bm, BMOperator *op, BMOpSlot *slot_targetmap)
{
BMIter liter;
BMLoop *l;
@@ -44,7 +44,7 @@ static void remdoubles_splitface(BMFace *f, BMesh *bm, BMOperator *op)
int split = FALSE;
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
- v2 = BMO_slot_map_ptr_get(bm, op, "targetmap", l->v);
+ v2 = BMO_slot_map_ptr_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)) &&
@@ -61,8 +61,8 @@ static void remdoubles_splitface(BMFace *f, BMesh *bm, BMOperator *op)
BMLoop *nl;
BMFace *f2 = BM_face_split(bm, f, doub, v2, &nl, NULL, FALSE);
- remdoubles_splitface(f, bm, op);
- remdoubles_splitface(f2, bm, op);
+ remdoubles_splitface(f, bm, op, slot_targetmap);
+ remdoubles_splitface(f2, bm, op, slot_targetmap);
}
}
@@ -106,10 +106,11 @@ void bmo_weld_verts_exec(BMesh *bm, BMOperator *op)
BLI_array_declare(loops);
BMFace *f, *f2;
int a, b;
+ BMOpSlot *slot_targetmap = BMO_slot_get(op->slots_in, "targetmap");
/* mark merge verts for deletion */
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
- if ((v2 = BMO_slot_map_ptr_get(bm, op, "targetmap", v))) {
+ if ((v2 = BMO_slot_map_ptr_get(slot_targetmap, v))) {
BMO_elem_flag_enable(bm, v, ELE_DEL);
/* merge the vertex flags, else we get randomly selected/unselected verts */
@@ -120,13 +121,13 @@ void bmo_weld_verts_exec(BMesh *bm, BMOperator *op)
/* check if any faces are getting their own corners merged
* together, split face if so */
BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
- remdoubles_splitface(f, bm, op);
+ remdoubles_splitface(f, bm, op, slot_targetmap);
}
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(bm, op, "targetmap", e->v1);
- v2 = BMO_slot_map_ptr_get(bm, op, "targetmap", e->v2);
+ v = BMO_slot_map_ptr_get(slot_targetmap, e->v1);
+ v2 = BMO_slot_map_ptr_get(slot_targetmap, e->v2);
if (!v) v = e->v1;
if (!v2) v2 = e->v2;
@@ -174,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(bm, op, "targetmap", v);
+ v = BMO_slot_map_ptr_get(slot_targetmap, v);
}
if (BMO_elem_flag_test(bm, v2, ELE_DEL)) {
- v2 = BMO_slot_map_ptr_get(bm, op, "targetmap", v2);
+ v2 = BMO_slot_map_ptr_get(slot_targetmap, v2);
}
e2 = v != v2 ? BM_edge_exists(v, v2) : NULL;
@@ -207,10 +208,10 @@ 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(bm, op, "targetmap", v);
+ v = BMO_slot_map_ptr_get(slot_targetmap, v);
}
if (BMO_elem_flag_test(bm, v2, ELE_DEL)) {
- v2 = BMO_slot_map_ptr_get(bm, op, "targetmap", v2);
+ v2 = BMO_slot_map_ptr_get(slot_targetmap, v2);
}
f2 = BM_face_create_ngon(bm, v, v2, edges, a, TRUE);
@@ -262,7 +263,7 @@ void bmo_pointmerge_facedata_exec(BMesh *bm, BMOperator *op)
float fac;
int i, tot;
- snapv = BMO_iter_new(&siter, bm, op, "snapv", BM_VERT);
+ snapv = BMO_iter_new(&siter, op->slots_in, "snapv", BM_VERT);
tot = BM_vert_face_count(snapv);
if (!tot)
@@ -290,7 +291,7 @@ void bmo_pointmerge_facedata_exec(BMesh *bm, BMOperator *op)
}
}
- BMO_ITER (v, &siter, bm, op, "verts", BM_VERT) {
+ BMO_ITER (v, &siter, op->slots_in, "verts", BM_VERT) {
BM_ITER_ELEM (l, &iter, v, BM_LOOPS_OF_VERT) {
if (l == firstl) {
continue;
@@ -318,7 +319,7 @@ void bmo_average_vert_facedata_exec(BMesh *bm, BMOperator *op)
type = bm->ldata.layers[i].type;
CustomData_data_initminmax(type, &min, &max);
- BMO_ITER (v, &siter, bm, op, "verts", BM_VERT) {
+ BMO_ITER (v, &siter, op->slots_in, "verts", BM_VERT) {
BM_ITER_ELEM (l, &iter, v, BM_LOOPS_OF_VERT) {
block = CustomData_bmesh_get_layer_n(&bm->ldata, l->head.data, i);
CustomData_data_dominmax(type, block, &min, &max);
@@ -329,7 +330,7 @@ void bmo_average_vert_facedata_exec(BMesh *bm, BMOperator *op)
CustomData_data_multiply(type, &max, 0.5f);
CustomData_data_add(type, &min, &max);
- BMO_ITER (v, &siter, bm, op, "verts", BM_VERT) {
+ BMO_ITER (v, &siter, op->slots_in, "verts", BM_VERT) {
BM_ITER_ELEM (l, &iter, v, BM_LOOPS_OF_VERT) {
block = CustomData_bmesh_get_layer_n(&bm->ldata, l->head.data, i);
CustomData_data_copy_value(type, &min, block);
@@ -344,19 +345,22 @@ void bmo_pointmerge_exec(BMesh *bm, BMOperator *op)
BMOIter siter;
BMVert *v, *snapv = NULL;
float vec[3];
+ BMOpSlot *slot_targetmap;
- BMO_slot_vec_get(op, "merge_co", vec);
+ BMO_slot_vec_get(op->slots_in, "merge_co", vec);
//BMO_op_callf(bm, op->flag, "collapse_uvs edges=%s", op, "edges");
BMO_op_init(bm, &weldop, op->flag, "weld_verts");
-
- BMO_ITER (v, &siter, bm, op, "verts", BM_VERT) {
+
+ 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);
}
else {
- BMO_slot_map_ptr_insert(bm, &weldop, "targetmap", v, snapv);
+ BMO_slot_map_ptr_insert(&weldop, slot_targetmap, v, snapv);
}
}
@@ -373,11 +377,13 @@ void bmo_collapse_exec(BMesh *bm, BMOperator *op)
BLI_array_declare(edges);
float min[3], max[3], center[3];
int i, tot;
+ BMOpSlot *slot_targetmap;
BMO_op_callf(bm, op->flag, "collapse_uvs edges=%s", op, "edges");
BMO_op_init(bm, &weldop, op->flag, "weld_verts");
+ slot_targetmap = BMO_slot_get(weldop.slots_in, "targetmap");
- BMO_slot_buffer_flag_enable(bm, op, "edges", BM_EDGE, EDGE_MARK);
+ BMO_slot_buffer_flag_enable(bm, op->slots_in, "edges", BM_EDGE, EDGE_MARK);
BMW_init(&walker, bm, BMW_SHELL,
BMW_MASK_NOP, EDGE_MARK, BMW_MASK_NOP,
@@ -408,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(bm, &weldop, "targetmap", edges[i]->v1, edges[0]->v1);
+ BMO_slot_map_ptr_insert(&weldop, slot_targetmap, edges[i]->v1, edges[0]->v1);
if (edges[i]->v2 != edges[0]->v1)
- BMO_slot_map_ptr_insert(bm, &weldop, "targetmap", edges[i]->v2, edges[0]->v1);
+ BMO_slot_map_ptr_insert(&weldop, slot_targetmap, edges[i]->v2, edges[0]->v1);
}
}
@@ -436,7 +442,7 @@ static void bmo_collapsecon_do_layer(BMesh *bm, BMOperator *op, int layer)
/* clear all short flags */
BMO_mesh_flag_disable_all(bm, op, BM_ALL, (1 << 16) - 1);
- BMO_slot_buffer_flag_enable(bm, op, "edges", BM_EDGE, EDGE_MARK);
+ BMO_slot_buffer_flag_enable(bm, op->slots_in, "edges", BM_EDGE, EDGE_MARK);
BMW_init(&walker, bm, BMW_LOOPDATA_ISLAND,
BMW_MASK_NOP, EDGE_MARK, BMW_MASK_NOP,
@@ -486,31 +492,32 @@ void bmo_collapse_uvs_exec(BMesh *bm, BMOperator *op)
}
}
-static void bmesh_find_doubles_common(BMesh *bm, BMOperator *op, BMOperator *optarget, const char *targetmapname)
+static void bmesh_find_doubles_common(BMesh *bm, BMOperator *op,
+ BMOperator *optarget, BMOpSlot *optarget_slot)
{
BMVert **verts;
int verts_len;
int i, j, keepvert = 0;
- const float dist = BMO_slot_float_get(op, "dist");
+ const float dist = BMO_slot_float_get(op->slots_in, "dist");
const float dist3 = dist * 3.0f;
/* Test whether keep_verts arg exists and is non-empty */
- if (BMO_slot_exists(op, "keep_verts")) {
+ if (BMO_slot_exists(op->slots_in, "keep_verts")) {
BMOIter oiter;
- keepvert = BMO_iter_new(&oiter, bm, op, "keep_verts", BM_VERT) != NULL;
+ keepvert = BMO_iter_new(&oiter, op->slots_in, "keep_verts", BM_VERT) != NULL;
}
/* get the verts as an array we can sort */
- verts = BMO_slot_as_arrayN(op, "verts", &verts_len);
+ verts = BMO_slot_as_arrayN(op->slots_in, "verts", &verts_len);
/* sort by vertex coordinates added together */
qsort(verts, verts_len, sizeof(BMVert *), vergaverco);
/* Flag keep_verts */
if (keepvert) {
- BMO_slot_buffer_flag_enable(bm, op, "keep_verts", BM_VERT, VERT_KEEP);
+ BMO_slot_buffer_flag_enable(bm, op->slots_in, "keep_verts", BM_VERT, VERT_KEEP);
}
for (i = 0; i < verts_len; i++) {
@@ -547,7 +554,7 @@ static void bmesh_find_doubles_common(BMesh *bm, BMOperator *op, BMOperator *opt
BMO_elem_flag_enable(bm, v_other, VERT_DOUBLE);
BMO_elem_flag_enable(bm, v_check, VERT_TARGET);
- BMO_slot_map_ptr_insert(bm, optarget, targetmapname, v_other, v_check);
+ BMO_slot_map_ptr_insert(optarget, optarget_slot, v_other, v_check);
}
}
}
@@ -558,9 +565,12 @@ static void bmesh_find_doubles_common(BMesh *bm, BMOperator *op, BMOperator *opt
void bmo_remove_doubles_exec(BMesh *bm, BMOperator *op)
{
BMOperator weldop;
+ BMOpSlot *slot_targetmap;
BMO_op_init(bm, &weldop, op->flag, "weld_verts");
- bmesh_find_doubles_common(bm, op, &weldop, "targetmap");
+ slot_targetmap = BMO_slot_get(weldop.slots_in, "targetmap");
+ bmesh_find_doubles_common(bm, op,
+ &weldop, slot_targetmap);
BMO_op_exec(bm, &weldop);
BMO_op_finish(bm, &weldop);
}
@@ -568,7 +578,10 @@ void bmo_remove_doubles_exec(BMesh *bm, BMOperator *op)
void bmo_find_doubles_exec(BMesh *bm, BMOperator *op)
{
- bmesh_find_doubles_common(bm, op, op, "targetmapout");
+ BMOpSlot *slot_targetmap_out;
+ slot_targetmap_out = BMO_slot_get(op->slots_out, "targetmap.out");
+ bmesh_find_doubles_common(bm, op,
+ op, slot_targetmap_out);
}
void bmo_automerge_exec(BMesh *bm, BMOperator *op)
@@ -580,7 +593,7 @@ void bmo_automerge_exec(BMesh *bm, BMOperator *op)
/* The "verts" input sent to this op is the set of verts that
* can be merged away into any other verts. Mark all other verts
* as VERT_KEEP. */
- BMO_slot_buffer_flag_enable(bm, op, "verts", BM_VERT, VERT_IN);
+ BMO_slot_buffer_flag_enable(bm, op->slots_in, "verts", BM_VERT, VERT_IN);
BM_ITER_MESH (v, &viter, bm, BM_VERTS_OF_MESH) {
if (!BMO_elem_flag_test(bm, v, VERT_IN)) {
BMO_elem_flag_enable(bm, v, VERT_KEEP);
@@ -590,12 +603,14 @@ void bmo_automerge_exec(BMesh *bm, BMOperator *op)
/* Search for doubles among all vertices, but only merge non-VERT_KEEP
* vertices into VERT_KEEP vertices. */
BMO_op_initf(bm, &findop, op->flag, "find_doubles verts=%av keep_verts=%fv", VERT_KEEP);
- BMO_slot_copy(op, &findop, "dist", "dist");
+ BMO_slot_copy(op, slots_in, "dist",
+ &findop, slots_in, "dist");
BMO_op_exec(bm, &findop);
/* weld the vertices */
BMO_op_init(bm, &weldop, op->flag, "weld_verts");
- BMO_slot_copy(&findop, &weldop, "targetmapout", "targetmap");
+ BMO_slot_copy(&findop, slots_out, "targetmap.out",
+ &weldop, slots_in, "targetmap");
BMO_op_exec(bm, &weldop);
BMO_op_finish(bm, &findop);
diff --git a/source/blender/bmesh/operators/bmo_similar.c b/source/blender/bmesh/operators/bmo_similar.c
index df03e50d2c4..548e1adf17d 100644
--- a/source/blender/bmesh/operators/bmo_similar.c
+++ b/source/blender/bmesh/operators/bmo_similar.c
@@ -103,10 +103,10 @@ void bmo_similar_faces_exec(BMesh *bm, BMOperator *op)
SimSel_FaceExt *f_ext = NULL;
int *indices = NULL;
float t_no[3]; /* temporary normal */
- const int type = BMO_slot_int_get(op, "type");
- const float thresh = BMO_slot_float_get(op, "thresh");
+ const int type = BMO_slot_int_get(op->slots_in, "type");
+ const float thresh = BMO_slot_float_get(op->slots_in, "thresh");
const float thresh_radians = thresh * (float)M_PI;
- const int compare = BMO_slot_int_get(op, "compare");
+ const int compare = BMO_slot_int_get(op->slots_in, "compare");
/* initial_elem - other_elem */
float delta_fl;
@@ -121,7 +121,7 @@ void bmo_similar_faces_exec(BMesh *bm, BMOperator *op)
* so the overall complexity will be less than $O(mn)$ where is the total number of selected faces,
* and n is the total number of faces
*/
- BMO_ITER (fs, &fs_iter, bm, op, "faces", BM_FACE) {
+ BMO_ITER (fs, &fs_iter, op->slots_in, "faces", BM_FACE) {
if (!BMO_elem_flag_test(bm, fs, FACE_MARK)) { /* is this really needed ? */
BMO_elem_flag_enable(bm, fs, FACE_MARK);
num_sels++;
@@ -256,7 +256,7 @@ void bmo_similar_faces_exec(BMesh *bm, BMOperator *op)
MEM_freeN(indices);
/* transfer all marked faces to the output slot */
- BMO_slot_buffer_from_enabled_flag(bm, op, "faceout", BM_FACE, FACE_MARK);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "faces.out", BM_FACE, FACE_MARK);
#undef FACE_MARK
}
@@ -299,9 +299,9 @@ void bmo_similar_edges_exec(BMesh *bm, BMOperator *op)
float angle;
int num_sels = 0, num_total = 0;
- const int type = BMO_slot_int_get(op, "type");
- const float thresh = BMO_slot_float_get(op, "thresh");
- const int compare = BMO_slot_int_get(op, "compare");
+ const int type = BMO_slot_int_get(op->slots_in, "type");
+ const float thresh = BMO_slot_float_get(op->slots_in, "thresh");
+ const int compare = BMO_slot_int_get(op->slots_in, "compare");
/* initial_elem - other_elem */
float delta_fl;
@@ -324,7 +324,7 @@ void bmo_similar_edges_exec(BMesh *bm, BMOperator *op)
num_total = BM_mesh_elem_count(bm, BM_EDGE);
/* iterate through all selected edges and mark them */
- BMO_ITER (es, &es_iter, bm, op, "edges", BM_EDGE) {
+ BMO_ITER (es, &es_iter, op->slots_in, "edges", BM_EDGE) {
BMO_elem_flag_enable(bm, es, EDGE_MARK);
num_sels++;
}
@@ -474,7 +474,7 @@ void bmo_similar_edges_exec(BMesh *bm, BMOperator *op)
MEM_freeN(indices);
/* transfer all marked edges to the output slot */
- BMO_slot_buffer_from_enabled_flag(bm, op, "edgeout", BM_EDGE, EDGE_MARK);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "edges.out", BM_EDGE, EDGE_MARK);
#undef EDGE_MARK
}
@@ -507,10 +507,10 @@ void bmo_similar_verts_exec(BMesh *bm, BMOperator *op)
SimSel_VertExt *v_ext = NULL;
int *indices = NULL;
int num_total = 0, num_sels = 0, i = 0, idx = 0;
- const int type = BMO_slot_int_get(op, "type");
- const float thresh = BMO_slot_float_get(op, "thresh");
+ const int type = BMO_slot_int_get(op->slots_in, "type");
+ const float thresh = BMO_slot_float_get(op->slots_in, "thresh");
const float thresh_radians = thresh * (float)M_PI;
- const int compare = BMO_slot_int_get(op, "compare");
+ const int compare = BMO_slot_int_get(op->slots_in, "compare");
/* initial_elem - other_elem */
// float delta_fl;
@@ -519,7 +519,7 @@ void bmo_similar_verts_exec(BMesh *bm, BMOperator *op)
num_total = BM_mesh_elem_count(bm, BM_VERT);
/* iterate through all selected edges and mark them */
- BMO_ITER (vs, &vs_iter, bm, op, "verts", BM_VERT) {
+ BMO_ITER (vs, &vs_iter, op->slots_in, "verts", BM_VERT) {
BMO_elem_flag_enable(bm, vs, VERT_MARK);
num_sels++;
}
@@ -608,7 +608,7 @@ void bmo_similar_verts_exec(BMesh *bm, BMOperator *op)
MEM_freeN(indices);
MEM_freeN(v_ext);
- BMO_slot_buffer_from_enabled_flag(bm, op, "vertout", BM_VERT, VERT_MARK);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "verts.out", BM_VERT, VERT_MARK);
#undef VERT_MARK
}
diff --git a/source/blender/bmesh/operators/bmo_slide.c b/source/blender/bmesh/operators/bmo_slide.c
index 6db76119205..9dde2461364 100644
--- a/source/blender/bmesh/operators/bmo_slide.c
+++ b/source/blender/bmesh/operators/bmo_slide.c
@@ -53,10 +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, "distance_t");
+ const float distance_t = BMO_slot_float_get(op->slots_in, "distance_t");
/* Get start vertex */
- vertex = BMO_iter_new(&oiter, bm, op, "vert", BM_VERT);
+ vertex = BMO_iter_new(&oiter, op->slots_in, "vert", BM_VERT);
if (!vertex) {
@@ -68,7 +68,7 @@ void bmo_slide_vert_exec(BMesh *bm, BMOperator *op)
}
/* Count selected edges */
- BMO_ITER (h, &oiter, bm, op, "edge", BM_VERT | BM_EDGE) {
+ BMO_ITER (h, &oiter, op->slots_in, "edge", BM_VERT | BM_EDGE) {
switch (h->htype) {
case BM_EDGE:
selected_edges++;
@@ -108,7 +108,7 @@ void bmo_slide_vert_exec(BMesh *bm, BMOperator *op)
}
/* Return the new edge. The same previously marked with VERT_MARK */
- BMO_slot_buffer_from_enabled_flag(bm, op, "vertout", BM_VERT, VERT_MARK);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "verts.out", BM_VERT, VERT_MARK);
return;
}
diff --git a/source/blender/bmesh/operators/bmo_smooth_laplacian.c b/source/blender/bmesh/operators/bmo_smooth_laplacian.c
index 362123e412d..4137c31961c 100644
--- a/source/blender/bmesh/operators/bmo_smooth_laplacian.c
+++ b/source/blender/bmesh/operators/bmo_smooth_laplacian.c
@@ -78,8 +78,8 @@ static void delete_laplacian_system(LaplacianSystem *sys);
static void delete_void_pointer(void *data);
static void fill_laplacian_matrix(LaplacianSystem *sys);
static void memset_laplacian_system(LaplacianSystem *sys, int val);
-static void validate_solution(LaplacianSystem *sys, int usex, int usey, int usez, int volumepreservation);
-static void volume_preservation(BMesh *bm, BMOperator *op, float vini, float vend, int usex, int usey, int usez);
+static void validate_solution(LaplacianSystem *sys, int usex, int usey, int usez, int preserve_volume);
+static void volume_preservation(BMOperator *op, float vini, float vend, int usex, int usey, int usez);
static void delete_void_pointer(void *data)
{
@@ -455,7 +455,7 @@ static float compute_volume(BMesh *bm)
return fabs(vol);
}
-static void volume_preservation(BMesh *bm, BMOperator *op, float vini, float vend, int usex, int usey, int usez)
+static void volume_preservation(BMOperator *op, float vini, float vend, int usex, int usey, int usez)
{
float beta;
BMOIter siter;
@@ -463,9 +463,9 @@ static void volume_preservation(BMesh *bm, BMOperator *op, float vini, float ven
if (vend != 0.0f) {
beta = pow(vini / vend, 1.0f / 3.0f);
- BMO_ITER (v, &siter, bm, op, "verts", BM_VERT) {
+ BMO_ITER (v, &siter, op->slots_in, "verts", BM_VERT) {
if (usex) {
- v->co[0] *= beta;
+ v->co[0] *= beta;
}
if (usey) {
v->co[1] *= beta;
@@ -478,7 +478,7 @@ static void volume_preservation(BMesh *bm, BMOperator *op, float vini, float ven
}
}
-static void validate_solution(LaplacianSystem *sys, int usex, int usey, int usez, int volumepreservation)
+static void validate_solution(LaplacianSystem *sys, int usex, int usey, int usez, int preserve_volume)
{
int m_vertex_id;
float leni, lene;
@@ -509,10 +509,10 @@ static void validate_solution(LaplacianSystem *sys, int usex, int usey, int usez
}
}
- if (volumepreservation) {
+ if (preserve_volume) {
vini = compute_volume(sys->bm);
}
- BMO_ITER (v, &siter, sys->bm, sys->op, "verts", BM_VERT) {
+ BMO_ITER (v, &siter, sys->op->slots_in, "verts", BM_VERT) {
m_vertex_id = BM_elem_index_get(v);
if (sys->zerola[m_vertex_id] == 0) {
if (usex) {
@@ -526,9 +526,9 @@ static void validate_solution(LaplacianSystem *sys, int usex, int usey, int usez
}
}
}
- if (volumepreservation) {
+ if (preserve_volume) {
vend = compute_volume(sys->bm);
- volume_preservation(sys->bm, sys->op, vini, vend, usex, usey, usez);
+ volume_preservation(sys->op, vini, vend, usex, usey, usez);
}
}
@@ -537,7 +537,7 @@ void bmo_smooth_laplacian_vert_exec(BMesh *bm, BMOperator *op)
{
int i;
int m_vertex_id;
- int usex, usey, usez, volumepreservation;
+ int usex, usey, usez, preserve_volume;
float lambda, lambda_border;
float w;
BMOIter siter;
@@ -552,13 +552,13 @@ void bmo_smooth_laplacian_vert_exec(BMesh *bm, BMOperator *op)
memset_laplacian_system(sys, 0);
BM_mesh_elem_index_ensure(bm, BM_VERT);
- lambda = BMO_slot_float_get(op, "lambda");
- lambda_border = BMO_slot_float_get(op, "lambda_border");
+ lambda = BMO_slot_float_get(op->slots_in, "lambda");
+ lambda_border = BMO_slot_float_get(op->slots_in, "lambda_border");
sys->min_area = 0.00001f;
- usex = BMO_slot_bool_get(op, "use_x");
- usey = BMO_slot_bool_get(op, "use_y");
- usez = BMO_slot_bool_get(op, "use_z");
- volumepreservation = BMO_slot_bool_get(op, "volume_preservation");
+ usex = BMO_slot_bool_get(op->slots_in, "use_x");
+ usey = BMO_slot_bool_get(op->slots_in, "use_y");
+ usez = BMO_slot_bool_get(op->slots_in, "use_z");
+ preserve_volume = BMO_slot_bool_get(op->slots_in, "preserve_volume");
nlNewContext();
@@ -573,7 +573,7 @@ void bmo_smooth_laplacian_vert_exec(BMesh *bm, BMOperator *op)
for (i = 0; i < bm->totvert; i++) {
nlLockVariable(i);
}
- BMO_ITER (v, &siter, bm, op, "verts", BM_VERT) {
+ BMO_ITER (v, &siter, op->slots_in, "verts", BM_VERT) {
m_vertex_id = BM_elem_index_get(v);
nlUnlockVariable(m_vertex_id);
nlSetVariable(0, m_vertex_id, v->co[0]);
@@ -583,7 +583,7 @@ void bmo_smooth_laplacian_vert_exec(BMesh *bm, BMOperator *op)
nlBegin(NL_MATRIX);
init_laplacian_matrix(sys);
- BMO_ITER (v, &siter, bm, op, "verts", BM_VERT) {
+ BMO_ITER (v, &siter, op->slots_in, "verts", BM_VERT) {
m_vertex_id = BM_elem_index_get(v);
nlRightHandSideAdd(0, m_vertex_id, v->co[0]);
nlRightHandSideAdd(1, m_vertex_id, v->co[1]);
@@ -612,7 +612,7 @@ void bmo_smooth_laplacian_vert_exec(BMesh *bm, BMOperator *op)
nlEnd(NL_SYSTEM);
if (nlSolveAdvanced(NULL, NL_TRUE) ) {
- validate_solution(sys, usex, usey, usez, volumepreservation);
+ validate_solution(sys, usex, usey, usez, preserve_volume);
}
delete_laplacian_system(sys);
diff --git a/source/blender/bmesh/operators/bmo_subdivide.c b/source/blender/bmesh/operators/bmo_subdivide.c
index f6b9b18d716..f9b6611c88b 100644
--- a/source/blender/bmesh/operators/bmo_subdivide.c
+++ b/source/blender/bmesh/operators/bmo_subdivide.c
@@ -165,7 +165,7 @@ static void alter_co(BMesh *bm, BMVert *v, BMEdge *UNUSED(origed), const SubDPar
}
/* apply the new difference to the rest of the shape keys,
- * note that this doent take rotations into account, we _could_ support
+ * note that this dosn't take rotations into account, we _could_ support
* this by getting the normals and coords for each shape key and
* re-calculate the smooth value for each but this is quite involved.
* for now its ok to simply apply the difference IMHO - campbell */
@@ -225,8 +225,9 @@ static BMVert *subdivideedgenum(BMesh *bm, BMEdge *edge, BMEdge *oedge,
BMVert *ev;
float percent, percent2 = 0.0f;
- if (BMO_elem_flag_test(bm, edge, EDGE_PERCENT) && totpoint == 1)
- percent = BMO_slot_map_float_get(bm, params->op, "edgepercents", edge);
+ if (BMO_elem_flag_test(bm, edge, EDGE_PERCENT) && totpoint == 1) {
+ percent = BMO_slot_map_float_get(params->slot_edgepercents, edge);
+ }
else {
percent = 1.0f / (float)(totpoint + 1 - curpoint);
percent2 = (float)(curpoint + 1) / (float)(totpoint + 1);
@@ -717,18 +718,18 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
int use_sphere, cornertype, use_singleedge, use_gridfill;
int skey, seed, i, j, matched, a, b, numcuts, totesel;
- BMO_slot_buffer_flag_enable(bm, op, "edges", BM_EDGE, SUBD_SPLIT);
+ BMO_slot_buffer_flag_enable(bm, op->slots_in, "edges", BM_EDGE, SUBD_SPLIT);
- numcuts = BMO_slot_int_get(op, "numcuts");
- seed = BMO_slot_int_get(op, "seed");
- smooth = BMO_slot_float_get(op, "smooth");
- fractal = BMO_slot_float_get(op, "fractal");
- along_normal = BMO_slot_float_get(op, "along_normal");
- cornertype = BMO_slot_int_get(op, "quadcornertype");
-
- use_singleedge = BMO_slot_bool_get(op, "use_singleedge");
- use_gridfill = BMO_slot_bool_get(op, "use_gridfill");
- use_sphere = BMO_slot_bool_get(op, "use_sphere");
+ numcuts = BMO_slot_int_get(op->slots_in, "cuts");
+ seed = BMO_slot_int_get(op->slots_in, "seed");
+ smooth = BMO_slot_float_get(op->slots_in, "smooth");
+ fractal = BMO_slot_float_get(op->slots_in, "fractal");
+ 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");
BLI_srandom(seed);
@@ -774,10 +775,12 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
}
/* first go through and tag edges */
- BMO_slot_buffer_from_enabled_flag(bm, op, "edges", BM_EDGE, SUBD_SPLIT);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_in, "edges", BM_EDGE, SUBD_SPLIT);
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.smooth = smooth;
params.seed = seed;
params.fractal = fractal;
@@ -790,10 +793,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, "custompatterns",
+ BMO_slot_map_to_flag(bm, op->slots_in, "custompatterns",
BM_FACE, FACE_CUSTOMFILL);
- BMO_slot_map_to_flag(bm, op, "edgepercents",
+ BMO_slot_map_to_flag(bm, op->slots_in, "edgepercents",
BM_EDGE, EDGE_PERCENT);
@@ -837,8 +840,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(bm, op,
- "custompatterns", face);
+ pat = BMO_slot_map_data_get(params.slot_custompatterns, face);
for (i = 0; i < pat->len; i++) {
matched = 1;
for (j = 0; j < pat->len; j++) {
@@ -910,11 +912,11 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
}
}
- einput = BMO_slot_get(op, "edges");
+ einput = BMO_slot_get(op->slots_in, "edges");
/* go through and split edges */
for (i = 0; i < einput->len; i++) {
- edge = ((BMEdge **)einput->data.p)[i];
+ edge = einput->data.buf[i];
bm_subdivide_multicut(bm, edge, &params, edge->v1, edge->v2);
}
@@ -1075,10 +1077,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, "outinner", BM_ALL, ELE_INNER);
- BMO_slot_buffer_from_enabled_flag(bm, op, "outsplit", BM_ALL, ELE_SPLIT);
+ 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, "geomout", BM_ALL, ELE_INNER | ELE_SPLIT | SUBD_SPLIT);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom.out", BM_ALL, ELE_INNER | ELE_SPLIT | SUBD_SPLIT);
}
/* editmesh-emulating function */
@@ -1095,8 +1097,8 @@ void BM_mesh_esubdivide(BMesh *bm, const char edge_hflag,
BMO_op_initf(bm, &op, BMO_FLAG_DEFAULTS,
"subdivide_edges edges=%he "
"smooth=%f fractal=%f along_normal=%f "
- "numcuts=%i "
- "quadcornertype=%i "
+ "cuts=%i "
+ "quad_corner_type=%i "
"use_singleedge=%b use_gridfill=%b "
"seed=%i",
edge_hflag,
@@ -1112,7 +1114,7 @@ void BM_mesh_esubdivide(BMesh *bm, const char edge_hflag,
BMOIter iter;
BMElem *ele;
- for (ele = BMO_iter_new(&iter, bm, &op, "outinner", BM_EDGE | BM_VERT); ele; ele = BMO_iter_step(&iter)) {
+ for (ele = BMO_iter_new(&iter, op.slots_out, "geom_inner.out", BM_EDGE | BM_VERT); ele; ele = BMO_iter_step(&iter)) {
BM_elem_select_set(bm, ele, TRUE);
}
}
@@ -1123,7 +1125,7 @@ void BM_mesh_esubdivide(BMesh *bm, const char edge_hflag,
/* deselect input */
BM_mesh_elem_hflag_disable_all(bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_SELECT, FALSE);
- for (ele = BMO_iter_new(&iter, bm, &op, "outinner", BM_EDGE | BM_VERT); ele; ele = BMO_iter_step(&iter)) {
+ for (ele = BMO_iter_new(&iter, op.slots_out, "geom_inner.out", BM_EDGE | BM_VERT); ele; ele = BMO_iter_step(&iter)) {
BM_elem_select_set(bm, ele, TRUE);
if (ele->head.htype == BM_VERT) {
@@ -1158,8 +1160,9 @@ void bmo_bisect_edges_exec(BMesh *bm, BMOperator *op)
SubDParams params = {0};
int skey;
- params.numcuts = BMO_slot_int_get(op, "numcuts");
+ params.numcuts = BMO_slot_int_get(op->slots_in, "cuts");
params.op = op;
+ params.slot_edgepercents = BMO_slot_get(op->slots_in, "edgepercents");
BM_data_layer_add(bm, &bm->vdata, CD_SHAPEKEY);
skey = CustomData_number_of_layers(&bm->vdata, CD_SHAPEKEY) - 1;
@@ -1167,11 +1170,11 @@ void bmo_bisect_edges_exec(BMesh *bm, BMOperator *op)
params.origkey = skey;
/* go through and split edges */
- BMO_ITER (e, &siter, bm, op, "edges", BM_EDGE) {
+ BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) {
bm_subdivide_multicut(bm, e, &params, e->v1, e->v2);
}
- BMO_slot_buffer_from_enabled_flag(bm, op, "outsplit", BM_ALL, ELE_SPLIT);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom_split.out", BM_ALL, 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 d4b926b9275..d0676508917 100644
--- a/source/blender/bmesh/operators/bmo_subdivide.h
+++ b/source/blender/bmesh/operators/bmo_subdivide.h
@@ -39,6 +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"); */
float off[3];
} SubDParams;
diff --git a/source/blender/bmesh/operators/bmo_symmetrize.c b/source/blender/bmesh/operators/bmo_symmetrize.c
index a428405fb8b..8c440cae83e 100644
--- a/source/blender/bmesh/operators/bmo_symmetrize.c
+++ b/source/blender/bmesh/operators/bmo_symmetrize.c
@@ -96,7 +96,7 @@ static void symm_verts_mirror(Symm *symm)
symm->vert_symm_map = BLI_ghash_ptr_new(AT);
- BMO_ITER (src_v, &oiter, symm->bm, symm->op, "input", BM_VERT) {
+ BMO_ITER (src_v, &oiter, symm->op->slots_in, "input", BM_VERT) {
SymmSide side = symm_co_side(symm, src_v->co);
float co[3];
@@ -145,7 +145,7 @@ static void symm_split_asymmetric_edges(Symm *symm)
symm->edge_split_map = BLI_ghash_ptr_new(AT);
- BMO_ITER (e, &oiter, symm->bm, symm->op, "input", BM_EDGE) {
+ BMO_ITER (e, &oiter, symm->op->slots_in, "input", BM_EDGE) {
float flipped[3];
copy_v3_v3(flipped, e->v1->co);
@@ -195,7 +195,7 @@ static void symm_mirror_edges(Symm *symm)
BMOIter oiter;
BMEdge *e;
- BMO_ITER (e, &oiter, symm->bm, symm->op, "input", BM_EDGE) {
+ BMO_ITER (e, &oiter, symm->op->slots_in, "input", BM_EDGE) {
BMVert *v1 = NULL, *v2 = NULL;
BMEdge *e_new;
@@ -448,7 +448,7 @@ static void symm_mirror_polygons(Symm *symm)
BLI_array_declare(fv);
BLI_array_declare(fe);
- BMO_ITER (f, &oiter, symm->bm, symm->op, "input", BM_FACE) {
+ BMO_ITER (f, &oiter, symm->op->slots_in, "input", BM_FACE) {
BMIter iter;
BMLoop *l;
int mirror_all = TRUE, ignore_all = TRUE;
@@ -607,7 +607,7 @@ static void symm_kill_unused(Symm *symm)
BMVert *v;
/* Kill unused edges */
- BMO_ITER (e, &oiter, symm->bm, symm->op, "input", BM_EDGE) {
+ BMO_ITER (e, &oiter, symm->op->slots_in, "input", BM_EDGE) {
const int crosses = symm_edge_crosses_axis(symm, e);
const int symmetric = (crosses &&
(!BLI_ghash_haskey(symm->edge_split_map, e)));
@@ -617,13 +617,13 @@ static void symm_kill_unused(Symm *symm)
!symmetric)
{
/* The edge might be used by a face outside the input set */
- if (BM_edge_face_count(e) == 0)
+ if (BM_edge_is_wire(e))
BM_edge_kill(symm->bm, e);
}
}
/* Kill unused vertices */
- BMO_ITER (v, &oiter, symm->bm, symm->op, "input", BM_VERT) {
+ BMO_ITER (v, &oiter, symm->op->slots_in, "input", BM_VERT) {
if (symm_co_side(symm, v->co) == SYMM_SIDE_KILL) {
if (BM_vert_edge_count(v) == 0)
BM_vert_kill(symm->bm, v);
@@ -634,7 +634,7 @@ static void symm_kill_unused(Symm *symm)
void bmo_symmetrize_exec(BMesh *bm, BMOperator *op)
{
Symm symm;
- BMO_SymmDirection direction = BMO_slot_int_get(op, "direction");
+ BMO_SymmDirection direction = BMO_slot_int_get(op->slots_in, "direction");
symm.bm = bm;
symm.op = op;
@@ -658,6 +658,6 @@ void bmo_symmetrize_exec(BMesh *bm, BMOperator *op)
BLI_ghash_free(symm.vert_symm_map, NULL, NULL);
BLI_ghash_free(symm.edge_split_map, NULL, NULL);
- BMO_slot_buffer_from_enabled_flag(bm, op, "geomout", BM_ALL,
- SYMM_OUTPUT_GEOM);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom.out",
+ BM_ALL, SYMM_OUTPUT_GEOM);
}
diff --git a/source/blender/bmesh/operators/bmo_triangulate.c b/source/blender/bmesh/operators/bmo_triangulate.c
index de876477e5a..775fa0cb60d 100644
--- a/source/blender/bmesh/operators/bmo_triangulate.c
+++ b/source/blender/bmesh/operators/bmo_triangulate.c
@@ -52,9 +52,10 @@ void bmo_triangulate_exec(BMesh *bm, BMOperator *op)
float (*projectverts)[3] = NULL;
BLI_array_declare(projectverts);
int i;
- const int use_beauty = BMO_slot_bool_get(op, "use_beauty");
+ 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");
- for (face = BMO_iter_new(&siter, bm, op, "faces", BM_FACE); face; face = BMO_iter_step(&siter)) {
+ for (face = BMO_iter_new(&siter, op->slots_in, "faces", BM_FACE); face; face = BMO_iter_step(&siter)) {
BLI_array_empty(projectverts);
BLI_array_empty(newfaces);
@@ -64,16 +65,14 @@ 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(bm, op, "facemap", face, face);
+ BMO_slot_map_ptr_insert(op, slot_facemap_out, face, face);
for (i = 0; newfaces[i]; i++) {
- BMO_slot_map_ptr_insert(bm, op, "facemap",
- newfaces[i], face);
-
+ BMO_slot_map_ptr_insert(op, slot_facemap_out, newfaces[i], face);
}
}
- BMO_slot_buffer_from_enabled_flag(bm, op, "edgeout", BM_EDGE, EDGE_NEW);
- BMO_slot_buffer_from_enabled_flag(bm, op, "faceout", BM_FACE, FACE_NEW);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "edges.out", BM_EDGE, EDGE_NEW);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "faces.out", BM_FACE, FACE_NEW);
BLI_array_free(projectverts);
BLI_array_free(newfaces);
@@ -87,9 +86,9 @@ void bmo_beautify_fill_exec(BMesh *bm, BMOperator *op)
BMEdge *e;
int stop = 0;
- BMO_slot_buffer_flag_enable(bm, op, "constrain_edges", BM_EDGE, EDGE_MARK);
+ BMO_slot_buffer_flag_enable(bm, op->slots_in, "constrain_edges", BM_EDGE, EDGE_MARK);
- BMO_ITER (f, &siter, bm, op, "faces", BM_FACE) {
+ BMO_ITER (f, &siter, op->slots_in, "faces", BM_FACE) {
if (f->len == 3) {
BMO_elem_flag_enable(bm, f, FACE_MARK);
}
@@ -152,7 +151,7 @@ void bmo_beautify_fill_exec(BMesh *bm, BMOperator *op)
}
}
- BMO_slot_buffer_from_enabled_flag(bm, op, "geomout", BM_EDGE | BM_FACE, ELE_NEW);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom.out", BM_EDGE | BM_FACE, ELE_NEW);
}
void bmo_triangle_fill_exec(BMesh *bm, BMOperator *op)
@@ -170,7 +169,7 @@ void bmo_triangle_fill_exec(BMesh *bm, BMOperator *op)
BLI_scanfill_begin(&sf_ctx);
- BMO_ITER (e, &siter, bm, op, "edges", BM_EDGE) {
+ BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) {
BMO_elem_flag_enable(bm, e, EDGE_MARK);
if (!BLI_smallhash_haskey(&hash, (uintptr_t)e->v1)) {
@@ -214,8 +213,8 @@ void bmo_triangle_fill_exec(BMesh *bm, BMOperator *op)
/* clean up fill */
BMO_op_initf(bm, &bmop, op->flag, "beautify_fill faces=%ff constrain_edges=%fe", ELE_NEW, EDGE_MARK);
BMO_op_exec(bm, &bmop);
- BMO_slot_buffer_flag_enable(bm, &bmop, "geomout", BM_FACE | BM_EDGE, ELE_NEW);
+ BMO_slot_buffer_flag_enable(bm, bmop.slots_out, "geom.out", BM_FACE | BM_EDGE, ELE_NEW);
BMO_op_finish(bm, &bmop);
- BMO_slot_buffer_from_enabled_flag(bm, op, "geomout", BM_EDGE | BM_FACE, ELE_NEW);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom.out", BM_EDGE | BM_FACE, ELE_NEW);
}
diff --git a/source/blender/bmesh/operators/bmo_unsubdivide.c b/source/blender/bmesh/operators/bmo_unsubdivide.c
index 3d44feac380..fae7db3d175 100644
--- a/source/blender/bmesh/operators/bmo_unsubdivide.c
+++ b/source/blender/bmesh/operators/bmo_unsubdivide.c
@@ -39,10 +39,10 @@ void bmo_unsubdivide_exec(BMesh *bm, BMOperator *op)
BMVert *v;
BMIter iter;
- const int iterations = max_ii(1, BMO_slot_int_get(op, "iterations"));
+ const int iterations = max_ii(1, BMO_slot_int_get(op->slots_in, "iterations"));
- BMOpSlot *vinput = BMO_slot_get(op, "verts");
- BMVert **vinput_arr = (BMVert **)vinput->data.p;
+ BMOpSlot *vinput = BMO_slot_get(op->slots_in, "verts");
+ BMVert **vinput_arr = (BMVert **)vinput->data.buf;
int v_index;
/* tag verts */
diff --git a/source/blender/bmesh/operators/bmo_utils.c b/source/blender/bmesh/operators/bmo_utils.c
index aa514a5c0a7..d56b2ca0d73 100644
--- a/source/blender/bmesh/operators/bmo_utils.c
+++ b/source/blender/bmesh/operators/bmo_utils.c
@@ -45,21 +45,21 @@ void bmo_create_vert_exec(BMesh *bm, BMOperator *op)
{
float vec[3];
- BMO_slot_vec_get(op, "co", vec);
+ BMO_slot_vec_get(op->slots_in, "co", vec);
BMO_elem_flag_enable(bm, BM_vert_create(bm, vec, NULL), 1);
- BMO_slot_buffer_from_enabled_flag(bm, op, "newvertout", BM_VERT, 1);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "vert.out", BM_VERT, 1);
}
-void bmo_transform_exec(BMesh *bm, BMOperator *op)
+void bmo_transform_exec(BMesh *UNUSED(bm), BMOperator *op)
{
BMOIter iter;
BMVert *v;
float mat[4][4];
- BMO_slot_mat4_get(op, "mat", mat);
+ BMO_slot_mat4_get(op->slots_in, "mat", mat);
- BMO_ITER (v, &iter, bm, op, "verts", BM_VERT) {
+ BMO_ITER (v, &iter, op->slots_in, "verts", BM_VERT) {
mul_m4_v3(mat, v->co);
}
}
@@ -68,7 +68,7 @@ void bmo_translate_exec(BMesh *bm, BMOperator *op)
{
float mat[4][4], vec[3];
- BMO_slot_vec_get(op, "vec", vec);
+ BMO_slot_vec_get(op->slots_in, "vec", vec);
unit_m4(mat);
copy_v3_v3(mat[3], vec);
@@ -80,7 +80,7 @@ void bmo_scale_exec(BMesh *bm, BMOperator *op)
{
float mat[3][3], vec[3];
- BMO_slot_vec_get(op, "vec", vec);
+ BMO_slot_vec_get(op->slots_in, "vec", vec);
unit_m3(mat);
mat[0][0] = vec[0];
@@ -94,7 +94,7 @@ void bmo_rotate_exec(BMesh *bm, BMOperator *op)
{
float vec[3];
- BMO_slot_vec_get(op, "cent", vec);
+ BMO_slot_vec_get(op->slots_in, "cent", vec);
/* there has to be a proper matrix way to do this, but
* this is how editmesh did it and I'm too tired to think
@@ -113,7 +113,7 @@ void bmo_reverse_faces_exec(BMesh *bm, BMOperator *op)
BMOIter siter;
BMFace *f;
- BMO_ITER (f, &siter, bm, op, "faces", BM_FACE) {
+ BMO_ITER (f, &siter, op->slots_in, "faces", BM_FACE) {
BM_face_normal_flip(bm, f);
}
}
@@ -122,8 +122,8 @@ void bmo_rotate_edges_exec(BMesh *bm, BMOperator *op)
{
BMOIter siter;
BMEdge *e, *e2;
- int ccw = BMO_slot_bool_get(op, "ccw");
- int is_single = BMO_slot_buffer_count(bm, op, "edges") == 1;
+ const int use_ccw = BMO_slot_bool_get(op->slots_in, "use_ccw");
+ const int is_single = BMO_slot_buffer_count(op->slots_in, "edges") == 1;
short check_flag = is_single ?
BM_EDGEROT_CHECK_EXISTS :
BM_EDGEROT_CHECK_EXISTS | BM_EDGEROT_CHECK_DEGENERATE;
@@ -131,7 +131,7 @@ void bmo_rotate_edges_exec(BMesh *bm, BMOperator *op)
#define EDGE_OUT 1
#define FACE_TAINT 1
- BMO_ITER (e, &siter, bm, op, "edges", BM_EDGE) {
+ BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) {
/**
* this ends up being called twice, could add option to not to call check in
* #BM_edge_rotate to get some extra speed */
@@ -144,7 +144,7 @@ void bmo_rotate_edges_exec(BMesh *bm, BMOperator *op)
BMO_elem_flag_test(bm, fb, FACE_TAINT) == FALSE)
{
- if (!(e2 = BM_edge_rotate(bm, e, ccw, check_flag))) {
+ if (!(e2 = BM_edge_rotate(bm, e, use_ccw, check_flag))) {
#if 0
BMO_error_raise(bm, op, BMERR_INVALID_SELECTION, "Could not rotate edge");
return;
@@ -162,7 +162,7 @@ void bmo_rotate_edges_exec(BMesh *bm, BMOperator *op)
}
}
- BMO_slot_buffer_from_enabled_flag(bm, op, "edgeout", BM_EDGE, EDGE_OUT);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "edges.out", BM_EDGE, EDGE_OUT);
#undef EDGE_OUT
#undef FACE_TAINT
@@ -180,7 +180,7 @@ static void bmo_region_extend_extend(BMesh *bm, BMOperator *op, int usefaces)
BMOIter siter;
if (!usefaces) {
- BMO_ITER (v, &siter, bm, op, "geom", BM_VERT) {
+ BMO_ITER (v, &siter, op->slots_in, "geom", BM_VERT) {
BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
if (!BM_elem_flag_test(e, BM_ELEM_HIDDEN))
if (!BMO_elem_flag_test(bm, e, SEL_ORIG))
@@ -202,7 +202,7 @@ static void bmo_region_extend_extend(BMesh *bm, BMOperator *op, int usefaces)
BMFace *f, *f2;
BMLoop *l;
- BMO_ITER (f, &siter, bm, op, "geom", BM_FACE) {
+ BMO_ITER (f, &siter, op->slots_in, "geom", BM_FACE) {
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
BM_ITER_ELEM (f2, &fiter, l->e, BM_FACES_OF_EDGE) {
if (!BM_elem_flag_test(f2, BM_ELEM_HIDDEN)) {
@@ -224,7 +224,7 @@ static void bmo_region_extend_constrict(BMesh *bm, BMOperator *op, int usefaces)
BMOIter siter;
if (!usefaces) {
- BMO_ITER (v, &siter, bm, op, "geom", BM_VERT) {
+ BMO_ITER (v, &siter, op->slots_in, "geom", BM_VERT) {
BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
if (!BM_elem_flag_test(e, BM_ELEM_HIDDEN))
if (!BMO_elem_flag_test(bm, e, SEL_ORIG))
@@ -248,7 +248,7 @@ static void bmo_region_extend_constrict(BMesh *bm, BMOperator *op, int usefaces)
BMFace *f, *f2;
BMLoop *l;
- BMO_ITER (f, &siter, bm, op, "geom", BM_FACE) {
+ BMO_ITER (f, &siter, op->slots_in, "geom", BM_FACE) {
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
BM_ITER_ELEM (f2, &fiter, l->e, BM_FACES_OF_EDGE) {
if (!BM_elem_flag_test(f2, BM_ELEM_HIDDEN)) {
@@ -265,17 +265,17 @@ static void bmo_region_extend_constrict(BMesh *bm, BMOperator *op, int usefaces)
void bmo_region_extend_exec(BMesh *bm, BMOperator *op)
{
- int use_faces = BMO_slot_bool_get(op, "use_faces");
- int constrict = BMO_slot_bool_get(op, "constrict");
+ 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, "geom", BM_ALL, SEL_ORIG);
+ BMO_slot_buffer_flag_enable(bm, op->slots_in, "geom", BM_ALL, 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, "geomout", BM_ALL, SEL_FLAG);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom.out", BM_ALL, SEL_FLAG);
}
/********* righthand faces implementation ****** */
@@ -314,15 +314,15 @@ void bmo_recalc_face_normals_exec(BMesh *bm, BMOperator *op)
BLI_array_declare(fstack);
BMLoop *l, *l2;
float maxx, maxx_test, cent[3];
- int i, i_max, flagflip = BMO_slot_bool_get(op, "do_flip");
+ int i, i_max, flagflip = BMO_slot_bool_get(op->slots_in, "use_flip");
startf = NULL;
maxx = -1.0e10;
- BMO_slot_buffer_flag_enable(bm, op, "faces", BM_FACE, FACE_FLAG);
+ BMO_slot_buffer_flag_enable(bm, op->slots_in, "faces", BM_FACE, FACE_FLAG);
/* find a starting face */
- BMO_ITER (f, &siter, bm, op, "faces", BM_FACE) {
+ BMO_ITER (f, &siter, op->slots_in, "faces", BM_FACE) {
/* clear dirty flag */
BM_elem_flag_disable(f, BM_ELEM_TAG);
@@ -405,7 +405,7 @@ void bmo_recalc_face_normals_exec(BMesh *bm, BMOperator *op)
BLI_array_free(fstack);
/* check if we have faces yet to do. if so, recurse */
- BMO_ITER (f, &siter, bm, op, "faces", BM_FACE) {
+ BMO_ITER (f, &siter, op->slots_in, "faces", BM_FACE) {
if (!BMO_elem_flag_test(bm, f, FACE_VIS)) {
bmo_recalc_face_normals_exec(bm, op);
break;
@@ -413,7 +413,7 @@ void bmo_recalc_face_normals_exec(BMesh *bm, BMOperator *op)
}
}
-void bmo_smooth_vert_exec(BMesh *bm, BMOperator *op)
+void bmo_smooth_vert_exec(BMesh *UNUSED(bm), BMOperator *op)
{
BMOIter siter;
BMIter iter;
@@ -421,20 +421,20 @@ void bmo_smooth_vert_exec(BMesh *bm, BMOperator *op)
BMEdge *e;
BLI_array_declare(cos);
float (*cos)[3] = NULL;
- float *co, *co2, clipdist = BMO_slot_float_get(op, "clipdist");
+ float *co, *co2, clip_dist = BMO_slot_float_get(op->slots_in, "clip_dist");
int i, j, clipx, clipy, clipz;
int xaxis, yaxis, zaxis;
- clipx = BMO_slot_bool_get(op, "mirror_clip_x");
- clipy = BMO_slot_bool_get(op, "mirror_clip_y");
- clipz = BMO_slot_bool_get(op, "mirror_clip_z");
+ clipx = BMO_slot_bool_get(op->slots_in, "mirror_clip_x");
+ clipy = BMO_slot_bool_get(op->slots_in, "mirror_clip_y");
+ clipz = BMO_slot_bool_get(op->slots_in, "mirror_clip_z");
- xaxis = BMO_slot_bool_get(op, "use_axis_x");
- yaxis = BMO_slot_bool_get(op, "use_axis_y");
- zaxis = BMO_slot_bool_get(op, "use_axis_z");
+ xaxis = BMO_slot_bool_get(op->slots_in, "use_axis_x");
+ yaxis = BMO_slot_bool_get(op->slots_in, "use_axis_y");
+ zaxis = BMO_slot_bool_get(op->slots_in, "use_axis_z");
i = 0;
- BMO_ITER (v, &siter, bm, op, "verts", BM_VERT) {
+ BMO_ITER (v, &siter, op->slots_in, "verts", BM_VERT) {
BLI_array_grow_one(cos);
co = cos[i];
@@ -454,18 +454,18 @@ void bmo_smooth_vert_exec(BMesh *bm, BMOperator *op)
mul_v3_fl(co, 1.0f / (float)j);
mid_v3_v3v3(co, co, v->co);
- if (clipx && fabsf(v->co[0]) <= clipdist)
+ if (clipx && fabsf(v->co[0]) <= clip_dist)
co[0] = 0.0f;
- if (clipy && fabsf(v->co[1]) <= clipdist)
+ if (clipy && fabsf(v->co[1]) <= clip_dist)
co[1] = 0.0f;
- if (clipz && fabsf(v->co[2]) <= clipdist)
+ if (clipz && fabsf(v->co[2]) <= clip_dist)
co[2] = 0.0f;
i++;
}
i = 0;
- BMO_ITER (v, &siter, bm, op, "verts", BM_VERT) {
+ BMO_ITER (v, &siter, op->slots_in, "verts", BM_VERT) {
if (xaxis)
v->co[0] = cos[i][0];
if (yaxis)
@@ -489,11 +489,11 @@ void bmo_rotate_uvs_exec(BMesh *bm, BMOperator *op)
BMFace *fs; /* current face */
BMIter l_iter; /* iteration loop */
- int dir = BMO_slot_int_get(op, "dir");
+ const int use_ccw = BMO_slot_bool_get(op->slots_in, "use_ccw");
- BMO_ITER (fs, &fs_iter, bm, op, "faces", BM_FACE) {
+ BMO_ITER (fs, &fs_iter, op->slots_in, "faces", BM_FACE) {
if (CustomData_has_layer(&(bm->ldata), CD_MLOOPUV)) {
- if (dir == DIRECTION_CW) { /* same loops direction */
+ if (use_ccw == FALSE) { /* same loops direction */
BMLoop *lf; /* current face loops */
MLoopUV *f_luv; /* first face loop uv */
float p_uv[2]; /* previous uvs */
@@ -517,7 +517,7 @@ void bmo_rotate_uvs_exec(BMesh *bm, BMOperator *op)
copy_v2_v2(f_luv->uv, p_uv);
}
- else if (dir == DIRECTION_CCW) { /* counter loop direction */
+ else { /* counter loop direction */
BMLoop *lf; /* current face loops */
MLoopUV *p_luv; /* previous loop uv */
MLoopUV *luv;
@@ -556,7 +556,7 @@ void bmo_reverse_uvs_exec(BMesh *bm, BMOperator *op)
BLI_array_declare(uvs);
float (*uvs)[2] = NULL;
- BMO_ITER (fs, &fs_iter, bm, op, "faces", BM_FACE) {
+ BMO_ITER (fs, &fs_iter, op->slots_in, "faces", BM_FACE) {
if (CustomData_has_layer(&(bm->ldata), CD_MLOOPUV)) {
BMLoop *lf; /* current face loops */
int i;
@@ -594,11 +594,11 @@ void bmo_rotate_colors_exec(BMesh *bm, BMOperator *op)
BMFace *fs; /* current face */
BMIter l_iter; /* iteration loop */
- int dir = BMO_slot_int_get(op, "dir");
+ const int use_ccw = BMO_slot_bool_get(op->slots_in, "use_ccw");
- BMO_ITER (fs, &fs_iter, bm, op, "faces", BM_FACE) {
+ BMO_ITER (fs, &fs_iter, op->slots_in, "faces", BM_FACE) {
if (CustomData_has_layer(&(bm->ldata), CD_MLOOPCOL)) {
- if (dir == DIRECTION_CW) { /* same loops direction */
+ if (use_ccw == FALSE) { /* same loops direction */
BMLoop *lf; /* current face loops */
MLoopCol *f_lcol; /* first face loop color */
MLoopCol p_col; /* previous color */
@@ -622,7 +622,7 @@ void bmo_rotate_colors_exec(BMesh *bm, BMOperator *op)
*f_lcol = p_col;
}
- else if (dir == DIRECTION_CCW) { /* counter loop direction */
+ else { /* counter loop direction */
BMLoop *lf; /* current face loops */
MLoopCol *p_lcol; /* previous loop color */
MLoopCol *lcol;
@@ -661,7 +661,7 @@ void bmo_reverse_colors_exec(BMesh *bm, BMOperator *op)
BLI_array_declare(cols);
MLoopCol *cols = NULL;
- BMO_ITER (fs, &fs_iter, bm, op, "faces", BM_FACE) {
+ BMO_ITER (fs, &fs_iter, op->slots_in, "faces", BM_FACE) {
if (CustomData_has_layer(&(bm->ldata), CD_MLOOPCOL)) {
BMLoop *lf; /* current face loops */
int i;
@@ -710,12 +710,13 @@ void bmo_shortest_path_exec(BMesh *bm, BMOperator *op)
ElemNode *vert_list = NULL;
int num_total = 0 /*, num_sels = 0 */, i = 0;
- const int type = BMO_slot_int_get(op, "type");
+ const int type = BMO_slot_int_get(op->slots_in, "type");
- BMO_ITER (vs, &vs_iter, bm, op, "startv", BM_VERT) {
+ /* 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, bm, op, "endv", BM_VERT) {
+ BMO_ITER (vs, &vs_iter, op->slots_in, "endv", BM_VERT) {
ev = vs;
}
@@ -795,5 +796,5 @@ void bmo_shortest_path_exec(BMesh *bm, BMOperator *op)
BLI_heap_free(h, NULL);
MEM_freeN(vert_list);
- BMO_slot_buffer_from_enabled_flag(bm, op, "vertout", BM_VERT, VERT_MARK);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "verts.out", BM_VERT, VERT_MARK);
}
diff --git a/source/blender/bmesh/operators/bmo_wireframe.c b/source/blender/bmesh/operators/bmo_wireframe.c
index d572a1c5863..532145ab129 100644
--- a/source/blender/bmesh/operators/bmo_wireframe.c
+++ b/source/blender/bmesh/operators/bmo_wireframe.c
@@ -77,39 +77,60 @@ static void bm_vert_boundary_tangent(BMVert *v, float r_no[3], float r_no_face[3
}
}
- l_a = bm_edge_tag_faceloop(e_a);
- l_b = bm_edge_tag_faceloop(e_b);
+ if (e_a && e_b) {
+ l_a = bm_edge_tag_faceloop(e_a);
+ l_b = bm_edge_tag_faceloop(e_b);
+
+ /* average edge face normal */
+ add_v3_v3v3(no_face, l_a->f->no, l_b->f->no);
+
+ /* average edge direction */
+ v_a = BM_edge_other_vert(e_a, v);
+ v_b = BM_edge_other_vert(e_b, v);
+
+ sub_v3_v3v3(tvec_a, v->co, v_a->co);
+ sub_v3_v3v3(tvec_b, v_b->co, v->co);
+ normalize_v3(tvec_a);
+ normalize_v3(tvec_b);
+ add_v3_v3v3(no_edge, tvec_a, tvec_b); /* not unit length but this is ok */
+
+ /* check are we flipped the right way */
+ BM_edge_calc_face_tangent(e_a, l_a, tvec_a);
+ BM_edge_calc_face_tangent(e_b, l_b, tvec_b);
+ add_v3_v3(tvec_a, tvec_b);
+
+ *r_va_other = v_a;
+ *r_vb_other = v_b;
+ }
+ else {
+ /* degenerate case - vertex connects a boundary edged face to other faces,
+ * so we have only one boundary face - only use it for calculations */
+ l_a = bm_edge_tag_faceloop(e_a);
- /* average edge face normal */
- add_v3_v3v3(no_face, l_a->f->no, l_b->f->no);
+ copy_v3_v3(no_face, l_a->f->no);
- /* average edge direction */
- v_a = BM_edge_other_vert(e_a, v);
- v_b = BM_edge_other_vert(e_b, v);
+ /* edge direction */
+ v_a = BM_edge_other_vert(e_a, v);
+ v_b = NULL;
- sub_v3_v3v3(tvec_a, v->co, v_a->co);
- sub_v3_v3v3(tvec_b, v_b->co, v->co);
- normalize_v3(tvec_a);
- normalize_v3(tvec_b);
- add_v3_v3v3(no_edge, tvec_a, tvec_b); /* not unit length but this is ok */
+ sub_v3_v3v3(no_edge, v->co, v_a->co);
+ /* check are we flipped the right way */
+ BM_edge_calc_face_tangent(e_a, l_a, tvec_a);
+
+ *r_va_other = NULL;
+ *r_vb_other = NULL;
+ }
/* find the normal */
cross_v3_v3v3(r_no, no_edge, no_face);
normalize_v3(r_no);
- /* check are we flipped the right way */
- BM_edge_calc_face_tangent(e_a, l_a, tvec_a);
- BM_edge_calc_face_tangent(e_b, l_b, tvec_b);
- add_v3_v3(tvec_a, tvec_b);
-
if (dot_v3v3(r_no, tvec_a) > 0.0f) {
negate_v3(r_no);
}
copy_v3_v3(r_no_face, no_face);
- *r_va_other = v_a;
- *r_vb_other = v_b;
}
/* check if we are the only tagged loop-face around this edge */
@@ -134,12 +155,12 @@ extern float BM_vert_calc_mean_tagged_edge_length(BMVert *v);
void bmo_wireframe_exec(BMesh *bm, BMOperator *op)
{
- const int use_boundary = BMO_slot_bool_get(op, "use_boundary");
- const int use_even_offset = BMO_slot_bool_get(op, "use_even_offset");
- const int use_relative_offset = BMO_slot_bool_get(op, "use_relative_offset");
- const int use_crease = (BMO_slot_bool_get(op, "use_crease") &&
+ const int use_boundary = BMO_slot_bool_get(op->slots_in, "use_boundary");
+ const int use_even_offset = BMO_slot_bool_get(op->slots_in, "use_even_offset");
+ const int use_relative_offset = BMO_slot_bool_get(op->slots_in, "use_relative_offset");
+ const int use_crease = (BMO_slot_bool_get(op->slots_in, "use_crease") &&
CustomData_has_layer(&bm->edata, CD_CREASE));
- const float depth = BMO_slot_float_get(op, "thickness");
+ const float depth = BMO_slot_float_get(op->slots_in, "thickness");
const float inset = depth;
const int totvert_orig = bm->totvert;
@@ -184,7 +205,7 @@ void bmo_wireframe_exec(BMesh *bm, BMOperator *op)
/* setup tags, all faces and verts will be tagged which will be duplicated */
BM_mesh_elem_hflag_disable_all(bm, BM_FACE, BM_ELEM_TAG, FALSE);
- BMO_ITER (f_src, &oiter, bm, op, "faces", BM_FACE) {
+ BMO_ITER (f_src, &oiter, op->slots_in, "faces", BM_FACE) {
verts_loop_tot += f_src->len;
BM_elem_flag_enable(f_src, BM_ELEM_TAG);
BM_ITER_ELEM (l, &itersub, f_src, BM_LOOPS_OF_FACE) {
@@ -230,7 +251,7 @@ void bmo_wireframe_exec(BMesh *bm, BMOperator *op)
verts_loop = MEM_mallocN(sizeof(BMVert **) * verts_loop_tot, __func__);
verts_loop_tot = 0; /* count up again */
- BMO_ITER (f_src, &oiter, bm, op, "faces", BM_FACE) {
+ BMO_ITER (f_src, &oiter, op->slots_in, "faces", BM_FACE) {
BM_ITER_ELEM (l, &itersub, f_src, BM_LOOPS_OF_FACE) {
BM_elem_index_set(l, verts_loop_tot); /* set_loop */
@@ -269,10 +290,12 @@ void bmo_wireframe_exec(BMesh *bm, BMOperator *op)
/* similar to code above but different angle calc */
fac = inset;
if (use_even_offset) {
- fac *= shell_angle_to_dist(((float)M_PI - angle_on_axis_v3v3v3_v3(va_other->co,
- l_pair[i]->v->co,
- vb_other->co,
- no_face)) * 0.5f);
+ if (va_other) { /* for verts with only one boundary edge - this will be NULL */
+ fac *= shell_angle_to_dist(((float)M_PI - angle_on_axis_v3v3v3_v3(va_other->co,
+ l_pair[i]->v->co,
+ vb_other->co,
+ no_face)) * 0.5f);
+ }
}
if (use_relative_offset) {
fac *= verts_relfac[BM_elem_index_get(l_pair[i]->v)];
@@ -288,7 +311,7 @@ void bmo_wireframe_exec(BMesh *bm, BMOperator *op)
}
}
- BMO_ITER (f_src, &oiter, bm, op, "faces", BM_FACE) {
+ BMO_ITER (f_src, &oiter, op->slots_in, "faces", BM_FACE) {
BM_elem_flag_disable(f_src, BM_ELEM_TAG);
BM_ITER_ELEM (l, &itersub, f_src, BM_LOOPS_OF_FACE) {
BMFace *f_new;
@@ -400,5 +423,5 @@ void bmo_wireframe_exec(BMesh *bm, BMOperator *op)
MEM_freeN(verts_pos);
MEM_freeN(verts_loop);
- BMO_slot_buffer_from_enabled_hflag(bm, op, "faceout", BM_FACE, BM_ELEM_TAG);
+ BMO_slot_buffer_from_enabled_hflag(bm, op, op->slots_out, "faces.out", BM_FACE, BM_ELEM_TAG);
}
diff --git a/source/blender/bmesh/tools/BME_bevel.c b/source/blender/bmesh/tools/BME_bevel.c
index a632a4446ed..cdfd8372d61 100644
--- a/source/blender/bmesh/tools/BME_bevel.c
+++ b/source/blender/bmesh/tools/BME_bevel.c
@@ -1110,10 +1110,13 @@ BMesh *BME_bevel(BMesh *bm, float value, int res, int options, int defgrp_index,
td = BME_init_transdata(BLI_MEMARENA_STD_BUFSIZE);
/* recursion math courtesy of Martin Poirier (theeth) */
for (i = 0; i < res - 1; i++) {
- if (i == 0) fac += 1.0 / 3.0; else fac += 1.0 / (3.0 * i * 2.0);
+ if (i == 0) fac += 1.0 / 3.0;
+ else fac += 1.0 / (3.0 * i * 2.0);
}
d = 1.0 / fac;
+ BM_mesh_elem_toolflags_ensure(bm);
+
for (i = 0; i < res || (res == 0 && i == 0); i++) {
BMO_push(bm, NULL);
BME_bevel_initialize(bm, options, defgrp_index, angle, td);
diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c
new file mode 100644
index 00000000000..4d8fc8e9c3f
--- /dev/null
+++ b/source/blender/bmesh/tools/bmesh_bevel.c
@@ -0,0 +1,1749 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s):
+ * Joseph Eagar,
+ * Aleksandr Mokhov,
+ * Howard Trickey,
+ * Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/bmesh/tools/bmesh_bevel.c
+ * \ingroup bmesh
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_array.h"
+#include "BLI_math.h"
+#include "BLI_memarena.h"
+
+#include "BKE_customdata.h"
+
+#include "bmesh.h"
+
+
+
+/* experemental - Campbell */
+// #define USE_ALTERNATE_ADJ
+
+#define BEVEL_EPSILON 1e-6
+
+/* for testing */
+// #pragma GCC diagnostic error "-Wpadded"
+
+/* Constructed vertex, sometimes later instantiated as BMVert */
+typedef struct NewVert {
+ BMVert *v;
+ float co[3];
+// int _pad;
+} NewVert;
+
+struct BoundVert;
+
+/* Data for one end of an edge involved in a bevel */
+typedef struct EdgeHalf {
+ struct EdgeHalf *next, *prev; /* in CCW order */
+ BMEdge *e; /* original mesh edge */
+ BMFace *fprev; /* face between this edge and previous, if any */
+ BMFace *fnext; /* face between this edge and next, if any */
+ struct BoundVert *leftv; /* left boundary vert (looking along edge to end) */
+ struct BoundVert *rightv; /* right boundary vert, if beveled */
+ short is_bev; /* is this edge beveled? */
+ short is_rev; /* is e->v2 the vertex at this end? */
+ int seg; /* how many segments for the bevel */
+ float offset; /* offset for this edge */
+// int _pad;
+} EdgeHalf;
+
+/* An element in a cyclic boundary of a Vertex Mesh (VMesh) */
+typedef struct BoundVert {
+ struct BoundVert *next, *prev; /* in CCW order */
+ NewVert nv;
+ EdgeHalf *efirst; /* first of edges attached here: in CCW order */
+ EdgeHalf *elast;
+ EdgeHalf *ebev; /* beveled edge whose left side is attached here, if any */
+ int index; /* used for vmesh indexing */
+// int _pad;
+} BoundVert;
+
+/* Mesh structure replacing a vertex */
+typedef struct VMesh {
+ NewVert *mesh; /* allocated array - size and structure depends on kind */
+ BoundVert *boundstart; /* start of boundary double-linked list */
+ int count; /* number of vertices in the boundary */
+ int seg; /* common # of segments for segmented edges */
+ enum {
+ M_NONE, /* no polygon mesh needed */
+ M_POLY, /* a simple polygon */
+ M_ADJ, /* "adjacent edges" mesh pattern */
+// M_CROSS, /* "cross edges" mesh pattern */
+ M_TRI_FAN, /* a simple polygon - fan filled */
+ M_QUAD_STRIP, /* a simple polygon - cut into paralelle strips */
+ } mesh_kind;
+// int _pad;
+} VMesh;
+
+/* Data for a vertex involved in a bevel */
+typedef struct BevVert {
+ BMVert *v; /* original mesh vertex */
+ int edgecount; /* total number of edges around the vertex */
+ int selcount; /* number of selected edges around the vertex */
+ EdgeHalf *edges; /* array of size edgecount; CCW order from vertex normal side */
+ VMesh *vmesh; /* mesh structure for replacing vertex */
+} BevVert;
+
+/* Bevel parameters and state */
+typedef struct BevelParams {
+ /* hash of BevVert for each vertex involved in bevel
+ * GHash: (key=(BMVert *), value=(BevVert *)) */
+ GHash *vert_hash;
+ MemArena *mem_arena; /* use for all allocs while bevel runs, if we need to free we can switch to mempool */
+
+ float offset; /* blender units to offset each side of a beveled edge */
+ int seg; /* number of segments in beveled edge profile */
+} BevelParams;
+
+// #pragma GCC diagnostic ignored "-Wpadded"
+
+//#include "bevdebug.c"
+
+/* Make a new BoundVert of the given kind, insert it at the end of the circular linked
+ * list with entry point bv->boundstart, and return it. */
+static BoundVert *add_new_bound_vert(MemArena *mem_arena, VMesh *vm, const float co[3])
+{
+ BoundVert *ans = (BoundVert *)BLI_memarena_alloc(mem_arena, sizeof(BoundVert));
+
+ copy_v3_v3(ans->nv.co, co);
+ if (!vm->boundstart) {
+ ans->index = 0;
+ vm->boundstart = ans;
+ ans->next = ans->prev = ans;
+ }
+ else {
+ BoundVert *tail = vm->boundstart->prev;
+ ans->index = tail->index + 1;
+ ans->prev = tail;
+ ans->next = vm->boundstart;
+ tail->next = ans;
+ vm->boundstart->prev = ans;
+ }
+ vm->count++;
+ return ans;
+}
+
+/* Mesh verts are indexed (i, j, k) where
+ * i = boundvert index (0 <= i < nv)
+ * j = ring index (0 <= j <= ns2)
+ * k = segment index (0 <= k <= ns)
+ * Not all of these are used, and some will share BMVerts */
+static NewVert *mesh_vert(VMesh *vm, int i, int j, int k)
+{
+ int nj = (vm->seg / 2) + 1;
+ int nk = vm->seg + 1;
+
+ return &vm->mesh[i * nk * nj + j * nk + 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);
+}
+
+static void copy_mesh_vert(VMesh *vm, int ito, int jto, int kto,
+ int ifrom, int jfrom, int kfrom)
+{
+ NewVert *nvto, *nvfrom;
+
+ nvto = mesh_vert(vm, ito, jto, kto);
+ nvfrom = mesh_vert(vm, ifrom, jfrom, kfrom);
+ nvto->v = nvfrom->v;
+ copy_v3_v3(nvto->co, nvfrom->co);
+}
+
+/* find the EdgeHalf in bv's array that has edge bme */
+static EdgeHalf *find_edge_half(BevVert *bv, BMEdge *bme)
+{
+ int i;
+
+ for (i = 0; i < bv->edgecount; i++) {
+ if (bv->edges[i].e == bme)
+ return &bv->edges[i];
+ }
+ return NULL;
+}
+
+/* Return the next EdgeHalf after from_e that is beveled.
+ * If from_e is NULL, find the first beveled edge. */
+static EdgeHalf *next_bev(BevVert *bv, EdgeHalf *from_e)
+{
+ EdgeHalf *e;
+
+ if (from_e == NULL)
+ from_e = &bv->edges[bv->edgecount - 1];
+ e = from_e;
+ do {
+ if (e->is_bev) {
+ return e;
+ }
+ } while ((e = e->next) != from_e);
+ return NULL;
+}
+
+/* find the BevVert corresponding to BMVert bmv */
+static BevVert *find_bevvert(BevelParams *bp, BMVert *bmv)
+{
+ return BLI_ghash_lookup(bp->vert_hash, bmv);
+}
+
+/* Return a good respresentative face (for materials, etc.) for faces
+ * created around/near BoundVert v */
+static BMFace *boundvert_rep_face(BoundVert *v)
+{
+ BMFace *fans = NULL;
+ BMFace *firstf = NULL;
+ BMEdge *e1, *e2;
+ BMFace *f1, *f2;
+ BMIter iter1, iter2;
+
+ BLI_assert(v->efirst != NULL && v->elast != NULL);
+ e1 = v->efirst->e;
+ e2 = v->elast->e;
+ BM_ITER_ELEM (f1, &iter1, e1, BM_FACES_OF_EDGE) {
+ if (!firstf)
+ firstf = f1;
+ BM_ITER_ELEM (f2, &iter2, e2, BM_FACES_OF_EDGE) {
+ if (f1 == f2) {
+ fans = f1;
+ break;
+ }
+ }
+ }
+ if (!fans)
+ fans = firstf;
+
+ return fans;
+}
+
+/**
+ * Make ngon from verts alone.
+ * Make sure to properly copy face attributes and do custom data interpolation from
+ * example face, facerep.
+ *
+ * \note ALL face creation goes through this function, this is important to keep!
+ */
+static BMFace *bev_create_ngon(BMesh *bm, BMVert **vert_arr, const int totv, BMFace *facerep)
+{
+ BMIter iter;
+ BMLoop *l;
+ BMFace *f;
+
+ if (totv == 3) {
+ f = BM_face_create_quad_tri_v(bm, vert_arr, 3, facerep, FALSE);
+ }
+ else if (totv == 4) {
+ f = BM_face_create_quad_tri_v(bm, vert_arr, 4, facerep, FALSE);
+ }
+ else {
+ int i;
+ BMEdge **ee = NULL;
+ BLI_array_staticdeclare(ee, BM_DEFAULT_NGON_STACK_SIZE);
+
+ 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);
+ }
+ f = BM_face_create_ngon(bm, vert_arr[0], vert_arr[1], ee, totv, FALSE);
+ BLI_array_free(ee);
+ }
+ if (facerep && f) {
+ int has_mdisps = CustomData_has_layer(&bm->ldata, CD_MDISPS);
+ BM_elem_attrs_copy(bm, bm, facerep, f);
+ BM_ITER_ELEM (l, &iter, f, BM_LOOPS_OF_FACE) {
+ BM_loop_interp_from_face(bm, l, facerep, TRUE, TRUE);
+ if (has_mdisps)
+ BM_loop_interp_multires(bm, l, facerep);
+ }
+ }
+
+ /* not essential for bevels own internal logic,
+ * this is done so the operator can select newly created faces */
+ if (f) {
+ BM_elem_flag_enable(f, BM_ELEM_TAG);
+ }
+
+ return f;
+}
+
+static BMFace *bev_create_quad_tri(BMesh *bm, BMVert *v1, BMVert *v2, BMVert *v3, BMVert *v4,
+ BMFace *facerep)
+{
+ BMVert *varr[4] = {v1, v2, v3, v4};
+ return bev_create_ngon(bm, varr, v4 ? 4 : 3, facerep);
+}
+
+/*
+ * Calculate the meeting point between the offset edges for e1 and e2, putting answer in meetco.
+ * e1 and e2 share vertex v and face f (may be NULL) and viewed from the normal side of
+ * the bevel vertex, e1 precedes e2 in CCW order.
+ * If on_right is true, offset edge is on right of both edges, where e1 enters v and
+ * e2 leave it. If on_right is false, then the offset edge is on the left.
+ * When offsets are equal, the new point is on the edge bisector, with length offset/sin(angle/2),
+ * but if the offsets are not equal (allowing for this, as bevel modifier has edge weights that may
+ * lead to different offsets) then meeting point can be found be intersecting offset lines.
+ */
+static void offset_meet(EdgeHalf *e1, EdgeHalf *e2, BMVert *v, BMFace *f,
+ int on_right, float meetco[3])
+{
+ float dir1[3], dir2[3], norm_v[3], norm_perp1[3], norm_perp2[3],
+ off1a[3], off1b[3], off2a[3], off2b[3], isect2[3];
+
+ /* get direction vectors for two offset lines */
+ sub_v3_v3v3(dir1, v->co, BM_edge_other_vert(e1->e, v)->co);
+ sub_v3_v3v3(dir2, BM_edge_other_vert(e2->e, v)->co, v->co);
+
+ /* get normal to plane where meet point should be */
+ cross_v3_v3v3(norm_v, dir2, dir1);
+ normalize_v3(norm_v);
+ if (!on_right)
+ negate_v3(norm_v);
+ if (is_zero_v3(norm_v)) {
+ /* special case: e1 and e2 are parallel; put offset point perp to both, from v.
+ * need to find a suitable plane.
+ * if offsets are different, we're out of luck: just use e1->offset */
+ if (f)
+ copy_v3_v3(norm_v, f->no);
+ else
+ copy_v3_v3(norm_v, v->no);
+ cross_v3_v3v3(norm_perp1, dir1, norm_v);
+ normalize_v3(norm_perp1);
+ copy_v3_v3(off1a, v->co);
+ madd_v3_v3fl(off1a, norm_perp1, e1->offset);
+ copy_v3_v3(meetco, off1a);
+ }
+ else {
+ /* get vectors perp to each edge, perp to norm_v, and pointing into face */
+ if (f) {
+ copy_v3_v3(norm_v, f->no);
+ }
+ cross_v3_v3v3(norm_perp1, dir1, norm_v);
+ cross_v3_v3v3(norm_perp2, dir2, norm_v);
+ normalize_v3(norm_perp1);
+ normalize_v3(norm_perp2);
+
+ /* get points that are offset distances from each line, then another point on each line */
+ copy_v3_v3(off1a, v->co);
+ madd_v3_v3fl(off1a, norm_perp1, e1->offset);
+ add_v3_v3v3(off1b, off1a, dir1);
+ copy_v3_v3(off2a, v->co);
+ madd_v3_v3fl(off2a, norm_perp2, e2->offset);
+ add_v3_v3v3(off2b, off2a, dir2);
+
+ /* intersect the lines; by construction they should be on the same plane and not parallel */
+ if (!isect_line_line_v3(off1a, off1b, off2a, off2b, meetco, isect2)) {
+ BLI_assert(!"offset_meet failure");
+ copy_v3_v3(meetco, off1a); /* just to do something */
+ }
+ }
+}
+
+/* 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])
+{
+ float dir1[3], dir2[3], norm_perp1[3], norm_perp2[3],
+ off1a[3], off1b[3], off2a[3], off2b[3], isect2[3];
+
+ BLI_assert(f1 != NULL && f2 != NULL);
+
+ /* get direction vectors for two offset lines */
+ sub_v3_v3v3(dir1, v->co, BM_edge_other_vert(e1->e, v)->co);
+ sub_v3_v3v3(dir2, BM_edge_other_vert(e2->e, v)->co, v->co);
+
+ /* get directions into offset planes */
+ cross_v3_v3v3(norm_perp1, dir1, f1->no);
+ normalize_v3(norm_perp1);
+ cross_v3_v3v3(norm_perp2, dir2, f2->no);
+ normalize_v3(norm_perp2);
+
+ /* get points that are offset distances from each line, then another point on each line */
+ copy_v3_v3(off1a, v->co);
+ madd_v3_v3fl(off1a, norm_perp1, e1->offset);
+ add_v3_v3v3(off1b, off1a, dir1);
+ copy_v3_v3(off2a, v->co);
+ madd_v3_v3fl(off2a, norm_perp2, e2->offset);
+ add_v3_v3v3(off2b, off2a, dir2);
+
+ if (angle_v3v3(dir1, dir2) < 100.0f * (float)BEVEL_EPSILON) {
+ /* 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);
+ }
+}
+
+/* Offset by e->offset in plane with normal plane_no, on left if left==TRUE,
+ * else on right. If no is NULL, choose an arbitrary plane different
+ * from eh's direction. */
+static void offset_in_plane(EdgeHalf *e, const float plane_no[3], int left, float r[3])
+{
+ float dir[3], no[3];
+ BMVert *v;
+
+ v = e->is_rev ? e->e->v1 : e->e->v2;
+
+ sub_v3_v3v3(dir, BM_edge_other_vert(e->e, v)->co, v->co);
+ normalize_v3(dir);
+ if (plane_no) {
+ copy_v3_v3(no, plane_no);
+ }
+ else {
+ zero_v3(no);
+ if (fabs(dir[0]) < fabs(dir[1]))
+ no[0] = 1.0f;
+ else
+ no[1] = 1.0f;
+ }
+ if (left)
+ cross_v3_v3v3(r, no, dir);
+ else
+ cross_v3_v3v3(r, dir, no);
+ normalize_v3(r);
+ mul_v3_fl(r, e->offset);
+}
+
+/* Calculate coordinates of a point a distance d from v on e->e and return it in slideco */
+static void slide_dist(EdgeHalf *e, BMVert *v, float d, float slideco[3])
+{
+ float dir[3], len;
+
+ sub_v3_v3v3(dir, v->co, BM_edge_other_vert(e->e, v)->co);
+ len = normalize_v3(dir);
+ if (d > len)
+ d = len - (float)(50.0 * BEVEL_EPSILON);
+ copy_v3_v3(slideco, v->co);
+ madd_v3_v3fl(slideco, dir, -d);
+}
+
+/* Calculate the point on e where line (co_a, co_b) comes closest to and return it in projco */
+static void project_to_edge(BMEdge *e, const float co_a[3], const float co_b[3], float projco[3])
+{
+ float otherco[3];
+
+ if (!isect_line_line_v3(e->v1->co, e->v2->co, co_a, co_b, projco, otherco)) {
+ BLI_assert(!"project meet failure");
+ copy_v3_v3(projco, e->v1->co);
+ }
+}
+
+/* return 1 if a and b are in CCW order on the normal side of f,
+ * and -1 if they are reversed, and 0 if there is no shared face f */
+static int bev_ccw_test(BMEdge *a, BMEdge *b, BMFace *f)
+{
+ BMLoop *la, *lb;
+
+ if (!f)
+ return 0;
+ la = BM_face_edge_share_loop(f, a);
+ lb = BM_face_edge_share_loop(f, b);
+ if (!la || !lb)
+ return 0;
+ return lb->next == la ? 1 : -1;
+}
+
+#ifdef USE_ALTERNATE_ADJ
+
+static void vmesh_cent(VMesh *vm, float r_cent[3])
+{
+ BoundVert *v;
+ zero_v3(r_cent);
+
+ v = vm->boundstart;
+ do {
+ add_v3_v3(r_cent, v->nv.co);
+ } while ((v = v->next) != vm->boundstart);
+ mul_v3_fl(r_cent, 1.0f / (float)vm->count);
+}
+
+/**
+ *
+ * This example shows a tri fan of quads,
+ * but could be an NGon fan of quads too.
+ * <pre>
+ * The whole triangle X
+ * represents the / \
+ * new bevel face. / \
+ * / \
+ * Split into / \
+ * a quad fan. / \
+ * / \
+ * / \
+ * / \
+ * co_prev +-. .-+
+ * / `-._ _.-' \
+ * / co_cent`-+-' \
+ * / | \
+ * Quad of / | \
+ * interest -- / ---> X | \
+ * / | \
+ * / | \
+ * / co_next| \
+ * co_orig +-----------------+-----------------+
+ *
+ * For each quad, calcualte UV's based on the following:
+ * U = k / (vm->seg * 2)
+ * V = ring / (vm->seg * 2)
+ * quad = (co_orig, co_prev, co_cent, co_next)
+ * ... note that co_cent is the same for all quads in the fan.
+ * </pre>
+ *
+ */
+
+static void get_point_uv(float uv[2],
+ /* all these args are int's originally
+ * but pass as floats to the function */
+ const float seg, const float ring, const float k)
+{
+ uv[0] = (ring / seg) * 2.0f;
+ uv[1] = (k / seg) * 2.0f;
+}
+
+/* TODO: make this a lot smarter!,
+ * this is the main reason USE_ALTERNATE_ADJ isn't so good right now :S */
+static float get_point_uv_factor(const float uv[2])
+{
+ return sinf(1.0f - max_ff(uv[0], uv[1]) / 2.0f);
+}
+
+static void get_point_on_round_edge(const float uv[2],
+ float quad[4][3],
+ float r_co[3])
+{
+ interp_bilinear_quad_v3(quad, uv[0], uv[1], r_co);
+}
+
+#else /* USE_ALTERNATE_ADJ */
+
+/*
+ * calculation of points on the round profile
+ * r - result, coordinate of point on round profile
+ * method:
+ * Inscribe a circle in angle va - v -vb
+ * such that it touches the arms at offset from v.
+ * Rotate the center-va segment by (i/n) of the
+ * angle va - center -vb, and put the endpoint
+ * of that segment in r.
+ */
+static void get_point_on_round_profile(float r_co[3], float offset, int k, int count,
+ const float va[3], const float v[3], const float vb[3])
+{
+ float vva[3], vvb[3], angle, center[3], rv[3], axis[3], co[3];
+
+ sub_v3_v3v3(vva, va, v);
+ sub_v3_v3v3(vvb, vb, v);
+ normalize_v3(vva);
+ normalize_v3(vvb);
+ angle = angle_normalized_v3v3(vva, vvb);
+
+ add_v3_v3v3(center, vva, vvb);
+ normalize_v3(center);
+ mul_v3_fl(center, offset * (1.0f / cosf(0.5f * angle)));
+ add_v3_v3(center, v); /* coordinates of the center of the inscribed circle */
+
+
+ sub_v3_v3v3(rv, va, center); /* radius vector */
+
+
+ sub_v3_v3v3(co, v, center);
+ cross_v3_v3v3(axis, rv, co); /* calculate axis */
+
+ sub_v3_v3v3(vva, va, center);
+ sub_v3_v3v3(vvb, vb, center);
+ angle = angle_v3v3(vva, vvb);
+
+ rotate_v3_v3v3fl(co, rv, axis, angle * (float)k / (float)count);
+
+ add_v3_v3(co, center);
+ copy_v3_v3(r_co, co);
+}
+
+/*
+ * 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:
+ * Adjust va and vb (along edge direction) so that they are perpendicular
+ * to edge at v, then use get_point_on_round_profile, then project
+ * back onto original va - vmid - vb plane.
+ * If va, vmid, and vb are all on the same plane, just interpolate between va and vb.
+ */
+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 vva[3], vvb[3], point[3], dir[3], vaadj[3], vbadj[3], p2[3], pn[3];
+ int n = e->seg;
+
+ sub_v3_v3v3(vva, va, vmid);
+ sub_v3_v3v3(vvb, vb, vmid);
+ if (e->is_rev)
+ sub_v3_v3v3(dir, e->e->v1->co, e->e->v2->co);
+ else
+ sub_v3_v3v3(dir, e->e->v2->co, e->e->v1->co);
+ normalize_v3(dir);
+ if (fabsf(angle_v3v3(vva, vvb) - (float)M_PI) > (float)BEVEL_EPSILON) {
+ copy_v3_v3(vaadj, va);
+ madd_v3_v3fl(vaadj, dir, -len_v3(vva) * cosf(angle_v3v3(vva, dir)));
+ copy_v3_v3(vbadj, vb);
+ madd_v3_v3fl(vbadj, dir, -len_v3(vvb) * cosf(angle_v3v3(vvb, dir)));
+
+ get_point_on_round_profile(point, e->offset, k, n, vaadj, vmid, vbadj);
+
+ add_v3_v3v3(p2, point, dir);
+ cross_v3_v3v3(pn, vva, vvb);
+ if (!isect_line_plane_v3(r_co, point, p2, vmid, pn, 0)) {
+ /* TODO: track down why this sometimes fails */
+ copy_v3_v3(r_co, point);
+ }
+ }
+ else {
+ /* planar case */
+ interp_v3_v3v3(r_co, va, vb, (float)k / (float)n);
+ }
+}
+
+#endif /* !USE_ALTERNATE_ADJ */
+
+/* Make a circular list of BoundVerts for bv, each of which has the coordinates
+ * of a vertex on the the boundary of the beveled vertex bv->v.
+ * Also decide on the mesh pattern that will be used inside the boundary.
+ * Doesn't make the actual BMVerts */
+static void build_boundary(MemArena *mem_arena, BevVert *bv)
+{
+ EdgeHalf *efirst, *e;
+ BoundVert *v;
+ VMesh *vm;
+ float co[3];
+ const float *no;
+ float lastd;
+
+ e = efirst = next_bev(bv, NULL);
+ vm = bv->vmesh;
+
+ BLI_assert(bv->edgecount >= 2); /* since bevel edges incident to 2 faces */
+
+ if (bv->edgecount == 2 && bv->selcount == 1) {
+ /* special case: beveled edge meets non-beveled one at valence 2 vert */
+ no = e->fprev ? e->fprev->no : (e->fnext ? e->fnext->no : NULL);
+ offset_in_plane(e, no, TRUE, co);
+ v = add_new_bound_vert(mem_arena, vm, co);
+ v->efirst = v->elast = v->ebev = e;
+ e->leftv = v;
+ no = e->fnext ? e->fnext->no : (e->fprev ? e->fprev->no : NULL);
+ offset_in_plane(e, no, FALSE, co);
+ v = add_new_bound_vert(mem_arena, vm, co);
+ v->efirst = v->elast = e;
+ e->rightv = v;
+ /* make artifical extra point along unbeveled edge, and form triangle */
+ slide_dist(e->next, bv->v, e->offset, co);
+ v = add_new_bound_vert(mem_arena, vm, co);
+ v->efirst = v->elast = e->next;
+ vm->mesh_kind = M_POLY;
+ return;
+ }
+
+ lastd = e->offset;
+ vm->boundstart = NULL;
+ do {
+ if (e->is_bev) {
+ /* handle only left side of beveled edge e here: next iteration should do right side */
+ if (e->prev->is_bev) {
+ BLI_assert(e->prev != e); /* see: wire edge special case */
+ offset_meet(e->prev, e, bv->v, e->fprev, TRUE, co);
+ v = add_new_bound_vert(mem_arena, vm, co);
+ v->efirst = e->prev;
+ v->elast = v->ebev = e;
+ e->leftv = v;
+ e->prev->rightv = v;
+ }
+ else {
+ /* e->prev is not beveled */
+ 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,
+ e->prev->prev->fnext, e->fprev, co);
+ v = add_new_bound_vert(mem_arena, vm, co);
+ v->efirst = e->prev->prev;
+ v->elast = v->ebev = e;
+ e->leftv = v;
+ e->prev->leftv = v;
+ e->prev->prev->rightv = v;
+ }
+ else {
+ /* neither e->prev nor e->prev->prev are beveled: make on-edge on e->prev */
+ offset_meet(e->prev, e, bv->v, e->fprev, TRUE, co);
+ v = add_new_bound_vert(mem_arena, vm, co);
+ v->efirst = e->prev;
+ v->elast = v->ebev = e;
+ e->leftv = v;
+ e->prev->leftv = v;
+ }
+ }
+ lastd = len_v3v3(bv->v->co, v->nv.co);
+ }
+ else {
+ /* e is not beveled */
+ if (e->next->is_bev) {
+ /* next iteration will place e between beveled previous and next edges */
+ /* do nothing... */
+ }
+ else if (e->prev->is_bev) {
+ /* on-edge meet between e->prev and e */
+ offset_meet(e->prev, e, bv->v, e->fprev, TRUE, co);
+ v = add_new_bound_vert(mem_arena, vm, co);
+ v->efirst = e->prev;
+ v->elast = e;
+ e->leftv = v;
+ e->prev->rightv = v;
+ }
+ else {
+ /* None of e->prev, e, e->next are beveled.
+ * could either leave alone or add slide points to make
+ * one polygon around bv->v. For now, we choose latter.
+ * Could slide to make an even bevel plane but for now will
+ * just use last distance a meet point moved from bv->v. */
+ slide_dist(e, bv->v, lastd, co);
+ v = add_new_bound_vert(mem_arena, vm, co);
+ v->efirst = v->elast = e;
+ e->leftv = v;
+ }
+ }
+ } while ((e = e->next) != efirst);
+
+ BLI_assert(vm->count >= 2);
+ if (vm->count == 2 && bv->edgecount == 3) {
+ vm->mesh_kind = M_NONE;
+ }
+ else if (bv->selcount == 2) {
+ vm->mesh_kind = M_QUAD_STRIP;
+ }
+ else if (efirst->seg == 1 || bv->selcount == 1) {
+ if (vm->count == 3 && bv->selcount == 1) {
+ vm->mesh_kind = M_TRI_FAN;
+ }
+ else {
+ vm->mesh_kind = M_POLY;
+ }
+ }
+ else {
+ vm->mesh_kind = M_ADJ;
+ }
+ /* TODO: if vm->count == 4 and bv->selcount == 4, use M_CROSS pattern */
+}
+
+/*
+ * Given that the boundary is built and the boundary BMVerts have been made,
+ * calculate the positions of the interior mesh points for the M_ADJ pattern,
+ * then make the BMVerts and the new faces. */
+static void bevel_build_rings(BMesh *bm, BevVert *bv)
+{
+ int k, ring, i, n, ns, ns2, nn;
+ VMesh *vm = bv->vmesh;
+ BoundVert *v, *vprev, *vnext;
+ NewVert *nv, *nvprev, *nvnext;
+ BMVert *bmv, *bmv1, *bmv2, *bmv3, *bmv4;
+ BMFace *f;
+ float co[3], coa[3], cob[3], midco[3];
+
+#ifdef USE_ALTERNATE_ADJ
+ /* ordered as follows (orig, prev, center, next)*/
+ float quad_plane[4][3];
+ float quad_orig[4][3];
+#endif
+
+
+#ifdef USE_ALTERNATE_ADJ
+ /* the rest are initialized inline, this remains the same for all */
+ vmesh_cent(vm, quad_plane[2]);
+ copy_v3_v3(quad_orig[2], bv->v->co);
+#endif
+
+ n = vm->count;
+ ns = vm->seg;
+ ns2 = ns / 2;
+ BLI_assert(n > 2 && ns > 1);
+ /* Make initial rings, going between points on neighbors.
+ * After this loop, will have coords for all (i, r, k) where
+ * BoundVert for i has a bevel, 0 <= r <= ns2, 0 <= k <= ns */
+ for (ring = 1; ring <= ns2; ring++) {
+ v = vm->boundstart;
+
+ do {
+ i = v->index;
+ if (v->ebev) {
+ /* get points coords of points a and b, on outer rings
+ * of prev and next edges, k away from this edge */
+ vprev = v->prev;
+ vnext = v->next;
+
+ if (vprev->ebev)
+ nvprev = mesh_vert(vm, vprev->index, 0, ns - ring);
+ else
+ nvprev = mesh_vert(vm, vprev->index, 0, ns);
+ copy_v3_v3(coa, nvprev->co);
+ nv = mesh_vert(vm, i, ring, 0);
+ copy_v3_v3(nv->co, coa);
+ nv->v = nvprev->v;
+
+ if (vnext->ebev)
+ nvnext = mesh_vert(vm, vnext->index, 0, ring);
+ else
+ nvnext = mesh_vert(vm, vnext->index, 0, 0);
+ copy_v3_v3(cob, nvnext->co);
+ nv = mesh_vert(vm, i, ring, ns);
+ copy_v3_v3(nv->co, cob);
+ nv->v = nvnext->v;
+
+#ifdef USE_ALTERNATE_ADJ
+ /* plane */
+ copy_v3_v3(quad_plane[0], v->nv.co);
+ mid_v3_v3v3(quad_plane[1], v->nv.co, v->prev->nv.co);
+ /* quad[2] is set */
+ mid_v3_v3v3(quad_plane[3], v->nv.co, v->next->nv.co);
+
+ /* orig */
+ copy_v3_v3(quad_orig[0], v->nv.co); /* only shared location between 2 quads */
+ project_to_edge(v->ebev->prev->e, v->nv.co, v->prev->nv.co, quad_orig[1]);
+ project_to_edge(v->ebev->e, v->nv.co, v->next->nv.co, quad_orig[3]);
+
+ //bl_debug_draw_quad_add(UNPACK4(quad_plane));
+ //bl_debug_draw_quad_add(UNPACK4(quad_orig));
+#endif
+
+#ifdef USE_ALTERNATE_ADJ
+ for (k = 1; k < ns; k++) {
+ float uv[2];
+ float fac;
+ float co_plane[3];
+ float co_orig[3];
+
+ get_point_uv(uv, v->ebev->seg, ring, k);
+ get_point_on_round_edge(uv, quad_plane, co_plane);
+ get_point_on_round_edge(uv, quad_orig, co_orig);
+ fac = get_point_uv_factor(uv);
+ interp_v3_v3v3(co, co_plane, co_orig, fac);
+ copy_v3_v3(mesh_vert(vm, i, ring, k)->co, co);
+ }
+#else
+ /* TODO: better calculation of new midarc point? */
+ project_to_edge(v->ebev->e, coa, cob, midco);
+
+ for (k = 1; k < ns; k++) {
+ get_point_on_round_edge(v->ebev, k, coa, midco, cob, co);
+ copy_v3_v3(mesh_vert(vm, i, ring, k)->co, co);
+ }
+#endif
+ }
+ } while ((v = v->next) != vm->boundstart);
+ }
+
+ /* Now make sure cross points of rings share coordinates and vertices.
+ * After this loop, will have BMVerts for all (i, r, k) where
+ * i is for a BoundVert that is beveled and has either a predecessor or
+ * successor BoundVert beveled too, and
+ * for odd ns: 0 <= r <= ns2, 0 <= k <= ns
+ * for even ns: 0 <= r < ns2, 0 <= k <= ns except k=ns2 */
+ v = vm->boundstart;
+ do {
+ i = v->index;
+ if (v->ebev) {
+ vprev = v->prev;
+ vnext = v->next;
+ if (vprev->ebev) {
+ for (ring = 1; ring <= ns2; ring++) {
+ for (k = 1; k <= ns2; k++) {
+ if (ns % 2 == 0 && (k == ns2 || ring == ns2))
+ continue; /* center line is special case: do after the rest are done */
+ nv = mesh_vert(vm, i, ring, k);
+ nvprev = mesh_vert(vm, vprev->index, k, ns - ring);
+ mid_v3_v3v3(co, nv->co, nvprev->co);
+#ifndef USE_ALTERNATE_ADJ
+ copy_v3_v3(nv->co, co);
+#endif
+ BLI_assert(nv->v == NULL && nvprev->v == NULL);
+ create_mesh_bmvert(bm, vm, i, ring, k, bv->v);
+ copy_mesh_vert(vm, vprev->index, k, ns - ring, i, ring, k);
+ }
+ }
+ if (!vprev->prev->ebev) {
+ for (ring = 1; ring <= ns2; ring++) {
+ for (k = 1; k <= ns2; k++) {
+ if (ns % 2 == 0 && (k == ns2 || ring == ns2))
+ continue;
+ create_mesh_bmvert(bm, vm, vprev->index, ring, k, bv->v);
+ }
+ }
+ }
+ if (!vnext->ebev) {
+ for (ring = 1; ring <= ns2; ring++) {
+ for (k = ns - ns2; k < ns; k++) {
+ if (ns % 2 == 0 && (k == ns2 || ring == ns2))
+ continue;
+ create_mesh_bmvert(bm, vm, i, ring, k, bv->v);
+ }
+ }
+ }
+ }
+ }
+ } while ((v = v->next) != vm->boundstart);
+
+ if (ns % 2 == 0) {
+ /* Do special case center lines.
+ * This loop makes verts for (i, ns2, k) for 1 <= k <= ns-1, k!=ns2
+ * and for (i, r, ns2) for 1 <= r <= ns2-1,
+ * whenever i is in a sequence of at least two beveled verts */
+ v = vm->boundstart;
+ do {
+ i = v->index;
+ if (v->ebev) {
+ vprev = v->prev;
+ vnext = v->next;
+ for (k = 1; k < ns2; k++) {
+ nv = mesh_vert(vm, i, k, ns2);
+ if (vprev->ebev)
+ nvprev = mesh_vert(vm, vprev->index, ns2, ns - k);
+ if (vnext->ebev)
+ nvnext = mesh_vert(vm, vnext->index, ns2, k);
+ if (vprev->ebev && vnext->ebev) {
+ mid_v3_v3v3v3(co, nvprev->co, nv->co, nvnext->co);
+#ifndef USE_ALTERNATE_ADJ
+ copy_v3_v3(nv->co, co);
+#endif
+ create_mesh_bmvert(bm, vm, i, k, ns2, bv->v);
+ copy_mesh_vert(vm, vprev->index, ns2, ns - k, i, k, ns2);
+ copy_mesh_vert(vm, vnext->index, ns2, k, i, k, ns2);
+
+ }
+ else if (vprev->ebev) {
+ mid_v3_v3v3(co, nvprev->co, nv->co);
+#ifndef USE_ALTERNATE_ADJ
+ copy_v3_v3(nv->co, co);
+#endif
+ create_mesh_bmvert(bm, vm, i, k, ns2, bv->v);
+ copy_mesh_vert(vm, vprev->index, ns2, ns - k, i, k, ns2);
+
+ create_mesh_bmvert(bm, vm, i, ns2, ns - k, bv->v);
+ }
+ else if (vnext->ebev) {
+ mid_v3_v3v3(co, nv->co, nvnext->co);
+#ifndef USE_ALTERNATE_ADJ
+ copy_v3_v3(nv->co, co);
+#endif
+ create_mesh_bmvert(bm, vm, i, k, ns2, bv->v);
+ copy_mesh_vert(vm, vnext->index, ns2, k, i, k, ns2);
+
+ create_mesh_bmvert(bm, vm, i, ns2, k, bv->v);
+ }
+ }
+ }
+ } while ((v = v->next) != vm->boundstart);
+
+ /* center point need to be average of all centers of rings */
+ /* TODO: this is wrong if not all verts have ebev: could have
+ * several disconnected sections of mesh. */
+ zero_v3(midco);
+ nn = 0;
+ v = vm->boundstart;
+ do {
+ i = v->index;
+ if (v->ebev) {
+ nv = mesh_vert(vm, i, ns2, ns2);
+ add_v3_v3(midco, nv->co);
+ nn++;
+ }
+ } while ((v = v->next) != vm->boundstart);
+ mul_v3_fl(midco, 1.0f / nn);
+ bmv = BM_vert_create(bm, midco, NULL);
+ v = vm->boundstart;
+ do {
+ i = v->index;
+ if (v->ebev) {
+ nv = mesh_vert(vm, i, ns2, ns2);
+ copy_v3_v3(nv->co, midco);
+ nv->v = bmv;
+ }
+ } while ((v = v->next) != vm->boundstart);
+ }
+
+ /* Make the ring quads */
+ for (ring = 0; ring < ns2; ring++) {
+ v = vm->boundstart;
+ do {
+ i = v->index;
+ f = boundvert_rep_face(v);
+ if (v->ebev && (v->prev->ebev || v->next->ebev)) {
+ for (k = 0; k < ns2 + (ns % 2); k++) {
+ bmv1 = mesh_vert(vm, i, ring, k)->v;
+ bmv2 = mesh_vert(vm, i, ring, k + 1)->v;
+ bmv3 = mesh_vert(vm, i, ring + 1, k + 1)->v;
+ bmv4 = mesh_vert(vm, i, ring + 1, k)->v;
+ BLI_assert(bmv1 && bmv2 && bmv3 && bmv4);
+ if (bmv3 == bmv4 || bmv1 == bmv4)
+ bmv4 = NULL;
+ bev_create_quad_tri(bm, bmv1, bmv2, bmv3, bmv4, f);
+ }
+ }
+ else if (v->prev->ebev && v->prev->prev->ebev) {
+ /* finish off a sequence of beveled edges */
+ i = v->prev->index;
+ f = boundvert_rep_face(v->prev);
+ for (k = ns2 + (ns % 2); k < ns; k++) {
+ bmv1 = mesh_vert(vm, i, ring, k)->v;
+ bmv2 = mesh_vert(vm, i, ring, k + 1)->v;
+ bmv3 = mesh_vert(vm, i, ring + 1, k + 1)->v;
+ bmv4 = mesh_vert(vm, i, ring + 1, k)->v;
+ BLI_assert(bmv1 && bmv2 && bmv3 && bmv4);
+ if (bmv2 == bmv3) {
+ bmv3 = bmv4;
+ bmv4 = NULL;
+ }
+ bev_create_quad_tri(bm, bmv1, bmv2, bmv3, bmv4, f);
+ }
+ }
+ } while ((v = v->next) != vm->boundstart);
+ }
+
+ /* Make center ngon if odd number of segments and fully beveled */
+ if (ns % 2 == 1 && vm->count == bv->selcount) {
+ BMVert **vv = NULL;
+ BLI_array_declare(vv);
+
+ v = vm->boundstart;
+ do {
+ i = v->index;
+ BLI_assert(v->ebev);
+ BLI_array_append(vv, mesh_vert(vm, i, ns2, ns2)->v);
+ } while ((v = v->next) != vm->boundstart);
+ f = boundvert_rep_face(vm->boundstart);
+ bev_create_ngon(bm, vv, BLI_array_count(vv), f);
+
+ BLI_array_free(vv);
+ }
+
+ /* Make 'rest-of-vmesh' polygon if not fully beveled */
+ if (vm->count > bv->selcount) {
+ int j;
+ BMVert **vv = NULL;
+ BLI_array_declare(vv);
+
+ v = vm->boundstart;
+ f = boundvert_rep_face(v);
+ j = 0;
+ do {
+ i = v->index;
+ if (v->ebev) {
+ if (!v->prev->ebev) {
+ for (k = 0; k < ns2; k++) {
+ bmv1 = mesh_vert(vm, i, ns2, k)->v;
+ if (!bmv1)
+ bmv1 = mesh_vert(vm, i, 0, k)->v;
+ if (!(j > 0 && bmv1 == vv[j - 1])) {
+ BLI_assert(bmv1 != NULL);
+ BLI_array_append(vv, bmv1);
+ j++;
+ }
+ }
+ }
+ bmv1 = mesh_vert(vm, i, ns2, ns2)->v;
+ if (!bmv1)
+ bmv1 = mesh_vert(vm, i, 0, ns2)->v;
+ if (!(j > 0 && bmv1 == vv[j - 1])) {
+ BLI_assert(bmv1 != NULL);
+ BLI_array_append(vv, bmv1);
+ j++;
+ }
+ if (!v->next->ebev) {
+ for (k = ns - ns2; k < ns; k++) {
+ bmv1 = mesh_vert(vm, i, ns2, k)->v;
+ if (!bmv1)
+ bmv1 = mesh_vert(vm, i, 0, k)->v;
+ if (!(j > 0 && bmv1 == vv[j - 1])) {
+ BLI_assert(bmv1 != NULL);
+ BLI_array_append(vv, bmv1);
+ j++;
+ }
+ }
+ }
+ }
+ else {
+ BLI_assert(mesh_vert(vm, i, 0, 0)->v != NULL);
+ BLI_array_append(vv, mesh_vert(vm, i, 0, 0)->v);
+ j++;
+ }
+ } while ((v = v->next) != vm->boundstart);
+ if (vv[0] == vv[j - 1])
+ j--;
+ bev_create_ngon(bm, vv, j, f);
+
+ BLI_array_free(vv);
+ }
+}
+
+static BMFace *bevel_build_poly_ex(BMesh *bm, BevVert *bv)
+{
+ BMFace *f;
+ int n, k;
+ VMesh *vm = bv->vmesh;
+ BoundVert *v;
+ BMVert **vv = NULL;
+ BLI_array_declare(vv);
+
+ v = vm->boundstart;
+ n = 0;
+ do {
+ /* accumulate vertices for vertex ngon */
+ BLI_array_append(vv, v->nv.v);
+ n++;
+ if (v->ebev && v->ebev->seg > 1) {
+ for (k = 1; k < v->ebev->seg; k++) {
+ BLI_array_append(vv, mesh_vert(vm, v->index, 0, k)->v);
+ n++;
+ }
+ }
+ } while ((v = v->next) != vm->boundstart);
+ if (n > 2) {
+ f = bev_create_ngon(bm, vv, n, boundvert_rep_face(v));
+ }
+ else {
+ f = NULL;
+ }
+ BLI_array_free(vv);
+ return f;
+}
+
+static void bevel_build_poly(BMesh *bm, BevVert *bv)
+{
+ bevel_build_poly_ex(bm, bv);
+}
+
+static void bevel_build_trifan(BMesh *bm, BevVert *bv)
+{
+ BMFace *f;
+ BLI_assert(next_bev(bv, NULL)->seg == 1 || bv->selcount == 1);
+
+ f = bevel_build_poly_ex(bm, bv);
+
+ if (f) {
+ /* we have a polygon which we know starts at the previous vertex, make it into a fan */
+ BMLoop *l_fan = BM_FACE_FIRST_LOOP(f)->prev;
+ BMVert *v_fan = l_fan->v;
+
+ while (f->len > 3) {
+ BMLoop *l_new;
+ BMFace *f_new;
+ BLI_assert(v_fan == l_fan->v);
+ f_new = BM_face_split(bm, f, l_fan->v, l_fan->next->next->v, &l_new, NULL, FALSE);
+
+ if (f_new->len > f->len) {
+ f = f_new;
+ if (l_new->v == v_fan) { l_fan = l_new; }
+ else if (l_new->next->v == v_fan) { l_fan = l_new->next; }
+ else if (l_new->prev->v == v_fan) { l_fan = l_new->prev; }
+ else { BLI_assert(0); }
+ }
+ else {
+ if (l_fan->v == v_fan) { l_fan = l_fan; }
+ else if (l_fan->next->v == v_fan) { l_fan = l_fan->next; }
+ else if (l_fan->prev->v == v_fan) { l_fan = l_fan->prev; }
+ else { BLI_assert(0); }
+ }
+ }
+ }
+}
+
+static void bevel_build_quadstrip(BMesh *bm, BevVert *bv)
+{
+ BMFace *f;
+ BLI_assert(bv->selcount == 2);
+
+ f = bevel_build_poly_ex(bm, bv);
+
+ if (f) {
+ /* we have a polygon which we know starts at this vertex, make it into strips */
+ EdgeHalf *eh_a = bv->vmesh->boundstart->elast;
+ EdgeHalf *eh_b = next_bev(bv, eh_a->next); /* since (selcount == 2) we know this is valid */
+ BMLoop *l_a = BM_face_vert_share_loop(f, eh_a->rightv->nv.v);
+ BMLoop *l_b = BM_face_vert_share_loop(f, eh_b->leftv->nv.v);
+ int seg_count = bv->vmesh->seg; /* ensure we don't walk past the segments */
+
+ if (l_a == l_b) {
+ /* step once around if we hit the same loop */
+ l_a = l_a->prev;
+ l_b = l_b->next;
+ seg_count--;
+ }
+
+ BLI_assert(l_a != l_b);
+
+ while (f->len > 4) {
+ BMLoop *l_new;
+ BLI_assert(l_a->f == f);
+ BLI_assert(l_b->f == f);
+
+ BM_face_split(bm, f, l_a->v, l_b->v, &l_new, NULL, FALSE);
+ if (seg_count-- == 0) {
+ break;
+ }
+
+ /* turns out we don't need this,
+ * because of how BM_face_split works we always get the loop of the next face */
+#if 0
+ if (l_new->f->len < l_new->radial_next->f->len) {
+ l_new = l_new->radial_next;
+ }
+#endif
+ f = l_new->f;
+
+ /* walk around the new face to get the next verts to split */
+ l_a = l_new->prev;
+ l_b = l_new->next->next;
+ }
+ }
+}
+
+/* Given that the boundary is built, now make the actual BMVerts
+ * for the boundary and the interior of the vertex mesh. */
+static void build_vmesh(MemArena *mem_arena, BMesh *bm, BevVert *bv)
+{
+ VMesh *vm = bv->vmesh;
+ BoundVert *v, *weld1, *weld2;
+ int n, ns, ns2, i, k, weld;
+ float *va, *vb, co[3];
+
+#ifdef USE_ALTERNATE_ADJ
+ /* ordered as follows (orig, prev, center, next)*/
+ float quad_plane[4][3];
+ float quad_orig_a[4][3];
+ float quad_orig_b[4][3];
+ const int is_odd = (vm->seg % 2);
+#else
+ float midco[3];
+#endif
+
+#ifdef USE_ALTERNATE_ADJ
+ /* the rest are initialized inline, this remains the same for all */
+ /* NOTE; in this usage we only interpolate on the 'V' so cent and next points are unused (2,3)*/
+ vmesh_cent(vm, quad_plane[2]);
+ copy_v3_v3(quad_orig_a[2], bv->v->co);
+ copy_v3_v3(quad_orig_b[2], bv->v->co);
+#endif
+
+ n = vm->count;
+ ns = vm->seg;
+ ns2 = ns / 2;
+
+ vm->mesh = (NewVert *)BLI_memarena_alloc(mem_arena, n * (ns2 + 1) * (ns + 1) * sizeof(NewVert));
+
+ /* special case: two beveled ends welded together */
+ weld = (bv->selcount == 2) && (vm->count == 2);
+ weld1 = weld2 = NULL; /* will hold two BoundVerts involved in weld */
+
+ /* make (i, 0, 0) mesh verts for all i */
+ v = vm->boundstart;
+ do {
+ i = v->index;
+ copy_v3_v3(mesh_vert(vm, i, 0, 0)->co, v->nv.co);
+ create_mesh_bmvert(bm, vm, i, 0, 0, bv->v);
+ v->nv.v = mesh_vert(vm, i, 0, 0)->v;
+ if (weld && v->ebev) {
+ if (!weld1)
+ weld1 = v;
+ else
+ weld2 = v;
+ }
+ } while ((v = v->next) != vm->boundstart);
+
+ /* copy other ends to (i, 0, ns) for all i, and fill in profiles for beveled edges */
+ v = vm->boundstart;
+ do {
+ i = v->index;
+ copy_mesh_vert(vm, i, 0, ns, v->next->index, 0, 0);
+ if (v->ebev) {
+
+#ifdef USE_ALTERNATE_ADJ
+ copy_v3_v3(quad_plane[0], v->nv.co);
+ mid_v3_v3v3(quad_plane[1], v->nv.co, v->prev->nv.co);
+ /* quad[2] is set */
+ mid_v3_v3v3(quad_plane[3], v->nv.co, v->next->nv.co);
+
+ /* orig 'A' */
+ copy_v3_v3(quad_orig_a[0], v->nv.co); /* only shared location between 2 quads */
+ project_to_edge(v->ebev->prev->e, v->nv.co, v->prev->nv.co, quad_orig_a[1]);
+ project_to_edge(v->ebev->e, v->nv.co, v->next->nv.co, quad_orig_a[3]);
+
+ /* orig 'B' */
+ copy_v3_v3(quad_orig_b[3], v->next->nv.co); /* only shared location between 2 quads */
+ project_to_edge(v->ebev->prev->e, v->nv.co, v->prev->nv.co, quad_orig_b[1]);
+ project_to_edge(v->ebev->e, v->nv.co, v->next->nv.co, quad_orig_b[0]);
+
+ //bl_debug_draw_quad_add(UNPACK4(quad_plane));
+ //bl_debug_draw_quad_add(UNPACK4(quad_orig_a));
+ //bl_debug_draw_quad_add(UNPACK4(quad_orig_b));
+#endif /* USE_ALTERNATE_ADJ */
+
+#ifdef USE_ALTERNATE_ADJ
+ for (k = 1; k < ns; k++) {
+ float uv[2];
+ float fac;
+ float co_plane[3];
+ float co_orig[3];
+
+ /* quad_plane */
+ get_point_uv(uv, v->ebev->seg, 0, k);
+ get_point_on_round_edge(uv, quad_plane, co_plane);
+
+ /* quad_orig */
+ /* each half has different UV's */
+ if (k <= ns2) {
+ get_point_uv(uv, v->ebev->seg, 0, k);
+ get_point_on_round_edge(uv, quad_orig_a, co_orig);
+ }
+ else {
+ get_point_uv(uv, v->ebev->seg, 0, (k - ns2) - (is_odd ? 0.5f : 0.0f));
+ get_point_on_round_edge(uv, quad_orig_b, co_orig);
+ uv[1] = 1.0f - uv[1]; /* so we can get the factor */
+ }
+ fac = get_point_uv_factor(uv);
+
+ /* done. interp */
+ interp_v3_v3v3(co, co_plane, co_orig, fac);
+ copy_v3_v3(mesh_vert(vm, i, 0, k)->co, co);
+ if (!weld)
+ create_mesh_bmvert(bm, vm, i, 0, k, bv->v);
+ }
+#else /* USE_ALTERNATE_ADJ */
+ va = mesh_vert(vm, i, 0, 0)->co;
+ vb = mesh_vert(vm, i, 0, ns)->co;
+ project_to_edge(v->ebev->e, va, vb, midco);
+ for (k = 1; k < ns; k++) {
+ get_point_on_round_edge(v->ebev, k, va, midco, vb, co);
+ copy_v3_v3(mesh_vert(vm, i, 0, k)->co, co);
+ if (!weld)
+ create_mesh_bmvert(bm, vm, i, 0, k, bv->v);
+ }
+#endif /* !USE_ALTERNATE_ADJ */
+ }
+ } while ((v = v->next) != vm->boundstart);
+
+ if (weld) {
+ vm->mesh_kind = M_NONE;
+ for (k = 1; k < ns; k++) {
+ va = mesh_vert(vm, weld1->index, 0, k)->co;
+ vb = mesh_vert(vm, weld2->index, 0, ns - k)->co;
+ mid_v3_v3v3(co, va, vb);
+ copy_v3_v3(mesh_vert(vm, weld1->index, 0, k)->co, co);
+ create_mesh_bmvert(bm, vm, weld1->index, 0, k, bv->v);
+ }
+ for (k = 1; k < ns; k++)
+ copy_mesh_vert(vm, weld2->index, 0, ns - k, weld1->index, 0, k);
+ }
+
+ switch (vm->mesh_kind) {
+ case M_NONE:
+ /* do nothing */
+ break;
+ case M_POLY:
+ bevel_build_poly(bm, bv);
+ break;
+ case M_ADJ:
+ bevel_build_rings(bm, bv);
+ break;
+ case M_TRI_FAN:
+ bevel_build_trifan(bm, bv);
+ break;
+ case M_QUAD_STRIP:
+ bevel_build_quadstrip(bm, bv);
+ break;
+ }
+}
+
+/* take care, this flag isn't cleared before use, it just so happens that its not set */
+#define BM_BEVEL_EDGE_TAG_ENABLE(bme) BM_elem_flag_enable( (bme)->l, BM_ELEM_TAG)
+#define BM_BEVEL_EDGE_TAG_DISABLE(bme) BM_elem_flag_disable( (bme)->l, BM_ELEM_TAG)
+#define BM_BEVEL_EDGE_TAG_TEST(bme) BM_elem_flag_test( (bme)->l, BM_ELEM_TAG)
+
+/*
+ * Construction around the vertex
+ */
+static void bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v)
+{
+ BMEdge *bme;
+ BevVert *bv;
+ BMEdge *bme2, *unflagged_bme;
+ BMFace *f;
+ BMIter iter, iter2;
+ EdgeHalf *e;
+ int i, found_shared_face, ccw_test_sum;
+ int nsel = 0;
+ int ntot = 0;
+
+ /* Gather input selected edges.
+ * Only bevel selected edges that have exactly two incident faces.
+ */
+
+ BM_ITER_ELEM (bme, &iter, v, BM_EDGES_OF_VERT) {
+ if (BM_elem_flag_test(bme, BM_ELEM_TAG)) {
+ BLI_assert(BM_edge_is_manifold(bme));
+ nsel++;
+ }
+ ntot++;
+ }
+
+ if (nsel == 0) {
+ /* signal this vert isn't being beveled */
+ BM_elem_flag_disable(v, BM_ELEM_TAG);
+ return;
+ }
+
+ /* avoid calling BM_vert_edge_count since we loop over edges already */
+ // ntot = BM_vert_edge_count(v);
+ // BLI_assert(ntot == BM_vert_edge_count(v));
+
+ bv = (BevVert *)BLI_memarena_alloc(bp->mem_arena, (sizeof(BevVert)));
+ bv->v = v;
+ bv->edgecount = ntot;
+ bv->selcount = nsel;
+ bv->edges = (EdgeHalf *)BLI_memarena_alloc(bp->mem_arena, ntot * sizeof(EdgeHalf));
+ bv->vmesh = (VMesh *)BLI_memarena_alloc(bp->mem_arena, sizeof(VMesh));
+ bv->vmesh->seg = bp->seg;
+ BLI_ghash_insert(bp->vert_hash, v, bv);
+
+ /* add edges to bv->edges in order that keeps adjacent edges sharing
+ * a face, if possible */
+ i = 0;
+ bme = v->e;
+ BM_BEVEL_EDGE_TAG_ENABLE(bme);
+ e = &bv->edges[0];
+ e->e = bme;
+ for (i = 0; i < ntot; i++) {
+ if (i > 0) {
+ /* find an unflagged edge bme2 that shares a face f with previous bme */
+ found_shared_face = 0;
+ unflagged_bme = NULL;
+ BM_ITER_ELEM (bme2, &iter, v, BM_EDGES_OF_VERT) {
+ if (BM_BEVEL_EDGE_TAG_TEST(bme2))
+ continue;
+ if (!unflagged_bme)
+ unflagged_bme = bme2;
+ BM_ITER_ELEM (f, &iter2, bme2, BM_FACES_OF_EDGE) {
+ if (BM_face_edge_share_loop(f, bme)) {
+ found_shared_face = 1;
+ break;
+ }
+ }
+ if (found_shared_face)
+ break;
+ }
+ e = &bv->edges[i];
+ if (found_shared_face) {
+ e->e = bme2;
+ e->fprev = f;
+ bv->edges[i - 1].fnext = f;
+ }
+ else {
+ e->e = unflagged_bme;
+ }
+ }
+ bme = e->e;
+ BM_BEVEL_EDGE_TAG_ENABLE(bme);
+ if (BM_elem_flag_test(bme, BM_ELEM_TAG)) {
+ e->is_bev = TRUE;
+ e->seg = bp->seg;
+ }
+ else {
+ e->is_bev = FALSE;
+ e->seg = 0;
+ }
+ e->is_rev = (bme->v2 == v);
+ e->offset = e->is_bev ? bp->offset : 0.0f;
+ }
+ /* find wrap-around shared face */
+ BM_ITER_ELEM (f, &iter2, bme, BM_FACES_OF_EDGE) {
+ if (BM_face_edge_share_loop(f, bv->edges[0].e)) {
+ if (bv->edges[0].fnext == f)
+ continue; /* if two shared faces, want the other one now */
+ bv->edges[ntot - 1].fnext = f;
+ bv->edges[0].fprev = f;
+ break;
+ }
+ }
+
+ /* do later when we loop over edges */
+#if 0
+ /* clear BEVEL_EDGE_TAG now that we are finished with it*/
+ for (i = 0; i < ntot; i++) {
+ BM_BEVEL_EDGE_TAG_DISABLE(bv->edges[i].e);
+ }
+#endif
+
+ /* if edge array doesn't go CCW around vertex from average normal side,
+ * reverse the array, being careful to reverse face pointers too */
+ if (ntot > 1) {
+ ccw_test_sum = 0;
+ for (i = 0; i < ntot; i++)
+ ccw_test_sum += bev_ccw_test(bv->edges[i].e, bv->edges[(i + 1) % ntot].e,
+ bv->edges[i].fnext);
+ if (ccw_test_sum < 0) {
+ for (i = 0; i <= (ntot / 2) - 1; i++) {
+ SWAP(EdgeHalf, bv->edges[i], bv->edges[ntot - i - 1]);
+ SWAP(BMFace *, bv->edges[i].fprev, bv->edges[i].fnext);
+ SWAP(BMFace *, bv->edges[ntot - i - 1].fprev, bv->edges[ntot - i - 1].fnext);
+ }
+ if (ntot % 2 == 1) {
+ i = ntot / 2;
+ SWAP(BMFace *, bv->edges[i].fprev, bv->edges[i].fnext);
+ }
+ }
+ }
+
+ for (i = 0, e = bv->edges; i < ntot; i++, e++) {
+ e->next = &bv->edges[(i + 1) % ntot];
+ e->prev = &bv->edges[(i + ntot - 1) % ntot];
+ BM_BEVEL_EDGE_TAG_DISABLE(e->e);
+ }
+
+ build_boundary(bp->mem_arena, bv);
+ build_vmesh(bp->mem_arena, bm, bv);
+}
+
+/* Face f has at least one beveled vertex. Rebuild f */
+static int bev_rebuild_polygon(BMesh *bm, BevelParams *bp, BMFace *f)
+{
+ BMIter liter;
+ BMLoop *l, *lprev;
+ BevVert *bv;
+ BoundVert *v, *vstart, *vend;
+ EdgeHalf *e, *eprev;
+ VMesh *vm;
+ int i, k;
+ int do_rebuild = FALSE;
+ BMVert *bmv;
+ BMVert **vv = NULL;
+ BLI_array_staticdeclare(vv, BM_DEFAULT_NGON_STACK_SIZE);
+
+ BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
+ if (BM_elem_flag_test(l->v, BM_ELEM_TAG)) {
+ lprev = l->prev;
+ bv = find_bevvert(bp, l->v);
+ e = find_edge_half(bv, l->e);
+ eprev = find_edge_half(bv, lprev->e);
+ BLI_assert(e != NULL && eprev != NULL);
+ vstart = eprev->leftv;
+ if (e->is_bev)
+ vend = e->rightv;
+ else
+ vend = e->leftv;
+ v = vstart;
+ vm = bv->vmesh;
+ BLI_array_append(vv, v->nv.v);
+ while (v != vend) {
+ if (vm->mesh_kind == M_NONE && v->ebev && v->ebev->seg > 1 && v->ebev != e && v->ebev != eprev) {
+ /* case of 3rd face opposite a beveled edge, with no vmesh */
+ i = v->index;
+ e = v->ebev;
+ for (k = 1; k < e->seg; k++) {
+ bmv = mesh_vert(vm, i, 0, k)->v;
+ BLI_array_append(vv, bmv);
+ }
+ }
+ v = v->prev;
+ BLI_array_append(vv, v->nv.v);
+ }
+
+ do_rebuild = TRUE;
+ }
+ else {
+ BLI_array_append(vv, l->v);
+ }
+ }
+ if (do_rebuild) {
+ BMFace *f_new = bev_create_ngon(bm, vv, BLI_array_count(vv), f);
+
+ /* don't select newly created boundary faces... */
+ if (f_new) {
+ BM_elem_flag_disable(f_new, BM_ELEM_TAG);
+ }
+ }
+
+ BLI_array_free(vv);
+ return do_rebuild;
+}
+
+/* All polygons touching v need rebuilding because beveling v has made new vertices */
+static void bevel_rebuild_existing_polygons(BMesh *bm, BevelParams *bp, BMVert *v)
+{
+ void *faces_stack[BM_DEFAULT_ITER_STACK_SIZE];
+ int faces_len, f_index;
+ BMFace **faces = BM_iter_as_arrayN(bm, BM_FACES_OF_VERT, v, &faces_len,
+ faces_stack, BM_DEFAULT_ITER_STACK_SIZE);
+
+ if (LIKELY(faces != NULL)) {
+ for (f_index = 0; f_index < faces_len; f_index++) {
+ BMFace *f = faces[f_index];
+ if (bev_rebuild_polygon(bm, bp, f)) {
+ BM_face_kill(bm, f);
+ }
+ }
+
+ if (faces != (BMFace **)faces_stack) {
+ MEM_freeN(faces);
+ }
+ }
+}
+
+
+/*
+ * Build the polygons along the selected Edge
+ */
+static void bevel_build_edge_polygons(BMesh *bm, BevelParams *bp, BMEdge *bme)
+{
+ BevVert *bv1, *bv2;
+ BMVert *bmv1, *bmv2, *bmv3, *bmv4, *bmv1i, *bmv2i, *bmv3i, *bmv4i;
+ VMesh *vm1, *vm2;
+ EdgeHalf *e1, *e2;
+ BMFace *f1, *f2, *f;
+ int k, nseg, i1, i2;
+
+ if (!BM_edge_is_manifold(bme))
+ return;
+
+ bv1 = find_bevvert(bp, bme->v1);
+ bv2 = find_bevvert(bp, bme->v2);
+
+ BLI_assert(bv1 && bv2);
+
+ e1 = find_edge_half(bv1, bme);
+ e2 = find_edge_half(bv2, bme);
+
+ BLI_assert(e1 && e2);
+
+ /* v4 v3
+ * \ /
+ * e->v1 - e->v2
+ * / \
+ * v1 v2
+ */
+ nseg = e1->seg;
+ BLI_assert(nseg > 0 && nseg == e2->seg);
+
+ bmv1 = e1->leftv->nv.v;
+ bmv4 = e1->rightv->nv.v;
+ bmv2 = e2->rightv->nv.v;
+ bmv3 = e2->leftv->nv.v;
+
+ BLI_assert(bmv1 && bmv2 && bmv3 && bmv4);
+
+ f1 = boundvert_rep_face(e1->leftv);
+ f2 = boundvert_rep_face(e1->rightv);
+
+ if (nseg == 1) {
+ bev_create_quad_tri(bm, bmv1, bmv2, bmv3, bmv4, f1);
+ }
+ else {
+ i1 = e1->leftv->index;
+ i2 = e2->leftv->index;
+ vm1 = bv1->vmesh;
+ vm2 = bv2->vmesh;
+ bmv1i = bmv1;
+ bmv2i = bmv2;
+ for (k = 1; k <= nseg; k++) {
+ bmv4i = mesh_vert(vm1, i1, 0, k)->v;
+ bmv3i = mesh_vert(vm2, i2, 0, nseg - k)->v;
+ f = (k <= nseg / 2 + (nseg % 2)) ? f1 : f2;
+ bev_create_quad_tri(bm, bmv1i, bmv2i, bmv3i, bmv4i, f);
+ bmv1i = bmv4i;
+ bmv2i = bmv3i;
+ }
+ }
+}
+
+/**
+ * - Currently only bevels BM_ELEM_TAG'd verts and edges.
+ *
+ * - Newly created faces are BM_ELEM_TAG'd too,
+ * the caller needs to ensure this is cleared before calling
+ * if its going to use this face tag.
+ *
+ * \warning all tagged edges _must_ be manifold.
+ */
+void BM_mesh_bevel(BMesh *bm, const float offset, const float segments)
+{
+ BMIter iter;
+ BMVert *v;
+ BMEdge *e;
+ BevelParams bp = {NULL};
+
+ bp.offset = offset;
+ bp.seg = segments;
+
+ if (bp.offset > 0) {
+ /* primary alloc */
+ bp.vert_hash = BLI_ghash_ptr_new(__func__);
+ bp.mem_arena = BLI_memarena_new((1 << 16), __func__);
+ BLI_memarena_use_calloc(bp.mem_arena);
+
+ /* The analysis of the input vertices and execution additional constructions */
+ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
+ if (BM_elem_flag_test(v, BM_ELEM_TAG)) {
+ bevel_vert_construct(bm, &bp, v);
+ }
+ }
+
+ /* Build polygons for edges */
+ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+ if (BM_elem_flag_test(e, BM_ELEM_TAG)) {
+ bevel_build_edge_polygons(bm, &bp, e);
+ }
+ }
+
+ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
+ if (BM_elem_flag_test(v, BM_ELEM_TAG)) {
+ bevel_rebuild_existing_polygons(bm, &bp, v);
+ }
+ }
+
+ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
+ if (BM_elem_flag_test(v, BM_ELEM_TAG)) {
+ BLI_assert(find_bevvert(&bp, v) != NULL);
+ BM_vert_kill(bm, v);
+ }
+ }
+
+ /* primary free */
+ BLI_ghash_free(bp.vert_hash, NULL, NULL);
+ BLI_memarena_free(bp.mem_arena);
+ }
+}
diff --git a/source/blender/bmesh/tools/bmesh_bevel.h b/source/blender/bmesh/tools/bmesh_bevel.h
new file mode 100644
index 00000000000..a80e4f3a4a2
--- /dev/null
+++ b/source/blender/bmesh/tools/bmesh_bevel.h
@@ -0,0 +1,32 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s):
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __BMESH_BEVEL_H__
+#define __BMESH_BEVEL_H__
+
+/** \file blender/bmesh/tools/bmesh_bevel.h
+ * \ingroup bmesh
+ */
+
+void BM_mesh_bevel(BMesh *bm, const float offset, const float segments);
+
+#endif /* __BMESH_BEVEL_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_decimate.h b/source/blender/bmesh/tools/bmesh_decimate.h
index 04dc0cfd2ea..4d382d65659 100644
--- a/source/blender/bmesh/intern/bmesh_decimate.h
+++ b/source/blender/bmesh/tools/bmesh_decimate.h
@@ -23,7 +23,7 @@
#ifndef __BMESH_DECIMATE_H__
#define __BMESH_DECIMATE_H__
-/** \file blender/bmesh/intern/bmesh_decimate.h
+/** \file blender/bmesh/tools/bmesh_decimate.h
* \ingroup bmesh
*/
diff --git a/source/blender/bmesh/intern/bmesh_decimate_collapse.c b/source/blender/bmesh/tools/bmesh_decimate_collapse.c
index 74792d1d558..781001508f2 100644
--- a/source/blender/bmesh/intern/bmesh_decimate_collapse.c
+++ b/source/blender/bmesh/tools/bmesh_decimate_collapse.c
@@ -20,7 +20,7 @@
* ***** END GPL LICENSE BLOCK *****
*/
-/** \file blender/bmesh/intern/bmesh_decimate_collapse.c
+/** \file blender/bmesh/tools/bmesh_decimate_collapse.c
* \ingroup bmesh
*
* BMesh decimator that uses an edge collapse method.
@@ -39,9 +39,10 @@
#include "BKE_customdata.h"
#include "bmesh.h"
-#include "bmesh_structure.h"
#include "bmesh_decimate.h" /* own include */
+#include "../intern/bmesh_structure.h"
+
/* defines for testing */
#define USE_CUSTOMDATA
#define USE_TRIANGULATE
diff --git a/source/blender/bmesh/intern/bmesh_decimate_dissolve.c b/source/blender/bmesh/tools/bmesh_decimate_dissolve.c
index d1371a18160..d2a5c580ae6 100644
--- a/source/blender/bmesh/intern/bmesh_decimate_dissolve.c
+++ b/source/blender/bmesh/tools/bmesh_decimate_dissolve.c
@@ -20,7 +20,7 @@
* ***** END GPL LICENSE BLOCK *****
*/
-/** \file blender/bmesh/intern/bmesh_decimate_dissolve.c
+/** \file blender/bmesh/tools/bmesh_decimate_dissolve.c
* \ingroup bmesh
*
* BMesh decimator that dissolves flat areas into polygons (ngons).
@@ -231,8 +231,8 @@ void BM_mesh_decimate_dissolve(BMesh *bm, const float angle_limit, const int do_
int vinput_len;
int einput_len;
- BMVert **vinput_arr = BM_iter_as_arrayN(bm, BM_VERTS_OF_MESH, NULL, &vinput_len);
- BMEdge **einput_arr = BM_iter_as_arrayN(bm, BM_EDGES_OF_MESH, NULL, &einput_len);
+ BMVert **vinput_arr = BM_iter_as_arrayN(bm, BM_VERTS_OF_MESH, NULL, &vinput_len, NULL, 0);
+ BMEdge **einput_arr = BM_iter_as_arrayN(bm, BM_EDGES_OF_MESH, NULL, &einput_len, NULL, 0);
BM_mesh_decimate_dissolve_ex(bm, angle_limit, do_dissolve_boundaries,
vinput_arr, vinput_len,
diff --git a/source/blender/bmesh/intern/bmesh_decimate_unsubdivide.c b/source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c
index 1ec13010d80..acdab2510a4 100644
--- a/source/blender/bmesh/intern/bmesh_decimate_unsubdivide.c
+++ b/source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c
@@ -20,7 +20,7 @@
* ***** END GPL LICENSE BLOCK *****
*/
-/** \file blender/bmesh/intern/bmesh_decimate_unsubdivide.c
+/** \file blender/bmesh/tools/bmesh_decimate_unsubdivide.c
* \ingroup bmesh
*
* BMesh decimator that uses a grid un-subdivide method.
diff --git a/source/blender/collada/AnimationImporter.cpp b/source/blender/collada/AnimationImporter.cpp
index 374f6385ea7..44e74e320cc 100644
--- a/source/blender/collada/AnimationImporter.cpp
+++ b/source/blender/collada/AnimationImporter.cpp
@@ -844,7 +844,7 @@ void AnimationImporter::apply_matrix_curves(Object *ob, std::vector<FCurve *>& a
* This function returns the aspet ration from the Collada camera.
*
* Note:COLLADA allows to specify either XFov, or YFov alone.
- * In tghat case the aspect ratio can be determined from
+ * In that case the aspect ratio can be determined from
* the viewport aspect ratio (which is 1:1 ?)
* XXX: check this: its probably wrong!
* If both values are specified, then the aspect ration is simply xfov/yfov
diff --git a/source/blender/collada/DocumentImporter.cpp b/source/blender/collada/DocumentImporter.cpp
index 1c4f0974c6d..084f71e0afc 100644
--- a/source/blender/collada/DocumentImporter.cpp
+++ b/source/blender/collada/DocumentImporter.cpp
@@ -552,8 +552,8 @@ bool DocumentImporter::writeVisualScene(const COLLADAFW::VisualScene *visualScen
}
/** When this method is called, the writer must handle all nodes contained in the
-* library nodes.
-* \return The writer should return true, if writing succeeded, false otherwise.*/
+ * library nodes.
+ * \return The writer should return true, if writing succeeded, false otherwise.*/
bool DocumentImporter::writeLibraryNodes(const COLLADAFW::LibraryNodes *libraryNodes)
{
if (mImportStage != General)
diff --git a/source/blender/collada/DocumentImporter.h b/source/blender/collada/DocumentImporter.h
index e878a5a5b48..d54b8db9f00 100644
--- a/source/blender/collada/DocumentImporter.h
+++ b/source/blender/collada/DocumentImporter.h
@@ -81,8 +81,8 @@ public:
/**
* This method will be called if an error in the loading process occurred and the loader cannot
* continue to load. The writer should undo all operations that have been performed.
- \param errorMessage A message containing informations about the error that occurred.
- */
+ * \param errorMessage A message containing informations about the error that occurred.
+ */
void cancel(const COLLADAFW::String& errorMessage);
/** This is the method called. The writer hast to prepare to receive data.*/
diff --git a/source/blender/collada/ImageExporter.cpp b/source/blender/collada/ImageExporter.cpp
index 2e0c0f1ea57..aba290f5ce4 100644
--- a/source/blender/collada/ImageExporter.cpp
+++ b/source/blender/collada/ImageExporter.cpp
@@ -61,7 +61,7 @@ void ImagesExporter::export_UV_Image(Image *image, bool use_copies)
if (not_yet_exported) {
- ImBuf *imbuf = BKE_image_get_ibuf(image, NULL);
+ ImBuf *imbuf = BKE_image_acquire_ibuf(image, NULL, NULL);
if (!imbuf) {
fprintf(stderr, "Collada export: image does not exist:\n%s\n", image->name);
return;
@@ -147,6 +147,8 @@ void ImagesExporter::export_UV_Image(Image *image, bool use_copies)
img.add(mSW);
fprintf(stdout, "Collada export: Added image: %s\n", export_file);
mImages.push_back(translated_name);
+
+ BKE_image_release_ibuf(image, imbuf, NULL);
}
}
diff --git a/source/blender/compositor/CMakeLists.txt b/source/blender/compositor/CMakeLists.txt
index ceb91e5a3ec..6e59ce60c9b 100644
--- a/source/blender/compositor/CMakeLists.txt
+++ b/source/blender/compositor/CMakeLists.txt
@@ -267,6 +267,8 @@ set(SRC
nodes/COM_MathNode.h
nodes/COM_MapValueNode.cpp
nodes/COM_MapValueNode.h
+ nodes/COM_MapRangeNode.cpp
+ nodes/COM_MapRangeNode.h
operations/COM_NormalizeOperation.cpp
operations/COM_NormalizeOperation.h
@@ -572,6 +574,8 @@ set(SRC
operations/COM_SetAlphaOperation.h
operations/COM_MapValueOperation.cpp
operations/COM_MapValueOperation.h
+ operations/COM_MapRangeOperation.cpp
+ operations/COM_MapRangeOperation.h
# Distort operation
operations/COM_TranslateOperation.h
diff --git a/source/blender/compositor/intern/COM_Converter.cpp b/source/blender/compositor/intern/COM_Converter.cpp
index 2b09c9d5b8c..9c4a32f20c9 100644
--- a/source/blender/compositor/intern/COM_Converter.cpp
+++ b/source/blender/compositor/intern/COM_Converter.cpp
@@ -83,6 +83,7 @@
#include "COM_LuminanceMatteNode.h"
#include "COM_MapUVNode.h"
#include "COM_MapValueNode.h"
+#include "COM_MapRangeNode.h"
#include "COM_MaskNode.h"
#include "COM_MathNode.h"
#include "COM_MixNode.h"
@@ -351,6 +352,9 @@ Node *Converter::convert(bNode *b_node, bool fast)
case CMP_NODE_MAP_VALUE:
node = new MapValueNode(b_node);
break;
+ case CMP_NODE_MAP_RANGE:
+ node = new MapRangeNode(b_node);
+ break;
case CMP_NODE_TRANSFORM:
node = new TransformNode(b_node);
break;
diff --git a/source/blender/compositor/intern/COM_ExecutionSystem.cpp b/source/blender/compositor/intern/COM_ExecutionSystem.cpp
index c6e0f6c2cfb..1ec4ac7699b 100644
--- a/source/blender/compositor/intern/COM_ExecutionSystem.cpp
+++ b/source/blender/compositor/intern/COM_ExecutionSystem.cpp
@@ -247,9 +247,14 @@ void ExecutionSystem::addReadWriteBufferOperations(NodeOperation *operation)
*/
static void debug_check_node_connections(Node *node)
{
+ /* note: connected inputs are not checked here,
+ * it would break quite a lot and such inputs are ignored later anyway
+ */
+#if 0
for (int i = 0; i < node->getNumberOfInputSockets(); ++i) {
BLI_assert(!node->getInputSocket(i)->isConnected());
}
+#endif
for (int i = 0; i < node->getNumberOfOutputSockets(); ++i) {
BLI_assert(!node->getOutputSocket(i)->isConnected());
}
diff --git a/source/blender/compositor/nodes/COM_BlurNode.cpp b/source/blender/compositor/nodes/COM_BlurNode.cpp
index 4f120ea5a6e..6a4987c2075 100644
--- a/source/blender/compositor/nodes/COM_BlurNode.cpp
+++ b/source/blender/compositor/nodes/COM_BlurNode.cpp
@@ -31,6 +31,7 @@
#include "COM_FastGaussianBlurOperation.h"
#include "COM_MathBaseOperation.h"
#include "COM_SetValueOperation.h"
+#include "COM_GammaCorrectOperation.h"
BlurNode::BlurNode(bNode *editorNode) : Node(editorNode)
{
@@ -48,16 +49,17 @@ void BlurNode::convertToOperations(ExecutionSystem *graph, CompositorContext *co
const float size = ((const bNodeSocketValueFloat *)sock->default_value)->value;
CompositorQuality quality = context->getQuality();
-
+ NodeOperation *input_operation = NULL, *output_operation = NULL;
+
if (data->filtertype == R_FILTER_FAST_GAUSS) {
FastGaussianBlurOperation *operationfgb = new FastGaussianBlurOperation();
operationfgb->setData(data);
operationfgb->setbNode(editorNode);
- this->getInputSocket(0)->relinkConnections(operationfgb->getInputSocket(0), 0, graph);
this->getInputSocket(1)->relinkConnections(operationfgb->getInputSocket(1), 1, graph);
- this->getOutputSocket(0)->relinkConnections(operationfgb->getOutputSocket(0));
graph->addOperation(operationfgb);
- addPreviewOperation(graph, context, operationfgb->getOutputSocket());
+
+ input_operation = operationfgb;
+ output_operation = operationfgb;
}
else if (editorNode->custom1 & CMP_NODEFLAG_BLUR_VARIABLE_SIZE) {
MathAddOperation *clamp = new MathAddOperation();
@@ -93,48 +95,68 @@ void BlurNode::convertToOperations(ExecutionSystem *graph, CompositorContext *co
operation->setData(data);
operation->setbNode(editorNode);
operation->setQuality(quality);
- this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph);
addLink(graph, operationy->getOutputSocket(), operation->getInputSocket(1));
graph->addOperation(operation);
- this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket());
- addPreviewOperation(graph, context, operation->getOutputSocket());
+
+ output_operation = operation;
+ input_operation = operation;
}
else if (!data->bokeh) {
GaussianXBlurOperation *operationx = new GaussianXBlurOperation();
operationx->setData(data);
operationx->setbNode(editorNode);
operationx->setQuality(quality);
- this->getInputSocket(0)->relinkConnections(operationx->getInputSocket(0), 0, graph);
this->getInputSocket(1)->relinkConnections(operationx->getInputSocket(1), 1, graph);
graph->addOperation(operationx);
GaussianYBlurOperation *operationy = new GaussianYBlurOperation();
operationy->setData(data);
operationy->setbNode(editorNode);
operationy->setQuality(quality);
- this->getOutputSocket(0)->relinkConnections(operationy->getOutputSocket());
+
graph->addOperation(operationy);
addLink(graph, operationx->getOutputSocket(), operationy->getInputSocket(0));
addLink(graph, operationx->getInputSocket(1)->getConnection()->getFromSocket(), operationy->getInputSocket(1));
- addPreviewOperation(graph, context, operationy->getOutputSocket());
if (!connectedSizeSocket) {
operationx->setSize(size);
operationy->setSize(size);
}
+
+ input_operation = operationx;
+ output_operation = operationy;
}
else {
GaussianBokehBlurOperation *operation = new GaussianBokehBlurOperation();
operation->setData(data);
operation->setbNode(editorNode);
- this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph);
this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1), 1, graph);
operation->setQuality(quality);
graph->addOperation(operation);
- this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket());
- addPreviewOperation(graph, context, operation->getOutputSocket());
if (!connectedSizeSocket) {
operation->setSize(size);
}
+
+ input_operation = operation;
+ output_operation = operation;
+ }
+
+ if (data->gamma) {
+ GammaCorrectOperation *correct = new GammaCorrectOperation();
+ GammaUncorrectOperation *inverse = new GammaUncorrectOperation();
+
+ this->getInputSocket(0)->relinkConnections(correct->getInputSocket(0), 0, graph);
+ addLink(graph, correct->getOutputSocket(), input_operation->getInputSocket(0));
+ addLink(graph, output_operation->getOutputSocket(), inverse->getInputSocket(0));
+ this->getOutputSocket()->relinkConnections(inverse->getOutputSocket());
+ graph->addOperation(correct);
+ graph->addOperation(inverse);
+
+ addPreviewOperation(graph, context, inverse->getOutputSocket());
+ }
+ else {
+ this->getInputSocket(0)->relinkConnections(input_operation->getInputSocket(0), 0, graph);
+ this->getOutputSocket()->relinkConnections(output_operation->getOutputSocket());
+ addPreviewOperation(graph, context, output_operation->getOutputSocket());
}
}
diff --git a/source/blender/compositor/nodes/COM_ImageNode.cpp b/source/blender/compositor/nodes/COM_ImageNode.cpp
index 4ebd28d710a..729cb1b70a0 100644
--- a/source/blender/compositor/nodes/COM_ImageNode.cpp
+++ b/source/blender/compositor/nodes/COM_ImageNode.cpp
@@ -73,7 +73,7 @@ void ImageNode::convertToOperations(ExecutionSystem *graph, CompositorContext *c
/* force a load, we assume iuser index will be set OK anyway */
if (image && image->type == IMA_TYPE_MULTILAYER) {
bool is_multilayer_ok = false;
- BKE_image_get_ibuf(image, imageuser);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(image, imageuser, NULL);
if (image->rr) {
RenderLayer *rl = (RenderLayer *)BLI_findlink(&image->rr->layers, imageuser->layer);
if (rl) {
@@ -118,6 +118,7 @@ void ImageNode::convertToOperations(ExecutionSystem *graph, CompositorContext *c
}
}
}
+ BKE_image_release_ibuf(image, ibuf, NULL);
/* without this, multilayer that fail to load will crash blender [#32490] */
if (is_multilayer_ok == false) {
diff --git a/source/blender/compositor/nodes/COM_MapRangeNode.cpp b/source/blender/compositor/nodes/COM_MapRangeNode.cpp
new file mode 100644
index 00000000000..232be3d41b0
--- /dev/null
+++ b/source/blender/compositor/nodes/COM_MapRangeNode.cpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2012, 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.
+ *
+ * Contributor:
+ * Dalai Felinto
+ * Daniel Salazar
+ */
+
+#include "COM_MapRangeNode.h"
+
+#include "COM_MapRangeOperation.h"
+#include "COM_ExecutionSystem.h"
+
+MapRangeNode::MapRangeNode(bNode *editorNode) : Node(editorNode)
+{
+ /* pass */
+}
+
+void MapRangeNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
+{
+ InputSocket *valueSocket = this->getInputSocket(0);
+ InputSocket *sourceMinSocket = this->getInputSocket(1);
+ InputSocket *sourceMaxSocket = this->getInputSocket(2);
+ InputSocket *destMinSocket = this->getInputSocket(3);
+ InputSocket *destMaxSocket = this->getInputSocket(4);
+ OutputSocket *outputSocket = this->getOutputSocket(0);
+
+ MapRangeOperation *operation = new MapRangeOperation();
+
+ valueSocket->relinkConnections(operation->getInputSocket(0), 0, graph);
+ sourceMinSocket->relinkConnections(operation->getInputSocket(1), 1, graph);
+ sourceMaxSocket->relinkConnections(operation->getInputSocket(2), 2, graph);
+ destMinSocket->relinkConnections(operation->getInputSocket(3), 3, graph);
+ destMaxSocket->relinkConnections(operation->getInputSocket(4), 4, graph);
+ outputSocket->relinkConnections(operation->getOutputSocket(0));
+
+ operation->setUseClamp(this->getbNode()->custom1);
+
+ graph->addOperation(operation);
+}
diff --git a/source/blender/compositor/nodes/COM_MapRangeNode.h b/source/blender/compositor/nodes/COM_MapRangeNode.h
new file mode 100644
index 00000000000..6667720be3d
--- /dev/null
+++ b/source/blender/compositor/nodes/COM_MapRangeNode.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2012, 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.
+ *
+ * Contributor:
+ * Dalai Felinto
+ * Daniel Salazar
+ */
+
+#ifndef __COM_MAPRANGENODE_H__
+#define __COM_MAPRANGENODE_H__
+
+#include "COM_Node.h"
+#include "DNA_node_types.h"
+/**
+ * @brief MapRangeNode
+ * @ingroup Node
+ */
+class MapRangeNode : public Node {
+public:
+ MapRangeNode(bNode *editorNode);
+ void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
+};
+
+#endif /* __COM_MAPRANGENODE_H__ */
diff --git a/source/blender/compositor/nodes/COM_MuteNode.cpp b/source/blender/compositor/nodes/COM_MuteNode.cpp
index 4502dcf469c..de12fff3591 100644
--- a/source/blender/compositor/nodes/COM_MuteNode.cpp
+++ b/source/blender/compositor/nodes/COM_MuteNode.cpp
@@ -43,6 +43,10 @@ void MuteNode::reconnect(ExecutionSystem *graph, OutputSocket *output)
if (input->getDataType() == output->getDataType()) {
if (input->isConnected()) {
output->relinkConnections(input->getConnection()->getFromSocket(), false);
+ /* output connections have been redirected,
+ * remove the input connection to completely unlink the node.
+ */
+ input->unlinkConnections(graph);
return;
}
}
diff --git a/source/blender/compositor/nodes/COM_NormalNode.cpp b/source/blender/compositor/nodes/COM_NormalNode.cpp
index e00e71e50e9..fbfff8386d0 100644
--- a/source/blender/compositor/nodes/COM_NormalNode.cpp
+++ b/source/blender/compositor/nodes/COM_NormalNode.cpp
@@ -41,9 +41,14 @@ void NormalNode::convertToOperations(ExecutionSystem *graph, CompositorContext *
SetVectorOperation *operationSet = new SetVectorOperation();
bNodeSocket *insock = (bNodeSocket *)editorNode->outputs.first;
bNodeSocketValueVector *dval = (bNodeSocketValueVector *)insock->default_value;
- operationSet->setX(dval->value[0]);
- operationSet->setY(dval->value[1]);
- operationSet->setZ(dval->value[2]);
+ float normal[3];
+
+ /* animation can break normalization, this restores it */
+ normalize_v3_v3(normal, dval->value);
+
+ operationSet->setX(normal[0]);
+ operationSet->setY(normal[1]);
+ operationSet->setZ(normal[2]);
operationSet->setW(0.0f);
outputSocket->relinkConnections(operationSet->getOutputSocket(0));
diff --git a/source/blender/compositor/nodes/COM_OutputFileNode.cpp b/source/blender/compositor/nodes/COM_OutputFileNode.cpp
index 921b9e63a73..3b1871b307b 100644
--- a/source/blender/compositor/nodes/COM_OutputFileNode.cpp
+++ b/source/blender/compositor/nodes/COM_OutputFileNode.cpp
@@ -41,6 +41,12 @@ void OutputFileNode::convertToOperations(ExecutionSystem *graph, CompositorConte
* otherwise, it overwrites the output files just
* scrubbing through the timeline when the compositor updates.
*/
+
+ /* still, need to unlink input sockets to remove the node from the graph completely */
+ int num_inputs = getNumberOfInputSockets();
+ for (int i = 0; i < num_inputs; ++i) {
+ getInputSocket(i)->unlinkConnections(graph);
+ }
return;
}
diff --git a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp
index 4bdb2591cb7..9231261986d 100644
--- a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp
+++ b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp
@@ -230,6 +230,7 @@ FastGaussianBlurValueOperation::FastGaussianBlurValueOperation() : NodeOperation
this->m_iirgaus = NULL;
this->m_inputprogram = NULL;
this->m_sigma = 1.0f;
+ this->m_overlay = 0;
setComplex(true);
}
@@ -281,7 +282,7 @@ void *FastGaussianBlurValueOperation::initializeTileData(rcti *rect)
if (this->m_overlay == FAST_GAUSS_OVERLAY_MIN) {
float *src = newBuf->getBuffer();
float *dst = copy->getBuffer();
- for (int i = copy->getWidth() * copy->getHeight() * COM_NUMBER_OF_CHANNELS; i != 0; i--, src++, dst++) {
+ for (int i = copy->getWidth() * copy->getHeight(); i != 0; i--, src += COM_NUMBER_OF_CHANNELS, dst += COM_NUMBER_OF_CHANNELS) {
if (*src < *dst) {
*dst = *src;
}
@@ -290,7 +291,7 @@ void *FastGaussianBlurValueOperation::initializeTileData(rcti *rect)
else if (this->m_overlay == FAST_GAUSS_OVERLAY_MAX) {
float *src = newBuf->getBuffer();
float *dst = copy->getBuffer();
- for (int i = copy->getWidth() * copy->getHeight() * COM_NUMBER_OF_CHANNELS; i != 0; i--, src++, dst++) {
+ for (int i = copy->getWidth() * copy->getHeight(); i != 0; i--, src += COM_NUMBER_OF_CHANNELS, dst += COM_NUMBER_OF_CHANNELS) {
if (*src > *dst) {
*dst = *src;
}
diff --git a/source/blender/compositor/operations/COM_GammaCorrectOperation.cpp b/source/blender/compositor/operations/COM_GammaCorrectOperation.cpp
index af990f4f3e0..8f92dc02a57 100644
--- a/source/blender/compositor/operations/COM_GammaCorrectOperation.cpp
+++ b/source/blender/compositor/operations/COM_GammaCorrectOperation.cpp
@@ -48,15 +48,13 @@ void GammaCorrectOperation::executePixel(float output[4], float x, float y, Pixe
output[0] = inputColor[0] > 0.0f ? inputColor[0] * inputColor[0] : 0.0f;
output[1] = inputColor[1] > 0.0f ? inputColor[1] * inputColor[1] : 0.0f;
output[2] = inputColor[2] > 0.0f ? inputColor[2] * inputColor[2] : 0.0f;
-
- inputColor[0] *= inputColor[3];
- inputColor[1] *= inputColor[3];
- inputColor[2] *= inputColor[3];
-
- output[0] = inputColor[0];
- output[1] = inputColor[1];
- output[2] = inputColor[2];
output[3] = inputColor[3];
+
+ if (inputColor[3] > 0.0f) {
+ output[0] *= inputColor[3];
+ output[1] *= inputColor[3];
+ output[2] *= inputColor[3];
+ }
}
void GammaCorrectOperation::deinitExecution()
@@ -89,15 +87,13 @@ void GammaUncorrectOperation::executePixel(float output[4], float x, float y, Pi
output[0] = inputColor[0] > 0.0f ? sqrtf(inputColor[0]) : 0.0f;
output[1] = inputColor[1] > 0.0f ? sqrtf(inputColor[1]) : 0.0f;
output[2] = inputColor[2] > 0.0f ? sqrtf(inputColor[2]) : 0.0f;
-
- inputColor[0] *= inputColor[3];
- inputColor[1] *= inputColor[3];
- inputColor[2] *= inputColor[3];
-
- output[0] = inputColor[0];
- output[1] = inputColor[1];
- output[2] = inputColor[2];
output[3] = inputColor[3];
+
+ if (inputColor[3] > 0.0f) {
+ output[0] *= inputColor[3];
+ output[1] *= inputColor[3];
+ output[2] *= inputColor[3];
+ }
}
void GammaUncorrectOperation::deinitExecution()
diff --git a/source/blender/compositor/operations/COM_ImageOperation.cpp b/source/blender/compositor/operations/COM_ImageOperation.cpp
index fb3efbb67ed..d4c35f5afaa 100644
--- a/source/blender/compositor/operations/COM_ImageOperation.cpp
+++ b/source/blender/compositor/operations/COM_ImageOperation.cpp
@@ -65,8 +65,9 @@ ImBuf *BaseImageOperation::getImBuf()
{
ImBuf *ibuf;
- ibuf = BKE_image_get_ibuf(this->m_image, this->m_imageUser);
+ ibuf = BKE_image_acquire_ibuf(this->m_image, this->m_imageUser, NULL);
if (ibuf == NULL || (ibuf->rect == NULL && ibuf->rect_float == NULL)) {
+ BKE_image_release_ibuf(this->m_image, ibuf, NULL);
return NULL;
}
@@ -93,6 +94,7 @@ void BaseImageOperation::initExecution()
void BaseImageOperation::deinitExecution()
{
this->m_imageBuffer = NULL;
+ BKE_image_release_ibuf(this->m_image, this->m_buffer, NULL);
}
void BaseImageOperation::determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2])
@@ -106,6 +108,8 @@ void BaseImageOperation::determineResolution(unsigned int resolution[2], unsigne
resolution[0] = stackbuf->x;
resolution[1] = stackbuf->y;
}
+
+ IMB_freeImBuf(stackbuf);
}
void ImageOperation::executePixel(float output[4], float x, float y, PixelSampler sampler)
diff --git a/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp b/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp
index 0874e2f59be..201dc99eb9e 100644
--- a/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp
+++ b/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp
@@ -202,9 +202,9 @@ KeyingScreenOperation::TriangulationData *KeyingScreenOperation::buildVoronoiTri
INIT_MINMAX2(min, max);
- DO_MINMAX2(a->co, min, max);
- DO_MINMAX2(b->co, min, max);
- DO_MINMAX2(c->co, min, max);
+ minmax_v2v2_v2(min, max, a->co);
+ minmax_v2v2_v2(min, max, b->co);
+ minmax_v2v2_v2(min, max, c->co);
rect->xmin = min[0];
rect->ymin = min[1];
diff --git a/source/blender/compositor/operations/COM_MapRangeOperation.cpp b/source/blender/compositor/operations/COM_MapRangeOperation.cpp
new file mode 100644
index 00000000000..a18f418e48e
--- /dev/null
+++ b/source/blender/compositor/operations/COM_MapRangeOperation.cpp
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2012, 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.
+ *
+ * Contributor:
+ * Dalai Felinto
+ * Daniel Salazar
+ */
+
+#include "COM_MapRangeOperation.h"
+
+MapRangeOperation::MapRangeOperation() : NodeOperation()
+{
+ this->addInputSocket(COM_DT_VALUE);
+ this->addInputSocket(COM_DT_VALUE);
+ this->addInputSocket(COM_DT_VALUE);
+ this->addInputSocket(COM_DT_VALUE);
+ this->addInputSocket(COM_DT_VALUE);
+ this->addOutputSocket(COM_DT_VALUE);
+ this->m_inputOperation = NULL;
+ this->m_useClamp = FALSE;
+}
+
+void MapRangeOperation::initExecution()
+{
+ this->m_inputOperation = this->getInputSocketReader(0);
+ this->m_sourceMinOperation = this->getInputSocketReader(1);
+ this->m_sourceMaxOperation = this->getInputSocketReader(2);
+ this->m_destMinOperation = this->getInputSocketReader(3);
+ this->m_destMaxOperation = this->getInputSocketReader(4);
+}
+
+void MapRangeOperation::executePixel(float output[4], float x, float y, PixelSampler sampler)
+{
+ float inputs[8]; /* includes the 5 inputs + 3 pads */
+ float value;
+ float source_min, source_max;
+ float dest_min, dest_max;
+
+ this->m_inputOperation->read(inputs, x, y, sampler);
+ this->m_sourceMinOperation->read(inputs + 1, x, y, sampler);
+ this->m_sourceMaxOperation->read(inputs + 2, x, y, sampler);
+ this->m_destMinOperation->read(inputs + 3, x, y, sampler);
+ this->m_destMaxOperation->read(inputs + 4, x, y, sampler);
+
+ value = inputs[0];
+ source_min = inputs[1];
+ 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 (this->m_useClamp) {
+ if (dest_max > dest_min) {
+ CLAMP(value, dest_min, dest_max);
+ }
+ else {
+ CLAMP(value, dest_max, dest_min);
+ }
+ }
+
+ output[0] = value;
+}
+
+void MapRangeOperation::deinitExecution()
+{
+ this->m_inputOperation = NULL;
+ this->m_sourceMinOperation = NULL;
+ this->m_sourceMaxOperation = NULL;
+ this->m_destMinOperation = NULL;
+ this->m_destMaxOperation = NULL;
+}
diff --git a/source/blender/compositor/operations/COM_MapRangeOperation.h b/source/blender/compositor/operations/COM_MapRangeOperation.h
new file mode 100644
index 00000000000..00dfc68168c
--- /dev/null
+++ b/source/blender/compositor/operations/COM_MapRangeOperation.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2012, 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.
+ *
+ * Contributor:
+ * Dalai Felinto
+ * Daniel Salazar
+ */
+
+#ifndef _COM_MapRangeOperation_h
+#define _COM_MapRangeOperation_h
+#include "COM_NodeOperation.h"
+#include "DNA_texture_types.h"
+
+/**
+ * this program converts an input color to an output value.
+ * it assumes we are in sRGB color space.
+ */
+class MapRangeOperation : public NodeOperation {
+private:
+ /**
+ * Cached reference to the inputProgram
+ */
+ SocketReader *m_inputOperation;
+ SocketReader *m_sourceMinOperation;
+ SocketReader *m_sourceMaxOperation;
+ SocketReader *m_destMinOperation;
+ SocketReader *m_destMaxOperation;
+
+ bool m_useClamp;
+public:
+ /**
+ * Default constructor
+ */
+ MapRangeOperation();
+
+ /**
+ * the inner loop of this program
+ */
+ void executePixel(float output[4], float x, float y, PixelSampler sampler);
+
+ /**
+ * Initialize the execution
+ */
+ void initExecution();
+
+ /**
+ * Deinitialize the execution
+ */
+ void deinitExecution();
+
+ /**
+ * Clamp the output
+ */
+ void setUseClamp(bool value) { this->m_useClamp = value; }
+
+};
+#endif
diff --git a/source/blender/compositor/operations/COM_PixelateOperation.h b/source/blender/compositor/operations/COM_PixelateOperation.h
index b16b21b2ec1..83603a59331 100644
--- a/source/blender/compositor/operations/COM_PixelateOperation.h
+++ b/source/blender/compositor/operations/COM_PixelateOperation.h
@@ -35,7 +35,7 @@
class PixelateOperation : public NodeOperation {
private:
/**
- * @brief cached refeerence to the input operation
+ * @brief cached reference to the input operation
*/
SocketReader *m_inputOperation;
public:
diff --git a/source/blender/compositor/operations/COM_RenderLayersBaseProg.cpp b/source/blender/compositor/operations/COM_RenderLayersBaseProg.cpp
index f4160a5fbcb..2ca499683d3 100644
--- a/source/blender/compositor/operations/COM_RenderLayersBaseProg.cpp
+++ b/source/blender/compositor/operations/COM_RenderLayersBaseProg.cpp
@@ -91,11 +91,11 @@ void RenderLayersBaseProg::doInterpolation(float output[4], float x, float y, Pi
break;
case COM_PS_BILINEAR:
- BLI_bilinear_interpolation(this->m_inputBuffer, output, width, height, this->m_elementsize, x, y);
+ BLI_bilinear_interpolation_fl(this->m_inputBuffer, output, width, height, this->m_elementsize, x, y);
break;
case COM_PS_BICUBIC:
- BLI_bicubic_interpolation(this->m_inputBuffer, output, width, height, this->m_elementsize, x, y);
+ BLI_bicubic_interpolation_fl(this->m_inputBuffer, output, width, height, this->m_elementsize, x, y);
break;
}
diff --git a/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp b/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp
index 4d4c1199f3e..cc313512316 100644
--- a/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp
+++ b/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp
@@ -87,20 +87,16 @@ void ViewerBaseOperation::initImage()
/* now we combine the input with ibuf */
this->m_outputBuffer = ibuf->rect_float;
- /* needed for display buffer update
- *
- * no need to lock / reference the image buffer because it's seems
- * to be the single place which changes buffers of viewer image
- * which is this node
- */
+ /* needed for display buffer update */
this->m_ibuf = ibuf;
if (m_doDepthBuffer) {
this->m_depthBuffer = ibuf->zbuf_float;
}
- BKE_image_release_ibuf(this->m_image, this->m_lock);
+ BKE_image_release_ibuf(this->m_image, this->m_ibuf, this->m_lock);
}
+
void ViewerBaseOperation:: updateImage(rcti *rect)
{
IMB_partial_display_buffer_update(this->m_ibuf, this->m_outputBuffer, NULL, getWidth(), 0, 0,
diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c
index f19dbe740bc..fe836204c27 100644
--- a/source/blender/editors/animation/anim_channels_edit.c
+++ b/source/blender/editors/animation/anim_channels_edit.c
@@ -1560,6 +1560,8 @@ static int animchannels_setflag_exec(bContext *C, wmOperator *op)
/* duplicate of 'ANIM_OT_channels_setting_toggle' for menu title only, weak! */
static void ANIM_OT_channels_setting_enable(wmOperatorType *ot)
{
+ PropertyRNA *prop;
+
/* identifiers */
ot->name = "Enable Channel Setting";
ot->idname = "ANIM_OT_channels_setting_enable";
@@ -1575,13 +1577,16 @@ static void ANIM_OT_channels_setting_enable(wmOperatorType *ot)
/* props */
/* flag-setting mode */
- RNA_def_enum(ot->srna, "mode", prop_animchannel_setflag_types, ACHANNEL_SETFLAG_ADD, "Mode", "");
+ prop = RNA_def_enum(ot->srna, "mode", prop_animchannel_setflag_types, ACHANNEL_SETFLAG_ADD, "Mode", "");
+ RNA_def_property_flag(prop, PROP_HIDDEN);
/* setting to set */
ot->prop = RNA_def_enum(ot->srna, "type", prop_animchannel_settings_types, 0, "Type", "");
}
/* duplicate of 'ANIM_OT_channels_setting_toggle' for menu title only, weak! */
static void ANIM_OT_channels_setting_disable(wmOperatorType *ot)
{
+ PropertyRNA *prop;
+
/* identifiers */
ot->name = "Disable Channel Setting";
ot->idname = "ANIM_OT_channels_setting_disable";
@@ -1597,13 +1602,16 @@ static void ANIM_OT_channels_setting_disable(wmOperatorType *ot)
/* props */
/* flag-setting mode */
- RNA_def_enum(ot->srna, "mode", prop_animchannel_setflag_types, ACHANNEL_SETFLAG_CLEAR, "Mode", "");
+ prop = RNA_def_enum(ot->srna, "mode", prop_animchannel_setflag_types, ACHANNEL_SETFLAG_CLEAR, "Mode", "");
+ RNA_def_property_flag(prop, PROP_HIDDEN); /* internal hack - don't expose */
/* setting to set */
ot->prop = RNA_def_enum(ot->srna, "type", prop_animchannel_settings_types, 0, "Type", "");
}
static void ANIM_OT_channels_setting_toggle(wmOperatorType *ot)
{
+ PropertyRNA *prop;
+
/* identifiers */
ot->name = "Toggle Channel Setting";
ot->idname = "ANIM_OT_channels_setting_toggle";
@@ -1619,13 +1627,16 @@ static void ANIM_OT_channels_setting_toggle(wmOperatorType *ot)
/* props */
/* flag-setting mode */
- RNA_def_enum(ot->srna, "mode", prop_animchannel_setflag_types, ACHANNEL_SETFLAG_TOGGLE, "Mode", "");
+ prop = RNA_def_enum(ot->srna, "mode", prop_animchannel_setflag_types, ACHANNEL_SETFLAG_TOGGLE, "Mode", "");
+ RNA_def_property_flag(prop, PROP_HIDDEN); /* internal hack - don't expose */
/* setting to set */
ot->prop = RNA_def_enum(ot->srna, "type", prop_animchannel_settings_types, 0, "Type", "");
}
static void ANIM_OT_channels_editable_toggle(wmOperatorType *ot)
{
+ PropertyRNA *prop;
+
/* identifiers */
ot->name = "Toggle Channel Editability";
ot->idname = "ANIM_OT_channels_editable_toggle";
@@ -1642,7 +1653,8 @@ static void ANIM_OT_channels_editable_toggle(wmOperatorType *ot)
/* flag-setting mode */
RNA_def_enum(ot->srna, "mode", prop_animchannel_setflag_types, ACHANNEL_SETFLAG_TOGGLE, "Mode", "");
/* setting to set */
- RNA_def_enum(ot->srna, "type", prop_animchannel_settings_types, ACHANNEL_SETTING_PROTECT, "Type", "");
+ prop = RNA_def_enum(ot->srna, "type", prop_animchannel_settings_types, ACHANNEL_SETTING_PROTECT, "Type", "");
+ RNA_def_property_flag(prop, PROP_HIDDEN); /* internal hack - don't expose */
}
/* ********************** Expand Channels Operator *********************** */
diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c
index 8124dd268be..3846a5a2380 100644
--- a/source/blender/editors/armature/editarmature.c
+++ b/source/blender/editors/armature/editarmature.c
@@ -3569,16 +3569,16 @@ static int armature_subdivide_exec(bContext *C, wmOperator *op)
Object *obedit = CTX_data_edit_object(C);
bArmature *arm = obedit->data;
EditBone *newbone, *tbone;
- int numcuts, i;
+ int cuts, i;
/* there may not be a number_cuts property defined (for 'simple' subdivide) */
- numcuts = RNA_int_get(op->ptr, "number_cuts");
+ cuts = RNA_int_get(op->ptr, "number_cuts");
/* loop over all editable bones */
// XXX the old code did this in reverse order though!
CTX_DATA_BEGIN(C, EditBone *, ebone, selected_editable_bones)
{
- for (i = numcuts + 1; i > 1; i--) {
+ for (i = cuts + 1; i > 1; i--) {
/* compute cut ratio first */
float cutratio = 1.0f / (float)i;
float cutratioI = 1.0f - cutratio;
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index 957dcfbd848..23fed4ce8fc 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -1069,7 +1069,7 @@ static void curve_rename_fcurves(Curve *cu, ListBase *orig_curves)
Nurb *nu = editnurb->nurbs.first;
CVKeyIndex *keyIndex;
char rna_path[64], orig_rna_path[64];
- AnimData *ad = BKE_animdata_from_id(&cu->id);
+ AnimData *adt = BKE_animdata_from_id(&cu->id);
ListBase curves = {NULL, NULL};
FCurve *fcu, *next;
@@ -1089,14 +1089,14 @@ static void curve_rename_fcurves(Curve *cu, ListBase *orig_curves)
char handle_path[64], orig_handle_path[64];
BLI_snprintf(orig_handle_path, sizeof(orig_rna_path), "%s.handle_left", orig_rna_path);
BLI_snprintf(handle_path, sizeof(rna_path), "%s.handle_right", rna_path);
- fcurve_path_rename(ad, orig_handle_path, handle_path, orig_curves, &curves);
+ fcurve_path_rename(adt, orig_handle_path, handle_path, orig_curves, &curves);
BLI_snprintf(orig_handle_path, sizeof(orig_rna_path), "%s.handle_right", orig_rna_path);
BLI_snprintf(handle_path, sizeof(rna_path), "%s.handle_left", rna_path);
- fcurve_path_rename(ad, orig_handle_path, handle_path, orig_curves, &curves);
+ fcurve_path_rename(adt, orig_handle_path, handle_path, orig_curves, &curves);
}
- fcurve_path_rename(ad, orig_rna_path, rna_path, orig_curves, &curves);
+ fcurve_path_rename(adt, orig_rna_path, rna_path, orig_curves, &curves);
keyIndex->nu_index = nu_index;
keyIndex->pt_index = pt_index;
@@ -1116,7 +1116,7 @@ static void curve_rename_fcurves(Curve *cu, ListBase *orig_curves)
if (keyIndex) {
BLI_snprintf(rna_path, sizeof(rna_path), "splines[%d].points[%d]", nu_index, pt_index);
BLI_snprintf(orig_rna_path, sizeof(orig_rna_path), "splines[%d].points[%d]", keyIndex->nu_index, keyIndex->pt_index);
- fcurve_path_rename(ad, orig_rna_path, rna_path, orig_curves, &curves);
+ fcurve_path_rename(adt, orig_rna_path, rna_path, orig_curves, &curves);
keyIndex->nu_index = nu_index;
keyIndex->pt_index = pt_index;
@@ -1140,7 +1140,7 @@ static void curve_rename_fcurves(Curve *cu, ListBase *orig_curves)
char *ch = strchr(fcu->rna_path, '.');
if (ch && (!strncmp(ch, ".bezier_points", 14) || !strncmp(ch, ".points", 7)))
- fcurve_remove(ad, orig_curves, fcu);
+ fcurve_remove(adt, orig_curves, fcu);
}
}
@@ -1156,7 +1156,7 @@ static void curve_rename_fcurves(Curve *cu, ListBase *orig_curves)
if (keyIndex) {
BLI_snprintf(rna_path, sizeof(rna_path), "splines[%d]", nu_index);
BLI_snprintf(orig_rna_path, sizeof(orig_rna_path), "splines[%d]", keyIndex->nu_index);
- fcurve_path_rename(ad, orig_rna_path, rna_path, orig_curves, &curves);
+ fcurve_path_rename(adt, orig_rna_path, rna_path, orig_curves, &curves);
}
nu_index++;
@@ -1168,7 +1168,7 @@ static void curve_rename_fcurves(Curve *cu, ListBase *orig_curves)
for (fcu = orig_curves->first; fcu; fcu = next) {
next = fcu->next;
- if (!strncmp(fcu->rna_path, "splines", 7)) fcurve_remove(ad, orig_curves, fcu);
+ if (!strncmp(fcu->rna_path, "splines", 7)) fcurve_remove(adt, orig_curves, fcu);
else BLI_addtail(&curves, fcu);
}
@@ -1178,14 +1178,14 @@ static void curve_rename_fcurves(Curve *cu, ListBase *orig_curves)
/* return 0 if animation data wasn't changed, 1 otherwise */
int ED_curve_updateAnimPaths(Curve *cu)
{
- AnimData *ad = BKE_animdata_from_id(&cu->id);
+ AnimData *adt = BKE_animdata_from_id(&cu->id);
if (!curve_is_animated(cu)) return 0;
- if (ad->action)
- curve_rename_fcurves(cu, &ad->action->curves);
+ if (adt->action)
+ curve_rename_fcurves(cu, &adt->action->curves);
- curve_rename_fcurves(cu, &ad->drivers);
+ curve_rename_fcurves(cu, &adt->drivers);
return 1;
}
@@ -3678,10 +3678,12 @@ static int is_u_selected(Nurb *nu, int u)
/* what about resolu == 2? */
bp = &nu->bp[u];
for (v = 0; v < nu->pntsv - 1; v++, bp += nu->pntsu) {
- if (v) if (bp->f1 & SELECT) return 1;
+ if ((v != 0) && (bp->f1 & SELECT)) {
+ return TRUE;
+ }
}
- return 0;
+ return FALSE;
}
typedef struct NurbSort {
@@ -6464,7 +6466,7 @@ Nurb *add_nurbs_primitive(bContext *C, Object *obedit, float mat[4][4], int type
bp->vec[0] += fac * grid;
fac = (float)b - 1.5f;
bp->vec[1] += fac * grid;
- if (a == 1 || a == 2) if (b == 1 || b == 2) {
+ if ((a == 1 || a == 2) && (b == 1 || b == 2)) {
bp->vec[2] += grid;
}
mul_m4_v3(mat, bp->vec);
diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c
index fd87e6752f2..257dfca051f 100644
--- a/source/blender/editors/curve/editfont.c
+++ b/source/blender/editors/curve/editfont.c
@@ -1289,6 +1289,13 @@ static int insert_text_invoke(bContext *C, wmOperator *op, wmEvent *evt)
insert_into_textbuf(obedit, ascii);
accentcode = 0;
}
+ else if (ascii) {
+ insert_into_textbuf(obedit, ascii);
+ accentcode = 0;
+ }
+ else {
+ BLI_assert(0);
+ }
kill_selection(obedit, 1);
text_update_edited(C, scene, obedit, 1, FO_EDIT);
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c
index ed8a1ea8280..e9ca7392752 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -40,8 +40,10 @@
#include "BLI_math.h"
#include "BLI_blenlib.h"
+#include "BLI_rand.h"
#include "BLI_utildefines.h"
+#include "DNA_anim_types.h"
#include "DNA_curve_types.h"
#include "DNA_object_types.h"
#include "DNA_node_types.h"
@@ -51,14 +53,19 @@
#include "DNA_view3d_types.h"
#include "DNA_gpencil_types.h"
+#include "BKE_animsys.h"
#include "BKE_context.h"
#include "BKE_curve.h"
+#include "BKE_depsgraph.h"
+#include "BKE_fcurve.h"
+#include "BKE_global.h"
#include "BKE_gpencil.h"
#include "BKE_library.h"
#include "BKE_object.h"
#include "BKE_report.h"
#include "BKE_tracking.h"
+#include "UI_interface.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -71,6 +78,7 @@
#include "ED_gpencil.h"
#include "ED_view3d.h"
#include "ED_clip.h"
+#include "ED_keyframing.h"
#include "gpencil_intern.h"
@@ -131,11 +139,11 @@ bGPdata **gpencil_data_get_pointers(const bContext *C, PointerRNA *ptr)
return &sseq->gpd;
}
break;
-
+
case SPACE_IMAGE: /* Image/UV Editor */
{
SpaceImage *sima = (SpaceImage *)CTX_wm_space_data(C);
-
+
/* for now, Grease Pencil data is associated with the space... */
/* XXX our convention for everything else is to link to data though... */
if (ptr) RNA_pointer_create(screen_id, &RNA_SpaceImageEditor, sima, ptr);
@@ -151,19 +159,19 @@ bGPdata **gpencil_data_get_pointers(const bContext *C, PointerRNA *ptr)
if (clip) {
if (sc->gpencil_src == SC_GPENCIL_SRC_TRACK) {
MovieTrackingTrack *track = BKE_tracking_track_get_active(&clip->tracking);
-
+
if (!track)
return NULL;
-
+
if (ptr)
RNA_pointer_create(&clip->id, &RNA_MovieTrackingTrack, track, ptr);
-
+
return &track->gpd;
}
else {
if (ptr)
RNA_id_pointer_create(&clip->id, ptr);
-
+
return &clip->gpd;
}
}
@@ -387,6 +395,14 @@ enum {
GP_STROKECONVERT_CURVE,
};
+/* Defines for possible timing modes */
+enum {
+ GP_STROKECONVERT_TIMING_NONE = 1,
+ GP_STROKECONVERT_TIMING_LINEAR = 2,
+ GP_STROKECONVERT_TIMING_FULL = 3,
+ GP_STROKECONVERT_TIMING_CUSTOMGAP = 4,
+};
+
/* RNA enum define */
static EnumPropertyItem prop_gpencil_convertmodes[] = {
{GP_STROKECONVERT_PATH, "PATH", 0, "Path", ""},
@@ -394,6 +410,31 @@ static EnumPropertyItem prop_gpencil_convertmodes[] = {
{0, NULL, 0, NULL, NULL}
};
+static EnumPropertyItem prop_gpencil_convert_timingmodes_restricted[] = {
+ {GP_STROKECONVERT_TIMING_NONE, "NONE", 0, "No Timing", "Ignore timing"},
+ {GP_STROKECONVERT_TIMING_LINEAR, "LINEAR", 0, "Linear", "Simple linear timing"},
+ {0, NULL, 0, NULL, NULL},
+};
+
+static EnumPropertyItem prop_gpencil_convert_timingmodes[] = {
+ {GP_STROKECONVERT_TIMING_NONE, "NONE", 0, "No Timing", "Ignore timing"},
+ {GP_STROKECONVERT_TIMING_LINEAR, "LINEAR", 0, "Linear", "Simple linear timing"},
+ {GP_STROKECONVERT_TIMING_FULL, "FULL", 0, "Original", "Use the original timing, gaps included"},
+ {GP_STROKECONVERT_TIMING_CUSTOMGAP, "CUSTOMGAP", 0, "Custom Gaps",
+ "Use the original timing, but with custom gap lengths (in frames)"},
+ {0, NULL, 0, NULL, NULL},
+};
+
+static EnumPropertyItem *rna_GPConvert_mode_items(bContext *UNUSED(C), PointerRNA *ptr, PropertyRNA *UNUSED(prop),
+ int *free)
+{
+ *free = FALSE;
+ if (RNA_boolean_get(ptr, "use_timing_data")) {
+ return prop_gpencil_convert_timingmodes;
+ }
+ return prop_gpencil_convert_timingmodes_restricted;
+}
+
/* --- */
/* convert the coordinates from the given stroke point into 3d-coordinates
@@ -430,7 +471,7 @@ static void gp_strokepoint_convertcoords(bContext *C, bGPDstroke *gps, bGPDspoin
mvalf[1] = (float)pt->y / 100.0f * ar->winy;
}
}
-
+
/* convert screen coordinate to 3d coordinates
* - method taken from editview.c - mouse_cursor()
*/
@@ -440,47 +481,510 @@ static void gp_strokepoint_convertcoords(bContext *C, bGPDstroke *gps, bGPDspoin
/* --- */
-/* convert stroke to 3d path */
-static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curve *cu, rctf *subrect)
+/* temp struct for gp_stroke_path_animation() */
+typedef struct tGpTimingData {
+ /* Data set from operator settings */
+ int mode;
+ int frame_range; /* Number of frames evaluated for path animation */
+ int start_frame, end_frame;
+ int realtime; /* A bool, actually, will overwrite end_frame in case of Original or CustomGap timing... */
+ float gap_duration, gap_randomness; /* To be used with CustomGap mode*/
+ int seed;
+
+ /* Data set from points, used to compute final timing FCurve */
+ int num_points, cur_point;
+
+ /* Distances */
+ float *dists;
+ float tot_dist;
+
+ /* Times */
+ float *times; /* Note: Gap times will be negative! */
+ float tot_time, gap_tot_time;
+ double inittime;
+} tGpTimingData;
+
+/* init point buffers for timing data */
+static void _gp_timing_data_set_nbr(tGpTimingData *gtd, int nbr)
{
- bGPDspoint *pt;
- Nurb *nu;
- BPoint *bp;
+ float *tmp;
+
+ BLI_assert(nbr > gtd->num_points);
+
+ /* distances */
+ tmp = gtd->dists;
+ gtd->dists = MEM_callocN(sizeof(float) * nbr, __func__);
+ if (tmp) {
+ memcpy(gtd->dists, tmp, sizeof(float) * gtd->num_points);
+ MEM_freeN(tmp);
+ }
+
+ /* times */
+ tmp = gtd->times;
+ gtd->times = MEM_callocN(sizeof(float) * nbr, __func__);
+ if (tmp) {
+ memcpy(gtd->times, tmp, sizeof(float) * gtd->num_points);
+ MEM_freeN(tmp);
+ }
+
+ gtd->num_points = nbr;
+}
+
+/* add stroke point to timing buffers */
+static void gp_timing_data_add_point(tGpTimingData *gtd, double stroke_inittime, float time, float delta_dist)
+{
+ if (time < 0.0f) {
+ /* This is a gap, negative value! */
+ gtd->times[gtd->cur_point] = -(((float)(stroke_inittime - gtd->inittime)) + time);
+ gtd->tot_time = -gtd->times[gtd->cur_point];
+
+ gtd->gap_tot_time += gtd->times[gtd->cur_point] - gtd->times[gtd->cur_point - 1];
+ }
+ else {
+ gtd->times[gtd->cur_point] = (((float)(stroke_inittime - gtd->inittime)) + time);
+ gtd->tot_time = (gtd->times[gtd->cur_point]);
+ }
+
+ gtd->tot_dist += delta_dist;
+ gtd->dists[gtd->cur_point] = gtd->tot_dist;
+
+ gtd->cur_point++;
+}
+
+/* In frames! Binary search for FCurve keys have a threshold of 0.01, so we can't set
+ * arbitrarily close points - this is esp. important with NoGaps mode!
+ */
+#define MIN_TIME_DELTA 0.02f
+
+/* Loop over next points to find the end of the stroke, and compute */
+static int gp_find_end_of_stroke_idx(tGpTimingData *gtd, int idx, int nbr_gaps, int *nbr_done_gaps,
+ float tot_gaps_time, float delta_time, float *next_delta_time)
+{
+ int j;
+
+ for (j = idx + 1; j < gtd->num_points; j++) {
+ if (gtd->times[j] < 0) {
+ gtd->times[j] = -gtd->times[j];
+ if (gtd->mode == GP_STROKECONVERT_TIMING_CUSTOMGAP) {
+ /* In this mode, gap time between this stroke and the next should be 0 currently...
+ * So we have to compute its final duration!
+ */
+ if (gtd->gap_randomness > 0.0f) {
+ /* We want gaps that are in gtd->gap_duration +/- gtd->gap_randomness range,
+ * and which sum to exactly tot_gaps_time...
+ */
+ int rem_gaps = nbr_gaps - (*nbr_done_gaps);
+ if (rem_gaps < 2) {
+ /* Last gap, just give remaining time! */
+ *next_delta_time = tot_gaps_time;
+ }
+ else {
+ float delta, min, max;
+
+ /* This code ensures that if the first gaps have been shorter than average gap_duration,
+ * next gaps will tend to be longer (i.e. try to recover the lateness), and vice-versa!
+ */
+ delta = delta_time - (gtd->gap_duration * (*nbr_done_gaps));
+
+ /* Clamp min between [-gap_randomness, 0.0], with lower delta giving higher min */
+ min = -gtd->gap_randomness - delta;
+ CLAMP(min, -gtd->gap_randomness, 0.0f);
+
+ /* Clamp max between [0.0, gap_randomness], with lower delta giving higher max */
+ max = gtd->gap_randomness - delta;
+ CLAMP(max, 0.0f, gtd->gap_randomness);
+ *next_delta_time += gtd->gap_duration + (BLI_frand() * (max - min)) + min;
+ }
+ }
+ else {
+ *next_delta_time += gtd->gap_duration;
+ }
+ }
+ (*nbr_done_gaps)++;
+ break;
+ }
+ }
+
+ return j - 1;
+}
+
+static void gp_stroke_path_animation_preprocess_gaps(tGpTimingData *gtd, int *nbr_gaps, float *tot_gaps_time)
+{
+ int i;
+ float delta_time = 0.0f;
+
+ for (i = 0; i < gtd->num_points; i++) {
+ if (gtd->times[i] < 0 && i) {
+ (*nbr_gaps)++;
+ gtd->times[i] = -gtd->times[i] - delta_time;
+ delta_time += gtd->times[i] - gtd->times[i - 1];
+ gtd->times[i] = -gtd->times[i - 1]; /* Temp marker, values *have* to be different! */
+ }
+ else {
+ gtd->times[i] -= delta_time;
+ }
+ }
+ gtd->tot_time -= delta_time;
+
+ *tot_gaps_time = (float)(*nbr_gaps) * gtd->gap_duration;
+ gtd->tot_time += *tot_gaps_time;
+ if (G.debug & G_DEBUG) {
+ printf("%f, %f, %f, %d\n", gtd->tot_time, delta_time, *tot_gaps_time, *nbr_gaps);
+ }
+ if (gtd->gap_randomness > 0.0f) {
+ BLI_srandom(gtd->seed);
+ }
+}
+
+static void gp_stroke_path_animation_add_keyframes(ReportList *reports, PointerRNA ptr, PropertyRNA *prop, FCurve *fcu,
+ Curve *cu, tGpTimingData *gtd, float time_range,
+ int nbr_gaps, float tot_gaps_time)
+{
+ /* Use actual recorded timing! */
+ float time_start = (float)gtd->start_frame;
+
+ float last_valid_time = 0.0f;
+ int end_stroke_idx = -1, start_stroke_idx = 0;
+ float end_stroke_time = 0.0f;
+
+ /* CustomGaps specific */
+ float delta_time = 0.0f, next_delta_time = 0.0f;
+ int nbr_done_gaps = 0;
+
int i;
+ float cfra;
+
+ /* This is a bit tricky, as:
+ * - We can't add arbitrarily close points on FCurve (in time).
+ * - We *must* have all "caps" points of all strokes in FCurve, as much as possible!
+ */
+ for (i = 0; i < gtd->num_points; i++) {
+ /* If new stroke... */
+ if (i > end_stroke_idx) {
+ start_stroke_idx = i;
+ delta_time = next_delta_time;
+ /* find end of that new stroke */
+ end_stroke_idx = gp_find_end_of_stroke_idx(gtd, i, nbr_gaps, &nbr_done_gaps,
+ tot_gaps_time, delta_time, &next_delta_time);
+ /* This one should *never* be negative! */
+ end_stroke_time = time_start + ((gtd->times[end_stroke_idx] + delta_time) / gtd->tot_time * time_range);
+ }
+
+ /* Simple proportional stuff... */
+ cu->ctime = gtd->dists[i] / gtd->tot_dist * cu->pathlen;
+ cfra = time_start + ((gtd->times[i] + delta_time) / gtd->tot_time * time_range);
+
+ /* And now, the checks about timing... */
+ if (i == start_stroke_idx) {
+ /* If first point of a stroke, be sure it's enough ahead of last valid keyframe, and
+ * that the end point of the stroke is far enough!
+ * In case it is not, we keep the end point...
+ * Note that with CustomGaps mode, this is here we set the actual gap timing!
+ */
+ if ((end_stroke_time - last_valid_time) > MIN_TIME_DELTA * 2) {
+ if ((cfra - last_valid_time) < MIN_TIME_DELTA) {
+ cfra = last_valid_time + MIN_TIME_DELTA;
+ }
+ insert_keyframe_direct(reports, ptr, prop, fcu, cfra, INSERTKEY_FAST);
+ last_valid_time = cfra;
+ }
+ else if (G.debug & G_DEBUG) {
+ printf("\t Skipping start point %d, too close from end point %d\n", i, end_stroke_idx);
+ }
+ }
+ else if (i == end_stroke_idx) {
+ /* Always try to insert end point of a curve (should be safe enough, anyway...) */
+ if ((cfra - last_valid_time) < MIN_TIME_DELTA) {
+ cfra = last_valid_time + MIN_TIME_DELTA;
+ }
+ insert_keyframe_direct(reports, ptr, prop, fcu, cfra, INSERTKEY_FAST);
+ last_valid_time = cfra;
+ }
+ else {
+ /* Else ("middle" point), we only insert it if it's far enough from last keyframe,
+ * and also far enough from (not yet added!) end_stroke keyframe!
+ */
+ if ((cfra - last_valid_time) > MIN_TIME_DELTA && (end_stroke_time - cfra) > MIN_TIME_DELTA) {
+ insert_keyframe_direct(reports, ptr, prop, fcu, cfra, INSERTKEY_FAST);
+ last_valid_time = cfra;
+ }
+ else if (G.debug & G_DEBUG) {
+ printf("\t Skipping \"middle\" point %d, too close from last added point or end point %d\n",
+ i, end_stroke_idx);
+ }
+ }
+ }
+}
- /* create new 'nurb' within the curve */
- nu = (Nurb *)MEM_callocN(sizeof(Nurb), "gpstroke_to_path(nurb)");
+static void gp_stroke_path_animation(bContext *C, ReportList *reports, Curve *cu, tGpTimingData *gtd)
+{
+ Scene *scene = CTX_data_scene(C);
+ bAction *act;
+ FCurve *fcu;
+ PointerRNA ptr;
+ PropertyRNA *prop = NULL;
+ int nbr_gaps = 0, i;
+
+ if (gtd->mode == GP_STROKECONVERT_TIMING_NONE)
+ return;
+
+ /* gap_duration and gap_randomness are in frames, but we need seconds!!! */
+ gtd->gap_duration = FRA2TIME(gtd->gap_duration);
+ gtd->gap_randomness = FRA2TIME(gtd->gap_randomness);
- nu->pntsu = gps->totpoints;
- nu->pntsv = 1;
- nu->orderu = gps->totpoints;
- nu->flagu = CU_NURB_ENDPOINT;
- nu->resolu = 32;
+ /* Enable path! */
+ cu->flag |= CU_PATH;
+ cu->pathlen = gtd->frame_range;
- nu->bp = (BPoint *)MEM_callocN(sizeof(BPoint) * gps->totpoints, "bpoints");
+ /* Get RNA pointer to read/write path time values */
+ RNA_id_pointer_create((ID *)cu, &ptr);
+ prop = RNA_struct_find_property(&ptr, "eval_time");
+
+ /* Ensure we have an F-Curve to add keyframes to */
+ act = verify_adt_action((ID *)cu, TRUE);
+ fcu = verify_fcurve(act, NULL, &ptr, "eval_time", 0, TRUE);
+
+ if (G.debug & G_DEBUG) {
+ printf("%s: tot len: %f\t\ttot time: %f\n", __func__, gtd->tot_dist, gtd->tot_time);
+ for (i = 0; i < gtd->num_points; i++) {
+ printf("\tpoint %d:\t\tlen: %f\t\ttime: %f\n", i, gtd->dists[i], gtd->times[i]);
+ }
+ }
+
+ if (gtd->mode == GP_STROKECONVERT_TIMING_LINEAR) {
+ float cfra;
+
+ /* Linear extrapolation! */
+ fcu->extend = FCURVE_EXTRAPOLATE_LINEAR;
+
+ cu->ctime = 0.0f;
+ cfra = (float)gtd->start_frame;
+ insert_keyframe_direct(reports, ptr, prop, fcu, cfra, INSERTKEY_FAST);
+
+ cu->ctime = cu->pathlen;
+ if (gtd->realtime) {
+ cfra += (float)TIME2FRA(gtd->tot_time); /* Seconds to frames */
+ }
+ else {
+ cfra = (float)gtd->end_frame;
+ }
+ insert_keyframe_direct(reports, ptr, prop, fcu, cfra, INSERTKEY_FAST);
+ }
+ else {
+ /* Use actual recorded timing! */
+ float time_range;
+
+ /* CustomGaps specific */
+ float tot_gaps_time = 0.0f;
+
+ /* Pre-process gaps, in case we don't want to keep their original timing */
+ if (gtd->mode == GP_STROKECONVERT_TIMING_CUSTOMGAP) {
+ gp_stroke_path_animation_preprocess_gaps(gtd, &nbr_gaps, &tot_gaps_time);
+ }
+
+ if (gtd->realtime) {
+ time_range = (float)TIME2FRA(gtd->tot_time); /* Seconds to frames */
+ }
+ else {
+ time_range = (float)(gtd->end_frame - gtd->start_frame);
+ }
+
+ if (G.debug & G_DEBUG) {
+ printf("GP Stroke Path Conversion: Starting keying!\n");
+ }
+
+ gp_stroke_path_animation_add_keyframes(reports, ptr, prop, fcu, cu, gtd, time_range,
+ nbr_gaps, tot_gaps_time);
+ }
+
+ /* As we used INSERTKEY_FAST mode, we need to recompute all curve's handles now */
+ calchandles_fcurve(fcu);
+
+ if (G.debug & G_DEBUG) {
+ printf("%s: \ntot len: %f\t\ttot time: %f\n", __func__, gtd->tot_dist, gtd->tot_time);
+ for (i = 0; i < gtd->num_points; i++) {
+ printf("\tpoint %d:\t\tlen: %f\t\ttime: %f\n", i, gtd->dists[i], gtd->times[i]);
+ }
+ printf("\n\n");
+ }
+
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
+
+ /* send updates */
+ DAG_id_tag_update(&cu->id, 0);
+}
+
+#undef MIN_TIME_DELTA
+
+#define GAP_DFAC 0.05f
+#define WIDTH_CORR_FAC 0.1f
+#define BEZT_HANDLE_FAC 0.3f
+
+/* convert stroke to 3d path */
+static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curve *cu, rctf *subrect, Nurb **curnu,
+ float minmax_weights[2], float rad_fac, int stitch, tGpTimingData *gtd)
+{
+ bGPDspoint *pt;
+ Nurb *nu = (curnu) ? *curnu : NULL;
+ BPoint *bp, *prev_bp = NULL;
+ const int do_gtd = (gtd->mode != GP_STROKECONVERT_TIMING_NONE);
+ int i, old_nbp = 0;
+
+ /* create new 'nurb' or extend current one within the curve */
+ if (nu) {
+ old_nbp = nu->pntsu;
+
+ /* If stitch, the first point of this stroke is already present in current nu.
+ * Else, we have to add to additional points to make the zero-radius link between strokes.
+ */
+ BKE_nurb_points_add(nu, gps->totpoints + (stitch ? -1 : 2));
+ }
+ else {
+ nu = (Nurb *)MEM_callocN(sizeof(Nurb), "gpstroke_to_path(nurb)");
+
+ nu->pntsu = gps->totpoints;
+ nu->pntsv = 1;
+ nu->orderu = 2; /* point-to-point! */
+ nu->type = CU_NURBS;
+ nu->flagu = CU_NURB_ENDPOINT;
+ nu->resolu = cu->resolu;
+ nu->resolv = cu->resolv;
+ nu->knotsu = NULL;
+
+ nu->bp = (BPoint *)MEM_callocN(sizeof(BPoint) * nu->pntsu, "bpoints");
+
+ stitch = FALSE; /* Security! */
+ }
+
+ if (do_gtd) {
+ _gp_timing_data_set_nbr(gtd, nu->pntsu);
+ }
+
+ /* If needed, make the link between both strokes with two zero-radius additional points */
+ /* About "zero-radius" point interpolations:
+ * - If we have at least two points in current curve (most common case), we linearly extrapolate
+ * the last segment to get the first point (p1) position and timing.
+ * - If we do not have those (quite odd, but may happen), we linearly interpolate the last point
+ * with the first point of the current stroke.
+ * The same goes for the second point, first segment of the current stroke is "negatively" extrapolated
+ * if it exists, else (if the stroke is a single point), linear interpolation with last curve point...
+ */
+ if (curnu && !stitch && old_nbp) {
+ float p1[3], p2[3], p[3], next_p[3];
+ float delta_time;
+
+ prev_bp = NULL;
+ if ((old_nbp > 1) && gps->prev && (gps->prev->totpoints > 1)) {
+ /* Only use last curve segment if previous stroke was not a single-point one! */
+ prev_bp = nu->bp + old_nbp - 2;
+ }
+ bp = nu->bp + old_nbp - 1;
+
+ /* XXX We do this twice... Not sure it's worth to bother about this! */
+ gp_strokepoint_convertcoords(C, gps, gps->points, p, subrect);
+ if (prev_bp) {
+ interp_v3_v3v3(p1, prev_bp->vec, bp->vec, 1.0f + GAP_DFAC);
+ }
+ else {
+ interp_v3_v3v3(p1, bp->vec, p, GAP_DFAC);
+ }
+
+ if (gps->totpoints > 1) {
+ /* XXX We do this twice... Not sure it's worth to bother about this! */
+ gp_strokepoint_convertcoords(C, gps, gps->points + 1, next_p, subrect);
+ interp_v3_v3v3(p2, p, next_p, -GAP_DFAC);
+ }
+ else {
+ interp_v3_v3v3(p2, p, bp->vec, GAP_DFAC);
+ }
+
+ /* First point */
+ bp++;
+ copy_v3_v3(bp->vec, p1);
+ bp->vec[3] = 1.0f;
+ bp->f1 = SELECT;
+ minmax_weights[0] = bp->radius = bp->weight = 0.0f;
+ if (do_gtd) {
+ if (prev_bp) {
+ delta_time = gtd->tot_time + (gtd->tot_time - gtd->times[gtd->cur_point - 1]) * GAP_DFAC;
+ }
+ else {
+ delta_time = gtd->tot_time + (((float)(gps->inittime - gtd->inittime)) - gtd->tot_time) * GAP_DFAC;
+ }
+ gp_timing_data_add_point(gtd, gtd->inittime, delta_time, len_v3v3((bp - 1)->vec, p1));
+ }
+
+ /* Second point */
+ bp++;
+ copy_v3_v3(bp->vec, p2);
+ bp->vec[3] = 1.0f;
+ bp->f1 = SELECT;
+ minmax_weights[0] = bp->radius = bp->weight = 0.0f;
+ if (do_gtd) {
+ /* This negative delta_time marks the gap! */
+ if (gps->totpoints > 1) {
+ delta_time = ((gps->points + 1)->time - gps->points->time) * -GAP_DFAC;
+ }
+ else {
+ delta_time = -(((float)(gps->inittime - gtd->inittime)) - gtd->tot_time) * GAP_DFAC;
+ }
+ gp_timing_data_add_point(gtd, gps->inittime, delta_time, len_v3v3(p1, p2));
+ }
+
+ old_nbp += 2;
+ }
+ if (old_nbp && do_gtd) {
+ prev_bp = nu->bp + old_nbp - 1;
+ }
/* add points */
- for (i = 0, pt = gps->points, bp = nu->bp; i < gps->totpoints; i++, pt++, bp++) {
+ for (i = (stitch) ? 1 : 0, pt = gps->points + ((stitch) ? 1 : 0), bp = nu->bp + old_nbp;
+ i < gps->totpoints;
+ i++, pt++, bp++)
+ {
float p3d[3];
+ float width = pt->pressure * gpl->thickness * WIDTH_CORR_FAC;
/* get coordinates to add at */
gp_strokepoint_convertcoords(C, gps, pt, p3d, subrect);
copy_v3_v3(bp->vec, p3d);
+ bp->vec[3] = 1.0f;
/* set settings */
bp->f1 = SELECT;
- bp->radius = bp->weight = pt->pressure * gpl->thickness;
+ bp->radius = width * rad_fac;
+ bp->weight = width;
+ CLAMP(bp->weight, 0.0f, 1.0f);
+ if (bp->weight < minmax_weights[0]) {
+ minmax_weights[0] = bp->weight;
+ }
+ else if (bp->weight > minmax_weights[1]) {
+ minmax_weights[1] = bp->weight;
+ }
+
+ /* Update timing data */
+ if (do_gtd) {
+ gp_timing_data_add_point(gtd, gps->inittime, pt->time, (prev_bp) ? len_v3v3(prev_bp->vec, p3d) : 0.0f);
+ }
+ prev_bp = bp;
}
/* add nurb to curve */
- BLI_addtail(&cu->nurb, nu);
+ if (!curnu || !*curnu) {
+ BLI_addtail(&cu->nurb, nu);
+ }
+ if (curnu) {
+ *curnu = nu;
+ }
+
+ BKE_nurb_knot_calc_u(nu);
}
static int gp_camera_view_subrect(bContext *C, rctf *subrect)
{
View3D *v3d = CTX_wm_view3d(C);
ARegion *ar = CTX_wm_region(C);
-
+
if (v3d) {
RegionView3D *rv3d = ar->regiondata;
@@ -491,48 +995,178 @@ static int gp_camera_view_subrect(bContext *C, rctf *subrect)
return 1;
}
}
-
+
return 0;
}
/* convert stroke to 3d bezier */
-static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curve *cu, rctf *subrect)
+static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curve *cu, rctf *subrect, Nurb **curnu,
+ float minmax_weights[2], float rad_fac, int stitch, tGpTimingData *gtd)
{
bGPDspoint *pt;
- Nurb *nu;
- BezTriple *bezt;
- int i, tot;
+ Nurb *nu = (curnu) ? *curnu : NULL;
+ BezTriple *bezt, *prev_bezt = NULL;
+ int i, tot, old_nbezt = 0;
float p3d_cur[3], p3d_prev[3], p3d_next[3];
+ const int do_gtd = (gtd->mode != GP_STROKECONVERT_TIMING_NONE);
+
+ /* create new 'nurb' or extend current one within the curve */
+ if (nu) {
+ old_nbezt = nu->pntsu;
+ /* If we do stitch, first point of current stroke is assumed the same as last point of previous stroke,
+ * so no need to add it.
+ * If no stitch, we want to add two additional points to make a "zero-radius" link between both strokes.
+ */
+ BKE_nurb_bezierPoints_add(nu, gps->totpoints + ((stitch) ? -1 : 2));
+ }
+ else {
+ nu = (Nurb *)MEM_callocN(sizeof(Nurb), "gpstroke_to_bezier(nurb)");
+
+ nu->pntsu = gps->totpoints;
+ nu->resolu = 12;
+ nu->resolv = 12;
+ nu->type = CU_BEZIER;
+ nu->bezt = (BezTriple *)MEM_callocN(gps->totpoints * sizeof(BezTriple), "bezts");
+
+ stitch = FALSE; /* Security! */
+ }
- /* create new 'nurb' within the curve */
- nu = (Nurb *)MEM_callocN(sizeof(Nurb), "gpstroke_to_bezier(nurb)");
-
- nu->pntsu = gps->totpoints;
- nu->resolu = 12;
- nu->resolv = 12;
- nu->type = CU_BEZIER;
- nu->bezt = (BezTriple *)MEM_callocN(gps->totpoints * sizeof(BezTriple), "bezts");
+ if (do_gtd) {
+ _gp_timing_data_set_nbr(gtd, nu->pntsu);
+ }
tot = gps->totpoints;
/* get initial coordinates */
pt = gps->points;
if (tot) {
- gp_strokepoint_convertcoords(C, gps, pt, p3d_cur, subrect);
+ gp_strokepoint_convertcoords(C, gps, pt, (stitch) ? p3d_prev : p3d_cur, subrect);
if (tot > 1) {
- gp_strokepoint_convertcoords(C, gps, pt + 1, p3d_next, subrect);
+ gp_strokepoint_convertcoords(C, gps, pt + 1, (stitch) ? p3d_cur : p3d_next, subrect);
+ }
+ if (stitch && tot > 2) {
+ gp_strokepoint_convertcoords(C, gps, pt + 2, p3d_next, subrect);
}
}
+ /* If needed, make the link between both strokes with two zero-radius additional points */
+ if (curnu && old_nbezt) {
+ /* Update last point's second handle */
+ if (stitch) {
+ float h2[3];
+ bezt = nu->bezt + old_nbezt - 1;
+ interp_v3_v3v3(h2, bezt->vec[1], p3d_cur, BEZT_HANDLE_FAC);
+ copy_v3_v3(bezt->vec[2], h2);
+ pt++;
+ }
+
+ /* Create "link points" */
+ /* About "zero-radius" point interpolations:
+ * - If we have at least two points in current curve (most common case), we linearly extrapolate
+ * the last segment to get the first point (p1) position and timing.
+ * - If we do not have those (quite odd, but may happen), we linearly interpolate the last point
+ * with the first point of the current stroke.
+ * The same goes for the second point, first segment of the current stroke is "negatively" extrapolated
+ * if it exists, else (if the stroke is a single point), linear interpolation with last curve point...
+ */
+ else {
+ float h1[3], h2[3], p1[3], p2[3];
+ float delta_time;
+
+ prev_bezt = NULL;
+ if (old_nbezt > 1 && gps->prev && gps->prev->totpoints > 1) {
+ /* Only use last curve segment if previous stroke was not a single-point one! */
+ prev_bezt = nu->bezt + old_nbezt - 2;
+ }
+ bezt = nu->bezt + old_nbezt - 1;
+ if (prev_bezt) {
+ interp_v3_v3v3(p1, prev_bezt->vec[1], bezt->vec[1], 1.0f + GAP_DFAC);
+ }
+ else {
+ interp_v3_v3v3(p1, bezt->vec[1], p3d_cur, GAP_DFAC);
+ }
+ if (tot > 1) {
+ interp_v3_v3v3(p2, p3d_cur, p3d_next, -GAP_DFAC);
+ }
+ else {
+ interp_v3_v3v3(p2, p3d_cur, bezt->vec[1], GAP_DFAC);
+ }
+
+ /* Second handle of last point */
+ interp_v3_v3v3(h2, bezt->vec[1], p1, BEZT_HANDLE_FAC);
+ copy_v3_v3(bezt->vec[2], h2);
+
+ /* First point */
+ interp_v3_v3v3(h1, p1, bezt->vec[1], BEZT_HANDLE_FAC);
+ interp_v3_v3v3(h2, p1, p2, BEZT_HANDLE_FAC);
+
+ bezt++;
+ copy_v3_v3(bezt->vec[0], h1);
+ copy_v3_v3(bezt->vec[1], p1);
+ copy_v3_v3(bezt->vec[2], h2);
+ bezt->h1 = bezt->h2 = HD_FREE;
+ bezt->f1 = bezt->f2 = bezt->f3 = SELECT;
+ minmax_weights[0] = bezt->radius = bezt->weight = 0.0f;
+
+ if (do_gtd) {
+ if (prev_bezt) {
+ delta_time = gtd->tot_time + (gtd->tot_time - gtd->times[gtd->cur_point - 1]) * GAP_DFAC;
+ }
+ else {
+ delta_time = gtd->tot_time + (((float)(gps->inittime - gtd->inittime)) - gtd->tot_time) * GAP_DFAC;
+ }
+ gp_timing_data_add_point(gtd, gtd->inittime, delta_time, len_v3v3((bezt - 1)->vec[1], p1));
+ }
+
+ /* Second point */
+ interp_v3_v3v3(h1, p2, p1, BEZT_HANDLE_FAC);
+ interp_v3_v3v3(h2, p2, p3d_cur, BEZT_HANDLE_FAC);
+
+ bezt++;
+ copy_v3_v3(bezt->vec[0], h1);
+ copy_v3_v3(bezt->vec[1], p2);
+ copy_v3_v3(bezt->vec[2], h2);
+ bezt->h1 = bezt->h2 = HD_FREE;
+ bezt->f1 = bezt->f2 = bezt->f3 = SELECT;
+ minmax_weights[0] = bezt->radius = bezt->weight = 0.0f;
+
+ if (do_gtd) {
+ /* This negative delta_time marks the gap! */
+ if (tot > 1) {
+ delta_time = ((gps->points + 1)->time - gps->points->time) * -GAP_DFAC;
+ }
+ else {
+ delta_time = -(((float)(gps->inittime - gtd->inittime)) - gtd->tot_time) * GAP_DFAC;
+ }
+ gp_timing_data_add_point(gtd, gps->inittime, delta_time, len_v3v3(p1, p2));
+ }
+
+ old_nbezt += 2;
+ copy_v3_v3(p3d_prev, p2);
+ }
+ }
+ if (old_nbezt && do_gtd) {
+ prev_bezt = nu->bezt + old_nbezt - 1;
+ }
+
/* add points */
- for (i = 0, bezt = nu->bezt; i < tot; i++, pt++, bezt++) {
+ for (i = stitch ? 1 : 0, bezt = nu->bezt + old_nbezt; i < tot; i++, pt++, bezt++) {
float h1[3], h2[3];
+ float width = pt->pressure * gpl->thickness * WIDTH_CORR_FAC;
- if (i) interp_v3_v3v3(h1, p3d_cur, p3d_prev, 0.3);
- else interp_v3_v3v3(h1, p3d_cur, p3d_next, -0.3);
+ if (i || old_nbezt) {
+ interp_v3_v3v3(h1, p3d_cur, p3d_prev, BEZT_HANDLE_FAC);
+ }
+ else {
+ interp_v3_v3v3(h1, p3d_cur, p3d_next, -BEZT_HANDLE_FAC);
+ }
- if (i < tot - 1) interp_v3_v3v3(h2, p3d_cur, p3d_next, 0.3);
- else interp_v3_v3v3(h2, p3d_cur, p3d_prev, -0.3);
+ if (i < tot - 1) {
+ interp_v3_v3v3(h2, p3d_cur, p3d_next, BEZT_HANDLE_FAC);
+ }
+ else {
+ interp_v3_v3v3(h2, p3d_cur, p3d_prev, -BEZT_HANDLE_FAC);
+ }
copy_v3_v3(bezt->vec[0], h1);
copy_v3_v3(bezt->vec[1], p3d_cur);
@@ -541,7 +1175,20 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
/* set settings */
bezt->h1 = bezt->h2 = HD_FREE;
bezt->f1 = bezt->f2 = bezt->f3 = SELECT;
- bezt->radius = bezt->weight = pt->pressure * gpl->thickness * 0.1f;
+ bezt->radius = width * rad_fac;
+ bezt->weight = width;
+ CLAMP(bezt->weight, 0.0f, 1.0f);
+ if (bezt->weight < minmax_weights[0]) {
+ minmax_weights[0] = bezt->weight;
+ }
+ else if (bezt->weight > minmax_weights[1]) {
+ minmax_weights[1] = bezt->weight;
+ }
+
+ /* Update timing data */
+ if (do_gtd) {
+ gp_timing_data_add_point(gtd, gps->inittime, pt->time, prev_bezt ? len_v3v3(prev_bezt->vec[1], p3d_cur) : 0.0f);
+ }
/* shift coord vects */
copy_v3_v3(p3d_prev, p3d_cur);
@@ -550,31 +1197,103 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
if (i + 2 < tot) {
gp_strokepoint_convertcoords(C, gps, pt + 2, p3d_next, subrect);
}
+
+ prev_bezt = bezt;
}
-
+
/* must calculate handles or else we crash */
BKE_nurb_handles_calc(nu);
- /* add nurb to curve */
- BLI_addtail(&cu->nurb, nu);
+ if (!curnu || !*curnu) {
+ BLI_addtail(&cu->nurb, nu);
+ }
+ if (curnu) {
+ *curnu = nu;
+ }
+}
+
+#undef GAP_DFAC
+#undef WIDTH_CORR_FAC
+#undef BEZT_HANDLE_FAC
+
+static void gp_stroke_finalize_curve_endpoints(Curve *cu)
+{
+ /* start */
+ Nurb *nu = cu->nurb.first;
+ int i = 0;
+ if (nu->bezt) {
+ BezTriple *bezt = nu->bezt;
+ if (bezt) {
+ bezt[i].weight = bezt[i].radius = 0.0f;
+ }
+ }
+ else if (nu->bp) {
+ BPoint *bp = nu->bp;
+ if (bp) {
+ bp[i].weight = bp[i].radius = 0.0f;
+ }
+ }
+
+ /* end */
+ nu = cu->nurb.last;
+ i = nu->pntsu - 1;
+ if (nu->bezt) {
+ BezTriple *bezt = nu->bezt;
+ if (bezt) {
+ bezt[i].weight = bezt[i].radius = 0.0f;
+ }
+ }
+ else if (nu->bp) {
+ BPoint *bp = nu->bp;
+ if (bp) {
+ bp[i].weight = bp[i].radius = 0.0f;
+ }
+ }
+}
+
+static void gp_stroke_norm_curve_weights(Curve *cu, float minmax_weights[2])
+{
+ Nurb *nu;
+ const float delta = minmax_weights[0];
+ const float fac = 1.0f / (minmax_weights[1] - delta);
+ int i;
+
+ for (nu = cu->nurb.first; nu; nu = nu->next) {
+ if (nu->bezt) {
+ BezTriple *bezt = nu->bezt;
+ for (i = 0; i < nu->pntsu; i++, bezt++) {
+ bezt->weight = (bezt->weight - delta) * fac;
+ }
+ }
+ else if (nu->bp) {
+ BPoint *bp = nu->bp;
+ for (i = 0; i < nu->pntsu; i++, bp++) {
+ bp->weight = (bp->weight - delta) * fac;
+ }
+ }
+ }
}
/* convert a given grease-pencil layer to a 3d-curve representation (using current view if appropriate) */
-static void gp_layer_to_curve(bContext *C, bGPdata *gpd, bGPDlayer *gpl, short mode)
+static void gp_layer_to_curve(bContext *C, ReportList *reports, bGPdata *gpd, bGPDlayer *gpl, int mode,
+ int norm_weights, float rad_fac, int link_strokes, tGpTimingData *gtd)
{
Scene *scene = CTX_data_scene(C);
bGPDframe *gpf = gpencil_layer_getframe(gpl, CFRA, 0);
- bGPDstroke *gps;
+ bGPDstroke *gps, *prev_gps = NULL;
Object *ob;
Curve *cu;
+ Nurb *nu = NULL;
+ Base *base = BASACT, *newbase = NULL;
+ float minmax_weights[2] = {1.0f, 0.0f};
/* camera framing */
rctf subrect, *subrect_ptr = NULL;
-
+
/* error checking */
if (ELEM3(NULL, gpd, gpl, gpf))
return;
-
+
/* only convert if there are any strokes on this layer's frame to convert */
if (gpf->strokes.first == NULL)
return;
@@ -583,7 +1302,7 @@ static void gp_layer_to_curve(bContext *C, bGPdata *gpd, bGPDlayer *gpl, short m
if (gp_camera_view_subrect(C, &subrect)) {
subrect_ptr = &subrect;
}
-
+
/* init the curve object (remove rotation and get curve data from it)
* - must clear transforms set on object, as those skew our results
*/
@@ -597,24 +1316,125 @@ static void gp_layer_to_curve(bContext *C, bGPdata *gpd, bGPDlayer *gpl, short m
rename_id((ID *)ob, gpl->info);
rename_id((ID *)cu, gpl->info);
+ gtd->inittime = ((bGPDstroke *)gpf->strokes.first)->inittime;
+
/* add points to curve */
for (gps = gpf->strokes.first; gps; gps = gps->next) {
+ /* Detect new strokes created because of GP_STROKE_BUFFER_MAX reached,
+ * and stitch them to previous one.
+ */
+ int stitch = FALSE;
+
+ if (prev_gps) {
+ bGPDspoint *pt1 = prev_gps->points + prev_gps->totpoints - 1;
+ bGPDspoint *pt2 = gps->points;
+
+ if ((pt1->x == pt2->x) && (pt1->y == pt2->y)) {
+ stitch = TRUE;
+ }
+ }
+
+ /* Decide whether we connect this stroke to previous one */
+ if (!(stitch || link_strokes)) {
+ nu = NULL;
+ }
+
switch (mode) {
case GP_STROKECONVERT_PATH:
- gp_stroke_to_path(C, gpl, gps, cu, subrect_ptr);
+ gp_stroke_to_path(C, gpl, gps, cu, subrect_ptr, &nu, minmax_weights, rad_fac, stitch, gtd);
break;
case GP_STROKECONVERT_CURVE:
- gp_stroke_to_bezier(C, gpl, gps, cu, subrect_ptr);
+ gp_stroke_to_bezier(C, gpl, gps, cu, subrect_ptr, &nu, minmax_weights, rad_fac, stitch, gtd);
break;
default:
BLI_assert(!"invalid mode");
break;
}
+ prev_gps = gps;
+ }
+
+ /* If link_strokes, be sure first and last points have a zero weight/size! */
+ if (link_strokes)
+ gp_stroke_finalize_curve_endpoints(cu);
+
+ /* Update curve's weights, if needed */
+ if (norm_weights && ((minmax_weights[0] > 0.0f) || (minmax_weights[1] < 1.0f)))
+ gp_stroke_norm_curve_weights(cu, minmax_weights);
+
+ /* Create the path animation, if needed */
+ gp_stroke_path_animation(C, reports, cu, gtd);
+
+ /* Reset original object as active, else we can't edit operator's settings!!! */
+ /* set layers OK */
+ newbase = BASACT;
+ if (base) {
+ newbase->lay = base->lay;
+ ob->lay = newbase->lay;
+ }
+
+ /* restore, BKE_object_add sets active */
+ BASACT = base;
+ if (base) {
+ base->flag |= SELECT;
}
}
/* --- */
+/* Check a GP layer has valid timing data! Else, most timing options are hidden in the operator.
+ * op may be NULL.
+ */
+static int gp_convert_check_has_valid_timing(bContext *C, bGPDlayer *gpl, wmOperator *op)
+{
+ Scene *scene = CTX_data_scene(C);
+ bGPDframe *gpf = gpencil_layer_getframe(gpl, CFRA, 0);
+ bGPDstroke *gps = gpf->strokes.first;
+ bGPDspoint *pt;
+ double base_time, cur_time, prev_time = -1.0;
+ int i, valid = TRUE;
+
+ do {
+ base_time = cur_time = gps->inittime;
+ if (cur_time <= prev_time) {
+ valid = FALSE;
+ break;
+ }
+
+ prev_time = cur_time;
+ for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+ cur_time = base_time + (double)pt->time;
+ /* First point of a stroke should have the same time as stroke's inittime,
+ * so it's the only case where equality is allowed!
+ */
+ if ((i && cur_time <= prev_time) || (cur_time < prev_time)) {
+ valid = FALSE;
+ break;
+ }
+ prev_time = cur_time;
+ }
+
+ if (!valid) {
+ break;
+ }
+ } while ((gps = gps->next));
+
+ if (op) {
+ RNA_boolean_set(op->ptr, "use_timing_data", valid);
+ }
+ return valid;
+}
+
+/* Check end_frame is always > start frame! */
+static void gp_convert_set_end_frame(struct Main *UNUSED(main), struct Scene *UNUSED(scene), struct PointerRNA *ptr)
+{
+ int start_frame = RNA_int_get(ptr, "start_frame");
+ int end_frame = RNA_int_get(ptr, "end_frame");
+
+ if (end_frame <= start_frame) {
+ RNA_int_set(ptr, "end_frame", start_frame + 1);
+ }
+}
+
static int gp_convert_poll(bContext *C)
{
bGPdata *gpd = gpencil_data_get_active(C);
@@ -627,45 +1447,204 @@ static int gp_convert_poll(bContext *C)
static int gp_convert_layer_exec(bContext *C, wmOperator *op)
{
+ PropertyRNA *prop = RNA_struct_find_property(op->ptr, "use_timing_data");
bGPdata *gpd = gpencil_data_get_active(C);
bGPDlayer *gpl = gpencil_layer_getactive(gpd);
Scene *scene = CTX_data_scene(C);
int mode = RNA_enum_get(op->ptr, "type");
-
+ int norm_weights = RNA_boolean_get(op->ptr, "use_normalize_weights");
+ float rad_fac = RNA_float_get(op->ptr, "radius_multiplier");
+ int link_strokes = RNA_boolean_get(op->ptr, "use_link_strokes");
+ int valid_timing;
+ tGpTimingData gtd;
+
/* check if there's data to work with */
if (gpd == NULL) {
- BKE_report(op->reports, RPT_ERROR, "No grease pencil data to work on");
+ BKE_report(op->reports, RPT_ERROR, "No Grease Pencil data to work on");
return OPERATOR_CANCELLED;
}
-
- gp_layer_to_curve(C, gpd, gpl, mode);
-
+
+ if (!RNA_property_is_set(op->ptr, prop) && !gp_convert_check_has_valid_timing(C, gpl, op)) {
+ BKE_report(op->reports, RPT_WARNING,
+ "Current Grease Pencil strokes have no valid timing data, most timing options will be hidden!");
+ }
+ valid_timing = RNA_property_boolean_get(op->ptr, prop);
+
+ gtd.mode = RNA_enum_get(op->ptr, "timing_mode");
+ /* Check for illegal timing mode! */
+ if (!valid_timing && !ELEM(gtd.mode, GP_STROKECONVERT_TIMING_NONE, GP_STROKECONVERT_TIMING_LINEAR)) {
+ gtd.mode = GP_STROKECONVERT_TIMING_LINEAR;
+ RNA_enum_set(op->ptr, "timing_mode", gtd.mode);
+ }
+ if (!link_strokes) {
+ gtd.mode = GP_STROKECONVERT_TIMING_NONE;
+ }
+
+ /* grab all relevant settings */
+ gtd.frame_range = RNA_int_get(op->ptr, "frame_range");
+ gtd.start_frame = RNA_int_get(op->ptr, "start_frame");
+ gtd.realtime = valid_timing ? RNA_boolean_get(op->ptr, "use_realtime") : FALSE;
+ gtd.end_frame = RNA_int_get(op->ptr, "end_frame");
+ gtd.gap_duration = RNA_float_get(op->ptr, "gap_duration");
+ gtd.gap_randomness = RNA_float_get(op->ptr, "gap_randomness");
+ gtd.gap_randomness = min_ff(gtd.gap_randomness, gtd.gap_duration);
+ gtd.seed = RNA_int_get(op->ptr, "seed");
+ gtd.num_points = gtd.cur_point = 0;
+ gtd.dists = gtd.times = NULL;
+ gtd.tot_dist = gtd.tot_time = gtd.gap_tot_time = 0.0f;
+ gtd.inittime = 0.0;
+
+ /* perform conversion */
+ gp_layer_to_curve(C, op->reports, gpd, gpl, mode, norm_weights, rad_fac, link_strokes, &gtd);
+
+ /* free temp memory */
+ if (gtd.dists) {
+ MEM_freeN(gtd.dists);
+ gtd.dists = NULL;
+ }
+ if (gtd.times) {
+ MEM_freeN(gtd.times);
+ gtd.times = NULL;
+ }
+
/* notifiers */
WM_event_add_notifier(C, NC_OBJECT | NA_ADDED, NULL);
WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
-
+
/* done */
return OPERATOR_FINISHED;
}
+static int gp_convert_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop)
+{
+ const char *prop_id = RNA_property_identifier(prop);
+ int link_strokes = RNA_boolean_get(ptr, "use_link_strokes");
+ int timing_mode = RNA_enum_get(ptr, "timing_mode");
+ int realtime = RNA_boolean_get(ptr, "use_realtime");
+ float gap_duration = RNA_float_get(ptr, "gap_duration");
+ float gap_randomness = RNA_float_get(ptr, "gap_randomness");
+ int valid_timing = RNA_boolean_get(ptr, "use_timing_data");
+
+ /* Always show those props */
+ if (strcmp(prop_id, "type") == 0 ||
+ strcmp(prop_id, "use_normalize_weights") == 0 ||
+ strcmp(prop_id, "radius_multiplier") == 0 ||
+ strcmp(prop_id, "use_link_strokes") == 0)
+ {
+ return TRUE;
+ }
+
+ /* Never show this prop */
+ if (strcmp(prop_id, "use_timing_data") == 0)
+ return FALSE;
+
+ if (link_strokes) {
+ /* Only show when link_stroke is TRUE */
+ if (strcmp(prop_id, "timing_mode") == 0)
+ return TRUE;
+
+ if (timing_mode != GP_STROKECONVERT_TIMING_NONE) {
+ /* Only show when link_stroke is TRUE and stroke timing is enabled */
+ if (strcmp(prop_id, "frame_range") == 0 ||
+ strcmp(prop_id, "start_frame") == 0)
+ {
+ return TRUE;
+ }
+
+ /* Only show if we have valid timing data! */
+ if (valid_timing && strcmp(prop_id, "use_realtime") == 0)
+ return TRUE;
+
+ /* Only show if realtime or valid_timing is FALSE! */
+ if ((!realtime || !valid_timing) && strcmp(prop_id, "end_frame") == 0)
+ return TRUE;
+
+ if (valid_timing && timing_mode == GP_STROKECONVERT_TIMING_CUSTOMGAP) {
+ /* Only show for custom gaps! */
+ if (strcmp(prop_id, "gap_duration") == 0)
+ return TRUE;
+
+ /* Only show randomness for non-null custom gaps! */
+ if (strcmp(prop_id, "gap_randomness") == 0 && (gap_duration > 0.0f))
+ return TRUE;
+
+ /* Only show seed for randomize action! */
+ if (strcmp(prop_id, "seed") == 0 && (gap_duration > 0.0f) && (gap_randomness > 0.0f))
+ return TRUE;
+ }
+ }
+ }
+
+ /* Else, hidden! */
+ return FALSE;
+}
+
+static void gp_convert_ui(bContext *C, wmOperator *op)
+{
+ uiLayout *layout = op->layout;
+ wmWindowManager *wm = CTX_wm_manager(C);
+ PointerRNA ptr;
+
+ RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
+
+ /* Main auto-draw call */
+ uiDefAutoButsRNA(layout, &ptr, gp_convert_draw_check_prop, '\0');
+}
+
void GPENCIL_OT_convert(wmOperatorType *ot)
{
+ PropertyRNA *prop;
+
/* identifiers */
ot->name = "Convert Grease Pencil";
ot->idname = "GPENCIL_OT_convert";
- ot->description = "Convert the active Grease Pencil layer to a new Object";
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ ot->description = "Convert the active Grease Pencil layer to a new Curve Object";
/* callbacks */
ot->invoke = WM_menu_invoke;
ot->exec = gp_convert_layer_exec;
ot->poll = gp_convert_poll;
+ ot->ui = gp_convert_ui;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
- ot->prop = RNA_def_enum(ot->srna, "type", prop_gpencil_convertmodes, 0, "Type", "");
+ ot->prop = RNA_def_enum(ot->srna, "type", prop_gpencil_convertmodes, 0, "Type", "Which type of curve to convert to");
+
+ RNA_def_boolean(ot->srna, "use_normalize_weights", TRUE, "Normalize Weight",
+ "Normalize weight (set from stroke width)");
+ RNA_def_float(ot->srna, "radius_multiplier", 1.0f, 0.0f, 1000.0f, "Radius Fac",
+ "Multiplier for the points' radii (set from stroke width)", 0.0f, 10.0f);
+ RNA_def_boolean(ot->srna, "use_link_strokes", TRUE, "Link Strokes",
+ "Whether to link strokes with zero-radius sections of curves");
+
+ prop = RNA_def_enum(ot->srna, "timing_mode", prop_gpencil_convert_timingmodes, GP_STROKECONVERT_TIMING_FULL,
+ "Timing Mode", "How to use timing data stored in strokes");
+ RNA_def_enum_funcs(prop, rna_GPConvert_mode_items);
+
+ RNA_def_int(ot->srna, "frame_range", 100, 1, 10000, "Frame Range",
+ "The duration of evaluation of the path control curve", 1, 1000);
+ RNA_def_int(ot->srna, "start_frame", 1, 1, 100000, "Start Frame",
+ "The start frame of the path control curve", 1, 100000);
+ RNA_def_boolean(ot->srna, "use_realtime", FALSE, "Realtime",
+ "Whether the path control curve reproduces the drawing in realtime, starting from Start Frame");
+ prop = RNA_def_int(ot->srna, "end_frame", 250, 1, 100000, "End Frame",
+ "The end frame of the path control curve (if Realtime is not set)", 1, 100000);
+ RNA_def_property_update_runtime(prop, gp_convert_set_end_frame);
+
+ RNA_def_float(ot->srna, "gap_duration", 0.0f, 0.0f, 10000.0f, "Gap Duration",
+ "Custom Gap mode: (Average) length of gaps, in frames "
+ "(Note: Realtime value, will be scaled if Realtime is not set)", 0.0f, 1000.0f);
+ RNA_def_float(ot->srna, "gap_randomness", 0.0f, 0.0f, 10000.0f, "Gap Randomness",
+ "Custom Gap mode: Number of frames that gap lengths can vary", 0.0f, 1000.0f);
+ RNA_def_int(ot->srna, "seed", 0, 0, 1000, "Random Seed",
+ "Custom Gap mode: Random generator seed", 0, 100);
+
+ /* Note: Internal use, this one will always be hidden by UI code... */
+ prop = RNA_def_boolean(ot->srna, "use_timing_data", FALSE, "Has Valid Timing",
+ "Whether the converted Grease Pencil layer has valid timing data (internal use)");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
/* ************************************************ */
diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c
index 432292c259d..3fbd4a8f736 100644
--- a/source/blender/editors/gpencil/gpencil_paint.c
+++ b/source/blender/editors/gpencil/gpencil_paint.c
@@ -39,6 +39,8 @@
#include "BLI_math.h"
#include "BLI_utildefines.h"
+#include "PIL_time.h"
+
#include "BKE_gpencil.h"
#include "BKE_context.h"
#include "BKE_global.h"
@@ -100,6 +102,14 @@ typedef struct tGPsdata {
short radius; /* radius of influence for eraser */
short flags; /* flags that can get set during runtime */
+
+ /* These need to be doubles, as (at least under unix) they are in seconds since epoch,
+ * float (and its 7 digits precision) is definitively not enough here!
+ * double, with its 15 digits precision, ensures us millisecond precision for a few centuries at least.
+ */
+ double inittime; /* Used when converting to path */
+ double curtime; /* Used when converting to path */
+ double ocurtime; /* Used when converting to path */
float imat[4][4]; /* inverted transformation matrix applying when converting coords from screen-space
* to region space */
@@ -203,7 +213,7 @@ static void gp_get_3d_reference(tGPsdata *p, float vec[3])
float *fp = give_cursor(p->scene, v3d);
/* the reference point used depends on the owner... */
-#if 0 // XXX: disabled for now, since we can't draw relative to the owner yet
+#if 0 /* XXX: disabled for now, since we can't draw relative to the owner yet */
if (p->ownerPtr.type == &RNA_Object) {
Object *ob = (Object *)p->ownerPtr.data;
@@ -251,7 +261,7 @@ static short gp_stroke_filtermval(tGPsdata *p, const int mval[2], int pmval[2])
}
/* convert screen-coordinates to buffer-coordinates */
-// XXX this method needs a total overhaul!
+/* XXX this method needs a total overhaul! */
static void gp_stroke_convertcoords(tGPsdata *p, const int mval[2], float out[3], float *depth)
{
bGPdata *gpd = p->gpd;
@@ -312,7 +322,7 @@ static void gp_stroke_convertcoords(tGPsdata *p, const int mval[2], float out[3]
}
/* add current stroke-point to buffer (returns whether point was successfully added) */
-static short gp_stroke_addpoint(tGPsdata *p, const int mval[2], float pressure)
+static short gp_stroke_addpoint(tGPsdata *p, const int mval[2], float pressure, double curtime)
{
bGPdata *gpd = p->gpd;
tGPspoint *pt;
@@ -327,6 +337,7 @@ static short gp_stroke_addpoint(tGPsdata *p, const int mval[2], float pressure)
/* store settings */
copy_v2_v2_int(&pt->x, mval);
pt->pressure = pressure;
+ pt->time = (float)(curtime - p->inittime);
/* increment buffer size */
gpd->sbuffer_size++;
@@ -340,6 +351,7 @@ static short gp_stroke_addpoint(tGPsdata *p, const int mval[2], float pressure)
/* store settings */
copy_v2_v2_int(&pt->x, mval);
pt->pressure = pressure;
+ pt->time = (float)(curtime - p->inittime);
/* if this is just the second point we've added, increment the buffer size
* so that it will be drawn properly...
@@ -363,6 +375,7 @@ static short gp_stroke_addpoint(tGPsdata *p, const int mval[2], float pressure)
/* store settings */
copy_v2_v2_int(&pt->x, mval);
pt->pressure = pressure;
+ pt->time = (float)(curtime - p->inittime);
/* increment counters */
gpd->sbuffer_size++;
@@ -380,10 +393,11 @@ static short gp_stroke_addpoint(tGPsdata *p, const int mval[2], float pressure)
/* store settings */
copy_v2_v2_int(&pt->x, mval);
pt->pressure = pressure;
+ pt->time = (float)(curtime - p->inittime);
/* if there's stroke for this poly line session add (or replace last) point
* to stroke. This allows to draw lines more interactively (see new segment
- * during mouse slide, i.e.)
+ * during mouse slide, e.g.)
*/
if (gp_stroke_added_check(p)) {
bGPDstroke *gps = p->gpf->strokes.last;
@@ -412,8 +426,9 @@ static short gp_stroke_addpoint(tGPsdata *p, const int mval[2], float pressure)
/* convert screen-coordinates to appropriate coordinates (and store them) */
gp_stroke_convertcoords(p, &pt->x, &pts->x, NULL);
- /* copy pressure */
+ /* copy pressure and time */
pts->pressure = pt->pressure;
+ pts->time = pt->time;
}
/* increment counters */
@@ -427,18 +442,11 @@ static short gp_stroke_addpoint(tGPsdata *p, const int mval[2], float pressure)
return GP_STROKEADD_INVALID;
}
-
-/* temp struct for gp_stroke_smooth() */
-typedef struct tGpSmoothCo {
- int x;
- int y;
-} tGpSmoothCo;
-
/* smooth a stroke (in buffer) before storing it */
static void gp_stroke_smooth(tGPsdata *p)
{
bGPdata *gpd = p->gpd;
- tGpSmoothCo *smoothArray, *spc;
+ tGPspoint *spt, tmp_spt[3];
int i = 0, cmx = gpd->sbuffer_size;
/* only smooth if smoothing is enabled, and we're not doing a straight line */
@@ -449,30 +457,28 @@ static void gp_stroke_smooth(tGPsdata *p)
if ((cmx <= 2) || (gpd->sbuffer == NULL))
return;
- /* create a temporary smoothing coordinates buffer, use to store calculated values to prevent sequential error */
- smoothArray = MEM_callocN(sizeof(tGpSmoothCo) * cmx, "gp_stroke_smooth smoothArray");
+ /* Calculate smoothing coordinates using weighted-averages
+ * WARNING: we do NOT smooth first and last points (to avoid shrinkage)
+ */
+ spt = (tGPspoint *)gpd->sbuffer;
- /* first pass: calculate smoothing coordinates using weighted-averages */
- for (i = 0, spc = smoothArray; i < gpd->sbuffer_size; i++, spc++) {
- const tGPspoint *pc = (((tGPspoint *)gpd->sbuffer) + i);
- const tGPspoint *pb = (i - 1 > 0) ? (pc - 1) : (pc);
- const tGPspoint *pa = (i - 2 > 0) ? (pc - 2) : (pb);
- const tGPspoint *pd = (i + 1 < cmx) ? (pc + 1) : (pc);
+ /* This (tmp_spt) small array stores the last two points' original coordinates,
+ * as we don't want to use already averaged ones! It is used as a cyclic buffer...
+ */
+ tmp_spt[0] = *spt;
+ for (i = 1, spt++; i < cmx - 1; i++, spt++) {
+ const tGPspoint *pc = spt;
+ const tGPspoint *pb = &tmp_spt[(i - 1) % 3];
+ const tGPspoint *pa = (i - 1 > 0) ? (&tmp_spt[(i - 2) % 3]) : (pb);
+ const tGPspoint *pd = pc + 1;
const tGPspoint *pe = (i + 2 < cmx) ? (pc + 2) : (pd);
- spc->x = (int)(0.1 * pa->x + 0.2 * pb->x + 0.4 * pc->x + 0.2 * pd->x + 0.1 * pe->x);
- spc->y = (int)(0.1 * pa->y + 0.2 * pb->y + 0.4 * pc->y + 0.2 * pd->y + 0.1 * pe->y);
- }
-
- /* second pass: apply smoothed coordinates */
- for (i = 0, spc = smoothArray; i < gpd->sbuffer_size; i++, spc++) {
- tGPspoint *pc = (((tGPspoint *)gpd->sbuffer) + i);
+ /* Store current point's original state for the two next points! */
+ tmp_spt[i % 3] = *spt;
- copy_v2_v2_int(&pc->x, &spc->x);
+ spt->x = (int)(0.1 * pa->x + 0.2 * pb->x + 0.4 * pc->x + 0.2 * pd->x + 0.1 * pe->x);
+ spt->y = (int)(0.1 * pa->y + 0.2 * pb->y + 0.4 * pc->y + 0.2 * pd->y + 0.1 * pe->y);
}
-
- /* free temp array */
- MEM_freeN(smoothArray);
}
/* simplify a stroke (in buffer) before storing it
@@ -494,7 +500,7 @@ static void gp_stroke_simplify(tGPsdata *p)
/* don't simplify if less than 4 points in buffer */
if ((num_points <= 4) || (old_points == NULL))
return;
-
+
/* clear buffer (but don't free mem yet) so that we can write to it
* - firstly set sbuffer to NULL, so a new one is allocated
* - secondly, reset flag after, as it gets cleared auto
@@ -511,17 +517,21 @@ static void gp_stroke_simplify(tGPsdata *p)
co[0] += (float)(old_points[offs].x * sfac); \
co[1] += (float)(old_points[offs].y * sfac); \
pressure += old_points[offs].pressure * sfac; \
+ time += old_points[offs].time * sfac; \
} (void)0
+ /* XXX Here too, do not lose start and end points! */
+ gp_stroke_addpoint(p, &old_points->x, old_points->pressure, p->inittime + (double)old_points->time);
for (i = 0, j = 0; i < num_points; i++) {
if (i - j == 3) {
- float co[2], pressure;
+ float co[2], pressure, time;
int mco[2];
/* initialize values */
- co[0] = 0;
- co[1] = 0;
- pressure = 0;
+ co[0] = 0.0f;
+ co[1] = 0.0f;
+ pressure = 0.0f;
+ time = 0.0f;
/* using macro, calculate new point */
GP_SIMPLIFY_AVPOINT(j, -0.25f);
@@ -534,11 +544,13 @@ static void gp_stroke_simplify(tGPsdata *p)
mco[1] = (int)co[1];
/* ignore return values on this... assume to be ok for now */
- gp_stroke_addpoint(p, mco, pressure);
+ gp_stroke_addpoint(p, mco, pressure, p->inittime + (double)time);
j += 2;
}
}
+ gp_stroke_addpoint(p, &old_points[num_points - 1].x, old_points[num_points - 1].pressure,
+ p->inittime + (double)old_points[num_points - 1].time);
/* free old buffer */
MEM_freeN(old_points);
@@ -573,13 +585,14 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
/* special case for poly line -- for already added stroke during session
* coordinates are getting added to stroke immediately to allow more
- * interactive behavior */
+ * interactive behavior
+ */
if (p->paintmode == GP_PAINTMODE_DRAW_POLY) {
if (gp_stroke_added_check(p)) {
return;
}
}
-
+
/* allocate memory for a new stroke */
gps = MEM_callocN(sizeof(bGPDstroke), "gp_stroke");
@@ -587,13 +600,14 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
gps->totpoints = totelem;
gps->thickness = p->gpl->thickness;
gps->flag = gpd->sbuffer_sflag;
+ gps->inittime = p->inittime;
/* allocate enough memory for a continuous array for storage points */
gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points");
-
+
/* set pointer to first non-initialized point */
pt = gps->points + (gps->totpoints - totelem);
-
+
/* copy points from the buffer to the stroke */
if (p->paintmode == GP_PAINTMODE_DRAW_STRAIGHT) {
/* straight lines only -> only endpoints */
@@ -604,8 +618,9 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
/* convert screen-coordinates to appropriate coordinates (and store them) */
gp_stroke_convertcoords(p, &ptc->x, &pt->x, NULL);
- /* copy pressure */
+ /* copy pressure and time */
pt->pressure = ptc->pressure;
+ pt->time = ptc->time;
pt++;
}
@@ -617,8 +632,9 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
/* convert screen-coordinates to appropriate coordinates (and store them) */
gp_stroke_convertcoords(p, &ptc->x, &pt->x, NULL);
- /* copy pressure */
+ /* copy pressure and time */
pt->pressure = ptc->pressure;
+ pt->time = ptc->time;
}
}
else if (p->paintmode == GP_PAINTMODE_DRAW_POLY) {
@@ -628,8 +644,9 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
/* convert screen-coordinates to appropriate coordinates (and store them) */
gp_stroke_convertcoords(p, &ptc->x, &pt->x, NULL);
- /* copy pressure */
+ /* copy pressure and time */
pt->pressure = ptc->pressure;
+ pt->time = ptc->time;
}
else {
float *depth_arr = NULL;
@@ -701,14 +718,15 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
/* convert screen-coordinates to appropriate coordinates (and store them) */
gp_stroke_convertcoords(p, &ptc->x, &pt->x, depth_arr ? depth_arr + i : NULL);
- /* copy pressure */
+ /* copy pressure and time */
pt->pressure = ptc->pressure;
+ pt->time = ptc->time;
}
if (depth_arr)
MEM_freeN(depth_arr);
}
-
+
/* add stroke to frame */
BLI_addtail(&p->gpf->strokes, gps);
gp_stroke_added_enable(p);
@@ -721,7 +739,7 @@ static short gp_stroke_eraser_splitdel(bGPDframe *gpf, bGPDstroke *gps, int i)
{
bGPDspoint *pt_tmp = gps->points;
bGPDstroke *gsn = NULL;
-
+
/* if stroke only had two points, get rid of stroke */
if (gps->totpoints == 2) {
/* free stroke points, then stroke */
@@ -731,7 +749,7 @@ static short gp_stroke_eraser_splitdel(bGPDframe *gpf, bGPDstroke *gps, int i)
/* nothing left in stroke, so stop */
return 1;
}
-
+
/* if last segment, just remove segment from the stroke */
else if (i == gps->totpoints - 2) {
/* allocate new points array, and assign most of the old stroke there */
@@ -745,7 +763,7 @@ static short gp_stroke_eraser_splitdel(bGPDframe *gpf, bGPDstroke *gps, int i)
/* nothing left in stroke, so stop */
return 1;
}
-
+
/* if first segment, just remove segment from the stroke */
else if (i == 0) {
/* allocate new points array, and assign most of the old stroke there */
@@ -753,13 +771,32 @@ static short gp_stroke_eraser_splitdel(bGPDframe *gpf, bGPDstroke *gps, int i)
gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points");
memcpy(gps->points, pt_tmp + 1, sizeof(bGPDspoint) * gps->totpoints);
+ /* We must adjust timings!
+ * Each point's timing data is a delta from stroke's inittime, so as we erase the first
+ * point of the stroke, we have to offset this inittime and all remaining points' delta values.
+ * This way we get a new stroke with exactly the same timing as if user had started drawing from
+ * the second point...
+ */
+ {
+ bGPDspoint *pts;
+ float delta = pt_tmp[1].time;
+ int j;
+
+ gps->inittime += (double)delta;
+
+ pts = gps->points;
+ for (j = 0; j < gps->totpoints; j++, pts++) {
+ pts->time -= delta;
+ }
+ }
+
/* free temp buffer */
MEM_freeN(pt_tmp);
/* no break here, as there might still be stuff to remove in this stroke */
return 0;
}
-
+
/* segment occurs in 'middle' of stroke, so split */
else {
/* duplicate stroke, and assign 'later' data to that stroke */
@@ -771,6 +808,25 @@ static short gp_stroke_eraser_splitdel(bGPDframe *gpf, bGPDstroke *gps, int i)
gsn->points = MEM_callocN(sizeof(bGPDspoint) * gsn->totpoints, "gp_stroke_points");
memcpy(gsn->points, pt_tmp + i, sizeof(bGPDspoint) * gsn->totpoints);
+ /* We must adjust timings of this new stroke!
+ * Each point's timing data is a delta from stroke's inittime, so as we erase the first
+ * point of the stroke, we have to offset this inittime and all remaing points' delta values.
+ * This way we get a new stroke with exactly the same timing as if user had started drawing from
+ * the second point...
+ */
+ {
+ bGPDspoint *pts;
+ float delta = pt_tmp[i].time;
+ int j;
+
+ gsn->inittime += (double)delta;
+
+ pts = gsn->points;
+ for (j = 0; j < gsn->totpoints; j++, pts++) {
+ pts->time -= delta;
+ }
+ }
+
/* adjust existing stroke */
gps->totpoints = i;
gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points");
@@ -792,7 +848,7 @@ static short gp_stroke_eraser_strokeinside(const int mval[], const int UNUSED(mv
const float mval_fl[2] = {mval[0], mval[1]};
const float screen_co_a[2] = {x0, y0};
const float screen_co_b[2] = {x1, y1};
-
+
if (edge_inside_circle(mval_fl, rad, screen_co_a, screen_co_b)) {
return TRUE;
}
@@ -833,7 +889,7 @@ static void gp_point_to_xy(ARegion *ar, View2D *v2d, rctf *subrect, bGPDstroke *
/* eraser tool - evaluation per stroke */
-// TODO: this could really do with some optimization (KD-Tree/BVH?)
+/* TODO: this could really do with some optimization (KD-Tree/BVH?) */
static void gp_stroke_eraser_dostroke(tGPsdata *p,
const int mval[], const int mvalo[],
short rad, const rcti *rect, bGPDframe *gpf, bGPDstroke *gps)
@@ -852,7 +908,6 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p,
gp_point_to_xy(p->ar, p->v2d, p->subrect, gps, gps->points, &x0, &y0);
/* do boundbox check first */
-
if ((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(rect, x0, y0)) {
/* only check if point is inside */
if (((x0 - mval[0]) * (x0 - mval[0]) + (y0 - mval[1]) * (y0 - mval[1])) <= rad * rad) {
@@ -870,10 +925,10 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p,
/* get points to work with */
pt1 = gps->points + i;
pt2 = gps->points + i + 1;
-
+
gp_point_to_xy(p->ar, p->v2d, p->subrect, gps, pt1, &x0, &y0);
gp_point_to_xy(p->ar, p->v2d, p->subrect, gps, pt2, &x1, &y1);
-
+
/* check that point segment of the boundbox of the eraser stroke */
if (((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(rect, x0, y0)) ||
((!ELEM(V2D_IS_CLIPPED, x1, y1)) && BLI_rcti_isect_pt(rect, x1, y1))) {
@@ -921,11 +976,11 @@ static void gp_session_validatebuffer(tGPsdata *p)
/* clear memory of buffer (or allocate it if starting a new session) */
if (gpd->sbuffer) {
- //printf("\t\tGP - reset sbuffer\n");
+ /* printf("\t\tGP - reset sbuffer\n"); */
memset(gpd->sbuffer, 0, sizeof(tGPspoint) * GP_STROKE_BUFFER_MAX);
}
else {
- //printf("\t\tGP - allocate sbuffer\n");
+ /* printf("\t\tGP - allocate sbuffer\n"); */
gpd->sbuffer = MEM_callocN(sizeof(tGPspoint) * GP_STROKE_BUFFER_MAX, "gp_session_strokebuffer");
}
@@ -934,6 +989,9 @@ static void gp_session_validatebuffer(tGPsdata *p)
/* reset flags */
gpd->sbuffer_sflag = 0;
+
+ /* reset inittime */
+ p->inittime = 0.0;
}
/* (re)init new painting data */
@@ -961,8 +1019,8 @@ static int gp_session_initdata(bContext *C, tGPsdata *p)
/* supported views first */
case SPACE_VIEW3D:
{
- // View3D *v3d = curarea->spacedata.first;
- // RegionView3D *rv3d = ar->regiondata;
+ /* View3D *v3d = curarea->spacedata.first; */
+ /* RegionView3D *rv3d = ar->regiondata; */
/* set current area
* - must verify that region data is 3D-view (and not something else)
@@ -978,10 +1036,10 @@ static int gp_session_initdata(bContext *C, tGPsdata *p)
}
}
break;
-
+
case SPACE_NODE:
{
- //SpaceNode *snode = curarea->spacedata.first;
+ /* SpaceNode *snode = curarea->spacedata.first; */
/* set current area */
p->sa = curarea;
@@ -1009,7 +1067,7 @@ static int gp_session_initdata(bContext *C, tGPsdata *p)
break;
case SPACE_IMAGE:
{
- //SpaceImage *sima = curarea->spacedata.first;
+ /* SpaceImage *sima = curarea->spacedata.first; */
/* set the current area */
p->sa = curarea;
@@ -1074,7 +1132,8 @@ static int gp_session_initdata(bContext *C, tGPsdata *p)
if (ED_gpencil_session_active() == 0) {
/* initialize undo stack,
- * also, existing undo stack would make buffer drawn */
+ * also, existing undo stack would make buffer drawn
+ */
gpencil_undo_init(p->gpd);
}
@@ -1109,7 +1168,7 @@ static void gp_session_cleanup(tGPsdata *p)
/* free stroke buffer */
if (gpd->sbuffer) {
- //printf("\t\tGP - free sbuffer\n");
+ /* printf("\t\tGP - free sbuffer\n"); */
MEM_freeN(gpd->sbuffer);
gpd->sbuffer = NULL;
}
@@ -1117,6 +1176,7 @@ static void gp_session_cleanup(tGPsdata *p)
/* clear flags */
gpd->sbuffer_size = 0;
gpd->sbuffer_sflag = 0;
+ p->inittime = 0.0;
}
/* init new stroke */
@@ -1261,7 +1321,8 @@ static void gp_paint_strokeend(tGPsdata *p)
static void gp_paint_cleanup(tGPsdata *p)
{
/* p->gpd==NULL happens when stroke failed to initialize,
- * for example. when GP is hidden in current space (sergey) */
+ * for example when GP is hidden in current space (sergey)
+ */
if (p->gpd) {
/* finish off a stroke */
gp_paint_strokeend(p);
@@ -1303,7 +1364,7 @@ static void gpencil_draw_toggle_eraser_cursor(bContext *C, tGPsdata *p, short en
else if (enable) {
/* enable cursor */
p->erasercursor = WM_paint_cursor_activate(CTX_wm_manager(C),
- NULL, // XXX
+ NULL, /* XXX */
gpencil_draw_eraser, p);
}
}
@@ -1444,16 +1505,26 @@ static void gpencil_draw_apply(wmOperator *op, tGPsdata *p)
/* only add current point to buffer if mouse moved (even though we got an event, it might be just noise) */
else if (gp_stroke_filtermval(p, p->mval, p->mvalo)) {
/* try to add point */
- short ok = gp_stroke_addpoint(p, p->mval, p->pressure);
+ short ok = gp_stroke_addpoint(p, p->mval, p->pressure, p->curtime);
/* handle errors while adding point */
if ((ok == GP_STROKEADD_FULL) || (ok == GP_STROKEADD_OVERFLOW)) {
/* finish off old stroke */
gp_paint_strokeend(p);
+ /* And start a new one!!! Else, projection errors! */
+ gp_paint_initstroke(p, p->paintmode);
/* start a new stroke, starting from previous point */
- gp_stroke_addpoint(p, p->mvalo, p->opressure);
- gp_stroke_addpoint(p, p->mval, p->pressure);
+ /* XXX Must manually reset inittime... */
+ /* XXX We only need to reuse previous point if overflow! */
+ if (ok == GP_STROKEADD_OVERFLOW) {
+ p->inittime = p->ocurtime;
+ gp_stroke_addpoint(p, p->mvalo, p->opressure, p->ocurtime);
+ }
+ else {
+ p->inittime = p->curtime;
+ }
+ gp_stroke_addpoint(p, p->mval, p->pressure, p->curtime);
}
else if (ok == GP_STROKEADD_INVALID) {
/* the painting operation cannot continue... */
@@ -1469,6 +1540,7 @@ static void gpencil_draw_apply(wmOperator *op, tGPsdata *p)
p->mvalo[0] = p->mval[0];
p->mvalo[1] = p->mval[1];
p->opressure = p->pressure;
+ p->ocurtime = p->curtime;
}
}
@@ -1479,13 +1551,14 @@ static void gpencil_draw_apply_event(wmOperator *op, wmEvent *event)
PointerRNA itemptr;
float mousef[2];
int tablet = 0;
-
+
/* convert from window-space to area-space mouse coordinates
- * NOTE: float to ints conversions, +1 factor is probably used to ensure a bit more accurate rounding...
+ * NOTE: float to ints conversions, +1 factor is probably used to ensure a bit more accurate rounding...
*/
p->mval[0] = event->mval[0] + 1;
p->mval[1] = event->mval[1] + 1;
-
+ p->curtime = PIL_check_seconds_timer();
+
/* handle pressure sensitivity (which is supplied by tablets) */
if (event->customdatatype == EVT_DATA_TABLET) {
wmTabletData *wmtab = event->customdata;
@@ -1493,8 +1566,8 @@ static void gpencil_draw_apply_event(wmOperator *op, wmEvent *event)
tablet = (wmtab->Active != EVT_TABLET_NONE);
p->pressure = wmtab->Pressure;
- //if (wmtab->Active == EVT_TABLET_ERASER)
- // TODO... this should get caught by the keymaps which call drawing in the first place
+ /* if (wmtab->Active == EVT_TABLET_ERASER) */
+ /* TODO... this should get caught by the keymaps which call drawing in the first place */
}
else
p->pressure = 1.0f;
@@ -1515,14 +1588,17 @@ static void gpencil_draw_apply_event(wmOperator *op, wmEvent *event)
p->mvalo[0] = p->mval[0];
p->mvalo[1] = p->mval[1];
p->opressure = p->pressure;
+ p->inittime = p->ocurtime = p->curtime;
/* special exception here for too high pressure values on first touch in
- * windows for some tablets, then we just skip first touch ..
+ * windows for some tablets, then we just skip first touch...
*/
if (tablet && (p->pressure >= 0.99f))
return;
}
+ RNA_float_set(&itemptr, "time", p->curtime - p->inittime);
+
/* apply the current latest drawing point */
gpencil_draw_apply(op, p);
@@ -1537,18 +1613,18 @@ static int gpencil_draw_exec(bContext *C, wmOperator *op)
{
tGPsdata *p = NULL;
- //printf("GPencil - Starting Re-Drawing\n");
+ /* printf("GPencil - Starting Re-Drawing\n"); */
/* try to initialize context data needed while drawing */
if (!gpencil_draw_init(C, op)) {
if (op->customdata) MEM_freeN(op->customdata);
- //printf("\tGP - no valid data\n");
+ /* printf("\tGP - no valid data\n"); */
return OPERATOR_CANCELLED;
}
else
p = op->customdata;
- //printf("\tGP - Start redrawing stroke\n");
+ /* printf("\tGP - Start redrawing stroke\n"); */
/* loop over the stroke RNA elements recorded (i.e. progress of mouse movement),
* setting the relevant values in context at each step, then applying
@@ -1557,20 +1633,21 @@ static int gpencil_draw_exec(bContext *C, wmOperator *op)
{
float mousef[2];
- //printf("\t\tGP - stroke elem\n");
+ /* printf("\t\tGP - stroke elem\n"); */
/* get relevant data for this point from stroke */
RNA_float_get_array(&itemptr, "mouse", mousef);
p->mval[0] = (int)mousef[0];
p->mval[1] = (int)mousef[1];
p->pressure = RNA_float_get(&itemptr, "pressure");
+ p->curtime = (double)RNA_float_get(&itemptr, "time") + p->inittime;
if (RNA_boolean_get(&itemptr, "is_start")) {
/* if first-run flag isn't set already (i.e. not true first stroke),
* then we must terminate the previous one first before continuing
*/
if ((p->flags & GP_PAINTFLAG_FIRSTRUN) == 0) {
- // TODO: both of these ops can set error-status, but we probably don't need to worry
+ /* TODO: both of these ops can set error-status, but we probably don't need to worry */
gp_paint_strokeend(p);
gp_paint_initstroke(p, p->paintmode);
}
@@ -1583,6 +1660,7 @@ static int gpencil_draw_exec(bContext *C, wmOperator *op)
p->mvalo[0] = p->mval[0];
p->mvalo[1] = p->mval[1];
p->opressure = p->pressure;
+ p->ocurtime = p->curtime;
}
/* apply this data as necessary now (as per usual) */
@@ -1590,7 +1668,7 @@ static int gpencil_draw_exec(bContext *C, wmOperator *op)
}
RNA_END;
- //printf("\tGP - done\n");
+ /* printf("\tGP - done\n"); */
/* cleanup */
gpencil_draw_exit(C, op);
@@ -1636,7 +1714,7 @@ static int gpencil_draw_invoke(bContext *C, wmOperator *op, wmEvent *event)
/* set cursor */
if (p->paintmode == GP_PAINTMODE_ERASER)
- WM_cursor_modal(win, BC_CROSSCURSOR); // XXX need a better cursor
+ WM_cursor_modal(win, BC_CROSSCURSOR); /* XXX need a better cursor */
else
WM_cursor_modal(win, BC_PAINTBRUSHCURSOR);
@@ -1646,7 +1724,7 @@ static int gpencil_draw_invoke(bContext *C, wmOperator *op, wmEvent *event)
*/
if (event->val == KM_PRESS) {
/* hotkey invoked - start drawing */
- //printf("\tGP - set first spot\n");
+ /* printf("\tGP - set first spot\n"); */
p->status = GP_STATUS_PAINTING;
/* handle the initial drawing - i.e. for just doing a simple dot */
@@ -1654,7 +1732,7 @@ static int gpencil_draw_invoke(bContext *C, wmOperator *op, wmEvent *event)
}
else {
/* toolbar invoked - don't start drawing yet... */
- //printf("\tGP - hotkey invoked... waiting for click-drag\n");
+ /* printf("\tGP - hotkey invoked... waiting for click-drag\n"); */
}
WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL);
@@ -1673,7 +1751,7 @@ static int gpencil_area_exists(bContext *C, ScrArea *sa_test)
static tGPsdata *gpencil_stroke_begin(bContext *C, wmOperator *op)
{
tGPsdata *p = op->customdata;
-
+
/* we must check that we're still within the area that we're set up to work from
* otherwise we could crash (see bug #20586)
*/
@@ -1681,20 +1759,20 @@ static tGPsdata *gpencil_stroke_begin(bContext *C, wmOperator *op)
printf("\t\t\tGP - wrong area execution abort!\n");
p->status = GP_STATUS_ERROR;
}
-
- //printf("\t\tGP - start stroke\n");
-
+
+ /* printf("\t\tGP - start stroke\n"); */
+
/* we may need to set up paint env again if we're resuming */
/* XXX: watch it with the paintmode! in future,
* it'd be nice to allow changing paint-mode when in sketching-sessions */
/* XXX: with tablet events, we may event want to check for eraser here, for nicer tablet support */
-
+
if (gp_session_initdata(C, p))
gp_paint_initstroke(p, p->paintmode);
-
+
if (p->status != GP_STATUS_ERROR)
p->status = GP_STATUS_PAINTING;
-
+
return op->customdata;
}
@@ -1719,7 +1797,7 @@ static void gpencil_stroke_end(wmOperator *op)
static int gpencil_draw_modal(bContext *C, wmOperator *op, wmEvent *event)
{
tGPsdata *p = op->customdata;
- int estate = OPERATOR_RUNNING_MODAL; /* default exit state - we don't pass on events, GP is used with key-modifiers */
+ int estate = OPERATOR_PASS_THROUGH; /* default exit state - pass through to support MMB view nav, etc. */
/* if (event->type == NDOF_MOTION)
* return OPERATOR_PASS_THROUGH;
@@ -1731,8 +1809,13 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, wmEvent *event)
* the stroke is converted to 3D only after
* it is finished. This approach should work
* better in tools that immediately apply
- * in 3D space. */
-
+ * in 3D space.
+ */
+
+ /* we don't pass on key events, GP is used with key-modifiers - prevents Dkey to insert drivers */
+ if (ISKEYBOARD(event->type))
+ estate = OPERATOR_RUNNING_MODAL;
+
//printf("\tGP - handle modal event...\n");
/* exit painting mode (and/or end current stroke)
@@ -1740,7 +1823,7 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, wmEvent *event)
*/
if (ELEM4(event->type, RETKEY, PADENTER, ESCKEY, SPACEKEY)) {
/* exit() ends the current stroke before cleaning up */
- //printf("\t\tGP - end of paint op + end of stroke\n");
+ /* printf("\t\tGP - end of paint op + end of stroke\n"); */
p->status = GP_STATUS_DONE;
estate = OPERATOR_FINISHED;
}
@@ -1764,7 +1847,7 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, wmEvent *event)
if (sketch) {
/* end stroke only, and then wait to resume painting soon */
- //printf("\t\tGP - end stroke only\n");
+ /* printf("\t\tGP - end stroke only\n"); */
gpencil_stroke_end(op);
/* we've just entered idling state, so this event was processed (but no others yet) */
@@ -1774,7 +1857,7 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, wmEvent *event)
WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL);
}
else {
- //printf("\t\tGP - end of stroke + op\n");
+ /* printf("\t\tGP - end of stroke + op\n"); */
p->status = GP_STATUS_DONE;
estate = OPERATOR_FINISHED;
}
@@ -1797,7 +1880,7 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, wmEvent *event)
/* handle painting mouse-movements? */
if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE) || (p->flags & GP_PAINTFLAG_FIRSTRUN)) {
/* handle drawing event */
- //printf("\t\tGP - add point\n");
+ /* printf("\t\tGP - add point\n"); */
gpencil_draw_apply_event(op, event);
/* finish painting operation if anything went wrong just now */
@@ -1807,7 +1890,7 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, wmEvent *event)
}
else {
/* event handled, so just tag as running modal */
- //printf("\t\t\t\tGP - add point handled!\n");
+ /* printf("\t\t\t\tGP - add point handled!\n"); */
estate = OPERATOR_RUNNING_MODAL;
}
}
@@ -1818,7 +1901,7 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, wmEvent *event)
/* just resize the brush (local version)
* TODO: fix the hardcoded size jumps (set to make a visible difference) and hardcoded keys
*/
- //printf("\t\tGP - resize eraser\n");
+ /* printf("\t\tGP - resize eraser\n"); */
switch (event->type) {
case WHEELUPMOUSE: /* larger */
case PADPLUSKEY:
diff --git a/source/blender/editors/include/ED_gpencil.h b/source/blender/editors/include/ED_gpencil.h
index 1d461f797d6..39dd8822267 100644
--- a/source/blender/editors/include/ED_gpencil.h
+++ b/source/blender/editors/include/ED_gpencil.h
@@ -56,6 +56,7 @@ struct wmKeyConfig;
typedef struct tGPspoint {
int x, y; /* x and y coordinates of cursor (in relative to area) */
float pressure; /* pressure of tablet at this point */
+ float time; /* Time relative to stroke start (used when converting to path) */
} tGPspoint;
diff --git a/source/blender/editors/include/ED_image.h b/source/blender/editors/include/ED_image.h
index a50b33966c6..9b726cea56c 100644
--- a/source/blender/editors/include/ED_image.h
+++ b/source/blender/editors/include/ED_image.h
@@ -49,7 +49,7 @@ void ED_space_image_set_mask(struct bContext *C, struct SpaceImage *sim
int ED_space_image_color_sample(struct SpaceImage *sima, struct ARegion *ar, int mval[2], float r_col[3]);
struct ImBuf *ED_space_image_acquire_buffer(struct SpaceImage *sima, void **lock_r);
-void ED_space_image_release_buffer(struct SpaceImage *sima, void *lock);
+void ED_space_image_release_buffer(struct SpaceImage *sima, struct ImBuf *ibuf, void *lock);
int ED_space_image_has_buffer(struct SpaceImage *sima);
void ED_space_image_get_size(struct SpaceImage *sima, int *width, int *height);
diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h
index 05e4d8c4a2f..b9811bf0a93 100644
--- a/source/blender/editors/include/ED_mesh.h
+++ b/source/blender/editors/include/ED_mesh.h
@@ -153,7 +153,12 @@ int EDBM_select_pick(struct bContext *C, const int mval[2], short extend, short
void EDBM_selectmode_set(struct BMEditMesh *em);
void EDBM_selectmode_convert(struct BMEditMesh *em, short selectmode_old, short selectmode_new);
-void EDBM_deselect_by_material(struct BMEditMesh *em, short index, short select);
+/* user access this */
+int EDBM_selectmode_toggle(struct bContext *C, const short selectmode_new,
+ const int action, const int use_extend, const int use_expand);
+
+
+void EDBM_deselect_by_material(struct BMEditMesh *em, const short index, const short select);
void EDBM_select_toggle_all(struct BMEditMesh *em);
diff --git a/source/blender/editors/include/UI_icons.h b/source/blender/editors/include/UI_icons.h
index e400e44e944..10c585aa802 100644
--- a/source/blender/editors/include/UI_icons.h
+++ b/source/blender/editors/include/UI_icons.h
@@ -593,6 +593,7 @@ DEF_ICON(MOD_REMESH)
DEF_ICON(MOD_OCEAN)
DEF_ICON(MOD_WARP)
DEF_ICON(MOD_SKIN)
+DEF_ICON(MOD_TRIANGULATE)
#ifndef DEF_ICON_BLANK_SKIP
DEF_ICON(BLANK166)
DEF_ICON(BLANK167)
@@ -606,7 +607,6 @@ DEF_ICON(MOD_SKIN)
DEF_ICON(BLANK175)
DEF_ICON(BLANK176)
DEF_ICON(BLANK177)
- DEF_ICON(BLANK177b)
#endif
/* ANIMATION */
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index 560a5a716c3..264aa895fc5 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -1675,7 +1675,7 @@ void ui_get_but_string(uiBut *but, char *str, size_t maxlen)
{
if (but->rnaprop && ELEM3(but->type, TEX, IDPOIN, SEARCH_MENU)) {
PropertyType type;
- char *buf = NULL;
+ const char *buf = NULL;
int buf_len;
type = RNA_property_type(but->rnaprop);
@@ -1684,11 +1684,22 @@ void ui_get_but_string(uiBut *but, char *str, size_t maxlen)
/* RNA string */
buf = RNA_property_string_get_alloc(&but->rnapoin, but->rnaprop, str, maxlen, &buf_len);
}
+ else if (type == PROP_ENUM) {
+ /* RNA enum */
+ int value = RNA_property_enum_get(&but->rnapoin, but->rnaprop);
+ if (RNA_property_enum_name(but->block->evil_C, &but->rnapoin, but->rnaprop, value, &buf)) {
+ BLI_strncpy(str, buf, maxlen);
+ buf = str;
+ }
+ }
else if (type == PROP_POINTER) {
/* RNA pointer */
PointerRNA ptr = RNA_property_pointer_get(&but->rnapoin, but->rnaprop);
buf = RNA_struct_name_get_alloc(&ptr, str, maxlen, &buf_len);
}
+ else {
+ BLI_assert(0);
+ }
if (!buf) {
str[0] = '\0';
@@ -1696,7 +1707,7 @@ void ui_get_but_string(uiBut *but, char *str, size_t maxlen)
else if (buf && buf != str) {
/* string was too long, we have to truncate */
memcpy(str, buf, MIN2(maxlen, (size_t)buf_len + 1));
- MEM_freeN(buf);
+ MEM_freeN((void *)buf);
}
}
else if (but->type == IDPOIN) {
@@ -1839,6 +1850,17 @@ int ui_set_but_string(bContext *C, uiBut *but, const char *str)
return 0;
}
+ else if (type == PROP_ENUM) {
+ int value;
+ if (RNA_property_enum_value(but->block->evil_C, &but->rnapoin, but->rnaprop, str, &value)) {
+ RNA_property_enum_set(&but->rnapoin, but->rnaprop, value);
+ return 1;
+ }
+ return 0;
+ }
+ else {
+ BLI_assert(0);
+ }
}
}
else if (but->type == IDPOIN) {
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 540a9cc752b..23d3810e058 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -358,7 +358,7 @@ struct uiBlock {
char color_profile; /* color profile for correcting linear colors for display */
- char *display_device; /* display devide name used to display this block,
+ char *display_device; /* display device name used to display this block,
* used by color widgets to transform colors from/to scene linear
*/
};
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index 52d909a34c0..9759c22f30e 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -68,6 +68,8 @@
#define EM_SEPR_X 6
#define EM_SEPR_Y 6
+// #define USE_OP_RESET_BUT // we may want to make this optional, disable for now.
+
#define UI_OPERATOR_ERROR_RET(_ot, _opname, return_statement) \
if (ot == NULL) { \
ui_item_disabled(layout, _opname); \
@@ -428,7 +430,7 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, const char *name, in
but->type = NUMSLI;
}
}
- else if (subtype == PROP_DIRECTION) {
+ else if (subtype == PROP_DIRECTION && !expand) {
uiDefButR_prop(block, BUT_NORMAL, 0, name, x, y, UI_UNIT_X * 3, UI_UNIT_Y * 3, ptr, prop, 0, 0, 0, -1, -1, NULL);
}
else {
@@ -1382,6 +1384,12 @@ void ui_but_add_search(uiBut *but, PointerRNA *ptr, PropertyRNA *prop, PointerRN
but->rnasearchprop = searchprop;
but->flag |= UI_ICON_LEFT | UI_TEXT_LEFT;
+ if (RNA_property_type(prop) == PROP_ENUM) {
+ /* XXX, this will have a menu string,
+ * but in this case we just want the text */
+ but->str[0] = 0;
+ }
+
uiButSetSearchFunc(but, rna_search_cb, but, NULL, NULL);
}
}
@@ -1399,13 +1407,14 @@ void uiItemPointerR(uiLayout *layout, struct PointerRNA *ptr, const char *propna
prop = RNA_struct_find_property(ptr, propname);
if (!prop) {
- RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
+ RNA_warning("property not found: %s.%s",
+ RNA_struct_identifier(ptr->type), propname);
return;
}
type = RNA_property_type(prop);
- if (!ELEM(type, PROP_POINTER, PROP_STRING)) {
- RNA_warning("Property %s must be a pointer or string", propname);
+ if (!ELEM3(type, PROP_POINTER, PROP_STRING, PROP_ENUM)) {
+ RNA_warning("Property %s must be a pointer, string or enum", propname);
return;
}
@@ -1413,11 +1422,13 @@ void uiItemPointerR(uiLayout *layout, struct PointerRNA *ptr, const char *propna
if (!searchprop) {
- RNA_warning("search collection property not found: %s.%s", RNA_struct_identifier(ptr->type), searchpropname);
+ RNA_warning("search collection property not found: %s.%s",
+ RNA_struct_identifier(searchptr->type), searchpropname);
return;
}
else if (RNA_property_type(searchprop) != PROP_COLLECTION) {
- RNA_warning("search collection property is not a collection type: %s.%s", RNA_struct_identifier(ptr->type), searchpropname);
+ RNA_warning("search collection property is not a collection type: %s.%s",
+ RNA_struct_identifier(searchptr->type), searchpropname);
return;
}
@@ -2840,10 +2851,12 @@ const char *uiLayoutIntrospect(uiLayout *layout)
return str;
}
+#ifdef USE_OP_RESET_BUT
static void ui_layout_operator_buts__reset_cb(bContext *UNUSED(C), void *op_pt, void *UNUSED(arg_dummy2))
{
WM_operator_properties_reset((wmOperator *)op_pt);
}
+#endif
/* this function does not initialize the layout, functions can be called on the layout before and after */
void uiLayoutOperatorButs(const bContext *C, uiLayout *layout, wmOperator *op,
@@ -2911,6 +2924,7 @@ void uiLayoutOperatorButs(const bContext *C, uiLayout *layout, wmOperator *op,
}
}
+#ifdef USE_OP_RESET_BUT
/* its possible that reset can do nothing if all have PROP_SKIP_SAVE enabled
* but this is not so important if this button is drawn in those cases
* (which isn't all that likely anyway) - campbell */
@@ -2925,6 +2939,7 @@ void uiLayoutOperatorButs(const bContext *C, uiLayout *layout, wmOperator *op,
NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Reset operator defaults"));
uiButSetFunc(but, ui_layout_operator_buts__reset_cb, op, NULL);
}
+#endif
/* set various special settings for buttons */
{
diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c
index 9e7e50d69ac..4712e03d454 100644
--- a/source/blender/editors/interface/interface_regions.c
+++ b/source/blender/editors/interface/interface_regions.c
@@ -1413,8 +1413,8 @@ static void ui_block_position(wmWindow *window, ARegion *butregion, uiBut *but,
dir1 &= (UI_TOP | UI_DOWN);
}
- if (dir2 == 0) if (dir1 == UI_LEFT || dir1 == UI_RIGHT) dir2 = UI_DOWN;
- if (dir2 == 0) if (dir1 == UI_TOP || dir1 == UI_DOWN) dir2 = UI_LEFT;
+ if ((dir2 == 0) && (dir1 == UI_LEFT || dir1 == UI_RIGHT)) dir2 = UI_DOWN;
+ if ((dir2 == 0) && (dir1 == UI_TOP || dir1 == UI_DOWN)) dir2 = UI_LEFT;
/* no space at all? don't change */
if (left || right) {
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index 84ae3a8f57d..f872afed486 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -185,7 +185,8 @@ static uiBlock *id_search_menu(bContext *C, ARegion *ar, void *arg_litem)
/* fake button, it holds space for search items */
uiDefBut(block, LABEL, 0, "", 10, 15, w, h, NULL, 0, 0, 0, 0, NULL);
- but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 0, w, 19, template.prv_rows, template.prv_cols, "");
+ but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 0, w, 19,
+ template.prv_rows, template.prv_cols, "");
uiButSetSearchFunc(but, id_search_cb, &template, id_search_call_cb, idptr.data);
}
/* list view */
@@ -315,33 +316,68 @@ static const char *template_id_browse_tip(StructRNA *type)
if (type) {
switch (RNA_type_to_ID_code(type)) {
case ID_SCE: return N_("Browse Scene to be linked");
- case ID_OB: return N_("Browse Object to be linked");
- case ID_ME: return N_("Browse Mesh Data to be linked");
- case ID_CU: return N_("Browse Curve Data to be linked");
- case ID_MB: return N_("Browse Metaball Data to be linked");
- case ID_MA: return N_("Browse Material to be linked");
- case ID_TE: return N_("Browse Texture to be linked");
- case ID_IM: return N_("Browse Image to be linked");
- case ID_LT: return N_("Browse Lattice Data to be linked");
- case ID_LA: return N_("Browse Lamp Data to be linked");
- case ID_CA: return N_("Browse Camera Data to be linked");
- case ID_WO: return N_("Browse World Settings to be linked");
+ case ID_OB: return N_("Browse Object to be linked");
+ case ID_ME: return N_("Browse Mesh Data to be linked");
+ case ID_CU: return N_("Browse Curve Data to be linked");
+ case ID_MB: return N_("Browse Metaball Data to be linked");
+ case ID_MA: return N_("Browse Material to be linked");
+ case ID_TE: return N_("Browse Texture to be linked");
+ case ID_IM: return N_("Browse Image to be linked");
+ case ID_LT: return N_("Browse Lattice Data to be linked");
+ case ID_LA: return N_("Browse Lamp Data to be linked");
+ case ID_CA: return N_("Browse Camera Data to be linked");
+ case ID_WO: return N_("Browse World Settings to be linked");
case ID_SCR: return N_("Choose Screen lay-out");
case ID_TXT: return N_("Browse Text to be linked");
case ID_SPK: return N_("Browse Speaker Data to be linked");
- case ID_SO: return N_("Browse Sound to be linked");
- case ID_AR: return N_("Browse Armature data to be linked");
- case ID_AC: return N_("Browse Action to be linked");
- case ID_NT: return N_("Browse Node Tree to be linked");
- case ID_BR: return N_("Browse Brush to be linked");
- case ID_PA: return N_("Browse Particle System to be linked");
- case ID_GD: return N_("Browse Grease Pencil Data to be linked");
+ case ID_SO: return N_("Browse Sound to be linked");
+ case ID_AR: return N_("Browse Armature data to be linked");
+ case ID_AC: return N_("Browse Action to be linked");
+ case ID_NT: return N_("Browse Node Tree to be linked");
+ case ID_BR: return N_("Browse Brush to be linked");
+ case ID_PA: return N_("Browse Particle System to be linked");
+ case ID_GD: return N_("Browse Grease Pencil Data to be linked");
}
}
return N_("Browse ID data to be linked");
}
-static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, StructRNA *type, short idcode, int flag, const char *newop, const char *openop, const char *unlinkop)
+/* Return a type-based i18n context, needed e.g. by "New" button.
+ * In most languages, this adjective takes different form based on gender of type name...
+ */
+static const char *template_id_context(StructRNA *type)
+{
+ if (type) {
+ switch (RNA_type_to_ID_code(type)) {
+ case ID_SCE: return BLF_I18NCONTEXT_ID_SCENE;
+ case ID_OB: return BLF_I18NCONTEXT_ID_OBJECT;
+ case ID_ME: return BLF_I18NCONTEXT_ID_MESH;
+ case ID_CU: return BLF_I18NCONTEXT_ID_CURVE;
+ case ID_MB: return BLF_I18NCONTEXT_ID_METABALL;
+ case ID_MA: return BLF_I18NCONTEXT_ID_MATERIAL;
+ case ID_TE: return BLF_I18NCONTEXT_ID_TEXTURE;
+ case ID_IM: return BLF_I18NCONTEXT_ID_IMAGE;
+ case ID_LT: return BLF_I18NCONTEXT_ID_LATTICE;
+ case ID_LA: return BLF_I18NCONTEXT_ID_LAMP;
+ case ID_CA: return BLF_I18NCONTEXT_ID_CAMERA;
+ case ID_WO: return BLF_I18NCONTEXT_ID_WORLD;
+ case ID_SCR: return BLF_I18NCONTEXT_ID_SCREEN;
+ case ID_TXT: return BLF_I18NCONTEXT_ID_TEXT;
+ case ID_SPK: return BLF_I18NCONTEXT_ID_SPEAKER;
+ case ID_SO: return BLF_I18NCONTEXT_ID_SOUND;
+ case ID_AR: return BLF_I18NCONTEXT_ID_ARMATURE;
+ case ID_AC: return BLF_I18NCONTEXT_ID_ACTION;
+ case ID_NT: return BLF_I18NCONTEXT_ID_NODETREE;
+ case ID_BR: return BLF_I18NCONTEXT_ID_BRUSH;
+ case ID_PA: return BLF_I18NCONTEXT_ID_PARTICLESETTINGS;
+ case ID_GD: return BLF_I18NCONTEXT_ID_GPENCIL;
+ }
+ }
+ return BLF_I18NCONTEXT_DEFAULT;
+}
+
+static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, StructRNA *type, short idcode, int flag,
+ const char *newop, const char *openop, const char *unlinkop)
{
uiBut *but;
uiBlock *block;
@@ -349,6 +385,7 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str
// ListBase *lb; // UNUSED
ID *id, *idfrom;
int editable = RNA_property_editable(&template->ptr, template->prop);
+ const char *i18n_ctxt = template_id_context(type);
idptr = RNA_property_pointer_get(&template->ptr, template->prop);
id = idptr.data;
@@ -400,19 +437,20 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str
//text_idbutton(id, name);
name[0] = '\0';
- but = uiDefButR(block, TEX, 0, name, 0, 0, UI_UNIT_X * 6, UI_UNIT_Y, &idptr, "name", -1, 0, 0, -1, -1, RNA_struct_ui_description(type));
+ but = uiDefButR(block, TEX, 0, name, 0, 0, UI_UNIT_X * 6, UI_UNIT_Y,
+ &idptr, "name", -1, 0, 0, -1, -1, RNA_struct_ui_description(type));
uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_RENAME));
if (user_alert) uiButSetFlag(but, UI_BUT_REDALERT);
if (id->lib) {
if (id->flag & LIB_INDIRECT) {
- but = uiDefIconBut(block, BUT, 0, ICON_LIBRARY_DATA_INDIRECT, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0,
- TIP_("Indirect library datablock, cannot change"));
+ but = uiDefIconBut(block, BUT, 0, ICON_LIBRARY_DATA_INDIRECT, 0, 0, UI_UNIT_X, UI_UNIT_Y,
+ NULL, 0, 0, 0, 0, TIP_("Indirect library datablock, cannot change"));
uiButSetFlag(but, UI_BUT_DISABLED);
}
else {
- but = uiDefIconBut(block, BUT, 0, ICON_LIBRARY_DATA_DIRECT, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0,
- TIP_("Direct linked library datablock, click to make local"));
+ but = uiDefIconBut(block, BUT, 0, ICON_LIBRARY_DATA_DIRECT, 0, 0, UI_UNIT_X, UI_UNIT_Y,
+ NULL, 0, 0, 0, 0, TIP_("Direct linked library datablock, click to make local"));
if (!id_make_local(id, 1 /* test */) || (idfrom && idfrom->lib))
uiButSetFlag(but, UI_BUT_DISABLED);
}
@@ -425,7 +463,8 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str
BLI_snprintf(numstr, sizeof(numstr), "%d", id->us);
- but = uiDefBut(block, BUT, 0, numstr, 0, 0, UI_UNIT_X + ((id->us < 10) ? 0 : 10), UI_UNIT_Y, NULL, 0, 0, 0, 0,
+ but = uiDefBut(block, BUT, 0, numstr, 0, 0, UI_UNIT_X + ((id->us < 10) ? 0 : 10), UI_UNIT_Y,
+ NULL, 0, 0, 0, 0,
TIP_("Display number of users of this data (click to make a single-user copy)"));
uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_ALONE));
@@ -450,12 +489,39 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str
if (flag & UI_ID_ADD_NEW) {
int w = id ? UI_UNIT_X : (flag & UI_ID_OPEN) ? UI_UNIT_X * 3 : UI_UNIT_X * 6;
+ /* i18n markup, does nothing! */
+ BLF_I18N_MSGID_MULTI_CTXT("New", BLF_I18NCONTEXT_DEFAULT,
+ BLF_I18NCONTEXT_ID_SCENE,
+ BLF_I18NCONTEXT_ID_OBJECT,
+ BLF_I18NCONTEXT_ID_MESH,
+ BLF_I18NCONTEXT_ID_CURVE,
+ BLF_I18NCONTEXT_ID_METABALL,
+ BLF_I18NCONTEXT_ID_MATERIAL,
+ BLF_I18NCONTEXT_ID_TEXTURE,
+ BLF_I18NCONTEXT_ID_IMAGE,
+ BLF_I18NCONTEXT_ID_LATTICE,
+ BLF_I18NCONTEXT_ID_LAMP,
+ BLF_I18NCONTEXT_ID_CAMERA,
+ BLF_I18NCONTEXT_ID_WORLD,
+ BLF_I18NCONTEXT_ID_SCREEN,
+ BLF_I18NCONTEXT_ID_TEXT);
+ BLF_I18N_MSGID_MULTI_CTXT("New", BLF_I18NCONTEXT_ID_SPEAKER,
+ BLF_I18NCONTEXT_ID_SOUND,
+ BLF_I18NCONTEXT_ID_ARMATURE,
+ BLF_I18NCONTEXT_ID_ACTION,
+ BLF_I18NCONTEXT_ID_NODETREE,
+ BLF_I18NCONTEXT_ID_BRUSH,
+ BLF_I18NCONTEXT_ID_PARTICLESETTINGS,
+ BLF_I18NCONTEXT_ID_GPENCIL);
+
if (newop) {
- but = uiDefIconTextButO(block, BUT, newop, WM_OP_INVOKE_DEFAULT, ICON_ZOOMIN, (id) ? "" : IFACE_("New"), 0, 0, w, UI_UNIT_Y, NULL);
+ but = uiDefIconTextButO(block, BUT, newop, WM_OP_INVOKE_DEFAULT, ICON_ZOOMIN,
+ (id) ? "" : CTX_IFACE_(i18n_ctxt, "New"), 0, 0, w, UI_UNIT_Y, NULL);
uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_ADD_NEW));
}
else {
- but = uiDefIconTextBut(block, BUT, 0, ICON_ZOOMIN, (id) ? "" : IFACE_("New"), 0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
+ but = uiDefIconTextBut(block, BUT, 0, ICON_ZOOMIN, (id) ? "" : CTX_IFACE_(i18n_ctxt, "New"),
+ 0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_ADD_NEW));
}
@@ -467,11 +533,13 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str
int w = id ? UI_UNIT_X : (flag & UI_ID_ADD_NEW) ? UI_UNIT_X * 3 : UI_UNIT_X * 6;
if (openop) {
- but = uiDefIconTextButO(block, BUT, openop, WM_OP_INVOKE_DEFAULT, ICON_FILESEL, (id) ? "" : IFACE_("Open"), 0, 0, w, UI_UNIT_Y, NULL);
+ but = uiDefIconTextButO(block, BUT, openop, WM_OP_INVOKE_DEFAULT, ICON_FILESEL, (id) ? "" : IFACE_("Open"),
+ 0, 0, w, UI_UNIT_Y, NULL);
uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_OPEN));
}
else {
- but = uiDefIconTextBut(block, BUT, 0, ICON_FILESEL, (id) ? "" : IFACE_("Open"), 0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
+ but = uiDefIconTextBut(block, BUT, 0, ICON_FILESEL, (id) ? "" : IFACE_("Open"), 0, 0, w, UI_UNIT_Y,
+ NULL, 0, 0, 0, 0, NULL);
uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_OPEN));
}
@@ -488,7 +556,8 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str
}
else {
but = uiDefIconBut(block, BUT, 0, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0,
- TIP_("Unlink datablock. Shift + Click to set users to zero, data will then not be saved"));
+ TIP_("Unlink datablock "
+ "(Shift + Click to set users to zero, data will then not be saved)"));
uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_DELETE));
if (RNA_property_flag(template->prop) & PROP_NEVER_NULL)
@@ -505,7 +574,8 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str
uiBlockEndAlign(block);
}
-static void ui_template_id(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, const char *newop, const char *openop, const char *unlinkop, int flag, int prv_rows, int prv_cols)
+static void ui_template_id(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, const char *newop,
+ const char *openop, const char *unlinkop, int flag, int prv_rows, int prv_cols)
{
TemplateID *template;
PropertyRNA *prop;
@@ -545,19 +615,24 @@ static void ui_template_id(uiLayout *layout, bContext *C, PointerRNA *ptr, const
MEM_freeN(template);
}
-void uiTemplateID(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, const char *newop, const char *openop, const char *unlinkop)
+void uiTemplateID(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, const char *newop,
+ const char *openop, const char *unlinkop)
{
- ui_template_id(layout, C, ptr, propname, newop, openop, unlinkop, UI_ID_BROWSE | UI_ID_RENAME | UI_ID_DELETE, 0, 0);
+ ui_template_id(layout, C, ptr, propname, newop, openop, unlinkop,
+ UI_ID_BROWSE | UI_ID_RENAME | UI_ID_DELETE, 0, 0);
}
-void uiTemplateIDBrowse(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, const char *newop, const char *openop, const char *unlinkop)
+void uiTemplateIDBrowse(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, const char *newop,
+ const char *openop, const char *unlinkop)
{
ui_template_id(layout, C, ptr, propname, newop, openop, unlinkop, UI_ID_BROWSE | UI_ID_RENAME, 0, 0);
}
-void uiTemplateIDPreview(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, const char *newop, const char *openop, const char *unlinkop, int rows, int cols)
+void uiTemplateIDPreview(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, const char *newop,
+ const char *openop, const char *unlinkop, int rows, int cols)
{
- ui_template_id(layout, C, ptr, propname, newop, openop, unlinkop, UI_ID_BROWSE | UI_ID_RENAME | UI_ID_DELETE | UI_ID_PREVIEWS, rows, cols);
+ ui_template_id(layout, C, ptr, propname, newop, openop, unlinkop,
+ UI_ID_BROWSE | UI_ID_RENAME | UI_ID_DELETE | UI_ID_PREVIEWS, rows, cols);
}
/************************ ID Chooser Template ***************************/
@@ -567,7 +642,8 @@ void uiTemplateIDPreview(uiLayout *layout, bContext *C, PointerRNA *ptr, const c
* - propname: property identifier for property that ID-pointer gets stored to
* - proptypename: property identifier for property used to determine the type of ID-pointer that can be used
*/
-void uiTemplateAnyID(uiLayout *layout, PointerRNA *ptr, const char *propname, const char *proptypename, const char *text)
+void uiTemplateAnyID(uiLayout *layout, PointerRNA *ptr, const char *propname, const char *proptypename,
+ const char *text)
{
PropertyRNA *propID, *propType;
uiLayout *row;
@@ -614,7 +690,8 @@ void uiTemplateAnyID(uiLayout *layout, PointerRNA *ptr, const char *propname, co
* - propname: property identifier for property that path gets stored to
* - root_ptr: struct that path gets built from
*/
-void uiTemplatePathBuilder(uiLayout *layout, PointerRNA *ptr, const char *propname, PointerRNA *UNUSED(root_ptr), const char *text)
+void uiTemplatePathBuilder(uiLayout *layout, PointerRNA *ptr, const char *propname, PointerRNA *UNUSED(root_ptr),
+ const char *text)
{
PropertyRNA *propPath;
uiLayout *row;
@@ -779,7 +856,7 @@ static uiLayout *draw_modifier(uiLayout *layout, Scene *scene, Object *ob,
uiBlockBeginAlign(block);
/* Softbody not allowed in this situation, enforce! */
if (((md->type != eModifierType_Softbody && md->type != eModifierType_Collision) || !(ob->pd && ob->pd->deflect)) &&
- (md->type != eModifierType_Surface) )
+ (md->type != eModifierType_Surface) )
{
uiItemR(row, &ptr, "show_render", 0, "", ICON_NONE);
uiItemR(row, &ptr, "show_viewport", 0, "", ICON_NONE);
@@ -791,7 +868,8 @@ static uiLayout *draw_modifier(uiLayout *layout, Scene *scene, Object *ob,
if (ob->type == OB_MESH) {
if (modifier_couldBeCage(scene, md) && (index <= lastCageIndex)) {
/* -- convert to rna ? */
- but = uiDefIconButBitI(block, TOG, eModifierMode_OnCage, 0, ICON_MESH_DATA, 0, 0, UI_UNIT_X - 2, UI_UNIT_Y, &md->mode, 0.0, 0.0, 0.0, 0.0,
+ but = uiDefIconButBitI(block, TOG, eModifierMode_OnCage, 0, ICON_MESH_DATA, 0, 0,
+ UI_UNIT_X - 2, UI_UNIT_Y, &md->mode, 0.0, 0.0, 0.0, 0.0,
TIP_("Apply modifier to editing cage during Edit mode"));
if (index < cageIndex)
uiButSetFlag(but, UI_BUT_DISABLED);
@@ -802,7 +880,8 @@ static uiLayout *draw_modifier(uiLayout *layout, Scene *scene, Object *ob,
/* place holder button */
uiBlockSetEmboss(block, UI_EMBOSSN);
- but = uiDefIconBut(block, BUT, 0, ICON_NONE, 0, 0, UI_UNIT_X - 2, UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, NULL);
+ but = uiDefIconBut(block, BUT, 0, ICON_NONE, 0, 0, UI_UNIT_X - 2, UI_UNIT_Y,
+ NULL, 0.0, 0.0, 0.0, 0.0, NULL);
uiButSetFlag(but, UI_BUT_DISABLED);
uiBlockSetEmboss(block, UI_EMBOSS);
}
@@ -812,7 +891,8 @@ static uiLayout *draw_modifier(uiLayout *layout, Scene *scene, Object *ob,
if (ELEM3(md->type, eModifierType_Hook, eModifierType_Softbody, eModifierType_MeshDeform)) {
/* add disabled pre-tessellated button, so users could have
* message for this modifiers */
- but = uiDefIconButBitI(block, TOG, eModifierMode_ApplyOnSpline, 0, ICON_SURFACE_DATA, 0, 0, UI_UNIT_X - 2, UI_UNIT_Y, &md->mode, 0.0, 0.0, 0.0, 0.0,
+ but = uiDefIconButBitI(block, TOG, eModifierMode_ApplyOnSpline, 0, ICON_SURFACE_DATA, 0, 0,
+ UI_UNIT_X - 2, UI_UNIT_Y, &md->mode, 0.0, 0.0, 0.0, 0.0,
TIP_("This modifier could be applied on splines' points only"));
uiButSetFlag(but, UI_BUT_DISABLED);
}
@@ -866,15 +946,20 @@ static uiLayout *draw_modifier(uiLayout *layout, Scene *scene, Object *ob,
uiLayoutSetOperatorContext(row, WM_OP_INVOKE_DEFAULT);
uiItemEnumO(row, "OBJECT_OT_modifier_apply", IFACE_("Apply"), 0, "apply_as", MODIFIER_APPLY_DATA);
- if (modifier_sameTopology(md) && !modifier_nonGeometrical(md))
- uiItemEnumO(row, "OBJECT_OT_modifier_apply", IFACE_("Apply as Shape Key"), 0, "apply_as", MODIFIER_APPLY_SHAPE);
+ if (modifier_isSameTopology(md) && !modifier_isNonGeometrical(md)) {
+ uiItemEnumO(row, "OBJECT_OT_modifier_apply", IFACE_("Apply as Shape Key"), 0,
+ "apply_as", MODIFIER_APPLY_SHAPE);
+ }
}
uiBlockClearButLock(block);
uiBlockSetButLock(block, ob && ob->id.lib, ERROR_LIBDATA_MESSAGE);
- if (!ELEM5(md->type, eModifierType_Fluidsim, eModifierType_Softbody, eModifierType_ParticleSystem, eModifierType_Cloth, eModifierType_Smoke))
+ if (!ELEM5(md->type, eModifierType_Fluidsim, eModifierType_Softbody, eModifierType_ParticleSystem,
+ eModifierType_Cloth, eModifierType_Smoke))
+ {
uiItemO(row, IFACE_("Copy"), ICON_NONE, "OBJECT_OT_modifier_copy");
+ }
}
/* result is the layout block inside the box, that we return so that modifier settings can be drawn */
@@ -1046,8 +1131,10 @@ static uiLayout *draw_constraint(uiLayout *layout, Object *ob, bConstraint *con)
uiBlockSetEmboss(block, UI_EMBOSSN);
/* draw a ghost icon (for proxy) and also a lock beside it, to show that constraint is "proxy locked" */
- uiDefIconBut(block, BUT, B_CONSTRAINT_TEST, ICON_GHOST, xco + 244, yco, 19, 19, NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Proxy Protected"));
- uiDefIconBut(block, BUT, B_CONSTRAINT_TEST, ICON_LOCKED, xco + 262, yco, 19, 19, NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Proxy Protected"));
+ uiDefIconBut(block, BUT, B_CONSTRAINT_TEST, ICON_GHOST, xco + 244, yco, 19, 19,
+ NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Proxy Protected"));
+ uiDefIconBut(block, BUT, B_CONSTRAINT_TEST, ICON_LOCKED, xco + 262, yco, 19, 19,
+ NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Proxy Protected"));
uiBlockSetEmboss(block, UI_EMBOSS);
}
@@ -1076,7 +1163,8 @@ static uiLayout *draw_constraint(uiLayout *layout, Object *ob, bConstraint *con)
/* enabled */
uiBlockSetEmboss(block, UI_EMBOSSN);
- uiItemR(row, &ptr, "mute", 0, "", (con->flag & CONSTRAINT_OFF) ? ICON_RESTRICT_VIEW_ON : ICON_RESTRICT_VIEW_OFF);
+ uiItemR(row, &ptr, "mute", 0, "",
+ (con->flag & CONSTRAINT_OFF) ? ICON_RESTRICT_VIEW_ON : ICON_RESTRICT_VIEW_OFF);
uiBlockSetEmboss(block, UI_EMBOSS);
uiLayoutSetOperatorContext(row, WM_OP_INVOKE_DEFAULT);
@@ -1233,14 +1321,22 @@ void uiTemplatePreview(uiLayout *layout, ID *id, int show_buttons, ID *parent, M
RNA_pointer_create(id, &RNA_Texture, tex, &texture_ptr);
uiLayoutRow(layout, TRUE);
- uiDefButS(block, ROW, B_MATPRV, IFACE_("Texture"), 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, pr_texture, 10, TEX_PR_TEXTURE, 0, 0, "");
- if (GS(parent->name) == ID_MA)
- uiDefButS(block, ROW, B_MATPRV, IFACE_("Material"), 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, pr_texture, 10, TEX_PR_OTHER, 0, 0, "");
- else if (GS(parent->name) == ID_LA)
- uiDefButS(block, ROW, B_MATPRV, IFACE_("Lamp"), 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, pr_texture, 10, TEX_PR_OTHER, 0, 0, "");
- else if (GS(parent->name) == ID_WO)
- uiDefButS(block, ROW, B_MATPRV, IFACE_("World"), 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, pr_texture, 10, TEX_PR_OTHER, 0, 0, "");
- uiDefButS(block, ROW, B_MATPRV, IFACE_("Both"), 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, pr_texture, 10, TEX_PR_BOTH, 0, 0, "");
+ uiDefButS(block, ROW, B_MATPRV, IFACE_("Texture"), 0, 0, UI_UNIT_X * 10, UI_UNIT_Y,
+ pr_texture, 10, TEX_PR_TEXTURE, 0, 0, "");
+ if (GS(parent->name) == ID_MA) {
+ uiDefButS(block, ROW, B_MATPRV, IFACE_("Material"), 0, 0, UI_UNIT_X * 10, UI_UNIT_Y,
+ pr_texture, 10, TEX_PR_OTHER, 0, 0, "");
+ }
+ else if (GS(parent->name) == ID_LA) {
+ uiDefButS(block, ROW, B_MATPRV, IFACE_("Lamp"), 0, 0, UI_UNIT_X * 10, UI_UNIT_Y,
+ pr_texture, 10, TEX_PR_OTHER, 0, 0, "");
+ }
+ else if (GS(parent->name) == ID_WO) {
+ uiDefButS(block, ROW, B_MATPRV, IFACE_("World"), 0, 0, UI_UNIT_X * 10, UI_UNIT_Y,
+ pr_texture, 10, TEX_PR_OTHER, 0, 0, "");
+ }
+ uiDefButS(block, ROW, B_MATPRV, IFACE_("Both"), 0, 0, UI_UNIT_X * 10, UI_UNIT_Y,
+ pr_texture, 10, TEX_PR_BOTH, 0, 0, "");
/* Alpha button for texture preview */
if (*pr_texture != TEX_PR_OTHER) {
@@ -1330,7 +1426,8 @@ static void colorband_update_cb(bContext *UNUSED(C), void *bt_v, void *coba_v)
}
/* offset aligns from bottom, standard width 300, height 115 */
-static void colorband_buttons_large(uiLayout *layout, uiBlock *block, ColorBand *coba, int xoffs, int yoffs, RNAUpdateCb *cb)
+static void colorband_buttons_large(uiLayout *layout, uiBlock *block, ColorBand *coba,
+ int xoffs, int yoffs, RNAUpdateCb *cb)
{
uiBut *bt;
uiLayout *row;
@@ -1349,13 +1446,16 @@ static void colorband_buttons_large(uiLayout *layout, uiBlock *block, ColorBand
/* XXX, todo for later - convert to operator - campbell */
- bt = uiDefBut(block, BUT, 0, "F", 95 + xoffs, line1_y, 20, UI_UNIT_Y, NULL, 0, 0, 0, 0, TIP_("Flip colorband"));
+ bt = uiDefBut(block, BUT, 0, "F", 95 + xoffs, line1_y, 20, UI_UNIT_Y,
+ NULL, 0, 0, 0, 0, TIP_("Flip colorband"));
uiButSetNFunc(bt, colorband_flip_cb, MEM_dupallocN(cb), coba);
- uiDefButS(block, NUM, 0, "", 120 + xoffs, line1_y, 80, UI_UNIT_Y, &coba->cur, 0.0, (float)(MAX2(0, coba->tot - 1)), 0, 0, TIP_("Choose active color stop"));
+ uiDefButS(block, NUM, 0, "", 120 + xoffs, line1_y, 80, UI_UNIT_Y, &coba->cur, 0.0, (float)(MAX2(0, coba->tot - 1)),
+ 0, 0, TIP_("Choose active color stop"));
- bt = uiDefButS(block, MENU, 0, IFACE_("Interpolation %t|Ease %x1|Cardinal %x3|Linear %x0|B-Spline %x2|Constant %x4"),
- 210 + xoffs, line1_y, 90, UI_UNIT_Y, &coba->ipotype, 0.0, 0.0, 0, 0, TIP_("Set interpolation between color stops"));
+ bt = uiDefButS(block, MENU, 0, IFACE_("Interpolation %t|Ease %x1|Cardinal %x3|Linear %x0|B-Spline %x2|Constant %x4"),
+ 210 + xoffs, line1_y, 90, UI_UNIT_Y, &coba->ipotype, 0.0, 0.0, 0, 0,
+ TIP_("Set interpolation between color stops"));
uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
uiBlockEndAlign(block);
@@ -1391,10 +1491,11 @@ static void colorband_buttons_small(uiLayout *layout, uiBlock *block, ColorBand
bt = uiDefBut(block, BUT, 0, IFACE_("Add"), xs, butr->ymin + UI_UNIT_Y, 2.0f * unit, UI_UNIT_Y, NULL, 0, 0, 0, 0,
TIP_("Add a new color stop to the colorband"));
uiButSetNFunc(bt, colorband_add_cb, MEM_dupallocN(cb), coba);
- bt = uiDefBut(block, BUT, 0, IFACE_("Delete"), xs + 2.0f * unit, butr->ymin + UI_UNIT_Y, 1.5f * unit, UI_UNIT_Y, NULL, 0, 0, 0, 0,
- TIP_("Delete the active position"));
+ bt = uiDefBut(block, BUT, 0, IFACE_("Delete"), xs + 2.0f * unit, butr->ymin + UI_UNIT_Y, 1.5f * unit, UI_UNIT_Y,
+ NULL, 0, 0, 0, 0, TIP_("Delete the active position"));
uiButSetNFunc(bt, colorband_del_cb, MEM_dupallocN(cb), coba);
- bt = uiDefBut(block, BUT, 0, "F", xs + 3.5f * unit, butr->ymin + UI_UNIT_Y, 0.5f * unit, UI_UNIT_Y, NULL, 0, 0, 0, 0, TIP_("Flip the color ramp"));
+ bt = uiDefBut(block, BUT, 0, "F", xs + 3.5f * unit, butr->ymin + UI_UNIT_Y, 0.5f * unit, UI_UNIT_Y,
+ NULL, 0, 0, 0, 0, TIP_("Flip the color ramp"));
uiButSetNFunc(bt, colorband_flip_cb, MEM_dupallocN(cb), coba);
uiBlockEndAlign(block);
@@ -1406,7 +1507,7 @@ static void colorband_buttons_small(uiLayout *layout, uiBlock *block, ColorBand
}
bt = uiDefButS(block, MENU, 0, IFACE_("Interpolation %t|Ease %x1|Cardinal %x3|Linear %x0|B-Spline %x2|Constant %x4"),
- xs + 10.0f * unit, butr->ymin + UI_UNIT_Y, unit * 4, UI_UNIT_Y, &coba->ipotype, 0.0, 0.0, 0, 0,
+ xs + 10.0f * unit, butr->ymin + UI_UNIT_Y, unit * 4, UI_UNIT_Y, &coba->ipotype, 0.0, 0.0, 0, 0,
TIP_("Set interpolation between color stops"));
uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
@@ -1416,7 +1517,8 @@ static void colorband_buttons_small(uiLayout *layout, uiBlock *block, ColorBand
uiBlockEndAlign(block);
}
-static void colorband_buttons_layout(uiLayout *layout, uiBlock *block, ColorBand *coba, rctf *butr, int small, RNAUpdateCb *cb)
+static void colorband_buttons_layout(uiLayout *layout, uiBlock *block, ColorBand *coba, rctf *butr,
+ int small, RNAUpdateCb *cb)
{
if (small)
colorband_buttons_small(layout, block, coba, butr, cb);
@@ -1485,7 +1587,8 @@ void uiTemplateHistogram(uiLayout *layout, PointerRNA *ptr, const char *propname
hist->height = (hist->height <= UI_UNIT_Y) ? UI_UNIT_Y : hist->height;
- bt = uiDefBut(block, HISTOGRAM, 0, "", rect.xmin, rect.ymin, BLI_rctf_size_x(&rect), hist->height, hist, 0, 0, 0, 0, "");
+ bt = uiDefBut(block, HISTOGRAM, 0, "", rect.xmin, rect.ymin, BLI_rctf_size_x(&rect), hist->height, hist,
+ 0, 0, 0, 0, "");
uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
MEM_freeN(cb);
@@ -1522,7 +1625,8 @@ void uiTemplateWaveform(uiLayout *layout, PointerRNA *ptr, const char *propname)
scopes->wavefrm_height = (scopes->wavefrm_height <= UI_UNIT_Y) ? UI_UNIT_Y : scopes->wavefrm_height;
- bt = uiDefBut(block, WAVEFORM, 0, "", rect.xmin, rect.ymin, BLI_rctf_size_x(&rect), scopes->wavefrm_height, scopes, 0, 0, 0, 0, "");
+ bt = uiDefBut(block, WAVEFORM, 0, "", rect.xmin, rect.ymin, BLI_rctf_size_x(&rect), scopes->wavefrm_height, scopes,
+ 0, 0, 0, 0, "");
(void)bt; /* UNUSED */
MEM_freeN(cb);
@@ -1559,7 +1663,8 @@ void uiTemplateVectorscope(uiLayout *layout, PointerRNA *ptr, const char *propna
scopes->vecscope_height = (scopes->vecscope_height <= UI_UNIT_Y) ? UI_UNIT_Y : scopes->vecscope_height;
- bt = uiDefBut(block, VECTORSCOPE, 0, "", rect.xmin, rect.ymin, BLI_rctf_size_x(&rect), scopes->vecscope_height, scopes, 0, 0, 0, 0, "");
+ bt = uiDefBut(block, VECTORSCOPE, 0, "", rect.xmin, rect.ymin, BLI_rctf_size_x(&rect),
+ scopes->vecscope_height, scopes, 0, 0, 0, 0, "");
uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
MEM_freeN(cb);
@@ -1658,10 +1763,14 @@ static uiBlock *curvemap_clipping_func(bContext *C, ARegion *ar, void *cumap_v)
uiButSetFunc(bt, curvemap_buttons_setclip, cumap, NULL);
uiBlockBeginAlign(block);
- uiDefButF(block, NUM, 0, IFACE_("Min X "), 0, 4 * UI_UNIT_Y, width, UI_UNIT_Y, &cumap->clipr.xmin, -100.0, cumap->clipr.xmax, 10, 0, "");
- uiDefButF(block, NUM, 0, IFACE_("Min Y "), 0, 3 * UI_UNIT_Y, width, UI_UNIT_Y, &cumap->clipr.ymin, -100.0, cumap->clipr.ymax, 10, 0, "");
- uiDefButF(block, NUM, 0, IFACE_("Max X "), 0, 2 * UI_UNIT_Y, width, UI_UNIT_Y, &cumap->clipr.xmax, cumap->clipr.xmin, 100.0, 10, 0, "");
- uiDefButF(block, NUM, 0, IFACE_("Max Y "), 0, UI_UNIT_Y, width, UI_UNIT_Y, &cumap->clipr.ymax, cumap->clipr.ymin, 100.0, 10, 0, "");
+ uiDefButF(block, NUM, 0, IFACE_("Min X "), 0, 4 * UI_UNIT_Y, width, UI_UNIT_Y,
+ &cumap->clipr.xmin, -100.0, cumap->clipr.xmax, 10, 0, "");
+ uiDefButF(block, NUM, 0, IFACE_("Min Y "), 0, 3 * UI_UNIT_Y, width, UI_UNIT_Y,
+ &cumap->clipr.ymin, -100.0, cumap->clipr.ymax, 10, 0, "");
+ uiDefButF(block, NUM, 0, IFACE_("Max X "), 0, 2 * UI_UNIT_Y, width, UI_UNIT_Y,
+ &cumap->clipr.xmax, cumap->clipr.xmin, 100.0, 10, 0, "");
+ uiDefButF(block, NUM, 0, IFACE_("Max Y "), 0, UI_UNIT_Y, width, UI_UNIT_Y,
+ &cumap->clipr.ymax, cumap->clipr.ymin, 100.0, 10, 0, "");
uiBlockSetDirection(block, UI_RIGHT);
@@ -1710,12 +1819,18 @@ static uiBlock *curvemap_tools_func(bContext *C, ARegion *ar, void *cumap_v)
block = uiBeginBlock(C, ar, __func__, UI_EMBOSS);
uiBlockSetButmFunc(block, curvemap_tools_dofunc, cumap_v);
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, IFACE_("Reset View"), 0, yco -= UI_UNIT_Y, menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 1, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, IFACE_("Vector Handle"), 0, yco -= UI_UNIT_Y, menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 2, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, IFACE_("Auto Handle"), 0, yco -= UI_UNIT_Y, menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 3, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, IFACE_("Extend Horizontal"), 0, yco -= UI_UNIT_Y, menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 4, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, IFACE_("Extend Extrapolated"), 0, yco -= UI_UNIT_Y, menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 5, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, IFACE_("Reset Curve"), 0, yco -= UI_UNIT_Y, menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, IFACE_("Reset View"), 0, yco -= UI_UNIT_Y,
+ menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 1, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, IFACE_("Vector Handle"), 0, yco -= UI_UNIT_Y,
+ menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 2, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, IFACE_("Auto Handle"), 0, yco -= UI_UNIT_Y,
+ menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 3, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, IFACE_("Extend Horizontal"), 0, yco -= UI_UNIT_Y,
+ menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 4, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, IFACE_("Extend Extrapolated"), 0, yco -= UI_UNIT_Y,
+ menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 5, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, IFACE_("Reset Curve"), 0, yco -= UI_UNIT_Y,
+ menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
uiBlockSetDirection(block, UI_RIGHT);
uiTextBoundsBlock(block, 50);
@@ -1732,10 +1847,14 @@ static uiBlock *curvemap_brush_tools_func(bContext *C, ARegion *ar, void *cumap_
block = uiBeginBlock(C, ar, __func__, UI_EMBOSS);
uiBlockSetButmFunc(block, curvemap_tools_dofunc, cumap_v);
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, IFACE_("Reset View"), 0, yco -= UI_UNIT_Y, menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 1, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, IFACE_("Vector Handle"), 0, yco -= UI_UNIT_Y, menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 2, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, IFACE_("Auto Handle"), 0, yco -= UI_UNIT_Y, menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 3, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, IFACE_("Reset Curve"), 0, yco -= UI_UNIT_Y, menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, IFACE_("Reset View"), 0, yco -= UI_UNIT_Y,
+ menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 1, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, IFACE_("Vector Handle"), 0, yco -= UI_UNIT_Y,
+ menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 2, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, IFACE_("Auto Handle"), 0, yco -= UI_UNIT_Y,
+ menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 3, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, IFACE_("Reset Curve"), 0, yco -= UI_UNIT_Y,
+ menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
uiBlockSetDirection(block, UI_RIGHT);
uiTextBoundsBlock(block, 50);
@@ -1775,7 +1894,8 @@ static void curvemap_buttons_reset(bContext *C, void *cb_v, void *cumap_v)
}
/* still unsure how this call evolves... we use labeltype for defining what curve-channels to show */
-static void curvemap_buttons_layout(uiLayout *layout, PointerRNA *ptr, char labeltype, int levels, int brush, RNAUpdateCb *cb)
+static void curvemap_buttons_layout(uiLayout *layout, PointerRNA *ptr, char labeltype, int levels,
+ int brush, RNAUpdateCb *cb)
{
CurveMapping *cumap = ptr->data;
CurveMap *cm = &cumap->cm[cumap->cur];
@@ -1956,7 +2076,8 @@ void uiTemplateCurveMapping(uiLayout *layout, PointerRNA *ptr, const char *propn
#define WHEEL_SIZE 100
/* This template now follows User Preference for type - name is not correct anymore... */
-void uiTemplateColorPicker(uiLayout *layout, PointerRNA *ptr, const char *propname, int value_slider, int lock, int lock_luminosity, int cubic)
+void uiTemplateColorPicker(uiLayout *layout, PointerRNA *ptr, const char *propname, int value_slider,
+ int lock, int lock_luminosity, int cubic)
{
PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
uiBlock *block = uiLayoutGetBlock(layout);
@@ -1976,16 +2097,20 @@ void uiTemplateColorPicker(uiLayout *layout, PointerRNA *ptr, const char *propna
switch (U.color_picker_type) {
case USER_CP_CIRCLE:
- but = uiDefButR_prop(block, HSVCIRCLE, 0, "", 0, 0, WHEEL_SIZE, WHEEL_SIZE, ptr, prop, -1, 0.0, 0.0, 0, 0, "");
+ but = uiDefButR_prop(block, HSVCIRCLE, 0, "", 0, 0, WHEEL_SIZE, WHEEL_SIZE, ptr, prop,
+ -1, 0.0, 0.0, 0, 0, "");
break;
case USER_CP_SQUARE_SV:
- but = uiDefButR_prop(block, HSVCUBE, 0, "", 0, 0, WHEEL_SIZE, WHEEL_SIZE, ptr, prop, -1, 0.0, 0.0, UI_GRAD_SV, 0, "");
+ but = uiDefButR_prop(block, HSVCUBE, 0, "", 0, 0, WHEEL_SIZE, WHEEL_SIZE, ptr, prop,
+ -1, 0.0, 0.0, UI_GRAD_SV, 0, "");
break;
case USER_CP_SQUARE_HS:
- but = uiDefButR_prop(block, HSVCUBE, 0, "", 0, 0, WHEEL_SIZE, WHEEL_SIZE, ptr, prop, -1, 0.0, 0.0, UI_GRAD_HS, 0, "");
+ but = uiDefButR_prop(block, HSVCUBE, 0, "", 0, 0, WHEEL_SIZE, WHEEL_SIZE, ptr, prop,
+ -1, 0.0, 0.0, UI_GRAD_HS, 0, "");
break;
case USER_CP_SQUARE_HV:
- but = uiDefButR_prop(block, HSVCUBE, 0, "", 0, 0, WHEEL_SIZE, WHEEL_SIZE, ptr, prop, -1, 0.0, 0.0, UI_GRAD_HV, 0, "");
+ but = uiDefButR_prop(block, HSVCUBE, 0, "", 0, 0, WHEEL_SIZE, WHEEL_SIZE, ptr, prop,
+ -1, 0.0, 0.0, UI_GRAD_HV, 0, "");
break;
}
@@ -2010,19 +2135,23 @@ void uiTemplateColorPicker(uiLayout *layout, PointerRNA *ptr, const char *propna
switch (U.color_picker_type) {
case USER_CP_CIRCLE:
uiItemS(row);
- uiDefButR_prop(block, HSVCUBE, 0, "", WHEEL_SIZE + 6, 0, 14, WHEEL_SIZE, ptr, prop, -1, softmin, softmax, UI_GRAD_V_ALT, 0, "");
+ uiDefButR_prop(block, HSVCUBE, 0, "", WHEEL_SIZE + 6, 0, 14, WHEEL_SIZE, ptr, prop,
+ -1, softmin, softmax, UI_GRAD_V_ALT, 0, "");
break;
case USER_CP_SQUARE_SV:
uiItemS(col);
- uiDefButR_prop(block, HSVCUBE, 0, "", 0, 4, WHEEL_SIZE, 18, ptr, prop, -1, softmin, softmax, UI_GRAD_SV + 3, 0, "");
+ uiDefButR_prop(block, HSVCUBE, 0, "", 0, 4, WHEEL_SIZE, 18, ptr, prop,
+ -1, softmin, softmax, UI_GRAD_SV + 3, 0, "");
break;
case USER_CP_SQUARE_HS:
uiItemS(col);
- uiDefButR_prop(block, HSVCUBE, 0, "", 0, 4, WHEEL_SIZE, 18, ptr, prop, -1, softmin, softmax, UI_GRAD_HS + 3, 0, "");
+ uiDefButR_prop(block, HSVCUBE, 0, "", 0, 4, WHEEL_SIZE, 18, ptr, prop,
+ -1, softmin, softmax, UI_GRAD_HS + 3, 0, "");
break;
case USER_CP_SQUARE_HV:
uiItemS(col);
- uiDefButR_prop(block, HSVCUBE, 0, "", 0, 4, WHEEL_SIZE, 18, ptr, prop, -1, softmin, softmax, UI_GRAD_HV + 3, 0, "");
+ uiDefButR_prop(block, HSVCUBE, 0, "", 0, 4, WHEEL_SIZE, 18, ptr, prop,
+ -1, softmin, softmax, UI_GRAD_HV + 3, 0, "");
break;
}
@@ -2184,7 +2313,8 @@ void uiTemplateGameStates(uiLayout *layout, PointerRNA *ptr, const char *propnam
else if (used_prop && RNA_property_boolean_get_index(used_ptr, used_prop, state))
icon = ICON_LAYER_USED;
- but = uiDefIconButR_prop(block, ICONTOG, 0, icon, 0, 0, UI_UNIT_X / 2, UI_UNIT_Y / 2, ptr, prop, state, 0, 0, -1, -1, sca_state_name_get(ob, state));
+ but = uiDefIconButR_prop(block, ICONTOG, 0, icon, 0, 0, UI_UNIT_X / 2, UI_UNIT_Y / 2, ptr, prop,
+ state, 0, 0, -1, -1, sca_state_name_get(ob, state));
uiButSetFunc(but, handle_layer_buttons, but, SET_INT_IN_POINTER(state));
but->type = TOG;
}
@@ -2232,7 +2362,8 @@ static int list_item_icon_get(bContext *C, PointerRNA *itemptr, int rnaicon, int
return rnaicon;
}
-static void list_item_row(bContext *C, uiLayout *layout, PointerRNA *ptr, PointerRNA *itemptr, int i, int rnaicon, PointerRNA *activeptr, PropertyRNA *activeprop, const char *prop_list_id)
+static void list_item_row(bContext *C, uiLayout *layout, PointerRNA *ptr, PointerRNA *itemptr, int i,
+ int rnaicon, PointerRNA *activeptr, PropertyRNA *activeprop, const char *prop_list_id)
{
uiBlock *block = uiLayoutGetBlock(layout);
uiBut *but;
@@ -2246,7 +2377,8 @@ static void list_item_row(bContext *C, uiLayout *layout, PointerRNA *ptr, Pointe
/* list item behind label & other buttons */
sub = uiLayoutRow(overlap, FALSE);
- but = uiDefButR_prop(block, LISTROW, 0, "", 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, activeptr, activeprop, 0, 0, i, 0, 0, "");
+ but = uiDefButR_prop(block, LISTROW, 0, "", 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, activeptr, activeprop,
+ 0, 0, i, 0, 0, "");
uiButSetFlag(but, UI_BUT_NO_TOOLTIP);
sub = uiLayoutRow(overlap, FALSE);
@@ -2263,7 +2395,8 @@ static void list_item_row(bContext *C, uiLayout *layout, PointerRNA *ptr, Pointe
if (itemptr->type == &RNA_MeshTexturePolyLayer || itemptr->type == &RNA_MeshLoopColorLayer) {
uiItemL(sub, name, icon);
uiBlockSetEmboss(block, UI_EMBOSSN);
- uiDefIconButR(block, TOG, 0, ICON_SCENE, 0, 0, UI_UNIT_X, UI_UNIT_Y, itemptr, "active_render", 0, 0, 0, 0, 0, NULL);
+ uiDefIconButR(block, TOG, 0, ICON_SCENE, 0, 0, UI_UNIT_X, UI_UNIT_Y, itemptr, "active_render",
+ 0, 0, 0, 0, 0, NULL);
uiBlockSetEmboss(block, UI_EMBOSS);
}
else if (RNA_struct_is_a(itemptr->type, &RNA_MaterialTextureSlot)) {
@@ -2356,7 +2489,8 @@ static void list_item_row(bContext *C, uiLayout *layout, PointerRNA *ptr, Pointe
uiItemL(sub, name_final, icon);
if (dynamicPaint_surfaceHasColorPreview(surface)) {
uiBlockSetEmboss(block, UI_EMBOSSN);
- uiDefIconButR(block, OPTION, 0, (surface->flags & MOD_DPAINT_PREVIEW) ? ICON_RESTRICT_VIEW_OFF : ICON_RESTRICT_VIEW_ON,
+ uiDefIconButR(block, OPTION, 0,
+ (surface->flags & MOD_DPAINT_PREVIEW) ? ICON_RESTRICT_VIEW_OFF : ICON_RESTRICT_VIEW_ON,
0, 0, UI_UNIT_X, UI_UNIT_Y, itemptr, "show_preview", 0, 0, 0, 0, 0, NULL);
uiBlockSetEmboss(block, UI_EMBOSS);
}
@@ -2445,7 +2579,8 @@ static void list_item_row(bContext *C, uiLayout *layout, PointerRNA *ptr, Pointe
}
}
-void uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, PointerRNA *activeptr, const char *activepropname, const char *prop_list, int rows, int maxrows, int listtype)
+void uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, PointerRNA *activeptr,
+ const char *activepropname, const char *prop_list, int rows, int maxrows, int listtype)
{
PropertyRNA *prop = NULL, *activeprop;
PropertyType type, activetype;
@@ -2521,7 +2656,8 @@ void uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *
row = uiLayoutRow(col, FALSE);
icon = list_item_icon_get(C, &itemptr, rnaicon, 1);
- but = uiDefIconButR_prop(block, LISTROW, 0, icon, 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, activeptr, activeprop, 0, 0, i, 0, 0, "");
+ but = uiDefIconButR_prop(block, LISTROW, 0, icon, 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, activeptr,
+ activeprop, 0, 0, i, 0, 0, "");
uiButSetFlag(but, UI_BUT_NO_TOOLTIP);
@@ -2563,7 +2699,8 @@ void uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *
/* next/prev button */
BLI_snprintf(numstr, sizeof(numstr), "%d :", i);
- but = uiDefIconTextButR_prop(block, NUM, 0, 0, numstr, 0, 0, UI_UNIT_X * 5, UI_UNIT_Y, activeptr, activeprop, 0, 0, 0, 0, 0, "");
+ but = uiDefIconTextButR_prop(block, NUM, 0, 0, numstr, 0, 0, UI_UNIT_X * 5, UI_UNIT_Y, activeptr,
+ activeprop, 0, 0, 0, 0, 0, "");
if (i == 0)
uiButSetFlag(but, UI_BUT_DISABLED);
}
@@ -2620,7 +2757,8 @@ void uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *
/* add scrollbar */
if (len > items) {
col = uiLayoutColumn(row, FALSE);
- uiDefButI(block, SCROLL, 0, "", 0, 0, UI_UNIT_X * 0.75, UI_UNIT_Y * items, &pa->list_scroll, 0, len - items, items, 0, "");
+ uiDefButI(block, SCROLL, 0, "", 0, 0, UI_UNIT_X * 0.75, UI_UNIT_Y * items, &pa->list_scroll,
+ 0, len - items, items, 0, "");
}
}
}
@@ -2767,19 +2905,19 @@ void uiTemplateRunningJobs(uiLayout *layout, bContext *C)
ui_abs = uiLayoutAbsolute(layout, FALSE);
(void)ui_abs; /* UNUSED */
- uiDefIconBut(block, BUT, handle_event, ICON_PANEL_CLOSE,
- 0, UI_UNIT_Y * 0.1, UI_UNIT_X * 0.8, UI_UNIT_Y * 0.8, NULL, 0.0f, 0.0f, 0, 0, TIP_("Stop this job"));
+ uiDefIconBut(block, BUT, handle_event, ICON_PANEL_CLOSE, 0, UI_UNIT_Y * 0.1, UI_UNIT_X * 0.8, UI_UNIT_Y * 0.8,
+ NULL, 0.0f, 0.0f, 0, 0, TIP_("Stop this job"));
uiDefBut(block, PROGRESSBAR, 0, WM_jobs_name(wm, owner),
UI_UNIT_X, 0, 100, UI_UNIT_Y, NULL, 0.0f, 0.0f, WM_jobs_progress(wm, owner), 0, TIP_("Progress"));
uiLayoutRow(layout, FALSE);
}
if (WM_jobs_test(wm, screen, WM_JOB_TYPE_SCREENCAST))
- uiDefIconTextBut(block, BUT, B_STOPCAST, ICON_CANCEL, IFACE_("Capture"), 0, 0, 85, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0,
- TIP_("Stop screencast"));
+ uiDefIconTextBut(block, BUT, B_STOPCAST, ICON_CANCEL, IFACE_("Capture"), 0, 0, 85, UI_UNIT_Y,
+ NULL, 0.0f, 0.0f, 0, 0, TIP_("Stop screencast"));
if (screen->animtimer)
- uiDefIconTextBut(block, BUT, B_STOPANIM, ICON_CANCEL, IFACE_("Anim Player"), 0, 0, 100, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0,
- TIP_("Stop animation playback"));
+ uiDefIconTextBut(block, BUT, B_STOPANIM, ICON_CANCEL, IFACE_("Anim Player"), 0, 0, 100, UI_UNIT_Y,
+ NULL, 0.0f, 0.0f, 0, 0, TIP_("Stop animation playback"));
}
/************************* Reports for Last Operator Template **************************/
@@ -2818,7 +2956,8 @@ void uiTemplateReportsBanner(uiLayout *layout, bContext *C)
rgb_float_to_uchar(but->col, rti->col);
but->col[3] = 255;
- but = uiDefBut(block, ROUNDBOX, 0, "", UI_UNIT_X + 10, 0, UI_UNIT_X + width, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, "");
+ but = uiDefBut(block, ROUNDBOX, 0, "", UI_UNIT_X + 10, 0, UI_UNIT_X + width, UI_UNIT_Y,
+ NULL, 0.0f, 0.0f, 0, 0, "");
but->col[0] = but->col[1] = but->col[2] = FTOCHAR(rti->grayscale);
but->col[3] = 255;
@@ -2839,14 +2978,15 @@ void uiTemplateReportsBanner(uiLayout *layout, bContext *C)
uiBlockSetEmboss(block, UI_EMBOSSN);
if (reports->list.first != reports->list.last)
- uiDefIconButO(block, BUT, "UI_OT_reports_to_textblock", WM_OP_INVOKE_REGION_WIN, icon, 2, 0,
- UI_UNIT_X, UI_UNIT_Y, TIP_("Click to see the remaining reports in text block: 'Recent Reports'"));
+ uiDefIconButO(block, BUT, "UI_OT_reports_to_textblock", WM_OP_INVOKE_REGION_WIN, icon, 2, 0, UI_UNIT_X,
+ UI_UNIT_Y, TIP_("Click to see the remaining reports in text block: 'Recent Reports'"));
else
uiDefIconBut(block, LABEL, 0, icon, 2, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, "");
uiBlockSetEmboss(block, UI_EMBOSS);
- uiDefBut(block, LABEL, 0, report->message, UI_UNIT_X + 10, 0, UI_UNIT_X + width, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, "");
+ uiDefBut(block, LABEL, 0, report->message, UI_UNIT_X + 10, 0, UI_UNIT_X + width, UI_UNIT_Y,
+ NULL, 0.0f, 0.0f, 0, 0, "");
}
/********************************* Keymap *************************************/
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index bef8fff4ae3..c43fc4bc4e4 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -2648,6 +2648,11 @@ static void widget_swatch(uiBut *but, uiWidgetColors *wcol, rcti *rect, int stat
}
+static void widget_normal(uiBut *but, uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int UNUSED(roundboxalign))
+{
+ ui_draw_but_NORMAL(but, wcol, rect);
+}
+
static void widget_icon_has_anim(uiBut *UNUSED(but), uiWidgetColors *wcol, rcti *rect, int state, int UNUSED(roundboxalign))
{
if (state & (UI_BUT_ANIMATED | UI_BUT_ANIMATED_KEY | UI_BUT_DRIVEN | UI_BUT_REDALERT)) {
@@ -3055,6 +3060,7 @@ static uiWidgetType *widget_type(uiWidgetTypeEnum type)
break;
case UI_WTYPE_NORMAL:
+ wt.custom = widget_normal;
break;
case UI_WTYPE_SCROLL:
@@ -3294,7 +3300,7 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct
break;
case BUT_NORMAL:
- ui_draw_but_NORMAL(but, &tui->wcol_regular, rect);
+ wt = widget_type(UI_WTYPE_NORMAL);
break;
case BUT_IMAGE:
diff --git a/source/blender/editors/mesh/editmesh_add.c b/source/blender/editors/mesh/editmesh_add.c
index 70b359d3e28..65d70e231a4 100644
--- a/source/blender/editors/mesh/editmesh_add.c
+++ b/source/blender/editors/mesh/editmesh_add.c
@@ -108,8 +108,8 @@ static int add_primitive_plane_exec(bContext *C, wmOperator *op)
obedit = make_prim_init(C, "Plane", &dia, mat, &state, loc, rot, layer);
em = BMEdit_FromObject(obedit);
- if (!EDBM_op_call_and_selectf(em, op, "vertout",
- "create_grid xsegments=%i ysegments=%i size=%f mat=%m4", 1, 1, dia, mat))
+ 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))
{
return OPERATOR_CANCELLED;
}
@@ -149,7 +149,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, "vertout", "create_cube mat=%m4 size=%f", mat, dia * 2.0f)) {
+ if (!EDBM_op_call_and_selectf(em, op, "verts.out", "create_cube mat=%m4 size=%f", mat, dia * 2.0f)) {
return OPERATOR_CANCELLED;
}
@@ -198,7 +198,7 @@ static int add_primitive_circle_exec(bContext *C, wmOperator *op)
obedit = make_prim_init(C, "Circle", &dia, mat, &state, loc, rot, layer);
em = BMEdit_FromObject(obedit);
- if (!EDBM_op_call_and_selectf(em, op, "vertout",
+ if (!EDBM_op_call_and_selectf(em, op, "verts.out",
"create_circle segments=%i diameter=%f cap_ends=%b cap_tris=%b mat=%m4",
RNA_int_get(op->ptr, "vertices"), RNA_float_get(op->ptr, "radius") * dia,
cap_end, cap_tri, mat))
@@ -253,7 +253,7 @@ static int add_primitive_cylinder_exec(bContext *C, wmOperator *op)
em = BMEdit_FromObject(obedit);
if (!EDBM_op_call_and_selectf(
- em, op, "vertout",
+ em, op, "verts.out",
"create_cone segments=%i diameter1=%f diameter2=%f cap_ends=%b cap_tris=%b depth=%f mat=%m4",
RNA_int_get(op->ptr, "vertices"),
RNA_float_get(op->ptr, "radius") * dia,
@@ -313,7 +313,7 @@ static int add_primitive_cone_exec(bContext *C, wmOperator *op)
em = BMEdit_FromObject(obedit);
if (!EDBM_op_call_and_selectf(
- em, op, "vertout",
+ em, op, "verts.out",
"create_cone segments=%i diameter1=%f diameter2=%f cap_ends=%b cap_tris=%b depth=%f mat=%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))
@@ -368,8 +368,8 @@ static int add_primitive_grid_exec(bContext *C, wmOperator *op)
obedit = make_prim_init(C, "Grid", &dia, mat, &state, loc, rot, layer);
em = BMEdit_FromObject(obedit);
- if (!EDBM_op_call_and_selectf(em, op, "vertout",
- "create_grid xsegments=%i ysegments=%i size=%f mat=%m4",
+ if (!EDBM_op_call_and_selectf(em, op, "verts.out",
+ "create_grid x_segments=%i y_segments=%i size=%f mat=%m4",
RNA_int_get(op->ptr, "x_subdivisions"),
RNA_int_get(op->ptr, "y_subdivisions"),
RNA_float_get(op->ptr, "size") * dia, mat))
@@ -420,14 +420,14 @@ static int add_primitive_monkey_exec(bContext *C, wmOperator *op)
if (!view_aligned)
rot[0] += (float)M_PI / 2.0f;
- obedit = make_prim_init(C, "Monkey", &dia, mat, &state, loc, rot, layer);
+ obedit = make_prim_init(C, "Suzanne", &dia, mat, &state, loc, rot, layer);
mat[0][0] *= dia;
mat[1][1] *= dia;
mat[2][2] *= dia;
em = BMEdit_FromObject(obedit);
- if (!EDBM_op_call_and_selectf(em, op, "vertout", "create_monkey mat=%m4", mat)) {
+ if (!EDBM_op_call_and_selectf(em, op, "verts.out", "create_monkey mat=%m4", mat)) {
return OPERATOR_CANCELLED;
}
@@ -466,8 +466,8 @@ static int add_primitive_uvsphere_exec(bContext *C, wmOperator *op)
obedit = make_prim_init(C, "Sphere", &dia, mat, &state, loc, rot, layer);
em = BMEdit_FromObject(obedit);
- if (!EDBM_op_call_and_selectf(em, op, "vertout",
- "create_uvsphere segments=%i revolutions=%i diameter=%f mat=%m4",
+ if (!EDBM_op_call_and_selectf(em, op, "verts.out",
+ "create_uvsphere u_segments=%i v_segments=%i diameter=%f mat=%m4",
RNA_int_get(op->ptr, "segments"), RNA_int_get(op->ptr, "ring_count"),
RNA_float_get(op->ptr, "size") * dia, mat))
{
@@ -518,7 +518,7 @@ static int add_primitive_icosphere_exec(bContext *C, wmOperator *op)
em = BMEdit_FromObject(obedit);
if (!EDBM_op_call_and_selectf(
- em, op, "vertout",
+ em, op, "verts.out",
"create_icosphere subdivisions=%i diameter=%f mat=%m4",
RNA_int_get(op->ptr, "subdivisions"),
RNA_float_get(op->ptr, "size") * dia, mat))
diff --git a/source/blender/editors/mesh/editmesh_bvh.c b/source/blender/editors/mesh/editmesh_bvh.c
index 3f7100c5417..289dc37b3e4 100644
--- a/source/blender/editors/mesh/editmesh_bvh.c
+++ b/source/blender/editors/mesh/editmesh_bvh.c
@@ -157,13 +157,13 @@ BMBVHTree *BMBVH_NewBVH(BMEditMesh *em, int flag, Scene *scene, Object *obedit)
if (flag & BMBVH_RESPECT_SELECT) {
- /* note, the arrays wont allign now! take care */
+ /* note, the arrays wont align now! take care */
if (!BM_elem_flag_test(em->looptris[i][0]->f, BM_ELEM_SELECT)) {
continue;
}
}
else if (flag & BMBVH_RESPECT_HIDDEN) {
- /* note, the arrays wont allign now! take care */
+ /* note, the arrays wont align now! take care */
if (BM_elem_flag_test(em->looptris[i][0]->f, BM_ELEM_HIDDEN)) {
continue;
}
diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c
index f6f226ec614..9e0c85a2f17 100644
--- a/source/blender/editors/mesh/editmesh_knife.c
+++ b/source/blender/editors/mesh/editmesh_knife.c
@@ -1828,7 +1828,7 @@ static void remerge_faces(KnifeTool_OpData *kcd)
BMO_op_initf(bm, &bmop, "beautify_fill faces=%ff constrain_edges=%fe", FACE_NEW, BOUNDARY);
BMO_op_exec(bm, &bmop);
- BMO_slot_buffer_flag_enable(bm, &bmop, "geomout", BM_FACE, FACE_NEW);
+ BMO_slot_buffer_flag_enable(bm, &bmop, "geom.out", BM_FACE, FACE_NEW);
BMO_op_finish(bm, &bmop);
@@ -2578,8 +2578,8 @@ static void knife_make_chain_cut(KnifeTool_OpData *kcd, BMFace *f, ListBase *cha
int nco = BLI_countlist(chain) - 1;
float (*cos)[3] = NULL;
KnifeVert **kverts;
- BLI_array_fixedstack_declare(cos, BM_NGON_STACK_SIZE, nco, __func__);
- BLI_array_fixedstack_declare(kverts, BM_NGON_STACK_SIZE, nco, __func__);
+ BLI_array_fixedstack_declare(cos, BM_DEFAULT_NGON_STACK_SIZE, nco, __func__);
+ BLI_array_fixedstack_declare(kverts, BM_DEFAULT_NGON_STACK_SIZE, nco, __func__);
kfe = ((Ref *)chain->first)->ref;
v1 = kfe->v1->v ? kfe->v1->v : kfe->v2->v;
diff --git a/source/blender/editors/mesh/editmesh_loopcut.c b/source/blender/editors/mesh/editmesh_loopcut.c
index 851a72f5631..d4b73dd1b64 100644
--- a/source/blender/editors/mesh/editmesh_loopcut.c
+++ b/source/blender/editors/mesh/editmesh_loopcut.c
@@ -311,7 +311,8 @@ static void ringsel_find_edge(RingSelOpData *lcd, int cuts)
static void ringsel_finish(bContext *C, wmOperator *op)
{
RingSelOpData *lcd = op->customdata;
- int cuts = RNA_int_get(op->ptr, "number_cuts");
+ const int cuts = RNA_int_get(op->ptr, "number_cuts");
+ const float smoothness = 0.292f * RNA_float_get(op->ptr, "smoothness");
if (lcd->eed) {
BMEditMesh *em = lcd->em;
@@ -323,7 +324,7 @@ static void ringsel_finish(bContext *C, wmOperator *op)
* Note though that it will break edgeslide in this specific case.
* See [#31939]. */
BM_mesh_esubdivide(em->bm, BM_ELEM_SELECT,
- 0.0f, 0.0f, 0.0f,
+ smoothness, 0.0f, 0.0f,
cuts,
SUBDIV_SELECT_LOOPCUT, SUBD_PATH, 0, TRUE, 0);
@@ -417,6 +418,7 @@ static int ringcut_cancel(bContext *C, wmOperator *op)
static int ringcut_invoke(bContext *C, wmOperator *op, wmEvent *evt)
{
+ ScrArea *sa = CTX_wm_area(C);
Object *obedit = CTX_data_edit_object(C);
RingSelOpData *lcd;
BMEdge *edge;
@@ -442,13 +444,17 @@ static int ringcut_invoke(bContext *C, wmOperator *op, wmEvent *evt)
lcd->eed = edge;
ringsel_find_edge(lcd, 1);
}
- ED_area_headerprint(CTX_wm_area(C), "Select a ring to be cut, use mouse-wheel or page-up/down for number of cuts");
+ ED_area_headerprint(sa,
+ "Select a ring to be cut, "
+ "use mouse-wheel or page-up/down for number of cuts, "
+ "Hold Alt for smooth");
return OPERATOR_RUNNING_MODAL;
}
static int loopcut_modal(bContext *C, wmOperator *op, wmEvent *event)
{
+ float smoothness = RNA_float_get(op->ptr, "smoothness");
int cuts = RNA_int_get(op->ptr, "number_cuts");
RingSelOpData *lcd = op->customdata;
int show_cuts = 0;
@@ -495,11 +501,17 @@ static int loopcut_modal(bContext *C, wmOperator *op, wmEvent *event)
case WHEELUPMOUSE: /* change number of cuts */
if (event->val == KM_RELEASE)
break;
-
- cuts++;
- RNA_int_set(op->ptr, "number_cuts", cuts);
- ringsel_find_edge(lcd, cuts);
- show_cuts = TRUE;
+ if (event->alt == 0) {
+ cuts++;
+ RNA_int_set(op->ptr, "number_cuts", cuts);
+ ringsel_find_edge(lcd, cuts);
+ show_cuts = TRUE;
+ }
+ else {
+ smoothness = min_ff(smoothness + 0.05f, 4.0f);
+ RNA_float_set(op->ptr, "smoothness", smoothness);
+ show_cuts = TRUE;
+ }
ED_region_tag_redraw(lcd->ar);
break;
@@ -509,10 +521,17 @@ static int loopcut_modal(bContext *C, wmOperator *op, wmEvent *event)
if (event->val == KM_RELEASE)
break;
- cuts = max_ii(cuts - 1, 0);
- RNA_int_set(op->ptr, "number_cuts", cuts);
- ringsel_find_edge(lcd, cuts);
- show_cuts = TRUE;
+ if (event->alt == 0) {
+ cuts = max_ii(cuts - 1, 0);
+ RNA_int_set(op->ptr, "number_cuts", cuts);
+ ringsel_find_edge(lcd, cuts);
+ show_cuts = TRUE;
+ }
+ else {
+ smoothness = max_ff(smoothness - 0.05f, 0.0f);
+ RNA_float_set(op->ptr, "smoothness", smoothness);
+ show_cuts = TRUE;
+ }
ED_region_tag_redraw(lcd->ar);
break;
@@ -556,7 +575,7 @@ static int loopcut_modal(bContext *C, wmOperator *op, wmEvent *event)
if (show_cuts) {
char buf[64];
- BLI_snprintf(buf, sizeof(buf), "Number of Cuts: %d", cuts);
+ BLI_snprintf(buf, sizeof(buf), "Number of Cuts: %d, Smooth: %.2f (Alt)", cuts, smoothness);
ED_area_headerprint(CTX_wm_area(C), buf);
}
@@ -608,4 +627,7 @@ void MESH_OT_loopcut(wmOperatorType *ot)
prop = RNA_def_int(ot->srna, "number_cuts", 1, 1, INT_MAX, "Number of Cuts", "", 1, 10);
/* avoid re-using last var because it can cause _very_ high poly meshes and annoy users (or worse crash) */
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+
+ prop = RNA_def_float(ot->srna, "smoothness", 0.0f, 0.0f, FLT_MAX, "Smoothness", "Smoothness factor", 0.0f, 4.0f);
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
diff --git a/source/blender/editors/mesh/editmesh_rip.c b/source/blender/editors/mesh/editmesh_rip.c
index 6379bdbc0ca..d3a4c951e06 100644
--- a/source/blender/editors/mesh/editmesh_rip.c
+++ b/source/blender/editors/mesh/editmesh_rip.c
@@ -489,7 +489,7 @@ static void edbm_tagged_loop_pairs_do_fill_faces(BMesh *bm, UnorderedLoopPair *u
}
/* face should never exist */
- BLI_assert(BM_face_exists(bm, f_verts, f_verts[3] ? 4 : 3, &f) == FALSE);
+ BLI_assert(BM_face_exists(f_verts, f_verts[3] ? 4 : 3, &f) == FALSE);
f = BM_face_create_quad_tri_v(bm, f_verts, f_verts[3] ? 4 : 3, f_example, FALSE);
diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c
index 0bdb5032a30..453c29f004f 100644
--- a/source/blender/editors/mesh/editmesh_select.c
+++ b/source/blender/editors/mesh/editmesh_select.c
@@ -56,6 +56,7 @@
#include "ED_mesh.h"
#include "ED_screen.h"
+#include "ED_util.h"
#include "ED_uvedit.h"
#include "ED_object.h"
#include "ED_view3d.h"
@@ -69,6 +70,7 @@
#include "mesh_intern.h"
+#include "UI_resources.h"
/* ****************************** MIRROR **************** */
@@ -731,7 +733,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, "faceout", BM_ALL, BM_ELEM_SELECT, TRUE);
+ BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "faces.out", BM_ALL, BM_ELEM_SELECT, TRUE);
/* finish the operator */
if (!EDBM_op_finish(em, &bmop, op, TRUE)) {
@@ -772,7 +774,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, "edgeout", BM_ALL, BM_ELEM_SELECT, TRUE);
+ BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "edges.out", BM_ALL, BM_ELEM_SELECT, TRUE);
EDBM_selectmode_flush(em);
/* finish the operator */
@@ -816,7 +818,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, "vertout", BM_ALL, BM_ELEM_SELECT, TRUE);
+ BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "verts.out", BM_ALL, BM_ELEM_SELECT, TRUE);
/* finish the operator */
if (!EDBM_op_finish(em, &bmop, op, TRUE)) {
@@ -916,6 +918,74 @@ void MESH_OT_select_similar(wmOperatorType *ot)
RNA_def_float(ot->srna, "threshold", 0.0, 0.0, 1.0, "Threshold", "", 0.0, 1.0);
}
+
+/* **************** Mode Select *************** */
+
+static int edbm_select_mode_exec(bContext *C, wmOperator *op)
+{
+ const int type = RNA_enum_get(op->ptr, "type");
+ const int action = RNA_enum_get(op->ptr, "action");
+ const int use_extend = RNA_boolean_get(op->ptr, "use_extend");
+ const int use_expand = RNA_boolean_get(op->ptr, "use_expand");
+
+ if (EDBM_selectmode_toggle(C, type, action, use_extend, use_expand)) {
+ return OPERATOR_FINISHED;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
+}
+
+static int edbm_select_mode_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+ // RNA_enum_set(op->ptr, "type"); /* type must be set already */
+ RNA_boolean_set(op->ptr, "use_extend", event->shift);
+ RNA_boolean_set(op->ptr, "use_expand", event->ctrl);
+ return edbm_select_mode_exec(C, op);
+}
+
+void MESH_OT_select_mode(wmOperatorType *ot)
+{
+ PropertyRNA *prop;
+
+ static EnumPropertyItem elem_items[] = {
+ {SCE_SELECT_VERTEX, "VERT", ICON_VERTEXSEL, "Vertices", ""},
+ {SCE_SELECT_EDGE, "EDGE", ICON_EDGESEL, "Edges", ""},
+ {SCE_SELECT_FACE, "FACE", ICON_FACESEL, "Faces", ""},
+ {0, NULL, 0, NULL, NULL},
+ };
+
+ static EnumPropertyItem actions_items[] = {
+ {0, "DISABLE", 0, "Disable", "Disable selected markers"},
+ {1, "ENABLE", 0, "Enable", "Enable selected markers"},
+ {2, "TOGGLE", 0, "Toggle", "Toggle disabled flag for selected markers"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ /* identifiers */
+ ot->name = "Select Mode";
+ ot->idname = "MESH_OT_select_mode";
+ ot->description = "Change selection mode";
+
+ /* api callbacks */
+ ot->invoke = edbm_select_mode_invoke;
+ ot->exec = edbm_select_mode_exec;
+ ot->poll = ED_operator_editmesh;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ prop = RNA_def_boolean(ot->srna, "use_extend", FALSE, "Extend", "");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ prop = RNA_def_boolean(ot->srna, "use_expand", FALSE, "Expand", "");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ ot->prop = prop = RNA_def_enum(ot->srna, "type", elem_items, 0, "Type", "");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+
+ RNA_def_enum(ot->srna, "action", actions_items, 2, "Action", "Selection action to execute");
+}
+
/* ***************************************************** */
/* **************** LOOP SELECTS *************** */
@@ -1014,7 +1084,7 @@ void MESH_OT_loop_multi_select(wmOperatorType *ot)
/* ***************** loop select (non modal) ************** */
-static void mouse_mesh_loop(bContext *C, int mval[2], short extend, short ring)
+static void mouse_mesh_loop(bContext *C, int mval[2], short extend, short deselect, short toggle, short ring)
{
ViewContext vc;
BMEditMesh *em;
@@ -1033,14 +1103,20 @@ static void mouse_mesh_loop(bContext *C, int mval[2], short extend, short ring)
eed = EDBM_edge_find_nearest(&vc, &dist);
if (eed) {
- if (extend == 0) {
+ if (extend == 0 && deselect == 0 && toggle == 0) {
EDBM_flag_disable_all(em, BM_ELEM_SELECT);
}
- if (BM_elem_flag_test(eed, BM_ELEM_SELECT) == 0) {
+ if (extend) {
+ select = TRUE;
+ }
+ else if (deselect) {
+ select = FALSE;
+ }
+ else if (BM_elem_flag_test(eed, BM_ELEM_SELECT) == 0) {
select = TRUE;
}
- else if (extend) {
+ else if (toggle) {
select = FALSE;
}
@@ -1133,6 +1209,8 @@ static int edbm_select_loop_invoke(bContext *C, wmOperator *op, wmEvent *event)
view3d_operator_needs_opengl(C);
mouse_mesh_loop(C, event->mval, RNA_boolean_get(op->ptr, "extend"),
+ RNA_boolean_get(op->ptr, "deselect"),
+ RNA_boolean_get(op->ptr, "toggle"),
RNA_boolean_get(op->ptr, "ring"));
/* cannot do tweaks for as long this keymap is after transform map */
@@ -1155,6 +1233,8 @@ void MESH_OT_loop_select(wmOperatorType *ot)
/* properties */
RNA_def_boolean(ot->srna, "extend", 0, "Extend Select", "Extend the selection");
+ RNA_def_boolean(ot->srna, "deselect", 0, "Deselect", "Remove from the selection");
+ RNA_def_boolean(ot->srna, "toggle", 0, "Toggle Select", "Toggle the selection");
RNA_def_boolean(ot->srna, "ring", 0, "Select Ring", "Select ring");
}
@@ -1173,6 +1253,8 @@ void MESH_OT_edgering_select(wmOperatorType *ot)
ot->flag = OPTYPE_UNDO;
RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend the selection");
+ RNA_def_boolean(ot->srna, "deselect", 0, "Deselect", "Remove from the selection");
+ RNA_def_boolean(ot->srna, "toggle", 0, "Toggle Select", "Toggle the selection");
RNA_def_boolean(ot->srna, "ring", 1, "Select Ring", "Select ring");
}
@@ -1882,58 +1964,148 @@ void EDBM_selectmode_convert(BMEditMesh *em, short selectmode_old, short selectm
BMFace *efa;
BMIter iter;
+ /* first tag-to-select, then select --- this avoids a feedback loop */
+
/* have to find out what the selectionmode was previously */
if (selectmode_old == SCE_SELECT_VERTEX) {
if (selectmode_new == SCE_SELECT_EDGE) {
- /* select all edges associated with every selected vertex */
- eed = BM_iter_new(&iter, em->bm, BM_EDGES_OF_MESH, NULL);
- for (; eed; eed = BM_iter_step(&iter)) {
- if ((BM_elem_flag_test(eed->v1, BM_ELEM_SELECT) ||
- BM_elem_flag_test(eed->v2, BM_ELEM_SELECT)))
- {
+ /* select all edges associated with every selected vert */
+ BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
+ BM_elem_flag_set(eed, BM_ELEM_TAG, BM_edge_is_any_vert_flag_test(eed, BM_ELEM_SELECT));
+ }
+
+ BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
+ if (BM_elem_flag_test(eed, BM_ELEM_TAG)) {
BM_edge_select_set(em->bm, eed, TRUE);
}
}
}
else if (selectmode_new == SCE_SELECT_FACE) {
- BMIter liter;
- BMLoop *l;
-
- /* select all faces associated with every selected vertex */
- efa = BM_iter_new(&iter, em->bm, BM_FACES_OF_MESH, NULL);
- for (; efa; efa = BM_iter_step(&iter)) {
- l = BM_iter_new(&liter, em->bm, BM_LOOPS_OF_FACE, efa);
- for (; l; l = BM_iter_step(&liter)) {
- if (BM_elem_flag_test(l->v, BM_ELEM_SELECT)) {
- BM_face_select_set(em->bm, efa, TRUE);
- break;
- }
+ /* select all faces associated with every selected vert */
+ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+ BM_elem_flag_set(efa, BM_ELEM_TAG, BM_face_is_any_vert_flag_test(efa, BM_ELEM_SELECT));
+ }
+
+ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+ if (BM_elem_flag_test(efa, BM_ELEM_TAG)) {
+ BM_face_select_set(em->bm, efa, TRUE);
}
}
}
}
else if (selectmode_old == SCE_SELECT_EDGE) {
if (selectmode_new == SCE_SELECT_FACE) {
- BMIter liter;
- BMLoop *l;
-
- /* select all faces associated with every selected vertex */
- efa = BM_iter_new(&iter, em->bm, BM_FACES_OF_MESH, NULL);
- for (; efa; efa = BM_iter_step(&iter)) {
- l = BM_iter_new(&liter, em->bm, BM_LOOPS_OF_FACE, efa);
- for (; l; l = BM_iter_step(&liter)) {
- if (BM_elem_flag_test(l->v, BM_ELEM_SELECT)) {
- BM_face_select_set(em->bm, efa, TRUE);
- break;
- }
+ /* select all faces associated with every selected edge */
+ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+ BM_elem_flag_set(efa, BM_ELEM_TAG, BM_face_is_any_edge_flag_test(efa, BM_ELEM_SELECT));
+ }
+
+ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+ if (BM_elem_flag_test(efa, BM_ELEM_TAG)) {
+ BM_face_select_set(em->bm, efa, TRUE);
}
}
}
}
}
+/* user facing function, does notification and undo push */
+int EDBM_selectmode_toggle(bContext *C, const short selectmode_new,
+ const int action, const int use_extend, const int use_expand)
+{
+ ToolSettings *ts = CTX_data_tool_settings(C);
+ Object *obedit = CTX_data_edit_object(C);
+ BMEditMesh *em = NULL;
+ int ret = FALSE;
+
+ if (obedit && obedit->type == OB_MESH) {
+ em = BMEdit_FromObject(obedit);
+ }
+
+ if (em == NULL) {
+ return ret;
+ }
-void EDBM_deselect_by_material(BMEditMesh *em, short index, short select)
+ switch (action) {
+ case -1:
+ /* already set */
+ break;
+ case 0: /* disable */
+ /* check we have something to do */
+ if ((em->selectmode & selectmode_new) == 0) {
+ return FALSE;
+ }
+ em->selectmode &= ~selectmode_new;
+ break;
+ case 1: /* enable */
+ /* check we have something to do */
+ if ((em->selectmode & selectmode_new) != 0) {
+ return FALSE;
+ }
+ em->selectmode |= selectmode_new;
+ break;
+ case 2: /* toggle */
+ /* can't disable this flag if its the only one set */
+ if (em->selectmode == selectmode_new) {
+ return FALSE;
+ }
+ em->selectmode ^= selectmode_new;
+ break;
+ default:
+ BLI_assert(0);
+ }
+
+ switch (selectmode_new) {
+ case SCE_SELECT_VERTEX:
+ if (use_extend == 0 || em->selectmode == 0)
+ em->selectmode = SCE_SELECT_VERTEX;
+ ts->selectmode = em->selectmode;
+ EDBM_selectmode_set(em);
+ ret = TRUE;
+ break;
+ case SCE_SELECT_EDGE:
+ if (use_extend == 0 || em->selectmode == 0) {
+ if (use_expand) {
+ const short selmode_max = highest_order_bit_s(ts->selectmode);
+ if (selmode_max == SCE_SELECT_VERTEX) {
+ EDBM_selectmode_convert(em, selmode_max, SCE_SELECT_EDGE);
+ }
+ }
+ em->selectmode = SCE_SELECT_EDGE;
+ }
+ ts->selectmode = em->selectmode;
+ EDBM_selectmode_set(em);
+ ret = TRUE;
+ break;
+ case SCE_SELECT_FACE:
+ if (use_extend == 0 || em->selectmode == 0) {
+ if (use_expand) {
+ const short selmode_max = highest_order_bit_s(ts->selectmode);
+ if (ELEM(selmode_max, SCE_SELECT_VERTEX, SCE_SELECT_EDGE)) {
+ EDBM_selectmode_convert(em, selmode_max, SCE_SELECT_FACE);
+ }
+ }
+
+ em->selectmode = SCE_SELECT_FACE;
+ }
+ ts->selectmode = em->selectmode;
+ EDBM_selectmode_set(em);
+ ret = TRUE;
+ break;
+ default:
+ BLI_assert(0);
+ break;
+ }
+
+ if (ret == TRUE) {
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
+ WM_main_add_notifier(NC_SCENE | ND_TOOLSETTINGS, NULL);
+ }
+
+ return ret;
+}
+
+void EDBM_deselect_by_material(BMEditMesh *em, const short index, const short select)
{
BMIter iter;
BMFace *efa;
@@ -2079,6 +2251,8 @@ static int edbm_select_linked_pick_invoke(bContext *C, wmOperator *op, wmEvent *
return OPERATOR_CANCELLED;
if (limit) {
+ /* grr, shouldn't need to alloc BMO flags here */
+ BM_mesh_elem_toolflags_ensure(bm);
/* hflag no-seam --> bmo-tag */
BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
/* BMESH_TODO, don't use 'BM_ELEM_SELECT' here, its a HFLAG only! */
@@ -2171,6 +2345,8 @@ static int edbm_select_linked_exec(bContext *C, wmOperator *op)
}
if (limit) {
+ /* grr, shouldn't need to alloc BMO flags here */
+ BM_mesh_elem_toolflags_ensure(bm);
BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
/* BMESH_TODO, don't use 'BM_ELEM_SELECT' here, its a HFLAG only! */
BMO_elem_flag_set(bm, e, BM_ELEM_SELECT, !BM_elem_flag_test(e, BM_ELEM_SEAM));
@@ -2191,6 +2367,10 @@ static int edbm_select_linked_exec(bContext *C, wmOperator *op)
}
}
BMW_end(&walker);
+
+ if (limit) {
+ BM_mesh_elem_toolflags_clear(bm);
+ }
}
else {
BM_ITER_MESH (v, &iter, em->bm, BM_VERTS_OF_MESH) {
@@ -2336,6 +2516,9 @@ static void walker_deselect_nth(BMEditMesh *em, int nth, int offset, BMHeader *h
break;
}
+ /* grr, shouldn't need to alloc BMO flags here */
+ BM_mesh_elem_toolflags_ensure(bm);
+
/* Walker restrictions uses BMO flags, not header flags,
* so transfer BM_ELEM_SELECT from HFlags onto a BMO flag layer. */
BMO_push(bm, NULL);
diff --git a/source/blender/editors/mesh/editmesh_slide.c b/source/blender/editors/mesh/editmesh_slide.c
index 5d77dd88c91..e5889955fc7 100644
--- a/source/blender/editors/mesh/editmesh_slide.c
+++ b/source/blender/editors/mesh/editmesh_slide.c
@@ -741,10 +741,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, "edge", BM_ALL, BM_ELEM_SELECT, TRUE);
+ BMO_slot_buffer_hflag_disable(bm, bmop.slots_in, "edge", BM_ALL, BM_ELEM_SELECT, TRUE);
/* Select the output vert */
- BMO_slot_buffer_hflag_enable(bm, &bmop, "vertout", BM_ALL, BM_ELEM_SELECT, TRUE);
+ BMO_slot_buffer_hflag_enable(bm, bmop.slots_out, "verts.out", BM_ALL, BM_ELEM_SELECT, TRUE);
/* Flush the select buffers */
EDBM_selectmode_flush(em);
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index 0c5c756a0fc..9bc926598db 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -72,6 +72,7 @@
#include "RE_render_ext.h"
#include "UI_interface.h"
+#include "UI_resources.h"
#include "mesh_intern.h"
@@ -242,7 +243,7 @@ static short edbm_extrude_discrete_faces(BMEditMesh *em, wmOperator *op, const c
BMO_op_exec(em->bm, &bmop);
- BMO_ITER (f, &siter, em->bm, &bmop, "faceout", BM_FACE) {
+ BMO_ITER (f, &siter, bmop.slots_out, "faces.out", BM_FACE) {
BM_face_select_set(em->bm, f, TRUE);
/* set face vertex normals to face normal */
@@ -269,7 +270,7 @@ static short edbm_extrude_edges_indiv(BMEditMesh *em, wmOperator *op, const char
EDBM_flag_disable_all(em, BM_ELEM_SELECT);
BMO_op_exec(em->bm, &bmop);
- BMO_slot_buffer_hflag_enable(em->bm, &bmop, "geomout", BM_VERT | BM_EDGE, BM_ELEM_SELECT, TRUE);
+ BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "geom.out", BM_VERT | BM_EDGE, BM_ELEM_SELECT, TRUE);
if (!EDBM_op_finish(em, &bmop, op, TRUE)) {
return 0;
@@ -286,10 +287,10 @@ static short edbm_extrude_verts_indiv(BMEditMesh *em, wmOperator *op, const char
EDBM_op_init(em, &bmop, op, "extrude_vert_indiv verts=%hv", hflag);
/* deselect original verts */
- BMO_slot_buffer_hflag_disable(em->bm, &bmop, "verts", BM_VERT, BM_ELEM_SELECT, TRUE);
+ BMO_slot_buffer_hflag_disable(em->bm, bmop.slots_in, "verts", BM_VERT, BM_ELEM_SELECT, TRUE);
BMO_op_exec(em->bm, &bmop);
- BMO_slot_buffer_hflag_enable(em->bm, &bmop, "vertout", BM_VERT, BM_ELEM_SELECT, TRUE);
+ BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "verts.out", BM_VERT, BM_ELEM_SELECT, TRUE);
if (!EDBM_op_finish(em, &bmop, op, TRUE)) {
return 0;
@@ -308,9 +309,12 @@ static short edbm_extrude_edge(Object *obedit, BMEditMesh *em, const char hflag,
BMFace *f;
ModifierData *md;
BMElem *ele;
+ BMOpSlot *slot_edges_exclude;
BMO_op_init(bm, &extop, BMO_FLAG_DEFAULTS, "extrude_face_region");
- BMO_slot_buffer_from_enabled_hflag(bm, &extop, "edgefacein", BM_VERT | BM_EDGE | BM_FACE, hflag);
+ BMO_slot_buffer_from_enabled_hflag(bm, &extop, extop.slots_in, "geom", BM_VERT | BM_EDGE | BM_FACE, hflag);
+
+ slot_edges_exclude = BMO_slot_get(extop.slots_in, "edges_exclude");
/* If a mirror modifier with clipping is on, we need to adjust some
* of the cases above to handle edges on the line of symmetry.
@@ -350,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(bm, &extop, "exclude", edge, NULL);
+ BMO_slot_map_ptr_insert(&extop, slot_edges_exclude, edge, NULL);
}
}
if (mmd->flag & MOD_MIR_AXIS_Y) {
if ((fabsf(co1[1]) < mmd->tolerance) &&
(fabsf(co2[1]) < mmd->tolerance))
{
- BMO_slot_map_ptr_insert(bm, &extop, "exclude", edge, NULL);
+ BMO_slot_map_ptr_insert(&extop, slot_edges_exclude, edge, NULL);
}
}
if (mmd->flag & MOD_MIR_AXIS_Z) {
if ((fabsf(co1[2]) < mmd->tolerance) &&
(fabsf(co2[2]) < mmd->tolerance))
{
- BMO_slot_map_ptr_insert(bm, &extop, "exclude", edge, NULL);
+ BMO_slot_map_ptr_insert(&extop, slot_edges_exclude, edge, NULL);
}
}
}
@@ -379,7 +383,7 @@ static short edbm_extrude_edge(Object *obedit, BMEditMesh *em, const char hflag,
zero_v3(nor);
- BMO_ITER (ele, &siter, bm, &extop, "geomout", BM_ALL) {
+ BMO_ITER (ele, &siter, extop.slots_out, "geom.out", BM_ALL) {
BM_elem_select_set(bm, ele, TRUE);
if (ele->head.htype == BM_FACE) {
@@ -449,7 +453,7 @@ static int edbm_extrude_repeat_exec(bContext *C, wmOperator *op)
for (a = 0; a < steps; a++) {
edbm_extrude_edge(obedit, em, BM_ELEM_SELECT, nor);
- //BMO_op_callf(em->bm, BMO_FLAG_DEFAULTS, "extrude_face_region edgefacein=%hef", BM_ELEM_SELECT);
+ //BMO_op_callf(em->bm, BMO_FLAG_DEFAULTS, "extrude_face_region geom=%hef", BM_ELEM_SELECT);
BMO_op_callf(em->bm, BMO_FLAG_DEFAULTS,
"translate vec=%v verts=%hv",
(float *)dvec, BM_ELEM_SELECT);
@@ -915,7 +919,7 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, wmEvent
EDBM_op_init(vc.em, &bmop, op, "create_vert co=%v", min);
BMO_op_exec(vc.em->bm, &bmop);
- BMO_ITER (v1, &oiter, vc.em->bm, &bmop, "newvertout", BM_VERT) {
+ BMO_ITER (v1, &oiter, bmop.slots_out, "vert.out", BM_VERT) {
BM_vert_select_set(vc.em->bm, v1, TRUE);
}
@@ -1110,8 +1114,8 @@ static int edbm_add_edge_face_exec(bContext *C, wmOperator *op)
}
BMO_op_exec(em->bm, &bmop);
- BMO_slot_buffer_hflag_enable(em->bm, &bmop, "faceout", BM_FACE, BM_ELEM_SELECT, TRUE);
- BMO_slot_buffer_hflag_enable(em->bm, &bmop, "edgeout", BM_EDGE, BM_ELEM_SELECT, TRUE);
+ BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "faces.out", BM_FACE, BM_ELEM_SELECT, TRUE);
+ BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "edges.out", BM_EDGE, BM_ELEM_SELECT, TRUE);
if (!EDBM_op_finish(em, &bmop, op, TRUE)) {
return OPERATOR_CANCELLED;
@@ -1261,7 +1265,7 @@ static int edbm_vert_connect(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
BMO_op_exec(bm, &bmop);
- len = BMO_slot_get(&bmop, "edgeout")->len;
+ len = BMO_slot_get(bmop.slots_out, "edges.out")->len;
if (!EDBM_op_finish(em, &bmop, op, TRUE)) {
return OPERATOR_CANCELLED;
}
@@ -1301,7 +1305,7 @@ static int edbm_edge_split_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
BMO_op_exec(bm, &bmop);
- len = BMO_slot_get(&bmop, "edgeout")->len;
+ len = BMO_slot_get(bmop.slots_out, "edges.out")->len;
if (!EDBM_op_finish(em, &bmop, op, TRUE)) {
return OPERATOR_CANCELLED;
}
@@ -1339,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, "newout", BM_ALL, BM_ELEM_SELECT, TRUE);
+ BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "geom.out", BM_ALL, BM_ELEM_SELECT, TRUE);
if (!EDBM_op_finish(em, &bmop, op, TRUE)) {
return OPERATOR_CANCELLED;
@@ -1405,8 +1409,8 @@ void MESH_OT_flip_normals(wmOperatorType *ot)
}
static const EnumPropertyItem direction_items[] = {
- {DIRECTION_CW, "CW", 0, "Clockwise", ""},
- {DIRECTION_CCW, "CCW", 0, "Counter Clockwise", ""},
+ {FALSE, "CW", 0, "Clockwise", ""},
+ {TRUE, "CCW", 0, "Counter Clockwise", ""},
{0, NULL, 0, NULL, NULL}
};
@@ -1418,7 +1422,7 @@ static int edbm_edge_rotate_selected_exec(bContext *C, wmOperator *op)
BMOperator bmop;
BMEdge *eed;
BMIter iter;
- const int do_ccw = RNA_enum_get(op->ptr, "direction") == 1;
+ const int use_ccw = RNA_boolean_get(op->ptr, "use_ccw");
int tot = 0;
if (em->bm->totedgesel == 0) {
@@ -1448,17 +1452,17 @@ static int edbm_edge_rotate_selected_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_ERROR, "Could not find any selected edges that can be rotated");
return OPERATOR_CANCELLED;
}
-
- EDBM_op_init(em, &bmop, op, "rotate_edges edges=%he ccw=%b", BM_ELEM_TAG, do_ccw);
+
+ EDBM_op_init(em, &bmop, op, "rotate_edges edges=%he use_ccw=%b", BM_ELEM_TAG, use_ccw);
/* avoids leaving old verts selected which can be a problem running multiple times,
* since this means the edges become selected around the face which then attempt to rotate */
- BMO_slot_buffer_hflag_disable(em->bm, &bmop, "edges", BM_EDGE, BM_ELEM_SELECT, TRUE);
+ BMO_slot_buffer_hflag_disable(em->bm, bmop.slots_in, "edges", BM_EDGE, BM_ELEM_SELECT, TRUE);
BMO_op_exec(em->bm, &bmop);
/* edges may rotate into hidden vertices, if this does _not_ run we get an ilogical state */
- BMO_slot_buffer_hflag_disable(em->bm, &bmop, "edgeout", BM_EDGE, BM_ELEM_HIDDEN, TRUE);
- BMO_slot_buffer_hflag_enable(em->bm, &bmop, "edgeout", BM_EDGE, BM_ELEM_SELECT, TRUE);
+ BMO_slot_buffer_hflag_disable(em->bm, bmop.slots_out, "edges.out", BM_EDGE, BM_ELEM_HIDDEN, TRUE);
+ BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "edges.out", BM_EDGE, BM_ELEM_SELECT, TRUE);
EDBM_selectmode_flush(em);
if (!EDBM_op_finish(em, &bmop, op, TRUE)) {
@@ -1485,7 +1489,7 @@ void MESH_OT_edge_rotate(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* props */
- RNA_def_enum(ot->srna, "direction", direction_items, DIRECTION_CW, "Direction", "Direction to rotate edge around");
+ RNA_def_boolean(ot->srna, "use_ccw", FALSE, "Counter Clockwise", "");
}
@@ -1553,7 +1557,7 @@ static int edbm_normals_make_consistent_exec(bContext *C, wmOperator *op)
/* doflip has to do with bmesh_rationalize_normals, it's an internal
* thing */
- if (!EDBM_op_callf(em, op, "recalc_face_normals faces=%hf do_flip=%b", BM_ELEM_SELECT, TRUE))
+ if (!EDBM_op_callf(em, op, "recalc_face_normals faces=%hf use_flip=%b", BM_ELEM_SELECT, TRUE))
return OPERATOR_CANCELLED;
if (RNA_boolean_get(op->ptr, "inside"))
@@ -1590,7 +1594,7 @@ static int edbm_do_smooth_vertex_exec(bContext *C, wmOperator *op)
ModifierData *md;
int mirrx = FALSE, mirry = FALSE, mirrz = FALSE;
int i, repeat;
- float clipdist = 0.0f;
+ float clip_dist = 0.0f;
int xaxis = RNA_boolean_get(op->ptr, "xaxis");
int yaxis = RNA_boolean_get(op->ptr, "yaxis");
@@ -1616,7 +1620,7 @@ static int edbm_do_smooth_vertex_exec(bContext *C, wmOperator *op)
if (mmd->flag & MOD_MIR_AXIS_Z)
mirrz = TRUE;
- clipdist = mmd->tolerance;
+ clip_dist = mmd->tolerance;
}
}
}
@@ -1627,9 +1631,9 @@ static int edbm_do_smooth_vertex_exec(bContext *C, wmOperator *op)
for (i = 0; i < repeat; i++) {
if (!EDBM_op_callf(em, op,
- "smooth_vert verts=%hv mirror_clip_x=%b mirror_clip_y=%b mirror_clip_z=%b clipdist=%f "
+ "smooth_vert verts=%hv mirror_clip_x=%b mirror_clip_y=%b mirror_clip_z=%b clip_dist=%f "
"use_axis_x=%b use_axis_y=%b use_axis_z=%b",
- BM_ELEM_SELECT, mirrx, mirry, mirrz, clipdist, xaxis, yaxis, zaxis))
+ BM_ELEM_SELECT, mirrx, mirry, mirrz, clip_dist, xaxis, yaxis, zaxis))
{
return OPERATOR_CANCELLED;
}
@@ -1670,7 +1674,7 @@ static int edbm_do_smooth_laplacian_vertex_exec(bContext *C, wmOperator *op)
{
Object *obedit = CTX_data_edit_object(C);
BMEditMesh *em = BMEdit_FromObject(obedit);
- int usex = TRUE, usey = TRUE, usez = TRUE, volume_preservation = TRUE;
+ int usex = TRUE, usey = TRUE, usez = TRUE, preserve_volume = TRUE;
int i, repeat;
float lambda;
float lambda_border;
@@ -1698,14 +1702,14 @@ static int edbm_do_smooth_laplacian_vertex_exec(bContext *C, wmOperator *op)
usex = RNA_boolean_get(op->ptr, "use_x");
usey = RNA_boolean_get(op->ptr, "use_y");
usez = RNA_boolean_get(op->ptr, "use_z");
- volume_preservation = RNA_boolean_get(op->ptr, "volume_preservation");
+ preserve_volume = RNA_boolean_get(op->ptr, "preserve_volume");
if (!repeat)
repeat = 1;
for (i = 0; i < repeat; i++) {
if (!EDBM_op_callf(em, op,
- "smooth_laplacian_vert verts=%hv lambda=%f lambda_border=%f use_x=%b use_y=%b use_z=%b volume_preservation=%b",
- BM_ELEM_SELECT, lambda, lambda_border, usex, usey, usez, volume_preservation))
+ "smooth_laplacian_vert verts=%hv lambda=%f lambda_border=%f use_x=%b use_y=%b use_z=%b preserve_volume=%b",
+ BM_ELEM_SELECT, lambda, lambda_border, usex, usey, usez, preserve_volume))
{
return OPERATOR_CANCELLED;
}
@@ -1745,7 +1749,7 @@ void MESH_OT_vertices_smooth_laplacian(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "use_x", 1, "Smooth X Axis", "Smooth object along X axis");
RNA_def_boolean(ot->srna, "use_y", 1, "Smooth Y Axis", "Smooth object along Y axis");
RNA_def_boolean(ot->srna, "use_z", 1, "Smooth Z Axis", "Smooth object along Z axis");
- RNA_def_boolean(ot->srna, "volume_preservation", 1, "Preserve Volume", "Apply volume preservation after smooth");
+ RNA_def_boolean(ot->srna, "preserve_volume", 1, "Preserve Volume", "Apply volume preservation after smooth");
}
/********************** Smooth/Solid Operators *************************/
@@ -1828,10 +1832,10 @@ static int edbm_rotate_uvs_exec(bContext *C, wmOperator *op)
BMOperator bmop;
/* get the direction from RNA */
- int dir = RNA_enum_get(op->ptr, "direction");
+ const int use_ccw = RNA_boolean_get(op->ptr, "use_ccw");
/* initialize the bmop using EDBM api, which does various ui error reporting and other stuff */
- EDBM_op_init(em, &bmop, op, "rotate_uvs faces=%hf dir=%i", BM_ELEM_SELECT, dir);
+ EDBM_op_init(em, &bmop, op, "rotate_uvs faces=%hf use_ccw=%b", BM_ELEM_SELECT, use_ccw);
/* execute the operator */
BMO_op_exec(em->bm, &bmop);
@@ -1877,10 +1881,10 @@ static int edbm_rotate_colors_exec(bContext *C, wmOperator *op)
BMOperator bmop;
/* get the direction from RNA */
- int dir = RNA_enum_get(op->ptr, "direction");
+ const int use_ccw = RNA_boolean_get(op->ptr, "use_ccw");
/* initialize the bmop using EDBM api, which does various ui error reporting and other stuff */
- EDBM_op_init(em, &bmop, op, "rotate_colors faces=%hf dir=%i", BM_ELEM_SELECT, dir);
+ EDBM_op_init(em, &bmop, op, "rotate_colors faces=%hf use_ccw=%b", BM_ELEM_SELECT, use_ccw);
/* execute the operator */
BMO_op_exec(em->bm, &bmop);
@@ -1936,7 +1940,7 @@ void MESH_OT_uvs_rotate(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* props */
- RNA_def_enum(ot->srna, "direction", direction_items, DIRECTION_CW, "Direction", "Direction to rotate UVs around");
+ RNA_def_boolean(ot->srna, "use_ccw", FALSE, "Counter Clockwise", "");
}
//void MESH_OT_uvs_mirror(wmOperatorType *ot)
@@ -1973,7 +1977,7 @@ void MESH_OT_colors_rotate(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* props */
- RNA_def_enum(ot->srna, "direction", direction_items, DIRECTION_CCW, "Direction", "Direction to rotate edge around");
+ RNA_def_boolean(ot->srna, "use_ccw", FALSE, "Counter Clockwise", "");
}
void MESH_OT_colors_reverse(wmOperatorType *ot)
@@ -2174,7 +2178,7 @@ void MESH_OT_merge(wmOperatorType *ot)
/* properties */
ot->prop = RNA_def_enum(ot->srna, "type", merge_type_items, 3, "Type", "Merge method to use");
RNA_def_enum_funcs(ot->prop, merge_type_itemf);
- RNA_def_boolean(ot->srna, "uvs", 1, "UVs", "Move UVs according to merge");
+ RNA_def_boolean(ot->srna, "uvs", 0, "UVs", "Move UVs according to merge");
}
@@ -2183,7 +2187,7 @@ static int edbm_remove_doubles_exec(bContext *C, wmOperator *op)
Object *obedit = CTX_data_edit_object(C);
BMEditMesh *em = BMEdit_FromObject(obedit);
BMOperator bmop;
- const float mergedist = RNA_float_get(op->ptr, "mergedist");
+ const float threshold = RNA_float_get(op->ptr, "threshold");
int use_unselected = RNA_boolean_get(op->ptr, "use_unselected");
int totvert_orig = em->bm->totvert;
int count;
@@ -2191,7 +2195,7 @@ static int edbm_remove_doubles_exec(bContext *C, wmOperator *op)
if (use_unselected) {
EDBM_op_init(em, &bmop, op,
"automerge verts=%hv dist=%f",
- BM_ELEM_SELECT, mergedist);
+ BM_ELEM_SELECT, threshold);
BMO_op_exec(em->bm, &bmop);
if (!EDBM_op_finish(em, &bmop, op, TRUE)) {
@@ -2201,10 +2205,10 @@ static int edbm_remove_doubles_exec(bContext *C, wmOperator *op)
else {
EDBM_op_init(em, &bmop, op,
"find_doubles verts=%hv dist=%f",
- BM_ELEM_SELECT, mergedist);
+ BM_ELEM_SELECT, threshold);
BMO_op_exec(em->bm, &bmop);
- if (!EDBM_op_callf(em, op, "weld_verts targetmap=%s", &bmop, "targetmapout")) {
+ if (!EDBM_op_callf(em, op, "weld_verts targetmap=%S", &bmop, "targetmap.out")) {
BMO_op_finish(em->bm, &bmop);
return OPERATOR_CANCELLED;
}
@@ -2236,8 +2240,7 @@ void MESH_OT_remove_doubles(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- RNA_def_float(ot->srna, "mergedist", 0.0001f, 0.000001f, 50.0f,
- "Merge Distance",
+ RNA_def_float(ot->srna, "threshold", 0.0001f, 0.000001f, 50.0f, "Merge Distance",
"Minimum distance between elements to merge", 0.00001, 10.0);
RNA_def_boolean(ot->srna, "use_unselected", 0, "Unselected", "Merge selected to other unselected vertices");
}
@@ -2314,7 +2317,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, "vertout", BM_ALL, BM_ELEM_SELECT, TRUE);
+ BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "verts.out", BM_ALL, BM_ELEM_SELECT, TRUE);
/* finish the operator */
if (!EDBM_op_finish(em, &bmop, op, TRUE)) {
@@ -2439,7 +2442,7 @@ static int edbm_blend_from_shape_exec(bContext *C, wmOperator *op)
totshape = CustomData_number_of_layers(&em->bm->vdata, CD_SHAPEKEY);
if (totshape == 0 || shape < 0 || shape >= totshape)
return OPERATOR_CANCELLED;
-
+
/* get shape key - needed for finding reference shape (for add mode only) */
if (key) {
kb = BLI_findlink(&key->block, shape);
@@ -2506,6 +2509,22 @@ static EnumPropertyItem *shape_itemf(bContext *C, PointerRNA *UNUSED(ptr), Prop
return item;
}
+static void edbm_blend_from_shape_ui(bContext *C, wmOperator *op)
+{
+ uiLayout *layout = op->layout;
+ PointerRNA ptr;
+ Object *obedit = CTX_data_edit_object(C);
+ Mesh *me = obedit->data;
+ PointerRNA ptr_key;
+
+ RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr);
+ RNA_id_pointer_create((ID *)me->key, &ptr_key);
+
+ uiItemPointerR(layout, &ptr, "shape", &ptr_key, "key_blocks", "", ICON_SHAPEKEY_DATA);
+ uiItemR(layout, &ptr, "blend", 0, NULL, ICON_NONE);
+ uiItemR(layout, &ptr, "add", 0, NULL, ICON_NONE);
+}
+
void MESH_OT_blend_from_shape(wmOperatorType *ot)
{
PropertyRNA *prop;
@@ -2518,7 +2537,8 @@ void MESH_OT_blend_from_shape(wmOperatorType *ot)
/* api callbacks */
ot->exec = edbm_blend_from_shape_exec;
- ot->invoke = WM_operator_props_popup;
+// ot->invoke = WM_operator_props_popup_call; /* disable because search popup closes too easily */
+ ot->ui = edbm_blend_from_shape_ui;
ot->poll = ED_operator_editmesh;
/* flags */
@@ -2631,13 +2651,13 @@ static int edbm_solidify_exec(bContext *C, wmOperator *op)
/* deselect only the faces in the region to be solidified (leave wire
* edges and loose verts selected, as there will be no corresponding
* geometry selected below) */
- BMO_slot_buffer_hflag_disable(bm, &bmop, "geom", BM_FACE, BM_ELEM_SELECT, TRUE);
+ BMO_slot_buffer_hflag_disable(bm, bmop.slots_in, "geom", BM_FACE, BM_ELEM_SELECT, TRUE);
/* run the solidify operator */
BMO_op_exec(bm, &bmop);
/* select the newly generated faces */
- BMO_slot_buffer_hflag_enable(bm, &bmop, "geomout", BM_FACE, BM_ELEM_SELECT, TRUE);
+ BMO_slot_buffer_hflag_enable(bm, bmop.slots_out, "geom.out", BM_FACE, BM_ELEM_SELECT, TRUE);
if (!EDBM_op_finish(em, &bmop, op, TRUE)) {
return OPERATOR_CANCELLED;
@@ -2869,6 +2889,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;
/* allocd vars */
float (*screen_vert_coords)[2], (*sco)[2], (*mouse_path)[2];
@@ -2923,6 +2944,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");
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)) {
@@ -2935,9 +2957,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(bm, &bmop,
- "edgepercents",
- be, isect);
+ BMO_slot_map_float_insert(&bmop, slot_edgepercents, be, isect);
}
}
}
@@ -2952,16 +2972,16 @@ static int edbm_knife_cut_exec(bContext *C, wmOperator *op)
MEM_freeN(mouse_path);
- BMO_slot_buffer_from_enabled_flag(bm, &bmop, "edges", BM_EDGE, ELE_EDGE_CUT);
+ BMO_slot_buffer_from_enabled_flag(bm, &bmop, bmop.slots_in, "edges", BM_EDGE, ELE_EDGE_CUT);
if (mode == KNIFE_MIDPOINT) numcuts = 1;
- BMO_slot_int_set(&bmop, "numcuts", numcuts);
+ BMO_slot_int_set(bmop.slots_in, "cuts", numcuts);
- BMO_slot_int_set(&bmop, "quadcornertype", SUBD_STRAIGHT_CUT);
- BMO_slot_bool_set(&bmop, "use_singleedge", FALSE);
- BMO_slot_bool_set(&bmop, "use_gridfill", FALSE);
+ 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_float_set(&bmop, "radius", 0);
+ BMO_slot_float_set(bmop.slots_in, "radius", 0);
BMO_op_exec(bm, &bmop);
if (!EDBM_op_finish(em, &bmop, op, TRUE)) {
@@ -3007,6 +3027,8 @@ static int mesh_separate_tagged(Main *bmain, Scene *scene, Base *base_old, BMesh
BMesh *bm_new;
bm_new = BM_mesh_create(&bm_mesh_allocsize_default);
+ BM_mesh_elem_toolflags_ensure(bm_new); /* needed for 'duplicate' bmo */
+
CustomData_copy(&bm_old->vdata, &bm_new->vdata, CD_MASK_BMESH, CD_CALLOC, 0);
CustomData_copy(&bm_old->edata, &bm_new->edata, CD_MASK_BMESH, CD_CALLOC, 0);
CustomData_copy(&bm_old->ldata, &bm_new->ldata, CD_MASK_BMESH, CD_CALLOC, 0);
@@ -3302,7 +3324,7 @@ static int edbm_fill_exec(bContext *C, wmOperator *op)
BMO_op_exec(em->bm, &bmop);
/* select new geometry */
- BMO_slot_buffer_hflag_enable(em->bm, &bmop, "geomout", BM_FACE | BM_EDGE, BM_ELEM_SELECT, TRUE);
+ BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "geom.out", BM_FACE | BM_EDGE, BM_ELEM_SELECT, TRUE);
if (!EDBM_op_finish(em, &bmop, op, TRUE)) {
return OPERATOR_CANCELLED;
@@ -3574,7 +3596,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, "geomout", BM_ALL, BM_ELEM_SELECT, TRUE);
+ BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "geom.out", BM_ALL, BM_ELEM_SELECT, TRUE);
if (!EDBM_op_finish(em, &bmop, op, TRUE)) {
return OPERATOR_CANCELLED;
}
@@ -3629,14 +3651,14 @@ static int edbm_spin_exec(bContext *C, wmOperator *op)
mul_m3_v3(imat, axis);
if (!EDBM_op_init(em, &spinop, op,
- "spin geom=%hvef cent=%v axis=%v dvec=%v steps=%i ang=%f do_dupli=%b",
+ "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))
{
return OPERATOR_CANCELLED;
}
BMO_op_exec(bm, &spinop);
EDBM_flag_disable_all(em, BM_ELEM_SELECT);
- BMO_slot_buffer_hflag_enable(bm, &spinop, "lastout", BM_ALL, BM_ELEM_SELECT, TRUE);
+ BMO_slot_buffer_hflag_enable(bm, spinop.slots_out, "geom_last.out", BM_ALL, BM_ELEM_SELECT, TRUE);
if (!EDBM_op_finish(em, &spinop, op, TRUE)) {
return OPERATOR_CANCELLED;
}
@@ -3753,14 +3775,14 @@ static int edbm_screw_exec(bContext *C, wmOperator *op)
negate_v3(dvec);
if (!EDBM_op_init(em, &spinop, op,
- "spin geom=%hvef cent=%v axis=%v dvec=%v steps=%i ang=%f do_dupli=%b",
+ "spin geom=%hvef cent=%v axis=%v dvec=%v steps=%i angle=%f use_duplicate=%b",
BM_ELEM_SELECT, cent, axis, dvec, turns * steps, 360.0f * turns, FALSE))
{
return OPERATOR_CANCELLED;
}
BMO_op_exec(bm, &spinop);
EDBM_flag_disable_all(em, BM_ELEM_SELECT);
- BMO_slot_buffer_hflag_enable(bm, &spinop, "lastout", BM_ALL, BM_ELEM_SELECT, TRUE);
+ BMO_slot_buffer_hflag_enable(bm, spinop.slots_out, "geom_last.out", BM_ALL, BM_ELEM_SELECT, TRUE);
if (!EDBM_op_finish(em, &spinop, op, TRUE)) {
return OPERATOR_CANCELLED;
}
@@ -4756,11 +4778,20 @@ static int edbm_bevel_calc(bContext *C, wmOperator *op)
if (!EDBM_op_init(em, &bmop, op,
"bevel geom=%hev offset=%f segments=%i",
BM_ELEM_SELECT, offset, segments))
- {
- return 0;
- }
-
+ {
+ return 0;
+ }
+
BMO_op_exec(em->bm, &bmop);
+
+ if (offset != 0.0f) {
+ /* not essential, but we may have some loose geometry that
+ * won't get bevel'd and better not leave it selected */
+ EDBM_flag_disable_all(em, BM_ELEM_SELECT);
+ BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "faces.out", BM_FACE, BM_ELEM_SELECT, TRUE);
+ }
+
+ /* no need to de-select existing geometry */
if (!EDBM_op_finish(em, &bmop, op, TRUE))
return 0;
#else
@@ -5094,7 +5125,7 @@ static int edbm_bridge_edge_loops_exec(bContext *C, wmOperator *op)
/* when merge is used the edges are joined and remain selected */
if (use_merge == FALSE) {
EDBM_flag_disable_all(em, BM_ELEM_SELECT);
- BMO_slot_buffer_hflag_enable(em->bm, &bmop, "faceout", BM_FACE, BM_ELEM_SELECT, TRUE);
+ BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "faces.out", BM_FACE, BM_ELEM_SELECT, TRUE);
}
if (!EDBM_op_finish(em, &bmop, op, TRUE)) {
@@ -5267,11 +5298,11 @@ static int edbm_inset_calc(bContext *C, wmOperator *op)
if (use_select_inset) {
/* deselect original faces/verts */
EDBM_flag_disable_all(em, BM_ELEM_SELECT);
- BMO_slot_buffer_hflag_enable(em->bm, &bmop, "faceout", BM_FACE, BM_ELEM_SELECT, TRUE);
+ BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "faces.out", BM_FACE, BM_ELEM_SELECT, TRUE);
}
else {
BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT | BM_EDGE, BM_ELEM_SELECT, FALSE);
- BMO_slot_buffer_hflag_disable(em->bm, &bmop, "faceout", BM_FACE, BM_ELEM_SELECT, FALSE);
+ BMO_slot_buffer_hflag_disable(em->bm, bmop.slots_out, "faces.out", BM_FACE, BM_ELEM_SELECT, FALSE);
/* re-select faces so the verts and edges get selected too */
BM_mesh_elem_hflag_enable_test(em->bm, BM_FACE, BM_ELEM_SELECT, TRUE, BM_ELEM_SELECT);
}
@@ -5528,7 +5559,7 @@ static int edbm_wireframe_exec(bContext *C, wmOperator *op)
if (use_replace) {
BM_mesh_elem_hflag_disable_all(em->bm, BM_FACE, BM_ELEM_TAG, FALSE);
- BMO_slot_buffer_hflag_enable(em->bm, &bmop, "faces", BM_FACE, BM_ELEM_TAG, FALSE);
+ BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_in, "faces", BM_FACE, BM_ELEM_TAG, FALSE);
BMO_op_callf(em->bm, BMO_FLAG_DEFAULTS,
"delete geom=%hvef context=%i",
@@ -5536,7 +5567,7 @@ static int edbm_wireframe_exec(bContext *C, wmOperator *op)
}
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, "faceout", BM_FACE, BM_ELEM_SELECT, TRUE);
+ BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "faces.out", BM_FACE, BM_ELEM_SELECT, TRUE);
if (!EDBM_op_finish(em, &bmop, op, TRUE)) {
return OPERATOR_CANCELLED;
@@ -5599,8 +5630,8 @@ static int edbm_convex_hull_exec(bContext *C, wmOperator *op)
/* Delete unused vertices, edges, and faces */
if (RNA_boolean_get(op->ptr, "delete_unused")) {
- if (!EDBM_op_callf(em, op, "delete geom=%s context=%i",
- &bmop, "unused_geom", DEL_ONLYTAGGED))
+ if (!EDBM_op_callf(em, op, "delete geom=%S context=%i",
+ &bmop, "geom_unused.out", DEL_ONLYTAGGED))
{
EDBM_op_finish(em, &bmop, op, TRUE);
return OPERATOR_CANCELLED;
@@ -5609,8 +5640,8 @@ static int edbm_convex_hull_exec(bContext *C, wmOperator *op)
/* Delete hole edges/faces */
if (RNA_boolean_get(op->ptr, "make_holes")) {
- if (!EDBM_op_callf(em, op, "delete geom=%s context=%i",
- &bmop, "holes_geom", DEL_ONLYTAGGED))
+ if (!EDBM_op_callf(em, op, "delete geom=%S context=%i",
+ &bmop, "geom_holes.out", DEL_ONLYTAGGED))
{
EDBM_op_finish(em, &bmop, op, TRUE);
return OPERATOR_CANCELLED;
@@ -5619,8 +5650,8 @@ static int edbm_convex_hull_exec(bContext *C, wmOperator *op)
/* Merge adjacent triangles */
if (RNA_boolean_get(op->ptr, "join_triangles")) {
- if (!EDBM_op_callf(em, op, "join_triangles faces=%s limit=%f",
- &bmop, "geomout",
+ if (!EDBM_op_callf(em, op, "join_triangles faces=%S limit=%f",
+ &bmop, "geom.out",
RNA_float_get(op->ptr, "limit")))
{
EDBM_op_finish(em, &bmop, op, TRUE);
diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c
index ef3d8db4156..22c71d5d3ca 100644
--- a/source/blender/editors/mesh/editmesh_utils.c
+++ b/source/blender/editors/mesh/editmesh_utils.c
@@ -263,7 +263,7 @@ int EDBM_op_callf(BMEditMesh *em, wmOperator *op, const char *fmt, ...)
return EDBM_op_finish(em, &bmop, op, TRUE);
}
-int EDBM_op_call_and_selectf(BMEditMesh *em, wmOperator *op, const char *selectslot, const char *fmt, ...)
+int EDBM_op_call_and_selectf(BMEditMesh *em, wmOperator *op, const char *select_slot_out, const char *fmt, ...)
{
BMesh *bm = em->bm;
BMOperator bmop;
@@ -285,7 +285,7 @@ int EDBM_op_call_and_selectf(BMEditMesh *em, wmOperator *op, const char *selects
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, selectslot, BM_ALL, BM_ELEM_SELECT, TRUE);
+ BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, select_slot_out, BM_ALL, BM_ELEM_SELECT, TRUE);
va_end(list);
return EDBM_op_finish(em, &bmop, op, TRUE);
@@ -494,11 +494,11 @@ void EDBM_select_more(BMEditMesh *em)
int use_faces = em->selectmode == SCE_SELECT_FACE;
BMO_op_initf(em->bm, &bmop, BMO_FLAG_DEFAULTS,
- "region_extend geom=%hvef constrict=%b use_faces=%b",
+ "region_extend geom=%hvef use_constrict=%b use_faces=%b",
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, "geomout", BM_ALL, BM_ELEM_SELECT, use_faces ? TRUE : FALSE);
+ BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "geom.out", BM_ALL, BM_ELEM_SELECT, use_faces ? TRUE : FALSE);
BMO_op_finish(em->bm, &bmop);
EDBM_select_flush(em);
@@ -510,11 +510,11 @@ void EDBM_select_less(BMEditMesh *em)
int use_faces = em->selectmode == SCE_SELECT_FACE;
BMO_op_initf(em->bm, &bmop, BMO_FLAG_DEFAULTS,
- "region_extend geom=%hvef constrict=%b use_faces=%b",
+ "region_extend geom=%hvef use_constrict=%b use_faces=%b",
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, "geomout", BM_ALL, BM_ELEM_SELECT, use_faces ? TRUE : FALSE);
+ BMO_slot_buffer_hflag_disable(em->bm, bmop.slots_out, "geom.out", BM_ALL, 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_intern.h b/source/blender/editors/mesh/mesh_intern.h
index 82b785e5785..8e63bd74ece 100644
--- a/source/blender/editors/mesh/mesh_intern.h
+++ b/source/blender/editors/mesh/mesh_intern.h
@@ -129,6 +129,7 @@ void MESH_OT_faces_select_linked_flat(struct wmOperatorType *ot);
void MESH_OT_edges_select_sharp(struct wmOperatorType *ot);
void MESH_OT_select_shortest_path(struct wmOperatorType *ot);
void MESH_OT_select_similar(struct wmOperatorType *ot);
+void MESH_OT_select_mode(struct wmOperatorType *ot);
void MESH_OT_select_random(struct wmOperatorType *ot);
void MESH_OT_loop_multi_select(struct wmOperatorType *ot);
void MESH_OT_mark_seam(struct wmOperatorType *ot);
diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c
index d319fdcca26..a413a60412c 100644
--- a/source/blender/editors/mesh/mesh_ops.c
+++ b/source/blender/editors/mesh/mesh_ops.c
@@ -129,6 +129,7 @@ void ED_operatortypes_mesh(void)
WM_operatortype_append(MESH_OT_edge_face_add);
WM_operatortype_append(MESH_OT_select_shortest_path);
WM_operatortype_append(MESH_OT_select_similar);
+ WM_operatortype_append(MESH_OT_select_mode);
WM_operatortype_append(MESH_OT_loop_multi_select);
WM_operatortype_append(MESH_OT_mark_seam);
WM_operatortype_append(MESH_OT_mark_sharp);
@@ -277,13 +278,21 @@ void ED_keymap_mesh(wmKeyConfig *keyconf)
/* standard mouse selection goes via space_view3d */
kmi = WM_keymap_add_item(keymap, "MESH_OT_loop_select", SELECTMOUSE, KM_PRESS, KM_ALT, 0);
RNA_boolean_set(kmi->ptr, "extend", FALSE);
+ RNA_boolean_set(kmi->ptr, "deselect", FALSE);
+ RNA_boolean_set(kmi->ptr, "toggle", FALSE);
kmi = WM_keymap_add_item(keymap, "MESH_OT_loop_select", SELECTMOUSE, KM_PRESS, KM_SHIFT | KM_ALT, 0);
- RNA_boolean_set(kmi->ptr, "extend", TRUE);
+ RNA_boolean_set(kmi->ptr, "extend", FALSE);
+ RNA_boolean_set(kmi->ptr, "deselect", FALSE);
+ RNA_boolean_set(kmi->ptr, "toggle", TRUE);
kmi = WM_keymap_add_item(keymap, "MESH_OT_edgering_select", SELECTMOUSE, KM_PRESS, KM_ALT | KM_CTRL, 0);
RNA_boolean_set(kmi->ptr, "extend", FALSE);
+ RNA_boolean_set(kmi->ptr, "deselect", FALSE);
+ RNA_boolean_set(kmi->ptr, "toggle", FALSE);
kmi = WM_keymap_add_item(keymap, "MESH_OT_edgering_select", SELECTMOUSE, KM_PRESS, KM_SHIFT | KM_ALT | KM_CTRL, 0);
- RNA_boolean_set(kmi->ptr, "extend", TRUE);
+ RNA_boolean_set(kmi->ptr, "extend", FALSE);
+ RNA_boolean_set(kmi->ptr, "deselect", FALSE);
+ RNA_boolean_set(kmi->ptr, "toggle", TRUE);
WM_keymap_add_item(keymap, "MESH_OT_select_shortest_path", SELECTMOUSE, KM_PRESS, KM_CTRL, 0);
diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c
index ee3c66b6eac..e144c38a350 100644
--- a/source/blender/editors/object/object_bake.c
+++ b/source/blender/editors/object/object_bake.c
@@ -114,7 +114,7 @@ typedef struct {
} MultiresBakeRender;
typedef void (*MPassKnownData)(DerivedMesh *lores_dm, DerivedMesh *hires_dm, const void *bake_data,
- const int face_index, const int lvl, const float st[2],
+ ImBuf *ibuf, const int face_index, const int lvl, const float st[2],
float tangmat[3][3], const int x, const int y);
typedef void * (*MInitBakeData)(MultiresBakeRender *bkr, Image *ima);
@@ -133,6 +133,7 @@ typedef struct {
DerivedMesh *lores_dm, *hires_dm;
int lvl;
void *bake_data;
+ ImBuf *ibuf;
MPassKnownData pass_data;
} MResolvePixelData;
@@ -257,7 +258,7 @@ static void flush_pixel(const MResolvePixelData *data, const int x, const int y)
/* sequence end */
data->pass_data(data->lores_dm, data->hires_dm, data->bake_data,
- data->face_index, data->lvl, st, to_tang, x, y);
+ data->ibuf, data->face_index, data->lvl, st, to_tang, x, y);
}
static void set_rast_triangle(const MBakeRast *bake_rast, const int x, const int y)
@@ -368,7 +369,7 @@ static void do_multires_bake(MultiresBakeRender *bkr, Image *ima, MPassKnownData
MInitBakeData initBakeData, MApplyBakeData applyBakeData, MFreeBakeData freeBakeData)
{
DerivedMesh *dm = bkr->lores_dm;
- ImBuf *ibuf = BKE_image_get_ibuf(ima, NULL);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
const int lvl = bkr->lvl;
const int tot_face = dm->getNumTessFaces(dm);
MVert *mvert = dm->getVertArray(dm);
@@ -414,6 +415,7 @@ static void do_multires_bake(MultiresBakeRender *bkr, Image *ima, MPassKnownData
continue;
data.face_index = f;
+ data.ibuf = ibuf;
/* might support other forms of diagonal splits later on such as
* split by shortest diagonal.*/
@@ -449,32 +451,8 @@ static void do_multires_bake(MultiresBakeRender *bkr, Image *ima, MPassKnownData
if (freeBakeData)
freeBakeData(data.bake_data);
}
-}
-
-static void interp_bilinear_quad_data(float data[4][3], float u, float v, float res[3])
-{
- float vec[3];
-
- copy_v3_v3(res, data[0]);
- mul_v3_fl(res, (1 - u) * (1 - v));
- copy_v3_v3(vec, data[1]);
- mul_v3_fl(vec, u * (1 - v)); add_v3_v3(res, vec);
- copy_v3_v3(vec, data[2]);
- mul_v3_fl(vec, u * v); add_v3_v3(res, vec);
- copy_v3_v3(vec, data[3]);
- mul_v3_fl(vec, (1 - u) * v); add_v3_v3(res, vec);
-}
-static void interp_barycentric_tri_data(float data[3][3], float u, float v, float res[3])
-{
- float vec[3];
-
- copy_v3_v3(res, data[0]);
- mul_v3_fl(res, u);
- copy_v3_v3(vec, data[1]);
- mul_v3_fl(vec, v); add_v3_v3(res, vec);
- copy_v3_v3(vec, data[2]);
- mul_v3_fl(vec, 1.0f - u - v); add_v3_v3(res, vec);
+ BKE_image_release_ibuf(ima, ibuf, NULL);
}
/* mode = 0: interpolate normals,
@@ -507,7 +485,7 @@ static void interp_bilinear_grid(CCGKey *key, CCGElem *grid, float crn_x, float
copy_v3_v3(data[3], CCG_grid_elem_co(key, grid, x0, y1));
}
- interp_bilinear_quad_data(data, u, v, res);
+ interp_bilinear_quad_v3(data, u, v, res);
}
static void get_ccgdm_data(DerivedMesh *lodm, DerivedMesh *hidm,
@@ -579,7 +557,7 @@ static void interp_bilinear_mface(DerivedMesh *dm, MFace *mface, const float u,
dm->getVertCo(dm, mface->v4, data[3]);
}
- interp_bilinear_quad_data(data, u, v, res);
+ interp_bilinear_quad_v3(data, u, v, res);
}
/* mode = 0: interpolate normals,
@@ -599,13 +577,13 @@ static void interp_barycentric_mface(DerivedMesh *dm, MFace *mface, const float
dm->getVertCo(dm, mface->v3, data[2]);
}
- interp_barycentric_tri_data(data, u, v, res);
+ interp_barycentric_tri_v3(data, u, v, res);
}
static void *init_heights_data(MultiresBakeRender *bkr, Image *ima)
{
MHeightBakeData *height_data;
- ImBuf *ibuf = BKE_image_get_ibuf(ima, NULL);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
DerivedMesh *lodm = bkr->lores_dm;
height_data = MEM_callocN(sizeof(MHeightBakeData), "MultiresBake heightData");
@@ -635,6 +613,8 @@ static void *init_heights_data(MultiresBakeRender *bkr, Image *ima)
height_data->orig_index_mf_to_mpoly = lodm->getTessFaceDataArray(lodm, CD_ORIGINDEX);
height_data->orig_index_mp_to_orig = lodm->getPolyDataArray(lodm, CD_ORIGINDEX);
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+
return (void *)height_data;
}
@@ -661,7 +641,7 @@ static void free_normal_data(void *bake_data)
static void apply_heights_data(void *bake_data)
{
MHeightBakeData *height_data = (MHeightBakeData *)bake_data;
- ImBuf *ibuf = BKE_image_get_ibuf(height_data->ima, NULL);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(height_data->ima, NULL, NULL);
int x, y, i;
float height, *heights = height_data->heights;
float min = height_data->height_min, max = height_data->height_max;
@@ -693,6 +673,8 @@ static void apply_heights_data(void *bake_data)
}
ibuf->userflags = IB_RECT_INVALID | IB_DISPLAY_BUFFER_INVALID;
+
+ BKE_image_release_ibuf(height_data->ima, ibuf, NULL);
}
static void free_heights_data(void *bake_data)
@@ -713,13 +695,11 @@ static void free_heights_data(void *bake_data)
* mesh to make texture smoother) let's call this point p0 and n.
* - height wound be dot(n, p1-p0) */
static void apply_heights_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, const void *bake_data,
- const int face_index, const int lvl, const float st[2],
+ ImBuf *ibuf, const int face_index, const int lvl, const float st[2],
float UNUSED(tangmat[3][3]), const int x, const int y)
{
MTFace *mtface = CustomData_get_layer(&lores_dm->faceData, CD_MTFACE);
MFace mface;
- Image *ima = mtface[face_index].tpage;
- ImBuf *ibuf = BKE_image_get_ibuf(ima, NULL);
MHeightBakeData *height_data = (MHeightBakeData *)bake_data;
float uv[2], *st0, *st1, *st2, *st3;
int pixel = ibuf->x * y + x;
@@ -790,13 +770,11 @@ static void apply_heights_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm,
* - multiply it by tangmat
* - vector in color space would be norm(vec) /2 + (0.5, 0.5, 0.5) */
static void apply_tangmat_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, const void *bake_data,
- const int face_index, const int lvl, const float st[2],
+ ImBuf *ibuf, const int face_index, const int lvl, const float st[2],
float tangmat[3][3], const int x, const int y)
{
MTFace *mtface = CustomData_get_layer(&lores_dm->faceData, CD_MTFACE);
MFace mface;
- Image *ima = mtface[face_index].tpage;
- ImBuf *ibuf = BKE_image_get_ibuf(ima, NULL);
MNormalBakeData *normal_data = (MNormalBakeData *)bake_data;
float uv[2], *st0, *st1, *st2, *st3;
int pixel = ibuf->x * y + x;
@@ -879,7 +857,7 @@ static void bake_images(MultiresBakeRender *bkr)
for (link = bkr->image.first; link; link = link->next) {
Image *ima = (Image *)link->data;
- ImBuf *ibuf = BKE_image_get_ibuf(ima, NULL);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
if (ibuf->x > 0 && ibuf->y > 0) {
ibuf->userdata = MEM_callocN(ibuf->y * ibuf->x, "MultiresBake imbuf mask");
@@ -895,6 +873,8 @@ static void bake_images(MultiresBakeRender *bkr)
}
}
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+
ima->id.flag |= LIB_DOIT;
}
}
@@ -905,7 +885,7 @@ static void finish_images(MultiresBakeRender *bkr)
for (link = bkr->image.first; link; link = link->next) {
Image *ima = (Image *)link->data;
- ImBuf *ibuf = BKE_image_get_ibuf(ima, NULL);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
if (ibuf->x <= 0 || ibuf->y <= 0)
continue;
@@ -926,6 +906,8 @@ static void finish_images(MultiresBakeRender *bkr)
MEM_freeN(ibuf->userdata);
ibuf->userdata = NULL;
}
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
}
}
@@ -1000,7 +982,7 @@ static int multiresbake_check(bContext *C, wmOperator *op)
ok = 0;
}
else {
- ImBuf *ibuf = BKE_image_get_ibuf(ima, NULL);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
if (!ibuf) {
BKE_report(op->reports, RPT_ERROR, "Baking should happen to image with image buffer");
@@ -1017,6 +999,8 @@ static int multiresbake_check(bContext *C, wmOperator *op)
if (!ok)
BKE_report(op->reports, RPT_ERROR, "Baking to unsupported image type");
}
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
}
}
}
@@ -1087,10 +1071,12 @@ static void clear_images(MTFace *mtface, int totface)
Image *ima = mtface[a].tpage;
if ((ima->id.flag & LIB_DOIT) == 0) {
- ImBuf *ibuf = BKE_image_get_ibuf(ima, NULL);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? vec_alpha : vec_solid);
ima->id.flag |= LIB_DOIT;
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
}
}
@@ -1384,7 +1370,7 @@ static void finish_bake_internal(BakeRender *bkr)
/* force OpenGL reload and mipmap recalc */
for (ima = G.main->image.first; ima; ima = ima->id.next) {
- ImBuf *ibuf = BKE_image_get_ibuf(ima, NULL);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
/* some of the images could have been changed during bake,
* so recreate mipmaps regardless bake result status
@@ -1409,6 +1395,8 @@ static void finish_bake_internal(BakeRender *bkr)
ibuf->userdata = NULL;
}
}
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
}
}
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index c0c2195592b..d39e34824b9 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -550,7 +550,8 @@ static int editmode_toggle_poll(bContext *C)
if (ELEM(NULL, ob, ob->data) || ((ID *)ob->data)->lib)
return 0;
- if (ob->restrictflag & OB_RESTRICT_VIEW)
+ /* if hidden but in edit mode, we still display */
+ if ((ob->restrictflag & OB_RESTRICT_VIEW) && !(ob->mode & OB_MODE_EDIT))
return 0;
return (ob->type == OB_MESH || ob->type == OB_ARMATURE ||
@@ -1380,7 +1381,7 @@ static void UNUSED_FUNCTION(image_aspect) (Scene * scene, View3D * v3d)
if (ma->mtex[b] && ma->mtex[b]->tex) {
tex = ma->mtex[b]->tex;
if (tex->type == TEX_IMAGE && tex->ima) {
- ImBuf *ibuf = BKE_image_get_ibuf(tex->ima, NULL);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(tex->ima, NULL, NULL);
/* texturespace */
space = 1.0;
@@ -1402,6 +1403,8 @@ static void UNUSED_FUNCTION(image_aspect) (Scene * scene, View3D * v3d)
done = TRUE;
DAG_id_tag_update(&ob->id, OB_RECALC_OB);
+
+ BKE_image_release_ibuf(tex->ima, ibuf, NULL);
}
}
if (done) break;
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index 3d2c4f95624..7d3d6861418 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -555,7 +555,7 @@ static int modifier_apply_shape(ReportList *reports, Scene *scene, Object *ob, M
Key *key = me->key;
KeyBlock *kb;
- if (!modifier_sameTopology(md) || mti->type == eModifierTypeType_NonGeometrical) {
+ if (!modifier_isSameTopology(md) || mti->type == eModifierTypeType_NonGeometrical) {
BKE_report(reports, RPT_ERROR, "Only deforming modifiers can be applied to shapes");
return 0;
}
@@ -688,6 +688,13 @@ int ED_object_modifier_apply(ReportList *reports, Scene *scene, Object *ob, Modi
BKE_report(reports, RPT_ERROR, "Modifiers cannot be applied to multi-user data");
return 0;
}
+ else if ((ob->mode & OB_MODE_SCULPT) &&
+ (find_multires_modifier_before(scene, md)) &&
+ (modifier_isSameTopology(md) == FALSE))
+ {
+ BKE_report(reports, RPT_ERROR, "Constructive modifier cannot be applied to multi-res data in sculpt mode");
+ return 0;
+ }
if (md != ob->modifiers.first)
BKE_report(reports, RPT_INFO, "Applied modifier was not first, result may not be as expected");
@@ -1000,7 +1007,7 @@ static int modifier_apply_exec(bContext *C, wmOperator *op)
Object *ob = ED_object_active_context(C);
ModifierData *md = edit_modifier_property_get(op, ob, 0);
int apply_as = RNA_enum_get(op->ptr, "apply_as");
-
+
if (!ob || !md || !ED_object_modifier_apply(op->reports, scene, ob, md, apply_as)) {
return OPERATOR_CANCELLED;
}
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
index 58c6959d6f0..e7f09b4055a 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 *event)
+static int move_to_layer_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(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 *event)
}
else {
move_to_layer_init(C, op);
- return WM_operator_props_popup(C, op, event);
+ return WM_operator_props_dialog_popup(C, op, 260, 30);
}
}
diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c
index 05524af34f0..e56ca20dfcc 100644
--- a/source/blender/editors/object/object_vgroup.c
+++ b/source/blender/editors/object/object_vgroup.c
@@ -845,25 +845,26 @@ void ED_vgroup_vert_remove(Object *ob, bDeformGroup *dg, int vertnum)
static float get_vert_def_nr(Object *ob, const int def_nr, const int vertnum)
{
MDeformVert *dv = NULL;
- BMVert *eve;
- Mesh *me;
/* get the deform vertices corresponding to the vertnum */
if (ob->type == OB_MESH) {
- me = ob->data;
+ Mesh *me = ob->data;
if (me->edit_btmesh) {
- eve = BM_vert_at_index(me->edit_btmesh->bm, vertnum);
+ /* warning, this lookup is _not_ fast */
+ BMVert *eve = BM_vert_at_index(me->edit_btmesh->bm, vertnum);
if (!eve) {
return 0.0f;
}
dv = CustomData_bmesh_get(&me->edit_btmesh->bm->vdata, eve->head.data, CD_MDEFORMVERT);
}
else {
- if (vertnum >= me->totvert) {
- return 0.0f;
+ if (me->dvert) {
+ if (vertnum >= me->totvert) {
+ return 0.0f;
+ }
+ dv = &me->dvert[vertnum];
}
- dv = &me->dvert[vertnum];
}
}
else if (ob->type == OB_LATTICE) {
diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c
index 82e47312222..9121e4e55b5 100644
--- a/source/blender/editors/physics/particle_edit.c
+++ b/source/blender/editors/physics/particle_edit.c
@@ -404,6 +404,7 @@ static int key_test_depth(PEData *data, const float co[3], const int screen_co[2
{
View3D *v3d= data->vc.v3d;
GLfloat u[3];
+ ViewDepths *vd = data->vc.rv3d->depths;
float depth;
/* nothing to do */
@@ -430,12 +431,15 @@ static int key_test_depth(PEData *data, const float co[3], const int screen_co[2
/* view3d_validate_backbuf(&data->vc); */
glReadPixels(screen_co[0], screen_co[1], 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth);
#else /* faster to use depths, these are calculated in PE_set_view3d_data */
- {
- ViewDepths *vd = data->vc.rv3d->depths;
- assert(vd && vd->depths);
+
+ /* 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) {
+ BLI_assert(vd && vd->depths);
/* we know its not clipped */
depth = vd->depths[screen_co[1] * vd->w + screen_co[0]];
}
+ else
+ return 0;
#endif
if (u[2] - 0.00001f > depth)
@@ -2439,7 +2443,8 @@ void PARTICLE_OT_remove_doubles(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
/* properties */
- RNA_def_float(ot->srna, "threshold", 0.0002f, 0.0f, FLT_MAX, "Threshold", "Threshold distance withing which particles are removed", 0.00001f, 0.1f);
+ RNA_def_float(ot->srna, "threshold", 0.0002f, 0.0f, FLT_MAX,
+ "Merge Distance", "Threshold distance withing which particles are removed", 0.00001f, 0.1f);
}
diff --git a/source/blender/editors/physics/physics_fluid.c b/source/blender/editors/physics/physics_fluid.c
index 7cd153d9564..5304c64c2a9 100644
--- a/source/blender/editors/physics/physics_fluid.c
+++ b/source/blender/editors/physics/physics_fluid.c
@@ -446,7 +446,7 @@ static void fluid_init_all_channels(bContext *C, Object *UNUSED(fsDomain), Fluid
for (fobj=fobjects->first; fobj; fobj=fobj->next) {
Object *ob = fobj->object;
FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim);
- float active= (float)(fluidmd->fss->flag & OB_FLUIDSIM_ACTIVE);
+ float active= (float) ((fluidmd->fss->flag & OB_FLUIDSIM_ACTIVE) > 0 ? 1 : 0);
float rot_d[3] = {0.f, 0.f, 0.f}, old_rot[3] = {0.f, 0.f, 0.f};
if (ELEM(fluidmd->fss->type, OB_FLUIDSIM_DOMAIN, OB_FLUIDSIM_PARTICLE))
@@ -467,6 +467,8 @@ static void fluid_init_all_channels(bContext *C, Object *UNUSED(fsDomain), Fluid
set_channel(fobj->Scale, timeAtFrame, ob->size, i, CHANNEL_VEC);
set_channel(fobj->Active, timeAtFrame, &active, i, CHANNEL_FLOAT);
set_channel(fobj->InitialVelocity, timeAtFrame, &fluidmd->fss->iniVelx, i, CHANNEL_VEC);
+
+ // printf("Active: %f, Frame: %f\n", active, timeAtFrame);
if (fluidmd->fss->type == OB_FLUIDSIM_CONTROL) {
set_channel(fobj->AttractforceStrength, timeAtFrame, &fluidmd->fss->attractforceStrength, i, CHANNEL_FLOAT);
@@ -962,8 +964,8 @@ static int fluidsimBake(bContext *C, ReportList *reports, Object *fsDomain, shor
/* ******** prepare output file paths ******** */
outStringsChanged = fluid_init_filepaths(fsDomain, targetDir, targetFile, debugStrBuffer);
- channels->length = scene->r.efra;
- channels->aniFrameTime = (double)(domainSettings->animEnd - domainSettings->animStart) / (double)noFrames;
+ channels->length = scene->r.efra; // DG TODO: why using endframe and not "noFrames" here? .. because "noFrames" is buggy too? (not using sfra)
+ channels->aniFrameTime = (double)((double)domainSettings->animEnd - (double)domainSettings->animStart) / (double)noFrames;
/* ******** initialize and allocate animation channels ******** */
fluid_init_all_channels(C, fsDomain, domainSettings, channels, fobjects);
diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c
index 4b177629f72..7b67f63c646 100644
--- a/source/blender/editors/render/render_internal.c
+++ b/source/blender/editors/render/render_internal.c
@@ -375,7 +375,7 @@ static void image_rect_update(void *rjv, RenderResult *rr, volatile rcti *renrec
/* make jobs timer to send notifier */
*(rj->do_update) = TRUE;
}
- BKE_image_release_ibuf(ima, lock);
+ BKE_image_release_ibuf(ima, ibuf, lock);
}
static void render_startjob(void *rjv, short *stop, short *do_update, float *progress)
diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c
index 4dc08d2687a..4364ec712fd 100644
--- a/source/blender/editors/render/render_opengl.c
+++ b/source/blender/editors/render/render_opengl.c
@@ -287,7 +287,7 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
}
}
- BKE_image_release_ibuf(oglrender->ima, lock);
+ BKE_image_release_ibuf(oglrender->ima, ibuf, lock);
}
static int screen_opengl_render_init(bContext *C, wmOperator *op)
@@ -612,7 +612,7 @@ static int screen_opengl_render_anim_step(bContext *C, wmOperator *op)
IMB_freeImBuf(ibuf);
}
- BKE_image_release_ibuf(oglrender->ima, lock);
+ BKE_image_release_ibuf(oglrender->ima, ibuf, lock);
/* movie stats prints have no line break */
printf("\n");
diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c
index 2f9b6231858..73a250ec6a9 100644
--- a/source/blender/editors/render/render_preview.c
+++ b/source/blender/editors/render/render_preview.c
@@ -934,13 +934,15 @@ static void icon_preview_startjob(void *customdata, short *stop, short *do_updat
/* elubie: this needs to be changed: here image is always loaded if not
* already there. Very expensive for large images. Need to find a way to
* only get existing ibuf */
- ibuf = BKE_image_get_ibuf(ima, &iuser);
+ ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL);
if (ibuf == NULL || ibuf->rect == NULL)
return;
icon_copy_rect(ibuf, sp->sizex, sp->sizey, sp->pr_rect);
*do_update = TRUE;
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
}
else if (idtype == ID_BR) {
Brush *br = (Brush *)id;
diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c
index 5155f1001ab..3f438c5948e 100644
--- a/source/blender/editors/render/render_update.c
+++ b/source/blender/editors/render/render_update.c
@@ -250,6 +250,24 @@ static void material_changed(Main *bmain, Material *ma)
}
}
+static void lamp_changed(Main *bmain, Lamp *la)
+{
+ Object *ob;
+ Material *ma;
+
+ /* icons */
+ BKE_icon_changed(BKE_icon_getid(&la->id));
+
+ /* glsl */
+ for (ob = bmain->object.first; ob; ob = ob->id.next)
+ if (ob->data == la && ob->gpulamp.first)
+ GPU_lamp_free(ob);
+
+ for (ma = bmain->mat.first; ma; ma = ma->id.next)
+ if (ma->gpumaterial.first)
+ GPU_material_free(ma);
+}
+
static void texture_changed(Main *bmain, Tex *tex)
{
Material *ma;
@@ -282,16 +300,14 @@ static void texture_changed(Main *bmain, Tex *tex)
/* find lamps */
for (la = bmain->lamp.first; la; la = la->id.next) {
if (mtex_use_tex(la->mtex, MAX_MTEX, tex)) {
- /* pass */
+ lamp_changed(bmain, la);
}
else if (la->nodetree && nodes_use_tex(la->nodetree, tex)) {
- /* pass */
+ lamp_changed(bmain, la);
}
else {
continue;
}
-
- BKE_icon_changed(BKE_icon_getid(&la->id));
}
/* find worlds */
@@ -320,24 +336,6 @@ static void texture_changed(Main *bmain, Tex *tex)
}
}
-static void lamp_changed(Main *bmain, Lamp *la)
-{
- Object *ob;
- Material *ma;
-
- /* icons */
- BKE_icon_changed(BKE_icon_getid(&la->id));
-
- /* glsl */
- for (ob = bmain->object.first; ob; ob = ob->id.next)
- if (ob->data == la && ob->gpulamp.first)
- GPU_lamp_free(ob);
-
- for (ma = bmain->mat.first; ma; ma = ma->id.next)
- if (ma->gpumaterial.first)
- GPU_material_free(ma);
-}
-
static void world_changed(Main *bmain, World *wo)
{
Material *ma;
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index 6a9c24d2913..67d4af916aa 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -293,29 +293,35 @@ int ED_operator_console_active(bContext *C)
return ed_spacetype_test(C, SPACE_CONSOLE);
}
+static int ed_object_hidden(Object *ob)
+{
+ /* if hidden but in edit mode, we still display, can happen with animation */
+ return ((ob->restrictflag & OB_RESTRICT_VIEW) && !(ob->mode & OB_MODE_EDIT));
+}
+
int ED_operator_object_active(bContext *C)
{
Object *ob = ED_object_active_context(C);
- return ((ob != NULL) && !(ob->restrictflag & OB_RESTRICT_VIEW));
+ return ((ob != NULL) && !ed_object_hidden(ob));
}
int ED_operator_object_active_editable(bContext *C)
{
Object *ob = ED_object_active_context(C);
- return ((ob != NULL) && !(ob->id.lib) && !(ob->restrictflag & OB_RESTRICT_VIEW));
+ return ((ob != NULL) && !(ob->id.lib) && !ed_object_hidden(ob));
}
int ED_operator_object_active_editable_mesh(bContext *C)
{
Object *ob = ED_object_active_context(C);
- return ((ob != NULL) && !(ob->id.lib) && !(ob->restrictflag & OB_RESTRICT_VIEW) &&
+ return ((ob != NULL) && !(ob->id.lib) && !ed_object_hidden(ob) &&
(ob->type == OB_MESH) && !(((ID *)ob->data)->lib));
}
int ED_operator_object_active_editable_font(bContext *C)
{
Object *ob = ED_object_active_context(C);
- return ((ob != NULL) && !(ob->id.lib) && !(ob->restrictflag & OB_RESTRICT_VIEW) &&
+ return ((ob != NULL) && !(ob->id.lib) && !ed_object_hidden(ob) &&
(ob->type == OB_FONT));
}
diff --git a/source/blender/editors/screen/screendump.c b/source/blender/editors/screen/screendump.c
index d980703dce5..ae5d6ed6152 100644
--- a/source/blender/editors/screen/screendump.c
+++ b/source/blender/editors/screen/screendump.c
@@ -35,6 +35,7 @@
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
+#include "BLI_math.h"
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
@@ -52,6 +53,8 @@
#include "BKE_writeavi.h"
#include "GPU_compatibility.h"
+#include "GPU_primitives.h"
+#include "BIF_glutil.h"
#include "RNA_access.h"
#include "RNA_define.h"
@@ -278,6 +281,7 @@ void SCREEN_OT_screenshot(wmOperatorType *ot)
typedef struct ScreenshotJob {
Main *bmain;
Scene *scene;
+ wmWindowManager *wm;
unsigned int *dumprect;
int x, y, dumpsx, dumpsy;
short *stop;
@@ -395,6 +399,54 @@ static void screenshot_startjob(void *sjv, short *stop, short *do_update, float
BKE_report(&sj->reports, RPT_INFO, "Screencast job stopped");
}
+/* Helper callback for drawing the cursor itself */
+static void screencast_draw_cursor(bContext *UNUSED(C), int x, int y, void *UNUSED(p_ptr))
+{
+
+ glPushMatrix();
+
+ glTranslatef((float)x, (float)y, 0.0f);
+
+
+ glEnable(GL_LINE_SMOOTH);
+ glEnable(GL_BLEND);
+
+ gpuCurrentColor4ub(0, 0, 0, 32);
+ gpuSingleArc(0, 0, 0, 2*M_PI, 20, 20, 40);
+
+ gpuCurrentColor4ub(255, 255, 255, 128);
+ gpuSingleArc(0, 0, 0, 2*M_PI, 20, 20, 40);
+
+ glDisable(GL_BLEND);
+ glDisable(GL_LINE_SMOOTH);
+
+ glPopMatrix();
+}
+
+/* Turn brush cursor in 3D view on/off */
+static void screencast_cursor_toggle(wmWindowManager *wm, short enable)
+{
+ static void *cursor = NULL;
+
+ if (cursor && !enable) {
+ /* clear cursor */
+ WM_paint_cursor_end(wm, cursor);
+ cursor = NULL;
+ }
+ else if (enable) {
+ /* enable cursor */
+ cursor = WM_paint_cursor_activate(wm, NULL, screencast_draw_cursor, NULL);
+ }
+}
+
+static void screenshot_endjob(void *sjv)
+{
+ ScreenshotJob *sj = sjv;
+
+ screencast_cursor_toggle(sj->wm, 0);
+}
+
+
static int screencast_exec(bContext *C, wmOperator *op)
{
bScreen *screen = CTX_wm_screen(C);
@@ -418,15 +470,18 @@ static int screencast_exec(bContext *C, wmOperator *op)
}
sj->bmain = CTX_data_main(C);
sj->scene = CTX_data_scene(C);
-
+ sj->wm = CTX_wm_manager(C);
+
BKE_reports_init(&sj->reports, RPT_PRINT);
/* setup job */
WM_jobs_customdata_set(wm_job, sj, screenshot_freejob);
WM_jobs_timer(wm_job, 0.1, 0, NC_SCREEN | ND_SCREENCAST);
- WM_jobs_callbacks(wm_job, screenshot_startjob, NULL, screenshot_updatejob, NULL);
+ WM_jobs_callbacks(wm_job, screenshot_startjob, NULL, screenshot_updatejob, screenshot_endjob);
+
+ WM_jobs_start(sj->wm, wm_job);
- WM_jobs_start(CTX_wm_manager(C), wm_job);
+ screencast_cursor_toggle(sj->wm, 1);
WM_event_add_notifier(C, NC_SCREEN | ND_SCREENCAST, screen);
diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c
index 3cf4c947c26..80d49387df7 100644
--- a/source/blender/editors/sculpt_paint/paint_image.c
+++ b/source/blender/editors/sculpt_paint/paint_image.c
@@ -501,7 +501,7 @@ static void image_undo_restore(bContext *C, ListBase *lb)
ima = BLI_findstring(&bmain->image, tile->idname, offsetof(ID, name));
}
- ibuf = BKE_image_get_ibuf(ima, NULL);
+ ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
if (ima && ibuf && strcmp(tile->ibufname, ibuf->name) != 0) {
/* current ImBuf filename was changed, probably current frame
@@ -509,19 +509,27 @@ static void image_undo_restore(bContext *C, ListBase *lb)
* full image user (which isn't so obvious, btw) try to find ImBuf with
* matched file name in list of already loaded images */
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+
ibuf = BLI_findstring(&ima->ibufs, tile->ibufname, offsetof(ImBuf, name));
}
- if (!ima || !ibuf || !(ibuf->rect || ibuf->rect_float))
+ if (!ima || !ibuf || !(ibuf->rect || ibuf->rect_float)) {
+ BKE_image_release_ibuf(ima, ibuf, NULL);
continue;
+ }
- if (ima->gen_type != tile->gen_type || ima->source != tile->source)
+ if (ima->gen_type != tile->gen_type || ima->source != tile->source) {
+ BKE_image_release_ibuf(ima, ibuf, NULL);
continue;
+ }
use_float = ibuf->rect_float ? 1 : 0;
- if (use_float != tile->use_float)
+ if (use_float != tile->use_float) {
+ BKE_image_release_ibuf(ima, ibuf, NULL);
continue;
+ }
undo_copy_tile(tile, tmpibuf, ibuf, 1);
@@ -531,6 +539,8 @@ static void image_undo_restore(bContext *C, ListBase *lb)
if (ibuf->mipmap[0])
ibuf->userflags |= IB_MIPMAP_INVALID; /* force mipmap recreatiom */
ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
}
IMB_freeImBuf(tmpibuf);
@@ -1050,11 +1060,11 @@ static int pixel_bounds_uv(
INIT_MINMAX2(min_uv, max_uv);
- DO_MINMAX2(uv1, min_uv, max_uv);
- DO_MINMAX2(uv2, min_uv, max_uv);
- DO_MINMAX2(uv3, min_uv, max_uv);
+ minmax_v2v2_v2(min_uv, max_uv, uv1);
+ minmax_v2v2_v2(min_uv, max_uv, uv2);
+ minmax_v2v2_v2(min_uv, max_uv, uv3);
if (is_quad)
- DO_MINMAX2(uv4, min_uv, max_uv);
+ minmax_v2v2_v2(min_uv, max_uv, uv4);
bounds_px->xmin = (int)(ibuf_x * min_uv[0]);
bounds_px->ymin = (int)(ibuf_y * min_uv[1]);
@@ -1080,7 +1090,7 @@ static int pixel_bounds_array(float (*uv)[2], rcti *bounds_px, const int ibuf_x,
INIT_MINMAX2(min_uv, max_uv);
while (tot--) {
- DO_MINMAX2((*uv), min_uv, max_uv);
+ minmax_v2v2_v2(min_uv, max_uv, (*uv));
uv++;
}
@@ -1399,8 +1409,8 @@ static float project_paint_uvpixel_mask(
Image *other_tpage = project_paint_face_image(ps, ps->dm_mtface_stencil, face_index);
const MTFace *tf_other = ps->dm_mtface_stencil + face_index;
- if (other_tpage && (ibuf_other = BKE_image_get_ibuf(other_tpage, NULL))) {
- /* BKE_image_get_ibuf - TODO - this may be slow */
+ if (other_tpage && (ibuf_other = BKE_image_acquire_ibuf(other_tpage, NULL, NULL))) {
+ /* BKE_image_acquire_ibuf - TODO - this may be slow */
unsigned char rgba_ub[4];
float rgba_f[4];
@@ -1412,7 +1422,9 @@ static float project_paint_uvpixel_mask(
else { /* from char to float */
mask = ((rgba_ub[0] + rgba_ub[1] + rgba_ub[2]) / (256 * 3.0f)) * (rgba_ub[3] / 256.0f);
}
-
+
+ BKE_image_release_ibuf(other_tpage, ibuf_other, NULL);
+
if (!ps->do_layer_stencil_inv) /* matching the gimps layer mask black/white rules, white==full opacity */
mask = (1.0f - mask);
@@ -1580,8 +1592,8 @@ static ProjPixel *project_paint_uvpixel_init(
Image *other_tpage = project_paint_face_image(ps, ps->dm_mtface_clone, face_index);
const MTFace *tf_other = ps->dm_mtface_clone + face_index;
- if (other_tpage && (ibuf_other = BKE_image_get_ibuf(other_tpage, NULL))) {
- /* BKE_image_get_ibuf - TODO - this may be slow */
+ if (other_tpage && (ibuf_other = BKE_image_acquire_ibuf(other_tpage, NULL, NULL))) {
+ /* BKE_image_acquire_ibuf - TODO - this may be slow */
if (ibuf->rect_float) {
if (ibuf_other->rect_float) { /* from float to float */
@@ -1603,6 +1615,8 @@ static ProjPixel *project_paint_uvpixel_init(
project_face_pixel(tf_other, ibuf_other, w, side, ((ProjPixelClone *)projPixel)->clonepx.ch, NULL);
}
}
+
+ BKE_image_release_ibuf(other_tpage, ibuf_other, NULL);
}
else {
if (ibuf->rect_float) {
@@ -2927,7 +2941,7 @@ static void project_paint_delayed_face_init(ProjPaintState *ps, const MFace *mf,
fidx = mf->v4 ? 3 : 2;
do {
vCoSS = ps->screenCoords[*(&mf->v1 + fidx)];
- DO_MINMAX2(vCoSS, min, max);
+ minmax_v2v2_v2(min, max, vCoSS);
} while (fidx--);
project_paint_bucket_bounds(ps, min, max, bucketMin, bucketMax);
@@ -3192,7 +3206,7 @@ static void project_paint_begin(ProjPaintState *ps)
/* screen space, not clamped */
projScreenCo[0] = (float)(ps->winx / 2.0f) + (ps->winx / 2.0f) * projScreenCo[0];
projScreenCo[1] = (float)(ps->winy / 2.0f) + (ps->winy / 2.0f) * projScreenCo[1];
- DO_MINMAX2(projScreenCo, ps->screenMin, ps->screenMax);
+ minmax_v2v2_v2(ps->screenMin, ps->screenMax, projScreenCo);
}
}
else {
@@ -3207,7 +3221,7 @@ static void project_paint_begin(ProjPaintState *ps)
projScreenCo[0] = (float)(ps->winx / 2.0f) + (ps->winx / 2.0f) * projScreenCo[0] / projScreenCo[3];
projScreenCo[1] = (float)(ps->winy / 2.0f) + (ps->winy / 2.0f) * projScreenCo[1] / projScreenCo[3];
projScreenCo[2] = projScreenCo[2] / projScreenCo[3]; /* Use the depth for bucket point occlusion */
- DO_MINMAX2(projScreenCo, ps->screenMin, ps->screenMax);
+ minmax_v2v2_v2(ps->screenMin, ps->screenMax, projScreenCo);
}
else {
/* TODO - deal with cases where 1 side of a face goes behind the view ?
@@ -3409,7 +3423,7 @@ static void project_paint_begin(ProjPaintState *ps)
image_index = BLI_linklist_index(image_LinkList, tpage);
- if (image_index == -1 && BKE_image_get_ibuf(tpage, NULL)) { /* MemArena dosnt have an append func */
+ if (image_index == -1 && BKE_image_has_ibuf(tpage, NULL)) { /* MemArena dosnt have an append func */
BLI_linklist_append(&image_LinkList, tpage);
image_index = ps->image_tot;
ps->image_tot++;
@@ -3432,7 +3446,7 @@ static void project_paint_begin(ProjPaintState *ps)
for (node = image_LinkList, i = 0; node; node = node->next, i++, projIma++) {
projIma->ima = node->link;
projIma->touch = 0;
- projIma->ibuf = BKE_image_get_ibuf(projIma->ima, NULL);
+ projIma->ibuf = BKE_image_acquire_ibuf(projIma->ima, NULL, NULL);
projIma->partRedrawRect = BLI_memarena_alloc(arena, sizeof(ImagePaintPartialRedraw) * PROJ_BOUNDBOX_SQUARED);
memset(projIma->partRedrawRect, 0, sizeof(ImagePaintPartialRedraw) * PROJ_BOUNDBOX_SQUARED);
}
@@ -3459,6 +3473,7 @@ static void project_paint_begin_clone(ProjPaintState *ps, int mouse[2])
static void project_paint_end(ProjPaintState *ps)
{
int a;
+ ProjPaintImage *projIma;
/* build undo data from original pixel colors */
if (U.uiflag & USER_GLOBALUNDO) {
@@ -3546,7 +3561,14 @@ static void project_paint_end(ProjPaintState *ps)
if (tmpibuf_float) IMB_freeImBuf(tmpibuf_float);
}
/* done calculating undo data */
-
+
+ /* dereference used image buffers */
+ for (a = 0, projIma = ps->projImages; a < ps->image_tot; a++, projIma++) {
+ BKE_image_release_ibuf(projIma->ima, projIma->ibuf, NULL);
+ }
+
+ BKE_image_release_ibuf(ps->reproject_image, ps->reproject_ibuf, NULL);
+
MEM_freeN(ps->screenCoords);
MEM_freeN(ps->bucketRect);
MEM_freeN(ps->bucketFaces);
@@ -4673,7 +4695,7 @@ static int texpaint_break_stroke(float *prevuv, float *fwuv, float *bkuv, float
static int imapaint_canvas_set(ImagePaintState *s, Image *ima)
{
- ImBuf *ibuf = BKE_image_get_ibuf(ima, s->sima ? &s->sima->iuser : NULL);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, s->sima ? &s->sima->iuser : NULL, NULL);
/* verify that we can paint and set canvas */
if (ima == NULL) {
@@ -4696,10 +4718,12 @@ static int imapaint_canvas_set(ImagePaintState *s, Image *ima)
/* set clone canvas */
if (s->tool == PAINT_TOOL_CLONE) {
ima = s->brush->clone.image;
- ibuf = BKE_image_get_ibuf(ima, s->sima ? &s->sima->iuser : NULL);
+ ibuf = BKE_image_acquire_ibuf(ima, s->sima ? &s->sima->iuser : NULL, NULL);
- if (!ima || !ibuf || !(ibuf->rect || ibuf->rect_float))
+ if (!ima || !ibuf || !(ibuf->rect || ibuf->rect_float)) {
+ BKE_image_release_ibuf(ima, ibuf, NULL);
return 0;
+ }
s->clonecanvas = ibuf;
@@ -4714,13 +4738,15 @@ static int imapaint_canvas_set(ImagePaintState *s, Image *ima)
return 1;
}
-static void imapaint_canvas_free(ImagePaintState *UNUSED(s))
+static void imapaint_canvas_free(ImagePaintState *s)
{
+ BKE_image_release_ibuf(s->image, s->canvas, NULL);
+ BKE_image_release_ibuf(s->brush->clone.image, s->clonecanvas, NULL);
}
static int imapaint_paint_sub_stroke(ImagePaintState *s, BrushPainter *painter, Image *image, short texpaint, float *uv, double time, int update, float pressure)
{
- ImBuf *ibuf = BKE_image_get_ibuf(image, s->sima ? &s->sima->iuser : NULL);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(image, s->sima ? &s->sima->iuser : NULL, NULL);
float pos[2];
int is_data;
@@ -4740,9 +4766,13 @@ static int imapaint_paint_sub_stroke(ImagePaintState *s, BrushPainter *painter,
if (BKE_brush_painter_paint(painter, imapaint_paint_op, pos, time, pressure, s, is_data == FALSE)) {
if (update)
imapaint_image_update(s->scene, s->sima, image, ibuf, texpaint);
+ BKE_image_release_ibuf(image, ibuf, NULL);
return 1;
}
- else return 0;
+ else {
+ BKE_image_release_ibuf(image, ibuf, NULL);
+ return 0;
+ }
}
static int imapaint_paint_stroke(ViewContext *vc, ImagePaintState *s, BrushPainter *painter, short texpaint, const int prevmval[2], const int mval[2], double time, float pressure)
@@ -4760,7 +4790,7 @@ static int imapaint_paint_stroke(ViewContext *vc, ImagePaintState *s, BrushPaint
ImBuf *ibuf;
newimage = imapaint_face_image(s, newfaceindex);
- ibuf = BKE_image_get_ibuf(newimage, s->sima ? &s->sima->iuser : NULL);
+ ibuf = BKE_image_acquire_ibuf(newimage, s->sima ? &s->sima->iuser : NULL, NULL);
if (ibuf && ibuf->rect)
imapaint_pick_uv(s->scene, s->ob, newfaceindex, mval, newuv);
@@ -4768,6 +4798,8 @@ static int imapaint_paint_stroke(ViewContext *vc, ImagePaintState *s, BrushPaint
newimage = NULL;
newuv[0] = newuv[1] = 0.0f;
}
+
+ BKE_image_release_ibuf(newimage, ibuf, NULL);
}
else
newuv[0] = newuv[1] = 0.0f;
@@ -5891,7 +5923,7 @@ static int texture_paint_camera_project_exec(bContext *C, wmOperator *op)
}
ps.reproject_image = image;
- ps.reproject_ibuf = BKE_image_get_ibuf(image, NULL);
+ ps.reproject_ibuf = BKE_image_acquire_ibuf(image, NULL, NULL);
if (ps.reproject_ibuf == NULL || ps.reproject_ibuf->rect == NULL) {
BKE_report(op->reports, RPT_ERROR, "Image data could not be found");
diff --git a/source/blender/editors/space_buttons/buttons_texture.c b/source/blender/editors/space_buttons/buttons_texture.c
index 0e82d8651f3..abfefba02b9 100644
--- a/source/blender/editors/space_buttons/buttons_texture.c
+++ b/source/blender/editors/space_buttons/buttons_texture.c
@@ -248,7 +248,7 @@ static void buttons_texture_users_from_context(ListBase *users, const bContext *
void buttons_texture_context_compute(const bContext *C, SpaceButs *sbuts)
{
- /* gatheravailable texture users in context. runs on every draw of
+ /* gather available texture users in context. runs on every draw of
* properties editor, before the buttons are created. */
ButsContextTexture *ct = sbuts->texuser;
Scene *scene = CTX_data_scene(C);
diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c
index 157dc3282b9..a7ba2b7dbdb 100644
--- a/source/blender/editors/space_clip/clip_draw.c
+++ b/source/blender/editors/space_clip/clip_draw.c
@@ -1322,7 +1322,7 @@ static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip,
BKE_tracking_undistort_v2(tracking, pos, tpos);
- DO_MINMAX2(tpos, min, max);
+ minmax_v2v2_v2(min, max, tpos);
}
copy_v2_v2(pos, min);
@@ -1535,7 +1535,7 @@ void clip_draw_grease_pencil(bContext *C, int onlyv2d)
if (onlyv2d) {
/* if manual calibration is used then grease pencil data is already
- * drawed in draw_distortion */
+ * drawn in draw_distortion */
if ((sc->flag & SC_MANUAL_CALIBRATION) == 0 || sc->mode != SC_MODE_DISTORTION) {
gpuPushMatrix();
gpuMultMatrix(sc->unistabmat);
diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c
index 20ccdf74890..ac6bb785e72 100644
--- a/source/blender/editors/space_clip/clip_editor.c
+++ b/source/blender/editors/space_clip/clip_editor.c
@@ -349,7 +349,7 @@ static int selected_boundbox(SpaceClip *sc, float min[2], float max[2])
mul_v3_m4v3(pos, sc->stabmat, pos);
- DO_MINMAX2(pos, min, max);
+ minmax_v2v2_v2(min, max, pos);
ok = TRUE;
}
diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c
index 1620ea9cb1f..5f0e4db9dd7 100644
--- a/source/blender/editors/space_clip/space_clip.c
+++ b/source/blender/editors/space_clip/space_clip.c
@@ -1030,17 +1030,14 @@ static void clip_refresh(const bContext *C, ScrArea *sa)
static void movieclip_main_area_set_view2d(const bContext *C, ARegion *ar)
{
SpaceClip *sc = CTX_wm_space_clip(C);
- MovieClip *clip = ED_space_clip_get_clip(sc);
- float x1, y1, w, h;
+ float x1, y1, w, h, aspx, aspy;
int width, height, winx, winy;
ED_space_clip_get_size(sc, &width, &height);
+ ED_space_clip_get_aspect(sc, &aspx, &aspy);
- w = width;
- h = height;
-
- if (clip)
- h *= clip->aspy / clip->aspx / clip->tracking.camera.pixel_aspect;
+ w = width * aspx;
+ h = height * aspy;
winx = BLI_rcti_size_x(&ar->winrct) + 1;
winy = BLI_rcti_size_y(&ar->winrct) + 1;
diff --git a/source/blender/editors/space_console/console_ops.c b/source/blender/editors/space_console/console_ops.c
index d3ae5373a18..bb46135545c 100644
--- a/source/blender/editors/space_console/console_ops.c
+++ b/source/blender/editors/space_console/console_ops.c
@@ -157,10 +157,9 @@ static ConsoleLine *console_lb_add__internal(ListBase *lb, ConsoleLine *from)
ConsoleLine *ci = MEM_callocN(sizeof(ConsoleLine), "ConsoleLine Add");
if (from) {
- ci->line = BLI_strdup(from->line);
- ci->len = strlen(ci->line);
- ci->len_alloc = ci->len;
-
+ BLI_assert(strlen(from->line) == from->len);
+ ci->line = BLI_strdupn(from->line, from->len);
+ ci->len = ci->len_alloc = from->len;
ci->cursor = from->cursor;
ci->type = from->type;
}
@@ -174,10 +173,8 @@ static ConsoleLine *console_lb_add__internal(ListBase *lb, ConsoleLine *from)
return ci;
}
-static ConsoleLine *console_history_add(const bContext *C, ConsoleLine *from)
+static ConsoleLine *console_history_add(SpaceConsole *sc, ConsoleLine *from)
{
- SpaceConsole *sc = CTX_wm_space_console(C);
-
return console_lb_add__internal(&sc->history, from);
}
@@ -217,7 +214,7 @@ ConsoleLine *console_history_verify(const bContext *C)
SpaceConsole *sc = CTX_wm_space_console(C);
ConsoleLine *ci = sc->history.last;
if (ci == NULL)
- ci = console_history_add(C, NULL);
+ ci = console_history_add(sc, NULL);
return ci;
}
@@ -623,8 +620,9 @@ static int console_clear_line_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_CANCELLED;
}
- console_history_add(C, ci);
- console_history_add(C, NULL);
+ console_history_add(sc, ci);
+ console_history_add(sc, NULL);
+ console_select_offset(sc, -ci->len);
console_textview_update_rect(sc, ar);
@@ -727,7 +725,7 @@ static int console_history_cycle_exec(bContext *C, wmOperator *op)
while ((cl = console_history_find(sc, ci->line, ci)))
console_history_free(sc, cl);
- console_history_add(C, (ConsoleLine *)sc->history.last);
+ console_history_add(sc, (ConsoleLine *)sc->history.last);
}
ci = sc->history.last;
diff --git a/source/blender/editors/space_graph/graph_buttons.c b/source/blender/editors/space_graph/graph_buttons.c
index 8bb57a32090..483348db18e 100644
--- a/source/blender/editors/space_graph/graph_buttons.c
+++ b/source/blender/editors/space_graph/graph_buttons.c
@@ -714,7 +714,17 @@ static void graph_panel_drivers(const bContext *C, Panel *pa)
row = uiLayoutRow(box, TRUE);
uiItemL(row, IFACE_("Value:"), ICON_NONE);
- BLI_snprintf(valBuf, sizeof(valBuf), "%.3f", dvar->curval);
+ if ((dvar->type == DVAR_TYPE_ROT_DIFF) ||
+ (dvar->type == DVAR_TYPE_TRANSFORM_CHAN &&
+ dvar->targets[0].transChan >= DTAR_TRANSCHAN_ROTX &&
+ dvar->targets[0].transChan < DTAR_TRANSCHAN_SCALEX))
+ {
+ BLI_snprintf(valBuf, sizeof(valBuf), "%.3f (%4.1f°)", dvar->curval, RAD2DEGF(dvar->curval));
+ }
+ else {
+ BLI_snprintf(valBuf, sizeof(valBuf), "%.3f", dvar->curval);
+ }
+
uiItemL(row, valBuf, ICON_NONE);
}
}
diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c
index ae7a718ab5b..0a3db59096a 100644
--- a/source/blender/editors/space_image/image_buttons.c
+++ b/source/blender/editors/space_image/image_buttons.c
@@ -593,7 +593,7 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char
if (ima->source == IMA_SRC_VIEWER) {
ibuf = BKE_image_acquire_ibuf(ima, iuser, &lock);
image_info(scene, iuser, ima, ibuf, str);
- BKE_image_release_ibuf(ima, lock);
+ BKE_image_release_ibuf(ima, ibuf, lock);
uiItemL(layout, ima->id.name + 2, ICON_NONE);
uiItemL(layout, str, ICON_NONE);
@@ -663,7 +663,7 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char
if (compact == 0) {
ibuf = BKE_image_acquire_ibuf(ima, iuser, &lock);
image_info(scene, iuser, ima, ibuf, str);
- BKE_image_release_ibuf(ima, lock);
+ BKE_image_release_ibuf(ima, ibuf, lock);
uiItemL(layout, str, ICON_NONE);
}
}
@@ -722,7 +722,6 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char
split = uiLayoutSplit(layout, 0.0f, FALSE);
col = uiLayoutColumn(split, TRUE);
- uiLayoutSetEnabled(col, 0);
uiItemR(col, &imaptr, "generated_width", 0, "X", ICON_NONE);
uiItemR(col, &imaptr, "generated_height", 0, "Y", ICON_NONE);
diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c
index f418deeb1c9..9f67da768c5 100644
--- a/source/blender/editors/space_image/image_draw.c
+++ b/source/blender/editors/space_image/image_draw.c
@@ -661,7 +661,7 @@ static unsigned char *get_alpha_clone_image(const bContext *C, Scene *scene, int
if (!brush || !brush->clone.image)
return NULL;
- ibuf = BKE_image_get_ibuf(brush->clone.image, NULL);
+ ibuf = BKE_image_acquire_ibuf(brush->clone.image, NULL, NULL);
if (!ibuf)
return NULL;
@@ -669,6 +669,7 @@ static unsigned char *get_alpha_clone_image(const bContext *C, Scene *scene, int
display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, &cache_handle);
if (!display_buffer) {
+ BKE_image_release_ibuf(brush->clone.image, ibuf, NULL);
IMB_display_buffer_release(cache_handle);
return NULL;
@@ -678,8 +679,10 @@ static unsigned char *get_alpha_clone_image(const bContext *C, Scene *scene, int
IMB_display_buffer_release(cache_handle);
- if (!rect)
+ if (!rect) {
+ BKE_image_release_ibuf(brush->clone.image, ibuf, NULL);
return NULL;
+ }
*width = ibuf->x;
*height = ibuf->y;
@@ -693,6 +696,8 @@ static unsigned char *get_alpha_clone_image(const bContext *C, Scene *scene, int
cp += 4;
}
+ BKE_image_release_ibuf(brush->clone.image, ibuf, NULL);
+
return rect;
}
@@ -807,7 +812,7 @@ void draw_image_main(const bContext *C, ARegion *ar)
}
#endif
- ED_space_image_release_buffer(sima, lock);
+ ED_space_image_release_buffer(sima, ibuf, lock);
if (show_viewer) {
BLI_unlock_thread(LOCK_DRAW_IMAGE);
diff --git a/source/blender/editors/space_image/image_edit.c b/source/blender/editors/space_image/image_edit.c
index 4ca2f8888f8..c4e2230e7a7 100644
--- a/source/blender/editors/space_image/image_edit.c
+++ b/source/blender/editors/space_image/image_edit.c
@@ -117,8 +117,12 @@ ImBuf *ED_space_image_acquire_buffer(SpaceImage *sima, void **lock_r)
#endif
ibuf = BKE_image_acquire_ibuf(sima->image, &sima->iuser, lock_r);
- if (ibuf && (ibuf->rect || ibuf->rect_float))
- return ibuf;
+ if (ibuf) {
+ if (ibuf->rect || ibuf->rect_float)
+ return ibuf;
+
+ BKE_image_release_ibuf(sima->image, ibuf, NULL);
+ }
}
else
*lock_r = NULL;
@@ -126,10 +130,10 @@ ImBuf *ED_space_image_acquire_buffer(SpaceImage *sima, void **lock_r)
return NULL;
}
-void ED_space_image_release_buffer(SpaceImage *sima, void *lock)
+void ED_space_image_release_buffer(SpaceImage *sima, ImBuf *ibuf, void *lock)
{
if (sima && sima->image)
- BKE_image_release_ibuf(sima->image, lock);
+ BKE_image_release_ibuf(sima->image, ibuf, lock);
}
int ED_space_image_has_buffer(SpaceImage *sima)
@@ -140,7 +144,7 @@ int ED_space_image_has_buffer(SpaceImage *sima)
ibuf = ED_space_image_acquire_buffer(sima, &lock);
has_buffer = (ibuf != NULL);
- ED_space_image_release_buffer(sima, lock);
+ ED_space_image_release_buffer(sima, ibuf, lock);
return has_buffer;
}
@@ -175,7 +179,7 @@ void ED_space_image_get_size(SpaceImage *sima, int *width, int *height)
*height = IMG_SIZE_FALLBACK;
}
- ED_space_image_release_buffer(sima, lock);
+ ED_space_image_release_buffer(sima, ibuf, lock);
}
void ED_space_image_get_size_fl(SpaceImage *sima, float size[2])
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index ce3c6e1fd26..d4f24babff6 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -167,7 +167,7 @@ static int space_image_file_exists_poll(bContext *C)
ret = TRUE;
}
}
- ED_space_image_release_buffer(sima, lock);
+ ED_space_image_release_buffer(sima, ibuf, lock);
return ret;
}
@@ -1188,7 +1188,7 @@ static int save_image_options_init(SaveImageOptions *simopts, SpaceImage *sima,
BKE_color_managed_view_settings_copy(&simopts->im_format.view_settings, &scene->view_settings);
}
- ED_space_image_release_buffer(sima, lock);
+ ED_space_image_release_buffer(sima, ibuf, lock);
return (ibuf != NULL);
}
@@ -1328,7 +1328,7 @@ static void save_image_doit(bContext *C, SpaceImage *sima, wmOperator *op, SaveI
IMB_freeImBuf(colormanaged_ibuf);
}
- ED_space_image_release_buffer(sima, lock);
+ ED_space_image_release_buffer(sima, ibuf, lock);
}
static void image_save_as_free(wmOperator *op)
@@ -1743,17 +1743,14 @@ void IMAGE_OT_new(wmOperatorType *ot)
static int image_invert_poll(bContext *C)
{
Image *ima = CTX_data_edit_image(C);
- ImBuf *ibuf = BKE_image_get_ibuf(ima, NULL);
-
- if (ibuf != NULL)
- return 1;
- return 0;
+
+ return BKE_image_has_ibuf(ima, NULL);
}
static int image_invert_exec(bContext *C, wmOperator *op)
{
Image *ima = CTX_data_edit_image(C);
- ImBuf *ibuf = BKE_image_get_ibuf(ima, NULL);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
/* flags indicate if this channel should be inverted */
const short r = RNA_boolean_get(op->ptr, "invert_r");
@@ -1792,6 +1789,7 @@ static int image_invert_exec(bContext *C, wmOperator *op)
}
}
else {
+ BKE_image_release_ibuf(ima, ibuf, NULL);
return OPERATOR_CANCELLED;
}
@@ -1800,6 +1798,9 @@ static int image_invert_exec(bContext *C, wmOperator *op)
ibuf->userflags |= IB_MIPMAP_INVALID;
WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, ima);
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+
return OPERATOR_FINISHED;
}
@@ -1848,7 +1849,7 @@ static int image_pack_exec(bContext *C, wmOperator *op)
{
struct Main *bmain = CTX_data_main(C);
Image *ima = CTX_data_edit_image(C);
- ImBuf *ibuf = BKE_image_get_ibuf(ima, NULL);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
int as_png = RNA_boolean_get(op->ptr, "as_png");
if (!image_pack_test(C, op))
@@ -1865,30 +1866,38 @@ static int image_pack_exec(bContext *C, wmOperator *op)
ima->packedfile = newPackedFile(op->reports, ima->name, ID_BLEND_PATH(bmain, &ima->id));
WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, ima);
-
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+
return OPERATOR_FINISHED;
}
static int image_pack_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
{
Image *ima = CTX_data_edit_image(C);
- ImBuf *ibuf = BKE_image_get_ibuf(ima, NULL);
+ ImBuf *ibuf;
uiPopupMenu *pup;
uiLayout *layout;
int as_png = RNA_boolean_get(op->ptr, "as_png");
if (!image_pack_test(C, op))
return OPERATOR_CANCELLED;
-
+
+ ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
+
if (!as_png && (ibuf && (ibuf->userflags & IB_BITMAPDIRTY))) {
pup = uiPupMenuBegin(C, "OK", ICON_QUESTION);
layout = uiPupMenuLayout(pup);
uiItemBooleanO(layout, "Can't pack edited image from disk. Pack as internal PNG?", ICON_NONE, op->idname, "as_png", 1);
uiPupMenuEnd(C, pup);
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+
return OPERATOR_CANCELLED;
}
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+
return image_pack_exec(C, op);
}
@@ -2032,7 +2041,7 @@ int ED_space_image_color_sample(SpaceImage *sima, ARegion *ar, int mval[2], floa
int ret = FALSE;
if (ibuf == NULL) {
- ED_space_image_release_buffer(sima, lock);
+ ED_space_image_release_buffer(sima, ibuf, lock);
return FALSE;
}
@@ -2058,7 +2067,7 @@ int ED_space_image_color_sample(SpaceImage *sima, ARegion *ar, int mval[2], floa
}
}
- ED_space_image_release_buffer(sima, lock);
+ ED_space_image_release_buffer(sima, ibuf, lock);
return ret;
}
@@ -2074,7 +2083,7 @@ static void image_sample_apply(bContext *C, wmOperator *op, wmEvent *event)
CurveMapping *curve_mapping = scene->view_settings.curve_mapping;
if (ibuf == NULL) {
- ED_space_image_release_buffer(sima, lock);
+ ED_space_image_release_buffer(sima, ibuf, lock);
info->draw = 0;
return;
}
@@ -2175,7 +2184,7 @@ static void image_sample_apply(bContext *C, wmOperator *op, wmEvent *event)
info->draw = 0;
}
- ED_space_image_release_buffer(sima, lock);
+ ED_space_image_release_buffer(sima, ibuf, lock);
ED_area_tag_redraw(CTX_wm_area(C));
}
@@ -2266,12 +2275,12 @@ static int image_sample_line_exec(bContext *C, wmOperator *op)
float x1f, y1f, x2f, y2f;
if (ibuf == NULL) {
- ED_space_image_release_buffer(sima, lock);
+ ED_space_image_release_buffer(sima, ibuf, lock);
return OPERATOR_CANCELLED;
}
/* hmmmm */
if (ibuf->channels < 3) {
- ED_space_image_release_buffer(sima, lock);
+ ED_space_image_release_buffer(sima, ibuf, lock);
return OPERATOR_CANCELLED;
}
@@ -2288,7 +2297,7 @@ static int image_sample_line_exec(bContext *C, wmOperator *op)
/* reset y zoom */
hist->ymax = 1.0f;
- ED_space_image_release_buffer(sima, lock);
+ ED_space_image_release_buffer(sima, ibuf, lock);
ED_area_tag_redraw(CTX_wm_area(C));
@@ -2383,11 +2392,13 @@ static int image_record_composite_apply(bContext *C, wmOperator *op)
ED_area_tag_redraw(CTX_wm_area(C));
- ibuf = BKE_image_get_ibuf(sima->image, &sima->iuser);
+ ibuf = BKE_image_acquire_ibuf(sima->image, &sima->iuser, NULL);
/* save memory in flipbooks */
if (ibuf)
imb_freerectfloatImBuf(ibuf);
-
+
+ BKE_image_release_ibuf(sima->image, ibuf, NULL);
+
scene->r.cfra++;
return (scene->r.cfra <= rcd->efra);
diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c
index f0b3e70f359..7eff00d3882 100644
--- a/source/blender/editors/space_image/space_image.c
+++ b/source/blender/editors/space_image/space_image.c
@@ -779,7 +779,7 @@ static void image_scope_area_draw(const bContext *C, ARegion *ar)
}
scopes_update(&sima->scopes, ibuf, &scene->view_settings, &scene->display_settings);
}
- ED_space_image_release_buffer(sima, lock);
+ ED_space_image_release_buffer(sima, ibuf, lock);
ED_region_panels(C, ar, 1, NULL, -1);
}
diff --git a/source/blender/editors/space_info/info_ops.c b/source/blender/editors/space_info/info_ops.c
index 131908bc9db..48b5eaf7b44 100644
--- a/source/blender/editors/space_info/info_ops.c
+++ b/source/blender/editors/space_info/info_ops.c
@@ -87,10 +87,14 @@ static int pack_all_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
// first check for dirty images
for (ima = bmain->image.first; ima; ima = ima->id.next) {
if (ima->ibufs.first) { /* XXX FIX */
- ibuf = BKE_image_get_ibuf(ima, NULL);
+ ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
- if (ibuf && (ibuf->userflags & IB_BITMAPDIRTY))
+ if (ibuf && (ibuf->userflags & IB_BITMAPDIRTY)) {
+ BKE_image_release_ibuf(ima, ibuf, NULL);
break;
+ }
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
}
}
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index e5cc6bf4bc7..bd6639c6575 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -400,29 +400,15 @@ static void node_buts_curvecol(uiLayout *layout, bContext *UNUSED(C), PointerRNA
uiTemplateCurveMapping(layout, ptr, "mapping", 'c', 0, 0);
}
-static void node_normal_cb(bContext *C, void *ntree_v, void *node_v)
-{
- Main *bmain = CTX_data_main(C);
-
- ED_node_generic_update(bmain, ntree_v, node_v);
- WM_event_add_notifier(C, NC_NODE|NA_EDITED, ntree_v);
-}
-
static void node_buts_normal(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
- uiBlock *block= uiLayoutAbsoluteBlock(layout);
- bNodeTree *ntree= ptr->id.data;
- bNode *node= ptr->data;
- rctf *butr= &node->butr;
+ bNodeTree *ntree = (bNodeTree*)ptr->id.data;
+ bNode *node = (bNode*)ptr->data;
bNodeSocket *sock= node->outputs.first; /* first socket stores normal */
- float *nor= ((bNodeSocketValueVector*)sock->default_value)->value;
- uiBut *bt;
-
- bt= uiDefButF(block, BUT_NORMAL, B_NODE_EXEC, "",
- (int)butr->xmin, (int)butr->xmin,
- (short)BLI_rctf_size_x(butr), (short)BLI_rctf_size_x(butr),
- nor, 0.0f, 1.0f, 0, 0, "");
- uiButSetFunc(bt, node_normal_cb, ntree, node);
+ PointerRNA sockptr;
+
+ RNA_pointer_create(&ntree->id, &RNA_NodeSocket, sock, &sockptr);
+ uiItemR(layout, &sockptr, "default_value", 0, "", ICON_NONE);
}
#if 0 /* not used in 2.5x yet */
static void node_browse_tex_cb(bContext *C, void *ntree_v, void *node_v)
@@ -1486,9 +1472,10 @@ static void node_shader_buts_script_details(uiLayout *layout, bContext *C, Point
node_shader_buts_script(layout, C, ptr);
- /* not implemented yet
+#if 0 /* not implemented yet */
if (RNA_enum_get(ptr, "mode") == NODE_SCRIPT_EXTERNAL)
- uiItemR(layout, ptr, "use_auto_update", 0, NULL, ICON_NONE);*/
+ uiItemR(layout, ptr, "use_auto_update", 0, NULL, ICON_NONE);
+#endif
}
/* only once called */
@@ -1888,6 +1875,14 @@ static void node_composit_buts_double_edge_mask(uiLayout *layout, bContext *UNUS
uiItemR(col, ptr, "edge_mode", 0, "", ICON_NONE);
}
+static void node_composit_buts_map_range(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiLayout *col;
+
+ col = uiLayoutColumn(layout, TRUE);
+ uiItemR(col, ptr, "use_clamp", 0, NULL, ICON_NONE);
+}
+
static void node_composit_buts_map_value(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiLayout *sub, *col;
@@ -2826,6 +2821,9 @@ static void node_composit_set_butfunc(bNodeType *ntype)
case CMP_NODE_MAP_VALUE:
ntype->uifunc= node_composit_buts_map_value;
break;
+ case CMP_NODE_MAP_RANGE:
+ ntype->uifunc = node_composit_buts_map_range;
+ break;
case CMP_NODE_TIME:
ntype->uifunc= node_buts_time;
break;
@@ -3303,7 +3301,7 @@ void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode)
gpuPopMatrix();
}
- BKE_image_release_ibuf(ima, lock);
+ BKE_image_release_ibuf(ima, ibuf, lock);
}
}
@@ -3316,7 +3314,7 @@ static void draw_nodespace_back_tex(ScrArea *sa, SpaceNode *snode)
if (snode->flag & SNODE_BACKDRAW) {
Image *ima= BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node");
- ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
if (ibuf) {
int x, y;
float zoom = 1.0;
@@ -3352,6 +3350,8 @@ static void draw_nodespace_back_tex(ScrArea *sa, SpaceNode *snode)
gpuPopMatrix();
gpuMatrixMode(GL_MODELVIEW);
gpuPopMatrix();
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
}
}
}
diff --git a/source/blender/editors/space_node/node_group.c b/source/blender/editors/space_node/node_group.c
index 5f8b5db7766..4dd9c89375d 100644
--- a/source/blender/editors/space_node/node_group.c
+++ b/source/blender/editors/space_node/node_group.c
@@ -29,13 +29,18 @@
* \ingroup spnode
*/
+#include <stdlib.h>
+
#include "MEM_guardedalloc.h"
#include "DNA_node_types.h"
#include "DNA_object_types.h"
#include "DNA_anim_types.h"
-#include "BLI_blenlib.h"
+#include "BLI_listbase.h"
+#include "BLI_string.h"
+#include "BLI_rect.h"
+#include "BLI_math.h"
#include "BKE_action.h"
#include "BKE_animsys.h"
@@ -865,7 +870,7 @@ static void node_get_selected_minmax(bNodeTree *ntree, bNode *gnode, float *min,
if (node == gnode)
continue;
if (node->flag & NODE_SELECT) {
- DO_MINMAX2((&node->locx), min, max);
+ minmax_v2v2_v2(min, max, &node->locx);
}
}
}
diff --git a/source/blender/editors/space_node/node_view.c b/source/blender/editors/space_node/node_view.c
index ccf5c4b540f..f386657c460 100644
--- a/source/blender/editors/space_node/node_view.c
+++ b/source/blender/editors/space_node/node_view.c
@@ -241,7 +241,7 @@ static int snode_bg_viewmove_invoke(bContext *C, wmOperator *op, wmEvent *event)
ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock);
if (ibuf == NULL) {
- BKE_image_release_ibuf(ima, lock);
+ BKE_image_release_ibuf(ima, ibuf, lock);
return OPERATOR_CANCELLED;
}
@@ -255,7 +255,7 @@ static int snode_bg_viewmove_invoke(bContext *C, wmOperator *op, wmEvent *event)
nvm->ymin = -(ar->winy / 2) - (ibuf->y * (0.5f * snode->zoom)) + pad;
nvm->ymax = (ar->winy / 2) + (ibuf->y * (0.5f * snode->zoom)) - pad;
- BKE_image_release_ibuf(ima, lock);
+ BKE_image_release_ibuf(ima, ibuf, lock);
/* add modal handler */
WM_event_add_modal_handler(C, op);
@@ -330,6 +330,12 @@ typedef struct ImageSampleInfo {
unsigned char col[4];
float colf[4];
+
+ int z;
+ float zf;
+
+ int *zp;
+ float *zfp;
int draw;
int color_manage;
@@ -343,8 +349,7 @@ static void sample_draw(const bContext *C, ARegion *ar, void *arg_info)
if (info->draw) {
ED_image_draw_info(scene, ar, info->color_manage, FALSE, info->channels,
info->x, info->y, info->col, info->colf,
- NULL, NULL /* zbuf - unused for nodes */
- );
+ info->zp, info->zfp);
}
}
@@ -398,7 +403,7 @@ int ED_space_node_color_sample(SpaceNode *snode, ARegion *ar, int mval[2], float
}
}
- BKE_image_release_ibuf(ima, lock);
+ BKE_image_release_ibuf(ima, ibuf, lock);
return ret;
}
@@ -443,6 +448,9 @@ static void sample_apply(bContext *C, wmOperator *op, wmEvent *event)
info->draw = 1;
info->channels = ibuf->channels;
+ info->zp = NULL;
+ info->zfp = NULL;
+
if (ibuf->rect) {
cp = (unsigned char *)(ibuf->rect + y * ibuf->x + x);
@@ -468,6 +476,15 @@ static void sample_apply(bContext *C, wmOperator *op, wmEvent *event)
info->color_manage = TRUE;
}
+
+ if (ibuf->zbuf) {
+ info->z = ibuf->zbuf[y * ibuf->x + x];
+ info->zp = &info->z;
+ }
+ if (ibuf->zbuf_float) {
+ info->zf = ibuf->zbuf_float[y * ibuf->x + x];
+ info->zfp = &info->zf;
+ }
ED_node_sample_set(info->colf);
}
@@ -476,7 +493,7 @@ static void sample_apply(bContext *C, wmOperator *op, wmEvent *event)
ED_node_sample_set(NULL);
}
- BKE_image_release_ibuf(ima, lock);
+ BKE_image_release_ibuf(ima, ibuf, lock);
ED_area_tag_redraw(CTX_wm_area(C));
}
diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c
index 324d9e3e6fe..6cda8660c5b 100644
--- a/source/blender/editors/space_outliner/outliner_draw.c
+++ b/source/blender/editors/space_outliner/outliner_draw.c
@@ -1046,6 +1046,8 @@ static void tselem_draw_icon(uiBlock *block, int xmax, float x, float y, TreeSto
UI_icon_draw(x, y, ICON_MOD_WARP); break;
case eModifierType_Skin:
UI_icon_draw(x, y, ICON_MOD_SKIN); break;
+ case eModifierType_Triangulate:
+ UI_icon_draw(x, y, ICON_MOD_TRIANGULATE); break;
/* Default */
case eModifierType_None:
diff --git a/source/blender/editors/space_sequencer/SConscript b/source/blender/editors/space_sequencer/SConscript
index 0b429ae750b..bc72786fc5f 100644
--- a/source/blender/editors/space_sequencer/SConscript
+++ b/source/blender/editors/space_sequencer/SConscript
@@ -3,7 +3,7 @@ Import ('env')
sources = env.Glob('*.c')
-incs = '../include ../../blenlib ../../blenkernel ../../blenfont ../../makesdna ../../imbuf'
+incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf'
incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include'
incs += ' ../../makesrna ../../blenloader ../../blenfont'
incs += ' #/intern/audaspace/intern'
diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c
index dd57566ff91..7f0ae1d7680 100644
--- a/source/blender/editors/space_sequencer/sequencer_draw.c
+++ b/source/blender/editors/space_sequencer/sequencer_draw.c
@@ -837,6 +837,7 @@ ImBuf *sequencer_ibuf_get(struct Main *bmain, Scene *scene, SpaceSeq *sseq, int
int rectx, recty;
float render_size = 0.0;
float proxy_size = 100.0;
+ short is_break = G.is_break;
render_size = sseq->render_size;
if (render_size == 0) {
@@ -855,6 +856,11 @@ ImBuf *sequencer_ibuf_get(struct Main *bmain, Scene *scene, SpaceSeq *sseq, int
context = BKE_sequencer_new_render_data(bmain, scene, rectx, recty, proxy_size);
+ /* sequencer could start rendering, in this case we need to be sure it wouldn't be canceled
+ * by Esc pressed somewhere in the past
+ */
+ G.is_break = FALSE;
+
if (special_seq_update)
ibuf = BKE_sequencer_give_ibuf_direct(context, cfra + frame_ofs, special_seq_update);
else if (!U.prefetchframes) // XXX || (G.f & G_PLAYANIM) == 0) {
@@ -862,6 +868,9 @@ ImBuf *sequencer_ibuf_get(struct Main *bmain, Scene *scene, SpaceSeq *sseq, int
else
ibuf = BKE_sequencer_give_ibuf_threaded(context, cfra + frame_ofs, sseq->chanshown);
+ /* restore state so real rendering would be canceled (if needed) */
+ G.is_break = is_break;
+
return ibuf;
}
diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c
index 7270516aa51..00d4a943626 100644
--- a/source/blender/editors/space_sequencer/sequencer_edit.c
+++ b/source/blender/editors/space_sequencer/sequencer_edit.c
@@ -1686,7 +1686,7 @@ static int sequencer_delete_invoke(bContext *C, wmOperator *op, wmEvent *event)
if (ar->regiontype == RGN_TYPE_WINDOW) {
/* bounding box of 30 pixels is used for markers shortcuts,
- * prevent conflict with markers shortcurts here
+ * prevent conflict with markers shortcuts here
*/
if (event->mval[1] <= 30)
return OPERATOR_PASS_THROUGH;
diff --git a/source/blender/editors/space_text/space_text.c b/source/blender/editors/space_text/space_text.c
index f546c90c82c..1f806b78dc8 100644
--- a/source/blender/editors/space_text/space_text.c
+++ b/source/blender/editors/space_text/space_text.c
@@ -196,10 +196,6 @@ static void text_operatortypes(void)
WM_operatortype_append(TEXT_OT_unindent);
WM_operatortype_append(TEXT_OT_indent);
- WM_operatortype_append(TEXT_OT_markers_clear);
- WM_operatortype_append(TEXT_OT_next_marker);
- WM_operatortype_append(TEXT_OT_previous_marker);
-
WM_operatortype_append(TEXT_OT_select_line);
WM_operatortype_append(TEXT_OT_select_all);
WM_operatortype_append(TEXT_OT_select_word);
@@ -227,7 +223,6 @@ static void text_operatortypes(void)
WM_operatortype_append(TEXT_OT_find_set_selected);
WM_operatortype_append(TEXT_OT_replace);
WM_operatortype_append(TEXT_OT_replace_set_selected);
- WM_operatortype_append(TEXT_OT_mark_all);
WM_operatortype_append(TEXT_OT_to_3d_object);
diff --git a/source/blender/editors/space_text/text_draw.c b/source/blender/editors/space_text/text_draw.c
index d352e9f7b41..1818c4a5b31 100644
--- a/source/blender/editors/space_text/text_draw.c
+++ b/source/blender/editors/space_text/text_draw.c
@@ -764,7 +764,7 @@ static int text_draw_wrapped(SpaceText *st, const char *str, int x, int y, int w
buffer[len] = '\0';
text_font_draw(st, ox, y, buffer);
- y -= st->lheight;
+ y -= st->lheight + TXT_LINE_SPACING;
x = basex;
lines++;
start = end; mstart = mend;
@@ -1172,40 +1172,6 @@ int text_get_total_lines(SpaceText *st, ARegion *ar)
return drawcache->total_lines;
}
-/* Move pointer to first visible line (top) */
-static TextLine *first_visible_line(SpaceText *st, ARegion *ar, int *wrap_top)
-{
- Text *text = st->text;
- TextLine *pline = text->lines.first;
- int i = st->top, lineno = 0;
-
- text_update_drawcache(st, ar);
-
- if (wrap_top) *wrap_top = 0;
-
- if (st->wordwrap) {
- while (i > 0 && pline) {
- int lines = text_get_visible_lines_no(st, lineno);
-
- if (i - lines < 0) {
- if (wrap_top) *wrap_top = i;
- break;
- }
- else {
- pline = pline->next;
- i -= lines;
- lineno++;
- }
- }
- }
- else {
- for (i = st->top; pline->next && i > 0; i--)
- pline = pline->next;
- }
-
- return pline;
-}
-
/************************ draw scrollbar *****************************/
static void calc_text_rcts(SpaceText *st, ARegion *ar, rcti *scroll, rcti *back)
@@ -1343,94 +1309,6 @@ static void draw_textscroll(SpaceText *st, rcti *scroll, rcti *back)
glDisable(GL_BLEND);
}
-/************************** draw markers **************************/
-
-static void draw_markers(SpaceText *st, ARegion *ar)
-{
- Text *text = st->text;
- TextMarker *marker, *next;
- TextLine *top, *line;
- int offl, offc, i, x1, x2, y1, y2, x, y;
- int topi, topy;
-
- /* Move pointer to first visible line (top) */
- top = first_visible_line(st, ar, NULL);
- topi = BLI_findindex(&text->lines, top);
-
- topy = txt_get_span(text->lines.first, top);
-
- for (marker = text->markers.first; marker; marker = next) {
- next = marker->next;
-
- /* invisible line (before top) */
- if (marker->lineno < topi) continue;
-
- line = BLI_findlink(&text->lines, marker->lineno);
-
- /* Remove broken markers */
- if (marker->end > line->len || marker->start > marker->end) {
- BLI_freelinkN(&text->markers, marker);
- continue;
- }
-
- wrap_offset(st, ar, line, marker->start, &offl, &offc);
- y1 = txt_get_span(top, line) - st->top + offl + topy;
- x1 = text_get_char_pos(st, line->line, marker->start) - st->left + offc;
-
- wrap_offset(st, ar, line, marker->end, &offl, &offc);
- y2 = txt_get_span(top, line) - st->top + offl + topy;
- x2 = text_get_char_pos(st, line->line, marker->end) - st->left + offc;
-
- /* invisible part of line (before top, after last visible line) */
- if (y2 < 0 || y1 > st->top + st->viewlines) continue;
-
- gpuCurrentColor3ubv(marker->color);
- x = st->showlinenrs ? TXT_OFFSET + TEXTXLOC : TXT_OFFSET;
- y = ar->winy - 3;
-
- gpuImmediateFormat_V2();
-
- if (y1 == y2) {
- y -= y1 * st->lheight;
- gpuBegin(GL_LINE_LOOP);
- gpuVertex2i(x + x2 * st->cwidth + 1, y);
- gpuVertex2i(x + x1 * st->cwidth - 2, y);
- gpuVertex2i(x + x1 * st->cwidth - 2, y - st->lheight);
- gpuVertex2i(x + x2 * st->cwidth + 1, y - st->lheight);
- gpuEnd();
- }
- else {
- y -= y1 * st->lheight;
- gpuBegin(GL_LINE_STRIP);
- gpuVertex2i(ar->winx, y);
- gpuVertex2i(x + x1 * st->cwidth - 2, y);
- gpuVertex2i(x + x1 * st->cwidth - 2, y - st->lheight);
- gpuVertex2i(ar->winx, y - st->lheight);
- gpuEnd();
- y -= st->lheight;
-
- for (i = y1 + 1; i < y2; i++) {
- gpuBegin(GL_LINES);
- gpuVertex2i(x, y);
- gpuVertex2i(ar->winx, y);
- gpuVertex2i(x, y - st->lheight);
- gpuVertex2i(ar->winx, y - st->lheight);
- gpuEnd();
- y -= st->lheight;
- }
-
- gpuBegin(GL_LINE_STRIP);
- gpuVertex2i(x, y);
- gpuVertex2i(x + x2 * st->cwidth + 1, y);
- gpuVertex2i(x + x2 * st->cwidth + 1, y - st->lheight);
- gpuVertex2i(x, y - st->lheight);
- gpuEnd();
- }
-
- gpuImmediateUnformat();
- }
-}
-
/*********************** draw documentation *******************************/
static void draw_documentation(SpaceText *st, ARegion *ar)
@@ -1610,6 +1488,7 @@ static void draw_cursor(SpaceText *st, ARegion *ar)
Text *text = st->text;
int vcurl, vcurc, vsell, vselc, hidden = 0;
int x, y, w, i;
+ int lheight = st->lheight + TXT_LINE_SPACING;
/* Draw the selection */
if (text->curl != text->sell || text->curc != text->selc) {
@@ -1630,11 +1509,11 @@ static void draw_cursor(SpaceText *st, ARegion *ar)
y = ar->winy - 2;
if (vcurl == vsell) {
- y -= vcurl * st->lheight;
+ y -= vcurl * lheight;
if (vcurc < vselc)
- gpuSingleFilledRecti(x + vcurc * st->cwidth - 1, y, x + vselc * st->cwidth, y - st->lheight);
+ gpuSingleFilledRecti(x + vcurc * st->cwidth - 1, y, x + vselc * st->cwidth, y - st->lheight + TXT_LINE_SPACING);
else
- gpuSingleFilledRecti(x + vselc * st->cwidth - 1, y, x + vcurc * st->cwidth, y - st->lheight);
+ gpuSingleFilledRecti(x + vselc * st->cwidth - 1, y, x + vcurc * st->cwidth, y - st->lheight + TXT_LINE_SPACING);
}
else {
int froml, fromc, tol, toc;
@@ -1648,12 +1527,13 @@ static void draw_cursor(SpaceText *st, ARegion *ar)
fromc = vselc; toc = vcurc;
}
- y -= froml * st->lheight;
+ y -= froml * lheight;
gpuSingleFilledRecti(x + fromc * st->cwidth - 1, y, ar->winx, y - st->lheight);
y -= st->lheight;
+ for (i = froml + 1; i < tol; i++)
for (i = froml + 1; i < tol; i++) {
- gpuSingleFilledRecti(x - 4, y, ar->winx, y - st->lheight);
+ gpuSingleFilledRecti(x - 4, y, ar->winx, y - st->lheight + TXT_LINE_SPACING);
y -= st->lheight;
}
@@ -1681,12 +1561,12 @@ static void draw_cursor(SpaceText *st, ARegion *ar)
wrap_offset_in_line(st, ar, text->sell, text->selc, &offl, &offc);
- y1 = ar->winy - 2 - (vsell - offl) * st->lheight;
- y2 = y1 - st->lheight * visible_lines + 1;
+ y1 = ar->winy - 2 - (vsell - offl) * lheight;
+ y2 = y1 - lheight * visible_lines + 1;
}
else {
- y1 = ar->winy - 2 - vsell * st->lheight;
- y2 = y1 - st->lheight + 1;
+ y1 = ar->winy - 2 - vsell * lheight;
+ y2 = y1 - lheight + 1;
}
if (!(y1 < 0 || y2 > ar->winy)) { /* check we need to draw */
@@ -1696,7 +1576,7 @@ static void draw_cursor(SpaceText *st, ARegion *ar)
gpuCurrentColor4x(CPACK_WHITE, 0.125f);
glEnable(GL_BLEND);
- gpuSingleFilledRecti(x1 - 4, y1, x2, y2);
+ gpuSingleFilledRecti(x1 - 4, y1, x2, y2 + TXT_LINE_SPACING);
glDisable(GL_BLEND);
}
}
@@ -1705,20 +1585,21 @@ static void draw_cursor(SpaceText *st, ARegion *ar)
/* Draw the cursor itself (we draw the sel. cursor as this is the leading edge) */
x = st->showlinenrs ? TXT_OFFSET + TEXTXLOC : TXT_OFFSET;
x += vselc * st->cwidth;
- y = ar->winy - 2 - vsell * st->lheight;
+ y = ar->winy - 2 - vsell * lheight;
if (st->overwrite) {
char ch = text->sell->line[text->selc];
+ y += TXT_LINE_SPACING;
w = st->cwidth;
if (ch == '\t') w *= st->tabnumber - (vselc + st->left) % st->tabnumber;
UI_ThemeColor(TH_HILITE);
- gpuSingleFilledRecti(x, y - st->lheight - 1, x + w, y - st->lheight + 1);
+ gpuSingleFilledRecti(x, y - lheight - 1, x + w, y - lheight + 1);
}
else {
UI_ThemeColor(TH_HILITE);
- gpuSingleFilledRecti(x - 1, y, x + 1, y - st->lheight);
+ gpuSingleFilledRecti(x - 1, y, x + 1, y - lheight + TXT_LINE_SPACING);
}
}
}
@@ -1833,8 +1714,8 @@ static void draw_brackets(SpaceText *st, ARegion *ar)
if (viewc >= 0) {
viewl = txt_get_span(text->lines.first, startl) - st->top + offl;
- text_font_draw_character(st, x + viewc * st->cwidth, y - viewl * st->lheight, ch);
- text_font_draw_character(st, x + viewc * st->cwidth + 1, y - viewl * st->lheight, ch);
+ text_font_draw_character(st, x + viewc * st->cwidth, y - viewl * (st->lheight + TXT_LINE_SPACING), ch);
+ text_font_draw_character(st, x + viewc * st->cwidth + 1, y - viewl * (st->lheight + TXT_LINE_SPACING), ch);
}
/* draw closing bracket */
@@ -1845,8 +1726,8 @@ static void draw_brackets(SpaceText *st, ARegion *ar)
if (viewc >= 0) {
viewl = txt_get_span(text->lines.first, endl) - st->top + offl;
- text_font_draw_character(st, x + viewc * st->cwidth, y - viewl * st->lheight, ch);
- text_font_draw_character(st, x + viewc * st->cwidth + 1, y - viewl * st->lheight, ch);
+ text_font_draw_character(st, x + viewc * st->cwidth, y - viewl * (st->lheight + TXT_LINE_SPACING), ch);
+ text_font_draw_character(st, x + viewc * st->cwidth + 1, y - viewl * (st->lheight + TXT_LINE_SPACING), ch);
}
}
@@ -1862,7 +1743,7 @@ void draw_text_main(SpaceText *st, ARegion *ar)
int wraplinecount = 0, wrap_skip = 0;
int margin_column_x;
- if (st->lheight) st->viewlines = (int)ar->winy / st->lheight;
+ if (st->lheight) st->viewlines = (int)ar->winy / (st->lheight + TXT_LINE_SPACING);
else st->viewlines = 0;
/* if no text, nothing to do */
@@ -1955,14 +1836,14 @@ void draw_text_main(SpaceText *st, ARegion *ar)
if (st->wordwrap) {
/* draw word wrapped text */
int lines = text_draw_wrapped(st, tmp->line, x, y, winx - x, tmp->format, wrap_skip);
- y -= lines * st->lheight;
+ y -= lines * (st->lheight + TXT_LINE_SPACING);
}
else {
/* draw unwrapped text */
text_draw(st, tmp->line, st->left, ar->winx / st->cwidth, 1, x, y, tmp->format);
- y -= st->lheight;
+ y -= st->lheight + TXT_LINE_SPACING;
}
-
+
wrap_skip = 0;
}
@@ -1987,7 +1868,6 @@ void draw_text_main(SpaceText *st, ARegion *ar)
/* draw other stuff */
draw_brackets(st, ar);
- draw_markers(st, ar);
gpuTranslate(GLA_PIXEL_OFS, GLA_PIXEL_OFS, 0.0f); /* XXX scroll requires exact pixel space */
draw_textscroll(st, &scroll, &back);
draw_documentation(st, ar);
diff --git a/source/blender/editors/space_text/text_intern.h b/source/blender/editors/space_text/text_intern.h
index 4f973e7076b..ea61644cee9 100644
--- a/source/blender/editors/space_text/text_intern.h
+++ b/source/blender/editors/space_text/text_intern.h
@@ -57,6 +57,7 @@ void text_update_cursor_moved(struct bContext *C);
#define TXT_OFFSET 15
#define TXT_SCROLL_WIDTH 20
#define TXT_SCROLL_SPACE 2
+#define TXT_LINE_SPACING 4 /* space between lines */
#define TEXTXLOC (st->cwidth * st->linenrs_tot)
@@ -68,9 +69,6 @@ void text_update_cursor_moved(struct bContext *C);
#define TOOL_SUGG_LIST 0x01
#define TOOL_DOCUMENT 0x02
-#define TMARK_GRP_CUSTOM 0x00010000 /* Lower 2 bytes used for Python groups */
-#define TMARK_GRP_FINDALL 0x00020000
-
typedef struct FlattenString {
char fixedbuf[256];
int fixedaccum[256];
@@ -129,10 +127,6 @@ void TEXT_OT_indent(struct wmOperatorType *ot);
void TEXT_OT_line_break(struct wmOperatorType *ot);
void TEXT_OT_insert(struct wmOperatorType *ot);
-void TEXT_OT_markers_clear(struct wmOperatorType *ot);
-void TEXT_OT_next_marker(struct wmOperatorType *ot);
-void TEXT_OT_previous_marker(struct wmOperatorType *ot);
-
void TEXT_OT_select_line(struct wmOperatorType *ot);
void TEXT_OT_select_all(struct wmOperatorType *ot);
void TEXT_OT_select_word(struct wmOperatorType *ot);
@@ -157,7 +151,6 @@ void TEXT_OT_find(struct wmOperatorType *ot);
void TEXT_OT_find_set_selected(struct wmOperatorType *ot);
void TEXT_OT_replace(struct wmOperatorType *ot);
void TEXT_OT_replace_set_selected(struct wmOperatorType *ot);
-void TEXT_OT_mark_all(struct wmOperatorType *ot);
void TEXT_OT_to_3d_object(struct wmOperatorType *ot);
diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c
index 1be50a54b68..cd6d8719544 100644
--- a/source/blender/editors/space_text/text_ops.c
+++ b/source/blender/editors/space_text/text_ops.c
@@ -1135,7 +1135,8 @@ static int text_convert_whitespace_exec(bContext *C, wmOperator *op)
tmp = text->lines.first;
- //first convert to all space, this make it a lot easier to convert to tabs because there is no mixtures of ' ' && '\t'
+ /* first convert to all space, this make it a lot easier to convert to tabs
+ * because there is no mixtures of ' ' && '\t' */
while (tmp) {
text_check_line = tmp->line;
number = flatten_string(st, &fs, text_check_line) + 1;
@@ -1376,104 +1377,6 @@ void TEXT_OT_move_lines(wmOperatorType *ot)
RNA_def_enum(ot->srna, "direction", direction_items, 1, "Direction", "");
}
-/******************* previous marker operator *********************/
-
-static int text_previous_marker_exec(bContext *C, wmOperator *UNUSED(op))
-{
- Text *text = CTX_data_edit_text(C);
- TextMarker *mrk;
- int lineno;
-
- lineno = txt_get_span(text->lines.first, text->curl);
- mrk = text->markers.last;
- while (mrk && (mrk->lineno > lineno || (mrk->lineno == lineno && mrk->end > text->curc)))
- mrk = mrk->prev;
- if (!mrk) mrk = text->markers.last;
- if (mrk) {
- txt_move_to(text, mrk->lineno, mrk->start, 0);
- txt_move_to(text, mrk->lineno, mrk->end, 1);
- }
-
- text_update_cursor_moved(C);
- WM_event_add_notifier(C, NC_TEXT | NA_EDITED, text);
-
- return OPERATOR_FINISHED;
-}
-
-void TEXT_OT_previous_marker(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name = "Previous Marker";
- ot->idname = "TEXT_OT_previous_marker";
- ot->description = "Move to previous marker";
-
- /* api callbacks */
- ot->exec = text_previous_marker_exec;
- ot->poll = text_edit_poll;
-}
-
-/******************* next marker operator *********************/
-
-static int text_next_marker_exec(bContext *C, wmOperator *UNUSED(op))
-{
- Text *text = CTX_data_edit_text(C);
- TextMarker *mrk;
- int lineno;
-
- lineno = txt_get_span(text->lines.first, text->curl);
- mrk = text->markers.first;
- while (mrk && (mrk->lineno < lineno || (mrk->lineno == lineno && mrk->start <= text->curc)))
- mrk = mrk->next;
- if (!mrk) mrk = text->markers.first;
- if (mrk) {
- txt_move_to(text, mrk->lineno, mrk->start, 0);
- txt_move_to(text, mrk->lineno, mrk->end, 1);
- }
-
- text_update_cursor_moved(C);
- WM_event_add_notifier(C, NC_TEXT | NA_EDITED, text);
-
- return OPERATOR_FINISHED;
-}
-
-void TEXT_OT_next_marker(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name = "Next Marker";
- ot->idname = "TEXT_OT_next_marker";
- ot->description = "Move to next marker";
-
- /* api callbacks */
- ot->exec = text_next_marker_exec;
- ot->poll = text_edit_poll;
-}
-
-/******************* clear all markers operator *********************/
-
-static int text_clear_all_markers_exec(bContext *C, wmOperator *UNUSED(op))
-{
- Text *text = CTX_data_edit_text(C);
-
- txt_clear_markers(text, 0, 0);
-
- text_update_cursor_moved(C);
- WM_event_add_notifier(C, NC_TEXT | NA_EDITED, text);
-
- return OPERATOR_FINISHED;
-}
-
-void TEXT_OT_markers_clear(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name = "Clear All Markers";
- ot->idname = "TEXT_OT_markers_clear";
- ot->description = "Clear all markers";
-
- /* api callbacks */
- ot->exec = text_clear_all_markers_exec;
- ot->poll = text_edit_poll;
-}
-
/************************ move operator ************************/
static EnumPropertyItem move_type_items[] = {
@@ -1664,16 +1567,15 @@ static void txt_wrap_move_bol(SpaceText *st, ARegion *ar, short sel)
Text *text = st->text;
TextLine **linep;
int *charp;
- int oldl, oldc, i, j, max, start, end, endj, chop, loop;
+ int oldc, i, j, max, start, end, endj, chop, loop;
char ch;
text_update_character_width(st);
- if (sel) linep = &text->sell, charp = &text->selc;
- else linep = &text->curl, charp = &text->curc;
+ if (sel) { linep = &text->sell; charp = &text->selc; }
+ else { linep = &text->curl; charp = &text->curc; }
oldc = *charp;
- oldl = txt_get_span(text->lines.first, *linep);
max = wrap_width(st, ar);
@@ -1724,7 +1626,6 @@ static void txt_wrap_move_bol(SpaceText *st, ARegion *ar, short sel)
}
if (!sel) txt_pop_sel(text);
- txt_undo_add_toop(text, sel ? UNDO_STO : UNDO_CTO, oldl, oldc, oldl, *charp);
}
static void txt_wrap_move_eol(SpaceText *st, ARegion *ar, short sel)
@@ -1732,16 +1633,15 @@ static void txt_wrap_move_eol(SpaceText *st, ARegion *ar, short sel)
Text *text = st->text;
TextLine **linep;
int *charp;
- int oldl, oldc, i, j, max, start, end, endj, chop, loop;
+ int oldc, i, j, max, start, end, endj, chop, loop;
char ch;
text_update_character_width(st);
- if (sel) linep = &text->sell, charp = &text->selc;
- else linep = &text->curl, charp = &text->curc;
+ if (sel) { linep = &text->sell; charp = &text->selc; }
+ else { linep = &text->curl; charp = &text->curc; }
oldc = *charp;
- oldl = txt_get_span(text->lines.first, *linep);
max = wrap_width(st, ar);
@@ -1790,7 +1690,6 @@ static void txt_wrap_move_eol(SpaceText *st, ARegion *ar, short sel)
}
if (!sel) txt_pop_sel(text);
- txt_undo_add_toop(text, sel ? UNDO_STO : UNDO_CTO, oldl, oldc, oldl, *charp);
}
static void txt_wrap_move_up(SpaceText *st, ARegion *ar, short sel)
@@ -1798,22 +1697,17 @@ static void txt_wrap_move_up(SpaceText *st, ARegion *ar, short sel)
Text *text = st->text;
TextLine **linep;
int *charp;
- int oldl, oldc, offl, offc, col, newl;
+ int offl, offc, col;
text_update_character_width(st);
- if (sel) linep = &text->sell, charp = &text->selc;
- else linep = &text->curl, charp = &text->curc;
-
- /* store previous position */
- oldc = *charp;
- newl = oldl = txt_get_span(text->lines.first, *linep);
+ if (sel) { linep = &text->sell; charp = &text->selc; }
+ else { linep = &text->curl; charp = &text->curc; }
wrap_offset_in_line(st, ar, *linep, *charp, &offl, &offc);
col = text_get_char_pos(st, (*linep)->line, *charp) + offc;
if (offl) {
*charp = text_get_cursor_rel(st, ar, *linep, offl - 1, col);
- newl = BLI_findindex(&text->lines, linep);
}
else {
if ((*linep)->prev) {
@@ -1822,13 +1716,11 @@ static void txt_wrap_move_up(SpaceText *st, ARegion *ar, short sel)
*linep = (*linep)->prev;
visible_lines = text_get_visible_lines(st, ar, (*linep)->line);
*charp = text_get_cursor_rel(st, ar, *linep, visible_lines - 1, col);
- newl--;
}
else *charp = 0;
}
if (!sel) txt_pop_sel(text);
- txt_undo_add_toop(text, sel ? UNDO_STO : UNDO_CTO, oldl, oldc, newl, *charp);
}
static void txt_wrap_move_down(SpaceText *st, ARegion *ar, short sel)
@@ -1836,35 +1728,28 @@ static void txt_wrap_move_down(SpaceText *st, ARegion *ar, short sel)
Text *text = st->text;
TextLine **linep;
int *charp;
- int oldl, oldc, offl, offc, col, newl, visible_lines;
+ int offl, offc, col, visible_lines;
text_update_character_width(st);
- if (sel) linep = &text->sell, charp = &text->selc;
- else linep = &text->curl, charp = &text->curc;
-
- /* store previous position */
- oldc = *charp;
- newl = oldl = txt_get_span(text->lines.first, *linep);
+ if (sel) { linep = &text->sell; charp = &text->selc; }
+ else { linep = &text->curl; charp = &text->curc; }
wrap_offset_in_line(st, ar, *linep, *charp, &offl, &offc);
col = text_get_char_pos(st, (*linep)->line, *charp) + offc;
visible_lines = text_get_visible_lines(st, ar, (*linep)->line);
if (offl < visible_lines - 1) {
*charp = text_get_cursor_rel(st, ar, *linep, offl + 1, col);
- newl = BLI_findindex(&text->lines, linep);
}
else {
if ((*linep)->next) {
*linep = (*linep)->next;
*charp = text_get_cursor_rel(st, ar, *linep, 0, col);
- newl++;
}
else *charp = (*linep)->len;
}
if (!sel) txt_pop_sel(text);
- txt_undo_add_toop(text, sel ? UNDO_STO : UNDO_CTO, oldl, oldc, newl, *charp);
}
/* Moves the cursor vertically by the specified number of lines.
@@ -1876,12 +1761,10 @@ static void txt_wrap_move_down(SpaceText *st, ARegion *ar, short sel)
static void cursor_skip(SpaceText *st, ARegion *ar, Text *text, int lines, int sel)
{
TextLine **linep;
- int oldl, oldc, *charp;
+ int *charp;
- if (sel) linep = &text->sell, charp = &text->selc;
- else linep = &text->curl, charp = &text->curc;
- oldl = txt_get_span(text->lines.first, *linep);
- oldc = *charp;
+ if (sel) { linep = &text->sell; charp = &text->selc; }
+ else { linep = &text->curl; charp = &text->curc; }
if (st && ar && st->wordwrap) {
int rell, relc;
@@ -1904,7 +1787,6 @@ static void cursor_skip(SpaceText *st, ARegion *ar, Text *text, int lines, int s
if (*charp > (*linep)->len) *charp = (*linep)->len;
if (!sel) txt_pop_sel(text);
- txt_undo_add_toop(text, sel ? UNDO_STO : UNDO_CTO, oldl, oldc, txt_get_span(text->lines.first, *linep), *charp);
}
static int text_move_cursor(bContext *C, int type, int select)
@@ -2222,10 +2104,10 @@ static void text_scroll_apply(bContext *C, wmOperator *op, wmEvent *event)
if (!tsc->scrollbar) {
txtdelta[0] = -tsc->delta[0] / st->cwidth;
- txtdelta[1] = tsc->delta[1] / st->lheight;
+ txtdelta[1] = tsc->delta[1] / (st->lheight + TXT_LINE_SPACING);
tsc->delta[0] %= st->cwidth;
- tsc->delta[1] %= st->lheight;
+ tsc->delta[1] %= (st->lheight + TXT_LINE_SPACING);
}
else {
txtdelta[1] = -tsc->delta[1] * st->pix_per_line;
@@ -2611,7 +2493,7 @@ static void text_cursor_set_to_pos_wrapped(SpaceText *st, ARegion *ar, int x, in
if (linep && charp != -1) {
if (sel) { text->sell = linep; text->selc = charp; }
- else { text->curl = linep; text->curc = charp; }
+ else { text->curl = linep; text->curc = charp; }
}
}
@@ -2619,7 +2501,7 @@ static void text_cursor_set_to_pos(SpaceText *st, ARegion *ar, int x, int y, int
{
Text *text = st->text;
text_update_character_width(st);
- y = (ar->winy - 2 - y) / st->lheight;
+ y = (ar->winy - 2 - y) / (st->lheight + TXT_LINE_SPACING);
if (st->showlinenrs) x -= TXT_OFFSET + TEXTXLOC;
else x -= TXT_OFFSET;
@@ -2636,7 +2518,7 @@ static void text_cursor_set_to_pos(SpaceText *st, ARegion *ar, int x, int y, int
int w;
if (sel) { linep = &text->sell; charp = &text->selc; }
- else { linep = &text->curl; charp = &text->curc; }
+ else { linep = &text->curl; charp = &text->curc; }
y -= txt_get_span(text->lines.first, *linep) - st->top;
@@ -2696,7 +2578,6 @@ static void text_cursor_set_exit(bContext *C, wmOperator *op)
SpaceText *st = CTX_wm_space_text(C);
Text *text = st->text;
SetSelection *ssel = op->customdata;
- int linep2, charp2;
char *buffer;
if (txt_has_sel(text)) {
@@ -2705,12 +2586,6 @@ static void text_cursor_set_exit(bContext *C, wmOperator *op)
MEM_freeN(buffer);
}
- linep2 = txt_get_span(st->text->lines.first, st->text->sell);
- charp2 = st->text->selc;
-
- if (ssel->sell != linep2 || ssel->selc != charp2)
- txt_undo_add_toop(st->text, UNDO_STO, ssel->sell, ssel->selc, linep2, charp2);
-
text_update_cursor_moved(C);
WM_event_add_notifier(C, NC_TEXT | ND_CURSOR, st->text);
@@ -2786,19 +2661,12 @@ void TEXT_OT_selection_set(wmOperatorType *ot)
static int text_cursor_set_exec(bContext *C, wmOperator *op)
{
SpaceText *st = CTX_wm_space_text(C);
- Text *text = st->text;
ARegion *ar = CTX_wm_region(C);
int x = RNA_int_get(op->ptr, "x");
int y = RNA_int_get(op->ptr, "y");
- int oldl, oldc;
-
- oldl = txt_get_span(text->lines.first, text->curl);
- oldc = text->curc;
text_cursor_set_to_pos(st, ar, x, y, 0);
- txt_undo_add_toop(text, UNDO_CTO, oldl, oldc, txt_get_span(text->lines.first, text->curl), text->curc);
-
text_update_cursor_moved(C);
WM_event_add_notifier(C, NC_TEXT | ND_CURSOR, st->text);
@@ -2990,14 +2858,13 @@ void TEXT_OT_insert(wmOperatorType *ot)
/* mode */
#define TEXT_FIND 0
#define TEXT_REPLACE 1
-#define TEXT_MARK_ALL 2
static int text_find_and_replace(bContext *C, wmOperator *op, short mode)
{
Main *bmain = CTX_data_main(C);
SpaceText *st = CTX_wm_space_text(C);
- Text *start = NULL, *text = st->text;
- int flags, first = 1;
+ Text *text = st->text;
+ int flags;
int found = 0;
char *tmp;
@@ -3006,79 +2873,48 @@ static int text_find_and_replace(bContext *C, wmOperator *op, short mode)
flags = st->flags;
if (flags & ST_FIND_ALL)
- flags ^= ST_FIND_WRAP;
-
- do {
- int proceed = 0;
+ flags &= ~ST_FIND_WRAP;
- if (first) {
- if (text->markers.first)
- WM_event_add_notifier(C, NC_TEXT | NA_EDITED, text);
+ /* Replace current */
+ if (mode != TEXT_FIND && txt_has_sel(text)) {
+ tmp = txt_sel_to_buf(text);
- txt_clear_markers(text, TMARK_GRP_FINDALL, 0);
- }
+ if (flags & ST_MATCH_CASE) found = strcmp(st->findstr, tmp) == 0;
+ else found = BLI_strcasecmp(st->findstr, tmp) == 0;
- first = 0;
-
- /* Replace current */
- if (mode != TEXT_FIND && txt_has_sel(text)) {
- tmp = txt_sel_to_buf(text);
-
- if (flags & ST_MATCH_CASE) proceed = strcmp(st->findstr, tmp) == 0;
- else proceed = BLI_strcasecmp(st->findstr, tmp) == 0;
-
- if (proceed) {
- if (mode == TEXT_REPLACE) {
- txt_insert_buf(text, st->replacestr);
- if (text->curl && text->curl->format) {
- MEM_freeN(text->curl->format);
- text->curl->format = NULL;
- }
- text_update_cursor_moved(C);
- WM_event_add_notifier(C, NC_TEXT | NA_EDITED, text);
- text_drawcache_tag_update(CTX_wm_space_text(C), 1);
- }
- else if (mode == TEXT_MARK_ALL) {
- unsigned char color[4];
- UI_GetThemeColor4ubv(TH_SHADE2, color);
-
- if (txt_find_marker(text, text->curl, text->selc, TMARK_GRP_FINDALL, 0)) {
- if (tmp) MEM_freeN(tmp), tmp = NULL;
- break;
- }
-
- txt_add_marker(text, text->curl, text->curc, text->selc, color, TMARK_GRP_FINDALL, TMARK_EDITALL);
- text_update_cursor_moved(C);
- WM_event_add_notifier(C, NC_TEXT | NA_EDITED, text);
+ if (found) {
+ if (mode == TEXT_REPLACE) {
+ txt_insert_buf(text, st->replacestr);
+ if (text->curl && text->curl->format) {
+ MEM_freeN(text->curl->format);
+ text->curl->format = NULL;
}
+ text_update_cursor_moved(C);
+ WM_event_add_notifier(C, NC_TEXT | NA_EDITED, text);
+ text_drawcache_tag_update(CTX_wm_space_text(C), 1);
}
- MEM_freeN(tmp);
- tmp = NULL;
}
+ MEM_freeN(tmp);
+ tmp = NULL;
+ }
- /* Find next */
- if (txt_find_string(text, st->findstr, flags & ST_FIND_WRAP, flags & ST_MATCH_CASE)) {
- text_update_cursor_moved(C);
- WM_event_add_notifier(C, NC_TEXT | ND_CURSOR, text);
- }
- else if (flags & ST_FIND_ALL) {
- if (text == start) break;
- if (!start) start = text;
- if (text->id.next)
- text = st->text = text->id.next;
- else
- text = st->text = bmain->text.first;
- txt_move_toline(text, 0, 0);
- text_update_cursor_moved(C);
- WM_event_add_notifier(C, NC_TEXT | ND_CURSOR, text);
- first = 1;
- }
- else {
- if (!found && !proceed) BKE_reportf(op->reports, RPT_ERROR, "Text not found: %s", st->findstr);
- break;
- }
- found = 1;
- } while (mode == TEXT_MARK_ALL);
+ /* Find next */
+ if (txt_find_string(text, st->findstr, flags & ST_FIND_WRAP, flags & ST_MATCH_CASE)) {
+ text_update_cursor_moved(C);
+ WM_event_add_notifier(C, NC_TEXT | ND_CURSOR, text);
+ }
+ else if (flags & ST_FIND_ALL) {
+ if (text->id.next)
+ text = st->text = text->id.next;
+ else
+ text = st->text = bmain->text.first;
+ txt_move_toline(text, 0, 0);
+ text_update_cursor_moved(C);
+ WM_event_add_notifier(C, NC_TEXT | ND_CURSOR, text);
+ }
+ else {
+ if (!found) BKE_reportf(op->reports, RPT_ERROR, "Text not found: %s", st->findstr);
+ }
return OPERATOR_FINISHED;
}
@@ -3119,25 +2955,6 @@ void TEXT_OT_replace(wmOperatorType *ot)
ot->poll = text_space_edit_poll;
}
-/******************* mark all operator *********************/
-
-static int text_mark_all_exec(bContext *C, wmOperator *op)
-{
- return text_find_and_replace(C, op, TEXT_MARK_ALL);
-}
-
-void TEXT_OT_mark_all(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name = "Mark All";
- ot->idname = "TEXT_OT_mark_all";
- ot->description = "Mark all specified text";
-
- /* api callbacks */
- ot->exec = text_mark_all_exec;
- ot->poll = text_space_edit_poll;
-}
-
/******************* find set selected *********************/
static int text_find_set_selected_exec(bContext *C, wmOperator *op)
diff --git a/source/blender/editors/space_text/text_python.c b/source/blender/editors/space_text/text_python.c
index 966afe22e42..4c9b4b900cc 100644
--- a/source/blender/editors/space_text/text_python.c
+++ b/source/blender/editors/space_text/text_python.c
@@ -359,177 +359,3 @@ static short UNUSED_FUNCTION(do_texttools) (SpaceText * st, char ascii, unsigned
return swallow;
}
-
-static short UNUSED_FUNCTION(do_textmarkers) (SpaceText * st, char ascii, unsigned short evnt, short val)
-{
- Text *text;
- TextMarker *marker, *mrk, *nxt;
- int c, s, draw = 0, swallow = 0;
- int qual = 0; // XXX
-
- text = st->text;
- if (!text || text->id.lib || text->curl != text->sell) return 0;
-
- marker = txt_find_marker(text, text->sell, text->selc, 0, 0);
- if (marker && (marker->start > text->curc || marker->end < text->curc))
- marker = NULL;
-
- if (!marker) {
- /* Find the next temporary marker */
- if (evnt == TABKEY) {
- int lineno = txt_get_span(text->lines.first, text->curl);
- mrk = text->markers.first;
- while (mrk) {
- if (!marker && (mrk->flags & TMARK_TEMP)) marker = mrk;
- if ((mrk->flags & TMARK_TEMP) && (mrk->lineno > lineno || (mrk->lineno == lineno && mrk->end > text->curc))) {
- marker = mrk;
- break;
- }
- mrk = mrk->next;
- }
- if (marker) {
- txt_move_to(text, marker->lineno, marker->start, 0);
- txt_move_to(text, marker->lineno, marker->end, 1);
- // XXX text_update_cursor_moved(C);
- // XXX WM_event_add_notifier(C, NC_TEXT|ND_CURSOR, text);
- evnt = ascii = val = 0;
- draw = 1;
- swallow = 1;
- }
- }
- else if (evnt == ESCKEY) {
- if (txt_clear_markers(text, 0, TMARK_TEMP)) swallow = 1;
- else if (txt_clear_markers(text, 0, 0)) swallow = 1;
- else return 0;
- evnt = ascii = val = 0;
- draw = 1;
- }
- if (!swallow) return 0;
- }
-
- if (ascii) {
- if (marker->flags & TMARK_EDITALL) {
- c = text->curc - marker->start;
- s = text->selc - marker->start;
- if (s < 0 || s > marker->end - marker->start) return 0;
-
- mrk = txt_next_marker(text, marker);
- while (mrk) {
- nxt = txt_next_marker(text, mrk); /* mrk may become invalid */
- txt_move_to(text, mrk->lineno, mrk->start + c, 0);
- if (s != c) txt_move_to(text, mrk->lineno, mrk->start + s, 1);
- if (st->overwrite) {
- if (txt_replace_char(text, ascii))
- text_update_line_edited(st->text->curl);
- }
- else {
- if (txt_add_char(text, ascii)) {
- text_update_line_edited(st->text->curl);
- }
- }
-
- if (mrk == marker || mrk == nxt) break;
- mrk = nxt;
- }
- swallow = 1;
- draw = 1;
- }
- }
- else if (val) {
- switch (evnt) {
- case BACKSPACEKEY:
- if (marker->flags & TMARK_EDITALL) {
- c = text->curc - marker->start;
- s = text->selc - marker->start;
- if (s < 0 || s > marker->end - marker->start) return 0;
-
- mrk = txt_next_marker(text, marker);
- while (mrk) {
- nxt = txt_next_marker(text, mrk); /* mrk may become invalid */
- txt_move_to(text, mrk->lineno, mrk->start + c, 0);
- if (s != c) txt_move_to(text, mrk->lineno, mrk->start + s, 1);
- txt_backspace_char(text);
- text_update_line_edited(st->text->curl);
- if (mrk == marker || mrk == nxt) break;
- mrk = nxt;
- }
- swallow = 1;
- draw = 1;
- }
- break;
- case DELKEY:
- if (marker->flags & TMARK_EDITALL) {
- c = text->curc - marker->start;
- s = text->selc - marker->start;
- if (s < 0 || s > marker->end - marker->start) return 0;
-
- mrk = txt_next_marker(text, marker);
- while (mrk) {
- nxt = txt_next_marker(text, mrk); /* mrk may become invalid */
- txt_move_to(text, mrk->lineno, mrk->start + c, 0);
- if (s != c) txt_move_to(text, mrk->lineno, mrk->start + s, 1);
- txt_delete_char(text);
- text_update_line_edited(st->text->curl);
- if (mrk == marker || mrk == nxt) break;
- mrk = nxt;
- }
- swallow = 1;
- draw = 1;
- }
- break;
- case TABKEY:
- if (qual & LR_SHIFTKEY) {
- nxt = marker->prev;
- if (!nxt) nxt = text->markers.last;
- }
- else {
- nxt = marker->next;
- if (!nxt) nxt = text->markers.first;
- }
- if (marker->flags & TMARK_TEMP) {
- if (nxt == marker) nxt = NULL;
- BLI_freelinkN(&text->markers, marker);
- }
- mrk = nxt;
- if (mrk) {
- txt_move_to(text, mrk->lineno, mrk->start, 0);
- txt_move_to(text, mrk->lineno, mrk->end, 1);
- // XXX text_update_cursor_moved(C);
- // XXX WM_event_add_notifier(C, NC_TEXT|ND_CURSOR, text);
- }
- swallow = 1;
- draw = 1;
- break;
-
- /* Events that should clear markers */
- case UKEY: if (!(qual & LR_ALTKEY)) break;
- case ZKEY: if (evnt == ZKEY && !(qual & LR_CTRLKEY)) break;
- case RETKEY:
- case ESCKEY:
- if (marker->flags & (TMARK_EDITALL | TMARK_TEMP))
- txt_clear_markers(text, marker->group, 0);
- else
- BLI_freelinkN(&text->markers, marker);
- swallow = 1;
- draw = 1;
- break;
- case RIGHTMOUSE: /* Marker context menu? */
- case LEFTMOUSE:
- break;
- case FKEY: /* Allow find */
- if (qual & LR_SHIFTKEY) swallow = 1;
- break;
-
- default:
- if (qual != 0 && qual != LR_SHIFTKEY)
- swallow = 1; /* Swallow all other shortcut events */
- }
- }
-
- if (draw) {
- // XXX redraw_alltext();
- }
-
- return swallow;
-}
-
diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c
index 20d5e8ee69c..5d442aff84d 100644
--- a/source/blender/editors/space_view3d/drawmesh.c
+++ b/source/blender/editors/space_view3d/drawmesh.c
@@ -741,7 +741,7 @@ static void draw_mesh_text(Scene *scene, Object *ob, int glsl)
BKE_bproperty_set_valstr(prop, string);
characters = strlen(string);
- if (!BKE_image_get_ibuf(mtpoly->tpage, NULL))
+ if (!BKE_image_has_ibuf(mtpoly->tpage, NULL))
characters = 0;
if (!mf_smooth) {
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index 8cb4d1ff308..7cd432db661 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -462,7 +462,7 @@ void drawaxes(float size, char drawtype)
static void draw_empty_image(Object *ob, const short dflag, const unsigned char ob_wire_col[4])
{
Image *ima = (Image *)ob->data;
- ImBuf *ibuf = ima ? BKE_image_get_ibuf(ima, NULL) : NULL;
+ ImBuf *ibuf = ima ? BKE_image_acquire_ibuf(ima, NULL, NULL) : NULL;
float scale, ofs_x, ofs_y, sca_x, sca_y;
int ima_x, ima_y;
@@ -547,6 +547,8 @@ static void draw_empty_image(Object *ob, const short dflag, const unsigned char
/* Reset GL settings */
gpuMatrixMode(GL_MODELVIEW);
gpuPopMatrix();
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
}
/* circle for object centers, special_color is for library or ob users */
@@ -3551,9 +3553,12 @@ static int drawCurveDerivedMesh(Scene *scene, View3D *v3d, RegionView3D *rv3d, B
return 0;
}
-/* returns 1 when nothing was drawn */
-static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
- const short dt, const short dflag, const unsigned char ob_wire_col[4])
+/**
+ * Only called by #drawDispList
+ * \return 1 when nothing was drawn
+ */
+static int drawDispList_nobackface(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
+ const short dt, const short dflag, const unsigned char ob_wire_col[4])
{
Object *ob = base->object;
ListBase *lb = NULL;
@@ -3561,20 +3566,9 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas
Curve *cu;
const short render_only = (v3d->flag2 & V3D_RENDER_OVERRIDE);
const short solid = (dt > OB_WIRE);
- int retval = 0;
-
- /* backface culling */
- if (v3d->flag2 & V3D_BACKFACE_CULLING) {
- /* not all displists use same in/out normal direction convention */
- glEnable(GL_CULL_FACE);
- glCullFace((ob->type == OB_MBALL) ? GL_BACK : GL_FRONT);
- }
if (drawCurveDerivedMesh(scene, v3d, rv3d, base, dt) == 0) {
- if (v3d->flag2 & V3D_BACKFACE_CULLING)
- glDisable(GL_CULL_FACE);
-
- return 0;
+ return FALSE;
}
switch (ob->type) {
@@ -3586,7 +3580,9 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas
if (solid) {
dl = lb->first;
- if (dl == NULL) return 1;
+ if (dl == NULL) {
+ return TRUE;
+ }
if (dl->nors == NULL) BKE_displist_normals_add(lb);
index3_nors_incr = 0;
@@ -3620,9 +3616,11 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas
}
else {
if (!render_only || (render_only && BKE_displist_has_faces(lb))) {
+ int retval;
draw_index_wire = 0;
retval = drawDispListwire(lb);
draw_index_wire = 1;
+ return retval;
}
}
break;
@@ -3632,7 +3630,9 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas
if (solid) {
dl = lb->first;
- if (dl == NULL) return 1;
+ if (dl == NULL) {
+ return TRUE;
+ }
if (dl->nors == NULL) BKE_displist_normals_add(lb);
@@ -3648,7 +3648,7 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas
}
}
else {
- retval = drawDispListwire(lb);
+ return drawDispListwire(lb);
}
break;
case OB_MBALL:
@@ -3656,7 +3656,9 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas
if (BKE_mball_is_basis(ob)) {
lb = &ob->disp;
if (lb->first == NULL) BKE_displist_make_mball(scene, ob);
- if (lb->first == NULL) return 1;
+ if (lb->first == NULL) {
+ return TRUE;
+ }
if (solid) {
@@ -3673,14 +3675,31 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas
}
else {
/* MetaBalls use DL_INDEX4 type of DispList */
- retval = drawDispListwire(lb);
+ return drawDispListwire(lb);
}
}
break;
}
-
- if (v3d->flag2 & V3D_BACKFACE_CULLING)
+
+ return FALSE;
+}
+static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
+ const short dt, const short dflag, const unsigned char ob_wire_col[4])
+{
+ int retval;
+
+ /* backface culling */
+ if (v3d->flag2 & V3D_BACKFACE_CULLING) {
+ /* not all displists use same in/out normal direction convention */
+ glEnable(GL_CULL_FACE);
+ glCullFace((base->object->type == OB_MBALL) ? GL_BACK : GL_FRONT);
+ }
+
+ retval = drawDispList_nobackface(scene, v3d, rv3d, base, dt, dflag, ob_wire_col);
+
+ if (v3d->flag2 & V3D_BACKFACE_CULLING) {
glDisable(GL_CULL_FACE);
+ }
return retval;
}
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index 88b100c6c13..26eebd16fba 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -946,7 +946,7 @@ static void view3d_buttons_area_listener(ARegion *ar, wmNotifier *wmn)
ED_region_tag_redraw(ar);
break;
case NC_GPENCIL:
- if (wmn->data == ND_DATA)
+ if (wmn->data == ND_DATA || wmn->action == NA_EDITED)
ED_region_tag_redraw(ar);
break;
}
@@ -1120,16 +1120,21 @@ static int view3d_context(const bContext *C, const char *member, bContextDataRes
return 1;
}
else if (CTX_data_equals(member, "active_base")) {
- if (scene->basact && (scene->basact->lay & lay))
- if ((scene->basact->object->restrictflag & OB_RESTRICT_VIEW) == 0)
+ if (scene->basact && (scene->basact->lay & lay)) {
+ Object *ob = scene->basact->object;
+ /* if hidden but in edit mode, we still display, can happen with animation */
+ if ((ob->restrictflag & OB_RESTRICT_VIEW) == 0 || (ob->mode & OB_MODE_EDIT))
CTX_data_pointer_set(result, &scene->id, &RNA_ObjectBase, scene->basact);
+ }
return 1;
}
else if (CTX_data_equals(member, "active_object")) {
- if (scene->basact && (scene->basact->lay & lay))
- if ((scene->basact->object->restrictflag & OB_RESTRICT_VIEW) == 0)
+ if (scene->basact && (scene->basact->lay & lay)) {
+ Object *ob = scene->basact->object;
+ if ((ob->restrictflag & OB_RESTRICT_VIEW) == 0 || (ob->mode & OB_MODE_EDIT))
CTX_data_id_pointer_set(result, &scene->basact->object->id);
+ }
return 1;
}
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 2c85dc62edb..10480a3872a 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -97,6 +97,16 @@
#include "view3d_intern.h" /* own include */
+/* handy utility for drawing shapes in the viewport for arbitrary code.
+ * could add lines and points too */
+// #define DEBUG_DRAW
+#ifdef DEBUG_DRAW
+static void bl_debug_draw(void);
+/* add these locally when using these functions for testing */
+extern void bl_debug_draw_quad_clear(void);
+extern void bl_debug_draw_quad_add(const float v0[3], const float v1[3], const float v2[3], const float v3[3]);
+extern void bl_debug_draw_edge_add(const float v0[3], const float v1[3]);
+#endif
static void star_stuff_init_func(void)
{
@@ -1271,7 +1281,7 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d)
hmargin = 0.035f * (x2 - x1);
vmargin = 0.035f * (y2 - y1);
- uiDrawBox(GL_LINE_LOOP, x1 + hmargin, y1+vmargin, x2 - hmargin, y2 - vmargin, 2.0f);
+ uiDrawBox(GL_LINE_LOOP, x1 + hmargin, y1 + vmargin, x2 - hmargin, y2 - vmargin, 2.0f);
}
if (ca && (ca->flag & CAM_SHOWSENSOR)) {
/* determine sensor fit, and get sensor x/y, for auto fit we
@@ -1464,8 +1474,8 @@ ImBuf *view3d_read_backbuf(ViewContext *vc, short xmin, short ymin, short xmax,
ibuf = IMB_allocImBuf((xmaxc - xminc + 1), (ymaxc - yminc + 1), 32, IB_rect);
- view3d_validate_backbuf(vc);
-
+ view3d_validate_backbuf(vc);
+
glReadPixels(vc->ar->winrct.xmin + xminc,
vc->ar->winrct.ymin + yminc,
(xmaxc - xminc + 1),
@@ -1613,7 +1623,8 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d,
ibuf = NULL; /* frame is out of range, dont show */
}
else {
- ibuf = BKE_image_get_ibuf(ima, &bgpic->iuser);
+ ibuf = BKE_image_acquire_ibuf(ima, &bgpic->iuser, NULL);
+ freeibuf = ibuf;
}
image_aspect[0] = ima->aspx;
@@ -3036,9 +3047,10 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const
v3d->zbuf = FALSE;
/* enables anti-aliasing for 3D view drawing */
- if (U.ogl_multisamples)
- if (!(U.gameflags & USER_DISABLE_AA))
- glEnable(GL_MULTISAMPLE_ARB);
+ if (U.ogl_multisamples != USER_MULTISAMPLE_NONE) {
+ // if (!(U.gameflags & USER_DISABLE_AA))
+ glEnable(GL_MULTISAMPLE_ARB);
+ }
/* needs to be done always, gridview is adjusted in drawgrid() now */
@@ -3153,9 +3165,10 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const
BIF_draw_manipulator(C);
/* Disable back anti-aliasing */
- if (U.ogl_multisamples)
- if (!(U.gameflags & USER_DISABLE_AA))
- glDisable(GL_MULTISAMPLE_ARB);
+ if (U.ogl_multisamples != USER_MULTISAMPLE_NONE) {
+ // if (!(U.gameflags & USER_DISABLE_AA))
+ glDisable(GL_MULTISAMPLE_ARB);
+ }
if (v3d->zbuf) {
@@ -3257,6 +3270,9 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar)
/* draw viewport using opengl */
if (v3d->drawtype != OB_RENDER || !view3d_main_area_do_render_draw(C) || draw_border) {
view3d_main_area_draw_objects(C, ar, &grid_unit);
+#ifdef DEBUG_DRAW
+ bl_debug_draw();
+#endif
ED_region_pixelspace(ar);
}
@@ -3269,3 +3285,57 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar)
v3d->flag |= V3D_INVALID_BACKBUF;
}
+#ifdef DEBUG_DRAW
+/* debug drawing */
+#define _DEBUG_DRAW_QUAD_TOT 1024
+static float _bl_debug_draw_quads[_DEBUG_DRAW_QUAD_TOT][4][3];
+static int _bl_debug_draw_quads_tot = 0;
+
+void bl_debug_draw_quad_clear(void)
+{
+ _bl_debug_draw_quads_tot = 0;
+}
+void bl_debug_draw_quad_add(const float v0[3], const float v1[3], const float v2[3], const float v3[3])
+{
+ if (_bl_debug_draw_quads_tot >= _DEBUG_DRAW_QUAD_TOT) {
+ printf("%s: max quad count hit %d!", __func__, _bl_debug_draw_quads_tot);
+ }
+ else {
+ float *pt = &_bl_debug_draw_quads[_bl_debug_draw_quads_tot][0][0];
+ copy_v3_v3(pt, v0); pt += 3;
+ copy_v3_v3(pt, v1); pt += 3;
+ copy_v3_v3(pt, v2); pt += 3;
+ copy_v3_v3(pt, v3); pt += 3;
+ _bl_debug_draw_quads_tot++;
+ }
+}
+void bl_debug_draw_edge_add(const float v0[3], const float v1[3])
+{
+ if (_bl_debug_draw_quads_tot >= _DEBUG_DRAW_QUAD_TOT) {
+ printf("%s: max edge count hit %d!", __func__, _bl_debug_draw_quads_tot);
+ }
+ else {
+ float *pt = &_bl_debug_draw_quads[_bl_debug_draw_quads_tot][0][0];
+ copy_v3_v3(pt, v0); pt += 3;
+ copy_v3_v3(pt, v1); pt += 3;
+ copy_v3_v3(pt, v0); pt += 3;
+ copy_v3_v3(pt, v1); pt += 3;
+ _bl_debug_draw_quads_tot++;
+ }
+}
+static void bl_debug_draw(void)
+{
+ if (_bl_debug_draw_quads_tot) {
+ int i;
+ cpack(0x00FF0000);
+ glBegin(GL_LINE_LOOP);
+ for (i = 0; i < _bl_debug_draw_quads_tot; i ++) {
+ glVertex3fv(_bl_debug_draw_quads[i][0]);
+ glVertex3fv(_bl_debug_draw_quads[i][1]);
+ glVertex3fv(_bl_debug_draw_quads[i][2]);
+ glVertex3fv(_bl_debug_draw_quads[i][3]);
+ }
+ glEnd();
+ }
+}
+#endif
diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c
index d8fcc7e12e7..79bf003a563 100644
--- a/source/blender/editors/space_view3d/view3d_header.c
+++ b/source/blender/editors/space_view3d/view3d_header.c
@@ -310,21 +310,14 @@ static char *view3d_modeselect_pup(Scene *scene)
return (string);
}
-
static void do_view3d_header_buttons(bContext *C, void *UNUSED(arg), int event)
{
wmWindow *win = CTX_wm_window(C);
- ToolSettings *ts = CTX_data_tool_settings(C);
ScrArea *sa = CTX_wm_area(C);
View3D *v3d = sa->spacedata.first;
- Object *obedit = CTX_data_edit_object(C);
- BMEditMesh *em = NULL;
- int ctrl = win->eventstate->ctrl, shift = win->eventstate->shift;
+ const int ctrl = win->eventstate->ctrl, shift = win->eventstate->shift;
PointerRNA props_ptr;
-
- if (obedit && obedit->type == OB_MESH) {
- em = BMEdit_FromObject(obedit);
- }
+
/* watch it: if sa->win does not exist, check that when calling direct drawing routines */
switch (event) {
@@ -336,42 +329,17 @@ static void do_view3d_header_buttons(bContext *C, void *UNUSED(arg), int event)
break;
case B_SEL_VERT:
- if (em) {
- if (shift == 0 || em->selectmode == 0)
- em->selectmode = SCE_SELECT_VERTEX;
- ts->selectmode = em->selectmode;
- EDBM_selectmode_set(em);
- WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
+ if (EDBM_selectmode_toggle(C, SCE_SELECT_VERTEX, -1, shift, ctrl)) {
ED_undo_push(C, "Selectmode Set: Vertex");
}
break;
case B_SEL_EDGE:
- if (em) {
- if (shift == 0 || em->selectmode == 0) {
- if ((em->selectmode ^ SCE_SELECT_EDGE) == SCE_SELECT_VERTEX) {
- if (ctrl) EDBM_selectmode_convert(em, SCE_SELECT_VERTEX, SCE_SELECT_EDGE);
- }
- em->selectmode = SCE_SELECT_EDGE;
- }
- ts->selectmode = em->selectmode;
- EDBM_selectmode_set(em);
- WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
+ if (EDBM_selectmode_toggle(C, SCE_SELECT_EDGE, -1, shift, ctrl)) {
ED_undo_push(C, "Selectmode Set: Edge");
}
break;
case B_SEL_FACE:
- if (em) {
- if (shift == 0 || em->selectmode == 0) {
- if (((ts->selectmode ^ SCE_SELECT_FACE) == SCE_SELECT_VERTEX) ||
- ((ts->selectmode ^ SCE_SELECT_FACE) == SCE_SELECT_EDGE))
- {
- if (ctrl) EDBM_selectmode_convert(em, (ts->selectmode ^ SCE_SELECT_FACE), SCE_SELECT_FACE);
- }
- em->selectmode = SCE_SELECT_FACE;
- }
- ts->selectmode = em->selectmode;
- EDBM_selectmode_set(em);
- WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
+ if (EDBM_selectmode_toggle(C, SCE_SELECT_FACE, -1, shift, ctrl)) {
ED_undo_push(C, "Selectmode Set: Face");
}
break;
@@ -430,9 +398,15 @@ void uiTemplateEditModeSelection(uiLayout *layout, struct bContext *C)
row = uiLayoutRow(layout, TRUE);
block = uiLayoutGetBlock(row);
- uiDefIconButBitS(block, TOG, SCE_SELECT_VERTEX, B_SEL_VERT, ICON_VERTEXSEL, 0, 0, UI_UNIT_X, UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0, "Vertex select - Shift-Click for multiple modes");
- uiDefIconButBitS(block, TOG, SCE_SELECT_EDGE, B_SEL_EDGE, ICON_EDGESEL, 0, 0, UI_UNIT_X, UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0, "Edge select - Shift-Click for multiple modes");
- uiDefIconButBitS(block, TOG, SCE_SELECT_FACE, B_SEL_FACE, ICON_FACESEL, 0, 0, UI_UNIT_X, UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0, "Face select - Shift-Click for multiple modes");
+ uiDefIconButBitS(block, TOG, SCE_SELECT_VERTEX, B_SEL_VERT, ICON_VERTEXSEL,
+ 0, 0, UI_UNIT_X, UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0,
+ "Vertex select - Shift-Click for multiple modes");
+ uiDefIconButBitS(block, TOG, SCE_SELECT_EDGE, B_SEL_EDGE, ICON_EDGESEL,
+ 0, 0, UI_UNIT_X, UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0,
+ "Edge select - Shift-Click for multiple modes, Ctrl-Click expands selection");
+ uiDefIconButBitS(block, TOG, SCE_SELECT_FACE, B_SEL_FACE, ICON_FACESEL,
+ 0, 0, UI_UNIT_X, UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0,
+ "Face select - Shift-Click for multiple modes, Ctrl-Click expands selection");
}
}
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index a9dcbdc1687..1a4d345705b 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -1066,11 +1066,11 @@ static EnumPropertyItem *object_select_menu_enum_itemf(bContext *C, PointerRNA *
static int object_select_menu_exec(bContext *C, wmOperator *op)
{
int name_index = RNA_enum_get(op->ptr, "name");
- short extend = RNA_boolean_get(op->ptr, "extend");
+ short toggle = RNA_boolean_get(op->ptr, "toggle");
short changed = 0;
const char *name = object_mouse_select_menu_data[name_index].idname;
- if (!extend) {
+ if (!toggle) {
CTX_DATA_BEGIN (C, Base *, base, selectable_bases)
{
if (base->flag & SELECT) {
@@ -1127,7 +1127,7 @@ void VIEW3D_OT_select_menu(wmOperatorType *ot)
RNA_def_property_flag(prop, PROP_HIDDEN);
ot->prop = prop;
- RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend selection instead of deselecting everything first");
+ RNA_def_boolean(ot->srna, "toggle", 0, "Toggle", "Toggle selection instead of deselecting everything first");
}
static void deselectall_except(Scene *scene, Base *b) /* deselect all except b */
@@ -1143,7 +1143,7 @@ static void deselectall_except(Scene *scene, Base *b) /* deselect all except b
}
}
-static Base *object_mouse_select_menu(bContext *C, ViewContext *vc, unsigned int *buffer, int hits, const int mval[2], short extend)
+static Base *object_mouse_select_menu(bContext *C, ViewContext *vc, unsigned int *buffer, int hits, const int mval[2], short toggle)
{
short baseCount = 0;
short ok;
@@ -1209,7 +1209,7 @@ static Base *object_mouse_select_menu(bContext *C, ViewContext *vc, unsigned int
PointerRNA ptr;
WM_operator_properties_create(&ptr, "VIEW3D_OT_select_menu");
- RNA_boolean_set(&ptr, "extend", extend);
+ RNA_boolean_set(&ptr, "toggle", toggle);
WM_operator_name_call(C, "VIEW3D_OT_select_menu", WM_OP_INVOKE_DEFAULT, &ptr);
WM_operator_properties_free(&ptr);
}
@@ -1442,7 +1442,7 @@ static int mouse_select(bContext *C, const int mval[2], short extend, short dese
/* note; shift+alt goes to group-flush-selecting */
if (enumerate) {
- basact = object_mouse_select_menu(C, &vc, NULL, 0, mval, extend);
+ basact = object_mouse_select_menu(C, &vc, NULL, 0, mval, toggle);
}
else {
base = startbase;
@@ -1482,7 +1482,7 @@ static int mouse_select(bContext *C, const int mval[2], short extend, short dese
/* note; shift+alt goes to group-flush-selecting */
if (has_bones == 0 && enumerate) {
- basact = object_mouse_select_menu(C, &vc, buffer, hits, mval, extend);
+ basact = object_mouse_select_menu(C, &vc, buffer, hits, mval, toggle);
}
else {
basact = mouse_select_eval_buffer(&vc, buffer, hits, mval, startbase, has_bones);
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index 1c50e833c6d..e69f0695697 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -3209,11 +3209,21 @@ static void headerResize(TransInfo *t, float vec[3], char *str)
(void)spos;
}
-#define SIGN(a) (a<-FLT_EPSILON ? 1 : a>FLT_EPSILON ? 2 : 3)
-#define VECSIGNFLIP(a, b) ((SIGN(a[0]) & SIGN(b[0])) == 0 || (SIGN(a[1]) & SIGN(b[1])) == 0 || (SIGN(a[2]) & SIGN(b[2])) == 0)
+/* FLT_EPSILON is too small [#29633], 0.0000001f starts to flip */
+#define TX_FLIP_EPS 0.00001f
+BLI_INLINE int tx_sign(const float a)
+{
+ return (a < -TX_FLIP_EPS ? 1 : a > TX_FLIP_EPS ? 2 : 3);
+}
+BLI_INLINE int tx_vec_sign_flip(const float a[3], const float b[3])
+{
+ return ((tx_sign(a[0]) & tx_sign(b[0])) == 0 ||
+ (tx_sign(a[1]) & tx_sign(b[1])) == 0 ||
+ (tx_sign(a[2]) & tx_sign(b[2])) == 0);
+}
/* smat is reference matrix, only scaled */
-static void TransMat3ToSize(float mat[][3], float smat[][3], float *size)
+static void TransMat3ToSize(float mat[][3], float smat[][3], float size[3])
{
float vec[3];
@@ -3225,9 +3235,9 @@ static void TransMat3ToSize(float mat[][3], float smat[][3], float *size)
size[2] = normalize_v3(vec);
/* first tried with dotproduct... but the sign flip is crucial */
- if (VECSIGNFLIP(mat[0], smat[0]) ) size[0] = -size[0];
- if (VECSIGNFLIP(mat[1], smat[1]) ) size[1] = -size[1];
- if (VECSIGNFLIP(mat[2], smat[2]) ) size[2] = -size[2];
+ if (tx_vec_sign_flip(mat[0], smat[0]) ) size[0] = -size[0];
+ if (tx_vec_sign_flip(mat[1], smat[1]) ) size[1] = -size[1];
+ if (tx_vec_sign_flip(mat[2], smat[2]) ) size[2] = -size[2];
}
diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c
index 8e8b909270b..58d8a06415a 100644
--- a/source/blender/editors/transform/transform_constraints.c
+++ b/source/blender/editors/transform/transform_constraints.c
@@ -151,8 +151,8 @@ static void postConstraintChecks(TransInfo *t, float vec[3], float pvec[3])
if (hasNumInput(&t->num)) {
applyNumInput(&t->num, vec);
- removeAspectRatio(t, vec);
constraintNumInput(t, vec);
+ removeAspectRatio(t, vec);
}
/* autovalues is operator param, use that directly but not if snapping is forced */
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index 9bbd3f59cbf..5b79b69f7ec 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -2486,7 +2486,7 @@ int clipUVTransform(TransInfo *t, float *vec, int resize)
max[0] = aspx; max[1] = aspy;
for (a = 0, td = t->data; a < t->total; a++, td++) {
- DO_MINMAX2(td->loc, min, max);
+ minmax_v2v2_v2(min, max, td->loc);
}
if (resize) {
diff --git a/source/blender/editors/uvedit/uvedit_buttons.c b/source/blender/editors/uvedit/uvedit_buttons.c
index fa39a52444b..1c32c01b8f0 100644
--- a/source/blender/editors/uvedit/uvedit_buttons.c
+++ b/source/blender/editors/uvedit/uvedit_buttons.c
@@ -94,14 +94,19 @@ static int uvedit_center(Scene *scene, BMEditMesh *em, Image *ima, float center[
return tot;
}
-static void uvedit_translate(Scene *scene, BMEditMesh *em, Image *UNUSED(ima), float delta[2])
+static void uvedit_translate(Scene *scene, BMEditMesh *em, Image *ima, float delta[2])
{
BMFace *f;
BMLoop *l;
BMIter iter, liter;
MLoopUV *luv;
+ MTexPoly *tf;
BM_ITER_MESH (f, &iter, em->bm, BM_FACES_OF_MESH) {
+ tf = CustomData_bmesh_get(&em->bm->pdata, f->head.data, CD_MTEXPOLY);
+ if (!uvedit_face_visible_test(scene, ima, f, tf))
+ continue;
+
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
if (uvedit_uv_select_test(em, scene, l)) {
diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c
index d3d85c19487..c6db7d4896a 100644
--- a/source/blender/editors/uvedit/uvedit_ops.c
+++ b/source/blender/editors/uvedit/uvedit_ops.c
@@ -616,7 +616,7 @@ int ED_uvedit_minmax(Scene *scene, Image *ima, Object *obedit, float r_min[2], f
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
if (uvedit_uv_select_test(em, scene, l)) {
luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
- DO_MINMAX2(luv->uv, r_min, r_max);
+ minmax_v2v2_v2(r_min, r_max, luv->uv);
sel = 1;
}
}
@@ -1327,7 +1327,7 @@ static void weld_align_uv(bContext *C, int tool)
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
if (uvedit_uv_select_test(em, scene, l)) {
MLoopUV *luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
- DO_MINMAX2(luv->uv, min, max);
+ minmax_v2v2_v2(min, max, luv->uv);
}
}
}
@@ -1553,7 +1553,170 @@ static void UV_OT_align(wmOperatorType *ot)
/* properties */
RNA_def_enum(ot->srna, "axis", axis_items, 'a', "Axis", "Axis to align UV locations on");
}
+/* ******************** weld near operator **************** */
+typedef struct UVvert {
+ MLoopUV *uv_loop;
+ int weld;
+} UVvert;
+
+static int remove_doubles_exec(bContext *C, wmOperator *op)
+{
+ const float threshold = RNA_float_get(op->ptr, "threshold");
+ const int use_unselected = RNA_boolean_get(op->ptr, "use_unselected");
+
+ SpaceImage *sima;
+ Scene *scene;
+ Object *obedit;
+ Image *ima;
+ BMEditMesh *em;
+ MTexPoly *tf;
+ int uv_a_index;
+ int uv_b_index;
+ float *uv_a;
+ float *uv_b;
+
+ BMIter iter, liter;
+ BMFace *efa;
+ BMLoop *l;
+
+ sima = CTX_wm_space_image(C);
+ scene = CTX_data_scene(C);
+ obedit = CTX_data_edit_object(C);
+ em = BMEdit_FromObject(obedit);
+ ima = CTX_data_edit_image(C);
+
+ if (use_unselected == FALSE) {
+ UVvert *vert_arr = NULL;
+ BLI_array_declare(vert_arr);
+ MLoopUV **loop_arr = NULL;
+ BLI_array_declare(loop_arr);
+
+ /* TODO, use qsort as with MESH_OT_remove_doubles, this isn't optimal */
+ 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, ima, efa, tf))
+ continue;
+
+ BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
+ if (uvedit_uv_select_test(em, scene, l)) {
+ MLoopUV *luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ UVvert vert;
+ vert.uv_loop = luv;
+ vert.weld = FALSE;
+ BLI_array_append(vert_arr, vert);
+ }
+
+ }
+ }
+
+ for (uv_a_index = 0; uv_a_index < BLI_array_count(vert_arr); uv_a_index++) {
+ if (vert_arr[uv_a_index].weld == FALSE) {
+ float uv_min[2];
+ float uv_max[2];
+
+ BLI_array_empty(loop_arr);
+ BLI_array_append(loop_arr, vert_arr[uv_a_index].uv_loop);
+
+ uv_a = vert_arr[uv_a_index].uv_loop->uv;
+
+ copy_v2_v2(uv_max, uv_a);
+ copy_v2_v2(uv_min, uv_a);
+
+ vert_arr[uv_a_index].weld = TRUE;
+ for (uv_b_index = uv_a_index + 1; uv_b_index < BLI_array_count(vert_arr); uv_b_index++) {
+ uv_b = vert_arr[uv_b_index].uv_loop->uv;
+ if ((vert_arr[uv_b_index].weld == FALSE) &&
+ (len_manhattan_v2v2(uv_a, uv_b) < threshold))
+ {
+ minmax_v2v2_v2(uv_max, uv_min, uv_b);
+ BLI_array_append(loop_arr, vert_arr[uv_b_index].uv_loop);
+ vert_arr[uv_b_index].weld = TRUE;
+ }
+ }
+ if (BLI_array_count(loop_arr)) {
+ float uv_mid[2];
+ mid_v2_v2v2(uv_mid, uv_min, uv_max);
+ for (uv_b_index = 0; uv_b_index < BLI_array_count(loop_arr); uv_b_index++) {
+ copy_v2_v2(loop_arr[uv_b_index]->uv, uv_mid);
+ }
+ }
+ }
+ }
+
+ BLI_array_free(vert_arr);
+ BLI_array_free(loop_arr);
+ }
+ else {
+ /* selected -> unselected
+ *
+ * No need to use 'UVvert' here */
+ MLoopUV **loop_arr = NULL;
+ BLI_array_declare(loop_arr);
+ MLoopUV **loop_arr_unselected = NULL;
+ BLI_array_declare(loop_arr_unselected);
+
+ 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, ima, efa, tf))
+ continue;
+
+ BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
+ MLoopUV *luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ if (uvedit_uv_select_test(em, scene, l)) {
+ BLI_array_append(loop_arr, luv);
+ }
+ else {
+ BLI_array_append(loop_arr_unselected, luv);
+ }
+ }
+ }
+
+ for (uv_a_index = 0; uv_a_index < BLI_array_count(loop_arr); uv_a_index++) {
+ float dist_best = FLT_MAX, dist;
+ float *uv_best = NULL;
+
+ uv_a = loop_arr[uv_a_index]->uv;
+ for (uv_b_index = 0; uv_b_index < BLI_array_count(loop_arr_unselected); uv_b_index++) {
+ uv_b = loop_arr_unselected[uv_b_index]->uv;
+ dist = len_manhattan_v2v2(uv_a, uv_b);
+ if ((dist < threshold) && (dist < dist_best)) {
+ uv_best = uv_b;
+ dist_best = dist;
+ }
+ }
+ if (uv_best) {
+ copy_v2_v2(uv_a, uv_best);
+ }
+ }
+
+ BLI_array_free(loop_arr);
+ BLI_array_free(loop_arr_unselected);
+ }
+
+ uvedit_live_unwrap_update(sima, scene, obedit);
+ DAG_id_tag_update(obedit->data, 0);
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+
+ return OPERATOR_FINISHED;
+}
+
+static void UV_OT_remove_doubles(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Remove Doubles UV";
+ ot->description = "Selected UV vertices that are within a radius of each other are welded together";
+ ot->idname = "UV_OT_remove_doubles";
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* api callbacks */
+ ot->exec = remove_doubles_exec;
+ ot->poll = ED_operator_uvedit;
+
+ RNA_def_float(ot->srna, "threshold", 0.02f, 0.0f, 10.0f,
+ "Merge Distance", "Maximum distance between welded vertices", 0.0f, 1.0f);
+ RNA_def_boolean(ot->srna, "use_unselected", 0, "Unselected", "Merge selected to other unselected vertices");
+}
/* ******************** weld operator **************** */
static int weld_exec(bContext *C, wmOperator *UNUSED(op))
@@ -3776,6 +3939,7 @@ void ED_operatortypes_uvedit(void)
WM_operatortype_append(UV_OT_seams_from_islands);
WM_operatortype_append(UV_OT_mark_seam);
WM_operatortype_append(UV_OT_weld);
+ WM_operatortype_append(UV_OT_remove_doubles);
WM_operatortype_append(UV_OT_pin);
WM_operatortype_append(UV_OT_average_islands_scale);
diff --git a/source/blender/editors/uvedit/uvedit_parametrizer.c b/source/blender/editors/uvedit/uvedit_parametrizer.c
index 5b6125b558b..8703234122a 100644
--- a/source/blender/editors/uvedit/uvedit_parametrizer.c
+++ b/source/blender/editors/uvedit/uvedit_parametrizer.c
@@ -450,7 +450,7 @@ static void p_chart_uv_bbox(PChart *chart, float minv[2], float maxv[2])
INIT_MINMAX2(minv, maxv);
for (v = chart->verts; v; v = v->nextlink) {
- DO_MINMAX2(v->uv, minv, maxv);
+ minmax_v2v2_v2(minv, maxv, v->uv);
}
}
@@ -3891,9 +3891,9 @@ static void p_smooth(PChart *chart)
INIT_MINMAX2(fmin, fmax);
- DO_MINMAX2(e1->vert->uv, fmin, fmax);
- DO_MINMAX2(e2->vert->uv, fmin, fmax);
- DO_MINMAX2(e3->vert->uv, fmin, fmax);
+ minmax_v2v2_v2(fmin, fmax, e1->vert->uv);
+ minmax_v2v2_v2(fmin, fmax, e2->vert->uv);
+ minmax_v2v2_v2(fmin, fmax, e3->vert->uv);
bx1 = (int)((fmin[0] - minv[0]) * invmedian);
by1 = (int)((fmin[1] - minv[1]) * invmedian);
diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c
index 4f6aa224586..cd260c4ea77 100644
--- a/source/blender/editors/uvedit/uvedit_smart_stitch.c
+++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c
@@ -1444,18 +1444,22 @@ static int stitch_modal(bContext *C, wmOperator *op, wmEvent *event)
}
case PADENTER:
case RETKEY:
- if (stitch_process_data(stitch_state, scene, 1)) {
- stitch_exit(C, op, 1);
- return OPERATOR_FINISHED;
+ if (event->val == KM_PRESS) {
+ if (stitch_process_data(stitch_state, scene, 1)) {
+ stitch_exit(C, op, 1);
+ return OPERATOR_FINISHED;
+ }
+ else {
+ return stitch_cancel(C, op);
+ }
}
else {
- return stitch_cancel(C, op);
+ return OPERATOR_PASS_THROUGH;
}
-
/* Increase limit */
case PADPLUSKEY:
case WHEELUPMOUSE:
- if (event->alt) {
+ if (event->val == KM_PRESS && event->alt) {
stitch_state->limit_dist += 0.01f;
if (!stitch_process_data(stitch_state, scene, 0)) {
return stitch_cancel(C, op);
@@ -1468,7 +1472,7 @@ static int stitch_modal(bContext *C, wmOperator *op, wmEvent *event)
/* Decrease limit */
case PADMINUS:
case WHEELDOWNMOUSE:
- if (event->alt) {
+ if (event->val == KM_PRESS && event->alt) {
stitch_state->limit_dist -= 0.01f;
stitch_state->limit_dist = MAX2(0.01f, stitch_state->limit_dist);
if (!stitch_process_data(stitch_state, scene, 0)) {
diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
index f615902eedf..efe9d1fedfe 100644
--- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c
+++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
@@ -1089,7 +1089,7 @@ static void uv_map_clip_correct(Scene *scene, Object *ob, BMEditMesh *em, wmOper
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
- DO_MINMAX2(luv->uv, min, max);
+ minmax_v2v2_v2(min, max, luv->uv);
}
}
@@ -1414,7 +1414,7 @@ static void uv_map_mirror(BMEditMesh *em, BMFace *efa, MTexPoly *UNUSED(tf))
BMIter liter;
MLoopUV *luv;
float **uvs = NULL;
- BLI_array_fixedstack_declare(uvs, BM_NGON_STACK_SIZE, efa->len, __func__);
+ BLI_array_fixedstack_declare(uvs, BM_DEFAULT_NGON_STACK_SIZE, efa->len, __func__);
float dx;
int i, mi;
diff --git a/source/blender/gpu/SConscript b/source/blender/gpu/SConscript
index f7ed9effc7a..9b8a86eac15 100644
--- a/source/blender/gpu/SConscript
+++ b/source/blender/gpu/SConscript
@@ -27,7 +27,6 @@ sources.extend((
os.path.join(env['DATA_SOURCES'], "gpu_shader_vertex.glsl.c"),
os.path.join(env['DATA_SOURCES'], "gpu_shader_sep_gaussian_blur_frag.glsl.c"),
os.path.join(env['DATA_SOURCES'], "gpu_shader_sep_gaussian_blur_vert.glsl.c"),
- os.path.join(env['DATA_SOURCES'], "gpu_shader_material.glsl.c"),
os.path.join(env['DATA_SOURCES'], "gpu_shader_vsm_store_frag.glsl.c"),
os.path.join(env['DATA_SOURCES'], "gpu_shader_vsm_store_vert.glsl.c"),
))
diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c
index 53a51c9c9fd..b89f0196794 100644
--- a/source/blender/gpu/intern/gpu_draw.c
+++ b/source/blender/gpu/intern/gpu_draw.c
@@ -327,7 +327,7 @@ static void gpu_make_repbind(Image *ima)
{
ImBuf *ibuf;
- ibuf = BKE_image_get_ibuf(ima, NULL);
+ ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
if (ibuf==NULL)
return;
@@ -342,6 +342,8 @@ static void gpu_make_repbind(Image *ima)
if (ima->totbind>1)
ima->repbind= MEM_callocN(sizeof(int)*ima->totbind, "repbind");
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
}
static void reset_default_alphablend_state(void);
@@ -586,7 +588,7 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int
return 0;
/* check if we have a valid image buffer */
- ibuf= BKE_image_get_ibuf(ima, iuser);
+ ibuf= BKE_image_acquire_ibuf(ima, iuser, NULL);
if (ibuf==NULL)
return 0;
@@ -682,6 +684,7 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int
/* enable opengl drawing with textures */
#include REAL_GL_MODE
glBindTexture(GL_TEXTURE_2D, *bind);
+ BKE_image_release_ibuf(ima, ibuf, NULL);
return *bind;
}
@@ -743,6 +746,8 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int
if (srgb_frect)
MEM_freeN(srgb_frect);
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+
return *bind;
}
@@ -997,7 +1002,7 @@ void GPU_paint_update_image(Image *ima, int x, int y, int w, int h)
{
ImBuf *ibuf;
- ibuf = BKE_image_get_ibuf(ima, NULL);
+ ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
if (ima->repbind || (GPU_get_mipmap() && !GTS.gpu_mipmap) || !ima->bindcode || !ibuf ||
(!is_power_of_2_i(ibuf->x) || !is_power_of_2_i(ibuf->y)) ||
@@ -1031,6 +1036,7 @@ void GPU_paint_update_image(Image *ima, int x, int y, int w, int h)
ima->tpageflag &= ~IMA_MIPMAP_COMPLETE;
}
+ BKE_image_release_ibuf(ima, ibuf, NULL);
return;
}
@@ -1065,6 +1071,8 @@ void GPU_paint_update_image(Image *ima, int x, int y, int w, int h)
ima->tpageflag &= ~IMA_MIPMAP_COMPLETE;
}
}
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
}
#include REAL_GL_MODE
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c
index 1005a60d8b1..ace97215d8d 100644
--- a/source/blender/gpu/intern/gpu_material.c
+++ b/source/blender/gpu/intern/gpu_material.c
@@ -1187,13 +1187,14 @@ static void do_material_tex(GPUShadeInput *shi)
// resolve texture resolution
if ( (mtex->texflag & MTEX_BUMP_TEXTURESPACE) || found_deriv_map ) {
- ImBuf *ibuf= BKE_image_get_ibuf(tex->ima, &tex->iuser);
+ ImBuf *ibuf= BKE_image_acquire_ibuf(tex->ima, &tex->iuser, NULL);
ima_x= 512.0f; ima_y= 512.f; // prevent calling textureSize, glsl 1.3 only
if (ibuf) {
ima_x= ibuf->x;
ima_y= ibuf->y;
aspect = ((float) ima_y) / ima_x;
}
+ BKE_image_release_ibuf(tex->ima, ibuf, NULL);
}
// The negate on norfac is done because the
diff --git a/source/blender/gpu/shaders/gpu_shader_vertex.glsl b/source/blender/gpu/shaders/gpu_shader_vertex.glsl
index a86431bdd7a..574455e42b3 100644
--- a/source/blender/gpu/shaders/gpu_shader_vertex.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_vertex.glsl
@@ -10,3 +10,11 @@ void main()
varnormal = normalize(gl_NormalMatrix * gl_Normal);
gl_Position = gl_ProjectionMatrix * co;
+ // Setting gl_ClipVertex is necessary to get glClipPlane working on NVIDIA graphic cards.
+ // gl_ClipVertex works only on NVIDIA graphic cards so we have to check with
+ // __GLSL_CG_DATA_TYPES if a NVIDIA graphic card is used (Cg support).
+ // gl_ClipVerte is supported up to GLSL 1.20.
+ #ifdef __GLSL_CG_DATA_TYPES
+ gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex;
+ #endif
+
diff --git a/source/blender/ikplugin/intern/ikplugin_api.c b/source/blender/ikplugin/intern/ikplugin_api.c
index 9a0878f24ce..efe07b2c48c 100644
--- a/source/blender/ikplugin/intern/ikplugin_api.c
+++ b/source/blender/ikplugin/intern/ikplugin_api.c
@@ -79,14 +79,14 @@ static IKPlugin ikplugin_tab[] = {
itasc_update_param,
itasc_test_constraint,
},
- #endif
+#endif
{ NULL }
};
static IKPlugin *get_plugin(bPose *pose)
{
- if (!pose || pose->iksolver < 0 || pose->iksolver >= (sizeof(ikplugin_tab) / sizeof(IKPlugin)))
+ 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/ikplugin/intern/iksolver_plugin.c b/source/blender/ikplugin/intern/iksolver_plugin.c
index af15333ece5..ca81f4c915a 100644
--- a/source/blender/ikplugin/intern/iksolver_plugin.c
+++ b/source/blender/ikplugin/intern/iksolver_plugin.c
@@ -379,6 +379,7 @@ static void execute_posetree(struct Scene *scene, Object *ob, PoseTree *tree)
copy_v3_v3(goalpos, goal[3]);
copy_m3_m4(goalrot, goal);
+ normalize_m3(goalrot);
/* same for pole vector target */
if (data->poletar) {
@@ -433,7 +434,7 @@ static void execute_posetree(struct Scene *scene, Object *ob, PoseTree *tree)
iktarget = iktree[target->tip];
- if (data->weight != 0.0f) {
+ if ((data->flag & CONSTRAINT_IK_POS) && data->weight != 0.0f) {
if (poleconstrain)
IK_SolverSetPoleVectorConstraint(solver, iktarget, goalpos,
polepos, data->poleangle, (poleangledata == data));
diff --git a/source/blender/imbuf/intern/cineon/cineon_dpx.c b/source/blender/imbuf/intern/cineon/cineon_dpx.c
index d20c6dec9d3..c8bc3f8ebb8 100644
--- a/source/blender/imbuf/intern/cineon/cineon_dpx.c
+++ b/source/blender/imbuf/intern/cineon/cineon_dpx.c
@@ -139,9 +139,19 @@ static int imb_save_dpx_cineon(ImBuf *ibuf, const char *filename, int use_cineon
if (ibuf->rect_float != 0 && bitspersample != 8) {
/* don't use the float buffer to save 8 bpp picture to prevent color banding
(there's no dithering algorithm behing the logImageSetDataRGBA function) */
- IMB_flipy(ibuf);
- rvalue = (logImageSetDataRGBA(logImage, ibuf->rect_float, 1) == 0);
- IMB_flipy(ibuf);
+
+ fbuf = (float *)MEM_mallocN(ibuf->x * ibuf->y * 4 * sizeof(float), "fbuf in imb_save_dpx_cineon");
+
+ for (y = 0; y < ibuf->y; y++) {
+ float *dst_ptr = fbuf + 4 * ((ibuf->y - y - 1) * ibuf->x);
+ float *src_ptr = ibuf->rect_float + 4 * (y * ibuf->x);
+
+ memcpy(dst_ptr, src_ptr, 4 * ibuf->x * sizeof(float));
+ }
+
+ rvalue = (logImageSetDataRGBA(logImage, fbuf, 1) == 0);
+
+ MEM_freeN(fbuf);
}
else {
if (ibuf->rect == 0)
diff --git a/source/blender/imbuf/intern/cineon/cineonlib.c b/source/blender/imbuf/intern/cineon/cineonlib.c
index 9926d8c8562..3049a5be514 100644
--- a/source/blender/imbuf/intern/cineon/cineonlib.c
+++ b/source/blender/imbuf/intern/cineon/cineonlib.c
@@ -188,7 +188,7 @@ LogImageFile *cineonOpen(const unsigned char *byteStuff, int fromMemory, size_t
}
else {
if (verbose) printf("Cineon: Bad magic number %lu in \"%s\".\n",
- (uintptr_t)header.fileHeader.magic_num, byteStuff);
+ (unsigned long)header.fileHeader.magic_num, byteStuff);
logImageClose(cineon);
return 0;
}
diff --git a/source/blender/imbuf/intern/cineon/dpxlib.c b/source/blender/imbuf/intern/cineon/dpxlib.c
index aedce52a7bf..4c9b5e620dd 100644
--- a/source/blender/imbuf/intern/cineon/dpxlib.c
+++ b/source/blender/imbuf/intern/cineon/dpxlib.c
@@ -457,7 +457,7 @@ LogImageFile *dpxCreate(const char *filename, int width, int height, int bitsPer
}
/* Header should be rounded to next 8k block
- 6044 = 8092 - sizeof(DpxMainHeader) */
+ * 6044 = 8092 - sizeof(DpxMainHeader) */
memset(&pad, 0, 6044);
if (fwrite(&pad, 6044, 1, dpx->file) == 0) {
if (verbose) printf("DPX: Couldn't write image header\n");
diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c
index b9774a9f7b0..1c68a466ade 100644
--- a/source/blender/imbuf/intern/colormanagement.c
+++ b/source/blender/imbuf/intern/colormanagement.c
@@ -164,7 +164,7 @@ typedef struct ColormanageProcessor {
* but they holds indexes of all transformations and color spaces, not
* their names.
*
- * This helps avoid extra colorsmace / display / view lookup without
+ * This helps avoid extra colorspace / display / view lookup without
* requiring to pass all variables which affects on display buffer
* to color management cache system and keeps calls small and nice.
*/
@@ -2465,7 +2465,8 @@ ColormanageProcessor *IMB_colormanagement_display_processor_new(const ColorManag
}
display_space = display_transform_get_colorspace(applied_view_settings, display_settings);
- cm_processor->is_data_result = display_space->is_data;
+ if (display_space)
+ cm_processor->is_data_result = display_space->is_data;
cm_processor->processor = create_display_buffer_processor(applied_view_settings->view_transform, display_settings->display_device,
applied_view_settings->exposure, applied_view_settings->gamma);
diff --git a/source/blender/imbuf/intern/dds/BlockDXT.h b/source/blender/imbuf/intern/dds/BlockDXT.h
index 0291816cd03..7e5a1e504b8 100644
--- a/source/blender/imbuf/intern/dds/BlockDXT.h
+++ b/source/blender/imbuf/intern/dds/BlockDXT.h
@@ -147,7 +147,7 @@ struct BlockDXT3
struct AlphaBlockDXT5
{
// uint64 unions do not compile on all platforms
- /*
+#if 0
union {
struct {
uint64 alpha0 : 8; // 8
@@ -171,7 +171,7 @@ struct AlphaBlockDXT5
};
uint64 u;
};
- */
+#endif
uint64 u;
uint8 alpha0() const { return u & 0xffLL; }
uint8 alpha1() const { return (u >> 8) & 0xffLL; }
diff --git a/source/blender/imbuf/intern/dds/SConscript b/source/blender/imbuf/intern/dds/SConscript
index d5a613f5981..475d21135aa 100644
--- a/source/blender/imbuf/intern/dds/SConscript
+++ b/source/blender/imbuf/intern/dds/SConscript
@@ -3,16 +3,17 @@ Import ('env')
source_files = ['dds_api.cpp', 'DirectDrawSurface.cpp', 'Stream.cpp', 'BlockDXT.cpp', 'ColorBlock.cpp', 'Image.cpp', 'FlipDXT.cpp']
-incs = ['.',
- '../../',
- '../..',
+incs = [
+ '.',
'..',
+ '../..',
'../../../makesdna',
'../../../blenkernel',
'../../../blenlib',
'intern/include',
'#/intern/guardedalloc',
- '#/intern/utfconv']
+ '#/intern/utfconv'
+ ]
defs = ['WITH_DDS']
diff --git a/source/blender/imbuf/intern/imageprocess.c b/source/blender/imbuf/intern/imageprocess.c
index 57fbce710a1..a185c4ee3e0 100644
--- a/source/blender/imbuf/intern/imageprocess.c
+++ b/source/blender/imbuf/intern/imageprocess.c
@@ -43,6 +43,7 @@
#include "BLI_utildefines.h"
#include "BLI_threads.h"
#include "BLI_listbase.h"
+#include "BLI_math.h"
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
@@ -95,132 +96,15 @@ static void pixel_from_buffer(struct ImBuf *ibuf, unsigned char **outI, float **
*outF = ibuf->rect_float + offset;
}
-/**************************************************************************
- * INTERPOLATIONS
- *
- * Reference and docs:
- * http://wiki.blender.org/index.php/User:Damiles#Interpolations_Algorithms
- ***************************************************************************/
-
-/* BICUBIC Interpolation functions
- * More info: http://wiki.blender.org/index.php/User:Damiles#Bicubic_pixel_interpolation
- * function assumes out to be zero'ed, only does RGBA */
-
-static float P(float k)
-{
- float p1, p2, p3, p4;
- p1 = MAX2(k + 2.0f, 0);
- p2 = MAX2(k + 1.0f, 0);
- p3 = MAX2(k, 0);
- p4 = MAX2(k - 1.0f, 0);
- return (float)(1.0f / 6.0f) * (p1 * p1 * p1 - 4.0f * p2 * p2 * p2 + 6.0f * p3 * p3 * p3 - 4.0f * p4 * p4 * p4);
-}
-
-
-#if 0
-/* older, slower function, works the same as above */
-static float P(float k)
-{
- return (float)(1.0f / 6.0f) * (pow(MAX2(k + 2.0f, 0), 3.0f) - 4.0f * pow(MAX2(k + 1.0f, 0), 3.0f) + 6.0f * pow(MAX2(k, 0), 3.0f) - 4.0f * pow(MAX2(k - 1.0f, 0), 3.0f));
-}
-#endif
+/* BICUBIC Interpolation */
void bicubic_interpolation_color(struct ImBuf *in, unsigned char outI[4], float outF[4], float u, float v)
{
- int i, j, n, m, x1, y1;
- unsigned char *dataI;
- float a, b, w, wx, wy[4], outR, outG, outB, outA, *dataF;
-
- /* sample area entirely outside image? */
- if (ceil(u) < 0 || floor(u) > in->x - 1 || ceil(v) < 0 || floor(v) > in->y - 1) {
- return;
- }
-
- /* ImBuf in must have a valid rect or rect_float, assume this is already checked */
-
- i = (int)floor(u);
- j = (int)floor(v);
- a = u - i;
- b = v - j;
-
- outR = outG = outB = outA = 0.0f;
-
-/* Optimized and not so easy to read */
-
- /* avoid calling multiple times */
- wy[0] = P(b - (-1));
- wy[1] = P(b - 0);
- wy[2] = P(b - 1);
- wy[3] = P(b - 2);
-
- for (n = -1; n <= 2; n++) {
- x1 = i + n;
- CLAMP(x1, 0, in->x - 1);
- wx = P(n - a);
- for (m = -1; m <= 2; m++) {
- y1 = j + m;
- CLAMP(y1, 0, in->y - 1);
- /* normally we could do this */
- /* w = P(n-a) * P(b-m); */
- /* except that would call P() 16 times per pixel therefor pow() 64 times, better precalc these */
- w = wx * wy[m + 1];
-
- if (outF) {
- dataF = in->rect_float + in->x * y1 * 4 + 4 * x1;
- outR += dataF[0] * w;
- outG += dataF[1] * w;
- outB += dataF[2] * w;
- outA += dataF[3] * w;
- }
- if (outI) {
- dataI = (unsigned char *)in->rect + in->x * y1 * 4 + 4 * x1;
- outR += dataI[0] * w;
- outG += dataI[1] * w;
- outB += dataI[2] * w;
- outA += dataI[3] * w;
- }
- }
- }
-
-/* Done with optimized part */
-
-#if 0
- /* older, slower function, works the same as above */
- for (n = -1; n <= 2; n++) {
- for (m = -1; m <= 2; m++) {
- x1 = i + n;
- y1 = j + m;
- if (x1 > 0 && x1 < in->x && y1 > 0 && y1 < in->y) {
- if (do_float) {
- dataF = in->rect_float + in->x * y1 * 4 + 4 * x1;
- outR += dataF[0] * P(n - a) * P(b - m);
- outG += dataF[1] * P(n - a) * P(b - m);
- outB += dataF[2] * P(n - a) * P(b - m);
- outA += dataF[3] * P(n - a) * P(b - m);
- }
- if (do_rect) {
- dataI = (unsigned char *)in->rect + in->x * y1 * 4 + 4 * x1;
- outR += dataI[0] * P(n - a) * P(b - m);
- outG += dataI[1] * P(n - a) * P(b - m);
- outB += dataI[2] * P(n - a) * P(b - m);
- outA += dataI[3] * P(n - a) * P(b - m);
- }
- }
- }
- }
-#endif
-
- if (outI) {
- outI[0] = (int)outR;
- outI[1] = (int)outG;
- outI[2] = (int)outB;
- outI[3] = (int)outA;
- }
if (outF) {
- outF[0] = outR;
- outF[1] = outG;
- outF[2] = outB;
- outF[3] = outA;
+ BLI_bicubic_interpolation_fl(in->rect_float, outF, in->x, in->y, 4, u, v);
+ }
+ else {
+ BLI_bicubic_interpolation_char((unsigned char*) in->rect, outI, in->x, in->y, 4, u, v);
}
}
@@ -239,77 +123,14 @@ void bicubic_interpolation(ImBuf *in, ImBuf *out, float u, float v, int xout, in
bicubic_interpolation_color(in, outI, outF, u, v);
}
-/* function assumes out to be zero'ed, only does RGBA */
/* BILINEAR INTERPOLATION */
void bilinear_interpolation_color(struct ImBuf *in, unsigned char outI[4], float outF[4], float u, float v)
{
- float *row1, *row2, *row3, *row4, a, b;
- unsigned char *row1I, *row2I, *row3I, *row4I;
- float a_b, ma_b, a_mb, ma_mb;
- float empty[4] = {0.0f, 0.0f, 0.0f, 0.0f};
- unsigned char emptyI[4] = {0, 0, 0, 0};
- int y1, y2, x1, x2;
-
-
- /* ImBuf in must have a valid rect or rect_float, assume this is already checked */
-
- x1 = (int)floor(u);
- x2 = (int)ceil(u);
- y1 = (int)floor(v);
- y2 = (int)ceil(v);
-
- /* sample area entirely outside image? */
- if (x2 < 0 || x1 > in->x - 1 || y2 < 0 || y1 > in->y - 1) {
- return;
- }
-
if (outF) {
- /* sample including outside of edges of image */
- if (x1 < 0 || y1 < 0) row1 = empty;
- else row1 = in->rect_float + in->x * y1 * 4 + 4 * x1;
-
- if (x1 < 0 || y2 > in->y - 1) row2 = empty;
- else row2 = in->rect_float + in->x * y2 * 4 + 4 * x1;
-
- if (x2 > in->x - 1 || y1 < 0) row3 = empty;
- else row3 = in->rect_float + in->x * y1 * 4 + 4 * x2;
-
- if (x2 > in->x - 1 || y2 > in->y - 1) row4 = empty;
- else row4 = in->rect_float + in->x * y2 * 4 + 4 * x2;
-
- a = u - floorf(u);
- b = v - floorf(v);
- a_b = a * b; ma_b = (1.0f - a) * b; a_mb = a * (1.0f - b); ma_mb = (1.0f - a) * (1.0f - b);
-
- outF[0] = ma_mb * row1[0] + a_mb * row3[0] + ma_b * row2[0] + a_b * row4[0];
- outF[1] = ma_mb * row1[1] + a_mb * row3[1] + ma_b * row2[1] + a_b * row4[1];
- outF[2] = ma_mb * row1[2] + a_mb * row3[2] + ma_b * row2[2] + a_b * row4[2];
- outF[3] = ma_mb * row1[3] + a_mb * row3[3] + ma_b * row2[3] + a_b * row4[3];
+ BLI_bilinear_interpolation_fl(in->rect_float, outF, in->x, in->y, 4, u, v);
}
- if (outI) {
- /* sample including outside of edges of image */
- if (x1 < 0 || y1 < 0) row1I = emptyI;
- else row1I = (unsigned char *)in->rect + in->x * y1 * 4 + 4 * x1;
-
- if (x1 < 0 || y2 > in->y - 1) row2I = emptyI;
- else row2I = (unsigned char *)in->rect + in->x * y2 * 4 + 4 * x1;
-
- if (x2 > in->x - 1 || y1 < 0) row3I = emptyI;
- else row3I = (unsigned char *)in->rect + in->x * y1 * 4 + 4 * x2;
-
- if (x2 > in->x - 1 || y2 > in->y - 1) row4I = emptyI;
- else row4I = (unsigned char *)in->rect + in->x * y2 * 4 + 4 * x2;
-
- a = u - floorf(u);
- b = v - floorf(v);
- a_b = a * b; ma_b = (1.0f - a) * b; a_mb = a * (1.0f - b); ma_mb = (1.0f - a) * (1.0f - b);
-
- /* need to add 0.5 to avoid rounding down (causes darken with the smear brush)
- * tested with white images and this should not wrap back to zero */
- outI[0] = (ma_mb * row1I[0] + a_mb * row3I[0] + ma_b * row2I[0] + a_b * row4I[0]) + 0.5f;
- outI[1] = (ma_mb * row1I[1] + a_mb * row3I[1] + ma_b * row2I[1] + a_b * row4I[1]) + 0.5f;
- outI[2] = (ma_mb * row1I[2] + a_mb * row3I[2] + ma_b * row2I[2] + a_b * row4I[2]) + 0.5f;
- outI[3] = (ma_mb * row1I[3] + a_mb * row3I[3] + ma_b * row2I[3] + a_b * row4I[3]) + 0.5f;
+ else {
+ BLI_bilinear_interpolation_char((unsigned char*) in->rect, outI, in->x, in->y, 4, u, v);
}
}
diff --git a/source/blender/imbuf/intern/jp2.c b/source/blender/imbuf/intern/jp2.c
index d94f6368298..3a2bf99c75c 100644
--- a/source/blender/imbuf/intern/jp2.c
+++ b/source/blender/imbuf/intern/jp2.c
@@ -387,8 +387,8 @@ BLI_INLINE int DOWNSAMPLE_FLOAT_TO_16BIT(const float _val)
/*
* 2048x1080 (2K) at 24 fps or 48 fps, or 4096x2160 (4K) at 24 fps; 3x12 bits per pixel, XYZ color space
*
- * - In 2K, for Scope (2.39:1) presentation 2048x858 pixels of the imager is used
- * - In 2K, for Flat (1.85:1) presentation 1998x1080 pixels of the imager is used
+ * - In 2K, for Scope (2.39:1) presentation 2048x858 pixels of the image is used
+ * - In 2K, for Flat (1.85:1) presentation 1998x1080 pixels of the image is used
*/
/* ****************************** COPIED FROM image_to_j2k.c */
diff --git a/source/blender/imbuf/intern/jpeg.c b/source/blender/imbuf/intern/jpeg.c
index d96a01d7093..758617bdd48 100644
--- a/source/blender/imbuf/intern/jpeg.c
+++ b/source/blender/imbuf/intern/jpeg.c
@@ -348,25 +348,12 @@ static ImBuf *ibJpegImageFromCinfo(struct jpeg_decompress_struct *cinfo, int fla
g = *buffer++;
b = *buffer++;
k = *buffer++;
-
- k = 255 - k;
- r -= k;
- if (r & 0xffffff00) {
- if (r < 0) r = 0;
- else r = 255;
- }
- g -= k;
- if (g & 0xffffff00) {
- if (g < 0) g = 0;
- else g = 255;
- }
- b -= k;
- if (b & 0xffffff00) {
- if (b < 0) b = 0;
- else b = 255;
- }
-
- rect[3] = 255 - k;
+
+ r = (r * k) / 255;
+ g = (g * k) / 255;
+ b = (b * k) / 255;
+
+ rect[3] = 255;
rect[2] = b;
rect[1] = g;
rect[0] = r;
diff --git a/source/blender/imbuf/intern/openexr/CMakeLists.txt b/source/blender/imbuf/intern/openexr/CMakeLists.txt
index d5cb8e8a3b6..6c428afe535 100644
--- a/source/blender/imbuf/intern/openexr/CMakeLists.txt
+++ b/source/blender/imbuf/intern/openexr/CMakeLists.txt
@@ -52,4 +52,6 @@ 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/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp
index 60c6e184070..da7b31cc2ba 100644
--- a/source/blender/imbuf/intern/openexr/openexr_api.cpp
+++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp
@@ -72,21 +72,6 @@ _CRTIMP void __cdecl _invalid_parameter_noinfo(void)
#include <iostream>
-#if defined(_WIN32) && !defined(FREE_WINDOWS)
-#include <half.h>
-#include <Iex/Iex.h>
-#include <IlmImf/ImfVersion.h>
-#include <IlmImf/ImfArray.h>
-#include <IlmImf/ImfIO.h>
-#include <IlmImf/ImfChannelList.h>
-#include <IlmImf/ImfPixelType.h>
-#include <IlmImf/ImfInputFile.h>
-#include <IlmImf/ImfOutputFile.h>
-#include <IlmImf/ImfCompression.h>
-#include <IlmImf/ImfCompressionAttribute.h>
-#include <IlmImf/ImfStringAttribute.h>
-#include <Imath/ImathBox.h>
-#else
#include <half.h>
#include <Iex.h>
#include <ImfVersion.h>
@@ -100,7 +85,6 @@ _CRTIMP void __cdecl _invalid_parameter_noinfo(void)
#include <ImfCompression.h>
#include <ImfCompressionAttribute.h>
#include <ImfStringAttribute.h>
-#endif
using namespace Imf;
using namespace Imath;
@@ -881,7 +865,7 @@ void IMB_exr_close(void *handle)
/* get a substring from the end of the name, separated by '.' */
static int imb_exr_split_token(const char *str, const char *end, const char **token)
{
- int maxlen = end - str;
+ ptrdiff_t maxlen = end - str;
int len = 0;
while (len < maxlen && *(end - len - 1) != '.') {
len++;
@@ -1183,7 +1167,7 @@ struct ImBuf *imb_load_openexr(unsigned char *mem, size_t size, int flags, char
frameBuffer.insert(exr_rgba_channelname(file, "B"),
Slice(Imf::FLOAT, (char *) (first + 2), xstride, ystride));
- /* 1.0 is fill value, this still neesd to be assigned even when (is_alpha == 0) */
+ /* 1.0 is fill value, this still needs to be assigned even when (is_alpha == 0) */
frameBuffer.insert(exr_rgba_channelname(file, "A"),
Slice(Imf::FLOAT, (char *) (first + 3), xstride, ystride, 1, 1, 1.0f));
diff --git a/source/blender/imbuf/intern/openexr/openexr_multi.h b/source/blender/imbuf/intern/openexr/openexr_multi.h
index 78071975c72..376d2401b1c 100644
--- a/source/blender/imbuf/intern/openexr/openexr_multi.h
+++ b/source/blender/imbuf/intern/openexr/openexr_multi.h
@@ -35,10 +35,10 @@
/* experiment with more advanced exr api */
-/* Note: as for now openexr only supports 32 chars in channel names.
- * This api also supports max 8 channels per pass now. easy to fix! */
-#define EXR_LAY_MAXNAME 51
-#define EXR_PASS_MAXNAME 11
+/* XXX layer+pass name max 64? */
+/* This api also supports max 8 channels per pass now. easy to fix! */
+#define EXR_LAY_MAXNAME 64
+#define EXR_PASS_MAXNAME 64
#define EXR_TOT_MAXNAME 64
#define EXR_PASS_MAXCHAN 8
diff --git a/source/blender/imbuf/intern/scaling.c b/source/blender/imbuf/intern/scaling.c
index b9525ccccf1..1e701b8d615 100644
--- a/source/blender/imbuf/intern/scaling.c
+++ b/source/blender/imbuf/intern/scaling.c
@@ -1467,10 +1467,10 @@ struct ImBuf *IMB_scaleImBuf(struct ImBuf *ibuf, unsigned int newx, unsigned int
return ibuf;
}
- if (newx < ibuf->x) if (newx) scaledownx(ibuf, newx);
- if (newy < ibuf->y) if (newy) scaledowny(ibuf, newy);
- if (newx > ibuf->x) if (newx) scaleupx(ibuf, newx);
- if (newy > ibuf->y) if (newy) scaleupy(ibuf, newy);
+ if (newx && (newx < ibuf->x)) scaledownx(ibuf, newx);
+ if (newy && (newy < ibuf->y)) scaledowny(ibuf, newy);
+ if (newx && (newx > ibuf->x)) scaleupx(ibuf, newx);
+ if (newy && (newy > ibuf->y)) scaleupy(ibuf, newy);
return(ibuf);
}
diff --git a/source/blender/imbuf/intern/util.c b/source/blender/imbuf/intern/util.c
index fe138a71a4a..42fb0c79b62 100644
--- a/source/blender/imbuf/intern/util.c
+++ b/source/blender/imbuf/intern/util.c
@@ -228,16 +228,27 @@ static int isqtime(const char *name)
#ifdef WITH_FFMPEG
+#ifdef _MSC_VER
+#define va_copy(dst, src) ((dst) = (src))
+#endif
+
/* BLI_vsnprintf in ffmpeg_log_callback() causes invalid warning */
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wmissing-format-attribute"
+#ifdef __GNUC__
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wmissing-format-attribute"
+#endif
static char ffmpeg_last_error[1024];
static void ffmpeg_log_callback(void *ptr, int level, const char *format, va_list arg)
{
if (ELEM(level, AV_LOG_FATAL, AV_LOG_ERROR)) {
- size_t n = BLI_vsnprintf(ffmpeg_last_error, sizeof(ffmpeg_last_error), format, arg);
+ size_t n;
+ va_list arg2;
+
+ va_copy(arg2, arg);
+
+ n = BLI_vsnprintf(ffmpeg_last_error, sizeof(ffmpeg_last_error), format, arg2);
/* strip trailing \n */
ffmpeg_last_error[n - 1] = '\0';
@@ -249,7 +260,9 @@ static void ffmpeg_log_callback(void *ptr, int level, const char *format, va_lis
}
}
-#pragma GCC diagnostic pop
+#ifdef __GNUC__
+# pragma GCC diagnostic pop
+#endif
void IMB_ffmpeg_init(void)
{
diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h
index d8d1ad78451..f227af78dab 100644
--- a/source/blender/makesdna/DNA_action_types.h
+++ b/source/blender/makesdna/DNA_action_types.h
@@ -372,7 +372,7 @@ typedef enum ePose_Flags {
/* bPose->iksolver and bPose->ikparam->iksolver */
typedef enum ePose_IKSolverType {
- IKSOLVER_LEGACY = 0,
+ IKSOLVER_STANDARD = 0,
IKSOLVER_ITASC = 1
} ePose_IKSolverType;
diff --git a/source/blender/makesdna/DNA_gpencil_types.h b/source/blender/makesdna/DNA_gpencil_types.h
index 100968e7257..b64fc08a47a 100644
--- a/source/blender/makesdna/DNA_gpencil_types.h
+++ b/source/blender/makesdna/DNA_gpencil_types.h
@@ -41,6 +41,7 @@
typedef struct bGPDspoint {
float x, y, z; /* co-ordinates of point (usually 2d, but can be 3d as well) */
float pressure; /* pressure of input device (from 0 to 1) at this point */
+ float time; /* seconds since start of stroke */
} bGPDspoint;
/* Grease-Pencil Annotations - 'Stroke'
@@ -49,12 +50,14 @@ typedef struct bGPDspoint {
*/
typedef struct bGPDstroke {
struct bGPDstroke *next, *prev;
-
bGPDspoint *points; /* array of data-points for stroke */
+ void *pad; /* keep 4 pointers at the beginning, padding for 'inittime' is tricky 64/32bit */
int totpoints; /* number of data-points in array */
short thickness; /* thickness of stroke (currently not used) */
short flag; /* various settings about this stroke */
+
+ double inittime; /* Init time of stroke */
} bGPDstroke;
/* bGPDstroke->flag */
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 2c896e4893f..3875a0d5799 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -76,6 +76,7 @@ typedef enum ModifierType {
eModifierType_Remesh = 41,
eModifierType_Skin = 42,
eModifierType_LaplacianSmooth = 43,
+ eModifierType_Triangulate = 44,
NUM_MODIFIER_TYPES
} ModifierType;
@@ -1114,11 +1115,23 @@ enum {
MOD_SKIN_SMOOTH_SHADING = 1
};
+/* Triangulate modifier */
+
+typedef struct TriangulateModifierData {
+ ModifierData modifier;
+ int flag;
+ int pad;
+} TriangulateModifierData;
+
+enum {
+ MOD_TRIANGULATE_BEAUTY = (1 << 0),
+};
+
/* Smooth modifier flags */
#define MOD_LAPLACIANSMOOTH_X (1<<1)
#define MOD_LAPLACIANSMOOTH_Y (1<<2)
#define MOD_LAPLACIANSMOOTH_Z (1<<3)
-#define MOD_LAPLACIANSMOOTH_VOLUME_PRESERVATION (1<<4)
+#define MOD_LAPLACIANSMOOTH_PRESERVE_VOLUME (1 << 4)
typedef struct LaplacianSmoothModifierData {
ModifierData modifier;
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index 9dc4480fc35..a5af4234503 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -1200,7 +1200,8 @@ typedef struct Scene {
#define R_NO_OVERWRITE 0x400000 /* skip existing files */
#define R_TOUCH 0x800000 /* touch files before rendering */
#define R_SIMPLIFY 0x1000000
-#define R_PERSISTENT_DATA 0x2000000 /* keep data around for re-render */
+#define R_EDGE_FRS 0x2000000 /* R_EDGE reserved for Freestyle */
+#define R_PERSISTENT_DATA 0x4000000 /* keep data around for re-render */
/* seq_flag */
#define R_SEQ_GL_PREV 1
@@ -1453,9 +1454,9 @@ typedef struct Scene {
/* Paint.flags */
typedef enum {
- PAINT_SHOW_BRUSH = (1<<0),
- PAINT_FAST_NAVIGATE = (1<<1),
- PAINT_SHOW_BRUSH_ON_SURFACE = (1<<2),
+ PAINT_SHOW_BRUSH = (1 << 0),
+ PAINT_FAST_NAVIGATE = (1 << 1),
+ PAINT_SHOW_BRUSH_ON_SURFACE = (1 << 2),
} PaintFlags;
/* Sculpt.flags */
diff --git a/source/blender/makesdna/DNA_text_types.h b/source/blender/makesdna/DNA_text_types.h
index cf26dae402d..6ce883905d4 100644
--- a/source/blender/makesdna/DNA_text_types.h
+++ b/source/blender/makesdna/DNA_text_types.h
@@ -44,15 +44,6 @@ typedef struct TextLine {
int len, blen; /* blen unused */
} TextLine;
-typedef struct TextMarker {
- struct TextMarker *next, *prev;
-
- int lineno, start, end, pad1; /* line number and start/end character indices */
-
- int group, flags; /* see BKE_text.h for flag defines */
- unsigned char color[4], pad[4]; /* draw color of the marker */
-} TextMarker;
-
typedef struct Text {
ID id;
@@ -63,7 +54,6 @@ typedef struct Text {
ListBase lines;
TextLine *curl, *sell;
int curc, selc;
- ListBase markers;
char *undo_buf;
int undo_pos, undo_len;
@@ -78,7 +68,6 @@ typedef struct Text {
/* text flags */
#define TXT_ISDIRTY 0x0001
-#define TXT_DEPRECATED 0x0004 /* deprecated ISTMP flag */
#define TXT_ISMEM 0x0004
#define TXT_ISEXT 0x0008
#define TXT_ISSCRIPT 0x0010 /* used by space handler scriptlinks */
diff --git a/source/blender/makesdna/DNA_tracking_types.h b/source/blender/makesdna/DNA_tracking_types.h
index 9c80d30bca4..12819303b26 100644
--- a/source/blender/makesdna/DNA_tracking_types.h
+++ b/source/blender/makesdna/DNA_tracking_types.h
@@ -163,7 +163,7 @@ typedef struct MovieTrackingSettings {
/* ** reconstruction settings ** */
int keyframe1 DNA_DEPRECATED,
- keyframe2 DNA_DEPRECATED; /* two keyframes for reconstrution initialization
+ keyframe2 DNA_DEPRECATED; /* two keyframes for reconstruction initialization
* were moved to per-tracking object settings
*/
@@ -228,7 +228,7 @@ typedef struct MovieTrackingObject {
MovieTrackingReconstruction reconstruction; /* reconstruction data for this object */
/* reconstruction options */
- int keyframe1, keyframe2; /* two keyframes for reconstrution initialization */
+ int keyframe1, keyframe2; /* two keyframes for reconstruction initialization */
} MovieTrackingObject;
typedef struct MovieTrackingStats {
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index 69e67461a56..2e2f65dbec7 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -600,7 +600,7 @@ typedef enum eOpenGL_RenderingOptions {
/* backwards compatibilty in do_versions! */
USER_DISABLE_MIPMAP = (1 << 2),
USER_DISABLE_VBO = (1 << 3),
- USER_DISABLE_AA = (1 << 4),
+ /* USER_DISABLE_AA = (1 << 4), */ /* DEPRECATED */
} eOpenGL_RenderingOptions;
/* wm draw method */
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index 5f667db4425..2b68cc8bdc1 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -148,6 +148,7 @@ extern StructRNA RNA_CompositorNodeLevels;
extern StructRNA RNA_CompositorNodeLumaMatte;
extern StructRNA RNA_CompositorNodeMapUV;
extern StructRNA RNA_CompositorNodeMapValue;
+extern StructRNA RNA_CompositorNodeMapRange;
extern StructRNA RNA_CompositorNodeMath;
extern StructRNA RNA_CompositorNodeMask;
extern StructRNA RNA_CompositorNodeMixRGB;
@@ -525,7 +526,6 @@ extern StructRNA RNA_TextBox;
extern StructRNA RNA_TextCharacterFormat;
extern StructRNA RNA_TextCurve;
extern StructRNA RNA_TextLine;
-extern StructRNA RNA_TextMarker;
extern StructRNA RNA_Texture;
extern StructRNA RNA_TextureNode;
extern StructRNA RNA_TextureNodeBricks;
@@ -1053,6 +1053,11 @@ __attribute__ ((format(printf, 1, 2)))
#endif
;
+/* Equals test (skips pointers and collections) */
+
+int RNA_property_equals(struct PointerRNA *a, struct PointerRNA *b, struct PropertyRNA *prop);
+int RNA_struct_equals(struct PointerRNA *a, struct PointerRNA *b);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c
index 7a3bb230a78..9b1a947941c 100644
--- a/source/blender/makesrna/intern/makesrna.c
+++ b/source/blender/makesrna/intern/makesrna.c
@@ -1223,6 +1223,89 @@ static char *rna_def_property_lookup_int_func(FILE *f, StructRNA *srna, Property
return func;
}
+static char *rna_def_property_lookup_string_func(FILE *f, StructRNA *srna, PropertyRNA *prop, PropertyDefRNA *dp,
+ const char *manualfunc, const char *item_type)
+{
+ char *func;
+ StructRNA *item_srna, *item_name_base;
+ PropertyRNA *item_name_prop;
+ const int namebuflen = 1024;
+
+ if (prop->flag & PROP_IDPROPERTY && manualfunc == NULL)
+ return NULL;
+
+ if (!manualfunc) {
+ if (!dp->dnastructname || !dp->dnaname)
+ return NULL;
+
+ /* only supported for collection items with name properties */
+ item_srna = rna_find_struct(item_type);
+ if (item_srna && item_srna->nameproperty) {
+ item_name_prop = item_srna->nameproperty;
+ item_name_base = item_srna;
+ while (item_name_base->base && item_name_base->base->nameproperty == item_name_prop)
+ item_name_base = item_name_base->base;
+ }
+ else
+ return NULL;
+ }
+
+ func = rna_alloc_function_name(srna->identifier, rna_safe_id(prop->identifier), "lookup_string");
+
+ fprintf(f, "int %s(PointerRNA *ptr, const char *key, PointerRNA *r_ptr)\n", func);
+ fprintf(f, "{\n");
+
+ if (manualfunc) {
+ fprintf(f, " return %s(ptr, key, r_ptr);\n", manualfunc);
+ fprintf(f, "}\n\n");
+ return func;
+ }
+
+ /* XXX extern declaration could be avoid by including RNA_blender.h, but this has lots of unknown
+ * DNA types in functions, leading to conflicting function signatures.
+ */
+ fprintf(f, " extern int %s_%s_length(PointerRNA *);\n", item_name_base->identifier, rna_safe_id(item_name_prop->identifier));
+ fprintf(f, " extern void %s_%s_get(PointerRNA *, char *);\n\n", item_name_base->identifier, rna_safe_id(item_name_prop->identifier));
+
+ fprintf(f, " int found= 0;\n");
+ fprintf(f, " CollectionPropertyIterator iter;\n");
+ fprintf(f, " char namebuf[%d];\n", namebuflen);
+ fprintf(f, " char *name;\n\n");
+
+ fprintf(f, " %s_%s_begin(&iter, ptr);\n\n", srna->identifier, rna_safe_id(prop->identifier));
+
+ fprintf(f, " while (iter.valid) {\n");
+ fprintf(f, " int namelen = %s_%s_length(&iter.ptr);\n", item_name_base->identifier, rna_safe_id(item_name_prop->identifier));
+ fprintf(f, " if (namelen < %d) {\n", namebuflen);
+ fprintf(f, " %s_%s_get(&iter.ptr, namebuf);\n", item_name_base->identifier, rna_safe_id(item_name_prop->identifier));
+ fprintf(f, " if (strcmp(namebuf, key) == 0) {\n");
+ fprintf(f, " found = 1;\n");
+ fprintf(f, " *r_ptr = iter.ptr;\n");
+ fprintf(f, " break;\n");
+ fprintf(f, " }\n");
+ fprintf(f, " }\n");
+ fprintf(f, " else {\n");
+ fprintf(f, " name = MEM_mallocN(namelen+1, \"name string\");\n");
+ fprintf(f, " %s_%s_get(&iter.ptr, name);\n", item_name_base->identifier, rna_safe_id(item_name_prop->identifier));
+ fprintf(f, " if (strcmp(name, key) == 0) {\n");
+ fprintf(f, " MEM_freeN(name);\n\n");
+ fprintf(f, " found = 1;\n");
+ fprintf(f, " *r_ptr = iter.ptr;\n");
+ fprintf(f, " break;\n");
+ fprintf(f, " }\n");
+ fprintf(f, " else\n");
+ fprintf(f, " MEM_freeN(name);\n");
+ fprintf(f, " }\n");
+ fprintf(f, " %s_%s_next(&iter);\n", srna->identifier, rna_safe_id(prop->identifier));
+ fprintf(f, " }\n");
+ fprintf(f, " %s_%s_end(&iter);\n\n", srna->identifier, rna_safe_id(prop->identifier));
+
+ fprintf(f, " return found;\n");
+ fprintf(f, "}\n\n");
+
+ return func;
+}
+
static char *rna_def_property_next_func(FILE *f, StructRNA *srna, PropertyRNA *prop, PropertyDefRNA *UNUSED(dp),
const char *manualfunc)
{
@@ -1403,6 +1486,7 @@ static void rna_def_property_funcs(FILE *f, StructRNA *srna, PropertyDefRNA *dp)
{
CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)prop;
const char *nextfunc = (const char *)cprop->next;
+ const char *item_type = (const char *)cprop->item_type;
if (dp->dnatype && strcmp(dp->dnatype, "ListBase") == 0) {
/* pass */
@@ -1426,6 +1510,8 @@ static void rna_def_property_funcs(FILE *f, StructRNA *srna, PropertyDefRNA *dp)
cprop->end = (void *)rna_def_property_end_func(f, srna, prop, dp, (const char *)cprop->end);
cprop->lookupint = (void *)rna_def_property_lookup_int_func(f, srna, prop, dp,
(const char *)cprop->lookupint, nextfunc);
+ cprop->lookupstring = (void *)rna_def_property_lookup_string_func(f, srna, prop, dp,
+ (const char *)cprop->lookupstring, item_type);
if (!(prop->flag & PROP_IDPROPERTY)) {
if (!cprop->begin) {
@@ -3171,6 +3257,8 @@ static void rna_generate(BlenderRNA *brna, FILE *f, const char *filename, const
fprintf(f, "#include <string.h>\n\n");
fprintf(f, "#include <stddef.h>\n\n");
+ fprintf(f, "#include \"MEM_guardedalloc.h\"\n\n");
+
fprintf(f, "#include \"DNA_ID.h\"\n");
fprintf(f, "#include \"DNA_scene_types.h\"\n");
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index 69332dcd250..07febfb85f4 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -1224,10 +1224,10 @@ void RNA_property_enum_items_gettexted(bContext *C, PointerRNA *ptr, PropertyRNA
if (prop->translation_context)
nitem[i].name = BLF_pgettext(prop->translation_context, nitem[i].name);
else
- nitem[i].name = BLF_gettext(nitem[i].name);
+ nitem[i].name = BLF_pgettext(NULL, nitem[i].name);
}
if (nitem[i].description)
- nitem[i].description = BLF_gettext(nitem[i].description);
+ nitem[i].description = BLF_pgettext(NULL, nitem[i].description);
}
*item = nitem;
@@ -2551,7 +2551,10 @@ PointerRNA RNA_property_pointer_get(PointerRNA *ptr, PropertyRNA *prop)
pprop = (PointerPropertyRNA *)prop;
/* for groups, data is idprop itself */
- return rna_pointer_inherit_refine(ptr, pprop->type, idprop);
+ if (pprop->typef)
+ return rna_pointer_inherit_refine(ptr, pprop->typef(ptr), idprop);
+ else
+ return rna_pointer_inherit_refine(ptr, pprop->type, idprop);
}
else if (pprop->get) {
return pprop->get(ptr);
@@ -5718,7 +5721,7 @@ int RNA_property_copy(PointerRNA *ptr, PointerRNA *fromptr, PropertyRNA *prop, i
/* get the length of the array to work with */
len = RNA_property_array_length(ptr, prop);
- fromlen = RNA_property_array_length(ptr, prop);
+ fromlen = RNA_property_array_length(fromptr, prop);
if (len != fromlen)
return 0;
@@ -5832,3 +5835,142 @@ void _RNA_warning(const char *format, ...)
}
#endif
}
+
+int RNA_property_equals(PointerRNA *a, PointerRNA *b, PropertyRNA *prop)
+{
+ /* get the length of the array to work with */
+ int len = RNA_property_array_length(a, prop);
+ int fromlen = RNA_property_array_length(b, prop);
+
+ if (len != fromlen)
+ return 0;
+
+ /* get and set the default values as appropriate for the various types */
+ switch (RNA_property_type(prop)) {
+ case PROP_BOOLEAN: {
+ if (len) {
+ int fixed_a[16], fixed_b[16];
+ int *array_a, *array_b;
+ int equals;
+
+ array_a = (len > 16)? MEM_callocN(sizeof(int) * len, "RNA equals"): fixed_a;
+ array_b = (len > 16)? MEM_callocN(sizeof(int) * len, "RNA equals"): fixed_b;
+
+ RNA_property_boolean_get_array(a, prop, array_a);
+ RNA_property_boolean_get_array(b, prop, array_b);
+
+ equals = memcmp(array_a, array_b, sizeof(int) * len) == 0;
+
+ if (array_a != fixed_a) MEM_freeN(array_a);
+ if (array_b != fixed_b) MEM_freeN(array_b);
+
+ return equals;
+ }
+ else {
+ int value = RNA_property_boolean_get(a, prop);
+ return value == RNA_property_boolean_get(b, prop);
+ }
+ }
+
+ case PROP_INT: {
+ if (len) {
+ int fixed_a[16], fixed_b[16];
+ int *array_a, *array_b;
+ int equals;
+
+ array_a = (len > 16)? MEM_callocN(sizeof(int) * len, "RNA equals"): fixed_a;
+ array_b = (len > 16)? MEM_callocN(sizeof(int) * len, "RNA equals"): fixed_b;
+
+ RNA_property_int_get_array(a, prop, array_a);
+ RNA_property_int_get_array(b, prop, array_b);
+
+ equals = memcmp(array_a, array_b, sizeof(int) * len) == 0;
+
+ if (array_a != fixed_a) MEM_freeN(array_a);
+ if (array_b != fixed_b) MEM_freeN(array_b);
+
+ return equals;
+ }
+ else {
+ int value = RNA_property_int_get(a, prop);
+ return value == RNA_property_int_get(b, prop);
+ }
+ }
+
+ case PROP_FLOAT: {
+ if (len) {
+ float fixed_a[16], fixed_b[16];
+ float *array_a, *array_b;
+ int equals;
+
+ array_a = (len > 16)? MEM_callocN(sizeof(float) * len, "RNA equals"): fixed_a;
+ array_b = (len > 16)? MEM_callocN(sizeof(float) * len, "RNA equals"): fixed_b;
+
+ RNA_property_float_get_array(a, prop, array_a);
+ RNA_property_float_get_array(b, prop, array_b);
+
+ equals = memcmp(array_a, array_b, sizeof(float) * len) == 0;
+
+ if (array_a != fixed_a) MEM_freeN(array_a);
+ if (array_b != fixed_b) MEM_freeN(array_b);
+
+ return equals;
+ }
+ else {
+ float value = RNA_property_float_get(a, prop);
+ return value == RNA_property_float_get(b, prop);
+ }
+ }
+
+ case PROP_ENUM: {
+ int value = RNA_property_enum_get(a, prop);
+ return value == RNA_property_enum_get(b, prop);
+ }
+
+ case PROP_STRING: {
+ char fixed_a[128], fixed_b[128];
+ int len_a, len_b;
+ char *value_a = RNA_property_string_get_alloc(a, prop, fixed_a, sizeof(fixed_a), &len_a);
+ char *value_b = RNA_property_string_get_alloc(b, prop, fixed_b, sizeof(fixed_b), &len_b);
+ int equals = strcmp(value_a, value_b) == 0;
+
+ if (value_a != fixed_a) MEM_freeN(value_a);
+ if (value_b != fixed_b) MEM_freeN(value_b);
+
+ return equals;
+ }
+
+ default:
+ break;
+ }
+
+ return 1;
+}
+
+int RNA_struct_equals(PointerRNA *a, PointerRNA *b)
+{
+ CollectionPropertyIterator iter;
+ CollectionPropertyRNA *citerprop;
+ PropertyRNA *iterprop;
+ int equals = 1;
+
+ if (a->type != b->type)
+ return 0;
+
+ iterprop = RNA_struct_iterator_property(a->type);
+ citerprop = (CollectionPropertyRNA *)rna_ensure_property(iterprop);
+
+ RNA_property_collection_begin(a, iterprop, &iter);
+ for (; iter.valid; RNA_property_collection_next(&iter)) {
+ PropertyRNA *prop = iter.ptr.data;
+
+ if (!RNA_property_equals(a, b, prop)) {
+ equals = 0;
+ break;
+ }
+ }
+ RNA_property_collection_end(&iter);
+
+ return equals;
+}
+
diff --git a/source/blender/makesrna/intern/rna_actuator.c b/source/blender/makesrna/intern/rna_actuator.c
index b1fdfccd0be..b653289e44d 100644
--- a/source/blender/makesrna/intern/rna_actuator.c
+++ b/source/blender/makesrna/intern/rna_actuator.c
@@ -973,13 +973,13 @@ static void rna_def_sound_actuator(BlenderRNA *brna)
RNA_def_property_ui_range(prop, 0.0, 1.0, 1, 2);
RNA_def_property_range(prop, 0.0, 2.0);
RNA_def_property_ui_text(prop, "Volume", "Initial volume of the sound");
- RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_AUDIO);
+ RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_ID_SOUND);
RNA_def_property_update(prop, NC_LOGIC, NULL);
prop = RNA_def_property(srna, "pitch", PROP_FLOAT, PROP_NONE);
RNA_def_property_ui_range(prop, -12.0, 12.0, 1, 2);
RNA_def_property_ui_text(prop, "Pitch", "Pitch of the sound");
- RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_AUDIO);
+ RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_ID_SOUND);
RNA_def_property_update(prop, NC_LOGIC, NULL);
/* floats - 3D Parameters */
diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c
index 7b6b629ca82..30a9bfd81f6 100644
--- a/source/blender/makesrna/intern/rna_constraint.c
+++ b/source/blender/makesrna/intern/rna_constraint.c
@@ -614,7 +614,7 @@ static void rna_def_constraint_kinematic(BlenderRNA *brna)
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_dependency_update");
prop = RNA_def_property(srna, "iterations", PROP_INT, PROP_NONE);
- RNA_def_property_range(prop, 1, 10000);
+ RNA_def_property_range(prop, 0, 10000);
RNA_def_property_ui_text(prop, "Iterations", "Maximum number of solving iterations");
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c
index 1e1a8c82b8e..21aed20ccc3 100644
--- a/source/blender/makesrna/intern/rna_curve.c
+++ b/source/blender/makesrna/intern/rna_curve.c
@@ -1424,7 +1424,7 @@ static void rna_def_curve(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_map_taper", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", CU_MAP_TAPER);
- RNA_def_property_ui_text(prop, "Map Taper", "Map effect of taper object on actually bevelled curve");
+ RNA_def_property_ui_text(prop, "Map Taper", "Map effect of taper object on actually beveled curve");
RNA_def_property_update(prop, 0, "rna_Curve_update_data");
/* texture space */
diff --git a/source/blender/makesrna/intern/rna_image.c b/source/blender/makesrna/intern/rna_image.c
index f8af2427827..9fedbee41ff 100644
--- a/source/blender/makesrna/intern/rna_image.c
+++ b/source/blender/makesrna/intern/rna_image.c
@@ -113,7 +113,7 @@ static void rna_Image_fields_update(Main *UNUSED(bmain), Scene *UNUSED(scene), P
BKE_image_signal(ima, NULL, IMA_SIGNAL_FREE);
}
- BKE_image_release_ibuf(ima, lock);
+ BKE_image_release_ibuf(ima, ibuf, lock);
}
static void rna_Image_free_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
@@ -187,8 +187,12 @@ static EnumPropertyItem *rna_Image_source_itemf(bContext *UNUSED(C), PointerRNA
static int rna_Image_file_format_get(PointerRNA *ptr)
{
Image *image = (Image *)ptr->data;
- ImBuf *ibuf = BKE_image_get_ibuf(image, NULL);
- return BKE_ftype_to_imtype(ibuf ? ibuf->ftype : 0);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(image, NULL, NULL);
+ int imtype = BKE_ftype_to_imtype(ibuf ? ibuf->ftype : 0);
+
+ BKE_image_release_ibuf(image, ibuf, NULL);
+
+ return imtype;
}
static void rna_Image_file_format_set(PointerRNA *ptr, int value)
@@ -199,12 +203,13 @@ static void rna_Image_file_format_set(PointerRNA *ptr, int value)
int ftype = BKE_imtype_to_ftype(value);
#if 0
- ibuf = BKE_image_get_ibuf(image, NULL);
+ ibuf = BKE_image_acquire_ibuf(image, NULL, NULL);
if (ibuf)
ibuf->ftype = ftype;
#endif
/* to be safe change all buffer file types */
+ /* TODO: this is never threadsafe */
for (ibuf = image->ibufs.first; ibuf; ibuf = ibuf->next) {
ibuf->ftype = ftype;
}
@@ -237,7 +242,7 @@ static void rna_Image_size_get(PointerRNA *ptr, int *values)
values[1] = 0;
}
- BKE_image_release_ibuf(im, lock);
+ BKE_image_release_ibuf(im, ibuf, lock);
}
static void rna_Image_resolution_get(PointerRNA *ptr, float *values)
@@ -256,7 +261,7 @@ static void rna_Image_resolution_get(PointerRNA *ptr, float *values)
values[1] = 0;
}
- BKE_image_release_ibuf(im, lock);
+ BKE_image_release_ibuf(im, ibuf, lock);
}
static void rna_Image_resolution_set(PointerRNA *ptr, const float *values)
@@ -271,7 +276,7 @@ static void rna_Image_resolution_set(PointerRNA *ptr, const float *values)
ibuf->ppm[1] = values[1];
}
- BKE_image_release_ibuf(im, lock);
+ BKE_image_release_ibuf(im, ibuf, lock);
}
static int rna_Image_depth_get(PointerRNA *ptr)
@@ -290,7 +295,7 @@ static int rna_Image_depth_get(PointerRNA *ptr)
else
planes = ibuf->planes;
- BKE_image_release_ibuf(im, lock);
+ BKE_image_release_ibuf(im, ibuf, lock);
return planes;
}
@@ -317,7 +322,7 @@ static int rna_Image_pixels_get_length(PointerRNA *ptr, int length[RNA_MAX_ARRAY
else
length[0] = 0;
- BKE_image_release_ibuf(ima, lock);
+ BKE_image_release_ibuf(ima, ibuf, lock);
return length[0];
}
@@ -343,7 +348,7 @@ static void rna_Image_pixels_get(PointerRNA *ptr, float *values)
}
}
- BKE_image_release_ibuf(ima, lock);
+ BKE_image_release_ibuf(ima, ibuf, lock);
}
static void rna_Image_pixels_set(PointerRNA *ptr, const float *values)
@@ -369,7 +374,7 @@ static void rna_Image_pixels_set(PointerRNA *ptr, const float *values)
ibuf->userflags |= IB_BITMAPDIRTY | IB_DISPLAY_BUFFER_INVALID;
}
- BKE_image_release_ibuf(ima, lock);
+ BKE_image_release_ibuf(ima, ibuf, lock);
}
#else
diff --git a/source/blender/makesrna/intern/rna_image_api.c b/source/blender/makesrna/intern/rna_image_api.c
index 4d951b54c26..3c04fcc89ec 100644
--- a/source/blender/makesrna/intern/rna_image_api.c
+++ b/source/blender/makesrna/intern/rna_image_api.c
@@ -98,7 +98,7 @@ static void rna_Image_save_render(Image *image, bContext *C, ReportList *reports
IMB_freeImBuf(write_ibuf);
}
- BKE_image_release_ibuf(image, lock);
+ BKE_image_release_ibuf(image, ibuf, lock);
}
else {
BKE_report(reports, RPT_ERROR, "Scene not in context, could not get save parameters");
@@ -107,7 +107,7 @@ static void rna_Image_save_render(Image *image, bContext *C, ReportList *reports
static void rna_Image_save(Image *image, ReportList *reports)
{
- ImBuf *ibuf = BKE_image_get_ibuf(image, NULL);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(image, NULL, NULL);
if (ibuf) {
char filename[FILE_MAX];
BLI_strncpy(filename, image->name, sizeof(filename));
@@ -135,11 +135,13 @@ static void rna_Image_save(Image *image, ReportList *reports)
else {
BKE_reportf(reports, RPT_ERROR, "Image '%s' does not have any image data", image->id.name + 2);
}
+
+ BKE_image_release_ibuf(image, ibuf, NULL);
}
static void rna_Image_pack(Image *image, ReportList *reports, int as_png)
{
- ImBuf *ibuf = BKE_image_get_ibuf(image, NULL);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(image, NULL, NULL);
if (!as_png && (ibuf && (ibuf->userflags & IB_BITMAPDIRTY))) {
BKE_report(reports, RPT_ERROR, "Cannot pack edited image from disk, only as internal PNG");
@@ -152,6 +154,8 @@ static void rna_Image_pack(Image *image, ReportList *reports, int as_png)
image->packedfile = newPackedFile(reports, image->name, ID_BLEND_PATH(G.main, &image->id));
}
}
+
+ BKE_image_release_ibuf(image, ibuf, NULL);
}
static void rna_Image_unpack(Image *image, ReportList *reports, int method)
@@ -176,7 +180,7 @@ static void rna_Image_reload(Image *image)
static void rna_Image_update(Image *image, ReportList *reports)
{
- ImBuf *ibuf = BKE_image_get_ibuf(image, NULL);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(image, NULL, NULL);
if (ibuf == NULL) {
BKE_reportf(reports, RPT_ERROR, "Image '%s' does not have any image data", image->id.name + 2);
@@ -187,6 +191,8 @@ static void rna_Image_update(Image *image, ReportList *reports)
IMB_rect_from_float(ibuf);
ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
+
+ BKE_image_release_ibuf(image, ibuf, NULL);
}
static void rna_Image_scale(Image *image, ReportList *reports, int width, int height)
@@ -205,10 +211,11 @@ static int rna_Image_gl_load(Image *image, ReportList *reports, int filter, int
if (*bind)
return error;
- ibuf = BKE_image_get_ibuf(image, NULL);
+ ibuf = BKE_image_acquire_ibuf(image, NULL, NULL);
if (ibuf == NULL || ibuf->rect == NULL) {
BKE_reportf(reports, RPT_ERROR, "Image '%s' does not have any image data", image->id.name + 2);
+ BKE_image_release_ibuf(image, ibuf, NULL);
return (int)GL_INVALID_OPERATION;
}
@@ -237,6 +244,8 @@ static int rna_Image_gl_load(Image *image, ReportList *reports, int filter, int
image->bindcode = 0;
}
+ BKE_image_release_ibuf(image, ibuf, NULL);
+
return error;
}
diff --git a/source/blender/makesrna/intern/rna_lamp.c b/source/blender/makesrna/intern/rna_lamp.c
index 9d63e0e687d..af39500442d 100644
--- a/source/blender/makesrna/intern/rna_lamp.c
+++ b/source/blender/makesrna/intern/rna_lamp.c
@@ -421,7 +421,7 @@ static void rna_def_lamp(BlenderRNA *brna)
/* textures */
rna_def_mtex_common(brna, srna, "rna_Lamp_mtex_begin", "rna_Lamp_active_texture_get",
- "rna_Lamp_active_texture_set", NULL, "LampTextureSlot", "LampTextureSlots", "rna_Lamp_update");
+ "rna_Lamp_active_texture_set", NULL, "LampTextureSlot", "LampTextureSlots", "rna_Lamp_draw_update");
}
static void rna_def_lamp_falloff(StructRNA *srna)
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index a381dd489c7..9d90601c075 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -78,6 +78,7 @@ EnumPropertyItem modifier_type_items[] = {
{eModifierType_Skin, "SKIN", ICON_MOD_SKIN, "Skin", ""},
{eModifierType_Solidify, "SOLIDIFY", ICON_MOD_SOLIDIFY, "Solidify", ""},
{eModifierType_Subsurf, "SUBSURF", ICON_MOD_SUBSURF, "Subdivision Surface", ""},
+ {eModifierType_Triangulate, "TRIANGULATE", ICON_MOD_TRIANGULATE, "Triangulate", ""},
{0, "", 0, N_("Deform"), ""},
{eModifierType_Armature, "ARMATURE", ICON_MOD_ARMATURE, "Armature", ""},
{eModifierType_Cast, "CAST", ICON_MOD_CAST, "Cast", ""},
@@ -213,6 +214,8 @@ static StructRNA *rna_Modifier_refine(struct PointerRNA *ptr)
return &RNA_SkinModifier;
case eModifierType_LaplacianSmooth:
return &RNA_LaplacianSmoothModifier;
+ case eModifierType_Triangulate:
+ return &RNA_TriangulateModifier;
default:
return &RNA_Modifier;
}
@@ -1814,7 +1817,7 @@ static void rna_def_modifier_laplaciansmooth(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "use_volume_preserve", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_LAPLACIANSMOOTH_VOLUME_PRESERVATION);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_LAPLACIANSMOOTH_PRESERVE_VOLUME);
RNA_def_property_ui_text(prop, "Preserve Volume", "Apply volume preservation after smooth");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
@@ -3361,6 +3364,22 @@ static void rna_def_modifier_skin(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_Modifier_update");
}
+static void rna_def_modifier_triangulate(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna = RNA_def_struct(brna, "TriangulateModifier", "Modifier");
+ RNA_def_struct_ui_text(srna, "Triangulate Modifier", "Triangulate Mesh");
+ RNA_def_struct_sdna(srna, "TriangulateModifierData");
+ RNA_def_struct_ui_icon(srna, ICON_MOD_TRIANGULATE);
+
+ prop = RNA_def_property(srna, "use_beauty", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_TRIANGULATE_BEAUTY);
+ RNA_def_property_ui_text(prop, "Beauty Subdivide", "Subdivide across shortest diagonal");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+}
+
void RNA_def_modifier(BlenderRNA *brna)
{
StructRNA *srna;
@@ -3468,6 +3487,7 @@ void RNA_def_modifier(BlenderRNA *brna)
rna_def_modifier_remesh(brna);
rna_def_modifier_skin(brna);
rna_def_modifier_laplaciansmooth(brna);
+ rna_def_modifier_triangulate(brna);
}
#endif
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 33a41ff6f6e..1da9a450c2c 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -1140,7 +1140,7 @@ static void rna_ShaderNodeScript_update(Main *bmain, Scene *scene, PointerRNA *p
bNode *node = (bNode *)ptr->data;
RenderEngineType *engine_type = RE_engines_find(scene->r.engine);
- if(engine_type && engine_type->update_script_node) {
+ if (engine_type && engine_type->update_script_node) {
/* auto update node */
RenderEngine *engine = RE_engine_create(engine_type);
engine_type->update_script_node(engine, ntree, node);
@@ -2199,6 +2199,16 @@ static void def_cmp_map_value(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}
+static void def_cmp_map_range(StructRNA *srna)
+{
+ PropertyRNA *prop;
+
+ prop = RNA_def_property(srna, "use_clamp", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "custom1", 1);
+ RNA_def_property_ui_text(prop, "Clamp", "Clamp result of the node to 0..1 range");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+}
+
static void def_cmp_vector_blur(StructRNA *srna)
{
PropertyRNA *prop;
@@ -4641,18 +4651,22 @@ static void rna_def_node(BlenderRNA *brna)
prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", NODE_SELECT);
RNA_def_property_ui_text(prop, "Select", "");
+ RNA_def_property_update(prop, NC_NODE | NA_SELECTED, NULL);
prop = RNA_def_property(srna, "show_options", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", NODE_OPTIONS);
RNA_def_property_ui_text(prop, "Show Options", "");
+ RNA_def_property_update(prop, NC_NODE | ND_DISPLAY, NULL);
prop = RNA_def_property(srna, "show_preview", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", NODE_PREVIEW);
RNA_def_property_ui_text(prop, "Show Preview", "");
+ RNA_def_property_update(prop, NC_NODE | ND_DISPLAY, NULL);
prop = RNA_def_property(srna, "hide", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", NODE_HIDDEN);
RNA_def_property_ui_text(prop, "Hide", "");
+ RNA_def_property_update(prop, NC_NODE | ND_DISPLAY, NULL);
prop = RNA_def_property(srna, "mute", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", NODE_MUTED);
diff --git a/source/blender/makesrna/intern/rna_nodetree_types.h b/source/blender/makesrna/intern/rna_nodetree_types.h
index fbbcbae6c12..14cdbc6cf7d 100644
--- a/source/blender/makesrna/intern/rna_nodetree_types.h
+++ b/source/blender/makesrna/intern/rna_nodetree_types.h
@@ -114,6 +114,7 @@ DefNode( CompositorNode, CMP_NODE_ALPHAOVER, def_cmp_alpha_over, "ALPHA
DefNode( CompositorNode, CMP_NODE_BLUR, def_cmp_blur, "BLUR", Blur, "Blur", "" )
DefNode( CompositorNode, CMP_NODE_FILTER, def_cmp_filter, "FILTER", Filter, "Filter", "" )
DefNode( CompositorNode, CMP_NODE_MAP_VALUE, def_cmp_map_value, "MAP_VALUE", MapValue, "Map Value", "" )
+DefNode( CompositorNode, CMP_NODE_MAP_RANGE, def_cmp_map_range, "MAP_RANGE", MapRange, "Map Range", "" )
DefNode( CompositorNode, CMP_NODE_TIME, def_time, "TIME", Time, "Time", "" )
DefNode( CompositorNode, CMP_NODE_VECBLUR, def_cmp_vector_blur, "VECBLUR", VecBlur, "Vector Blur", "" )
DefNode( CompositorNode, CMP_NODE_SEPRGBA, 0, "SEPRGBA", SepRGBA, "Separate RGBA", "" )
diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c
index d436e4719ea..a669cb2558a 100644
--- a/source/blender/makesrna/intern/rna_object.c
+++ b/source/blender/makesrna/intern/rna_object.c
@@ -1643,21 +1643,23 @@ static void rna_def_object_game_settings(BlenderRNA *brna)
RNA_def_property_range(prop, 0.0, 1000.0);
RNA_def_property_ui_text(prop, "Velocity Max", "Clamp velocity to this maximum speed");
+ /* Character physics */
prop = RNA_def_property(srna, "step_height", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "step_height");
- RNA_def_property_range(prop, 0.0, 1.0);
+ RNA_def_property_range(prop, 0.01, 1.0);
RNA_def_property_ui_text(prop, "Step Height", "Maximum height of steps the character can run over");
prop = RNA_def_property(srna, "jump_speed", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "jump_speed");
RNA_def_property_range(prop, 0.0, 1000.0);
- RNA_def_property_ui_text(prop, "Jump Force", "Upward velocity applied to the character when jumping (with the Motion actuator)");
+ RNA_def_property_ui_text(prop, "Jump Force", "Upward velocity applied to the character when jumping");
prop = RNA_def_property(srna, "fall_speed", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "fall_speed");
RNA_def_property_range(prop, 0.0, 1000.0);
RNA_def_property_ui_text(prop, "Fall Speed Max", "Maximum speed at which the character will fall");
+ /* Collision Masks */
prop = RNA_def_property(srna, "collision_group", PROP_BOOLEAN, PROP_LAYER_MEMBER);
RNA_def_property_boolean_sdna(prop, NULL, "col_group", 1);
RNA_def_property_array(prop, OB_MAX_COL_MASKS);
diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c
index 412aad20a41..5c90fb8787c 100644
--- a/source/blender/makesrna/intern/rna_pose.c
+++ b/source/blender/makesrna/intern/rna_pose.c
@@ -675,7 +675,7 @@ static void rna_def_bone_group(BlenderRNA *brna)
}
static EnumPropertyItem prop_iksolver_items[] = {
- {IKSOLVER_LEGACY, "LEGACY", 0, "Legacy", "Original IK solver"},
+ {IKSOLVER_STANDARD, "LEGACY", 0, "Standard", "Original IK solver"},
{IKSOLVER_ITASC, "ITASC", 0, "iTaSC", "Multi constraint, stateful IK solver"},
{0, NULL, 0, NULL, NULL}
};
@@ -1126,7 +1126,7 @@ static void rna_def_pose_itasc(BlenderRNA *brna)
prop = RNA_def_property(srna, "iterations", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "numiter");
- RNA_def_property_range(prop, 1.f, 1000.f);
+ RNA_def_property_range(prop, 0, 1000);
RNA_def_property_ui_text(prop, "Iterations",
"Maximum number of iterations for convergence in case of reiteration");
RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Itasc_update");
@@ -1221,8 +1221,7 @@ static void rna_def_pose_ikparam(BlenderRNA *brna)
RNA_def_property_enum_sdna(prop, NULL, "iksolver");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_enum_items(prop, prop_iksolver_items);
- RNA_def_property_ui_text(prop, "IK Solver",
- "IK solver for which these parameters are defined, 0 for Legacy, 1 for iTaSC");
+ RNA_def_property_ui_text(prop, "IK Solver", "IK solver for which these parameters are defined");
}
/* pose.bone_groups */
@@ -1285,8 +1284,7 @@ static void rna_def_pose(BlenderRNA *brna)
RNA_def_property_enum_sdna(prop, NULL, "iksolver");
RNA_def_property_enum_funcs(prop, NULL, "rna_Pose_ik_solver_set", NULL);
RNA_def_property_enum_items(prop, prop_iksolver_items);
- RNA_def_property_ui_text(prop, "IK Solver",
- "Selection of IK solver for IK chain, current choice is 0 for Legacy, 1 for iTaSC");
+ RNA_def_property_ui_text(prop, "IK Solver", "Selection of IK solver for IK chain");
RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_ik_solver_update");
prop = RNA_def_property(srna, "ik_param", PROP_POINTER, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index 0ba15193985..5529c3a375e 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -1123,6 +1123,12 @@ static void rna_SceneRenderLayer_name_set(PointerRNA *ptr, const char *value)
}
}
+static char *rna_SceneRenderLayer_path(PointerRNA *ptr)
+{
+ SceneRenderLayer *srl = (SceneRenderLayer*)ptr->data;
+ return BLI_sprintfN("render.layers[\"%s\"]", srl->name);
+}
+
static int rna_RenderSettings_multiple_engines_get(PointerRNA *UNUSED(ptr))
{
return (BLI_countlist(&R_engines) > 1);
@@ -2788,6 +2794,7 @@ static void rna_def_scene_render_layer(BlenderRNA *brna)
srna = RNA_def_struct(brna, "SceneRenderLayer", NULL);
RNA_def_struct_ui_text(srna, "Scene Render Layer", "Render layer");
RNA_def_struct_ui_icon(srna, ICON_RENDERLAYERS);
+ RNA_def_struct_path_func(srna, "rna_SceneRenderLayer_path");
rna_def_render_layer_common(srna, 1);
}
@@ -3144,7 +3151,7 @@ static void rna_def_scene_ffmpeg_settings(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Volume", "Audio volume");
- RNA_def_property_translation_context(prop, "Audio");
+ RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_ID_SOUND);
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
#endif
@@ -3967,6 +3974,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_sequencer_gl_preview", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "seq_flag", R_SEQ_GL_PREV);
RNA_def_property_ui_text(prop, "Sequencer OpenGL", "");
+ RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SceneSequencer_update");
#if 0 /* see R_SEQ_GL_REND comment */
prop = RNA_def_property(srna, "use_sequencer_gl_render", PROP_BOOLEAN, PROP_NONE);
@@ -4565,7 +4573,7 @@ void RNA_def_scene(BlenderRNA *brna)
RNA_def_property_float_sdna(prop, NULL, "audio.volume");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Volume", "Audio volume");
- RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_AUDIO);
+ RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_ID_SOUND);
RNA_def_property_update(prop, NC_SCENE, NULL);
RNA_def_property_float_funcs(prop, NULL, "rna_Scene_volume_set", NULL);
diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c
index c2fa64698e4..18a9b9683f8 100644
--- a/source/blender/makesrna/intern/rna_sequencer.c
+++ b/source/blender/makesrna/intern/rna_sequencer.c
@@ -1875,7 +1875,7 @@ static void rna_def_sound(BlenderRNA *brna)
RNA_def_property_float_sdna(prop, NULL, "volume");
RNA_def_property_range(prop, 0.0f, 100.0f);
RNA_def_property_ui_text(prop, "Volume", "Playback volume of the sound");
- RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_AUDIO);
+ RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_ID_SOUND);
RNA_def_property_float_funcs(prop, NULL, "rna_Sequence_volume_set", NULL);
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
@@ -1883,7 +1883,7 @@ static void rna_def_sound(BlenderRNA *brna)
RNA_def_property_float_sdna(prop, NULL, "pitch");
RNA_def_property_range(prop, 0.1f, 10.0f);
RNA_def_property_ui_text(prop, "Pitch", "Playback pitch of the sound");
- RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_AUDIO);
+ RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_ID_SOUND);
RNA_def_property_float_funcs(prop, NULL, "rna_Sequence_pitch_set", NULL);
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index 962a92223eb..caa81dafa0e 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -598,7 +598,7 @@ static EnumPropertyItem *rna_SpaceImageEditor_draw_channels_itemf(bContext *UNUS
alpha = ibuf && (ibuf->channels == 4);
zbuf = ibuf && (ibuf->zbuf || ibuf->zbuf_float || (ibuf->channels == 1));
- ED_space_image_release_buffer(sima, lock);
+ ED_space_image_release_buffer(sima, ibuf, lock);
if (alpha && zbuf)
return draw_channels_items;
@@ -678,7 +678,7 @@ static void rna_SpaceImageEditor_scopes_update(Main *UNUSED(bmain), Scene *scene
scopes_update(&sima->scopes, ibuf, &scene->view_settings, &scene->display_settings);
WM_main_add_notifier(NC_IMAGE, sima->image);
}
- ED_space_image_release_buffer(sima, lock);
+ ED_space_image_release_buffer(sima, ibuf, lock);
}
/* Space Text Editor */
diff --git a/source/blender/makesrna/intern/rna_speaker.c b/source/blender/makesrna/intern/rna_speaker.c
index a160aaf94e2..139582104ee 100644
--- a/source/blender/makesrna/intern/rna_speaker.c
+++ b/source/blender/makesrna/intern/rna_speaker.c
@@ -152,7 +152,7 @@ static void rna_def_speaker(BlenderRNA *brna)
RNA_def_property_float_sdna(prop, NULL, "volume");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Volume", "How loud the sound is");
- RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_AUDIO);
+ RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_ID_SOUND);
/* RNA_def_property_float_funcs(prop, NULL, "rna_Speaker_volume_set", NULL); */
/* RNA_def_property_update(prop, 0, "rna_Speaker_update"); */
@@ -160,7 +160,7 @@ static void rna_def_speaker(BlenderRNA *brna)
RNA_def_property_float_sdna(prop, NULL, "pitch");
RNA_def_property_range(prop, 0.1f, 10.0f);
RNA_def_property_ui_text(prop, "Pitch", "Playback pitch of the sound");
- RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_AUDIO);
+ RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_ID_SOUND);
/* RNA_def_property_float_funcs(prop, NULL, "rna_Speaker_pitch_set", NULL); */
/* RNA_def_property_update(prop, 0, "rna_Speaker_update"); */
diff --git a/source/blender/makesrna/intern/rna_text.c b/source/blender/makesrna/intern/rna_text.c
index e46373b250c..b1637ef4c8a 100644
--- a/source/blender/makesrna/intern/rna_text.c
+++ b/source/blender/makesrna/intern/rna_text.c
@@ -129,49 +129,6 @@ static void rna_def_text_line(BlenderRNA *brna)
RNA_def_property_update(prop, NC_TEXT | NA_EDITED, NULL);
}
-static void rna_def_text_marker(BlenderRNA *brna)
-{
- StructRNA *srna;
- PropertyRNA *prop;
-
- srna = RNA_def_struct(brna, "TextMarker", NULL);
- RNA_def_struct_ui_text(srna, "Text Marker", "Marker highlighting a portion of text in a Text datablock");
-
- prop = RNA_def_property(srna, "line", PROP_INT, PROP_UNSIGNED);
- RNA_def_property_int_sdna(prop, NULL, "lineno");
- RNA_def_property_clear_flag(prop, PROP_EDITABLE);
- RNA_def_property_ui_text(prop, "Line", "Line in which the marker is located");
-
- prop = RNA_def_property(srna, "character_index_start", PROP_INT, PROP_UNSIGNED);
- RNA_def_property_int_sdna(prop, NULL, "start");
- RNA_def_property_clear_flag(prop, PROP_EDITABLE);
- RNA_def_property_ui_text(prop, "Start", "Start position of the marker in the line");
-
- prop = RNA_def_property(srna, "character_index_end", PROP_INT, PROP_UNSIGNED);
- RNA_def_property_int_sdna(prop, NULL, "end");
- RNA_def_property_clear_flag(prop, PROP_EDITABLE);
- RNA_def_property_ui_text(prop, "End", "Start position of the marker in the line");
-
- prop = RNA_def_property(srna, "group", PROP_INT, PROP_UNSIGNED);
- RNA_def_property_clear_flag(prop, PROP_EDITABLE);
- RNA_def_property_range(prop, 0, (int)0xFFFF);
- RNA_def_property_ui_text(prop, "Group", "");
-
- prop = RNA_def_property(srna, "is_temporary", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flags", TMARK_TEMP);
- RNA_def_property_clear_flag(prop, PROP_EDITABLE);
- RNA_def_property_ui_text(prop, "Temporary", "Marker is temporary");
-
- prop = RNA_def_property(srna, "use_edit_all", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flags", TMARK_EDITALL);
- RNA_def_property_clear_flag(prop, PROP_EDITABLE);
- RNA_def_property_ui_text(prop, "Edit All", "Edit all markers of the same group as one");
-
- prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR_GAMMA);
- RNA_def_property_range(prop, 0.0f, 1.0f);
- RNA_def_property_ui_text(prop, "Color", "Color to display the marker with");
-}
-
static void rna_def_text(BlenderRNA *brna)
{
StructRNA *srna;
@@ -241,17 +198,12 @@ static void rna_def_text(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Selection End Character",
"Index of character after end of selection in the selection end line");
- prop = RNA_def_property(srna, "markers", PROP_COLLECTION, PROP_NONE);
- RNA_def_property_struct_type(prop, "TextMarker");
- RNA_def_property_ui_text(prop, "Markers", "Text markers highlighting part of the text");
-
RNA_api_text(srna);
}
void RNA_def_text(BlenderRNA *brna)
{
rna_def_text_line(brna);
- rna_def_text_marker(brna);
rna_def_text(brna);
}
diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c
index e77c5d13a6b..e67985f68c5 100644
--- a/source/blender/makesrna/intern/rna_texture.c
+++ b/source/blender/makesrna/intern/rna_texture.c
@@ -233,6 +233,7 @@ void rna_TextureSlot_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRN
break;
case ID_LA:
WM_main_add_notifier(NC_LAMP | ND_LIGHTING, id);
+ WM_main_add_notifier(NC_LAMP | ND_LIGHTING_DRAW, id);
break;
case ID_BR:
WM_main_add_notifier(NC_BRUSH, id);
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index 3e9f5b44a3d..7be34c398ae 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -3019,11 +3019,11 @@ static void rna_def_userdef_system(BlenderRNA *brna)
};
static EnumPropertyItem multi_sample_levels[] = {
- {USER_MULTISAMPLE_NONE, "MULTISAMPLE_NONE", 0, "No MultiSample", "Do not use OpenGL MultiSample"},
- {USER_MULTISAMPLE_2, "MULTISAMPLE_2", 0, "MultiSample: 2", "Use 2x OpenGL MultiSample (requires restart)"},
- {USER_MULTISAMPLE_4, "MULTISAMPLE_4", 0, "MultiSample: 4", "Use 4x OpenGL MultiSample (requires restart)"},
- {USER_MULTISAMPLE_8, "MULTISAMPLE_8", 0, "MultiSample: 8", "Use 8x OpenGL MultiSample (requires restart)"},
- {USER_MULTISAMPLE_16, "MULTISAMPLE_16", 0, "MultiSample: 16", "Use 16x OpenGL MultiSample (requires restart)"},
+ {USER_MULTISAMPLE_NONE, "NONE", 0, "No MultiSample", "Do not use OpenGL MultiSample"},
+ {USER_MULTISAMPLE_2, "2", 0, "MultiSample: 2", "Use 2x OpenGL MultiSample (requires restart)"},
+ {USER_MULTISAMPLE_4, "4", 0, "MultiSample: 4", "Use 4x OpenGL MultiSample (requires restart)"},
+ {USER_MULTISAMPLE_8, "8", 0, "MultiSample: 8", "Use 8x OpenGL MultiSample (requires restart)"},
+ {USER_MULTISAMPLE_16, "16", 0, "MultiSample: 16", "Use 16x OpenGL MultiSample (requires restart)"},
{0, NULL, 0, NULL, NULL}
};
@@ -3236,10 +3236,12 @@ static void rna_def_userdef_system(BlenderRNA *brna)
/* this isn't essential but nice to check if VBO draws any differently */
RNA_def_property_update(prop, NC_WINDOW, NULL);
+#if 0
prop = RNA_def_property(srna, "use_antialiasing", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "gameflags", USER_DISABLE_AA);
RNA_def_property_ui_text(prop, "Anti-aliasing",
"Use anti-aliasing for the 3D view (may impact redraw performance)");
+#endif
prop = RNA_def_property(srna, "anisotropic_filter", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "anisotropic_filter");
@@ -3322,7 +3324,7 @@ static void rna_def_userdef_system(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_userdef_text_update");
/* Full scene anti-aliasing */
- prop = RNA_def_property(srna, "ogl_multisamples", PROP_ENUM, PROP_NONE);
+ prop = RNA_def_property(srna, "multi_sample", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "ogl_multisamples");
RNA_def_property_enum_items(prop, multi_sample_levels);
RNA_def_property_ui_text(prop, "MultiSample", "Enable OpenGL multi-sampling, only for systems that support it, requires restart");
diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c
index e5f44644f7a..f83410e7cc1 100644
--- a/source/blender/makesrna/intern/rna_wm.c
+++ b/source/blender/makesrna/intern/rna_wm.c
@@ -555,7 +555,7 @@ static void rna_Window_screen_set(PointerRNA *ptr, PointerRNA value)
if (value.data == NULL)
return;
- /* exception: can't set screens inside of area/region handers */
+ /* exception: can't set screens inside of area/region handlers */
win->newscreen = value.data;
}
@@ -563,8 +563,8 @@ static void rna_Window_screen_update(bContext *C, PointerRNA *ptr)
{
wmWindow *win = (wmWindow *)ptr->data;
- /* exception: can't set screens inside of area/region handers, and must
- * use context so notifier gets to the right window */
+ /* exception: can't set screens inside of area/region handlers,
+ * and must use context so notifier gets to the right window */
if (win->newscreen) {
WM_event_add_notifier(C, NC_SCREEN | ND_SCREENBROWSE, win->newscreen);
win->newscreen = NULL;
diff --git a/source/blender/modifiers/CMakeLists.txt b/source/blender/modifiers/CMakeLists.txt
index 3a7066ff41a..cf3bb05849a 100644
--- a/source/blender/modifiers/CMakeLists.txt
+++ b/source/blender/modifiers/CMakeLists.txt
@@ -94,6 +94,7 @@ set(SRC
intern/MOD_weightvgedit.c
intern/MOD_weightvgmix.c
intern/MOD_weightvgproximity.c
+ intern/MOD_triangulate.c
MOD_modifiertypes.h
intern/MOD_boolean_util.h
diff --git a/source/blender/modifiers/MOD_modifiertypes.h b/source/blender/modifiers/MOD_modifiertypes.h
index a4817ff775d..290ba193567 100644
--- a/source/blender/modifiers/MOD_modifiertypes.h
+++ b/source/blender/modifiers/MOD_modifiertypes.h
@@ -76,6 +76,7 @@ extern ModifierTypeInfo modifierType_DynamicPaint;
extern ModifierTypeInfo modifierType_Remesh;
extern ModifierTypeInfo modifierType_Skin;
extern ModifierTypeInfo modifierType_LaplacianSmooth;
+extern ModifierTypeInfo modifierType_Triangulate;
/* MOD_util.c */
void modifier_type_init(ModifierTypeInfo *types[]);
diff --git a/source/blender/modifiers/intern/MOD_armature.c b/source/blender/modifiers/intern/MOD_armature.c
index 7219038b087..7ab3a5df531 100644
--- a/source/blender/modifiers/intern/MOD_armature.c
+++ b/source/blender/modifiers/intern/MOD_armature.c
@@ -58,7 +58,7 @@ static void initData(ModifierData *md)
{
ArmatureModifierData *amd = (ArmatureModifierData *) md;
- amd->deformflag = ARM_DEF_ENVELOPE | ARM_DEF_VGROUP;
+ amd->deformflag = ARM_DEF_VGROUP;
}
static void copyData(ModifierData *md, ModifierData *target)
diff --git a/source/blender/modifiers/intern/MOD_array.c b/source/blender/modifiers/intern/MOD_array.c
index b9dd37ac50c..d4463098f07 100644
--- a/source/blender/modifiers/intern/MOD_array.c
+++ b/source/blender/modifiers/intern/MOD_array.c
@@ -178,14 +178,14 @@ static int *find_doubles_index_map(BMesh *bm, BMOperator *dupe_op,
amd->merge_dist, dupe_op, "geom");
BMO_op_exec(bm, &find_op);
-
+
i = 0;
- BMO_ITER (ele, &oiter, bm, dupe_op, "geom", BM_ALL) {
+ BMO_ITER (ele, &oiter, dupe_op->slots_in, "geom", BM_ALL) {
BM_elem_index_set(ele, i); /* set_dirty */
i++;
}
- BMO_ITER (ele, &oiter, bm, dupe_op, "newout", BM_ALL) {
+ BMO_ITER (ele, &oiter, dupe_op->slots_out, "geom.out", BM_ALL) {
BM_elem_index_set(ele, i); /* set_dirty */
i++;
}
@@ -197,7 +197,7 @@ static int *find_doubles_index_map(BMesh *bm, BMOperator *dupe_op,
index_map = MEM_callocN(sizeof(int) * (*index_map_length), "index_map");
/*element type argument doesn't do anything here*/
- BMO_ITER (v, &oiter, bm, &find_op, "targetmapout", 0) {
+ BMO_ITER (v, &oiter, find_op.slots_out, "targetmap.out", 0) {
v2 = BMO_iter_map_value_p(&oiter);
index_map[BM_elem_index_get(v)] = BM_elem_index_get(v2) + 1;
@@ -218,9 +218,10 @@ static int *find_doubles_index_map(BMesh *bm, BMOperator *dupe_op,
static void bm_merge_dm_transform(BMesh *bm, DerivedMesh *dm, float mat[4][4],
const ArrayModifierData *amd,
BMOperator *dupe_op,
- const char *dupe_slot_name,
+ BMOpSlot dupe_op_slot_args[BMO_OP_MAX_SLOTS], const char *dupe_slot_name,
BMOperator *weld_op)
{
+ const int is_input = (dupe_op->slots_in == dupe_op_slot_args);
BMVert *v, *v2, *v3;
BMIter iter;
@@ -234,14 +235,27 @@ static void bm_merge_dm_transform(BMesh *bm, DerivedMesh *dm, float mat[4][4],
BMOIter oiter;
BMOperator find_op;
+ BMOpSlot *slot_targetmap;
BMO_op_initf(bm, &find_op, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE),
- "find_doubles verts=%Hv dist=%f keep_verts=%s",
+ is_input ? /* ugh */
+ "find_doubles verts=%Hv dist=%f keep_verts=%s" :
+ "find_doubles verts=%Hv dist=%f keep_verts=%S",
BM_ELEM_TAG, amd->merge_dist,
dupe_op, dupe_slot_name);
/* append the dupe's geom to the findop input verts */
- BMO_slot_buffer_append(&find_op, "verts", dupe_op, dupe_slot_name);
+ if (is_input) {
+ BMO_slot_buffer_append(&find_op, slots_in, "verts",
+ dupe_op, slots_in, dupe_slot_name);
+ }
+ else if (dupe_op->slots_out == dupe_op_slot_args) {
+ BMO_slot_buffer_append(&find_op, slots_in, "verts",
+ dupe_op, slots_out, dupe_slot_name);
+ }
+ else {
+ BLI_assert(0);
+ }
/* transform and tag verts */
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
@@ -253,15 +267,17 @@ static void bm_merge_dm_transform(BMesh *bm, DerivedMesh *dm, float mat[4][4],
BMO_op_exec(bm, &find_op);
+ slot_targetmap = BMO_slot_get(weld_op->slots_in, "targetmap");
+
/* add new merge targets to weld operator */
- BMO_ITER (v, &oiter, bm, &find_op, "targetmapout", 0) {
+ BMO_ITER (v, &oiter, find_op.slots_out, "targetmap.out", 0) {
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(bm, weld_op, "targetmap", v2))) {
+ while ((v3 = BMO_slot_map_ptr_get(slot_targetmap, v2))) {
v2 = v3;
}
- BMO_slot_map_ptr_insert(bm, weld_op, "targetmap", v, v2);
+ BMO_slot_map_ptr_insert(weld_op, slot_targetmap, v, v2);
}
BMO_op_finish(bm, &find_op);
@@ -286,6 +302,7 @@ static void merge_first_last(BMesh *bm,
BMOperator find_op;
BMOIter oiter;
BMVert *v, *v2;
+ BMOpSlot *slot_targetmap;
BMO_op_initf(bm, &find_op, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE),
"find_doubles verts=%s dist=%f keep_verts=%s",
@@ -293,14 +310,16 @@ static void merge_first_last(BMesh *bm,
dupe_first, "geom");
/* append the last dupe's geom to the findop input verts */
- BMO_slot_buffer_append(&find_op, "verts", dupe_last, "newout");
+ BMO_slot_buffer_append(&find_op, slots_in, "verts",
+ dupe_last, slots_out, "geom.out");
BMO_op_exec(bm, &find_op);
/* add new merge targets to weld operator */
- BMO_ITER (v, &oiter, bm, &find_op, "targetmapout", 0) {
+ 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(bm, weld_op, "targetmap", v, v2);
+ BMO_slot_map_ptr_insert(weld_op, slot_targetmap, v, v2);
}
BMO_op_finish(bm, &find_op);
@@ -325,6 +344,7 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
int *indexMap = NULL;
DerivedMesh *start_cap = NULL, *end_cap = NULL;
MVert *src_mvert;
+ BMOpSlot *slot_targetmap = NULL; /* for weldop */
/* need to avoid infinite recursion here */
if (amd->start_cap && amd->start_cap != ob)
@@ -408,13 +428,17 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
* cleaner way to do this. One possibility: a "mirror" BMOp would
* certainly help by compressing it all into one top-level BMOp that
* executes a lot of second-level BMOps. */
+ BM_mesh_elem_toolflags_ensure(bm);
BMO_push(bm, NULL);
bmesh_edit_begin(bm, 0);
- if (amd->flags & MOD_ARR_MERGE)
+ if (amd->flags & MOD_ARR_MERGE) {
BMO_op_init(bm, &weld_op, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE),
"weld_verts");
+ slot_targetmap = BMO_slot_get(weld_op.slots_in, "targetmap");
+ }
+
BMO_op_initf(bm, &dupe_op, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE),
"duplicate geom=%avef");
first_dupe_op = dupe_op;
@@ -422,18 +446,18 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
for (j = 0; j < count - 1; j++) {
BMVert *v, *v2, *v3;
BMOpSlot *geom_slot;
- BMOpSlot *newout_slot;
+ BMOpSlot *geom_out_slot;
BMOIter oiter;
if (j != 0) {
BMO_op_initf(bm, &dupe_op,
(BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE),
- "duplicate geom=%s", &old_dupe_op, "newout");
+ "duplicate geom=%S", &old_dupe_op, "geom.out");
}
BMO_op_exec(bm, &dupe_op);
- geom_slot = BMO_slot_get(&dupe_op, "geom");
- newout_slot = BMO_slot_get(&dupe_op, "newout");
+ geom_slot = BMO_slot_get(dupe_op.slots_in, "geom");
+ geom_out_slot = BMO_slot_get(dupe_op.slots_out, "geom.out");
if ((amd->flags & MOD_ARR_MERGEFINAL) && j == 0) {
int first_geom_bytes = sizeof(BMVert *) * geom_slot->len;
@@ -445,7 +469,7 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
}
/* apply transformation matrix */
- BMO_ITER (v, &oiter, bm, &dupe_op, "newout", BM_VERT) {
+ BMO_ITER (v, &oiter, dupe_op.slots_out, "geom.out", BM_VERT) {
mul_m4_v3(offset, v->co);
}
@@ -464,17 +488,17 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
for (i = 0; i < index_len; i++) {
if (!indexMap[i]) continue;
- /* merge v (from 'newout') into v2 (from old 'geom') */
- v = _E(newout_slot, i - geom_slot->len);
+ /* merge v (from 'geom.out') into v2 (from old 'geom') */
+ v = _E(geom_out_slot, i - geom_slot->len);
v2 = _E(geom_slot, indexMap[i] - 1);
/* check in case the target vertex (v2) is already marked
* for merging */
- while ((v3 = BMO_slot_map_ptr_get(bm, &weld_op, "targetmap", v2))) {
+ while ((v3 = BMO_slot_map_ptr_get(slot_targetmap, v2))) {
v2 = v3;
}
- BMO_slot_map_ptr_insert(bm, &weld_op, "targetmap", v, v2);
+ BMO_slot_map_ptr_insert(&weld_op, slot_targetmap, v, v2);
}
#undef _E
@@ -510,14 +534,15 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
float startoffset[4][4];
invert_m4_m4(startoffset, offset);
bm_merge_dm_transform(bm, start_cap, startoffset, amd,
- &first_dupe_op, "geom", &weld_op);
+ &first_dupe_op, first_dupe_op.slots_in, "geom", &weld_op);
}
if (end_cap) {
float endoffset[4][4];
mult_m4_m4m4(endoffset, offset, final_offset);
bm_merge_dm_transform(bm, end_cap, endoffset, amd,
- &dupe_op, count == 1 ? "geom" : "newout", &weld_op);
+ &dupe_op, (count == 1) ? dupe_op.slots_in : dupe_op.slots_out,
+ (count == 1) ? "geom" : "geom.out", &weld_op);
}
}
/* done capping */
diff --git a/source/blender/modifiers/intern/MOD_bevel.c b/source/blender/modifiers/intern/MOD_bevel.c
index 3e3bcb73491..59befe4db05 100644
--- a/source/blender/modifiers/intern/MOD_bevel.c
+++ b/source/blender/modifiers/intern/MOD_bevel.c
@@ -92,20 +92,15 @@ static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
#ifdef USE_BM_BEVEL_OP_AS_MOD
-#define EDGE_MARK 1
-
/* BMESH_TODO
*
- * this bevel calls the operator which is missing many of the options
- * which the bevel modifier in trunk has.
+ * this bevel calls the new bevel code (added since 2.64)
+ * which is missing many of the options which the bevel modifier from 2.4x has.
* - no vertex bevel
* - no weight bevel
*
* These will need to be added to the bmesh operator.
- * - campbell
- *
- * note: this code is very close to MOD_edgesplit.c.
- * note: if 0'd code from trunk included below.
+ * - campbell
*/
static DerivedMesh *applyModifier(ModifierData *md, struct Object *UNUSED(ob),
DerivedMesh *dm,
@@ -116,22 +111,20 @@ static DerivedMesh *applyModifier(ModifierData *md, struct Object *UNUSED(ob),
BMIter iter;
BMEdge *e;
BevelModifierData *bmd = (BevelModifierData *) md;
- float threshold = cos((bmd->bevel_angle + 0.00001f) * M_PI / 180.0f);
+ const float threshold = cosf((bmd->bevel_angle + 0.00001f) * (float)M_PI / 180.0f);
+ const int segments = 16; /* XXX */
bm = DM_to_bmesh(dm);
- BM_mesh_normals_update(bm, FALSE);
- BMO_push(bm, NULL);
-
if (bmd->lim_flags & BME_BEVEL_ANGLE) {
BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
/* check for 1 edge having 2 face users */
- BMLoop *l1, *l2;
- if ((l1 = e->l) &&
- (l2 = e->l->radial_next) != l1)
- {
- if (dot_v3v3(l1->f->no, l2->f->no) < threshold) {
- BMO_elem_flag_enable(bm, e, EDGE_MARK);
+ BMLoop *l_a, *l_b;
+ if (BM_edge_loop_pair(e, &l_a, &l_b)) {
+ if (dot_v3v3(l_a->f->no, l_b->f->no) < threshold) {
+ BM_elem_flag_enable(e, BM_ELEM_TAG);
+ BM_elem_flag_enable(e->v1, BM_ELEM_TAG);
+ BM_elem_flag_enable(e->v2, BM_ELEM_TAG);
}
}
}
@@ -139,18 +132,23 @@ static DerivedMesh *applyModifier(ModifierData *md, struct Object *UNUSED(ob),
else {
/* crummy, is there a way just to operator on all? - campbell */
BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
- BMO_elem_flag_enable(bm, e, EDGE_MARK);
+ if (BM_edge_is_manifold(e)) {
+ BM_elem_flag_enable(e, BM_ELEM_TAG);
+ BM_elem_flag_enable(e->v1, BM_ELEM_TAG);
+ BM_elem_flag_enable(e->v2, BM_ELEM_TAG);
+ }
}
}
- BMO_op_callf(bm, BMO_FLAG_DEFAULTS,
- "bevel geom=%fe percent=%f use_even=%b use_dist=%b",
- EDGE_MARK, bmd->value, (bmd->flags & BME_BEVEL_EVEN) != 0, (bmd->flags & BME_BEVEL_DIST) != 0);
- BMO_pop(bm);
+ BM_mesh_bevel(bm, bmd->value, segments);
result = CDDM_from_bmesh(bm, TRUE);
+
+ BLI_assert(bm->toolflagpool == NULL); /* make sure we never alloc'd this */
BM_mesh_free(bm);
+ CDDM_calc_normals(result);
+
return result;
}
diff --git a/source/blender/modifiers/intern/MOD_decimate.c b/source/blender/modifiers/intern/MOD_decimate.c
index dc29e59d549..3f8eaa438c9 100644
--- a/source/blender/modifiers/intern/MOD_decimate.c
+++ b/source/blender/modifiers/intern/MOD_decimate.c
@@ -186,6 +186,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
/* update for display only */
dmd->face_count = bm->totface;
result = CDDM_from_bmesh(bm, FALSE);
+ BLI_assert(bm->toolflagpool == NULL); /* make sure we never alloc'd this */
BM_mesh_free(bm);
#ifdef USE_TIMEIT
diff --git a/source/blender/modifiers/intern/MOD_edgesplit.c b/source/blender/modifiers/intern/MOD_edgesplit.c
index 21717d07fef..ec81c5ce699 100644
--- a/source/blender/modifiers/intern/MOD_edgesplit.c
+++ b/source/blender/modifiers/intern/MOD_edgesplit.c
@@ -67,8 +67,7 @@ static DerivedMesh *doEdgeSplit(DerivedMesh *dm, EdgeSplitModifierData *emd, Obj
float threshold = cosf((emd->split_angle + 0.00001f) * (float)M_PI / 180.0f);
bm = DM_to_bmesh(dm);
-
- BMO_push(bm, NULL);
+ BM_mesh_elem_toolflags_ensure(bm);
if (emd->flags & MOD_EDGESPLIT_FROMANGLE) {
BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
@@ -103,8 +102,6 @@ static DerivedMesh *doEdgeSplit(DerivedMesh *dm, EdgeSplitModifierData *emd, Obj
BMO_op_callf(bm, BMO_FLAG_DEFAULTS,
"split_edges edges=%fe", EDGE_MARK);
-
- BMO_pop(bm);
/* BM_mesh_validate(bm); */ /* for troubleshooting */
diff --git a/source/blender/modifiers/intern/MOD_fluidsim_util.c b/source/blender/modifiers/intern/MOD_fluidsim_util.c
index 47523286229..13d409dc941 100644
--- a/source/blender/modifiers/intern/MOD_fluidsim_util.c
+++ b/source/blender/modifiers/intern/MOD_fluidsim_util.c
@@ -426,7 +426,11 @@ static DerivedMesh *fluidsim_read_cache(Object *ob, DerivedMesh *orgdm,
FluidsimModifierData *fluidmd, int framenr, int useRenderParams)
{
int displaymode = 0;
- int curFrame = framenr - 1 /*scene->r.sfra*/; /* start with 0 at start frame */
+
+ int curFrame = framenr /* - 1 */ /*scene->r.sfra*/; /* start with 0 at start frame */
+ /* why start with 0 as start frame?? Animations + time are frozen for frame 0 anyway. (See physics_fluid.c for that. - DG */
+ /* If we start with frame 0, we need to remap all animation channels, too, because they will all be 1 frame late if using frame-1! - DG */
+
char targetFile[FILE_MAX];
FluidsimSettings *fss = fluidmd->fss;
DerivedMesh *dm = NULL;
diff --git a/source/blender/modifiers/intern/MOD_laplaciansmooth.c b/source/blender/modifiers/intern/MOD_laplaciansmooth.c
index 6f6589d4d14..266226040a3 100644
--- a/source/blender/modifiers/intern/MOD_laplaciansmooth.c
+++ b/source/blender/modifiers/intern/MOD_laplaciansmooth.c
@@ -199,7 +199,7 @@ static void init_data(ModifierData *md)
smd->lambda = 0.00001f;
smd->lambda_border = 0.00005f;
smd->repeat = 1;
- smd->flag = MOD_LAPLACIANSMOOTH_X | MOD_LAPLACIANSMOOTH_Y | MOD_LAPLACIANSMOOTH_Z | MOD_LAPLACIANSMOOTH_VOLUME_PRESERVATION;
+ smd->flag = MOD_LAPLACIANSMOOTH_X | MOD_LAPLACIANSMOOTH_Y | MOD_LAPLACIANSMOOTH_Z | MOD_LAPLACIANSMOOTH_PRESERVE_VOLUME;
smd->defgrp_name[0] = '\0';
}
@@ -511,7 +511,7 @@ static void validate_solution(LaplacianSystem *sys, short flag)
float leni, lene;
float vini, vend;
float *vi1, *vi2, ve1[3], ve2[3];
- if (flag & MOD_LAPLACIANSMOOTH_VOLUME_PRESERVATION) {
+ if (flag & MOD_LAPLACIANSMOOTH_PRESERVE_VOLUME) {
vini = compute_volume(sys->vertexCos, sys->mfaces, sys->numFaces);
}
for (i = 0; i < sys->numEdges; i++) {
@@ -545,7 +545,7 @@ static void validate_solution(LaplacianSystem *sys, short flag)
}
}
}
- if (flag & MOD_LAPLACIANSMOOTH_VOLUME_PRESERVATION) {
+ if (flag & MOD_LAPLACIANSMOOTH_PRESERVE_VOLUME) {
vend = compute_volume(sys->vertexCos, sys->mfaces, sys->numFaces);
volume_preservation(sys, vini, vend, flag);
}
diff --git a/source/blender/modifiers/intern/MOD_skin.c b/source/blender/modifiers/intern/MOD_skin.c
index 38ec0e8bb4c..9f702957fa5 100644
--- a/source/blender/modifiers/intern/MOD_skin.c
+++ b/source/blender/modifiers/intern/MOD_skin.c
@@ -249,14 +249,14 @@ static int build_hull(SkinOutput *so, Frame **frames, int totframe)
}
/* Apply face attributes to hull output */
- BMO_ITER (f, &oiter, bm, &op, "geomout", BM_FACE) {
+ BMO_ITER (f, &oiter, op.slots_out, "geom.out", BM_FACE) {
if (so->smd->flag & MOD_SKIN_SMOOTH_SHADING)
BM_elem_flag_enable(f, BM_ELEM_SMOOTH);
f->mat_nr = so->mat_nr;
}
/* Mark interior frames */
- BMO_ITER (v, &oiter, bm, &op, "interior_geom", BM_VERT) {
+ BMO_ITER (v, &oiter, op.slots_out, "geom_interior.out", BM_VERT) {
for (i = 0; i < totframe; i++) {
Frame *frame = frames[i];
@@ -309,7 +309,7 @@ static int build_hull(SkinOutput *so, Frame **frames, int totframe)
/* Check if removing triangles above will create wire triangles,
* mark them too */
- BMO_ITER (e, &oiter, bm, &op, "geomout", BM_EDGE) {
+ BMO_ITER (e, &oiter, op.slots_out, "geom.out", BM_EDGE) {
int is_wire = TRUE;
BM_ITER_ELEM (f, &iter, e, BM_FACES_OF_EDGE) {
if (!BM_elem_flag_test(f, BM_ELEM_TAG)) {
@@ -537,6 +537,7 @@ static int connection_node_mat(float mat[3][3], int v, const MeshElemMap *emap,
/* Get axis and angle to rotate frame by */
angle = angle_normalized_v3v3(ine[0], oute[0]) / 2.0f;
cross_v3_v3v3(axis, ine[0], oute[0]);
+ normalize_v3(axis);
/* Build frame matrix (don't care about X axis here) */
copy_v3_v3(mat[0], ine[0]);
@@ -1079,17 +1080,20 @@ static BMFace *collapse_face_corners(BMesh *bm, BMFace *f, int n,
BMOperator op;
BMIter iter;
int i;
+ BMOpSlot *slot_targetmap;
shortest_edge = BM_face_find_shortest_loop(f)->e;
BMO_op_initf(bm, &op, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE), "weld_verts");
+ slot_targetmap = BMO_slot_get(op.slots_in, "targetmap");
+
/* Note: could probably calculate merges in one go to be
* faster */
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(bm, &op, "targetmap", v_merge, v_safe);
+ BMO_slot_map_ptr_insert(&op, slot_targetmap, v_merge, v_safe);
BMO_op_exec(bm, &op);
BMO_op_finish(bm, &op);
@@ -1215,6 +1219,7 @@ static void skin_fix_hole_no_good_verts(BMesh *bm, Frame *frame, BMFace *split_f
BMOIter oiter;
BMOperator op;
int i, best_order[4];
+ BMOpSlot *slot_targetmap;
BLI_assert(split_face->len >= 3);
@@ -1228,7 +1233,7 @@ static void skin_fix_hole_no_good_verts(BMesh *bm, Frame *frame, BMFace *split_f
/* Update split face (should only be one new face created
* during extrusion) */
split_face = NULL;
- BMO_ITER (f, &oiter, bm, &op, "faceout", BM_FACE) {
+ BMO_ITER (f, &oiter, op.slots_out, "faces.out", BM_FACE) {
BLI_assert(!split_face);
split_face = f;
}
@@ -1246,7 +1251,7 @@ static void skin_fix_hole_no_good_verts(BMesh *bm, Frame *frame, BMFace *split_f
BM_elem_flag_enable(longest_edge, BM_ELEM_TAG);
BMO_op_callf(bm, BMO_FLAG_DEFAULTS,
- "subdivide_edges edges=%he numcuts=%i quadcornertype=%i",
+ "subdivide_edges edges=%he cuts=%i quad_corner_type=%i",
BM_ELEM_TAG, 1, SUBD_STRAIGHT_CUT);
}
else if (split_face->len > 4) {
@@ -1280,8 +1285,9 @@ static void skin_fix_hole_no_good_verts(BMesh *bm, Frame *frame, BMFace *split_f
BM_face_kill(bm, split_face);
BMO_op_init(bm, &op, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE),
"weld_verts");
+ slot_targetmap = BMO_slot_get(op.slots_in, "targetmap");
for (i = 0; i < 4; i++) {
- BMO_slot_map_ptr_insert(bm, &op, "targetmap",
+ BMO_slot_map_ptr_insert(&op, slot_targetmap,
verts[i], frame->verts[best_order[i]]);
}
BMO_op_exec(bm, &op);
diff --git a/source/blender/modifiers/intern/MOD_triangulate.c b/source/blender/modifiers/intern/MOD_triangulate.c
new file mode 100644
index 00000000000..645fd5eb2cf
--- /dev/null
+++ b/source/blender/modifiers/intern/MOD_triangulate.c
@@ -0,0 +1,144 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Antony Riakiotakis
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ */
+
+/** \file blender/modifiers/intern/MOD_triangulate.c
+ * \ingroup modifiers
+ */
+
+#include "DNA_object_types.h"
+
+#include "BLI_utildefines.h"
+
+#include "BKE_cdderivedmesh.h"
+#include "BKE_modifier.h"
+#include "BKE_tessmesh.h"
+
+/* triangulation modifier, directly calls the bmesh operator */
+
+static DerivedMesh *triangulate_dm(DerivedMesh *dm, const int flag)
+{
+ DerivedMesh *result;
+ BMesh *bm;
+ int total_edges, i;
+ MEdge *me;
+
+ bm = DM_to_bmesh(dm);
+
+ BM_mesh_elem_toolflags_ensure(bm);
+ BMO_push(bm, NULL);
+
+ BMO_op_callf(bm, BMO_FLAG_DEFAULTS,
+ "triangulate faces=%af use_beauty=%b",
+ (flag & MOD_TRIANGULATE_BEAUTY));
+ BMO_pop(bm);
+
+ result = CDDM_from_bmesh(bm, FALSE);
+ BM_mesh_free(bm);
+
+ total_edges = result->getNumEdges(result);
+ me = CDDM_get_edges(result);
+
+ /* force drawing of all edges (seems to be omitted in CDDM_from_bmesh) */
+ for (i = 0; i < total_edges; i++, me++)
+ me->flag |= ME_EDGEDRAW | ME_EDGERENDER;
+
+ CDDM_calc_normals(result);
+
+ return result;
+}
+
+
+static void initData(ModifierData *md)
+{
+ TriangulateModifierData *tmd = (TriangulateModifierData *)md;
+
+ /* Enable in editmode by default */
+ md->mode |= eModifierMode_Editmode;
+ tmd->flag = MOD_TRIANGULATE_BEAUTY;
+}
+
+
+static void copyData(ModifierData *md, ModifierData *target)
+{
+ TriangulateModifierData *smd = (TriangulateModifierData *) md;
+ TriangulateModifierData *tsmd = (TriangulateModifierData *) target;
+
+ *tsmd = *smd;
+}
+
+static DerivedMesh *applyModifierEM(ModifierData *md,
+ Object *UNUSED(ob),
+ struct BMEditMesh *UNUSED(em),
+ DerivedMesh *dm)
+{
+ TriangulateModifierData *tmd = (TriangulateModifierData *)md;
+ DerivedMesh *result;
+ if (!(result = triangulate_dm(dm, tmd->flag))) {
+ return dm;
+ }
+
+ return result;
+}
+
+static DerivedMesh *applyModifier(ModifierData *md,
+ Object *UNUSED(ob),
+ DerivedMesh *dm,
+ ModifierApplyFlag UNUSED(flag))
+{
+ TriangulateModifierData *tmd = (TriangulateModifierData *)md;
+ DerivedMesh *result;
+ if (!(result = triangulate_dm(dm, tmd->flag))) {
+ return dm;
+ }
+
+ return result;
+}
+
+ModifierTypeInfo modifierType_Triangulate = {
+ /* name */ "Triangulate",
+ /* structName */ "TriangulateModifierData",
+ /* structSize */ sizeof(TriangulateModifierData),
+ /* type */ eModifierTypeType_Constructive,
+ /* flags */ eModifierTypeFlag_AcceptsMesh |
+ eModifierTypeFlag_SupportsEditmode |
+ eModifierTypeFlag_SupportsMapping |
+ eModifierTypeFlag_EnableInEditmode |
+ eModifierTypeFlag_AcceptsCVs,
+
+ /* copyData */ copyData,
+ /* deformVerts */ NULL,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ NULL,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ applyModifier,
+ /* applyModifierEM */ applyModifierEM,
+ /* initData */ initData,
+ /* requiredDataMask */ NULL, //requiredDataMask,
+ /* freeData */ NULL,
+ /* isDisabled */ NULL,
+ /* updateDepgraph */ NULL,
+ /* dependsOnTime */ NULL,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ NULL,
+ /* foreachIDLink */ NULL,
+};
diff --git a/source/blender/modifiers/intern/MOD_util.c b/source/blender/modifiers/intern/MOD_util.c
index 3b769a30994..a27d5e5e03b 100644
--- a/source/blender/modifiers/intern/MOD_util.c
+++ b/source/blender/modifiers/intern/MOD_util.c
@@ -278,5 +278,6 @@ void modifier_type_init(ModifierTypeInfo *types[])
INIT_TYPE(Remesh);
INIT_TYPE(Skin);
INIT_TYPE(LaplacianSmooth);
+ INIT_TYPE(Triangulate);
#undef INIT_TYPE
}
diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt
index 7dca4d07b24..141a3680df2 100644
--- a/source/blender/nodes/CMakeLists.txt
+++ b/source/blender/nodes/CMakeLists.txt
@@ -84,6 +84,7 @@ set(SRC
composite/nodes/node_composite_lummaMatte.c
composite/nodes/node_composite_mapUV.c
composite/nodes/node_composite_mapValue.c
+ composite/nodes/node_composite_mapRange.c
composite/nodes/node_composite_math.c
composite/nodes/node_composite_mask.c
composite/nodes/node_composite_mixrgb.c
@@ -122,7 +123,6 @@ set(SRC
composite/nodes/node_composite_pixelate.c
composite/node_composite_tree.c
- composite/node_composite_util.c
shader/nodes/node_shader_camera.c
shader/nodes/node_shader_common.c
@@ -222,7 +222,6 @@ set(SRC
intern/node_common.c
intern/node_socket.c
- composite/node_composite_util.h
shader/node_shader_util.h
texture/node_texture_util.h
@@ -235,6 +234,13 @@ set(SRC
intern/node_common.h
)
+if(WITH_COMPOSITOR_LEGACY)
+ list(APPEND SRC
+ composite/node_composite_util.h
+ composite/node_composite_util.c
+ )
+endif()
+
if(WITH_PYTHON)
list(APPEND INC
../python
diff --git a/source/blender/nodes/NOD_composite.h b/source/blender/nodes/NOD_composite.h
index ee67ac88085..eecc1e46827 100644
--- a/source/blender/nodes/NOD_composite.h
+++ b/source/blender/nodes/NOD_composite.h
@@ -72,6 +72,7 @@ void register_node_type_cmp_huecorrect(struct bNodeTreeType *ttype);
void register_node_type_cmp_normal(struct bNodeTreeType *ttype);
void register_node_type_cmp_curve_vec(struct bNodeTreeType *ttype);
void register_node_type_cmp_map_value(struct bNodeTreeType *ttype);
+void register_node_type_cmp_map_range(struct bNodeTreeType *ttype);
void register_node_type_cmp_normalize(struct bNodeTreeType *ttype);
void register_node_type_cmp_filter(struct bNodeTreeType *ttype);
diff --git a/source/blender/nodes/composite/nodes/node_composite_colorbalance.c b/source/blender/nodes/composite/nodes/node_composite_colorbalance.c
index e9d26ebebbc..df49e537788 100644
--- a/source/blender/nodes/composite/nodes/node_composite_colorbalance.c
+++ b/source/blender/nodes/composite/nodes/node_composite_colorbalance.c
@@ -49,14 +49,14 @@ static bNodeSocketTemplate cmp_node_colorbalance_out[] = {
#ifdef WITH_COMPOSITOR_LEGACY
/* this function implements ASC-CDL according to the spec at http://www.asctech.org/
- Slope
- S = in * slope
- Offset
- O = S + offset
- = (in * slope) + offset
- Power
- out = Clamp(O) ^ power
- = Clamp((in * slope) + offset) ^ power
+ * Slope
+ * S = in * slope
+ * Offset
+ * O = S + offset
+ * = (in * slope) + offset
+ * Power
+ * out = Clamp(O) ^ power
+ * = Clamp((in * slope) + offset) ^ power
*/
DO_INLINE float colorbalance_cdl(float in, float offset, float power, float slope)
{
diff --git a/source/blender/nodes/composite/nodes/node_composite_image.c b/source/blender/nodes/composite/nodes/node_composite_image.c
index 150382c1f8f..88d78df190f 100644
--- a/source/blender/nodes/composite/nodes/node_composite_image.c
+++ b/source/blender/nodes/composite/nodes/node_composite_image.c
@@ -173,9 +173,10 @@ static void cmp_node_image_create_outputs(bNodeTree *ntree, bNode *node)
Image *ima= (Image *)node->id;
if (ima) {
ImageUser *iuser= node->storage;
+ ImBuf *ibuf;
/* make sure ima->type is correct */
- BKE_image_get_ibuf(ima, iuser);
+ ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL);
if (ima->rr) {
RenderLayer *rl= BLI_findlink(&ima->rr->layers, iuser->layer);
@@ -191,6 +192,8 @@ static void cmp_node_image_create_outputs(bNodeTree *ntree, bNode *node)
}
else
cmp_node_image_add_render_pass_outputs(ntree, node, RRES_OUT_IMAGE|RRES_OUT_ALPHA|RRES_OUT_Z);
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
}
else
cmp_node_image_add_render_pass_outputs(ntree, node, RRES_OUT_IMAGE|RRES_OUT_ALPHA);
@@ -312,7 +315,7 @@ float *node_composit_get_float_buffer(RenderData *rd, ImBuf *ibuf, int *alloc)
}
/* note: this function is used for multilayer too, to ensure uniform
- * handling with BKE_image_get_ibuf() */
+ * handling with BKE_image_acquire_ibuf() */
static CompBuf *node_composit_get_image(RenderData *rd, Image *ima, ImageUser *iuser)
{
ImBuf *ibuf;
@@ -322,7 +325,7 @@ static CompBuf *node_composit_get_image(RenderData *rd, Image *ima, ImageUser *i
float *rect;
int alloc= FALSE;
- ibuf= BKE_image_get_ibuf(ima, iuser);
+ ibuf= BKE_image_acquire_ibuf(ima, iuser, NULL);
if (ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL)) {
return NULL;
}
@@ -374,12 +377,15 @@ static CompBuf *node_composit_get_image(RenderData *rd, Image *ima, ImageUser *i
}
}
#endif
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+
return stackbuf;
}
static CompBuf *node_composit_get_zimage(bNode *node, RenderData *rd)
{
- ImBuf *ibuf= BKE_image_get_ibuf((Image *)node->id, node->storage);
+ ImBuf *ibuf= BKE_image_acquire_ibuf((Image *)node->id, node->storage, NULL);
CompBuf *zbuf= NULL;
if (ibuf && ibuf->zbuf_float) {
@@ -391,6 +397,9 @@ static CompBuf *node_composit_get_zimage(bNode *node, RenderData *rd)
zbuf->rect= ibuf->zbuf_float;
}
}
+
+ BKE_image_release_ibuf((Image *)node->id, ibuf, NULL);
+
return zbuf;
}
@@ -418,13 +427,14 @@ static void node_composit_exec_image(void *data, bNode *node, bNodeStack **UNUSE
RenderData *rd= data;
Image *ima= (Image *)node->id;
ImageUser *iuser= (ImageUser *)node->storage;
+ ImBuf *ibuf = NULL;
/* first set the right frame number in iuser */
BKE_image_user_frame_calc(iuser, rd->cfra, 0);
/* force a load, we assume iuser index will be set OK anyway */
if (ima->type==IMA_TYPE_MULTILAYER)
- BKE_image_get_ibuf(ima, iuser);
+ ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL);
if (ima->type==IMA_TYPE_MULTILAYER && ima->rr) {
RenderLayer *rl= BLI_findlink(&ima->rr->layers, iuser->layer);
@@ -505,6 +515,8 @@ static void node_composit_exec_image(void *data, bNode *node, bNodeStack **UNUSE
generate_preview(data, node, stackbuf);
}
}
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
}
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_mapRange.c b/source/blender/nodes/composite/nodes/node_composite_mapRange.c
new file mode 100644
index 00000000000..f96e133b19f
--- /dev/null
+++ b/source/blender/nodes/composite/nodes/node_composite_mapRange.c
@@ -0,0 +1,58 @@
+/*
+ * ***** 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) 2006 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/nodes/composite/nodes/node_composite_mapRange.c
+ * \ingroup cmpnodes
+ */
+
+
+#include "node_composite_util.h"
+
+/* **************** MAP VALUE ******************** */
+static bNodeSocketTemplate cmp_node_map_range_in[] = {
+ { SOCK_FLOAT, 1, N_("Value"), 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, PROP_NONE},
+ { SOCK_FLOAT, 1, N_("From Min"), 0.0f, 1.0f, 1.0f, 1.0f, -10000.0f, 10000.0f, PROP_NONE},
+ { SOCK_FLOAT, 1, N_("From Max"), 1.0f, 1.0f, 1.0f, 1.0f, -10000.0f, 10000.0f, PROP_NONE},
+ { SOCK_FLOAT, 1, N_("To Min"), 0.0f, 1.0f, 1.0f, 1.0f, -10000.0f, 10000.0f, PROP_NONE},
+ { SOCK_FLOAT, 1, N_("To Max"), 1.0f, 1.0f, 1.0f, 1.0f, -10000.0f, 10000.0f, PROP_NONE},
+ { -1, 0, "" }
+};
+static bNodeSocketTemplate cmp_node_map_range_out[] = {
+ { SOCK_FLOAT, 0, N_("Value")},
+ { -1, 0, "" }
+};
+
+void register_node_type_cmp_map_range(bNodeTreeType *ttype)
+{
+ static bNodeType ntype;
+
+ node_type_base(ttype, &ntype, CMP_NODE_MAP_RANGE, "Map Range", NODE_CLASS_OP_VECTOR, NODE_OPTIONS);
+ node_type_socket_templates(&ntype, cmp_node_map_range_in, cmp_node_map_range_out);
+ node_type_size(&ntype, 120, 60, 150);
+
+ nodeRegisterType(ttype, &ntype);
+}
diff --git a/source/blender/nodes/composite/nodes/node_composite_normal.c b/source/blender/nodes/composite/nodes/node_composite_normal.c
index 93fd7ca1c1b..d104e8f03e6 100644
--- a/source/blender/nodes/composite/nodes/node_composite_normal.c
+++ b/source/blender/nodes/composite/nodes/node_composite_normal.c
@@ -40,7 +40,7 @@ static bNodeSocketTemplate cmp_node_normal_in[] = {
};
static bNodeSocketTemplate cmp_node_normal_out[] = {
- { SOCK_VECTOR, 0, N_("Normal")},
+ { SOCK_VECTOR, 0, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_DIRECTION},
{ SOCK_FLOAT, 0, N_("Dot")},
{ -1, 0, "" }
};
diff --git a/source/blender/nodes/composite/nodes/node_composite_splitViewer.c b/source/blender/nodes/composite/nodes/node_composite_splitViewer.c
index 73cf039c6df..41fb0e822ed 100644
--- a/source/blender/nodes/composite/nodes/node_composite_splitViewer.c
+++ b/source/blender/nodes/composite/nodes/node_composite_splitViewer.c
@@ -77,7 +77,7 @@ static void node_composit_exec_splitviewer(void *data, bNode *node, bNodeStack *
ibuf= BKE_image_acquire_ibuf(ima, node->storage, &lock);
if (ibuf==NULL) {
printf("node_composit_exec_viewer error\n");
- BKE_image_release_ibuf(ima, lock);
+ BKE_image_release_ibuf(ima, ibuf, lock);
return;
}
@@ -128,7 +128,7 @@ static void node_composit_exec_splitviewer(void *data, bNode *node, bNodeStack *
composit3_pixel_processor(node, cbuf, buf1, in[0]->vec, buf2, in[1]->vec, mask, NULL, do_copy_split_rgba, CB_RGBA, CB_RGBA, CB_VAL);
- BKE_image_release_ibuf(ima, lock);
+ BKE_image_release_ibuf(ima, ibuf, lock);
generate_preview(data, node, cbuf);
free_compbuf(cbuf);
diff --git a/source/blender/nodes/composite/nodes/node_composite_viewer.c b/source/blender/nodes/composite/nodes/node_composite_viewer.c
index 938f75cf3f5..1c27cc21b06 100644
--- a/source/blender/nodes/composite/nodes/node_composite_viewer.c
+++ b/source/blender/nodes/composite/nodes/node_composite_viewer.c
@@ -62,7 +62,7 @@ static void node_composit_exec_viewer(void *data, bNode *node, bNodeStack **in,
ibuf = BKE_image_acquire_ibuf(ima, node->storage, &lock);
if (ibuf == NULL) {
printf("node_composit_exec_viewer error\n");
- BKE_image_release_ibuf(ima, lock);
+ BKE_image_release_ibuf(ima, ibuf, lock);
return;
}
@@ -112,7 +112,7 @@ static void node_composit_exec_viewer(void *data, bNode *node, bNodeStack **in,
free_compbuf(zbuf);
}
- BKE_image_release_ibuf(ima, lock);
+ BKE_image_release_ibuf(ima, ibuf, lock);
generate_preview(data, node, cbuf);
free_compbuf(cbuf);
diff --git a/source/blender/nodes/shader/nodes/node_shader_normal_map.c b/source/blender/nodes/shader/nodes/node_shader_normal_map.c
index ee83699abdb..6a4eb9d81df 100644
--- a/source/blender/nodes/shader/nodes/node_shader_normal_map.c
+++ b/source/blender/nodes/shader/nodes/node_shader_normal_map.c
@@ -31,7 +31,7 @@
static bNodeSocketTemplate sh_node_normal_map_in[] = {
{ SOCK_FLOAT, 1, N_("Strength"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 10.0f},
- { SOCK_RGBA, 0, N_("Color"), 0.5f, 0.5f, 1.0f, 1.0f, 0.0f, 1.0f},
+ { SOCK_RGBA, 1, N_("Color"), 0.5f, 0.5f, 1.0f, 1.0f, 0.0f, 1.0f},
{ -1, 0, "" }
};
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_environment.c b/source/blender/nodes/shader/nodes/node_shader_tex_environment.c
index abe8e0190c8..d2d0870e2ed 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_environment.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_environment.c
@@ -75,12 +75,13 @@ static int node_shader_gpu_tex_environment(GPUMaterial *mat, bNode *node, GPUNod
ret = GPU_stack_link(mat, "node_tex_environment", in, out, GPU_image(ima, iuser, isdata));
if (ret) {
- ImBuf *ibuf = BKE_image_get_ibuf(ima, iuser);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL);
if (ibuf && (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA) == 0 &&
GPU_material_do_color_management(mat))
{
GPU_link(mat, "srgb_to_linearrgb", out[0].link, &out[0].link);
}
+ BKE_image_release_ibuf(ima, ibuf, NULL);
}
return ret;
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_image.c b/source/blender/nodes/shader/nodes/node_shader_tex_image.c
index 9b17f76bd47..49b38434246 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_image.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_image.c
@@ -75,12 +75,13 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat, bNode *node, GPUNodeStack
ret = GPU_stack_link(mat, "node_tex_image", in, out, GPU_image(ima, iuser, isdata));
if (ret) {
- ImBuf *ibuf = BKE_image_get_ibuf(ima, iuser);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL);
if (ibuf && (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA) == 0 &&
GPU_material_do_color_management(mat))
{
GPU_link(mat, "srgb_to_linearrgb", out[0].link, &out[0].link);
}
+ BKE_image_release_ibuf(ima, ibuf, NULL);
}
return ret;
diff --git a/source/blender/nodes/shader/nodes/node_shader_texture.c b/source/blender/nodes/shader/nodes/node_shader_texture.c
index 6d1b3ff6dba..b77c7d07407 100644
--- a/source/blender/nodes/shader/nodes/node_shader_texture.c
+++ b/source/blender/nodes/shader/nodes/node_shader_texture.c
@@ -128,12 +128,13 @@ static int gpu_shader_texture(GPUMaterial *mat, bNode *node, GPUNodeStack *in, G
int ret = GPU_stack_link(mat, "texture_image", in, out, texlink);
if (ret) {
- ImBuf *ibuf = BKE_image_get_ibuf(tex->ima, &tex->iuser);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(tex->ima, &tex->iuser, NULL);
if (ibuf && (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA) ==0 &&
GPU_material_do_color_management(mat))
{
GPU_link(mat, "srgb_to_linearrgb", out[1].link, &out[1].link);
}
+ BKE_image_release_ibuf(tex->ima, ibuf, NULL);
}
return ret;
diff --git a/source/blender/nodes/texture/nodes/node_texture_image.c b/source/blender/nodes/texture/nodes/node_texture_image.c
index f3fdaf0bb64..2ef1669a266 100644
--- a/source/blender/nodes/texture/nodes/node_texture_image.c
+++ b/source/blender/nodes/texture/nodes/node_texture_image.c
@@ -46,7 +46,7 @@ static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **UNUSED(i
ImageUser *iuser= (ImageUser *)node->storage;
if ( ima ) {
- ImBuf *ibuf = BKE_image_get_ibuf(ima, iuser);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL);
if ( ibuf ) {
float xsize, ysize;
float xoff, yoff;
@@ -77,6 +77,8 @@ static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **UNUSED(i
result = ibuf->rect_float + py*ibuf->x*4 + px*4;
copy_v4_v4(out, result);
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
}
}
}
diff --git a/source/blender/python/bmesh/bmesh_py_ops.c b/source/blender/python/bmesh/bmesh_py_ops.c
index fb5b94249e6..2b82826eb04 100644
--- a/source/blender/python/bmesh/bmesh_py_ops.c
+++ b/source/blender/python/bmesh/bmesh_py_ops.c
@@ -90,6 +90,7 @@ 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;
@@ -122,7 +123,7 @@ static PyObject *pyrna_op_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject *
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, slot_name);
+ BMOpSlot *slot = BMO_slot_get(bmop.slots_in, slot_name);
if (slot == NULL) {
PyErr_Format(PyExc_TypeError,
@@ -146,7 +147,7 @@ static PyObject *pyrna_op_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject *
return NULL;
}
else {
- slot->data.i = param;
+ BMO_SLOT_AS_BOOL(slot) = param;
}
break;
@@ -169,7 +170,7 @@ static PyObject *pyrna_op_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject *
return NULL;
}
else {
- slot->data.i = (int)param;
+ BMO_SLOT_AS_INT(slot) = (int)param;
}
break;
}
@@ -183,7 +184,7 @@ static PyObject *pyrna_op_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject *
return NULL;
}
else {
- slot->data.f = param;
+ BMO_SLOT_AS_FLOAT(slot) = param;
}
break;
}
@@ -210,13 +211,13 @@ static PyObject *pyrna_op_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject *
return NULL;
}
- BMO_slot_mat_set(&bmop, slot_name, ((MatrixObject *)value)->matrix, size);
+ 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(slot->data.vec, 3, 3, value, slot_name) == -1) {
+ if (mathutils_array_parse(BMO_SLOT_AS_VECTOR(slot), 3, 3, value, slot_name) == -1) {
return NULL;
}
break;
@@ -243,15 +244,15 @@ static PyObject *pyrna_op_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject *
if (BPy_BMVertSeq_Check(value)) {
BPY_BM_GENERIC_MESH_TEST("verts");
- BMO_slot_buffer_from_all(bm, &bmop, slot_name, BM_VERT);
+ 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, slot_name, BM_EDGE);
+ 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, slot_name, BM_FACE);
+ BMO_slot_buffer_from_all(bm, &bmop, bmop.slots_in, slot_name, BM_FACE);
}
else if (BPy_BMElemSeq_Check(value)) {
BMIter iter;
@@ -266,11 +267,11 @@ static PyObject *pyrna_op_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject *
/* calls bpy_bmelemseq_length() */
tot = Py_TYPE(value)->tp_as_sequence->sq_length((PyObject *)self);
- BMO_slot_buffer_alloc(&bmop, slot_name, tot);
+ BMO_slot_buffer_alloc(&bmop, bmop.slots_in, slot_name, tot);
i = 0;
BM_ITER_BPY_BM_SEQ (ele, &iter, ((BPy_BMElemSeq *)value)) {
- ((void **)slot->data.buf)[i] = (void *)ele;
+ slot->data.buf[i] = ele;
i++;
}
}
@@ -288,7 +289,7 @@ static PyObject *pyrna_op_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject *
return NULL;
}
- BMO_slot_buffer_alloc(&bmop, slot_name, elem_array_len);
+ 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);
}
@@ -316,13 +317,104 @@ static PyObject *pyrna_op_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject *
}
BMO_op_exec(bm, &bmop);
- BMO_op_finish(bm, &bmop);
- if (bpy_bm_op_as_py_error(bm) == -1) {
- return NULL;
+ /* 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();
- Py_RETURN_NONE;
+ 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;
}
@@ -413,17 +505,17 @@ static PyObject *bpy_bmesh_fmod_getattro(PyObject *UNUSED(self), PyObject *pynam
{
const unsigned int tot = bmesh_total_ops;
unsigned int i;
- const char *name = _PyUnicode_AsString(pyname);
+ const char *opname = _PyUnicode_AsString(pyname);
for (i = 0; i < tot; i++) {
- if (strcmp(opdefines[i]->name, name) == 0) {
- return bpy_bmesh_op_CreatePyObject(opdefines[i]->name);
+ if (strcmp(opdefines[i]->opname, opname) == 0) {
+ return bpy_bmesh_op_CreatePyObject(opdefines[i]->opname);
}
}
PyErr_Format(PyExc_AttributeError,
"BMeshOpsModule: operator \"%.200s\" doesn't exist",
- name);
+ opname);
return NULL;
}
@@ -436,7 +528,7 @@ static PyObject *bpy_bmesh_fmod_dir(PyObject *UNUSED(self))
ret = PyList_New(bmesh_total_ops);
for (i = 0; i < tot; i++) {
- PyList_SET_ITEM(ret, i, PyUnicode_FromString(opdefines[i]->name));
+ PyList_SET_ITEM(ret, i, PyUnicode_FromString(opdefines[i]->opname));
}
return ret;
diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c
index 2cae10101d1..ee4528df50d 100644
--- a/source/blender/python/bmesh/bmesh_py_types.c
+++ b/source/blender/python/bmesh/bmesh_py_types.c
@@ -801,34 +801,92 @@ static PyObject *bpy_bmesh_to_mesh(BPy_BMesh *self, PyObject *args)
Py_RETURN_NONE;
}
-/* note: rna_Object_to_mesh() also has apply_modifiers arg that works the same way */
PyDoc_STRVAR(bpy_bmesh_from_object_doc,
-".. method:: from_object(mesh, apply_modifiers=True)\n"
+".. method:: from_object(object, scene, deform=True, render=False, cage=False)\n"
"\n"
-" Initialize this bmesh from existing object datablock.\n"
+" Initialize this bmesh from existing object datablock (currently only meshes are supported).\n"
"\n"
" :arg object: The object data to load.\n"
" :type object: :class:`Object`\n"
-" :arg apply_modifiers: Use the final display mesh rather then the deformed cage.\n"
-" :type apply_modifiers: boolean\n"
+" :arg deform: Apply deformation modifiers.\n"
+" :type deform: boolean\n"
+" :arg render: Use render settings.\n"
+" :type render: boolean\n"
+" :arg cage: Get the mesh as a deformed cage.\n"
+" :type cage: boolean\n"
);
static PyObject *bpy_bmesh_from_object(BPy_BMesh *self, PyObject *args)
{
PyObject *py_object;
+ PyObject *py_scene;
Object *ob;
+ struct Scene *scene;
BMesh *bm;
- int apply_modifiers = TRUE;
+ int use_deform = TRUE;
+ int use_render = FALSE;
+ int use_cage = FALSE;
DerivedMesh *dm;
+ const int mask = CD_MASK_BMESH;
BPY_BM_CHECK_OBJ(self);
- if (!PyArg_ParseTuple(args, "O|i:from_object", &py_object, &apply_modifiers) ||
- !(ob = PyC_RNA_AsPointer(py_object, "Object")))
+ if (!PyArg_ParseTuple(args, "OO|iii:from_object", &py_object, &py_scene, &use_render, &use_cage) ||
+ !(ob = PyC_RNA_AsPointer(py_object, "Object")) ||
+ !(scene = PyC_RNA_AsPointer(py_scene, "Scene")))
{
return NULL;
}
- dm = apply_modifiers ? ob->derivedFinal : ob->derivedDeform;
+ if (ob->type != OB_MESH) {
+ PyErr_SetString(PyExc_ValueError,
+ "from_object(...): currently only mesh objects are supported");
+ return NULL;
+ }
+
+ /* Write the display mesh into the dummy mesh */
+ if (use_deform) {
+ if (use_render) {
+ if (use_cage) {
+ PyErr_SetString(PyExc_ValueError,
+ "from_object(...): cage arg is unsupported when (render=True)");
+ return NULL;
+ }
+ else {
+ dm = mesh_create_derived_render(scene, ob, mask);
+ }
+ }
+ else {
+ if (use_cage) {
+ dm = mesh_get_derived_deform(scene, ob, mask); /* ob->derivedDeform */
+ }
+ else {
+ dm = mesh_get_derived_final(scene, ob, mask); /* ob->derivedFinal */
+ }
+ }
+ }
+ else {
+ /* !use_deform */
+ if (use_render) {
+ if (use_cage) {
+ PyErr_SetString(PyExc_ValueError,
+ "from_object(...): cage arg is unsupported when (render=True)");
+ return NULL;
+ }
+ else {
+ dm = mesh_create_derived_no_deform_render(scene, ob, NULL, mask);
+ }
+ }
+ else {
+ if (use_cage) {
+ PyErr_SetString(PyExc_ValueError,
+ "from_object(...): cage arg is unsupported when (deform=False, render=False)");
+ return NULL;
+ }
+ else {
+ dm = mesh_create_derived_no_deform(scene, ob, NULL, mask);
+ }
+ }
+ }
if (dm == NULL) {
PyErr_Format(PyExc_ValueError,
@@ -840,6 +898,8 @@ static PyObject *bpy_bmesh_from_object(BPy_BMesh *self, PyObject *args)
DM_to_bmesh_ex(dm, bm);
+ dm->release(dm);
+
Py_RETURN_NONE;
}
@@ -1790,7 +1850,7 @@ static PyObject *bpy_bmfaceseq_new(BPy_BMElemSeq *self, PyObject *args)
}
/* check if the face exists */
- if (BM_face_exists(bm, vert_array, vert_seq_len, NULL)) {
+ if (BM_face_exists(vert_array, vert_seq_len, NULL)) {
PyErr_SetString(PyExc_ValueError,
"faces.new(verts): face already exists");
goto cleanup;
@@ -2012,7 +2072,7 @@ static PyObject *bpy_bmfaceseq_get__method(BPy_BMElemSeq *self, PyObject *args)
return NULL;
}
- if (BM_face_exists(bm, vert_array, vert_seq_len, &f)) {
+ if (BM_face_exists(vert_array, vert_seq_len, &f)) {
ret = BPy_BMFace_CreatePyObject(bm, f);
}
else {
@@ -3306,6 +3366,7 @@ PyObject *BPy_BMElem_CreatePyObject(BMesh *bm, BMHeader *ele)
case BM_LOOP:
return BPy_BMLoop_CreatePyObject(bm, (BMLoop *)ele);
default:
+ BLI_assert(0);
PyErr_SetString(PyExc_SystemError, "internal error");
return NULL;
}
diff --git a/source/blender/python/bmesh/bmesh_py_types_customdata.c b/source/blender/python/bmesh/bmesh_py_types_customdata.c
index 1fea12d105c..14132d08fe6 100644
--- a/source/blender/python/bmesh/bmesh_py_types_customdata.c
+++ b/source/blender/python/bmesh/bmesh_py_types_customdata.c
@@ -981,7 +981,7 @@ PyObject *BPy_BMLayerItem_GetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer)
}
case CD_PROP_INT:
{
- ret = PyLong_FromSsize_t((Py_ssize_t)(*(int *)value));
+ ret = PyLong_FromLong(*(int *)value);
break;
}
case CD_PROP_STR:
@@ -1060,7 +1060,7 @@ int BPy_BMLayerItem_SetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer, PyObj
}
case CD_PROP_INT:
{
- int tmp_val = PyLong_AsSsize_t(py_value);
+ int tmp_val = PyLong_AsLong(py_value);
if (UNLIKELY(tmp_val == -1 && PyErr_Occurred())) {
PyErr_Format(PyExc_TypeError, "expected an int, not a %.200s", Py_TYPE(py_value)->tp_name);
ret = -1;
diff --git a/source/blender/python/bmesh/bmesh_py_types_meshdata.c b/source/blender/python/bmesh/bmesh_py_types_meshdata.c
index 8316d33ea38..b0870578f5a 100644
--- a/source/blender/python/bmesh/bmesh_py_types_meshdata.c
+++ b/source/blender/python/bmesh/bmesh_py_types_meshdata.c
@@ -527,7 +527,7 @@ static PyObject *bpy_bmdeformvert_keys(BPy_BMDeformVert *self)
ret = PyList_New(self->data->totweight);
for (i = 0; i < self->data->totweight; i++, dw++) {
- PyList_SET_ITEM(ret, i, PyLong_FromSsize_t(dw->def_nr));
+ PyList_SET_ITEM(ret, i, PyLong_FromLong(dw->def_nr));
}
return ret;
@@ -576,7 +576,7 @@ static PyObject *bpy_bmdeformvert_items(BPy_BMDeformVert *self)
for (i = 0; i < self->data->totweight; i++, dw++) {
item = PyTuple_New(2);
- PyTuple_SET_ITEM(item, 0, PyLong_FromSsize_t(dw->def_nr));
+ PyTuple_SET_ITEM(item, 0, PyLong_FromLong(dw->def_nr));
PyTuple_SET_ITEM(item, 1, PyFloat_FromDouble(dw->weight));
PyList_SET_ITEM(ret, i, item);
diff --git a/source/blender/python/generic/bgl.c b/source/blender/python/generic/bgl.c
index a10bfef2a8d..22b9c1a2208 100644
--- a/source/blender/python/generic/bgl.c
+++ b/source/blender/python/generic/bgl.c
@@ -613,15 +613,15 @@ static PyObject *Buffer_repr(Buffer *self)
}
-BGL_Wrap(2, Accum, void, (GLenum, GLfloat))
-BGL_Wrap(1, ActiveTexture, void, (GLenum))
-BGL_Wrap(2, AlphaFunc, void, (GLenum, GLclampf))
+BGL_Wrap(2, Accum, void, (GLenum, GLfloat))
+BGL_Wrap(1, ActiveTexture, void, (GLenum))
+BGL_Wrap(2, AlphaFunc, void, (GLenum, GLclampf))
BGL_Wrap(3, AreTexturesResident, GLboolean, (GLsizei, GLuintP, GLbooleanP))
BGL_Wrap(2, AttachShader, void, (GLuint, GLuint))
-BGL_Wrap(1, Begin, void, (GLenum))
-BGL_Wrap(2, BindTexture, void, (GLenum, GLuint))
-BGL_Wrap(7, Bitmap, void, (GLsizei, GLsizei, GLfloat,
- GLfloat, GLfloat, GLfloat, GLubyteP))
+BGL_Wrap(1, Begin, void, (GLenum))
+BGL_Wrap(2, BindTexture, void, (GLenum, GLuint))
+BGL_Wrap(7, Bitmap, void, (GLsizei, GLsizei, GLfloat,
+ GLfloat, GLfloat, GLfloat, GLubyteP))
BGL_Wrap(2, BlendFunc, void, (GLenum, GLenum))
BGL_Wrap(1, CallList, void, (GLuint))
BGL_Wrap(3, CallLists, void, (GLsizei, GLenum, GLvoidP))
@@ -675,7 +675,7 @@ BGL_Wrap(1, CullFace, void, (GLenum))
BGL_Wrap(2, DeleteLists, void, (GLuint, GLsizei))
BGL_Wrap(1, DeleteProgram, void, (GLuint))
BGL_Wrap(1, DeleteShader, void, (GLuint))
-BGL_Wrap(2, DeleteTextures, void, (GLsizei, GLuintP))
+BGL_Wrap(2, DeleteTextures, void, (GLsizei, GLuintP))
BGL_Wrap(1, DepthFunc, void, (GLenum))
BGL_Wrap(1, DepthMask, void, (GLboolean))
BGL_Wrap(2, DepthRange, void, (GLclampd, GLclampd))
@@ -773,7 +773,7 @@ BGL_Wrap(3, Lighti, void, (GLenum, GLenum, GLint))
BGL_Wrap(3, Lightiv, void, (GLenum, GLenum, GLintP))
BGL_Wrap(2, LineStipple, void, (GLint, GLushort))
BGL_Wrap(1, LineWidth, void, (GLfloat))
-BGL_Wrap(1, LinkProgram, void, (GLuint))
+BGL_Wrap(1, LinkProgram, void, (GLuint))
BGL_Wrap(1, ListBase, void, (GLuint))
BGL_Wrap(1, LoadIdentity, void, (void))
BGL_Wrap(1, LoadMatrixd, void, (GLdoubleP))
@@ -1907,9 +1907,9 @@ PyObject *BPyInit_bgl(void)
return submodule;
}
-static PyObject *Method_ShaderSource (PyObject *UNUSED(self), PyObject *args)
+static PyObject *Method_ShaderSource(PyObject *UNUSED(self), PyObject *args)
{
- int shader;
+ unsigned int shader;
char *source;
if (!PyArg_ParseTuple(args, "Is", &shader, &source))
diff --git a/source/blender/python/generic/bpy_internal_import.c b/source/blender/python/generic/bpy_internal_import.c
index ad97ceb68d4..8d146bedb48 100644
--- a/source/blender/python/generic/bpy_internal_import.c
+++ b/source/blender/python/generic/bpy_internal_import.c
@@ -59,6 +59,19 @@ static PyMethodDef bpy_reload_meth;
static PyObject *imp_reload_orig = NULL;
/* 'builtins' is most likely PyEval_GetBuiltins() */
+
+/**
+ * \note to the discerning developer, yes - this is nasty
+ * monkey-patching our own import into Python's builtin 'imp' module.
+ *
+ * However Python's alternative is to use import hooks,
+ * which are implemented in a way that we can't use our own importer as a
+ * fall-back (instead we must try and fail - raise an exception evert time).
+ * Since importing from blenders text-blocks is not the common case
+ * I prefer to use Pythons import by default and fall-back to
+ * Blenders - which we can only do by intercepting import calls I'm afraid.
+ * - Campbell
+ */
void bpy_import_init(PyObject *builtins)
{
PyObject *item;
diff --git a/source/blender/python/generic/idprop_py_api.c b/source/blender/python/generic/idprop_py_api.c
index 529b2e708ad..53112d46098 100644
--- a/source/blender/python/generic/idprop_py_api.c
+++ b/source/blender/python/generic/idprop_py_api.c
@@ -249,7 +249,7 @@ static int BPy_IDGroup_SetName(BPy_IDProperty *self, PyObject *value, void *UNUS
#if 0
static PyObject *BPy_IDGroup_GetType(BPy_IDProperty *self)
{
- return PyLong_FromSsize_t(self->prop->type);
+ return PyLong_FromLong(self->prop->type);
}
#endif
@@ -351,7 +351,7 @@ const char *BPy_IDProperty_Map_ValidateAndCreate(PyObject *name_obj, IDProperty
prop = IDP_New(IDP_DOUBLE, &val, name);
}
else if (PyLong_Check(ob)) {
- val.i = (int) PyLong_AsSsize_t(ob);
+ val.i = (int)PyLong_AsLong(ob);
prop = IDP_New(IDP_INT, &val, name);
}
else if (PyUnicode_Check(ob)) {
@@ -409,7 +409,7 @@ const char *BPy_IDProperty_Map_ValidateAndCreate(PyObject *name_obj, IDProperty
prop = IDP_New(IDP_ARRAY, &val, name);
for (i = 0; i < val.array.len; i++) {
item = PySequence_Fast_GET_ITEM(ob_seq_fast, i);
- ((int *)IDP_Array(prop))[i] = (int)PyLong_AsSsize_t(item);
+ ((int *)IDP_Array(prop))[i] = (int)PyLong_AsLong(item);
}
break;
case IDP_IDPARRAY:
@@ -1072,7 +1072,7 @@ static int BPy_IDArray_SetItem(BPy_IDArray *self, int index, PyObject *value)
((double *)IDP_Array(self->prop))[index] = d;
break;
case IDP_INT:
- i = PyLong_AsSsize_t(value);
+ i = PyLong_AsLong(value);
if (i == -1 && PyErr_Occurred()) {
PyErr_SetString(PyExc_TypeError, "expected an int type");
return -1;
diff --git a/source/blender/python/generic/py_capi_utils.c b/source/blender/python/generic/py_capi_utils.c
index b8537a1359f..f62fdaf09db 100644
--- a/source/blender/python/generic/py_capi_utils.c
+++ b/source/blender/python/generic/py_capi_utils.c
@@ -83,13 +83,13 @@ int PyC_AsArray(void *array, PyObject *value, const Py_ssize_t length,
/* could use is_double for 'long int' but no use now */
int *array_int = array;
for (i = 0; i < length; i++) {
- array_int[i] = PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value_fast, i));
+ array_int[i] = PyLong_AsLong(PySequence_Fast_GET_ITEM(value_fast, i));
}
}
else if (type == &PyBool_Type) {
int *array_bool = array;
for (i = 0; i < length; i++) {
- array_bool[i] = (PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value_fast, i)) != 0);
+ array_bool[i] = (PyLong_AsLong(PySequence_Fast_GET_ITEM(value_fast, i)) != 0);
}
}
else {
@@ -567,7 +567,7 @@ void PyC_RunQuicky(const char *filepath, int n, ...)
ret = PyObject_CallFunction(calcsize, (char *)"s", format);
if (ret) {
- sizes[i] = PyLong_AsSsize_t(ret);
+ sizes[i] = PyLong_AsLong(ret);
Py_DECREF(ret);
ret = PyObject_CallFunction(unpack, (char *)"sy#", format, (char *)ptr, sizes[i]);
}
diff --git a/source/blender/python/intern/bpy_app.c b/source/blender/python/intern/bpy_app.c
index a8aa7269b72..b1eeff8b3ae 100644
--- a/source/blender/python/intern/bpy_app.c
+++ b/source/blender/python/intern/bpy_app.c
@@ -195,12 +195,12 @@ PyDoc_STRVAR(bpy_app_debug_value_doc,
);
static PyObject *bpy_app_debug_value_get(PyObject *UNUSED(self), void *UNUSED(closure))
{
- return PyLong_FromSsize_t(G.debug_value);
+ return PyLong_FromLong(G.debug_value);
}
static int bpy_app_debug_value_set(PyObject *UNUSED(self), PyObject *value, void *UNUSED(closure))
{
- int param = PyLong_AsSsize_t(value);
+ int param = PyLong_AsLong(value);
if (param == -1 && PyErr_Occurred()) {
PyErr_SetString(PyExc_TypeError, "bpy.app.debug_value can only be set to a whole number");
diff --git a/source/blender/python/intern/bpy_intern_string.c b/source/blender/python/intern/bpy_intern_string.c
index 7c8291d62d3..70ea57bb33f 100644
--- a/source/blender/python/intern/bpy_intern_string.c
+++ b/source/blender/python/intern/bpy_intern_string.c
@@ -38,6 +38,8 @@ PyObject *bpy_intern_str_bl_rna;
PyObject *bpy_intern_str_order;
PyObject *bpy_intern_str_attr;
PyObject *bpy_intern_str___slots__;
+PyObject *bpy_intern_str___name__;
+PyObject *bpy_intern_str___doc__;
void bpy_intern_string_init(void)
{
@@ -47,6 +49,8 @@ void bpy_intern_string_init(void)
bpy_intern_str_order = PyUnicode_FromString("order");
bpy_intern_str_attr = PyUnicode_FromString("attr");
bpy_intern_str___slots__ = PyUnicode_FromString("__slots__");
+ bpy_intern_str___name__ = PyUnicode_FromString("__name__");
+ bpy_intern_str___doc__ = PyUnicode_FromString("__doc__");
}
void bpy_intern_string_exit(void)
@@ -57,4 +61,6 @@ void bpy_intern_string_exit(void)
Py_DECREF(bpy_intern_str_order);
Py_DECREF(bpy_intern_str_attr);
Py_DECREF(bpy_intern_str___slots__);
+ Py_DECREF(bpy_intern_str___name__);
+ Py_DECREF(bpy_intern_str___doc__);
}
diff --git a/source/blender/python/intern/bpy_intern_string.h b/source/blender/python/intern/bpy_intern_string.h
index dc7af735743..0b7ca2cd47b 100644
--- a/source/blender/python/intern/bpy_intern_string.h
+++ b/source/blender/python/intern/bpy_intern_string.h
@@ -33,3 +33,5 @@ extern PyObject *bpy_intern_str_bl_rna;
extern PyObject *bpy_intern_str_order;
extern PyObject *bpy_intern_str_attr;
extern PyObject *bpy_intern_str___slots__;
+extern PyObject *bpy_intern_str___name__;
+extern PyObject *bpy_intern_str___doc__;
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c
index eaaced416fe..a0df8988068 100644
--- a/source/blender/python/intern/bpy_rna.c
+++ b/source/blender/python/intern/bpy_rna.c
@@ -1344,7 +1344,7 @@ PyObject *pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop)
ret = PyBool_FromLong(RNA_property_boolean_get(ptr, prop));
break;
case PROP_INT:
- ret = PyLong_FromSsize_t((Py_ssize_t)RNA_property_int_get(ptr, prop));
+ ret = PyLong_FromLong(RNA_property_int_get(ptr, prop));
break;
case PROP_FLOAT:
ret = PyFloat_FromDouble(RNA_property_float_get(ptr, prop));
@@ -2371,7 +2371,7 @@ static PyObject *pyrna_prop_array_subscript_slice(BPy_PropertyArrayRNA *self, Po
RNA_property_int_get_array(ptr, prop, values);
for (count = start; count < stop; count++)
- PyTuple_SET_ITEM(tuple, count - start, PyLong_FromSsize_t(values[count]));
+ PyTuple_SET_ITEM(tuple, count - start, PyLong_FromLong(values[count]));
if (values != values_stack) {
PyMem_FREE(values);
@@ -4077,7 +4077,7 @@ static PyObject *pyrna_prop_collection_items(BPy_PropertyRNA *self)
}
else {
/* a bit strange but better then returning an empty list */
- PyTuple_SET_ITEM(item, 0, PyLong_FromSsize_t(i));
+ PyTuple_SET_ITEM(item, 0, PyLong_FromLong(i));
}
PyTuple_SET_ITEM(item, 1, pyrna_struct_CreatePyObject(&itemptr));
@@ -4256,7 +4256,7 @@ static PyObject *pyrna_prop_collection_find(BPy_PropertyRNA *self, PyObject *key
}
RNA_PROP_END;
- return PyLong_FromSsize_t(index);
+ return PyLong_FromLong(index);
}
static void foreach_attr_type(BPy_PropertyRNA *self, const char *attr,
@@ -4463,13 +4463,13 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set)
switch (raw_type) {
case PROP_RAW_CHAR:
- item = PyLong_FromSsize_t((Py_ssize_t) ((char *)array)[i]);
+ item = PyLong_FromLong((long) ((char *)array)[i]);
break;
case PROP_RAW_SHORT:
- item = PyLong_FromSsize_t((Py_ssize_t) ((short *)array)[i]);
+ item = PyLong_FromLong((long) ((short *)array)[i]);
break;
case PROP_RAW_INT:
- item = PyLong_FromSsize_t((Py_ssize_t) ((int *)array)[i]);
+ item = PyLong_FromLong((long) ((int *)array)[i]);
break;
case PROP_RAW_FLOAT:
item = PyFloat_FromDouble((double) ((float *)array)[i]);
@@ -4756,7 +4756,7 @@ static PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *dat
case PROP_INT:
ret = PyTuple_New(len);
for (a = 0; a < len; a++)
- PyTuple_SET_ITEM(ret, a, PyLong_FromSsize_t((Py_ssize_t)((int *)data)[a]));
+ PyTuple_SET_ITEM(ret, a, PyLong_FromLong(((int *)data)[a]));
break;
case PROP_FLOAT:
switch (RNA_property_subtype(prop)) {
@@ -4797,7 +4797,7 @@ static PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *dat
ret = PyBool_FromLong(*(int *)data);
break;
case PROP_INT:
- ret = PyLong_FromSsize_t((Py_ssize_t)*(int *)data);
+ ret = PyLong_FromLong(*(int *)data);
break;
case PROP_FLOAT:
ret = PyFloat_FromDouble(*(float *)data);
@@ -6883,8 +6883,8 @@ static int bpy_class_validate_recursive(PointerRNA *dummyptr, StructRNA *srna, v
/* Sneaky workaround to use the class name as the bl_idname */
#define BPY_REPLACEMENT_STRING(rna_attr, py_attr) \
- if (strcmp(identifier, rna_attr) == 0) { \
- item = PyObject_GetAttrString(py_class, py_attr); \
+ (strcmp(identifier, rna_attr) == 0) { \
+ item = PyObject_GetAttr(py_class, py_attr); \
if (item && item != Py_None) { \
if (pyrna_py_to_prop(dummyptr, prop, NULL, \
item, "validating class:") != 0) \
@@ -6894,11 +6894,10 @@ static int bpy_class_validate_recursive(PointerRNA *dummyptr, StructRNA *srna, v
} \
} \
Py_XDECREF(item); \
- } (void)0
-
+ } /* intendionally allow else here */
- BPY_REPLACEMENT_STRING("bl_idname", "__name__");
- BPY_REPLACEMENT_STRING("bl_description", "__doc__");
+ if BPY_REPLACEMENT_STRING("bl_idname", bpy_intern_str___name__)
+ else if BPY_REPLACEMENT_STRING("bl_description", bpy_intern_str___doc__)
#undef BPY_REPLACEMENT_STRING
@@ -6912,10 +6911,11 @@ static int bpy_class_validate_recursive(PointerRNA *dummyptr, StructRNA *srna, v
PyErr_Clear();
}
else {
- Py_DECREF(item); /* no need to keep a ref, the class owns it */
-
- if (pyrna_py_to_prop(dummyptr, prop, NULL, item, "validating class:") != 0)
+ if (pyrna_py_to_prop(dummyptr, prop, NULL, item, "validating class:") != 0) {
+ Py_DECREF(item);
return -1;
+ }
+ Py_DECREF(item);
}
}
diff --git a/source/blender/python/intern/bpy_rna_array.c b/source/blender/python/intern/bpy_rna_array.c
index e66d8f05309..62c0ced9eab 100644
--- a/source/blender/python/intern/bpy_rna_array.c
+++ b/source/blender/python/intern/bpy_rna_array.c
@@ -507,7 +507,7 @@ static void py_to_float(PyObject *py, char *data)
static void py_to_int(PyObject *py, char *data)
{
- *(int *)data = (int)PyLong_AsSsize_t(py);
+ *(int *)data = (int)PyLong_AsLong(py);
}
static void py_to_bool(PyObject *py, char *data)
@@ -609,7 +609,7 @@ PyObject *pyrna_array_index(PointerRNA *ptr, PropertyRNA *prop, int index)
item = PyBool_FromLong(RNA_property_boolean_get_index(ptr, prop, index));
break;
case PROP_INT:
- item = PyLong_FromSsize_t(RNA_property_int_get_index(ptr, prop, index));
+ item = PyLong_FromLong(RNA_property_int_get_index(ptr, prop, index));
break;
default:
PyErr_SetString(PyExc_TypeError, "not an array type");
@@ -766,7 +766,7 @@ int pyrna_array_contains_py(PointerRNA *ptr, PropertyRNA *prop, PyObject *value)
case PROP_BOOLEAN:
case PROP_INT:
{
- int value_i = PyLong_AsSsize_t(value);
+ int value_i = PyLong_AsLong(value);
if (value_i == -1 && PyErr_Occurred()) {
PyErr_Clear();
return 0;
diff --git a/source/blender/python/mathutils/mathutils_Vector.c b/source/blender/python/mathutils/mathutils_Vector.c
index 19be2b6a62e..e98af997507 100644
--- a/source/blender/python/mathutils/mathutils_Vector.c
+++ b/source/blender/python/mathutils/mathutils_Vector.c
@@ -2784,7 +2784,7 @@ static struct PyMethodDef Vector_methods[] = {
/* Note
* Py_TPFLAGS_CHECKTYPES allows us to avoid casting all types to Vector when coercing
* but this means for eg that
- * (vec * mat) and (mat * vec) both get sent to Vector_mul and it neesd to sort out the order
+ * (vec * mat) and (mat * vec) both get sent to Vector_mul and it needs to sort out the order
*/
PyDoc_STRVAR(vector_doc,
diff --git a/source/blender/render/extern/include/RE_engine.h b/source/blender/render/extern/include/RE_engine.h
index 1331c287d7c..d2ffc3a0e26 100644
--- a/source/blender/render/extern/include/RE_engine.h
+++ b/source/blender/render/extern/include/RE_engine.h
@@ -60,6 +60,7 @@ struct Scene;
#define RE_ENGINE_PREVIEW 2
#define RE_ENGINE_DO_DRAW 4
#define RE_ENGINE_DO_UPDATE 8
+#define RE_ENGINE_RENDERING 16
extern ListBase R_engines;
diff --git a/source/blender/render/intern/include/initrender.h b/source/blender/render/intern/include/initrender.h
index 43ab9552194..73dc29c8feb 100644
--- a/source/blender/render/intern/include/initrender.h
+++ b/source/blender/render/intern/include/initrender.h
@@ -40,8 +40,9 @@ struct Object;
void free_sample_tables(Render *re);
void make_sample_tables(Render *re);
-void initparts(Render *re, int do_crop);
-void freeparts(Render *re);
+void RE_parts_clamp(Render *re);
+void RE_parts_init(Render *re, int do_crop);
+void RE_parts_free(Render *re);
#endif /* __INITRENDER_H__ */
diff --git a/source/blender/render/intern/raytrace/rayobject_internal.h b/source/blender/render/intern/raytrace/rayobject_internal.h
index 92ac39909a8..aa8ab8c3da4 100644
--- a/source/blender/render/intern/raytrace/rayobject_internal.h
+++ b/source/blender/render/intern/raytrace/rayobject_internal.h
@@ -92,7 +92,7 @@ int RE_rayobjectcontrol_test_break(RayObjectControl *c);
* eg.: on render code)
*
* 0 means it's reserved and has it own meaning inside each ray acceleration structure
- * (this way each structure can use the allign offset to determine if a node represents a
+ * (this way each structure can use the align offset to determine if a node represents a
* RayObject primitive, which can be used to save memory)
*/
diff --git a/source/blender/render/intern/raytrace/rayobject_octree.cpp b/source/blender/render/intern/raytrace/rayobject_octree.cpp
index 77e9dc9d8fd..afb8fe6c3b5 100644
--- a/source/blender/render/intern/raytrace/rayobject_octree.cpp
+++ b/source/blender/render/intern/raytrace/rayobject_octree.cpp
@@ -1026,7 +1026,7 @@ static int RE_rayobject_octree_intersect(RayObject *tree, Isect *is)
labdao = ddalabda;
- /* traversing ocree nodes need careful detection of smallest values, with proper
+ /* traversing octree nodes need careful detection of smallest values, with proper
* exceptions for equal labdas */
eqval = (labdax == labday);
if (labday == labdaz) eqval += 2;
diff --git a/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp b/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp
index bae65c492f4..4195b103811 100644
--- a/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp
+++ b/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp
@@ -435,7 +435,7 @@ int rtbuild_heuristic_object_split(RTBuilder *b, int nchilds)
/*
* Helper code
* PARTITION code / used on mean-split
- * basicly this a std::nth_element (like on C++ STL algorithm)
+ * basically this a std::nth_element (like on C++ STL algorithm)
*/
#if 0
static void split_leafs(RTBuilder *b, int *nth, int partitions, int split_axis)
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index 759b0737c01..d6e6171047e 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -125,7 +125,9 @@
#define FLT_EPSILON10 1.19209290e-06F
/* could enable at some point but for now there are far too many conversions */
-#pragma GCC diagnostic ignored "-Wdouble-promotion"
+#ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wdouble-promotion"
+#endif
/* ------------------------------------------------------------------------- */
diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c
index 28f70211a9c..c3126e57b53 100644
--- a/source/blender/render/intern/source/envmap.c
+++ b/source/blender/render/intern/source/envmap.c
@@ -687,11 +687,12 @@ int envmaptex(Tex *tex, const float texvec[3], float dxt[3], float dyt[3], int o
env->ima = tex->ima;
if (env->ima && env->ima->ok) {
if (env->cube[1] == NULL) {
- ImBuf *ibuf_ima = BKE_image_get_ibuf(env->ima, NULL);
+ ImBuf *ibuf_ima = BKE_image_acquire_ibuf(env->ima, NULL, NULL);
if (ibuf_ima)
envmap_split_ima(env, ibuf_ima);
else
env->ok = 0;
+ BKE_image_release_ibuf(env->ima, ibuf_ima, NULL);
}
}
}
diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c
index d771cf2253d..6fdf11ba48c 100644
--- a/source/blender/render/intern/source/external_engine.c
+++ b/source/blender/render/intern/source/external_engine.c
@@ -316,6 +316,7 @@ int RE_engine_render(Render *re, int do_all)
{
RenderEngineType *type = RE_engines_find(re->r.engine);
RenderEngine *engine;
+ int persistent_data = re->r.mode & R_PERSISTENT_DATA;
/* verify if we can render */
if (!type->render)
@@ -349,11 +350,17 @@ int RE_engine_render(Render *re, int do_all)
re->i.totface = re->i.totvert = re->i.totstrand = re->i.totlamp = re->i.tothalo = 0;
/* render */
- if(!re->engine)
- re->engine = RE_engine_create(type);
-
engine = re->engine;
+ if (!engine) {
+ engine = RE_engine_create(type);
+
+ if (persistent_data)
+ re->engine = engine;
+ }
+
+ engine->flag |= RE_ENGINE_RENDERING;
+
/* TODO: actually link to a parent which shouldn't happen */
engine->re = re;
@@ -369,7 +376,7 @@ int RE_engine_render(Render *re, int do_all)
if ((re->r.scemode & (R_NO_FRAME_UPDATE | R_PREVIEWBUTS)) == 0)
BKE_scene_update_for_newframe(re->main, re->scene, re->lay);
- initparts(re, FALSE);
+ RE_parts_init(re, FALSE);
engine->tile_x = re->partx;
engine->tile_y = re->party;
@@ -382,8 +389,15 @@ int RE_engine_render(Render *re, int do_all)
if (type->render)
type->render(engine, re->scene);
- if(!(re->r.mode & R_PERSISTENT_DATA)) {
- RE_engine_free(re->engine);
+ engine->tile_x = 0;
+ engine->tile_y = 0;
+ engine->flag &= ~RE_ENGINE_RENDERING;
+
+ render_result_free_list(&engine->fullresult, engine->fullresult.first);
+
+ /* re->engine becomes zero if user changed active render engine during render */
+ if (!persistent_data || !re->engine) {
+ RE_engine_free(engine);
re->engine = NULL;
}
@@ -393,11 +407,7 @@ int RE_engine_render(Render *re, int do_all)
BLI_rw_mutex_unlock(&re->resultmutex);
}
- engine->tile_x = 0;
- engine->tile_y = 0;
- freeparts(re);
-
- render_result_free_list(&engine->fullresult, engine->fullresult.first);
+ RE_parts_free(re);
if (BKE_reports_contain(re->reports, RPT_ERROR))
G.is_break = TRUE;
diff --git a/source/blender/render/intern/source/imagetexture.c b/source/blender/render/intern/source/imagetexture.c
index db1454fd82f..cd06839b004 100644
--- a/source/blender/render/intern/source/imagetexture.c
+++ b/source/blender/render/intern/source/imagetexture.c
@@ -124,13 +124,16 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResul
/* hack for icon render */
if (ima->ibufs.first==NULL && (R.r.scemode & R_NO_IMAGE_LOAD))
return retval;
-
- ibuf= BKE_image_get_ibuf(ima, &tex->iuser);
+
+ ibuf= BKE_image_acquire_ibuf(ima, &tex->iuser, NULL);
ima->flag|= IMA_USED_FOR_RENDER;
}
- if (ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL))
+ if (ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL)) {
+ if (ima)
+ BKE_image_release_ibuf(ima, ibuf, NULL);
return retval;
+ }
/* setup mapping */
if (tex->imaflag & TEX_IMAROT) {
@@ -155,11 +158,17 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResul
/* pass */
}
else {
+ if (ima)
+ BKE_image_release_ibuf(ima, ibuf, NULL);
return retval;
}
}
if ( (tex->flag & TEX_CHECKER_EVEN)==0) {
- if ((xs+ys) & 1) return retval;
+ if ((xs+ys) & 1) {
+ if (ima)
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ return retval;
+ }
}
/* scale around center, (0.5, 0.5) */
if (tex->checkerdist<1.0f) {
@@ -173,11 +182,15 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResul
if (tex->extend == TEX_CLIPCUBE) {
if (x<0 || y<0 || x>=ibuf->x || y>=ibuf->y || texvec[2]<-1.0f || texvec[2]>1.0f) {
+ if (ima)
+ BKE_image_release_ibuf(ima, ibuf, NULL);
return retval;
}
}
else if ( tex->extend==TEX_CLIP || tex->extend==TEX_CHECKER) {
if (x<0 || y<0 || x>=ibuf->x || y>=ibuf->y) {
+ if (ima)
+ BKE_image_release_ibuf(ima, ibuf, NULL);
return retval;
}
}
@@ -287,6 +300,9 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResul
texres->tb*= fx;
}
+ if (ima)
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+
BRICONTRGB;
return retval;
@@ -1056,10 +1072,14 @@ static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, const float tex
if (ima) { /* hack for icon render */
if ((ima->ibufs.first == NULL) && (R.r.scemode & R_NO_IMAGE_LOAD)) return retval;
- ibuf = BKE_image_get_ibuf(ima, &tex->iuser);
+ ibuf = BKE_image_acquire_ibuf(ima, &tex->iuser, NULL);
}
- if ((ibuf == NULL) || ((ibuf->rect == NULL) && (ibuf->rect_float == NULL))) return retval;
+ if ((ibuf == NULL) || ((ibuf->rect == NULL) && (ibuf->rect_float == NULL))) {
+ if (ima)
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ return retval;
+ }
if (ima) {
ima->flag |= IMA_USED_FOR_RENDER;
@@ -1172,8 +1192,16 @@ static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, const float tex
}
}
else {
- if ((tex->flag & TEX_CHECKER_ODD) == 0 && ((xs + ys) & 1) == 0) return retval;
- if ((tex->flag & TEX_CHECKER_EVEN) == 0 && (xs + ys) & 1) return retval;
+ if ((tex->flag & TEX_CHECKER_ODD) == 0 && ((xs + ys) & 1) == 0) {
+ if (ima)
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ return retval;
+ }
+ if ((tex->flag & TEX_CHECKER_EVEN) == 0 && (xs + ys) & 1) {
+ if (ima)
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ return retval;
+ }
fx -= xs;
fy -= ys;
}
@@ -1189,10 +1217,18 @@ static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, const float tex
}
if (tex->extend == TEX_CLIPCUBE) {
- if ((fx + minx) < 0.f || (fy + miny) < 0.f || (fx - minx) > 1.f || (fy - miny) > 1.f || texvec[2] < -1.f || texvec[2] > 1.f) return retval;
+ if ((fx + minx) < 0.f || (fy + miny) < 0.f || (fx - minx) > 1.f || (fy - miny) > 1.f || texvec[2] < -1.f || texvec[2] > 1.f) {
+ if (ima)
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ return retval;
+ }
}
else if (tex->extend == TEX_CLIP || tex->extend == TEX_CHECKER) {
- if ((fx + minx) < 0.f || (fy + miny) < 0.f || (fx - minx) > 1.f || (fy - miny) > 1.f) return retval;
+ if ((fx + minx) < 0.f || (fy + miny) < 0.f || (fx - minx) > 1.f || (fy - miny) > 1.f) {
+ if (ima)
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ return retval;
+ }
}
else {
if (tex->extend == TEX_EXTEND) {
@@ -1413,6 +1449,9 @@ static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, const float tex
texres->tb *= fx;
}
+ if (ima)
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+
BRICONTRGB;
return retval;
@@ -1449,12 +1488,15 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const
if (ima->ibufs.first==NULL && (R.r.scemode & R_NO_IMAGE_LOAD))
return retval;
- ibuf= BKE_image_get_ibuf(ima, &tex->iuser);
+ ibuf= BKE_image_acquire_ibuf(ima, &tex->iuser, NULL);
ima->flag|= IMA_USED_FOR_RENDER;
}
- if (ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL))
+ if (ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL)) {
+ if (ima)
+ BKE_image_release_ibuf(ima, ibuf, NULL);
return retval;
+ }
/* mipmap test */
image_mipmap_test(tex, ibuf);
@@ -1565,11 +1607,15 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const
/* pass */
}
else {
+ if (ima)
+ BKE_image_release_ibuf(ima, ibuf, NULL);
return retval;
}
}
if ( (tex->flag & TEX_CHECKER_EVEN)==0) {
if ((xs + ys) & 1) {
+ if (ima)
+ BKE_image_release_ibuf(ima, ibuf, NULL);
return retval;
}
}
@@ -1605,11 +1651,15 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const
if (tex->extend == TEX_CLIPCUBE) {
if (fx+minx<0.0f || fy+miny<0.0f || fx-minx>1.0f || fy-miny>1.0f || texvec[2]<-1.0f || texvec[2]>1.0f) {
+ if (ima)
+ BKE_image_release_ibuf(ima, ibuf, NULL);
return retval;
}
}
else if (tex->extend==TEX_CLIP || tex->extend==TEX_CHECKER) {
if (fx+minx<0.0f || fy+miny<0.0f || fx-minx>1.0f || fy-miny>1.0f) {
+ if (ima)
+ BKE_image_release_ibuf(ima, ibuf, NULL);
return retval;
}
}
@@ -1804,6 +1854,9 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const
mul_v3_fl(&texres->tr, 1.0f / texres->ta);
}
+ if (ima)
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+
BRICONTRGB;
return retval;
@@ -1812,7 +1865,7 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const
void image_sample(Image *ima, float fx, float fy, float dx, float dy, float result[4])
{
TexResult texres;
- ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
+ ImBuf *ibuf= BKE_image_acquire_ibuf(ima, NULL, NULL);
if (UNLIKELY(ibuf == NULL)) {
zero_v4(result);
@@ -1830,6 +1883,8 @@ void image_sample(Image *ima, float fx, float fy, float dx, float dy, float resu
ibuf->rect-= (ibuf->x*ibuf->y);
ima->flag|= IMA_USED_FOR_RENDER;
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
}
void ibuf_sample(ImBuf *ibuf, float fx, float fy, float dx, float dy, float result[4])
diff --git a/source/blender/render/intern/source/initrender.c b/source/blender/render/intern/source/initrender.c
index b2cf8db7995..3ea74abbcc2 100644
--- a/source/blender/render/intern/source/initrender.c
+++ b/source/blender/render/intern/source/initrender.c
@@ -525,7 +525,7 @@ void RE_GetCameraWindow(struct Render *re, struct Object *camera, int frame, flo
/* ~~~~~~~~~~~~~~~~ part (tile) calculus ~~~~~~~~~~~~~~~~~~~~~~ */
-void freeparts(Render *re)
+void RE_parts_free(Render *re)
{
RenderPart *part = re->parts.first;
@@ -537,12 +537,19 @@ void freeparts(Render *re)
BLI_freelistN(&re->parts);
}
-void initparts(Render *re, int do_crop)
+void RE_parts_clamp(Render *re)
+{
+ /* part size */
+ re->partx = min_ii(re->r.tilex, re->rectx);
+ re->party = min_ii(re->r.tiley, re->recty);
+}
+
+void RE_parts_init(Render *re, int do_crop)
{
int nr, xd, yd, partx, party, xparts, yparts;
int xminb, xmaxb, yminb, ymaxb;
- freeparts(re);
+ RE_parts_free(re);
/* this is render info for caller, is not reset when parts are freed! */
re->i.totpart = 0;
@@ -555,13 +562,10 @@ void initparts(Render *re, int do_crop)
xmaxb = re->disprect.xmax;
ymaxb = re->disprect.ymax;
- /* part size */
- partx = min_ii(re->r.tilex, re->rectx);
- party = min_ii(re->r.tiley, re->recty);
-
- re->partx = partx;
- re->party = party;
-
+ RE_parts_clamp(re);
+
+ partx = re->partx;
+ party = re->party;
/* part count */
xparts = (re->rectx + partx - 1) / partx;
yparts = (re->recty + party - 1) / party;
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index 85cafa07759..6b5b9716f3b 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -63,6 +63,7 @@
#include "BLI_string.h"
#include "BLI_path_util.h"
#include "BLI_fileops.h"
+#include "BLI_threads.h"
#include "BLI_rand.h"
#include "BLI_callbacks.h"
@@ -432,7 +433,10 @@ void RE_FreePersistentData(void)
/* render engines can be kept around for quick re-render, this clears all */
for (re = RenderGlobal.renderlist.first; re; re = re->next) {
if (re->engine) {
- RE_engine_free(re->engine);
+ /* if engine is currently rendering, just tag it to be freed when render is finished */
+ if (!(re->engine->flag & RE_ENGINE_RENDERING))
+ RE_engine_free(re->engine);
+
re->engine = NULL;
}
}
@@ -689,7 +693,7 @@ static void *do_part_thread(void *pa_v)
/* calculus for how much 1 pixel rendered should rotate the 3d geometry */
/* is not that simple, needs to be corrected for errors of larger viewplane sizes */
-/* called in initrender.c, initparts() and convertblender.c, for speedvectors */
+/* called in initrender.c, RE_parts_init() and convertblender.c, for speedvectors */
float panorama_pixel_rot(Render *re)
{
float psize, phi, xfac;
@@ -832,7 +836,7 @@ static void threaded_tile_processor(Render *re)
/* warning; no return here without closing exr file */
- initparts(re, TRUE);
+ RE_parts_init(re, TRUE);
if (re->result->do_exr_tile)
render_result_exr_file_begin(re);
@@ -924,7 +928,7 @@ static void threaded_tile_processor(Render *re)
g_break = 0;
BLI_end_threads(&threads);
- freeparts(re);
+ RE_parts_free(re);
re->viewplane = viewplane; /* restore viewplane, modified by pano render */
}
@@ -943,6 +947,7 @@ static void do_render_3d(Render *re)
return;
/* internal */
+ RE_parts_clamp(re);
// re->cfra= cfra; /* <- unused! */
re->scene->r.subframe = re->mblur_offs + re->field_offs;
diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c
index c507d6595e0..e6daa5f9094 100644
--- a/source/blender/render/intern/source/render_texture.c
+++ b/source/blender/render/intern/source/render_texture.c
@@ -1233,11 +1233,13 @@ int multitex_nodes(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int os
rgbnor = multitex(tex, texvec, dxt, dyt, osatex, texres, thread, which_output);
if (mtex->mapto & (MAP_COL+MAP_COLSPEC+MAP_COLMIR)) {
- ImBuf *ibuf = BKE_image_get_ibuf(tex->ima, &tex->iuser);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(tex->ima, &tex->iuser, NULL);
/* don't linearize float buffers, assumed to be linear */
if (ibuf && !(ibuf->rect_float) && R.scene_color_manage)
IMB_colormanagement_colorspace_to_scene_linear_v3(&texres->tr, ibuf->rect_colorspace);
+
+ BKE_image_release_ibuf(tex->ima, ibuf, NULL);
}
}
else {
@@ -1264,11 +1266,13 @@ int multitex_nodes(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int os
rgbnor= multitex(tex, texvec_l, dxt_l, dyt_l, osatex, texres, thread, which_output);
{
- ImBuf *ibuf = BKE_image_get_ibuf(tex->ima, &tex->iuser);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(tex->ima, &tex->iuser, NULL);
/* don't linearize float buffers, assumed to be linear */
if (ibuf && !(ibuf->rect_float) && R.scene_color_manage)
IMB_colormanagement_colorspace_to_scene_linear_v3(&texres->tr, ibuf->rect_colorspace);
+
+ BKE_image_release_ibuf(tex->ima, ibuf, NULL);
}
}
@@ -1723,11 +1727,12 @@ static int compatible_bump_compute(CompatibleBump *compat_bump, ShadeInput *shi,
if (!shi->osatex && (tex->type == TEX_IMAGE) && tex->ima) {
/* in case we have no proper derivatives, fall back to
* computing du/dv it based on image size */
- ImBuf *ibuf = BKE_image_get_ibuf(tex->ima, &tex->iuser);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(tex->ima, &tex->iuser, NULL);
if (ibuf) {
du = 1.f/(float)ibuf->x;
dv = 1.f/(float)ibuf->y;
}
+ BKE_image_release_ibuf(tex->ima, ibuf, NULL);
}
else if (shi->osatex) {
/* we have derivatives, can compute proper du/dv */
@@ -1900,12 +1905,13 @@ static int ntap_bump_compute(NTapBump *ntap_bump, ShadeInput *shi, MTex *mtex, T
/* resolve image dimensions */
if (found_deriv_map || (mtex->texflag&MTEX_BUMP_TEXTURESPACE)!=0) {
- ImBuf *ibuf = BKE_image_get_ibuf(tex->ima, &tex->iuser);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(tex->ima, &tex->iuser, NULL);
if (ibuf) {
dimx = ibuf->x;
dimy = ibuf->y;
aspect = ((float) dimy) / dimx;
}
+ BKE_image_release_ibuf(tex->ima, ibuf, NULL);
}
if (found_deriv_map) {
@@ -2396,11 +2402,13 @@ void do_material_tex(ShadeInput *shi, Render *re)
/* inverse gamma correction */
if (tex->type==TEX_IMAGE) {
Image *ima = tex->ima;
- ImBuf *ibuf = BKE_image_get_ibuf(ima, &tex->iuser);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &tex->iuser, NULL);
/* don't linearize float buffers, assumed to be linear */
if (ibuf && !(ibuf->rect_float) && R.scene_color_manage)
IMB_colormanagement_colorspace_to_scene_linear_v3(tcol, ibuf->rect_colorspace);
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
}
if (mtex->mapto & MAP_COL) {
@@ -2928,11 +2936,13 @@ void do_halo_tex(HaloRen *har, float xn, float yn, float col_r[4])
/* inverse gamma correction */
if (mtex->tex->type==TEX_IMAGE) {
Image *ima = mtex->tex->ima;
- ImBuf *ibuf = BKE_image_get_ibuf(ima, &mtex->tex->iuser);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &mtex->tex->iuser, NULL);
/* don't linearize float buffers, assumed to be linear */
if (ibuf && !(ibuf->rect_float) && R.scene_color_manage)
IMB_colormanagement_colorspace_to_scene_linear_v3(&texres.tr, ibuf->rect_colorspace);
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
}
fact= texres.tin*mtex->colfac;
@@ -3147,11 +3157,13 @@ void do_sky_tex(const float rco[3], float lo[3], const float dxyview[2], float h
/* inverse gamma correction */
if (tex->type==TEX_IMAGE) {
Image *ima = tex->ima;
- ImBuf *ibuf = BKE_image_get_ibuf(ima, &tex->iuser);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &tex->iuser, NULL);
/* don't linearize float buffers, assumed to be linear */
if (ibuf && !(ibuf->rect_float) && R.scene_color_manage)
IMB_colormanagement_colorspace_to_scene_linear_v3(tcol, ibuf->rect_colorspace);
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
}
if (mtex->mapto & WOMAP_HORIZ) {
@@ -3361,11 +3373,13 @@ void do_lamp_tex(LampRen *la, const float lavec[3], ShadeInput *shi, float col_r
/* inverse gamma correction */
if (tex->type==TEX_IMAGE) {
Image *ima = tex->ima;
- ImBuf *ibuf = BKE_image_get_ibuf(ima, &tex->iuser);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &tex->iuser, NULL);
/* don't linearize float buffers, assumed to be linear */
if (ibuf && !(ibuf->rect_float) && R.scene_color_manage)
IMB_colormanagement_colorspace_to_scene_linear_v3(&texres.tr, ibuf->rect_colorspace);
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
}
/* lamp colors were premultiplied with this */
diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c
index 9fe2620747c..3431c3ff5de 100644
--- a/source/blender/render/intern/source/rendercore.c
+++ b/source/blender/render/intern/source/rendercore.c
@@ -2506,21 +2506,26 @@ static int get_next_bake_face(BakeShade *bs)
if (tface && tface->tpage) {
Image *ima= tface->tpage;
- ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
+ ImBuf *ibuf= BKE_image_acquire_ibuf(ima, NULL, NULL);
const float vec_alpha[4]= {0.0f, 0.0f, 0.0f, 0.0f};
const float vec_solid[4]= {0.0f, 0.0f, 0.0f, 1.0f};
if (ibuf==NULL)
continue;
- if (ibuf->rect==NULL && ibuf->rect_float==NULL)
+ if (ibuf->rect==NULL && ibuf->rect_float==NULL) {
+ BKE_image_release_ibuf(ima, ibuf, NULL);
continue;
+ }
- if (ibuf->rect_float && !(ibuf->channels==0 || ibuf->channels==4))
+ if (ibuf->rect_float && !(ibuf->channels==0 || ibuf->channels==4)) {
+ BKE_image_release_ibuf(ima, ibuf, NULL);
continue;
+ }
if (ima->flag & IMA_USED_FOR_RENDER) {
ima->id.flag &= ~LIB_DOIT;
+ BKE_image_release_ibuf(ima, ibuf, NULL);
continue;
}
@@ -2548,6 +2553,9 @@ static int get_next_bake_face(BakeShade *bs)
v++;
BLI_unlock_thread(LOCK_CUSTOM1);
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+
return 1;
}
}
@@ -2571,8 +2579,10 @@ static void shade_tface(BakeShade *bs)
/* check valid zspan */
if (ima!=bs->ima) {
+ BKE_image_release_ibuf(bs->ima, bs->ibuf, NULL);
+
bs->ima= ima;
- bs->ibuf= BKE_image_get_ibuf(ima, NULL);
+ bs->ibuf= BKE_image_acquire_ibuf(ima, NULL, NULL);
/* note, these calls only free/fill contents of zspan struct, not zspan itself */
zbuf_free_span(bs->zspan);
zbuf_alloc_span(bs->zspan, bs->ibuf->x, bs->ibuf->y, R.clipcrop);
@@ -2638,7 +2648,9 @@ static void *do_bake_thread(void *bs_v)
*bs->do_update= TRUE;
}
bs->ready= 1;
-
+
+ BKE_image_release_ibuf(bs->ima, bs->ibuf, NULL);
+
return NULL;
}
@@ -2689,12 +2701,13 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_up
/* baker uses this flag to detect if image was initialized */
for (ima= G.main->image.first; ima; ima= ima->id.next) {
- ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
+ ImBuf *ibuf= BKE_image_acquire_ibuf(ima, NULL, NULL);
ima->id.flag |= LIB_DOIT;
ima->flag&= ~IMA_USED_FOR_RENDER;
if (ibuf) {
ibuf->userdata = NULL; /* use for masking if needed */
}
+ BKE_image_release_ibuf(ima, ibuf, NULL);
}
BLI_init_threads(&threads, do_bake_thread, re->r.threads);
@@ -2747,7 +2760,7 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_up
/* filter and refresh images */
for (ima= G.main->image.first; ima; ima= ima->id.next) {
if ((ima->id.flag & LIB_DOIT)==0) {
- ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
+ ImBuf *ibuf= BKE_image_acquire_ibuf(ima, NULL, NULL);
if (ima->flag & IMA_USED_FOR_RENDER)
result= BAKE_RESULT_FEEDBACK_LOOP;
@@ -2758,6 +2771,7 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_up
RE_bake_ibuf_filter(ibuf, (char *)ibuf->userdata, re->r.bake_filter);
ibuf->userflags |= IB_BITMAPDIRTY;
+ BKE_image_release_ibuf(ima, ibuf, NULL);
}
}
diff --git a/source/blender/render/intern/source/renderdatabase.c b/source/blender/render/intern/source/renderdatabase.c
index 7a7602dcce2..44daaf516e1 100644
--- a/source/blender/render/intern/source/renderdatabase.c
+++ b/source/blender/render/intern/source/renderdatabase.c
@@ -1179,30 +1179,36 @@ HaloRen *RE_inithalo_particle(Render *re, ObjectRen *obr, DerivedMesh *dm, Mater
/* -------------------------- operations on entire database ----------------------- */
/* ugly function for halos in panorama */
-static int panotestclip(Render *re, int do_pano, float *v)
+static int panotestclip(Render *re, int do_pano, float v[4])
{
- /* to be used for halos en infos */
- float abs4;
- short c=0;
- int xparts = (re->rectx + re->partx - 1) / re->partx;
+ /* part size (ensure we run RE_parts_clamp first) */
+ BLI_assert(re->partx == min_ii(re->r.tilex, re->rectx));
+ BLI_assert(re->party == min_ii(re->r.tiley, re->recty));
if (do_pano == FALSE) {
return testclip(v);
}
+ else {
+ /* to be used for halos en infos */
+ float abs4;
+ short c = 0;
+
+ int xparts = (re->rectx + re->partx - 1) / re->partx;
- abs4= fabs(v[3]);
+ abs4= fabsf(v[3]);
- if (v[2]< -abs4) c=16; /* this used to be " if (v[2]<0) ", see clippz() */
- else if (v[2]> abs4) c+= 32;
+ if (v[2]< -abs4) c=16; /* this used to be " if (v[2]<0) ", see clippz() */
+ else if (v[2]> abs4) c+= 32;
- if ( v[1]>abs4) c+=4;
- else if ( v[1]< -abs4) c+=8;
+ if ( v[1]>abs4) c+=4;
+ else if ( v[1]< -abs4) c+=8;
- abs4*= xparts;
- if ( v[0]>abs4) c+=2;
- else if ( v[0]< -abs4) c+=1;
+ abs4*= xparts;
+ if ( v[0]>abs4) c+=2;
+ else if ( v[0]< -abs4) c+=1;
- return c;
+ return c;
+ }
}
/**
diff --git a/source/blender/render/intern/source/shadeoutput.c b/source/blender/render/intern/source/shadeoutput.c
index 77602edf955..597196f464b 100644
--- a/source/blender/render/intern/source/shadeoutput.c
+++ b/source/blender/render/intern/source/shadeoutput.c
@@ -58,7 +58,9 @@
#include "shading.h" /* own include */
/* could enable at some point but for now there are far too many conversions */
-#pragma GCC diagnostic ignored "-Wdouble-promotion"
+#ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wdouble-promotion"
+#endif
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
diff --git a/source/blender/render/intern/source/sunsky.c b/source/blender/render/intern/source/sunsky.c
index e4a42fcd675..e812b99287c 100644
--- a/source/blender/render/intern/source/sunsky.c
+++ b/source/blender/render/intern/source/sunsky.c
@@ -118,8 +118,8 @@ static void DirectionToThetaPhi(float *toSun, float *theta, float *phi)
/**
* PerezFunction:
- * compute perez function value based on input paramters
- * */
+ * compute perez function value based on input parameters
+ */
static float PerezFunction(struct SunSky *sunsky, const float *lam, float theta, float gamma, float lvz)
{
float den, num;
diff --git a/source/blender/render/intern/source/voxeldata.c b/source/blender/render/intern/source/voxeldata.c
index 42849a01971..77d6644479a 100644
--- a/source/blender/render/intern/source/voxeldata.c
+++ b/source/blender/render/intern/source/voxeldata.c
@@ -157,10 +157,10 @@ static void load_frame_image_sequence(VoxelData *vd, Tex *tex)
/* find the first valid ibuf and use it to initialize the resolution of the data set */
/* need to do this in advance so we know how much memory to allocate */
- ibuf = BKE_image_get_ibuf(ima, &iuser);
+ ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL);
while (!ibuf && (iuser.framenr < iuser.frames)) {
iuser.framenr++;
- ibuf = BKE_image_get_ibuf(ima, &iuser);
+ ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL);
}
if (!ibuf) return;
if (!ibuf->rect_float) IMB_float_from_rect(ibuf);
@@ -175,7 +175,8 @@ static void load_frame_image_sequence(VoxelData *vd, Tex *tex)
/* get a new ibuf for each frame */
if (z > 0) {
iuser.framenr++;
- ibuf = BKE_image_get_ibuf(ima, &iuser);
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL);
if (!ibuf) break;
if (!ibuf->rect_float) IMB_float_from_rect(ibuf);
}
@@ -191,7 +192,9 @@ static void load_frame_image_sequence(VoxelData *vd, Tex *tex)
BKE_image_free_anim_ibufs(ima, iuser.framenr);
}
-
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+
vd->ok = 1;
return;
}
diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c
index 62bf9ac2005..c52fb84a7f8 100644
--- a/source/blender/render/intern/source/zbuf.c
+++ b/source/blender/render/intern/source/zbuf.c
@@ -77,7 +77,9 @@
#include "zbuf.h"
/* could enable at some point but for now there are far too many conversions */
-#pragma GCC diagnostic ignored "-Wdouble-promotion"
+#ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wdouble-promotion"
+#endif
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 9a3b8513810..ecb70a5740e 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -181,6 +181,7 @@ int WM_operator_filesel_ensure_ext_imtype(wmOperator *op, const char imt
/* poll callback, context checks */
int WM_operator_winactive (struct bContext *C);
/* invoke callback, exec + redo popup */
+int WM_operator_props_popup_call(struct bContext *C, struct wmOperator *op, struct wmEvent *event);
int WM_operator_props_popup (struct bContext *C, struct wmOperator *op, struct wmEvent *event);
int WM_operator_props_dialog_popup (struct bContext *C, struct wmOperator *op, int width, int height);
int WM_operator_redo_popup (struct bContext *C, struct wmOperator *op);
diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c
index ad19df3aaf6..97808d75dbe 100644
--- a/source/blender/windowmanager/intern/wm_draw.c
+++ b/source/blender/windowmanager/intern/wm_draw.c
@@ -718,14 +718,14 @@ static int wm_automatic_draw_method(wmWindow *win)
if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_UNIX, GPU_DRIVER_OPENSOURCE))
return USER_DRAW_OVERLAP;
/* also Intel drivers are slow */
- /* 2.64 BCon3 period, let's try if intel now works...
+#if 0 /* 2.64 BCon3 period, let's try if intel now works... */
else if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_UNIX, GPU_DRIVER_ANY))
return USER_DRAW_OVERLAP;
else if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_WIN, GPU_DRIVER_ANY))
return USER_DRAW_OVERLAP_FLIP;
else if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_MAC, GPU_DRIVER_ANY))
return USER_DRAW_OVERLAP_FLIP;
- */
+#endif
/* Windows software driver darkens color on each redraw */
else if (GPU_type_matches(GPU_DEVICE_SOFTWARE, GPU_OS_WIN, GPU_DRIVER_SOFTWARE))
return USER_DRAW_OVERLAP_FLIP;
@@ -760,6 +760,15 @@ void wm_draw_update(bContext *C)
GPU_free_unused_buffers();
for (win = wm->windows.first; win; win = win->next) {
+ int state = GHOST_GetWindowState(win->ghostwin);;
+
+ if (state == GHOST_kWindowStateMinimized) {
+ /* do not update minimized windows, it gives issues on intel drivers (see [#33223])
+ * anyway, it seems logical to skip update for invisile windows
+ */
+ continue;
+ }
+
if (win->drawmethod != U.wmdrawmethod) {
wm_draw_window_clear(win);
win->drawmethod = U.wmdrawmethod;
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 551f9157dfe..4066c8d7f5a 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -341,7 +341,7 @@ static int wm_handler_ui_call(bContext *C, wmEventHandler *handler, wmEvent *eve
int retval;
/* UI code doesn't handle return values - it just always returns break.
- to make the DBL_CLICK conversion work, we just don't send this to UI */
+ * to make the DBL_CLICK conversion work, we just don't send this to UI */
if (event->val == KM_DBL_CLICK)
return WM_HANDLER_CONTINUE;
@@ -1280,74 +1280,6 @@ int WM_userdef_event_map(int kmitype)
return kmitype;
}
-static void wm_eventemulation(wmEvent *event)
-{
- /* Store last mmb event value to make emulation work when modifier keys are released first. */
- static int mmb_emulated = 0; /* this should be in a data structure somwhere */
-
- /* middlemouse emulation */
- if (U.flag & USER_TWOBUTTONMOUSE) {
- if (event->type == LEFTMOUSE) {
-
- if (event->val == KM_PRESS && event->alt) {
- event->type = MIDDLEMOUSE;
- event->alt = 0;
- mmb_emulated = 1;
- }
- else if (event->val == KM_RELEASE) {
- /* only send middle-mouse release if emulated */
- if (mmb_emulated) {
- event->type = MIDDLEMOUSE;
- event->alt = 0;
- }
- mmb_emulated = 0;
- }
- }
-
- }
-
-#ifdef __APPLE__
-
- /* rightmouse emulation */
- if (U.flag & USER_TWOBUTTONMOUSE) {
- if (event->type == LEFTMOUSE) {
-
- if (event->val == KM_PRESS && event->oskey) {
- event->type = RIGHTMOUSE;
- event->oskey = 0;
- mmb_emulated = 1;
- }
- else if (event->val == KM_RELEASE) {
- if (mmb_emulated) {
- event->oskey = RIGHTMOUSE;
- event->alt = 0;
- }
- mmb_emulated = 0;
- }
- }
-
- }
-#endif
-
- /* numpad emulation */
- if (U.flag & USER_NONUMPAD) {
- switch (event->type) {
- case ZEROKEY: event->type = PAD0; break;
- case ONEKEY: event->type = PAD1; break;
- case TWOKEY: event->type = PAD2; break;
- case THREEKEY: event->type = PAD3; break;
- case FOURKEY: event->type = PAD4; break;
- case FIVEKEY: event->type = PAD5; break;
- case SIXKEY: event->type = PAD6; break;
- case SEVENKEY: event->type = PAD7; break;
- case EIGHTKEY: event->type = PAD8; break;
- case NINEKEY: event->type = PAD9; break;
- case MINUSKEY: event->type = PADMINUS; break;
- case EQUALKEY: event->type = PADPLUSKEY; break;
- case BACKSLASHKEY: event->type = PADSLASHKEY; break;
- }
- }
-}
static int wm_eventmatch(wmEvent *winevent, wmKeyMapItem *kmi)
{
@@ -1357,9 +1289,9 @@ static int wm_eventmatch(wmEvent *winevent, wmKeyMapItem *kmi)
/* the matching rules */
if (kmitype == KM_TEXTINPUT)
- if (winevent->val == KM_PRESS) { // prevent double clicks
+ if (winevent->val == KM_PRESS) { /* prevent double clicks */
/* NOT using ISTEXTINPUT anymore because (at least on Windows) some key codes above 255
- could have printable ascii keys - BUG [#30479] */
+ * could have printable ascii keys - BUG [#30479] */
if (ISKEYBOARD(winevent->type) && (winevent->ascii || winevent->utf8_buf[0])) return 1;
}
@@ -1379,7 +1311,8 @@ static int wm_eventmatch(wmEvent *winevent, wmKeyMapItem *kmi)
if (kmi->oskey != KM_ANY)
if (winevent->oskey != kmi->oskey && !(winevent->oskey & kmi->oskey)) return 0;
- if (winevent->keymodifier != kmi->keymodifier) return 0;
+ if (kmi->keymodifier)
+ if (winevent->keymodifier != kmi->keymodifier) return 0;
return 1;
@@ -1619,8 +1552,8 @@ static int wm_handler_fileselect_call(bContext *C, ListBase *handlers, wmEventHa
if (handler->op->reports->list.first) {
/* FIXME, temp setting window, this is really bad!
- * only have because lib linking errors need to be seen by users :(
- * it can be removed without breaking anything but then no linking errors - campbell */
+ * only have because lib linking errors need to be seen by users :(
+ * it can be removed without breaking anything but then no linking errors - campbell */
wmWindow *win_prev = CTX_wm_window(C);
ScrArea *area_prev = CTX_wm_area(C);
ARegion *ar_prev = CTX_wm_region(C);
@@ -2114,8 +2047,6 @@ void wm_event_do_handlers(bContext *C)
}
#endif
- wm_eventemulation(event);
-
CTX_wm_window_set(C, win);
/* we let modal handlers get active area/region, also wm_paintcursor_test needs it */
@@ -2617,6 +2548,75 @@ static int convert_key(GHOST_TKey key)
}
}
+static void wm_eventemulation(wmEvent *event)
+{
+ /* Store last mmb event value to make emulation work when modifier keys are released first. */
+ static int mmb_emulated = 0; /* this should be in a data structure somwhere */
+
+ /* middlemouse emulation */
+ if (U.flag & USER_TWOBUTTONMOUSE) {
+ if (event->type == LEFTMOUSE) {
+
+ if (event->val == KM_PRESS && event->alt) {
+ event->type = MIDDLEMOUSE;
+ event->alt = 0;
+ mmb_emulated = 1;
+ }
+ else if (event->val == KM_RELEASE) {
+ /* only send middle-mouse release if emulated */
+ if (mmb_emulated) {
+ event->type = MIDDLEMOUSE;
+ event->alt = 0;
+ }
+ mmb_emulated = 0;
+ }
+ }
+
+ }
+
+#ifdef __APPLE__
+
+ /* rightmouse emulation */
+ if (U.flag & USER_TWOBUTTONMOUSE) {
+ if (event->type == LEFTMOUSE) {
+
+ if (event->val == KM_PRESS && event->oskey) {
+ event->type = RIGHTMOUSE;
+ event->oskey = 0;
+ mmb_emulated = 1;
+ }
+ else if (event->val == KM_RELEASE) {
+ if (mmb_emulated) {
+ event->oskey = RIGHTMOUSE;
+ event->alt = 0;
+ }
+ mmb_emulated = 0;
+ }
+ }
+
+ }
+#endif
+
+ /* numpad emulation */
+ if (U.flag & USER_NONUMPAD) {
+ switch (event->type) {
+ case ZEROKEY: event->type = PAD0; break;
+ case ONEKEY: event->type = PAD1; break;
+ case TWOKEY: event->type = PAD2; break;
+ case THREEKEY: event->type = PAD3; break;
+ case FOURKEY: event->type = PAD4; break;
+ case FIVEKEY: event->type = PAD5; break;
+ case SIXKEY: event->type = PAD6; break;
+ case SEVENKEY: event->type = PAD7; break;
+ case EIGHTKEY: event->type = PAD8; break;
+ case NINEKEY: event->type = PAD9; break;
+ case MINUSKEY: event->type = PADMINUS; break;
+ case EQUALKEY: event->type = PADPLUSKEY; break;
+ case BACKSLASHKEY: event->type = PADSLASHKEY; break;
+ }
+ }
+}
+
/* adds customdata to event */
static void update_tablet_data(wmWindow *win, wmEvent *event)
{
@@ -2826,6 +2826,8 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U
else
event.type = MIDDLEMOUSE;
+ wm_eventemulation(&event);
+
/* copy previous state to prev event state (two old!) */
evt->prevval = evt->val;
evt->prevtype = evt->type;
@@ -2891,6 +2893,8 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U
memcpy(event.utf8_buf, kd->utf8_buf, sizeof(event.utf8_buf)); /* might be not null terminated*/
event.val = (type == GHOST_kEventKeyDown) ? KM_PRESS : KM_RELEASE;
+ wm_eventemulation(&event);
+
/* copy previous state to prev event state (two old!) */
evt->prevval = evt->val;
evt->prevtype = evt->type;
diff --git a/source/blender/windowmanager/intern/wm_jobs.c b/source/blender/windowmanager/intern/wm_jobs.c
index f5c83d48cb9..7481c01d72b 100644
--- a/source/blender/windowmanager/intern/wm_jobs.c
+++ b/source/blender/windowmanager/intern/wm_jobs.c
@@ -405,9 +405,11 @@ void WM_jobs_kill_all(wmWindowManager *wm)
/* wait until every job ended, except for one owner (used in undo to keep screen job alive) */
void WM_jobs_kill_all_except(wmWindowManager *wm, void *owner)
{
- wmJob *wm_job;
+ wmJob *wm_job, *next_job;
- for (wm_job = wm->jobs.first; wm_job; wm_job = wm_job->next) {
+ for (wm_job = wm->jobs.first; wm_job; wm_job = next_job) {
+ next_job = wm_job->next;
+
if (wm_job->owner != owner)
wm_jobs_kill_job(wm, wm_job);
}
diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c
index 7aa2b403897..4fe1e3b64ab 100644
--- a/source/blender/windowmanager/intern/wm_keymap.c
+++ b/source/blender/windowmanager/intern/wm_keymap.c
@@ -101,11 +101,8 @@ static int wm_keymap_item_equals_result(wmKeyMapItem *a, wmKeyMapItem *b)
if (strcmp(a->idname, b->idname) != 0)
return 0;
- if (!((a->ptr == NULL && b->ptr == NULL) ||
- (a->ptr && b->ptr && IDP_EqualsProperties(a->ptr->data, b->ptr->data))))
- {
+ if (!RNA_struct_equals(a->ptr, b->ptr))
return 0;
- }
if ((a->flag & KMI_INACTIVE) != (b->flag & KMI_INACTIVE))
return 0;
@@ -545,7 +542,7 @@ static wmKeyMap *wm_keymap_patch_update(ListBase *lb, wmKeyMap *defaultmap, wmKe
/* copy new keymap from an existing one */
if (usermap && !(usermap->flag & KEYMAP_DIFF)) {
- /* for compatibiltiy with old user preferences with non-diff
+ /* for compatibility with old user preferences with non-diff
* keymaps we override the original entirely */
wmKeyMapItem *kmi, *orig_kmi;
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 962eb55996d..69b2d5326a4 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -625,7 +625,7 @@ void WM_operator_properties_sanitize(PointerRNA *ptr, const short no_context)
/** set all props to their default,
* \param do_update Only update un-initialized props.
*
- * \note, theres nothing spesific to operators here.
+ * \note, theres nothing specific to operators here.
* this could be made a general function.
*/
int WM_operator_properties_default(PointerRNA *ptr, const int do_update)
@@ -1187,6 +1187,8 @@ static void wm_operator_ui_popup_ok(struct bContext *C, void *arg, int retval)
if (op && retval > 0)
WM_operator_call(C, op);
+
+ MEM_freeN(data);
}
int WM_operator_ui_popup(bContext *C, wmOperator *op, int width, int height)
@@ -1200,8 +1202,11 @@ int WM_operator_ui_popup(bContext *C, wmOperator *op, int width, int height)
return OPERATOR_RUNNING_MODAL;
}
-/* operator menu needs undo, for redo callback */
-int WM_operator_props_popup(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+/**
+ * For use by #WM_operator_props_popup_call, #WM_operator_props_popup only.
+ *
+ * \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) {
@@ -1209,15 +1214,34 @@ int WM_operator_props_popup(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
"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);
uiPupBlock(C, wm_block_create_redo, op);
+ if (do_call) {
+ WM_operator_repeat(C, op);
+ }
+
return OPERATOR_RUNNING_MODAL;
}
+/* Same as WM_operator_props_popup but call the operator first,
+ * This way - the button values correspond to the result of the operator.
+ * Without this, first access to a button will make the result jump,
+ * see [#32452] */
+int WM_operator_props_popup_call(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+{
+ return wm_operator_props_popup_ex(C, op, TRUE);
+}
+
+int WM_operator_props_popup(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+{
+ return wm_operator_props_popup_ex(C, op, FALSE);
+}
+
int WM_operator_props_dialog_popup(bContext *C, wmOperator *op, int width, int height)
{
wmOpPopUp *data = MEM_callocN(sizeof(wmOpPopUp), "WM_operator_props_dialog_popup");
@@ -1281,6 +1305,31 @@ static void WM_OT_debug_menu(wmOperatorType *ot)
RNA_def_int(ot->srna, "debug_value", 0, SHRT_MIN, SHRT_MAX, "Debug Value", "", -10000, 10000);
}
+/* ***************** Operator defaults ************************* */
+static int wm_operator_defaults_exec(bContext *C, wmOperator *op)
+{
+ PointerRNA ptr = CTX_data_pointer_get_type(C, "active_operator", &RNA_Operator);
+
+ if (!ptr.data) {
+ BKE_report(op->reports, RPT_ERROR, "No operator in context");
+ return OPERATOR_CANCELLED;
+ }
+
+ WM_operator_properties_reset((wmOperator *)ptr.data);
+ return OPERATOR_FINISHED;
+}
+
+/* used by operator preset menu. pre-2.65 this was a 'Reset' button */
+static void WM_OT_operator_defaults(wmOperatorType *ot)
+{
+ ot->name = "Restore Defaults";
+ ot->idname = "WM_OT_operator_defaults";
+ ot->description = "Set the active operator to its default values";
+
+ ot->exec = wm_operator_defaults_exec;
+
+ ot->flag = OPTYPE_INTERNAL;
+}
/* ***************** Splash Screen ************************* */
@@ -1402,7 +1451,7 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar
uiItemL(col, "Links", ICON_NONE);
uiItemStringO(col, IFACE_("Donations"), ICON_URL, "WM_OT_url_open", "url", "http://www.blender.org/blenderorg/blender-foundation/donation-payment");
uiItemStringO(col, IFACE_("Credits"), ICON_URL, "WM_OT_url_open", "url", "http://www.blender.org/development/credits");
- uiItemStringO(col, IFACE_("Release Log"), ICON_URL, "WM_OT_url_open", "url", "http://www.blender.org/development/release-logs/blender-264");
+ uiItemStringO(col, IFACE_("Release Log"), ICON_URL, "WM_OT_url_open", "url", "http://www.blender.org/development/release-logs/blender-265");
uiItemStringO(col, IFACE_("Manual"), ICON_URL, "WM_OT_url_open", "url", "http://wiki.blender.org/index.php/Doc:2.6/Manual");
uiItemStringO(col, IFACE_("Blender Website"), ICON_URL, "WM_OT_url_open", "url", "http://www.blender.org");
uiItemStringO(col, IFACE_("User Community"), ICON_URL, "WM_OT_url_open", "url", "http://www.blender.org/community/user-community");
@@ -3766,6 +3815,7 @@ void wm_operatortype_init(void)
WM_operatortype_append(WM_OT_memory_statistics);
WM_operatortype_append(WM_OT_dependency_relations);
WM_operatortype_append(WM_OT_debug_menu);
+ WM_operatortype_append(WM_OT_operator_defaults);
WM_operatortype_append(WM_OT_splash);
WM_operatortype_append(WM_OT_search_menu);
WM_operatortype_append(WM_OT_call_menu);
diff --git a/source/blender/windowmanager/intern/wm_playanim.c b/source/blender/windowmanager/intern/wm_playanim.c
index b323f9d70a8..41f6a7e5ab0 100644
--- a/source/blender/windowmanager/intern/wm_playanim.c
+++ b/source/blender/windowmanager/intern/wm_playanim.c
@@ -61,6 +61,7 @@
#include "BKE_blender.h"
#include "BKE_global.h"
+#include "BKE_image.h"
#include "GPU_colors.h"
#include "GPU_compatibility.h"
@@ -76,6 +77,9 @@
#include "WM_api.h" /* only for WM_main_playanim */
+struct PlayState;
+static void playanim_window_zoom(const struct PlayState *ps, const float zoom_offset);
+
typedef struct PlayState {
/* playback state */
@@ -86,7 +90,6 @@ typedef struct PlayState {
short pingpong;
short noskip;
short sstep;
- short pause;
short wait2;
short stopped;
short go;
@@ -134,6 +137,7 @@ typedef enum eWS_Qual {
WS_QUAL_ALT = (WS_QUAL_LALT | WS_QUAL_RALT),
WS_QUAL_LCTRL = (1 << 4),
WS_QUAL_RCTRL = (1 << 5),
+ WS_QUAL_CTRL = (WS_QUAL_LCTRL | WS_QUAL_RCTRL),
WS_QUAL_LMOUSE = (1 << 16),
WS_QUAL_MMOUSE = (1 << 17),
WS_QUAL_RMOUSE = (1 << 18),
@@ -181,27 +185,12 @@ static void playanim_event_qual_update(void)
/* Alt */
GHOST_GetModifierKeyState(g_WS.ghost_system, GHOST_kModifierKeyLeftAlt, &val);
- if (val) g_WS.qual |= WS_QUAL_LCTRL;
- else g_WS.qual &= ~WS_QUAL_LCTRL;
+ if (val) g_WS.qual |= WS_QUAL_LALT;
+ else g_WS.qual &= ~WS_QUAL_LALT;
GHOST_GetModifierKeyState(g_WS.ghost_system, GHOST_kModifierKeyRightAlt, &val);
- if (val) g_WS.qual |= WS_QUAL_RCTRL;
- else g_WS.qual &= ~WS_QUAL_RCTRL;
-
- /* LMB */
- GHOST_GetButtonState(g_WS.ghost_system, GHOST_kButtonMaskLeft, &val);
- if (val) g_WS.qual |= WS_QUAL_LMOUSE;
- else g_WS.qual &= ~WS_QUAL_LMOUSE;
-
- /* MMB */
- GHOST_GetButtonState(g_WS.ghost_system, GHOST_kButtonMaskMiddle, &val);
- if (val) g_WS.qual |= WS_QUAL_MMOUSE;
- else g_WS.qual &= ~WS_QUAL_MMOUSE;
-
- /* RMB */
- GHOST_GetButtonState(g_WS.ghost_system, GHOST_kButtonMaskRight, &val);
- if (val) g_WS.qual |= WS_QUAL_RMOUSE;
- else g_WS.qual &= ~WS_QUAL_RMOUSE;
+ if (val) g_WS.qual |= WS_QUAL_RALT;
+ else g_WS.qual &= ~WS_QUAL_RALT;
}
typedef struct PlayAnimPict {
@@ -236,7 +225,7 @@ static void playanim_toscreen(PlayAnimPict *picture, struct ImBuf *ibuf, int fon
{
if (ibuf == NULL) {
- printf("no ibuf !\n");
+ printf("%s: no ibuf for picture '%s'\n", __func__, picture ? picture->name : "<NIL>");
return;
}
if (ibuf->rect == NULL && ibuf->rect_float) {
@@ -434,6 +423,11 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void)
ps->stopped = FALSE;
}
+ if (ps->wait2) {
+ pupdate_time();
+ ptottime = 0;
+ }
+
switch (type) {
case GHOST_kEventKeyDown:
case GHOST_kEventKeyUp:
@@ -448,33 +442,42 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void)
case GHOST_kKeyP:
if (val) ps->pingpong = !ps->pingpong;
break;
+ case GHOST_kKey1:
case GHOST_kKeyNumpad1:
if (val) swaptime = ps->fstep / 60.0;
break;
+ case GHOST_kKey2:
case GHOST_kKeyNumpad2:
if (val) swaptime = ps->fstep / 50.0;
break;
+ case GHOST_kKey3:
case GHOST_kKeyNumpad3:
if (val) swaptime = ps->fstep / 30.0;
break;
+ case GHOST_kKey4:
case GHOST_kKeyNumpad4:
if (g_WS.qual & WS_QUAL_SHIFT)
swaptime = ps->fstep / 24.0;
else
swaptime = ps->fstep / 25.0;
break;
+ case GHOST_kKey5:
case GHOST_kKeyNumpad5:
if (val) swaptime = ps->fstep / 20.0;
break;
+ case GHOST_kKey6:
case GHOST_kKeyNumpad6:
if (val) swaptime = ps->fstep / 15.0;
break;
+ case GHOST_kKey7:
case GHOST_kKeyNumpad7:
if (val) swaptime = ps->fstep / 12.0;
break;
+ case GHOST_kKey8:
case GHOST_kKeyNumpad8:
if (val) swaptime = ps->fstep / 10.0;
break;
+ case GHOST_kKey9:
case GHOST_kKeyNumpad9:
if (val) swaptime = ps->fstep / 6.0;
break;
@@ -541,28 +544,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void)
}
}
break;
- case GHOST_kKeyEqual:
- if (val) {
- if (g_WS.qual & WS_QUAL_SHIFT) {
- ps->pause++;
- printf("pause:%d\n", ps->pause);
- }
- else {
- swaptime /= 1.1;
- }
- }
- break;
- case GHOST_kKeyMinus:
- if (val) {
- if (g_WS.qual & WS_QUAL_SHIFT) {
- ps->pause--;
- printf("pause:%d\n", ps->pause);
- }
- else {
- swaptime *= 1.1;
- }
- }
- break;
+ case GHOST_kKey0:
case GHOST_kKeyNumpad0:
if (val) {
if (ps->once) {
@@ -581,6 +563,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void)
ps->wait2 = ps->sstep = FALSE;
}
break;
+ case GHOST_kKeyPeriod:
case GHOST_kKeyNumpadPeriod:
if (val) {
if (ps->sstep) ps->wait2 = FALSE;
@@ -590,29 +573,28 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void)
}
}
break;
+ case GHOST_kKeyEqual:
case GHOST_kKeyNumpadPlus:
+ {
if (val == 0) break;
- zoomx += 2.0f;
- zoomy += 2.0f;
- /* no break??? - is this intentional? - campbell XXX25 */
+ if (g_WS.qual & WS_QUAL_CTRL) {
+ playanim_window_zoom(ps, 1.0f);
+ }
+ else {
+ swaptime /= 1.1;
+ }
+ break;
+ }
+ case GHOST_kKeyMinus:
case GHOST_kKeyNumpadMinus:
{
- int sizex, sizey;
- /* int ofsx, ofsy; */ /* UNUSED */
-
if (val == 0) break;
- if (zoomx > 1.0f) zoomx -= 1.0f;
- if (zoomy > 1.0f) zoomy -= 1.0f;
- // playanim_window_get_position(&ofsx, &ofsy);
- playanim_window_get_size(&sizex, &sizey);
- /* ofsx += sizex / 2; */ /* UNUSED */
- /* ofsy += sizey / 2; */ /* UNUSED */
- sizex = zoomx * ps->ibufx;
- sizey = zoomy * ps->ibufy;
- /* ofsx -= sizex / 2; */ /* UNUSED */
- /* ofsy -= sizey / 2; */ /* UNUSED */
- // window_set_position(g_WS.ghost_window,sizex,sizey);
- GHOST_SetClientSize(g_WS.ghost_window, sizex, sizey);
+ if (g_WS.qual & WS_QUAL_CTRL) {
+ playanim_window_zoom(ps, -1.0f);
+ }
+ else {
+ swaptime *= 1.1;
+ }
break;
}
case GHOST_kKeyEsc:
@@ -623,6 +605,44 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void)
}
break;
}
+ case GHOST_kEventButtonDown:
+ case GHOST_kEventButtonUp:
+ {
+ GHOST_TEventButtonData *bd = GHOST_GetEventData(evt);
+ int cx, cy, sizex, sizey, inside_window;
+
+ GHOST_GetCursorPosition(g_WS.ghost_system, &cx, &cy);
+ GHOST_ScreenToClient(g_WS.ghost_window, cx, cy, &cx, &cy);
+ playanim_window_get_size(&sizex, &sizey);
+
+ inside_window = (cx >= 0 && cx < sizex && cy >= 0 && cy <= sizey);
+
+ if (bd->button == GHOST_kButtonMaskLeft) {
+ if (type == GHOST_kEventButtonDown) {
+ if (inside_window)
+ g_WS.qual |= WS_QUAL_LMOUSE;
+ }
+ else
+ g_WS.qual &= ~WS_QUAL_LMOUSE;
+ }
+ else if (bd->button == GHOST_kButtonMaskMiddle) {
+ if (type == GHOST_kEventButtonDown) {
+ if (inside_window)
+ g_WS.qual |= WS_QUAL_MMOUSE;
+ }
+ else
+ g_WS.qual &= ~WS_QUAL_MMOUSE;
+ }
+ else if (bd->button == GHOST_kButtonMaskRight) {
+ if (type == GHOST_kEventButtonDown) {
+ if (inside_window)
+ g_WS.qual |= WS_QUAL_RMOUSE;
+ }
+ else
+ g_WS.qual &= ~WS_QUAL_RMOUSE;
+ }
+ break;
+ }
case GHOST_kEventCursorMove:
{
if (g_WS.qual & WS_QUAL_LMOUSE) {
@@ -654,6 +674,11 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void)
}
break;
}
+ case GHOST_kEventWindowActivate:
+ case GHOST_kEventWindowDeactivate: {
+ g_WS.qual &= ~WS_QUAL_MOUSE;
+ break;
+ }
case GHOST_kEventWindowSize:
case GHOST_kEventWindowMove:
{
@@ -718,6 +743,25 @@ static void playanim_window_open(const char *title, int posx, int posy, int size
FALSE /* no stereo */, FALSE);
}
+static void playanim_window_zoom(const PlayState *ps, const float zoom_offset)
+{
+ int sizex, sizey;
+ /* int ofsx, ofsy; */ /* UNUSED */
+
+ if (zoomx + zoom_offset > 0.0f) zoomx += zoom_offset;
+ if (zoomy + zoom_offset > 0.0f) zoomy += zoom_offset;
+
+ // playanim_window_get_position(&ofsx, &ofsy);
+ playanim_window_get_size(&sizex, &sizey);
+ /* ofsx += sizex / 2; */ /* UNUSED */
+ /* ofsy += sizey / 2; */ /* UNUSED */
+ sizex = zoomx * ps->ibufx;
+ sizey = zoomy * ps->ibufy;
+ /* ofsx -= sizex / 2; */ /* UNUSED */
+ /* ofsy -= sizey / 2; */ /* UNUSED */
+ // window_set_position(g_WS.ghost_window,sizex,sizey);
+ GHOST_SetClientSize(g_WS.ghost_window, sizex, sizey);
+}
void WM_main_playanim(int argc, const char **argv)
{
@@ -738,13 +782,12 @@ void WM_main_playanim(int argc, const char **argv)
/* ps.doubleb = TRUE;*/ /* UNUSED */
ps.go = TRUE;
ps.direction = TRUE;
- ps.next = TRUE;
+ ps.next = 1;
ps.once = FALSE;
ps.turbo = FALSE;
ps.pingpong = FALSE;
ps.noskip = FALSE;
ps.sstep = FALSE;
- ps.pause = FALSE;
ps.wait2 = FALSE;
ps.stopped = FALSE;
ps.picture = NULL;
@@ -941,6 +984,7 @@ void WM_main_playanim(int argc, const char **argv)
if (ptottime > 0.0) ptottime = 0.0;
while (ps.picture) {
+ int hasevent;
#ifndef USE_IMB_CACHE
if (ibuf != NULL && ibuf->ftype == 0) IMB_freeImBuf(ibuf);
#endif
@@ -994,19 +1038,22 @@ void WM_main_playanim(int argc, const char **argv)
ps.next = ps.direction;
- {
- int hasevent = GHOST_ProcessEvents(g_WS.ghost_system, 0);
+ while ((hasevent = GHOST_ProcessEvents(g_WS.ghost_system, 0) || ps.wait2 != 0)) {
if (hasevent) {
GHOST_DispatchEvents(g_WS.ghost_system);
}
- }
-
- /* XXX25 - we should not have to do this, but it makes scrubbing functional! */
- if (g_WS.qual & WS_QUAL_LMOUSE) {
- ps.next = 0;
- }
- else {
- ps.sstep = 0;
+ if (ps.wait2) {
+ if (hasevent) {
+ if (ibuf) {
+ while (pupdate_time()) PIL_sleep_ms(1);
+ ptottime -= swaptime;
+ playanim_toscreen(ps.picture, ibuf, ps.fontid, ps.fstep);
+ }
+ }
+ }
+ if (!ps.go) {
+ break;
+ }
}
ps.wait2 = ps.sstep;
@@ -1084,6 +1131,7 @@ void WM_main_playanim(int argc, const char **argv)
/* we still miss freeing a lot!,
* but many areas could skip initialization too for anim play */
IMB_exit();
+ BKE_images_exit();
BLF_exit();
#endif
GHOST_DisposeWindow(g_WS.ghost_system, g_WS.ghost_window);
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index 1da6328d7c8..6864624e163 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -333,8 +333,14 @@ void wm_window_title(wmWindowManager *wm, wmWindow *win)
static void wm_window_add_ghostwindow(const char *title, wmWindow *win)
{
GHOST_WindowHandle ghostwin;
+ static int multisamples = -1;
int scr_w, scr_h, posy;
+ /* force setting multisamples only once, it requires restart - and you cannot
+ * mix it, either all windows have it, or none (tested in OSX opengl) */
+ if (multisamples == -1)
+ multisamples = U.ogl_multisamples;
+
wm_get_screensize(&scr_w, &scr_h);
posy = (scr_h - win->posy - win->sizey);
@@ -345,7 +351,7 @@ static void wm_window_add_ghostwindow(const char *title, wmWindow *win)
(GHOST_TWindowState)win->windowstate,
GHOST_kDrawingContextTypeOpenGL,
0 /* no stereo */,
- U.ogl_multisamples /* AA */);
+ multisamples /* AA */);
if (ghostwin) {
/* needed so we can detect the graphics card below */
@@ -748,6 +754,11 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr
state = GHOST_GetWindowState(win->ghostwin);
win->windowstate = state;
+ /* stop screencast if resize */
+ if (type == GHOST_kEventWindowSize) {
+ WM_jobs_stop(CTX_wm_manager(C), win->screen, NULL);
+ }
+
/* win32: gives undefined window size when minimized */
if (state != GHOST_kWindowStateMinimized) {
GHOST_RectangleHandle client_rect;
diff --git a/source/blender/windowmanager/wm_event_types.h b/source/blender/windowmanager/wm_event_types.h
index 62baa328654..8b52bd6a228 100644
--- a/source/blender/windowmanager/wm_event_types.h
+++ b/source/blender/windowmanager/wm_event_types.h
@@ -287,9 +287,9 @@ enum {
/* for event checks */
/* only used for KM_TEXTINPUT, so assume that we want all user-inputtable ascii codes included */
- /* UNUSED - see wm_eventmatch - BUG [#30479]
-#define ISTEXTINPUT(event) (event >= ' ' && event <= 255)
- */
+ /* UNUSED - see wm_eventmatch - BUG [#30479] */
+// #define ISTEXTINPUT(event) (event >= ' ' && event <= 255)
+
/* test whether the event is a key on the keyboard */
#define ISKEYBOARD(event) (event >= ' ' && event <= 320)
diff --git a/source/blenderplayer/CMakeLists.txt b/source/blenderplayer/CMakeLists.txt
index 3c537c3d64b..90bf913bbf2 100644
--- a/source/blenderplayer/CMakeLists.txt
+++ b/source/blenderplayer/CMakeLists.txt
@@ -60,7 +60,7 @@ elseif(APPLE)
add_executable(blenderplayer ${EXETYPE} bad_level_call_stubs/stubs.c)
# setup Info.plist
execute_process(COMMAND date "+%Y-%m-%d" OUTPUT_VARIABLE BLENDER_DATE OUTPUT_STRIP_TRAILING_WHITESPACE)
- set(PLAYER_SOURCEDIR ${CMAKE_SOURCE_DIR}/source/darwin/blenderplayer.app)
+ set(PLAYER_SOURCEDIR ${CMAKE_SOURCE_DIR}/release/darwin/blenderplayer.app)
set(PLAYER_SOURCEINFO ${PLAYER_SOURCEDIR}/Contents/Info.plist)
set_target_properties(blenderplayer PROPERTIES
MACOSX_BUNDLE_INFO_PLIST ${PLAYER_SOURCEINFO}
@@ -199,6 +199,10 @@ endif()
list(APPEND BLENDER_SORTED_LIBS bf_intern_guardedalloc_cpp)
endif()
+ if(WITH_INTERNATIONAL)
+ list(APPEND BLENDER_SORTED_LIBS bf_intern_locale)
+ endif()
+
foreach(SORTLIB ${BLENDER_SORTED_LIBS})
set(REMLIB ${SORTLIB})
foreach(SEARCHLIB ${BLENDER_LINK_LIBS})
diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt
index 201c89c820d..6ed8bd4a0c8 100644
--- a/source/creator/CMakeLists.txt
+++ b/source/creator/CMakeLists.txt
@@ -471,20 +471,6 @@ elseif(WIN32)
DESTINATION ${TARGETDIR}
)
- if(WITH_INTERNATIONAL AND (NOT WITH_MINGW64))
- install(
- FILES ${LIBDIR}/gettext/lib/gnu_gettext.dll
- DESTINATION ${TARGETDIR}
- )
-
- if(NOT CMAKE_CL_64)
- install(
- FILES ${LIBDIR}/iconv/lib/iconv.dll
- DESTINATION ${TARGETDIR}
- )
- endif()
- endif()
-
if(WITH_PYTHON)
set_lib_path(PYLIB "python")
install(
@@ -532,7 +518,7 @@ elseif(WIN32)
endif()
if(CMAKE_CL_64)
- # gettext and png are statically linked on win64
+ # png is statically linked on win64
install(
FILES ${LIBDIR}/zlib/lib/zlib.dll
DESTINATION ${TARGETDIR}
@@ -634,18 +620,7 @@ elseif(WIN32)
install( # x86 builds can run on x64 Windows, so this is required at all times
FILES ${LIBDIR}/thumbhandler/lib/BlendThumb64.dll
DESTINATION ${TARGETDIR}
- )
-
- if(WITH_OPENIMAGEIO)
- if(NOT MINGW)
- set(OIIOBIN ${LIBDIR}/openimageio)
- install(
- FILES
- ${OIIOBIN}/bin/OpenImageIO.dll
- DESTINATION ${TARGETDIR}
- )
- endif()
- endif()
+ )
if(WITH_OPENCOLORIO)
set(OCIOBIN ${LIBDIR}/opencolorio/bin)
@@ -683,7 +658,7 @@ elseif(APPLE)
)
endmacro()
- set(OSX_APP_SOURCEDIR ${CMAKE_SOURCE_DIR}/source/darwin/blender.app)
+ set(OSX_APP_SOURCEDIR ${CMAKE_SOURCE_DIR}/release/darwin/blender.app)
# setup Info.plist
execute_process(COMMAND date "+%Y-%m-%d" OUTPUT_VARIABLE BLENDER_DATE OUTPUT_STRIP_TRAILING_WHITESPACE)
@@ -742,7 +717,7 @@ elseif(APPLE)
# install blenderplayer bundle - copy of blender.app above. re-using macros et al
# note we are using OSX Bundle as base and copying Blender dummy bundle on top of it
if(WITH_GAMEENGINE AND WITH_PLAYER)
- set(OSX_APP_PLAYER_SOURCEDIR ${CMAKE_SOURCE_DIR}/source/darwin/blenderplayer.app)
+ set(OSX_APP_PLAYER_SOURCEDIR ${CMAKE_SOURCE_DIR}/release/darwin/blenderplayer.app)
set(PLAYER_SOURCEINFO ${OSX_APP_PLAYER_SOURCEDIR}/Contents/Info.plist)
set(PLAYER_TARGETDIR_VER ${TARGETDIR}/blenderplayer.app/Contents/MacOS/${BLENDER_VERSION})
@@ -989,6 +964,10 @@ endif()
list_insert_after(BLENDER_SORTED_LIBS "cycles_kernel" "cycles_kernel_osl")
endif()
+ if(WITH_INTERNATIONAL)
+ list(APPEND BLENDER_SORTED_LIBS bf_intern_locale)
+ endif()
+
foreach(SORTLIB ${BLENDER_SORTED_LIBS})
set(REMLIB ${SORTLIB})
foreach(SEARCHLIB ${BLENDER_LINK_LIBS})
diff --git a/source/creator/blender.map b/source/creator/blender.map
new file mode 100644
index 00000000000..dc7bc3151e8
--- /dev/null
+++ b/source/creator/blender.map
@@ -0,0 +1,11 @@
+
+/* on Linux we exclude LLVM symbols, they conflict with Mesa llvmpipe */
+
+{
+global:
+ *;
+local:
+ *llvm*;
+ *LLVM*;
+};
+
diff --git a/source/creator/creator.c b/source/creator/creator.c
index 86a9e411ef7..37327d95628 100644
--- a/source/creator/creator.c
+++ b/source/creator/creator.c
@@ -1080,7 +1080,9 @@ static void setupArguments(bContext *C, bArgs *ba, SYS_SystemHandle *syshandle)
"\n\t\t-p <sx> <sy>\tOpen with lower left corner at <sx>, <sy>"
"\n\t\t-m\t\tRead from disk (Don't buffer)"
"\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-j <frame>\tSet frame step to <frame>"
+ "\n\t\t-s <frame>\tPlay from <frame>"
+ "\n\t\t-j <frame>\tPlay until <frame>";
static char game_doc[] = "Game Engine specific options"
"\n\t-g fixedtime\t\tRun on 50 hertz without dropping frames"
@@ -1273,6 +1275,7 @@ int main(int argc, const char **argv)
initglobals(); /* blender.c */
IMB_init();
+ BKE_images_init();
#ifdef WITH_FFMPEG
IMB_ffmpeg_init();
diff --git a/source/tests/bl_rst_completeness.py b/source/tests/bl_rst_completeness.py
new file mode 100644
index 00000000000..e9e2779bda8
--- /dev/null
+++ b/source/tests/bl_rst_completeness.py
@@ -0,0 +1,159 @@
+# ##### 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>
+
+# run this script in the game engine.
+# or on the command line with...
+# ./blender.bin --background -noaudio --python source/tests/bl_rst_completeness.py
+
+# Paste this into the bge and run on an always actuator.
+'''
+filepath = "/dsk/data/src/blender/blender/source/tests/bl_rst_completeness.py"
+exec(compile(open(filepath).read(), filepath, 'exec'))
+'''
+
+import os
+
+THIS_DIR = os.path.dirname(__file__)
+RST_DIR = os.path.normpath(os.path.join(THIS_DIR, "..", "..", "doc", "python_api", "rst"))
+
+import sys
+sys.path.append(THIS_DIR)
+
+import rst_to_doctree_mini
+
+try:
+ import bge
+except:
+ bge = None
+
+# (file, module)
+modules = (
+ ("bge.constraints.rst", "bge.constraints", False),
+ ("bge.events.rst", "bge.events", False),
+ ("bge.logic.rst", "bge.logic", False),
+ ("bge.render.rst", "bge.render", False),
+ ("bge.texture.rst", "bge.texture", False),
+ ("bge.types.rst", "bge.types", False),
+
+ ("bgl.rst", "bgl", True),
+ ("gpu.rst", "gpu", False),
+)
+
+def is_directive_pydata(filepath, directive):
+ if directive.type in {"function", "method", "class", "attribute", "data"}:
+ return True
+ elif directive.type in {"module", "note", "warning", "code-block", "hlist", "seealso"}:
+ return False
+ elif directive.type in {"literalinclude"}: # TODO
+ return False
+ else:
+ print(directive_to_str(filepath, directive), end=" ")
+ print("unknown directive type %r" % directive.type)
+ return False
+
+
+def directive_to_str(filepath, directive):
+ return "%s:%d:%d:" % (filepath, directive.line + 1, directive.indent)
+
+
+def directive_members_dict(filepath, directive_members):
+ return {directive.value_strip: directive for directive in directive_members
+ if is_directive_pydata(filepath, directive)}
+
+
+def module_validate(filepath, mod, mod_name, doctree, partial_ok):
+ # RST member missing from MODULE ???
+ for directive in doctree:
+ # print(directive.type)
+ if is_directive_pydata(filepath, directive):
+ attr = directive.value_strip
+ has_attr = hasattr(mod, attr)
+ ok = False
+ if not has_attr:
+ # so we can have glNormal docs cover glNormal3f
+ if partial_ok:
+ for s in dir(mod):
+ if s.startswith(attr):
+ ok = True
+ break
+
+ if not ok:
+ print(directive_to_str(filepath, directive), end=" ")
+ print("rst contains non existing member %r" % attr)
+
+ # if its a class, scan down the class...
+ # print(directive.type)
+ if has_attr:
+ if directive.type == "class":
+ cls = getattr(mod, attr)
+ # print("directive: ", directive)
+ for directive_child in directive.members:
+ # print("directive_child: ", directive_child)
+ if is_directive_pydata(filepath, directive_child):
+ attr_child = directive_child.value_strip
+ if attr_child not in cls.__dict__:
+ attr_id = "%s.%s" % (attr, attr_child)
+ print(directive_to_str(filepath, directive_child), end=" ")
+ print("rst contains non existing class member %r" % attr_id)
+
+
+ # MODULE member missing from RST ???
+ doctree_dict = directive_members_dict(filepath, doctree)
+ for attr in dir(mod):
+ if attr.startswith("_"):
+ continue
+
+ directive = doctree_dict.get(attr)
+ if directive is None:
+ print("module contains undocumented member %r from %r" % ("%s.%s" % (mod_name, attr), filepath))
+ else:
+ if directive.type == "class":
+ directive_dict = directive_members_dict(filepath, directive.members)
+ cls = getattr(mod, attr)
+ for attr_child in cls.__dict__.keys():
+ if attr_child.startswith("_"):
+ continue
+ if attr_child not in directive_dict:
+ attr_id = "%s.%s.%s" % (mod_name, attr, attr_child), filepath
+ print("module contains undocumented member %r from %r" % attr_id)
+
+
+def main():
+
+ if bge is None:
+ print("Skipping BGE modules!")
+
+ for filename, modname, partial_ok in modules:
+ if bge is None and modname.startswith("bge"):
+ continue
+
+ filepath = os.path.join(RST_DIR, filename)
+ if not os.path.exists(filepath):
+ raise Exception("%r not found" % filepath)
+
+ doctree = rst_to_doctree_mini.parse_rst_py(filepath)
+ __import__(modname)
+ mod = sys.modules[modname]
+
+ module_validate(filepath, mod, modname, doctree, partial_ok)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/source/tests/rst_to_doctree_mini.py b/source/tests/rst_to_doctree_mini.py
new file mode 100644
index 00000000000..181037299cf
--- /dev/null
+++ b/source/tests/rst_to_doctree_mini.py
@@ -0,0 +1,91 @@
+# ##### 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>
+
+# Module with function to extract a doctree from an reStructuredText file.
+# Named 'Mini' because we only parse the minimum data needed to check
+# Python classes, methods and attributes match up to those in existing modules.
+# (To test for documentation completeness)
+
+# note: literalinclude's are not followed.
+# could be nice to add but not really needed either right now.
+
+import collections
+
+Directive = collections.namedtuple('Directive',
+ ("type",
+ "value",
+ "value_strip",
+ "line",
+ "indent",
+ "members"))
+
+
+def parse_rst_py(filepath):
+ import re
+
+ # Get the prefix assuming the line is lstrip()'d
+ # ..foo:: bar
+ # -->
+ # ("foo", "bar")
+ re_prefix = re.compile(r"^\.\.\s([a-zA-Z09\-]+)::\s*(.*)\s*$")
+
+ tree = collections.defaultdict(list)
+ indent_map = {}
+ indent_prev = 0
+ f = open(filepath, encoding="utf-8")
+ indent_lists = []
+ for i, line in enumerate(f):
+ line_strip = line.lstrip()
+ # ^\.\.\s[a-zA-Z09\-]+::.*$
+ #if line.startswith(".. "):
+ march = re_prefix.match(line_strip)
+
+ if march:
+ directive, value = march.group(1, 2)
+ indent = len(line) - len(line_strip)
+ value_strip = value.replace("(", " ").split()
+ value_strip = value_strip[0] if value_strip else ""
+
+ item = Directive(type=directive,
+ value=value,
+ value_strip=value_strip,
+ line=i,
+ indent=indent,
+ members=[])
+
+ tree[indent].append(item)
+ if indent_prev < indent:
+ indent_map[indent] = indent_prev
+ if indent > 0:
+ tree[indent_map[indent]][-1].members.append(item)
+ indent_prev = indent
+ f.close()
+
+ return tree[0]
+
+
+if __name__ == "__main__":
+ # not intended use, but may as well print rst files passed as a test.
+ import sys
+ for arg in sys.argv:
+ if arg.lower().endswith((".txt", ".rst")):
+ items = parse_rst_py(arg)
+ for i in items:
+ print(i)