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:
authorDaniel Stokes <kupomail@gmail.com>2013-10-14 00:59:55 +0400
committerDaniel Stokes <kupomail@gmail.com>2013-10-14 00:59:55 +0400
commit0aa392d2ff4cc29f2e53485a6456a7deb838e1bb (patch)
tree50aa44367f0df077be6115c1f9deb85656018d4d
parent6167313105cd0b65ba777459ce9333ac51e0cb3b (diff)
parent2ce3bd0d672e7e26e1a8710444872ad6478a7565 (diff)
Merged revisions 60248-60717 from trunk/blendersoc-2013-bge
-rw-r--r--CMakeLists.txt75
-rw-r--r--GNUmakefile4
-rw-r--r--SConstruct16
-rwxr-xr-xbuild_files/build_environment/install_deps.sh20
-rw-r--r--build_files/cmake/macros.cmake11
-rw-r--r--build_files/scons/config/darwin-config.py2
-rw-r--r--build_files/scons/tools/Blender.py16
-rw-r--r--build_files/scons/tools/btools.py2
-rw-r--r--doc/python_api/examples/bpy.types.UIList.2.py2
-rw-r--r--extern/libmv/CMakeLists.txt8
-rw-r--r--extern/libmv/SConscript3
-rwxr-xr-xextern/libmv/bundle.sh11
-rw-r--r--extern/libmv/libmv-capi.cc53
-rw-r--r--extern/libmv/libmv-capi.h3
-rw-r--r--extern/libmv/libmv-capi_intern.h59
-rw-r--r--extern/libmv/libmv-capi_stub.cc4
-rw-r--r--extern/libmv/libmv/multiview/fundamental.cc91
-rw-r--r--extern/libmv/libmv/multiview/fundamental.h37
-rw-r--r--extern/libmv/libmv/multiview/homography.cc111
-rw-r--r--extern/libmv/libmv/multiview/homography.h39
-rw-r--r--extern/libmv/libmv/simple_pipeline/keyframe_selection.cc176
-rw-r--r--extern/libmv/third_party/msinttypes/stdint.h12
-rw-r--r--intern/cycles/blender/CMakeLists.txt2
-rw-r--r--intern/cycles/blender/addon/ui.py9
-rw-r--r--intern/cycles/blender/blender_curves.cpp4
-rw-r--r--intern/cycles/blender/blender_mesh.cpp2
-rw-r--r--intern/cycles/blender/blender_shader.cpp5
-rw-r--r--intern/cycles/blender/blender_sync.cpp3
-rw-r--r--intern/cycles/device/device.cpp75
-rw-r--r--intern/cycles/device/device_cuda.cpp219
-rw-r--r--intern/cycles/device/device_opencl.cpp12
-rw-r--r--intern/cycles/kernel/CMakeLists.txt38
-rw-r--r--intern/cycles/kernel/SConscript34
-rw-r--r--intern/cycles/kernel/kernel_bvh.h19
-rw-r--r--intern/cycles/kernel/kernel_compat_cuda.h11
-rw-r--r--intern/cycles/kernel/kernel_film.h4
-rw-r--r--intern/cycles/kernel/kernel_globals.h4
-rw-r--r--intern/cycles/kernel/kernel_path.h85
-rw-r--r--intern/cycles/kernel/kernel_primitive.h8
-rw-r--r--intern/cycles/kernel/kernel_shader.h23
-rw-r--r--intern/cycles/kernel/kernel_sse2.cpp3
-rw-r--r--intern/cycles/kernel/kernel_sse3.cpp3
-rw-r--r--intern/cycles/kernel/kernel_subsurface.h159
-rw-r--r--intern/cycles/kernel/kernel_types.h12
-rw-r--r--intern/cycles/kernel/osl/osl_shader.cpp2
-rw-r--r--intern/cycles/kernel/shaders/SConscript2
-rw-r--r--intern/cycles/kernel/shaders/node_environment_texture.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_hair_bsdf.osl43
-rw-r--r--intern/cycles/kernel/shaders/node_sky_texture.osl12
-rw-r--r--intern/cycles/kernel/shaders/node_subsurface_scattering.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_ward_bsdf.osl2
-rw-r--r--intern/cycles/kernel/shaders/stdosl.h19
-rw-r--r--intern/cycles/kernel/svm/svm_closure.h3
-rw-r--r--intern/cycles/kernel/svm/svm_types.h3
-rw-r--r--intern/cycles/render/CMakeLists.txt2
-rw-r--r--intern/cycles/render/bssrdf.cpp134
-rw-r--r--intern/cycles/render/bssrdf.h29
-rw-r--r--intern/cycles/render/nodes.cpp75
-rw-r--r--intern/cycles/render/nodes.h3
-rw-r--r--intern/cycles/render/shader.cpp24
-rw-r--r--intern/cycles/render/shader.h1
-rw-r--r--intern/cycles/util/util_opengl.h5
-rw-r--r--intern/cycles/util/util_types.h5
-rw-r--r--intern/elbeem/CMakeLists.txt1
-rw-r--r--intern/elbeem/SConscript2
-rw-r--r--intern/elbeem/intern/attributes.h25
-rw-r--r--intern/elbeem/intern/controlparticles.h23
-rw-r--r--intern/elbeem/intern/isosurface.h9
-rw-r--r--intern/elbeem/intern/mvmcoords.h18
-rw-r--r--intern/elbeem/intern/ntl_blenderdumper.h8
-rw-r--r--intern/elbeem/intern/ntl_bsptree.h7
-rw-r--r--intern/elbeem/intern/ntl_geometryclass.h8
-rw-r--r--intern/elbeem/intern/ntl_geometrymodel.h9
-rw-r--r--intern/elbeem/intern/ntl_geometryobject.h9
-rw-r--r--intern/elbeem/intern/ntl_geometryshader.h10
-rw-r--r--intern/elbeem/intern/ntl_lighting.h13
-rw-r--r--intern/elbeem/intern/ntl_matrices.h7
-rw-r--r--intern/elbeem/intern/ntl_ray.h21
-rw-r--r--intern/elbeem/intern/ntl_vector3dim.h9
-rw-r--r--intern/elbeem/intern/ntl_world.h15
-rw-r--r--intern/elbeem/intern/parametrizer.h9
-rw-r--r--intern/elbeem/intern/particletracer.cpp1
-rw-r--r--intern/elbeem/intern/particletracer.h15
-rw-r--r--intern/elbeem/intern/simulation_object.cpp12
-rw-r--r--intern/elbeem/intern/simulation_object.h9
-rw-r--r--intern/elbeem/intern/solver_class.h18
-rw-r--r--intern/elbeem/intern/solver_control.cpp9
-rw-r--r--intern/elbeem/intern/solver_control.h14
-rw-r--r--intern/elbeem/intern/solver_interface.cpp9
-rw-r--r--intern/elbeem/intern/solver_interface.h27
-rw-r--r--intern/elbeem/intern/solver_main.cpp6
-rw-r--r--intern/ghost/SConscript3
-rw-r--r--intern/ghost/intern/GHOST_DisplayManagerCocoa.mm9
-rw-r--r--intern/ghost/intern/GHOST_NDOFManager3Dconnexion.c71
-rw-r--r--intern/ghost/intern/GHOST_SystemCocoa.mm26
-rw-r--r--intern/ghost/intern/GHOST_SystemPathsX11.cpp9
-rw-r--r--intern/ghost/intern/GHOST_SystemWin32.cpp26
-rw-r--r--intern/ghost/intern/GHOST_WindowCocoa.h4
-rw-r--r--intern/ghost/intern/GHOST_WindowWin32.cpp78
-rw-r--r--intern/ghost/intern/GHOST_WindowX11.cpp61
-rw-r--r--intern/guardedalloc/CMakeLists.txt12
-rw-r--r--intern/guardedalloc/MEM_guardedalloc.h117
-rw-r--r--intern/guardedalloc/SConscript10
-rw-r--r--intern/guardedalloc/intern/mallocn.c1300
-rw-r--r--intern/guardedalloc/intern/mallocn_guarded_impl.c1114
-rw-r--r--intern/guardedalloc/intern/mallocn_intern.h132
-rw-r--r--intern/guardedalloc/intern/mallocn_lockfree_impl.c376
-rw-r--r--intern/guardedalloc/mmap_win.h2
-rw-r--r--intern/locale/boost_locale_wrapper.cpp2
-rw-r--r--intern/opencolorio/CMakeLists.txt2
-rw-r--r--intern/opencolorio/SConscript7
-rw-r--r--intern/opencolorio/fallback_impl.cc3
-rw-r--r--intern/opencolorio/gpu_shader_display_transform.glsl123
-rw-r--r--intern/opencolorio/ocio_capi.cc5
-rw-r--r--intern/opencolorio/ocio_capi.h59
-rw-r--r--intern/opencolorio/ocio_impl.cc53
-rw-r--r--intern/opencolorio/ocio_impl.h9
-rw-r--r--intern/opencolorio/ocio_impl_glsl.cc164
-rw-r--r--intern/utfconv/utf_winfunc.c19
-rw-r--r--release/datafiles/splash.pngbin139754 -> 256816 bytes
-rw-r--r--release/scripts/freestyle/style_modules/ChainingIterators.py6
-rw-r--r--release/scripts/freestyle/style_modules/PredicatesB1D.py2
-rw-r--r--release/scripts/freestyle/style_modules/PredicatesU1D.py14
-rw-r--r--release/scripts/freestyle/style_modules/parameter_editor.py17
-rw-r--r--release/scripts/freestyle/style_modules/shaders.py2
-rw-r--r--release/scripts/modules/bpy/path.py1
-rw-r--r--release/scripts/modules/bpy_types.py9
-rw-r--r--release/scripts/modules/rna_info.py3
-rw-r--r--release/scripts/modules/rna_keymap_ui.py13
-rw-r--r--release/scripts/presets/keyconfig/maya.py6
-rw-r--r--release/scripts/presets/operator/wm.collada_export/sl_plus_open_sim_rigged.py (renamed from release/scripts/presets/operator/wm.collada_export/second_life_rigged.py)2
-rw-r--r--release/scripts/presets/operator/wm.collada_export/sl_plus_open_sim_static.py (renamed from release/scripts/presets/operator/wm.collada_export/second_life_static.py)2
-rw-r--r--release/scripts/startup/bl_operators/node.py7
-rw-r--r--release/scripts/startup/bl_operators/uvcalc_lightmap.py4
-rw-r--r--release/scripts/startup/bl_operators/wm.py10
-rw-r--r--release/scripts/startup/bl_ui/properties_data_modifier.py6
-rw-r--r--release/scripts/startup/bl_ui/properties_freestyle.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_mask_common.py5
-rw-r--r--release/scripts/startup/bl_ui/properties_material.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_paint_common.py19
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_common.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_render.py11
-rw-r--r--release/scripts/startup/bl_ui/properties_texture.py2
-rw-r--r--release/scripts/startup/bl_ui/space_image.py70
-rw-r--r--release/scripts/startup/bl_ui/space_info.py2
-rw-r--r--release/scripts/startup/bl_ui/space_node.py4
-rw-r--r--release/scripts/startup/bl_ui/space_sequencer.py7
-rw-r--r--release/scripts/startup/bl_ui/space_text.py2
-rw-r--r--release/scripts/startup/bl_ui/space_view3d_toolbar.py126
-rw-r--r--release/scripts/templates_py/custom_nodes.py2
-rw-r--r--release/scripts/templates_py/ui_list.py2
-rw-r--r--release/text/readme.html14
-rw-r--r--source/blender/CMakeLists.txt4
-rw-r--r--source/blender/SConscript3
-rw-r--r--source/blender/blenkernel/BKE_action.h4
-rw-r--r--source/blender/blenkernel/BKE_animsys.h3
-rw-r--r--source/blender/blenkernel/BKE_blender.h6
-rw-r--r--source/blender/blenkernel/BKE_curve.h3
-rw-r--r--source/blender/blenkernel/BKE_customdata.h3
-rw-r--r--source/blender/blenkernel/BKE_deform.h8
-rw-r--r--source/blender/blenkernel/BKE_fcurve.h5
-rw-r--r--source/blender/blenkernel/BKE_mesh.h10
-rw-r--r--source/blender/blenkernel/BKE_modifier.h2
-rw-r--r--source/blender/blenkernel/BKE_node.h31
-rw-r--r--source/blender/blenkernel/BKE_subsurf.h4
-rw-r--r--source/blender/blenkernel/BKE_texture.h4
-rw-r--r--source/blender/blenkernel/SConscript3
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf.c19
-rw-r--r--source/blender/blenkernel/intern/action.c16
-rw-r--r--source/blender/blenkernel/intern/anim.c2
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c71
-rw-r--r--source/blender/blenkernel/intern/boids.c4
-rw-r--r--source/blender/blenkernel/intern/bvhutils.c2
-rw-r--r--source/blender/blenkernel/intern/colortools.c3
-rw-r--r--source/blender/blenkernel/intern/curve.c121
-rw-r--r--source/blender/blenkernel/intern/customdata.c94
-rw-r--r--source/blender/blenkernel/intern/deform.c115
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c2
-rw-r--r--source/blender/blenkernel/intern/dynamicpaint.c13
-rw-r--r--source/blender/blenkernel/intern/fcurve.c64
-rw-r--r--source/blender/blenkernel/intern/freestyle.c3
-rw-r--r--source/blender/blenkernel/intern/gpencil.c8
-rw-r--r--source/blender/blenkernel/intern/idprop.c118
-rw-r--r--source/blender/blenkernel/intern/image.c6
-rw-r--r--source/blender/blenkernel/intern/library.c5
-rw-r--r--source/blender/blenkernel/intern/mask_rasterize.c2
-rw-r--r--source/blender/blenkernel/intern/mesh.c112
-rw-r--r--source/blender/blenkernel/intern/mesh_evaluate.c23
-rw-r--r--source/blender/blenkernel/intern/mesh_validate.c20
-rw-r--r--source/blender/blenkernel/intern/modifier.c16
-rw-r--r--source/blender/blenkernel/intern/modifiers_bmesh.c3
-rw-r--r--source/blender/blenkernel/intern/movieclip.c1
-rw-r--r--source/blender/blenkernel/intern/multires.c16
-rw-r--r--source/blender/blenkernel/intern/node.c60
-rw-r--r--source/blender/blenkernel/intern/object.c19
-rw-r--r--source/blender/blenkernel/intern/paint.c4
-rw-r--r--source/blender/blenkernel/intern/particle.c8
-rw-r--r--source/blender/blenkernel/intern/particle_system.c11
-rw-r--r--source/blender/blenkernel/intern/pbvh_bmesh.c32
-rw-r--r--source/blender/blenkernel/intern/rigidbody.c2
-rw-r--r--source/blender/blenkernel/intern/scene.c13
-rw-r--r--source/blender/blenkernel/intern/screen.c2
-rw-r--r--source/blender/blenkernel/intern/sequencer.c5
-rw-r--r--source/blender/blenkernel/intern/shrinkwrap.c2
-rw-r--r--source/blender/blenkernel/intern/smoke.c3
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c10
-rw-r--r--source/blender/blenkernel/intern/texture.c63
-rw-r--r--source/blender/blenkernel/intern/tracking.c4
-rw-r--r--source/blender/blenlib/BLI_bitmap.h3
-rw-r--r--source/blender/blenlib/BLI_boxpack2d.h5
-rw-r--r--source/blender/blenlib/BLI_linklist_stack.h2
-rw-r--r--source/blender/blenlib/BLI_math_geom.h9
-rw-r--r--source/blender/blenlib/BLI_memarena.h2
-rw-r--r--source/blender/blenlib/BLI_mempool.h4
-rw-r--r--source/blender/blenlib/BLI_scanfill.h2
-rw-r--r--source/blender/blenlib/BLI_task.h108
-rw-r--r--source/blender/blenlib/BLI_threads.h32
-rw-r--r--source/blender/blenlib/CMakeLists.txt6
-rw-r--r--source/blender/blenlib/PIL_time_utildefines.h5
-rw-r--r--source/blender/blenlib/intern/BLI_heap.c2
-rw-r--r--source/blender/blenlib/intern/BLI_kdopbvh.c2
-rw-r--r--source/blender/blenlib/intern/BLI_memarena.c23
-rw-r--r--source/blender/blenlib/intern/BLI_mempool.c51
-rw-r--r--source/blender/blenlib/intern/boxpack2d.c41
-rw-r--r--source/blender/blenlib/intern/lasso.c2
-rw-r--r--source/blender/blenlib/intern/math_geom.c81
-rw-r--r--source/blender/blenlib/intern/math_rotation.c6
-rw-r--r--source/blender/blenlib/intern/noise.c24
-rw-r--r--source/blender/blenlib/intern/path_util.c16
-rw-r--r--source/blender/blenlib/intern/smallhash.c2
-rw-r--r--source/blender/blenlib/intern/task.c424
-rw-r--r--source/blender/blenlib/intern/threads.c114
-rw-r--r--source/blender/blenloader/intern/readfile.c88
-rw-r--r--source/blender/blenloader/intern/versioning_legacy.c27
-rw-r--r--source/blender/blenloader/intern/writefile.c9
-rw-r--r--source/blender/bmesh/intern/bmesh_construct.c17
-rw-r--r--source/blender/bmesh/intern/bmesh_core.c26
-rw-r--r--source/blender/bmesh/intern/bmesh_core.h2
-rw-r--r--source/blender/bmesh/intern/bmesh_iterators.c56
-rw-r--r--source/blender/bmesh/intern/bmesh_iterators.h15
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh.h7
-rw-r--r--source/blender/bmesh/intern/bmesh_operators.c31
-rw-r--r--source/blender/bmesh/intern/bmesh_polygon.c307
-rw-r--r--source/blender/bmesh/intern/bmesh_polygon.h1
-rw-r--r--source/blender/bmesh/intern/bmesh_walkers_impl.c96
-rw-r--r--source/blender/bmesh/operators/bmo_bridge.c2
-rw-r--r--source/blender/bmesh/operators/bmo_connect.c2
-rw-r--r--source/blender/bmesh/operators/bmo_connect_nonplanar.c2
-rw-r--r--source/blender/bmesh/operators/bmo_dissolve.c68
-rw-r--r--source/blender/bmesh/operators/bmo_dupe.c2
-rw-r--r--source/blender/bmesh/operators/bmo_edgenet.c8
-rw-r--r--source/blender/bmesh/operators/bmo_fill_attribute.c2
-rw-r--r--source/blender/bmesh/operators/bmo_fill_holes.c2
-rw-r--r--source/blender/bmesh/operators/bmo_inset.c1
-rw-r--r--source/blender/bmesh/operators/bmo_join_triangles.c12
-rw-r--r--source/blender/bmesh/operators/bmo_primitive.c12
-rw-r--r--source/blender/bmesh/operators/bmo_removedoubles.c28
-rw-r--r--source/blender/bmesh/operators/bmo_symmetrize.c3
-rw-r--r--source/blender/bmesh/operators/bmo_triangulate.c1
-rw-r--r--source/blender/bmesh/operators/bmo_utils.c1
-rw-r--r--source/blender/bmesh/tools/bmesh_bevel.c23
-rw-r--r--source/blender/bmesh/tools/bmesh_bisect_plane.c6
-rw-r--r--source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c4
-rw-r--r--source/blender/bmesh/tools/bmesh_triangulate.c16
-rw-r--r--source/blender/collada/AnimationExporter.cpp4
-rw-r--r--source/blender/collada/ArmatureExporter.cpp8
-rw-r--r--source/blender/collada/ControllerExporter.cpp4
-rw-r--r--source/blender/collada/DocumentImporter.cpp2
-rw-r--r--source/blender/collada/ExportSettings.h2
-rw-r--r--source/blender/collada/MeshImporter.cpp10
-rw-r--r--source/blender/collada/collada.cpp4
-rw-r--r--source/blender/collada/collada.h2
-rw-r--r--source/blender/collada/version.conf1
-rw-r--r--source/blender/compositor/intern/COM_MemoryBuffer.cpp2
-rw-r--r--source/blender/editors/animation/anim_filter.c9
-rw-r--r--source/blender/editors/animation/anim_markers.c2
-rw-r--r--source/blender/editors/animation/keyframes_edit.c2
-rw-r--r--source/blender/editors/animation/keyframing.c82
-rw-r--r--source/blender/editors/armature/BIF_retarget.h4
-rw-r--r--source/blender/editors/armature/armature_naming.c28
-rw-r--r--source/blender/editors/armature/editarmature_retarget.c46
-rw-r--r--source/blender/editors/armature/pose_lib.c2
-rw-r--r--source/blender/editors/curve/editcurve_add.c2
-rw-r--r--source/blender/editors/curve/editfont.c2
-rw-r--r--source/blender/editors/include/BIF_glutil.h3
-rw-r--r--source/blender/editors/include/ED_mask.h2
-rw-r--r--source/blender/editors/include/ED_mesh.h2
-rw-r--r--source/blender/editors/include/ED_render.h2
-rw-r--r--source/blender/editors/include/ED_transform.h2
-rw-r--r--source/blender/editors/include/ED_view3d.h3
-rw-r--r--source/blender/editors/interface/CMakeLists.txt1
-rw-r--r--source/blender/editors/interface/interface.c8
-rw-r--r--source/blender/editors/interface/interface_draw.c6
-rw-r--r--source/blender/editors/interface/interface_eyedropper.c642
-rw-r--r--source/blender/editors/interface/interface_handlers.c121
-rw-r--r--source/blender/editors/interface/interface_intern.h6
-rw-r--r--source/blender/editors/interface/interface_layout.c23
-rw-r--r--source/blender/editors/interface/interface_ops.c379
-rw-r--r--source/blender/editors/interface/interface_regions.c2
-rw-r--r--source/blender/editors/interface/interface_templates.c22
-rw-r--r--source/blender/editors/interface/view2d_ops.c6
-rw-r--r--source/blender/editors/io/io_collada.c12
-rw-r--r--source/blender/editors/mask/mask_draw.c118
-rw-r--r--source/blender/editors/mesh/editmesh_bevel.c2
-rw-r--r--source/blender/editors/mesh/editmesh_bisect.c2
-rw-r--r--source/blender/editors/mesh/editmesh_extrude.c2
-rw-r--r--source/blender/editors/mesh/editmesh_inset.c2
-rw-r--r--source/blender/editors/mesh/editmesh_knife.c119
-rw-r--r--source/blender/editors/mesh/editmesh_loopcut.c7
-rw-r--r--source/blender/editors/mesh/editmesh_select.c156
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c27
-rw-r--r--source/blender/editors/mesh/editmesh_utils.c5
-rw-r--r--source/blender/editors/mesh/meshtools.c8
-rw-r--r--source/blender/editors/object/object_bake.c119
-rw-r--r--source/blender/editors/object/object_edit.c8
-rw-r--r--source/blender/editors/object/object_group.c4
-rw-r--r--source/blender/editors/object/object_hook.c4
-rw-r--r--source/blender/editors/object/object_vgroup.c33
-rw-r--r--source/blender/editors/physics/particle_edit.c8
-rw-r--r--source/blender/editors/render/render_internal.c16
-rw-r--r--source/blender/editors/render/render_opengl.c23
-rw-r--r--source/blender/editors/render/render_shading.c48
-rw-r--r--source/blender/editors/screen/area.c1
-rw-r--r--source/blender/editors/screen/glutil.c65
-rw-r--r--source/blender/editors/screen/screen_edit.c8
-rw-r--r--source/blender/editors/screen/screendump.c18
-rw-r--r--source/blender/editors/sculpt_paint/paint_cursor.c77
-rw-r--r--source/blender/editors/sculpt_paint/paint_image.c55
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_proj.c6
-rw-r--r--source/blender/editors/sculpt_paint/paint_intern.h2
-rw-r--r--source/blender/editors/sculpt_paint/paint_ops.c11
-rw-r--r--source/blender/editors/sculpt_paint/paint_stroke.c6
-rw-r--r--source/blender/editors/sculpt_paint/paint_utils.c2
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex.c8
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c26
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_uv.c3
-rw-r--r--source/blender/editors/space_clip/clip_editor.c14
-rw-r--r--source/blender/editors/space_clip/space_clip.c4
-rw-r--r--source/blender/editors/space_clip/tracking_ops.c2
-rw-r--r--source/blender/editors/space_console/console_ops.c1
-rw-r--r--source/blender/editors/space_console/space_console.c1
-rw-r--r--source/blender/editors/space_file/CMakeLists.txt4
-rw-r--r--source/blender/editors/space_file/SConscript3
-rw-r--r--source/blender/editors/space_file/file_intern.h2
-rw-r--r--source/blender/editors/space_file/file_ops.c4
-rw-r--r--source/blender/editors/space_file/file_panels.c2
-rw-r--r--source/blender/editors/space_file/space_file.c2
-rw-r--r--source/blender/editors/space_graph/graph_draw.c2
-rw-r--r--source/blender/editors/space_image/CMakeLists.txt4
-rw-r--r--source/blender/editors/space_image/SConscript2
-rw-r--r--source/blender/editors/space_image/image_buttons.c2
-rw-r--r--source/blender/editors/space_image/image_draw.c12
-rw-r--r--source/blender/editors/space_image/image_ops.c5
-rw-r--r--source/blender/editors/space_image/space_image.c7
-rw-r--r--source/blender/editors/space_info/info_stats.c6
-rw-r--r--source/blender/editors/space_node/drawnode.c436
-rw-r--r--source/blender/editors/space_node/node_draw.c20
-rw-r--r--source/blender/editors/space_node/node_edit.c10
-rw-r--r--source/blender/editors/space_node/node_templates.c8
-rw-r--r--source/blender/editors/space_node/node_view.c2
-rw-r--r--source/blender/editors/space_outliner/outliner_tree.c16
-rw-r--r--source/blender/editors/space_sequencer/sequencer_draw.c6
-rw-r--r--source/blender/editors/space_sequencer/sequencer_edit.c2
-rw-r--r--source/blender/editors/space_sequencer/sequencer_modifier.c4
-rw-r--r--source/blender/editors/space_sequencer/sequencer_select.c2
-rw-r--r--source/blender/editors/space_sequencer/sequencer_view.c3
-rw-r--r--source/blender/editors/space_text/space_text.c2
-rw-r--r--source/blender/editors/space_text/text_autocomplete.c1
-rw-r--r--source/blender/editors/space_text/text_ops.c10
-rw-r--r--source/blender/editors/space_view3d/drawarmature.c16
-rw-r--r--source/blender/editors/space_view3d/drawobject.c4
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c20
-rw-r--r--source/blender/editors/space_view3d/view3d_buttons.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c4
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c179
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c30
-rw-r--r--source/blender/editors/space_view3d/view3d_snap.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c16
-rw-r--r--source/blender/editors/transform/transform.c71
-rw-r--r--source/blender/editors/transform/transform.h6
-rw-r--r--source/blender/editors/transform/transform_conversions.c40
-rw-r--r--source/blender/editors/transform/transform_generics.c8
-rw-r--r--source/blender/editors/transform/transform_input.c2
-rw-r--r--source/blender/editors/transform/transform_manipulator.c17
-rw-r--r--source/blender/editors/transform/transform_ops.c2
-rw-r--r--source/blender/editors/transform/transform_orientations.c38
-rw-r--r--source/blender/editors/transform/transform_snap.c3
-rw-r--r--source/blender/editors/util/crazyspace.c16
-rw-r--r--source/blender/editors/util/ed_util.c4
-rw-r--r--source/blender/editors/uvedit/uvedit_parametrizer.c4
-rw-r--r--source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp14
-rw-r--r--source/blender/freestyle/intern/stroke/StrokeRep.cpp12
-rw-r--r--source/blender/gpu/intern/gpu_material.c9
-rw-r--r--source/blender/gpu/shaders/gpu_shader_material.glsl24
-rw-r--r--source/blender/imbuf/CMakeLists.txt5
-rw-r--r--source/blender/imbuf/IMB_colormanagement.h9
-rw-r--r--source/blender/imbuf/IMB_imbuf.h2
-rw-r--r--source/blender/imbuf/IMB_imbuf_types.h7
-rw-r--r--source/blender/imbuf/SConscript3
-rw-r--r--source/blender/imbuf/intern/IMB_filetype.h3
-rw-r--r--source/blender/imbuf/intern/colormanagement.c135
-rw-r--r--source/blender/imbuf/intern/filetype.c43
-rw-r--r--source/blender/imbuf/intern/indexer.c8
-rw-r--r--source/blender/imbuf/intern/oiio/CMakeLists.txt54
-rw-r--r--source/blender/imbuf/intern/oiio/SConscript49
-rw-r--r--source/blender/imbuf/intern/oiio/openimageio_api.cpp256
-rw-r--r--source/blender/imbuf/intern/oiio/openimageio_api.h53
-rw-r--r--source/blender/imbuf/intern/readimage.c134
-rw-r--r--source/blender/imbuf/intern/tiff.c8
-rw-r--r--source/blender/imbuf/intern/util.c23
-rw-r--r--source/blender/imbuf/intern/writeimage.c2
-rw-r--r--source/blender/makesdna/DNA_mask_types.h7
-rw-r--r--source/blender/makesdna/DNA_mesh_types.h2
-rw-r--r--source/blender/makesdna/DNA_node_types.h31
-rw-r--r--source/blender/makesdna/DNA_object_types.h2
-rw-r--r--source/blender/makesdna/DNA_scene_types.h52
-rw-r--r--source/blender/makesdna/DNA_space_types.h3
-rw-r--r--source/blender/makesdna/DNA_texture_types.h8
-rw-r--r--source/blender/makesdna/intern/CMakeLists.txt9
-rw-r--r--source/blender/makesdna/intern/SConscript2
-rw-r--r--source/blender/makesrna/RNA_access.h10
-rw-r--r--source/blender/makesrna/RNA_define.h10
-rw-r--r--source/blender/makesrna/SConscript3
-rw-r--r--source/blender/makesrna/intern/CMakeLists.txt16
-rw-r--r--source/blender/makesrna/intern/SConscript5
-rw-r--r--source/blender/makesrna/intern/makesrna.c14
-rw-r--r--source/blender/makesrna/intern/rna_ID.c2
-rw-r--r--source/blender/makesrna/intern/rna_access.c28
-rw-r--r--source/blender/makesrna/intern/rna_action.c3
-rw-r--r--source/blender/makesrna/intern/rna_animation.c3
-rw-r--r--source/blender/makesrna/intern/rna_armature.c3
-rw-r--r--source/blender/makesrna/intern/rna_boid.c5
-rw-r--r--source/blender/makesrna/intern/rna_color.c28
-rw-r--r--source/blender/makesrna/intern/rna_constraint.c4
-rw-r--r--source/blender/makesrna/intern/rna_curve.c6
-rw-r--r--source/blender/makesrna/intern/rna_define.c11
-rw-r--r--source/blender/makesrna/intern/rna_dynamicpaint.c13
-rw-r--r--source/blender/makesrna/intern/rna_fcurve.c25
-rw-r--r--source/blender/makesrna/intern/rna_gpencil.c12
-rw-r--r--source/blender/makesrna/intern/rna_internal.h11
-rw-r--r--source/blender/makesrna/intern/rna_key.c9
-rw-r--r--source/blender/makesrna/intern/rna_lamp.c2
-rw-r--r--source/blender/makesrna/intern/rna_linestyle.c2
-rw-r--r--source/blender/makesrna/intern/rna_main_api.c2
-rw-r--r--source/blender/makesrna/intern/rna_material.c12
-rw-r--r--source/blender/makesrna/intern/rna_mesh.c61
-rw-r--r--source/blender/makesrna/intern/rna_mesh_api.c5
-rw-r--r--source/blender/makesrna/intern/rna_mesh_utils.h8
-rw-r--r--source/blender/makesrna/intern/rna_meta.c2
-rw-r--r--source/blender/makesrna/intern/rna_modifier.c3
-rw-r--r--source/blender/makesrna/intern/rna_nla.c2
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c127
-rw-r--r--source/blender/makesrna/intern/rna_object.c27
-rw-r--r--source/blender/makesrna/intern/rna_object_api.c2
-rw-r--r--source/blender/makesrna/intern/rna_object_force.c12
-rw-r--r--source/blender/makesrna/intern/rna_particle.c92
-rw-r--r--source/blender/makesrna/intern/rna_pose.c16
-rw-r--r--source/blender/makesrna/intern/rna_render.c4
-rw-r--r--source/blender/makesrna/intern/rna_rigidbody.c32
-rw-r--r--source/blender/makesrna/intern/rna_scene.c57
-rw-r--r--source/blender/makesrna/intern/rna_scene_api.c6
-rw-r--r--source/blender/makesrna/intern/rna_screen.c3
-rw-r--r--source/blender/makesrna/intern/rna_sculpt_paint.c10
-rw-r--r--source/blender/makesrna/intern/rna_sequencer.c2
-rw-r--r--source/blender/makesrna/intern/rna_smoke.c2
-rw-r--r--source/blender/makesrna/intern/rna_space.c46
-rw-r--r--source/blender/makesrna/intern/rna_test.c3
-rw-r--r--source/blender/makesrna/intern/rna_texture.c20
-rw-r--r--source/blender/makesrna/intern/rna_tracking.c11
-rw-r--r--source/blender/makesrna/intern/rna_ui.c4
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c1
-rw-r--r--source/blender/makesrna/intern/rna_wm.c2
-rw-r--r--source/blender/makesrna/intern/rna_wm_api.c20
-rw-r--r--source/blender/nodes/NOD_static_types.h1
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_mapValue.c2
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_scale.c19
-rw-r--r--source/blender/nodes/shader/node_shader_util.c3
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_gamma.c6
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_mapping.c15
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_brick.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_checker.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_environment.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_gradient.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_image.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_magic.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_musgrave.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_noise.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_sky.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_voronoi.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_wave.c2
-rw-r--r--source/blender/python/intern/CMakeLists.txt4
-rw-r--r--source/blender/python/intern/bpy_operator_wrap.c9
-rw-r--r--source/blender/python/mathutils/mathutils_Euler.c2
-rw-r--r--source/blender/python/mathutils/mathutils_Euler.h2
-rw-r--r--source/blender/python/mathutils/mathutils_Quaternion.c2
-rw-r--r--source/blender/python/mathutils/mathutils_Quaternion.h2
-rw-r--r--source/blender/python/mathutils/mathutils_Vector.c6
-rw-r--r--source/blender/python/mathutils/mathutils_Vector.h4
-rw-r--r--source/blender/quicktime/apple/qtkit_export.m14
-rw-r--r--source/blender/quicktime/apple/qtkit_import.m28
-rw-r--r--source/blender/render/extern/include/RE_multires_bake.h21
-rw-r--r--source/blender/render/extern/include/RE_pipeline.h4
-rw-r--r--source/blender/render/extern/include/RE_shader_ext.h3
-rw-r--r--source/blender/render/intern/include/render_types.h2
-rw-r--r--source/blender/render/intern/include/texture.h12
-rw-r--r--source/blender/render/intern/source/bake.c217
-rw-r--r--source/blender/render/intern/source/convertblender.c15
-rw-r--r--source/blender/render/intern/source/imagetexture.c2
-rw-r--r--source/blender/render/intern/source/multires_bake.c15
-rw-r--r--source/blender/render/intern/source/pipeline.c4
-rw-r--r--source/blender/render/intern/source/pixelshading.c8
-rw-r--r--source/blender/render/intern/source/rayshade.c2
-rw-r--r--source/blender/render/intern/source/rendercore.c5
-rw-r--r--source/blender/render/intern/source/shadbuf.c15
-rw-r--r--source/blender/render/intern/source/shadeinput.c10
-rw-r--r--source/blender/render/intern/source/sss.c2
-rw-r--r--source/blender/render/intern/source/volume_precache.c210
-rw-r--r--source/blender/windowmanager/WM_api.h3
-rw-r--r--source/blender/windowmanager/WM_keymap.h5
-rw-r--r--source/blender/windowmanager/WM_types.h1
-rw-r--r--source/blender/windowmanager/intern/wm_dragdrop.c4
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c2
-rw-r--r--source/blender/windowmanager/intern/wm_files.c5
-rw-r--r--source/blender/windowmanager/intern/wm_gesture.c96
-rw-r--r--source/blender/windowmanager/intern/wm_jobs.c7
-rw-r--r--source/blender/windowmanager/intern/wm_keymap.c29
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c24
-rw-r--r--source/blender/windowmanager/intern/wm_subwindow.c9
-rw-r--r--source/blender/windowmanager/intern/wm_window.c10
-rw-r--r--source/blender/windowmanager/wm_subwindow.h1
-rw-r--r--source/blenderplayer/CMakeLists.txt1
-rw-r--r--source/blenderplayer/bad_level_call_stubs/stubs.c2
-rw-r--r--source/creator/CMakeLists.txt9
-rw-r--r--source/creator/creator.c52
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp10
-rw-r--r--source/gameengine/Converter/BL_BlenderDataConversion.cpp3
-rw-r--r--source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp22
-rw-r--r--source/gameengine/GamePlayer/common/GPC_RenderTools.cpp19
-rw-r--r--source/gameengine/GamePlayer/ghost/GPG_ghost.cpp10
-rw-r--r--source/gameengine/Ketsji/KX_BlenderMaterial.cpp2
540 files changed, 10069 insertions, 5662 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 14209d2c8ad..bf8304629ae 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -203,6 +203,7 @@ option(WITH_MOD_REMESH "Enable Remesh Modifier" ON)
option(WITH_MOD_OCEANSIM "Enable Ocean Modifier" OFF)
# Image format support
+option(WITH_IMAGE_OPENIMAGEIO "Enable OpenImageIO Support (http://www.openimageio.org)" OFF)
option(WITH_IMAGE_OPENEXR "Enable OpenEXR Support (http://www.openexr.com)" ON)
option(WITH_IMAGE_OPENJPEG "Enable OpenJpeg Support (http://www.openjpeg.org)" ON)
option(WITH_IMAGE_TIFF "Enable LibTIFF Support" ON)
@@ -278,13 +279,14 @@ mark_as_advanced(LLVM_STATIC)
option(WITH_MEM_JEMALLOC "Enable malloc replacement (http://www.canonware.com/jemalloc)" OFF)
mark_as_advanced(WITH_MEM_JEMALLOC)
+# currently only used for BLI_mempool
+option(WITH_MEM_VALGRIND "Enable extended valgrind support for better reporting" OFF)
+mark_as_advanced(WITH_MEM_VALGRIND)
+
# Debug
option(WITH_CXX_GUARDEDALLOC "Enable GuardedAlloc for C++ memory allocation tracking (only enable for development)" OFF)
mark_as_advanced(WITH_CXX_GUARDEDALLOC)
-option(WITH_GUARDEDALLOC "Enable GuardedAlloc (DISABLE AT OWN RISK!)" ON)
-mark_as_advanced(WITH_GUARDEDALLOC)
-
option(WITH_ASSERT_ABORT "Call abort() when raising an assertion through BLI_assert()" OFF)
mark_as_advanced(WITH_ASSERT_ABORT)
@@ -368,7 +370,7 @@ if(APPLE)
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
+ 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")
@@ -418,6 +420,10 @@ if(WITH_IMAGE_REDCODE AND ((NOT WITH_IMAGE_OPENJPEG) OR (NOT WITH_CODEC_FFMPEG))
message(FATAL_ERROR "WITH_IMAGE_REDCODE requires WITH_IMAGE_OPENJPEG and WITH_CODEC_FFMPEG")
endif()
+if(WITH_IMAGE_OPENIMAGEIO)
+ set(WITH_OPENIMAGEIO ON)
+endif()
+
# python module, needs some different options
if(WITH_PYTHON_MODULE AND WITH_PLAYER)
message(FATAL_ERROR "WITH_PYTHON_MODULE requires WITH_PLAYER to be OFF")
@@ -456,7 +462,7 @@ if(NOT WITH_BOOST)
set_and_warn(WITH_OPENAL OFF) # depends on AUDASPACE
set_and_warn(WITH_GAMEENGINE OFF) # depends on AUDASPACE
-elseif(WITH_CYCLES OR WITH_MOD_BOOLEAN OR WITH_AUDASPACE OR WITH_INTERNATIONAL)
+elseif(WITH_CYCLES OR WITH_OPENIMAGEIO OR WITH_MOD_BOOLEAN OR WITH_AUDASPACE OR WITH_INTERNATIONAL)
# Keep enabled
else()
# Enabled but we don't need it
@@ -798,33 +804,38 @@ if(UNIX AND NOT APPLE)
find_program(LLVM_CONFIG llvm-config)
endif()
endif()
- execute_process(COMMAND ${LLVM_CONFIG} --version
- OUTPUT_VARIABLE LLVM_VERSION
- OUTPUT_STRIP_TRAILING_WHITESPACE)
- execute_process(COMMAND ${LLVM_CONFIG} --prefix
- OUTPUT_VARIABLE LLVM_DIRECTORY
- OUTPUT_STRIP_TRAILING_WHITESPACE)
- execute_process(COMMAND ${LLVM_CONFIG} --libdir
- OUTPUT_VARIABLE LLVM_LIB_DIR
- OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ if(NOT DEFINED LLVM_VERSION)
+ execute_process(COMMAND ${LLVM_CONFIG} --version
+ OUTPUT_VARIABLE LLVM_VERSION
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ set(LLVM_VERSION ${LLVM_VERSION} CACHE STRING "Version of LLVM to use")
+ endif()
+ if(NOT DEFINED LLVM_DIRECTORY)
+ execute_process(COMMAND ${LLVM_CONFIG} --prefix
+ OUTPUT_VARIABLE LLVM_DIRECTORY
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ set(LLVM_DIRECTORY ${LLVM_DIRECTORY} CACHE PATH "Path to the LLVM installation")
+ endif()
+ if(NOT DEFINED LLVM_LIBPATH)
+ execute_process(COMMAND ${LLVM_CONFIG} --libdir
+ OUTPUT_VARIABLE LLVM_LIBPATH
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ set(LLVM_LIBPATH ${LLVM_LIBPATH} CACHE PATH "Path to the LLVM library path")
+ endif()
if(LLVM_STATIC)
find_library(LLVM_LIBRARY
NAMES LLVMAnalysis # first of a whole bunch of libs to get
- PATHS ${LLVM_LIB_DIR})
+ PATHS ${LLVM_LIBPATH})
else()
find_library(LLVM_LIBRARY
NAMES LLVM-${LLVM_VERSION}
- PATHS ${LLVM_LIB_DIR})
+ PATHS ${LLVM_LIBPATH})
endif()
- 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_LIBRARY AND LLVM_DIRECTORY AND LLVM_LIBPATH)
if(LLVM_STATIC)
# if static LLVM libraries were requested, use llvm-config to generate
# the list of what libraries we need, and substitute that in the right
@@ -832,7 +843,7 @@ if(UNIX AND NOT APPLE)
execute_process(COMMAND ${LLVM_CONFIG} --libfiles
OUTPUT_VARIABLE LLVM_LIBRARY
OUTPUT_STRIP_TRAILING_WHITESPACE)
- string(REPLACE " " ";" LLVM_LIBRARY ${LLVM_LIBRARY})
+ string(REPLACE " " ";" LLVM_LIBRARY "${LLVM_LIBRARY}")
endif()
else()
message(FATAL_ERROR "LLVM not found.")
@@ -1449,7 +1460,7 @@ elseif(WIN32)
if(WITH_LLVM)
set(LLVM_DIRECTORY ${LIBDIR}/llvm CACHE PATH "Path to the LLVM installation")
- set(LLVM_LIB_DIR ${LLVM_DIRECTORY}/lib)
+ set(LLVM_LIBPATH ${LLVM_DIRECTORY}/lib)
# Explicitly set llvm lib order.
#---- WARNING ON GCC ORDER OF LIBS IS IMPORTANT, DO NOT CHANGE! ---------
set(LLVM_LIBRARY LLVMSelectionDAG LLVMCodeGen LLVMScalarOpts LLVMAnalysis LLVMArchive
@@ -1743,13 +1754,13 @@ elseif(APPLE)
OUTPUT_VARIABLE LLVM_DIRECTORY
OUTPUT_STRIP_TRAILING_WHITESPACE)
execute_process(COMMAND ${LLVM_CONFIG} --libdir
- OUTPUT_VARIABLE LLVM_LIB_DIR
+ OUTPUT_VARIABLE LLVM_LIBPATH
OUTPUT_STRIP_TRAILING_WHITESPACE)
find_library(LLVM_LIBRARY
NAMES LLVMAnalysis # first of a whole bunch of libs to get
- PATHS ${LLVM_LIB_DIR})
+ PATHS ${LLVM_LIBPATH})
- if(LLVM_LIBRARY AND LLVM_DIRECTORY AND LLVM_LIB_DIR)
+ if(LLVM_LIBRARY AND LLVM_DIRECTORY AND LLVM_LIBPATH)
if(LLVM_STATIC)
# if static LLVM libraries were requested, use llvm-config to generate
# the list of what libraries we need, and substitute that in the right
@@ -1823,22 +1834,22 @@ endif()
if(WITH_CYCLES)
if(NOT WITH_OPENIMAGEIO)
- message(FATAL_ERROR "Cycles reqires WITH_OPENIMAGEIO, the library may not have been found. Configure OIIO or disable WITH_CYCLES")
+ message(FATAL_ERROR "Cycles requires WITH_OPENIMAGEIO, the library may not have been found. Configure OIIO or disable WITH_CYCLES")
endif()
if(NOT WITH_BOOST)
- message(FATAL_ERROR "Cycles reqires WITH_BOOST, the library may not have been found. Configure BOOST or disable WITH_CYCLES")
+ message(FATAL_ERROR "Cycles requires WITH_BOOST, the library may not have been found. Configure BOOST or disable WITH_CYCLES")
endif()
if(WITH_CYCLES_OSL)
if(NOT WITH_LLVM)
- message(FATAL_ERROR "Cycles OSL reqires WITH_LLVM, the library may not have been found. Configure LLVM or disable WITH_CYCLES_OSL")
+ message(FATAL_ERROR "Cycles OSL requires WITH_LLVM, the library may not have been found. Configure LLVM or disable WITH_CYCLES_OSL")
endif()
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")
+ message(FATAL_ERROR "Internationalization requires WITH_BOOST, the library may not have been found. Configure BOOST or disable WITH_INTERNATIONAL")
endif()
endif()
@@ -2276,10 +2287,12 @@ if(FIRST_RUN)
info_cfg_option(WITH_X11_XF86VMODE)
info_cfg_option(WITH_X11_XINPUT)
info_cfg_option(WITH_MEM_JEMALLOC)
+ info_cfg_option(WITH_MEM_VALGRIND)
info_cfg_option(WITH_SYSTEM_GLEW)
info_cfg_option(WITH_SYSTEM_OPENJPEG)
info_cfg_text("Image Formats:")
+ info_cfg_option(WITH_IMAGE_OPENIMAGEIO)
info_cfg_option(WITH_IMAGE_CINEON)
info_cfg_option(WITH_IMAGE_DDS)
info_cfg_option(WITH_IMAGE_HDR)
diff --git a/GNUmakefile b/GNUmakefile
index d5570a8e170..417ff7770ed 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -182,6 +182,7 @@ help:
@echo " * check_spelling_c_qtc - same as check_spelling_c but outputs QtCreator tasks format"
@echo " * check_spelling_osl - check for spelling errors (OSL only)"
@echo " * check_spelling_py - check for spelling errors (Python only)"
+ @echo " * check_descriptions - check for duplicate/invalid descriptions"
@echo ""
@echo "Utilities (not associated with building blender)"
@echo " * icons - updates PNG icons from SVG files."
@@ -313,6 +314,9 @@ check_spelling_c_qtc:
check_spelling_osl:
cd $(BUILD_DIR) ; PYTHONIOENCODING=utf_8 python3 $(BLENDER_DIR)/source/tools/spell_check_source.py $(BLENDER_DIR)/intern/cycles/kernel/shaders
+check_descriptions:
+ $(BUILD_DIR)/bin/blender --background -noaudio --factory-startup --python $(BLENDER_DIR)/source/tools/check_descriptions.py
+
# -----------------------------------------------------------------------------
# Utilities
#
diff --git a/SConstruct b/SConstruct
index 668b30170d9..9f9eaa886a3 100644
--- a/SConstruct
+++ b/SConstruct
@@ -246,6 +246,7 @@ if 'blenderlite' in B.targets:
target_env_defs['WITH_BF_CYCLES'] = False
target_env_defs['WITH_BF_OPENAL'] = False
target_env_defs['WITH_BF_OPENEXR'] = False
+ target_env_defs['WITH_BF_PSD'] = False
target_env_defs['WITH_BF_OPENMP'] = False
target_env_defs['WITH_BF_ICONV'] = False
target_env_defs['WITH_BF_INTERNATIONAL'] = False
@@ -289,13 +290,13 @@ if env['OURPLATFORM']=='darwin':
print B.bc.OKGREEN + "Detected Xcode version: -- " + B.bc.ENDC + env['XCODE_CUR_VER'] + " --"
print "Available " + env['MACOSX_SDK_CHECK']
if not 'Mac OS X 10.6' in env['MACOSX_SDK_CHECK']:
- print B.bc.OKGREEN + "Auto-setting available MacOSX SDK -> " + B.bc.ENDC + "MacOSX10.7.sdk"
+ print B.bc.OKGREEN + "Building with user-defined OS X SDK ( Xcode 4.4 or newer )"
elif not 'Mac OS X 10.5' in env['MACOSX_SDK_CHECK']:
print B.bc.OKGREEN + "Auto-setting available MacOSX SDK -> " + B.bc.ENDC + "MacOSX10.6.sdk"
else:
print B.bc.OKGREEN + "Found recommended sdk :" + B.bc.ENDC + " using MacOSX10.5.sdk"
- if env['CXX'].startswith('clang') and env['XCODE_CUR_VER'] >= '5':
+ if env['XCODE_CUR_VER'] >= '5' and not (env['CXX'][:-2].endswith('4.6') or env['CXX'][:-2].endswith('4.8')):
env['CCFLAGS'].append('-ftemplate-depth=1024') # only valid for clang bundled with xcode 5
# for now, Mac builders must download and install the 3DxWare 10 Beta 4 driver framework from 3Dconnexion
@@ -322,7 +323,10 @@ if env['OURPLATFORM']=='darwin':
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'])
+ if env['CC'][:-2].endswith('4.8'):
+ env.Append(LINKFLAGS=['-L'+OSX_OSL_LIBPATH,'-loslcomp','-loslexec','-loslquery'])
+ else:
+ env.Append(LINKFLAGS=['-L'+OSX_OSL_LIBPATH,'-loslcomp','-force_load '+ OSX_OSL_LIBPATH +'/liboslexec.a','-loslquery'])
env.Append(BF_PROGRAM_LINKFLAGS=['-Xlinker','-force_load','-Xlinker',OSX_OSL_LIBPATH +'/liboslexec.a'])
# Trying to get rid of eventually clashes, we export some explicite as local symbols
@@ -548,6 +552,7 @@ if B.targets != ['cudakernels']:
data_to_c_simple("source/blender/gpu/shaders/gpu_shader_vertex.glsl")
data_to_c_simple("source/blender/gpu/shaders/gpu_shader_vsm_store_frag.glsl")
data_to_c_simple("source/blender/gpu/shaders/gpu_shader_vsm_store_vert.glsl")
+ data_to_c_simple("intern/opencolorio/gpu_shader_display_transform.glsl")
# --- blender ---
data_to_c_simple("release/datafiles/bfont.pfb")
@@ -906,6 +911,11 @@ for tp, tn, tf in os.walk('release/text'):
for f in tf:
textlist.append(tp+os.sep+f)
+# Font licenses
+textlist.append('release/datafiles/LICENSE-bfont.ttf.txt')
+if env['WITH_BF_INTERNATIONAL']:
+ textlist += ['release/datafiles/LICENSE-droidsans.ttf.txt', 'release/datafiles/LICENSE-bmonofont-i18n.ttf.txt']
+
textinstall = env.Install(dir=env['BF_INSTALLDIR'], source=textlist)
if env['OURPLATFORM']=='darwin':
diff --git a/build_files/build_environment/install_deps.sh b/build_files/build_environment/install_deps.sh
index 34cba73d0bf..dc21f85e85c 100755
--- a/build_files/build_environment/install_deps.sh
+++ b/build_files/build_environment/install_deps.sh
@@ -247,6 +247,8 @@ _ffmpeg_list_sep=";"
# FFMPEG optional libs.
VORBIS_USE=false
VORBIS_DEV=""
+OGG_USE=false
+OGG_DEV=""
THEORA_USE=false
THEORA_DEV=""
XVID_USE=false
@@ -1890,16 +1892,18 @@ install_DEB() {
# These libs should always be available in debian/ubuntu official repository...
OPENJPEG_DEV="libopenjpeg-dev"
VORBIS_DEV="libvorbis-dev"
+ OGG_DEV="libogg-dev"
THEORA_DEV="libtheora-dev"
_packages="gawk cmake cmake-curses-gui scons build-essential libjpeg-dev libpng-dev \
libfreetype6-dev libx11-dev libxi-dev wget libsqlite3-dev libbz2-dev \
libncurses5-dev libssl-dev liblzma-dev libreadline-dev $OPENJPEG_DEV \
- libopenal-dev libglew-dev yasm $THEORA_DEV $VORBIS_DEV \
+ libopenal-dev libglew-dev yasm $THEORA_DEV $VORBIS_DEV $OGG_DEV \
libsdl1.2-dev libfftw3-dev patch bzip2"
OPENJPEG_USE=true
VORBIS_USE=true
+ OGG_USE=true
THEORA_USE=true
# Install newest libtiff-dev in debian/ubuntu.
@@ -2307,15 +2311,17 @@ install_RPM() {
# These libs should always be available in fedora/suse official repository...
OPENJPEG_DEV="openjpeg-devel"
VORBIS_DEV="libvorbis-devel"
+ OGG_DEV="libogg-devel"
THEORA_DEV="libtheora-devel"
_packages="gcc gcc-c++ make scons libtiff-devel freetype-devel libjpeg-devel\
libpng-devel libX11-devel libXi-devel wget ncurses-devel \
readline-devel $OPENJPEG_DEV openal-soft-devel \
- glew-devel yasm $THEORA_DEV $VORBIS_DEV patch"
+ glew-devel yasm $THEORA_DEV $VORBIS_DEV $OGG_DEV patch"
OPENJPEG_USE=true
VORBIS_USE=true
+ OGG_USE=true
THEORA_USE=true
if [ $RPM = "FEDORA" -o $RPM = "RHEL" ]; then
@@ -2643,13 +2649,15 @@ install_ARCH() {
# These libs should always be available in arch official repository...
OPENJPEG_DEV="openjpeg"
VORBIS_DEV="libvorbis"
+ OGG_DEV="libogg"
THEORA_DEV="libtheora"
_packages="base-devel scons cmake libxi glew libpng libtiff wget openal \
- $OPENJPEG_DEV $VORBIS_DEV $THEORA_DEV yasm sdl fftw"
+ $OPENJPEG_DEV $VORBIS_DEV $OGG_DEV $THEORA_DEV yasm sdl fftw"
OPENJPEG_USE=true
VORBIS_USE=true
+ OGG_USE=true
THEORA_USE=true
if $WITH_ALL; then
@@ -2912,6 +2920,10 @@ print_info_ffmpeglink() {
_packages="$_packages $VORBIS_DEV"
fi
+ if $OGG_USE; then
+ _packages="$_packages $OGG_DEV"
+ fi
+
if $XVID_USE; then
_packages="$_packages $XVID_DEV"
fi
@@ -3133,7 +3145,7 @@ print_info() {
fi
if $ALL_STATIC; then
- INFO "LLIB = ["xml2", "expat"] + LLIB"
+ INFO "LLIBS = [\""xml2"\", \""expat"\"] + LLIBS"
fi
INFO ""
diff --git a/build_files/cmake/macros.cmake b/build_files/cmake/macros.cmake
index e8f3f3190a8..9ded803f45b 100644
--- a/build_files/cmake/macros.cmake
+++ b/build_files/cmake/macros.cmake
@@ -243,7 +243,7 @@ macro(SETUP_LIBDIRS)
link_directories(${EXPAT_LIBPATH})
endif()
if(WITH_LLVM)
- link_directories(${LLVM_LIB_DIR})
+ link_directories(${LLVM_LIBPATH})
endif()
if(WITH_MEM_JEMALLOC)
link_directories(${JEMALLOC_LIBPATH})
@@ -585,7 +585,8 @@ endmacro()
macro(get_blender_version)
# So cmake depends on BKE_blender.h, beware of inf-loops!
- CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/source/blender/blenkernel/BKE_blender.h ${CMAKE_BINARY_DIR}/source/blender/blenkernel/BKE_blender.h.done)
+ CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/source/blender/blenkernel/BKE_blender.h
+ ${CMAKE_BINARY_DIR}/source/blender/blenkernel/BKE_blender.h.done)
file(STRINGS ${CMAKE_SOURCE_DIR}/source/blender/blenkernel/BKE_blender.h _contents REGEX "^#define[ \t]+BLENDER_.*$")
@@ -774,6 +775,9 @@ macro(data_to_c
COMMAND ${CMAKE_COMMAND} -E make_directory ${_file_to_path}
COMMAND ${CMAKE_BINARY_DIR}/bin/${CMAKE_CFG_INTDIR}/datatoc ${file_from} ${file_to}
DEPENDS ${file_from} datatoc)
+
+ set_source_files_properties(${file_to} PROPERTIES GENERATED TRUE)
+
unset(_file_to_path)
endmacro()
@@ -797,10 +801,11 @@ macro(data_to_c_simple
COMMAND ${CMAKE_BINARY_DIR}/bin/${CMAKE_CFG_INTDIR}/datatoc ${_file_from} ${_file_to}
DEPENDS ${_file_from} datatoc)
+ set_source_files_properties(${_file_to} PROPERTIES GENERATED TRUE)
+
unset(_file_from)
unset(_file_to)
unset(_file_to_path)
-
endmacro()
# XXX Not used for now...
diff --git a/build_files/scons/config/darwin-config.py b/build_files/scons/config/darwin-config.py
index a87070500dd..5a1069618b9 100644
--- a/build_files/scons/config/darwin-config.py
+++ b/build_files/scons/config/darwin-config.py
@@ -113,7 +113,7 @@ if XCODE_CUR_VER >= '4.3': ## since version 4.3, XCode and developer dir are bu
#Defaults openMP to true if compiler handles it ( only gcc 4.6.1 and newer )
# if your compiler does not have accurate suffix you may have to enable it by hand !
-if CC[:-2].endswith('4.6'):
+if CC[:-2].endswith('4.6') or CC[:-2].endswith('4.8'):
WITH_BF_OPENMP = True # multithreading for fluids, cloth, sculpt and smoke
else:
WITH_BF_OPENMP = False
diff --git a/build_files/scons/tools/Blender.py b/build_files/scons/tools/Blender.py
index ee2399500d0..f181f290104 100644
--- a/build_files/scons/tools/Blender.py
+++ b/build_files/scons/tools/Blender.py
@@ -683,15 +683,23 @@ def AppIt(target=None, source=None, env=None):
commands.getoutput(cmd)
cmd = 'find %s/%s.app -name __MACOSX -exec rm -rf {} \;'%(installdir, binary)
commands.getoutput(cmd)
- if env['CC'][:-2].endswith('4.6'): # for correct errorhandling with gcc 4.6.x we need the gcc.dylib to link, thus distribute in app-bundle
+ if env['CC'][:-2].endswith('4.6') or env['CC'][:-2].endswith('4.8'): # for correct errorhandling with gcc 4.6/4.8.x we need the gcc.dylib and gomp.dylib to link, thus distribute in app-bundle
cmd = 'mkdir %s/%s.app/Contents/MacOS/lib'%(installdir, binary)
commands.getoutput(cmd)
instname = env['BF_CXX']
- cmd = 'ditto --arch %s %s/lib/libgcc_s.1.dylib %s/%s.app/Contents/MacOS/lib/'%(osxarch, instname, installdir, binary)
+ cmd = 'ditto --arch %s %s/lib/libgcc_s.1.dylib %s/%s.app/Contents/MacOS/lib/'%(osxarch, instname, installdir, binary) # copy libgcc
commands.getoutput(cmd)
- cmd = 'install_name_tool -id @executable_path/lib/libgcc_s.1.dylib %s/%s.app/Contents/MacOS/lib/libgcc_s.1.dylib'%(installdir, binary)
+ cmd = 'install_name_tool -id @executable_path/lib/libgcc_s.1.dylib %s/%s.app/Contents/MacOS/lib/libgcc_s.1.dylib'%(installdir, binary) # change id of libgcc
commands.getoutput(cmd)
- cmd = 'install_name_tool -change %s/lib/libgcc_s.1.dylib @executable_path/lib/libgcc_s.1.dylib %s/%s.app/Contents/MacOS/%s'%(instname, installdir, binary, binary)
+ cmd = 'ditto --arch %s %s/lib/libgomp.1.dylib %s/%s.app/Contents/MacOS/lib/'%(osxarch, instname, installdir, binary) # copy libgomp
+ commands.getoutput(cmd)
+ cmd = 'install_name_tool -id @executable_path/lib/libgomp.1.dylib %s/%s.app/Contents/MacOS/lib/libgomp.1.dylib'%(installdir, binary) # change id of libgomp
+ commands.getoutput(cmd)
+ cmd = 'install_name_tool -change %s/lib/libgcc_s.1.dylib @executable_path/lib/libgcc_s.1.dylib %s/%s.app/Contents/MacOS/lib/libgomp.1.dylib'%(instname, installdir, binary) # change ref to libgcc
+ commands.getoutput(cmd)
+ cmd = 'install_name_tool -change %s/lib/libgcc_s.1.dylib @executable_path/lib/libgcc_s.1.dylib %s/%s.app/Contents/MacOS/%s'%(instname, installdir, binary, binary) # change ref to libgcc ( blender )
+ commands.getoutput(cmd)
+ cmd = 'install_name_tool -change %s/lib/libgomp.1.dylib @executable_path/lib/libgomp.1.dylib %s/%s.app/Contents/MacOS/%s'%(instname, installdir, binary, binary) # change ref to libgomp ( blender )
commands.getoutput(cmd)
# extract copy system python, be sure to update other build systems
diff --git a/build_files/scons/tools/btools.py b/build_files/scons/tools/btools.py
index 454e72a1a72..8f0d3ff590b 100644
--- a/build_files/scons/tools/btools.py
+++ b/build_files/scons/tools/btools.py
@@ -576,7 +576,7 @@ def read_opts(env, cfg, args):
('BF_CYCLES_CUDA_BINARIES_ARCH', 'CUDA architectures to compile binaries for', []),
(BoolVariable('WITH_BF_OIIO', 'Build with OpenImageIO', False)),
- (BoolVariable('WITH_BF_STATICOIIO', 'Staticly link to OpenImageIO', False)),
+ (BoolVariable('WITH_BF_STATICOIIO', 'Statically link to OpenImageIO', False)),
('BF_OIIO', 'OIIO root path', ''),
('BF_OIIO_INC', 'OIIO include path', ''),
('BF_OIIO_LIB', 'OIIO library', ''),
diff --git a/doc/python_api/examples/bpy.types.UIList.2.py b/doc/python_api/examples/bpy.types.UIList.2.py
index 3ffd099859a..4e30e6895d6 100644
--- a/doc/python_api/examples/bpy.types.UIList.2.py
+++ b/doc/python_api/examples/bpy.types.UIList.2.py
@@ -8,7 +8,7 @@ example of how to create/use filtering/reordering callbacks.
import bpy
-class MESH_UL_vgroups_slow(UIList):
+class MESH_UL_vgroups_slow(bpy.types.UIList):
# Constants (flags)
# Be careful not to shadow FILTER_ITEM!
VGROUP_EMPTY = 1 << 0
diff --git a/extern/libmv/CMakeLists.txt b/extern/libmv/CMakeLists.txt
index 2c9a21965f0..80a212b64f8 100644
--- a/extern/libmv/CMakeLists.txt
+++ b/extern/libmv/CMakeLists.txt
@@ -32,15 +32,19 @@ set(INC
set(SRC
libmv-capi.h
+ libmv-capi_intern.h
)
if(WITH_LIBMV)
add_definitions(
-DWITH_LIBMV
+ -DWITH_LIBMV_GUARDED_ALLOC
+ -DGOOGLE_GLOG_DLL_DECL=
)
list(APPEND INC
third_party/ceres/include
+ ../../intern/guardedalloc
)
set(INC_SYS
@@ -224,10 +228,6 @@ if(WITH_LIBMV)
third_party/glog/src
)
endif()
-
- add_definitions(
- -DGOOGLE_GLOG_DLL_DECL=
- )
else()
list(APPEND SRC
libmv-capi_stub.cc
diff --git a/extern/libmv/SConscript b/extern/libmv/SConscript
index f422eb08c58..6926b36f335 100644
--- a/extern/libmv/SConscript
+++ b/extern/libmv/SConscript
@@ -15,6 +15,7 @@ incs = '.'
if env['WITH_BF_LIBMV']:
defs.append('GOOGLE_GLOG_DLL_DECL=')
defs.append('WITH_LIBMV')
+ defs.append('WITH_LIBMV_GUARDED_ALLOC')
src = env.Glob("libmv-capi.cc")
src += env.Glob('libmv/image/*.cc')
@@ -25,7 +26,7 @@ if env['WITH_BF_LIBMV']:
src += env.Glob('third_party/fast/*.c')
src += env.Glob('third_party/gflags/*.cc')
- incs += ' ../Eigen3 third_party/ceres/include'
+ incs += ' ../Eigen3 third_party/ceres/include ../../intern/guardedalloc'
incs += ' ' + env['BF_PNG_INC']
incs += ' ' + env['BF_ZLIB_INC']
diff --git a/extern/libmv/bundle.sh b/extern/libmv/bundle.sh
index 16fb754d30a..57e3598a5ae 100755
--- a/extern/libmv/bundle.sh
+++ b/extern/libmv/bundle.sh
@@ -128,15 +128,19 @@ set(INC
set(SRC
libmv-capi.h
+ libmv-capi_intern.h
)
if(WITH_LIBMV)
add_definitions(
-DWITH_LIBMV
+ -DWITH_LIBMV_GUARDED_ALLOC
+ -DGOOGLE_GLOG_DLL_DECL=
)
list(APPEND INC
third_party/ceres/include
+ ../../intern/guardedalloc
)
set(INC_SYS
@@ -203,10 +207,6 @@ ${third_glog_headers}
third_party/glog/src
)
endif()
-
- add_definitions(
- -DGOOGLE_GLOG_DLL_DECL=
- )
else()
list(APPEND SRC
libmv-capi_stub.cc
@@ -238,11 +238,12 @@ incs = '.'
if env['WITH_BF_LIBMV']:
defs.append('GOOGLE_GLOG_DLL_DECL=')
defs.append('WITH_LIBMV')
+ defs.append('WITH_LIBMV_GUARDED_ALLOC')
src = env.Glob("libmv-capi.cc")
$src
- incs += ' ../Eigen3 third_party/ceres/include'
+ incs += ' ../Eigen3 third_party/ceres/include ../../intern/guardedalloc'
incs += ' ' + env['BF_PNG_INC']
incs += ' ' + env['BF_ZLIB_INC']
diff --git a/extern/libmv/libmv-capi.cc b/extern/libmv/libmv-capi.cc
index a8f396d5df1..11608318a40 100644
--- a/extern/libmv/libmv-capi.cc
+++ b/extern/libmv/libmv-capi.cc
@@ -43,10 +43,10 @@
# include <png.h>
#endif
+#include "libmv-capi_intern.h"
#include "libmv/logging/logging.h"
-
+#include "libmv/multiview/homography.h"
#include "libmv/tracking/track_region.h"
-
#include "libmv/simple_pipeline/callbacks.h"
#include "libmv/simple_pipeline/tracks.h"
#include "libmv/simple_pipeline/initialize_reconstruction.h"
@@ -58,12 +58,6 @@
#include "libmv/simple_pipeline/reconstruction_scale.h"
#include "libmv/simple_pipeline/keyframe_selection.h"
-#include "libmv/multiview/homography.h"
-
-#ifdef _MSC_VER
-# define snprintf _snprintf
-#endif
-
struct libmv_Reconstruction {
libmv::EuclideanReconstruction reconstruction;
@@ -388,14 +382,15 @@ void libmv_samplePlanarPatch(const float *image, int width, int height,
struct libmv_Tracks *libmv_tracksNew(void)
{
- libmv::Tracks *libmv_tracks = new libmv::Tracks();
+ libmv::Tracks *libmv_tracks = LIBMV_OBJECT_NEW(libmv::Tracks);
return (struct libmv_Tracks *)libmv_tracks;
}
void libmv_tracksDestroy(struct libmv_Tracks *libmv_tracks)
{
- delete (libmv::Tracks*) libmv_tracks;
+ using libmv::Tracks;
+ LIBMV_OBJECT_DELETE(libmv_tracks, Tracks);
}
void libmv_tracksInsert(struct libmv_Tracks *libmv_tracks, int image, int track, double x, double y)
@@ -578,7 +573,7 @@ struct libmv_Reconstruction *libmv_solveReconstruction(const struct libmv_Tracks
reconstruct_progress_update_cb progress_update_callback,
void *callback_customdata)
{
- struct libmv_Reconstruction *libmv_reconstruction = new libmv_Reconstruction();
+ struct libmv_Reconstruction *libmv_reconstruction = LIBMV_OBJECT_NEW(libmv_Reconstruction);
libmv::Tracks &tracks = *((libmv::Tracks *) libmv_tracks);
libmv::EuclideanReconstruction &reconstruction = libmv_reconstruction->reconstruction;
@@ -660,7 +655,7 @@ struct libmv_Reconstruction *libmv_solveModal(const struct libmv_Tracks *libmv_t
reconstruct_progress_update_cb progress_update_callback,
void *callback_customdata)
{
- struct libmv_Reconstruction *libmv_reconstruction = new libmv_Reconstruction();
+ struct libmv_Reconstruction *libmv_reconstruction = LIBMV_OBJECT_NEW(libmv_Reconstruction);
libmv::Tracks &tracks = *((libmv::Tracks *) libmv_tracks);
libmv::EuclideanReconstruction &reconstruction = libmv_reconstruction->reconstruction;
@@ -703,7 +698,7 @@ struct libmv_Reconstruction *libmv_solveModal(const struct libmv_Tracks *libmv_t
void libmv_reconstructionDestroy(struct libmv_Reconstruction *libmv_reconstruction)
{
- delete libmv_reconstruction;
+ LIBMV_OBJECT_DELETE(libmv_reconstruction, libmv_Reconstruction);
}
int libmv_reprojectionPointForTrack(const struct libmv_Reconstruction *libmv_reconstruction, int track, double pos[3])
@@ -850,7 +845,7 @@ struct libmv_Features *libmv_detectFeaturesFAST(const unsigned char *data,
{
libmv::Feature *features = NULL;
std::vector<libmv::Feature> v;
- struct libmv_Features *libmv_features = new libmv_Features();
+ struct libmv_Features *libmv_features = LIBMV_STRUCT_NEW(libmv_Features, 1);
int i = 0, count;
if (margin) {
@@ -864,7 +859,7 @@ struct libmv_Features *libmv_detectFeaturesFAST(const unsigned char *data,
count = v.size();
if (count) {
- features = new libmv::Feature[count];
+ features = LIBMV_STRUCT_NEW(libmv::Feature, count);
for(std::vector<libmv::Feature>::iterator it = v.begin(); it != v.end(); it++) {
features[i++] = *it;
@@ -883,7 +878,7 @@ struct libmv_Features *libmv_detectFeaturesMORAVEC(const unsigned char *data,
int margin, int count, int min_distance)
{
libmv::Feature *features = NULL;
- struct libmv_Features *libmv_features = new libmv_Features;
+ struct libmv_Features *libmv_features = LIBMV_STRUCT_NEW(libmv_Features, 1);
if (count) {
if (margin) {
@@ -892,7 +887,7 @@ struct libmv_Features *libmv_detectFeaturesMORAVEC(const unsigned char *data,
height -= 2 * margin;
}
- features = new libmv::Feature[count];
+ features = LIBMV_STRUCT_NEW(libmv::Feature, count);
libmv::DetectMORAVEC(data, stride, width, height, features, &count, min_distance, NULL);
}
@@ -905,10 +900,11 @@ struct libmv_Features *libmv_detectFeaturesMORAVEC(const unsigned char *data,
void libmv_featuresDestroy(struct libmv_Features *libmv_features)
{
- if (libmv_features->features)
- delete [] libmv_features->features;
+ if (libmv_features->features) {
+ LIBMV_STRUCT_DELETE(libmv_features->features);
+ }
- delete libmv_features;
+ LIBMV_STRUCT_DELETE(libmv_features);
}
int libmv_countFeatures(const struct libmv_Features *libmv_features)
@@ -930,14 +926,14 @@ void libmv_getFeature(const struct libmv_Features *libmv_features, int number, d
struct libmv_CameraIntrinsics *libmv_cameraIntrinsicsNewEmpty(void)
{
- libmv::CameraIntrinsics *camera_intrinsics = new libmv::CameraIntrinsics();
+ libmv::CameraIntrinsics *camera_intrinsics = LIBMV_OBJECT_NEW(libmv::CameraIntrinsics);
return (struct libmv_CameraIntrinsics *) camera_intrinsics;
}
struct libmv_CameraIntrinsics *libmv_cameraIntrinsicsNew(const libmv_CameraIntrinsicsOptions *libmv_camera_intrinsics_options)
{
- libmv::CameraIntrinsics *camera_intrinsics = new libmv::CameraIntrinsics();
+ libmv::CameraIntrinsics *camera_intrinsics = LIBMV_OBJECT_NEW(libmv::CameraIntrinsics);
cameraIntrinsicsFromOptions(libmv_camera_intrinsics_options, camera_intrinsics);
@@ -947,16 +943,15 @@ struct libmv_CameraIntrinsics *libmv_cameraIntrinsicsNew(const libmv_CameraIntri
struct libmv_CameraIntrinsics *libmv_cameraIntrinsicsCopy(const libmv_CameraIntrinsics *libmvIntrinsics)
{
libmv::CameraIntrinsics *orig_intrinsics = (libmv::CameraIntrinsics *) libmvIntrinsics;
- libmv::CameraIntrinsics *new_intrinsics = new libmv::CameraIntrinsics(*orig_intrinsics);
+ libmv::CameraIntrinsics *new_intrinsics = LIBMV_OBJECT_NEW(libmv::CameraIntrinsics, *orig_intrinsics);
return (struct libmv_CameraIntrinsics *) new_intrinsics;
}
void libmv_cameraIntrinsicsDestroy(struct libmv_CameraIntrinsics *libmvIntrinsics)
{
- libmv::CameraIntrinsics *intrinsics = (libmv::CameraIntrinsics *) libmvIntrinsics;
-
- delete intrinsics;
+ using libmv::CameraIntrinsics;
+ LIBMV_OBJECT_DELETE(libmvIntrinsics, CameraIntrinsics);
}
void libmv_cameraIntrinsicsUpdate(const libmv_CameraIntrinsicsOptions *libmv_camera_intrinsics_options,
@@ -1082,8 +1077,7 @@ void libmv_cameraIntrinsicsInvert(const libmv_CameraIntrinsicsOptions *libmv_cam
}
}
-void libmv_homography2DFromCorrespondencesLinear(double (*x1)[2], double (*x2)[2], int num_points,
- double H[3][3], double expected_precision)
+void libmv_homography2DFromCorrespondencesEuc(double (*x1)[2], double (*x2)[2], int num_points, double H[3][3])
{
libmv::Mat x1_mat, x2_mat;
libmv::Mat3 H_mat;
@@ -1099,7 +1093,8 @@ void libmv_homography2DFromCorrespondencesLinear(double (*x1)[2], double (*x2)[2
LG << "x1: " << x1_mat;
LG << "x2: " << x2_mat;
- libmv::Homography2DFromCorrespondencesLinear(x1_mat, x2_mat, &H_mat, expected_precision);
+ libmv::HomographyEstimationOptions options;
+ libmv::Homography2DFromCorrespondencesEuc(x1_mat, x2_mat, options, &H_mat);
LG << "H: " << H_mat;
diff --git a/extern/libmv/libmv-capi.h b/extern/libmv/libmv-capi.h
index 37aab2465ed..a872eeb60a1 100644
--- a/extern/libmv/libmv-capi.h
+++ b/extern/libmv/libmv-capi.h
@@ -159,8 +159,7 @@ void libmv_cameraIntrinsicsApply(const libmv_CameraIntrinsicsOptions *libmv_came
void libmv_cameraIntrinsicsInvert(const libmv_CameraIntrinsicsOptions *libmv_camera_intrinsics_options,
double x, double y, double *x1, double *y1);
-void libmv_homography2DFromCorrespondencesLinear(double (*x1)[2], double (*x2)[2], int num_points,
- double H[3][3], double expected_precision);
+void libmv_homography2DFromCorrespondencesEuc(double (*x1)[2], double (*x2)[2], int num_points, double H[3][3]);
#ifdef __cplusplus
}
diff --git a/extern/libmv/libmv-capi_intern.h b/extern/libmv/libmv-capi_intern.h
new file mode 100644
index 00000000000..90087c52a6c
--- /dev/null
+++ b/extern/libmv/libmv-capi_intern.h
@@ -0,0 +1,59 @@
+/*
+ * ***** 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) 2013 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef LIBMV_C_API_INTERN_H
+#define LIBMV_C_API_INTERN_H
+
+#if defined(_MSC_VER)
+# define __func__ __FUNCTION__
+# define snprintf _snprintf
+#endif
+
+#ifdef WITH_LIBMV_GUARDED_ALLOC
+# include "MEM_guardedalloc.h"
+# define LIBMV_OBJECT_NEW OBJECT_GUARDED_NEW
+# define LIBMV_OBJECT_DELETE OBJECT_GUARDED_DELETE
+# define LIBMV_OBJECT_DELETE OBJECT_GUARDED_DELETE
+# define LIBMV_STRUCT_NEW(type, count) (type*)MEM_mallocN(sizeof(type) * count, __func__)
+# define LIBMV_STRUCT_DELETE(what) MEM_freeN(what)
+#else
+// Need this to keep libmv-capi potentially standalone.
+# if defined __GNUC__ || defined __sun
+# define LIBMV_OBJECT_NEW(type, args ...) \
+ new(malloc(sizeof(type))) type(args)
+# else
+# define LIBMV_OBJECT_NEW(type, ...) \
+ new(malloc(sizeof(type))) type(__VA_ARGS__)
+#endif
+# define LIBMV_OBJECT_DELETE(what, type) \
+ { if(what) { \
+ ((type*)(what))->~type(); \
+ free(what); \
+ } } (void)0
+# define LIBMV_STRUCT_NEW(type, count) (type*)malloc(sizeof(type) * count)
+# define LIBMV_STRUCT_DELETE(what) { if (what) free(what); } (void)0
+#endif
+
+#endif // LIBMV_C_API_INTERN_H
diff --git a/extern/libmv/libmv-capi_stub.cc b/extern/libmv/libmv-capi_stub.cc
index 4896f4c6949..e6d3753961b 100644
--- a/extern/libmv/libmv-capi_stub.cc
+++ b/extern/libmv/libmv-capi_stub.cc
@@ -277,8 +277,8 @@ void libmv_cameraIntrinsicsInvert(const libmv_CameraIntrinsicsOptions *libmv_cam
*y1 = (y - principal_y) / focal_length;
}
-void libmv_homography2DFromCorrespondencesLinear(double (* /* x1 */)[2], double (* /* x2 */)[2], int /* num_points */,
- double H[3][3], double /* expected_precision */)
+void libmv_homography2DFromCorrespondencesEuc(double (* /* x1 */)[2], double (* /* x2 */)[2], int /* num_points */,
+ double H[3][3])
{
memset(H, 0, sizeof(double[3][3]));
H[0][0] = 1.0f;
diff --git a/extern/libmv/libmv/multiview/fundamental.cc b/extern/libmv/libmv/multiview/fundamental.cc
index a05ef7907a2..ec6c70d81cf 100644
--- a/extern/libmv/libmv/multiview/fundamental.cc
+++ b/extern/libmv/libmv/multiview/fundamental.cc
@@ -20,6 +20,7 @@
#include "libmv/multiview/fundamental.h"
+#include "ceres/ceres.h"
#include "libmv/logging/logging.h"
#include "libmv/numeric/numeric.h"
#include "libmv/numeric/poly.h"
@@ -407,4 +408,94 @@ void FundamentalToEssential(const Mat3 &F, Mat3 *E) {
*E = svd.matrixU() * diag.asDiagonal() * svd.matrixV().transpose();
}
+FundamentalEstimationOptions::FundamentalEstimationOptions(void) :
+ use_refine_if_algebraic_fails(true),
+ max_num_iterations(50),
+ parameter_tolerance(1e-16),
+ function_tolerance(1e-16) {
+}
+
+class FundamentalSymmetricEpipolarCostFunctor {
+ public:
+ FundamentalSymmetricEpipolarCostFunctor(const Vec2 &x,
+ const Vec2 &y)
+ : x_(x), y_(y) {}
+
+ template<typename T>
+ bool operator()(const T *fundamental_parameters, T *residuals) const {
+ typedef Eigen::Matrix<T, 3, 3> Mat3;
+ typedef Eigen::Matrix<T, 3, 1> Vec3;
+
+ Mat3 F(fundamental_parameters);
+
+ Vec3 x(T(x_(0)), T(x_(1)), T(1.0));
+ Vec3 y(T(y_(0)), T(y_(1)), T(1.0));
+
+ Vec3 F_x = F * x;
+ Vec3 Ft_y = F.transpose() * y;
+ T y_F_x = y.dot(F_x);
+
+ residuals[0] = y_F_x * T(1) / F_x.head(2).norm();
+ residuals[1] = y_F_x * T(1) / Ft_y.head(2).norm();
+
+ return true;
+ }
+
+ const Mat x_;
+ const Mat y_;
+};
+
+/* Fundamental transformation estimation. */
+bool FundamentalFromCorrespondencesEuc(
+ const Mat &x1,
+ const Mat &x2,
+ const FundamentalEstimationOptions &options,
+ Mat3 *F) {
+ // Step 1: Algebraic fundamental estimation.
+ bool algebraic_success = NormalizedEightPointSolver(x1, x2, F);
+
+ LG << "Algebraic result " << algebraic_success
+ << ", estimated matrix:\n" << *F;
+
+ if (!algebraic_success && !options.use_refine_if_algebraic_fails) {
+ return false;
+ }
+
+ // Step 2: Refine matrix using Ceres minimizer.
+ ceres::Problem problem;
+ for (int i = 0; i < x1.cols(); i++) {
+ FundamentalSymmetricEpipolarCostFunctor
+ *fundamental_symmetric_epipolar_cost_function =
+ new FundamentalSymmetricEpipolarCostFunctor(x1.col(i),
+ x2.col(i));
+
+ problem.AddResidualBlock(
+ new ceres::AutoDiffCostFunction<
+ FundamentalSymmetricEpipolarCostFunctor,
+ 2, // num_residuals
+ 9>(fundamental_symmetric_epipolar_cost_function),
+ NULL,
+ F->data());
+ }
+
+ // Configure the solve.
+ ceres::Solver::Options solver_options;
+ solver_options.linear_solver_type = ceres::DENSE_QR;
+ solver_options.max_num_iterations = options.max_num_iterations;
+ solver_options.update_state_every_iteration = true;
+ solver_options.parameter_tolerance = options.parameter_tolerance;
+ solver_options.function_tolerance = options.function_tolerance;
+
+ // Run the solve.
+ ceres::Solver::Summary summary;
+ ceres::Solve(solver_options, &problem, &summary);
+
+ VLOG(1) << "Summary:\n" << summary.FullReport();
+
+ LG << "Final refined matrix:\n" << *F;
+
+ return !(summary.termination_type == ceres::DID_NOT_RUN ||
+ summary.termination_type == ceres::NUMERICAL_FAILURE);
+}
+
} // namespace libmv
diff --git a/extern/libmv/libmv/multiview/fundamental.h b/extern/libmv/libmv/multiview/fundamental.h
index 1ad184d8314..2961a46cdc4 100644
--- a/extern/libmv/libmv/multiview/fundamental.h
+++ b/extern/libmv/libmv/multiview/fundamental.h
@@ -144,6 +144,43 @@ bool MotionFromEssentialAndCorrespondence(const Mat3 &E,
*/
void FundamentalToEssential(const Mat3 &F, Mat3 *E);
+/**
+ * This structure contains options that controls how the fundamental
+ * estimation operates.
+ *
+ * Defaults should be suitable for a wide range of use cases, but
+ * better performance and accuracy might require tweaking/
+ */
+struct FundamentalEstimationOptions {
+ // Default constructor which sets up a options for generic usage.
+ FundamentalEstimationOptions(void);
+
+ // Refine fundamental matrix even if algebraic estimation reported failure.
+ bool use_refine_if_algebraic_fails;
+
+ // Maximal number of iterations for refinement step.
+ int max_num_iterations;
+
+ // Paramaneter tolerance used by minimizer termination criteria.
+ float parameter_tolerance;
+
+ // Function tolerance used by minimizer termination criteria.
+ float function_tolerance;
+};
+
+/**
+ * Fundamental transformation estimation.
+ *
+ * This function estimates the fundamental transformation from a list of 2D
+ * correspondences by doing algebraic estimation first followed with result
+ * refinement.
+ */
+bool FundamentalFromCorrespondencesEuc(
+ const Mat &x1,
+ const Mat &x2,
+ const FundamentalEstimationOptions &options,
+ Mat3 *F);
+
} // namespace libmv
#endif // LIBMV_MULTIVIEW_FUNDAMENTAL_H_
diff --git a/extern/libmv/libmv/multiview/homography.cc b/extern/libmv/libmv/multiview/homography.cc
index 317eb3f85c6..6041849d9fe 100644
--- a/extern/libmv/libmv/multiview/homography.cc
+++ b/extern/libmv/libmv/multiview/homography.cc
@@ -20,6 +20,7 @@
#include "libmv/multiview/homography.h"
+#include "ceres/ceres.h"
#include "libmv/logging/logging.h"
#include "libmv/multiview/homography_parameterization.h"
@@ -153,6 +154,116 @@ bool Homography2DFromCorrespondencesLinear(const Mat &x1,
return false;
}
}
+
+HomographyEstimationOptions::HomographyEstimationOptions(void) :
+ expected_algebraic_precision(EigenDouble::dummy_precision()),
+ use_refine_if_algebraic_fails(true),
+ max_num_iterations(50),
+ parameter_tolerance(1e-16),
+ function_tolerance(1e-16) {
+}
+
+class HomographySymmetricGeometricCostFunctor {
+ public:
+ HomographySymmetricGeometricCostFunctor(const Vec2 &x,
+ const Vec2 &y)
+ : x_(x), y_(y) { }
+
+ template<typename T>
+ bool operator()(const T *homography_parameters, T *residuals) const {
+ typedef Eigen::Matrix<T, 3, 3> Mat3;
+ typedef Eigen::Matrix<T, 3, 1> Vec3;
+
+ Mat3 H(homography_parameters);
+
+ Vec3 x(T(x_(0)), T(x_(1)), T(1.0));
+ Vec3 y(T(y_(0)), T(y_(1)), T(1.0));
+
+ Vec3 H_x = H * x;
+ Vec3 Hinv_y = H.inverse() * y;
+
+ H_x /= H_x(2);
+ Hinv_y /= Hinv_y(2);
+
+ // This is a forward error.
+ residuals[0] = H_x(0) - T(y_(0));
+ residuals[1] = H_x(1) - T(y_(1));
+
+ // This is a backward error.
+ residuals[2] = Hinv_y(0) - T(x_(0));
+ residuals[3] = Hinv_y(1) - T(x_(1));
+
+ return true;
+ }
+
+ const Vec2 x_;
+ const Vec2 y_;
+};
+
+/** 2D Homography transformation estimation in the case that points are in
+ * euclidean coordinates.
+ */
+bool Homography2DFromCorrespondencesEuc(
+ const Mat &x1,
+ const Mat &x2,
+ const HomographyEstimationOptions &options,
+ Mat3 *H) {
+ // TODO(sergey): Support homogenous coordinates, not just euclidean.
+
+ assert(2 == x1.rows());
+ assert(4 <= x1.cols());
+ assert(x1.rows() == x2.rows());
+ assert(x1.cols() == x2.cols());
+
+ // Step 1: Algebraic homography estimation.
+ bool algebraic_success =
+ Homography2DFromCorrespondencesLinear(x1, x2, H,
+ options.expected_algebraic_precision);
+
+ LG << "Algebraic result " << algebraic_success
+ << ", estimated matrix:\n" << *H;
+
+ if (!algebraic_success && !options.use_refine_if_algebraic_fails) {
+ return false;
+ }
+
+ // Step 2: Refine matrix using Ceres minimizer.
+ ceres::Problem problem;
+ for (int i = 0; i < x1.cols(); i++) {
+ HomographySymmetricGeometricCostFunctor
+ *homography_symmetric_geometric_cost_function =
+ new HomographySymmetricGeometricCostFunctor(x1.col(i),
+ x2.col(i));
+
+ problem.AddResidualBlock(
+ new ceres::AutoDiffCostFunction<
+ HomographySymmetricGeometricCostFunctor,
+ 4, // num_residuals
+ 9>(homography_symmetric_geometric_cost_function),
+ NULL,
+ H->data());
+ }
+
+ // Configure the solve.
+ ceres::Solver::Options solver_options;
+ solver_options.linear_solver_type = ceres::DENSE_QR;
+ solver_options.max_num_iterations = options.max_num_iterations;
+ solver_options.update_state_every_iteration = true;
+ solver_options.parameter_tolerance = options.parameter_tolerance;
+ solver_options.function_tolerance = options.function_tolerance;
+
+ // Run the solve.
+ ceres::Solver::Summary summary;
+ ceres::Solve(solver_options, &problem, &summary);
+
+ VLOG(1) << "Summary:\n" << summary.FullReport();
+
+ LG << "Final refined matrix:\n" << *H;
+
+ return !(summary.termination_type == ceres::DID_NOT_RUN ||
+ summary.termination_type == ceres::NUMERICAL_FAILURE);
+}
+
/**
* x2 ~ A * x1
* x2^t * Hi * A *x1 = 0
diff --git a/extern/libmv/libmv/multiview/homography.h b/extern/libmv/libmv/multiview/homography.h
index 8d2dff930eb..1928e39dffb 100644
--- a/extern/libmv/libmv/multiview/homography.h
+++ b/extern/libmv/libmv/multiview/homography.h
@@ -54,6 +54,45 @@ bool Homography2DFromCorrespondencesLinear(const Mat &x1,
EigenDouble::dummy_precision());
/**
+ * This structure contains options that controls how the homography
+ * estimation operates.
+ *
+ * Defaults should be suitable for a wide range of use cases, but
+ * better performance and accuracy might require tweaking/
+ */
+struct HomographyEstimationOptions {
+ // Default constructor which sets up a options for generic usage.
+ HomographyEstimationOptions(void);
+
+ // Expected precision of algebraic estimation.
+ double expected_algebraic_precision;
+
+ // Refine homography even if algebraic estimation reported failure.
+ bool use_refine_if_algebraic_fails;
+
+ // Maximal number of iterations for refinement step.
+ int max_num_iterations;
+
+ // Paramaneter tolerance used by minimizer termination criteria.
+ float parameter_tolerance;
+
+ // Function tolerance used by minimizer termination criteria.
+ float function_tolerance;
+};
+
+/**
+ * 2D homography transformation estimation.
+ *
+ * This function estimates the homography transformation from a list of 2D
+ * correspondences by doing algebraic estimation first followed with result
+ * refinement.
+ */
+bool Homography2DFromCorrespondencesEuc(const Mat &x1,
+ const Mat &x2,
+ const HomographyEstimationOptions &options,
+ Mat3 *H);
+
+/**
* 3D Homography transformation estimation.
*
* This function can be used in order to estimate the homography transformation
diff --git a/extern/libmv/libmv/simple_pipeline/keyframe_selection.cc b/extern/libmv/libmv/simple_pipeline/keyframe_selection.cc
index 976adb288b3..d4ddee56fda 100644
--- a/extern/libmv/libmv/simple_pipeline/keyframe_selection.cc
+++ b/extern/libmv/libmv/simple_pipeline/keyframe_selection.cc
@@ -61,161 +61,6 @@ Mat3 IntrinsicsNormalizationMatrix(const CameraIntrinsics &intrinsics) {
return S * T;
}
-class HomographySymmetricGeometricCostFunctor {
- public:
- HomographySymmetricGeometricCostFunctor(const Vec2 &x,
- const Vec2 &y)
- : x_(x), y_(y) { }
-
- template<typename T>
- bool operator()(const T *homography_parameters, T *residuals) const {
- typedef Eigen::Matrix<T, 3, 3> Mat3;
- typedef Eigen::Matrix<T, 3, 1> Vec3;
-
- Mat3 H(homography_parameters);
-
- Vec3 x(T(x_(0)), T(x_(1)), T(1.0));
- Vec3 y(T(y_(0)), T(y_(1)), T(1.0));
-
- Vec3 H_x = H * x;
- Vec3 Hinv_y = H.inverse() * y;
-
- H_x /= H_x(2);
- Hinv_y /= Hinv_y(2);
-
- residuals[0] = H_x(0) - T(y_(0));
- residuals[1] = H_x(1) - T(y_(1));
-
- residuals[2] = Hinv_y(0) - T(x_(0));
- residuals[3] = Hinv_y(1) - T(x_(1));
-
- return true;
- }
-
- const Vec2 x_;
- const Vec2 y_;
-};
-
-void ComputeHomographyFromCorrespondences(const Mat &x1, const Mat &x2,
- CameraIntrinsics &intrinsics,
- Mat3 *H) {
- // Algebraic homography estimation, happens with normalized coordinates
- Homography2DFromCorrespondencesLinear(x1, x2, H, 1e-12);
-
- // Refine matrix using Ceres minimizer
-
- // TODO(sergey): look into refinement in pixel space.
- ceres::Problem problem;
-
- for (int i = 0; i < x1.cols(); i++) {
- HomographySymmetricGeometricCostFunctor
- *homography_symmetric_geometric_cost_function =
- new HomographySymmetricGeometricCostFunctor(x1.col(i),
- x2.col(i));
-
- problem.AddResidualBlock(
- new ceres::AutoDiffCostFunction<
- HomographySymmetricGeometricCostFunctor,
- 4, /* num_residuals */
- 9>(homography_symmetric_geometric_cost_function),
- NULL,
- H->data());
- }
-
- // Configure the solve.
- ceres::Solver::Options solver_options;
- solver_options.linear_solver_type = ceres::DENSE_QR;
- solver_options.max_num_iterations = 50;
- solver_options.update_state_every_iteration = true;
- solver_options.parameter_tolerance = 1e-16;
- solver_options.function_tolerance = 1e-16;
-
- // Run the solve.
- ceres::Solver::Summary summary;
- ceres::Solve(solver_options, &problem, &summary);
-
- VLOG(1) << "Summary:\n" << summary.FullReport();
-
- // Convert homography to original pixel space
- Mat3 N = IntrinsicsNormalizationMatrix(intrinsics);
- *H = N.inverse() * (*H) * N;
-}
-
-class FundamentalSymmetricEpipolarCostFunctor {
- public:
- FundamentalSymmetricEpipolarCostFunctor(const Vec2 &x,
- const Vec2 &y)
- : x_(x), y_(y) {}
-
- template<typename T>
- bool operator()(const T *fundamental_parameters, T *residuals) const {
- typedef Eigen::Matrix<T, 3, 3> Mat3;
- typedef Eigen::Matrix<T, 3, 1> Vec3;
-
- Mat3 F(fundamental_parameters);
-
- Vec3 x(T(x_(0)), T(x_(1)), T(1.0));
- Vec3 y(T(y_(0)), T(y_(1)), T(1.0));
-
- Vec3 F_x = F * x;
- Vec3 Ft_y = F.transpose() * y;
- T y_F_x = y.dot(F_x);
-
- residuals[0] = y_F_x * T(1) / F_x.head(2).norm();
- residuals[1] = y_F_x * T(1) / Ft_y.head(2).norm();
-
- return true;
- }
-
- const Mat x_;
- const Mat y_;
-};
-
-void ComputeFundamentalFromCorrespondences(const Mat &x1, const Mat &x2,
- CameraIntrinsics &intrinsics,
- Mat3 *F) {
- // Algebraic fundamental estimation, happens with normalized coordinates
- NormalizedEightPointSolver(x1, x2, F);
-
- // Refine matrix using Ceres minimizer
-
- // TODO(sergey): look into refinement in pixel space.
- ceres::Problem problem;
-
- for (int i = 0; i < x1.cols(); i++) {
- FundamentalSymmetricEpipolarCostFunctor
- *fundamental_symmetric_epipolar_cost_function =
- new FundamentalSymmetricEpipolarCostFunctor(x1.col(i),
- x2.col(i));
-
- problem.AddResidualBlock(
- new ceres::AutoDiffCostFunction<
- FundamentalSymmetricEpipolarCostFunctor,
- 2, /* num_residuals */
- 9>(fundamental_symmetric_epipolar_cost_function),
- NULL,
- F->data());
- }
-
- // Configure the solve.
- ceres::Solver::Options solver_options;
- solver_options.linear_solver_type = ceres::DENSE_NORMAL_CHOLESKY;
- solver_options.max_num_iterations = 50;
- solver_options.update_state_every_iteration = true;
- solver_options.parameter_tolerance = 1e-16;
- solver_options.function_tolerance = 1e-16;
-
- // Run the solve.
- ceres::Solver::Summary summary;
- ceres::Solve(solver_options, &problem, &summary);
-
- VLOG(1) << "Summary:\n" << summary.FullReport();
-
- // Convert fundamental to original pixel space
- Mat3 N = IntrinsicsNormalizationMatrix(intrinsics);
- *F = N.inverse() * (*F) * N;
-}
-
// P.H.S. Torr
// Geometric Motion Segmentation and Model Selection
//
@@ -360,8 +205,25 @@ void SelectKeyframesBasedOnGRICAndVariance(const Tracks &tracks,
continue;
Mat3 H, F;
- ComputeHomographyFromCorrespondences(x1, x2, intrinsics, &H);
- ComputeFundamentalFromCorrespondences(x1, x2, intrinsics, &F);
+
+ // Estimate homography using default options.
+ HomographyEstimationOptions homography_estimation_options;
+ Homography2DFromCorrespondencesEuc(x1,
+ x2,
+ homography_estimation_options,
+ &H);
+
+ // Convert homography to original pixel space.
+ H = N_inverse * H * N;
+
+ FundamentalEstimationOptions fundamental_estimation_options;
+ FundamentalFromCorrespondencesEuc(x1,
+ x2,
+ fundamental_estimation_options,
+ &F);
+
+ // Convert fundamental to original pixel space.
+ F = N_inverse * F * N;
// TODO(sergey): STEP 2: Discard outlier matches
diff --git a/extern/libmv/third_party/msinttypes/stdint.h b/extern/libmv/third_party/msinttypes/stdint.h
index e236bb00015..189ee34571c 100644
--- a/extern/libmv/third_party/msinttypes/stdint.h
+++ b/extern/libmv/third_party/msinttypes/stdint.h
@@ -72,16 +72,16 @@ extern "C" {
// realize that, e.g. char has the same size as __int8
// so we give up on __intX for them.
#if (_MSC_VER < 1300)
- typedef char int8_t;
- typedef short int16_t;
- typedef int int32_t;
+ typedef signed char int8_t;
+ typedef signed short int16_t;
+ typedef signed int int32_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
#else
- typedef __int8 int8_t;
- typedef __int16 int16_t;
- typedef __int32 int32_t;
+ typedef signed __int8 int8_t;
+ typedef signed __int16 int16_t;
+ typedef signed __int32 int32_t;
typedef unsigned __int8 uint8_t;
typedef unsigned __int16 uint16_t;
typedef unsigned __int32 uint32_t;
diff --git a/intern/cycles/blender/CMakeLists.txt b/intern/cycles/blender/CMakeLists.txt
index 9b72efd90cf..25f91a0caea 100644
--- a/intern/cycles/blender/CMakeLists.txt
+++ b/intern/cycles/blender/CMakeLists.txt
@@ -45,6 +45,8 @@ set(ADDON_FILES
addon/ui.py
)
+add_definitions(-DGLEW_STATIC)
+
blender_add_lib(bf_intern_cycles "${SRC}" "${INC}" "${INC_SYS}")
add_dependencies(bf_intern_cycles bf_rna)
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py
index 5fa497776fe..7a03df4f35a 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -1085,6 +1085,8 @@ class CyclesTexture_PT_mapping(CyclesButtonsPanel, Panel):
mapping = node.texture_mapping
+ layout.prop(mapping, "vector_type", expand=True)
+
row = layout.row()
row.column().prop(mapping, "translation")
@@ -1178,7 +1180,7 @@ class CyclesRender_PT_CurveRendering(CyclesButtonsPanel, Panel):
scene = context.scene
cscene = scene.cycles
psys = context.particle_system
- return CyclesButtonsPanel.poll(context) and psys
+ return CyclesButtonsPanel.poll(context) and psys and psys.settings.type == 'HAIR'
def draw_header(self, context):
ccscene = context.scene.cycles_curves
@@ -1218,8 +1220,9 @@ class CyclesParticle_PT_CurveSettings(CyclesButtonsPanel, Panel):
scene = context.scene
cscene = scene.cycles
ccscene = scene.cycles_curves
- use_curves = ccscene.use_curves and context.particle_system
- return CyclesButtonsPanel.poll(context) and use_curves
+ psys = context.particle_system
+ use_curves = ccscene.use_curves and psys
+ return CyclesButtonsPanel.poll(context) and use_curves and psys.settings.type == 'HAIR'
def draw(self, context):
layout = self.layout
diff --git a/intern/cycles/blender/blender_curves.cpp b/intern/cycles/blender/blender_curves.cpp
index 57ef9a1005c..1cddc25a22b 100644
--- a/intern/cycles/blender/blender_curves.cpp
+++ b/intern/cycles/blender/blender_curves.cpp
@@ -217,8 +217,8 @@ bool ObtainCacheParticleData(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Par
float3 pcKey;
for(int step_no = 0; step_no <= ren_step; step_no++) {
float nco[3];
- b_psys.co_hair(*b_ob, psmd, pa_no, step_no, nco);
- float3 cKey = make_float3(nco[0],nco[1],nco[2]);
+ b_psys.co_hair(*b_ob, pa_no, step_no, nco);
+ float3 cKey = make_float3(nco[0], nco[1], nco[2]);
cKey = transform_point(&itfm, cKey);
if(step_no > 0)
curve_length += len(cKey - pcKey);
diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp
index caa61e0c5d7..940a923e5af 100644
--- a/intern/cycles/blender/blender_mesh.cpp
+++ b/intern/cycles/blender/blender_mesh.cpp
@@ -480,7 +480,7 @@ Mesh *BlenderSync::sync_mesh(BL::Object b_ob, bool object_updated, bool hide_tri
BL::Mesh b_mesh = object_to_mesh(b_data, b_ob, b_scene, true, !preview, need_undeformed);
if(b_mesh) {
- if(render_layer.use_surfaces && !(hide_tris && experimental)) {
+ if(render_layer.use_surfaces && !hide_tris) {
if(cmesh.data && experimental && RNA_boolean_get(&cmesh, "use_subdivision"))
create_subd_mesh(mesh, b_mesh, &cmesh, used_shaders);
else
diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp
index 2007171642f..b576181d890 100644
--- a/intern/cycles/blender/blender_shader.cpp
+++ b/intern/cycles/blender/blender_shader.cpp
@@ -147,6 +147,7 @@ static void get_tex_mapping(TextureMapping *mapping, BL::TexMapping b_mapping)
mapping->translation = get_float3(b_mapping.translation());
mapping->rotation = get_float3(b_mapping.rotation());
mapping->scale = get_float3(b_mapping.scale());
+ mapping->type = (TextureMapping::Type)b_mapping.vector_type();
mapping->x_mapping = (TextureMapping::Mapping)b_mapping.mapping_x();
mapping->y_mapping = (TextureMapping::Mapping)b_mapping.mapping_y();
@@ -161,6 +162,7 @@ static void get_tex_mapping(TextureMapping *mapping, BL::ShaderNodeMapping b_map
mapping->translation = get_float3(b_mapping.translation());
mapping->rotation = get_float3(b_mapping.rotation());
mapping->scale = get_float3(b_mapping.scale());
+ mapping->type = (TextureMapping::Type)b_mapping.vector_type();
mapping->use_minmax = b_mapping.use_min() || b_mapping.use_max();
@@ -320,9 +322,6 @@ static ShaderNode *add_node(Scene *scene, BL::BlendData b_data, BL::Scene b_scen
SubsurfaceScatteringNode *subsurface = new SubsurfaceScatteringNode();
switch(b_subsurface_node.falloff()) {
- case BL::ShaderNodeSubsurfaceScattering::falloff_COMPATIBLE:
- subsurface->closure = CLOSURE_BSSRDF_COMPATIBLE_ID;
- break;
case BL::ShaderNodeSubsurfaceScattering::falloff_CUBIC:
subsurface->closure = CLOSURE_BSSRDF_CUBIC_ID;
break;
diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp
index 337d075cce4..a349ddc5c3f 100644
--- a/intern/cycles/blender/blender_sync.cpp
+++ b/intern/cycles/blender/blender_sync.cpp
@@ -34,6 +34,7 @@
#include "util_debug.h"
#include "util_foreach.h"
+#include "util_opengl.h"
CCL_NAMESPACE_BEGIN
@@ -494,7 +495,7 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine b_engine, BL::Use
params.shadingsystem = SessionParams::OSL;
/* color managagement */
- params.display_buffer_linear = b_engine.support_display_space_shader(b_scene);
+ params.display_buffer_linear = GLEW_ARB_half_float_pixel && b_engine.support_display_space_shader(b_scene);
return params;
}
diff --git a/intern/cycles/device/device.cpp b/intern/cycles/device/device.cpp
index 10d4112b57d..eb262a907a4 100644
--- a/intern/cycles/device/device.cpp
+++ b/intern/cycles/device/device.cpp
@@ -56,18 +56,6 @@ void Device::draw_pixels(device_memory& rgba, int y, int w, int h, int dy, int w
{
pixels_copy_from(rgba, y, w, h);
- GLuint texid;
- glGenTextures(1, &texid);
- glBindTexture(GL_TEXTURE_2D, texid);
- if(rgba.data_type == TYPE_HALF)
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F_ARB, w, h, 0, GL_RGBA, GL_HALF_FLOAT, (void*)rgba.data_pointer);
- else
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, (void*)rgba.data_pointer);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-
- glEnable(GL_TEXTURE_2D);
-
if(transparent) {
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
@@ -75,30 +63,57 @@ void Device::draw_pixels(device_memory& rgba, int y, int w, int h, int dy, int w
glColor3f(1.0f, 1.0f, 1.0f);
- glPushMatrix();
- glTranslatef(0.0f, (float)dy, 0.0f);
+ if(rgba.data_type == TYPE_HALF) {
+ /* draw half float texture, GLSL shader for display transform assumed to be bound */
+ GLuint texid;
+ glGenTextures(1, &texid);
+ glBindTexture(GL_TEXTURE_2D, texid);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F_ARB, w, h, 0, GL_RGBA, GL_HALF_FLOAT, (void*)rgba.data_pointer);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glBegin(GL_QUADS);
-
- glTexCoord2f(0.0f, 0.0f);
- glVertex2f(0.0f, 0.0f);
- glTexCoord2f(1.0f, 0.0f);
- glVertex2f((float)width, 0.0f);
- glTexCoord2f(1.0f, 1.0f);
- glVertex2f((float)width, (float)height);
- glTexCoord2f(0.0f, 1.0f);
- glVertex2f(0.0f, (float)height);
+ glEnable(GL_TEXTURE_2D);
+
+ glPushMatrix();
+ glTranslatef(0.0f, (float)dy, 0.0f);
+
+ glBegin(GL_QUADS);
+
+ glTexCoord2f(0.0f, 0.0f);
+ glVertex2f(0.0f, 0.0f);
+ glTexCoord2f(1.0f, 0.0f);
+ glVertex2f((float)width, 0.0f);
+ glTexCoord2f(1.0f, 1.0f);
+ glVertex2f((float)width, (float)height);
+ glTexCoord2f(0.0f, 1.0f);
+ glVertex2f(0.0f, (float)height);
- glEnd();
+ glEnd();
- glPopMatrix();
+ glPopMatrix();
+
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glDisable(GL_TEXTURE_2D);
+ glDeleteTextures(1, &texid);
+ }
+ else {
+ /* fallback for old graphics cards that don't support GLSL, half float,
+ * and non-power-of-two textures */
+ glPixelZoom((float)width/(float)w, (float)height/(float)h);
+ glRasterPos2f(0, dy);
+
+ uint8_t *pixels = (uint8_t*)rgba.data_pointer;
+
+ pixels += 4*y*w;
+
+ glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
+
+ glRasterPos2f(0.0f, 0.0f);
+ glPixelZoom(1.0f, 1.0f);
+ }
if(transparent)
glDisable(GL_BLEND);
-
- glBindTexture(GL_TEXTURE_2D, 0);
- glDisable(GL_TEXTURE_2D);
- glDeleteTextures(1, &texid);
}
Device *Device::create(DeviceInfo& info, Stats &stats, bool background)
diff --git a/intern/cycles/device/device_cuda.cpp b/intern/cycles/device/device_cuda.cpp
index b5eaa69bf0e..4ce7f6fd729 100644
--- a/intern/cycles/device/device_cuda.cpp
+++ b/intern/cycles/device/device_cuda.cpp
@@ -43,7 +43,9 @@ public:
CUmodule cuModule;
map<device_ptr, bool> tex_interp_map;
int cuDevId;
+ int cuDevArchitecture;
bool first_error;
+ bool use_texture_storage;
struct PixelMem {
GLuint cuPBO;
@@ -173,6 +175,7 @@ public:
{
first_error = true;
background = background_;
+ use_texture_storage = true;
cuDevId = info.num;
cuDevice = 0;
@@ -203,6 +206,15 @@ public:
if(cuda_error_(result, "cuCtxCreate"))
return;
+ int major, minor;
+ cuDeviceComputeCapability(&major, &minor, cuDevId);
+ cuDevArchitecture = major*100 + minor*10;
+
+ /* In order to use full 6GB of memory on Titan cards, use arrays instead
+ * of textures. On earlier cards this seems slower, but on Titan it is
+ * actually slightly faster in tests. */
+ use_texture_storage = (cuDevArchitecture < 350);
+
cuda_pop_context();
}
@@ -210,20 +222,17 @@ public:
{
task_pool.stop();
- cuda_push_context();
- cuda_assert(cuCtxDetach(cuContext))
+ cuda_assert(cuCtxDestroy(cuContext))
}
bool support_device(bool experimental)
{
- if(!experimental) {
- int major, minor;
- cuDeviceComputeCapability(&major, &minor, cuDevId);
+ int major, minor;
+ cuDeviceComputeCapability(&major, &minor, cuDevId);
- if(major < 2) {
- cuda_error_message(string_printf("CUDA device supported only with compute capability 2.0 or up, found %d.%d.", major, minor));
- return false;
- }
+ if(major < 2) {
+ cuda_error_message(string_printf("CUDA device supported only with compute capability 2.0 or up, found %d.%d.", major, minor));
+ return false;
}
return true;
@@ -275,8 +284,12 @@ public:
cuda_error_message("CUDA nvcc compiler version could not be parsed.");
return "";
}
+ if(cuda_version < 50) {
+ printf("Unsupported CUDA version %d.%d detected, you need CUDA 5.0.\n", cuda_version/10, cuda_version%10);
+ return "";
+ }
- if(cuda_version != 50)
+ else if(cuda_version > 50)
printf("CUDA version %d.%d detected, build may succeed but only CUDA 5.0 is officially supported.\n", cuda_version/10, cuda_version%10);
/* compile */
@@ -285,36 +298,14 @@ public:
const int machine = system_cpu_bits();
string arch_flags;
- /* build flags depending on CUDA version and arch */
- if(cuda_version < 50) {
- /* CUDA 4.x */
- if(major == 1) {
- /* sm_1x */
- arch_flags = "--maxrregcount=24 --opencc-options -OPT:Olimit=0";
- }
- else if(major == 2) {
- /* sm_2x */
- arch_flags = "--maxrregcount=24";
- }
- else {
- /* sm_3x */
- arch_flags = "--maxrregcount=32";
- }
+ /* CUDA 5.x build flags for different archs */
+ if(major == 2) {
+ /* sm_2x */
+ arch_flags = "--maxrregcount=32 --use_fast_math";
}
- else {
- /* CUDA 5.x */
- if(major == 1) {
- /* sm_1x */
- arch_flags = "--maxrregcount=24 --opencc-options -OPT:Olimit=0 --use_fast_math";
- }
- else if(major == 2) {
- /* sm_2x */
- arch_flags = "--maxrregcount=32 --use_fast_math";
- }
- else {
- /* sm_3x */
- arch_flags = "--maxrregcount=32 --use_fast_math";
- }
+ else if(major == 3) {
+ /* sm_3x */
+ arch_flags = "--maxrregcount=32 --use_fast_math";
}
double starttime = time_dt();
@@ -448,90 +439,118 @@ public:
CUarray_format_enum format;
size_t dsize = datatype_size(mem.data_type);
size_t size = mem.memory_size();
+ bool use_texture = interpolation || use_texture_storage;
- switch(mem.data_type) {
- case TYPE_UCHAR: format = CU_AD_FORMAT_UNSIGNED_INT8; break;
- case TYPE_UINT: format = CU_AD_FORMAT_UNSIGNED_INT32; break;
- case TYPE_INT: format = CU_AD_FORMAT_SIGNED_INT32; break;
- case TYPE_FLOAT: format = CU_AD_FORMAT_FLOAT; break;
- default: assert(0); return;
- }
-
- CUtexref texref = NULL;
-
- cuda_push_context();
- cuda_assert(cuModuleGetTexRef(&texref, cuModule, name))
-
- if(!texref) {
- cuda_pop_context();
- return;
- }
+ if(use_texture) {
- if(interpolation) {
- CUarray handle = NULL;
- CUDA_ARRAY_DESCRIPTOR desc;
+ switch(mem.data_type) {
+ case TYPE_UCHAR: format = CU_AD_FORMAT_UNSIGNED_INT8; break;
+ case TYPE_UINT: format = CU_AD_FORMAT_UNSIGNED_INT32; break;
+ case TYPE_INT: format = CU_AD_FORMAT_SIGNED_INT32; break;
+ case TYPE_FLOAT: format = CU_AD_FORMAT_FLOAT; break;
+ default: assert(0); return;
+ }
- desc.Width = mem.data_width;
- desc.Height = mem.data_height;
- desc.Format = format;
- desc.NumChannels = mem.data_elements;
+ CUtexref texref = NULL;
- cuda_assert(cuArrayCreate(&handle, &desc))
+ cuda_push_context();
+ cuda_assert(cuModuleGetTexRef(&texref, cuModule, name))
- if(!handle) {
+ if(!texref) {
cuda_pop_context();
return;
}
- if(mem.data_height > 1) {
- CUDA_MEMCPY2D param;
- memset(&param, 0, sizeof(param));
- param.dstMemoryType = CU_MEMORYTYPE_ARRAY;
- param.dstArray = handle;
- param.srcMemoryType = CU_MEMORYTYPE_HOST;
- param.srcHost = (void*)mem.data_pointer;
- param.srcPitch = mem.data_width*dsize*mem.data_elements;
- param.WidthInBytes = param.srcPitch;
- param.Height = mem.data_height;
-
- cuda_assert(cuMemcpy2D(&param))
+ if(interpolation) {
+ CUarray handle = NULL;
+ CUDA_ARRAY_DESCRIPTOR desc;
+
+ desc.Width = mem.data_width;
+ desc.Height = mem.data_height;
+ desc.Format = format;
+ desc.NumChannels = mem.data_elements;
+
+ cuda_assert(cuArrayCreate(&handle, &desc))
+
+ if(!handle) {
+ cuda_pop_context();
+ return;
+ }
+
+ if(mem.data_height > 1) {
+ CUDA_MEMCPY2D param;
+ memset(&param, 0, sizeof(param));
+ param.dstMemoryType = CU_MEMORYTYPE_ARRAY;
+ param.dstArray = handle;
+ param.srcMemoryType = CU_MEMORYTYPE_HOST;
+ param.srcHost = (void*)mem.data_pointer;
+ param.srcPitch = mem.data_width*dsize*mem.data_elements;
+ param.WidthInBytes = param.srcPitch;
+ param.Height = mem.data_height;
+
+ cuda_assert(cuMemcpy2D(&param))
+ }
+ else
+ cuda_assert(cuMemcpyHtoA(handle, 0, (void*)mem.data_pointer, size))
+
+ cuda_assert(cuTexRefSetArray(texref, handle, CU_TRSA_OVERRIDE_FORMAT))
+
+ cuda_assert(cuTexRefSetFilterMode(texref, CU_TR_FILTER_MODE_LINEAR))
+ cuda_assert(cuTexRefSetFlags(texref, CU_TRSF_NORMALIZED_COORDINATES))
+
+ mem.device_pointer = (device_ptr)handle;
+
+ stats.mem_alloc(size);
}
- else
- cuda_assert(cuMemcpyHtoA(handle, 0, (void*)mem.data_pointer, size))
+ else {
+ cuda_pop_context();
- cuda_assert(cuTexRefSetArray(texref, handle, CU_TRSA_OVERRIDE_FORMAT))
+ mem_alloc(mem, MEM_READ_ONLY);
+ mem_copy_to(mem);
- cuda_assert(cuTexRefSetFilterMode(texref, CU_TR_FILTER_MODE_LINEAR))
- cuda_assert(cuTexRefSetFlags(texref, CU_TRSF_NORMALIZED_COORDINATES))
+ cuda_push_context();
+
+ cuda_assert(cuTexRefSetAddress(NULL, texref, cuda_device_ptr(mem.device_pointer), size))
+ cuda_assert(cuTexRefSetFilterMode(texref, CU_TR_FILTER_MODE_POINT))
+ cuda_assert(cuTexRefSetFlags(texref, CU_TRSF_READ_AS_INTEGER))
+ }
- mem.device_pointer = (device_ptr)handle;
+ if(periodic) {
+ cuda_assert(cuTexRefSetAddressMode(texref, 0, CU_TR_ADDRESS_MODE_WRAP))
+ cuda_assert(cuTexRefSetAddressMode(texref, 1, CU_TR_ADDRESS_MODE_WRAP))
+ }
+ else {
+ cuda_assert(cuTexRefSetAddressMode(texref, 0, CU_TR_ADDRESS_MODE_CLAMP))
+ cuda_assert(cuTexRefSetAddressMode(texref, 1, CU_TR_ADDRESS_MODE_CLAMP))
+ }
+ cuda_assert(cuTexRefSetFormat(texref, format, mem.data_elements))
- stats.mem_alloc(size);
+ cuda_pop_context();
}
else {
- cuda_pop_context();
-
mem_alloc(mem, MEM_READ_ONLY);
mem_copy_to(mem);
cuda_push_context();
- cuda_assert(cuTexRefSetAddress(NULL, texref, cuda_device_ptr(mem.device_pointer), size))
- cuda_assert(cuTexRefSetFilterMode(texref, CU_TR_FILTER_MODE_POINT))
- cuda_assert(cuTexRefSetFlags(texref, CU_TRSF_READ_AS_INTEGER))
- }
+ CUdeviceptr cumem;
+ size_t cubytes;
- if(periodic) {
- cuda_assert(cuTexRefSetAddressMode(texref, 0, CU_TR_ADDRESS_MODE_WRAP))
- cuda_assert(cuTexRefSetAddressMode(texref, 1, CU_TR_ADDRESS_MODE_WRAP))
- }
- else {
- cuda_assert(cuTexRefSetAddressMode(texref, 0, CU_TR_ADDRESS_MODE_CLAMP))
- cuda_assert(cuTexRefSetAddressMode(texref, 1, CU_TR_ADDRESS_MODE_CLAMP))
- }
- cuda_assert(cuTexRefSetFormat(texref, format, mem.data_elements))
+ cuda_assert(cuModuleGetGlobal(&cumem, &cubytes, cuModule, name))
- cuda_pop_context();
+ if(cubytes == 8) {
+ /* 64 bit device pointer */
+ uint64_t ptr = mem.device_pointer;
+ cuda_assert(cuMemcpyHtoD(cumem, (void*)&ptr, cubytes))
+ }
+ else {
+ /* 32 bit device pointer */
+ uint32_t ptr = (uint32_t)mem.device_pointer;
+ cuda_assert(cuMemcpyHtoD(cumem, (void*)&ptr, cubytes))
+ }
+
+ cuda_pop_context();
+ }
tex_interp_map[mem.device_pointer] = interpolation;
}
diff --git a/intern/cycles/device/device_opencl.cpp b/intern/cycles/device/device_opencl.cpp
index d723df70c89..11c7bc6f099 100644
--- a/intern/cycles/device/device_opencl.cpp
+++ b/intern/cycles/device/device_opencl.cpp
@@ -892,8 +892,16 @@ public:
void tex_free(device_memory& mem)
{
- if(mem.data_pointer)
+ if(mem.device_pointer) {
+ foreach(const MemMap::value_type& value, mem_map) {
+ if(value.second == mem.device_pointer) {
+ mem_map.erase(value.first);
+ break;
+ }
+ }
+
mem_free(mem);
+ }
}
size_t global_size_round_up(int group_size, int global_size)
@@ -1086,7 +1094,7 @@ public:
tile.sample = sample + 1;
- //task->update_progress(tile);
+ task->update_progress(tile);
}
task->release_tile(tile);
diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt
index eaa4e304ebb..56ba0e08743 100644
--- a/intern/cycles/kernel/CMakeLists.txt
+++ b/intern/cycles/kernel/CMakeLists.txt
@@ -151,36 +151,16 @@ if(WITH_CYCLES_CUDA_BINARIES)
set(cuda_version_flags "-D__KERNEL_CUDA_VERSION__=${CUDA_VERSION}")
- # build flags depending on CUDA version and arch
- if(CUDA_VERSION LESS 50)
- # CUDA 4.x
- if(${arch} MATCHES "sm_1[0-9]")
- # sm_1x
- set(cuda_arch_flags "--maxrregcount=24 --opencc-options -OPT:Olimit=0")
- elseif(${arch} MATCHES "sm_2[0-9]")
- # sm_2x
- set(cuda_arch_flags "--maxrregcount=24")
- else()
- # sm_3x
- set(cuda_arch_flags "--maxrregcount=32")
- endif()
-
- set(cuda_math_flags "")
- else()
- # CUDA 5.x
- if(${arch} MATCHES "sm_1[0-9]")
- # sm_1x
- set(cuda_arch_flags "--maxrregcount=24 --opencc-options -OPT:Olimit=0")
- elseif(${arch} MATCHES "sm_2[0-9]")
- # sm_2x
- set(cuda_arch_flags "--maxrregcount=32")
- else()
- # sm_3x
- set(cuda_arch_flags "--maxrregcount=32")
- endif()
-
- set(cuda_math_flags "--use_fast_math")
+ # CUDA 5.x build flags for different archs
+ if(${arch} MATCHES "sm_2[0-9]")
+ # sm_2x
+ set(cuda_arch_flags "--maxrregcount=32")
+ elseif(${arch} MATCHES "sm_3[0-9]")
+ # sm_3x
+ set(cuda_arch_flags "--maxrregcount=32")
endif()
+
+ set(cuda_math_flags "--use_fast_math")
if(CUDA_VERSION LESS 50 AND ${arch} MATCHES "sm_35")
message(WARNING "Can't build kernel for CUDA sm_35 architecture, skipping")
diff --git a/intern/cycles/kernel/SConscript b/intern/cycles/kernel/SConscript
index 6459c3ed183..a0522d9ba8e 100644
--- a/intern/cycles/kernel/SConscript
+++ b/intern/cycles/kernel/SConscript
@@ -86,33 +86,13 @@ if env['WITH_BF_CYCLES_CUDA_BINARIES']:
for arch in cuda_archs:
cubin_file = os.path.join(build_dir, "kernel_%s.cubin" % arch)
- # build flags depending on CUDA version and arch
- if cuda_version < 50:
- if arch == "sm_35":
- print("Can't build kernel for CUDA sm_35 architecture, skipping")
- continue
-
- # CUDA 4.x
- if arch.startswith("sm_1"):
- # sm_1x
- cuda_arch_flags = "--maxrregcount=24 --opencc-options -OPT:Olimit=0"
- elif arch.startswith("sm_2"):
- # sm_2x
- cuda_arch_flags = "--maxrregcount=24"
- else:
- # sm_3x
- cuda_arch_flags = "--maxrregcount=32"
- else:
- # CUDA 5.x
- if arch.startswith("sm_1"):
- # sm_1x
- cuda_arch_flags = "--maxrregcount=24 --opencc-options -OPT:Olimit=0 --use_fast_math"
- elif arch.startswith("sm_2"):
- # sm_2x
- cuda_arch_flags = "--maxrregcount=32 --use_fast_math"
- else:
- # sm_3x
- cuda_arch_flags = "--maxrregcount=32 --use_fast_math"
+ # CUDA 5.x build flags for different archs
+ if arch.startswith("sm_2"):
+ # sm_2x
+ cuda_arch_flags = "--maxrregcount=32 --use_fast_math"
+ elif arch.startswith("sm_3"):
+ # sm_3x
+ cuda_arch_flags = "--maxrregcount=32 --use_fast_math"
command = "\"%s\" -arch=%s %s %s \"%s\" -o \"%s\"" % (nvcc, arch, nvcc_flags, cuda_arch_flags, kernel_file, cubin_file)
diff --git a/intern/cycles/kernel/kernel_bvh.h b/intern/cycles/kernel/kernel_bvh.h
index 4b01f2eebcd..44a9822c103 100644
--- a/intern/cycles/kernel/kernel_bvh.h
+++ b/intern/cycles/kernel/kernel_bvh.h
@@ -809,11 +809,16 @@ __device_inline void bvh_triangle_intersect_subsurface(KernelGlobals *kg, Inters
#include "kernel_bvh_subsurface.h"
#endif
-
+/* to work around titan bug when using arrays instead of textures */
+#if !defined(__KERNEL_CUDA__) || defined(__KERNEL_CUDA_TEX_STORAGE__)
+__device_inline
+#else
+__device_noinline
+#endif
#ifdef __HAIR__
-__device_inline bool scene_intersect(KernelGlobals *kg, const Ray *ray, const uint visibility, Intersection *isect, uint *lcg_state, float difl, float extmax)
+bool scene_intersect(KernelGlobals *kg, const Ray *ray, const uint visibility, Intersection *isect, uint *lcg_state, float difl, float extmax)
#else
-__device_inline bool scene_intersect(KernelGlobals *kg, const Ray *ray, const uint visibility, Intersection *isect)
+bool scene_intersect(KernelGlobals *kg, const Ray *ray, const uint visibility, Intersection *isect)
#endif
{
#ifdef __OBJECT_MOTION__
@@ -851,8 +856,14 @@ __device_inline bool scene_intersect(KernelGlobals *kg, const Ray *ray, const ui
#endif /* __KERNEL_CPU__ */
}
+/* to work around titan bug when using arrays instead of textures */
#ifdef __SUBSURFACE__
-__device_inline uint scene_intersect_subsurface(KernelGlobals *kg, const Ray *ray, Intersection *isect, int subsurface_object, uint *lcg_state, int max_hits)
+#if !defined(__KERNEL_CUDA__) || defined(__KERNEL_CUDA_TEX_STORAGE__)
+__device_inline
+#else
+__device_noinline
+#endif
+uint scene_intersect_subsurface(KernelGlobals *kg, const Ray *ray, Intersection *isect, int subsurface_object, uint *lcg_state, int max_hits)
{
#ifdef __OBJECT_MOTION__
if(kernel_data.bvh.have_motion) {
diff --git a/intern/cycles/kernel/kernel_compat_cuda.h b/intern/cycles/kernel/kernel_compat_cuda.h
index cb86ce8c4ae..44c2b9effe9 100644
--- a/intern/cycles/kernel/kernel_compat_cuda.h
+++ b/intern/cycles/kernel/kernel_compat_cuda.h
@@ -57,7 +57,18 @@ typedef texture<uchar4, 2, cudaReadModeNormalizedFloat> texture_image_uchar4;
/* Macros to handle different memory storage on different devices */
+/* In order to use full 6GB of memory on Titan cards, use arrays instead
+ * of textures. On earlier cards this seems slower, but on Titan it is
+ * actually slightly faster in tests. */
+#if __CUDA_ARCH__ < 350
+#define __KERNEL_CUDA_TEX_STORAGE__
+#endif
+
+#ifdef __KERNEL_CUDA_TEX_STORAGE__
#define kernel_tex_fetch(t, index) tex1Dfetch(t, index)
+#else
+#define kernel_tex_fetch(t, index) t[(index)]
+#endif
#define kernel_tex_image_interp(t, x, y) tex2D(t, x, y)
#define kernel_data __data
diff --git a/intern/cycles/kernel/kernel_film.h b/intern/cycles/kernel/kernel_film.h
index 8868a335037..721eceabc37 100644
--- a/intern/cycles/kernel/kernel_film.h
+++ b/intern/cycles/kernel/kernel_film.h
@@ -70,8 +70,8 @@ __device void kernel_film_convert_to_half_float(KernelGlobals *kg,
/* buffer offset */
int index = offset + x + y*stride;
- float4 *in = (float4*)(buffer + index*kernel_data.film.pass_stride);
- half *out = (half*)rgba + index*4;
+ __global float4 *in = (__global float4*)(buffer + index*kernel_data.film.pass_stride);
+ __global half *out = (__global half*)rgba + index*4;
float scale = kernel_data.film.exposure*sample_scale;
float4_store_half(out, in, scale);
diff --git a/intern/cycles/kernel/kernel_globals.h b/intern/cycles/kernel/kernel_globals.h
index ab0a717b592..b5e691eb615 100644
--- a/intern/cycles/kernel/kernel_globals.h
+++ b/intern/cycles/kernel/kernel_globals.h
@@ -66,7 +66,11 @@ typedef struct KernelGlobals {
__constant__ KernelData __data;
typedef struct KernelGlobals {} KernelGlobals;
+#ifdef __KERNEL_CUDA_TEX_STORAGE__
#define KERNEL_TEX(type, ttype, name) ttype name;
+#else
+#define KERNEL_TEX(type, ttype, name) const __constant__ __device__ type *name;
+#endif
#define KERNEL_IMAGE_TEX(type, ttype, name) ttype name;
#include "kernel_textures.h"
diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h
index 1afe8480616..5354738d378 100644
--- a/intern/cycles/kernel/kernel_path.h
+++ b/intern/cycles/kernel/kernel_path.h
@@ -266,14 +266,9 @@ __device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray
if(sc) {
uint lcg_state = lcg_init(*rng + rng_offset + sample*0x68bc21eb);
- if(old_subsurface_scatter_use(&sd)) {
- old_subsurface_scatter_step(kg, &sd, state.flag, sc, &lcg_state, false);
- }
- else {
- float bssrdf_u, bssrdf_v;
- path_rng_2D(kg, rng, sample, num_total_samples, rng_offset + PRNG_BSDF_U, &bssrdf_u, &bssrdf_v);
- subsurface_scatter_step(kg, &sd, state.flag, sc, &lcg_state, bssrdf_u, bssrdf_v, false);
- }
+ float bssrdf_u, bssrdf_v;
+ path_rng_2D(kg, rng, sample, num_total_samples, rng_offset + PRNG_BSDF_U, &bssrdf_u, &bssrdf_v);
+ subsurface_scatter_step(kg, &sd, state.flag, sc, &lcg_state, bssrdf_u, bssrdf_v, false);
state.flag |= PATH_RAY_BSSRDF_ANCESTOR;
}
@@ -468,7 +463,9 @@ __device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, R
float min_ray_pdf = FLT_MAX;
float ray_pdf = 0.0f;
+#ifdef __LAMP_MIS__
float ray_t = 0.0f;
+#endif
PathState state;
int rng_offset = PRNG_BASE_NUM;
#ifdef __CMJ__
@@ -662,41 +659,35 @@ __device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, R
if(sc) {
uint lcg_state = lcg_init(*rng + rng_offset + sample*0x68bc21eb);
- if(old_subsurface_scatter_use(&sd)) {
- old_subsurface_scatter_step(kg, &sd, state.flag, sc, &lcg_state, false);
- }
- else {
- ShaderData bssrdf_sd[BSSRDF_MAX_HITS];
- float bssrdf_u, bssrdf_v;
- path_rng_2D(kg, rng, sample, num_samples, rng_offset + PRNG_BSDF_U, &bssrdf_u, &bssrdf_v);
- int num_hits = subsurface_scatter_multi_step(kg, &sd, bssrdf_sd, state.flag, sc, &lcg_state, bssrdf_u, bssrdf_v, false);
-
- /* compute lighting with the BSDF closure */
- for(int hit = 0; hit < num_hits; hit++) {
- float3 tp = throughput;
- PathState hit_state = state;
- Ray hit_ray = ray;
- float hit_ray_t = ray_t;
- float hit_ray_pdf = ray_pdf;
- float hit_min_ray_pdf = min_ray_pdf;
-
- hit_state.flag |= PATH_RAY_BSSRDF_ANCESTOR;
-
- if(kernel_path_integrate_lighting(kg, rng, sample, num_samples, &bssrdf_sd[hit],
- &tp, &hit_min_ray_pdf, &hit_ray_pdf, &hit_state, rng_offset+PRNG_BOUNCE_NUM, &L, &hit_ray, &hit_ray_t)) {
- kernel_path_indirect(kg, rng, sample, hit_ray, buffer,
- tp, num_samples, num_samples,
- hit_min_ray_pdf, hit_ray_pdf, hit_state, rng_offset+PRNG_BOUNCE_NUM*2, &L);
-
- /* for render passes, sum and reset indirect light pass variables
- * for the next samples */
- path_radiance_sum_indirect(&L);
- path_radiance_reset_indirect(&L);
- }
+ ShaderData bssrdf_sd[BSSRDF_MAX_HITS];
+ float bssrdf_u, bssrdf_v;
+ path_rng_2D(kg, rng, sample, num_samples, rng_offset + PRNG_BSDF_U, &bssrdf_u, &bssrdf_v);
+ int num_hits = subsurface_scatter_multi_step(kg, &sd, bssrdf_sd, state.flag, sc, &lcg_state, bssrdf_u, bssrdf_v, false);
+
+ /* compute lighting with the BSDF closure */
+ for(int hit = 0; hit < num_hits; hit++) {
+ float3 tp = throughput;
+ PathState hit_state = state;
+ Ray hit_ray = ray;
+ float hit_ray_t = ray_t;
+ float hit_ray_pdf = ray_pdf;
+ float hit_min_ray_pdf = min_ray_pdf;
+
+ hit_state.flag |= PATH_RAY_BSSRDF_ANCESTOR;
+
+ if(kernel_path_integrate_lighting(kg, rng, sample, num_samples, &bssrdf_sd[hit],
+ &tp, &hit_min_ray_pdf, &hit_ray_pdf, &hit_state, rng_offset+PRNG_BOUNCE_NUM, &L, &hit_ray, &hit_ray_t)) {
+ kernel_path_indirect(kg, rng, sample, hit_ray, buffer,
+ tp, num_samples, num_samples,
+ hit_min_ray_pdf, hit_ray_pdf, hit_state, rng_offset+PRNG_BOUNCE_NUM*2, &L);
+
+ /* for render passes, sum and reset indirect light pass variables
+ * for the next samples */
+ path_radiance_sum_indirect(&L);
+ path_radiance_reset_indirect(&L);
}
-
- break;
}
+ break;
}
}
#endif
@@ -1129,17 +1120,6 @@ __device float4 kernel_branched_path_integrate(KernelGlobals *kg, RNG *rng, int
/* do subsurface scatter step with copy of shader data, this will
* replace the BSSRDF with a diffuse BSDF closure */
for(int j = 0; j < num_samples; j++) {
- if(old_subsurface_scatter_use(&sd)) {
- ShaderData bssrdf_sd = sd;
- old_subsurface_scatter_step(kg, &bssrdf_sd, state.flag, sc, &lcg_state, true);
-
- /* compute lighting with the BSDF closure */
- kernel_branched_path_integrate_lighting(kg, rng, sample*num_samples + j,
- aa_samples*num_samples,
- &bssrdf_sd, throughput, num_samples_inv,
- ray_pdf, ray_pdf, state, rng_offset, &L, buffer);
- }
- else {
ShaderData bssrdf_sd[BSSRDF_MAX_HITS];
float bssrdf_u, bssrdf_v;
path_rng_2D(kg, &bssrdf_rng, sample*num_samples + j, aa_samples*num_samples, rng_offset + PRNG_BSDF_U, &bssrdf_u, &bssrdf_v);
@@ -1151,7 +1131,6 @@ __device float4 kernel_branched_path_integrate(KernelGlobals *kg, RNG *rng, int
aa_samples*num_samples,
&bssrdf_sd[hit], throughput, num_samples_inv,
ray_pdf, ray_pdf, state, rng_offset+PRNG_BOUNCE_NUM, &L, buffer);
- }
}
state.flag &= ~PATH_RAY_BSSRDF_ANCESTOR;
diff --git a/intern/cycles/kernel/kernel_primitive.h b/intern/cycles/kernel/kernel_primitive.h
index 4a06dff84bf..636cfd06532 100644
--- a/intern/cycles/kernel/kernel_primitive.h
+++ b/intern/cycles/kernel/kernel_primitive.h
@@ -93,7 +93,11 @@ __device float3 primitive_tangent(KernelGlobals *kg, ShaderData *sd)
{
#ifdef __HAIR__
if(sd->segment != ~0)
+#ifdef __DPDU__
return normalize(sd->dPdu);
+#else
+ return make_float3(0.0f, 0.0f, 0.0f);
+#endif
#endif
/* try to create spherical tangent from generated coordinates */
@@ -108,7 +112,11 @@ __device float3 primitive_tangent(KernelGlobals *kg, ShaderData *sd)
}
else {
/* otherwise use surface derivatives */
+#ifdef __DPDU__
return normalize(sd->dPdu);
+#else
+ return make_float3(0.0f, 0.0f, 0.0f);
+#endif
}
}
diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h
index ee71a0cfcf4..81630caed9a 100644
--- a/intern/cycles/kernel/kernel_shader.h
+++ b/intern/cycles/kernel/kernel_shader.h
@@ -36,15 +36,8 @@ CCL_NAMESPACE_BEGIN
/* ShaderData setup from incoming ray */
#ifdef __OBJECT_MOTION__
-#if defined(__KERNEL_CUDA_VERSION__) && __KERNEL_CUDA_VERSION__ <= 42
-__device_noinline
-#else
-__device
-#endif
-void shader_setup_object_transforms(KernelGlobals *kg, ShaderData *sd, float time)
+__device void shader_setup_object_transforms(KernelGlobals *kg, ShaderData *sd, float time)
{
- /* note that this is a separate non-inlined function to work around crash
- * on CUDA sm 2.0, otherwise kernel execution crashes (compiler bug?) */
if(sd->flag & SD_OBJECT_MOTION) {
sd->ob_tfm = object_fetch_transform_motion(kg, sd->object, time);
sd->ob_itfm= transform_quick_inverse(sd->ob_tfm);
@@ -56,12 +49,7 @@ void shader_setup_object_transforms(KernelGlobals *kg, ShaderData *sd, float tim
}
#endif
-#if defined(__KERNEL_CUDA_VERSION__) && __KERNEL_CUDA_VERSION__ <= 42
-__device_noinline
-#else
-__device
-#endif
-void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
+__device void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
const Intersection *isect, const Ray *ray, int bounce)
{
#ifdef __INSTANCING__
@@ -249,12 +237,7 @@ __device_inline void shader_setup_from_subsurface(KernelGlobals *kg, ShaderData
/* ShaderData setup from position sampled on mesh */
-#if defined(__KERNEL_CUDA_VERSION__) && __KERNEL_CUDA_VERSION__ <= 42
-__device_noinline
-#else
-__device
-#endif
-void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
+__device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
const float3 P, const float3 Ng, const float3 I,
int shader, int object, int prim, float u, float v, float t, float time, int bounce, int segment)
{
diff --git a/intern/cycles/kernel/kernel_sse2.cpp b/intern/cycles/kernel/kernel_sse2.cpp
index 862626d6899..9c69e519dca 100644
--- a/intern/cycles/kernel/kernel_sse2.cpp
+++ b/intern/cycles/kernel/kernel_sse2.cpp
@@ -20,7 +20,10 @@
#ifdef WITH_OPTIMIZED_KERNEL
+/* SSE optimization disabled for now on 32 bit, see bug #36316 */
+#if !(defined(__GNUC__) && (defined(i386) || defined(_M_IX86)))
#define __KERNEL_SSE2__
+#endif
#include "kernel.h"
#include "kernel_compat_cpu.h"
diff --git a/intern/cycles/kernel/kernel_sse3.cpp b/intern/cycles/kernel/kernel_sse3.cpp
index c44098606a5..05877a41b4a 100644
--- a/intern/cycles/kernel/kernel_sse3.cpp
+++ b/intern/cycles/kernel/kernel_sse3.cpp
@@ -20,9 +20,12 @@
#ifdef WITH_OPTIMIZED_KERNEL
+/* SSE optimization disabled for now on 32 bit, see bug #36316 */
+#if !(defined(__GNUC__) && (defined(i386) || defined(_M_IX86)))
#define __KERNEL_SSE2__
#define __KERNEL_SSE3__
#define __KERNEL_SSSE3__
+#endif
#include "kernel.h"
#include "kernel_compat_cpu.h"
diff --git a/intern/cycles/kernel/kernel_subsurface.h b/intern/cycles/kernel/kernel_subsurface.h
index 4567f2ff0ce..d16b9328bf2 100644
--- a/intern/cycles/kernel/kernel_subsurface.h
+++ b/intern/cycles/kernel/kernel_subsurface.h
@@ -403,164 +403,5 @@ __device void subsurface_scatter_step(KernelGlobals *kg, ShaderData *sd,
subsurface_scatter_setup_diffuse_bsdf(sd, eval, (num_hits > 0), N);
}
-
-/* OLD BSSRDF */
-
-__device float old_bssrdf_sample_distance(KernelGlobals *kg, float radius, float refl, float u)
-{
- int table_offset = kernel_data.bssrdf.table_offset;
- float r = lookup_table_read_2D(kg, u, refl, table_offset, BSSRDF_RADIUS_TABLE_SIZE, BSSRDF_REFL_TABLE_SIZE);
-
- return r*radius;
-}
-
-#ifdef BSSRDF_MULTI_EVAL
-__device float old_bssrdf_pdf(KernelGlobals *kg, float radius, float refl, float r)
-{
- if(r >= radius)
- return 0.0f;
-
- /* todo: when we use the real BSSRDF this will need to be divided by the maximum
- * radius instead of the average radius */
- float t = r/radius;
-
- int table_offset = kernel_data.bssrdf.table_offset + BSSRDF_PDF_TABLE_OFFSET;
- float pdf = lookup_table_read_2D(kg, t, refl, table_offset, BSSRDF_RADIUS_TABLE_SIZE, BSSRDF_REFL_TABLE_SIZE);
-
- pdf /= radius;
-
- return pdf;
-}
-#endif
-
-#ifdef BSSRDF_MULTI_EVAL
-__device float3 old_subsurface_scatter_multi_eval(KernelGlobals *kg, ShaderData *sd, bool hit, float refl, float *r, int num_r, bool all)
-{
- /* compute pdf */
- float3 eval_sum = make_float3(0.0f, 0.0f, 0.0f);
- float pdf_sum = 0.0f;
- float sample_weight_sum = 0.0f;
- int num_bssrdf = 0;
-
- for(int i = 0; i < sd->num_closure; i++) {
- ShaderClosure *sc = &sd->closure[i];
-
- if(CLOSURE_IS_BSSRDF(sc->type)) {
- float sample_weight = (all)? 1.0f: sc->sample_weight;
-
- /* compute pdf */
- float pdf = 1.0f;
- for(int i = 0; i < num_r; i++)
- pdf *= old_bssrdf_pdf(kg, sc->data0, refl, r[i]);
-
- eval_sum += sc->weight*pdf;
- pdf_sum += sample_weight*pdf;
-
- sample_weight_sum += sample_weight;
- num_bssrdf++;
- }
- }
-
- float inv_pdf_sum;
-
- if(pdf_sum > 0.0f) {
- /* in case of branched path integrate we sample all bssrdf's once,
- * for path trace we pick one, so adjust pdf for that */
- if(all)
- inv_pdf_sum = 1.0f/pdf_sum;
- else
- inv_pdf_sum = sample_weight_sum/pdf_sum;
- }
- else
- inv_pdf_sum = 0.0f;
-
- float3 weight = eval_sum * inv_pdf_sum;
-
- return weight;
-}
-#endif
-
-/* subsurface scattering step, from a point on the surface to another nearby point on the same object */
-__device void old_subsurface_scatter_step(KernelGlobals *kg, ShaderData *sd, int state_flag, ShaderClosure *sc, uint *lcg_state, bool all)
-{
- float radius = sc->data0;
- float refl = max(average(sc->weight)*3.0f, 0.0f);
- float r = 0.0f;
- bool hit = false;
- float3 weight = make_float3(1.0f, 1.0f, 1.0f);
-#ifdef BSSRDF_MULTI_EVAL
- float r_attempts[BSSRDF_MAX_ATTEMPTS];
-#endif
- int num_attempts;
-
- /* attempt to find a hit a given number of times before giving up */
- for(num_attempts = 0; num_attempts < kernel_data.bssrdf.num_attempts; num_attempts++) {
- /* random numbers for sampling */
- float u1 = lcg_step_float(lcg_state);
- float u2 = lcg_step_float(lcg_state);
- float u3 = lcg_step_float(lcg_state);
- float u4 = lcg_step_float(lcg_state);
- float u5 = lcg_step_float(lcg_state);
-
- r = old_bssrdf_sample_distance(kg, radius, refl, u5);
-#ifdef BSSRDF_MULTI_EVAL
- r_attempts[num_attempts] = r;
-#endif
-
- float3 p1 = sd->P + sample_uniform_sphere(u1, u2)*r;
- float3 p2 = sd->P + sample_uniform_sphere(u3, u4)*r;
-
- /* create ray */
- Ray ray;
- ray.P = p1;
- ray.D = normalize_len(p2 - p1, &ray.t);
- ray.dP = sd->dP;
- ray.dD = differential3_zero();
- ray.time = sd->time;
-
- /* intersect with the same object. if multiple intersections are
- * found it will randomly pick one of them */
- Intersection isect;
- if(scene_intersect_subsurface(kg, &ray, &isect, sd->object, lcg_state, 1) == 0)
- continue;
-
- /* setup new shading point */
- shader_setup_from_subsurface(kg, sd, &isect, &ray);
-
- hit = true;
- num_attempts++;
- break;
- }
-
- /* evaluate subsurface scattering closures */
-#ifdef BSSRDF_MULTI_EVAL
- weight *= old_subsurface_scatter_multi_eval(kg, sd, hit, refl, r_attempts, num_attempts, all);
-#else
- weight *= sc->weight;
-#endif
-
- if(!hit)
- weight = make_float3(0.0f, 0.0f, 0.0f);
-
- /* optionally blur colors and bump mapping */
- float3 N = sd->N;
- subsurface_color_bump_blur(kg, sd, sd, state_flag, &weight, &N);
-
- /* replace closures with a single diffuse BSDF */
- subsurface_scatter_setup_diffuse_bsdf(sd, weight, hit, N);
-}
-
-__device bool old_subsurface_scatter_use(ShaderData *sd)
-{
- for(int i = 0; i < sd->num_closure; i++) {
- ShaderClosure *sc = &sd->closure[i];
-
- if(sc->type == CLOSURE_BSSRDF_COMPATIBLE_ID)
- return true;
- }
-
- return false;
-}
-
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index d039b708bd4..3371c580c71 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -35,12 +35,7 @@ CCL_NAMESPACE_BEGIN
#define PARTICLE_SIZE 5
#define TIME_INVALID FLT_MAX
-#define BSSRDF_RADIUS_TABLE_SIZE 1024
-#define BSSRDF_REFL_TABLE_SIZE 256
-#define BSSRDF_PDF_TABLE_OFFSET (BSSRDF_RADIUS_TABLE_SIZE*BSSRDF_REFL_TABLE_SIZE)
-#define BSSRDF_LOOKUP_TABLE_SIZE (BSSRDF_RADIUS_TABLE_SIZE*BSSRDF_REFL_TABLE_SIZE*2)
#define BSSRDF_MIN_RADIUS 1e-8f
-#define BSSRDF_MAX_ATTEMPTS 8
#define BSSRDF_MAX_HITS 4
#define BB_DRAPPER 800.0f
@@ -815,12 +810,6 @@ typedef struct KernelCurves {
int pad2;
} KernelCurves;
-typedef struct KernelBSSRDF {
- int table_offset;
- int num_attempts;
- int pad1, pad2;
-} KernelBSSRDF;
-
typedef struct KernelBlackbody {
int table_offset;
int pad1, pad2, pad3;
@@ -834,7 +823,6 @@ typedef struct KernelData {
KernelIntegrator integrator;
KernelBVH bvh;
KernelCurves curve;
- KernelBSSRDF bssrdf;
KernelBlackbody blackbody;
} KernelData;
diff --git a/intern/cycles/kernel/osl/osl_shader.cpp b/intern/cycles/kernel/osl/osl_shader.cpp
index 625ad263f7f..18e8fee4348 100644
--- a/intern/cycles/kernel/osl/osl_shader.cpp
+++ b/intern/cycles/kernel/osl/osl_shader.cpp
@@ -253,7 +253,7 @@ static void flatten_surface_closure_tree(ShaderData *sd, int path_flag,
/* disable in case of diffuse ancestor, can't see it well then and
* adds considerably noise due to probabilities of continuing path
* getting lower and lower */
- if(sc.type != CLOSURE_BSSRDF_COMPATIBLE_ID && (path_flag & PATH_RAY_DIFFUSE_ANCESTOR))
+ if(path_flag & PATH_RAY_DIFFUSE_ANCESTOR)
bssrdf->radius = make_float3(0.0f, 0.0f, 0.0f);
/* create one closure for each color channel */
diff --git a/intern/cycles/kernel/shaders/SConscript b/intern/cycles/kernel/shaders/SConscript
index aad6e23e4d4..8bc1c2206e0 100644
--- a/intern/cycles/kernel/shaders/SConscript
+++ b/intern/cycles/kernel/shaders/SConscript
@@ -57,7 +57,7 @@ if env['WITH_BF_CYCLES_OSL']:
osl_file = os.path.join(source_dir, f)
oso_file = os.path.join(build_dir, f.replace('.osl', '.oso'))
- command = "%s -q -O2 -I%s -o %s %s" % (osl_compiler, source_dir, oso_file, osl_file)
+ command = "\"%s\" -q -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)
diff --git a/intern/cycles/kernel/shaders/node_environment_texture.osl b/intern/cycles/kernel/shaders/node_environment_texture.osl
index 6b61c689066..136ccdf8b18 100644
--- a/intern/cycles/kernel/shaders/node_environment_texture.osl
+++ b/intern/cycles/kernel/shaders/node_environment_texture.osl
@@ -19,7 +19,7 @@
vector environment_texture_direction_to_equirectangular(vector dir)
{
- float u = -atan2(dir[1], dir[0]) / (2.0 * M_PI) + 0.5;
+ float u = -atan2(dir[1], dir[0]) / (M_2PI) + 0.5;
float v = atan2(dir[2], hypot(dir[0], dir[1])) / M_PI + 0.5;
return vector(u, v, 0.0);
diff --git a/intern/cycles/kernel/shaders/node_hair_bsdf.osl b/intern/cycles/kernel/shaders/node_hair_bsdf.osl
index d1d7d0fb6a6..54d4cb67c3b 100644
--- a/intern/cycles/kernel/shaders/node_hair_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_hair_bsdf.osl
@@ -19,8 +19,8 @@
#include "stdosl.h"
shader node_hair_bsdf(
- color Color = 0.8,
- string component = "Reflection",
+ color Color = 0.8,
+ string component = "Reflection",
float Offset = 0.0,
float RoughnessU = 0.1,
float RoughnessV = 1.0,
@@ -28,29 +28,30 @@ shader node_hair_bsdf(
output closure color BSDF = 0)
{
float IsStrand;
- float roughnessh = clamp(RoughnessU, 0.001,1.0);
- float roughnessv = clamp(RoughnessV, 0.001,1.0);
+ float roughnessh = clamp(RoughnessU, 0.001, 1.0);
+ float roughnessv = clamp(RoughnessV, 0.001, 1.0);
getattribute("geom:is_curve", IsStrand);
- if (!IsStrand) {
- if (backfacing())
- BSDF = transparent();
- else {
- if (component == "Reflection")
- BSDF = Color * hair_reflection(Normal, roughnessh, roughnessv, normalize(dPdv), 0.0);
- else
- BSDF = Color * hair_transmission(Normal, roughnessh, roughnessv, normalize(dPdv), 0.0);
+ if (!IsStrand) {
+ if (backfacing()) {
+ BSDF = transparent();
+ }
+ else {
+ if (component == "Reflection")
+ BSDF = Color * hair_reflection(Normal, roughnessh, roughnessv, normalize(dPdv), 0.0);
+ else
+ BSDF = Color * hair_transmission(Normal, roughnessh, roughnessv, normalize(dPdv), 0.0);
}
}
- else {
- if (backfacing())
- BSDF = transparent();
- else {
- if (component == "Reflection")
- BSDF = Color * hair_reflection(Normal, roughnessh, roughnessv, dPdu, -Offset);
- else
- BSDF = Color * hair_transmission(Normal, roughnessh, roughnessv, dPdu, -Offset);
+ else {
+ if (backfacing()) {
+ BSDF = transparent();
+ }
+ else {
+ if (component == "Reflection")
+ BSDF = Color * hair_reflection(Normal, roughnessh, roughnessv, dPdu, -Offset);
+ else
+ BSDF = Color * hair_transmission(Normal, roughnessh, roughnessv, dPdu, -Offset);
}
}
}
-
diff --git a/intern/cycles/kernel/shaders/node_sky_texture.osl b/intern/cycles/kernel/shaders/node_sky_texture.osl
index 3ed791fdc92..85c2dbdb2c2 100644
--- a/intern/cycles/kernel/shaders/node_sky_texture.osl
+++ b/intern/cycles/kernel/shaders/node_sky_texture.osl
@@ -44,8 +44,8 @@ float sky_perez_function(float lam[9], float theta, float gamma)
}
color sky_radiance_old(normal dir,
- float sunphi, float suntheta, color radiance,
- float config_x[9], float config_y[9], float config_z[9])
+ float sunphi, float suntheta, color radiance,
+ float config_x[9], float config_y[9], float config_z[9])
{
/* convert vector to spherical coordinates */
vector spherical = sky_spherical_coordinates(dir);
@@ -76,7 +76,7 @@ float sky_radiance_internal(float config[9], float theta, float gamma)
float expM = exp(config[4] * gamma);
float rayM = cgamma * cgamma;
- float mieM = (1.0 + rayM) / pow((1.0 + config[8]*config[8] - 2.0*config[8]*cgamma), 1.5);
+ float mieM = (1.0 + rayM) / pow((1.0 + config[8] * config[8] - 2.0 * config[8] * cgamma), 1.5);
float zenith = sqrt(ctheta);
return (1.0 + config[0] * exp(config[1] / (ctheta + 0.01))) *
@@ -84,8 +84,8 @@ float sky_radiance_internal(float config[9], float theta, float gamma)
}
color sky_radiance_new(normal dir,
- float sunphi, float suntheta, color radiance,
- float config_x[9], float config_y[9], float config_z[9])
+ float sunphi, float suntheta, color radiance,
+ float config_x[9], float config_y[9], float config_z[9])
{
/* convert vector to spherical coordinates */
vector spherical = sky_spherical_coordinates(dir);
@@ -104,7 +104,7 @@ color sky_radiance_new(normal dir,
float z = sky_radiance_internal(config_z, theta, gamma) * radiance[2];
/* convert to RGB and adjust strength */
- return xyz_to_rgb(x, y, z) * (M_2PI/683);
+ return xyz_to_rgb(x, y, z) * (M_2PI / 683);
}
shader node_sky_texture(
diff --git a/intern/cycles/kernel/shaders/node_subsurface_scattering.osl b/intern/cycles/kernel/shaders/node_subsurface_scattering.osl
index 5c1d1be0ee7..1c0cd74c0be 100644
--- a/intern/cycles/kernel/shaders/node_subsurface_scattering.osl
+++ b/intern/cycles/kernel/shaders/node_subsurface_scattering.osl
@@ -26,7 +26,7 @@ shader node_subsurface_scattering(
normal Normal = N,
output closure color BSSRDF = 0)
{
- if(Falloff == "Gaussian")
+ if (Falloff == "Gaussian")
BSSRDF = Color * bssrdf_gaussian(N, Scale * Radius, TextureBlur);
else
BSSRDF = Color * bssrdf_cubic(N, Scale * Radius, TextureBlur, Sharpness);
diff --git a/intern/cycles/kernel/shaders/node_ward_bsdf.osl b/intern/cycles/kernel/shaders/node_ward_bsdf.osl
index a21dd24059d..2d360d594f2 100644
--- a/intern/cycles/kernel/shaders/node_ward_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_ward_bsdf.osl
@@ -29,7 +29,7 @@ shader node_ward_bsdf(
vector T = Tangent;
if (Rotation != 0.0)
- T = rotate(T, Rotation * 2.0 * M_PI, point(0.0, 0.0, 0.0), Normal);
+ T = rotate(T, Rotation * M_2PI, point(0.0, 0.0, 0.0), Normal);
/* compute roughness */
float RoughnessU, RoughnessV;
diff --git a/intern/cycles/kernel/shaders/stdosl.h b/intern/cycles/kernel/shaders/stdosl.h
index 424ca335903..47c5dc27f2b 100644
--- a/intern/cycles/kernel/shaders/stdosl.h
+++ b/intern/cycles/kernel/shaders/stdosl.h
@@ -134,12 +134,16 @@ normal mod (normal a, float b) { return a - b*floor(a/b); }
color mod (color a, float b) { return a - b*floor(a/b); }
float mod (float a, float b) { return a - b*floor(a/b); }
PERCOMP2 (min)
+int min (int a, int b) BUILTIN;
PERCOMP2 (max)
+int max (int a, int b) BUILTIN;
normal clamp (normal x, normal minval, normal maxval) { return max(min(x,maxval),minval); }
vector clamp (vector x, vector minval, vector maxval) { return max(min(x,maxval),minval); }
point clamp (point x, point minval, point maxval) { return max(min(x,maxval),minval); }
color clamp (color x, color minval, color maxval) { return max(min(x,maxval),minval); }
float clamp (float x, float minval, float maxval) { return max(min(x,maxval),minval); }
+int clamp (int x, int minval, int maxval) { return max(min(x,maxval),minval); }
+#if 0
normal mix (normal x, normal y, normal a) { return x*(1-a) + y*a; }
normal mix (normal x, normal y, float a) { return x*(1-a) + y*a; }
vector mix (vector x, vector y, vector a) { return x*(1-a) + y*a; }
@@ -149,6 +153,17 @@ point mix (point x, point y, float a) { return x*(1-a) + y*a; }
color mix (color x, color y, color a) { return x*(1-a) + y*a; }
color mix (color x, color y, float a) { return x*(1-a) + y*a; }
float mix (float x, float y, float a) { return x*(1-a) + y*a; }
+#else
+normal mix (normal x, normal y, normal a) BUILTIN;
+normal mix (normal x, normal y, float a) BUILTIN;
+vector mix (vector x, vector y, vector a) BUILTIN;
+vector mix (vector x, vector y, float a) BUILTIN;
+point mix (point x, point y, point a) BUILTIN;
+point mix (point x, point y, float a) BUILTIN;
+color mix (color x, color y, color a) BUILTIN;
+color mix (color x, color y, float a) BUILTIN;
+float mix (float x, float y, float a) BUILTIN;
+#endif
int isnan (float x) BUILTIN;
int isinf (float x) BUILTIN;
int isfinite (float x) BUILTIN;
@@ -418,8 +433,8 @@ int startswith (string s, string prefix) BUILTIN;
int endswith (string s, string suffix) BUILTIN;
string substr (string s, int start, int len) BUILTIN;
string substr (string s, int start) { return substr (s, start, strlen(s)); }
-float strtof (string str) BUILTIN;
-int strtoi (string str) BUILTIN;
+float stof (string str) BUILTIN;
+int stoi (string str) BUILTIN;
// Define concat in terms of shorter concat
string concat (string a, string b, string c) {
diff --git a/intern/cycles/kernel/svm/svm_closure.h b/intern/cycles/kernel/svm/svm_closure.h
index 6d9c4e215e6..0d4716ab078 100644
--- a/intern/cycles/kernel/svm/svm_closure.h
+++ b/intern/cycles/kernel/svm/svm_closure.h
@@ -378,7 +378,6 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st
#endif
#ifdef __SUBSURFACE__
- case CLOSURE_BSSRDF_COMPATIBLE_ID:
case CLOSURE_BSSRDF_CUBIC_ID:
case CLOSURE_BSSRDF_GAUSSIAN_ID: {
ShaderClosure *sc = &sd->closure[sd->num_closure];
@@ -388,7 +387,7 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st
/* disable in case of diffuse ancestor, can't see it well then and
* adds considerably noise due to probabilities of continuing path
* getting lower and lower */
- if(type != CLOSURE_BSSRDF_COMPATIBLE_ID && (path_flag & PATH_RAY_DIFFUSE_ANCESTOR))
+ if(path_flag & PATH_RAY_DIFFUSE_ANCESTOR)
param1 = 0.0f;
if(sample_weight > 1e-5f && sd->num_closure+2 < MAX_CLOSURE) {
diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h
index 50daf159f26..abd63530d63 100644
--- a/intern/cycles/kernel/svm/svm_types.h
+++ b/intern/cycles/kernel/svm/svm_types.h
@@ -377,7 +377,6 @@ typedef enum ClosureType {
CLOSURE_BSDF_TRANSPARENT_ID,
/* BSSRDF */
- CLOSURE_BSSRDF_COMPATIBLE_ID,
CLOSURE_BSSRDF_CUBIC_ID,
CLOSURE_BSSRDF_GAUSSIAN_ID,
@@ -402,7 +401,7 @@ typedef enum ClosureType {
#define CLOSURE_IS_BSDF_GLOSSY(type) (type >= CLOSURE_BSDF_GLOSSY_ID && type <= CLOSURE_BSDF_HAIR_REFLECTION_ID)
#define CLOSURE_IS_BSDF_TRANSMISSION(type) (type >= CLOSURE_BSDF_TRANSMISSION_ID && type <= CLOSURE_BSDF_HAIR_TRANSMISSION_ID)
#define CLOSURE_IS_BSDF_BSSRDF(type) (type == CLOSURE_BSDF_BSSRDF_ID)
-#define CLOSURE_IS_BSSRDF(type) (type >= CLOSURE_BSSRDF_COMPATIBLE_ID && type <= CLOSURE_BSSRDF_GAUSSIAN_ID)
+#define CLOSURE_IS_BSSRDF(type) (type >= CLOSURE_BSSRDF_CUBIC_ID && type <= CLOSURE_BSSRDF_GAUSSIAN_ID)
#define CLOSURE_IS_VOLUME(type) (type >= CLOSURE_VOLUME_ID && type <= CLOSURE_VOLUME_ISOTROPIC_ID)
#define CLOSURE_IS_EMISSION(type) (type == CLOSURE_EMISSION_ID)
#define CLOSURE_IS_HOLDOUT(type) (type == CLOSURE_HOLDOUT_ID)
diff --git a/intern/cycles/render/CMakeLists.txt b/intern/cycles/render/CMakeLists.txt
index dbbfe2ee7c9..7d00ed92164 100644
--- a/intern/cycles/render/CMakeLists.txt
+++ b/intern/cycles/render/CMakeLists.txt
@@ -18,7 +18,6 @@ set(SRC
background.cpp
blackbody.cpp
buffers.cpp
- bssrdf.cpp
camera.cpp
film.cpp
graph.cpp
@@ -47,7 +46,6 @@ set(SRC_HEADERS
background.h
blackbody.h
buffers.h
- bssrdf.h
camera.h
film.h
graph.h
diff --git a/intern/cycles/render/bssrdf.cpp b/intern/cycles/render/bssrdf.cpp
deleted file mode 100644
index 69cab5e1824..00000000000
--- a/intern/cycles/render/bssrdf.cpp
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright 2011-2013 Blender Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-#include "bssrdf.h"
-
-#include "util_algorithm.h"
-#include "util_math.h"
-#include "util_types.h"
-
-#include "kernel_types.h"
-#include "kernel_montecarlo.h"
-
-CCL_NAMESPACE_BEGIN
-
-static float bssrdf_cubic(float ld, float r)
-{
- if(ld == 0.0f)
- return (r == 0.0f)? 1.0f: 0.0f;
-
- return powf(ld - min(r, ld), 3.0f) * 4.0f/powf(ld, 4.0f);
-}
-
-/* Cumulative density function utilities */
-
-static float cdf_lookup_inverse(const vector<float>& table, float2 range, float x)
-{
- int index = upper_bound(table.begin(), table.end(), x) - table.begin();
-
- if(index == 0)
- return range[0];
- else if(index == table.size())
- return range[1];
- else
- index--;
-
- float t = (x - table[index])/(table[index+1] - table[index]);
- float y = ((index + t)/(table.size() - 1));
-
- return y*(range[1] - range[0]) + range[0];
-}
-
-static void cdf_invert(vector<float>& to, float2 to_range, const vector<float>& from, float2 from_range)
-{
- float step = 1.0f/(float)(to.size() - 1);
-
- for(int i = 0; i < to.size(); i++) {
- float x = (i*step)*(from_range[1] - from_range[0]) + from_range[0];
- to[i] = cdf_lookup_inverse(from, to_range, x);
- }
-}
-
-/* BSSRDF */
-
-static void bssrdf_lookup_table_create(float ld, vector<float>& sample_table, vector<float>& pdf_table)
-{
- const int size = BSSRDF_RADIUS_TABLE_SIZE;
- vector<float> cdf(size);
- vector<float> pdf(size);
- float step = 1.0f/(float)(size - 1);
- float max_radius = ld;
- float pdf_sum = 0.0f;
-
- /* compute the probability density function */
- for(int i = 0; i < pdf.size(); i++) {
- float x = (i*step)*max_radius;
- pdf[i] = bssrdf_cubic(ld, x);
- pdf_sum += pdf[i];
- }
-
- /* adjust for area covered by each distance */
- for(int i = 0; i < pdf.size(); i++) {
- float x = (i*step)*max_radius;
- pdf[i] *= M_2PI_F*x;
- }
-
- /* normalize pdf, we multiply in reflectance later */
- if(pdf_sum > 0.0f)
- for(int i = 0; i < pdf.size(); i++)
- pdf[i] /= pdf_sum;
-
- /* sum to account for sampling which uses overlapping sphere */
- for(int i = pdf.size() - 2; i >= 0; i--)
- pdf[i] = pdf[i] + pdf[i+1];
-
- /* compute the cumulative density function */
- cdf[0] = 0.0f;
-
- for(int i = 1; i < size; i++)
- cdf[i] = cdf[i-1] + 0.5f*(pdf[i-1] + pdf[i])*step*max_radius;
-
- /* invert cumulative density function for importance sampling */
- float2 cdf_range = make_float2(0.0f, cdf[size - 1]);
- float2 table_range = make_float2(0.0f, max_radius);
-
- cdf_invert(sample_table, table_range, cdf, cdf_range);
-
- /* copy pdf table */
- for(int i = 0; i < pdf.size(); i++)
- pdf_table[i] = pdf[i];
-}
-
-void bssrdf_table_build(vector<float>& table)
-{
- vector<float> sample_table(BSSRDF_RADIUS_TABLE_SIZE);
- vector<float> pdf_table(BSSRDF_RADIUS_TABLE_SIZE);
-
- table.resize(BSSRDF_LOOKUP_TABLE_SIZE);
-
- /* create a 2D lookup table, for reflection x sample radius */
- for(int i = 0; i < BSSRDF_REFL_TABLE_SIZE; i++) {
- float radius = 1.0f;
-
- bssrdf_lookup_table_create(radius, sample_table, pdf_table);
-
- memcpy(&table[i*BSSRDF_RADIUS_TABLE_SIZE], &sample_table[0], BSSRDF_RADIUS_TABLE_SIZE*sizeof(float));
- memcpy(&table[BSSRDF_PDF_TABLE_OFFSET + i*BSSRDF_RADIUS_TABLE_SIZE], &pdf_table[0], BSSRDF_RADIUS_TABLE_SIZE*sizeof(float));
- }
-}
-
-CCL_NAMESPACE_END
-
diff --git a/intern/cycles/render/bssrdf.h b/intern/cycles/render/bssrdf.h
deleted file mode 100644
index b8f0d44bc34..00000000000
--- a/intern/cycles/render/bssrdf.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright 2011-2013 Blender Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-#ifndef __BSSRDF_H__
-#define __BSSRDF_H__
-
-#include "util_vector.h"
-
-CCL_NAMESPACE_BEGIN
-
-void bssrdf_table_build(vector<float>& table);
-
-CCL_NAMESPACE_END
-
-#endif /* __BSSRDF_H__ */
-
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index 70cb5613e61..621d52bbbbf 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -20,6 +20,7 @@
#include "osl.h"
#include "sky_model.h"
+#include "util_foreach.h"
#include "util_transform.h"
CCL_NAMESPACE_BEGIN
@@ -41,6 +42,8 @@ TextureMapping::TextureMapping()
y_mapping = Y;
z_mapping = Z;
+ type = TEXTURE;
+
projection = FLAT;
}
@@ -54,12 +57,52 @@ Transform TextureMapping::compute_transform()
mmat[1][y_mapping-1] = 1.0f;
if(z_mapping != NONE)
mmat[2][z_mapping-1] = 1.0f;
+
+ float3 scale_clamped = scale;
- Transform smat = transform_scale(scale);
+ if(type == TEXTURE || type == NORMAL) {
+ /* keep matrix invertible */
+ if(fabsf(scale.x) < 1e-5f)
+ scale_clamped.x = signf(scale.x)*1e-5f;
+ if(fabsf(scale.y) < 1e-5f)
+ scale_clamped.y = signf(scale.y)*1e-5f;
+ if(fabsf(scale.z) < 1e-5f)
+ scale_clamped.z = signf(scale.z)*1e-5f;
+ }
+
+ Transform smat = transform_scale(scale_clamped);
Transform rmat = transform_euler(rotation);
Transform tmat = transform_translate(translation);
- return tmat*rmat*smat*mmat;
+ Transform mat;
+
+ switch(type) {
+ case TEXTURE:
+ /* inverse transform on texture coordinate gives
+ * forward transform on texture */
+ mat = tmat*rmat*smat;
+ mat = transform_inverse(mat);
+ break;
+ case POINT:
+ /* full transform */
+ mat = tmat*rmat*smat;
+ break;
+ case VECTOR:
+ /* no translation for vectors */
+ mat = rmat*smat;
+ break;
+ case NORMAL:
+ /* no translation for normals, and inverse transpose */
+ mat = rmat*smat;
+ mat = transform_inverse(mat);
+ mat = transform_transpose(mat);
+ break;
+ }
+
+ /* projection last */
+ mat = mat*mmat;
+
+ return mat;
}
bool TextureMapping::skip()
@@ -97,6 +140,11 @@ void TextureMapping::compile(SVMCompiler& compiler, int offset_in, int offset_ou
compiler.add_node(float3_to_float4(min));
compiler.add_node(float3_to_float4(max));
}
+
+ if(type == NORMAL) {
+ compiler.add_node(NODE_VECTOR_MATH, NODE_VECTOR_MATH_NORMALIZE, offset_out, offset_out);
+ compiler.add_node(NODE_VECTOR_MATH, SVM_STACK_INVALID, offset_out);
+ }
}
void TextureMapping::compile(OSLCompiler &compiler)
@@ -472,6 +520,9 @@ static void sky_texture_precompute_new(SunSky *sunsky, float3 dir, float turbidi
float theta = spherical.x;
float phi = spherical.y;
+ /* Clamp Turbidity */
+ turbidity = clamp(turbidity, 0.0f, 10.0f);
+
/* Clamp to Horizon */
theta = clamp(theta, 0.0f, M_PI_2_F);
@@ -3677,6 +3728,26 @@ void OSLScriptNode::compile(SVMCompiler& compiler)
void OSLScriptNode::compile(OSLCompiler& compiler)
{
+ /* XXX fix for #36790:
+ * point and normal parameters are reflected as generic SOCK_VECTOR sockets
+ * on the node. Socket fixed input values need to be copied explicitly here for
+ * vector sockets, otherwise OSL will reject the value due to mismatching type.
+ */
+ foreach(ShaderInput *input, this->inputs) {
+ if(!input->link) {
+ /* no need for compatible_name here, OSL parameter names are always unique */
+ string param_name(input->name);
+ switch(input->type) {
+ case SHADER_SOCKET_VECTOR:
+ compiler.parameter_point(param_name.c_str(), input->value);
+ compiler.parameter_normal(param_name.c_str(), input->value);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
if(!filepath.empty())
compiler.add(this, filepath.c_str(), true);
else
diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h
index d58c6633a41..430c37158f4 100644
--- a/intern/cycles/render/nodes.h
+++ b/intern/cycles/render/nodes.h
@@ -43,6 +43,9 @@ public:
float3 min, max;
bool use_minmax;
+ enum Type { POINT = 0, TEXTURE = 1, VECTOR = 2, NORMAL = 3 };
+ Type type;
+
enum Mapping { NONE = 0, X = 1, Y = 2, Z = 3 };
Mapping x_mapping, y_mapping, z_mapping;
diff --git a/intern/cycles/render/shader.cpp b/intern/cycles/render/shader.cpp
index 385395e3752..26af60572f6 100644
--- a/intern/cycles/render/shader.cpp
+++ b/intern/cycles/render/shader.cpp
@@ -15,7 +15,6 @@
*/
#include "background.h"
-#include "bssrdf.h"
#include "blackbody.h"
#include "device.h"
#include "graph.h"
@@ -127,7 +126,6 @@ void Shader::tag_used(Scene *scene)
ShaderManager::ShaderManager()
{
need_update = true;
- bssrdf_table_offset = TABLE_OFFSET_INVALID;
blackbody_table_offset = TABLE_OFFSET_INVALID;
}
@@ -254,23 +252,6 @@ void ShaderManager::device_update_common(Device *device, DeviceScene *dscene, Sc
device->tex_alloc("__shader_flag", dscene->shader_flag);
- /* bssrdf lookup table */
- KernelBSSRDF *kbssrdf = &dscene->data.bssrdf;
-
- if(has_surface_bssrdf && bssrdf_table_offset == TABLE_OFFSET_INVALID) {
- vector<float> table;
-
- bssrdf_table_build(table);
- bssrdf_table_offset = scene->lookup_tables->add_table(dscene, table);
-
- kbssrdf->table_offset = (int)bssrdf_table_offset;
- kbssrdf->num_attempts = BSSRDF_MAX_ATTEMPTS;
- }
- else if(!has_surface_bssrdf && bssrdf_table_offset != TABLE_OFFSET_INVALID) {
- scene->lookup_tables->remove_table(bssrdf_table_offset);
- bssrdf_table_offset = TABLE_OFFSET_INVALID;
- }
-
/* blackbody lookup table */
KernelBlackbody *kblackbody = &dscene->data.blackbody;
@@ -289,11 +270,6 @@ void ShaderManager::device_update_common(Device *device, DeviceScene *dscene, Sc
void ShaderManager::device_free_common(Device *device, DeviceScene *dscene, Scene *scene)
{
- if(bssrdf_table_offset != TABLE_OFFSET_INVALID) {
- scene->lookup_tables->remove_table(bssrdf_table_offset);
- bssrdf_table_offset = TABLE_OFFSET_INVALID;
- }
-
if(blackbody_table_offset != TABLE_OFFSET_INVALID) {
scene->lookup_tables->remove_table(blackbody_table_offset);
blackbody_table_offset = TABLE_OFFSET_INVALID;
diff --git a/intern/cycles/render/shader.h b/intern/cycles/render/shader.h
index a58d6955da0..6869a651b46 100644
--- a/intern/cycles/render/shader.h
+++ b/intern/cycles/render/shader.h
@@ -141,7 +141,6 @@ protected:
typedef unordered_map<ustring, uint, ustringHash> AttributeIDMap;
AttributeIDMap unique_attribute_id;
- size_t bssrdf_table_offset;
size_t blackbody_table_offset;
};
diff --git a/intern/cycles/util/util_opengl.h b/intern/cycles/util/util_opengl.h
index 07a296ed1e6..04a3e039c9d 100644
--- a/intern/cycles/util/util_opengl.h
+++ b/intern/cycles/util/util_opengl.h
@@ -20,12 +20,7 @@
/* OpenGL header includes, used everywhere we use OpenGL, to deal with
* platform differences in one central place. */
-#ifdef __APPLE__
-#include <OpenGL/gl.h>
-#include <OpenGL/glu.h>
-#else
#include <GL/glew.h>
-#endif
#endif /* __UTIL_OPENGL_H__ */
diff --git a/intern/cycles/util/util_types.h b/intern/cycles/util/util_types.h
index f48fd1e124b..a8f514864db 100644
--- a/intern/cycles/util/util_types.h
+++ b/intern/cycles/util/util_types.h
@@ -545,10 +545,7 @@ template<size_t i0, size_t i1, size_t i2, size_t i3> __device_inline const __m12
#ifdef __KERNEL_OPENCL__
-__device_inline void float4_store_half(half *h, const float4 *f, float scale)
-{
- vstore_half4(*f * scale, 0, h);
-}
+#define float4_store_half(h, f, scale) vstore_half4(*(f) * (scale), 0, h);
#else
diff --git a/intern/elbeem/CMakeLists.txt b/intern/elbeem/CMakeLists.txt
index 2adeb573f06..887abea3604 100644
--- a/intern/elbeem/CMakeLists.txt
+++ b/intern/elbeem/CMakeLists.txt
@@ -25,6 +25,7 @@
set(INC
extern
+ ../guardedalloc
)
set(INC_SYS
diff --git a/intern/elbeem/SConscript b/intern/elbeem/SConscript
index 133f02e41bc..e3a20cf9d45 100644
--- a/intern/elbeem/SConscript
+++ b/intern/elbeem/SConscript
@@ -43,6 +43,6 @@ if env['WITH_BF_OPENMP']:
if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
defs += ' USE_MSVC6FIXES'
incs += ' ' + env['BF_PNG_INC'] + ' ' + env['BF_ZLIB_INC']
-incs += ' extern '
+incs += ' extern ../../guardedalloc'
env.BlenderLib ('bf_intern_elbeem', sources, Split(incs), Split(defs), libtype='intern', priority=0 )
diff --git a/intern/elbeem/intern/attributes.h b/intern/elbeem/intern/attributes.h
index b2fbd7fd910..f5617313f69 100644
--- a/intern/elbeem/intern/attributes.h
+++ b/intern/elbeem/intern/attributes.h
@@ -14,6 +14,11 @@
#ifndef NTL_ATTRIBUTES_H
#include "utilities.h"
+
+#ifdef WITH_CXX_GUARDEDALLOC
+# include "MEM_guardedalloc.h"
+#endif
+
template<class T> class ntlMatrix4x4;
class ntlSetVec3f;
std::ostream& operator<<( std::ostream& os, const ntlSetVec3f& i );
@@ -110,6 +115,11 @@ class AnimChannel
vector<Scalar> mValue;
/*! anim channel attr times */
vector<double> mTimes;
+
+private:
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:AnimChannel")
+#endif
};
@@ -127,6 +137,11 @@ class ntlSetVec3f {
ntlSetVec3f& operator*=( const ntlSetVec3f &v );
vector<ntlVec3f> mVerts;
+
+private:
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:ntlSetVec3f")
+#endif
};
@@ -163,6 +178,11 @@ class Attribute
protected:
bool initChannel(int elemSize);
+
+private:
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:Attribute")
+#endif
};
@@ -195,6 +215,11 @@ class AttributeList
bool ignoreParameter(string name, string source);
void print();
protected:
+
+private:
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:AttributeList")
+#endif
};
ntlVec3f channelFindMaxVf (AnimChannel<ntlVec3f> channel);
diff --git a/intern/elbeem/intern/controlparticles.h b/intern/elbeem/intern/controlparticles.h
index 6b4b77881cc..915ede66fe6 100644
--- a/intern/elbeem/intern/controlparticles.h
+++ b/intern/elbeem/intern/controlparticles.h
@@ -18,6 +18,10 @@
#include "ntl_geometrymodel.h"
+#ifdef WITH_CXX_GUARDEDALLOC
+# include "MEM_guardedalloc.h"
+#endif
+
// indicator for LBM inclusion
//#ifndef LBMDIM
@@ -80,6 +84,11 @@ public:
forceAtt = forceVel = forceMaxd = LbmVec(0.,0.,0.);
compAvWeight=0.; compAv=LbmVec(0.);
};
+
+private:
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:ControlForces")
+#endif
};
@@ -115,6 +124,11 @@ public:
// init all zero / defaults
void reset();
+
+private:
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:ControlParticle")
+#endif
};
@@ -128,6 +142,10 @@ public:
// particle positions
std::vector<ControlParticle> particles;
+private:
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:ControlParticleSet")
+#endif
};
@@ -296,6 +314,11 @@ protected:
void initTimeArray(LbmFloat t, std::vector<ControlParticle> &parts);
bool checkPointInside(ntlTree *tree, ntlVec3Gfx org, gfxReal &distance);
+
+private:
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:ControlParticles")
+#endif
};
diff --git a/intern/elbeem/intern/isosurface.h b/intern/elbeem/intern/isosurface.h
index be78db9b293..15b923866d3 100644
--- a/intern/elbeem/intern/isosurface.h
+++ b/intern/elbeem/intern/isosurface.h
@@ -15,6 +15,10 @@
#include "ntl_geometryobject.h"
#include "ntl_bsptree.h"
+#ifdef WITH_CXX_GUARDEDALLOC
+# include "MEM_guardedalloc.h"
+#endif
+
#define ISO_STRICT_DEBUG 0
#define ISOSTRICT_EXIT *((int *)0)=0;
@@ -224,6 +228,11 @@ class IsoSurface :
vector<int> mDboundary;
float mSCrad1, mSCrad2;
ntlVec3Gfx mSCcenter;
+
+private:
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:IsoSurface")
+#endif
};
diff --git a/intern/elbeem/intern/mvmcoords.h b/intern/elbeem/intern/mvmcoords.h
index cb51e91d467..56d991aac6e 100644
--- a/intern/elbeem/intern/mvmcoords.h
+++ b/intern/elbeem/intern/mvmcoords.h
@@ -34,6 +34,10 @@
#include "ieeefp.h"
#endif
+#ifdef WITH_CXX_GUARDEDALLOC
+# include "MEM_guardedalloc.h"
+#endif
+
// weight and triangle index
class mvmIndexWeight {
public:
@@ -49,6 +53,11 @@ class mvmIndexWeight {
mvmFloat weight;
int index;
+
+private:
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:mvmIndexWeight")
+#endif
};
// transfer point with weights
@@ -58,6 +67,11 @@ class mvmTransferPoint {
ntlVec3Gfx lastpos;
//! triangle weights
std::vector<mvmIndexWeight> weights;
+
+private:
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:mvmTransferPoint")
+#endif
};
@@ -86,6 +100,10 @@ class MeanValueMeshCoords {
std::vector<mvmTransferPoint> mVertices;
int mNumVerts;
+private:
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:MeanValueMeshCoords")
+#endif
};
#endif
diff --git a/intern/elbeem/intern/ntl_blenderdumper.h b/intern/elbeem/intern/ntl_blenderdumper.h
index cd1331afa83..473e746463c 100644
--- a/intern/elbeem/intern/ntl_blenderdumper.h
+++ b/intern/elbeem/intern/ntl_blenderdumper.h
@@ -12,6 +12,10 @@
#ifndef NTL_BLENDERDUMPER_H
#include "ntl_world.h"
+#ifdef WITH_CXX_GUARDEDALLOC
+# include "MEM_guardedalloc.h"
+#endif
+
class ntlBlenderDumper :
public ntlWorld
{
@@ -27,6 +31,10 @@ public:
protected:
+private:
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:ntlBlenderDumper")
+#endif
};
#define NTL_BLENDERDUMPER_H
diff --git a/intern/elbeem/intern/ntl_bsptree.h b/intern/elbeem/intern/ntl_bsptree.h
index 775a216fba8..9c6bf37c591 100644
--- a/intern/elbeem/intern/ntl_bsptree.h
+++ b/intern/elbeem/intern/ntl_bsptree.h
@@ -22,6 +22,9 @@
#define BSP_STACK_SIZE 50
+#ifdef WITH_CXX_GUARDEDALLOC
+# include "MEM_guardedalloc.h"
+#endif
//! bsp tree stack classes, defined in ntl_bsptree.cpp,
// detailed definition unnecesseary here
@@ -120,6 +123,10 @@ class ntlTree
//! duplicated triangles, inited during subdivide
int mTriDoubles;
+private:
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:ntlTree")
+#endif
};
diff --git a/intern/elbeem/intern/ntl_geometryclass.h b/intern/elbeem/intern/ntl_geometryclass.h
index 5b7ff1492db..9d8f1ee23d5 100644
--- a/intern/elbeem/intern/ntl_geometryclass.h
+++ b/intern/elbeem/intern/ntl_geometryclass.h
@@ -16,6 +16,10 @@
#include "attributes.h"
+#ifdef WITH_CXX_GUARDEDALLOC
+# include "MEM_guardedalloc.h"
+#endif
+
//! geometry class type ids
#define GEOCLASSTID_OBJECT 1
#define GEOCLASSTID_SHADER 2
@@ -111,6 +115,10 @@ class ntlGeometryClass
private:
+private:
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:ntlGeometryClass")
+#endif
};
diff --git a/intern/elbeem/intern/ntl_geometrymodel.h b/intern/elbeem/intern/ntl_geometrymodel.h
index 93fe2076811..08d3bcb16a3 100644
--- a/intern/elbeem/intern/ntl_geometrymodel.h
+++ b/intern/elbeem/intern/ntl_geometrymodel.h
@@ -14,6 +14,10 @@
#include "ntl_geometryobject.h"
+#ifdef WITH_CXX_GUARDEDALLOC
+# include "MEM_guardedalloc.h"
+#endif
+
/*! A simple box object generatedd by 12 triangles */
class ntlGeometryObjModel : public ntlGeometryObject
{
@@ -89,6 +93,11 @@ class ntlGeometryObjModel : public ntlGeometryObject
/*! set data file name */
inline void setFilename(string set) { mFilename = set; }
+
+private:
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:ntlGeometryObjModel")
+#endif
};
#endif
diff --git a/intern/elbeem/intern/ntl_geometryobject.h b/intern/elbeem/intern/ntl_geometryobject.h
index 677f132f4c3..2c229193358 100644
--- a/intern/elbeem/intern/ntl_geometryobject.h
+++ b/intern/elbeem/intern/ntl_geometryobject.h
@@ -16,6 +16,11 @@
#include "ntl_geometryclass.h"
#include "ntl_lighting.h"
#include "ntl_ray.h"
+
+#ifdef WITH_CXX_GUARDEDALLOC
+# include "MEM_guardedalloc.h"
+#endif
+
class ntlRenderGlobals;
class ntlTriangle;
@@ -240,6 +245,10 @@ class ntlGeometryObject : public ntlGeometryClass
public:
+private:
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:ntlGeometryObject")
+#endif
};
#endif
diff --git a/intern/elbeem/intern/ntl_geometryshader.h b/intern/elbeem/intern/ntl_geometryshader.h
index f43df6539e6..7e0d61f453e 100644
--- a/intern/elbeem/intern/ntl_geometryshader.h
+++ b/intern/elbeem/intern/ntl_geometryshader.h
@@ -13,6 +13,11 @@
#define NTL_GEOMETRYSHADER_H
#include "ntl_geometryclass.h"
+
+#ifdef WITH_CXX_GUARDEDALLOC
+# include "MEM_guardedalloc.h"
+#endif
+
class ntlGeometryObject;
class ntlRenderGlobals;
@@ -57,6 +62,11 @@ class ntlGeometryShader :
/*! surface output name for this simulation */
string mOutFilename;
+
+private:
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:ntlGeometryShader")
+#endif
};
#endif
diff --git a/intern/elbeem/intern/ntl_lighting.h b/intern/elbeem/intern/ntl_lighting.h
index 88fcaef90e6..0cae32f40ad 100644
--- a/intern/elbeem/intern/ntl_lighting.h
+++ b/intern/elbeem/intern/ntl_lighting.h
@@ -14,6 +14,11 @@
#define NTL_LIGHTING_H
#include "ntl_vector3dim.h"
+
+#ifdef WITH_CXX_GUARDEDALLOC
+# include "MEM_guardedalloc.h"
+#endif
+
class ntlMaterial;
class ntlRay;
class ntlRenderGlobals;
@@ -88,6 +93,10 @@ protected:
private:
+private:
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:ntlLightObject")
+#endif
};
@@ -195,6 +204,10 @@ public:
//! Set Fresnel on/off
inline void setFresnel(int set) { mFresnel = set; }
+private:
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:ntlMaterial")
+#endif
};
diff --git a/intern/elbeem/intern/ntl_matrices.h b/intern/elbeem/intern/ntl_matrices.h
index ab2a30b49f2..597fcf1c64e 100644
--- a/intern/elbeem/intern/ntl_matrices.h
+++ b/intern/elbeem/intern/ntl_matrices.h
@@ -14,6 +14,9 @@
#include "ntl_vector3dim.h"
+#ifdef WITH_CXX_GUARDEDALLOC
+# include "MEM_guardedalloc.h"
+#endif
// The basic vector class
template<class Scalar>
@@ -96,6 +99,10 @@ public:
protected:
+private:
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:ntlMatrix4x4")
+#endif
};
diff --git a/intern/elbeem/intern/ntl_ray.h b/intern/elbeem/intern/ntl_ray.h
index 5f6d34e3020..6384edcb1b1 100644
--- a/intern/elbeem/intern/ntl_ray.h
+++ b/intern/elbeem/intern/ntl_ray.h
@@ -18,6 +18,10 @@
#include "ntl_geometryobject.h"
#include "ntl_bsptree.h"
+#ifdef WITH_CXX_GUARDEDALLOC
+# include "MEM_guardedalloc.h"
+#endif
+
class ntlTriangle;
class ntlRay;
class ntlTree;
@@ -39,6 +43,11 @@ class ntlIntersection {
ntlRay *ray;
ntlTriangle *tri;
char flags;
+
+private:
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:ntlIntersection")
+#endif
};
//! the main ray class
@@ -138,6 +147,10 @@ private:
/*! ID of this ray (from renderglobals */
int mID;
+private:
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:ntlRay")
+#endif
};
@@ -225,6 +238,10 @@ private:
/*! ID of last ray that an intersection was calculated for */
int mLastRay;
+private:
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:ntlTriangle")
+#endif
};
@@ -410,6 +427,10 @@ private:
/*! shader/obj initializations are only done on first init */
bool mFirstInitDone;
+private:
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:ntlScene")
+#endif
};
diff --git a/intern/elbeem/intern/ntl_vector3dim.h b/intern/elbeem/intern/ntl_vector3dim.h
index e3e492c396e..38a6d2da80b 100644
--- a/intern/elbeem/intern/ntl_vector3dim.h
+++ b/intern/elbeem/intern/ntl_vector3dim.h
@@ -32,6 +32,10 @@
#include <stdio.h>
#include <stdlib.h>
+#ifdef WITH_CXX_GUARDEDALLOC
+# include "MEM_guardedalloc.h"
+#endif
+
/* absolute value */
template < class T >
inline T
@@ -205,6 +209,11 @@ protected:
private:
Scalar value[3]; //< Storage of vector values
+
+private:
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:ntlVector3Dim")
+#endif
};
diff --git a/intern/elbeem/intern/ntl_world.h b/intern/elbeem/intern/ntl_world.h
index 6cec098132b..30b7cbf4d92 100644
--- a/intern/elbeem/intern/ntl_world.h
+++ b/intern/elbeem/intern/ntl_world.h
@@ -18,6 +18,11 @@
#include "ntl_geometryobject.h"
#include "simulation_object.h"
#include "elbeem.h"
+
+#ifdef WITH_CXX_GUARDEDALLOC
+# include "MEM_guardedalloc.h"
+#endif
+
class ntlOpenGLRenderer;
class ntlScene;
class SimulationObject;
@@ -119,6 +124,11 @@ class ntlWorld
/*! count no. of frame for correct sim time */
int mSimFrameCnt;
vector<int> mSimFrameValue;
+
+private:
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:ntlWorld")
+#endif
};
@@ -389,6 +399,11 @@ private:
bool mSingleFrameMode;
//! filename for single frame mode
string mSingleFrameFilename;
+
+private:
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:ntlRenderGlobals")
+#endif
};
diff --git a/intern/elbeem/intern/parametrizer.h b/intern/elbeem/intern/parametrizer.h
index f3ea3186654..2d96b5b039f 100644
--- a/intern/elbeem/intern/parametrizer.h
+++ b/intern/elbeem/intern/parametrizer.h
@@ -17,6 +17,10 @@
#include "utilities.h"
#include "attributes.h"
+#ifdef WITH_CXX_GUARDEDALLOC
+# include "MEM_guardedalloc.h"
+#endif
+
/* parametrizer accuracy */
typedef double ParamFloat;
typedef ntlVec3d ParamVec;
@@ -306,6 +310,11 @@ class Parametrizer {
/*! pointer to the attribute list */
AttributeList *mpAttrs;
+
+private:
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:Parametrizer")
+#endif
};
diff --git a/intern/elbeem/intern/particletracer.cpp b/intern/elbeem/intern/particletracer.cpp
index d6bc450198f..593b582d91f 100644
--- a/intern/elbeem/intern/particletracer.cpp
+++ b/intern/elbeem/intern/particletracer.cpp
@@ -53,6 +53,7 @@ ParticleTracer::ParticleTracer() :
ParticleTracer::~ParticleTracer() {
debMsgStd("ParticleTracer::~ParticleTracer",DM_MSG,"destroyed",10);
+ if(mpTrafo) delete mpTrafo;
}
/*****************************************************************************/
diff --git a/intern/elbeem/intern/particletracer.h b/intern/elbeem/intern/particletracer.h
index 5d328907e71..c14c8e2f0cb 100644
--- a/intern/elbeem/intern/particletracer.h
+++ b/intern/elbeem/intern/particletracer.h
@@ -12,6 +12,11 @@
#ifndef NTL_PARTICLETRACER_H
#include "ntl_geometryobject.h"
+
+#ifdef WITH_CXX_GUARDEDALLOC
+# include "MEM_guardedalloc.h"
+#endif
+
template<class Scalar> class ntlMatrix4x4;
// particle types
@@ -131,6 +136,11 @@ class ParticleObject
/* for list constructions */
ParticleObject *mpNext;
+
+private:
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:ParticleObject")
+#endif
};
@@ -274,6 +284,11 @@ class ParticleTracer :
/* prev pos save interval */
float mTrailTimeLast, mTrailInterval;
int mTrailLength;
+
+private:
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:ParticleTracer")
+#endif
};
#define NTL_PARTICLETRACER_H
diff --git a/intern/elbeem/intern/simulation_object.cpp b/intern/elbeem/intern/simulation_object.cpp
index 9e98adfc734..99c3b170634 100644
--- a/intern/elbeem/intern/simulation_object.cpp
+++ b/intern/elbeem/intern/simulation_object.cpp
@@ -32,10 +32,6 @@
//! lbm factory functions
LbmSolverInterface* createSolver();
-#if PARALLEL==1
-static int omp_threadcache;
-#endif
-
/******************************************************************************
* Constructor
*****************************************************************************/
@@ -71,10 +67,6 @@ SimulationObject::~SimulationObject()
if(mpParam) delete mpParam;
if(mpParts) delete mpParts;
debMsgStd("SimulationObject",DM_MSG,"El'Beem Done!\n",10);
-#if (PARALLEL == 1)
- omp_set_num_threads(omp_threadcache);
- printf("Resetting omp_threads to cached value %d \n", omp_threadcache);
-#endif
}
@@ -185,9 +177,7 @@ int SimulationObject::initializeLbmSimulation(ntlRenderGlobals *glob)
mpLbm->setSmoothing(1.0 * mpElbeemSettings->surfaceSmoothing, 1.0 * mpElbeemSettings->surfaceSmoothing);
mpLbm->setIsoSubdivs(mpElbeemSettings->surfaceSubdivs);
#if PARALLEL==1
- omp_threadcache = omp_get_max_threads();
- omp_set_num_threads(mpElbeemSettings->threads);
- printf("Setting omp_threads to usersetting %d \n", mpElbeemSettings->threads);
+ mpLbm->setNumOMPThreads(mpElbeemSettings->threads);
#endif
mpLbm->setSizeX(mpElbeemSettings->resolutionxyz);
mpLbm->setSizeY(mpElbeemSettings->resolutionxyz);
diff --git a/intern/elbeem/intern/simulation_object.h b/intern/elbeem/intern/simulation_object.h
index 76684fa6f83..4a89d1510a9 100644
--- a/intern/elbeem/intern/simulation_object.h
+++ b/intern/elbeem/intern/simulation_object.h
@@ -18,6 +18,10 @@
#include "ntl_geometryshader.h"
#include "parametrizer.h"
+#ifdef WITH_CXX_GUARDEDALLOC
+# include "MEM_guardedalloc.h"
+#endif
+
class LbmSolverInterface;
class CellIdentifierInterface;
class ntlTree;
@@ -188,6 +192,11 @@ class SimulationObject :
virtual inline ntlVec3Gfx *getBBStart() { return &mGeoStart; }
virtual inline ntlVec3Gfx *getBBEnd() { return &mGeoEnd; }
+
+private:
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:SimulationObject")
+#endif
};
diff --git a/intern/elbeem/intern/solver_class.h b/intern/elbeem/intern/solver_class.h
index 1962e801a4e..593fea1b998 100644
--- a/intern/elbeem/intern/solver_class.h
+++ b/intern/elbeem/intern/solver_class.h
@@ -21,6 +21,10 @@
#include "ntl_ray.h"
#include <stdio.h>
+#ifdef WITH_CXX_GUARDEDALLOC
+# include "MEM_guardedalloc.h"
+#endif
+
#if PARALLEL==1
#include <omp.h>
#endif // PARALLEL=1
@@ -145,6 +149,11 @@ class UniformFsgrCellIdentifier :
if( x==cid->x && y==cid->y && z==cid->z && level==cid->level ) return true;
return false;
}
+
+private:
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:UniformFsgrCellIdentifier")
+#endif
};
//! information needed for each level in the simulation
@@ -193,6 +202,10 @@ public:
int lSizex, lSizey, lSizez;
int lOffsx, lOffsy, lOffsz;
+private:
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:FsgrLevelData")
+#endif
};
@@ -740,6 +753,11 @@ class LbmFsgrSolver :
static LbmFloat lesCoeffOffdiag[ 2 ][ 9 ];
# endif // LBMDIM==2
+
+private:
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:LbmFsgrSolver")
+#endif
};
#undef STCON
diff --git a/intern/elbeem/intern/solver_control.cpp b/intern/elbeem/intern/solver_control.cpp
index 75134804f13..c3015b82f0a 100644
--- a/intern/elbeem/intern/solver_control.cpp
+++ b/intern/elbeem/intern/solver_control.cpp
@@ -225,7 +225,10 @@ LbmFsgrSolver::initCpdata()
// manually switch on! if this is zero, nothing is done...
mpControl->mSetForceStrength = this->mTForceStrength = 1.;
- mpControl->mCons.clear();
+ while (!mpControl->mCons.empty()) {
+ delete mpControl->mCons.back(); mpControl->mCons.pop_back();
+ }
+
// init all control fluid objects
int numobjs = (int)(mpGiObjects->size());
@@ -264,7 +267,9 @@ LbmFsgrSolver::initCpdata()
if(0) {
// manually switch on! if this is zero, nothing is done...
mpControl->mSetForceStrength = this->mTForceStrength = 1.;
- mpControl->mCons.clear();
+ while (!mpControl->mCons.empty()) {
+ delete mpControl->mCons.back(); mpControl->mCons.pop_back();
+ }
// add new set
LbmControlSet *cset;
diff --git a/intern/elbeem/intern/solver_control.h b/intern/elbeem/intern/solver_control.h
index afbe5394918..d20823d1827 100644
--- a/intern/elbeem/intern/solver_control.h
+++ b/intern/elbeem/intern/solver_control.h
@@ -16,6 +16,10 @@
#ifndef LBM_TESTCLASS_H
#define LBM_TESTCLASS_H
+#ifdef WITH_CXX_GUARDEDALLOC
+# include "MEM_guardedalloc.h"
+#endif
+
//class IsoSurface;
class ParticleObject;
class ControlParticles;
@@ -147,6 +151,11 @@ class LbmControlSet {
AnimChannel<ntlVec3f> mcCpScale;
AnimChannel<ntlVec3f> mcCpOffset;
+
+private:
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:LbmControlSet")
+#endif
};
@@ -180,6 +189,11 @@ class LbmControlData
// cp debug displau
LbmFloat mDebugCpscale, mDebugVelScale, mDebugCompavScale, mDebugAttScale, mDebugMaxdScale, mDebugAvgVelScale;
+
+private:
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:LbmControlData ")
+#endif
};
#endif // LBM_TESTCLASS_H
diff --git a/intern/elbeem/intern/solver_interface.cpp b/intern/elbeem/intern/solver_interface.cpp
index c3421fe1968..d5221048020 100644
--- a/intern/elbeem/intern/solver_interface.cpp
+++ b/intern/elbeem/intern/solver_interface.cpp
@@ -65,6 +65,9 @@ LbmSolverInterface::LbmSolverInterface() :
mDumpRawText(false),
mDumpRawBinary(false),
mDumpRawBinaryZip(true)
+#if PARALLEL==1
+ , mNumOMPThreads(1)
+#endif // PARALLEL==1
{
#if ELBEEM_PLUGIN==1
if(gDebugLevel<=1) setSilent(true);
@@ -670,6 +673,12 @@ void LbmSolverInterface::markedClearList() {
mMarkedCells.clear();
}
+#if PARALLEL==1
+void LbmSolverInterface::setNumOMPThreads(int num_threads) {
+ mNumOMPThreads = num_threads;
+}
+#endif // PARALLEL==1
+
/*******************************************************************************/
/*! string helper functions */
/*******************************************************************************/
diff --git a/intern/elbeem/intern/solver_interface.h b/intern/elbeem/intern/solver_interface.h
index 8f3181a307d..e4720df307b 100644
--- a/intern/elbeem/intern/solver_interface.h
+++ b/intern/elbeem/intern/solver_interface.h
@@ -35,6 +35,11 @@
#include "parametrizer.h"
#include "attributes.h"
#include "isosurface.h"
+
+#ifdef WITH_CXX_GUARDEDALLOC
+# include "MEM_guardedalloc.h"
+#endif
+
class ParticleTracer;
class ParticleObject;
@@ -171,6 +176,11 @@ class LbmCellContents {
CellFlagType flag;
BubbleId bubble;
LbmFloat ffrac;
+
+private:
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:LbmCellContents")
+#endif
};
/* struct for the coordinates of a cell in the grid */
@@ -224,6 +234,10 @@ class CellIdentifierInterface {
//! has the grid been traversed?
bool mEnd;
+private:
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:CellIdentifierInterface")
+#endif
};
@@ -452,7 +466,9 @@ class LbmSolverInterface
CellIdentifierInterface* markedAdvanceCell();
void markedClearList();
-
+#if PARALLEL==1
+ void setNumOMPThreads(int num_threads);
+#endif // PARALLEL==1
protected:
/*! abort simulation on error... */
@@ -595,6 +611,15 @@ class LbmSolverInterface
bool mDumpRawText;
bool mDumpRawBinary;
bool mDumpRawBinaryZip;
+
+#if PARALLEL==1
+ int mNumOMPThreads;
+#endif // PARALLEL==1
+
+private:
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:LbmSolverInterface")
+#endif
};
diff --git a/intern/elbeem/intern/solver_main.cpp b/intern/elbeem/intern/solver_main.cpp
index 99278657fd9..46af6740cf1 100644
--- a/intern/elbeem/intern/solver_main.cpp
+++ b/intern/elbeem/intern/solver_main.cpp
@@ -378,7 +378,7 @@ LbmFsgrSolver::mainLoop(int lev)
const int gridLoopBound=1;
GRID_REGION_INIT();
#if PARALLEL==1
-#pragma omp parallel default(shared) \
+#pragma omp parallel default(shared) num_threads(mNumOMPThreads) \
reduction(+: \
calcCurrentMass,calcCurrentVolume, \
calcCellsFilled,calcCellsEmptied, \
@@ -1119,7 +1119,7 @@ LbmFsgrSolver::preinitGrids()
GRID_REGION_INIT();
#if PARALLEL==1
-#pragma omp parallel default(shared) \
+#pragma omp parallel default(shared) num_threads(mNumOMPThreads) \
reduction(+: \
calcCurrentMass,calcCurrentVolume, \
calcCellsFilled,calcCellsEmptied, \
@@ -1156,7 +1156,7 @@ LbmFsgrSolver::standingFluidPreinit()
GRID_REGION_INIT();
#if PARALLEL==1
-#pragma omp parallel default(shared) \
+#pragma omp parallel default(shared) num_threads(mNumOMPThreads) \
reduction(+: \
calcCurrentMass,calcCurrentVolume, \
calcCellsFilled,calcCellsEmptied, \
diff --git a/intern/ghost/SConscript b/intern/ghost/SConscript
index fb289801e7a..fed8cd7aa3c 100644
--- a/intern/ghost/SConscript
+++ b/intern/ghost/SConscript
@@ -157,8 +157,9 @@ if window_system in ('win32-vc', 'win64-vc'):
elif env['WITH_GHOST_COCOA']: # always use default-Apple-gcc for objC language, for gnu-compilers do not support it fully yet
env.BlenderLib ('bf_intern_ghost', sources, Split(incs), defines=defs, libtype=['intern','player'], priority = [40,15], cc_compilerchange='/usr/bin/gcc', cxx_compilerchange='/usr/bin/g++' )
- env.BlenderLib ('bf_intern_ghostndof3dconnexion', sources2, Split(incs), defines=defs, libtype=['intern','player'], priority = [40,15], cc_compilerchange='/usr/bin/gcc', cxx_compilerchange='/usr/bin/g++' )
print "GHOST COCOA WILL BE COMPILED WITH APPLE GCC"
+ if env['WITH_BF_3DMOUSE']:
+ env.BlenderLib ('bf_intern_ghostndof3dconnexion', sources2, Split(incs), defines=defs, libtype=['intern','player'], priority = [40,15], cc_compilerchange='/usr/bin/gcc', cxx_compilerchange='/usr/bin/g++' )
else:
env.BlenderLib ('bf_intern_ghost', sources, Split(incs), defines=defs, libtype=['intern','player'], priority = [40,15] )
diff --git a/intern/ghost/intern/GHOST_DisplayManagerCocoa.mm b/intern/ghost/intern/GHOST_DisplayManagerCocoa.mm
index 555f883cbf2..876be90025f 100644
--- a/intern/ghost/intern/GHOST_DisplayManagerCocoa.mm
+++ b/intern/ghost/intern/GHOST_DisplayManagerCocoa.mm
@@ -52,8 +52,6 @@ GHOST_TSuccess GHOST_DisplayManagerCocoa::getNumDisplays(GHOST_TUns8& numDisplay
GHOST_TSuccess GHOST_DisplayManagerCocoa::getNumDisplaySettings(GHOST_TUns8 display, GHOST_TInt32& numSettings) const
{
- GHOST_ASSERT((display==kMainDisplay), "GHOST_DisplayManagerCocoa::getNumDisplaySettings(): only main display is supported");
-
numSettings = (GHOST_TInt32)3; //Width, Height, BitsPerPixel
return GHOST_kSuccess;
@@ -62,11 +60,8 @@ GHOST_TSuccess GHOST_DisplayManagerCocoa::getNumDisplaySettings(GHOST_TUns8 disp
GHOST_TSuccess GHOST_DisplayManagerCocoa::getDisplaySetting(GHOST_TUns8 display, GHOST_TInt32 index, GHOST_DisplaySetting& setting) const
{
- //Note that only current display setting is available
NSScreen *askedDisplay;
- GHOST_ASSERT((display==kMainDisplay), "GHOST_DisplayManagerCocoa::getDisplaySetting(): only main display is supported");
-
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
if (display == kMainDisplay) //Screen #0 may not be the main one
@@ -74,7 +69,7 @@ GHOST_TSuccess GHOST_DisplayManagerCocoa::getDisplaySetting(GHOST_TUns8 display,
else
askedDisplay = [[NSScreen screens] objectAtIndex:display];
- if(askedDisplay == nil) {
+ if (askedDisplay == nil) {
[pool drain];
return GHOST_kFailure;
}
@@ -109,7 +104,7 @@ GHOST_TSuccess GHOST_DisplayManagerCocoa::getCurrentDisplaySetting(GHOST_TUns8 d
else
askedDisplay = [[NSScreen screens] objectAtIndex:display];
- if(askedDisplay == nil) {
+ if (askedDisplay == nil) {
[pool drain];
return GHOST_kFailure;
}
diff --git a/intern/ghost/intern/GHOST_NDOFManager3Dconnexion.c b/intern/ghost/intern/GHOST_NDOFManager3Dconnexion.c
index 2efa0e6d5e8..9df9a56f8b8 100644
--- a/intern/ghost/intern/GHOST_NDOFManager3Dconnexion.c
+++ b/intern/ghost/intern/GHOST_NDOFManager3Dconnexion.c
@@ -30,7 +30,7 @@
/* It is to be noted that these implementations are linked in as
* 'extern "C"' calls from GHOST_NDOFManagerCocoa.
-
+
* This is done in order to
* preserve weak linking capability (which as of clang-3.3 and xcode5
* breaks weak linking when there is name mangling of c++ libraries.)
@@ -42,42 +42,53 @@
OSErr GHOST_NDOFManager3Dconnexion_available(void)
{
- // extern unsigned int InstallConnexionHandlers() __attribute__((weak_import));
- // Make the linker happy for the framework check (see link below for more info)
- // http://developer.apple.com/documentation/MacOSX/Conceptual/BPFrameworks/Concepts/WeakLinking.html
- return InstallConnexionHandlers != 0;
- // this means that the driver is installed and dynamically linked to blender
+ // extern unsigned int InstallConnexionHandlers() __attribute__((weak_import));
+ // Make the linker happy for the framework check (see link below for more info)
+ // http://developer.apple.com/documentation/MacOSX/Conceptual/BPFrameworks/Concepts/WeakLinking.html
+ return InstallConnexionHandlers != 0;
+ // this means that the driver is installed and dynamically linked to blender
}
OSErr GHOST_NDOFManager3Dconnexion_oldDRV()
{
- //extern unsigned int SetConnexionClientButtonMask() __attribute__((weak_import));
- // Make the linker happy for the framework check (see link below for more info)
- // http://developer.apple.com/documentation/MacOSX/Conceptual/BPFrameworks/Concepts/WeakLinking.html
- return SetConnexionClientButtonMask != 0;
- // this means that the driver has this symbol
+ //extern unsigned int SetConnexionClientButtonMask() __attribute__((weak_import));
+ // Make the linker happy for the framework check (see link below for more info)
+ // http://developer.apple.com/documentation/MacOSX/Conceptual/BPFrameworks/Concepts/WeakLinking.html
+ return SetConnexionClientButtonMask != 0;
+ // this means that the driver has this symbol
+}
+
+UInt16 GHOST_NDOFManager3Dconnexion_RegisterConnexionClient(UInt32 signature, UInt8 *name, UInt16 mode, UInt32 mask)
+{
+ return RegisterConnexionClient(signature, name, mode, mask);
+}
+
+void GHOST_NDOFManager3Dconnexion_SetConnexionClientButtonMask(UInt16 clientID, UInt32 buttonMask)
+{
+ return SetConnexionClientButtonMask( clientID, buttonMask);
+}
+
+void GHOST_NDOFManager3Dconnexion_UnregisterConnexionClient(UInt16 clientID)
+{
+ return UnregisterConnexionClient( clientID);
+}
+
+OSErr GHOST_NDOFManager3Dconnexion_InstallConnexionHandlers(
+ ConnexionMessageHandlerProc messageHandler,
+ ConnexionAddedHandlerProc addedHandler,
+ ConnexionRemovedHandlerProc removedHandler)
+{
+ return InstallConnexionHandlers( messageHandler, addedHandler, removedHandler);
}
-UInt16 GHOST_NDOFManager3Dconnexion_RegisterConnexionClient (UInt32 signature, UInt8 *name, UInt16 mode, UInt32 mask) {
- return RegisterConnexionClient(signature, name, mode, mask);
-};
-void GHOST_NDOFManager3Dconnexion_SetConnexionClientButtonMask (UInt16 clientID, UInt32 buttonMask){
- return SetConnexionClientButtonMask( clientID, buttonMask);
-};
-void GHOST_NDOFManager3Dconnexion_UnregisterConnexionClient (UInt16 clientID){
- return UnregisterConnexionClient( clientID);
-};
-OSErr GHOST_NDOFManager3Dconnexion_InstallConnexionHandlers (ConnexionMessageHandlerProc messageHandler, ConnexionAddedHandlerProc addedHandler, ConnexionRemovedHandlerProc removedHandler){
- return InstallConnexionHandlers( messageHandler, addedHandler, removedHandler);
-
-
-};
-void GHOST_NDOFManager3Dconnexion_CleanupConnexionHandlers (void){
- return CleanupConnexionHandlers();
-};
-OSErr GHOST_NDOFManager3Dconnexion_ConnexionControl(UInt32 message, SInt32 param, SInt32 *result){
-return ConnexionControl( message, param, result);
+void GHOST_NDOFManager3Dconnexion_CleanupConnexionHandlers(void)
+{
+ return CleanupConnexionHandlers();
}
+OSErr GHOST_NDOFManager3Dconnexion_ConnexionControl(UInt32 message, SInt32 param, SInt32 *result)
+{
+ return ConnexionControl( message, param, result);
+}
#endif // WITH_INPUT_NDOF
diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm
index 004821a0857..fcf39523917 100644
--- a/intern/ghost/intern/GHOST_SystemCocoa.mm
+++ b/intern/ghost/intern/GHOST_SystemCocoa.mm
@@ -1018,12 +1018,20 @@ void GHOST_SystemCocoa::notifyExternalEventProcessed()
//Note: called from NSWindow delegate
GHOST_TSuccess GHOST_SystemCocoa::handleWindowEvent(GHOST_TEventType eventType, GHOST_WindowCocoa* window)
{
+ NSArray *windowsList;
+ windowsList = [NSApp orderedWindows];
if (!validWindow(window)) {
return GHOST_kFailure;
}
switch (eventType) {
case GHOST_kEventWindowClose:
- pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowClose, window) );
+ // check for index of mainwindow as it would quit blender without dialog and discard
+ if ([windowsList count] > 1 && window->getCocoaWindow() != [windowsList objectAtIndex:[windowsList count] - 1]) {
+ pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowClose, window) );
+ }
+ else {
+ handleQuitRequest(); // -> quit dialog
+ }
break;
case GHOST_kEventWindowActivate:
m_windowManager->setActiveWindow(window);
@@ -1541,8 +1549,8 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
window->clientToScreenIntern(x_warp+x_accum, y_warp+y_accum, x, y);
pushEvent(new GHOST_EventCursor([event timestamp] * 1000, GHOST_kEventCursorMove, window, x, y));
- }
break;
+ }
case GHOST_kGrabWrap: //Wrap cursor at area/window boundaries
{
NSPoint mousePos = [cocoawindow mouseLocationOutsideOfEventStream];
@@ -1552,7 +1560,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
GHOST_Rect bounds, windowBounds, correctedBounds;
/* fallback to window bounds */
- if(window->getCursorGrabBounds(bounds)==GHOST_kFailure)
+ if (window->getCursorGrabBounds(bounds) == GHOST_kFailure)
window->getClientBounds(bounds);
//Switch back to Cocoa coordinates orientation (y=0 at botton,the same as blender internal btw!), and to client coordinates
@@ -1586,8 +1594,8 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
window->getCursorGrabInitPos(x_cur, y_cur);
window->clientToScreenIntern(x_cur + x_accum, y_cur + y_accum, x, y);
pushEvent(new GHOST_EventCursor([event timestamp] * 1000, GHOST_kEventCursorMove, window, x, y));
- }
break;
+ }
default:
{
//Normal cursor operation: send mouse position in window
@@ -1599,8 +1607,8 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
m_cursorDelta_x=0;
m_cursorDelta_y=0; //Mouse motion occurred between two cursor warps, so we can reset the delta counter
- }
break;
+ }
}
}
break;
@@ -1763,6 +1771,10 @@ GHOST_TSuccess GHOST_SystemCocoa::handleKeyEvent(void *eventPtr)
if ((keyCode > 266) && (keyCode < 271))
utf8_buf[0] = '\0';
+ /* no text with command key pressed */
+ if (m_modifierMask & NSCommandKeyMask)
+ utf8_buf[0] = '\0';
+
if ((keyCode == GHOST_kKeyQ) && (m_modifierMask & NSCommandKeyMask))
break; //Cmd-Q is directly handled by Cocoa
@@ -1854,7 +1866,7 @@ GHOST_TUns8* GHOST_SystemCocoa::getClipboard(bool selection) const
[pool drain];
- if(temp_buff) {
+ if (temp_buff) {
return temp_buff;
}
else {
@@ -1866,7 +1878,7 @@ void GHOST_SystemCocoa::putClipboard(GHOST_TInt8 *buffer, bool selection) const
{
NSString *textToCopy;
- if(selection) {return;} // for copying the selection, used on X11
+ if (selection) return; // for copying the selection, used on X11
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
diff --git a/intern/ghost/intern/GHOST_SystemPathsX11.cpp b/intern/ghost/intern/GHOST_SystemPathsX11.cpp
index 50eb68d9264..e2d9733a9b2 100644
--- a/intern/ghost/intern/GHOST_SystemPathsX11.cpp
+++ b/intern/ghost/intern/GHOST_SystemPathsX11.cpp
@@ -74,13 +74,16 @@ const GHOST_TUns8 *GHOST_SystemPathsX11::getSystemDir(int, const char *versionst
const GHOST_TUns8 *GHOST_SystemPathsX11::getUserDir(int version, const char *versionstr) const
{
static string user_path = "";
+ static int last_version = 0;
/* in blender 2.64, we migrate to XDG. to ensure the copy previous settings
* operator works we give a different path depending on the requested version */
if (version < 264) {
- if (user_path.empty()) {
+ if (user_path.empty() || last_version != version) {
const char *home = getenv("HOME");
+ last_version = version;
+
if (home) {
user_path = string(home) + "/.blender/" + versionstr;
}
@@ -91,9 +94,11 @@ const GHOST_TUns8 *GHOST_SystemPathsX11::getUserDir(int version, const char *ver
return (GHOST_TUns8 *)user_path.c_str();
}
else {
- if (user_path.empty()) {
+ if (user_path.empty() || last_version != version) {
const char *home = getenv("XDG_CONFIG_HOME");
+ last_version = version;
+
if (home) {
user_path = string(home) + "/blender/" + versionstr;
}
diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp
index b43758b345f..ebb419b6c04 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.cpp
+++ b/intern/ghost/intern/GHOST_SystemWin32.cpp
@@ -599,17 +599,19 @@ GHOST_TKey GHOST_SystemWin32::convertKey(GHOST_IWindow *window, short vKey, shor
case VK_GR_LESS: key = GHOST_kKeyGrLess; break;
case VK_SHIFT:
- /* Check single shift presses */
- if (scanCode == 0x36) {
- key = GHOST_kKeyRightShift;
- } else if (scanCode == 0x2a) {
- key = GHOST_kKeyLeftShift;
- } else {
- /* Must be a combination SHIFT (Left or Right) + a Key
- * Ignore this as the next message will contain
- * the desired "Key" */
- key = GHOST_kKeyUnknown;
- }
+ /* Check single shift presses */
+ if (scanCode == 0x36) {
+ key = GHOST_kKeyRightShift;
+ }
+ else if (scanCode == 0x2a) {
+ key = GHOST_kKeyLeftShift;
+ }
+ else {
+ /* Must be a combination SHIFT (Left or Right) + a Key
+ * Ignore this as the next message will contain
+ * the desired "Key" */
+ key = GHOST_kKeyUnknown;
+ }
break;
case VK_CONTROL:
key = (extend) ? GHOST_kKeyRightControl : GHOST_kKeyLeftControl;
@@ -1162,7 +1164,7 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
* message without calling DefWindowProc.
*/
/* we get first WM_SIZE before we fully init. So, do not dispatch before we continiously resizng */
- if(window->m_inLiveResize) {
+ if (window->m_inLiveResize) {
system->pushEvent(processWindowEvent(GHOST_kEventWindowSize, window));
system->dispatchEvents();
}
diff --git a/intern/ghost/intern/GHOST_WindowCocoa.h b/intern/ghost/intern/GHOST_WindowCocoa.h
index fe0830edeae..28a463c47f4 100644
--- a/intern/ghost/intern/GHOST_WindowCocoa.h
+++ b/intern/ghost/intern/GHOST_WindowCocoa.h
@@ -269,7 +269,9 @@ public:
GHOST_TSuccess beginFullScreen() const {return GHOST_kFailure;}
GHOST_TSuccess endFullScreen() const {return GHOST_kFailure;}
-
+
+ /** public function to get the window containing the OpenGL view */
+ CocoaWindow *getCocoaWindow() const {return m_window;};
protected:
/**
diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp
index 2b311f96647..8290f4ee205 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.cpp
+++ b/intern/ghost/intern/GHOST_WindowWin32.cpp
@@ -176,44 +176,58 @@ GHOST_WindowWin32::GHOST_WindowWin32(
}
if (state != GHOST_kWindowStateFullScreen) {
- RECT rect, desktop;
- int wintype = WS_OVERLAPPEDWINDOW;
+ RECT rect;
+ MONITORINFO monitor;
+ GHOST_TUns32 tw, th;
+
+ width += GetSystemMetrics(SM_CXSIZEFRAME) * 2;
+ height += GetSystemMetrics(SM_CYSIZEFRAME) * 2 + GetSystemMetrics(SM_CYCAPTION);
+
+ rect.left = left;
+ rect.right = left + width;
+ rect.top = top;
+ rect.bottom = top + height;
+
+ monitor.cbSize = sizeof(monitor);
+ monitor.dwFlags = 0;
+
+ // take taskbar into account
+ GetMonitorInfo(MonitorFromRect(&rect, MONITOR_DEFAULTTONEAREST), &monitor);
+
+ th = monitor.rcWork.bottom - monitor.rcWork.top;
+ tw = monitor.rcWork.right - monitor.rcWork.left;
+
+ if (tw < width)
+ {
+ width = tw;
+ left = monitor.rcWork.left;
+ }
+ else if (monitor.rcWork.right < left + (int)width)
+ left = monitor.rcWork.right - width;
+ else if (left < monitor.rcWork.left)
+ left = monitor.rcWork.left;
+ if (th < height)
+ {
+ height = th;
+ top = monitor.rcWork.top;
+ }
+ else if (monitor.rcWork.bottom < top + (int)height)
+ top = monitor.rcWork.bottom - height;
+ else if (top < monitor.rcWork.top)
+ top = monitor.rcWork.top;
+
+ int wintype = WS_OVERLAPPEDWINDOW;
if (m_parentWindowHwnd != 0)
{
wintype = WS_CHILD;
- /* check against parent window if given */
GetWindowRect((HWND)m_parentWindowHwnd, &rect);
- } else {
- int framex = GetSystemMetrics(SM_CXSIZEFRAME);
- int framey = GetSystemMetrics(SM_CYSIZEFRAME);
- int caption = GetSystemMetrics(SM_CYCAPTION);
-
- /* set up total window rect, taking in account window decorations. */
- rect.left = left - framex;
- rect.right = rect.left + width + framex*2;
- rect.top = top - (caption + framey);
- rect.bottom = rect.top + height + (caption + framey * 2);
+ left = 0;
+ top = 0;
+ width = rect.right - rect.left;
+ height = rect.bottom - rect.top;
}
-
- /* ask how large virtual screen is */
- desktop.left = GetSystemMetrics(SM_XVIRTUALSCREEN);
- desktop.top = GetSystemMetrics(SM_YVIRTUALSCREEN);
- desktop.right = GetSystemMetrics(SM_CXVIRTUALSCREEN);
- desktop.bottom = GetSystemMetrics(SM_CYVIRTUALSCREEN);
-
- /* virtual screen (desktop) bound checks */
- if(rect.left < desktop.left) rect.left = desktop.left;
- if(rect.top < desktop.top) rect.top = desktop.top;
- if(rect.bottom > desktop.bottom) rect.bottom = desktop.bottom;
- if(rect.right > desktop.right) rect.right = desktop.right;
-
- /* dimension vars to use in window creation */
- left = rect.left;
- top = rect.top;
- width = rect.right - rect.left;
- height = rect.bottom - rect.top;
-
+
wchar_t *title_16 = alloc_utf16_from_8((char *)(const char *)title, 0);
m_hWnd = ::CreateWindowW(
s_windowClassName, // pointer to registered class name
diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp
index 25c74a0a6cb..c32b2727c4c 100644
--- a/intern/ghost/intern/GHOST_WindowX11.cpp
+++ b/intern/ghost/intern/GHOST_WindowX11.cpp
@@ -65,6 +65,14 @@ typedef struct {
long input_mode;
} MotifWmHints;
+// Workaround for MESA bug #54080
+// https://bugs.freedesktop.org/show_bug.cgi?id=54080()
+#define SWAP_INTERVALS_WORKAROUND
+
+#ifdef SWAP_INTERVALS_WORKAROUND
+static bool g_swap_interval_disabled = false;
+#endif // SWAP_INTERVALS_WORKAROUND
+
#define MWM_HINTS_DECORATIONS (1L << 1)
@@ -1519,18 +1527,67 @@ endFullScreen() const
GHOST_TSuccess
GHOST_WindowX11::
setSwapInterval(int interval) {
- if (!GLX_EXT_swap_control)
+ if (!GLX_EXT_swap_control || !glXSwapIntervalEXT
+#ifdef SWAP_INTERVALS_WORKAROUND
+ || g_swap_interval_disabled
+#endif // SWAP_INTERVALS_WORKAROUND
+ )
+ {
return GHOST_kFailure;
+ }
glXSwapIntervalEXT(m_display, m_window, interval);
return GHOST_kSuccess;
}
+#ifdef SWAP_INTERVALS_WORKAROUND
+static int QueryDrawable_ApplicationErrorHandler(Display *display, XErrorEvent *theEvent)
+{
+ fprintf(stderr, "Ignoring Xlib error: error code %d request code %d\n",
+ theEvent->error_code, theEvent->request_code);
+ if (!g_swap_interval_disabled) {
+ fprintf(stderr, "Disabling SWAP INTERVALS extension\n");
+ g_swap_interval_disabled = true;
+ }
+ return 0;
+}
+
+static int QueryDrawable_ApplicationIOErrorHandler(Display *display)
+{
+ fprintf(stderr, "Ignoring Xlib error: error IO\n");
+ if (!g_swap_interval_disabled) {
+ fprintf(stderr, "Disabling SWAP INTERVALS extension\n");
+ g_swap_interval_disabled = true;
+ }
+ return 0;
+}
+#endif // SWAP_INTERVALS_WORKAROUND
+
int
GHOST_WindowX11::
getSwapInterval() {
if (GLX_EXT_swap_control) {
- unsigned int value;
+#ifdef SWAP_INTERVALS_WORKAROUND
+ /* XXX: Current MESA driver will give GLXBadDrawable for all
+ * the glXQueryDrawable requests with direct contexts.
+ *
+ * To prevent crashes and unexpected behaviors, we will
+ * disable swap intervals extension if query fails here.
+ * (because if we will override interval without having
+ * old value we couldn't restore it properly).
+ */
+ XErrorHandler old_handler = XSetErrorHandler(QueryDrawable_ApplicationErrorHandler);
+ XIOErrorHandler old_handler_io = XSetIOErrorHandler(QueryDrawable_ApplicationIOErrorHandler);
+#endif // SWAP_INTERVALS_WORKAROUND
+
+ unsigned int value = 0;
glXQueryDrawable(m_display, m_window, GLX_SWAP_INTERVAL_EXT, &value);
+
+#ifdef SWAP_INTERVALS_WORKAROUND
+ /* Restore handler */
+ (void) XSetErrorHandler(old_handler);
+ (void) XSetIOErrorHandler(old_handler_io);
+#endif // SWAP_INTERVALS_WORKAROUND
+
return (int)value;
}
return 0;
diff --git a/intern/guardedalloc/CMakeLists.txt b/intern/guardedalloc/CMakeLists.txt
index 1e140c5b674..b7a59da7813 100644
--- a/intern/guardedalloc/CMakeLists.txt
+++ b/intern/guardedalloc/CMakeLists.txt
@@ -34,11 +34,11 @@ set(INC_SYS
set(SRC
./intern/mallocn.c
+ ./intern/mallocn_guarded_impl.c
+ ./intern/mallocn_lockfree_impl.c
MEM_guardedalloc.h
-
- # include here since its a header-only
- ../atomic/atomic_ops.h
+ ./intern/mallocn_intern.h
)
if(WIN32 AND NOT UNIX)
@@ -49,12 +49,6 @@ if(WIN32 AND NOT UNIX)
)
endif()
-if (WITH_GUARDEDALLOC)
- add_definitions(-DWITH_GUARDEDALLOC)
-else()
- message(WARNING "Disabling GuardedAlloc is experemental, use at own risk!")
-endif()
-
blender_add_lib(bf_intern_guardedalloc "${SRC}" "${INC}" "${INC_SYS}")
# Override C++ alloc, optional.
diff --git a/intern/guardedalloc/MEM_guardedalloc.h b/intern/guardedalloc/MEM_guardedalloc.h
index d5ba2f5bd68..4fb68965338 100644
--- a/intern/guardedalloc/MEM_guardedalloc.h
+++ b/intern/guardedalloc/MEM_guardedalloc.h
@@ -62,11 +62,9 @@
#include <stdio.h> /* needed for FILE* */
-/* needed for uintptr_t, exception, dont use BLI anywhere else in MEM_* */
+/* needed for uintptr_t and attributes, exception, dont use BLI anywhere else in MEM_* */
#include "../../source/blender/blenlib/BLI_sys_types.h"
-
-/* some GNU attributes are only available from GCC 4.3 */
-#define MEM_GNU_ATTRIBUTES (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 403))
+#include "../../source/blender/blenlib/BLI_compiler_attrs.h"
#ifdef __cplusplus
extern "C" {
@@ -75,57 +73,36 @@ extern "C" {
/** Returns the length of the allocated memory segment pointed at
* by vmemh. If the pointer was not previously allocated by this
* module, the result is undefined.*/
- size_t MEM_allocN_len(const void *vmemh)
-#if MEM_GNU_ATTRIBUTES
- __attribute__((warn_unused_result))
-#endif
- ;
+ extern size_t (*MEM_allocN_len)(const void *vmemh) ATTR_WARN_UNUSED_RESULT;
/**
* Release memory previously allocatred by this module.
*/
- void MEM_freeN(void *vmemh);
+ extern void (*MEM_freeN)(void *vmemh);
#if 0 /* UNUSED */
/**
* Return zero if memory is not in allocated list
*/
- short MEM_testN(void *vmemh);
+ extern short (*MEM_testN)(void *vmemh);
#endif
/**
* Duplicates a block of memory, and returns a pointer to the
* newly allocated block. */
- void *MEM_dupallocN(const void *vmemh)
-#if MEM_GNU_ATTRIBUTES
- __attribute__((malloc))
- __attribute__((warn_unused_result))
-#endif
- ;
+ extern void *(*MEM_dupallocN)(const void *vmemh) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT;
/**
* Reallocates a block of memory, and returns pointer to the newly
* allocated block, the old one is freed. this is not as optimized
* as a system realloc but just makes a new allocation and copies
* over from existing memory. */
- void *MEM_reallocN_id(void *vmemh, size_t len, const char *str)
-#if MEM_GNU_ATTRIBUTES
- __attribute__((malloc))
- __attribute__((warn_unused_result))
- __attribute__((alloc_size(2)))
-#endif
- ;
+ extern void *(*MEM_reallocN_id)(void *vmemh, size_t len, const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(2);
/**
* A variant of realloc which zeros new bytes
*/
- void *MEM_recallocN_id(void *vmemh, size_t len, const char *str)
-#if MEM_GNU_ATTRIBUTES
- __attribute__((malloc))
- __attribute__((warn_unused_result))
- __attribute__((alloc_size(2)))
-#endif
- ;
+ extern void *(*MEM_recallocN_id)(void *vmemh, size_t len, const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(2);
#define MEM_reallocN(vmemh, len) MEM_reallocN_id(vmemh, len, __func__)
#define MEM_recallocN(vmemh, len) MEM_recallocN_id(vmemh, len, __func__)
@@ -134,97 +111,79 @@ extern "C" {
* Allocate a block of memory of size len, with tag name str. The
* memory is cleared. The name must be static, because only a
* pointer to it is stored ! */
- void *MEM_callocN(size_t len, const char *str)
-#if MEM_GNU_ATTRIBUTES
- __attribute__((malloc))
- __attribute__((warn_unused_result))
- __attribute__((nonnull(2)))
- __attribute__((alloc_size(1)))
-#endif
- ;
+ extern void *(*MEM_callocN)(size_t len, const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
/**
* Allocate a block of memory of size len, with tag name str. The
* name must be a static, because only a pointer to it is stored !
* */
- void *MEM_mallocN(size_t len, const char *str)
-#if MEM_GNU_ATTRIBUTES
- __attribute__((malloc))
- __attribute__((warn_unused_result))
- __attribute__((nonnull(2)))
- __attribute__((alloc_size(1)))
-#endif
- ;
+ extern void *(*MEM_mallocN)(size_t len, const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
/**
* Same as callocN, clears memory and uses mmap (disk cached) if supported.
* Can be free'd with MEM_freeN as usual.
* */
- void *MEM_mapallocN(size_t len, const char *str)
-#if MEM_GNU_ATTRIBUTES
- __attribute__((malloc))
- __attribute__((warn_unused_result))
- __attribute__((nonnull(2)))
- __attribute__((alloc_size(1)))
-#endif
- ;
+ extern void *(*MEM_mapallocN)(size_t len, const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
/** Print a list of the names and sizes of all allocated memory
* blocks. as a python dict for easy investigation */
- void MEM_printmemlist_pydict(void);
+ extern void (*MEM_printmemlist_pydict)(void);
/** Print a list of the names and sizes of all allocated memory
* blocks. */
- void MEM_printmemlist(void);
+ extern void (*MEM_printmemlist)(void);
/** calls the function on all allocated memory blocks. */
- void MEM_callbackmemlist(void (*func)(void *));
+ extern void (*MEM_callbackmemlist)(void (*func)(void *));
/** Print statistics about memory usage */
- void MEM_printmemlist_stats(void);
+ extern void (*MEM_printmemlist_stats)(void);
/** Set the callback function for error output. */
- void MEM_set_error_callback(void (*func)(const char *));
+ extern void (*MEM_set_error_callback)(void (*func)(const char *));
/**
* Are the start/end block markers still correct ?
*
* @retval 0 for correct memory, 1 for corrupted memory. */
- bool MEM_check_memory_integrity(void);
+ extern bool (*MEM_check_memory_integrity)(void);
/** Set thread locking functions for safe memory allocation from multiple
* threads, pass NULL pointers to disable thread locking again. */
- void MEM_set_lock_callback(void (*lock)(void), void (*unlock)(void));
+ extern void (*MEM_set_lock_callback)(void (*lock)(void), void (*unlock)(void));
/** Attempt to enforce OSX (or other OS's) to have malloc and stack nonzero */
- void MEM_set_memory_debug(void);
+ extern void (*MEM_set_memory_debug)(void);
/**
* Memory usage stats
* - MEM_get_memory_in_use is all memory
* - MEM_get_mapped_memory_in_use is a subset of all memory */
- uintptr_t MEM_get_memory_in_use(void);
+ extern uintptr_t (*MEM_get_memory_in_use)(void);
/** Get mapped memory usage. */
- uintptr_t MEM_get_mapped_memory_in_use(void);
+ extern uintptr_t (*MEM_get_mapped_memory_in_use)(void);
/** Get amount of memory blocks in use. */
- unsigned int MEM_get_memory_blocks_in_use(void);
+ extern unsigned int (*MEM_get_memory_blocks_in_use)(void);
/** Reset the peak memory statistic to zero. */
- void MEM_reset_peak_memory(void);
+ extern void (*MEM_reset_peak_memory)(void);
/** Get the peak memory usage in bytes, including mmap allocations. */
- size_t MEM_get_peak_memory(void)
-#if MEM_GNU_ATTRIBUTES
- __attribute__((warn_unused_result))
-#endif
- ;
+ extern size_t (*MEM_get_peak_memory)(void) ATTR_WARN_UNUSED_RESULT;
#define MEM_SAFE_FREE(v) if (v) { MEM_freeN(v); v = NULL; } (void)0
+/* overhead for lockfree allocator (use to avoid slop-space) */
+#define MEM_SIZE_OVERHEAD sizeof(size_t)
+#define MEM_SIZE_OPTIMAL(size) ((size) - MEM_SIZE_OVERHEAD)
+
#ifndef NDEBUG
-const char *MEM_name_ptr(void *vmemh);
+extern const char *(*MEM_name_ptr)(void *vmemh);
#endif
+/* Switch allocator to slower but fully guarded mode. */
+void MEM_use_guarded_allocator(void);
+
#ifdef __cplusplus
/* alloc funcs for C++ only */
#define MEM_CXX_CLASS_ALLOC_FUNCS(_id) \
@@ -244,6 +203,18 @@ public: \
MEM_freeN(mem); \
} \
+#if defined __GNUC__ || defined __sun
+# define OBJECT_GUARDED_NEW(type, args ...) \
+ new(MEM_mallocN(sizeof(type), __func__)) type(args)
+#else
+# define OBJECT_GUARDED_NEW(type, ...) \
+ new(MEM_mallocN(sizeof(type), __FUNCTION__)) type(__VA_ARGS__)
+#endif
+#define OBJECT_GUARDED_DELETE(what, type) \
+ { if(what) { \
+ ((type*)(what))->~type(); \
+ MEM_freeN(what); \
+ } } (void)0
#endif /* __cplusplus */
#ifdef __cplusplus
diff --git a/intern/guardedalloc/SConscript b/intern/guardedalloc/SConscript
index e3f787fe6c2..3bae808cc94 100644
--- a/intern/guardedalloc/SConscript
+++ b/intern/guardedalloc/SConscript
@@ -29,10 +29,12 @@ Import('env')
defs = []
-sources = ['intern/mallocn.c', 'intern/mmap_win.c']
-
-# could make this optional
-defs.append('WITH_GUARDEDALLOC')
+sources = [
+ 'intern/mallocn.c',
+ 'intern/mallocn_guarded_impl.c',
+ 'intern/mallocn_lockfree_impl.c',
+ 'intern/mmap_win.c'
+]
if env['WITH_BF_CXX_GUARDEDALLOC']:
sources.append('cpp/mallocn.cpp')
diff --git a/intern/guardedalloc/intern/mallocn.c b/intern/guardedalloc/intern/mallocn.c
index e8102d98345..2ac01a6c7e4 100644
--- a/intern/guardedalloc/intern/mallocn.c
+++ b/intern/guardedalloc/intern/mallocn.c
@@ -32,1262 +32,64 @@
* Guarded memory allocation, and boundary-write detection.
*/
-#include <stdlib.h>
-#include <string.h> /* memcpy */
-#include <stdarg.h>
-#include <sys/types.h>
-
-/* mmap exception */
-#if defined(WIN32)
-# include "mmap_win.h"
-#else
-# include <sys/mman.h>
-#endif
-
-#if defined(_MSC_VER)
-# define __func__ __FUNCTION__
-#endif
-
-/* only for utility functions */
-#if defined(__GNUC__) && defined(__linux__)
-#include <malloc.h>
-# define HAVE_MALLOC_H
-#endif
-
#include "MEM_guardedalloc.h"
/* to ensure strict conversions */
#include "../../source/blender/blenlib/BLI_strict_flags.h"
-
-/* should always be defined except for experimental cases */
-#ifdef WITH_GUARDEDALLOC
-
-#include "atomic_ops.h"
-
-/* Only for debugging:
- * store original buffer's name when doing MEM_dupallocN
- * helpful to profile issues with non-freed "dup_alloc" buffers,
- * but this introduces some overhead to memory header and makes
- * things slower a bit, so better to keep disabled by default
- */
-//#define DEBUG_MEMDUPLINAME
-
-/* Only for debugging:
- * lets you count the allocations so as to find the allocator of unfreed memory
- * in situations where the leak is predictable */
-
-//#define DEBUG_MEMCOUNTER
-
-/* Only for debugging:
- * defining DEBUG_THREADS will enable check whether memory manager
- * is locked with a mutex when allocation is called from non-main
- * thread.
- *
- * This helps troubleshooting memory issues caused by the fact
- * guarded allocator is not thread-safe, however this check will
- * fail to check allocations from openmp threads.
- */
-//#define DEBUG_THREADS
-
-/* Only for debugging:
- * Defining DEBUG_BACKTRACE will store a backtrace from where
- * memory block was allocated and print this trace for all
- * unfreed blocks.
- */
-//#define DEBUG_BACKTRACE
-
-#ifdef DEBUG_BACKTRACE
-# define BACKTRACE_SIZE 100
-#endif
-
-#ifdef DEBUG_MEMCOUNTER
- /* set this to the value that isn't being freed */
-# define DEBUG_MEMCOUNTER_ERROR_VAL 0
-static int _mallocn_count = 0;
-
-/* breakpoint here */
-static void memcount_raise(const char *name)
-{
- fprintf(stderr, "%s: memcount-leak, %d\n", name, _mallocn_count);
-}
-#endif
-
-/* Blame Microsoft for LLP64 and no inttypes.h, quick workaround needed: */
-#if defined(WIN64)
-# define SIZET_FORMAT "%I64u"
-# define SIZET_ARG(a) ((unsigned long long)(a))
-#else
-# define SIZET_FORMAT "%lu"
-# define SIZET_ARG(a) ((unsigned long)(a))
-#endif
-
-#define SIZET_ALIGN_4(len) ((len + 3) & ~(size_t)3)
-
-
-/* --------------------------------------------------------------------- */
-/* Data definition */
-/* --------------------------------------------------------------------- */
-/* all memory chunks are put in linked lists */
-typedef struct localLink {
- struct localLink *next, *prev;
-} localLink;
-
-typedef struct localListBase {
- void *first, *last;
-} localListBase;
-
-/* note: keep this struct aligned (e.g., irix/gcc) - Hos */
-typedef struct MemHead {
- int tag1;
- size_t len;
- struct MemHead *next, *prev;
- const char *name;
- const char *nextname;
- int tag2;
- int mmap; /* if true, memory was mmapped */
-#ifdef DEBUG_MEMCOUNTER
- int _count;
-#endif
-
-#ifdef DEBUG_MEMDUPLINAME
- int need_free_name, pad;
-#endif
-
-#ifdef DEBUG_BACKTRACE
- void *backtrace[BACKTRACE_SIZE];
- int backtrace_size;
-#endif
-} MemHead;
-
-/* for openmp threading asserts, saves time troubleshooting
- * we may need to extend this if blender code starts using MEM_
- * functions inside OpenMP correctly with omp_set_lock() */
-
-#if 0 /* disable for now, only use to debug openmp code which doesn lock threads for malloc */
-#if defined(_OPENMP) && defined(DEBUG)
-# include <assert.h>
-# include <omp.h>
-# define DEBUG_OMP_MALLOC
-#endif
-#endif
-
-#ifdef DEBUG_THREADS
-# include <assert.h>
-# include <pthread.h>
-static pthread_t mainid;
-#endif
-
-#ifdef DEBUG_BACKTRACE
-# if defined(__linux__) || defined(__APPLE__)
-# include <execinfo.h>
-// Windows is not supported yet.
-//# elif defined(_MSV_VER)
-//# include <DbgHelp.h>
-# endif
-#endif
-
-typedef struct MemTail {
- int tag3, pad;
-} MemTail;
-
-
-/* --------------------------------------------------------------------- */
-/* local functions */
-/* --------------------------------------------------------------------- */
-
-static void addtail(volatile localListBase *listbase, void *vlink);
-static void remlink(volatile localListBase *listbase, void *vlink);
-static void rem_memblock(MemHead *memh);
-static void MemorY_ErroR(const char *block, const char *error);
-static const char *check_memlist(MemHead *memh);
-
-/* --------------------------------------------------------------------- */
-/* locally used defines */
-/* --------------------------------------------------------------------- */
-
-#ifdef __BIG_ENDIAN__
-# define MAKE_ID(a, b, c, d) ((int)(a) << 24 | (int)(b) << 16 | (c) << 8 | (d))
-#else
-# define MAKE_ID(a, b, c, d) ((int)(d) << 24 | (int)(c) << 16 | (b) << 8 | (a))
-#endif
-
-#define MEMTAG1 MAKE_ID('M', 'E', 'M', 'O')
-#define MEMTAG2 MAKE_ID('R', 'Y', 'B', 'L')
-#define MEMTAG3 MAKE_ID('O', 'C', 'K', '!')
-#define MEMFREE MAKE_ID('F', 'R', 'E', 'E')
-
-#define MEMNEXT(x) \
- ((MemHead *)(((char *) x) - ((char *) &(((MemHead *)0)->next))))
-
-/* --------------------------------------------------------------------- */
-/* vars */
-/* --------------------------------------------------------------------- */
-
-
-static unsigned int totblock = 0;
-static size_t mem_in_use = 0, mmap_in_use = 0, peak_mem = 0;
-
-static volatile struct localListBase _membase;
-static volatile struct localListBase *membase = &_membase;
-static void (*error_callback)(const char *) = NULL;
-static void (*thread_lock_callback)(void) = NULL;
-static void (*thread_unlock_callback)(void) = NULL;
-
-static bool malloc_debug_memset = false;
-
-#ifdef malloc
-#undef malloc
-#endif
-
-#ifdef calloc
-#undef calloc
-#endif
-
-#ifdef free
-#undef free
-#endif
-
-
-/* --------------------------------------------------------------------- */
-/* implementation */
-/* --------------------------------------------------------------------- */
-
-#ifdef __GNUC__
-__attribute__ ((format(printf, 1, 2)))
-#endif
-static void print_error(const char *str, ...)
-{
- char buf[512];
- va_list ap;
-
- va_start(ap, str);
- vsnprintf(buf, sizeof(buf), str, ap);
- va_end(ap);
- buf[sizeof(buf) - 1] = '\0';
-
- if (error_callback) error_callback(buf);
-}
-
-static void mem_lock_thread(void)
-{
-#ifdef DEBUG_THREADS
- static int initialized = 0;
-
- if (initialized == 0) {
- /* assume first allocation happens from main thread */
- mainid = pthread_self();
- initialized = 1;
- }
-
- if (!pthread_equal(pthread_self(), mainid) && thread_lock_callback == NULL) {
- assert(!"Memory function is called from non-main thread without lock");
- }
-#endif
-
-#ifdef DEBUG_OMP_MALLOC
- assert(omp_in_parallel() == 0);
-#endif
-
- if (thread_lock_callback)
- thread_lock_callback();
-}
-
-static void mem_unlock_thread(void)
-{
-#ifdef DEBUG_THREADS
- if (!pthread_equal(pthread_self(), mainid) && thread_lock_callback == NULL) {
- assert(!"Thread lock was removed while allocation from thread is in progress");
- }
-#endif
-
- if (thread_unlock_callback)
- thread_unlock_callback();
-}
-
-bool MEM_check_memory_integrity(void)
-{
- const char *err_val = NULL;
- MemHead *listend;
- /* check_memlist starts from the front, and runs until it finds
- * the requested chunk. For this test, that's the last one. */
- listend = membase->last;
-
- err_val = check_memlist(listend);
-
- return (err_val != NULL);
-}
-
-
-void MEM_set_error_callback(void (*func)(const char *))
-{
- error_callback = func;
-}
-
-void MEM_set_lock_callback(void (*lock)(void), void (*unlock)(void))
-{
- thread_lock_callback = lock;
- thread_unlock_callback = unlock;
-}
-
-void MEM_set_memory_debug(void)
-{
- malloc_debug_memset = true;
-}
-
-size_t MEM_allocN_len(const void *vmemh)
-{
- if (vmemh) {
- const MemHead *memh = vmemh;
-
- memh--;
- return memh->len;
- }
- else {
- return 0;
- }
-}
-
-void *MEM_dupallocN(const void *vmemh)
-{
- void *newp = NULL;
-
- if (vmemh) {
- const MemHead *memh = vmemh;
- memh--;
-
-#ifndef DEBUG_MEMDUPLINAME
- if (memh->mmap)
- newp = MEM_mapallocN(memh->len, "dupli_mapalloc");
- else
- newp = MEM_mallocN(memh->len, "dupli_alloc");
-
- if (newp == NULL) return NULL;
-#else
- {
- MemHead *nmemh;
- char *name = malloc(strlen(memh->name) + 24);
-
- if (memh->mmap) {
- sprintf(name, "%s %s", "dupli_mapalloc", memh->name);
- newp = MEM_mapallocN(memh->len, name);
- }
- else {
- sprintf(name, "%s %s", "dupli_alloc", memh->name);
- newp = MEM_mallocN(memh->len, name);
- }
-
- if (newp == NULL) return NULL;
-
- nmemh = newp;
- nmemh--;
-
- nmemh->need_free_name = 1;
- }
-#endif
-
- memcpy(newp, vmemh, memh->len);
- }
-
- return newp;
-}
-
-void *MEM_reallocN_id(void *vmemh, size_t len, const char *str)
-{
- void *newp = NULL;
-
- if (vmemh) {
- MemHead *memh = vmemh;
- memh--;
-
- newp = MEM_mallocN(len, memh->name);
- if (newp) {
- if (len < memh->len) {
- /* shrink */
- memcpy(newp, vmemh, len);
- }
- else {
- /* grow (or remain same size) */
- memcpy(newp, vmemh, memh->len);
- }
- }
-
- MEM_freeN(vmemh);
- }
- else {
- newp = MEM_mallocN(len, str);
- }
-
- return newp;
-}
-
-void *MEM_recallocN_id(void *vmemh, size_t len, const char *str)
-{
- void *newp = NULL;
-
- if (vmemh) {
- MemHead *memh = vmemh;
- memh--;
-
- newp = MEM_mallocN(len, memh->name);
- if (newp) {
- if (len < memh->len) {
- /* shrink */
- memcpy(newp, vmemh, len);
- }
- else {
- memcpy(newp, vmemh, memh->len);
-
- if (len > memh->len) {
- /* grow */
- /* zero new bytes */
- memset(((char *)newp) + memh->len, 0, len - memh->len);
- }
- }
- }
-
- MEM_freeN(vmemh);
- }
- else {
- newp = MEM_callocN(len, str);
- }
-
- return newp;
-}
-
-#ifdef DEBUG_BACKTRACE
-# if defined(__linux__) || defined(__APPLE__)
-static void make_memhead_backtrace(MemHead *memh)
-{
- memh->backtrace_size = backtrace(memh->backtrace, BACKTRACE_SIZE);
-}
-
-static void print_memhead_backtrace(MemHead *memh)
-{
- char **strings;
- int i;
-
- strings = backtrace_symbols(memh->backtrace, memh->backtrace_size);
- for (i = 0; i < memh->backtrace_size; i++) {
- print_error(" %s\n", strings[i]);
- }
-
- free(strings);
-}
-# else
-static void make_memhead_backtrace(MemHead *memh)
-{
- (void) memh; /* Ignored. */
-}
-
-static void print_memhead_backtrace(MemHead *memh)
-{
- (void) memh; /* Ignored. */
-}
-# endif /* defined(__linux__) || defined(__APPLE__) */
-#endif /* DEBUG_BACKTRACE */
-
-static void make_memhead_header(MemHead *memh, size_t len, const char *str)
-{
- MemTail *memt;
-
- memh->tag1 = MEMTAG1;
- memh->name = str;
- memh->nextname = NULL;
- memh->len = len;
- memh->mmap = 0;
- memh->tag2 = MEMTAG2;
-
-#ifdef DEBUG_MEMDUPLINAME
- memh->need_free_name = 0;
-#endif
-
-#ifdef DEBUG_BACKTRACE
- make_memhead_backtrace(memh);
-#endif
-
- memt = (MemTail *)(((char *) memh) + sizeof(MemHead) + len);
- memt->tag3 = MEMTAG3;
-
- atomic_add_u(&totblock, 1);
- atomic_add_z(&mem_in_use, len);
-
- mem_lock_thread();
- addtail(membase, &memh->next);
- if (memh->next) {
- memh->nextname = MEMNEXT(memh->next)->name;
- }
- peak_mem = mem_in_use > peak_mem ? mem_in_use : peak_mem;
- mem_unlock_thread();
-}
-
-void *MEM_mallocN(size_t len, const char *str)
-{
- MemHead *memh;
-
- len = SIZET_ALIGN_4(len);
-
- memh = (MemHead *)malloc(len + sizeof(MemHead) + sizeof(MemTail));
-
- if (memh) {
- make_memhead_header(memh, len, str);
- if (malloc_debug_memset && len)
- memset(memh + 1, 255, len);
-
-#ifdef DEBUG_MEMCOUNTER
- if (_mallocn_count == DEBUG_MEMCOUNTER_ERROR_VAL)
- memcount_raise(__func__);
- memh->_count = _mallocn_count++;
-#endif
- return (++memh);
- }
- print_error("Malloc returns null: len=" SIZET_FORMAT " in %s, total %u\n",
- SIZET_ARG(len), str, (unsigned int) mem_in_use);
- return NULL;
-}
-
-void *MEM_callocN(size_t len, const char *str)
-{
- MemHead *memh;
-
- len = SIZET_ALIGN_4(len);
-
- memh = (MemHead *)calloc(len + sizeof(MemHead) + sizeof(MemTail), 1);
-
- if (memh) {
- make_memhead_header(memh, len, str);
-#ifdef DEBUG_MEMCOUNTER
- if (_mallocn_count == DEBUG_MEMCOUNTER_ERROR_VAL)
- memcount_raise(__func__);
- memh->_count = _mallocn_count++;
-#endif
- return (++memh);
- }
- print_error("Calloc returns null: len=" SIZET_FORMAT " in %s, total %u\n",
- SIZET_ARG(len), str, (unsigned int) mem_in_use);
- return NULL;
-}
-
-/* note; mmap returns zero'd memory */
-void *MEM_mapallocN(size_t len, const char *str)
-{
- MemHead *memh;
-
- len = SIZET_ALIGN_4(len);
-
-#if defined(WIN32)
- /* our windows mmap implementation is not thread safe */
- mem_lock_thread();
-#endif
- memh = mmap(NULL, len + sizeof(MemHead) + sizeof(MemTail),
- PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
-#if defined(WIN32)
- mem_unlock_thread();
-#endif
-
- if (memh != (MemHead *)-1) {
- make_memhead_header(memh, len, str);
- memh->mmap = 1;
- atomic_add_z(&mmap_in_use, len);
- mem_lock_thread();
- peak_mem = mmap_in_use > peak_mem ? mmap_in_use : peak_mem;
- mem_unlock_thread();
-#ifdef DEBUG_MEMCOUNTER
- if (_mallocn_count == DEBUG_MEMCOUNTER_ERROR_VAL)
- memcount_raise(__func__);
- memh->_count = _mallocn_count++;
-#endif
- return (++memh);
- }
- else {
- print_error("Mapalloc returns null, fallback to regular malloc: "
- "len=" SIZET_FORMAT " in %s, total %u\n",
- SIZET_ARG(len), str, (unsigned int) mmap_in_use);
- return MEM_callocN(len, str);
- }
-}
-
-/* Memory statistics print */
-typedef struct MemPrintBlock {
- const char *name;
- uintptr_t len;
- int items;
-} MemPrintBlock;
-
-static int compare_name(const void *p1, const void *p2)
-{
- const MemPrintBlock *pb1 = (const MemPrintBlock *)p1;
- const MemPrintBlock *pb2 = (const MemPrintBlock *)p2;
-
- return strcmp(pb1->name, pb2->name);
-}
-
-static int compare_len(const void *p1, const void *p2)
-{
- const MemPrintBlock *pb1 = (const MemPrintBlock *)p1;
- const MemPrintBlock *pb2 = (const MemPrintBlock *)p2;
-
- if (pb1->len < pb2->len)
- return 1;
- else if (pb1->len == pb2->len)
- return 0;
- else
- return -1;
-}
-
-void MEM_printmemlist_stats(void)
-{
- MemHead *membl;
- MemPrintBlock *pb, *printblock;
- unsigned int totpb, a, b;
-#ifdef HAVE_MALLOC_H
- size_t mem_in_use_slop = 0;
-#endif
- mem_lock_thread();
-
- /* put memory blocks into array */
- printblock = malloc(sizeof(MemPrintBlock) * totblock);
-
- pb = printblock;
- totpb = 0;
-
- membl = membase->first;
- if (membl) membl = MEMNEXT(membl);
-
- while (membl) {
- pb->name = membl->name;
- pb->len = membl->len;
- pb->items = 1;
-
- totpb++;
- pb++;
-
-#ifdef HAVE_MALLOC_H
- if (!membl->mmap) {
- mem_in_use_slop += (sizeof(MemHead) + sizeof(MemTail) +
- malloc_usable_size((void *)membl)) - membl->len;
- }
-#endif
-
- if (membl->next)
- membl = MEMNEXT(membl->next);
- else break;
- }
-
- /* sort by name and add together blocks with the same name */
- qsort(printblock, totpb, sizeof(MemPrintBlock), compare_name);
- for (a = 0, b = 0; a < totpb; a++) {
- if (a == b) {
- continue;
- }
- else if (strcmp(printblock[a].name, printblock[b].name) == 0) {
- printblock[b].len += printblock[a].len;
- printblock[b].items++;
- }
- else {
- b++;
- memcpy(&printblock[b], &printblock[a], sizeof(MemPrintBlock));
- }
- }
- totpb = b + 1;
-
- /* sort by length and print */
- qsort(printblock, totpb, sizeof(MemPrintBlock), compare_len);
- printf("\ntotal memory len: %.3f MB\n",
- (double)mem_in_use / (double)(1024 * 1024));
- printf("peak memory len: %.3f MB\n",
- (double)peak_mem / (double)(1024 * 1024));
-#ifdef HAVE_MALLOC_H
- printf("slop memory len: %.3f MB\n",
- (double)mem_in_use_slop / (double)(1024 * 1024));
-#endif
- printf(" ITEMS TOTAL-MiB AVERAGE-KiB TYPE\n");
- for (a = 0, pb = printblock; a < totpb; a++, pb++) {
- printf("%6d (%8.3f %8.3f) %s\n",
- pb->items, (double)pb->len / (double)(1024 * 1024),
- (double)pb->len / 1024.0 / (double)pb->items, pb->name);
- }
- free(printblock);
-
- mem_unlock_thread();
-
-#ifdef HAVE_MALLOC_H /* GLIBC only */
- printf("System Statistics:\n");
- malloc_stats();
-#endif
-}
-
-static const char mem_printmemlist_pydict_script[] =
-"mb_userinfo = {}\n"
-"totmem = 0\n"
-"for mb_item in membase:\n"
-" mb_item_user_size = mb_userinfo.setdefault(mb_item['name'], [0,0])\n"
-" mb_item_user_size[0] += 1 # Add a user\n"
-" mb_item_user_size[1] += mb_item['len'] # Increment the size\n"
-" totmem += mb_item['len']\n"
-"print('(membase) items:', len(membase), '| unique-names:',\n"
-" len(mb_userinfo), '| total-mem:', totmem)\n"
-"mb_userinfo_sort = list(mb_userinfo.items())\n"
-"for sort_name, sort_func in (('size', lambda a: -a[1][1]),\n"
-" ('users', lambda a: -a[1][0]),\n"
-" ('name', lambda a: a[0])):\n"
-" print('\\nSorting by:', sort_name)\n"
-" mb_userinfo_sort.sort(key = sort_func)\n"
-" for item in mb_userinfo_sort:\n"
-" print('name:%%s, users:%%i, len:%%i' %%\n"
-" (item[0], item[1][0], item[1][1]))\n";
-
-/* Prints in python syntax for easy */
-static void MEM_printmemlist_internal(int pydict)
-{
- MemHead *membl;
-
- mem_lock_thread();
-
- membl = membase->first;
- if (membl) membl = MEMNEXT(membl);
-
- if (pydict) {
- print_error("# membase_debug.py\n");
- print_error("membase = [\n");
- }
- while (membl) {
- if (pydict) {
- fprintf(stderr,
- " {'len':" SIZET_FORMAT ", "
- "'name':'''%s''', "
- "'pointer':'%p'},\n",
- SIZET_ARG(membl->len), membl->name, (void *)(membl + 1));
- }
- else {
-#ifdef DEBUG_MEMCOUNTER
- print_error("%s len: " SIZET_FORMAT " %p, count: %d\n",
- membl->name, SIZET_ARG(membl->len), membl + 1,
- membl->_count);
-#else
- print_error("%s len: " SIZET_FORMAT " %p\n",
- membl->name, SIZET_ARG(membl->len), membl + 1);
-#endif
-#ifdef DEBUG_BACKTRACE
- print_memhead_backtrace(membl);
-#endif
- }
- if (membl->next)
- membl = MEMNEXT(membl->next);
- else break;
- }
- if (pydict) {
- fprintf(stderr, "]\n\n");
- fprintf(stderr, mem_printmemlist_pydict_script);
- }
-
- mem_unlock_thread();
-}
-
-void MEM_callbackmemlist(void (*func)(void *))
-{
- MemHead *membl;
-
- mem_lock_thread();
-
- membl = membase->first;
- if (membl) membl = MEMNEXT(membl);
-
- while (membl) {
- func(membl + 1);
- if (membl->next)
- membl = MEMNEXT(membl->next);
- else break;
- }
-
- mem_unlock_thread();
-}
-
-#if 0
-short MEM_testN(void *vmemh)
-{
- MemHead *membl;
-
- mem_lock_thread();
-
- membl = membase->first;
- if (membl) membl = MEMNEXT(membl);
-
- while (membl) {
- if (vmemh == membl + 1) {
- mem_unlock_thread();
- return 1;
- }
-
- if (membl->next)
- membl = MEMNEXT(membl->next);
- else break;
- }
-
- mem_unlock_thread();
-
- print_error("Memoryblock %p: pointer not in memlist\n", vmemh);
- return 0;
-}
-#endif
-
-void MEM_printmemlist(void)
-{
- MEM_printmemlist_internal(0);
-}
-void MEM_printmemlist_pydict(void)
-{
- MEM_printmemlist_internal(1);
-}
-
-void MEM_freeN(void *vmemh)
-{
- MemTail *memt;
- MemHead *memh = vmemh;
- const char *name;
-
- if (memh == NULL) {
- MemorY_ErroR("free", "attempt to free NULL pointer");
- /* print_error(err_stream, "%d\n", (memh+4000)->tag1); */
- return;
- }
-
- if (sizeof(intptr_t) == 8) {
- if (((intptr_t) memh) & 0x7) {
- MemorY_ErroR("free", "attempt to free illegal pointer");
- return;
- }
- }
- else {
- if (((intptr_t) memh) & 0x3) {
- MemorY_ErroR("free", "attempt to free illegal pointer");
- return;
- }
- }
-
- memh--;
- if (memh->tag1 == MEMFREE && memh->tag2 == MEMFREE) {
- MemorY_ErroR(memh->name, "double free");
- return;
- }
-
- if ((memh->tag1 == MEMTAG1) &&
- (memh->tag2 == MEMTAG2) &&
- ((memh->len & 0x3) == 0))
- {
- memt = (MemTail *)(((char *) memh) + sizeof(MemHead) + memh->len);
- if (memt->tag3 == MEMTAG3) {
-
- memh->tag1 = MEMFREE;
- memh->tag2 = MEMFREE;
- memt->tag3 = MEMFREE;
- /* after tags !!! */
- rem_memblock(memh);
-
- return;
- }
- MemorY_ErroR(memh->name, "end corrupt");
- name = check_memlist(memh);
- if (name != NULL) {
- if (name != memh->name) MemorY_ErroR(name, "is also corrupt");
- }
- }
- else {
- mem_lock_thread();
- name = check_memlist(memh);
- mem_unlock_thread();
- if (name == NULL)
- MemorY_ErroR("free", "pointer not in memlist");
- else
- MemorY_ErroR(name, "error in header");
- }
-
- totblock--;
- /* here a DUMP should happen */
-
- return;
-}
-
-/* --------------------------------------------------------------------- */
-/* local functions */
-/* --------------------------------------------------------------------- */
-
-static void addtail(volatile localListBase *listbase, void *vlink)
-{
- struct localLink *link = vlink;
-
- /* for a generic API error checks here is fine but
- * the limited use here they will never be NULL */
-#if 0
- if (link == NULL) return;
- if (listbase == NULL) return;
-#endif
-
- link->next = NULL;
- link->prev = listbase->last;
-
- if (listbase->last) ((struct localLink *)listbase->last)->next = link;
- if (listbase->first == NULL) listbase->first = link;
- listbase->last = link;
-}
-
-static void remlink(volatile localListBase *listbase, void *vlink)
-{
- struct localLink *link = vlink;
-
- /* for a generic API error checks here is fine but
- * the limited use here they will never be NULL */
-#if 0
- if (link == NULL) return;
- if (listbase == NULL) return;
-#endif
-
- if (link->next) link->next->prev = link->prev;
- if (link->prev) link->prev->next = link->next;
-
- if (listbase->last == link) listbase->last = link->prev;
- if (listbase->first == link) listbase->first = link->next;
-}
-
-static void rem_memblock(MemHead *memh)
-{
- mem_lock_thread();
- remlink(membase, &memh->next);
- if (memh->prev) {
- if (memh->next)
- MEMNEXT(memh->prev)->nextname = MEMNEXT(memh->next)->name;
- else
- MEMNEXT(memh->prev)->nextname = NULL;
- }
- mem_unlock_thread();
-
- atomic_sub_u(&totblock, 1);
- atomic_sub_z(&mem_in_use, memh->len);
-
-#ifdef DEBUG_MEMDUPLINAME
- if (memh->need_free_name)
- free((char *) memh->name);
-#endif
-
- if (memh->mmap) {
- atomic_sub_z(&mmap_in_use, memh->len);
-#if defined(WIN32)
- /* our windows mmap implementation is not thread safe */
- mem_lock_thread();
-#endif
- if (munmap(memh, memh->len + sizeof(MemHead) + sizeof(MemTail)))
- printf("Couldn't unmap memory %s\n", memh->name);
-#if defined(WIN32)
- mem_unlock_thread();
-#endif
- }
- else {
- if (malloc_debug_memset && memh->len)
- memset(memh + 1, 255, memh->len);
- free(memh);
- }
-}
-
-static void MemorY_ErroR(const char *block, const char *error)
-{
- print_error("Memoryblock %s: %s\n", block, error);
-
-#ifdef WITH_ASSERT_ABORT
- abort();
-#endif
-}
-
-static const char *check_memlist(MemHead *memh)
-{
- MemHead *forw, *back, *forwok, *backok;
- const char *name;
-
- forw = membase->first;
- if (forw) forw = MEMNEXT(forw);
- forwok = NULL;
- while (forw) {
- if (forw->tag1 != MEMTAG1 || forw->tag2 != MEMTAG2) break;
- forwok = forw;
- if (forw->next) forw = MEMNEXT(forw->next);
- else forw = NULL;
- }
-
- back = (MemHead *) membase->last;
- if (back) back = MEMNEXT(back);
- backok = NULL;
- while (back) {
- if (back->tag1 != MEMTAG1 || back->tag2 != MEMTAG2) break;
- backok = back;
- if (back->prev) back = MEMNEXT(back->prev);
- else back = NULL;
- }
-
- if (forw != back) return ("MORE THAN 1 MEMORYBLOCK CORRUPT");
-
- if (forw == NULL && back == NULL) {
- /* no wrong headers found then but in search of memblock */
-
- forw = membase->first;
- if (forw) forw = MEMNEXT(forw);
- forwok = NULL;
- while (forw) {
- if (forw == memh) break;
- if (forw->tag1 != MEMTAG1 || forw->tag2 != MEMTAG2) break;
- forwok = forw;
- if (forw->next) forw = MEMNEXT(forw->next);
- else forw = NULL;
- }
- if (forw == NULL) return NULL;
-
- back = (MemHead *) membase->last;
- if (back) back = MEMNEXT(back);
- backok = NULL;
- while (back) {
- if (back == memh) break;
- if (back->tag1 != MEMTAG1 || back->tag2 != MEMTAG2) break;
- backok = back;
- if (back->prev) back = MEMNEXT(back->prev);
- else back = NULL;
- }
- }
-
- if (forwok) name = forwok->nextname;
- else name = "No name found";
-
- if (forw == memh) {
- /* to be sure but this block is removed from the list */
- if (forwok) {
- if (backok) {
- forwok->next = (MemHead *)&backok->next;
- backok->prev = (MemHead *)&forwok->next;
- forwok->nextname = backok->name;
- }
- else {
- forwok->next = NULL;
- membase->last = (struct localLink *) &forwok->next;
- }
- }
- else {
- if (backok) {
- backok->prev = NULL;
- membase->first = &backok->next;
- }
- else {
- membase->first = membase->last = NULL;
- }
- }
- }
- else {
- MemorY_ErroR(name, "Additional error in header");
- return("Additional error in header");
- }
-
- return(name);
-}
-
-size_t MEM_get_peak_memory(void)
-{
- size_t _peak_mem;
-
- mem_lock_thread();
- _peak_mem = peak_mem;
- mem_unlock_thread();
-
- return _peak_mem;
-}
-
-void MEM_reset_peak_memory(void)
-{
- mem_lock_thread();
- peak_mem = 0;
- mem_unlock_thread();
-}
-
-uintptr_t MEM_get_memory_in_use(void)
-{
- uintptr_t _mem_in_use;
-
- mem_lock_thread();
- _mem_in_use = mem_in_use;
- mem_unlock_thread();
-
- return _mem_in_use;
-}
-
-uintptr_t MEM_get_mapped_memory_in_use(void)
-{
- uintptr_t _mmap_in_use;
-
- mem_lock_thread();
- _mmap_in_use = mmap_in_use;
- mem_unlock_thread();
-
- return _mmap_in_use;
-}
-
-unsigned int MEM_get_memory_blocks_in_use(void)
-{
- unsigned int _totblock;
-
- mem_lock_thread();
- _totblock = totblock;
- mem_unlock_thread();
-
- return _totblock;
-}
+#include "mallocn_intern.h"
+
+size_t (*MEM_allocN_len)(const void *vmemh) = MEM_lockfree_allocN_len;
+void (*MEM_freeN)(void *vmemh) = MEM_lockfree_freeN;
+void *(*MEM_dupallocN)(const void *vmemh) = MEM_lockfree_dupallocN;
+void *(*MEM_reallocN_id)(void *vmemh, size_t len, const char *str) = MEM_lockfree_reallocN_id;
+void *(*MEM_recallocN_id)(void *vmemh, size_t len, const char *str) = MEM_lockfree_recallocN_id;;
+void *(*MEM_callocN)(size_t len, const char *str) = MEM_lockfree_callocN;
+void *(*MEM_mallocN)(size_t len, const char *str) = MEM_lockfree_mallocN;
+void *(*MEM_mapallocN)(size_t len, const char *str) = MEM_lockfree_mapallocN;
+void (*MEM_printmemlist_pydict)(void) = MEM_lockfree_printmemlist_pydict;
+void (*MEM_printmemlist)(void) = MEM_lockfree_printmemlist;
+void (*MEM_callbackmemlist)(void (*func)(void *)) = MEM_lockfree_callbackmemlist;
+void (*MEM_printmemlist_stats)(void) = MEM_lockfree_printmemlist_stats;
+void (*MEM_set_error_callback)(void (*func)(const char *)) = MEM_lockfree_set_error_callback;
+bool (*MEM_check_memory_integrity)(void) = MEM_lockfree_check_memory_integrity;
+void (*MEM_set_lock_callback)(void (*lock)(void), void (*unlock)(void)) = MEM_lockfree_set_lock_callback;
+void (*MEM_set_memory_debug)(void) = MEM_lockfree_set_memory_debug;
+uintptr_t (*MEM_get_memory_in_use)(void) = MEM_lockfree_get_memory_in_use;
+uintptr_t (*MEM_get_mapped_memory_in_use)(void) = MEM_lockfree_get_mapped_memory_in_use;
+unsigned int (*MEM_get_memory_blocks_in_use)(void) = MEM_lockfree_get_memory_blocks_in_use;
+void (*MEM_reset_peak_memory)(void) = MEM_lockfree_reset_peak_memory;
+uintptr_t (*MEM_get_peak_memory)(void) = MEM_lockfree_get_peak_memory;
#ifndef NDEBUG
-const char *MEM_name_ptr(void *vmemh)
-{
- if (vmemh) {
- MemHead *memh = vmemh;
- memh--;
- return memh->name;
- }
- else {
- return "MEM_name_ptr(NULL)";
- }
-}
-#endif /* NDEBUG */
+const char *(*MEM_name_ptr)(void *vmemh) = MEM_lockfree_name_ptr;
+#endif
+
+void MEM_use_guarded_allocator(void)
+{
+ MEM_allocN_len = MEM_guarded_allocN_len;
+ MEM_freeN = MEM_guarded_freeN;
+ MEM_dupallocN = MEM_guarded_dupallocN;
+ MEM_reallocN_id = MEM_guarded_reallocN_id;
+ MEM_recallocN_id = MEM_guarded_recallocN_id;;
+ MEM_callocN = MEM_guarded_callocN;
+ MEM_mallocN = MEM_guarded_mallocN;
+ MEM_mapallocN = MEM_guarded_mapallocN;
+ MEM_printmemlist_pydict = MEM_guarded_printmemlist_pydict;
+ MEM_printmemlist = MEM_guarded_printmemlist;
+ MEM_callbackmemlist = MEM_guarded_callbackmemlist;
+ MEM_printmemlist_stats = MEM_guarded_printmemlist_stats;
+ MEM_set_error_callback = MEM_guarded_set_error_callback;
+ MEM_check_memory_integrity = MEM_guarded_check_memory_integrity;
+ MEM_set_lock_callback = MEM_guarded_set_lock_callback;
+ MEM_set_memory_debug = MEM_guarded_set_memory_debug;
+ MEM_get_memory_in_use = MEM_guarded_get_memory_in_use;
+ MEM_get_mapped_memory_in_use = MEM_guarded_get_mapped_memory_in_use;
+ MEM_get_memory_blocks_in_use = MEM_guarded_get_memory_blocks_in_use;
+ MEM_reset_peak_memory = MEM_guarded_reset_peak_memory;
+ MEM_get_peak_memory = MEM_guarded_get_peak_memory;
-#else /* !WITH_GUARDEDALLOC */
-
-#ifdef __GNUC__
-# define UNUSED(x) UNUSED_ ## x __attribute__((__unused__))
-#else
-# define UNUSED(x) UNUSED_ ## x
+#ifndef NDEBUG
+ MEM_name_ptr = MEM_guarded_name_ptr;
#endif
-
-#include <malloc.h>
-
-size_t MEM_allocN_len(const void *vmemh)
-{
- return malloc_usable_size((void *)vmemh);
-}
-
-void MEM_freeN(void *vmemh)
-{
- free(vmemh);
-}
-
-void *MEM_dupallocN(const void *vmemh)
-{
- void *newp = NULL;
- if (vmemh) {
- const size_t prev_size = MEM_allocN_len(vmemh);
- newp = malloc(prev_size);
- memcpy(newp, vmemh, prev_size);
- }
- return newp;
-}
-
-void *MEM_reallocN_id(void *vmemh, size_t len, const char *UNUSED(str))
-{
- return realloc(vmemh, len);
}
-
-void *MEM_recallocN_id(void *vmemh, size_t len, const char *UNUSED(str))
-{
- void *newp = NULL;
-
- if (vmemh) {
- size_t vmemh_len = MEM_allocN_len(vmemh);
- newp = malloc(len);
- if (newp) {
- if (len < vmemh_len) {
- /* shrink */
- memcpy(newp, vmemh, len);
- }
- else {
- memcpy(newp, vmemh, vmemh_len);
-
- if (len > vmemh_len) {
- /* grow */
- /* zero new bytes */
- memset(((char *)newp) + vmemh_len, 0, len - vmemh_len);
- }
- }
- }
-
- free(vmemh);
- }
- else {
- newp = calloc(1, len);
- }
-
- return newp;
-}
-
-void *MEM_callocN(size_t len, const char *UNUSED(str))
-{
- return calloc(1, len);
-}
-
-void *MEM_mallocN(size_t len, const char *UNUSED(str))
-{
- return malloc(len);
-}
-
-void *MEM_mapallocN(size_t len, const char *UNUSED(str))
-{
- /* could us mmap */
- return calloc(1, len);
-}
-
-void MEM_printmemlist_pydict(void) {}
-void MEM_printmemlist(void) {}
-
-/* unused */
-void MEM_callbackmemlist(void (*func)(void *))
-{
- (void)func;
-}
-
-void MEM_printmemlist_stats(void) {}
-
-void MEM_set_error_callback(void (*func)(const char *))
-{
- (void)func;
-}
-
-int MEM_check_memory_integrity(void)
-{
- return 1;
-}
-
-void MEM_set_lock_callback(void (*lock)(void), void (*unlock)(void))
-{
- (void)lock;
- (void)unlock;
-}
-
-void MEM_set_memory_debug(void) {}
-
-uintptr_t MEM_get_memory_in_use(void)
-{
- struct mallinfo mi;
- mi = mallinfo();
- return mi.uordblks;
-}
-
-uintptr_t MEM_get_mapped_memory_in_use(void)
-{
- return MEM_get_memory_in_use();
-}
-
-int MEM_get_memory_blocks_in_use(void)
-{
- struct mallinfo mi;
- mi = mallinfo();
- return mi.smblks + mi.hblks;
-}
-
-/* dummy */
-void MEM_reset_peak_memory(void) {}
-
-uintptr_t MEM_get_peak_memory(void)
-{
- return MEM_get_memory_in_use();
-}
-
-#endif /* WITH_GUARDEDALLOC */
diff --git a/intern/guardedalloc/intern/mallocn_guarded_impl.c b/intern/guardedalloc/intern/mallocn_guarded_impl.c
new file mode 100644
index 00000000000..92392ce4dd3
--- /dev/null
+++ b/intern/guardedalloc/intern/mallocn_guarded_impl.c
@@ -0,0 +1,1114 @@
+/*
+ * ***** 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) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Brecht Van Lommel
+ * Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file guardedalloc/intern/mallocn.c
+ * \ingroup MEM
+ *
+ * Guarded memory allocation, and boundary-write detection.
+ */
+
+#include <stdlib.h>
+#include <string.h> /* memcpy */
+#include <stdarg.h>
+#include <sys/types.h>
+
+#include "MEM_guardedalloc.h"
+
+/* to ensure strict conversions */
+#include "../../source/blender/blenlib/BLI_strict_flags.h"
+
+#include "mallocn_intern.h"
+#include "atomic_ops.h"
+
+/* Only for debugging:
+ * store original buffer's name when doing MEM_dupallocN
+ * helpful to profile issues with non-freed "dup_alloc" buffers,
+ * but this introduces some overhead to memory header and makes
+ * things slower a bit, so better to keep disabled by default
+ */
+//#define DEBUG_MEMDUPLINAME
+
+/* Only for debugging:
+ * lets you count the allocations so as to find the allocator of unfreed memory
+ * in situations where the leak is predictable */
+
+//#define DEBUG_MEMCOUNTER
+
+/* Only for debugging:
+ * defining DEBUG_THREADS will enable check whether memory manager
+ * is locked with a mutex when allocation is called from non-main
+ * thread.
+ *
+ * This helps troubleshooting memory issues caused by the fact
+ * guarded allocator is not thread-safe, however this check will
+ * fail to check allocations from openmp threads.
+ */
+//#define DEBUG_THREADS
+
+/* Only for debugging:
+ * Defining DEBUG_BACKTRACE will store a backtrace from where
+ * memory block was allocated and print this trace for all
+ * unfreed blocks.
+ */
+//#define DEBUG_BACKTRACE
+
+#ifdef DEBUG_BACKTRACE
+# define BACKTRACE_SIZE 100
+#endif
+
+#ifdef DEBUG_MEMCOUNTER
+ /* set this to the value that isn't being freed */
+# define DEBUG_MEMCOUNTER_ERROR_VAL 0
+static int _mallocn_count = 0;
+
+/* breakpoint here */
+static void memcount_raise(const char *name)
+{
+ fprintf(stderr, "%s: memcount-leak, %d\n", name, _mallocn_count);
+}
+#endif
+
+/* --------------------------------------------------------------------- */
+/* Data definition */
+/* --------------------------------------------------------------------- */
+/* all memory chunks are put in linked lists */
+typedef struct localLink {
+ struct localLink *next, *prev;
+} localLink;
+
+typedef struct localListBase {
+ void *first, *last;
+} localListBase;
+
+/* note: keep this struct aligned (e.g., irix/gcc) - Hos */
+typedef struct MemHead {
+ int tag1;
+ size_t len;
+ struct MemHead *next, *prev;
+ const char *name;
+ const char *nextname;
+ int tag2;
+ int mmap; /* if true, memory was mmapped */
+#ifdef DEBUG_MEMCOUNTER
+ int _count;
+#endif
+
+#ifdef DEBUG_MEMDUPLINAME
+ int need_free_name, pad;
+#endif
+
+#ifdef DEBUG_BACKTRACE
+ void *backtrace[BACKTRACE_SIZE];
+ int backtrace_size;
+#endif
+} MemHead;
+
+/* for openmp threading asserts, saves time troubleshooting
+ * we may need to extend this if blender code starts using MEM_
+ * functions inside OpenMP correctly with omp_set_lock() */
+
+#if 0 /* disable for now, only use to debug openmp code which doesn lock threads for malloc */
+#if defined(_OPENMP) && defined(DEBUG)
+# include <assert.h>
+# include <omp.h>
+# define DEBUG_OMP_MALLOC
+#endif
+#endif
+
+#ifdef DEBUG_THREADS
+# include <assert.h>
+# include <pthread.h>
+static pthread_t mainid;
+#endif
+
+#ifdef DEBUG_BACKTRACE
+# if defined(__linux__) || defined(__APPLE__)
+# include <execinfo.h>
+// Windows is not supported yet.
+//# elif defined(_MSV_VER)
+//# include <DbgHelp.h>
+# endif
+#endif
+
+typedef struct MemTail {
+ int tag3, pad;
+} MemTail;
+
+
+/* --------------------------------------------------------------------- */
+/* local functions */
+/* --------------------------------------------------------------------- */
+
+static void addtail(volatile localListBase *listbase, void *vlink);
+static void remlink(volatile localListBase *listbase, void *vlink);
+static void rem_memblock(MemHead *memh);
+static void MemorY_ErroR(const char *block, const char *error);
+static const char *check_memlist(MemHead *memh);
+
+/* --------------------------------------------------------------------- */
+/* locally used defines */
+/* --------------------------------------------------------------------- */
+
+#ifdef __BIG_ENDIAN__
+# define MAKE_ID(a, b, c, d) ((int)(a) << 24 | (int)(b) << 16 | (c) << 8 | (d))
+#else
+# define MAKE_ID(a, b, c, d) ((int)(d) << 24 | (int)(c) << 16 | (b) << 8 | (a))
+#endif
+
+#define MEMTAG1 MAKE_ID('M', 'E', 'M', 'O')
+#define MEMTAG2 MAKE_ID('R', 'Y', 'B', 'L')
+#define MEMTAG3 MAKE_ID('O', 'C', 'K', '!')
+#define MEMFREE MAKE_ID('F', 'R', 'E', 'E')
+
+#define MEMNEXT(x) \
+ ((MemHead *)(((char *) x) - ((char *) &(((MemHead *)0)->next))))
+
+/* --------------------------------------------------------------------- */
+/* vars */
+/* --------------------------------------------------------------------- */
+
+
+static unsigned int totblock = 0;
+static size_t mem_in_use = 0, mmap_in_use = 0, peak_mem = 0;
+
+static volatile struct localListBase _membase;
+static volatile struct localListBase *membase = &_membase;
+static void (*error_callback)(const char *) = NULL;
+static void (*thread_lock_callback)(void) = NULL;
+static void (*thread_unlock_callback)(void) = NULL;
+
+static bool malloc_debug_memset = false;
+
+#ifdef malloc
+#undef malloc
+#endif
+
+#ifdef calloc
+#undef calloc
+#endif
+
+#ifdef free
+#undef free
+#endif
+
+
+/* --------------------------------------------------------------------- */
+/* implementation */
+/* --------------------------------------------------------------------- */
+
+#ifdef __GNUC__
+__attribute__ ((format(printf, 1, 2)))
+#endif
+static void print_error(const char *str, ...)
+{
+ char buf[512];
+ va_list ap;
+
+ va_start(ap, str);
+ vsnprintf(buf, sizeof(buf), str, ap);
+ va_end(ap);
+ buf[sizeof(buf) - 1] = '\0';
+
+ if (error_callback) error_callback(buf);
+}
+
+static void mem_lock_thread(void)
+{
+#ifdef DEBUG_THREADS
+ static int initialized = 0;
+
+ if (initialized == 0) {
+ /* assume first allocation happens from main thread */
+ mainid = pthread_self();
+ initialized = 1;
+ }
+
+ if (!pthread_equal(pthread_self(), mainid) && thread_lock_callback == NULL) {
+ assert(!"Memory function is called from non-main thread without lock");
+ }
+#endif
+
+#ifdef DEBUG_OMP_MALLOC
+ assert(omp_in_parallel() == 0);
+#endif
+
+ if (thread_lock_callback)
+ thread_lock_callback();
+}
+
+static void mem_unlock_thread(void)
+{
+#ifdef DEBUG_THREADS
+ if (!pthread_equal(pthread_self(), mainid) && thread_lock_callback == NULL) {
+ assert(!"Thread lock was removed while allocation from thread is in progress");
+ }
+#endif
+
+ if (thread_unlock_callback)
+ thread_unlock_callback();
+}
+
+bool MEM_guarded_check_memory_integrity(void)
+{
+ const char *err_val = NULL;
+ MemHead *listend;
+ /* check_memlist starts from the front, and runs until it finds
+ * the requested chunk. For this test, that's the last one. */
+ listend = membase->last;
+
+ err_val = check_memlist(listend);
+
+ return (err_val != NULL);
+}
+
+
+void MEM_guarded_set_error_callback(void (*func)(const char *))
+{
+ error_callback = func;
+}
+
+void MEM_guarded_set_lock_callback(void (*lock)(void), void (*unlock)(void))
+{
+ thread_lock_callback = lock;
+ thread_unlock_callback = unlock;
+}
+
+void MEM_guarded_set_memory_debug(void)
+{
+ malloc_debug_memset = true;
+}
+
+size_t MEM_guarded_allocN_len(const void *vmemh)
+{
+ if (vmemh) {
+ const MemHead *memh = vmemh;
+
+ memh--;
+ return memh->len;
+ }
+ else {
+ return 0;
+ }
+}
+
+void *MEM_guarded_dupallocN(const void *vmemh)
+{
+ void *newp = NULL;
+
+ if (vmemh) {
+ const MemHead *memh = vmemh;
+ memh--;
+
+#ifndef DEBUG_MEMDUPLINAME
+ if (memh->mmap)
+ newp = MEM_guarded_mapallocN(memh->len, "dupli_mapalloc");
+ else
+ newp = MEM_guarded_mallocN(memh->len, "dupli_alloc");
+
+ if (newp == NULL) return NULL;
+#else
+ {
+ MemHead *nmemh;
+ char *name = malloc(strlen(memh->name) + 24);
+
+ if (memh->mmap) {
+ sprintf(name, "%s %s", "dupli_mapalloc", memh->name);
+ newp = MEM_guarded_mapallocN(memh->len, name);
+ }
+ else {
+ sprintf(name, "%s %s", "dupli_alloc", memh->name);
+ newp = MEM_guarded_mallocN(memh->len, name);
+ }
+
+ if (newp == NULL) return NULL;
+
+ nmemh = newp;
+ nmemh--;
+
+ nmemh->need_free_name = 1;
+ }
+#endif
+
+ memcpy(newp, vmemh, memh->len);
+ }
+
+ return newp;
+}
+
+void *MEM_guarded_reallocN_id(void *vmemh, size_t len, const char *str)
+{
+ void *newp = NULL;
+
+ if (vmemh) {
+ MemHead *memh = vmemh;
+ memh--;
+
+ newp = MEM_guarded_mallocN(len, memh->name);
+ if (newp) {
+ if (len < memh->len) {
+ /* shrink */
+ memcpy(newp, vmemh, len);
+ }
+ else {
+ /* grow (or remain same size) */
+ memcpy(newp, vmemh, memh->len);
+ }
+ }
+
+ MEM_guarded_freeN(vmemh);
+ }
+ else {
+ newp = MEM_guarded_mallocN(len, str);
+ }
+
+ return newp;
+}
+
+void *MEM_guarded_recallocN_id(void *vmemh, size_t len, const char *str)
+{
+ void *newp = NULL;
+
+ if (vmemh) {
+ MemHead *memh = vmemh;
+ memh--;
+
+ newp = MEM_guarded_mallocN(len, memh->name);
+ if (newp) {
+ if (len < memh->len) {
+ /* shrink */
+ memcpy(newp, vmemh, len);
+ }
+ else {
+ memcpy(newp, vmemh, memh->len);
+
+ if (len > memh->len) {
+ /* grow */
+ /* zero new bytes */
+ memset(((char *)newp) + memh->len, 0, len - memh->len);
+ }
+ }
+ }
+
+ MEM_guarded_freeN(vmemh);
+ }
+ else {
+ newp = MEM_guarded_callocN(len, str);
+ }
+
+ return newp;
+}
+
+#ifdef DEBUG_BACKTRACE
+# if defined(__linux__) || defined(__APPLE__)
+static void make_memhead_backtrace(MemHead *memh)
+{
+ memh->backtrace_size = backtrace(memh->backtrace, BACKTRACE_SIZE);
+}
+
+static void print_memhead_backtrace(MemHead *memh)
+{
+ char **strings;
+ int i;
+
+ strings = backtrace_symbols(memh->backtrace, memh->backtrace_size);
+ for (i = 0; i < memh->backtrace_size; i++) {
+ print_error(" %s\n", strings[i]);
+ }
+
+ free(strings);
+}
+# else
+static void make_memhead_backtrace(MemHead *memh)
+{
+ (void) memh; /* Ignored. */
+}
+
+static void print_memhead_backtrace(MemHead *memh)
+{
+ (void) memh; /* Ignored. */
+}
+# endif /* defined(__linux__) || defined(__APPLE__) */
+#endif /* DEBUG_BACKTRACE */
+
+static void make_memhead_header(MemHead *memh, size_t len, const char *str)
+{
+ MemTail *memt;
+
+ memh->tag1 = MEMTAG1;
+ memh->name = str;
+ memh->nextname = NULL;
+ memh->len = len;
+ memh->mmap = 0;
+ memh->tag2 = MEMTAG2;
+
+#ifdef DEBUG_MEMDUPLINAME
+ memh->need_free_name = 0;
+#endif
+
+#ifdef DEBUG_BACKTRACE
+ make_memhead_backtrace(memh);
+#endif
+
+ memt = (MemTail *)(((char *) memh) + sizeof(MemHead) + len);
+ memt->tag3 = MEMTAG3;
+
+ atomic_add_u(&totblock, 1);
+ atomic_add_z(&mem_in_use, len);
+
+ mem_lock_thread();
+ addtail(membase, &memh->next);
+ if (memh->next) {
+ memh->nextname = MEMNEXT(memh->next)->name;
+ }
+ peak_mem = mem_in_use > peak_mem ? mem_in_use : peak_mem;
+ mem_unlock_thread();
+}
+
+void *MEM_guarded_mallocN(size_t len, const char *str)
+{
+ MemHead *memh;
+
+ len = SIZET_ALIGN_4(len);
+
+ memh = (MemHead *)malloc(len + sizeof(MemHead) + sizeof(MemTail));
+
+ if (memh) {
+ make_memhead_header(memh, len, str);
+ if (malloc_debug_memset && len)
+ memset(memh + 1, 255, len);
+
+#ifdef DEBUG_MEMCOUNTER
+ if (_mallocn_count == DEBUG_MEMCOUNTER_ERROR_VAL)
+ memcount_raise(__func__);
+ memh->_count = _mallocn_count++;
+#endif
+ return (++memh);
+ }
+ print_error("Malloc returns null: len=" SIZET_FORMAT " in %s, total %u\n",
+ SIZET_ARG(len), str, (unsigned int) mem_in_use);
+ return NULL;
+}
+
+void *MEM_guarded_callocN(size_t len, const char *str)
+{
+ MemHead *memh;
+
+ len = SIZET_ALIGN_4(len);
+
+ memh = (MemHead *)calloc(len + sizeof(MemHead) + sizeof(MemTail), 1);
+
+ if (memh) {
+ make_memhead_header(memh, len, str);
+#ifdef DEBUG_MEMCOUNTER
+ if (_mallocn_count == DEBUG_MEMCOUNTER_ERROR_VAL)
+ memcount_raise(__func__);
+ memh->_count = _mallocn_count++;
+#endif
+ return (++memh);
+ }
+ print_error("Calloc returns null: len=" SIZET_FORMAT " in %s, total %u\n",
+ SIZET_ARG(len), str, (unsigned int) mem_in_use);
+ return NULL;
+}
+
+/* note; mmap returns zero'd memory */
+void *MEM_guarded_mapallocN(size_t len, const char *str)
+{
+ MemHead *memh;
+
+ len = SIZET_ALIGN_4(len);
+
+#if defined(WIN32)
+ /* our windows mmap implementation is not thread safe */
+ mem_lock_thread();
+#endif
+ memh = mmap(NULL, len + sizeof(MemHead) + sizeof(MemTail),
+ PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
+#if defined(WIN32)
+ mem_unlock_thread();
+#endif
+
+ if (memh != (MemHead *)-1) {
+ make_memhead_header(memh, len, str);
+ memh->mmap = 1;
+ atomic_add_z(&mmap_in_use, len);
+ mem_lock_thread();
+ peak_mem = mmap_in_use > peak_mem ? mmap_in_use : peak_mem;
+ mem_unlock_thread();
+#ifdef DEBUG_MEMCOUNTER
+ if (_mallocn_count == DEBUG_MEMCOUNTER_ERROR_VAL)
+ memcount_raise(__func__);
+ memh->_count = _mallocn_count++;
+#endif
+ return (++memh);
+ }
+ else {
+ print_error("Mapalloc returns null, fallback to regular malloc: "
+ "len=" SIZET_FORMAT " in %s, total %u\n",
+ SIZET_ARG(len), str, (unsigned int) mmap_in_use);
+ return MEM_guarded_callocN(len, str);
+ }
+}
+
+/* Memory statistics print */
+typedef struct MemPrintBlock {
+ const char *name;
+ uintptr_t len;
+ int items;
+} MemPrintBlock;
+
+static int compare_name(const void *p1, const void *p2)
+{
+ const MemPrintBlock *pb1 = (const MemPrintBlock *)p1;
+ const MemPrintBlock *pb2 = (const MemPrintBlock *)p2;
+
+ return strcmp(pb1->name, pb2->name);
+}
+
+static int compare_len(const void *p1, const void *p2)
+{
+ const MemPrintBlock *pb1 = (const MemPrintBlock *)p1;
+ const MemPrintBlock *pb2 = (const MemPrintBlock *)p2;
+
+ if (pb1->len < pb2->len)
+ return 1;
+ else if (pb1->len == pb2->len)
+ return 0;
+ else
+ return -1;
+}
+
+void MEM_guarded_printmemlist_stats(void)
+{
+ MemHead *membl;
+ MemPrintBlock *pb, *printblock;
+ unsigned int totpb, a, b;
+ size_t mem_in_use_slop = 0;
+
+ mem_lock_thread();
+
+ /* put memory blocks into array */
+ printblock = malloc(sizeof(MemPrintBlock) * totblock);
+
+ pb = printblock;
+ totpb = 0;
+
+ membl = membase->first;
+ if (membl) membl = MEMNEXT(membl);
+
+ while (membl) {
+ pb->name = membl->name;
+ pb->len = membl->len;
+ pb->items = 1;
+
+ totpb++;
+ pb++;
+
+ if (!membl->mmap) {
+ mem_in_use_slop += (sizeof(MemHead) + sizeof(MemTail) +
+ malloc_usable_size((void *)membl)) - membl->len;
+ }
+
+ if (membl->next)
+ membl = MEMNEXT(membl->next);
+ else break;
+ }
+
+ /* sort by name and add together blocks with the same name */
+ qsort(printblock, totpb, sizeof(MemPrintBlock), compare_name);
+ for (a = 0, b = 0; a < totpb; a++) {
+ if (a == b) {
+ continue;
+ }
+ else if (strcmp(printblock[a].name, printblock[b].name) == 0) {
+ printblock[b].len += printblock[a].len;
+ printblock[b].items++;
+ }
+ else {
+ b++;
+ memcpy(&printblock[b], &printblock[a], sizeof(MemPrintBlock));
+ }
+ }
+ totpb = b + 1;
+
+ /* sort by length and print */
+ qsort(printblock, totpb, sizeof(MemPrintBlock), compare_len);
+ printf("\ntotal memory len: %.3f MB\n",
+ (double)mem_in_use / (double)(1024 * 1024));
+ printf("peak memory len: %.3f MB\n",
+ (double)peak_mem / (double)(1024 * 1024));
+ printf("slop memory len: %.3f MB\n",
+ (double)mem_in_use_slop / (double)(1024 * 1024));
+ printf(" ITEMS TOTAL-MiB AVERAGE-KiB TYPE\n");
+ for (a = 0, pb = printblock; a < totpb; a++, pb++) {
+ printf("%6d (%8.3f %8.3f) %s\n",
+ pb->items, (double)pb->len / (double)(1024 * 1024),
+ (double)pb->len / 1024.0 / (double)pb->items, pb->name);
+ }
+ free(printblock);
+
+ mem_unlock_thread();
+
+#ifdef HAVE_MALLOC_STATS
+ printf("System Statistics:\n");
+ malloc_stats();
+#endif
+}
+
+static const char mem_printmemlist_pydict_script[] =
+"mb_userinfo = {}\n"
+"totmem = 0\n"
+"for mb_item in membase:\n"
+" mb_item_user_size = mb_userinfo.setdefault(mb_item['name'], [0,0])\n"
+" mb_item_user_size[0] += 1 # Add a user\n"
+" mb_item_user_size[1] += mb_item['len'] # Increment the size\n"
+" totmem += mb_item['len']\n"
+"print('(membase) items:', len(membase), '| unique-names:',\n"
+" len(mb_userinfo), '| total-mem:', totmem)\n"
+"mb_userinfo_sort = list(mb_userinfo.items())\n"
+"for sort_name, sort_func in (('size', lambda a: -a[1][1]),\n"
+" ('users', lambda a: -a[1][0]),\n"
+" ('name', lambda a: a[0])):\n"
+" print('\\nSorting by:', sort_name)\n"
+" mb_userinfo_sort.sort(key = sort_func)\n"
+" for item in mb_userinfo_sort:\n"
+" print('name:%%s, users:%%i, len:%%i' %%\n"
+" (item[0], item[1][0], item[1][1]))\n";
+
+/* Prints in python syntax for easy */
+static void MEM_guarded_printmemlist_internal(int pydict)
+{
+ MemHead *membl;
+
+ mem_lock_thread();
+
+ membl = membase->first;
+ if (membl) membl = MEMNEXT(membl);
+
+ if (pydict) {
+ print_error("# membase_debug.py\n");
+ print_error("membase = [\n");
+ }
+ while (membl) {
+ if (pydict) {
+ fprintf(stderr,
+ " {'len':" SIZET_FORMAT ", "
+ "'name':'''%s''', "
+ "'pointer':'%p'},\n",
+ SIZET_ARG(membl->len), membl->name, (void *)(membl + 1));
+ }
+ else {
+#ifdef DEBUG_MEMCOUNTER
+ print_error("%s len: " SIZET_FORMAT " %p, count: %d\n",
+ membl->name, SIZET_ARG(membl->len), membl + 1,
+ membl->_count);
+#else
+ print_error("%s len: " SIZET_FORMAT " %p\n",
+ membl->name, SIZET_ARG(membl->len), membl + 1);
+#endif
+#ifdef DEBUG_BACKTRACE
+ print_memhead_backtrace(membl);
+#endif
+ }
+ if (membl->next)
+ membl = MEMNEXT(membl->next);
+ else break;
+ }
+ if (pydict) {
+ fprintf(stderr, "]\n\n");
+ fprintf(stderr, mem_printmemlist_pydict_script);
+ }
+
+ mem_unlock_thread();
+}
+
+void MEM_guarded_callbackmemlist(void (*func)(void *))
+{
+ MemHead *membl;
+
+ mem_lock_thread();
+
+ membl = membase->first;
+ if (membl) membl = MEMNEXT(membl);
+
+ while (membl) {
+ func(membl + 1);
+ if (membl->next)
+ membl = MEMNEXT(membl->next);
+ else break;
+ }
+
+ mem_unlock_thread();
+}
+
+#if 0
+short MEM_guarded_testN(void *vmemh)
+{
+ MemHead *membl;
+
+ mem_lock_thread();
+
+ membl = membase->first;
+ if (membl) membl = MEMNEXT(membl);
+
+ while (membl) {
+ if (vmemh == membl + 1) {
+ mem_unlock_thread();
+ return 1;
+ }
+
+ if (membl->next)
+ membl = MEMNEXT(membl->next);
+ else break;
+ }
+
+ mem_unlock_thread();
+
+ print_error("Memoryblock %p: pointer not in memlist\n", vmemh);
+ return 0;
+}
+#endif
+
+void MEM_guarded_printmemlist(void)
+{
+ MEM_guarded_printmemlist_internal(0);
+}
+void MEM_guarded_printmemlist_pydict(void)
+{
+ MEM_guarded_printmemlist_internal(1);
+}
+
+void MEM_guarded_freeN(void *vmemh)
+{
+ MemTail *memt;
+ MemHead *memh = vmemh;
+ const char *name;
+
+ if (memh == NULL) {
+ MemorY_ErroR("free", "attempt to free NULL pointer");
+ /* print_error(err_stream, "%d\n", (memh+4000)->tag1); */
+ return;
+ }
+
+ if (sizeof(intptr_t) == 8) {
+ if (((intptr_t) memh) & 0x7) {
+ MemorY_ErroR("free", "attempt to free illegal pointer");
+ return;
+ }
+ }
+ else {
+ if (((intptr_t) memh) & 0x3) {
+ MemorY_ErroR("free", "attempt to free illegal pointer");
+ return;
+ }
+ }
+
+ memh--;
+ if (memh->tag1 == MEMFREE && memh->tag2 == MEMFREE) {
+ MemorY_ErroR(memh->name, "double free");
+ return;
+ }
+
+ if ((memh->tag1 == MEMTAG1) &&
+ (memh->tag2 == MEMTAG2) &&
+ ((memh->len & 0x3) == 0))
+ {
+ memt = (MemTail *)(((char *) memh) + sizeof(MemHead) + memh->len);
+ if (memt->tag3 == MEMTAG3) {
+
+ memh->tag1 = MEMFREE;
+ memh->tag2 = MEMFREE;
+ memt->tag3 = MEMFREE;
+ /* after tags !!! */
+ rem_memblock(memh);
+
+ return;
+ }
+ MemorY_ErroR(memh->name, "end corrupt");
+ name = check_memlist(memh);
+ if (name != NULL) {
+ if (name != memh->name) MemorY_ErroR(name, "is also corrupt");
+ }
+ }
+ else {
+ mem_lock_thread();
+ name = check_memlist(memh);
+ mem_unlock_thread();
+ if (name == NULL)
+ MemorY_ErroR("free", "pointer not in memlist");
+ else
+ MemorY_ErroR(name, "error in header");
+ }
+
+ totblock--;
+ /* here a DUMP should happen */
+
+ return;
+}
+
+/* --------------------------------------------------------------------- */
+/* local functions */
+/* --------------------------------------------------------------------- */
+
+static void addtail(volatile localListBase *listbase, void *vlink)
+{
+ struct localLink *link = vlink;
+
+ /* for a generic API error checks here is fine but
+ * the limited use here they will never be NULL */
+#if 0
+ if (link == NULL) return;
+ if (listbase == NULL) return;
+#endif
+
+ link->next = NULL;
+ link->prev = listbase->last;
+
+ if (listbase->last) ((struct localLink *)listbase->last)->next = link;
+ if (listbase->first == NULL) listbase->first = link;
+ listbase->last = link;
+}
+
+static void remlink(volatile localListBase *listbase, void *vlink)
+{
+ struct localLink *link = vlink;
+
+ /* for a generic API error checks here is fine but
+ * the limited use here they will never be NULL */
+#if 0
+ if (link == NULL) return;
+ if (listbase == NULL) return;
+#endif
+
+ if (link->next) link->next->prev = link->prev;
+ if (link->prev) link->prev->next = link->next;
+
+ if (listbase->last == link) listbase->last = link->prev;
+ if (listbase->first == link) listbase->first = link->next;
+}
+
+static void rem_memblock(MemHead *memh)
+{
+ mem_lock_thread();
+ remlink(membase, &memh->next);
+ if (memh->prev) {
+ if (memh->next)
+ MEMNEXT(memh->prev)->nextname = MEMNEXT(memh->next)->name;
+ else
+ MEMNEXT(memh->prev)->nextname = NULL;
+ }
+ mem_unlock_thread();
+
+ atomic_sub_u(&totblock, 1);
+ atomic_sub_z(&mem_in_use, memh->len);
+
+#ifdef DEBUG_MEMDUPLINAME
+ if (memh->need_free_name)
+ free((char *) memh->name);
+#endif
+
+ if (memh->mmap) {
+ atomic_sub_z(&mmap_in_use, memh->len);
+#if defined(WIN32)
+ /* our windows mmap implementation is not thread safe */
+ mem_lock_thread();
+#endif
+ if (munmap(memh, memh->len + sizeof(MemHead) + sizeof(MemTail)))
+ printf("Couldn't unmap memory %s\n", memh->name);
+#if defined(WIN32)
+ mem_unlock_thread();
+#endif
+ }
+ else {
+ if (malloc_debug_memset && memh->len)
+ memset(memh + 1, 255, memh->len);
+ free(memh);
+ }
+}
+
+static void MemorY_ErroR(const char *block, const char *error)
+{
+ print_error("Memoryblock %s: %s\n", block, error);
+
+#ifdef WITH_ASSERT_ABORT
+ abort();
+#endif
+}
+
+static const char *check_memlist(MemHead *memh)
+{
+ MemHead *forw, *back, *forwok, *backok;
+ const char *name;
+
+ forw = membase->first;
+ if (forw) forw = MEMNEXT(forw);
+ forwok = NULL;
+ while (forw) {
+ if (forw->tag1 != MEMTAG1 || forw->tag2 != MEMTAG2) break;
+ forwok = forw;
+ if (forw->next) forw = MEMNEXT(forw->next);
+ else forw = NULL;
+ }
+
+ back = (MemHead *) membase->last;
+ if (back) back = MEMNEXT(back);
+ backok = NULL;
+ while (back) {
+ if (back->tag1 != MEMTAG1 || back->tag2 != MEMTAG2) break;
+ backok = back;
+ if (back->prev) back = MEMNEXT(back->prev);
+ else back = NULL;
+ }
+
+ if (forw != back) return ("MORE THAN 1 MEMORYBLOCK CORRUPT");
+
+ if (forw == NULL && back == NULL) {
+ /* no wrong headers found then but in search of memblock */
+
+ forw = membase->first;
+ if (forw) forw = MEMNEXT(forw);
+ forwok = NULL;
+ while (forw) {
+ if (forw == memh) break;
+ if (forw->tag1 != MEMTAG1 || forw->tag2 != MEMTAG2) break;
+ forwok = forw;
+ if (forw->next) forw = MEMNEXT(forw->next);
+ else forw = NULL;
+ }
+ if (forw == NULL) return NULL;
+
+ back = (MemHead *) membase->last;
+ if (back) back = MEMNEXT(back);
+ backok = NULL;
+ while (back) {
+ if (back == memh) break;
+ if (back->tag1 != MEMTAG1 || back->tag2 != MEMTAG2) break;
+ backok = back;
+ if (back->prev) back = MEMNEXT(back->prev);
+ else back = NULL;
+ }
+ }
+
+ if (forwok) name = forwok->nextname;
+ else name = "No name found";
+
+ if (forw == memh) {
+ /* to be sure but this block is removed from the list */
+ if (forwok) {
+ if (backok) {
+ forwok->next = (MemHead *)&backok->next;
+ backok->prev = (MemHead *)&forwok->next;
+ forwok->nextname = backok->name;
+ }
+ else {
+ forwok->next = NULL;
+ membase->last = (struct localLink *) &forwok->next;
+ }
+ }
+ else {
+ if (backok) {
+ backok->prev = NULL;
+ membase->first = &backok->next;
+ }
+ else {
+ membase->first = membase->last = NULL;
+ }
+ }
+ }
+ else {
+ MemorY_ErroR(name, "Additional error in header");
+ return("Additional error in header");
+ }
+
+ return(name);
+}
+
+size_t MEM_guarded_get_peak_memory(void)
+{
+ size_t _peak_mem;
+
+ mem_lock_thread();
+ _peak_mem = peak_mem;
+ mem_unlock_thread();
+
+ return _peak_mem;
+}
+
+void MEM_guarded_reset_peak_memory(void)
+{
+ mem_lock_thread();
+ peak_mem = 0;
+ mem_unlock_thread();
+}
+
+uintptr_t MEM_guarded_get_memory_in_use(void)
+{
+ uintptr_t _mem_in_use;
+
+ mem_lock_thread();
+ _mem_in_use = mem_in_use;
+ mem_unlock_thread();
+
+ return _mem_in_use;
+}
+
+uintptr_t MEM_guarded_get_mapped_memory_in_use(void)
+{
+ uintptr_t _mmap_in_use;
+
+ mem_lock_thread();
+ _mmap_in_use = mmap_in_use;
+ mem_unlock_thread();
+
+ return _mmap_in_use;
+}
+
+unsigned int MEM_guarded_get_memory_blocks_in_use(void)
+{
+ unsigned int _totblock;
+
+ mem_lock_thread();
+ _totblock = totblock;
+ mem_unlock_thread();
+
+ return _totblock;
+}
+
+#ifndef NDEBUG
+const char *MEM_guarded_name_ptr(void *vmemh)
+{
+ if (vmemh) {
+ MemHead *memh = vmemh;
+ memh--;
+ return memh->name;
+ }
+ else {
+ return "MEM_guarded_name_ptr(NULL)";
+ }
+}
+#endif /* NDEBUG */
diff --git a/intern/guardedalloc/intern/mallocn_intern.h b/intern/guardedalloc/intern/mallocn_intern.h
new file mode 100644
index 00000000000..db45b59b884
--- /dev/null
+++ b/intern/guardedalloc/intern/mallocn_intern.h
@@ -0,0 +1,132 @@
+/*
+ * ***** 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) 2013 by Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file guardedalloc/intern/mallocn_intern.h
+ * \ingroup MEM
+ */
+
+#ifndef __MALLOCN_INTERN_H__
+#define __MALLOCN_INTERN_H__
+
+/* mmap exception */
+#if defined(WIN32)
+# include "mmap_win.h"
+#else
+# include <sys/mman.h>
+#endif
+
+#if defined(_MSC_VER)
+# define __func__ __FUNCTION__
+#endif
+
+#ifdef __GNUC__
+# define UNUSED(x) UNUSED_ ## x __attribute__((__unused__))
+#else
+# define UNUSED(x) UNUSED_ ## x
+#endif
+
+#undef HAVE_MALLOC_STATS
+
+#if defined(__linux__)
+# include <malloc.h>
+# define HAVE_MALLOC_STATS
+#elif defined(__FreeBSD__)
+# include <malloc_np.h>
+#elif defined(__APPLE__)
+# include <malloc/malloc.h>
+# define malloc_usable_size malloc_size
+#elif defined(WIN32)
+# include <malloc.h>
+# define malloc_usable_size _msize
+#else
+# error "We don't know how to use malloc_usable_size on your platform"
+#endif
+
+/* Blame Microsoft for LLP64 and no inttypes.h, quick workaround needed: */
+#if defined(WIN64)
+# define SIZET_FORMAT "%I64u"
+# define SIZET_ARG(a) ((unsigned long long)(a))
+#else
+# define SIZET_FORMAT "%lu"
+# define SIZET_ARG(a) ((unsigned long)(a))
+#endif
+
+#define SIZET_ALIGN_4(len) ((len + 3) & ~(size_t)3)
+
+/* Prototypes for counted allocator functions */
+size_t MEM_lockfree_allocN_len(const void *vmemh) ATTR_WARN_UNUSED_RESULT;
+void MEM_lockfree_freeN(void *vmemh);
+void *MEM_lockfree_dupallocN(const void *vmemh) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
+void *MEM_lockfree_reallocN_id(void *vmemh, size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(2);
+void *MEM_lockfree_recallocN_id(void *vmemh, size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(2);
+void *MEM_lockfree_callocN(size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
+void *MEM_lockfree_mallocN(size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
+void *MEM_lockfree_mapallocN(size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
+void MEM_lockfree_printmemlist_pydict(void);
+void MEM_lockfree_printmemlist(void);
+void MEM_lockfree_callbackmemlist(void (*func)(void *));
+void MEM_lockfree_printmemlist_stats(void);
+void MEM_lockfree_set_error_callback(void (*func)(const char *));
+bool MEM_lockfree_check_memory_integrity(void);
+void MEM_lockfree_set_lock_callback(void (*lock)(void), void (*unlock)(void));
+void MEM_lockfree_set_memory_debug(void);
+uintptr_t MEM_lockfree_get_memory_in_use(void);
+uintptr_t MEM_lockfree_get_mapped_memory_in_use(void);
+unsigned int MEM_lockfree_get_memory_blocks_in_use(void);
+void MEM_lockfree_reset_peak_memory(void);
+uintptr_t MEM_lockfree_get_peak_memory(void) ATTR_WARN_UNUSED_RESULT;
+#ifndef NDEBUG
+const char *MEM_lockfree_name_ptr(void *vmemh);
+#endif
+
+/* Prototypes for fully guarded allocator functions */
+size_t MEM_guarded_allocN_len(const void *vmemh) ATTR_WARN_UNUSED_RESULT;
+void MEM_guarded_freeN(void *vmemh);
+void *MEM_guarded_dupallocN(const void *vmemh) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
+void *MEM_guarded_reallocN_id(void *vmemh, size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(2);
+void *MEM_guarded_recallocN_id(void *vmemh, size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(2);
+void *MEM_guarded_callocN(size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
+void *MEM_guarded_mallocN(size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
+void *MEM_guarded_mapallocN(size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
+void MEM_guarded_printmemlist_pydict(void);
+void MEM_guarded_printmemlist(void);
+void MEM_guarded_callbackmemlist(void (*func)(void *));
+void MEM_guarded_printmemlist_stats(void);
+void MEM_guarded_set_error_callback(void (*func)(const char *));
+bool MEM_guarded_check_memory_integrity(void);
+void MEM_guarded_set_lock_callback(void (*lock)(void), void (*unlock)(void));
+void MEM_guarded_set_memory_debug(void);
+uintptr_t MEM_guarded_get_memory_in_use(void);
+uintptr_t MEM_guarded_get_mapped_memory_in_use(void);
+unsigned int MEM_guarded_get_memory_blocks_in_use(void);
+void MEM_guarded_reset_peak_memory(void);
+uintptr_t MEM_guarded_get_peak_memory(void) ATTR_WARN_UNUSED_RESULT;
+#ifndef NDEBUG
+const char *MEM_guarded_name_ptr(void *vmemh);
+#endif
+
+#endif /* __MALLOCN_INTERN_H__ */
diff --git a/intern/guardedalloc/intern/mallocn_lockfree_impl.c b/intern/guardedalloc/intern/mallocn_lockfree_impl.c
new file mode 100644
index 00000000000..35caebcc5e8
--- /dev/null
+++ b/intern/guardedalloc/intern/mallocn_lockfree_impl.c
@@ -0,0 +1,376 @@
+/*
+ * ***** 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) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Brecht Van Lommel
+ * Campbell Barton
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file guardedalloc/intern/mallocn.c
+ * \ingroup MEM
+ *
+ * Memory allocation which keeps track on allocated memory counters
+ */
+
+#include <stdlib.h>
+#include <string.h> /* memcpy */
+#include <stdarg.h>
+#include <sys/types.h>
+
+#include "MEM_guardedalloc.h"
+
+/* to ensure strict conversions */
+#include "../../source/blender/blenlib/BLI_strict_flags.h"
+
+#include "atomic_ops.h"
+#include "mallocn_intern.h"
+
+typedef struct MemHead {
+ /* Length of allocated memory block. */
+ size_t len;
+} MemHead;
+
+static unsigned int totblock = 0;
+static size_t mem_in_use = 0, mmap_in_use = 0, peak_mem = 0;
+static bool malloc_debug_memset = false;
+
+static void (*error_callback)(const char *) = NULL;
+static void (*thread_lock_callback)(void) = NULL;
+static void (*thread_unlock_callback)(void) = NULL;
+
+#define MEMHEAD_FROM_PTR(ptr) (((MemHead*) vmemh) - 1)
+#define PTR_FROM_MEMHEAD(memhead) (memhead + 1)
+
+#ifdef __GNUC__
+__attribute__ ((format(printf, 1, 2)))
+#endif
+static void print_error(const char *str, ...)
+{
+ char buf[512];
+ va_list ap;
+
+ va_start(ap, str);
+ vsnprintf(buf, sizeof(buf), str, ap);
+ va_end(ap);
+ buf[sizeof(buf) - 1] = '\0';
+
+ if (error_callback) {
+ error_callback(buf);
+ }
+}
+
+#if defined(WIN32)
+static void mem_lock_thread(void)
+{
+ if (thread_lock_callback)
+ thread_lock_callback();
+}
+
+static void mem_unlock_thread(void)
+{
+ if (thread_unlock_callback)
+ thread_unlock_callback();
+}
+#endif
+
+size_t MEM_lockfree_allocN_len(const void *vmemh)
+{
+ if (vmemh) {
+ return MEMHEAD_FROM_PTR(vmemh)->len & ~((size_t) 1);
+ }
+ else {
+ return 0;
+ }
+}
+
+void MEM_lockfree_freeN(void *vmemh)
+{
+ MemHead *memh = MEMHEAD_FROM_PTR(vmemh);
+ size_t len = MEM_lockfree_allocN_len(vmemh);
+
+ atomic_sub_u(&totblock, 1);
+ atomic_sub_z(&mem_in_use, len);
+
+ if (memh->len & (size_t) 1) {
+ atomic_sub_z(&mmap_in_use, len);
+#if defined(WIN32)
+ /* our windows mmap implementation is not thread safe */
+ mem_lock_thread();
+#endif
+ if (munmap(memh, memh->len + sizeof(MemHead)))
+ printf("Couldn't unmap memory\n");
+#if defined(WIN32)
+ mem_unlock_thread();
+#endif
+ }
+ else {
+ if (malloc_debug_memset && len) {
+ memset(memh + 1, 255, len);
+ }
+ free(memh);
+ }
+}
+
+void *MEM_lockfree_dupallocN(const void *vmemh)
+{
+ void *newp = NULL;
+ if (vmemh) {
+ const size_t prev_size = MEM_allocN_len(vmemh);
+ newp = MEM_lockfree_mallocN(prev_size, "dupli_malloc");
+ memcpy(newp, vmemh, prev_size);
+ }
+ return newp;
+}
+
+void *MEM_lockfree_reallocN_id(void *vmemh, size_t len, const char *str)
+{
+ void *newp = NULL;
+
+ if (vmemh) {
+ size_t old_len = MEM_allocN_len(vmemh);
+
+ newp = MEM_lockfree_mallocN(len, "realloc");
+ if (newp) {
+ if (len < old_len) {
+ /* shrink */
+ memcpy(newp, vmemh, len);
+ }
+ else {
+ /* grow (or remain same size) */
+ memcpy(newp, vmemh, old_len);
+ }
+ }
+
+ MEM_lockfree_freeN(vmemh);
+ }
+ else {
+ newp = MEM_lockfree_mallocN(len, str);
+ }
+
+ return newp;
+}
+
+void *MEM_lockfree_recallocN_id(void *vmemh, size_t len, const char *str)
+{
+ void *newp = NULL;
+
+ if (vmemh) {
+ size_t old_len = MEM_allocN_len(vmemh);
+
+ newp = MEM_lockfree_mallocN(len, "recalloc");
+ if (newp) {
+ if (len < old_len) {
+ /* shrink */
+ memcpy(newp, vmemh, len);
+ }
+ else {
+ memcpy(newp, vmemh, old_len);
+
+ if (len > old_len) {
+ /* grow */
+ /* zero new bytes */
+ memset(((char *)newp) + old_len, 0, len - old_len);
+ }
+ }
+ }
+
+ MEM_lockfree_freeN(vmemh);
+ }
+ else {
+ newp = MEM_lockfree_callocN(len, str);
+ }
+
+ return newp;
+}
+
+void *MEM_lockfree_callocN(size_t len, const char *str)
+{
+ MemHead *memh;
+
+ len = SIZET_ALIGN_4(len);
+
+ memh = (MemHead *)calloc(1, len + sizeof(MemHead));
+
+ if (memh) {
+ memh->len = len;
+ atomic_add_u(&totblock, 1);
+ atomic_add_z(&mem_in_use, len);
+
+ /* TODO(sergey): Not strictly speaking thread-safe. */
+ peak_mem = mem_in_use > peak_mem ? mem_in_use : peak_mem;
+
+ return PTR_FROM_MEMHEAD(memh);
+ }
+ print_error("Calloc returns null: len=" SIZET_FORMAT " in %s, total %u\n",
+ SIZET_ARG(len), str, (unsigned int) mem_in_use);
+ return NULL;
+}
+
+void *MEM_lockfree_mallocN(size_t len, const char *str)
+{
+ MemHead *memh;
+
+ len = SIZET_ALIGN_4(len);
+
+ memh = (MemHead *)malloc(len + sizeof(MemHead));
+
+ if (memh) {
+ if (malloc_debug_memset && len) {
+ memset(memh + 1, 255, len);
+ }
+
+ memh->len = len;
+ atomic_add_u(&totblock, 1);
+ atomic_add_z(&mem_in_use, len);
+
+ /* TODO(sergey): Not strictly speaking thread-safe. */
+ peak_mem = mem_in_use > peak_mem ? mem_in_use : peak_mem;
+
+ return PTR_FROM_MEMHEAD(memh);
+ }
+ print_error("Malloc returns null: len=" SIZET_FORMAT " in %s, total %u\n",
+ SIZET_ARG(len), str, (unsigned int) mem_in_use);
+ return NULL;
+}
+
+void *MEM_lockfree_mapallocN(size_t len, const char *str)
+{
+ MemHead *memh;
+
+ len = SIZET_ALIGN_4(len);
+
+#if defined(WIN32)
+ /* our windows mmap implementation is not thread safe */
+ mem_lock_thread();
+#endif
+ memh = mmap(NULL, len + sizeof(MemHead),
+ PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
+#if defined(WIN32)
+ mem_unlock_thread();
+#endif
+
+ if (memh != (MemHead *)-1) {
+ memh->len = len | (size_t) 1;
+ atomic_add_u(&totblock, 1);
+ atomic_add_z(&mem_in_use, len);
+ atomic_add_z(&mmap_in_use, len);
+
+ /* TODO(sergey): Not strictly speaking thread-safe. */
+ peak_mem = mem_in_use > peak_mem ? mem_in_use : peak_mem;
+ peak_mem = mmap_in_use > peak_mem ? mmap_in_use : peak_mem;
+
+ return PTR_FROM_MEMHEAD(memh);
+ }
+ print_error("Mapalloc returns null, fallback to regular malloc: "
+ "len=" SIZET_FORMAT " in %s, total %u\n",
+ SIZET_ARG(len), str, (unsigned int) mmap_in_use);
+ return MEM_lockfree_callocN(len, str);
+}
+
+void MEM_lockfree_printmemlist_pydict(void)
+{
+}
+
+void MEM_lockfree_printmemlist(void)
+{
+}
+
+/* unused */
+void MEM_lockfree_callbackmemlist(void (*func)(void *))
+{
+ (void) func; /* Ignored. */
+}
+
+void MEM_lockfree_printmemlist_stats(void)
+{
+ printf("\ntotal memory len: %.3f MB\n",
+ (double)mem_in_use / (double)(1024 * 1024));
+ printf("peak memory len: %.3f MB\n",
+ (double)peak_mem / (double)(1024 * 1024));
+ printf("\nFor more detailed per-block statistics run Blender with memory debugging command line argument.\n");
+
+#ifdef HAVE_MALLOC_STATS
+ printf("System Statistics:\n");
+ malloc_stats();
+#endif
+}
+
+void MEM_lockfree_set_error_callback(void (*func)(const char *))
+{
+ error_callback = func;
+}
+
+bool MEM_lockfree_check_memory_integrity(void)
+{
+ return true;
+}
+
+void MEM_lockfree_set_lock_callback(void (*lock)(void), void (*unlock)(void))
+{
+ thread_lock_callback = lock;
+ thread_unlock_callback = unlock;
+}
+
+void MEM_lockfree_set_memory_debug(void)
+{
+ malloc_debug_memset = true;
+}
+
+uintptr_t MEM_lockfree_get_memory_in_use(void)
+{
+ return mem_in_use;
+}
+
+uintptr_t MEM_lockfree_get_mapped_memory_in_use(void)
+{
+ return mmap_in_use;
+}
+
+unsigned int MEM_lockfree_get_memory_blocks_in_use(void)
+{
+ return totblock;
+}
+
+/* dummy */
+void MEM_lockfree_reset_peak_memory(void)
+{
+ peak_mem = 0;
+}
+
+uintptr_t MEM_lockfree_get_peak_memory(void)
+{
+ return peak_mem;
+}
+
+#ifndef NDEBUG
+const char *MEM_lockfree_name_ptr(void *vmemh)
+{
+ if (vmemh) {
+ return "unknown block name ptr";
+ }
+ else {
+ return "MEM_lockfree_name_ptr(NULL)";
+ }
+}
+#endif /* NDEBUG */
diff --git a/intern/guardedalloc/mmap_win.h b/intern/guardedalloc/mmap_win.h
index 0f88a8e3ba8..a1959fed9f9 100644
--- a/intern/guardedalloc/mmap_win.h
+++ b/intern/guardedalloc/mmap_win.h
@@ -51,6 +51,8 @@
/* needed for uintptr_t, exception, dont use BLI anywhere else in MEM_* */
#include "../../source/blender/blenlib/BLI_sys_types.h"
+#include <sys/types.h>
+
void *mmap(void *start, size_t len, int prot, int flags, int fd, off_t offset);
intptr_t munmap(void *ptr, size_t size);
diff --git a/intern/locale/boost_locale_wrapper.cpp b/intern/locale/boost_locale_wrapper.cpp
index 5d7ba599467..945d0bbc5da 100644
--- a/intern/locale/boost_locale_wrapper.cpp
+++ b/intern/locale/boost_locale_wrapper.cpp
@@ -109,7 +109,7 @@ const char *bl_locale_pgettext(const char *msgctxt, const char *msgid)
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)
+ if (r)
return r;
return msgid;
}
diff --git a/intern/opencolorio/CMakeLists.txt b/intern/opencolorio/CMakeLists.txt
index 30a74baa646..3a139dc64cf 100644
--- a/intern/opencolorio/CMakeLists.txt
+++ b/intern/opencolorio/CMakeLists.txt
@@ -62,6 +62,8 @@ if(WITH_OPENCOLORIO)
${BOOST_INCLUDE_DIR}
)
endif()
+
+ data_to_c_simple(gpu_shader_display_transform.glsl SRC)
endif()
diff --git a/intern/opencolorio/SConscript b/intern/opencolorio/SConscript
index 7f050f25cae..70aa9000719 100644
--- a/intern/opencolorio/SConscript
+++ b/intern/opencolorio/SConscript
@@ -39,6 +39,13 @@ if env['WITH_BF_OCIO']:
if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
incs += ' ' + env['BF_BOOST_INC']
+
+ # generated data files
+ import os
+ sources.extend((
+ os.path.join(env['DATA_SOURCES'], "gpu_shader_display_transform.glsl.c"),
+ ))
+
else:
sources.remove('ocio_impl.cc')
sources.remove('ocio_impl_glsl.cc')
diff --git a/intern/opencolorio/fallback_impl.cc b/intern/opencolorio/fallback_impl.cc
index 36dac689287..ca999eab569 100644
--- a/intern/opencolorio/fallback_impl.cc
+++ b/intern/opencolorio/fallback_impl.cc
@@ -418,7 +418,8 @@ bool FallbackImpl::supportGLSLDraw(void)
return false;
}
-bool FallbackImpl::setupGLSLDraw(struct OCIO_GLSLDrawState ** /*state_r*/, OCIO_ConstProcessorRcPtr * /*processor*/, bool /*predivide*/)
+bool FallbackImpl::setupGLSLDraw(struct OCIO_GLSLDrawState ** /*state_r*/, OCIO_ConstProcessorRcPtr * /*processor*/,
+ OCIO_CurveMappingSettings * /*curve_mapping_settings*/, bool /*predivide*/)
{
return false;
}
diff --git a/intern/opencolorio/gpu_shader_display_transform.glsl b/intern/opencolorio/gpu_shader_display_transform.glsl
new file mode 100644
index 00000000000..6ba3fa55e8f
--- /dev/null
+++ b/intern/opencolorio/gpu_shader_display_transform.glsl
@@ -0,0 +1,123 @@
+uniform sampler2D image_texture;
+uniform sampler3D lut3d_texture;
+uniform bool predivide;
+
+#ifdef USE_CURVE_MAPPING
+/* Curve mapping parameters
+ *
+ * See documentation for OCIO_CurveMappingSettings to get fields descriptions.
+ * (this ones pretyt much copies stuff from C structure.)
+ */
+uniform sampler1D curve_mapping_texture;
+uniform int curve_mapping_lut_size;
+uniform ivec4 use_curve_mapping_extend_extrapolate;
+uniform vec4 curve_mapping_mintable;
+uniform vec4 curve_mapping_range;
+uniform vec4 curve_mapping_ext_in_x;
+uniform vec4 curve_mapping_ext_in_y;
+uniform vec4 curve_mapping_ext_out_x;
+uniform vec4 curve_mapping_ext_out_y;
+uniform vec4 curve_mapping_first_x;
+uniform vec4 curve_mapping_first_y;
+uniform vec4 curve_mapping_last_x;
+uniform vec4 curve_mapping_last_y;
+uniform vec3 curve_mapping_black;
+uniform vec3 curve_mapping_bwmul;
+
+float read_curve_mapping(int table, int index)
+{
+ /* TODO(sergey): Without -1 here image is getting darken after applying unite curve.
+ * But is it actually correct to subtract 1 here?
+ */
+ float texture_index = float(index) / float(curve_mapping_lut_size - 1);
+ return texture1D(curve_mapping_texture, texture_index) [table];
+}
+
+float curvemap_calc_extend(int table, float x, vec2 first, vec2 last)
+{
+ if (x <= first[0]) {
+ if (use_curve_mapping_extend_extrapolate[table] == 0) {
+ /* no extrapolate */
+ return first[1];
+ }
+ else {
+ if (curve_mapping_ext_in_x[table] == 0.0)
+ return first[1] + curve_mapping_ext_in_y[table] * 10000.0;
+ else
+ return first[1] + curve_mapping_ext_in_y[table] * (x - first[0]) / curve_mapping_ext_in_x[table];
+ }
+ }
+ else if (x >= last[0]) {
+ if (use_curve_mapping_extend_extrapolate[table] == 0) {
+ /* no extrapolate */
+ return last[1];
+ }
+ else {
+ if (curve_mapping_ext_out_x[table] == 0.0)
+ return last[1] - curve_mapping_ext_out_y[table] * 10000.0;
+ else
+ return last[1] + curve_mapping_ext_out_y[table] * (x - last[0]) / curve_mapping_ext_out_x[table];
+ }
+ }
+ return 0.0;
+}
+
+float curvemap_evaluateF(int table, float value)
+{
+ float mintable_ = curve_mapping_mintable[table];
+ float range = curve_mapping_range[table];
+ float mintable = 0.0;
+ int CM_TABLE = curve_mapping_lut_size - 1;
+
+ float fi;
+ int i;
+
+ /* index in table */
+ fi = (value - mintable) * range;
+ i = int(fi);
+
+ /* fi is table float index and should check against table range i.e. [0.0 CM_TABLE] */
+ if (fi < 0.0 || fi > float(CM_TABLE)) {
+ return curvemap_calc_extend(table, value,
+ vec2(curve_mapping_first_x[table], curve_mapping_first_y[table]),
+ vec2(curve_mapping_last_x[table], curve_mapping_last_y[table]));
+ }
+ else {
+ if (i < 0) return read_curve_mapping(table, 0);
+ if (i >= CM_TABLE) return read_curve_mapping(table, CM_TABLE);
+
+ fi = fi - float(i);
+ return (1.0 - fi) * read_curve_mapping(table, i) + fi * read_curve_mapping(table, i + 1);
+ }
+}
+
+vec4 curvemapping_evaluate_premulRGBF(vec4 col)
+{
+ vec4 result = col;
+ result[0] = curvemap_evaluateF(0, (col[0] - curve_mapping_black[0]) * curve_mapping_bwmul[0]);
+ result[1] = curvemap_evaluateF(1, (col[1] - curve_mapping_black[1]) * curve_mapping_bwmul[1]);
+ result[2] = curvemap_evaluateF(2, (col[2] - curve_mapping_black[2]) * curve_mapping_bwmul[2]);
+ result[3] = col[3];
+ return result;
+}
+#endif
+
+void main()
+{
+ vec4 col = texture2D(image_texture, gl_TexCoord[0].st);
+#ifdef USE_CURVE_MAPPING
+ col = curvemapping_evaluate_premulRGBF(col);
+#endif
+ if (predivide && col[3] > 0.0 && col[3] < 1.0) {
+ float inv_alpha = 1.0 / col[3];
+ col[0] *= inv_alpha;
+ col[1] *= inv_alpha;
+ col[2] *= inv_alpha;
+ }
+
+ /* NOTE: This is true we only do de-premul here and NO premul
+ * and the reason is simple -- opengl is always configured
+ * for straight alpha at this moment
+ */
+ gl_FragColor = OCIODisplay(col, lut3d_texture);
+}
diff --git a/intern/opencolorio/ocio_capi.cc b/intern/opencolorio/ocio_capi.cc
index 1656ad9cbc0..30668dff245 100644
--- a/intern/opencolorio/ocio_capi.cc
+++ b/intern/opencolorio/ocio_capi.cc
@@ -323,9 +323,10 @@ int OCIO_supportGLSLDraw(void)
return (int) impl->supportGLSLDraw();
}
-int OCIO_setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor, int predivide)
+int OCIO_setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor,
+ OCIO_CurveMappingSettings *curve_mapping_settings, bool predivide)
{
- return (int) impl->setupGLSLDraw(state_r, processor, (bool) predivide);
+ return (int) impl->setupGLSLDraw(state_r, processor, curve_mapping_settings, predivide);
}
void OCIO_finishGLSLDraw(struct OCIO_GLSLDrawState *state)
diff --git a/intern/opencolorio/ocio_capi.h b/intern/opencolorio/ocio_capi.h
index 0846b8ff7b3..5532ade1f3a 100644
--- a/intern/opencolorio/ocio_capi.h
+++ b/intern/opencolorio/ocio_capi.h
@@ -54,6 +54,62 @@ OCIO_DECLARE_HANDLE(OCIO_ExponentTransformRcPtr);
OCIO_DECLARE_HANDLE(OCIO_MatrixTransformRcPtr);
OCIO_DECLARE_HANDLE(OCIO_ConstLookRcPtr);
+/* This structure is used to pass curve mapping settings from
+ * blender's DNA structure stored in view transform settings
+ * to a generic OpenColorIO C-API.
+ */
+typedef struct OCIO_CurveMappingSettings {
+ /* This is a LUT which contain values for all 4 curve mapping tables
+ * (combined, R, G and B).
+ *
+ * Element I for table T is stored at I * 4 + T element of this LUT.
+ *
+ * This array is usually returned by curvemapping_table_RGBA().
+ */
+ float *lut;
+
+ /* Size of single curve mapping table, 1/4 size of lut array. */
+ int lut_size;
+
+ /* Extend extrapolation flags for all the tables.
+ * if use_extend_extrapolate[T] != 0 means extrapolation for
+ * table T is needed.
+ */
+ int use_extend_extrapolate[4];
+
+ /* Minimal X value of the curve mapping tables. */
+ float mintable[4];
+
+ /* Per curve mapping table range. */
+ float range[4];
+
+ /* Lower extension value, stored as per-component arrays. */
+ float ext_in_x[4], ext_in_y[4];
+
+ /* Higher extension value, stored as per-component arrays. */
+ float ext_out_x[4], ext_out_y[4];
+
+ /* First points of the tables, both X and Y values.
+ * Needed for easier and faster access when extrapolating.
+ */
+ float first_x[4], first_y[4];
+
+ /* Last points of the tables, both X and Y values.
+ * Needed for easier and faster access when extrapolating.
+ */
+ float last_x[4], last_y[4];
+
+ /* Premultiplication settings: black level and scale to match
+ * with white level.
+ */
+ float black[3], bwmul[3];
+
+ /* Cache id of the original curve mapping, used to detect when
+ * upload of new settings to GPU is needed.
+ */
+ size_t cache_id;
+} OCIO_CurveMappingSettings;
+
void OCIO_init(void);
void OCIO_exit(void);
@@ -132,7 +188,8 @@ void OCIO_matrixTransformRelease(OCIO_MatrixTransformRcPtr *mt);
void OCIO_matrixTransformScale(float *m44, float *offset4, const float *scale4);
int OCIO_supportGLSLDraw(void);
-int OCIO_setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor, int predivide);
+int OCIO_setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor,
+ OCIO_CurveMappingSettings *curve_mapping_settings, bool predivide);
void OCIO_finishGLSLDraw(struct OCIO_GLSLDrawState *state);
void OCIO_freeOGLState(struct OCIO_GLSLDrawState *state);
diff --git a/intern/opencolorio/ocio_impl.cc b/intern/opencolorio/ocio_impl.cc
index dff25f238a7..2cffe1a89ef 100644
--- a/intern/opencolorio/ocio_impl.cc
+++ b/intern/opencolorio/ocio_impl.cc
@@ -55,9 +55,6 @@ using namespace OCIO_NAMESPACE;
# define __func__ __FUNCTION__
#endif
-#define MEM_NEW(type) new(MEM_mallocN(sizeof(type), __func__)) type()
-#define MEM_DELETE(what, type) if (what) { ((type*)(what))->~type(); MEM_freeN(what); } (void)0
-
static void OCIO_reportError(const char *err)
{
std::cerr << "OpenColorIO Error: " << err << std::endl;
@@ -72,7 +69,7 @@ static void OCIO_reportException(Exception &exception)
OCIO_ConstConfigRcPtr *OCIOImpl::getCurrentConfig(void)
{
- ConstConfigRcPtr *config = MEM_NEW(ConstConfigRcPtr);
+ ConstConfigRcPtr *config = OBJECT_GUARDED_NEW(ConstConfigRcPtr);
try {
*config = GetCurrentConfig();
@@ -84,7 +81,7 @@ OCIO_ConstConfigRcPtr *OCIOImpl::getCurrentConfig(void)
OCIO_reportException(exception);
}
- MEM_DELETE(config, ConstConfigRcPtr);
+ OBJECT_GUARDED_DELETE(config, ConstConfigRcPtr);
return NULL;
}
@@ -101,7 +98,7 @@ void OCIOImpl::setCurrentConfig(const OCIO_ConstConfigRcPtr *config)
OCIO_ConstConfigRcPtr *OCIOImpl::configCreateFromEnv(void)
{
- ConstConfigRcPtr *config = MEM_NEW(ConstConfigRcPtr);
+ ConstConfigRcPtr *config = OBJECT_GUARDED_NEW(ConstConfigRcPtr);
try {
*config = Config::CreateFromEnv();
@@ -113,7 +110,7 @@ OCIO_ConstConfigRcPtr *OCIOImpl::configCreateFromEnv(void)
OCIO_reportException(exception);
}
- MEM_DELETE(config, ConstConfigRcPtr);
+ OBJECT_GUARDED_DELETE(config, ConstConfigRcPtr);
return NULL;
}
@@ -121,7 +118,7 @@ OCIO_ConstConfigRcPtr *OCIOImpl::configCreateFromEnv(void)
OCIO_ConstConfigRcPtr *OCIOImpl::configCreateFromFile(const char *filename)
{
- ConstConfigRcPtr *config = MEM_NEW(ConstConfigRcPtr);
+ ConstConfigRcPtr *config = OBJECT_GUARDED_NEW(ConstConfigRcPtr);
try {
*config = Config::CreateFromFile(filename);
@@ -133,14 +130,14 @@ OCIO_ConstConfigRcPtr *OCIOImpl::configCreateFromFile(const char *filename)
OCIO_reportException(exception);
}
- MEM_DELETE(config, ConstConfigRcPtr);
+ OBJECT_GUARDED_DELETE(config, ConstConfigRcPtr);
return NULL;
}
void OCIOImpl::configRelease(OCIO_ConstConfigRcPtr *config)
{
- MEM_DELETE((ConstConfigRcPtr *) config, ConstConfigRcPtr);
+ OBJECT_GUARDED_DELETE((ConstConfigRcPtr *) config, ConstConfigRcPtr);
}
int OCIOImpl::configGetNumColorSpaces(OCIO_ConstConfigRcPtr *config)
@@ -169,7 +166,7 @@ const char *OCIOImpl::configGetColorSpaceNameByIndex(OCIO_ConstConfigRcPtr *conf
OCIO_ConstColorSpaceRcPtr *OCIOImpl::configGetColorSpace(OCIO_ConstConfigRcPtr *config, const char *name)
{
- ConstColorSpaceRcPtr *cs = MEM_NEW(ConstColorSpaceRcPtr);
+ ConstColorSpaceRcPtr *cs = OBJECT_GUARDED_NEW(ConstColorSpaceRcPtr);
try {
*cs = (*(ConstConfigRcPtr *) config)->getColorSpace(name);
@@ -181,7 +178,7 @@ OCIO_ConstColorSpaceRcPtr *OCIOImpl::configGetColorSpace(OCIO_ConstConfigRcPtr *
OCIO_reportException(exception);
}
- MEM_DELETE(cs, ConstColorSpaceRcPtr);
+ OBJECT_GUARDED_DELETE(cs, ConstColorSpaceRcPtr);
return NULL;
}
@@ -308,7 +305,7 @@ const char *OCIOImpl::configGetLookNameByIndex(OCIO_ConstConfigRcPtr *config, in
OCIO_ConstLookRcPtr *OCIOImpl::configGetLook(OCIO_ConstConfigRcPtr *config, const char *name)
{
- ConstLookRcPtr *look = MEM_NEW(ConstLookRcPtr);
+ ConstLookRcPtr *look = OBJECT_GUARDED_NEW(ConstLookRcPtr);
try {
*look = (*(ConstConfigRcPtr *) config)->getLook(name);
@@ -320,7 +317,7 @@ OCIO_ConstLookRcPtr *OCIOImpl::configGetLook(OCIO_ConstConfigRcPtr *config, cons
OCIO_reportException(exception);
}
- MEM_DELETE(look, ConstLookRcPtr);
+ OBJECT_GUARDED_DELETE(look, ConstLookRcPtr);
return NULL;
}
@@ -332,7 +329,7 @@ const char *OCIOImpl::lookGetProcessSpace(OCIO_ConstLookRcPtr *look)
void OCIOImpl::lookRelease(OCIO_ConstLookRcPtr *look)
{
- MEM_DELETE((ConstLookRcPtr *) look, ConstLookRcPtr);
+ OBJECT_GUARDED_DELETE((ConstLookRcPtr *) look, ConstLookRcPtr);
}
int OCIOImpl::colorSpaceIsInvertible(OCIO_ConstColorSpaceRcPtr *cs_)
@@ -367,12 +364,12 @@ int OCIOImpl::colorSpaceIsData(OCIO_ConstColorSpaceRcPtr *cs)
void OCIOImpl::colorSpaceRelease(OCIO_ConstColorSpaceRcPtr *cs)
{
- MEM_DELETE((ConstColorSpaceRcPtr *) cs, ConstColorSpaceRcPtr);
+ OBJECT_GUARDED_DELETE((ConstColorSpaceRcPtr *) cs, ConstColorSpaceRcPtr);
}
OCIO_ConstProcessorRcPtr *OCIOImpl::configGetProcessorWithNames(OCIO_ConstConfigRcPtr *config, const char *srcName, const char *dstName)
{
- ConstProcessorRcPtr *p = MEM_NEW(ConstProcessorRcPtr);
+ ConstProcessorRcPtr *p = OBJECT_GUARDED_NEW(ConstProcessorRcPtr);
try {
*p = (*(ConstConfigRcPtr *) config)->getProcessor(srcName, dstName);
@@ -384,14 +381,14 @@ OCIO_ConstProcessorRcPtr *OCIOImpl::configGetProcessorWithNames(OCIO_ConstConfig
OCIO_reportException(exception);
}
- MEM_DELETE(p, ConstProcessorRcPtr);
+ OBJECT_GUARDED_DELETE(p, ConstProcessorRcPtr);
return 0;
}
OCIO_ConstProcessorRcPtr *OCIOImpl::configGetProcessor(OCIO_ConstConfigRcPtr *config, OCIO_ConstTransformRcPtr *transform)
{
- ConstProcessorRcPtr *p = MEM_NEW(ConstProcessorRcPtr);
+ ConstProcessorRcPtr *p = OBJECT_GUARDED_NEW(ConstProcessorRcPtr);
try {
*p = (*(ConstConfigRcPtr *) config)->getProcessor(*(ConstTransformRcPtr *) transform);
@@ -403,7 +400,7 @@ OCIO_ConstProcessorRcPtr *OCIOImpl::configGetProcessor(OCIO_ConstConfigRcPtr *co
OCIO_reportException(exception);
}
- MEM_DELETE(p, ConstProcessorRcPtr);
+ OBJECT_GUARDED_DELETE(p, ConstProcessorRcPtr);
return NULL;
}
@@ -482,7 +479,7 @@ void OCIOImpl::processorApplyRGBA_predivide(OCIO_ConstProcessorRcPtr *processor,
void OCIOImpl::processorRelease(OCIO_ConstProcessorRcPtr *p)
{
- MEM_DELETE(p, ConstProcessorRcPtr);
+ OBJECT_GUARDED_DELETE(p, ConstProcessorRcPtr);
}
const char *OCIOImpl::colorSpaceGetName(OCIO_ConstColorSpaceRcPtr *cs)
@@ -502,7 +499,7 @@ const char *OCIOImpl::colorSpaceGetFamily(OCIO_ConstColorSpaceRcPtr *cs)
OCIO_DisplayTransformRcPtr *OCIOImpl::createDisplayTransform(void)
{
- DisplayTransformRcPtr *dt = MEM_NEW(DisplayTransformRcPtr);
+ DisplayTransformRcPtr *dt = OBJECT_GUARDED_NEW(DisplayTransformRcPtr);
*dt = DisplayTransform::Create();
@@ -546,7 +543,7 @@ void OCIOImpl::displayTransformSetLooksOverrideEnabled(OCIO_DisplayTransformRcPt
void OCIOImpl::displayTransformRelease(OCIO_DisplayTransformRcPtr *dt)
{
- MEM_DELETE((DisplayTransformRcPtr *) dt, DisplayTransformRcPtr);
+ OBJECT_GUARDED_DELETE((DisplayTransformRcPtr *) dt, DisplayTransformRcPtr);
}
OCIO_PackedImageDesc *OCIOImpl::createOCIO_PackedImageDesc(float *data, long width, long height, long numChannels,
@@ -567,12 +564,12 @@ OCIO_PackedImageDesc *OCIOImpl::createOCIO_PackedImageDesc(float *data, long wid
void OCIOImpl::OCIO_PackedImageDescRelease(OCIO_PackedImageDesc* id)
{
- MEM_DELETE((PackedImageDesc *) id, PackedImageDesc);
+ OBJECT_GUARDED_DELETE((PackedImageDesc *) id, PackedImageDesc);
}
OCIO_ExponentTransformRcPtr *OCIOImpl::createExponentTransform(void)
{
- ExponentTransformRcPtr *et = MEM_NEW(ExponentTransformRcPtr);
+ ExponentTransformRcPtr *et = OBJECT_GUARDED_NEW(ExponentTransformRcPtr);
*et = ExponentTransform::Create();
@@ -586,12 +583,12 @@ void OCIOImpl::exponentTransformSetValue(OCIO_ExponentTransformRcPtr *et, const
void OCIOImpl::exponentTransformRelease(OCIO_ExponentTransformRcPtr *et)
{
- MEM_DELETE((ExponentTransformRcPtr *) et, ExponentTransformRcPtr);
+ OBJECT_GUARDED_DELETE((ExponentTransformRcPtr *) et, ExponentTransformRcPtr);
}
OCIO_MatrixTransformRcPtr *OCIOImpl::createMatrixTransform(void)
{
- MatrixTransformRcPtr *mt = MEM_NEW(MatrixTransformRcPtr);
+ MatrixTransformRcPtr *mt = OBJECT_GUARDED_NEW(MatrixTransformRcPtr);
*mt = MatrixTransform::Create();
@@ -605,7 +602,7 @@ void OCIOImpl::matrixTransformSetValue(OCIO_MatrixTransformRcPtr *mt, const floa
void OCIOImpl::matrixTransformRelease(OCIO_MatrixTransformRcPtr *mt)
{
- MEM_DELETE((MatrixTransformRcPtr *) mt, MatrixTransformRcPtr);
+ OBJECT_GUARDED_DELETE((MatrixTransformRcPtr *) mt, MatrixTransformRcPtr);
}
void OCIOImpl::matrixTransformScale(float *m44, float *offset4, const float *scale4f)
diff --git a/intern/opencolorio/ocio_impl.h b/intern/opencolorio/ocio_impl.h
index 48d18fa78ea..8b666e8ae14 100644
--- a/intern/opencolorio/ocio_impl.h
+++ b/intern/opencolorio/ocio_impl.h
@@ -106,7 +106,8 @@ public:
virtual void matrixTransformScale(float * m44, float * offset4, const float * scale4) = 0;
virtual bool supportGLSLDraw(void) = 0;
- virtual bool setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor, bool predivide) = 0;
+ virtual bool setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor,
+ OCIO_CurveMappingSettings *curve_mapping_settings, bool predivide) = 0;
virtual void finishGLSLDraw(struct OCIO_GLSLDrawState *state) = 0;
virtual void freeGLState(struct OCIO_GLSLDrawState *state_r) = 0;
};
@@ -189,7 +190,8 @@ public:
void matrixTransformScale(float *m44, float *offset4, const float *scale4);
bool supportGLSLDraw(void);
- bool setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor, bool predivide);
+ bool setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor,
+ OCIO_CurveMappingSettings *curve_mapping_settings, bool predivide);
void finishGLSLDraw(struct OCIO_GLSLDrawState *state);
void freeGLState(struct OCIO_GLSLDrawState *state_r);
};
@@ -273,7 +275,8 @@ public:
void matrixTransformScale(float * m44, float * offset4, const float * scale4);
bool supportGLSLDraw(void);
- bool setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor, bool predivide);
+ bool setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor,
+ OCIO_CurveMappingSettings *curve_mapping_settings, bool predivide);
void finishGLSLDraw(struct OCIO_GLSLDrawState *state);
void freeGLState(struct OCIO_GLSLDrawState *state_r);
};
diff --git a/intern/opencolorio/ocio_impl_glsl.cc b/intern/opencolorio/ocio_impl_glsl.cc
index 1a3132fa4b3..2af3befc8a9 100644
--- a/intern/opencolorio/ocio_impl_glsl.cc
+++ b/intern/opencolorio/ocio_impl_glsl.cc
@@ -48,6 +48,8 @@ using namespace OCIO_NAMESPACE;
static const int LUT3D_EDGE_SIZE = 64;
+extern "C" char datatoc_gpu_shader_display_transform_glsl[];
+
/* **** OpenGL drawing routines using GLSL for color space transform ***** */
typedef struct OCIO_GLSLDrawState {
@@ -60,42 +62,24 @@ typedef struct OCIO_GLSLDrawState {
float *lut3d; /* 3D LUT table */
+ bool curve_mapping_used;
+ bool curve_mapping_texture_allocated;
+ bool curve_mapping_texture_valid;
+ GLuint curve_mapping_texture;
+ size_t curve_mapping_cache_id;
+
/* Cache */
std::string lut3dcacheid;
std::string shadercacheid;
/* GLSL stuff */
- GLuint fragShader;
+ GLuint ocio_shader;
GLuint program;
/* Previous OpenGL state. */
GLint last_texture, last_texture_unit;
} OCIO_GLSLDrawState;
-/* Hardcoded to do alpha predivide before color space conversion */
-/* NOTE: This is true we only do de-premul here and NO premul
- * and the reason is simple -- opengl is always configured
- * for straight alpha at this moment
- */
-static const char *g_fragShaderText = ""
-"\n"
-"uniform sampler2D tex1;\n"
-"uniform sampler3D tex2;\n"
-"uniform bool predivide;\n"
-"\n"
-"void main()\n"
-"{\n"
-" vec4 col = texture2D(tex1, gl_TexCoord[0].st);\n"
-" if (predivide && col[3] > 0.0 && col[3] < 1.0) {\n"
-" float inv_alpha = 1.0 / col[3];\n"
-" col[0] *= inv_alpha;\n"
-" col[1] *= inv_alpha;\n"
-" col[2] *= inv_alpha;\n"
-" }\n"
-" gl_FragColor = OCIODisplay(col, tex2);\n"
-"\n"
-"}\n";
-
static GLuint compileShaderText(GLenum shaderType, const char *text)
{
GLuint shader;
@@ -117,15 +101,14 @@ static GLuint compileShaderText(GLenum shaderType, const char *text)
return shader;
}
-static GLuint linkShaders(GLuint fragShader)
+static GLuint linkShaders(GLuint ocio_shader)
{
- if (!fragShader)
+ if (!ocio_shader)
return 0;
GLuint program = glCreateProgram();
- if (fragShader)
- glAttachShader(program, fragShader);
+ glAttachShader(program, ocio_shader);
glLinkProgram(program);
@@ -197,6 +180,37 @@ static bool ensureLUT3DAllocated(OCIO_GLSLDrawState *state)
return state->lut3d_texture_valid;
}
+static bool ensureCurveMappingAllocated(OCIO_GLSLDrawState *state, OCIO_CurveMappingSettings *curve_mapping_settings)
+{
+ if (state->curve_mapping_texture_allocated)
+ return state->curve_mapping_texture_valid;
+
+ glGenTextures(1, &state->curve_mapping_texture);
+
+ glActiveTexture(GL_TEXTURE2);
+ glBindTexture(GL_TEXTURE_1D, state->curve_mapping_texture);
+ glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
+
+ /* clean glError buffer */
+ while (glGetError() != GL_NO_ERROR) {}
+
+ glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA16F_ARB, curve_mapping_settings->lut_size,
+ 0, GL_RGBA, GL_FLOAT, curve_mapping_settings->lut);
+
+ state->curve_mapping_texture_allocated = true;
+
+ /* GL_RGB16F_ARB could be not supported at some drivers
+ * in this case we could not use GLSL display
+ */
+ state->curve_mapping_texture_valid = glGetError() == GL_NO_ERROR;
+
+ return state->curve_mapping_texture_valid;
+}
+
/* Detect if we can support GLSL drawing */
bool OCIOImpl::supportGLSLDraw()
{
@@ -214,9 +228,11 @@ bool OCIOImpl::supportGLSLDraw()
* When all drawing is finished, finishGLSLDraw shall be called to
* restore OpenGL context to it's pre-GLSL draw state.
*/
-bool OCIOImpl::setupGLSLDraw(OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor, bool predivide)
+bool OCIOImpl::setupGLSLDraw(OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor,
+ OCIO_CurveMappingSettings *curve_mapping_settings, bool predivide)
{
ConstProcessorRcPtr ocio_processor = *(ConstProcessorRcPtr *) processor;
+ bool use_curve_mapping = curve_mapping_settings != NULL;
/* Create state if needed. */
OCIO_GLSLDrawState *state;
@@ -234,12 +250,36 @@ bool OCIOImpl::setupGLSLDraw(OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRc
return false;
}
+ if (use_curve_mapping) {
+ if (!ensureCurveMappingAllocated(state, curve_mapping_settings)) {
+ glActiveTexture(state->last_texture_unit);
+ glBindTexture(GL_TEXTURE_2D, state->last_texture);
+
+ return false;
+ }
+ }
+ else {
+ if (state->curve_mapping_texture_allocated) {
+ glDeleteTextures(1, &state->curve_mapping_texture);
+ state->curve_mapping_texture_allocated = false;
+ }
+ }
+
/* Step 1: Create a GPU Shader Description */
GpuShaderDesc shaderDesc;
shaderDesc.setLanguage(GPU_LANGUAGE_GLSL_1_0);
shaderDesc.setFunctionName("OCIODisplay");
shaderDesc.setLut3DEdgeLen(LUT3D_EDGE_SIZE);
+ if (use_curve_mapping) {
+ if (state->curve_mapping_cache_id != curve_mapping_settings->cache_id) {
+ glActiveTexture(GL_TEXTURE2);
+ glBindTexture(GL_TEXTURE_1D, state->curve_mapping_texture);
+ glTexSubImage1D(GL_TEXTURE_1D, 0, 0, curve_mapping_settings->lut_size,
+ GL_RGBA, GL_FLOAT, curve_mapping_settings->lut);
+ }
+ }
+
/* Step 2: Compute the 3D LUT */
std::string lut3dCacheID = ocio_processor->getGpuLut3DCacheID(shaderDesc);
if (lut3dCacheID != state->lut3dcacheid) {
@@ -255,37 +295,73 @@ bool OCIOImpl::setupGLSLDraw(OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRc
/* Step 3: Compute the Shader */
std::string shaderCacheID = ocio_processor->getGpuShaderTextCacheID(shaderDesc);
- if (state->program == 0 || shaderCacheID != state->shadercacheid) {
+ if (state->program == 0 ||
+ shaderCacheID != state->shadercacheid ||
+ use_curve_mapping != state->curve_mapping_used)
+ {
state->shadercacheid = shaderCacheID;
+ if (state->program) {
+ glDeleteProgram(state->program);
+ }
+
+ if (state->ocio_shader) {
+ glDeleteShader(state->ocio_shader);
+ }
+
std::ostringstream os;
- os << ocio_processor->getGpuShaderText(shaderDesc) << "\n";
- os << g_fragShaderText;
- if (state->fragShader)
- glDeleteShader(state->fragShader);
+ if (use_curve_mapping) {
+ os << "#define USE_CURVE_MAPPING\n";
+ }
- state->fragShader = compileShaderText(GL_FRAGMENT_SHADER, os.str().c_str());
+ os << ocio_processor->getGpuShaderText(shaderDesc) << "\n";
+ os << datatoc_gpu_shader_display_transform_glsl;
- if (state->fragShader) {
- if (state->program)
- glDeleteProgram(state->program);
+ state->ocio_shader = compileShaderText(GL_FRAGMENT_SHADER, os.str().c_str());
- state->program = linkShaders(state->fragShader);
+ if (state->ocio_shader) {
+ state->program = linkShaders(state->ocio_shader);
}
+
+ state->curve_mapping_used = use_curve_mapping;
}
if (state->program) {
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_3D, state->lut3d_texture);
+ if (use_curve_mapping) {
+ glActiveTexture(GL_TEXTURE2);
+ glBindTexture(GL_TEXTURE_1D, state->curve_mapping_texture);
+ }
+
glActiveTexture(GL_TEXTURE0);
glUseProgram(state->program);
- glUniform1i(glGetUniformLocation(state->program, "tex1"), 0);
- glUniform1i(glGetUniformLocation(state->program, "tex2"), 1);
+
+ glUniform1i(glGetUniformLocation(state->program, "image_texture"), 0);
+ glUniform1i(glGetUniformLocation(state->program, "lut3d_texture"), 1);
glUniform1i(glGetUniformLocation(state->program, "predivide"), predivide);
+ if (use_curve_mapping) {
+ glUniform1i(glGetUniformLocation(state->program, "curve_mapping_texture"), 2);
+ glUniform1i(glGetUniformLocation(state->program, "curve_mapping_lut_size"), curve_mapping_settings->lut_size);
+ glUniform4iv(glGetUniformLocation(state->program, "use_curve_mapping_extend_extrapolate"), 1, curve_mapping_settings->use_extend_extrapolate);
+ glUniform4fv(glGetUniformLocation(state->program, "curve_mapping_mintable"), 1, curve_mapping_settings->mintable);
+ glUniform4fv(glGetUniformLocation(state->program, "curve_mapping_range"), 1, curve_mapping_settings->range);
+ glUniform4fv(glGetUniformLocation(state->program, "curve_mapping_ext_in_x"), 1, curve_mapping_settings->ext_in_x);
+ glUniform4fv(glGetUniformLocation(state->program, "curve_mapping_ext_in_y"), 1, curve_mapping_settings->ext_in_y);
+ glUniform4fv(glGetUniformLocation(state->program, "curve_mapping_ext_out_x"), 1, curve_mapping_settings->ext_out_x);
+ glUniform4fv(glGetUniformLocation(state->program, "curve_mapping_ext_out_y"), 1, curve_mapping_settings->ext_out_y);
+ glUniform4fv(glGetUniformLocation(state->program, "curve_mapping_first_x"), 1, curve_mapping_settings->first_x);
+ glUniform4fv(glGetUniformLocation(state->program, "curve_mapping_first_y"), 1, curve_mapping_settings->first_y);
+ glUniform4fv(glGetUniformLocation(state->program, "curve_mapping_last_x"), 1, curve_mapping_settings->last_x);
+ glUniform4fv(glGetUniformLocation(state->program, "curve_mapping_last_y"), 1, curve_mapping_settings->last_y);
+ glUniform3fv(glGetUniformLocation(state->program, "curve_mapping_black"), 1, curve_mapping_settings->black);
+ glUniform3fv(glGetUniformLocation(state->program, "curve_mapping_bwmul"), 1, curve_mapping_settings->bwmul);
+ }
+
return true;
}
else {
@@ -316,8 +392,8 @@ void OCIOImpl::freeGLState(struct OCIO_GLSLDrawState *state)
if (state->program)
glDeleteProgram(state->program);
- if (state->fragShader)
- glDeleteShader(state->fragShader);
+ if (state->ocio_shader)
+ glDeleteShader(state->ocio_shader);
state->lut3dcacheid.~string();
state->shadercacheid.~string();
diff --git a/intern/utfconv/utf_winfunc.c b/intern/utfconv/utf_winfunc.c
index 2ae261b44a8..19917571b5e 100644
--- a/intern/utfconv/utf_winfunc.c
+++ b/intern/utfconv/utf_winfunc.c
@@ -166,12 +166,23 @@ int uputenv(const char *name, const char *value)
{
int r = -1;
UTF16_ENCODE(name);
- UTF16_ENCODE(value);
- if (name_16 && value_16) {
- r = (SetEnvironmentVariableW(name_16,value_16)!= 0) ? 0 : -1;
+ if (value) {
+ /* set */
+ UTF16_ENCODE(value);
+
+ if (name_16 && value_16) {
+ r = (SetEnvironmentVariableW(name_16,value_16)!= 0) ? 0 : -1;
+ }
+ UTF16_UN_ENCODE(value);
}
- UTF16_UN_ENCODE(value);
+ else {
+ /* clear */
+ if (name_16) {
+ r = (SetEnvironmentVariableW(name_16,NULL)!= 0) ? 0 : -1;
+ }
+ }
+
UTF16_UN_ENCODE(name);
return r;
diff --git a/release/datafiles/splash.png b/release/datafiles/splash.png
index 9551fad2fac..4ee82bcbb62 100644
--- a/release/datafiles/splash.png
+++ b/release/datafiles/splash.png
Binary files differ
diff --git a/release/scripts/freestyle/style_modules/ChainingIterators.py b/release/scripts/freestyle/style_modules/ChainingIterators.py
index b908fad0b89..9be5a0ef03f 100644
--- a/release/scripts/freestyle/style_modules/ChainingIterators.py
+++ b/release/scripts/freestyle/style_modules/ChainingIterators.py
@@ -280,7 +280,7 @@ class pyFillOcclusionsRelativeChainingIterator(ChainingIterator):
def traverse(self, iter):
winner = None
winnerOrientation = 0
- print(self.current_edge.id.first, self.current_edge.id.second)
+ #print(self.current_edge.id.first, self.current_edge.id.second)
it = AdjacencyIterator(iter)
tvertex = self.next_vertex
if type(tvertex) is TVertex:
@@ -450,7 +450,7 @@ class pyFillOcclusionsAbsoluteAndRelativeChainingIterator(ChainingIterator):
def traverse(self, iter):
winner = None
winnerOrientation = 0
- print(self.current_edge.id.first, self.current_edge.id.second)
+ #print(self.current_edge.id.first, self.current_edge.id.second)
it = AdjacencyIterator(iter)
tvertex = self.next_vertex
if type(tvertex) is TVertex:
@@ -553,7 +553,7 @@ class pyFillQi0AbsoluteAndRelativeChainingIterator(ChainingIterator):
def traverse(self, iter):
winner = None
winnerOrientation = 0
- print(self.current_edge.id.first, self.current_edge.id.second)
+ #print(self.current_edge.id.first, self.current_edge.id.second)
it = AdjacencyIterator(iter)
tvertex = self.next_vertex
if type(tvertex) is TVertex:
diff --git a/release/scripts/freestyle/style_modules/PredicatesB1D.py b/release/scripts/freestyle/style_modules/PredicatesB1D.py
index 21bba923a2a..604692a999f 100644
--- a/release/scripts/freestyle/style_modules/PredicatesB1D.py
+++ b/release/scripts/freestyle/style_modules/PredicatesB1D.py
@@ -60,7 +60,7 @@ class pyViewMapGradientNormBP1D(BinaryPredicate1D):
BinaryPredicate1D.__init__(self)
self._GetGradient = pyViewMapGradientNormF1D(l, IntegrationType.MEAN)
def __call__(self, i1,i2):
- print("compare gradient")
+ #print("compare gradient")
return (self._GetGradient(i1) > self._GetGradient(i2))
class pyShuffleBP1D(BinaryPredicate1D):
diff --git a/release/scripts/freestyle/style_modules/PredicatesU1D.py b/release/scripts/freestyle/style_modules/PredicatesU1D.py
index 30472dc34b0..54f920d0563 100644
--- a/release/scripts/freestyle/style_modules/PredicatesU1D.py
+++ b/release/scripts/freestyle/style_modules/PredicatesU1D.py
@@ -92,7 +92,7 @@ class pyLowSteerableViewMapDensityUP1D(UnaryPredicate1D):
def __call__(self, inter):
func = GetSteerableViewMapDensityF1D(self._level, self._integration)
v = func(inter)
- print(v)
+ #print(v)
if v < self._threshold:
return 1
return 0
@@ -202,23 +202,23 @@ class pyIsOccludedByUP1D(UnaryPredicate1D):
vlast = itlast.object
tvertex = v.viewvertex
if type(tvertex) is TVertex:
- print("TVertex: [ ", tvertex.id.first, ",", tvertex.id.second," ]")
+ #print("TVertex: [ ", tvertex.id.first, ",", tvertex.id.second," ]")
eit = tvertex.edges_begin()
while not eit.is_end:
ve, incoming = eit.object
if ve.id == self._id:
return 1
- print("-------", ve.id.first, "-", ve.id.second)
+ #print("-------", ve.id.first, "-", ve.id.second)
eit.increment()
tvertex = vlast.viewvertex
if type(tvertex) is TVertex:
- print("TVertex: [ ", tvertex.id.first, ",", tvertex.id.second," ]")
+ #print("TVertex: [ ", tvertex.id.first, ",", tvertex.id.second," ]")
eit = tvertex.edges_begin()
while not eit.is_end:
ve, incoming = eit.object
if ve.id == self._id:
return 1
- print("-------", ve.id.first, "-", ve.id.second)
+ #print("-------", ve.id.first, "-", ve.id.second)
eit.increment()
return 0
@@ -335,8 +335,8 @@ class pyClosedCurveUP1D(UnaryPredicate1D):
itlast.decrement()
vlast = itlast.object
v = it.object
- print(v.id.first, v.id.second)
- print(vlast.id.first, vlast.id.second)
+ #print(v.id.first, v.id.second)
+ #print(vlast.id.first, vlast.id.second)
if v.id == vlast.id:
return 1
return 0
diff --git a/release/scripts/freestyle/style_modules/parameter_editor.py b/release/scripts/freestyle/style_modules/parameter_editor.py
index 371019ebe18..dd6206fff99 100644
--- a/release/scripts/freestyle/style_modules/parameter_editor.py
+++ b/release/scripts/freestyle/style_modules/parameter_editor.py
@@ -1062,8 +1062,8 @@ class Seed:
_seed = Seed()
-### T.K. 07-Aug-2013 Temporary fix for unexpected line gaps
+### T.K. 07-Aug-2013 Temporary fix for unexpected line gaps
def iter_three_segments(stroke):
n = stroke.stroke_vertices_size()
@@ -1093,14 +1093,15 @@ class StrokeCleaner(StrokeShader):
seg2 = sv3.point - sv2.point
seg3 = sv4.point - sv3.point
if seg1.dot(seg2) < 0.0 and seg2.dot(seg3) < 0.0:
- print(sv2.first_svertex.viewvertex)
- print(sv2.second_svertex.viewvertex)
- print(sv3.first_svertex.viewvertex)
- print(sv3.second_svertex.viewvertex)
+ #print(sv2.first_svertex.viewvertex)
+ #print(sv2.second_svertex.viewvertex)
+ #print(sv3.first_svertex.viewvertex)
+ #print(sv3.second_svertex.viewvertex)
p2 = mathutils.Vector(sv2.point)
p3 = mathutils.Vector(sv3.point)
sv2.point = p3
sv3.point = p2
+ stroke.update_length()
# main function for parameter processing
@@ -1233,6 +1234,9 @@ def process(layer_name, lineset_name):
Operators.select(LengthThresholdUP1D(length_min, length_max))
# prepare a list of stroke shaders
shaders_list = []
+ ###
+ shaders_list.append(StrokeCleaner())
+ ###
for m in linestyle.geometry_modifiers:
if not m.use:
continue
@@ -1282,9 +1286,6 @@ def process(layer_name, lineset_name):
elif m.type == '2D_TRANSFORM':
shaders_list.append(Transform2DShader(
m.pivot, m.scale_x, m.scale_y, m.angle, m.pivot_u, m.pivot_x, m.pivot_y))
- ###
- shaders_list.append(StrokeCleaner())
- ###
color = linestyle.color
if (not linestyle.use_chaining) or (linestyle.chaining == 'PLAIN' and linestyle.use_same_object):
thickness_position = linestyle.thickness_position
diff --git a/release/scripts/freestyle/style_modules/shaders.py b/release/scripts/freestyle/style_modules/shaders.py
index c9b022d46dc..01bfac4d074 100644
--- a/release/scripts/freestyle/style_modules/shaders.py
+++ b/release/scripts/freestyle/style_modules/shaders.py
@@ -459,7 +459,7 @@ class pyRandomColorShader(StrokeShader):
c0 = float(random.uniform(15,75))/100.0
c1 = float(random.uniform(15,75))/100.0
c2 = float(random.uniform(15,75))/100.0
- print(c0, c1, c2)
+ #print(c0, c1, c2)
it = stroke.stroke_vertices_begin()
while not it.is_end:
it.object.attribute.color = (c0,c1,c2)
diff --git a/release/scripts/modules/bpy/path.py b/release/scripts/modules/bpy/path.py
index e6ccb419059..da1a52e560d 100644
--- a/release/scripts/modules/bpy/path.py
+++ b/release/scripts/modules/bpy/path.py
@@ -163,6 +163,7 @@ def display_name(name):
"""
# string replacements
name = name.replace("_colon_", ":")
+ name = name.replace("_plus_", "+")
name = name.replace("_", " ")
diff --git a/release/scripts/modules/bpy_types.py b/release/scripts/modules/bpy_types.py
index 819d3e112ff..f7af297a0e0 100644
--- a/release/scripts/modules/bpy_types.py
+++ b/release/scripts/modules/bpy_types.py
@@ -306,6 +306,15 @@ class _GenericBone:
class PoseBone(StructRNA, _GenericBone, metaclass=StructMetaPropGroup):
__slots__ = ()
+ @property
+ def children(self):
+ obj = self.id_data
+ pbones = obj.pose.bones
+ self_bone = self.bone
+
+ return tuple(pbones[bone.name] for bone in obj.data.bones
+ if bone.parent == self_bone)
+
class Bone(StructRNA, _GenericBone, metaclass=StructMetaPropGroup):
__slots__ = ()
diff --git a/release/scripts/modules/rna_info.py b/release/scripts/modules/rna_info.py
index a4fd2c996cb..60b11884e30 100644
--- a/release/scripts/modules/rna_info.py
+++ b/release/scripts/modules/rna_info.py
@@ -648,7 +648,8 @@ def BuildRNAInfo():
for prop in func.return_values:
prop.build()
- if 1:
+ # there are too many invalid defaults, unless we intend to fix, leave this off
+ if 0:
for rna_info in InfoStructRNA.global_lookup.values():
for prop in rna_info.properties:
# ERROR CHECK
diff --git a/release/scripts/modules/rna_keymap_ui.py b/release/scripts/modules/rna_keymap_ui.py
index 727e9935bcc..60590158fbd 100644
--- a/release/scripts/modules/rna_keymap_ui.py
+++ b/release/scripts/modules/rna_keymap_ui.py
@@ -74,15 +74,14 @@ def draw_km(display_keymaps, kc, km, children, layout, level):
row.prop(km, "show_expanded_children", text="", emboss=False)
row.label(text=km.name, text_ctxt=i18n_contexts.id_windowmanager)
- row.label()
- row.label()
+ subrow = row.row()
+ subrow.alignment = 'RIGHT'
- if km.is_modal:
- row.label(text="", icon='LINKED')
if km.is_user_modified:
- row.operator("wm.keymap_restore", text="Restore")
- else:
- row.label()
+ subrow.operator("wm.keymap_restore", text="Restore")
+ if km.is_modal:
+ subrow.label(text="", icon='LINKED')
+ del subrow
if km.show_expanded_children:
if children:
diff --git a/release/scripts/presets/keyconfig/maya.py b/release/scripts/presets/keyconfig/maya.py
index c22b2546309..21fd757c4e5 100644
--- a/release/scripts/presets/keyconfig/maya.py
+++ b/release/scripts/presets/keyconfig/maya.py
@@ -655,8 +655,10 @@ kmi = km.keymap_items.new('mesh.duplicate_move', 'D', 'PRESS', ctrl=True)
kmi = km.keymap_items.new('wm.call_menu', 'A', 'PRESS', shift=True)
kmi.properties.name = 'INFO_MT_mesh_add'
kmi = km.keymap_items.new('mesh.dupli_extrude_cursor', 'MIDDLEMOUSE', 'CLICK', ctrl=True)
-kmi = km.keymap_items.new('mesh.delete', 'BACK_SPACE', 'PRESS')
-kmi = km.keymap_items.new('mesh.delete', 'DEL', 'PRESS')
+kmi = km.keymap_items.new('wm.call_menu', 'BACK_SPACE', 'PRESS')
+kmi.properties.name = 'VIEW3D_MT_edit_mesh_delete'
+kmi = km.keymap_items.new('wm.call_menu', 'DEL', 'PRESS')
+kmi.properties.name = 'VIEW3D_MT_edit_mesh_delete'
kmi = km.keymap_items.new('mesh.knife_tool', 'LEFTMOUSE', 'PRESS', key_modifier='K')
kmi = km.keymap_items.new('object.vertex_parent_set', 'P', 'PRESS')
kmi = km.keymap_items.new('wm.call_menu', 'RIGHTMOUSE', 'PRESS', ctrl=True)
diff --git a/release/scripts/presets/operator/wm.collada_export/second_life_rigged.py b/release/scripts/presets/operator/wm.collada_export/sl_plus_open_sim_rigged.py
index 717e044ccd6..7825a4d0f32 100644
--- a/release/scripts/presets/operator/wm.collada_export/second_life_rigged.py
+++ b/release/scripts/presets/operator/wm.collada_export/sl_plus_open_sim_rigged.py
@@ -15,4 +15,4 @@ op.use_texture_copies = True
op.triangulate = True
op.use_object_instantiation = False
op.sort_by_name = True
-op.second_life = True
+op.open_sim = True
diff --git a/release/scripts/presets/operator/wm.collada_export/second_life_static.py b/release/scripts/presets/operator/wm.collada_export/sl_plus_open_sim_static.py
index 9518fe5fb35..9e2efcaa727 100644
--- a/release/scripts/presets/operator/wm.collada_export/second_life_static.py
+++ b/release/scripts/presets/operator/wm.collada_export/sl_plus_open_sim_static.py
@@ -15,4 +15,4 @@ op.use_texture_copies = True
op.triangulate = True
op.use_object_instantiation = False
op.sort_by_name = True
-op.second_life = False
+op.open_sim = False
diff --git a/release/scripts/startup/bl_operators/node.py b/release/scripts/startup/bl_operators/node.py
index 9b629c3f976..77978c71ed9 100644
--- a/release/scripts/startup/bl_operators/node.py
+++ b/release/scripts/startup/bl_operators/node.py
@@ -113,8 +113,11 @@ class NodeAddOperator():
# Default execute simply adds a node
def execute(self, context):
- self.create_node(context)
- return {'FINISHED'}
+ if self.properties.is_property_set("type"):
+ self.create_node(context)
+ return {'FINISHED'}
+ else:
+ return {'CANCELLED'}
# Default invoke stores the mouse position to place the node correctly
# and optionally invokes the transform operator
diff --git a/release/scripts/startup/bl_operators/uvcalc_lightmap.py b/release/scripts/startup/bl_operators/uvcalc_lightmap.py
index f8f4b8d35e6..6f54c051c0b 100644
--- a/release/scripts/startup/bl_operators/uvcalc_lightmap.py
+++ b/release/scripts/startup/bl_operators/uvcalc_lightmap.py
@@ -556,8 +556,6 @@ def lightmap_uvpack(meshes,
print("finished all %.2f " % (time.time() - t))
- # Window.RedrawAll()
-
def unwrap(operator, context, **kwargs):
@@ -590,7 +588,7 @@ from bpy.props import BoolProperty, FloatProperty, IntProperty
class LightMapPack(Operator):
- """Follow UVs from active quads along continuous face loops"""
+ """Pack each faces UV's into the UV bounds"""
bl_idname = "uv.lightmap_pack"
bl_label = "Lightmap Pack"
diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py
index 909842d3c2b..5a249159d86 100644
--- a/release/scripts/startup/bl_operators/wm.py
+++ b/release/scripts/startup/bl_operators/wm.py
@@ -498,7 +498,7 @@ class WM_OT_context_menu_enum(Operator):
class WM_OT_context_set_id(Operator):
- """Toggle a context value"""
+ """Set a context value to an ID data-block"""
bl_idname = "wm.context_set_id"
bl_label = "Set Library ID"
bl_options = {'UNDO', 'INTERNAL'}
@@ -903,8 +903,9 @@ class WM_OT_doc_view(Operator):
return {'FINISHED'}
+'''
class WM_OT_doc_edit(Operator):
- """Load online reference docs"""
+ """Edit online reference docs"""
bl_idname = "wm.doc_edit"
bl_label = "Edit Documentation"
@@ -972,6 +973,7 @@ class WM_OT_doc_edit(Operator):
def invoke(self, context, event):
wm = context.window_manager
return wm.invoke_props_dialog(self, width=600)
+'''
rna_path = StringProperty(
@@ -1893,7 +1895,7 @@ class WM_OT_addon_install(Operator):
class WM_OT_addon_remove(Operator):
- "Disable an addon"
+ "Delete the addon from the file system"
bl_idname = "wm.addon_remove"
bl_label = "Remove Addon"
@@ -1935,6 +1937,8 @@ class WM_OT_addon_remove(Operator):
else:
os.remove(path)
+ addon_utils.modules_refresh()
+
context.area.tag_redraw()
return {'FINISHED'}
diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py
index 5d998ca0404..9bfc14f1f28 100644
--- a/release/scripts/startup/bl_ui/properties_data_modifier.py
+++ b/release/scripts/startup/bl_ui/properties_data_modifier.py
@@ -670,13 +670,17 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
col = split.column()
col.prop(md, "offset")
- col.prop(md, "subsurf_levels")
col = split.column()
col.label(text="Mode:")
col.prop(md, "wrap_method", text="")
if md.wrap_method == 'PROJECT':
+ split = layout.split()
+ col = split.column()
+ col.prop(md, "subsurf_levels")
+ col = split.column()
+
col.prop(md, "project_limit", text="Limit")
split = layout.split(percentage=0.25)
diff --git a/release/scripts/startup/bl_ui/properties_freestyle.py b/release/scripts/startup/bl_ui/properties_freestyle.py
index 18dd8f591e8..a96441a26e5 100644
--- a/release/scripts/startup/bl_ui/properties_freestyle.py
+++ b/release/scripts/startup/bl_ui/properties_freestyle.py
@@ -530,6 +530,8 @@ class RENDERLAYER_PT_freestyle_linestyle(RenderLayerFreestyleEditorButtonsPanel,
linestyle = lineset.linestyle
layout.template_ID(lineset, "linestyle", new="scene.freestyle_linestyle_new")
+ if linestyle is None:
+ return
row = layout.row(align=True)
row.prop(linestyle, "panel", expand=True)
if linestyle.panel == 'STROKES':
diff --git a/release/scripts/startup/bl_ui/properties_mask_common.py b/release/scripts/startup/bl_ui/properties_mask_common.py
index aa4d671e938..45f3471ad35 100644
--- a/release/scripts/startup/bl_ui/properties_mask_common.py
+++ b/release/scripts/startup/bl_ui/properties_mask_common.py
@@ -222,6 +222,11 @@ class MASK_PT_display():
layout.prop(space_data, "mask_draw_type", text="")
layout.prop(space_data, "show_mask_smooth")
+ layout.prop(space_data, "show_mask_overlay")
+ row = layout.row()
+ row.active = space_data.show_mask_overlay
+ row.prop(space_data, "mask_overlay_mode", text="")
+
class MASK_PT_tools():
# subclasses must define...
diff --git a/release/scripts/startup/bl_ui/properties_material.py b/release/scripts/startup/bl_ui/properties_material.py
index eff538971c0..bb0b137da0a 100644
--- a/release/scripts/startup/bl_ui/properties_material.py
+++ b/release/scripts/startup/bl_ui/properties_material.py
@@ -518,7 +518,7 @@ class MATERIAL_PT_sss(MaterialButtonsPanel, Panel):
layout.active = (sss.use) and (not mat.use_shadeless)
row = layout.row().split()
- sub = row.row(align=True).split(percentage=0.75)
+ sub = row.row(align=True).split(align=True, percentage=0.75)
sub.menu("MATERIAL_MT_sss_presets", text=bpy.types.MATERIAL_MT_sss_presets.bl_label)
sub.operator("material.sss_preset_add", text="", icon='ZOOMIN')
sub.operator("material.sss_preset_add", text="", icon='ZOOMOUT').remove_active = True
diff --git a/release/scripts/startup/bl_ui/properties_paint_common.py b/release/scripts/startup/bl_ui/properties_paint_common.py
index 5995b765ae6..e27d80bc8c3 100644
--- a/release/scripts/startup/bl_ui/properties_paint_common.py
+++ b/release/scripts/startup/bl_ui/properties_paint_common.py
@@ -134,13 +134,12 @@ def brush_mask_texture_settings(layout, brush):
layout.operator("brush.stencil_fit_image_aspect").mask = True
layout.operator("brush.stencil_reset_transform").mask = True
- if brush.mask_texture:
- col = layout.column()
- col.label(text="Angle:")
- col.active = brush.brush_capabilities.has_texture_angle
- col.prop(mask_tex_slot, "angle", text="")
-
- # scale and offset
- split = layout.split()
- split.prop(mask_tex_slot, "offset")
- split.prop(mask_tex_slot, "scale")
+ col = layout.column()
+ col.label(text="Angle:")
+ col.active = brush.brush_capabilities.has_texture_angle
+ col.prop(mask_tex_slot, "angle", text="")
+
+ # scale and offset
+ split = layout.split()
+ split.prop(mask_tex_slot, "offset")
+ split.prop(mask_tex_slot, "scale")
diff --git a/release/scripts/startup/bl_ui/properties_physics_common.py b/release/scripts/startup/bl_ui/properties_physics_common.py
index 26587472566..22c71c233c2 100644
--- a/release/scripts/startup/bl_ui/properties_physics_common.py
+++ b/release/scripts/startup/bl_ui/properties_physics_common.py
@@ -180,7 +180,7 @@ def point_cache_ui(self, context, cache, enabled, cachetype):
layout.separator()
- if cache.id_data.library:
+ if cache.id_data.library and not cache.use_disk_cache:
can_bake = False
col = layout.column(align=True)
diff --git a/release/scripts/startup/bl_ui/properties_render.py b/release/scripts/startup/bl_ui/properties_render.py
index e11f179e2cb..288f95ca4b0 100644
--- a/release/scripts/startup/bl_ui/properties_render.py
+++ b/release/scripts/startup/bl_ui/properties_render.py
@@ -501,7 +501,7 @@ class RENDER_PT_bake(RenderButtonsPanel, Panel):
layout.prop(rd, "bake_type")
multires_bake = False
- if rd.bake_type in ['NORMALS', 'DISPLACEMENT', 'AO']:
+ if rd.bake_type in ['NORMALS', 'DISPLACEMENT', 'DERIVATIVE', 'AO']:
layout.prop(rd, "use_bake_multires")
multires_bake = rd.use_bake_multires
@@ -542,11 +542,20 @@ class RENDER_PT_bake(RenderButtonsPanel, Panel):
if rd.bake_type == 'DISPLACEMENT':
col = split.column()
col.prop(rd, "use_bake_lores_mesh")
+
if rd.bake_type == 'AO':
col = split.column()
col.prop(rd, "bake_bias")
col.prop(rd, "bake_samples")
+ if rd.bake_type == 'DERIVATIVE':
+ row = layout.row()
+ row.prop(rd, "use_bake_user_scale", text="")
+
+ sub = row.column()
+ sub.active = rd.use_bake_user_scale
+ sub.prop(rd, "bake_user_scale", text="User Scale")
+
if __name__ == "__main__": # only for live edit.
bpy.utils.register_module(__name__)
diff --git a/release/scripts/startup/bl_ui/properties_texture.py b/release/scripts/startup/bl_ui/properties_texture.py
index e1b6aee29ae..023b3a13848 100644
--- a/release/scripts/startup/bl_ui/properties_texture.py
+++ b/release/scripts/startup/bl_ui/properties_texture.py
@@ -476,7 +476,7 @@ class TEXTURE_PT_image_sampling(TextureTypePanel, Panel):
col = split.column()
col.label(text="Alpha:")
row = col.row()
- row.active = tex.image and tex.image.use_alpha
+ row.active = bool(tex.image and tex.image.use_alpha)
row.prop(tex, "use_alpha", text="Use")
col.prop(tex, "use_calculate_alpha", text="Calculate")
col.prop(tex, "invert_alpha", text="Invert")
diff --git a/release/scripts/startup/bl_ui/space_image.py b/release/scripts/startup/bl_ui/space_image.py
index 398d1596216..17ed7b44cf1 100644
--- a/release/scripts/startup/bl_ui/space_image.py
+++ b/release/scripts/startup/bl_ui/space_image.py
@@ -390,7 +390,7 @@ class IMAGE_HT_header(Header):
if show_maskedit:
sub.menu("MASK_MT_mask")
- layout.template_ID(sima, "image", new="image.new")
+ layout.template_ID(sima, "image", new="image.new", open="image.open")
if not show_render:
layout.prop(sima, "use_image_pin", text="")
@@ -715,8 +715,8 @@ class IMAGE_PT_paint(Panel, ImagePaintPanel):
col.prop(brush, "clone_alpha", text="Alpha")
-class IMAGE_PT_tools_brush_texture(BrushButtonsPanel, Panel):
- bl_label = "Texture"
+class IMAGE_PT_tools_brush_overlay(BrushButtonsPanel, Panel):
+ bl_label = "Overlay"
bl_options = {'DEFAULT_CLOSED'}
def draw(self, context):
@@ -725,17 +725,24 @@ class IMAGE_PT_tools_brush_texture(BrushButtonsPanel, Panel):
toolsettings = context.tool_settings.image_paint
brush = toolsettings.brush
tex_slot = brush.texture_slot
+ tex_slot_mask = brush.mask_texture_slot
col = layout.column()
- col.template_ID_preview(brush, "texture", new="texture.new", rows=3, cols=8)
+
+ col.label(text="Curve:")
- brush_texture_settings(col, brush, 0)
+ row = col.row(align=True)
+ if brush.use_cursor_overlay:
+ row.prop(brush, "use_cursor_overlay", toggle=True, text="", icon='RESTRICT_VIEW_OFF')
+ else:
+ row.prop(brush, "use_cursor_overlay", toggle=True, text="", icon='RESTRICT_VIEW_ON')
- # use_texture_overlay and texture_overlay_alpha
- col = layout.column(align=True)
- col.active = brush.brush_capabilities.has_overlay
- col.label(text="Overlay:")
+ sub = row.row(align=True)
+ sub.prop(brush, "cursor_overlay_alpha", text="Alpha")
+ sub.prop(brush, "use_cursor_overlay_override", toggle=True, text="", icon='BRUSH_DATA')
+ col.active = brush.brush_capabilities.has_overlay
+ col.label(text="Texture:")
row = col.row(align=True)
if tex_slot.map_mode != 'STENCIL':
if brush.use_primary_overlay:
@@ -747,6 +754,36 @@ class IMAGE_PT_tools_brush_texture(BrushButtonsPanel, Panel):
sub.prop(brush, "texture_overlay_alpha", text="Alpha")
sub.prop(brush, "use_primary_overlay_override", toggle=True, text="", icon='BRUSH_DATA')
+ col.label(text="Mask Texture:")
+
+ row = col.row(align=True)
+ if tex_slot_mask.map_mode != 'STENCIL':
+ if brush.use_secondary_overlay:
+ row.prop(brush, "use_secondary_overlay", toggle=True, text="", icon='RESTRICT_VIEW_OFF')
+ else:
+ row.prop(brush, "use_secondary_overlay", toggle=True, text="", icon='RESTRICT_VIEW_ON')
+
+ sub = row.row(align=True)
+ sub.prop(brush, "mask_overlay_alpha", text="Alpha")
+ sub.prop(brush, "use_secondary_overlay_override", toggle=True, text="", icon='BRUSH_DATA')
+
+
+class IMAGE_PT_tools_brush_texture(BrushButtonsPanel, Panel):
+ bl_label = "Texture"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ def draw(self, context):
+ layout = self.layout
+
+ toolsettings = context.tool_settings.image_paint
+ brush = toolsettings.brush
+ tex_slot = brush.texture_slot
+
+ col = layout.column()
+ col.template_ID_preview(brush, "texture", new="texture.new", rows=3, cols=8)
+
+ brush_texture_settings(col, brush, 0)
+
class IMAGE_PT_tools_mask_texture(BrushButtonsPanel, Panel):
bl_label = "Texture Mask"
@@ -764,21 +801,6 @@ class IMAGE_PT_tools_mask_texture(BrushButtonsPanel, Panel):
brush_mask_texture_settings(col, brush)
- col = layout.column(align=True)
- col.active = brush.brush_capabilities.has_overlay
- col.label(text="Overlay:")
-
- row = col.row(align=True)
- if tex_slot_alpha.map_mode != 'STENCIL':
- if brush.use_secondary_overlay:
- row.prop(brush, "use_secondary_overlay", toggle=True, text="", icon='RESTRICT_VIEW_OFF')
- else:
- row.prop(brush, "use_secondary_overlay", toggle=True, text="", icon='RESTRICT_VIEW_ON')
-
- sub = row.row(align=True)
- sub.prop(brush, "mask_overlay_alpha", text="Alpha")
- sub.prop(brush, "use_secondary_overlay_override", toggle=True, text="", icon='BRUSH_DATA')
-
class IMAGE_PT_tools_brush_tool(BrushButtonsPanel, Panel):
bl_label = "Tool"
diff --git a/release/scripts/startup/bl_ui/space_info.py b/release/scripts/startup/bl_ui/space_info.py
index 591cfde5c16..5a570d18312 100644
--- a/release/scripts/startup/bl_ui/space_info.py
+++ b/release/scripts/startup/bl_ui/space_info.py
@@ -394,7 +394,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-268"
+ layout.operator("wm.url_open", text="Release Log", icon='URL').url = "http://www.blender.org/development/release-logs/blender-269"
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_node.py b/release/scripts/startup/bl_ui/space_node.py
index 843bafabdec..1721eacd8ac 100644
--- a/release/scripts/startup/bl_ui/space_node.py
+++ b/release/scripts/startup/bl_ui/space_node.py
@@ -407,13 +407,13 @@ class NODE_UL_interface_sockets(bpy.types.UIList):
row = layout.row(align=True)
# inputs get icon on the left
- if socket.in_out == 'IN':
+ if not socket.is_output:
row.template_node_socket(color)
row.label(text=socket.name, icon_value=icon)
# outputs get icon on the right
- if socket.in_out == 'OUT':
+ if socket.is_output:
row.template_node_socket(color)
elif self.layout_type in {'GRID'}:
diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py
index 7137a5097ee..ea88d35b4e9 100644
--- a/release/scripts/startup/bl_ui/space_sequencer.py
+++ b/release/scripts/startup/bl_ui/space_sequencer.py
@@ -685,10 +685,15 @@ class SEQUENCER_PT_sound(SequencerButtonsPanel, Panel):
layout.prop(strip, "pan")
col = layout.column(align=True)
- col.label(text="Trim Duration:")
+ col.label(text="Trim Duration (hard):")
col.prop(strip, "animation_offset_start", text="Start")
col.prop(strip, "animation_offset_end", text="End")
+ col = layout.column(align=True)
+ col.label(text="Trim Duration (soft):")
+ col.prop(strip, "frame_offset_start", text="Start")
+ col.prop(strip, "frame_offset_end", text="End")
+
class SEQUENCER_PT_scene(SequencerButtonsPanel, Panel):
bl_label = "Scene"
diff --git a/release/scripts/startup/bl_ui/space_text.py b/release/scripts/startup/bl_ui/space_text.py
index baaffa6530d..41ded2fe768 100644
--- a/release/scripts/startup/bl_ui/space_text.py
+++ b/release/scripts/startup/bl_ui/space_text.py
@@ -301,7 +301,7 @@ class TEXT_MT_edit(Menu):
layout.separator()
layout.operator("text.jump")
- layout.operator("text.properties", text="Find...")
+ layout.operator("text.start_find", text="Find...")
layout.operator("text.autocomplete")
layout.separator()
diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
index d01df810307..0bb31f51c1b 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -673,19 +673,6 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
col.prop(brush, "use_persistent")
col.operator("sculpt.set_persistent_base")
- col = layout.column(align=True)
- col.label(text="Overlay:")
-
- row = col.row(align=True)
- if brush.use_cursor_overlay:
- row.prop(brush, "use_cursor_overlay", toggle=True, text="", icon='RESTRICT_VIEW_OFF')
- else:
- row.prop(brush, "use_cursor_overlay", toggle=True, text="", icon='RESTRICT_VIEW_ON')
-
- sub = row.row(align=True)
- sub.prop(brush, "cursor_overlay_alpha", text="Alpha")
- sub.prop(brush, "use_cursor_overlay_override", toggle=True, text="", icon='BRUSH_DATA')
-
# Texture Paint Mode #
elif context.image_paint_object and brush:
@@ -709,19 +696,6 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
col.active = (brush.blend not in {'ERASE_ALPHA', 'ADD_ALPHA'})
col.prop(brush, "use_alpha")
- col = layout.column(align=True)
- col.label(text="Overlay:")
-
- row = col.row(align=True)
- if brush.use_cursor_overlay:
- row.prop(brush, "use_cursor_overlay", toggle=True, text="", icon='RESTRICT_VIEW_OFF')
- else:
- row.prop(brush, "use_cursor_overlay", toggle=True, text="", icon='RESTRICT_VIEW_ON')
-
- sub = row.row(align=True)
- sub.prop(brush, "cursor_overlay_alpha", text="Alpha")
- sub.prop(brush, "use_cursor_overlay_override", toggle=True, text="", icon='BRUSH_DATA')
-
# Weight Paint Mode #
elif context.weight_paint_object and brush:
@@ -765,18 +739,71 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
col.prop(brush, "vertex_tool", text="Blend")
- col = layout.column(align=True)
- col.label(text="Overlay:")
+class VIEW3D_PT_tools_brush_overlay(Panel, View3DPaintPanel):
+ bl_label = "Overlay"
+ bl_options = {'DEFAULT_CLOSED'}
+ @classmethod
+ def poll(cls, context):
+ settings = cls.paint_settings(context)
+ return (settings and
+ settings.brush and
+ (context.sculpt_object or
+ context.vertex_paint_object or
+ context.weight_paint_object or
+ context.image_paint_object))
+
+
+ def draw(self, context):
+ layout = self.layout
+
+ settings = self.paint_settings(context)
+ brush = settings.brush
+ tex_slot = brush.texture_slot
+ tex_slot_mask = brush.mask_texture_slot
+
+ col = layout.column()
+
+ col.label(text="Curve:")
+
+ row = col.row(align=True)
+ if brush.use_cursor_overlay:
+ row.prop(brush, "use_cursor_overlay", toggle=True, text="", icon='RESTRICT_VIEW_OFF')
+ else:
+ row.prop(brush, "use_cursor_overlay", toggle=True, text="", icon='RESTRICT_VIEW_ON')
+
+ sub = row.row(align=True)
+ sub.prop(brush, "cursor_overlay_alpha", text="Alpha")
+ sub.prop(brush, "use_cursor_overlay_override", toggle=True, text="", icon='BRUSH_DATA')
+
+ col.active = brush.brush_capabilities.has_overlay
+
+ if context.image_paint_object or context.sculpt_object or context.vertex_paint_object:
+ col.label(text="Texture:")
row = col.row(align=True)
- if brush.use_cursor_overlay:
- row.prop(brush, "use_cursor_overlay", toggle=True, text="", icon='RESTRICT_VIEW_OFF')
- else:
- row.prop(brush, "use_cursor_overlay", toggle=True, text="", icon='RESTRICT_VIEW_ON')
+ if tex_slot.map_mode != 'STENCIL':
+ if brush.use_primary_overlay:
+ row.prop(brush, "use_primary_overlay", toggle=True, text="", icon='RESTRICT_VIEW_OFF')
+ else:
+ row.prop(brush, "use_primary_overlay", toggle=True, text="", icon='RESTRICT_VIEW_ON')
+
+ sub = row.row(align=True)
+ sub.prop(brush, "texture_overlay_alpha", text="Alpha")
+ sub.prop(brush, "use_primary_overlay_override", toggle=True, text="", icon='BRUSH_DATA')
+
+ if context.image_paint_object:
+ col.label(text="Mask Texture:")
+
+ row = col.row(align=True)
+ if tex_slot_mask.map_mode != 'STENCIL':
+ if brush.use_secondary_overlay:
+ row.prop(brush, "use_secondary_overlay", toggle=True, text="", icon='RESTRICT_VIEW_OFF')
+ else:
+ row.prop(brush, "use_secondary_overlay", toggle=True, text="", icon='RESTRICT_VIEW_ON')
sub = row.row(align=True)
- sub.prop(brush, "cursor_overlay_alpha", text="Alpha")
- sub.prop(brush, "use_cursor_overlay_override", toggle=True, text="", icon='BRUSH_DATA')
+ sub.prop(brush, "mask_overlay_alpha", text="Alpha")
+ sub.prop(brush, "use_secondary_overlay_override", toggle=True, text="", icon='BRUSH_DATA')
class VIEW3D_PT_tools_brush_texture(Panel, View3DPaintPanel):
@@ -802,22 +829,6 @@ class VIEW3D_PT_tools_brush_texture(Panel, View3DPaintPanel):
brush_texture_settings(col, brush, context.sculpt_object)
- # use_texture_overlay and texture_overlay_alpha
- col = layout.column(align=True)
- col.active = brush.brush_capabilities.has_overlay
- col.label(text="Overlay:")
-
- row = col.row(align=True)
- if tex_slot.map_mode != 'STENCIL':
- if brush.use_primary_overlay:
- row.prop(brush, "use_primary_overlay", toggle=True, text="", icon='RESTRICT_VIEW_OFF')
- else:
- row.prop(brush, "use_primary_overlay", toggle=True, text="", icon='RESTRICT_VIEW_ON')
-
- sub = row.row(align=True)
- sub.prop(brush, "texture_overlay_alpha", text="Alpha")
- sub.prop(brush, "use_primary_overlay_override", toggle=True, text="", icon='BRUSH_DATA')
-
class VIEW3D_PT_tools_mask_texture(View3DPanel, Panel):
bl_context = "imagepaint"
@@ -841,21 +852,6 @@ class VIEW3D_PT_tools_mask_texture(View3DPanel, Panel):
brush_mask_texture_settings(col, brush)
- col = layout.column(align=True)
- col.active = brush.brush_capabilities.has_overlay
- col.label(text="Overlay:")
-
- row = col.row(align=True)
- if tex_slot_alpha.map_mode != 'STENCIL':
- if brush.use_secondary_overlay:
- row.prop(brush, "use_secondary_overlay", toggle=True, text="", icon='RESTRICT_VIEW_OFF')
- else:
- row.prop(brush, "use_secondary_overlay", toggle=True, text="", icon='RESTRICT_VIEW_ON')
-
- sub = row.row(align=True)
- sub.prop(brush, "mask_overlay_alpha", text="Alpha")
- sub.prop(brush, "use_secondary_overlay_override", toggle=True, text="", icon='BRUSH_DATA')
-
class VIEW3D_PT_tools_brush_stroke(Panel, View3DPaintPanel):
bl_label = "Stroke"
diff --git a/release/scripts/templates_py/custom_nodes.py b/release/scripts/templates_py/custom_nodes.py
index 5f002f37161..975ae1881f2 100644
--- a/release/scripts/templates_py/custom_nodes.py
+++ b/release/scripts/templates_py/custom_nodes.py
@@ -40,7 +40,7 @@ class MyCustomSocket(NodeSocket):
# Optional function for drawing the socket input value
def draw(self, context, layout, node, text):
- if self.is_linked:
+ if self.is_output or self.is_linked:
layout.label(text)
else:
layout.prop(self, "myEnumProperty", text=text)
diff --git a/release/scripts/templates_py/ui_list.py b/release/scripts/templates_py/ui_list.py
index 61ad0ae0435..92e1b29d2ae 100644
--- a/release/scripts/templates_py/ui_list.py
+++ b/release/scripts/templates_py/ui_list.py
@@ -1,7 +1,7 @@
import bpy
-class MESH_UL_mylist(UIList):
+class MESH_UL_mylist(bpy.types.UIList):
# Constants (flags)
# Be careful not to shadow FILTER_ITEM (i.e. UIList().bitflag_filter_item)!
# E.g. VGROUP_EMPTY = 1 << 0
diff --git a/release/text/readme.html b/release/text/readme.html
index 35057220c95..b15ea9b3847 100644
--- a/release/text/readme.html
+++ b/release/text/readme.html
@@ -12,18 +12,18 @@
</style>
</head>
<body>
-<p class="title"><b>Blender 2.68</b></p>
+<p class="title"><b>Blender 2.69</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">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 and Windows 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.68</b></p>
-<p class="body">The Blender Foundation and online developer community is proud to present Blender 2.68. This release is the ninth 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-268/">More information about this release</a>.</p>
+<p class="header"><b>2.69</b></p>
+<p class="body">The Blender Foundation and online developer community is proud to present Blender 2.69. This release is the tenth 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-269/">More information about this release</a>.</p>
<p><br></p>
<p class="header"><b>Bugs</b></p>
-<p class="body">Although Blender 2.68 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.69 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>
@@ -33,7 +33,7 @@
<p><br></p>
<p class="header"><b>Installation</b></p>
<p class="body"><b>Windows: </b>The download .zip contains a Blender folder. You may put this anywhere on your hard drive. To launch Blender, double-click on Blender.exe.</p>
-<p class="body"><b>Linux, FreeBSD: </b>Unpack the archive, Then run the Blender executable.</p>
+<p class="body"><b>Linux: </b>Unpack the archive, then run the Blender executable.</p>
<p class="body"><b>Mac OS X: </b>The downloaded package includes blender.app. Optionally copy this to your Applications folder, and add it to the dock by dragging it from there to the dock.</p>
<p></p>
<p class="body"><b>Installing Addons (all systems)</b> Addons can be installed from the user preferences addons section, download an addon as a .py or .zip file, then press the "Install Addon" button and select the file to install it.</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-268/">www.blender.org/development/release-logs/blender-268/</a><br>
+ Full release log <a href="http://www.blender.org/development/release-logs/blender-269/">www.blender.org/development/release-logs/blender-269/</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/CMakeLists.txt b/source/blender/CMakeLists.txt
index 7e327028a01..dd0583ef01f 100644
--- a/source/blender/CMakeLists.txt
+++ b/source/blender/CMakeLists.txt
@@ -117,6 +117,10 @@ if(WITH_IMAGE_OPENEXR)
add_subdirectory(imbuf/intern/openexr)
endif()
+if(WITH_IMAGE_OPENIMAGEIO)
+ add_subdirectory(imbuf/intern/oiio)
+endif()
+
if(WITH_IMAGE_DDS)
add_subdirectory(imbuf/intern/dds)
endif()
diff --git a/source/blender/SConscript b/source/blender/SConscript
index 66d54961131..de052f24c33 100644
--- a/source/blender/SConscript
+++ b/source/blender/SConscript
@@ -49,6 +49,9 @@ makesrna = SConscript('makesrna/SConscript')
if env['WITH_BF_PYTHON']:
SConscript(['python/SConscript'])
+if env['WITH_BF_OIIO']:
+ SConscript (['imbuf/intern/oiio/SConscript'])
+
if env['WITH_BF_DDS']:
SConscript (['imbuf/intern/dds/SConscript'])
diff --git a/source/blender/blenkernel/BKE_action.h b/source/blender/blenkernel/BKE_action.h
index d485632955d..698098d28c3 100644
--- a/source/blender/blenkernel/BKE_action.h
+++ b/source/blender/blenkernel/BKE_action.h
@@ -188,6 +188,10 @@ struct bPoseChannel *BKE_pose_channel_active(struct Object *ob);
*/
struct bPoseChannel *BKE_pose_channel_verify(struct bPose *pose, const char *name);
+#ifndef NDEBUG
+bool BKE_pose_channels_is_valid(const struct bPose *pose);
+#endif
+
/* Copy the data from the action-pose (src) into the pose */
void extract_pose_from_pose(struct bPose *pose, const struct bPose *src);
diff --git a/source/blender/blenkernel/BKE_animsys.h b/source/blender/blenkernel/BKE_animsys.h
index dd150ba6a63..f0f6b5a2319 100644
--- a/source/blender/blenkernel/BKE_animsys.h
+++ b/source/blender/blenkernel/BKE_animsys.h
@@ -112,6 +112,9 @@ void BKE_animdata_fix_paths_rename(struct ID *owner_id, struct AnimData *adt, st
/* Fix all the paths for the entire database... */
void BKE_all_animdata_fix_paths_rename(ID *ref_id, const char *prefix, const char *oldName, const char *newName);
+/* Fix the path after removing elements that are not ID (e.g., node) */
+void BKE_animdata_fix_paths_remove(struct ID *id, const char *path);
+
/* -------------------------------------- */
/* Move animation data from src to destination if it's paths are based on basepaths */
diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h
index f434bcf3cad..5b32e7229d5 100644
--- a/source/blender/blenkernel/BKE_blender.h
+++ b/source/blender/blenkernel/BKE_blender.h
@@ -41,15 +41,15 @@ extern "C" {
/* these lines are grep'd, watch out for our not-so-awesome regex
* and keep comment above the defines.
* Use STRINGIFY() rather than defining with quotes */
-#define BLENDER_VERSION 268
-#define BLENDER_SUBVERSION 5
+#define BLENDER_VERSION 269
+#define BLENDER_SUBVERSION 1
/* 262 was the last editmesh release but it has compatibility code for bmesh data */
#define BLENDER_MINVERSION 262
#define BLENDER_MINSUBVERSION 0
/* used by packaging tools */
/* can be left blank, otherwise a,b,c... etc with no quotes */
-#define BLENDER_VERSION_CHAR a
+#define BLENDER_VERSION_CHAR
/* alpha/beta/rc/release, docs use this */
#define BLENDER_VERSION_CYCLE alpha
diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h
index ac114a62de6..07116979eab 100644
--- a/source/blender/blenkernel/BKE_curve.h
+++ b/source/blender/blenkernel/BKE_curve.h
@@ -155,6 +155,7 @@ void BKE_nurb_handle_calc_simple(struct Nurb *nu, struct BezTriple *bezt);
void BKE_nurb_handles_calc(struct Nurb *nu);
void BKE_nurb_handles_autocalc(struct Nurb *nu, int flag);
-void BKE_nurb_handles_test(struct Nurb *nu);
+void BKE_nurb_bezt_handle_test(struct BezTriple *bezt, const bool use_handle);
+void BKE_nurb_handles_test(struct Nurb *nu, const bool use_handles);
#endif /* __BKE_CURVE_H__ */
diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h
index d47d03fe903..5a283922707 100644
--- a/source/blender/blenkernel/BKE_customdata.h
+++ b/source/blender/blenkernel/BKE_customdata.h
@@ -192,6 +192,9 @@ void CustomData_set_only_copy(const struct CustomData *data,
void CustomData_copy_data(const struct CustomData *source,
struct CustomData *dest, int source_index,
int dest_index, int count);
+void CustomData_copy_data_named(const struct CustomData *source,
+ struct CustomData *dest, int source_index,
+ int dest_index, int count);
void CustomData_copy_elements(int type, void *source, void *dest, int count);
void CustomData_bmesh_copy_data(const struct CustomData *source,
struct CustomData *dest, void *src_block,
diff --git a/source/blender/blenkernel/BKE_deform.h b/source/blender/blenkernel/BKE_deform.h
index a43a243106d..435cad17e57 100644
--- a/source/blender/blenkernel/BKE_deform.h
+++ b/source/blender/blenkernel/BKE_deform.h
@@ -78,8 +78,12 @@ void defvert_flip_merged(struct MDeformVert *dvert, const int *flip_map, const i
void defvert_normalize(struct MDeformVert *dvert);
void defvert_normalize_subset(struct MDeformVert *dvert,
const bool *vgroup_subset, const int vgroup_tot);
-void defvert_normalize_lock_single(struct MDeformVert *dvert, const int def_nr_lock);
-void defvert_normalize_lock_map(struct MDeformVert *dvert, const bool *lock_flags, const int defbase_tot);
+void defvert_normalize_lock_single(struct MDeformVert *dvert,
+ const bool *vgroup_subset, const int vgroup_tot,
+ const int def_nr_lock);
+void defvert_normalize_lock_map(struct MDeformVert *dvert,
+ const bool *vgroup_subset, const int vgroup_tot,
+ const bool *lock_flags, const int defbase_tot);
/* utility function, note that MAX_VGROUP_NAME chars is the maximum string length since its only
* used with defgroups currently */
diff --git a/source/blender/blenkernel/BKE_fcurve.h b/source/blender/blenkernel/BKE_fcurve.h
index 64a6811bf51..c31dd745911 100644
--- a/source/blender/blenkernel/BKE_fcurve.h
+++ b/source/blender/blenkernel/BKE_fcurve.h
@@ -229,12 +229,13 @@ short calc_fcurve_bounds(struct FCurve *fcu, float *xmin, float *xmax, float *ym
short fcurve_are_keyframes_usable(struct FCurve *fcu);
/* Can keyframes be added to F-Curve? */
-short fcurve_is_keyframable(struct FCurve *fcu);
+bool fcurve_is_keyframable(struct FCurve *fcu);
+bool BKE_fcurve_is_protected(struct FCurve *fcu);
/* -------- Curve Sanity -------- */
void calchandles_fcurve(struct FCurve *fcu);
-void testhandles_fcurve(struct FCurve *fcu, const short use_handle);
+void testhandles_fcurve(struct FCurve *fcu, const bool use_handle);
void sort_time_fcurve(struct FCurve *fcu);
short test_time_fcurve(struct FCurve *fcu);
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index 8b514c04a1f..a3d1eb74211 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -119,6 +119,10 @@ struct BoundBox *BKE_mesh_boundbox_get(struct Object *ob);
void BKE_mesh_texspace_get(struct Mesh *me, float r_loc[3], float r_rot[3], float r_size[3]);
void BKE_mesh_texspace_copy_from_object(struct Mesh *me, struct Object *ob);
+bool BKE_mesh_uv_cdlayer_rename_index(struct Mesh *me, const int poly_index, const int loop_index, const int face_index,
+ const char *new_name, const bool do_tessface);
+bool BKE_mesh_uv_cdlayer_rename(struct Mesh *me, const char *old_name, const char *new_name, bool do_tessface);
+
float (*BKE_mesh_vertexCos_get(struct Mesh *me, int *r_numVerts))[3];
/* vertex level transformations & checks (no derived mesh) */
@@ -165,9 +169,9 @@ void BKE_mesh_calc_normals_tessface(
struct MFace *mfaces, int numFaces,
float (*faceNors_r)[3]);
void BKE_mesh_normals_loop_split(
- struct MVert *mverts, int numVerts, struct MEdge *medges, int numEdges,
- struct MLoop *mloops, float (*r_loopnors)[3], int numLoops,
- struct MPoly *mpolys, float (*polynors)[3], int numPolys, float split_angle);
+ struct MVert *mverts, const int numVerts, struct MEdge *medges, const int numEdges,
+ struct MLoop *mloops, float (*r_loopnors)[3], const int numLoops,
+ struct MPoly *mpolys, float (*polynors)[3], const int numPolys, float split_angle);
void BKE_mesh_calc_poly_normal(
struct MPoly *mpoly, struct MLoop *loopstart,
diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h
index f42e131394b..6bf42a3e885 100644
--- a/source/blender/blenkernel/BKE_modifier.h
+++ b/source/blender/blenkernel/BKE_modifier.h
@@ -354,7 +354,7 @@ struct Object *modifiers_isDeformedByArmature(struct Object *ob);
struct Object *modifiers_isDeformedByLattice(struct Object *ob);
struct Object *modifiers_isDeformedByCurve(struct Object *ob);
bool modifiers_usesArmature(struct Object *ob, struct bArmature *arm);
-bool modifiers_isCorrectableDeformed(struct Object *ob);
+bool modifiers_isCorrectableDeformed(struct Scene *scene, struct Object *ob);
void modifier_freeTemporaryData(struct ModifierData *md);
bool modifiers_isPreview(struct Object *ob);
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 7f19a867093..7cc8c7290f7 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -131,8 +131,6 @@ typedef struct bNodeSocketType {
int type, subtype;
} bNodeSocketType;
-typedef void (*NodeSocketDrawFunction)(struct bContext *C, struct uiLayout *layout, struct PointerRNA *ptr, struct PointerRNA *node_ptr);
-
typedef void *(*NodeInitExecFunction)(struct bNodeExecContext *context, struct bNode *node, bNodeInstanceKey key);
typedef void (*NodeFreeExecFunction)(struct bNode *node, void *nodedata);
typedef void (*NodeExecFunction)(void *data, int thread, struct bNode *, struct bNodeExecData *execdata, struct bNodeStack **in, struct bNodeStack **out);
@@ -162,24 +160,19 @@ typedef struct bNodeType {
char storagename[64]; /* struct name for DNA */
- /// Main draw function for the node.
- void (*drawfunc)(const struct bContext *C, struct ARegion *ar, struct SpaceNode *snode,
+ /* Main draw function for the node */
+ void (*draw_nodetype)(const struct bContext *C, struct ARegion *ar, struct SpaceNode *snode,
struct bNodeTree *ntree, struct bNode *node, bNodeInstanceKey key);
- /// Updates the node geometry attributes according to internal state before actual drawing.
- void (*drawupdatefunc)(const struct bContext *C, struct bNodeTree *ntree, struct bNode *node);
- /// Draw the option buttons on the node.
- void (*uifunc)(struct uiLayout *, struct bContext *C, struct PointerRNA *ptr);
- /// Additional parameters in the side panel.
- void (*uifuncbut)(struct uiLayout *, struct bContext *C, struct PointerRNA *ptr);
- /// Additional drawing on backdrop.
- void (*uibackdropfunc)(struct SpaceNode *snode, struct ImBuf *backdrop, struct bNode *node, int x, int y);
-
- /// Draw a node socket. Default draws the input value button.
- /* XXX deprecated, only used for the OutputFile node,
- * should be removed at some point.
- */
- NodeSocketDrawFunction drawinputfunc;
- NodeSocketDrawFunction drawoutputfunc;
+ /* Updates the node geometry attributes according to internal state before actual drawing */
+ void (*draw_nodetype_prepare)(const struct bContext *C, struct bNodeTree *ntree, struct bNode *node);
+
+ /* Draw the option buttons on the node */
+ void (*draw_buttons)(struct uiLayout *, struct bContext *C, struct PointerRNA *ptr);
+ /* Additional parameters in the side panel */
+ void (*draw_buttons_ex)(struct uiLayout *, struct bContext *C, struct PointerRNA *ptr);
+
+ /* Additional drawing on backdrop */
+ void (*draw_backdrop)(struct SpaceNode *snode, struct ImBuf *backdrop, struct bNode *node, int x, int y);
/// Optional custom label function for the node header.
const char *(*labelfunc)(struct bNode *);
diff --git a/source/blender/blenkernel/BKE_subsurf.h b/source/blender/blenkernel/BKE_subsurf.h
index 653f2a42675..ab8b8b29915 100644
--- a/source/blender/blenkernel/BKE_subsurf.h
+++ b/source/blender/blenkernel/BKE_subsurf.h
@@ -72,11 +72,11 @@ struct DerivedMesh *subsurf_make_derived_from_derived(
void subsurf_calculate_limit_positions(struct Mesh *me, float (*positions_r)[3]);
/* get gridsize from 'level', level must be greater than zero */
-int ccg_gridsize(int level);
+int BKE_ccg_gridsize(int level);
/* x/y grid coordinates at 'low_level' can be multiplied by the result
* of this function to convert to grid coordinates at 'high_level' */
-int ccg_factor(int low_level, int high_level);
+int BKE_ccg_factor(int low_level, int high_level);
void subsurf_copy_grid_hidden(struct DerivedMesh *dm,
const struct MPoly *mpoly,
diff --git a/source/blender/blenkernel/BKE_texture.h b/source/blender/blenkernel/BKE_texture.h
index ac0d507003e..2a00dee2a3f 100644
--- a/source/blender/blenkernel/BKE_texture.h
+++ b/source/blender/blenkernel/BKE_texture.h
@@ -101,8 +101,8 @@ void set_current_particle_texture(struct ParticleSettings *part, struct Tex *tex
int has_current_material_texture(struct Material *ma);
-struct TexMapping *add_tex_mapping(void);
-void default_tex_mapping(struct TexMapping *texmap);
+struct TexMapping *add_tex_mapping(int type);
+void default_tex_mapping(struct TexMapping *texmap, int type);
void init_tex_mapping(struct TexMapping *texmap);
struct ColorMapping *add_color_mapping(void);
diff --git a/source/blender/blenkernel/SConscript b/source/blender/blenkernel/SConscript
index 3c3ac61a3cb..07dbc1d6065 100644
--- a/source/blender/blenkernel/SConscript
+++ b/source/blender/blenkernel/SConscript
@@ -101,6 +101,9 @@ if env['WITH_BF_SDL']:
incs += ' ' + env['BF_SDL_INC']
defs.append('WITH_SDL')
+if env['WITH_BF_OIIO']:
+ defs.append('WITH_OPENIMAGEIO')
+
if env['WITH_BF_OPENEXR']:
defs.append('WITH_OPENEXR')
diff --git a/source/blender/blenkernel/intern/CCGSubSurf.c b/source/blender/blenkernel/intern/CCGSubSurf.c
index d4454a95a2d..ffb92788d4d 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf.c
+++ b/source/blender/blenkernel/intern/CCGSubSurf.c
@@ -248,7 +248,7 @@ static CCGAllocatorIFC *_getStandardAllocatorIFC(void)
/***/
-int ccg_gridsize(int level)
+BLI_INLINE int ccg_gridsize(int level)
{
BLI_assert(level > 0);
BLI_assert(level <= CCGSUBSURF_LEVEL_MAX + 1);
@@ -256,7 +256,12 @@ int ccg_gridsize(int level)
return (1 << (level - 1)) + 1;
}
-int ccg_factor(int low_level, int high_level)
+int BKE_ccg_gridsize(int level)
+{
+ return ccg_gridsize(level);
+}
+
+int BKE_ccg_factor(int low_level, int high_level)
{
BLI_assert(low_level > 0 && high_level > 0);
BLI_assert(low_level <= high_level);
@@ -264,7 +269,7 @@ int ccg_factor(int low_level, int high_level)
return 1 << (high_level - low_level);
}
-static int ccg_edgesize(int level)
+BLI_INLINE int ccg_edgesize(int level)
{
BLI_assert(level > 0);
BLI_assert(level <= CCGSUBSURF_LEVEL_MAX + 1);
@@ -272,7 +277,7 @@ static int ccg_edgesize(int level)
return 1 + (1 << level);
}
-static int ccg_spacing(int high_level, int low_level)
+BLI_INLINE int ccg_spacing(int high_level, int low_level)
{
BLI_assert(high_level > 0 && low_level > 0);
BLI_assert(high_level >= low_level);
@@ -281,7 +286,7 @@ static int ccg_spacing(int high_level, int low_level)
return 1 << (high_level - low_level);
}
-static int ccg_edgebase(int level)
+BLI_INLINE int ccg_edgebase(int level)
{
BLI_assert(level > 0);
BLI_assert(level <= CCGSUBSURF_LEVEL_MAX + 1);
@@ -742,7 +747,7 @@ BLI_INLINE float *_face_getIFNo(CCGFace *f, int lvl, int S, int x, int y, int le
byte *gridBase = FACE_getCenterData(f) + dataSize * (1 + S * (maxGridSize + maxGridSize * maxGridSize));
return (float *) &gridBase[dataSize * (maxGridSize + (y * maxGridSize + x) * spacing) + normalDataOffset];
}
-static int _face_getVertIndex(CCGFace *f, CCGVert *v)
+BLI_INLINE int _face_getVertIndex(CCGFace *f, CCGVert *v)
{
int i;
for (i = 0; i < f->numVerts; i++)
@@ -750,7 +755,7 @@ static int _face_getVertIndex(CCGFace *f, CCGVert *v)
return i;
return -1;
}
-static int _face_getEdgeIndex(CCGFace *f, CCGEdge *e)
+BLI_INLINE int _face_getEdgeIndex(CCGFace *f, CCGEdge *e)
{
int i;
for (i = 0; i < f->numVerts; i++)
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index 644fefad3b0..b0644da4598 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -489,6 +489,22 @@ bPoseChannel *BKE_pose_channel_verify(bPose *pose, const char *name)
return chan;
}
+#ifndef NDEBUG
+bool BKE_pose_channels_is_valid(const bPose *pose)
+{
+ if (pose->chanhash) {
+ bPoseChannel *pchan;
+ for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
+ if (BLI_ghash_lookup(pose->chanhash, pchan->name) != pchan) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+#endif
/* Find the active posechannel for an object (we can't just use pose, as layer info is in armature) */
bPoseChannel *BKE_pose_channel_active(Object *ob)
{
diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c
index 5c3f67d8959..225be335c6d 100644
--- a/source/blender/blenkernel/intern/anim.c
+++ b/source/blender/blenkernel/intern/anim.c
@@ -530,7 +530,7 @@ void calc_curvepath(Object *ob, ListBase *nurbs)
path->len = nu->resolu * SEGMENTSU(nu);
}
- dist = (float *)MEM_mallocN((tot + 1) * 4, "calcpathdist");
+ dist = (float *)MEM_mallocN(sizeof(float) * (tot + 1), "calcpathdist");
/* all lengths in *dist */
bevp = bevpfirst = (BevPoint *)(bl + 1);
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index 8e697ad4ef3..74578266c63 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -42,6 +42,7 @@
#include "BLI_blenlib.h"
#include "BLI_alloca.h"
#include "BLI_dynstr.h"
+#include "BLI_listbase.h"
#include "BLF_translation.h"
@@ -759,6 +760,76 @@ void BKE_animdata_fix_paths_rename(ID *owner_id, AnimData *adt, ID *ref_id, cons
MEM_freeN(newN);
}
+/* *************************** */
+/* remove of individual paths */
+
+/* Check RNA-Paths for a list of F-Curves */
+static void fcurves_path_remove_fix(const char *prefix, ListBase *curves)
+{
+ FCurve *fcu, *fcn;
+ if (!prefix) return;
+
+ /* we need to check every curve... */
+ for (fcu = curves->first; fcu; fcu = fcn) {
+ fcn = fcu->next;
+
+ if (fcu->rna_path) {
+ if (STRPREFIX(fcu->rna_path, prefix)) {
+ BLI_remlink(curves, fcu);
+ free_fcurve(fcu);
+ }
+ }
+ }
+}
+
+/* Check RNA-Paths for a list of F-Curves */
+static void nlastrips_path_remove_fix(const char *prefix, ListBase *strips)
+{
+ NlaStrip *strip;
+
+ /* recursively check strips, fixing only actions... */
+ for (strip = strips->first; strip; strip = strip->next) {
+
+ /* fix strip's action */
+ if (strip->act)
+ fcurves_path_remove_fix(prefix, &strip->act->curves);
+
+ /* check sub-strips (if metas) */
+ nlastrips_path_remove_fix(prefix, &strip->strips);
+ }
+}
+
+void BKE_animdata_fix_paths_remove(ID *id, const char *prefix)
+{
+ /* Only some ID-blocks have this info for now, so we cast the
+ * types that do to be of type IdAdtTemplate
+ */
+ NlaTrack *nlt;
+
+ if (id_type_can_have_animdata(id)) {
+ IdAdtTemplate *iat = (IdAdtTemplate *)id;
+ AnimData *adt = iat->adt;
+
+ /* check if there's any AnimData to start with */
+ if (adt) {
+
+ /* free fcurves */
+ if (adt->action)
+ fcurves_path_remove_fix(prefix, &adt->action->curves);
+
+ if (adt->tmpact)
+ fcurves_path_remove_fix(prefix, &adt->tmpact->curves);
+
+ /* free drivers - stored as a list of F-Curves */
+ fcurves_path_remove_fix(prefix, &adt->drivers);
+
+ /* NLA Data - Animation Data for Strips */
+ for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next)
+ nlastrips_path_remove_fix(prefix, &nlt->strips);
+ }
+ }
+}
+
/* Whole Database Ops -------------------------------------------- */
/* apply the given callback function on all data in main database */
diff --git a/source/blender/blenkernel/intern/boids.c b/source/blender/blenkernel/intern/boids.c
index 8ce84609c15..a8d64ea9fb6 100644
--- a/source/blender/blenkernel/intern/boids.c
+++ b/source/blender/blenkernel/intern/boids.c
@@ -206,6 +206,8 @@ static int rule_avoid_collision(BoidRule *rule, BoidBrainData *bbd, BoidValues *
BVHTreeRayHit hit;
float radius = val->personal_space * pa->size, ray_dir[3];
+ memset(&col, 0, sizeof(ParticleCollision));
+
copy_v3_v3(col.co1, pa->prev_state.co);
add_v3_v3v3(col.co2, pa->prev_state.co, pa->prev_state.vel);
sub_v3_v3v3(ray_dir, col.co2, col.co1);
@@ -777,6 +779,8 @@ static Object *boid_find_ground(BoidBrainData *bbd, ParticleData *pa, float grou
if (!bbd->sim->colliders)
return NULL;
+ memset(&col, 0, sizeof(ParticleCollision));
+
/* first try to find below boid */
copy_v3_v3(col.co1, pa->state.co);
sub_v3_v3v3(col.co2, pa->state.co, zvec);
diff --git a/source/blender/blenkernel/intern/bvhutils.c b/source/blender/blenkernel/intern/bvhutils.c
index 5b66b8b4cd4..370dbc62ef8 100644
--- a/source/blender/blenkernel/intern/bvhutils.c
+++ b/source/blender/blenkernel/intern/bvhutils.c
@@ -355,7 +355,7 @@ float nearest_point_in_tri_surface(const float v0[3], const float v1[3], const f
/*
- * BVH from meshs callbacks
+ * BVH from meshes callbacks
*/
/* Callback to bvh tree nearest point. The tree must bust have been built using bvhtree_from_mesh_faces.
diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c
index 7f94f365925..578fa5d348d 100644
--- a/source/blender/blenkernel/intern/colortools.c
+++ b/source/blender/blenkernel/intern/colortools.c
@@ -972,9 +972,6 @@ void BKE_histogram_update_sample_line(Histogram *hist, ImBuf *ibuf, const ColorM
if (ibuf->rect_float)
cm_processor = IMB_colormanagement_display_processor_new(view_settings, display_settings);
- /* persistent draw */
- hist->flag |= HISTO_FLAG_SAMPLELINE; /* keep drawing the flag after */
-
for (i = 0; i < 256; i++) {
x = (int)(0.5f + x1 + (float)i * (x2 - x1) / 255.0f);
y = (int)(0.5f + y1 + (float)i * (y2 - y1) / 255.0f);
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index 02b35794d28..e255732d3fb 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -3102,46 +3102,67 @@ void BKE_nurb_handle_calc_simple(Nurb *nu, BezTriple *bezt)
}
}
-void BKE_nurb_handles_test(Nurb *nu)
-{
- /* use when something has changed with handles.
- * it treats all BezTriples with the following rules:
- * PHASE 1: do types have to be altered?
- * Auto handles: become aligned when selection status is NOT(000 || 111)
- * Vector handles: become 'nothing' when (one half selected AND other not)
- * PHASE 2: recalculate handles
- */
- BezTriple *bezt;
- short flag, a;
+/**
+ * Use when something has changed handle positions.
+ *
+ * The caller needs to recalculate handles.
+ */
+void BKE_nurb_bezt_handle_test(BezTriple *bezt, const bool use_handle)
+{
+ short flag = 0;
- if (nu->type != CU_BEZIER) return;
+#define SEL_F1 (1 << 0)
+#define SEL_F2 (1 << 1)
+#define SEL_F3 (1 << 2)
- bezt = nu->bezt;
- a = nu->pntsu;
- while (a--) {
- flag = 0;
- if (bezt->f1 & SELECT)
- flag++;
- if (bezt->f2 & SELECT)
- flag += 2;
- if (bezt->f3 & SELECT)
- flag += 4;
+ if (use_handle) {
+ if (bezt->f1 & SELECT) flag |= SEL_F1;
+ if (bezt->f2 & SELECT) flag |= SEL_F2;
+ if (bezt->f3 & SELECT) flag |= SEL_F3;
+ }
+ else {
+ flag = (bezt->f2 & SELECT) ? (SEL_F1 | SEL_F2 | SEL_F3) : 0;
+ }
- if (!(flag == 0 || flag == 7) ) {
- if (ELEM(bezt->h1, HD_AUTO, HD_AUTO_ANIM)) { /* auto */
- bezt->h1 = HD_ALIGN;
- }
- if (ELEM(bezt->h2, HD_AUTO, HD_AUTO_ANIM)) { /* auto */
- bezt->h2 = HD_ALIGN;
- }
+ /* check for partial selection */
+ if (!ELEM(flag, 0, SEL_F1 | SEL_F2 | SEL_F3)) {
+ if (ELEM(bezt->h1, HD_AUTO, HD_AUTO_ANIM)) {
+ bezt->h1 = HD_ALIGN;
+ }
+ if (ELEM(bezt->h2, HD_AUTO, HD_AUTO_ANIM)) {
+ bezt->h2 = HD_ALIGN;
+ }
- if (bezt->h1 == HD_VECT) { /* vector */
- if (flag < 4) bezt->h1 = 0;
+ if (bezt->h1 == HD_VECT) {
+ if ((!(flag & SEL_F1)) != (!(flag & SEL_F2))) {
+ bezt->h1 = HD_FREE;
}
- if (bezt->h2 == HD_VECT) { /* vector */
- if (flag > 3) bezt->h2 = 0;
+ }
+ if (bezt->h2 == HD_VECT) {
+ if ((!(flag & SEL_F3)) != (!(flag & SEL_F2))) {
+ bezt->h2 = HD_FREE;
}
}
+ }
+
+#undef SEL_F1
+#undef SEL_F2
+#undef SEL_F3
+
+}
+
+void BKE_nurb_handles_test(Nurb *nu, const bool use_handle)
+{
+ BezTriple *bezt;
+ short a;
+
+ if (nu->type != CU_BEZIER)
+ return;
+
+ bezt = nu->bezt;
+ a = nu->pntsu;
+ while (a--) {
+ BKE_nurb_bezt_handle_test(bezt, use_handle);
bezt++;
}
@@ -3151,9 +3172,11 @@ void BKE_nurb_handles_test(Nurb *nu)
void BKE_nurb_handles_autocalc(Nurb *nu, int flag)
{
/* checks handle coordinates and calculates type */
+ const float eps = 0.0001f;
+ const float eps_sq = eps * eps;
BezTriple *bezt2, *bezt1, *bezt0;
- int i, align, leftsmall, rightsmall;
+ int i;
if (nu == NULL || nu->bezt == NULL)
return;
@@ -3164,54 +3187,54 @@ void BKE_nurb_handles_autocalc(Nurb *nu, int flag)
i = nu->pntsu;
while (i--) {
- align = leftsmall = rightsmall = 0;
+ bool align = false, leftsmall = false, rightsmall = false;
/* left handle: */
if (flag == 0 || (bezt1->f1 & flag) ) {
- bezt1->h1 = 0;
+ bezt1->h1 = HD_FREE;
/* distance too short: vectorhandle */
- if (len_v3v3(bezt1->vec[1], bezt0->vec[1]) < 0.0001f) {
+ if (len_squared_v3v3(bezt1->vec[1], bezt0->vec[1]) < eps_sq) {
bezt1->h1 = HD_VECT;
- leftsmall = 1;
+ leftsmall = true;
}
else {
/* aligned handle? */
- if (dist_to_line_v2(bezt1->vec[1], bezt1->vec[0], bezt1->vec[2]) < 0.0001f) {
- align = 1;
+ if (dist_to_line_v2(bezt1->vec[1], bezt1->vec[0], bezt1->vec[2]) < eps) {
+ align = true;
bezt1->h1 = HD_ALIGN;
}
/* or vector handle? */
- if (dist_to_line_v2(bezt1->vec[0], bezt1->vec[1], bezt0->vec[1]) < 0.0001f)
+ if (dist_to_line_v2(bezt1->vec[0], bezt1->vec[1], bezt0->vec[1]) < eps)
bezt1->h1 = HD_VECT;
}
}
/* right handle: */
if (flag == 0 || (bezt1->f3 & flag) ) {
- bezt1->h2 = 0;
+ bezt1->h2 = HD_FREE;
/* distance too short: vectorhandle */
- if (len_v3v3(bezt1->vec[1], bezt2->vec[1]) < 0.0001f) {
+ if (len_squared_v3v3(bezt1->vec[1], bezt2->vec[1]) < eps_sq) {
bezt1->h2 = HD_VECT;
- rightsmall = 1;
+ rightsmall = true;
}
else {
/* aligned handle? */
if (align) bezt1->h2 = HD_ALIGN;
/* or vector handle? */
- if (dist_to_line_v2(bezt1->vec[2], bezt1->vec[1], bezt2->vec[1]) < 0.0001f)
+ if (dist_to_line_v2(bezt1->vec[2], bezt1->vec[1], bezt2->vec[1]) < eps)
bezt1->h2 = HD_VECT;
}
}
if (leftsmall && bezt1->h2 == HD_ALIGN)
- bezt1->h2 = 0;
+ bezt1->h2 = HD_FREE;
if (rightsmall && bezt1->h1 == HD_ALIGN)
- bezt1->h1 = 0;
+ bezt1->h1 = HD_FREE;
/* undesired combination: */
if (bezt1->h1 == HD_ALIGN && bezt1->h2 == HD_VECT)
- bezt1->h1 = 0;
+ bezt1->h1 = HD_FREE;
if (bezt1->h2 == HD_ALIGN && bezt1->h1 == HD_VECT)
- bezt1->h2 = 0;
+ bezt1->h2 = HD_FREE;
bezt0 = bezt1;
bezt1 = bezt2;
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index 03dfee4b57c..8a74f4719d5 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -971,6 +971,11 @@ static void layerDefault_mcol(void *data, int count)
}
}
+static void layerDefault_origindex(void *data, int count)
+{
+ fill_vn_i((int *)data, count, ORIGINDEX_NONE);
+}
+
static void layerInterp_bweight(void **sources, const float *weights,
const float *UNUSED(sub_weights), int count, void *dest)
{
@@ -1077,7 +1082,7 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
{sizeof(MCol) * 4, "MCol", 4, N_("Col"), NULL, NULL, layerInterp_mcol,
layerSwap_mcol, layerDefault_mcol},
/* 7: CD_ORIGINDEX */
- {sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
+ {sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, layerDefault_origindex},
/* 8: CD_NORMAL */
/* 3 floats per normal vector */
{sizeof(float) * 3, "vec3f", 1, NULL, NULL, NULL, NULL, NULL, NULL},
@@ -1313,7 +1318,7 @@ bool CustomData_merge(const struct CustomData *source, struct CustomData *dest,
if (lastflag & CD_FLAG_NOCOPY) continue;
else if (!(mask & CD_TYPE_AS_MASK(type))) continue;
- else if (number < CustomData_number_of_layers(dest, type)) continue;
+ else if (CustomData_get_layer_named(dest, type, layer->name)) continue;
switch (alloctype) {
case CD_ASSIGN:
@@ -1457,8 +1462,9 @@ int CustomData_get_named_layer_index(const CustomData *data, int type, const cha
int i;
for (i = 0; i < data->totlayer; ++i)
- if (data->layers[i].type == type && strcmp(data->layers[i].name, name) == 0)
- return i;
+ if (data->layers[i].type == type)
+ if (strcmp(data->layers[i].name, name) == 0)
+ return i;
return -1;
}
@@ -1947,13 +1953,61 @@ void CustomData_copy_elements(int type, void *source, void *dest, int count)
memcpy(dest, source, typeInfo->size * count);
}
+static void CustomData_copy_data_layer(const CustomData *source, CustomData *dest,
+ int src_i, int dest_i,
+ int source_index, int dest_index, int count) {
+ const LayerTypeInfo *typeInfo;
+ int src_offset;
+ int dest_offset;
+
+ char *src_data = source->layers[src_i].data;
+ char *dest_data = dest->layers[dest_i].data;
+
+ typeInfo = layerType_getInfo(source->layers[src_i].type);
+
+ src_offset = source_index * typeInfo->size;
+ dest_offset = dest_index * typeInfo->size;
+
+ if (!src_data || !dest_data) {
+ if (!(src_data == NULL && dest_data == NULL)) {
+ printf("%s: warning null data for %s type (%p --> %p), skipping\n",
+ __func__, layerType_getName(source->layers[src_i].type),
+ (void *)src_data, (void *)dest_data);
+ }
+ return;
+ }
+
+ if (typeInfo->copy)
+ typeInfo->copy(src_data + src_offset,
+ dest_data + dest_offset,
+ count);
+ else
+ memcpy(dest_data + dest_offset,
+ src_data + src_offset,
+ count * typeInfo->size);
+}
+
+void CustomData_copy_data_named(const CustomData *source, CustomData *dest,
+ int source_index, int dest_index, int count)
+{
+ int src_i, dest_i;
+
+ /* copies a layer at a time */
+ for (src_i = 0; src_i < source->totlayer; ++src_i) {
+
+ dest_i = CustomData_get_named_layer_index(dest, source->layers[src_i].type, source->layers[src_i].name);
+
+ /* if we found a matching layer, copy the data */
+ if (dest_i > -1) {
+ CustomData_copy_data_layer(source, dest, src_i, dest_i, source_index, dest_index, count);
+ }
+ }
+}
+
void CustomData_copy_data(const CustomData *source, CustomData *dest,
int source_index, int dest_index, int count)
{
- const LayerTypeInfo *typeInfo;
int src_i, dest_i;
- int src_offset;
- int dest_offset;
/* copies a layer at a time */
dest_i = 0;
@@ -1971,32 +2025,8 @@ void CustomData_copy_data(const CustomData *source, CustomData *dest,
/* if we found a matching layer, copy the data */
if (dest->layers[dest_i].type == source->layers[src_i].type) {
- char *src_data = source->layers[src_i].data;
- char *dest_data = dest->layers[dest_i].data;
-
- typeInfo = layerType_getInfo(source->layers[src_i].type);
-
- src_offset = source_index * typeInfo->size;
- dest_offset = dest_index * typeInfo->size;
-
- if (!src_data || !dest_data) {
- if (src_data != NULL && dest_data != NULL) {
- printf("%s: warning null data for %s type (%p --> %p), skipping\n",
- __func__, layerType_getName(source->layers[src_i].type),
- (void *)src_data, (void *)dest_data);
- }
- continue;
- }
+ CustomData_copy_data_layer(source, dest, src_i, dest_i, source_index, dest_index, count);
- if (typeInfo->copy)
- typeInfo->copy(src_data + src_offset,
- dest_data + dest_offset,
- count);
- else
- memcpy(dest_data + dest_offset,
- src_data + src_offset,
- count * typeInfo->size);
-
/* if there are multiple source & dest layers of the same type,
* we don't want to copy all source layers to the same dest, so
* increment dest_i
diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c
index 882085aa5db..a183872552d 100644
--- a/source/blender/blenkernel/intern/deform.c
+++ b/source/blender/blenkernel/intern/deform.c
@@ -217,24 +217,35 @@ void defvert_remap(MDeformVert *dvert, int *map, const int map_len)
void defvert_normalize_subset(MDeformVert *dvert,
const bool *vgroup_subset, const int vgroup_tot)
{
- MDeformWeight *dw;
- unsigned int i;
- float tot_weight = 0.0f;
-
- for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
+ if (dvert->totweight == 0) {
+ /* nothing */
+ }
+ else if (dvert->totweight == 1) {
+ MDeformWeight *dw = dvert->dw;
if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
- tot_weight += dw->weight;
+ dw->weight = 1.0f;
}
}
+ else {
+ MDeformWeight *dw;
+ unsigned int i;
+ float tot_weight = 0.0f;
- if (tot_weight > 0.0f) {
- float scalar = 1.0f / tot_weight;
for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
- dw->weight *= scalar;
-
- /* in case of division errors with very low weights */
- CLAMP(dw->weight, 0.0f, 1.0f);
+ tot_weight += dw->weight;
+ }
+ }
+
+ if (tot_weight > 0.0f) {
+ float scalar = 1.0f / tot_weight;
+ for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
+ if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
+ dw->weight *= scalar;
+
+ /* in case of division errors with very low weights */
+ CLAMP(dw->weight, 0.0f, 1.0f);
+ }
}
}
}
@@ -242,7 +253,7 @@ void defvert_normalize_subset(MDeformVert *dvert,
void defvert_normalize(MDeformVert *dvert)
{
- if (dvert->totweight <= 0) {
+ if (dvert->totweight == 0) {
/* nothing */
}
else if (dvert->totweight == 1) {
@@ -269,14 +280,20 @@ void defvert_normalize(MDeformVert *dvert)
}
}
-void defvert_normalize_lock_single(MDeformVert *dvert, const int def_nr_lock)
+/* Same as defvert_normalize() if the locked vgroup is not a member of the subset */
+void defvert_normalize_lock_single(MDeformVert *dvert,
+ const bool *vgroup_subset, const int vgroup_tot,
+ const int def_nr_lock)
{
- if (dvert->totweight <= 0) {
+ if (dvert->totweight == 0) {
/* nothing */
}
else if (dvert->totweight == 1) {
- if (def_nr_lock != 0) {
- dvert->dw[0].weight = 1.0f;
+ MDeformWeight *dw = dvert->dw;
+ if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
+ if (def_nr_lock != 0) {
+ dw->weight = 1.0f;
+ }
}
}
else {
@@ -287,13 +304,15 @@ void defvert_normalize_lock_single(MDeformVert *dvert, const int def_nr_lock)
float lock_iweight = 1.0f;
for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
- if (dw->def_nr != def_nr_lock) {
- tot_weight += dw->weight;
- }
- else {
- dw_lock = dw;
- lock_iweight = (1.0f - dw_lock->weight);
- CLAMP(lock_iweight, 0.0f, 1.0f);
+ if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
+ if (dw->def_nr != def_nr_lock) {
+ tot_weight += dw->weight;
+ }
+ else {
+ dw_lock = dw;
+ lock_iweight = (1.0f - dw_lock->weight);
+ CLAMP(lock_iweight, 0.0f, 1.0f);
+ }
}
}
@@ -302,25 +321,33 @@ void defvert_normalize_lock_single(MDeformVert *dvert, const int def_nr_lock)
float scalar = (1.0f / tot_weight) * lock_iweight;
for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
- if (dw != dw_lock) {
- dw->weight *= scalar;
+ if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
+ if (dw != dw_lock) {
+ dw->weight *= scalar;
- /* in case of division errors with very low weights */
- CLAMP(dw->weight, 0.0f, 1.0f);
+ /* in case of division errors with very low weights */
+ CLAMP(dw->weight, 0.0f, 1.0f);
+ }
}
}
}
}
}
-void defvert_normalize_lock_map(MDeformVert *dvert, const bool *lock_flags, const int defbase_tot)
+/* Same as defvert_normalize() if no locked vgroup is a member of the subset */
+void defvert_normalize_lock_map(MDeformVert *dvert,
+ const bool *vgroup_subset, const int vgroup_tot,
+ const bool *lock_flags, const int defbase_tot)
{
- if (dvert->totweight <= 0) {
+ if (dvert->totweight == 0) {
/* nothing */
}
else if (dvert->totweight == 1) {
- if (LIKELY(defbase_tot >= 1) && lock_flags[0]) {
- dvert->dw[0].weight = 1.0f;
+ MDeformWeight *dw = dvert->dw;
+ if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
+ if (LIKELY(defbase_tot >= 1) && lock_flags[0]) {
+ dw->weight = 1.0f;
+ }
}
}
else {
@@ -330,12 +357,14 @@ void defvert_normalize_lock_map(MDeformVert *dvert, const bool *lock_flags, cons
float lock_iweight = 0.0f;
for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
- if ((dw->def_nr < defbase_tot) && (lock_flags[dw->def_nr] == FALSE)) {
- tot_weight += dw->weight;
- }
- else {
- /* invert after */
- lock_iweight += dw->weight;
+ if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
+ if ((dw->def_nr < defbase_tot) && (lock_flags[dw->def_nr] == FALSE)) {
+ tot_weight += dw->weight;
+ }
+ else {
+ /* invert after */
+ lock_iweight += dw->weight;
+ }
}
}
@@ -346,11 +375,13 @@ void defvert_normalize_lock_map(MDeformVert *dvert, const bool *lock_flags, cons
float scalar = (1.0f / tot_weight) * lock_iweight;
for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
- if ((dw->def_nr < defbase_tot) && (lock_flags[dw->def_nr] == FALSE)) {
- dw->weight *= scalar;
+ if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
+ if ((dw->def_nr < defbase_tot) && (lock_flags[dw->def_nr] == FALSE)) {
+ dw->weight *= scalar;
- /* in case of division errors with very low weights */
- CLAMP(dw->weight, 0.0f, 1.0f);
+ /* in case of division errors with very low weights */
+ CLAMP(dw->weight, 0.0f, 1.0f);
+ }
}
}
}
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index 13181662bd8..cb7b4a32feb 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -2115,6 +2115,8 @@ void DAG_on_visible_update(Main *bmain, const short do_time)
if ((oblay & lay) & ~scene->lay_updated) {
if (ELEM6(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL, OB_LATTICE))
ob->recalc |= OB_RECALC_DATA;
+ if (ob->proxy && (ob->proxy_group == NULL))
+ ob->proxy->recalc |= OB_RECALC_DATA;
if (ob->dup_group)
dag_group_on_visible_update(ob->dup_group);
}
diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c
index 580172bcccd..fe9a96d60cf 100644
--- a/source/blender/blenkernel/intern/dynamicpaint.c
+++ b/source/blender/blenkernel/intern/dynamicpaint.c
@@ -98,12 +98,13 @@
#endif
/* precalculated gaussian factors for 5x super sampling */
-static float gaussianFactors[5] = {0.996849f,
- 0.596145f,
- 0.596145f,
- 0.596145f,
- 0.524141f};
-static float gaussianTotal = 3.309425f;
+static const float gaussianFactors[5] = {
+ 0.996849f,
+ 0.596145f,
+ 0.596145f,
+ 0.596145f,
+ 0.524141f};
+static const float gaussianTotal = 3.309425f;
/* UV Image neighboring pixel table x and y list */
static int neighX[8] = {1, 1, 0, -1, -1, -1, 0, 1};
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index 791c47cc551..dbdf30ea63d 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -688,21 +688,27 @@ short fcurve_are_keyframes_usable(FCurve *fcu)
return 1;
}
+bool BKE_fcurve_is_protected(FCurve *fcu)
+{
+ return ((fcu->flag & FCURVE_PROTECTED) ||
+ ((fcu->grp) && (fcu->grp->flag & AGRP_PROTECTED)));
+}
+
/* Can keyframes be added to F-Curve?
* Keyframes can only be added if they are already visible
*/
-short fcurve_is_keyframable(FCurve *fcu)
+bool fcurve_is_keyframable(FCurve *fcu)
{
/* F-Curve's keyframes must be "usable" (i.e. visible + have an effect on final result) */
if (fcurve_are_keyframes_usable(fcu) == 0)
- return 0;
+ return false;
/* F-Curve must currently be editable too */
- if ( (fcu->flag & FCURVE_PROTECTED) || ((fcu->grp) && (fcu->grp->flag & AGRP_PROTECTED)) )
- return 0;
+ if (BKE_fcurve_is_protected(fcu))
+ return false;
/* F-Curve is keyframable */
- return 1;
+ return true;
}
/* ***************************** Keyframe Column Tools ********************************* */
@@ -841,14 +847,7 @@ void calchandles_fcurve(FCurve *fcu)
}
}
-/* Use when F-Curve with handles has changed
- * It treats all BezTriples with the following rules:
- * - PHASE 1: do types have to be altered?
- * -> Auto handles: become aligned when selection status is NOT(000 || 111)
- * -> Vector handles: become 'nothing' when (one half selected AND other not)
- * - PHASE 2: recalculate handles
- */
-void testhandles_fcurve(FCurve *fcu, const short use_handle)
+void testhandles_fcurve(FCurve *fcu, const bool use_handle)
{
BezTriple *bezt;
unsigned int a;
@@ -856,45 +855,10 @@ void testhandles_fcurve(FCurve *fcu, const short use_handle)
/* only beztriples have handles (bpoints don't though) */
if (ELEM(NULL, fcu, fcu->bezt))
return;
-
+
/* loop over beztriples */
for (a = 0, bezt = fcu->bezt; a < fcu->totvert; a++, bezt++) {
- short flag = 0;
-
- /* flag is initialized as selection status
- * of beztriple control-points (labelled 0, 1, 2)
- */
- if (bezt->f2 & SELECT) flag |= (1 << 1); // == 2
- if (use_handle == FALSE) {
- if (flag & 2) {
- flag |= (1 << 0) | (1 << 2);
- }
- }
- else {
- if (bezt->f1 & SELECT) flag |= (1 << 0); // == 1
- if (bezt->f3 & SELECT) flag |= (1 << 2); // == 4
- }
-
- /* one or two handles selected only */
- if (ELEM(flag, 0, 7) == 0) {
- /* auto handles become aligned */
- if (ELEM(bezt->h1, HD_AUTO, HD_AUTO_ANIM))
- bezt->h1 = HD_ALIGN;
- if (ELEM(bezt->h2, HD_AUTO, HD_AUTO_ANIM))
- bezt->h2 = HD_ALIGN;
-
- /* vector handles become 'free' when only one half selected */
- if (bezt->h1 == HD_VECT) {
- /* only left half (1 or 2 or 1+2) */
- if (flag < 4)
- bezt->h1 = 0;
- }
- if (bezt->h2 == HD_VECT) {
- /* only right half (4 or 2+4) */
- if (flag > 3)
- bezt->h2 = 0;
- }
- }
+ BKE_nurb_bezt_handle_test(bezt, use_handle);
}
/* recalculate handles */
diff --git a/source/blender/blenkernel/intern/freestyle.c b/source/blender/blenkernel/intern/freestyle.c
index 1f106ff90a7..d87c93310c8 100644
--- a/source/blender/blenkernel/intern/freestyle.c
+++ b/source/blender/blenkernel/intern/freestyle.c
@@ -107,7 +107,8 @@ void BKE_freestyle_config_copy(FreestyleConfig *new_config, FreestyleConfig *con
static void copy_lineset(FreestyleLineSet *new_lineset, FreestyleLineSet *lineset)
{
new_lineset->linestyle = lineset->linestyle;
- new_lineset->linestyle->id.us++;
+ if (new_lineset->linestyle)
+ new_lineset->linestyle->id.us++;
new_lineset->flags = lineset->flags;
new_lineset->selection = lineset->selection;
new_lineset->qi = lineset->qi;
diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index 31dd79e7623..4d17bd286b4 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -42,6 +42,7 @@
#include "BLF_translation.h"
#include "DNA_gpencil_types.h"
+#include "DNA_userdef_types.h"
#include "BKE_global.h"
#include "BKE_gpencil.h"
@@ -125,8 +126,8 @@ bGPDframe *gpencil_frame_addnew(bGPDlayer *gpl, int cframe)
bGPDframe *gpf, *gf;
short state = 0;
- /* error checking */
- if ((gpl == NULL) || (cframe <= 0))
+ /* error checking (neg frame only if they are not allowed in Blender!) */
+ if ((gpl == NULL) || ((U.flag & USER_NONEGFRAMES) && (cframe <= 0)))
return NULL;
/* allocate memory for this frame */
@@ -349,7 +350,8 @@ bGPDframe *gpencil_layer_getframe(bGPDlayer *gpl, int cframe, short addnew)
/* error checking */
if (gpl == NULL) return NULL;
- if (cframe <= 0) cframe = 1;
+ /* No reason to forbid negative frames when they are allowed in Blender! */
+ if ((U.flag & USER_NONEGFRAMES) && cframe <= 0) cframe = 1;
/* check if there is already an active frame */
if (gpl->actframe) {
diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c
index 2e32c18b264..6f275e4ec75 100644
--- a/source/blender/blenkernel/intern/idprop.c
+++ b/source/blender/blenkernel/intern/idprop.c
@@ -56,7 +56,13 @@ static char idp_size_table[] = {
sizeof(double)
};
-/* ------------Property Array Type ----------- */
+
+/* -------------------------------------------------------------------- */
+/* Array Functions */
+
+/** \name IDP Array API
+ * \{ */
+
#define GETPROP(prop, i) (((IDProperty *)(prop)->data.pointer) + (i))
/* --------- property array type -------------*/
@@ -78,9 +84,12 @@ IDProperty *IDP_NewIDPArray(const char *name)
IDProperty *IDP_CopyIDPArray(IDProperty *array)
{
/* don't use MEM_dupallocN because this may be part of an array */
- IDProperty *narray = MEM_mallocN(sizeof(IDProperty), "IDP_CopyIDPArray"), *tmp;
+ IDProperty *narray, *tmp;
int i;
+ BLI_assert(array->type == IDP_IDPARRAY);
+
+ narray = MEM_mallocN(sizeof(IDProperty), __func__);
*narray = *array;
narray->data.pointer = MEM_dupallocN(array->data.pointer);
@@ -103,6 +112,8 @@ void IDP_FreeIDPArray(IDProperty *prop)
{
int i;
+ BLI_assert(prop->type == IDP_IDPARRAY);
+
for (i = 0; i < prop->len; i++)
IDP_FreeProperty(GETPROP(prop, i));
@@ -113,7 +124,11 @@ void IDP_FreeIDPArray(IDProperty *prop)
/*shallow copies item*/
void IDP_SetIndexArray(IDProperty *prop, int index, IDProperty *item)
{
- IDProperty *old = GETPROP(prop, index);
+ IDProperty *old;
+
+ BLI_assert(prop->type == IDP_IDPARRAY);
+
+ old = GETPROP(prop, index);
if (index >= prop->len || index < 0) return;
if (item != old) IDP_FreeProperty(old);
@@ -122,11 +137,15 @@ void IDP_SetIndexArray(IDProperty *prop, int index, IDProperty *item)
IDProperty *IDP_GetIndexArray(IDProperty *prop, int index)
{
+ BLI_assert(prop->type == IDP_IDPARRAY);
+
return GETPROP(prop, index);
}
void IDP_AppendArray(IDProperty *prop, IDProperty *item)
{
+ BLI_assert(prop->type == IDP_IDPARRAY);
+
IDP_ResizeIDPArray(prop, prop->len + 1);
IDP_SetIndexArray(prop, prop->len - 1, item);
}
@@ -135,6 +154,8 @@ void IDP_ResizeIDPArray(IDProperty *prop, int newlen)
{
int newsize;
+ BLI_assert(prop->type == IDP_IDPARRAY);
+
/* first check if the array buffer size has room */
/* if newlen is 200 items less then totallen, reallocate anyway */
if (newlen <= prop->totallen) {
@@ -286,8 +307,14 @@ static IDProperty *IDP_CopyArray(IDProperty *prop)
return newp;
}
+/** \} */
+
-/* ---------- String Type ------------ */
+/* -------------------------------------------------------------------- */
+/* String Functions */
+
+/** \name IDProperty String API
+ * \{ */
/**
*
@@ -327,9 +354,13 @@ IDProperty *IDP_NewString(const char *st, const char *name, int maxlen)
static IDProperty *IDP_CopyString(IDProperty *prop)
{
- IDProperty *newp = idp_generic_copy(prop);
+ IDProperty *newp;
+
+ BLI_assert(prop->type == IDP_STRING);
+ newp = idp_generic_copy(prop);
- if (prop->data.pointer) newp->data.pointer = MEM_dupallocN(prop->data.pointer);
+ if (prop->data.pointer)
+ newp->data.pointer = MEM_dupallocN(prop->data.pointer);
newp->len = prop->len;
newp->subtype = prop->subtype;
newp->totallen = prop->totallen;
@@ -340,8 +371,10 @@ static IDProperty *IDP_CopyString(IDProperty *prop)
void IDP_AssignString(IDProperty *prop, const char *st, int maxlen)
{
- int stlen = strlen(st);
+ int stlen;
+ BLI_assert(prop->type == IDP_STRING);
+ stlen = strlen(st);
if (maxlen > 0 && maxlen < stlen)
stlen = maxlen;
@@ -360,6 +393,8 @@ void IDP_ConcatStringC(IDProperty *prop, const char *st)
{
int newlen;
+ BLI_assert(prop->type == IDP_STRING);
+
newlen = prop->len + strlen(st);
/* we have to remember that prop->len includes the null byte for strings.
* so there's no need to add +1 to the resize function.*/
@@ -371,6 +406,8 @@ void IDP_ConcatString(IDProperty *str1, IDProperty *append)
{
int newlen;
+ BLI_assert(append->type == IDP_STRING);
+
/* since ->len for strings includes the NULL byte, we have to subtract one or
* we'll get an extra null byte after each concatenation operation.*/
newlen = str1->len + append->len - 1;
@@ -380,13 +417,19 @@ void IDP_ConcatString(IDProperty *str1, IDProperty *append)
void IDP_FreeString(IDProperty *prop)
{
+ BLI_assert(prop->type == IDP_STRING);
+
if (prop->data.pointer)
MEM_freeN(prop->data.pointer);
}
+/** \} */
-/*-------- ID Type, not in use yet -------*/
+/* -------------------------------------------------------------------- */
+/* ID Type (not in use yet) */
+/** \name IDProperty ID API (unused)
+ * \{ */
void IDP_LinkID(IDProperty *prop, ID *id)
{
if (prop->data.pointer) ((ID *)prop->data.pointer)->us--;
@@ -398,15 +441,26 @@ void IDP_UnlinkID(IDProperty *prop)
{
((ID *)prop->data.pointer)->us--;
}
+/** \} */
+
-/*-------- Group Functions -------*/
+/* -------------------------------------------------------------------- */
+/* Group Functions */
-/*checks if a property with the same name as prop exists, and if so replaces it.*/
+/** \name IDProperty Group API
+ * \{ */
+
+/**
+ * Checks if a property with the same name as prop exists, and if so replaces it.
+ */
static IDProperty *IDP_CopyGroup(IDProperty *prop)
{
- IDProperty *newp = idp_generic_copy(prop), *link;
- newp->len = prop->len;
+ IDProperty *newp, *link;
+ BLI_assert(prop->type == IDP_GROUP);
+ newp = idp_generic_copy(prop);
+ newp->len = prop->len;
+
for (link = prop->data.group.first; link; link = link->next) {
BLI_addtail(&newp->data.group, IDP_CopyProperty(link));
}
@@ -419,6 +473,10 @@ static IDProperty *IDP_CopyGroup(IDProperty *prop)
void IDP_SyncGroupValues(IDProperty *dest, IDProperty *src)
{
IDProperty *other, *prop;
+
+ BLI_assert(dest->type == IDP_GROUP);
+ BLI_assert(src->type == IDP_GROUP);
+
for (prop = src->data.group.first; prop; prop = prop->next) {
other = BLI_findstring(&dest->data.group, prop->name, offsetof(IDProperty, name));
if (other && prop->type == other->type) {
@@ -454,6 +512,10 @@ void IDP_SyncGroupValues(IDProperty *dest, IDProperty *src)
void IDP_ReplaceGroupInGroup(IDProperty *dest, IDProperty *src)
{
IDProperty *loop, *prop;
+
+ BLI_assert(dest->type == IDP_GROUP);
+ BLI_assert(src->type == IDP_GROUP);
+
for (prop = src->data.group.first; prop; prop = prop->next) {
for (loop = dest->data.group.first; loop; loop = loop->next) {
if (STREQ(loop->name, prop->name)) {
@@ -484,6 +546,9 @@ void IDP_ReplaceGroupInGroup(IDProperty *dest, IDProperty *src)
void IDP_ReplaceInGroup(IDProperty *group, IDProperty *prop)
{
IDProperty *loop;
+
+ BLI_assert(group->type == IDP_GROUP);
+
if ((loop = IDP_GetPropertyFromGroup(group, prop->name))) {
BLI_insertlinkafter(&group->data.group, loop, prop);
@@ -497,13 +562,16 @@ void IDP_ReplaceInGroup(IDProperty *group, IDProperty *prop)
}
}
-/*
+/**
* If a property is missing in \a dest, add it.
*/
void IDP_MergeGroup(IDProperty *dest, IDProperty *src, const int do_overwrite)
{
IDProperty *prop;
+ BLI_assert(dest->type == IDP_GROUP);
+ BLI_assert(src->type == IDP_GROUP);
+
if (do_overwrite) {
for (prop = src->data.group.first; prop; prop = prop->next) {
IDProperty *copy = IDP_CopyProperty(prop);
@@ -538,6 +606,8 @@ void IDP_MergeGroup(IDProperty *dest, IDProperty *src, const int do_overwrite)
*/
int IDP_AddToGroup(IDProperty *group, IDProperty *prop)
{
+ BLI_assert(group->type == IDP_GROUP);
+
if (IDP_GetPropertyFromGroup(group, prop->name) == NULL) {
group->len++;
BLI_addtail(&group->data.group, prop);
@@ -553,6 +623,8 @@ int IDP_AddToGroup(IDProperty *group, IDProperty *prop)
*/
int IDP_InsertToGroup(IDProperty *group, IDProperty *previous, IDProperty *pnew)
{
+ BLI_assert(group->type == IDP_GROUP);
+
if (IDP_GetPropertyFromGroup(group, pnew->name) == NULL) {
group->len++;
BLI_insertlinkafter(&group->data.group, previous, pnew);
@@ -571,12 +643,16 @@ int IDP_InsertToGroup(IDProperty *group, IDProperty *previous, IDProperty *pnew)
*/
void IDP_RemFromGroup(IDProperty *group, IDProperty *prop)
{
+ BLI_assert(group->type == IDP_GROUP);
+
group->len--;
BLI_remlink(&group->data.group, prop);
}
IDProperty *IDP_GetPropertyFromGroup(IDProperty *prop, const char *name)
{
+ BLI_assert(prop->type == IDP_GROUP);
+
return (IDProperty *)BLI_findstring(&prop->data.group, name, offsetof(IDProperty, name));
}
/** same as above but ensure type match */
@@ -599,7 +675,10 @@ typedef struct IDPIter {
*/
void *IDP_GetGroupIterator(IDProperty *prop)
{
- IDPIter *iter = MEM_callocN(sizeof(IDPIter), "IDPIter");
+ IDPIter *iter;
+
+ BLI_assert(prop->type == IDP_GROUP);
+ iter = MEM_mallocN(sizeof(IDPIter), "IDPIter");
iter->next = prop->data.group.first;
iter->parent = prop;
return (void *) iter;
@@ -640,14 +719,21 @@ void IDP_FreeIterBeforeEnd(void *vself)
static void IDP_FreeGroup(IDProperty *prop)
{
IDProperty *loop;
+
+ BLI_assert(prop->type == IDP_GROUP);
for (loop = prop->data.group.first; loop; loop = loop->next) {
IDP_FreeProperty(loop);
}
BLI_freelistN(&prop->data.group);
}
+/** \} */
-/*-------- Main Functions --------*/
+/* -------------------------------------------------------------------- */
+/* Main Functions */
+
+/** \name IDProperty Main API
+ * \{ */
IDProperty *IDP_CopyProperty(IDProperty *prop)
{
switch (prop->type) {
@@ -909,3 +995,5 @@ void IDP_UnlinkProperty(IDProperty *prop)
break;
}
}
+
+/** \} */
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index 2bf6304b04b..01b41eb22cd 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -1250,6 +1250,12 @@ static int do_add_image_extension(char *string, const char imtype, const ImageFo
}
}
#endif
+#ifdef WITH_OPENIMAGEIO
+ else if (imtype == R_IMF_IMTYPE_PSD) {
+ if (!BLI_testextensie(string, ".psd"))
+ extension = ".psd";
+ }
+#endif
#ifdef WITH_OPENEXR
else if (ELEM(imtype, R_IMF_IMTYPE_OPENEXR, R_IMF_IMTYPE_MULTILAYER)) {
if (!BLI_testextensie(string, ".exr"))
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index c23fa097d3e..9b8d34e651d 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -269,7 +269,8 @@ bool id_make_local(ID *id, bool test)
if (!test) BKE_action_make_local((bAction *)id);
return true;
case ID_NT:
- return false; /* not implemented */
+ if (!test) ntreeMakeLocal((bNodeTree *)id);
+ return true;
case ID_BR:
if (!test) BKE_brush_make_local((Brush *)id);
return true;
@@ -1410,7 +1411,7 @@ bool new_id(ListBase *lb, ID *id, const char *tname)
/* This was in 2.43 and previous releases
* however all data in blender should be sorted, not just duplicate names
- * sorting should not hurt, but noting just incause it alters the way other
+ * sorting should not hurt, but noting just incase it alters the way other
* functions work, so sort every time */
#if 0
if (result)
diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c
index 874e60936d1..a43bf41058c 100644
--- a/source/blender/blenkernel/intern/mask_rasterize.c
+++ b/source/blender/blenkernel/intern/mask_rasterize.c
@@ -409,7 +409,7 @@ static void layer_bucket_init_dummy(MaskRasterLayer *layer)
static void layer_bucket_init(MaskRasterLayer *layer, const float pixel_size)
{
- MemArena *arena = BLI_memarena_new(1 << 16, __func__);
+ MemArena *arena = BLI_memarena_new(MEM_SIZE_OPTIMAL(1 << 16), __func__);
const float bucket_dim_x = BLI_rctf_size_x(&layer->bounds);
const float bucket_dim_y = BLI_rctf_size_y(&layer->bounds);
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index 63a7b8cd982..a77f768835a 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -40,6 +40,8 @@
#include "BLI_math.h"
#include "BLI_listbase.h"
#include "BLI_edgehash.h"
+#include "BLI_string_utf8.h"
+#include "BLI_string.h"
#include "BKE_animsys.h"
#include "BKE_main.h"
@@ -528,8 +530,9 @@ Mesh *BKE_mesh_copy(Mesh *me)
BMesh *BKE_mesh_to_bmesh(Mesh *me, Object *ob)
{
BMesh *bm;
+ const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(me);
- bm = BM_mesh_create(&bm_mesh_allocsize_default);
+ bm = BM_mesh_create(&allocsize);
BM_mesh_bm_from_me(bm, me, false, true, ob->shapenr);
@@ -622,6 +625,113 @@ void BKE_mesh_make_local(Mesh *me)
}
}
+bool BKE_mesh_uv_cdlayer_rename_index(Mesh *me, const int poly_index, const int loop_index, const int face_index,
+ const char *new_name, const bool do_tessface)
+{
+ CustomData *pdata, *ldata, *fdata;
+ CustomDataLayer *cdlp, *cdlu, *cdlf;
+ const int step = do_tessface ? 3 : 2;
+ int i;
+
+ if (me->edit_btmesh) {
+ pdata = &me->edit_btmesh->bm->pdata;
+ ldata = &me->edit_btmesh->bm->ldata;
+ fdata = NULL; /* No tessellated data in BMesh! */
+ }
+ else {
+ pdata = &me->pdata;
+ ldata = &me->ldata;
+ fdata = &me->fdata;
+ }
+ cdlp = &pdata->layers[poly_index];
+ cdlu = &ldata->layers[loop_index];
+ cdlf = fdata && do_tessface ? &fdata->layers[face_index] : NULL;
+
+ BLI_strncpy(cdlp->name, new_name, sizeof(cdlp->name));
+ CustomData_set_layer_unique_name(pdata, cdlp - pdata->layers);
+
+ /* Loop until we do have exactly the same name for all layers! */
+ for (i = 1; (strcmp(cdlp->name, cdlu->name) != 0 || (cdlf && strcmp(cdlp->name, cdlf->name) != 0)); i++) {
+ switch (i % step) {
+ case 0:
+ BLI_strncpy(cdlp->name, cdlu->name, sizeof(cdlp->name));
+ CustomData_set_layer_unique_name(pdata, cdlp - pdata->layers);
+ break;
+ case 1:
+ BLI_strncpy(cdlu->name, cdlp->name, sizeof(cdlu->name));
+ CustomData_set_layer_unique_name(ldata, cdlu - ldata->layers);
+ break;
+ case 2:
+ if (cdlf) {
+ BLI_strncpy(cdlf->name, cdlp->name, sizeof(cdlf->name));
+ CustomData_set_layer_unique_name(fdata, cdlf - fdata->layers);
+ }
+ break;
+ }
+ }
+
+ return true;
+}
+
+bool BKE_mesh_uv_cdlayer_rename(Mesh *me, const char *old_name, const char *new_name, bool do_tessface)
+{
+ CustomData *pdata, *ldata, *fdata;
+ if (me->edit_btmesh) {
+ pdata = &me->edit_btmesh->bm->pdata;
+ ldata = &me->edit_btmesh->bm->ldata;
+ /* No tessellated data in BMesh! */
+ fdata = NULL;
+ do_tessface = false;
+ }
+ else {
+ pdata = &me->pdata;
+ ldata = &me->ldata;
+ fdata = &me->fdata;
+ do_tessface = (do_tessface && fdata->totlayer);
+ }
+
+ {
+ const int pidx_start = CustomData_get_layer_index(pdata, CD_MTEXPOLY);
+ const int lidx_start = CustomData_get_layer_index(ldata, CD_MLOOPUV);
+ const int fidx_start = do_tessface ? CustomData_get_layer_index(fdata, CD_MTFACE) : -1;
+ int pidx = CustomData_get_named_layer(pdata, CD_MTEXPOLY, old_name);
+ int lidx = CustomData_get_named_layer(ldata, CD_MLOOPUV, old_name);
+ int fidx = do_tessface ? CustomData_get_named_layer(fdata, CD_MTFACE, old_name) : -1;
+
+ /* None of those cases should happen, in theory!
+ * Note this assume we have the same number of mtexpoly, mloopuv and mtface layers!
+ */
+ if (pidx == -1) {
+ if (lidx == -1) {
+ if (fidx == -1) {
+ /* No layer found with this name! */
+ return false;
+ }
+ else {
+ lidx = lidx_start + (fidx - fidx_start);
+ }
+ }
+ pidx = pidx_start + (lidx - lidx_start);
+ }
+ else {
+ if (lidx == -1) {
+ lidx = lidx_start + (pidx - pidx_start);
+ }
+ if (fidx == -1 && do_tessface) {
+ fidx = fidx_start + (pidx - pidx_start);
+ }
+ }
+#if 0
+ /* For now, we do not consider mismatch in indices (i.e. same name leading to (relative) different indices). */
+ else if ((pidx - pidx_start) != (lidx - lidx_start)) {
+ lidx = lidx_start + (pidx - pidx_start);
+ }
+#endif
+
+ return BKE_mesh_uv_cdlayer_rename_index(me, pidx, lidx, fidx, new_name, do_tessface);
+ }
+}
+
void BKE_mesh_boundbox_calc(Mesh *me, float r_loc[3], float r_size[3])
{
BoundBox *bb;
diff --git a/source/blender/blenkernel/intern/mesh_evaluate.c b/source/blender/blenkernel/intern/mesh_evaluate.c
index 07dfae2f28a..47b8e053bf7 100644
--- a/source/blender/blenkernel/intern/mesh_evaluate.c
+++ b/source/blender/blenkernel/intern/mesh_evaluate.c
@@ -318,9 +318,9 @@ void BKE_mesh_calc_normals_tessface(MVert *mverts, int numVerts, MFace *mfaces,
* Compute split normals, i.e. vertex normals associated with each poly (hence 'loop normals').
* Useful to materialize sharp edges (or non-smooth faces) without actually modifying the geometry (splitting edges).
*/
-void BKE_mesh_normals_loop_split(MVert *mverts, int UNUSED(numVerts), MEdge *medges, int numEdges,
- MLoop *mloops, float (*r_loopnors)[3], int numLoops,
- MPoly *mpolys, float (*polynors)[3], int numPolys, float split_angle)
+void BKE_mesh_normals_loop_split(MVert *mverts, const int UNUSED(numVerts), MEdge *medges, const int numEdges,
+ MLoop *mloops, float (*r_loopnors)[3], const int numLoops,
+ MPoly *mpolys, float (*polynors)[3], const int numPolys, float split_angle)
{
#define INDEX_UNSET INT_MIN
#define INDEX_INVALID -1
@@ -333,7 +333,7 @@ void BKE_mesh_normals_loop_split(MVert *mverts, int UNUSED(numVerts), MEdge *med
* sharp edge: < 0 (INDEX_INVALID || INDEX_UNSET),
* unset: INDEX_UNSET
* Note that currently we only have two values for second loop of sharp edges. However, if needed, we can
- * store the negated value of loop index instead of INDEX_INVALID to retrieve th real value later in code).
+ * store the negated value of loop index instead of INDEX_INVALID to retrieve the real value later in code).
* Note also that lose edges always have both values set to 0!
*/
int (*edge_to_loops)[2] = MEM_callocN(sizeof(int[2]) * (size_t)numEdges, __func__);
@@ -377,7 +377,7 @@ void BKE_mesh_normals_loop_split(MVert *mverts, int UNUSED(numVerts), MEdge *med
/* Check whether current edge might be smooth or sharp */
if ((e2l[0] | e2l[1]) == 0) {
- /* 'Empty' edge until now, set e2l[0] (and e2l[1] to INT_MIN to tag it as unset). */
+ /* 'Empty' edge until now, set e2l[0] (and e2l[1] to INDEX_UNSET to tag it as unset). */
e2l[0] = ml_curr_index;
e2l[1] = INDEX_UNSET;
}
@@ -397,7 +397,7 @@ void BKE_mesh_normals_loop_split(MVert *mverts, int UNUSED(numVerts), MEdge *med
}
}
else if (!IS_EDGE_SHARP(e2l)) {
- /* More that two loops using this edge, tag as sharp if not yet done. */
+ /* More than two loops using this edge, tag as sharp if not yet done. */
e2l[1] = INDEX_INVALID;
}
/* Else, edge is already 'disqualified' (i.e. sharp)! */
@@ -448,6 +448,7 @@ void BKE_mesh_normals_loop_split(MVert *mverts, int UNUSED(numVerts), MEdge *med
* it should not be a common case in real-life meshes anyway).
*/
const unsigned int mv_pivot_index = ml_curr->v; /* The vertex we are "fanning" around! */
+ const MVert *mv_pivot = &mverts[mv_pivot_index];
const int *e2lfan_curr;
float vec_curr[3], vec_prev[3];
MLoop *mlfan_curr, *mlfan_next;
@@ -464,11 +465,10 @@ void BKE_mesh_normals_loop_split(MVert *mverts, int UNUSED(numVerts), MEdge *med
/* Only need to compute previous edge's vector once, then we can just reuse old current one! */
{
- const MEdge *me_prev = &medges[ml_prev->e];
- const MVert *mv_1 = &mverts[mv_pivot_index];
+ const MEdge *me_prev = &medges[ml_curr->e]; /* ml_curr would be mlfan_prev if we needed that one */
const MVert *mv_2 = (me_prev->v1 == mv_pivot_index) ? &mverts[me_prev->v2] : &mverts[me_prev->v1];
- sub_v3_v3v3(vec_prev, mv_2->co, mv_1->co);
+ sub_v3_v3v3(vec_prev, mv_2->co, mv_pivot->co);
normalize_v3(vec_prev);
}
@@ -479,12 +479,11 @@ void BKE_mesh_normals_loop_split(MVert *mverts, int UNUSED(numVerts), MEdge *med
* given the fact that this code should not be called that much in real-life meshes...
*/
{
- const MEdge *me_curr = &medges[ml_curr->e];
- const MVert *mv_1 = &mverts[mv_pivot_index];
+ const MEdge *me_curr = &medges[mlfan_curr->e];
const MVert *mv_2 = (me_curr->v1 == mv_pivot_index) ? &mverts[me_curr->v2] :
&mverts[me_curr->v1];
- sub_v3_v3v3(vec_curr, mv_2->co, mv_1->co);
+ sub_v3_v3v3(vec_curr, mv_2->co, mv_pivot->co);
normalize_v3(vec_curr);
}
diff --git a/source/blender/blenkernel/intern/mesh_validate.c b/source/blender/blenkernel/intern/mesh_validate.c
index 557d201e7fd..1c9576d74d0 100644
--- a/source/blender/blenkernel/intern/mesh_validate.c
+++ b/source/blender/blenkernel/intern/mesh_validate.c
@@ -989,28 +989,40 @@ void BKE_mesh_cd_validate(Mesh *me)
{
int totlayer_mtex = CustomData_number_of_layers(&me->pdata, CD_MTEXPOLY);
int totlayer_uv = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV);
+ int mtex_index = CustomData_get_layer_index(&me->pdata, CD_MTEXPOLY);
+ int uv_index = CustomData_get_layer_index(&me->ldata, CD_MLOOPUV);
+ int i;
if (LIKELY(totlayer_mtex == totlayer_uv)) {
/* pass */
}
else if (totlayer_mtex < totlayer_uv) {
- const int uv_index_first = CustomData_get_layer_index(&me->ldata, CD_MLOOPUV);
do {
- const char *from_name = me->ldata.layers[uv_index_first + totlayer_mtex].name;
+ const char *from_name = me->ldata.layers[uv_index + totlayer_mtex].name;
CustomData_add_layer_named(&me->pdata, CD_MTEXPOLY, CD_DEFAULT, NULL, me->totpoly, from_name);
CustomData_set_layer_unique_name(&me->pdata, totlayer_mtex);
} while (totlayer_uv != ++totlayer_mtex);
+ mtex_index = CustomData_get_layer_index(&me->pdata, CD_MTEXPOLY);
}
else if (totlayer_uv < totlayer_mtex) {
- const int mtex_index_first = CustomData_get_layer_index(&me->pdata, CD_MTEXPOLY);
do {
- const char *from_name = me->pdata.layers[mtex_index_first + totlayer_uv].name;
+ const char *from_name = me->pdata.layers[mtex_index + totlayer_uv].name;
CustomData_add_layer_named(&me->ldata, CD_MLOOPUV, CD_DEFAULT, NULL, me->totloop, from_name);
CustomData_set_layer_unique_name(&me->ldata, totlayer_uv);
} while (totlayer_mtex != ++totlayer_uv);
+ uv_index = CustomData_get_layer_index(&me->ldata, CD_MLOOPUV);
}
BLI_assert(totlayer_mtex == totlayer_uv);
+
+ /* Check uv/tex names match as well!!! */
+ for (i = 0; i < totlayer_mtex; i++, mtex_index++, uv_index++) {
+ const char *name_src = me->pdata.layers[mtex_index].name;
+ const char *name_dst = me->ldata.layers[uv_index].name;
+ if (!STREQ(name_src, name_dst)) {
+ BKE_mesh_uv_cdlayer_rename_index(me, mtex_index, uv_index, -1, name_src, false);
+ }
+ }
}
/** \} */
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index 780bd9733f5..4871b9bf3bf 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -593,21 +593,21 @@ bool modifiers_usesArmature(Object *ob, bArmature *arm)
bool modifier_isCorrectableDeformed(ModifierData *md)
{
- if (md->type == eModifierType_Armature)
- return true;
- if (md->type == eModifierType_ShapeKey)
- return true;
-
- return false;
+ ModifierTypeInfo *mti = modifierType_getInfo(md->type);
+ return (mti->deformMatricesEM != NULL);
}
-bool modifiers_isCorrectableDeformed(Object *ob)
+bool modifiers_isCorrectableDeformed(struct Scene *scene, Object *ob)
{
VirtualModifierData virtualModifierData;
ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData);
+ int required_mode = eModifierMode_Realtime;
+
+ if (ob->mode == OB_MODE_EDIT)
+ required_mode |= eModifierMode_Editmode;
for (; md; md = md->next) {
- if (ob->mode == OB_MODE_EDIT && (md->mode & eModifierMode_Editmode) == 0) {
+ if (!modifier_isEnabled(scene, md, required_mode)) {
/* pass */
}
else if (modifier_isCorrectableDeformed(md)) {
diff --git a/source/blender/blenkernel/intern/modifiers_bmesh.c b/source/blender/blenkernel/intern/modifiers_bmesh.c
index d1797810c86..a9ff569e70a 100644
--- a/source/blender/blenkernel/intern/modifiers_bmesh.c
+++ b/source/blender/blenkernel/intern/modifiers_bmesh.c
@@ -232,8 +232,9 @@ BMEditMesh *DM_to_editbmesh(DerivedMesh *dm, BMEditMesh *existing, const bool do
BMesh *DM_to_bmesh(DerivedMesh *dm, const bool calc_face_normal)
{
BMesh *bm;
+ const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_DM(dm);
- bm = BM_mesh_create(&bm_mesh_allocsize_default);
+ bm = BM_mesh_create(&allocsize);
DM_to_bmesh_ex(dm, bm, calc_face_normal);
diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c
index bf4a63c52a8..d9630a7343d 100644
--- a/source/blender/blenkernel/intern/movieclip.c
+++ b/source/blender/blenkernel/intern/movieclip.c
@@ -62,7 +62,6 @@
#include "BLI_blenlib.h"
#include "BLI_ghash.h"
#include "BLI_math.h"
-#include "BLI_mempool.h"
#include "BLI_threads.h"
#include "BKE_animsys.h"
diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c
index 4519a116946..0cdcf4e7298 100644
--- a/source/blender/blenkernel/intern/multires.c
+++ b/source/blender/blenkernel/intern/multires.c
@@ -114,8 +114,8 @@ static BLI_bitmap *multires_mdisps_upsample_hidden(BLI_bitmap *lo_hidden,
BLI_bitmap *prev_hidden)
{
BLI_bitmap *subd;
- int hi_gridsize = ccg_gridsize(hi_level);
- int lo_gridsize = ccg_gridsize(lo_level);
+ int hi_gridsize = BKE_ccg_gridsize(hi_level);
+ int lo_gridsize = BKE_ccg_gridsize(lo_level);
int yh, xh, xl, yl, xo, yo, hi_ndx;
int offset, factor;
@@ -127,7 +127,7 @@ static BLI_bitmap *multires_mdisps_upsample_hidden(BLI_bitmap *lo_hidden,
subd = BLI_BITMAP_NEW(hi_gridsize * hi_gridsize, "MDisps.hidden upsample");
- factor = ccg_factor(lo_level, hi_level);
+ factor = BKE_ccg_factor(lo_level, hi_level);
offset = 1 << (hi_level - lo_level - 1);
/* low-res blocks */
@@ -173,12 +173,12 @@ static BLI_bitmap *multires_mdisps_downsample_hidden(BLI_bitmap *old_hidden,
int new_level)
{
BLI_bitmap *new_hidden;
- int new_gridsize = ccg_gridsize(new_level);
- int old_gridsize = ccg_gridsize(old_level);
+ int new_gridsize = BKE_ccg_gridsize(new_level);
+ int old_gridsize = BKE_ccg_gridsize(old_level);
int x, y, factor, old_value;
BLI_assert(new_level <= old_level);
- factor = ccg_factor(new_level, old_level);
+ factor = BKE_ccg_factor(new_level, old_level);
new_hidden = BLI_BITMAP_NEW(new_gridsize * new_gridsize,
"downsample hidden");
@@ -246,7 +246,7 @@ static MDisps *multires_mdisps_initialize_hidden(Mesh *me, int level)
{
MDisps *mdisps = CustomData_add_layer(&me->ldata, CD_MDISPS,
CD_CALLOC, NULL, me->totloop);
- int gridsize = ccg_gridsize(level);
+ int gridsize = BKE_ccg_gridsize(level);
int gridarea = gridsize * gridsize;
int i, j, k;
@@ -594,7 +594,7 @@ static void multires_copy_dm_grid(CCGElem *gridA, CCGElem *gridB, CCGKey *keyA,
static void multires_grid_paint_mask_downsample(GridPaintMask *gpm, int level)
{
if (level < gpm->level) {
- int gridsize = ccg_gridsize(level);
+ int gridsize = BKE_ccg_gridsize(level);
float *data = MEM_callocN(sizeof(float) * gridsize * gridsize,
"multires_grid_paint_mask_downsample");
int x, y;
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index 2305c0696af..c0df306a3fa 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -1107,7 +1107,7 @@ bNodeTree *ntreeAddTree(Main *bmain, const char *name, const char *idname)
* copying for internal use (threads for eg), where you wont want it to modify the
* scene data.
*/
-static bNodeTree *ntreeCopyTree_internal(bNodeTree *ntree, const short do_id_user, const short do_make_extern, const short copy_previews)
+static bNodeTree *ntreeCopyTree_internal(bNodeTree *ntree, Main *bmain, bool do_id_user, bool do_make_extern, bool copy_previews)
{
bNodeTree *newtree;
bNode *node /*, *nnode */ /* UNUSED */, *last;
@@ -1116,13 +1116,17 @@ static bNodeTree *ntreeCopyTree_internal(bNodeTree *ntree, const short do_id_use
if (ntree == NULL) return NULL;
- /* is ntree part of library? */
- for (newtree = G.main->nodetree.first; newtree; newtree = newtree->id.next)
- if (newtree == ntree) break;
- if (newtree) {
- newtree = BKE_libblock_copy(&ntree->id);
+ if (bmain) {
+ /* is ntree part of library? */
+ if (BLI_findindex(&bmain->nodetree, ntree) != -1)
+ newtree = BKE_libblock_copy(&ntree->id);
+ else
+ newtree = NULL;
}
- else {
+ else
+ newtree = NULL;
+
+ if (newtree == NULL) {
newtree = MEM_dupallocN(ntree);
newtree->id.lib = NULL; /* same as owning datablock id.lib */
BKE_libblock_copy_data(&newtree->id, &ntree->id, true); /* copy animdata and ID props */
@@ -1208,7 +1212,7 @@ static bNodeTree *ntreeCopyTree_internal(bNodeTree *ntree, const short do_id_use
bNodeTree *ntreeCopyTree_ex(bNodeTree *ntree, const short do_id_user)
{
- return ntreeCopyTree_internal(ntree, do_id_user, TRUE, TRUE);
+ return ntreeCopyTree_internal(ntree, G.main, do_id_user, TRUE, TRUE);
}
bNodeTree *ntreeCopyTree(bNodeTree *ntree)
{
@@ -1590,6 +1594,8 @@ static void node_unlink_attached(bNodeTree *ntree, bNode *parent)
void nodeFreeNode(bNodeTree *ntree, bNode *node)
{
bNodeSocket *sock, *nextsock;
+ char propname_esc[MAX_IDPROP_NAME * 2];
+ char prefix[MAX_IDPROP_NAME * 2];
/* extra free callback */
if (node->typeinfo && node->typeinfo->freefunc_api) {
@@ -1609,6 +1615,11 @@ void nodeFreeNode(bNodeTree *ntree, bNode *node)
BLI_remlink(&ntree->nodes, node);
+ BLI_strescape(propname_esc, node->name, sizeof(propname_esc));
+ BLI_snprintf(prefix, sizeof(prefix), "nodes[\"%s\"]", propname_esc);
+
+ BKE_animdata_fix_paths_remove((ID *)ntree, prefix);
+
if (ntree->typeinfo && ntree->typeinfo->free_node_cache)
ntree->typeinfo->free_node_cache(ntree, node);
@@ -1657,6 +1668,22 @@ static void node_socket_interface_free(bNodeTree *UNUSED(ntree), bNodeSocket *so
MEM_freeN(sock->default_value);
}
+static void free_localized_node_groups(bNodeTree *ntree)
+{
+ bNode *node;
+
+ for (node = ntree->nodes.first; node; node = node->next) {
+ if (node->type == NODE_GROUP && node->id) {
+ bNodeTree *ngroup = (bNodeTree *)node->id;
+ if (BLI_findindex(&G.main->nodetree, ngroup) == -1) {
+ /* ntree is not in library, i.e. localized node group: free it */
+ ntreeFreeTree_ex(ngroup, false);
+ MEM_freeN(ngroup);
+ }
+ }
+ }
+}
+
/* do not free ntree itself here, BKE_libblock_free calls this function too */
void ntreeFreeTree_ex(bNodeTree *ntree, const short do_id_user)
{
@@ -1683,6 +1710,9 @@ void ntreeFreeTree_ex(bNodeTree *ntree, const short do_id_user)
}
}
+ /* XXX not nice, but needed to free localized node groups properly */
+ free_localized_node_groups(ntree);
+
/* unregister associated RNA types */
ntreeInterfaceTypeFree(ntree);
@@ -1932,8 +1962,14 @@ bNodeTree *ntreeLocalize(bNodeTree *ntree)
/* Make full copy.
* Note: previews are not copied here.
*/
- ltree = ntreeCopyTree_internal(ntree, FALSE, FALSE, FALSE);
-
+ ltree = ntreeCopyTree_internal(ntree, NULL, FALSE, FALSE, FALSE);
+
+ for (node = ltree->nodes.first; node; node = node->next) {
+ if (node->type == NODE_GROUP && node->id) {
+ node->id = (ID *)ntreeLocalize((bNodeTree *)node->id);
+ }
+ }
+
if (adt) {
AnimData *ladt = BKE_animdata_from_id(&ltree->id);
@@ -1978,7 +2014,7 @@ void ntreeLocalSync(bNodeTree *localtree, bNodeTree *ntree)
/* we have to assume the editor already changed completely */
void ntreeLocalMerge(bNodeTree *localtree, bNodeTree *ntree)
{
- if (localtree && ntree) {
+ if (ntree && localtree) {
if (ntree->typeinfo->local_merge)
ntree->typeinfo->local_merge(localtree, ntree);
@@ -2285,7 +2321,7 @@ bNode *nodeGetActive(bNodeTree *ntree)
static bNode *node_get_active_id_recursive(bNodeInstanceKey active_key, bNodeInstanceKey parent_key, bNodeTree *ntree, short idtype)
{
- if (parent_key.value == active_key.value) {
+ if (parent_key.value == active_key.value || active_key.value == 0) {
bNode *node;
for (node = ntree->nodes.first; node; node = node->next)
if (node->id && GS(node->id->name) == idtype)
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 26890380f53..2b95b2346f6 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -652,7 +652,9 @@ void BKE_object_unlink(Object *ob)
for (lineset = (FreestyleLineSet *)srl->freestyleConfig.linesets.first;
lineset; lineset = lineset->next)
{
- BKE_unlink_linestyle_target_object(lineset->linestyle, ob);
+ if (lineset->linestyle) {
+ BKE_unlink_linestyle_target_object(lineset->linestyle, ob);
+ }
}
}
}
@@ -2990,21 +2992,20 @@ void BKE_object_handle_update_ex(Scene *scene, Object *ob,
/* quick cache removed */
}
- /* the no-group proxy case, we call update */
- if (ob->proxy && ob->proxy_group == NULL) {
- /* set pointer in library proxy target, for copying, but restore it */
- ob->proxy->proxy_from = ob;
- // printf("call update, lib ob %s proxy %s\n", ob->proxy->id.name, ob->id.name);
- BKE_object_handle_update(scene, ob->proxy);
- }
-
ob->recalc &= ~OB_RECALC_ALL;
}
/* the case when this is a group proxy, object_update is called in group.c */
if (ob->proxy) {
+ /* set pointer in library proxy target, for copying, but restore it */
ob->proxy->proxy_from = ob;
// printf("set proxy pointer for later group stuff %s\n", ob->id.name);
+
+ /* the no-group proxy case, we call update */
+ if (ob->proxy_group == NULL) {
+ // printf("call update, lib ob %s proxy %s\n", ob->proxy->id.name, ob->id.name);
+ BKE_object_handle_update(scene, ob->proxy);
+ }
}
}
/* WARNING: "scene" here may not be the scene object actually resides in.
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index b47a493581e..6bdfb22dc1a 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -359,8 +359,8 @@ int paint_is_bmesh_face_hidden(BMFace *f)
float paint_grid_paint_mask(const GridPaintMask *gpm, unsigned level,
unsigned x, unsigned y)
{
- int factor = ccg_factor(level, gpm->level);
- int gridsize = ccg_gridsize(gpm->level);
+ int factor = BKE_ccg_factor(level, gpm->level);
+ int gridsize = BKE_ccg_gridsize(gpm->level);
return gpm->data[(y * factor) * gridsize + (x * factor)];
}
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 216bc94a058..24cf98d957d 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -1729,7 +1729,7 @@ static int psys_map_index_on_dm(DerivedMesh *dm, int from, int index, int index_
return 0;
if (dm->deformedOnly || index_dmcache == DMCACHE_ISCHILD) {
- /* for meshes that are either only defined or for child particles, the
+ /* for meshes that are either only deformed or for child particles, the
* index and fw do not require any mapping, so we can directly use it */
if (from == PART_FROM_VERT) {
if (index >= dm->getNumVerts(dm))
@@ -1817,8 +1817,8 @@ void psys_particle_on_dm(DerivedMesh *dm, int from, int index, int index_dmcache
copy_v3_v3(orco, orcodata[mapindex]);
if (ornor) {
- dm->getVertNo(dm, mapindex, nor);
- normalize_v3(nor);
+ dm->getVertNo(dm, mapindex, ornor);
+ normalize_v3(ornor);
}
if (utan && vtan) {
@@ -1843,7 +1843,7 @@ void psys_particle_on_dm(DerivedMesh *dm, int from, int index, int index_dmcache
if (nor)
copy_v3_v3(nor, tmpnor);
- normalize_v3(tmpnor);
+ normalize_v3(tmpnor); /* XXX Why not normalize tmpnor before copying it into nor??? -- mont29 */
mul_v3_fl(tmpnor, -foffset);
add_v3_v3(vec, tmpnor);
}
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index db22e030821..526d54a97fa 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -3313,9 +3313,14 @@ static float collision_newton_rhapson(ParticleCollision *col, float radius, Part
pce->inv_nor = -1;
- /* Initial step size should be small, but not too small or floating point
- * precision errors will appear. - z0r */
- dt_init = COLLISION_INIT_STEP * col->inv_total_time;
+ if (col->inv_total_time > 0.0f) {
+ /* Initial step size should be small, but not too small or floating point
+ * precision errors will appear. - z0r */
+ dt_init = COLLISION_INIT_STEP * col->inv_total_time;
+ }
+ else {
+ dt_init = 0.001f;
+ }
/* start from the beginning */
t0 = 0.f;
diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c
index c83d760797b..deb77d14988 100644
--- a/source/blender/blenkernel/intern/pbvh_bmesh.c
+++ b/source/blender/blenkernel/intern/pbvh_bmesh.c
@@ -438,10 +438,6 @@ static void pbvh_bmesh_face_remove(PBVH *bvh, BMFace *f)
if (new_node) {
pbvh_bmesh_vert_ownership_transfer(bvh, new_node, v);
}
- else {
- BLI_gset_remove(f_node->bm_unique_verts, v, NULL);
- BLI_ghash_remove(bvh->bm_vert_to_node, v, NULL, NULL);
- }
}
else {
/* Remove from other verts */
@@ -516,10 +512,10 @@ static int edge_queue_tri_in_sphere(const EdgeQueue *q, BMFace *f)
return ((len_squared_v3v3(q->center, c) <= q->radius_squared));
}
-/* Return true if the vertex mask is less than 0.5, false otherwise */
-static bool check_mask_half(EdgeQueueContext *eq_ctx, BMVert *v)
+/* Return true if the vertex mask is less than 1.0, false otherwise */
+static bool check_mask(EdgeQueueContext *eq_ctx, BMVert *v)
{
- return (BM_ELEM_CD_GET_FLOAT(v, eq_ctx->cd_vert_mask_offset) < 0.5f);
+ return (BM_ELEM_CD_GET_FLOAT(v, eq_ctx->cd_vert_mask_offset) < 1.0f);
}
static void edge_queue_insert(EdgeQueueContext *eq_ctx, BMEdge *e,
@@ -527,11 +523,13 @@ static void edge_queue_insert(EdgeQueueContext *eq_ctx, BMEdge *e,
{
BMVert **pair;
- /* Don't let topology update affect masked vertices. Unlike with
- * displacements, can't do 50% topology update, so instead set
- * (arbitrary) cutoff: if both vertices' masks are less than 50%,
- * topology update can happen. */
- if (check_mask_half(eq_ctx, e->v1) && check_mask_half(eq_ctx, e->v2)) {
+ /* Don't let topology update affect fully masked vertices. This used to
+ * have a 50% mask cutoff, with the reasoning that you can't do a 50%
+ * topology update. But this gives an ugly border in the mesh. The mask
+ * should already make the brush move the vertices only 50%, which means
+ * that topology updates will also happen less frequent, that should be
+ * enough. */
+ if (check_mask(eq_ctx, e->v1) || check_mask(eq_ctx, e->v2)) {
pair = BLI_mempool_alloc(eq_ctx->pool);
pair[0] = e->v1;
pair[1] = e->v2;
@@ -678,6 +676,7 @@ static void pbvh_bmesh_split_edge(EdgeQueueContext *eq_ctx, PBVH *bvh,
BMVert *v_new;
float mid[3];
int i, node_index;
+ const int cd_vert_mask_offset = CustomData_get_offset(&bvh->bm->vdata, CD_PAINT_MASK);
/* Get all faces adjacent to the edge */
pbvh_bmesh_edge_loops(edge_loops, e);
@@ -689,6 +688,15 @@ static void pbvh_bmesh_split_edge(EdgeQueueContext *eq_ctx, PBVH *bvh,
e->v1));
v_new = pbvh_bmesh_vert_create(bvh, node_index, mid, e->v1);
+ /* update paint mask */
+ if (cd_vert_mask_offset != -1) {
+ float mask_v1 = BM_ELEM_CD_GET_FLOAT(e->v1, cd_vert_mask_offset);
+ float mask_v2 = BM_ELEM_CD_GET_FLOAT(e->v2, cd_vert_mask_offset);
+ float mask_v_new = 0.5f * (mask_v1 + mask_v2);
+
+ BM_ELEM_CD_SET_FLOAT(v_new, cd_vert_mask_offset, mask_v_new);
+ }
+
/* For each face, add two new triangles and delete the original */
for (i = 0; i < edge_loops->count; i++) {
BMLoop *l_adj = BLI_buffer_at(edge_loops, BMLoop *, i);
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index f3276992381..42147be33e4 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -1166,7 +1166,7 @@ static void rigidbody_update_simulation_post_step(RigidBodyWorld *rbw)
if (ob) {
RigidBodyOb *rbo = ob->rigidbody_object;
/* reset kinematic state for transformed objects */
- if (ob->flag & SELECT && G.moving & G_TRANSFORM_OBJ) {
+ if (rbo && (ob->flag & SELECT) && (G.moving & G_TRANSFORM_OBJ)) {
RB_body_set_kinematic_state(rbo->physics_object, rbo->flag & RBO_FLAG_KINEMATIC || rbo->flag & RBO_FLAG_DISABLED);
RB_body_set_mass(rbo->physics_object, RBO_GET_MASS(rbo));
/* deactivate passive objects so they don't interfere with deactivation of active objects */
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index b89cb6b7b82..41e43c00457 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -493,23 +493,10 @@ Scene *BKE_scene_add(Main *bmain, const char *name)
sce->r.border.ymax = 1.0f;
sce->toolsettings = MEM_callocN(sizeof(struct ToolSettings), "Tool Settings Struct");
- sce->toolsettings->cornertype = 1;
- sce->toolsettings->degr = 90;
- sce->toolsettings->step = 9;
- sce->toolsettings->turn = 1;
- sce->toolsettings->extr_offs = 1;
sce->toolsettings->doublimit = 0.001;
- sce->toolsettings->segments = 32;
- sce->toolsettings->rings = 32;
- sce->toolsettings->vertices = 32;
- sce->toolsettings->uvcalc_radius = 1.0f;
- sce->toolsettings->uvcalc_cubesize = 1.0f;
- sce->toolsettings->uvcalc_mapdir = 1;
- sce->toolsettings->uvcalc_mapalign = 1;
sce->toolsettings->uvcalc_margin = 0.001f;
sce->toolsettings->unwrapper = 1;
sce->toolsettings->select_thresh = 0.01f;
- sce->toolsettings->jointrilimit = 0.8f;
sce->toolsettings->selectmode = SCE_SELECT_VERTEX;
sce->toolsettings->uv_selectmode = UV_SELECT_VERTEX;
diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c
index efcbcacf974..c41c66ef561 100644
--- a/source/blender/blenkernel/intern/screen.c
+++ b/source/blender/blenkernel/intern/screen.c
@@ -112,7 +112,7 @@ ARegionType *BKE_regiontype_from_id(SpaceType *st, int regionid)
if (art->regionid == regionid)
return art;
- printf("Error, region type missing in - name:\"%s\", id:%d\n", st->name, st->spaceid);
+ printf("Error, region type %d missing in - name:\"%s\", id:%d\n", regionid, st->name, st->spaceid);
return st->regiontypes.first;
}
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index 43845638754..dd7e847feaf 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -632,7 +632,7 @@ static void seq_update_sound_bounds_recursive_rec(Scene *scene, Sequence *metase
endofs = seq->start + seq->len - end;
sound_move_scene_sound(scene, seq->scene_sound, seq->start + startofs,
- seq->start + seq->len - endofs, startofs);
+ seq->start + seq->len - endofs, startofs + seq->anim_startofs);
}
}
}
@@ -664,8 +664,9 @@ void BKE_sequence_calc_disp(Scene *scene, Sequence *seq)
if (ELEM(seq->type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SCENE)) {
BKE_sequencer_update_sound_bounds(scene, seq);
}
- else if (seq->type == SEQ_TYPE_META)
+ else if (seq->type == SEQ_TYPE_META) {
seq_update_sound_bounds_recursive(scene, seq);
+ }
}
void BKE_sequence_calc(Scene *scene, Sequence *seq)
diff --git a/source/blender/blenkernel/intern/shrinkwrap.c b/source/blender/blenkernel/intern/shrinkwrap.c
index 9bc7f4b9e2b..5c9c564998e 100644
--- a/source/blender/blenkernel/intern/shrinkwrap.c
+++ b/source/blender/blenkernel/intern/shrinkwrap.c
@@ -506,7 +506,7 @@ void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd, Object *ob, DerivedM
DerivedMesh *ss_mesh = NULL;
ShrinkwrapCalcData calc = NULL_ShrinkwrapCalcData;
- /* remove loop dependencies on derived meshs (TODO should this be done elsewhere?) */
+ /* remove loop dependencies on derived meshes (TODO should this be done elsewhere?) */
if (smd->target == ob) smd->target = NULL;
if (smd->auxTarget == ob) smd->auxTarget = NULL;
diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c
index 189c1e967dd..fb0e22abf2a 100644
--- a/source/blender/blenkernel/intern/smoke.c
+++ b/source/blender/blenkernel/intern/smoke.c
@@ -2386,6 +2386,7 @@ static void update_effectors(Scene *scene, Object *ob, SmokeDomainSettings *sds,
if (effectors)
{
float *density = smoke_get_density(sds->fluid);
+ float *fuel = smoke_get_fuel(sds->fluid);
float *force_x = smoke_get_force_x(sds->fluid);
float *force_y = smoke_get_force_y(sds->fluid);
float *force_z = smoke_get_force_z(sds->fluid);
@@ -2408,7 +2409,7 @@ static void update_effectors(Scene *scene, Object *ob, SmokeDomainSettings *sds,
float voxelCenter[3] = {0, 0, 0}, vel[3] = {0, 0, 0}, retvel[3] = {0, 0, 0};
unsigned int index = smoke_get_index(x, sds->res[0], y, sds->res[1], z);
- if ((density[index] < FLT_EPSILON) || obstacle[index])
+ if (((fuel ? MAX2(density[index], fuel[index]) : density[index]) < FLT_EPSILON) || obstacle[index])
continue;
vel[0] = velocity_x[index];
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index 2461ec85bb4..9a38a5f87b8 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -170,7 +170,7 @@ static CCGSubSurf *_getSubSurf(CCGSubSurf *prevSS, int subdivLevels,
if (useArena) {
CCGAllocatorIFC allocatorIFC;
- CCGAllocatorHDL allocator = BLI_memarena_new((1 << 16), "subsurf arena");
+ CCGAllocatorHDL allocator = BLI_memarena_new(MEM_SIZE_OPTIMAL(1 << 16), "subsurf arena");
allocatorIFC.alloc = arena_alloc;
allocatorIFC.realloc = arena_realloc;
@@ -1064,8 +1064,8 @@ void subsurf_copy_grid_hidden(DerivedMesh *dm, const MPoly *mpoly,
for (j = 0; j < mpoly[i].totloop; j++) {
const MDisps *md = &mdisps[mpoly[i].loopstart + j];
- int hidden_gridsize = ccg_gridsize(md->level);
- int factor = ccg_factor(level, md->level);
+ int hidden_gridsize = BKE_ccg_gridsize(md->level);
+ int factor = BKE_ccg_factor(level, md->level);
if (!md->hidden)
continue;
@@ -1107,8 +1107,8 @@ void subsurf_copy_grid_paint_mask(DerivedMesh *dm, const MPoly *mpoly,
if (!gpm->data)
continue;
- factor = ccg_factor(level, gpm->level);
- gpm_gridsize = ccg_gridsize(gpm->level);
+ factor = BKE_ccg_factor(level, gpm->level);
+ gpm_gridsize = BKE_ccg_gridsize(gpm->level);
for (y = 0; y < gridSize; y++) {
for (x = 0; x < gridSize; x++) {
diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c
index e2b7358525a..22b0fe7bc24 100644
--- a/source/blender/blenkernel/intern/texture.c
+++ b/source/blender/blenkernel/intern/texture.c
@@ -71,16 +71,16 @@
/* ****************** Mapping ******************* */
-TexMapping *add_tex_mapping(void)
+TexMapping *add_tex_mapping(int type)
{
TexMapping *texmap = MEM_callocN(sizeof(TexMapping), "TexMapping");
- default_tex_mapping(texmap);
+ default_tex_mapping(texmap, type);
return texmap;
}
-void default_tex_mapping(TexMapping *texmap)
+void default_tex_mapping(TexMapping *texmap, int type)
{
memset(texmap, 0, sizeof(TexMapping));
@@ -92,11 +92,12 @@ void default_tex_mapping(TexMapping *texmap)
texmap->projy = PROJ_Y;
texmap->projz = PROJ_Z;
texmap->mapping = MTEX_FLAT;
+ texmap->type = type;
}
void init_tex_mapping(TexMapping *texmap)
{
- float smat[3][3], rmat[3][3], mat[3][3], proj[3][3];
+ float smat[4][4], rmat[4][4], tmat[4][4], proj[4][4], size[3];
if (texmap->projx == PROJ_X && texmap->projy == PROJ_Y && texmap->projz == PROJ_Z &&
is_zero_v3(texmap->loc) && is_zero_v3(texmap->rot) && is_one_v3(texmap->size))
@@ -107,7 +108,8 @@ void init_tex_mapping(TexMapping *texmap)
}
else {
/* axis projection */
- zero_m3(proj);
+ zero_m4(proj);
+ proj[3][3] = 1.0f;
if (texmap->projx != PROJ_N)
proj[texmap->projx - 1][0] = 1.0f;
@@ -117,19 +119,50 @@ void init_tex_mapping(TexMapping *texmap)
proj[texmap->projz - 1][2] = 1.0f;
/* scale */
- size_to_mat3(smat, texmap->size);
+ copy_v3_v3(size, texmap->size);
+
+ if (ELEM(texmap->type, TEXMAP_TYPE_TEXTURE, TEXMAP_TYPE_NORMAL)) {
+ /* keep matrix invertible */
+ if (fabsf(size[0]) < 1e-5f)
+ size[0] = signf(size[0]) * 1e-5f;
+ if (fabsf(size[1]) < 1e-5f)
+ size[1] = signf(size[1]) * 1e-5f;
+ if (fabsf(size[2]) < 1e-5f)
+ size[2] = signf(size[2]) * 1e-5f;
+ }
+ size_to_mat4(smat, texmap->size);
+
/* rotation */
- /* TexMapping rotation are now in radians. */
- eul_to_mat3(rmat, texmap->rot);
-
- /* compose it all */
- mul_m3_m3m3(mat, rmat, smat);
- mul_m3_m3m3(mat, proj, mat);
-
+ eul_to_mat4(rmat, texmap->rot);
+
/* translation */
- copy_m4_m3(texmap->mat, mat);
- copy_v3_v3(texmap->mat[3], texmap->loc);
+ unit_m4(tmat);
+ copy_v3_v3(tmat[3], texmap->loc);
+
+ if (texmap->type == TEXMAP_TYPE_TEXTURE) {
+ /* to transform a texture, the inverse transform needs
+ * to be applied to the texture coordinate */
+ mul_serie_m4(texmap->mat, tmat, rmat, smat, 0, 0, 0, 0, 0);
+ invert_m4(texmap->mat);
+ }
+ else if (texmap->type == TEXMAP_TYPE_POINT) {
+ /* forward transform */
+ mul_serie_m4(texmap->mat, tmat, rmat, smat, 0, 0, 0, 0, 0);
+ }
+ else if (texmap->type == TEXMAP_TYPE_VECTOR) {
+ /* no translation for vectors */
+ mul_m4_m4m4(texmap->mat, rmat, smat);
+ }
+ else if (texmap->type == TEXMAP_TYPE_NORMAL) {
+ /* no translation for normals, and inverse transpose */
+ mul_m4_m4m4(texmap->mat, rmat, smat);
+ invert_m4(texmap->mat);
+ transpose_m4(texmap->mat);
+ }
+
+ /* projection last */
+ mul_m4_m4m4(texmap->mat, texmap->mat, proj);
texmap->flag &= ~TEXMAP_UNIT_MATRIX;
}
diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c
index fd92ec9f462..b8711f6e5f6 100644
--- a/source/blender/blenkernel/intern/tracking.c
+++ b/source/blender/blenkernel/intern/tracking.c
@@ -3340,7 +3340,7 @@ static void track_plane_from_existing_motion(MovieTrackingPlaneTrack *plane_trac
break;
}
- libmv_homography2DFromCorrespondencesLinear(x1, x2, num_correspondences, H_double, 1e-8);
+ libmv_homography2DFromCorrespondencesEuc(x1, x2, num_correspondences, H_double);
mat3f_from_mat3d(H, H_double);
@@ -3444,7 +3444,7 @@ void BKE_tracking_homography_between_two_quads(/*const*/ float reference_corners
float_corners_to_double(reference_corners, x1);
float_corners_to_double(corners, x2);
- libmv_homography2DFromCorrespondencesLinear(x1, x2, 4, H_double, 1e-8);
+ libmv_homography2DFromCorrespondencesEuc(x1, x2, 4, H_double);
mat3f_from_mat3d(H, H_double);
}
diff --git a/source/blender/blenlib/BLI_bitmap.h b/source/blender/blenlib/BLI_bitmap.h
index bcdc97cdaa7..cf10fe53a5d 100644
--- a/source/blender/blenlib/BLI_bitmap.h
+++ b/source/blender/blenlib/BLI_bitmap.h
@@ -60,6 +60,9 @@ typedef unsigned int BLI_bitmap;
((_bitmap)[(_index) >> BLI_BITMAP_POWER] & \
(1u << ((_index) & BLI_BITMAP_MASK)))
+#define BLI_BITMAP_GET_BOOL(_bitmap, _index) \
+ (BLI_BITMAP_GET(_bitmap, _index) != 0)
+
/* set the value of a single bit at '_index' */
#define BLI_BITMAP_SET(_bitmap, _index) \
((_bitmap)[(_index) >> BLI_BITMAP_POWER] |= \
diff --git a/source/blender/blenlib/BLI_boxpack2d.h b/source/blender/blenlib/BLI_boxpack2d.h
index 8316987dfcd..b02e3423f88 100644
--- a/source/blender/blenlib/BLI_boxpack2d.h
+++ b/source/blender/blenlib/BLI_boxpack2d.h
@@ -39,14 +39,15 @@ typedef struct BoxPack {
float y;
float w;
float h;
- int index;
/* Verts this box uses
* (BL,TR,TL,BR) / 0,1,2,3 */
struct BoxVert *v[4];
+
+ int index;
} BoxPack;
-void BLI_box_pack_2d(BoxPack *boxarray, const int len, float *tot_width, float *tot_height);
+void BLI_box_pack_2d(BoxPack *boxarray, const unsigned int len, float *tot_width, float *tot_height);
#endif
diff --git a/source/blender/blenlib/BLI_linklist_stack.h b/source/blender/blenlib/BLI_linklist_stack.h
index ca050883018..c9fb00ecdf5 100644
--- a/source/blender/blenlib/BLI_linklist_stack.h
+++ b/source/blender/blenlib/BLI_linklist_stack.h
@@ -151,8 +151,6 @@
(void)&(_##var##_type); \
} (void)0
-#include "BLI_alloca.h"
-
/** \} */
#endif /* __BLI_LINKLIST_STACK_H__ */
diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h
index d3f6c7ef14b..f815716148b 100644
--- a/source/blender/blenlib/BLI_math_geom.h
+++ b/source/blender/blenlib/BLI_math_geom.h
@@ -155,8 +155,8 @@ bool isect_ray_tri_epsilon_v3(const float p1[3], const float d[3],
const float v0[3], const float v1[3], const float v2[3], float *r_lambda, float r_uv[2], const float epsilon);
/* point in polygon */
-bool isect_point_poly_v2(const float pt[2], const float verts[][2], const unsigned int nr);
-bool isect_point_poly_v2_int(const int pt[2], const int verts[][2], const unsigned int nr);
+bool isect_point_poly_v2(const float pt[2], const float verts[][2], const unsigned int nr, const bool use_holes);
+bool isect_point_poly_v2_int(const int pt[2], const int verts[][2], const unsigned int nr, const bool use_holes);
int isect_point_quad_v2(const float p[2], const float a[2], const float b[2], const float c[2], const float d[2]);
@@ -188,7 +188,10 @@ bool clip_segment_v3_plane(float p1[3], float p2[3], const float plane[4]);
bool clip_segment_v3_plane_n(float p1[3], float p2[3], float plane_array[][4], const int plane_tot);
void plot_line_v2v2i(const int p1[2], const int p2[2], bool (*callback)(int, int, void *), void *userData);
-
+void fill_poly_v2i_n(
+ const int xmin, const int ymin, const int xmax, const int ymax,
+ const int polyXY[][2], const int polyCorners,
+ void (*callback)(int, int, void *), void *userData);
/****************************** Interpolation ********************************/
/* tri or quad, d can be NULL */
diff --git a/source/blender/blenlib/BLI_memarena.h b/source/blender/blenlib/BLI_memarena.h
index 9ff4883c89c..737324ebc16 100644
--- a/source/blender/blenlib/BLI_memarena.h
+++ b/source/blender/blenlib/BLI_memarena.h
@@ -47,7 +47,7 @@ extern "C" {
* enough to not cause much internal fragmentation,
* small enough not to waste resources
*/
-#define BLI_MEMARENA_STD_BUFSIZE (1 << 14)
+#define BLI_MEMARENA_STD_BUFSIZE MEM_SIZE_OPTIMAL(1 << 14)
struct MemArena;
typedef struct MemArena MemArena;
diff --git a/source/blender/blenlib/BLI_mempool.h b/source/blender/blenlib/BLI_mempool.h
index 88650719712..3fab77f2cb2 100644
--- a/source/blender/blenlib/BLI_mempool.h
+++ b/source/blender/blenlib/BLI_mempool.h
@@ -67,6 +67,10 @@ void **BLI_mempool_as_tableN(BLI_mempool *pool, const char *allocstr) ATTR_
void BLI_mempool_as_array(BLI_mempool *pool, void *data) ATTR_NONNULL(1, 2);
void *BLI_mempool_as_arrayN(BLI_mempool *pool, const char *allocstr) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2);
+#ifdef DEBUG
+void BLI_mempool_set_memory_debug(void);
+#endif
+
/** iteration stuff. note: this may easy to produce bugs with **/
/* private structure */
typedef struct BLI_mempool_iter {
diff --git a/source/blender/blenlib/BLI_scanfill.h b/source/blender/blenlib/BLI_scanfill.h
index e7d2130e473..52f5decb4f4 100644
--- a/source/blender/blenlib/BLI_scanfill.h
+++ b/source/blender/blenlib/BLI_scanfill.h
@@ -51,7 +51,7 @@ typedef struct ScanFillContext {
struct MemArena *arena;
} ScanFillContext;
-#define BLI_SCANFILL_ARENA_SIZE 16384
+#define BLI_SCANFILL_ARENA_SIZE MEM_SIZE_OPTIMAL(1 << 14)
typedef struct ScanFillVert {
struct ScanFillVert *next, *prev;
diff --git a/source/blender/blenlib/BLI_task.h b/source/blender/blenlib/BLI_task.h
new file mode 100644
index 00000000000..f57d42858c7
--- /dev/null
+++ b/source/blender/blenlib/BLI_task.h
@@ -0,0 +1,108 @@
+/*
+ * ***** 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 *****
+ */
+
+#ifndef __BLI_TASK_H__
+#define __BLI_TASK_H__
+
+/** \file BLI_task.h
+ * \ingroup bli
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "BLI_threads.h"
+#include "BLI_utildefines.h"
+
+/* Task Scheduler
+ *
+ * Central scheduler that holds running threads ready to execute tasks. A single
+ * queue holds the task from all pools.
+ *
+ * Init/exit must be called before/after any task pools are created/freed, and
+ * must be called from the main threads. All other scheduler and pool functions
+ * are thread-safe. */
+
+typedef struct TaskScheduler TaskScheduler;
+
+enum {
+ TASK_SCHEDULER_AUTO_THREADS = 0,
+ TASK_SCHEDULER_SINGLE_THREAD = 1
+};
+
+TaskScheduler *BLI_task_scheduler_create(int num_threads);
+void BLI_task_scheduler_free(TaskScheduler *scheduler);
+
+int BLI_task_scheduler_num_threads(TaskScheduler *scheduler);
+
+/* Task Pool
+ *
+ * Pool of tasks that will be executed by the central TaskScheduler. For each
+ * pool, we can wait for all tasks to be done, or cancel them before they are
+ * done.
+ *
+ * Running tasks may spawn new tasks.
+ *
+ * Pools may be nested, i.e. a thread running a task can create another task
+ * pool with smaller tasks. When other threads are busy they will continue
+ * working on their own tasks, if not they will join in, no new threads will
+ * be launched.
+ */
+
+typedef enum TaskPriority {
+ TASK_PRIORITY_LOW,
+ TASK_PRIORITY_HIGH
+} TaskPriority;
+
+typedef struct TaskPool TaskPool;
+typedef void (*TaskRunFunction)(TaskPool *pool, void *taskdata, int threadid);
+
+TaskPool *BLI_task_pool_create(TaskScheduler *scheduler, void *userdata);
+void BLI_task_pool_free(TaskPool *pool);
+
+void BLI_task_pool_push(TaskPool *pool, TaskRunFunction run,
+ void *taskdata, bool free_taskdata, TaskPriority priority);
+
+/* work and wait until all tasks are done */
+void BLI_task_pool_work_and_wait(TaskPool *pool);
+/* cancel all tasks, keep worker threads running */
+void BLI_task_pool_cancel(TaskPool *pool);
+/* stop all worker threads */
+void BLI_task_pool_stop(TaskPool *pool);
+
+/* for worker threads, test if cancelled */
+bool BLI_task_pool_cancelled(TaskPool *pool);
+
+/* optional userdata pointer to pass along to run function */
+void *BLI_task_pool_userdata(TaskPool *pool);
+
+/* optional mutex to use from run function */
+ThreadMutex *BLI_task_pool_user_mutex(TaskPool *pool);
+
+/* number of tasks done, for stats, don't use this to make decisions */
+size_t BLI_task_pool_tasks_done(TaskPool *pool);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/source/blender/blenlib/BLI_threads.h b/source/blender/blenlib/BLI_threads.h
index 38ad0827246..7a3ee1dd0f4 100644
--- a/source/blender/blenlib/BLI_threads.h
+++ b/source/blender/blenlib/BLI_threads.h
@@ -45,6 +45,7 @@ extern "C" {
#define BLENDER_MAX_THREADS 64
struct ListBase;
+struct TaskScheduler;
/* Threading API */
@@ -52,6 +53,8 @@ struct ListBase;
void BLI_threadapi_init(void);
void BLI_threadapi_exit(void);
+struct TaskScheduler *BLI_task_scheduler_get(void);
+
void BLI_init_threads(struct ListBase *threadbase, void *(*do_thread)(void *), int tot);
int BLI_available_threads(struct ListBase *threadbase);
int BLI_available_thread_index(struct ListBase *threadbase);
@@ -101,6 +104,7 @@ ThreadMutex *BLI_mutex_alloc(void);
void BLI_mutex_free(ThreadMutex *mutex);
void BLI_mutex_lock(ThreadMutex *mutex);
+bool BLI_mutex_trylock(ThreadMutex *mutex);
void BLI_mutex_unlock(ThreadMutex *mutex);
/* Spin Lock */
@@ -144,27 +148,15 @@ void BLI_ticket_mutex_free(TicketMutex *ticket);
void BLI_ticket_mutex_lock(TicketMutex *ticket);
void BLI_ticket_mutex_unlock(TicketMutex *ticket);
-/* ThreadedWorker
- *
- * A simple tool for dispatching work to a limited number of threads
- * in a transparent fashion from the caller's perspective. */
-
-struct ThreadedWorker;
-
-/* Create a new worker supporting tot parallel threads.
- * When new work in inserted and all threads are busy, sleep(sleep_time) before checking again
- */
-struct ThreadedWorker *BLI_create_worker(void *(*do_thread)(void *), int tot, int sleep_time);
-
-/* join all working threads */
-void BLI_end_worker(struct ThreadedWorker *worker);
-
-/* also ends all working threads */
-void BLI_destroy_worker(struct ThreadedWorker *worker);
+/* Condition */
+
+typedef pthread_cond_t ThreadCondition;
-/* Spawns a new work thread if possible, sleeps until one is available otherwise
- * NOTE: inserting work is NOT thread safe, so make sure it is only done from one thread */
-void BLI_insert_work(struct ThreadedWorker *worker, void *param);
+void BLI_condition_init(ThreadCondition *cond);
+void BLI_condition_wait(ThreadCondition *cond, ThreadMutex *mutex);
+void BLI_condition_notify_one(ThreadCondition *cond);
+void BLI_condition_notify_all(ThreadCondition *cond);
+void BLI_condition_end(ThreadCondition *cond);
/* ThreadWorkQueue
*
diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt
index 31125fd3153..d855d45760a 100644
--- a/source/blender/blenlib/CMakeLists.txt
+++ b/source/blender/blenlib/CMakeLists.txt
@@ -94,6 +94,7 @@ set(SRC
intern/string.c
intern/string_cursor_utf8.c
intern/string_utf8.c
+ intern/task.c
intern/threads.c
intern/time.c
intern/uvproject.c
@@ -160,6 +161,7 @@ set(SRC
BLI_string_cursor_utf8.h
BLI_string_utf8.h
BLI_sys_types.h
+ BLI_task.h
BLI_threads.h
BLI_utildefines.h
BLI_uvproject.h
@@ -178,6 +180,10 @@ if(WITH_BINRELOC)
add_definitions(-DWITH_BINRELOC)
endif()
+if(WITH_MEM_VALGRIND)
+ add_definitions(-DWITH_MEM_VALGRIND)
+endif()
+
if(WIN32)
list(APPEND INC
../../../intern/utfconv
diff --git a/source/blender/blenlib/PIL_time_utildefines.h b/source/blender/blenlib/PIL_time_utildefines.h
index c253aba875f..135817f6a17 100644
--- a/source/blender/blenlib/PIL_time_utildefines.h
+++ b/source/blender/blenlib/PIL_time_utildefines.h
@@ -29,13 +29,14 @@
/** \file blender/blenlib/PIL_time_utildefines.h
* \ingroup bli
* \brief Utility defines for timing/benchmarks.
- *
- * \note requires BLI_utildefines.h for 'AT'.
*/
#ifndef __PIL_TIME_UTILDEFINES_H__
#define __PIL_TIME_UTILDEFINES_H__
+#include "PIL_time.h" /* for PIL_check_seconds_timer */
+#include "BLI_utildefines.h" /* for AT */
+
#define TIMEIT_START(var) \
{ \
double _timeit_##var = PIL_check_seconds_timer(); \
diff --git a/source/blender/blenlib/intern/BLI_heap.c b/source/blender/blenlib/intern/BLI_heap.c
index 45bdeeedcf9..206a8041c4a 100644
--- a/source/blender/blenlib/intern/BLI_heap.c
+++ b/source/blender/blenlib/intern/BLI_heap.c
@@ -127,7 +127,7 @@ Heap *BLI_heap_new_ex(unsigned int tot_reserve)
/* ensure we have at least one so we can keep doubling it */
heap->bufsize = MAX2(1, tot_reserve);
heap->tree = (HeapNode **)MEM_mallocN(heap->bufsize * sizeof(HeapNode *), "BLIHeapTree");
- heap->arena = BLI_memarena_new(1 << 16, "heap arena");
+ heap->arena = BLI_memarena_new(MEM_SIZE_OPTIMAL(1 << 16), "heap arena");
return heap;
}
diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c
index 80483fbfa38..7c1cdd593c3 100644
--- a/source/blender/blenlib/intern/BLI_kdopbvh.c
+++ b/source/blender/blenlib/intern/BLI_kdopbvh.c
@@ -117,7 +117,7 @@ typedef struct BVHRayCastData {
* Notes: You can choose the tree type --> binary, quad, octree, choose below
*/
-static float KDOP_AXES[13][3] = {
+static const float KDOP_AXES[13][3] = {
{1.0, 0, 0}, {0, 1.0, 0}, {0, 0, 1.0}, {1.0, 1.0, 1.0}, {1.0, -1.0, 1.0}, {1.0, 1.0, -1.0},
{1.0, -1.0, -1.0}, {1.0, 1.0, 0}, {1.0, 0, 1.0}, {0, 1.0, 1.0}, {1.0, -1.0, 0}, {1.0, 0, -1.0},
{0, 1.0, -1.0}
diff --git a/source/blender/blenlib/intern/BLI_memarena.c b/source/blender/blenlib/intern/BLI_memarena.c
index 747c2f0c2b7..4a6712201a9 100644
--- a/source/blender/blenlib/intern/BLI_memarena.c
+++ b/source/blender/blenlib/intern/BLI_memarena.c
@@ -38,6 +38,10 @@
#include "BLI_linklist.h"
#include "BLI_strict_flags.h"
+#ifdef WITH_MEM_VALGRIND
+# include "valgrind/memcheck.h"
+#endif
+
struct MemArena {
unsigned char *curbuf;
int bufsize, cursize;
@@ -56,6 +60,10 @@ MemArena *BLI_memarena_new(const int bufsize, const char *name)
ma->align = 8;
ma->name = name;
+#ifdef WITH_MEM_VALGRIND
+ VALGRIND_CREATE_MEMPOOL(ma, 0, false);
+#endif
+
return ma;
}
@@ -78,6 +86,11 @@ void BLI_memarena_use_align(struct MemArena *ma, const int align)
void BLI_memarena_free(MemArena *ma)
{
BLI_linklist_freeN(ma->bufs);
+
+#ifdef WITH_MEM_VALGRIND
+ VALGRIND_DESTROY_MEMPOOL(ma);
+#endif
+
MEM_freeN(ma);
}
@@ -122,6 +135,10 @@ void *BLI_memarena_alloc(MemArena *ma, int size)
ma->curbuf += size;
ma->cursize -= size;
+#ifdef WITH_MEM_VALGRIND
+ VALGRIND_MEMPOOL_ALLOC(ma, ptr, size);
+#endif
+
return ptr;
}
@@ -152,4 +169,10 @@ void BLI_memarena_clear(MemArena *ma)
memset(ma->curbuf, 0, (size_t)curbuf_used);
}
}
+
+#ifdef WITH_MEM_VALGRIND
+ VALGRIND_DESTROY_MEMPOOL(ma);
+ VALGRIND_CREATE_MEMPOOL(ma, 0, false);
+#endif
+
}
diff --git a/source/blender/blenlib/intern/BLI_mempool.c b/source/blender/blenlib/intern/BLI_mempool.c
index febf09745fb..261e53f0f55 100644
--- a/source/blender/blenlib/intern/BLI_mempool.c
+++ b/source/blender/blenlib/intern/BLI_mempool.c
@@ -45,6 +45,9 @@
#include "BLI_strict_flags.h" /* keep last */
+#ifdef WITH_MEM_VALGRIND
+# include "valgrind/memcheck.h"
+#endif
/* note: copied from BLO_blend_defs.h, don't use here because we're in BLI */
#ifdef __BIG_ENDIAN__
@@ -63,6 +66,10 @@
/* when undefined, merge the allocs for BLI_mempool_chunk and its data */
// #define USE_DATA_PTR
+#ifndef NDEBUG
+static bool mempool_debug_memset = false;
+#endif
+
/**
* A free element from #BLI_mempool_chunk. Data is cast to this type and stored in
* #BLI_mempool.free as a single linked list, each item #BLI_mempool.esize large.
@@ -275,6 +282,10 @@ BLI_mempool *BLI_mempool_create(unsigned int esize, unsigned int totelem,
lasttail = mempool_chunk_add(pool, mpchunk, lasttail);
}
+#ifdef WITH_MEM_VALGRIND
+ VALGRIND_CREATE_MEMPOOL(pool, 0, false);
+#endif
+
return pool;
}
@@ -297,6 +308,11 @@ void *BLI_mempool_alloc(BLI_mempool *pool)
}
pool->free = pool->free->next;
+
+#ifdef WITH_MEM_VALGRIND
+ VALGRIND_MEMPOOL_ALLOC(pool, retval, pool->esize);
+#endif
+
return retval;
}
@@ -330,6 +346,11 @@ void BLI_mempool_free(BLI_mempool *pool, void *addr)
BLI_assert(!"Attempt to free data which is not in pool.\n");
}
}
+
+ /* enable for debugging */
+ if (UNLIKELY(mempool_debug_memset)) {
+ memset(addr, 255, pool->esize);
+ }
#endif
if (pool->flag & BLI_MEMPOOL_ALLOW_ITER) {
@@ -345,8 +366,12 @@ void BLI_mempool_free(BLI_mempool *pool, void *addr)
pool->totused--;
+#ifdef WITH_MEM_VALGRIND
+ VALGRIND_MEMPOOL_FREE(pool, addr);
+#endif
+
/* nothing is in use; free all the chunks except the first */
- if (pool->totused == 0) {
+ if (UNLIKELY(pool->totused == 0)) {
BLI_freenode *curnode = NULL;
char *tmpaddr = NULL;
unsigned int i;
@@ -359,6 +384,10 @@ void BLI_mempool_free(BLI_mempool *pool, void *addr)
pool->totalloc = pool->pchunk;
#endif
+ /* temp alloc so valgrind doesn't complain when setting free'd blocks 'next' */
+#ifdef WITH_MEM_VALGRIND
+ VALGRIND_MEMPOOL_ALLOC(pool, CHUNK_DATA(first), pool->csize);
+#endif
pool->free = CHUNK_DATA(first); /* start of the list */
for (tmpaddr = CHUNK_DATA(first), i = 0; i < pool->pchunk; i++) {
curnode = ((BLI_freenode *)tmpaddr);
@@ -366,6 +395,10 @@ void BLI_mempool_free(BLI_mempool *pool, void *addr)
curnode->next = (BLI_freenode *)tmpaddr;
}
curnode->next = NULL; /* terminate the list */
+
+#ifdef WITH_MEM_VALGRIND
+ VALGRIND_MEMPOOL_FREE(pool, CHUNK_DATA(first));
+#endif
}
}
@@ -537,6 +570,11 @@ void BLI_mempool_clear_ex(BLI_mempool *pool, const int totelem_reserve)
ListBase chunks_temp;
BLI_freenode *lasttail = NULL;
+#ifdef WITH_MEM_VALGRIND
+ VALGRIND_DESTROY_MEMPOOL(pool);
+ VALGRIND_CREATE_MEMPOOL(pool, 0, false);
+#endif
+
if (totelem_reserve == -1) {
maxchunks = pool->maxchunks;
}
@@ -582,6 +620,10 @@ void BLI_mempool_destroy(BLI_mempool *pool)
{
mempool_chunk_free_all(&pool->chunks, pool->flag);
+#ifdef WITH_MEM_VALGRIND
+ VALGRIND_DESTROY_MEMPOOL(pool);
+#endif
+
if (pool->flag & BLI_MEMPOOL_SYSMALLOC) {
free(pool);
}
@@ -589,3 +631,10 @@ void BLI_mempool_destroy(BLI_mempool *pool)
MEM_freeN(pool);
}
}
+
+#ifndef NDEBUG
+void BLI_mempool_set_memory_debug(void)
+{
+ mempool_debug_memset = true;
+}
+#endif
diff --git a/source/blender/blenlib/intern/boxpack2d.c b/source/blender/blenlib/intern/boxpack2d.c
index 8707be46196..4b51aefbd87 100644
--- a/source/blender/blenlib/intern/boxpack2d.c
+++ b/source/blender/blenlib/intern/boxpack2d.c
@@ -31,14 +31,19 @@
#include "BLI_boxpack2d.h" /* own include */
+#ifdef __GNUC__
+# pragma GCC diagnostic error "-Wpadded"
+#endif
+
/* BoxPacker for backing 2D rectangles into a square
*
* The defined Below are for internal use only */
-
typedef struct BoxVert {
float x;
float y;
- short free;
+
+ int free; /* could be a char */
+ unsigned int index;
struct BoxPack *trb; /* top right box */
struct BoxPack *blb; /* bottom left box */
@@ -48,8 +53,6 @@ typedef struct BoxVert {
/* Store last intersecting boxes here
* speedup intersection testing */
struct BoxPack *isect_cache[4];
-
- int index;
} BoxVert;
/* free vert flags */
@@ -156,13 +159,15 @@ static int vertex_sort(const void *p1, const void *p2)
* len - the number of boxes in the array.
* tot_width and tot_height are set so you can normalize the data.
* */
-void BLI_box_pack_2d(BoxPack *boxarray, const int len, float *tot_width, float *tot_height)
+void BLI_box_pack_2d(BoxPack *boxarray, const unsigned int len, float *tot_width, float *tot_height)
{
- BoxVert *vert; /* the current vert */
- int box_index, verts_pack_len, i, j, k, isect;
- int quad_flags[4] = {BLF, TRF, TLF, BRF}; /* use for looping */
+ const int quad_flags[4] = {BLF, TRF, TLF, BRF}; /* use for looping */
+ unsigned int box_index, verts_pack_len, i, j, k;
+ unsigned int *vertex_pack_indices; /* an array of indices used for sorting verts */
+ bool isect;
+
BoxPack *box, *box_test; /*current box and another for intersection tests*/
- int *vertex_pack_indices; /*an array of indices used for sorting verts*/
+ BoxVert *vert; /* the current vert */
if (!len) {
*tot_width = 0.0f;
@@ -184,7 +189,7 @@ void BLI_box_pack_2d(BoxPack *boxarray, const int len, float *tot_width, float *
vert->isect_cache[2] = vert->isect_cache[3] = NULL;
vert->free = CORNERFLAGS & ~TRF;
vert->trb = box;
- vert->index = i; i++;
+ vert->index = i++;
box->v[BL] = vert; vert++;
vert->trb = vert->brb = vert->tlb =
@@ -192,7 +197,7 @@ void BLI_box_pack_2d(BoxPack *boxarray, const int len, float *tot_width, float *
vert->isect_cache[2] = vert->isect_cache[3] = NULL;
vert->free = CORNERFLAGS & ~BLF;
vert->blb = box;
- vert->index = i; i++;
+ vert->index = i++;
box->v[TR] = vert; vert++;
vert->trb = vert->blb = vert->tlb =
@@ -200,7 +205,7 @@ void BLI_box_pack_2d(BoxPack *boxarray, const int len, float *tot_width, float *
vert->isect_cache[2] = vert->isect_cache[3] = NULL;
vert->free = CORNERFLAGS & ~BRF;
vert->brb = box;
- vert->index = i; i++;
+ vert->index = i++;
box->v[TL] = vert; vert++;
vert->trb = vert->blb = vert->brb =
@@ -208,7 +213,7 @@ void BLI_box_pack_2d(BoxPack *boxarray, const int len, float *tot_width, float *
vert->isect_cache[2] = vert->isect_cache[3] = NULL;
vert->free = CORNERFLAGS & ~TLF;
vert->tlb = box;
- vert->index = i; i++;
+ vert->index = i++;
box->v[BR] = vert; vert++;
}
vert = NULL;
@@ -247,7 +252,7 @@ void BLI_box_pack_2d(BoxPack *boxarray, const int len, float *tot_width, float *
/* Pack the box in with the others */
/* sort the verts */
- isect = 1;
+ isect = true;
for (i = 0; i < verts_pack_len && isect; i++) {
vert = vertarray + vertex_pack_indices[i];
@@ -283,7 +288,7 @@ void BLI_box_pack_2d(BoxPack *boxarray, const int len, float *tot_width, float *
/* Now we need to check that the box intersects
* with any other boxes
* Assume no intersection... */
- isect = 0;
+ isect = false;
if ( /* Constrain boxes to positive X/Y values */
BOXLEFT(box) < 0.0f || BOXBOTTOM(box) < 0.0f ||
@@ -296,7 +301,7 @@ void BLI_box_pack_2d(BoxPack *boxarray, const int len, float *tot_width, float *
* isect_cache that can store a pointer to a
* box for each quadrant
* big speedup */
- isect = 1;
+ isect = true;
}
else {
/* do a full search for colliding box
@@ -307,7 +312,7 @@ void BLI_box_pack_2d(BoxPack *boxarray, const int len, float *tot_width, float *
/* Store the last intersecting here as cache
* for faster checking next time around */
vert->isect_cache[j] = box_test;
- isect = 1;
+ isect = true;
break;
}
}
@@ -320,7 +325,7 @@ void BLI_box_pack_2d(BoxPack *boxarray, const int len, float *tot_width, float *
(*tot_height) = max_ff(BOXTOP(box), (*tot_height));
/* Place the box */
- vert->free &= (short)~quad_flags[j];
+ vert->free &= ~quad_flags[j];
switch (j) {
case TR:
diff --git a/source/blender/blenlib/intern/lasso.c b/source/blender/blenlib/intern/lasso.c
index 8e22d6f1182..e89f7fd795b 100644
--- a/source/blender/blenlib/intern/lasso.c
+++ b/source/blender/blenlib/intern/lasso.c
@@ -63,7 +63,7 @@ bool BLI_lasso_is_point_inside(const int mcords[][2], const unsigned int moves,
}
else {
int pt[2] = {sx, sy};
- return isect_point_poly_v2_int(pt, mcords, moves);
+ return isect_point_poly_v2_int(pt, mcords, moves, true);
}
}
diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c
index bf20dd48486..0d15eede9ea 100644
--- a/source/blender/blenlib/intern/math_geom.c
+++ b/source/blender/blenlib/intern/math_geom.c
@@ -712,7 +712,8 @@ int isect_line_sphere_v2(const float l1[2], const float l2[2],
}
/* point in polygon (keep float and int versions in sync) */
-bool isect_point_poly_v2(const float pt[2], const float verts[][2], const unsigned int nr)
+bool isect_point_poly_v2(const float pt[2], const float verts[][2], const unsigned int nr,
+ const bool use_holes)
{
/* we do the angle rule, define that all added angles should be about zero or (2 * PI) */
float angletot = 0.0;
@@ -749,9 +750,18 @@ bool isect_point_poly_v2(const float pt[2], const float verts[][2], const unsign
p1 = p2;
}
- return (fabsf(angletot) > 4.0f);
+ angletot = fabsf(angletot);
+ if (use_holes) {
+ const int nested = floorf((angletot / (float)(M_PI * 2.0)) + 0.00001f);
+ angletot -= nested * (float)(M_PI * 2.0);
+ return (angletot > 4.0f) != (nested % 2);
+ }
+ else {
+ return (angletot > 4.0f);
+ }
}
-bool isect_point_poly_v2_int(const int pt[2], const int verts[][2], const unsigned int nr)
+bool isect_point_poly_v2_int(const int pt[2], const int verts[][2], const unsigned int nr,
+ const bool use_holes)
{
/* we do the angle rule, define that all added angles should be about zero or (2 * PI) */
float angletot = 0.0;
@@ -788,7 +798,15 @@ bool isect_point_poly_v2_int(const int pt[2], const int verts[][2], const unsign
p1 = p2;
}
- return (fabsf(angletot) > 4.0f);
+ angletot = fabsf(angletot);
+ if (use_holes) {
+ const int nested = floorf((angletot / (float)(M_PI * 2.0)) + 0.00001f);
+ angletot -= nested * (float)(M_PI * 2.0);
+ return (angletot > 4.0f) != (nested % 2);
+ }
+ else {
+ return (angletot > 4.0f);
+ }
}
/* point in tri */
@@ -1114,7 +1132,7 @@ bool isect_point_planes_v3(float (*planes)[4], int totplane, const float p[3])
}
/**
- * Intersect line/plane, optionally treat line as directional (like a ray) with the no_flip argument.
+ * Intersect line/plane.
*
* \param out The intersection point.
* \param l1 The first point of the line.
@@ -1979,6 +1997,59 @@ void plot_line_v2v2i(const int p1[2], const int p2[2], bool (*callback)(int, int
}
}
+void fill_poly_v2i_n(
+ const int xmin, const int ymin, const int xmax, const int ymax,
+ const int verts[][2], const int nr,
+ void (*callback)(int, int, void *), void *userData)
+{
+ /* originally by Darel Rex Finley, 2007 */
+
+ int nodes, pixel_y, i, j, swap;
+ int *node_x = MEM_mallocN(sizeof(*node_x) * (nr + 1), __func__);
+
+ /* Loop through the rows of the image. */
+ for (pixel_y = ymin; pixel_y < ymax; pixel_y++) {
+
+ /* Build a list of nodes. */
+ nodes = 0; j = nr - 1;
+ for (i = 0; i < nr; i++) {
+ if ((verts[i][1] < pixel_y && verts[j][1] >= pixel_y) ||
+ (verts[j][1] < pixel_y && verts[i][1] >= pixel_y))
+ {
+ node_x[nodes++] = (int)(verts[i][0] +
+ ((double)(pixel_y - verts[i][1]) / (verts[j][1] - verts[i][1])) *
+ (verts[j][0] - verts[i][0]));
+ }
+ j = i;
+ }
+
+ /* Sort the nodes, via a simple "Bubble" sort. */
+ i = 0;
+ while (i < nodes - 1) {
+ if (node_x[i] > node_x[i + 1]) {
+ SWAP_TVAL(swap, node_x[i], node_x[i + 1]);
+ if (i) i--;
+ }
+ else {
+ i++;
+ }
+ }
+
+ /* Fill the pixels between node pairs. */
+ for (i = 0; i < nodes; i += 2) {
+ if (node_x[i] >= xmax) break;
+ if (node_x[i + 1] > xmin) {
+ if (node_x[i ] < xmin) node_x[i ] = xmin;
+ if (node_x[i + 1] > xmax) node_x[i + 1] = xmax;
+ for (j = node_x[i]; j < node_x[i + 1]; j++) {
+ callback(j - xmin, pixel_y - ymin, userData);
+ }
+ }
+ }
+ }
+ MEM_freeN(node_x);
+}
+
/****************************** Axis Utils ********************************/
/**
diff --git a/source/blender/blenlib/intern/math_rotation.c b/source/blender/blenlib/intern/math_rotation.c
index 6bac102e1b1..2eebe10dd58 100644
--- a/source/blender/blenlib/intern/math_rotation.c
+++ b/source/blender/blenlib/intern/math_rotation.c
@@ -286,7 +286,7 @@ void mat3_to_quat(float q[4], float wmat[3][3])
tr = 0.25 * (double)(1.0f + mat[0][0] + mat[1][1] + mat[2][2]);
- if (tr > (double)FLT_EPSILON) {
+ if (tr > (double)1e-4f) {
s = sqrt(tr);
q[0] = (float)s;
s = 1.0 / (4.0 * s);
@@ -300,7 +300,7 @@ void mat3_to_quat(float q[4], float wmat[3][3])
q[1] = (float)(0.25 * s);
s = 1.0 / s;
- q[0] = (float)((double)(mat[2][1] - mat[1][2]) * s);
+ q[0] = (float)((double)(mat[1][2] - mat[2][1]) * s);
q[2] = (float)((double)(mat[1][0] + mat[0][1]) * s);
q[3] = (float)((double)(mat[2][0] + mat[0][2]) * s);
}
@@ -318,7 +318,7 @@ void mat3_to_quat(float q[4], float wmat[3][3])
q[3] = (float)(0.25 * s);
s = 1.0 / s;
- q[0] = (float)((double)(mat[1][0] - mat[0][1]) * s);
+ q[0] = (float)((double)(mat[0][1] - mat[1][0]) * s);
q[1] = (float)((double)(mat[2][0] + mat[0][2]) * s);
q[2] = (float)((double)(mat[2][1] + mat[1][2]) * s);
}
diff --git a/source/blender/blenlib/intern/noise.c b/source/blender/blenlib/intern/noise.c
index 2f94e833e9d..5b9fefe77bb 100644
--- a/source/blender/blenlib/intern/noise.c
+++ b/source/blender/blenlib/intern/noise.c
@@ -42,7 +42,7 @@
/* local */
static float noise3_perlin(float vec[3]);
-//static float turbulence_perlin(float *point, float lofreq, float hifreq);
+//static float turbulence_perlin(const float point[3], float lofreq, float hifreq);
//static float turbulencep(float noisesize, float x, float y, float z, int nr);
/* UNUSED */
@@ -50,7 +50,7 @@ static float noise3_perlin(float vec[3]);
/* needed for voronoi */
#define HASHPNT(x, y, z) hashpntf + 3 * hash[(hash[(hash[(z) & 255] + (y)) & 255] + (x)) & 255]
-static float hashpntf[768] = {
+static const float hashpntf[768] = {
0.536902, 0.020915, 0.501445, 0.216316, 0.517036, 0.822466, 0.965315,
0.377313, 0.678764, 0.744545, 0.097731, 0.396357, 0.247202, 0.520897,
0.613396, 0.542124, 0.146813, 0.255489, 0.810868, 0.638641, 0.980742,
@@ -163,7 +163,7 @@ static float hashpntf[768] = {
0.114246, 0.905043, 0.713870, 0.555261, 0.951333
};
-unsigned char hash[512] = {
+const unsigned char hash[512] = {
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,
@@ -194,7 +194,7 @@ unsigned char hash[512] = {
};
-float hashvectf[768] = {
+const float hashvectf[768] = {
0.33783, 0.715698, -0.611206, -0.944031, -0.326599, -0.045624, -0.101074, -0.416443, -0.903503, 0.799286, 0.49411,
-0.341949, -0.854645, 0.518036, 0.033936, 0.42514, -0.437866, -0.792114, -0.358948, 0.597046, 0.717377, -0.985413,
0.144714, 0.089294, -0.601776, -0.33728, -0.723907, -0.449921, 0.594513, 0.666382, 0.208313, -0.10791, 0.972076,
@@ -327,7 +327,8 @@ static float newPerlinU(float x, float y, float z)
/* Was BLI_hnoise(), removed noisesize, so other functions can call it without scaling. */
static float orgBlenderNoise(float x, float y, float z)
{
- register float cn1, cn2, cn3, cn4, cn5, cn6, i, *h;
+ register float cn1, cn2, cn3, cn4, cn5, cn6, i;
+ register const float *h;
float fx, fy, fz, ox, oy, oz, jx, jy, jz;
float n = 0.5;
int ix, iy, iz, b00, b01, b10, b11, b20, b21;
@@ -504,7 +505,7 @@ static const char p[512 + 2] = {
};
-static float g[512 + 2][3] = {
+static const float g[512 + 2][3] = {
{0.33783, 0.715698, -0.611206},
{-0.944031, -0.326599, -0.045624},
{-0.101074, -0.416443, -0.903503},
@@ -1034,7 +1035,8 @@ static float g[512 + 2][3] = {
static float noise3_perlin(float vec[3])
{
int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11;
- float rx0, rx1, ry0, ry1, rz0, rz1, *q, sx, sy, sz, a, b, c, d, t, u, v;
+ float rx0, rx1, ry0, ry1, rz0, rz1, sx, sy, sz, a, b, c, d, t, u, v;
+ const float *q;
register int i, j;
@@ -1095,7 +1097,7 @@ static float noise3_perlin(float vec[3])
}
#if 0
-static float turbulence_perlin(float *point, float lofreq, float hifreq)
+static float turbulence_perlin(const float point[3], float lofreq, float hifreq)
{
float freq, t, p[3];
@@ -1227,7 +1229,7 @@ static float dist_Minkovsky(float x, float y, float z, float e)
void voronoi(float x, float y, float z, float *da, float *pa, float me, int dtype)
{
int xx, yy, zz, xi, yi, zi;
- float xd, yd, zd, d, *p;
+ float xd, yd, zd, d;
float (*distfunc)(float, float, float, float);
switch (dtype) {
@@ -1262,7 +1264,7 @@ void voronoi(float x, float y, float z, float *da, float *pa, float me, int dtyp
for (xx = xi - 1; xx <= xi + 1; xx++) {
for (yy = yi - 1; yy <= yi + 1; yy++) {
for (zz = zi - 1; zz <= zi + 1; zz++) {
- p = HASHPNT(xx, yy, zz);
+ const float *p = HASHPNT(xx, yy, zz);
xd = x - (p[0] + xx);
yd = y - (p[1] + yy);
zd = z - (p[2] + zz);
@@ -1416,7 +1418,7 @@ void cellNoiseV(float x, float y, float z, float *ca)
int xi = (int)(floor(x));
int yi = (int)(floor(y));
int zi = (int)(floor(z));
- float *p = HASHPNT(xi, yi, zi);
+ const float *p = HASHPNT(xi, yi, zi);
ca[0] = p[0];
ca[1] = p[1];
ca[2] = p[2];
diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c
index 68e0f2c4026..d323098827b 100644
--- a/source/blender/blenlib/intern/path_util.c
+++ b/source/blender/blenlib/intern/path_util.c
@@ -1324,15 +1324,20 @@ const char *BLI_get_folder_version(const int id, const int ver, const bool do_ch
#endif
/**
- * Sets the specified environment variable to the specified value.
+ * Sets the specified environment variable to the specified value,
+ * and clears it if val == NULL.
*/
void BLI_setenv(const char *env, const char *val)
{
/* free windows */
#if (defined(WIN32) || defined(WIN64)) && defined(FREE_WINDOWS)
- char *envstr = MEM_mallocN(sizeof(char) * (strlen(env) + strlen(val) + 2), "envstr"); /* one for = another for \0 */
+ char *envstr;
+
+ if (val)
+ envstr = BLI_sprintfN("%s=%s", env, val);
+ else
+ envstr = BLI_sprintfN("%s=", env);
- sprintf(envstr, "%s=%s", env, val);
putenv(envstr);
MEM_freeN(envstr);
@@ -1343,7 +1348,10 @@ void BLI_setenv(const char *env, const char *val)
#else
/* linux/osx/bsd */
- setenv(env, val, 1);
+ if (val)
+ setenv(env, val, 1);
+ else
+ unsetenv(env);
#endif
}
diff --git a/source/blender/blenlib/intern/smallhash.c b/source/blender/blenlib/intern/smallhash.c
index 19eb88f9e15..9790ce1f0b4 100644
--- a/source/blender/blenlib/intern/smallhash.c
+++ b/source/blender/blenlib/intern/smallhash.c
@@ -55,7 +55,7 @@
((h) + (((hoff) = ((hoff) * 2) + 1), (hoff))) \
)
-extern unsigned int hashsizes[];
+extern const unsigned int hashsizes[];
void BLI_smallhash_init(SmallHash *hash)
{
diff --git a/source/blender/blenlib/intern/task.c b/source/blender/blenlib/intern/task.c
new file mode 100644
index 00000000000..7fa108b906f
--- /dev/null
+++ b/source/blender/blenlib/intern/task.c
@@ -0,0 +1,424 @@
+/*
+ * ***** 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 *****
+ */
+
+#include <stdlib.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_listbase.h"
+#include "BLI_task.h"
+#include "BLI_threads.h"
+
+/* Types */
+
+typedef struct Task {
+ struct Task *next, *prev;
+
+ TaskRunFunction run;
+ void *taskdata;
+ bool free_taskdata;
+ TaskPool *pool;
+} Task;
+
+struct TaskPool {
+ TaskScheduler *scheduler;
+
+ volatile size_t num;
+ volatile size_t done;
+ ThreadMutex num_mutex;
+ ThreadCondition num_cond;
+
+ void *userdata;
+ ThreadMutex user_mutex;
+
+ volatile bool do_cancel;
+};
+
+struct TaskScheduler {
+ pthread_t *threads;
+ struct TaskThread *task_threads;
+ int num_threads;
+
+ ListBase queue;
+ ThreadMutex queue_mutex;
+ ThreadCondition queue_cond;
+
+ volatile bool do_exit;
+};
+
+typedef struct TaskThread {
+ TaskScheduler *scheduler;
+ int id;
+} TaskThread;
+
+/* Task Scheduler */
+
+static void task_pool_num_decrease(TaskPool *pool, size_t done)
+{
+ BLI_mutex_lock(&pool->num_mutex);
+
+ BLI_assert(pool->num >= done);
+
+ pool->num -= done;
+ pool->done += done;
+
+ if (pool->num == 0)
+ BLI_condition_notify_all(&pool->num_cond);
+
+ BLI_mutex_unlock(&pool->num_mutex);
+}
+
+static void task_pool_num_increase(TaskPool *pool)
+{
+ BLI_mutex_lock(&pool->num_mutex);
+
+ pool->num++;
+ BLI_condition_notify_all(&pool->num_cond);
+
+ BLI_mutex_unlock(&pool->num_mutex);
+}
+
+static bool task_scheduler_thread_wait_pop(TaskScheduler *scheduler, Task **task)
+{
+ BLI_mutex_lock(&scheduler->queue_mutex);
+
+ while (!scheduler->queue.first && !scheduler->do_exit)
+ BLI_condition_wait(&scheduler->queue_cond, &scheduler->queue_mutex);
+
+ if (!scheduler->queue.first) {
+ BLI_mutex_unlock(&scheduler->queue_mutex);
+ BLI_assert(scheduler->do_exit);
+ return false;
+ }
+
+ *task = scheduler->queue.first;
+ BLI_remlink(&scheduler->queue, *task);
+
+ BLI_mutex_unlock(&scheduler->queue_mutex);
+
+ return true;
+}
+
+static void *task_scheduler_thread_run(void *thread_p)
+{
+ TaskThread *thread = (TaskThread *) thread_p;
+ TaskScheduler *scheduler = thread->scheduler;
+ int thread_id = thread->id;
+ Task *task;
+
+ /* keep popping off tasks */
+ while (task_scheduler_thread_wait_pop(scheduler, &task)) {
+ TaskPool *pool = task->pool;
+
+ /* run task */
+ task->run(pool, task->taskdata, thread_id);
+
+ /* delete task */
+ if (task->free_taskdata)
+ MEM_freeN(task->taskdata);
+ MEM_freeN(task);
+
+ /* notify pool task was done */
+ task_pool_num_decrease(pool, 1);
+ }
+
+ return NULL;
+}
+
+TaskScheduler *BLI_task_scheduler_create(int num_threads)
+{
+ TaskScheduler *scheduler = MEM_callocN(sizeof(TaskScheduler), "TaskScheduler");
+
+ /* multiple places can use this task scheduler, sharing the same
+ * threads, so we keep track of the number of users. */
+ scheduler->do_exit = false;
+
+ scheduler->queue.first = scheduler->queue.last = NULL;
+ BLI_mutex_init(&scheduler->queue_mutex);
+ BLI_condition_init(&scheduler->queue_cond);
+
+ if (num_threads == 0) {
+ /* automatic number of threads will be main thread + num cores */
+ num_threads = BLI_system_thread_count();
+ }
+
+ /* main thread will also work, so we count it too */
+ num_threads -= 1;
+
+ /* launch threads that will be waiting for work */
+ if (num_threads > 0) {
+ int i;
+
+ scheduler->num_threads = num_threads;
+ scheduler->threads = MEM_callocN(sizeof(pthread_t) * num_threads, "TaskScheduler threads");
+ scheduler->task_threads = MEM_callocN(sizeof(TaskThread) * num_threads, "TaskScheduler task threads");
+
+ for (i = 0; i < num_threads; i++) {
+ TaskThread *thread = &scheduler->task_threads[i];
+ thread->scheduler = scheduler;
+ thread->id = i + 1;
+
+ if (pthread_create(&scheduler->threads[i], NULL, task_scheduler_thread_run, thread) != 0) {
+ fprintf(stderr, "TaskScheduler failed to launch thread %d/%d\n", i, num_threads);
+ MEM_freeN(thread);
+ }
+ }
+ }
+
+ return scheduler;
+}
+
+void BLI_task_scheduler_free(TaskScheduler *scheduler)
+{
+ Task *task;
+
+ /* stop all waiting threads */
+ BLI_mutex_lock(&scheduler->queue_mutex);
+ scheduler->do_exit = true;
+ BLI_condition_notify_all(&scheduler->queue_cond);
+ BLI_mutex_unlock(&scheduler->queue_mutex);
+
+ /* delete threads */
+ if (scheduler->threads) {
+ int i;
+
+ for (i = 0; i < scheduler->num_threads; i++) {
+ if (pthread_join(scheduler->threads[i], NULL) != 0)
+ fprintf(stderr, "TaskScheduler failed to join thread %d/%d\n", i, scheduler->num_threads);
+ }
+
+ MEM_freeN(scheduler->threads);
+ }
+
+ /* Delete task thread data */
+ if (scheduler->task_threads) {
+ MEM_freeN(scheduler->task_threads);
+ }
+
+ /* delete leftover tasks */
+ for (task = scheduler->queue.first; task; task = task->next) {
+ if (task->free_taskdata)
+ MEM_freeN(task->taskdata);
+ }
+ BLI_freelistN(&scheduler->queue);
+
+ /* delete mutex/condition */
+ BLI_mutex_end(&scheduler->queue_mutex);
+ BLI_condition_end(&scheduler->queue_cond);
+
+ MEM_freeN(scheduler);
+}
+
+int BLI_task_scheduler_num_threads(TaskScheduler *scheduler)
+{
+ return scheduler->num_threads + 1;
+}
+
+static void task_scheduler_push(TaskScheduler *scheduler, Task *task, TaskPriority priority)
+{
+ task_pool_num_increase(task->pool);
+
+ /* add task to queue */
+ BLI_mutex_lock(&scheduler->queue_mutex);
+
+ if (priority == TASK_PRIORITY_HIGH)
+ BLI_addhead(&scheduler->queue, task);
+ else
+ BLI_addtail(&scheduler->queue, task);
+
+ BLI_condition_notify_one(&scheduler->queue_cond);
+ BLI_mutex_unlock(&scheduler->queue_mutex);
+}
+
+static void task_scheduler_clear(TaskScheduler *scheduler, TaskPool *pool)
+{
+ Task *task, *nexttask;
+ size_t done = 0;
+
+ BLI_mutex_lock(&scheduler->queue_mutex);
+
+ /* free all tasks from this pool from the queue */
+ for (task = scheduler->queue.first; task; task = nexttask) {
+ nexttask = task->next;
+
+ if (task->pool == pool) {
+ if (task->free_taskdata)
+ MEM_freeN(task->taskdata);
+ BLI_freelinkN(&scheduler->queue, task);
+
+ done++;
+ }
+ }
+
+ BLI_mutex_unlock(&scheduler->queue_mutex);
+
+ /* notify done */
+ task_pool_num_decrease(pool, done);
+}
+
+/* Task Pool */
+
+TaskPool *BLI_task_pool_create(TaskScheduler *scheduler, void *userdata)
+{
+ TaskPool *pool = MEM_callocN(sizeof(TaskPool), "TaskPool");
+
+ pool->scheduler = scheduler;
+ pool->num = 0;
+ pool->do_cancel = false;
+
+ BLI_mutex_init(&pool->num_mutex);
+ BLI_condition_init(&pool->num_cond);
+
+ pool->userdata = userdata;
+ BLI_mutex_init(&pool->user_mutex);
+
+ /* Ensure malloc will go fine from threads,
+ *
+ * This is needed because we could be in main thread here
+ * and malloc could be non-threda safe at this point because
+ * no other jobs are running.
+ */
+ BLI_begin_threaded_malloc();
+
+ return pool;
+}
+
+void BLI_task_pool_free(TaskPool *pool)
+{
+ BLI_task_pool_stop(pool);
+
+ BLI_mutex_end(&pool->num_mutex);
+ BLI_condition_end(&pool->num_cond);
+
+ BLI_mutex_end(&pool->user_mutex);
+
+ MEM_freeN(pool);
+
+ BLI_end_threaded_malloc();
+}
+
+void BLI_task_pool_push(TaskPool *pool, TaskRunFunction run,
+ void *taskdata, bool free_taskdata, TaskPriority priority)
+{
+ Task *task = MEM_callocN(sizeof(Task), "Task");
+
+ task->run = run;
+ task->taskdata = taskdata;
+ task->free_taskdata = free_taskdata;
+ task->pool = pool;
+
+ task_scheduler_push(pool->scheduler, task, priority);
+}
+
+void BLI_task_pool_work_and_wait(TaskPool *pool)
+{
+ TaskScheduler *scheduler = pool->scheduler;
+
+ BLI_mutex_lock(&pool->num_mutex);
+
+ while (pool->num != 0) {
+ Task *task, *work_task = NULL;
+ bool found_task = false;
+
+ BLI_mutex_unlock(&pool->num_mutex);
+
+ BLI_mutex_lock(&scheduler->queue_mutex);
+
+ /* find task from this pool. if we get a task from another pool,
+ * we can get into deadlock */
+
+ for (task = scheduler->queue.first; task; task = task->next) {
+ if (task->pool == pool) {
+ work_task = task;
+ found_task = true;
+ BLI_remlink(&scheduler->queue, task);
+ break;
+ }
+ }
+
+ BLI_mutex_unlock(&scheduler->queue_mutex);
+
+ /* if found task, do it, otherwise wait until other tasks are done */
+ if (found_task) {
+ /* run task */
+ work_task->run(pool, work_task->taskdata, 0);
+
+ /* delete task */
+ if (work_task->free_taskdata)
+ MEM_freeN(work_task->taskdata);
+ MEM_freeN(work_task);
+
+ /* notify pool task was done */
+ task_pool_num_decrease(pool, 1);
+ }
+
+ BLI_mutex_lock(&pool->num_mutex);
+ if (pool->num == 0)
+ break;
+
+ if (!found_task)
+ BLI_condition_wait(&pool->num_cond, &pool->num_mutex);
+ }
+
+ BLI_mutex_unlock(&pool->num_mutex);
+}
+
+void BLI_task_pool_cancel(TaskPool *pool)
+{
+ pool->do_cancel = true;
+
+ task_scheduler_clear(pool->scheduler, pool);
+
+ /* wait until all entries are cleared */
+ BLI_mutex_lock(&pool->num_mutex);
+ while (pool->num)
+ BLI_condition_wait(&pool->num_cond, &pool->num_mutex);
+ BLI_mutex_unlock(&pool->num_mutex);
+
+ pool->do_cancel = false;
+}
+
+void BLI_task_pool_stop(TaskPool *pool)
+{
+ task_scheduler_clear(pool->scheduler, pool);
+
+ BLI_assert(pool->num == 0);
+}
+
+bool BLI_task_pool_cancelled(TaskPool *pool)
+{
+ return pool->do_cancel;
+}
+
+void *BLI_task_pool_userdata(TaskPool *pool)
+{
+ return pool->userdata;
+}
+
+ThreadMutex *BLI_task_pool_user_mutex(TaskPool *pool)
+{
+ return &pool->user_mutex;
+}
+
+size_t BLI_task_pool_tasks_done(TaskPool *pool)
+{
+ return pool->done;
+}
+
diff --git a/source/blender/blenlib/intern/threads.c b/source/blender/blenlib/intern/threads.c
index c8b84d9310a..64682965649 100644
--- a/source/blender/blenlib/intern/threads.c
+++ b/source/blender/blenlib/intern/threads.c
@@ -37,6 +37,7 @@
#include "BLI_listbase.h"
#include "BLI_gsqueue.h"
+#include "BLI_task.h"
#include "BLI_threads.h"
#include "PIL_time.h"
@@ -63,6 +64,9 @@ extern pthread_key_t gomp_tls_key;
static void *thread_tls_data;
#endif
+/* We're using one global task scheduler for all kind of tasks. */
+static TaskScheduler *task_scheduler = NULL;
+
/* ********** basic thread control API ************
*
* Many thread cases have an X amount of jobs, and only an Y amount of
@@ -151,9 +155,26 @@ void BLI_threadapi_init(void)
void BLI_threadapi_exit(void)
{
+ if (task_scheduler) {
+ BLI_task_scheduler_free(task_scheduler);
+ }
BLI_spin_end(&_malloc_lock);
}
+TaskScheduler *BLI_task_scheduler_get(void)
+{
+ if (task_scheduler == NULL) {
+ int tot_thread = BLI_system_thread_count();
+
+ /* Do a lazy initialization, so it happes after
+ * command line arguments parsing
+ */
+ task_scheduler = BLI_task_scheduler_create(tot_thread);
+ }
+
+ return task_scheduler;
+}
+
/* tot = 0 only initializes malloc mutex in a safe way (see sequence.c)
* problem otherwise: scene render will kill of the mutex!
*/
@@ -419,6 +440,11 @@ void BLI_mutex_unlock(ThreadMutex *mutex)
pthread_mutex_unlock(mutex);
}
+bool BLI_mutex_trylock(ThreadMutex *mutex)
+{
+ return (pthread_mutex_trylock(mutex) == 0);
+}
+
void BLI_mutex_end(ThreadMutex *mutex)
{
pthread_mutex_destroy(mutex);
@@ -563,97 +589,31 @@ void BLI_ticket_mutex_unlock(TicketMutex *ticket)
/* ************************************************ */
-typedef struct ThreadedWorker {
- ListBase threadbase;
- void *(*work_fnct)(void *);
- char busy[RE_MAX_THREAD];
- int total;
- int sleep_time;
-} ThreadedWorker;
-
-typedef struct WorkParam {
- ThreadedWorker *worker;
- void *param;
- int index;
-} WorkParam;
+/* Condition */
-static void *exec_work_fnct(void *v_param)
+void BLI_condition_init(ThreadCondition *cond)
{
- WorkParam *p = (WorkParam *)v_param;
- void *value;
-
- value = p->worker->work_fnct(p->param);
-
- p->worker->busy[p->index] = 0;
- MEM_freeN(p);
-
- return value;
+ pthread_cond_init(cond, NULL);
}
-ThreadedWorker *BLI_create_worker(void *(*do_thread)(void *), int tot, int sleep_time)
+void BLI_condition_wait(ThreadCondition *cond, ThreadMutex *mutex)
{
- ThreadedWorker *worker;
-
- (void)sleep_time; /* unused */
-
- worker = MEM_callocN(sizeof(ThreadedWorker), "threadedworker");
-
- if (tot > RE_MAX_THREAD) {
- tot = RE_MAX_THREAD;
- }
- else if (tot < 1) {
- tot = 1;
- }
-
- worker->total = tot;
- worker->work_fnct = do_thread;
-
- BLI_init_threads(&worker->threadbase, exec_work_fnct, tot);
-
- return worker;
+ pthread_cond_wait(cond, mutex);
}
-void BLI_end_worker(ThreadedWorker *worker)
+void BLI_condition_notify_one(ThreadCondition *cond)
{
- BLI_remove_threads(&worker->threadbase);
+ pthread_cond_signal(cond);
}
-void BLI_destroy_worker(ThreadedWorker *worker)
+void BLI_condition_notify_all(ThreadCondition *cond)
{
- BLI_end_worker(worker);
- BLI_freelistN(&worker->threadbase);
- MEM_freeN(worker);
+ pthread_cond_broadcast(cond);
}
-void BLI_insert_work(ThreadedWorker *worker, void *param)
+void BLI_condition_end(ThreadCondition *cond)
{
- WorkParam *p = MEM_callocN(sizeof(WorkParam), "workparam");
- int index;
-
- if (BLI_available_threads(&worker->threadbase) == 0) {
- index = worker->total;
- while (index == worker->total) {
- PIL_sleep_ms(worker->sleep_time);
-
- for (index = 0; index < worker->total; index++) {
- if (worker->busy[index] == 0) {
- BLI_remove_thread_index(&worker->threadbase, index);
- break;
- }
- }
- }
- }
- else {
- index = BLI_available_thread_index(&worker->threadbase);
- }
-
- worker->busy[index] = 1;
-
- p->param = param;
- p->index = index;
- p->worker = worker;
-
- BLI_insert_thread(&worker->threadbase, p);
+ pthread_cond_destroy(cond);
}
/* ************************************************ */
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 942d5516dc7..a9e9a07a2b1 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -1776,6 +1776,27 @@ static void IDP_DirectLinkProperty(IDProperty *prop, int switch_endian, FileData
}
}
+#define IDP_DirectLinkGroup_OrFree(prop, switch_endian, fd) \
+ _IDP_DirectLinkGroup_OrFree(prop, switch_endian, fd, __func__)
+
+static void _IDP_DirectLinkGroup_OrFree(IDProperty **prop, int switch_endian, FileData *fd,
+ const char *caller_func_id)
+{
+ if (*prop) {
+ if ((*prop)->type == IDP_GROUP) {
+ IDP_DirectLinkGroup(*prop, switch_endian, fd);
+ }
+ else {
+ /* corrupt file! */
+ printf("%s: found non group data, freeing type %d!\n",
+ caller_func_id, (*prop)->type);
+ /* don't risk id, data's likely corrupt. */
+ // IDP_FreeProperty(*prop);
+ *prop = NULL;
+ }
+ }
+}
+
/* stub function */
static void IDP_LibLinkProperty(IDProperty *UNUSED(prop), int UNUSED(switch_endian), FileData *UNUSED(fd))
{
@@ -1788,9 +1809,8 @@ static void direct_link_id(FileData *fd, ID *id)
/*link direct data of ID properties*/
if (id->properties) {
id->properties = newdataadr(fd, id->properties);
- if (id->properties) { /* this case means the data was written incorrectly, it should not happen */
- IDP_DirectLinkProperty(id->properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
- }
+ /* this case means the data was written incorrectly, it should not happen */
+ IDP_DirectLinkGroup_OrFree(&id->properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
}
}
@@ -2041,7 +2061,7 @@ static void direct_link_fmodifiers(FileData *fd, ListBase *list)
FMod_Python *data = (FMod_Python *)fcm->data;
data->prop = newdataadr(fd, data->prop);
- IDP_DirectLinkProperty(data->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ IDP_DirectLinkGroup_OrFree(&data->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
}
break;
}
@@ -2596,8 +2616,7 @@ static void lib_verify_nodetree(Main *main, int UNUSED(open))
static void direct_link_node_socket(FileData *fd, bNodeSocket *sock)
{
sock->prop = newdataadr(fd, sock->prop);
- if (sock->prop)
- IDP_DirectLinkProperty(sock->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ IDP_DirectLinkGroup_OrFree(&sock->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
sock->link = newdataadr(fd, sock->link);
sock->typeinfo = NULL;
@@ -2635,8 +2654,7 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree)
link_list(fd, &node->outputs);
node->prop = newdataadr(fd, node->prop);
- if (node->prop)
- IDP_DirectLinkProperty(node->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ IDP_DirectLinkGroup_OrFree(&node->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
link_list(fd, &node->internal_links);
for (link = node->internal_links.first; link; link = link->next) {
@@ -2794,8 +2812,7 @@ static void direct_link_constraints(FileData *fd, ListBase *lb)
link_list(fd, &data->targets);
data->prop = newdataadr(fd, data->prop);
- if (data->prop)
- IDP_DirectLinkProperty(data->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ IDP_DirectLinkGroup_OrFree(&data->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
break;
}
case CONSTRAINT_TYPE_SPLINEIK:
@@ -2894,8 +2911,7 @@ static void direct_link_bones(FileData *fd, Bone *bone)
bone->parent = newdataadr(fd, bone->parent);
bone->prop = newdataadr(fd, bone->prop);
- if (bone->prop)
- IDP_DirectLinkProperty(bone->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ IDP_DirectLinkGroup_OrFree(&bone->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
bone->flag &= ~BONE_DRAW_ACTIVE;
@@ -4148,12 +4164,6 @@ static void direct_link_mesh(FileData *fd, Mesh *mesh)
direct_link_customdata(fd, &mesh->fdata, mesh->totface);
direct_link_customdata(fd, &mesh->ldata, mesh->totloop);
direct_link_customdata(fd, &mesh->pdata, mesh->totpoly);
-
- if (mesh->mloopuv || mesh->mtpoly) {
- /* for now we have to ensure texpoly and mloopuv layers are aligned
- * in the future we may allow non-aligned layers */
- BKE_mesh_cd_validate(mesh);
- }
mesh->bb = NULL;
mesh->edit_btmesh = NULL;
@@ -4163,6 +4173,12 @@ static void direct_link_mesh(FileData *fd, Mesh *mesh)
mesh->totselect = 0;
}
+ if (mesh->mloopuv || mesh->mtpoly) {
+ /* for now we have to ensure texpoly and mloopuv layers are aligned
+ * in the future we may allow non-aligned layers */
+ BKE_mesh_cd_validate(mesh);
+ }
+
/* Multires data */
mesh->mr= newdataadr(fd, mesh->mr);
if (mesh->mr) {
@@ -4544,8 +4560,7 @@ static void direct_link_pose(FileData *fd, bPose *pose)
direct_link_constraints(fd, &pchan->constraints);
pchan->prop = newdataadr(fd, pchan->prop);
- if (pchan->prop)
- IDP_DirectLinkProperty(pchan->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ IDP_DirectLinkGroup_OrFree(&pchan->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
pchan->mpath = newdataadr(fd, pchan->mpath);
if (pchan->mpath)
@@ -5445,10 +5460,7 @@ static void direct_link_scene(FileData *fd, Scene *sce)
}
if (sce->r.ffcodecdata.properties) {
sce->r.ffcodecdata.properties = newdataadr(fd, sce->r.ffcodecdata.properties);
- if (sce->r.ffcodecdata.properties) {
- IDP_DirectLinkProperty(sce->r.ffcodecdata.properties,
- (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
- }
+ IDP_DirectLinkGroup_OrFree(&sce->r.ffcodecdata.properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
}
link_list(fd, &(sce->markers));
@@ -6142,8 +6154,7 @@ static void direct_link_region(FileData *fd, ARegion *ar, int spacetype)
ui_list->type = NULL;
ui_list->dyn_data = NULL;
ui_list->properties = newdataadr(fd, ui_list->properties);
- if (ui_list->properties)
- IDP_DirectLinkProperty(ui_list->properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ IDP_DirectLinkGroup_OrFree(&ui_list->properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
}
if (spacetype == SPACE_EMPTY) {
@@ -9709,11 +9720,27 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
}
}
}
+
+ if (!MAIN_VERSION_ATLEAST(main, 269, 1)) {
+ /* Removal of Cycles SSS Compatible falloff */
+ FOREACH_NODETREE(main, ntree, id) {
+ if (ntree->type == NTREE_SHADER) {
+ bNode *node;
+ for (node = ntree->nodes.first; node; node = node->next) {
+ if (node->type == SH_NODE_SUBSURFACE_SCATTERING) {
+ if (node->custom1 == SHD_SUBSURFACE_COMPATIBLE) {
+ node->custom1 = SHD_SUBSURFACE_CUBIC;
+ }
+ }
+ }
+ }
+ } FOREACH_NODETREE_END
+ }
/* WATCH IT!!!: pointers from libdata have not been converted yet here! */
/* WATCH IT 2!: Userdef struct init see do_versions_userdef() above! */
- /* don't forget to set version number in blender.c! */
+ /* don't forget to set version number in BKE_blender.h! */
}
#if 0 // XXX: disabled for now... we still don't have this in the right place in the loading code for it to work
@@ -9769,8 +9796,7 @@ static void lib_link_all(FileData *fd, Main *main)
static void direct_link_keymapitem(FileData *fd, wmKeyMapItem *kmi)
{
kmi->properties = newdataadr(fd, kmi->properties);
- if (kmi->properties)
- IDP_DirectLinkProperty(kmi->properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ IDP_DirectLinkGroup_OrFree(&kmi->properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
kmi->ptr = NULL;
kmi->flag &= ~KMI_UPDATE;
}
@@ -9827,9 +9853,7 @@ static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead)
for (addon = user->addons.first; addon; addon = addon->next) {
addon->prop = newdataadr(fd, addon->prop);
- if (addon->prop) {
- IDP_DirectLinkProperty(addon->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
- }
+ IDP_DirectLinkGroup_OrFree(&addon->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
}
// XXX
diff --git a/source/blender/blenloader/intern/versioning_legacy.c b/source/blender/blenloader/intern/versioning_legacy.c
index f32215dbf03..067a8629906 100644
--- a/source/blender/blenloader/intern/versioning_legacy.c
+++ b/source/blender/blenloader/intern/versioning_legacy.c
@@ -1994,15 +1994,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
while (sce) {
if (sce->toolsettings == NULL) {
sce->toolsettings = MEM_callocN(sizeof(struct ToolSettings), "Tool Settings Struct");
- sce->toolsettings->cornertype =0;
- sce->toolsettings->degr = 90;
- sce->toolsettings->step = 9;
- sce->toolsettings->turn = 1;
- sce->toolsettings->extr_offs = 1;
sce->toolsettings->doublimit = 0.001f;
- sce->toolsettings->segments = 32;
- sce->toolsettings->rings = 32;
- sce->toolsettings->vertices = 32;
}
sce = sce->id.next;
}
@@ -2149,9 +2141,6 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
for (; sce; sce = sce->id.next) {
- /* make 'innervert' the default subdivide type, for backwards compat */
- sce->toolsettings->cornertype = 1;
-
if (sce->r.scemode & R_PASSEPARTOUT) {
set_passepartout = 1;
sce->r.scemode &= ~R_PASSEPARTOUT;
@@ -2238,11 +2227,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
ntree_version_241(sce->nodetree);
/* uv calculation options moved to toolsettings */
- if (sce->toolsettings->uvcalc_radius == 0.0f) {
- sce->toolsettings->uvcalc_radius = 1.0f;
- sce->toolsettings->uvcalc_cubesize = 1.0f;
- sce->toolsettings->uvcalc_mapdir = 1;
- sce->toolsettings->uvcalc_mapalign = 1;
+ if (sce->toolsettings->unwrapper == 0) {
sce->toolsettings->uvcalc_flag = UVCALC_FILLHOLES;
sce->toolsettings->unwrapper = 1;
}
@@ -2343,8 +2328,6 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
for (sce = main->scene.first; sce; sce = sce->id.next) {
if (sce->toolsettings->select_thresh == 0.0f)
sce->toolsettings->select_thresh = 0.01f;
- if (sce->toolsettings->clean_thresh == 0.0f)
- sce->toolsettings->clean_thresh = 0.1f;
if (sce->r.threads == 0) {
if (sce->r.mode & R_THREADS)
@@ -2554,14 +2537,6 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
sce->r.bake_flag = R_BAKE_CLEAR;
}
}
-
- if (main->subversionfile < 5) {
- for (sce = main->scene.first; sce; sce = sce->id.next) {
- /* improved triangle to quad conversion settings */
- if (sce->toolsettings->jointrilimit == 0.0f)
- sce->toolsettings->jointrilimit = 0.8f;
- }
- }
}
if (main->versionfile <= 243) {
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index de95b2c0c0a..cff5d796473 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -1738,7 +1738,7 @@ static void write_grid_paint_mask(WriteData *wd, int count, GridPaintMask *grid_
for (i = 0; i < count; ++i) {
GridPaintMask *gpm = &grid_paint_mask[i];
if (gpm->data) {
- const int gridsize = ccg_gridsize(gpm->level);
+ const int gridsize = BKE_ccg_gridsize(gpm->level);
writedata(wd, DATA,
sizeof(*gpm->data) * gridsize * gridsize,
gpm->data);
@@ -1810,7 +1810,7 @@ static void write_customdata(WriteData *wd, ID *id, int count, CustomData *data,
CustomData_free(&data_tmp, count);
}
-static void write_meshs(WriteData *wd, ListBase *idbase)
+static void write_meshes(WriteData *wd, ListBase *idbase)
{
Mesh *mesh;
int save_for_old_blender= 0;
@@ -2451,7 +2451,8 @@ static void write_soops(WriteData *wd, SpaceOops *so, LinkNode **tmp_mem_list)
/* restore old treestore */
so->treestore = ts;
- } else {
+ }
+ else {
writestruct(wd, DATA, "SpaceOops", 1, so);
}
}
@@ -3367,7 +3368,7 @@ static int write_file_handle(Main *mainvar, int handle, MemFile *compare, MemFil
write_objects (wd, &mainvar->object);
write_materials(wd, &mainvar->mat);
write_textures (wd, &mainvar->tex);
- write_meshs (wd, &mainvar->mesh);
+ write_meshes (wd, &mainvar->mesh);
write_particlesettings(wd, &mainvar->particle);
write_nodetrees(wd, &mainvar->nodetree);
write_brushes (wd, &mainvar->brush);
diff --git a/source/blender/bmesh/intern/bmesh_construct.c b/source/blender/bmesh/intern/bmesh_construct.c
index 60d9b62d6b9..1a7464ce340 100644
--- a/source/blender/bmesh/intern/bmesh_construct.c
+++ b/source/blender/bmesh/intern/bmesh_construct.c
@@ -500,10 +500,10 @@ BMFace *BM_face_create_ngon_vcloud(BMesh *bm, BMVert **vert_arr, int len,
*/
void BMO_remove_tagged_faces(BMesh *bm, const short oflag)
{
- BMFace *f;
+ BMFace *f, *f_next;
BMIter iter;
- BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
+ BM_ITER_MESH_MUTABLE (f, f_next, &iter, bm, BM_FACES_OF_MESH) {
if (BMO_elem_flag_test(bm, f, oflag)) {
BM_face_kill(bm, f);
}
@@ -512,10 +512,10 @@ void BMO_remove_tagged_faces(BMesh *bm, const short oflag)
void BMO_remove_tagged_edges(BMesh *bm, const short oflag)
{
- BMEdge *e;
+ BMEdge *e, *e_next;
BMIter iter;
- BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+ BM_ITER_MESH_MUTABLE (e, e_next, &iter, bm, BM_EDGES_OF_MESH) {
if (BMO_elem_flag_test(bm, e, oflag)) {
BM_edge_kill(bm, e);
}
@@ -524,10 +524,10 @@ void BMO_remove_tagged_edges(BMesh *bm, const short oflag)
void BMO_remove_tagged_verts(BMesh *bm, const short oflag)
{
- BMVert *v;
+ BMVert *v, *v_next;
BMIter iter;
- BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
+ BM_ITER_MESH_MUTABLE (v, v_next, &iter, bm, BM_VERTS_OF_MESH) {
if (BMO_elem_flag_test(bm, v, oflag)) {
BM_vert_kill(bm, v);
}
@@ -911,10 +911,7 @@ BMesh *BM_mesh_copy(BMesh *bm_old)
BMEditSelection *ese;
BMIter iter;
int i;
- const BMAllocTemplate allocsize = {bm_old->totvert,
- bm_old->totedge,
- bm_old->totloop,
- bm_old->totface};
+ const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_BM(bm_old);
/* allocate a bmesh */
bm_new = BM_mesh_create(&allocsize);
diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c
index 34e11f5c9f9..8441a6ec75f 100644
--- a/source/blender/bmesh/intern/bmesh_core.c
+++ b/source/blender/bmesh/intern/bmesh_core.c
@@ -1278,6 +1278,7 @@ BMFace *bmesh_sfme(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2,
}
if (!l_v1 || !l_v2) {
+ BLI_assert(0);
return NULL;
}
@@ -2278,3 +2279,28 @@ BMVert *bmesh_urmv(BMesh *bm, BMFace *f_sep, BMVert *v_sep)
BMLoop *l = BM_face_vert_share_loop(f_sep, v_sep);
return bmesh_urmv_loop(bm, l);
}
+
+/**
+ * Avoid calling this where possible,
+ * low level function so both face pointers remain intact but point to swapped data.
+ * \note must be from the same bmesh.
+ */
+void bmesh_face_swap_data(BMesh *bm, BMFace *f_a, BMFace *f_b)
+{
+ BMLoop *l_iter, *l_first;
+
+ BLI_assert(f_a != f_b);
+
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f_a);
+ do {
+ l_iter->f = f_b;
+ } while ((l_iter = l_iter->next) != l_first);
+
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f_b);
+ do {
+ l_iter->f = f_a;
+ } while ((l_iter = l_iter->next) != l_first);
+
+ SWAP(BMFace, (*f_a), (*f_b));
+ bm->elem_index_dirty |= BM_FACE;
+}
diff --git a/source/blender/bmesh/intern/bmesh_core.h b/source/blender/bmesh/intern/bmesh_core.h
index a18c2ebd32c..9e33509c2c8 100644
--- a/source/blender/bmesh/intern/bmesh_core.h
+++ b/source/blender/bmesh/intern/bmesh_core.h
@@ -87,4 +87,6 @@ BMFace *bmesh_jfke(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e);
BMVert *bmesh_urmv(BMesh *bm, BMFace *f_sep, BMVert *v_sep);
BMVert *bmesh_urmv_loop(BMesh *bm, BMLoop *l_sep);
+void bmesh_face_swap_data(BMesh *bm, BMFace *f_a, BMFace *f_b);
+
#endif /* __BMESH_CORE_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_iterators.c b/source/blender/bmesh/intern/bmesh_iterators.c
index 4555de7b13d..91b9774634d 100644
--- a/source/blender/bmesh/intern/bmesh_iterators.c
+++ b/source/blender/bmesh/intern/bmesh_iterators.c
@@ -54,6 +54,32 @@ const char bm_iter_itype_htype_map[BM_ITYPE_MAX] = {
};
/**
+ * Utility function.
+ */
+int BM_iter_mesh_count(BMesh *bm, const char itype)
+{
+ int count;
+
+ switch (itype) {
+ case BM_VERTS_OF_MESH:
+ count = bm->totvert;
+ break;
+ case BM_EDGES_OF_MESH:
+ count = bm->totedge;
+ break;
+ case BM_FACES_OF_MESH:
+ count = bm->totface;
+ break;
+ default:
+ count = 0;
+ BLI_assert(0);
+ break;
+ }
+
+ return count;
+}
+
+/**
* \note Use #BM_vert_at_index / #BM_edge_at_index / #BM_face_at_index for mesh arrays.
*/
void *BM_iter_at_index(BMesh *bm, const char itype, void *data, int index)
@@ -304,36 +330,66 @@ int BM_iter_mesh_count_flag(const char itype, BMesh *bm, const char hflag, const
* VERT OF MESH CALLBACKS
*/
+/* see bug [#36923] for why we need this,
+ * allow adding but not removing, this isnt _totally_ safe since
+ * you could add/remove within the same loop, but catches common cases
+ */
+#ifdef DEBUG
+# define USE_IMMUTABLE_ASSERT
+#endif
+
void bmiter__vert_of_mesh_begin(struct BMIter__vert_of_mesh *iter)
{
+#ifdef USE_IMMUTABLE_ASSERT
+ ((BMIter *)iter)->count = iter->bm->totvert;
+#endif
BLI_mempool_iternew(iter->bm->vpool, &iter->pooliter);
}
void *bmiter__vert_of_mesh_step(struct BMIter__vert_of_mesh *iter)
{
+#ifdef USE_IMMUTABLE_ASSERT
+ BLI_assert(((BMIter *)iter)->count <= iter->bm->totvert);
+#endif
return BLI_mempool_iterstep(&iter->pooliter);
}
void bmiter__edge_of_mesh_begin(struct BMIter__edge_of_mesh *iter)
{
+#ifdef USE_IMMUTABLE_ASSERT
+ ((BMIter *)iter)->count = iter->bm->totedge;
+#endif
BLI_mempool_iternew(iter->bm->epool, &iter->pooliter);
}
void *bmiter__edge_of_mesh_step(struct BMIter__edge_of_mesh *iter)
{
+#ifdef USE_IMMUTABLE_ASSERT
+ BLI_assert(((BMIter *)iter)->count <= iter->bm->totedge);
+#endif
return BLI_mempool_iterstep(&iter->pooliter);
}
void bmiter__face_of_mesh_begin(struct BMIter__face_of_mesh *iter)
{
+#ifdef USE_IMMUTABLE_ASSERT
+ ((BMIter *)iter)->count = iter->bm->totface;
+#endif
BLI_mempool_iternew(iter->bm->fpool, &iter->pooliter);
}
void *bmiter__face_of_mesh_step(struct BMIter__face_of_mesh *iter)
{
+#ifdef USE_IMMUTABLE_ASSERT
+ BLI_assert(((BMIter *)iter)->count <= iter->bm->totface);
+#endif
return BLI_mempool_iterstep(&iter->pooliter);
}
+#ifdef USE_IMMUTABLE_ASSERT
+# undef USE_IMMUTABLE_ASSERT
+#endif
+
/*
* EDGE OF VERT CALLBACKS
*/
diff --git a/source/blender/bmesh/intern/bmesh_iterators.h b/source/blender/bmesh/intern/bmesh_iterators.h
index bb25d3fabd1..fdf0f27f05f 100644
--- a/source/blender/bmesh/intern/bmesh_iterators.h
+++ b/source/blender/bmesh/intern/bmesh_iterators.h
@@ -89,6 +89,20 @@ extern const char bm_iter_itype_htype_map[BM_ITYPE_MAX];
#define BM_ITER_MESH_INDEX(ele, iter, bm, itype, indexvar) \
for (ele = BM_iter_new(iter, bm, itype, NULL), indexvar = 0; ele; ele = BM_iter_step(iter), (indexvar)++)
+/* a version of BM_ITER_MESH which keeps the next item in storage
+ * so we can delete the current item, see bug [#36923] */
+#ifdef DEBUG
+# define BM_ITER_MESH_MUTABLE(ele, ele_next, iter, bm, itype) \
+ for (ele = BM_iter_new(iter, bm, itype, NULL); \
+ ele ? ((void)((iter)->count = BM_iter_mesh_count(bm, itype)), \
+ (void)(ele_next = BM_iter_step(iter)), 1) : 0; \
+ ele = ele_next)
+#else
+# define BM_ITER_MESH_MUTABLE(ele, ele_next, iter, bm, itype) \
+ for (ele = BM_iter_new(iter, bm, itype, NULL); ele ? ((ele_next = BM_iter_step(iter)), 1) : 0; ele = ele_next)
+#endif
+
+
#define BM_ITER_ELEM(ele, iter, data, itype) \
for (ele = BM_iter_new(iter, NULL, itype, data); ele; ele = BM_iter_step(iter))
@@ -182,6 +196,7 @@ typedef struct BMIter {
char itype;
} BMIter;
+int BM_iter_mesh_count(BMesh *bm, const char itype);
void *BM_iter_at_index(BMesh *bm, const char itype, void *data, int index) ATTR_WARN_UNUSED_RESULT;
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,
diff --git a/source/blender/bmesh/intern/bmesh_mesh.h b/source/blender/bmesh/intern/bmesh_mesh.h
index efcd80b374b..583b1589290 100644
--- a/source/blender/bmesh/intern/bmesh_mesh.h
+++ b/source/blender/bmesh/intern/bmesh_mesh.h
@@ -60,6 +60,13 @@ typedef struct BMAllocTemplate {
extern const BMAllocTemplate bm_mesh_allocsize_default;
extern const BMAllocTemplate bm_mesh_chunksize_default;
+#define BMALLOC_TEMPLATE_FROM_BM(bm) { (CHECK_TYPE_INLINE(bm, BMesh *), \
+ (bm)->totvert), (bm)->totedge, (bm)->totloop, (bm)->totface}
+#define BMALLOC_TEMPLATE_FROM_ME(me) { (CHECK_TYPE_INLINE(me, Mesh *), \
+ (me)->totvert), (me)->totedge, (me)->totloop, (me)->totpoly}
+#define BMALLOC_TEMPLATE_FROM_DM(dm) { (CHECK_TYPE_INLINE(dm, DerivedMesh *), \
+ (dm)->getNumVerts(dm)), (dm)->getNumEdges(dm), (dm)->getNumLoops(dm), (dm)->getNumPolys(dm)}
+
enum {
BM_MESH_CREATE_USE_TOOLFLAGS = (1 << 0)
};
diff --git a/source/blender/bmesh/intern/bmesh_operators.c b/source/blender/bmesh/intern/bmesh_operators.c
index 284ff3e759c..611ee4d03b8 100644
--- a/source/blender/bmesh/intern/bmesh_operators.c
+++ b/source/blender/bmesh/intern/bmesh_operators.c
@@ -1639,9 +1639,9 @@ bool BMO_op_vinitf(BMesh *bm, BMOperator *op, const int flag, const char *_fmt,
// BMOpDefine *def;
char *opname, *ofmt, *fmt;
char slot_name[64] = {0};
- int i /*, n = strlen(fmt) */, stop /*, slot_code = -1 */, type, state;
+ int i, type;
+ bool noslot, state;
char htype;
- int noslot = 0;
/* basic useful info to help find where bmop formatting strings fail */
@@ -1662,7 +1662,7 @@ bool BMO_op_vinitf(BMesh *bm, BMOperator *op, const int flag, const char *_fmt,
i = strcspn(fmt, " ");
opname = fmt;
- if (!opname[i]) noslot = 1;
+ noslot = (opname[i] == '\0');
opname[i] = '\0';
fmt += i + (noslot ? 0 : 1);
@@ -1679,7 +1679,7 @@ bool BMO_op_vinitf(BMesh *bm, BMOperator *op, const int flag, const char *_fmt,
// def = bmo_opdefines[i];
i = 0;
- state = 1; /* 0: not inside slot_code name, 1: inside slot_code name */
+ state = true; /* false: not inside slot_code name, true: inside slot_code name */
while (*fmt) {
if (state) {
@@ -1705,7 +1705,7 @@ bool BMO_op_vinitf(BMesh *bm, BMOperator *op, const int flag, const char *_fmt,
BLI_strncpy(slot_name, fmt, sizeof(slot_name));
- state = 0;
+ state = false;
fmt += i;
}
else {
@@ -1726,13 +1726,13 @@ bool BMO_op_vinitf(BMesh *bm, BMOperator *op, const int flag, const char *_fmt,
else GOTO_ERROR("matrix size was not 3 or 4");
BMO_slot_mat_set(op, op->slots_in, slot_name, va_arg(vlist, void *), size);
- state = 1;
+ state = true;
break;
}
case 'v':
{
BMO_slot_vec_set(op->slots_in, slot_name, va_arg(vlist, float *));
- state = 1;
+ state = true;
break;
}
case 'e': /* single vert/edge/face */
@@ -1742,7 +1742,7 @@ bool BMO_op_vinitf(BMesh *bm, BMOperator *op, const int flag, const char *_fmt,
BMO_slot_buffer_from_single(op, slot, ele);
- state = 1;
+ state = true;
break;
}
case 's':
@@ -1761,20 +1761,20 @@ bool BMO_op_vinitf(BMesh *bm, BMOperator *op, const int flag, const char *_fmt,
BMO_slot_copy(op_other, slots_out, slot_name_other,
op, slots_in, slot_name);
}
- state = 1;
+ state = true;
break;
}
case 'i':
BMO_slot_int_set(op->slots_in, slot_name, va_arg(vlist, int));
- state = 1;
+ state = true;
break;
case 'b':
BMO_slot_bool_set(op->slots_in, slot_name, va_arg(vlist, int));
- state = 1;
+ state = true;
break;
case 'p':
BMO_slot_ptr_set(op->slots_in, slot_name, va_arg(vlist, void *));
- state = 1;
+ state = true;
break;
case 'f':
case 'F':
@@ -1787,15 +1787,16 @@ bool BMO_op_vinitf(BMesh *bm, BMOperator *op, const int flag, const char *_fmt,
BMO_slot_float_set(op->slots_in, slot_name, va_arg(vlist, double));
}
else {
+ bool stop = false;
+
htype = 0;
- stop = 0;
while (1) {
switch (NEXT_CHAR(fmt)) {
case 'f': htype |= BM_FACE; break;
case 'e': htype |= BM_EDGE; break;
case 'v': htype |= BM_VERT; break;
default:
- stop = 1;
+ stop = true;
break;
}
if (stop) {
@@ -1822,7 +1823,7 @@ bool BMO_op_vinitf(BMesh *bm, BMOperator *op, const int flag, const char *_fmt,
}
}
- state = 1;
+ state = true;
break;
default:
fprintf(stderr,
diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c
index dbfb08454e4..1dfd2535913 100644
--- a/source/blender/bmesh/intern/bmesh_polygon.c
+++ b/source/blender/bmesh/intern/bmesh_polygon.c
@@ -30,10 +30,9 @@
#include "DNA_listBase.h"
-#include "MEM_guardedalloc.h"
-
#include "BLI_alloca.h"
#include "BLI_math.h"
+#include "BLI_memarena.h"
#include "BLI_scanfill.h"
#include "BLI_listbase.h"
@@ -801,261 +800,125 @@ bool BM_face_point_inside_test(BMFace *f, const float co[3])
return crosses % 2 != 0;
}
-static bool bm_face_goodline(float const (*projectverts)[2], BMFace *f, int v1i, int v2i, int v3i)
-{
- BMLoop *l_iter;
- BMLoop *l_first;
-
- float pv1[2];
- const float *v1 = projectverts[v1i];
- const float *v2 = projectverts[v2i];
- const float *v3 = projectverts[v3i];
- int i;
-
- /* v3 must be on the left side of [v1, v2] line, else we know [v1, v3] is outside of f! */
- if (testedgesidef(v1, v2, v3)) {
- return false;
- }
-
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- i = BM_elem_index_get(l_iter->v);
- copy_v2_v2(pv1, projectverts[i]);
-
- if (ELEM3(i, v1i, v2i, v3i)) {
-#if 0
- printf("%d in (%d, %d, %d) tri (from indices!), continuing\n", i, v1i, v2i, v3i);
-#endif
- continue;
- }
-
- if (isect_point_tri_v2(pv1, v1, v2, v3) ||
- isect_point_tri_v2(pv1, v3, v2, v1))
- {
-#if 0
- if (isect_point_tri_v2(pv1, v1, v2, v3))
- printf("%d in (%d, %d, %d)\n", v3i, i, v1i, v2i);
- else
- printf("%d in (%d, %d, %d)\n", v1i, i, v3i, v2i);
-#endif
- return false;
- }
- } while ((l_iter = l_iter->next) != l_first);
- return true;
-}
-
/**
- * \brief Find Ear
+ * \brief BMESH TRIANGULATE FACE
+ *
+ * Currently repeatedly find the best triangle (i.e. the most "open" one), provided it does not
+ * produces a "remaining" face with too much wide/narrow angles
+ * (using cos (i.e. dot product of normalized vectors) of angles).
*
- * Used by tessellator to find the next triangle to 'clip off' of a polygon while tessellating.
+ * \param r_faces_new if non-null, must be an array of BMFace pointers,
+ * with a length equal to (f->len - 2). It will be filled with the new
+ * triangles.
*
- * \param f The face to search.
- * \param projectverts an array of face vert coords.
- * \param use_beauty Currently only applies to quads, can be extended later on.
- * \param abscoss Must be allocated by caller, and at least f->len length
- * (allow to avoid allocating a new one for each tri!).
+ * \note use_tag tags new flags and edges.
*/
-static BMLoop *poly_find_ear(BMFace *f, float (*projectverts)[2], const bool use_beauty, float *abscoss)
+void BM_face_triangulate(BMesh *bm, BMFace *f,
+ BMFace **r_faces_new,
+ MemArena *sf_arena,
+ const bool UNUSED(use_beauty), const bool use_tag)
{
- BMLoop *bestear = NULL;
+ int nf_i = 0;
+ BMLoop *l_iter, *l_first, *l_new;
+ BMFace *f_new;
- BMLoop *l_iter;
- BMLoop *l_first;
-
- const float cos_threshold = 0.9f;
- const float bias = 1.0f + 1e-6f;
+ BLI_assert(BM_face_is_normal_valid(f));
- BLI_assert(len_squared_v3(f->no) > FLT_EPSILON);
if (f->len == 4) {
- BMLoop *larr[4];
- int i = 0, i4;
- float cos1, cos2;
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- larr[i] = l_iter;
- i++;
- } while ((l_iter = l_iter->next) != l_first);
+ l_first = BM_FACE_FIRST_LOOP(f);
- /* pick 0/1 based on best length */
- /* 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) * 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! */
- cos1 = fabsf(cos_v3v3v3(larr[i4]->v->co, larr[i]->v->co, larr[i + 1]->v->co));
- cos2 = fabsf(cos_v3v3v3(larr[i4]->v->co, larr[i + 2]->v->co, larr[i + 1]->v->co));
-#if 0
- printf("%d, (%f, %f), (%f, %f)\n", i, cos1, cos2,
- fabsf(cos_v3v3v3(larr[i]->v->co, larr[i4]->v->co, larr[i + 2]->v->co)),
- fabsf(cos_v3v3v3(larr[i]->v->co, larr[i + 1]->v->co, larr[i + 2]->v->co)));
-#endif
- if (cos1 < cos2)
- cos1 = cos2;
-
- if (cos1 > cos_threshold) {
- if (cos1 > fabsf(cos_v3v3v3(larr[i]->v->co, larr[i4]->v->co, larr[i + 2]->v->co)) &&
- cos1 > fabsf(cos_v3v3v3(larr[i]->v->co, larr[i + 1]->v->co, larr[i + 2]->v->co)))
- {
- i = !i;
- }
- }
- /* Last check we do not get overlapping triangles
- * (as much as possible, there are some cases with no good solution!) */
- i4 = (i + 3) % 4;
- if (!bm_face_goodline((float const (*)[2])projectverts, f,
- BM_elem_index_get(larr[i4]->v),
- BM_elem_index_get(larr[i]->v),
- BM_elem_index_get(larr[i + 1]->v)))
- {
- i = !i;
+ f_new = BM_face_split(bm, f, l_first->v, l_first->next->next->v, &l_new, NULL, false);
+ copy_v3_v3(f_new->no, f->no);
+
+ if (use_tag) {
+ BM_elem_flag_enable(l_new->e, BM_ELEM_TAG);
+ BM_elem_flag_enable(f, BM_ELEM_TAG);
}
-/* printf("%d\n", i);*/
- bestear = larr[i];
+ if (r_faces_new) {
+ r_faces_new[nf_i++] = f_new;
+ }
}
- else {
- /* float angle, bestangle = 180.0f; */
- const int len = f->len;
- float cos, cos_best = 1.0f;
- int i, j;
+ else if (f->len > 4) {
+ /* scanfill */
+ ScanFillContext sf_ctx;
+ ScanFillVert *sf_vert, *sf_vert_prev = NULL;
+ ScanFillFace *sf_tri;
+ int totfilltri;
- /* Compute cos of all corners! */
- i = 0;
+ /* populate scanfill */
+ BLI_scanfill_begin_arena(&sf_ctx, sf_arena);
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- const BMVert *v1 = l_iter->prev->v;
- const BMVert *v2 = l_iter->v;
- const BMVert *v3 = l_iter->next->v;
- abscoss[i] = fabsf(cos_v3v3v3(v1->co, v2->co, v3->co));
-/* printf("tcoss: %f\n", *tcoss);*/
- i++;
- } while ((l_iter = l_iter->next) != l_first);
+ /* step once before entering the loop */
+ sf_vert = BLI_scanfill_vert_add(&sf_ctx, l_iter->v->co);
+ sf_vert->tmp.p = l_iter;
+ sf_vert_prev = sf_vert;
+ l_iter = l_iter->next;
- i = 0;
- l_iter = l_first;
do {
- const BMVert *v1 = l_iter->prev->v;
- const BMVert *v2 = l_iter->v;
- const BMVert *v3 = l_iter->next->v;
-
- /* Compute highest cos (i.e. narrowest angle) of this tri. */
- cos = max_fff(abscoss[i],
- fabsf(cos_v3v3v3(v2->co, v3->co, v1->co)),
- fabsf(cos_v3v3v3(v3->co, v1->co, v2->co)));
-
- /* Compare to prev best (i.e. lowest) cos. */
- if (cos < cos_best) {
- if (bm_face_goodline((float const (*)[2])projectverts, f,
- BM_elem_index_get(v1),
- BM_elem_index_get(v2),
- BM_elem_index_get(v3)))
- {
- /* We must check this tri would not leave a (too much) degenerated remaining face! */
- /* For now just assume if the average of cos of all
- * "remaining face"'s corners is below a given threshold, it's OK. */
- float cos_mean = fabsf(cos_v3v3v3(v1->co, v3->co, l_iter->next->next->v->co));
- const int i_limit = (i - 1 + len) % len;
- cos_mean += fabsf(cos_v3v3v3(l_iter->prev->prev->v->co, v1->co, v3->co));
- j = (i + 2) % len;
- do {
- cos_mean += abscoss[j];
- } while ((j = (j + 1) % len) != i_limit);
- cos_mean /= len - 1;
-
- /* We need a best ear in any case... */
- if (cos_mean < cos_threshold || (!bestear && cos_mean < 1.0f)) {
- /* OKI, keep this ear (corner...) as a potential best one! */
- bestear = l_iter;
- cos_best = cos;
- }
-#if 0
- else
- printf("Had a nice tri (higest cos of %f, current cos_best is %f), "
- "but average cos of all \"remaining face\"'s corners is too high (%f)!\n",
- cos, cos_best, cos_mean);
-#endif
- }
- }
- i++;
+ sf_vert = BLI_scanfill_vert_add(&sf_ctx, l_iter->v->co);
+ BLI_scanfill_edge_add(&sf_ctx, sf_vert_prev, sf_vert);
+
+ sf_vert->tmp.p = l_iter;
+ sf_vert_prev = sf_vert;
} while ((l_iter = l_iter->next) != l_first);
- }
- return bestear;
-}
+ BLI_scanfill_edge_add(&sf_ctx, sf_vert_prev, sf_ctx.fillvertbase.first);
-/**
- * \brief BMESH TRIANGULATE FACE
- *
- * Currently repeatedly find the best triangle (i.e. the most "open" one), provided it does not
- * produces a "remaining" face with too much wide/narrow angles
- * (using cos (i.e. dot product of normalized vectors) of angles).
- *
- * \param r_faces_new if non-null, must be an array of BMFace pointers,
- * with a length equal to (f->len - 2). It will be filled with the new
- * triangles.
- *
- * \note use_tag tags new flags and edges.
- */
-void BM_face_triangulate(BMesh *bm, BMFace *f,
- BMFace **r_faces_new,
- const bool use_beauty, const bool use_tag)
-{
- const float f_len_orig = f->len;
- int i, nf_i = 0;
- BMLoop *l_new;
- BMLoop *l_iter;
- BMLoop *l_first;
- /* BM_face_triangulate: temp absolute cosines of face corners */
- float (*projectverts)[2] = BLI_array_alloca(projectverts, f_len_orig);
- float *abscoss = BLI_array_alloca(abscoss, f_len_orig);
- float mat[3][3];
+ /* calculate filled triangles */
+ totfilltri = BLI_scanfill_calc_ex(&sf_ctx, 0, f->no);
+ BLI_assert(totfilltri <= f->len - 2);
- BLI_assert(BM_face_is_normal_valid(f));
- axis_dominant_v3_to_m3(mat, f->no);
+ /* loop over calculated triangles and create new geometry */
+ for (sf_tri = sf_ctx.fillfacebase.first; sf_tri; sf_tri = sf_tri->next) {
+ /* the order is reverse, otherwise the normal is flipped */
+ BMLoop *l_tri[3] = {
+ sf_tri->v3->tmp.p,
+ sf_tri->v2->tmp.p,
+ sf_tri->v1->tmp.p};
- /* copy vertex coordinates to vertspace area */
- i = 0;
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- mul_v2_m3v3(projectverts[i], mat, l_iter->v->co);
- BM_elem_index_set(l_iter->v, i++); /* set dirty! */
- } while ((l_iter = l_iter->next) != l_first);
+ BMVert *v_tri[3] = {
+ l_tri[0]->v,
+ l_tri[1]->v,
+ l_tri[2]->v};
- bm->elem_index_dirty |= BM_VERT; /* see above */
+ f_new = BM_face_create_verts(bm, v_tri, 3, f, false, true);
+ l_new = BM_FACE_FIRST_LOOP(f_new);
- while (f->len > 3) {
- l_iter = poly_find_ear(f, projectverts, use_beauty, abscoss);
+ BLI_assert(v_tri[0] == l_new->v);
- /* force triangulation - if we can't find an ear the face is degenerate */
- if (l_iter == NULL) {
- l_iter = BM_FACE_FIRST_LOOP(f);
- }
+ /* copy CD data */
+ BM_elem_attrs_copy(bm, bm, l_tri[0], l_new);
+ BM_elem_attrs_copy(bm, bm, l_tri[1], l_new->next);
+ BM_elem_attrs_copy(bm, bm, l_tri[2], l_new->prev);
-/* printf("Subdividing face...\n");*/
- f = BM_face_split(bm, l_iter->f, l_iter->prev->v, l_iter->next->v, &l_new, NULL, true);
+ if (use_tag) {
+ BM_elem_flag_enable(l_new->e, BM_ELEM_TAG);
+ }
- if (UNLIKELY(!f)) {
- fprintf(stderr, "%s: triangulator failed to split face! (bmesh internal error)\n", __func__);
- break;
+ /* add all but the last face which is swapped and removed (below) */
+ if (r_faces_new && sf_tri->prev) {
+ r_faces_new[nf_i++] = f_new;
+ }
}
- copy_v3_v3(f->no, l_iter->f->no);
+ if (sf_ctx.fillfacebase.first) {
+ /* we can't delete the real face, because some of the callers expect it to remain valid.
+ * so swap data and delete the last created tri */
+ bmesh_face_swap_data(bm, f, f_new);
+ BM_face_kill(bm, f_new);
- if (use_tag) {
- BM_elem_flag_enable(l_new->e, BM_ELEM_TAG);
- BM_elem_flag_enable(f, BM_ELEM_TAG);
+ if (use_tag) {
+ BM_elem_flag_enable(f, BM_ELEM_TAG);
+ }
}
- if (r_faces_new) {
- r_faces_new[nf_i++] = f;
- }
+ /* garbage collection */
+ BLI_scanfill_end_arena(&sf_ctx, sf_arena);
}
-
- BLI_assert(f->len == 3);
}
/**
diff --git a/source/blender/bmesh/intern/bmesh_polygon.h b/source/blender/bmesh/intern/bmesh_polygon.h
index 14fe1e76360..b7117621273 100644
--- a/source/blender/bmesh/intern/bmesh_polygon.h
+++ b/source/blender/bmesh/intern/bmesh_polygon.h
@@ -53,6 +53,7 @@ void BM_face_normal_flip(BMesh *bm, BMFace *f) ATTR_NONNULL();
bool BM_face_point_inside_test(BMFace *f, const float co[3]) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
void BM_face_triangulate(BMesh *bm, BMFace *f, BMFace **newfaces,
+ struct MemArena *sf_arena,
const bool use_beauty, const bool use_tag) ATTR_NONNULL(1, 2);
void BM_face_legal_splits(BMFace *f, BMLoop *(*loops)[2], int len) ATTR_NONNULL();
diff --git a/source/blender/bmesh/intern/bmesh_walkers_impl.c b/source/blender/bmesh/intern/bmesh_walkers_impl.c
index a68d9ccd2bc..238b7b4aaaa 100644
--- a/source/blender/bmesh/intern/bmesh_walkers_impl.c
+++ b/source/blender/bmesh/intern/bmesh_walkers_impl.c
@@ -26,6 +26,8 @@
* BMesh Walker Code.
*/
+#include <string.h>
+
#include "BLI_utildefines.h"
#include "BKE_customdata.h"
@@ -34,6 +36,12 @@
#include "intern/bmesh_private.h"
#include "intern/bmesh_walkers_private.h"
+/* pop into stack memory (common operation) */
+#define BMW_state_remove_r(walker, owalk) { \
+ memcpy(owalk, BMW_current_state(walker), sizeof(*(owalk))); \
+ BMW_state_remove(walker); \
+} (void)0
+
static bool bmw_mask_check_vert(BMWalker *walker, BMVert *v)
{
if ((walker->flag & BMW_FLAG_TEST_HIDDEN) && BM_elem_flag_test(v, BM_ELEM_HIDDEN)) {
@@ -140,14 +148,16 @@ static void *bmw_ShellWalker_yield(BMWalker *walker)
static void *bmw_ShellWalker_step(BMWalker *walker)
{
- BMwShellWalker *swalk = BMW_current_state(walker);
+ BMwShellWalker *swalk, owalk;
BMEdge *e, *e2;
BMVert *v;
BMIter iter;
int i;
+ BMW_state_remove_r(walker, &owalk);
+ swalk = &owalk;
+
e = swalk->curedge;
- BMW_state_remove(walker);
for (i = 0; i < 2; i++) {
v = i ? e->v2 : e->v1;
@@ -240,14 +250,15 @@ static void *bmw_ConnectedVertexWalker_yield(BMWalker *walker)
static void *bmw_ConnectedVertexWalker_step(BMWalker *walker)
{
- BMwConnectedVertexWalker *vwalk = BMW_current_state(walker);
+ BMwConnectedVertexWalker *vwalk, owalk;
BMVert *v, *v2;
BMEdge *e;
BMIter iter;
- v = vwalk->curvert;
+ BMW_state_remove_r(walker, &owalk);
+ vwalk = &owalk;
- BMW_state_remove(walker);
+ v = vwalk->curvert;
BM_ITER_ELEM (e, &iter, v, BM_EDGES_OF_VERT) {
v2 = BM_edge_other_vert(e, v);
@@ -289,14 +300,19 @@ static void *bmw_IslandboundWalker_yield(BMWalker *walker)
static void *bmw_IslandboundWalker_step(BMWalker *walker)
{
- BMwIslandboundWalker *iwalk = BMW_current_state(walker), owalk;
+ BMwIslandboundWalker *iwalk, owalk;
BMVert *v;
- BMEdge *e = iwalk->curloop->e;
+ BMEdge *e;
BMFace *f;
- BMLoop *l = iwalk->curloop;
+ BMLoop *l;
/* int found = 0; */
- owalk = *iwalk;
+ memcpy(&owalk, BMW_current_state(walker), sizeof(owalk));
+ /* normally we'd remove here, but delay until after error checking */
+ iwalk = &owalk;
+
+ l = iwalk->curloop;
+ e = l->e;
v = BM_edge_other_vert(e, iwalk->lastv);
@@ -307,7 +323,7 @@ static void *bmw_IslandboundWalker_step(BMWalker *walker)
return NULL;
}
- /* pop off current stat */
+ /* pop off current state */
BMW_state_remove(walker);
f = l->f;
@@ -381,13 +397,13 @@ static void *bmw_IslandWalker_yield(BMWalker *walker)
static void *bmw_IslandWalker_step(BMWalker *walker)
{
- BMwIslandWalker *iwalk = BMW_current_state(walker);
- /* BMwIslandWalker *owalk = iwalk; */ /* UNUSED */
+ BMwIslandWalker *iwalk, owalk;
BMIter iter, liter;
- BMFace *f, *curf = iwalk->cur;
+ BMFace *f;
BMLoop *l;
- BMW_state_remove(walker);
+ BMW_state_remove_r(walker, &owalk);
+ iwalk = &owalk;
l = BM_iter_new(&liter, walker->bm, BM_LOOPS_OF_FACE, iwalk->cur);
for ( ; l; l = BM_iter_step(&liter)) {
@@ -419,7 +435,7 @@ static void *bmw_IslandWalker_step(BMWalker *walker)
}
}
- return curf;
+ return owalk.cur;
}
@@ -507,15 +523,16 @@ static void *bmw_LoopWalker_yield(BMWalker *walker)
static void *bmw_LoopWalker_step(BMWalker *walker)
{
- BMwLoopWalker *lwalk = BMW_current_state(walker), owalk;
- BMEdge *e = lwalk->cur, *nexte = NULL;
+ BMwLoopWalker *lwalk, owalk;
+ BMEdge *e, *nexte = NULL;
BMLoop *l;
BMVert *v;
int i = 0;
- owalk = *lwalk;
- BMW_state_remove(walker);
+ BMW_state_remove_r(walker, &owalk);
+ lwalk = &owalk;
+ e = lwalk->cur;
l = e->l;
if (owalk.f_hub) { /* NGON EDGE */
@@ -770,13 +787,15 @@ static void *bmw_FaceLoopWalker_yield(BMWalker *walker)
static void *bmw_FaceLoopWalker_step(BMWalker *walker)
{
- BMwFaceLoopWalker *lwalk = BMW_current_state(walker);
- BMFace *f = lwalk->l->f;
- BMLoop *l = lwalk->l, *origl = lwalk->l;
+ BMwFaceLoopWalker *lwalk, owalk;
+ BMFace *f;
+ BMLoop *l;
- BMW_state_remove(walker);
+ BMW_state_remove_r(walker, &owalk);
+ lwalk = &owalk;
- l = l->radial_next;
+ f = lwalk->l->f;
+ l = lwalk->l->radial_next;
if (lwalk->no_calc) {
return f;
@@ -797,7 +816,7 @@ static void *bmw_FaceLoopWalker_step(BMWalker *walker)
if (l->f->len != 4) {
lwalk->no_calc = true;
- lwalk->l = origl;
+ lwalk->l = owalk.l;
}
else {
lwalk->no_calc = false;
@@ -878,19 +897,21 @@ static void *bmw_EdgeringWalker_yield(BMWalker *walker)
static void *bmw_EdgeringWalker_step(BMWalker *walker)
{
- BMwEdgeringWalker *lwalk = BMW_current_state(walker);
- BMEdge *e, *wireedge = lwalk->wireedge;
- BMLoop *l = lwalk->l, *origl = lwalk->l;
+ BMwEdgeringWalker *lwalk, owalk;
+ BMEdge *e;
+ BMLoop *l;
#ifdef BMW_EDGERING_NGON
int i, len;
#endif
#define EDGE_CHECK(e) (bmw_mask_check_edge(walker, e) && (BM_edge_is_boundary(e) || BM_edge_is_manifold(e)))
- BMW_state_remove(walker);
+ BMW_state_remove_r(walker, &owalk);
+ lwalk = &owalk;
+ l = lwalk->l;
if (!l)
- return wireedge;
+ return lwalk->wireedge;
e = l->e;
if (!EDGE_CHECK(e)) {
@@ -913,7 +934,7 @@ static void *bmw_EdgeringWalker_step(BMWalker *walker)
if ((len <= 0) || (len % 2 != 0) || !EDGE_CHECK(l->e) ||
!bmw_mask_check_face(walker, l->f))
{
- l = origl;
+ l = owalk.l;
i = len;
while (i > 0) {
l = l->next;
@@ -930,7 +951,7 @@ static void *bmw_EdgeringWalker_step(BMWalker *walker)
l = l->next->next;
if ((l->f->len != 4) || !EDGE_CHECK(l->e) || !bmw_mask_check_face(walker, l->f)) {
- l = origl->next->next;
+ l = owalk.l->next->next;
}
/* only walk to manifold edge */
if ((l->f->len == 4) && EDGE_CHECK(l->e) &&
@@ -975,17 +996,18 @@ static void *bmw_UVEdgeWalker_yield(BMWalker *walker)
static void *bmw_UVEdgeWalker_step(BMWalker *walker)
{
- BMwUVEdgeWalker *lwalk = BMW_current_state(walker);
+ const int type = walker->bm->ldata.layers[walker->layer].type;
+ BMwUVEdgeWalker *lwalk, owalk;
BMLoop *l, *l2, *l3, *nl, *cl;
BMIter liter;
void *d1, *d2;
- int i, j, rlen, type;
+ int i, j, rlen;
+
+ BMW_state_remove_r(walker, &owalk);
+ lwalk = &owalk;
l = lwalk->l;
nl = l->next;
- type = walker->bm->ldata.layers[walker->layer].type;
-
- BMW_state_remove(walker);
if (!bmw_mask_check_edge(walker, l->e)) {
return l;
diff --git a/source/blender/bmesh/operators/bmo_bridge.c b/source/blender/bmesh/operators/bmo_bridge.c
index 9dfbf951fc0..10d15d93995 100644
--- a/source/blender/bmesh/operators/bmo_bridge.c
+++ b/source/blender/bmesh/operators/bmo_bridge.c
@@ -26,8 +26,6 @@
* Connect verts across faces (splits faces) and bridge tool.
*/
-#include "MEM_guardedalloc.h"
-
#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "BLI_listbase.h"
diff --git a/source/blender/bmesh/operators/bmo_connect.c b/source/blender/bmesh/operators/bmo_connect.c
index b3a42ba533e..d0f64eb2892 100644
--- a/source/blender/bmesh/operators/bmo_connect.c
+++ b/source/blender/bmesh/operators/bmo_connect.c
@@ -26,8 +26,6 @@
* Connect verts across faces (splits faces).
*/
-#include "MEM_guardedalloc.h"
-
#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "BLI_alloca.h"
diff --git a/source/blender/bmesh/operators/bmo_connect_nonplanar.c b/source/blender/bmesh/operators/bmo_connect_nonplanar.c
index 61085596acc..bd7a625406c 100644
--- a/source/blender/bmesh/operators/bmo_connect_nonplanar.c
+++ b/source/blender/bmesh/operators/bmo_connect_nonplanar.c
@@ -26,8 +26,6 @@
* Connect verts non-planer faces iteratively (splits faces).
*/
-#include "MEM_guardedalloc.h"
-
#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "BLI_alloca.h"
diff --git a/source/blender/bmesh/operators/bmo_dissolve.c b/source/blender/bmesh/operators/bmo_dissolve.c
index d3c7a6864c3..cf36e88ea98 100644
--- a/source/blender/bmesh/operators/bmo_dissolve.c
+++ b/source/blender/bmesh/operators/bmo_dissolve.c
@@ -37,14 +37,21 @@
#include "intern/bmesh_operators_private.h"
+/* ***_ISGC: mark for garbage-collection */
+
#define FACE_MARK 1
#define FACE_ORIG 2
#define FACE_NEW 4
+
#define EDGE_MARK 1
#define EDGE_TAG 2
+#define EDGE_ISGC 8
#define VERT_MARK 1
#define VERT_TAG 2
+#define VERT_ISGC 8
+
+
static bool UNUSED_FUNCTION(check_hole_in_region) (BMesh *bm, BMFace *f)
{
@@ -232,14 +239,12 @@ cleanup:
void bmo_dissolve_edges_exec(BMesh *bm, BMOperator *op)
{
- /* might want to make this an option or mode - campbell */
-
/* BMOperator fop; */
BMFace *act_face = bm->act_face;
BMOIter eiter;
- BMEdge *e;
- BMIter viter;
- BMVert *v;
+ BMIter iter;
+ BMEdge *e, *e_next;
+ BMVert *v, *v_next;
const bool use_verts = BMO_slot_bool_get(op->slots_in, "use_verts");
const bool use_face_split = BMO_slot_bool_get(op->slots_in, "use_face_split");
@@ -247,10 +252,10 @@ void bmo_dissolve_edges_exec(BMesh *bm, BMOperator *op)
if (use_face_split) {
BMO_slot_buffer_flag_enable(bm, op->slots_in, "edges", BM_EDGE, EDGE_TAG);
- BM_ITER_MESH (v, &viter, bm, BM_VERTS_OF_MESH) {
- BMIter iter;
+ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
+ BMIter itersub;
int untag_count = 0;
- BM_ITER_ELEM (e, &iter, v, BM_EDGES_OF_VERT) {
+ BM_ITER_ELEM (e, &itersub, v, BM_EDGES_OF_VERT) {
if (!BMO_elem_flag_test(bm, e, EDGE_TAG)) {
untag_count++;
}
@@ -266,22 +271,34 @@ void bmo_dissolve_edges_exec(BMesh *bm, BMOperator *op)
}
if (use_verts) {
- BM_ITER_MESH (v, &viter, bm, BM_VERTS_OF_MESH) {
+ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
BMO_elem_flag_set(bm, v, VERT_MARK, (BM_vert_edge_count(v) != 2));
}
}
+ /* tag all verts/edges connected to faces */
BMO_ITER (e, &eiter, op->slots_in, "edges", BM_EDGE) {
- BMFace *fa, *fb;
+ BMFace *f_pair[2];
+ if (BM_edge_face_pair(e, &f_pair[0], &f_pair[1])) {
+ unsigned int j;
+ for (j = 0; j < 2; j++) {
+ BMLoop *l_first, *l_iter;
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f_pair[j]);
+ do {
+ BMO_elem_flag_enable(bm, l_iter->v, VERT_ISGC);
+ BMO_elem_flag_enable(bm, l_iter->e, EDGE_ISGC);
+ } while ((l_iter = l_iter->next) != l_first);
+ }
+ }
+ }
+ BMO_ITER (e, &eiter, op->slots_in, "edges", BM_EDGE) {
+ BMFace *fa, *fb;
if (BM_edge_face_pair(e, &fa, &fb)) {
BMFace *f_new;
/* join faces */
-
- /* BMESH_TODO - check on delaying edge removal since we may end up removing more than
- * one edge, and later reference a removed edge */
- f_new = BM_faces_join_pair(bm, fa, fb, e, true);
+ f_new = BM_faces_join_pair(bm, fa, fb, e, false);
if (f_new) {
/* maintain active face */
@@ -292,8 +309,23 @@ void bmo_dissolve_edges_exec(BMesh *bm, BMOperator *op)
}
}
+ /* Cleanup geometry (#BM_faces_join_pair, but it removes geometry we're looping on)
+ * so do this in a separate pass instead. */
+ BM_ITER_MESH_MUTABLE (e, e_next, &iter, bm, BM_EDGES_OF_MESH) {
+ if ((e->l == NULL) && BMO_elem_flag_test(bm, e, EDGE_ISGC)) {
+ BM_edge_kill(bm, e);
+ }
+ }
+ BM_ITER_MESH_MUTABLE (v, v_next, &iter, bm, BM_VERTS_OF_MESH) {
+ if ((v->e == NULL) && BMO_elem_flag_test(bm, v, VERT_ISGC)) {
+ BM_vert_kill(bm, v);
+ }
+ }
+ /* done with cleanup */
+
+
if (use_verts) {
- BM_ITER_MESH (v, &viter, bm, BM_VERTS_OF_MESH) {
+ BM_ITER_MESH_MUTABLE (v, v_next, &iter, bm, BM_VERTS_OF_MESH) {
if (BMO_elem_flag_test(bm, v, VERT_MARK)) {
if (BM_vert_edge_count(v) == 2) {
BM_vert_collapse_edge(bm, v->e, v, true);
@@ -349,7 +381,7 @@ static bool test_extra_verts(BMesh *bm, BMVert *v)
void bmo_dissolve_verts_exec(BMesh *bm, BMOperator *op)
{
BMIter iter, fiter;
- BMVert *v;
+ BMVert *v, *v_next;
BMFace *f;
const bool use_face_split = BMO_slot_bool_get(op->slots_in, "use_face_split");
@@ -361,7 +393,7 @@ void bmo_dissolve_verts_exec(BMesh *bm, BMOperator *op)
bm_face_split(bm, VERT_MARK);
}
- BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
+ BM_ITER_MESH_MUTABLE (v, v_next, &iter, bm, BM_VERTS_OF_MESH) {
if (BMO_elem_flag_test(bm, v, VERT_MARK)) {
/* check if it's a two-valence ver */
if (BM_vert_edge_count(v) == 2) {
@@ -409,7 +441,7 @@ void bmo_dissolve_verts_exec(BMesh *bm, BMOperator *op)
}
/* clean up any remainin */
- BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
+ BM_ITER_MESH_MUTABLE (v, v_next, &iter, bm, BM_VERTS_OF_MESH) {
if (BMO_elem_flag_test(bm, v, VERT_MARK)) {
if (!BM_vert_dissolve(bm, v)) {
BMO_error_raise(bm, op, BMERR_DISSOLVEVERTS_FAILED, NULL);
diff --git a/source/blender/bmesh/operators/bmo_dupe.c b/source/blender/bmesh/operators/bmo_dupe.c
index bd2485b92fb..a5c34f7623b 100644
--- a/source/blender/bmesh/operators/bmo_dupe.c
+++ b/source/blender/bmesh/operators/bmo_dupe.c
@@ -26,8 +26,6 @@
* Duplicate, Split, Split operators.
*/
-#include "MEM_guardedalloc.h"
-
#include "BLI_math.h"
#include "BLI_alloca.h"
diff --git a/source/blender/bmesh/operators/bmo_edgenet.c b/source/blender/bmesh/operators/bmo_edgenet.c
index c58a11f21ec..de41bc7937d 100644
--- a/source/blender/bmesh/operators/bmo_edgenet.c
+++ b/source/blender/bmesh/operators/bmo_edgenet.c
@@ -28,13 +28,8 @@
#include "MEM_guardedalloc.h"
-#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BLI_array.h"
-#include "BLI_alloca.h"
-#include "BLI_smallhash.h"
-#include "BLI_rand.h"
-#include "BLI_heap.h"
#include "bmesh.h"
#include "bmesh_tools.h"
@@ -44,10 +39,7 @@
#define EDGE_MARK 1
#define EDGE_VIS 2
-#define FACE_NEW 1
-
#define ELE_NEW 1
-#define ELE_ORIG 4
void bmo_edgenet_fill_exec(BMesh *bm, BMOperator *op)
{
diff --git a/source/blender/bmesh/operators/bmo_fill_attribute.c b/source/blender/bmesh/operators/bmo_fill_attribute.c
index f53b4536e44..fa77e6b509c 100644
--- a/source/blender/bmesh/operators/bmo_fill_attribute.c
+++ b/source/blender/bmesh/operators/bmo_fill_attribute.c
@@ -27,8 +27,6 @@
* Fill in geometry with the attributes of their adjacent data.
*/
-#include "MEM_guardedalloc.h"
-
#include "BLI_utildefines.h"
#include "BLI_linklist_stack.h"
diff --git a/source/blender/bmesh/operators/bmo_fill_holes.c b/source/blender/bmesh/operators/bmo_fill_holes.c
index 8160d28d7a7..eadfbdb1aa8 100644
--- a/source/blender/bmesh/operators/bmo_fill_holes.c
+++ b/source/blender/bmesh/operators/bmo_fill_holes.c
@@ -26,8 +26,6 @@
* Fill boundary edge loop(s) with faces.
*/
-#include "MEM_guardedalloc.h"
-
#include "BLI_utildefines.h"
#include "bmesh.h"
diff --git a/source/blender/bmesh/operators/bmo_inset.c b/source/blender/bmesh/operators/bmo_inset.c
index 20cd828af1e..e20556a830d 100644
--- a/source/blender/bmesh/operators/bmo_inset.c
+++ b/source/blender/bmesh/operators/bmo_inset.c
@@ -31,7 +31,6 @@
#include "MEM_guardedalloc.h"
#include "BLI_math.h"
-#include "BLI_array.h"
#include "BLI_alloca.h"
#include "BLI_memarena.h"
#include "BKE_customdata.h"
diff --git a/source/blender/bmesh/operators/bmo_join_triangles.c b/source/blender/bmesh/operators/bmo_join_triangles.c
index 6d4f257909c..6562f26062f 100644
--- a/source/blender/bmesh/operators/bmo_join_triangles.c
+++ b/source/blender/bmesh/operators/bmo_join_triangles.c
@@ -203,7 +203,7 @@ void bmo_join_triangles_exec(BMesh *bm, BMOperator *op)
BMIter iter;
BMOIter siter;
BMFace *f;
- BMEdge *e;
+ BMEdge *e, *e_next;
/* data: edge-to-join, sort_value: error weight */
struct SortPointerByFloat *jedges;
unsigned i, totedge;
@@ -291,7 +291,7 @@ void bmo_join_triangles_exec(BMesh *bm, BMOperator *op)
MEM_freeN(jedges);
/* join best weighted */
- BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+ BM_ITER_MESH_MUTABLE (e, e_next, &iter, bm, BM_EDGES_OF_MESH) {
BMFace *f_new;
BMFace *f_a, *f_b;
@@ -308,7 +308,7 @@ void bmo_join_triangles_exec(BMesh *bm, BMOperator *op)
}
/* join 2-tri islands */
- BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+ BM_ITER_MESH_MUTABLE (e, e_next, &iter, bm, BM_EDGES_OF_MESH) {
if (BMO_elem_flag_test(bm, e, EDGE_MARK)) {
BMLoop *l_a, *l_b;
BMFace *f_a, *f_b;
@@ -326,7 +326,11 @@ void bmo_join_triangles_exec(BMesh *bm, BMOperator *op)
(BMO_elem_flag_test(bm, l_a->next->e, EDGE_MARK) == false) &&
(BMO_elem_flag_test(bm, l_a->prev->e, EDGE_MARK) == false) &&
(BMO_elem_flag_test(bm, l_b->next->e, EDGE_MARK) == false) &&
- (BMO_elem_flag_test(bm, l_b->prev->e, EDGE_MARK) == false))
+ (BMO_elem_flag_test(bm, l_b->prev->e, EDGE_MARK) == false) &&
+ /* check for faces that use same verts, this is supported but raises an error
+ * and cancels the operation when performed from editmode, since this is only
+ * two triangles we only need to compare a single vertex */
+ (LIKELY(l_a->prev->v != l_b->prev->v)))
{
BMFace *f_new;
f_new = BM_faces_join_pair(bm, f_a, f_b, e, true);
diff --git a/source/blender/bmesh/operators/bmo_primitive.c b/source/blender/bmesh/operators/bmo_primitive.c
index 45653f3411f..6a540928d43 100644
--- a/source/blender/bmesh/operators/bmo_primitive.c
+++ b/source/blender/bmesh/operators/bmo_primitive.c
@@ -36,7 +36,7 @@
/* ************************ primitives ******************* */
-static float icovert[12][3] = {
+static const float icovert[12][3] = {
{0.0f, 0.0f, -200.0f},
{144.72f, -105.144f, -89.443f},
{-55.277f, -170.128, -89.443f},
@@ -51,7 +51,7 @@ static float icovert[12][3] = {
{0.0f, 0.0f, 200.0f}
};
-static short icoface[20][3] = {
+static const short icoface[20][3] = {
{0, 1, 2},
{1, 0, 5},
{0, 2, 3},
@@ -78,10 +78,10 @@ static short icoface[20][3] = {
* this hack is only used so that scons & mingw + split-sources hack works
* ------------------------------- start copied code */
/* these are not the monkeys you are looking for */
-static int monkeyo = 4;
-static int monkeynv = 271;
-static int monkeynf = 250;
-static signed char monkeyv[271][3] = {
+static const int monkeyo = 4;
+static const int monkeynv = 271;
+static const int monkeynf = 250;
+static const signed char monkeyv[271][3] = {
{-71, 21, 98}, {-63, 12, 88}, {-57, 7, 74}, {-82, -3, 79}, {-82, 4, 92},
{-82, 17, 100}, {-92, 21, 102}, {-101, 12, 95}, {-107, 7, 83},
{-117, 31, 84}, {-109, 31, 95}, {-96, 31, 102}, {-92, 42, 102},
diff --git a/source/blender/bmesh/operators/bmo_removedoubles.c b/source/blender/bmesh/operators/bmo_removedoubles.c
index 5ab909ffb0c..cc5a635092a 100644
--- a/source/blender/bmesh/operators/bmo_removedoubles.c
+++ b/source/blender/bmesh/operators/bmo_removedoubles.c
@@ -354,7 +354,7 @@ void bmo_collapse_exec(BMesh *bm, BMOperator *op)
BMEdge *e, **edges = NULL;
BLI_array_declare(edges);
float min[3], max[3], center[3];
- int i, tot;
+ unsigned int i, tot;
BMOpSlot *slot_targetmap;
BMO_op_callf(bm, op->flag, "collapse_uvs edges=%s", op, "edges");
@@ -369,6 +369,8 @@ void bmo_collapse_exec(BMesh *bm, BMOperator *op)
BMW_NIL_LAY);
BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+ BMVert *v_tar;
+
if (!BMO_elem_flag_test(bm, e, EDGE_MARK))
continue;
@@ -381,19 +383,29 @@ void bmo_collapse_exec(BMesh *bm, BMOperator *op)
minmax_v3v3_v3(min, max, e->v1->co);
minmax_v3v3_v3(min, max, e->v2->co);
+
+ /* prevent adding to slot_targetmap multiple times */
+ BM_elem_flag_disable(e->v1, BM_ELEM_TAG);
+ BM_elem_flag_disable(e->v2, BM_ELEM_TAG);
}
mid_v3_v3v3(center, min, max);
/* snap edges to a point. for initial testing purposes anyway */
+ v_tar = edges[0]->v1;
+
for (i = 0; i < tot; i++) {
- copy_v3_v3(edges[i]->v1->co, center);
- copy_v3_v3(edges[i]->v2->co, center);
-
- if (edges[i]->v1 != edges[0]->v1)
- BMO_slot_map_elem_insert(&weldop, slot_targetmap, edges[i]->v1, edges[0]->v1);
- if (edges[i]->v2 != edges[0]->v1)
- BMO_slot_map_elem_insert(&weldop, slot_targetmap, edges[i]->v2, edges[0]->v1);
+ unsigned int j;
+
+ for (j = 0; j < 2; j++) {
+ BMVert *v_src = *((&edges[i]->v1) + j);
+
+ copy_v3_v3(v_src->co, center);
+ if ((v_src != v_tar) && !BM_elem_flag_test(v_src, BM_ELEM_TAG)) {
+ BM_elem_flag_enable(v_src, BM_ELEM_TAG);
+ BMO_slot_map_elem_insert(&weldop, slot_targetmap, v_src, v_tar);
+ }
+ }
}
}
diff --git a/source/blender/bmesh/operators/bmo_symmetrize.c b/source/blender/bmesh/operators/bmo_symmetrize.c
index 4b538dccb4e..74f880906c0 100644
--- a/source/blender/bmesh/operators/bmo_symmetrize.c
+++ b/source/blender/bmesh/operators/bmo_symmetrize.c
@@ -26,9 +26,6 @@
* Makes the mesh symmetrical by splitting along an axis and duplicating the geometry.
*/
-
-#include "MEM_guardedalloc.h"
-
#include "BLI_utildefines.h"
#include "BLI_math.h"
diff --git a/source/blender/bmesh/operators/bmo_triangulate.c b/source/blender/bmesh/operators/bmo_triangulate.c
index 590b5ea97c4..ca45289520b 100644
--- a/source/blender/bmesh/operators/bmo_triangulate.c
+++ b/source/blender/bmesh/operators/bmo_triangulate.c
@@ -26,7 +26,6 @@
* Triangulate faces, also defines triangle fill.
*/
-#include "MEM_guardedalloc.h"
#include "DNA_listBase.h"
#include "BLI_math.h"
diff --git a/source/blender/bmesh/operators/bmo_utils.c b/source/blender/bmesh/operators/bmo_utils.c
index e23358bf4ff..c89fee71cbc 100644
--- a/source/blender/bmesh/operators/bmo_utils.c
+++ b/source/blender/bmesh/operators/bmo_utils.c
@@ -32,7 +32,6 @@
#include "DNA_meshdata_types.h"
#include "BLI_math.h"
-#include "BLI_heap.h"
#include "BLI_alloca.h"
#include "BKE_customdata.h"
diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c
index adeb3fdc630..bb3fe129e0b 100644
--- a/source/blender/bmesh/tools/bmesh_bevel.c
+++ b/source/blender/bmesh/tools/bmesh_bevel.c
@@ -900,7 +900,12 @@ static void build_boundary(BevelParams *bp, BevVert *bv)
BLI_assert(vm->count >= 2);
if (bp->vertex_only) {
- vm->mesh_kind = bp->seg > 1 ? M_ADJ_SUBDIV : M_POLY;
+ if (vm->count == 2)
+ vm->mesh_kind = M_NONE;
+ else if (bp->seg > 1)
+ vm->mesh_kind = M_ADJ_SUBDIV;
+ else
+ vm->mesh_kind = M_POLY;
}
else if (vm->count == 2 && bv->edgecount == 3) {
vm->mesh_kind = M_NONE;
@@ -1202,8 +1207,12 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv)
f = boundvert_rep_face(v);
f2 = boundvert_rep_face(v->next);
if (!v->any_seam) {
- for (ring = 1; ring < ns2; ring++)
- bev_merge_uvs(bm, mesh_vert(vm, i, ring, ns2)->v);
+ for (ring = 1; ring < ns2; ring++) {
+ BMVert *v_uv = mesh_vert(vm, i, ring, ns2)->v;
+ if (v_uv) {
+ bev_merge_uvs(bm, v_uv);
+ }
+ }
}
} while ((v = v->next) != vm->boundstart);
if (!bv->any_seam)
@@ -1962,7 +1971,7 @@ static void bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v)
if (!first_bme)
first_bme = v->e;
- if ((nsel == 0 && !bp->vertex_only) || (ntot < 3 && bp->vertex_only)) {
+ if ((nsel == 0 && !bp->vertex_only) || (ntot < 2 && bp->vertex_only)) {
/* signal this vert isn't being beveled */
BM_elem_flag_disable(v, BM_ELEM_TAG);
return;
@@ -2366,7 +2375,7 @@ void BM_mesh_bevel(BMesh *bm, const float offset, const float segments,
const struct MDeformVert *dvert, const int vertex_group)
{
BMIter iter;
- BMVert *v;
+ BMVert *v, *v_next;
BMEdge *e;
BevelParams bp = {NULL};
@@ -2380,7 +2389,7 @@ void BM_mesh_bevel(BMesh *bm, const float offset, const float segments,
if (bp.offset > 0) {
/* primary alloc */
bp.vert_hash = BLI_ghash_ptr_new(__func__);
- bp.mem_arena = BLI_memarena_new((1 << 16), __func__);
+ bp.mem_arena = BLI_memarena_new(MEM_SIZE_OPTIMAL(1 << 16), __func__);
BLI_memarena_use_calloc(bp.mem_arena);
if (limit_offset)
@@ -2409,7 +2418,7 @@ void BM_mesh_bevel(BMesh *bm, const float offset, const float segments,
}
}
- BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
+ BM_ITER_MESH_MUTABLE (v, v_next, &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);
diff --git a/source/blender/bmesh/tools/bmesh_bisect_plane.c b/source/blender/bmesh/tools/bmesh_bisect_plane.c
index 3baf8675a0d..9cfe17d6413 100644
--- a/source/blender/bmesh/tools/bmesh_bisect_plane.c
+++ b/source/blender/bmesh/tools/bmesh_bisect_plane.c
@@ -39,7 +39,6 @@
#include "BLI_utildefines.h"
#include "BLI_alloca.h"
-#include "BLI_mempool.h"
#include "BLI_linklist.h"
#include "BLI_linklist_stack.h"
#include "BLI_math.h"
@@ -122,9 +121,6 @@ static void bm_face_bisect_verts(BMesh *bm, BMFace *f, const float plane[4], con
l_first = BM_FACE_FIRST_LOOP(f);
- (void)bm;
- (void)plane;
-
/* add plane-aligned verts to the stack
* and check we have verts from both sides in this face,
* ... that the face doesn't only have boundry verts on the plane for eg. */
@@ -238,7 +234,7 @@ static void bm_face_bisect_verts(BMesh *bm, BMFace *f, const float plane[4], con
face_verts_proj_2d[BM_VERT_LOOPINDEX(v_a)],
face_verts_proj_2d[BM_VERT_LOOPINDEX(v_b)]);
- if (isect_point_poly_v2(co_mid, (const float (*)[2])face_verts_proj_2d, f_len_orig)) {
+ if (isect_point_poly_v2(co_mid, (const float (*)[2])face_verts_proj_2d, f_len_orig, false)) {
BMLoop *l_a, *l_b;
bool found = false;
unsigned int j;
diff --git a/source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c b/source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c
index bc9288f98f6..868caa49ec7 100644
--- a/source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c
+++ b/source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c
@@ -197,7 +197,7 @@ void BM_mesh_decimate_unsubdivide_ex(BMesh *bm, const int iterations, const bool
}
for (iter_step = 0; iter_step < iterations; iter_step++) {
- BMVert *v;
+ BMVert *v, *v_next;
bool iter_done;
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
@@ -318,7 +318,7 @@ void BM_mesh_decimate_unsubdivide_ex(BMesh *bm, const int iterations, const bool
/* now we tagged all verts -1 for removal, lets loop over and rebuild faces */
iter_done = false;
- BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
+ BM_ITER_MESH_MUTABLE (v, v_next, &iter, bm, BM_VERTS_OF_MESH) {
if (BM_elem_index_get(v) == VERT_INDEX_DO_COLLAPSE) {
if (bm_vert_dissolve_fan(bm, v)) {
iter_done = true;
diff --git a/source/blender/bmesh/tools/bmesh_triangulate.c b/source/blender/bmesh/tools/bmesh_triangulate.c
index 2eacf62d68a..34ff493a026 100644
--- a/source/blender/bmesh/tools/bmesh_triangulate.c
+++ b/source/blender/bmesh/tools/bmesh_triangulate.c
@@ -31,6 +31,9 @@
#include "BLI_utildefines.h"
#include "BLI_alloca.h"
+#include "BLI_memarena.h"
+#include "BLI_listbase.h"
+#include "BLI_scanfill.h"
#include "bmesh.h"
@@ -39,14 +42,14 @@
/**
* a version of #BM_face_triangulate that maps to #BMOpSlot
*/
-static void bm_face_triangulate_mapping(BMesh *bm, BMFace *face, const bool use_beauty, const bool use_tag,
+static void bm_face_triangulate_mapping(BMesh *bm, BMFace *face, MemArena *sf_arena, const bool use_beauty, const bool use_tag,
BMOperator *op, BMOpSlot *slot_facemap_out)
{
const int faces_array_tot = face->len - 3;
BMFace **faces_array = BLI_array_alloca(faces_array, faces_array_tot);
BLI_assert(face->len > 3);
- BM_face_triangulate(bm, face, faces_array, use_beauty, use_tag);
+ BM_face_triangulate(bm, face, faces_array, sf_arena, use_beauty, use_tag);
if (faces_array) {
int i;
@@ -63,13 +66,16 @@ void BM_mesh_triangulate(BMesh *bm, const bool use_beauty, const bool tag_only,
{
BMIter iter;
BMFace *face;
+ MemArena *sf_arena;
+
+ sf_arena = BLI_memarena_new(BLI_SCANFILL_ARENA_SIZE, __func__);
if (slot_facemap_out) {
/* same as below but call: bm_face_triangulate_mapping() */
BM_ITER_MESH (face, &iter, bm, BM_FACES_OF_MESH) {
if (face->len > 3) {
if (tag_only == false || BM_elem_flag_test(face, BM_ELEM_TAG)) {
- bm_face_triangulate_mapping(bm, face, use_beauty, tag_only,
+ bm_face_triangulate_mapping(bm, face, sf_arena, use_beauty, tag_only,
op, slot_facemap_out);
}
}
@@ -79,9 +85,11 @@ void BM_mesh_triangulate(BMesh *bm, const bool use_beauty, const bool tag_only,
BM_ITER_MESH (face, &iter, bm, BM_FACES_OF_MESH) {
if (face->len > 3) {
if (tag_only == false || BM_elem_flag_test(face, BM_ELEM_TAG)) {
- BM_face_triangulate(bm, face, NULL, use_beauty, tag_only);
+ BM_face_triangulate(bm, face, NULL, sf_arena, use_beauty, tag_only);
}
}
}
}
+
+ BLI_memarena_free(sf_arena);
}
diff --git a/source/blender/collada/AnimationExporter.cpp b/source/blender/collada/AnimationExporter.cpp
index bcbcdd42752..c1b6dc83139 100644
--- a/source/blender/collada/AnimationExporter.cpp
+++ b/source/blender/collada/AnimationExporter.cpp
@@ -963,10 +963,10 @@ std::string AnimationExporter::create_4x4_source(std::vector<float> &frames, Obj
else
copy_m4_m4(mat, pchan->pose_mat);
- // SECOND_LIFE_COMPATIBILITY
+ // OPEN_SIM_COMPATIBILITY
// AFAIK animation to second life is via BVH, but no
// reason to not have the collada-animation be correct
- if (export_settings->second_life) {
+ if (export_settings->open_sim) {
float temp[4][4];
copy_m4_m4(temp, bone->arm_mat);
temp[3][0] = temp[3][1] = temp[3][2] = 0.0f;
diff --git a/source/blender/collada/ArmatureExporter.cpp b/source/blender/collada/ArmatureExporter.cpp
index 438421ccd14..174331c4644 100644
--- a/source/blender/collada/ArmatureExporter.cpp
+++ b/source/blender/collada/ArmatureExporter.cpp
@@ -193,11 +193,11 @@ void ArmatureExporter::add_bone_node(Bone *bone, Object *ob_arm, Scene *sce,
// and not it's head, seems arbitrary.
(*i)->parentinv[3][1] += bone->length;
- // SECOND_LIFE_COMPATIBILITY
+ // OPEN_SIM_COMPATIBILITY
// TODO: when such objects are animated as
// single matrix the tweak must be applied
// to the result.
- if (export_settings->second_life) {
+ if (export_settings->open_sim) {
// tweak objects parentinverse to match compatibility
float temp[4][4];
@@ -272,8 +272,8 @@ void ArmatureExporter::add_bone_transform(Object *ob_arm, Bone *bone, COLLADASW:
copy_m4_m4(mat, bone->arm_mat);
}
- // SECOND_LIFE_COMPATIBILITY
- if (export_settings->second_life) {
+ // OPEN_SIM_COMPATIBILITY
+ if (export_settings->open_sim) {
// Remove rotations vs armature from transform
// parent_rest_rot * mat * irest_rot
float temp[4][4];
diff --git a/source/blender/collada/ControllerExporter.cpp b/source/blender/collada/ControllerExporter.cpp
index d04ed8d6fa1..948a3dc5ae1 100644
--- a/source/blender/collada/ControllerExporter.cpp
+++ b/source/blender/collada/ControllerExporter.cpp
@@ -507,8 +507,8 @@ std::string ControllerExporter::add_inv_bind_mats_source(Object *ob_arm, ListBas
float world[4][4];
float inv_bind_mat[4][4];
- // SECOND_LIFE_COMPATIBILITY
- if (export_settings->second_life) {
+ // OPEN_SIM_COMPATIBILITY
+ if (export_settings->open_sim) {
// Only translations, no rotation vs armature
float temp[4][4];
unit_m4(temp);
diff --git a/source/blender/collada/DocumentImporter.cpp b/source/blender/collada/DocumentImporter.cpp
index 5592be6e872..79c725166f6 100644
--- a/source/blender/collada/DocumentImporter.cpp
+++ b/source/blender/collada/DocumentImporter.cpp
@@ -944,7 +944,7 @@ bool DocumentImporter::writeCamera(const COLLADAFW::Camera *camera)
return true;
}
- if(et && et->isProfile("blender")) {
+ if (et && et->isProfile("blender")) {
et->setData("shiftx",&(cam->shiftx));
et->setData("shifty",&(cam->shifty));
et->setData("YF_dofdist",&(cam->YF_dofdist));
diff --git a/source/blender/collada/ExportSettings.h b/source/blender/collada/ExportSettings.h
index f9eb4cbc26f..3dc7e74379e 100644
--- a/source/blender/collada/ExportSettings.h
+++ b/source/blender/collada/ExportSettings.h
@@ -50,7 +50,7 @@ public:
bool use_object_instantiation;
bool sort_by_name;
BC_export_transformation_type export_transformation_type;
- bool second_life;
+ bool open_sim;
char *filepath;
LinkNode *export_set;
diff --git a/source/blender/collada/MeshImporter.cpp b/source/blender/collada/MeshImporter.cpp
index 09d71f22a0d..c7652bd7ae7 100644
--- a/source/blender/collada/MeshImporter.cpp
+++ b/source/blender/collada/MeshImporter.cpp
@@ -665,9 +665,10 @@ void MeshImporter::get_vector(float v[3], COLLADAFW::MeshVertexData& arr, int i,
v[0] = (*values)[i++];
v[1] = (*values)[i++];
- if(stride>=3) {
+ if (stride>=3) {
v[2] = (*values)[i];
- } else {
+ }
+ else {
v[2] = 0.0f;
}
@@ -680,9 +681,10 @@ void MeshImporter::get_vector(float v[3], COLLADAFW::MeshVertexData& arr, int i,
v[0] = (float)(*values)[i++];
v[1] = (float)(*values)[i++];
- if(stride>=3) {
+ if (stride >= 3) {
v[2] = (float)(*values)[i];
- } else {
+ }
+ else {
v[2] = 0.0f;
}
}
diff --git a/source/blender/collada/collada.cpp b/source/blender/collada/collada.cpp
index 85bbaf4748f..223ab3eca2a 100644
--- a/source/blender/collada/collada.cpp
+++ b/source/blender/collada/collada.cpp
@@ -79,7 +79,7 @@ int collada_export(Scene *sce,
int use_object_instantiation,
int sort_by_name,
BC_export_transformation_type export_transformation_type,
- int second_life)
+ int open_sim)
{
ExportSettings export_settings;
@@ -102,7 +102,7 @@ int collada_export(Scene *sce,
export_settings.use_object_instantiation = use_object_instantiation != 0;
export_settings.sort_by_name = sort_by_name != 0;
export_settings.export_transformation_type = export_transformation_type;
- export_settings.second_life = second_life != 0;
+ export_settings.open_sim = open_sim != 0;
int includeFilter = OB_REL_NONE;
diff --git a/source/blender/collada/collada.h b/source/blender/collada/collada.h
index b3a8156b6fe..e96bc2ea8a4 100644
--- a/source/blender/collada/collada.h
+++ b/source/blender/collada/collada.h
@@ -77,7 +77,7 @@ int collada_export(Scene *sce,
int use_object_instantiation,
int sort_by_name,
BC_export_transformation_type export_transformation_type,
- int second_life);
+ int open_sim);
diff --git a/source/blender/collada/version.conf b/source/blender/collada/version.conf
new file mode 100644
index 00000000000..d39af7a53df
--- /dev/null
+++ b/source/blender/collada/version.conf
@@ -0,0 +1 @@
+463ba8a2ef5a021ce21df614dde29e0ee800e10b
diff --git a/source/blender/compositor/intern/COM_MemoryBuffer.cpp b/source/blender/compositor/intern/COM_MemoryBuffer.cpp
index 4bebf004a89..f10e6696c6a 100644
--- a/source/blender/compositor/intern/COM_MemoryBuffer.cpp
+++ b/source/blender/compositor/intern/COM_MemoryBuffer.cpp
@@ -179,7 +179,7 @@ void MemoryBuffer::addPixel(int x, int y, const float color[4])
// table of (exp(ar) - exp(a)) / (1 - exp(a)) for r in range [0, 1] and a = -2
// used instead of actual gaussian, otherwise at high texture magnifications circular artifacts are visible
#define EWA_MAXIDX 255
-static float EWA_WTS[EWA_MAXIDX + 1] = {
+static const float EWA_WTS[EWA_MAXIDX + 1] = {
1.f, 0.990965f, 0.982f, 0.973105f, 0.96428f, 0.955524f, 0.946836f, 0.938216f, 0.929664f,
0.921178f, 0.912759f, 0.904405f, 0.896117f, 0.887893f, 0.879734f, 0.871638f, 0.863605f,
0.855636f, 0.847728f, 0.839883f, 0.832098f, 0.824375f, 0.816712f, 0.809108f, 0.801564f,
diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c
index 041a2c2216e..09b6e7d2206 100644
--- a/source/blender/editors/animation/anim_filter.c
+++ b/source/blender/editors/animation/anim_filter.c
@@ -1546,7 +1546,9 @@ static size_t animdata_filter_ds_linestyle(bAnimContext *ac, ListBase *anim_data
for (srl = sce->r.layers.first; srl; srl = srl->next) {
for (lineset = srl->freestyleConfig.linesets.first; lineset; lineset = lineset->next) {
- lineset->linestyle->id.flag |= LIB_DOIT;
+ if (lineset->linestyle) {
+ lineset->linestyle->id.flag |= LIB_DOIT;
+ }
}
}
@@ -1562,8 +1564,11 @@ static size_t animdata_filter_ds_linestyle(bAnimContext *ac, ListBase *anim_data
ListBase tmp_data = {NULL, NULL};
size_t tmp_items = 0;
- if (!(linestyle->id.flag & LIB_DOIT))
+ if ((linestyle == NULL) ||
+ !(linestyle->id.flag & LIB_DOIT))
+ {
continue;
+ }
linestyle->id.flag &= ~LIB_DOIT;
/* add scene-level animation channels */
diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c
index 3c8576be312..34246427b7e 100644
--- a/source/blender/editors/animation/anim_markers.c
+++ b/source/blender/editors/animation/anim_markers.c
@@ -1380,7 +1380,7 @@ static int ed_marker_rename_invoke_wrapper(bContext *C, wmOperator *op, const wm
RNA_string_set(op->ptr, "name", marker->name);
/* now see if the operator is usable */
- return ed_markers_opwrap_invoke_custom(C, op, event, WM_operator_props_popup);
+ return ed_markers_opwrap_invoke_custom(C, op, event, WM_operator_props_popup_confirm);
}
static void MARKER_OT_rename(wmOperatorType *ot)
diff --git a/source/blender/editors/animation/keyframes_edit.c b/source/blender/editors/animation/keyframes_edit.c
index decbc351cad..71717284d8e 100644
--- a/source/blender/editors/animation/keyframes_edit.c
+++ b/source/blender/editors/animation/keyframes_edit.c
@@ -396,7 +396,7 @@ void ANIM_editkeyframes_refresh(bAnimContext *ac)
int filter;
/* when not in graph view, don't use handles */
SpaceIpo *sipo = (ac->spacetype == SPACE_IPO) ? (SpaceIpo *)ac->sl : NULL;
- const short use_handle = sipo ? !(sipo->flag & SIPO_NOHANDLES) : FALSE;
+ const bool use_handle = sipo ? !(sipo->flag & SIPO_NOHANDLES) : false;
/* filter animation data */
filter = ANIMFILTER_DATA_VISIBLE;
diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c
index 70361f00004..6b9200afb75 100644
--- a/source/blender/editors/animation/keyframing.c
+++ b/source/blender/editors/animation/keyframing.c
@@ -61,6 +61,7 @@
#include "BKE_depsgraph.h"
#include "BKE_fcurve.h"
#include "BKE_main.h"
+#include "BKE_idcode.h"
#include "BKE_nla.h"
#include "BKE_global.h"
#include "BKE_context.h"
@@ -141,9 +142,18 @@ bAction *verify_adt_action(ID *id, short add)
/* init action if none available yet */
/* TODO: need some wizardry to handle NLA stuff correct */
if ((adt->action == NULL) && (add)) {
+ /* init action name from name of ID block */
char actname[sizeof(id->name) - 2];
BLI_snprintf(actname, sizeof(actname), "%sAction", id->name + 2);
+
+ /* create action */
adt->action = add_empty_action(G.main, actname);
+
+ /* set ID-type from ID-block that this is going to be assigned to
+ * so that users can't accidentally break actions by assigning them
+ * to the wrong places
+ */
+ adt->action->idroot = GS(id->name);
}
/* return the action */
@@ -996,6 +1006,34 @@ short insert_keyframe(ReportList *reports, ID *id, bAction *act, const char grou
* The flag argument is used for special settings that alter the behavior of
* the keyframe deletion. These include the quick refresh options.
*/
+
+
+
+/**
+ * \note caller needs to run #BKE_nla_tweakedit_remap to get NLA relative frame.
+ * caller should also check #BKE_fcurve_is_protected before keying.
+ */
+static bool delete_keyframe_fcurve(AnimData *adt, FCurve *fcu, float cfra)
+{
+ bool found;
+ int i;
+
+ /* try to find index of beztriple to get rid of */
+ i = binarysearch_bezt_index(fcu->bezt, cfra, fcu->totvert, &found);
+ if (found) {
+ /* delete the key at the index (will sanity check + do recalc afterwards) */
+ delete_fcurve_key(fcu, i, 1);
+
+ /* Only delete curve too if it won't be doing anything anymore */
+ if ((fcu->totvert == 0) && (list_has_suitable_fmodifier(&fcu->modifiers, 0, FMI_TYPE_GENERATE_CURVE) == 0))
+ ANIM_fcurve_delete_from_animdata(NULL, adt, fcu);
+
+ /* return success */
+ return true;
+ }
+ return false;
+}
+
short delete_keyframe(ReportList *reports, ID *id, bAction *act, const char group[], const char rna_path[], int array_index, float cfra, short UNUSED(flag))
{
AnimData *adt = BKE_animdata_from_id(id);
@@ -1055,32 +1093,20 @@ short delete_keyframe(ReportList *reports, ID *id, bAction *act, const char grou
/* will only loop once unless the array index was -1 */
for (; array_index < array_index_max; array_index++) {
FCurve *fcu = verify_fcurve(act, group, &ptr, rna_path, array_index, 0);
- bool found;
- int i;
-
+
/* check if F-Curve exists and/or whether it can be edited */
if (fcu == NULL)
continue;
-
- if ( (fcu->flag & FCURVE_PROTECTED) || ((fcu->grp) && (fcu->grp->flag & AGRP_PROTECTED)) ) {
- if (G.debug & G_DEBUG)
- printf("WARNING: not deleting keyframe for locked F-Curve\n");
+
+ if (BKE_fcurve_is_protected(fcu)) {
+ BKE_reportf(reports, RPT_WARNING,
+ "not deleting keyframe for locked F-Curve '%s' for %s '%s'",
+ fcu->rna_path, BKE_idcode_to_name(GS(id->name)), id->name + 2);
continue;
}
-
- /* try to find index of beztriple to get rid of */
- i = binarysearch_bezt_index(fcu->bezt, cfra, fcu->totvert, &found);
- if (found) {
- /* delete the key at the index (will sanity check + do recalc afterwards) */
- delete_fcurve_key(fcu, i, 1);
-
- /* Only delete curve too if it won't be doing anything anymore */
- if ((fcu->totvert == 0) && (list_has_suitable_fmodifier(&fcu->modifiers, 0, FMI_TYPE_GENERATE_CURVE) == 0))
- ANIM_fcurve_delete_from_animdata(NULL, adt, fcu);
-
- /* return success */
- ret++;
- }
+
+ ret += delete_keyframe_fcurve(adt, fcu, cfra);
+
}
/* return success/failure */
@@ -1158,7 +1184,7 @@ static short clear_keyframe(ReportList *reports, ID *id, bAction *act, const cha
if (fcu == NULL)
continue;
- if ( (fcu->flag & FCURVE_PROTECTED) || ((fcu->grp) && (fcu->grp->flag & AGRP_PROTECTED)) ) {
+ if (BKE_fcurve_is_protected(fcu)) {
if (G.debug & G_DEBUG)
printf("WARNING: not deleting keyframe for locked F-Curve\n");
continue;
@@ -1537,14 +1563,22 @@ static int delete_key_v3d_exec(bContext *C, wmOperator *op)
AnimData *adt = ob->adt;
bAction *act = adt->action;
FCurve *fcu, *fcn;
+ const float cfra_unmap = BKE_nla_tweakedit_remap(adt, cfra, NLATIME_CONVERT_UNMAP);
for (fcu = act->curves.first; fcu; fcu = fcn) {
fcn = fcu->next;
-
+
+ if (BKE_fcurve_is_protected(fcu)) {
+ BKE_reportf(op->reports, RPT_WARNING,
+ "not deleting keyframe for locked F-Curve '%s', object '%s'",
+ fcu->rna_path, id->name + 2);
+ continue;
+ }
+
/* delete keyframes on current frame
* WARNING: this can delete the next F-Curve, hence the "fcn" copying
*/
- success += delete_keyframe(op->reports, id, NULL, NULL, fcu->rna_path, fcu->array_index, cfra, 0);
+ success += delete_keyframe_fcurve(adt, fcu, cfra_unmap);
}
}
diff --git a/source/blender/editors/armature/BIF_retarget.h b/source/blender/editors/armature/BIF_retarget.h
index 2ea0e0ab0d7..21e85b6fe89 100644
--- a/source/blender/editors/armature/BIF_retarget.h
+++ b/source/blender/editors/armature/BIF_retarget.h
@@ -29,6 +29,7 @@
#include "BLI_graph.h"
#include "BLI_ghash.h"
+#include "BLI_task.h"
#include "BLI_threads.h"
#include "reeb.h"
@@ -68,7 +69,8 @@ typedef struct RigGraph {
ReebGraph *link_mesh;
- struct ThreadedWorker *worker;
+ TaskScheduler *task_scheduler;
+ TaskPool *task_pool;
GHash *bones_map; /* map of editbones by name */
GHash *controls_map; /* map of rigcontrols by bone pointer */
diff --git a/source/blender/editors/armature/armature_naming.c b/source/blender/editors/armature/armature_naming.c
index 1ee2dc80a97..8745d571a28 100644
--- a/source/blender/editors/armature/armature_naming.c
+++ b/source/blender/editors/armature/armature_naming.c
@@ -182,16 +182,22 @@ void ED_armature_bone_rename(bArmature *arm, const char *oldnamep, const char *n
if (ob->pose) {
bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, oldname);
if (pchan) {
+ GHash *gh = ob->pose->chanhash;
+
+ /* remove the old hash entry, and replace with the new name */
+ if (gh) {
+ BLI_assert(BLI_ghash_haskey(gh, pchan->name));
+ BLI_ghash_remove(gh, pchan->name, NULL, NULL);
+ }
+
BLI_strncpy(pchan->name, newname, MAXBONENAME);
-
- if (ob->pose->chanhash) {
- GHash *gh = ob->pose->chanhash;
-
- /* remove the old hash entry, and replace with the new name */
- BLI_ghash_remove(gh, oldname, NULL, NULL);
+
+ if (gh) {
BLI_ghash_insert(gh, pchan->name, pchan);
}
}
+
+ BLI_assert(BKE_pose_channels_is_valid(ob->pose) == true);
}
/* Update any object constraints to use the new bone name */
@@ -294,9 +300,13 @@ static int armature_flip_names_exec(bContext *C, wmOperator *UNUSED(op))
/* since we renamed stuff... */
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
- /* note, notifier might evolve */
- WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
-
+ /* copied from #rna_Bone_update_renamed */
+ /* redraw view */
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
+
+ /* update animation channels */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN, ob->data);
+
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/armature/editarmature_retarget.c b/source/blender/editors/armature/editarmature_retarget.c
index 687455495a1..c03e7861307 100644
--- a/source/blender/editors/armature/editarmature_retarget.c
+++ b/source/blender/editors/armature/editarmature_retarget.c
@@ -83,7 +83,7 @@ static RigGraph *GLOBAL_RIGG = NULL;
/*******************************************************************************************************/
-void *exec_retargetArctoArc(void *param);
+void exec_retargetArctoArc(TaskPool *pool, void *taskdata, int threadid);
static void RIG_calculateEdgeAngles(RigEdge *edge_first, RigEdge *edge_second);
float rollBoneByQuat(EditBone *bone, float old_up_axis[3], float qrot[4]);
@@ -235,9 +235,8 @@ void RIG_freeRigGraph(BGraph *rg)
BNode *node;
BArc *arc;
-#ifdef USE_THREADS
- BLI_destroy_worker(rigg->worker);
-#endif
+ BLI_task_pool_free(rigg->task_pool);
+ BLI_task_scheduler_free(rigg->task_scheduler);
if (rigg->link_mesh) {
REEB_freeGraph(rigg->link_mesh);
@@ -284,12 +283,14 @@ static RigGraph *newRigGraph(void)
rg->free_node = NULL;
#ifdef USE_THREADS
- //totthread = BKE_scene_num_threads(G.scene);
- totthread = BLI_system_thread_count();
-
- rg->worker = BLI_create_worker(exec_retargetArctoArc, totthread, 20); /* fix number of threads */
+ totthread = TASK_SCHEDULER_AUTO_THREADS;
+#else
+ totthread = TASK_SCHEDULER_SINGLE_THREAD;
#endif
-
+
+ rg->task_scheduler = BLI_task_scheduler_create(totthread);
+ rg->task_pool = BLI_task_pool_create(rg->task_scheduler, NULL);
+
return rg;
}
@@ -2133,7 +2134,6 @@ static void retargetArctoArcLength(bContext *C, RigGraph *rigg, RigArc *iarc, Ri
static void retargetArctoArc(bContext *C, RigGraph *rigg, RigArc *iarc, RigNode *inode_start)
{
-#ifdef USE_THREADS
RetargetParam *p = MEM_callocN(sizeof(RetargetParam), "RetargetParam");
p->rigg = rigg;
@@ -2141,22 +2141,12 @@ static void retargetArctoArc(bContext *C, RigGraph *rigg, RigArc *iarc, RigNode
p->inode_start = inode_start;
p->context = C;
- BLI_insert_work(rigg->worker, p);
-#else
- RetargetParam p;
-
- p.rigg = rigg;
- p.iarc = iarc;
- p.inode_start = inode_start;
- p.context = C;
-
- exec_retargetArctoArc(&p);
-#endif
+ BLI_task_pool_push(rigg->task_pool, exec_retargetArctoArc, p, true, TASK_PRIORITY_HIGH);
}
-void *exec_retargetArctoArc(void *param)
+void exec_retargetArctoArc(TaskPool *UNUSED(pool), void *taskdata, int UNUSED(threadid))
{
- RetargetParam *p = (RetargetParam *)param;
+ RetargetParam *p = (RetargetParam *)taskdata;
RigGraph *rigg = p->rigg;
RigArc *iarc = p->iarc;
bContext *C = p->context;
@@ -2183,12 +2173,6 @@ void *exec_retargetArctoArc(void *param)
retargetArctoArcLength(C, rigg, iarc, inode_start);
}
}
-
-#ifdef USE_THREADS
- MEM_freeN(p);
-#endif
-
- return NULL;
}
static void matchMultiResolutionNode(RigGraph *rigg, RigNode *inode, ReebNode *top_node)
@@ -2414,9 +2398,7 @@ static void retargetSubgraph(bContext *C, RigGraph *rigg, RigArc *start_arc, Rig
static void finishRetarget(RigGraph *rigg)
{
-#ifdef USE_THREADS
- BLI_end_worker(rigg->worker);
-#endif
+ BLI_task_pool_work_and_wait(rigg->task_pool);
}
static void adjustGraphs(bContext *C, RigGraph *rigg)
diff --git a/source/blender/editors/armature/pose_lib.c b/source/blender/editors/armature/pose_lib.c
index cb7a699b522..182f94b3693 100644
--- a/source/blender/editors/armature/pose_lib.c
+++ b/source/blender/editors/armature/pose_lib.c
@@ -638,7 +638,7 @@ static int poselib_rename_invoke(bContext *C, wmOperator *op, const wmEvent *eve
}
/* part to sync with other similar operators... */
- return WM_operator_props_popup(C, op, event);
+ return WM_operator_props_popup_confirm(C, op, event);
}
static int poselib_rename_exec(bContext *C, wmOperator *op)
diff --git a/source/blender/editors/curve/editcurve_add.c b/source/blender/editors/curve/editcurve_add.c
index 0bcb550b930..9b858a2c4e9 100644
--- a/source/blender/editors/curve/editcurve_add.c
+++ b/source/blender/editors/curve/editcurve_add.c
@@ -58,7 +58,7 @@
#include "curve_intern.h"
-static float nurbcircle[8][2] = {
+static const float nurbcircle[8][2] = {
{0.0, -1.0}, {-1.0, -1.0}, {-1.0, 0.0}, {-1.0, 1.0},
{0.0, 1.0}, { 1.0, 1.0}, { 1.0, 0.0}, { 1.0, -1.0}
};
diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c
index b9759e16f20..ac9c338e431 100644
--- a/source/blender/editors/curve/editfont.c
+++ b/source/blender/editors/curve/editfont.c
@@ -981,7 +981,7 @@ void FONT_OT_move_select(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Move Select";
- ot->description = "Make selection from current cursor position to new cursor position type";
+ ot->description = "Move the cursor while selecting";
ot->idname = "FONT_OT_move_select";
/* api callbacks */
diff --git a/source/blender/editors/include/BIF_glutil.h b/source/blender/editors/include/BIF_glutil.h
index 352a74cf172..dd1995a5428 100644
--- a/source/blender/editors/include/BIF_glutil.h
+++ b/source/blender/editors/include/BIF_glutil.h
@@ -221,8 +221,5 @@ void glaDrawImBuf_glsl(struct ImBuf *ibuf, float x, float y, int zoomfilter,
/* Draw imbuf on a screen, preferably using GLSL display transform */
void glaDrawImBuf_glsl_ctx(const struct bContext *C, struct ImBuf *ibuf, float x, float y, int zoomfilter);
-/* Transform buffer from role to scene linear space using GLSL OCIO conversion */
-int glaBufferTransformFromRole_glsl(float *buffer, int width, int height, int role);
-
#endif /* __BIF_GLUTIL_H__ */
diff --git a/source/blender/editors/include/ED_mask.h b/source/blender/editors/include/ED_mask.h
index 3e2dbe255df..8da36f015dc 100644
--- a/source/blender/editors/include/ED_mask.h
+++ b/source/blender/editors/include/ED_mask.h
@@ -57,7 +57,7 @@ void ED_operatormacros_mask(void);
/* mask_draw.c */
void ED_mask_draw(const struct bContext *C, const char draw_flag, const char draw_type);
void ED_mask_draw_region(struct Mask *mask, struct ARegion *ar,
- const char draw_flag, const char draw_type,
+ const char draw_flag, const char draw_type, const char overlay_mode,
const int width_i, const int height_i,
const float aspx, const float aspy,
const short do_scale_applied, const short do_draw_cb,
diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h
index b7fd181883b..5d3d72d0e3d 100644
--- a/source/blender/editors/include/ED_mesh.h
+++ b/source/blender/editors/include/ED_mesh.h
@@ -152,7 +152,7 @@ void EDBM_select_mirrored(struct BMEditMesh *em, bool extend,
void EDBM_automerge(struct Scene *scene, struct Object *ob, bool update, const char hflag);
bool EDBM_backbuf_border_init(struct ViewContext *vc, short xmin, short ymin, short xmax, short ymax);
-int EDBM_backbuf_check(unsigned int index);
+bool EDBM_backbuf_check(unsigned int index);
void EDBM_backbuf_free(void);
bool EDBM_backbuf_border_mask_init(struct ViewContext *vc, const int mcords[][2], short tot,
diff --git a/source/blender/editors/include/ED_render.h b/source/blender/editors/include/ED_render.h
index bdfbbbb9c74..518bee665ae 100644
--- a/source/blender/editors/include/ED_render.h
+++ b/source/blender/editors/include/ED_render.h
@@ -40,6 +40,7 @@ struct Scene;
struct ScrArea;
struct RegionView3D;
struct RenderEngine;
+struct View3D;
/* render_ops.c */
@@ -51,6 +52,7 @@ void ED_render_id_flush_update(struct Main *bmain, struct ID *id);
void ED_render_engine_changed(struct Main *bmain);
void ED_render_engine_area_exit(struct ScrArea *sa);
void ED_render_scene_update(struct Main *bmain, struct Scene *scene, int updated);
+void ED_render_view3d_shade_update(struct Main *bmain, struct View3D *v3d, struct ScrArea *sa);
void ED_viewport_render_kill_jobs(const struct bContext *C, bool free_database);
diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h
index 81308dd84f2..eff79b6a039 100644
--- a/source/blender/editors/include/ED_transform.h
+++ b/source/blender/editors/include/ED_transform.h
@@ -103,7 +103,7 @@ enum TfmMode {
* returns 1 if successful, 0 otherwise (usually means there's no selection)
* (if 0 is returns, *vec is unmodified)
* */
-int calculateTransformCenter(struct bContext *C, int centerMode, float cent3d[3], int cent2d[2]);
+int calculateTransformCenter(struct bContext *C, int centerMode, float cent3d[3], float cent2d[2]);
struct TransInfo;
struct ScrArea;
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index ce9d3af3013..86abf29c308 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -336,4 +336,7 @@ void ED_view3d_operator_properties_viewmat_set(struct bContext *C, struct wmOper
void ED_view3d_operator_properties_viewmat_get(struct wmOperator *op, int *winx, int *winy, float persmat[4][4]);
#endif
+/* render */
+void ED_view3d_shade_update(struct Main *bmain, struct View3D *v3d, struct ScrArea *sa);
+
#endif /* __ED_VIEW3D_H__ */
diff --git a/source/blender/editors/interface/CMakeLists.txt b/source/blender/editors/interface/CMakeLists.txt
index a8b8765a5c6..e13517adbb3 100644
--- a/source/blender/editors/interface/CMakeLists.txt
+++ b/source/blender/editors/interface/CMakeLists.txt
@@ -40,6 +40,7 @@ set(SRC
interface.c
interface_anim.c
interface_draw.c
+ interface_eyedropper.c
interface_handlers.c
interface_icons.c
interface_layout.c
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index e02cdf018c0..3bad2577409 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -611,6 +611,9 @@ static void ui_but_update_linklines(uiBlock *block, uiBut *oldbut, uiBut *newbut
static int ui_but_update_from_old_block(const bContext *C, uiBlock *block, uiBut **butpp)
{
+ /* flags from the buttons we want to refresh, may want to add more here... */
+ const int flag_copy = UI_BUT_REDALERT;
+
uiBlock *oldblock;
uiBut *oldbut, *but = *butpp;
int found = 0;
@@ -659,6 +662,7 @@ static int ui_but_update_from_old_block(const bContext *C, uiBlock *block, uiBut
/* drawing */
oldbut->icon = but->icon;
oldbut->iconadd = but->iconadd;
+ oldbut->alignnr = but->alignnr;
/* typically the same pointers, but not on undo/redo */
/* XXX some menu buttons store button itself in but->poin. Ugly */
@@ -667,6 +671,8 @@ static int ui_but_update_from_old_block(const bContext *C, uiBlock *block, uiBut
SWAP(void *, oldbut->func_argN, but->func_argN);
}
+ oldbut->flag = (oldbut->flag & ~flag_copy) | (but->flag & flag_copy);
+
/* copy hardmin for list rows to prevent 'sticking' highlight to mouse position
* when scrolling without moving mouse (see [#28432]) */
if (ELEM(oldbut->type, ROW, LISTROW))
@@ -2869,7 +2875,7 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, const char *str,
}
/* keep track of UI_interface.h */
- if (ELEM8(but->type, BLOCK, BUT, LABEL, PULLDOWN, ROUNDBOX, BUTM, SCROLL, SEPR)) {}
+ if (ELEM9(but->type, BLOCK, BUT, LABEL, PULLDOWN, ROUNDBOX, LISTBOX, BUTM, SCROLL, SEPR)) {}
else if (but->type >= SEARCH_MENU) {}
else but->flag |= UI_BUT_UNDO;
diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c
index cd845da10c6..11062ea2bd2 100644
--- a/source/blender/editors/interface/interface_draw.c
+++ b/source/blender/editors/interface/interface_draw.c
@@ -1389,7 +1389,7 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wc
if (scopes->track_disabled) {
glColor4f(0.7f, 0.3f, 0.3f, 0.3f);
- uiSetRoundBox(15);
+ uiSetRoundBox(UI_CNR_ALL);
uiDrawBox(GL_POLYGON, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f);
ok = 1;
@@ -1437,7 +1437,7 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wc
if (scopes->use_track_mask) {
glColor4f(0.0f, 0.0f, 0.0f, 0.3f);
- uiSetRoundBox(15);
+ uiSetRoundBox(UI_CNR_ALL);
uiDrawBox(GL_POLYGON, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f);
}
@@ -1478,7 +1478,7 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wc
if (!ok) {
glColor4f(0.f, 0.f, 0.f, 0.3f);
- uiSetRoundBox(15);
+ uiSetRoundBox(UI_CNR_ALL);
uiDrawBox(GL_POLYGON, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f);
}
diff --git a/source/blender/editors/interface/interface_eyedropper.c b/source/blender/editors/interface/interface_eyedropper.c
new file mode 100644
index 00000000000..783a777a2fe
--- /dev/null
+++ b/source/blender/editors/interface/interface_eyedropper.c
@@ -0,0 +1,642 @@
+/*
+ * ***** 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) 2009 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation, Joshua Leung
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/interface/interface_eyedropper.c
+ * \ingroup edinterface
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_space_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_object_types.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_math_vector.h"
+
+#include "BKE_context.h"
+#include "BKE_screen.h"
+#include "BKE_report.h"
+#include "BKE_idcode.h"
+
+#include "RNA_access.h"
+
+#include "BIF_gl.h"
+
+#include "UI_interface.h"
+
+#include "IMB_colormanagement.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "interface_intern.h"
+
+/* for HDR color sampling */
+#include "ED_image.h"
+#include "ED_node.h"
+#include "ED_clip.h"
+
+/* for ID data eyedropper */
+#include "ED_space_api.h"
+#include "ED_screen.h"
+#include "ED_view3d.h"
+
+
+/* -------------------------------------------------------------------- */
+/* Eyedropper
+ */
+
+/** \name Eyedropper (RGB Color)
+ * \{ */
+
+typedef struct Eyedropper {
+ struct ColorManagedDisplay *display;
+
+ PointerRNA ptr;
+ PropertyRNA *prop;
+ int index;
+
+ int accum_start; /* has mouse been presed */
+ float accum_col[3];
+ int accum_tot;
+} Eyedropper;
+
+static int eyedropper_init(bContext *C, wmOperator *op)
+{
+ Scene *scene = CTX_data_scene(C);
+ Eyedropper *eye;
+
+ op->customdata = eye = MEM_callocN(sizeof(Eyedropper), "Eyedropper");
+
+ uiContextActiveProperty(C, &eye->ptr, &eye->prop, &eye->index);
+
+ if ((eye->ptr.data == NULL) ||
+ (eye->prop == NULL) ||
+ (RNA_property_editable(&eye->ptr, eye->prop) == FALSE) ||
+ (RNA_property_array_length(&eye->ptr, eye->prop) < 3) ||
+ (RNA_property_type(eye->prop) != PROP_FLOAT))
+ {
+ return FALSE;
+ }
+
+ if (RNA_property_subtype(eye->prop) == PROP_COLOR) {
+ const char *display_device;
+
+ display_device = scene->display_settings.display_device;
+ eye->display = IMB_colormanagement_display_get_named(display_device);
+ }
+
+ return TRUE;
+}
+
+static void eyedropper_exit(bContext *C, wmOperator *op)
+{
+ WM_cursor_modal_restore(CTX_wm_window(C));
+
+ if (op->customdata) {
+ MEM_freeN(op->customdata);
+ op->customdata = NULL;
+ }
+}
+
+static int eyedropper_cancel(bContext *C, wmOperator *op)
+{
+ eyedropper_exit(C, op);
+ return OPERATOR_CANCELLED;
+}
+
+/* *** eyedropper_color_ helper functions *** */
+
+/**
+ * \brief get the color from the screen.
+ *
+ * Special check for image or nodes where we MAY have HDR pixels which don't display.
+ */
+static void eyedropper_color_sample_fl(bContext *C, Eyedropper *UNUSED(eye), int mx, int my, float r_col[3])
+{
+
+ /* we could use some clever */
+ wmWindow *win = CTX_wm_window(C);
+ ScrArea *sa;
+ for (sa = win->screen->areabase.first; sa; sa = sa->next) {
+ if (BLI_rcti_isect_pt(&sa->totrct, mx, my)) {
+ if (sa->spacetype == SPACE_IMAGE) {
+ ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
+ if (ar && BLI_rcti_isect_pt(&ar->winrct, mx, my)) {
+ SpaceImage *sima = sa->spacedata.first;
+ int mval[2] = {mx - ar->winrct.xmin,
+ my - ar->winrct.ymin};
+
+ if (ED_space_image_color_sample(sima, ar, mval, r_col)) {
+ return;
+ }
+ }
+ }
+ else if (sa->spacetype == SPACE_NODE) {
+ ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
+ if (ar && BLI_rcti_isect_pt(&ar->winrct, mx, my)) {
+ SpaceNode *snode = sa->spacedata.first;
+ int mval[2] = {mx - ar->winrct.xmin,
+ my - ar->winrct.ymin};
+
+ if (ED_space_node_color_sample(snode, ar, mval, r_col)) {
+ return;
+ }
+ }
+ }
+ else if (sa->spacetype == SPACE_CLIP) {
+ ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
+ if (ar && BLI_rcti_isect_pt(&ar->winrct, mx, my)) {
+ SpaceClip *sc = sa->spacedata.first;
+ int mval[2] = {mx - ar->winrct.xmin,
+ my - ar->winrct.ymin};
+
+ if (ED_space_clip_color_sample(sc, ar, mval, r_col)) {
+ return;
+ }
+ }
+ }
+ }
+ }
+
+ /* fallback to simple opengl picker */
+ glReadBuffer(GL_FRONT);
+ glReadPixels(mx, my, 1, 1, GL_RGB, GL_FLOAT, r_col);
+ glReadBuffer(GL_BACK);
+}
+
+/* sets the sample color RGB, maintaining A */
+static void eyedropper_color_set(bContext *C, Eyedropper *eye, const float col[3])
+{
+ float col_conv[4];
+
+ /* to maintain alpha */
+ RNA_property_float_get_array(&eye->ptr, eye->prop, col_conv);
+
+ /* convert from display space to linear rgb space */
+ if (eye->display) {
+ copy_v3_v3(col_conv, col);
+ IMB_colormanagement_display_to_scene_linear_v3(col_conv, eye->display);
+ }
+ else {
+ copy_v3_v3(col_conv, col);
+ }
+
+ RNA_property_float_set_array(&eye->ptr, eye->prop, col_conv);
+
+ RNA_property_update(C, &eye->ptr, eye->prop);
+}
+
+/* set sample from accumulated values */
+static void eyedropper_color_set_accum(bContext *C, Eyedropper *eye)
+{
+ float col[3];
+ mul_v3_v3fl(col, eye->accum_col, 1.0f / (float)eye->accum_tot);
+ eyedropper_color_set(C, eye, col);
+}
+
+/* single point sample & set */
+static void eyedropper_color_sample(bContext *C, Eyedropper *eye, int mx, int my)
+{
+ float col[3];
+ eyedropper_color_sample_fl(C, eye, mx, my, col);
+ eyedropper_color_set(C, eye, col);
+}
+
+static void eyedropper_color_sample_accum(bContext *C, Eyedropper *eye, int mx, int my)
+{
+ float col[3];
+ eyedropper_color_sample_fl(C, eye, mx, my, col);
+ /* delay linear conversion */
+ add_v3_v3(eye->accum_col, col);
+ eye->accum_tot++;
+}
+
+/* main modal status check */
+static int eyedropper_modal(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ Eyedropper *eye = (Eyedropper *)op->customdata;
+
+ switch (event->type) {
+ case ESCKEY:
+ case RIGHTMOUSE:
+ return eyedropper_cancel(C, op);
+ case LEFTMOUSE:
+ if (event->val == KM_RELEASE) {
+ if (eye->accum_tot == 0) {
+ eyedropper_color_sample(C, eye, event->x, event->y);
+ }
+ else {
+ eyedropper_color_set_accum(C, eye);
+ }
+ eyedropper_exit(C, op);
+ return OPERATOR_FINISHED;
+ }
+ else if (event->val == KM_PRESS) {
+ /* enable accum and make first sample */
+ eye->accum_start = TRUE;
+ eyedropper_color_sample_accum(C, eye, event->x, event->y);
+ }
+ break;
+ case MOUSEMOVE:
+ if (eye->accum_start) {
+ /* button is pressed so keep sampling */
+ eyedropper_color_sample_accum(C, eye, event->x, event->y);
+ eyedropper_color_set_accum(C, eye);
+ }
+ break;
+ case SPACEKEY:
+ if (event->val == KM_RELEASE) {
+ eye->accum_tot = 0;
+ zero_v3(eye->accum_col);
+ eyedropper_color_sample_accum(C, eye, event->x, event->y);
+ eyedropper_color_set_accum(C, eye);
+ }
+ break;
+ }
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+/* Modal Operator init */
+static int eyedropper_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+{
+ /* init */
+ if (eyedropper_init(C, op)) {
+ WM_cursor_modal_set(CTX_wm_window(C), BC_EYEDROPPER_CURSOR);
+
+ /* add temp handler */
+ WM_event_add_modal_handler(C, op);
+
+ return OPERATOR_RUNNING_MODAL;
+ }
+ else {
+ eyedropper_exit(C, op);
+ return OPERATOR_CANCELLED;
+ }
+}
+
+/* Repeat operator */
+static int eyedropper_exec(bContext *C, wmOperator *op)
+{
+ /* init */
+ if (eyedropper_init(C, op)) {
+
+ /* do something */
+
+ /* cleanup */
+ eyedropper_exit(C, op);
+
+ return OPERATOR_FINISHED;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
+}
+
+static int eyedropper_poll(bContext *C)
+{
+ if (!CTX_wm_window(C)) return 0;
+ else return 1;
+}
+
+void UI_OT_eyedropper_color(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Eyedropper";
+ ot->idname = "UI_OT_eyedropper_color";
+ ot->description = "Sample a color from the Blender Window to store in a property";
+
+ /* api callbacks */
+ ot->invoke = eyedropper_invoke;
+ ot->modal = eyedropper_modal;
+ ot->cancel = eyedropper_cancel;
+ ot->exec = eyedropper_exec;
+ ot->poll = eyedropper_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_BLOCKING;
+
+ /* properties */
+}
+/** \} */
+
+
+/* -------------------------------------------------------------------- */
+/* Data Dropper
+ *
+ * note: datadropper is only internal name to avoid confusion in this file
+ */
+
+/** \name Eyedropper (ID data-blocks)
+ * \{ */
+
+typedef struct DataDropper {
+ PointerRNA ptr;
+ PropertyRNA *prop;
+ short idcode;
+ const char *idcode_name;
+
+ ARegionType *art;
+ void *draw_handle_pixel;
+ char name[200];
+} DataDropper;
+
+
+static void datadropper_draw_cb(const struct bContext *C, ARegion *ar, void *arg)
+{
+ DataDropper *ddr = arg;
+ int width;
+ const char *name = ddr->name;
+ wmWindow *win = CTX_wm_window(C);
+ int x = win->eventstate->x;
+ int y = win->eventstate->y;
+
+ if ((name[0] == '\0') ||
+ (BLI_rcti_isect_pt(&ar->winrct, x, y) == false))
+ {
+ return;
+ }
+
+ width = UI_GetStringWidth(name);
+ x = x - ar->winrct.xmin;
+ y = y - ar->winrct.ymin;
+
+ y += 20;
+
+ glColor4ub(0, 0, 0, 50);
+
+ uiSetRoundBox(UI_CNR_ALL | UI_RB_ALPHA);
+ uiRoundBox(x, y, x + width + 8, y + 15, 4);
+
+ glColor4ub(255, 255, 255, 255);
+ UI_DrawString(x + 4, y + 4, name);
+}
+
+
+static int datadropper_init(bContext *C, wmOperator *op)
+{
+ DataDropper *ddr;
+ int index_dummy;
+ StructRNA *type;
+
+ SpaceType *st;
+ ARegionType *art;
+
+ st = BKE_spacetype_from_id(SPACE_VIEW3D);
+ art = BKE_regiontype_from_id(st, RGN_TYPE_WINDOW);
+
+ op->customdata = ddr = MEM_callocN(sizeof(DataDropper), "DataDropper");
+
+ uiContextActiveProperty(C, &ddr->ptr, &ddr->prop, &index_dummy);
+
+ if ((ddr->ptr.data == NULL) ||
+ (ddr->prop == NULL) ||
+ (RNA_property_editable(&ddr->ptr, ddr->prop) == false) ||
+ (RNA_property_type(ddr->prop) != PROP_POINTER))
+ {
+ return false;
+ }
+
+ ddr->art = art;
+ ddr->draw_handle_pixel = ED_region_draw_cb_activate(art, datadropper_draw_cb, ddr, REGION_DRAW_POST_PIXEL);
+
+ type = RNA_property_pointer_type(&ddr->ptr, ddr->prop);
+ ddr->idcode = RNA_type_to_ID_code(type);
+ BLI_assert(ddr->idcode != 0);
+ ddr->idcode_name = BKE_idcode_to_name(ddr->idcode);
+
+ return true;
+}
+
+static void datadropper_exit(bContext *C, wmOperator *op)
+{
+ WM_cursor_modal_restore(CTX_wm_window(C));
+
+ if (op->customdata) {
+ DataDropper *ddr = (DataDropper *)op->customdata;
+
+ ED_region_draw_cb_exit(ddr->art, ddr->draw_handle_pixel);
+
+ MEM_freeN(op->customdata);
+
+ op->customdata = NULL;
+ }
+}
+
+static int datadropper_cancel(bContext *C, wmOperator *op)
+{
+ datadropper_exit(C, op);
+ return OPERATOR_CANCELLED;
+}
+
+/* *** datadropper id helper functions *** */
+/**
+ * \brief get the ID from the screen.
+ *
+ */
+static void datadropper_id_sample_pt(bContext *C, DataDropper *ddr, int mx, int my, ID **r_id)
+{
+
+ /* we could use some clever */
+ wmWindow *win = CTX_wm_window(C);
+ ScrArea *sa;
+
+ ScrArea *area_prev = CTX_wm_area(C);
+ ARegion *ar_prev = CTX_wm_region(C);
+
+ ddr->name[0] = '\0';
+
+ for (sa = win->screen->areabase.first; sa; sa = sa->next) {
+ if (BLI_rcti_isect_pt(&sa->totrct, mx, my)) {
+ if (sa->spacetype == SPACE_VIEW3D) {
+ ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
+ if (ar && BLI_rcti_isect_pt(&ar->winrct, mx, my)) {
+ int mval[2] = {mx - ar->winrct.xmin,
+ my - ar->winrct.ymin};
+ Base *base;
+
+ CTX_wm_area_set(C, sa);
+ CTX_wm_region_set(C, ar);
+
+ /* grr, always draw else we leave stale text */
+ ED_region_tag_redraw(ar);
+
+ base = ED_view3d_give_base_under_cursor(C, mval);
+ if (base) {
+ Object *ob = base->object;
+ ID *id = NULL;
+ if (ddr->idcode == ID_OB) {
+ id = (ID *)ob;
+ }
+ else if (ob->data) {
+ if (GS(((ID *)ob->data)->name) == ddr->idcode) {
+ id = (ID *)ob->data;
+ }
+ else {
+ BLI_snprintf(ddr->name, sizeof(ddr->name), "Incompatible, expected a %s",
+ ddr->idcode_name);
+ }
+ }
+
+ if (id) {
+ BLI_snprintf(ddr->name, sizeof(ddr->name), "%s: %s",
+ ddr->idcode_name, id->name + 2);
+ *r_id = id;
+ }
+
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ CTX_wm_area_set(C, area_prev);
+ CTX_wm_region_set(C, ar_prev);
+}
+
+/* sets the ID, returns success */
+static bool datadropper_id_set(bContext *C, DataDropper *ddr, ID *id)
+{
+ PointerRNA ptr_value;
+
+ RNA_id_pointer_create(id, &ptr_value);
+
+ RNA_property_pointer_set(&ddr->ptr, ddr->prop, ptr_value);
+
+ RNA_property_update(C, &ddr->ptr, ddr->prop);
+
+ ptr_value = RNA_property_pointer_get(&ddr->ptr, ddr->prop);
+
+ return (ptr_value.id.data == id);
+}
+
+/* single point sample & set */
+static bool datadropper_id_sample(bContext *C, DataDropper *ddr, int mx, int my)
+{
+ ID *id = NULL;
+
+ datadropper_id_sample_pt(C, ddr, mx, my, &id);
+ return datadropper_id_set(C, ddr, id);
+}
+
+/* main modal status check */
+static int datadropper_modal(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ DataDropper *ddr = (DataDropper *)op->customdata;
+
+ switch (event->type) {
+ case ESCKEY:
+ case RIGHTMOUSE:
+ return datadropper_cancel(C, op);
+ case LEFTMOUSE:
+ if (event->val == KM_RELEASE) {
+ bool success;
+
+ success = datadropper_id_sample(C, ddr, event->x, event->y);
+ datadropper_exit(C, op);
+
+ if (success) {
+ return OPERATOR_FINISHED;
+ }
+ else {
+ BKE_report(op->reports, RPT_WARNING, "Failed to set value");
+ return OPERATOR_CANCELLED;
+ }
+ }
+ break;
+ case MOUSEMOVE:
+ {
+ ID *id = NULL;
+ datadropper_id_sample_pt(C, ddr, event->x, event->y, &id);
+ break;
+ }
+ }
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+/* Modal Operator init */
+static int datadropper_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+{
+ /* init */
+ if (datadropper_init(C, op)) {
+ WM_cursor_modal_set(CTX_wm_window(C), BC_EYEDROPPER_CURSOR);
+
+ /* add temp handler */
+ WM_event_add_modal_handler(C, op);
+
+ return OPERATOR_RUNNING_MODAL;
+ }
+ else {
+ datadropper_exit(C, op);
+ return OPERATOR_CANCELLED;
+ }
+}
+
+/* Repeat operator */
+static int datadropper_exec(bContext *C, wmOperator *op)
+{
+ /* init */
+ if (datadropper_init(C, op)) {
+ /* cleanup */
+ datadropper_exit(C, op);
+
+ return OPERATOR_FINISHED;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
+}
+
+static int datadropper_poll(bContext *C)
+{
+ if (!CTX_wm_window(C)) return 0;
+ else return 1;
+}
+
+void UI_OT_eyedropper_id(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Eyedropper Datablock";
+ ot->idname = "UI_OT_eyedropper_id";
+ ot->description = "Sample a color from the Blender Window to store in a property";
+
+ /* api callbacks */
+ ot->invoke = datadropper_invoke;
+ ot->modal = datadropper_modal;
+ ot->cancel = datadropper_cancel;
+ ot->exec = datadropper_exec;
+ ot->poll = datadropper_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_BLOCKING;
+
+ /* properties */
+}
+
+/** \} */
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 5d982b60c91..c5faa99e067 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -2227,8 +2227,16 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle
break;
case AKEY:
+
/* Ctrl + A: Select all */
- if (event->ctrl && !(event->alt || event->shift || event->oskey)) {
+#if defined(__APPLE__)
+ /* OSX uses cmd-a systemwide, so add it */
+ if ((event->oskey && !(event->alt || event->shift || event->ctrl)) ||
+ (event->ctrl && !(event->alt || event->shift || event->oskey)))
+#else
+ if (event->ctrl && !(event->alt || event->shift || event->oskey))
+#endif
+ {
ui_textedit_move(but, data, STRCUR_DIR_PREV,
false, STRCUR_JUMP_ALL);
ui_textedit_move(but, data, STRCUR_DIR_NEXT,
@@ -2613,7 +2621,10 @@ static int ui_do_but_TEX(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
{
if (data->state == BUTTON_STATE_HIGHLIGHT) {
if (ELEM4(event->type, LEFTMOUSE, EVT_BUT_OPEN, PADENTER, RETKEY) && event->val == KM_PRESS) {
- if (but->dt == UI_EMBOSSN && !event->ctrl) {
+ if (ELEM(event->type, PADENTER, RETKEY) && (!ui_is_but_utf8(but))) {
+ /* pass - allow filesel, enter to execute */
+ }
+ else if (but->dt == UI_EMBOSSN && !event->ctrl) {
/* pass */
}
else {
@@ -2647,13 +2658,8 @@ static int ui_do_but_SEARCH_UNLINK(bContext *C, uiBlock *block, uiBut *but, uiHa
BLI_rcti_rctf_copy(&rect, &but->rect);
rect.xmin = rect.xmax - (BLI_rcti_size_y(&rect));
- if ( BLI_rcti_isect_pt(&rect, x, y) ) {
- /* most likely NULL, but let's check, and give it temp zero string */
- if (data->str == NULL)
- data->str = MEM_callocN(16, "temp str");
- data->str[0] = 0;
-
- ui_apply_but_TEX(C, but, data);
+ if (BLI_rcti_isect_pt(&rect, x, y)) {
+ ui_set_but_string(C, but, "");
button_activate_state(C, but, BUTTON_STATE_EXIT);
return WM_UI_HANDLER_BREAK;
@@ -3579,31 +3585,6 @@ static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, co
return WM_UI_HANDLER_BREAK;
}
}
- else if (but->type == COLOR) {
- if (ELEM3(event->type, MOUSEPAN, WHEELDOWNMOUSE, WHEELUPMOUSE) && event->alt) {
- float *hsv = ui_block_hsv_get(but->block);
- float col[3];
-
- ui_get_but_vectorf(but, col);
- rgb_to_hsv_compat_v(col, hsv);
-
- if (event->type == WHEELDOWNMOUSE)
- hsv[2] = CLAMPIS(hsv[2] - 0.05f, 0.0f, 1.0f);
- else if (event->type == WHEELUPMOUSE)
- hsv[2] = CLAMPIS(hsv[2] + 0.05f, 0.0f, 1.0f);
- else {
- float fac = 0.005 * (event->y - event->prevy);
- hsv[2] = CLAMPIS(hsv[2] + fac, 0.0f, 1.0f);
- }
-
- hsv_to_rgb_v(hsv, data->vec);
- ui_set_but_vectorf(but, data->vec);
-
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- ui_apply_button(C, but->block, but, data, true);
- return WM_UI_HANDLER_BREAK;
- }
- }
}
else if (data->state == BUTTON_STATE_WAIT_DRAG) {
@@ -3691,6 +3672,41 @@ static bool ui_numedit_but_NORMAL(uiBut *but, uiHandleButtonData *data, int mx,
return changed;
}
+static int ui_do_but_COLOR(bContext *C, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
+{
+ if (data->state == BUTTON_STATE_HIGHLIGHT) {
+ if (ELEM3(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->val == KM_PRESS) {
+ button_activate_state(C, but, BUTTON_STATE_MENU_OPEN);
+ return WM_UI_HANDLER_BREAK;
+ }
+ else if (ELEM3(event->type, MOUSEPAN, WHEELDOWNMOUSE, WHEELUPMOUSE) && event->alt) {
+ float *hsv = ui_block_hsv_get(but->block);
+ float col[3];
+
+ ui_get_but_vectorf(but, col);
+ rgb_to_hsv_compat_v(col, hsv);
+
+ if (event->type == WHEELDOWNMOUSE)
+ hsv[2] = CLAMPIS(hsv[2] - 0.05f, 0.0f, 1.0f);
+ else if (event->type == WHEELUPMOUSE)
+ hsv[2] = CLAMPIS(hsv[2] + 0.05f, 0.0f, 1.0f);
+ else {
+ float fac = 0.005 * (event->y - event->prevy);
+ hsv[2] = CLAMPIS(hsv[2] + fac, 0.0f, 1.0f);
+ }
+
+ hsv_to_rgb_v(hsv, data->vec);
+ ui_set_but_vectorf(but, data->vec);
+
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ ui_apply_button(C, but->block, but, data, true);
+ return WM_UI_HANDLER_BREAK;
+ }
+ }
+
+ return WM_UI_HANDLER_CONTINUE;
+}
+
static int ui_do_but_NORMAL(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
int mx, my;
@@ -5092,7 +5108,12 @@ static bool ui_but_menu(bContext *C, uiBut *but)
uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_DEFAULT);
if (but->rnapoin.data && but->rnaprop) {
- bool is_anim = RNA_property_animateable(&but->rnapoin, but->rnaprop);
+ PointerRNA *ptr = &but->rnapoin;
+ PropertyRNA *prop = but->rnaprop;
+ bool is_anim = RNA_property_animateable(ptr, prop);
+ bool is_editable = RNA_property_editable(ptr, prop);
+ /*bool is_idprop = RNA_property_is_idprop(prop);*/ /* XXX does not work as expected, not strictly needed */
+ bool is_set = RNA_property_is_set(ptr, prop);
/* second slower test, saved people finding keyframe items in menus when its not possible */
if (is_anim)
@@ -5239,6 +5260,10 @@ static bool ui_but_menu(bContext *C, uiBut *but)
uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Reset to Default Value"),
ICON_NONE, "UI_OT_reset_default_button", "all", 1);
}
+ if (is_editable /*&& is_idprop*/ && is_set) {
+ uiItemO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Unset"),
+ ICON_NONE, "UI_OT_unset_property_button");
+ }
uiItemO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Copy Data Path"),
ICON_NONE, "UI_OT_copy_data_path_button");
@@ -5380,6 +5405,28 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *
else if (event->type == EVT_DROP) {
ui_but_drop(C, event, but, data);
}
+ /* handle eyedropper */
+ else if ((event->type == EKEY) && (event->val == KM_PRESS)) {
+ if (event->alt || event->shift || event->ctrl || event->oskey) {
+ /* pass */
+ }
+ else {
+ if (but->type == COLOR) {
+ WM_operator_name_call(C, "UI_OT_eyedropper_color", WM_OP_INVOKE_DEFAULT, NULL);
+ return WM_UI_HANDLER_BREAK;
+ }
+ else if (but->type == SEARCH_MENU_UNLINK) {
+ if (but->rnaprop && RNA_property_type(but->rnaprop) == PROP_POINTER) {
+ StructRNA *type = RNA_property_pointer_type(&but->rnapoin, but->rnaprop);
+ const short idcode = RNA_type_to_ID_code(type);
+ if ((idcode == ID_OB) || OB_DATA_SUPPORT_ID(idcode)) {
+ WM_operator_name_call(C, "UI_OT_eyedropper_id", WM_OP_INVOKE_DEFAULT, NULL);
+ return WM_UI_HANDLER_BREAK;
+ }
+ }
+ }
+ }
+ }
/* handle keyframing */
else if ((event->type == IKEY) &&
!ELEM(KM_MOD_FIRST, event->ctrl, event->oskey) &&
@@ -5525,7 +5572,7 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *
if (but->a1 == UI_GRAD_V_ALT) /* signal to prevent calling up color picker */
retval = ui_do_but_EXIT(C, but, data, event);
else
- retval = ui_do_but_BLOCK(C, but, data, event);
+ retval = ui_do_but_COLOR(C, but, data, event);
break;
case BUT_NORMAL:
retval = ui_do_but_NORMAL(C, block, but, data, event);
@@ -7719,6 +7766,8 @@ static int ui_handler_popup(bContext *C, const wmEvent *event, void *userdata)
}
else if (temp.cancel_func)
temp.cancel_func(C, temp.popup_arg);
+
+ WM_event_add_mousemove(C);
}
else {
/* re-enable tooltips */
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 6382130cbbd..9cc16d82810 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -584,4 +584,8 @@ int ui_but_anim_expression_set(uiBut *but, const char *str);
int ui_but_anim_expression_create(uiBut *but, const char *str);
void ui_but_anim_autokey(struct bContext *C, uiBut *but, struct Scene *scene, float cfra);
-#endif
+/* interface_eyedropper.c */
+void UI_OT_eyedropper_color(struct wmOperatorType *ot);
+void UI_OT_eyedropper_id(struct wmOperatorType *ot);
+
+#endif /* __INTERFACE_INTERN_H__ */
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index 424d2231a03..b453a3b8363 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -505,6 +505,14 @@ static void ui_item_enum_expand_handle(bContext *C, void *arg1, void *arg2)
static void ui_item_enum_expand(uiLayout *layout, uiBlock *block, PointerRNA *ptr, PropertyRNA *prop,
const char *uiname, int h, int icon_only)
{
+ /* XXX The way this function currently handles uiname parameter is insane and inconsistent with general UI API:
+ * * uiname is the *enum property* label.
+ * * when it is NULL or empty, we do not draw *enum items* labels, this doubles the icon_only parameter.
+ * * we *never* draw (i.e. really use) the enum label uiname, it is just used as a mere flag!
+ * Unfortunately, fixing this implies an API "soft break", so better to defer it for later... :/
+ * --mont29
+ */
+
uiBut *but;
EnumPropertyItem *item, *item_array;
const char *name;
@@ -3091,20 +3099,25 @@ void uiLayoutOperatorButs(const bContext *C, uiLayout *layout, wmOperator *op,
/* set various special settings for buttons */
{
+ uiBlock *block = uiLayoutGetBlock(layout);
+ const bool is_popup = (block->flag & UI_BLOCK_KEEP_OPEN) != 0;
uiBut *but;
+
- for (but = uiLayoutGetBlock(layout)->buttons.first; but; but = but->next) {
+ for (but = block->buttons.first; but; but = but->next) {
/* no undo for buttons for operator redo panels */
uiButClearFlag(but, UI_BUT_UNDO);
-#if 0 /* broken, causes freedback loop, see [#36109] */
+ /* only for popups, see [#36109] */
+
/* if button is operator's default property, and a text-field, enable focus for it
* - this is used for allowing operators with popups to rename stuff with fewer clicks
*/
- if ((but->rnaprop == op->type->prop) && (but->type == TEX)) {
- uiButSetFocusOnEnter(CTX_wm_window(C), but);
+ if (is_popup) {
+ if ((but->rnaprop == op->type->prop) && (but->type == TEX)) {
+ uiButSetFocusOnEnter(CTX_wm_window(C), but);
+ }
}
-#endif
}
}
}
diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c
index d714402de9f..36e965e13d2 100644
--- a/source/blender/editors/interface/interface_ops.c
+++ b/source/blender/editors/interface/interface_ops.c
@@ -27,20 +27,14 @@
* \ingroup edinterface
*/
-#include <stdio.h>
-#include <math.h>
#include <string.h>
#include "MEM_guardedalloc.h"
-#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_text_types.h" /* for UI_OT_reports_to_text */
#include "BLI_blenlib.h"
-#include "BLI_math_color.h"
-#include "BLI_math_vector.h"
-#include "BLI_utildefines.h"
#include "BLF_api.h"
#include "BLF_translation.h"
@@ -54,12 +48,8 @@
#include "RNA_access.h"
#include "RNA_define.h"
-#include "BIF_gl.h"
-
#include "UI_interface.h"
-#include "IMB_colormanagement.h"
-
#include "interface_intern.h"
#include "WM_api.h"
@@ -70,282 +60,6 @@
#include "BKE_main.h"
#include "BLI_ghash.h"
-#include "ED_image.h" /* for HDR color sampling */
-#include "ED_node.h" /* for HDR color sampling */
-#include "ED_clip.h" /* for HDR color sampling */
-
-/* ********************************************************** */
-
-typedef struct Eyedropper {
- struct ColorManagedDisplay *display;
-
- PointerRNA ptr;
- PropertyRNA *prop;
- int index;
-
- int accum_start; /* has mouse been presed */
- float accum_col[3];
- int accum_tot;
-} Eyedropper;
-
-static int eyedropper_init(bContext *C, wmOperator *op)
-{
- Scene *scene = CTX_data_scene(C);
- Eyedropper *eye;
-
- op->customdata = eye = MEM_callocN(sizeof(Eyedropper), "Eyedropper");
-
- uiContextActiveProperty(C, &eye->ptr, &eye->prop, &eye->index);
-
- if ((eye->ptr.data == NULL) ||
- (eye->prop == NULL) ||
- (RNA_property_editable(&eye->ptr, eye->prop) == FALSE) ||
- (RNA_property_array_length(&eye->ptr, eye->prop) < 3) ||
- (RNA_property_type(eye->prop) != PROP_FLOAT))
- {
- return FALSE;
- }
-
- if (RNA_property_subtype(eye->prop) == PROP_COLOR) {
- const char *display_device;
-
- display_device = scene->display_settings.display_device;
- eye->display = IMB_colormanagement_display_get_named(display_device);
- }
-
- return TRUE;
-}
-
-static void eyedropper_exit(bContext *C, wmOperator *op)
-{
- WM_cursor_modal_restore(CTX_wm_window(C));
-
- if (op->customdata)
- MEM_freeN(op->customdata);
- op->customdata = NULL;
-}
-
-static int eyedropper_cancel(bContext *C, wmOperator *op)
-{
- eyedropper_exit(C, op);
- return OPERATOR_CANCELLED;
-}
-
-/* *** eyedropper_color_ helper functions *** */
-
-/**
- * \brief get the color from the screen.
- *
- * Special check for image or nodes where we MAY have HDR pixels which don't display.
- */
-static void eyedropper_color_sample_fl(bContext *C, Eyedropper *UNUSED(eye), int mx, int my, float r_col[3])
-{
-
- /* we could use some clever */
- wmWindow *win = CTX_wm_window(C);
- ScrArea *sa;
- for (sa = win->screen->areabase.first; sa; sa = sa->next) {
- if (BLI_rcti_isect_pt(&sa->totrct, mx, my)) {
- if (sa->spacetype == SPACE_IMAGE) {
- ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
- if (ar && BLI_rcti_isect_pt(&ar->winrct, mx, my)) {
- SpaceImage *sima = sa->spacedata.first;
- int mval[2] = {mx - ar->winrct.xmin,
- my - ar->winrct.ymin};
-
- if (ED_space_image_color_sample(sima, ar, mval, r_col)) {
- return;
- }
- }
- }
- else if (sa->spacetype == SPACE_NODE) {
- ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
- if (ar && BLI_rcti_isect_pt(&ar->winrct, mx, my)) {
- SpaceNode *snode = sa->spacedata.first;
- int mval[2] = {mx - ar->winrct.xmin,
- my - ar->winrct.ymin};
-
- if (ED_space_node_color_sample(snode, ar, mval, r_col)) {
- return;
- }
- }
- }
- else if (sa->spacetype == SPACE_CLIP) {
- ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
- if (ar && BLI_rcti_isect_pt(&ar->winrct, mx, my)) {
- SpaceClip *sc = sa->spacedata.first;
- int mval[2] = {mx - ar->winrct.xmin,
- my - ar->winrct.ymin};
-
- if (ED_space_clip_color_sample(sc, ar, mval, r_col)) {
- return;
- }
- }
- }
- }
- }
-
- /* fallback to simple opengl picker */
- glReadBuffer(GL_FRONT);
- glReadPixels(mx, my, 1, 1, GL_RGB, GL_FLOAT, r_col);
- glReadBuffer(GL_BACK);
-}
-
-/* sets the sample color RGB, maintaining A */
-static void eyedropper_color_set(bContext *C, Eyedropper *eye, const float col[3])
-{
- float col_conv[4];
-
- /* to maintain alpha */
- RNA_property_float_get_array(&eye->ptr, eye->prop, col_conv);
-
- /* convert from display space to linear rgb space */
- if (eye->display) {
- copy_v3_v3(col_conv, col);
- IMB_colormanagement_display_to_scene_linear_v3(col_conv, eye->display);
- }
- else {
- copy_v3_v3(col_conv, col);
- }
-
- RNA_property_float_set_array(&eye->ptr, eye->prop, col_conv);
-
- RNA_property_update(C, &eye->ptr, eye->prop);
-}
-
-/* set sample from accumulated values */
-static void eyedropper_color_set_accum(bContext *C, Eyedropper *eye)
-{
- float col[3];
- mul_v3_v3fl(col, eye->accum_col, 1.0f / (float)eye->accum_tot);
- eyedropper_color_set(C, eye, col);
-}
-
-/* single point sample & set */
-static void eyedropper_color_sample(bContext *C, Eyedropper *eye, int mx, int my)
-{
- float col[3];
- eyedropper_color_sample_fl(C, eye, mx, my, col);
- eyedropper_color_set(C, eye, col);
-}
-
-static void eyedropper_color_sample_accum(bContext *C, Eyedropper *eye, int mx, int my)
-{
- float col[3];
- eyedropper_color_sample_fl(C, eye, mx, my, col);
- /* delay linear conversion */
- add_v3_v3(eye->accum_col, col);
- eye->accum_tot++;
-}
-
-/* main modal status check */
-static int eyedropper_modal(bContext *C, wmOperator *op, const wmEvent *event)
-{
- Eyedropper *eye = (Eyedropper *)op->customdata;
-
- switch (event->type) {
- case ESCKEY:
- case RIGHTMOUSE:
- return eyedropper_cancel(C, op);
- case LEFTMOUSE:
- if (event->val == KM_RELEASE) {
- if (eye->accum_tot == 0) {
- eyedropper_color_sample(C, eye, event->x, event->y);
- }
- else {
- eyedropper_color_set_accum(C, eye);
- }
- eyedropper_exit(C, op);
- return OPERATOR_FINISHED;
- }
- else if (event->val == KM_PRESS) {
- /* enable accum and make first sample */
- eye->accum_start = TRUE;
- eyedropper_color_sample_accum(C, eye, event->x, event->y);
- }
- break;
- case MOUSEMOVE:
- if (eye->accum_start) {
- /* button is pressed so keep sampling */
- eyedropper_color_sample_accum(C, eye, event->x, event->y);
- eyedropper_color_set_accum(C, eye);
- }
- break;
- case SPACEKEY:
- if (event->val == KM_RELEASE) {
- eye->accum_tot = 0;
- zero_v3(eye->accum_col);
- eyedropper_color_sample_accum(C, eye, event->x, event->y);
- eyedropper_color_set_accum(C, eye);
- }
- break;
- }
-
- return OPERATOR_RUNNING_MODAL;
-}
-
-/* Modal Operator init */
-static int eyedropper_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
-{
- /* init */
- if (eyedropper_init(C, op)) {
- WM_cursor_modal_set(CTX_wm_window(C), BC_EYEDROPPER_CURSOR);
-
- /* add temp handler */
- WM_event_add_modal_handler(C, op);
-
- return OPERATOR_RUNNING_MODAL;
- }
- else {
- eyedropper_exit(C, op);
- return OPERATOR_CANCELLED;
- }
-}
-
-/* Repeat operator */
-static int eyedropper_exec(bContext *C, wmOperator *op)
-{
- /* init */
- if (eyedropper_init(C, op)) {
-
- /* do something */
-
- /* cleanup */
- eyedropper_exit(C, op);
-
- return OPERATOR_FINISHED;
- }
- else {
- return OPERATOR_CANCELLED;
- }
-}
-
-static int eyedropper_poll(bContext *C)
-{
- if (!CTX_wm_window(C)) return 0;
- else return 1;
-}
-
-static void UI_OT_eyedropper(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name = "Eyedropper";
- ot->idname = "UI_OT_eyedropper";
- ot->description = "Sample a color from the Blender Window to store in a property";
-
- /* api callbacks */
- ot->invoke = eyedropper_invoke;
- ot->modal = eyedropper_modal;
- ot->cancel = eyedropper_cancel;
- ot->exec = eyedropper_exec;
- ot->poll = eyedropper_poll;
-
- /* flags */
- ot->flag = OPTYPE_BLOCKING;
-
- /* properties */
-}
-
/* Reset Default Theme ------------------------ */
static int reset_default_theme_exec(bContext *C, wmOperator *UNUSED(op))
@@ -434,6 +148,28 @@ static void UI_OT_copy_data_path_button(wmOperatorType *ot)
/* Reset to Default Values Button Operator ------------------------ */
+static int operator_button_property_finish(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
+{
+ ID *id = ptr->id.data;
+
+ /* perform updates required for this property */
+ RNA_property_update(C, ptr, prop);
+
+ /* as if we pressed the button */
+ uiContextActivePropertyHandle(C);
+
+ /* Since we don't want to undo _all_ edits to settings, eg window
+ * edits on the screen or on operator settings.
+ * it might be better to move undo's inline - campbell */
+ if (id && ID_CHECK_UNDO(id)) {
+ /* do nothing, go ahead with undo */
+ return OPERATOR_FINISHED;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
+}
+
static int reset_default_button_poll(bContext *C)
{
PointerRNA ptr;
@@ -449,7 +185,6 @@ static int reset_default_button_exec(bContext *C, wmOperator *op)
{
PointerRNA ptr;
PropertyRNA *prop;
- int success = 0;
int index, all = RNA_boolean_get(op->ptr, "all");
/* try to reset the nominated setting to its default value */
@@ -457,32 +192,11 @@ static int reset_default_button_exec(bContext *C, wmOperator *op)
/* if there is a valid property that is editable... */
if (ptr.data && prop && RNA_property_editable(&ptr, prop)) {
- if (RNA_property_reset(&ptr, prop, (all) ? -1 : index)) {
- /* perform updates required for this property */
- RNA_property_update(C, &ptr, prop);
-
- /* as if we pressed the button */
- uiContextActivePropertyHandle(C);
-
- success = 1;
- }
+ if (RNA_property_reset(&ptr, prop, (all) ? -1 : index))
+ return operator_button_property_finish(C, &ptr, prop);
}
- /* Since we don't want to undo _all_ edits to settings, eg window
- * edits on the screen or on operator settings.
- * it might be better to move undo's inline - campbell */
- if (success) {
- ID *id = ptr.id.data;
- if (id && ID_CHECK_UNDO(id)) {
- /* do nothing, go ahead with undo */
- }
- else {
- return OPERATOR_CANCELLED;
- }
- }
- /* end hack */
-
- return (success) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
+ return OPERATOR_CANCELLED;
}
static void UI_OT_reset_default_button(wmOperatorType *ot)
@@ -503,6 +217,43 @@ static void UI_OT_reset_default_button(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "all", 1, "All", "Reset to default values all elements of the array");
}
+/* Unset Property Button Operator ------------------------ */
+
+static int unset_property_button_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ PointerRNA ptr;
+ PropertyRNA *prop;
+ int index;
+
+ /* try to unset the nominated property */
+ uiContextActiveProperty(C, &ptr, &prop, &index);
+
+ /* if there is a valid property that is editable... */
+ if (ptr.data && prop && RNA_property_editable(&ptr, prop)
+ /*&& RNA_property_is_idprop(prop)*/ && RNA_property_is_set(&ptr, prop))
+ {
+ RNA_property_unset(&ptr, prop);
+ return operator_button_property_finish(C, &ptr, prop);
+ }
+
+ return OPERATOR_CANCELLED;
+}
+
+static void UI_OT_unset_property_button(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Unset property";
+ ot->idname = "UI_OT_unset_property_button";
+ ot->description = "Clear the property and use default or generated value in operators";
+
+ /* callbacks */
+ ot->poll = ED_operator_regionactive;
+ ot->exec = unset_property_button_exec;
+
+ /* flags */
+ ot->flag = OPTYPE_UNDO;
+}
+
/* Copy To Selected Operator ------------------------ */
static int copy_to_selected_list(bContext *C, PointerRNA *ptr, ListBase *lb, int *use_path)
@@ -1077,10 +828,10 @@ static void UI_OT_reloadtranslation(wmOperatorType *ot)
void UI_buttons_operatortypes(void)
{
- WM_operatortype_append(UI_OT_eyedropper);
WM_operatortype_append(UI_OT_reset_default_theme);
WM_operatortype_append(UI_OT_copy_data_path_button);
WM_operatortype_append(UI_OT_reset_default_button);
+ WM_operatortype_append(UI_OT_unset_property_button);
WM_operatortype_append(UI_OT_copy_to_selected_button);
WM_operatortype_append(UI_OT_reports_to_textblock); /* XXX: temp? */
@@ -1089,4 +840,8 @@ void UI_buttons_operatortypes(void)
WM_operatortype_append(UI_OT_edittranslation_init);
#endif
WM_operatortype_append(UI_OT_reloadtranslation);
+
+ /* external */
+ WM_operatortype_append(UI_OT_eyedropper_color);
+ WM_operatortype_append(UI_OT_eyedropper_id);
}
diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c
index 35741618211..15fbd51c6fc 100644
--- a/source/blender/editors/interface/interface_regions.c
+++ b/source/blender/editors/interface/interface_regions.c
@@ -2185,7 +2185,7 @@ static void uiBlockPicker(uiBlock *block, float rgba[4], PointerRNA *ptr, Proper
yco = -3.0f * UI_UNIT_Y;
if (show_picker) {
- bt = uiDefIconButO(block, BUT, "UI_OT_eyedropper", WM_OP_INVOKE_DEFAULT, ICON_EYEDROPPER, butwidth + 10, yco, UI_UNIT_X, UI_UNIT_Y, NULL);
+ bt = uiDefIconButO(block, BUT, "UI_OT_eyedropper_color", WM_OP_INVOKE_DEFAULT, ICON_EYEDROPPER, butwidth + 10, yco, UI_UNIT_X, UI_UNIT_Y, NULL);
uiButSetFunc(bt, close_popup_cb, bt, NULL);
}
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index bd3103e499e..6b6b7114c84 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -3344,7 +3344,7 @@ static void keymap_item_modified(bContext *UNUSED(C), void *kmi_p, void *UNUSED(
static void template_keymap_item_properties(uiLayout *layout, const char *title, PointerRNA *ptr)
{
- uiLayout *flow;
+ uiLayout *flow, *box, *row;
uiItemS(layout);
@@ -3356,6 +3356,8 @@ static void template_keymap_item_properties(uiLayout *layout, const char *title,
RNA_STRUCT_BEGIN (ptr, prop)
{
int flag = RNA_property_flag(prop);
+ bool is_set = RNA_property_is_set(ptr, prop);
+ uiBut *but;
if (flag & PROP_HIDDEN)
continue;
@@ -3371,8 +3373,22 @@ static void template_keymap_item_properties(uiLayout *layout, const char *title,
}
}
- /* add property */
- uiItemFullR(flow, ptr, prop, -1, 0, 0, NULL, ICON_NONE);
+ box = uiLayoutBox(flow);
+ uiLayoutSetActive(box, is_set);
+ row = uiLayoutRow(box, false);
+
+ /* property value */
+ uiItemFullR(row, ptr, prop, -1, 0, 0, NULL, ICON_NONE);
+
+ if (is_set) {
+ /* unset operator */
+ uiBlock *block = uiLayoutGetBlock(row);
+ uiBlockSetEmboss(block, UI_EMBOSSN);
+ but = uiDefIconButO(block, BUT, "UI_OT_unset_property_button", WM_OP_EXEC_DEFAULT, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL);
+ but->rnapoin = *ptr;
+ but->rnaprop = prop;
+ uiBlockSetEmboss(block, UI_EMBOSS);
+ }
}
RNA_STRUCT_END;
}
diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c
index 22c20842723..00113666872 100644
--- a/source/blender/editors/interface/view2d_ops.c
+++ b/source/blender/editors/interface/view2d_ops.c
@@ -1374,14 +1374,16 @@ static void VIEW2D_OT_smoothview(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Smooth View 2D";
- ot->description = "Zoom in the view to the nearest item contained in the border";
+ ot->description = "";
ot->idname = "VIEW2D_OT_smoothview";
/* api callbacks */
ot->invoke = view2d_smoothview_invoke;
-
ot->poll = view2d_poll;
+ /* flags */
+ ot->flag = OPTYPE_INTERNAL;
+
/* rna */
WM_operator_properties_gesture_border(ot, FALSE);
}
diff --git a/source/blender/editors/io/io_collada.c b/source/blender/editors/io/io_collada.c
index 70fa97bebc1..f50e4400b91 100644
--- a/source/blender/editors/io/io_collada.c
+++ b/source/blender/editors/io/io_collada.c
@@ -96,7 +96,7 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op)
int use_object_instantiation;
int sort_by_name;
int export_transformation_type;
- int second_life;
+ int open_sim;
if (!RNA_struct_property_is_set(op->ptr, "filepath")) {
BKE_report(op->reports, RPT_ERROR, "No filename given");
@@ -142,7 +142,7 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op)
use_object_instantiation = RNA_boolean_get(op->ptr, "use_object_instantiation");
sort_by_name = RNA_boolean_get(op->ptr, "sort_by_name");
export_transformation_type = RNA_enum_get(op->ptr, "export_transformation_type_selection");
- second_life = RNA_boolean_get(op->ptr, "second_life");
+ open_sim = RNA_boolean_get(op->ptr, "open_sim");
/* get editmode results */
ED_object_editmode_load(CTX_data_edit_object(C));
@@ -168,7 +168,7 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op)
use_object_instantiation,
sort_by_name,
export_transformation_type,
- second_life))
+ open_sim))
{
return OPERATOR_FINISHED;
}
@@ -236,7 +236,7 @@ static void uiCollada_exportSettings(uiLayout *layout, PointerRNA *imfptr)
row = uiLayoutRow(box, FALSE);
uiItemR(row, imfptr, "deform_bones_only", 0, NULL, ICON_NONE);
row = uiLayoutRow(box, FALSE);
- uiItemR(row, imfptr, "second_life", 0, NULL, ICON_NONE);
+ uiItemR(row, imfptr, "open_sim", 0, NULL, ICON_NONE);
/* Collada options: */
box = uiLayoutBox(layout);
@@ -350,8 +350,8 @@ void WM_OT_collada_export(wmOperatorType *ot)
RNA_def_enum(ot->srna, "export_transformation_type_selection", prop_bc_export_transformation_type, 0,
"Transform", "Transformation type for translation, scale and rotation");
- RNA_def_boolean(ot->srna, "second_life", 0, "Export for Second Life",
- "Compatibility mode for Second Life");
+ RNA_def_boolean(ot->srna, "open_sim", 0, "Export for OpenSim",
+ "Compatibility mode for OpenSim and compatible online worlds");
}
diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c
index fec4ab87996..50d8e653737 100644
--- a/source/blender/editors/mask/mask_draw.c
+++ b/source/blender/editors/mask/mask_draw.c
@@ -35,6 +35,7 @@
#include "BLI_utildefines.h"
#include "BLI_math.h"
#include "BLI_rect.h"
+#include "BLI_task.h"
#include "BKE_context.h"
#include "BKE_mask.h"
@@ -48,6 +49,7 @@
#include "ED_mask.h" /* own include */
#include "ED_space_api.h"
#include "BIF_gl.h"
+#include "BIF_glutil.h"
#include "UI_resources.h"
#include "UI_view2d.h"
@@ -535,10 +537,93 @@ void ED_mask_draw(const bContext *C,
draw_masklays(C, mask, draw_flag, draw_type, width, height);
}
+typedef struct ThreadedMaskRasterizeState {
+ MaskRasterHandle *handle;
+ float *buffer;
+ int width, height;
+} ThreadedMaskRasterizeState;
+
+typedef struct ThreadedMaskRasterizeData {
+ int start_scanline;
+ int num_scanlines;
+} ThreadedMaskRasterizeData;
+
+static void mask_rasterize_func(TaskPool *pool, void *taskdata, int UNUSED(threadid))
+{
+ ThreadedMaskRasterizeState *state = (ThreadedMaskRasterizeState *) BLI_task_pool_userdata(pool);
+ ThreadedMaskRasterizeData *data = (ThreadedMaskRasterizeData *) taskdata;
+ int scanline;
+
+ for (scanline = 0; scanline < data->num_scanlines; scanline++) {
+ int x, y = data->start_scanline + scanline;
+ for (x = 0; x < state->width; x++) {
+ int index = y * state->width + x;
+ float xy[2];
+
+ xy[0] = (float) x / state->width;
+ xy[1] = (float) y / state->height;
+
+ state->buffer[index] = BKE_maskrasterize_handle_sample(state->handle, xy);
+ }
+ }
+}
+
+static float *threaded_mask_rasterize(Mask *mask, const int width, const int height)
+{
+ TaskScheduler *task_scheduler = BLI_task_scheduler_get();
+ TaskPool *task_pool;
+ MaskRasterHandle *handle;
+ ThreadedMaskRasterizeState state;
+ float *buffer;
+ int i, num_threads = BLI_task_scheduler_num_threads(task_scheduler), scanlines_per_thread;
+
+ buffer = MEM_mallocN(sizeof(float) * height * width, "rasterized mask buffer");
+
+ /* Initialize rasterization handle. */
+ handle = BKE_maskrasterize_handle_new();
+ BKE_maskrasterize_handle_init(handle, mask, width, height, TRUE, TRUE, TRUE);
+
+ state.handle = handle;
+ state.buffer = buffer;
+ state.width = width;
+ state.height = height;
+
+ task_pool = BLI_task_pool_create(task_scheduler, &state);
+
+ BLI_begin_threaded_malloc();
+
+ scanlines_per_thread = height / num_threads;
+ for (i = 0; i < num_threads; i++) {
+ ThreadedMaskRasterizeData *data = MEM_mallocN(sizeof(ThreadedMaskRasterizeData),
+ "threaded mask rasterize data");
+
+ data->start_scanline = i * scanlines_per_thread;
+
+ if (i < num_threads - 1) {
+ data->num_scanlines = scanlines_per_thread;
+ }
+ else {
+ data->num_scanlines = height - data->start_scanline;
+ }
+
+ BLI_task_pool_push(task_pool, mask_rasterize_func, data, true, TASK_PRIORITY_LOW);
+ }
+
+ /* work and wait until tasks are done */
+ BLI_task_pool_work_and_wait(task_pool);
+
+ /* Free memory. */
+ BLI_task_pool_free(task_pool);
+ BLI_end_threaded_malloc();
+ BKE_maskrasterize_handle_free(handle);
+
+ return buffer;
+}
+
/* sets up the opengl context.
* width, height are to match the values from ED_mask_get_size() */
void ED_mask_draw_region(Mask *mask, ARegion *ar,
- const char draw_flag, const char draw_type,
+ const char draw_flag, const char draw_type, const char overlay_mode,
const int width_i, const int height_i, /* convert directly into aspect corrected vars */
const float aspx, const float aspy,
const short do_scale_applied, const short do_draw_cb,
@@ -592,6 +677,37 @@ void ED_mask_draw_region(Mask *mask, ARegion *ar,
yofs = ((width - height) / -2.0f) * zoomy;
}
+ if (draw_flag & MASK_DRAWFLAG_OVERLAY) {
+ float *buffer = threaded_mask_rasterize(mask, width, height);
+ int format;
+
+ if (overlay_mode == MASK_OVERLAY_ALPHACHANNEL) {
+ glColor3f(1.0f, 1.0f, 1.0f);
+ format = GL_LUMINANCE;
+ }
+ else {
+ /* More blending types could be supported in the future. */
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_DST_COLOR, GL_SRC_ALPHA);
+ format = GL_ALPHA;
+ }
+
+ glPushMatrix();
+ glTranslatef(x, y, 0);
+ glScalef(zoomx, zoomy, 0);
+ if (stabmat) {
+ glMultMatrixf(stabmat);
+ }
+ glaDrawPixelsTex(0.0f, 0.0f, width, height, format, GL_FLOAT, GL_NEAREST, buffer);
+ glPopMatrix();
+
+ if (overlay_mode != MASK_OVERLAY_ALPHACHANNEL) {
+ glDisable(GL_BLEND);
+ }
+
+ MEM_freeN(buffer);
+ }
+
/* apply transformation so mask editing tools will assume drawing from the origin in normalized space */
glPushMatrix();
glTranslatef(x + xofs, y + yofs, 0);
diff --git a/source/blender/editors/mesh/editmesh_bevel.c b/source/blender/editors/mesh/editmesh_bevel.c
index 6033e7ee471..97da0047793 100644
--- a/source/blender/editors/mesh/editmesh_bevel.c
+++ b/source/blender/editors/mesh/editmesh_bevel.c
@@ -64,7 +64,7 @@ typedef struct {
float shift_factor; /* The current factor when shift is pressed. Negative when shift not active. */
/* modal only */
- int mcenter[2];
+ float mcenter[2];
BMBackup mesh_backup;
void *draw_handle_pixel;
short twtype;
diff --git a/source/blender/editors/mesh/editmesh_bisect.c b/source/blender/editors/mesh/editmesh_bisect.c
index afafd8458c5..5431b1deb1c 100644
--- a/source/blender/editors/mesh/editmesh_bisect.c
+++ b/source/blender/editors/mesh/editmesh_bisect.c
@@ -300,7 +300,7 @@ void MESH_OT_bisect(struct wmOperatorType *ot)
/* identifiers */
ot->name = "Bisect";
- ot->description = "Enforce symmetry (both form and topological) across an axis";
+ ot->description = "Cut geometry along a plane";
ot->idname = "MESH_OT_bisect";
/* api callbacks */
diff --git a/source/blender/editors/mesh/editmesh_extrude.c b/source/blender/editors/mesh/editmesh_extrude.c
index 300fb67ec80..3df4ad738ae 100644
--- a/source/blender/editors/mesh/editmesh_extrude.c
+++ b/source/blender/editors/mesh/editmesh_extrude.c
@@ -290,7 +290,7 @@ static int edbm_extrude_repeat_exec(bContext *C, wmOperator *op)
//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);
+ dvec, BM_ELEM_SELECT);
//extrudeflag(obedit, em, SELECT, nor);
//translateflag(em, SELECT, dvec);
}
diff --git a/source/blender/editors/mesh/editmesh_inset.c b/source/blender/editors/mesh/editmesh_inset.c
index 3966826a5b2..71822868026 100644
--- a/source/blender/editors/mesh/editmesh_inset.c
+++ b/source/blender/editors/mesh/editmesh_inset.c
@@ -68,7 +68,7 @@ typedef struct {
NumInput num_input;
/* modal only */
- int mcenter[2];
+ float mcenter[2];
BMBackup mesh_backup;
void *draw_handle_pixel;
short twtype;
diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c
index ea974fc76f5..9d8b283fe1a 100644
--- a/source/blender/editors/mesh/editmesh_knife.c
+++ b/source/blender/editors/mesh/editmesh_knife.c
@@ -628,13 +628,13 @@ static int find_connected_linehit(KnifeTool_OpData *kcd, int testi, BMFace *f, i
}
if (testfaces) {
if (ifaces)
- shareface = knife_find_common_face(testfaces, ifaces);
+ shareface = (knife_find_common_face(testfaces, ifaces) != NULL);
else if (iface)
- shareface = find_ref(testfaces, iface);
+ shareface = (find_ref(testfaces, iface) != NULL);
}
else if (ifaces) {
if (testface)
- shareface = find_ref(ifaces, testface);
+ shareface = (find_ref(ifaces, testface) != NULL);
}
else if (testface && iface) {
shareface = (testface == iface);
@@ -1233,6 +1233,69 @@ static float len_v3_tri_side_max(const float v1[3], const float v2[3], const flo
return sqrtf(max_fff(s1, s2, s3));
}
+/**
+ * given a tri, return 3 planes aligned with the tri's normal.
+ *
+ * If the triangle were extruded along its normal,
+ * the planes calculated would be the 3 sides around the extrusion.
+ */
+static void plane_from_tri_clip3_v3(
+ float tri_plane_clip[3][4],
+ const float v0[3], const float v1[3], const float v2[3])
+{
+ float tri_norm[3];
+ float tvec[3], cross[3];
+
+ normal_tri_v3(tri_norm, v0, v1, v2);
+
+ sub_v3_v3v3(tvec, v0, v1);
+ cross_v3_v3v3(cross, tvec, tri_norm);
+ plane_from_point_normal_v3(tri_plane_clip[0], v0, cross);
+
+ sub_v3_v3v3(tvec, v1, v2);
+ cross_v3_v3v3(cross, tvec, tri_norm);
+ plane_from_point_normal_v3(tri_plane_clip[1], v1, cross);
+
+ sub_v3_v3v3(tvec, v2, v0);
+ cross_v3_v3v3(cross, tvec, tri_norm);
+ plane_from_point_normal_v3(tri_plane_clip[2], v2, cross);
+}
+
+/**
+ * Given a line that is planar with a tri, clip the segment by that tri.
+ *
+ * This is needed so we end up with both points in the triangle.
+ */
+static bool isect_line_tri_coplanar_v3(
+ const float p1[3], const float p2[3],
+ const float v0[3], const float v1[3], const float v2[3],
+ float r_isects[2][3],
+
+ /* avoid re-calculating every time */
+ float tri_plane[4], float tri_plane_clip[3][4])
+{
+ float p1_tmp[3] = {UNPACK3(p1)};
+ float p2_tmp[3] = {UNPACK3(p2)};
+
+ (void)v0, (void)v1, (void)v2;
+
+ /* first check if the points are planar with the tri */
+ if ((fabsf(dist_squared_to_plane_v3(p1, tri_plane)) < KNIFE_FLT_EPS_SQUARED) &&
+ (fabsf(dist_squared_to_plane_v3(p2, tri_plane)) < KNIFE_FLT_EPS_SQUARED) &&
+ /* clip the segment by planes around the triangle so we can be sure the points
+ * aren't outside the triangle */
+ (clip_segment_v3_plane_n(p1_tmp, p2_tmp, tri_plane_clip, 3)))
+ {
+ copy_v3_v3(r_isects[0], p1_tmp);
+ copy_v3_v3(r_isects[1], p2_tmp);
+
+ return true;
+ }
+ else {
+ return false;
+ }
+}
+
static BMEdgeHit *knife_edge_tri_isect(KnifeTool_OpData *kcd, BMBVHTree *bmtree,
const float v1[3], const float v2[3], const float v3[3],
SmallHash *ehash, bglMats *mats, int *count)
@@ -1243,9 +1306,11 @@ static BMEdgeHit *knife_edge_tri_isect(KnifeTool_OpData *kcd, BMBVHTree *bmtree,
BVHTreeOverlap *results, *result;
BMLoop **ls;
float cos[9], tri_norm[3], tri_plane[4], isects[2][3], lambda;
+ float tri_plane_clip[3][4];
unsigned int tot = 0;
int i, j, n_isects;
+
/* for comparing distances, error of intersection depends on triangle scale.
* need to scale down before squaring for accurate comparison */
const float depsilon = (FLT_EPSILON / 2.0f) * len_v3_tri_side_max(v1, v2, v3);
@@ -1255,8 +1320,10 @@ static BMEdgeHit *knife_edge_tri_isect(KnifeTool_OpData *kcd, BMBVHTree *bmtree,
copy_v3_v3(cos + 3, v2);
copy_v3_v3(cos + 6, v3);
+ /* avoid re-calculation in #isect_line_tri_coplanar_v3 */
normal_tri_v3(tri_norm, v1, v2, v3);
plane_from_point_normal_v3(tri_plane, v1, tri_norm);
+ plane_from_tri_clip3_v3(tri_plane_clip, v1, v2, v3);
BLI_bvhtree_insert(tree2, 0, cos, 3);
BLI_bvhtree_balance(tree2);
@@ -1282,21 +1349,25 @@ static BMEdgeHit *knife_edge_tri_isect(KnifeTool_OpData *kcd, BMBVHTree *bmtree,
}
n_isects = 0;
- if (fabsf(dist_to_plane_v3(kfe->v1->cageco, tri_plane)) < KNIFE_FLT_EPS &&
- fabsf(dist_to_plane_v3(kfe->v2->cageco, tri_plane)) < KNIFE_FLT_EPS)
+
+ if (isect_line_tri_coplanar_v3(kfe->v1->cageco, kfe->v2->cageco, v1, v2, v3,
+ isects,
+ /* cached values */
+ tri_plane, tri_plane_clip))
{
/* both kfe ends are in cutting triangle */
- copy_v3_v3(isects[0], kfe->v1->cageco);
- copy_v3_v3(isects[1], kfe->v2->cageco);
n_isects = 2;
}
- else if (isect_line_tri_epsilon_v3(kfe->v1->cageco, kfe->v2->cageco, v1, v2, v3, &lambda, NULL, depsilon)) {
+ else if (isect_line_tri_epsilon_v3(kfe->v1->cageco, kfe->v2->cageco, v1, v2, v3,
+ &lambda, NULL, depsilon))
+ {
/* kfe intersects cutting triangle lambda of the way along kfe */
interp_v3_v3v3(isects[0], kfe->v1->cageco, kfe->v2->cageco, lambda);
n_isects = 1;
}
+
for (j = 0; j < n_isects; j++) {
- float p[3], no[3], view[3], sp[2];
+ float p[3];
copy_v3_v3(p, isects[j]);
if (kcd->curr.vert && len_squared_v3v3(kcd->curr.vert->cageco, p) < depsilon_sq) {
@@ -1316,16 +1387,18 @@ static BMEdgeHit *knife_edge_tri_isect(KnifeTool_OpData *kcd, BMBVHTree *bmtree,
continue;
}
- knife_project_v2(kcd, p, sp);
- ED_view3d_unproject(mats, view, sp[0], sp[1], 0.0f);
- mul_m4_v3(kcd->ob->imat, view);
-
if (kcd->cut_through) {
f_hit = NULL;
}
else {
/* check if this point is visible in the viewport */
- float p1[3], lambda1;
+ float p1[3], no[3], view[3], sp[2];
+ float lambda1;
+
+ /* screen projection */
+ knife_project_v2(kcd, p, sp);
+ ED_view3d_unproject(mats, view, sp[0], sp[1], 0.0f);
+ mul_m4_v3(kcd->ob->imat, view);
/* if face isn't planer, p may be behind the current tesselated tri,
* so move it onto that and then a little towards eye */
@@ -1473,8 +1546,16 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
knife_project_v2(kcd, v1, s1);
knife_project_v2(kcd, v2, s2);
- if (len_squared_v2v2(s1, s2) < 1)
- return;
+ if (kcd->is_interactive) {
+ if (len_squared_v2v2(s1, s2) < 1.0f) {
+ return;
+ }
+ }
+ else {
+ if (len_squared_v2v2(s1, s2) < KNIFE_FLT_EPS_SQUARED) {
+ return;
+ }
+ }
/* unproject screen line */
ED_view3d_win_to_segment(kcd->ar, kcd->vc.v3d, s1, v1, v3, true);
@@ -2050,7 +2131,7 @@ static void knifenet_fill_faces(KnifeTool_OpData *kcd)
facenet_entry *entry;
ListBase *face_nets = MEM_callocN(sizeof(ListBase) * bm->totface, "face_nets");
BMFace **faces = MEM_callocN(sizeof(BMFace *) * bm->totface, "faces knife");
- MemArena *arena = BLI_memarena_new(1 << 16, "knifenet_fill_faces");
+ MemArena *arena = BLI_memarena_new(MEM_SIZE_OPTIMAL(1 << 16), "knifenet_fill_faces");
SmallHash shash;
RNG *rng;
int i, j, k = 0, totface = bm->totface;
@@ -3078,7 +3159,7 @@ static void knifetool_init(bContext *C, KnifeTool_OpData *kcd,
(only_select ? BMBVH_RESPECT_SELECT : BMBVH_RESPECT_HIDDEN),
kcd->cagecos, false);
- kcd->arena = BLI_memarena_new(1 << 15, "knife");
+ kcd->arena = BLI_memarena_new(MEM_SIZE_OPTIMAL(1 << 15), "knife");
kcd->vthresh = KMAXDIST - 1;
kcd->ethresh = KMAXDIST;
@@ -3444,7 +3525,7 @@ static bool edbm_mesh_knife_face_isect(ARegion *ar, LinkNode *polys, BMFace *f,
while (p) {
const float (*mval_fl)[2] = p->link;
const int mval_tot = MEM_allocN_len(mval_fl) / sizeof(*mval_fl);
- isect += (int)isect_point_poly_v2(cent_ss, mval_fl, mval_tot - 1);
+ isect += (int)isect_point_poly_v2(cent_ss, mval_fl, mval_tot - 1, false);
p = p->next;
}
diff --git a/source/blender/editors/mesh/editmesh_loopcut.c b/source/blender/editors/mesh/editmesh_loopcut.c
index 892b773b1ba..ae1007cb98a 100644
--- a/source/blender/editors/mesh/editmesh_loopcut.c
+++ b/source/blender/editors/mesh/editmesh_loopcut.c
@@ -537,7 +537,8 @@ static int loopcut_modal(bContext *C, wmOperator *op, const wmEvent *event)
if (event->val == KM_PRESS) {
/* finish */
ED_region_tag_redraw(lcd->ar);
-
+ ED_area_headerprint(CTX_wm_area(C), NULL);
+
if (lcd->eed) {
/* set for redo */
BM_mesh_elem_index_ensure(lcd->em->bm, BM_EDGE);
@@ -550,9 +551,7 @@ static int loopcut_modal(bContext *C, wmOperator *op, const wmEvent *event)
else {
return ringcut_cancel(C, op);
}
-
- ED_area_headerprint(CTX_wm_area(C), NULL);
-
+
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c
index 806ae96cb61..f975d801d10 100644
--- a/source/blender/editors/mesh/editmesh_select.c
+++ b/source/blender/editors/mesh/editmesh_select.c
@@ -31,6 +31,7 @@
#include "MEM_guardedalloc.h"
+#include "BLI_bitmap.h"
#include "BLI_listbase.h"
#include "BLI_linklist.h"
#include "BLI_linklist_stack.h"
@@ -184,55 +185,13 @@ void EDBM_automerge(Scene *scene, Object *obedit, bool update, const char hflag)
unsigned int bm_solidoffs = 0, bm_wireoffs = 0, bm_vertoffs = 0; /* set in drawobject.c ... for colorindices */
/* facilities for border select and circle select */
-static char *selbuf = NULL;
+static BLI_bitmap *selbuf = NULL;
-/* opengl doesn't support concave... */
-static void draw_triangulated(const int mcords[][2], const short tot)
+static BLI_bitmap *edbm_backbuf_alloc(const int size)
{
- ListBase lb = {NULL, NULL};
- DispList *dl;
- float *fp;
- int a;
- const float z_up[3] = {0.0f, 0.0f, 1.0f};
-
- /* make displist */
- dl = MEM_callocN(sizeof(DispList), "poly disp");
- dl->type = DL_POLY;
- dl->parts = 1;
- dl->nr = tot;
- dl->verts = fp = MEM_callocN(tot * 3 * sizeof(float), "poly verts");
- BLI_addtail(&lb, dl);
-
- for (a = 0; a < tot; a++, fp += 3) {
- fp[0] = (float)mcords[a][0];
- fp[1] = (float)mcords[a][1];
- }
-
- /* do the fill */
- BKE_displist_fill(&lb, &lb, z_up, false);
-
- /* do the draw */
- dl = lb.first; /* filldisplist adds in head of list */
- if (dl->type == DL_INDEX3) {
- int *index;
-
- a = dl->parts;
- fp = dl->verts;
- index = dl->index;
- glBegin(GL_TRIANGLES);
- while (a--) {
- glVertex3fv(fp + 3 * index[0]);
- glVertex3fv(fp + 3 * index[1]);
- glVertex3fv(fp + 3 * index[2]);
- index += 3;
- }
- glEnd();
- }
-
- BKE_displist_free(&lb);
+ return BLI_BITMAP_NEW(size, "selbuf");
}
-
/* reads rect, and builds selection array for quick lookup */
/* returns if all is OK */
bool EDBM_backbuf_border_init(ViewContext *vc, short xmin, short ymin, short xmax, short ymax)
@@ -252,24 +211,31 @@ bool EDBM_backbuf_border_init(ViewContext *vc, short xmin, short ymin, short xma
dr = buf->rect;
/* build selection lookup */
- selbuf = MEM_callocN(bm_vertoffs + 1, "selbuf");
+ selbuf = edbm_backbuf_alloc(bm_vertoffs + 1);
a = (xmax - xmin + 1) * (ymax - ymin + 1);
while (a--) {
- if (*dr > 0 && *dr <= bm_vertoffs)
- selbuf[*dr] = 1;
+ if (*dr > 0 && *dr <= bm_vertoffs) {
+ BLI_BITMAP_SET(selbuf, *dr);
+ }
dr++;
}
IMB_freeImBuf(buf);
return true;
}
-int EDBM_backbuf_check(unsigned int index)
+bool EDBM_backbuf_check(unsigned int index)
{
- if (selbuf == NULL) return 1;
+ /* odd logic, if selbuf is NULL we assume no zbuf-selection is enabled
+ * and just ignore the depth buffer, this is error prone since its possible
+ * code doesn't set the depth buffer by accident, but leave for now. - Campbell */
+ if (selbuf == NULL)
+ return true;
+
if (index > 0 && index <= bm_vertoffs)
- return selbuf[index];
- return 0;
+ return BLI_BITMAP_GET_BOOL(selbuf, index);
+
+ return false;
}
void EDBM_backbuf_free(void)
@@ -278,6 +244,18 @@ void EDBM_backbuf_free(void)
selbuf = NULL;
}
+struct LassoMaskData {
+ unsigned int *px;
+ int width;
+};
+
+static void edbm_mask_lasso_px_cb(int x, int y, void *user_data)
+{
+ struct LassoMaskData *data = user_data;
+ data->px[(y * data->width) + x] = true;
+}
+
+
/* mcords is a polygon mask
* - grab backbuffer,
* - draw with black in backbuffer,
@@ -286,9 +264,10 @@ void EDBM_backbuf_free(void)
*/
bool EDBM_backbuf_border_mask_init(ViewContext *vc, const int mcords[][2], short tot, short xmin, short ymin, short xmax, short ymax)
{
- unsigned int *dr, *drm;
- struct ImBuf *buf, *bufmask;
+ unsigned int *dr, *dr_mask, *dr_mask_arr;
+ struct ImBuf *buf;
int a;
+ struct LassoMaskData lasso_mask_data;
/* method in use for face selecting too */
if (vc->obedit == NULL) {
@@ -306,49 +285,27 @@ bool EDBM_backbuf_border_mask_init(ViewContext *vc, const int mcords[][2], short
dr = buf->rect;
- if (vc->rv3d->gpuoffscreen)
- GPU_offscreen_bind(vc->rv3d->gpuoffscreen);
-
- /* draw the mask */
- glDisable(GL_DEPTH_TEST);
-
- glColor3ub(0, 0, 0);
-
- /* yah, opengl doesn't do concave... tsk! */
- ED_region_pixelspace(vc->ar);
- draw_triangulated(mcords, tot);
-
- glBegin(GL_LINE_LOOP); /* for zero sized masks, lines */
- for (a = 0; a < tot; a++) {
- glVertex2iv(mcords[a]);
- }
- glEnd();
-
- glFinish(); /* to be sure readpixels sees mask */
-
- if (vc->rv3d->gpuoffscreen)
- GPU_offscreen_unbind(vc->rv3d->gpuoffscreen);
-
- /* grab mask */
- bufmask = view3d_read_backbuf(vc, xmin, ymin, xmax, ymax);
+ dr_mask = dr_mask_arr = MEM_callocN(sizeof(*dr_mask) * buf->x * buf->y, __func__);
+ lasso_mask_data.px = dr_mask;
+ lasso_mask_data.width = (xmax - xmin) + 1;
- if (bufmask == NULL) {
- return false; /* only when mem alloc fails, go crash somewhere else! */
- }
- else {
- drm = bufmask->rect;
- }
+ fill_poly_v2i_n(
+ xmin, ymin, xmax + 1, ymax + 1,
+ mcords, tot,
+ edbm_mask_lasso_px_cb, &lasso_mask_data);
/* build selection lookup */
- selbuf = MEM_callocN(bm_vertoffs + 1, "selbuf");
+ selbuf = edbm_backbuf_alloc(bm_vertoffs + 1);
a = (xmax - xmin + 1) * (ymax - ymin + 1);
while (a--) {
- if (*dr > 0 && *dr <= bm_vertoffs && *drm == 0) selbuf[*dr] = 1;
- dr++; drm++;
+ if (*dr > 0 && *dr <= bm_vertoffs && *dr_mask == true) {
+ BLI_BITMAP_SET(selbuf, *dr);
+ }
+ dr++; dr_mask++;
}
IMB_freeImBuf(buf);
- IMB_freeImBuf(bufmask);
+ MEM_freeN(dr_mask_arr);
return true;
}
@@ -380,12 +337,14 @@ bool EDBM_backbuf_circle_init(ViewContext *vc, short xs, short ys, short rads)
dr = buf->rect;
/* build selection lookup */
- selbuf = MEM_callocN(bm_vertoffs + 1, "selbuf");
+ selbuf = edbm_backbuf_alloc(bm_vertoffs + 1);
radsq = rads * rads;
for (yc = -rads; yc <= rads; yc++) {
for (xc = -rads; xc <= rads; xc++, dr++) {
if (xc * xc + yc * yc < radsq) {
- if (*dr > 0 && *dr <= bm_vertoffs) selbuf[*dr] = 1;
+ if (*dr > 0 && *dr <= bm_vertoffs) {
+ BLI_BITMAP_SET(selbuf, *dr);
+ }
}
}
}
@@ -1897,7 +1856,6 @@ static int edbm_select_linked_exec(bContext *C, wmOperator *op)
BMEditMesh *em = BKE_editmesh_from_object(obedit);
BMesh *bm = em->bm;
BMIter iter;
- BMVert *v;
BMEdge *e;
BMWalker walker;
@@ -1911,8 +1869,7 @@ static int edbm_select_linked_exec(bContext *C, wmOperator *op)
BMFace *efa;
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- BM_elem_flag_set(efa, BM_ELEM_TAG, (BM_elem_flag_test(efa, BM_ELEM_SELECT) &&
- !BM_elem_flag_test(efa, BM_ELEM_HIDDEN)));
+ BM_elem_flag_set(efa, BM_ELEM_TAG, BM_elem_flag_test(efa, BM_ELEM_SELECT));
}
if (limit) {
@@ -1932,6 +1889,7 @@ static int edbm_select_linked_exec(bContext *C, wmOperator *op)
if (BM_elem_flag_test(efa, BM_ELEM_TAG)) {
for (efa = BMW_begin(&walker, efa); efa; efa = BMW_step(&walker)) {
BM_face_select_set(bm, efa, true);
+ BM_elem_flag_disable(efa, BM_ELEM_TAG);
}
}
}
@@ -1942,13 +1900,10 @@ static int edbm_select_linked_exec(bContext *C, wmOperator *op)
}
}
else {
+ BMVert *v;
+
BM_ITER_MESH (v, &iter, em->bm, BM_VERTS_OF_MESH) {
- if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
- BM_elem_flag_enable(v, BM_ELEM_TAG);
- }
- else {
- BM_elem_flag_disable(v, BM_ELEM_TAG);
- }
+ BM_elem_flag_set(v, BM_ELEM_TAG, BM_elem_flag_test(v, BM_ELEM_SELECT));
}
BMW_init(&walker, em->bm, BMW_SHELL,
@@ -1960,6 +1915,7 @@ static int edbm_select_linked_exec(bContext *C, wmOperator *op)
if (BM_elem_flag_test(v, BM_ELEM_TAG)) {
for (e = BMW_begin(&walker, v); e; e = BMW_step(&walker)) {
BM_edge_select_set(em->bm, e, true);
+ BM_elem_flag_disable(e, BM_ELEM_TAG);
}
}
}
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index f0e5a64b1bd..9e5782c12f2 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -983,12 +983,6 @@ void MESH_OT_flip_normals(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-static const EnumPropertyItem direction_items[] = {
- {false, "CW", 0, "Clockwise", ""},
- {true, "CCW", 0, "Counter Clockwise", ""},
- {0, NULL, 0, NULL, NULL}
-};
-
/* only accepts 1 selected edge, or 2 selected faces */
static int edbm_edge_rotate_selected_exec(bContext *C, wmOperator *op)
{
@@ -3008,7 +3002,7 @@ static int edbm_fill_grid_exec(bContext *C, wmOperator *op)
}
offset = RNA_property_int_get(op->ptr, prop_offset);
- offset = mod_i(offset, clamp);
+ offset = clamp ? mod_i(offset, clamp) : 0;
/* in simple cases, move selection for tags, but also support more advanced cases */
edbm_fill_grid_prepare(em->bm, offset, &span, calc_span);
@@ -3342,7 +3336,7 @@ void MESH_OT_dissolve_verts(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Dissolve Vertices";
- ot->description = "Dissolve geometry";
+ ot->description = "Dissolve verts, merge edges and faces";
ot->idname = "MESH_OT_dissolve_verts";
/* api callbacks */
@@ -3379,7 +3373,7 @@ void MESH_OT_dissolve_edges(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Dissolve Edges";
- ot->description = "Dissolve geometry";
+ ot->description = "Dissolve edges, merging faces";
ot->idname = "MESH_OT_dissolve_edges";
/* api callbacks */
@@ -3418,7 +3412,7 @@ void MESH_OT_dissolve_faces(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Dissolve Faces";
- ot->description = "Dissolve geometry";
+ ot->description = "Dissolve faces";
ot->idname = "MESH_OT_dissolve_faces";
/* api callbacks */
@@ -4519,7 +4513,7 @@ void MESH_OT_wireframe(wmOperatorType *ot)
/* identifiers */
ot->name = "Wire Frame";
ot->idname = "MESH_OT_wireframe";
- ot->description = "Inset new faces into selected faces";
+ ot->description = "Create a solid wire-frame from faces";
/* api callbacks */
ot->exec = edbm_wireframe_exec;
@@ -4561,7 +4555,8 @@ static int edbm_convex_hull_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
-
+ BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "geom.out", BM_FACE, BM_ELEM_SELECT, true);
+
/* 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",
@@ -4584,9 +4579,11 @@ 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, "geom.out",
- RNA_float_get(op->ptr, "limit")))
+ if (!EDBM_op_call_and_selectf(em, op,
+ "faces.out", true,
+ "join_triangles faces=%S limit=%f",
+ &bmop, "geom.out",
+ RNA_float_get(op->ptr, "limit")))
{
EDBM_op_finish(em, &bmop, op, true);
return OPERATOR_CANCELLED;
diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c
index a64a23a9f4a..e457f7c45af 100644
--- a/source/blender/editors/mesh/editmesh_utils.c
+++ b/source/blender/editors/mesh/editmesh_utils.c
@@ -662,10 +662,7 @@ static void undoMesh_to_editbtMesh(void *umv, void *em_v, void *UNUSED(obdata))
UndoMesh *um = umv;
BMesh *bm;
- const BMAllocTemplate allocsize = {um->me.totvert,
- um->me.totedge,
- um->me.totloop,
- um->me.totpoly};
+ const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(&um->me);
ob->shapenr = em->bm->shapenr = um->shapenr;
diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c
index efa619bd10c..5ee980ef5cb 100644
--- a/source/blender/editors/mesh/meshtools.c
+++ b/source/blender/editors/mesh/meshtools.c
@@ -314,7 +314,7 @@ int join_mesh_exec(bContext *C, wmOperator *op)
/* standard data */
CustomData_merge(&me->vdata, &vdata, CD_MASK_MESH, CD_DEFAULT, totvert);
- CustomData_copy_data(&me->vdata, &vdata, 0, vertofs, me->totvert);
+ CustomData_copy_data_named(&me->vdata, &vdata, 0, vertofs, me->totvert);
/* vertex groups */
dvert = CustomData_get(&vdata, vertofs, CD_MDEFORMVERT);
@@ -415,7 +415,7 @@ int join_mesh_exec(bContext *C, wmOperator *op)
if (me->totedge) {
CustomData_merge(&me->edata, &edata, CD_MASK_MESH, CD_DEFAULT, totedge);
- CustomData_copy_data(&me->edata, &edata, 0, edgeofs, me->totedge);
+ CustomData_copy_data_named(&me->edata, &edata, 0, edgeofs, me->totedge);
for (a = 0; a < me->totedge; a++, medge++) {
medge->v1 += vertofs;
@@ -437,7 +437,7 @@ int join_mesh_exec(bContext *C, wmOperator *op)
}
CustomData_merge(&me->ldata, &ldata, CD_MASK_MESH, CD_DEFAULT, totloop);
- CustomData_copy_data(&me->ldata, &ldata, 0, loopofs, me->totloop);
+ CustomData_copy_data_named(&me->ldata, &ldata, 0, loopofs, me->totloop);
for (a = 0; a < me->totloop; a++, mloop++) {
mloop->v += vertofs;
@@ -461,7 +461,7 @@ int join_mesh_exec(bContext *C, wmOperator *op)
}
CustomData_merge(&me->pdata, &pdata, CD_MASK_MESH, CD_DEFAULT, totpoly);
- CustomData_copy_data(&me->pdata, &pdata, 0, polyofs, me->totpoly);
+ CustomData_copy_data_named(&me->pdata, &pdata, 0, polyofs, me->totpoly);
for (a = 0; a < me->totpoly; a++, mpoly++) {
mpoly->loopstart += loopofs;
diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c
index 8b674cf1e50..4a8097f260e 100644
--- a/source/blender/editors/object/object_bake.c
+++ b/source/blender/editors/object/object_bake.c
@@ -91,20 +91,24 @@
typedef struct MultiresBakerJobData {
struct MultiresBakerJobData *next, *prev;
DerivedMesh *lores_dm, *hires_dm;
- int simple, lvl, tot_lvl;
+ bool simple;
+ int lvl, tot_lvl;
ListBase images;
} MultiresBakerJobData;
/* data passing to multires-baker job */
typedef struct {
ListBase data;
- int bake_clear, bake_filter;
- short mode, use_lores_mesh;
- int number_of_rays;
- float bias;
- int raytrace_structure;
- int octree_resolution;
- int threads;
+ bool bake_clear; /* Clear the images before baking */
+ int bake_filter; /* Bake-filter, aka margin */
+ short mode; /* mode of baking (displacement, normals, AO) */
+ bool use_lores_mesh; /* Use low-resolution mesh when baking displacement maps */
+ int number_of_rays; /* Number of rays to be cast when doing AO baking */
+ float bias; /* Bias between object and start ray point when doing AO baking */
+ int raytrace_structure; /* Optimization structure to be used for AO baking */
+ int octree_resolution; /* Reslution of octotree when using octotree optimization structure */
+ int threads; /* Number of threads to be used for baking */
+ float user_scale; /* User scale used to scale displacement when baking derivative map. */
} MultiresBakeJob;
static bool multiresbake_check(bContext *C, wmOperator *op)
@@ -236,7 +240,7 @@ static DerivedMesh *multiresbake_create_loresdm(Scene *scene, Object *ob, int *l
return dm;
}
-static DerivedMesh *multiresbake_create_hiresdm(Scene *scene, Object *ob, int *lvl, int *simple)
+static DerivedMesh *multiresbake_create_hiresdm(Scene *scene, Object *ob, int *lvl, bool *simple)
{
Mesh *me = (Mesh *)ob->data;
MultiresModifierData *mmd = get_multires_modifier(scene, ob, 0);
@@ -253,7 +257,7 @@ static DerivedMesh *multiresbake_create_hiresdm(Scene *scene, Object *ob, int *l
CustomData_set_only_copy(&cddm->polyData, CD_MASK_BAREMESH);
*lvl = mmd->totlvl;
- *simple = mmd->simple;
+ *simple = mmd->simple != 0;
tmp_mmd.lvl = mmd->totlvl;
tmp_mmd.sculptlvl = mmd->totlvl;
@@ -264,40 +268,68 @@ static DerivedMesh *multiresbake_create_hiresdm(Scene *scene, Object *ob, int *l
}
typedef enum ClearFlag {
- CLEAR_NORMAL = 1
+ CLEAR_TANGENT_NORMAL = 1,
+ CLEAR_DISPLACEMENT = 2
} ClearFlag;
-static void clear_images(MTFace *mtface, int totface, ClearFlag flag)
+static void clear_single_image(Image *image, ClearFlag flag)
{
- int a;
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};
const float nor_alpha[4] = {0.5f, 0.5f, 1.0f, 0.0f};
const float nor_solid[4] = {0.5f, 0.5f, 1.0f, 1.0f};
+ const float disp_alpha[4] = {0.5f, 0.5f, 0.5f, 0.0f};
+ const float disp_solid[4] = {0.5f, 0.5f, 0.5f, 1.0f};
+
+ if ((image->id.flag & LIB_DOIT) == 0) {
+ ImBuf *ibuf = BKE_image_acquire_ibuf(image, NULL, NULL);
+
+ if (flag == CLEAR_TANGENT_NORMAL)
+ IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? nor_alpha : nor_solid);
+ else if (flag == CLEAR_DISPLACEMENT)
+ IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? disp_alpha : disp_solid);
+ else
+ IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? vec_alpha : vec_solid);
+
+ image->id.flag |= LIB_DOIT;
- for (a = 0; a < totface; a++)
+ BKE_image_release_ibuf(image, ibuf, NULL);
+ }
+}
+
+static void clear_images(MTFace *mtface, int totface, ClearFlag flag)
+{
+ int a;
+
+ for (a = 0; a < totface; a++) {
mtface[a].tpage->id.flag &= ~LIB_DOIT;
+ }
for (a = 0; a < totface; a++) {
- Image *ima = mtface[a].tpage;
+ clear_single_image(mtface[a].tpage, flag);
+ }
- if ((ima->id.flag & LIB_DOIT) == 0) {
- ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
+ for (a = 0; a < totface; a++) {
+ mtface[a].tpage->id.flag &= ~LIB_DOIT;
+ }
+}
- if (flag == CLEAR_NORMAL)
- IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? nor_alpha : nor_solid);
- else
- IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? vec_alpha : vec_solid);
+static void clear_images_poly(MTexPoly *mtpoly, int totpoly, ClearFlag flag)
+{
+ int a;
- ima->id.flag |= LIB_DOIT;
+ for (a = 0; a < totpoly; a++) {
+ mtpoly[a].tpage->id.flag &= ~LIB_DOIT;
+ }
- BKE_image_release_ibuf(ima, ibuf, NULL);
- }
+ for (a = 0; a < totpoly; a++) {
+ clear_single_image(mtpoly[a].tpage, flag);
}
- for (a = 0; a < totface; a++)
- mtface[a].tpage->id.flag &= ~LIB_DOIT;
+ for (a = 0; a < totpoly; a++) {
+ mtpoly[a].tpage->id.flag &= ~LIB_DOIT;
+ }
}
static int multiresbake_image_exec_locked(bContext *C, wmOperator *op)
@@ -313,14 +345,20 @@ static int multiresbake_image_exec_locked(bContext *C, wmOperator *op)
CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
{
Mesh *me;
+ ClearFlag clear_flag = 0;
ob = base->object;
me = (Mesh *)ob->data;
- if (scene->r.bake_mode == RE_BAKE_NORMALS && scene->r.bake_normal_space == R_BAKE_SPACE_TANGENT)
- clear_images(me->mtface, me->totface, CLEAR_NORMAL);
- else
- clear_images(me->mtface, me->totface, 0);
+ if (scene->r.bake_mode == RE_BAKE_NORMALS) {
+ clear_flag = CLEAR_TANGENT_NORMAL;
+ }
+ else if (ELEM(scene->r.bake_mode, RE_BAKE_DISPLACEMENT, RE_BAKE_DERIVATIVE)) {
+ clear_flag = CLEAR_DISPLACEMENT;
+ }
+
+ clear_images(me->mtface, me->totface, clear_flag);
+ clear_images_poly(me->mtpoly, me->totpoly, clear_flag);
}
CTX_DATA_END;
}
@@ -342,6 +380,8 @@ static int multiresbake_image_exec_locked(bContext *C, wmOperator *op)
bkr.raytrace_structure = scene->r.raytrace_structure;
bkr.octree_resolution = scene->r.ocres;
bkr.threads = BKE_scene_num_threads(scene);
+ bkr.user_scale = (scene->r.bake_flag & R_BAKE_USERSCALE) ? scene->r.bake_user_scale : -1.0f;
+ //bkr.reports= op->reports;
/* create low-resolution DM (to bake to) and hi-resolution DM (to bake from) */
bkr.hires_dm = multiresbake_create_hiresdm(scene, ob, &bkr.tot_lvl, &bkr.simple);
@@ -380,6 +420,8 @@ static void init_multiresbake_job(bContext *C, MultiresBakeJob *bkj)
bkj->raytrace_structure = scene->r.raytrace_structure;
bkj->octree_resolution = scene->r.ocres;
bkj->threads = BKE_scene_num_threads(scene);
+ bkj->user_scale = (scene->r.bake_flag & R_BAKE_USERSCALE) ? scene->r.bake_user_scale : -1.0f;
+ //bkj->reports = op->reports;
CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
{
@@ -414,11 +456,16 @@ static void multiresbake_startjob(void *bkv, short *stop, short *do_update, floa
for (data = bkj->data.first; data; data = data->next) {
DerivedMesh *dm = data->lores_dm;
MTFace *mtface = CustomData_get_layer(&dm->faceData, CD_MTFACE);
+ ClearFlag clear_flag = 0;
+
+ if (bkj->mode == RE_BAKE_NORMALS) {
+ clear_flag = CLEAR_TANGENT_NORMAL;
+ }
+ else if (ELEM(bkj->mode, RE_BAKE_DISPLACEMENT, RE_BAKE_DERIVATIVE)) {
+ clear_flag = CLEAR_DISPLACEMENT;
+ }
- if (bkj->mode == RE_BAKE_NORMALS)
- clear_images(mtface, dm->getNumTessFaces(dm), CLEAR_NORMAL);
- else
- clear_images(mtface, dm->getNumTessFaces(dm), 0);
+ clear_images(mtface, dm->getNumTessFaces(dm), clear_flag);
}
}
@@ -429,6 +476,8 @@ static void multiresbake_startjob(void *bkv, short *stop, short *do_update, floa
bkr.bake_filter = bkj->bake_filter;
bkr.mode = bkj->mode;
bkr.use_lores_mesh = bkj->use_lores_mesh;
+ bkr.user_scale = bkj->user_scale;
+ //bkr.reports = bkj->reports;
/* create low-resolution DM (to bake to) and hi-resolution DM (to bake from) */
bkr.lores_dm = data->lores_dm;
@@ -734,7 +783,7 @@ static int objects_bake_render_modal(bContext *C, wmOperator *UNUSED(op), const
static int is_multires_bake(Scene *scene)
{
- if (ELEM3(scene->r.bake_mode, RE_BAKE_NORMALS, RE_BAKE_DISPLACEMENT, RE_BAKE_AO))
+ if (ELEM4(scene->r.bake_mode, RE_BAKE_NORMALS, RE_BAKE_DISPLACEMENT, RE_BAKE_DERIVATIVE, RE_BAKE_AO))
return scene->r.bake_flag & R_BAKE_MULTIRES;
return 0;
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index 96144d13519..bd4c2e997fe 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -1471,12 +1471,14 @@ static EnumPropertyItem *object_mode_set_itemsf(bContext *C, PointerRNA *UNUSED(
ob = CTX_data_active_object(C);
if (ob) {
+ const bool use_mode_particle_edit = (ob->particlesystem.first != NULL) || (ob->soft != NULL) ||
+ (modifiers_findByType(ob, eModifierType_Cloth) != NULL);
while (input->identifier) {
if ((input->value == OB_MODE_EDIT && OB_TYPE_SUPPORT_EDITMODE(ob->type)) ||
(input->value == OB_MODE_POSE && (ob->type == OB_ARMATURE)) ||
- (input->value == OB_MODE_PARTICLE_EDIT && ob->particlesystem.first) ||
- ((input->value == OB_MODE_SCULPT || input->value == OB_MODE_VERTEX_PAINT ||
- input->value == OB_MODE_WEIGHT_PAINT || input->value == OB_MODE_TEXTURE_PAINT) && (ob->type == OB_MESH)) ||
+ (input->value == OB_MODE_PARTICLE_EDIT && use_mode_particle_edit) ||
+ (ELEM4(input->value, OB_MODE_SCULPT, OB_MODE_VERTEX_PAINT,
+ OB_MODE_WEIGHT_PAINT, OB_MODE_TEXTURE_PAINT) && (ob->type == OB_MESH)) ||
(input->value == OB_MODE_OBJECT))
{
RNA_enum_item_add(&item, &totitem, input);
diff --git a/source/blender/editors/object/object_group.c b/source/blender/editors/object/object_group.c
index 1f52346222c..a9fd3ce1288 100644
--- a/source/blender/editors/object/object_group.c
+++ b/source/blender/editors/object/object_group.c
@@ -289,7 +289,7 @@ void GROUP_OT_objects_remove_all(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Remove From All Groups";
- ot->description = "Remove selected objects from all groups or a selected group";
+ ot->description = "Remove selected objects from all groups";
ot->idname = "GROUP_OT_objects_remove_all";
/* api callbacks */
@@ -335,7 +335,7 @@ void GROUP_OT_objects_remove(wmOperatorType *ot)
/* identifiers */
ot->name = "Remove From Group";
- ot->description = "Remove selected objects from all groups or a selected group";
+ ot->description = "Remove selected objects from a group";
ot->idname = "GROUP_OT_objects_remove";
/* api callbacks */
diff --git a/source/blender/editors/object/object_hook.c b/source/blender/editors/object/object_hook.c
index 5b20489c9cb..37656f82b25 100644
--- a/source/blender/editors/object/object_hook.c
+++ b/source/blender/editors/object/object_hook.c
@@ -569,7 +569,7 @@ void OBJECT_OT_hook_add_selob(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Hook to Selected Object";
- ot->description = "Hook selected vertices to the first selected Object";
+ ot->description = "Hook selected vertices to the first selected object";
ot->idname = "OBJECT_OT_hook_add_selob";
/* api callbacks */
@@ -603,7 +603,7 @@ void OBJECT_OT_hook_add_newob(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Hook to New Object";
- ot->description = "Hook selected vertices to the first selected Object";
+ ot->description = "Hook selected vertices to a newly created object";
ot->idname = "OBJECT_OT_hook_add_newob";
/* api callbacks */
diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c
index 917f816d6b1..d6c365e9247 100644
--- a/source/blender/editors/object/object_vgroup.c
+++ b/source/blender/editors/object/object_vgroup.c
@@ -47,6 +47,7 @@
#include "DNA_scene_types.h"
#include "DNA_particle_types.h"
+#include "BLI_alloca.h"
#include "BLI_array.h"
#include "BLI_math.h"
#include "BLI_blenlib.h"
@@ -1480,7 +1481,7 @@ bool *ED_vgroup_subset_from_select_type(Object *ob, eVGroupSelect subset_type, i
const int def_nr_active = ob->actdef - 1;
vgroup_validmap = MEM_mallocN(*r_vgroup_tot * sizeof(*vgroup_validmap), __func__);
memset(vgroup_validmap, false, *r_vgroup_tot * sizeof(*vgroup_validmap));
- if (def_nr_active < *r_vgroup_tot) {
+ if ((def_nr_active >= 0) && (def_nr_active < *r_vgroup_tot)) {
*r_subset_count = 1;
vgroup_validmap[def_nr_active] = true;
}
@@ -2000,7 +2001,11 @@ static void vgroup_levels_subset(Object *ob, const bool *vgroup_validmap, const
}
}
-static void vgroup_normalize_all(Object *ob, const bool lock_active)
+static void vgroup_normalize_all(Object *ob,
+ const bool *vgroup_validmap,
+ const int vgroup_tot,
+ const int subset_count,
+ const bool lock_active)
{
MDeformVert *dv, **dvert_array = NULL;
int i, dvert_tot = 0;
@@ -2008,7 +2013,7 @@ static void vgroup_normalize_all(Object *ob, const bool lock_active)
const int use_vert_sel = vertex_group_use_vert_sel(ob);
- if (lock_active && !BLI_findlink(&ob->defbase, def_nr)) {
+ if ((lock_active && !BLI_findlink(&ob->defbase, def_nr)) || subset_count == 0) {
return;
}
@@ -2029,13 +2034,15 @@ static void vgroup_normalize_all(Object *ob, const bool lock_active)
/* in case its not selected */
if ((dv = dvert_array[i])) {
if (lock_flags) {
- defvert_normalize_lock_map(dv, lock_flags, defbase_tot);
+ defvert_normalize_lock_map(dv, vgroup_validmap, vgroup_tot,
+ lock_flags, defbase_tot);
}
else if (lock_active) {
- defvert_normalize_lock_single(dv, def_nr);
+ defvert_normalize_lock_single(dv, vgroup_validmap, vgroup_tot,
+ def_nr);
}
else {
- defvert_normalize(dv);
+ defvert_normalize_subset(dv, vgroup_validmap, vgroup_tot);
}
}
}
@@ -2262,7 +2269,8 @@ static void vgroup_blend_subset(Object *ob, const bool *vgroup_validmap, const i
MEM_freeN(emap_mem);
}
- MEM_freeN(dvert_array);
+ if (dvert_array)
+ MEM_freeN(dvert_array);
BLI_SMALLSTACK_FREE(dv_stack);
/* not so efficient to get 'dvert_array' again just so unselected verts are NULL'd */
@@ -2270,7 +2278,8 @@ static void vgroup_blend_subset(Object *ob, const bool *vgroup_validmap, const i
ED_vgroup_parray_alloc(ob->data, &dvert_array, &dvert_tot, true);
ED_vgroup_parray_mirror_sync(ob, dvert_array, dvert_tot,
vgroup_validmap, vgroup_tot);
- MEM_freeN(dvert_array);
+ if (dvert_array)
+ MEM_freeN(dvert_array);
}
}
@@ -3471,8 +3480,13 @@ static int vertex_group_normalize_all_exec(bContext *C, wmOperator *op)
{
Object *ob = ED_object_context(C);
bool lock_active = RNA_boolean_get(op->ptr, "lock_active");
+ eVGroupSelect subset_type = RNA_enum_get(op->ptr, "group_select_mode");
- vgroup_normalize_all(ob, lock_active);
+ int subset_count, vgroup_tot;
+
+ const bool *vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count);
+ vgroup_normalize_all(ob, vgroup_validmap, vgroup_tot, subset_count, lock_active);
+ MEM_freeN((void *)vgroup_validmap);
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
@@ -3496,6 +3510,7 @@ void OBJECT_OT_vertex_group_normalize_all(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ vgroup_operator_subset_select_props(ot, false);
RNA_def_boolean(ot->srna, "lock_active", true, "Lock Active",
"Keep the values of the active group while normalizing others");
}
diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c
index 1a561efd217..b0e19d04e35 100644
--- a/source/blender/editors/physics/particle_edit.c
+++ b/source/blender/editors/physics/particle_edit.c
@@ -4421,7 +4421,7 @@ static int clear_edited_exec(bContext *C, wmOperator *UNUSED(op))
ParticleSystem *psys = psys_get_current(ob);
if (psys->edit) {
- if (psys->edit->edited || 1) { // XXX okee("Lose changes done in particle mode?"))
+ if (psys->edit->edited || 1) {
PE_free_ptcache_edit(psys->edit);
psys->edit = NULL;
@@ -4447,6 +4447,11 @@ static int clear_edited_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
+static int clear_edited_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+{
+ return WM_operator_confirm_message(C, op, "Lose changes done in particle mode? (no undo)");
+}
+
void PARTICLE_OT_edited_clear(wmOperatorType *ot)
{
/* identifiers */
@@ -4457,6 +4462,7 @@ void PARTICLE_OT_edited_clear(wmOperatorType *ot)
/* api callbacks */
ot->exec = clear_edited_exec;
ot->poll = particle_edit_toggle_poll;
+ ot->invoke = clear_edited_invoke;
/* flags */
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c
index 0f83316edca..df8d5ec4e84 100644
--- a/source/blender/editors/render/render_internal.c
+++ b/source/blender/editors/render/render_internal.c
@@ -564,6 +564,17 @@ static int screen_render_modal(bContext *C, wmOperator *op, const wmEvent *event
return OPERATOR_PASS_THROUGH;
}
+static int screen_render_cancel(bContext *C, wmOperator *op)
+{
+ wmWindowManager *wm = CTX_wm_manager(C);
+ Scene *scene = (Scene *) op->customdata;
+
+ /* kill on cancel, because job is using op->reports */
+ WM_jobs_kill_type(wm, scene, WM_JOB_TYPE_RENDER);
+
+ return OPERATOR_CANCELLED;
+}
+
/* using context, starts job */
static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
@@ -732,6 +743,7 @@ void RENDER_OT_render(wmOperatorType *ot)
/* api callbacks */
ot->invoke = screen_render_invoke;
ot->modal = screen_render_modal;
+ ot->cancel = screen_render_cancel;
ot->exec = screen_render_exec;
/*ot->poll = ED_operator_screenactive;*/ /* this isn't needed, causes failer in background mode */
@@ -1140,7 +1152,7 @@ void render_view3d_draw(RenderEngine *engine, const bContext *C)
/* Try using GLSL display transform. */
if (force_fallback == false) {
- if (IMB_colormanagement_setup_glsl_draw(NULL, &scene->display_settings, true, false)) {
+ if (IMB_colormanagement_setup_glsl_draw(&scene->view_settings, &scene->display_settings, true)) {
glEnable(GL_BLEND);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glaDrawPixelsTex(rres.xof, rres.yof, rres.rectx, rres.recty, GL_RGBA, GL_FLOAT,
@@ -1158,7 +1170,7 @@ void render_view3d_draw(RenderEngine *engine, const bContext *C)
"render_view3d_draw");
IMB_colormanagement_buffer_make_display_space(rres.rectf, display_buffer, rres.rectx, rres.recty,
- 4, dither, NULL, &scene->display_settings);
+ 4, dither, &scene->view_settings, &scene->display_settings);
glEnable(GL_BLEND);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c
index cdebbf4e103..21074bdc47c 100644
--- a/source/blender/editors/render/render_opengl.c
+++ b/source/blender/editors/render/render_opengl.c
@@ -517,7 +517,7 @@ static int screen_opengl_render_anim_initialize(bContext *C, wmOperator *op)
return 1;
}
-static int screen_opengl_render_anim_step(bContext *C, wmOperator *op)
+static bool screen_opengl_render_anim_step(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
OGLRender *oglrender = op->customdata;
@@ -549,12 +549,9 @@ static int screen_opengl_render_anim_step(bContext *C, wmOperator *op)
BKE_makepicstring(name, scene->r.pic, oglrender->bmain->name, scene->r.cfra, &scene->r.im_format, scene->r.scemode & R_EXTENSION, TRUE);
if ((scene->r.mode & R_NO_OVERWRITE) && BLI_exists(name)) {
- printf("skipping existing frame \"%s\"\n", name);
-
- /* go to next frame */
- oglrender->nfra += scene->r.frame_step;
-
- return 1;
+ BKE_reportf(op->reports, RPT_INFO, "Skipping existing frame \"%s\"", name);
+ ok = true;
+ goto finally;
}
}
@@ -656,6 +653,9 @@ static int screen_opengl_render_anim_step(bContext *C, wmOperator *op)
/* movie stats prints have no line break */
printf("\n");
+
+finally: /* Step the frame and bail early if needed */
+
/* go to next frame */
oglrender->nfra += scene->r.frame_step;
@@ -673,7 +673,7 @@ static int screen_opengl_render_modal(bContext *C, wmOperator *op, const wmEvent
{
OGLRender *oglrender = op->customdata;
int anim = RNA_boolean_get(op->ptr, "animation");
- int ret;
+ bool ret;
switch (event->type) {
case ESCKEY:
@@ -698,11 +698,12 @@ static int screen_opengl_render_modal(bContext *C, wmOperator *op, const wmEvent
screen_opengl_render_end(C, op->customdata);
return OPERATOR_FINISHED;
}
- else
+ else {
ret = screen_opengl_render_anim_step(C, op);
+ }
/* stop at the end or on error */
- if (ret == 0) {
+ if (ret == false) {
return OPERATOR_FINISHED;
}
@@ -750,7 +751,7 @@ static int screen_opengl_render_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
else {
- int ret = 1;
+ bool ret = true;
if (!screen_opengl_render_anim_initialize(C, op))
return OPERATOR_CANCELLED;
diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c
index 58c244228ed..553a543390f 100644
--- a/source/blender/editors/render/render_shading.c
+++ b/source/blender/editors/render/render_shading.c
@@ -588,6 +588,20 @@ void SCENE_OT_render_layer_remove(wmOperatorType *ot)
#ifdef WITH_FREESTYLE
+static bool freestyle_linestyle_check_report(FreestyleLineSet *lineset, ReportList *reports)
+{
+ if (!lineset) {
+ BKE_report(reports, RPT_ERROR, "No active lineset and associated line style to add the modifier to");
+ return false;
+ }
+ if (!lineset->linestyle) {
+ BKE_report(reports, RPT_ERROR, "The active lineset does not have a line style (indicating data corruption)");
+ return false;
+ }
+
+ return true;
+}
+
static int freestyle_active_module_poll(bContext *C)
{
PointerRNA ptr = CTX_data_pointer_get_type(C, "freestyle_module", &RNA_FreestyleModuleSettings);
@@ -860,8 +874,13 @@ static int freestyle_linestyle_new_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_ERROR, "No active lineset to add a new line style to");
return OPERATOR_CANCELLED;
}
- lineset->linestyle->id.us--;
- lineset->linestyle = BKE_copy_linestyle(lineset->linestyle);
+ if (lineset->linestyle) {
+ lineset->linestyle->id.us--;
+ lineset->linestyle = BKE_copy_linestyle(lineset->linestyle);
+ }
+ else {
+ lineset->linestyle = BKE_new_linestyle("LineStyle", NULL);
+ }
WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
@@ -890,10 +909,10 @@ static int freestyle_color_modifier_add_exec(bContext *C, wmOperator *op)
FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&srl->freestyleConfig);
int type = RNA_enum_get(op->ptr, "type");
- if (!lineset) {
- BKE_report(op->reports, RPT_ERROR, "No active lineset and associated line style to add the modifier to");
+ if (!freestyle_linestyle_check_report(lineset, op->reports)) {
return OPERATOR_CANCELLED;
}
+
if (BKE_add_linestyle_color_modifier(lineset->linestyle, type) == NULL) {
BKE_report(op->reports, RPT_ERROR, "Unknown line color modifier type");
return OPERATOR_CANCELLED;
@@ -929,10 +948,10 @@ static int freestyle_alpha_modifier_add_exec(bContext *C, wmOperator *op)
FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&srl->freestyleConfig);
int type = RNA_enum_get(op->ptr, "type");
- if (!lineset) {
- BKE_report(op->reports, RPT_ERROR, "No active lineset and associated line style to add the modifier to");
+ if (!freestyle_linestyle_check_report(lineset, op->reports)) {
return OPERATOR_CANCELLED;
}
+
if (BKE_add_linestyle_alpha_modifier(lineset->linestyle, type) == NULL) {
BKE_report(op->reports, RPT_ERROR, "Unknown alpha transparency modifier type");
return OPERATOR_CANCELLED;
@@ -968,10 +987,10 @@ static int freestyle_thickness_modifier_add_exec(bContext *C, wmOperator *op)
FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&srl->freestyleConfig);
int type = RNA_enum_get(op->ptr, "type");
- if (!lineset) {
- BKE_report(op->reports, RPT_ERROR, "No active lineset and associated line style to add the modifier to");
+ if (!freestyle_linestyle_check_report(lineset, op->reports)) {
return OPERATOR_CANCELLED;
}
+
if (BKE_add_linestyle_thickness_modifier(lineset->linestyle, type) == NULL) {
BKE_report(op->reports, RPT_ERROR, "Unknown line thickness modifier type");
return OPERATOR_CANCELLED;
@@ -1007,10 +1026,10 @@ static int freestyle_geometry_modifier_add_exec(bContext *C, wmOperator *op)
FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&srl->freestyleConfig);
int type = RNA_enum_get(op->ptr, "type");
- if (!lineset) {
- BKE_report(op->reports, RPT_ERROR, "No active lineset and associated line style to add the modifier to");
+ if (!freestyle_linestyle_check_report(lineset, op->reports)) {
return OPERATOR_CANCELLED;
}
+
if (BKE_add_linestyle_geometry_modifier(lineset->linestyle, type) == NULL) {
BKE_report(op->reports, RPT_ERROR, "Unknown stroke geometry modifier type");
return OPERATOR_CANCELLED;
@@ -1060,8 +1079,7 @@ static int freestyle_modifier_remove_exec(bContext *C, wmOperator *op)
PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_LineStyleModifier);
LineStyleModifier *modifier = ptr.data;
- if (!lineset) {
- BKE_report(op->reports, RPT_ERROR, "No active lineset and associated line style the modifier belongs to");
+ if (!freestyle_linestyle_check_report(lineset, op->reports)) {
return OPERATOR_CANCELLED;
}
@@ -1110,8 +1128,7 @@ static int freestyle_modifier_copy_exec(bContext *C, wmOperator *op)
PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_LineStyleModifier);
LineStyleModifier *modifier = ptr.data;
- if (!lineset) {
- BKE_report(op->reports, RPT_ERROR, "No active lineset and associated line style the modifier belongs to");
+ if (!freestyle_linestyle_check_report(lineset, op->reports)) {
return OPERATOR_CANCELLED;
}
@@ -1161,8 +1178,7 @@ static int freestyle_modifier_move_exec(bContext *C, wmOperator *op)
LineStyleModifier *modifier = ptr.data;
int dir = RNA_enum_get(op->ptr, "direction");
- if (!lineset) {
- BKE_report(op->reports, RPT_ERROR, "No active lineset and associated line style the modifier belongs to");
+ if (!freestyle_linestyle_check_report(lineset, op->reports)) {
return OPERATOR_CANCELLED;
}
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index 91d1985cd00..fccce0357a4 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -1446,7 +1446,6 @@ void ED_area_newspace(bContext *C, ScrArea *sa, int type)
}
if (sl) {
-
/* swap regions */
slold->regionbase = sa->regionbase;
sa->regionbase = sl->regionbase;
diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c
index 13befeceee9..d356c3d8de3 100644
--- a/source/blender/editors/screen/glutil.c
+++ b/source/blender/editors/screen/glutil.c
@@ -531,7 +531,7 @@ void glaDrawPixelsTexScaled(float x, float y, int img_w, int img_h, int format,
components = 4;
else if (format == GL_RGB)
components = 3;
- else if (format == GL_LUMINANCE)
+ else if (ELEM(format, GL_LUMINANCE, GL_ALPHA))
components = 1;
else {
BLI_assert(!"Incompatible format passed to glaDrawPixelsTexScaled");
@@ -1091,18 +1091,15 @@ void glaDrawImBuf_glsl(ImBuf *ibuf, float x, float y, int zoomfilter,
if (ibuf->rect_float) {
if (ibuf->float_colorspace) {
ok = IMB_colormanagement_setup_glsl_draw_from_space(view_settings, display_settings,
- ibuf->float_colorspace,
- true, false);
+ ibuf->float_colorspace, true);
}
else {
- ok = IMB_colormanagement_setup_glsl_draw(view_settings, display_settings,
- true, false);
+ ok = IMB_colormanagement_setup_glsl_draw(view_settings, display_settings, true);
}
}
else {
ok = IMB_colormanagement_setup_glsl_draw_from_space(view_settings, display_settings,
- ibuf->rect_colorspace,
- false, false);
+ ibuf->rect_colorspace, false);
}
if (ok) {
@@ -1160,57 +1157,3 @@ void glaDrawImBuf_glsl_ctx(const bContext *C, ImBuf *ibuf, float x, float y, int
glaDrawImBuf_glsl(ibuf, x, y, zoomfilter, view_settings, display_settings);
}
-
-/* Transform buffer from role to scene linear space using GLSL OCIO conversion
- *
- * See IMB_colormanagement_setup_transform_from_role_glsl description for
- * some more details
- *
- * NOTE: this only works for RGBA buffers!
- */
-int glaBufferTransformFromRole_glsl(float *buffer, int width, int height, int role)
-{
- GPUOffScreen *ofs;
- char err_out[256];
- rcti display_rect;
-
- ofs = GPU_offscreen_create(width, height, err_out);
-
- if (!ofs)
- return FALSE;
-
- GPU_offscreen_bind(ofs);
-
- if (!IMB_colormanagement_setup_transform_from_role_glsl(role, true)) {
- GPU_offscreen_unbind(ofs);
- GPU_offscreen_free(ofs);
- return FALSE;
- }
-
- BLI_rcti_init(&display_rect, 0, width, 0, height);
-
- glMatrixMode(GL_PROJECTION);
- glPushMatrix();
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
-
- glaDefine2DArea(&display_rect);
-
- glaDrawPixelsTex(0, 0, width, height, GL_RGBA, GL_FLOAT,
- GL_NEAREST, buffer);
-
- glMatrixMode(GL_PROJECTION);
- glPopMatrix();
- glMatrixMode(GL_MODELVIEW);
- glPopMatrix();
-
- GPU_offscreen_read_pixels(ofs, GL_FLOAT, buffer);
-
- IMB_colormanagement_finish_glsl_transform();
-
- /* unbind */
- GPU_offscreen_unbind(ofs);
- GPU_offscreen_free(ofs);
-
- return TRUE;
-}
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c
index 10c2ecd6fd9..356db174c2f 100644
--- a/source/blender/editors/screen/screen_edit.c
+++ b/source/blender/editors/screen/screen_edit.c
@@ -1009,8 +1009,6 @@ void ED_screen_do_listen(bContext *C, wmNotifier *note)
win->screen->do_draw = TRUE;
break;
case NC_SCREEN:
- if (note->data == ND_SUBWINACTIVE)
- uiFreeActiveButtons(C, win->screen);
if (note->action == NA_EDITED)
win->screen->do_draw = win->screen->do_refresh = TRUE;
break;
@@ -1335,7 +1333,11 @@ void ED_screen_set_subwinactive(bContext *C, wmEvent *event)
/* notifier invokes freeing the buttons... causing a bit too much redraws */
if (oldswin != scr->subwinactive) {
region_cursor_set(win, scr->subwinactive, TRUE);
- WM_event_add_notifier(C, NC_SCREEN | ND_SUBWINACTIVE, scr);
+
+ /* this used to be a notifier, but needs to be done immediate
+ * because it can undo setting the right button as active due
+ * to delayed notifier handling */
+ uiFreeActiveButtons(C, win->screen);
}
else
region_cursor_set(win, scr->subwinactive, FALSE);
diff --git a/source/blender/editors/screen/screendump.c b/source/blender/editors/screen/screendump.c
index 584d4cef133..dbe1197436b 100644
--- a/source/blender/editors/screen/screendump.c
+++ b/source/blender/editors/screen/screendump.c
@@ -77,6 +77,18 @@ typedef struct ScreenshotData {
ImageFormatData im_format;
} ScreenshotData;
+static void screenshot_read_pixels(int x, int y, int w, int h, unsigned char *rect)
+{
+ int i;
+
+ glReadPixels(x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, rect);
+ glFinish();
+
+ /* clear alpha, it is not set to a meaningful value in opengl */
+ for (i = 0, rect += 3; i < w * h; i++, rect += 4)
+ *rect = 255;
+}
+
/* get shot from frontbuffer */
static unsigned int *screenshot(bContext *C, int *dumpsx, int *dumpsy)
{
@@ -93,8 +105,7 @@ static unsigned int *screenshot(bContext *C, int *dumpsx, int *dumpsy)
dumprect = MEM_mallocN(sizeof(int) * (*dumpsx) * (*dumpsy), "dumprect");
glReadBuffer(GL_FRONT);
- glReadPixels(x, y, *dumpsx, *dumpsy, GL_RGBA, GL_UNSIGNED_BYTE, dumprect);
- glFinish();
+ screenshot_read_pixels(x, y, *dumpsx, *dumpsy, (unsigned char*)dumprect);
glReadBuffer(GL_BACK);
}
@@ -316,8 +327,7 @@ static void screenshot_updatejob(void *sjv)
if (sj->dumprect == NULL) {
dumprect = MEM_mallocN(sizeof(int) * sj->dumpsx * sj->dumpsy, "dumprect");
- glReadPixels(sj->x, sj->y, sj->dumpsx, sj->dumpsy, GL_RGBA, GL_UNSIGNED_BYTE, dumprect);
- glFinish();
+ screenshot_read_pixels(sj->x, sj->y, sj->dumpsx, sj->dumpsy, (unsigned char *)dumprect);
sj->dumprect = dumprect;
}
diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c
index c18afd066fa..56143d00afe 100644
--- a/source/blender/editors/sculpt_paint/paint_cursor.c
+++ b/source/blender/editors/sculpt_paint/paint_cursor.c
@@ -73,12 +73,38 @@ typedef struct TexSnapshot {
GLuint overlay_texture;
int winx;
int winy;
- bool init;
int old_size;
float old_zoom;
bool old_col;
} TexSnapshot;
+typedef struct CursorSnapshot {
+ GLuint overlay_texture;
+ int size;
+ int zoom;
+} CursorSnapshot;
+
+static TexSnapshot primary_snap = {0};
+static TexSnapshot secondary_snap = {0};
+static CursorSnapshot cursor_snap = {0};
+
+/* delete overlay cursor textures to preserve memory and invalidate all overlay flags */
+void paint_cursor_delete_textures(void)
+{
+ if (primary_snap.overlay_texture)
+ glDeleteTextures(1, &primary_snap.overlay_texture);
+ if (secondary_snap.overlay_texture)
+ glDeleteTextures(1, &secondary_snap.overlay_texture);
+ if (cursor_snap.overlay_texture)
+ glDeleteTextures(1, &cursor_snap.overlay_texture);
+
+ memset(&primary_snap, 0, sizeof(TexSnapshot));
+ memset(&secondary_snap, 0, sizeof(TexSnapshot));
+ memset(&cursor_snap, 0, sizeof(CursorSnapshot));
+
+ BKE_paint_invalidate_overlay_all();
+}
+
static int same_tex_snap(TexSnapshot *snap, MTex *mtex, ViewContext *vc, bool col, float zoom)
{
return (/* make brush smaller shouldn't cause a resample */
@@ -103,9 +129,7 @@ static void make_tex_snap(TexSnapshot *snap, ViewContext *vc, float zoom)
static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool primary)
{
- static int init = 0;
- static TexSnapshot primary_snap = {0};
- static TexSnapshot secondary_snap = {0};
+ bool init;
TexSnapshot *target;
MTex *mtex = (primary) ? &br->mtex : &br->mask_mtex;
@@ -120,12 +144,14 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool prima
(overlay_flags & PAINT_INVALID_OVERLAY_TEXTURE_SECONDARY);
target = (primary) ? &primary_snap : &secondary_snap;
-
+
refresh =
!target->overlay_texture ||
(invalid != 0) ||
!same_tex_snap(target, mtex, vc, col, zoom);
+ init = (target->overlay_texture != 0);
+
if (refresh) {
struct ImagePool *pool = NULL;
/* stencil is rotated later */
@@ -160,7 +186,7 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool prima
target->overlay_texture = 0;
}
- init = 0;
+ init = false;
target->old_size = size;
}
@@ -267,7 +293,6 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool prima
if (refresh) {
if (!init || (target->old_col != col)) {
glTexImage2D(GL_TEXTURE_2D, 0, format, size, size, 0, format, GL_UNSIGNED_BYTE, buffer);
- init = 1;
}
else {
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, size, size, format, GL_UNSIGNED_BYTE, buffer);
@@ -297,10 +322,7 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool prima
static int load_tex_cursor(Brush *br, ViewContext *vc, float zoom)
{
- static GLuint overlay_texture = 0;
- static int init = 0;
- static int old_size = -1;
- static int old_zoom = -1;
+ bool init;
OverlayControlFlags overlay_flags = BKE_paint_get_overlay_flags();
GLubyte *buffer = NULL;
@@ -310,14 +332,16 @@ static int load_tex_cursor(Brush *br, ViewContext *vc, float zoom)
int refresh;
refresh =
- !overlay_texture ||
+ !cursor_snap.overlay_texture ||
(overlay_flags & PAINT_INVALID_OVERLAY_CURVE) ||
- old_zoom != zoom;
+ cursor_snap.zoom != zoom;
+
+ init = (cursor_snap.overlay_texture != 0);
if (refresh) {
int s, r;
- old_zoom = zoom;
+ cursor_snap.zoom = zoom;
s = BKE_brush_size_get(vc->scene, br);
r = 1;
@@ -330,18 +354,18 @@ static int load_tex_cursor(Brush *br, ViewContext *vc, float zoom)
if (size < 256)
size = 256;
- if (size < old_size)
- size = old_size;
+ if (size < cursor_snap.size)
+ size = cursor_snap.size;
- if (old_size != size) {
- if (overlay_texture) {
- glDeleteTextures(1, &overlay_texture);
- overlay_texture = 0;
+ if (cursor_snap.size != size) {
+ if (cursor_snap.overlay_texture) {
+ glDeleteTextures(1, &cursor_snap.overlay_texture);
+ cursor_snap.overlay_texture = 0;
}
- init = 0;
+ init = false;
- old_size = size;
+ cursor_snap.size = size;
}
buffer = MEM_mallocN(sizeof(GLubyte) * size * size, "load_tex");
@@ -383,19 +407,18 @@ static int load_tex_cursor(Brush *br, ViewContext *vc, float zoom)
}
}
- if (!overlay_texture)
- glGenTextures(1, &overlay_texture);
+ if (!cursor_snap.overlay_texture)
+ glGenTextures(1, &cursor_snap.overlay_texture);
}
else {
- size = old_size;
+ size = cursor_snap.size;
}
- glBindTexture(GL_TEXTURE_2D, overlay_texture);
+ glBindTexture(GL_TEXTURE_2D, cursor_snap.overlay_texture);
if (refresh) {
if (!init) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, size, size, 0, GL_ALPHA, GL_UNSIGNED_BYTE, buffer);
- init = 1;
}
else {
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, size, size, GL_ALPHA, GL_UNSIGNED_BYTE, buffer);
diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c
index feff02fa121..a5d4ff98b4b 100644
--- a/source/blender/editors/sculpt_paint/paint_image.c
+++ b/source/blender/editors/sculpt_paint/paint_image.c
@@ -792,6 +792,7 @@ static void toggle_paint_cursor(bContext *C, int enable)
if (settings->imapaint.paintcursor && !enable) {
WM_paint_cursor_end(wm, settings->imapaint.paintcursor);
settings->imapaint.paintcursor = NULL;
+ paint_cursor_delete_textures();
}
else if (enable)
paint_cursor_start(C, image_paint_poll);
@@ -820,6 +821,9 @@ void ED_space_image_paint_update(wmWindowManager *wm, ToolSettings *settings)
paint_cursor_start_explicit(&imapaint->paint, wm, image_paint_poll);
}
+ else {
+ paint_cursor_delete_textures();
+ }
}
/************************ grab clone operator ************************/
@@ -922,9 +926,15 @@ void PAINT_OT_grab_clone(wmOperatorType *ot)
}
/******************** sample color operator ********************/
+typedef struct {
+ bool show_cursor;
+ short event_type;
+} SampleColorData;
+
static int sample_color_exec(bContext *C, wmOperator *op)
{
- Brush *brush = image_paint_brush(C);
+ Paint *paint = BKE_paint_get_active_from_context(C);
+ Brush *brush = BKE_paint_brush(paint);
ARegion *ar = CTX_wm_region(C);
int location[2];
@@ -938,11 +948,17 @@ static int sample_color_exec(bContext *C, wmOperator *op)
static int sample_color_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
+ Paint *paint = BKE_paint_get_active_from_context(C);
+ SampleColorData *data = MEM_mallocN(sizeof(SampleColorData), "sample color custom data");
+
+ data->event_type = event->type;
+ data->show_cursor = ((paint->flags & PAINT_SHOW_BRUSH) != 0);
+ op->customdata = data;
+ paint->flags &= ~PAINT_SHOW_BRUSH;
+
RNA_int_set_array(op->ptr, "location", event->mval);
sample_color_exec(C, op);
- op->customdata = SET_INT_IN_POINTER(event->type);
-
WM_event_add_modal_handler(C, op);
return OPERATOR_RUNNING_MODAL;
@@ -950,8 +966,18 @@ static int sample_color_invoke(bContext *C, wmOperator *op, const wmEvent *event
static int sample_color_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
- if (event->type == (intptr_t)(op->customdata) && event->val == KM_RELEASE)
+ SampleColorData *data = op->customdata;
+
+ if ((event->type == data->event_type) && (event->val == KM_RELEASE)) {
+ Paint *paint = BKE_paint_get_active_from_context(C);
+
+ if(data->show_cursor) {
+ paint->flags |= PAINT_SHOW_BRUSH;
+ }
+
+ MEM_freeN(data);
return OPERATOR_FINISHED;
+ }
switch (event->type) {
case MOUSEMOVE:
@@ -963,24 +989,9 @@ static int sample_color_modal(bContext *C, wmOperator *op, const wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
-/* same as image_paint_poll but fail when face mask mode is enabled */
-static int image_paint_sample_color_poll(bContext *C)
+static int sample_color_poll(bContext *C)
{
- if (image_paint_poll(C)) {
- if (CTX_wm_view3d(C)) {
- Object *obact = CTX_data_active_object(C);
- if (obact && obact->mode & OB_MODE_TEXTURE_PAINT) {
- Mesh *me = BKE_mesh_from_object(obact);
- if (me) {
- return !(me->editflag & ME_EDIT_PAINT_FACE_SEL);
- }
- }
- }
-
- return 1;
- }
-
- return 0;
+ return (image_paint_poll(C) || vertex_paint_poll(C));
}
void PAINT_OT_sample_color(wmOperatorType *ot)
@@ -994,7 +1005,7 @@ void PAINT_OT_sample_color(wmOperatorType *ot)
ot->exec = sample_color_exec;
ot->invoke = sample_color_invoke;
ot->modal = sample_color_modal;
- ot->poll = image_paint_sample_color_poll;
+ ot->poll = sample_color_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c
index c90f9756707..4a2046f6682 100644
--- a/source/blender/editors/sculpt_paint/paint_image_proj.c
+++ b/source/blender/editors/sculpt_paint/paint_image_proj.c
@@ -3129,7 +3129,7 @@ static void project_paint_begin(ProjPaintState *ps)
ps->thread_tot = 1;
for (a = 0; a < ps->thread_tot; a++) {
- ps->arena_mt[a] = BLI_memarena_new(1 << 16, "project paint arena");
+ ps->arena_mt[a] = BLI_memarena_new(MEM_SIZE_OPTIMAL(1 << 16), "project paint arena");
}
arena = ps->arena_mt[0];
@@ -3841,10 +3841,10 @@ static void *do_projectpaint_thread(void *ph_v)
pos_ofs[0] = pos[0] - lastpos[0];
pos_ofs[1] = pos[1] - lastpos[1];
- smearArena = BLI_memarena_new(1 << 16, "paint smear arena");
+ smearArena = BLI_memarena_new(MEM_SIZE_OPTIMAL(1 << 16), "paint smear arena");
}
else if (tool == PAINT_TOOL_SOFTEN) {
- softenArena = BLI_memarena_new(1 << 16, "paint soften arena");
+ softenArena = BLI_memarena_new(MEM_SIZE_OPTIMAL(1 << 16), "paint soften arena");
}
/* printf("brush bounds %d %d %d %d\n", bucketMin[0], bucketMin[1], bucketMax[0], bucketMax[1]); */
diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h
index 6c13f6efb74..2545328ec65 100644
--- a/source/blender/editors/sculpt_paint/paint_intern.h
+++ b/source/blender/editors/sculpt_paint/paint_intern.h
@@ -74,6 +74,7 @@ bool paint_space_stroke_enabled(struct Brush *br, enum PaintMode mode);
bool paint_supports_dynamic_size(struct Brush *br, enum PaintMode mode);
bool paint_supports_dynamic_tex_coords(struct Brush *br, enum PaintMode mode);
bool paint_supports_smooth_stroke(struct Brush *br, enum PaintMode mode);
+bool paint_supports_texture(enum PaintMode mode);
bool paint_supports_jitter(enum PaintMode mode);
struct wmKeyMap *paint_stroke_modal_keymap(struct wmKeyConfig *keyconf);
@@ -86,6 +87,7 @@ void paint_stroke_set_mode_data(struct PaintStroke *stroke, void *mode_data);
int paint_poll(struct bContext *C);
void paint_cursor_start(struct bContext *C, int (*poll)(struct bContext *C));
void paint_cursor_start_explicit(struct Paint *p, struct wmWindowManager *wm, int (*poll)(struct bContext *C));
+void paint_cursor_delete_textures(void);
/* paint_vertex.c */
int weight_paint_poll(struct bContext *C);
diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c
index 0b0607babc1..8b038973831 100644
--- a/source/blender/editors/sculpt_paint/paint_ops.c
+++ b/source/blender/editors/sculpt_paint/paint_ops.c
@@ -728,9 +728,16 @@ static int stencil_control_modal(bContext *C, wmOperator *op, const wmEvent *eve
static int stencil_control_poll(bContext *C)
{
- Paint *paint = BKE_paint_get_active_from_context(C);
- Brush *br = BKE_paint_brush(paint);
+ PaintMode mode = BKE_paintmode_get_active_from_context(C);
+
+ Paint *paint;
+ Brush *br;
+
+ if (!paint_supports_texture(mode))
+ return false;
+ paint = BKE_paint_get_active_from_context(C);
+ br = BKE_paint_brush(paint);
return (br &&
(br->mtex.brush_map_mode == MTEX_MAP_MODE_STENCIL ||
br->mask_mtex.brush_map_mode == MTEX_MAP_MODE_STENCIL));
diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c
index 973f6555deb..b00b1c3ecff 100644
--- a/source/blender/editors/sculpt_paint/paint_stroke.c
+++ b/source/blender/editors/sculpt_paint/paint_stroke.c
@@ -572,6 +572,12 @@ bool paint_supports_smooth_stroke(Brush *br, PaintMode mode)
return true;
}
+bool paint_supports_texture(PaintMode mode)
+{
+ /* ommit: PAINT_WEIGHT, PAINT_SCULPT_UV, PAINT_INVALID */
+ return ELEM4(mode, PAINT_SCULPT, PAINT_VERTEX, PAINT_TEXTURE_PROJECTIVE, PAINT_TEXTURE_2D);
+}
+
/* return true if the brush size can change during paint (normally used for pressure) */
bool paint_supports_dynamic_tex_coords(Brush *br, PaintMode mode)
{
diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c
index d376bd3180f..bfc431baea5 100644
--- a/source/blender/editors/sculpt_paint/paint_utils.c
+++ b/source/blender/editors/sculpt_paint/paint_utils.c
@@ -441,7 +441,7 @@ static int paint_select_linked_pick_invoke(bContext *C, wmOperator *op, const wm
void PAINT_OT_face_select_linked_pick(wmOperatorType *ot)
{
ot->name = "Select Linked Pick";
- ot->description = "Select linked faces";
+ ot->description = "Select linked faces under the cursor";
ot->idname = "PAINT_OT_face_select_linked_pick";
ot->invoke = paint_select_linked_pick_invoke;
diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c
index 538e8394b1f..1c3caf5d8bc 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex.c
@@ -2062,6 +2062,8 @@ static int wpaint_mode_toggle_exec(bContext *C, wmOperator *op)
/* weight paint spesific */
mesh_octree_table(NULL, NULL, NULL, 'e');
mesh_mirrtopo_table(NULL, 'e');
+
+ paint_cursor_delete_textures();
}
else {
ob->mode |= mode_flag;
@@ -2684,6 +2686,8 @@ static int vpaint_mode_toggle_exec(bContext *C, wmOperator *op)
if (me->editflag & ME_EDIT_PAINT_FACE_SEL) {
BKE_mesh_flush_select_from_polys(me);
}
+
+ paint_cursor_delete_textures();
}
else {
ob->mode |= mode_flag;
@@ -2784,7 +2788,7 @@ static void vpaint_build_poly_facemap(struct VPaintData *vd, Mesh *me)
int *origIndex;
int i;
- vd->polyfacemap_arena = BLI_memarena_new(1 << 13, "vpaint tmp");
+ vd->polyfacemap_arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "vpaint tmp");
BLI_memarena_use_calloc(vd->polyfacemap_arena);
vd->polyfacemap = BLI_memarena_alloc(vd->polyfacemap_arena, sizeof(ListBase) * me->totpoly);
@@ -3480,7 +3484,7 @@ void PAINT_OT_weight_gradient(wmOperatorType *ot)
/* identifiers */
ot->name = "Weight Gradient";
ot->idname = "PAINT_OT_weight_gradient";
- ot->description = "Sample a line and show it in Scope panels";
+ ot->description = "Draw a line to apply a weight gradient to selected vertices";
/* api callbacks */
ot->invoke = paint_weight_gradient_invoke;
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index a557afcdf3d..2a6b6d4b3d9 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -3795,15 +3795,26 @@ static void sculpt_update_cache_invariants(bContext *C, Sculpt *sd, SculptSessio
Object *ob = CTX_data_active_object(C);
float mat[3][3];
float viewDir[3] = {0.0f, 0.0f, 1.0f};
+ float max_scale;
int i;
int mode;
ss->cache = cache;
/* Set scaling adjustment */
- cache->scale[0] = 1.0f / ob->size[0];
- cache->scale[1] = 1.0f / ob->size[1];
- cache->scale[2] = 1.0f / ob->size[2];
+ if (brush->sculpt_tool == SCULPT_TOOL_LAYER) {
+ max_scale = 1.0f;
+ }
+ else {
+ max_scale = 0.0f;
+ for (i = 0; i < 3; i ++) {
+ max_scale = max_ff(max_scale, fabsf(ob->size[i]));
+ }
+ }
+ cache->scale[0] = max_scale / ob->size[0];
+ cache->scale[1] = max_scale / ob->size[1];
+ cache->scale[2] = max_scale / ob->size[2];
+
cache->plane_trim_squared = brush->plane_trim * brush->plane_trim;
@@ -4677,10 +4688,7 @@ void sculpt_dynamic_topology_enable(bContext *C)
Object *ob = CTX_data_active_object(C);
SculptSession *ss = ob->sculpt;
Mesh *me = ob->data;
- const BMAllocTemplate allocsize = {me->totvert,
- me->totedge,
- me->totloop,
- me->totpoly};
+ const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(me);
sculpt_pbvh_clear(ob);
@@ -4931,7 +4939,7 @@ int ED_sculpt_mask_layers_ensure(Object *ob, MultiresModifierData *mmd)
if (mmd && !CustomData_has_layer(&me->ldata, CD_GRID_PAINT_MASK)) {
GridPaintMask *gmask;
int level = max_ii(1, mmd->sculptlvl);
- int gridsize = ccg_gridsize(level);
+ int gridsize = BKE_ccg_gridsize(level);
int gridarea = gridsize * gridsize;
int i, j;
@@ -5031,6 +5039,8 @@ static int sculpt_mode_toggle_exec(bContext *C, wmOperator *op)
ob->mode &= ~mode_flag;
free_sculptsession(ob);
+
+ paint_cursor_delete_textures();
}
else {
/* Enter sculptmode */
diff --git a/source/blender/editors/sculpt_paint/sculpt_uv.c b/source/blender/editors/sculpt_paint/sculpt_uv.c
index d630b6478fb..7a973d8c1ae 100644
--- a/source/blender/editors/sculpt_paint/sculpt_uv.c
+++ b/source/blender/editors/sculpt_paint/sculpt_uv.c
@@ -45,6 +45,7 @@
#include "BKE_brush.h"
#include "BKE_paint.h"
+#include "BKE_colortools.h"
#include "BKE_context.h"
#include "BKE_main.h"
#include "BKE_depsgraph.h"
@@ -538,6 +539,8 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm
op->customdata = data;
+ curvemapping_initialize(ts->uvsculpt->paint.brush->curve);
+
if (data) {
int counter = 0, i;
ARegion *ar = CTX_wm_region(C);
diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c
index 0d64a3ce594..f5db34d87d7 100644
--- a/source/blender/editors/space_clip/clip_editor.c
+++ b/source/blender/editors/space_clip/clip_editor.c
@@ -710,8 +710,14 @@ static unsigned char *prefetch_thread_next_frame(PrefetchQueue *queue, MovieClip
if (queue->direction > 0) {
current_frame = prefetch_find_uncached_frame(clip, queue->current_frame + 1, queue->end_frame,
queue->render_size, queue->render_flag, 1);
+ /* switch direction if read frames from current up to scene end frames */
+ if (current_frame >= queue->end_frame) {
+ queue->current_frame = queue->initial_frame;
+ queue->direction = -1;
+ }
}
- else {
+
+ if (queue->direction < 0) {
current_frame = prefetch_find_uncached_frame(clip, queue->current_frame - 1, queue->start_frame,
queue->render_size, queue->render_flag, -1);
}
@@ -736,12 +742,6 @@ static unsigned char *prefetch_thread_next_frame(PrefetchQueue *queue, MovieClip
*queue->do_update = 1;
*queue->progress = (float)frames_processed / (queue->end_frame - queue->start_frame);
-
- /* switch direction if read frames from current up to scene end frames */
- if (current_frame == queue->end_frame) {
- queue->current_frame = queue->initial_frame;
- queue->direction = -1;
- }
}
}
BLI_spin_unlock(&queue->spin);
diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c
index 3ede63adb72..adc902bf4ba 100644
--- a/source/blender/editors/space_clip/space_clip.c
+++ b/source/blender/editors/space_clip/space_clip.c
@@ -1191,7 +1191,9 @@ static void clip_main_area_draw(const bContext *C, ARegion *ar)
int mask_width, mask_height;
ED_mask_get_size(sa, &mask_width, &mask_height);
ED_mask_draw_region(mask, ar,
- sc->mask_info.draw_flag, sc->mask_info.draw_type,
+ sc->mask_info.draw_flag,
+ sc->mask_info.draw_type,
+ sc->mask_info.overlay_mode,
mask_width, mask_height,
aspx, aspy,
TRUE, TRUE,
diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c
index 7a6546053cd..246ea7fe140 100644
--- a/source/blender/editors/space_clip/tracking_ops.c
+++ b/source/blender/editors/space_clip/tracking_ops.c
@@ -2405,7 +2405,7 @@ static int set_axis_exec(bContext *C, wmOperator *op)
track = tracksbase->first;
while (track) {
- if (TRACK_VIEW_SELECTED(sc, track))
+ if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_HAS_BUNDLE))
break;
track = track->next;
diff --git a/source/blender/editors/space_console/console_ops.c b/source/blender/editors/space_console/console_ops.c
index c10ea96096f..289986d7fba 100644
--- a/source/blender/editors/space_console/console_ops.c
+++ b/source/blender/editors/space_console/console_ops.c
@@ -681,6 +681,7 @@ static int console_clear_exec(bContext *C, wmOperator *op)
if (history) {
while (sc->history.first)
console_history_free(sc, sc->history.first);
+ console_history_verify(C);
}
console_textview_update_rect(sc, ar);
diff --git a/source/blender/editors/space_console/space_console.c b/source/blender/editors/space_console/space_console.c
index 88a04197847..5c8d1e84fd5 100644
--- a/source/blender/editors/space_console/space_console.c
+++ b/source/blender/editors/space_console/space_console.c
@@ -317,6 +317,7 @@ static void console_keymap(struct wmKeyConfig *keyconf)
RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_delete", BACKSPACEKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", DEL_PREV_WORD);
WM_keymap_add_item(keymap, "CONSOLE_OT_clear_line", RETKEY, KM_PRESS, KM_SHIFT, 0);
+ WM_keymap_add_item(keymap, "CONSOLE_OT_clear_line", PADENTER, KM_PRESS, KM_SHIFT, 0);
#ifdef WITH_PYTHON
kmi = WM_keymap_add_item(keymap, "CONSOLE_OT_execute", RETKEY, KM_PRESS, 0, 0);
diff --git a/source/blender/editors/space_file/CMakeLists.txt b/source/blender/editors/space_file/CMakeLists.txt
index b30f008e1bf..ce0b08c6708 100644
--- a/source/blender/editors/space_file/CMakeLists.txt
+++ b/source/blender/editors/space_file/CMakeLists.txt
@@ -58,6 +58,10 @@ if(WITH_IMAGE_OPENEXR)
add_definitions(-DWITH_OPENEXR)
endif()
+if(WITH_IMAGE_OPENIMAGEIO)
+ add_definitions(-DWITH_OPENIMAGEIO)
+endif()
+
if(WITH_IMAGE_TIFF)
add_definitions(-DWITH_TIFF)
endif()
diff --git a/source/blender/editors/space_file/SConscript b/source/blender/editors/space_file/SConscript
index e1eadb66a11..d42394454eb 100644
--- a/source/blender/editors/space_file/SConscript
+++ b/source/blender/editors/space_file/SConscript
@@ -55,6 +55,9 @@ if env['WITH_BF_OPENEXR']:
if env['WITH_BF_TIFF']:
defs.append('WITH_TIFF')
+if env['WITH_BF_OIIO']:
+ defs.append('WITH_OPENIMAGEIO')
+
if env['WITH_BF_INTERNATIONAL']:
defs.append('WITH_INTERNATIONAL')
diff --git a/source/blender/editors/space_file/file_intern.h b/source/blender/editors/space_file/file_intern.h
index 240106d37d5..d01286442be 100644
--- a/source/blender/editors/space_file/file_intern.h
+++ b/source/blender/editors/space_file/file_intern.h
@@ -65,7 +65,7 @@ void FILE_OT_select_all_toggle(struct wmOperatorType *ot);
void FILE_OT_select_border(struct wmOperatorType *ot);
void FILE_OT_select_bookmark(struct wmOperatorType *ot);
void FILE_OT_bookmark_add(struct wmOperatorType *ot);
-void FILE_OT_delete_bookmark(struct wmOperatorType *ot);
+void FILE_OT_bookmark_delete(struct wmOperatorType *ot);
void FILE_OT_reset_recent(wmOperatorType *ot);
void FILE_OT_hidedot(struct wmOperatorType *ot);
void FILE_OT_execute(struct wmOperatorType *ot);
diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c
index e3270d9ce8e..a97b3b1d719 100644
--- a/source/blender/editors/space_file/file_ops.c
+++ b/source/blender/editors/space_file/file_ops.c
@@ -503,14 +503,14 @@ static int bookmark_delete_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void FILE_OT_delete_bookmark(wmOperatorType *ot)
+void FILE_OT_bookmark_delete(wmOperatorType *ot)
{
PropertyRNA *prop;
/* identifiers */
ot->name = "Delete Bookmark";
ot->description = "Delete selected bookmark";
- ot->idname = "FILE_OT_delete_bookmark";
+ ot->idname = "FILE_OT_bookmark_delete";
/* api callbacks */
ot->exec = bookmark_delete_exec;
diff --git a/source/blender/editors/space_file/file_panels.c b/source/blender/editors/space_file/file_panels.c
index 0efc7b927a9..f4161c7da1c 100644
--- a/source/blender/editors/space_file/file_panels.c
+++ b/source/blender/editors/space_file/file_panels.c
@@ -121,7 +121,7 @@ static void file_panel_category(const bContext *C, Panel *pa, FSMenuCategory cat
/* create delete button */
if (allow_delete && fsmenu_can_save(fsmenu, category, i)) {
uiBlockSetEmboss(block, UI_EMBOSSN);
- uiItemIntO(layout, "", ICON_X, "FILE_OT_delete_bookmark", "index", i);
+ uiItemIntO(layout, "", ICON_X, "FILE_OT_bookmark_delete", "index", i);
uiBlockSetEmboss(block, UI_EMBOSS);
}
}
diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c
index 9758e2e9135..1a8565a58b1 100644
--- a/source/blender/editors/space_file/space_file.c
+++ b/source/blender/editors/space_file/space_file.c
@@ -387,7 +387,7 @@ static void file_operatortypes(void)
WM_operatortype_append(FILE_OT_refresh);
WM_operatortype_append(FILE_OT_bookmark_toggle);
WM_operatortype_append(FILE_OT_bookmark_add);
- WM_operatortype_append(FILE_OT_delete_bookmark);
+ WM_operatortype_append(FILE_OT_bookmark_delete);
WM_operatortype_append(FILE_OT_reset_recent);
WM_operatortype_append(FILE_OT_hidedot);
WM_operatortype_append(FILE_OT_filenum);
diff --git a/source/blender/editors/space_graph/graph_draw.c b/source/blender/editors/space_graph/graph_draw.c
index 7610f7a9192..23c39a5e99a 100644
--- a/source/blender/editors/space_graph/graph_draw.c
+++ b/source/blender/editors/space_graph/graph_draw.c
@@ -951,7 +951,7 @@ void graph_draw_curves(bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGrid
/* 1) draw curve line */
{
/* set color/drawing style for curve itself */
- if (((fcu->grp) && (fcu->grp->flag & AGRP_PROTECTED)) || (fcu->flag & FCURVE_PROTECTED)) {
+ if (BKE_fcurve_is_protected(fcu)) {
/* protected curves (non editable) are drawn with dotted lines */
setlinestyle(2);
}
diff --git a/source/blender/editors/space_image/CMakeLists.txt b/source/blender/editors/space_image/CMakeLists.txt
index 6509af179e7..2f78818d012 100644
--- a/source/blender/editors/space_image/CMakeLists.txt
+++ b/source/blender/editors/space_image/CMakeLists.txt
@@ -50,6 +50,10 @@ if(WITH_INTERNATIONAL)
add_definitions(-DWITH_INTERNATIONAL)
endif()
+if(WITH_IMAGE_OPENIMAGEIO)
+ add_definitions(-DWITH_OPENIMAGEIO)
+endif()
+
if(WITH_IMAGE_OPENJPEG)
add_definitions(-DWITH_OPENJPEG)
endif()
diff --git a/source/blender/editors/space_image/SConscript b/source/blender/editors/space_image/SConscript
index 268172b300d..89def32e70f 100644
--- a/source/blender/editors/space_image/SConscript
+++ b/source/blender/editors/space_image/SConscript
@@ -57,6 +57,8 @@ if env['WITH_BF_TIFF']:
defs.append('WITH_TIFF')
if env['WITH_BF_CINEON']:
defs.append('WITH_CINEON')
+if env['WITH_BF_OIIO']:
+ defs.append('WITH_OPENIMAGEIO')
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', 'win64-mingw'):
incs += ' ' + env['BF_PTHREADS_INC']
diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c
index 144d2c14e9f..3ff404d38a9 100644
--- a/source/blender/editors/space_image/image_buttons.c
+++ b/source/blender/editors/space_image/image_buttons.c
@@ -640,7 +640,7 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char
else
uiItemO(row, "", ICON_UGLYPACKAGE, "image.pack");
- row = uiLayoutRow(row, FALSE);
+ row = uiLayoutRow(row, TRUE);
uiLayoutSetEnabled(row, ima->packedfile == NULL);
uiItemR(row, &imaptr, "filepath", 0, "", ICON_NONE);
uiItemO(row, "", ICON_FILE_REFRESH, "image.reload");
diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c
index 23c85699b00..89e57955339 100644
--- a/source/blender/editors/space_image/image_draw.c
+++ b/source/blender/editors/space_image/image_draw.c
@@ -268,8 +268,6 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, int color_manage, int use_def
else
rgba[3] = linearcol[3];
- (void)color_manage;
-
if (use_default_view)
IMB_colormanagement_pixel_to_display_space_v4(rgba, rgba, NULL, &scene->display_settings);
else
@@ -360,14 +358,8 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, int color_manage, int use_def
dx += BLF_width(blf_mono_font, str);
}
else if (channels >= 3) {
- if (fp) {
- rgb_to_hsv(fp[0], fp[1], fp[2], &hue, &sat, &val);
- rgb_to_yuv(fp[0], fp[1], fp[2], &lum, &u, &v);
- }
- else if (cp) {
- rgb_to_hsv((float)cp[0] / 255.0f, (float)cp[1] / 255.0f, (float)cp[2] / 255.0f, &hue, &sat, &val);
- rgb_to_yuv((float)cp[0] / 255.0f, (float)cp[1] / 255.0f, (float)cp[2] / 255.0f, &lum, &u, &v);
- }
+ rgb_to_hsv(finalcol[0], finalcol[1], finalcol[2], &hue, &sat, &val);
+ rgb_to_yuv(finalcol[0], finalcol[1], finalcol[2], &lum, &u, &v);
BLI_snprintf(str, sizeof(str), "H:%-.4f", hue);
BLF_position(blf_mono_font, dx, 0.3f * UI_UNIT_X, 0);
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index cbd3917cacb..710d5c8cd81 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -1804,6 +1804,8 @@ static int image_new_exec(bContext *C, wmOperator *op)
BKE_image_signal(ima, (sima) ? &sima->iuser : NULL, IMA_SIGNAL_USER_NEW_IMAGE);
+ WM_event_add_notifier(C, NC_IMAGE | NA_ADDED, ima);
+
return OPERATOR_FINISHED;
}
@@ -2415,6 +2417,9 @@ static int image_sample_line_exec(bContext *C, wmOperator *op)
hist->co[1][0] = x2f;
hist->co[1][1] = y2f;
+ /* enable line drawing */
+ hist->flag |= HISTO_FLAG_SAMPLELINE;
+
BKE_histogram_update_sample_line(hist, ibuf, &scene->view_settings, &scene->display_settings);
/* reset y zoom */
diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c
index 5a8292abcab..7b20af340ae 100644
--- a/source/blender/editors/space_image/space_image.c
+++ b/source/blender/editors/space_image/space_image.c
@@ -674,7 +674,6 @@ static void image_main_area_draw(const bContext *C, ARegion *ar)
}
else if (sima->mode == SI_MODE_MASK) {
mask = ED_space_image_get_mask(sima);
- draw_image_cursor(ar, sima->cursor);
}
ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW);
@@ -715,7 +714,9 @@ static void image_main_area_draw(const bContext *C, ARegion *ar)
BLI_unlock_thread(LOCK_DRAW_IMAGE);
ED_mask_draw_region(mask, ar,
- sima->mask_info.draw_flag, sima->mask_info.draw_type,
+ sima->mask_info.draw_flag,
+ sima->mask_info.draw_type,
+ sima->mask_info.overlay_mode,
width, height,
aspx, aspy,
TRUE, FALSE,
@@ -723,7 +724,9 @@ static void image_main_area_draw(const bContext *C, ARegion *ar)
ED_mask_draw_frames(mask, ar, CFRA, mask->sfra, mask->efra);
+ UI_view2d_view_ortho(v2d);
draw_image_cursor(ar, sima->cursor);
+ UI_view2d_view_restore(C);
}
/* scrollers? */
diff --git a/source/blender/editors/space_info/info_stats.c b/source/blender/editors/space_info/info_stats.c
index c1cddf092aa..9686c6dfc29 100644
--- a/source/blender/editors/space_info/info_stats.c
+++ b/source/blender/editors/space_info/info_stats.c
@@ -194,9 +194,9 @@ static void stats_object_edit(Object *obedit, SceneStats *stats)
a = nu->pntsu;
while (a--) {
stats->totvert += 3;
- if (bezt->f1) stats->totvertsel++;
- if (bezt->f2) stats->totvertsel++;
- if (bezt->f3) stats->totvertsel++;
+ if (bezt->f1 & SELECT) stats->totvertsel++;
+ if (bezt->f2 & SELECT) stats->totvertsel++;
+ if (bezt->f3 & SELECT) stats->totvertsel++;
bezt++;
}
}
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index 45428425138..ba28f502349 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -86,18 +86,6 @@ static void node_socket_button_label(bContext *UNUSED(C), uiLayout *layout, Poin
uiItemL(layout, text, 0);
}
-static void node_draw_input_default(bContext *C, uiLayout *layout, PointerRNA *ptr, PointerRNA *node_ptr)
-{
- bNodeSocket *sock = (bNodeSocket *)ptr->data;
- sock->typeinfo->draw(C, layout, ptr, node_ptr, IFACE_(sock->name));
-}
-
-static void node_draw_output_default(bContext *C, uiLayout *layout, PointerRNA *ptr, PointerRNA *node_ptr)
-{
- bNodeSocket *sock = ptr->data;
- node_socket_button_label(C, layout, ptr, node_ptr, IFACE_(sock->name));
-}
-
/* ****************** BASE DRAW FUNCTIONS FOR NEW OPERATOR NODES ***************** */
@@ -339,7 +327,7 @@ static int node_resize_area_default(bNode *node, int x, int y)
/* ****************** BUTTON CALLBACKS FOR COMMON NODES ***************** */
-static void node_uifunc_group(uiLayout *layout, bContext *C, PointerRNA *ptr)
+static void node_draw_buttons_group(uiLayout *layout, bContext *C, PointerRNA *ptr)
{
uiTemplateIDBrowse(layout, C, ptr, "node_tree", NULL, NULL, NULL);
}
@@ -348,7 +336,7 @@ static void node_uifunc_group(uiLayout *layout, bContext *C, PointerRNA *ptr)
* Not ideal to do this in every draw call, but doing as transform callback doesn't work,
* since the child node totr rects are not updated properly at that point.
*/
-static void node_update_frame(const bContext *UNUSED(C), bNodeTree *ntree, bNode *node)
+static void node_draw_frame_prepare(const bContext *UNUSED(C), bNodeTree *ntree, bNode *node)
{
const float margin = 1.5f * U.widget_unit;
NodeFrame *data = (NodeFrame *)node->storage;
@@ -511,7 +499,7 @@ static int node_resize_area_frame(bNode *node, int x, int y)
return dir;
}
-static void node_buts_frame_details(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_buts_frame_ex(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiItemR(layout, ptr, "label_size", 0, IFACE_("Label Size"), ICON_NONE);
uiItemR(layout, ptr, "shrink", 0, IFACE_("Shrink"), ICON_NONE);
@@ -520,7 +508,7 @@ static void node_buts_frame_details(uiLayout *layout, bContext *UNUSED(C), Point
#define NODE_REROUTE_SIZE 8.0f
-static void node_update_reroute(const bContext *UNUSED(C), bNodeTree *UNUSED(ntree), bNode *node)
+static void node_draw_reroute_prepare(const bContext *UNUSED(C), bNodeTree *UNUSED(ntree), bNode *node)
{
bNodeSocket *nsock;
float locx, locy;
@@ -571,7 +559,7 @@ static void node_draw_reroute(const bContext *C, ARegion *ar, SpaceNode *UNUSED(
*/
#if 0
/* body */
- uiSetRoundBox(15);
+ uiSetRoundBox(UI_CNR_ALL);
UI_ThemeColor4(TH_NODE);
glEnable(GL_BLEND);
uiRoundBox(rct->xmin, rct->ymin, rct->xmax, rct->ymax, size);
@@ -632,17 +620,17 @@ static void node_common_set_butfunc(bNodeType *ntype)
{
switch (ntype->type) {
case NODE_GROUP:
- ntype->uifunc = node_uifunc_group;
+ ntype->draw_buttons = node_draw_buttons_group;
break;
case NODE_FRAME:
- ntype->drawfunc = node_draw_frame;
- ntype->drawupdatefunc = node_update_frame;
- ntype->uifuncbut = node_buts_frame_details;
+ ntype->draw_nodetype = node_draw_frame;
+ ntype->draw_nodetype_prepare = node_draw_frame_prepare;
+ ntype->draw_buttons_ex = node_buts_frame_ex;
ntype->resize_area_func = node_resize_area_frame;
break;
case NODE_REROUTE:
- ntype->drawfunc = node_draw_reroute;
- ntype->drawupdatefunc = node_update_reroute;
+ ntype->draw_nodetype = node_draw_reroute;
+ ntype->draw_nodetype_prepare = node_draw_reroute_prepare;
ntype->tweak_area_func = node_tweak_area_reroute;
break;
}
@@ -709,6 +697,8 @@ static void node_shader_buts_mapping(uiLayout *layout, bContext *UNUSED(C), Poin
{
uiLayout *row;
+ uiItemR(layout, ptr, "vector_type", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+
uiItemL(layout, IFACE_("Location:"), ICON_NONE);
row = uiLayoutRow(layout, TRUE);
uiItemR(row, ptr, "translation", 0, "", ICON_NONE);
@@ -737,7 +727,7 @@ static void node_shader_buts_vect_math(uiLayout *layout, bContext *UNUSED(C), Po
static void node_shader_buts_vect_transform(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
- uiItemR(layout, ptr, "type", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "vector_type", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
uiItemR(layout, ptr, "convert_from", 0, "", ICON_NONE);
uiItemR(layout, ptr, "convert_to", 0, "", ICON_NONE);
}
@@ -790,7 +780,7 @@ static void node_shader_buts_tex_image(uiLayout *layout, bContext *C, PointerRNA
node_buts_image_user(layout, C, &iuserptr, &imaptr, &iuserptr);
}
-static void node_shader_buts_tex_image_details(uiLayout *layout, bContext *C, PointerRNA *ptr)
+static void node_shader_buts_tex_image_ex(uiLayout *layout, bContext *C, PointerRNA *ptr)
{
PointerRNA iuserptr = RNA_pointer_get(ptr, "image_user");
uiTemplateImage(layout, C, ptr, "image", &iuserptr, 0);
@@ -911,8 +901,16 @@ static void node_shader_buts_glossy(uiLayout *layout, bContext *UNUSED(C), Point
uiItemR(layout, ptr, "distribution", 0, "", ICON_NONE);
}
-static void node_shader_buts_subsurface(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_shader_buts_subsurface(uiLayout *layout, bContext *C, PointerRNA *ptr)
{
+ /* SSS does not work on GPU yet */
+ PointerRNA scene = CTX_data_pointer_get(C, "scene");
+ if (scene.data) {
+ PointerRNA cscene = RNA_pointer_get(&scene, "cycles");
+ if (cscene.data && RNA_enum_get(&cscene, "device") == 1)
+ uiItemL(layout, IFACE_("SSS not supported on GPU"), ICON_ERROR);
+ }
+
uiItemR(layout, ptr, "falloff", 0, "", ICON_NONE);
}
@@ -943,7 +941,7 @@ static void node_shader_buts_script(uiLayout *layout, bContext *UNUSED(C), Point
uiItemO(row, "", ICON_FILE_REFRESH, "node.shader_script_update");
}
-static void node_shader_buts_script_details(uiLayout *layout, bContext *C, PointerRNA *ptr)
+static void node_shader_buts_script_ex(uiLayout *layout, bContext *C, PointerRNA *ptr)
{
uiItemS(layout);
@@ -961,110 +959,110 @@ static void node_shader_set_butfunc(bNodeType *ntype)
switch (ntype->type) {
case SH_NODE_MATERIAL:
case SH_NODE_MATERIAL_EXT:
- ntype->uifunc = node_shader_buts_material;
+ ntype->draw_buttons = node_shader_buts_material;
break;
case SH_NODE_TEXTURE:
- ntype->uifunc = node_buts_texture;
+ ntype->draw_buttons = node_buts_texture;
break;
case SH_NODE_NORMAL:
- ntype->uifunc = node_buts_normal;
+ ntype->draw_buttons = node_buts_normal;
break;
case SH_NODE_CURVE_VEC:
- ntype->uifunc = node_buts_curvevec;
+ ntype->draw_buttons = node_buts_curvevec;
break;
case SH_NODE_CURVE_RGB:
- ntype->uifunc = node_buts_curvecol;
+ ntype->draw_buttons = node_buts_curvecol;
break;
case SH_NODE_MAPPING:
- ntype->uifunc = node_shader_buts_mapping;
+ ntype->draw_buttons = node_shader_buts_mapping;
break;
case SH_NODE_VALUE:
- ntype->uifunc = node_buts_value;
+ ntype->draw_buttons = node_buts_value;
break;
case SH_NODE_RGB:
- ntype->uifunc = node_buts_rgb;
+ ntype->draw_buttons = node_buts_rgb;
break;
case SH_NODE_MIX_RGB:
- ntype->uifunc = node_buts_mix_rgb;
+ ntype->draw_buttons = node_buts_mix_rgb;
break;
case SH_NODE_VALTORGB:
- ntype->uifunc = node_buts_colorramp;
+ ntype->draw_buttons = node_buts_colorramp;
break;
case SH_NODE_MATH:
- ntype->uifunc = node_buts_math;
+ ntype->draw_buttons = node_buts_math;
break;
case SH_NODE_VECT_MATH:
- ntype->uifunc = node_shader_buts_vect_math;
+ ntype->draw_buttons = node_shader_buts_vect_math;
break;
case SH_NODE_VECT_TRANSFORM:
- ntype->uifunc = node_shader_buts_vect_transform;
+ ntype->draw_buttons = node_shader_buts_vect_transform;
break;
case SH_NODE_GEOMETRY:
- ntype->uifunc = node_shader_buts_geometry;
+ ntype->draw_buttons = node_shader_buts_geometry;
break;
case SH_NODE_ATTRIBUTE:
- ntype->uifunc = node_shader_buts_attribute;
+ ntype->draw_buttons = node_shader_buts_attribute;
break;
case SH_NODE_WIREFRAME:
- ntype->uifunc = node_shader_buts_wireframe;
+ ntype->draw_buttons = node_shader_buts_wireframe;
break;
case SH_NODE_TEX_SKY:
- ntype->uifunc = node_shader_buts_tex_sky;
+ ntype->draw_buttons = node_shader_buts_tex_sky;
break;
case SH_NODE_TEX_IMAGE:
- ntype->uifunc = node_shader_buts_tex_image;
- ntype->uifuncbut = node_shader_buts_tex_image_details;
+ ntype->draw_buttons = node_shader_buts_tex_image;
+ ntype->draw_buttons_ex = node_shader_buts_tex_image_ex;
break;
case SH_NODE_TEX_ENVIRONMENT:
- ntype->uifunc = node_shader_buts_tex_environment;
+ ntype->draw_buttons = node_shader_buts_tex_environment;
break;
case SH_NODE_TEX_GRADIENT:
- ntype->uifunc = node_shader_buts_tex_gradient;
+ ntype->draw_buttons = node_shader_buts_tex_gradient;
break;
case SH_NODE_TEX_MAGIC:
- ntype->uifunc = node_shader_buts_tex_magic;
+ ntype->draw_buttons = node_shader_buts_tex_magic;
break;
case SH_NODE_TEX_BRICK:
- ntype->uifunc = node_shader_buts_tex_brick;
+ ntype->draw_buttons = node_shader_buts_tex_brick;
break;
case SH_NODE_TEX_WAVE:
- ntype->uifunc = node_shader_buts_tex_wave;
+ ntype->draw_buttons = node_shader_buts_tex_wave;
break;
case SH_NODE_TEX_MUSGRAVE:
- ntype->uifunc = node_shader_buts_tex_musgrave;
+ ntype->draw_buttons = node_shader_buts_tex_musgrave;
break;
case SH_NODE_TEX_VORONOI:
- ntype->uifunc = node_shader_buts_tex_voronoi;
+ ntype->draw_buttons = node_shader_buts_tex_voronoi;
break;
case SH_NODE_TEX_COORD:
- ntype->uifunc = node_shader_buts_tex_coord;
+ ntype->draw_buttons = node_shader_buts_tex_coord;
break;
case SH_NODE_BUMP:
- ntype->uifunc = node_shader_buts_bump;
+ ntype->draw_buttons = node_shader_buts_bump;
break;
case SH_NODE_NORMAL_MAP:
- ntype->uifunc = node_shader_buts_normal_map;
+ ntype->draw_buttons = node_shader_buts_normal_map;
break;
case SH_NODE_TANGENT:
- ntype->uifunc = node_shader_buts_tangent;
+ ntype->draw_buttons = node_shader_buts_tangent;
break;
case SH_NODE_BSDF_GLOSSY:
case SH_NODE_BSDF_GLASS:
case SH_NODE_BSDF_REFRACTION:
- ntype->uifunc = node_shader_buts_glossy;
+ ntype->draw_buttons = node_shader_buts_glossy;
break;
case SH_NODE_SUBSURFACE_SCATTERING:
- ntype->uifunc = node_shader_buts_subsurface;
+ ntype->draw_buttons = node_shader_buts_subsurface;
break;
case SH_NODE_BSDF_TOON:
- ntype->uifunc = node_shader_buts_toon;
+ ntype->draw_buttons = node_shader_buts_toon;
break;
case SH_NODE_BSDF_HAIR:
- ntype->uifunc = node_shader_buts_hair;
+ ntype->draw_buttons = node_shader_buts_hair;
break;
case SH_NODE_SCRIPT:
- ntype->uifunc = node_shader_buts_script;
- ntype->uifuncbut = node_shader_buts_script_details;
+ ntype->draw_buttons = node_shader_buts_script;
+ ntype->draw_buttons_ex = node_shader_buts_script_ex;
break;
}
}
@@ -1086,7 +1084,7 @@ static void node_composit_buts_image(uiLayout *layout, bContext *C, PointerRNA *
node_buts_image_user(layout, C, ptr, &imaptr, &iuserptr);
}
-static void node_composit_buts_image_details(uiLayout *layout, bContext *C, PointerRNA *ptr)
+static void node_composit_buts_image_ex(uiLayout *layout, bContext *C, PointerRNA *ptr)
{
bNode *node = ptr->data;
PointerRNA iuserptr;
@@ -1568,46 +1566,6 @@ static void node_composit_buts_id_mask(uiLayout *layout, bContext *UNUSED(C), Po
uiItemR(layout, ptr, "use_antialiasing", 0, NULL, ICON_NONE);
}
-/* draw function for file output node sockets, displays only sub-path and format, no value button */
-static void node_draw_input_file_output(bContext *C, uiLayout *layout, PointerRNA *ptr, PointerRNA *node_ptr)
-{
- bNodeTree *ntree = ptr->id.data;
- bNodeSocket *sock = ptr->data;
- uiLayout *row;
- PointerRNA inputptr, imfptr;
- int imtype;
-
- row = uiLayoutRow(layout, FALSE);
-
- imfptr = RNA_pointer_get(node_ptr, "format");
- imtype = RNA_enum_get(&imfptr, "file_format");
- if (imtype == R_IMF_IMTYPE_MULTILAYER) {
- NodeImageMultiFileSocket *input = sock->storage;
- RNA_pointer_create(&ntree->id, &RNA_NodeOutputFileSlotLayer, input, &inputptr);
-
- uiItemL(row, input->layer, ICON_NONE);
- }
- else {
- NodeImageMultiFileSocket *input = sock->storage;
- PropertyRNA *imtype_prop;
- const char *imtype_name;
- uiBlock *block;
- RNA_pointer_create(&ntree->id, &RNA_NodeOutputFileSlotFile, input, &inputptr);
-
- uiItemL(row, input->path, ICON_NONE);
-
- if (!RNA_boolean_get(&inputptr, "use_node_format"))
- imfptr = RNA_pointer_get(&inputptr, "format");
-
- imtype_prop = RNA_struct_find_property(&imfptr, "file_format");
- RNA_property_enum_name((bContext *)C, &imfptr, imtype_prop,
- RNA_property_enum_get(&imfptr, imtype_prop), &imtype_name);
- block = uiLayoutGetBlock(row);
- uiBlockSetEmboss(block, UI_EMBOSSP);
- uiItemL(row, imtype_name, ICON_NONE);
- uiBlockSetEmboss(block, UI_EMBOSSN);
- }
-}
static void node_composit_buts_file_output(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
PointerRNA imfptr = RNA_pointer_get(ptr, "format");
@@ -1619,7 +1577,7 @@ static void node_composit_buts_file_output(uiLayout *layout, bContext *UNUSED(C)
uiItemL(layout, IFACE_("Base Path:"), ICON_NONE);
uiItemR(layout, ptr, "base_path", 0, "", ICON_NONE);
}
-static void node_composit_buts_file_output_details(uiLayout *layout, bContext *C, PointerRNA *ptr)
+static void node_composit_buts_file_output_ex(uiLayout *layout, bContext *C, PointerRNA *ptr)
{
PointerRNA imfptr = RNA_pointer_get(ptr, "format");
PointerRNA active_input_ptr, op_ptr;
@@ -1777,7 +1735,7 @@ static void node_composit_buts_colorbalance(uiLayout *layout, bContext *UNUSED(C
}
}
-static void node_composit_buts_colorbalance_but(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_composit_buts_colorbalance_ex(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiItemR(layout, ptr, "correction_method", 0, NULL, ICON_NONE);
@@ -1831,7 +1789,7 @@ static void node_composit_buts_movieclip(uiLayout *layout, bContext *C, PointerR
uiTemplateID(layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL);
}
-static void node_composit_buts_movieclip_details(uiLayout *layout, bContext *C, PointerRNA *ptr)
+static void node_composit_buts_movieclip_ex(uiLayout *layout, bContext *C, PointerRNA *ptr)
{
bNode *node = ptr->data;
PointerRNA clipptr;
@@ -1935,7 +1893,7 @@ static void node_composit_buts_colorcorrection(uiLayout *layout, bContext *UNUSE
uiItemR(row, ptr, "midtones_end", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
}
-static void node_composit_buts_colorcorrection_but(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_composit_buts_colorcorrection_ex(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiLayout *row;
@@ -2137,7 +2095,7 @@ static void node_composit_buts_viewer(uiLayout *layout, bContext *UNUSED(C), Poi
uiItemR(layout, ptr, "use_alpha", 0, NULL, ICON_NONE);
}
-static void node_composit_buts_viewer_but(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_composit_buts_viewer_ex(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiLayout *col;
@@ -2285,222 +2243,221 @@ static void node_composit_set_butfunc(bNodeType *ntype)
{
switch (ntype->type) {
case CMP_NODE_IMAGE:
- ntype->uifunc = node_composit_buts_image;
- ntype->uifuncbut = node_composit_buts_image_details;
+ ntype->draw_buttons = node_composit_buts_image;
+ ntype->draw_buttons_ex = node_composit_buts_image_ex;
break;
case CMP_NODE_R_LAYERS:
- ntype->uifunc = node_composit_buts_renderlayers;
+ ntype->draw_buttons = node_composit_buts_renderlayers;
break;
case CMP_NODE_NORMAL:
- ntype->uifunc = node_buts_normal;
+ ntype->draw_buttons = node_buts_normal;
break;
case CMP_NODE_CURVE_VEC:
- ntype->uifunc = node_buts_curvevec;
+ ntype->draw_buttons = node_buts_curvevec;
break;
case CMP_NODE_CURVE_RGB:
- ntype->uifunc = node_buts_curvecol;
+ ntype->draw_buttons = node_buts_curvecol;
break;
case CMP_NODE_VALUE:
- ntype->uifunc = node_buts_value;
+ ntype->draw_buttons = node_buts_value;
break;
case CMP_NODE_RGB:
- ntype->uifunc = node_buts_rgb;
+ ntype->draw_buttons = node_buts_rgb;
break;
case CMP_NODE_FLIP:
- ntype->uifunc = node_composit_buts_flip;
+ ntype->draw_buttons = node_composit_buts_flip;
break;
case CMP_NODE_SPLITVIEWER:
- ntype->uifunc = node_composit_buts_splitviewer;
+ ntype->draw_buttons = node_composit_buts_splitviewer;
break;
case CMP_NODE_MIX_RGB:
- ntype->uifunc = node_buts_mix_rgb;
+ ntype->draw_buttons = node_buts_mix_rgb;
break;
case CMP_NODE_VALTORGB:
- ntype->uifunc = node_buts_colorramp;
+ ntype->draw_buttons = node_buts_colorramp;
break;
case CMP_NODE_CROP:
- ntype->uifunc = node_composit_buts_crop;
+ ntype->draw_buttons = node_composit_buts_crop;
break;
case CMP_NODE_BLUR:
- ntype->uifunc = node_composit_buts_blur;
+ ntype->draw_buttons = node_composit_buts_blur;
break;
case CMP_NODE_DBLUR:
- ntype->uifunc = node_composit_buts_dblur;
+ ntype->draw_buttons = node_composit_buts_dblur;
break;
case CMP_NODE_BILATERALBLUR:
- ntype->uifunc = node_composit_buts_bilateralblur;
+ ntype->draw_buttons = node_composit_buts_bilateralblur;
break;
case CMP_NODE_DEFOCUS:
- ntype->uifunc = node_composit_buts_defocus;
+ ntype->draw_buttons = node_composit_buts_defocus;
break;
case CMP_NODE_GLARE:
- ntype->uifunc = node_composit_buts_glare;
+ ntype->draw_buttons = node_composit_buts_glare;
break;
case CMP_NODE_TONEMAP:
- ntype->uifunc = node_composit_buts_tonemap;
+ ntype->draw_buttons = node_composit_buts_tonemap;
break;
case CMP_NODE_LENSDIST:
- ntype->uifunc = node_composit_buts_lensdist;
+ ntype->draw_buttons = node_composit_buts_lensdist;
break;
case CMP_NODE_VECBLUR:
- ntype->uifunc = node_composit_buts_vecblur;
+ ntype->draw_buttons = node_composit_buts_vecblur;
break;
case CMP_NODE_FILTER:
- ntype->uifunc = node_composit_buts_filter;
+ ntype->draw_buttons = node_composit_buts_filter;
break;
case CMP_NODE_MAP_VALUE:
- ntype->uifunc = node_composit_buts_map_value;
+ ntype->draw_buttons = node_composit_buts_map_value;
break;
case CMP_NODE_MAP_RANGE:
- ntype->uifunc = node_composit_buts_map_range;
+ ntype->draw_buttons = node_composit_buts_map_range;
break;
case CMP_NODE_TIME:
- ntype->uifunc = node_buts_time;
+ ntype->draw_buttons = node_buts_time;
break;
case CMP_NODE_ALPHAOVER:
- ntype->uifunc = node_composit_buts_alphaover;
+ ntype->draw_buttons = node_composit_buts_alphaover;
break;
case CMP_NODE_HUE_SAT:
- ntype->uifunc = node_composit_buts_hue_sat;
+ ntype->draw_buttons = node_composit_buts_hue_sat;
break;
case CMP_NODE_TEXTURE:
- ntype->uifunc = node_buts_texture;
+ ntype->draw_buttons = node_buts_texture;
break;
case CMP_NODE_DILATEERODE:
- ntype->uifunc = node_composit_buts_dilateerode;
+ ntype->draw_buttons = node_composit_buts_dilateerode;
break;
case CMP_NODE_INPAINT:
- ntype->uifunc = node_composit_buts_inpaint;
+ ntype->draw_buttons = node_composit_buts_inpaint;
break;
case CMP_NODE_DESPECKLE:
- ntype->uifunc = node_composit_buts_despeckle;
+ ntype->draw_buttons = node_composit_buts_despeckle;
break;
case CMP_NODE_OUTPUT_FILE:
- ntype->uifunc = node_composit_buts_file_output;
- ntype->uifuncbut = node_composit_buts_file_output_details;
- ntype->drawinputfunc = node_draw_input_file_output;
+ ntype->draw_buttons = node_composit_buts_file_output;
+ ntype->draw_buttons_ex = node_composit_buts_file_output_ex;
break;
case CMP_NODE_DIFF_MATTE:
- ntype->uifunc = node_composit_buts_diff_matte;
+ ntype->draw_buttons = node_composit_buts_diff_matte;
break;
case CMP_NODE_DIST_MATTE:
- ntype->uifunc = node_composit_buts_distance_matte;
+ ntype->draw_buttons = node_composit_buts_distance_matte;
break;
case CMP_NODE_COLOR_SPILL:
- ntype->uifunc = node_composit_buts_color_spill;
+ ntype->draw_buttons = node_composit_buts_color_spill;
break;
case CMP_NODE_CHROMA_MATTE:
- ntype->uifunc = node_composit_buts_chroma_matte;
+ ntype->draw_buttons = node_composit_buts_chroma_matte;
break;
case CMP_NODE_COLOR_MATTE:
- ntype->uifunc = node_composit_buts_color_matte;
+ ntype->draw_buttons = node_composit_buts_color_matte;
break;
case CMP_NODE_SCALE:
- ntype->uifunc = node_composit_buts_scale;
+ ntype->draw_buttons = node_composit_buts_scale;
break;
case CMP_NODE_ROTATE:
- ntype->uifunc = node_composit_buts_rotate;
+ ntype->draw_buttons = node_composit_buts_rotate;
break;
case CMP_NODE_CHANNEL_MATTE:
- ntype->uifunc = node_composit_buts_channel_matte;
+ ntype->draw_buttons = node_composit_buts_channel_matte;
break;
case CMP_NODE_LUMA_MATTE:
- ntype->uifunc = node_composit_buts_luma_matte;
+ ntype->draw_buttons = node_composit_buts_luma_matte;
break;
case CMP_NODE_MAP_UV:
- ntype->uifunc = node_composit_buts_map_uv;
+ ntype->draw_buttons = node_composit_buts_map_uv;
break;
case CMP_NODE_ID_MASK:
- ntype->uifunc = node_composit_buts_id_mask;
+ ntype->draw_buttons = node_composit_buts_id_mask;
break;
case CMP_NODE_DOUBLEEDGEMASK:
- ntype->uifunc = node_composit_buts_double_edge_mask;
+ ntype->draw_buttons = node_composit_buts_double_edge_mask;
break;
case CMP_NODE_MATH:
- ntype->uifunc = node_buts_math;
+ ntype->draw_buttons = node_buts_math;
break;
case CMP_NODE_INVERT:
- ntype->uifunc = node_composit_buts_invert;
+ ntype->draw_buttons = node_composit_buts_invert;
break;
case CMP_NODE_PREMULKEY:
- ntype->uifunc = node_composit_buts_premulkey;
+ ntype->draw_buttons = node_composit_buts_premulkey;
break;
case CMP_NODE_VIEW_LEVELS:
- ntype->uifunc = node_composit_buts_view_levels;
+ ntype->draw_buttons = node_composit_buts_view_levels;
break;
case CMP_NODE_COLORBALANCE:
- ntype->uifunc = node_composit_buts_colorbalance;
- ntype->uifuncbut = node_composit_buts_colorbalance_but;
+ ntype->draw_buttons = node_composit_buts_colorbalance;
+ ntype->draw_buttons_ex = node_composit_buts_colorbalance_ex;
break;
case CMP_NODE_HUECORRECT:
- ntype->uifunc = node_composit_buts_huecorrect;
+ ntype->draw_buttons = node_composit_buts_huecorrect;
break;
case CMP_NODE_ZCOMBINE:
- ntype->uifunc = node_composit_buts_zcombine;
+ ntype->draw_buttons = node_composit_buts_zcombine;
break;
case CMP_NODE_COMBYCCA:
case CMP_NODE_SEPYCCA:
- ntype->uifunc = node_composit_buts_ycc;
+ ntype->draw_buttons = node_composit_buts_ycc;
break;
case CMP_NODE_MOVIECLIP:
- ntype->uifunc = node_composit_buts_movieclip;
- ntype->uifuncbut = node_composit_buts_movieclip_details;
+ ntype->draw_buttons = node_composit_buts_movieclip;
+ ntype->draw_buttons_ex = node_composit_buts_movieclip_ex;
break;
case CMP_NODE_STABILIZE2D:
- ntype->uifunc = node_composit_buts_stabilize2d;
+ ntype->draw_buttons = node_composit_buts_stabilize2d;
break;
case CMP_NODE_TRANSFORM:
- ntype->uifunc = node_composit_buts_transform;
+ ntype->draw_buttons = node_composit_buts_transform;
break;
case CMP_NODE_TRANSLATE:
- ntype->uifunc = node_composit_buts_translate;
+ ntype->draw_buttons = node_composit_buts_translate;
break;
case CMP_NODE_MOVIEDISTORTION:
- ntype->uifunc = node_composit_buts_moviedistortion;
+ ntype->draw_buttons = node_composit_buts_moviedistortion;
break;
case CMP_NODE_COLORCORRECTION:
- ntype->uifunc = node_composit_buts_colorcorrection;
- ntype->uifuncbut = node_composit_buts_colorcorrection_but;
+ ntype->draw_buttons = node_composit_buts_colorcorrection;
+ ntype->draw_buttons_ex = node_composit_buts_colorcorrection_ex;
break;
case CMP_NODE_SWITCH:
- ntype->uifunc = node_composit_buts_switch;
+ ntype->draw_buttons = node_composit_buts_switch;
break;
case CMP_NODE_MASK_BOX:
- ntype->uifunc = node_composit_buts_boxmask;
- ntype->uibackdropfunc = node_composit_backdrop_boxmask;
+ ntype->draw_buttons = node_composit_buts_boxmask;
+ ntype->draw_backdrop = node_composit_backdrop_boxmask;
break;
case CMP_NODE_MASK_ELLIPSE:
- ntype->uifunc = node_composit_buts_ellipsemask;
- ntype->uibackdropfunc = node_composit_backdrop_ellipsemask;
+ ntype->draw_buttons = node_composit_buts_ellipsemask;
+ ntype->draw_backdrop = node_composit_backdrop_ellipsemask;
break;
case CMP_NODE_BOKEHIMAGE:
- ntype->uifunc = node_composit_buts_bokehimage;
+ ntype->draw_buttons = node_composit_buts_bokehimage;
break;
case CMP_NODE_BOKEHBLUR:
- ntype->uifunc = node_composit_buts_bokehblur;
+ ntype->draw_buttons = node_composit_buts_bokehblur;
break;
case CMP_NODE_VIEWER:
- ntype->uifunc = node_composit_buts_viewer;
- ntype->uifuncbut = node_composit_buts_viewer_but;
- ntype->uibackdropfunc = node_composit_backdrop_viewer;
+ ntype->draw_buttons = node_composit_buts_viewer;
+ ntype->draw_buttons_ex = node_composit_buts_viewer_ex;
+ ntype->draw_backdrop = node_composit_backdrop_viewer;
break;
case CMP_NODE_COMPOSITE:
- ntype->uifunc = node_composit_buts_composite;
+ ntype->draw_buttons = node_composit_buts_composite;
break;
case CMP_NODE_MASK:
- ntype->uifunc = node_composit_buts_mask;
+ ntype->draw_buttons = node_composit_buts_mask;
break;
case CMP_NODE_KEYINGSCREEN:
- ntype->uifunc = node_composit_buts_keyingscreen;
+ ntype->draw_buttons = node_composit_buts_keyingscreen;
break;
case CMP_NODE_KEYING:
- ntype->uifunc = node_composit_buts_keying;
+ ntype->draw_buttons = node_composit_buts_keying;
break;
case CMP_NODE_TRACKPOS:
- ntype->uifunc = node_composit_buts_trackpos;
+ ntype->draw_buttons = node_composit_buts_trackpos;
break;
case CMP_NODE_PLANETRACKDEFORM:
- ntype->uifunc = node_composit_buts_planetrackdeform;
+ ntype->draw_buttons = node_composit_buts_planetrackdeform;
break;
}
}
@@ -2605,7 +2562,7 @@ static void node_texture_buts_image(uiLayout *layout, bContext *C, PointerRNA *p
uiTemplateID(layout, C, ptr, "image", NULL, "IMAGE_OT_open", NULL);
}
-static void node_texture_buts_image_details(uiLayout *layout, bContext *C, PointerRNA *ptr)
+static void node_texture_buts_image_ex(uiLayout *layout, bContext *C, PointerRNA *ptr)
{
bNode *node = ptr->data;
PointerRNA iuserptr;
@@ -2623,46 +2580,46 @@ static void node_texture_buts_output(uiLayout *layout, bContext *UNUSED(C), Poin
static void node_texture_set_butfunc(bNodeType *ntype)
{
if (ntype->type >= TEX_NODE_PROC && ntype->type < TEX_NODE_PROC_MAX) {
- ntype->uifunc = node_texture_buts_proc;
+ ntype->draw_buttons = node_texture_buts_proc;
}
else {
switch (ntype->type) {
case TEX_NODE_MATH:
- ntype->uifunc = node_buts_math;
+ ntype->draw_buttons = node_buts_math;
break;
case TEX_NODE_MIX_RGB:
- ntype->uifunc = node_buts_mix_rgb;
+ ntype->draw_buttons = node_buts_mix_rgb;
break;
case TEX_NODE_VALTORGB:
- ntype->uifunc = node_buts_colorramp;
+ ntype->draw_buttons = node_buts_colorramp;
break;
case TEX_NODE_CURVE_RGB:
- ntype->uifunc = node_buts_curvecol;
+ ntype->draw_buttons = node_buts_curvecol;
break;
case TEX_NODE_CURVE_TIME:
- ntype->uifunc = node_buts_time;
+ ntype->draw_buttons = node_buts_time;
break;
case TEX_NODE_TEXTURE:
- ntype->uifunc = node_buts_texture;
+ ntype->draw_buttons = node_buts_texture;
break;
case TEX_NODE_BRICKS:
- ntype->uifunc = node_texture_buts_bricks;
+ ntype->draw_buttons = node_texture_buts_bricks;
break;
case TEX_NODE_IMAGE:
- ntype->uifunc = node_texture_buts_image;
- ntype->uifuncbut = node_texture_buts_image_details;
+ ntype->draw_buttons = node_texture_buts_image;
+ ntype->draw_buttons_ex = node_texture_buts_image_ex;
break;
case TEX_NODE_OUTPUT:
- ntype->uifunc = node_texture_buts_output;
+ ntype->draw_buttons = node_texture_buts_output;
break;
}
}
@@ -2736,14 +2693,12 @@ void ED_node_init_butfuncs(void)
extern bNodeSocketType NodeSocketTypeUndefined;
/* default ui functions */
- NodeTypeUndefined.drawfunc = node_draw_default;
- NodeTypeUndefined.drawupdatefunc = node_update_default;
+ NodeTypeUndefined.draw_nodetype = node_draw_default;
+ NodeTypeUndefined.draw_nodetype_prepare = node_update_default;
NodeTypeUndefined.select_area_func = node_select_area_default;
NodeTypeUndefined.tweak_area_func = node_tweak_area_default;
- NodeTypeUndefined.uifunc = NULL;
- NodeTypeUndefined.uifuncbut = NULL;
- NodeTypeUndefined.drawinputfunc = node_draw_input_default;
- NodeTypeUndefined.drawoutputfunc = node_draw_output_default;
+ NodeTypeUndefined.draw_buttons = NULL;
+ NodeTypeUndefined.draw_buttons_ex = NULL;
NodeTypeUndefined.resize_area_func = node_resize_area_default;
NodeSocketTypeUndefined.draw = node_socket_undefined_draw;
@@ -2754,14 +2709,12 @@ void ED_node_init_butfuncs(void)
/* node type ui functions */
NODE_TYPES_BEGIN(ntype)
/* default ui functions */
- ntype->drawfunc = node_draw_default;
- ntype->drawupdatefunc = node_update_default;
+ ntype->draw_nodetype = node_draw_default;
+ ntype->draw_nodetype_prepare = node_update_default;
ntype->select_area_func = node_select_area_default;
ntype->tweak_area_func = node_tweak_area_default;
- ntype->uifunc = NULL;
- ntype->uifuncbut = NULL;
- ntype->drawinputfunc = node_draw_input_default;
- ntype->drawoutputfunc = node_draw_output_default;
+ ntype->draw_buttons = NULL;
+ ntype->draw_buttons_ex = NULL;
ntype->resize_area_func = node_resize_area_default;
node_common_set_butfunc(ntype);
@@ -2783,10 +2736,8 @@ void ED_node_init_butfuncs(void)
void ED_init_custom_node_type(bNodeType *ntype)
{
/* default ui functions */
- ntype->drawfunc = node_draw_default;
- ntype->drawupdatefunc = node_update_default;
- ntype->drawinputfunc = node_draw_input_default;
- ntype->drawoutputfunc = node_draw_output_default;
+ ntype->draw_nodetype = node_draw_default;
+ ntype->draw_nodetype_prepare = node_update_default;
ntype->resize_area_func = node_resize_area_default;
ntype->select_area_func = node_select_area_default;
ntype->tweak_area_func = node_tweak_area_default;
@@ -2824,13 +2775,60 @@ static void std_node_socket_interface_draw_color(bContext *UNUSED(C), PointerRNA
copy_v4_v4(r_color, std_node_socket_colors[type]);
}
+/* draw function for file output node sockets, displays only sub-path and format, no value button */
+static void node_file_output_socket_draw(bContext *C, uiLayout *layout, PointerRNA *ptr, PointerRNA *node_ptr)
+{
+ bNodeTree *ntree = ptr->id.data;
+ bNodeSocket *sock = ptr->data;
+ uiLayout *row;
+ PointerRNA inputptr, imfptr;
+ int imtype;
+
+ row = uiLayoutRow(layout, FALSE);
+
+ imfptr = RNA_pointer_get(node_ptr, "format");
+ imtype = RNA_enum_get(&imfptr, "file_format");
+ if (imtype == R_IMF_IMTYPE_MULTILAYER) {
+ NodeImageMultiFileSocket *input = sock->storage;
+ RNA_pointer_create(&ntree->id, &RNA_NodeOutputFileSlotLayer, input, &inputptr);
+
+ uiItemL(row, input->layer, ICON_NONE);
+ }
+ else {
+ NodeImageMultiFileSocket *input = sock->storage;
+ PropertyRNA *imtype_prop;
+ const char *imtype_name;
+ uiBlock *block;
+ RNA_pointer_create(&ntree->id, &RNA_NodeOutputFileSlotFile, input, &inputptr);
+
+ uiItemL(row, input->path, ICON_NONE);
+
+ if (!RNA_boolean_get(&inputptr, "use_node_format"))
+ imfptr = RNA_pointer_get(&inputptr, "format");
+
+ imtype_prop = RNA_struct_find_property(&imfptr, "file_format");
+ RNA_property_enum_name((bContext *)C, &imfptr, imtype_prop,
+ RNA_property_enum_get(&imfptr, imtype_prop), &imtype_name);
+ block = uiLayoutGetBlock(row);
+ uiBlockSetEmboss(block, UI_EMBOSSP);
+ uiItemL(row, imtype_name, ICON_NONE);
+ uiBlockSetEmboss(block, UI_EMBOSSN);
+ }
+}
+
static void std_node_socket_draw(bContext *C, uiLayout *layout, PointerRNA *ptr, PointerRNA *node_ptr, const char *text)
{
+ bNode *node = node_ptr->data;
bNodeSocket *sock = ptr->data;
int type = sock->typeinfo->type;
/*int subtype = sock->typeinfo->subtype;*/
- if ((sock->flag & SOCK_IN_USE) || (sock->flag & SOCK_HIDE_VALUE)) {
+ /* XXX not nice, eventually give this node its own socket type ... */
+ if (node->type == CMP_NODE_OUTPUT_FILE) {
+ node_file_output_socket_draw(C, layout, ptr, node_ptr);
+ }
+
+ if ((sock->in_out == SOCK_OUT) || (sock->flag & SOCK_IN_USE) || (sock->flag & SOCK_HIDE_VALUE)) {
node_socket_button_label(C, layout, ptr, node_ptr, text);
return;
}
@@ -3043,8 +3041,8 @@ void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode, b
rctf *viewer_border = &snode->nodetree->viewer_border;
while (node) {
if (node->flag & NODE_SELECT) {
- if (node->typeinfo->uibackdropfunc) {
- node->typeinfo->uibackdropfunc(snode, ibuf, node, x, y);
+ if (node->typeinfo->draw_backdrop) {
+ node->typeinfo->draw_backdrop(snode, ibuf, node, x, y);
}
}
node = node->next;
diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c
index 29f796aecb1..65eb75f8523 100644
--- a/source/blender/editors/space_node/node_draw.c
+++ b/source/blender/editors/space_node/node_draw.c
@@ -351,7 +351,7 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node)
row = uiLayoutRow(layout, 1);
uiLayoutSetAlignment(row, UI_LAYOUT_ALIGN_RIGHT);
- node->typeinfo->drawoutputfunc((bContext *)C, row, &sockptr, &nodeptr);
+ nsock->typeinfo->draw((bContext *)C, row, &sockptr, &nodeptr, IFACE_(nsock->name));
uiBlockEndAlign(node->block);
uiBlockLayoutResolve(node->block, NULL, &buty);
@@ -402,7 +402,7 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node)
}
/* buttons rect? */
- if (node->typeinfo->uifunc && (node->flag & NODE_OPTIONS)) {
+ if (node->typeinfo->draw_buttons && (node->flag & NODE_OPTIONS)) {
dy -= NODE_DYS / 2;
/* set this for uifunc() that don't use layout engine yet */
@@ -416,7 +416,7 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node)
locx + NODE_DYS, dy, node->butr.xmax, 0, UI_GetStyle());
uiLayoutSetContextPointer(layout, "node", &nodeptr);
- node->typeinfo->uifunc(layout, (bContext *)C, &nodeptr);
+ node->typeinfo->draw_buttons(layout, (bContext *)C, &nodeptr);
uiBlockEndAlign(node->block);
uiBlockLayoutResolve(node->block, NULL, &buty);
@@ -437,7 +437,9 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node)
uiLayoutSetContextPointer(layout, "node", &nodeptr);
uiLayoutSetContextPointer(layout, "socket", &sockptr);
- node->typeinfo->drawinputfunc((bContext *)C, layout, &sockptr, &nodeptr);
+ row = uiLayoutRow(layout, 1);
+
+ nsock->typeinfo->draw((bContext *)C, row, &sockptr, &nodeptr, IFACE_(nsock->name));
uiBlockEndAlign(node->block);
uiBlockLayoutResolve(node->block, NULL, &buty);
@@ -1115,8 +1117,8 @@ void node_draw_default(const bContext *C, ARegion *ar, SpaceNode *snode, bNodeTr
static void node_update(const bContext *C, bNodeTree *ntree, bNode *node)
{
- if (node->typeinfo->drawupdatefunc)
- node->typeinfo->drawupdatefunc(C, ntree, node);
+ if (node->typeinfo->draw_nodetype_prepare)
+ node->typeinfo->draw_nodetype_prepare(C, ntree, node);
}
void node_update_nodetree(const bContext *C, bNodeTree *ntree)
@@ -1131,8 +1133,8 @@ void node_update_nodetree(const bContext *C, bNodeTree *ntree)
static void node_draw(const bContext *C, ARegion *ar, SpaceNode *snode, bNodeTree *ntree, bNode *node, bNodeInstanceKey key)
{
- if (node->typeinfo->drawfunc)
- node->typeinfo->drawfunc(C, ar, snode, ntree, node, key);
+ if (node->typeinfo->draw_nodetype)
+ node->typeinfo->draw_nodetype(C, ar, snode, ntree, node, key);
}
#define USE_DRAW_TOT_UPDATE
@@ -1241,7 +1243,7 @@ static void draw_group_overlay(const bContext *C, ARegion *ar)
/* shade node groups to separate them visually */
UI_ThemeColorShadeAlpha(TH_NODE_GROUP, 0, -70);
glEnable(GL_BLEND);
- uiSetRoundBox(0);
+ uiSetRoundBox(UI_CNR_NONE);
uiDrawBox(GL_POLYGON, rect.xmin, rect.ymin, rect.xmax, rect.ymax, 0);
glDisable(GL_BLEND);
diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c
index ff6a8e884a6..1d93fe65c09 100644
--- a/source/blender/editors/space_node/node_edit.c
+++ b/source/blender/editors/space_node/node_edit.c
@@ -1419,7 +1419,7 @@ static void node_flag_toggle_exec(SpaceNode *snode, int toggle_flag)
if (toggle_flag == NODE_PREVIEW && (node->typeinfo->flag & NODE_PREVIEW) == 0)
continue;
- if (toggle_flag == NODE_OPTIONS && !(node->typeinfo->uifunc || node->typeinfo->uifuncbut))
+ if (toggle_flag == NODE_OPTIONS && !(node->typeinfo->draw_buttons || node->typeinfo->draw_buttons_ex))
continue;
if (node->flag & toggle_flag)
@@ -1433,7 +1433,7 @@ static void node_flag_toggle_exec(SpaceNode *snode, int toggle_flag)
if (toggle_flag == NODE_PREVIEW && (node->typeinfo->flag & NODE_PREVIEW) == 0)
continue;
- if (toggle_flag == NODE_OPTIONS && !(node->typeinfo->uifunc || node->typeinfo->uifuncbut))
+ if (toggle_flag == NODE_OPTIONS && !(node->typeinfo->draw_buttons || node->typeinfo->draw_buttons_ex))
continue;
if ((tot_eq && tot_neq) || tot_eq == 0)
@@ -1731,7 +1731,7 @@ static int node_output_file_add_socket_exec(bContext *C, wmOperator *op)
node = nodeGetActive(snode->edittree);
}
- if (!node)
+ if (!node || node->type != CMP_NODE_OUTPUT_FILE)
return OPERATOR_CANCELLED;
RNA_string_get(op->ptr, "file_path", file_path);
@@ -1777,7 +1777,7 @@ static int node_output_file_remove_active_socket_exec(bContext *C, wmOperator *U
node = nodeGetActive(snode->edittree);
}
- if (!node)
+ if (!node || node->type != CMP_NODE_OUTPUT_FILE)
return OPERATOR_CANCELLED;
if (!ntreeCompositOutputFileRemoveActiveSocket(ntree, node))
@@ -1819,7 +1819,7 @@ static int node_output_file_move_active_socket_exec(bContext *C, wmOperator *op)
else if (snode && snode->edittree)
node = nodeGetActive(snode->edittree);
- if (!node)
+ if (!node || node->type != CMP_NODE_OUTPUT_FILE)
return OPERATOR_CANCELLED;
nimf = node->storage;
diff --git a/source/blender/editors/space_node/node_templates.c b/source/blender/editors/space_node/node_templates.c
index 83c11e69d84..a67a8791a64 100644
--- a/source/blender/editors/space_node/node_templates.c
+++ b/source/blender/editors/space_node/node_templates.c
@@ -207,7 +207,7 @@ static void node_socket_add_replace(const bContext *C, bNodeTree *ntree, bNode *
break;
if (node_from)
- if (node_from->inputs.first || node_from->typeinfo->uifunc || node_from->typeinfo->uifuncbut)
+ if (node_from->inputs.first || node_from->typeinfo->draw_buttons || node_from->typeinfo->draw_buttons_ex)
node_from = NULL;
if (node_prev && node_prev->type == type && node_link_item_compare(node_prev, item)) {
@@ -586,13 +586,13 @@ static void ui_node_draw_node(uiLayout *layout, bContext *C, bNodeTree *ntree, b
RNA_pointer_create(&ntree->id, &RNA_Node, node, &nodeptr);
- if (node->typeinfo->uifunc) {
+ if (node->typeinfo->draw_buttons) {
if (node->type != NODE_GROUP) {
split = uiLayoutSplit(layout, 0.35f, FALSE);
col = uiLayoutColumn(split, FALSE);
col = uiLayoutColumn(split, FALSE);
- node->typeinfo->uifunc(col, C, &nodeptr);
+ node->typeinfo->draw_buttons(col, C, &nodeptr);
}
}
@@ -639,7 +639,7 @@ static void ui_node_draw_input(uiLayout *layout, bContext *C, bNodeTree *ntree,
if (depth > 0) {
uiBlockSetEmboss(block, UI_EMBOSSN);
- if (lnode && (lnode->inputs.first || (lnode->typeinfo->uifunc && lnode->type != NODE_GROUP))) {
+ if (lnode && (lnode->inputs.first || (lnode->typeinfo->draw_buttons && lnode->type != NODE_GROUP))) {
int icon = (input->flag & SOCK_COLLAPSED) ? ICON_DISCLOSURE_TRI_RIGHT : ICON_DISCLOSURE_TRI_DOWN;
uiItemR(row, &inputptr, "show_expanded", UI_ITEM_R_ICON_ONLY, "", icon);
}
diff --git a/source/blender/editors/space_node/node_view.c b/source/blender/editors/space_node/node_view.c
index e4a9c4fa5db..f889a8ec97b 100644
--- a/source/blender/editors/space_node/node_view.c
+++ b/source/blender/editors/space_node/node_view.c
@@ -373,7 +373,7 @@ void NODE_OT_backimage_fit(wmOperatorType *ot)
/* identifiers */
ot->name = "Background Image Fit";
ot->idname = "NODE_OT_backimage_fit";
- ot->description = "Zoom in/out the background image";
+ ot->description = "Fit the background image to the view";
/* api callbacks */
ot->exec = backimage_fit_exec;
diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c
index b86fba1398a..10890a305fb 100644
--- a/source/blender/editors/space_outliner/outliner_tree.c
+++ b/source/blender/editors/space_outliner/outliner_tree.c
@@ -384,17 +384,21 @@ static void outliner_add_line_styles(SpaceOops *soops, ListBase *lb, Scene *sce,
for (srl = sce->r.layers.first; srl; srl = srl->next) {
for (lineset = srl->freestyleConfig.linesets.first; lineset; lineset = lineset->next) {
- lineset->linestyle->id.flag |= LIB_DOIT;
+ FreestyleLineStyle *linestyle = lineset->linestyle;
+ if (linestyle) {
+ linestyle->id.flag |= LIB_DOIT;
+ }
}
}
for (srl = sce->r.layers.first; srl; srl = srl->next) {
for (lineset = srl->freestyleConfig.linesets.first; lineset; lineset = lineset->next) {
FreestyleLineStyle *linestyle = lineset->linestyle;
-
- if (!(linestyle->id.flag & LIB_DOIT))
- continue;
- linestyle->id.flag &= ~LIB_DOIT;
- outliner_add_element(soops, lb, linestyle, te, 0, 0);
+ if (linestyle) {
+ if (!(linestyle->id.flag & LIB_DOIT))
+ continue;
+ linestyle->id.flag &= ~LIB_DOIT;
+ outliner_add_element(soops, lb, linestyle, te, 0, 0);
+ }
}
}
}
diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c
index ebec818bb36..cb69a7fe654 100644
--- a/source/blender/editors/space_sequencer/sequencer_draw.c
+++ b/source/blender/editors/space_sequencer/sequencer_draw.c
@@ -926,13 +926,13 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
/* stop all running jobs, except screen one. currently previews frustrate Render
* needed to make so sequencer's rendering doesn't conflict with compositor
*/
- WM_jobs_kill_type(CTX_wm_manager(C), WM_JOB_TYPE_COMPOSITE);
+ WM_jobs_kill_type(CTX_wm_manager(C), NULL, WM_JOB_TYPE_COMPOSITE);
if ((scene->r.seq_flag & R_SEQ_GL_PREV) == 0) {
/* in case of final rendering used for preview, kill all previews,
* otherwise threading conflict will happen in rendering module
*/
- WM_jobs_kill_type(CTX_wm_manager(C), WM_JOB_TYPE_RENDER_PREVIEW);
+ WM_jobs_kill_type(CTX_wm_manager(C), NULL, WM_JOB_TYPE_RENDER_PREVIEW);
}
}
@@ -1251,7 +1251,7 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
height = (scene->r.size * scene->r.ysch) / 100;
ED_mask_draw_region(mask, ar,
- 0, 0, /* TODO */
+ 0, 0, 0, /* TODO */
width, height,
aspx, aspy,
FALSE, TRUE,
diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c
index d8b4824b528..8b2e7067eb9 100644
--- a/source/blender/editors/space_sequencer/sequencer_edit.c
+++ b/source/blender/editors/space_sequencer/sequencer_edit.c
@@ -2960,7 +2960,7 @@ void SEQUENCER_OT_view_ghost_border(wmOperatorType *ot)
/* identifiers */
ot->name = "Border Offset View";
ot->idname = "SEQUENCER_OT_view_ghost_border";
- ot->description = "Enable border select mode";
+ ot->description = "Set the boundaries of the border used for offset-view";
/* api callbacks */
ot->invoke = WM_border_select_invoke;
diff --git a/source/blender/editors/space_sequencer/sequencer_modifier.c b/source/blender/editors/space_sequencer/sequencer_modifier.c
index 51df21e509a..c8fd6e4b6ea 100644
--- a/source/blender/editors/space_sequencer/sequencer_modifier.c
+++ b/source/blender/editors/space_sequencer/sequencer_modifier.c
@@ -99,7 +99,7 @@ void SEQUENCER_OT_strip_modifier_add(wmOperatorType *ot)
/* identifiers */
ot->name = "Add Strip Modifier";
ot->idname = "SEQUENCER_OT_strip_modifier_add";
- ot->description = "Add a modifier to strip";
+ ot->description = "Add a modifier to the strip";
/* api callbacks */
ot->exec = strip_modifier_add_exec;
@@ -142,7 +142,7 @@ void SEQUENCER_OT_strip_modifier_remove(wmOperatorType *ot)
/* identifiers */
ot->name = "Remove Strip Modifier";
ot->idname = "SEQUENCER_OT_strip_modifier_remove";
- ot->description = "Add a modifier to strip";
+ ot->description = "Remove a modifier from the strip";
/* api callbacks */
ot->exec = strip_modifier_remove_exec;
diff --git a/source/blender/editors/space_sequencer/sequencer_select.c b/source/blender/editors/space_sequencer/sequencer_select.c
index 254d15341cd..45f05d56076 100644
--- a/source/blender/editors/space_sequencer/sequencer_select.c
+++ b/source/blender/editors/space_sequencer/sequencer_select.c
@@ -892,7 +892,7 @@ void SEQUENCER_OT_select_border(wmOperatorType *ot)
/* identifiers */
ot->name = "Border Select";
ot->idname = "SEQUENCER_OT_select_border";
- ot->description = "Enable border select mode";
+ ot->description = "Select strips using border selection";
/* api callbacks */
ot->invoke = WM_border_select_invoke;
diff --git a/source/blender/editors/space_sequencer/sequencer_view.c b/source/blender/editors/space_sequencer/sequencer_view.c
index 18733d4e409..deb37f8d943 100644
--- a/source/blender/editors/space_sequencer/sequencer_view.c
+++ b/source/blender/editors/space_sequencer/sequencer_view.c
@@ -220,7 +220,8 @@ static int sample_cancel(bContext *C, wmOperator *op)
static int sample_poll(bContext *C)
{
- return BKE_sequencer_editing_get(CTX_data_scene(C), FALSE) != NULL;
+ SpaceSeq *sseq = CTX_wm_space_seq(C);
+ return sseq && BKE_sequencer_editing_get(CTX_data_scene(C), FALSE) != NULL;
}
void SEQUENCER_OT_sample(wmOperatorType *ot)
diff --git a/source/blender/editors/space_text/space_text.c b/source/blender/editors/space_text/space_text.c
index b04d2b16e8d..c668c8063a8 100644
--- a/source/blender/editors/space_text/space_text.c
+++ b/source/blender/editors/space_text/space_text.c
@@ -309,6 +309,8 @@ static void text_keymap(struct wmKeyConfig *keyconf)
RNA_boolean_set(kmi->ptr, "selection", TRUE);
}
+ WM_keymap_add_item(keymap, "TEXT_OT_properties", TKEY, KM_PRESS, KM_CTRL, 0);
+
WM_keymap_add_item(keymap, "TEXT_OT_jump", JKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "TEXT_OT_find", GKEY, KM_PRESS, KM_CTRL, 0);
diff --git a/source/blender/editors/space_text/text_autocomplete.c b/source/blender/editors/space_text/text_autocomplete.c
index ba61399f6d5..eaba537c0a8 100644
--- a/source/blender/editors/space_text/text_autocomplete.c
+++ b/source/blender/editors/space_text/text_autocomplete.c
@@ -361,6 +361,7 @@ static int text_autocomplete_modal(bContext *C, wmOperator *op, const wmEvent *e
}
break;
case RETKEY:
+ case PADENTER:
if (event->val == KM_PRESS) {
if (tools & TOOL_SUGG_LIST) {
confirm_suggestion(st->text);
diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c
index 2c2a8b255da..c078e612d68 100644
--- a/source/blender/editors/space_text/text_ops.c
+++ b/source/blender/editors/space_text/text_ops.c
@@ -1943,7 +1943,7 @@ void TEXT_OT_move_select(wmOperatorType *ot)
/* identifiers */
ot->name = "Move Select";
ot->idname = "TEXT_OT_move_select";
- ot->description = "Make selection from current cursor position to new cursor position type";
+ ot->description = "Move the cursor while selecting";
/* api callbacks */
ot->exec = text_move_select_exec;
@@ -2291,7 +2291,7 @@ void TEXT_OT_scroll(wmOperatorType *ot)
* scroll_bar. Both do basically the same thing (aside
* from keymaps).*/
ot->idname = "TEXT_OT_scroll";
- ot->description = "Scroll text screen";
+ ot->description = "";
/* api callbacks */
ot->exec = text_scroll_exec;
@@ -2301,7 +2301,7 @@ void TEXT_OT_scroll(wmOperatorType *ot)
ot->poll = text_scroll_poll;
/* flags */
- ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_POINTER;
+ ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_POINTER | OPTYPE_INTERNAL;
/* properties */
RNA_def_int(ot->srna, "lines", 1, INT_MIN, INT_MAX, "Lines", "Number of lines to scroll", -100, 100);
@@ -2385,7 +2385,7 @@ void TEXT_OT_scroll_bar(wmOperatorType *ot)
* scroll. Both do basically the same thing (aside
* from keymaps).*/
ot->idname = "TEXT_OT_scroll_bar";
- ot->description = "Scroll text screen";
+ ot->description = "";
/* api callbacks */
ot->invoke = text_scroll_bar_invoke;
@@ -2394,7 +2394,7 @@ void TEXT_OT_scroll_bar(wmOperatorType *ot)
ot->poll = text_region_scroll_poll;
/* flags */
- ot->flag = OPTYPE_BLOCKING;
+ ot->flag = OPTYPE_BLOCKING | OPTYPE_INTERNAL;
/* properties */
RNA_def_int(ot->srna, "lines", 1, INT_MIN, INT_MAX, "Lines", "Number of lines to scroll", -100, 100);
diff --git a/source/blender/editors/space_view3d/drawarmature.c b/source/blender/editors/space_view3d/drawarmature.c
index 2634dd3ec08..de6fafb2cd8 100644
--- a/source/blender/editors/space_view3d/drawarmature.c
+++ b/source/blender/editors/space_view3d/drawarmature.c
@@ -304,7 +304,7 @@ static void set_ebone_glColor(const unsigned int boneflag)
/* *************** Armature drawing, helper calls for parts ******************* */
/* half the cube, in Y */
-static float cube[8][3] = {
+static const float cube[8][3] = {
{-1.0, 0.0, -1.0},
{-1.0, 0.0, 1.0},
{-1.0, 1.0, 1.0},
@@ -440,7 +440,7 @@ static void draw_bonevert_solid(void)
glCallList(displist);
}
-static float bone_octahedral_verts[6][3] = {
+static const float bone_octahedral_verts[6][3] = {
{ 0.0f, 0.0f, 0.0f},
{ 0.1f, 0.1f, 0.1f},
{ 0.1f, 0.1f, -0.1f},
@@ -449,10 +449,10 @@ static float bone_octahedral_verts[6][3] = {
{ 0.0f, 1.0f, 0.0f}
};
-static unsigned int bone_octahedral_wire_sides[8] = {0, 1, 5, 3, 0, 4, 5, 2};
-static unsigned int bone_octahedral_wire_square[8] = {1, 2, 3, 4, 1};
+static const unsigned int bone_octahedral_wire_sides[8] = {0, 1, 5, 3, 0, 4, 5, 2};
+static const unsigned int bone_octahedral_wire_square[8] = {1, 2, 3, 4, 1};
-static unsigned int bone_octahedral_solid_tris[8][3] = {
+static const unsigned int bone_octahedral_solid_tris[8][3] = {
{2, 1, 0}, /* bottom */
{3, 2, 0},
{4, 3, 0},
@@ -465,7 +465,7 @@ static unsigned int bone_octahedral_solid_tris[8][3] = {
};
/* aligned with bone_octahedral_solid_tris */
-static float bone_octahedral_solid_normals[8][3] = {
+static const float bone_octahedral_solid_normals[8][3] = {
{ 0.70710683f, -0.70710683f, 0.00000000f},
{-0.00000000f, -0.70710683f, -0.70710683f},
{-0.70710683f, -0.70710683f, 0.00000000f},
@@ -599,7 +599,7 @@ static void draw_bone_points(const short dt, int armflag, unsigned int boneflag,
}
/* 16 values of sin function (still same result!) */
-static float si[16] = {
+static const float si[16] = {
0.00000000f,
0.20129852f, 0.39435585f,
0.57126821f, 0.72479278f,
@@ -611,7 +611,7 @@ static float si[16] = {
0.10116832f
};
/* 16 values of cos function (still same result!) */
-static float co[16] = {
+static const float co[16] = {
1.00000000f,
0.97952994f, 0.91895781f,
0.82076344f, 0.68896691f,
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index dc751599c46..612e0fde194 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -2043,7 +2043,7 @@ static void draw_dm_face_normals__mapFunc(void *userData, int index, const float
if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
if (!data->uniform_scale) {
- mul_v3_m3v3(n, data->tmat, (float *) no);
+ mul_v3_m3v3(n, data->tmat, no);
normalize_v3(n);
mul_m3_v3(data->imat, n);
}
@@ -2108,7 +2108,7 @@ static void draw_dm_vert_normals__mapFunc(void *userData, int index, const float
}
if (!data->uniform_scale) {
- mul_v3_m3v3(n, data->tmat, (float *) no);
+ mul_v3_m3v3(n, data->tmat, no);
normalize_v3(n);
mul_m3_v3(data->imat, n);
}
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index f397e869882..9f3da9250cc 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -44,6 +44,7 @@
#include "BKE_context.h"
#include "BKE_icons.h"
+#include "BKE_main.h"
#include "BKE_object.h"
#include "BKE_screen.h"
@@ -258,6 +259,25 @@ void ED_view3d_check_mats_rv3d(struct RegionView3D *rv3d)
}
#endif
+void ED_view3d_shade_update(Main *bmain, View3D *v3d, ScrArea *sa)
+{
+ wmWindowManager *wm = bmain->wm.first;
+
+ if (v3d->drawtype != OB_RENDER) {
+ ARegion *ar;
+
+ for (ar = sa->regionbase.first; ar; ar = ar->next) {
+ RegionView3D *rv3d = ar->regiondata;
+
+ if (rv3d && rv3d->render_engine) {
+ WM_jobs_kill_type(wm, ar, WM_JOB_TYPE_RENDER_PREVIEW);
+ RE_engine_free(rv3d->render_engine);
+ rv3d->render_engine = NULL;
+ }
+ }
+ }
+}
+
/* ******************** default callbacks for view3d space ***************** */
static SpaceLink *view3d_new(const bContext *C)
diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c
index 75e7605df6b..eea084b4750 100644
--- a/source/blender/editors/space_view3d/view3d_buttons.c
+++ b/source/blender/editors/space_view3d/view3d_buttons.c
@@ -682,7 +682,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
}
}
BKE_nurb_test2D(nu);
- BKE_nurb_handles_test(nu); /* test for bezier too */
+ BKE_nurb_handles_test(nu, true); /* test for bezier too */
nu = nu->next;
}
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index cafefb2a769..215d2b387d7 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -113,9 +113,9 @@ static void star_stuff_init_func(void)
glPointSize(1.0);
glBegin(GL_POINTS);
}
-static void star_stuff_vertex_func(float *i)
+static void star_stuff_vertex_func(const float vec[3])
{
- glVertex3fv(i);
+ glVertex3fv(vec);
}
static void star_stuff_term_func(void)
{
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index 5686c500270..67c9ea4599c 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -85,26 +85,23 @@
/* for ndof prints */
// #define DEBUG_NDOF_MOTION
-static void view3d_offset_lock_report(ReportList *reports)
-{
- BKE_report(reports, RPT_WARNING, "View offset is locked");
-}
-
bool ED_view3d_offset_lock_check(struct View3D *v3d, struct RegionView3D *rv3d)
{
return (rv3d->persp != RV3D_CAMOB) && (v3d->ob_centre_cursor || v3d->ob_centre);
}
-#define VIEW3D_OP_OFS_LOCK_TEST(C, op) \
- { \
- View3D *v3d_tmp = CTX_wm_view3d(C); \
- RegionView3D *rv3d_tmp = CTX_wm_region_view3d(C); \
- if (ED_view3d_offset_lock_check(v3d_tmp, rv3d_tmp)) { \
- view3d_offset_lock_report((op)->reports); \
- return OPERATOR_CANCELLED; \
- } \
- } (void)0
-
+static bool view3d_operator_offset_lock_check(bContext *C, wmOperator *op)
+{
+ View3D *v3d = CTX_wm_view3d(C);
+ RegionView3D *rv3d = CTX_wm_region_view3d(C);
+ if (ED_view3d_offset_lock_check(v3d, rv3d)) {
+ BKE_report(op->reports, RPT_WARNING, "View offset is locked");
+ return true;
+ }
+ else {
+ return false;
+ }
+}
/* ********************** view3d_edit: view manipulations ********************* */
@@ -182,6 +179,27 @@ bool ED_view3d_camera_lock_sync(View3D *v3d, RegionView3D *rv3d)
}
}
+/**
+ * For viewport operators that exit camera persp.
+ *
+ * \note This differs from simply setting ``rv3d->persp = persp`` because it
+ * sets the ``ofs`` and ``dist`` values of the viewport so it matches the camera,
+ * otherwise switching out of camera view may jump to a different part of the scene.
+ */
+static void view3d_persp_switch_from_camera(View3D *v3d, RegionView3D *rv3d, const char persp)
+{
+ BLI_assert(rv3d->persp == RV3D_CAMOB);
+ BLI_assert(persp != RV3D_CAMOB);
+
+ if (v3d->camera) {
+ rv3d->dist = ED_view3d_offset_distance(v3d->camera->obmat, rv3d->ofs, VIEW3D_DIST_FALLBACK);
+ ED_view3d_from_object(v3d->camera, rv3d->ofs, rv3d->viewquat, &rv3d->dist, NULL);
+ }
+
+ if (!ED_view3d_camera_lock_check(v3d, rv3d)) {
+ rv3d->persp = persp;
+ }
+}
/* ********************* box view support ***************** */
@@ -378,6 +396,7 @@ void ED_view3d_quadview_update(ScrArea *sa, ARegion *ar, bool do_clip)
/* ************************** init for view ops **********************************/
typedef struct ViewOpsData {
+ /* context pointers (assigned by viewops_data_alloc) */
ScrArea *sa;
ARegion *ar;
View3D *v3d;
@@ -435,10 +454,17 @@ static void calctrackballvec(const rcti *rect, int mx, int my, float vec[3])
}
-static void viewops_data_create(bContext *C, wmOperator *op, const wmEvent *event)
+/* -------------------------------------------------------------------- */
+/* ViewOpsData */
+
+/** \name Generic View Operator Custom-Data.
+ * \{ */
+
+/**
+ * Allocate and fill in context pointers for #ViewOpsData
+ */
+static void viewops_data_alloc(bContext *C, wmOperator *op)
{
- static float lastofs[3] = {0, 0, 0};
- RegionView3D *rv3d;
ViewOpsData *vod = MEM_callocN(sizeof(ViewOpsData), "viewops data");
/* store data */
@@ -446,7 +472,17 @@ static void viewops_data_create(bContext *C, wmOperator *op, const wmEvent *even
vod->sa = CTX_wm_area(C);
vod->ar = CTX_wm_region(C);
vod->v3d = vod->sa->spacedata.first;
- vod->rv3d = rv3d = vod->ar->regiondata;
+ vod->rv3d = vod->ar->regiondata;
+}
+
+/**
+ * Calculate the values for #ViewOpsData
+ */
+static void viewops_data_create(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ ViewOpsData *vod = op->customdata;
+ static float lastofs[3] = {0, 0, 0};
+ RegionView3D *rv3d = vod->rv3d;
/* set the view from the camera, if view locking is enabled.
* we may want to make this optional but for now its needed always */
@@ -589,6 +625,8 @@ static void viewops_data_free(bContext *C, wmOperator *op)
if (p && (p->flags & PAINT_FAST_NAVIGATE))
ED_region_tag_redraw(ar);
}
+/** \} */
+
/* ************************** viewrotate **********************************/
@@ -941,37 +979,27 @@ static int viewrotate_modal(bContext *C, wmOperator *op, const wmEvent *event)
static int viewrotate_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ViewOpsData *vod;
- RegionView3D *rv3d;
/* makes op->customdata */
+ viewops_data_alloc(C, op);
viewops_data_create(C, op, event);
vod = op->customdata;
- rv3d = vod->rv3d;
- if (rv3d->viewlock) { /* poll should check but in some cases fails, see poll func for details */
+ if (vod->rv3d->viewlock) { /* poll should check but in some cases fails, see poll func for details */
viewops_data_free(C, op);
return OPERATOR_PASS_THROUGH;
}
/* switch from camera view when: */
- if (rv3d->persp != RV3D_PERSP) {
+ if (vod->rv3d->persp != RV3D_PERSP) {
if (U.uiflag & USER_AUTOPERSP) {
if (!ED_view3d_camera_lock_check(vod->v3d, vod->rv3d)) {
- rv3d->persp = RV3D_PERSP;
+ vod->rv3d->persp = RV3D_PERSP;
}
}
- else if (rv3d->persp == RV3D_CAMOB) {
-
- /* changed since 2.4x, use the camera view */
- if (vod->v3d->camera) {
- rv3d->dist = ED_view3d_offset_distance(vod->v3d->camera->obmat, rv3d->ofs, VIEW3D_DIST_FALLBACK);
- ED_view3d_from_object(vod->v3d->camera, rv3d->ofs, rv3d->viewquat, &rv3d->dist, NULL);
- }
-
- if (!ED_view3d_camera_lock_check(vod->v3d, vod->rv3d)) {
- rv3d->persp = rv3d->lpersp;
- }
+ else if (vod->rv3d->persp == RV3D_CAMOB) {
+ view3d_persp_switch_from_camera(vod->v3d, vod->rv3d, vod->rv3d->lpersp);
}
ED_region_tag_redraw(vod->ar);
}
@@ -983,7 +1011,7 @@ static int viewrotate_invoke(bContext *C, wmOperator *op, const wmEvent *event)
else
viewrotate_apply(vod, event->prevx, event->prevy);
- ED_view3d_depth_tag_update(rv3d);
+ ED_view3d_depth_tag_update(vod->rv3d);
viewops_data_free(C, op);
@@ -992,7 +1020,7 @@ static int viewrotate_invoke(bContext *C, wmOperator *op, const wmEvent *event)
else if (event->type == MOUSEROTATE) {
/* MOUSEROTATE performs orbital rotation, so y axis delta is set to 0 */
viewrotate_apply(vod, event->prevx, event->y);
- ED_view3d_depth_tag_update(rv3d);
+ ED_view3d_depth_tag_update(vod->rv3d);
viewops_data_free(C, op);
@@ -1160,8 +1188,9 @@ static void view3d_ndof_orbit(const struct wmNDOFMotionData *ndof, RegionView3D
static int ndof_orbit_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- if (event->type != NDOF_MOTION)
+ if (event->type != NDOF_MOTION) {
return OPERATOR_CANCELLED;
+ }
else {
View3D *v3d = CTX_wm_view3d(C);
ViewOpsData *vod;
@@ -1170,6 +1199,7 @@ static int ndof_orbit_invoke(bContext *C, wmOperator *op, const wmEvent *event)
ED_view3d_camera_lock_init(v3d, rv3d);
+ viewops_data_alloc(C, op);
viewops_data_create(C, op, event);
vod = op->customdata;
@@ -1227,7 +1257,7 @@ void VIEW3D_OT_ndof_orbit(struct wmOperatorType *ot)
{
/* identifiers */
ot->name = "NDOF Orbit View";
- ot->description = "Explore every angle of an object using the 3D mouse";
+ ot->description = "Orbit the view using the 3D mouse";
ot->idname = "VIEW3D_OT_ndof_orbit";
/* api callbacks */
@@ -1242,8 +1272,9 @@ void VIEW3D_OT_ndof_orbit(struct wmOperatorType *ot)
static int ndof_orbit_zoom_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- if (event->type != NDOF_MOTION)
+ if (event->type != NDOF_MOTION) {
return OPERATOR_CANCELLED;
+ }
else {
ViewOpsData *vod;
View3D *v3d = CTX_wm_view3d(C);
@@ -1254,6 +1285,7 @@ static int ndof_orbit_zoom_invoke(bContext *C, wmOperator *op, const wmEvent *ev
rv3d->rot_angle = 0.f; /* off by default, until changed later this function */
+ viewops_data_alloc(C, op);
viewops_data_create(C, op, event);
vod = op->customdata;
@@ -1323,7 +1355,7 @@ void VIEW3D_OT_ndof_orbit_zoom(struct wmOperatorType *ot)
{
/* identifiers */
ot->name = "NDOF Orbit View with Zoom";
- ot->description = "Explore every angle of an object using the 3D mouse";
+ ot->description = "Orbit and zoom the view using the 3D mouse";
ot->idname = "VIEW3D_OT_ndof_orbit_zoom";
/* api callbacks */
@@ -1339,14 +1371,16 @@ void VIEW3D_OT_ndof_orbit_zoom(struct wmOperatorType *ot)
*/
static int ndof_pan_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- if (event->type != NDOF_MOTION)
+ if (event->type != NDOF_MOTION) {
return OPERATOR_CANCELLED;
+ }
else {
View3D *v3d = CTX_wm_view3d(C);
RegionView3D *rv3d = CTX_wm_region_view3d(C);
wmNDOFMotionData *ndof = (wmNDOFMotionData *) event->customdata;
- VIEW3D_OP_OFS_LOCK_TEST(C, op);
+ if (view3d_operator_offset_lock_check(C, op))
+ return OPERATOR_CANCELLED;
ED_view3d_camera_lock_init(v3d, rv3d);
@@ -1418,7 +1452,7 @@ void VIEW3D_OT_ndof_pan(struct wmOperatorType *ot)
{
/* identifiers */
ot->name = "NDOF Pan View";
- ot->description = "Position your viewpoint with the 3D mouse";
+ ot->description = "Pan the view with the 3D mouse";
ot->idname = "VIEW3D_OT_ndof_pan";
/* api callbacks */
@@ -1439,13 +1473,13 @@ static int ndof_all_invoke(bContext *C, wmOperator *op, const wmEvent *event)
return OPERATOR_CANCELLED;
}
else {
-
ViewOpsData *vod;
RegionView3D *rv3d;
View3D *v3d = CTX_wm_view3d(C);
wmNDOFMotionData *ndof = (wmNDOFMotionData *) event->customdata;
+ viewops_data_alloc(C, op);
viewops_data_create(C, op, event);
vod = op->customdata;
rv3d = vod->rv3d;
@@ -1509,7 +1543,7 @@ void VIEW3D_OT_ndof_all(struct wmOperatorType *ot)
{
/* identifiers */
ot->name = "NDOF Move View";
- ot->description = "Position your viewpoint with the 3D mouse";
+ ot->description = "Pan and rotate the view with the 3D mouse";
ot->idname = "VIEW3D_OT_ndof_all";
/* api callbacks */
@@ -1644,6 +1678,7 @@ static int viewmove_invoke(bContext *C, wmOperator *op, const wmEvent *event)
ViewOpsData *vod;
/* makes op->customdata */
+ viewops_data_alloc(C, op);
viewops_data_create(C, op, event);
vod = op->customdata;
@@ -2010,6 +2045,7 @@ static int viewzoom_invoke(bContext *C, wmOperator *op, const wmEvent *event)
ViewOpsData *vod;
/* makes op->customdata */
+ viewops_data_alloc(C, op);
viewops_data_create(C, op, event);
vod = op->customdata;
@@ -2224,12 +2260,34 @@ static int viewdolly_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ViewOpsData *vod;
- VIEW3D_OP_OFS_LOCK_TEST(C, op);
+ if (view3d_operator_offset_lock_check(C, op))
+ return OPERATOR_CANCELLED;
/* makes op->customdata */
- viewops_data_create(C, op, event);
+ viewops_data_alloc(C, op);
vod = op->customdata;
+ if (vod->rv3d->viewlock) { /* poll should check but in some cases fails, see poll func for details */
+ viewops_data_free(C, op);
+ return OPERATOR_PASS_THROUGH;
+ }
+
+ /* needs to run before 'viewops_data_create' so the backup 'rv3d->ofs' is correct */
+ /* switch from camera view when: */
+ if (vod->rv3d->persp != RV3D_PERSP) {
+ if (vod->rv3d->persp == RV3D_CAMOB) {
+ /* ignore rv3d->lpersp because dolly only makes sense in perspective mode */
+ view3d_persp_switch_from_camera(vod->v3d, vod->rv3d, RV3D_PERSP);
+ }
+ else {
+ vod->rv3d->persp = RV3D_PERSP;
+ }
+ ED_region_tag_redraw(vod->ar);
+ }
+
+ viewops_data_create(C, op, event);
+
+
/* if one or the other zoom position aren't set, set from event */
if (!RNA_struct_property_is_set(op->ptr, "mx") || !RNA_struct_property_is_set(op->ptr, "my")) {
RNA_int_set(op->ptr, "mx", event->x);
@@ -2274,25 +2332,6 @@ static int viewdolly_invoke(bContext *C, wmOperator *op, const wmEvent *event)
return OPERATOR_FINISHED;
}
-/* like ED_operator_region_view3d_active but check its not in ortho view */
-static int viewdolly_poll(bContext *C)
-{
- RegionView3D *rv3d = CTX_wm_region_view3d(C);
-
- if (rv3d) {
- if (rv3d->persp == RV3D_PERSP) {
- return 1;
- }
- else {
- View3D *v3d = CTX_wm_view3d(C);
- if (ED_view3d_camera_lock_check(v3d, rv3d)) {
- return 1;
- }
- }
- }
- return 0;
-}
-
static int viewdolly_cancel(bContext *C, wmOperator *op)
{
viewops_data_free(C, op);
@@ -2311,7 +2350,7 @@ void VIEW3D_OT_dolly(wmOperatorType *ot)
ot->invoke = viewdolly_invoke;
ot->exec = viewdolly_exec;
ot->modal = viewdolly_modal;
- ot->poll = viewdolly_poll;
+ ot->poll = ED_operator_region_view3d_active;
ot->cancel = viewdolly_cancel;
/* flags */
@@ -3703,6 +3742,7 @@ static int viewroll_invoke(bContext *C, wmOperator *op, const wmEvent *event)
ViewOpsData *vod;
/* makes op->customdata */
+ viewops_data_alloc(C, op);
viewops_data_create(C, op, event);
vod = op->customdata;
@@ -3780,7 +3820,8 @@ static int viewpan_exec(bContext *C, wmOperator *op)
float zfac;
int pandir;
- VIEW3D_OP_OFS_LOCK_TEST(C, op);
+ if (view3d_operator_offset_lock_check(C, op))
+ return OPERATOR_CANCELLED;
pandir = RNA_enum_get(op->ptr, "type");
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index c812f1084e2..c48ce8a2343 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -160,7 +160,7 @@ static void edbm_backbuf_check_and_select_edges(BMEditMesh *em, const bool selec
{
BMEdge *eed;
BMIter iter;
- int index = bm_solidoffs;
+ unsigned int index = bm_solidoffs;
BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
@@ -288,12 +288,12 @@ static int view3d_selectable_data(bContext *C)
/* helper also for borderselect */
-static int edge_fully_inside_rect(const rctf *rect, const float v1[2], const float v2[2])
+static bool edge_fully_inside_rect(const rctf *rect, const float v1[2], const float v2[2])
{
return BLI_rctf_isect_pt_v(rect, v1) && BLI_rctf_isect_pt_v(rect, v2);
}
-static int edge_inside_rect(const rctf *rect, const float v1[2], const float v2[2])
+static bool edge_inside_rect(const rctf *rect, const float v1[2], const float v2[2])
{
int d1, d2, d3, d4;
@@ -725,7 +725,7 @@ static void do_lasso_select_paintvert(ViewContext *vc, const int mcords[][2], sh
{
const int use_zbuf = (vc->v3d->flag & V3D_ZBUF_SELECT);
Object *ob = vc->obact;
- Mesh *me = ob ? ob->data : NULL;
+ Mesh *me = ob->data;
rcti rect;
if (me == NULL || me->totvert == 0)
@@ -764,7 +764,7 @@ static void do_lasso_select_paintvert(ViewContext *vc, const int mcords[][2], sh
static void do_lasso_select_paintface(ViewContext *vc, const int mcords[][2], short moves, bool extend, bool select)
{
Object *ob = vc->obact;
- Mesh *me = ob ? ob->data : NULL;
+ Mesh *me = ob->data;
rcti rect;
if (me == NULL || me->totpoly == 0)
@@ -2405,13 +2405,13 @@ static void mesh_circle_select(ViewContext *vc, const bool select, const int mva
static void paint_facesel_circle_select(ViewContext *vc, const bool select, const int mval[2], float rad)
{
Object *ob = vc->obact;
- Mesh *me = ob ? ob->data : NULL;
- /* int bbsel; */ /* UNUSED */
+ Mesh *me = ob->data;
+ bool bbsel;
- if (me) {
- bm_vertoffs = me->totpoly + 1; /* max index array */
+ bm_vertoffs = me->totpoly + 1; /* max index array */
- /* bbsel = */ /* UNUSED */ EDBM_backbuf_circle_init(vc, mval[0], mval[1], (short)(rad + 1.0f));
+ bbsel = EDBM_backbuf_circle_init(vc, mval[0], mval[1], (short)(rad + 1.0f));
+ if (bbsel) {
edbm_backbuf_check_and_select_tfaces(me, select);
EDBM_backbuf_free();
paintface_flush_flags(ob);
@@ -2431,15 +2431,17 @@ static void paint_vertsel_circle_select(ViewContext *vc, const bool select, cons
const int use_zbuf = (vc->v3d->flag & V3D_ZBUF_SELECT);
Object *ob = vc->obact;
Mesh *me = ob->data;
- /* int bbsel; */ /* UNUSED */
+ bool bbsel;
/* CircleSelectUserData data = {NULL}; */ /* UNUSED */
if (use_zbuf) {
bm_vertoffs = me->totvert + 1; /* max index array */
- /* bbsel = */ /* UNUSED */ EDBM_backbuf_circle_init(vc, mval[0], mval[1], (short)(rad + 1.0f));
- edbm_backbuf_check_and_select_verts_obmode(me, select);
- EDBM_backbuf_free();
+ bbsel = EDBM_backbuf_circle_init(vc, mval[0], mval[1], (short)(rad + 1.0f));
+ if (bbsel) {
+ edbm_backbuf_check_and_select_verts_obmode(me, select);
+ EDBM_backbuf_free();
+ }
}
else {
CircleSelectUserData data;
diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c
index 5f988edb950..7c29ab01c24 100644
--- a/source/blender/editors/space_view3d/view3d_snap.c
+++ b/source/blender/editors/space_view3d/view3d_snap.c
@@ -143,7 +143,7 @@ static void special_transvert_update(Object *obedit)
}
BKE_nurb_test2D(nu);
- BKE_nurb_handles_test(nu); /* test for bezier too */
+ BKE_nurb_handles_test(nu, true); /* test for bezier too */
nu = nu->next;
}
}
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index 7e39c0b6be0..74d72061995 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -378,12 +378,15 @@ void VIEW3D_OT_smoothview(wmOperatorType *ot)
/* identifiers */
ot->name = "Smooth View";
+ ot->description = "";
ot->idname = "VIEW3D_OT_smoothview";
- ot->description = "The time to animate the change of view (in milliseconds)";
/* api callbacks */
ot->invoke = view3d_smoothview_invoke;
+ /* flags */
+ ot->flag = OPTYPE_INTERNAL;
+
ot->poll = ED_operator_view3d_active;
}
@@ -1177,7 +1180,7 @@ static bool view3d_localview_init(Main *bmain, Scene *scene, ScrArea *sa, Report
return ok;
}
-static void restore_localviewdata(ScrArea *sa, int free)
+static void restore_localviewdata(Main *bmain, ScrArea *sa, int free)
{
ARegion *ar;
View3D *v3d = sa->spacedata.first;
@@ -1214,12 +1217,7 @@ static void restore_localviewdata(ScrArea *sa, int free)
}
}
- if (v3d->drawtype != OB_RENDER) {
- if (rv3d->render_engine) {
- RE_engine_free(rv3d->render_engine);
- rv3d->render_engine = NULL;
- }
- }
+ ED_view3d_shade_update(bmain, v3d, sa);
}
}
}
@@ -1234,7 +1232,7 @@ static bool view3d_localview_exit(Main *bmain, Scene *scene, ScrArea *sa)
locallay = v3d->lay & 0xFF000000;
- restore_localviewdata(sa, 1); /* 1 = free */
+ restore_localviewdata(bmain, sa, 1); /* 1 = free */
/* for when in other window the layers have changed */
if (v3d->scenelock) v3d->lay = scene->lay;
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index 87ef3d6742a..b08f66d0454 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -1360,7 +1360,7 @@ int transformEvent(TransInfo *t, const wmEvent *event)
}
}
-int calculateTransformCenter(bContext *C, int centerMode, float cent3d[3], int cent2d[2])
+int calculateTransformCenter(bContext *C, int centerMode, float cent3d[3], float cent2d[2])
{
TransInfo *t = MEM_callocN(sizeof(TransInfo), "TransInfo data");
int success;
@@ -1390,7 +1390,7 @@ int calculateTransformCenter(bContext *C, int centerMode, float cent3d[3], int c
calculateCenter(t);
if (cent2d) {
- copy_v2_v2_int(cent2d, t->center2d);
+ copy_v2_v2(cent2d, t->center2d);
}
if (cent3d) {
@@ -2600,8 +2600,8 @@ void initWarp(TransInfo *t)
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
- t->snap[1] = 5.0f / 180.0f * (float)M_PI;
- t->snap[2] = 1.0f / 180.0f * (float)M_PI;
+ t->snap[1] = DEG2RAD(5.0);
+ t->snap[2] = DEG2RAD(1.0);
t->num.increment = 1.0f;
@@ -3369,8 +3369,8 @@ void initRotation(TransInfo *t)
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
- t->snap[1] = (float)((5.0 / 180) * M_PI);
- t->snap[2] = t->snap[1] * 0.2f;
+ t->snap[1] = DEG2RAD(5.0);
+ t->snap[2] = DEG2RAD(1.0);
t->num.increment = 1.0f;
@@ -3701,8 +3701,8 @@ void initTrackball(TransInfo *t)
t->idx_max = 1;
t->num.idx_max = 1;
t->snap[0] = 0.0f;
- t->snap[1] = (float)((5.0 / 180) * M_PI);
- t->snap[2] = t->snap[1] * 0.2f;
+ t->snap[1] = DEG2RAD(5.0);
+ t->snap[2] = DEG2RAD(1.0);
t->num.increment = 1.0f;
@@ -4149,8 +4149,8 @@ void initTilt(TransInfo *t)
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
- t->snap[1] = (float)((5.0 / 180) * M_PI);
- t->snap[2] = t->snap[1] * 0.2f;
+ t->snap[1] = DEG2RAD(5.0);
+ t->snap[2] = DEG2RAD(1.0);
t->num.increment = t->snap[1];
@@ -4804,6 +4804,26 @@ static BMEdge *get_other_edge(BMVert *v, BMEdge *e)
return NULL;
}
+/* interpoaltes along a line made up of 2 segments (used for edge slide) */
+static void interp_line_v3_v3v3v3(float p[3], const float v1[3], const float v2[3], const float v3[3], const float t)
+{
+ float t_mid, t_delta;
+
+ /* could be pre-calculated */
+ t_mid = line_point_factor_v3(v2, v1, v3);
+
+ t_delta = t - t_mid;
+ if (fabsf(t_delta) < FLT_EPSILON) {
+ copy_v3_v3(p, v2);
+ }
+ else if (t_delta < 0.0f) {
+ interp_v3_v3v3(p, v1, v2, t / t_mid);
+ }
+ else {
+ interp_v3_v3v3(p, v2, v3, (t - t_mid) / (1.0f - t_mid));
+ }
+}
+
static void len_v3_ensure(float v[3], const float length)
{
normalize_v3(v);
@@ -5716,20 +5736,16 @@ static void drawEdgeSlide(const struct bContext *C, TransInfo *t)
/* Non-Prop mode */
if (sld && sld->is_proportional == FALSE) {
View3D *v3d = CTX_wm_view3d(C);
- float marker[3];
- float v1[3], v2[3];
- float interp_v;
+ float co_a[3], co_b[3], co_mark[3];
TransDataEdgeSlideVert *curr_sv = &sld->sv[sld->curr_sv_index];
+ const float fac = (sld->perc + 1.0f) / 2.0f;
const float ctrl_size = UI_GetThemeValuef(TH_FACEDOT_SIZE) + 1.5f;
const float guide_size = ctrl_size - 0.5f;
const float line_size = UI_GetThemeValuef(TH_OUTLINE_WIDTH) + 0.5f;
const int alpha_shade = -30;
- add_v3_v3v3(v1, curr_sv->v_co_orig, curr_sv->dir_a);
- add_v3_v3v3(v2, curr_sv->v_co_orig, curr_sv->dir_b);
-
- interp_v = (sld->perc + 1.0f) / 2.0f;
- interp_v3_v3v3(marker, v2, v1, interp_v);
+ add_v3_v3v3(co_a, curr_sv->v_co_orig, curr_sv->dir_a);
+ add_v3_v3v3(co_b, curr_sv->v_co_orig, curr_sv->dir_b);
if (v3d && v3d->zbuf)
glDisable(GL_DEPTH_TEST);
@@ -5770,7 +5786,12 @@ static void drawEdgeSlide(const struct bContext *C, TransInfo *t)
UI_ThemeColorShadeAlpha(TH_SELECT, 255, alpha_shade);
glPointSize(guide_size);
bglBegin(GL_POINTS);
- bglVertex3fv(marker);
+#if 0
+ interp_v3_v3v3(co_mark, co_b, co_a, fac);
+ bglVertex3fv(co_mark);
+#endif
+ interp_line_v3_v3v3v3(co_mark, co_b, curr_sv->v_co_orig, co_a, fac);
+ bglVertex3fv(co_mark);
bglEnd();
@@ -5832,10 +5853,10 @@ static int doEdgeSlide(TransInfo *t, float perc)
add_v3_v3v3(co_b, sv->v_co_orig, sv->dir_b);
if (sld->flipped_vtx) {
- interp_v3_v3v3(sv->v->co, co_b, co_a, fac);
+ interp_line_v3_v3v3v3(sv->v->co, co_b, sv->v_co_orig, co_a, fac);
}
else {
- interp_v3_v3v3(sv->v->co, co_a, co_b, fac);
+ interp_line_v3_v3v3v3(sv->v->co, co_a, sv->v_co_orig, co_b, fac);
}
}
}
@@ -6414,8 +6435,8 @@ void initBoneRoll(TransInfo *t)
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
- t->snap[1] = (float)((5.0 / 180) * M_PI);
- t->snap[2] = t->snap[1] * 0.2f;
+ t->snap[1] = DEG2RAD(5.0);
+ t->snap[2] = DEG2RAD(1.0);
t->num.increment = 1.0f;
@@ -7217,7 +7238,7 @@ int TimeSlide(TransInfo *t, const int mval[2])
void initTimeScale(TransInfo *t)
{
- int center[2];
+ float center[2];
/* this tool is only really available in the Action Editor
* AND NLA Editor (for strip scaling)
@@ -7232,7 +7253,7 @@ void initTimeScale(TransInfo *t)
/* recalculate center2d to use CFRA and mouse Y, since that's
* what is used in time scale */
t->center[0] = t->scene->r.cfra;
- projectIntView(t, t->center, center);
+ projectFloatView(t, t->center, center);
center[1] = t->imval[1];
/* force a reinit with the center2d used here */
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index a4828317604..9355773c47b 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -271,7 +271,7 @@ typedef struct MouseInput {
int imval[2]; /* initial mouse position */
char precision;
int precision_mval[2]; /* mouse position when precision key was pressed */
- int center[2];
+ float center[2];
float factor;
void *data; /* additional data, if needed by the particular function */
} MouseInput;
@@ -300,7 +300,7 @@ typedef struct TransInfo {
float prop_size; /* proportional circle radius */
char proptext[20]; /* proportional falloff text */
float center[3]; /* center of transformation */
- int center2d[2]; /* center in screen coordinates */
+ float center2d[2]; /* center in screen coordinates */
int imval[2]; /* initial mouse position */
short event_type; /* event->type used to invoke transform */
short idx_max; /* maximum index on the input vector */
@@ -687,7 +687,7 @@ typedef enum {
INPUT_CUSTOM_RATIO_FLIP
} MouseInputMode;
-void initMouseInput(TransInfo *t, MouseInput *mi, const int center[2], const int mval[2]);
+void initMouseInput(TransInfo *t, MouseInput *mi, const float center[2], const int mval[2]);
void initMouseInputMode(TransInfo *t, MouseInput *mi, MouseInputMode mode);
int handleMouseInput(struct TransInfo *t, struct MouseInput *mi, const struct wmEvent *event);
void applyMouseInput(struct TransInfo *t, struct MouseInput *mi, const int mval[2], float output[3]);
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index adfbbc26df2..f5a12fed076 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -123,6 +123,20 @@
#include "transform.h"
#include "bmesh.h"
+/**
+ * Transforming around ourselves is no use, fallback to individual origins,
+ * useful for curve/armatures.
+ */
+static void transform_around_single_fallback(TransInfo *t)
+{
+ if ((t->total == 1) &&
+ (ELEM3(t->around, V3D_CENTER, V3D_CENTROID, V3D_ACTIVE)) &&
+ (ELEM3(t->mode, TFM_RESIZE, TFM_ROTATION, TFM_TRACKBALL)))
+ {
+ t->around = V3D_LOCAL;
+ }
+}
+
/* when transforming islands */
struct TransIslandData {
float co[3];
@@ -1084,6 +1098,8 @@ static void createTransArmatureVerts(TransInfo *t)
if (!t->total) return;
+ transform_around_single_fallback(t);
+
copy_m3_m4(mtx, t->obedit->obmat);
pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
@@ -1408,6 +1424,8 @@ static void createTransCurveVerts(TransInfo *t)
else t->total = countsel;
t->data = MEM_callocN(t->total * sizeof(TransData), "TransObData(Curve EditMode)");
+ transform_around_single_fallback(t);
+
copy_m3_m4(mtx, t->obedit->obmat);
pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
@@ -1443,7 +1461,9 @@ static void createTransCurveVerts(TransInfo *t)
{
copy_v3_v3(td->iloc, bezt->vec[0]);
td->loc = bezt->vec[0];
- copy_v3_v3(td->center, bezt->vec[(hide_handles || bezt->f2 & SELECT) ? 1 : 0]);
+ copy_v3_v3(td->center, bezt->vec[(hide_handles ||
+ (t->around == V3D_LOCAL) ||
+ (bezt->f2 & SELECT)) ? 1 : 0]);
if (hide_handles) {
if (bezt->f2 & SELECT) td->flag = TD_SELECTED;
else td->flag = 0;
@@ -1511,7 +1531,9 @@ static void createTransCurveVerts(TransInfo *t)
{
copy_v3_v3(td->iloc, bezt->vec[2]);
td->loc = bezt->vec[2];
- copy_v3_v3(td->center, bezt->vec[(hide_handles || bezt->f2 & SELECT) ? 1 : 2]);
+ copy_v3_v3(td->center, bezt->vec[(hide_handles ||
+ (t->around == V3D_LOCAL) ||
+ (bezt->f2 & SELECT)) ? 1 : 2]);
if (hide_handles) {
if (bezt->f2 & SELECT) td->flag = TD_SELECTED;
else td->flag = 0;
@@ -1552,7 +1574,7 @@ static void createTransCurveVerts(TransInfo *t)
* but for now just don't change handle types */
if (ELEM(t->mode, TFM_CURVE_SHRINKFATTEN, TFM_TILT) == 0) {
/* sets the handles based on their selection, do this after the data is copied to the TransData */
- BKE_nurb_handles_test(nu);
+ BKE_nurb_handles_test(nu, !hide_handles);
}
}
else {
@@ -2219,7 +2241,7 @@ static void createTransEditVerts(TransInfo *t)
/* detect CrazySpace [tm] */
if (modifiers_getCageIndex(t->scene, t->obedit, NULL, 1) >= 0) {
int totleft = -1;
- if (modifiers_isCorrectableDeformed(t->obedit)) {
+ if (modifiers_isCorrectableDeformed(t->scene, t->obedit)) {
/* check if we can use deform matrices for modifier from the
* start up to stack, they are more accurate than quats */
totleft = editbmesh_get_first_deform_matrices(t->scene, t->obedit, em, &defmats, &defcos);
@@ -2228,7 +2250,13 @@ static void createTransEditVerts(TransInfo *t)
/* if we still have more modifiers, also do crazyspace
* correction with quats, relative to the coordinates after
* the modifiers that support deform matrices (defcos) */
- if ((totleft > 0) || (totleft == -1)) {
+
+#if 0 /* TODO, fix crazyspace+extrude so it can be enabled for general use - campbell */
+ if ((totleft > 0) || (totleft == -1))
+#else
+ if (totleft > 0)
+#endif
+ {
mappedcos = crazyspace_get_mapped_editverts(t->scene, t->obedit);
quats = MEM_mallocN(em->bm->totvert * sizeof(*quats), "crazy quats");
crazyspace_set_quats_editmesh(em, defcos, mappedcos, quats);
@@ -3866,7 +3894,7 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
}
/* if handles were not selected, store their selection status */
- if (!(sel1) && !(sel3)) {
+ if (!(sel1) || !(sel3)) {
if (hdata == NULL)
hdata = initTransDataCurveHandles(td, bezt);
}
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index 233ef1d18a5..b6f031614ca 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -1484,10 +1484,10 @@ void calculateCenter2D(TransInfo *t)
copy_v3_v3(vec, t->center);
mul_m4_v3(ob->obmat, vec);
- projectIntView(t, vec, t->center2d);
+ projectFloatView(t, vec, t->center2d);
}
else {
- projectIntView(t, t->center, t->center2d);
+ projectFloatView(t, t->center, t->center2d);
}
}
@@ -1691,7 +1691,7 @@ void calculateCenter(TransInfo *t)
Object *ob = OBACT;
if (ob) {
copy_v3_v3(t->center, ob->obmat[3]);
- projectIntView(t, t->center, t->center2d);
+ projectFloatView(t, t->center, t->center2d);
}
}
break;
@@ -1723,7 +1723,7 @@ void calculateCenter(TransInfo *t)
axis[1] = t->center[1] - 6.0f * axis[1];
axis[2] = t->center[2] - 6.0f * axis[2];
- projectIntView(t, axis, t->center2d);
+ projectFloatView(t, axis, t->center2d);
/* rotate only needs correct 2d center, grab needs ED_view3d_calc_zfac() value */
if (t->mode == TFM_TRANSLATION) {
diff --git a/source/blender/editors/transform/transform_input.c b/source/blender/editors/transform/transform_input.c
index c035b6173c8..db214e1f6db 100644
--- a/source/blender/editors/transform/transform_input.c
+++ b/source/blender/editors/transform/transform_input.c
@@ -279,7 +279,7 @@ static void InputAngle(TransInfo *UNUSED(t), MouseInput *mi, const int mval[2],
output[0] = *angle;
}
-void initMouseInput(TransInfo *UNUSED(t), MouseInput *mi, const int center[2], const int mval[2])
+void initMouseInput(TransInfo *UNUSED(t), MouseInput *mi, const float center[2], const int mval[2])
{
mi->factor = 0;
mi->precision = 0;
diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c
index 6fecf0d6642..f667a98812b 100644
--- a/source/blender/editors/transform/transform_manipulator.c
+++ b/source/blender/editors/transform/transform_manipulator.c
@@ -428,12 +428,12 @@ int calc_manipulator_stats(const bContext *C)
totsel++;
}
else {
- if (bezt->f1) {
- calc_tw_center(scene, bezt->vec[0]);
+ if (bezt->f1 & SELECT) {
+ calc_tw_center(scene, bezt->vec[(v3d->around == V3D_LOCAL) ? 1 : 0]);
totsel++;
}
- if (bezt->f3) {
- calc_tw_center(scene, bezt->vec[2]);
+ if (bezt->f3 & SELECT) {
+ calc_tw_center(scene, bezt->vec[(v3d->around == V3D_LOCAL) ? 1 : 2]);
totsel++;
}
}
@@ -1858,11 +1858,12 @@ int BIF_do_manipulator(bContext *C, const struct wmEvent *event, wmOperator *op)
* See [#34621], it's a miracle it did not cause more problems!!! */
/* However, we need to copy the "release_confirm" property... */
PointerRNA props_ptr;
- WM_operator_properties_create(&props_ptr, "TRANSFORM_OT_trackball");
+ wmOperatorType *ot = WM_operatortype_find("TRANSFORM_OT_trackball", true);
+ WM_operator_properties_create_ptr(&props_ptr, ot);
RNA_boolean_set(&props_ptr, "release_confirm", RNA_boolean_get(op->ptr, "release_confirm"));
-
- WM_operator_name_call(C, "TRANSFORM_OT_trackball", WM_OP_INVOKE_DEFAULT, &props_ptr);
- //wm_operator_invoke(C, WM_operatortype_find("TRANSFORM_OT_trackball", 0), event, NULL, NULL, FALSE);
+ WM_operator_name_call(C, ot->idname, WM_OP_INVOKE_DEFAULT, &props_ptr);
+ //wm_operator_invoke(C, WM_operatortype_find(ot->idname, 0), event, NULL, NULL, FALSE);
+ WM_operator_properties_free(&props_ptr);
}
else if (drawflags & MAN_ROT_C) {
switch (drawflags) {
diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c
index e7c22fc0899..2904b37c2e5 100644
--- a/source/blender/editors/transform/transform_ops.c
+++ b/source/blender/editors/transform/transform_ops.c
@@ -60,7 +60,7 @@ typedef struct TransformModeItem {
void (*opfunc)(wmOperatorType *);
} TransformModeItem;
-static float VecOne[3] = {1, 1, 1};
+static const float VecOne[3] = {1, 1, 1};
static char OP_TRANSLATION[] = "TRANSFORM_OT_translate";
static char OP_ROTATION[] = "TRANSFORM_OT_rotate";
diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c
index 55d80d63234..cd6a2e6712e 100644
--- a/source/blender/editors/transform/transform_orientations.c
+++ b/source/blender/editors/transform/transform_orientations.c
@@ -728,31 +728,46 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3],
}
}
else {
+ const bool use_handle = (cu->drawflag & CU_HIDE_HANDLES) == 0;
+
for (nu = nurbs->first; nu; nu = nu->next) {
/* only bezier has a normal */
if (nu->type == CU_BEZIER) {
bezt = nu->bezt;
a = nu->pntsu;
while (a--) {
+ short flag = 0;
+
+#define SEL_F1 (1 << 0)
+#define SEL_F2 (1 << 1)
+#define SEL_F3 (1 << 2)
+
+ if (use_handle) {
+ if (bezt->f1 & SELECT) flag |= SEL_F1;
+ if (bezt->f2 & SELECT) flag |= SEL_F2;
+ if (bezt->f3 & SELECT) flag |= SEL_F3;
+ }
+ else {
+ flag = (bezt->f2 & SELECT) ? (SEL_F1 | SEL_F2 | SEL_F3) : 0;
+ }
+
/* exception */
- if ((bezt->f1 | bezt->f2 | bezt->f3) & SELECT) {
+ if (flag) {
float tvec[3];
- if ((bezt->f1 & SELECT) + (bezt->f2 & SELECT) + (bezt->f3 & SELECT) > SELECT) {
+ if ((v3d->around == V3D_LOCAL) ||
+ ELEM3(flag, SEL_F2, SEL_F1 | SEL_F3, SEL_F1 | SEL_F2 | SEL_F3))
+ {
BKE_nurb_bezt_calc_normal(nu, bezt, tvec);
add_v3_v3(normal, tvec);
}
else {
- if (bezt->f1 & SELECT) {
+ /* ignore bezt->f2 in this case */
+ if (flag & SEL_F1) {
sub_v3_v3v3(tvec, bezt->vec[0], bezt->vec[1]);
normalize_v3(tvec);
add_v3_v3(normal, tvec);
}
- if (bezt->f2 & SELECT) {
- sub_v3_v3v3(tvec, bezt->vec[0], bezt->vec[2]);
- normalize_v3(tvec);
- add_v3_v3(normal, tvec);
- }
- if (bezt->f3 & SELECT) {
+ if (flag & SEL_F3) {
sub_v3_v3v3(tvec, bezt->vec[1], bezt->vec[2]);
normalize_v3(tvec);
add_v3_v3(normal, tvec);
@@ -762,6 +777,11 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3],
BKE_nurb_bezt_calc_plane(nu, bezt, tvec);
add_v3_v3(plane, tvec);
}
+
+#undef SEL_F1
+#undef SEL_F2
+#undef SEL_F3
+
bezt++;
}
}
diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c
index 4a208f6eee1..04bccac2a15 100644
--- a/source/blender/editors/transform/transform_snap.c
+++ b/source/blender/editors/transform/transform_snap.c
@@ -134,7 +134,8 @@ bool validSnap(TransInfo *t)
bool activeSnap(TransInfo *t)
{
- return (t->modifiers & (MOD_SNAP | MOD_SNAP_INVERT)) == MOD_SNAP || (t->modifiers & (MOD_SNAP | MOD_SNAP_INVERT)) == MOD_SNAP_INVERT;
+ return ((t->modifiers & (MOD_SNAP | MOD_SNAP_INVERT)) == MOD_SNAP) ||
+ ((t->modifiers & (MOD_SNAP | MOD_SNAP_INVERT)) == MOD_SNAP_INVERT);
}
void drawSnapping(const struct bContext *C, TransInfo *t)
diff --git a/source/blender/editors/util/crazyspace.c b/source/blender/editors/util/crazyspace.c
index 06a70cf9277..ff65e11f53e 100644
--- a/source/blender/editors/util/crazyspace.c
+++ b/source/blender/editors/util/crazyspace.c
@@ -40,6 +40,7 @@
#include "BLI_utildefines.h"
#include "BLI_math.h"
+#include "BLI_bitmap.h"
#include "BKE_DerivedMesh.h"
#include "BKE_modifier.h"
@@ -51,6 +52,7 @@
typedef struct {
float (*vertexcos)[3];
+ BLI_bitmap *vertex_visit;
} MappedUserData;
BLI_INLINE void tan_calc_v3(float a[3], const float b[3], const float c[3])
@@ -83,7 +85,14 @@ static void make_vertexcos__mapFunc(void *userData, int index, const float co[3]
const float UNUSED(no_f[3]), const short UNUSED(no_s[3]))
{
MappedUserData *mappedData = (MappedUserData *)userData;
- copy_v3_v3(mappedData->vertexcos[index], co);
+
+ if (BLI_BITMAP_GET(mappedData->vertex_visit, index) == 0) {
+ /* we need coord from prototype vertex, not from copies,
+ * assume they stored in the beginning of vertex array stored in DM
+ * (mirror modifier for eg does this) */
+ copy_v3_v3(mappedData->vertexcos[index], co);
+ BLI_BITMAP_SET(mappedData->vertex_visit, index);
+ }
}
static int modifiers_disable_subsurf_temporary(Object *ob)
@@ -108,6 +117,7 @@ float (*crazyspace_get_mapped_editverts(Scene *scene, Object *obedit))[3]
DerivedMesh *dm;
float (*vertexcos)[3];
int nverts = me->edit_btmesh->bm->totvert;
+ BLI_bitmap *vertex_visit;
MappedUserData userData;
/* disable subsurf temporal, get mapped cos, and enable it */
@@ -120,8 +130,10 @@ float (*crazyspace_get_mapped_editverts(Scene *scene, Object *obedit))[3]
dm = editbmesh_get_derived_cage(scene, obedit, me->edit_btmesh, CD_MASK_BAREMESH);
vertexcos = MEM_callocN(sizeof(*vertexcos) * nverts, "vertexcos map");
+ vertex_visit = BLI_BITMAP_NEW(nverts, "vertexcos flags");
userData.vertexcos = vertexcos;
+ userData.vertex_visit = vertex_visit;
dm->foreachMappedVert(dm, make_vertexcos__mapFunc, &userData, DM_FOREACH_NOP);
dm->release(dm);
@@ -129,6 +141,8 @@ float (*crazyspace_get_mapped_editverts(Scene *scene, Object *obedit))[3]
/* set back the flag, no new cage needs to be built, transform does it */
modifiers_disable_subsurf_temporary(obedit);
+ MEM_freeN(vertex_visit);
+
return vertexcos;
}
diff --git a/source/blender/editors/util/ed_util.c b/source/blender/editors/util/ed_util.c
index 35e6c40c36b..7424acd752f 100644
--- a/source/blender/editors/util/ed_util.c
+++ b/source/blender/editors/util/ed_util.c
@@ -258,7 +258,7 @@ void unpack_menu(bContext *C, const char *opname, const char *id_name, const cha
void ED_region_draw_mouse_line_cb(const bContext *C, ARegion *ar, void *arg_info)
{
wmWindow *win = CTX_wm_window(C);
- const int *mval_src = (int *)arg_info;
+ const float *mval_src = (float *)arg_info;
const int mval_dst[2] = {win->eventstate->x - ar->winrct.xmin,
win->eventstate->y - ar->winrct.ymin};
@@ -266,7 +266,7 @@ void ED_region_draw_mouse_line_cb(const bContext *C, ARegion *ar, void *arg_info
setlinestyle(3);
glBegin(GL_LINE_STRIP);
glVertex2iv(mval_dst);
- glVertex2iv(mval_src);
+ glVertex2fv(mval_src);
glEnd();
setlinestyle(0);
}
diff --git a/source/blender/editors/uvedit/uvedit_parametrizer.c b/source/blender/editors/uvedit/uvedit_parametrizer.c
index b8a54c56c63..2d33a2d3937 100644
--- a/source/blender/editors/uvedit/uvedit_parametrizer.c
+++ b/source/blender/editors/uvedit/uvedit_parametrizer.c
@@ -4123,7 +4123,7 @@ static void p_smooth(PChart *chart)
MEM_freeN(nodesx);
MEM_freeN(nodesy);
- arena = BLI_memarena_new(1 << 16, "param smooth arena");
+ arena = BLI_memarena_new(MEM_SIZE_OPTIMAL(1 << 16), "param smooth arena");
root = p_node_new(arena, tri, esize * 2, minv, maxv, 0);
for (v = chart->verts; v; v = v->nextlink)
@@ -4143,7 +4143,7 @@ ParamHandle *param_construct_begin(void)
PHandle *handle = MEM_callocN(sizeof(*handle), "PHandle");
handle->construction_chart = p_chart_new(handle);
handle->state = PHANDLE_STATE_ALLOCATED;
- handle->arena = BLI_memarena_new((1 << 16), "param construct arena");
+ handle->arena = BLI_memarena_new(MEM_SIZE_OPTIMAL(1 << 16), "param construct arena");
handle->aspx = 1.0f;
handle->aspy = 1.0f;
handle->do_aspect = FALSE;
diff --git a/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp b/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
index 8cb44d05b84..7dc218c74df 100644
--- a/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
+++ b/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
@@ -369,7 +369,7 @@ static void prepare(Main *bmain, Render *re, SceneRenderLayer *srl)
if (lineset->flags & FREESTYLE_LINESET_ENABLED) {
if (G.debug & G_DEBUG_FREESTYLE) {
cout << " " << layer_count+1 << ": " << lineset->name << " - " <<
- lineset->linestyle->id.name + 2 << endl;
+ (lineset->linestyle ? (lineset->linestyle->id.name + 2) : "<NULL>") << endl;
}
Text *text = create_lineset_handler(bmain, srl->name, lineset->name);
controller->InsertStyleModule(layer_count, lineset->name, text);
@@ -680,9 +680,11 @@ void FRS_paste_active_lineset(FreestyleConfig *config)
FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(config);
if (lineset) {
- lineset->linestyle->id.us--;
+ if (lineset->linestyle)
+ lineset->linestyle->id.us--;
lineset->linestyle = lineset_buffer.linestyle;
- lineset->linestyle->id.us++;
+ if (lineset->linestyle)
+ lineset->linestyle->id.us++;
lineset->flags = lineset_buffer.flags;
lineset->selection = lineset_buffer.selection;
lineset->qi = lineset_buffer.qi;
@@ -711,10 +713,10 @@ void FRS_delete_active_lineset(FreestyleConfig *config)
if (lineset) {
if (lineset->group) {
lineset->group->id.us--;
- lineset->group = NULL;
}
- lineset->linestyle->id.us--;
- lineset->linestyle = NULL;
+ if (lineset->linestyle) {
+ lineset->linestyle->id.us--;
+ }
BLI_remlink(&config->linesets, lineset);
MEM_freeN(lineset);
BKE_freestyle_lineset_set_active_index(config, 0);
diff --git a/source/blender/freestyle/intern/stroke/StrokeRep.cpp b/source/blender/freestyle/intern/stroke/StrokeRep.cpp
index 2615df0a124..fb6da853e02 100644
--- a/source/blender/freestyle/intern/stroke/StrokeRep.cpp
+++ b/source/blender/freestyle/intern/stroke/StrokeRep.cpp
@@ -149,7 +149,8 @@ void Strip::createStrip (const vector<StrokeVertex*>& iStrokeVertices)
if (dp < 0)
userDir = userDir * (-1.0f);
stripDir = userDir;
- } else {
+ }
+ else {
++orientationErrors;
}
}
@@ -207,7 +208,8 @@ void Strip::createStrip (const vector<StrokeVertex*>& iStrokeVertices)
if (dp < 0)
userDir = userDir * (-1.0f);
stripDir = userDir;
- } else {
+ }
+ else {
++orientationErrors;
}
}
@@ -226,7 +228,8 @@ void Strip::createStrip (const vector<StrokeVertex*>& iStrokeVertices)
if (dp < 0)
userDir = userDir * (-1.0f);
stripDirPrev = userDir;
- } else {
+ }
+ else {
++orientationErrors;
}
}
@@ -302,7 +305,8 @@ void Strip::createStrip (const vector<StrokeVertex*>& iStrokeVertices)
if (dp < 0)
userDir = userDir * (-1.0f);
stripDirLast = userDir;
- } else {
+ }
+ else {
++orientationErrors;
}
}
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c
index 0ca929da65d..ed7a2f4ede0 100644
--- a/source/blender/gpu/intern/gpu_material.c
+++ b/source/blender/gpu/intern/gpu_material.c
@@ -1127,7 +1127,16 @@ static void do_material_tex(GPUShadeInput *shi)
GPU_link(mat, "mtex_nspace_tangent", GPU_attribute(CD_TANGENT, ""), shi->vn, tnor, &newnor);
}
}
+ else if (mtex->normapspace == MTEX_NSPACE_OBJECT) {
+ /* transform normal by object then view matrix */
+ GPU_link(mat, "mtex_nspace_object", GPU_builtin(GPU_VIEW_MATRIX), GPU_builtin(GPU_OBJECT_MATRIX), tnor, &newnor);
+ }
+ else if (mtex->normapspace == MTEX_NSPACE_WORLD) {
+ /* transform normal by view matrix */
+ GPU_link(mat, "mtex_nspace_world", GPU_builtin(GPU_VIEW_MATRIX), tnor, &newnor);
+ }
else {
+ /* no transform, normal in camera space */
newnor = tnor;
}
diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl
index d2c9ad7cfd1..633112095a7 100644
--- a/source/blender/gpu/shaders/gpu_shader_material.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_material.glsl
@@ -1415,6 +1415,16 @@ void mtex_nspace_tangent(vec4 tangent, vec3 normal, vec3 texnormal, out vec3 out
outnormal = normalize(outnormal);
}
+void mtex_nspace_world(mat4 viewmat, vec3 texnormal, out vec3 outnormal)
+{
+ outnormal = normalize((viewmat*vec4(texnormal, 0.0)).xyz);
+}
+
+void mtex_nspace_object(mat4 viewmat, mat4 obmat, vec3 texnormal, out vec3 outnormal)
+{
+ outnormal = normalize((viewmat*(obmat*vec4(texnormal, 0.0))).xyz);
+}
+
void mtex_blend_normal(float norfac, vec3 normal, vec3 newnormal, out vec3 outnormal)
{
outnormal = (1.0 - norfac)*normal + norfac*newnormal;
@@ -2124,6 +2134,20 @@ void node_fresnel(float ior, vec3 N, vec3 I, out float result)
result = fresnel_dielectric(I, N, (gl_FrontFacing)? eta: 1.0/eta);
}
+/* gamma */
+
+void node_gamma(vec4 col, float gamma, out vec4 outcol)
+{
+ outcol = col;
+
+ if(col.r > 0.0)
+ outcol.r = compatible_pow(col.r, gamma);
+ if(col.g > 0.0)
+ outcol.g = compatible_pow(col.g, gamma);
+ if(col.b > 0.0)
+ outcol.b = compatible_pow(col.b, gamma);
+}
+
/* geometry */
void node_attribute(vec3 attr_uv, out vec4 outcol, out vec3 outvec, out float outf)
diff --git a/source/blender/imbuf/CMakeLists.txt b/source/blender/imbuf/CMakeLists.txt
index 29ed8c95fc6..26cf19fc158 100644
--- a/source/blender/imbuf/CMakeLists.txt
+++ b/source/blender/imbuf/CMakeLists.txt
@@ -105,6 +105,11 @@ if(WITH_IMAGE_TIFF)
add_definitions(-DWITH_TIFF)
endif()
+
+if(WITH_IMAGE_OPENIMAGEIO)
+ add_definitions(-DWITH_OPENIMAGEIO)
+endif()
+
if(WITH_IMAGE_OPENJPEG)
list(APPEND INC_SYS
${OPENJPEG_INCLUDE_DIRS}
diff --git a/source/blender/imbuf/IMB_colormanagement.h b/source/blender/imbuf/IMB_colormanagement.h
index 64a2bbb72d9..8af86389db3 100644
--- a/source/blender/imbuf/IMB_colormanagement.h
+++ b/source/blender/imbuf/IMB_colormanagement.h
@@ -174,19 +174,16 @@ void IMB_colormanagement_processor_free(struct ColormanageProcessor *cm_processo
/* ** OpenGL drawing routines using GLSL for color space transform ** */
/* Test if GLSL drawing is supported for combination of graphics card and this configuration */
-bool IMB_colormanagement_support_glsl_draw(const struct ColorManagedViewSettings *view_settings,
- bool skip_curves);
+bool IMB_colormanagement_support_glsl_draw(const struct ColorManagedViewSettings *view_settings);
/* Configures GLSL shader for conversion from scene linear to display space */
bool IMB_colormanagement_setup_glsl_draw(const struct ColorManagedViewSettings *view_settings,
const struct ColorManagedDisplaySettings *display_settings,
- bool predivide,
- bool skip_curves);
+ bool predivide);
/* Same as above, but display space conversion happens from a specified space */
bool IMB_colormanagement_setup_glsl_draw_from_space(const struct ColorManagedViewSettings *view_settings,
const struct ColorManagedDisplaySettings *display_settings,
struct ColorSpace *colorspace,
- bool predivide,
- bool skip_curves);
+ bool predivide);
/* Same as setup_glsl_draw, but color management settings are guessing from a given context */
bool IMB_colormanagement_setup_glsl_draw_ctx(const struct bContext *C, bool predivide);
/* Same as setup_glsl_draw_from_space, but color management settings are guessing from a given context */
diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h
index 8c2e79ab7d8..c70ab5d7189 100644
--- a/source/blender/imbuf/IMB_imbuf.h
+++ b/source/blender/imbuf/IMB_imbuf.h
@@ -429,7 +429,7 @@ void IMB_alpha_under_color_byte(unsigned char *rect, int x, int y, float backcol
*
* \attention defined in readimage.c
*/
-struct ImBuf *IMB_loadifffile(int file, int flags, char colorspace[IM_MAX_SPACE], const char *descr);
+struct ImBuf *IMB_loadifffile(int file, const char *filepath, int flags, char colorspace[IM_MAX_SPACE], const char *descr);
/**
*
diff --git a/source/blender/imbuf/IMB_imbuf_types.h b/source/blender/imbuf/IMB_imbuf_types.h
index 1734073dd6c..d20130805c0 100644
--- a/source/blender/imbuf/IMB_imbuf_types.h
+++ b/source/blender/imbuf/IMB_imbuf_types.h
@@ -180,6 +180,10 @@ typedef struct ImBuf {
*/
#define IB_CUSTOM_FLAGS_MASK 0x7ff
+#ifdef WITH_OPENIMAGEIO
+#define PSD (1 << 31)
+#endif
+
#define PNG (1 << 30)
#define TGA (1 << 28)
#define JPG (1 << 27)
@@ -273,6 +277,9 @@ extern const char *imb_ext_image_qt[];
extern const char *imb_ext_movie[];
extern const char *imb_ext_audio[];
+/* image formats that can only be loaded via filepath */
+extern const char *imb_ext_image_filepath_only[];
+
enum {
IMB_COLORMANAGE_IS_DATA = (1 << 0)
};
diff --git a/source/blender/imbuf/SConscript b/source/blender/imbuf/SConscript
index 03064df293d..ccee3ebcc85 100644
--- a/source/blender/imbuf/SConscript
+++ b/source/blender/imbuf/SConscript
@@ -55,6 +55,9 @@ if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', '
incs += ' ' + env['BF_PTHREADS_INC']
incs += ' ../../../intern/utfconv'
+if env['WITH_BF_OIIO']:
+ defs.append('WITH_OPENIMAGEIO')
+
if env['WITH_BF_OPENEXR']:
defs.append('WITH_OPENEXR')
else:
diff --git a/source/blender/imbuf/intern/IMB_filetype.h b/source/blender/imbuf/intern/IMB_filetype.h
index 3c8b29cf68a..9327c15c415 100644
--- a/source/blender/imbuf/intern/IMB_filetype.h
+++ b/source/blender/imbuf/intern/IMB_filetype.h
@@ -39,8 +39,10 @@ typedef struct ImFileType {
void (*exit)(void);
int (*is_a)(unsigned char *buf);
+ int (*is_a_filepath)(const char *name);
int (*ftype)(struct ImFileType *type, struct ImBuf *ibuf);
struct ImBuf *(*load)(unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]);
+ struct ImBuf *(*load_filepath)(const char *name, int flags, char colorspace[IM_MAX_SPACE]);
int (*save)(struct ImBuf *ibuf, const char *name, int flags);
void (*load_tile)(struct ImBuf *ibuf, unsigned char *mem, size_t size, int tx, int ty, unsigned int *rect);
@@ -50,6 +52,7 @@ typedef struct ImFileType {
} ImFileType;
extern ImFileType IMB_FILE_TYPES[];
+extern ImFileType *IMB_FILE_TYPES_LAST;
void imb_filetypes_init(void);
void imb_filetypes_exit(void);
diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c
index 4c4c82a0bb4..cf9cc0c2e6f 100644
--- a/source/blender/imbuf/intern/colormanagement.c
+++ b/source/blender/imbuf/intern/colormanagement.c
@@ -119,6 +119,11 @@ static struct global_glsl_state {
char input[MAX_COLORSPACE_NAME];
float exposure, gamma;
+ CurveMapping *curve_mapping, *orig_curve_mapping;
+ bool use_curve_mapping;
+ int curve_mapping_timestamp;
+ OCIO_CurveMappingSettings curve_mapping_settings;
+
/* Container for GLSL state needed for OCIO module. */
struct OCIO_GLSLDrawState *ocio_glsl_state;
struct OCIO_GLSLDrawState *transform_ocio_glsl_state;
@@ -196,6 +201,7 @@ typedef struct ColormanageCacheViewSettings {
int view;
float exposure;
float gamma;
+ float dither;
CurveMapping *curve_mapping;
} ColormanageCacheViewSettings;
@@ -213,6 +219,7 @@ typedef struct ColormnaageCacheData {
int look; /* Additional artistics transform */
float exposure; /* exposure value cached buffer is calculated with */
float gamma; /* gamma value cached buffer is calculated with */
+ float dither; /* dither value cached buffer is calculated with */
CurveMapping *curve_mapping; /* curve mapping used for cached buffer */
int curve_mapping_timestamp; /* time stamp of curve mapping used for cached buffer */
} ColormnaageCacheData;
@@ -291,7 +298,8 @@ static void colormanage_cachedata_set(ImBuf *ibuf, ColormnaageCacheData *data)
ibuf->colormanage_cache->data = data;
}
-static void colormanage_view_settings_to_cache(ColormanageCacheViewSettings *cache_view_settings,
+static void colormanage_view_settings_to_cache(ImBuf *ibuf,
+ ColormanageCacheViewSettings *cache_view_settings,
const ColorManagedViewSettings *view_settings)
{
int look = IMB_colormanagement_look_get_named_index(view_settings->look);
@@ -301,6 +309,7 @@ static void colormanage_view_settings_to_cache(ColormanageCacheViewSettings *cac
cache_view_settings->view = view;
cache_view_settings->exposure = view_settings->exposure;
cache_view_settings->gamma = view_settings->gamma;
+ cache_view_settings->dither = ibuf->dither;
cache_view_settings->flag = view_settings->flag;
cache_view_settings->curve_mapping = view_settings->curve_mapping;
}
@@ -378,6 +387,7 @@ static unsigned char *colormanage_cache_get(ImBuf *ibuf, const ColormanageCacheV
if (cache_data->look != view_settings->look ||
cache_data->exposure != view_settings->exposure ||
cache_data->gamma != view_settings->gamma ||
+ cache_data->dither != view_settings->dither ||
cache_data->flag != view_settings->flag ||
cache_data->curve_mapping != curve_mapping ||
cache_data->curve_mapping_timestamp != curve_mapping_timestamp)
@@ -424,6 +434,7 @@ static void colormanage_cache_put(ImBuf *ibuf, const ColormanageCacheViewSetting
cache_data->look = view_settings->look;
cache_data->exposure = view_settings->exposure;
cache_data->gamma = view_settings->gamma;
+ cache_data->dither = view_settings->dither;
cache_data->flag = view_settings->flag;
cache_data->curve_mapping = curve_mapping;
cache_data->curve_mapping_timestamp = curve_mapping_timestamp;
@@ -657,6 +668,12 @@ void colormanagement_exit(void)
if (global_glsl_state.processor)
OCIO_processorRelease(global_glsl_state.processor);
+ if (global_glsl_state.curve_mapping)
+ curvemapping_free(global_glsl_state.curve_mapping);
+
+ if (global_glsl_state.curve_mapping_settings.lut)
+ MEM_freeN(global_glsl_state.curve_mapping_settings.lut);
+
if (global_glsl_state.ocio_glsl_state)
OCIO_freeOGLState(global_glsl_state.ocio_glsl_state);
@@ -1909,7 +1926,7 @@ ImBuf *IMB_colormanagement_imbuf_for_write(ImBuf *ibuf, bool save_as_render, boo
* we need to allocate byte buffer and store color managed
* image there
*/
- for (type = IMB_FILE_TYPES; type->is_a; type++) {
+ for (type = IMB_FILE_TYPES; type < IMB_FILE_TYPES_LAST; type++) {
if (type->save && type->ftype(type, colormanaged_ibuf)) {
if ((type->flag & IM_FTYPE_FLOAT) == 0)
make_byte = true;
@@ -2024,7 +2041,7 @@ unsigned char *IMB_display_buffer_acquire(ImBuf *ibuf, const ColorManagedViewSet
return (unsigned char *) ibuf->rect;
}
- colormanage_view_settings_to_cache(&cache_view_settings, applied_view_settings);
+ colormanage_view_settings_to_cache(ibuf, &cache_view_settings, applied_view_settings);
colormanage_display_settings_to_cache(&cache_display_settings, display_settings);
if (ibuf->invalid_rect.xmin != ibuf->invalid_rect.xmax) {
@@ -2445,7 +2462,7 @@ void IMB_colormanagment_colorspace_from_ibuf_ftype(ColorManagedColorspaceSetting
{
ImFileType *type;
- for (type = IMB_FILE_TYPES; type->is_a; type++) {
+ for (type = IMB_FILE_TYPES; type < IMB_FILE_TYPES_LAST; type++) {
if (type->save && type->ftype(type, ibuf)) {
const char *role_colorspace;
@@ -2735,7 +2752,7 @@ void IMB_partial_display_buffer_update(ImBuf *ibuf, const float *linear_buffer,
unsigned char *display_buffer = NULL;
int view_flag, display_index, buffer_width;
- colormanage_view_settings_to_cache(&cache_view_settings, view_settings);
+ colormanage_view_settings_to_cache(ibuf, &cache_view_settings, view_settings);
colormanage_display_settings_to_cache(&cache_display_settings, display_settings);
view_flag = 1 << (cache_view_settings.view - 1);
@@ -2931,16 +2948,61 @@ static bool check_glsl_display_processor_changed(const ColorManagedViewSettings
STREQ(global_glsl_state.input, from_colorspace));
}
+static void curve_mapping_to_ocio_settings(CurveMapping *curve_mapping,
+ OCIO_CurveMappingSettings *curve_mapping_settings)
+{
+ int i;
+
+ curvemapping_initialize(curve_mapping);
+ curvemapping_premultiply(curve_mapping, false);
+ curvemapping_table_RGBA(curve_mapping,
+ &curve_mapping_settings->lut,
+ &curve_mapping_settings->lut_size);
+
+ for (i = 0; i < 4; i++) {
+ CurveMap *cuma = curve_mapping->cm + i;
+ curve_mapping_settings->use_extend_extrapolate[i] = (cuma->flag & CUMA_EXTEND_EXTRAPOLATE) != 0;
+ curve_mapping_settings->range[i] = cuma->range;
+ curve_mapping_settings->mintable[i] = cuma->mintable;
+ curve_mapping_settings->ext_in_x[i] = cuma->ext_in[0];
+ curve_mapping_settings->ext_in_y[i] = cuma->ext_in[1];
+ curve_mapping_settings->ext_out_x[i] = cuma->ext_out[0];
+ curve_mapping_settings->ext_out_y[i] = cuma->ext_out[1];
+ curve_mapping_settings->first_x[i] = cuma->table[0].x;
+ curve_mapping_settings->first_y[i] = cuma->table[0].y;
+ curve_mapping_settings->last_x[i] = cuma->table[CM_TABLE].x;
+ curve_mapping_settings->last_y[i] = cuma->table[CM_TABLE].y;
+ }
+
+ copy_v3_v3(curve_mapping_settings->black, curve_mapping->black);
+ copy_v3_v3(curve_mapping_settings->bwmul, curve_mapping->bwmul);
+
+ curve_mapping_settings->cache_id = (size_t) curve_mapping;
+}
+
static void update_glsl_display_processor(const ColorManagedViewSettings *view_settings,
const ColorManagedDisplaySettings *display_settings,
const char *from_colorspace)
{
+ bool use_curve_mapping = (view_settings->flag & COLORMANAGE_VIEW_USE_CURVES) != 0;
+ bool need_update = false;
+
+ need_update = global_glsl_state.processor == NULL ||
+ check_glsl_display_processor_changed(view_settings, display_settings, from_colorspace) ||
+ use_curve_mapping != global_glsl_state.use_curve_mapping;
+
+ if (use_curve_mapping && need_update == false) {
+ need_update |= view_settings->curve_mapping->changed_timestamp != global_glsl_state.curve_mapping_timestamp ||
+ view_settings->curve_mapping != global_glsl_state.orig_curve_mapping;
+ }
+
/* Update state if there's no processor yet or
* processor settings has been changed.
*/
- if (global_glsl_state.processor == NULL ||
- check_glsl_display_processor_changed(view_settings, display_settings, from_colorspace))
- {
+ if (need_update) {
+ OCIO_CurveMappingSettings *curve_mapping_settings = &global_glsl_state.curve_mapping_settings;
+ CurveMapping *new_curve_mapping = NULL;
+
/* Store settings of processor for further comparison. */
BLI_strncpy(global_glsl_state.look, view_settings->look, MAX_COLORSPACE_NAME);
BLI_strncpy(global_glsl_state.view, view_settings->view_transform, MAX_COLORSPACE_NAME);
@@ -2949,6 +3011,35 @@ static void update_glsl_display_processor(const ColorManagedViewSettings *view_s
global_glsl_state.exposure = view_settings->exposure;
global_glsl_state.gamma = view_settings->gamma;
+ /* We're using curve mapping's address as a acache ID,
+ * so we need to make sure re-allocation gives new address here.
+ * We do this by allocating new curve mapping before freeing ol one.
+ */
+ if (use_curve_mapping) {
+ new_curve_mapping = curvemapping_copy(view_settings->curve_mapping);
+ }
+
+ if (global_glsl_state.curve_mapping) {
+ curvemapping_free(global_glsl_state.curve_mapping);
+ MEM_freeN(curve_mapping_settings->lut);
+ global_glsl_state.curve_mapping = NULL;
+ curve_mapping_settings->lut = NULL;
+ }
+
+ /* Fill in OCIO's curve mapping settings. */
+ if (use_curve_mapping) {
+ curve_mapping_to_ocio_settings(new_curve_mapping, &global_glsl_state.curve_mapping_settings);
+
+ global_glsl_state.curve_mapping = new_curve_mapping;
+ global_glsl_state.curve_mapping_timestamp = view_settings->curve_mapping->changed_timestamp;
+ global_glsl_state.orig_curve_mapping = view_settings->curve_mapping;
+ global_glsl_state.use_curve_mapping = true;
+ }
+ else {
+ global_glsl_state.orig_curve_mapping = NULL;
+ global_glsl_state.use_curve_mapping = false;
+ }
+
/* Free old processor, if any. */
if (global_glsl_state.processor)
OCIO_processorRelease(global_glsl_state.processor);
@@ -2964,14 +3055,8 @@ static void update_glsl_display_processor(const ColorManagedViewSettings *view_s
}
}
-bool IMB_colormanagement_support_glsl_draw(const ColorManagedViewSettings *view_settings,
- bool skip_curves)
+bool IMB_colormanagement_support_glsl_draw(const ColorManagedViewSettings *UNUSED(view_settings))
{
- /* curves not supported yet */
- if (!skip_curves)
- if (view_settings && (view_settings->flag & COLORMANAGE_VIEW_USE_CURVES))
- return 0;
-
return OCIO_supportGLSLDraw();
}
@@ -2990,8 +3075,7 @@ bool IMB_colormanagement_support_glsl_draw(const ColorManagedViewSettings *view_
*/
bool IMB_colormanagement_setup_glsl_draw_from_space(const ColorManagedViewSettings *view_settings,
const ColorManagedDisplaySettings *display_settings,
- struct ColorSpace *from_colorspace, bool predivide,
- bool skip_curves)
+ struct ColorSpace *from_colorspace, bool predivide)
{
ColorManagedViewSettings default_view_settings;
const ColorManagedViewSettings *applied_view_settings;
@@ -3008,25 +3092,22 @@ bool IMB_colormanagement_setup_glsl_draw_from_space(const ColorManagedViewSettin
applied_view_settings = &default_view_settings;
}
- /* RGB curves mapping is not supported on GPU yet. */
- if (!skip_curves)
- if (applied_view_settings->flag & COLORMANAGE_VIEW_USE_CURVES)
- return false;
-
/* Make sure OCIO processor is up-to-date. */
update_glsl_display_processor(applied_view_settings, display_settings,
from_colorspace ? from_colorspace->name : global_role_scene_linear);
- return OCIO_setupGLSLDraw(&global_glsl_state.ocio_glsl_state, global_glsl_state.processor, predivide);
+ return OCIO_setupGLSLDraw(&global_glsl_state.ocio_glsl_state, global_glsl_state.processor,
+ global_glsl_state.use_curve_mapping ? &global_glsl_state.curve_mapping_settings : NULL,
+ predivide);
}
/* Configures GLSL shader for conversion from scene linear to display space */
bool IMB_colormanagement_setup_glsl_draw(const ColorManagedViewSettings *view_settings,
const ColorManagedDisplaySettings *display_settings,
- bool predivide, bool skip_curves)
+ bool predivide)
{
return IMB_colormanagement_setup_glsl_draw_from_space(view_settings, display_settings,
- NULL, predivide, skip_curves);
+ NULL, predivide);
}
/* Same as setup_glsl_draw_from_space, but color management settings are guessing from a given context */
@@ -3037,7 +3118,7 @@ bool IMB_colormanagement_setup_glsl_draw_from_space_ctx(const struct bContext *C
IMB_colormanagement_display_settings_from_ctx(C, &view_settings, &display_settings);
- return IMB_colormanagement_setup_glsl_draw_from_space(view_settings, display_settings, from_colorspace, predivide, false);
+ return IMB_colormanagement_setup_glsl_draw_from_space(view_settings, display_settings, from_colorspace, predivide);
}
/* Same as setup_glsl_draw, but color management settings are guessing from a given context */
@@ -3076,7 +3157,7 @@ bool IMB_colormanagement_setup_transform_from_role_glsl(int role, bool predivide
processor = colorspace_to_scene_linear_processor(colorspace);
- return OCIO_setupGLSLDraw(&global_glsl_state.transform_ocio_glsl_state, processor, predivide);
+ return OCIO_setupGLSLDraw(&global_glsl_state.transform_ocio_glsl_state, processor, NULL, predivide);
}
/* Finish GLSL-based color space conversion */
diff --git a/source/blender/imbuf/intern/filetype.c b/source/blender/imbuf/intern/filetype.c
index 37070c7e2bf..f9e05dbd6d6 100644
--- a/source/blender/imbuf/intern/filetype.c
+++ b/source/blender/imbuf/intern/filetype.c
@@ -35,6 +35,10 @@
#include "IMB_colormanagement.h"
+#ifdef WITH_OPENIMAGEIO
+#include "oiio/openimageio_api.h"
+#endif
+
#ifdef WITH_OPENEXR
#include "openexr/openexr_api.h"
#endif
@@ -71,41 +75,46 @@ void quicktime_exit(void);
#endif
ImFileType IMB_FILE_TYPES[] = {
- {NULL, NULL, imb_is_a_jpeg, imb_ftype_default, imb_load_jpeg, imb_savejpeg, NULL, 0, JPG, COLOR_ROLE_DEFAULT_BYTE},
- {NULL, NULL, imb_is_a_png, imb_ftype_default, imb_loadpng, imb_savepng, NULL, 0, PNG, COLOR_ROLE_DEFAULT_BYTE},
- {NULL, NULL, imb_is_a_bmp, imb_ftype_default, imb_bmp_decode, imb_savebmp, NULL, 0, BMP, COLOR_ROLE_DEFAULT_BYTE},
- {NULL, NULL, imb_is_a_targa, imb_ftype_default, imb_loadtarga, imb_savetarga, NULL, 0, TGA, COLOR_ROLE_DEFAULT_BYTE},
- {NULL, NULL, imb_is_a_iris, imb_ftype_iris, imb_loadiris, imb_saveiris, NULL, 0, IMAGIC, COLOR_ROLE_DEFAULT_BYTE},
+ {NULL, NULL, imb_is_a_jpeg, NULL, imb_ftype_default, imb_load_jpeg, NULL, imb_savejpeg, NULL, 0, JPG, COLOR_ROLE_DEFAULT_BYTE},
+ {NULL, NULL, imb_is_a_png, NULL, imb_ftype_default, imb_loadpng, NULL, imb_savepng, NULL, 0, PNG, COLOR_ROLE_DEFAULT_BYTE},
+ {NULL, NULL, imb_is_a_bmp, NULL, imb_ftype_default, imb_bmp_decode, NULL, imb_savebmp, NULL, 0, BMP, COLOR_ROLE_DEFAULT_BYTE},
+ {NULL, NULL, imb_is_a_targa, NULL, imb_ftype_default, imb_loadtarga, NULL, imb_savetarga, NULL, 0, TGA, COLOR_ROLE_DEFAULT_BYTE},
+ {NULL, NULL, imb_is_a_iris, NULL, imb_ftype_iris, imb_loadiris, NULL, imb_saveiris, NULL, 0, IMAGIC, COLOR_ROLE_DEFAULT_BYTE},
#ifdef WITH_CINEON
- {NULL, NULL, imb_is_dpx, imb_ftype_default, imb_load_dpx, imb_save_dpx, NULL, IM_FTYPE_FLOAT, DPX, COLOR_ROLE_DEFAULT_FLOAT},
- {NULL, NULL, imb_is_cineon, imb_ftype_default, imb_load_cineon, imb_save_cineon, NULL, IM_FTYPE_FLOAT, CINEON, COLOR_ROLE_DEFAULT_FLOAT},
+ {NULL, NULL, imb_is_dpx, NULL, imb_ftype_default, imb_load_dpx, NULL, imb_save_dpx, NULL, IM_FTYPE_FLOAT, DPX, COLOR_ROLE_DEFAULT_FLOAT},
+ {NULL, NULL, imb_is_cineon, NULL, imb_ftype_default, imb_load_cineon, NULL, imb_save_cineon, NULL, IM_FTYPE_FLOAT, CINEON, COLOR_ROLE_DEFAULT_FLOAT},
#endif
#ifdef WITH_TIFF
- {imb_inittiff, NULL, imb_is_a_tiff, imb_ftype_default, imb_loadtiff, imb_savetiff, imb_loadtiletiff, 0, TIF, COLOR_ROLE_DEFAULT_BYTE},
+ {imb_inittiff, NULL, imb_is_a_tiff, NULL, imb_ftype_default, imb_loadtiff, NULL, imb_savetiff, imb_loadtiletiff, 0, TIF, COLOR_ROLE_DEFAULT_BYTE},
#endif
#ifdef WITH_HDR
- {NULL, NULL, imb_is_a_hdr, imb_ftype_default, imb_loadhdr, imb_savehdr, NULL, IM_FTYPE_FLOAT, RADHDR, COLOR_ROLE_DEFAULT_FLOAT},
+ {NULL, NULL, imb_is_a_hdr, NULL, imb_ftype_default, imb_loadhdr, NULL, imb_savehdr, NULL, IM_FTYPE_FLOAT, RADHDR, COLOR_ROLE_DEFAULT_FLOAT},
#endif
#ifdef WITH_OPENEXR
- {imb_initopenexr, NULL, imb_is_a_openexr, imb_ftype_default, imb_load_openexr, imb_save_openexr, NULL, IM_FTYPE_FLOAT, OPENEXR, COLOR_ROLE_DEFAULT_FLOAT},
+ {imb_initopenexr, NULL, imb_is_a_openexr, NULL, imb_ftype_default, imb_load_openexr, NULL, imb_save_openexr, NULL, IM_FTYPE_FLOAT, OPENEXR, COLOR_ROLE_DEFAULT_FLOAT},
#endif
#ifdef WITH_OPENJPEG
- {NULL, NULL, imb_is_a_jp2, imb_ftype_default, imb_jp2_decode, imb_savejp2, NULL, IM_FTYPE_FLOAT, JP2, COLOR_ROLE_DEFAULT_BYTE},
+ {NULL, NULL, imb_is_a_jp2, NULL, imb_ftype_default, imb_jp2_decode, NULL, imb_savejp2, NULL, IM_FTYPE_FLOAT, JP2, COLOR_ROLE_DEFAULT_BYTE},
#endif
#ifdef WITH_DDS
- {NULL, NULL, imb_is_a_dds, imb_ftype_default, imb_load_dds, NULL, NULL, 0, DDS, COLOR_ROLE_DEFAULT_BYTE},
+ {NULL, NULL, imb_is_a_dds, NULL, imb_ftype_default, imb_load_dds, NULL, NULL, NULL, 0, DDS, COLOR_ROLE_DEFAULT_BYTE},
#endif
#ifdef WITH_QUICKTIME
- {quicktime_init, quicktime_exit, imb_is_a_quicktime, imb_ftype_quicktime, imb_quicktime_decode, NULL, NULL, 0, QUICKTIME, COLOR_ROLE_DEFAULT_BYTE},
+ {quicktime_init, quicktime_exit, imb_is_a_quicktime, NULL, imb_ftype_quicktime, imb_quicktime_decode, NULL, NULL, 0, QUICKTIME, COLOR_ROLE_DEFAULT_BYTE},
+#endif
+#ifdef WITH_OPENIMAGEIO
+ {NULL, NULL, NULL, imb_is_a_photoshop, imb_ftype_default, NULL, imb_load_photoshop, NULL, NULL, IM_FTYPE_FLOAT, PSD, COLOR_ROLE_DEFAULT_FLOAT},
#endif
- {NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0}
+ {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0}
};
-
+
+ImFileType *IMB_FILE_TYPES_LAST = &IMB_FILE_TYPES[sizeof(IMB_FILE_TYPES) / sizeof(ImFileType) - 1];
+
void imb_filetypes_init(void)
{
ImFileType *type;
- for (type = IMB_FILE_TYPES; type->is_a; type++)
+ for (type = IMB_FILE_TYPES; type < IMB_FILE_TYPES_LAST; type++)
if (type->init)
type->init();
}
@@ -114,7 +123,7 @@ void imb_filetypes_exit(void)
{
ImFileType *type;
- for (type = IMB_FILE_TYPES; type->is_a; type++)
+ for (type = IMB_FILE_TYPES; type < IMB_FILE_TYPES_LAST; type++)
if (type->exit)
type->exit();
}
diff --git a/source/blender/imbuf/intern/indexer.c b/source/blender/imbuf/intern/indexer.c
index dd0970a71f2..93324b94cdc 100644
--- a/source/blender/imbuf/intern/indexer.c
+++ b/source/blender/imbuf/intern/indexer.c
@@ -55,12 +55,12 @@
#endif
-static char magic[] = "BlenMIdx";
-static char temp_ext[] = "_part";
+static const char magic[] = "BlenMIdx";
+static const char temp_ext[] = "_part";
-static int proxy_sizes[] = { IMB_PROXY_25, IMB_PROXY_50, IMB_PROXY_75,
+static const int proxy_sizes[] = { IMB_PROXY_25, IMB_PROXY_50, IMB_PROXY_75,
IMB_PROXY_100 };
-static float proxy_fac[] = { 0.25, 0.50, 0.75, 1.00 };
+static const float proxy_fac[] = { 0.25, 0.50, 0.75, 1.00 };
#ifdef WITH_FFMPEG
static int tc_types[] = {IMB_TC_RECORD_RUN,
diff --git a/source/blender/imbuf/intern/oiio/CMakeLists.txt b/source/blender/imbuf/intern/oiio/CMakeLists.txt
new file mode 100644
index 00000000000..271a2bc3268
--- /dev/null
+++ b/source/blender/imbuf/intern/oiio/CMakeLists.txt
@@ -0,0 +1,54 @@
+# ***** 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) 2013, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s):
+#
+# ***** END GPL LICENSE BLOCK *****
+
+set(INC
+ .
+ ..
+ ../..
+ ../../../blenkernel
+ ../../../blenlib
+ ../../../makesdna
+ ../../../../../intern/guardedalloc
+ ../../../../../intern/utfconv
+)
+
+set(INC_SYS
+
+)
+
+set(SRC
+ openimageio_api.h
+
+ openimageio_api.cpp
+)
+
+if(WITH_IMAGE_OPENIMAGEIO)
+ list(APPEND INC_SYS
+ ${OPENIMAGEIO_INCLUDE_DIRS}
+ )
+ add_definitions(-DWITH_OPENIMAGEIO)
+endif()
+
+blender_add_lib(bf_imbuf_openimageio "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/source/blender/imbuf/intern/oiio/SConscript b/source/blender/imbuf/intern/oiio/SConscript
new file mode 100644
index 00000000000..82b47e9c46b
--- /dev/null
+++ b/source/blender/imbuf/intern/oiio/SConscript
@@ -0,0 +1,49 @@
+#!/usr/bin/env python
+#
+# ***** 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) 2013, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s):
+#
+# ***** END GPL LICENSE BLOCK *****
+
+Import ('env')
+
+source_files = ['openimageio_api.cpp']
+
+incs = ['.',
+ '../../../blenkernel',
+ '../../',
+ '..',
+ '../../../blenlib',
+ 'intern/include',
+ '#/intern/guardedalloc',
+ '../../../makesdna',
+ '#/intern/utfconv']
+
+incs += Split(env['BF_OIIO_INC'])
+
+defs = ['WITH_OPENIMAGEIO']
+
+if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'):
+ incs.append(env['BF_PTHREADS_INC'])
+
+env.BlenderLib ('bf_imbuf_openimageio', source_files, incs, defs, libtype=['core','player'], priority = [225,180])
diff --git a/source/blender/imbuf/intern/oiio/openimageio_api.cpp b/source/blender/imbuf/intern/oiio/openimageio_api.cpp
new file mode 100644
index 00000000000..838343dce35
--- /dev/null
+++ b/source/blender/imbuf/intern/oiio/openimageio_api.cpp
@@ -0,0 +1,256 @@
+/*
+ * ***** 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) 2013 Blender Foundation
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Dalai Felinto and Brecht van Lommel
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/imbuf/intern/oiio/openimageio_api.cpp
+ * \ingroup openimageio
+ */
+
+#include <set>
+
+#include <openimageio_api.h>
+#include <OpenImageIO/imageio.h>
+
+OIIO_NAMESPACE_USING
+
+#if defined(WIN32) && !defined(FREE_WINDOWS)
+#include "utfconv.h"
+#endif
+
+extern "C"
+{
+#include "MEM_guardedalloc.h"
+
+#include "BLI_blenlib.h"
+
+#include "IMB_imbuf_types.h"
+#include "IMB_imbuf.h"
+#include "IMB_allocimbuf.h"
+#include "IMB_colormanagement.h"
+#include "IMB_colormanagement_intern.h"
+}
+
+using namespace std;
+
+typedef unsigned char uchar;
+
+template <class T, class Q>
+static void fill_all_channels(T *pixels, int width, int height, int components, Q alpha)
+{
+ if (components == 2) {
+ for (int i = width * height - 1; i >= 0; i--) {
+ pixels[i * 4 + 3] = pixels[i * 2 + 1];
+ pixels[i * 4 + 2] = pixels[i * 2 + 0];
+ pixels[i * 4 + 1] = pixels[i * 2 + 0];
+ pixels[i * 4 + 0] = pixels[i * 2 + 0];
+ }
+ }
+ else if (components == 3) {
+ for (int i = width * height - 1; i >= 0; i--) {
+ pixels[i * 4 + 3] = alpha;
+ pixels[i * 4 + 2] = pixels[i * 3 + 2];
+ pixels[i * 4 + 1] = pixels[i * 3 + 1];
+ pixels[i * 4 + 0] = pixels[i * 3 + 0];
+
+ }
+ }
+ else if (components == 1) {
+ for (int i = width * height - 1; i >= 0; i--) {
+ pixels[i * 4 + 3] = alpha;
+ pixels[i * 4 + 2] = pixels[i];
+ pixels[i * 4 + 1] = pixels[i];
+ pixels[i * 4 + 0] = pixels[i];
+ }
+ }
+
+}
+
+static ImBuf *imb_oiio_load_image(ImageInput *in, int width, int height, int components, int flags, bool is_alpha)
+{
+ ImBuf *ibuf;
+ int scanlinesize = width * components * sizeof(uchar);
+
+ /* allocate the memory for the image */
+ ibuf = IMB_allocImBuf(width, height, is_alpha ? 32 : 24, flags | IB_rect);
+
+ try
+ {
+ in->read_image(TypeDesc::UINT8,
+ (uchar *)ibuf->rect + (height - 1) * scanlinesize,
+ AutoStride,
+ -scanlinesize,
+ AutoStride);
+ }
+ catch (const std::exception &exc)
+ {
+ std::cerr << exc.what() << std::endl;
+ if (ibuf) IMB_freeImBuf(ibuf);
+
+ return NULL;
+ }
+
+ /* ImBuf always needs 4 channels */
+ fill_all_channels((uchar *)ibuf->rect, width, height, components, 0xFF);
+
+ return ibuf;
+}
+
+static ImBuf *imb_oiio_load_image_float(ImageInput *in, int width, int height, int components, int flags, bool is_alpha)
+{
+ ImBuf *ibuf;
+ int scanlinesize = width * components * sizeof(float);
+
+ /* allocate the memory for the image */
+ ibuf = IMB_allocImBuf(width, height, is_alpha ? 32 : 24, flags | IB_rectfloat);
+
+ try
+ {
+ in->read_image(TypeDesc::FLOAT,
+ (uchar *)ibuf->rect_float + (height - 1) * scanlinesize,
+ AutoStride,
+ -scanlinesize,
+ AutoStride);
+ }
+ catch (const std::exception &exc)
+ {
+ std::cerr << exc.what() << std::endl;
+ if (ibuf) IMB_freeImBuf(ibuf);
+
+ return NULL;
+ }
+
+ /* ImBuf always needs 4 channels */
+ fill_all_channels((float *)ibuf->rect_float, width, height, components, 1.0f);
+
+ /* note: Photoshop 16 bit files never has alpha with it, so no need to handle associated/unassociated alpha */
+ return ibuf;
+}
+
+extern "C"
+{
+
+int imb_is_a_photoshop(const char *filename)
+{
+ const char *photoshop_extension[] = {
+ ".psd",
+ ".pdd",
+ ".psb",
+ NULL
+ };
+
+ return BLI_testextensie_array(filename, photoshop_extension);
+}
+
+int imb_save_photoshop(struct ImBuf *ibuf, const char *name, int flags)
+{
+ if (flags & IB_mem) {
+ printf("Photoshop PSD-save: Create PSD in memory CURRENTLY NOT SUPPORTED !\n");
+ imb_addencodedbufferImBuf(ibuf);
+ ibuf->encodedsize = 0;
+ return(0);
+ }
+
+ return(0);
+}
+
+struct ImBuf *imb_load_photoshop(const char *filename, int flags, char colorspace[IM_MAX_SPACE])
+{
+ ImageInput *in = NULL;
+ struct ImBuf *ibuf = NULL;
+ int width, height, components;
+ bool is_float, is_alpha;
+ TypeDesc typedesc;
+ int basesize;
+
+ /* load image from file through OIIO */
+ if (imb_is_a_photoshop(filename) == 0) return (NULL);
+
+ colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE);
+
+ in = ImageInput::create(filename);
+ if (!in) return NULL;
+
+ ImageSpec spec, config;
+ config.attribute("oiio:UnassociatedAlpha", (int) 1);
+
+ if (!in->open(filename, spec, config)) {
+ delete in;
+ return NULL;
+ }
+
+ string ics = spec.get_string_attribute("oiio:ColorSpace");
+ BLI_strncpy(colorspace, ics.c_str(), IM_MAX_SPACE);
+
+ width = spec.width;
+ height = spec.height;
+ components = spec.nchannels;
+ is_alpha = spec.alpha_channel != -1;
+ basesize = spec.format.basesize();
+ is_float = basesize > 1;
+
+ /* we only handle certain number of components */
+ if (!(components >= 1 && components <= 4)) {
+ if (in) {
+ in->close();
+ delete in;
+ }
+ return NULL;
+ }
+
+ if (is_float)
+ ibuf = imb_oiio_load_image_float(in, width, height, components, flags, is_alpha);
+ else
+ ibuf = imb_oiio_load_image(in, width, height, components, flags, is_alpha);
+
+ if (in) {
+ in->close();
+ delete in;
+ }
+
+ if (!ibuf)
+ return NULL;
+
+ /* ImBuf always needs 4 channels */
+ ibuf->ftype = PSD;
+ ibuf->channels = 4;
+ ibuf->planes = (3 + (is_alpha ? 1 : 0)) * 4 << basesize;
+
+ try
+ {
+ return ibuf;
+ }
+ catch (const std::exception &exc)
+ {
+ std::cerr << exc.what() << std::endl;
+ if (ibuf) IMB_freeImBuf(ibuf);
+
+ return NULL;
+ }
+}
+
+} // export "C"
+
+
diff --git a/source/blender/imbuf/intern/oiio/openimageio_api.h b/source/blender/imbuf/intern/oiio/openimageio_api.h
new file mode 100644
index 00000000000..ad11f4bcfe3
--- /dev/null
+++ b/source/blender/imbuf/intern/oiio/openimageio_api.h
@@ -0,0 +1,53 @@
+/*
+ * ***** 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) 2013 Blender Foundation
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s):
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/imbuf/intern/oiio/openimageio_api.h
+ * \ingroup openimageio
+ */
+
+
+#ifndef __OPENIMAGEIO_API_H__
+#define __OPENIMAGEIO_API_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+
+int imb_is_a_photoshop (const char *name);
+
+int imb_save_photoshop (struct ImBuf *ibuf, const char *name, int flags);
+
+struct ImBuf *imb_load_photoshop (const char *name, int flags, char *colorspace);
+
+#ifdef __cplusplus
+}
+
+#endif
+
+#endif /* __OPENIMAGEIO_API_H__ */
diff --git a/source/blender/imbuf/intern/readimage.c b/source/blender/imbuf/intern/readimage.c
index d73fa9a7ab7..6988687e4ed 100644
--- a/source/blender/imbuf/intern/readimage.c
+++ b/source/blender/imbuf/intern/readimage.c
@@ -56,6 +56,53 @@
#include "IMB_colormanagement.h"
#include "IMB_colormanagement_intern.h"
+static void imb_handle_alpha(ImBuf *ibuf, int flags, char colorspace[IM_MAX_SPACE], char effective_colorspace[IM_MAX_SPACE])
+{
+ int alpha_flags;
+
+ if (colorspace) {
+ if (ibuf->rect) {
+ /* byte buffer is never internally converted to some standard space,
+ * store pointer to it's color space descriptor instead
+ */
+ ibuf->rect_colorspace = colormanage_colorspace_get_named(effective_colorspace);
+ }
+
+ BLI_strncpy(colorspace, effective_colorspace, IM_MAX_SPACE);
+ }
+
+ if (flags & IB_alphamode_detect)
+ alpha_flags = ibuf->flags & IB_alphamode_premul;
+ else
+ alpha_flags = flags & IB_alphamode_premul;
+
+ if (flags & IB_ignore_alpha) {
+ IMB_rectfill_alpha(ibuf, 1.0f);
+ }
+ else {
+ if (alpha_flags & IB_alphamode_premul) {
+ if (ibuf->rect) {
+ IMB_unpremultiply_alpha(ibuf);
+ }
+ else {
+ /* pass, floats are expected to be premul */
+ }
+ }
+ else {
+ if (ibuf->rect_float) {
+ IMB_premultiply_alpha(ibuf);
+ }
+ else {
+ /* pass, bytes are expected to be straight */
+ }
+ }
+ }
+
+ /* OCIO_TODO: in some cases it's faster to do threaded conversion,
+ * but how to distinguish such cases */
+ colormanage_imbuf_make_linear(ibuf, effective_colorspace);
+}
+
ImBuf *IMB_ibImageFromMemory(unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE], const char *descr)
{
ImBuf *ibuf;
@@ -70,54 +117,36 @@ ImBuf *IMB_ibImageFromMemory(unsigned char *mem, size_t size, int flags, char co
if (colorspace)
BLI_strncpy(effective_colorspace, colorspace, sizeof(effective_colorspace));
- for (type = IMB_FILE_TYPES; type->is_a; type++) {
+ for (type = IMB_FILE_TYPES; type < IMB_FILE_TYPES_LAST; type++) {
if (type->load) {
ibuf = type->load(mem, size, flags, effective_colorspace);
if (ibuf) {
- int alpha_flags;
-
- if (colorspace) {
- if (ibuf->rect) {
- /* byte buffer is never internally converted to some standard space,
- * store pointer to it's color space descriptor instead
- */
- ibuf->rect_colorspace = colormanage_colorspace_get_named(effective_colorspace);
- }
-
- BLI_strncpy(colorspace, effective_colorspace, IM_MAX_SPACE);
- }
-
- if (flags & IB_alphamode_detect)
- alpha_flags = ibuf->flags & IB_alphamode_premul;
- else
- alpha_flags = flags & IB_alphamode_premul;
-
- if (flags & IB_ignore_alpha) {
- IMB_rectfill_alpha(ibuf, 1.0f);
- }
- else {
- if (alpha_flags & IB_alphamode_premul) {
- if (ibuf->rect) {
- IMB_unpremultiply_alpha(ibuf);
- }
- else {
- /* pass, floats are expected to be premul */
- }
- }
- else {
- if (ibuf->rect_float) {
- IMB_premultiply_alpha(ibuf);
- }
- else {
- /* pass, bytes are expected to be straight */
- }
- }
- }
-
- /* OCIO_TODO: in some cases it's faster to do threaded conversion,
- * but how to distinguish such cases */
- colormanage_imbuf_make_linear(ibuf, effective_colorspace);
+ imb_handle_alpha(ibuf, flags, colorspace, effective_colorspace);
+ return ibuf;
+ }
+ }
+ }
+
+ if ((flags & IB_test) == 0)
+ fprintf(stderr, "%s: unknown fileformat (%s)\n", __func__, descr);
+
+ return NULL;
+}
+
+static ImBuf *IMB_ibImageFromFile(const char *filepath, int flags, char colorspace[IM_MAX_SPACE], const char *descr)
+{
+ ImBuf *ibuf;
+ ImFileType *type;
+ char effective_colorspace[IM_MAX_SPACE] = "";
+
+ if (colorspace)
+ BLI_strncpy(effective_colorspace, colorspace, sizeof(effective_colorspace));
+ for (type = IMB_FILE_TYPES; type < IMB_FILE_TYPES_LAST; type++) {
+ if (type->load_filepath) {
+ ibuf = type->load_filepath(filepath, flags, effective_colorspace);
+ if (ibuf) {
+ imb_handle_alpha(ibuf, flags, colorspace, effective_colorspace);
return ibuf;
}
}
@@ -129,7 +158,13 @@ ImBuf *IMB_ibImageFromMemory(unsigned char *mem, size_t size, int flags, char co
return NULL;
}
-ImBuf *IMB_loadifffile(int file, int flags, char colorspace[IM_MAX_SPACE], const char *descr)
+static bool imb_is_filepath_format(const char *filepath)
+{
+ /* return true if this is one of the formats that can't be loaded from memory */
+ return BLI_testextensie_array(filepath, imb_ext_image_filepath_only);
+}
+
+ImBuf *IMB_loadifffile(int file, const char *filepath, int flags, char colorspace[IM_MAX_SPACE], const char *descr)
{
ImBuf *ibuf;
unsigned char *mem;
@@ -137,6 +172,9 @@ ImBuf *IMB_loadifffile(int file, int flags, char colorspace[IM_MAX_SPACE], const
if (file == -1) return NULL;
+ if (imb_is_filepath_format(filepath))
+ return IMB_ibImageFromFile(filepath, flags, colorspace, descr);
+
size = BLI_file_descriptor_size(file);
mem = mmap(NULL, size, PROT_READ, MAP_SHARED, file, 0);
@@ -179,7 +217,7 @@ ImBuf *IMB_loadiffname(const char *filepath, int flags, char colorspace[IM_MAX_S
file = BLI_open(filepath_tx, O_BINARY | O_RDONLY, 0);
if (file < 0) return NULL;
- ibuf = IMB_loadifffile(file, flags, colorspace, filepath_tx);
+ ibuf = IMB_loadifffile(file, filepath, flags, colorspace, filepath_tx);
if (ibuf) {
BLI_strncpy(ibuf->name, filepath, sizeof(ibuf->name));
@@ -206,7 +244,7 @@ ImBuf *IMB_testiffname(const char *filepath, int flags)
file = BLI_open(filepath_tx, O_BINARY | O_RDONLY, 0);
if (file < 0) return NULL;
- ibuf = IMB_loadifffile(file, flags | IB_test | IB_multilayer, colorspace, filepath_tx);
+ ibuf = IMB_loadifffile(file, filepath, flags | IB_test | IB_multilayer, colorspace, filepath_tx);
if (ibuf) {
BLI_strncpy(ibuf->name, filepath, sizeof(ibuf->name));
@@ -234,7 +272,7 @@ static void imb_loadtilefile(ImBuf *ibuf, int file, int tx, int ty, unsigned int
return;
}
- for (type = IMB_FILE_TYPES; type->is_a; type++)
+ for (type = IMB_FILE_TYPES; type < IMB_FILE_TYPES_LAST; type++)
if (type->load_tile && type->ftype(type, ibuf))
type->load_tile(ibuf, mem, size, tx, ty, rect);
diff --git a/source/blender/imbuf/intern/tiff.c b/source/blender/imbuf/intern/tiff.c
index eaba04c9310..05e9a4fa134 100644
--- a/source/blender/imbuf/intern/tiff.c
+++ b/source/blender/imbuf/intern/tiff.c
@@ -315,7 +315,7 @@ int imb_is_a_tiff(unsigned char *mem)
(memcmp(lil_endian, mem, IMB_TIFF_NCB) == 0) );
}
-static void scanline_contig_16bit(float *rectf, unsigned short *sbuf, int scanline_w, int spp)
+static void scanline_contig_16bit(float *rectf, const unsigned short *sbuf, int scanline_w, int spp)
{
int i;
for (i = 0; i < scanline_w; i++) {
@@ -326,7 +326,7 @@ static void scanline_contig_16bit(float *rectf, unsigned short *sbuf, int scanli
}
}
-static void scanline_contig_32bit(float *rectf, float *fbuf, int scanline_w, int spp)
+static void scanline_contig_32bit(float *rectf, const float *fbuf, int scanline_w, int spp)
{
int i;
for (i = 0; i < scanline_w; i++) {
@@ -337,14 +337,14 @@ static void scanline_contig_32bit(float *rectf, float *fbuf, int scanline_w, int
}
}
-static void scanline_separate_16bit(float *rectf, unsigned short *sbuf, int scanline_w, int chan)
+static void scanline_separate_16bit(float *rectf, const unsigned short *sbuf, int scanline_w, int chan)
{
int i;
for (i = 0; i < scanline_w; i++)
rectf[i * 4 + chan] = sbuf[i] / 65535.0;
}
-static void scanline_separate_32bit(float *rectf, float *fbuf, int scanline_w, int chan)
+static void scanline_separate_32bit(float *rectf, const float *fbuf, int scanline_w, int chan)
{
int i;
for (i = 0; i < scanline_w; i++)
diff --git a/source/blender/imbuf/intern/util.c b/source/blender/imbuf/intern/util.c
index a4b0e61d544..ecf6458ac57 100644
--- a/source/blender/imbuf/intern/util.c
+++ b/source/blender/imbuf/intern/util.c
@@ -98,6 +98,16 @@ const char *imb_ext_image[] = {
#ifdef WITH_OPENEXR
".exr",
#endif
+#ifdef WITH_OPENIMAGEIO
+ ".psd", ".pdd", ".psb",
+#endif
+ NULL
+};
+
+const char *imb_ext_image_filepath_only[] = {
+#ifdef WITH_OPENIMAGEIO
+ ".psd", ".pdd", ".psb",
+#endif
NULL
};
@@ -188,9 +198,16 @@ static int IMB_ispic_name(const char *name)
if ((BIG_LONG(((int *)buf)[0]) & 0xfffffff0) == 0xffd8ffe0)
return JPG;
- for (type = IMB_FILE_TYPES; type->is_a; type++) {
- if (type->is_a(buf)) {
- return type->filetype;
+ for (type = IMB_FILE_TYPES; type < IMB_FILE_TYPES_LAST; type++) {
+ if (type->is_a) {
+ if (type->is_a(buf)) {
+ return type->filetype;
+ }
+ }
+ else if (type->is_a_filepath) {
+ if (type->is_a_filepath(name)) {
+ return type->filetype;
+ }
}
}
diff --git a/source/blender/imbuf/intern/writeimage.c b/source/blender/imbuf/intern/writeimage.c
index 5d785e08212..1519fc1990d 100644
--- a/source/blender/imbuf/intern/writeimage.c
+++ b/source/blender/imbuf/intern/writeimage.c
@@ -67,7 +67,7 @@ short IMB_saveiff(struct ImBuf *ibuf, const char *name, int flags)
if (ibuf == NULL) return (FALSE);
ibuf->flags = flags;
- for (type = IMB_FILE_TYPES; type->is_a; type++) {
+ for (type = IMB_FILE_TYPES; type < IMB_FILE_TYPES_LAST; type++) {
if (type->save && type->ftype(type, ibuf)) {
ImBuf *write_ibuf;
short result = FALSE;
diff --git a/source/blender/makesdna/DNA_mask_types.h b/source/blender/makesdna/DNA_mask_types.h
index 4307ea57f15..a72e287c16f 100644
--- a/source/blender/makesdna/DNA_mask_types.h
+++ b/source/blender/makesdna/DNA_mask_types.h
@@ -178,6 +178,7 @@ enum {
/* SpaceClip->mask_draw_flag */
#define MASK_DRAWFLAG_SMOOTH 1
+#define MASK_DRAWFLAG_OVERLAY 2
/* copy of eSpaceImage_UVDT */
/* SpaceClip->mask_draw_type */
@@ -188,6 +189,12 @@ enum {
MASK_DT_WHITE = 3
};
+/* MaskSpaceInfo->overlay_mode */
+enum {
+ MASK_OVERLAY_ALPHACHANNEL = 0,
+ MASK_OVERLAY_COMBINED = 1
+};
+
/* masklay->blend */
enum {
MASK_BLEND_ADD = 0,
diff --git a/source/blender/makesdna/DNA_mesh_types.h b/source/blender/makesdna/DNA_mesh_types.h
index e37d1368892..7cdb79232a9 100644
--- a/source/blender/makesdna/DNA_mesh_types.h
+++ b/source/blender/makesdna/DNA_mesh_types.h
@@ -79,7 +79,7 @@ typedef struct Mesh {
* real faces are now stored in nface.*/
struct MFace *mface; /* array of mesh object mode faces for tessellation */
struct MTFace *mtface; /* store tessellation face UV's and texture here */
- struct TFace *tface; /* depecrated, use mtface */
+ struct TFace *tface DNA_DEPRECATED; /* deprecated, use mtface */
struct MVert *mvert; /* array of verts */
struct MEdge *medge; /* array of edges */
struct MDeformVert *dvert; /* deformgroup vertices */
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index a82d1a71a1e..75b9540f736 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -149,23 +149,16 @@ typedef enum eNodeSocketInOut {
} eNodeSocketInOut;
/* sock->flag, first bit is select */
- /* hidden is user defined, to hide unused */
-#define SOCK_HIDDEN 2
- /* for quick check if socket is linked */
-#define SOCK_IN_USE 4
- /* unavailable is for dynamic sockets */
-#define SOCK_UNAVAIL 8
- /* DEPRECATED dynamic socket (can be modified by user) */
-#define __SOCK_DYNAMIC 16
- /* DEPRECATED group socket should not be exposed */
-#define __SOCK_INTERNAL 32
- /* socket collapsed in UI */
-#define SOCK_COLLAPSED 64
- /* hide socket value, if it gets auto default */
-#define SOCK_HIDE_VALUE 128
- /* socket hidden automatically, to distinguish from manually hidden */
- /* DEPRECATED, only kept here to avoid reusing the flag */
-#define SOCK_AUTO_HIDDEN__DEPRECATED 256
+typedef enum eNodeSocketFlag {
+ SOCK_HIDDEN = 2, /* hidden is user defined, to hide unused */
+ SOCK_IN_USE = 4, /* for quick check if socket is linked */
+ SOCK_UNAVAIL = 8, /* unavailable is for dynamic sockets */
+ __SOCK_DYNAMIC = 16, /* DEPRECATED dynamic socket (can be modified by user) */
+ __SOCK_INTERNAL = 32, /* DEPRECATED group socket should not be exposed */
+ SOCK_COLLAPSED = 64, /* socket collapsed in UI */
+ SOCK_HIDE_VALUE = 128, /* hide socket value, if it gets auto default */
+ SOCK_AUTO_HIDDEN__DEPRECATED = 256 /* socket hidden automatically, to distinguish from manually hidden */
+} eNodeSocketFlag;
/* limit data in bNode to what we want to see saved? */
typedef struct bNode {
@@ -975,8 +968,8 @@ typedef struct NodeShaderNormalMap {
#define SHD_NORMAL_MAP_BLENDER_OBJECT 3
#define SHD_NORMAL_MAP_BLENDER_WORLD 4
-/* tangent */
-#define SHD_SUBSURFACE_COMPATIBLE 0
+/* subsurface */
+#define SHD_SUBSURFACE_COMPATIBLE 0 // Deprecated
#define SHD_SUBSURFACE_CUBIC 1
#define SHD_SUBSURFACE_GAUSSIAN 2
diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h
index a346e7b5149..f8a163ab8f8 100644
--- a/source/blender/makesdna/DNA_object_types.h
+++ b/source/blender/makesdna/DNA_object_types.h
@@ -149,7 +149,7 @@ typedef struct Object {
/* materials */
struct Material **mat; /* material slots */
char *matbits; /* a boolean field, with each byte 1 if corresponding material is linked to object */
- int totcol; /* copy of mesh or curve or meta */
+ int totcol; /* copy of mesh, curve & meta struct member of same name (keep in sync) */
int actcol; /* currently selected material in the UI */
/* rot en drot have to be together! (transform('r' en 's')) */
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index 002d77fb0e6..232fe62df31 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -316,6 +316,7 @@ typedef struct ImageFormatData {
#define R_IMF_IMTYPE_H264 31
#define R_IMF_IMTYPE_XVID 32
#define R_IMF_IMTYPE_THEORA 33
+#define R_IMF_IMTYPE_PSD 34
#define R_IMF_IMTYPE_INVALID 255
@@ -510,6 +511,7 @@ typedef struct RenderData {
short bake_normal_space, bake_quad_split;
float bake_maxdist, bake_biasdist;
short bake_samples, bake_pad;
+ float bake_user_scale, bake_pad1;
/* path to render output */
char pic[1024]; /* 1024 = FILE_MAX */
@@ -981,17 +983,6 @@ typedef struct ToolSettings {
* paint */
float vgroup_weight;
- /* Subdivide Settings */
- short cornertype;
- short pad1;
- /*Triangle to Quad conversion threshold*/
- float jointrilimit;
- /* Editmode Tools */
- float degr;
- short step;
- short turn;
-
- float extr_offs; /* extrude offset */
float doublimit; /* remove doubles limit */
float normalsize; /* size of normals */
short automerge;
@@ -999,30 +990,21 @@ typedef struct ToolSettings {
/* Selection Mode for Mesh */
short selectmode;
- /* Primitive Settings */
- /* UV Sphere */
- short segments;
- short rings;
-
- /* Cylinder - Tube - Circle */
- short vertices;
-
/* UV Calculation */
- short unwrapper;
- float uvcalc_radius;
- float uvcalc_cubesize;
+ char unwrapper;
+ char uvcalc_flag;
+ char uv_flag;
+ char uv_selectmode;
+
float uvcalc_margin;
- short uvcalc_mapdir;
- short uvcalc_mapalign;
- short uvcalc_flag;
- short uv_flag, uv_selectmode;
- short pad2;
-
- /* Grease Pencil */
- short gpencil_flags;
-
+
/* Auto-IK */
- short autoik_chainlen;
+ short autoik_chainlen; /* runtime only */
+
+ /* Grease Pencil */
+ char gpencil_flags;
+
+ char pad[5];
/* Image Paint (8 byttse aligned please!) */
struct ImagePaintSettings imapaint;
@@ -1035,16 +1017,13 @@ typedef struct ToolSettings {
/* Select Group Threshold */
float select_thresh;
-
- /* Graph Editor */
- float clean_thresh;
/* Auto-Keying Mode */
short autokey_mode, autokey_flag; /* defines in DNA_userdef_types.h */
/* Multires */
char multires_subdiv_type;
- char pad3[5];
+ char pad3[1];
/* Skeleton generation */
short skgen_resolution;
@@ -1375,6 +1354,7 @@ typedef struct Scene {
#define R_BAKE_MULTIRES 16
#define R_BAKE_LORES_MESH 32
#define R_BAKE_VCOL 64
+#define R_BAKE_USERSCALE 128
/* bake_normal_space */
#define R_BAKE_SPACE_CAMERA 0
diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h
index 0478ff567a0..5befaa87e7f 100644
--- a/source/blender/makesdna/DNA_space_types.h
+++ b/source/blender/makesdna/DNA_space_types.h
@@ -546,7 +546,8 @@ typedef struct MaskSpaceInfo
/* draw options */
char draw_flag;
char draw_type;
- char pad3[6];
+ char overlay_mode;
+ char pad3[5];
} MaskSpaceInfo;
/* sseq->mainb */
diff --git a/source/blender/makesdna/DNA_texture_types.h b/source/blender/makesdna/DNA_texture_types.h
index 0b6e5f9c7bb..fcd0575f1c5 100644
--- a/source/blender/makesdna/DNA_texture_types.h
+++ b/source/blender/makesdna/DNA_texture_types.h
@@ -263,7 +263,7 @@ typedef struct TexMapping {
float loc[3], rot[3], size[3];
int flag;
char projx, projy, projz, mapping;
- int pad;
+ int type;
float mat[4][4];
float min[3], max[3];
@@ -287,6 +287,12 @@ typedef struct ColorMapping {
#define TEXMAP_CLIP_MAX 2
#define TEXMAP_UNIT_MATRIX 4
+/* texmap->type */
+#define TEXMAP_TYPE_POINT 0
+#define TEXMAP_TYPE_TEXTURE 1
+#define TEXMAP_TYPE_VECTOR 2
+#define TEXMAP_TYPE_NORMAL 3
+
/* colormap->flag */
#define COLORMAP_USE_RAMP 1
diff --git a/source/blender/makesdna/intern/CMakeLists.txt b/source/blender/makesdna/intern/CMakeLists.txt
index f8fa625415e..317141b14e3 100644
--- a/source/blender/makesdna/intern/CMakeLists.txt
+++ b/source/blender/makesdna/intern/CMakeLists.txt
@@ -40,6 +40,8 @@ blender_include_dirs(
set(SRC
makesdna.c
../../../../intern/guardedalloc/intern/mallocn.c
+ ../../../../intern/guardedalloc/intern/mallocn_guarded_impl.c
+ ../../../../intern/guardedalloc/intern/mallocn_lockfree_impl.c
)
if(WIN32 AND NOT UNIX)
@@ -50,11 +52,6 @@ endif()
# SRC_DNA_INC is defined in the parent dir
-# for mallocn.c
-if (WITH_GUARDEDALLOC)
- add_definitions(-DWITH_GUARDEDALLOC)
-endif()
-
add_executable(makesdna ${SRC} ${SRC_DNA_INC})
# Output dna.c
@@ -81,6 +78,8 @@ set(SRC
${SRC_DNA_INC}
)
+set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/dna.c PROPERTIES GENERATED TRUE)
+
blender_add_lib(bf_dna "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/source/blender/makesdna/intern/SConscript b/source/blender/makesdna/intern/SConscript
index 7c3af30ee83..35b4ff262ed 100644
--- a/source/blender/makesdna/intern/SConscript
+++ b/source/blender/makesdna/intern/SConscript
@@ -36,8 +36,6 @@ cflags = ''
defines = []
root_build_dir=normpath(env['BF_BUILDDIR'])
-defines.append('WITH_GUARDEDALLOC')
-
source_files = ['makesdna.c']
header_files = env.Glob('../*.h')
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index d18fe7629fd..b4b79059f93 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -1119,8 +1119,14 @@ void _RNA_warning(const char *format, ...) ATTR_PRINTF_FORMAT(1, 2);
/* Equals test (skips pointers and collections)
* is_strict false assumes uninitialized properties are equal */
-bool RNA_property_equals(struct PointerRNA *a, struct PointerRNA *b, struct PropertyRNA *prop, bool is_strict);
-bool RNA_struct_equals(struct PointerRNA *a, struct PointerRNA *b, bool is_strict);
+typedef enum eRNAEqualsMode {
+ RNA_EQ_STRICT, /* set/unset ignored */
+ RNA_EQ_UNSET_MATCH_ANY, /* unset property matches anything */
+ RNA_EQ_UNSET_MATCH_NONE /* unset property never matches set property */
+} eRNAEqualsMode;
+
+bool RNA_property_equals(struct PointerRNA *a, struct PointerRNA *b, struct PropertyRNA *prop, eRNAEqualsMode mode);
+bool RNA_struct_equals(struct PointerRNA *a, struct PointerRNA *b, eRNAEqualsMode mode);
#ifdef __cplusplus
}
diff --git a/source/blender/makesrna/RNA_define.h b/source/blender/makesrna/RNA_define.h
index 924fc505fda..2b1a5bc71ff 100644
--- a/source/blender/makesrna/RNA_define.h
+++ b/source/blender/makesrna/RNA_define.h
@@ -42,8 +42,8 @@ extern "C" {
BlenderRNA *RNA_create(void);
void RNA_define_free(BlenderRNA *brna);
void RNA_free(BlenderRNA *brna);
-void RNA_define_verify_sdna(int verify);
-void RNA_define_animate_sdna(int animate);
+void RNA_define_verify_sdna(bool verify);
+void RNA_define_animate_sdna(bool animate);
void RNA_init(void);
void RNA_exit(void);
@@ -164,7 +164,7 @@ void RNA_def_property_update(PropertyRNA *prop, int noteflag, const char *update
void RNA_def_property_editable_func(PropertyRNA *prop, const char *editable);
void RNA_def_property_editable_array_func(PropertyRNA *prop, const char *editable);
-void RNA_def_property_update_runtime(PropertyRNA *prop, void *func);
+void RNA_def_property_update_runtime(PropertyRNA *prop, const void *func);
void RNA_def_property_dynamic_array_funcs(PropertyRNA *prop, const char *getlength);
void RNA_def_property_boolean_funcs(PropertyRNA *prop, const char *get, const char *set);
@@ -225,6 +225,10 @@ const char *RNA_property_typename(PropertyType type);
void RNA_identifier_sanitize(char *identifier, int property);
+extern const int rna_matrix_dimsize_3x3[];
+extern const int rna_matrix_dimsize_4x4[];
+extern const int rna_matrix_dimsize_4x2[];
+
/* max size for dynamic defined type descriptors,
* this value is arbitrary */
#define RNA_DYN_DESCR_MAX 240
diff --git a/source/blender/makesrna/SConscript b/source/blender/makesrna/SConscript
index dfe1ebb3385..5053c8082e9 100644
--- a/source/blender/makesrna/SConscript
+++ b/source/blender/makesrna/SConscript
@@ -66,6 +66,9 @@ if env['WITH_BF_BULLET']:
defs.append('WITH_BULLET')
incs += ' #/intern/rigidbody'
+if env['WITH_BF_OIIO']:
+ defs.append('WITH_OPENIMAGEIO')
+
if env['WITH_BF_OPENEXR']:
defs.append('WITH_OPENEXR')
diff --git a/source/blender/makesrna/intern/CMakeLists.txt b/source/blender/makesrna/intern/CMakeLists.txt
index eb0c4f7c422..bac335572f5 100644
--- a/source/blender/makesrna/intern/CMakeLists.txt
+++ b/source/blender/makesrna/intern/CMakeLists.txt
@@ -23,9 +23,6 @@
#
# ***** END GPL LICENSE BLOCK *****
-# Generated code has some unused vars we can ignore.
-remove_strict_flags()
-
if(CMAKE_COMPILER_IS_GNUCC)
# add here so we fail early.
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror=implicit-function-declaration")
@@ -124,7 +121,7 @@ set(APISRC
)
string(REGEX REPLACE "rna_([a-zA-Z0-9_-]*).c" "${CMAKE_CURRENT_BINARY_DIR}/rna_\\1_gen.c" GENSRC "${DEFSRC}")
-set_source_files_properties(GENSRC PROPERTIES GENERATED true)
+set_source_files_properties(${GENSRC} PROPERTIES GENERATED TRUE)
set(SRC_RNA_INC
../RNA_access.h
@@ -140,6 +137,8 @@ set(SRC
${DEFSRC}
${APISRC}
../../../../intern/guardedalloc/intern/mallocn.c
+ ../../../../intern/guardedalloc/intern/mallocn_guarded_impl.c
+ ../../../../intern/guardedalloc/intern/mallocn_lockfree_impl.c
../../../../intern/guardedalloc/intern/mmap_win.c
)
@@ -167,6 +166,10 @@ if(WITH_IMAGE_OPENEXR)
add_definitions(-DWITH_OPENEXR)
endif()
+if(WITH_IMAGE_OPENIMAGEIO)
+ add_definitions(-DWITH_OPENIMAGEIO)
+endif()
+
if(WITH_IMAGE_TIFF)
add_definitions(-DWITH_TIFF)
endif()
@@ -252,11 +255,6 @@ if(WITH_BULLET)
add_definitions(-DWITH_BULLET)
endif()
-# for mallocn.c
-if (WITH_GUARDEDALLOC)
- add_definitions(-DWITH_GUARDEDALLOC)
-endif()
-
# Build makesrna executable
blender_include_dirs(
.
diff --git a/source/blender/makesrna/intern/SConscript b/source/blender/makesrna/intern/SConscript
index 10b6a8c8d10..fe6950e62dd 100644
--- a/source/blender/makesrna/intern/SConscript
+++ b/source/blender/makesrna/intern/SConscript
@@ -82,6 +82,9 @@ if env['WITH_BF_BULLET']:
defs.append('WITH_BULLET')
incs += ' #/intern/rigidbody'
+if env['WITH_BF_OIIO']:
+ defs.append('WITH_OPENIMAGEIO')
+
if env['WITH_BF_OPENEXR']:
defs.append('WITH_OPENEXR')
@@ -150,8 +153,6 @@ if env['WITH_BF_INTERNATIONAL']:
if not env['BF_DEBUG']:
defs.append('NDEBUG')
-defs.append('WITH_GUARDEDALLOC')
-
makesrna_tool.Append(CPPDEFINES=defs)
makesrna_tool.Append (CPPPATH = Split(incs))
diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c
index 838f8a33f07..8a4022de104 100644
--- a/source/blender/makesrna/intern/makesrna.c
+++ b/source/blender/makesrna/intern/makesrna.c
@@ -82,7 +82,7 @@ static void rna_generate_static_parameter_prototypes(FILE *f, StructRNA *srna, F
fprintf(f, param); \
} (void)0
-static int replace_if_different(char *tmpfile, const char *dep_files[])
+static int replace_if_different(const char *tmpfile, const char *dep_files[])
{
/* return 0; *//* use for testing had edited rna */
@@ -2692,7 +2692,11 @@ static void rna_generate_static_parameter_prototypes(FILE *f, StructRNA *srna, F
}
+ /* ensure func(void) if there are no args */
+ if (first) fprintf(f, "void");
+
fprintf(f, ")");
+
if (close_prototype)
fprintf(f, ";\n");
}
@@ -2764,7 +2768,7 @@ static void rna_generate_struct_prototypes(FILE *f)
static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, PropertyRNA *prop)
{
- char *strnest = "", *errnest = "";
+ char *strnest = (char *)"", *errnest = (char *)"";
int len, freenest = 0;
if (nest != NULL) {
@@ -3330,6 +3334,12 @@ static void rna_generate(BlenderRNA *brna, FILE *f, const char *filename, const
fprintf(f, "#include \"%s\"\n", api_filename);
fprintf(f, "\n");
+ /* we want the included C files to have warnings enabled but for the generated code
+ * ignore unused-parameter warnings which are hard to prevent */
+#ifdef __GNUC__
+ fprintf(f, "#pragma GCC diagnostic ignored \"-Wunused-parameter\"\n\n");
+#endif
+
fprintf(f, "/* Autogenerated Functions */\n\n");
for (ds = DefRNA.structs.first; ds; ds = ds->cont.next) {
diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c
index 0bce3ac2907..075f852a032 100644
--- a/source/blender/makesrna/intern/rna_ID.c
+++ b/source/blender/makesrna/intern/rna_ID.c
@@ -58,7 +58,7 @@ EnumPropertyItem id_type_items[] = {
{ID_KE, "KEY", ICON_SHAPEKEY_DATA, "Key", ""},
{ID_LA, "LAMP", ICON_LAMP_DATA, "Lamp", ""},
{ID_LI, "LIBRARY", ICON_LIBRARY_DATA_DIRECT, "Library", ""},
- {ID_LS, "LINESTYLE", ICON_PARTICLE_DATA, "FreestyleLineStyle", ""}, /* FIXME proper icon */
+ {ID_LS, "LINESTYLE", ICON_BRUSH_DATA, "Line Style", ""}, /* FIXME proper icon */
{ID_LT, "LATTICE", ICON_LATTICE_DATA, "Lattice", ""},
{ID_MA, "MATERIAL", ICON_MATERIAL_DATA, "Material", ""},
{ID_MB, "META", ICON_META_DATA, "MetaBall", ""},
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index 918c67b4513..341ba02fd47 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -4419,10 +4419,12 @@ char *RNA_path_full_struct_py(struct PointerRNA *ptr)
data_path = RNA_path_from_ID_to_struct(ptr);
- ret = BLI_sprintfN("%s.%s",
- id_path, data_path);
+ /* XXX data_path may be NULL (see #36788), do we want to get the 'bpy.data.foo["bar"].(null)' stuff? */
+ ret = BLI_sprintfN("%s.%s", id_path, data_path);
- MEM_freeN(data_path);
+ if (data_path) {
+ MEM_freeN(data_path);
+ }
MEM_freeN(id_path);
return ret;
@@ -6316,14 +6318,20 @@ void _RNA_warning(const char *format, ...)
#endif
}
-bool RNA_property_equals(PointerRNA *a, PointerRNA *b, PropertyRNA *prop, bool is_strict)
+bool RNA_property_equals(PointerRNA *a, PointerRNA *b, PropertyRNA *prop, eRNAEqualsMode mode)
{
int len, fromlen;
- /* if not strict, uninitialized properties are assumed to match */
- if (!is_strict)
- if (!(RNA_property_is_set(a, prop) && RNA_property_is_set(b, prop)))
+ if (mode == RNA_EQ_UNSET_MATCH_ANY) {
+ /* uninitialized properties are assumed to match anything */
+ if (!RNA_property_is_set(a, prop) || !RNA_property_is_set(b, prop))
return true;
+ }
+ else if (mode == RNA_EQ_UNSET_MATCH_NONE) {
+ /* unset properties never match set properties */
+ if (RNA_property_is_set(a, prop) != RNA_property_is_set(b, prop))
+ return false;
+ }
/* get the length of the array to work with */
len = RNA_property_array_length(a, prop);
@@ -6437,7 +6445,7 @@ bool RNA_property_equals(PointerRNA *a, PointerRNA *b, PropertyRNA *prop, bool i
if (!STREQ(RNA_property_identifier(prop), "rna_type")) {
PointerRNA propptr_a = RNA_property_pointer_get(a, prop);
PointerRNA propptr_b = RNA_property_pointer_get(b, prop);
- return RNA_struct_equals(&propptr_a, &propptr_b, is_strict);
+ return RNA_struct_equals(&propptr_a, &propptr_b, mode);
}
break;
}
@@ -6449,7 +6457,7 @@ bool RNA_property_equals(PointerRNA *a, PointerRNA *b, PropertyRNA *prop, bool i
return true;
}
-bool RNA_struct_equals(PointerRNA *a, PointerRNA *b, bool is_strict)
+bool RNA_struct_equals(PointerRNA *a, PointerRNA *b, eRNAEqualsMode mode)
{
CollectionPropertyIterator iter;
// CollectionPropertyRNA *citerprop; /* UNUSED */
@@ -6470,7 +6478,7 @@ bool RNA_struct_equals(PointerRNA *a, PointerRNA *b, bool is_strict)
for (; iter.valid; RNA_property_collection_next(&iter)) {
PropertyRNA *prop = iter.ptr.data;
- if (!RNA_property_equals(a, b, prop, is_strict)) {
+ if (!RNA_property_equals(a, b, prop, mode)) {
equals = false;
break;
}
diff --git a/source/blender/makesrna/intern/rna_action.c b/source/blender/makesrna/intern/rna_action.c
index c008ac90e38..c5b7c88d8fc 100644
--- a/source/blender/makesrna/intern/rna_action.c
+++ b/source/blender/makesrna/intern/rna_action.c
@@ -191,7 +191,8 @@ static void rna_Action_active_pose_marker_index_set(PointerRNA *ptr, int value)
act->active_marker = value + 1;
}
-static void rna_Action_active_pose_marker_index_range(PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax)
+static void rna_Action_active_pose_marker_index_range(PointerRNA *ptr, int *min, int *max,
+ int *UNUSED(softmin), int *UNUSED(softmax))
{
bAction *act = (bAction *)ptr->data;
diff --git a/source/blender/makesrna/intern/rna_animation.c b/source/blender/makesrna/intern/rna_animation.c
index 7bdaca3c847..31fdd19f169 100644
--- a/source/blender/makesrna/intern/rna_animation.c
+++ b/source/blender/makesrna/intern/rna_animation.c
@@ -408,7 +408,8 @@ static void rna_KeyingSet_active_ksPath_index_set(PointerRNA *ptr, int value)
ks->active_path = value + 1;
}
-static void rna_KeyingSet_active_ksPath_index_range(PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax)
+static void rna_KeyingSet_active_ksPath_index_range(PointerRNA *ptr, int *min, int *max,
+ int *UNUSED(softmin), int *UNUSED(softmax))
{
KeyingSet *ks = (KeyingSet *)ptr->data;
diff --git a/source/blender/makesrna/intern/rna_armature.c b/source/blender/makesrna/intern/rna_armature.c
index b9cbbdb32f7..4b9f7ea32f6 100644
--- a/source/blender/makesrna/intern/rna_armature.c
+++ b/source/blender/makesrna/intern/rna_armature.c
@@ -471,9 +471,6 @@ static int rna_Armature_is_editmode_get(PointerRNA *ptr)
#else
-static int rna_matrix_dimsize_4x4[] = {4, 4};
-static int rna_matrix_dimsize_3x3[] = {3, 3};
-
static void rna_def_bone_common(StructRNA *srna, int editbone)
{
PropertyRNA *prop;
diff --git a/source/blender/makesrna/intern/rna_boid.c b/source/blender/makesrna/intern/rna_boid.c
index 1dcc35c8fb3..6233649fb12 100644
--- a/source/blender/makesrna/intern/rna_boid.c
+++ b/source/blender/makesrna/intern/rna_boid.c
@@ -164,7 +164,8 @@ static PointerRNA rna_BoidState_active_boid_rule_get(PointerRNA *ptr)
}
return rna_pointer_inherit_refine(ptr, &RNA_BoidRule, NULL);
}
-static void rna_BoidState_active_boid_rule_index_range(PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax)
+static void rna_BoidState_active_boid_rule_index_range(PointerRNA *ptr, int *min, int *max,
+ int *UNUSED(softmin), int *UNUSED(softmax))
{
BoidState *state = (BoidState *)ptr->data;
*min = 0;
@@ -230,7 +231,7 @@ static PointerRNA rna_BoidSettings_active_boid_state_get(PointerRNA *ptr)
return rna_pointer_inherit_refine(ptr, &RNA_BoidState, NULL);
}
static void rna_BoidSettings_active_boid_state_index_range(PointerRNA *ptr, int *min, int *max,
- int *softmin, int *softmax)
+ int *UNUSED(softmin), int *UNUSED(softmax))
{
BoidSettings *boids = (BoidSettings *)ptr->data;
*min = 0;
diff --git a/source/blender/makesrna/intern/rna_color.c b/source/blender/makesrna/intern/rna_color.c
index 2fba4e9ed7b..d848acd5971 100644
--- a/source/blender/makesrna/intern/rna_color.c
+++ b/source/blender/makesrna/intern/rna_color.c
@@ -110,7 +110,8 @@ static void rna_CurveMapping_white_level_set(PointerRNA *ptr, const float *value
curvemapping_set_black_white(cumap, NULL, NULL);
}
-static void rna_CurveMapping_clipminx_range(PointerRNA *ptr, float *min, float *max, float *softmin, float *softmax)
+static void rna_CurveMapping_clipminx_range(PointerRNA *ptr, float *min, float *max,
+ float *UNUSED(softmin), float *UNUSED(softmax))
{
CurveMapping *cumap = (CurveMapping *)ptr->data;
@@ -118,7 +119,8 @@ static void rna_CurveMapping_clipminx_range(PointerRNA *ptr, float *min, float *
*max = cumap->clipr.xmax;
}
-static void rna_CurveMapping_clipminy_range(PointerRNA *ptr, float *min, float *max, float *softmin, float *softmax)
+static void rna_CurveMapping_clipminy_range(PointerRNA *ptr, float *min, float *max,
+ float *UNUSED(softmin), float *UNUSED(softmax))
{
CurveMapping *cumap = (CurveMapping *)ptr->data;
@@ -126,7 +128,8 @@ static void rna_CurveMapping_clipminy_range(PointerRNA *ptr, float *min, float *
*max = cumap->clipr.ymax;
}
-static void rna_CurveMapping_clipmaxx_range(PointerRNA *ptr, float *min, float *max, float *softmin, float *softmax)
+static void rna_CurveMapping_clipmaxx_range(PointerRNA *ptr, float *min, float *max,
+ float *UNUSED(softmin), float *UNUSED(softmax))
{
CurveMapping *cumap = (CurveMapping *)ptr->data;
@@ -134,7 +137,8 @@ static void rna_CurveMapping_clipmaxx_range(PointerRNA *ptr, float *min, float *
*max = 100.0f;
}
-static void rna_CurveMapping_clipmaxy_range(PointerRNA *ptr, float *min, float *max, float *softmin, float *softmax)
+static void rna_CurveMapping_clipmaxy_range(PointerRNA *ptr, float *min, float *max,
+ float *UNUSED(softmin), float *UNUSED(softmax))
{
CurveMapping *cumap = (CurveMapping *)ptr->data;
@@ -407,8 +411,8 @@ static void rna_ColorManagedDisplaySettings_display_device_set(struct PointerRNA
}
}
-static EnumPropertyItem *rna_ColorManagedDisplaySettings_display_device_itemf(bContext *UNUSED(C), PointerRNA *ptr,
- PropertyRNA *UNUSED(prop), int *free)
+static EnumPropertyItem *rna_ColorManagedDisplaySettings_display_device_itemf(
+ bContext *UNUSED(C), PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), int *free)
{
EnumPropertyItem *items = NULL;
int totitem = 0;
@@ -455,8 +459,8 @@ static void rna_ColorManagedViewSettings_view_transform_set(PointerRNA *ptr, int
}
}
-static EnumPropertyItem *rna_ColorManagedViewSettings_view_transform_itemf(bContext *C, PointerRNA *ptr,
- PropertyRNA *UNUSED(prop), int *free)
+static EnumPropertyItem *rna_ColorManagedViewSettings_view_transform_itemf(
+ bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), int *free)
{
Scene *scene = CTX_data_scene(C);
EnumPropertyItem *items = NULL;
@@ -488,8 +492,8 @@ static void rna_ColorManagedViewSettings_look_set(PointerRNA *ptr, int value)
}
}
-static EnumPropertyItem *rna_ColorManagedViewSettings_look_itemf(bContext *C, PointerRNA *ptr,
- PropertyRNA *UNUSED(prop), int *free)
+static EnumPropertyItem *rna_ColorManagedViewSettings_look_itemf(
+ bContext *UNUSED(C), PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), int *free)
{
EnumPropertyItem *items = NULL;
int totitem = 0;
@@ -534,8 +538,8 @@ static void rna_ColorManagedColorspaceSettings_colorspace_set(struct PointerRNA
}
}
-static EnumPropertyItem *rna_ColorManagedColorspaceSettings_colorspace_itemf(bContext *UNUSED(C), PointerRNA *ptr,
- PropertyRNA *UNUSED(prop), int *free)
+static EnumPropertyItem *rna_ColorManagedColorspaceSettings_colorspace_itemf(
+ bContext *UNUSED(C), PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), int *free)
{
EnumPropertyItem *items = NULL;
int totitem = 0;
diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c
index 10349748713..0c7c2ea1e49 100644
--- a/source/blender/makesrna/intern/rna_constraint.c
+++ b/source/blender/makesrna/intern/rna_constraint.c
@@ -344,7 +344,8 @@ static EnumPropertyItem *rna_Constraint_target_space_itemf(bContext *UNUSED(C),
return space_object_items;
}
-static void rna_ActionConstraint_minmax_range(PointerRNA *ptr, float *min, float *max, float *softmin, float *softmax)
+static void rna_ActionConstraint_minmax_range(PointerRNA *ptr, float *min, float *max,
+ float *UNUSED(softmin), float *UNUSED(softmax))
{
bConstraint *con = (bConstraint *)ptr->data;
bActionConstraint *acon = (bActionConstraint *)con->data;
@@ -504,7 +505,6 @@ static void rna_def_constrainttarget(BlenderRNA *brna)
static void rna_def_constraint_childof(BlenderRNA *brna)
{
- static int rna_matrix_dimsize_4x4[] = {4, 4};
StructRNA *srna;
PropertyRNA *prop;
diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c
index cd3b30687b3..bd4b8dd76b1 100644
--- a/source/blender/makesrna/intern/rna_curve.c
+++ b/source/blender/makesrna/intern/rna_curve.c
@@ -243,14 +243,16 @@ static void rna_Curve_texspace_size_set(PointerRNA *ptr, const float *values)
copy_v3_v3(cu->size, values);
}
-static void rna_Curve_material_index_range(PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax)
+static void rna_Curve_material_index_range(PointerRNA *ptr, int *min, int *max,
+ int *UNUSED(softmin), int *UNUSED(softmax))
{
Curve *cu = (Curve *)ptr->id.data;
*min = 0;
*max = max_ii(0, cu->totcol - 1);
}
-static void rna_Curve_active_textbox_index_range(PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax)
+static void rna_Curve_active_textbox_index_range(PointerRNA *ptr, int *min, int *max,
+ int *UNUSED(softmin), int *UNUSED(softmax))
{
Curve *cu = (Curve *)ptr->id.data;
*min = 0;
diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c
index d4b1130763b..fe9e9573957 100644
--- a/source/blender/makesrna/intern/rna_define.c
+++ b/source/blender/makesrna/intern/rna_define.c
@@ -574,13 +574,13 @@ void RNA_define_free(BlenderRNA *UNUSED(brna))
DefRNA.error = 0;
}
-void RNA_define_verify_sdna(int verify)
+void RNA_define_verify_sdna(bool verify)
{
DefRNA.verify = verify;
}
#ifndef RNA_RUNTIME
-void RNA_define_animate_sdna(int animate)
+void RNA_define_animate_sdna(bool animate)
{
DefRNA.animate = animate;
}
@@ -1253,6 +1253,11 @@ void RNA_def_property_array(PropertyRNA *prop, int length)
}
}
+/* common args for length */
+const int rna_matrix_dimsize_3x3[] = {3, 3};
+const int rna_matrix_dimsize_4x4[] = {4, 4};
+const int rna_matrix_dimsize_4x2[] = {4, 2};
+
void RNA_def_property_multi_array(PropertyRNA *prop, int dimension, const int length[])
{
StructRNA *srna = DefRNA.laststruct;
@@ -2124,7 +2129,7 @@ void RNA_def_property_update(PropertyRNA *prop, int noteflag, const char *func)
prop->update = (UpdateFunc)func;
}
-void RNA_def_property_update_runtime(PropertyRNA *prop, void *func)
+void RNA_def_property_update_runtime(PropertyRNA *prop, const void *func)
{
prop->update = func;
}
diff --git a/source/blender/makesrna/intern/rna_dynamicpaint.c b/source/blender/makesrna/intern/rna_dynamicpaint.c
index ffcd1f823b2..e13ec1f09a4 100644
--- a/source/blender/makesrna/intern/rna_dynamicpaint.c
+++ b/source/blender/makesrna/intern/rna_dynamicpaint.c
@@ -96,12 +96,12 @@ static char *rna_DynamicPaintSurface_path(PointerRNA *ptr)
* Surfaces
*/
-static void rna_DynamicPaint_redoModifier(Main *bmain, Scene *scene, PointerRNA *ptr)
+static void rna_DynamicPaint_redoModifier(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
DAG_id_tag_update(ptr->id.data, OB_RECALC_DATA);
}
-static void rna_DynamicPaintSurfaces_updateFrames(Main *bmain, Scene *scene, PointerRNA *ptr)
+static void rna_DynamicPaintSurfaces_updateFrames(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
dynamicPaint_cacheUpdateFrames((DynamicPaintSurface *)ptr->data);
}
@@ -135,7 +135,7 @@ static void rna_DynamicPaintSurface_changePreview(Main *bmain, Scene *scene, Poi
rna_DynamicPaint_redoModifier(bmain, scene, ptr);
}
-static void rna_DynamicPaintSurface_uniqueName(Main *bmain, Scene *scene, PointerRNA *ptr)
+static void rna_DynamicPaintSurface_uniqueName(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
dynamicPaintSurface_setUniqueName((DynamicPaintSurface *)ptr->data, ((DynamicPaintSurface *)ptr->data)->name);
}
@@ -197,7 +197,8 @@ static void rna_Surface_active_point_index_set(struct PointerRNA *ptr, int value
return;
}
-static void rna_Surface_active_point_range(PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax)
+static void rna_Surface_active_point_range(PointerRNA *ptr, int *min, int *max,
+ int *UNUSED(softmin), int *UNUSED(softmax))
{
DynamicPaintCanvasSettings *canvas = (DynamicPaintCanvasSettings *)ptr->data;
@@ -244,8 +245,8 @@ static int rna_DynamicPaint_is_output_exists(DynamicPaintSurface *surface, Objec
}
-static EnumPropertyItem *rna_DynamicPaint_surface_type_itemf(bContext *C, PointerRNA *ptr,
- PropertyRNA *UNUSED(prop), int *free)
+static EnumPropertyItem *rna_DynamicPaint_surface_type_itemf(
+ bContext *UNUSED(C), PointerRNA *ptr, PropertyRNA *UNUSED(prop), int *free)
{
DynamicPaintSurface *surface = (DynamicPaintSurface *)ptr->data;
diff --git a/source/blender/makesrna/intern/rna_fcurve.c b/source/blender/makesrna/intern/rna_fcurve.c
index 2ad8ded4656..4b50127d999 100644
--- a/source/blender/makesrna/intern/rna_fcurve.c
+++ b/source/blender/makesrna/intern/rna_fcurve.c
@@ -459,7 +459,8 @@ static void rna_FModifier_active_set(PointerRNA *ptr, int UNUSED(value))
fm->flag |= FMODIFIER_FLAG_ACTIVE;
}
-static void rna_FModifier_start_frame_range(PointerRNA *ptr, float *min, float *max, float *softmin, float *softmax)
+static void rna_FModifier_start_frame_range(PointerRNA *ptr, float *min, float *max,
+ float *UNUSED(softmin), float *UNUSED(softmax))
{
FModifier *fcm = (FModifier *)ptr->data;
@@ -467,7 +468,8 @@ static void rna_FModifier_start_frame_range(PointerRNA *ptr, float *min, float *
*max = (fcm->flag & FMODIFIER_FLAG_RANGERESTRICT) ? fcm->efra : MAXFRAMEF;
}
-static void rna_FModifier_end_frame_range(PointerRNA *ptr, float *min, float *max, float *softmin, float *softmax)
+static void rna_FModifier_end_frame_range(PointerRNA *ptr, float *min, float *max,
+ float *UNUSED(softmin), float *UNUSED(softmax))
{
FModifier *fcm = (FModifier *)ptr->data;
@@ -475,7 +477,8 @@ static void rna_FModifier_end_frame_range(PointerRNA *ptr, float *min, float *ma
*max = MAXFRAMEF;
}
-static void rna_FModifier_blending_range(PointerRNA *ptr, float *min, float *max, float *softmin, float *softmax)
+static void rna_FModifier_blending_range(PointerRNA *ptr, float *min, float *max,
+ float *UNUSED(softmin), float *UNUSED(softmax))
{
FModifier *fcm = (FModifier *)ptr->data;
@@ -524,7 +527,8 @@ static void rna_FModifierGenerator_coefficients_set(PointerRNA *ptr, const float
memcpy(gen->coefficients, values, gen->arraysize * sizeof(float));
}
-static void rna_FModifierLimits_minx_range(PointerRNA *ptr, float *min, float *max, float *softmin, float *softmax)
+static void rna_FModifierLimits_minx_range(PointerRNA *ptr, float *min, float *max,
+ float *UNUSED(softmin), float *UNUSED(softmax))
{
FModifier *fcm = (FModifier *)ptr->data;
FMod_Limits *data = fcm->data;
@@ -533,7 +537,8 @@ static void rna_FModifierLimits_minx_range(PointerRNA *ptr, float *min, float *m
*max = (data->flag & FCM_LIMIT_XMAX) ? data->rect.xmax : MAXFRAMEF;
}
-static void rna_FModifierLimits_maxx_range(PointerRNA *ptr, float *min, float *max, float *softmin, float *softmax)
+static void rna_FModifierLimits_maxx_range(PointerRNA *ptr, float *min, float *max,
+ float *UNUSED(softmin), float *UNUSED(softmax))
{
FModifier *fcm = (FModifier *)ptr->data;
FMod_Limits *data = fcm->data;
@@ -542,7 +547,8 @@ static void rna_FModifierLimits_maxx_range(PointerRNA *ptr, float *min, float *m
*max = MAXFRAMEF;
}
-static void rna_FModifierLimits_miny_range(PointerRNA *ptr, float *min, float *max, float *softmin, float *softmax)
+static void rna_FModifierLimits_miny_range(PointerRNA *ptr, float *min, float *max,
+ float *UNUSED(softmin), float *UNUSED(softmax))
{
FModifier *fcm = (FModifier *)ptr->data;
FMod_Limits *data = fcm->data;
@@ -551,7 +557,8 @@ static void rna_FModifierLimits_miny_range(PointerRNA *ptr, float *min, float *m
*max = (data->flag & FCM_LIMIT_YMAX) ? data->rect.ymax : FLT_MAX;
}
-static void rna_FModifierLimits_maxy_range(PointerRNA *ptr, float *min, float *max, float *softmin, float *softmax)
+static void rna_FModifierLimits_maxy_range(PointerRNA *ptr, float *min, float *max,
+ float *UNUSED(softmin), float *UNUSED(softmax))
{
FModifier *fcm = (FModifier *)ptr->data;
FMod_Limits *data = fcm->data;
@@ -562,7 +569,7 @@ static void rna_FModifierLimits_maxy_range(PointerRNA *ptr, float *min, float *m
static void rna_FModifierStepped_start_frame_range(PointerRNA *ptr, float *min, float *max,
- float *softmin, float *softmax)
+ float *UNUSED(softmin), float *UNUSED(softmax))
{
FModifier *fcm = (FModifier *)ptr->data;
FMod_Stepped *data = fcm->data;
@@ -572,7 +579,7 @@ static void rna_FModifierStepped_start_frame_range(PointerRNA *ptr, float *min,
}
static void rna_FModifierStepped_end_frame_range(PointerRNA *ptr, float *min, float *max,
- float *softmin, float *softmax)
+ float *UNUSED(softmin), float *UNUSED(softmax))
{
FModifier *fcm = (FModifier *)ptr->data;
FMod_Stepped *data = fcm->data;
diff --git a/source/blender/makesrna/intern/rna_gpencil.c b/source/blender/makesrna/intern/rna_gpencil.c
index 439bc51896f..6423763c49c 100644
--- a/source/blender/makesrna/intern/rna_gpencil.c
+++ b/source/blender/makesrna/intern/rna_gpencil.c
@@ -354,15 +354,15 @@ static void rna_def_gpencil_strokes_api(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_property_srna(cprop, "GPencilStrokes");
srna = RNA_def_struct(brna, "GPencilStrokes", NULL);
RNA_def_struct_sdna(srna, "bGPDframe");
- RNA_def_struct_ui_text(srna, "Grease Pencil Frames", "Collection of grease pencil frames");
+ RNA_def_struct_ui_text(srna, "Grease Pencil Frames", "Collection of grease pencil stroke");
func = RNA_def_function(srna, "new", "rna_GPencil_stroke_new");
- RNA_def_function_ui_description(func, "Add a new grease pencil frame");
+ RNA_def_function_ui_description(func, "Add a new grease pencil stroke");
parm = RNA_def_pointer(func, "stroke", "GPencilStroke", "", "The newly created stroke");
RNA_def_function_return(func, parm);
func = RNA_def_function(srna, "remove", "rna_GPencil_stroke_remove");
- RNA_def_function_ui_description(func, "Remove a grease pencil frame");
+ RNA_def_function_ui_description(func, "Remove a grease pencil stroke");
RNA_def_function_flag(func, FUNC_USE_REPORTS);
parm = RNA_def_pointer(func, "stroke", "GPencilStroke", "Stroke", "The stroke to remove");
RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
@@ -390,7 +390,8 @@ static void rna_def_gpencil_frame(BlenderRNA *brna)
/* Frame Number */
prop = RNA_def_property(srna, "frame_number", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "framenum");
- RNA_def_property_range(prop, MINFRAME, MAXFRAME); /* XXX note: this cannot occur on the same frame as another sketch */
+ /* XXX note: this cannot occur on the same frame as another sketch */
+ RNA_def_property_range(prop, MINAFRAME, MAXFRAME);
RNA_def_property_ui_text(prop, "Frame Number", "The frame on which this sketch appears");
/* Flags */
@@ -421,7 +422,8 @@ static void rna_def_gpencil_frames_api(BlenderRNA *brna, PropertyRNA *cprop)
func = RNA_def_function(srna, "new", "rna_GPencil_frame_new");
RNA_def_function_ui_description(func, "Add a new grease pencil frame");
RNA_def_function_flag(func, FUNC_USE_REPORTS);
- parm = RNA_def_int(func, "frame_number", 1, MINFRAME, MAXFRAME, "Frame Number", "The frame on which this sketch appears", MINFRAME, MAXFRAME);
+ parm = RNA_def_int(func, "frame_number", 1, MINAFRAME, MAXFRAME, "Frame Number",
+ "The frame on which this sketch appears", MINAFRAME, MAXFRAME);
RNA_def_property_flag(parm, PROP_REQUIRED);
parm = RNA_def_pointer(func, "frame", "GPencilFrame", "", "The newly created frame");
RNA_def_function_return(func, parm);
diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h
index f1e1569c87d..7950ed424ee 100644
--- a/source/blender/makesrna/intern/rna_internal.h
+++ b/source/blender/makesrna/intern/rna_internal.h
@@ -124,8 +124,9 @@ typedef struct BlenderDefRNA {
extern BlenderDefRNA DefRNA;
/* Define functions for all types */
-
+#ifndef __RNA_ACCESS_H__
extern BlenderRNA BLENDER_RNA;
+#endif
void RNA_def_ID(struct BlenderRNA *brna);
void RNA_def_action(struct BlenderRNA *brna);
@@ -332,8 +333,10 @@ extern CollectionPropertyRNA rna_PropertyGroupItem_idp_array;
extern FloatPropertyRNA rna_PropertyGroupItem_double;
extern FloatPropertyRNA rna_PropertyGroupItem_double_array;
+#ifndef __RNA_ACCESS_H__
extern StructRNA RNA_PropertyGroupItem;
extern StructRNA RNA_PropertyGroup;
+#endif
struct IDProperty *rna_idproperty_check(struct PropertyRNA **prop, struct PointerRNA *ptr);
@@ -421,4 +424,10 @@ int rna_IDMaterials_assign_int(struct PointerRNA *ptr, int key, const struct Poi
void rna_RenderLayer_rect_set(PointerRNA *ptr, const float *values);
void rna_RenderPass_rect_set(PointerRNA *ptr, const float *values);
+#ifdef RNA_RUNTIME
+# ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wredundant-decls"
+# endif
+#endif
+
#endif /* __RNA_INTERNAL_H__ */
diff --git a/source/blender/makesrna/intern/rna_key.c b/source/blender/makesrna/intern/rna_key.c
index d5c9ec53b20..a20cb73b3aa 100644
--- a/source/blender/makesrna/intern/rna_key.c
+++ b/source/blender/makesrna/intern/rna_key.c
@@ -99,7 +99,8 @@ static void rna_ShapeKey_value_set(PointerRNA *ptr, float value)
data->curval = value;
}
-static void rna_ShapeKey_value_range(PointerRNA *ptr, float *min, float *max, float *softmin, float *softmax)
+static void rna_ShapeKey_value_range(PointerRNA *ptr, float *min, float *max,
+ float *UNUSED(softmin), float *UNUSED(softmax))
{
KeyBlock *data = (KeyBlock *)ptr->data;
@@ -110,7 +111,8 @@ static void rna_ShapeKey_value_range(PointerRNA *ptr, float *min, float *max, fl
/* epsilon for how close one end of shapekey range can get to the other */
#define SHAPEKEY_SLIDER_TOL 0.001f
-static void rna_ShapeKey_slider_min_range(PointerRNA *ptr, float *min, float *max, float *softmin, float *softmax)
+static void rna_ShapeKey_slider_min_range(PointerRNA *ptr, float *min, float *max,
+ float *UNUSED(softmin), float *UNUSED(softmax))
{
KeyBlock *data = (KeyBlock *)ptr->data;
@@ -128,7 +130,8 @@ static void rna_ShapeKey_slider_min_set(PointerRNA *ptr, float value)
data->slidermin = value;
}
-static void rna_ShapeKey_slider_max_range(PointerRNA *ptr, float *min, float *max, float *softmin, float *softmax)
+static void rna_ShapeKey_slider_max_range(PointerRNA *ptr, float *min, float *max,
+ float *UNUSED(softmin), float *UNUSED(softmax))
{
KeyBlock *data = (KeyBlock *)ptr->data;
diff --git a/source/blender/makesrna/intern/rna_lamp.c b/source/blender/makesrna/intern/rna_lamp.c
index f59f3db3652..63fc5dbdbbd 100644
--- a/source/blender/makesrna/intern/rna_lamp.c
+++ b/source/blender/makesrna/intern/rna_lamp.c
@@ -132,7 +132,7 @@ static StructRNA *rna_Lamp_refine(struct PointerRNA *ptr)
}
}
-static void rna_Lamp_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *ptr)
+static void rna_Lamp_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
Lamp *la = ptr->id.data;
diff --git a/source/blender/makesrna/intern/rna_linestyle.c b/source/blender/makesrna/intern/rna_linestyle.c
index 660ef57dbfe..03319a9ccf8 100644
--- a/source/blender/makesrna/intern/rna_linestyle.c
+++ b/source/blender/makesrna/intern/rna_linestyle.c
@@ -254,7 +254,7 @@ static void rna_LineStyleGeometryModifier_name_set(PointerRNA *ptr, const char *
#include "BLI_math.h"
static void rna_def_modifier_type_common(StructRNA *srna, EnumPropertyItem *modifier_type_items,
- char *set_name_func, int blend, int color)
+ const char *set_name_func, const bool blend, const bool color)
{
PropertyRNA *prop;
diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c
index 8104fc169f6..dffe392e6f1 100644
--- a/source/blender/makesrna/intern/rna_main_api.c
+++ b/source/blender/makesrna/intern/rna_main_api.c
@@ -832,7 +832,7 @@ static Mask *rna_Main_mask_new(Main *bmain, const char *name)
{
Mask *mask;
- mask = BKE_mask_new(bmain, "Mask");
+ mask = BKE_mask_new(bmain, name);
return mask;
}
diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c
index ed2dba907e8..e9f506b6f0b 100644
--- a/source/blender/makesrna/intern/rna_material.c
+++ b/source/blender/makesrna/intern/rna_material.c
@@ -93,7 +93,7 @@ EnumPropertyItem ramp_blend_items[] = {
#include "ED_node.h"
-static void rna_Material_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *ptr)
+static void rna_Material_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
Material *ma = ptr->id.data;
@@ -101,7 +101,7 @@ static void rna_Material_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *p
WM_main_add_notifier(NC_MATERIAL | ND_SHADING, ma);
}
-static void rna_Material_update_previews(Main *bmain, Scene *scene, PointerRNA *ptr)
+static void rna_Material_update_previews(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
Material *ma = ptr->id.data;
@@ -111,7 +111,7 @@ static void rna_Material_update_previews(Main *bmain, Scene *scene, PointerRNA *
WM_main_add_notifier(NC_MATERIAL | ND_SHADING_PREVIEW, ma);
}
-static void rna_Material_draw_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *ptr)
+static void rna_Material_draw_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
Material *ma = ptr->id.data;
@@ -202,7 +202,8 @@ static void rna_Material_active_node_material_set(PointerRNA *ptr, PointerRNA va
nodeSetActiveID(ma->nodetree, ID_MA, &ma_act->id);
}
-static void rna_MaterialStrand_start_size_range(PointerRNA *ptr, float *min, float *max, float *softmin, float *softmax)
+static void rna_MaterialStrand_start_size_range(PointerRNA *ptr, float *min, float *max,
+ float *UNUSED(softmin), float *UNUSED(softmax))
{
Material *ma = (Material *)ptr->id.data;
@@ -216,7 +217,8 @@ static void rna_MaterialStrand_start_size_range(PointerRNA *ptr, float *min, flo
}
}
-static void rna_MaterialStrand_end_size_range(PointerRNA *ptr, float *min, float *max, float *softmin, float *softmax)
+static void rna_MaterialStrand_end_size_range(PointerRNA *ptr, float *min, float *max,
+ float *UNUSED(softmin), float *UNUSED(softmax))
{
Material *ma = (Material *)ptr->id.data;
diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c
index 1376eccb448..fe6f33abc8c 100644
--- a/source/blender/makesrna/intern/rna_mesh.c
+++ b/source/blender/makesrna/intern/rna_mesh.c
@@ -184,18 +184,22 @@ static void rna_MeshEdgeLayer_name_set(PointerRNA *ptr, const char *value)
rna_cd_layer_name_set(rna_mesh_edata(ptr), (CustomDataLayer *)ptr->data, value);
}
#endif
+#if 0
static void rna_MeshPolyLayer_name_set(PointerRNA *ptr, const char *value)
{
rna_cd_layer_name_set(rna_mesh_pdata(ptr), (CustomDataLayer *)ptr->data, value);
}
+#endif
static void rna_MeshLoopLayer_name_set(PointerRNA *ptr, const char *value)
{
rna_cd_layer_name_set(rna_mesh_ldata(ptr), (CustomDataLayer *)ptr->data, value);
}
+#if 0
static void rna_MeshTessfaceLayer_name_set(PointerRNA *ptr, const char *value)
{
rna_cd_layer_name_set(rna_mesh_fdata(ptr), (CustomDataLayer *)ptr->data, value);
}
+#endif
/* only for layers shared between types */
static void rna_MeshAnyLayer_name_set(PointerRNA *ptr, const char *value)
{
@@ -207,7 +211,7 @@ static void rna_MeshAnyLayer_name_set(PointerRNA *ptr, const char *value)
/* -------------------------------------------------------------------- */
/* Update Callbacks */
-static void rna_Mesh_update_data(Main *bmain, Scene *scene, PointerRNA *ptr)
+static void rna_Mesh_update_data(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
ID *id = ptr->id.data;
@@ -227,7 +231,7 @@ static void rna_Mesh_update_data_edit_color(Main *bmain, Scene *scene, PointerRN
}
}
-static void rna_Mesh_update_select(Main *bmain, Scene *scene, PointerRNA *ptr)
+static void rna_Mesh_update_select(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
ID *id = ptr->id.data;
/* cheating way for importers to avoid slow updates */
@@ -236,7 +240,7 @@ static void rna_Mesh_update_select(Main *bmain, Scene *scene, PointerRNA *ptr)
}
}
-void rna_Mesh_update_draw(Main *bmain, Scene *scene, PointerRNA *ptr)
+void rna_Mesh_update_draw(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
ID *id = ptr->id.data;
/* cheating way for importers to avoid slow updates */
@@ -646,7 +650,7 @@ static int rna_CustomDataLayer_active_get(PointerRNA *ptr, CustomData *data, int
else return (n == CustomData_get_active_layer_index(data, type));
}
-static int rna_CustomDataLayer_clone_get(PointerRNA *ptr, CustomData *data, int type, int render)
+static int rna_CustomDataLayer_clone_get(PointerRNA *ptr, CustomData *data, int type)
{
int n = ((CustomDataLayer *)ptr->data) - data->layers;
@@ -674,7 +678,7 @@ static void rna_CustomDataLayer_active_set(PointerRNA *ptr, CustomData *data, in
BKE_mesh_update_customdata_pointers(me, true);
}
-static void rna_CustomDataLayer_clone_set(PointerRNA *ptr, CustomData *data, int value, int type, int render)
+static void rna_CustomDataLayer_clone_set(PointerRNA *ptr, CustomData *data, int value, int type)
{
int n = ((CustomDataLayer *)ptr->data) - data->layers;
@@ -684,6 +688,14 @@ static void rna_CustomDataLayer_clone_set(PointerRNA *ptr, CustomData *data, int
CustomData_set_layer_clone_index(data, type, n);
}
+/* Generic UV rename! */
+static void rna_MeshUVLayer_name_set(PointerRNA *ptr, const char *name)
+{
+ char buf[MAX_CUSTOMDATA_LAYER_NAME];
+ BLI_strncpy_utf8(buf, name, MAX_CUSTOMDATA_LAYER_NAME);
+ BKE_mesh_uv_cdlayer_rename(rna_mesh(ptr), ((CustomDataLayer *)ptr->data)->name, buf, true);
+}
+
/* uv_layers */
DEFINE_CUSTOMDATA_LAYER_COLLECTION(uv_layer, ldata, CD_MLOOPUV)
@@ -748,7 +760,7 @@ static int rna_MeshTextureFaceLayer_active_get(PointerRNA *ptr)
static int rna_MeshTextureFaceLayer_clone_get(PointerRNA *ptr)
{
- return rna_CustomDataLayer_clone_get(ptr, rna_mesh_fdata(ptr), CD_MTFACE, 0);
+ return rna_CustomDataLayer_clone_get(ptr, rna_mesh_fdata(ptr), CD_MTFACE);
}
static void rna_MeshTextureFaceLayer_active_render_set(PointerRNA *ptr, int value)
@@ -763,7 +775,7 @@ static void rna_MeshTextureFaceLayer_active_set(PointerRNA *ptr, int value)
static void rna_MeshTextureFaceLayer_clone_set(PointerRNA *ptr, int value)
{
- rna_CustomDataLayer_clone_set(ptr, rna_mesh_fdata(ptr), value, CD_MTFACE, 0);
+ rna_CustomDataLayer_clone_set(ptr, rna_mesh_fdata(ptr), value, CD_MTFACE);
}
/* poly uv_textures */
@@ -799,7 +811,7 @@ static int rna_MeshTexturePolyLayer_active_get(PointerRNA *ptr)
static int rna_MeshTexturePolyLayer_clone_get(PointerRNA *ptr)
{
- return rna_CustomDataLayer_clone_get(ptr, rna_mesh_pdata(ptr), CD_MTEXPOLY, 0);
+ return rna_CustomDataLayer_clone_get(ptr, rna_mesh_pdata(ptr), CD_MTEXPOLY);
}
static void rna_MeshTexturePolyLayer_active_render_set(PointerRNA *ptr, int value)
@@ -814,7 +826,7 @@ static void rna_MeshTexturePolyLayer_active_set(PointerRNA *ptr, int value)
static void rna_MeshTexturePolyLayer_clone_set(PointerRNA *ptr, int value)
{
- rna_CustomDataLayer_clone_set(ptr, rna_mesh_pdata(ptr), value, CD_MTEXPOLY, 0);
+ rna_CustomDataLayer_clone_set(ptr, rna_mesh_pdata(ptr), value, CD_MTEXPOLY);
}
/* vertex_color_layers */
@@ -906,7 +918,7 @@ static int rna_MeshFloatPropertyLayer_data_length(PointerRNA *ptr)
return me->totpoly;
}
-static int rna_float_layer_check(CollectionPropertyIterator *iter, void *data)
+static int rna_float_layer_check(CollectionPropertyIterator *UNUSED(iter), void *data)
{
CustomDataLayer *layer = (CustomDataLayer *)data;
return (layer->type != CD_PROP_FLT);
@@ -924,7 +936,7 @@ static int rna_Mesh_polygon_float_layers_length(PointerRNA *ptr)
return CustomData_number_of_layers(rna_mesh_pdata(ptr), CD_PROP_FLT);
}
-static int rna_int_layer_check(CollectionPropertyIterator *iter, void *data)
+static int rna_int_layer_check(CollectionPropertyIterator *UNUSED(iter), void *data)
{
CustomDataLayer *layer = (CustomDataLayer *)data;
return (layer->type != CD_PROP_INT);
@@ -955,7 +967,7 @@ static int rna_Mesh_polygon_int_layers_length(PointerRNA *ptr)
return CustomData_number_of_layers(rna_mesh_pdata(ptr), CD_PROP_INT);
}
-static int rna_string_layer_check(CollectionPropertyIterator *iter, void *data)
+static int rna_string_layer_check(CollectionPropertyIterator *UNUSED(iter), void *data)
{
CustomDataLayer *layer = (CustomDataLayer *)data;
return (layer->type != CD_PROP_STR);
@@ -997,7 +1009,7 @@ static char *rna_MeshSkinVertexLayer_path(PointerRNA *ptr)
return BLI_sprintfN("skin_vertices[\"%s\"]", name_esc);
}
-static char *rna_VertCustomData_data_path(PointerRNA *ptr, char *collection, int type);
+static char *rna_VertCustomData_data_path(PointerRNA *ptr, const char *collection, int type);
static char *rna_MeshSkinVertex_path(PointerRNA *ptr)
{
return rna_VertCustomData_data_path(ptr, "skin_vertices", CD_MVERT_SKIN);
@@ -1226,7 +1238,7 @@ static char *rna_MeshTexturePolyLayer_path(PointerRNA *ptr)
return BLI_sprintfN("uv_textures[\"%s\"]", name_esc);
}
-static char *rna_VertCustomData_data_path(PointerRNA *ptr, char *collection, int type)
+static char *rna_VertCustomData_data_path(PointerRNA *ptr, const char *collection, int type)
{
CustomDataLayer *cdl;
Mesh *me = rna_mesh(ptr);
@@ -1247,7 +1259,7 @@ static char *rna_VertCustomData_data_path(PointerRNA *ptr, char *collection, int
return NULL;
}
-static char *rna_PolyCustomData_data_path(PointerRNA *ptr, char *collection, int type)
+static char *rna_PolyCustomData_data_path(PointerRNA *ptr, const char *collection, int type)
{
CustomDataLayer *cdl;
Mesh *me = rna_mesh(ptr);
@@ -1268,7 +1280,7 @@ static char *rna_PolyCustomData_data_path(PointerRNA *ptr, char *collection, int
return NULL;
}
-static char *rna_LoopCustomData_data_path(PointerRNA *ptr, char *collection, int type)
+static char *rna_LoopCustomData_data_path(PointerRNA *ptr, const char *collection, int type)
{
CustomDataLayer *cdl;
Mesh *me = rna_mesh(ptr);
@@ -1289,7 +1301,7 @@ static char *rna_LoopCustomData_data_path(PointerRNA *ptr, char *collection, int
return NULL;
}
-static char *rna_FaceCustomData_data_path(PointerRNA *ptr, char *collection, int type)
+static char *rna_FaceCustomData_data_path(PointerRNA *ptr, const char *collection, int type)
{
CustomDataLayer *cdl;
Mesh *me = rna_mesh(ptr);
@@ -1475,7 +1487,7 @@ static PointerRNA rna_Mesh_tessface_vertex_color_new(struct Mesh *me, ReportList
return ptr;
}
-static PointerRNA rna_Mesh_polygon_int_property_new(struct Mesh *me, struct bContext *C, const char *name)
+static PointerRNA rna_Mesh_polygon_int_property_new(struct Mesh *me, const char *name)
{
PointerRNA ptr;
CustomDataLayer *cdl = NULL;
@@ -1490,7 +1502,7 @@ static PointerRNA rna_Mesh_polygon_int_property_new(struct Mesh *me, struct bCon
return ptr;
}
-static PointerRNA rna_Mesh_polygon_float_property_new(struct Mesh *me, struct bContext *C, const char *name)
+static PointerRNA rna_Mesh_polygon_float_property_new(struct Mesh *me, const char *name)
{
PointerRNA ptr;
CustomDataLayer *cdl = NULL;
@@ -1505,7 +1517,7 @@ static PointerRNA rna_Mesh_polygon_float_property_new(struct Mesh *me, struct bC
return ptr;
}
-static PointerRNA rna_Mesh_polygon_string_property_new(struct Mesh *me, struct bContext *C, const char *name)
+static PointerRNA rna_Mesh_polygon_string_property_new(struct Mesh *me, const char *name)
{
PointerRNA ptr;
CustomDataLayer *cdl = NULL;
@@ -1961,7 +1973,7 @@ static void rna_def_mloopuv(BlenderRNA *brna)
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
RNA_def_struct_name_property(srna, prop);
- RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MeshLoopLayer_name_set");
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MeshUVLayer_name_set");
RNA_def_property_ui_text(prop, "Name", "Name of UV map");
RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
@@ -1999,7 +2011,7 @@ static void rna_def_mtface(BlenderRNA *brna)
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
RNA_def_struct_name_property(srna, prop);
- RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MeshTessfaceLayer_name_set");
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MeshUVLayer_name_set");
RNA_def_property_ui_text(prop, "Name", "Name of UV map");
RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
@@ -2111,7 +2123,7 @@ static void rna_def_mtexpoly(BlenderRNA *brna)
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
RNA_def_struct_name_property(srna, prop);
- RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MeshPolyLayer_name_set");
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MeshUVLayer_name_set");
RNA_def_property_ui_text(prop, "Name", "Name of UV map");
RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
@@ -2677,7 +2689,6 @@ static void rna_def_polygon_int_layers(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_struct_ui_text(srna, "Int Properties", "Collection of int properties");
func = RNA_def_function(srna, "new", "rna_Mesh_polygon_int_property_new");
- RNA_def_function_flag(func, FUNC_USE_CONTEXT);
RNA_def_function_ui_description(func, "Add a integer property layer to Mesh");
RNA_def_string(func, "name", "Int Prop", 0, "", "Int property name");
parm = RNA_def_pointer(func, "layer", "MeshIntPropertyLayer", "", "The newly created layer");
@@ -2699,7 +2710,6 @@ static void rna_def_polygon_float_layers(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_struct_ui_text(srna, "Float Properties", "Collection of float properties");
func = RNA_def_function(srna, "new", "rna_Mesh_polygon_float_property_new");
- RNA_def_function_flag(func, FUNC_USE_CONTEXT);
RNA_def_function_ui_description(func, "Add a float property layer to Mesh");
RNA_def_string(func, "name", "Float Prop", 0, "", "Float property name");
parm = RNA_def_pointer(func, "layer", "MeshFloatPropertyLayer", "", "The newly created layer");
@@ -2721,7 +2731,6 @@ static void rna_def_polygon_string_layers(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_struct_ui_text(srna, "String Properties", "Collection of string properties");
func = RNA_def_function(srna, "new", "rna_Mesh_polygon_string_property_new");
- RNA_def_function_flag(func, FUNC_USE_CONTEXT);
RNA_def_function_ui_description(func, "Add a string property layer to Mesh");
RNA_def_string(func, "name", "String Prop", 0, "", "String property name");
parm = RNA_def_pointer(func, "layer", "MeshStringPropertyLayer", "", "The newly created layer");
diff --git a/source/blender/makesrna/intern/rna_mesh_api.c b/source/blender/makesrna/intern/rna_mesh_api.c
index 4bf879f689f..a25f56f2259 100644
--- a/source/blender/makesrna/intern/rna_mesh_api.c
+++ b/source/blender/makesrna/intern/rna_mesh_api.c
@@ -48,7 +48,7 @@
#include "DNA_mesh_types.h"
-static const char *rna_Mesh_unit_test_compare(struct Mesh *mesh, bContext *C, struct Mesh *mesh2)
+static const char *rna_Mesh_unit_test_compare(struct Mesh *mesh, struct Mesh *mesh2)
{
const char *ret = BKE_mesh_cmp(mesh, mesh2, FLT_EPSILON * 60);
@@ -130,7 +130,7 @@ void RNA_api_mesh(StructRNA *srna)
parm = RNA_def_float(func, "split_angle", M_PI, 0.0f, M_PI, "",
"Angle between polys' normals above which an edge is always sharp (180° to disable)",
0.0f, M_PI);
- RNA_def_property_subtype(parm, PROP_UNIT_ROTATION);
+ RNA_def_property_subtype(parm, (PropertySubType)PROP_UNIT_ROTATION);
func = RNA_def_function(srna, "free_normals_split", "rna_Mesh_free_normals_split");
RNA_def_function_ui_description(func, "Free split vertex normals");
@@ -155,7 +155,6 @@ void RNA_api_mesh(StructRNA *srna)
func = RNA_def_function(srna, "unit_test_compare", "rna_Mesh_unit_test_compare");
RNA_def_pointer(func, "mesh", "Mesh", "", "Mesh to compare to");
- RNA_def_function_flag(func, FUNC_USE_CONTEXT);
/* return value */
parm = RNA_def_string(func, "result", "nothing", 64, "Return value", "String description of result of comparison");
RNA_def_function_return(func, parm);
diff --git a/source/blender/makesrna/intern/rna_mesh_utils.h b/source/blender/makesrna/intern/rna_mesh_utils.h
index dfe36da033b..c0ea1a153ff 100644
--- a/source/blender/makesrna/intern/rna_mesh_utils.h
+++ b/source/blender/makesrna/intern/rna_mesh_utils.h
@@ -32,7 +32,8 @@
/* Define the accessors for a basic CustomDataLayer collection */
#define DEFINE_CUSTOMDATA_LAYER_COLLECTION(collection_name, customdata_type, layer_type) \
/* check */ \
- static int rna_##collection_name##_check(CollectionPropertyIterator *iter, void *data) \
+ static int rna_##collection_name##_check( \
+ CollectionPropertyIterator *UNUSED(iter), void *data) \
{ \
CustomDataLayer *layer = (CustomDataLayer *)data; \
return (layer->type != layer_type); \
@@ -59,8 +60,9 @@
return data ? CustomData_number_of_layers(data, layer_type) : 0; \
} \
/* index range */ \
- static void rna_Mesh_##collection_name##_index_range(PointerRNA *ptr, int *min, int *max, \
- int *softmin, int *softmax) \
+ static void rna_Mesh_##collection_name##_index_range( \
+ PointerRNA *ptr, int *min, int *max, \
+ int *UNUSED(softmin), int *UNUSED(softmax)) \
{ \
CustomData *data = rna_mesh_##customdata_type(ptr); \
*min = 0; \
diff --git a/source/blender/makesrna/intern/rna_meta.c b/source/blender/makesrna/intern/rna_meta.c
index f01b5af7aaa..6bf7c8926e8 100644
--- a/source/blender/makesrna/intern/rna_meta.c
+++ b/source/blender/makesrna/intern/rna_meta.c
@@ -321,12 +321,14 @@ static void rna_def_metaball(BlenderRNA *brna)
prop = RNA_def_property(srna, "resolution", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "wiresize");
RNA_def_property_range(prop, 0.005f, 10000.0f);
+ RNA_def_property_ui_range(prop, 0.05f, 1000.0f, 2.5f, 3);
RNA_def_property_ui_text(prop, "Wire Size", "Polygonization resolution in the 3D viewport");
RNA_def_property_update(prop, 0, "rna_MetaBall_update_data");
prop = RNA_def_property(srna, "render_resolution", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "rendersize");
RNA_def_property_range(prop, 0.005f, 10000.0f);
+ RNA_def_property_ui_range(prop, 0.025f, 1000.0f, 2.5f, 3);
RNA_def_property_ui_text(prop, "Render Size", "Polygonization resolution in rendering");
RNA_def_property_update(prop, 0, "rna_MetaBall_update_data");
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index 7fc61c0acfd..34f138cd7c5 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -492,7 +492,8 @@ static void rna_MultiresModifier_type_set(PointerRNA *ptr, int value)
mmd->simple = value;
}
-static void rna_MultiresModifier_level_range(PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax)
+static void rna_MultiresModifier_level_range(PointerRNA *ptr, int *min, int *max,
+ int *UNUSED(softmin), int *UNUSED(softmax))
{
MultiresModifierData *mmd = (MultiresModifierData *)ptr->data;
diff --git a/source/blender/makesrna/intern/rna_nla.c b/source/blender/makesrna/intern/rna_nla.c
index d2dea03b29b..d905e6a014a 100644
--- a/source/blender/makesrna/intern/rna_nla.c
+++ b/source/blender/makesrna/intern/rna_nla.c
@@ -98,7 +98,7 @@ static char *rna_NlaStrip_path(PointerRNA *ptr)
}
/* no path */
- return "";
+ return BLI_strdup("");
}
static void rna_NlaStrip_transform_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 0e4f1f96733..bb8e8d87252 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -584,8 +584,9 @@ static void rna_NodeTree_unregister(Main *UNUSED(bmain), StructRNA *type)
WM_main_add_notifier(NC_NODE | NA_EDITED, NULL);
}
-static StructRNA *rna_NodeTree_register(Main *bmain, ReportList *reports, void *data, const char *identifier,
- StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
+static StructRNA *rna_NodeTree_register(
+ Main *bmain, ReportList *reports, void *data, const char *identifier,
+ StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
{
bNodeTreeType *nt, dummynt;
bNodeTree dummyntree;
@@ -652,7 +653,7 @@ static bool rna_NodeTree_check(bNodeTree *ntree, ReportList *reports)
return true;
}
-static void rna_NodeTree_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+static void rna_NodeTree_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
{
bNodeTree *ntree = (bNodeTree *)ptr->id.data;
@@ -1376,8 +1377,8 @@ static bNodeType *rna_Node_register_base(Main *bmain, ReportList *reports, Struc
nt->initfunc_api = (have_function[3]) ? rna_Node_init : NULL;
nt->copyfunc_api = (have_function[4]) ? rna_Node_copy : NULL;
nt->freefunc_api = (have_function[5]) ? rna_Node_free : NULL;
- nt->uifunc = (have_function[6]) ? rna_Node_draw_buttons : NULL;
- nt->uifuncbut = (have_function[7]) ? rna_Node_draw_buttons_ext : NULL;
+ nt->draw_buttons = (have_function[6]) ? rna_Node_draw_buttons : NULL;
+ nt->draw_buttons_ex = (have_function[7]) ? rna_Node_draw_buttons_ext : NULL;
/* sanitize size values in case not all have been registered */
if (nt->maxwidth < nt->minwidth)
@@ -1390,9 +1391,10 @@ static bNodeType *rna_Node_register_base(Main *bmain, ReportList *reports, Struc
return nt;
}
-static StructRNA *rna_Node_register(Main *bmain, ReportList *reports,
- void *data, const char *identifier,
- StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
+static StructRNA *rna_Node_register(
+ Main *bmain, ReportList *reports,
+ void *data, const char *identifier,
+ StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
{
bNodeType *nt = rna_Node_register_base(bmain, reports, &RNA_Node, data, identifier, validate, call, free);
if (!nt)
@@ -1406,9 +1408,10 @@ static StructRNA *rna_Node_register(Main *bmain, ReportList *reports,
return nt->ext.srna;
}
-static StructRNA *rna_ShaderNode_register(Main *bmain, ReportList *reports,
- void *data, const char *identifier,
- StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
+static StructRNA *rna_ShaderNode_register(
+ Main *bmain, ReportList *reports,
+ void *data, const char *identifier,
+ StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
{
bNodeType *nt = rna_Node_register_base(bmain, reports, &RNA_ShaderNode, data, identifier, validate, call, free);
if (!nt)
@@ -1422,9 +1425,10 @@ static StructRNA *rna_ShaderNode_register(Main *bmain, ReportList *reports,
return nt->ext.srna;
}
-static StructRNA *rna_CompositorNode_register(Main *bmain, ReportList *reports,
- void *data, const char *identifier,
- StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
+static StructRNA *rna_CompositorNode_register(
+ Main *bmain, ReportList *reports,
+ void *data, const char *identifier,
+ StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
{
bNodeType *nt = rna_Node_register_base(bmain, reports, &RNA_CompositorNode, data, identifier, validate, call, free);
if (!nt)
@@ -1438,9 +1442,10 @@ static StructRNA *rna_CompositorNode_register(Main *bmain, ReportList *reports,
return nt->ext.srna;
}
-static StructRNA *rna_TextureNode_register(Main *bmain, ReportList *reports,
- void *data, const char *identifier,
- StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
+static StructRNA *rna_TextureNode_register(
+ Main *bmain, ReportList *reports,
+ void *data, const char *identifier,
+ StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
{
bNodeType *nt = rna_Node_register_base(bmain, reports, &RNA_TextureNode, data, identifier, validate, call, free);
if (!nt)
@@ -1762,8 +1767,9 @@ static void rna_NodeSocket_unregister(Main *UNUSED(bmain), StructRNA *type)
WM_main_add_notifier(NC_NODE | NA_EDITED, NULL);
}
-static StructRNA *rna_NodeSocket_register(Main *bmain, ReportList *reports, void *data, const char *identifier,
- StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
+static StructRNA *rna_NodeSocket_register(
+ Main *UNUSED(bmain), ReportList *reports, void *data, const char *identifier,
+ StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
{
bNodeSocketType *st, dummyst;
bNodeSocket dummysock;
@@ -1883,6 +1889,12 @@ static void rna_NodeSocket_update(Main *bmain, Scene *UNUSED(scene), PointerRNA
ED_node_tag_update_nodetree(bmain, ntree);
}
+static int rna_NodeSocket_is_output_get(PointerRNA *ptr)
+{
+ bNodeSocket *sock = ptr->data;
+ return sock->in_out == SOCK_OUT;
+}
+
static void rna_NodeSocket_link_limit_set(PointerRNA *ptr, int value)
{
bNodeSocket *sock = ptr->data;
@@ -2033,8 +2045,9 @@ static void rna_NodeSocketInterface_unregister(Main *UNUSED(bmain), StructRNA *t
WM_main_add_notifier(NC_NODE | NA_EDITED, NULL);
}
-static StructRNA *rna_NodeSocketInterface_register(Main *bmain, ReportList *reports, void *data, const char *identifier,
- StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
+static StructRNA *rna_NodeSocketInterface_register(
+ Main *UNUSED(bmain), ReportList *UNUSED(reports), void *data, const char *identifier,
+ StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
{
bNodeSocketType *st, dummyst;
bNodeSocket dummysock;
@@ -2329,30 +2342,31 @@ static void rna_NodeInternal_update(ID *id, bNode *node)
static void rna_NodeInternal_draw_buttons(ID *id, bNode *node, struct bContext *C, struct uiLayout *layout)
{
- if (node->typeinfo->uifunc) {
+ if (node->typeinfo->draw_buttons) {
PointerRNA ptr;
RNA_pointer_create(id, &RNA_Node, node, &ptr);
- node->typeinfo->uifunc(layout, C, &ptr);
+ node->typeinfo->draw_buttons(layout, C, &ptr);
}
}
static void rna_NodeInternal_draw_buttons_ext(ID *id, bNode *node, struct bContext *C, struct uiLayout *layout)
{
- if (node->typeinfo->uifuncbut) {
+ if (node->typeinfo->draw_buttons_ex) {
PointerRNA ptr;
RNA_pointer_create(id, &RNA_Node, node, &ptr);
- node->typeinfo->uifuncbut(layout, C, &ptr);
+ node->typeinfo->draw_buttons_ex(layout, C, &ptr);
}
- else if (node->typeinfo->uifunc) {
+ else if (node->typeinfo->draw_buttons) {
PointerRNA ptr;
RNA_pointer_create(id, &RNA_Node, node, &ptr);
- node->typeinfo->uifunc(layout, C, &ptr);
+ node->typeinfo->draw_buttons(layout, C, &ptr);
}
}
-static StructRNA *rna_NodeCustomGroup_register(Main *bmain, ReportList *reports,
- void *data, const char *identifier,
- StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
+static StructRNA *rna_NodeCustomGroup_register(
+ Main *bmain, ReportList *reports,
+ void *data, const char *identifier,
+ StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
{
bNodeType *nt = rna_Node_register_base(bmain, reports, &RNA_NodeCustomGroup, data, identifier, validate, call, free);
if (!nt)
@@ -2839,6 +2853,15 @@ static void rna_ShaderNodeSubsurface_update(Main *bmain, Scene *scene, PointerRN
rna_Node_update(bmain, scene, ptr);
}
+static void rna_CompositorNodeScale_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+ bNodeTree *ntree = (bNodeTree *)ptr->id.data;
+ bNode *node = (bNode *)ptr->data;
+
+ nodeUpdate(ntree, node);
+ rna_Node_update(bmain, scene, ptr);
+}
+
#else
static EnumPropertyItem prop_image_layer_items[] = {
@@ -3127,10 +3150,24 @@ static void def_sh_material(StructRNA *srna)
static void def_sh_mapping(StructRNA *srna)
{
+ static EnumPropertyItem prop_vect_type_items[] = {
+ {TEXMAP_TYPE_TEXTURE, "TEXTURE", 0, "Texture", "Transform a texture by inverse mapping the texture coordinate"},
+ {TEXMAP_TYPE_POINT, "POINT", 0, "Point", "Transform a point"},
+ {TEXMAP_TYPE_VECTOR, "VECTOR", 0, "Vector", "Transform a direction vector"},
+ {TEXMAP_TYPE_NORMAL, "NORMAL", 0, "Normal", "Transform a normal vector with unit length"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
PropertyRNA *prop;
RNA_def_struct_sdna_from(srna, "TexMapping", "storage");
+ prop = RNA_def_property(srna, "vector_type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "type");
+ RNA_def_property_enum_items(prop, prop_vect_type_items);
+ RNA_def_property_ui_text(prop, "Type", "Type of vector that the mapping transforms");
+ RNA_def_property_update(prop, 0, "rna_Mapping_Node_update");
+
prop = RNA_def_property(srna, "translation", PROP_FLOAT, PROP_TRANSLATION);
RNA_def_property_float_sdna(prop, NULL, "loc");
RNA_def_property_ui_text(prop, "Location", "");
@@ -3236,7 +3273,7 @@ static void def_sh_tex_sky(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
prop = RNA_def_property(srna, "turbidity", PROP_FLOAT, PROP_NONE);
- RNA_def_property_range(prop, 1.0f, 30.0f);
+ RNA_def_property_range(prop, 1.0f, 10.0f);
RNA_def_property_ui_range(prop, 1.0f, 10.0f, 10, 3);
RNA_def_property_ui_text(prop, "Turbidity", "Atmospheric turbidity");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
@@ -3514,9 +3551,9 @@ static void def_sh_tex_coord(StructRNA *srna)
static void def_sh_vect_transform(StructRNA *srna)
{
static EnumPropertyItem prop_vect_type_items[] = {
- {SHD_VECT_TRANSFORM_TYPE_VECTOR, "VECTOR", 0, "Vector", ""},
- {SHD_VECT_TRANSFORM_TYPE_POINT, "POINT", 0, "Point", ""},
- {SHD_VECT_TRANSFORM_TYPE_NORMAL, "NORMAL", 0, "Normal", ""},
+ {SHD_VECT_TRANSFORM_TYPE_POINT, "POINT", 0, "Point", "Transform a point"},
+ {SHD_VECT_TRANSFORM_TYPE_VECTOR, "VECTOR", 0, "Vector", "Transform a direction vector"},
+ {SHD_VECT_TRANSFORM_TYPE_NORMAL, "NORMAL", 0, "Normal", "Transform a normal vector with unit length"},
{0, NULL, 0, NULL, NULL}
};
@@ -3531,7 +3568,8 @@ static void def_sh_vect_transform(StructRNA *srna)
RNA_def_struct_sdna_from(srna, "NodeShaderVectTransform", "storage");
- prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
+ prop = RNA_def_property(srna, "vector_type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "type");
RNA_def_property_enum_items(prop, prop_vect_type_items);
RNA_def_property_ui_text(prop, "Type", "");
RNA_def_property_update(prop, 0, "rna_Node_update");
@@ -3667,7 +3705,6 @@ static void def_sh_tangent(StructRNA *srna)
static void def_sh_subsurface(StructRNA *srna)
{
static EnumPropertyItem prop_subsurface_falloff_items[] = {
- {SHD_SUBSURFACE_COMPATIBLE, "COMPATIBLE", 0, "Compatible", "Subsurface scattering falloff compatible with previous versions"},
{SHD_SUBSURFACE_CUBIC, "CUBIC", 0, "Cubic", "Simple cubic falloff function"},
{SHD_SUBSURFACE_GAUSSIAN, "GAUSSIAN", 0, "Gaussian", "Normal distribution, multiple can be combined to fit more complex profiles"},
{0, NULL, 0, NULL, NULL}
@@ -4337,7 +4374,7 @@ static void def_cmp_scale(StructRNA *srna)
RNA_def_property_enum_sdna(prop, NULL, "custom1");
RNA_def_property_enum_items(prop, space_items);
RNA_def_property_ui_text(prop, "Space", "Coordinate space to scale relative to");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_CompositorNodeScale_update");
/* expose 2 flags as a enum of 3 items */
prop = RNA_def_property(srna, "frame_method", PROP_ENUM, PROP_NONE);
@@ -6150,12 +6187,10 @@ static void rna_def_node_socket(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Identifier", "Unique identifier for mapping sockets");
- prop = RNA_def_property(srna, "in_out", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_sdna(prop, NULL, "in_out");
- RNA_def_property_enum_items(prop, node_socket_in_out_items);
- RNA_def_property_enum_default(prop, SOCK_IN);
+ prop = RNA_def_property(srna, "is_output", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_funcs(prop, "rna_NodeSocket_is_output_get", NULL);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
- RNA_def_property_ui_text(prop, "Input or Output", "Input or Output type");
+ RNA_def_property_ui_text(prop, "Is Output", "True if the socket is an output, otherwise input");
prop = RNA_def_property(srna, "hide", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SOCK_HIDDEN);
@@ -6277,12 +6312,10 @@ static void rna_def_node_socket_interface(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Identifier", "Unique identifier for mapping sockets");
- prop = RNA_def_property(srna, "in_out", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_sdna(prop, NULL, "in_out");
- RNA_def_property_enum_items(prop, node_socket_in_out_items);
- RNA_def_property_enum_default(prop, SOCK_IN);
+ prop = RNA_def_property(srna, "is_output", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_funcs(prop, "rna_NodeSocket_is_output_get", NULL);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
- RNA_def_property_ui_text(prop, "Input or Output", "Input or Output type");
+ RNA_def_property_ui_text(prop, "Is Output", "True if the socket is an output, otherwise input");
/* registration */
prop = RNA_def_property(srna, "bl_socket_idname", PROP_STRING, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c
index d4a78ce73d5..11a818c6a9c 100644
--- a/source/blender/makesrna/intern/rna_object.c
+++ b/source/blender/makesrna/intern/rna_object.c
@@ -557,7 +557,8 @@ static void rna_Object_active_vertex_group_index_set(PointerRNA *ptr, int value)
ob->actdef = value + 1;
}
-static void rna_Object_active_vertex_group_index_range(PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax)
+static void rna_Object_active_vertex_group_index_range(PointerRNA *ptr, int *min, int *max,
+ int *UNUSED(softmin), int *UNUSED(softmax))
{
Object *ob = (Object *)ptr->id.data;
@@ -668,7 +669,8 @@ static void rna_Object_active_material_index_set(PointerRNA *ptr, int value)
}
}
-static void rna_Object_active_material_index_range(PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax)
+static void rna_Object_active_material_index_range(PointerRNA *ptr, int *min, int *max,
+ int *UNUSED(softmin), int *UNUSED(softmax))
{
Object *ob = (Object *)ptr->id.data;
*min = 0;
@@ -694,7 +696,7 @@ static void rna_Object_active_material_set(PointerRNA *ptr, PointerRNA value)
}
static void rna_Object_active_particle_system_index_range(PointerRNA *ptr, int *min, int *max,
- int *softmin, int *softmax)
+ int *UNUSED(softmin), int *UNUSED(softmax))
{
Object *ob = (Object *)ptr->id.data;
*min = 0;
@@ -907,6 +909,15 @@ static void rna_MaterialSlot_update(Main *bmain, Scene *scene, PointerRNA *ptr)
WM_main_add_notifier(NC_MATERIAL | ND_SHADING_LINKS, NULL);
}
+static char *rna_MaterialSlot_path(PointerRNA *ptr)
+{
+ Object *ob = (Object *)ptr->id.data;
+ int index = (Material **)ptr->data - ob->mat;
+
+ /* from armature... */
+ return BLI_sprintfN("material_slots[%d]", index);
+}
+
/* why does this have to be so complicated?, can't all this crap be
* moved to in BGE conversion function? - Campbell *
*
@@ -1185,7 +1196,8 @@ static void rna_GameObjectSettings_col_mask_set(PointerRNA *ptr, const int *valu
}
-static void rna_Object_active_shape_key_index_range(PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax)
+static void rna_Object_active_shape_key_index_range(PointerRNA *ptr, int *min, int *max,
+ int *UNUSED(softmin), int *UNUSED(softmax))
{
Object *ob = (Object *)ptr->id.data;
Key *key = BKE_key_from_object(ob);
@@ -1454,8 +1466,6 @@ static void rna_Object_lod_distance_update(Main *bmain, Scene *scene, PointerRNA
}
#else
-static int rna_matrix_dimsize_4x4[] = {4, 4};
-
static void rna_def_vertex_group(BlenderRNA *brna)
{
StructRNA *srna;
@@ -1556,6 +1566,8 @@ static void rna_def_material_slot(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Name", "Material slot name");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_struct_name_property(srna, prop);
+
+ RNA_def_struct_path_func(srna, "rna_MaterialSlot_path");
}
static void rna_def_object_game_settings(BlenderRNA *brna)
@@ -2811,11 +2823,14 @@ static void rna_def_object_base(BlenderRNA *brna)
void RNA_def_object(BlenderRNA *brna)
{
rna_def_object(brna);
+
+ RNA_define_animate_sdna(false);
rna_def_object_game_settings(brna);
rna_def_object_base(brna);
rna_def_vertex_group(brna);
rna_def_material_slot(brna);
rna_def_dupli_object(brna);
+ RNA_define_animate_sdna(true);
rna_def_object_lodlevel(brna);
}
diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c
index 25ca231e58d..0f71e26b687 100644
--- a/source/blender/makesrna/intern/rna_object_api.c
+++ b/source/blender/makesrna/intern/rna_object_api.c
@@ -430,8 +430,6 @@ void RNA_api_object(StructRNA *srna)
{0, NULL, 0, NULL, NULL}
};
- static int rna_matrix_dimsize_4x4[] = {4, 4};
-
#ifndef NDEBUG
static EnumPropertyItem mesh_dm_info_items[] = {
{0, "SOURCE", 0, "Source", "Source mesh"},
diff --git a/source/blender/makesrna/intern/rna_object_force.c b/source/blender/makesrna/intern/rna_object_force.c
index 2fda576fcc2..33ae256c042 100644
--- a/source/blender/makesrna/intern/rna_object_force.c
+++ b/source/blender/makesrna/intern/rna_object_force.c
@@ -228,7 +228,8 @@ static void rna_Cache_list_begin(CollectionPropertyIterator *iter, PointerRNA *p
rna_iterator_listbase_begin(iter, &lb, NULL);
}
-static void rna_Cache_active_point_cache_index_range(PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax)
+static void rna_Cache_active_point_cache_index_range(PointerRNA *ptr, int *min, int *max,
+ int *UNUSED(softmin), int *UNUSED(softmax))
{
Object *ob = ptr->id.data;
PointCache *cache = ptr->data;
@@ -291,7 +292,8 @@ static void rna_Cache_active_point_cache_index_set(struct PointerRNA *ptr, int v
BLI_freelistN(&pidlist);
}
-static void rna_PointCache_frame_step_range(PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax)
+static void rna_PointCache_frame_step_range(PointerRNA *ptr, int *min, int *max,
+ int *UNUSED(softmin), int *UNUSED(softmax))
{
Object *ob = ptr->id.data;
PointCache *cache = ptr->data;
@@ -1538,8 +1540,6 @@ static void rna_def_softbody(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
- const int matrix_dimsize[] = {3, 3};
-
static EnumPropertyItem collision_type_items[] = {
{SBC_MODE_MANUAL, "MANUAL", 0, "Manual", "Manual adjust"},
@@ -1782,12 +1782,12 @@ static void rna_def_softbody(BlenderRNA *brna)
/* matrix */
prop = RNA_def_property(srna, "rotation_estimate", PROP_FLOAT, PROP_MATRIX);
RNA_def_property_float_sdna(prop, NULL, "lrot");
- RNA_def_property_multi_array(prop, 2, matrix_dimsize);
+ RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_3x3);
RNA_def_property_ui_text(prop, "Rot Matrix", "Estimated rotation matrix");
prop = RNA_def_property(srna, "scale_estimate", PROP_FLOAT, PROP_MATRIX);
RNA_def_property_float_sdna(prop, NULL, "lscale");
- RNA_def_property_multi_array(prop, 2, matrix_dimsize);
+ RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_3x3);
RNA_def_property_ui_text(prop, "Scale Matrix", "Estimated scale matrix");
/***********************************************************************************/
diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c
index 7d30194277b..8dafe54e678 100644
--- a/source/blender/makesrna/intern/rna_particle.c
+++ b/source/blender/makesrna/intern/rna_particle.c
@@ -271,7 +271,8 @@ static void rna_ParticleHairKey_co_object(HairKey *hairkey, Object *object, Part
}
}
-static void rna_Particle_uv_on_emitter(ParticleData *particle, ParticleSystemModifierData *modifier, float n_uv[2])
+static void rna_Particle_uv_on_emitter(ParticleData *particle, ReportList *reports,
+ ParticleSystemModifierData *modifier, float r_uv[2])
{
/*psys_particle_on_emitter(psmd, part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, co, nor, 0, 0, sd.orco, 0);*/
@@ -279,28 +280,39 @@ static void rna_Particle_uv_on_emitter(ParticleData *particle, ParticleSystemMod
int num = particle->num_dmcache;
int from = modifier->psys->part->from;
+ if (!CustomData_has_layer(&modifier->dm->loopData, CD_MLOOPUV)) {
+ BKE_report(reports, RPT_ERROR, "Mesh has no UV data");
+ return;
+ }
+ DM_ensure_tessface(modifier->dm); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */
+
if (num == DMCACHE_NOTFOUND)
if (particle->num < modifier->dm->getNumTessFaces(modifier->dm))
num = particle->num;
/* get uvco */
- if (n_uv && ELEM(from, PART_FROM_FACE, PART_FROM_VOLUME)) {
+ if (r_uv && ELEM(from, PART_FROM_FACE, PART_FROM_VOLUME)) {
if (num != DMCACHE_NOTFOUND) {
- MFace *mface = modifier->dm->getTessFaceData(modifier->dm, num, CD_MFACE);
- MTFace *mtface = (MTFace *)CustomData_get_layer_n(&modifier->dm->faceData, CD_MTFACE, 0);
- mtface += num;
-
- psys_interpolate_uvs(mtface, mface->v4, particle->fuv, n_uv);
- }
- else {
- n_uv[0] = 0.0f;
- n_uv[1] = 0.0f;
+ MFace *mface;
+ MTFace *mtface;
+
+ mface = modifier->dm->getTessFaceData(modifier->dm, num, CD_MFACE);
+ mtface = (MTFace *)CustomData_get_layer_n(&modifier->dm->faceData, CD_MTFACE, 0);
+
+ if (mface && mtface) {
+ mtface += num;
+ psys_interpolate_uvs(mtface, mface->v4, particle->fuv, r_uv);
+ return;
+ }
}
}
+
+ r_uv[0] = 0.0f;
+ r_uv[1] = 0.0f;
}
-static void rna_ParticleSystem_co_hair(ParticleSystem *particlesystem, Object *object, ParticleSystemModifierData *modifier,
+static void rna_ParticleSystem_co_hair(ParticleSystem *particlesystem, Object *object,
int particle_no, int step, float n_co[3])
{
ParticleSettings *part = 0;
@@ -378,14 +390,22 @@ static void rna_ParticleSystem_co_hair(ParticleSystem *particlesystem, Object *o
}
-static void rna_ParticleSystem_uv_on_emitter(ParticleSystem *particlesystem, ParticleSystemModifierData *modifier, ParticleData *particle, int particle_no, int uv_no,
- float n_uv[2])
+static void rna_ParticleSystem_uv_on_emitter(ParticleSystem *particlesystem, ReportList *reports,
+ ParticleSystemModifierData *modifier, ParticleData *particle,
+ int particle_no, int uv_no,
+ float r_uv[2])
{
ParticleSettings *part = 0;
int totpart;
int totchild = 0;
int num;
+ if (!CustomData_has_layer(&modifier->dm->loopData, CD_MLOOPUV)) {
+ BKE_report(reports, RPT_ERROR, "Mesh has no UV data");
+ return;
+ }
+ DM_ensure_tessface(modifier->dm); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */
+
/* 1. check that everything is ok & updated */
if (particlesystem == NULL)
return;
@@ -419,17 +439,17 @@ static void rna_ParticleSystem_uv_on_emitter(ParticleSystem *particlesystem, Par
if (particle->num < modifier->dm->getNumTessFaces(modifier->dm))
num = particle->num;
- if (n_uv && ELEM(part->from, PART_FROM_FACE, PART_FROM_VOLUME)) {
+ if (r_uv && ELEM(part->from, PART_FROM_FACE, PART_FROM_VOLUME)) {
if (num != DMCACHE_NOTFOUND) {
MFace *mface = modifier->dm->getTessFaceData(modifier->dm, num, CD_MFACE);
MTFace *mtface = (MTFace *)CustomData_get_layer_n(&modifier->dm->faceData, CD_MTFACE, uv_no);
mtface += num;
- psys_interpolate_uvs(mtface, mface->v4, particle->fuv, n_uv);
+ psys_interpolate_uvs(mtface, mface->v4, particle->fuv, r_uv);
}
else {
- n_uv[0] = 0.0f;
- n_uv[1] = 0.0f;
+ r_uv[0] = 0.0f;
+ r_uv[1] = 0.0f;
}
}
}
@@ -440,17 +460,17 @@ static void rna_ParticleSystem_uv_on_emitter(ParticleSystem *particlesystem, Par
/* get uvco & mcol */
if (part->childtype == PART_CHILD_FACES) {
- if (n_uv && ELEM(PART_FROM_FACE, PART_FROM_FACE, PART_FROM_VOLUME)) {
+ if (r_uv && ELEM(PART_FROM_FACE, PART_FROM_FACE, PART_FROM_VOLUME)) {
if (cpa->num != DMCACHE_NOTFOUND) {
MFace *mface = modifier->dm->getTessFaceData(modifier->dm, cpa->num, CD_MFACE);
MTFace *mtface = (MTFace *)CustomData_get_layer_n(&modifier->dm->faceData, CD_MTFACE, uv_no);
mtface += cpa->num;
- psys_interpolate_uvs(mtface, mface->v4, cpa->fuv, n_uv);
+ psys_interpolate_uvs(mtface, mface->v4, cpa->fuv, r_uv);
}
else {
- n_uv[0] = 0.0f;
- n_uv[1] = 0.0f;
+ r_uv[0] = 0.0f;
+ r_uv[1] = 0.0f;
}
}
}
@@ -462,17 +482,17 @@ static void rna_ParticleSystem_uv_on_emitter(ParticleSystem *particlesystem, Par
if (parent->num < modifier->dm->getNumTessFaces(modifier->dm))
num = parent->num;
- if (n_uv && ELEM(part->from, PART_FROM_FACE, PART_FROM_VOLUME)) {
+ if (r_uv && ELEM(part->from, PART_FROM_FACE, PART_FROM_VOLUME)) {
if (num != DMCACHE_NOTFOUND) {
MFace *mface = modifier->dm->getTessFaceData(modifier->dm, num, CD_MFACE);
MTFace *mtface = (MTFace *)CustomData_get_layer_n(&modifier->dm->faceData, CD_MTFACE, uv_no);
mtface += num;
- psys_interpolate_uvs(mtface, mface->v4, parent->fuv, n_uv);
+ psys_interpolate_uvs(mtface, mface->v4, parent->fuv, r_uv);
}
else {
- n_uv[0] = 0.0f;
- n_uv[1] = 0.0f;
+ r_uv[0] = 0.0f;
+ r_uv[1] = 0.0f;
}
}
}
@@ -842,7 +862,8 @@ static float rna_PartSetting_linelentail_get(struct PointerRNA *ptr)
ParticleSettings *settings = (ParticleSettings *)ptr->data;
return settings->draw_line[0];
}
-static void rna_PartSetting_pathstartend_range(PointerRNA *ptr, float *min, float *max, float *softmin, float *softmax)
+static void rna_PartSetting_pathstartend_range(PointerRNA *ptr, float *min, float *max,
+ float *UNUSED(softmin), float *UNUSED(softmax))
{
ParticleSettings *settings = (ParticleSettings *)ptr->data;
@@ -899,7 +920,7 @@ static PointerRNA rna_ParticleSystem_active_particle_target_get(PointerRNA *ptr)
return rna_pointer_inherit_refine(ptr, &RNA_ParticleTarget, NULL);
}
static void rna_ParticleSystem_active_particle_target_index_range(PointerRNA *ptr, int *min, int *max,
- int *softmin, int *softmax)
+ int *UNUSED(softmin), int *UNUSED(softmax))
{
ParticleSystem *psys = (ParticleSystem *)ptr->data;
*min = 0;
@@ -1021,7 +1042,8 @@ static PointerRNA rna_ParticleDupliWeight_active_get(PointerRNA *ptr)
}
return rna_pointer_inherit_refine(ptr, &RNA_ParticleTarget, NULL);
}
-static void rna_ParticleDupliWeight_active_index_range(PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax)
+static void rna_ParticleDupliWeight_active_index_range(PointerRNA *ptr, int *min, int *max,
+ int *UNUSED(softmin), int *UNUSED(softmax))
{
ParticleSettings *part = (ParticleSettings *)ptr->id.data;
*min = 0;
@@ -1294,8 +1316,11 @@ static void rna_def_particle_hair_key(BlenderRNA *brna)
RNA_def_function_ui_description(func, "Obtain hairkey location with particle and modifier data");
prop = RNA_def_pointer(func, "object", "Object", "", "Object");
+ RNA_def_property_flag(prop, PROP_REQUIRED | PROP_NEVER_NULL);
prop = RNA_def_pointer(func, "modifier", "ParticleSystemModifier", "", "Particle modifier");
+ RNA_def_property_flag(prop, PROP_REQUIRED | PROP_NEVER_NULL);
prop = RNA_def_pointer(func, "particle", "Particle", "", "hair particle");
+ RNA_def_property_flag(prop, PROP_REQUIRED | PROP_NEVER_NULL);
prop = RNA_def_float_vector(func, "co", 3, NULL, -FLT_MAX, FLT_MAX, "Co",
"Exported hairkey location", -1e4, 1e4);
@@ -1461,7 +1486,9 @@ static void rna_def_particle(BlenderRNA *brna)
/* UVs */
func = RNA_def_function(srna, "uv_on_emitter", "rna_Particle_uv_on_emitter");
RNA_def_function_ui_description(func, "Obtain uv for particle on derived mesh");
+ RNA_def_function_flag(func, FUNC_USE_REPORTS);
prop = RNA_def_pointer(func, "modifier", "ParticleSystemModifier", "", "Particle modifier");
+ RNA_def_property_flag(prop, PROP_REQUIRED | PROP_NEVER_NULL);
prop = RNA_def_property(func, "uv", PROP_FLOAT, PROP_COORDS);
RNA_def_property_array(prop, 2);
RNA_def_property_flag(prop, PROP_THICK_WRAP);
@@ -3388,7 +3415,7 @@ static void rna_def_particle_system(BlenderRNA *brna)
RNA_def_function_ui_description(func, "Obtain cache hair data");
prop = RNA_def_pointer(func, "object", "Object", "", "Object");
- prop = RNA_def_pointer(func, "modifier", "ParticleSystemModifier", "", "Particle modifier");
+ RNA_def_property_flag(prop, PROP_REQUIRED | PROP_NEVER_NULL);
prop = RNA_def_int(func, "particle_no", 0, INT_MIN, INT_MAX, "Particle no", "", INT_MIN, INT_MAX);
prop = RNA_def_int(func, "step", 0, INT_MIN, INT_MAX, "step no", "", INT_MIN, INT_MAX);
@@ -3400,8 +3427,11 @@ static void rna_def_particle_system(BlenderRNA *brna)
/* extract hair UVs */
func = RNA_def_function(srna, "uv_on_emitter", "rna_ParticleSystem_uv_on_emitter");
RNA_def_function_ui_description(func, "Obtain uv for all particles");
+ RNA_def_function_flag(func, FUNC_USE_REPORTS);
prop = RNA_def_pointer(func, "modifier", "ParticleSystemModifier", "", "Particle modifier");
+ RNA_def_property_flag(prop, PROP_REQUIRED | PROP_NEVER_NULL);
prop = RNA_def_pointer(func, "particle", "Particle", "", "Particle");
+ RNA_def_property_flag(prop, PROP_REQUIRED | PROP_NEVER_NULL);
prop = RNA_def_int(func, "particle_no", 0, INT_MIN, INT_MAX, "Particle no", "", INT_MIN, INT_MAX);
prop = RNA_def_int(func, "uv_no", 0, INT_MIN, INT_MAX, "UV no", "", INT_MIN, INT_MAX);
prop = RNA_def_property(func, "uv", PROP_FLOAT, PROP_COORDS);
@@ -3413,7 +3443,9 @@ static void rna_def_particle_system(BlenderRNA *brna)
func = RNA_def_function(srna, "mcol_on_emitter", "rna_ParticleSystem_mcol_on_emitter");
RNA_def_function_ui_description(func, "Obtain mcol for all particles");
prop = RNA_def_pointer(func, "modifier", "ParticleSystemModifier", "", "Particle modifier");
+ RNA_def_property_flag(prop, PROP_REQUIRED | PROP_NEVER_NULL);
prop = RNA_def_pointer(func, "particle", "Particle", "", "Particle");
+ RNA_def_property_flag(prop, PROP_REQUIRED | PROP_NEVER_NULL);
prop = RNA_def_int(func, "particle_no", 0, INT_MIN, INT_MAX, "Particle no", "", INT_MIN, INT_MAX);
prop = RNA_def_int(func, "vcol_no", 0, INT_MIN, INT_MAX, "vcol no", "", INT_MIN, INT_MAX);
prop = RNA_def_property(func, "mcol", PROP_FLOAT, PROP_COLOR);
diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c
index 35347d656df..9c4e7f034cb 100644
--- a/source/blender/makesrna/intern/rna_pose.c
+++ b/source/blender/makesrna/intern/rna_pose.c
@@ -382,7 +382,8 @@ static void rna_PoseChannel_bone_group_index_set(PointerRNA *ptr, int value)
pchan->agrp_index = value + 1;
}
-static void rna_PoseChannel_bone_group_index_range(PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax)
+static void rna_PoseChannel_bone_group_index_range(PointerRNA *ptr, int *min, int *max,
+ int *UNUSED(softmin), int *UNUSED(softmax))
{
Object *ob = (Object *)ptr->id.data;
bPose *pose = (ob) ? ob->pose : NULL;
@@ -415,7 +416,8 @@ static void rna_Pose_active_bone_group_index_set(PointerRNA *ptr, int value)
pose->active_group = value + 1;
}
-static void rna_Pose_active_bone_group_index_range(PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax)
+static void rna_Pose_active_bone_group_index_range(PointerRNA *ptr, int *min, int *max,
+ int *UNUSED(softmin), int *UNUSED(softmax))
{
bPose *pose = (bPose *)ptr->data;
@@ -740,9 +742,7 @@ static void rna_def_pose_channel(BlenderRNA *brna)
static float default_quat[4] = {1, 0, 0, 0}; /* default quaternion values */
static float default_axisAngle[4] = {0, 0, 1, 0}; /* default axis-angle rotation values */
static float default_scale[3] = {1, 1, 1}; /* default scale values */
-
- const int matrix_dimsize[] = {4, 4};
-
+
StructRNA *srna;
PropertyRNA *prop;
@@ -839,13 +839,13 @@ static void rna_def_pose_channel(BlenderRNA *brna)
/* transform matrices - should be read-only since these are set directly by AnimSys evaluation */
prop = RNA_def_property(srna, "matrix_channel", PROP_FLOAT, PROP_MATRIX);
RNA_def_property_float_sdna(prop, NULL, "chan_mat");
- RNA_def_property_multi_array(prop, 2, matrix_dimsize);
+ RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_4x4);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Channel Matrix", "4x4 matrix, before constraints");
/* writable because it touches loc/scale/rot directly */
prop = RNA_def_property(srna, "matrix_basis", PROP_FLOAT, PROP_MATRIX);
- RNA_def_property_multi_array(prop, 2, matrix_dimsize);
+ RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_4x4);
RNA_def_property_ui_text(prop, "Basis Matrix",
"Alternative access to location/scale/rotation relative to the parent and own rest bone");
RNA_def_property_float_funcs(prop, "rna_PoseChannel_matrix_basis_get", "rna_PoseChannel_matrix_basis_set", NULL);
@@ -855,7 +855,7 @@ static void rna_def_pose_channel(BlenderRNA *brna)
/* final matrix */
prop = RNA_def_property(srna, "matrix", PROP_FLOAT, PROP_MATRIX);
RNA_def_property_float_sdna(prop, NULL, "pose_mat");
- RNA_def_property_multi_array(prop, 2, matrix_dimsize);
+ RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_4x4);
RNA_def_property_float_funcs(prop, NULL, "rna_PoseChannel_matrix_set", NULL);
RNA_def_property_ui_text(prop, "Pose Matrix",
"Final 4x4 matrix after constraints and drivers are applied (object space)");
diff --git a/source/blender/makesrna/intern/rna_render.c b/source/blender/makesrna/intern/rna_render.c
index 5b809a51705..7ebbcf7b39b 100644
--- a/source/blender/makesrna/intern/rna_render.c
+++ b/source/blender/makesrna/intern/rna_render.c
@@ -66,14 +66,14 @@ static void engine_tag_update(RenderEngine *engine)
static int engine_support_display_space_shader(RenderEngine *UNUSED(engine), Scene *scene)
{
- return IMB_colormanagement_support_glsl_draw(&scene->view_settings, true);
+ return IMB_colormanagement_support_glsl_draw(&scene->view_settings);
}
static void engine_bind_display_space_shader(RenderEngine *UNUSED(engine), Scene *scene)
{
IMB_colormanagement_setup_glsl_draw(&scene->view_settings,
&scene->display_settings,
- false, true);
+ false);
}
static void engine_unbind_display_space_shader(RenderEngine *UNUSED(engine))
diff --git a/source/blender/makesrna/intern/rna_rigidbody.c b/source/blender/makesrna/intern/rna_rigidbody.c
index b1f704551e0..cc14e60f45a 100644
--- a/source/blender/makesrna/intern/rna_rigidbody.c
+++ b/source/blender/makesrna/intern/rna_rigidbody.c
@@ -96,14 +96,14 @@ EnumPropertyItem rigidbody_constraint_type_items[] = {
/* ******************************** */
-static void rna_RigidBodyWorld_reset(Main *bmain, Scene *scene, PointerRNA *ptr)
+static void rna_RigidBodyWorld_reset(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
RigidBodyWorld *rbw = (RigidBodyWorld *)ptr->data;
BKE_rigidbody_cache_reset(rbw);
}
-static char *rna_RigidBodyWorld_path(PointerRNA *ptr)
+static char *rna_RigidBodyWorld_path(PointerRNA *UNUSED(ptr))
{
return BLI_sprintfN("rigidbody_world");
}
@@ -136,14 +136,14 @@ static void rna_RigidBodyWorld_split_impulse_set(PointerRNA *ptr, int value)
/* ******************************** */
-static void rna_RigidBodyOb_reset(Main *bmain, Scene *scene, PointerRNA *ptr)
+static void rna_RigidBodyOb_reset(Main *UNUSED(bmain), Scene *scene, PointerRNA *UNUSED(ptr))
{
RigidBodyWorld *rbw = scene->rigidbody_world;
BKE_rigidbody_cache_reset(rbw);
}
-static void rna_RigidBodyOb_shape_reset(Main *bmain, Scene *scene, PointerRNA *ptr)
+static void rna_RigidBodyOb_shape_reset(Main *UNUSED(bmain), Scene *scene, PointerRNA *ptr)
{
RigidBodyWorld *rbw = scene->rigidbody_world;
RigidBodyOb *rbo = (RigidBodyOb *)ptr->data;
@@ -153,7 +153,7 @@ static void rna_RigidBodyOb_shape_reset(Main *bmain, Scene *scene, PointerRNA *p
rbo->flag |= RBO_FLAG_NEEDS_RESHAPE;
}
-static char *rna_RigidBodyOb_path(PointerRNA *ptr)
+static char *rna_RigidBodyOb_path(PointerRNA *UNUSED(ptr))
{
/* NOTE: this hardcoded path should work as long as only Objects have this */
return BLI_sprintfN("rigid_body");
@@ -167,6 +167,14 @@ static void rna_RigidBodyOb_type_set(PointerRNA *ptr, int value)
rbo->flag |= RBO_FLAG_NEEDS_VALIDATE;
}
+static void rna_RigidBodyOb_shape_set(PointerRNA *ptr, int value)
+{
+ RigidBodyOb *rbo = (RigidBodyOb *)ptr->data;
+
+ rbo->shape = value;
+ rbo->flag |= RBO_FLAG_NEEDS_VALIDATE;
+}
+
static void rna_RigidBodyOb_disabled_set(PointerRNA *ptr, int value)
{
RigidBodyOb *rbo = (RigidBodyOb *)ptr->data;
@@ -335,7 +343,7 @@ static void rna_RigidBodyOb_angular_damping_set(PointerRNA *ptr, float value)
#endif
}
-static char *rna_RigidBodyCon_path(PointerRNA *ptr)
+static char *rna_RigidBodyCon_path(PointerRNA *UNUSED(ptr))
{
/* NOTE: this hardcoded path should work as long as only Objects have this */
return BLI_sprintfN("rigid_body_constraint");
@@ -596,13 +604,17 @@ static void rna_RigidBodyCon_motor_ang_target_velocity_set(PointerRNA *ptr, floa
}
/* Sweep test */
-static void rna_RigidBodyWorld_convex_sweep_test(RigidBodyWorld *rbw, ReportList *reports, Object *object, float ray_start[3], float ray_end[3], float r_location[3], float r_hitpoint[3], float r_normal[3], int *r_hit)
+static void rna_RigidBodyWorld_convex_sweep_test(
+ RigidBodyWorld *rbw, ReportList *reports,
+ Object *object, float ray_start[3], float ray_end[3],
+ float r_location[3], float r_hitpoint[3], float r_normal[3], int *r_hit)
{
#ifdef WITH_BULLET
RigidBodyOb *rob = object->rigidbody_object;
if (rbw->physics_world != NULL && rob->physics_object != NULL) {
- RB_world_convex_sweep_test(rbw->physics_world, rob->physics_object, ray_start, ray_end, r_location, r_hitpoint, r_normal, r_hit);
+ RB_world_convex_sweep_test(rbw->physics_world, rob->physics_object, ray_start, ray_end,
+ r_location, r_hitpoint, r_normal, r_hit);
if (*r_hit == -2) {
BKE_report(reports, RPT_ERROR,
"A non convex collision shape was passed to the function, use only convex collision shapes");
@@ -612,6 +624,9 @@ static void rna_RigidBodyWorld_convex_sweep_test(RigidBodyWorld *rbw, ReportList
*r_hit = -1;
BKE_report(reports, RPT_ERROR, "Rigidbody world was not properly initialized, need to step the simulation first");
}
+#else
+ (void)rbw, (void)reports, (void)object, (void)ray_start, (void)ray_end;
+ (void)r_location, (void)r_hitpoint, (void)r_normal, (void)r_hit;
#endif
}
@@ -764,6 +779,7 @@ static void rna_def_rigidbody_object(BlenderRNA *brna)
prop = RNA_def_property(srna, "collision_shape", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "shape");
RNA_def_property_enum_items(prop, rigidbody_object_shape_items);
+ RNA_def_property_enum_funcs(prop, NULL, "rna_RigidBodyOb_shape_set", NULL);
RNA_def_property_ui_text(prop, "Collision Shape", "Collision Shape of object in Rigid Body Simulations");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_reset");
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index e58bf2598f7..4d35acc84a0 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -219,6 +219,13 @@ EnumPropertyItem snap_uv_element_items[] = {
# define R_IMF_ENUM_TIFF
#endif
+#ifdef WITH_OPENIMAGEIO
+# define R_IMF_ENUM_PSD {R_IMF_IMTYPE_PSD, "PSD", ICON_FILE_IMAGE, "Photosp PSD", \
+ "Output image in Photoshop PSD format"},
+#else
+# define R_IMF_ENUM_PSD
+#endif
+
#define IMAGE_TYPE_ITEMS_IMAGE_ONLY \
R_IMF_ENUM_BMP \
@@ -236,6 +243,7 @@ EnumPropertyItem snap_uv_element_items[] = {
R_IMF_ENUM_EXR \
R_IMF_ENUM_HDR \
R_IMF_ENUM_TIFF \
+ R_IMF_ENUM_PSD \
EnumPropertyItem image_only_type_items[] = {
@@ -781,7 +789,7 @@ static void rna_ImageFormatSettings_file_format_set(PointerRNA *ptr, int value)
}
}
-static EnumPropertyItem *rna_ImageFormatSettings_file_format_itemf(bContext *C, PointerRNA *ptr,
+static EnumPropertyItem *rna_ImageFormatSettings_file_format_itemf(bContext *UNUSED(C), PointerRNA *ptr,
PropertyRNA *UNUSED(prop), int *UNUSED(free))
{
ID *id = ptr->id.data;
@@ -793,7 +801,7 @@ static EnumPropertyItem *rna_ImageFormatSettings_file_format_itemf(bContext *C,
}
}
-static EnumPropertyItem *rna_ImageFormatSettings_color_mode_itemf(bContext *C, PointerRNA *ptr,
+static EnumPropertyItem *rna_ImageFormatSettings_color_mode_itemf(bContext *UNUSED(C), PointerRNA *ptr,
PropertyRNA *UNUSED(prop), int *free)
{
ImageFormatData *imf = (ImageFormatData *)ptr->data;
@@ -838,7 +846,7 @@ static EnumPropertyItem *rna_ImageFormatSettings_color_mode_itemf(bContext *C, P
}
}
-static EnumPropertyItem *rna_ImageFormatSettings_color_depth_itemf(bContext *C, PointerRNA *ptr,
+static EnumPropertyItem *rna_ImageFormatSettings_color_depth_itemf(bContext *UNUSED(C), PointerRNA *ptr,
PropertyRNA *UNUSED(prop), int *free)
{
ImageFormatData *imf = (ImageFormatData *)ptr->data;
@@ -932,7 +940,7 @@ static void rna_RenderSettings_qtcodecsettings_codecType_set(PointerRNA *ptr, in
settings->codecType = quicktime_videocodecType_from_rnatmpvalue(value);
}
-static EnumPropertyItem *rna_RenderSettings_qtcodecsettings_codecType_itemf(bContext *C, PointerRNA *ptr,
+static EnumPropertyItem *rna_RenderSettings_qtcodecsettings_codecType_itemf(bContext *UNUSED(C), PointerRNA *UNUSED(ptr),
PropertyRNA *UNUSED(prop), int *free)
{
EnumPropertyItem *item = NULL;
@@ -971,7 +979,7 @@ static void rna_RenderSettings_qtcodecsettings_audiocodecType_set(PointerRNA *pt
settings->audiocodecType = quicktime_audiocodecType_from_rnatmpvalue(value);
}
-static EnumPropertyItem *rna_RenderSettings_qtcodecsettings_audiocodecType_itemf(bContext *C, PointerRNA *ptr,
+static EnumPropertyItem *rna_RenderSettings_qtcodecsettings_audiocodecType_itemf(bContext *UNUSED(C), PointerRNA *UNUSED(ptr),
PropertyRNA *UNUSED(prop), int *free)
{
EnumPropertyItem *item = NULL;
@@ -1032,7 +1040,8 @@ static void rna_RenderSettings_active_layer_index_set(PointerRNA *ptr, int value
rd->actlay = value;
}
-static void rna_RenderSettings_active_layer_index_range(PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax)
+static void rna_RenderSettings_active_layer_index_range(PointerRNA *ptr, int *min, int *max,
+ int *UNUSED(softmin), int *UNUSED(softmax))
{
RenderData *rd = (RenderData *)ptr->data;
@@ -1313,7 +1322,7 @@ static void rna_Scene_simplify_update(Main *bmain, Scene *UNUSED(scene), Pointer
rna_Scene_use_simplify_update(bmain, sce, ptr);
}
-static void rna_Scene_use_persistent_data_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
+static void rna_Scene_use_persistent_data_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
Scene *sce = ptr->id.data;
@@ -1462,13 +1471,13 @@ static void rna_UnifiedPaintSettings_unprojected_radius_set(PointerRNA *ptr, flo
ups->unprojected_radius = value;
}
-static void rna_UnifiedPaintSettings_radius_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+static void rna_UnifiedPaintSettings_radius_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *UNUSED(ptr))
{
/* changing the unified size should invalidate */
BKE_paint_invalidate_overlay_all();
}
-static char *rna_UnifiedPaintSettings_path(PointerRNA *ptr)
+static char *rna_UnifiedPaintSettings_path(PointerRNA *UNUSED(ptr))
{
return BLI_strdup("tool_settings.unified_paint_settings");
}
@@ -1490,7 +1499,7 @@ static void rna_EditMesh_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *U
}
}
-static char *rna_MeshStatVis_path(PointerRNA *ptr)
+static char *rna_MeshStatVis_path(PointerRNA *UNUSED(ptr))
{
return BLI_strdup("tool_settings.statvis");
}
@@ -1524,7 +1533,7 @@ static void rna_SceneSequencer_update(Main *UNUSED(bmain), Scene *UNUSED(scene),
BKE_sequencer_preprocessed_cache_cleanup();
}
-static char *rna_ToolSettings_path(PointerRNA *ptr)
+static char *rna_ToolSettings_path(PointerRNA *UNUSED(ptr))
{
return BLI_strdup("tool_settings");
}
@@ -1540,7 +1549,8 @@ static void rna_FreestyleLineSet_linestyle_set(PointerRNA *ptr, PointerRNA value
{
FreestyleLineSet *lineset = (FreestyleLineSet *)ptr->data;
- lineset->linestyle->id.us--;
+ if (lineset->linestyle)
+ lineset->linestyle->id.us--;
lineset->linestyle = (FreestyleLineStyle *)value.data;
lineset->linestyle->id.us++;
}
@@ -1553,7 +1563,7 @@ static PointerRNA rna_FreestyleSettings_active_lineset_get(PointerRNA *ptr)
}
static void rna_FreestyleSettings_active_lineset_index_range(PointerRNA *ptr, int *min, int *max,
- int *softmin, int *softmax)
+ int *UNUSED(softmin), int *UNUSED(softmax))
{
FreestyleConfig *config = (FreestyleConfig *)ptr->data;
@@ -1579,14 +1589,12 @@ static void rna_def_transform_orientation(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
- const int matrix_dimsize[] = {3, 3};
srna = RNA_def_struct(brna, "TransformOrientation", NULL);
prop = RNA_def_property(srna, "matrix", PROP_FLOAT, PROP_MATRIX);
RNA_def_property_float_sdna(prop, NULL, "mat");
- RNA_def_property_multi_array(prop, 2, matrix_dimsize);
+ RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_3x3);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
@@ -2071,8 +2079,8 @@ static void rna_def_statvis(BlenderRNA *brna)
{SCE_STATVIS_OVERHANG, "OVERHANG", 0, "Overhang", ""},
{SCE_STATVIS_THICKNESS, "THICKNESS", 0, "Thickness", ""},
{SCE_STATVIS_INTERSECT, "INTERSECT", 0, "Intersect", ""},
- {SCE_STATVIS_DISTORT, "DISTORT", 0, "Distort", ""},
- {SCE_STATVIS_SHARP, "SHARP", 0, "Sharp", ""},
+ {SCE_STATVIS_DISTORT, "DISTORT", 0, "Distortion", ""},
+ {SCE_STATVIS_SHARP, "SHARP", 0, "Sharp", ""},
{0, NULL, 0, NULL, NULL}};
srna = RNA_def_struct(brna, "MeshStatVis", NULL);
@@ -4078,6 +4086,8 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
{RE_BAKE_NORMALS, "NORMALS", 0, "Normals", "Bake normals"},
{RE_BAKE_TEXTURE, "TEXTURE", 0, "Textures", "Bake textures"},
{RE_BAKE_DISPLACEMENT, "DISPLACEMENT", 0, "Displacement", "Bake displacement"},
+ {RE_BAKE_DERIVATIVE, "DERIVATIVE", 0, "Derivative", "Bake derivative map"},
+ {RE_BAKE_VERTEX_COLORS, "VERTEX_COLORS", 0, "Vertex Colors", "Bake vertex colors"},
{RE_BAKE_EMIT, "EMIT", 0, "Emission", "Bake Emit values (glow)"},
{RE_BAKE_ALPHA, "ALPHA", 0, "Alpha", "Bake Alpha values (transparency)"},
{RE_BAKE_MIRROR_INTENSITY, "MIRROR_INTENSITY", 0, "Mirror Intensity", "Bake Mirror values"},
@@ -4664,6 +4674,17 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
"Bake to vertex colors instead of to a UV-mapped image");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+ prop = RNA_def_property(srna, "use_bake_user_scale", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "bake_flag", R_BAKE_USERSCALE);
+ RNA_def_property_ui_text(prop, "User scale", "Use a user scale for the derivative map");
+
+ prop = RNA_def_property(srna, "bake_user_scale", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "bake_user_scale");
+ RNA_def_property_range(prop, 0.0, 1000.0);
+ RNA_def_property_ui_text(prop, "Scale",
+ "Instead of automatically normalizing to 0..1, "
+ "apply a user scale to the derivative map");
+
/* stamp */
prop = RNA_def_property(srna, "use_stamp_time", PROP_BOOLEAN, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_scene_api.c b/source/blender/makesrna/intern/rna_scene_api.c
index 375b31e0586..ae6c5e71e6e 100644
--- a/source/blender/makesrna/intern/rna_scene_api.c
+++ b/source/blender/makesrna/intern/rna_scene_api.c
@@ -142,12 +142,12 @@ static void rna_Scene_collada_export(
int use_object_instantiation,
int sort_by_name,
int export_transformation_type,
- int second_life)
+ int open_sim)
{
collada_export(scene, filepath, apply_modifiers, export_mesh_type, selected,
include_children, include_armatures, include_shapekeys, deform_bones_only,
active_uv_only, include_uv_textures, include_material_textures,
- use_texture_copies, use_ngons, use_object_instantiation, sort_by_name, export_transformation_type, second_life);
+ use_texture_copies, use_ngons, use_object_instantiation, sort_by_name, export_transformation_type, open_sim);
}
#endif
@@ -218,7 +218,7 @@ void RNA_api_scene(StructRNA *srna)
parm = RNA_def_boolean(func, "use_ngons", 1, "Use NGons", "Keep NGons in Export");
parm = RNA_def_boolean(func, "use_object_instantiation", 1, "Use Object Instances", "Instantiate multiple Objects from same Data");
parm = RNA_def_boolean(func, "sort_by_name", 0, "Sort by Object name", "Sort exported data by Object name");
- parm = RNA_def_boolean(func, "second_life", 0, "Export for Second Life", "Compatibility mode for Second Life");
+ parm = RNA_def_boolean(func, "open_sim", 0, "Export for SL/OpenSim", "Compatibility mode for SL, OpenSim and similar online worlds");
parm = RNA_def_int(func, "export_transformation_type", 0, INT_MIN, INT_MAX,
"Transformation", "Transformation type for translation, scale and rotation", INT_MIN, INT_MAX);
diff --git a/source/blender/makesrna/intern/rna_screen.c b/source/blender/makesrna/intern/rna_screen.c
index f9171887bfb..b8269c428a1 100644
--- a/source/blender/makesrna/intern/rna_screen.c
+++ b/source/blender/makesrna/intern/rna_screen.c
@@ -94,7 +94,7 @@ static void rna_Screen_redraw_update(Main *UNUSED(bmain), Scene *UNUSED(scene),
}
-static int rna_Screen_is_animation_playing_get(PointerRNA *ptr)
+static int rna_Screen_is_animation_playing_get(PointerRNA *UNUSED(ptr))
{
return (ED_screen_animation_playing(G.main->wm.first) != NULL);
}
@@ -213,6 +213,7 @@ static void rna_def_area(BlenderRNA *brna)
prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "spacetype");
RNA_def_property_enum_items(prop, space_type_items);
+ RNA_def_property_enum_default(prop, SPACE_VIEW3D);
RNA_def_property_enum_funcs(prop, NULL, "rna_Area_type_set", "rna_Area_type_itemf");
RNA_def_property_ui_text(prop, "Editor Type", "Current editor type for this area");
RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c
index 11b3f94a446..89714e49ebf 100644
--- a/source/blender/makesrna/intern/rna_sculpt_paint.c
+++ b/source/blender/makesrna/intern/rna_sculpt_paint.c
@@ -190,7 +190,7 @@ static int rna_ParticleEdit_hair_get(PointerRNA *ptr)
return 0;
}
-static char *rna_ParticleEdit_path(PointerRNA *ptr)
+static char *rna_ParticleEdit_path(PointerRNA *UNUSED(ptr))
{
return BLI_strdup("tool_settings.particle_edit");
}
@@ -247,7 +247,7 @@ static void rna_Sculpt_ShowDiffuseColor_update(Main *UNUSED(bmain), Scene *scene
}
}
-static char *rna_Sculpt_path(PointerRNA *ptr)
+static char *rna_Sculpt_path(PointerRNA *UNUSED(ptr))
{
return BLI_strdup("tool_settings.sculpt");
}
@@ -264,17 +264,17 @@ static char *rna_VertexPaint_path(PointerRNA *ptr)
}
}
-static char *rna_ImagePaintSettings_path(PointerRNA *ptr)
+static char *rna_ImagePaintSettings_path(PointerRNA *UNUSED(ptr))
{
return BLI_strdup("tool_settings.image_paint");
}
-static char *rna_UvSculpt_path(PointerRNA *ptr)
+static char *rna_UvSculpt_path(PointerRNA *UNUSED(ptr))
{
return BLI_strdup("tool_settings.uv_sculpt");
}
-static char *rna_ParticleBrush_path(PointerRNA *ptr)
+static char *rna_ParticleBrush_path(PointerRNA *UNUSED(ptr))
{
return BLI_strdup("tool_settings.particle_edit.brush");
}
diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c
index bc50be00ddd..342d94c7667 100644
--- a/source/blender/makesrna/intern/rna_sequencer.c
+++ b/source/blender/makesrna/intern/rna_sequencer.c
@@ -720,7 +720,7 @@ static Sequence *sequence_get_by_proxy(Editing *ed, StripProxy *proxy)
return data.seq;
}
-static void rna_Sequence_tcindex_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
+static void rna_Sequence_tcindex_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
Scene *scene = (Scene *) ptr->id.data;
Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
diff --git a/source/blender/makesrna/intern/rna_smoke.c b/source/blender/makesrna/intern/rna_smoke.c
index 8b01a785f1e..ba90e3b1e4a 100644
--- a/source/blender/makesrna/intern/rna_smoke.c
+++ b/source/blender/makesrna/intern/rna_smoke.c
@@ -65,7 +65,7 @@ static void rna_Smoke_dependency_update(Main *bmain, Scene *scene, PointerRNA *p
DAG_relations_tag_update(bmain);
}
-static void rna_Smoke_resetCache(Main *bmain, Scene *scene, PointerRNA *ptr)
+static void rna_Smoke_resetCache(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
SmokeDomainSettings *settings = (SmokeDomainSettings *)ptr->data;
if (settings->smd && settings->smd->domain)
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index c2a8b25013e..41ea74ebb8c 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -406,23 +406,12 @@ static void rna_SpaceView3D_layer_update(Main *bmain, Scene *UNUSED(scene), Poin
DAG_on_visible_update(bmain, FALSE);
}
-static void rna_SpaceView3D_viewport_shade_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
+static void rna_SpaceView3D_viewport_shade_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
{
View3D *v3d = (View3D *)(ptr->data);
ScrArea *sa = rna_area_from_space(ptr);
- if (v3d->drawtype != OB_RENDER) {
- ARegion *ar;
-
- for (ar = sa->regionbase.first; ar; ar = ar->next) {
- RegionView3D *rv3d = ar->regiondata;
-
- if (rv3d && rv3d->render_engine) {
- RE_engine_free(rv3d->render_engine);
- rv3d->render_engine = NULL;
- }
- }
- }
+ ED_view3d_shade_update(bmain, v3d, sa);
}
static void rna_SpaceView3D_matcap_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
@@ -628,7 +617,7 @@ static PointerRNA rna_SpaceImageEditor_uvedit_get(PointerRNA *ptr)
return rna_pointer_inherit_refine(ptr, &RNA_SpaceUVEditor, ptr->data);
}
-static void rna_SpaceImageEditor_mode_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+static void rna_SpaceImageEditor_mode_update(Main *bmain, Scene *scene, PointerRNA *UNUSED(ptr))
{
ED_space_image_paint_update(bmain->wm.first, scene->toolsettings);
}
@@ -856,8 +845,8 @@ static void rna_SpaceProperties_context_set(PointerRNA *ptr, int value)
sbuts->mainbuser = value;
}
-static EnumPropertyItem *rna_SpaceProperties_context_itemf(bContext *C, PointerRNA *ptr,
- PropertyRNA *UNUSED(prop), int *free)
+static EnumPropertyItem *rna_SpaceProperties_context_itemf(bContext *UNUSED(C), PointerRNA *ptr,
+ PropertyRNA *UNUSED(prop), int *free)
{
SpaceButs *sbuts = (SpaceButs *)(ptr->data);
EnumPropertyItem *item = NULL;
@@ -1003,7 +992,8 @@ static void rna_ConsoleLine_body_set(PointerRNA *ptr, const char *value)
ci->cursor = len;
}
-static void rna_ConsoleLine_cursor_index_range(PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax)
+static void rna_ConsoleLine_cursor_index_range(PointerRNA *ptr, int *min, int *max,
+ int *UNUSED(softmin), int *UNUSED(softmax))
{
ConsoleLine *ci = (ConsoleLine *)ptr->data;
@@ -1346,6 +1336,12 @@ static void rna_def_space_mask_info(StructRNA *srna, int noteflag, const char *m
{
PropertyRNA *prop;
+ static EnumPropertyItem overlay_mode_items[] = {
+ {MASK_OVERLAY_ALPHACHANNEL, "ALPHACHANNEL", ICON_NONE, "Alpha Channel", "Show alpha channel of the mask"},
+ {MASK_OVERLAY_COMBINED, "COMBINED", ICON_NONE, "Combined", "Combine space background image with the mask"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
prop = RNA_def_property(srna, "mask", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "mask_info.mask");
RNA_def_property_flag(prop, PROP_EDITABLE);
@@ -1364,6 +1360,17 @@ static void rna_def_space_mask_info(StructRNA *srna, int noteflag, const char *m
RNA_def_property_boolean_sdna(prop, NULL, "mask_info.draw_flag", MASK_DRAWFLAG_SMOOTH);
RNA_def_property_ui_text(prop, "Draw Smooth Splines", "");
RNA_def_property_update(prop, noteflag, NULL);
+
+ prop = RNA_def_property(srna, "show_mask_overlay", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "mask_info.draw_flag", MASK_DRAWFLAG_OVERLAY);
+ RNA_def_property_ui_text(prop, "Show Mask Overlay", "");
+ RNA_def_property_update(prop, noteflag, NULL);
+
+ prop = RNA_def_property(srna, "mask_overlay_mode", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "mask_info.overlay_mode");
+ RNA_def_property_enum_items(prop, overlay_mode_items);
+ RNA_def_property_ui_text(prop, "Overlay Mode", "Overlay mode of rasterized mask");
+ RNA_def_property_update(prop, noteflag, NULL);
}
static void rna_def_space_image_uv(BlenderRNA *brna)
@@ -1694,7 +1701,6 @@ static void rna_def_space_view3d(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
- const int matrix_dimsize[] = {4, 4};
static EnumPropertyItem pivot_items[] = {
{V3D_CENTER, "BOUNDING_BOX_CENTER", ICON_ROTATE, "Bounding Box Center",
@@ -2114,12 +2120,12 @@ static void rna_def_space_view3d(BlenderRNA *brna)
prop = RNA_def_property(srna, "perspective_matrix", PROP_FLOAT, PROP_MATRIX);
RNA_def_property_float_sdna(prop, NULL, "persmat");
RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* XXX: for now, it's too risky for users to do this */
- RNA_def_property_multi_array(prop, 2, matrix_dimsize);
+ RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_4x4);
RNA_def_property_ui_text(prop, "Perspective Matrix", "Current perspective matrix of the 3D region");
prop = RNA_def_property(srna, "view_matrix", PROP_FLOAT, PROP_MATRIX);
RNA_def_property_float_sdna(prop, NULL, "viewmat");
- RNA_def_property_multi_array(prop, 2, matrix_dimsize);
+ RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_4x4);
RNA_def_property_float_funcs(prop, NULL, "rna_RegionView3D_view_matrix_set", NULL);
RNA_def_property_ui_text(prop, "View Matrix", "Current view matrix of the 3D region");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
diff --git a/source/blender/makesrna/intern/rna_test.c b/source/blender/makesrna/intern/rna_test.c
index e54e5f9bcad..cf0dc5e332d 100644
--- a/source/blender/makesrna/intern/rna_test.c
+++ b/source/blender/makesrna/intern/rna_test.c
@@ -185,7 +185,8 @@ void RNA_def_test(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_DYNAMIC);
RNA_def_property_dynamic_array_funcs(prop, "rna_Test_bdmarr_get_length", "rna_Test_bdmarr_set_length");
RNA_def_property_boolean_funcs(prop, "rna_Test_bdmarr_get", "rna_Test_bdmarr_set");
-
+#else
+ (void)brna;
#endif
}
diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c
index 2c68661f3bd..a26272b34ce 100644
--- a/source/blender/makesrna/intern/rna_texture.c
+++ b/source/blender/makesrna/intern/rna_texture.c
@@ -184,7 +184,7 @@ static void rna_Texture_mapping_update(Main *bmain, Scene *scene, PointerRNA *pt
rna_Texture_update(bmain, scene, ptr);
}
-static void rna_Color_mapping_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+static void rna_Color_mapping_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *UNUSED(ptr))
{
/* nothing to do */
}
@@ -366,7 +366,7 @@ static int rna_TextureSlot_output_node_get(PointerRNA *ptr)
}
-static EnumPropertyItem *rna_TextureSlot_output_node_itemf(bContext *C, PointerRNA *ptr,
+static EnumPropertyItem *rna_TextureSlot_output_node_itemf(bContext *UNUSED(C), PointerRNA *ptr,
PropertyRNA *UNUSED(prop), int *free)
{
MTex *mtex = ptr->data;
@@ -478,7 +478,7 @@ static char *rna_VoxelData_path(PointerRNA *UNUSED(ptr))
return BLI_sprintfN("voxel_data");
}
-static char *rna_OceanTex_path(PointerRNA *ptr)
+static char *rna_OceanTex_path(PointerRNA *UNUSED(ptr))
{
return BLI_sprintfN("ocean");
}
@@ -495,6 +495,14 @@ static void rna_def_texmapping(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL}
};
+ static EnumPropertyItem prop_vect_type_items[] = {
+ {TEXMAP_TYPE_TEXTURE, "TEXTURE", 0, "Texture", "Transform a texture by inverse mapping the texture coordinate"},
+ {TEXMAP_TYPE_POINT, "POINT", 0, "Point", "Transform a point"},
+ {TEXMAP_TYPE_VECTOR, "VECTOR", 0, "Vector", "Transform a direction vector"},
+ {TEXMAP_TYPE_NORMAL, "NORMAL", 0, "Normal", "Transform a normal vector with unit length"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
static EnumPropertyItem prop_xyz_mapping_items[] = {
{0, "NONE", 0, "None", ""},
{1, "X", 0, "X", ""},
@@ -509,6 +517,12 @@ static void rna_def_texmapping(BlenderRNA *brna)
srna = RNA_def_struct(brna, "TexMapping", NULL);
RNA_def_struct_ui_text(srna, "Texture Mapping", "Texture coordinate mapping settings");
+ prop = RNA_def_property(srna, "vector_type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "type");
+ RNA_def_property_enum_items(prop, prop_vect_type_items);
+ RNA_def_property_ui_text(prop, "Type", "Type of vector that the mapping transforms");
+ RNA_def_property_update(prop, 0, "rna_Texture_mapping_update");
+
prop = RNA_def_property(srna, "translation", PROP_FLOAT, PROP_TRANSLATION);
RNA_def_property_float_sdna(prop, NULL, "loc");
RNA_def_property_ui_text(prop, "Location", "");
diff --git a/source/blender/makesrna/intern/rna_tracking.c b/source/blender/makesrna/intern/rna_tracking.c
index 0feaec85e38..97f5c24dc56 100644
--- a/source/blender/makesrna/intern/rna_tracking.c
+++ b/source/blender/makesrna/intern/rna_tracking.c
@@ -124,7 +124,8 @@ static void rna_tracking_active_object_index_set(PointerRNA *ptr, int value)
BKE_tracking_dopesheet_tag_update(&clip->tracking);
}
-static void rna_tracking_active_object_index_range(PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax)
+static void rna_tracking_active_object_index_range(PointerRNA *ptr, int *min, int *max,
+ int *UNUSED(softmin), int *UNUSED(softmax))
{
MovieClip *clip = (MovieClip *)ptr->id.data;
@@ -362,7 +363,8 @@ static void rna_tracking_stabTracks_active_index_set(PointerRNA *ptr, int value)
clip->tracking.stabilization.act_track = value;
}
-static void rna_tracking_stabTracks_active_index_range(PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax)
+static void rna_tracking_stabTracks_active_index_range(PointerRNA *ptr, int *min, int *max,
+ int *UNUSED(softmin), int *UNUSED(softmax))
{
MovieClip *clip = (MovieClip *)ptr->id.data;
@@ -525,7 +527,7 @@ static void rna_tracking_markerPattern_boundbox_get(PointerRNA *ptr, float *valu
copy_v2_v2(values + 2, max);
}
-static void rna_trackingDopesheet_tagUpdate(Main *UNUSED(bmain), Scene *scene, PointerRNA *ptr)
+static void rna_trackingDopesheet_tagUpdate(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
MovieClip *clip = (MovieClip *)ptr->id.data;
MovieTrackingDopesheet *dopesheet = &clip->tracking.dopesheet;
@@ -709,9 +711,6 @@ static EnumPropertyItem pattern_match_items[] = {
{0, NULL, 0, NULL, NULL}
};
-static int rna_matrix_dimsize_4x4[] = {4, 4};
-static int rna_matrix_dimsize_4x2[] = {4, 2};
-
static void rna_def_trackingSettings(BlenderRNA *brna)
{
StructRNA *srna;
diff --git a/source/blender/makesrna/intern/rna_ui.c b/source/blender/makesrna/intern/rna_ui.c
index 40bc0d3973e..39f305f7d47 100644
--- a/source/blender/makesrna/intern/rna_ui.c
+++ b/source/blender/makesrna/intern/rna_ui.c
@@ -166,7 +166,7 @@ static void panel_draw_header(const bContext *C, Panel *pnl)
RNA_parameter_list_free(&list);
}
-static void rna_Panel_unregister(Main *bmain, StructRNA *type)
+static void rna_Panel_unregister(Main *UNUSED(bmain), StructRNA *type)
{
ARegionType *art;
PanelType *pt = RNA_struct_blender_type_get(type);
@@ -268,7 +268,7 @@ static StructRNA *rna_Panel_refine(PointerRNA *ptr)
}
/* UIList */
-static unsigned int rna_UIList_filter_const_FILTER_ITEM_get(PointerRNA *ptr)
+static unsigned int rna_UIList_filter_const_FILTER_ITEM_get(PointerRNA *UNUSED(ptr))
{
return UILST_FLT_ITEM;
}
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index 3b609b69374..20e5083b1c4 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -505,6 +505,7 @@ static EnumPropertyItem *rna_userdef_audio_device_itemf(bContext *UNUSED(C), Poi
return item;
}
#else
+ (void)free;
return audio_device_items;
#endif
}
diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c
index 71e3d86387b..c6366745c55 100644
--- a/source/blender/makesrna/intern/rna_wm.c
+++ b/source/blender/makesrna/intern/rna_wm.c
@@ -590,7 +590,7 @@ static void rna_Window_screen_set(PointerRNA *ptr, PointerRNA value)
win->newscreen = value.data;
}
-int rna_Window_screen_assign_poll(PointerRNA *ptr, PointerRNA value)
+int rna_Window_screen_assign_poll(PointerRNA *UNUSED(ptr), PointerRNA value)
{
bScreen *screen = (bScreen *)value.id.data;
diff --git a/source/blender/makesrna/intern/rna_wm_api.c b/source/blender/makesrna/intern/rna_wm_api.c
index 824fed98338..eb84bb61e1f 100644
--- a/source/blender/makesrna/intern/rna_wm_api.c
+++ b/source/blender/makesrna/intern/rna_wm_api.c
@@ -118,7 +118,7 @@ struct wmStaticProgress {
} wm_progress_state = {0, 0, false};
-static void rna_progress_begin(struct wmWindowManager *wm, float min, float max)
+static void rna_progress_begin(struct wmWindowManager *UNUSED(wm), float min, float max)
{
float range = max - min;
if (range != 0) {
@@ -262,6 +262,18 @@ static wmKeyMap *rna_keymap_find_modal(wmKeyConfig *UNUSED(keyconf), const char
return ot->modalkeymap;
}
+static void rna_KeyMap_remove(wmKeyConfig *keyconfig, ReportList *reports, PointerRNA *keymap_ptr)
+{
+ wmKeyMap *keymap = keymap_ptr->data;
+
+ if (WM_keymap_remove(keyconfig, keymap) == FALSE) {
+ BKE_reportf(reports, RPT_ERROR, "KeyConfig '%s' cannot be removed", keymap->idname);
+ return;
+ }
+
+ RNA_POINTER_INVALIDATE(keymap_ptr);
+}
+
static void rna_KeyConfig_remove(wmWindowManager *wm, ReportList *reports, PointerRNA *keyconf_ptr)
{
wmKeyConfig *keyconf = keyconf_ptr->data;
@@ -671,6 +683,12 @@ void RNA_api_keymaps(StructRNA *srna)
parm = RNA_def_pointer(func, "keymap", "KeyMap", "Key Map", "Added key map");
RNA_def_function_return(func, parm);
+ func = RNA_def_function(srna, "remove", "rna_KeyMap_remove"); /* remove_keymap */
+ RNA_def_function_flag(func, FUNC_USE_REPORTS);
+ parm = RNA_def_pointer(func, "keymap", "KeyMap", "Key Map", "Removed key map");
+ RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
+ RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
+
func = RNA_def_function(srna, "find", "rna_keymap_find"); /* find_keymap */
parm = RNA_def_string(func, "name", "", 0, "Name", "");
RNA_def_property_flag(parm, PROP_REQUIRED);
diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h
index f90ee49fc14..db9f710b6cf 100644
--- a/source/blender/nodes/NOD_static_types.h
+++ b/source/blender/nodes/NOD_static_types.h
@@ -1,4 +1,3 @@
-
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
diff --git a/source/blender/nodes/composite/nodes/node_composite_mapValue.c b/source/blender/nodes/composite/nodes/node_composite_mapValue.c
index 316e5b344ce..22d16e93879 100644
--- a/source/blender/nodes/composite/nodes/node_composite_mapValue.c
+++ b/source/blender/nodes/composite/nodes/node_composite_mapValue.c
@@ -44,7 +44,7 @@ static bNodeSocketTemplate cmp_node_map_value_out[] = {
static void node_composit_init_map_value(bNodeTree *UNUSED(ntree), bNode *node)
{
- node->storage = add_tex_mapping();
+ node->storage = add_tex_mapping(TEXMAP_TYPE_POINT);
}
void register_node_type_cmp_map_value(void)
diff --git a/source/blender/nodes/composite/nodes/node_composite_scale.c b/source/blender/nodes/composite/nodes/node_composite_scale.c
index 134402c00e1..8041a2e56e9 100644
--- a/source/blender/nodes/composite/nodes/node_composite_scale.c
+++ b/source/blender/nodes/composite/nodes/node_composite_scale.c
@@ -45,12 +45,31 @@ static bNodeSocketTemplate cmp_node_scale_out[] = {
{ -1, 0, "" }
};
+static void node_composite_update_scale(bNodeTree *UNUSED(ntree), bNode *node)
+{
+ bNodeSocket *sock;
+ bool use_xy_scale = ELEM(node->custom1, CMP_SCALE_RELATIVE, CMP_SCALE_ABSOLUTE);
+
+ /* Only show X/Y scale factor inputs for modes using them! */
+ for (sock = node->inputs.first; sock; sock = sock->next) {
+ if (STREQ(sock->name, "X") || STREQ(sock->name, "Y")) {
+ if (use_xy_scale) {
+ sock->flag &= ~SOCK_UNAVAIL;
+ }
+ else {
+ sock->flag |= SOCK_UNAVAIL;
+ }
+ }
+ }
+}
+
void register_node_type_cmp_scale(void)
{
static bNodeType ntype;
cmp_node_type_base(&ntype, CMP_NODE_SCALE, "Scale", NODE_CLASS_DISTORT, 0);
node_type_socket_templates(&ntype, cmp_node_scale_in, cmp_node_scale_out);
+ node_type_update(&ntype, node_composite_update_scale, NULL);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/node_shader_util.c b/source/blender/nodes/shader/node_shader_util.c
index aed8a0224f1..86e59cd779a 100644
--- a/source/blender/nodes/shader/node_shader_util.c
+++ b/source/blender/nodes/shader/node_shader_util.c
@@ -271,6 +271,9 @@ void node_shader_gpu_tex_mapping(GPUMaterial *mat, bNode *node, GPUNodeStack *in
GPUNodeLink *tdomax = GPU_uniform(&domax);
GPU_link(mat, "mapping", in[0].link, tmat, tmin, tmax, tdomin, tdomax, &in[0].link);
+
+ if (texmap->type == TEXMAP_TYPE_NORMAL)
+ GPU_link(mat, "texco_norm", in[0].link, &in[0].link);
}
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_gamma.c b/source/blender/nodes/shader/nodes/node_shader_gamma.c
index fad1a69d364..9956fd712c8 100644
--- a/source/blender/nodes/shader/nodes/node_shader_gamma.c
+++ b/source/blender/nodes/shader/nodes/node_shader_gamma.c
@@ -41,6 +41,11 @@ static bNodeSocketTemplate sh_node_gamma_out[] = {
{ -1, 0, "" }
};
+static int node_shader_gpu_gamma(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
+{
+ return GPU_stack_link(mat, "node_gamma", in, out);
+}
+
void register_node_type_sh_gamma(void)
{
static bNodeType ntype;
@@ -50,6 +55,7 @@ void register_node_type_sh_gamma(void)
node_type_socket_templates(&ntype, sh_node_gamma_in, sh_node_gamma_out);
node_type_init(&ntype, NULL);
node_type_storage(&ntype, "", NULL, NULL);
+ node_type_gpu(&ntype, node_shader_gpu_gamma);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_mapping.c b/source/blender/nodes/shader/nodes/node_shader_mapping.c
index 05936e22775..cff4a039602 100644
--- a/source/blender/nodes/shader/nodes/node_shader_mapping.c
+++ b/source/blender/nodes/shader/nodes/node_shader_mapping.c
@@ -29,7 +29,6 @@
* \ingroup shdnodes
*/
-
#include "node_shader_util.h"
/* **************** MAPPING ******************** */
@@ -53,7 +52,7 @@ static void node_shader_exec_mapping(void *UNUSED(data), int UNUSED(thread), bNo
/* stack order output: vector */
nodestack_get_vec(vec, SOCK_VECTOR, in[0]);
mul_m4_v3(texmap->mat, vec);
-
+
if (texmap->flag & TEXMAP_CLIP_MIN) {
if (vec[0] < texmap->min[0]) vec[0] = texmap->min[0];
if (vec[1] < texmap->min[1]) vec[1] = texmap->min[1];
@@ -64,12 +63,15 @@ static void node_shader_exec_mapping(void *UNUSED(data), int UNUSED(thread), bNo
if (vec[1] > texmap->max[1]) vec[1] = texmap->max[1];
if (vec[2] > texmap->max[2]) vec[2] = texmap->max[2];
}
+
+ if (texmap->type == TEXMAP_TYPE_NORMAL)
+ normalize_v3(vec);
}
static void node_shader_init_mapping(bNodeTree *UNUSED(ntree), bNode *node)
{
- node->storage = add_tex_mapping();
+ node->storage = add_tex_mapping(TEXMAP_TYPE_POINT);
}
static int gpu_shader_mapping(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
@@ -83,7 +85,12 @@ static int gpu_shader_mapping(GPUMaterial *mat, bNode *node, bNodeExecData *UNUS
GPUNodeLink *tdomin = GPU_uniform(&domin);
GPUNodeLink *tdomax = GPU_uniform(&domax);
- return GPU_stack_link(mat, "mapping", in, out, tmat, tmin, tmax, tdomin, tdomax);
+ int result = GPU_stack_link(mat, "mapping", in, out, tmat, tmin, tmax, tdomin, tdomax);
+
+ if (result && texmap->type == TEXMAP_TYPE_NORMAL)
+ GPU_link(mat, "texco_norm", out[0].link, &out[0].link);
+
+ return result;
}
void register_node_type_sh_mapping(void)
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_brick.c b/source/blender/nodes/shader/nodes/node_shader_tex_brick.c
index 826b7d9337d..12da301d090 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_brick.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_brick.c
@@ -51,7 +51,7 @@ static bNodeSocketTemplate sh_node_tex_brick_out[] = {
static void node_shader_init_tex_brick(bNodeTree *UNUSED(ntree), bNode *node)
{
NodeTexBrick *tex = MEM_callocN(sizeof(NodeTexBrick), "NodeTexBrick");
- default_tex_mapping(&tex->base.tex_mapping);
+ default_tex_mapping(&tex->base.tex_mapping, TEXMAP_TYPE_POINT);
default_color_mapping(&tex->base.color_mapping);
tex->offset = 0.5f;
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_checker.c b/source/blender/nodes/shader/nodes/node_shader_tex_checker.c
index ceb3911f429..725b5654523 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_checker.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_checker.c
@@ -46,7 +46,7 @@ static bNodeSocketTemplate sh_node_tex_checker_out[] = {
static void node_shader_init_tex_checker(bNodeTree *UNUSED(ntree), bNode *node)
{
NodeTexChecker *tex = MEM_callocN(sizeof(NodeTexChecker), "NodeTexChecker");
- default_tex_mapping(&tex->base.tex_mapping);
+ default_tex_mapping(&tex->base.tex_mapping, TEXMAP_TYPE_POINT);
default_color_mapping(&tex->base.color_mapping);
node->storage = tex;
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 2fbf5b6faf9..5e6471eab77 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_environment.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_environment.c
@@ -44,7 +44,7 @@ static bNodeSocketTemplate sh_node_tex_environment_out[] = {
static void node_shader_init_tex_environment(bNodeTree *UNUSED(ntree), bNode *node)
{
NodeTexEnvironment *tex = MEM_callocN(sizeof(NodeTexEnvironment), "NodeTexEnvironment");
- default_tex_mapping(&tex->base.tex_mapping);
+ default_tex_mapping(&tex->base.tex_mapping, TEXMAP_TYPE_POINT);
default_color_mapping(&tex->base.color_mapping);
tex->color_space = SHD_COLORSPACE_COLOR;
tex->projection = SHD_PROJ_EQUIRECTANGULAR;
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_gradient.c b/source/blender/nodes/shader/nodes/node_shader_tex_gradient.c
index 5ee3b1f6176..c3ef897b1ad 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_gradient.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_gradient.c
@@ -43,7 +43,7 @@ static bNodeSocketTemplate sh_node_tex_gradient_out[] = {
static void node_shader_init_tex_gradient(bNodeTree *UNUSED(ntree), bNode *node)
{
NodeTexGradient *tex = MEM_callocN(sizeof(NodeTexGradient), "NodeTexGradient");
- default_tex_mapping(&tex->base.tex_mapping);
+ default_tex_mapping(&tex->base.tex_mapping, TEXMAP_TYPE_POINT);
default_color_mapping(&tex->base.color_mapping);
tex->gradient_type = SHD_BLEND_LINEAR;
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 53c44ebd715..1b705e12daf 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_image.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_image.c
@@ -45,7 +45,7 @@ static bNodeSocketTemplate sh_node_tex_image_out[] = {
static void node_shader_init_tex_image(bNodeTree *UNUSED(ntree), bNode *node)
{
NodeTexImage *tex = MEM_callocN(sizeof(NodeTexImage), "NodeTexImage");
- default_tex_mapping(&tex->base.tex_mapping);
+ default_tex_mapping(&tex->base.tex_mapping, TEXMAP_TYPE_POINT);
default_color_mapping(&tex->base.color_mapping);
tex->color_space = SHD_COLORSPACE_COLOR;
tex->iuser.frames = 1;
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_magic.c b/source/blender/nodes/shader/nodes/node_shader_tex_magic.c
index 38292939a3c..b9339bc483f 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_magic.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_magic.c
@@ -45,7 +45,7 @@ static bNodeSocketTemplate sh_node_tex_magic_out[] = {
static void node_shader_init_tex_magic(bNodeTree *UNUSED(ntree), bNode *node)
{
NodeTexMagic *tex = MEM_callocN(sizeof(NodeTexMagic), "NodeTexMagic");
- default_tex_mapping(&tex->base.tex_mapping);
+ default_tex_mapping(&tex->base.tex_mapping, TEXMAP_TYPE_POINT);
default_color_mapping(&tex->base.color_mapping);
tex->depth = 2;
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_musgrave.c b/source/blender/nodes/shader/nodes/node_shader_tex_musgrave.c
index b41cc7d8812..2b5d5e12420 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_musgrave.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_musgrave.c
@@ -49,7 +49,7 @@ static bNodeSocketTemplate sh_node_tex_musgrave_out[] = {
static void node_shader_init_tex_musgrave(bNodeTree *UNUSED(ntree), bNode *node)
{
NodeTexMusgrave *tex = MEM_callocN(sizeof(NodeTexMusgrave), "NodeTexMusgrave");
- default_tex_mapping(&tex->base.tex_mapping);
+ default_tex_mapping(&tex->base.tex_mapping, TEXMAP_TYPE_POINT);
default_color_mapping(&tex->base.color_mapping);
tex->musgrave_type = SHD_MUSGRAVE_FBM;
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_noise.c b/source/blender/nodes/shader/nodes/node_shader_tex_noise.c
index a7009b81e9a..36e26925501 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_noise.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_noise.c
@@ -46,7 +46,7 @@ static bNodeSocketTemplate sh_node_tex_noise_out[] = {
static void node_shader_init_tex_noise(bNodeTree *UNUSED(ntree), bNode *node)
{
NodeTexNoise *tex = MEM_callocN(sizeof(NodeTexNoise), "NodeTexNoise");
- default_tex_mapping(&tex->base.tex_mapping);
+ default_tex_mapping(&tex->base.tex_mapping, TEXMAP_TYPE_POINT);
default_color_mapping(&tex->base.color_mapping);
node->storage = tex;
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_sky.c b/source/blender/nodes/shader/nodes/node_shader_tex_sky.c
index c80b5282de3..22061979b12 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_sky.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_sky.c
@@ -42,7 +42,7 @@ static bNodeSocketTemplate sh_node_tex_sky_out[] = {
static void node_shader_init_tex_sky(bNodeTree *UNUSED(ntree), bNode *node)
{
NodeTexSky *tex = MEM_callocN(sizeof(NodeTexSky), "NodeTexSky");
- default_tex_mapping(&tex->base.tex_mapping);
+ default_tex_mapping(&tex->base.tex_mapping, TEXMAP_TYPE_POINT);
default_color_mapping(&tex->base.color_mapping);
tex->sun_direction[0] = 0.0f;
tex->sun_direction[1] = 0.0f;
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_voronoi.c b/source/blender/nodes/shader/nodes/node_shader_tex_voronoi.c
index 3f1b0638b99..f75c05601aa 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_voronoi.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_voronoi.c
@@ -44,7 +44,7 @@ static bNodeSocketTemplate sh_node_tex_voronoi_out[] = {
static void node_shader_init_tex_voronoi(bNodeTree *UNUSED(ntree), bNode *node)
{
NodeTexVoronoi *tex = MEM_callocN(sizeof(NodeTexVoronoi), "NodeTexVoronoi");
- default_tex_mapping(&tex->base.tex_mapping);
+ default_tex_mapping(&tex->base.tex_mapping, TEXMAP_TYPE_POINT);
default_color_mapping(&tex->base.color_mapping);
tex->coloring = SHD_VORONOI_INTENSITY;
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_wave.c b/source/blender/nodes/shader/nodes/node_shader_tex_wave.c
index a424265c94a..be7df85fbee 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_wave.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_wave.c
@@ -47,7 +47,7 @@ static bNodeSocketTemplate sh_node_tex_wave_out[] = {
static void node_shader_init_tex_wave(bNodeTree *UNUSED(ntree), bNode *node)
{
NodeTexWave *tex = MEM_callocN(sizeof(NodeTexWave), "NodeTexWave");
- default_tex_mapping(&tex->base.tex_mapping);
+ default_tex_mapping(&tex->base.tex_mapping, TEXMAP_TYPE_POINT);
default_color_mapping(&tex->base.color_mapping);
tex->wave_type = SHD_WAVE_BANDS;
diff --git a/source/blender/python/intern/CMakeLists.txt b/source/blender/python/intern/CMakeLists.txt
index aae0f926e81..4b2b86ab6c4 100644
--- a/source/blender/python/intern/CMakeLists.txt
+++ b/source/blender/python/intern/CMakeLists.txt
@@ -174,6 +174,10 @@ if(WITH_IMAGE_OPENEXR)
add_definitions(-DWITH_OPENEXR)
endif()
+if(WITH_IMAGE_OPENIMAGEIO)
+ add_definitions(-DWITH_OPENIMAGEIO)
+endif()
+
if(WITH_IMAGE_OPENJPEG)
add_definitions(-DWITH_OPENJPEG)
endif()
diff --git a/source/blender/python/intern/bpy_operator_wrap.c b/source/blender/python/intern/bpy_operator_wrap.c
index 65b7bf62032..efee9b13d58 100644
--- a/source/blender/python/intern/bpy_operator_wrap.c
+++ b/source/blender/python/intern/bpy_operator_wrap.c
@@ -177,14 +177,17 @@ PyObject *PYOP_wrap_macro_define(PyObject *UNUSED(self), PyObject *args)
}
/* identifiers */
- srna = srna_from_self(macro, "Macro Define:");
- macroname = RNA_struct_identifier(srna);
+ srna = pyrna_struct_as_srna((PyObject *)macro, false, "Macro Define:");
+ if (srna == NULL) {
+ return NULL;
+ }
+ macroname = RNA_struct_identifier(srna);
ot = WM_operatortype_find(macroname, true);
if (!ot) {
PyErr_Format(PyExc_ValueError,
- "Macro Define: '%s' is not a valid macro or hasn't been registered yet",
+ "Macro Define: '%s' is not a valid macro",
macroname);
return NULL;
}
diff --git a/source/blender/python/mathutils/mathutils_Euler.c b/source/blender/python/mathutils/mathutils_Euler.c
index 6bb3031f0a3..2a874f51fd4 100644
--- a/source/blender/python/mathutils/mathutils_Euler.c
+++ b/source/blender/python/mathutils/mathutils_Euler.c
@@ -707,7 +707,7 @@ PyTypeObject euler_Type = {
* (i.e. it was allocated elsewhere by MEM_mallocN())
* pass Py_NEW - if vector is not a WRAPPER and managed by PYTHON
* (i.e. it must be created here with PyMEM_malloc())*/
-PyObject *Euler_CreatePyObject(float *eul, const short order, int type, PyTypeObject *base_type)
+PyObject *Euler_CreatePyObject(float eul[3], const short order, int type, PyTypeObject *base_type)
{
EulerObject *self;
diff --git a/source/blender/python/mathutils/mathutils_Euler.h b/source/blender/python/mathutils/mathutils_Euler.h
index 355d0ed1810..62fb83ef234 100644
--- a/source/blender/python/mathutils/mathutils_Euler.h
+++ b/source/blender/python/mathutils/mathutils_Euler.h
@@ -43,7 +43,7 @@ typedef struct {
* blender (stored in blend_data). This is an either/or struct not both */
/* prototypes */
-PyObject *Euler_CreatePyObject(float *eul, const short order, int type, PyTypeObject *base_type);
+PyObject *Euler_CreatePyObject(float eul[3], const short order, int type, PyTypeObject *base_type);
PyObject *Euler_CreatePyObject_cb(PyObject *cb_user, const short order,
unsigned char cb_type, unsigned char cb_subtype);
diff --git a/source/blender/python/mathutils/mathutils_Quaternion.c b/source/blender/python/mathutils/mathutils_Quaternion.c
index b0b818faaa0..e13136057c8 100644
--- a/source/blender/python/mathutils/mathutils_Quaternion.c
+++ b/source/blender/python/mathutils/mathutils_Quaternion.c
@@ -1246,7 +1246,7 @@ PyTypeObject quaternion_Type = {
* (i.e. it was allocated elsewhere by MEM_mallocN())
* pass Py_NEW - if vector is not a WRAPPER and managed by PYTHON
* (i.e. it must be created here with PyMEM_malloc())*/
-PyObject *Quaternion_CreatePyObject(float *quat, int type, PyTypeObject *base_type)
+PyObject *Quaternion_CreatePyObject(float quat[4], int type, PyTypeObject *base_type)
{
QuaternionObject *self;
diff --git a/source/blender/python/mathutils/mathutils_Quaternion.h b/source/blender/python/mathutils/mathutils_Quaternion.h
index be3566934a4..36036c6d3fa 100644
--- a/source/blender/python/mathutils/mathutils_Quaternion.h
+++ b/source/blender/python/mathutils/mathutils_Quaternion.h
@@ -40,7 +40,7 @@ typedef struct {
* blender (stored in blend_data). This is an either/or struct not both */
/* prototypes */
-PyObject *Quaternion_CreatePyObject(float *quat, int type, PyTypeObject *base_type);
+PyObject *Quaternion_CreatePyObject(float quat[4], int type, PyTypeObject *base_type);
PyObject *Quaternion_CreatePyObject_cb(PyObject *cb_user,
unsigned char cb_type, unsigned char cb_subtype);
diff --git a/source/blender/python/mathutils/mathutils_Vector.c b/source/blender/python/mathutils/mathutils_Vector.c
index 8a5a8446ac6..6b2da9ca593 100644
--- a/source/blender/python/mathutils/mathutils_Vector.c
+++ b/source/blender/python/mathutils/mathutils_Vector.c
@@ -1853,7 +1853,7 @@ static PyObject *Vector_neg(VectorObject *self)
}
/*------------------------vec_magnitude_nosqrt (internal) - for comparing only */
-static double vec_magnitude_nosqrt(float *data, int size)
+static double vec_magnitude_nosqrt(const float *data, int size)
{
/* return (double)sqrt(dot);*/
/* warning, line above removed because we are not using the length,
@@ -2940,10 +2940,10 @@ PyObject *Vector_CreatePyObject_cb(PyObject *cb_user, int size, unsigned char cb
return (PyObject *)self;
}
-PyObject *Vector_CreatePyObject_alloc(float *vec, const int size, PyTypeObject *base_type)
+PyObject *Vector_CreatePyObject_alloc(const float *vec, const int size, PyTypeObject *base_type)
{
VectorObject *vect_ob;
- vect_ob = (VectorObject *)Vector_CreatePyObject(vec, size, Py_WRAP, base_type);
+ vect_ob = (VectorObject *)Vector_CreatePyObject((float *)vec, size, Py_WRAP, base_type);
vect_ob->wrapped = Py_NEW;
return (PyObject *)vect_ob;
diff --git a/source/blender/python/mathutils/mathutils_Vector.h b/source/blender/python/mathutils/mathutils_Vector.h
index 18d89e73734..2074270670a 100644
--- a/source/blender/python/mathutils/mathutils_Vector.h
+++ b/source/blender/python/mathutils/mathutils_Vector.h
@@ -41,6 +41,6 @@ typedef struct {
PyObject *Vector_CreatePyObject(float *vec, const int size, const int type, PyTypeObject *base_type);
PyObject *Vector_CreatePyObject_cb(PyObject *user, int size,
unsigned char cb_type, unsigned char subtype);
-PyObject *Vector_CreatePyObject_alloc(float *vec, const int size, PyTypeObject *base_type);
+PyObject *Vector_CreatePyObject_alloc(const float *vec, const int size, PyTypeObject *base_type);
-#endif /* __MATHUTILS_VECTOR_H__ */
+#endif /* __MATHUTILS_VECTOR_H__ */
diff --git a/source/blender/quicktime/apple/qtkit_export.m b/source/blender/quicktime/apple/qtkit_export.m
index 7b42c89d936..8cf91e44c77 100644
--- a/source/blender/quicktime/apple/qtkit_export.m
+++ b/source/blender/quicktime/apple/qtkit_export.m
@@ -317,7 +317,7 @@ int start_qt(struct Scene *scene, struct RenderData *rd, int rectx, int recty, R
int success = 1;
OSStatus err = noErr;
- if(qtexport == NULL) qtexport = MEM_callocN(sizeof(QuicktimeExport), "QuicktimeExport");
+ if (qtexport == NULL) qtexport = MEM_callocN(sizeof(QuicktimeExport), "QuicktimeExport");
[QTMovie enterQTKitOnThread];
@@ -476,7 +476,7 @@ int start_qt(struct Scene *scene, struct RenderData *rd, int rectx, int recty, R
err = AudioFileCreateWithURL(outputFileURL, audioFileType, &qtexport->audioOutputFormat, kAudioFileFlags_EraseFile, &qtexport->audioFile);
CFRelease(outputFileURL);
- if(err)
+ if (err)
BKE_report(reports, RPT_ERROR, "\nQuicktime: unable to create temporary audio file. Format error ?");
else {
err = AudioConverterNew(&qtexport->audioInputFormat, &qtexport->audioOutputFormat, &qtexport->audioConverter);
@@ -542,7 +542,7 @@ int start_qt(struct Scene *scene, struct RenderData *rd, int rectx, int recty, R
else
qtexport->movie = [[QTMovie alloc] initToWritableFile:qtexport->filename error:&error];
- if(qtexport->movie == nil) {
+ if (qtexport->movie == nil) {
BKE_report(reports, RPT_ERROR, "Unable to create quicktime movie.");
success = 0;
if (qtexport->filename) [qtexport->filename release];
@@ -749,13 +749,11 @@ void end_qt(void)
if (audioTmpMovie) {
NSArray *audioTracks = [audioTmpMovie tracksOfMediaType:QTMediaTypeSound];
QTTrack *audioTrack = nil;
- if( [audioTracks count] > 0 )
- {
+ if ( [audioTracks count] > 0 ) {
audioTrack = [audioTracks objectAtIndex:0];
}
- if( audioTrack )
- {
+ if (audioTrack) {
QTTimeRange totalRange;
totalRange.time = QTZeroTime;
totalRange.duration = [[audioTmpMovie attributeForKey:QTMovieDurationAttribute] QTTimeValue];
@@ -798,7 +796,7 @@ void end_qt(void)
[QTMovie exitQTKitOnThread];
- if(qtexport) {
+ if (qtexport) {
MEM_freeN(qtexport);
qtexport = NULL;
}
diff --git a/source/blender/quicktime/apple/qtkit_import.m b/source/blender/quicktime/apple/qtkit_import.m
index bee26c5348e..fbe4733c3b1 100644
--- a/source/blender/quicktime/apple/qtkit_import.m
+++ b/source/blender/quicktime/apple/qtkit_import.m
@@ -128,7 +128,7 @@ void free_anim_quicktime(struct anim *anim)
if (anim == NULL) return;
if (anim->qtime == NULL) return;
- if(anim->qtime->ibuf)
+ if (anim->qtime->ibuf)
IMB_freeImBuf(anim->qtime->ibuf);
[anim->qtime->media release];
@@ -136,7 +136,7 @@ void free_anim_quicktime(struct anim *anim)
[QTMovie exitQTKitOnThread];
- if(anim->qtime) MEM_freeN (anim->qtime);
+ if (anim->qtime) MEM_freeN (anim->qtime);
anim->qtime = NULL;
@@ -289,7 +289,7 @@ ImBuf *qtime_fetchibuf (struct anim *anim, int position)
}
if (frameImage == nil) {
- if(QTIME_DEBUG) printf ("Error reading frame from Quicktime");
+ if (QTIME_DEBUG) printf ("Error reading frame from Quicktime");
[pool drain];
return NULL;
}
@@ -312,7 +312,7 @@ int startquicktime(struct anim *anim)
anim->qtime = MEM_callocN(sizeof(QuicktimeMovie),"animqt");
if (anim->qtime == NULL) {
- if(QTIME_DEBUG) printf("Can't alloc qtime: %s\n", anim->name);
+ if (QTIME_DEBUG) printf("Can't alloc qtime: %s\n", anim->name);
return -1;
}
@@ -329,9 +329,9 @@ int startquicktime(struct anim *anim)
anim->qtime->movie = [QTMovie movieWithAttributes:attributes error:NULL];
if (!anim->qtime->movie) {
- if(QTIME_DEBUG) printf("qt: bad movie %s\n", anim->name);
+ if (QTIME_DEBUG) printf("qt: bad movie %s\n", anim->name);
MEM_freeN(anim->qtime);
- if(QTIME_DEBUG) printf("qt: can't load %s\n", anim->name);
+ if (QTIME_DEBUG) printf("qt: can't load %s\n", anim->name);
[QTMovie exitQTKitOnThread];
[pool drain];
return -1;
@@ -342,11 +342,11 @@ int startquicktime(struct anim *anim)
videoTracks = [anim->qtime->movie tracksOfMediaType:QTMediaTypeVideo];
- if([videoTracks count] == 0) {
- if(QTIME_DEBUG) printf("qt: no video tracks for movie %s\n", anim->name);
+ if ([videoTracks count] == 0) {
+ if (QTIME_DEBUG) printf("qt: no video tracks for movie %s\n", anim->name);
[anim->qtime->movie release];
MEM_freeN(anim->qtime);
- if(QTIME_DEBUG) printf("qt: can't load %s\n", anim->name);
+ if (QTIME_DEBUG) printf("qt: can't load %s\n", anim->name);
[QTMovie exitQTKitOnThread];
[pool drain];
return -1;
@@ -360,8 +360,8 @@ int startquicktime(struct anim *anim)
anim->x = frameSize.width;
anim->y = frameSize.height;
- if(anim->x == 0 && anim->y == 0) {
- if(QTIME_DEBUG) printf("qt: error, no dimensions\n");
+ if (anim->x == 0 && anim->y == 0) {
+ if (QTIME_DEBUG) printf("qt: error, no dimensions\n");
free_anim_quicktime(anim);
[pool drain];
return -1;
@@ -398,12 +398,12 @@ int imb_is_a_quicktime(char *name)
int result;
NSAutoreleasePool *pool;
- if(!G.have_quicktime) return 0;
+ if (!G.have_quicktime) return 0;
pool = [[NSAutoreleasePool alloc] init];
// don't let quicktime image import handle these
- if( BLI_testextensie(name, ".swf") ||
+ if (BLI_testextensie(name, ".swf") ||
BLI_testextensie(name, ".txt") ||
BLI_testextensie(name, ".mpg") ||
BLI_testextensie(name, ".wav") ||
@@ -437,7 +437,7 @@ ImBuf *imb_quicktime_decode(unsigned char *mem, int size, int flags)
NSBitmapImageRep *blBitmapFormatImageRGB,*blBitmapFormatImageRGBA;
NSAutoreleasePool *pool;
- if(!G.have_quicktime)
+ if (!G.have_quicktime)
return NULL;
pool = [[NSAutoreleasePool alloc] init];
diff --git a/source/blender/render/extern/include/RE_multires_bake.h b/source/blender/render/extern/include/RE_multires_bake.h
index 04cfe55e3a3..c1c5fc4a04d 100644
--- a/source/blender/render/extern/include/RE_multires_bake.h
+++ b/source/blender/render/extern/include/RE_multires_bake.h
@@ -37,21 +37,26 @@ struct MultiresBakeRender;
typedef struct MultiresBakeRender {
DerivedMesh *lores_dm, *hires_dm;
- int simple, lvl, tot_lvl, bake_filter;
- short mode, use_lores_mesh;
+ bool simple;
+ int bake_filter; /* Bake-filter, aka margin */
+ int lvl, tot_lvl;
+ short mode;
+ bool use_lores_mesh; /* Use low-resolution mesh when baking displacement maps */
- int number_of_rays;
- float bias;
+ int number_of_rays; /* Number of rays to be cast when doing AO baking */
+ float bias; /* Bias between object and start ray point when doing AO baking */
int tot_obj, tot_image;
ListBase image;
int baked_objects, baked_faces;
- int raytrace_structure;
- int octree_resolution;
- int threads;
-
+ int raytrace_structure; /* Optimization structure to be used for AO baking */
+ int octree_resolution; /* Reslution of octotree when using octotree optimization structure */
+ int threads; /* Number of threads to be used for baking */
+
+ float user_scale; /* User scale used to scale displacement when baking derivative map. */
+
short *stop;
short *do_update;
float *progress;
diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h
index 73a89ad884f..79826a63690 100644
--- a/source/blender/render/extern/include/RE_pipeline.h
+++ b/source/blender/render/extern/include/RE_pipeline.h
@@ -249,7 +249,7 @@ void RE_MergeFullSample(struct Render *re, struct Main *bmain, struct Scene *sce
/* ancient stars function... go away! */
void RE_make_stars(struct Render *re, struct Scene *scenev3d, void (*initfunc)(void),
- void (*vertexfunc)(float *), void (*termfunc)(void));
+ void (*vertexfunc)(const float *), void (*termfunc)(void));
/* display and event callbacks */
void RE_display_init_cb (struct Render *re, void *handle, void (*f)(void *handle, RenderResult *rr));
@@ -281,6 +281,8 @@ int RE_seq_render_active(struct Scene *scene, struct RenderData *rd);
#define RE_BAKE_MIRROR_INTENSITY 10
#define RE_BAKE_ALPHA 11
#define RE_BAKE_EMIT 12
+#define RE_BAKE_DERIVATIVE 13
+#define RE_BAKE_VERTEX_COLORS 14
void RE_Database_Baking(struct Render *re, struct Main *bmain, struct Scene *scene, unsigned int lay, const int type, struct Object *actob);
diff --git a/source/blender/render/extern/include/RE_shader_ext.h b/source/blender/render/extern/include/RE_shader_ext.h
index 19ddfb7a13d..baec1a74721 100644
--- a/source/blender/render/extern/include/RE_shader_ext.h
+++ b/source/blender/render/extern/include/RE_shader_ext.h
@@ -213,6 +213,9 @@ int RE_bake_shade_all_selected(struct Render *re, int type, struct Object *actob
struct Image *RE_bake_shade_get_image(void);
void RE_bake_ibuf_filter(struct ImBuf *ibuf, char *mask, const int filter);
void RE_bake_ibuf_normalize_displacement(struct ImBuf *ibuf, float *displacement, char *mask, float displacement_min, float displacement_max);
+float RE_bake_make_derivative(struct ImBuf *ibuf, float *heights_buffer, const char *mask,
+ const float height_min, const float height_max,
+ const float fmult);
#define BAKE_RESULT_OK 0
#define BAKE_RESULT_NO_OBJECTS 1
diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h
index 42dc9bcdfb2..3d97eda50d9 100644
--- a/source/blender/render/intern/include/render_types.h
+++ b/source/blender/render/intern/include/render_types.h
@@ -236,7 +236,6 @@ struct Render
struct Object *excludeob;
ListBase render_volumes_inside;
ListBase volumes;
- ListBase volume_precache_parts;
#ifdef WITH_FREESTYLE
struct Main freestyle_bmain;
@@ -621,6 +620,7 @@ typedef struct LampRen {
#define R_BAKE_TRACE 32
#define R_BAKING 64
#define R_ANIMATION 128
+#define R_NEED_VCOL 256
/* vlakren->flag (vlak = face in dutch) char!!! */
#define R_SMOOTH 1
diff --git a/source/blender/render/intern/include/texture.h b/source/blender/render/intern/include/texture.h
index 2dc12f39db7..b23d6b09524 100644
--- a/source/blender/render/intern/include/texture.h
+++ b/source/blender/render/intern/include/texture.h
@@ -35,17 +35,17 @@
#define BRICONT \
texres->tin= (texres->tin-0.5f) * tex->contrast+tex->bright-0.5f; \
- if(texres->tin < 0.0f) texres->tin= 0.0f; \
- else if(texres->tin > 1.0f) texres->tin= 1.0f; \
+ if (texres->tin < 0.0f) texres->tin= 0.0f; \
+ else if (texres->tin > 1.0f) texres->tin= 1.0f; \
#define BRICONTRGB \
texres->tr= tex->rfac*((texres->tr-0.5f)*tex->contrast+tex->bright-0.5f); \
- if(texres->tr<0.0f) texres->tr= 0.0f; \
+ if (texres->tr<0.0f) texres->tr= 0.0f; \
texres->tg= tex->gfac*((texres->tg-0.5f)*tex->contrast+tex->bright-0.5f); \
- if(texres->tg<0.0f) texres->tg= 0.0f; \
+ if (texres->tg<0.0f) texres->tg= 0.0f; \
texres->tb= tex->bfac*((texres->tb-0.5f)*tex->contrast+tex->bright-0.5f); \
- if(texres->tb<0.0f) texres->tb= 0.0f; \
- if(tex->saturation != 1.0f) { \
+ if (texres->tb<0.0f) texres->tb= 0.0f; \
+ if (tex->saturation != 1.0f) { \
float _hsv[3]; \
rgb_to_hsv(texres->tr, texres->tg, texres->tb, \
_hsv, _hsv+1, _hsv+2); \
diff --git a/source/blender/render/intern/source/bake.c b/source/blender/render/intern/source/bake.c
index 564cca09834..72e47f89bb2 100644
--- a/source/blender/render/intern/source/bake.c
+++ b/source/blender/render/intern/source/bake.c
@@ -168,7 +168,7 @@ static void bake_shade(void *handle, Object *ob, ShadeInput *shi, int UNUSED(qua
else {
if (bs->type == RE_BAKE_SHADOW) /* Why do shadows set the color anyhow?, ignore material color for baking */
shi->r = shi->g = shi->b = 1.0f;
-
+
shade_input_set_shade_texco(shi);
/* only do AO for a full bake (and obviously AO bakes)
@@ -260,12 +260,16 @@ static void bake_shade(void *handle, Object *ob, ShadeInput *shi, int UNUSED(qua
copy_v3_fl(shr.combined, shi->emit);
shr.alpha = 1.0f;
}
+ else if (bs->type == RE_BAKE_VERTEX_COLORS) {
+ copy_v3_v3(shr.combined, shi->vcol);
+ shr.alpha = shi->vcol[3];
+ }
}
if (bs->rect_float && !bs->vcol) {
float *col = bs->rect_float + 4 * (bs->rectx * y + x);
copy_v3_v3(col, shr.combined);
- if (bs->type == RE_BAKE_ALL || bs->type == RE_BAKE_TEXTURE) {
+ if (bs->type == RE_BAKE_ALL || bs->type == RE_BAKE_TEXTURE || bs->type == RE_BAKE_VERTEX_COLORS) {
col[3] = shr.alpha;
}
else {
@@ -294,7 +298,7 @@ static void bake_shade(void *handle, Object *ob, ShadeInput *shi, int UNUSED(qua
rgb_float_to_uchar(col, shr.combined);
}
- if (ELEM(bs->type, RE_BAKE_ALL, RE_BAKE_TEXTURE)) {
+ if (ELEM3(bs->type, RE_BAKE_ALL, RE_BAKE_TEXTURE, RE_BAKE_VERTEX_COLORS)) {
col[3] = FTOCHAR(shr.alpha);
}
else {
@@ -553,7 +557,7 @@ static void do_bake_shade(void *handle, int x, int y, float u, float v)
}
}
- if (bs->type == RE_BAKE_DISPLACEMENT) {
+ if (ELEM(bs->type, RE_BAKE_DISPLACEMENT, RE_BAKE_DERIVATIVE)) {
if (hit)
bake_displacement(handle, shi, (dir == -1) ? mindist : -mindist, x, y);
else
@@ -647,6 +651,8 @@ static int get_next_bake_face(BakeShade *bs)
const float vec_solid[4] = {0.0f, 0.0f, 0.0f, 1.0f};
const float nor_alpha[4] = {0.5f, 0.5f, 1.0f, 0.0f};
const float nor_solid[4] = {0.5f, 0.5f, 1.0f, 1.0f};
+ const float disp_alpha[4] = {0.5f, 0.5f, 0.5f, 0.0f};
+ const float disp_solid[4] = {0.5f, 0.5f, 0.5f, 1.0f};
tface = RE_vlakren_get_tface(obr, vlr, obr->bakemtface, NULL, 0);
@@ -686,6 +692,8 @@ static int get_next_bake_face(BakeShade *bs)
if (R.r.bake_flag & R_BAKE_CLEAR) {
if (R.r.bake_mode == RE_BAKE_NORMALS && R.r.bake_normal_space == R_BAKE_SPACE_TANGENT)
IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? nor_alpha : nor_solid);
+ else if (ELEM(R.r.bake_mode, RE_BAKE_DISPLACEMENT, RE_BAKE_DERIVATIVE))
+ IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? disp_alpha : disp_solid);
else
IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? vec_alpha : vec_solid);
}
@@ -828,8 +836,11 @@ static void shade_tface(BakeShade *bs)
}
}
- if (bs->use_displacement_buffer)
- userdata->displacement_buffer = MEM_callocN(sizeof(float) * bs->rectx * bs->recty, "BakeDisp");
+ if (bs->use_displacement_buffer) {
+ if (userdata->displacement_buffer == NULL) {
+ userdata->displacement_buffer = MEM_callocN(sizeof(float) * bs->rectx * bs->recty, "BakeDisp");
+ }
+ }
bs->ibuf->userdata = userdata;
@@ -977,8 +988,10 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_up
use_mask = true;
/* do we need buffer to store displacements */
- if (type == RE_BAKE_DISPLACEMENT) {
- if ((R.r.bake_flag & R_BAKE_NORMALIZE) && R.r.bake_maxdist == 0.0f) {
+ if (ELEM(type, RE_BAKE_DISPLACEMENT, RE_BAKE_DERIVATIVE)) {
+ if (((R.r.bake_flag & R_BAKE_NORMALIZE) && R.r.bake_maxdist == 0.0f) ||
+ (type == RE_BAKE_DERIVATIVE))
+ {
use_displacement_buffer = true;
use_mask = true;
}
@@ -1081,12 +1094,19 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_up
userdata = (BakeImBufuserData *)ibuf->userdata;
if (userdata) {
- RE_bake_ibuf_filter(ibuf, userdata->mask_buffer, re->r.bake_filter);
-
if (use_displacement_buffer) {
- RE_bake_ibuf_normalize_displacement(ibuf, userdata->displacement_buffer, userdata->mask_buffer,
- displacement_min, displacement_max);
+ if (type == RE_BAKE_DERIVATIVE) {
+ float user_scale = (R.r.bake_flag & R_BAKE_USERSCALE) ? R.r.bake_user_scale : -1.0f;
+ RE_bake_make_derivative(ibuf, userdata->displacement_buffer, userdata->mask_buffer,
+ displacement_min, displacement_max, user_scale);
+ }
+ else {
+ RE_bake_ibuf_normalize_displacement(ibuf, userdata->displacement_buffer, userdata->mask_buffer,
+ displacement_min, displacement_max);
+ }
}
+
+ RE_bake_ibuf_filter(ibuf, userdata->mask_buffer, re->r.bake_filter);
}
ibuf->userflags |= IB_BITMAPDIRTY;
@@ -1117,3 +1137,176 @@ struct Image *RE_bake_shade_get_image(void)
return R.bakebuf;
}
+/* **************** Derivative Maps Baker **************** */
+
+static void add_single_heights_margin(const ImBuf *ibuf, const char *mask, float *heights_buffer)
+{
+ int x ,y;
+
+ for (y = 0; y < ibuf->y; y++) {
+ for (x = 0; x < ibuf->x; x++) {
+ int index = ibuf->x * y + x;
+
+ /* If unassigned pixel, look for neighbors. */
+ if (mask[index] != FILTER_MASK_USED) {
+ float height_acc = 0;
+ int denom = 0;
+ int i, j;
+
+ for (j = -1; j <= 1; j++)
+ for (i = -1; i <= 1; i++) {
+ int w = (i == 0 ? 1 : 0) + (j == 0 ? 1 : 0) + 1;
+
+ if (i != 0 || j != 0) {
+ int index2 = 0;
+ int x0 = x + i;
+ int y0 = y + j;
+
+ CLAMP(x0, 0, ibuf->x - 1);
+ CLAMP(y0, 0, ibuf->y - 1);
+
+ index2 = ibuf->x * y0 + x0;
+
+ if (mask[index2] == FILTER_MASK_USED) {
+ height_acc += w * heights_buffer[index2];
+ denom += w;
+ }
+ }
+ }
+
+ /* Insert final value. */
+ if (denom > 0) {
+ heights_buffer[index] = height_acc / denom;
+ }
+ }
+ }
+ }
+}
+
+/* returns user-scale */
+float RE_bake_make_derivative(ImBuf *ibuf, float *heights_buffer, const char *mask,
+ const float height_min, const float height_max,
+ const float fmult)
+{
+ const float delta_height = height_max - height_min;
+ const float denom = delta_height > 0.0f ? (8 * delta_height) : 1.0f;
+ bool auto_range_fit = fmult <= 0.0f;
+ float max_num_deriv = -1.0f;
+ int x, y, index;
+
+ /* Need a single margin to calculate good derivatives. */
+ add_single_heights_margin(ibuf, mask, heights_buffer);
+
+ if (auto_range_fit) {
+ /* If automatic range fitting is enabled. */
+ for (y = 0; y < ibuf->y; y++) {
+ const int Yu = y == (ibuf->y - 1) ? (ibuf->y - 1) : (y+1);
+ const int Yc = y;
+ const int Yd = y == 0 ? 0 : (y - 1);
+
+ for (x= 0; x < ibuf->x; x++) {
+ const int Xl = x == 0 ? 0 : (x - 1);
+ const int Xc = x;
+ const int Xr = x == (ibuf->x - 1) ? (ibuf->x - 1) : (x + 1);
+
+ const float Hcy = heights_buffer[Yc * ibuf->x + Xr] - heights_buffer[Yc * ibuf->x + Xl];
+ const float Hu = heights_buffer[Yu * ibuf->x + Xr] - heights_buffer[Yu * ibuf->x + Xl];
+ const float Hd = heights_buffer[Yd * ibuf->x + Xr] - heights_buffer[Yd * ibuf->x + Xl];
+
+ const float Hl = heights_buffer[Yu * ibuf->x + Xl] - heights_buffer[Yd * ibuf->x + Xl];
+ const float Hcx = heights_buffer[Yu * ibuf->x + Xc] - heights_buffer[Yd * ibuf->x + Xc];
+ const float Hr = heights_buffer[Yu * ibuf->x + Xr] - heights_buffer[Yd * ibuf->x + Xr];
+
+ /* This corresponds to using the sobel kernel on the heights buffer
+ * to obtain the derivative multiplied by 8.
+ */
+ const float deriv_x = Hu + 2 * Hcy + Hd;
+ const float deriv_y = Hr + 2 * Hcx + Hl;
+
+ /* early out */
+ index = ibuf->x * y + x;
+ if (mask[index] != FILTER_MASK_USED) {
+ continue;
+ }
+
+ /* Widen bound. */
+ if (fabsf(deriv_x) > max_num_deriv) {
+ max_num_deriv = fabsf(deriv_x);
+ }
+
+ if (fabsf(deriv_y) > max_num_deriv) {
+ max_num_deriv = fabsf(deriv_y);
+ }
+ }
+ }
+ }
+
+ /* Output derivatives. */
+ auto_range_fit &= (max_num_deriv > 0);
+ for (y = 0; y < ibuf->y; y++) {
+ const int Yu= y==(ibuf->y-1) ? (ibuf->y-1) : (y+1);
+ const int Yc= y;
+ const int Yd= y==0 ? 0 : (y-1);
+
+ for(x= 0; x<ibuf->x; x++) {
+ const int Xl = x == 0 ? 0 : (x - 1);
+ const int Xc = x;
+ const int Xr = x == (ibuf->x - 1) ? (ibuf->x - 1) : (x + 1);
+
+ const float Hcy = heights_buffer[Yc * ibuf->x + Xr] - heights_buffer[Yc * ibuf->x + Xl];
+ const float Hu = heights_buffer[Yu * ibuf->x + Xr] - heights_buffer[Yu * ibuf->x + Xl];
+ const float Hd = heights_buffer[Yd * ibuf->x + Xr] - heights_buffer[Yd * ibuf->x + Xl];
+
+ const float Hl = heights_buffer[Yu * ibuf->x + Xl] - heights_buffer[Yd * ibuf->x + Xl];
+ const float Hcx = heights_buffer[Yu * ibuf->x + Xc] - heights_buffer[Yd * ibuf->x + Xc];
+ const float Hr = heights_buffer[Yu * ibuf->x + Xr] - heights_buffer[Yd * ibuf->x + Xr];
+
+ /* This corresponds to using the sobel kernel on the heights buffer
+ * to obtain the derivative multiplied by 8.
+ */
+ float deriv_x = Hu + 2 * Hcy + Hd;
+ float deriv_y = Hr + 2 * Hcx + Hl;
+
+ /* Early out. */
+ index = ibuf->x * y + x;
+ if (mask[index] != FILTER_MASK_USED){
+ continue;
+ }
+
+ if (auto_range_fit) {
+ deriv_x /= max_num_deriv;
+ deriv_y /= max_num_deriv;
+ } else {
+ deriv_x *= (fmult / denom);
+ deriv_y *= (fmult / denom);
+ }
+
+ deriv_x = deriv_x * 0.5f + 0.5f;
+ deriv_y = deriv_y * 0.5f + 0.5f;
+
+ /* Clamp. */
+ CLAMP(deriv_x, 0.0f, 1.0f);
+ CLAMP(deriv_y, 0.0f, 1.0f);
+
+ /* Write out derivatives. */
+ if (ibuf->rect_float) {
+ float *rrgbf = ibuf->rect_float + index * 4;
+
+ rrgbf[0] = deriv_x;
+ rrgbf[1] = deriv_y;
+ rrgbf[2] = 0.0f;
+ rrgbf[3] = 1.0f;
+ } else {
+ char *rrgb = (char*)ibuf->rect + index * 4;
+
+ rrgb[0] = FTOCHAR(deriv_x);
+ rrgb[1] = FTOCHAR(deriv_y);
+ rrgb[2] = 0;
+ rrgb[3] = 255;
+ }
+ }
+ }
+
+ /* Eeturn user-scale (for rendering). */
+ return auto_range_fit ? (max_num_deriv / denom) : (fmult > 0.0f ? (1.0f / fmult) : 0.0f);
+}
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index a0104a30d0e..18f658fb169 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -167,7 +167,7 @@ static HaloRen *initstar(Render *re, ObjectRen *obr, const float vec[3], float h
*/
void RE_make_stars(Render *re, Scene *scenev3d, void (*initfunc)(void),
- void (*vertexfunc)(float *), void (*termfunc)(void))
+ void (*vertexfunc)(const float *), void (*termfunc)(void))
{
extern unsigned char hash[512];
ObjectRen *obr= NULL;
@@ -5982,7 +5982,9 @@ void RE_Database_FromScene_Vectors(Render *re, Main *bmain, Scene *sce, unsigned
* RE_BAKE_NORMALS:for baking, no lamps and only selected objects
* RE_BAKE_AO: for baking, no lamps, but all objects
* RE_BAKE_TEXTURE:for baking, no lamps, only selected objects
+ * RE_BAKE_VERTEX_COLORS:for baking, no lamps, only selected objects
* RE_BAKE_DISPLACEMENT:for baking, no lamps, only selected objects
+ * RE_BAKE_DERIVATIVE:for baking, no lamps, only selected objects
* RE_BAKE_SHADOW: for baking, only shadows, but all objects
*/
void RE_Database_Baking(Render *re, Main *bmain, Scene *scene, unsigned int lay, const int type, Object *actob)
@@ -5990,8 +5992,8 @@ void RE_Database_Baking(Render *re, Main *bmain, Scene *scene, unsigned int lay,
Object *camera;
float mat[4][4];
float amb[3];
- const short onlyselected= !ELEM4(type, RE_BAKE_LIGHT, RE_BAKE_ALL, RE_BAKE_SHADOW, RE_BAKE_AO);
- const short nolamps= ELEM3(type, RE_BAKE_NORMALS, RE_BAKE_TEXTURE, RE_BAKE_DISPLACEMENT);
+ const short onlyselected= !ELEM5(type, RE_BAKE_LIGHT, RE_BAKE_ALL, RE_BAKE_SHADOW, RE_BAKE_AO, RE_BAKE_VERTEX_COLORS);
+ const short nolamps= ELEM5(type, RE_BAKE_NORMALS, RE_BAKE_TEXTURE, RE_BAKE_DISPLACEMENT, RE_BAKE_DERIVATIVE, RE_BAKE_VERTEX_COLORS);
re->main= bmain;
re->scene= scene;
@@ -6009,8 +6011,11 @@ void RE_Database_Baking(Render *re, Main *bmain, Scene *scene, unsigned int lay,
if (type==RE_BAKE_NORMALS && re->r.bake_normal_space==R_BAKE_SPACE_TANGENT)
re->flag |= R_NEED_TANGENT;
-
- if (!actob && ELEM4(type, RE_BAKE_LIGHT, RE_BAKE_NORMALS, RE_BAKE_TEXTURE, RE_BAKE_DISPLACEMENT)) {
+
+ if (type==RE_BAKE_VERTEX_COLORS)
+ re->flag |= R_NEED_VCOL;
+
+ if (!actob && ELEM6(type, RE_BAKE_LIGHT, RE_BAKE_NORMALS, RE_BAKE_TEXTURE, RE_BAKE_DISPLACEMENT, RE_BAKE_DERIVATIVE, RE_BAKE_VERTEX_COLORS)) {
re->r.mode &= ~R_SHADOW;
re->r.mode &= ~R_RAYTRACE;
}
diff --git a/source/blender/render/intern/source/imagetexture.c b/source/blender/render/intern/source/imagetexture.c
index c5e4f97c6bc..bfc13bf6151 100644
--- a/source/blender/render/intern/source/imagetexture.c
+++ b/source/blender/render/intern/source/imagetexture.c
@@ -799,7 +799,7 @@ static void area_sample(TexResult *texr, ImBuf *ibuf, float fx, float fy, afdata
/* table of (exp(ar) - exp(a)) / (1 - exp(a)) for r in range [0, 1] and a = -2
* used instead of actual gaussian, otherwise at high texture magnifications circular artifacts are visible */
#define EWA_MAXIDX 255
-static float EWA_WTS[EWA_MAXIDX + 1] = {
+static const float EWA_WTS[EWA_MAXIDX + 1] = {
1.f, 0.990965f, 0.982f, 0.973105f, 0.96428f, 0.955524f, 0.946836f, 0.938216f, 0.929664f,
0.921178f, 0.912759f, 0.904405f, 0.896117f, 0.887893f, 0.879734f, 0.871638f, 0.863605f,
0.855636f, 0.847728f, 0.839883f, 0.832098f, 0.824375f, 0.816712f, 0.809108f, 0.801564f,
diff --git a/source/blender/render/intern/source/multires_bake.c b/source/blender/render/intern/source/multires_bake.c
index a2fa37fd7ea..3259608c18f 100644
--- a/source/blender/render/intern/source/multires_bake.c
+++ b/source/blender/render/intern/source/multires_bake.c
@@ -124,7 +124,7 @@ typedef struct {
const int *orig_index_mp_to_orig;
} MAOBakeData;
-static void multiresbake_get_normal(const MResolvePixelData *data, float norm[], const int face_num, const int vert_index)
+static void multiresbake_get_normal(const MResolvePixelData *data, float norm[],const int face_num, const int vert_index)
{
unsigned int indices[] = {data->mface[face_num].v1, data->mface[face_num].v2,
data->mface[face_num].v3, data->mface[face_num].v4};
@@ -1231,6 +1231,7 @@ static void bake_images(MultiresBakeRender *bkr, MultiresBakeResult *result)
do_multires_bake(bkr, ima, TRUE, apply_tangmat_callback, init_normal_data, free_normal_data, result);
break;
case RE_BAKE_DISPLACEMENT:
+ case RE_BAKE_DERIVATIVE:
do_multires_bake(bkr, ima, FALSE, apply_heights_callback, init_heights_data, free_heights_data, result);
break;
case RE_BAKE_AO:
@@ -1248,7 +1249,7 @@ static void bake_images(MultiresBakeRender *bkr, MultiresBakeResult *result)
static void finish_images(MultiresBakeRender *bkr, MultiresBakeResult *result)
{
LinkData *link;
- int use_displacement_buffer = bkr->mode == RE_BAKE_DISPLACEMENT;
+ bool use_displacement_buffer = ELEM(bkr->mode, RE_BAKE_DISPLACEMENT, RE_BAKE_DERIVATIVE);
for (link = bkr->image.first; link; link = link->next) {
Image *ima = (Image *)link->data;
@@ -1259,8 +1260,14 @@ static void finish_images(MultiresBakeRender *bkr, MultiresBakeResult *result)
continue;
if (use_displacement_buffer) {
- RE_bake_ibuf_normalize_displacement(ibuf, userdata->displacement_buffer, userdata->mask_buffer,
- result->height_min, result->height_max);
+ if (bkr->mode == RE_BAKE_DERIVATIVE) {
+ RE_bake_make_derivative(ibuf, userdata->displacement_buffer, userdata->mask_buffer,
+ result->height_min, result->height_max, bkr->user_scale);
+ }
+ else {
+ RE_bake_ibuf_normalize_displacement(ibuf, userdata->displacement_buffer, userdata->mask_buffer,
+ result->height_min, result->height_max);
+ }
}
RE_bake_ibuf_filter(ibuf, userdata->mask_buffer, bkr->bake_filter);
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index 6118d479cab..fa05f8dd18d 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -1309,6 +1309,10 @@ static void do_render_blur_3d(Render *re)
re->mblur_offs = 0.0f;
re->i.curblur = 0; /* stats */
+ /* make sure motion blur changes get reset to current frame */
+ if ((re->r.scemode & (R_NO_FRAME_UPDATE|R_BUTS_PREVIEW|R_VIEWPORT_PREVIEW))==0)
+ BKE_scene_update_for_newframe(re->main, re->scene, re->lay);
+
/* weak... the display callback wants an active renderlayer pointer... */
re->result->renlay = render_get_active_layer(re, re->result);
re->display_draw(re->ddh, re->result, NULL);
diff --git a/source/blender/render/intern/source/pixelshading.c b/source/blender/render/intern/source/pixelshading.c
index 8a023a2c009..43e052a6efc 100644
--- a/source/blender/render/intern/source/pixelshading.c
+++ b/source/blender/render/intern/source/pixelshading.c
@@ -73,7 +73,7 @@ extern struct Render R;
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
-extern float hashvectf[];
+extern const float hashvectf[];
static void render_lighting_halo(HaloRen *har, float col_r[3])
{
@@ -341,7 +341,8 @@ int shadeHaloFloat(HaloRen *har, float col[4], int zz,
if (flarec) har->pixels+= (int)(har->rad-radist);
if (har->ringc) {
- float *rc, fac;
+ const float *rc;
+ float fac;
int ofs;
/* per ring an antialised circle */
@@ -393,7 +394,8 @@ int shadeHaloFloat(HaloRen *har, float col[4], int zz,
dist= 0.0f;
if (har->linec) {
- float *rc, fac;
+ const float *rc;
+ float fac;
int ofs;
/* per starpoint an antialiased line */
diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c
index 768fd2cdcf5..90ae39ee767 100644
--- a/source/blender/render/intern/source/rayshade.c
+++ b/source/blender/render/intern/source/rayshade.c
@@ -739,7 +739,7 @@ static void traceray(ShadeInput *origshi, ShadeResult *origshr, short depth, con
* in two each time, giving 2^depth rays. we need to be able to cancel such
* a render to avoid hanging, a better solution would be random picking
* between directions and russian roulette termination */
- if(R.test_break(R.tbh)) {
+ if (R.test_break(R.tbh)) {
zero_v4(col);
return;
}
diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c
index 982e9b1a410..89d8345a0d7 100644
--- a/source/blender/render/intern/source/rendercore.c
+++ b/source/blender/render/intern/source/rendercore.c
@@ -1875,10 +1875,11 @@ static void renderhalo_post(RenderResult *rr, float *rectf, HaloRen *har) /* pos
static void renderflare(RenderResult *rr, float *rectf, HaloRen *har)
{
- extern float hashvectf[];
+ extern const float hashvectf[];
HaloRen fla;
Material *ma;
- float *rc, rad, alfa, visifac, vec[3];
+ const float *rc;
+ float rad, alfa, visifac, vec[3];
int b, type;
fla= *har;
diff --git a/source/blender/render/intern/source/shadbuf.c b/source/blender/render/intern/source/shadbuf.c
index 0d85cfe78b7..0c3bf85cd24 100644
--- a/source/blender/render/intern/source/shadbuf.c
+++ b/source/blender/render/intern/source/shadbuf.c
@@ -1373,7 +1373,7 @@ float shadow_halo(LampRen *lar, const float p1[3], const float p2[3])
/* printf("start %x %x \n", (int)(0x7FFFFFFF*zf1), (int)(0x7FFFFFFF*zf2)); */
- while (1) {
+ do {
lambda_o= lambda;
if (lambda_x==lambda_y) {
@@ -1394,7 +1394,13 @@ float shadow_halo(LampRen *lar, const float p1[3], const float p2[3])
}
lambda = min_ff(lambda_x, lambda_y);
-
+
+ /* not making any progress? */
+ if (lambda==lambda_o) break;
+
+ /* clip to end of volume */
+ lambda = min_ff(lambda, 1.0f);
+
zf= zf1 + lambda*(zf2-zf1);
count+= (float)shb->totbuf;
@@ -1409,10 +1415,9 @@ float shadow_halo(LampRen *lar, const float p1[3], const float p2[3])
lightcount+= readshadowbuf_halo(shb, shsample, x, y, z);
}
- /* break after sample, so it takes at least one */
- if (lambda==lambda_o || lambda>=1.0f) break;
}
-
+ while (lambda < 1.0f);
+
if (count!=0.0f) return (lightcount/count);
return 0.0f;
diff --git a/source/blender/render/intern/source/shadeinput.c b/source/blender/render/intern/source/shadeinput.c
index 2dcb55f1f5d..bc9ba348c62 100644
--- a/source/blender/render/intern/source/shadeinput.c
+++ b/source/blender/render/intern/source/shadeinput.c
@@ -1002,7 +1002,7 @@ void shade_input_set_shade_texco(ShadeInput *shi)
}
/* pass option forces UV calc */
- if (shi->passflag & SCE_PASS_UV)
+ if ((shi->passflag & SCE_PASS_UV) || (R.flag & R_NEED_VCOL))
texco |= (NEED_UV | TEXCO_UV);
/* texture coordinates. shi->dxuv shi->dyuv have been set */
@@ -1056,7 +1056,7 @@ void shade_input_set_shade_texco(ShadeInput *shi)
}
}
- if ((texco & TEXCO_UV) || (mode & (MA_VERTEXCOL | MA_VERTEXCOLP | MA_FACETEXTURE))) {
+ if ((texco & TEXCO_UV) || (mode & (MA_VERTEXCOL | MA_VERTEXCOLP | MA_FACETEXTURE)) || (R.flag & R_NEED_VCOL)) {
VlakRen *vlr = shi->vlr;
MTFace *tface;
MCol *mcol;
@@ -1071,7 +1071,7 @@ void shade_input_set_shade_texco(ShadeInput *shi)
shi->actuv = obr->actmtface;
shi->actcol = obr->actmcol;
- if (mode & (MA_VERTEXCOL | MA_VERTEXCOLP)) {
+ if ((mode & (MA_VERTEXCOL | MA_VERTEXCOLP)) || (R.flag & R_NEED_VCOL)) {
for (i = 0; (mcol = RE_vlakren_get_mcol(obr, vlr, i, &name, 0)); i++) {
ShadeInputCol *scol = &shi->col[i];
char *cp1, *cp2, *cp3;
@@ -1213,7 +1213,7 @@ void shade_input_set_shade_texco(ShadeInput *shi)
}
if ((mode & MA_FACETEXTURE) && i == obr->actmtface) {
- if ((mode & (MA_VERTEXCOL | MA_VERTEXCOLP)) == 0) {
+ if (((mode & (MA_VERTEXCOL | MA_VERTEXCOLP)) == 0) && ((R.flag & R_NEED_VCOL) == 0)) {
shi->vcol[0] = 1.0f;
shi->vcol[1] = 1.0f;
shi->vcol[2] = 1.0f;
@@ -1299,7 +1299,7 @@ void shade_input_set_shade_texco(ShadeInput *shi)
* else un-initialized values are used
*/
if (shi->do_manage) {
- if (mode & (MA_VERTEXCOL | MA_VERTEXCOLP | MA_FACETEXTURE)) {
+ if ((mode & (MA_VERTEXCOL | MA_VERTEXCOLP | MA_FACETEXTURE)) || (R.flag & R_NEED_VCOL)) {
srgb_to_linearrgb_v3_v3(shi->vcol, shi->vcol);
}
}
diff --git a/source/blender/render/intern/source/sss.c b/source/blender/render/intern/source/sss.c
index f86942f7918..732892ed357 100644
--- a/source/blender/render/intern/source/sss.c
+++ b/source/blender/render/intern/source/sss.c
@@ -309,7 +309,7 @@ ScatterSettings *scatter_settings_new(float refl, float radius, float ior, float
ss->Fdr= -1.440f/ior*ior + 0.710f/ior + 0.668f + 0.0636f*ior;
ss->A= (1.0f + ss->Fdr)/(1.0f - ss->Fdr);
ss->ld= radius;
- ss->ro= min_ff(refl, 0.999f);
+ ss->ro= min_ff(refl, 0.99f);
ss->color= ss->ro*reflfac + (1.0f-reflfac);
ss->alpha_= compute_reduced_albedo(ss);
diff --git a/source/blender/render/intern/source/volume_precache.c b/source/blender/render/intern/source/volume_precache.c
index 028217b8609..6912f998e7a 100644
--- a/source/blender/render/intern/source/volume_precache.c
+++ b/source/blender/render/intern/source/volume_precache.c
@@ -39,6 +39,7 @@
#include "BLI_blenlib.h"
#include "BLI_math.h"
+#include "BLI_task.h"
#include "BLI_threads.h"
#include "BLI_voxel.h"
#include "BLI_utildefines.h"
@@ -483,82 +484,96 @@ static void *vol_precache_part_test(void *data)
}
#endif
-typedef struct VolPrecacheQueue {
- ThreadQueue *work;
- ThreadQueue *done;
-} VolPrecacheQueue;
-
/* Iterate over the 3d voxel grid, and fill the voxels with scattering information
*
* It's stored in memory as 3 big float grids next to each other, one for each RGB channel.
* I'm guessing the memory alignment may work out better this way for the purposes
* of doing linear interpolation, but I haven't actually tested this theory! :)
*/
-static void *vol_precache_part(void *data)
+typedef struct VolPrecacheState {
+ double lasttime;
+ int totparts;
+} VolPrecacheState;
+
+static void vol_precache_part(TaskPool *pool, void *taskdata, int threadid)
{
- VolPrecacheQueue *queue = (VolPrecacheQueue *)data;
- VolPrecachePart *pa;
-
- while ((pa = BLI_thread_queue_pop(queue->work))) {
- ObjectInstanceRen *obi = pa->obi;
- RayObject *tree = pa->tree;
- ShadeInput *shi = pa->shi;
- float scatter_col[3] = {0.f, 0.f, 0.f};
- float co[3], cco[3], view[3];
- int x, y, z, i;
- int res[3];
-
- if (pa->re->test_break && pa->re->test_break(pa->re->tbh))
- break;
-
- res[0]= pa->res[0];
- res[1]= pa->res[1];
- res[2]= pa->res[2];
-
- for (z= pa->minz; z < pa->maxz; z++) {
- co[2] = pa->bbmin[2] + (pa->voxel[2] * (z + 0.5f));
+ VolPrecacheState *state = (VolPrecacheState *)BLI_task_pool_userdata(pool);
+ VolPrecachePart *pa = (VolPrecachePart *)taskdata;
+ Render *re = pa->re;
+
+ ObjectInstanceRen *obi = pa->obi;
+ RayObject *tree = pa->tree;
+ ShadeInput *shi = pa->shi;
+ float scatter_col[3] = {0.f, 0.f, 0.f};
+ float co[3], cco[3], view[3];
+ int x, y, z, i;
+ int res[3];
+ double time;
+
+ if (re->test_break && re->test_break(re->tbh))
+ return;
+
+ printf("thread id %d\n", threadid);
+
+ res[0]= pa->res[0];
+ res[1]= pa->res[1];
+ res[2]= pa->res[2];
+
+ for (z= pa->minz; z < pa->maxz; z++) {
+ co[2] = pa->bbmin[2] + (pa->voxel[2] * (z + 0.5f));
+
+ for (y= pa->miny; y < pa->maxy; y++) {
+ co[1] = pa->bbmin[1] + (pa->voxel[1] * (y + 0.5f));
- for (y= pa->miny; y < pa->maxy; y++) {
- co[1] = pa->bbmin[1] + (pa->voxel[1] * (y + 0.5f));
+ for (x=pa->minx; x < pa->maxx; x++) {
+ co[0] = pa->bbmin[0] + (pa->voxel[0] * (x + 0.5f));
- for (x=pa->minx; x < pa->maxx; x++) {
- co[0] = pa->bbmin[0] + (pa->voxel[0] * (x + 0.5f));
-
- if (pa->re->test_break && pa->re->test_break(pa->re->tbh))
- break;
-
- /* convert from world->camera space for shading */
- mul_v3_m4v3(cco, pa->viewmat, co);
+ if (re->test_break && re->test_break(re->tbh))
+ break;
+
+ /* convert from world->camera space for shading */
+ mul_v3_m4v3(cco, pa->viewmat, co);
- i = BLI_VOXEL_INDEX(x, y, z, res);
+ i = BLI_VOXEL_INDEX(x, y, z, res);
- /* don't bother if the point is not inside the volume mesh */
- if (!point_inside_obi(tree, obi, cco)) {
- obi->volume_precache->data_r[i] = -1.0f;
- obi->volume_precache->data_g[i] = -1.0f;
- obi->volume_precache->data_b[i] = -1.0f;
- continue;
- }
-
- copy_v3_v3(view, cco);
- normalize_v3(view);
- vol_get_scattering(shi, scatter_col, cco, view);
-
- obi->volume_precache->data_r[i] = scatter_col[0];
- obi->volume_precache->data_g[i] = scatter_col[1];
- obi->volume_precache->data_b[i] = scatter_col[2];
-
+ /* don't bother if the point is not inside the volume mesh */
+ if (!point_inside_obi(tree, obi, cco)) {
+ obi->volume_precache->data_r[i] = -1.0f;
+ obi->volume_precache->data_g[i] = -1.0f;
+ obi->volume_precache->data_b[i] = -1.0f;
+ continue;
}
+
+ copy_v3_v3(view, cco);
+ normalize_v3(view);
+ vol_get_scattering(shi, scatter_col, cco, view);
+
+ obi->volume_precache->data_r[i] = scatter_col[0];
+ obi->volume_precache->data_g[i] = scatter_col[1];
+ obi->volume_precache->data_b[i] = scatter_col[2];
+
}
}
+ }
+
+ time = PIL_check_seconds_timer();
+ if (time - state->lasttime > 1.0) {
+ ThreadMutex *mutex = BLI_task_pool_user_mutex(pool);
- BLI_thread_queue_push(queue->done, pa);
+ if (BLI_mutex_trylock(mutex)) {
+ char str[64];
+ float ratio = (float)BLI_task_pool_tasks_done(pool)/(float)state->totparts;
+ BLI_snprintf(str, sizeof(str), IFACE_("Precaching volume: %d%%"), (int)(100.0f * ratio));
+ re->i.infostr = str;
+ re->stats_draw(re->sdh, &re->i);
+ re->i.infostr = NULL;
+ state->lasttime = time;
+
+ BLI_mutex_unlock(mutex);
+ }
}
-
- return NULL;
}
-
static void precache_setup_shadeinput(Render *re, ObjectInstanceRen *obi, Material *ma, ShadeInput *shi)
{
memset(shi, 0, sizeof(ShadeInput));
@@ -573,9 +588,12 @@ static void precache_setup_shadeinput(Render *re, ObjectInstanceRen *obi, Materi
shi->lay = re->lay;
}
-static void precache_init_parts(Render *re, RayObject *tree, ShadeInput *shi, ObjectInstanceRen *obi, int totthread, int *parts)
+static void precache_launch_parts(Render *re, RayObject *tree, ShadeInput *shi, ObjectInstanceRen *obi)
{
+ TaskScheduler *task_scheduler;
+ TaskPool *task_pool;
VolumePrecache *vp = obi->volume_precache;
+ VolPrecacheState state;
int i=0, x, y, z;
float voxel[3];
int sizex, sizey, sizez;
@@ -584,15 +602,23 @@ static void precache_init_parts(Render *re, RayObject *tree, ShadeInput *shi, Ob
int minx, maxx;
int miny, maxy;
int minz, maxz;
+ int totthread = re->r.threads;
+ int parts[3];
if (!vp) return;
- BLI_freelistN(&re->volume_precache_parts);
-
/* currently we just subdivide the box, number of threads per side */
parts[0] = parts[1] = parts[2] = totthread;
res = vp->res;
+ /* setup task scheduler */
+ memset(&state, 0, sizeof(state));
+ state.totparts = parts[0]*parts[1]*parts[2];
+ state.lasttime = PIL_check_seconds_timer();
+
+ task_scheduler = BLI_task_scheduler_create(totthread);
+ task_pool = BLI_task_pool_create(task_scheduler, &state);
+
/* using boundbox in worldspace */
global_bounds_obi(re, obi, bbmin, bbmax);
sub_v3_v3v3(voxel, bbmax, bbmin);
@@ -636,13 +662,19 @@ static void precache_init_parts(Render *re, RayObject *tree, ShadeInput *shi, Ob
pa->miny = miny; pa->maxy = maxy;
pa->minz = minz; pa->maxz = maxz;
-
- BLI_addtail(&re->volume_precache_parts, pa);
+ BLI_task_pool_push(task_pool, vol_precache_part, pa, true, TASK_PRIORITY_HIGH);
i++;
}
}
}
+
+ /* work and wait until tasks are done */
+ BLI_task_pool_work_and_wait(task_pool);
+
+ /* free */
+ BLI_task_pool_free(task_pool);
+ BLI_task_scheduler_free(task_scheduler);
}
/* calculate resolution from bounding box in world space */
@@ -678,17 +710,8 @@ static int precache_resolution(Render *re, VolumePrecache *vp, ObjectInstanceRen
static void vol_precache_objectinstance_threads(Render *re, ObjectInstanceRen *obi, Material *ma)
{
VolumePrecache *vp;
- VolPrecachePart *pa;
RayObject *tree;
ShadeInput shi;
- ListBase threads;
- VolPrecacheQueue queue;
- int parts[3] = {1, 1, 1}, totparts;
-
- int counter=0;
- int totthread = re->r.threads, thread;
-
- double time, lasttime= PIL_check_seconds_timer();
R = *re;
@@ -717,49 +740,8 @@ static void vol_precache_objectinstance_threads(Render *re, ObjectInstanceRen *o
/* Need a shadeinput to calculate scattering */
precache_setup_shadeinput(re, obi, ma, &shi);
- precache_init_parts(re, tree, &shi, obi, totthread, parts);
- totparts = parts[0] * parts[1] * parts[2];
-
- /* setup work and done queues */
- queue.work = BLI_thread_queue_init();
- queue.done = BLI_thread_queue_init();
- BLI_thread_queue_nowait(queue.work);
+ precache_launch_parts(re, tree, &shi, obi);
- for (pa= re->volume_precache_parts.first; pa; pa= pa->next)
- BLI_thread_queue_push(queue.work, pa);
-
- /* launch threads */
- BLI_init_threads(&threads, vol_precache_part, totthread);
-
- for (thread= 0; thread<totthread; thread++)
- BLI_insert_thread(&threads, &queue);
-
- /* loop waiting for work to be done */
- while (counter < totparts) {
- if (re->test_break && re->test_break(re->tbh))
- break;
-
- if (BLI_thread_queue_pop_timeout(queue.done, 50))
- counter++;
-
- time= PIL_check_seconds_timer();
- if (time-lasttime>1.0) {
- char str[64];
- BLI_snprintf(str, sizeof(str), IFACE_("Precaching volume: %d%%"),
- (int)(100.0f * ((float)counter / (float)totparts)));
- re->i.infostr = str;
- re->stats_draw(re->sdh, &re->i);
- re->i.infostr = NULL;
- lasttime = time;
- }
- }
-
- /* free */
- BLI_end_threads(&threads);
- BLI_thread_queue_free(queue.work);
- BLI_thread_queue_free(queue.done);
- BLI_freelistN(&re->volume_precache_parts);
-
if (tree) {
/* TODO: makeraytree_object creates a tree and saves it on OBI,
* if we free this tree we should also clear other pointers to it */
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index f9c18a3e0a2..c338d49fe17 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -198,6 +198,7 @@ bool WM_operator_filesel_ensure_ext_imtype(wmOperator *op, const struct I
/* poll callback, context checks */
int WM_operator_winactive (struct bContext *C);
/* invoke callback, exec + redo popup */
+int WM_operator_props_popup_confirm(struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
int WM_operator_props_popup_call(struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
int WM_operator_props_popup (struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
int WM_operator_props_dialog_popup(struct bContext *C, struct wmOperator *op, int width, int height);
@@ -393,7 +394,7 @@ void WM_jobs_stop(struct wmWindowManager *wm, void *owner, void *startjob);
void WM_jobs_kill(struct wmWindowManager *wm, void *owner, void (*)(void *, short int *, short int *, float *));
void WM_jobs_kill_all(struct wmWindowManager *wm);
void WM_jobs_kill_all_except(struct wmWindowManager *wm, void *owner);
-void WM_jobs_kill_type(struct wmWindowManager *wm, int job_type);
+void WM_jobs_kill_type(struct wmWindowManager *wm, void *owner, int job_type);
int WM_jobs_has_running(struct wmWindowManager *wm);
diff --git a/source/blender/windowmanager/WM_keymap.h b/source/blender/windowmanager/WM_keymap.h
index cebafcea12d..121e5e401fa 100644
--- a/source/blender/windowmanager/WM_keymap.h
+++ b/source/blender/windowmanager/WM_keymap.h
@@ -44,7 +44,7 @@ struct EnumPropertyItem;
wmKeyConfig *WM_keyconfig_new (struct wmWindowManager *wm, const char *idname);
wmKeyConfig *WM_keyconfig_new_user(struct wmWindowManager *wm, const char *idname);
-int WM_keyconfig_remove (struct wmWindowManager *wm, struct wmKeyConfig *keyconf);
+bool WM_keyconfig_remove (struct wmWindowManager *wm, struct wmKeyConfig *keyconf);
void WM_keyconfig_free (struct wmKeyConfig *keyconf);
void WM_keyconfig_set_active(struct wmWindowManager *wm, const char *idname);
@@ -64,7 +64,7 @@ wmKeyMapItem *WM_keymap_add_item(struct wmKeyMap *keymap, const char *idname, in
wmKeyMapItem *WM_keymap_add_menu(struct wmKeyMap *keymap, const char *idname, int type,
int val, int modifier, int keymodifier);
-int WM_keymap_remove_item(struct wmKeyMap *keymap, struct wmKeyMapItem *kmi);
+bool WM_keymap_remove_item(struct wmKeyMap *keymap, struct wmKeyMapItem *kmi);
int WM_keymap_item_to_string(wmKeyMapItem *kmi, char *str, const int len);
wmKeyMap *WM_keymap_list_find(ListBase *lb, const char *idname, int spaceid, int regionid);
@@ -72,6 +72,7 @@ wmKeyMap *WM_keymap_find(struct wmKeyConfig *keyconf, const char *idname, int sp
wmKeyMap *WM_keymap_find_all(const struct bContext *C, const char *idname, int spaceid, int regionid);
wmKeyMap *WM_keymap_active(struct wmWindowManager *wm, struct wmKeyMap *keymap);
wmKeyMap *WM_keymap_guess_opname(const struct bContext *C, const char *opname);
+bool WM_keymap_remove(struct wmKeyConfig *keyconfig, struct wmKeyMap *keymap);
wmKeyMapItem *WM_keymap_item_find_id(struct wmKeyMap *keymap, int id);
int WM_keymap_item_compare(struct wmKeyMapItem *k1, struct wmKeyMapItem *k2);
diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h
index 9a31dea68a2..b66cc11b51c 100644
--- a/source/blender/windowmanager/WM_types.h
+++ b/source/blender/windowmanager/WM_types.h
@@ -261,7 +261,6 @@ typedef struct wmNotifier {
#define ND_EDITOR_CHANGED (6<<16) /*sent to new editors after switching to them*/
#define ND_SCREENSET (7<<16)
#define ND_SKETCH (8<<16)
-#define ND_SUBWINACTIVE (9<<16)
/* NC_SCENE Scene */
#define ND_SCENEBROWSE (1<<16)
diff --git a/source/blender/windowmanager/intern/wm_dragdrop.c b/source/blender/windowmanager/intern/wm_dragdrop.c
index 3e2d01d6e80..4c58089f4e7 100644
--- a/source/blender/windowmanager/intern/wm_dragdrop.c
+++ b/source/blender/windowmanager/intern/wm_dragdrop.c
@@ -226,13 +226,13 @@ static void wm_drop_operator_options(bContext *C, wmDrag *drag, wmEvent *event)
/* check buttons (XXX todo rna and value) */
if (UI_but_active_drop_name(C) ) {
- strcpy(drag->opname, IFACE_("Paste name"));
+ BLI_strncpy(drag->opname, IFACE_("Paste name"), sizeof(drag->opname));
}
else {
const char *opname = wm_dropbox_active(C, drag, event);
if (opname) {
- BLI_strncpy(drag->opname, opname, FILE_MAX);
+ BLI_strncpy(drag->opname, opname, sizeof(drag->opname));
// WM_cursor_modal_set(win, CURSOR_COPY);
}
// else
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 37bcfa4f591..825c1ca9252 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -2171,7 +2171,7 @@ void wm_event_do_handlers(bContext *C)
while ( (event = win->queue.first) ) {
int action = WM_HANDLER_CONTINUE;
-#ifdef DEBUG
+#ifndef NDEBUG
if (G.debug & (G_DEBUG_HANDLERS | G_DEBUG_EVENTS) && !ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) {
printf("\n%s: Handling event\n", __func__);
WM_event_print(event);
diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c
index cc4d422331d..f7bbb84facc 100644
--- a/source/blender/windowmanager/intern/wm_files.c
+++ b/source/blender/windowmanager/intern/wm_files.c
@@ -865,9 +865,10 @@ int wm_file_write(bContext *C, const char *filepath, int fileflags, ReportList *
/* first time saving */
/* XXX temp solution to solve bug, real fix coming (ton) */
- if (G.main->name[0] == 0)
+ if ((G.main->name[0] == '\0') && !(fileflags & G_FILE_SAVE_COPY)) {
BLI_strncpy(G.main->name, filepath, sizeof(G.main->name));
-
+ }
+
/* XXX temp solution to solve bug, real fix coming (ton) */
G.main->recovered = 0;
diff --git a/source/blender/windowmanager/intern/wm_gesture.c b/source/blender/windowmanager/intern/wm_gesture.c
index adf159bcfee..05ee23e2361 100644
--- a/source/blender/windowmanager/intern/wm_gesture.c
+++ b/source/blender/windowmanager/intern/wm_gesture.c
@@ -40,6 +40,7 @@
#include "BLI_math.h"
#include "BLI_scanfill.h" /* lasso tessellation */
#include "BLI_utildefines.h"
+#include "BLI_lasso.h"
#include "BKE_context.h"
@@ -231,56 +232,73 @@ static void wm_gesture_draw_circle(wmGesture *gt)
}
-static void draw_filled_lasso(wmGesture *gt)
+struct LassoFillData {
+ unsigned int *px;
+ int width;
+};
+
+static void draw_filled_lasso_px_cb(int x, int y, void *user_data)
+{
+ struct LassoFillData *data = user_data;
+ unsigned char *col = (unsigned char *)&(data->px[(y * data->width) + x]);
+ col[0] = col[1] = col[2] = 0xff;
+ col[3] = 0x10;
+}
+
+static void draw_filled_lasso(wmWindow *win, wmGesture *gt)
{
- ScanFillContext sf_ctx;
- ScanFillVert *sf_vert = NULL, *sf_vert_last = NULL, *sf_vert_first = NULL;
- ScanFillFace *sf_tri;
short *lasso = (short *)gt->customdata;
+ const int tot = gt->points;
+ int (*moves)[2] = MEM_mallocN(sizeof(*moves) * (tot + 1), __func__);
int i;
-
- BLI_scanfill_begin(&sf_ctx);
- for (i = 0; i < gt->points; i++, lasso += 2) {
- float co[3];
-
- co[0] = (float)lasso[0];
- co[1] = (float)lasso[1];
- co[2] = 0.0f;
-
- sf_vert = BLI_scanfill_vert_add(&sf_ctx, co);
- if (sf_vert_last)
- /* e = */ /* UNUSED */ BLI_scanfill_edge_add(&sf_ctx, sf_vert_last, sf_vert);
- sf_vert_last = sf_vert;
- if (sf_vert_first == NULL) sf_vert_first = sf_vert;
+ rcti rect;
+ rcti rect_win;
+
+ for (i = 0; i < tot; i++, lasso += 2) {
+ moves[i][0] = lasso[0];
+ moves[i][1] = lasso[1];
}
-
- /* highly unlikely this will fail, but could crash if (gt->points == 0) */
- if (sf_vert_first) {
- const float zvec[3] = {0.0f, 0.0f, 1.0f};
- BLI_scanfill_edge_add(&sf_ctx, sf_vert_first, sf_vert);
- BLI_scanfill_calc_ex(&sf_ctx, BLI_SCANFILL_CALC_REMOVE_DOUBLES | BLI_SCANFILL_CALC_HOLES, zvec);
-
+
+ BLI_lasso_boundbox(&rect, (const int (*)[2])moves, tot);
+
+ wm_subwindow_getrect(win, gt->swinid, &rect_win);
+ BLI_rcti_translate(&rect, rect_win.xmin, rect_win.ymin);
+ BLI_rcti_isect(&rect_win, &rect, &rect);
+ BLI_rcti_translate(&rect, -rect_win.xmin, -rect_win.ymin);
+
+ /* highly unlikely this will fail, but could crash if (tot == 0) */
+ if (BLI_rcti_is_empty(&rect) == false) {
+ const int w = BLI_rcti_size_x(&rect);
+ const int h = BLI_rcti_size_y(&rect);
+ unsigned int *pixel_buf = MEM_callocN(sizeof(*pixel_buf) * w * h, __func__);
+ struct LassoFillData lasso_fill_data = {pixel_buf, w};
+
+ fill_poly_v2i_n(
+ rect.xmin, rect.ymin, rect.xmax, rect.ymax,
+ (const int (*)[2])moves, tot,
+ draw_filled_lasso_px_cb, &lasso_fill_data);
+
glEnable(GL_BLEND);
- glColor4f(1.0, 1.0, 1.0, 0.05);
- glBegin(GL_TRIANGLES);
- for (sf_tri = sf_ctx.fillfacebase.first; sf_tri; sf_tri = sf_tri->next) {
- glVertex2fv(sf_tri->v1->co);
- glVertex2fv(sf_tri->v2->co);
- glVertex2fv(sf_tri->v3->co);
- }
- glEnd();
+ // glColor4f(1.0, 1.0, 1.0, 0.05);
+
+ glRasterPos2f(rect.xmin, rect.ymin);
+
+ glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixel_buf);
+
glDisable(GL_BLEND);
-
- BLI_scanfill_end(&sf_ctx);
+ MEM_freeN(pixel_buf);
}
+
+ MEM_freeN(moves);
}
-static void wm_gesture_draw_lasso(wmGesture *gt)
+
+static void wm_gesture_draw_lasso(wmWindow *win, wmGesture *gt)
{
short *lasso = (short *)gt->customdata;
int i;
- draw_filled_lasso(gt);
+ draw_filled_lasso(win, gt);
glEnable(GL_LINE_STIPPLE);
glColor3ub(96, 96, 96);
@@ -347,9 +365,9 @@ void wm_gesture_draw(wmWindow *win)
wm_gesture_draw_cross(win, gt);
}
else if (gt->type == WM_GESTURE_LINES)
- wm_gesture_draw_lasso(gt);
+ wm_gesture_draw_lasso(win, gt);
else if (gt->type == WM_GESTURE_LASSO)
- wm_gesture_draw_lasso(gt);
+ wm_gesture_draw_lasso(win, gt);
else if (gt->type == WM_GESTURE_STRAIGHTLINE)
wm_gesture_draw_line(gt);
}
diff --git a/source/blender/windowmanager/intern/wm_jobs.c b/source/blender/windowmanager/intern/wm_jobs.c
index 188ad251b8a..c9c3d2df788 100644
--- a/source/blender/windowmanager/intern/wm_jobs.c
+++ b/source/blender/windowmanager/intern/wm_jobs.c
@@ -474,15 +474,16 @@ void WM_jobs_kill_all_except(wmWindowManager *wm, void *owner)
}
-void WM_jobs_kill_type(struct wmWindowManager *wm, int job_type)
+void WM_jobs_kill_type(struct wmWindowManager *wm, void *owner, int job_type)
{
wmJob *wm_job, *next_job;
for (wm_job = wm->jobs.first; wm_job; wm_job = next_job) {
next_job = wm_job->next;
- if (wm_job->job_type == job_type)
- wm_jobs_kill_job(wm, wm_job);
+ if (!owner || wm_job->owner == owner)
+ if (wm_job->job_type == job_type)
+ 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 ff805579b44..43a98a4600b 100644
--- a/source/blender/windowmanager/intern/wm_keymap.c
+++ b/source/blender/windowmanager/intern/wm_keymap.c
@@ -101,7 +101,7 @@ static int wm_keymap_item_equals_result(wmKeyMapItem *a, wmKeyMapItem *b)
if (strcmp(a->idname, b->idname) != 0)
return 0;
- if (!RNA_struct_equals(a->ptr, b->ptr, true))
+ if (!RNA_struct_equals(a->ptr, b->ptr, RNA_EQ_UNSET_MATCH_NONE))
return 0;
if ((a->flag & KMI_INACTIVE) != (b->flag & KMI_INACTIVE))
@@ -190,7 +190,7 @@ wmKeyConfig *WM_keyconfig_new_user(wmWindowManager *wm, const char *idname)
return keyconf;
}
-int WM_keyconfig_remove(wmWindowManager *wm, wmKeyConfig *keyconf)
+bool WM_keyconfig_remove(wmWindowManager *wm, wmKeyConfig *keyconf)
{
if (BLI_findindex(&wm->keyconfigs, keyconf) != -1) {
if (strncmp(U.keyconfigstr, keyconf->idname, sizeof(U.keyconfigstr)) == 0) {
@@ -201,10 +201,10 @@ int WM_keyconfig_remove(wmWindowManager *wm, wmKeyConfig *keyconf)
BLI_remlink(&wm->keyconfigs, keyconf);
WM_keyconfig_free(keyconf);
- return TRUE;
+ return true;
}
else {
- return FALSE;
+ return false;
}
}
@@ -299,6 +299,21 @@ void WM_keymap_free(wmKeyMap *keymap)
BLI_freelistN(&keymap->items);
}
+bool WM_keymap_remove(wmKeyConfig *keyconf, wmKeyMap *keymap)
+{
+ if (BLI_findindex(&keyconf->keymaps, keymap) != -1) {
+
+ WM_keymap_free(keymap);
+ BLI_remlink(&keyconf->keymaps, keymap);
+ MEM_freeN(keymap);
+
+ return true;
+ }
+ else {
+ return false;
+ }
+}
+
static void keymap_event_set(wmKeyMapItem *kmi, short type, short val, int modifier, short keymodifier)
{
kmi->type = type;
@@ -375,7 +390,7 @@ wmKeyMapItem *WM_keymap_add_menu(wmKeyMap *keymap, const char *idname, int type,
return kmi;
}
-int WM_keymap_remove_item(wmKeyMap *keymap, wmKeyMapItem *kmi)
+bool WM_keymap_remove_item(wmKeyMap *keymap, wmKeyMapItem *kmi)
{
if (BLI_findindex(&keymap->items, kmi) != -1) {
if (kmi->ptr) {
@@ -385,10 +400,10 @@ int WM_keymap_remove_item(wmKeyMap *keymap, wmKeyMapItem *kmi)
BLI_freelinkN(&keymap->items, kmi);
WM_keyconfig_update_tag(keymap, NULL);
- return TRUE;
+ return true;
}
else {
- return FALSE;
+ return false;
}
}
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 03567e864db..6091ec4a371 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -1433,7 +1433,8 @@ int WM_operator_ui_popup(bContext *C, wmOperator *op, int width, int height)
* 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)
+static int wm_operator_props_popup_ex(bContext *C, wmOperator *op,
+ const bool do_call, const bool do_redo)
{
if ((op->type->flag & OPTYPE_REGISTER) == 0) {
BKE_reportf(op->reports, RPT_ERROR,
@@ -1443,7 +1444,7 @@ static int wm_operator_props_popup_ex(bContext *C, wmOperator *op, const int do_
/* if we don't have global undo, we can't do undo push for automatic redo,
* so we require manual OK clicking in this popup */
- if (!(U.uiflag & USER_GLOBALUNDO))
+ if (!do_redo || !(U.uiflag & USER_GLOBALUNDO))
return WM_operator_props_dialog_popup(C, op, 15 * UI_UNIT_X, UI_UNIT_Y);
uiPupBlockEx(C, wm_block_create_redo, NULL, wm_block_redo_cancel_cb, op);
@@ -1454,18 +1455,26 @@ static int wm_operator_props_popup_ex(bContext *C, wmOperator *op, const int do_
return OPERATOR_RUNNING_MODAL;
}
+/* Same as WM_operator_props_popup but don't use operator redo.
+ * just wraps WM_operator_props_dialog_popup.
+ */
+int WM_operator_props_popup_confirm(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+{
+ return wm_operator_props_popup_ex(C, op, false, false);
+}
+
/* 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, const wmEvent *UNUSED(event))
{
- return wm_operator_props_popup_ex(C, op, TRUE);
+ return wm_operator_props_popup_ex(C, op, true, true);
}
int WM_operator_props_popup(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
- return wm_operator_props_popup_ex(C, op, FALSE);
+ return wm_operator_props_popup_ex(C, op, false, true);
}
int WM_operator_props_dialog_popup(bContext *C, wmOperator *op, int width, int height)
@@ -1681,7 +1690,7 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar
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-268");
+ "http://www.blender.org/development/release-logs/blender-269");
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");
@@ -2531,6 +2540,8 @@ static bool blend_save_check(bContext *UNUSED(C), wmOperator *op)
static void WM_OT_save_as_mainfile(wmOperatorType *ot)
{
+ PropertyRNA *prop;
+
ot->name = "Save As Blender File";
ot->idname = "WM_OT_save_as_mainfile";
ot->description = "Save the current file in the desired location";
@@ -2545,8 +2556,9 @@ static void WM_OT_save_as_mainfile(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "compress", 0, "Compress", "Write compressed .blend file");
RNA_def_boolean(ot->srna, "relative_remap", 1, "Remap Relative",
"Remap relative paths when saving in a different directory");
- RNA_def_boolean(ot->srna, "copy", 0, "Save Copy",
+ prop = RNA_def_boolean(ot->srna, "copy", 0, "Save Copy",
"Save a copy of the actual working state but does not make saved file active");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
#ifdef USE_BMESH_SAVE_AS_COMPAT
RNA_def_boolean(ot->srna, "use_mesh_compat", 0, "Legacy Mesh Format",
"Save using legacy mesh format (no ngons) - WARNING: only saves tris and quads, other ngons will "
diff --git a/source/blender/windowmanager/intern/wm_subwindow.c b/source/blender/windowmanager/intern/wm_subwindow.c
index 4ad4286b657..ae535ed45e8 100644
--- a/source/blender/windowmanager/intern/wm_subwindow.c
+++ b/source/blender/windowmanager/intern/wm_subwindow.c
@@ -148,6 +148,15 @@ void wm_subwindow_getmatrix(wmWindow *win, int swinid, float mat[4][4])
}
}
+void wm_subwindow_getrect(wmWindow *win, int swinid, rcti *r_rect)
+{
+ wmSubWindow *swin = swin_from_swinid(win, swinid);
+
+ if (swin) {
+ *r_rect = swin->winrct;
+ }
+}
+
/* always sets pixel-precise 2D window/view matrices */
/* coords is in whole pixels. xmin = 15, xmax = 16: means window is 2 pix big */
int wm_subwindow_open(wmWindow *win, rcti *winrct)
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index 78a2ed9b05d..9e89c17e024 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -131,7 +131,7 @@ static void wm_window_check_position(rcti *rect)
{
int width, height, d;
- wm_get_desktopsize(&width, &height);
+ wm_get_screensize(&width, &height);
#if defined(__APPLE__) && !defined(GHOST_COCOA)
height -= 70;
@@ -359,7 +359,7 @@ static void wm_window_add_ghostwindow(const char *title, wmWindow *win)
if (multisamples == -1)
multisamples = U.ogl_multisamples;
- wm_get_desktopsize(&scr_w, &scr_h);
+ wm_get_screensize(&scr_w, &scr_h);
posy = (scr_h - win->posy - win->sizey);
ghostwin = GHOST_CreateWindow(g_system, title,
@@ -378,12 +378,12 @@ static void wm_window_add_ghostwindow(const char *title, wmWindow *win)
win->ghostwin = ghostwin;
GHOST_SetWindowUserData(ghostwin, win); /* pointer back */
- /* set the state*/
- GHOST_SetWindowState(ghostwin, (GHOST_TWindowState)win->windowstate);
-
if (win->eventstate == NULL)
win->eventstate = MEM_callocN(sizeof(wmEvent), "window event state");
+ /* set the state */
+ GHOST_SetWindowState(ghostwin, (GHOST_TWindowState)win->windowstate);
+
/* until screens get drawn, make it nice gray */
glClearColor(0.55, 0.55, 0.55, 0.0);
/* Crash on OSS ATI: bugs.launchpad.net/ubuntu/+source/mesa/+bug/656100 */
diff --git a/source/blender/windowmanager/wm_subwindow.h b/source/blender/windowmanager/wm_subwindow.h
index 064d00b0723..a70e7765ecf 100644
--- a/source/blender/windowmanager/wm_subwindow.h
+++ b/source/blender/windowmanager/wm_subwindow.h
@@ -45,6 +45,7 @@ void wm_subwindow_position(wmWindow *win, int swinid, rcti *winrct);
void wm_subwindow_getsize(wmWindow *win, int swinid, int *x, int *y);
void wm_subwindow_getorigin(wmWindow *win, int swinid, int *x, int *y);
void wm_subwindow_getmatrix(wmWindow *win, int swinid, float mat[4][4]);
+void wm_subwindow_getrect(wmWindow *win, int swinid, struct rcti *r_rect);
unsigned int index_to_framebuffer(int index);
diff --git a/source/blenderplayer/CMakeLists.txt b/source/blenderplayer/CMakeLists.txt
index d91319d7477..67009bf2c8b 100644
--- a/source/blenderplayer/CMakeLists.txt
+++ b/source/blenderplayer/CMakeLists.txt
@@ -129,6 +129,7 @@ endif()
bf_intern_utfconv
bf_imbuf_cineon
bf_imbuf_openexr
+ bf_imbuf_openimageio
extern_openjpeg
extern_redcode
bf_imbuf_dds
diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c
index bd9aeee7111..f55f307e095 100644
--- a/source/blenderplayer/bad_level_call_stubs/stubs.c
+++ b/source/blenderplayer/bad_level_call_stubs/stubs.c
@@ -276,6 +276,7 @@ struct wmKeyMap *WM_keymap_list_find(struct ListBase *lb, char *idname, int spac
struct wmKeyConfig *WM_keyconfig_new(struct wmWindowManager *wm, char *idname) {STUB_ASSERT(0); return (struct wmKeyConfig *) NULL;}
struct wmKeyConfig *WM_keyconfig_new_user(struct wmWindowManager *wm, char *idname) {STUB_ASSERT(0); return (struct wmKeyConfig *) NULL;}
void WM_keyconfig_remove(struct wmWindowManager *wm, char *idname) {STUB_ASSERT(0);}
+void WM_keymap_remove(struct wmKeyConfig *keyconf, char *idname) {STUB_ASSERT(0);}
void WM_keyconfig_set_active(struct wmWindowManager *wm, const char *idname) {STUB_ASSERT(0);}
void WM_keymap_remove_item(struct wmKeyMap *keymap, struct wmKeyMapItem *kmi) {STUB_ASSERT(0);}
void WM_keymap_restore_to_default(struct wmKeyMap *keymap) {STUB_ASSERT(0);}
@@ -334,6 +335,7 @@ void ED_view3D_background_image_remove(struct View3D *v3d, struct BGpic *bgpic)
void ED_view3D_background_image_clear(struct View3D *v3d) {STUB_ASSERT(0);}
void ED_view3d_update_viewmat(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, float viewmat[4][4], float winmat[4][4]) {STUB_ASSERT(0);}
float ED_view3d_grid_scale(struct Scene *scene, struct View3D *v3d, const char **grid_unit) {STUB_ASSERT(0); return 0.0f;}
+void ED_view3d_shade_update(struct Main *bmain, struct View3D *v3d, struct ScrArea *sa) {STUB_ASSERT(0);}
void view3d_apply_mat4(float mat[4][4], float *ofs, float *quat, float *dist) {STUB_ASSERT(0);}
int text_file_modified(struct Text *text) {STUB_ASSERT(0); return 0;}
void ED_node_shader_default(struct bContext *C, struct ID *id) {STUB_ASSERT(0);}
diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt
index c45d59791c2..8e0ba6684ab 100644
--- a/source/creator/CMakeLists.txt
+++ b/source/creator/CMakeLists.txt
@@ -234,8 +234,16 @@ set(BLENDER_TEXT_FILES
${CMAKE_SOURCE_DIR}/release/text/Python-license.txt
${CMAKE_SOURCE_DIR}/release/text/copyright.txt
${CMAKE_SOURCE_DIR}/release/text/readme.html
+ ${CMAKE_SOURCE_DIR}/release/datafiles/LICENSE-bfont.ttf.txt
)
+if(WITH_INTERNATIONAL)
+ list(APPEND BLENDER_TEXT_FILES
+ ${CMAKE_SOURCE_DIR}/release/datafiles/LICENSE-droidsans.ttf.txt
+ ${CMAKE_SOURCE_DIR}/release/datafiles/LICENSE-bmonofont-i18n.ttf.txt
+ )
+endif()
+
# -----------------------------------------------------------------------------
# Platform Specific Var: TARGETDIR_VER
@@ -904,6 +912,7 @@ endif()
bf_avi
bf_imbuf_cineon
bf_imbuf_openexr
+ bf_imbuf_openimageio
bf_imbuf_dds
bf_collada
bf_intern_bsp
diff --git a/source/creator/creator.c b/source/creator/creator.c
index b442194bd7d..1596fe5359c 100644
--- a/source/creator/creator.c
+++ b/source/creator/creator.c
@@ -76,13 +76,13 @@
#include "BLI_threads.h"
#include "BLI_utildefines.h"
#include "BLI_callbacks.h"
+#include "BLI_blenlib.h"
+#include "BLI_mempool.h"
#include "DNA_ID.h"
#include "DNA_scene_types.h"
#include "DNA_userdef_types.h"
-#include "BLI_blenlib.h"
-
#include "BKE_blender.h"
#include "BKE_brush.h"
#include "BKE_context.h"
@@ -300,6 +300,7 @@ static int print_help(int UNUSED(argc), const char **UNUSED(argv), void *data)
#ifdef WITH_LIBMV
BLI_argsPrintArgDoc(ba, "--debug-libmv");
#endif
+ BLI_argsPrintArgDoc(ba, "--debug-memory");
BLI_argsPrintArgDoc(ba, "--debug-jobs");
BLI_argsPrintArgDoc(ba, "--debug-python");
@@ -412,10 +413,13 @@ static int debug_mode(int UNUSED(argc), const char **UNUSED(argv), void *data)
G.debug |= G_DEBUG; /* std output printf's */
printf(BLEND_VERSION_STRING_FMT);
MEM_set_memory_debug();
+#ifdef DEBUG
+ BLI_mempool_set_memory_debug();
+#endif
#ifdef WITH_BUILDINFO
printf("Build: %s %s %s %s\n", build_date, build_time, build_platform, build_type);
-#endif // WITH_BUILDINFO
+#endif
BLI_argsPrint(data);
return 0;
@@ -436,6 +440,12 @@ static int debug_mode_libmv(int UNUSED(argc), const char **UNUSED(argv), void *U
}
#endif
+static int debug_mode_memory(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
+{
+ MEM_set_memory_debug();
+ return 0;
+}
+
static int set_debug_value(int argc, const char **argv, void *UNUSED(data))
{
if (argc > 1) {
@@ -1381,6 +1391,7 @@ static void setupArguments(bContext *C, bArgs *ba, SYS_SystemHandle *syshandle)
#ifdef WITH_LIBMV
BLI_argsAdd(ba, 1, NULL, "--debug-libmv", "\n\tEnable debug messages from libmv library", debug_mode_libmv, NULL);
#endif
+ BLI_argsAdd(ba, 1, NULL, "--debug-memory", "\n\tEnable fully guarded memory allocation and debugging", debug_mode_memory, NULL);
BLI_argsAdd(ba, 1, NULL, "--debug-value", "<value>\n\tSet debug value of <value> on startup\n", set_debug_value, NULL);
BLI_argsAdd(ba, 1, NULL, "--debug-jobs", "\n\tEnable time profiling for background jobs.", debug_mode_generic, (void *)G_DEBUG_JOBS);
@@ -1451,23 +1462,50 @@ int main(int argc, const char **UNUSED(argv_c)) /* Do not mess with const */
int main(int argc, const char **argv)
#endif
{
- bContext *C = CTX_create();
+ bContext *C;
SYS_SystemHandle syshandle;
#ifndef WITH_PYTHON_MODULE
bArgs *ba;
#endif
-#ifdef WIN32
+#ifdef WIN32 /* Win32 Unicode Args */
+ /* NOTE: cannot use guardedalloc malloc here, as it's not yet initialised
+ * (it depends on the args passed in, which is what we're getting here!)
+ */
wchar_t **argv_16 = CommandLineToArgvW(GetCommandLineW(), &argc);
+ char **argv = malloc(argc * sizeof(char *));
int argci = 0;
- char **argv = MEM_mallocN(argc * sizeof(char *), "argv array");
+
for (argci = 0; argci < argc; argci++) {
argv[argci] = alloc_utf_8_from_16(argv_16[argci], 0);
}
+
LocalFree(argv_16);
#endif
+ /* NOTE: Special exception for guarded allocator type switch:
+ * we need to perform switch from lock-free to fully
+ * guarded allocator before any allocation happened.
+ */
+ {
+ int i;
+ for (i = 0; i < argc; i++) {
+ if (STREQ(argv[i], "--debug") || STREQ(argv[i], "-d") ||
+ STREQ(argv[i], "--debug-memory"))
+ {
+ printf("Switching to fully guarded memory allocator.\n");
+ MEM_use_guarded_allocator();
+ break;
+ }
+ else if (STREQ(argv[i], "--")) {
+ break;
+ }
+ }
+ }
+
+ C = CTX_create();
+
#ifdef WITH_PYTHON_MODULE
#ifdef __APPLE__
environ = *_NSGetEnviron();
@@ -1638,7 +1676,7 @@ int main(int argc, const char **argv)
while (argci) {
free(argv[--argci]);
}
- MEM_freeN(argv);
+ free(argv);
argv = NULL;
#endif
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp
index a6b71e0bc43..bcc62a341f8 100644
--- a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp
+++ b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp
@@ -211,7 +211,7 @@ void KX_BlenderRenderTools::applyTransform(RAS_IRasterizer* rasty,double* oglmat
MT_Vector3 dir = (campos - objpos).safe_normalized();
MT_Vector3 up(0,0,1.0);
- KX_GameObject* gameobj = (KX_GameObject*)m_clientobject;
+ KX_GameObject* gameobj = (KX_GameObject *)this->m_clientobject;
// get scaling of halo object
MT_Vector3 size = gameobj->GetSGNode()->GetWorldScaling();
@@ -225,7 +225,7 @@ void KX_BlenderRenderTools::applyTransform(RAS_IRasterizer* rasty,double* oglmat
}
MT_Vector3 left = dir.normalized();
- dir = (up.cross(left)).normalized();
+ dir = (left.cross(up)).normalized();
// we have calculated the row vectors, now we keep
// local scaling into account:
@@ -241,14 +241,13 @@ void KX_BlenderRenderTools::applyTransform(RAS_IRasterizer* rasty,double* oglmat
glTranslated(objpos[0],objpos[1],objpos[2]);
glMultMatrixd(maat);
-
}
else {
if (objectdrawmode & RAS_IPolyMaterial::SHADOW)
{
// shadow must be cast to the ground, physics system needed here!
MT_Point3 frompoint(oglmatrix[12],oglmatrix[13],oglmatrix[14]);
- KX_GameObject *gameobj = (KX_GameObject*)m_clientobject;
+ KX_GameObject *gameobj = (KX_GameObject *)this->m_clientobject;
MT_Vector3 direction = MT_Vector3(0,0,-1);
direction.normalize();
@@ -328,7 +327,7 @@ void KX_BlenderRenderTools::RenderText(
RAS_IPolyMaterial* polymat,
float v1[3], float v2[3], float v3[3], float v4[3], int glattrib)
{
- const STR_String& mytext = ((CValue*)m_clientobject)->GetPropertyText("Text");
+ const STR_String &mytext = ((CValue *)m_clientobject)->GetPropertyText("Text");
const unsigned int flag = polymat->GetFlag();
struct MTFace* tface = 0;
@@ -408,3 +407,4 @@ void KX_BlenderRenderTools::MotionBlur(RAS_IRasterizer* rasterizer)
}
}
}
+
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
index d43a226c373..bf7ac868d26 100644
--- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
@@ -2691,7 +2691,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
case PARBONE:
{
// parent this to a bone
- Bone *parent_bone = BKE_armature_find_bone_name( (bArmature *)(blenderchild->parent)->data, blenderchild->parsubstr);
+ Bone *parent_bone = BKE_armature_find_bone_name(BKE_armature_from_object(blenderchild->parent),
+ blenderchild->parsubstr);
if (parent_bone) {
KX_BoneParentRelation *bone_parent_relation = KX_BoneParentRelation::New(parent_bone);
diff --git a/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp b/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp
index 64ab0af4d26..793ce6a7b83 100644
--- a/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp
+++ b/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp
@@ -39,6 +39,8 @@
#include "SCA_Joystick.h"
#include "SCA_JoystickPrivate.h"
+#include "BLI_path_util.h"
+
SCA_Joystick::SCA_Joystick(short int index)
:
m_joyindex(index),
@@ -88,14 +90,26 @@ SCA_Joystick *SCA_Joystick::GetInstance( short int joyindex )
if (m_refCount == 0)
{
int i;
+
/* The video subsystem is required for joystick input to work. However,
- * when GHOST is running under SDL, video is initialized elsewhere.
- * Do this once only. */
+ * when GHOST is running under SDL, video is initialized elsewhere. We
+ * also need to set the videodriver to dummy, and do it here to avoid
+ * interfering with addons that may use SDL too.
+ *
+ * We also init SDL once only. */
# ifdef WITH_GHOST_SDL
- if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) == -1 ) {
+ int success = (SDL_InitSubSystem(SDL_INIT_JOYSTICK) != -1 );
# else
- if (SDL_InitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_VIDEO) == -1 ) {
+ /* set and restore environment variable */
+ char *videodriver = getenv("SDL_VIDEODRIVER");
+ BLI_setenv("SDL_VIDEODRIVER", "dummy");
+
+ int success = (SDL_InitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_VIDEO) != -1 );
+
+ BLI_setenv("SDL_VIDEODRIVER", videodriver);
# endif
+
+ if (!success) {
JOYSTICK_ECHO("Error-Initializing-SDL: " << SDL_GetError());
return NULL;
}
diff --git a/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp b/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp
index e8c29d5aa4f..0d851c4f10d 100644
--- a/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp
+++ b/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp
@@ -66,9 +66,7 @@ unsigned int GPC_RenderTools::m_numgllights;
GPC_RenderTools::GPC_RenderTools()
{
-// XXX m_font = BMF_GetFont(BMF_kHelvetica10);
-
- glGetIntegerv(GL_MAX_LIGHTS, (GLint*) &m_numgllights);
+ glGetIntegerv(GL_MAX_LIGHTS, (GLint *) &m_numgllights);
if (m_numgllights < 8)
m_numgllights = 8;
}
@@ -220,7 +218,7 @@ void GPC_RenderTools::applyTransform(RAS_IRasterizer* rasty,double* oglmatrix,in
MT_Vector3 dir = (campos - objpos).safe_normalized();
MT_Vector3 up(0,0,1.0);
- KX_GameObject* gameobj = (KX_GameObject*) this->m_clientobject;
+ KX_GameObject* gameobj = (KX_GameObject *)this->m_clientobject;
// get scaling of halo object
MT_Vector3 size = gameobj->GetSGNode()->GetWorldScaling();
@@ -256,7 +254,7 @@ void GPC_RenderTools::applyTransform(RAS_IRasterizer* rasty,double* oglmatrix,in
{
// shadow must be cast to the ground, physics system needed here!
MT_Point3 frompoint(oglmatrix[12],oglmatrix[13],oglmatrix[14]);
- KX_GameObject *gameobj = (KX_GameObject*) this->m_clientobject;
+ KX_GameObject *gameobj = (KX_GameObject *)this->m_clientobject;
MT_Vector3 direction = MT_Vector3(0,0,-1);
direction.normalize();
@@ -280,6 +278,12 @@ void GPC_RenderTools::applyTransform(RAS_IRasterizer* rasty,double* oglmatrix,in
// couldn't find something to cast the shadow on...
glMultMatrixd(oglmatrix);
}
+ else
+ { // we found the "ground", but the cast matrix doesn't take
+ // scaling in consideration, so we must apply the object scale
+ MT_Vector3 size = gameobj->GetSGNode()->GetLocalScale();
+ glScalef(size[0], size[1], size[2]);
+ }
} else
{
@@ -490,7 +494,7 @@ void GPC_RenderTools::RenderText(
RAS_IPolyMaterial* polymat,
float v1[3], float v2[3], float v3[3], float v4[3], int glattrib)
{
- STR_String mytext = ((CValue*)m_clientobject)->GetPropertyText("Text");
+ const STR_String &mytext = ((CValue *)m_clientobject)->GetPropertyText("Text");
const unsigned int flag = polymat->GetFlag();
struct MTFace* tface = 0;
@@ -562,8 +566,7 @@ void GPC_RenderTools::MotionBlur(RAS_IRasterizer* rasterizer)
glAccum(GL_LOAD, 1.0);
rasterizer->SetMotionBlurState(2);
}
- else if (motionblurvalue>=0.0 && motionblurvalue<=1.0)
- {
+ else if (motionblurvalue >= 0.0f && motionblurvalue <= 1.0f) {
glAccum(GL_MULT, motionblurvalue);
glAccum(GL_ACCUM, 1-motionblurvalue);
glAccum(GL_RETURN, 1.0);
diff --git a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
index 0b1fbf977dd..5bed4fa40b6 100644
--- a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
+++ b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
@@ -58,11 +58,15 @@ extern "C"
#endif // __cplusplus
#include "MEM_guardedalloc.h"
#include "BLI_threads.h"
+#include "BLI_mempool.h"
#include "BLI_blenlib.h"
+
#include "DNA_scene_types.h"
#include "DNA_userdef_types.h"
+
#include "BLO_readfile.h"
#include "BLO_runtime.h"
+
#include "BKE_blender.h"
#include "BKE_depsgraph.h"
#include "BKE_global.h"
@@ -74,6 +78,7 @@ extern "C"
#include "BKE_modifier.h"
#include "BKE_text.h"
#include "BKE_sound.h"
+
#include "IMB_imbuf.h"
int GHOST_HACK_getFirstFile(char buf[]);
@@ -580,8 +585,11 @@ int main(int argc, char** argv)
case 'd':
i++;
- G.debug |= G_DEBUG; /* std output printf's */
+ G.debug |= G_DEBUG;
MEM_set_memory_debug();
+#ifdef DEBUG
+ BLI_mempool_set_memory_debug();
+#endif
break;
case 'f':
diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp
index b3a38cb4f98..e5b8159753b 100644
--- a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp
+++ b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp
@@ -968,7 +968,7 @@ KX_PYMETHODDEF_DOC( KX_BlenderMaterial, setTexture , "setTexture( index, tex)")
return NULL;
}
-static unsigned int GL_array[11] = {
+static const unsigned int GL_array[11] = {
GL_ZERO,
GL_ONE,
GL_SRC_COLOR,