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:
authorClément Foucault <foucault.clem@gmail.com>2020-05-25 12:48:31 +0300
committerClément Foucault <foucault.clem@gmail.com>2020-05-25 12:48:31 +0300
commite76ff4df4123b5517599930629dbcf0507b582e9 (patch)
tree3cf9a67f3a3a05c678f39a04533da81f56e66c02
parent15dd6cb66887eb83fcc3ecf44c3b42a53161e390 (diff)
parent528f0b95c4462b2e429600a566ca0434c90310f6 (diff)
Merge branch 'master' into tmp-widget-optitmp-widget-opti
# Conflicts: # source/blender/gpu/shaders/gpu_shader_2D_widget_base_vert.glsl
-rw-r--r--CMakeLists.txt8
-rw-r--r--build_files/build_environment/CMakeLists.txt1
-rw-r--r--build_files/build_environment/cmake/faad.cmake40
-rw-r--r--build_files/build_environment/cmake/ffmpeg.cmake1
-rw-r--r--build_files/build_environment/cmake/fftw.cmake13
-rw-r--r--build_files/build_environment/cmake/harvest.cmake4
-rw-r--r--build_files/build_environment/cmake/openal.cmake1
-rw-r--r--build_files/build_environment/cmake/opensubdiv.cmake2
-rw-r--r--build_files/build_environment/cmake/sndfile.cmake11
-rw-r--r--build_files/build_environment/cmake/versions.cmake50
-rw-r--r--build_files/build_environment/cmake/x264.cmake4
-rw-r--r--build_files/build_environment/patches/openal.diff13
-rw-r--r--build_files/build_environment/patches/x264.diff22
-rw-r--r--build_files/cmake/config/blender_lite.cmake1
-rw-r--r--build_files/cmake/platform/platform_win32.cmake2
-rw-r--r--doc/python_api/requirements.txt4
-rw-r--r--extern/mantaflow/preprocessed/gitinfo.h2
-rw-r--r--extern/mantaflow/preprocessed/particle.h62
-rw-r--r--intern/cycles/blender/addon/__init__.py4
-rw-r--r--intern/cycles/blender/addon/engine.py4
-rw-r--r--intern/cycles/blender/addon/ui.py11
-rw-r--r--intern/cycles/blender/blender_object.cpp15
-rw-r--r--intern/cycles/blender/blender_python.cpp28
-rw-r--r--intern/cycles/blender/blender_session.cpp168
-rw-r--r--intern/cycles/blender/blender_session.h13
-rw-r--r--intern/cycles/blender/blender_sync.cpp3
-rw-r--r--intern/cycles/blender/blender_volume.cpp15
-rw-r--r--intern/cycles/device/cuda/device_cuda.h2
-rw-r--r--intern/cycles/device/cuda/device_cuda_impl.cpp52
-rw-r--r--intern/cycles/device/device_cpu.cpp28
-rw-r--r--intern/cycles/device/opencl/device_opencl.h1
-rw-r--r--intern/cycles/device/opencl/device_opencl_impl.cpp53
-rw-r--r--intern/cycles/kernel/kernel_bake.h152
-rw-r--r--intern/cycles/kernel/kernel_film.h8
-rw-r--r--intern/cycles/kernel/kernel_light.h16
-rw-r--r--intern/cycles/kernel/kernel_types.h17
-rw-r--r--intern/cycles/kernel/kernels/cpu/kernel_cpu.h3
-rw-r--r--intern/cycles/kernel/kernels/cpu/kernel_cpu_impl.h19
-rw-r--r--intern/cycles/kernel/kernels/cuda/kernel.cu11
-rw-r--r--intern/cycles/render/bake.cpp305
-rw-r--r--intern/cycles/render/bake.h52
-rw-r--r--intern/cycles/render/buffers.cpp34
-rw-r--r--intern/cycles/render/buffers.h3
-rw-r--r--intern/cycles/render/film.cpp17
-rw-r--r--intern/cycles/render/session.cpp32
-rw-r--r--intern/cycles/render/session.h1
-rw-r--r--intern/ghost/intern/GHOST_System.cpp11
-rw-r--r--intern/ghost/intern/GHOST_SystemWayland.cpp200
-rw-r--r--intern/guardedalloc/CMakeLists.txt8
-rw-r--r--intern/guardedalloc/MEM_guardedalloc.h19
-rw-r--r--intern/guardedalloc/intern/mallocn.c7
-rw-r--r--intern/guardedalloc/intern/mallocn_guarded_impl.c178
-rw-r--r--intern/guardedalloc/intern/mallocn_intern.h17
-rw-r--r--intern/guardedalloc/intern/mallocn_lockfree_impl.c109
-rw-r--r--intern/libmv/libmv/autotrack/reconstruction.h3
-rw-r--r--intern/libmv/libmv/simple_pipeline/bundle.cc57
-rw-r--r--intern/libmv/libmv/simple_pipeline/reconstruction.cc65
-rw-r--r--intern/libmv/libmv/simple_pipeline/reconstruction.h13
-rw-r--r--intern/mantaflow/intern/MANTA_main.cpp731
-rw-r--r--intern/mantaflow/intern/MANTA_main.h23
-rw-r--r--intern/mantaflow/intern/strings/fluid_script.h2
-rw-r--r--intern/mantaflow/intern/strings/liquid_script.h21
-rw-r--r--intern/mantaflow/intern/strings/smoke_script.h32
-rw-r--r--intern/opensubdiv/CMakeLists.txt18
-rw-r--r--intern/opensubdiv/internal/opensubdiv.cc4
-rw-r--r--intern/opensubdiv/internal/opensubdiv_converter_factory.cc13
-rw-r--r--intern/opensubdiv/internal/opensubdiv_converter_factory.h6
-rw-r--r--intern/opensubdiv/internal/opensubdiv_converter_internal.cc6
-rw-r--r--intern/opensubdiv/internal/opensubdiv_converter_internal.h6
-rw-r--r--intern/opensubdiv/internal/opensubdiv_converter_orient.cc67
-rw-r--r--intern/opensubdiv/internal/opensubdiv_converter_orient.h49
-rw-r--r--intern/opensubdiv/internal/opensubdiv_converter_orient_impl.h69
-rw-r--r--intern/opensubdiv/internal/opensubdiv_edge_map.h10
-rw-r--r--intern/opensubdiv/internal/opensubdiv_evaluator_internal.cc12
-rw-r--r--intern/opensubdiv/internal/opensubdiv_evaluator_internal.h8
-rw-r--r--intern/opensubdiv/internal/opensubdiv_gl_mesh.cc260
-rw-r--r--intern/opensubdiv/internal/opensubdiv_gl_mesh_draw.cc577
-rw-r--r--intern/opensubdiv/internal/opensubdiv_gl_mesh_draw.h39
-rw-r--r--intern/opensubdiv/internal/opensubdiv_gl_mesh_fvar.cc171
-rw-r--r--intern/opensubdiv/internal/opensubdiv_gl_mesh_fvar.h57
-rw-r--r--intern/opensubdiv/internal/opensubdiv_gl_mesh_internal.cc32
-rw-r--r--intern/opensubdiv/internal/opensubdiv_gl_mesh_internal.h43
-rw-r--r--intern/opensubdiv/internal/opensubdiv_topology_refiner.cc24
-rw-r--r--intern/opensubdiv/internal/opensubdiv_util.cc6
-rw-r--r--intern/opensubdiv/internal/opensubdiv_util.h6
-rw-r--r--intern/opensubdiv/opensubdiv_gl_mesh_capi.h92
-rw-r--r--intern/opensubdiv/shader/gpu_shader_opensubdiv_fragment.glsl163
-rw-r--r--intern/opensubdiv/shader/gpu_shader_opensubdiv_geometry.glsl149
-rw-r--r--intern/opensubdiv/shader/gpu_shader_opensubdiv_vertex.glsl42
-rw-r--r--intern/opensubdiv/stub/opensubdiv_gl_mesh_stub.cc40
m---------release/datafiles/locale0
m---------release/scripts/addons0
-rw-r--r--release/scripts/modules/bpy_extras/object_utils.py8
-rw-r--r--release/scripts/presets/tracking_camera/1__colon__2.3_inch.py1
-rw-r--r--release/scripts/presets/tracking_camera/1__colon__2.5_inch.py1
-rw-r--r--release/scripts/presets/tracking_camera/2__colon__3_inch.py1
-rw-r--r--release/scripts/presets/tracking_camera/4__colon__3_inch.py1
-rw-r--r--release/scripts/presets/tracking_camera/Arri_Alexa.py1
-rw-r--r--release/scripts/presets/tracking_camera/Canon_1100D.py1
-rw-r--r--release/scripts/presets/tracking_camera/Canon_APS-C.py1
-rw-r--r--release/scripts/presets/tracking_camera/Canon_APS-H.py1
-rw-r--r--release/scripts/presets/tracking_camera/Canon_C300.py1
-rw-r--r--release/scripts/presets/tracking_camera/Full_Frame_35mm_Camera.py1
-rw-r--r--release/scripts/presets/tracking_camera/GoPro_Hero3_Black.py1
-rw-r--r--release/scripts/presets/tracking_camera/GoPro_Hero3_Silver.py1
-rw-r--r--release/scripts/presets/tracking_camera/GoPro_Hero3_White.py1
-rw-r--r--release/scripts/presets/tracking_camera/Nexus_5.py1
-rw-r--r--release/scripts/presets/tracking_camera/Samsung_Galaxy_S3.py1
-rw-r--r--release/scripts/presets/tracking_camera/Samsung_Galaxy_S4.py1
-rw-r--r--release/scripts/presets/tracking_camera/Super_16.py1
-rw-r--r--release/scripts/presets/tracking_camera/Super_35.py1
-rw-r--r--release/scripts/presets/tracking_camera/iPhone_4.py1
-rw-r--r--release/scripts/presets/tracking_camera/iPhone_4S.py1
-rw-r--r--release/scripts/presets/tracking_camera/iPhone_5.py1
-rw-r--r--release/scripts/startup/bl_ui/properties_data_bone.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_fluid.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_render.py1
-rw-r--r--release/scripts/startup/bl_ui/space_image.py3
-rw-r--r--release/scripts/startup/bl_ui/space_topbar.py10
-rw-r--r--release/scripts/startup/bl_ui/space_userpref.py101
-rw-r--r--release/scripts/startup/bl_ui/space_view3d.py12
-rw-r--r--release/scripts/startup/bl_ui/space_view3d_toolbar.py4
-rw-r--r--source/blender/blenkernel/BKE_armature.h2
-rw-r--r--source/blender/blenkernel/BKE_blender_version.h2
-rw-r--r--source/blender/blenkernel/BKE_brush.h16
-rw-r--r--source/blender/blenkernel/BKE_curve.h5
-rw-r--r--source/blender/blenkernel/BKE_lib_query.h4
-rw-r--r--source/blender/blenkernel/BKE_light.h3
-rw-r--r--source/blender/blenkernel/BKE_pbvh.h15
-rw-r--r--source/blender/blenkernel/BKE_screen.h3
-rw-r--r--source/blender/blenkernel/BKE_subdiv.h6
-rw-r--r--source/blender/blenkernel/BKE_subsurf.h9
-rw-r--r--source/blender/blenkernel/CMakeLists.txt2
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf.c80
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf.h53
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf_intern.h65
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c970
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf_opensubdiv_converter.c777
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c4
-rw-r--r--source/blender/blenkernel/intern/action.c11
-rw-r--r--source/blender/blenkernel/intern/armature.c18
-rw-r--r--source/blender/blenkernel/intern/brush.c229
-rw-r--r--source/blender/blenkernel/intern/cachefile.c1
-rw-r--r--source/blender/blenkernel/intern/collection.c24
-rw-r--r--source/blender/blenkernel/intern/curve.c11
-rw-r--r--source/blender/blenkernel/intern/customdata.c20
-rw-r--r--source/blender/blenkernel/intern/displist.c9
-rw-r--r--source/blender/blenkernel/intern/dynamicpaint.c4
-rw-r--r--source/blender/blenkernel/intern/fcurve.c2
-rw-r--r--source/blender/blenkernel/intern/fluid.c57
-rw-r--r--source/blender/blenkernel/intern/font.c1
-rw-r--r--source/blender/blenkernel/intern/gpencil.c26
-rw-r--r--source/blender/blenkernel/intern/hair.c139
-rw-r--r--source/blender/blenkernel/intern/image.c1
-rw-r--r--source/blender/blenkernel/intern/ipo.c1
-rw-r--r--source/blender/blenkernel/intern/lib_query.c910
-rw-r--r--source/blender/blenkernel/intern/light.c7
-rw-r--r--source/blender/blenkernel/intern/linestyle.c46
-rw-r--r--source/blender/blenkernel/intern/mask.c16
-rw-r--r--source/blender/blenkernel/intern/movieclip.c24
-rw-r--r--source/blender/blenkernel/intern/multires_reshape.c11
-rw-r--r--source/blender/blenkernel/intern/object.c156
-rw-r--r--source/blender/blenkernel/intern/paint.c60
-rw-r--r--source/blender/blenkernel/intern/particle.c59
-rw-r--r--source/blender/blenkernel/intern/pbvh.c27
-rw-r--r--source/blender/blenkernel/intern/pbvh_intern.h1
-rw-r--r--source/blender/blenkernel/intern/pointcloud.c85
-rw-r--r--source/blender/blenkernel/intern/scene.c184
-rw-r--r--source/blender/blenkernel/intern/screen.c159
-rw-r--r--source/blender/blenkernel/intern/seqcache.c13
-rw-r--r--source/blender/blenkernel/intern/seqprefetch.c62
-rw-r--r--source/blender/blenkernel/intern/sequencer.c7
-rw-r--r--source/blender/blenkernel/intern/simulation.cc22
-rw-r--r--source/blender/blenkernel/intern/sound.c1
-rw-r--r--source/blender/blenkernel/intern/subdiv.c12
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c277
-rw-r--r--source/blender/blenkernel/intern/text.c1
-rw-r--r--source/blender/blenkernel/intern/tracking_stabilize.c4
-rw-r--r--source/blender/blenkernel/intern/tracking_util.c4
-rw-r--r--source/blender/blenkernel/intern/volume.cc71
-rw-r--r--source/blender/blenkernel/intern/workspace.c19
-rw-r--r--source/blender/blenkernel/intern/writeffmpeg.c5
-rw-r--r--source/blender/blenlib/BLI_threads.h3
-rw-r--r--source/blender/blenlib/BLI_vector_set.hh2
-rw-r--r--source/blender/blenlib/intern/boxpack_2d.c2
-rw-r--r--source/blender/blenlib/intern/storage.c5
-rw-r--r--source/blender/blenlib/intern/task_pool.cc10
-rw-r--r--source/blender/blenlib/intern/task_range.cc1
-rw-r--r--source/blender/blenlib/intern/threads.c39
-rw-r--r--source/blender/blenloader/intern/readfile.c88
-rw-r--r--source/blender/blenloader/intern/versioning_280.c9
-rw-r--r--source/blender/blenloader/intern/versioning_defaults.c4
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh_conv.c4
-rw-r--r--source/blender/bmesh/intern/bmesh_opdefines.c9
-rw-r--r--source/blender/bmesh/tools/bmesh_bevel.c9
-rw-r--r--source/blender/compositor/operations/COM_VectorBlurOperation.cpp14
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.cc13
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.cc8
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_operation.cc2
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_operation.h1
-rw-r--r--source/blender/draw/CMakeLists.txt2
-rw-r--r--source/blender/draw/engines/eevee/eevee_subsurface.c8
-rw-r--r--source/blender/draw/engines/eevee/eevee_volumes.c7
-rw-r--r--source/blender/draw/engines/external/external_engine.c2
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_common_lib.glsl6
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_frag.glsl4
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_vert.glsl2
-rw-r--r--source/blender/draw/engines/overlay/overlay_armature.c20
-rw-r--r--source/blender/draw/engines/overlay/overlay_background.c7
-rw-r--r--source/blender/draw/engines/overlay/overlay_image.c3
-rw-r--r--source/blender/draw/engines/overlay/overlay_private.h7
-rw-r--r--source/blender/draw/engines/overlay/overlay_wireframe.c62
-rw-r--r--source/blender/draw/engines/overlay/shaders/wireframe_vert.glsl11
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_curvature_lib.glsl4
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_image_lib.glsl24
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_merge_infront_frag.glsl2
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_world_light_lib.glsl2
-rw-r--r--source/blender/draw/intern/draw_cache_impl_curve.c2
-rw-r--r--source/blender/draw/intern/draw_cache_impl_gpencil.c2
-rw-r--r--source/blender/draw/intern/draw_manager_data.c5
-rw-r--r--source/blender/draw/intern/draw_manager_shader.c3
-rw-r--r--source/blender/editors/animation/fmodifier_ui.c51
-rw-r--r--source/blender/editors/armature/armature_relations.c3
-rw-r--r--source/blender/editors/armature/pose_edit.c2
-rw-r--r--source/blender/editors/armature/pose_slide.c95
-rw-r--r--source/blender/editors/gpencil/gpencil_data.c8
-rw-r--r--source/blender/editors/gpencil/gpencil_edit.c21
-rw-r--r--source/blender/editors/gpencil/gpencil_intern.h7
-rw-r--r--source/blender/editors/gpencil/gpencil_merge.c2
-rw-r--r--source/blender/editors/gpencil/gpencil_paint.c26
-rw-r--r--source/blender/editors/gpencil/gpencil_primitive.c2
-rw-r--r--source/blender/editors/gpencil/gpencil_utils.c2
-rw-r--r--source/blender/editors/include/ED_object.h1
-rw-r--r--source/blender/editors/include/ED_screen.h1
-rw-r--r--source/blender/editors/include/ED_transform.h2
-rw-r--r--source/blender/editors/include/ED_uvedit.h17
-rw-r--r--source/blender/editors/include/UI_interface.h2
-rw-r--r--source/blender/editors/interface/interface_eyedropper_color.c11
-rw-r--r--source/blender/editors/interface/interface_eyedropper_colorband.c5
-rw-r--r--source/blender/editors/interface/interface_eyedropper_datablock.c5
-rw-r--r--source/blender/editors/interface/interface_eyedropper_depth.c5
-rw-r--r--source/blender/editors/interface/interface_eyedropper_driver.c5
-rw-r--r--source/blender/editors/interface/interface_handlers.c9
-rw-r--r--source/blender/editors/interface/interface_intern.h1
-rw-r--r--source/blender/editors/interface/interface_panel.c4
-rw-r--r--source/blender/editors/interface/interface_region_hud.c5
-rw-r--r--source/blender/editors/interface/interface_template_search_menu.c43
-rw-r--r--source/blender/editors/interface/view2d_draw.c15
-rw-r--r--source/blender/editors/object/object_add.c16
-rw-r--r--source/blender/editors/object/object_bake_api.c30
-rw-r--r--source/blender/editors/object/object_collection.c8
-rw-r--r--source/blender/editors/object/object_edit.c9
-rw-r--r--source/blender/editors/physics/particle_edit.c3
-rw-r--r--source/blender/editors/physics/physics_fluid.c9
-rw-r--r--source/blender/editors/render/render_internal.c16
-rw-r--r--source/blender/editors/render/render_opengl.c2
-rw-r--r--source/blender/editors/screen/screen_ops.c30
-rw-r--r--source/blender/editors/sculpt_paint/paint_image.c3
-rw-r--r--source/blender/editors/sculpt_paint/paint_ops.c9
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c14
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_undo.c15
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_uv.c3
-rw-r--r--source/blender/editors/space_console/console_draw.c15
-rw-r--r--source/blender/editors/space_file/fsmenu.c5
-rw-r--r--source/blender/editors/space_graph/graph_buttons.c79
-rw-r--r--source/blender/editors/space_graph/graph_draw.c10
-rw-r--r--source/blender/editors/space_image/image_ops.c5
-rw-r--r--source/blender/editors/space_image/image_undo.c6
-rw-r--r--source/blender/editors/space_info/info_draw.c1
-rw-r--r--source/blender/editors/space_info/info_stats.c8
-rw-r--r--source/blender/editors/space_info/textview.c38
-rw-r--r--source/blender/editors/space_info/textview.h2
-rw-r--r--source/blender/editors/space_node/node_view.c2
-rw-r--r--source/blender/editors/space_outliner/outliner_draw.c52
-rw-r--r--source/blender/editors/space_outliner/outliner_edit.c19
-rw-r--r--source/blender/editors/space_outliner/outliner_tools.c30
-rw-r--r--source/blender/editors/space_view3d/view3d_buttons.c6
-rw-r--r--source/blender/editors/space_view3d/view3d_iterators.c2
-rw-r--r--source/blender/editors/transform/transform.c184
-rw-r--r--source/blender/editors/transform/transform.h30
-rw-r--r--source/blender/editors/transform/transform_constraints.c273
-rw-r--r--source/blender/editors/transform/transform_constraints.h3
-rw-r--r--source/blender/editors/transform/transform_convert.c38
-rw-r--r--source/blender/editors/transform/transform_convert.h1
-rw-r--r--source/blender/editors/transform/transform_convert_curve.c4
-rw-r--r--source/blender/editors/transform/transform_convert_mesh.c3
-rw-r--r--source/blender/editors/transform/transform_generics.c62
-rw-r--r--source/blender/editors/transform/transform_gizmo_2d.c4
-rw-r--r--source/blender/editors/transform/transform_gizmo_3d.c26
-rw-r--r--source/blender/editors/transform/transform_mode.c12
-rw-r--r--source/blender/editors/transform/transform_mode.h1
-rw-r--r--source/blender/editors/transform/transform_mode_edge_seq_slide.c3
-rw-r--r--source/blender/editors/transform/transform_mode_rotate.c3
-rw-r--r--source/blender/editors/transform/transform_mode_shear.c6
-rw-r--r--source/blender/editors/transform/transform_mode_translate.c43
-rw-r--r--source/blender/editors/transform/transform_orientations.c141
-rw-r--r--source/blender/editors/transform/transform_snap.c7
-rw-r--r--source/blender/editors/transform/transform_snap_object.c26
-rw-r--r--source/blender/editors/util/ed_transverts.c2
-rw-r--r--source/blender/editors/uvedit/uvedit_buttons.c21
-rw-r--r--source/blender/editors/uvedit/uvedit_draw.c20
-rw-r--r--source/blender/editors/uvedit/uvedit_intern.h11
-rw-r--r--source/blender/editors/uvedit/uvedit_ops.c111
-rw-r--r--source/blender/editors/uvedit/uvedit_select.c206
-rw-r--r--source/blender/editors/uvedit/uvedit_smart_stitch.c5
-rw-r--r--source/blender/freestyle/intern/application/Controller.cpp7
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c5
-rw-r--r--source/blender/gpu/intern/gpu_buffers.c33
-rw-r--r--source/blender/gpu/intern/gpu_draw.c2
-rw-r--r--source/blender/gpu/intern/gpu_extensions.c8
-rw-r--r--source/blender/gpu/intern/gpu_shader_interface.c4
-rw-r--r--source/blender/imbuf/IMB_colormanagement.h1
-rw-r--r--source/blender/imbuf/intern/allocimbuf.c2
-rw-r--r--source/blender/imbuf/intern/cache.c4
-rw-r--r--source/blender/imbuf/intern/colormanagement.c17
-rw-r--r--source/blender/imbuf/intern/divers.c2
-rw-r--r--source/blender/imbuf/intern/openexr/openexr_api.cpp4
-rw-r--r--source/blender/io/alembic/intern/abc_reader_nurbs.cc2
-rw-r--r--source/blender/io/avi/intern/avi_mjpeg.c37
-rw-r--r--source/blender/io/usd/intern/abstract_hierarchy_iterator.cc2
-rw-r--r--source/blender/io/usd/intern/usd_capi.cc2
-rw-r--r--source/blender/io/usd/intern/usd_writer_mesh.cc4
-rw-r--r--source/blender/io/usd/intern/usd_writer_transform.cc2
-rw-r--r--source/blender/makesdna/DNA_fluid_types.h92
-rw-r--r--source/blender/makesdna/DNA_scene_types.h3
-rw-r--r--source/blender/makesdna/DNA_view3d_defaults.h2
-rw-r--r--source/blender/makesdna/intern/CMakeLists.txt4
-rw-r--r--source/blender/makesrna/intern/CMakeLists.txt4
-rw-r--r--source/blender/makesrna/intern/makesrna.c4
-rw-r--r--source/blender/makesrna/intern/rna_access.c4
-rw-r--r--source/blender/makesrna/intern/rna_action.c9
-rw-r--r--source/blender/makesrna/intern/rna_armature.c20
-rw-r--r--source/blender/makesrna/intern/rna_fluid.c6
-rw-r--r--source/blender/makesrna/intern/rna_gpencil.c1
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c3
-rw-r--r--source/blender/makesrna/intern/rna_object.c1
-rw-r--r--source/blender/makesrna/intern/rna_pose.c13
-rw-r--r--source/blender/makesrna/intern/rna_render.c96
-rw-r--r--source/blender/makesrna/intern/rna_scene.c19
-rw-r--r--source/blender/makesrna/intern/rna_texture.c6
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c5
-rw-r--r--source/blender/makesrna/intern/rna_wm.c2
-rw-r--r--source/blender/modifiers/intern/MOD_mask.cc1
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_image.c3
-rw-r--r--source/blender/render/CMakeLists.txt2
-rw-r--r--source/blender/render/extern/include/RE_bake.h3
-rw-r--r--source/blender/render/extern/include/RE_engine.h16
-rw-r--r--source/blender/render/intern/include/render_result.h11
-rw-r--r--source/blender/render/intern/source/bake_api.c13
-rw-r--r--source/blender/render/intern/source/external_engine.c144
-rw-r--r--source/blender/render/intern/source/pipeline.c13
-rw-r--r--source/blender/render/intern/source/render_result.c20
-rw-r--r--source/blender/windowmanager/CMakeLists.txt4
-rw-r--r--source/blender/windowmanager/intern/wm.c27
-rw-r--r--source/blender/windowmanager/intern/wm_draw.c5
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c54
-rw-r--r--source/blender/windowmanager/intern/wm_files.c7
-rw-r--r--source/blender/windowmanager/intern/wm_init_exit.c17
-rw-r--r--source/blender/windowmanager/intern/wm_splash_screen.c3
-rw-r--r--source/blender/windowmanager/intern/wm_window.c26
-rw-r--r--source/blender/windowmanager/wm_event_system.h5
-rw-r--r--source/blender/windowmanager/wm_event_types.h1
-rw-r--r--source/blender/windowmanager/wm_window.h5
-rw-r--r--source/blender/windowmanager/xr/intern/wm_xr.c7
-rw-r--r--source/creator/CMakeLists.txt7
-rw-r--r--source/creator/creator_args.c12
-rw-r--r--tests/gtests/blenlib/BLI_linklist_lockfree_test.cc2
-rw-r--r--tests/gtests/blenlib/BLI_type_construct_mock.hh63
-rw-r--r--tests/gtests/blenlib/BLI_vector_test.cc149
369 files changed, 4908 insertions, 8345 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ae9f3992aa5..a4037dc1e3e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -281,7 +281,7 @@ option(WITH_ALEMBIC "Enable Alembic Support" ON)
option(WITH_ALEMBIC_HDF5 "Enable Legacy Alembic Support (not officially supported)" OFF)
# Universal Scene Description support
-option(WITH_USD "Enable Universal Scene Description (USD) Support" OFF)
+option(WITH_USD "Enable Universal Scene Description (USD) Support" ON)
# 3D format support
# Disable opencollada when we don't have precompiled libs
@@ -628,12 +628,6 @@ if(WITH_PYTHON_MODULE AND WITH_PYTHON_INSTALL)
message(FATAL_ERROR "WITH_PYTHON_MODULE requires WITH_PYTHON_INSTALL to be OFF")
endif()
-
-# may as well build python module without a UI
-if(WITH_PYTHON_MODULE)
- set(WITH_HEADLESS ON)
-endif()
-
if(NOT WITH_PYTHON)
set(WITH_CYCLES OFF)
set(WITH_DRACO OFF)
diff --git a/build_files/build_environment/CMakeLists.txt b/build_files/build_environment/CMakeLists.txt
index 53d88b12129..dd90eb9adde 100644
--- a/build_files/build_environment/CMakeLists.txt
+++ b/build_files/build_environment/CMakeLists.txt
@@ -130,7 +130,6 @@ if(NOT WIN32 OR ENABLE_MINGW64)
include(cmake/vpx.cmake)
include(cmake/x264.cmake)
include(cmake/xvidcore.cmake)
- include(cmake/faad.cmake)
include(cmake/ffmpeg.cmake)
include(cmake/fftw.cmake)
include(cmake/sndfile.cmake)
diff --git a/build_files/build_environment/cmake/faad.cmake b/build_files/build_environment/cmake/faad.cmake
deleted file mode 100644
index 15934cc1879..00000000000
--- a/build_files/build_environment/cmake/faad.cmake
+++ /dev/null
@@ -1,40 +0,0 @@
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ***** END GPL LICENSE BLOCK *****
-
-set(FAAD_EXTRA_ARGS)
-
-if(WIN32)
- set(FAAD_EXTRA_CONFIGURE "utils\\win32\\ac2ver.exe" "faad2" "configure.ac" > libfaad\\win32_ver.h)
-else()
- set(FAAD_EXTRA_CONFIGURE echo .)
-endif()
-
-ExternalProject_Add(external_faad
- URL ${FAAD_URI}
- DOWNLOAD_DIR ${DOWNLOAD_DIR}
- URL_HASH MD5=${FAAD_HASH}
- PREFIX ${BUILD_DIR}/faad
- CONFIGURE_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/faad/src/external_faad/ && ${FAAD_EXTRA_CONFIGURE} && ${CONFIGURE_COMMAND} --disable-shared --enable-static --prefix=${LIBDIR}/faad
- BUILD_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/faad/src/external_faad/ && make -j${MAKE_THREADS}
- INSTALL_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/faad/src/external_faad/ && make install
- INSTALL_DIR ${LIBDIR}/faad
-)
-
-if(MSVC)
- set_target_properties(external_faad PROPERTIES FOLDER Mingw)
-endif()
diff --git a/build_files/build_environment/cmake/ffmpeg.cmake b/build_files/build_environment/cmake/ffmpeg.cmake
index 9ff52914f53..02e78c605af 100644
--- a/build_files/build_environment/cmake/ffmpeg.cmake
+++ b/build_files/build_environment/cmake/ffmpeg.cmake
@@ -127,7 +127,6 @@ endif()
add_dependencies(
external_ffmpeg
external_zlib
- external_faad
external_openjpeg
external_xvidcore
external_x264
diff --git a/build_files/build_environment/cmake/fftw.cmake b/build_files/build_environment/cmake/fftw.cmake
index 2d10cf6ad28..b359df2f47d 100644
--- a/build_files/build_environment/cmake/fftw.cmake
+++ b/build_files/build_environment/cmake/fftw.cmake
@@ -19,8 +19,12 @@
set(FFTW_EXTRA_ARGS)
if(WIN32)
- set(FFTW3_ENV set CFLAGS=-fno-stack-check -fno-stack-protector -mno-stack-arg-probe -fno-lto &&)
set(FFTW3_PATCH_COMMAND ${PATCH_CMD} --verbose -p 0 -N -d ${BUILD_DIR}/fftw3/src/external_fftw3 < ${PATCH_DIR}/fftw3.diff)
+ set(FFTW_EXTRA_ARGS --disable-static --enable-shared)
+ set(FFTW_INSTALL install-strip)
+else()
+ set(FFTW_EXTRA_ARGS --enable-static)
+ set(FFTW_INSTALL install)
endif()
ExternalProject_Add(external_fftw3
@@ -28,10 +32,10 @@ ExternalProject_Add(external_fftw3
DOWNLOAD_DIR ${DOWNLOAD_DIR}
URL_HASH MD5=${FFTW_HASH}
PREFIX ${BUILD_DIR}/fftw3
- CONFIGURE_COMMAND ${CONFIGURE_ENV} && ${FFTW3_ENV} cd ${BUILD_DIR}/fftw3/src/external_fftw3/ && ${CONFIGURE_COMMAND} --enable-static --prefix=${mingw_LIBDIR}/fftw3
+ CONFIGURE_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/fftw3/src/external_fftw3/ && ${CONFIGURE_COMMAND} ${FFTW_EXTRA_ARGS} --prefix=${mingw_LIBDIR}/fftw3
PATCH_COMMAND ${FFTW3_PATCH_COMMAND}
BUILD_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/fftw3/src/external_fftw3/ && make -j${MAKE_THREADS}
- INSTALL_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/fftw3/src/external_fftw3/ && make install
+ INSTALL_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/fftw3/src/external_fftw3/ && make ${FFTW_INSTALL}
INSTALL_DIR ${LIBDIR}/fftw3
)
@@ -39,7 +43,8 @@ if(MSVC)
set_target_properties(external_fftw3 PROPERTIES FOLDER Mingw)
if(BUILD_MODE STREQUAL Release)
ExternalProject_Add_Step(external_fftw3 after_install
- COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/fftw3/lib/libfftw3.a ${HARVEST_TARGET}/fftw3/lib/libfftw.lib
+ COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/fftw3/lib/libfftw3.dll.a ${HARVEST_TARGET}/fftw3/lib/libfftw.lib
+ COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/fftw3/bin/libfftw3-3.dll ${HARVEST_TARGET}/fftw3/lib/libfftw3-3.dll
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/fftw3/include/fftw3.h ${HARVEST_TARGET}/fftw3/include/fftw3.h
DEPENDEES install
)
diff --git a/build_files/build_environment/cmake/harvest.cmake b/build_files/build_environment/cmake/harvest.cmake
index 4d27509890f..d05a06c9518 100644
--- a/build_files/build_environment/cmake/harvest.cmake
+++ b/build_files/build_environment/cmake/harvest.cmake
@@ -44,10 +44,6 @@ if(BUILD_MODE STREQUAL Release)
# glew-> opengl
${CMAKE_COMMAND} -E copy ${LIBDIR}/glew/lib/libglew32.lib ${HARVEST_TARGET}/opengl/lib/glew.lib &&
${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/glew/include/ ${HARVEST_TARGET}/opengl/include/ &&
- # sndfile
- ${CMAKE_COMMAND} -E copy ${LIBDIR}/sndfile/lib/libsndfile.dll.a ${HARVEST_TARGET}/sndfile/lib/libsndfile-1.lib &&
- ${CMAKE_COMMAND} -E copy ${LIBDIR}/sndfile/bin/libsndfile-1.dll ${HARVEST_TARGET}/sndfile/lib/libsndfile-1.dll &&
- ${CMAKE_COMMAND} -E copy ${LIBDIR}/sndfile/include/sndfile.h ${HARVEST_TARGET}/sndfile/include/sndfile.h &&
# tiff
${CMAKE_COMMAND} -E copy ${LIBDIR}/tiff/lib/tiff.lib ${HARVEST_TARGET}/tiff/lib/libtiff.lib &&
${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/tiff/include/ ${HARVEST_TARGET}/tiff/include/ &&
diff --git a/build_files/build_environment/cmake/openal.cmake b/build_files/build_environment/cmake/openal.cmake
index 44f6cdf72a3..315f2e8ba7e 100644
--- a/build_files/build_environment/cmake/openal.cmake
+++ b/build_files/build_environment/cmake/openal.cmake
@@ -52,7 +52,6 @@ if(BUILD_MODE STREQUAL Release)
PREFIX ${BUILD_DIR}/openal
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/openal ${DEFAULT_CMAKE_FLAGS} ${OPENAL_EXTRA_ARGS}
INSTALL_DIR ${LIBDIR}/openal
- PATCH_COMMAND ${PATCH_CMD} -p 1 -d ${BUILD_DIR}/openal/src/external_openal < ${PATCH_DIR}/openal.diff
)
if(WIN32)
diff --git a/build_files/build_environment/cmake/opensubdiv.cmake b/build_files/build_environment/cmake/opensubdiv.cmake
index 9ec849a219b..d183b9f02b7 100644
--- a/build_files/build_environment/cmake/opensubdiv.cmake
+++ b/build_files/build_environment/cmake/opensubdiv.cmake
@@ -67,7 +67,7 @@ endif()
ExternalProject_Add(external_opensubdiv
URL ${OPENSUBDIV_URI}
DOWNLOAD_DIR ${DOWNLOAD_DIR}
- URL_HASH MD5=${OPENSUBDIV_Hash}
+ URL_HASH MD5=${OPENSUBDIV_HASH}
PREFIX ${BUILD_DIR}/opensubdiv
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/opensubdiv -Wno-dev ${DEFAULT_CMAKE_FLAGS} ${OPENSUBDIV_EXTRA_ARGS}
INSTALL_DIR ${LIBDIR}/opensubdiv
diff --git a/build_files/build_environment/cmake/sndfile.cmake b/build_files/build_environment/cmake/sndfile.cmake
index bafd8fe2ac6..df9b14c8887 100644
--- a/build_files/build_environment/cmake/sndfile.cmake
+++ b/build_files/build_environment/cmake/sndfile.cmake
@@ -60,3 +60,14 @@ if(UNIX)
external_flac
)
endif()
+
+if(BUILD_MODE STREQUAL Release AND WIN32)
+ ExternalProject_Add_Step(external_sndfile after_install
+ COMMAND lib /def:${BUILD_DIR}/sndfile/src/external_sndfile/src/libsndfile-1.def /machine:x64 /out:${BUILD_DIR}/sndfile/src/external_sndfile/src/libsndfile-1.lib
+ COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/sndfile/bin/libsndfile-1.dll ${HARVEST_TARGET}/sndfile/lib/libsndfile-1.dll
+ COMMAND ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/sndfile/src/external_sndfile/src/libsndfile-1.lib ${HARVEST_TARGET}/sndfile/lib/libsndfile-1.lib
+ COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/sndfile/include/sndfile.h ${HARVEST_TARGET}/sndfile/include/sndfile.h
+
+ DEPENDEES install
+ )
+endif()
diff --git a/build_files/build_environment/cmake/versions.cmake b/build_files/build_environment/cmake/versions.cmake
index d1e729a29e5..235620019e3 100644
--- a/build_files/build_environment/cmake/versions.cmake
+++ b/build_files/build_environment/cmake/versions.cmake
@@ -20,9 +20,9 @@ set(ZLIB_VERSION 1.2.11)
set(ZLIB_URI https://zlib.net/zlib-${ZLIB_VERSION}.tar.gz)
set(ZLIB_HASH 1c9f62f0778697a09d36121ead88e08e)
-set(OPENAL_VERSION 1.18.2)
+set(OPENAL_VERSION 1.20.1)
set(OPENAL_URI http://openal-soft.org/openal-releases/openal-soft-${OPENAL_VERSION}.tar.bz2)
-set(OPENAL_HASH d4eeb0889812e2fdeaa1843523d76190)
+set(OPENAL_HASH 556695068ce8375b89986083d810fd35)
set(PNG_VERSION 1.6.35)
set(PNG_URI http://prdownloads.sourceforge.net/libpng/libpng-${PNG_VERSION}.tar.xz)
@@ -66,9 +66,9 @@ else()
set(OPENEXR_VERSION_POSTFIX)
endif()
-set(FREETYPE_VERSION 2.10.1)
+set(FREETYPE_VERSION 2.10.2)
set(FREETYPE_URI http://prdownloads.sourceforge.net/freetype/freetype-${FREETYPE_VERSION}.tar.gz)
-set(FREETYPE_HASH c50a3c9e5e62bdc938a6e1598a782947)
+set(FREETYPE_HASH b1cb620e4c875cd4d1bfa04945400945)
set(GLEW_VERSION 1.13.0)
set(GLEW_URI http://prdownloads.sourceforge.net/glew/glew/${GLEW_VERSION}/glew-${GLEW_VERSION}.tgz)
@@ -101,13 +101,13 @@ set(CUEW_GIT_UID 1744972026de9cf27c8a7dc39cf39cd83d5f922f)
set(CUEW_URI https://github.com/CudaWrangler/cuew/archive/${CUEW_GIT_UID}.zip)
set(CUEW_HASH 86760d62978ebfd96cd93f5aa1abaf4a)
-set(OPENSUBDIV_VERSION v3_4_0_RC2)
-set(OPENSUBDIV_Hash f6a10ba9efaa82fde86fe65aad346319)
+set(OPENSUBDIV_VERSION v3_4_3)
set(OPENSUBDIV_URI https://github.com/PixarAnimationStudios/OpenSubdiv/archive/${OPENSUBDIV_VERSION}.tar.gz)
+set(OPENSUBDIV_HASH 7bbfa275d021fb829e521df749160edb)
-set(SDL_VERSION 2.0.8)
+set(SDL_VERSION 2.0.12)
set(SDL_URI https://www.libsdl.org/release/SDL2-${SDL_VERSION}.tar.gz)
-set(SDL_HASH 3800d705cef742c6a634f202c37f263f)
+set(SDL_HASH 783b6f2df8ff02b19bb5ce492b99c8ff)
set(OPENCOLLADA_VERSION v1.6.68)
set(OPENCOLLADA_URI https://github.com/KhronosGroup/OpenCOLLADA/archive/${OPENCOLLADA_VERSION}.tar.gz)
@@ -168,9 +168,9 @@ set(LAME_VERSION 3.100)
set(LAME_URI http://downloads.sourceforge.net/project/lame/lame/3.100/lame-${LAME_VERSION}.tar.gz)
set(LAME_HASH 83e260acbe4389b54fe08e0bdbf7cddb)
-set(OGG_VERSION 1.3.3)
+set(OGG_VERSION 1.3.4)
set(OGG_URI http://downloads.xiph.org/releases/ogg/libogg-${OGG_VERSION}.tar.gz)
-set(OGG_HASH c2e8a485110b97550f453226ec644ebac6cb29d1caef2902c007edab4308d985)
+set(OGG_HASH fe5670640bd49e828d64d2879c31cb4dde9758681bb664f9bdbf159a01b0c76e)
set(VORBIS_VERSION 1.3.6)
set(VORBIS_URI http://downloads.xiph.org/releases/vorbis/libvorbis-${VORBIS_VERSION}.tar.gz)
@@ -180,24 +180,24 @@ set(THEORA_VERSION 1.1.1)
set(THEORA_URI http://downloads.xiph.org/releases/theora/libtheora-${THEORA_VERSION}.tar.bz2)
set(THEORA_HASH b6ae1ee2fa3d42ac489287d3ec34c5885730b1296f0801ae577a35193d3affbc)
-set(FLAC_VERSION 1.3.2)
+set(FLAC_VERSION 1.3.3)
set(FLAC_URI http://downloads.xiph.org/releases/flac/flac-${FLAC_VERSION}.tar.xz)
-set(FLAC_HASH 91cfc3ed61dc40f47f050a109b08610667d73477af6ef36dcad31c31a4a8d53f)
+set(FLAC_HASH 213e82bd716c9de6db2f98bcadbc4c24c7e2efe8c75939a1a84e28539c4e1748)
-set(VPX_VERSION 1.7.0)
+set(VPX_VERSION 1.8.2)
set(VPX_URI https://github.com/webmproject/libvpx/archive/v${VPX_VERSION}/libvpx-v${VPX_VERSION}.tar.gz)
-set(VPX_HASH 1fec931eb5c94279ad219a5b6e0202358e94a93a90cfb1603578c326abfc1238)
+set(VPX_HASH 8735d9fcd1a781ae6917f28f239a8aa358ce4864ba113ea18af4bb2dc8b474ac)
set(OPUS_VERSION 1.3.1)
set(OPUS_URI https://archive.mozilla.org/pub/opus/opus-${OPUS_VERSION}.tar.gz)
set(OPUS_HASH 65b58e1e25b2a114157014736a3d9dfeaad8d41be1c8179866f144a2fb44ff9d)
-set(X264_URI http://download.videolan.org/pub/videolan/x264/snapshots/x264-snapshot-20180811-2245-stable.tar.bz2)
-set(X264_HASH ae8a868a0e236a348b35d79f3ee80294b169d1195408b689f9851383661ed7aa)
+set(X264_URI https://code.videolan.org/videolan/x264/-/archive/master/x264-33f9e1474613f59392be5ab6a7e7abf60fa63622.tar.gz)
+set(X264_HASH 300dfb5b6c35722516f168868ce9419252a9e9eb77a05d82c9cede925b691bd6)
-set(XVIDCORE_VERSION 1.3.5)
-set(XVIDCORE_URI http://downloads.xvid.org/downloads/xvidcore-${XVIDCORE_VERSION}.tar.gz)
-set(XVIDCORE_HASH 165ba6a2a447a8375f7b06db5a3c91810181f2898166e7c8137401d7fc894cf0)
+set(XVIDCORE_VERSION 1.3.7)
+set(XVIDCORE_URI https://downloads.xvid.com/downloads/xvidcore-${XVIDCORE_VERSION}.tar.gz)
+set(XVIDCORE_HASH abbdcbd39555691dd1c9b4d08f0a031376a3b211652c0d8b3b8aa9be1303ce2d)
# This has to be in sync with the version in blenders /extern folder.
set(OPENJPEG_VERSION 2.3.0)
@@ -206,13 +206,9 @@ set(OPENJPEG_SHORT_VERSION 2.3)
set(OPENJPEG_URI https://github.com/uclouvain/openjpeg/archive/66297f07a43.zip)
set(OPENJPEG_HASH 8242b18d908c7c42174e4231a741cfa7ce7c26b6ed5c9644feb9df7b3054310b)
-set(FAAD_VERSION 2-2.8.8)
-set(FAAD_URI http://downloads.sourceforge.net/faac/faad${FAAD_VERSION}.tar.gz)
-set(FAAD_HASH 28f6116efdbe9378269f8a6221767d1f)
-
-set(FFMPEG_VERSION 4.0.2)
+set(FFMPEG_VERSION 4.2.3)
set(FFMPEG_URI http://ffmpeg.org/releases/ffmpeg-${FFMPEG_VERSION}.tar.bz2)
-set(FFMPEG_HASH 5576e8a22f80b6a336db39808f427cfb)
+set(FFMPEG_HASH 695fad11f3baf27784e24cb0e977b65a)
set(FFTW_VERSION 3.3.8)
set(FFTW_URI http://www.fftw.org/fftw-${FFTW_VERSION}.tar.gz)
@@ -319,6 +315,6 @@ set(MESA_VERSION 18.3.1)
set(MESA_URI ftp://ftp.freedesktop.org/pub/mesa//mesa-${MESA_VERSION}.tar.xz)
set(MESA_HASH d60828056d77bfdbae0970f9b15fb1be)
-set(XR_OPENXR_SDK_VERSION 1.0.6)
+set(XR_OPENXR_SDK_VERSION 1.0.8)
set(XR_OPENXR_SDK_URI https://github.com/KhronosGroup/OpenXR-SDK/archive/release-${XR_OPENXR_SDK_VERSION}.tar.gz)
-set(XR_OPENXR_SDK_HASH 21daea7c3bfec365298d779a0e19caa1)
+set(XR_OPENXR_SDK_HASH c6de63d2e0f9029aa58dfa97cad8ce07)
diff --git a/build_files/build_environment/cmake/x264.cmake b/build_files/build_environment/cmake/x264.cmake
index eba0709e196..8bcb5a2938f 100644
--- a/build_files/build_environment/cmake/x264.cmake
+++ b/build_files/build_environment/cmake/x264.cmake
@@ -18,9 +18,6 @@
if(WIN32)
set(X264_EXTRA_ARGS --enable-win32thread --cross-prefix=${MINGW_HOST}- --host=${MINGW_HOST})
- set(X264_PATCH_CMD ${PATCH_CMD} --verbose -p 1 -N -d ${BUILD_DIR}/x264/src/external_x264 < ${PATCH_DIR}/x264.diff)
-else()
- set(X264_PATCH_CMD echo .)
endif()
@@ -29,7 +26,6 @@ ExternalProject_Add(external_x264
DOWNLOAD_DIR ${DOWNLOAD_DIR}
URL_HASH SHA256=${X264_HASH}
PREFIX ${BUILD_DIR}/x264
- PATCH_COMMAND ${X264_PATCH_CMD}
CONFIGURE_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/x264/src/external_x264/ && ${CONFIGURE_COMMAND} --prefix=${LIBDIR}/x264
--enable-static
--enable-pic
diff --git a/build_files/build_environment/patches/openal.diff b/build_files/build_environment/patches/openal.diff
deleted file mode 100644
index 2c9862b95a0..00000000000
--- a/build_files/build_environment/patches/openal.diff
+++ /dev/null
@@ -1,13 +0,0 @@
-diff -Naur external_openal_original/CMakeLists.txt external_openal/CMakeLists.txt
---- external_openal_original/CMakeLists.txt 2016-01-24 20:12:39 -0700
-+++ external_openal/CMakeLists.txt 2018-06-02 12:16:52 -0600
-@@ -885,7 +885,8 @@
- OPTION(ALSOFT_REQUIRE_MMDEVAPI "Require MMDevApi backend" OFF)
- IF(HAVE_WINDOWS_H)
- # Check MMSystem backend
-- CHECK_INCLUDE_FILES("windows.h;mmsystem.h" HAVE_MMSYSTEM_H -D_WIN32_WINNT=0x0502)
-+ set(CMAKE_REQUIRED_FLAGS "-D_WIN32_WINNT=0x0502")
-+ CHECK_INCLUDE_FILES("windows.h;mmsystem.h" HAVE_MMSYSTEM_H)
- IF(HAVE_MMSYSTEM_H)
- CHECK_SHARED_FUNCTION_EXISTS(waveOutOpen "windows.h;mmsystem.h" winmm "" HAVE_LIBWINMM)
- IF(HAVE_LIBWINMM)
diff --git a/build_files/build_environment/patches/x264.diff b/build_files/build_environment/patches/x264.diff
deleted file mode 100644
index 2f2e68083ac..00000000000
--- a/build_files/build_environment/patches/x264.diff
+++ /dev/null
@@ -1,22 +0,0 @@
---- x264-snapshot-20180811-2245-stable\configure 2018-08-11 14:45:05 -0600
-+++ external_x264\configure 2018-08-11 23:51:35 -0600
-@@ -396,7 +396,7 @@
- # list of all preprocessor HAVE values we can define
- CONFIG_HAVE="MALLOC_H ALTIVEC ALTIVEC_H MMX ARMV6 ARMV6T2 NEON BEOSTHREAD POSIXTHREAD WIN32THREAD THREAD LOG2F SWSCALE \
- LAVF FFMS GPAC AVS GPL VECTOREXT INTERLACED CPU_COUNT OPENCL THP LSMASH X86_INLINE_ASM AS_FUNC INTEL_DISPATCHER \
-- MSA MMAP WINRT VSX ARM_INLINE_ASM STRTOK_R BITDEPTH8 BITDEPTH10"
-+ MSA MMAP WINRT VSX ARM_INLINE_ASM BITDEPTH8 BITDEPTH10"
-
- # parse options
-
-@@ -1071,10 +1071,6 @@
- define HAVE_LOG2F
- fi
-
--if cc_check 'string.h' '' 'strtok_r(0, 0, 0);' ; then
-- define HAVE_STRTOK_R
--fi
--
- if [ "$SYS" != "WINDOWS" ] && cpp_check "sys/mman.h unistd.h" "" "defined(MAP_PRIVATE)"; then
- define HAVE_MMAP
- fi
diff --git a/build_files/cmake/config/blender_lite.cmake b/build_files/cmake/config/blender_lite.cmake
index 7c94ce9d672..f3a6d4608fe 100644
--- a/build_files/cmake/config/blender_lite.cmake
+++ b/build_files/cmake/config/blender_lite.cmake
@@ -52,6 +52,7 @@ set(WITH_OPENVDB OFF CACHE BOOL "" FORCE)
set(WITH_QUADRIFLOW OFF CACHE BOOL "" FORCE)
set(WITH_SDL OFF CACHE BOOL "" FORCE)
set(WITH_TBB OFF CACHE BOOL "" FORCE)
+set(WITH_USD OFF CACHE BOOL "" FORCE)
if(UNIX AND NOT APPLE)
set(WITH_GHOST_XDND OFF CACHE BOOL "" FORCE)
diff --git a/build_files/cmake/platform/platform_win32.cmake b/build_files/cmake/platform/platform_win32.cmake
index 1889c9773fb..57bfe19a5bc 100644
--- a/build_files/cmake/platform/platform_win32.cmake
+++ b/build_files/cmake/platform/platform_win32.cmake
@@ -190,7 +190,7 @@ if(MSVC_VERSION GREATER 1914 AND NOT MSVC_CLANG)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /JMC")
endif()
-set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} /SUBSYSTEM:CONSOLE /STACK:2097152 ")
+set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} /SUBSYSTEM:CONSOLE /STACK:2097152")
set(PLATFORM_LINKFLAGS_RELEASE "/NODEFAULTLIB:libcmt.lib /NODEFAULTLIB:libcmtd.lib /NODEFAULTLIB:msvcrtd.lib")
set(PLATFORM_LINKFLAGS_DEBUG "${PLATFORM_LINKFLAGS_DEBUG} /IGNORE:4099 /NODEFAULTLIB:libcmt.lib /NODEFAULTLIB:msvcrt.lib /NODEFAULTLIB:libcmtd.lib")
diff --git a/doc/python_api/requirements.txt b/doc/python_api/requirements.txt
index c2b5b2fd794..263b12eb604 100644
--- a/doc/python_api/requirements.txt
+++ b/doc/python_api/requirements.txt
@@ -1,2 +1,2 @@
-Sphinx==1.8.5
-sphinx_rtd_theme==0.4.3
+Sphinx==3.0.3
+sphinx_rtd_theme==0.5.0rc1
diff --git a/extern/mantaflow/preprocessed/gitinfo.h b/extern/mantaflow/preprocessed/gitinfo.h
index e5cd4a3d6ce..023974fd6cd 100644
--- a/extern/mantaflow/preprocessed/gitinfo.h
+++ b/extern/mantaflow/preprocessed/gitinfo.h
@@ -1,3 +1,3 @@
-#define MANTA_GIT_VERSION "commit b4a2742bd743e2913fba94dd35846042e2650212"
+#define MANTA_GIT_VERSION "commit b61bf9efa7a1d8ca98635076a7e9f2c4dacb2914"
diff --git a/extern/mantaflow/preprocessed/particle.h b/extern/mantaflow/preprocessed/particle.h
index 2d41397a961..d9dd3f49c38 100644
--- a/extern/mantaflow/preprocessed/particle.h
+++ b/extern/mantaflow/preprocessed/particle.h
@@ -469,6 +469,7 @@ template<class S> class ParticleSystem : public ParticleBase {
const int integrationMode,
const bool deleteInObstacle = true,
const bool stopInObstacle = true,
+ const bool skipNew = false,
const ParticleDataImpl<int> *ptype = NULL,
const int exclude = 0);
static PyObject *_W_9(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
@@ -486,13 +487,20 @@ template<class S> class ParticleSystem : public ParticleBase {
const int integrationMode = _args.get<int>("integrationMode", 2, &_lock);
const bool deleteInObstacle = _args.getOpt<bool>("deleteInObstacle", 3, true, &_lock);
const bool stopInObstacle = _args.getOpt<bool>("stopInObstacle", 4, true, &_lock);
+ const bool skipNew = _args.getOpt<bool>("skipNew", 5, false, &_lock);
const ParticleDataImpl<int> *ptype = _args.getPtrOpt<ParticleDataImpl<int>>(
- "ptype", 5, NULL, &_lock);
- const int exclude = _args.getOpt<int>("exclude", 6, 0, &_lock);
+ "ptype", 6, NULL, &_lock);
+ const int exclude = _args.getOpt<int>("exclude", 7, 0, &_lock);
pbo->_args.copy(_args);
_retval = getPyNone();
- pbo->advectInGrid(
- flags, vel, integrationMode, deleteInObstacle, stopInObstacle, ptype, exclude);
+ pbo->advectInGrid(flags,
+ vel,
+ integrationMode,
+ deleteInObstacle,
+ stopInObstacle,
+ skipNew,
+ ptype,
+ exclude);
pbo->_args.check();
}
pbFinalizePlugin(pbo->getParent(), "ParticleSystem::advectInGrid", !noTiming);
@@ -1863,6 +1871,7 @@ template<class S> struct _GridAdvectKernel : public KernelBase {
const Real dt,
const bool deleteInObstacle,
const bool stopInObstacle,
+ const bool skipNew,
const ParticleDataImpl<int> *ptype,
const int exclude,
std::vector<Vec3> &u)
@@ -1873,6 +1882,7 @@ template<class S> struct _GridAdvectKernel : public KernelBase {
dt(dt),
deleteInObstacle(deleteInObstacle),
stopInObstacle(stopInObstacle),
+ skipNew(skipNew),
ptype(ptype),
exclude(exclude),
u(u)
@@ -1885,11 +1895,13 @@ template<class S> struct _GridAdvectKernel : public KernelBase {
const Real dt,
const bool deleteInObstacle,
const bool stopInObstacle,
+ const bool skipNew,
const ParticleDataImpl<int> *ptype,
const int exclude,
std::vector<Vec3> &u) const
{
- if ((p[idx].flag & ParticleBase::PDELETE) || (ptype && ((*ptype)[idx] & exclude))) {
+ if ((p[idx].flag & ParticleBase::PDELETE) || (ptype && ((*ptype)[idx] & exclude)) ||
+ (skipNew && (p[idx].flag & ParticleBase::PNEW))) {
u[idx] = 0.;
return;
}
@@ -1910,7 +1922,7 @@ template<class S> struct _GridAdvectKernel : public KernelBase {
void operator()(const tbb::blocked_range<IndexInt> &__r) const
{
for (IndexInt idx = __r.begin(); idx != (IndexInt)__r.end(); idx++)
- op(idx, p, vel, flags, dt, deleteInObstacle, stopInObstacle, ptype, exclude, u);
+ op(idx, p, vel, flags, dt, deleteInObstacle, stopInObstacle, skipNew, ptype, exclude, u);
}
void run()
{
@@ -1922,6 +1934,7 @@ template<class S> struct _GridAdvectKernel : public KernelBase {
const Real dt;
const bool deleteInObstacle;
const bool stopInObstacle;
+ const bool skipNew;
const ParticleDataImpl<int> *ptype;
const int exclude;
std::vector<Vec3> &u;
@@ -1933,6 +1946,7 @@ template<class S> struct GridAdvectKernel : public KernelBase {
const Real dt,
const bool deleteInObstacle,
const bool stopInObstacle,
+ const bool skipNew,
const ParticleDataImpl<int> *ptype,
const int exclude)
: KernelBase(p.size()),
@@ -1943,6 +1957,7 @@ template<class S> struct GridAdvectKernel : public KernelBase {
dt,
deleteInObstacle,
stopInObstacle,
+ skipNew,
ptype,
exclude,
u),
@@ -1952,6 +1967,7 @@ template<class S> struct GridAdvectKernel : public KernelBase {
dt(dt),
deleteInObstacle(deleteInObstacle),
stopInObstacle(stopInObstacle),
+ skipNew(skipNew),
ptype(ptype),
exclude(exclude),
u((size))
@@ -2001,16 +2017,21 @@ template<class S> struct GridAdvectKernel : public KernelBase {
return stopInObstacle;
}
typedef bool type5;
- inline const ParticleDataImpl<int> *getArg6()
+ inline const bool &getArg6()
+ {
+ return skipNew;
+ }
+ typedef bool type6;
+ inline const ParticleDataImpl<int> *getArg7()
{
return ptype;
}
- typedef ParticleDataImpl<int> type6;
- inline const int &getArg7()
+ typedef ParticleDataImpl<int> type7;
+ inline const int &getArg8()
{
return exclude;
}
- typedef int type7;
+ typedef int type8;
void runMessage()
{
debMsg("Executing kernel GridAdvectKernel ", 3);
@@ -2025,6 +2046,7 @@ template<class S> struct GridAdvectKernel : public KernelBase {
const Real dt;
const bool deleteInObstacle;
const bool stopInObstacle;
+ const bool skipNew;
const ParticleDataImpl<int> *ptype;
const int exclude;
std::vector<Vec3> u;
@@ -2195,6 +2217,7 @@ void ParticleSystem<S>::advectInGrid(const FlagGrid &flags,
const int integrationMode,
const bool deleteInObstacle,
const bool stopInObstacle,
+ const bool skipNew,
const ParticleDataImpl<int> *ptype,
const int exclude)
{
@@ -2208,8 +2231,15 @@ void ParticleSystem<S>::advectInGrid(const FlagGrid &flags,
}
// update positions
- GridAdvectKernel<S> kernel(
- mData, vel, flags, getParent()->getDt(), deleteInObstacle, stopInObstacle, ptype, exclude);
+ GridAdvectKernel<S> kernel(mData,
+ vel,
+ flags,
+ getParent()->getDt(),
+ deleteInObstacle,
+ stopInObstacle,
+ skipNew,
+ ptype,
+ exclude);
integratePointSet(kernel, integrationMode);
if (!deleteInObstacle) {
@@ -2438,15 +2468,15 @@ template<class S> void ParticleSystem<S>::compress()
//! insert buffered positions as new particles, update additional particle data
template<class S> void ParticleSystem<S>::insertBufferedParticles()
{
+ // clear new flag everywhere
+ for (IndexInt i = 0; i < (IndexInt)mData.size(); ++i)
+ mData[i].flag &= ~PNEW;
+
if (mNewBufferPos.size() == 0)
return;
IndexInt newCnt = mData.size();
resizeAll(newCnt + mNewBufferPos.size());
- // clear new flag everywhere
- for (IndexInt i = 0; i < (IndexInt)mData.size(); ++i)
- mData[i].flag &= ~PNEW;
-
for (IndexInt i = 0; i < (IndexInt)mNewBufferPos.size(); ++i) {
int flag = (mNewBufferFlag.size() > 0) ? mNewBufferFlag[i] : 0;
// note, other fields are not initialized here...
diff --git a/intern/cycles/blender/addon/__init__.py b/intern/cycles/blender/addon/__init__.py
index 3d2a52d0cf6..3ab352e52a2 100644
--- a/intern/cycles/blender/addon/__init__.py
+++ b/intern/cycles/blender/addon/__init__.py
@@ -82,8 +82,8 @@ class CyclesRender(bpy.types.RenderEngine):
def render(self, depsgraph):
engine.render(self, depsgraph)
- def bake(self, depsgraph, obj, pass_type, pass_filter, object_id, pixel_array, num_pixels, depth, result):
- engine.bake(self, depsgraph, obj, pass_type, pass_filter, object_id, pixel_array, num_pixels, depth, result)
+ def bake(self, depsgraph, obj, pass_type, pass_filter, width, height):
+ engine.bake(self, depsgraph, obj, pass_type, pass_filter, width, height)
# viewport render
def view_update(self, context, depsgraph):
diff --git a/intern/cycles/blender/addon/engine.py b/intern/cycles/blender/addon/engine.py
index a1b063430f5..e7ea5e7a1f6 100644
--- a/intern/cycles/blender/addon/engine.py
+++ b/intern/cycles/blender/addon/engine.py
@@ -168,11 +168,11 @@ def render(engine, depsgraph):
_cycles.render(engine.session, depsgraph.as_pointer())
-def bake(engine, depsgraph, obj, pass_type, pass_filter, object_id, pixel_array, num_pixels, depth, result):
+def bake(engine, depsgraph, obj, pass_type, pass_filter, width, height):
import _cycles
session = getattr(engine, "session", None)
if session is not None:
- _cycles.bake(engine.session, depsgraph.as_pointer(), obj.as_pointer(), pass_type, pass_filter, object_id, pixel_array.as_pointer(), num_pixels, depth, result.as_pointer())
+ _cycles.bake(engine.session, depsgraph.as_pointer(), obj.as_pointer(), pass_type, pass_filter, width, height)
def reset(engine, data, depsgraph):
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py
index 08641c05941..a15daee706f 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -1907,10 +1907,15 @@ class CYCLES_RENDER_PT_bake_selected_to_active(CyclesButtonsPanel, Panel):
col.prop(cbk, "use_cage", text="Cage")
if cbk.use_cage:
- col.prop(cbk, "cage_extrusion", text="Extrusion")
- col.prop(cbk, "cage_object", text="Cage Object")
+ col.prop(cbk, "cage_object")
+ col = layout.column()
+ col.prop(cbk, "cage_extrusion")
+ col.active = cbk.cage_object is None
else:
- col.prop(cbk, "cage_extrusion", text="Ray Distance")
+ col.prop(cbk, "cage_extrusion", text="Extrusion")
+
+ col = layout.column()
+ col.prop(cbk, "max_ray_distance")
class CYCLES_RENDER_PT_bake_output(CyclesButtonsPanel, Panel):
diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp
index 4b29c28913b..a461982a538 100644
--- a/intern/cycles/blender/blender_object.cpp
+++ b/intern/cycles/blender/blender_object.cpp
@@ -460,9 +460,12 @@ void BlenderSync::sync_motion(BL::RenderSettings &b_render,
sync_objects(b_depsgraph, b_v3d, 0.0f);
}
- /* always sample these times for camera motion */
- motion_times.insert(-1.0f);
- motion_times.insert(1.0f);
+ /* Insert motion times from camera. Motion times from other objects
+ * have already been added in a sync_objects call. */
+ uint camera_motion_steps = object_motion_steps(b_cam, b_cam);
+ for (size_t step = 0; step < camera_motion_steps; step++) {
+ motion_times.insert(scene->camera->motion_time(step));
+ }
/* note iteration over motion_times set happens in sorted order */
foreach (float relative_time, motion_times) {
@@ -487,10 +490,8 @@ void BlenderSync::sync_motion(BL::RenderSettings &b_render,
b_engine.frame_set(frame, subframe);
python_thread_state_save(python_thread_state);
- /* sync camera, only supports two times at the moment */
- if (relative_time == -1.0f || relative_time == 1.0f) {
- sync_camera_motion(b_render, b_cam, width, height, relative_time);
- }
+ /* Syncs camera motion if relative_time is one of the camera's motion times. */
+ sync_camera_motion(b_render, b_cam, width, height, relative_time);
/* sync object */
sync_objects(b_depsgraph, b_v3d, relative_time);
diff --git a/intern/cycles/blender/blender_python.cpp b/intern/cycles/blender/blender_python.cpp
index 8c7c0bc1daa..79c16856462 100644
--- a/intern/cycles/blender/blender_python.cpp
+++ b/intern/cycles/blender/blender_python.cpp
@@ -298,22 +298,18 @@ static PyObject *render_func(PyObject * /*self*/, PyObject *args)
static PyObject *bake_func(PyObject * /*self*/, PyObject *args)
{
PyObject *pysession, *pydepsgraph, *pyobject;
- PyObject *pypixel_array, *pyresult;
const char *pass_type;
- int num_pixels, depth, object_id, pass_filter;
+ int pass_filter, width, height;
if (!PyArg_ParseTuple(args,
- "OOOsiiOiiO",
+ "OOOsiii",
&pysession,
&pydepsgraph,
&pyobject,
&pass_type,
&pass_filter,
- &object_id,
- &pypixel_array,
- &num_pixels,
- &depth,
- &pyresult))
+ &width,
+ &height))
return NULL;
BlenderSession *session = (BlenderSession *)PyLong_AsVoidPtr(pysession);
@@ -326,23 +322,9 @@ static PyObject *bake_func(PyObject * /*self*/, PyObject *args)
RNA_id_pointer_create((ID *)PyLong_AsVoidPtr(pyobject), &objectptr);
BL::Object b_object(objectptr);
- void *b_result = PyLong_AsVoidPtr(pyresult);
-
- PointerRNA bakepixelptr;
- RNA_pointer_create(NULL, &RNA_BakePixel, PyLong_AsVoidPtr(pypixel_array), &bakepixelptr);
- BL::BakePixel b_bake_pixel(bakepixelptr);
-
python_thread_state_save(&session->python_thread_state);
- session->bake(b_depsgraph,
- b_object,
- pass_type,
- pass_filter,
- object_id,
- b_bake_pixel,
- (size_t)num_pixels,
- depth,
- (float *)b_result);
+ session->bake(b_depsgraph, b_object, pass_type, pass_filter, width, height);
python_thread_state_restore(&session->python_thread_state);
diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp
index 5ea96d6bdfd..31b09695632 100644
--- a/intern/cycles/blender/blender_session.cpp
+++ b/intern/cycles/blender/blender_session.cpp
@@ -247,9 +247,7 @@ void BlenderSession::reset_session(BL::BlendData &b_data, BL::Depsgraph &b_depsg
void BlenderSession::free_session()
{
- if (sync)
- delete sync;
-
+ delete sync;
delete session;
}
@@ -317,6 +315,7 @@ static void end_render_result(BL::RenderEngine &b_engine,
void BlenderSession::do_write_update_render_tile(RenderTile &rtile,
bool do_update_only,
+ bool do_read_only,
bool highlight)
{
int x = rtile.x - session->tile_manager.params.full_x;
@@ -342,7 +341,23 @@ void BlenderSession::do_write_update_render_tile(RenderTile &rtile,
BL::RenderLayer b_rlay = *b_single_rlay;
- if (do_update_only) {
+ if (do_read_only) {
+ /* copy each pass */
+ BL::RenderLayer::passes_iterator b_iter;
+
+ for (b_rlay.passes.begin(b_iter); b_iter != b_rlay.passes.end(); ++b_iter) {
+ BL::RenderPass b_pass(*b_iter);
+
+ /* find matching pass type */
+ PassType pass_type = BlenderSync::get_pass_type(b_pass);
+ int components = b_pass.channels();
+
+ rtile.buffers->set_pass_rect(pass_type, components, (float *)b_pass.rect());
+ }
+
+ end_render_result(b_engine, b_rr, false, false, false);
+ }
+ else if (do_update_only) {
/* Sample would be zero at initial tile update, which is only needed
* to tag tile form blender side as IN PROGRESS for proper highlight
* no buffers should be sent to blender yet. For denoise we also
@@ -362,9 +377,14 @@ void BlenderSession::do_write_update_render_tile(RenderTile &rtile,
}
}
+void BlenderSession::read_render_tile(RenderTile &rtile)
+{
+ do_write_update_render_tile(rtile, false, true, false);
+}
+
void BlenderSession::write_render_tile(RenderTile &rtile)
{
- do_write_update_render_tile(rtile, false, false);
+ do_write_update_render_tile(rtile, false, false, false);
}
void BlenderSession::update_render_tile(RenderTile &rtile, bool highlight)
@@ -374,9 +394,9 @@ void BlenderSession::update_render_tile(RenderTile &rtile, bool highlight)
* would need to be investigated a bit further, but for now shall be fine
*/
if (!b_engine.is_preview())
- do_write_update_render_tile(rtile, true, highlight);
+ do_write_update_render_tile(rtile, true, false, highlight);
else
- do_write_update_render_tile(rtile, false, false);
+ do_write_update_render_tile(rtile, false, false, false);
}
static void add_cryptomatte_layer(BL::RenderResult &b_rr, string name, string manifest)
@@ -593,25 +613,6 @@ void BlenderSession::render(BL::Depsgraph &b_depsgraph_)
#endif
}
-static void populate_bake_data(BakeData *data,
- const int object_id,
- BL::BakePixel &pixel_array,
- const int num_pixels)
-{
- BL::BakePixel bp = pixel_array;
-
- int i;
- for (i = 0; i < num_pixels; i++) {
- if (bp.object_id() == object_id) {
- data->set(i, bp.primitive_id(), bp.uv(), bp.du_dx(), bp.du_dy(), bp.dv_dx(), bp.dv_dy());
- }
- else {
- data->set_null(i);
- }
- bp = bp.next();
- }
-}
-
static int bake_pass_filter_get(const int pass_filter)
{
int flag = BAKE_FILTER_NONE;
@@ -642,43 +643,26 @@ void BlenderSession::bake(BL::Depsgraph &b_depsgraph_,
BL::Object &b_object,
const string &pass_type,
const int pass_filter,
- const int object_id,
- BL::BakePixel &pixel_array,
- const size_t num_pixels,
- const int /*depth*/,
- float result[])
+ const int bake_width,
+ const int bake_height)
{
b_depsgraph = b_depsgraph_;
ShaderEvalType shader_type = get_shader_type(pass_type);
-
- /* Set baking flag in advance, so kernel loading can check if we need
- * any baking capabilities.
- */
- scene->bake_manager->set_baking(true);
-
- /* ensure kernels are loaded before we do any scene updates */
- session->load_kernels();
-
- if (shader_type == SHADER_EVAL_UV) {
- /* force UV to be available */
- Pass::add(PASS_UV, scene->film->passes);
- }
-
int bake_pass_filter = bake_pass_filter_get(pass_filter);
- bake_pass_filter = BakeManager::shader_type_to_pass_filter(shader_type, bake_pass_filter);
- /* force use_light_pass to be true if we bake more than just colors */
- if (bake_pass_filter & ~BAKE_FILTER_COLOR) {
- Pass::add(PASS_LIGHT, scene->film->passes);
- }
+ /* Initialize bake manager, before we load the baking kernels. */
+ scene->bake_manager->set(scene, b_object.name(), shader_type, bake_pass_filter);
- /* create device and update scene */
- scene->film->tag_update(scene);
- scene->integrator->tag_update(scene);
+ /* Passes are identified by name, so in order to return the combined pass we need to set the
+ * name. */
+ Pass::add(PASS_COMBINED, scene->film->passes, "Combined");
+
+ session->read_bake_tile_cb = function_bind(&BlenderSession::read_render_tile, this, _1);
+ session->write_render_tile_cb = function_bind(&BlenderSession::write_render_tile, this, _1);
if (!session->progress.get_cancel()) {
- /* update scene */
+ /* Sync scene. */
BL::Object b_camera_override(b_engine.camera_override());
sync->sync_camera(b_render, b_camera_override, width, height, "");
sync->sync_data(
@@ -686,75 +670,43 @@ void BlenderSession::bake(BL::Depsgraph &b_depsgraph_,
builtin_images_load();
}
- BakeData *bake_data = NULL;
+ /* Object might have been disabled for rendering or excluded in some
+ * other way, in that case Blender will report a warning afterwards. */
+ bool object_found = false;
+ foreach (Object *ob, scene->objects) {
+ if (ob->name == b_object.name()) {
+ object_found = true;
+ break;
+ }
+ }
- if (!session->progress.get_cancel()) {
- /* get buffer parameters */
+ if (object_found && !session->progress.get_cancel()) {
+ /* Get session and buffer parameters. */
SessionParams session_params = BlenderSync::get_session_params(
b_engine, b_userpref, b_scene, background);
- BufferParams buffer_params = BlenderSync::get_buffer_params(
- b_scene, b_render, b_v3d, b_rv3d, scene->camera, width, height);
+ session_params.progressive_refine = false;
- scene->bake_manager->set_shader_limit((size_t)b_engine.tile_x(), (size_t)b_engine.tile_y());
+ BufferParams buffer_params;
+ buffer_params.width = bake_width;
+ buffer_params.height = bake_height;
+ buffer_params.passes = scene->film->passes;
- /* set number of samples */
+ /* Update session. */
session->tile_manager.set_samples(session_params.samples);
session->reset(buffer_params, session_params.samples);
- session->update_scene();
-
- /* find object index. todo: is arbitrary - copied from mesh_displace.cpp */
- size_t object_index = OBJECT_NONE;
- int tri_offset = 0;
-
- for (size_t i = 0; i < scene->objects.size(); i++) {
- const Object *object = scene->objects[i];
- const Geometry *geom = object->geometry;
- if (object->name == b_object.name() && geom->type == Geometry::MESH) {
- const Mesh *mesh = static_cast<const Mesh *>(geom);
- object_index = i;
- tri_offset = mesh->prim_offset;
- break;
- }
- }
-
- /* Object might have been disabled for rendering or excluded in some
- * other way, in that case Blender will report a warning afterwards. */
- if (object_index != OBJECT_NONE) {
- int object = object_index;
-
- bake_data = scene->bake_manager->init(object, tri_offset, num_pixels);
- populate_bake_data(bake_data, object_id, pixel_array, num_pixels);
- }
-
- /* set number of samples */
- session->tile_manager.set_samples(session_params.samples);
- session->reset(buffer_params, session_params.samples);
- session->update_scene();
session->progress.set_update_callback(
function_bind(&BlenderSession::update_bake_progress, this));
}
/* Perform bake. Check cancel to avoid crash with incomplete scene data. */
- if (!session->progress.get_cancel() && bake_data) {
- scene->bake_manager->bake(scene->device,
- &scene->dscene,
- scene,
- session->progress,
- shader_type,
- bake_pass_filter,
- bake_data,
- result);
+ if (object_found && !session->progress.get_cancel()) {
+ session->start();
+ session->wait();
}
- /* free all memory used (host and device), so we wouldn't leave render
- * engine with extra memory allocated
- */
-
- session->device_free();
-
- delete sync;
- sync = NULL;
+ session->read_bake_tile_cb = function_null;
+ session->write_render_tile_cb = function_null;
}
void BlenderSession::do_write_update_render_result(BL::RenderLayer &b_rlay,
diff --git a/intern/cycles/blender/blender_session.h b/intern/cycles/blender/blender_session.h
index 3e6498bb655..34e952e312b 100644
--- a/intern/cycles/blender/blender_session.h
+++ b/intern/cycles/blender/blender_session.h
@@ -66,14 +66,12 @@ class BlenderSession {
BL::Object &b_object,
const string &pass_type,
const int custom_flag,
- const int object_id,
- BL::BakePixel &pixel_array,
- const size_t num_pixels,
- const int depth,
- float pixels[]);
+ const int bake_width,
+ const int bake_height);
void write_render_result(BL::RenderLayer &b_rlay, RenderTile &rtile);
void write_render_tile(RenderTile &rtile);
+ void read_render_tile(RenderTile &rtile);
/* update functions are used to update display buffer only after sample was rendered
* only needed for better visual feedback */
@@ -155,7 +153,10 @@ class BlenderSession {
void do_write_update_render_result(BL::RenderLayer &b_rlay,
RenderTile &rtile,
bool do_update_only);
- void do_write_update_render_tile(RenderTile &rtile, bool do_update_only, bool highlight);
+ void do_write_update_render_tile(RenderTile &rtile,
+ bool do_update_only,
+ bool do_read_only,
+ bool highlight);
void builtin_images_load();
diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp
index e8031be7dd1..f16305e737d 100644
--- a/intern/cycles/blender/blender_sync.cpp
+++ b/intern/cycles/blender/blender_sync.cpp
@@ -481,6 +481,9 @@ PassType BlenderSync::get_pass_type(BL::RenderPass &b_pass)
MAP_PASS("AO", PASS_AO);
MAP_PASS("Shadow", PASS_SHADOW);
+ MAP_PASS("BakePrimitive", PASS_BAKE_PRIMITIVE);
+ MAP_PASS("BakeDifferential", PASS_BAKE_DIFFERENTIAL);
+
#ifdef __KERNEL_DEBUG__
MAP_PASS("Debug BVH Traversed Nodes", PASS_BVH_TRAVERSED_NODES);
MAP_PASS("Debug BVH Traversed Instances", PASS_BVH_TRAVERSED_INSTANCES);
diff --git a/intern/cycles/blender/blender_volume.cpp b/intern/cycles/blender/blender_volume.cpp
index 6254a1a1b24..4eed6be8c7c 100644
--- a/intern/cycles/blender/blender_volume.cpp
+++ b/intern/cycles/blender/blender_volume.cpp
@@ -34,15 +34,13 @@ CCL_NAMESPACE_BEGIN
/* TODO: verify this is not loading unnecessary attributes. */
class BlenderSmokeLoader : public ImageLoader {
public:
- BlenderSmokeLoader(const BL::Object &b_ob, AttributeStandard attribute)
- : b_ob(b_ob), attribute(attribute)
+ BlenderSmokeLoader(BL::Object &b_ob, AttributeStandard attribute)
+ : b_domain(object_fluid_gas_domain_find(b_ob)), b_mesh(b_ob.data()), attribute(attribute)
{
}
bool load_metadata(ImageMetaData &metadata) override
{
- BL::FluidDomainSettings b_domain = object_fluid_gas_domain_find(b_ob);
-
if (!b_domain) {
return false;
}
@@ -79,7 +77,6 @@ class BlenderSmokeLoader : public ImageLoader {
/* Create a matrix to transform from object space to mesh texture space.
* This does not work with deformations but that can probably only be done
* well with a volume grid mapping of coordinates. */
- BL::Mesh b_mesh(b_ob.data());
float3 loc, size;
mesh_texture_space(b_mesh, loc, size);
metadata.transform_3d = transform_translate(-loc) * transform_scale(size);
@@ -90,9 +87,6 @@ class BlenderSmokeLoader : public ImageLoader {
bool load_pixels(const ImageMetaData &, void *pixels, const size_t, const bool) override
{
- /* smoke volume data */
- BL::FluidDomainSettings b_domain = object_fluid_gas_domain_find(b_ob);
-
if (!b_domain) {
return false;
}
@@ -179,10 +173,11 @@ class BlenderSmokeLoader : public ImageLoader {
bool equals(const ImageLoader &other) const override
{
const BlenderSmokeLoader &other_loader = (const BlenderSmokeLoader &)other;
- return b_ob == other_loader.b_ob && attribute == other_loader.attribute;
+ return b_domain == other_loader.b_domain && attribute == other_loader.attribute;
}
- BL::Object b_ob;
+ BL::FluidDomainSettings b_domain;
+ BL::Mesh b_mesh;
AttributeStandard attribute;
};
diff --git a/intern/cycles/device/cuda/device_cuda.h b/intern/cycles/device/cuda/device_cuda.h
index 3e397da895b..3f23f0fe4c5 100644
--- a/intern/cycles/device/cuda/device_cuda.h
+++ b/intern/cycles/device/cuda/device_cuda.h
@@ -223,7 +223,7 @@ class CUDADevice : public Device {
CUdeviceptr d_wtile,
CUstream stream = 0);
- void path_trace(DeviceTask &task, RenderTile &rtile, device_vector<WorkTile> &work_tiles);
+ void render(DeviceTask &task, RenderTile &rtile, device_vector<WorkTile> &work_tiles);
void film_convert(DeviceTask &task,
device_ptr buffer,
diff --git a/intern/cycles/device/cuda/device_cuda_impl.cpp b/intern/cycles/device/cuda/device_cuda_impl.cpp
index ba5d479e0e7..acf53c3eb1b 100644
--- a/intern/cycles/device/cuda/device_cuda_impl.cpp
+++ b/intern/cycles/device/cuda/device_cuda_impl.cpp
@@ -586,20 +586,23 @@ void CUDADevice::reserve_local_memory(const DeviceRequestedFeatures &requested_f
cuMemGetInfo(&free_before, &total);
/* Get kernel function. */
- CUfunction cuPathTrace;
+ CUfunction cuRender;
- if (requested_features.use_integrator_branched) {
- cuda_assert(cuModuleGetFunction(&cuPathTrace, cuModule, "kernel_cuda_branched_path_trace"));
+ if (requested_features.use_baking) {
+ cuda_assert(cuModuleGetFunction(&cuRender, cuModule, "kernel_cuda_bake"));
+ }
+ else if (requested_features.use_integrator_branched) {
+ cuda_assert(cuModuleGetFunction(&cuRender, cuModule, "kernel_cuda_branched_path_trace"));
}
else {
- cuda_assert(cuModuleGetFunction(&cuPathTrace, cuModule, "kernel_cuda_path_trace"));
+ cuda_assert(cuModuleGetFunction(&cuRender, cuModule, "kernel_cuda_path_trace"));
}
- cuda_assert(cuFuncSetCacheConfig(cuPathTrace, CU_FUNC_CACHE_PREFER_L1));
+ cuda_assert(cuFuncSetCacheConfig(cuRender, CU_FUNC_CACHE_PREFER_L1));
int min_blocks, num_threads_per_block;
- cuda_assert(cuOccupancyMaxPotentialBlockSize(
- &min_blocks, &num_threads_per_block, cuPathTrace, NULL, 0, 0));
+ cuda_assert(
+ cuOccupancyMaxPotentialBlockSize(&min_blocks, &num_threads_per_block, cuRender, NULL, 0, 0));
/* Launch kernel, using just 1 block appears sufficient to reserve
* memory for all multiprocessors. It would be good to do this in
@@ -609,7 +612,7 @@ void CUDADevice::reserve_local_memory(const DeviceRequestedFeatures &requested_f
void *args[] = {&d_work_tiles, &total_work_size};
- cuda_assert(cuLaunchKernel(cuPathTrace, 1, 1, 1, num_threads_per_block, 1, 1, 0, 0, args, 0));
+ cuda_assert(cuLaunchKernel(cuRender, 1, 1, 1, num_threads_per_block, 1, 1, 0, 0, args, 0));
cuda_assert(cuCtxSynchronize());
@@ -1780,9 +1783,7 @@ void CUDADevice::adaptive_sampling_post(RenderTile &rtile,
0));
}
-void CUDADevice::path_trace(DeviceTask &task,
- RenderTile &rtile,
- device_vector<WorkTile> &work_tiles)
+void CUDADevice::render(DeviceTask &task, RenderTile &rtile, device_vector<WorkTile> &work_tiles)
{
scoped_timer timer(&rtile.buffers->render_time);
@@ -1790,21 +1791,24 @@ void CUDADevice::path_trace(DeviceTask &task,
return;
CUDAContextScope scope(this);
- CUfunction cuPathTrace;
+ CUfunction cuRender;
/* Get kernel function. */
- if (task.integrator_branched) {
- cuda_assert(cuModuleGetFunction(&cuPathTrace, cuModule, "kernel_cuda_branched_path_trace"));
+ if (rtile.task == RenderTile::BAKE) {
+ cuda_assert(cuModuleGetFunction(&cuRender, cuModule, "kernel_cuda_bake"));
+ }
+ else if (task.integrator_branched) {
+ cuda_assert(cuModuleGetFunction(&cuRender, cuModule, "kernel_cuda_branched_path_trace"));
}
else {
- cuda_assert(cuModuleGetFunction(&cuPathTrace, cuModule, "kernel_cuda_path_trace"));
+ cuda_assert(cuModuleGetFunction(&cuRender, cuModule, "kernel_cuda_path_trace"));
}
if (have_error()) {
return;
}
- cuda_assert(cuFuncSetCacheConfig(cuPathTrace, CU_FUNC_CACHE_PREFER_L1));
+ cuda_assert(cuFuncSetCacheConfig(cuRender, CU_FUNC_CACHE_PREFER_L1));
/* Allocate work tile. */
work_tiles.alloc(1);
@@ -1822,8 +1826,8 @@ void CUDADevice::path_trace(DeviceTask &task,
* remain conservative for GPUs connected to a display to avoid driver
* timeouts and display freezing. */
int min_blocks, num_threads_per_block;
- cuda_assert(cuOccupancyMaxPotentialBlockSize(
- &min_blocks, &num_threads_per_block, cuPathTrace, NULL, 0, 0));
+ cuda_assert(
+ cuOccupancyMaxPotentialBlockSize(&min_blocks, &num_threads_per_block, cuRender, NULL, 0, 0));
if (!info.display_device) {
min_blocks *= 8;
}
@@ -1851,7 +1855,7 @@ void CUDADevice::path_trace(DeviceTask &task,
void *args[] = {&d_work_tiles, &total_work_size};
cuda_assert(
- cuLaunchKernel(cuPathTrace, num_blocks, 1, 1, num_threads_per_block, 1, 1, 0, 0, args, 0));
+ cuLaunchKernel(cuRender, num_blocks, 1, 1, num_threads_per_block, 1, 1, 0, 0, args, 0));
/* Run the adaptive sampling kernels at selected samples aligned to step samples. */
uint filter_sample = sample + wtile->num_samples - 1;
@@ -1957,10 +1961,7 @@ void CUDADevice::shader(DeviceTask &task)
CUdeviceptr d_output = (CUdeviceptr)task.shader_output;
/* get kernel function */
- if (task.shader_eval_type >= SHADER_EVAL_BAKE) {
- cuda_assert(cuModuleGetFunction(&cuShader, cuModule, "kernel_cuda_bake"));
- }
- else if (task.shader_eval_type == SHADER_EVAL_DISPLACE) {
+ if (task.shader_eval_type == SHADER_EVAL_DISPLACE) {
cuda_assert(cuModuleGetFunction(&cuShader, cuModule, "kernel_cuda_displace"));
}
else {
@@ -2297,9 +2298,12 @@ void CUDADevice::thread_run(DeviceTask *task)
split_kernel->path_trace(task, tile, void_buffer, void_buffer);
}
else {
- path_trace(*task, tile, work_tiles);
+ render(*task, tile, work_tiles);
}
}
+ else if (tile.task == RenderTile::BAKE) {
+ render(*task, tile, work_tiles);
+ }
else if (tile.task == RenderTile::DENOISE) {
tile.sample = tile.start_sample + tile.num_samples;
diff --git a/intern/cycles/device/device_cpu.cpp b/intern/cycles/device/device_cpu.cpp
index c701c14318f..fc6febd8cee 100644
--- a/intern/cycles/device/device_cpu.cpp
+++ b/intern/cycles/device/device_cpu.cpp
@@ -188,6 +188,7 @@ class CPUDevice : public Device {
convert_to_byte_kernel;
KernelFunctions<void (*)(KernelGlobals *, uint4 *, float4 *, int, int, int, int, int)>
shader_kernel;
+ KernelFunctions<void (*)(KernelGlobals *, float *, int, int, int, int, int)> bake_kernel;
KernelFunctions<void (*)(
int, TileInfo *, int, int, float *, float *, float *, float *, float *, int *, int, int)>
@@ -270,6 +271,7 @@ class CPUDevice : public Device {
REGISTER_KERNEL(convert_to_half_float),
REGISTER_KERNEL(convert_to_byte),
REGISTER_KERNEL(shader),
+ REGISTER_KERNEL(bake),
REGISTER_KERNEL(filter_divide_shadow),
REGISTER_KERNEL(filter_get_feature),
REGISTER_KERNEL(filter_write_feature),
@@ -895,7 +897,7 @@ class CPUDevice : public Device {
}
}
- void path_trace(DeviceTask &task, RenderTile &tile, KernelGlobals *kg)
+ void render(DeviceTask &task, RenderTile &tile, KernelGlobals *kg)
{
const bool use_coverage = kernel_data.film.cryptomatte_passes & CRYPT_ACCURATE;
@@ -919,12 +921,21 @@ class CPUDevice : public Device {
break;
}
- for (int y = tile.y; y < tile.y + tile.h; y++) {
- for (int x = tile.x; x < tile.x + tile.w; x++) {
- if (use_coverage) {
- coverage.init_pixel(x, y);
+ if (tile.task == RenderTile::PATH_TRACE) {
+ for (int y = tile.y; y < tile.y + tile.h; y++) {
+ for (int x = tile.x; x < tile.x + tile.w; x++) {
+ if (use_coverage) {
+ coverage.init_pixel(x, y);
+ }
+ path_trace_kernel()(kg, render_buffer, sample, x, y, tile.offset, tile.stride);
+ }
+ }
+ }
+ else {
+ for (int y = tile.y; y < tile.y + tile.h; y++) {
+ for (int x = tile.x; x < tile.x + tile.w; x++) {
+ bake_kernel()(kg, render_buffer, sample, x, y, tile.offset, tile.stride);
}
- path_trace_kernel()(kg, render_buffer, sample, x, y, tile.offset, tile.stride);
}
}
tile.sample = sample + 1;
@@ -1019,9 +1030,12 @@ class CPUDevice : public Device {
split_kernel->path_trace(&task, tile, kgbuffer, void_buffer);
}
else {
- path_trace(task, tile, kg);
+ render(task, tile, kg);
}
}
+ else if (tile.task == RenderTile::BAKE) {
+ render(task, tile, kg);
+ }
else if (tile.task == RenderTile::DENOISE) {
denoise(denoising, tile);
task.update_progress(&tile, tile.w * tile.h);
diff --git a/intern/cycles/device/opencl/device_opencl.h b/intern/cycles/device/opencl/device_opencl.h
index d6f4fb43061..389268e1c2a 100644
--- a/intern/cycles/device/opencl/device_opencl.h
+++ b/intern/cycles/device/opencl/device_opencl.h
@@ -451,6 +451,7 @@ class OpenCLDevice : public Device {
device_ptr rgba_half);
void shader(DeviceTask &task);
void update_adaptive(DeviceTask &task, RenderTile &tile, int sample);
+ void bake(DeviceTask &task, RenderTile &tile);
void denoise(RenderTile &tile, DenoisingTask &denoising);
diff --git a/intern/cycles/device/opencl/device_opencl_impl.cpp b/intern/cycles/device/opencl/device_opencl_impl.cpp
index 2766f85d17c..beb3174b111 100644
--- a/intern/cycles/device/opencl/device_opencl_impl.cpp
+++ b/intern/cycles/device/opencl/device_opencl_impl.cpp
@@ -1367,6 +1367,9 @@ void OpenCLDevice::thread_run(DeviceTask *task)
*/
clFinish(cqCommandQueue);
}
+ else if (tile.task == RenderTile::BAKE) {
+ bake(*task, tile);
+ }
else if (tile.task == RenderTile::DENOISE) {
tile.sample = tile.start_sample + tile.num_samples;
denoise(tile, denoising);
@@ -1858,10 +1861,7 @@ void OpenCLDevice::shader(DeviceTask &task)
cl_int d_offset = task.offset;
OpenCLDevice::OpenCLProgram *program = &background_program;
- if (task.shader_eval_type >= SHADER_EVAL_BAKE) {
- program = &bake_program;
- }
- else if (task.shader_eval_type == SHADER_EVAL_DISPLACE) {
+ if (task.shader_eval_type == SHADER_EVAL_DISPLACE) {
program = &displace_program;
}
program->wait_for_availability();
@@ -1892,6 +1892,51 @@ void OpenCLDevice::shader(DeviceTask &task)
}
}
+void OpenCLDevice::bake(DeviceTask &task, RenderTile &rtile)
+{
+ scoped_timer timer(&rtile.buffers->render_time);
+
+ /* Cast arguments to cl types. */
+ cl_mem d_data = CL_MEM_PTR(const_mem_map["__data"]->device_pointer);
+ cl_mem d_buffer = CL_MEM_PTR(rtile.buffer);
+ cl_int d_x = rtile.x;
+ cl_int d_y = rtile.y;
+ cl_int d_w = rtile.w;
+ cl_int d_h = rtile.h;
+ cl_int d_offset = rtile.offset;
+ cl_int d_stride = rtile.stride;
+
+ bake_program.wait_for_availability();
+ cl_kernel kernel = bake_program();
+
+ cl_uint start_arg_index = kernel_set_args(kernel, 0, d_data, d_buffer);
+
+ set_kernel_arg_buffers(kernel, &start_arg_index);
+
+ start_arg_index += kernel_set_args(
+ kernel, start_arg_index, d_x, d_y, d_w, d_h, d_offset, d_stride);
+
+ int start_sample = rtile.start_sample;
+ int end_sample = rtile.start_sample + rtile.num_samples;
+
+ for (int sample = start_sample; sample < end_sample; sample++) {
+ if (task.get_cancel()) {
+ if (task.need_finish_queue == false)
+ break;
+ }
+
+ kernel_set_args(kernel, start_arg_index, sample);
+
+ enqueue_kernel(kernel, d_w, d_h);
+
+ rtile.sample = sample + 1;
+
+ task.update_progress(&rtile, rtile.w * rtile.h);
+ }
+
+ clFinish(cqCommandQueue);
+}
+
string OpenCLDevice::kernel_build_options(const string *debug_src)
{
string build_options = "-cl-no-signed-zeros -cl-mad-enable ";
diff --git a/intern/cycles/kernel/kernel_bake.h b/intern/cycles/kernel/kernel_bake.h
index f1fc697553a..2709a9da734 100644
--- a/intern/cycles/kernel/kernel_bake.h
+++ b/intern/cycles/kernel/kernel_bake.h
@@ -18,38 +18,40 @@ CCL_NAMESPACE_BEGIN
#ifdef __BAKING__
-ccl_device_inline void compute_light_pass(
+ccl_device_noinline void compute_light_pass(
KernelGlobals *kg, ShaderData *sd, PathRadiance *L, uint rng_hash, int pass_filter, int sample)
{
kernel_assert(kernel_data.film.use_light_pass);
- PathRadiance L_sample;
- PathState state;
- Ray ray;
float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
- /* emission and indirect shader data memory used by various functions */
- ShaderData emission_sd, indirect_sd;
-
- ray.P = sd->P + sd->Ng;
- ray.D = -sd->Ng;
- ray.t = FLT_MAX;
-# ifdef __CAMERA_MOTION__
- ray.time = 0.5f;
-# endif
+ /* Emission and indirect shader data memory used by various functions. */
+ ShaderDataTinyStorage emission_sd_storage;
+ ShaderData *emission_sd = AS_SHADER_DATA(&emission_sd_storage);
+ ShaderData indirect_sd;
- /* init radiance */
- path_radiance_init(kg, &L_sample);
+ /* Init radiance. */
+ path_radiance_init(kg, L);
- /* init path state */
- path_state_init(kg, &emission_sd, &state, rng_hash, sample, NULL);
+ /* Init path state. */
+ PathState state;
+ path_state_init(kg, emission_sd, &state, rng_hash, sample, NULL);
- /* evaluate surface shader */
+ /* Evaluate surface shader. */
shader_eval_surface(kg, sd, &state, NULL, state.flag);
/* TODO, disable more closures we don't need besides transparent */
shader_bsdf_disable_transparency(kg, sd);
+ /* Init ray. */
+ Ray ray;
+ ray.P = sd->P + sd->Ng;
+ ray.D = -sd->Ng;
+ ray.t = FLT_MAX;
+# ifdef __CAMERA_MOTION__
+ ray.time = 0.5f;
+# endif
+
# ifdef __BRANCHED_PATH__
if (!kernel_data.integrator.branched) {
/* regular path tracer */
@@ -57,14 +59,13 @@ ccl_device_inline void compute_light_pass(
/* sample ambient occlusion */
if (pass_filter & BAKE_FILTER_AO) {
- kernel_path_ao(
- kg, sd, &emission_sd, &L_sample, &state, throughput, shader_bsdf_alpha(kg, sd));
+ kernel_path_ao(kg, sd, emission_sd, L, &state, throughput, shader_bsdf_alpha(kg, sd));
}
/* sample emission */
if ((pass_filter & BAKE_FILTER_EMISSION) && (sd->flag & SD_EMISSION)) {
float3 emission = indirect_primitive_emission(kg, sd, 0.0f, state.flag, state.ray_pdf);
- path_radiance_accum_emission(kg, &L_sample, &state, throughput, emission);
+ path_radiance_accum_emission(kg, L, &state, throughput, emission);
}
bool is_sss_sample = false;
@@ -77,12 +78,10 @@ ccl_device_inline void compute_light_pass(
SubsurfaceIndirectRays ss_indirect;
kernel_path_subsurface_init_indirect(&ss_indirect);
if (kernel_path_subsurface_scatter(
- kg, sd, &emission_sd, &L_sample, &state, &ray, &throughput, &ss_indirect)) {
+ kg, sd, emission_sd, L, &state, &ray, &throughput, &ss_indirect)) {
while (ss_indirect.num_rays) {
- kernel_path_subsurface_setup_indirect(
- kg, &ss_indirect, &state, &ray, &L_sample, &throughput);
- kernel_path_indirect(
- kg, &indirect_sd, &emission_sd, &ray, throughput, &state, &L_sample);
+ kernel_path_subsurface_setup_indirect(kg, &ss_indirect, &state, &ray, L, &throughput);
+ kernel_path_indirect(kg, &indirect_sd, emission_sd, &ray, throughput, &state, L);
}
is_sss_sample = true;
}
@@ -91,18 +90,18 @@ ccl_device_inline void compute_light_pass(
/* sample light and BSDF */
if (!is_sss_sample && (pass_filter & (BAKE_FILTER_DIRECT | BAKE_FILTER_INDIRECT))) {
- kernel_path_surface_connect_light(kg, sd, &emission_sd, throughput, &state, &L_sample);
+ kernel_path_surface_connect_light(kg, sd, emission_sd, throughput, &state, L);
- if (kernel_path_surface_bounce(kg, sd, &throughput, &state, &L_sample.state, &ray)) {
+ if (kernel_path_surface_bounce(kg, sd, &throughput, &state, &L->state, &ray)) {
# ifdef __LAMP_MIS__
state.ray_t = 0.0f;
# endif
/* compute indirect light */
- kernel_path_indirect(kg, &indirect_sd, &emission_sd, &ray, throughput, &state, &L_sample);
+ kernel_path_indirect(kg, &indirect_sd, emission_sd, &ray, throughput, &state, L);
/* sum and reset indirect light pass variables for the next samples */
- path_radiance_sum_indirect(&L_sample);
- path_radiance_reset_indirect(&L_sample);
+ path_radiance_sum_indirect(L);
+ path_radiance_reset_indirect(L);
}
}
# ifdef __BRANCHED_PATH__
@@ -112,13 +111,13 @@ ccl_device_inline void compute_light_pass(
/* sample ambient occlusion */
if (pass_filter & BAKE_FILTER_AO) {
- kernel_branched_path_ao(kg, sd, &emission_sd, &L_sample, &state, throughput);
+ kernel_branched_path_ao(kg, sd, emission_sd, L, &state, throughput);
}
/* sample emission */
if ((pass_filter & BAKE_FILTER_EMISSION) && (sd->flag & SD_EMISSION)) {
float3 emission = indirect_primitive_emission(kg, sd, 0.0f, state.flag, state.ray_pdf);
- path_radiance_accum_emission(kg, &L_sample, &state, throughput, emission);
+ path_radiance_accum_emission(kg, L, &state, throughput, emission);
}
# ifdef __SUBSURFACE__
@@ -127,7 +126,7 @@ ccl_device_inline void compute_light_pass(
/* When mixing BSSRDF and BSDF closures we should skip BSDF lighting
* if scattering was successful. */
kernel_branched_path_subsurface_scatter(
- kg, sd, &indirect_sd, &emission_sd, &L_sample, &state, &ray, throughput);
+ kg, sd, &indirect_sd, emission_sd, L, &state, &ray, throughput);
}
# endif
@@ -138,19 +137,16 @@ ccl_device_inline void compute_light_pass(
if (kernel_data.integrator.use_direct_light) {
int all = kernel_data.integrator.sample_all_lights_direct;
kernel_branched_path_surface_connect_light(
- kg, sd, &emission_sd, &state, throughput, 1.0f, &L_sample, all);
+ kg, sd, emission_sd, &state, throughput, 1.0f, L, all);
}
# endif
/* indirect light */
kernel_branched_path_surface_indirect_light(
- kg, sd, &indirect_sd, &emission_sd, throughput, 1.0f, &state, &L_sample);
+ kg, sd, &indirect_sd, emission_sd, throughput, 1.0f, &state, L);
}
}
# endif
-
- /* accumulate into master L */
- path_radiance_accum_sample(L, &L_sample);
}
/* this helps with AA but it's not the real solution as it does not AA the geometry
@@ -225,41 +221,28 @@ ccl_device float3 kernel_bake_evaluate_direct_indirect(KernelGlobals *kg,
return out;
}
-ccl_device void kernel_bake_evaluate(KernelGlobals *kg,
- ccl_global uint4 *input,
- ccl_global float4 *output,
- ShaderEvalType type,
- int pass_filter,
- int i,
- int offset,
- int sample)
+ccl_device void kernel_bake_evaluate(
+ KernelGlobals *kg, ccl_global float *buffer, int sample, int x, int y, int offset, int stride)
{
- ShaderData sd;
- PathState state = {0};
- uint4 in = input[i * 2];
- uint4 diff = input[i * 2 + 1];
-
- float3 out = make_float3(0.0f, 0.0f, 0.0f);
+ /* Setup render buffers. */
+ const int index = offset + x + y * stride;
+ const int pass_stride = kernel_data.film.pass_stride;
+ buffer += index * pass_stride;
- int object = in.x;
- int prim = in.y;
+ ccl_global float *primitive = buffer + kernel_data.film.pass_bake_primitive;
+ ccl_global float *differential = buffer + kernel_data.film.pass_bake_differential;
+ ccl_global float *output = buffer + kernel_data.film.pass_combined;
+ int prim = __float_as_uint(primitive[1]);
if (prim == -1)
return;
- float u = __uint_as_float(in.z);
- float v = __uint_as_float(in.w);
-
- float dudx = __uint_as_float(diff.x);
- float dudy = __uint_as_float(diff.y);
- float dvdx = __uint_as_float(diff.z);
- float dvdy = __uint_as_float(diff.w);
+ prim += kernel_data.bake.tri_offset;
+ /* Random number generator. */
+ uint rng_hash = hash_uint2(x, y) ^ kernel_data.integrator.seed;
int num_samples = kernel_data.integrator.aa_samples;
- /* random number generator */
- uint rng_hash = cmj_hash(offset + i, kernel_data.integrator.seed);
-
float filter_x, filter_y;
if (sample == 0) {
filter_x = filter_y = 0.5f;
@@ -268,23 +251,29 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg,
path_rng_2D(kg, rng_hash, sample, num_samples, PRNG_FILTER_U, &filter_x, &filter_y);
}
- /* subpixel u/v offset */
+ /* Barycentric UV with subpixel offset. */
+ float u = primitive[2];
+ float v = primitive[3];
+
+ float dudx = differential[0];
+ float dudy = differential[1];
+ float dvdx = differential[2];
+ float dvdy = differential[3];
+
if (sample > 0) {
u = bake_clamp_mirror_repeat(u + dudx * (filter_x - 0.5f) + dudy * (filter_y - 0.5f), 1.0f);
v = bake_clamp_mirror_repeat(v + dvdx * (filter_x - 0.5f) + dvdy * (filter_y - 0.5f),
1.0f - u);
}
- /* triangle */
+ /* Shader data setup. */
+ int object = kernel_data.bake.object_index;
int shader;
float3 P, Ng;
triangle_point_normal(kg, object, prim, u, v, &P, &Ng, &shader);
- /* light passes */
- PathRadiance L;
- path_radiance_init(kg, &L);
-
+ ShaderData sd;
shader_setup_from_sample(
kg,
&sd,
@@ -302,7 +291,7 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg,
LAMP_NONE);
sd.I = sd.N;
- /* update differentials */
+ /* Setup differentials. */
sd.dP.dx = sd.dPdu * dudx + sd.dPdv * dvdx;
sd.dP.dy = sd.dPdu * dudy + sd.dPdv * dvdy;
sd.du.dx = dudx;
@@ -310,17 +299,24 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg,
sd.dv.dx = dvdx;
sd.dv.dy = dvdy;
- /* set RNG state for shaders that use sampling */
+ /* Set RNG state for shaders that use sampling. */
+ PathState state = {0};
state.rng_hash = rng_hash;
state.rng_offset = 0;
state.sample = sample;
state.num_samples = num_samples;
state.min_ray_pdf = FLT_MAX;
- /* light passes if we need more than color */
- if (pass_filter & ~BAKE_FILTER_COLOR)
+ /* Light passes if we need more than color. */
+ PathRadiance L;
+ int pass_filter = kernel_data.bake.pass_filter;
+
+ if (kernel_data.bake.pass_filter & ~BAKE_FILTER_COLOR)
compute_light_pass(kg, &sd, &L, rng_hash, pass_filter, sample);
+ float3 out = make_float3(0.0f, 0.0f, 0.0f);
+
+ ShaderEvalType type = (ShaderEvalType)kernel_data.bake.type;
switch (type) {
/* data passes */
case SHADER_EVAL_NORMAL:
@@ -441,10 +437,8 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg,
}
/* write output */
- const float output_fac = 1.0f / num_samples;
- const float4 scaled_result = make_float4(out.x, out.y, out.z, 1.0f) * output_fac;
-
- output[i] = (sample == 0) ? scaled_result : output[i] + scaled_result;
+ const float4 result = make_float4(out.x, out.y, out.z, 1.0f);
+ kernel_write_pass_float4(output, result);
}
#endif /* __BAKING__ */
diff --git a/intern/cycles/kernel/kernel_film.h b/intern/cycles/kernel/kernel_film.h
index 3829426f261..8344f4b4f47 100644
--- a/intern/cycles/kernel/kernel_film.h
+++ b/intern/cycles/kernel/kernel_film.h
@@ -28,13 +28,13 @@ ccl_device float4 film_get_pass_result(KernelGlobals *kg,
int display_pass_components = kernel_data.film.display_pass_components;
if (display_pass_components == 4) {
- ccl_global float4 *in = (ccl_global float4 *)(buffer + display_pass_stride +
- index * kernel_data.film.pass_stride);
+ float4 in = *(ccl_global float4 *)(buffer + display_pass_stride +
+ index * kernel_data.film.pass_stride);
float alpha = use_display_sample_scale ?
- (kernel_data.film.use_display_pass_alpha ? in->w : 1.0f / sample_scale) :
+ (kernel_data.film.use_display_pass_alpha ? in.w : 1.0f / sample_scale) :
1.0f;
- pass_result = make_float4(in->x, in->y, in->z, alpha);
+ pass_result = make_float4(in.x, in.y, in.z, alpha);
int display_divide_pass_stride = kernel_data.film.display_divide_pass_stride;
if (display_divide_pass_stride != -1) {
diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h
index ce908ce0fe2..d918abed381 100644
--- a/intern/cycles/kernel/kernel_light.h
+++ b/intern/cycles/kernel/kernel_light.h
@@ -1041,11 +1041,19 @@ ccl_device_forceinline void triangle_light_sample(KernelGlobals *kg,
}
}
else {
- /* compute random point in triangle */
- randu = sqrtf(randu);
+ /* compute random point in triangle. From Eric Heitz's "A Low-Distortion Map Between Triangle
+ * and Square" */
+ float u = randu;
+ float v = randv;
+ if (v > u) {
+ u *= 0.5f;
+ v -= u;
+ }
+ else {
+ v *= 0.5f;
+ u -= v;
+ }
- const float u = 1.0f - randu;
- const float v = randv * randu;
const float t = 1.0f - u - v;
ls->P = u * V[0] + v * V[1] + t * V[2];
/* compute incoming direction, distance and pdf */
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index a1f8c35348d..304835a1685 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -395,6 +395,10 @@ typedef enum PassType {
PASS_VOLUME_INDIRECT,
/* No Scatter color since it's tricky to define what it would even mean. */
PASS_CATEGORY_LIGHT_END = 63,
+
+ PASS_BAKE_PRIMITIVE,
+ PASS_BAKE_DIFFERENTIAL,
+ PASS_CATEGORY_BAKE_END = 95
} PassType;
#define PASS_ANY (~0)
@@ -1248,6 +1252,10 @@ typedef struct KernelFilm {
float4 xyz_to_b;
float4 rgb_to_y;
+ int pass_bake_primitive;
+ int pass_bake_differential;
+ int pad;
+
#ifdef __KERNEL_DEBUG__
int pass_bvh_traversed_nodes;
int pass_bvh_traversed_instances;
@@ -1427,6 +1435,14 @@ typedef struct KernelTables {
} KernelTables;
static_assert_align(KernelTables, 16);
+typedef struct KernelBake {
+ int object_index;
+ int tri_offset;
+ int type;
+ int pass_filter;
+} KernelBake;
+static_assert_align(KernelBake, 16);
+
typedef struct KernelData {
KernelCamera cam;
KernelFilm film;
@@ -1435,6 +1451,7 @@ typedef struct KernelData {
KernelBVH bvh;
KernelCurves curve;
KernelTables tables;
+ KernelBake bake;
} KernelData;
static_assert_align(KernelData, 16);
diff --git a/intern/cycles/kernel/kernels/cpu/kernel_cpu.h b/intern/cycles/kernel/kernels/cpu/kernel_cpu.h
index 683f4b88d79..ea3103f12c3 100644
--- a/intern/cycles/kernel/kernels/cpu/kernel_cpu.h
+++ b/intern/cycles/kernel/kernels/cpu/kernel_cpu.h
@@ -46,6 +46,9 @@ void KERNEL_FUNCTION_FULL_NAME(shader)(KernelGlobals *kg,
int offset,
int sample);
+void KERNEL_FUNCTION_FULL_NAME(bake)(
+ KernelGlobals *kg, float *buffer, int sample, int x, int y, int offset, int stride);
+
/* Split kernels */
void KERNEL_FUNCTION_FULL_NAME(data_init)(KernelGlobals *kg,
diff --git a/intern/cycles/kernel/kernels/cpu/kernel_cpu_impl.h b/intern/cycles/kernel/kernels/cpu/kernel_cpu_impl.h
index 091e53cfd83..5aa3fb14318 100644
--- a/intern/cycles/kernel/kernels/cpu/kernel_cpu_impl.h
+++ b/intern/cycles/kernel/kernels/cpu/kernel_cpu_impl.h
@@ -132,6 +132,18 @@ void KERNEL_FUNCTION_FULL_NAME(convert_to_half_float)(KernelGlobals *kg,
# endif /* KERNEL_STUB */
}
+/* Bake */
+
+void KERNEL_FUNCTION_FULL_NAME(bake)(
+ KernelGlobals *kg, float *buffer, int sample, int x, int y, int offset, int stride)
+{
+# ifdef KERNEL_STUB
+ STUB_ASSERT(KERNEL_ARCH, bake);
+# else
+ kernel_bake_evaluate(kg, buffer, sample, x, y, offset, stride);
+# endif /* KERNEL_STUB */
+}
+
/* Shader Evaluate */
void KERNEL_FUNCTION_FULL_NAME(shader)(KernelGlobals *kg,
@@ -146,12 +158,7 @@ void KERNEL_FUNCTION_FULL_NAME(shader)(KernelGlobals *kg,
# ifdef KERNEL_STUB
STUB_ASSERT(KERNEL_ARCH, shader);
# else
- if (type >= SHADER_EVAL_BAKE) {
-# ifdef __BAKING__
- kernel_bake_evaluate(kg, input, output, (ShaderEvalType)type, filter, i, offset, sample);
-# endif
- }
- else if (type == SHADER_EVAL_DISPLACE) {
+ if (type == SHADER_EVAL_DISPLACE) {
kernel_displace_evaluate(kg, input, output, i);
}
else {
diff --git a/intern/cycles/kernel/kernels/cuda/kernel.cu b/intern/cycles/kernel/kernels/cuda/kernel.cu
index c4c810c6a82..d4f41132a11 100644
--- a/intern/cycles/kernel/kernels/cuda/kernel.cu
+++ b/intern/cycles/kernel/kernels/cuda/kernel.cu
@@ -214,13 +214,16 @@ kernel_cuda_background(uint4 *input,
#ifdef __BAKING__
extern "C" __global__ void
CUDA_LAUNCH_BOUNDS(CUDA_THREADS_BLOCK_WIDTH, CUDA_KERNEL_MAX_REGISTERS)
-kernel_cuda_bake(uint4 *input, float4 *output, int type, int filter, int sx, int sw, int offset, int sample)
+kernel_cuda_bake(WorkTile *tile, uint total_work_size)
{
- int x = sx + blockDim.x*blockIdx.x + threadIdx.x;
+ int work_index = ccl_global_id(0);
+
+ if(work_index < total_work_size) {
+ uint x, y, sample;
+ get_work_pixel(tile, work_index, &x, &y, &sample);
- if(x < sx + sw) {
KernelGlobals kg;
- kernel_bake_evaluate(&kg, input, output, (ShaderEvalType)type, filter, x, offset, sample);
+ kernel_bake_evaluate(&kg, tile->buffer, sample, x, y, tile->offset, tile->stride);
}
}
#endif
diff --git a/intern/cycles/render/bake.cpp b/intern/cycles/render/bake.cpp
index 35f942b3e9b..6044182a51a 100644
--- a/intern/cycles/render/bake.cpp
+++ b/intern/cycles/render/bake.cpp
@@ -15,6 +15,7 @@
*/
#include "render/bake.h"
+#include "render/buffers.h"
#include "render/integrator.h"
#include "render/mesh.h"
#include "render/object.h"
@@ -24,272 +25,130 @@
CCL_NAMESPACE_BEGIN
-BakeData::BakeData(const int object, const size_t tri_offset, const size_t num_pixels)
- : m_object(object), m_tri_offset(tri_offset), m_num_pixels(num_pixels)
+static int aa_samples(Scene *scene, Object *object, ShaderEvalType type)
{
- m_primitive.resize(num_pixels);
- m_u.resize(num_pixels);
- m_v.resize(num_pixels);
- m_dudx.resize(num_pixels);
- m_dudy.resize(num_pixels);
- m_dvdx.resize(num_pixels);
- m_dvdy.resize(num_pixels);
-}
-
-BakeData::~BakeData()
-{
- m_primitive.clear();
- m_u.clear();
- m_v.clear();
- m_dudx.clear();
- m_dudy.clear();
- m_dvdx.clear();
- m_dvdy.clear();
-}
-
-void BakeData::set(int i, int prim, float uv[2], float dudx, float dudy, float dvdx, float dvdy)
-{
- m_primitive[i] = (prim == -1 ? -1 : m_tri_offset + prim);
- m_u[i] = uv[0];
- m_v[i] = uv[1];
- m_dudx[i] = dudx;
- m_dudy[i] = dudy;
- m_dvdx[i] = dvdx;
- m_dvdy[i] = dvdy;
-}
-
-void BakeData::set_null(int i)
-{
- m_primitive[i] = -1;
-}
-
-int BakeData::object()
-{
- return m_object;
-}
-
-size_t BakeData::size()
-{
- return m_num_pixels;
-}
+ if (type == SHADER_EVAL_UV || type == SHADER_EVAL_ROUGHNESS) {
+ return 1;
+ }
+ else if (type == SHADER_EVAL_NORMAL) {
+ /* Only antialias normal if mesh has bump mapping. */
+ if (object->geometry) {
+ foreach (Shader *shader, object->geometry->used_shaders) {
+ if (shader->has_bump) {
+ return scene->integrator->aa_samples;
+ }
+ }
+ }
-bool BakeData::is_valid(int i)
-{
- return m_primitive[i] != -1;
+ return 1;
+ }
+ else {
+ return scene->integrator->aa_samples;
+ }
}
-uint4 BakeData::data(int i)
+/* Keep it synced with kernel_bake.h logic */
+static int shader_type_to_pass_filter(ShaderEvalType type, int pass_filter)
{
- return make_uint4(m_object, m_primitive[i], __float_as_int(m_u[i]), __float_as_int(m_v[i]));
-}
+ const int component_flags = pass_filter &
+ (BAKE_FILTER_DIRECT | BAKE_FILTER_INDIRECT | BAKE_FILTER_COLOR);
-uint4 BakeData::differentials(int i)
-{
- return make_uint4(__float_as_int(m_dudx[i]),
- __float_as_int(m_dudy[i]),
- __float_as_int(m_dvdx[i]),
- __float_as_int(m_dvdy[i]));
+ switch (type) {
+ case SHADER_EVAL_AO:
+ return BAKE_FILTER_AO;
+ case SHADER_EVAL_SHADOW:
+ return BAKE_FILTER_DIRECT;
+ case SHADER_EVAL_DIFFUSE:
+ return BAKE_FILTER_DIFFUSE | component_flags;
+ case SHADER_EVAL_GLOSSY:
+ return BAKE_FILTER_GLOSSY | component_flags;
+ case SHADER_EVAL_TRANSMISSION:
+ return BAKE_FILTER_TRANSMISSION | component_flags;
+ case SHADER_EVAL_COMBINED:
+ return pass_filter;
+ default:
+ return 0;
+ }
}
BakeManager::BakeManager()
{
- m_bake_data = NULL;
- m_is_baking = false;
+ type = SHADER_EVAL_BAKE;
+ pass_filter = 0;
+
need_update = true;
- m_shader_limit = 512 * 512;
}
BakeManager::~BakeManager()
{
- if (m_bake_data)
- delete m_bake_data;
}
bool BakeManager::get_baking()
{
- return m_is_baking;
-}
-
-void BakeManager::set_baking(const bool value)
-{
- m_is_baking = value;
+ return !object_name.empty();
}
-BakeData *BakeManager::init(const int object, const size_t tri_offset, const size_t num_pixels)
+void BakeManager::set(Scene *scene,
+ const std::string &object_name_,
+ ShaderEvalType type_,
+ int pass_filter_)
{
- m_bake_data = new BakeData(object, tri_offset, num_pixels);
- return m_bake_data;
-}
-
-void BakeManager::set_shader_limit(const size_t x, const size_t y)
-{
- m_shader_limit = x * y;
- m_shader_limit = (size_t)pow(2, std::ceil(log(m_shader_limit) / log(2)));
-}
+ object_name = object_name_;
+ type = type_;
+ pass_filter = shader_type_to_pass_filter(type_, pass_filter_);
-bool BakeManager::bake(Device *device,
- DeviceScene *dscene,
- Scene *scene,
- Progress &progress,
- ShaderEvalType shader_type,
- const int pass_filter,
- BakeData *bake_data,
- float result[])
-{
- size_t num_pixels = bake_data->size();
-
- int num_samples = aa_samples(scene, bake_data, shader_type);
+ Pass::add(PASS_BAKE_PRIMITIVE, scene->film->passes);
+ Pass::add(PASS_BAKE_DIFFERENTIAL, scene->film->passes);
- /* calculate the total pixel samples for the progress bar */
- total_pixel_samples = 0;
- for (size_t shader_offset = 0; shader_offset < num_pixels; shader_offset += m_shader_limit) {
- size_t shader_size = (size_t)fminf(num_pixels - shader_offset, m_shader_limit);
- total_pixel_samples += shader_size * num_samples;
+ if (type == SHADER_EVAL_UV) {
+ /* force UV to be available */
+ Pass::add(PASS_UV, scene->film->passes);
}
- progress.reset_sample();
- progress.set_total_pixel_samples(total_pixel_samples);
-
- /* needs to be up to date for baking specific AA samples */
- dscene->data.integrator.aa_samples = num_samples;
- device->const_copy_to("__data", &dscene->data, sizeof(dscene->data));
-
- for (size_t shader_offset = 0; shader_offset < num_pixels; shader_offset += m_shader_limit) {
- size_t shader_size = (size_t)fminf(num_pixels - shader_offset, m_shader_limit);
- /* setup input for device task */
- device_vector<uint4> d_input(device, "bake_input", MEM_READ_ONLY);
- uint4 *d_input_data = d_input.alloc(shader_size * 2);
- size_t d_input_size = 0;
-
- for (size_t i = shader_offset; i < (shader_offset + shader_size); i++) {
- d_input_data[d_input_size++] = bake_data->data(i);
- d_input_data[d_input_size++] = bake_data->differentials(i);
- }
-
- if (d_input_size == 0) {
- m_is_baking = false;
- return false;
- }
-
- /* run device task */
- device_vector<float4> d_output(device, "bake_output", MEM_READ_WRITE);
- d_output.alloc(shader_size);
- d_output.zero_to_device();
- d_input.copy_to_device();
-
- DeviceTask task(DeviceTask::SHADER);
- task.shader_input = d_input.device_pointer;
- task.shader_output = d_output.device_pointer;
- task.shader_eval_type = shader_type;
- task.shader_filter = pass_filter;
- task.shader_x = 0;
- task.offset = shader_offset;
- task.shader_w = d_output.size();
- task.num_samples = num_samples;
- task.get_cancel = function_bind(&Progress::get_cancel, &progress);
- task.update_progress_sample = function_bind(&Progress::add_samples_update, &progress, _1, _2);
-
- device->task_add(task);
- device->task_wait();
-
- if (progress.get_cancel()) {
- d_input.free();
- d_output.free();
- m_is_baking = false;
- return false;
- }
-
- d_output.copy_from_device(0, 1, d_output.size());
- d_input.free();
-
- /* read result */
- int k = 0;
-
- float4 *offset = d_output.data();
-
- size_t depth = 4;
- for (size_t i = shader_offset; i < (shader_offset + shader_size); i++) {
- size_t index = i * depth;
- float4 out = offset[k++];
-
- if (bake_data->is_valid(i)) {
- for (size_t j = 0; j < 4; j++) {
- result[index + j] = out[j];
- }
- }
- }
-
- d_output.free();
+ /* force use_light_pass to be true if we bake more than just colors */
+ if (pass_filter & ~BAKE_FILTER_COLOR) {
+ Pass::add(PASS_LIGHT, scene->film->passes);
}
- m_is_baking = false;
- return true;
+ /* create device and update scene */
+ scene->film->tag_update(scene);
+ scene->integrator->tag_update(scene);
+
+ need_update = true;
}
void BakeManager::device_update(Device * /*device*/,
- DeviceScene * /*dscene*/,
- Scene * /*scene*/,
- Progress &progress)
+ DeviceScene *dscene,
+ Scene *scene,
+ Progress & /* progress */)
{
if (!need_update)
return;
- if (progress.get_cancel())
- return;
+ KernelIntegrator *kintegrator = &dscene->data.integrator;
+ KernelBake *kbake = &dscene->data.bake;
- need_update = false;
-}
-
-void BakeManager::device_free(Device * /*device*/, DeviceScene * /*dscene*/)
-{
-}
-
-int BakeManager::aa_samples(Scene *scene, BakeData *bake_data, ShaderEvalType type)
-{
- if (type == SHADER_EVAL_UV || type == SHADER_EVAL_ROUGHNESS) {
- return 1;
- }
- else if (type == SHADER_EVAL_NORMAL) {
- /* Only antialias normal if mesh has bump mapping. */
- Object *object = scene->objects[bake_data->object()];
+ kbake->type = type;
+ kbake->pass_filter = pass_filter;
- if (object->geometry) {
- foreach (Shader *shader, object->geometry->used_shaders) {
- if (shader->has_bump) {
- return scene->integrator->aa_samples;
- }
- }
+ int object_index = 0;
+ foreach (Object *object, scene->objects) {
+ const Geometry *geom = object->geometry;
+ if (object->name == object_name && geom->type == Geometry::MESH) {
+ kbake->object_index = object_index;
+ kbake->tri_offset = geom->prim_offset;
+ kintegrator->aa_samples = aa_samples(scene, object, type);
+ break;
}
- return 1;
- }
- else {
- return scene->integrator->aa_samples;
+ object_index++;
}
+
+ need_update = false;
}
-/* Keep it synced with kernel_bake.h logic */
-int BakeManager::shader_type_to_pass_filter(ShaderEvalType type, const int pass_filter)
+void BakeManager::device_free(Device * /*device*/, DeviceScene * /*dscene*/)
{
- const int component_flags = pass_filter &
- (BAKE_FILTER_DIRECT | BAKE_FILTER_INDIRECT | BAKE_FILTER_COLOR);
-
- switch (type) {
- case SHADER_EVAL_AO:
- return BAKE_FILTER_AO;
- case SHADER_EVAL_SHADOW:
- return BAKE_FILTER_DIRECT;
- case SHADER_EVAL_DIFFUSE:
- return BAKE_FILTER_DIFFUSE | component_flags;
- case SHADER_EVAL_GLOSSY:
- return BAKE_FILTER_GLOSSY | component_flags;
- case SHADER_EVAL_TRANSMISSION:
- return BAKE_FILTER_TRANSMISSION | component_flags;
- case SHADER_EVAL_COMBINED:
- return pass_filter;
- default:
- return 0;
- }
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/bake.h b/intern/cycles/render/bake.h
index 88537623efb..93e664c2ab1 100644
--- a/intern/cycles/render/bake.h
+++ b/intern/cycles/render/bake.h
@@ -25,67 +25,23 @@
CCL_NAMESPACE_BEGIN
-class BakeData {
- public:
- BakeData(const int object, const size_t tri_offset, const size_t num_pixels);
- ~BakeData();
-
- void set(int i, int prim, float uv[2], float dudx, float dudy, float dvdx, float dvdy);
- void set_null(int i);
- int object();
- size_t size();
- uint4 data(int i);
- uint4 differentials(int i);
- bool is_valid(int i);
-
- private:
- int m_object;
- size_t m_tri_offset;
- size_t m_num_pixels;
- vector<int> m_primitive;
- vector<float> m_u;
- vector<float> m_v;
- vector<float> m_dudx;
- vector<float> m_dudy;
- vector<float> m_dvdx;
- vector<float> m_dvdy;
-};
-
class BakeManager {
public:
BakeManager();
~BakeManager();
+ void set(Scene *scene, const std::string &object_name, ShaderEvalType type, int pass_filter);
bool get_baking();
- void set_baking(const bool value);
-
- BakeData *init(const int object, const size_t tri_offset, const size_t num_pixels);
-
- void set_shader_limit(const size_t x, const size_t y);
-
- bool bake(Device *device,
- DeviceScene *dscene,
- Scene *scene,
- Progress &progress,
- ShaderEvalType shader_type,
- const int pass_filter,
- BakeData *bake_data,
- float result[]);
void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress);
void device_free(Device *device, DeviceScene *dscene);
- static int shader_type_to_pass_filter(ShaderEvalType type, const int pass_filter);
- static int aa_samples(Scene *scene, BakeData *bake_data, ShaderEvalType type);
-
bool need_update;
- size_t total_pixel_samples;
-
private:
- BakeData *m_bake_data;
- bool m_is_baking;
- size_t m_shader_limit;
+ ShaderEvalType type;
+ int pass_filter;
+ std::string object_name;
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/buffers.cpp b/intern/cycles/render/buffers.cpp
index 2d89fb9ffba..b26366af852 100644
--- a/intern/cycles/render/buffers.cpp
+++ b/intern/cycles/render/buffers.cpp
@@ -459,6 +459,40 @@ bool RenderBuffers::get_pass_rect(
return false;
}
+bool RenderBuffers::set_pass_rect(PassType type, int components, float *pixels)
+{
+ if (buffer.data() == NULL) {
+ return false;
+ }
+
+ int pass_offset = 0;
+
+ for (size_t j = 0; j < params.passes.size(); j++) {
+ Pass &pass = params.passes[j];
+
+ if (pass.type != type) {
+ pass_offset += pass.components;
+ continue;
+ }
+
+ float *out = buffer.data() + pass_offset;
+ int pass_stride = params.get_passes_size();
+ int size = params.width * params.height;
+
+ assert(pass.components == components);
+
+ for (int i = 0; i < size; i++, out += pass_stride, pixels += components) {
+ for (int j = 0; j < components; j++) {
+ out[j] = pixels[j];
+ }
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
/* Display Buffer */
DisplayBuffer::DisplayBuffer(Device *device, bool linear)
diff --git a/intern/cycles/render/buffers.h b/intern/cycles/render/buffers.h
index 42efb031843..975bae2239c 100644
--- a/intern/cycles/render/buffers.h
+++ b/intern/cycles/render/buffers.h
@@ -92,6 +92,7 @@ class RenderBuffers {
const string &name, float exposure, int sample, int components, float *pixels);
bool get_denoising_pass_rect(
int offset, float exposure, int sample, int components, float *pixels);
+ bool set_pass_rect(PassType type, int components, float *pixels);
};
/* Display Buffer
@@ -130,7 +131,7 @@ class DisplayBuffer {
class RenderTile {
public:
- typedef enum { PATH_TRACE = (1 << 0), DENOISE = (1 << 1) } Task;
+ typedef enum { PATH_TRACE = (1 << 0), BAKE = (1 << 1), DENOISE = (1 << 2) } Task;
Task task;
int x, y, w, h;
diff --git a/intern/cycles/render/film.cpp b/intern/cycles/render/film.cpp
index 26eda93fadd..d7cbf4a3581 100644
--- a/intern/cycles/render/film.cpp
+++ b/intern/cycles/render/film.cpp
@@ -196,6 +196,10 @@ void Pass::add(PassType type, vector<Pass> &passes, const char *name)
case PASS_AOV_VALUE:
pass.components = 1;
break;
+ case PASS_BAKE_PRIMITIVE:
+ case PASS_BAKE_DIFFERENTIAL:
+ pass.components = 4;
+ break;
default:
assert(false);
break;
@@ -386,11 +390,13 @@ void Film::device_update(Device *device, DeviceScene *dscene, Scene *scene)
if (pass.type <= PASS_CATEGORY_MAIN_END) {
kfilm->pass_flag |= pass_flag;
}
- else {
- assert(pass.type <= PASS_CATEGORY_LIGHT_END);
+ else if (pass.type <= PASS_CATEGORY_LIGHT_END) {
kfilm->use_light_pass = 1;
kfilm->light_pass_flag |= pass_flag;
}
+ else {
+ assert(pass.type <= PASS_CATEGORY_BAKE_END);
+ }
switch (pass.type) {
case PASS_COMBINED:
@@ -471,6 +477,13 @@ void Film::device_update(Device *device, DeviceScene *dscene, Scene *scene)
kfilm->pass_volume_direct = kfilm->pass_stride;
break;
+ case PASS_BAKE_PRIMITIVE:
+ kfilm->pass_bake_primitive = kfilm->pass_stride;
+ break;
+ case PASS_BAKE_DIFFERENTIAL:
+ kfilm->pass_bake_differential = kfilm->pass_stride;
+ break;
+
#ifdef WITH_CYCLES_DEBUG
case PASS_BVH_TRAVERSED_NODES:
kfilm->pass_bvh_traversed_nodes = kfilm->pass_stride;
diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp
index f7df81a0601..361a1465aac 100644
--- a/intern/cycles/render/session.cpp
+++ b/intern/cycles/render/session.cpp
@@ -410,7 +410,16 @@ bool Session::acquire_tile(RenderTile &rtile, Device *tile_device, uint tile_typ
rtile.num_samples = tile_manager.state.num_samples;
rtile.resolution = tile_manager.state.resolution_divider;
rtile.tile_index = tile->index;
- rtile.task = tile->state == Tile::DENOISE ? RenderTile::DENOISE : RenderTile::PATH_TRACE;
+
+ if (tile->state == Tile::DENOISE) {
+ rtile.task = RenderTile::DENOISE;
+ }
+ else if (read_bake_tile_cb) {
+ rtile.task = RenderTile::BAKE;
+ }
+ else {
+ rtile.task = RenderTile::PATH_TRACE;
+ }
tile_lock.unlock();
@@ -451,11 +460,20 @@ bool Session::acquire_tile(RenderTile &rtile, Device *tile_device, uint tile_typ
rtile.buffers = tile->buffers;
rtile.sample = tile_manager.state.sample;
- /* this will tag tile as IN PROGRESS in blender-side render pipeline,
- * which is needed to highlight currently rendering tile before first
- * sample was processed for it
- */
- update_tile_sample(rtile);
+ if (read_bake_tile_cb) {
+ /* This will read any passes needed as input for baking. */
+ {
+ thread_scoped_lock tile_lock(tile_mutex);
+ read_bake_tile_cb(rtile);
+ }
+ rtile.buffers->buffer.copy_to_device();
+ }
+ else {
+ /* This will tag tile as IN PROGRESS in blender-side render pipeline,
+ * which is needed to highlight currently rendering tile before first
+ * sample was processed for it. */
+ update_tile_sample(rtile);
+ }
return true;
}
@@ -484,6 +502,7 @@ void Session::release_tile(RenderTile &rtile, const bool need_denoise)
bool delete_tile;
if (tile_manager.finish_tile(rtile.tile_index, need_denoise, delete_tile)) {
+ /* Finished tile pixels write. */
if (write_render_tile_cb && params.progressive_refine == false) {
write_render_tile_cb(rtile);
}
@@ -494,6 +513,7 @@ void Session::release_tile(RenderTile &rtile, const bool need_denoise)
}
}
else {
+ /* In progress tile pixels update. */
if (update_render_tile_cb && params.progressive_refine == false) {
update_render_tile_cb(rtile, false);
}
diff --git a/intern/cycles/render/session.h b/intern/cycles/render/session.h
index f06952e8020..2707eed5531 100644
--- a/intern/cycles/render/session.h
+++ b/intern/cycles/render/session.h
@@ -148,6 +148,7 @@ class Session {
function<void(RenderTile &)> write_render_tile_cb;
function<void(RenderTile &, bool)> update_render_tile_cb;
+ function<void(RenderTile &)> read_bake_tile_cb;
explicit Session(const SessionParams &params);
~Session();
diff --git a/intern/ghost/intern/GHOST_System.cpp b/intern/ghost/intern/GHOST_System.cpp
index 587e4c28102..b0d2adff4bc 100644
--- a/intern/ghost/intern/GHOST_System.cpp
+++ b/intern/ghost/intern/GHOST_System.cpp
@@ -23,8 +23,8 @@
#include "GHOST_System.h"
+#include <chrono>
#include <stdio.h> /* just for printf */
-#include <time.h>
#include "GHOST_DisplayManager.h"
#include "GHOST_EventManager.h"
@@ -58,12 +58,9 @@ GHOST_System::~GHOST_System()
GHOST_TUns64 GHOST_System::getMilliSeconds() const
{
- GHOST_TUns64 millis = ::clock();
- if (CLOCKS_PER_SEC != 1000) {
- millis *= 1000;
- millis /= CLOCKS_PER_SEC;
- }
- return millis;
+ return std::chrono::duration_cast<std::chrono::milliseconds>(
+ std::chrono::steady_clock::now().time_since_epoch())
+ .count();
}
GHOST_ITimerTask *GHOST_System::installTimer(GHOST_TUns64 delay,
diff --git a/intern/ghost/intern/GHOST_SystemWayland.cpp b/intern/ghost/intern/GHOST_SystemWayland.cpp
index 1346e1bce20..633451feb85 100644
--- a/intern/ghost/intern/GHOST_SystemWayland.cpp
+++ b/intern/ghost/intern/GHOST_SystemWayland.cpp
@@ -25,6 +25,7 @@
#include "GHOST_EventDragnDrop.h"
#include "GHOST_EventKey.h"
#include "GHOST_EventWheel.h"
+#include "GHOST_TimerManager.h"
#include "GHOST_WindowManager.h"
#include "GHOST_ContextEGL.h"
@@ -34,7 +35,7 @@
#include <algorithm>
#include <atomic>
-#include <exception>
+#include <stdexcept>
#include <thread>
#include <unordered_map>
#include <unordered_set>
@@ -91,6 +92,13 @@ struct data_source_t {
char *buffer_out;
};
+struct key_repeat_payload_t {
+ GHOST_SystemWayland *system;
+ GHOST_IWindow *window;
+ GHOST_TKey key;
+ GHOST_TEventKeyData key_data;
+};
+
struct input_t {
GHOST_SystemWayland *system;
@@ -109,6 +117,17 @@ struct input_t {
struct xkb_context *xkb_context;
struct xkb_state *xkb_state;
+ struct {
+ /* Key repetition in character per second. */
+ int32_t rate;
+ /* Time (milliseconds) after which to start repeating keys. */
+ int32_t delay;
+ /* Timer for key repeats. */
+ GHOST_ITimerTask *timer = nullptr;
+ } key_repeat;
+
+ struct wl_surface *focus_pointer = nullptr;
+ struct wl_surface *focus_keyboard = nullptr;
struct wl_data_device *data_device = nullptr;
struct data_offer_t *data_offer_dnd; /* Drag & Drop. */
@@ -174,6 +193,11 @@ static void display_destroy(display_t *d)
}
}
if (input->keyboard) {
+ if (input->key_repeat.timer) {
+ delete static_cast<key_repeat_payload_t *>(input->key_repeat.timer->getUserData());
+ input->system->removeTimer(input->key_repeat.timer);
+ input->key_repeat.timer = nullptr;
+ }
wl_keyboard_destroy(input->keyboard);
}
if (input->xkb_state) {
@@ -420,22 +444,26 @@ static void relative_pointer_relative_motion(
input->x += wl_fixed_to_int(dx);
input->y += wl_fixed_to_int(dy);
- input->system->pushEvent(
- new GHOST_EventCursor(input->system->getMilliSeconds(),
- GHOST_kEventCursorMove,
- input->system->getWindowManager()->getActiveWindow(),
- input->x,
- input->y,
- GHOST_TABLET_DATA_NONE));
+ GHOST_IWindow *win = static_cast<GHOST_WindowWayland *>(
+ wl_surface_get_user_data(input->focus_pointer));
+
+ input->system->pushEvent(new GHOST_EventCursor(input->system->getMilliSeconds(),
+ GHOST_kEventCursorMove,
+ win,
+ input->x,
+ input->y,
+ GHOST_TABLET_DATA_NONE));
}
static const zwp_relative_pointer_v1_listener relative_pointer_listener = {
- relative_pointer_relative_motion};
+ relative_pointer_relative_motion,
+};
static void dnd_events(const input_t *const input, const GHOST_TEventType event)
{
const GHOST_TUns64 time = input->system->getMilliSeconds();
- GHOST_IWindow *const window = input->system->getWindowManager()->getActiveWindow();
+ GHOST_IWindow *const window = static_cast<GHOST_WindowWayland *>(
+ wl_surface_get_user_data(input->focus_pointer));
for (const std::string &type : mime_preference_order) {
input->system->pushEvent(new GHOST_EventDragnDrop(time,
event,
@@ -641,7 +669,7 @@ static void data_device_drop(void *data, struct wl_data_device * /*wl_data_devic
data_offer->types.begin(),
data_offer->types.end());
- auto read_uris = [](GHOST_SystemWayland *const system,
+ auto read_uris = [](input_t *const input,
data_offer_t *data_offer,
const std::string mime_receive) {
const int x = data_offer->dnd.x;
@@ -655,6 +683,8 @@ static void data_device_drop(void *data, struct wl_data_device * /*wl_data_devic
delete data_offer;
data_offer = nullptr;
+ GHOST_SystemWayland *const system = input->system;
+
if (mime_receive == mime_text_uri) {
static constexpr const char *file_proto = "file://";
static constexpr const char *crlf = "\r\n";
@@ -683,10 +713,12 @@ static void data_device_drop(void *data, struct wl_data_device * /*wl_data_devic
malloc((uris[i].size() + 1) * sizeof(GHOST_TUns8)));
memcpy(flist->strings[i], uris[i].data(), uris[i].size() + 1);
}
+ GHOST_IWindow *win = static_cast<GHOST_WindowWayland *>(
+ wl_surface_get_user_data(input->focus_pointer));
system->pushEvent(new GHOST_EventDragnDrop(system->getMilliSeconds(),
GHOST_kEventDraggingDropDone,
GHOST_kDragnDropTypeFilenames,
- system->getWindowManager()->getActiveWindow(),
+ win,
x,
y,
flist));
@@ -698,7 +730,7 @@ static void data_device_drop(void *data, struct wl_data_device * /*wl_data_devic
wl_display_roundtrip(system->display());
};
- std::thread read_thread(read_uris, input->system, data_offer, mime_receive);
+ std::thread read_thread(read_uris, input, data_offer, mime_receive);
read_thread.detach();
}
@@ -778,17 +810,24 @@ static void pointer_enter(void *data,
input->pointer_serial = serial;
input->x = wl_fixed_to_int(surface_x);
input->y = wl_fixed_to_int(surface_y);
+ input->focus_pointer = surface;
- static_cast<GHOST_WindowWayland *>(wl_surface_get_user_data(surface))->activate();
+ input->system->pushEvent(
+ new GHOST_EventCursor(input->system->getMilliSeconds(),
+ GHOST_kEventCursorMove,
+ static_cast<GHOST_WindowWayland *>(wl_surface_get_user_data(surface)),
+ input->x,
+ input->y,
+ GHOST_TABLET_DATA_NONE));
}
-static void pointer_leave(void * /*data*/,
+static void pointer_leave(void *data,
struct wl_pointer * /*wl_pointer*/,
uint32_t /*serial*/,
struct wl_surface *surface)
{
if (surface != nullptr) {
- static_cast<GHOST_WindowWayland *>(wl_surface_get_user_data(surface))->deactivate();
+ static_cast<input_t *>(data)->focus_pointer = nullptr;
}
}
@@ -800,16 +839,22 @@ static void pointer_motion(void *data,
{
input_t *input = static_cast<input_t *>(data);
+ GHOST_IWindow *win = static_cast<GHOST_WindowWayland *>(
+ wl_surface_get_user_data(input->focus_pointer));
+
+ if (!win) {
+ return;
+ }
+
input->x = wl_fixed_to_int(surface_x);
input->y = wl_fixed_to_int(surface_y);
- input->system->pushEvent(
- new GHOST_EventCursor(input->system->getMilliSeconds(),
- GHOST_kEventCursorMove,
- input->system->getWindowManager()->getActiveWindow(),
- wl_fixed_to_int(surface_x),
- wl_fixed_to_int(surface_y),
- GHOST_TABLET_DATA_NONE));
+ input->system->pushEvent(new GHOST_EventCursor(input->system->getMilliSeconds(),
+ GHOST_kEventCursorMove,
+ win,
+ wl_fixed_to_int(surface_x),
+ wl_fixed_to_int(surface_y),
+ GHOST_TABLET_DATA_NONE));
}
static void pointer_button(void *data,
@@ -843,14 +888,12 @@ static void pointer_button(void *data,
}
input_t *input = static_cast<input_t *>(data);
+ GHOST_IWindow *win = static_cast<GHOST_WindowWayland *>(
+ wl_surface_get_user_data(input->focus_pointer));
input->data_source->source_serial = serial;
input->buttons.set(ebutton, state == WL_POINTER_BUTTON_STATE_PRESSED);
- input->system->pushEvent(
- new GHOST_EventButton(input->system->getMilliSeconds(),
- etype,
- input->system->getWindowManager()->getActiveWindow(),
- ebutton,
- GHOST_TABLET_DATA_NONE));
+ input->system->pushEvent(new GHOST_EventButton(
+ input->system->getMilliSeconds(), etype, win, ebutton, GHOST_TABLET_DATA_NONE));
}
static void pointer_axis(void *data,
@@ -863,10 +906,10 @@ static void pointer_axis(void *data,
return;
}
input_t *input = static_cast<input_t *>(data);
+ GHOST_IWindow *win = static_cast<GHOST_WindowWayland *>(
+ wl_surface_get_user_data(input->focus_pointer));
input->system->pushEvent(
- new GHOST_EventWheel(input->system->getMilliSeconds(),
- input->system->getWindowManager()->getActiveWindow(),
- std::signbit(value) ? +1 : -1));
+ new GHOST_EventWheel(input->system->getMilliSeconds(), win, std::signbit(value) ? +1 : -1));
}
static const struct wl_pointer_listener pointer_listener = {
@@ -913,13 +956,15 @@ static void keyboard_keymap(
* Notification that this seat's keyboard focus is on a certain
* surface.
*/
-static void keyboard_enter(void * /*data*/,
+static void keyboard_enter(void *data,
struct wl_keyboard * /*wl_keyboard*/,
uint32_t /*serial*/,
- struct wl_surface * /*surface*/,
+ struct wl_surface *surface,
struct wl_array * /*keys*/)
{
- /* pass */
+ if (surface != nullptr) {
+ static_cast<input_t *>(data)->focus_keyboard = surface;
+ }
}
/**
@@ -928,12 +973,14 @@ static void keyboard_enter(void * /*data*/,
* Notification that this seat's keyboard focus is no longer on a
* certain surface.
*/
-static void keyboard_leave(void * /*data*/,
+static void keyboard_leave(void *data,
struct wl_keyboard * /*wl_keyboard*/,
uint32_t /*serial*/,
- struct wl_surface * /*surface*/)
+ struct wl_surface *surface)
{
- /* pass */
+ if (surface != nullptr) {
+ static_cast<input_t *>(data)->focus_keyboard = nullptr;
+ }
}
/**
@@ -988,6 +1035,14 @@ static void keyboard_key(void *data,
}
const GHOST_TKey gkey = xkb_map_gkey(sym);
+ /* Delete previous timer. */
+ if (xkb_keymap_key_repeats(xkb_state_get_keymap(input->xkb_state), key + 8) &&
+ input->key_repeat.timer) {
+ delete static_cast<key_repeat_payload_t *>(input->key_repeat.timer->getUserData());
+ input->system->removeTimer(input->key_repeat.timer);
+ input->key_repeat.timer = nullptr;
+ }
+
GHOST_TEventKeyData key_data;
if (etype == GHOST_kEventKeyDown) {
@@ -999,13 +1054,38 @@ static void keyboard_key(void *data,
}
input->data_source->source_serial = serial;
- input->system->pushEvent(new GHOST_EventKey(input->system->getMilliSeconds(),
- etype,
- input->system->getWindowManager()->getActiveWindow(),
- gkey,
- '\0',
- key_data.utf8_buf,
- false));
+
+ GHOST_IWindow *win = static_cast<GHOST_WindowWayland *>(
+ wl_surface_get_user_data(input->focus_keyboard));
+ input->system->pushEvent(new GHOST_EventKey(
+ input->system->getMilliSeconds(), etype, win, gkey, '\0', key_data.utf8_buf, false));
+
+ /* Start timer for repeating key, if applicable. */
+ if (input->key_repeat.rate > 0 &&
+ xkb_keymap_key_repeats(xkb_state_get_keymap(input->xkb_state), key + 8) &&
+ etype == GHOST_kEventKeyDown) {
+
+ key_repeat_payload_t *payload = new key_repeat_payload_t({
+ .system = input->system,
+ .window = win,
+ .key = gkey,
+ .key_data = key_data,
+ });
+
+ auto cb = [](GHOST_ITimerTask *task, GHOST_TUns64 /*time*/) {
+ struct key_repeat_payload_t *payload = static_cast<key_repeat_payload_t *>(
+ task->getUserData());
+ payload->system->pushEvent(new GHOST_EventKey(payload->system->getMilliSeconds(),
+ GHOST_kEventKeyDown,
+ payload->window,
+ payload->key,
+ '\0',
+ payload->key_data.utf8_buf,
+ true));
+ };
+ input->key_repeat.timer = input->system->installTimer(
+ input->key_repeat.delay, 1000 / input->key_repeat.rate, cb, payload);
+ }
}
static void keyboard_modifiers(void *data,
@@ -1025,12 +1105,24 @@ static void keyboard_modifiers(void *data,
group);
}
+static void keyboard_repeat_info(void *data,
+ struct wl_keyboard * /*wl_keyboard*/,
+ int32_t rate,
+ int32_t delay)
+{
+ input_t *input = static_cast<input_t *>(data);
+
+ input->key_repeat.rate = rate;
+ input->key_repeat.delay = delay;
+}
+
static const struct wl_keyboard_listener keyboard_listener = {
keyboard_keymap,
keyboard_enter,
keyboard_leave,
keyboard_key,
keyboard_modifiers,
+ keyboard_repeat_info,
};
static void seat_capabilities(void *data, struct wl_seat *wl_seat, uint32_t capabilities)
@@ -1163,7 +1255,7 @@ static void global_add(void *data,
input->relative_pointer = nullptr;
input->locked_pointer = nullptr;
input->seat = static_cast<wl_seat *>(
- wl_registry_bind(wl_registry, name, &wl_seat_interface, 2));
+ wl_registry_bind(wl_registry, name, &wl_seat_interface, 4));
display->inputs.push_back(input);
wl_seat_add_listener(input->seat, &seat_listener, input);
}
@@ -1260,10 +1352,18 @@ GHOST_SystemWayland::~GHOST_SystemWayland()
display_destroy(d);
}
-bool GHOST_SystemWayland::processEvents(bool /*waitForEvent*/)
+bool GHOST_SystemWayland::processEvents(bool waitForEvent)
{
- wl_display_dispatch(d->display);
- return true;
+ const bool fired = getTimerManager()->fireTimers(getMilliSeconds());
+
+ if (waitForEvent) {
+ wl_display_dispatch(d->display);
+ }
+ else {
+ wl_display_roundtrip(d->display);
+ }
+
+ return fired || (getEventManager()->getNumEvents() > 0);
}
int GHOST_SystemWayland::toggleConsole(int /*action*/)
@@ -1352,7 +1452,7 @@ GHOST_TUns8 GHOST_SystemWayland::getNumDisplays() const
GHOST_TSuccess GHOST_SystemWayland::getCursorPosition(GHOST_TInt32 &x, GHOST_TInt32 &y) const
{
- if (getWindowManager()->getActiveWindow() != nullptr && !d->inputs.empty()) {
+ if (!d->inputs.empty() && (d->inputs[0]->focus_pointer != nullptr)) {
x = d->inputs[0]->x;
y = d->inputs[0]->y;
return GHOST_kSuccess;
diff --git a/intern/guardedalloc/CMakeLists.txt b/intern/guardedalloc/CMakeLists.txt
index 1d4f846623c..cb24df65ba0 100644
--- a/intern/guardedalloc/CMakeLists.txt
+++ b/intern/guardedalloc/CMakeLists.txt
@@ -53,6 +53,14 @@ if(WIN32 AND NOT UNIX)
mmap_win.h
)
+
+ list(APPEND INC_SYS
+ ${PTHREADS_INC}
+ )
+
+ list(APPEND LIB
+ ${PTHREADS_LIBRARIES}
+ )
endif()
# Jemalloc 5.0.0+ needs extra configuration.
diff --git a/intern/guardedalloc/MEM_guardedalloc.h b/intern/guardedalloc/MEM_guardedalloc.h
index d5b109ee59f..602297576c8 100644
--- a/intern/guardedalloc/MEM_guardedalloc.h
+++ b/intern/guardedalloc/MEM_guardedalloc.h
@@ -145,14 +145,6 @@ extern void *(*MEM_mallocN_aligned)(size_t len,
const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT
ATTR_ALLOC_SIZE(1) ATTR_NONNULL(3);
-/**
- * Same as callocN, clears memory and uses mmap (disk cached) if supported.
- * Can be free'd with MEM_freeN as usual.
- * */
-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 */
extern void (*MEM_printmemlist_pydict)(void);
@@ -176,20 +168,11 @@ extern void (*MEM_set_error_callback)(void (*func)(const char *));
* @retval true for correct memory, false for corrupted memory. */
extern bool (*MEM_consistency_check)(void);
-/** Set thread locking functions for safe memory allocation from multiple
- * threads, pass NULL pointers to disable thread locking again. */
-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 */
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 */
+/** Memory usage stats. */
extern size_t (*MEM_get_memory_in_use)(void);
-/** Get mapped memory usage. */
-extern size_t (*MEM_get_mapped_memory_in_use)(void);
/** Get amount of memory blocks in use. */
extern unsigned int (*MEM_get_memory_blocks_in_use)(void);
diff --git a/intern/guardedalloc/intern/mallocn.c b/intern/guardedalloc/intern/mallocn.c
index d24437c85f2..e85f8eb03ed 100644
--- a/intern/guardedalloc/intern/mallocn.c
+++ b/intern/guardedalloc/intern/mallocn.c
@@ -48,18 +48,14 @@ void *(*MEM_malloc_arrayN)(size_t len, size_t size, const char *str) = MEM_lockf
void *(*MEM_mallocN_aligned)(size_t len,
size_t alignment,
const char *str) = MEM_lockfree_mallocN_aligned;
-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_consistency_check)(void) = MEM_lockfree_consistency_check;
-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;
size_t (*MEM_get_memory_in_use)(void) = MEM_lockfree_get_memory_in_use;
-size_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;
size_t (*MEM_get_peak_memory)(void) = MEM_lockfree_get_peak_memory;
@@ -111,17 +107,14 @@ void MEM_use_guarded_allocator(void)
MEM_mallocN = MEM_guarded_mallocN;
MEM_malloc_arrayN = MEM_guarded_malloc_arrayN;
MEM_mallocN_aligned = MEM_guarded_mallocN_aligned;
- 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_consistency_check = MEM_guarded_consistency_check;
- 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;
diff --git a/intern/guardedalloc/intern/mallocn_guarded_impl.c b/intern/guardedalloc/intern/mallocn_guarded_impl.c
index f601609c6e0..20dcbed7235 100644
--- a/intern/guardedalloc/intern/mallocn_guarded_impl.c
+++ b/intern/guardedalloc/intern/mallocn_guarded_impl.c
@@ -28,6 +28,8 @@
#include <string.h> /* memcpy */
#include <sys/types.h>
+#include <pthread.h>
+
#include "MEM_guardedalloc.h"
/* to ensure strict conversions */
@@ -51,17 +53,6 @@
//#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.
@@ -104,7 +95,7 @@ typedef struct MemHead {
const char *name;
const char *nextname;
int tag2;
- short mmap; /* if true, memory was mmapped */
+ short pad1;
short alignment; /* if non-zero aligned alloc was used
* and alignment is stored here.
*/
@@ -124,24 +115,6 @@ typedef struct MemHead {
typedef MemHead MemHeadAligned;
-/* 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>
@@ -187,13 +160,11 @@ static const char *check_memlist(MemHead *memh);
/* --------------------------------------------------------------------- */
static unsigned int totblock = 0;
-static size_t mem_in_use = 0, mmap_in_use = 0, peak_mem = 0;
+static size_t mem_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;
@@ -233,40 +204,16 @@ print_error(const char *str, ...)
fputs(buf, stderr);
}
+static pthread_mutex_t thread_lock = PTHREAD_MUTEX_INITIALIZER;
+
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();
+ pthread_mutex_lock(&thread_lock);
}
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();
+ pthread_mutex_unlock(&thread_lock);
}
bool MEM_guarded_consistency_check(void)
@@ -287,12 +234,6 @@ 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;
@@ -320,10 +261,8 @@ void *MEM_guarded_dupallocN(const void *vmemh)
memh--;
#ifndef DEBUG_MEMDUPLINAME
- if (UNLIKELY(memh->mmap))
- newp = MEM_guarded_mapallocN(memh->len, "dupli_mapalloc");
- else if (LIKELY(memh->alignment == 0))
- newp = MEM_guarded_mapallocN(memh->len, "dupli_mapalloc");
+ if (LIKELY(memh->alignment == 0))
+ newp = MEM_guarded_mallocN(memh->len, "dupli_alloc");
else
newp = MEM_guarded_mallocN_aligned(memh->len, (size_t)memh->alignment, "dupli_alloc");
@@ -334,11 +273,7 @@ void *MEM_guarded_dupallocN(const void *vmemh)
MemHead *nmemh;
char *name = malloc(strlen(memh->name) + 24);
- if (UNLIKELY(memh->mmap)) {
- sprintf(name, "%s %s", "dupli_mapalloc", memh->name);
- newp = MEM_guarded_mapallocN(memh->len, name);
- }
- else if (LIKELY(memh->alignment == 0)) {
+ if (LIKELY(memh->alignment == 0)) {
sprintf(name, "%s %s", "dupli_alloc", memh->name);
newp = MEM_guarded_mallocN(memh->len, name);
}
@@ -478,7 +413,7 @@ static void make_memhead_header(MemHead *memh, size_t len, const char *str)
memh->name = str;
memh->nextname = NULL;
memh->len = len;
- memh->mmap = 0;
+ memh->pad1 = 0;
memh->alignment = 0;
memh->tag2 = MEMTAG2;
@@ -646,58 +581,6 @@ void *MEM_guarded_calloc_arrayN(size_t len, size_t size, const char *str)
return MEM_guarded_callocN(total_size, str);
}
-/* note; mmap returns zero'd memory */
-void *MEM_guarded_mapallocN(size_t len, const char *str)
-{
- MemHead *memh;
-
- /* on 64 bit, simply use calloc instead, as mmap does not support
- * allocating > 4 GB on Windows. the only reason mapalloc exists
- * is to get around address space limitations in 32 bit OSes. */
- if (sizeof(void *) >= 8)
- return MEM_guarded_callocN(len, str);
-
- 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_and_fetch_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;
@@ -765,7 +648,7 @@ void MEM_guarded_printmemlist_stats(void)
pb++;
#ifdef USE_MALLOC_USABLE_SIZE
- if (!membl->mmap && membl->alignment == 0) {
+ if (membl->alignment == 0) {
mem_in_use_slop += (sizeof(MemHead) + sizeof(MemTail) + malloc_usable_size((void *)membl)) -
membl->len;
}
@@ -1098,27 +981,13 @@ static void rem_memblock(MemHead *memh)
free((char *)memh->name);
#endif
- if (memh->mmap) {
- atomic_sub_and_fetch_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
+ if (UNLIKELY(malloc_debug_memset && memh->len))
+ memset(memh + 1, 255, memh->len);
+ if (LIKELY(memh->alignment == 0)) {
+ free(memh);
}
else {
- if (UNLIKELY(malloc_debug_memset && memh->len))
- memset(memh + 1, 255, memh->len);
- if (LIKELY(memh->alignment == 0)) {
- free(memh);
- }
- else {
- aligned_free(MEMHEAD_REAL_PTR(memh));
- }
+ aligned_free(MEMHEAD_REAL_PTR(memh));
}
}
@@ -1270,17 +1139,6 @@ size_t MEM_guarded_get_memory_in_use(void)
return _mem_in_use;
}
-size_t MEM_guarded_get_mapped_memory_in_use(void)
-{
- size_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;
diff --git a/intern/guardedalloc/intern/mallocn_intern.h b/intern/guardedalloc/intern/mallocn_intern.h
index 876607fdb77..ef8845a66b3 100644
--- a/intern/guardedalloc/intern/mallocn_intern.h
+++ b/intern/guardedalloc/intern/mallocn_intern.h
@@ -24,13 +24,6 @@
#ifndef __MALLOCN_INTERN_H__
#define __MALLOCN_INTERN_H__
-/* mmap exception */
-#if defined(WIN32)
-# include "mmap_win.h"
-#else
-# include <sys/mman.h>
-#endif
-
#ifdef __GNUC__
# define UNUSED(x) UNUSED_##x __attribute__((__unused__))
#else
@@ -140,19 +133,14 @@ void *MEM_lockfree_mallocN_aligned(size_t len,
size_t alignment,
const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
ATTR_ALLOC_SIZE(1) ATTR_NONNULL(3);
-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_consistency_check(void);
-void MEM_lockfree_set_lock_callback(void (*lock)(void), void (*unlock)(void));
void MEM_lockfree_set_memory_debug(void);
size_t MEM_lockfree_get_memory_in_use(void);
-size_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);
size_t MEM_lockfree_get_peak_memory(void) ATTR_WARN_UNUSED_RESULT;
@@ -188,19 +176,14 @@ void *MEM_guarded_mallocN_aligned(size_t len,
size_t alignment,
const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
ATTR_ALLOC_SIZE(1) ATTR_NONNULL(3);
-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_consistency_check(void);
-void MEM_guarded_set_lock_callback(void (*lock)(void), void (*unlock)(void));
void MEM_guarded_set_memory_debug(void);
size_t MEM_guarded_get_memory_in_use(void);
-size_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);
size_t MEM_guarded_get_peak_memory(void) ATTR_WARN_UNUSED_RESULT;
diff --git a/intern/guardedalloc/intern/mallocn_lockfree_impl.c b/intern/guardedalloc/intern/mallocn_lockfree_impl.c
index ab7d9097669..205cc688d72 100644
--- a/intern/guardedalloc/intern/mallocn_lockfree_impl.c
+++ b/intern/guardedalloc/intern/mallocn_lockfree_impl.c
@@ -44,22 +44,18 @@ typedef struct MemHeadAligned {
} MemHeadAligned;
static unsigned int totblock = 0;
-static size_t mem_in_use = 0, mmap_in_use = 0, peak_mem = 0;
+static size_t mem_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;
enum {
- MEMHEAD_MMAP_FLAG = 1,
- MEMHEAD_ALIGN_FLAG = 2,
+ MEMHEAD_ALIGN_FLAG = 1,
};
#define MEMHEAD_FROM_PTR(ptr) (((MemHead *)ptr) - 1)
#define PTR_FROM_MEMHEAD(memhead) (memhead + 1)
#define MEMHEAD_ALIGNED_FROM_PTR(ptr) (((MemHeadAligned *)ptr) - 1)
-#define MEMHEAD_IS_MMAP(memhead) ((memhead)->len & (size_t)MEMHEAD_MMAP_FLAG)
#define MEMHEAD_IS_ALIGNED(memhead) ((memhead)->len & (size_t)MEMHEAD_ALIGN_FLAG)
/* Uncomment this to have proper peak counter. */
@@ -93,24 +89,10 @@ print_error(const char *str, ...)
}
}
-#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)(MEMHEAD_MMAP_FLAG | MEMHEAD_ALIGN_FLAG));
+ return MEMHEAD_FROM_PTR(vmemh)->len & ~((size_t)(MEMHEAD_ALIGN_FLAG));
}
else {
return 0;
@@ -133,29 +115,15 @@ void MEM_lockfree_freeN(void *vmemh)
atomic_sub_and_fetch_u(&totblock, 1);
atomic_sub_and_fetch_z(&mem_in_use, len);
- if (MEMHEAD_IS_MMAP(memh)) {
- atomic_sub_and_fetch_z(&mmap_in_use, len);
-#if defined(WIN32)
- /* our windows mmap implementation is not thread safe */
- mem_lock_thread();
-#endif
- if (munmap(memh, len + sizeof(MemHead)))
- printf("Couldn't unmap memory\n");
-#if defined(WIN32)
- mem_unlock_thread();
-#endif
+ if (UNLIKELY(malloc_debug_memset && len)) {
+ memset(memh + 1, 255, len);
+ }
+ if (UNLIKELY(MEMHEAD_IS_ALIGNED(memh))) {
+ MemHeadAligned *memh_aligned = MEMHEAD_ALIGNED_FROM_PTR(vmemh);
+ aligned_free(MEMHEAD_REAL_PTR(memh_aligned));
}
else {
- if (UNLIKELY(malloc_debug_memset && len)) {
- memset(memh + 1, 255, len);
- }
- if (UNLIKELY(MEMHEAD_IS_ALIGNED(memh))) {
- MemHeadAligned *memh_aligned = MEMHEAD_ALIGNED_FROM_PTR(vmemh);
- aligned_free(MEMHEAD_REAL_PTR(memh_aligned));
- }
- else {
- free(memh);
- }
+ free(memh);
}
}
@@ -165,10 +133,7 @@ void *MEM_lockfree_dupallocN(const void *vmemh)
if (vmemh) {
MemHead *memh = MEMHEAD_FROM_PTR(vmemh);
const size_t prev_size = MEM_lockfree_allocN_len(vmemh);
- if (UNLIKELY(MEMHEAD_IS_MMAP(memh))) {
- newp = MEM_lockfree_mapallocN(prev_size, "dupli_mapalloc");
- }
- else if (UNLIKELY(MEMHEAD_IS_ALIGNED(memh))) {
+ if (UNLIKELY(MEMHEAD_IS_ALIGNED(memh))) {
MemHeadAligned *memh_aligned = MEMHEAD_ALIGNED_FROM_PTR(vmemh);
newp = MEM_lockfree_mallocN_aligned(
prev_size, (size_t)memh_aligned->alignment, "dupli_malloc");
@@ -397,47 +362,6 @@ void *MEM_lockfree_mallocN_aligned(size_t len, size_t alignment, const char *str
return NULL;
}
-void *MEM_lockfree_mapallocN(size_t len, const char *str)
-{
- MemHead *memh;
-
- /* on 64 bit, simply use calloc instead, as mmap does not support
- * allocating > 4 GB on Windows. the only reason mapalloc exists
- * is to get around address space limitations in 32 bit OSes. */
- if (sizeof(void *) >= 8)
- return MEM_lockfree_callocN(len, str);
-
- 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)MEMHEAD_MMAP_FLAG;
- atomic_add_and_fetch_u(&totblock, 1);
- atomic_add_and_fetch_z(&mem_in_use, len);
- atomic_add_and_fetch_z(&mmap_in_use, len);
-
- update_maximum(&peak_mem, mem_in_use);
- update_maximum(&peak_mem, mmap_in_use);
-
- 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)
{
}
@@ -476,12 +400,6 @@ bool MEM_lockfree_consistency_check(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;
@@ -492,11 +410,6 @@ size_t MEM_lockfree_get_memory_in_use(void)
return mem_in_use;
}
-size_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;
diff --git a/intern/libmv/libmv/autotrack/reconstruction.h b/intern/libmv/libmv/autotrack/reconstruction.h
index 7b34a0951a3..732e74063f1 100644
--- a/intern/libmv/libmv/autotrack/reconstruction.h
+++ b/intern/libmv/libmv/autotrack/reconstruction.h
@@ -23,6 +23,7 @@
#ifndef LIBMV_AUTOTRACK_RECONSTRUCTION_H_
#define LIBMV_AUTOTRACK_RECONSTRUCTION_H_
+#include "libmv/base/map.h"
#include "libmv/base/vector.h"
#include "libmv/numeric/numeric.h"
#include "libmv/simple_pipeline/camera_intrinsics.h"
@@ -75,7 +76,7 @@ class Reconstruction {
vector<CameraIntrinsics*> camera_intrinsics_;
// Indexed by Marker::clip then by Marker::frame.
- vector<vector<CameraPose> > camera_poses_;
+ vector<map<int, CameraPose>> camera_poses_;
// Indexed by Marker::track.
vector<Point> points_;
diff --git a/intern/libmv/libmv/simple_pipeline/bundle.cc b/intern/libmv/libmv/simple_pipeline/bundle.cc
index a70fdbc9888..2ecc0505e1f 100644
--- a/intern/libmv/libmv/simple_pipeline/bundle.cc
+++ b/intern/libmv/libmv/simple_pipeline/bundle.cc
@@ -24,6 +24,7 @@
#include "ceres/ceres.h"
#include "ceres/rotation.h"
+#include "libmv/base/map.h"
#include "libmv/base/vector.h"
#include "libmv/logging/logging.h"
#include "libmv/multiview/fundamental.h"
@@ -407,47 +408,39 @@ void UnpackIntrinsicsFromArray(const double intrinsics_block[OFFSET_MAX],
// Get a vector of camera's rotations denoted by angle axis
// conjuncted with translations into single block
//
-// Element with index i matches to a rotation+translation for
+// Element with key i matches to a rotation+translation for
// camera at image i.
-vector<Vec6> PackCamerasRotationAndTranslation(
- const Tracks &tracks,
+map<int, Vec6> PackCamerasRotationAndTranslation(
const EuclideanReconstruction &reconstruction) {
- vector<Vec6> all_cameras_R_t;
- int max_image = tracks.MaxImage();
-
- all_cameras_R_t.resize(max_image + 1);
-
- for (int i = 0; i <= max_image; i++) {
- const EuclideanCamera *camera = reconstruction.CameraForImage(i);
-
- if (!camera) {
- continue;
- }
-
- ceres::RotationMatrixToAngleAxis(&camera->R(0, 0),
- &all_cameras_R_t[i](0));
- all_cameras_R_t[i].tail<3>() = camera->t;
+ map<int, Vec6> all_cameras_R_t;
+
+ vector<EuclideanCamera> all_cameras = reconstruction.AllCameras();
+ for (const EuclideanCamera& camera : all_cameras) {
+ Vec6 camera_R_t;
+ ceres::RotationMatrixToAngleAxis(&camera.R(0, 0), &camera_R_t(0));
+ camera_R_t.tail<3>() = camera.t;
+ all_cameras_R_t.insert(make_pair(camera.image, camera_R_t));
}
+
return all_cameras_R_t;
}
// Convert cameras rotations fro mangle axis back to rotation matrix.
void UnpackCamerasRotationAndTranslation(
- const Tracks &tracks,
- const vector<Vec6> &all_cameras_R_t,
+ const map<int, Vec6> &all_cameras_R_t,
EuclideanReconstruction *reconstruction) {
- int max_image = tracks.MaxImage();
- for (int i = 0; i <= max_image; i++) {
- EuclideanCamera *camera = reconstruction->CameraForImage(i);
+ for (map<int, Vec6>::value_type image_and_camera_R_T : all_cameras_R_t) {
+ const int image = image_and_camera_R_T.first;
+ const Vec6& camera_R_t = image_and_camera_R_T.second;
+ EuclideanCamera *camera = reconstruction->CameraForImage(image);
if (!camera) {
continue;
}
- ceres::AngleAxisToRotationMatrix(&all_cameras_R_t[i](0),
- &camera->R(0, 0));
- camera->t = all_cameras_R_t[i].tail<3>();
+ ceres::AngleAxisToRotationMatrix(&camera_R_t(0), &camera->R(0, 0));
+ camera->t = camera_R_t.tail<3>();
}
}
@@ -476,7 +469,7 @@ void CRSMatrixToEigenMatrix(const ceres::CRSMatrix &crs_matrix,
void EuclideanBundlerPerformEvaluation(const Tracks &tracks,
EuclideanReconstruction *reconstruction,
- vector<Vec6> *all_cameras_R_t,
+ map<int, Vec6> *all_cameras_R_t,
ceres::Problem *problem,
BundleEvaluation *evaluation) {
int max_track = tracks.MaxTrack();
@@ -603,7 +596,7 @@ void AddResidualBlockToProblem(const CameraIntrinsics *invariant_intrinsics,
// are to be totally still here.
void EuclideanBundlePointsOnly(const CameraIntrinsics *invariant_intrinsics,
const vector<Marker> &markers,
- vector<Vec6> &all_cameras_R_t,
+ map<int, Vec6> &all_cameras_R_t,
double intrinsics_block[OFFSET_MAX],
EuclideanReconstruction *reconstruction) {
ceres::Problem::Options problem_options;
@@ -699,8 +692,8 @@ void EuclideanBundleCommonIntrinsics(
//
// Block for minimization has got the following structure:
// <3 elements for angle-axis> <3 elements for translation>
- vector<Vec6> all_cameras_R_t =
- PackCamerasRotationAndTranslation(tracks, *reconstruction);
+ map<int, Vec6> all_cameras_R_t =
+ PackCamerasRotationAndTranslation(*reconstruction);
// Parameterization used to restrict camera motion for modal solvers.
ceres::SubsetParameterization *constant_translation_parameterization = NULL;
@@ -827,9 +820,7 @@ void EuclideanBundleCommonIntrinsics(
LG << "Final report:\n" << summary.FullReport();
// Copy rotations and translations back.
- UnpackCamerasRotationAndTranslation(tracks,
- all_cameras_R_t,
- reconstruction);
+ UnpackCamerasRotationAndTranslation(all_cameras_R_t, reconstruction);
// Copy intrinsics back.
if (bundle_intrinsics != BUNDLE_NO_INTRINSICS)
diff --git a/intern/libmv/libmv/simple_pipeline/reconstruction.cc b/intern/libmv/libmv/simple_pipeline/reconstruction.cc
index 65e5dd27d5d..851eedb5bb1 100644
--- a/intern/libmv/libmv/simple_pipeline/reconstruction.cc
+++ b/intern/libmv/libmv/simple_pipeline/reconstruction.cc
@@ -27,14 +27,14 @@ namespace libmv {
EuclideanReconstruction::EuclideanReconstruction() {}
EuclideanReconstruction::EuclideanReconstruction(
const EuclideanReconstruction &other) {
- cameras_ = other.cameras_;
+ image_to_cameras_map_ = other.image_to_cameras_map_;
points_ = other.points_;
}
EuclideanReconstruction &EuclideanReconstruction::operator=(
const EuclideanReconstruction &other) {
if (&other != this) {
- cameras_ = other.cameras_;
+ image_to_cameras_map_ = other.image_to_cameras_map_;
points_ = other.points_;
}
return *this;
@@ -44,12 +44,13 @@ void EuclideanReconstruction::InsertCamera(int image,
const Mat3 &R,
const Vec3 &t) {
LG << "InsertCamera " << image << ":\nR:\n"<< R << "\nt:\n" << t;
- if (image >= cameras_.size()) {
- cameras_.resize(image + 1);
- }
- cameras_[image].image = image;
- cameras_[image].R = R;
- cameras_[image].t = t;
+
+ EuclideanCamera camera;
+ camera.image = image;
+ camera.R = R;
+ camera.t = t;
+
+ image_to_cameras_map_.insert(make_pair(image, camera));
}
void EuclideanReconstruction::InsertPoint(int track, const Vec3 &X) {
@@ -69,22 +70,18 @@ EuclideanCamera *EuclideanReconstruction::CameraForImage(int image) {
const EuclideanCamera *EuclideanReconstruction::CameraForImage(
int image) const {
- if (image < 0 || image >= cameras_.size()) {
+ ImageToCameraMap::const_iterator it = image_to_cameras_map_.find(image);
+ if (it == image_to_cameras_map_.end()) {
return NULL;
}
- const EuclideanCamera *camera = &cameras_[image];
- if (camera->image == -1) {
- return NULL;
- }
- return camera;
+ return &it->second;
}
vector<EuclideanCamera> EuclideanReconstruction::AllCameras() const {
vector<EuclideanCamera> cameras;
- for (int i = 0; i < cameras_.size(); ++i) {
- if (cameras_[i].image != -1) {
- cameras.push_back(cameras_[i]);
- }
+ for (const ImageToCameraMap::value_type& image_and_camera :
+ image_to_cameras_map_) {
+ cameras.push_back(image_and_camera.second);
}
return cameras;
}
@@ -115,14 +112,14 @@ vector<EuclideanPoint> EuclideanReconstruction::AllPoints() const {
return points;
}
-void ProjectiveReconstruction::InsertCamera(int image,
- const Mat34 &P) {
+void ProjectiveReconstruction::InsertCamera(int image, const Mat34 &P) {
LG << "InsertCamera " << image << ":\nP:\n"<< P;
- if (image >= cameras_.size()) {
- cameras_.resize(image + 1);
- }
- cameras_[image].image = image;
- cameras_[image].P = P;
+
+ ProjectiveCamera camera;
+ camera.image = image;
+ camera.P = P;
+
+ image_to_cameras_map_.insert(make_pair(image, camera));
}
void ProjectiveReconstruction::InsertPoint(int track, const Vec4 &X) {
@@ -142,22 +139,18 @@ ProjectiveCamera *ProjectiveReconstruction::CameraForImage(int image) {
const ProjectiveCamera *ProjectiveReconstruction::CameraForImage(
int image) const {
- if (image < 0 || image >= cameras_.size()) {
- return NULL;
+ ImageToCameraMap::const_iterator it = image_to_cameras_map_.find(image);
+ if (it == image_to_cameras_map_.end()) {
+ return NULL;
}
- const ProjectiveCamera *camera = &cameras_[image];
- if (camera->image == -1) {
- return NULL;
- }
- return camera;
+ return &it->second;
}
vector<ProjectiveCamera> ProjectiveReconstruction::AllCameras() const {
vector<ProjectiveCamera> cameras;
- for (int i = 0; i < cameras_.size(); ++i) {
- if (cameras_[i].image != -1) {
- cameras.push_back(cameras_[i]);
- }
+ for (const ImageToCameraMap::value_type& image_and_camera :
+ image_to_cameras_map_) {
+ cameras.push_back(image_and_camera.second);
}
return cameras;
}
diff --git a/intern/libmv/libmv/simple_pipeline/reconstruction.h b/intern/libmv/libmv/simple_pipeline/reconstruction.h
index 79c693c5e6d..544aeac042e 100644
--- a/intern/libmv/libmv/simple_pipeline/reconstruction.h
+++ b/intern/libmv/libmv/simple_pipeline/reconstruction.h
@@ -22,6 +22,7 @@
#define LIBMV_SIMPLE_PIPELINE_RECONSTRUCTION_H_
#include "libmv/base/vector.h"
+#include "libmv/base/map.h"
#include "libmv/numeric/numeric.h"
namespace libmv {
@@ -120,7 +121,11 @@ class EuclideanReconstruction {
vector<EuclideanPoint> AllPoints() const;
private:
- vector<EuclideanCamera> cameras_;
+ // Indexed by frame number.
+ typedef map<int, EuclideanCamera> ImageToCameraMap;
+ ImageToCameraMap image_to_cameras_map_;
+
+ // Insxed by track.
vector<EuclideanPoint> points_;
};
@@ -208,7 +213,11 @@ class ProjectiveReconstruction {
vector<ProjectivePoint> AllPoints() const;
private:
- vector<ProjectiveCamera> cameras_;
+ // Indexed by frame number.
+ typedef map<int, ProjectiveCamera> ImageToCameraMap;
+ ImageToCameraMap image_to_cameras_map_;
+
+ // Indexed by track.
vector<ProjectivePoint> points_;
};
diff --git a/intern/mantaflow/intern/MANTA_main.cpp b/intern/mantaflow/intern/MANTA_main.cpp
index 11ce32fb828..95013958561 100644
--- a/intern/mantaflow/intern/MANTA_main.cpp
+++ b/intern/mantaflow/intern/MANTA_main.cpp
@@ -81,6 +81,7 @@ MANTA::MANTA(int *res, FluidModifierData *mmd) : mCurrentID(++solverID)
mUsingNoise = (mds->flags & FLUID_DOMAIN_USE_NOISE) && mUsingSmoke;
mUsingFractions = (mds->flags & FLUID_DOMAIN_USE_FRACTIONS) && mUsingLiquid;
mUsingMesh = (mds->flags & FLUID_DOMAIN_USE_MESH) && mUsingLiquid;
+ mUsingDiffusion = (mds->flags & FLUID_DOMAIN_USE_DIFFUSION) && mUsingLiquid;
mUsingMVel = (mds->flags & FLUID_DOMAIN_USE_SPEED_VECTORS) && mUsingLiquid;
mUsingGuiding = (mds->flags & FLUID_DOMAIN_USE_GUIDE);
mUsingDrops = (mds->particle_type & FLUID_DOMAIN_PARTICLE_SPRAY) && mUsingLiquid;
@@ -230,6 +231,10 @@ MANTA::MANTA(int *res, FluidModifierData *mmd) : mCurrentID(++solverID)
initLiquidMesh();
}
+ if (mUsingDiffusion) {
+ initCurvature();
+ }
+
if (mUsingGuiding) {
mResGuiding = (mds->guide_parent) ? mds->guide_res : mds->res;
initGuiding();
@@ -438,6 +443,16 @@ void MANTA::initLiquidMesh(FluidModifierData *mmd)
mUsingMesh = true;
}
+void MANTA::initCurvature(FluidModifierData *mmd)
+{
+ std::vector<std::string> pythonCommands;
+ std::string finalString = parseScript(liquid_alloc_curvature, mmd);
+ pythonCommands.push_back(finalString);
+
+ runPythonString(pythonCommands);
+ mUsingDiffusion = true;
+}
+
void MANTA::initObstacle(FluidModifierData *mmd)
{
if (!mPhiObsIn) {
@@ -549,7 +564,7 @@ MANTA::~MANTA()
result = runPythonString(pythonCommands);
assert(result);
- (void)result; // not needed in release
+ UNUSED_VARS(result);
}
/**
@@ -574,8 +589,8 @@ bool MANTA::runPythonString(vector<string> commands)
manta_main_module = PyImport_ImportModule("__main__");
}
- for (vector<std::string>::iterator it = commands.begin(); it != commands.end(); ++it) {
- std::string command = *it;
+ for (vector<string>::iterator it = commands.begin(); it != commands.end(); ++it) {
+ string command = *it;
PyObject *globals_dict = PyModule_GetDict(manta_main_module);
PyObject *return_value = PyRun_String(
@@ -843,6 +858,23 @@ void MANTA::initializeRNAMap(FluidModifierData *mmd)
mRNAMap["GRAVITY_Y"] = to_string(mds->gravity[1]);
mRNAMap["GRAVITY_Z"] = to_string(mds->gravity[2]);
mRNAMap["CACHE_DIR"] = cacheDirectory;
+ mRNAMap["NAME_DENSITY"] = FLUID_GRIDNAME_DENSITY;
+ mRNAMap["NAME_SHADOW"] = FLUID_GRIDNAME_SHADOW;
+ mRNAMap["NAME_HEAT"] = FLUID_GRIDNAME_HEAT;
+ mRNAMap["NAME_VELOCITY"] = FLUID_GRIDNAME_VELOCITY;
+ mRNAMap["NAME_COLORR"] = FLUID_GRIDNAME_COLORR;
+ mRNAMap["NAME_COLORG"] = FLUID_GRIDNAME_COLORG;
+ mRNAMap["NAME_COLORB"] = FLUID_GRIDNAME_COLORB;
+ mRNAMap["NAME_FLAME"] = FLUID_GRIDNAME_FLAME;
+ mRNAMap["NAME_FUEL"] = FLUID_GRIDNAME_FUEL;
+ mRNAMap["NAME_REACT"] = FLUID_GRIDNAME_REACT;
+ mRNAMap["NAME_DENSITYNOISE"] = FLUID_GRIDNAME_DENSITYNOISE;
+ mRNAMap["NAME_COLORRNOISE"] = FLUID_GRIDNAME_COLORRNOISE;
+ mRNAMap["NAME_COLORGNOISE"] = FLUID_GRIDNAME_COLORGNOISE;
+ mRNAMap["NAME_COLORBNOISE"] = FLUID_GRIDNAME_COLORBNOISE;
+ mRNAMap["NAME_FLAMENOISE"] = FLUID_GRIDNAME_FLAMENOISE;
+ mRNAMap["NAME_FUELNOISE"] = FLUID_GRIDNAME_FUELNOISE;
+ mRNAMap["NAME_REACTNOISE"] = FLUID_GRIDNAME_REACTNOISE;
}
string MANTA::getRealValue(const string &varName)
@@ -933,8 +965,7 @@ bool MANTA::updateFlipStructures(FluidModifierData *mmd, int framenr)
mFlipParticleVelocity->clear();
string pformat = getCacheFileEnding(mds->cache_particle_format);
- string file = getFile(
- mmd, FLUID_DOMAIN_DIR_DATA, FLUID_DOMAIN_FILE_PP, pformat.c_str(), framenr);
+ string file = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_FILENAME_PP, pformat, framenr);
expected += 1;
if (BLI_exists(file.c_str())) {
@@ -942,7 +973,7 @@ bool MANTA::updateFlipStructures(FluidModifierData *mmd, int framenr)
assert(result == expected);
}
- file = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_DOMAIN_FILE_PVEL, pformat.c_str(), framenr);
+ file = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_FILENAME_PVEL, pformat, framenr);
expected += 1;
if (BLI_exists(file.c_str())) {
result += updateParticlesFromFile(file, false, true);
@@ -980,7 +1011,7 @@ bool MANTA::updateMeshStructures(FluidModifierData *mmd, int framenr)
string mformat = getCacheFileEnding(mds->cache_mesh_format);
string dformat = getCacheFileEnding(mds->cache_data_format);
- string file = getFile(mmd, FLUID_DOMAIN_DIR_MESH, FLUID_DOMAIN_FILE_MESH, mformat, framenr);
+ string file = getFile(mmd, FLUID_DOMAIN_DIR_MESH, FLUID_FILENAME_MESH, mformat, framenr);
expected += 1;
if (BLI_exists(file.c_str())) {
@@ -989,7 +1020,7 @@ bool MANTA::updateMeshStructures(FluidModifierData *mmd, int framenr)
}
if (mUsingMVel) {
- file = getFile(mmd, FLUID_DOMAIN_DIR_MESH, FLUID_DOMAIN_FILE_MESHVEL, dformat, framenr);
+ file = getFile(mmd, FLUID_DOMAIN_DIR_MESH, FLUID_FILENAME_MESHVEL, dformat, framenr);
expected += 1;
if (BLI_exists(file.c_str())) {
result += updateMeshFromFile(file);
@@ -1025,8 +1056,7 @@ bool MANTA::updateParticleStructures(FluidModifierData *mmd, int framenr)
mSndParticleLife->clear();
string pformat = getCacheFileEnding(mds->cache_particle_format);
- string file = getFile(
- mmd, FLUID_DOMAIN_DIR_PARTICLES, FLUID_DOMAIN_FILE_PPSND, pformat, framenr);
+ string file = getFile(mmd, FLUID_DOMAIN_DIR_PARTICLES, FLUID_FILENAME_PPSND, pformat, framenr);
expected += 1;
if (BLI_exists(file.c_str())) {
@@ -1034,14 +1064,14 @@ bool MANTA::updateParticleStructures(FluidModifierData *mmd, int framenr)
assert(result == expected);
}
- file = getFile(mmd, FLUID_DOMAIN_DIR_PARTICLES, FLUID_DOMAIN_FILE_PVELSND, pformat, framenr);
+ file = getFile(mmd, FLUID_DOMAIN_DIR_PARTICLES, FLUID_FILENAME_PVELSND, pformat, framenr);
expected += 1;
if (BLI_exists(file.c_str())) {
result += updateParticlesFromFile(file, true, true);
assert(result == expected);
}
- file = getFile(mmd, FLUID_DOMAIN_DIR_PARTICLES, FLUID_DOMAIN_FILE_PLIFESND, pformat, framenr);
+ file = getFile(mmd, FLUID_DOMAIN_DIR_PARTICLES, FLUID_FILENAME_PLIFESND, pformat, framenr);
expected += 1;
if (BLI_exists(file.c_str())) {
result += updateParticlesFromFile(file, true, false);
@@ -1051,6 +1081,26 @@ bool MANTA::updateParticleStructures(FluidModifierData *mmd, int framenr)
return mParticlesFromFile = (result == expected);
}
+static void assertGridItems(vector<MANTA::GridItem> gList)
+{
+ vector<MANTA::GridItem>::iterator gIter = gList.begin();
+ int *resPrev = (*gIter).res;
+
+ for (vector<MANTA::GridItem>::iterator it = gList.begin(); it != gList.end(); ++it) {
+ MANTA::GridItem item = *it;
+ assert(
+ ELEM(item.type, FLUID_DOMAIN_GRID_FLOAT, FLUID_DOMAIN_GRID_INT, FLUID_DOMAIN_GRID_VEC3F));
+ assert(item.pointer[0]);
+ if (item.type == FLUID_DOMAIN_GRID_VEC3F) {
+ assert(item.pointer[1] && item.pointer[2]);
+ }
+ assert(item.res[0] == resPrev[0] && item.res[1] == resPrev[1] && item.res[2] == resPrev[2]);
+ assert((item.name).compare("") != 0);
+ }
+
+ UNUSED_VARS(resPrev);
+}
+
bool MANTA::updateSmokeStructures(FluidModifierData *mmd, int framenr)
{
if (MANTA::with_debug)
@@ -1065,80 +1115,106 @@ bool MANTA::updateSmokeStructures(FluidModifierData *mmd, int framenr)
return false;
int result = 0;
- int expected = 0; /* Expected number of read successes for this frame. */
-
string dformat = getCacheFileEnding(mds->cache_data_format);
- string file = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_DOMAIN_FILE_DENSITY, dformat, framenr);
-
- expected += 1;
- if (BLI_exists(file.c_str())) {
- result += updateGridFromFile(file, mDensity, false);
- assert(result == expected);
- }
-
- file = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_DOMAIN_FILE_SHADOW, dformat, framenr);
- expected += 1;
- if (BLI_exists(file.c_str())) {
- result += updateGridFromFile(file, mShadow, false);
- assert(result == expected);
- }
- if (mUsingHeat) {
- file = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_DOMAIN_FILE_HEAT, dformat, framenr);
- expected += 1;
- if (BLI_exists(file.c_str())) {
- result += updateGridFromFile(file, mHeat, false);
- assert(result == expected);
+ vector<FileItem> filesData;
+ vector<GridItem> gridsData;
+
+ int res[] = {mResX, mResY, mResZ};
+
+ /* Put grid pointers into pointer lists, some grids have more than 1 pointer. */
+ void *aDensity[] = {mDensity};
+ void *aShadow[] = {mShadow};
+ void *aVelocities[] = {mVelocityX, mVelocityY, mVelocityZ};
+ void *aHeat[] = {mHeat};
+ void *aColorR[] = {mColorR};
+ void *aColorG[] = {mColorG};
+ void *aColorB[] = {mColorB};
+ void *aFlame[] = {mFlame};
+ void *aFuel[] = {mFuel};
+ void *aReact[] = {mReact};
+
+ /* File names for grids. */
+ string fDensity = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_FILENAME_DENSITY, dformat, framenr);
+ string fShadow = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_FILENAME_SHADOW, dformat, framenr);
+ string fVel = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_FILENAME_VELOCITY, dformat, framenr);
+ string fHeat = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_FILENAME_HEAT, dformat, framenr);
+ string fColorR = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_FILENAME_COLORR, dformat, framenr);
+ string fColorG = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_FILENAME_COLORG, dformat, framenr);
+ string fColorB = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_FILENAME_COLORB, dformat, framenr);
+ string fFlame = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_FILENAME_FLAME, dformat, framenr);
+ string fFuel = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_FILENAME_FUEL, dformat, framenr);
+ string fReact = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_FILENAME_REACT, dformat, framenr);
+ string fFluid = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_FILENAME_DATA, dformat, framenr);
+
+ /* Prepare grid info containers. */
+ GridItem gDensity = {aDensity, FLUID_DOMAIN_GRID_FLOAT, res, FLUID_GRIDNAME_DENSITY};
+ GridItem gShadow = {aShadow, FLUID_DOMAIN_GRID_FLOAT, res, FLUID_GRIDNAME_SHADOW};
+ GridItem gVel = {aVelocities, FLUID_DOMAIN_GRID_VEC3F, res, FLUID_GRIDNAME_VELOCITY};
+ GridItem gHeat = {aHeat, FLUID_DOMAIN_GRID_FLOAT, res, FLUID_GRIDNAME_HEAT};
+ GridItem gColorR = {aColorR, FLUID_DOMAIN_GRID_FLOAT, res, FLUID_GRIDNAME_COLORR};
+ GridItem gColorG = {aColorG, FLUID_DOMAIN_GRID_FLOAT, res, FLUID_GRIDNAME_COLORG};
+ GridItem gColorB = {aColorB, FLUID_DOMAIN_GRID_FLOAT, res, FLUID_GRIDNAME_COLORB};
+ GridItem gFlame = {aFlame, FLUID_DOMAIN_GRID_FLOAT, res, FLUID_GRIDNAME_FLAME};
+ GridItem gFuel = {aFuel, FLUID_DOMAIN_GRID_FLOAT, res, FLUID_GRIDNAME_FUEL};
+ GridItem gReact = {aReact, FLUID_DOMAIN_GRID_FLOAT, res, FLUID_GRIDNAME_REACT};
+
+ /* TODO (sebbas): For now, only allow single file mode. Combined grid file export is todo. */
+ const int fileMode = FLUID_DOMAIN_CACHE_FILES_SINGLE;
+ if (fileMode == FLUID_DOMAIN_CACHE_FILES_SINGLE) {
+
+ filesData.push_back({fDensity, {gDensity}});
+ filesData.push_back({fShadow, {gShadow}});
+ filesData.push_back({fVel, {gVel}});
+ if (mUsingHeat) {
+ filesData.push_back({fHeat, {gHeat}});
}
- }
-
- if (mUsingColors) {
- file = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_DOMAIN_FILE_COLORR, dformat, framenr);
- expected += 1;
- if (BLI_exists(file.c_str())) {
- result += updateGridFromFile(file, mColorR, false);
- assert(result == expected);
- }
-
- file = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_DOMAIN_FILE_COLORG, dformat, framenr);
- expected += 1;
- if (BLI_exists(file.c_str())) {
- result += updateGridFromFile(file, mColorG, false);
- assert(result == expected);
+ if (mUsingColors) {
+ filesData.push_back({fColorR, {gColorR}});
+ filesData.push_back({fColorG, {gColorG}});
+ filesData.push_back({fColorB, {gColorB}});
}
-
- file = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_DOMAIN_FILE_COLORB, dformat, framenr);
- expected += 1;
- if (BLI_exists(file.c_str())) {
- result += updateGridFromFile(file, mColorB, false);
- assert(result == expected);
+ if (mUsingFire) {
+ filesData.push_back({fFlame, {gFlame}});
+ filesData.push_back({fFuel, {gFuel}});
+ filesData.push_back({fReact, {gReact}});
}
}
+ else if (fileMode == FLUID_DOMAIN_CACHE_FILES_COMBINED) {
- if (mUsingFire) {
- file = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_DOMAIN_FILE_FLAME, dformat, framenr);
- expected += 1;
- if (BLI_exists(file.c_str())) {
- result += updateGridFromFile(file, mFlame, false);
- assert(result == expected);
+ gridsData.push_back(gDensity);
+ gridsData.push_back(gShadow);
+ gridsData.push_back(gVel);
+ if (mUsingHeat) {
+ gridsData.push_back(gHeat);
+ }
+ if (mUsingColors) {
+ gridsData.push_back(gColorR);
+ gridsData.push_back(gColorG);
+ gridsData.push_back(gColorB);
+ }
+ if (mUsingFire) {
+ gridsData.push_back(gFlame);
+ gridsData.push_back(gFuel);
+ gridsData.push_back(gReact);
}
- file = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_DOMAIN_FILE_FUEL, dformat, framenr);
- expected += 1;
- if (BLI_exists(file.c_str())) {
- result += updateGridFromFile(file, mFuel, false);
- assert(result == expected);
+ if (with_debug) {
+ assertGridItems(gridsData);
}
+ filesData.push_back({fFluid, gridsData});
+ }
- file = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_DOMAIN_FILE_REACT, dformat, framenr);
- expected += 1;
- if (BLI_exists(file.c_str())) {
- result += updateGridFromFile(file, mReact, false);
- assert(result == expected);
+ /* Update files from data directory. */
+ for (vector<FileItem>::iterator it = filesData.begin(); it != filesData.end(); ++it) {
+ FileItem item = *it;
+ if (BLI_exists(item.filename.c_str())) {
+ result += updateGridsFromFile(item.filename, item.grids);
+ assert(result);
}
}
- return mSmokeFromFile = (result == expected);
+ return mSmokeFromFile = result;
}
bool MANTA::updateNoiseStructures(FluidModifierData *mmd, int framenr)
@@ -1155,73 +1231,121 @@ bool MANTA::updateNoiseStructures(FluidModifierData *mmd, int framenr)
return false;
int result = 0;
- int expected = 0; /* Expected number of read successes for this frame. */
-
string dformat = getCacheFileEnding(mds->cache_data_format);
string nformat = getCacheFileEnding(mds->cache_noise_format);
- string file = getFile(
- mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_DOMAIN_FILE_DENSITYNOISE, nformat, framenr);
- expected += 1;
- if (BLI_exists(file.c_str())) {
- result += updateGridFromFile(file, mDensityHigh, true);
- assert(result == expected);
+ vector<FileItem> filesData, filesNoise;
+ vector<GridItem> gridsData, gridsNoise;
+
+ int resData[] = {mResX, mResY, mResZ};
+ int resNoise[] = {mResXNoise, mResYNoise, mResZNoise};
+
+ /* Put grid pointers into pointer lists, some grids have more than 1 pointer. */
+ void *aShadow[] = {mShadow};
+ void *aVelocities[] = {mVelocityX, mVelocityY, mVelocityZ};
+ void *aDensity[] = {mDensityHigh};
+ void *aColorR[] = {mColorRHigh};
+ void *aColorG[] = {mColorGHigh};
+ void *aColorB[] = {mColorBHigh};
+ void *aFlame[] = {mFlameHigh};
+ void *aFuel[] = {mFuelHigh};
+ void *aReact[] = {mReactHigh};
+
+ /* File names for grids. */
+ string fShadow = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_FILENAME_SHADOW, dformat, framenr);
+ string fVel = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_FILENAME_VELOCITY, dformat, framenr);
+ string fFluid = getFile(mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_FILENAME_DATA, dformat, framenr);
+
+ string fDensity = getFile(
+ mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_FILENAME_DENSITYNOISE, nformat, framenr);
+ string fColorR = getFile(
+ mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_FILENAME_COLORRNOISE, nformat, framenr);
+ string fColorG = getFile(
+ mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_FILENAME_COLORGNOISE, nformat, framenr);
+ string fColorB = getFile(
+ mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_FILENAME_COLORBNOISE, nformat, framenr);
+ string fFlame = getFile(
+ mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_FILENAME_FLAMENOISE, nformat, framenr);
+ string fFuel = getFile(mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_FILENAME_FUELNOISE, nformat, framenr);
+ string fReact = getFile(
+ mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_FILENAME_REACTNOISE, nformat, framenr);
+ string fNoise = getFile(mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_FILENAME_NOISE, nformat, framenr);
+
+ /* Prepare grid info containers. */
+ GridItem gShadow = {aShadow, FLUID_DOMAIN_GRID_FLOAT, resData, FLUID_GRIDNAME_SHADOW};
+ GridItem gVel = {aVelocities, FLUID_DOMAIN_GRID_VEC3F, resData, FLUID_GRIDNAME_VELOCITY};
+
+ GridItem gDensity = {aDensity, FLUID_DOMAIN_GRID_FLOAT, resNoise, FLUID_GRIDNAME_DENSITYNOISE};
+ GridItem gColorR = {aColorR, FLUID_DOMAIN_GRID_FLOAT, resNoise, FLUID_GRIDNAME_COLORRNOISE};
+ GridItem gColorG = {aColorG, FLUID_DOMAIN_GRID_FLOAT, resNoise, FLUID_GRIDNAME_COLORGNOISE};
+ GridItem gColorB = {aColorB, FLUID_DOMAIN_GRID_FLOAT, resNoise, FLUID_GRIDNAME_COLORBNOISE};
+ GridItem gFlame = {aFlame, FLUID_DOMAIN_GRID_FLOAT, resNoise, FLUID_GRIDNAME_FLAMENOISE};
+ GridItem gFuel = {aFuel, FLUID_DOMAIN_GRID_FLOAT, resNoise, FLUID_GRIDNAME_FUELNOISE};
+ GridItem gReact = {aReact, FLUID_DOMAIN_GRID_FLOAT, resNoise, FLUID_GRIDNAME_REACTNOISE};
+
+ /* TODO (sebbas): For now, only allow single file mode. Combined grid file export is todo. */
+ const int fileMode = FLUID_DOMAIN_CACHE_FILES_SINGLE;
+ if (fileMode == FLUID_DOMAIN_CACHE_FILES_SINGLE) {
+
+ filesData.push_back({fShadow, {gShadow}});
+ filesData.push_back({fVel, {gVel}});
+
+ filesNoise.push_back({fDensity, {gDensity}});
+ if (mUsingColors) {
+ filesNoise.push_back({fColorR, {gColorR}});
+ filesNoise.push_back({fColorG, {gColorG}});
+ filesNoise.push_back({fColorB, {gColorB}});
+ }
+ if (mUsingFire) {
+ filesNoise.push_back({fFlame, {gFlame}});
+ filesNoise.push_back({fFuel, {gFuel}});
+ filesNoise.push_back({fReact, {gReact}});
+ }
}
+ else if (fileMode == FLUID_DOMAIN_CACHE_FILES_COMBINED) {
- file = getFile(mmd, FLUID_DOMAIN_DIR_DATA, FLUID_DOMAIN_FILE_SHADOW, dformat, framenr);
- expected += 1;
- if (BLI_exists(file.c_str())) {
- result += updateGridFromFile(file, mShadow, false);
- assert(result == expected);
- }
+ gridsData.push_back(gShadow);
+ gridsData.push_back(gVel);
- if (mUsingColors) {
- file = getFile(mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_DOMAIN_FILE_COLORRNOISE, nformat, framenr);
- expected += 1;
- if (BLI_exists(file.c_str())) {
- result += updateGridFromFile(file, mColorRHigh, true);
- assert(result == expected);
+ gridsNoise.push_back(gDensity);
+ if (mUsingColors) {
+ gridsNoise.push_back(gColorR);
+ gridsNoise.push_back(gColorG);
+ gridsNoise.push_back(gColorB);
}
-
- file = getFile(mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_DOMAIN_FILE_COLORGNOISE, nformat, framenr);
- expected += 1;
- if (BLI_exists(file.c_str())) {
- result += updateGridFromFile(file, mColorGHigh, true);
- assert(result == expected);
+ if (mUsingFire) {
+ gridsNoise.push_back(gFlame);
+ gridsNoise.push_back(gFuel);
+ gridsNoise.push_back(gReact);
}
- file = getFile(mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_DOMAIN_FILE_COLORBNOISE, nformat, framenr);
- expected += 1;
- if (BLI_exists(file.c_str())) {
- result += updateGridFromFile(file, mColorBHigh, true);
- assert(result == expected);
+ if (with_debug) {
+ assertGridItems(gridsData);
+ assertGridItems(gridsNoise);
}
+ filesData.push_back({fFluid, gridsData});
+ filesNoise.push_back({fNoise, gridsNoise});
}
- if (mUsingFire) {
- file = getFile(mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_DOMAIN_FILE_FLAMENOISE, nformat, framenr);
- expected += 1;
- if (BLI_exists(file.c_str())) {
- result += updateGridFromFile(file, mFlameHigh, true);
- assert(result == expected);
- }
-
- file = getFile(mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_DOMAIN_FILE_FUELNOISE, nformat, framenr);
- expected += 1;
- if (BLI_exists(file.c_str())) {
- result += updateGridFromFile(file, mFuelHigh, true);
- assert(result == expected);
+ /* Update files from data directory. */
+ for (vector<FileItem>::iterator it = filesData.begin(); it != filesData.end(); ++it) {
+ FileItem item = *it;
+ if (BLI_exists(item.filename.c_str())) {
+ result += updateGridsFromFile(item.filename, item.grids);
+ assert(result);
}
+ }
- file = getFile(mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_DOMAIN_FILE_REACTNOISE, nformat, framenr);
- expected += 1;
- if (BLI_exists(file.c_str())) {
- result += updateGridFromFile(file, mReactHigh, true);
- assert(result == expected);
+ /* Update files from noise directory. */
+ for (vector<FileItem>::iterator it = filesNoise.begin(); it != filesNoise.end(); ++it) {
+ FileItem item = *it;
+ if (BLI_exists(item.filename.c_str())) {
+ result += updateGridsFromFile(item.filename, item.grids);
+ assert(result);
}
}
- return mNoiseFromFile = (result == expected);
+ return mNoiseFromFile = result;
}
/* Dirty hack: Needed to format paths from python code that is run via PyRun_SimpleString */
@@ -1247,7 +1371,7 @@ bool MANTA::writeConfiguration(FluidModifierData *mmd, int framenr)
string directory = getDirectory(mmd, FLUID_DOMAIN_DIR_CONFIG);
string format = FLUID_DOMAIN_EXTENSION_UNI;
- string file = getFile(mmd, FLUID_DOMAIN_DIR_CONFIG, FLUID_DOMAIN_FILE_CONFIG, format, framenr);
+ string file = getFile(mmd, FLUID_DOMAIN_DIR_CONFIG, FLUID_FILENAME_CONFIG, format, framenr);
/* Create 'config' subdir if it does not exist already. */
BLI_dir_create_recursive(directory.c_str());
@@ -1347,7 +1471,7 @@ bool MANTA::readConfiguration(FluidModifierData *mmd, int framenr)
string directory = getDirectory(mmd, FLUID_DOMAIN_DIR_CONFIG);
string format = FLUID_DOMAIN_EXTENSION_UNI;
- string file = getFile(mmd, FLUID_DOMAIN_DIR_CONFIG, FLUID_DOMAIN_FILE_CONFIG, format, framenr);
+ string file = getFile(mmd, FLUID_DOMAIN_DIR_CONFIG, FLUID_FILENAME_CONFIG, format, framenr);
if (!hasConfig(mmd, framenr))
return false;
@@ -2741,14 +2865,13 @@ bool MANTA::updateParticlesFromUni(string filename, bool isSecondarySys, bool is
return (gzclose(gzf) == Z_OK);
}
-bool MANTA::updateGridFromFile(string filename, float *grid, bool isNoise)
+bool MANTA::updateGridsFromFile(string filename, vector<GridItem> grids)
{
if (with_debug)
- cout << "MANTA::updateGridFromFile()" << endl;
+ cout << "MANTA::updateGridsFromFile()" << endl;
- if (!grid) {
- cerr << "Fluid Error -- updateGridFromFile(): Cannot read into uninitialized grid (grid "
- "is null)."
+ if (grids.empty()) {
+ cerr << "Fluid Error -- updateGridsFromFile(): Cannot read into uninitialized grid vector."
<< endl;
return false;
}
@@ -2758,118 +2881,142 @@ bool MANTA::updateGridFromFile(string filename, float *grid, bool isNoise)
idx = fname.rfind('.');
if (idx != string::npos) {
- string extension = fname.substr(idx + 1);
+ string extension = fname.substr(idx);
- if (extension.compare("uni") == 0)
- return updateGridFromUni(filename, grid, isNoise);
+ if (extension.compare(FLUID_DOMAIN_EXTENSION_UNI) == 0) {
+ return updateGridsFromUni(filename, grids);
+ }
#if OPENVDB == 1
- else if (extension.compare("vdb") == 0)
- return updateGridFromVDB(filename, grid, isNoise);
+ else if (extension.compare(FLUID_DOMAIN_EXTENSION_OPENVDB) == 0) {
+ return updateGridsFromVDB(filename, grids);
+ }
#endif
- else if (extension.compare("raw") == 0)
- return updateGridFromRaw(filename, grid, isNoise);
- else
- cerr << "Fluid Error -- updateGridFromFile(): Invalid file extension in file: " << filename
+ else if (extension.compare(FLUID_DOMAIN_EXTENSION_RAW) == 0) {
+ return updateGridsFromRaw(filename, grids);
+ }
+ else {
+ cerr << "Fluid Error -- updateGridsFromFile(): Invalid file extension in file: " << filename
<< endl;
+ }
return false;
}
else {
- cerr << "Fluid Error -- updateGridFromFile(): Unable to open file: " << filename << endl;
+ cerr << "Fluid Error -- updateGridsFromFile(): Unable to open file: " << filename << endl;
return false;
}
}
-bool MANTA::updateGridFromUni(string filename, float *grid, bool isNoise)
+bool MANTA::updateGridsFromUni(string filename, vector<GridItem> grids)
{
if (with_debug)
- cout << "MANTA::updateGridFromUni()" << endl;
+ cout << "MANTA::updateGridsFromUni()" << endl;
gzFile gzf;
+ int expectedBytes = 0, readBytes = 0;
int ibuffer[4];
gzf = (gzFile)BLI_gzopen(filename.c_str(), "rb1");
if (!gzf) {
- cerr << "Fluid Error -- updateGridFromUni(): Unable to open file: " << filename << endl;
+ cerr << "Fluid Error -- updateGridsFromUni(): Unable to open file: " << filename << endl;
return false;
}
- int readBytes = 0;
char file_magic[5] = {0, 0, 0, 0, 0};
readBytes = gzread(gzf, file_magic, 4);
if (!readBytes) {
- cerr << "Fluid Error -- updateGridFromUni(): Unable to read header in file: " << filename
- << endl;
- gzclose(gzf);
- return false;
- }
-
- if (!strcmp(file_magic, "DDF2")) {
- cerr << "Fluid Error -- updateGridFromUni(): Grid uni file format DDF2 not supported anymore."
- << endl;
- gzclose(gzf);
- return false;
- }
-
- if (!strcmp(file_magic, "MNT1")) {
- cerr << "Fluid Error -- updateGridFromUni(): Grid uni file format MNT1 not supported anymore."
- << endl;
+ cerr << "Fluid Error -- updateGridsFromUni(): Invalid header in file: " << filename << endl;
gzclose(gzf);
return false;
}
-
- if (!strcmp(file_magic, "MNT2")) {
- cerr << "Fluid Error -- updateGridFromUni(): Grid uni file format MNT2 not supported anymore."
+ if (!strcmp(file_magic, "DDF2") || !strcmp(file_magic, "MNT1") || !strcmp(file_magic, "MNT2")) {
+ cerr << "Fluid Error -- updateGridsFromUni(): Unsupported header in file: " << filename
<< endl;
gzclose(gzf);
return false;
}
- // grid uni header
- const int STR_LEN_GRID = 252;
- int elementType, bytesPerElement; // data type info
- char info[STR_LEN_GRID]; // mantaflow build information
- int dimT; // optionally store forth dimension for 4d grids
- unsigned long long timestamp; // creation time
+ if (!strcmp(file_magic, "MNT3")) {
- // read grid header
- gzread(gzf, &ibuffer, sizeof(int) * 4); // dimX, dimY, dimZ, gridType
- gzread(gzf, &elementType, sizeof(int));
- gzread(gzf, &bytesPerElement, sizeof(int));
- gzread(gzf, &info, sizeof(info));
- gzread(gzf, &dimT, sizeof(int));
- gzread(gzf, &timestamp, sizeof(unsigned long long));
+ // grid uni header
+ const int STR_LEN_GRID = 252;
+ int elementType, bytesPerElement; // data type info
+ char info[STR_LEN_GRID]; // mantaflow build information
+ int dimT; // optionally store forth dimension for 4d grids
+ unsigned long long timestamp; // creation time
+
+ // read grid header
+ gzread(gzf, &ibuffer, sizeof(int) * 4); // dimX, dimY, dimZ, gridType
+ gzread(gzf, &elementType, sizeof(int));
+ gzread(gzf, &bytesPerElement, sizeof(int));
+ gzread(gzf, &info, sizeof(info));
+ gzread(gzf, &dimT, sizeof(int));
+ gzread(gzf, &timestamp, sizeof(unsigned long long));
- int resX = (isNoise) ? mResXNoise : mResX;
- int resY = (isNoise) ? mResYNoise : mResY;
- int resZ = (isNoise) ? mResZNoise : mResZ;
+ if (with_debug)
+ cout << "Fluid: Read " << ibuffer[3] << " grid type in file: " << filename << endl;
+
+ for (vector<GridItem>::iterator gIter = grids.begin(); gIter != grids.end(); ++gIter) {
+ GridItem gridItem = *gIter;
+ void **pointerList = gridItem.pointer;
+ int type = gridItem.type;
+ int *res = gridItem.res;
+ assert(pointerList[0]);
+ assert(res[0] == res[0] && res[1] == res[1] && res[2] == res[2]);
+ UNUSED_VARS(res);
+
+ switch (type) {
+ case FLUID_DOMAIN_GRID_VEC3F: {
+ assert(pointerList[1] && pointerList[2]);
+ float **fpointers = (float **)pointerList;
+ expectedBytes = sizeof(float) * 3 * ibuffer[0] * ibuffer[1] * ibuffer[2];
+ readBytes = 0;
+ for (int i = 0; i < ibuffer[0] * ibuffer[1] * ibuffer[2]; ++i) {
+ for (int j = 0; j < 3; ++j) {
+ readBytes += gzread(gzf, fpointers[j], sizeof(float));
+ ++fpointers[j];
+ }
+ }
+ break;
+ }
+ case FLUID_DOMAIN_GRID_FLOAT: {
+ float **fpointers = (float **)pointerList;
+ expectedBytes = sizeof(float) * ibuffer[0] * ibuffer[1] * ibuffer[2];
+ readBytes = gzread(
+ gzf, fpointers[0], sizeof(float) * ibuffer[0] * ibuffer[1] * ibuffer[2]);
+ break;
+ }
+ default: {
+ cerr << "Fluid Error -- Unknown grid type" << endl;
+ }
+ }
- if (with_debug)
- cout << "Fluid: Read " << ibuffer[3] << " grid type in file: " << filename << endl;
+ if (!readBytes) {
+ cerr << "Fluid Error -- updateGridFromRaw(): Unable to read raw file: " << filename
+ << endl;
+ gzclose(gzf);
+ return false;
+ }
+ assert(expectedBytes == readBytes);
+ UNUSED_VARS(expectedBytes);
- // Sanity checks
- if (ibuffer[0] != resX || ibuffer[1] != resY || ibuffer[2] != resZ) {
- cout << "Fluid: Grid dim doesn't match, read: (" << ibuffer[0] << ", " << ibuffer[1] << ", "
- << ibuffer[2] << ") vs setup: (" << resX << ", " << resY << ", " << resZ << ")" << endl;
+ if (with_debug)
+ cout << "Fluid: Read successfully: " << filename << endl;
+ }
+ }
+ else {
+ cerr << "Fluid Error -- updateGridsFromUni(): Unknown header in file: " << filename << endl;
gzclose(gzf);
return false;
}
- // Actual data reading
- if (!strcmp(file_magic, "MNT3")) {
- gzread(gzf, grid, sizeof(float) * ibuffer[0] * ibuffer[1] * ibuffer[2]);
- }
-
- if (with_debug)
- cout << "Fluid: Read successfully: " << filename << endl;
-
return (gzclose(gzf) == Z_OK);
}
#if OPENVDB == 1
-bool MANTA::updateGridFromVDB(string filename, float *grid, bool isNoise)
+bool MANTA::updateGridsFromVDB(string filename, vector<GridItem> grids)
{
if (with_debug)
- cout << "MANTA::updateGridFromVDB()" << endl;
+ cout << "MANTA::updateGridsFromVDB()" << endl;
openvdb::initialize();
openvdb::io::File file(filename);
@@ -2877,66 +3024,191 @@ bool MANTA::updateGridFromVDB(string filename, float *grid, bool isNoise)
file.open();
}
catch (const openvdb::IoError &) {
- cerr << "Fluid Error -- updateGridFromVDB(): IOError, invalid OpenVDB file: " << filename
+ cerr << "Fluid Error -- updateGridsFromVDB(): IOError, invalid OpenVDB file: " << filename
<< endl;
return false;
}
+ if (grids.empty()) {
+ cerr << "Fluid Error -- updateGridsFromVDB(): No grids found in grid vector" << endl;
+ return false;
+ }
+ unordered_map<string, openvdb::FloatGrid::Accessor> floatAccessors;
+ unordered_map<string, openvdb::Vec3SGrid::Accessor> vec3fAccessors;
openvdb::GridBase::Ptr baseGrid;
- for (openvdb::io::File::NameIterator nameIter = file.beginName(); nameIter != file.endName();
- ++nameIter) {
- baseGrid = file.readGrid(nameIter.gridName());
- break;
+
+ /* Get accessors to all grids in this OpenVDB file.*/
+ for (vector<GridItem>::iterator gIter = grids.begin(); gIter != grids.end(); ++gIter) {
+ GridItem gridItem = *gIter;
+ string itemName = gridItem.name;
+ int itemType = gridItem.type;
+
+ for (openvdb::io::File::NameIterator nameIter = file.beginName(); nameIter != file.endName();
+ ++nameIter) {
+ string vdbName = nameIter.gridName();
+ bool nameMatch = !itemName.compare(vdbName);
+
+ /* Support for <= 2.83: If file has only one grid in it, use that grid. */
+ openvdb::io::File::NameIterator peekNext = nameIter;
+ bool onlyGrid = (++peekNext == file.endName());
+ if (onlyGrid) {
+ vdbName = itemName;
+ }
+
+ if (nameMatch || onlyGrid) {
+ baseGrid = file.readGrid(nameIter.gridName());
+
+ switch (itemType) {
+ case FLUID_DOMAIN_GRID_VEC3F: {
+ openvdb::Vec3SGrid::Ptr gridVDB = openvdb::gridPtrCast<openvdb::Vec3SGrid>(baseGrid);
+ openvdb::Vec3SGrid::Accessor vdbAccessor = gridVDB->getAccessor();
+ vec3fAccessors.emplace(vdbName, vdbAccessor);
+ break;
+ }
+ case FLUID_DOMAIN_GRID_FLOAT: {
+ openvdb::FloatGrid::Ptr gridVDB = openvdb::gridPtrCast<openvdb::FloatGrid>(baseGrid);
+ openvdb::FloatGrid::Accessor vdbAccessor = gridVDB->getAccessor();
+ floatAccessors.emplace(vdbName, vdbAccessor);
+ break;
+ }
+ default: {
+ cerr << "Fluid Error -- Unknown grid type" << endl;
+ }
+ }
+ }
+ else {
+ cerr << "Fluid Error -- Could not read grid from file" << endl;
+ return false;
+ }
+ }
}
file.close();
- openvdb::FloatGrid::Ptr gridVDB = openvdb::gridPtrCast<openvdb::FloatGrid>(baseGrid);
- openvdb::FloatGrid::Accessor accessor = gridVDB->getAccessor();
-
- int resX = (isNoise) ? mResXNoise : mResX;
- int resY = (isNoise) ? mResYNoise : mResY;
- int resZ = (isNoise) ? mResZNoise : mResZ;
size_t index = 0;
- for (int z = 0; z < resZ; ++z) {
- for (int y = 0; y < resY; ++y) {
- for (int x = 0; x < resX; ++x, ++index) {
+
+ /* Use res of first grid for grid loop. All grids must be same size anyways. */
+ vector<GridItem>::iterator gIter = grids.begin();
+ int *res = (*gIter).res;
+
+ for (int z = 0; z < res[2]; ++z) {
+ for (int y = 0; y < res[1]; ++y) {
+ for (int x = 0; x < res[0]; ++x, ++index) {
openvdb::Coord xyz(x, y, z);
- float v = accessor.getValue(xyz);
- grid[index] = v;
+
+ for (vector<GridItem>::iterator gIter = grids.begin(); gIter != grids.end(); ++gIter) {
+ GridItem gridItem = *gIter;
+ void **pointerList = gridItem.pointer;
+ int type = gridItem.type;
+ int *res = gridItem.res;
+ assert(pointerList[0]);
+ assert(res[0] == res[0] && res[1] == res[1] && res[2] == res[2]);
+ UNUSED_VARS(res);
+
+ switch (type) {
+ case FLUID_DOMAIN_GRID_VEC3F: {
+ unordered_map<string, openvdb::Vec3SGrid::Accessor>::iterator it;
+ it = vec3fAccessors.find(gridItem.name);
+ if (it == vec3fAccessors.end()) {
+ cerr << "Fluid Error -- '" << gridItem.name << "' not in vdb grid map" << endl;
+ return false;
+ }
+ openvdb::Vec3f v = it->second.getValue(xyz);
+
+ assert(pointerList[1] && pointerList[2]);
+ float **fpointers = (float **)pointerList;
+ for (int j = 0; j < 3; ++j) {
+ (fpointers[j])[index] = (float)v[j];
+ }
+ break;
+ }
+ case FLUID_DOMAIN_GRID_FLOAT: {
+ unordered_map<string, openvdb::FloatGrid::Accessor>::iterator it;
+ it = floatAccessors.find(gridItem.name);
+ if (it == floatAccessors.end()) {
+ cerr << "Fluid Error -- '" << gridItem.name << "' not in vdb grid map" << endl;
+ return false;
+ }
+ float v = it->second.getValue(xyz);
+ float **fpointers = (float **)pointerList;
+ (fpointers[0])[index] = v;
+ break;
+ }
+ default: {
+ cerr << "Fluid Error -- Unknown grid type" << endl;
+ }
+ }
+ }
}
}
}
+ if (with_debug)
+ cout << "Fluid: Read successfully: " << filename << endl;
+
return true;
}
#endif
-bool MANTA::updateGridFromRaw(string filename, float *grid, bool isNoise)
+bool MANTA::updateGridsFromRaw(string filename, vector<GridItem> grids)
{
if (with_debug)
- cout << "MANTA::updateGridFromRaw()" << endl;
+ cout << "MANTA::updateGridsFromRaw()" << endl;
gzFile gzf;
int expectedBytes, readBytes;
gzf = (gzFile)BLI_gzopen(filename.c_str(), "rb");
if (!gzf) {
- cout << "MANTA::updateGridFromRaw(): unable to open file" << endl;
+ cout << "MANTA::updateGridsFromRaw(): unable to open file" << endl;
return false;
}
- int resX = (isNoise) ? mResXNoise : mResX;
- int resY = (isNoise) ? mResYNoise : mResY;
- int resZ = (isNoise) ? mResZNoise : mResZ;
+ for (vector<GridItem>::iterator gIter = grids.begin(); gIter != grids.end(); ++gIter) {
+ GridItem gridItem = *gIter;
+ void **pointerList = gridItem.pointer;
+ int type = gridItem.type;
+ int *res = gridItem.res;
+ assert(pointerList[0]);
+ assert(res[0] == res[0] && res[1] == res[1] && res[2] == res[2]);
+ UNUSED_VARS(res);
+
+ switch (type) {
+ case FLUID_DOMAIN_GRID_VEC3F: {
+ assert(pointerList[1] && pointerList[2]);
+ float **fpointers = (float **)pointerList;
+ expectedBytes = sizeof(float) * 3 * res[0] * res[1] * res[2];
+ readBytes = 0;
+ for (int i = 0; i < res[0] * res[1] * res[2]; ++i) {
+ for (int j = 0; j < 3; ++j) {
+ readBytes += gzread(gzf, fpointers[j], sizeof(float));
+ ++fpointers[j];
+ }
+ }
+ break;
+ }
+ case FLUID_DOMAIN_GRID_FLOAT: {
+ float **fpointers = (float **)pointerList;
+ expectedBytes = sizeof(float) * res[0] * res[1] * res[2];
+ readBytes = gzread(gzf, fpointers[0], expectedBytes);
+ break;
+ }
+ default: {
+ cerr << "Fluid Error -- Unknown grid type" << endl;
+ }
+ }
+
+ if (!readBytes) {
+ cerr << "Fluid Error -- updateGridsFromRaw(): Unable to read raw file: " << filename << endl;
+ gzclose(gzf);
+ return false;
+ }
+ assert(expectedBytes == readBytes);
- expectedBytes = sizeof(float) * resX * resY * resZ;
- readBytes = gzread(gzf, grid, expectedBytes);
- if (!readBytes) {
- cerr << "Fluid Error -- updateGridFromRaw(): Unable to read raw file: " << filename << endl;
- gzclose(gzf);
- return false;
+ if (with_debug)
+ cout << "Fluid: Read successfully: " << filename << endl;
}
- assert(expectedBytes == readBytes);
+ if (with_debug)
+ cout << "Fluid: Read successfully: " << filename << endl;
return (gzclose(gzf) == Z_OK);
}
@@ -3084,12 +3356,12 @@ bool MANTA::hasConfig(FluidModifierData *mmd, int framenr)
{
string extension = FLUID_DOMAIN_EXTENSION_UNI;
return BLI_exists(
- getFile(mmd, FLUID_DOMAIN_DIR_CONFIG, FLUID_DOMAIN_FILE_CONFIG, extension, framenr).c_str());
+ getFile(mmd, FLUID_DOMAIN_DIR_CONFIG, FLUID_FILENAME_CONFIG, extension, framenr).c_str());
}
bool MANTA::hasData(FluidModifierData *mmd, int framenr)
{
- string filename = (mUsingSmoke) ? FLUID_DOMAIN_FILE_DENSITY : FLUID_DOMAIN_FILE_PP;
+ string filename = (mUsingSmoke) ? FLUID_FILENAME_DENSITY : FLUID_FILENAME_PP;
string extension = getCacheFileEnding(mmd->domain->cache_data_format);
return BLI_exists(getFile(mmd, FLUID_DOMAIN_DIR_DATA, filename, extension, framenr).c_str());
}
@@ -3098,7 +3370,7 @@ bool MANTA::hasNoise(FluidModifierData *mmd, int framenr)
{
string extension = getCacheFileEnding(mmd->domain->cache_noise_format);
return BLI_exists(
- getFile(mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_DOMAIN_FILE_DENSITYNOISE, extension, framenr)
+ getFile(mmd, FLUID_DOMAIN_DIR_NOISE, FLUID_FILENAME_DENSITYNOISE, extension, framenr)
.c_str());
}
@@ -3106,21 +3378,20 @@ bool MANTA::hasMesh(FluidModifierData *mmd, int framenr)
{
string extension = getCacheFileEnding(mmd->domain->cache_mesh_format);
return BLI_exists(
- getFile(mmd, FLUID_DOMAIN_DIR_MESH, FLUID_DOMAIN_FILE_MESH, extension, framenr).c_str());
+ getFile(mmd, FLUID_DOMAIN_DIR_MESH, FLUID_FILENAME_MESH, extension, framenr).c_str());
}
bool MANTA::hasParticles(FluidModifierData *mmd, int framenr)
{
string extension = getCacheFileEnding(mmd->domain->cache_particle_format);
return BLI_exists(
- getFile(mmd, FLUID_DOMAIN_DIR_PARTICLES, FLUID_DOMAIN_FILE_PPSND, extension, framenr)
- .c_str());
+ getFile(mmd, FLUID_DOMAIN_DIR_PARTICLES, FLUID_FILENAME_PPSND, extension, framenr).c_str());
}
bool MANTA::hasGuiding(FluidModifierData *mmd, int framenr, bool sourceDomain)
{
string subdirectory = (sourceDomain) ? FLUID_DOMAIN_DIR_DATA : FLUID_DOMAIN_DIR_GUIDE;
- string filename = (sourceDomain) ? FLUID_DOMAIN_FILE_VEL : FLUID_DOMAIN_FILE_GUIDEVEL;
+ string filename = (sourceDomain) ? FLUID_FILENAME_VELOCITY : FLUID_FILENAME_GUIDEVEL;
string extension = getCacheFileEnding(mmd->domain->cache_data_format);
return BLI_exists(getFile(mmd, subdirectory, filename, extension, framenr).c_str());
}
diff --git a/intern/mantaflow/intern/MANTA_main.h b/intern/mantaflow/intern/MANTA_main.h
index 9b3fd6aa141..6a8484c75d9 100644
--- a/intern/mantaflow/intern/MANTA_main.h
+++ b/intern/mantaflow/intern/MANTA_main.h
@@ -60,6 +60,19 @@ struct MANTA {
int flags;
} Triangle;
+ // Cache helper typedefs
+ typedef struct GridItem {
+ void **pointer; /* Array of pointers for this grid.*/
+ int type;
+ int *res;
+ string name;
+ } GridItem;
+
+ typedef struct FileItem {
+ string filename;
+ vector<GridItem> grids;
+ } FileItem;
+
// Manta step, handling everything
void step(struct FluidModifierData *mmd, int startFrame);
@@ -72,6 +85,7 @@ struct MANTA {
void initLiquid(FluidModifierData *mmd = NULL);
void initLiquidMesh(FluidModifierData *mmd = NULL);
void initObstacle(FluidModifierData *mmd = NULL);
+ void initCurvature(FluidModifierData *mmd = NULL);
void initGuiding(FluidModifierData *mmd = NULL);
void initFractions(FluidModifierData *mmd = NULL);
void initInVelocity(FluidModifierData *mmd = NULL);
@@ -761,6 +775,7 @@ struct MANTA {
bool mUsingOutflow;
bool mUsingNoise;
bool mUsingMesh;
+ bool mUsingDiffusion;
bool mUsingMVel;
bool mUsingLiquid;
bool mUsingSmoke;
@@ -888,12 +903,12 @@ struct MANTA {
bool updateMeshFromObj(string filename);
bool updateMeshFromUni(string filename);
bool updateParticlesFromUni(string filename, bool isSecondarySys, bool isVelData);
- bool updateGridFromUni(string filename, float *grid, bool isNoise);
- bool updateGridFromVDB(string filename, float *grid, bool isNoise);
- bool updateGridFromRaw(string filename, float *grid, bool isNoise);
+ bool updateGridsFromUni(string filename, vector<GridItem> grids);
+ bool updateGridsFromVDB(string filename, vector<GridItem> grids);
+ bool updateGridsFromRaw(string filename, vector<GridItem> grids);
bool updateMeshFromFile(string filename);
bool updateParticlesFromFile(string filename, bool isSecondarySys, bool isVelData);
- bool updateGridFromFile(string filename, float *grid, bool isNoise);
+ bool updateGridsFromFile(string filename, vector<GridItem> grids);
string getDirectory(struct FluidModifierData *mmd, string subdirectory);
string getFile(struct FluidModifierData *mmd,
string subdirectory,
diff --git a/intern/mantaflow/intern/strings/fluid_script.h b/intern/mantaflow/intern/strings/fluid_script.h
index 922e591c001..cf99717c102 100644
--- a/intern/mantaflow/intern/strings/fluid_script.h
+++ b/intern/mantaflow/intern/strings/fluid_script.h
@@ -259,7 +259,7 @@ const std::string fluid_alloc =
"\n\
mantaMsg('Fluid alloc data')\n\
flags_s$ID$ = s$ID$.create(FlagGrid)\n\
-vel_s$ID$ = s$ID$.create(MACGrid)\n\
+vel_s$ID$ = s$ID$.create(MACGrid, name='$NAME_VELOCITY$')\n\
velTmp_s$ID$ = s$ID$.create(MACGrid)\n\
x_vel_s$ID$ = s$ID$.create(RealGrid)\n\
y_vel_s$ID$ = s$ID$.create(RealGrid)\n\
diff --git a/intern/mantaflow/intern/strings/liquid_script.h b/intern/mantaflow/intern/strings/liquid_script.h
index cdacea16953..e9777eb9cda 100644
--- a/intern/mantaflow/intern/strings/liquid_script.h
+++ b/intern/mantaflow/intern/strings/liquid_script.h
@@ -80,11 +80,11 @@ mantaMsg('Liquid alloc')\n\
phiParts_s$ID$ = s$ID$.create(LevelsetGrid)\n\
phi_s$ID$ = s$ID$.create(LevelsetGrid)\n\
phiTmp_s$ID$ = s$ID$.create(LevelsetGrid)\n\
-curvature_s$ID$ = s$ID$.create(RealGrid)\n\
velOld_s$ID$ = s$ID$.create(MACGrid)\n\
velParts_s$ID$ = s$ID$.create(MACGrid)\n\
mapWeights_s$ID$ = s$ID$.create(MACGrid)\n\
fractions_s$ID$ = None # allocated dynamically\n\
+curvature_s$ID$ = None\n\
\n\
pp_s$ID$ = s$ID$.create(BasicParticleSystem)\n\
pVel_pp$ID$ = pp_s$ID$.create(PdataVec3)\n\
@@ -124,6 +124,11 @@ liquid_mesh_dict_s$ID$ = dict(lMesh=mesh_sm$ID$)\n\
if using_speedvectors_s$ID$:\n\
liquid_meshvel_dict_s$ID$ = dict(lVelMesh=mVel_mesh$ID$)\n";
+const std::string liquid_alloc_curvature =
+ "\n\
+mantaMsg('Liquid alloc curvature')\n\
+curvature_s$ID$ = s$ID$.create(RealGrid)\n";
+
const std::string liquid_alloc_particles =
"\n\
ppSnd_sp$ID$ = sp$ID$.create(BasicParticleSystem)\n\
@@ -227,7 +232,7 @@ def liquid_step_$ID$():\n\
mantaMsg('Liquid step')\n\
\n\
mantaMsg('Advecting particles')\n\
- pp_s$ID$.advectInGrid(flags=flags_s$ID$, vel=vel_s$ID$, integrationMode=IntRK4, deleteInObstacle=deleteInObstacle_s$ID$, stopInObstacle=False)\n\
+ pp_s$ID$.advectInGrid(flags=flags_s$ID$, vel=vel_s$ID$, integrationMode=IntRK4, deleteInObstacle=deleteInObstacle_s$ID$, stopInObstacle=False, skipNew=True)\n\
\n\
mantaMsg('Pushing particles out of obstacles')\n\
pushOutofObs(parts=pp_s$ID$, flags=flags_s$ID$, phiObs=phiObs_s$ID$)\n\
@@ -284,12 +289,13 @@ def liquid_step_$ID$():\n\
alphaV = viscosity_s$ID$ * s$ID$.timestep * float(res_s$ID$*res_s$ID$)\n\
setWallBcs(flags=flags_s$ID$, vel=vel_s$ID$, obvel=None if using_fractions_s$ID$ else obvel_s$ID$, phiObs=phiObs_s$ID$, fractions=fractions_s$ID$)\n\
cgSolveDiffusion(flags_s$ID$, vel_s$ID$, alphaV)\n\
+ \n\
+ mantaMsg('Curvature')\n\
+ getLaplacian(laplacian=curvature_s$ID$, grid=phi_s$ID$)\n\
+ curvature_s$ID$.clamp(-1.0, 1.0)\n\
\n\
setWallBcs(flags=flags_s$ID$, vel=vel_s$ID$, obvel=None if using_fractions_s$ID$ else obvel_s$ID$, phiObs=phiObs_s$ID$, fractions=fractions_s$ID$)\n\
\n\
- mantaMsg('Calculating curvature')\n\
- getLaplacian(laplacian=curvature_s$ID$, grid=phi_s$ID$)\n\
- \n\
if using_guiding_s$ID$:\n\
mantaMsg('Guiding and pressure')\n\
PD_fluid_guiding(vel=vel_s$ID$, velT=velT_s$ID$, flags=flags_s$ID$, phi=phi_s$ID$, curv=curvature_s$ID$, surfTens=surfaceTension_s$ID$, fractions=fractions_s$ID$, weight=weightGuide_s$ID$, blurRadius=beta_sg$ID$, pressure=pressure_s$ID$, tau=tau_sg$ID$, sigma=sigma_sg$ID$, theta=theta_sg$ID$, zeroPressureFixing=not doOpen_s$ID$)\n\
@@ -343,7 +349,10 @@ def liquid_step_mesh_$ID$():\n\
interpolateMACGrid(target=vel_sm$ID$, source=vel_s$ID$)\n\
mVel_mesh$ID$.setSource(vel_sm$ID$, isMAC=True)\n\
\n\
- phi_sm$ID$.setBound(0.5,int(((upres_sm$ID$)*2)-2) )\n\
+ # Set 0.5 boundary at walls + account for extra wall thickness in fractions mode + account for grid scaling:\n\
+ # E.g. at upres=1 we expect 1 cell border (or 2 with fractions), at upres=2 we expect 2 cell border (or 4 with fractions), etc.\n\
+ # Use -1 since setBound() starts counting at 0 (and additional -1 for fractions to account for solid/fluid interface cells)\n\
+ phi_sm$ID$.setBound(value=0.5, boundaryWidth=(upres_sm$ID$*2)-2 if using_fractions_s$ID$ else upres_sm$ID$-1)\n\
phi_sm$ID$.createMesh(mesh_sm$ID$)\n";
const std::string liquid_step_particles =
diff --git a/intern/mantaflow/intern/strings/smoke_script.h b/intern/mantaflow/intern/strings/smoke_script.h
index ea2b1e9d848..72d5e20b58b 100644
--- a/intern/mantaflow/intern/strings/smoke_script.h
+++ b/intern/mantaflow/intern/strings/smoke_script.h
@@ -81,10 +81,10 @@ using_fire_s$ID$ = True\n";
const std::string smoke_alloc =
"\n\
mantaMsg('Smoke alloc')\n\
-shadow_s$ID$ = s$ID$.create(RealGrid)\n\
+shadow_s$ID$ = s$ID$.create(RealGrid, name='$NAME_SHADOW$')\n\
emission_s$ID$ = s$ID$.create(RealGrid)\n\
emissionIn_s$ID$ = s$ID$.create(RealGrid)\n\
-density_s$ID$ = s$ID$.create(RealGrid)\n\
+density_s$ID$ = s$ID$.create(RealGrid, name='$NAME_DENSITY$')\n\
densityIn_s$ID$ = s$ID$.create(RealGrid)\n\
heat_s$ID$ = None # allocated dynamically\n\
heatIn_s$ID$ = None\n\
@@ -108,7 +108,7 @@ const std::string smoke_alloc_noise =
"\n\
mantaMsg('Smoke alloc noise')\n\
vel_sn$ID$ = sn$ID$.create(MACGrid)\n\
-density_sn$ID$ = sn$ID$.create(RealGrid)\n\
+density_sn$ID$ = sn$ID$.create(RealGrid, name='$NAME_DENSITYNOISE$')\n\
phiIn_sn$ID$ = sn$ID$.create(LevelsetGrid)\n\
phiOut_sn$ID$ = sn$ID$.create(LevelsetGrid)\n\
phiObs_sn$ID$ = sn$ID$.create(LevelsetGrid)\n\
@@ -157,9 +157,9 @@ if 'color_g_s$ID$' in globals(): del color_g_s$ID$\n\
if 'color_b_s$ID$' in globals(): del color_b_s$ID$\n\
\n\
mantaMsg('Allocating colors')\n\
-color_r_s$ID$ = s$ID$.create(RealGrid)\n\
-color_g_s$ID$ = s$ID$.create(RealGrid)\n\
-color_b_s$ID$ = s$ID$.create(RealGrid)\n\
+color_r_s$ID$ = s$ID$.create(RealGrid, name='$NAME_COLORR$')\n\
+color_g_s$ID$ = s$ID$.create(RealGrid, name='$NAME_COLORG$')\n\
+color_b_s$ID$ = s$ID$.create(RealGrid, name='$NAME_COLORB$')\n\
color_r_in_s$ID$ = s$ID$.create(RealGrid)\n\
color_g_in_s$ID$ = s$ID$.create(RealGrid)\n\
color_b_in_s$ID$ = s$ID$.create(RealGrid)\n\
@@ -178,9 +178,9 @@ if 'color_g_sn$ID$' in globals(): del color_g_sn$ID$\n\
if 'color_b_sn$ID$' in globals(): del color_b_sn$ID$\n\
\n\
mantaMsg('Allocating colors noise')\n\
-color_r_sn$ID$ = sn$ID$.create(RealGrid)\n\
-color_g_sn$ID$ = sn$ID$.create(RealGrid)\n\
-color_b_sn$ID$ = sn$ID$.create(RealGrid)\n\
+color_r_sn$ID$ = sn$ID$.create(RealGrid, name='$NAME_COLORRNOISE$')\n\
+color_g_sn$ID$ = sn$ID$.create(RealGrid, name='$NAME_COLORGNOISE$')\n\
+color_b_sn$ID$ = sn$ID$.create(RealGrid, name='$NAME_COLORBNOISE$')\n\
\n\
# Add objects to dict to load them later on\n\
if 'smoke_noise_dict_final_s$ID$' in globals():\n\
@@ -213,7 +213,7 @@ if 'heat_s$ID$' in globals(): del heat_s$ID$\n\
if 'heatIn_s$ID$' in globals(): del heatIn_s$ID$\n\
\n\
mantaMsg('Allocating heat')\n\
-heat_s$ID$ = s$ID$.create(RealGrid)\n\
+heat_s$ID$ = s$ID$.create(RealGrid, name='$NAME_HEAT$')\n\
heatIn_s$ID$ = s$ID$.create(RealGrid)\n\
\n\
# Add objects to dict to load them later on\n\
@@ -232,9 +232,9 @@ if 'fuelIn_s$ID$' in globals(): del fuelIn_s$ID$\n\
if 'reactIn_s$ID$' in globals(): del reactIn_s$ID$\n\
\n\
mantaMsg('Allocating fire')\n\
-flame_s$ID$ = s$ID$.create(RealGrid)\n\
-fuel_s$ID$ = s$ID$.create(RealGrid)\n\
-react_s$ID$ = s$ID$.create(RealGrid)\n\
+flame_s$ID$ = s$ID$.create(RealGrid, name='$NAME_FLAME$')\n\
+fuel_s$ID$ = s$ID$.create(RealGrid, name='$NAME_FUEL$')\n\
+react_s$ID$ = s$ID$.create(RealGrid, name='$NAME_REACT$')\n\
fuelIn_s$ID$ = s$ID$.create(RealGrid)\n\
reactIn_s$ID$ = s$ID$.create(RealGrid)\n\
\n\
@@ -252,9 +252,9 @@ if 'fuel_sn$ID$' in globals(): del fuel_sn$ID$\n\
if 'react_sn$ID$' in globals(): del react_sn$ID$\n\
\n\
mantaMsg('Allocating fire noise')\n\
-flame_sn$ID$ = sn$ID$.create(RealGrid)\n\
-fuel_sn$ID$ = sn$ID$.create(RealGrid)\n\
-react_sn$ID$ = sn$ID$.create(RealGrid)\n\
+flame_sn$ID$ = sn$ID$.create(RealGrid, name='$NAME_FLAMENOISE$')\n\
+fuel_sn$ID$ = sn$ID$.create(RealGrid, name='$NAME_FUELNOISE$')\n\
+react_sn$ID$ = sn$ID$.create(RealGrid, name='$NAME_REACTNOISE$')\n\
\n\
# Add objects to dict to load them later on\n\
if 'smoke_noise_dict_final_s$ID$' in globals():\n\
diff --git a/intern/opensubdiv/CMakeLists.txt b/intern/opensubdiv/CMakeLists.txt
index e7292872e9c..13565a6ed28 100644
--- a/intern/opensubdiv/CMakeLists.txt
+++ b/intern/opensubdiv/CMakeLists.txt
@@ -31,7 +31,6 @@ set(SRC
opensubdiv_capi_type.h
opensubdiv_converter_capi.h
opensubdiv_evaluator_capi.h
- opensubdiv_gl_mesh_capi.h
opensubdiv_topology_refiner_capi.h
)
@@ -54,30 +53,20 @@ if(WITH_OPENSUBDIV)
internal/opensubdiv.cc
internal/opensubdiv_converter_factory.cc
internal/opensubdiv_converter_internal.cc
- internal/opensubdiv_converter_orient.cc
internal/opensubdiv_device_context_cuda.cc
internal/opensubdiv_device_context_opencl.cc
internal/opensubdiv_evaluator.cc
internal/opensubdiv_evaluator_internal.cc
- internal/opensubdiv_gl_mesh.cc
- internal/opensubdiv_gl_mesh_draw.cc
- internal/opensubdiv_gl_mesh_fvar.cc
- internal/opensubdiv_gl_mesh_internal.cc
internal/opensubdiv_topology_refiner.cc
internal/opensubdiv_topology_refiner_internal.cc
internal/opensubdiv_util.cc
internal/opensubdiv_converter_factory.h
internal/opensubdiv_converter_internal.h
- internal/opensubdiv_converter_orient.h
- internal/opensubdiv_converter_orient_impl.h
internal/opensubdiv_device_context_cuda.h
internal/opensubdiv_device_context_opencl.h
internal/opensubdiv_edge_map.h
internal/opensubdiv_evaluator_internal.h
- internal/opensubdiv_gl_mesh_draw.h
- internal/opensubdiv_gl_mesh_fvar.h
- internal/opensubdiv_gl_mesh_internal.h
internal/opensubdiv_internal.h
internal/opensubdiv_topology_refiner_internal.h
internal/opensubdiv_util.h
@@ -101,11 +90,7 @@ if(WITH_OPENSUBDIV)
OPENSUBDIV_DEFINE_COMPONENT(OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK)
OPENSUBDIV_DEFINE_COMPONENT(OPENSUBDIV_HAS_GLSL_COMPUTE)
- data_to_c_simple(shader/gpu_shader_opensubdiv_vertex.glsl SRC)
- data_to_c_simple(shader/gpu_shader_opensubdiv_geometry.glsl SRC)
- data_to_c_simple(shader/gpu_shader_opensubdiv_fragment.glsl SRC)
-
- add_definitions(-DGLEW_STATIC)
+ add_definitions(${GL_DEFINITIONS})
add_definitions(-DOSD_USES_GLEW)
if(WIN32)
@@ -131,7 +116,6 @@ else()
list(APPEND SRC
stub/opensubdiv_stub.cc
stub/opensubdiv_evaluator_stub.cc
- stub/opensubdiv_gl_mesh_stub.cc
stub/opensubdiv_topology_refiner_stub.cc
)
endif()
diff --git a/intern/opensubdiv/internal/opensubdiv.cc b/intern/opensubdiv/internal/opensubdiv.cc
index 74b81b13351..e9f6086851b 100644
--- a/intern/opensubdiv/internal/opensubdiv.cc
+++ b/intern/opensubdiv/internal/opensubdiv.cc
@@ -24,7 +24,6 @@
#include "opensubdiv_device_context_cuda.h"
#include "opensubdiv_device_context_opencl.h"
-#include "opensubdiv_gl_mesh_capi.h"
void openSubdiv_init(void)
{
@@ -34,7 +33,6 @@ void openSubdiv_init(void)
void openSubdiv_cleanup(void)
{
- openSubdiv_deinitGLMeshDrawingResources();
}
int openSubdiv_getAvailableEvaluators(void)
@@ -86,7 +84,7 @@ int openSubdiv_getVersionHex(void)
}
int major = 0, minor = 0, patch = 0;
vector<string> tokens;
- opensubdiv_capi::stringSplit(&tokens, version, "_", true);
+ blender::opensubdiv::stringSplit(&tokens, version, "_", true);
if (tokens.size() == 3) {
major = atoi(tokens[0].c_str());
minor = atoi(tokens[1].c_str());
diff --git a/intern/opensubdiv/internal/opensubdiv_converter_factory.cc b/intern/opensubdiv/internal/opensubdiv_converter_factory.cc
index ab93b5ce952..dba2a969062 100644
--- a/intern/opensubdiv/internal/opensubdiv_converter_factory.cc
+++ b/intern/opensubdiv/internal/opensubdiv_converter_factory.cc
@@ -28,14 +28,13 @@
#include <opensubdiv/far/topologyRefinerFactory.h>
#include "internal/opensubdiv_converter_internal.h"
-#include "internal/opensubdiv_converter_orient.h"
#include "internal/opensubdiv_internal.h"
#include "internal/opensubdiv_util.h"
#include "opensubdiv_converter_capi.h"
-using opensubdiv_capi::min;
-using opensubdiv_capi::stack;
-using opensubdiv_capi::vector;
+using blender::opensubdiv::min;
+using blender::opensubdiv::stack;
+using blender::opensubdiv::vector;
struct TopologyRefinerData {
const OpenSubdiv_Converter *converter;
@@ -246,7 +245,8 @@ inline void TopologyRefinerFactory<TopologyRefinerData>::reportInvalidTopology(
} /* namespace OPENSUBDIV_VERSION */
} /* namespace OpenSubdiv */
-namespace opensubdiv_capi {
+namespace blender {
+namespace opensubdiv {
namespace {
@@ -292,4 +292,5 @@ OpenSubdiv::Far::TopologyRefiner *createOSDTopologyRefinerFromConverter(
return TopologyRefinerFactory<TopologyRefinerData>::Create(cb_data, topology_options);
}
-} // namespace opensubdiv_capi
+} // namespace opensubdiv
+} // namespace blender
diff --git a/intern/opensubdiv/internal/opensubdiv_converter_factory.h b/intern/opensubdiv/internal/opensubdiv_converter_factory.h
index a1038474d33..3519d3059b2 100644
--- a/intern/opensubdiv/internal/opensubdiv_converter_factory.h
+++ b/intern/opensubdiv/internal/opensubdiv_converter_factory.h
@@ -27,11 +27,13 @@
struct OpenSubdiv_Converter;
-namespace opensubdiv_capi {
+namespace blender {
+namespace opensubdiv {
OpenSubdiv::Far::TopologyRefiner *createOSDTopologyRefinerFromConverter(
struct OpenSubdiv_Converter *converter);
-} // namespace opensubdiv_capi
+} // namespace opensubdiv
+} // namespace blender
#endif // OPENSUBDIV_CONVERTER_FACTORY_H_
diff --git a/intern/opensubdiv/internal/opensubdiv_converter_internal.cc b/intern/opensubdiv/internal/opensubdiv_converter_internal.cc
index 0335219d6b9..eedca88f77b 100644
--- a/intern/opensubdiv/internal/opensubdiv_converter_internal.cc
+++ b/intern/opensubdiv/internal/opensubdiv_converter_internal.cc
@@ -25,7 +25,8 @@
#include <cassert>
#include <opensubdiv/sdc/crease.h>
-namespace opensubdiv_capi {
+namespace blender {
+namespace opensubdiv {
OpenSubdiv::Sdc::SchemeType getSchemeTypeFromCAPI(OpenSubdiv_SchemeType type)
{
@@ -85,4 +86,5 @@ OpenSubdiv_FVarLinearInterpolation getCAPIFVarLinearInterpolationFromOSD(
return OSD_FVAR_LINEAR_INTERPOLATION_NONE;
}
-} // namespace opensubdiv_capi
+} // namespace opensubdiv
+} // namespace blender
diff --git a/intern/opensubdiv/internal/opensubdiv_converter_internal.h b/intern/opensubdiv/internal/opensubdiv_converter_internal.h
index 11c6bdd7f3b..7c586b0787a 100644
--- a/intern/opensubdiv/internal/opensubdiv_converter_internal.h
+++ b/intern/opensubdiv/internal/opensubdiv_converter_internal.h
@@ -30,7 +30,8 @@
struct OpenSubdiv_Converter;
-namespace opensubdiv_capi {
+namespace blender {
+namespace opensubdiv {
// Convert scheme type from C-API enum to an OpenSubdiv native enum.
OpenSubdiv::Sdc::SchemeType getSchemeTypeFromCAPI(OpenSubdiv_SchemeType type);
@@ -44,6 +45,7 @@ OpenSubdiv::Sdc::Options::FVarLinearInterpolation getFVarLinearInterpolationFrom
OpenSubdiv_FVarLinearInterpolation getCAPIFVarLinearInterpolationFromOSD(
OpenSubdiv::Sdc::Options::FVarLinearInterpolation linear_interpolation);
-} // namespace opensubdiv_capi
+} // namespace opensubdiv
+} // namespace blender
#endif // OPENSUBDIV_CONVERTER_INTERNAL_H_
diff --git a/intern/opensubdiv/internal/opensubdiv_converter_orient.cc b/intern/opensubdiv/internal/opensubdiv_converter_orient.cc
deleted file mode 100644
index e3367fc6314..00000000000
--- a/intern/opensubdiv/internal/opensubdiv_converter_orient.cc
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2018 Blender Foundation. All rights reserved.
-//
-// 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.
-//
-// Author: Sergey Sharybin
-
-#include "internal/opensubdiv_converter_orient.h"
-
-#include "internal/opensubdiv_internal.h"
-
-namespace opensubdiv_capi {
-
-void checkOrientedVertexConnectivity(const int num_vertex_edges,
- const int num_vertex_faces,
- const int *vertex_edges,
- const int *vertex_faces,
- const int *dst_vertex_edges,
- const int *dst_vertex_faces)
-{
-#ifndef NDEBUG
- for (int i = 0; i < num_vertex_faces; ++i) {
- bool found = false;
- for (int j = 0; j < num_vertex_faces; ++j) {
- if (vertex_faces[i] == dst_vertex_faces[j]) {
- found = true;
- break;
- }
- }
- if (!found) {
- assert(!"vert-faces connectivity ruined");
- }
- }
- for (int i = 0; i < num_vertex_edges; ++i) {
- bool found = false;
- for (int j = 0; j < num_vertex_edges; ++j) {
- if (vertex_edges[i] == dst_vertex_edges[j]) {
- found = true;
- break;
- }
- }
- if (!found) {
- assert(!"vert-edges connectivity ruined");
- }
- }
-#else
- (void)num_vertex_edges;
- (void)num_vertex_faces;
- (void)vertex_edges;
- (void)vertex_faces;
- (void)dst_vertex_edges;
- (void)dst_vertex_faces;
-#endif
-}
-
-} // namespace opensubdiv_capi
diff --git a/intern/opensubdiv/internal/opensubdiv_converter_orient.h b/intern/opensubdiv/internal/opensubdiv_converter_orient.h
deleted file mode 100644
index 967871845cb..00000000000
--- a/intern/opensubdiv/internal/opensubdiv_converter_orient.h
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2018 Blender Foundation. All rights reserved.
-//
-// 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.
-//
-// Author: Sergey Sharybin
-
-#ifndef OPENSUBDIV_CONVERTER_ORIENT_H_
-# define OPENSUBDIV_CONVERTER_ORIENT_H_
-
-# include <opensubdiv/far/types.h>
-
-// Set of utility functions which are needed to bring topology to an orientation
-// (or, winding, if you wish) which OpenSubdiv expects.
-
-namespace opensubdiv_capi {
-
-inline void reverseFaceVertices(int *face_vertices, const int num_vertices);
-
-// TODO(sergey): Document which value corresponds to which winding.
-inline int getLoopWinding(int vert0_of_face, int vert1_of_face);
-
-inline void reverseFaceLoops(OpenSubdiv::Far::IndexArray *face_vertices,
- OpenSubdiv::Far::IndexArray *face_edges);
-
-// Used for debugging, checks whether orientation happened correct.
-void checkOrientedVertexConnectivity(const int num_vertex_edges,
- const int num_vertex_faces,
- const int *vertex_edges,
- const int *vertex_faces,
- const int *dst_vertex_edges,
- const int *dst_vertex_faces);
-
-} // namespace opensubdiv_capi
-
-#endif // OPENSUBDIV_CONVERTER_ORIENT_H_
-
-#include "internal/opensubdiv_converter_orient_impl.h"
diff --git a/intern/opensubdiv/internal/opensubdiv_converter_orient_impl.h b/intern/opensubdiv/internal/opensubdiv_converter_orient_impl.h
deleted file mode 100644
index aa717f5d99d..00000000000
--- a/intern/opensubdiv/internal/opensubdiv_converter_orient_impl.h
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2018 Blender Foundation. All rights reserved.
-//
-// 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.
-//
-// Author: Sergey Sharybin
-
-#ifndef OPENSUBDIV_CONVERTER_ORIENT_IMPL_H_
-#define OPENSUBDIV_CONVERTER_ORIENT_IMPL_H_
-
-#include "internal/opensubdiv_converter_orient.h"
-
-#include <cmath>
-
-#include "internal/opensubdiv_util.h"
-
-namespace opensubdiv_capi {
-
-inline void reverseFaceVertices(int *face_vertices, const int num_vertices)
-{
- int last_vert = face_vertices[num_vertices - 1];
- for (int i = num_vertices - 1; i > 0; --i) {
- face_vertices[i] = face_vertices[i - 1];
- }
- face_vertices[0] = last_vert;
-}
-
-inline int getLoopWinding(int vert0_of_face, int vert1_of_face)
-{
- int delta_face = vert1_of_face - vert0_of_face;
- if (abs(delta_face) != 1) {
- if (delta_face > 0) {
- delta_face = -1;
- }
- else {
- delta_face = 1;
- }
- }
- return delta_face;
-}
-
-inline void reverseFaceLoops(OpenSubdiv::Far::IndexArray *face_vertices,
- OpenSubdiv::Far::IndexArray *face_edges)
-{
- const int num_face_vertices = face_vertices->size();
- for (int i = 0; i < num_face_vertices / 2; ++i) {
- const int j = num_face_vertices - i - 1;
- if (i != j) {
- swap((*face_vertices)[i], (*face_vertices)[j]);
- swap((*face_edges)[i], (*face_edges)[j]);
- }
- }
- reverseFaceVertices(&(*face_vertices)[0], num_face_vertices);
-}
-
-} // namespace opensubdiv_capi
-
-#endif // OPENSUBDIV_CONVERTER_ORIENT_IMPL_H_
diff --git a/intern/opensubdiv/internal/opensubdiv_edge_map.h b/intern/opensubdiv/internal/opensubdiv_edge_map.h
index e2e6d2328fe..454068b58a4 100644
--- a/intern/opensubdiv/internal/opensubdiv_edge_map.h
+++ b/intern/opensubdiv/internal/opensubdiv_edge_map.h
@@ -21,7 +21,8 @@
#include "internal/opensubdiv_util.h"
-namespace opensubdiv_capi {
+namespace blender {
+namespace opensubdiv {
// Helper class to ease dealing with edge indexing.
// Simply takes care of ensuring order of vertices is strictly defined.
@@ -144,12 +145,13 @@ template<typename T> typename EdgeTagMap<T>::value_type &EdgeTagMap<T>::operator
return edge_tags_[key];
}
-} // namespace opensubdiv_capi
+} // namespace opensubdiv
+} // namespace blender
namespace std {
-template<> struct hash<opensubdiv_capi::EdgeKey> {
- std::size_t operator()(const opensubdiv_capi::EdgeKey &key) const
+template<> struct hash<blender::opensubdiv::EdgeKey> {
+ std::size_t operator()(const blender::opensubdiv::EdgeKey &key) const
{
return key.hash();
}
diff --git a/intern/opensubdiv/internal/opensubdiv_evaluator_internal.cc b/intern/opensubdiv/internal/opensubdiv_evaluator_internal.cc
index c35909a045b..5279752ea4e 100644
--- a/intern/opensubdiv/internal/opensubdiv_evaluator_internal.cc
+++ b/intern/opensubdiv/internal/opensubdiv_evaluator_internal.cc
@@ -53,7 +53,8 @@ using OpenSubdiv::Osd::CpuPatchTable;
using OpenSubdiv::Osd::CpuVertexBuffer;
using OpenSubdiv::Osd::PatchCoord;
-namespace opensubdiv_capi {
+namespace blender {
+namespace opensubdiv {
namespace {
@@ -731,7 +732,8 @@ void CpuEvalOutputAPI::evaluatePatchesLimit(const OpenSubdiv_PatchCoord *patch_c
}
}
-} // namespace opensubdiv_capi
+} // namespace opensubdiv
+} // namespace blender
OpenSubdiv_EvaluatorInternal::OpenSubdiv_EvaluatorInternal()
: eval_output(NULL), patch_map(NULL), patch_table(NULL)
@@ -748,7 +750,7 @@ OpenSubdiv_EvaluatorInternal::~OpenSubdiv_EvaluatorInternal()
OpenSubdiv_EvaluatorInternal *openSubdiv_createEvaluatorInternal(
OpenSubdiv_TopologyRefiner *topology_refiner)
{
- using opensubdiv_capi::vector;
+ using blender::opensubdiv::vector;
TopologyRefiner *refiner = topology_refiner->internal->osd_topology_refiner;
if (refiner == NULL) {
// Happens on bad topology.
@@ -851,13 +853,13 @@ OpenSubdiv_EvaluatorInternal *openSubdiv_createEvaluatorInternal(
}
// Create OpenSubdiv's CPU side evaluator.
// TODO(sergey): Make it possible to use different evaluators.
- opensubdiv_capi::CpuEvalOutput *eval_output = new opensubdiv_capi::CpuEvalOutput(
+ blender::opensubdiv::CpuEvalOutput *eval_output = new blender::opensubdiv::CpuEvalOutput(
vertex_stencils, varying_stencils, all_face_varying_stencils, 2, patch_table);
OpenSubdiv::Far::PatchMap *patch_map = new PatchMap(*patch_table);
// Wrap everything we need into an object which we control from our side.
OpenSubdiv_EvaluatorInternal *evaluator_descr;
evaluator_descr = OBJECT_GUARDED_NEW(OpenSubdiv_EvaluatorInternal);
- evaluator_descr->eval_output = new opensubdiv_capi::CpuEvalOutputAPI(eval_output, patch_map);
+ evaluator_descr->eval_output = new blender::opensubdiv::CpuEvalOutputAPI(eval_output, patch_map);
evaluator_descr->patch_map = patch_map;
evaluator_descr->patch_table = patch_table;
// TOOD(sergey): Look into whether we've got duplicated stencils arrays.
diff --git a/intern/opensubdiv/internal/opensubdiv_evaluator_internal.h b/intern/opensubdiv/internal/opensubdiv_evaluator_internal.h
index 392633944c6..dbe4d88539f 100644
--- a/intern/opensubdiv/internal/opensubdiv_evaluator_internal.h
+++ b/intern/opensubdiv/internal/opensubdiv_evaluator_internal.h
@@ -29,7 +29,8 @@
struct OpenSubdiv_PatchCoord;
struct OpenSubdiv_TopologyRefiner;
-namespace opensubdiv_capi {
+namespace blender {
+namespace opensubdiv {
// Anonymous forward declaration of actual evaluator implementation.
class CpuEvalOutput;
@@ -132,14 +133,15 @@ class CpuEvalOutputAPI {
OpenSubdiv::Far::PatchMap *patch_map_;
};
-} // namespace opensubdiv_capi
+} // namespace opensubdiv
+} // namespace blender
struct OpenSubdiv_EvaluatorInternal {
public:
OpenSubdiv_EvaluatorInternal();
~OpenSubdiv_EvaluatorInternal();
- opensubdiv_capi::CpuEvalOutputAPI *eval_output;
+ blender::opensubdiv::CpuEvalOutputAPI *eval_output;
const OpenSubdiv::Far::PatchMap *patch_map;
const OpenSubdiv::Far::PatchTable *patch_table;
};
diff --git a/intern/opensubdiv/internal/opensubdiv_gl_mesh.cc b/intern/opensubdiv/internal/opensubdiv_gl_mesh.cc
deleted file mode 100644
index 6afd763a63e..00000000000
--- a/intern/opensubdiv/internal/opensubdiv_gl_mesh.cc
+++ /dev/null
@@ -1,260 +0,0 @@
-// Copyright 2013 Blender Foundation. All rights reserved.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software Foundation,
-// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-
-#include "opensubdiv_gl_mesh_capi.h"
-
-#ifdef _MSC_VER
-# include <iso646.h>
-#endif
-
-#include <opensubdiv/far/stencilTable.h>
-#include <opensubdiv/osd/glMesh.h>
-#include <opensubdiv/osd/glPatchTable.h>
-
-using OpenSubdiv::Far::StencilTable;
-using OpenSubdiv::Osd::GLMeshInterface;
-using OpenSubdiv::Osd::GLPatchTable;
-using OpenSubdiv::Osd::Mesh;
-using OpenSubdiv::Osd::MeshBitset;
-
-// CPU backend.
-#include <opensubdiv/osd/cpuEvaluator.h>
-#include <opensubdiv/osd/cpuGLVertexBuffer.h>
-using OpenSubdiv::Osd::CpuEvaluator;
-using OpenSubdiv::Osd::CpuGLVertexBuffer;
-typedef Mesh<CpuGLVertexBuffer, StencilTable, CpuEvaluator, GLPatchTable> OsdCpuMesh;
-// OpenMP backend.
-#ifdef OPENSUBDIV_HAS_OPENMP
-# include <opensubdiv/osd/ompEvaluator.h>
-using OpenSubdiv::Osd::OmpEvaluator;
-typedef Mesh<CpuGLVertexBuffer, StencilTable, OmpEvaluator, GLPatchTable> OsdOmpMesh;
-#endif
-// OpenCL backend.
-#ifdef OPENSUBDIV_HAS_OPENCL
-# include "opensubdiv_device_context_opencl.h"
-# include <opensubdiv/osd/clEvaluator.h>
-# include <opensubdiv/osd/clGLVertexBuffer.h>
-using OpenSubdiv::Osd::CLEvaluator;
-using OpenSubdiv::Osd::CLGLVertexBuffer;
-using OpenSubdiv::Osd::CLStencilTable;
-/* TODO(sergey): Use CLDeviceContext similar to OSD examples? */
-typedef Mesh<CLGLVertexBuffer, CLStencilTable, CLEvaluator, GLPatchTable, CLDeviceContext>
- OsdCLMesh;
-static CLDeviceContext g_cl_device_context;
-#endif
-// CUDA backend.
-#ifdef OPENSUBDIV_HAS_CUDA
-# include "opensubdiv_device_context_cuda.h"
-# include <opensubdiv/osd/cudaEvaluator.h>
-# include <opensubdiv/osd/cudaGLVertexBuffer.h>
-using OpenSubdiv::Osd::CudaEvaluator;
-using OpenSubdiv::Osd::CudaGLVertexBuffer;
-using OpenSubdiv::Osd::CudaStencilTable;
-typedef Mesh<CudaGLVertexBuffer, CudaStencilTable, CudaEvaluator, GLPatchTable> OsdCudaMesh;
-static CudaDeviceContext g_cuda_device_context;
-#endif
-// Transform feedback backend.
-#ifdef OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK
-# include <opensubdiv/osd/glVertexBuffer.h>
-# include <opensubdiv/osd/glXFBEvaluator.h>
-using OpenSubdiv::Osd::GLStencilTableTBO;
-using OpenSubdiv::Osd::GLVertexBuffer;
-using OpenSubdiv::Osd::GLXFBEvaluator;
-typedef Mesh<GLVertexBuffer, GLStencilTableTBO, GLXFBEvaluator, GLPatchTable>
- OsdGLSLTransformFeedbackMesh;
-#endif
-// GLSL compute backend.
-#ifdef OPENSUBDIV_HAS_GLSL_COMPUTE
-# include <opensubdiv/osd/glComputeEvaluator.h>
-# include <opensubdiv/osd/glVertexBuffer.h>
-using OpenSubdiv::Osd::GLComputeEvaluator;
-using OpenSubdiv::Osd::GLStencilTableSSBO;
-using OpenSubdiv::Osd::GLVertexBuffer;
-typedef Mesh<GLVertexBuffer, GLStencilTableSSBO, GLComputeEvaluator, GLPatchTable>
- OsdGLSLComputeMesh;
-#endif
-
-#include "MEM_guardedalloc.h"
-
-#include "internal/opensubdiv_gl_mesh_draw.h"
-#include "internal/opensubdiv_gl_mesh_fvar.h"
-#include "internal/opensubdiv_gl_mesh_internal.h"
-#include "internal/opensubdiv_topology_refiner_internal.h"
-#include "internal/opensubdiv_util.h"
-#include "opensubdiv_topology_refiner_capi.h"
-
-using opensubdiv_capi::vector;
-
-namespace {
-
-GLMeshInterface *createGLMeshInterface(OpenSubdiv::Far::TopologyRefiner *topology_refiner,
- const MeshBitset &bits,
- const int num_vertex_elements,
- const int num_varying_elements,
- const int level,
- eOpenSubdivEvaluator evaluator_type)
-{
- GLMeshInterface *mesh = NULL;
- switch (evaluator_type) {
-#define CHECK_EVALUATOR_TYPE(type, class) \
- case OPENSUBDIV_EVALUATOR_##type: \
- mesh = new class(topology_refiner, num_vertex_elements, num_varying_elements, level, bits); \
- break;
-
-#define CHECK_EVALUATOR_TYPE_STUB(type) \
- case OPENSUBDIV_EVALUATOR_##type: \
- mesh = NULL; \
- break;
-
- CHECK_EVALUATOR_TYPE(CPU, OsdCpuMesh)
-#ifdef OPENSUBDIV_HAS_OPENMP
- CHECK_EVALUATOR_TYPE(OPENMP, OsdOmpMesh)
-#else
- CHECK_EVALUATOR_TYPE_STUB(OPENMP)
-#endif
-#ifdef OPENSUBDIV_HAS_OPENCL
- CHECK_EVALUATOR_TYPE(OPENCL, OsdCLMesh)
-#else
- CHECK_EVALUATOR_TYPE_STUB(OPENCL)
-#endif
-#ifdef OPENSUBDIV_HAS_CUDA
- CHECK_EVALUATOR_TYPE(CUDA, OsdCudaMesh)
-#else
- CHECK_EVALUATOR_TYPE_STUB(CUDA)
-#endif
-#ifdef OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK
- CHECK_EVALUATOR_TYPE(GLSL_TRANSFORM_FEEDBACK, OsdGLSLTransformFeedbackMesh)
-#else
- CHECK_EVALUATOR_TYPE_STUB(GLSL_TRANSFORM_FEEDBACK)
-#endif
-#ifdef OPENSUBDIV_HAS_GLSL_COMPUTE
- CHECK_EVALUATOR_TYPE(GLSL_COMPUTE, OsdGLSLComputeMesh)
-#else
- CHECK_EVALUATOR_TYPE_STUB(GLSL_COMPUTE)
-#endif
-
-#undef CHECK_EVALUATOR_TYPE
-#undef CHECK_EVALUATOR_TYPE_STUB
- }
- return mesh;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// GLMesh structure "methods".
-
-opensubdiv_capi::GLMeshFVarData *createFVarData(OpenSubdiv::Far::TopologyRefiner *topology_refiner,
- GLMeshInterface *mesh,
- const float *fvar_src_buffer)
-{
- using opensubdiv_capi::GLMeshFVarData;
- GLMeshFVarData *fvar_data = new GLMeshFVarData();
- fvar_data->create(topology_refiner, mesh->GetFarPatchTable(), 2, fvar_src_buffer);
- return fvar_data;
-}
-
-unsigned int getPatchIndexBuffer(OpenSubdiv_GLMesh *gl_mesh)
-{
- return gl_mesh->internal->mesh_interface->GetPatchTable()->GetPatchIndexBuffer();
-}
-
-void bindVertexBuffer(OpenSubdiv_GLMesh *gl_mesh)
-{
- gl_mesh->internal->mesh_interface->BindVertexBuffer();
-}
-
-void setCoarsePositions(OpenSubdiv_GLMesh *gl_mesh,
- const float *positions,
- const int start_vertex,
- const int num_vertices)
-{
- gl_mesh->internal->mesh_interface->UpdateVertexBuffer(positions, start_vertex, num_vertices);
-}
-
-void refine(OpenSubdiv_GLMesh *gl_mesh)
-{
- gl_mesh->internal->mesh_interface->Refine();
-}
-
-void synchronize(struct OpenSubdiv_GLMesh *gl_mesh)
-{
- gl_mesh->internal->mesh_interface->Synchronize();
-}
-
-void assignFunctionPointers(OpenSubdiv_GLMesh *gl_mesh)
-{
- gl_mesh->getPatchIndexBuffer = getPatchIndexBuffer;
- gl_mesh->bindVertexBuffer = bindVertexBuffer;
- gl_mesh->setCoarsePositions = setCoarsePositions;
- gl_mesh->refine = refine;
- gl_mesh->synchronize = synchronize;
-
- gl_mesh->prepareDraw = opensubdiv_capi::GLMeshDisplayPrepare;
- gl_mesh->drawPatches = opensubdiv_capi::GLMeshDisplayDrawPatches;
-}
-
-} // namespace
-
-struct OpenSubdiv_GLMesh *openSubdiv_createOsdGLMeshFromTopologyRefiner(
- OpenSubdiv_TopologyRefiner *topology_refiner, eOpenSubdivEvaluator evaluator_type)
-{
- using OpenSubdiv::Far::TopologyRefiner;
- TopologyRefiner *osd_topology_refiner = topology_refiner->internal->osd_topology_refiner;
- // TODO(sergey): Query this from refiner.
- const bool is_adaptive = false;
- MeshBitset bits;
- bits.set(OpenSubdiv::Osd::MeshAdaptive, is_adaptive);
- bits.set(OpenSubdiv::Osd::MeshUseSingleCreasePatch, 0);
- bits.set(OpenSubdiv::Osd::MeshInterleaveVarying, 1);
- bits.set(OpenSubdiv::Osd::MeshFVarData, 1);
- bits.set(OpenSubdiv::Osd::MeshEndCapBSplineBasis, 1);
- const int num_vertex_elements = 3;
- const int num_varying_elements = 3;
- GLMeshInterface *mesh = createGLMeshInterface(osd_topology_refiner,
- bits,
- num_vertex_elements,
- num_varying_elements,
- osd_topology_refiner->GetMaxLevel(),
- evaluator_type);
- if (mesh == NULL) {
- return NULL;
- }
- OpenSubdiv_GLMesh *gl_mesh = OBJECT_GUARDED_NEW(OpenSubdiv_GLMesh);
- assignFunctionPointers(gl_mesh);
- gl_mesh->internal = new OpenSubdiv_GLMeshInternal();
- gl_mesh->internal->evaluator_type = evaluator_type;
- gl_mesh->internal->mesh_interface = mesh;
- // Face-varying support.
- // TODO(sergey): This part needs to be re-done.
- if (osd_topology_refiner->GetNumFVarChannels() > 0) {
- // TODO(sergey): This is a temporary stub to get things compiled. Need
- // to store base level UVs somewhere else.
- vector<float> uvs;
- vector<float> fvar_data_buffer;
- opensubdiv_capi::interpolateFVarData(*osd_topology_refiner, uvs, &fvar_data_buffer);
- gl_mesh->internal->fvar_data = createFVarData(
- osd_topology_refiner, mesh, &fvar_data_buffer[0]);
- }
- else {
- gl_mesh->internal->fvar_data = NULL;
- }
- return gl_mesh;
-}
-
-void openSubdiv_deleteOsdGLMesh(OpenSubdiv_GLMesh *gl_mesh)
-{
- delete gl_mesh->internal;
- OBJECT_GUARDED_DELETE(gl_mesh, OpenSubdiv_GLMesh);
-}
diff --git a/intern/opensubdiv/internal/opensubdiv_gl_mesh_draw.cc b/intern/opensubdiv/internal/opensubdiv_gl_mesh_draw.cc
deleted file mode 100644
index cbccf69e02d..00000000000
--- a/intern/opensubdiv/internal/opensubdiv_gl_mesh_draw.cc
+++ /dev/null
@@ -1,577 +0,0 @@
-// Copyright 2013 Blender Foundation. All rights reserved.
-//
-// 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.
-//
-// Author: Sergey Sharybin
-
-#include "internal/opensubdiv_gl_mesh_draw.h"
-
-#ifdef _MSC_VER
-# include <iso646.h>
-#endif
-
-#include <GL/glew.h>
-#include <cmath>
-#include <cstdio>
-
-#include <opensubdiv/osd/glMesh.h>
-
-#ifdef OPENSUBDIV_HAS_CUDA
-# include <opensubdiv/osd/cudaGLVertexBuffer.h>
-#endif // OPENSUBDIV_HAS_CUDA
-
-#include <opensubdiv/osd/cpuEvaluator.h>
-#include <opensubdiv/osd/cpuGLVertexBuffer.h>
-
-#include "internal/opensubdiv_gl_mesh_fvar.h"
-#include "internal/opensubdiv_gl_mesh_internal.h"
-#include "internal/opensubdiv_util.h"
-#include "opensubdiv_capi.h"
-#include "opensubdiv_gl_mesh_capi.h"
-
-using OpenSubdiv::Osd::GLMeshInterface;
-
-extern "C" char datatoc_gpu_shader_opensubdiv_vertex_glsl[];
-extern "C" char datatoc_gpu_shader_opensubdiv_geometry_glsl[];
-extern "C" char datatoc_gpu_shader_opensubdiv_fragment_glsl[];
-
-// TODO(sergey): Those are a bit of bad level calls :S
-extern "C" {
-void copy_m3_m3(float m1[3][3], float m2[3][3]);
-void copy_m3_m4(float m1[3][3], float m2[4][4]);
-void adjoint_m3_m3(float m1[3][3], float m[3][3]);
-float determinant_m3_array(float m[3][3]);
-bool invert_m3_m3(float m1[3][3], float m2[3][3]);
-bool invert_m3(float m[3][3]);
-void transpose_m3(float mat[3][3]);
-}
-
-#define MAX_LIGHTS 8
-#define SUPPORT_COLOR_MATERIAL
-
-typedef struct Light {
- float position[4];
- float ambient[4];
- float diffuse[4];
- float specular[4];
- float spot_direction[4];
-#ifdef SUPPORT_COLOR_MATERIAL
- float constant_attenuation;
- float linear_attenuation;
- float quadratic_attenuation;
- float spot_cutoff;
- float spot_exponent;
- float spot_cos_cutoff;
- float pad, pad2;
-#endif
-} Light;
-
-typedef struct Lighting {
- Light lights[MAX_LIGHTS];
- int num_enabled;
-} Lighting;
-
-typedef struct Transform {
- float projection_matrix[16];
- float model_view_matrix[16];
- float normal_matrix[9];
-} Transform;
-
-static bool g_use_osd_glsl = false;
-static int g_active_uv_index = 0;
-
-static GLuint g_flat_fill_solid_program = 0;
-static GLuint g_flat_fill_texture2d_program = 0;
-static GLuint g_smooth_fill_solid_program = 0;
-static GLuint g_smooth_fill_texture2d_program = 0;
-
-static GLuint g_flat_fill_solid_shadeless_program = 0;
-static GLuint g_flat_fill_texture2d_shadeless_program = 0;
-static GLuint g_smooth_fill_solid_shadeless_program = 0;
-static GLuint g_smooth_fill_texture2d_shadeless_program = 0;
-
-static GLuint g_wireframe_program = 0;
-
-static GLuint g_lighting_ub = 0;
-static Lighting g_lighting_data;
-static Transform g_transform;
-
-namespace {
-
-GLuint compileShader(GLenum shaderType,
- const char *version,
- const char *define,
- const char *source)
-{
- const char *sources[] = {
- version,
- define,
-#ifdef SUPPORT_COLOR_MATERIAL
- "#define SUPPORT_COLOR_MATERIAL\n",
-#else
- "",
-#endif
- source,
- };
-
- GLuint shader = glCreateShader(shaderType);
- glShaderSource(shader, 4, sources, NULL);
- glCompileShader(shader);
-
- GLint status;
- glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
- if (status == GL_FALSE) {
- GLchar emsg[1024];
- glGetShaderInfoLog(shader, sizeof(emsg), 0, emsg);
- fprintf(stderr, "Error compiling GLSL: %s\n", emsg);
- fprintf(stderr, "Version: %s\n", version);
- fprintf(stderr, "Defines: %s\n", define);
- fprintf(stderr, "Source: %s\n", source);
- return 0;
- }
-
- return shader;
-}
-
-GLuint linkProgram(const char *version, const char *define)
-{
- GLuint vertexShader = compileShader(
- GL_VERTEX_SHADER, version, define, datatoc_gpu_shader_opensubdiv_vertex_glsl);
- if (vertexShader == 0) {
- return 0;
- }
- GLuint geometryShader = compileShader(
- GL_GEOMETRY_SHADER, version, define, datatoc_gpu_shader_opensubdiv_geometry_glsl);
- if (geometryShader == 0) {
- return 0;
- }
- GLuint fragmentShader = compileShader(
- GL_FRAGMENT_SHADER, version, define, datatoc_gpu_shader_opensubdiv_fragment_glsl);
- if (fragmentShader == 0) {
- return 0;
- }
-
- GLuint program = glCreateProgram();
-
- glAttachShader(program, vertexShader);
- glAttachShader(program, geometryShader);
- glAttachShader(program, fragmentShader);
-
- glBindAttribLocation(program, 0, "position");
- glBindAttribLocation(program, 1, "normal");
-
- glLinkProgram(program);
-
- glDeleteShader(vertexShader);
- glDeleteShader(geometryShader);
- glDeleteShader(fragmentShader);
-
- GLint status;
- glGetProgramiv(program, GL_LINK_STATUS, &status);
- if (status == GL_FALSE) {
- GLchar emsg[1024];
- glGetProgramInfoLog(program, sizeof(emsg), 0, emsg);
- fprintf(stderr, "Error linking GLSL program : %s\n", emsg);
- fprintf(stderr, "Defines: %s\n", define);
- glDeleteProgram(program);
- return 0;
- }
-
- glUniformBlockBinding(program, glGetUniformBlockIndex(program, "Lighting"), 0);
-
- if (GLEW_VERSION_4_1) {
- glProgramUniform1i(program, glGetUniformLocation(program, "texture_buffer"), 0);
- glProgramUniform1i(program, glGetUniformLocation(program, "FVarDataOffsetBuffer"), 30);
- glProgramUniform1i(program, glGetUniformLocation(program, "FVarDataBuffer"), 31);
- }
- else {
- glUseProgram(program);
- glUniform1i(glGetUniformLocation(program, "texture_buffer"), 0);
- glUniform1i(glGetUniformLocation(program, "FVarDataOffsetBuffer"), 30);
- glUniform1i(glGetUniformLocation(program, "FVarDataBuffer"), 31);
- glUseProgram(0);
- }
-
- return program;
-}
-
-void bindProgram(OpenSubdiv_GLMesh *gl_mesh, int program)
-{
- glUseProgram(program);
- // Matrices
- glUniformMatrix4fv(
- glGetUniformLocation(program, "modelViewMatrix"), 1, false, g_transform.model_view_matrix);
- glUniformMatrix4fv(
- glGetUniformLocation(program, "projectionMatrix"), 1, false, g_transform.projection_matrix);
- glUniformMatrix3fv(
- glGetUniformLocation(program, "normalMatrix"), 1, false, g_transform.normal_matrix);
- // Lighting.
- glBindBuffer(GL_UNIFORM_BUFFER, g_lighting_ub);
- glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(g_lighting_data), &g_lighting_data);
- glBindBuffer(GL_UNIFORM_BUFFER, 0);
- glBindBufferBase(GL_UNIFORM_BUFFER, 0, g_lighting_ub);
- // Color.
- {
- // TODO(sergey): Stop using glGetMaterial.
- float color[4];
- glGetMaterialfv(GL_FRONT, GL_DIFFUSE, color);
- glUniform4fv(glGetUniformLocation(program, "diffuse"), 1, color);
- glGetMaterialfv(GL_FRONT, GL_SPECULAR, color);
- glUniform4fv(glGetUniformLocation(program, "specular"), 1, color);
- glGetMaterialfv(GL_FRONT, GL_SHININESS, color);
- glUniform1f(glGetUniformLocation(program, "shininess"), color[0]);
- }
- // Face-vertex data.
- opensubdiv_capi::GLMeshFVarData *fvar_data = gl_mesh->internal->fvar_data;
- if (fvar_data != NULL) {
- if (fvar_data->texture_buffer) {
- glActiveTexture(GL_TEXTURE31);
- glBindTexture(GL_TEXTURE_BUFFER, fvar_data->texture_buffer);
- glActiveTexture(GL_TEXTURE0);
- }
- if (fvar_data->offset_buffer) {
- glActiveTexture(GL_TEXTURE30);
- glBindTexture(GL_TEXTURE_BUFFER, fvar_data->offset_buffer);
- glActiveTexture(GL_TEXTURE0);
- }
- glUniform1i(glGetUniformLocation(program, "osd_fvar_count"), fvar_data->fvar_width);
- if (fvar_data->channel_offsets.size() > 0 && g_active_uv_index >= 0) {
- glUniform1i(glGetUniformLocation(program, "osd_active_uv_offset"),
- fvar_data->channel_offsets[g_active_uv_index]);
- }
- else {
- glUniform1i(glGetUniformLocation(program, "osd_active_uv_offset"), 0);
- }
- }
- else {
- glUniform1i(glGetUniformLocation(program, "osd_fvar_count"), 0);
- glUniform1i(glGetUniformLocation(program, "osd_active_uv_offset"), 0);
- }
-}
-
-} // namespace
-
-bool openSubdiv_initGLMeshDrawingResources(void)
-{
- static bool need_init = true;
- static bool init_success = false;
- if (!need_init) {
- return init_success;
- }
- // TODO(sergey): Update OSD drawing to OpenGL 3.3 core,
- // then remove following line.
- return false;
- const char *version = "";
- if (GLEW_VERSION_3_2) {
- version = "#version 150 compatibility\n";
- }
- else if (GLEW_VERSION_3_1) {
- version =
- "#version 140\n"
- "#extension GL_ARB_compatibility: enable\n";
- }
- else {
- version = "#version 130\n";
- // Minimum supported for OpenSubdiv.
- }
- g_flat_fill_solid_program = linkProgram(version,
- "#define USE_COLOR_MATERIAL\n"
- "#define USE_LIGHTING\n"
- "#define FLAT_SHADING\n");
- g_flat_fill_texture2d_program = linkProgram(version,
- "#define USE_COLOR_MATERIAL\n"
- "#define USE_LIGHTING\n"
- "#define USE_TEXTURE_2D\n"
- "#define FLAT_SHADING\n");
- g_smooth_fill_solid_program = linkProgram(version,
- "#define USE_COLOR_MATERIAL\n"
- "#define USE_LIGHTING\n"
- "#define SMOOTH_SHADING\n");
- g_smooth_fill_texture2d_program = linkProgram(version,
- "#define USE_COLOR_MATERIAL\n"
- "#define USE_LIGHTING\n"
- "#define USE_TEXTURE_2D\n"
- "#define SMOOTH_SHADING\n");
-
- g_flat_fill_solid_shadeless_program = linkProgram(version,
- "#define USE_COLOR_MATERIAL\n"
- "#define FLAT_SHADING\n");
- g_flat_fill_texture2d_shadeless_program = linkProgram(version,
- "#define USE_COLOR_MATERIAL\n"
- "#define USE_TEXTURE_2D\n"
- "#define FLAT_SHADING\n");
- g_smooth_fill_solid_shadeless_program = linkProgram(version,
- "#define USE_COLOR_MATERIAL\n"
- "#define SMOOTH_SHADING\n");
- g_smooth_fill_texture2d_shadeless_program = linkProgram(version,
- "#define USE_COLOR_MATERIAL\n"
- "#define USE_TEXTURE_2D\n"
- "#define SMOOTH_SHADING\n");
- g_wireframe_program = linkProgram(version, "#define WIREFRAME\n");
-
- glGenBuffers(1, &g_lighting_ub);
- glBindBuffer(GL_UNIFORM_BUFFER, g_lighting_ub);
- glBufferData(GL_UNIFORM_BUFFER, sizeof(g_lighting_data), NULL, GL_STATIC_DRAW);
- need_init = false;
- init_success = g_flat_fill_solid_program != 0 && g_flat_fill_texture2d_program != 0 &&
- g_smooth_fill_solid_program != 0 && g_smooth_fill_texture2d_program != 0 &&
- g_wireframe_program;
- return init_success;
-}
-
-void openSubdiv_deinitGLMeshDrawingResources(void)
-{
- if (g_lighting_ub != 0) {
- glDeleteBuffers(1, &g_lighting_ub);
- }
-#define SAFE_DELETE_PROGRAM(program) \
- do { \
- if (program) { \
- glDeleteProgram(program); \
- } \
- } while (false)
-
- SAFE_DELETE_PROGRAM(g_flat_fill_solid_program);
- SAFE_DELETE_PROGRAM(g_flat_fill_texture2d_program);
- SAFE_DELETE_PROGRAM(g_smooth_fill_solid_program);
- SAFE_DELETE_PROGRAM(g_smooth_fill_texture2d_program);
- SAFE_DELETE_PROGRAM(g_flat_fill_solid_shadeless_program);
- SAFE_DELETE_PROGRAM(g_flat_fill_texture2d_shadeless_program);
- SAFE_DELETE_PROGRAM(g_smooth_fill_solid_shadeless_program);
- SAFE_DELETE_PROGRAM(g_smooth_fill_texture2d_shadeless_program);
- SAFE_DELETE_PROGRAM(g_wireframe_program);
-
-#undef SAFE_DELETE_PROGRAM
-}
-
-namespace opensubdiv_capi {
-
-namespace {
-
-GLuint prepare_patchDraw(OpenSubdiv_GLMesh *gl_mesh, bool fill_quads)
-{
- GLint program = 0;
- if (!g_use_osd_glsl) {
- glGetIntegerv(GL_CURRENT_PROGRAM, &program);
- if (program) {
- GLint model;
- glGetIntegerv(GL_SHADE_MODEL, &model);
- GLint location = glGetUniformLocation(program, "osd_flat_shading");
- if (location != -1) {
- glUniform1i(location, model == GL_FLAT);
- }
- // Face-vertex data.
- opensubdiv_capi::GLMeshFVarData *fvar_data = gl_mesh->internal->fvar_data;
- if (fvar_data != NULL) {
- if (fvar_data->texture_buffer) {
- glActiveTexture(GL_TEXTURE31);
- glBindTexture(GL_TEXTURE_BUFFER, fvar_data->texture_buffer);
- glActiveTexture(GL_TEXTURE0);
- }
- if (fvar_data->offset_buffer) {
- glActiveTexture(GL_TEXTURE30);
- glBindTexture(GL_TEXTURE_BUFFER, fvar_data->offset_buffer);
- glActiveTexture(GL_TEXTURE0);
- }
- GLint location = glGetUniformLocation(program, "osd_fvar_count");
- if (location != -1) {
- glUniform1i(location, fvar_data->fvar_width);
- }
- location = glGetUniformLocation(program, "osd_active_uv_offset");
- if (location != -1) {
- if (fvar_data->channel_offsets.size() > 0 && g_active_uv_index >= 0) {
- glUniform1i(location, fvar_data->channel_offsets[g_active_uv_index]);
- }
- else {
- glUniform1i(location, 0);
- }
- }
- }
- else {
- glUniform1i(glGetUniformLocation(program, "osd_fvar_count"), 0);
- glUniform1i(glGetUniformLocation(program, "osd_active_uv_offset"), 0);
- }
- }
- return program;
- }
- if (fill_quads) {
- int model;
- GLboolean use_texture_2d;
- glGetIntegerv(GL_SHADE_MODEL, &model);
- glGetBooleanv(GL_TEXTURE_2D, &use_texture_2d);
- if (model == GL_FLAT) {
- if (use_texture_2d) {
- program = g_flat_fill_texture2d_program;
- }
- else {
- program = g_flat_fill_solid_program;
- }
- }
- else {
- if (use_texture_2d) {
- program = g_smooth_fill_texture2d_program;
- }
- else {
- program = g_smooth_fill_solid_program;
- }
- }
- }
- else {
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- program = g_wireframe_program;
- }
- bindProgram(gl_mesh, program);
- return program;
-}
-
-void perform_drawElements(GLuint program, int patch_index, int num_elements, int start_element)
-{
- if (program) {
- glUniform1i(glGetUniformLocation(program, "PrimitiveIdBase"), patch_index);
- }
- glDrawElements(GL_LINES_ADJACENCY,
- num_elements,
- GL_UNSIGNED_INT,
- reinterpret_cast<void *>(start_element * sizeof(unsigned int)));
-}
-
-void finishPatchDraw(bool fill_quads)
-{
- // TODO(sergey): Some of the stuff could be done once after the whole
- // mesh is displayed.
- /// Restore state.
- if (!fill_quads) {
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- }
- glBindVertexArray(0);
- if (g_use_osd_glsl) {
- // TODO(sergey): Store previously used program and roll back to it?
- glUseProgram(0);
- }
-}
-
-void drawPartitionPatchesRange(GLMeshInterface *mesh,
- GLuint program,
- int start_patch,
- int num_patches)
-{
- int traversed_patches = 0, num_remained_patches = num_patches;
- const OpenSubdiv::Osd::PatchArrayVector &patches = mesh->GetPatchTable()->GetPatchArrays();
- for (int i = 0; i < patches.size(); ++i) {
- const OpenSubdiv::Osd::PatchArray &patch = patches[i];
- OpenSubdiv::Far::PatchDescriptor desc = patch.GetDescriptor();
- OpenSubdiv::Far::PatchDescriptor::Type patchType = desc.GetType();
- if (patchType == OpenSubdiv::Far::PatchDescriptor::QUADS) {
- const int num_block_patches = patch.GetNumPatches();
- if (start_patch >= traversed_patches &&
- start_patch < traversed_patches + num_block_patches) {
- const int num_control_verts = desc.GetNumControlVertices();
- const int start_draw_patch = start_patch - traversed_patches;
- const int num_draw_patches = min(num_remained_patches,
- num_block_patches - start_draw_patch);
- perform_drawElements(program,
- i + start_draw_patch,
- num_draw_patches * num_control_verts,
- patch.GetIndexBase() + start_draw_patch * num_control_verts);
- num_remained_patches -= num_draw_patches;
- }
- if (num_remained_patches == 0) {
- break;
- }
- traversed_patches += num_block_patches;
- }
- }
-}
-
-static void drawAllPatches(GLMeshInterface *mesh, GLuint program)
-{
- const OpenSubdiv::Osd::PatchArrayVector &patches = mesh->GetPatchTable()->GetPatchArrays();
- for (int i = 0; i < patches.size(); ++i) {
- const OpenSubdiv::Osd::PatchArray &patch = patches[i];
- OpenSubdiv::Far::PatchDescriptor desc = patch.GetDescriptor();
- OpenSubdiv::Far::PatchDescriptor::Type patchType = desc.GetType();
-
- if (patchType == OpenSubdiv::Far::PatchDescriptor::QUADS) {
- perform_drawElements(
- program, i, patch.GetNumPatches() * desc.GetNumControlVertices(), patch.GetIndexBase());
- }
- }
-}
-
-} // namespace
-
-void GLMeshDisplayPrepare(struct OpenSubdiv_GLMesh * /*gl_mesh*/,
- const bool use_osd_glsl,
- const int active_uv_index)
-{
- g_active_uv_index = active_uv_index;
- g_use_osd_glsl = (use_osd_glsl != 0);
- // Update transformation matrices.
- glGetFloatv(GL_PROJECTION_MATRIX, g_transform.projection_matrix);
- glGetFloatv(GL_MODELVIEW_MATRIX, g_transform.model_view_matrix);
- copy_m3_m4((float(*)[3])g_transform.normal_matrix, (float(*)[4])g_transform.model_view_matrix);
- invert_m3((float(*)[3])g_transform.normal_matrix);
- transpose_m3((float(*)[3])g_transform.normal_matrix);
- // Update OpenGL lights positions, colors etc.
- g_lighting_data.num_enabled = 0;
- for (int i = 0; i < MAX_LIGHTS; ++i) {
- GLboolean enabled;
- glGetBooleanv(GL_LIGHT0 + i, &enabled);
- if (enabled) {
- g_lighting_data.num_enabled++;
- }
- // TODO(sergey): Stop using glGetLight.
- glGetLightfv(GL_LIGHT0 + i, GL_POSITION, g_lighting_data.lights[i].position);
- glGetLightfv(GL_LIGHT0 + i, GL_AMBIENT, g_lighting_data.lights[i].ambient);
- glGetLightfv(GL_LIGHT0 + i, GL_DIFFUSE, g_lighting_data.lights[i].diffuse);
- glGetLightfv(GL_LIGHT0 + i, GL_SPECULAR, g_lighting_data.lights[i].specular);
- glGetLightfv(GL_LIGHT0 + i, GL_SPOT_DIRECTION, g_lighting_data.lights[i].spot_direction);
-#ifdef SUPPORT_COLOR_MATERIAL
- glGetLightfv(
- GL_LIGHT0 + i, GL_CONSTANT_ATTENUATION, &g_lighting_data.lights[i].constant_attenuation);
- glGetLightfv(
- GL_LIGHT0 + i, GL_LINEAR_ATTENUATION, &g_lighting_data.lights[i].linear_attenuation);
- glGetLightfv(
- GL_LIGHT0 + i, GL_QUADRATIC_ATTENUATION, &g_lighting_data.lights[i].quadratic_attenuation);
- glGetLightfv(GL_LIGHT0 + i, GL_SPOT_CUTOFF, &g_lighting_data.lights[i].spot_cutoff);
- glGetLightfv(GL_LIGHT0 + i, GL_SPOT_EXPONENT, &g_lighting_data.lights[i].spot_exponent);
- g_lighting_data.lights[i].spot_cos_cutoff = cos(g_lighting_data.lights[i].spot_cutoff);
-#endif
- }
-}
-
-void GLMeshDisplayDrawPatches(OpenSubdiv_GLMesh *gl_mesh,
- const bool fill_quads,
- const int start_patch,
- const int num_patches)
-{
- GLMeshInterface *mesh = gl_mesh->internal->mesh_interface;
- // Make sure all global invariants are initialized.
- if (!openSubdiv_initGLMeshDrawingResources()) {
- return;
- }
- /// Setup GLSL/OpenGL to draw patches in current context.
- GLuint program = prepare_patchDraw(gl_mesh, fill_quads != 0);
- if (start_patch != -1) {
- drawPartitionPatchesRange(mesh, program, start_patch, num_patches);
- }
- else {
- drawAllPatches(mesh, program);
- }
- // Finish patch drawing by restoring all changes to the OpenGL context.
- finishPatchDraw(fill_quads != 0);
-}
-
-} // namespace opensubdiv_capi
diff --git a/intern/opensubdiv/internal/opensubdiv_gl_mesh_draw.h b/intern/opensubdiv/internal/opensubdiv_gl_mesh_draw.h
deleted file mode 100644
index 599ab9550e7..00000000000
--- a/intern/opensubdiv/internal/opensubdiv_gl_mesh_draw.h
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2013 Blender Foundation. All rights reserved.
-//
-// 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.
-//
-// Author: Sergey Sharybin
-
-#ifndef OPENSUBDIV_GL_MESH_DRAW_H_
-#define OPENSUBDIV_GL_MESH_DRAW_H_
-
-#include <stdint.h> // for bool
-
-struct OpenSubdiv_GLMesh;
-
-namespace opensubdiv_capi {
-
-void GLMeshDisplayPrepare(struct OpenSubdiv_GLMesh *gl_mesh,
- const bool use_osd_glsl,
- const int active_uv_index);
-
-void GLMeshDisplayDrawPatches(OpenSubdiv_GLMesh *gl_mesh,
- const bool fill_quads,
- const int start_patch,
- const int num_patches);
-
-} // namespace opensubdiv_capi
-
-#endif // OPENSUBDIV_GL_MESH_DRAW_H_
diff --git a/intern/opensubdiv/internal/opensubdiv_gl_mesh_fvar.cc b/intern/opensubdiv/internal/opensubdiv_gl_mesh_fvar.cc
deleted file mode 100644
index 6efbe93d2d8..00000000000
--- a/intern/opensubdiv/internal/opensubdiv_gl_mesh_fvar.cc
+++ /dev/null
@@ -1,171 +0,0 @@
-// Copyright 2013 Blender Foundation. All rights reserved.
-//
-// 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.
-//
-// Author: Sergey Sharybin
-
-#include "internal/opensubdiv_gl_mesh_fvar.h"
-
-#include <GL/glew.h>
-#include <opensubdiv/far/primvarRefiner.h>
-
-#include "internal/opensubdiv_util.h"
-
-namespace opensubdiv_capi {
-
-////////////////////////////////////////////////////////////////////////////////
-// GLMeshFVarData
-
-GLMeshFVarData::GLMeshFVarData() : texture_buffer(0), offset_buffer(0)
-{
-}
-
-GLMeshFVarData::~GLMeshFVarData()
-{
- release();
-}
-
-void GLMeshFVarData::release()
-{
- if (texture_buffer) {
- glDeleteTextures(1, &texture_buffer);
- }
- if (offset_buffer) {
- glDeleteTextures(1, &offset_buffer);
- }
- texture_buffer = 0;
- offset_buffer = 0;
- fvar_width = 0;
- channel_offsets.clear();
-}
-
-void GLMeshFVarData::create(const OpenSubdiv::Far::TopologyRefiner *topology_refiner,
- const OpenSubdiv::Far::PatchTable *patch_table,
- int fvar_width,
- const float *fvar_src_data)
-{
- release();
- this->fvar_width = fvar_width;
- /// Expand fvar data to per-patch array.
- const int max_level = topology_refiner->GetMaxLevel();
- const int num_channels = patch_table->GetNumFVarChannels();
- vector<float> data;
- int fvar_data_offset = 0;
- channel_offsets.resize(num_channels);
- for (int channel = 0; channel < num_channels; ++channel) {
- OpenSubdiv::Far::ConstIndexArray indices = patch_table->GetFVarValues(channel);
- channel_offsets[channel] = data.size();
- data.reserve(data.size() + indices.size() * fvar_width);
- for (int fvert = 0; fvert < indices.size(); ++fvert) {
- int index = indices[fvert] * fvar_width;
- for (int i = 0; i < fvar_width; ++i) {
- data.push_back(fvar_src_data[fvar_data_offset + index++]);
- }
- }
- if (topology_refiner->IsUniform()) {
- const int num_values_max = topology_refiner->GetLevel(max_level).GetNumFVarValues(channel);
- fvar_data_offset += num_values_max * fvar_width;
- }
- else {
- const int num_values_total = topology_refiner->GetNumFVarValuesTotal(channel);
- fvar_data_offset += num_values_total * fvar_width;
- }
- }
- GLuint buffer;
- glGenBuffers(1, &buffer);
- glBindBuffer(GL_ARRAY_BUFFER, buffer);
- glBufferData(GL_ARRAY_BUFFER, data.size() * sizeof(float), &data[0], GL_STATIC_DRAW);
- glGenTextures(1, &texture_buffer);
- glBindTexture(GL_TEXTURE_BUFFER, texture_buffer);
- glTexBuffer(GL_TEXTURE_BUFFER, GL_R32F, buffer);
- glDeleteBuffers(1, &buffer);
- glGenBuffers(1, &buffer);
- glBindBuffer(GL_ARRAY_BUFFER, buffer);
- glBufferData(
- GL_ARRAY_BUFFER, channel_offsets.size() * sizeof(int), &channel_offsets[0], GL_STATIC_DRAW);
- glGenTextures(1, &offset_buffer);
- glBindTexture(GL_TEXTURE_BUFFER, offset_buffer);
- glTexBuffer(GL_TEXTURE_BUFFER, GL_R32I, buffer);
- glBindTexture(GL_TEXTURE_BUFFER, 0);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Helper functions.
-
-struct FVarVertex {
- float u, v;
-
- void Clear()
- {
- u = v = 0.0f;
- }
-
- void AddWithWeight(FVarVertex const &src, float weight)
- {
- u += weight * src.u;
- v += weight * src.v;
- }
-};
-
-void interpolateFVarData(const OpenSubdiv::Far::TopologyRefiner &refiner,
- const vector<float> &uvs,
- vector<float> *fvar_data)
-{
- const int fvar_width = 2;
- const int max_level = refiner.GetMaxLevel();
- size_t fvar_data_offset = 0, values_offset = 0;
- for (int channel = 0; channel < refiner.GetNumFVarChannels(); ++channel) {
- const int num_values = refiner.GetLevel(0).GetNumFVarValues(channel) * 2;
- const int num_values_max = refiner.GetLevel(max_level).GetNumFVarValues(channel);
- const int num_values_total = refiner.GetNumFVarValuesTotal(channel);
- if (num_values_total <= 0) {
- continue;
- }
- OpenSubdiv::Far::PrimvarRefiner primvar_refiner(refiner);
- if (refiner.IsUniform()) {
- // For uniform we only keep the highest level of refinement.
- fvar_data->resize(fvar_data->size() + num_values_max * fvar_width);
- vector<FVarVertex> buffer(num_values_total - num_values_max);
- FVarVertex *src = &buffer[0];
- memcpy(src, &uvs[values_offset], num_values * sizeof(float));
- // Defer the last level to treat separately with its alternate
- // destination.
- for (int level = 1; level < max_level; ++level) {
- FVarVertex *dst = src + refiner.GetLevel(level - 1).GetNumFVarValues(channel);
- primvar_refiner.InterpolateFaceVarying(level, src, dst, channel);
- src = dst;
- }
- FVarVertex *dst = reinterpret_cast<FVarVertex *>(&(*fvar_data)[fvar_data_offset]);
- primvar_refiner.InterpolateFaceVarying(max_level, src, dst, channel);
- fvar_data_offset += num_values_max * fvar_width;
- }
- else {
- // For adaptive we keep all levels.
- fvar_data->resize(fvar_data->size() + num_values_total * fvar_width);
- FVarVertex *src = reinterpret_cast<FVarVertex *>(&(*fvar_data)[fvar_data_offset]);
- memcpy(src, &uvs[values_offset], num_values * sizeof(float));
- for (int level = 1; level <= max_level; ++level) {
- FVarVertex *dst = src + refiner.GetLevel(level - 1).GetNumFVarValues(channel);
- primvar_refiner.InterpolateFaceVarying(level, src, dst, channel);
- src = dst;
- }
- fvar_data_offset += num_values_total * fvar_width;
- }
- values_offset += num_values;
- }
-}
-
-} // namespace opensubdiv_capi
diff --git a/intern/opensubdiv/internal/opensubdiv_gl_mesh_fvar.h b/intern/opensubdiv/internal/opensubdiv_gl_mesh_fvar.h
deleted file mode 100644
index 73a1af05605..00000000000
--- a/intern/opensubdiv/internal/opensubdiv_gl_mesh_fvar.h
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2013 Blender Foundation. All rights reserved.
-//
-// 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.
-//
-// Author: Sergey Sharybin
-
-#ifndef OPENSUBDIV_GL_MESH_FVAR_H_
-#define OPENSUBDIV_GL_MESH_FVAR_H_
-
-// NOTE: This is a [sane(er)] port of previous ground work for getting UVs to
-// work. Still needs a lot of work to make it easy, correct and have proper
-// data ownership.
-
-#include <opensubdiv/far/patchTable.h>
-#include <opensubdiv/far/topologyRefiner.h>
-
-#include "internal/opensubdiv_util.h"
-
-namespace opensubdiv_capi {
-
-// The buffer which holds GPU resources for face-varying elements.
-class GLMeshFVarData {
- public:
- GLMeshFVarData();
- ~GLMeshFVarData();
-
- void release();
- void create(const OpenSubdiv::Far::TopologyRefiner *refiner,
- const OpenSubdiv::Far::PatchTable *patch_table,
- int fvar_width,
- const float *fvar_src_data);
-
- unsigned int texture_buffer;
- unsigned int offset_buffer;
- vector<int> channel_offsets;
- int fvar_width;
-};
-
-void interpolateFVarData(const OpenSubdiv::Far::TopologyRefiner &refiner,
- const vector<float> &uvs,
- vector<float> *fvar_data);
-
-} // namespace opensubdiv_capi
-
-#endif // OPENSUBDIV_GL_MESH_FVAR_H_
diff --git a/intern/opensubdiv/internal/opensubdiv_gl_mesh_internal.cc b/intern/opensubdiv/internal/opensubdiv_gl_mesh_internal.cc
deleted file mode 100644
index 57e56bad3fb..00000000000
--- a/intern/opensubdiv/internal/opensubdiv_gl_mesh_internal.cc
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2018 Blender Foundation. All rights reserved.
-//
-// 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.
-//
-// Author: Sergey Sharybin
-
-#include "internal/opensubdiv_gl_mesh_internal.h"
-
-#include "internal/opensubdiv_gl_mesh_fvar.h"
-
-OpenSubdiv_GLMeshInternal::OpenSubdiv_GLMeshInternal()
- : evaluator_type(OPENSUBDIV_EVALUATOR_CPU), mesh_interface(NULL), fvar_data(NULL)
-{
-}
-
-OpenSubdiv_GLMeshInternal::~OpenSubdiv_GLMeshInternal()
-{
- delete mesh_interface;
- delete fvar_data;
-}
diff --git a/intern/opensubdiv/internal/opensubdiv_gl_mesh_internal.h b/intern/opensubdiv/internal/opensubdiv_gl_mesh_internal.h
deleted file mode 100644
index cb92fb18362..00000000000
--- a/intern/opensubdiv/internal/opensubdiv_gl_mesh_internal.h
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2018 Blender Foundation. All rights reserved.
-//
-// 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.
-//
-// Author: Sergey Sharybin
-
-#ifndef OPENSUBDIV_GL_MESH_INTERNAL_H_
-#define OPENSUBDIV_GL_MESH_INTERNAL_H_
-
-#ifdef _MSC_VER
-# include <iso646.h>
-#endif
-
-#include <opensubdiv/osd/glMesh.h>
-
-#include "opensubdiv_capi_type.h"
-
-namespace opensubdiv_capi {
-class GLMeshFVarData;
-} // namespace opensubdiv_capi
-
-typedef struct OpenSubdiv_GLMeshInternal {
- OpenSubdiv_GLMeshInternal();
- ~OpenSubdiv_GLMeshInternal();
-
- eOpenSubdivEvaluator evaluator_type;
- OpenSubdiv::Osd::GLMeshInterface *mesh_interface;
- opensubdiv_capi::GLMeshFVarData *fvar_data;
-} OpenSubdiv_GLMeshInternal;
-
-#endif // OPENSUBDIV_GL_MESH_INTERNAL_H_
diff --git a/intern/opensubdiv/internal/opensubdiv_topology_refiner.cc b/intern/opensubdiv/internal/opensubdiv_topology_refiner.cc
index ac27cbdefdc..6e2dae4533a 100644
--- a/intern/opensubdiv/internal/opensubdiv_topology_refiner.cc
+++ b/intern/opensubdiv/internal/opensubdiv_topology_refiner.cc
@@ -28,7 +28,7 @@
#include "internal/opensubdiv_topology_refiner_internal.h"
#include "internal/opensubdiv_util.h"
-using opensubdiv_capi::vector;
+using blender::opensubdiv::vector;
namespace {
@@ -182,7 +182,7 @@ int getNumFVarChannels(const struct OpenSubdiv_TopologyRefiner *topology_refiner
OpenSubdiv_FVarLinearInterpolation getFVarLinearInterpolation(
const struct OpenSubdiv_TopologyRefiner *topology_refiner)
{
- return opensubdiv_capi::getCAPIFVarLinearInterpolationFromOSD(
+ return blender::opensubdiv::getCAPIFVarLinearInterpolationFromOSD(
getOSDTopologyRefiner(topology_refiner)->GetFVarLinearInterpolation());
}
@@ -243,7 +243,7 @@ OpenSubdiv_TopologyRefiner *openSubdiv_createTopologyRefinerFromConverter(
OpenSubdiv_Converter *converter, const OpenSubdiv_TopologyRefinerSettings *settings)
{
OpenSubdiv::Far::TopologyRefiner *osd_topology_refiner =
- opensubdiv_capi::createOSDTopologyRefinerFromConverter(converter);
+ blender::opensubdiv::createOSDTopologyRefinerFromConverter(converter);
if (osd_topology_refiner == NULL) {
// Happens on empty or bad topology.
return NULL;
@@ -265,7 +265,8 @@ void openSubdiv_deleteTopologyRefiner(OpenSubdiv_TopologyRefiner *topology_refin
////////////////////////////////////////////////////////////////////////////////
// Comparison with converter.
-namespace opensubdiv_capi {
+namespace blender {
+namespace opensubdiv {
namespace {
///////////////////////////////////////////////////////////
@@ -274,8 +275,8 @@ namespace {
bool checkSchemeTypeMatches(const OpenSubdiv::Far::TopologyRefiner *topology_refiner,
const OpenSubdiv_Converter *converter)
{
- const OpenSubdiv::Sdc::SchemeType converter_scheme_type = opensubdiv_capi::getSchemeTypeFromCAPI(
- converter->getSchemeType(converter));
+ const OpenSubdiv::Sdc::SchemeType converter_scheme_type =
+ blender::opensubdiv::getSchemeTypeFromCAPI(converter->getSchemeType(converter));
return (converter_scheme_type == topology_refiner->GetSchemeType());
}
@@ -286,7 +287,7 @@ bool checkOptionsMatches(const OpenSubdiv::Far::TopologyRefiner *topology_refine
const Options options = topology_refiner->GetSchemeOptions();
const Options::FVarLinearInterpolation fvar_interpolation = options.GetFVarLinearInterpolation();
const Options::FVarLinearInterpolation converter_fvar_interpolation =
- opensubdiv_capi::getFVarLinearInterpolationFromCAPI(
+ blender::opensubdiv::getFVarLinearInterpolationFromCAPI(
converter->getFVarLinearInterpolation(converter));
if (fvar_interpolation != converter_fvar_interpolation) {
return false;
@@ -660,13 +661,14 @@ bool checkTopologyAttributesMatch(const OpenSubdiv::Far::TopologyRefiner *topolo
}
} // namespace
-} // namespace opensubdiv_capi
+} // namespace opensubdiv
+} // namespace blender
bool openSubdiv_topologyRefinerCompareWithConverter(
const OpenSubdiv_TopologyRefiner *topology_refiner, const OpenSubdiv_Converter *converter)
{
const OpenSubdiv::Far::TopologyRefiner *refiner = getOSDTopologyRefiner(topology_refiner);
- return (opensubdiv_capi::checkPreliminaryMatches(refiner, converter) &&
- opensubdiv_capi::checkGeometryMatches(refiner, converter) &&
- opensubdiv_capi::checkTopologyAttributesMatch(refiner, converter));
+ return (blender::opensubdiv::checkPreliminaryMatches(refiner, converter) &&
+ blender::opensubdiv::checkGeometryMatches(refiner, converter) &&
+ blender::opensubdiv::checkTopologyAttributesMatch(refiner, converter));
}
diff --git a/intern/opensubdiv/internal/opensubdiv_util.cc b/intern/opensubdiv/internal/opensubdiv_util.cc
index 6e6f3a0920f..ea61b21e5d0 100644
--- a/intern/opensubdiv/internal/opensubdiv_util.cc
+++ b/intern/opensubdiv/internal/opensubdiv_util.cc
@@ -23,7 +23,8 @@
# include <iso646.h>
#endif
-namespace opensubdiv_capi {
+namespace blender {
+namespace opensubdiv {
void stringSplit(vector<string> *tokens,
const string &str,
@@ -56,4 +57,5 @@ void stringSplit(vector<string> *tokens,
}
}
-} // namespace opensubdiv_capi
+} // namespace opensubdiv
+} // namespace blender
diff --git a/intern/opensubdiv/internal/opensubdiv_util.h b/intern/opensubdiv/internal/opensubdiv_util.h
index e515859b42f..3fcfdd4c32b 100644
--- a/intern/opensubdiv/internal/opensubdiv_util.h
+++ b/intern/opensubdiv/internal/opensubdiv_util.h
@@ -27,7 +27,8 @@
#include <utility>
#include <vector>
-namespace opensubdiv_capi {
+namespace blender {
+namespace opensubdiv {
using std::fill;
using std::make_pair;
@@ -51,6 +52,7 @@ void stringSplit(vector<string> *tokens,
const string &separators,
bool skip_empty);
-} // namespace opensubdiv_capi
+} // namespace opensubdiv
+} // namespace blender
#endif // OPENSUBDIV_UTIL_H_
diff --git a/intern/opensubdiv/opensubdiv_gl_mesh_capi.h b/intern/opensubdiv/opensubdiv_gl_mesh_capi.h
deleted file mode 100644
index f7dd6f83434..00000000000
--- a/intern/opensubdiv/opensubdiv_gl_mesh_capi.h
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright 2013 Blender Foundation. All rights reserved.
-//
-// 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.
-//
-// Author: Sergey Sharybin
-
-#ifndef OPENSUBDIV_CAPI_GL_MESH_CAPI_H_
-#define OPENSUBDIV_CAPI_GL_MESH_CAPI_H_
-
-#include <stdint.h> // for bool
-
-#include "opensubdiv_capi_type.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct OpenSubdiv_GLMeshInternal;
-
-// Mesh which is displayable in OpenGL context.
-typedef struct OpenSubdiv_GLMesh {
- //////////////////////////////////////////////////////////////////////////////
- // Subdivision/topology part.
-
- // Returns the GL index buffer containing the patch control vertices.
- unsigned int (*getPatchIndexBuffer)(struct OpenSubdiv_GLMesh *gl_mesh);
-
- // Bind GL buffer which contains vertices (VBO).
- // TODO(sergey): Is this a coarse vertices?
- void (*bindVertexBuffer)(struct OpenSubdiv_GLMesh *gl_mesh);
-
- // Set coarse positions from a continuous array of coordinates.
- void (*setCoarsePositions)(struct OpenSubdiv_GLMesh *gl_mesh,
- const float *positions,
- const int start_vertex,
- const int num_vertices);
- // TODO(sergey): setCoarsePositionsFromBuffer().
-
- // Refine after coarse positions update.
- void (*refine)(struct OpenSubdiv_GLMesh *gl_mesh);
-
- // Synchronize after coarse positions update and refine.
- void (*synchronize)(struct OpenSubdiv_GLMesh *gl_mesh);
-
- //////////////////////////////////////////////////////////////////////////////
- // Drawing part.
-
- // Prepare mesh for display.
- void (*prepareDraw)(struct OpenSubdiv_GLMesh *gl_mesh,
- const bool use_osd_glsl,
- const int active_uv_index);
-
- // Draw given range of patches.
- //
- // If fill_quads is false, then patches are drawn in wireframe.
- void (*drawPatches)(struct OpenSubdiv_GLMesh *gl_mesh,
- const bool fill_quads,
- const int start_patch,
- const int num_patches);
-
- // Internal storage for the use in this module only.
- //
- // Tease: This contains an actual OpenSubdiv's Mesh object.
- struct OpenSubdiv_GLMeshInternal *internal;
-} OpenSubdiv_GLMesh;
-
-OpenSubdiv_GLMesh *openSubdiv_createOsdGLMeshFromTopologyRefiner(
- struct OpenSubdiv_TopologyRefiner *topology_refiner, eOpenSubdivEvaluator evaluator_type);
-
-void openSubdiv_deleteOsdGLMesh(OpenSubdiv_GLMesh *gl_mesh);
-
-// Global resources needed for GL mesh drawing.
-bool openSubdiv_initGLMeshDrawingResources(void);
-void openSubdiv_deinitGLMeshDrawingResources(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // OPENSUBDIV_CAPI_GL_MESH_CAPI_H_
diff --git a/intern/opensubdiv/shader/gpu_shader_opensubdiv_fragment.glsl b/intern/opensubdiv/shader/gpu_shader_opensubdiv_fragment.glsl
deleted file mode 100644
index 7f08182d78a..00000000000
--- a/intern/opensubdiv/shader/gpu_shader_opensubdiv_fragment.glsl
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * 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) 2014 Blender Foundation.
- * All rights reserved.
- */
-
-struct VertexData {
- vec4 position;
- vec3 normal;
- vec2 uv;
-};
-
-#define MAX_LIGHTS 8
-#define NUM_SOLID_LIGHTS 3
-
-struct LightSource {
- vec4 position;
- vec4 ambient;
- vec4 diffuse;
- vec4 specular;
- vec4 spotDirection;
-#ifdef SUPPORT_COLOR_MATERIAL
- float constantAttenuation;
- float linearAttenuation;
- float quadraticAttenuation;
- float spotCutoff;
- float spotExponent;
- float spotCosCutoff;
- float pad, pad2;
-#endif
-};
-
-layout(std140) uniform Lighting
-{
- LightSource lightSource[MAX_LIGHTS];
- int num_enabled_lights;
-};
-
-uniform vec4 diffuse;
-uniform vec4 specular;
-uniform float shininess;
-
-uniform sampler2D texture_buffer;
-
-in block
-{
- VertexData v;
-}
-inpt;
-
-void main()
-{
-#ifdef WIREFRAME
- gl_FragColor = diffuse;
-#else
- vec3 N = inpt.v.normal;
-
- if (!gl_FrontFacing)
- N = -N;
-
- /* Compute diffuse and specular lighting. */
- vec3 L_diffuse = vec3(0.0);
- vec3 L_specular = vec3(0.0);
-
-# ifdef USE_LIGHTING
-# ifndef USE_COLOR_MATERIAL
- /* Assume NUM_SOLID_LIGHTS directional lights. */
- for (int i = 0; i < NUM_SOLID_LIGHTS; i++) {
- vec4 Plight = lightSource[i].position;
-# ifdef USE_DIRECTIONAL_LIGHT
- vec3 l = (Plight.w == 0.0) ? normalize(Plight.xyz) : normalize(inpt.v.position.xyz);
-# else /* USE_DIRECTIONAL_LIGHT */
- /* TODO(sergey): We can normalize it outside of the shader. */
- vec3 l = normalize(Plight.xyz);
-# endif /* USE_DIRECTIONAL_LIGHT */
- vec3 h = normalize(l + vec3(0, 0, 1));
- float d = max(0.0, dot(N, l));
- float s = pow(max(0.0, dot(N, h)), shininess);
- L_diffuse += d * lightSource[i].diffuse.rgb;
- L_specular += s * lightSource[i].specular.rgb;
- }
-# else /* USE_COLOR_MATERIAL */
- vec3 varying_position = inpt.v.position.xyz;
- vec3 V = (gl_ProjectionMatrix[3][3] == 0.0) ? normalize(varying_position) : vec3(0.0, 0.0, -1.0);
- for (int i = 0; i < num_enabled_lights; i++) {
- /* todo: this is a slow check for disabled lights */
- if (lightSource[i].specular.a == 0.0)
- continue;
-
- float intensity = 1.0;
- vec3 light_direction;
-
- if (lightSource[i].position.w == 0.0) {
- /* directional light */
- light_direction = lightSource[i].position.xyz;
- }
- else {
- /* point light */
- vec3 d = lightSource[i].position.xyz - varying_position;
- light_direction = normalize(d);
-
- /* spot light cone */
- if (lightSource[i].spotCutoff < 90.0) {
- float cosine = max(dot(light_direction, -lightSource[i].spotDirection.xyz), 0.0);
- intensity = pow(cosine, lightSource[i].spotExponent);
- intensity *= step(lightSource[i].spotCosCutoff, cosine);
- }
-
- /* falloff */
- float distance = length(d);
-
- intensity /= lightSource[i].constantAttenuation +
- lightSource[i].linearAttenuation * distance +
- lightSource[i].quadraticAttenuation * distance * distance;
- }
-
- /* diffuse light */
- vec3 light_diffuse = lightSource[i].diffuse.rgb;
- float diffuse_bsdf = max(dot(N, light_direction), 0.0);
- L_diffuse += light_diffuse * diffuse_bsdf * intensity;
-
- /* specular light */
- vec3 light_specular = lightSource[i].specular.rgb;
- vec3 H = normalize(light_direction - V);
-
- float specular_bsdf = pow(max(dot(N, H), 0.0), gl_FrontMaterial.shininess);
- L_specular += light_specular * specular_bsdf * intensity;
- }
-# endif /* USE_COLOR_MATERIAL */
-# else /* USE_LIGHTING */
- L_diffuse = vec3(1.0);
-# endif
-
- /* Compute diffuse color. */
-# ifdef USE_TEXTURE_2D
- L_diffuse *= texture2D(texture_buffer, inpt.v.uv).rgb;
-# else
- L_diffuse *= diffuse.rgb;
-# endif
-
- /* Sum lighting. */
- vec3 L = L_diffuse;
- if (shininess != 0) {
- L += L_specular * specular.rgb;
- }
-
- /* Write out fragment color. */
- gl_FragColor = vec4(L, diffuse.a);
-#endif
-}
diff --git a/intern/opensubdiv/shader/gpu_shader_opensubdiv_geometry.glsl b/intern/opensubdiv/shader/gpu_shader_opensubdiv_geometry.glsl
deleted file mode 100644
index 37bc0720113..00000000000
--- a/intern/opensubdiv/shader/gpu_shader_opensubdiv_geometry.glsl
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * 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) 2014 Blender Foundation.
- * All rights reserved.
- */
-
-struct VertexData {
- vec4 position;
- vec3 normal;
- vec2 uv;
-};
-
-layout(lines_adjacency) in;
-#ifdef WIREFRAME
-layout(line_strip, max_vertices = 8) out;
-#else
-layout(triangle_strip, max_vertices = 4) out;
-#endif
-
-uniform mat4 modelViewMatrix;
-uniform mat4 projectionMatrix;
-uniform int PrimitiveIdBase;
-uniform int osd_fvar_count;
-uniform int osd_active_uv_offset;
-
-in block
-{
- VertexData v;
-}
-inpt[];
-
-#define INTERP_FACE_VARYING_2(result, fvarOffset, tessCoord) \
- { \
- vec2 v[4]; \
- int primOffset = (gl_PrimitiveID + PrimitiveIdBase) * 4; \
- for (int i = 0; i < 4; ++i) { \
- int index = (primOffset + i) * osd_fvar_count + fvarOffset; \
- v[i] = vec2(texelFetch(FVarDataBuffer, index).s, texelFetch(FVarDataBuffer, index + 1).s); \
- } \
- result = mix(mix(v[0], v[1], tessCoord.s), mix(v[3], v[2], tessCoord.s), tessCoord.t); \
- }
-
-uniform samplerBuffer FVarDataBuffer;
-uniform isamplerBuffer FVarDataOffsetBuffer;
-
-out block
-{
- VertexData v;
-}
-outpt;
-
-#ifdef FLAT_SHADING
-void emit(int index, vec3 normal)
-{
- outpt.v.position = inpt[index].v.position;
- outpt.v.normal = normal;
-
- /* TODO(sergey): Only uniform subdivisions atm. */
- vec2 quadst[4] = vec2[](vec2(0, 0), vec2(1, 0), vec2(1, 1), vec2(0, 1));
- vec2 st = quadst[index];
-
- INTERP_FACE_VARYING_2(outpt.v.uv, osd_active_uv_offset, st);
-
- gl_Position = projectionMatrix * inpt[index].v.position;
- EmitVertex();
-}
-
-# ifdef WIREFRAME
-void emit_edge(int v0, int v1, vec3 normal)
-{
- emit(v0, normal);
- emit(v1, normal);
-}
-# endif
-
-#else
-void emit(int index)
-{
- outpt.v.position = inpt[index].v.position;
- outpt.v.normal = inpt[index].v.normal;
-
- /* TODO(sergey): Only uniform subdivisions atm. */
- vec2 quadst[4] = vec2[](vec2(0, 0), vec2(1, 0), vec2(1, 1), vec2(0, 1));
- vec2 st = quadst[index];
-
- INTERP_FACE_VARYING_2(outpt.v.uv, osd_active_uv_offset, st);
-
- gl_Position = projectionMatrix * inpt[index].v.position;
- EmitVertex();
-}
-
-# ifdef WIREFRAME
-void emit_edge(int v0, int v1)
-{
- emit(v0);
- emit(v1);
-}
-# endif
-
-#endif
-
-void main()
-{
- gl_PrimitiveID = gl_PrimitiveIDIn;
-
-#ifdef FLAT_SHADING
- vec3 A = (inpt[0].v.position - inpt[1].v.position).xyz;
- vec3 B = (inpt[3].v.position - inpt[1].v.position).xyz;
- vec3 flat_normal = normalize(cross(B, A));
-# ifndef WIREFRAME
- emit(0, flat_normal);
- emit(1, flat_normal);
- emit(3, flat_normal);
- emit(2, flat_normal);
-# else
- emit_edge(0, 1, flat_normal);
- emit_edge(1, 2, flat_normal);
- emit_edge(2, 3, flat_normal);
- emit_edge(3, 0, flat_normal);
-# endif
-#else
-# ifndef WIREFRAME
- emit(0);
- emit(1);
- emit(3);
- emit(2);
-# else
- emit_edge(0, 1);
- emit_edge(1, 2);
- emit_edge(2, 3);
- emit_edge(3, 0);
-# endif
-#endif
-
- EndPrimitive();
-}
diff --git a/intern/opensubdiv/shader/gpu_shader_opensubdiv_vertex.glsl b/intern/opensubdiv/shader/gpu_shader_opensubdiv_vertex.glsl
deleted file mode 100644
index 474a716e927..00000000000
--- a/intern/opensubdiv/shader/gpu_shader_opensubdiv_vertex.glsl
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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) 2014 Blender Foundation.
- * All rights reserved.
- */
-
-struct VertexData {
- vec4 position;
- vec3 normal;
- vec2 uv;
-};
-
-in vec3 normal;
-in vec4 position;
-
-uniform mat4 modelViewMatrix;
-uniform mat3 normalMatrix;
-
-out block
-{
- VertexData v;
-}
-outpt;
-
-void main()
-{
- outpt.v.position = modelViewMatrix * position;
- outpt.v.normal = normalize(normalMatrix * normal);
-}
diff --git a/intern/opensubdiv/stub/opensubdiv_gl_mesh_stub.cc b/intern/opensubdiv/stub/opensubdiv_gl_mesh_stub.cc
deleted file mode 100644
index 91ac0676dbd..00000000000
--- a/intern/opensubdiv/stub/opensubdiv_gl_mesh_stub.cc
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2018 Blender Foundation. All rights reserved.
-//
-// 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.
-//
-// Author: Sergey Sharybin
-
-#include "opensubdiv_gl_mesh_capi.h"
-
-#include <cstddef>
-
-struct OpenSubdiv_GLMesh *openSubdiv_createOsdGLMeshFromTopologyRefiner(
- OpenSubdiv_TopologyRefiner * /*topology_refiner*/, eOpenSubdivEvaluator /*evaluator_type*/)
-{
- return NULL;
-}
-
-void openSubdiv_deleteOsdGLMesh(OpenSubdiv_GLMesh * /*gl_mesh*/)
-{
-}
-
-bool openSubdiv_initGLMeshDrawingResources(void)
-{
- return false;
-}
-
-void openSubdiv_deinitGLMeshDrawingResources(void)
-{
-}
diff --git a/release/datafiles/locale b/release/datafiles/locale
-Subproject 1d9b8b2ffa67a8832073acf316150b2dfaa2db0
+Subproject 0fd21a7cc382066d184fda8153f925bb825af2c
diff --git a/release/scripts/addons b/release/scripts/addons
-Subproject 47a32a5370d36942674621e5a03e57e8dd4986d
+Subproject 9a9832d5d7fe61a446516f2e2722f8356bd7e70
diff --git a/release/scripts/modules/bpy_extras/object_utils.py b/release/scripts/modules/bpy_extras/object_utils.py
index 540bc75cece..5b7f26ff89c 100644
--- a/release/scripts/modules/bpy_extras/object_utils.py
+++ b/release/scripts/modules/bpy_extras/object_utils.py
@@ -256,15 +256,15 @@ def world_to_camera_view(scene, obj, coord):
z = -co_local.z
camera = obj.data
- frame = [-v for v in camera.view_frame(scene=scene)[:3]]
+ frame = [v for v in camera.view_frame(scene=scene)[:3]]
if camera.type != 'ORTHO':
if z == 0.0:
return Vector((0.5, 0.5, 0.0))
else:
- frame = [(v / (v.z / z)) for v in frame]
+ frame = [-(v / (v.z / z)) for v in frame]
- min_x, max_x = frame[1].x, frame[2].x
- min_y, max_y = frame[0].y, frame[1].y
+ min_x, max_x = frame[2].x, frame[1].x
+ min_y, max_y = frame[1].y, frame[0].y
x = (co_local.x - min_x) / (max_x - min_x)
y = (co_local.y - min_y) / (max_y - min_y)
diff --git a/release/scripts/presets/tracking_camera/1__colon__2.3_inch.py b/release/scripts/presets/tracking_camera/1__colon__2.3_inch.py
index 218e51a53a6..9fcd40fbb65 100644
--- a/release/scripts/presets/tracking_camera/1__colon__2.3_inch.py
+++ b/release/scripts/presets/tracking_camera/1__colon__2.3_inch.py
@@ -7,4 +7,3 @@ camera.pixel_aspect = 1
camera.k1 = 0.0
camera.k2 = 0.0
camera.k3 = 0.0
-
diff --git a/release/scripts/presets/tracking_camera/1__colon__2.5_inch.py b/release/scripts/presets/tracking_camera/1__colon__2.5_inch.py
index 0f16dc9b503..2f064e59838 100644
--- a/release/scripts/presets/tracking_camera/1__colon__2.5_inch.py
+++ b/release/scripts/presets/tracking_camera/1__colon__2.5_inch.py
@@ -7,4 +7,3 @@ camera.pixel_aspect = 1
camera.k1 = 0.0
camera.k2 = 0.0
camera.k3 = 0.0
-
diff --git a/release/scripts/presets/tracking_camera/2__colon__3_inch.py b/release/scripts/presets/tracking_camera/2__colon__3_inch.py
index 079d0c6308f..8936e627d77 100644
--- a/release/scripts/presets/tracking_camera/2__colon__3_inch.py
+++ b/release/scripts/presets/tracking_camera/2__colon__3_inch.py
@@ -7,4 +7,3 @@ camera.pixel_aspect = 1
camera.k1 = 0.0
camera.k2 = 0.0
camera.k3 = 0.0
-
diff --git a/release/scripts/presets/tracking_camera/4__colon__3_inch.py b/release/scripts/presets/tracking_camera/4__colon__3_inch.py
index 0d3313ab755..2317715e1b4 100644
--- a/release/scripts/presets/tracking_camera/4__colon__3_inch.py
+++ b/release/scripts/presets/tracking_camera/4__colon__3_inch.py
@@ -7,4 +7,3 @@ camera.pixel_aspect = 1
camera.k1 = 0.0
camera.k2 = 0.0
camera.k3 = 0.0
-
diff --git a/release/scripts/presets/tracking_camera/Arri_Alexa.py b/release/scripts/presets/tracking_camera/Arri_Alexa.py
index 7144f9a03aa..ded361ec965 100644
--- a/release/scripts/presets/tracking_camera/Arri_Alexa.py
+++ b/release/scripts/presets/tracking_camera/Arri_Alexa.py
@@ -7,4 +7,3 @@ camera.pixel_aspect = 1
camera.k1 = 0.0
camera.k2 = 0.0
camera.k3 = 0.0
-
diff --git a/release/scripts/presets/tracking_camera/Canon_1100D.py b/release/scripts/presets/tracking_camera/Canon_1100D.py
index dc09e3d0896..96d6d456337 100644
--- a/release/scripts/presets/tracking_camera/Canon_1100D.py
+++ b/release/scripts/presets/tracking_camera/Canon_1100D.py
@@ -7,4 +7,3 @@ camera.pixel_aspect = 1
camera.k1 = 0.0
camera.k2 = 0.0
camera.k3 = 0.0
-
diff --git a/release/scripts/presets/tracking_camera/Canon_APS-C.py b/release/scripts/presets/tracking_camera/Canon_APS-C.py
index c55716a06a8..cc4da545272 100644
--- a/release/scripts/presets/tracking_camera/Canon_APS-C.py
+++ b/release/scripts/presets/tracking_camera/Canon_APS-C.py
@@ -7,4 +7,3 @@ camera.pixel_aspect = 1
camera.k1 = 0.0
camera.k2 = 0.0
camera.k3 = 0.0
-
diff --git a/release/scripts/presets/tracking_camera/Canon_APS-H.py b/release/scripts/presets/tracking_camera/Canon_APS-H.py
index 0b757edef20..853edd5dcba 100644
--- a/release/scripts/presets/tracking_camera/Canon_APS-H.py
+++ b/release/scripts/presets/tracking_camera/Canon_APS-H.py
@@ -7,4 +7,3 @@ camera.pixel_aspect = 1
camera.k1 = 0.0
camera.k2 = 0.0
camera.k3 = 0.0
-
diff --git a/release/scripts/presets/tracking_camera/Canon_C300.py b/release/scripts/presets/tracking_camera/Canon_C300.py
index 24fbbc78ff7..809f8f432f8 100644
--- a/release/scripts/presets/tracking_camera/Canon_C300.py
+++ b/release/scripts/presets/tracking_camera/Canon_C300.py
@@ -7,4 +7,3 @@ camera.pixel_aspect = 1
camera.k1 = 0.0
camera.k2 = 0.0
camera.k3 = 0.0
-
diff --git a/release/scripts/presets/tracking_camera/Full_Frame_35mm_Camera.py b/release/scripts/presets/tracking_camera/Full_Frame_35mm_Camera.py
index 478e53584fb..0f3da0b4d72 100644
--- a/release/scripts/presets/tracking_camera/Full_Frame_35mm_Camera.py
+++ b/release/scripts/presets/tracking_camera/Full_Frame_35mm_Camera.py
@@ -7,4 +7,3 @@ camera.pixel_aspect = 1
camera.k1 = 0.0
camera.k2 = 0.0
camera.k3 = 0.0
-
diff --git a/release/scripts/presets/tracking_camera/GoPro_Hero3_Black.py b/release/scripts/presets/tracking_camera/GoPro_Hero3_Black.py
index 47e026e9d00..29851352284 100644
--- a/release/scripts/presets/tracking_camera/GoPro_Hero3_Black.py
+++ b/release/scripts/presets/tracking_camera/GoPro_Hero3_Black.py
@@ -8,4 +8,3 @@ camera.pixel_aspect = 1
camera.k1 = 0.0
camera.k2 = 0.0
camera.k3 = 0.0
-
diff --git a/release/scripts/presets/tracking_camera/GoPro_Hero3_Silver.py b/release/scripts/presets/tracking_camera/GoPro_Hero3_Silver.py
index 10ca885769a..9e08cf283a7 100644
--- a/release/scripts/presets/tracking_camera/GoPro_Hero3_Silver.py
+++ b/release/scripts/presets/tracking_camera/GoPro_Hero3_Silver.py
@@ -8,4 +8,3 @@ camera.pixel_aspect = 1
camera.k1 = 0.0
camera.k2 = 0.0
camera.k3 = 0.0
-
diff --git a/release/scripts/presets/tracking_camera/GoPro_Hero3_White.py b/release/scripts/presets/tracking_camera/GoPro_Hero3_White.py
index c9bda2258c8..6b1f9d97e81 100644
--- a/release/scripts/presets/tracking_camera/GoPro_Hero3_White.py
+++ b/release/scripts/presets/tracking_camera/GoPro_Hero3_White.py
@@ -8,4 +8,3 @@ camera.pixel_aspect = 1
camera.k1 = 0.0
camera.k2 = 0.0
camera.k3 = 0.0
-
diff --git a/release/scripts/presets/tracking_camera/Nexus_5.py b/release/scripts/presets/tracking_camera/Nexus_5.py
index 68ec347d3e1..172c8e93bfd 100644
--- a/release/scripts/presets/tracking_camera/Nexus_5.py
+++ b/release/scripts/presets/tracking_camera/Nexus_5.py
@@ -8,4 +8,3 @@ camera.pixel_aspect = 1
camera.k1 = 0.0
camera.k2 = 0.0
camera.k3 = 0.0
-
diff --git a/release/scripts/presets/tracking_camera/Samsung_Galaxy_S3.py b/release/scripts/presets/tracking_camera/Samsung_Galaxy_S3.py
index 6dbdaefbd2f..d10994e45f5 100644
--- a/release/scripts/presets/tracking_camera/Samsung_Galaxy_S3.py
+++ b/release/scripts/presets/tracking_camera/Samsung_Galaxy_S3.py
@@ -8,4 +8,3 @@ camera.pixel_aspect = 1
camera.k1 = 0.0
camera.k2 = 0.0
camera.k3 = 0.0
-
diff --git a/release/scripts/presets/tracking_camera/Samsung_Galaxy_S4.py b/release/scripts/presets/tracking_camera/Samsung_Galaxy_S4.py
index 051cdf64402..c5fef80b3de 100644
--- a/release/scripts/presets/tracking_camera/Samsung_Galaxy_S4.py
+++ b/release/scripts/presets/tracking_camera/Samsung_Galaxy_S4.py
@@ -8,4 +8,3 @@ camera.pixel_aspect = 1
camera.k1 = 0.0
camera.k2 = 0.0
camera.k3 = 0.0
-
diff --git a/release/scripts/presets/tracking_camera/Super_16.py b/release/scripts/presets/tracking_camera/Super_16.py
index f1a8bb37328..e94da9a99ba 100644
--- a/release/scripts/presets/tracking_camera/Super_16.py
+++ b/release/scripts/presets/tracking_camera/Super_16.py
@@ -7,4 +7,3 @@ camera.pixel_aspect = 1
camera.k1 = 0.0
camera.k2 = 0.0
camera.k3 = 0.0
-
diff --git a/release/scripts/presets/tracking_camera/Super_35.py b/release/scripts/presets/tracking_camera/Super_35.py
index f533d3e4bcf..e07edc3a22c 100644
--- a/release/scripts/presets/tracking_camera/Super_35.py
+++ b/release/scripts/presets/tracking_camera/Super_35.py
@@ -7,4 +7,3 @@ camera.pixel_aspect = 1
camera.k1 = 0.0
camera.k2 = 0.0
camera.k3 = 0.0
-
diff --git a/release/scripts/presets/tracking_camera/iPhone_4.py b/release/scripts/presets/tracking_camera/iPhone_4.py
index b0ac49706b3..220e5e08147 100644
--- a/release/scripts/presets/tracking_camera/iPhone_4.py
+++ b/release/scripts/presets/tracking_camera/iPhone_4.py
@@ -8,4 +8,3 @@ camera.pixel_aspect = 1
camera.k1 = 0.0
camera.k2 = 0.0
camera.k3 = 0.0
-
diff --git a/release/scripts/presets/tracking_camera/iPhone_4S.py b/release/scripts/presets/tracking_camera/iPhone_4S.py
index 2569f9b412b..686cffc8f99 100644
--- a/release/scripts/presets/tracking_camera/iPhone_4S.py
+++ b/release/scripts/presets/tracking_camera/iPhone_4S.py
@@ -8,4 +8,3 @@ camera.pixel_aspect = 1
camera.k1 = 0.0
camera.k2 = 0.0
camera.k3 = 0.0
-
diff --git a/release/scripts/presets/tracking_camera/iPhone_5.py b/release/scripts/presets/tracking_camera/iPhone_5.py
index f7944e3fa63..d8e05da8425 100644
--- a/release/scripts/presets/tracking_camera/iPhone_5.py
+++ b/release/scripts/presets/tracking_camera/iPhone_5.py
@@ -8,4 +8,3 @@ camera.pixel_aspect = 1
camera.k1 = 0.0
camera.k2 = 0.0
camera.k3 = 0.0
-
diff --git a/release/scripts/startup/bl_ui/properties_data_bone.py b/release/scripts/startup/bl_ui/properties_data_bone.py
index aca358870c8..ff4425fbb73 100644
--- a/release/scripts/startup/bl_ui/properties_data_bone.py
+++ b/release/scripts/startup/bl_ui/properties_data_bone.py
@@ -267,7 +267,7 @@ class BONE_PT_display(BoneButtonsPanel, Panel):
if bone:
col = layout.column()
- col.prop(bone, "hide", text="Hide")
+ col.prop(bone, "hide", text="Hide", toggle=0)
class BONE_PT_display_custom_shape(BoneButtonsPanel, Panel):
diff --git a/release/scripts/startup/bl_ui/properties_physics_fluid.py b/release/scripts/startup/bl_ui/properties_physics_fluid.py
index 4b0791a63e6..2c8ed363738 100644
--- a/release/scripts/startup/bl_ui/properties_physics_fluid.py
+++ b/release/scripts/startup/bl_ui/properties_physics_fluid.py
@@ -237,7 +237,7 @@ class PHYSICS_PT_settings(PhysicButtonsPanel, Panel):
col = grid.column()
col.prop(flow, "flow_behavior", expand=False)
if flow.flow_behavior in {'INFLOW', 'OUTFLOW'}:
- col.prop(flow, "use_inflow", text="Use Flow")
+ col.prop(flow, "use_inflow")
col.prop(flow, "subframes", text="Sampling Substeps")
diff --git a/release/scripts/startup/bl_ui/properties_render.py b/release/scripts/startup/bl_ui/properties_render.py
index b1ae6290ae7..155bbb523c7 100644
--- a/release/scripts/startup/bl_ui/properties_render.py
+++ b/release/scripts/startup/bl_ui/properties_render.py
@@ -551,7 +551,6 @@ class RENDER_PT_gpencil(RenderButtonsPanel, Panel):
col.prop(props, "antialias_threshold")
-
class RENDER_PT_opengl_sampling(RenderButtonsPanel, Panel):
bl_label = "Sampling"
COMPAT_ENGINES = {'BLENDER_WORKBENCH'}
diff --git a/release/scripts/startup/bl_ui/space_image.py b/release/scripts/startup/bl_ui/space_image.py
index bc4665209aa..76b7fc7f156 100644
--- a/release/scripts/startup/bl_ui/space_image.py
+++ b/release/scripts/startup/bl_ui/space_image.py
@@ -93,9 +93,6 @@ class IMAGE_MT_view(Menu):
layout.separator()
layout.prop(sima, "use_realtime_update")
- if show_uvedit:
- layout.prop(tool_settings, "show_uv_local_view")
-
layout.prop(uv, "show_metadata")
if paint.brush and (context.image_paint_object or sima.mode == 'PAINT'):
diff --git a/release/scripts/startup/bl_ui/space_topbar.py b/release/scripts/startup/bl_ui/space_topbar.py
index 9aedd7ef0b3..6fc29119cdc 100644
--- a/release/scripts/startup/bl_ui/space_topbar.py
+++ b/release/scripts/startup/bl_ui/space_topbar.py
@@ -309,16 +309,18 @@ class TOPBAR_MT_file_new(Menu):
template_paths = bpy.utils.app_template_paths()
- # expand template paths
- app_templates = []
+ # Expand template paths.
+
+ # Use a set to avoid duplicate user/system templates.
+ # This is a corner case, but users managed to do it! T76849.
+ app_templates = set()
for path in template_paths:
for d in os.listdir(path):
if d.startswith(("__", ".")):
continue
template = os.path.join(path, d)
if os.path.isdir(template):
- # template_paths_expand.append(template)
- app_templates.append(d)
+ app_templates.add(d)
return sorted(app_templates)
diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py
index 153533dbde6..3baedd889e0 100644
--- a/release/scripts/startup/bl_ui/space_userpref.py
+++ b/release/scripts/startup/bl_ui/space_userpref.py
@@ -1080,7 +1080,7 @@ class PreferenceThemeSpacePanel:
PreferenceThemeSpacePanel._theme_generic(layout, data, self.theme_area)
-class ThemeGenericClassGenerator():
+class ThemeGenericClassGenerator:
@staticmethod
def generate_panel_classes_for_wcols():
@@ -1436,16 +1436,7 @@ class USERPREF_PT_input_ndof(InputPanel, CenterAlignMixIn, Panel):
prefs = context.preferences
inputs = prefs.inputs
- flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False)
-
- flow.prop(inputs, "ndof_sensitivity", text="Pan Sensitivity")
- flow.prop(inputs, "ndof_orbit_sensitivity", text="Orbit Sensitivity")
- flow.prop(inputs, "ndof_deadzone", text="Deadzone")
-
- layout.separator()
-
- flow.row().prop(inputs, "ndof_view_navigate_method", expand=True)
- flow.row().prop(inputs, "ndof_view_rotate_method", expand=True)
+ USERPREF_PT_ndof_settings.draw_settings(layout, inputs)
# -----------------------------------------------------------------------------
@@ -1584,71 +1575,65 @@ class USERPREF_PT_ndof_settings(Panel):
bl_label = "3D Mouse Settings"
bl_space_type = 'TOPBAR' # dummy.
bl_region_type = 'HEADER'
+ bl_ui_units_x = 12
- def draw(self, context):
- layout = self.layout
- layout.use_property_split = True
- layout.use_property_decorate = False # No animation.
-
- input_prefs = context.preferences.inputs
-
- is_view3d = context.space_data.type == 'VIEW_3D'
+ @staticmethod
+ def draw_settings(layout, props, show_3dview_settings=True):
+ col = layout.column()
+ col.prop(props, "ndof_sensitivity", text="Pan Sensitivity")
+ col.prop(props, "ndof_orbit_sensitivity")
+ col.prop(props, "ndof_deadzone")
- col = layout.column(align=True)
- col.prop(input_prefs, "ndof_sensitivity")
- col.prop(input_prefs, "ndof_orbit_sensitivity")
- col.prop(input_prefs, "ndof_deadzone")
+ layout.separator()
- if is_view3d:
- layout.separator()
- layout.prop(input_prefs, "ndof_show_guide")
+ if show_3dview_settings:
+ col = layout.column()
+ col.row().prop(props, "ndof_view_navigate_method", expand=True, text="Navigation")
+ col.row().prop(props, "ndof_view_rotate_method", expand=True, text="Rotation")
layout.separator()
- layout.label(text="Orbit Style")
- layout.row().prop(input_prefs, "ndof_view_navigate_method", text="Navigate")
- layout.row().prop(input_prefs, "ndof_view_rotate_method", text="Orbit")
- layout.separator()
- layout.label(text="Orbit Options")
- split = layout.split(factor=0.6)
- row = split.row()
- row.alignment = 'RIGHT'
- row.label(text="Invert Axis")
- row = split.row(align=True)
- for text, attr in (
- ("X", "ndof_rotx_invert_axis"),
- ("Y", "ndof_roty_invert_axis"),
- ("Z", "ndof_rotz_invert_axis"),
- ):
- row.prop(input_prefs, attr, text=text, toggle=True)
+ col = layout.column()
+ if show_3dview_settings:
+ col.prop(props, "ndof_show_guide")
+ col.prop(props, "ndof_zoom_invert")
+ row = col.row(heading="Pan")
+ row.prop(props, "ndof_pan_yz_swap_axis", text="Swap Y and Z Axes")
- # view2d use pan/zoom
layout.separator()
- layout.label(text="Pan Options")
- split = layout.split(factor=0.6)
- row = split.row()
- row.alignment = 'RIGHT'
- row.label(text="Invert Axis")
- row = split.row(align=True)
+ row = layout.row(heading=("Invert Axis Pan" if show_3dview_settings else "Invert Pan Axis"))
for text, attr in (
("X", "ndof_panx_invert_axis"),
("Y", "ndof_pany_invert_axis"),
("Z", "ndof_panz_invert_axis"),
):
- row.prop(input_prefs, attr, text=text, toggle=True)
+ row.prop(props, attr, text=text, toggle=True)
- layout.prop(input_prefs, "ndof_pan_yz_swap_axis")
-
- layout.label(text="Zoom Options")
- layout.prop(input_prefs, "ndof_zoom_invert")
+ if show_3dview_settings:
+ row = layout.row(heading="Orbit")
+ for text, attr in (
+ ("X", "ndof_rotx_invert_axis"),
+ ("Y", "ndof_roty_invert_axis"),
+ ("Z", "ndof_rotz_invert_axis"),
+ ):
+ row.prop(props, attr, text=text, toggle=True)
- if is_view3d:
layout.separator()
- layout.label(text="Fly/Walk Options")
- layout.prop(input_prefs, "ndof_fly_helicopter")
- layout.prop(input_prefs, "ndof_lock_horizon")
+ col = layout.column(heading="Fly/Walk")
+ col.prop(props, "ndof_lock_horizon")
+ col.prop(props, "ndof_fly_helicopter")
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+ layout.use_property_decorate = False # No animation.
+
+ input_prefs = context.preferences.inputs
+
+ is_view3d = context.space_data.type == 'VIEW_3D'
+ self.draw_settings(layout, input_prefs, is_view3d)
# -----------------------------------------------------------------------------
# Key-Map Editor Panels
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index 664c40f2ec7..7ed969bc921 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -3183,7 +3183,6 @@ class VIEW3D_MT_face_sets_init(Menu):
op.mode = 'FACE_MAPS'
-
class VIEW3D_MT_particle(Menu):
bl_label = "Particle"
@@ -3762,6 +3761,11 @@ class VIEW3D_MT_edit_mesh_context_menu(Menu):
col.separator()
+ col.operator("mesh.mark_seam").clear = False
+ col.operator("mesh.mark_seam", text="Clear Seam").clear = True
+
+ col.separator()
+
col.operator("mesh.mark_sharp")
col.operator("mesh.mark_sharp", text="Clear Sharp").clear = True
@@ -4007,6 +4011,11 @@ class VIEW3D_MT_edit_mesh_edges(Menu):
layout.separator()
+ layout.operator("mesh.mark_seam").clear = False
+ layout.operator("mesh.mark_seam", text="Clear Seam").clear = True
+
+ layout.separator()
+
layout.operator("mesh.mark_sharp")
layout.operator("mesh.mark_sharp", text="Clear Sharp").clear = True
@@ -5270,6 +5279,7 @@ class VIEW3D_MT_sculpt_mask_edit_pie(Menu):
op.mode = 'INVERT'
op = pie.operator("paint.mask_flood_fill", text='Clear Mask')
op.mode = 'VALUE'
+ op.value = 0.0
op = pie.operator("sculpt.mask_filter", text='Smooth Mask')
op.filter_type = 'SMOOTH'
op.auto_iteration_count = True
diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
index 83144b33c67..3d72a2a588c 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -777,10 +777,6 @@ class VIEW3D_PT_sculpt_dyntopo(Panel, View3DPaintPanel):
col.prop(sculpt, "use_smooth_shading")
-
-
-
-
class VIEW3D_PT_sculpt_voxel_remesh(Panel, View3DPaintPanel):
bl_context = ".sculpt_mode" # dot on purpose (access from topbar)
bl_label = "Remesh"
diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h
index 5238853a105..c22e7a24afe 100644
--- a/source/blender/blenkernel/BKE_armature.h
+++ b/source/blender/blenkernel/BKE_armature.h
@@ -90,7 +90,7 @@ void BKE_armature_bone_hash_free(struct bArmature *arm);
bool BKE_armature_bone_flag_test_recursive(const struct Bone *bone, int flag);
-void BKE_armature_refresh_layer_used(struct bArmature *arm);
+void BKE_armature_refresh_layer_used(struct Depsgraph *depsgraph, struct bArmature *arm);
float distfactor_to_bone(
const float vec[3], const float b1[3], const float b2[3], float r1, float r2, float rdist);
diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h
index 5510f3c3d2e..ddebf50691f 100644
--- a/source/blender/blenkernel/BKE_blender_version.h
+++ b/source/blender/blenkernel/BKE_blender_version.h
@@ -31,7 +31,7 @@ extern "C" {
* \note Use #STRINGIFY() rather than defining with quotes.
*/
#define BLENDER_VERSION 290
-#define BLENDER_SUBVERSION 2
+#define BLENDER_SUBVERSION 3
/** Several breakages with 280, e.g. collections vs layers. */
#define BLENDER_MINVERSION 280
#define BLENDER_MINSUBVERSION 0
diff --git a/source/blender/blenkernel/BKE_brush.h b/source/blender/blenkernel/BKE_brush.h
index a97263a6523..4e9430ab3e1 100644
--- a/source/blender/blenkernel/BKE_brush.h
+++ b/source/blender/blenkernel/BKE_brush.h
@@ -57,10 +57,18 @@ struct Brush *BKE_brush_copy(struct Main *bmain, const struct Brush *brush);
void BKE_brush_sculpt_reset(struct Brush *brush);
-void BKE_brush_gpencil_paint_presets(struct Main *bmain, struct ToolSettings *ts);
-void BKE_brush_gpencil_vertex_presets(struct Main *bmain, struct ToolSettings *ts);
-void BKE_brush_gpencil_sculpt_presets(struct Main *bmain, struct ToolSettings *ts);
-void BKE_brush_gpencil_weight_presets(struct Main *bmain, struct ToolSettings *ts);
+void BKE_brush_gpencil_paint_presets(struct Main *bmain,
+ struct ToolSettings *ts,
+ const bool reset);
+void BKE_brush_gpencil_vertex_presets(struct Main *bmain,
+ struct ToolSettings *ts,
+ const bool reset);
+void BKE_brush_gpencil_sculpt_presets(struct Main *bmain,
+ struct ToolSettings *ts,
+ const bool reset);
+void BKE_brush_gpencil_weight_presets(struct Main *bmain,
+ struct ToolSettings *ts,
+ const bool reset);
void BKE_gpencil_brush_preset_set(struct Main *bmain, struct Brush *brush, const short type);
/* image icon function */
diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h
index 2b17cb7a875..bf270f2c06f 100644
--- a/source/blender/blenkernel/BKE_curve.h
+++ b/source/blender/blenkernel/BKE_curve.h
@@ -261,8 +261,9 @@ void BKE_nurb_handles_calc(struct Nurb *nu);
void BKE_nurb_handles_autocalc(struct Nurb *nu, int flag);
void BKE_nurb_bezt_handle_test(struct BezTriple *bezt,
const eBezTriple_Flag__Alias sel_flag,
- const bool use_handle);
-void BKE_nurb_handles_test(struct Nurb *nu, const bool use_handles);
+ const bool use_handle,
+ const bool use_around_local);
+void BKE_nurb_handles_test(struct Nurb *nu, const bool use_handles, const bool use_around_local);
/* **** Depsgraph evaluation **** */
diff --git a/source/blender/blenkernel/BKE_lib_query.h b/source/blender/blenkernel/BKE_lib_query.h
index 353ee3bbf5a..fac1852eafe 100644
--- a/source/blender/blenkernel/BKE_lib_query.h
+++ b/source/blender/blenkernel/BKE_lib_query.h
@@ -132,6 +132,10 @@ typedef struct LibraryForeachIDData LibraryForeachIDData;
bool BKE_lib_query_foreachid_process(struct LibraryForeachIDData *data,
struct ID **id_pp,
int cb_flag);
+int BKE_lib_query_foreachid_process_flags_get(struct LibraryForeachIDData *data);
+int BKE_lib_query_foreachid_process_callback_flag_override(struct LibraryForeachIDData *data,
+ const int cb_flag,
+ const bool do_replace);
#define BKE_LIB_FOREACHID_PROCESS_ID(_data, _id, _cb_flag) \
{ \
diff --git a/source/blender/blenkernel/BKE_light.h b/source/blender/blenkernel/BKE_light.h
index 17f7a8596bf..ead27ec8002 100644
--- a/source/blender/blenkernel/BKE_light.h
+++ b/source/blender/blenkernel/BKE_light.h
@@ -31,6 +31,7 @@
extern "C" {
#endif
+struct Depsgraph;
struct Light;
struct Main;
@@ -38,6 +39,8 @@ struct Light *BKE_light_add(struct Main *bmain, const char *name) ATTR_WARN_UNUS
struct Light *BKE_light_copy(struct Main *bmain, const struct Light *la) ATTR_WARN_UNUSED_RESULT;
struct Light *BKE_light_localize(struct Light *la) ATTR_WARN_UNUSED_RESULT;
+void BKE_light_eval(struct Depsgraph *depsgraph, struct Light *la);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index 409afcd9f75..2bf16e38716 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -309,6 +309,8 @@ void BKE_pbvh_face_sets_set(PBVH *bvh, int *face_sets);
void BKE_pbvh_face_sets_color_set(PBVH *bvh, int seed, int color_default);
+void BKE_pbvh_respect_hide_set(PBVH *bvh, bool respect_hide);
+
/* vertex deformer */
float (*BKE_pbvh_vert_coords_alloc(struct PBVH *pbvh))[3];
void BKE_pbvh_vert_coords_apply(struct PBVH *pbvh, const float (*vertCos)[3], const int totvert);
@@ -334,6 +336,7 @@ typedef struct PBVHVertexIter {
int gy;
int i;
int index;
+ bool respect_hide;
/* grid */
struct CCGKey key;
@@ -402,9 +405,15 @@ void pbvh_vertex_iter_init(PBVH *bvh, PBVHNode *node, PBVHVertexIter *vi, int mo
} \
else if (vi.mverts) { \
vi.mvert = &vi.mverts[vi.vert_indices[vi.gx]]; \
- vi.visible = !(vi.mvert->flag & ME_HIDE); \
- if (mode == PBVH_ITER_UNIQUE && !vi.visible) \
- continue; \
+ if (vi.respect_hide) { \
+ vi.visible = !(vi.mvert->flag & ME_HIDE); \
+ if (mode == PBVH_ITER_UNIQUE && !vi.visible) { \
+ continue; \
+ } \
+ } \
+ else { \
+ BLI_assert(vi.visible); \
+ } \
vi.co = vi.mvert->co; \
vi.no = vi.mvert->no; \
vi.index = vi.vert_indices[vi.i]; \
diff --git a/source/blender/blenkernel/BKE_screen.h b/source/blender/blenkernel/BKE_screen.h
index c49b6e27bba..0d8f5ed550c 100644
--- a/source/blender/blenkernel/BKE_screen.h
+++ b/source/blender/blenkernel/BKE_screen.h
@@ -48,6 +48,7 @@ struct WorkSpace;
struct bContext;
struct bContextDataResult;
struct bScreen;
+struct LibraryForeachIDData;
struct uiLayout;
struct uiList;
struct wmGizmoMap;
@@ -389,6 +390,8 @@ float BKE_screen_view3d_zoom_from_fac(float zoomfac);
void BKE_screen_view3d_shading_init(struct View3DShading *shading);
/* screen */
+void BKE_screen_foreach_id_screen_area(struct LibraryForeachIDData *data, struct ScrArea *area);
+
void BKE_screen_free(struct bScreen *screen);
void BKE_screen_area_map_free(struct ScrAreaMap *area_map) ATTR_NONNULL();
diff --git a/source/blender/blenkernel/BKE_subdiv.h b/source/blender/blenkernel/BKE_subdiv.h
index 0333d52a464..1323938e479 100644
--- a/source/blender/blenkernel/BKE_subdiv.h
+++ b/source/blender/blenkernel/BKE_subdiv.h
@@ -194,6 +194,12 @@ typedef struct Subdiv {
} cache_;
} Subdiv;
+/* =================----====--===== MODULE ==========================------== */
+
+/* (De)initialize the entire subdivision surface module. */
+void BKE_subdiv_init(void);
+void BKE_subdiv_exit(void);
+
/* ========================== CONVERSION HELPERS ============================ */
/* NOTE: uv_smooth is eSubsurfUVSmooth. */
diff --git a/source/blender/blenkernel/BKE_subsurf.h b/source/blender/blenkernel/BKE_subsurf.h
index 16013034823..2dee8de4dc7 100644
--- a/source/blender/blenkernel/BKE_subsurf.h
+++ b/source/blender/blenkernel/BKE_subsurf.h
@@ -103,7 +103,7 @@ typedef struct CCGDerivedMesh {
struct CCGSubSurf *ss;
int freeSS;
- int drawInteriorEdges, useSubsurfUv, useGpuBackend;
+ int drawInteriorEdges, useSubsurfUv;
struct {
int startVert;
@@ -156,13 +156,6 @@ typedef struct CCGDerivedMesh {
ThreadRWMutex origindex_cache_rwlock;
} CCGDerivedMesh;
-#ifdef WITH_OPENSUBDIV
-/* TODO(sergey): Not really ideal place, but we don't currently have better one. */
-void BKE_subsurf_osd_init(void);
-void BKE_subsurf_free_unused_buffers(void);
-void BKE_subsurf_osd_cleanup(void);
-#endif
-
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index 9716e5f5d3f..220bafa2187 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -64,8 +64,6 @@ set(SRC
${CMAKE_SOURCE_DIR}/release/datafiles/userdef/userdef_default.c
intern/CCGSubSurf.c
intern/CCGSubSurf_legacy.c
- intern/CCGSubSurf_opensubdiv.c
- intern/CCGSubSurf_opensubdiv_converter.c
intern/CCGSubSurf_util.c
intern/DerivedMesh.c
intern/action.c
diff --git a/source/blender/blenkernel/intern/CCGSubSurf.c b/source/blender/blenkernel/intern/CCGSubSurf.c
index d76a4d8f859..98deddb4316 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf.c
+++ b/source/blender/blenkernel/intern/CCGSubSurf.c
@@ -32,13 +32,6 @@
#include "CCGSubSurf.h"
#include "CCGSubSurf_intern.h"
-#ifdef WITH_OPENSUBDIV
-# include "opensubdiv_capi.h"
-# include "opensubdiv_converter_capi.h"
-# include "opensubdiv_evaluator_capi.h"
-# include "opensubdiv_topology_refiner_capi.h"
-#endif
-
#include "GPU_glew.h"
/***/
@@ -305,21 +298,6 @@ CCGSubSurf *ccgSubSurf_new(CCGMeshIFC *ifc,
ss->tempVerts = NULL;
ss->tempEdges = NULL;
-#ifdef WITH_OPENSUBDIV
- ss->osd_evaluator = NULL;
- ss->osd_mesh = NULL;
- ss->osd_topology_refiner = NULL;
- ss->osd_mesh_invalid = false;
- ss->osd_coarse_coords_invalid = false;
- ss->osd_vao = 0;
- ss->skip_grids = false;
- ss->osd_compute = 0;
- ss->osd_next_face_ptex_index = 0;
- ss->osd_coarse_coords = NULL;
- ss->osd_num_coarse_coords = 0;
- ss->osd_subdiv_uvs = false;
-#endif
-
return ss;
}
}
@@ -328,23 +306,6 @@ void ccgSubSurf_free(CCGSubSurf *ss)
{
CCGAllocatorIFC allocatorIFC = ss->allocatorIFC;
CCGAllocatorHDL allocator = ss->allocator;
-#ifdef WITH_OPENSUBDIV
- if (ss->osd_evaluator != NULL) {
- openSubdiv_deleteEvaluator(ss->osd_evaluator);
- }
- if (ss->osd_mesh != NULL) {
- ccgSubSurf__delete_osdGLMesh(ss->osd_mesh);
- }
- if (ss->osd_vao != 0) {
- ccgSubSurf__delete_vertex_array(ss->osd_vao);
- }
- if (ss->osd_coarse_coords != NULL) {
- MEM_freeN(ss->osd_coarse_coords);
- }
- if (ss->osd_topology_refiner != NULL) {
- openSubdiv_deleteTopologyRefiner(ss->osd_topology_refiner);
- }
-#endif
if (ss->syncState) {
ccg_ehash_free(ss->oldFMap, (EHEntryFreeFP)_face_free, ss);
@@ -529,9 +490,6 @@ CCGError ccgSubSurf_initFullSync(CCGSubSurf *ss)
ss->tempEdges = MEM_mallocN(sizeof(*ss->tempEdges) * ss->lenTempArrays, "CCGSubsurf tempEdges");
ss->syncState = eSyncState_Vert;
-#ifdef WITH_OPENSUBDIV
- ss->osd_next_face_ptex_index = 0;
-#endif
return eCCGError_None;
}
@@ -671,9 +629,6 @@ CCGError ccgSubSurf_syncVert(
ccg_ehash_insert(ss->vMap, (EHEntry *)v);
v->flags = 0;
}
-#ifdef WITH_OPENSUBDIV
- v->osd_index = ss->vMap->numEntries - 1;
-#endif
}
if (v_r) {
@@ -874,15 +829,6 @@ CCGError ccgSubSurf_syncFace(
}
}
}
-#ifdef WITH_OPENSUBDIV
- f->osd_index = ss->osd_next_face_ptex_index;
- if (numVerts == 4) {
- ss->osd_next_face_ptex_index++;
- }
- else {
- ss->osd_next_face_ptex_index += numVerts;
- }
-#endif
}
if (f_r) {
@@ -893,15 +839,7 @@ CCGError ccgSubSurf_syncFace(
static void ccgSubSurf__sync(CCGSubSurf *ss)
{
-#ifdef WITH_OPENSUBDIV
- if (ss->skip_grids) {
- ccgSubSurf__sync_opensubdiv(ss);
- }
- else
-#endif
- {
- ccgSubSurf__sync_legacy(ss);
- }
+ ccgSubSurf__sync_legacy(ss);
}
CCGError ccgSubSurf_processSync(CCGSubSurf *ss)
@@ -1615,12 +1553,6 @@ int ccgSubSurf_getNumFinalVerts(const CCGSubSurf *ss)
ss->fMap->numEntries +
ss->numGrids * ((gridSize - 2) + ((gridSize - 2) * (gridSize - 2))));
-#ifdef WITH_OPENSUBDIV
- if (ss->skip_grids) {
- return 0;
- }
-#endif
-
return numFinalVerts;
}
int ccgSubSurf_getNumFinalEdges(const CCGSubSurf *ss)
@@ -1629,22 +1561,12 @@ int ccgSubSurf_getNumFinalEdges(const CCGSubSurf *ss)
int gridSize = ccg_gridsize(ss->subdivLevels);
int numFinalEdges = (ss->eMap->numEntries * (edgeSize - 1) +
ss->numGrids * ((gridSize - 1) + 2 * ((gridSize - 2) * (gridSize - 1))));
-#ifdef WITH_OPENSUBDIV
- if (ss->skip_grids) {
- return 0;
- }
-#endif
return numFinalEdges;
}
int ccgSubSurf_getNumFinalFaces(const CCGSubSurf *ss)
{
int gridSize = ccg_gridsize(ss->subdivLevels);
int numFinalFaces = ss->numGrids * ((gridSize - 1) * (gridSize - 1));
-#ifdef WITH_OPENSUBDIV
- if (ss->skip_grids) {
- return 0;
- }
-#endif
return numFinalFaces;
}
diff --git a/source/blender/blenkernel/intern/CCGSubSurf.h b/source/blender/blenkernel/intern/CCGSubSurf.h
index 83b59941ac7..2e5100db6de 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf.h
+++ b/source/blender/blenkernel/intern/CCGSubSurf.h
@@ -211,57 +211,4 @@ CCGFace *ccgFaceIterator_getCurrent(CCGFaceIterator *fi);
int ccgFaceIterator_isStopped(CCGFaceIterator *fi);
void ccgFaceIterator_next(CCGFaceIterator *fi);
-#ifdef WITH_OPENSUBDIV
-struct DerivedMesh;
-
-/* Check if topology changed and evaluators are to be re-created. */
-void ccgSubSurf_checkTopologyChanged(CCGSubSurf *ss, struct DerivedMesh *dm);
-
-/* Create topology refiner from give derived mesh which then later will be
- * used for GL mesh creation.
- */
-void ccgSubSurf_prepareTopologyRefiner(CCGSubSurf *ss, struct DerivedMesh *dm);
-
-/* Make sure GL mesh exists, up to date and ready to draw. */
-bool ccgSubSurf_prepareGLMesh(CCGSubSurf *ss, bool use_osd_glsl, int active_uv_index);
-
-/* Draw given partitions of the GL mesh.
- *
- * TODO(sergey): fill_quads is actually an invariant and should be part
- * of the prepare routine.
- */
-void ccgSubSurf_drawGLMesh(CCGSubSurf *ss,
- bool fill_quads,
- int start_partition,
- int num_partitions);
-
-/* Get number of base faces in a particular GL mesh. */
-int ccgSubSurf_getNumGLMeshBaseFaces(CCGSubSurf *ss);
-
-/* Get number of vertices in base faces in a particular GL mesh. */
-int ccgSubSurf_getNumGLMeshBaseFaceVerts(CCGSubSurf *ss, int face);
-
-/* Controls whether CCG are needed (Cmeaning CPU evaluation) or fully GPU compute
- * and draw is allowed.
- */
-void ccgSubSurf_setSkipGrids(CCGSubSurf *ss, bool skip_grids);
-bool ccgSubSurf_needGrids(CCGSubSurf *ss);
-
-/* Set evaluator's face varying data from UV coordinates.
- * Used for CPU evaluation.
- */
-void ccgSubSurf_evaluatorSetFVarUV(CCGSubSurf *ss, struct DerivedMesh *dm, int layer_index);
-
-/* TODO(sergey): Temporary call to test things. */
-void ccgSubSurf_evaluatorFVarUV(
- CCGSubSurf *ss, int face_index, int S, float grid_u, float grid_v, float uv[2]);
-
-void ccgSubSurf_free_osd_mesh(CCGSubSurf *ss);
-
-void ccgSubSurf_getMinMax(CCGSubSurf *ss, float r_min[3], float r_max[3]);
-
-void ccgSubSurf__sync_subdivUvs(CCGSubSurf *ss, bool subsurf_uvs);
-
-#endif
-
#endif /* __CCGSUBSURF_H__ */
diff --git a/source/blender/blenkernel/intern/CCGSubSurf_intern.h b/source/blender/blenkernel/intern/CCGSubSurf_intern.h
index 51486db1bdc..7c35d2ccfce 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf_intern.h
+++ b/source/blender/blenkernel/intern/CCGSubSurf_intern.h
@@ -157,9 +157,6 @@ typedef enum {
eSyncState_Edge,
eSyncState_Face,
eSyncState_Partial,
-#ifdef WITH_OPENSUBDIV
- eSyncState_OpenSubdiv,
-#endif
} SyncState;
struct CCGSubSurf {
@@ -202,58 +199,6 @@ struct CCGSubSurf {
int lenTempArrays;
CCGVert **tempVerts;
CCGEdge **tempEdges;
-
-#ifdef WITH_OPENSUBDIV
- /* Skip grids means no CCG geometry is created and subsurf is possible
- * to be completely done on GPU.
- */
- bool skip_grids;
-
- /* ** GPU backend. ** */
-
- /* Compute device used by GL mesh. */
- short osd_compute;
- /* Coarse (base mesh) vertex coordinates.
- *
- * Filled in from the modifier stack and passed to OpenSubdiv compute
- * on mesh display.
- */
- float (*osd_coarse_coords)[3];
- int osd_num_coarse_coords;
- /* Denotes whether coarse positions in the GL mesh are invalid.
- * Used to avoid updating GL mesh coords on every redraw.
- */
- bool osd_coarse_coords_invalid;
-
- /* GL mesh descriptor, used for refinement and draw. */
- struct OpenSubdiv_GLMesh *osd_mesh;
- /* Refiner which is used to create GL mesh.
- *
- * Refiner is created from the modifier stack and used later from the main
- * thread to construct GL mesh to avoid threaded access to GL.
- */
- struct OpenSubdiv_TopologyRefiner
- *osd_topology_refiner; /* Only used at synchronization stage. */
- /* Denotes whether osd_mesh is invalid now due to topology changes and needs
- * to be reconstructed.
- *
- * Reconstruction happens from main thread due to OpenGL communication.
- */
- bool osd_mesh_invalid;
- /* Vertex array used for osd_mesh draw. */
- unsigned int osd_vao;
-
- /* ** CPU backend. ** */
-
- /* Limit evaluator, used to evaluate CCG. */
- struct OpenSubdiv_Evaluator *osd_evaluator;
- /* Next PTex face index, used while CCG synchronization
- * to fill in PTex index of CCGFace.
- */
- int osd_next_face_ptex_index;
-
- bool osd_subdiv_uvs;
-#endif
};
/* ** Utility macros ** */
@@ -322,16 +267,6 @@ void ccgSubSurf__sync_legacy(CCGSubSurf *ss);
void ccgSubSurf__sync_opensubdiv(CCGSubSurf *ss);
-/* Delayed free routines. Will do actual free if called from
- * main thread and schedule free for later free otherwise.
- */
-
-#ifdef WITH_OPENSUBDIV
-void ccgSubSurf__delete_osdGLMesh(struct OpenSubdiv_GLMesh *osd_mesh);
-void ccgSubSurf__delete_vertex_array(unsigned int vao);
-void ccgSubSurf__delete_pending(void);
-#endif
-
/* * CCGSubSurf_opensubdiv_converter.c * */
struct OpenSubdiv_Converter;
diff --git a/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c b/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c
deleted file mode 100644
index 3257dd2334c..00000000000
--- a/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c
+++ /dev/null
@@ -1,970 +0,0 @@
-/*
- * 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.
- */
-
-/** \file
- * \ingroup bke
- */
-
-#ifdef WITH_OPENSUBDIV
-
-# include "BLI_sys_types.h" // for intptr_t support
-# include "MEM_guardedalloc.h"
-
-# include "BLI_listbase.h"
-# include "BLI_math.h"
-# include "BLI_threads.h"
-# include "BLI_utildefines.h" /* for BLI_assert */
-
-# include "CCGSubSurf.h"
-# include "CCGSubSurf_intern.h"
-
-# include "BKE_DerivedMesh.h"
-# include "BKE_subsurf.h"
-
-# include "DNA_userdef_types.h"
-
-# include "opensubdiv_capi.h"
-# include "opensubdiv_converter_capi.h"
-# include "opensubdiv_evaluator_capi.h"
-# include "opensubdiv_gl_mesh_capi.h"
-# include "opensubdiv_topology_refiner_capi.h"
-
-# include "GPU_extensions.h"
-# include "GPU_glew.h"
-
-# define OSD_LOG \
- if (false) \
- printf
-
-static bool compare_ccg_derivedmesh_topology(CCGSubSurf *ss, DerivedMesh *dm)
-{
- const int num_verts = dm->getNumVerts(dm);
- const int num_edges = dm->getNumEdges(dm);
- const int num_polys = dm->getNumPolys(dm);
- const MEdge *medge = dm->getEdgeArray(dm);
- const MLoop *mloop = dm->getLoopArray(dm);
- const MPoly *mpoly = dm->getPolyArray(dm);
-
- /* Quick preliminary tests based on the number of verts and facces. */
- {
- if (num_verts != ss->vMap->numEntries || num_edges != ss->eMap->numEntries ||
- num_polys != ss->fMap->numEntries) {
- return false;
- }
- }
-
- /* Rather slow check for faces topology change. */
- {
- CCGFaceIterator ccg_face_iter;
- for (ccgSubSurf_initFaceIterator(ss, &ccg_face_iter);
- !ccgFaceIterator_isStopped(&ccg_face_iter);
- ccgFaceIterator_next(&ccg_face_iter)) {
- /*const*/ CCGFace *ccg_face = ccgFaceIterator_getCurrent(&ccg_face_iter);
- const int poly_index = POINTER_AS_INT(ccgSubSurf_getFaceFaceHandle(ccg_face));
- const MPoly *mp = &mpoly[poly_index];
- int corner;
- if (ccg_face->numVerts != mp->totloop) {
- return false;
- }
- for (corner = 0; corner < ccg_face->numVerts; corner++) {
- /*const*/ CCGVert *ccg_vert = FACE_getVerts(ccg_face)[corner];
- const int vert_index = POINTER_AS_INT(ccgSubSurf_getVertVertHandle(ccg_vert));
- if (vert_index != mloop[mp->loopstart + corner].v) {
- return false;
- }
- }
- }
- }
-
- /* Check for edge topology change. */
- {
- CCGEdgeIterator ccg_edge_iter;
- for (ccgSubSurf_initEdgeIterator(ss, &ccg_edge_iter);
- !ccgEdgeIterator_isStopped(&ccg_edge_iter);
- ccgEdgeIterator_next(&ccg_edge_iter)) {
- /* const */ CCGEdge *ccg_edge = ccgEdgeIterator_getCurrent(&ccg_edge_iter);
- /* const */ CCGVert *ccg_vert1 = ccg_edge->v0;
- /* const */ CCGVert *ccg_vert2 = ccg_edge->v1;
- const int ccg_vert1_index = POINTER_AS_INT(ccgSubSurf_getVertVertHandle(ccg_vert1));
- const int ccg_vert2_index = POINTER_AS_INT(ccgSubSurf_getVertVertHandle(ccg_vert2));
- const int edge_index = POINTER_AS_INT(ccgSubSurf_getEdgeEdgeHandle(ccg_edge));
- const MEdge *me = &medge[edge_index];
- if (me->v1 != ccg_vert1_index || me->v2 != ccg_vert2_index) {
- return false;
- }
- }
- }
-
- /* TODO(sergey): Crease topology changes detection. */
- {
- CCGEdgeIterator ccg_edge_iter;
- for (ccgSubSurf_initEdgeIterator(ss, &ccg_edge_iter);
- !ccgEdgeIterator_isStopped(&ccg_edge_iter);
- ccgEdgeIterator_next(&ccg_edge_iter)) {
- /* const */ CCGEdge *ccg_edge = ccgEdgeIterator_getCurrent(&ccg_edge_iter);
- const int edge_index = POINTER_AS_INT(ccgSubSurf_getEdgeEdgeHandle(ccg_edge));
- if (ccg_edge->crease != medge[edge_index].crease) {
- return false;
- }
- }
- }
-
- return true;
-}
-
-static bool compare_osd_derivedmesh_topology(CCGSubSurf *ss, DerivedMesh *dm)
-{
- OpenSubdiv_Converter converter;
- bool result;
- if (ss->osd_mesh == NULL && ss->osd_topology_refiner == NULL) {
- return true;
- }
- /* TODO(sergey): De-duplicate with topology counter at the bottom of
- * the file.
- */
- ccgSubSurf_converter_setup_from_derivedmesh(ss, dm, &converter);
- result = openSubdiv_topologyRefinerCompareWithConverter(ss->osd_topology_refiner, &converter);
- ccgSubSurf_converter_free(&converter);
- return result;
-}
-
-static bool opensubdiv_is_topology_changed(CCGSubSurf *ss, DerivedMesh *dm)
-{
- if (ss->osd_compute != U.opensubdiv_compute_type) {
- return true;
- }
- if (ss->osd_topology_refiner != NULL) {
- const int levels = ss->osd_topology_refiner->getSubdivisionLevel(ss->osd_topology_refiner);
- BLI_assert(ss->osd_mesh_invalid == true);
- if (levels != ss->subdivLevels) {
- return true;
- }
- }
- if (ss->skip_grids == false) {
- return compare_ccg_derivedmesh_topology(ss, dm) == false;
- }
- else {
- return compare_osd_derivedmesh_topology(ss, dm) == false;
- }
- return false;
-}
-
-void ccgSubSurf_checkTopologyChanged(CCGSubSurf *ss, DerivedMesh *dm)
-{
- if (opensubdiv_is_topology_changed(ss, dm)) {
- /* ** Make sure both GPU and CPU backends are properly reset. ** */
-
- ss->osd_coarse_coords_invalid = true;
-
- /* Reset GPU part. */
- ss->osd_mesh_invalid = true;
- if (ss->osd_topology_refiner != NULL) {
- openSubdiv_deleteTopologyRefiner(ss->osd_topology_refiner);
- ss->osd_topology_refiner = NULL;
- }
-
- /* Reset CPU side. */
- if (ss->osd_evaluator != NULL) {
- openSubdiv_deleteEvaluator(ss->osd_evaluator);
- ss->osd_evaluator = NULL;
- }
- }
-}
-
-static void ccgSubSurf__updateGLMeshCoords(CCGSubSurf *ss)
-{
- BLI_assert(ss->meshIFC.numLayers == 3);
- ss->osd_mesh->setCoarsePositions(
- ss->osd_mesh, (float *)ss->osd_coarse_coords, 0, ss->osd_num_coarse_coords);
-}
-
-bool ccgSubSurf_prepareGLMesh(CCGSubSurf *ss, bool use_osd_glsl, int active_uv_index)
-{
- int compute_type;
-
- switch (U.opensubdiv_compute_type) {
-# define CHECK_COMPUTE_TYPE(type) \
- case USER_OPENSUBDIV_COMPUTE_##type: \
- compute_type = OPENSUBDIV_EVALUATOR_##type; \
- break;
- CHECK_COMPUTE_TYPE(CPU)
- CHECK_COMPUTE_TYPE(OPENMP)
- CHECK_COMPUTE_TYPE(OPENCL)
- CHECK_COMPUTE_TYPE(CUDA)
- CHECK_COMPUTE_TYPE(GLSL_TRANSFORM_FEEDBACK)
- CHECK_COMPUTE_TYPE(GLSL_COMPUTE)
- default:
- compute_type = OPENSUBDIV_EVALUATOR_CPU;
- break;
-# undef CHECK_COMPUTE_TYPE
- }
-
- if (ss->osd_vao == 0) {
- glGenVertexArrays(1, &ss->osd_vao);
- }
-
- if (ss->osd_mesh_invalid) {
- if (ss->osd_mesh != NULL) {
- ccgSubSurf__delete_osdGLMesh(ss->osd_mesh);
- ss->osd_mesh = NULL;
- }
- ss->osd_mesh_invalid = false;
- }
-
- if (ss->osd_mesh == NULL) {
- if (ss->osd_topology_refiner == NULL) {
- /* Happens with empty meshes. */
- /* TODO(sergey): Add assert that mesh is indeed empty. */
- return false;
- }
-
- ss->osd_mesh = openSubdiv_createOsdGLMeshFromTopologyRefiner(ss->osd_topology_refiner,
- compute_type);
-
- if (UNLIKELY(ss->osd_mesh == NULL)) {
- /* Most likely compute device is not available. */
- return false;
- }
-
- ccgSubSurf__updateGLMeshCoords(ss);
- ss->osd_mesh->refine(ss->osd_mesh);
- ss->osd_mesh->synchronize(ss->osd_mesh);
- ss->osd_coarse_coords_invalid = false;
-
- glBindVertexArray(ss->osd_vao);
- ss->osd_mesh->bindVertexBuffer(ss->osd_mesh);
-
- glEnableVertexAttribArray(0);
- glEnableVertexAttribArray(1);
- glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 6, 0);
- glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 6, (float *)12);
-
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glBindVertexArray(0);
- }
- else if (ss->osd_coarse_coords_invalid) {
- ccgSubSurf__updateGLMeshCoords(ss);
- ss->osd_mesh->refine(ss->osd_mesh);
- ss->osd_mesh->synchronize(ss->osd_mesh);
- ss->osd_coarse_coords_invalid = false;
- }
-
- ss->osd_mesh->prepareDraw(ss->osd_mesh, use_osd_glsl, active_uv_index);
-
- return true;
-}
-
-void ccgSubSurf_drawGLMesh(CCGSubSurf *ss,
- bool fill_quads,
- int start_partition,
- int num_partitions)
-{
- if (LIKELY(ss->osd_mesh != NULL)) {
- glBindVertexArray(ss->osd_vao);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ss->osd_mesh->getPatchIndexBuffer(ss->osd_mesh));
-
- ss->osd_mesh->bindVertexBuffer(ss->osd_mesh);
- glBindVertexArray(ss->osd_vao);
- ss->osd_mesh->drawPatches(ss->osd_mesh, fill_quads, start_partition, num_partitions);
- glBindVertexArray(0);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
- }
-}
-
-int ccgSubSurf_getNumGLMeshBaseFaces(CCGSubSurf *ss)
-{
- if (ss->osd_topology_refiner != NULL) {
- return ss->osd_topology_refiner->getNumFaces(ss->osd_topology_refiner);
- }
- return 0;
-}
-
-/* Get number of vertices in base faces in a particular GL mesh. */
-int ccgSubSurf_getNumGLMeshBaseFaceVerts(CCGSubSurf *ss, int face)
-{
- if (ss->osd_topology_refiner != NULL) {
- return ss->osd_topology_refiner->getNumFaceVertices(ss->osd_topology_refiner, face);
- }
- return 0;
-}
-
-void ccgSubSurf_setSkipGrids(CCGSubSurf *ss, bool skip_grids)
-{
- ss->skip_grids = skip_grids;
-}
-
-bool ccgSubSurf_needGrids(CCGSubSurf *ss)
-{
- return ss->skip_grids == false;
-}
-
-BLI_INLINE void ccgSubSurf__mapGridToFace(
- int S, float grid_u, float grid_v, float *face_u, float *face_v)
-{
- float u, v;
-
- /* - Each grid covers half of the face along the edges.
- * - Grid's (0, 0) starts from the middle of the face.
- */
- u = 0.5f - 0.5f * grid_u;
- v = 0.5f - 0.5f * grid_v;
-
- if (S == 0) {
- *face_u = v;
- *face_v = u;
- }
- else if (S == 1) {
- *face_u = 1.0f - u;
- *face_v = v;
- }
- else if (S == 2) {
- *face_u = 1.0f - v;
- *face_v = 1.0f - u;
- }
- else {
- *face_u = u;
- *face_v = 1.0f - v;
- }
-}
-
-BLI_INLINE void ccgSubSurf__mapEdgeToFace(
- int S, int edge_segment, bool inverse_edge, int edgeSize, float *face_u, float *face_v)
-{
- int t = inverse_edge ? edgeSize - edge_segment - 1 : edge_segment;
- if (S == 0) {
- *face_u = (float)t / (edgeSize - 1);
- *face_v = 0.0f;
- }
- else if (S == 1) {
- *face_u = 1.0f;
- *face_v = (float)t / (edgeSize - 1);
- }
- else if (S == 2) {
- *face_u = 1.0f - (float)t / (edgeSize - 1);
- *face_v = 1.0f;
- }
- else {
- *face_u = 0.0f;
- *face_v = 1.0f - (float)t / (edgeSize - 1);
- }
-}
-
-void ccgSubSurf_evaluatorSetFVarUV(CCGSubSurf *ss, DerivedMesh *dm, int layer_index)
-{
- MPoly *mpoly = dm->getPolyArray(dm);
- MLoopUV *mloopuv = CustomData_get_layer_n(&dm->loopData, CD_MLOOPUV, layer_index);
- int num_polys = dm->getNumPolys(dm);
- int index, poly;
- BLI_assert(ss->osd_evaluator != NULL);
- for (poly = 0, index = 0; poly < num_polys; poly++) {
- int loop;
- MPoly *mp = &mpoly[poly];
- for (loop = 0; loop < mp->totloop; loop++, index++) {
- MLoopUV *mluv = &mloopuv[loop + mp->loopstart];
- (void)mluv;
- /* TODO(sergey): Send mluv->uv to the evaluator's face varying
- * buffer.
- */
- }
- }
- (void)ss;
-}
-
-void ccgSubSurf_evaluatorFVarUV(
- CCGSubSurf *ss, int face_index, int S, float grid_u, float grid_v, float uv[2])
-{
- float face_u, face_v;
- ccgSubSurf__mapGridToFace(S, grid_u, grid_v, &face_u, &face_v);
- (void)ss;
- (void)face_index;
- /* TODO(sergey): Evaluate face varying coordinate. */
- zero_v2(uv);
-}
-
-static bool opensubdiv_createEvaluator(CCGSubSurf *ss)
-{
- OpenSubdiv_Converter converter;
- OpenSubdiv_TopologyRefiner *topology_refiner;
- if (ss->fMap->numEntries == 0) {
- /* OpenSubdiv doesn't support meshes without faces. */
- return false;
- }
- ccgSubSurf_converter_setup_from_ccg(ss, &converter);
- OpenSubdiv_TopologyRefinerSettings settings;
- settings.level = ss->subdivLevels;
- settings.is_adaptive = false;
- topology_refiner = openSubdiv_createTopologyRefinerFromConverter(&converter, &settings);
- ccgSubSurf_converter_free(&converter);
- ss->osd_evaluator = openSubdiv_createEvaluatorFromTopologyRefiner(topology_refiner);
- if (ss->osd_evaluator == NULL) {
- BLI_assert(!"OpenSubdiv initialization failed, should not happen.");
- return false;
- }
- return true;
-}
-
-static bool opensubdiv_ensureEvaluator(CCGSubSurf *ss)
-{
- if (ss->osd_evaluator == NULL) {
- OSD_LOG("Allocating new evaluator, %d verts\n", ss->vMap->numEntries);
- opensubdiv_createEvaluator(ss);
- }
- return ss->osd_evaluator != NULL;
-}
-
-static void opensubdiv_updateEvaluatorCoarsePositions(CCGSubSurf *ss)
-{
- float(*positions)[3];
- int vertDataSize = ss->meshIFC.vertDataSize;
- int num_basis_verts = ss->vMap->numEntries;
- int i;
-
- /* TODO(sergey): Avoid allocation on every update. We could either update
- * coordinates in chunks of 1K vertices (which will only use stack memory)
- * or do some callback magic for OSD evaluator can invoke it and fill in
- * buffer directly.
- */
- if (ss->meshIFC.numLayers == 3) {
- /* If all the components are to be initialized, no need to memset the
- * new memory block.
- */
- positions = MEM_mallocN(3 * sizeof(float) * num_basis_verts, "OpenSubdiv coarse points");
- }
- else {
- /* Calloc in order to have z component initialized to 0 for Uvs */
- positions = MEM_callocN(3 * sizeof(float) * num_basis_verts, "OpenSubdiv coarse points");
- }
-# pragma omp parallel for
- for (i = 0; i < ss->vMap->curSize; i++) {
- CCGVert *v = (CCGVert *)ss->vMap->buckets[i];
- for (; v; v = v->next) {
- float *co = VERT_getCo(v, 0);
- BLI_assert(v->osd_index < ss->vMap->numEntries);
- VertDataCopy(positions[v->osd_index], co, ss);
- OSD_LOG("Point %d has value %f %f %f\n",
- v->osd_index,
- positions[v->osd_index][0],
- positions[v->osd_index][1],
- positions[v->osd_index][2]);
- }
- }
-
- ss->osd_evaluator->setCoarsePositions(ss->osd_evaluator, (float *)positions, 0, num_basis_verts);
- ss->osd_evaluator->refine(ss->osd_evaluator);
-
- MEM_freeN(positions);
-}
-
-static void opensubdiv_evaluateQuadFaceGrids(CCGSubSurf *ss,
- CCGFace *face,
- const int osd_face_index)
-{
- int normalDataOffset = ss->normalDataOffset;
- int subdivLevels = ss->subdivLevels;
- int gridSize = ccg_gridsize(subdivLevels);
- int edgeSize = ccg_edgesize(subdivLevels);
- int vertDataSize = ss->meshIFC.vertDataSize;
- int S;
- bool do_normals = ss->meshIFC.numLayers == 3;
-
-# pragma omp parallel for
- for (S = 0; S < face->numVerts; S++) {
- int x, y, k;
- CCGEdge *edge = NULL;
- bool inverse_edge = false;
-
- for (x = 0; x < gridSize; x++) {
- for (y = 0; y < gridSize; y++) {
- float *co = FACE_getIFCo(face, subdivLevels, S, x, y);
- float *no = FACE_getIFNo(face, subdivLevels, S, x, y);
- float grid_u = (float)x / (gridSize - 1), grid_v = (float)y / (gridSize - 1);
- float face_u, face_v;
- float P[3], dPdu[3], dPdv[3];
-
- ccgSubSurf__mapGridToFace(S, grid_u, grid_v, &face_u, &face_v);
-
- /* TODO(sergey): Need proper port. */
- ss->osd_evaluator->evaluateLimit(ss->osd_evaluator,
- osd_face_index,
- face_u,
- face_v,
- P,
- do_normals ? dPdu : NULL,
- do_normals ? dPdv : NULL);
-
- OSD_LOG("face=%d, corner=%d, grid_u=%f, grid_v=%f, face_u=%f, face_v=%f, P=(%f, %f, %f)\n",
- osd_face_index,
- S,
- grid_u,
- grid_v,
- face_u,
- face_v,
- P[0],
- P[1],
- P[2]);
-
- VertDataCopy(co, P, ss);
- if (do_normals) {
- cross_v3_v3v3(no, dPdu, dPdv);
- normalize_v3(no);
- }
-
- if (x == gridSize - 1 && y == gridSize - 1) {
- float *vert_co = VERT_getCo(FACE_getVerts(face)[S], subdivLevels);
- VertDataCopy(vert_co, co, ss);
- if (do_normals) {
- float *vert_no = VERT_getNo(FACE_getVerts(face)[S], subdivLevels);
- VertDataCopy(vert_no, no, ss);
- }
- }
- if (S == 0 && x == 0 && y == 0) {
- float *center_co = (float *)FACE_getCenterData(face);
- VertDataCopy(center_co, co, ss);
- if (do_normals) {
- float *center_no = (float *)((byte *)FACE_getCenterData(face) + normalDataOffset);
- VertDataCopy(center_no, no, ss);
- }
- }
- }
- }
-
- for (x = 0; x < gridSize; x++) {
- VertDataCopy(
- FACE_getIECo(face, subdivLevels, S, x), FACE_getIFCo(face, subdivLevels, S, x, 0), ss);
- if (do_normals) {
- VertDataCopy(
- FACE_getIENo(face, subdivLevels, S, x), FACE_getIFNo(face, subdivLevels, S, x, 0), ss);
- }
- }
-
- for (k = 0; k < face->numVerts; k++) {
- CCGEdge *current_edge = FACE_getEdges(face)[k];
- CCGVert **face_verts = FACE_getVerts(face);
- if (current_edge->v0 == face_verts[S] &&
- current_edge->v1 == face_verts[(S + 1) % face->numVerts]) {
- edge = current_edge;
- inverse_edge = false;
- break;
- }
- if (current_edge->v1 == face_verts[S] &&
- current_edge->v0 == face_verts[(S + 1) % face->numVerts]) {
- edge = current_edge;
- inverse_edge = true;
- break;
- }
- }
-
- BLI_assert(edge != NULL);
-
- for (x = 0; x < edgeSize; x++) {
- float u = 0, v = 0;
- float *co = EDGE_getCo(edge, subdivLevels, x);
- float *no = EDGE_getNo(edge, subdivLevels, x);
- float P[3], dPdu[3], dPdv[3];
- ccgSubSurf__mapEdgeToFace(S, x, inverse_edge, edgeSize, &u, &v);
-
- /* TODO(sergey): Ideally we will re-use grid here, but for now
- * let's just re-evaluate for simplicity.
- */
- /* TODO(sergey): Need proper port. */
- ss->osd_evaluator->evaluateLimit(ss->osd_evaluator, osd_face_index, u, v, P, dPdu, dPdv);
- VertDataCopy(co, P, ss);
- if (do_normals) {
- cross_v3_v3v3(no, dPdu, dPdv);
- normalize_v3(no);
- }
- }
- }
-}
-
-static void opensubdiv_evaluateNGonFaceGrids(CCGSubSurf *ss,
- CCGFace *face,
- const int osd_face_index)
-{
- CCGVert **all_verts = FACE_getVerts(face);
- int normalDataOffset = ss->normalDataOffset;
- int subdivLevels = ss->subdivLevels;
- int gridSize = ccg_gridsize(subdivLevels);
- int edgeSize = ccg_edgesize(subdivLevels);
- int vertDataSize = ss->meshIFC.vertDataSize;
- int S;
- bool do_normals = ss->meshIFC.numLayers == 3;
-
- /* Note about handling non-quad faces.
- *
- * In order to deal with non-quad faces we need to split them
- * into a quads in the following way:
- *
- * |
- * (vert_next)
- * |
- * |
- * |
- * (face_center) ------------------- (v2)
- * | (o)--------------------> |
- * | | v |
- * | | |
- * | | |
- * | | |
- * | | y ^ |
- * | | | |
- * | v u x | |
- * | <---(o) |
- * ---- (vert_prev) ---- (v1) -------------------- (vert)
- *
- * This is how grids are expected to be stored and it's how
- * OpenSubdiv deals with non-quad faces using ptex face indices.
- * We only need to convert ptex (x, y) to grid (u, v) by some
- * simple flips and evaluate the ptex face.
- */
-
- /* Evaluate face grids. */
-# pragma omp parallel for
- for (S = 0; S < face->numVerts; S++) {
- int x, y;
- for (x = 0; x < gridSize; x++) {
- for (y = 0; y < gridSize; y++) {
- float *co = FACE_getIFCo(face, subdivLevels, S, x, y);
- float *no = FACE_getIFNo(face, subdivLevels, S, x, y);
- float u = 1.0f - (float)y / (gridSize - 1), v = 1.0f - (float)x / (gridSize - 1);
- float P[3], dPdu[3], dPdv[3];
-
- /* TODO(sergey): Need proper port. */
- ss->osd_evaluator->evaluateLimit(
- ss->osd_evaluator, osd_face_index + S, u, v, P, dPdu, dPdv);
-
- OSD_LOG("face=%d, corner=%d, u=%f, v=%f, P=(%f, %f, %f)\n",
- osd_face_index + S,
- S,
- u,
- v,
- P[0],
- P[1],
- P[2]);
-
- VertDataCopy(co, P, ss);
- if (do_normals) {
- cross_v3_v3v3(no, dPdu, dPdv);
- normalize_v3(no);
- }
-
- /* TODO(sergey): De-dpuplicate with the quad case. */
- if (x == gridSize - 1 && y == gridSize - 1) {
- float *vert_co = VERT_getCo(FACE_getVerts(face)[S], subdivLevels);
- VertDataCopy(vert_co, co, ss);
- if (do_normals) {
- float *vert_no = VERT_getNo(FACE_getVerts(face)[S], subdivLevels);
- VertDataCopy(vert_no, no, ss);
- }
- }
- if (S == 0 && x == 0 && y == 0) {
- float *center_co = (float *)FACE_getCenterData(face);
- VertDataCopy(center_co, co, ss);
- if (do_normals) {
- float *center_no = (float *)((byte *)FACE_getCenterData(face) + normalDataOffset);
- VertDataCopy(center_no, no, ss);
- }
- }
- }
- }
- for (x = 0; x < gridSize; x++) {
- VertDataCopy(
- FACE_getIECo(face, subdivLevels, S, x), FACE_getIFCo(face, subdivLevels, S, x, 0), ss);
- if (do_normals) {
- VertDataCopy(
- FACE_getIENo(face, subdivLevels, S, x), FACE_getIFNo(face, subdivLevels, S, x, 0), ss);
- }
- }
- }
-
- /* Evaluate edges. */
- for (S = 0; S < face->numVerts; S++) {
- CCGEdge *edge = FACE_getEdges(face)[S];
- int x, S0 = 0, S1 = 0;
- bool flip;
-
- for (x = 0; x < face->numVerts; x++) {
- if (all_verts[x] == edge->v0) {
- S0 = x;
- }
- else if (all_verts[x] == edge->v1) {
- S1 = x;
- }
- }
- if (S == face->numVerts - 1) {
- flip = S0 > S1;
- }
- else {
- flip = S0 < S1;
- }
-
- for (x = 0; x <= edgeSize / 2; x++) {
- float *edge_co = EDGE_getCo(edge, subdivLevels, x);
- float *edge_no = EDGE_getNo(edge, subdivLevels, x);
- float *face_edge_co;
- float *face_edge_no;
- if (flip) {
- face_edge_co = FACE_getIFCo(face, subdivLevels, S0, gridSize - 1, gridSize - 1 - x);
- face_edge_no = FACE_getIFNo(face, subdivLevels, S0, gridSize - 1, gridSize - 1 - x);
- }
- else {
- face_edge_co = FACE_getIFCo(face, subdivLevels, S0, gridSize - 1 - x, gridSize - 1);
- face_edge_no = FACE_getIFNo(face, subdivLevels, S0, gridSize - 1 - x, gridSize - 1);
- }
- VertDataCopy(edge_co, face_edge_co, ss);
- if (do_normals) {
- VertDataCopy(edge_no, face_edge_no, ss);
- }
- }
- for (x = edgeSize / 2 + 1; x < edgeSize; x++) {
- float *edge_co = EDGE_getCo(edge, subdivLevels, x);
- float *edge_no = EDGE_getNo(edge, subdivLevels, x);
- float *face_edge_co;
- float *face_edge_no;
- if (flip) {
- face_edge_co = FACE_getIFCo(face, subdivLevels, S1, x - edgeSize / 2, gridSize - 1);
- face_edge_no = FACE_getIFNo(face, subdivLevels, S1, x - edgeSize / 2, gridSize - 1);
- }
- else {
- face_edge_co = FACE_getIFCo(face, subdivLevels, S1, gridSize - 1, x - edgeSize / 2);
- face_edge_no = FACE_getIFNo(face, subdivLevels, S1, gridSize - 1, x - edgeSize / 2);
- }
- VertDataCopy(edge_co, face_edge_co, ss);
- if (do_normals) {
- VertDataCopy(edge_no, face_edge_no, ss);
- }
- }
- }
-}
-
-static void opensubdiv_evaluateGrids(CCGSubSurf *ss)
-{
- int i;
- for (i = 0; i < ss->fMap->curSize; i++) {
- CCGFace *face = (CCGFace *)ss->fMap->buckets[i];
- for (; face; face = face->next) {
- if (face->numVerts == 4) {
- /* For quads we do special magic with converting face coords
- * into corner coords and interpolating grids from it.
- */
- opensubdiv_evaluateQuadFaceGrids(ss, face, face->osd_index);
- }
- else {
- /* NGons and tris are split into separate osd faces which
- * evaluates onto grids directly.
- */
- opensubdiv_evaluateNGonFaceGrids(ss, face, face->osd_index);
- }
- }
- }
-}
-
-CCGError ccgSubSurf_initOpenSubdivSync(CCGSubSurf *ss)
-{
- if (ss->syncState != eSyncState_None) {
- return eCCGError_InvalidSyncState;
- }
- ss->syncState = eSyncState_OpenSubdiv;
- return eCCGError_None;
-}
-
-void ccgSubSurf_prepareTopologyRefiner(CCGSubSurf *ss, DerivedMesh *dm)
-{
- if (ss->osd_mesh == NULL || ss->osd_mesh_invalid) {
- if (dm->getNumPolys(dm) != 0) {
- OpenSubdiv_Converter converter;
- ccgSubSurf_converter_setup_from_derivedmesh(ss, dm, &converter);
- /* TODO(sergey): Remove possibly previously allocated refiner. */
- OpenSubdiv_TopologyRefinerSettings settings;
- settings.level = ss->subdivLevels;
- settings.is_adaptive = false;
- ss->osd_topology_refiner = openSubdiv_createTopologyRefinerFromConverter(&converter,
- &settings);
- ccgSubSurf_converter_free(&converter);
- }
- }
-
- /* Update number of grids, needed for things like final faces
- * counter, used by display drawing.
- */
- {
- const int num_polys = dm->getNumPolys(dm);
- const MPoly *mpoly = dm->getPolyArray(dm);
- int poly;
- ss->numGrids = 0;
- for (poly = 0; poly < num_polys; poly++) {
- ss->numGrids += mpoly[poly].totloop;
- }
- }
-
- {
- const int num_verts = dm->getNumVerts(dm);
- const MVert *mvert = dm->getVertArray(dm);
- int vert;
- if (ss->osd_coarse_coords != NULL && num_verts != ss->osd_num_coarse_coords) {
- MEM_freeN(ss->osd_coarse_coords);
- ss->osd_coarse_coords = NULL;
- }
- if (ss->osd_coarse_coords == NULL) {
- ss->osd_coarse_coords = MEM_mallocN(sizeof(float) * 6 * num_verts, "osd coarse positions");
- }
- for (vert = 0; vert < num_verts; vert++) {
- copy_v3_v3(ss->osd_coarse_coords[vert * 2 + 0], mvert[vert].co);
- normal_short_to_float_v3(ss->osd_coarse_coords[vert * 2 + 1], mvert[vert].no);
- }
- ss->osd_num_coarse_coords = num_verts;
- ss->osd_coarse_coords_invalid = true;
- }
-}
-
-void ccgSubSurf__sync_opensubdiv(CCGSubSurf *ss)
-{
- BLI_assert(ss->meshIFC.numLayers == 2 || ss->meshIFC.numLayers == 3);
-
- /* Common synchronization steps */
- ss->osd_compute = U.opensubdiv_compute_type;
-
- if (ss->skip_grids == false) {
- /* Make sure OSD evaluator is up-to-date. */
- if (opensubdiv_ensureEvaluator(ss)) {
- /* Update coarse points in the OpenSubdiv evaluator. */
- opensubdiv_updateEvaluatorCoarsePositions(ss);
-
- /* Evaluate opensubdiv mesh into the CCG grids. */
- opensubdiv_evaluateGrids(ss);
- }
- }
- else {
- BLI_assert(ss->meshIFC.numLayers == 3);
- }
-
-# ifdef DUMP_RESULT_GRIDS
- ccgSubSurf__dumpCoords(ss);
-# endif
-}
-
-void ccgSubSurf_free_osd_mesh(CCGSubSurf *ss)
-{
- if (ss->osd_mesh != NULL) {
- ccgSubSurf__delete_osdGLMesh(ss->osd_mesh);
- ss->osd_mesh = NULL;
- }
- if (ss->osd_vao != 0) {
- glDeleteVertexArrays(1, &ss->osd_vao);
- ss->osd_vao = 0;
- }
-}
-
-void ccgSubSurf_getMinMax(CCGSubSurf *ss, float r_min[3], float r_max[3])
-{
- int i;
- BLI_assert(ss->skip_grids == true);
- if (ss->osd_num_coarse_coords == 0) {
- zero_v3(r_min);
- zero_v3(r_max);
- }
- for (i = 0; i < ss->osd_num_coarse_coords; i++) {
- /* Coarse coordinates has normals interleaved into the array. */
- DO_MINMAX(ss->osd_coarse_coords[2 * i], r_min, r_max);
- }
-}
-
-/* ** Delayed delete routines ** */
-
-typedef struct OsdDeletePendingItem {
- struct OsdDeletePendingItem *next, *prev;
- OpenSubdiv_GLMesh *osd_mesh;
- unsigned int vao;
-} OsdDeletePendingItem;
-
-static SpinLock delete_spin;
-static ListBase delete_pool = {NULL, NULL};
-
-static void delete_pending_push(OpenSubdiv_GLMesh *osd_mesh, unsigned int vao)
-{
- OsdDeletePendingItem *new_entry = MEM_mallocN(sizeof(OsdDeletePendingItem),
- "opensubdiv delete entry");
- new_entry->osd_mesh = osd_mesh;
- new_entry->vao = vao;
- BLI_spin_lock(&delete_spin);
- BLI_addtail(&delete_pool, new_entry);
- BLI_spin_unlock(&delete_spin);
-}
-
-void ccgSubSurf__delete_osdGLMesh(OpenSubdiv_GLMesh *osd_mesh)
-{
- if (BLI_thread_is_main()) {
- openSubdiv_deleteOsdGLMesh(osd_mesh);
- }
- else {
- delete_pending_push(osd_mesh, 0);
- }
-}
-
-void ccgSubSurf__delete_vertex_array(unsigned int vao)
-{
- if (BLI_thread_is_main()) {
- glDeleteVertexArrays(1, &vao);
- }
- else {
- delete_pending_push(NULL, vao);
- }
-}
-
-void ccgSubSurf__delete_pending(void)
-{
- OsdDeletePendingItem *entry;
- BLI_assert(BLI_thread_is_main());
- BLI_spin_lock(&delete_spin);
- for (entry = delete_pool.first; entry != NULL; entry = entry->next) {
- if (entry->osd_mesh != NULL) {
- openSubdiv_deleteOsdGLMesh(entry->osd_mesh);
- }
- if (entry->vao != 0) {
- glDeleteVertexArrays(1, &entry->vao);
- }
- }
- BLI_freelistN(&delete_pool);
- BLI_spin_unlock(&delete_spin);
-}
-
-void ccgSubSurf__sync_subdivUvs(CCGSubSurf *ss, bool subdiv_uvs)
-{
- ss->osd_subdiv_uvs = subdiv_uvs;
-}
-
-/* ** Public API ** */
-
-void BKE_subsurf_osd_init(void)
-{
- openSubdiv_init();
- BLI_spin_init(&delete_spin);
-}
-
-void BKE_subsurf_free_unused_buffers(void)
-{
- ccgSubSurf__delete_pending();
-}
-
-void BKE_subsurf_osd_cleanup(void)
-{
- openSubdiv_cleanup();
- ccgSubSurf__delete_pending();
- BLI_spin_end(&delete_spin);
-}
-
-#endif /* WITH_OPENSUBDIV */
diff --git a/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv_converter.c b/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv_converter.c
deleted file mode 100644
index 16766d52e57..00000000000
--- a/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv_converter.c
+++ /dev/null
@@ -1,777 +0,0 @@
-/*
- * 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.
- */
-
-/** \file
- * \ingroup bke
- */
-
-#ifdef WITH_OPENSUBDIV
-
-# include <stdlib.h>
-
-# include "BLI_sys_types.h" // for intptr_t support
-# include "MEM_guardedalloc.h"
-
-# include "BLI_math.h"
-# include "BLI_utildefines.h" /* for BLI_assert */
-
-# include "CCGSubSurf.h"
-# include "CCGSubSurf_intern.h"
-
-# include "BKE_DerivedMesh.h"
-# include "BKE_mesh_mapping.h"
-
-# include "opensubdiv_capi.h"
-# include "opensubdiv_converter_capi.h"
-
-/* Use mesh element mapping structures during conversion.
- * Uses more memory but is much faster than naive algorithm.
- */
-# define USE_MESH_ELEMENT_MAPPING
-
-/**
- * Converter from DerivedMesh.
- */
-
-typedef struct ConvDMStorage {
- CCGSubSurf *ss;
- DerivedMesh *dm;
-
-# ifdef USE_MESH_ELEMENT_MAPPING
- MeshElemMap *vert_edge_map, *vert_poly_map, *edge_poly_map;
- int *vert_edge_mem, *vert_poly_mem, *edge_poly_mem;
-# endif
-
- MVert *mvert;
- MEdge *medge;
- MLoop *mloop;
- MPoly *mpoly;
-
- MeshIslandStore island_store;
- int num_uvs;
- float *uvs;
- int *face_uvs;
-} ConvDMStorage;
-
-static OpenSubdiv_SchemeType conv_dm_get_type(const OpenSubdiv_Converter *converter)
-{
- ConvDMStorage *storage = converter->user_data;
- if (storage->ss->meshIFC.simpleSubdiv) {
- return OSD_SCHEME_BILINEAR;
- }
- else {
- return OSD_SCHEME_CATMARK;
- }
-}
-
-static OpenSubdiv_VtxBoundaryInterpolation conv_dm_get_vtx_boundary_interpolation(
- const OpenSubdiv_Converter *UNUSED(converter))
-{
- return OSD_VTX_BOUNDARY_EDGE_ONLY;
-}
-
-static OpenSubdiv_FVarLinearInterpolation conv_dm_get_fvar_linear_interpolation(
- const OpenSubdiv_Converter *converter)
-{
- ConvDMStorage *storage = converter->user_data;
- if (storage->ss->osd_subdiv_uvs) {
- return OSD_FVAR_LINEAR_INTERPOLATION_CORNERS_ONLY;
- }
- return OSD_FVAR_LINEAR_INTERPOLATION_ALL;
-}
-
-static bool conv_dm_specifies_full_topology(const OpenSubdiv_Converter *UNUSED(converter))
-{
- return true;
-}
-
-static int conv_dm_get_num_faces(const OpenSubdiv_Converter *converter)
-{
- ConvDMStorage *storage = converter->user_data;
- DerivedMesh *dm = storage->dm;
- return dm->getNumPolys(dm);
-}
-
-static int conv_dm_get_num_edges(const OpenSubdiv_Converter *converter)
-{
- ConvDMStorage *storage = converter->user_data;
- DerivedMesh *dm = storage->dm;
- return dm->getNumEdges(dm);
-}
-
-static int conv_dm_get_num_verts(const OpenSubdiv_Converter *converter)
-{
- ConvDMStorage *storage = converter->user_data;
- DerivedMesh *dm = storage->dm;
- return dm->getNumVerts(dm);
-}
-
-static int conv_dm_get_num_face_verts(const OpenSubdiv_Converter *converter, int face)
-{
- ConvDMStorage *storage = converter->user_data;
- const MPoly *mpoly = &storage->mpoly[face];
- return mpoly->totloop;
-}
-
-static void conv_dm_get_face_verts(const OpenSubdiv_Converter *converter,
- int face,
- int *face_verts)
-{
- ConvDMStorage *storage = converter->user_data;
- const MPoly *mpoly = &storage->mpoly[face];
- int loop;
- for (loop = 0; loop < mpoly->totloop; loop++) {
- face_verts[loop] = storage->mloop[mpoly->loopstart + loop].v;
- }
-}
-
-static void conv_dm_get_face_edges(const OpenSubdiv_Converter *converter,
- int face,
- int *face_edges)
-{
- ConvDMStorage *storage = converter->user_data;
- const MPoly *mpoly = &storage->mpoly[face];
- int loop;
- for (loop = 0; loop < mpoly->totloop; loop++) {
- face_edges[loop] = storage->mloop[mpoly->loopstart + loop].e;
- }
-}
-
-static void conv_dm_get_edge_verts(const OpenSubdiv_Converter *converter,
- int edge,
- int *edge_verts)
-{
- ConvDMStorage *storage = converter->user_data;
- const MEdge *medge = &storage->medge[edge];
- edge_verts[0] = medge->v1;
- edge_verts[1] = medge->v2;
-}
-
-static int conv_dm_get_num_edge_faces(const OpenSubdiv_Converter *converter, int edge)
-{
- ConvDMStorage *storage = converter->user_data;
-# ifndef USE_MESH_ELEMENT_MAPPING
- DerivedMesh *dm = storage->dm;
- int num = 0, poly;
- for (poly = 0; poly < dm->getNumPolys(dm); poly++) {
- const MPoly *mpoly = &user_data->mpoly[poly];
- int loop;
- for (loop = 0; loop < mpoly->totloop; loop++) {
- const MLoop *mloop = &storage->mloop[mpoly->loopstart + loop];
- if (mloop->e == edge) {
- num++;
- break;
- }
- }
- }
- return num;
-# else
- return storage->edge_poly_map[edge].count;
-# endif
-}
-
-static void conv_dm_get_edge_faces(const OpenSubdiv_Converter *converter,
- int edge,
- int *edge_faces)
-{
- ConvDMStorage *storage = converter->user_data;
-# ifndef USE_MESH_ELEMENT_MAPPING
- DerivedMesh *dm = storage->dm;
- int num = 0, poly;
- for (poly = 0; poly < dm->getNumPolys(dm); poly++) {
- const MPoly *mpoly = &user_data->mpoly[poly];
- int loop;
- for (loop = 0; loop < mpoly->totloop; loop++) {
- const MLoop *mloop = &storage->mloop[mpoly->loopstart + loop];
- if (mloop->e == edge) {
- edge_faces[num++] = poly;
- break;
- }
- }
- }
-# else
- memcpy(edge_faces,
- storage->edge_poly_map[edge].indices,
- sizeof(int) * storage->edge_poly_map[edge].count);
-# endif
-}
-
-static float conv_dm_get_edge_sharpness(const OpenSubdiv_Converter *converter, int edge)
-{
- ConvDMStorage *storage = converter->user_data;
- CCGSubSurf *ss = storage->ss;
- const MEdge *medge = storage->medge;
- return (float)medge[edge].crease / 255.0f * ss->subdivLevels;
-}
-
-static int conv_dm_get_num_vert_edges(const OpenSubdiv_Converter *converter, int vert)
-{
- ConvDMStorage *storage = converter->user_data;
-# ifndef USE_MESH_ELEMENT_MAPPING
- DerivedMesh *dm = storage->dm;
- int num = 0, edge;
- for (edge = 0; edge < dm->getNumEdges(dm); edge++) {
- const MEdge *medge = &user_data->medge[edge];
- if (medge->v1 == vert || medge->v2 == vert) {
- num++;
- }
- }
- return num;
-# else
- return storage->vert_edge_map[vert].count;
-# endif
-}
-
-static void conv_dm_get_vert_edges(const OpenSubdiv_Converter *converter,
- int vert,
- int *vert_edges)
-{
- ConvDMStorage *storage = converter->user_data;
-# ifndef USE_MESH_ELEMENT_MAPPING
- DerivedMesh *dm = storage->dm;
- int num = 0, edge;
- for (edge = 0; edge < dm->getNumEdges(dm); edge++) {
- const MEdge *medge = &user_data->medge[edge];
- if (medge->v1 == vert || medge->v2 == vert) {
- vert_edges[num++] = edge;
- }
- }
-# else
- memcpy(vert_edges,
- storage->vert_edge_map[vert].indices,
- sizeof(int) * storage->vert_edge_map[vert].count);
-# endif
-}
-
-static int conv_dm_get_num_vert_faces(const OpenSubdiv_Converter *converter, int vert)
-{
- ConvDMStorage *storage = converter->user_data;
-# ifndef USE_MESH_ELEMENT_MAPPING
- DerivedMesh *dm = storage->dm;
- int num = 0, poly;
- for (poly = 0; poly < dm->getNumPolys(dm); poly++) {
- const MPoly *mpoly = &user_data->mpoly[poly];
- int loop;
- for (loop = 0; loop < mpoly->totloop; loop++) {
- const MLoop *mloop = &storage->mloop[mpoly->loopstart + loop];
- if (mloop->v == vert) {
- num++;
- break;
- }
- }
- }
- return num;
-# else
- return storage->vert_poly_map[vert].count;
-# endif
-}
-
-static void conv_dm_get_vert_faces(const OpenSubdiv_Converter *converter,
- int vert,
- int *vert_faces)
-{
- ConvDMStorage *storage = converter->user_data;
-# ifndef USE_MESH_ELEMENT_MAPPING
- DerivedMesh *dm = storage->dm;
- int num = 0, poly;
- for (poly = 0; poly < dm->getNumPolys(dm); poly++) {
- const MPoly *mpoly = &storage->mpoly[poly];
- int loop;
- for (loop = 0; loop < mpoly->totloop; loop++) {
- const MLoop *mloop = &storage->mloop[mpoly->loopstart + loop];
- if (mloop->v == vert) {
- vert_faces[num++] = poly;
- break;
- }
- }
- }
-# else
- memcpy(vert_faces,
- storage->vert_poly_map[vert].indices,
- sizeof(int) * storage->vert_poly_map[vert].count);
-# endif
-}
-
-static bool conv_dm_is_infinite_sharp_vertex(const OpenSubdiv_Converter *UNUSED(converter),
- int UNUSED(manifold_vertex_index))
-{
- return false;
-}
-
-static float conv_dm_get_vertex_sharpness(const OpenSubdiv_Converter *UNUSED(converter),
- int UNUSED(manifold_vertex_index))
-{
- return 0.0f;
-}
-
-static int conv_dm_get_num_uv_layers(const OpenSubdiv_Converter *converter)
-{
- ConvDMStorage *storage = converter->user_data;
- DerivedMesh *dm = storage->dm;
- int num_uv_layers = CustomData_number_of_layers(&dm->loopData, CD_MLOOPUV);
- return num_uv_layers;
-}
-
-static void conv_dm_precalc_uv_layer(const OpenSubdiv_Converter *converter, int layer)
-{
- ConvDMStorage *storage = converter->user_data;
- DerivedMesh *dm = storage->dm;
-
- const MLoopUV *mloopuv = CustomData_get_layer_n(&dm->loopData, CD_MLOOPUV, layer);
- const int num_loops = dm->getNumLoops(dm);
-
- /* Initialize memory required for the operations. */
- if (storage->uvs == NULL) {
- storage->uvs = MEM_mallocN(sizeof(float) * 2 * num_loops, "osd uvs");
- }
- if (storage->face_uvs == NULL) {
- storage->face_uvs = MEM_mallocN(sizeof(int) * num_loops, "osd face uvs");
- }
-
- /* Calculate islands connectivity of the UVs. */
- BKE_mesh_calc_islands_loop_poly_uvmap(storage->mvert,
- dm->getNumVerts(dm),
- storage->medge,
- dm->getNumEdges(dm),
- storage->mpoly,
- dm->getNumPolys(dm),
- storage->mloop,
- dm->getNumLoops(dm),
- mloopuv,
- &storage->island_store);
-
- /* Here we "weld" duplicated vertices from island to the same UV value.
- * The idea here is that we need to pass individual islands to OpenSubdiv.
- */
- storage->num_uvs = 0;
- for (int island = 0; island < storage->island_store.islands_num; island++) {
- MeshElemMap *island_poly_map = storage->island_store.islands[island];
- for (int poly = 0; poly < island_poly_map->count; poly++) {
- int poly_index = island_poly_map->indices[poly];
- /* Within the same UV island we should share UV points across
- * loops. Otherwise each poly will be subdivided individually
- * which we don't really want.
- */
- const MPoly *mpoly = &storage->mpoly[poly_index];
- for (int loop = 0; loop < mpoly->totloop; loop++) {
- const MLoopUV *luv = &mloopuv[mpoly->loopstart + loop];
- bool found = false;
- /* TODO(sergey): Quite bad loop, which gives us O(N^2)
- * complexity here. But how can we do it smarter, hopefully
- * without requiring lots of additional memory.
- */
- for (int i = 0; i < storage->num_uvs; i++) {
- if (equals_v2v2(luv->uv, &storage->uvs[2 * i])) {
- storage->face_uvs[mpoly->loopstart + loop] = i;
- found = true;
- break;
- }
- }
- if (!found) {
- copy_v2_v2(&storage->uvs[2 * storage->num_uvs], luv->uv);
- storage->face_uvs[mpoly->loopstart + loop] = storage->num_uvs;
- ++storage->num_uvs;
- }
- }
- }
- }
-}
-
-static void conv_dm_finish_uv_layer(const OpenSubdiv_Converter *converter)
-{
- ConvDMStorage *storage = converter->user_data;
- BKE_mesh_loop_islands_free(&storage->island_store);
-}
-
-static int conv_dm_get_num_uvs(const OpenSubdiv_Converter *converter)
-{
- ConvDMStorage *storage = converter->user_data;
- return storage->num_uvs;
-}
-
-static int conv_dm_get_face_corner_uv_index(const OpenSubdiv_Converter *converter,
- int face,
- int corner)
-{
- ConvDMStorage *storage = converter->user_data;
- const MPoly *mpoly = &storage->mpoly[face];
- return storage->face_uvs[mpoly->loopstart + corner];
-}
-
-static void conv_dm_free_user_data(const OpenSubdiv_Converter *converter)
-{
- ConvDMStorage *user_data = converter->user_data;
- if (user_data->uvs != NULL) {
- MEM_freeN(user_data->uvs);
- }
- if (user_data->face_uvs != NULL) {
- MEM_freeN(user_data->face_uvs);
- }
-
-# ifdef USE_MESH_ELEMENT_MAPPING
- MEM_freeN(user_data->vert_edge_map);
- MEM_freeN(user_data->vert_edge_mem);
- MEM_freeN(user_data->vert_poly_map);
- MEM_freeN(user_data->vert_poly_mem);
- MEM_freeN(user_data->edge_poly_map);
- MEM_freeN(user_data->edge_poly_mem);
-# endif
- MEM_freeN(user_data);
-}
-
-void ccgSubSurf_converter_setup_from_derivedmesh(CCGSubSurf *ss,
- DerivedMesh *dm,
- OpenSubdiv_Converter *converter)
-{
- ConvDMStorage *user_data;
-
- converter->getSchemeType = conv_dm_get_type;
-
- converter->getVtxBoundaryInterpolation = conv_dm_get_vtx_boundary_interpolation;
- converter->getFVarLinearInterpolation = conv_dm_get_fvar_linear_interpolation;
- converter->specifiesFullTopology = conv_dm_specifies_full_topology;
-
- converter->getNumFaces = conv_dm_get_num_faces;
- converter->getNumEdges = conv_dm_get_num_edges;
- converter->getNumVertices = conv_dm_get_num_verts;
-
- converter->getNumFaceVertices = conv_dm_get_num_face_verts;
- converter->getFaceVertices = conv_dm_get_face_verts;
- converter->getFaceEdges = conv_dm_get_face_edges;
-
- converter->getEdgeVertices = conv_dm_get_edge_verts;
- converter->getNumEdgeFaces = conv_dm_get_num_edge_faces;
- converter->getEdgeFaces = conv_dm_get_edge_faces;
- converter->getEdgeSharpness = conv_dm_get_edge_sharpness;
-
- converter->getNumVertexEdges = conv_dm_get_num_vert_edges;
- converter->getVertexEdges = conv_dm_get_vert_edges;
- converter->getNumVertexFaces = conv_dm_get_num_vert_faces;
- converter->getVertexFaces = conv_dm_get_vert_faces;
- converter->isInfiniteSharpVertex = conv_dm_is_infinite_sharp_vertex;
- converter->getVertexSharpness = conv_dm_get_vertex_sharpness;
-
- converter->getNumUVLayers = conv_dm_get_num_uv_layers;
- converter->precalcUVLayer = conv_dm_precalc_uv_layer;
- converter->finishUVLayer = conv_dm_finish_uv_layer;
- converter->getNumUVCoordinates = conv_dm_get_num_uvs;
- converter->getFaceCornerUVIndex = conv_dm_get_face_corner_uv_index;
-
- user_data = MEM_mallocN(sizeof(ConvDMStorage), __func__);
- user_data->ss = ss;
- user_data->dm = dm;
-
- user_data->mvert = dm->getVertArray(dm);
- user_data->medge = dm->getEdgeArray(dm);
- user_data->mloop = dm->getLoopArray(dm);
- user_data->mpoly = dm->getPolyArray(dm);
-
- memset(&user_data->island_store, 0, sizeof(user_data->island_store));
-
- user_data->uvs = NULL;
- user_data->face_uvs = NULL;
-
- converter->freeUserData = conv_dm_free_user_data;
- converter->user_data = user_data;
-
-# ifdef USE_MESH_ELEMENT_MAPPING
- {
- const MEdge *medge = dm->getEdgeArray(dm);
- const MLoop *mloop = dm->getLoopArray(dm);
- const MPoly *mpoly = dm->getPolyArray(dm);
- const int num_vert = dm->getNumVerts(dm), num_edge = dm->getNumEdges(dm),
- num_loop = dm->getNumLoops(dm), num_poly = dm->getNumPolys(dm);
- BKE_mesh_vert_edge_map_create(
- &user_data->vert_edge_map, &user_data->vert_edge_mem, medge, num_vert, num_edge);
-
- BKE_mesh_vert_poly_map_create(&user_data->vert_poly_map,
- &user_data->vert_poly_mem,
- mpoly,
- mloop,
- num_vert,
- num_poly,
- num_loop);
-
- BKE_mesh_edge_poly_map_create(&user_data->edge_poly_map,
- &user_data->edge_poly_mem,
- medge,
- num_edge,
- mpoly,
- num_poly,
- mloop,
- num_loop);
- }
-# endif /* USE_MESH_ELEMENT_MAPPING */
-}
-
-/**
- * Converter from CCGSubSurf
- */
-
-static OpenSubdiv_SchemeType conv_ccg_get_bilinear_type(const OpenSubdiv_Converter *converter)
-{
- CCGSubSurf *ss = converter->user_data;
- if (ss->meshIFC.simpleSubdiv) {
- return OSD_SCHEME_BILINEAR;
- }
- else {
- return OSD_SCHEME_CATMARK;
- }
-}
-
-static OpenSubdiv_VtxBoundaryInterpolation conv_ccg_get_vtx_boundary_interpolation(
- const OpenSubdiv_Converter *UNUSED(converter))
-{
- return OSD_VTX_BOUNDARY_EDGE_ONLY;
-}
-
-static OpenSubdiv_FVarLinearInterpolation conv_ccg_get_fvar_linear_interpolation(
- const OpenSubdiv_Converter *converter)
-{
- CCGSubSurf *ss = converter->user_data;
- if (ss->osd_subdiv_uvs) {
- return OSD_FVAR_LINEAR_INTERPOLATION_CORNERS_ONLY;
- }
- return OSD_FVAR_LINEAR_INTERPOLATION_ALL;
-}
-
-static bool conv_ccg_specifies_full_topology(const OpenSubdiv_Converter *UNUSED(converter))
-{
- return true;
-}
-
-static int conv_ccg_get_num_faces(const OpenSubdiv_Converter *converter)
-{
- CCGSubSurf *ss = converter->user_data;
- return ss->fMap->numEntries;
-}
-
-static int conv_ccg_get_num_edges(const OpenSubdiv_Converter *converter)
-{
- CCGSubSurf *ss = converter->user_data;
- return ss->eMap->numEntries;
-}
-
-static int conv_ccg_get_num_verts(const OpenSubdiv_Converter *converter)
-{
- CCGSubSurf *ss = converter->user_data;
- return ss->vMap->numEntries;
-}
-
-static int conv_ccg_get_num_face_verts(const OpenSubdiv_Converter *converter, int face)
-{
- CCGSubSurf *ss = converter->user_data;
- CCGFace *ccg_face = ccgSubSurf_getFace(ss, POINTER_FROM_INT(face));
- return ccgSubSurf_getFaceNumVerts(ccg_face);
-}
-
-static void conv_ccg_get_face_verts(const OpenSubdiv_Converter *converter,
- int face,
- int *face_verts)
-{
- CCGSubSurf *ss = converter->user_data;
- CCGFace *ccg_face = ccgSubSurf_getFace(ss, POINTER_FROM_INT(face));
- int num_face_verts = ccgSubSurf_getFaceNumVerts(ccg_face);
- int loop;
- for (loop = 0; loop < num_face_verts; loop++) {
- CCGVert *ccg_vert = ccgSubSurf_getFaceVert(ccg_face, loop);
- face_verts[loop] = POINTER_AS_INT(ccgSubSurf_getVertVertHandle(ccg_vert));
- }
-}
-
-static void conv_ccg_get_face_edges(const OpenSubdiv_Converter *converter,
- int face,
- int *face_edges)
-{
- CCGSubSurf *ss = converter->user_data;
- CCGFace *ccg_face = ccgSubSurf_getFace(ss, POINTER_FROM_INT(face));
- int num_face_verts = ccgSubSurf_getFaceNumVerts(ccg_face);
- int loop;
- for (loop = 0; loop < num_face_verts; loop++) {
- CCGEdge *ccg_edge = ccgSubSurf_getFaceEdge(ccg_face, loop);
- face_edges[loop] = POINTER_AS_INT(ccgSubSurf_getEdgeEdgeHandle(ccg_edge));
- }
-}
-
-static void conv_ccg_get_edge_verts(const OpenSubdiv_Converter *converter,
- int edge,
- int *edge_verts)
-{
- CCGSubSurf *ss = converter->user_data;
- CCGEdge *ccg_edge = ccgSubSurf_getEdge(ss, POINTER_FROM_INT(edge));
- CCGVert *ccg_vert0 = ccgSubSurf_getEdgeVert0(ccg_edge);
- CCGVert *ccg_vert1 = ccgSubSurf_getEdgeVert1(ccg_edge);
- edge_verts[0] = POINTER_AS_INT(ccgSubSurf_getVertVertHandle(ccg_vert0));
- edge_verts[1] = POINTER_AS_INT(ccgSubSurf_getVertVertHandle(ccg_vert1));
-}
-
-static int conv_ccg_get_num_edge_faces(const OpenSubdiv_Converter *converter, int edge)
-{
- CCGSubSurf *ss = converter->user_data;
- CCGEdge *ccg_edge = ccgSubSurf_getEdge(ss, POINTER_FROM_INT(edge));
- return ccgSubSurf_getEdgeNumFaces(ccg_edge);
-}
-
-static void conv_ccg_get_edge_faces(const OpenSubdiv_Converter *converter,
- int edge,
- int *edge_faces)
-{
- CCGSubSurf *ss = converter->user_data;
- CCGEdge *ccg_edge = ccgSubSurf_getEdge(ss, POINTER_FROM_INT(edge));
- int num_edge_faces = ccgSubSurf_getEdgeNumFaces(ccg_edge);
- int face;
- for (face = 0; face < num_edge_faces; face++) {
- CCGFace *ccg_face = ccgSubSurf_getEdgeFace(ccg_edge, face);
- edge_faces[face] = POINTER_AS_INT(ccgSubSurf_getFaceFaceHandle(ccg_face));
- }
-}
-
-static float conv_ccg_get_edge_sharpness(const OpenSubdiv_Converter *converter, int edge)
-{
- CCGSubSurf *ss = converter->user_data;
- CCGEdge *ccg_edge = ccgSubSurf_getEdge(ss, POINTER_FROM_INT(edge));
- /* TODO(sergey): Multiply by subdivision level once CPU evaluator
- * is switched to uniform subdivision type.
- */
- return ccg_edge->crease;
-}
-
-static int conv_ccg_get_num_vert_edges(const OpenSubdiv_Converter *converter, int vert)
-{
- CCGSubSurf *ss = converter->user_data;
- CCGVert *ccg_vert = ccgSubSurf_getVert(ss, POINTER_FROM_INT(vert));
- return ccgSubSurf_getVertNumEdges(ccg_vert);
-}
-
-static void conv_ccg_get_vert_edges(const OpenSubdiv_Converter *converter,
- int vert,
- int *vert_edges)
-{
- CCGSubSurf *ss = converter->user_data;
- CCGVert *ccg_vert = ccgSubSurf_getVert(ss, POINTER_FROM_INT(vert));
- int num_vert_edges = ccgSubSurf_getVertNumEdges(ccg_vert);
- int edge;
- for (edge = 0; edge < num_vert_edges; edge++) {
- CCGEdge *ccg_edge = ccgSubSurf_getVertEdge(ccg_vert, edge);
- vert_edges[edge] = POINTER_AS_INT(ccgSubSurf_getEdgeEdgeHandle(ccg_edge));
- }
-}
-
-static int conv_ccg_get_num_vert_faces(const OpenSubdiv_Converter *converter, int vert)
-{
- CCGSubSurf *ss = converter->user_data;
- CCGVert *ccg_vert = ccgSubSurf_getVert(ss, POINTER_FROM_INT(vert));
- return ccgSubSurf_getVertNumFaces(ccg_vert);
-}
-
-static void conv_ccg_get_vert_faces(const OpenSubdiv_Converter *converter,
- int vert,
- int *vert_faces)
-{
- CCGSubSurf *ss = converter->user_data;
- CCGVert *ccg_vert = ccgSubSurf_getVert(ss, POINTER_FROM_INT(vert));
- int num_vert_faces = ccgSubSurf_getVertNumFaces(ccg_vert);
- int face;
- for (face = 0; face < num_vert_faces; face++) {
- CCGFace *ccg_face = ccgSubSurf_getVertFace(ccg_vert, face);
- vert_faces[face] = POINTER_AS_INT(ccgSubSurf_getFaceFaceHandle(ccg_face));
- }
-}
-
-static bool conv_ccg_is_infinite_sharp_vertex(const OpenSubdiv_Converter *UNUSED(converter),
- int UNUSED(manifold_vertex_index))
-{
- return false;
-}
-
-static float conv_ccg_get_vertex_sharpness(const OpenSubdiv_Converter *UNUSED(converter),
- int UNUSED(manifold_vertex_index))
-{
- return 0.0f;
-}
-
-static int conv_ccg_get_num_uv_layers(const OpenSubdiv_Converter *UNUSED(converter))
-{
- return 0;
-}
-
-static void conv_ccg_precalc_uv_layer(const OpenSubdiv_Converter *UNUSED(converter),
- int UNUSED(layer))
-{
-}
-
-static void conv_ccg_finish_uv_layer(const OpenSubdiv_Converter *UNUSED(converter))
-{
-}
-
-static int conv_ccg_get_num_uvs(const OpenSubdiv_Converter *UNUSED(converter))
-{
- return 0;
-}
-
-static int conv_ccg_get_face_corner_uv_index(const OpenSubdiv_Converter *UNUSED(converter),
- int UNUSED(face),
- int UNUSED(corner_))
-{
- return 0;
-}
-
-void ccgSubSurf_converter_setup_from_ccg(CCGSubSurf *ss, OpenSubdiv_Converter *converter)
-{
- converter->getSchemeType = conv_ccg_get_bilinear_type;
-
- converter->getVtxBoundaryInterpolation = conv_ccg_get_vtx_boundary_interpolation;
- converter->getFVarLinearInterpolation = conv_ccg_get_fvar_linear_interpolation;
- converter->specifiesFullTopology = conv_ccg_specifies_full_topology;
-
- converter->getNumFaces = conv_ccg_get_num_faces;
- converter->getNumEdges = conv_ccg_get_num_edges;
- converter->getNumVertices = conv_ccg_get_num_verts;
-
- converter->getNumFaceVertices = conv_ccg_get_num_face_verts;
- converter->getFaceVertices = conv_ccg_get_face_verts;
- converter->getFaceEdges = conv_ccg_get_face_edges;
-
- converter->getEdgeVertices = conv_ccg_get_edge_verts;
- converter->getNumEdgeFaces = conv_ccg_get_num_edge_faces;
- converter->getEdgeFaces = conv_ccg_get_edge_faces;
- converter->getEdgeSharpness = conv_ccg_get_edge_sharpness;
-
- converter->getNumVertexEdges = conv_ccg_get_num_vert_edges;
- converter->getVertexEdges = conv_ccg_get_vert_edges;
- converter->getNumVertexFaces = conv_ccg_get_num_vert_faces;
- converter->getVertexFaces = conv_ccg_get_vert_faces;
- converter->isInfiniteSharpVertex = conv_ccg_is_infinite_sharp_vertex;
- converter->getVertexSharpness = conv_ccg_get_vertex_sharpness;
-
- converter->getNumUVLayers = conv_ccg_get_num_uv_layers;
- converter->precalcUVLayer = conv_ccg_precalc_uv_layer;
- converter->finishUVLayer = conv_ccg_finish_uv_layer;
- converter->getNumUVCoordinates = conv_ccg_get_num_uvs;
- converter->getFaceCornerUVIndex = conv_ccg_get_face_corner_uv_index;
-
- converter->freeUserData = NULL;
- converter->user_data = ss;
-}
-
-void ccgSubSurf_converter_free(struct OpenSubdiv_Converter *converter)
-{
- if (converter->freeUserData) {
- converter->freeUserData(converter);
- }
-}
-
-#endif /* WITH_OPENSUBDIV */
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index b3893d8600f..52fe51afcb2 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -1798,9 +1798,7 @@ static void mesh_build_data(struct Depsgraph *depsgraph,
}
}
- if (mesh_eval != NULL) {
- mesh_runtime_check_normals_valid(mesh_eval);
- }
+ mesh_runtime_check_normals_valid(mesh_eval);
mesh_build_extra_data(depsgraph, ob, mesh_eval);
}
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index 4f51e23496c..bd39ffc65e7 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -52,6 +52,7 @@
#include "BKE_idprop.h"
#include "BKE_idtype.h"
#include "BKE_lib_id.h"
+#include "BKE_lib_query.h"
#include "BKE_main.h"
#include "BKE_object.h"
@@ -154,6 +155,15 @@ static void action_free_data(struct ID *id)
BLI_freelistN(&action->markers);
}
+static void action_foreach_id(ID *id, LibraryForeachIDData *data)
+{
+ bAction *act = (bAction *)id;
+
+ LISTBASE_FOREACH (TimeMarker *, marker, &act->markers) {
+ BKE_LIB_FOREACHID_PROCESS(data, marker->camera, IDWALK_CB_NOP);
+ }
+}
+
IDTypeInfo IDType_ID_AC = {
.id_code = ID_AC,
.id_filter = FILTER_ID_AC,
@@ -168,6 +178,7 @@ IDTypeInfo IDType_ID_AC = {
.copy_data = action_copy_data,
.free_data = action_free_data,
.make_local = NULL,
+ .foreach_id = action_foreach_id,
};
/* ***************** Library data level operations on action ************** */
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index 06a97fc3826..36921bd2662 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -67,6 +67,7 @@
#include "BKE_scene.h"
#include "DEG_depsgraph_build.h"
+#include "DEG_depsgraph_query.h"
#include "BIK_api.h"
@@ -500,14 +501,21 @@ static void armature_refresh_layer_used_recursive(bArmature *arm, ListBase *bone
}
}
-/* Update the layers_used variable after bones are moved between layer
- * NOTE: Used to be done in drawing code in 2.7, but that won't work with
- * Copy-on-Write, as drawing uses evaluated copies.
- */
-void BKE_armature_refresh_layer_used(bArmature *arm)
+void BKE_armature_refresh_layer_used(struct Depsgraph *depsgraph, struct bArmature *arm)
{
+ if (arm->edbo != NULL) {
+ /* Don't perform this update when the armature is in edit mode. In that case it should be
+ * handled by ED_armature_edit_refresh_layer_used(). */
+ return;
+ }
+
arm->layer_used = 0;
armature_refresh_layer_used_recursive(arm, &arm->bonebase);
+
+ if (depsgraph == NULL || DEG_is_active(depsgraph)) {
+ bArmature *arm_orig = (bArmature *)DEG_get_original_id(&arm->id);
+ arm_orig->layer_used = arm->layer_used;
+ }
}
/* Finds the best possible extension to the name on a particular axis. (For renaming, check for
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index c21dec16555..133917e441c 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -1063,14 +1063,20 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
}
}
-static Brush *gpencil_brush_ensure(Main *bmain,
- ToolSettings *ts,
- const char *brush_name,
- eObjectMode mode)
+static Brush *gpencil_brush_ensure(
+ Main *bmain, ToolSettings *ts, const char *brush_name, eObjectMode mode, bool *r_new)
{
+ *r_new = false;
Brush *brush = BLI_findstring(&bmain->brushes, brush_name, offsetof(ID, name) + 2);
+
+ /* If the brush exist, but the type is not GPencil or the mode is wrong, create a new one. */
+ if ((brush != NULL) && ((brush->gpencil_settings == NULL) || (brush->ob_mode != mode))) {
+ brush = NULL;
+ }
+
if (brush == NULL) {
brush = BKE_brush_add_gpencil(bmain, ts, brush_name, mode);
+ *r_new = true;
}
if (brush->gpencil_settings == NULL) {
@@ -1081,164 +1087,235 @@ static Brush *gpencil_brush_ensure(Main *bmain,
}
/* Create a set of grease pencil Drawing presets. */
-void BKE_brush_gpencil_paint_presets(Main *bmain, ToolSettings *ts)
+void BKE_brush_gpencil_paint_presets(Main *bmain, ToolSettings *ts, const bool reset)
{
+ bool r_new = false;
Paint *paint = &ts->gp_paint->paint;
-
+ Brush *brush_prev = paint->brush;
Brush *brush, *deft_draw;
/* Airbrush brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Airbrush", OB_MODE_PAINT_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_AIRBRUSH);
+ brush = gpencil_brush_ensure(bmain, ts, "Airbrush", OB_MODE_PAINT_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_AIRBRUSH);
+ }
/* Ink Pen brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Ink Pen", OB_MODE_PAINT_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_INK_PEN);
+ brush = gpencil_brush_ensure(bmain, ts, "Ink Pen", OB_MODE_PAINT_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_INK_PEN);
+ }
/* Ink Pen Rough brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Ink Pen Rough", OB_MODE_PAINT_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_INK_PEN_ROUGH);
+ brush = gpencil_brush_ensure(bmain, ts, "Ink Pen Rough", OB_MODE_PAINT_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_INK_PEN_ROUGH);
+ }
/* Marker Bold brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Marker Bold", OB_MODE_PAINT_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_MARKER_BOLD);
+ brush = gpencil_brush_ensure(bmain, ts, "Marker Bold", OB_MODE_PAINT_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_MARKER_BOLD);
+ }
/* Marker Chisel brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Marker Chisel", OB_MODE_PAINT_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_MARKER_CHISEL);
+ brush = gpencil_brush_ensure(bmain, ts, "Marker Chisel", OB_MODE_PAINT_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_MARKER_CHISEL);
+ }
/* Pen brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Pen", OB_MODE_PAINT_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_PEN);
+ brush = gpencil_brush_ensure(bmain, ts, "Pen", OB_MODE_PAINT_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_PEN);
+ }
/* Pencil Soft brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Pencil Soft", OB_MODE_PAINT_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_PENCIL_SOFT);
+ brush = gpencil_brush_ensure(bmain, ts, "Pencil Soft", OB_MODE_PAINT_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_PENCIL_SOFT);
+ }
/* Pencil brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Pencil", OB_MODE_PAINT_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_PENCIL);
+ brush = gpencil_brush_ensure(bmain, ts, "Pencil", OB_MODE_PAINT_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_PENCIL);
+ }
deft_draw = brush; /* save default brush. */
/* Fill brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Fill Area", OB_MODE_PAINT_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_FILL_AREA);
+ brush = gpencil_brush_ensure(bmain, ts, "Fill Area", OB_MODE_PAINT_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_FILL_AREA);
+ }
/* Soft Eraser brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Eraser Soft", OB_MODE_PAINT_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_ERASER_SOFT);
+ brush = gpencil_brush_ensure(bmain, ts, "Eraser Soft", OB_MODE_PAINT_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_ERASER_SOFT);
+ }
/* Hard Eraser brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Eraser Hard", OB_MODE_PAINT_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_ERASER_HARD);
+ brush = gpencil_brush_ensure(bmain, ts, "Eraser Hard", OB_MODE_PAINT_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_ERASER_HARD);
+ }
/* Point Eraser brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Eraser Point", OB_MODE_PAINT_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_ERASER_POINT);
+ brush = gpencil_brush_ensure(bmain, ts, "Eraser Point", OB_MODE_PAINT_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_ERASER_POINT);
+ }
/* Stroke Eraser brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Eraser Stroke", OB_MODE_PAINT_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_ERASER_STROKE);
+ brush = gpencil_brush_ensure(bmain, ts, "Eraser Stroke", OB_MODE_PAINT_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_ERASER_STROKE);
+ }
/* Tint brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Tint", OB_MODE_PAINT_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_TINT);
+ brush = gpencil_brush_ensure(bmain, ts, "Tint", OB_MODE_PAINT_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_TINT);
+ }
/* Set default Draw brush. */
- BKE_paint_brush_set(paint, deft_draw);
+ if (reset || brush_prev == NULL) {
+ BKE_paint_brush_set(paint, deft_draw);
+ }
}
/* Create a set of grease pencil Vertex Paint presets. */
-void BKE_brush_gpencil_vertex_presets(Main *bmain, ToolSettings *ts)
+void BKE_brush_gpencil_vertex_presets(Main *bmain, ToolSettings *ts, const bool reset)
{
- Paint *vertexpaint = &ts->gp_vertexpaint->paint;
+ bool r_new = false;
+ Paint *vertexpaint = &ts->gp_vertexpaint->paint;
+ Brush *brush_prev = vertexpaint->brush;
Brush *brush, *deft_vertex;
/* Vertex Draw brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Vertex Draw", OB_MODE_VERTEX_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_VERTEX_DRAW);
+ brush = gpencil_brush_ensure(bmain, ts, "Vertex Draw", OB_MODE_VERTEX_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_VERTEX_DRAW);
+ }
deft_vertex = brush; /* save default brush. */
/* Vertex Blur brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Vertex Blur", OB_MODE_VERTEX_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_VERTEX_BLUR);
-
+ brush = gpencil_brush_ensure(bmain, ts, "Vertex Blur", OB_MODE_VERTEX_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_VERTEX_BLUR);
+ }
/* Vertex Average brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Vertex Average", OB_MODE_VERTEX_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_VERTEX_AVERAGE);
-
+ brush = gpencil_brush_ensure(bmain, ts, "Vertex Average", OB_MODE_VERTEX_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_VERTEX_AVERAGE);
+ }
/* Vertex Smear brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Vertex Smear", OB_MODE_VERTEX_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_VERTEX_SMEAR);
-
+ brush = gpencil_brush_ensure(bmain, ts, "Vertex Smear", OB_MODE_VERTEX_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_VERTEX_SMEAR);
+ }
/* Vertex Replace brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Vertex Replace", OB_MODE_VERTEX_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_VERTEX_REPLACE);
+ brush = gpencil_brush_ensure(bmain, ts, "Vertex Replace", OB_MODE_VERTEX_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_VERTEX_REPLACE);
+ }
/* Set default Vertex brush. */
- BKE_paint_brush_set(vertexpaint, deft_vertex);
+ if (reset || brush_prev == NULL) {
+ BKE_paint_brush_set(vertexpaint, deft_vertex);
+ }
}
/* Create a set of grease pencil Sculpt Paint presets. */
-void BKE_brush_gpencil_sculpt_presets(Main *bmain, ToolSettings *ts)
+void BKE_brush_gpencil_sculpt_presets(Main *bmain, ToolSettings *ts, const bool reset)
{
+ bool r_new = false;
+
Paint *sculptpaint = &ts->gp_sculptpaint->paint;
+ Brush *brush_prev = sculptpaint->brush;
Brush *brush, *deft_sculpt;
/* Smooth brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Smooth Stroke", OB_MODE_SCULPT_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_SMOOTH_STROKE);
+ brush = gpencil_brush_ensure(bmain, ts, "Smooth Stroke", OB_MODE_SCULPT_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_SMOOTH_STROKE);
+ }
deft_sculpt = brush;
/* Strength brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Strength Stroke", OB_MODE_SCULPT_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_STRENGTH_STROKE);
+ brush = gpencil_brush_ensure(bmain, ts, "Strength Stroke", OB_MODE_SCULPT_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_STRENGTH_STROKE);
+ }
/* Thickness brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Thickness Stroke", OB_MODE_SCULPT_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_THICKNESS_STROKE);
+ brush = gpencil_brush_ensure(bmain, ts, "Thickness Stroke", OB_MODE_SCULPT_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_THICKNESS_STROKE);
+ }
/* Grab brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Grab Stroke", OB_MODE_SCULPT_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_GRAB_STROKE);
+ brush = gpencil_brush_ensure(bmain, ts, "Grab Stroke", OB_MODE_SCULPT_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_GRAB_STROKE);
+ }
/* Push brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Push Stroke", OB_MODE_SCULPT_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_PUSH_STROKE);
+ brush = gpencil_brush_ensure(bmain, ts, "Push Stroke", OB_MODE_SCULPT_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_PUSH_STROKE);
+ }
/* Twist brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Twist Stroke", OB_MODE_SCULPT_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_TWIST_STROKE);
+ brush = gpencil_brush_ensure(bmain, ts, "Twist Stroke", OB_MODE_SCULPT_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_TWIST_STROKE);
+ }
/* Pinch brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Pinch Stroke", OB_MODE_SCULPT_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_PINCH_STROKE);
+ brush = gpencil_brush_ensure(bmain, ts, "Pinch Stroke", OB_MODE_SCULPT_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_PINCH_STROKE);
+ }
/* Randomize brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Randomize Stroke", OB_MODE_SCULPT_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_RANDOMIZE_STROKE);
+ brush = gpencil_brush_ensure(bmain, ts, "Randomize Stroke", OB_MODE_SCULPT_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_RANDOMIZE_STROKE);
+ }
/* Clone brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Clone Stroke", OB_MODE_SCULPT_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_CLONE_STROKE);
+ brush = gpencil_brush_ensure(bmain, ts, "Clone Stroke", OB_MODE_SCULPT_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_CLONE_STROKE);
+ }
/* Set default brush. */
- BKE_paint_brush_set(sculptpaint, deft_sculpt);
+ if (reset || brush_prev == NULL) {
+ BKE_paint_brush_set(sculptpaint, deft_sculpt);
+ }
}
/* Create a set of grease pencil Weight Paint presets. */
-void BKE_brush_gpencil_weight_presets(Main *bmain, ToolSettings *ts)
+void BKE_brush_gpencil_weight_presets(Main *bmain, ToolSettings *ts, const bool reset)
{
- Paint *weightpaint = &ts->gp_weightpaint->paint;
+ bool r_new = false;
+ Paint *weightpaint = &ts->gp_weightpaint->paint;
+ Brush *brush_prev = weightpaint->brush;
Brush *brush, *deft_weight;
/* Vertex Draw brush. */
- brush = gpencil_brush_ensure(bmain, ts, "Draw Weight", OB_MODE_WEIGHT_GPENCIL);
- BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_DRAW_WEIGHT);
+ brush = gpencil_brush_ensure(bmain, ts, "Draw Weight", OB_MODE_WEIGHT_GPENCIL, &r_new);
+ if ((reset) || (r_new)) {
+ BKE_gpencil_brush_preset_set(bmain, brush, GP_BRUSH_PRESET_DRAW_WEIGHT);
+ }
deft_weight = brush; /* save default brush. */
/* Set default brush. */
- BKE_paint_brush_set(weightpaint, deft_weight);
+ if (reset || brush_prev == NULL) {
+ BKE_paint_brush_set(weightpaint, deft_weight);
+ }
}
struct Brush *BKE_brush_first_search(struct Main *bmain, const eObjectMode ob_mode)
diff --git a/source/blender/blenkernel/intern/cachefile.c b/source/blender/blenkernel/intern/cachefile.c
index d23b643ce70..da9dab36044 100644
--- a/source/blender/blenkernel/intern/cachefile.c
+++ b/source/blender/blenkernel/intern/cachefile.c
@@ -97,6 +97,7 @@ IDTypeInfo IDType_ID_CF = {
.copy_data = cache_file_copy_data,
.free_data = cache_file_free_data,
.make_local = NULL,
+ .foreach_id = NULL,
};
/* TODO: make this per cache file to avoid global locks. */
diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c
index 583bb39a851..c1d77fd5f9e 100644
--- a/source/blender/blenkernel/intern/collection.c
+++ b/source/blender/blenkernel/intern/collection.c
@@ -34,6 +34,7 @@
#include "BKE_idtype.h"
#include "BKE_layer.h"
#include "BKE_lib_id.h"
+#include "BKE_lib_query.h"
#include "BKE_lib_remap.h"
#include "BKE_main.h"
#include "BKE_object.h"
@@ -128,6 +129,28 @@ static void collection_free_data(ID *id)
BKE_collection_object_cache_free(collection);
}
+static void collection_foreach_id(ID *id, LibraryForeachIDData *data)
+{
+ Collection *collection = (Collection *)id;
+
+ LISTBASE_FOREACH (CollectionObject *, cob, &collection->gobject) {
+ BKE_LIB_FOREACHID_PROCESS(data, cob->ob, IDWALK_CB_USER);
+ }
+ LISTBASE_FOREACH (CollectionChild *, child, &collection->children) {
+ BKE_LIB_FOREACHID_PROCESS(data, child->collection, IDWALK_CB_NEVER_SELF | IDWALK_CB_USER);
+ }
+ LISTBASE_FOREACH (CollectionParent *, parent, &collection->parents) {
+ /* XXX This is very weak. The whole idea of keeping pointers to private IDs is very bad
+ * anyway... */
+ const int cb_flag = ((parent->collection != NULL &&
+ (parent->collection->id.flag & LIB_EMBEDDED_DATA) != 0) ?
+ IDWALK_CB_EMBEDDED :
+ IDWALK_CB_NOP);
+ BKE_LIB_FOREACHID_PROCESS(
+ data, parent->collection, IDWALK_CB_NEVER_SELF | IDWALK_CB_LOOPBACK | cb_flag);
+ }
+}
+
IDTypeInfo IDType_ID_GR = {
.id_code = ID_GR,
.id_filter = FILTER_ID_GR,
@@ -142,6 +165,7 @@ IDTypeInfo IDType_ID_GR = {
.copy_data = collection_copy_data,
.free_data = collection_free_data,
.make_local = NULL,
+ .foreach_id = collection_foreach_id,
};
/***************************** Add Collection *******************************/
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index 72197869f58..0798bc95797 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -4169,7 +4169,8 @@ void BKE_nurb_handle_calc_simple_auto(Nurb *nu, BezTriple *bezt)
*/
void BKE_nurb_bezt_handle_test(BezTriple *bezt,
const eBezTriple_Flag__Alias sel_flag,
- const bool use_handle)
+ const bool use_handle,
+ const bool use_around_local)
{
short flag = 0;
@@ -4192,6 +4193,10 @@ void BKE_nurb_bezt_handle_test(BezTriple *bezt,
flag = (bezt->f2 & sel_flag) ? (SEL_F1 | SEL_F2 | SEL_F3) : 0;
}
+ if (use_around_local) {
+ flag &= ~SEL_F2;
+ }
+
/* check for partial selection */
if (!ELEM(flag, 0, SEL_F1 | SEL_F2 | SEL_F3)) {
if (ELEM(bezt->h1, HD_AUTO, HD_AUTO_ANIM)) {
@@ -4218,7 +4223,7 @@ void BKE_nurb_bezt_handle_test(BezTriple *bezt,
#undef SEL_F3
}
-void BKE_nurb_handles_test(Nurb *nu, const bool use_handle)
+void BKE_nurb_handles_test(Nurb *nu, const bool use_handle, const bool use_around_local)
{
BezTriple *bezt;
int a;
@@ -4230,7 +4235,7 @@ void BKE_nurb_handles_test(Nurb *nu, const bool use_handle)
bezt = nu->bezt;
a = nu->pntsu;
while (a--) {
- BKE_nurb_bezt_handle_test(bezt, SELECT, use_handle);
+ BKE_nurb_bezt_handle_test(bezt, SELECT, use_handle, use_around_local);
bezt++;
}
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index 8c47401cbc3..a022f3f5d14 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -699,6 +699,24 @@ static size_t layerFilesize_mdisps(CDataFile *UNUSED(cdf), const void *data, int
return size;
}
+static void layerInterp_paint_mask(
+ const void **sources, const float *weights, const float *sub_weights, int count, void *dest)
+{
+ float mask = 0.0f;
+ const float *sub_weight = sub_weights;
+ for (int i = 0; i < count; i++) {
+ float weight = weights ? weights[i] : 1.0f;
+ const float *src = sources[i];
+ if (sub_weights) {
+ mask += (*src) * (*sub_weight) * weight;
+ sub_weight++;
+ }
+ else {
+ mask += (*src) * weight;
+ }
+ }
+ *(float *)dest = mask;
+}
static void layerCopy_grid_paint_mask(const void *source, void *dest, int count)
{
@@ -1595,7 +1613,7 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
/* END BMESH ONLY */
/* 34: CD_PAINT_MASK */
- {sizeof(float), "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
+ {sizeof(float), "", 0, NULL, NULL, NULL, layerInterp_paint_mask, NULL, NULL},
/* 35: CD_GRID_PAINT_MASK */
{sizeof(GridPaintMask),
"GridPaintMask",
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c
index d73f92b6073..a3e1eeb89c7 100644
--- a/source/blender/blenkernel/intern/displist.c
+++ b/source/blender/blenkernel/intern/displist.c
@@ -1134,17 +1134,18 @@ static void curve_calc_modifiers_post(Depsgraph *depsgraph,
if (r_final) {
if (force_mesh_conversion && !modified) {
- /* XXX 2.8 : This is a workaround for by some deeper technical depts:
+ /* XXX 2.8 : This is a workaround for by some deeper technical debts:
* - DRW Batch cache is stored inside the ob->data.
* - Curve data is not COWed for instances that use different modifiers.
- * This can causes the modifiers to be applied on all user of the same datablock (see T71055)
+ * This can causes the modifiers to be applied on all user of the same data-block
+ * (see T71055)
*
* The easy workaround is to force to generate a Mesh that will be used for display data
* since a Mesh output is already used for generative modifiers.
* However it does not fix problems with actual edit data still being shared.
*
- * The right solution would be to COW the Curve data block at the input of the modifer stack
- * just like what the mesh modifier does.
+ * The right solution would be to COW the Curve data block at the input of the modifier
+ * stack just like what the mesh modifier does.
* */
modified = BKE_mesh_new_nomain_from_curve_displist(ob, dispbase);
}
diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c
index 79d9a40f06b..f3cc17f46f6 100644
--- a/source/blender/blenkernel/intern/dynamicpaint.c
+++ b/source/blender/blenkernel/intern/dynamicpaint.c
@@ -4646,9 +4646,6 @@ static int dynamicPaint_paintParticles(DynamicPaintSurface *surface,
return 1;
}
- /* begin thread safe malloc */
- BLI_threaded_malloc_begin();
-
/* only continue if particle bb is close enough to canvas bb */
if (boundsIntersectDist(&grid->grid_bounds, &part_bb, range)) {
int c_index;
@@ -4684,7 +4681,6 @@ static int dynamicPaint_paintParticles(DynamicPaintSurface *surface,
&settings);
}
}
- BLI_threaded_malloc_end();
BLI_kdtree_3d_free(tree);
return 1;
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index 543d5c8b7c7..5d2207b5b80 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -1147,7 +1147,7 @@ void testhandles_fcurve(FCurve *fcu, eBezTriple_Flag sel_flag, const bool use_ha
/* loop over beztriples */
for (a = 0, bezt = fcu->bezt; a < fcu->totvert; a++, bezt++) {
- BKE_nurb_bezt_handle_test(bezt, sel_flag, use_handle);
+ BKE_nurb_bezt_handle_test(bezt, sel_flag, use_handle, false);
}
/* recalculate handles */
diff --git a/source/blender/blenkernel/intern/fluid.c b/source/blender/blenkernel/intern/fluid.c
index fddc6b5e0ee..b75592836e0 100644
--- a/source/blender/blenkernel/intern/fluid.c
+++ b/source/blender/blenkernel/intern/fluid.c
@@ -3306,6 +3306,16 @@ static Mesh *create_liquid_geometry(FluidDomainSettings *mds, Mesh *orgmesh, Obj
/* Biggest dimension will be used for upscaling. */
float max_size = MAX3(size[0], size[1], size[2]);
+ float co_scale[3];
+ co_scale[0] = max_size / ob->scale[0];
+ co_scale[1] = max_size / ob->scale[1];
+ co_scale[2] = max_size / ob->scale[2];
+
+ float co_offset[3];
+ co_offset[0] = (mds->p0[0] + mds->p1[0]) / 2.0f;
+ co_offset[1] = (mds->p0[1] + mds->p1[1]) / 2.0f;
+ co_offset[2] = (mds->p0[2] + mds->p1[2]) / 2.0f;
+
/* Normals. */
normals = MEM_callocN(sizeof(short) * num_normals * 3, "Fluidmesh_tmp_normals");
@@ -3329,9 +3339,9 @@ static Mesh *create_liquid_geometry(FluidDomainSettings *mds, Mesh *orgmesh, Obj
mverts->co[2] *= mds->dx / mds->mesh_scale;
}
- mverts->co[0] *= max_size / fabsf(ob->scale[0]);
- mverts->co[1] *= max_size / fabsf(ob->scale[1]);
- mverts->co[2] *= max_size / fabsf(ob->scale[2]);
+ mul_v3_v3(mverts->co, co_scale);
+ add_v3_v3(mverts->co, co_offset);
+
# ifdef DEBUG_PRINT
/* Debugging: Print coordinates of vertices. */
printf("mverts->co[0]: %f, mverts->co[1]: %f, mverts->co[2]: %f\n",
@@ -3977,9 +3987,7 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *mmd,
}
}
if (!baking_data && !baking_noise && next_data && next_noise) {
- /* TODO (sebbas): Confirm if this read call is really needed or not.
- * Currently only important to load the shadow grid. */
- has_data = manta_update_smoke_structures(mds->fluid, mmd, data_frame);
+ /* Nothing to do here since we already loaded noise grids. */
}
else {
has_data = manta_read_data(mds->fluid, mmd, data_frame);
@@ -4380,8 +4388,8 @@ static void manta_smoke_calc_transparency(FluidDomainSettings *mds, ViewLayer *v
}
}
-/* get smoke velocity and density at given coordinates
- * returns fluid density or -1.0f if outside domain. */
+/* Get fluid velocity and density at given coordinates
+ * Returns fluid density or -1.0f if outside domain. */
float BKE_fluid_get_velocity_at(struct Object *ob, float position[3], float velocity[3])
{
FluidModifierData *mmd = (FluidModifierData *)BKE_modifiers_findby_type(ob, eModifierType_Fluid);
@@ -4390,16 +4398,15 @@ float BKE_fluid_get_velocity_at(struct Object *ob, float position[3], float velo
if (mmd && (mmd->type & MOD_FLUID_TYPE_DOMAIN) && mmd->domain && mmd->domain->fluid) {
FluidDomainSettings *mds = mmd->domain;
float time_mult = 25.f * DT_DEFAULT;
+ float size_mult = MAX3(mds->global_size[0], mds->global_size[1], mds->global_size[2]) /
+ mds->maxres;
float vel_mag;
- float *velX = manta_get_velocity_x(mds->fluid);
- float *velY = manta_get_velocity_y(mds->fluid);
- float *velZ = manta_get_velocity_z(mds->fluid);
float density = 0.0f, fuel = 0.0f;
float pos[3];
copy_v3_v3(pos, position);
manta_pos_to_cell(mds, pos);
- /* check if point is outside domain max bounds */
+ /* Check if position is outside domain max bounds. */
if (pos[0] < mds->res_min[0] || pos[1] < mds->res_min[1] || pos[2] < mds->res_min[2]) {
return -1.0f;
}
@@ -4412,9 +4419,8 @@ float BKE_fluid_get_velocity_at(struct Object *ob, float position[3], float velo
pos[1] = (pos[1] - mds->res_min[1]) / ((float)mds->res[1]);
pos[2] = (pos[2] - mds->res_min[2]) / ((float)mds->res[2]);
- /* check if point is outside active area */
- if (mmd->domain->type == FLUID_DOMAIN_TYPE_GAS &&
- mmd->domain->flags & FLUID_DOMAIN_USE_ADAPTIVE_DOMAIN) {
+ /* Check if position is outside active area. */
+ if (mds->type == FLUID_DOMAIN_TYPE_GAS && mds->flags & FLUID_DOMAIN_USE_ADAPTIVE_DOMAIN) {
if (pos[0] < 0.0f || pos[1] < 0.0f || pos[2] < 0.0f) {
return 0.0f;
}
@@ -4423,21 +4429,22 @@ float BKE_fluid_get_velocity_at(struct Object *ob, float position[3], float velo
}
}
- /* get interpolated velocity */
- velocity[0] = BLI_voxel_sample_trilinear(velX, mds->res, pos) * mds->global_size[0] *
- time_mult;
- velocity[1] = BLI_voxel_sample_trilinear(velY, mds->res, pos) * mds->global_size[1] *
- time_mult;
- velocity[2] = BLI_voxel_sample_trilinear(velZ, mds->res, pos) * mds->global_size[2] *
- time_mult;
+ /* Get interpolated velocity at given position. */
+ velocity[0] = BLI_voxel_sample_trilinear(manta_get_velocity_x(mds->fluid), mds->res, pos);
+ velocity[1] = BLI_voxel_sample_trilinear(manta_get_velocity_y(mds->fluid), mds->res, pos);
+ velocity[2] = BLI_voxel_sample_trilinear(manta_get_velocity_z(mds->fluid), mds->res, pos);
+
+ /* Convert simulation units to Blender units. */
+ mul_v3_fl(velocity, size_mult);
+ mul_v3_fl(velocity, time_mult);
- /* convert velocity direction to global space */
+ /* Convert velocity direction to global space. */
vel_mag = len_v3(velocity);
mul_mat3_m4_v3(mds->obmat, velocity);
normalize_v3(velocity);
mul_v3_fl(velocity, vel_mag);
- /* use max value of fuel or smoke density */
+ /* Use max value of fuel or smoke density. */
density = BLI_voxel_sample_trilinear(manta_smoke_get_density(mds->fluid), mds->res, pos);
if (manta_smoke_has_fuel(mds->fluid)) {
fuel = BLI_voxel_sample_trilinear(manta_smoke_get_fuel(mds->fluid), mds->res, pos);
@@ -4922,7 +4929,7 @@ void BKE_fluid_modifier_create_type_data(struct FluidModifierData *mmd)
/* cache options */
mmd->domain->cache_frame_start = 1;
- mmd->domain->cache_frame_end = 50;
+ mmd->domain->cache_frame_end = 250;
mmd->domain->cache_frame_pause_data = 0;
mmd->domain->cache_frame_pause_noise = 0;
mmd->domain->cache_frame_pause_mesh = 0;
diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c
index 92eb6ea03e2..54f2492af93 100644
--- a/source/blender/blenkernel/intern/font.c
+++ b/source/blender/blenkernel/intern/font.c
@@ -134,6 +134,7 @@ IDTypeInfo IDType_ID_VF = {
.copy_data = vfont_copy_data,
.free_data = vfont_free_data,
.make_local = NULL,
+ .foreach_id = NULL,
};
/***************************** VFont *******************************/
diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index 041ef0503b9..4311e425abf 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -55,6 +55,7 @@
#include "BKE_idtype.h"
#include "BKE_image.h"
#include "BKE_lib_id.h"
+#include "BKE_lib_query.h"
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_paint.h"
@@ -97,6 +98,19 @@ static void greasepencil_free_data(ID *id)
BKE_gpencil_free((bGPdata *)id, true);
}
+static void greasepencil_foreach_id(ID *id, LibraryForeachIDData *data)
+{
+ bGPdata *gpencil = (bGPdata *)id;
+ /* materials */
+ for (int i = 0; i < gpencil->totcol; i++) {
+ BKE_LIB_FOREACHID_PROCESS(data, gpencil->mat[i], IDWALK_CB_USER);
+ }
+
+ LISTBASE_FOREACH (bGPDlayer *, gplayer, &gpencil->layers) {
+ BKE_LIB_FOREACHID_PROCESS(data, gplayer->parent, IDWALK_CB_NOP);
+ }
+}
+
IDTypeInfo IDType_ID_GD = {
.id_code = ID_GD,
.id_filter = FILTER_ID_GD,
@@ -111,6 +125,7 @@ IDTypeInfo IDType_ID_GD = {
.copy_data = greasepencil_copy_data,
.free_data = greasepencil_free_data,
.make_local = NULL,
+ .foreach_id = greasepencil_foreach_id,
};
/* ************************************************** */
@@ -1748,7 +1763,18 @@ void BKE_gpencil_palette_ensure(Main *bmain, Scene *scene)
GpPaint *gp_paint = ts->gp_paint;
Paint *paint = &gp_paint->paint;
+ if (paint->palette != NULL) {
+ return;
+ }
+
paint->palette = BLI_findstring(&bmain->palettes, "Palette", offsetof(ID, name) + 2);
+ /* Try with first palette. */
+ if (bmain->palettes.first != NULL) {
+ paint->palette = bmain->palettes.first;
+ ts->gp_vertexpaint->paint.palette = paint->palette;
+ return;
+ }
+
if (paint->palette == NULL) {
paint->palette = BKE_palette_add(bmain, "Palette");
ts->gp_vertexpaint->paint.palette = paint->palette;
diff --git a/source/blender/blenkernel/intern/hair.c b/source/blender/blenkernel/intern/hair.c
index 808c0347a37..90761d24b73 100644
--- a/source/blender/blenkernel/intern/hair.c
+++ b/source/blender/blenkernel/intern/hair.c
@@ -22,6 +22,7 @@
#include "DNA_defaults.h"
#include "DNA_hair_types.h"
+#include "DNA_material_types.h"
#include "DNA_object_types.h"
#include "BLI_listbase.h"
@@ -48,50 +49,7 @@
/* Hair datablock */
-static void hair_random(Hair *hair)
-{
- const int numpoints = 8;
-
- hair->totcurve = 500;
- hair->totpoint = hair->totcurve * numpoints;
-
- CustomData_realloc(&hair->pdata, hair->totpoint);
- CustomData_realloc(&hair->cdata, hair->totcurve);
- BKE_hair_update_customdata_pointers(hair);
-
- RNG *rng = BLI_rng_new(0);
-
- for (int i = 0; i < hair->totcurve; i++) {
- HairCurve *curve = &hair->curves[i];
- curve->firstpoint = i * numpoints;
- curve->numpoints = numpoints;
-
- float theta = 2.0f * M_PI * BLI_rng_get_float(rng);
- float phi = saacosf(2.0f * BLI_rng_get_float(rng) - 1.0f);
-
- float no[3] = {sinf(theta) * sinf(phi), cosf(theta) * sinf(phi), cosf(phi)};
- normalize_v3(no);
-
- float co[3];
- copy_v3_v3(co, no);
-
- float(*curve_co)[3] = hair->co + curve->firstpoint;
- float *curve_radius = hair->radius + curve->firstpoint;
- for (int key = 0; key < numpoints; key++) {
- float t = key / (float)(numpoints - 1);
- copy_v3_v3(curve_co[key], co);
- curve_radius[key] = 0.02f * (1.0f - t);
-
- float offset[3] = {2.0f * BLI_rng_get_float(rng) - 1.0f,
- 2.0f * BLI_rng_get_float(rng) - 1.0f,
- 2.0f * BLI_rng_get_float(rng) - 1.0f};
- add_v3_v3(offset, no);
- madd_v3_v3fl(co, offset, 1.0f / numpoints);
- }
- }
-
- BLI_rng_free(rng);
-}
+static void hair_random(Hair *hair);
static void hair_init_data(ID *id)
{
@@ -111,15 +69,6 @@ static void hair_init_data(ID *id)
hair_random(hair);
}
-void *BKE_hair_add(Main *bmain, const char *name)
-{
- Hair *hair = BKE_libblock_alloc(bmain, ID_HA, name, 0);
-
- hair_init_data(&hair->id);
-
- return hair;
-}
-
static void hair_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src, const int flag)
{
Hair *hair_dst = (Hair *)id_dst;
@@ -134,18 +83,6 @@ static void hair_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src, co
hair_dst->batch_cache = NULL;
}
-Hair *BKE_hair_copy(Main *bmain, const Hair *hair)
-{
- Hair *hair_copy;
- BKE_id_copy(bmain, &hair->id, (ID **)&hair_copy);
- return hair_copy;
-}
-
-static void hair_make_local(Main *bmain, ID *id, const int flags)
-{
- BKE_lib_id_make_local_generic(bmain, id, flags);
-}
-
static void hair_free_data(ID *id)
{
Hair *hair = (Hair *)id;
@@ -159,6 +96,14 @@ static void hair_free_data(ID *id)
MEM_SAFE_FREE(hair->mat);
}
+static void hair_foreach_id(ID *id, LibraryForeachIDData *data)
+{
+ Hair *hair = (Hair *)id;
+ for (int i = 0; i < hair->totcol; i++) {
+ BKE_LIB_FOREACHID_PROCESS(data, hair->mat[i], IDWALK_CB_USER);
+ }
+}
+
IDTypeInfo IDType_ID_HA = {
.id_code = ID_HA,
.id_filter = FILTER_ID_HA,
@@ -172,9 +117,71 @@ IDTypeInfo IDType_ID_HA = {
.init_data = hair_init_data,
.copy_data = hair_copy_data,
.free_data = hair_free_data,
- .make_local = hair_make_local,
+ .make_local = NULL,
+ .foreach_id = hair_foreach_id,
};
+static void hair_random(Hair *hair)
+{
+ const int numpoints = 8;
+
+ hair->totcurve = 500;
+ hair->totpoint = hair->totcurve * numpoints;
+
+ CustomData_realloc(&hair->pdata, hair->totpoint);
+ CustomData_realloc(&hair->cdata, hair->totcurve);
+ BKE_hair_update_customdata_pointers(hair);
+
+ RNG *rng = BLI_rng_new(0);
+
+ for (int i = 0; i < hair->totcurve; i++) {
+ HairCurve *curve = &hair->curves[i];
+ curve->firstpoint = i * numpoints;
+ curve->numpoints = numpoints;
+
+ float theta = 2.0f * M_PI * BLI_rng_get_float(rng);
+ float phi = saacosf(2.0f * BLI_rng_get_float(rng) - 1.0f);
+
+ float no[3] = {sinf(theta) * sinf(phi), cosf(theta) * sinf(phi), cosf(phi)};
+ normalize_v3(no);
+
+ float co[3];
+ copy_v3_v3(co, no);
+
+ float(*curve_co)[3] = hair->co + curve->firstpoint;
+ float *curve_radius = hair->radius + curve->firstpoint;
+ for (int key = 0; key < numpoints; key++) {
+ float t = key / (float)(numpoints - 1);
+ copy_v3_v3(curve_co[key], co);
+ curve_radius[key] = 0.02f * (1.0f - t);
+
+ float offset[3] = {2.0f * BLI_rng_get_float(rng) - 1.0f,
+ 2.0f * BLI_rng_get_float(rng) - 1.0f,
+ 2.0f * BLI_rng_get_float(rng) - 1.0f};
+ add_v3_v3(offset, no);
+ madd_v3_v3fl(co, offset, 1.0f / numpoints);
+ }
+ }
+
+ BLI_rng_free(rng);
+}
+
+void *BKE_hair_add(Main *bmain, const char *name)
+{
+ Hair *hair = BKE_libblock_alloc(bmain, ID_HA, name, 0);
+
+ hair_init_data(&hair->id);
+
+ return hair;
+}
+
+Hair *BKE_hair_copy(Main *bmain, const Hair *hair)
+{
+ Hair *hair_copy;
+ BKE_id_copy(bmain, &hair->id, (ID **)&hair_copy);
+ return hair_copy;
+}
+
BoundBox *BKE_hair_boundbox_get(Object *ob)
{
BLI_assert(ob->type == OB_HAIR);
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index 56cdce05d57..b4a3f249c63 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -199,6 +199,7 @@ IDTypeInfo IDType_ID_IM = {
.copy_data = image_copy_data,
.free_data = image_free_data,
.make_local = NULL,
+ .foreach_id = NULL,
};
/* prototypes */
diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c
index 12c1cf6bafa..780c3c2f14a 100644
--- a/source/blender/blenkernel/intern/ipo.c
+++ b/source/blender/blenkernel/intern/ipo.c
@@ -123,6 +123,7 @@ IDTypeInfo IDType_ID_IP = {
.copy_data = NULL,
.free_data = ipo_free_data,
.make_local = NULL,
+ .foreach_id = NULL,
};
/* *************************************************** */
diff --git a/source/blender/blenkernel/intern/lib_query.c b/source/blender/blenkernel/intern/lib_query.c
index d922c5dd24c..015fa235a06 100644
--- a/source/blender/blenkernel/intern/lib_query.c
+++ b/source/blender/blenkernel/intern/lib_query.c
@@ -79,64 +79,12 @@
#include "BKE_node.h"
#include "BKE_particle.h"
#include "BKE_rigidbody.h"
+#include "BKE_screen.h"
#include "BKE_sequencer.h"
#include "BKE_shader_fx.h"
#include "BKE_texture.h"
#include "BKE_workspace.h"
-#define FOREACH_FINALIZE _finalize
-#define FOREACH_FINALIZE_VOID \
- if (0) { \
- goto FOREACH_FINALIZE; \
- } \
- FOREACH_FINALIZE: \
- ((void)0)
-
-#define FOREACH_CALLBACK_INVOKE_ID_PP(_data, id_pp, _cb_flag) \
- CHECK_TYPE(id_pp, ID **); \
- if (!((_data)->status & IDWALK_STOP)) { \
- const int _flag = (_data)->flag; \
- ID *old_id = *(id_pp); \
- const int callback_return = (_data)->callback(&(struct LibraryIDLinkCallbackData){ \
- .user_data = (_data)->user_data, \
- .id_owner = (_data)->owner_id, \
- .id_self = (_data)->self_id, \
- .id_pointer = id_pp, \
- .cb_flag = ((_cb_flag | (_data)->cb_flag) & ~(_data)->cb_flag_clear)}); \
- if (_flag & IDWALK_READONLY) { \
- BLI_assert(*(id_pp) == old_id); \
- } \
- if (old_id && (_flag & IDWALK_RECURSE)) { \
- if (BLI_gset_add((_data)->ids_handled, old_id)) { \
- if (!(callback_return & IDWALK_RET_STOP_RECURSION)) { \
- BLI_LINKSTACK_PUSH((_data)->ids_todo, old_id); \
- } \
- } \
- } \
- if (callback_return & IDWALK_RET_STOP_ITER) { \
- (_data)->status |= IDWALK_STOP; \
- goto FOREACH_FINALIZE; \
- } \
- } \
- else { \
- goto FOREACH_FINALIZE; \
- } \
- ((void)0)
-
-#define FOREACH_CALLBACK_INVOKE_ID(_data, id, cb_flag) \
- { \
- CHECK_TYPE_ANY(id, ID *, void *); \
- FOREACH_CALLBACK_INVOKE_ID_PP(_data, (ID **)&(id), cb_flag); \
- } \
- ((void)0)
-
-#define FOREACH_CALLBACK_INVOKE(_data, id_super, cb_flag) \
- { \
- CHECK_TYPE(&((id_super)->id), ID *); \
- FOREACH_CALLBACK_INVOKE_ID_PP(_data, (ID **)&(id_super), cb_flag); \
- } \
- ((void)0)
-
/* status */
enum {
IDWALK_STOP = 1 << 0,
@@ -199,6 +147,25 @@ bool BKE_lib_query_foreachid_process(LibraryForeachIDData *data, ID **id_pp, int
}
}
+int BKE_lib_query_foreachid_process_flags_get(LibraryForeachIDData *data)
+{
+ return data->flag;
+}
+
+int BKE_lib_query_foreachid_process_callback_flag_override(LibraryForeachIDData *data,
+ const int cb_flag,
+ const bool do_replace)
+{
+ const int cb_flag_backup = data->cb_flag;
+ if (do_replace) {
+ data->cb_flag = cb_flag;
+ }
+ else {
+ data->cb_flag |= cb_flag;
+ }
+ return cb_flag_backup;
+}
+
static void library_foreach_ID_link(Main *bmain,
ID *id_owner,
ID *id,
@@ -215,82 +182,13 @@ void BKE_lib_query_idpropertiesForeachIDLink_callback(IDProperty *id_prop, void
BKE_LIB_FOREACHID_PROCESS_ID(data, id_prop->data.pointer, IDWALK_CB_USER);
}
-static void library_foreach_rigidbodyworldSceneLooper(struct RigidBodyWorld *UNUSED(rbw),
- ID **id_pointer,
- void *user_data,
- int cb_flag)
-{
- LibraryForeachIDData *data = (LibraryForeachIDData *)user_data;
- FOREACH_CALLBACK_INVOKE_ID_PP(data, id_pointer, cb_flag);
-
- FOREACH_FINALIZE_VOID;
-}
-
-static void library_foreach_modifiersForeachIDLink(void *user_data,
- Object *UNUSED(object),
- ID **id_pointer,
- int cb_flag)
-{
- LibraryForeachIDData *data = (LibraryForeachIDData *)user_data;
- FOREACH_CALLBACK_INVOKE_ID_PP(data, id_pointer, cb_flag);
-
- FOREACH_FINALIZE_VOID;
-}
-
-static void library_foreach_gpencil_modifiersForeachIDLink(void *user_data,
- Object *UNUSED(object),
- ID **id_pointer,
- int cb_flag)
-{
- LibraryForeachIDData *data = (LibraryForeachIDData *)user_data;
- FOREACH_CALLBACK_INVOKE_ID_PP(data, id_pointer, cb_flag);
-
- FOREACH_FINALIZE_VOID;
-}
-
-static void library_foreach_shaderfxForeachIDLink(void *user_data,
- Object *UNUSED(object),
- ID **id_pointer,
- int cb_flag)
-{
- LibraryForeachIDData *data = (LibraryForeachIDData *)user_data;
- FOREACH_CALLBACK_INVOKE_ID_PP(data, id_pointer, cb_flag);
-
- FOREACH_FINALIZE_VOID;
-}
-
-static void library_foreach_constraintObjectLooper(bConstraint *UNUSED(con),
- ID **id_pointer,
- bool is_reference,
- void *user_data)
-{
- LibraryForeachIDData *data = (LibraryForeachIDData *)user_data;
- const int cb_flag = is_reference ? IDWALK_CB_USER : IDWALK_CB_NOP;
- FOREACH_CALLBACK_INVOKE_ID_PP(data, id_pointer, cb_flag);
-
- FOREACH_FINALIZE_VOID;
-}
-
-static void library_foreach_particlesystemsObjectLooper(ParticleSystem *UNUSED(psys),
- ID **id_pointer,
- void *user_data,
- int cb_flag)
-{
- LibraryForeachIDData *data = (LibraryForeachIDData *)user_data;
- FOREACH_CALLBACK_INVOKE_ID_PP(data, id_pointer, cb_flag);
-
- FOREACH_FINALIZE_VOID;
-}
-
static void library_foreach_nla_strip(LibraryForeachIDData *data, NlaStrip *strip)
{
- FOREACH_CALLBACK_INVOKE(data, strip->act, IDWALK_CB_USER);
+ BKE_LIB_FOREACHID_PROCESS(data, strip->act, IDWALK_CB_USER);
LISTBASE_FOREACH (NlaStrip *, substrip, &strip->strips) {
library_foreach_nla_strip(data, substrip);
}
-
- FOREACH_FINALIZE_VOID;
}
static void library_foreach_animationData(LibraryForeachIDData *data, AnimData *adt)
@@ -301,215 +199,20 @@ static void library_foreach_animationData(LibraryForeachIDData *data, AnimData *
LISTBASE_FOREACH (DriverVar *, dvar, &driver->variables) {
/* only used targets */
DRIVER_TARGETS_USED_LOOPER_BEGIN (dvar) {
- FOREACH_CALLBACK_INVOKE_ID(data, dtar->id, IDWALK_CB_NOP);
+ BKE_LIB_FOREACHID_PROCESS_ID(data, dtar->id, IDWALK_CB_NOP);
}
DRIVER_TARGETS_LOOPER_END;
}
}
- FOREACH_CALLBACK_INVOKE(data, adt->action, IDWALK_CB_USER);
- FOREACH_CALLBACK_INVOKE(data, adt->tmpact, IDWALK_CB_USER);
+ BKE_LIB_FOREACHID_PROCESS(data, adt->action, IDWALK_CB_USER);
+ BKE_LIB_FOREACHID_PROCESS(data, adt->tmpact, IDWALK_CB_USER);
LISTBASE_FOREACH (NlaTrack *, nla_track, &adt->nla_tracks) {
LISTBASE_FOREACH (NlaStrip *, nla_strip, &nla_track->strips) {
library_foreach_nla_strip(data, nla_strip);
}
}
-
- FOREACH_FINALIZE_VOID;
-}
-
-static void library_foreach_paint(LibraryForeachIDData *data, Paint *paint)
-{
- FOREACH_CALLBACK_INVOKE(data, paint->brush, IDWALK_CB_USER);
- for (int i = 0; i < paint->tool_slots_len; i++) {
- FOREACH_CALLBACK_INVOKE(data, paint->tool_slots[i].brush, IDWALK_CB_USER);
- }
- FOREACH_CALLBACK_INVOKE(data, paint->palette, IDWALK_CB_USER);
-
- FOREACH_FINALIZE_VOID;
-}
-
-static void library_foreach_layer_collection(LibraryForeachIDData *data, ListBase *lb)
-{
- LISTBASE_FOREACH (LayerCollection *, lc, lb) {
- /* XXX This is very weak. The whole idea of keeping pointers to private IDs is very bad
- * anyway... */
- const int cb_flag = (lc->collection != NULL &&
- (lc->collection->id.flag & LIB_EMBEDDED_DATA) != 0) ?
- IDWALK_CB_EMBEDDED :
- IDWALK_CB_NOP;
- FOREACH_CALLBACK_INVOKE(data, lc->collection, cb_flag);
- library_foreach_layer_collection(data, &lc->layer_collections);
- }
-
- FOREACH_FINALIZE_VOID;
-}
-
-/* Used by both real Collection data-blocks, and the fake horror of master collection from Scene.
- */
-static void library_foreach_collection(LibraryForeachIDData *data, Collection *collection)
-{
- LISTBASE_FOREACH (CollectionObject *, cob, &collection->gobject) {
- FOREACH_CALLBACK_INVOKE(data, cob->ob, IDWALK_CB_USER);
- }
- LISTBASE_FOREACH (CollectionChild *, child, &collection->children) {
- FOREACH_CALLBACK_INVOKE(data, child->collection, IDWALK_CB_NEVER_SELF | IDWALK_CB_USER);
- }
- LISTBASE_FOREACH (CollectionParent *, parent, &collection->parents) {
- /* XXX This is very weak. The whole idea of keeping pointers to private IDs is very bad
- * anyway... */
- const int cb_flag = ((parent->collection != NULL &&
- (parent->collection->id.flag & LIB_EMBEDDED_DATA) != 0) ?
- IDWALK_CB_EMBEDDED :
- IDWALK_CB_NOP);
- FOREACH_CALLBACK_INVOKE(
- data, parent->collection, IDWALK_CB_NEVER_SELF | IDWALK_CB_LOOPBACK | cb_flag);
- }
-
- FOREACH_FINALIZE_VOID;
-}
-
-static void library_foreach_dopesheet(LibraryForeachIDData *data, bDopeSheet *ads)
-{
- if (ads != NULL) {
- FOREACH_CALLBACK_INVOKE_ID(data, ads->source, IDWALK_CB_NOP);
- FOREACH_CALLBACK_INVOKE(data, ads->filter_grp, IDWALK_CB_NOP);
- }
-
- FOREACH_FINALIZE_VOID;
-}
-
-static void library_foreach_screen_area(LibraryForeachIDData *data, ScrArea *area)
-{
- FOREACH_CALLBACK_INVOKE(data, area->full, IDWALK_CB_NOP);
-
- LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
- switch (sl->spacetype) {
- case SPACE_VIEW3D: {
- View3D *v3d = (View3D *)sl;
-
- FOREACH_CALLBACK_INVOKE(data, v3d->camera, IDWALK_CB_NOP);
- FOREACH_CALLBACK_INVOKE(data, v3d->ob_center, IDWALK_CB_NOP);
-
- if (v3d->localvd) {
- FOREACH_CALLBACK_INVOKE(data, v3d->localvd->camera, IDWALK_CB_NOP);
- }
- break;
- }
- case SPACE_GRAPH: {
- SpaceGraph *sipo = (SpaceGraph *)sl;
-
- library_foreach_dopesheet(data, sipo->ads);
- break;
- }
- case SPACE_PROPERTIES: {
- SpaceProperties *sbuts = (SpaceProperties *)sl;
-
- FOREACH_CALLBACK_INVOKE_ID(data, sbuts->pinid, IDWALK_CB_NOP);
- break;
- }
- case SPACE_FILE:
- break;
- case SPACE_ACTION: {
- SpaceAction *saction = (SpaceAction *)sl;
-
- library_foreach_dopesheet(data, &saction->ads);
- FOREACH_CALLBACK_INVOKE(data, saction->action, IDWALK_CB_NOP);
- break;
- }
- case SPACE_IMAGE: {
- SpaceImage *sima = (SpaceImage *)sl;
-
- FOREACH_CALLBACK_INVOKE(data, sima->image, IDWALK_CB_USER_ONE);
- FOREACH_CALLBACK_INVOKE(data, sima->mask_info.mask, IDWALK_CB_USER_ONE);
- FOREACH_CALLBACK_INVOKE(data, sima->gpd, IDWALK_CB_USER);
- break;
- }
- case SPACE_SEQ: {
- SpaceSeq *sseq = (SpaceSeq *)sl;
-
- FOREACH_CALLBACK_INVOKE(data, sseq->gpd, IDWALK_CB_USER);
- break;
- }
- case SPACE_NLA: {
- SpaceNla *snla = (SpaceNla *)sl;
-
- library_foreach_dopesheet(data, snla->ads);
- break;
- }
- case SPACE_TEXT: {
- SpaceText *st = (SpaceText *)sl;
-
- FOREACH_CALLBACK_INVOKE(data, st->text, IDWALK_CB_NOP);
- break;
- }
- case SPACE_SCRIPT: {
- SpaceScript *scpt = (SpaceScript *)sl;
-
- FOREACH_CALLBACK_INVOKE(data, scpt->script, IDWALK_CB_NOP);
- break;
- }
- case SPACE_OUTLINER: {
- SpaceOutliner *so = (SpaceOutliner *)sl;
-
- FOREACH_CALLBACK_INVOKE_ID(data, so->search_tse.id, IDWALK_CB_NOP);
-
- if (so->treestore != NULL) {
- TreeStoreElem *tselem;
- BLI_mempool_iter iter;
-
- BLI_mempool_iternew(so->treestore, &iter);
- while ((tselem = BLI_mempool_iterstep(&iter))) {
- FOREACH_CALLBACK_INVOKE_ID(data, tselem->id, IDWALK_CB_NOP);
- }
- }
- break;
- }
- case SPACE_NODE: {
- SpaceNode *snode = (SpaceNode *)sl;
-
- const bool is_private_nodetree = snode->id != NULL &&
- ntreeFromID(snode->id) == snode->nodetree;
-
- FOREACH_CALLBACK_INVOKE_ID(data, snode->id, IDWALK_CB_NOP);
- FOREACH_CALLBACK_INVOKE_ID(data, snode->from, IDWALK_CB_NOP);
-
- FOREACH_CALLBACK_INVOKE(
- data, snode->nodetree, is_private_nodetree ? IDWALK_CB_EMBEDDED : IDWALK_CB_USER_ONE);
-
- LISTBASE_FOREACH (bNodeTreePath *, path, &snode->treepath) {
- if (path == snode->treepath.first) {
- /* first nodetree in path is same as snode->nodetree */
- FOREACH_CALLBACK_INVOKE(data,
- path->nodetree,
- is_private_nodetree ? IDWALK_CB_EMBEDDED : IDWALK_CB_USER_ONE);
- }
- else {
- FOREACH_CALLBACK_INVOKE(data, path->nodetree, IDWALK_CB_USER_ONE);
- }
-
- if (path->nodetree == NULL) {
- break;
- }
- }
-
- FOREACH_CALLBACK_INVOKE(data, snode->edittree, IDWALK_CB_NOP);
- break;
- }
- case SPACE_CLIP: {
- SpaceClip *sclip = (SpaceClip *)sl;
-
- FOREACH_CALLBACK_INVOKE(data, sclip->clip, IDWALK_CB_USER_ONE);
- FOREACH_CALLBACK_INVOKE(data, sclip->mask_info.mask, IDWALK_CB_USER_ONE);
- break;
- }
- default:
- break;
- }
- }
-
- FOREACH_FINALIZE_VOID;
}
bool BKE_library_foreach_ID_embedded(LibraryForeachIDData *data, ID **id_pp)
@@ -556,7 +259,6 @@ static void library_foreach_ID_link(Main *bmain,
LibraryForeachIDData *inherit_data)
{
LibraryForeachIDData data = {.bmain = bmain};
- int i;
BLI_assert(inherit_data == NULL || data.bmain == inherit_data->bmain);
@@ -577,10 +279,11 @@ static void library_foreach_ID_link(Main *bmain,
data.callback = callback;
data.user_data = user_data;
-#define CALLBACK_INVOKE_ID(check_id, cb_flag) FOREACH_CALLBACK_INVOKE_ID(&data, check_id, cb_flag)
+#define CALLBACK_INVOKE_ID(check_id, cb_flag) \
+ BKE_LIB_FOREACHID_PROCESS_ID(&data, check_id, cb_flag)
#define CALLBACK_INVOKE(check_id_super, cb_flag) \
- FOREACH_CALLBACK_INVOKE(&data, check_id_super, cb_flag)
+ BKE_LIB_FOREACHID_PROCESS(&data, check_id_super, cb_flag)
for (; id != NULL; id = (flag & IDWALK_RECURSE) ? BLI_LINKSTACK_POP(data.ids_todo) : NULL) {
data.self_id = id;
@@ -616,7 +319,7 @@ static void library_foreach_ID_link(Main *bmain,
* especially if/when it starts modifying Main database). */
MainIDRelationsEntry *entry = BLI_ghash_lookup(bmain->relations->id_user_to_used, id);
for (; entry != NULL; entry = entry->next) {
- FOREACH_CALLBACK_INVOKE_ID_PP(&data, entry->id_pointer, entry->usage_flag);
+ BKE_lib_query_foreachid_process(&data, entry->id_pointer, entry->usage_flag);
}
continue;
}
@@ -642,569 +345,15 @@ static void library_foreach_ID_link(Main *bmain,
}
const IDTypeInfo *id_type = BKE_idtype_get_info_from_id(id);
-
- /* Note: this is temp logic until all code has been ported to IDTypeInfo... */
if (id_type->foreach_id != NULL) {
id_type->foreach_id(id, &data);
if (data.status & IDWALK_STOP) {
break;
}
- else {
- continue;
- }
- }
-
- switch ((ID_Type)GS(id->name)) {
- case ID_LI: {
- BLI_assert(0);
- break;
- }
- case ID_SCE: {
- Scene *scene = (Scene *)id;
- ToolSettings *toolsett = scene->toolsettings;
-
- CALLBACK_INVOKE(scene->camera, IDWALK_CB_NOP);
- CALLBACK_INVOKE(scene->world, IDWALK_CB_USER);
- CALLBACK_INVOKE(scene->set, IDWALK_CB_NEVER_SELF);
- CALLBACK_INVOKE(scene->clip, IDWALK_CB_USER);
- CALLBACK_INVOKE(scene->gpd, IDWALK_CB_USER);
- CALLBACK_INVOKE(scene->r.bake.cage_object, IDWALK_CB_NOP);
- if (scene->nodetree) {
- /* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
- BKE_library_foreach_ID_embedded(&data, (ID **)&scene->nodetree);
- }
- if (scene->ed) {
- Sequence *seq;
- SEQP_BEGIN (scene->ed, seq) {
- CALLBACK_INVOKE(seq->scene, IDWALK_CB_NEVER_SELF);
- CALLBACK_INVOKE(seq->scene_camera, IDWALK_CB_NOP);
- CALLBACK_INVOKE(seq->clip, IDWALK_CB_USER);
- CALLBACK_INVOKE(seq->mask, IDWALK_CB_USER);
- CALLBACK_INVOKE(seq->sound, IDWALK_CB_USER);
- IDP_foreach_property(seq->prop,
- IDP_TYPE_FILTER_ID,
- BKE_lib_query_idpropertiesForeachIDLink_callback,
- &data);
- LISTBASE_FOREACH (SequenceModifierData *, smd, &seq->modifiers) {
- CALLBACK_INVOKE(smd->mask_id, IDWALK_CB_USER);
- }
-
- if (seq->type == SEQ_TYPE_TEXT && seq->effectdata) {
- TextVars *text_data = seq->effectdata;
- CALLBACK_INVOKE(text_data->text_font, IDWALK_CB_USER);
- }
- }
- SEQ_END;
- }
-
- /* This pointer can be NULL during old files reading, better be safe than sorry. */
- if (scene->master_collection != NULL) {
- library_foreach_collection(&data, scene->master_collection);
- }
-
- LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
- CALLBACK_INVOKE(view_layer->mat_override, IDWALK_CB_USER);
-
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
- CALLBACK_INVOKE(base->object, IDWALK_CB_NOP);
- }
-
- library_foreach_layer_collection(&data, &view_layer->layer_collections);
-
- LISTBASE_FOREACH (FreestyleModuleConfig *, fmc, &view_layer->freestyle_config.modules) {
- if (fmc->script) {
- CALLBACK_INVOKE(fmc->script, IDWALK_CB_NOP);
- }
- }
-
- LISTBASE_FOREACH (FreestyleLineSet *, fls, &view_layer->freestyle_config.linesets) {
- if (fls->group) {
- CALLBACK_INVOKE(fls->group, IDWALK_CB_USER);
- }
-
- if (fls->linestyle) {
- CALLBACK_INVOKE(fls->linestyle, IDWALK_CB_USER);
- }
- }
- }
-
- LISTBASE_FOREACH (TimeMarker *, marker, &scene->markers) {
- CALLBACK_INVOKE(marker->camera, IDWALK_CB_NOP);
- }
-
- if (toolsett) {
- CALLBACK_INVOKE(toolsett->particle.scene, IDWALK_CB_NOP);
- CALLBACK_INVOKE(toolsett->particle.object, IDWALK_CB_NOP);
- CALLBACK_INVOKE(toolsett->particle.shape_object, IDWALK_CB_NOP);
-
- library_foreach_paint(&data, &toolsett->imapaint.paint);
- CALLBACK_INVOKE(toolsett->imapaint.stencil, IDWALK_CB_USER);
- CALLBACK_INVOKE(toolsett->imapaint.clone, IDWALK_CB_USER);
- CALLBACK_INVOKE(toolsett->imapaint.canvas, IDWALK_CB_USER);
-
- if (toolsett->vpaint) {
- library_foreach_paint(&data, &toolsett->vpaint->paint);
- }
- if (toolsett->wpaint) {
- library_foreach_paint(&data, &toolsett->wpaint->paint);
- }
- if (toolsett->sculpt) {
- library_foreach_paint(&data, &toolsett->sculpt->paint);
- CALLBACK_INVOKE(toolsett->sculpt->gravity_object, IDWALK_CB_NOP);
- }
- if (toolsett->uvsculpt) {
- library_foreach_paint(&data, &toolsett->uvsculpt->paint);
- }
- if (toolsett->gp_paint) {
- library_foreach_paint(&data, &toolsett->gp_paint->paint);
- }
- if (toolsett->gp_vertexpaint) {
- library_foreach_paint(&data, &toolsett->gp_vertexpaint->paint);
- }
- if (toolsett->gp_sculptpaint) {
- library_foreach_paint(&data, &toolsett->gp_sculptpaint->paint);
- }
- if (toolsett->gp_weightpaint) {
- library_foreach_paint(&data, &toolsett->gp_weightpaint->paint);
- }
-
- CALLBACK_INVOKE(toolsett->gp_sculpt.guide.reference_object, IDWALK_CB_NOP);
- }
-
- if (scene->rigidbody_world) {
- BKE_rigidbody_world_id_loop(
- scene->rigidbody_world, library_foreach_rigidbodyworldSceneLooper, &data);
- }
-
- break;
- }
-
- case ID_OB: {
- Object *object = (Object *)id;
-
- /* Object is special, proxies make things hard... */
- const int data_cb_flag = data.cb_flag;
- const int proxy_cb_flag = ((data.flag & IDWALK_NO_INDIRECT_PROXY_DATA_USAGE) == 0 &&
- (object->proxy || object->proxy_group)) ?
- IDWALK_CB_INDIRECT_USAGE :
- 0;
-
- /* object data special case */
- data.cb_flag |= proxy_cb_flag;
- if (object->type == OB_EMPTY) {
- /* empty can have NULL or Image */
- CALLBACK_INVOKE_ID(object->data, IDWALK_CB_USER);
- }
- else {
- /* when set, this can't be NULL */
- if (object->data) {
- CALLBACK_INVOKE_ID(object->data, IDWALK_CB_USER | IDWALK_CB_NEVER_NULL);
- }
- }
- data.cb_flag = data_cb_flag;
-
- CALLBACK_INVOKE(object->parent, IDWALK_CB_NEVER_SELF);
- CALLBACK_INVOKE(object->track, IDWALK_CB_NEVER_SELF);
- /* object->proxy is refcounted, but not object->proxy_group... *sigh* */
- CALLBACK_INVOKE(object->proxy, IDWALK_CB_USER | IDWALK_CB_NEVER_SELF);
- CALLBACK_INVOKE(object->proxy_group, IDWALK_CB_NOP);
-
- /* Special case!
- * Since this field is set/owned by 'user' of this ID (and not ID itself),
- * it is only indirect usage if proxy object is linked... Twisted. */
- if (object->proxy_from) {
- data.cb_flag = ID_IS_LINKED(object->proxy_from) ? IDWALK_CB_INDIRECT_USAGE : 0;
- }
- CALLBACK_INVOKE(object->proxy_from, IDWALK_CB_LOOPBACK | IDWALK_CB_NEVER_SELF);
- data.cb_flag = data_cb_flag;
-
- CALLBACK_INVOKE(object->poselib, IDWALK_CB_USER);
-
- data.cb_flag |= proxy_cb_flag;
- for (i = 0; i < object->totcol; i++) {
- CALLBACK_INVOKE(object->mat[i], IDWALK_CB_USER);
- }
- data.cb_flag = data_cb_flag;
-
- /* Note that ob->gpd is deprecated, so no need to handle it here. */
- CALLBACK_INVOKE(object->instance_collection, IDWALK_CB_USER);
-
- if (object->pd) {
- CALLBACK_INVOKE(object->pd->tex, IDWALK_CB_USER);
- CALLBACK_INVOKE(object->pd->f_source, IDWALK_CB_NOP);
- }
- /* Note that ob->effect is deprecated, so no need to handle it here. */
-
- if (object->pose) {
- data.cb_flag |= proxy_cb_flag;
- LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
- IDP_foreach_property(pchan->prop,
- IDP_TYPE_FILTER_ID,
- BKE_lib_query_idpropertiesForeachIDLink_callback,
- &data);
- CALLBACK_INVOKE(pchan->custom, IDWALK_CB_USER);
- BKE_constraints_id_loop(
- &pchan->constraints, library_foreach_constraintObjectLooper, &data);
- }
- data.cb_flag = data_cb_flag;
- }
-
- if (object->rigidbody_constraint) {
- CALLBACK_INVOKE(object->rigidbody_constraint->ob1, IDWALK_CB_NEVER_SELF);
- CALLBACK_INVOKE(object->rigidbody_constraint->ob2, IDWALK_CB_NEVER_SELF);
- }
-
- if (object->lodlevels.first) {
- LISTBASE_FOREACH (LodLevel *, level, &object->lodlevels) {
- CALLBACK_INVOKE(level->source, IDWALK_CB_NEVER_SELF);
- }
- }
-
- BKE_modifiers_foreach_ID_link(object, library_foreach_modifiersForeachIDLink, &data);
- BKE_gpencil_modifiers_foreach_ID_link(
- object, library_foreach_gpencil_modifiersForeachIDLink, &data);
- BKE_constraints_id_loop(
- &object->constraints, library_foreach_constraintObjectLooper, &data);
- BKE_shaderfx_foreach_ID_link(object, library_foreach_shaderfxForeachIDLink, &data);
-
- LISTBASE_FOREACH (ParticleSystem *, psys, &object->particlesystem) {
- BKE_particlesystem_id_loop(psys, library_foreach_particlesystemsObjectLooper, &data);
- }
-
- if (object->soft) {
- CALLBACK_INVOKE(object->soft->collision_group, IDWALK_CB_NOP);
-
- if (object->soft->effector_weights) {
- CALLBACK_INVOKE(object->soft->effector_weights->group, IDWALK_CB_NOP);
- }
- }
- break;
- }
-
- case ID_AR: {
- BLI_assert(0);
- break;
- }
-
- case ID_ME: {
- BLI_assert(0);
- break;
- }
-
- case ID_CU: {
- BLI_assert(0);
- break;
- }
-
- case ID_MB: {
- BLI_assert(0);
- break;
- }
-
- case ID_MA: {
- BLI_assert(0);
- break;
- }
-
- case ID_TE: {
- BLI_assert(0);
- break;
- }
-
- case ID_LT: {
- BLI_assert(0);
- break;
- }
-
- case ID_LA: {
- break;
- }
-
- case ID_CA: {
- BLI_assert(0);
- break;
- }
-
- case ID_KE: {
- break;
- }
-
- case ID_WO: {
- BLI_assert(0);
- break;
- }
-
- case ID_SPK: {
- BLI_assert(0);
- break;
- }
-
- case ID_LP: {
- BLI_assert(0);
- break;
- }
-
- case ID_GR: {
- Collection *collection = (Collection *)id;
- library_foreach_collection(&data, collection);
- break;
- }
-
- case ID_NT: {
- BLI_assert(0);
- break;
- }
-
- case ID_BR: {
- BLI_assert(0);
- break;
- }
-
- case ID_PA: {
- ParticleSettings *psett = (ParticleSettings *)id;
- CALLBACK_INVOKE(psett->instance_collection, IDWALK_CB_USER);
- CALLBACK_INVOKE(psett->instance_object, IDWALK_CB_NOP);
- CALLBACK_INVOKE(psett->bb_ob, IDWALK_CB_NOP);
- CALLBACK_INVOKE(psett->collision_group, IDWALK_CB_NOP);
-
- for (i = 0; i < MAX_MTEX; i++) {
- if (psett->mtex[i]) {
- BKE_texture_mtex_foreach_id(&data, psett->mtex[i]);
- }
- }
-
- if (psett->effector_weights) {
- CALLBACK_INVOKE(psett->effector_weights->group, IDWALK_CB_NOP);
- }
-
- if (psett->pd) {
- CALLBACK_INVOKE(psett->pd->tex, IDWALK_CB_USER);
- CALLBACK_INVOKE(psett->pd->f_source, IDWALK_CB_NOP);
- }
- if (psett->pd2) {
- CALLBACK_INVOKE(psett->pd2->tex, IDWALK_CB_USER);
- CALLBACK_INVOKE(psett->pd2->f_source, IDWALK_CB_NOP);
- }
-
- if (psett->boids) {
- LISTBASE_FOREACH (BoidState *, state, &psett->boids->states) {
- LISTBASE_FOREACH (BoidRule *, rule, &state->rules) {
- if (rule->type == eBoidRuleType_Avoid) {
- BoidRuleGoalAvoid *gabr = (BoidRuleGoalAvoid *)rule;
- CALLBACK_INVOKE(gabr->ob, IDWALK_CB_NOP);
- }
- else if (rule->type == eBoidRuleType_FollowLeader) {
- BoidRuleFollowLeader *flbr = (BoidRuleFollowLeader *)rule;
- CALLBACK_INVOKE(flbr->ob, IDWALK_CB_NOP);
- }
- }
- }
- }
-
- LISTBASE_FOREACH (ParticleDupliWeight *, dw, &psett->instance_weights) {
- CALLBACK_INVOKE(dw->ob, IDWALK_CB_NOP);
- }
- break;
- }
-
- case ID_MC: {
- MovieClip *clip = (MovieClip *)id;
- MovieTracking *tracking = &clip->tracking;
-
- CALLBACK_INVOKE(clip->gpd, IDWALK_CB_USER);
-
- LISTBASE_FOREACH (MovieTrackingTrack *, track, &tracking->tracks) {
- CALLBACK_INVOKE(track->gpd, IDWALK_CB_USER);
- }
- LISTBASE_FOREACH (MovieTrackingObject *, object, &tracking->objects) {
- LISTBASE_FOREACH (MovieTrackingTrack *, track, &object->tracks) {
- CALLBACK_INVOKE(track->gpd, IDWALK_CB_USER);
- }
- }
-
- LISTBASE_FOREACH (MovieTrackingPlaneTrack *, plane_track, &tracking->plane_tracks) {
- CALLBACK_INVOKE(plane_track->image, IDWALK_CB_USER);
- }
- break;
- }
-
- case ID_MSK: {
- Mask *mask = (Mask *)id;
-
- LISTBASE_FOREACH (MaskLayer *, mask_layer, &mask->masklayers) {
- LISTBASE_FOREACH (MaskSpline *, mask_spline, &mask_layer->splines) {
- for (i = 0; i < mask_spline->tot_point; i++) {
- MaskSplinePoint *point = &mask_spline->points[i];
- CALLBACK_INVOKE_ID(point->parent.id, IDWALK_CB_USER);
- }
- }
- }
- break;
- }
-
- case ID_LS: {
- FreestyleLineStyle *linestyle = (FreestyleLineStyle *)id;
-
- for (i = 0; i < MAX_MTEX; i++) {
- if (linestyle->mtex[i]) {
- BKE_texture_mtex_foreach_id(&data, linestyle->mtex[i]);
- }
- }
- if (linestyle->nodetree) {
- /* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
- BKE_library_foreach_ID_embedded(&data, (ID **)&linestyle->nodetree);
- }
-
- LISTBASE_FOREACH (LineStyleModifier *, lsm, &linestyle->color_modifiers) {
- if (lsm->type == LS_MODIFIER_DISTANCE_FROM_OBJECT) {
- LineStyleColorModifier_DistanceFromObject *p =
- (LineStyleColorModifier_DistanceFromObject *)lsm;
- if (p->target) {
- CALLBACK_INVOKE(p->target, IDWALK_CB_NOP);
- }
- }
- }
- LISTBASE_FOREACH (LineStyleModifier *, lsm, &linestyle->alpha_modifiers) {
- if (lsm->type == LS_MODIFIER_DISTANCE_FROM_OBJECT) {
- LineStyleAlphaModifier_DistanceFromObject *p =
- (LineStyleAlphaModifier_DistanceFromObject *)lsm;
- if (p->target) {
- CALLBACK_INVOKE(p->target, IDWALK_CB_NOP);
- }
- }
- }
- LISTBASE_FOREACH (LineStyleModifier *, lsm, &linestyle->thickness_modifiers) {
- if (lsm->type == LS_MODIFIER_DISTANCE_FROM_OBJECT) {
- LineStyleThicknessModifier_DistanceFromObject *p =
- (LineStyleThicknessModifier_DistanceFromObject *)lsm;
- if (p->target) {
- CALLBACK_INVOKE(p->target, IDWALK_CB_NOP);
- }
- }
- }
- break;
- }
-
- case ID_AC: {
- bAction *act = (bAction *)id;
-
- LISTBASE_FOREACH (TimeMarker *, marker, &act->markers) {
- CALLBACK_INVOKE(marker->camera, IDWALK_CB_NOP);
- }
- break;
- }
-
- case ID_WM: {
- wmWindowManager *wm = (wmWindowManager *)id;
-
- LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
- CALLBACK_INVOKE(win->scene, IDWALK_CB_USER_ONE);
-
- /* This pointer can be NULL during old files reading, better be safe than sorry. */
- if (win->workspace_hook != NULL) {
- ID *workspace = (ID *)BKE_workspace_active_get(win->workspace_hook);
- CALLBACK_INVOKE_ID(workspace, IDWALK_CB_NOP);
- /* allow callback to set a different workspace */
- BKE_workspace_active_set(win->workspace_hook, (WorkSpace *)workspace);
- }
- if (data.flag & IDWALK_INCLUDE_UI) {
- LISTBASE_FOREACH (ScrArea *, area, &win->global_areas.areabase) {
- library_foreach_screen_area(&data, area);
- }
- }
- }
- break;
- }
-
- case ID_WS: {
- WorkSpace *workspace = (WorkSpace *)id;
- ListBase *layouts = BKE_workspace_layouts_get(workspace);
-
- LISTBASE_FOREACH (WorkSpaceLayout *, layout, layouts) {
- bScreen *screen = BKE_workspace_layout_screen_get(layout);
-
- /* CALLBACK_INVOKE expects an actual pointer, not a variable holding the pointer.
- * However we can't access layout->screen here
- * since we are outside the workspace project. */
- CALLBACK_INVOKE(screen, IDWALK_CB_USER);
- /* allow callback to set a different screen */
- BKE_workspace_layout_screen_set(layout, screen);
- }
- break;
- }
-
- case ID_GD: {
- bGPdata *gpencil = (bGPdata *)id;
- /* materials */
- for (i = 0; i < gpencil->totcol; i++) {
- CALLBACK_INVOKE(gpencil->mat[i], IDWALK_CB_USER);
- }
-
- LISTBASE_FOREACH (bGPDlayer *, gplayer, &gpencil->layers) {
- CALLBACK_INVOKE(gplayer->parent, IDWALK_CB_NOP);
- }
-
- break;
- }
- case ID_HA: {
- Hair *hair = (Hair *)id;
- for (i = 0; i < hair->totcol; i++) {
- CALLBACK_INVOKE(hair->mat[i], IDWALK_CB_USER);
- }
- break;
- }
- case ID_PT: {
- PointCloud *pointcloud = (PointCloud *)id;
- for (i = 0; i < pointcloud->totcol; i++) {
- CALLBACK_INVOKE(pointcloud->mat[i], IDWALK_CB_USER);
- }
- break;
- }
- case ID_VO: {
- Volume *volume = (Volume *)id;
- for (i = 0; i < volume->totcol; i++) {
- CALLBACK_INVOKE(volume->mat[i], IDWALK_CB_USER);
- }
- break;
- }
-
- case ID_SCR: {
- if (data.flag & IDWALK_INCLUDE_UI) {
- bScreen *screen = (bScreen *)id;
-
- LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
- library_foreach_screen_area(&data, area);
- }
- }
- break;
- }
- case ID_SIM: {
- Simulation *simulation = (Simulation *)id;
- if (simulation->nodetree) {
- /* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
- BKE_library_foreach_ID_embedded(&data, (ID **)&simulation->nodetree);
- }
- break;
- }
-
- /* Nothing needed for those... */
- case ID_IM:
- case ID_VF:
- case ID_TXT:
- case ID_SO:
- case ID_PAL:
- case ID_PC:
- case ID_CF:
- break;
-
- /* Deprecated. */
- case ID_IP:
- break;
}
}
-FOREACH_FINALIZE:
if (data.ids_handled) {
BLI_gset_free(data.ids_handled, NULL);
BLI_LINKSTACK_FREE(data.ids_todo);
@@ -1214,9 +363,6 @@ FOREACH_FINALIZE:
#undef CALLBACK_INVOKE
}
-#undef FOREACH_CALLBACK_INVOKE_ID
-#undef FOREACH_CALLBACK_INVOKE
-
/**
* Loop over all of the ID's this data-block links to.
*/
diff --git a/source/blender/blenkernel/intern/light.c b/source/blender/blenkernel/intern/light.c
index 9dc338ce580..aa1005c663f 100644
--- a/source/blender/blenkernel/intern/light.c
+++ b/source/blender/blenkernel/intern/light.c
@@ -48,6 +48,8 @@
#include "BLT_translation.h"
+#include "DEG_depsgraph.h"
+
static void light_init_data(ID *id)
{
Light *la = (Light *)id;
@@ -178,3 +180,8 @@ Light *BKE_light_localize(Light *la)
return lan;
}
+
+void BKE_light_eval(struct Depsgraph *depsgraph, Light *la)
+{
+ DEG_debug_print_eval(depsgraph, __func__, la->id.name, la);
+}
diff --git a/source/blender/blenkernel/intern/linestyle.c b/source/blender/blenkernel/intern/linestyle.c
index 0401ae48b5c..a389af5c47f 100644
--- a/source/blender/blenkernel/intern/linestyle.c
+++ b/source/blender/blenkernel/intern/linestyle.c
@@ -45,9 +45,11 @@
#include "BKE_freestyle.h"
#include "BKE_idtype.h"
#include "BKE_lib_id.h"
+#include "BKE_lib_query.h"
#include "BKE_linestyle.h"
#include "BKE_main.h"
#include "BKE_node.h"
+#include "BKE_texture.h"
static void linestyle_init_data(ID *id)
{
@@ -144,6 +146,49 @@ static void linestyle_free_data(ID *id)
}
}
+static void linestyle_foreach_id(ID *id, LibraryForeachIDData *data)
+{
+ FreestyleLineStyle *linestyle = (FreestyleLineStyle *)id;
+
+ for (int i = 0; i < MAX_MTEX; i++) {
+ if (linestyle->mtex[i]) {
+ BKE_texture_mtex_foreach_id(data, linestyle->mtex[i]);
+ }
+ }
+ if (linestyle->nodetree) {
+ /* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
+ BKE_library_foreach_ID_embedded(data, (ID **)&linestyle->nodetree);
+ }
+
+ LISTBASE_FOREACH (LineStyleModifier *, lsm, &linestyle->color_modifiers) {
+ if (lsm->type == LS_MODIFIER_DISTANCE_FROM_OBJECT) {
+ LineStyleColorModifier_DistanceFromObject *p = (LineStyleColorModifier_DistanceFromObject *)
+ lsm;
+ if (p->target) {
+ BKE_LIB_FOREACHID_PROCESS(data, p->target, IDWALK_CB_NOP);
+ }
+ }
+ }
+ LISTBASE_FOREACH (LineStyleModifier *, lsm, &linestyle->alpha_modifiers) {
+ if (lsm->type == LS_MODIFIER_DISTANCE_FROM_OBJECT) {
+ LineStyleAlphaModifier_DistanceFromObject *p = (LineStyleAlphaModifier_DistanceFromObject *)
+ lsm;
+ if (p->target) {
+ BKE_LIB_FOREACHID_PROCESS(data, p->target, IDWALK_CB_NOP);
+ }
+ }
+ }
+ LISTBASE_FOREACH (LineStyleModifier *, lsm, &linestyle->thickness_modifiers) {
+ if (lsm->type == LS_MODIFIER_DISTANCE_FROM_OBJECT) {
+ LineStyleThicknessModifier_DistanceFromObject *p =
+ (LineStyleThicknessModifier_DistanceFromObject *)lsm;
+ if (p->target) {
+ BKE_LIB_FOREACHID_PROCESS(data, p->target, IDWALK_CB_NOP);
+ }
+ }
+ }
+}
+
IDTypeInfo IDType_ID_LS = {
.id_code = ID_LS,
.id_filter = FILTER_ID_LS,
@@ -158,6 +203,7 @@ IDTypeInfo IDType_ID_LS = {
.copy_data = linestyle_copy_data,
.free_data = linestyle_free_data,
.make_local = NULL,
+ .foreach_id = linestyle_foreach_id,
};
static const char *modifier_name[LS_MODIFIER_NUM] = {
diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c
index 6c835dc5fb2..49c909850de 100644
--- a/source/blender/blenkernel/intern/mask.c
+++ b/source/blender/blenkernel/intern/mask.c
@@ -45,6 +45,7 @@
#include "BKE_image.h"
#include "BKE_lib_id.h"
+#include "BKE_lib_query.h"
#include "BKE_main.h"
#include "BKE_mask.h"
#include "BKE_movieclip.h"
@@ -79,6 +80,20 @@ static void mask_free_data(ID *id)
BKE_mask_layer_free_list(&mask->masklayers);
}
+static void mask_foreach_id(ID *id, LibraryForeachIDData *data)
+{
+ Mask *mask = (Mask *)id;
+
+ LISTBASE_FOREACH (MaskLayer *, mask_layer, &mask->masklayers) {
+ LISTBASE_FOREACH (MaskSpline *, mask_spline, &mask_layer->splines) {
+ for (int i = 0; i < mask_spline->tot_point; i++) {
+ MaskSplinePoint *point = &mask_spline->points[i];
+ BKE_LIB_FOREACHID_PROCESS_ID(data, point->parent.id, IDWALK_CB_USER);
+ }
+ }
+ }
+}
+
IDTypeInfo IDType_ID_MSK = {
.id_code = ID_MSK,
.id_filter = FILTER_ID_MSK,
@@ -93,6 +108,7 @@ IDTypeInfo IDType_ID_MSK = {
.copy_data = mask_copy_data,
.free_data = mask_free_data,
.make_local = NULL,
+ .foreach_id = mask_foreach_id,
};
static struct {
diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c
index 4c7b791f103..fe7c2055aef 100644
--- a/source/blender/blenkernel/intern/movieclip.c
+++ b/source/blender/blenkernel/intern/movieclip.c
@@ -36,6 +36,7 @@
#include "MEM_guardedalloc.h"
#include "DNA_constraint_types.h"
+#include "DNA_gpencil_types.h"
#include "DNA_movieclip_types.h"
#include "DNA_node_types.h"
#include "DNA_object_types.h"
@@ -58,6 +59,7 @@
#include "BKE_idtype.h"
#include "BKE_image.h" /* openanim */
#include "BKE_lib_id.h"
+#include "BKE_lib_query.h"
#include "BKE_main.h"
#include "BKE_movieclip.h"
#include "BKE_node.h"
@@ -106,6 +108,27 @@ static void movie_clip_free_data(ID *id)
BKE_tracking_free(&movie_clip->tracking);
}
+static void movie_clip_foreach_id(ID *id, LibraryForeachIDData *data)
+{
+ MovieClip *movie_clip = (MovieClip *)id;
+ MovieTracking *tracking = &movie_clip->tracking;
+
+ BKE_LIB_FOREACHID_PROCESS(data, movie_clip->gpd, IDWALK_CB_USER);
+
+ LISTBASE_FOREACH (MovieTrackingTrack *, track, &tracking->tracks) {
+ BKE_LIB_FOREACHID_PROCESS(data, track->gpd, IDWALK_CB_USER);
+ }
+ LISTBASE_FOREACH (MovieTrackingObject *, object, &tracking->objects) {
+ LISTBASE_FOREACH (MovieTrackingTrack *, track, &object->tracks) {
+ BKE_LIB_FOREACHID_PROCESS(data, track->gpd, IDWALK_CB_USER);
+ }
+ }
+
+ LISTBASE_FOREACH (MovieTrackingPlaneTrack *, plane_track, &tracking->plane_tracks) {
+ BKE_LIB_FOREACHID_PROCESS(data, plane_track->image, IDWALK_CB_USER);
+ }
+}
+
IDTypeInfo IDType_ID_MC = {
.id_code = ID_MC,
.id_filter = FILTER_ID_MC,
@@ -120,6 +143,7 @@ IDTypeInfo IDType_ID_MC = {
.copy_data = movie_clip_copy_data,
.free_data = movie_clip_free_data,
.make_local = NULL,
+ .foreach_id = movie_clip_foreach_id,
};
/*********************** movieclip buffer loaders *************************/
diff --git a/source/blender/blenkernel/intern/multires_reshape.c b/source/blender/blenkernel/intern/multires_reshape.c
index e59b19638f8..64cc9130e25 100644
--- a/source/blender/blenkernel/intern/multires_reshape.c
+++ b/source/blender/blenkernel/intern/multires_reshape.c
@@ -197,7 +197,16 @@ void multiresModifier_subdivide_to_level(struct Object *object,
if (!has_mdisps) {
CustomData_add_layer(&coarse_mesh->ldata, CD_MDISPS, CD_CALLOC, NULL, coarse_mesh->totloop);
}
- if (!has_mdisps || top_level == 1) {
+
+ /* NOTE: Subdivision happens from the top level of the existing multires modifier. If it is set
+ * to 0 and there is mdisps layer it would mean that the modifier went out of sync with the data.
+ * This happens when, for example, linking modifiers from one object to another.
+ *
+ * In such cases simply ensure grids to be the proper level.
+ *
+ * If something smarter is needed it is up to the operators which does data synchronization, so
+ * that the mdisps layer is also synchronized. */
+ if (!has_mdisps || top_level == 1 || mmd->totlvl == 0) {
multires_reshape_ensure_grids(coarse_mesh, top_level);
if (ELEM(mode, MULTIRES_SUBDIVIDE_LINEAR, MULTIRES_SUBDIVIDE_SIMPLE)) {
multires_subdivide_create_tangent_displacement_linear_grids(object, mmd);
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 6bd841ca8e5..d17575195e3 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -375,6 +375,153 @@ static void object_make_local(Main *bmain, ID *id, const int flags)
}
}
+static void library_foreach_modifiersForeachIDLink(void *user_data,
+ Object *UNUSED(object),
+ ID **id_pointer,
+ int cb_flag)
+{
+ LibraryForeachIDData *data = (LibraryForeachIDData *)user_data;
+ BKE_lib_query_foreachid_process(data, id_pointer, cb_flag);
+}
+
+static void library_foreach_gpencil_modifiersForeachIDLink(void *user_data,
+ Object *UNUSED(object),
+ ID **id_pointer,
+ int cb_flag)
+{
+ LibraryForeachIDData *data = (LibraryForeachIDData *)user_data;
+ BKE_lib_query_foreachid_process(data, id_pointer, cb_flag);
+}
+
+static void library_foreach_shaderfxForeachIDLink(void *user_data,
+ Object *UNUSED(object),
+ ID **id_pointer,
+ int cb_flag)
+{
+ LibraryForeachIDData *data = (LibraryForeachIDData *)user_data;
+ BKE_lib_query_foreachid_process(data, id_pointer, cb_flag);
+}
+
+static void library_foreach_constraintObjectLooper(bConstraint *UNUSED(con),
+ ID **id_pointer,
+ bool is_reference,
+ void *user_data)
+{
+ LibraryForeachIDData *data = (LibraryForeachIDData *)user_data;
+ const int cb_flag = is_reference ? IDWALK_CB_USER : IDWALK_CB_NOP;
+ BKE_lib_query_foreachid_process(data, id_pointer, cb_flag);
+}
+
+static void library_foreach_particlesystemsObjectLooper(ParticleSystem *UNUSED(psys),
+ ID **id_pointer,
+ void *user_data,
+ int cb_flag)
+{
+ LibraryForeachIDData *data = (LibraryForeachIDData *)user_data;
+ BKE_lib_query_foreachid_process(data, id_pointer, cb_flag);
+}
+
+static void object_foreach_id(ID *id, LibraryForeachIDData *data)
+{
+ Object *object = (Object *)id;
+
+ /* Object is special, proxies make things hard... */
+ const int proxy_cb_flag = ((BKE_lib_query_foreachid_process_flags_get(data) &
+ IDWALK_NO_INDIRECT_PROXY_DATA_USAGE) == 0 &&
+ (object->proxy || object->proxy_group)) ?
+ IDWALK_CB_INDIRECT_USAGE :
+ 0;
+
+ /* object data special case */
+ if (object->type == OB_EMPTY) {
+ /* empty can have NULL or Image */
+ BKE_LIB_FOREACHID_PROCESS_ID(data, object->data, proxy_cb_flag | IDWALK_CB_USER);
+ }
+ else {
+ /* when set, this can't be NULL */
+ if (object->data) {
+ BKE_LIB_FOREACHID_PROCESS_ID(
+ data, object->data, proxy_cb_flag | IDWALK_CB_USER | IDWALK_CB_NEVER_NULL);
+ }
+ }
+
+ BKE_LIB_FOREACHID_PROCESS(data, object->parent, IDWALK_CB_NEVER_SELF);
+ BKE_LIB_FOREACHID_PROCESS(data, object->track, IDWALK_CB_NEVER_SELF);
+ /* object->proxy is refcounted, but not object->proxy_group... *sigh* */
+ BKE_LIB_FOREACHID_PROCESS(data, object->proxy, IDWALK_CB_USER | IDWALK_CB_NEVER_SELF);
+ BKE_LIB_FOREACHID_PROCESS(data, object->proxy_group, IDWALK_CB_NOP);
+
+ /* Special case!
+ * Since this field is set/owned by 'user' of this ID (and not ID itself),
+ * it is only indirect usage if proxy object is linked... Twisted. */
+ {
+ const int cb_flag_orig = BKE_lib_query_foreachid_process_callback_flag_override(
+ data,
+ (object->proxy_from != NULL && ID_IS_LINKED(object->proxy_from)) ?
+ IDWALK_CB_INDIRECT_USAGE :
+ 0,
+ true);
+ BKE_LIB_FOREACHID_PROCESS(data, object->proxy_from, IDWALK_CB_LOOPBACK | IDWALK_CB_NEVER_SELF);
+ BKE_lib_query_foreachid_process_callback_flag_override(data, cb_flag_orig, true);
+ }
+
+ BKE_LIB_FOREACHID_PROCESS(data, object->poselib, IDWALK_CB_USER);
+
+ for (int i = 0; i < object->totcol; i++) {
+ BKE_LIB_FOREACHID_PROCESS(data, object->mat[i], proxy_cb_flag | IDWALK_CB_USER);
+ }
+
+ /* Note that ob->gpd is deprecated, so no need to handle it here. */
+ BKE_LIB_FOREACHID_PROCESS(data, object->instance_collection, IDWALK_CB_USER);
+
+ if (object->pd) {
+ BKE_LIB_FOREACHID_PROCESS(data, object->pd->tex, IDWALK_CB_USER);
+ BKE_LIB_FOREACHID_PROCESS(data, object->pd->f_source, IDWALK_CB_NOP);
+ }
+ /* Note that ob->effect is deprecated, so no need to handle it here. */
+
+ if (object->pose) {
+ const int cb_flag_orig = BKE_lib_query_foreachid_process_callback_flag_override(
+ data, proxy_cb_flag, false);
+ LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
+ IDP_foreach_property(
+ pchan->prop, IDP_TYPE_FILTER_ID, BKE_lib_query_idpropertiesForeachIDLink_callback, data);
+ BKE_LIB_FOREACHID_PROCESS(data, pchan->custom, IDWALK_CB_USER);
+ BKE_constraints_id_loop(&pchan->constraints, library_foreach_constraintObjectLooper, data);
+ }
+ BKE_lib_query_foreachid_process_callback_flag_override(data, cb_flag_orig, true);
+ }
+
+ if (object->rigidbody_constraint) {
+ BKE_LIB_FOREACHID_PROCESS(data, object->rigidbody_constraint->ob1, IDWALK_CB_NEVER_SELF);
+ BKE_LIB_FOREACHID_PROCESS(data, object->rigidbody_constraint->ob2, IDWALK_CB_NEVER_SELF);
+ }
+
+ if (object->lodlevels.first) {
+ LISTBASE_FOREACH (LodLevel *, level, &object->lodlevels) {
+ BKE_LIB_FOREACHID_PROCESS(data, level->source, IDWALK_CB_NEVER_SELF);
+ }
+ }
+
+ BKE_modifiers_foreach_ID_link(object, library_foreach_modifiersForeachIDLink, data);
+ BKE_gpencil_modifiers_foreach_ID_link(
+ object, library_foreach_gpencil_modifiersForeachIDLink, data);
+ BKE_constraints_id_loop(&object->constraints, library_foreach_constraintObjectLooper, data);
+ BKE_shaderfx_foreach_ID_link(object, library_foreach_shaderfxForeachIDLink, data);
+
+ LISTBASE_FOREACH (ParticleSystem *, psys, &object->particlesystem) {
+ BKE_particlesystem_id_loop(psys, library_foreach_particlesystemsObjectLooper, data);
+ }
+
+ if (object->soft) {
+ BKE_LIB_FOREACHID_PROCESS(data, object->soft->collision_group, IDWALK_CB_NOP);
+
+ if (object->soft->effector_weights) {
+ BKE_LIB_FOREACHID_PROCESS(data, object->soft->effector_weights->group, IDWALK_CB_NOP);
+ }
+ }
+}
+
IDTypeInfo IDType_ID_OB = {
.id_code = ID_OB,
.id_filter = FILTER_ID_OB,
@@ -389,6 +536,7 @@ IDTypeInfo IDType_ID_OB = {
.copy_data = object_copy_data,
.free_data = object_free_data,
.make_local = object_make_local,
+ .foreach_id = object_foreach_id,
};
void BKE_object_workob_clear(Object *workob)
@@ -3887,6 +4035,10 @@ bool BKE_object_is_child_recursive(const Object *ob_parent, const Object *ob_chi
* cases false positives are hard to avoid (shape keys for example) */
int BKE_object_is_modified(Scene *scene, Object *ob)
{
+ /* Always test on original object since evaluated object may no longer
+ * have shape keys or modifiers that were used to evaluate it. */
+ ob = DEG_get_original_object(ob);
+
int flag = 0;
if (BKE_key_from_object(ob)) {
@@ -4017,6 +4169,10 @@ static bool modifiers_has_animation_check(const Object *ob)
* and we can still if there was actual deformation afterwards */
int BKE_object_is_deform_modified(Scene *scene, Object *ob)
{
+ /* Always test on original object since evaluated object may no longer
+ * have shape keys or modifiers that were used to evaluate it. */
+ ob = DEG_get_original_object(ob);
+
ModifierData *md;
VirtualModifierData virtualModifierData;
int flag = 0;
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index 5b608d579e8..f26b478c680 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -116,6 +116,7 @@ IDTypeInfo IDType_ID_PAL = {
.copy_data = palette_copy_data,
.free_data = palette_free_data,
.make_local = NULL,
+ .foreach_id = NULL,
};
static void paint_curve_copy_data(Main *UNUSED(bmain),
@@ -153,6 +154,7 @@ IDTypeInfo IDType_ID_PC = {
.copy_data = paint_curve_copy_data,
.free_data = paint_curve_free_data,
.make_local = NULL,
+ .foreach_id = NULL,
};
const char PAINT_CURSOR_SCULPT[3] = {255, 100, 100};
@@ -547,35 +549,35 @@ void BKE_paint_runtime_init(const ToolSettings *ts, Paint *paint)
paint->runtime.tool_offset = offsetof(Brush, imagepaint_tool);
paint->runtime.ob_mode = OB_MODE_TEXTURE_PAINT;
}
- else if (paint == &ts->sculpt->paint) {
+ else if (ts->sculpt && paint == &ts->sculpt->paint) {
paint->runtime.tool_offset = offsetof(Brush, sculpt_tool);
paint->runtime.ob_mode = OB_MODE_SCULPT;
}
- else if (paint == &ts->vpaint->paint) {
+ else if (ts->vpaint && paint == &ts->vpaint->paint) {
paint->runtime.tool_offset = offsetof(Brush, vertexpaint_tool);
paint->runtime.ob_mode = OB_MODE_VERTEX_PAINT;
}
- else if (paint == &ts->wpaint->paint) {
+ else if (ts->wpaint && paint == &ts->wpaint->paint) {
paint->runtime.tool_offset = offsetof(Brush, weightpaint_tool);
paint->runtime.ob_mode = OB_MODE_WEIGHT_PAINT;
}
- else if (paint == &ts->uvsculpt->paint) {
+ else if (ts->uvsculpt && paint == &ts->uvsculpt->paint) {
paint->runtime.tool_offset = offsetof(Brush, uv_sculpt_tool);
paint->runtime.ob_mode = OB_MODE_EDIT;
}
- else if (paint == &ts->gp_paint->paint) {
+ else if (ts->gp_paint && paint == &ts->gp_paint->paint) {
paint->runtime.tool_offset = offsetof(Brush, gpencil_tool);
paint->runtime.ob_mode = OB_MODE_PAINT_GPENCIL;
}
- else if (paint == &ts->gp_vertexpaint->paint) {
+ else if (ts->gp_vertexpaint && paint == &ts->gp_vertexpaint->paint) {
paint->runtime.tool_offset = offsetof(Brush, gpencil_vertex_tool);
paint->runtime.ob_mode = OB_MODE_VERTEX_GPENCIL;
}
- else if (paint == &ts->gp_sculptpaint->paint) {
+ else if (ts->gp_sculptpaint && paint == &ts->gp_sculptpaint->paint) {
paint->runtime.tool_offset = offsetof(Brush, gpencil_sculpt_tool);
paint->runtime.ob_mode = OB_MODE_SCULPT_GPENCIL;
}
- else if (paint == &ts->gp_weightpaint->paint) {
+ else if (ts->gp_weightpaint && paint == &ts->gp_weightpaint->paint) {
paint->runtime.tool_offset = offsetof(Brush, gpencil_weight_tool);
paint->runtime.ob_mode = OB_MODE_WEIGHT_GPENCIL;
}
@@ -1480,6 +1482,7 @@ static void sculpt_update_object(
SculptSession *ss = ob->sculpt;
Mesh *me = BKE_object_get_original_mesh(ob);
MultiresModifierData *mmd = BKE_sculpt_multires_active(scene, ob);
+ const bool use_face_sets = (ob->mode & OB_MODE_SCULPT) != 0;
ss->deform_modifiers_active = sculpt_modifiers_active(scene, sd, ob);
ss->show_mask = (sd->flags & SCULPT_HIDE_MASK) == 0;
@@ -1535,17 +1538,22 @@ static void sculpt_update_object(
}
/* Sculpt Face Sets. */
- if (!CustomData_has_layer(&me->pdata, CD_SCULPT_FACE_SETS)) {
- ss->face_sets = CustomData_add_layer(
- &me->pdata, CD_SCULPT_FACE_SETS, CD_CALLOC, NULL, me->totpoly);
- for (int i = 0; i < me->totpoly; i++) {
- ss->face_sets[i] = 1;
- }
+ if (use_face_sets) {
+ if (!CustomData_has_layer(&me->pdata, CD_SCULPT_FACE_SETS)) {
+ ss->face_sets = CustomData_add_layer(
+ &me->pdata, CD_SCULPT_FACE_SETS, CD_CALLOC, NULL, me->totpoly);
+ for (int i = 0; i < me->totpoly; i++) {
+ ss->face_sets[i] = 1;
+ }
- /* Set the default face set color if the datalayer did not exist. */
- me->face_sets_color_default = 1;
+ /* Set the default face set color if the datalayer did not exist. */
+ me->face_sets_color_default = 1;
+ }
+ ss->face_sets = CustomData_get_layer(&me->pdata, CD_SCULPT_FACE_SETS);
+ }
+ else {
+ ss->face_sets = NULL;
}
- ss->face_sets = CustomData_get_layer(&me->pdata, CD_SCULPT_FACE_SETS);
ss->subdiv_ccg = me_eval->runtime.subdiv_ccg;
@@ -1805,11 +1813,12 @@ static PBVH *build_pbvh_for_dynamic_topology(Object *ob)
return pbvh;
}
-static PBVH *build_pbvh_from_regular_mesh(Object *ob, Mesh *me_eval_deform)
+static PBVH *build_pbvh_from_regular_mesh(Object *ob, Mesh *me_eval_deform, bool respect_hide)
{
Mesh *me = BKE_object_get_original_mesh(ob);
const int looptris_num = poly_to_tri_count(me->totpoly, me->totloop);
PBVH *pbvh = BKE_pbvh_new();
+ BKE_pbvh_respect_hide_set(pbvh, respect_hide);
MLoopTri *looptri = MEM_malloc_arrayN(looptris_num, sizeof(*looptri), __func__);
@@ -1841,11 +1850,12 @@ static PBVH *build_pbvh_from_regular_mesh(Object *ob, Mesh *me_eval_deform)
return pbvh;
}
-static PBVH *build_pbvh_from_ccg(Object *ob, SubdivCCG *subdiv_ccg)
+static PBVH *build_pbvh_from_ccg(Object *ob, SubdivCCG *subdiv_ccg, bool respect_hide)
{
CCGKey key;
BKE_subdiv_ccg_key_top_level(&key, subdiv_ccg);
PBVH *pbvh = BKE_pbvh_new();
+ BKE_pbvh_respect_hide_set(pbvh, respect_hide);
BKE_pbvh_build_grids(pbvh,
subdiv_ccg->grids,
subdiv_ccg->num_grids,
@@ -1863,6 +1873,14 @@ PBVH *BKE_sculpt_object_pbvh_ensure(Depsgraph *depsgraph, Object *ob)
if (ob == NULL || ob->sculpt == NULL) {
return NULL;
}
+
+ bool respect_hide = true;
+ if (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT)) {
+ if (!(BKE_paint_select_vert_test(ob) || BKE_paint_select_face_test(ob))) {
+ respect_hide = false;
+ }
+ }
+
PBVH *pbvh = ob->sculpt->pbvh;
if (pbvh != NULL) {
/* NOTE: It is possible that grids were re-allocated due to modifier
@@ -1886,11 +1904,11 @@ PBVH *BKE_sculpt_object_pbvh_ensure(Depsgraph *depsgraph, Object *ob)
Object *object_eval = DEG_get_evaluated_object(depsgraph, ob);
Mesh *mesh_eval = object_eval->data;
if (mesh_eval->runtime.subdiv_ccg != NULL) {
- pbvh = build_pbvh_from_ccg(ob, mesh_eval->runtime.subdiv_ccg);
+ pbvh = build_pbvh_from_ccg(ob, mesh_eval->runtime.subdiv_ccg, respect_hide);
}
else if (ob->type == OB_MESH) {
Mesh *me_eval_deform = object_eval->runtime.mesh_deform_eval;
- pbvh = build_pbvh_from_regular_mesh(ob, me_eval_deform);
+ pbvh = build_pbvh_from_regular_mesh(ob, me_eval_deform, respect_hide);
}
}
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 2f2d3aded31..015c67806c6 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -55,21 +55,22 @@
#include "BKE_cloth.h"
#include "BKE_collection.h"
#include "BKE_colortools.h"
-#include "BKE_effect.h"
-#include "BKE_idtype.h"
-#include "BKE_lattice.h"
-#include "BKE_main.h"
-
#include "BKE_deform.h"
#include "BKE_displist.h"
+#include "BKE_effect.h"
+#include "BKE_idtype.h"
#include "BKE_key.h"
+#include "BKE_lattice.h"
#include "BKE_lib_id.h"
+#include "BKE_lib_query.h"
+#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_mesh.h"
#include "BKE_modifier.h"
#include "BKE_particle.h"
#include "BKE_pointcache.h"
#include "BKE_scene.h"
+#include "BKE_texture.h"
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_build.h"
@@ -146,6 +147,53 @@ static void particle_settings_free_data(ID *id)
fluid_free_settings(particle_settings->fluid);
}
+static void particle_settings_foreach_id(ID *id, LibraryForeachIDData *data)
+{
+ ParticleSettings *psett = (ParticleSettings *)id;
+ BKE_LIB_FOREACHID_PROCESS(data, psett->instance_collection, IDWALK_CB_USER);
+ BKE_LIB_FOREACHID_PROCESS(data, psett->instance_object, IDWALK_CB_NOP);
+ BKE_LIB_FOREACHID_PROCESS(data, psett->bb_ob, IDWALK_CB_NOP);
+ BKE_LIB_FOREACHID_PROCESS(data, psett->collision_group, IDWALK_CB_NOP);
+
+ for (int i = 0; i < MAX_MTEX; i++) {
+ if (psett->mtex[i]) {
+ BKE_texture_mtex_foreach_id(data, psett->mtex[i]);
+ }
+ }
+
+ if (psett->effector_weights) {
+ BKE_LIB_FOREACHID_PROCESS(data, psett->effector_weights->group, IDWALK_CB_NOP);
+ }
+
+ if (psett->pd) {
+ BKE_LIB_FOREACHID_PROCESS(data, psett->pd->tex, IDWALK_CB_USER);
+ BKE_LIB_FOREACHID_PROCESS(data, psett->pd->f_source, IDWALK_CB_NOP);
+ }
+ if (psett->pd2) {
+ BKE_LIB_FOREACHID_PROCESS(data, psett->pd2->tex, IDWALK_CB_USER);
+ BKE_LIB_FOREACHID_PROCESS(data, psett->pd2->f_source, IDWALK_CB_NOP);
+ }
+
+ if (psett->boids) {
+ LISTBASE_FOREACH (BoidState *, state, &psett->boids->states) {
+ LISTBASE_FOREACH (BoidRule *, rule, &state->rules) {
+ if (rule->type == eBoidRuleType_Avoid) {
+ BoidRuleGoalAvoid *gabr = (BoidRuleGoalAvoid *)rule;
+ BKE_LIB_FOREACHID_PROCESS(data, gabr->ob, IDWALK_CB_NOP);
+ }
+ else if (rule->type == eBoidRuleType_FollowLeader) {
+ BoidRuleFollowLeader *flbr = (BoidRuleFollowLeader *)rule;
+ BKE_LIB_FOREACHID_PROCESS(data, flbr->ob, IDWALK_CB_NOP);
+ }
+ }
+ }
+ }
+
+ LISTBASE_FOREACH (ParticleDupliWeight *, dw, &psett->instance_weights) {
+ BKE_LIB_FOREACHID_PROCESS(data, dw->ob, IDWALK_CB_NOP);
+ }
+}
+
IDTypeInfo IDType_ID_PA = {
.id_code = ID_PA,
.id_filter = FILTER_ID_PA,
@@ -160,6 +208,7 @@ IDTypeInfo IDType_ID_PA = {
.copy_data = particle_settings_copy_data,
.free_data = particle_settings_free_data,
.make_local = NULL,
+ .foreach_id = particle_settings_foreach_id,
};
unsigned int PSYS_FRAND_SEED_OFFSET[PSYS_FRAND_COUNT];
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index 21bbdf46104..e31d2a8e005 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -295,6 +295,10 @@ static void build_mesh_leaf_node(PBVH *bvh, PBVHNode *node)
node->face_vert_indices = (const int(*)[3])face_vert_indices;
+ if (bvh->respect_hide == false) {
+ has_visible = true;
+ }
+
for (int i = 0; i < totface; i++) {
const MLoopTri *lt = &bvh->looptri[node->prim_indices[i]];
for (int j = 0; j < 3; j++) {
@@ -302,8 +306,10 @@ static void build_mesh_leaf_node(PBVH *bvh, PBVHNode *node)
bvh, map, &node->face_verts, &node->uniq_verts, bvh->mloop[lt->tri[j]].v);
}
- if (!paint_is_face_hidden(lt, bvh->verts, bvh->mloop)) {
- has_visible = true;
+ if (has_visible == false) {
+ if (!paint_is_face_hidden(lt, bvh->verts, bvh->mloop)) {
+ has_visible = true;
+ }
}
}
@@ -666,7 +672,7 @@ void BKE_pbvh_build_grids(PBVH *bvh,
PBVH *BKE_pbvh_new(void)
{
PBVH *bvh = MEM_callocN(sizeof(PBVH), "pbvh");
-
+ bvh->respect_hide = true;
return bvh;
}
@@ -2117,7 +2123,7 @@ static bool pbvh_faces_node_raycast(PBVH *bvh,
const MLoopTri *lt = &bvh->looptri[faces[i]];
const int *face_verts = node->face_vert_indices[i];
- if (paint_is_face_hidden(lt, vert, mloop)) {
+ if (bvh->respect_hide && paint_is_face_hidden(lt, vert, mloop)) {
continue;
}
@@ -2426,7 +2432,7 @@ static bool pbvh_faces_node_nearest_to_ray(PBVH *bvh,
const MLoopTri *lt = &bvh->looptri[faces[i]];
const int *face_verts = node->face_vert_indices[i];
- if (paint_is_face_hidden(lt, vert, mloop)) {
+ if (bvh->respect_hide && paint_is_face_hidden(lt, vert, mloop)) {
continue;
}
@@ -2900,6 +2906,12 @@ void pbvh_vertex_iter_init(PBVH *bvh, PBVHNode *node, PBVHVertexIter *vi, int mo
vi->fno = NULL;
vi->mvert = NULL;
+ vi->respect_hide = bvh->respect_hide;
+ if (bvh->respect_hide == false) {
+ /* The same value for all vertices. */
+ vi->visible = true;
+ }
+
BKE_pbvh_node_get_grids(bvh, node, &grid_indices, &totgrid, NULL, &gridsize, &grids);
BKE_pbvh_node_num_verts(bvh, node, &uniq_verts, &totvert);
BKE_pbvh_node_get_verts(bvh, node, &vert_indices, &verts);
@@ -3014,3 +3026,8 @@ void BKE_pbvh_face_sets_set(PBVH *bvh, int *face_sets)
{
bvh->face_sets = face_sets;
}
+
+void BKE_pbvh_respect_hide_set(PBVH *bvh, bool respect_hide)
+{
+ bvh->respect_hide = respect_hide;
+}
diff --git a/source/blender/blenkernel/intern/pbvh_intern.h b/source/blender/blenkernel/intern/pbvh_intern.h
index d3e42ac7705..7397f939894 100644
--- a/source/blender/blenkernel/intern/pbvh_intern.h
+++ b/source/blender/blenkernel/intern/pbvh_intern.h
@@ -160,6 +160,7 @@ struct PBVH {
bool deformed;
bool show_mask;
bool show_face_sets;
+ bool respect_hide;
/* Dynamic topology */
BMesh *bm;
diff --git a/source/blender/blenkernel/intern/pointcloud.c b/source/blender/blenkernel/intern/pointcloud.c
index 79b16443122..e03888dcad7 100644
--- a/source/blender/blenkernel/intern/pointcloud.c
+++ b/source/blender/blenkernel/intern/pointcloud.c
@@ -21,6 +21,7 @@
#include "MEM_guardedalloc.h"
#include "DNA_defaults.h"
+#include "DNA_material_types.h"
#include "DNA_object_types.h"
#include "DNA_pointcloud_types.h"
@@ -48,23 +49,7 @@
/* PointCloud datablock */
-static void pointcloud_random(PointCloud *pointcloud)
-{
- pointcloud->totpoint = 400;
- CustomData_realloc(&pointcloud->pdata, pointcloud->totpoint);
- BKE_pointcloud_update_customdata_pointers(pointcloud);
-
- RNG *rng = BLI_rng_new(0);
-
- for (int i = 0; i < pointcloud->totpoint; i++) {
- pointcloud->co[i][0] = 2.0f * BLI_rng_get_float(rng) - 1.0f;
- pointcloud->co[i][1] = 2.0f * BLI_rng_get_float(rng) - 1.0f;
- pointcloud->co[i][2] = 2.0f * BLI_rng_get_float(rng) - 1.0f;
- pointcloud->radius[i] = 0.05f * BLI_rng_get_float(rng);
- }
-
- BLI_rng_free(rng);
-}
+static void pointcloud_random(PointCloud *pointcloud);
static void pointcloud_init_data(ID *id)
{
@@ -81,15 +66,6 @@ static void pointcloud_init_data(ID *id)
pointcloud_random(pointcloud);
}
-void *BKE_pointcloud_add(Main *bmain, const char *name)
-{
- PointCloud *pointcloud = BKE_libblock_alloc(bmain, ID_PT, name, 0);
-
- pointcloud_init_data(&pointcloud->id);
-
- return pointcloud;
-}
-
static void pointcloud_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src, const int flag)
{
PointCloud *pointcloud_dst = (PointCloud *)id_dst;
@@ -105,18 +81,6 @@ static void pointcloud_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_s
BKE_pointcloud_update_customdata_pointers(pointcloud_dst);
}
-PointCloud *BKE_pointcloud_copy(Main *bmain, const PointCloud *pointcloud)
-{
- PointCloud *pointcloud_copy;
- BKE_id_copy(bmain, &pointcloud->id, (ID **)&pointcloud_copy);
- return pointcloud_copy;
-}
-
-static void pointcloud_make_local(Main *bmain, ID *id, const int flags)
-{
- BKE_lib_id_make_local_generic(bmain, id, flags);
-}
-
static void pointcloud_free_data(ID *id)
{
PointCloud *pointcloud = (PointCloud *)id;
@@ -126,6 +90,14 @@ static void pointcloud_free_data(ID *id)
MEM_SAFE_FREE(pointcloud->mat);
}
+static void pointcloud_foreach_id(ID *id, LibraryForeachIDData *data)
+{
+ PointCloud *pointcloud = (PointCloud *)id;
+ for (int i = 0; i < pointcloud->totcol; i++) {
+ BKE_LIB_FOREACHID_PROCESS(data, pointcloud->mat[i], IDWALK_CB_USER);
+ }
+}
+
IDTypeInfo IDType_ID_PT = {
.id_code = ID_PT,
.id_filter = FILTER_ID_PT,
@@ -139,9 +111,44 @@ IDTypeInfo IDType_ID_PT = {
.init_data = pointcloud_init_data,
.copy_data = pointcloud_copy_data,
.free_data = pointcloud_free_data,
- .make_local = pointcloud_make_local,
+ .make_local = NULL,
+ .foreach_id = pointcloud_foreach_id,
};
+static void pointcloud_random(PointCloud *pointcloud)
+{
+ pointcloud->totpoint = 400;
+ CustomData_realloc(&pointcloud->pdata, pointcloud->totpoint);
+ BKE_pointcloud_update_customdata_pointers(pointcloud);
+
+ RNG *rng = BLI_rng_new(0);
+
+ for (int i = 0; i < pointcloud->totpoint; i++) {
+ pointcloud->co[i][0] = 2.0f * BLI_rng_get_float(rng) - 1.0f;
+ pointcloud->co[i][1] = 2.0f * BLI_rng_get_float(rng) - 1.0f;
+ pointcloud->co[i][2] = 2.0f * BLI_rng_get_float(rng) - 1.0f;
+ pointcloud->radius[i] = 0.05f * BLI_rng_get_float(rng);
+ }
+
+ BLI_rng_free(rng);
+}
+
+void *BKE_pointcloud_add(Main *bmain, const char *name)
+{
+ PointCloud *pointcloud = BKE_libblock_alloc(bmain, ID_PT, name, 0);
+
+ pointcloud_init_data(&pointcloud->id);
+
+ return pointcloud;
+}
+
+PointCloud *BKE_pointcloud_copy(Main *bmain, const PointCloud *pointcloud)
+{
+ PointCloud *pointcloud_copy;
+ BKE_id_copy(bmain, &pointcloud->id, (ID **)&pointcloud_copy);
+ return pointcloud_copy;
+}
+
BoundBox *BKE_pointcloud_boundbox_get(Object *ob)
{
BLI_assert(ob->type == OB_POINTCLOUD);
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index be6a4e4022b..34249e0a8f7 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -33,6 +33,7 @@
#include "DNA_defaults.h"
#include "DNA_gpencil_types.h"
#include "DNA_linestyle_types.h"
+#include "DNA_mask_types.h"
#include "DNA_mesh_types.h"
#include "DNA_node_types.h"
#include "DNA_object_types.h"
@@ -42,6 +43,7 @@
#include "DNA_sequence_types.h"
#include "DNA_sound_types.h"
#include "DNA_space_types.h"
+#include "DNA_text_types.h"
#include "DNA_view3d_types.h"
#include "DNA_windowmanager_types.h"
#include "DNA_workspace_types.h"
@@ -77,6 +79,7 @@
#include "BKE_image.h"
#include "BKE_layer.h"
#include "BKE_lib_id.h"
+#include "BKE_lib_query.h"
#include "BKE_lib_remap.h"
#include "BKE_linestyle.h"
#include "BKE_main.h"
@@ -418,6 +421,155 @@ static void scene_free_data(ID *id)
BLI_assert(scene->layer_properties == NULL);
}
+static void library_foreach_rigidbodyworldSceneLooper(struct RigidBodyWorld *UNUSED(rbw),
+ ID **id_pointer,
+ void *user_data,
+ int cb_flag)
+{
+ LibraryForeachIDData *data = (LibraryForeachIDData *)user_data;
+ BKE_lib_query_foreachid_process(data, id_pointer, cb_flag);
+}
+
+static void library_foreach_paint(LibraryForeachIDData *data, Paint *paint)
+{
+ BKE_LIB_FOREACHID_PROCESS(data, paint->brush, IDWALK_CB_USER);
+ for (int i = 0; i < paint->tool_slots_len; i++) {
+ BKE_LIB_FOREACHID_PROCESS(data, paint->tool_slots[i].brush, IDWALK_CB_USER);
+ }
+ BKE_LIB_FOREACHID_PROCESS(data, paint->palette, IDWALK_CB_USER);
+}
+
+static void library_foreach_layer_collection(LibraryForeachIDData *data, ListBase *lb)
+{
+ LISTBASE_FOREACH (LayerCollection *, lc, lb) {
+ /* XXX This is very weak. The whole idea of keeping pointers to private IDs is very bad
+ * anyway... */
+ const int cb_flag = (lc->collection != NULL &&
+ (lc->collection->id.flag & LIB_EMBEDDED_DATA) != 0) ?
+ IDWALK_CB_EMBEDDED :
+ IDWALK_CB_NOP;
+ BKE_LIB_FOREACHID_PROCESS(data, lc->collection, cb_flag);
+ library_foreach_layer_collection(data, &lc->layer_collections);
+ }
+}
+
+static void scene_foreach_id(ID *id, LibraryForeachIDData *data)
+{
+ Scene *scene = (Scene *)id;
+
+ BKE_LIB_FOREACHID_PROCESS(data, scene->camera, IDWALK_CB_NOP);
+ BKE_LIB_FOREACHID_PROCESS(data, scene->world, IDWALK_CB_USER);
+ BKE_LIB_FOREACHID_PROCESS(data, scene->set, IDWALK_CB_NEVER_SELF);
+ BKE_LIB_FOREACHID_PROCESS(data, scene->clip, IDWALK_CB_USER);
+ BKE_LIB_FOREACHID_PROCESS(data, scene->gpd, IDWALK_CB_USER);
+ BKE_LIB_FOREACHID_PROCESS(data, scene->r.bake.cage_object, IDWALK_CB_NOP);
+ if (scene->nodetree) {
+ /* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
+ BKE_library_foreach_ID_embedded(data, (ID **)&scene->nodetree);
+ }
+ if (scene->ed) {
+ Sequence *seq;
+ SEQP_BEGIN (scene->ed, seq) {
+ BKE_LIB_FOREACHID_PROCESS(data, seq->scene, IDWALK_CB_NEVER_SELF);
+ BKE_LIB_FOREACHID_PROCESS(data, seq->scene_camera, IDWALK_CB_NOP);
+ BKE_LIB_FOREACHID_PROCESS(data, seq->clip, IDWALK_CB_USER);
+ BKE_LIB_FOREACHID_PROCESS(data, seq->mask, IDWALK_CB_USER);
+ BKE_LIB_FOREACHID_PROCESS(data, seq->sound, IDWALK_CB_USER);
+ IDP_foreach_property(
+ seq->prop, IDP_TYPE_FILTER_ID, BKE_lib_query_idpropertiesForeachIDLink_callback, data);
+ LISTBASE_FOREACH (SequenceModifierData *, smd, &seq->modifiers) {
+ BKE_LIB_FOREACHID_PROCESS(data, smd->mask_id, IDWALK_CB_USER);
+ }
+
+ if (seq->type == SEQ_TYPE_TEXT && seq->effectdata) {
+ TextVars *text_data = seq->effectdata;
+ BKE_LIB_FOREACHID_PROCESS(data, text_data->text_font, IDWALK_CB_USER);
+ }
+ }
+ SEQ_END;
+ }
+
+ /* This pointer can be NULL during old files reading, better be safe than sorry. */
+ if (scene->master_collection != NULL) {
+ BKE_library_foreach_ID_embedded(data, (ID **)&scene->master_collection);
+ }
+
+ LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
+ BKE_LIB_FOREACHID_PROCESS(data, view_layer->mat_override, IDWALK_CB_USER);
+
+ LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ BKE_LIB_FOREACHID_PROCESS(data, base->object, IDWALK_CB_NOP);
+ }
+
+ library_foreach_layer_collection(data, &view_layer->layer_collections);
+
+ LISTBASE_FOREACH (FreestyleModuleConfig *, fmc, &view_layer->freestyle_config.modules) {
+ if (fmc->script) {
+ BKE_LIB_FOREACHID_PROCESS(data, fmc->script, IDWALK_CB_NOP);
+ }
+ }
+
+ LISTBASE_FOREACH (FreestyleLineSet *, fls, &view_layer->freestyle_config.linesets) {
+ if (fls->group) {
+ BKE_LIB_FOREACHID_PROCESS(data, fls->group, IDWALK_CB_USER);
+ }
+
+ if (fls->linestyle) {
+ BKE_LIB_FOREACHID_PROCESS(data, fls->linestyle, IDWALK_CB_USER);
+ }
+ }
+ }
+
+ LISTBASE_FOREACH (TimeMarker *, marker, &scene->markers) {
+ BKE_LIB_FOREACHID_PROCESS(data, marker->camera, IDWALK_CB_NOP);
+ }
+
+ ToolSettings *toolsett = scene->toolsettings;
+ if (toolsett) {
+ BKE_LIB_FOREACHID_PROCESS(data, toolsett->particle.scene, IDWALK_CB_NOP);
+ BKE_LIB_FOREACHID_PROCESS(data, toolsett->particle.object, IDWALK_CB_NOP);
+ BKE_LIB_FOREACHID_PROCESS(data, toolsett->particle.shape_object, IDWALK_CB_NOP);
+
+ library_foreach_paint(data, &toolsett->imapaint.paint);
+ BKE_LIB_FOREACHID_PROCESS(data, toolsett->imapaint.stencil, IDWALK_CB_USER);
+ BKE_LIB_FOREACHID_PROCESS(data, toolsett->imapaint.clone, IDWALK_CB_USER);
+ BKE_LIB_FOREACHID_PROCESS(data, toolsett->imapaint.canvas, IDWALK_CB_USER);
+
+ if (toolsett->vpaint) {
+ library_foreach_paint(data, &toolsett->vpaint->paint);
+ }
+ if (toolsett->wpaint) {
+ library_foreach_paint(data, &toolsett->wpaint->paint);
+ }
+ if (toolsett->sculpt) {
+ library_foreach_paint(data, &toolsett->sculpt->paint);
+ BKE_LIB_FOREACHID_PROCESS(data, toolsett->sculpt->gravity_object, IDWALK_CB_NOP);
+ }
+ if (toolsett->uvsculpt) {
+ library_foreach_paint(data, &toolsett->uvsculpt->paint);
+ }
+ if (toolsett->gp_paint) {
+ library_foreach_paint(data, &toolsett->gp_paint->paint);
+ }
+ if (toolsett->gp_vertexpaint) {
+ library_foreach_paint(data, &toolsett->gp_vertexpaint->paint);
+ }
+ if (toolsett->gp_sculptpaint) {
+ library_foreach_paint(data, &toolsett->gp_sculptpaint->paint);
+ }
+ if (toolsett->gp_weightpaint) {
+ library_foreach_paint(data, &toolsett->gp_weightpaint->paint);
+ }
+
+ BKE_LIB_FOREACHID_PROCESS(data, toolsett->gp_sculpt.guide.reference_object, IDWALK_CB_NOP);
+ }
+
+ if (scene->rigidbody_world) {
+ BKE_rigidbody_world_id_loop(
+ scene->rigidbody_world, library_foreach_rigidbodyworldSceneLooper, data);
+ }
+}
+
IDTypeInfo IDType_ID_SCE = {
.id_code = ID_SCE,
.id_filter = FILTER_ID_SCE,
@@ -434,6 +586,7 @@ IDTypeInfo IDType_ID_SCE = {
/* For now default `BKE_lib_id_make_local_generic()` should work, may need more work though to
* support all possible corner cases. */
.make_local = NULL,
+ .foreach_id = scene_foreach_id,
};
const char *RE_engine_id_BLENDER_EEVEE = "BLENDER_EEVEE";
@@ -1175,34 +1328,6 @@ int BKE_scene_orientation_slot_get_index(const TransformOrientationSlot *orient_
/** \} */
-/* That's like really a bummer, because currently animation data for armatures
- * might want to use pose, and pose might be missing on the object.
- * This happens when changing visible layers, which leads to situations when
- * pose is missing or marked for recalc, animation will change it and then
- * object update will restore the pose.
- *
- * This could be solved by the new dependency graph, but for until then we'll
- * do an extra pass on the objects to ensure it's all fine.
- */
-#define POSE_ANIMATION_WORKAROUND
-
-#ifdef POSE_ANIMATION_WORKAROUND
-static void scene_armature_depsgraph_workaround(Main *bmain, Depsgraph *depsgraph)
-{
- Object *ob;
- if (BLI_listbase_is_empty(&bmain->armatures) || !DEG_id_type_updated(depsgraph, ID_OB)) {
- return;
- }
- for (ob = bmain->objects.first; ob; ob = ob->id.next) {
- if (ob->type == OB_ARMATURE && ob->adt) {
- if (ob->pose == NULL || (ob->pose->flag & POSE_RECALC)) {
- BKE_pose_rebuild(bmain, ob, ob->data, true);
- }
- }
- }
-}
-#endif
-
static bool check_rendered_viewport_visible(Main *bmain)
{
wmWindowManager *wm = bmain->wm.first;
@@ -1387,9 +1512,6 @@ void BKE_scene_graph_update_for_newframe(Depsgraph *depsgraph, Main *bmain)
BKE_image_editors_update_frame(bmain, scene->r.cfra);
BKE_sound_set_cfra(scene->r.cfra);
DEG_graph_relations_update(depsgraph, bmain, scene, view_layer);
-#ifdef POSE_ANIMATION_WORKAROUND
- scene_armature_depsgraph_workaround(bmain, depsgraph);
-#endif
/* Update all objects: drivers, matrices, displists, etc. flags set
* by depgraph or manual, no layer check here, gets correct flushed.
*
diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c
index 997e807a253..bfc0d437994 100644
--- a/source/blender/blenkernel/intern/screen.c
+++ b/source/blender/blenkernel/intern/screen.c
@@ -32,14 +32,18 @@
#include "MEM_guardedalloc.h"
#include "DNA_defaults.h"
+#include "DNA_gpencil_types.h"
+#include "DNA_mask_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
+#include "DNA_text_types.h"
#include "DNA_view3d_types.h"
#include "DNA_workspace_types.h"
#include "BLI_listbase.h"
#include "BLI_math_vector.h"
+#include "BLI_mempool.h"
#include "BLI_rect.h"
#include "BLI_utildefines.h"
@@ -48,6 +52,8 @@
#include "BKE_icons.h"
#include "BKE_idprop.h"
#include "BKE_idtype.h"
+#include "BKE_lib_query.h"
+#include "BKE_node.h"
#include "BKE_screen.h"
#include "BKE_workspace.h"
@@ -72,6 +78,158 @@ static void screen_free_data(ID *id)
MEM_SAFE_FREE(screen->tool_tip);
}
+static void screen_foreach_id_dopesheet(LibraryForeachIDData *data, bDopeSheet *ads)
+{
+ if (ads != NULL) {
+ BKE_LIB_FOREACHID_PROCESS_ID(data, ads->source, IDWALK_CB_NOP);
+ BKE_LIB_FOREACHID_PROCESS(data, ads->filter_grp, IDWALK_CB_NOP);
+ }
+}
+
+void BKE_screen_foreach_id_screen_area(LibraryForeachIDData *data, ScrArea *area)
+{
+ BKE_LIB_FOREACHID_PROCESS(data, area->full, IDWALK_CB_NOP);
+
+ /* TODO this should be moved to a callback in `SpaceType`, defined in each editor's own code.
+ * Will be for a later round of cleanup though... */
+ LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
+ switch (sl->spacetype) {
+ case SPACE_VIEW3D: {
+ View3D *v3d = (View3D *)sl;
+
+ BKE_LIB_FOREACHID_PROCESS(data, v3d->camera, IDWALK_CB_NOP);
+ BKE_LIB_FOREACHID_PROCESS(data, v3d->ob_center, IDWALK_CB_NOP);
+
+ if (v3d->localvd) {
+ BKE_LIB_FOREACHID_PROCESS(data, v3d->localvd->camera, IDWALK_CB_NOP);
+ }
+ break;
+ }
+ case SPACE_GRAPH: {
+ SpaceGraph *sipo = (SpaceGraph *)sl;
+
+ screen_foreach_id_dopesheet(data, sipo->ads);
+ break;
+ }
+ case SPACE_PROPERTIES: {
+ SpaceProperties *sbuts = (SpaceProperties *)sl;
+
+ BKE_LIB_FOREACHID_PROCESS_ID(data, sbuts->pinid, IDWALK_CB_NOP);
+ break;
+ }
+ case SPACE_FILE:
+ break;
+ case SPACE_ACTION: {
+ SpaceAction *saction = (SpaceAction *)sl;
+
+ screen_foreach_id_dopesheet(data, &saction->ads);
+ BKE_LIB_FOREACHID_PROCESS(data, saction->action, IDWALK_CB_NOP);
+ break;
+ }
+ case SPACE_IMAGE: {
+ SpaceImage *sima = (SpaceImage *)sl;
+
+ BKE_LIB_FOREACHID_PROCESS(data, sima->image, IDWALK_CB_USER_ONE);
+ BKE_LIB_FOREACHID_PROCESS(data, sima->mask_info.mask, IDWALK_CB_USER_ONE);
+ BKE_LIB_FOREACHID_PROCESS(data, sima->gpd, IDWALK_CB_USER);
+ break;
+ }
+ case SPACE_SEQ: {
+ SpaceSeq *sseq = (SpaceSeq *)sl;
+
+ BKE_LIB_FOREACHID_PROCESS(data, sseq->gpd, IDWALK_CB_USER);
+ break;
+ }
+ case SPACE_NLA: {
+ SpaceNla *snla = (SpaceNla *)sl;
+
+ screen_foreach_id_dopesheet(data, snla->ads);
+ break;
+ }
+ case SPACE_TEXT: {
+ SpaceText *st = (SpaceText *)sl;
+
+ BKE_LIB_FOREACHID_PROCESS(data, st->text, IDWALK_CB_NOP);
+ break;
+ }
+ case SPACE_SCRIPT: {
+ SpaceScript *scpt = (SpaceScript *)sl;
+
+ BKE_LIB_FOREACHID_PROCESS(data, scpt->script, IDWALK_CB_NOP);
+ break;
+ }
+ case SPACE_OUTLINER: {
+ SpaceOutliner *so = (SpaceOutliner *)sl;
+
+ BKE_LIB_FOREACHID_PROCESS_ID(data, so->search_tse.id, IDWALK_CB_NOP);
+
+ if (so->treestore != NULL) {
+ TreeStoreElem *tselem;
+ BLI_mempool_iter iter;
+
+ BLI_mempool_iternew(so->treestore, &iter);
+ while ((tselem = BLI_mempool_iterstep(&iter))) {
+ BKE_LIB_FOREACHID_PROCESS_ID(data, tselem->id, IDWALK_CB_NOP);
+ }
+ }
+ break;
+ }
+ case SPACE_NODE: {
+ SpaceNode *snode = (SpaceNode *)sl;
+
+ const bool is_private_nodetree = snode->id != NULL &&
+ ntreeFromID(snode->id) == snode->nodetree;
+
+ BKE_LIB_FOREACHID_PROCESS_ID(data, snode->id, IDWALK_CB_NOP);
+ BKE_LIB_FOREACHID_PROCESS_ID(data, snode->from, IDWALK_CB_NOP);
+
+ BKE_LIB_FOREACHID_PROCESS(
+ data, snode->nodetree, is_private_nodetree ? IDWALK_CB_EMBEDDED : IDWALK_CB_USER_ONE);
+
+ LISTBASE_FOREACH (bNodeTreePath *, path, &snode->treepath) {
+ if (path == snode->treepath.first) {
+ /* first nodetree in path is same as snode->nodetree */
+ BKE_LIB_FOREACHID_PROCESS(data,
+ path->nodetree,
+ is_private_nodetree ? IDWALK_CB_EMBEDDED :
+ IDWALK_CB_USER_ONE);
+ }
+ else {
+ BKE_LIB_FOREACHID_PROCESS(data, path->nodetree, IDWALK_CB_USER_ONE);
+ }
+
+ if (path->nodetree == NULL) {
+ break;
+ }
+ }
+
+ BKE_LIB_FOREACHID_PROCESS(data, snode->edittree, IDWALK_CB_NOP);
+ break;
+ }
+ case SPACE_CLIP: {
+ SpaceClip *sclip = (SpaceClip *)sl;
+
+ BKE_LIB_FOREACHID_PROCESS(data, sclip->clip, IDWALK_CB_USER_ONE);
+ BKE_LIB_FOREACHID_PROCESS(data, sclip->mask_info.mask, IDWALK_CB_USER_ONE);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+}
+
+static void screen_foreach_id(ID *id, LibraryForeachIDData *data)
+{
+ if (BKE_lib_query_foreachid_process_flags_get(data) & IDWALK_INCLUDE_UI) {
+ bScreen *screen = (bScreen *)id;
+
+ LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
+ BKE_screen_foreach_id_screen_area(data, area);
+ }
+ }
+}
+
IDTypeInfo IDType_ID_SCR = {
.id_code = ID_SCR,
.id_filter = 0,
@@ -86,6 +244,7 @@ IDTypeInfo IDType_ID_SCR = {
.copy_data = NULL,
.free_data = screen_free_data,
.make_local = NULL,
+ .foreach_id = screen_foreach_id,
};
/* ************ Spacetype/regiontype handling ************** */
diff --git a/source/blender/blenkernel/intern/seqcache.c b/source/blender/blenkernel/intern/seqcache.c
index a08bbf182fa..5c2d5b0087f 100644
--- a/source/blender/blenkernel/intern/seqcache.c
+++ b/source/blender/blenkernel/intern/seqcache.c
@@ -1217,6 +1217,11 @@ void BKE_sequencer_cache_cleanup_sequence(Scene *scene,
struct ImBuf *BKE_sequencer_cache_get(
const SeqRenderData *context, Sequence *seq, float cfra, int type, bool skip_disk_cache)
{
+
+ if (context->skip_cache || context->is_proxy_render || !seq) {
+ return NULL;
+ }
+
Scene *scene = context->scene;
if (context->is_prefetch_render) {
@@ -1314,6 +1319,10 @@ void BKE_sequencer_cache_put(const SeqRenderData *context,
float cost,
bool skip_disk_cache)
{
+ if (i == NULL || context->skip_cache || context->is_proxy_render || !seq) {
+ return;
+ }
+
Scene *scene = context->scene;
if (context->is_prefetch_render) {
@@ -1322,10 +1331,6 @@ void BKE_sequencer_cache_put(const SeqRenderData *context,
seq = BKE_sequencer_prefetch_get_original_sequence(seq, scene);
}
- if (i == NULL || context->skip_cache || context->is_proxy_render || !seq) {
- return;
- }
-
/* Prevent reinserting, it breaks cache key linking. */
ImBuf *test = BKE_sequencer_cache_get(context, seq, cfra, type, true);
if (test) {
diff --git a/source/blender/blenkernel/intern/seqprefetch.c b/source/blender/blenkernel/intern/seqprefetch.c
index f00d517940a..dc75e2b9098 100644
--- a/source/blender/blenkernel/intern/seqprefetch.c
+++ b/source/blender/blenkernel/intern/seqprefetch.c
@@ -179,12 +179,17 @@ static bool seq_prefetch_is_cache_full(Scene *scene)
return BKE_sequencer_cache_recycle_item(pfjob->scene) == false;
}
+static float seq_prefetch_cfra(PrefetchJob *pfjob)
+{
+ return pfjob->cfra + pfjob->num_frames_prefetched;
+}
+
void BKE_sequencer_prefetch_get_time_range(Scene *scene, int *start, int *end)
{
PrefetchJob *pfjob = seq_prefetch_job_get(scene);
*start = pfjob->cfra;
- *end = pfjob->cfra + pfjob->num_frames_prefetched;
+ *end = seq_prefetch_cfra(pfjob);
}
static void seq_prefetch_free_depsgraph(PrefetchJob *pfjob)
@@ -198,8 +203,7 @@ static void seq_prefetch_free_depsgraph(PrefetchJob *pfjob)
static void seq_prefetch_update_depsgraph(PrefetchJob *pfjob)
{
- DEG_evaluate_on_framechange(
- pfjob->bmain_eval, pfjob->depsgraph, pfjob->cfra + pfjob->num_frames_prefetched);
+ DEG_evaluate_on_framechange(pfjob->bmain_eval, pfjob->depsgraph, seq_prefetch_cfra(pfjob));
}
static void seq_prefetch_init_depsgraph(PrefetchJob *pfjob)
@@ -347,7 +351,7 @@ static bool seq_prefetch_do_skip_frame(Scene *scene)
{
Editing *ed = scene->ed;
PrefetchJob *pfjob = seq_prefetch_job_get(scene);
- float cfra = pfjob->cfra + pfjob->num_frames_prefetched;
+ float cfra = seq_prefetch_cfra(pfjob);
Sequence *seq_arr[MAXSEQ + 1];
int count = BKE_sequencer_get_shown_sequences(ed->seqbasep, cfra, 0, seq_arr);
SeqRenderData *ctx = &pfjob->context_cpy;
@@ -403,18 +407,37 @@ static bool seq_prefetch_do_skip_frame(Scene *scene)
return false;
}
+static bool seq_prefetch_need_suspend(PrefetchJob *pfjob)
+{
+ return seq_prefetch_is_cache_full(pfjob->scene) || seq_prefetch_is_scrubbing(pfjob->bmain) ||
+ (seq_prefetch_cfra(pfjob) >= pfjob->scene->r.efra);
+}
+
+static void seq_prefetch_do_suspend(PrefetchJob *pfjob)
+{
+ BLI_mutex_lock(&pfjob->prefetch_suspend_mutex);
+ while (seq_prefetch_need_suspend(pfjob) &&
+ (pfjob->scene->ed->cache_flag & SEQ_CACHE_PREFETCH_ENABLE) && !pfjob->stop) {
+ pfjob->waiting = true;
+ BLI_condition_wait(&pfjob->prefetch_suspend_cond, &pfjob->prefetch_suspend_mutex);
+ seq_prefetch_update_area(pfjob);
+ }
+ pfjob->waiting = false;
+ BLI_mutex_unlock(&pfjob->prefetch_suspend_mutex);
+}
+
static void *seq_prefetch_frames(void *job)
{
PrefetchJob *pfjob = (PrefetchJob *)job;
- while (pfjob->cfra + pfjob->num_frames_prefetched <= pfjob->scene->r.efra) {
+ while (seq_prefetch_cfra(pfjob) <= pfjob->scene->r.efra) {
pfjob->scene_eval->ed->prefetch_job = NULL;
seq_prefetch_update_depsgraph(pfjob);
AnimData *adt = BKE_animdata_from_id(&pfjob->context_cpy.scene->id);
BKE_animsys_evaluate_animdata(&pfjob->context_cpy.scene->id,
adt,
- pfjob->cfra + pfjob->num_frames_prefetched,
+ seq_prefetch_cfra(pfjob),
ADT_RECALC_ALL,
false);
@@ -431,26 +454,17 @@ static void *seq_prefetch_frames(void *job)
continue;
}
- ImBuf *ibuf = BKE_sequencer_give_ibuf(
- &pfjob->context_cpy, pfjob->cfra + pfjob->num_frames_prefetched, 0);
+ ImBuf *ibuf = BKE_sequencer_give_ibuf(&pfjob->context_cpy, seq_prefetch_cfra(pfjob), 0);
BKE_sequencer_cache_free_temp_cache(
- pfjob->scene, pfjob->context.task_id, pfjob->cfra + pfjob->num_frames_prefetched);
+ pfjob->scene, pfjob->context.task_id, seq_prefetch_cfra(pfjob));
IMB_freeImBuf(ibuf);
- /* suspend thread */
- BLI_mutex_lock(&pfjob->prefetch_suspend_mutex);
- while ((seq_prefetch_is_cache_full(pfjob->scene) || seq_prefetch_is_scrubbing(pfjob->bmain)) &&
- pfjob->scene->ed->cache_flag & SEQ_CACHE_PREFETCH_ENABLE && !pfjob->stop) {
- pfjob->waiting = true;
- BLI_condition_wait(&pfjob->prefetch_suspend_cond, &pfjob->prefetch_suspend_mutex);
- seq_prefetch_update_area(pfjob);
- }
- pfjob->waiting = false;
- BLI_mutex_unlock(&pfjob->prefetch_suspend_mutex);
+ /* Suspend thread if there is nothing to be prefetched. */
+ seq_prefetch_do_suspend(pfjob);
/* Avoid "collision" with main thread, but make sure to fetch at least few frames */
if (pfjob->num_frames_prefetched > 5 &&
- (pfjob->cfra + pfjob->num_frames_prefetched - pfjob->scene->r.cfra) < 2) {
+ (seq_prefetch_cfra(pfjob) - pfjob->scene->r.cfra) < 2) {
break;
}
@@ -463,7 +477,7 @@ static void *seq_prefetch_frames(void *job)
}
BKE_sequencer_cache_free_temp_cache(
- pfjob->scene, pfjob->context.task_id, pfjob->cfra + pfjob->num_frames_prefetched);
+ pfjob->scene, pfjob->context.task_id, seq_prefetch_cfra(pfjob));
pfjob->running = false;
pfjob->scene_eval->ed->prefetch_job = NULL;
@@ -520,10 +534,12 @@ void BKE_sequencer_prefetch_start(const SeqRenderData *context, float cfra, floa
seq_prefetch_resume(scene);
/* conditions to start:
* prefetch enabled, prefetch not running, not scrubbing,
- * not playing and rendering-expensive footage, cache storage enabled, has strips to render
+ * not playing and rendering-expensive footage, cache storage enabled, has strips to render,
+ * not rendering, not doing modal transform - important, see D7820.
*/
if ((ed->cache_flag & SEQ_CACHE_PREFETCH_ENABLE) && !running && !scrubbing &&
- !(playing && cost > 0.9) && ed->cache_flag & SEQ_CACHE_ALL_TYPES && has_strips) {
+ !(playing && cost > 0.9) && ed->cache_flag & SEQ_CACHE_ALL_TYPES && has_strips &&
+ !G.is_rendering && !G.moving) {
seq_prefetch_start(context, cfra);
}
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index a14db79ffc6..954dca0f679 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -1910,9 +1910,10 @@ static bool seq_proxy_get_fname(Editing *ed,
static ImBuf *seq_proxy_fetch(const SeqRenderData *context, Sequence *seq, int cfra)
{
char name[PROXY_MAXFILE];
- IMB_Proxy_Size psize = seq_rendersize_to_proxysize(context->preview_render_size);
- int size_flags;
StripProxy *proxy = seq->strip->proxy;
+ const eSpaceSeq_Proxy_RenderSize psize = context->preview_render_size;
+ const IMB_Proxy_Size psize_flag = seq_rendersize_to_proxysize(psize);
+ int size_flags;
Editing *ed = context->scene->ed;
StripAnim *sanim;
@@ -1923,7 +1924,7 @@ static ImBuf *seq_proxy_fetch(const SeqRenderData *context, Sequence *seq, int c
size_flags = proxy->build_size_flags;
/* only use proxies, if they are enabled (even if present!) */
- if (psize == IMB_PROXY_NONE || (size_flags & psize) == 0) {
+ if (psize_flag == IMB_PROXY_NONE || (size_flags & psize_flag) == 0) {
return NULL;
}
diff --git a/source/blender/blenkernel/intern/simulation.cc b/source/blender/blenkernel/intern/simulation.cc
index b4cfa7cf0ef..50770125a18 100644
--- a/source/blender/blenkernel/intern/simulation.cc
+++ b/source/blender/blenkernel/intern/simulation.cc
@@ -87,13 +87,13 @@ static void simulation_free_data(ID *id)
}
}
-void *BKE_simulation_add(Main *bmain, const char *name)
+static void simulation_foreach_id(ID *id, LibraryForeachIDData *data)
{
- Simulation *simulation = (Simulation *)BKE_libblock_alloc(bmain, ID_SIM, name, 0);
-
- simulation_init_data(&simulation->id);
-
- return simulation;
+ Simulation *simulation = (Simulation *)id;
+ if (simulation->nodetree) {
+ /* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
+ BKE_library_foreach_ID_embedded(data, (ID **)&simulation->nodetree);
+ }
}
IDTypeInfo IDType_ID_SIM = {
@@ -110,8 +110,18 @@ IDTypeInfo IDType_ID_SIM = {
/* copy_data */ simulation_copy_data,
/* free_data */ simulation_free_data,
/* make_local */ nullptr,
+ /* foreach_id */ simulation_foreach_id,
};
+void *BKE_simulation_add(Main *bmain, const char *name)
+{
+ Simulation *simulation = (Simulation *)BKE_libblock_alloc(bmain, ID_SIM, name, 0);
+
+ simulation_init_data(&simulation->id);
+
+ return simulation;
+}
+
void BKE_simulation_data_update(Depsgraph *UNUSED(depsgraph), Scene *UNUSED(scene))
{
}
diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c
index 5500918428f..e8f31594cc0 100644
--- a/source/blender/blenkernel/intern/sound.c
+++ b/source/blender/blenkernel/intern/sound.c
@@ -127,6 +127,7 @@ IDTypeInfo IDType_ID_SO = {
.copy_data = sound_copy_data,
.free_data = sound_free_data,
.make_local = NULL,
+ .foreach_id = NULL,
};
#ifdef WITH_AUDASPACE
diff --git a/source/blender/blenkernel/intern/subdiv.c b/source/blender/blenkernel/intern/subdiv.c
index 1f7cb225fc7..fe1dd3835fd 100644
--- a/source/blender/blenkernel/intern/subdiv.c
+++ b/source/blender/blenkernel/intern/subdiv.c
@@ -38,6 +38,18 @@
#include "opensubdiv_evaluator_capi.h"
#include "opensubdiv_topology_refiner_capi.h"
+/* =================----====--===== MODULE ==========================------== */
+
+void BKE_subdiv_init()
+{
+ openSubdiv_init();
+}
+
+void BKE_subdiv_exit()
+{
+ openSubdiv_cleanup();
+}
+
/* ========================== CONVERSION HELPERS ============================ */
eSubdivFVarLinearInterpolation BKE_subdiv_fvar_interpolation_from_uv_smooth(int uv_smooth)
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index c21d640a4c1..7a0a5645b80 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -71,18 +71,13 @@
#include "CCGSubSurf.h"
-#ifdef WITH_OPENSUBDIV
-# include "opensubdiv_capi.h"
-#endif
-
/* assumes MLoop's are laid out 4 for each poly, in order */
#define USE_LOOP_LAYOUT_FAST
static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
int drawInteriorEdges,
int useSubsurfUv,
- DerivedMesh *dm,
- bool use_gpu_backend);
+ DerivedMesh *dm);
///
static void *arena_alloc(CCGAllocatorHDL a, int numBytes)
@@ -404,82 +399,6 @@ static int ss_sync_from_uv(CCGSubSurf *ss, CCGSubSurf *origss, DerivedMesh *dm,
return 1;
}
-#ifdef WITH_OPENSUBDIV
-static void UNUSED_FUNCTION(set_subsurf_osd_ccg_uv)(CCGSubSurf *ss,
- DerivedMesh *dm,
- DerivedMesh *result,
- int layer_index)
-{
- CCGFace **faceMap;
- MTFace *tf;
- MLoopUV *mluv;
- CCGFaceIterator fi;
- int index, gridSize, gridFaces, totface, x, y, S;
- MLoopUV *dmloopuv = CustomData_get_layer_n(&dm->loopData, CD_MLOOPUV, layer_index);
- /* need to update both CD_MTFACE & CD_MLOOPUV, hrmf, we could get away with
- * just tface except applying the modifier then looses subsurf UV */
- MTFace *tface = CustomData_get_layer_n(&result->faceData, CD_MTFACE, layer_index);
- MLoopUV *mloopuv = CustomData_get_layer_n(&result->loopData, CD_MLOOPUV, layer_index);
-
- if (dmloopuv == NULL || (tface == NULL && mloopuv == NULL)) {
- return;
- }
-
- ccgSubSurf_evaluatorSetFVarUV(ss, dm, layer_index);
-
- /* get some info from CCGSubSurf */
- totface = ccgSubSurf_getNumFaces(ss);
- gridSize = ccgSubSurf_getGridSize(ss);
- gridFaces = gridSize - 1;
-
- /* make a map from original faces to CCGFaces */
- faceMap = MEM_mallocN(totface * sizeof(*faceMap), "facemapuv");
- for (ccgSubSurf_initFaceIterator(ss, &fi); !ccgFaceIterator_isStopped(&fi);
- ccgFaceIterator_next(&fi)) {
- CCGFace *f = ccgFaceIterator_getCurrent(&fi);
- faceMap[POINTER_AS_INT(ccgSubSurf_getFaceFaceHandle(f))] = f;
- }
-
- /* load coordinates from uvss into tface */
- tf = tface;
- mluv = mloopuv;
- for (index = 0; index < totface; index++) {
- CCGFace *f = faceMap[index];
- int numVerts = ccgSubSurf_getFaceNumVerts(f);
- for (S = 0; S < numVerts; S++) {
- for (y = 0; y < gridFaces; y++) {
- for (x = 0; x < gridFaces; x++) {
- const int delta[4][2] = {{0, 0}, {0, 1}, {1, 1}, {1, 0}};
- float uv[4][2];
- int i;
- for (i = 0; i < 4; i++) {
- const int dx = delta[i][0], dy = delta[i][1];
- const float grid_u = ((float)(x + dx)) / (gridSize - 1),
- grid_v = ((float)(y + dy)) / (gridSize - 1);
- ccgSubSurf_evaluatorFVarUV(ss, index, S, grid_u, grid_v, uv[i]);
- }
- if (tf) {
- copy_v2_v2(tf->uv[0], uv[0]);
- copy_v2_v2(tf->uv[1], uv[1]);
- copy_v2_v2(tf->uv[2], uv[2]);
- copy_v2_v2(tf->uv[3], uv[3]);
- tf++;
- }
- if (mluv) {
- copy_v2_v2(mluv[0].uv, uv[0]);
- copy_v2_v2(mluv[1].uv, uv[1]);
- copy_v2_v2(mluv[2].uv, uv[2]);
- copy_v2_v2(mluv[3].uv, uv[3]);
- mluv += 4;
- }
- }
- }
- }
- }
- MEM_freeN(faceMap);
-}
-#endif /* WITH_OPENSUBDIV */
-
static void set_subsurf_legacy_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh *result, int n)
{
CCGSubSurf *uvss;
@@ -564,16 +483,7 @@ static void set_subsurf_legacy_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh *
static void set_subsurf_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh *result, int layer_index)
{
-#ifdef WITH_OPENSUBDIV
- if (!ccgSubSurf_needGrids(ss)) {
- /* GPU backend is used, no need to evaluate UVs on CPU. */
- /* TODO(sergey): Think of how to support edit mode of UVs. */
- }
- else
-#endif
- {
- set_subsurf_legacy_uv(ss, dm, result, layer_index);
- }
+ set_subsurf_legacy_uv(ss, dm, result, layer_index);
}
/* face weighting */
@@ -763,40 +673,13 @@ static void ss_sync_ccg_from_derivedmesh(CCGSubSurf *ss,
#endif
}
-#ifdef WITH_OPENSUBDIV
-static void ss_sync_osd_from_derivedmesh(CCGSubSurf *ss, DerivedMesh *dm)
-{
- ccgSubSurf_initFullSync(ss);
- ccgSubSurf_prepareTopologyRefiner(ss, dm);
- ccgSubSurf_processSync(ss);
-}
-#endif /* WITH_OPENSUBDIV */
-
static void ss_sync_from_derivedmesh(CCGSubSurf *ss,
DerivedMesh *dm,
float (*vertexCos)[3],
int use_flat_subdiv,
- bool use_subdiv_uvs)
+ bool UNUSED(use_subdiv_uvs))
{
-#ifndef WITH_OPENSUBDIV
- UNUSED_VARS(use_subdiv_uvs);
-#endif
-
-#ifdef WITH_OPENSUBDIV
- /* Reset all related descriptors if actual mesh topology changed or if
- * other evaluation-related settings changed.
- */
- if (!ccgSubSurf_needGrids(ss)) {
- /* TODO(sergey): Use vertex coordinates and flat subdiv flag. */
- ccgSubSurf__sync_subdivUvs(ss, use_subdiv_uvs);
- ccgSubSurf_checkTopologyChanged(ss, dm);
- ss_sync_osd_from_derivedmesh(ss, dm);
- }
- else
-#endif
- {
- ss_sync_ccg_from_derivedmesh(ss, dm, vertexCos, use_flat_subdiv);
- }
+ ss_sync_ccg_from_derivedmesh(ss, dm, vertexCos, use_flat_subdiv);
}
/***/
@@ -850,13 +733,6 @@ static void UNUSED_FUNCTION(ccgDM_getMinMax)(DerivedMesh *dm, float r_min[3], fl
int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
int gridSize = ccgSubSurf_getGridSize(ss);
-#ifdef WITH_OPENSUBDIV
- if (ccgdm->useGpuBackend) {
- ccgSubSurf_getMinMax(ccgdm->ss, r_min, r_max);
- return;
- }
-#endif
-
CCG_key_top_level(&key, ss);
if (!ccgSubSurf_getNumVerts(ss)) {
@@ -1642,11 +1518,9 @@ static void ccgDM_release(DerivedMesh *dm)
}
MEM_freeN(ccgdm->edgeFlags);
MEM_freeN(ccgdm->faceFlags);
- if (ccgdm->useGpuBackend == false) {
- MEM_freeN(ccgdm->vertMap);
- MEM_freeN(ccgdm->edgeMap);
- MEM_freeN(ccgdm->faceMap);
- }
+ MEM_freeN(ccgdm->vertMap);
+ MEM_freeN(ccgdm->edgeMap);
+ MEM_freeN(ccgdm->faceMap);
BLI_mutex_end(&ccgdm->loops_cache_lock);
BLI_rw_mutex_end(&ccgdm->origindex_cache_rwlock);
@@ -2417,76 +2291,44 @@ static void set_ccgdm_all_geometry(CCGDerivedMesh *ccgdm,
BLI_assert(faceNum == ccgSubSurf_getNumFinalFaces(ss));
}
-/* Fill in only geometry arrays needed for the GPU tessellation. */
-static void set_ccgdm_gpu_geometry(CCGDerivedMesh *ccgdm, DerivedMesh *dm)
-{
- const int totface = dm->getNumPolys(dm);
- MPoly *mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
- int index;
- DMFlagMat *faceFlags = ccgdm->faceFlags;
-
- for (index = 0; index < totface; index++) {
- faceFlags->flag = mpoly ? mpoly[index].flag : 0;
- faceFlags->mat_nr = mpoly ? mpoly[index].mat_nr : 0;
- faceFlags++;
- }
-
- /* TODO(sergey): Fill in edge flags. */
-}
-
-static CCGDerivedMesh *getCCGDerivedMesh(
- CCGSubSurf *ss, int drawInteriorEdges, int useSubsurfUv, DerivedMesh *dm, bool use_gpu_backend)
+static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
+ int drawInteriorEdges,
+ int useSubsurfUv,
+ DerivedMesh *dm)
{
-#ifdef WITH_OPENSUBDIV
- const int totedge = dm->getNumEdges(dm);
- const int totface = dm->getNumPolys(dm);
-#else
const int totedge = ccgSubSurf_getNumEdges(ss);
const int totface = ccgSubSurf_getNumFaces(ss);
-#endif
CCGDerivedMesh *ccgdm = MEM_callocN(sizeof(*ccgdm), "ccgdm");
- if (use_gpu_backend == false) {
- BLI_assert(totedge == ccgSubSurf_getNumEdges(ss));
- BLI_assert(totface == ccgSubSurf_getNumFaces(ss));
- DM_from_template(&ccgdm->dm,
- dm,
- DM_TYPE_CCGDM,
- ccgSubSurf_getNumFinalVerts(ss),
- ccgSubSurf_getNumFinalEdges(ss),
- 0,
- ccgSubSurf_getNumFinalFaces(ss) * 4,
- ccgSubSurf_getNumFinalFaces(ss));
+ BLI_assert(totedge == ccgSubSurf_getNumEdges(ss));
+ BLI_assert(totface == ccgSubSurf_getNumFaces(ss));
+ DM_from_template(&ccgdm->dm,
+ dm,
+ DM_TYPE_CCGDM,
+ ccgSubSurf_getNumFinalVerts(ss),
+ ccgSubSurf_getNumFinalEdges(ss),
+ 0,
+ ccgSubSurf_getNumFinalFaces(ss) * 4,
+ ccgSubSurf_getNumFinalFaces(ss));
- CustomData_free_layer_active(&ccgdm->dm.polyData, CD_NORMAL, ccgdm->dm.numPolyData);
+ CustomData_free_layer_active(&ccgdm->dm.polyData, CD_NORMAL, ccgdm->dm.numPolyData);
- ccgdm->reverseFaceMap = MEM_callocN(sizeof(int) * ccgSubSurf_getNumFinalFaces(ss),
- "reverseFaceMap");
+ ccgdm->reverseFaceMap = MEM_callocN(sizeof(int) * ccgSubSurf_getNumFinalFaces(ss),
+ "reverseFaceMap");
- create_ccgdm_maps(ccgdm, ss);
- }
- else {
- DM_from_template(&ccgdm->dm, dm, DM_TYPE_CCGDM, 0, 0, 0, 0, dm->getNumPolys(dm));
- CustomData_copy_data(&dm->polyData, &ccgdm->dm.polyData, 0, 0, dm->getNumPolys(dm));
- }
+ create_ccgdm_maps(ccgdm, ss);
set_default_ccgdm_callbacks(ccgdm);
ccgdm->ss = ss;
ccgdm->drawInteriorEdges = drawInteriorEdges;
ccgdm->useSubsurfUv = useSubsurfUv;
- ccgdm->useGpuBackend = use_gpu_backend;
/* CDDM hack. */
ccgdm->edgeFlags = MEM_callocN(sizeof(short) * totedge, "edgeFlags");
ccgdm->faceFlags = MEM_callocN(sizeof(DMFlagMat) * totface, "faceFlags");
- if (use_gpu_backend == false) {
- set_ccgdm_all_geometry(ccgdm, ss, dm, useSubsurfUv != 0);
- }
- else {
- set_ccgdm_gpu_geometry(ccgdm, dm);
- }
+ set_ccgdm_all_geometry(ccgdm, ss, dm, useSubsurfUv != 0);
ccgdm->dm.numVertData = ccgSubSurf_getNumFinalVerts(ss);
ccgdm->dm.numEdgeData = ccgSubSurf_getNumFinalEdges(ss);
@@ -2502,21 +2344,6 @@ static CCGDerivedMesh *getCCGDerivedMesh(
/***/
-static bool subsurf_use_gpu_backend(SubsurfFlags flags)
-{
-#ifdef WITH_OPENSUBDIV
- /* Use GPU backend if it's a last modifier in the stack
- * and user chose to use any of the OSD compute devices,
- * but also check if GPU has all needed features.
- */
- return (flags & SUBSURF_USE_GPU_BACKEND) != 0 &&
- (U.opensubdiv_compute_type != USER_OPENSUBDIV_COMPUTE_NONE);
-#else
- (void)flags;
- return false;
-#endif
-}
-
struct DerivedMesh *subsurf_make_derived_from_derived(struct DerivedMesh *dm,
struct SubsurfModifierData *smd,
const struct Scene *scene,
@@ -2527,7 +2354,6 @@ struct DerivedMesh *subsurf_make_derived_from_derived(struct DerivedMesh *dm,
const CCGFlags useAging = (smd->flags & eSubsurfModifierFlag_DebugIncr) ? CCG_USE_AGING : 0;
const int useSubsurfUv = (smd->uv_smooth != SUBSURF_UV_SMOOTH_NONE);
const int drawInteriorEdges = !(smd->flags & eSubsurfModifierFlag_ControlEdges);
- const bool use_gpu_backend = subsurf_use_gpu_backend(flags);
const bool ignore_simplify = (flags & SUBSURF_IGNORE_SIMPLIFY);
CCGDerivedMesh *result;
@@ -2546,11 +2372,8 @@ struct DerivedMesh *subsurf_make_derived_from_derived(struct DerivedMesh *dm,
smd->emCache = _getSubSurf(smd->emCache, levels, 3, useSimple | useAging | CCG_CALC_NORMALS);
-#ifdef WITH_OPENSUBDIV
- ccgSubSurf_setSkipGrids(smd->emCache, use_gpu_backend);
-#endif
ss_sync_from_derivedmesh(smd->emCache, dm, vertCos, useSimple, useSubsurfUv);
- result = getCCGDerivedMesh(smd->emCache, drawInteriorEdges, useSubsurfUv, dm, use_gpu_backend);
+ result = getCCGDerivedMesh(smd->emCache, drawInteriorEdges, useSubsurfUv, dm);
}
else if (flags & SUBSURF_USE_RENDER_PARAMS) {
/* Do not use cache in render mode. */
@@ -2567,7 +2390,7 @@ struct DerivedMesh *subsurf_make_derived_from_derived(struct DerivedMesh *dm,
ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple, useSubsurfUv);
- result = getCCGDerivedMesh(ss, drawInteriorEdges, useSubsurfUv, dm, false);
+ result = getCCGDerivedMesh(ss, drawInteriorEdges, useSubsurfUv, dm);
result->freeSS = 1;
}
@@ -2600,32 +2423,15 @@ struct DerivedMesh *subsurf_make_derived_from_derived(struct DerivedMesh *dm,
ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple, useSubsurfUv);
- result = getCCGDerivedMesh(smd->mCache, drawInteriorEdges, useSubsurfUv, dm, false);
+ result = getCCGDerivedMesh(smd->mCache, drawInteriorEdges, useSubsurfUv, dm);
}
else {
CCGFlags ccg_flags = useSimple | CCG_USE_ARENA | CCG_CALC_NORMALS;
CCGSubSurf *prevSS = NULL;
if (smd->mCache && (flags & SUBSURF_IS_FINAL_CALC)) {
-#ifdef WITH_OPENSUBDIV
- /* With OpenSubdiv enabled we always tries to re-use previous
- * subsurf structure in order to save computation time since
- * re-creation is rather a complicated business.
- *
- * TODO(sergey): There was a good reason why final calculation
- * used to free entirely cached subsurf structure. reason of
- * this is to be investigated still to be sure we don't have
- * regressions here.
- */
- if (use_gpu_backend) {
- prevSS = smd->mCache;
- }
- else
-#endif
- {
- ccgSubSurf_free(smd->mCache);
- smd->mCache = NULL;
- }
+ ccgSubSurf_free(smd->mCache);
+ smd->mCache = NULL;
}
if (flags & SUBSURF_ALLOC_PAINT_MASK) {
@@ -2633,12 +2439,9 @@ struct DerivedMesh *subsurf_make_derived_from_derived(struct DerivedMesh *dm,
}
ss = _getSubSurf(prevSS, levels, 3, ccg_flags);
-#ifdef WITH_OPENSUBDIV
- ccgSubSurf_setSkipGrids(ss, use_gpu_backend);
-#endif
ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple, useSubsurfUv);
- result = getCCGDerivedMesh(ss, drawInteriorEdges, useSubsurfUv, dm, use_gpu_backend);
+ result = getCCGDerivedMesh(ss, drawInteriorEdges, useSubsurfUv, dm);
if (flags & SUBSURF_IS_FINAL_CALC) {
smd->mCache = ss;
@@ -2710,26 +2513,10 @@ void subsurf_calculate_limit_positions(Mesh *me, float (*r_positions)[3])
bool subsurf_has_edges(DerivedMesh *dm)
{
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
-#ifdef WITH_OPENSUBDIV
- if (ccgdm->useGpuBackend) {
- return true;
- }
-#else
- (void)ccgdm;
-#endif
return dm->getNumEdges(dm) != 0;
}
bool subsurf_has_faces(DerivedMesh *dm)
{
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
-#ifdef WITH_OPENSUBDIV
- if (ccgdm->useGpuBackend) {
- return true;
- }
-#else
- (void)ccgdm;
-#endif
return dm->getNumPolys(dm) != 0;
}
diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c
index 3cdf3b40ce3..527b54a1aa2 100644
--- a/source/blender/blenkernel/intern/text.c
+++ b/source/blender/blenkernel/intern/text.c
@@ -206,6 +206,7 @@ IDTypeInfo IDType_ID_TXT = {
.copy_data = text_copy_data,
.free_data = text_free_data,
.make_local = NULL,
+ .foreach_id = NULL,
};
/***/
diff --git a/source/blender/blenkernel/intern/tracking_stabilize.c b/source/blender/blenkernel/intern/tracking_stabilize.c
index dffc703c943..e09e92588c6 100644
--- a/source/blender/blenkernel/intern/tracking_stabilize.c
+++ b/source/blender/blenkernel/intern/tracking_stabilize.c
@@ -42,6 +42,7 @@
#include "BKE_movieclip.h"
#include "BKE_tracking.h"
+#include "IMB_colormanagement.h"
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
#include "MEM_guardedalloc.h"
@@ -1399,7 +1400,7 @@ ImBuf *BKE_tracking_stabilize_frame(
return ibuf;
}
- /* Allocate frame for stabilization result. */
+ /* Allocate frame for stabilization result, copy alpha mode and colorspace. */
ibuf_flags = 0;
if (ibuf->rect) {
ibuf_flags |= IB_rect;
@@ -1409,6 +1410,7 @@ ImBuf *BKE_tracking_stabilize_frame(
}
tmpibuf = IMB_allocImBuf(ibuf->x, ibuf->y, ibuf->planes, ibuf_flags);
+ IMB_colormanagegent_copy_settings(ibuf, tmpibuf);
/* Calculate stabilization matrix. */
BKE_tracking_stabilization_data_get(clip, framenr, width, height, tloc, &tscale, &tangle);
diff --git a/source/blender/blenkernel/intern/tracking_util.c b/source/blender/blenkernel/intern/tracking_util.c
index 629c01ec298..dcaa9082026 100644
--- a/source/blender/blenkernel/intern/tracking_util.c
+++ b/source/blender/blenkernel/intern/tracking_util.c
@@ -713,7 +713,7 @@ static ImBuf *make_grayscale_ibuf_copy(ImBuf *ibuf)
*/
const size_t size = (size_t)grayscale->x * (size_t)grayscale->y * sizeof(float);
grayscale->channels = 1;
- if ((grayscale->rect_float = MEM_mapallocN(size, "tracking grayscale image")) != NULL) {
+ if ((grayscale->rect_float = MEM_callocN(size, "tracking grayscale image")) != NULL) {
grayscale->mall |= IB_rectfloat;
grayscale->flags |= IB_rectfloat;
@@ -741,7 +741,7 @@ static ImBuf *float_image_to_ibuf(libmv_FloatImage *float_image)
ImBuf *ibuf = IMB_allocImBuf(float_image->width, float_image->height, 32, 0);
size_t size = (size_t)ibuf->x * (size_t)ibuf->y * float_image->channels * sizeof(float);
ibuf->channels = float_image->channels;
- if ((ibuf->rect_float = MEM_mapallocN(size, "tracking grayscale image")) != NULL) {
+ if ((ibuf->rect_float = MEM_callocN(size, "tracking grayscale image")) != NULL) {
ibuf->mall |= IB_rectfloat;
ibuf->flags |= IB_rectfloat;
diff --git a/source/blender/blenkernel/intern/volume.cc b/source/blender/blenkernel/intern/volume.cc
index 9e636c0ee8b..26c5810aefa 100644
--- a/source/blender/blenkernel/intern/volume.cc
+++ b/source/blender/blenkernel/intern/volume.cc
@@ -21,6 +21,7 @@
#include "MEM_guardedalloc.h"
#include "DNA_defaults.h"
+#include "DNA_material_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_volume_types.h"
@@ -442,26 +443,6 @@ static void volume_init_data(ID *id)
BKE_volume_init_grids(volume);
}
-void BKE_volume_init_grids(Volume *volume)
-{
-#ifdef WITH_OPENVDB
- if (volume->runtime.grids == NULL) {
- volume->runtime.grids = OBJECT_GUARDED_NEW(VolumeGridVector);
- }
-#else
- UNUSED_VARS(volume);
-#endif
-}
-
-void *BKE_volume_add(Main *bmain, const char *name)
-{
- Volume *volume = (Volume *)BKE_libblock_alloc(bmain, ID_VO, name, 0);
-
- volume_init_data(&volume->id);
-
- return volume;
-}
-
static void volume_copy_data(Main *UNUSED(bmain),
ID *id_dst,
const ID *id_src,
@@ -483,18 +464,6 @@ static void volume_copy_data(Main *UNUSED(bmain),
#endif
}
-Volume *BKE_volume_copy(Main *bmain, const Volume *volume)
-{
- Volume *volume_copy;
- BKE_id_copy(bmain, &volume->id, (ID **)&volume_copy);
- return volume_copy;
-}
-
-static void volume_make_local(Main *bmain, ID *id, const int flags)
-{
- BKE_lib_id_make_local_generic(bmain, id, flags);
-}
-
static void volume_free_data(ID *id)
{
Volume *volume = (Volume *)id;
@@ -506,6 +475,14 @@ static void volume_free_data(ID *id)
#endif
}
+static void volume_foreach_id(ID *id, LibraryForeachIDData *data)
+{
+ Volume *volume = (Volume *)id;
+ for (int i = 0; i < volume->totcol; i++) {
+ BKE_LIB_FOREACHID_PROCESS(data, volume->mat[i], IDWALK_CB_USER);
+ }
+}
+
IDTypeInfo IDType_ID_VO = {
/* id_code */ ID_VO,
/* id_filter */ FILTER_ID_VO,
@@ -519,9 +496,37 @@ IDTypeInfo IDType_ID_VO = {
/* init_data */ volume_init_data,
/* copy_data */ volume_copy_data,
/* free_data */ volume_free_data,
- /* make_local */ volume_make_local,
+ /* make_local */ nullptr,
+ /* foreach_id */ volume_foreach_id,
};
+void BKE_volume_init_grids(Volume *volume)
+{
+#ifdef WITH_OPENVDB
+ if (volume->runtime.grids == NULL) {
+ volume->runtime.grids = OBJECT_GUARDED_NEW(VolumeGridVector);
+ }
+#else
+ UNUSED_VARS(volume);
+#endif
+}
+
+void *BKE_volume_add(Main *bmain, const char *name)
+{
+ Volume *volume = (Volume *)BKE_libblock_alloc(bmain, ID_VO, name, 0);
+
+ volume_init_data(&volume->id);
+
+ return volume;
+}
+
+Volume *BKE_volume_copy(Main *bmain, const Volume *volume)
+{
+ Volume *volume_copy;
+ BKE_id_copy(bmain, &volume->id, (ID **)&volume_copy);
+ return volume_copy;
+}
+
/* Sequence */
static int volume_sequence_frame(const Depsgraph *depsgraph, const Volume *volume)
diff --git a/source/blender/blenkernel/intern/workspace.c b/source/blender/blenkernel/intern/workspace.c
index c65d55785c1..3a69b95c114 100644
--- a/source/blender/blenkernel/intern/workspace.c
+++ b/source/blender/blenkernel/intern/workspace.c
@@ -32,6 +32,7 @@
#include "BKE_idprop.h"
#include "BKE_idtype.h"
#include "BKE_lib_id.h"
+#include "BKE_lib_query.h"
#include "BKE_main.h"
#include "BKE_object.h"
#include "BKE_scene.h"
@@ -65,6 +66,23 @@ static void workspace_free_data(ID *id)
MEM_SAFE_FREE(workspace->status_text);
}
+static void workspace_foreach_id(ID *id, LibraryForeachIDData *data)
+{
+ WorkSpace *workspace = (WorkSpace *)id;
+ ListBase *layouts = BKE_workspace_layouts_get(workspace);
+
+ LISTBASE_FOREACH (WorkSpaceLayout *, layout, layouts) {
+ bScreen *screen = BKE_workspace_layout_screen_get(layout);
+
+ /* CALLBACK_INVOKE expects an actual pointer, not a variable holding the pointer.
+ * However we can't access layout->screen here
+ * since we are outside the workspace project. */
+ BKE_LIB_FOREACHID_PROCESS(data, screen, IDWALK_CB_USER);
+ /* allow callback to set a different screen */
+ BKE_workspace_layout_screen_set(layout, screen);
+ }
+}
+
IDTypeInfo IDType_ID_WS = {
.id_code = ID_WS,
.id_filter = FILTER_ID_WS,
@@ -79,6 +97,7 @@ IDTypeInfo IDType_ID_WS = {
.copy_data = NULL,
.free_data = workspace_free_data,
.make_local = NULL,
+ .foreach_id = workspace_foreach_id,
};
/** \name Internal Utils
diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c
index 16e56200131..724c4ab93b2 100644
--- a/source/blender/blenkernel/intern/writeffmpeg.c
+++ b/source/blender/blenkernel/intern/writeffmpeg.c
@@ -606,7 +606,10 @@ static AVStream *alloc_video_stream(FFMpegContext *context,
c->gop_size = context->ffmpeg_gop_size;
c->max_b_frames = context->ffmpeg_max_b_frames;
- if (context->ffmpeg_crf >= 0) {
+ if (context->ffmpeg_type == FFMPEG_WEBM && context->ffmpeg_crf == 0) {
+ ffmpeg_dict_set_int(&opts, "lossless", 1);
+ }
+ else if (context->ffmpeg_crf >= 0) {
ffmpeg_dict_set_int(&opts, "crf", context->ffmpeg_crf);
}
else {
diff --git a/source/blender/blenlib/BLI_threads.h b/source/blender/blenlib/BLI_threads.h
index c199417017b..03fe27c10ed 100644
--- a/source/blender/blenlib/BLI_threads.h
+++ b/source/blender/blenlib/BLI_threads.h
@@ -58,9 +58,6 @@ void BLI_threadpool_clear(struct ListBase *threadbase);
void BLI_threadpool_end(struct ListBase *threadbase);
int BLI_thread_is_main(void);
-void BLI_threaded_malloc_begin(void);
-void BLI_threaded_malloc_end(void);
-
/* System Information */
int BLI_system_thread_count(void); /* gets the number of threads the system can make use of */
diff --git a/source/blender/blenlib/BLI_vector_set.hh b/source/blender/blenlib/BLI_vector_set.hh
index 9f887513816..f402f47c357 100644
--- a/source/blender/blenlib/BLI_vector_set.hh
+++ b/source/blender/blenlib/BLI_vector_set.hh
@@ -140,7 +140,7 @@ template<typename T, typename Allocator = GuardedAllocator> class VectorSet {
VectorSet(const VectorSet &other) : m_array(other.m_array)
{
m_elements = this->allocate_elements_array(m_array.slots_usable());
- copy_n(other.m_elements, m_array.slots_set(), m_elements);
+ uninitialized_copy_n(other.m_elements, m_array.slots_set(), m_elements);
}
VectorSet(VectorSet &&other) : m_array(std::move(other.m_array)), m_elements(other.m_elements)
diff --git a/source/blender/blenlib/intern/boxpack_2d.c b/source/blender/blenlib/intern/boxpack_2d.c
index 6ecadeecec5..83866f766df 100644
--- a/source/blender/blenlib/intern/boxpack_2d.c
+++ b/source/blender/blenlib/intern/boxpack_2d.c
@@ -705,7 +705,7 @@ void BLI_box_pack_2d_fixedarea(ListBase *boxes, int width, int height, ListBase
LISTBASE_FOREACH_MUTABLE (FixedSizeBoxPack *, box, boxes) {
LISTBASE_FOREACH (FixedSizeBoxPack *, space, &spaces) {
/* Skip this space if it's too small. */
- if (box->w > space->w || box->h > space->w) {
+ if (box->w > space->w || box->h > space->h) {
continue;
}
diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c
index 154fc966ca2..87536ea8116 100644
--- a/source/blender/blenlib/intern/storage.c
+++ b/source/blender/blenlib/intern/storage.c
@@ -233,8 +233,9 @@ eFileAttributes BLI_file_attributes(const char *path)
# ifdef WIN32
WCHAR wline[FILE_MAXDIR];
- size_t bsize = count_utf_16_from_8(path);
- conv_utf_8_to_16(path, wline, bsize);
+ if (conv_utf_8_to_16(path, wline, ARRAY_SIZE(wline)) != 0) {
+ return ret;
+ }
DWORD attr = GetFileAttributesW(wline);
if (attr & FILE_ATTRIBUTE_READONLY) {
ret |= FILE_ATTR_READONLY;
diff --git a/source/blender/blenlib/intern/task_pool.cc b/source/blender/blenlib/intern/task_pool.cc
index 670787697a3..cf328ec407c 100644
--- a/source/blender/blenlib/intern/task_pool.cc
+++ b/source/blender/blenlib/intern/task_pool.cc
@@ -364,14 +364,6 @@ static void background_task_pool_free(TaskPool *pool)
static TaskPool *task_pool_create_ex(void *userdata, TaskPoolType type, TaskPriority priority)
{
- /* Ensure malloc will go fine from threads,
- *
- * This is needed because we could be in main thread here
- * and malloc could be non-thread safe at this point because
- * no other jobs are running.
- */
- BLI_threaded_malloc_begin();
-
const bool use_threads = BLI_task_scheduler_num_threads() > 1 && type != TASK_POOL_NO_THREADS;
/* Background task pool uses regular TBB scheduling if available. Only when
@@ -475,8 +467,6 @@ void BLI_task_pool_free(TaskPool *pool)
BLI_mutex_end(&pool->user_mutex);
MEM_freeN(pool);
-
- BLI_threaded_malloc_end();
}
void BLI_task_pool_push(TaskPool *pool,
diff --git a/source/blender/blenlib/intern/task_range.cc b/source/blender/blenlib/intern/task_range.cc
index 55de35f0060..67d8960434e 100644
--- a/source/blender/blenlib/intern/task_range.cc
+++ b/source/blender/blenlib/intern/task_range.cc
@@ -128,7 +128,6 @@ void BLI_task_parallel_range(const int start,
else {
parallel_for(range, task);
}
-
return;
}
#endif
diff --git a/source/blender/blenlib/intern/threads.c b/source/blender/blenlib/intern/threads.c
index f535798f86d..be43c27e945 100644
--- a/source/blender/blenlib/intern/threads.c
+++ b/source/blender/blenlib/intern/threads.c
@@ -104,7 +104,6 @@ static void *thread_tls_data;
* BLI_threadpool_end(&lb);
*
************************************************ */
-static SpinLock _malloc_lock;
static pthread_mutex_t _image_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t _image_draw_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t _viewer_lock = PTHREAD_MUTEX_INITIALIZER;
@@ -132,21 +131,9 @@ typedef struct ThreadSlot {
int avail;
} ThreadSlot;
-static void BLI_lock_malloc_thread(void)
-{
- BLI_spin_lock(&_malloc_lock);
-}
-
-static void BLI_unlock_malloc_thread(void)
-{
- BLI_spin_unlock(&_malloc_lock);
-}
-
void BLI_threadapi_init(void)
{
mainid = pthread_self();
-
- BLI_spin_init(&_malloc_lock);
if (numaAPI_Initialize() == NUMAAPI_SUCCESS) {
is_numa_available = true;
}
@@ -154,7 +141,6 @@ void BLI_threadapi_init(void)
void BLI_threadapi_exit(void)
{
- BLI_spin_end(&_malloc_lock);
}
/* tot = 0 only initializes malloc mutex in a safe way (see sequence.c)
@@ -185,8 +171,6 @@ void BLI_threadpool_init(ListBase *threadbase, void *(*do_thread)(void *), int t
unsigned int level = atomic_fetch_and_add_u(&thread_levels, 1);
if (level == 0) {
- MEM_set_lock_callback(BLI_lock_malloc_thread, BLI_unlock_malloc_thread);
-
#ifdef USE_APPLE_OMP_FIX
/* workaround for Apple gcc 4.2.1 omp vs background thread bug,
* we copy gomp thread local storage pointer to setting it again
@@ -313,11 +297,6 @@ void BLI_threadpool_end(ListBase *threadbase)
}
BLI_freelistN(threadbase);
}
-
- unsigned int level = atomic_sub_and_fetch_u(&thread_levels, 1);
- if (level == 0) {
- MEM_set_lock_callback(NULL, NULL);
- }
}
/* System Information */
@@ -811,24 +790,6 @@ void BLI_thread_queue_wait_finish(ThreadQueue *queue)
pthread_mutex_unlock(&queue->mutex);
}
-/* ************************************************ */
-
-void BLI_threaded_malloc_begin(void)
-{
- unsigned int level = atomic_fetch_and_add_u(&thread_levels, 1);
- if (level == 0) {
- MEM_set_lock_callback(BLI_lock_malloc_thread, BLI_unlock_malloc_thread);
- }
-}
-
-void BLI_threaded_malloc_end(void)
-{
- unsigned int level = atomic_sub_and_fetch_u(&thread_levels, 1);
- if (level == 0) {
- MEM_set_lock_callback(NULL, NULL);
- }
-}
-
/* **** Special functions to help performance on crazy NUMA setups. **** */
#if 0 /* UNUSED */
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 9cbe6056dc4..b661a1e7696 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -2721,7 +2721,7 @@ static void lib_link_id(FileData *fd, Main *bmain, ID *id);
static void lib_link_nodetree(FileData *fd, Main *bmain, bNodeTree *ntree);
static void lib_link_collection(FileData *fd, Main *bmain, Collection *collection);
-static void lib_link_id_private_id(FileData *fd, Main *bmain, ID *id)
+static void lib_link_id_embedded_id(FileData *fd, Main *bmain, ID *id)
{
/* Handle 'private IDs'. */
bNodeTree *nodetree = ntreeFromID(id);
@@ -2755,7 +2755,7 @@ static void lib_link_id(FileData *fd, Main *bmain, ID *id)
id->override_library->storage = newlibadr(fd, id->lib, id->override_library->storage);
}
- lib_link_id_private_id(fd, bmain, id);
+ lib_link_id_embedded_id(fd, bmain, id);
}
static void direct_link_id_override_property_operation_cb(FileData *fd, void *data)
@@ -2779,18 +2779,22 @@ static void direct_link_id_override_property_cb(FileData *fd, void *data)
link_list_ex(fd, &op->operations, direct_link_id_override_property_operation_cb);
}
-static void direct_link_id_common(FileData *fd, ID *id, ID *id_old, const int tag);
+static void direct_link_id_common(
+ FileData *fd, Library *current_library, ID *id, ID *id_old, const int tag);
static void direct_link_nodetree(FileData *fd, bNodeTree *ntree);
static void direct_link_collection(FileData *fd, Collection *collection);
-static void direct_link_id_private_id(FileData *fd, ID *id, ID *id_old)
+static void direct_link_id_embedded_id(FileData *fd, Library *current_library, ID *id, ID *id_old)
{
/* Handle 'private IDs'. */
bNodeTree **nodetree = BKE_ntree_ptr_from_id(id);
if (nodetree != NULL && *nodetree != NULL) {
*nodetree = newdataadr(fd, *nodetree);
- direct_link_id_common(
- fd, (ID *)*nodetree, id_old != NULL ? (ID *)ntreeFromID(id_old) : NULL, 0);
+ direct_link_id_common(fd,
+ current_library,
+ (ID *)*nodetree,
+ id_old != NULL ? (ID *)ntreeFromID(id_old) : NULL,
+ 0);
direct_link_nodetree(fd, *nodetree);
}
@@ -2799,6 +2803,7 @@ static void direct_link_id_private_id(FileData *fd, ID *id, ID *id_old)
if (scene->master_collection != NULL) {
scene->master_collection = newdataadr(fd, scene->master_collection);
direct_link_id_common(fd,
+ current_library,
&scene->master_collection->id,
id_old != NULL ? &((Scene *)id_old)->master_collection->id : NULL,
0);
@@ -2863,18 +2868,40 @@ static int direct_link_id_restore_recalc(const FileData *fd,
return recalc;
}
-static void direct_link_id_common(FileData *fd, ID *id, ID *id_old, const int tag)
+static void direct_link_id_common(
+ FileData *fd, Library *current_library, ID *id, ID *id_old, const int tag)
{
+ if (fd->memfile == NULL) {
+ /* When actually reading a file , we do want to reset/re-generate session uuids.
+ * In undo case, we want to re-use existing ones. */
+ id->session_uuid = MAIN_ID_SESSION_UUID_UNSET;
+ }
+
+ BKE_lib_libblock_session_uuid_ensure(id);
+
+ id->lib = current_library;
+ id->us = ID_FAKE_USERS(id);
+ id->icon_id = 0;
+ id->newid = NULL; /* Needed because .blend may have been saved with crap value here... */
+ id->orig_id = NULL;
+ id->py_instance = NULL;
+
+ /* Initialize with provided tag. */
+ id->tag = tag;
+
+ if (tag & LIB_TAG_ID_LINK_PLACEHOLDER) {
+ /* For placeholder we only need to set the tag and properly init generic ID fieds above, no
+ * further data to read. */
+ return;
+ }
+
/*link direct data of ID properties*/
if (id->properties) {
id->properties = newdataadr(fd, id->properties);
/* this case means the data was written incorrectly, it should not happen */
IDP_DirectLinkGroup_OrFree(&id->properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
}
- id->py_instance = NULL;
- /* Initialize with provided tag. */
- id->tag = tag;
id->flag &= ~LIB_INDIRECT_WEAK_LINK;
/* NOTE: It is important to not clear the recalc flags for undo/redo.
@@ -2907,7 +2934,7 @@ static void direct_link_id_common(FileData *fd, ID *id, ID *id_old, const int ta
}
/* Handle 'private IDs'. */
- direct_link_id_private_id(fd, id, id_old);
+ direct_link_id_embedded_id(fd, current_library, id, id_old);
}
/** \} */
@@ -8177,23 +8204,9 @@ static void lib_link_workspace_layout_restore(struct IDNameLib_Map *id_map,
LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
if (sl->spacetype == SPACE_VIEW3D) {
View3D *v3d = (View3D *)sl;
- ARegion *region;
v3d->camera = restore_pointer_by_name(id_map, (ID *)v3d->camera, USER_REAL);
v3d->ob_center = restore_pointer_by_name(id_map, (ID *)v3d->ob_center, USER_REAL);
-
- /* Free render engines for now. */
- ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase :
- &sl->regionbase;
- for (region = regionbase->first; region; region = region->next) {
- if (region->regiontype == RGN_TYPE_WINDOW) {
- RegionView3D *rv3d = region->regiondata;
- if (rv3d && rv3d->render_engine) {
- RE_engine_free(rv3d->render_engine);
- rv3d->render_engine = NULL;
- }
- }
- }
}
else if (sl->spacetype == SPACE_GRAPH) {
SpaceGraph *sipo = (SpaceGraph *)sl;
@@ -9361,19 +9374,8 @@ static const char *dataname(short id_code)
static bool direct_link_id(FileData *fd, Main *main, const int tag, ID *id, ID *id_old)
{
- if (fd->memfile == NULL) {
- /* When actually reading a file , we do want to reset/re-generate session uuids.
- * In undo case, we want to re-use existing ones. */
- id->session_uuid = MAIN_ID_SESSION_UUID_UNSET;
- }
-
- BKE_lib_libblock_session_uuid_ensure(id);
-
- id->lib = main->curlib;
- id->us = ID_FAKE_USERS(id);
- id->icon_id = 0;
- id->newid = NULL; /* Needed because .blend may have been saved with crap value here... */
- id->orig_id = NULL;
+ /* Read part of datablock that is common between real and embedded datablocks. */
+ direct_link_id_common(fd, main->curlib, id, id_old, tag);
if (tag & LIB_TAG_ID_LINK_PLACEHOLDER) {
/* For placeholder we only need to set the tag, no further data to read. */
@@ -9381,9 +9383,6 @@ static bool direct_link_id(FileData *fd, Main *main, const int tag, ID *id, ID *
return true;
}
- /* Read part of datablock that is common between real and embedded datablocks. */
- direct_link_id_common(fd, id, id_old, tag);
-
/* XXX Very weakly handled currently, see comment in read_libblock() before trying to
* use it for anything new. */
bool success = true;
@@ -9634,7 +9633,8 @@ static void read_libblock_undo_restore_identical(
BLI_assert((fd->skip_flags & BLO_READ_SKIP_UNDO_OLD_MAIN) == 0);
BLI_assert(id_old != NULL);
- id_old->tag = tag;
+ /* Some tags need to be preserved here. */
+ id_old->tag = tag | (id_old->tag & LIB_TAG_EXTRAUSER);
id_old->lib = main->curlib;
id_old->us = ID_FAKE_USERS(id_old);
/* Do not reset id->icon_id here, memory allocated for it remains valid. */
@@ -10920,7 +10920,7 @@ static void expand_id(FileData *fd, Main *mainvar, ID *id);
static void expand_nodetree(FileData *fd, Main *mainvar, bNodeTree *ntree);
static void expand_collection(FileData *fd, Main *mainvar, Collection *collection);
-static void expand_id_private_id(FileData *fd, Main *mainvar, ID *id)
+static void expand_id_embedded_id(FileData *fd, Main *mainvar, ID *id)
{
/* Handle 'private IDs'. */
bNodeTree *nodetree = ntreeFromID(id);
@@ -10952,7 +10952,7 @@ static void expand_id(FileData *fd, Main *mainvar, ID *id)
expand_animdata(fd, mainvar, adt);
}
- expand_id_private_id(fd, mainvar, id);
+ expand_id_embedded_id(fd, mainvar, id);
}
static void expand_action(FileData *fd, Main *mainvar, bAction *act)
diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c
index 07551f3ea2b..e32a40e1ad5 100644
--- a/source/blender/blenloader/intern/versioning_280.c
+++ b/source/blender/blenloader/intern/versioning_280.c
@@ -5192,6 +5192,15 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
}
}
+
+ /* Set Brush default color for grease pencil. */
+ LISTBASE_FOREACH (Brush *, brush, &bmain->brushes) {
+ if (brush->gpencil_settings) {
+ brush->rgb[0] = 0.498f;
+ brush->rgb[1] = 1.0f;
+ brush->rgb[2] = 0.498f;
+ }
+ }
}
/**
diff --git a/source/blender/blenloader/intern/versioning_defaults.c b/source/blender/blenloader/intern/versioning_defaults.c
index a00cef745e5..665771cce1e 100644
--- a/source/blender/blenloader/intern/versioning_defaults.c
+++ b/source/blender/blenloader/intern/versioning_defaults.c
@@ -202,6 +202,8 @@ static void blo_update_defaults_screen(bScreen *screen,
if (v3d->shading.background_type != V3D_SHADING_BACKGROUND_VIEWPORT) {
copy_v3_fl(v3d->shading.background_color, 0.05f);
}
+ /* Disable Curve Normals. */
+ v3d->overlay.edit_flag &= ~V3D_OVERLAY_EDIT_CU_NORMALS;
}
else if (area->spacetype == SPACE_CLIP) {
SpaceClip *sclip = area->spacedata.first;
@@ -463,7 +465,7 @@ void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template)
/* Reset all grease pencil brushes. */
Scene *scene = bmain->scenes.first;
- BKE_brush_gpencil_paint_presets(bmain, scene->toolsettings);
+ BKE_brush_gpencil_paint_presets(bmain, scene->toolsettings, true);
/* Ensure new Paint modes. */
BKE_paint_ensure_from_paintmode(scene, PAINT_MODE_VERTEX_GPENCIL);
diff --git a/source/blender/bmesh/intern/bmesh_mesh_conv.c b/source/blender/bmesh/intern/bmesh_mesh_conv.c
index de32d7881b0..b8508f7e12c 100644
--- a/source/blender/bmesh/intern/bmesh_mesh_conv.c
+++ b/source/blender/bmesh/intern/bmesh_mesh_conv.c
@@ -893,6 +893,10 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
j = bm_to_mesh_shape_layer_index_from_kb(bm, currkey);
cd_shape_offset = CustomData_get_n_offset(&bm->vdata, CD_SHAPEKEY, j);
+ if (cd_shape_offset < 0) {
+ /* The target Mesh has more shapekeys than the BMesh. */
+ continue;
+ }
fp = newkey = MEM_callocN(me->key->elemsize * bm->totvert, "currkey->data");
oldkey = currkey->data;
diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c
index 255a52971bb..04cdc0020d9 100644
--- a/source/blender/bmesh/intern/bmesh_opdefines.c
+++ b/source/blender/bmesh/intern/bmesh_opdefines.c
@@ -122,6 +122,11 @@ static BMO_FlagSet bmo_enum_falloff_type[] = {
{0, NULL},
};
+/* Quiet 'enum-conversion' warning. */
+#define BM_FACE ((int)BM_FACE)
+#define BM_EDGE ((int)BM_EDGE)
+#define BM_VERT ((int)BM_VERT)
+
/*
* Vertex Smooth.
*
@@ -2074,6 +2079,10 @@ static BMOpDefine bmo_symmetrize_def = {
/* clang-format on */
+#undef BM_FACE
+#undef BM_EDGE
+#undef BM_VERT
+
const BMOpDefine *bmo_opdefines[] = {
&bmo_average_vert_facedata_def,
&bmo_beautify_fill_def,
diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c
index d1ddceb00b0..720eb34bda7 100644
--- a/source/blender/bmesh/tools/bmesh_bevel.c
+++ b/source/blender/bmesh/tools/bmesh_bevel.c
@@ -4167,6 +4167,10 @@ static int tri_corner_test(BevelParams *bp, BevVert *bv)
if (bv->vmesh->count != 3) {
return 0;
}
+
+ /* Only use the tri-corner special case if the offset is the same for every edge. */
+ float offset = bv->edges[0].offset_l;
+
totang = 0.0f;
for (i = 0; i < bv->edgecount; i++) {
e = &bv->edges[i];
@@ -4178,6 +4182,11 @@ static int tri_corner_test(BevelParams *bp, BevVert *bv)
else if (absang >= 3.0f * (float)M_PI_4) {
return -1;
}
+
+ if (e->is_bev && !compare_ff(e->offset_l, offset, BEVEL_EPSILON)) {
+ return -1;
+ }
+
totang += ang;
}
if (in_plane_e != bv->edgecount - 3) {
diff --git a/source/blender/compositor/operations/COM_VectorBlurOperation.cpp b/source/blender/compositor/operations/COM_VectorBlurOperation.cpp
index 7a34c84827e..ee1bb0739b9 100644
--- a/source/blender/compositor/operations/COM_VectorBlurOperation.cpp
+++ b/source/blender/compositor/operations/COM_VectorBlurOperation.cpp
@@ -570,15 +570,15 @@ void zbuf_accumulate_vecblur(NodeBlurData *nbd,
zspan.zofsy = 0.0f;
/* the buffers */
- rectz = (float *)MEM_mapallocN(sizeof(float) * xsize * ysize, "zbuf accum");
+ rectz = (float *)MEM_callocN(sizeof(float) * xsize * ysize, "zbuf accum");
zspan.rectz = (int *)rectz;
- rectmove = (char *)MEM_mapallocN(xsize * ysize, "rectmove");
- rectdraw = (DrawBufPixel *)MEM_mapallocN(sizeof(DrawBufPixel) * xsize * ysize, "rect draw");
+ rectmove = (char *)MEM_callocN(xsize * ysize, "rectmove");
+ rectdraw = (DrawBufPixel *)MEM_callocN(sizeof(DrawBufPixel) * xsize * ysize, "rect draw");
zspan.rectdraw = rectdraw;
- rectweight = (float *)MEM_mapallocN(sizeof(float) * xsize * ysize, "rect weight");
- rectmax = (float *)MEM_mapallocN(sizeof(float) * xsize * ysize, "rect max");
+ rectweight = (float *)MEM_callocN(sizeof(float) * xsize * ysize, "rect weight");
+ rectmax = (float *)MEM_callocN(sizeof(float) * xsize * ysize, "rect max");
/* debug... check if PASS_VECTOR_MAX still is in buffers */
dvec1 = vecbufrect;
@@ -597,7 +597,7 @@ void zbuf_accumulate_vecblur(NodeBlurData *nbd,
float minspeed = (float)nbd->minspeed;
float minspeedsq = minspeed * minspeed;
- minvecbufrect = (float *)MEM_mapallocN(4 * sizeof(float) * xsize * ysize, "minspeed buf");
+ minvecbufrect = (float *)MEM_callocN(4 * sizeof(float) * xsize * ysize, "minspeed buf");
dvec1 = vecbufrect;
dvec2 = minvecbufrect;
@@ -623,7 +623,7 @@ void zbuf_accumulate_vecblur(NodeBlurData *nbd,
}
/* make vertex buffer with averaged speed and zvalues */
- rectvz = (float *)MEM_mapallocN(4 * sizeof(float) * (xsize + 1) * (ysize + 1), "vertices");
+ rectvz = (float *)MEM_callocN(4 * sizeof(float) * (xsize + 1) * (ysize + 1), "vertices");
dvz = rectvz;
for (y = 0; y <= ysize; y++) {
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
index 44ddd9522e0..f76af5bdda5 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
@@ -83,6 +83,7 @@
#include "BKE_key.h"
#include "BKE_lattice.h"
#include "BKE_layer.h"
+#include "BKE_light.h"
#include "BKE_mask.h"
#include "BKE_material.h"
#include "BKE_mball.h"
@@ -1402,7 +1403,11 @@ void DepsgraphNodeBuilder::build_armature(bArmature *armature)
build_animdata(&armature->id);
build_parameters(&armature->id);
/* Make sure pose is up-to-date with armature updates. */
- add_operation_node(&armature->id, NodeType::ARMATURE, OperationCode::ARMATURE_EVAL);
+ bArmature *armature_cow = (bArmature *)get_cow_id(&armature->id);
+ add_operation_node(&armature->id,
+ NodeType::ARMATURE,
+ OperationCode::ARMATURE_EVAL,
+ function_bind(BKE_armature_refresh_layer_used, _1, armature_cow));
build_armature_bones(&armature->bonebase);
}
@@ -1437,6 +1442,12 @@ void DepsgraphNodeBuilder::build_light(Light *lamp)
build_parameters(&lamp->id);
/* light's nodetree */
build_nodetree(lamp->nodetree);
+
+ Light *lamp_cow = get_cow_datablock(lamp);
+ add_operation_node(&lamp->id,
+ NodeType::SHADING,
+ OperationCode::LIGHT_UPDATE,
+ function_bind(BKE_light_eval, _1, lamp_cow));
}
void DepsgraphNodeBuilder::build_nodetree(bNodeTree *ntree)
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
index ae90ad8a281..db8d9ed516a 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
@@ -2245,14 +2245,20 @@ void DepsgraphRelationBuilder::build_light(Light *lamp)
build_idproperties(lamp->id.properties);
build_animdata(&lamp->id);
build_parameters(&lamp->id);
+
+ ComponentKey lamp_parameters_key(&lamp->id, NodeType::PARAMETERS);
+
/* light's nodetree */
if (lamp->nodetree != nullptr) {
build_nodetree(lamp->nodetree);
- ComponentKey lamp_parameters_key(&lamp->id, NodeType::PARAMETERS);
ComponentKey nodetree_key(&lamp->nodetree->id, NodeType::SHADING);
add_relation(nodetree_key, lamp_parameters_key, "NTree->Light Parameters");
build_nested_nodetree(&lamp->id, lamp->nodetree);
}
+
+ /* For allowing drivers on lamp properties. */
+ ComponentKey shading_key(&lamp->id, NodeType::SHADING);
+ add_relation(lamp_parameters_key, shading_key, "Light Shading Parameters");
}
void DepsgraphRelationBuilder::build_nodetree(bNodeTree *ntree)
diff --git a/source/blender/depsgraph/intern/node/deg_node_operation.cc b/source/blender/depsgraph/intern/node/deg_node_operation.cc
index 2381076161f..91bd0117f6c 100644
--- a/source/blender/depsgraph/intern/node/deg_node_operation.cc
+++ b/source/blender/depsgraph/intern/node/deg_node_operation.cc
@@ -172,6 +172,8 @@ const char *operationCodeAsString(OperationCode opcode)
return "SHADING";
case OperationCode::MATERIAL_UPDATE:
return "MATERIAL_UPDATE";
+ case OperationCode::LIGHT_UPDATE:
+ return "LIGHT_UPDATE";
case OperationCode::WORLD_UPDATE:
return "WORLD_UPDATE";
/* Movie clip. */
diff --git a/source/blender/depsgraph/intern/node/deg_node_operation.h b/source/blender/depsgraph/intern/node/deg_node_operation.h
index 865a25d2124..6b14e6af02f 100644
--- a/source/blender/depsgraph/intern/node/deg_node_operation.h
+++ b/source/blender/depsgraph/intern/node/deg_node_operation.h
@@ -170,6 +170,7 @@ enum class OperationCode {
/* Shading. ------------------------------------------------------------- */
SHADING,
MATERIAL_UPDATE,
+ LIGHT_UPDATE,
WORLD_UPDATE,
/* Batch caches. -------------------------------------------------------- */
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index 6f932bf8797..0214a8e1887 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -401,4 +401,6 @@ if(WITH_XR_OPENXR)
add_definitions(-DWITH_XR_OPENXR)
endif()
+add_definitions(${GL_DEFINITIONS})
+
blender_add_lib(bf_draw "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/draw/engines/eevee/eevee_subsurface.c b/source/blender/draw/engines/eevee/eevee_subsurface.c
index 3f4008eb8b9..ebd45ef8e67 100644
--- a/source/blender/draw/engines/eevee/eevee_subsurface.c
+++ b/source/blender/draw/engines/eevee/eevee_subsurface.c
@@ -350,23 +350,15 @@ void EEVEE_subsurface_compute(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
if (!DRW_pass_is_empty(psl->sss_translucency_ps)) {
/* We sample the shadow-maps using normal sampler. We need to disable Comparison mode.
* TODO(fclem) avoid this by using sampler objects.*/
- GPU_texture_bind(sldata->shadow_cube_pool, 0);
GPU_texture_compare_mode(sldata->shadow_cube_pool, false);
- GPU_texture_unbind(sldata->shadow_cube_pool);
- GPU_texture_bind(sldata->shadow_cascade_pool, 0);
GPU_texture_compare_mode(sldata->shadow_cascade_pool, false);
- GPU_texture_unbind(sldata->shadow_cascade_pool);
GPU_framebuffer_bind(fbl->sss_translucency_fb);
DRW_draw_pass(psl->sss_translucency_ps);
/* Reset original state. */
- GPU_texture_bind(sldata->shadow_cube_pool, 0);
GPU_texture_compare_mode(sldata->shadow_cube_pool, true);
- GPU_texture_unbind(sldata->shadow_cube_pool);
- GPU_texture_bind(sldata->shadow_cascade_pool, 0);
GPU_texture_compare_mode(sldata->shadow_cascade_pool, true);
- GPU_texture_unbind(sldata->shadow_cascade_pool);
}
/* 1. horizontal pass */
diff --git a/source/blender/draw/engines/eevee/eevee_volumes.c b/source/blender/draw/engines/eevee/eevee_volumes.c
index ad90c52b08e..55e7b0eb0e3 100644
--- a/source/blender/draw/engines/eevee/eevee_volumes.c
+++ b/source/blender/draw/engines/eevee/eevee_volumes.c
@@ -486,8 +486,7 @@ static bool eevee_volume_object_mesh_init(Scene *scene,
ModifierData *md = NULL;
/* Smoke Simulation */
- if (((ob->base_flag & BASE_FROM_DUPLI) == 0) &&
- (md = BKE_modifiers_findby_type(ob, eModifierType_Fluid)) &&
+ if ((md = BKE_modifiers_findby_type(ob, eModifierType_Fluid)) &&
(BKE_modifier_is_enabled(scene, md, eModifierMode_Realtime)) &&
((FluidModifierData *)md)->domain != NULL) {
FluidModifierData *mmd = (FluidModifierData *)md;
@@ -776,12 +775,8 @@ void EEVEE_volumes_compute(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
/* We sample the shadow-maps using shadow sampler. We need to enable Comparison mode.
* TODO(fclem) avoid this by using sampler objects.*/
- GPU_texture_bind(sldata->shadow_cube_pool, 0);
GPU_texture_compare_mode(sldata->shadow_cube_pool, true);
- GPU_texture_unbind(sldata->shadow_cube_pool);
- GPU_texture_bind(sldata->shadow_cascade_pool, 0);
GPU_texture_compare_mode(sldata->shadow_cascade_pool, true);
- GPU_texture_unbind(sldata->shadow_cascade_pool);
GPU_framebuffer_bind(fbl->volumetric_fb);
DRW_draw_pass(psl->volumetric_world_ps);
diff --git a/source/blender/draw/engines/external/external_engine.c b/source/blender/draw/engines/external/external_engine.c
index 7dddbd07623..6e636e4dc93 100644
--- a/source/blender/draw/engines/external/external_engine.c
+++ b/source/blender/draw/engines/external/external_engine.c
@@ -215,7 +215,7 @@ static void external_draw_scene_do(void *vedata)
return;
}
- RenderEngine *engine = RE_engine_create_ex(engine_type, true);
+ RenderEngine *engine = RE_engine_create(engine_type);
engine->tile_x = scene->r.tilex;
engine->tile_y = scene->r.tiley;
engine_type->view_update(engine, draw_ctx->evil_C, draw_ctx->depsgraph);
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_common_lib.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_common_lib.glsl
index e2606473d07..fb5073b3dc7 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_common_lib.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_common_lib.glsl
@@ -473,8 +473,8 @@ void stroke_vertex()
float miter_dot = dot(miter_tan, line_adj);
/* Break corners after a certain angle to avoid really thick corners. */
const float miter_limit = 0.5; /* cos(60°) */
- bool miter_break = (miter_dot < miter_limit) || is_stroke_start || is_stroke_end;
- miter_tan = (miter_break) ? line : (miter_tan / miter_dot);
+ bool miter_break = (miter_dot < miter_limit);
+ miter_tan = (miter_break || is_stroke_start || is_stroke_end) ? line : (miter_tan / miter_dot);
vec2 miter = rotate_90deg(miter_tan);
@@ -487,7 +487,7 @@ void stroke_vertex()
/* Reminder: we packed the cap flag into the sign of stength and thickness sign. */
if ((is_stroke_start && strength1 > 0.0) || (is_stroke_end && thickness1 > 0.0) ||
- miter_break) {
+ (miter_break && !is_stroke_start && !is_stroke_end)) {
screen_ofs += line * x;
}
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_frag.glsl
index 8c2032f834a..d81c6f4fe0b 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_frag.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_frag.glsl
@@ -99,8 +99,10 @@ void main()
discard;
}
+ vec2 fb_size = max(vec2(textureSize(gpSceneDepthTexture, 0).xy),
+ vec2(textureSize(gpMaskTexture, 0).xy));
+ vec2 uvs = gl_FragCoord.xy / fb_size;
/* Manual depth test */
- vec2 uvs = gl_FragCoord.xy / vec2(textureSize(gpSceneDepthTexture, 0).xy);
float scene_depth = texture(gpSceneDepthTexture, uvs).r;
if (gl_FragCoord.z > scene_depth) {
discard;
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_vert.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_vert.glsl
index c6cfee5ef2d..225601eb9ba 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_vert.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_vert.glsl
@@ -2,4 +2,4 @@
void main()
{
gpencil_vertex();
-} \ No newline at end of file
+}
diff --git a/source/blender/draw/engines/overlay/overlay_armature.c b/source/blender/draw/engines/overlay/overlay_armature.c
index 624eef8fa47..a538b7ffd5f 100644
--- a/source/blender/draw/engines/overlay/overlay_armature.c
+++ b/source/blender/draw/engines/overlay/overlay_armature.c
@@ -137,9 +137,7 @@ void OVERLAY_armature_cache_init(OVERLAY_Data *vedata)
pd->armature.do_pose_fade_geom = pd->armature.do_pose_xray &&
((draw_ctx->object_mode & OB_MODE_WEIGHT_PAINT) == 0) &&
draw_ctx->object_pose != NULL;
-
- DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND_ADD;
- DRW_PASS_CREATE(psl->armature_transp_ps, state | pd->clipping_state);
+ DRWState state;
if (pd->armature.do_pose_fade_geom) {
state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_BLEND_ALPHA;
@@ -163,17 +161,21 @@ void OVERLAY_armature_cache_init(OVERLAY_Data *vedata)
OVERLAY_InstanceFormats *formats = OVERLAY_shader_instance_formats_get();
OVERLAY_ArmatureCallBuffers *cb = &pd->armature_call_buffers[i];
- DRWPass **p_armature_ps = &psl->armature_ps[i];
cb->custom_shapes_ghash = BLI_ghash_ptr_new(__func__);
cb->custom_shapes_transp_ghash = BLI_ghash_ptr_new(__func__);
+ DRWPass **p_armature_ps = &psl->armature_ps[i];
DRWState infront_state = (DRW_state_is_select() && (i == 1)) ? DRW_STATE_IN_FRONT_SELECT : 0;
state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_WRITE_DEPTH;
DRW_PASS_CREATE(*p_armature_ps, state | pd->clipping_state | infront_state);
-
DRWPass *armature_ps = *p_armature_ps;
+ DRWPass **p_armature_trans_ps = &psl->armature_transp_ps[i];
+ state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND_ADD;
+ DRW_PASS_CREATE(*p_armature_trans_ps, state | pd->clipping_state);
+ DRWPass *armature_transp_ps = *p_armature_trans_ps;
+
#define BUF_INSTANCE DRW_shgroup_call_buffer_instance
#define BUF_LINE(grp, format) DRW_shgroup_call_buffer(grp, format, GPU_PRIM_LINES)
@@ -231,7 +233,7 @@ void OVERLAY_armature_cache_init(OVERLAY_Data *vedata)
DRW_shgroup_uniform_block_persistent(grp, "globalsBlock", G_draw.block_ubo);
cb->dof_lines = BUF_INSTANCE(grp, format, DRW_cache_bone_dof_lines_get());
- grp = DRW_shgroup_create(sh, psl->armature_transp_ps);
+ grp = DRW_shgroup_create(sh, armature_transp_ps);
DRW_shgroup_uniform_block_persistent(grp, "globalsBlock", G_draw.block_ubo);
cb->dof_sphere = BUF_INSTANCE(grp, format, DRW_cache_bone_dof_sphere_get());
}
@@ -270,7 +272,7 @@ void OVERLAY_armature_cache_init(OVERLAY_Data *vedata)
format = formats->instance_bone_envelope_distance;
sh = OVERLAY_shader_armature_envelope(false);
- grp = DRW_shgroup_create(sh, psl->armature_transp_ps);
+ grp = DRW_shgroup_create(sh, armature_transp_ps);
DRW_shgroup_uniform_block_persistent(grp, "globalsBlock", G_draw.block_ubo);
DRW_shgroup_uniform_bool_copy(grp, "isDistance", true);
DRW_shgroup_state_enable(grp, DRW_STATE_CULL_FRONT);
@@ -2255,7 +2257,7 @@ void OVERLAY_armature_draw(OVERLAY_Data *vedata)
{
OVERLAY_PassList *psl = vedata->psl;
- DRW_draw_pass(psl->armature_transp_ps);
+ DRW_draw_pass(psl->armature_transp_ps[0]);
DRW_draw_pass(psl->armature_ps[0]);
}
@@ -2264,6 +2266,7 @@ void OVERLAY_armature_in_front_draw(OVERLAY_Data *vedata)
OVERLAY_PassList *psl = vedata->psl;
if (psl->armature_bone_select_ps == NULL || DRW_state_is_select()) {
+ DRW_draw_pass(psl->armature_transp_ps[1]);
DRW_draw_pass(psl->armature_ps[1]);
}
}
@@ -2285,6 +2288,7 @@ void OVERLAY_pose_draw(OVERLAY_Data *vedata)
GPU_framebuffer_clear_depth(fbl->overlay_line_in_front_fb, 1.0f);
}
+ DRW_draw_pass(psl->armature_transp_ps[1]);
DRW_draw_pass(psl->armature_ps[1]);
}
}
diff --git a/source/blender/draw/engines/overlay/overlay_background.c b/source/blender/draw/engines/overlay/overlay_background.c
index f1ffa9035e0..f52ae691a35 100644
--- a/source/blender/draw/engines/overlay/overlay_background.c
+++ b/source/blender/draw/engines/overlay/overlay_background.c
@@ -71,15 +71,16 @@ void OVERLAY_background_cache_init(OVERLAY_Data *vedata)
}
else {
switch (UI_GetThemeValue(TH_BACKGROUND_TYPE)) {
- case TH_BACKGROUND_SINGLE_COLOR:
- background_type = BG_SOLID;
- break;
case TH_BACKGROUND_GRADIENT_LINEAR:
background_type = BG_GRADIENT;
break;
case TH_BACKGROUND_GRADIENT_RADIAL:
background_type = BG_RADIAL;
break;
+ default:
+ case TH_BACKGROUND_SINGLE_COLOR:
+ background_type = BG_SOLID;
+ break;
}
}
diff --git a/source/blender/draw/engines/overlay/overlay_image.c b/source/blender/draw/engines/overlay/overlay_image.c
index c592f11a855..be3510967b6 100644
--- a/source/blender/draw/engines/overlay/overlay_image.c
+++ b/source/blender/draw/engines/overlay/overlay_image.c
@@ -287,6 +287,9 @@ static void image_camera_background_matrix_get(const Camera *cam,
translate[3][0] = bgpic->offset[0];
translate[3][1] = bgpic->offset[1];
translate[3][2] = cam_corners[0][2];
+ if (cam->type == CAM_ORTHO) {
+ mul_v2_fl(translate[3], cam->ortho_scale);
+ }
/* These lines are for keeping 2.80 behavior and could be removed to keep 2.79 behavior. */
translate[3][0] *= min_ff(1.0f, cam_aspect);
translate[3][1] /= max_ff(1.0f, cam_aspect) * (image_aspect / cam_aspect);
diff --git a/source/blender/draw/engines/overlay/overlay_private.h b/source/blender/draw/engines/overlay/overlay_private.h
index 0c29fe9d2e4..fa7c7f6d090 100644
--- a/source/blender/draw/engines/overlay/overlay_private.h
+++ b/source/blender/draw/engines/overlay/overlay_private.h
@@ -54,7 +54,7 @@ typedef struct OVERLAY_PassList {
DRWPass *antialiasing_ps;
DRWPass *armature_ps[2];
DRWPass *armature_bone_select_ps;
- DRWPass *armature_transp_ps;
+ DRWPass *armature_transp_ps[2];
DRWPass *background_ps;
DRWPass *clipping_frustum_ps;
DRWPass *edit_curve_wire_ps[2];
@@ -253,8 +253,9 @@ typedef struct OVERLAY_PrivateData {
DRWShadingGroup *particle_shapes_grp;
DRWShadingGroup *pointcloud_dots_grp;
DRWShadingGroup *sculpt_mask_grp;
- DRWShadingGroup *wires_grp[2][2]; /* With and without coloring. */
- DRWShadingGroup *wires_all_grp[2][2]; /* With and without coloring. */
+ DRWShadingGroup *wires_grp[2][2]; /* With and without coloring. */
+ DRWShadingGroup *wires_all_grp[2][2]; /* With and without coloring. */
+ DRWShadingGroup *wires_hair_grp[2][2]; /* With and without coloring. */
DRWShadingGroup *wires_sculpt_grp[2];
DRWView *view_default;
diff --git a/source/blender/draw/engines/overlay/overlay_wireframe.c b/source/blender/draw/engines/overlay/overlay_wireframe.c
index 99ff7f67d49..309c7c1021a 100644
--- a/source/blender/draw/engines/overlay/overlay_wireframe.c
+++ b/source/blender/draw/engines/overlay/overlay_wireframe.c
@@ -21,15 +21,18 @@
*/
#include "DNA_mesh_types.h"
+#include "DNA_particle_types.h"
#include "DNA_view3d_types.h"
#include "DNA_volume_types.h"
#include "BKE_curve.h"
#include "BKE_displist.h"
+#include "BKE_duplilist.h"
#include "BKE_editmesh.h"
#include "BKE_global.h"
#include "BKE_object.h"
#include "BKE_paint.h"
+#include "BKE_particle.h"
#include "BLI_hash.h"
@@ -95,16 +98,24 @@ void OVERLAY_wireframe_cache_init(OVERLAY_Data *vedata)
DRW_shgroup_uniform_bool_copy(grp, "isTransform", (G.moving & G_TRANSFORM_OBJ) != 0);
DRW_shgroup_uniform_bool_copy(grp, "isObjectColor", is_object_color);
DRW_shgroup_uniform_bool_copy(grp, "isRandomColor", is_random_color);
+ DRW_shgroup_uniform_bool_copy(grp, "isHair", false);
pd->wires_all_grp[xray][use_coloring] = grp = DRW_shgroup_create(wires_sh, pass);
DRW_shgroup_uniform_texture_ref(grp, "depthTex", depth_tx);
DRW_shgroup_uniform_float_copy(grp, "wireStepParam", 1.0f);
+
+ pd->wires_hair_grp[xray][use_coloring] = grp = DRW_shgroup_create(wires_sh, pass);
+ /* TODO(fclem) texture ref persist */
+ DRW_shgroup_uniform_texture_ref(grp, "depthTex", depth_tx);
+ DRW_shgroup_uniform_bool_copy(grp, "isHair", true);
+ DRW_shgroup_uniform_float_copy(grp, "wireStepParam", 10.0f);
}
pd->wires_sculpt_grp[xray] = grp = DRW_shgroup_create(wires_sh, pass);
DRW_shgroup_uniform_texture_ref(grp, "depthTex", depth_tx);
DRW_shgroup_uniform_float_copy(grp, "wireStepParam", 10.0f);
DRW_shgroup_uniform_bool_copy(grp, "useColoring", false);
+ DRW_shgroup_uniform_bool_copy(grp, "isHair", false);
}
if (is_material_shmode) {
@@ -112,19 +123,53 @@ void OVERLAY_wireframe_cache_init(OVERLAY_Data *vedata)
for (int use_coloring = 0; use_coloring < 2; use_coloring++) {
pd->wires_grp[1][use_coloring] = pd->wires_grp[0][use_coloring];
pd->wires_all_grp[1][use_coloring] = pd->wires_all_grp[0][use_coloring];
+ pd->wires_hair_grp[1][use_coloring] = pd->wires_hair_grp[0][use_coloring];
}
pd->wires_sculpt_grp[1] = pd->wires_sculpt_grp[0];
psl->wireframe_xray_ps = NULL;
}
}
+static void wireframe_hair_cache_populate(OVERLAY_Data *vedata, Object *ob, ParticleSystem *psys)
+{
+ OVERLAY_PrivateData *pd = vedata->stl->pd;
+ const bool is_xray = (ob->dtx & OB_DRAWXRAY) != 0;
+
+ Object *dupli_parent = DRW_object_get_dupli_parent(ob);
+ DupliObject *dupli_object = DRW_object_get_dupli(ob);
+
+ float dupli_mat[4][4];
+ if ((dupli_parent != NULL) && (dupli_object != NULL)) {
+ if (dupli_object->type & OB_DUPLICOLLECTION) {
+ copy_m4_m4(dupli_mat, dupli_parent->obmat);
+ }
+ else {
+ copy_m4_m4(dupli_mat, dupli_object->ob->obmat);
+ invert_m4(dupli_mat);
+ mul_m4_m4m4(dupli_mat, ob->obmat, dupli_mat);
+ }
+ }
+ else {
+ unit_m4(dupli_mat);
+ }
+
+ struct GPUBatch *hairs = DRW_cache_particles_get_hair(ob, psys, NULL);
+
+ const bool use_coloring = true;
+ DRWShadingGroup *shgrp = DRW_shgroup_create_sub(pd->wires_hair_grp[is_xray][use_coloring]);
+ DRW_shgroup_uniform_vec4_copy(shgrp, "hairDupliMatrix[0]", dupli_mat[0]);
+ DRW_shgroup_uniform_vec4_copy(shgrp, "hairDupliMatrix[1]", dupli_mat[1]);
+ DRW_shgroup_uniform_vec4_copy(shgrp, "hairDupliMatrix[2]", dupli_mat[2]);
+ DRW_shgroup_uniform_vec4_copy(shgrp, "hairDupliMatrix[3]", dupli_mat[3]);
+ DRW_shgroup_call_no_cull(shgrp, hairs, ob);
+}
+
void OVERLAY_wireframe_cache_populate(OVERLAY_Data *vedata,
Object *ob,
OVERLAY_DupliData *dupli,
bool init_dupli)
{
- OVERLAY_Data *data = vedata;
- OVERLAY_PrivateData *pd = data->stl->pd;
+ OVERLAY_PrivateData *pd = vedata->stl->pd;
const DRWContextState *draw_ctx = DRW_context_state_get();
const bool all_wires = (ob->dtx & OB_DRAW_ALL_EDGES) != 0;
const bool is_xray = (ob->dtx & OB_DRAWXRAY) != 0;
@@ -134,6 +179,19 @@ void OVERLAY_wireframe_cache_populate(OVERLAY_Data *vedata,
const bool use_wire = !is_mesh_verts_only && ((pd->overlay.flag & V3D_OVERLAY_WIREFRAMES) ||
(ob->dtx & OB_DRAWWIRE) || (ob->dt == OB_WIRE));
+ if (use_wire && pd->wireframe_mode && ob->particlesystem.first) {
+ for (ParticleSystem *psys = ob->particlesystem.first; psys != NULL; psys = psys->next) {
+ if (!DRW_object_is_visible_psys_in_active_context(ob, psys)) {
+ continue;
+ }
+ ParticleSettings *part = psys->part;
+ const int draw_as = (part->draw_as == PART_DRAW_REND) ? part->ren_as : part->draw_as;
+ if (draw_as == PART_DRAW_PATH) {
+ wireframe_hair_cache_populate(vedata, ob, psys);
+ }
+ }
+ }
+
if (ELEM(ob->type, OB_CURVE, OB_FONT, OB_SURF)) {
OVERLAY_ExtraCallBuffers *cb = OVERLAY_extra_call_buffer_get(vedata, ob);
float *color;
diff --git a/source/blender/draw/engines/overlay/shaders/wireframe_vert.glsl b/source/blender/draw/engines/overlay/shaders/wireframe_vert.glsl
index 7e71f4ae587..f7467aa3bf4 100644
--- a/source/blender/draw/engines/overlay/shaders/wireframe_vert.glsl
+++ b/source/blender/draw/engines/overlay/shaders/wireframe_vert.glsl
@@ -4,6 +4,8 @@ uniform bool useColoring;
uniform bool isTransform;
uniform bool isObjectColor;
uniform bool isRandomColor;
+uniform bool isHair;
+uniform vec4 hairDupliMatrix[4];
in vec3 pos;
in vec3 nor;
@@ -103,9 +105,16 @@ void main()
{
bool no_attr = all(equal(nor, vec3(0)));
vec3 wnor = no_attr ? ViewMatrixInverse[2].xyz : normalize(normal_object_to_world(nor));
-
vec3 wpos = point_object_to_world(pos);
+ if (isHair) {
+ mat4 obmat = mat4(
+ hairDupliMatrix[0], hairDupliMatrix[1], hairDupliMatrix[2], hairDupliMatrix[3]);
+
+ wpos = (obmat * vec4(pos, 1.0)).xyz;
+ wnor = -normalize(mat3(obmat) * nor);
+ }
+
bool is_persp = (ProjectionMatrix[3][3] == 0.0);
vec3 V = (is_persp) ? normalize(ViewMatrixInverse[3].xyz - wpos) : ViewMatrixInverse[2].xyz;
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_curvature_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_curvature_lib.glsl
index e6bc4c7bbc6..a4d81393dbc 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_curvature_lib.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_curvature_lib.glsl
@@ -26,6 +26,10 @@ void curvature_compute(vec2 uv,
if ((object_up != object_down) || (object_right != object_left)) {
return;
}
+ /* Avoid shading background pixels. */
+ if ((object_up == object_right) && (object_right == 0u)) {
+ return;
+ }
float normal_up = workbench_normal_decode(texture(normalBuffer, uv + offset.zy)).g;
float normal_down = workbench_normal_decode(texture(normalBuffer, uv - offset.zy)).g;
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_image_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_image_lib.glsl
index 6f99739f259..e45f7a7b9e3 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_image_lib.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_image_lib.glsl
@@ -24,11 +24,17 @@ bool node_tex_tile_lookup(inout vec3 co, sampler2DArray ima, sampler1DArray map)
vec4 workbench_sample_texture(sampler2D image, vec2 coord, bool nearest_sampling)
{
- vec2 tex_size = vec2(textureSize(image, 0).xy);
/* TODO(fclem) We could do the same with sampler objects.
* But this is a quick workaround instead of messing with the GPUTexture itself. */
- vec2 uv = nearest_sampling ? (floor(coord * tex_size) + 0.5) / tex_size : coord;
- return texture(image, uv);
+ if (nearest_sampling) {
+ /* Use texelFetch for nearest_sampling to reduce glitches. See: T73726 */
+ vec2 tex_size = vec2(textureSize(image, 0).xy);
+ ivec2 uv = ivec2(floor(coord * tex_size) + 0.5);
+ return texelFetch(image, uv, 0);
+ }
+ else {
+ return texture(image, coord);
+ }
}
vec4 workbench_sample_texture_array(sampler2DArray tile_array,
@@ -36,7 +42,6 @@ vec4 workbench_sample_texture_array(sampler2DArray tile_array,
vec2 coord,
bool nearest_sampling)
{
- vec2 tex_size = vec2(textureSize(tile_array, 0).xy);
vec3 uv = vec3(coord, 0);
if (!node_tex_tile_lookup(uv, tile_array, tile_data))
@@ -44,8 +49,15 @@ vec4 workbench_sample_texture_array(sampler2DArray tile_array,
/* TODO(fclem) We could do the same with sampler objects.
* But this is a quick workaround instead of messing with the GPUTexture itself. */
- uv.xy = nearest_sampling ? (floor(uv.xy * tex_size) + 0.5) / tex_size : uv.xy;
- return texture(tile_array, uv);
+ if (nearest_sampling) {
+ /* Use texelFetch for nearest_sampling to reduce glitches. See: T73726 */
+ vec3 tex_size = vec3(textureSize(tile_array, 0));
+ uv.xy = floor(uv.xy * tex_size.xy) + 0.5;
+ return texelFetch(tile_array, ivec3(uv), 0);
+ }
+ else {
+ return texture(tile_array, uv);
+ }
}
uniform sampler2DArray imageTileArray;
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_merge_infront_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_merge_infront_frag.glsl
index 58becb03290..b77e168889f 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_merge_infront_frag.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_merge_infront_frag.glsl
@@ -15,4 +15,4 @@ void main()
/* Make this fragment occlude any fragment that will try to
* render over it in the normal passes. */
gl_FragDepth = 0.0;
-} \ No newline at end of file
+}
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_world_light_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_world_light_lib.glsl
index 81f6e651be0..41ef516ee4d 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_world_light_lib.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_world_light_lib.glsl
@@ -128,4 +128,4 @@ float get_shadow(vec3 N)
float shadow_mix = smoothstep(world_data.shadow_shift, world_data.shadow_focus, light_factor);
shadow_mix *= forceShadowing ? 0.0 : world_data.shadow_mul;
return shadow_mix + world_data.shadow_add;
-} \ No newline at end of file
+}
diff --git a/source/blender/draw/intern/draw_cache_impl_curve.c b/source/blender/draw/intern/draw_cache_impl_curve.c
index 72ee7fe17c1..5642ffba4f1 100644
--- a/source/blender/draw/intern/draw_cache_impl_curve.c
+++ b/source/blender/draw/intern/draw_cache_impl_curve.c
@@ -1034,7 +1034,7 @@ void DRW_curve_batch_cache_create_requested(Object *ob)
}
if (DRW_vbo_requested(cache->ordered.loop_pos_nor) ||
- DRW_vbo_requested(cache->ordered.loop_uv)) {
+ DRW_vbo_requested(cache->ordered.loop_uv) || DRW_vbo_requested(cache->ordered.loop_tan)) {
DRW_displist_vertbuf_create_loop_pos_and_nor_and_uv_and_tan(
lb, cache->ordered.loop_pos_nor, cache->ordered.loop_uv, cache->ordered.loop_tan);
}
diff --git a/source/blender/draw/intern/draw_cache_impl_gpencil.c b/source/blender/draw/intern/draw_cache_impl_gpencil.c
index 62ce34fe556..ee148e0934d 100644
--- a/source/blender/draw/intern/draw_cache_impl_gpencil.c
+++ b/source/blender/draw/intern/draw_cache_impl_gpencil.c
@@ -291,7 +291,7 @@ static void gpencil_buffer_add_point(gpStrokeVert *verts,
vert->u_stroke = pt->uv_fac;
vert->stroke_id = gps->runtime.stroke_start;
vert->point_id = v;
- vert->thickness = max_ff(0.0f, gps->thickness * pt->pressure) * (round_cap1 ? 1.0 : -1.0);
+ vert->thickness = max_ff(0.0f, gps->thickness * pt->pressure) * (round_cap1 ? 1.0f : -1.0f);
/* Tag endpoint material to -1 so they get discarded by vertex shader. */
vert->mat = (is_endpoint) ? -1 : (gps->mat_nr % GP_MATERIAL_BUFFER_LEN);
diff --git a/source/blender/draw/intern/draw_manager_data.c b/source/blender/draw/intern/draw_manager_data.c
index 95b204ac004..ff27fa958ef 100644
--- a/source/blender/draw/intern/draw_manager_data.c
+++ b/source/blender/draw/intern/draw_manager_data.c
@@ -2000,7 +2000,10 @@ void DRW_pass_sort_shgroup_z(DRWPass *pass)
}
}
/* To be sorted a shgroup needs to have at least one draw command. */
- BLI_assert(handle != 0);
+ /* FIXME(fclem) In some case, we can still have empty shading group to sort. However their
+ * final order is not well defined.
+ * (see T76730 & D7729). */
+ // BLI_assert(handle != 0);
DRWObjectMatrix *obmats = DRW_memblock_elem_from_handle(DST.vmempool->obmats, &handle);
diff --git a/source/blender/draw/intern/draw_manager_shader.c b/source/blender/draw/intern/draw_manager_shader.c
index 7eac082a9e1..0d6527421d0 100644
--- a/source/blender/draw/intern/draw_manager_shader.c
+++ b/source/blender/draw/intern/draw_manager_shader.c
@@ -241,6 +241,9 @@ static void drw_deferred_shader_add(GPUMaterial *mat, bool deferred)
WM_jobs_timer(wm_job, 0.1, NC_MATERIAL | ND_SHADING_DRAW, 0);
WM_jobs_delay_start(wm_job, 0.1);
WM_jobs_callbacks(wm_job, drw_deferred_shader_compilation_exec, NULL, NULL, NULL);
+
+ G.is_break = false;
+
WM_jobs_start(wm, wm_job);
}
diff --git a/source/blender/editors/animation/fmodifier_ui.c b/source/blender/editors/animation/fmodifier_ui.c
index e795cb6e3ef..eadaa449b92 100644
--- a/source/blender/editors/animation/fmodifier_ui.c
+++ b/source/blender/editors/animation/fmodifier_ui.c
@@ -717,28 +717,31 @@ static void draw_modifier__envelope(uiLayout *layout,
/* control points list */
for (i = 0, fed = env->data; i < env->totvert; i++, fed++) {
+ PointerRNA ctrl_ptr;
+ RNA_pointer_create(fcurve_owner_id, &RNA_FModifierEnvelopeControlPoint, fed, &ctrl_ptr);
+
/* get a new row to operate on */
row = uiLayoutRow(layout, true);
block = uiLayoutGetBlock(row);
UI_block_align_begin(block);
- but = uiDefButF(block,
- UI_BTYPE_NUM,
- B_FMODIFIER_REDRAW,
- IFACE_("Fra:"),
- 0,
- 0,
- 4.5 * UI_UNIT_X,
- UI_UNIT_Y,
- &fed->time,
- -MAXFRAMEF,
- MAXFRAMEF,
- 10,
- 1,
- TIP_("Frame that envelope point occurs"));
- UI_but_func_set(but, validate_fmodifier_cb, fcm, NULL);
-
- uiDefButF(block,
+ uiDefButR(block,
+ UI_BTYPE_NUM,
+ B_FMODIFIER_REDRAW,
+ IFACE_("Fra:"),
+ 0,
+ 0,
+ 4.5 * UI_UNIT_X,
+ UI_UNIT_Y,
+ &ctrl_ptr,
+ "frame",
+ -1,
+ -MAXFRAMEF,
+ MAXFRAMEF,
+ 10,
+ 1,
+ NULL);
+ uiDefButR(block,
UI_BTYPE_NUM,
B_FMODIFIER_REDRAW,
IFACE_("Min:"),
@@ -746,13 +749,15 @@ static void draw_modifier__envelope(uiLayout *layout,
0,
5 * UI_UNIT_X,
UI_UNIT_Y,
- &fed->min,
+ &ctrl_ptr,
+ "min",
+ -1,
-UI_FLT_MAX,
UI_FLT_MAX,
10,
2,
- TIP_("Minimum bound of envelope at this point"));
- uiDefButF(block,
+ NULL);
+ uiDefButR(block,
UI_BTYPE_NUM,
B_FMODIFIER_REDRAW,
IFACE_("Max:"),
@@ -760,12 +765,14 @@ static void draw_modifier__envelope(uiLayout *layout,
0,
5 * UI_UNIT_X,
UI_UNIT_Y,
- &fed->max,
+ &ctrl_ptr,
+ "max",
+ -1,
-UI_FLT_MAX,
UI_FLT_MAX,
10,
2,
- TIP_("Maximum bound of envelope at this point"));
+ NULL);
but = uiDefIconBut(block,
UI_BTYPE_BUT,
diff --git a/source/blender/editors/armature/armature_relations.c b/source/blender/editors/armature/armature_relations.c
index 5f3b876efaf..d3d00fc44f2 100644
--- a/source/blender/editors/armature/armature_relations.c
+++ b/source/blender/editors/armature/armature_relations.c
@@ -432,7 +432,6 @@ int join_armature_exec(bContext *C, wmOperator *op)
ED_armature_from_edit(bmain, arm);
ED_armature_edit_free(arm);
- BKE_armature_refresh_layer_used(arm);
DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
@@ -689,9 +688,7 @@ static int separate_armature_exec(bContext *C, wmOperator *op)
/* 5) restore original conditions */
ED_armature_to_edit(ob_old->data);
-
ED_armature_edit_refresh_layer_used(ob_old->data);
- BKE_armature_refresh_layer_used(ob_new->data);
/* parents tips remain selected when connected children are removed. */
ED_armature_edit_deselect_all(ob_old);
diff --git a/source/blender/editors/armature/pose_edit.c b/source/blender/editors/armature/pose_edit.c
index daab945c106..0cd3afc9cf9 100644
--- a/source/blender/editors/armature/pose_edit.c
+++ b/source/blender/editors/armature/pose_edit.c
@@ -906,8 +906,6 @@ static int pose_bone_layers_exec(bContext *C, wmOperator *op)
RNA_boolean_set_array(&ptr, "layers", layers);
if (prev_ob != ob) {
- BKE_armature_refresh_layer_used(ob->data);
-
/* Note, notifier might evolve. */
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
DEG_id_tag_update((ID *)ob->data, ID_RECALC_COPY_ON_WRITE);
diff --git a/source/blender/editors/armature/pose_slide.c b/source/blender/editors/armature/pose_slide.c
index 481282d6df3..d9621dba730 100644
--- a/source/blender/editors/armature/pose_slide.c
+++ b/source/blender/editors/armature/pose_slide.c
@@ -1239,51 +1239,60 @@ static int pose_slide_exec_common(bContext *C, wmOperator *op, tPoseSlideOp *pso
return OPERATOR_FINISHED;
}
-/* common code for defining RNA properties */
-/* TODO: Skip save on these? */
+/**
+ * Common code for defining RNA properties.
+ */
static void pose_slide_opdef_properties(wmOperatorType *ot)
{
- RNA_def_float_percentage(ot->srna,
- "percentage",
- 0.5f,
- 0.0f,
- 1.0f,
- "Percentage",
- "Weighting factor for which keyframe is favored more",
- 0.0,
- 1.0);
-
- RNA_def_int(ot->srna,
- "prev_frame",
- 0,
- MINAFRAME,
- MAXFRAME,
- "Previous Keyframe",
- "Frame number of keyframe immediately before the current frame",
- 0,
- 50);
- RNA_def_int(ot->srna,
- "next_frame",
- 0,
- MINAFRAME,
- MAXFRAME,
- "Next Keyframe",
- "Frame number of keyframe immediately after the current frame",
- 0,
- 50);
-
- RNA_def_enum(ot->srna,
- "channels",
- prop_channels_types,
- PS_TFM_ALL,
- "Channels",
- "Set of properties that are affected");
- RNA_def_enum(ot->srna,
- "axis_lock",
- prop_axis_lock_types,
- 0,
- "Axis Lock",
- "Transform axis to restrict effects to");
+ PropertyRNA *prop;
+
+ prop = RNA_def_float_percentage(ot->srna,
+ "percentage",
+ 0.5f,
+ 0.0f,
+ 1.0f,
+ "Percentage",
+ "Weighting factor for which keyframe is favored more",
+ 0.0,
+ 1.0);
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+
+ prop = RNA_def_int(ot->srna,
+ "prev_frame",
+ 0,
+ MINAFRAME,
+ MAXFRAME,
+ "Previous Keyframe",
+ "Frame number of keyframe immediately before the current frame",
+ 0,
+ 50);
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+
+ prop = RNA_def_int(ot->srna,
+ "next_frame",
+ 0,
+ MINAFRAME,
+ MAXFRAME,
+ "Next Keyframe",
+ "Frame number of keyframe immediately after the current frame",
+ 0,
+ 50);
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+
+ prop = RNA_def_enum(ot->srna,
+ "channels",
+ prop_channels_types,
+ PS_TFM_ALL,
+ "Channels",
+ "Set of properties that are affected");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ prop = RNA_def_enum(ot->srna,
+ "axis_lock",
+ prop_axis_lock_types,
+ 0,
+ "Axis Lock",
+ "Transform axis to restrict effects to");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
/* ------------------------------------ */
diff --git a/source/blender/editors/gpencil/gpencil_data.c b/source/blender/editors/gpencil/gpencil_data.c
index a7e7246ee82..8c80334bf8a 100644
--- a/source/blender/editors/gpencil/gpencil_data.c
+++ b/source/blender/editors/gpencil/gpencil_data.c
@@ -1907,19 +1907,19 @@ static int gp_brush_reset_all_exec(bContext *C, wmOperator *UNUSED(op))
switch (mode) {
case CTX_MODE_PAINT_GPENCIL: {
- BKE_brush_gpencil_paint_presets(bmain, ts);
+ BKE_brush_gpencil_paint_presets(bmain, ts, true);
break;
}
case CTX_MODE_SCULPT_GPENCIL: {
- BKE_brush_gpencil_sculpt_presets(bmain, ts);
+ BKE_brush_gpencil_sculpt_presets(bmain, ts, true);
break;
}
case CTX_MODE_WEIGHT_GPENCIL: {
- BKE_brush_gpencil_weight_presets(bmain, ts);
+ BKE_brush_gpencil_weight_presets(bmain, ts, true);
break;
}
case CTX_MODE_VERTEX_GPENCIL: {
- BKE_brush_gpencil_vertex_presets(bmain, ts);
+ BKE_brush_gpencil_vertex_presets(bmain, ts, true);
break;
}
default: {
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c
index 2d53679b61a..151f4a930d0 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -369,12 +369,20 @@ static int gpencil_paintmode_toggle_exec(bContext *C, wmOperator *op)
}
if (mode == OB_MODE_PAINT_GPENCIL) {
- /* be sure we have brushes */
+ /* Be sure we have brushes and Paint settings.
+ * Need Draw and Vertex (used fro Tint). */
BKE_paint_ensure(ts, (Paint **)&ts->gp_paint);
+ BKE_paint_ensure(ts, (Paint **)&ts->gp_vertexpaint);
+
+ BKE_brush_gpencil_paint_presets(bmain, ts, false);
+
+ /* Ensure Palette by default. */
+ BKE_gpencil_palette_ensure(bmain, CTX_data_scene(C));
+
Paint *paint = &ts->gp_paint->paint;
/* if not exist, create a new one */
if ((paint->brush == NULL) || (paint->brush->gpencil_settings == NULL)) {
- BKE_brush_gpencil_paint_presets(bmain, ts);
+ BKE_brush_gpencil_paint_presets(bmain, ts, true);
}
BKE_paint_toolslots_brush_validate(bmain, &ts->gp_paint->paint);
}
@@ -480,6 +488,8 @@ static int gpencil_sculptmode_toggle_exec(bContext *C, wmOperator *op)
/* be sure we have brushes */
BKE_paint_ensure(ts, (Paint **)&ts->gp_sculptpaint);
BKE_paint_toolslots_brush_validate(bmain, &ts->gp_sculptpaint->paint);
+
+ BKE_brush_gpencil_sculpt_presets(bmain, ts, false);
}
/* setup other modes */
@@ -585,6 +595,8 @@ static int gpencil_weightmode_toggle_exec(bContext *C, wmOperator *op)
/* be sure we have brushes */
BKE_paint_ensure(ts, (Paint **)&ts->gp_weightpaint);
BKE_paint_toolslots_brush_validate(bmain, &ts->gp_weightpaint->paint);
+
+ BKE_brush_gpencil_weight_presets(bmain, ts, false);
}
/* setup other modes */
@@ -687,6 +699,11 @@ static int gpencil_vertexmode_toggle_exec(bContext *C, wmOperator *op)
/* be sure we have brushes */
BKE_paint_ensure(ts, (Paint **)&ts->gp_vertexpaint);
BKE_paint_toolslots_brush_validate(bmain, &ts->gp_vertexpaint->paint);
+
+ BKE_brush_gpencil_vertex_presets(bmain, ts, false);
+
+ /* Ensure Palette by default. */
+ BKE_gpencil_palette_ensure(bmain, CTX_data_scene(C));
}
/* setup other modes */
diff --git a/source/blender/editors/gpencil/gpencil_intern.h b/source/blender/editors/gpencil/gpencil_intern.h
index a98ccb1cba6..473913c5459 100644
--- a/source/blender/editors/gpencil/gpencil_intern.h
+++ b/source/blender/editors/gpencil/gpencil_intern.h
@@ -699,16 +699,13 @@ struct GP_EditableStrokes_Iter {
const bool is_multiedit_ = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd_); \
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd_->layers) { \
if (BKE_gpencil_layer_is_editable(gpl)) { \
- bGPDframe *init_gpf_ = gpl->actframe; \
- if (is_multiedit_) { \
- init_gpf_ = gpl->frames.first; \
- } \
+ bGPDframe *init_gpf_ = (is_multiedit_) ? gpl->frames.first : gpl->actframe; \
for (bGPDframe *gpf_ = init_gpf_; gpf_; gpf_ = gpf_->next) { \
if ((gpf_ == gpl->actframe) || ((gpf_->flag & GP_FRAME_SELECT) && is_multiedit_)) { \
BKE_gpencil_parent_matrix_get(depsgraph_, obact_, gpl, gpstroke_iter.diff_mat); \
invert_m4_m4(gpstroke_iter.inverse_diff_mat, gpstroke_iter.diff_mat); \
/* loop over strokes */ \
- for (bGPDstroke *gps = gpf_->strokes.first; gps; gps = gps->next) { \
+ LISTBASE_FOREACH (bGPDstroke *, gps, &gpf_->strokes) { \
/* skip strokes that are invalid for current view */ \
if (ED_gpencil_stroke_can_use(C, gps) == false) \
continue; \
diff --git a/source/blender/editors/gpencil/gpencil_merge.c b/source/blender/editors/gpencil/gpencil_merge.c
index b80e8d6ac73..e71bf2098dd 100644
--- a/source/blender/editors/gpencil/gpencil_merge.c
+++ b/source/blender/editors/gpencil/gpencil_merge.c
@@ -117,7 +117,7 @@ static bGPDstroke *gpencil_prepare_stroke(bContext *C, wmOperator *op, int totpo
/* if not exist, create a new one */
if ((paint->brush == NULL) || (paint->brush->gpencil_settings == NULL)) {
/* create new brushes */
- BKE_brush_gpencil_paint_presets(bmain, ts);
+ BKE_brush_gpencil_paint_presets(bmain, ts, false);
}
Brush *brush = paint->brush;
diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c
index cb72553c68b..4e83c4fb11c 100644
--- a/source/blender/editors/gpencil/gpencil_paint.c
+++ b/source/blender/editors/gpencil/gpencil_paint.c
@@ -1814,7 +1814,7 @@ static void gp_init_drawing_brush(bContext *C, tGPsdata *p)
/* if not exist, create a new one */
if ((paint->brush == NULL) || (paint->brush->gpencil_settings == NULL)) {
/* create new brushes */
- BKE_brush_gpencil_paint_presets(bmain, ts);
+ BKE_brush_gpencil_paint_presets(bmain, ts, true);
changed = true;
}
/* Be sure curves are initializated. */
@@ -2071,8 +2071,15 @@ static void gp_paint_initstroke(tGPsdata *p, eGPencil_PaintModes paintmode, Deps
return;
}
- /* Eraser mode: If no active strokes, just return. */
+ /* Eraser mode: If no active strokes, add one or just return. */
if (paintmode == GP_PAINTMODE_ERASER) {
+ /* Eraser mode:
+ * 1) Add new frames to all frames that we might touch,
+ * 2) Ensure that p->gpf refers to the frame used for the active layer
+ * (to avoid problems with other tools which expect it to exist)
+ *
+ * This is done only if additive drawing is enabled.
+ */
bool has_layer_to_erase = false;
LISTBASE_FOREACH (bGPDlayer *, gpl, &p->gpd->layers) {
@@ -2081,12 +2088,27 @@ static void gp_paint_initstroke(tGPsdata *p, eGPencil_PaintModes paintmode, Deps
continue;
}
+ /* Add a new frame if needed (and based off the active frame,
+ * as we need some existing strokes to erase)
+ *
+ * Note: We don't add a new frame if there's nothing there now, so
+ * -> If there are no frames at all, don't add one
+ * -> If there are no strokes in that frame, don't add a new empty frame
+ */
if (gpl->actframe && gpl->actframe->strokes.first) {
+ if (ts->gpencil_flags & GP_TOOL_FLAG_RETAIN_LAST) {
+ gpl->actframe = BKE_gpencil_layer_frame_get(gpl, CFRA, GP_GETFRAME_ADD_COPY);
+ }
has_layer_to_erase = true;
break;
}
}
+ /* Ensure this gets set. */
+ if (ts->gpencil_flags & GP_TOOL_FLAG_RETAIN_LAST) {
+ p->gpf = p->gpl->actframe;
+ }
+
if (has_layer_to_erase == false) {
p->status = GP_STATUS_ERROR;
return;
diff --git a/source/blender/editors/gpencil/gpencil_primitive.c b/source/blender/editors/gpencil/gpencil_primitive.c
index 1778162c1a3..875a6265497 100644
--- a/source/blender/editors/gpencil/gpencil_primitive.c
+++ b/source/blender/editors/gpencil/gpencil_primitive.c
@@ -1178,7 +1178,7 @@ static void gpencil_primitive_init(bContext *C, wmOperator *op)
/* if brush doesn't exist, create a new set (fix damaged files from old versions) */
if ((paint->brush == NULL) || (paint->brush->gpencil_settings == NULL)) {
- BKE_brush_gpencil_paint_presets(bmain, ts);
+ BKE_brush_gpencil_paint_presets(bmain, ts, true);
}
/* Set Draw brush. */
diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c
index 407571d18c8..3cab26eab44 100644
--- a/source/blender/editors/gpencil/gpencil_utils.c
+++ b/source/blender/editors/gpencil/gpencil_utils.c
@@ -1365,7 +1365,7 @@ void ED_gpencil_add_defaults(bContext *C, Object *ob)
/* if not exist, create a new one */
if ((paint->brush == NULL) || (paint->brush->gpencil_settings == NULL)) {
/* create new brushes */
- BKE_brush_gpencil_paint_presets(bmain, ts);
+ BKE_brush_gpencil_paint_presets(bmain, ts, true);
}
/* ensure a color exists and is assigned to object */
diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h
index 32e62a6436c..e6d39d5f966 100644
--- a/source/blender/editors/include/ED_object.h
+++ b/source/blender/editors/include/ED_object.h
@@ -260,6 +260,7 @@ float ED_object_new_primitive_matrix(struct bContext *C,
#define OBJECT_ADD_SIZE_MAXF 1.0e12f
void ED_object_add_unit_props_size(struct wmOperatorType *ot);
+void ED_object_add_unit_props_radius_ex(struct wmOperatorType *ot, float default_value);
void ED_object_add_unit_props_radius(struct wmOperatorType *ot);
void ED_object_add_generic_props(struct wmOperatorType *ot, bool do_editmode);
void ED_object_add_mesh_props(struct wmOperatorType *ot);
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h
index 43f3a578bfe..bc6a4b23609 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -347,6 +347,7 @@ bool ED_operator_info_active(struct bContext *C);
bool ED_operator_console_active(struct bContext *C);
bool ED_operator_object_active(struct bContext *C);
+bool ED_operator_object_active_editable_ex(struct bContext *C, const Object *ob);
bool ED_operator_object_active_editable(struct bContext *C);
bool ED_operator_object_active_editable_mesh(struct bContext *C);
bool ED_operator_object_active_editable_font(struct bContext *C);
diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h
index 27b7511c8a2..9969acd04b7 100644
--- a/source/blender/editors/include/ED_transform.h
+++ b/source/blender/editors/include/ED_transform.h
@@ -158,7 +158,7 @@ int BIF_countTransformOrientation(const struct bContext *C);
#define P_CURSOR_EDIT (1 << 14)
#define P_CLNOR_INVALIDATE (1 << 15)
/* For properties performed when confirming the transformation. */
-#define P_POST_TRANSFORM (1 << 16)
+#define P_POST_TRANSFORM (1 << 19)
void Transform_Properties(struct wmOperatorType *ot, int flags);
diff --git a/source/blender/editors/include/ED_uvedit.h b/source/blender/editors/include/ED_uvedit.h
index 8c565536c71..f656aaf9c07 100644
--- a/source/blender/editors/include/ED_uvedit.h
+++ b/source/blender/editors/include/ED_uvedit.h
@@ -50,20 +50,17 @@ void ED_operatortypes_uvedit(void);
void ED_keymap_uvedit(struct wmKeyConfig *keyconf);
bool ED_uvedit_minmax(const struct Scene *scene,
- struct Image *ima,
struct Object *obedit,
float min[2],
float max[2]);
void ED_uvedit_select_all(struct BMesh *bm);
bool ED_uvedit_minmax_multi(const struct Scene *scene,
- struct Image *ima,
struct Object **objects_edit,
uint objects_len,
float r_min[2],
float r_max[2]);
bool ED_uvedit_center_multi(const struct Scene *scene,
- Image *ima,
struct Object **objects_edit,
uint objects_len,
float r_cent[2],
@@ -95,11 +92,7 @@ void ED_object_assign_active_image(struct Main *bmain,
bool ED_uvedit_test(struct Object *obedit);
/* visibility and selection */
-bool uvedit_face_visible_nolocal_ex(const struct ToolSettings *ts, struct BMFace *efa);
-bool uvedit_face_visible_test_ex(const struct ToolSettings *ts,
- struct Object *obedit,
- struct Image *ima,
- struct BMFace *efa);
+bool uvedit_face_visible_test_ex(const struct ToolSettings *ts, struct BMFace *efa);
bool uvedit_face_select_test_ex(const struct ToolSettings *ts,
struct BMFace *efa,
const int cd_loop_uv_offset);
@@ -110,11 +103,7 @@ bool uvedit_uv_select_test_ex(const struct ToolSettings *ts,
struct BMLoop *l,
const int cd_loop_uv_offset);
-bool uvedit_face_visible_nolocal(const struct Scene *scene, struct BMFace *efa);
-bool uvedit_face_visible_test(const struct Scene *scene,
- struct Object *obedit,
- struct Image *ima,
- struct BMFace *efa);
+bool uvedit_face_visible_test(const struct Scene *scene, struct BMFace *efa);
bool uvedit_face_select_test(const struct Scene *scene,
struct BMFace *efa,
const int cd_loop_uv_offset);
@@ -175,12 +164,10 @@ void uvedit_uv_select_disable(struct BMEditMesh *em,
bool ED_uvedit_nearest_uv(const struct Scene *scene,
struct Object *obedit,
- struct Image *ima,
const float co[2],
float *dist_sq,
float r_uv[2]);
bool ED_uvedit_nearest_uv_multi(const struct Scene *scene,
- struct Image *ima,
struct Object **objects,
const uint objects_len,
const float co[2],
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 8b7b0430765..3ad1608b47b 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -2417,6 +2417,8 @@ uiBut *UI_context_active_but_prop_get(const struct bContext *C,
struct PropertyRNA **r_prop,
int *r_index);
void UI_context_active_but_prop_handle(struct bContext *C);
+void UI_context_active_but_clear(struct bContext *C, struct wmWindow *win, struct ARegion *region);
+
struct wmOperator *UI_context_active_operator_get(const struct bContext *C);
void UI_context_update_anim_flag(const struct bContext *C);
void UI_context_active_but_prop_get_filebrowser(const struct bContext *C,
diff --git a/source/blender/editors/interface/interface_eyedropper_color.c b/source/blender/editors/interface/interface_eyedropper_color.c
index 7527a1e0662..ace367fd513 100644
--- a/source/blender/editors/interface/interface_eyedropper_color.c
+++ b/source/blender/editors/interface/interface_eyedropper_color.c
@@ -82,11 +82,13 @@ static bool eyedropper_init(bContext *C, wmOperator *op)
eye->use_accum = RNA_boolean_get(op->ptr, "use_accumulate");
uiBut *but = UI_context_active_but_prop_get(C, &eye->ptr, &eye->prop, &eye->index);
+ const enum PropertySubType prop_subtype = eye->prop ? RNA_property_subtype(eye->prop) : 0;
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)) {
+ (RNA_property_type(eye->prop) != PROP_FLOAT) ||
+ (ELEM(prop_subtype, PROP_COLOR, PROP_COLOR_GAMMA) == 0)) {
MEM_freeN(eye);
return false;
}
@@ -96,7 +98,7 @@ static bool eyedropper_init(bContext *C, wmOperator *op)
float col[4];
RNA_property_float_get_array(&eye->ptr, eye->prop, col);
- if (RNA_property_subtype(eye->prop) != PROP_COLOR) {
+ if (prop_subtype != PROP_COLOR) {
Scene *scene = CTX_data_scene(C);
const char *display_device;
@@ -290,7 +292,10 @@ static int eyedropper_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(
{
/* init */
if (eyedropper_init(C, op)) {
- WM_cursor_modal_set(CTX_wm_window(C), WM_CURSOR_EYEDROPPER);
+ wmWindow *win = CTX_wm_window(C);
+ /* Workaround for de-activating the button clearing the cursor, see T76794 */
+ UI_context_active_but_clear(C, win, CTX_wm_region(C));
+ WM_cursor_modal_set(win, WM_CURSOR_EYEDROPPER);
/* add temp handler */
WM_event_add_modal_handler(C, op);
diff --git a/source/blender/editors/interface/interface_eyedropper_colorband.c b/source/blender/editors/interface/interface_eyedropper_colorband.c
index be23eacafff..24d06361c54 100644
--- a/source/blender/editors/interface/interface_eyedropper_colorband.c
+++ b/source/blender/editors/interface/interface_eyedropper_colorband.c
@@ -304,7 +304,10 @@ static int eyedropper_colorband_invoke(bContext *C, wmOperator *op, const wmEven
{
/* init */
if (eyedropper_colorband_init(C, op)) {
- WM_cursor_modal_set(CTX_wm_window(C), WM_CURSOR_EYEDROPPER);
+ wmWindow *win = CTX_wm_window(C);
+ /* Workaround for de-activating the button clearing the cursor, see T76794 */
+ UI_context_active_but_clear(C, win, CTX_wm_region(C));
+ WM_cursor_modal_set(win, WM_CURSOR_EYEDROPPER);
/* add temp handler */
WM_event_add_modal_handler(C, op);
diff --git a/source/blender/editors/interface/interface_eyedropper_datablock.c b/source/blender/editors/interface/interface_eyedropper_datablock.c
index d9c77c26941..f2217db9b7d 100644
--- a/source/blender/editors/interface/interface_eyedropper_datablock.c
+++ b/source/blender/editors/interface/interface_eyedropper_datablock.c
@@ -316,7 +316,10 @@ static int datadropper_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED
{
/* init */
if (datadropper_init(C, op)) {
- WM_cursor_modal_set(CTX_wm_window(C), WM_CURSOR_EYEDROPPER);
+ wmWindow *win = CTX_wm_window(C);
+ /* Workaround for de-activating the button clearing the cursor, see T76794 */
+ UI_context_active_but_clear(C, win, CTX_wm_region(C));
+ WM_cursor_modal_set(win, WM_CURSOR_EYEDROPPER);
/* add temp handler */
WM_event_add_modal_handler(C, op);
diff --git a/source/blender/editors/interface/interface_eyedropper_depth.c b/source/blender/editors/interface/interface_eyedropper_depth.c
index 907da917e75..5c85edc94a1 100644
--- a/source/blender/editors/interface/interface_eyedropper_depth.c
+++ b/source/blender/editors/interface/interface_eyedropper_depth.c
@@ -311,7 +311,10 @@ static int depthdropper_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSE
{
/* init */
if (depthdropper_init(C, op)) {
- WM_cursor_modal_set(CTX_wm_window(C), WM_CURSOR_EYEDROPPER);
+ wmWindow *win = CTX_wm_window(C);
+ /* Workaround for de-activating the button clearing the cursor, see T76794 */
+ UI_context_active_but_clear(C, win, CTX_wm_region(C));
+ WM_cursor_modal_set(win, WM_CURSOR_EYEDROPPER);
/* add temp handler */
WM_event_add_modal_handler(C, op);
diff --git a/source/blender/editors/interface/interface_eyedropper_driver.c b/source/blender/editors/interface/interface_eyedropper_driver.c
index 89c087855bc..276cc70f2b5 100644
--- a/source/blender/editors/interface/interface_eyedropper_driver.c
+++ b/source/blender/editors/interface/interface_eyedropper_driver.c
@@ -180,7 +180,10 @@ static int driverdropper_invoke(bContext *C, wmOperator *op, const wmEvent *UNUS
{
/* init */
if (driverdropper_init(C, op)) {
- WM_cursor_modal_set(CTX_wm_window(C), WM_CURSOR_EYEDROPPER);
+ wmWindow *win = CTX_wm_window(C);
+ /* Workaround for de-activating the button clearing the cursor, see T76794 */
+ UI_context_active_but_clear(C, win, CTX_wm_region(C));
+ WM_cursor_modal_set(win, WM_CURSOR_EYEDROPPER);
/* add temp handler */
WM_event_add_modal_handler(C, op);
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index ebde1d54c07..eb99d044e17 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -5559,7 +5559,7 @@ static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, co
}
else if (but->type == UI_BTYPE_MENU) {
if (ELEM(event->type, WHEELDOWNMOUSE, WHEELUPMOUSE) && event->ctrl) {
- const int direction = (event->type == WHEELDOWNMOUSE) ? -1 : 1;
+ const int direction = (event->type == WHEELDOWNMOUSE) ? 1 : -1;
data->value = ui_but_menu_step(but, direction);
@@ -8337,6 +8337,11 @@ void UI_context_active_but_prop_handle(bContext *C)
}
}
+void UI_context_active_but_clear(bContext *C, wmWindow *win, ARegion *region)
+{
+ wm_event_handler_ui_cancel_ex(C, win, region, false);
+}
+
wmOperator *UI_context_active_operator_get(const struct bContext *C)
{
ARegion *region_ctx = CTX_wm_region(C);
@@ -8868,7 +8873,7 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but)
if (post_but) {
button_activate_init(C, region, post_but, post_type);
}
- else {
+ else if (!((event->type == EVT_BUT_CANCEL) && (event->val == 1))) {
/* XXX issue is because WM_event_add_mousemove(wm) is a bad hack and not reliable,
* if that gets coded better this bypass can go away too.
*
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index fbcac6079ae..974fec13bee 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -105,7 +105,6 @@ extern const char ui_radial_dir_to_numpad[8];
extern const short ui_radial_dir_to_angle[8];
/* internal panel drawing defines */
-#define PNL_GRID (UI_UNIT_Y / 5) /* 4 default */
#define PNL_HEADER (UI_UNIT_Y * 1.2) /* 24 default */
/* bit button defines */
diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c
index 04179721305..c5f67e63bd3 100644
--- a/source/blender/editors/interface/interface_panel.c
+++ b/source/blender/editors/interface/interface_panel.c
@@ -1322,8 +1322,8 @@ static void ui_do_drag(const bContext *C, const wmEvent *event, Panel *panel)
return;
}
- dx = (event->x - data->startx) & ~(PNL_GRID - 1);
- dy = (event->y - data->starty) & ~(PNL_GRID - 1);
+ dx = (event->x - data->startx);
+ dy = (event->y - data->starty);
dx *= (float)BLI_rctf_size_x(&region->v2d.cur) / (float)BLI_rcti_size_x(&region->winrct);
dy *= (float)BLI_rctf_size_y(&region->v2d.cur) / (float)BLI_rcti_size_y(&region->winrct);
diff --git a/source/blender/editors/interface/interface_region_hud.c b/source/blender/editors/interface/interface_region_hud.c
index 34ac58c1dca..1f8af7b9e6e 100644
--- a/source/blender/editors/interface/interface_region_hud.c
+++ b/source/blender/editors/interface/interface_region_hud.c
@@ -177,11 +177,13 @@ static void hud_region_layout(const bContext *C, ARegion *region)
return;
}
+ ScrArea *area = CTX_wm_area(C);
int size_y = region->sizey;
ED_region_panels_layout(C, region);
- if (region->panels.first && (region->sizey != size_y)) {
+ if (region->panels.first &&
+ ((area->flag & AREA_FLAG_REGION_SIZE_UPDATE) || (region->sizey != size_y))) {
int winx_new = UI_DPI_FAC * (region->sizex + 0.5f);
int winy_new = UI_DPI_FAC * (region->sizey + 0.5f);
View2D *v2d = &region->v2d;
@@ -339,6 +341,7 @@ void ED_area_type_hud_ensure(bContext *C, ScrArea *area)
}
else {
if (region->flag & RGN_FLAG_HIDDEN) {
+ /* Also forces recalculating HUD size in hud_region_layout(). */
area->flag |= AREA_FLAG_REGION_SIZE_UPDATE;
}
region->flag &= ~RGN_FLAG_HIDDEN;
diff --git a/source/blender/editors/interface/interface_template_search_menu.c b/source/blender/editors/interface/interface_template_search_menu.c
index 0a06f765c0e..2c6b09168f4 100644
--- a/source/blender/editors/interface/interface_template_search_menu.c
+++ b/source/blender/editors/interface/interface_template_search_menu.c
@@ -41,6 +41,7 @@
#include "BLI_math_matrix.h"
#include "BLI_memarena.h"
#include "BLI_string.h"
+#include "BLI_string_utils.h"
#include "BLI_utildefines.h"
#include "BLT_translation.h"
@@ -177,7 +178,19 @@ static bool menu_items_from_ui_create_item_from_button(struct MenuSearch_Data *d
struct MenuSearch_Context *wm_context)
{
struct MenuSearch_Item *item = NULL;
+
+ /* Use override if the name is empty, this can happen with popovers. */
+ const char *drawstr_override = NULL;
+ const char *drawstr_sep = (but->flag & UI_BUT_HAS_SEP_CHAR) ?
+ strrchr(but->drawstr, UI_SEP_CHAR) :
+ NULL;
+ const bool drawstr_is_empty = (drawstr_sep == but->drawstr) || (but->drawstr[0] == '\0');
+
if (but->optype != NULL) {
+ if (drawstr_is_empty) {
+ drawstr_override = WM_operatortype_name(but->optype, but->opptr);
+ }
+
item = BLI_memarena_calloc(memarena, sizeof(*item));
item->type = MENU_SEARCH_TYPE_OP;
@@ -189,6 +202,25 @@ static bool menu_items_from_ui_create_item_from_button(struct MenuSearch_Data *d
}
else if (but->rnaprop != NULL) {
const int prop_type = RNA_property_type(but->rnaprop);
+
+ if (drawstr_is_empty) {
+ if (prop_type == PROP_ENUM) {
+ const int value_enum = (int)but->hardmax;
+ EnumPropertyItem enum_item;
+ if (RNA_property_enum_item_from_value_gettexted(
+ but->block->evil_C, &but->rnapoin, but->rnaprop, value_enum, &enum_item)) {
+ drawstr_override = enum_item.name;
+ }
+ else {
+ /* Should never happen. */
+ drawstr_override = "Unknown";
+ }
+ }
+ else {
+ drawstr_override = RNA_property_ui_name(but->rnaprop);
+ }
+ }
+
if (!ELEM(prop_type, PROP_BOOLEAN, PROP_ENUM)) {
/* Note that these buttons are not prevented,
* but aren't typically used in menus. */
@@ -213,7 +245,16 @@ static bool menu_items_from_ui_create_item_from_button(struct MenuSearch_Data *d
if (item != NULL) {
/* Handle shared settings. */
- item->drawstr = strdup_memarena(memarena, but->drawstr);
+ if (drawstr_override != NULL) {
+ const char *drawstr_suffix = drawstr_sep ? drawstr_sep : "";
+ char *drawstr_alloc = BLI_string_joinN("(", drawstr_override, ")", drawstr_suffix);
+ item->drawstr = strdup_memarena(memarena, drawstr_alloc);
+ MEM_freeN(drawstr_alloc);
+ }
+ else {
+ item->drawstr = strdup_memarena(memarena, but->drawstr);
+ }
+
item->icon = ui_but_icon(but);
item->state = (but->flag &
(UI_BUT_DISABLED | UI_BUT_INACTIVE | UI_BUT_REDALERT | UI_BUT_HAS_SEP_CHAR));
diff --git a/source/blender/editors/interface/view2d_draw.c b/source/blender/editors/interface/view2d_draw.c
index 17a95ba3fff..36213f919a3 100644
--- a/source/blender/editors/interface/view2d_draw.c
+++ b/source/blender/editors/interface/view2d_draw.c
@@ -40,6 +40,7 @@
#include "GPU_immediate.h"
#include "GPU_matrix.h"
+#include "GPU_state.h"
#include "WM_api.h"
@@ -196,7 +197,19 @@ static void draw_parallel_lines(const ParallelLinesSet *lines,
GPUVertFormat *format = immVertexFormat();
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ if (U.pixelsize > 1.0f) {
+ float viewport[4];
+ GPU_viewport_size_get_f(viewport);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR);
+ immUniform2fv("viewportSize", &viewport[2]);
+ /* -1.0f offset here is because the line is too fat due to the builtin antialiasing.
+ * TODO make a variant or a uniform to toggle it off. */
+ immUniform1f("lineWidth", U.pixelsize - 1.0f);
+ }
+ else {
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ }
immUniformColor3ubv(color);
immBegin(GPU_PRIM_LINES, steps * 2);
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index 74fba4d0cf9..2ee98f39306 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -303,10 +303,15 @@ void ED_object_add_unit_props_size(wmOperatorType *ot)
ot->srna, "size", 2.0f, 0.0, OBJECT_ADD_SIZE_MAXF, "Size", "", 0.001, 100.00);
}
-void ED_object_add_unit_props_radius(wmOperatorType *ot)
+void ED_object_add_unit_props_radius_ex(wmOperatorType *ot, float default_value)
{
RNA_def_float_distance(
- ot->srna, "radius", 1.0f, 0.0, OBJECT_ADD_SIZE_MAXF, "Radius", "", 0.001, 100.00);
+ ot->srna, "radius", default_value, 0.0, OBJECT_ADD_SIZE_MAXF, "Radius", "", 0.001, 100.00);
+}
+
+void ED_object_add_unit_props_radius(wmOperatorType *ot)
+{
+ ED_object_add_unit_props_radius_ex(ot, 1.0f);
}
void ED_object_add_generic_props(wmOperatorType *ot, bool do_editmode)
@@ -814,7 +819,10 @@ static int object_metaball_add_exec(bContext *C, wmOperator *op)
}
ED_object_new_primitive_matrix(C, obedit, loc, rot, mat);
- dia = RNA_float_get(op->ptr, "radius");
+ /* Halving here is done to account for constant values from #BKE_mball_element_add.
+ * While the default radius of the resulting meta element is 2,
+ * we want to pass in 1 so other values such as resolution are scaled by 1.0. */
+ dia = RNA_float_get(op->ptr, "radius") / 2;
ED_mball_add_primitive(C, obedit, mat, dia, RNA_enum_get(op->ptr, "type"));
@@ -845,7 +853,7 @@ void OBJECT_OT_metaball_add(wmOperatorType *ot)
ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_metaelem_type_items, 0, "Primitive", "");
- ED_object_add_unit_props_radius(ot);
+ ED_object_add_unit_props_radius_ex(ot, 2.0f);
ED_object_add_generic_props(ot, true);
}
diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c
index 46923b593b1..e84dbca2469 100644
--- a/source/blender/editors/object/object_bake_api.c
+++ b/source/blender/editors/object/object_bake_api.c
@@ -96,6 +96,7 @@ typedef struct BakeAPIRender {
bool is_cage;
float cage_extrusion;
+ float max_ray_distance;
int normal_space;
eBakeNormalSwizzle normal_swizzle[3];
@@ -737,6 +738,7 @@ static int bake(Render *re,
const bool is_selected_to_active,
const bool is_cage,
const float cage_extrusion,
+ const float max_ray_distance,
const int normal_space,
const eBakeNormalSwizzle normal_swizzle[],
const char *custom_cage,
@@ -1010,6 +1012,7 @@ static int bake(Render *re,
num_pixels,
ob_cage != NULL,
cage_extrusion,
+ max_ray_distance,
ob_low_eval->obmat,
(ob_cage ? ob_cage->obmat : ob_low_eval->obmat),
me_cage)) {
@@ -1024,7 +1027,7 @@ static int bake(Render *re,
highpoly[i].ob,
i,
pixel_array_high,
- num_pixels,
+ &bake_images,
depth,
pass_type,
pass_filter,
@@ -1046,7 +1049,7 @@ static int bake(Render *re,
ob_low_eval,
0,
pixel_array_low,
- num_pixels,
+ &bake_images,
depth,
pass_type,
pass_filter,
@@ -1305,6 +1308,7 @@ static void bake_init_api_data(wmOperator *op, bContext *C, BakeAPIRender *bkr)
bkr->is_selected_to_active = RNA_boolean_get(op->ptr, "use_selected_to_active");
bkr->is_cage = RNA_boolean_get(op->ptr, "use_cage");
bkr->cage_extrusion = RNA_float_get(op->ptr, "cage_extrusion");
+ bkr->max_ray_distance = RNA_float_get(op->ptr, "max_ray_distance");
bkr->normal_space = RNA_enum_get(op->ptr, "normal_space");
bkr->normal_swizzle[0] = RNA_enum_get(op->ptr, "normal_r");
@@ -1394,6 +1398,7 @@ static int bake_exec(bContext *C, wmOperator *op)
true,
bkr.is_cage,
bkr.cage_extrusion,
+ bkr.max_ray_distance,
bkr.normal_space,
bkr.normal_swizzle,
bkr.custom_cage,
@@ -1426,6 +1431,7 @@ static int bake_exec(bContext *C, wmOperator *op)
false,
bkr.is_cage,
bkr.cage_extrusion,
+ bkr.max_ray_distance,
bkr.normal_space,
bkr.normal_swizzle,
bkr.custom_cage,
@@ -1495,6 +1501,7 @@ static void bake_startjob(void *bkv, short *UNUSED(stop), short *do_update, floa
true,
bkr->is_cage,
bkr->cage_extrusion,
+ bkr->max_ray_distance,
bkr->normal_space,
bkr->normal_swizzle,
bkr->custom_cage,
@@ -1527,6 +1534,7 @@ static void bake_startjob(void *bkv, short *UNUSED(stop), short *do_update, floa
false,
bkr->is_cage,
bkr->cage_extrusion,
+ bkr->max_ray_distance,
bkr->normal_space,
bkr->normal_swizzle,
bkr->custom_cage,
@@ -1586,6 +1594,11 @@ static void bake_set_props(wmOperator *op, Scene *scene)
RNA_property_boolean_set(op->ptr, prop, (bake->flag & R_BAKE_TO_ACTIVE) != 0);
}
+ prop = RNA_struct_find_property(op->ptr, "max_ray_distance");
+ if (!RNA_property_is_set(op->ptr, prop)) {
+ RNA_property_float_set(op->ptr, prop, bake->max_ray_distance);
+ }
+
prop = RNA_struct_find_property(op->ptr, "cage_extrusion");
if (!RNA_property_is_set(op->ptr, prop)) {
RNA_property_float_set(op->ptr, prop, bake->cage_extrusion);
@@ -1766,12 +1779,23 @@ void OBJECT_OT_bake(wmOperatorType *ot)
"Selected to Active",
"Bake shading on the surface of selected objects to the active object");
RNA_def_float(ot->srna,
+ "max_ray_distance",
+ 0.0f,
+ 0.0f,
+ FLT_MAX,
+ "Max Ray Distance",
+ "The maximum ray distance for matching points between the active and selected "
+ "objects. If zero, there is no limit",
+ 0.0f,
+ 1.0f);
+ RNA_def_float(ot->srna,
"cage_extrusion",
0.0f,
0.0f,
FLT_MAX,
"Cage Extrusion",
- "Distance to use for the inward ray cast when using selected to active",
+ "Inflate the active object by the specified distance for baking. This helps "
+ "matching to points nearer to the outside of the selected object meshes",
0.0f,
1.0f);
RNA_def_string(ot->srna,
diff --git a/source/blender/editors/object/object_collection.c b/source/blender/editors/object/object_collection.c
index 74ba94fbf4c..7a83d582299 100644
--- a/source/blender/editors/object/object_collection.c
+++ b/source/blender/editors/object/object_collection.c
@@ -483,17 +483,13 @@ static int collection_link_exec(bContext *C, wmOperator *op)
/* Currently this should not be allowed (might be supported in the future though...). */
if (ID_IS_OVERRIDE_LIBRARY(&collection->id)) {
- BKE_report(op->reports,
- RPT_ERROR,
- "Could not add the collection because it is overridden.");
+ BKE_report(op->reports, RPT_ERROR, "Could not add the collection because it is overridden.");
return OPERATOR_CANCELLED;
}
/* Linked collections are already checked for by using RNA_collection_local_itemf
* but operator can be called without invoke */
if (ID_IS_LINKED(&collection->id)) {
- BKE_report(op->reports,
- RPT_ERROR,
- "Could not add the collection because it is linked.");
+ BKE_report(op->reports, RPT_ERROR, "Could not add the collection because it is linked.");
return OPERATOR_CANCELLED;
}
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index 690c63a2cbf..53a557c5871 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -1466,6 +1466,13 @@ static const EnumPropertyItem *object_mode_set_itemsf(bContext *C,
return item;
}
+static bool object_mode_set_poll(bContext *C)
+{
+ /* Needed as #ED_operator_object_active_editable doesn't call use 'active_object'. */
+ Object *ob = CTX_data_active_object(C);
+ return ED_operator_object_active_editable_ex(C, ob);
+}
+
static int object_mode_set_exec(bContext *C, wmOperator *op)
{
bool use_submode = STREQ(op->idname, "OBJECT_OT_mode_set_with_submode");
@@ -1551,7 +1558,7 @@ void OBJECT_OT_mode_set(wmOperatorType *ot)
/* api callbacks */
ot->exec = object_mode_set_exec;
- ot->poll = ED_operator_object_active_editable;
+ ot->poll = object_mode_set_poll;
/* flags */
ot->flag = 0; /* no register/undo here, leave it to operators being called */
diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c
index 6cafc51231c..ca2dec75160 100644
--- a/source/blender/editors/physics/particle_edit.c
+++ b/source/blender/editors/physics/particle_edit.c
@@ -5251,9 +5251,6 @@ static bool particle_edit_toggle_poll(bContext *C)
if (!ob->data || ID_IS_LINKED(ob->data)) {
return 0;
}
- if (CTX_data_edit_object(C)) {
- return 0;
- }
return (ob->particlesystem.first || BKE_modifiers_findby_type(ob, eModifierType_Cloth) ||
BKE_modifiers_findby_type(ob, eModifierType_Softbody));
diff --git a/source/blender/editors/physics/physics_fluid.c b/source/blender/editors/physics/physics_fluid.c
index ceaac201da3..8524870c15e 100644
--- a/source/blender/editors/physics/physics_fluid.c
+++ b/source/blender/editors/physics/physics_fluid.c
@@ -52,6 +52,7 @@
#include "DEG_depsgraph.h"
+#include "ED_object.h"
#include "ED_screen.h"
#include "PIL_time.h"
@@ -154,7 +155,7 @@ static bool fluid_initjob(
{
FluidModifierData *mmd = NULL;
FluidDomainSettings *mds;
- Object *ob = CTX_data_active_object(C);
+ Object *ob = ED_object_active_context(C);
mmd = (FluidModifierData *)BKE_modifiers_findby_type(ob, eModifierType_Fluid);
if (!mmd) {
@@ -170,7 +171,7 @@ static bool fluid_initjob(
job->bmain = CTX_data_main(C);
job->scene = CTX_data_scene(C);
job->depsgraph = CTX_data_depsgraph_pointer(C);
- job->ob = CTX_data_active_object(C);
+ job->ob = ob;
job->mmd = mmd;
job->type = op->type->idname;
job->name = op->type->name;
@@ -616,7 +617,7 @@ static int fluid_free_exec(struct bContext *C, struct wmOperator *op)
{
FluidModifierData *mmd = NULL;
FluidDomainSettings *mds;
- Object *ob = CTX_data_active_object(C);
+ Object *ob = ED_object_active_context(C);
Scene *scene = CTX_data_scene(C);
/*
@@ -679,7 +680,7 @@ static int fluid_pause_exec(struct bContext *C, struct wmOperator *op)
{
FluidModifierData *mmd = NULL;
FluidDomainSettings *mds;
- Object *ob = CTX_data_active_object(C);
+ Object *ob = ED_object_active_context(C);
/*
* Get modifier data
diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c
index 17049fdb28b..46827940b57 100644
--- a/source/blender/editors/render/render_internal.c
+++ b/source/blender/editors/render/render_internal.c
@@ -349,7 +349,6 @@ static int screen_render_exec(bContext *C, wmOperator *op)
RE_SetReports(re, op->reports);
- BLI_threaded_malloc_begin();
if (is_animation) {
RE_RenderAnim(re,
mainp,
@@ -363,7 +362,6 @@ static int screen_render_exec(bContext *C, wmOperator *op)
else {
RE_RenderFrame(re, mainp, scene, single_layer, camera_override, scene->r.cfra, is_write_still);
}
- BLI_threaded_malloc_end();
RE_SetReports(re, NULL);
@@ -391,16 +389,14 @@ static void make_renderinfo_string(const RenderStats *rs,
char *str)
{
char info_time_str[32]; // used to be extern to header_info.c
- uintptr_t mem_in_use, mmap_in_use, peak_memory;
- float megs_used_memory, mmap_used_memory, megs_peak_memory;
+ uintptr_t mem_in_use, peak_memory;
+ float megs_used_memory, megs_peak_memory;
char *spos = str;
mem_in_use = MEM_get_memory_in_use();
- mmap_in_use = MEM_get_mapped_memory_in_use();
peak_memory = MEM_get_peak_memory();
- megs_used_memory = (mem_in_use - mmap_in_use) / (1024.0 * 1024.0);
- mmap_used_memory = (mmap_in_use) / (1024.0 * 1024.0);
+ megs_used_memory = (mem_in_use) / (1024.0 * 1024.0);
megs_peak_memory = (peak_memory) / (1024.0 * 1024.0);
/* local view */
@@ -462,11 +458,7 @@ static void make_renderinfo_string(const RenderStats *rs,
}
if (rs->mem_peak == 0.0f) {
- spos += sprintf(spos,
- TIP_("| Mem:%.2fM (%.2fM, Peak %.2fM) "),
- megs_used_memory,
- mmap_used_memory,
- megs_peak_memory);
+ spos += sprintf(spos, TIP_("| Mem:%.2fM (Peak %.2fM) "), megs_used_memory, megs_peak_memory);
}
else {
spos += sprintf(spos, TIP_("| Mem:%.2fM, Peak: %.2fM "), rs->mem_used, rs->mem_peak);
diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c
index f2e8209b099..2861e851282 100644
--- a/source/blender/editors/render/render_opengl.c
+++ b/source/blender/editors/render/render_opengl.c
@@ -494,7 +494,7 @@ static void screen_opengl_render_apply(const bContext *C, OGLRender *oglrender)
scene,
oglrender->sizex,
oglrender->sizey,
- 100.0f,
+ 100,
false,
&context);
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index 5b808206935..f2bfcb7a395 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -339,7 +339,7 @@ bool ED_operator_console_active(bContext *C)
return ed_spacetype_test(C, SPACE_CONSOLE);
}
-static bool ed_object_hidden(Object *ob)
+static bool ed_object_hidden(const Object *ob)
{
/* if hidden but in edit mode, we still display, can happen with animation */
return ((ob->restrictflag & OB_RESTRICT_VIEWPORT) && !(ob->mode & OB_MODE_EDIT));
@@ -351,10 +351,15 @@ bool ED_operator_object_active(bContext *C)
return ((ob != NULL) && !ed_object_hidden(ob));
}
+bool ED_operator_object_active_editable_ex(bContext *UNUSED(C), const Object *ob)
+{
+ return ((ob != NULL) && !ID_IS_LINKED(ob) && !ed_object_hidden(ob));
+}
+
bool ED_operator_object_active_editable(bContext *C)
{
Object *ob = ED_object_active_context(C);
- return ((ob != NULL) && !ID_IS_LINKED(ob) && !ed_object_hidden(ob));
+ return ED_operator_object_active_editable_ex(C, ob);
}
bool ED_operator_object_active_editable_mesh(bContext *C)
@@ -4861,8 +4866,11 @@ static void SCREEN_OT_back_to_previous(struct wmOperatorType *ot)
/** \name Show User Preferences Operator
* \{ */
-static int userpref_show_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+static int userpref_show_exec(bContext *C, wmOperator *op)
{
+ wmWindow *win_cur = CTX_wm_window(C);
+ /* Use eventstate, not event from _invoke, so this can be called through exec(). */
+ const wmEvent *event = win_cur->eventstate;
int sizex = (500 + UI_NAVIGATION_REGION_WIDTH) * UI_DPI_FAC;
int sizey = 520 * UI_DPI_FAC;
@@ -4899,7 +4907,7 @@ static void SCREEN_OT_userpref_show(struct wmOperatorType *ot)
ot->idname = "SCREEN_OT_userpref_show";
/* api callbacks */
- ot->invoke = userpref_show_invoke;
+ ot->exec = userpref_show_exec;
ot->poll = ED_operator_screenactive;
}
@@ -4909,8 +4917,11 @@ static void SCREEN_OT_userpref_show(struct wmOperatorType *ot)
/** \name Show Drivers Editor Operator
* \{ */
-static int drivers_editor_show_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+static int drivers_editor_show_exec(bContext *C, wmOperator *op)
{
+ wmWindow *win_cur = CTX_wm_window(C);
+ /* Use eventstate, not event from _invoke, so this can be called through exec(). */
+ const wmEvent *event = win_cur->eventstate;
PointerRNA ptr = {NULL};
PropertyRNA *prop = NULL;
int index = -1;
@@ -4974,7 +4985,7 @@ static void SCREEN_OT_drivers_editor_show(struct wmOperatorType *ot)
ot->idname = "SCREEN_OT_drivers_editor_show";
/* api callbacks */
- ot->invoke = drivers_editor_show_invoke;
+ ot->exec = drivers_editor_show_exec;
ot->poll = ED_operator_screenactive;
}
@@ -4984,8 +4995,11 @@ static void SCREEN_OT_drivers_editor_show(struct wmOperatorType *ot)
/** \name Show Info Log Operator
* \{ */
-static int info_log_show_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+static int info_log_show_exec(bContext *C, wmOperator *op)
{
+ wmWindow *win_cur = CTX_wm_window(C);
+ /* Use eventstate, not event from _invoke, so this can be called through exec(). */
+ const wmEvent *event = win_cur->eventstate;
int sizex = 900 * UI_DPI_FAC;
int sizey = 580 * UI_DPI_FAC;
int shift_y = 480;
@@ -5015,7 +5029,7 @@ static void SCREEN_OT_info_log_show(struct wmOperatorType *ot)
ot->idname = "SCREEN_OT_info_log_show";
/* api callbacks */
- ot->invoke = info_log_show_invoke;
+ ot->exec = info_log_show_exec;
ot->poll = ED_operator_screenactive;
}
diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c
index e227db1c644..fd5018f76ff 100644
--- a/source/blender/editors/sculpt_paint/paint_image.c
+++ b/source/blender/editors/sculpt_paint/paint_image.c
@@ -1130,9 +1130,6 @@ static bool texture_paint_toggle_poll(bContext *C)
if (!ob->data || ID_IS_LINKED(ob->data)) {
return 0;
}
- if (CTX_data_edit_object(C)) {
- return 0;
- }
return 1;
}
diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c
index d607b6a9d6f..634e29ca400 100644
--- a/source/blender/editors/sculpt_paint/paint_ops.c
+++ b/source/blender/editors/sculpt_paint/paint_ops.c
@@ -731,7 +731,14 @@ static bool brush_generic_tool_set(bContext *C,
WM_main_add_notifier(NC_BRUSH | NA_EDITED, brush);
/* Tool System
- * This is needed for when there is a non-sculpt tool active (transform for e.g.) */
+ * This is needed for when there is a non-sculpt tool active (transform for e.g.).
+ * In case we are toggling (and the brush changed to the toggle_brush), we need to get the
+ * tool_name again. */
+ int tool_result = brush_tool(brush, paint->runtime.tool_offset);
+ ePaintMode paint_mode = BKE_paintmode_get_active_from_context(C);
+ const EnumPropertyItem *items = BKE_paint_get_tool_enum_from_paintmode(paint_mode);
+ RNA_enum_name_from_value(items, tool_result, &tool_name);
+
char tool_id[MAX_NAME];
SNPRINTF(tool_id, "builtin_brush.%s", tool_name);
WM_toolsystem_ref_set_by_id(C, tool_id);
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 045fd54b46a..855e7503e3b 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -7389,7 +7389,7 @@ static bool sculpt_no_multires_poll(bContext *C)
return false;
}
-static int sculpt_symmetrize_exec(bContext *C, wmOperator *UNUSED(op))
+static int sculpt_symmetrize_exec(bContext *C, wmOperator *op)
{
Object *ob = CTX_data_active_object(C);
const Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
@@ -7440,7 +7440,7 @@ static int sculpt_symmetrize_exec(bContext *C, wmOperator *UNUSED(op))
MirrorModifierData mmd = {{0}};
int axis = 0;
mmd.flag = 0;
- mmd.tolerance = 0.005f;
+ mmd.tolerance = RNA_float_get(op->ptr, "merge_tolerance");
switch (sd->symmetrize_direction) {
case BMO_SYMMETRIZE_NEGATIVE_X:
axis = 0;
@@ -7497,6 +7497,16 @@ static void SCULPT_OT_symmetrize(wmOperatorType *ot)
/* API callbacks. */
ot->exec = sculpt_symmetrize_exec;
ot->poll = sculpt_no_multires_poll;
+
+ RNA_def_float(ot->srna,
+ "merge_tolerance",
+ 0.001f,
+ 0.0f,
+ FLT_MAX,
+ "Merge Limit",
+ "Distance within which symmetrical vertices are merged",
+ 0.0f,
+ 1.0f);
}
/**** Toggle operator for turning sculpt mode on or off ****/
diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c
index 912a6e1aaf6..4a449e529d5 100644
--- a/source/blender/editors/sculpt_paint/sculpt_undo.c
+++ b/source/blender/editors/sculpt_paint/sculpt_undo.c
@@ -847,6 +847,7 @@ static void sculpt_undo_free_list(ListBase *lb)
sculpt_undo_geometry_free_data(&unode->geometry_original);
sculpt_undo_geometry_free_data(&unode->geometry_modified);
+ sculpt_undo_geometry_free_data(&unode->geometry_bmesh_enter);
if (unode->face_sets) {
MEM_freeN(unode->face_sets);
@@ -913,7 +914,7 @@ static void sculpt_undo_alloc_and_store_hidden(PBVH *pbvh, SculptUndoNode *unode
BKE_pbvh_node_get_grids(pbvh, node, &grid_indices, &totgrid, NULL, NULL, NULL);
- unode->grid_hidden = MEM_mapallocN(sizeof(*unode->grid_hidden) * totgrid, "unode->grid_hidden");
+ unode->grid_hidden = MEM_callocN(sizeof(*unode->grid_hidden) * totgrid, "unode->grid_hidden");
for (i = 0; i < totgrid; i++) {
if (grid_hidden[grid_indices[i]]) {
@@ -974,13 +975,11 @@ static SculptUndoNode *sculpt_undo_alloc_node(Object *ob, PBVHNode *node, Sculpt
maxgrid = 0;
}
- /* We will use this while sculpting, is mapalloc slow to access then? */
-
/* General TODO, fix count_alloc. */
switch (type) {
case SCULPT_UNDO_COORDS:
- unode->co = MEM_mapallocN(sizeof(float[3]) * allvert, "SculptUndoNode.co");
- unode->no = MEM_mapallocN(sizeof(short[3]) * allvert, "SculptUndoNode.no");
+ unode->co = MEM_callocN(sizeof(float[3]) * allvert, "SculptUndoNode.co");
+ unode->no = MEM_callocN(sizeof(short[3]) * allvert, "SculptUndoNode.no");
usculpt->undo_size = (sizeof(float[3]) + sizeof(short[3]) + sizeof(int)) * allvert;
break;
@@ -994,7 +993,7 @@ static SculptUndoNode *sculpt_undo_alloc_node(Object *ob, PBVHNode *node, Sculpt
break;
case SCULPT_UNDO_MASK:
- unode->mask = MEM_mapallocN(sizeof(float) * allvert, "SculptUndoNode.mask");
+ unode->mask = MEM_callocN(sizeof(float) * allvert, "SculptUndoNode.mask");
usculpt->undo_size += (sizeof(float) * sizeof(int)) * allvert;
@@ -1013,12 +1012,12 @@ static SculptUndoNode *sculpt_undo_alloc_node(Object *ob, PBVHNode *node, Sculpt
unode->maxgrid = maxgrid;
unode->totgrid = totgrid;
unode->gridsize = gridsize;
- unode->grids = MEM_mapallocN(sizeof(int) * totgrid, "SculptUndoNode.grids");
+ unode->grids = MEM_callocN(sizeof(int) * totgrid, "SculptUndoNode.grids");
}
else {
/* Regular mesh. */
unode->maxvert = ss->totvert;
- unode->index = MEM_mapallocN(sizeof(int) * allvert, "SculptUndoNode.index");
+ unode->index = MEM_callocN(sizeof(int) * allvert, "SculptUndoNode.index");
}
if (ss->deform_modifiers_active) {
diff --git a/source/blender/editors/sculpt_paint/sculpt_uv.c b/source/blender/editors/sculpt_paint/sculpt_uv.c
index a1094dde749..d6b259c9ac0 100644
--- a/source/blender/editors/sculpt_paint/sculpt_uv.c
+++ b/source/blender/editors/sculpt_paint/sculpt_uv.c
@@ -548,8 +548,7 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm
if (do_island_optimization) {
UvElement *element;
UvNearestHit hit = UV_NEAREST_HIT_INIT;
- Image *ima = CTX_data_edit_image(C);
- uv_find_nearest_vert(scene, ima, obedit, co, 0.0f, &hit);
+ uv_find_nearest_vert(scene, obedit, co, 0.0f, &hit);
element = BM_uv_element_get(data->elementMap, hit.efa, hit.l);
island_index = element->island;
diff --git a/source/blender/editors/space_console/console_draw.c b/source/blender/editors/space_console/console_draw.c
index 6c56e8dfb79..805e9608fec 100644
--- a/source/blender/editors/space_console/console_draw.c
+++ b/source/blender/editors/space_console/console_draw.c
@@ -91,7 +91,6 @@ void console_scrollback_prompt_end(SpaceConsole *sc, ConsoleLine *cl_dummy)
static int console_textview_begin(TextViewContext *tvc)
{
SpaceConsole *sc = (SpaceConsole *)tvc->arg1;
- tvc->lheight = sc->lheight * UI_DPI_FAC;
tvc->sel_start = sc->sel_start;
tvc->sel_end = sc->sel_end;
@@ -143,10 +142,7 @@ static void console_cursor_wrap_offset(
return;
}
-static void console_textview_draw_cursor(TextViewContext *tvc,
- int cwidth,
- int columns,
- int descender)
+static void console_textview_draw_cursor(TextViewContext *tvc, int cwidth, int columns)
{
int pen[2];
{
@@ -157,10 +153,10 @@ static void console_textview_draw_cursor(TextViewContext *tvc,
console_cursor_wrap_offset(sc->prompt, columns, &offl, &offc, NULL);
console_cursor_wrap_offset(cl->line, columns, &offl, &offc, cl->line + cl->cursor);
pen[0] = cwidth * offc;
- pen[1] = -2 - (tvc->lheight + descender) * offl;
+ pen[1] = -tvc->lheight * offl;
console_cursor_wrap_offset(cl->line + cl->cursor, columns, &offl, &offc, NULL);
- pen[1] += (tvc->lheight + descender) * offl;
+ pen[1] += tvc->lheight * offl;
pen[0] += tvc->draw_rect.xmin;
pen[1] += tvc->draw_rect.ymin;
@@ -172,8 +168,7 @@ static void console_textview_draw_cursor(TextViewContext *tvc,
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformThemeColor(TH_CONSOLE_CURSOR);
- immRectf(
- pos, pen[0] - U.pixelsize, pen[1], pen[0] + U.pixelsize, pen[1] + tvc->lheight + descender);
+ immRectf(pos, pen[0] - U.pixelsize, pen[1], pen[0] + U.pixelsize, pen[1] + tvc->lheight);
immUnbindProgram();
}
@@ -229,7 +224,7 @@ static int console_textview_main__internal(SpaceConsole *sc,
/* view */
tvc.sel_start = sc->sel_start;
tvc.sel_end = sc->sel_end;
- tvc.lheight = sc->lheight * 1.2f * UI_DPI_FAC;
+ tvc.lheight = sc->lheight * UI_DPI_FAC;
tvc.scroll_ymin = v2d->cur.ymin;
tvc.scroll_ymax = v2d->cur.ymax;
diff --git a/source/blender/editors/space_file/fsmenu.c b/source/blender/editors/space_file/fsmenu.c
index 66157296064..dc258157afd 100644
--- a/source/blender/editors/space_file/fsmenu.c
+++ b/source/blender/editors/space_file/fsmenu.c
@@ -848,6 +848,10 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks)
CFRelease(volEnum);
+ /* kLSSharedFileListFavoriteItems is deprecated, but available till macOS 10.15.
+ * Will have to find a new method to sync the Finder Favorites with File Browser. */
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
/* Finally get user favorite places */
if (read_bookmarks) {
UInt32 seed;
@@ -891,6 +895,7 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks)
CFRelease(pathesArray);
CFRelease(list);
}
+# pragma GCC diagnostic pop
}
# else
/* unix */
diff --git a/source/blender/editors/space_graph/graph_buttons.c b/source/blender/editors/space_graph/graph_buttons.c
index 6c984860efc..185bf029f1a 100644
--- a/source/blender/editors/space_graph/graph_buttons.c
+++ b/source/blender/editors/space_graph/graph_buttons.c
@@ -295,7 +295,7 @@ static void graphedit_activekey_handles_cb(bContext *C, void *fcu_ptr, void *bez
bezt->h2 = HD_ALIGN;
}
else {
- BKE_nurb_bezt_handle_test(bezt, SELECT, true);
+ BKE_nurb_bezt_handle_test(bezt, SELECT, true, false);
}
/* now call standard updates */
@@ -423,8 +423,7 @@ static void graph_panel_key_properties(const bContext *C, Panel *panel)
col = uiLayoutColumn(layout, true);
/* keyframe itself */
{
-
- uiItemL_respect_property_split(col, IFACE_("Key Value"), ICON_NONE);
+ uiItemL_respect_property_split(col, IFACE_("Key Frame"), ICON_NONE);
but = uiDefButR(block,
UI_BTYPE_NUM,
B_REDR,
@@ -435,16 +434,14 @@ static void graph_panel_key_properties(const bContext *C, Panel *panel)
UI_UNIT_Y,
&bezt_ptr,
"co",
- 1,
+ 0,
0,
0,
-1,
-1,
NULL);
- UI_but_func_set(but, graphedit_activekey_update_cb, fcu, bezt);
- UI_but_unit_type_set(but, unit);
- uiItemL_respect_property_split(col, IFACE_("Frame"), ICON_NONE);
+ uiItemL_respect_property_split(col, IFACE_("Value"), ICON_NONE);
but = uiDefButR(block,
UI_BTYPE_NUM,
B_REDR,
@@ -455,21 +452,42 @@ static void graph_panel_key_properties(const bContext *C, Panel *panel)
UI_UNIT_Y,
&bezt_ptr,
"co",
- 0,
+ 1,
0,
0,
-1,
-1,
NULL);
UI_but_func_set(but, graphedit_activekey_update_cb, fcu, bezt);
+ UI_but_unit_type_set(but, unit);
+
+ UI_but_func_set(but, graphedit_activekey_update_cb, fcu, bezt);
}
/* previous handle - only if previous was Bezier interpolation */
if ((prevbezt) && (prevbezt->ipo == BEZT_IPO_BEZ)) {
col = uiLayoutColumn(layout, true);
+ uiItemL_respect_property_split(col, IFACE_("Left Handle Type"), ICON_NONE);
+ but = uiDefButR(block,
+ UI_BTYPE_MENU,
+ B_REDR,
+ NULL,
+ 0,
+ 0,
+ but_max_width,
+ UI_UNIT_Y,
+ &bezt_ptr,
+ "handle_left_type",
+ 0,
+ 0,
+ 0,
+ -1,
+ -1,
+ "Type of left handle");
+ UI_but_func_set(but, graphedit_activekey_handles_cb, fcu, bezt);
- uiItemL_respect_property_split(col, IFACE_("Left Handle X"), ICON_NONE);
+ uiItemL_respect_property_split(col, IFACE_("Frame"), ICON_NONE);
but = uiDefButR(block,
UI_BTYPE_NUM,
B_REDR,
@@ -488,7 +506,7 @@ static void graph_panel_key_properties(const bContext *C, Panel *panel)
NULL);
UI_but_func_set(but, graphedit_activekey_left_handle_coord_cb, fcu, bezt);
- uiItemL_respect_property_split(col, IFACE_("Y"), ICON_NONE);
+ uiItemL_respect_property_split(col, IFACE_("Value"), ICON_NONE);
but = uiDefButR(block,
UI_BTYPE_NUM,
B_REDR,
@@ -507,8 +525,14 @@ static void graph_panel_key_properties(const bContext *C, Panel *panel)
NULL);
UI_but_func_set(but, graphedit_activekey_left_handle_coord_cb, fcu, bezt);
UI_but_unit_type_set(but, unit);
+ }
+
+ /* next handle - only if current is Bezier interpolation */
+ if (bezt->ipo == BEZT_IPO_BEZ) {
+ /* NOTE: special update callbacks are needed on the coords here due to T39911 */
- uiItemL_respect_property_split(col, IFACE_("Type"), ICON_NONE);
+ col = uiLayoutColumn(layout, true);
+ uiItemL_respect_property_split(col, IFACE_("Right Handle Type"), ICON_NONE);
but = uiDefButR(block,
UI_BTYPE_MENU,
B_REDR,
@@ -518,22 +542,16 @@ static void graph_panel_key_properties(const bContext *C, Panel *panel)
but_max_width,
UI_UNIT_Y,
&bezt_ptr,
- "handle_left_type",
+ "handle_right_type",
0,
0,
0,
-1,
-1,
- "Type of left handle");
+ "Type of right handle");
UI_but_func_set(but, graphedit_activekey_handles_cb, fcu, bezt);
- }
- /* next handle - only if current is Bezier interpolation */
- if (bezt->ipo == BEZT_IPO_BEZ) {
- /* NOTE: special update callbacks are needed on the coords here due to T39911 */
-
- col = uiLayoutColumn(layout, true);
- uiItemL_respect_property_split(col, IFACE_("Right Handle X"), ICON_NONE);
+ uiItemL_respect_property_split(col, IFACE_("Frame"), ICON_NONE);
but = uiDefButR(block,
UI_BTYPE_NUM,
B_REDR,
@@ -552,7 +570,7 @@ static void graph_panel_key_properties(const bContext *C, Panel *panel)
NULL);
UI_but_func_set(but, graphedit_activekey_right_handle_coord_cb, fcu, bezt);
- uiItemL_respect_property_split(col, IFACE_("Y"), ICON_NONE);
+ uiItemL_respect_property_split(col, IFACE_("Value"), ICON_NONE);
but = uiDefButR(block,
UI_BTYPE_NUM,
B_REDR,
@@ -571,25 +589,6 @@ static void graph_panel_key_properties(const bContext *C, Panel *panel)
NULL);
UI_but_func_set(but, graphedit_activekey_right_handle_coord_cb, fcu, bezt);
UI_but_unit_type_set(but, unit);
-
- uiItemL_respect_property_split(col, IFACE_("Type"), ICON_NONE);
- but = uiDefButR(block,
- UI_BTYPE_MENU,
- B_REDR,
- NULL,
- 0,
- 0,
- but_max_width,
- UI_UNIT_Y,
- &bezt_ptr,
- "handle_right_type",
- 0,
- 0,
- 0,
- -1,
- -1,
- "Type of right handle");
- UI_but_func_set(but, graphedit_activekey_handles_cb, fcu, bezt);
}
}
else {
diff --git a/source/blender/editors/space_graph/graph_draw.c b/source/blender/editors/space_graph/graph_draw.c
index eac87caf777..68fef5e921f 100644
--- a/source/blender/editors/space_graph/graph_draw.c
+++ b/source/blender/editors/space_graph/graph_draw.c
@@ -343,6 +343,10 @@ static void draw_fcurve_handles(SpaceGraph *sipo, FCurve *fcu)
uint color = GPU_vertformat_attr_add(
format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
+ if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) {
+ GPU_line_smooth(true);
+ }
+ GPU_blend(true);
immBeginAtMost(GPU_PRIM_LINES, 4 * 2 * fcu->totvert);
@@ -419,6 +423,10 @@ static void draw_fcurve_handles(SpaceGraph *sipo, FCurve *fcu)
immEnd();
immUnbindProgram();
+ GPU_blend(false);
+ if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) {
+ GPU_line_smooth(false);
+ }
}
/* Samples ---------------- */
@@ -1181,9 +1189,7 @@ void graph_draw_curves(bAnimContext *ac, SpaceGraph *sipo, ARegion *region, shor
if (do_handles) {
/* only draw handles/vertices on keyframes */
- GPU_blend(true);
draw_fcurve_handles(sipo, fcu);
- GPU_blend(false);
}
draw_fcurve_vertices(region, fcu, do_handles, (sipo->flag & SIPO_SELVHANDLESONLY));
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index eb97077f77a..8cb85ce9800 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -885,7 +885,6 @@ static int image_view_selected_exec(bContext *C, wmOperator *UNUSED(op))
Scene *scene;
ViewLayer *view_layer;
Object *obedit;
- Image *ima;
/* retrieve state */
sima = CTX_wm_space_image(C);
@@ -894,15 +893,13 @@ static int image_view_selected_exec(bContext *C, wmOperator *UNUSED(op))
view_layer = CTX_data_view_layer(C);
obedit = CTX_data_edit_object(C);
- ima = ED_space_image(sima);
-
/* get bounds */
float min[2], max[2];
if (ED_space_image_show_uvedit(sima, obedit)) {
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
view_layer, ((View3D *)NULL), &objects_len);
- bool success = ED_uvedit_minmax_multi(scene, ima, objects, objects_len, min, max);
+ bool success = ED_uvedit_minmax_multi(scene, objects, objects_len, min, max);
MEM_freeN(objects);
if (!success) {
return OPERATOR_CANCELLED;
diff --git a/source/blender/editors/space_image/image_undo.c b/source/blender/editors/space_image/image_undo.c
index eb1c46240cb..5668b88826e 100644
--- a/source/blender/editors/space_image/image_undo.c
+++ b/source/blender/editors/space_image/image_undo.c
@@ -225,9 +225,9 @@ void *ED_image_paint_tile_push(ListBase *paint_tiles,
"PaintTile.mask");
}
- ptile->rect.pt = MEM_mapallocN((ibuf->rect_float ? sizeof(float[4]) : sizeof(char[4])) *
- square_i(ED_IMAGE_UNDO_TILE_SIZE),
- "PaintTile.rect");
+ ptile->rect.pt = MEM_callocN((ibuf->rect_float ? sizeof(float[4]) : sizeof(char[4])) *
+ square_i(ED_IMAGE_UNDO_TILE_SIZE),
+ "PaintTile.rect");
ptile->use_float = has_float;
ptile->valid = true;
diff --git a/source/blender/editors/space_info/info_draw.c b/source/blender/editors/space_info/info_draw.c
index 2a3f6d6e365..3685e5de852 100644
--- a/source/blender/editors/space_info/info_draw.c
+++ b/source/blender/editors/space_info/info_draw.c
@@ -141,7 +141,6 @@ static int report_textview_begin(TextViewContext *tvc)
{
const ReportList *reports = tvc->arg2;
- tvc->lheight = 14 * UI_DPI_FAC;
tvc->sel_start = 0;
tvc->sel_end = 0;
diff --git a/source/blender/editors/space_info/info_stats.c b/source/blender/editors/space_info/info_stats.c
index f8c0e66873f..dbd3b65857a 100644
--- a/source/blender/editors/space_info/info_stats.c
+++ b/source/blender/editors/space_info/info_stats.c
@@ -414,17 +414,11 @@ static const char *footer_string(ViewLayer *view_layer)
size_t ofs = 0;
uintptr_t mem_in_use = MEM_get_memory_in_use();
- uintptr_t mmap_in_use = MEM_get_mapped_memory_in_use();
/* get memory statistics */
- BLI_str_format_byte_unit(formatted_mem, mem_in_use - mmap_in_use, false);
+ BLI_str_format_byte_unit(formatted_mem, mem_in_use, false);
ofs = BLI_snprintf(memstr, MAX_INFO_MEM_LEN, TIP_("Mem: %s"), formatted_mem);
- if (mmap_in_use) {
- BLI_str_format_byte_unit(formatted_mem, mmap_in_use, false);
- BLI_snprintf(memstr + ofs, MAX_INFO_MEM_LEN - ofs, TIP_(" (%s)"), formatted_mem);
- }
-
if (GPU_mem_stats_supported()) {
int gpu_free_mem, gpu_tot_memory;
diff --git a/source/blender/editors/space_info/textview.c b/source/blender/editors/space_info/textview.c
index c842fa8b4ac..8076d3d7eaf 100644
--- a/source/blender/editors/space_info/textview.c
+++ b/source/blender/editors/space_info/textview.c
@@ -394,25 +394,26 @@ int textview_draw(TextViewContext *tvc,
tvc->line_get(tvc, &ext_line, &ext_len);
- if (!textview_draw_string(&tds,
- ext_line,
- ext_len,
- (data_flag & TVC_LINE_FG) ? fg : NULL,
- (data_flag & TVC_LINE_BG) ? bg : NULL,
- (data_flag & TVC_LINE_ICON) ? icon : 0,
- (data_flag & TVC_LINE_ICON_FG) ? icon_fg : NULL,
- (data_flag & TVC_LINE_ICON_BG) ? icon_bg : NULL,
- bg_sel)) {
- /* When drawing, if we pass v2d->cur.ymax, then quit. */
- if (do_draw) {
- /* Past the y limits. */
- break;
- }
- }
+ const bool is_out_of_view_y = !textview_draw_string(
+ &tds,
+ ext_line,
+ ext_len,
+ (data_flag & TVC_LINE_FG) ? fg : NULL,
+ (data_flag & TVC_LINE_BG) ? bg : NULL,
+ (data_flag & TVC_LINE_ICON) ? icon : 0,
+ (data_flag & TVC_LINE_ICON_FG) ? icon_fg : NULL,
+ (data_flag & TVC_LINE_ICON_BG) ? icon_bg : NULL,
+ bg_sel);
if (do_draw) {
+ /* We always want the cursor to draw. */
if (tvc->draw_cursor && iter_index == 0) {
- tvc->draw_cursor(tvc, tds.cwidth, tds.columns, tds.lofs);
+ tvc->draw_cursor(tvc, tds.cwidth, tds.columns);
+ }
+
+ /* When drawing, if we pass v2d->cur.ymax, then quit. */
+ if (is_out_of_view_y) {
+ break;
}
}
@@ -428,6 +429,11 @@ int textview_draw(TextViewContext *tvc,
tvc->end(tvc);
+ /* Sanity checks (bugs here can be tricky to track down). */
+ BLI_assert(tds.lheight == tvc->lheight);
+ BLI_assert(tds.row_vpadding == tvc->row_vpadding);
+ BLI_assert(tds.do_draw == do_draw);
+
xy[1] += tvc->lheight * 2;
return xy[1] - y_orig;
diff --git a/source/blender/editors/space_info/textview.h b/source/blender/editors/space_info/textview.h
index 8eef4ef5d56..41f8baf634e 100644
--- a/source/blender/editors/space_info/textview.h
+++ b/source/blender/editors/space_info/textview.h
@@ -60,7 +60,7 @@ typedef struct TextViewContext {
int *r_icon,
uchar r_icon_fg[4],
uchar r_icon_bg[4]);
- void (*draw_cursor)(struct TextViewContext *tvc, int cwidth, int columns, int descender);
+ void (*draw_cursor)(struct TextViewContext *tvc, int cwidth, int columns);
/* constant theme colors */
void (*const_colors)(struct TextViewContext *tvc, unsigned char bg_sel[4]);
const void *iter;
diff --git a/source/blender/editors/space_node/node_view.c b/source/blender/editors/space_node/node_view.c
index 740d090e641..e879e01ecc4 100644
--- a/source/blender/editors/space_node/node_view.c
+++ b/source/blender/editors/space_node/node_view.c
@@ -209,6 +209,7 @@ static int snode_bg_viewmove_modal(bContext *C, wmOperator *op, const wmEvent *e
ED_region_tag_redraw(region);
WM_main_add_notifier(NC_NODE | ND_DISPLAY, NULL);
+ WM_main_add_notifier(NC_SPACE | ND_SPACE_NODE_VIEW, NULL);
break;
@@ -354,6 +355,7 @@ static int backimage_fit_exec(bContext *C, wmOperator *UNUSED(op))
ED_region_tag_redraw(region);
WM_main_add_notifier(NC_NODE | ND_DISPLAY, NULL);
+ WM_main_add_notifier(NC_SPACE | ND_SPACE_NODE_VIEW, NULL);
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c
index 13cbda5aad7..7d3b95721c6 100644
--- a/source/blender/editors/space_outliner/outliner_draw.c
+++ b/source/blender/editors/space_outliner/outliner_draw.c
@@ -178,20 +178,13 @@ static void restrictbutton_r_lay_cb(bContext *C, void *poin, void *UNUSED(poin2)
WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, poin);
}
-static void restrictbutton_bone_visibility_cb(bContext *C, void *poin, void *poin2)
+static void restrictbutton_bone_visibility_cb(bContext *C, void *poin, void *UNUSED(poin2))
{
- bArmature *arm = (bArmature *)poin;
- Bone *bone = (Bone *)poin2;
- if (bone->flag & BONE_HIDDEN_P) {
- bone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
- }
+ Bone *bone = (Bone *)poin;
if (CTX_wm_window(C)->eventstate->ctrl) {
restrictbutton_recursive_bone(bone, BONE_HIDDEN_P, (bone->flag & BONE_HIDDEN_P) != 0);
}
-
- WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL);
- DEG_id_tag_update(&arm->id, ID_RECALC_COPY_ON_WRITE);
}
static void restrictbutton_bone_select_cb(bContext *C, void *UNUSED(poin), void *poin2)
@@ -859,6 +852,7 @@ typedef struct RestrictProperties {
*layer_collection_hide_viewport;
PropertyRNA *modifier_show_viewport, *modifier_show_render;
PropertyRNA *constraint_enable;
+ PropertyRNA *bone_hide_viewport;
} RestrictProperties;
/* We don't care about the value of the property
@@ -877,6 +871,7 @@ typedef struct RestrictPropertiesActive {
bool modifier_show_viewport;
bool modifier_show_render;
bool constraint_enable;
+ bool bone_hide_viewport;
} RestrictPropertiesActive;
static void outliner_restrict_properties_enable_collection_set(
@@ -1011,6 +1006,8 @@ static void outliner_draw_restrictbuts(uiBlock *block,
props.constraint_enable = RNA_struct_type_find_property(&RNA_Constraint, "mute");
+ props.bone_hide_viewport = RNA_struct_type_find_property(&RNA_Bone, "hide");
+
props.initialized = true;
}
@@ -1279,27 +1276,32 @@ static void outliner_draw_restrictbuts(uiBlock *block,
}
}
else if (tselem->type == TSE_POSE_CHANNEL) {
+ PointerRNA ptr;
bPoseChannel *pchan = (bPoseChannel *)te->directdata;
Bone *bone = pchan->bone;
Object *ob = (Object *)tselem->id;
+ bArmature *arm = ob->data;
+
+ RNA_pointer_create(&arm->id, &RNA_Bone, bone, &ptr);
if (soops->show_restrict_flags & SO_RESTRICT_VIEWPORT) {
- bt = uiDefIconButBitI(block,
- UI_BTYPE_ICON_TOGGLE,
- BONE_HIDDEN_P,
- 0,
- ICON_RESTRICT_VIEW_OFF,
- (int)(region->v2d.cur.xmax - restrict_offsets.viewport),
- te->ys,
- UI_UNIT_X,
- UI_UNIT_Y,
- &(bone->flag),
- 0,
- 0,
- 0,
- 0,
- TIP_("Restrict visibility in the 3D View"));
- UI_but_func_set(bt, restrictbutton_bone_visibility_cb, ob->data, bone);
+ bt = uiDefIconButR_prop(block,
+ UI_BTYPE_ICON_TOGGLE,
+ 0,
+ 0,
+ (int)(region->v2d.cur.xmax - restrict_offsets.viewport),
+ te->ys,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &ptr,
+ props.bone_hide_viewport,
+ -1,
+ 0,
+ 0,
+ -1,
+ -1,
+ TIP_("Restrict visibility in the 3D View"));
+ UI_but_func_set(bt, restrictbutton_bone_visibility_cb, bone, NULL);
UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
UI_but_drawflag_enable(bt, UI_BUT_ICON_REVERSE);
}
diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c
index 97ce9ad549f..3db75d9288b 100644
--- a/source/blender/editors/space_outliner/outliner_edit.c
+++ b/source/blender/editors/space_outliner/outliner_edit.c
@@ -460,6 +460,9 @@ void OUTLINER_OT_item_rename(wmOperatorType *ot)
ot->invoke = outliner_item_rename;
ot->poll = ED_operator_outliner_active;
+
+ /* Flags. */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/** \} */
@@ -578,6 +581,9 @@ void OUTLINER_OT_id_delete(wmOperatorType *ot)
ot->invoke = outliner_id_delete_invoke;
ot->poll = ED_operator_outliner_active;
+
+ /* Flags. */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/** \} */
@@ -715,7 +721,8 @@ void OUTLINER_OT_id_remap(wmOperatorType *ot)
ot->exec = outliner_id_remap_exec;
ot->poll = ED_operator_outliner_active;
- ot->flag = 0;
+ /* Flags. */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
prop = RNA_def_enum(ot->srna, "id_type", rna_enum_id_type_items, ID_OB, "ID Type", "");
RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_ID);
@@ -823,6 +830,7 @@ void OUTLINER_OT_id_copy(wmOperatorType *ot)
ot->exec = outliner_id_copy_exec;
ot->poll = ED_operator_outliner_active;
+ /* Flags, don't need any undo here (this operator does not change anything in Blender data). */
ot->flag = 0;
}
@@ -863,7 +871,8 @@ void OUTLINER_OT_id_paste(wmOperatorType *ot)
ot->exec = outliner_id_paste_exec;
ot->poll = ED_operator_outliner_active;
- ot->flag = 0;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/** \} */
@@ -974,6 +983,9 @@ void OUTLINER_OT_lib_relocate(wmOperatorType *ot)
ot->invoke = outliner_lib_relocate_invoke;
ot->poll = ED_operator_outliner_active;
+
+ /* Flags. */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* XXX This does not work with several items
@@ -1028,6 +1040,9 @@ void OUTLINER_OT_lib_reload(wmOperatorType *ot)
ot->invoke = outliner_lib_reload_invoke;
ot->poll = ED_operator_outliner_active;
+
+ /* Flags. */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
void lib_reload_cb(bContext *C,
diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c
index 0ccf982fd29..53f2c6a90d4 100644
--- a/source/blender/editors/space_outliner/outliner_tools.c
+++ b/source/blender/editors/space_outliner/outliner_tools.c
@@ -1450,7 +1450,8 @@ static int outliner_object_operation_exec(bContext *C, wmOperator *op)
}
else if (event == OL_OP_REMAP) {
outliner_do_libdata_operation(C, op->reports, scene, soops, &soops->tree, id_remap_cb, NULL);
- str = "Remap ID";
+ /* No undo push here, operator does it itself (since it's a modal one, the op_undo_depth trick
+ * does not work here). */
}
else if (event == OL_OP_LOCALIZED) { /* disabled, see above enum (ton) */
outliner_do_object_operation(C, op->reports, scene, soops, &soops->tree, id_local_cb);
@@ -1481,7 +1482,9 @@ static int outliner_object_operation_exec(bContext *C, wmOperator *op)
ED_outliner_select_sync_from_object_tag(C);
}
- ED_undo_push(C, str);
+ if (str != NULL) {
+ ED_undo_push(C, str);
+ }
return OPERATOR_FINISHED;
}
@@ -1681,6 +1684,7 @@ static const EnumPropertyItem *outliner_id_operation_itemf(bContext *C,
static int outliner_id_operation_exec(bContext *C, wmOperator *op)
{
+ wmWindowManager *wm = CTX_wm_manager(C);
Scene *scene = CTX_data_scene(C);
SpaceOutliner *soops = CTX_wm_space_outliner(C);
int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0;
@@ -1801,16 +1805,22 @@ static int outliner_id_operation_exec(bContext *C, wmOperator *op)
if (idlevel > 0) {
outliner_do_libdata_operation(
C, op->reports, scene, soops, &soops->tree, id_remap_cb, NULL);
- ED_undo_push(C, "Remap");
+ /* No undo push here, operator does it itself (since it's a modal one, the op_undo_depth
+ * trick does not work here). */
}
break;
}
case OUTLINER_IDOP_COPY: {
+ wm->op_undo_depth++;
WM_operator_name_call(C, "OUTLINER_OT_id_copy", WM_OP_INVOKE_DEFAULT, NULL);
+ wm->op_undo_depth--;
+ /* No need for undo, this operation does not change anything... */
break;
}
case OUTLINER_IDOP_PASTE: {
+ wm->op_undo_depth++;
WM_operator_name_call(C, "OUTLINER_OT_id_paste", WM_OP_INVOKE_DEFAULT, NULL);
+ wm->op_undo_depth--;
ED_outliner_select_sync_from_all_tag(C);
ED_undo_push(C, "Paste");
break;
@@ -1929,7 +1939,6 @@ static int outliner_lib_operation_exec(bContext *C, wmOperator *op)
switch (event) {
case OL_LIB_RENAME: {
- /* rename */
outliner_do_libdata_operation(
C, op->reports, scene, soops, &soops->tree, item_rename_cb, NULL);
@@ -1944,16 +1953,17 @@ static int outliner_lib_operation_exec(bContext *C, wmOperator *op)
break;
}
case OL_LIB_RELOCATE: {
- /* rename */
outliner_do_libdata_operation(
C, op->reports, scene, soops, &soops->tree, lib_relocate_cb, NULL);
- ED_undo_push(C, "Relocate Library");
+ /* No undo push here, operator does it itself (since it's a modal one, the op_undo_depth
+ * trick does not work here). */
break;
}
case OL_LIB_RELOAD: {
- /* rename */
outliner_do_libdata_operation(
C, op->reports, scene, soops, &soops->tree, lib_reload_cb, NULL);
+ /* No undo push here, operator does it itself (since it's a modal one, the op_undo_depth
+ * trick does not work here). */
break;
}
default:
@@ -2102,7 +2112,7 @@ void OUTLINER_OT_action_set(wmOperatorType *ot)
ot->poll = ED_operator_outliner_active;
/* flags */
- ot->flag = 0;
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* props */
// TODO: this would be nicer as an ID-pointer...
@@ -2150,6 +2160,7 @@ static const EnumPropertyItem prop_animdata_op_types[] = {
static int outliner_animdata_operation_exec(bContext *C, wmOperator *op)
{
+ wmWindowManager *wm = CTX_wm_manager(C);
SpaceOutliner *soops = CTX_wm_space_outliner(C);
int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0;
eOutliner_AnimDataOps event;
@@ -2178,7 +2189,10 @@ static int outliner_animdata_operation_exec(bContext *C, wmOperator *op)
case OUTLINER_ANIMOP_SET_ACT:
/* delegate once again... */
+ wm->op_undo_depth++;
WM_operator_name_call(C, "OUTLINER_OT_action_set", WM_OP_INVOKE_REGION_WIN, NULL);
+ wm->op_undo_depth--;
+ ED_undo_push(C, "Set active action");
break;
case OUTLINER_ANIMOP_CLEAR_ACT:
diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c
index 7965422c117..f81b4bb09e2 100644
--- a/source/blender/editors/space_view3d/view3d_buttons.c
+++ b/source/blender/editors/space_view3d/view3d_buttons.c
@@ -1005,7 +1005,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
}
}
BKE_nurb_test_2d(nu);
- BKE_nurb_handles_test(nu, true); /* test for bezier too */
+ BKE_nurb_handles_test(nu, true, false); /* test for bezier too */
nu = nu->next;
}
@@ -1577,9 +1577,7 @@ static void view3d_panel_transform(const bContext *C, Panel *panel)
}
else {
View3D *v3d = CTX_wm_view3d(C);
- Scene *scene = CTX_data_scene(C);
- const float lim = 10000.0f * max_ff(1.0f, ED_view3d_grid_scale(scene, v3d, NULL));
- v3d_editvertex_buts(col, v3d, ob, lim);
+ v3d_editvertex_buts(col, v3d, ob, FLT_MAX);
}
}
else if (ob->mode & OB_MODE_POSE) {
diff --git a/source/blender/editors/space_view3d/view3d_iterators.c b/source/blender/editors/space_view3d/view3d_iterators.c
index 08e68c9174e..2ad7797f6c8 100644
--- a/source/blender/editors/space_view3d/view3d_iterators.c
+++ b/source/blender/editors/space_view3d/view3d_iterators.c
@@ -126,7 +126,7 @@ void meshobject_foreachScreenVert(
Scene *scene_eval = DEG_get_evaluated_scene(vc->depsgraph);
Object *ob_eval = DEG_get_evaluated_object(vc->depsgraph, vc->obact);
- me = mesh_get_eval_deform(vc->depsgraph, scene_eval, ob_eval, &CD_MASK_BAREMESH);
+ me = mesh_get_eval_final(vc->depsgraph, scene_eval, ob_eval, &CD_MASK_BAREMESH);
ED_view3d_check_mats_rv3d(vc->rv3d);
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index 8e3ad55bae1..5fc65522fe6 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -825,17 +825,17 @@ static void transform_event_xyz_constraint(TransInfo *t, short key_type, bool is
}
}
else if (!edit_2d) {
- if (t->orientation.index == 0 || ELEM(cmode, '\0', axis)) {
+ if (t->orient_curr == 0 || ELEM(cmode, '\0', axis)) {
/* Successive presses on existing axis, cycle orientation modes. */
- t->orientation.index = (t->orientation.index + 1) % ARRAY_SIZE(t->orientation.types);
- initTransformOrientation(t->context, t, t->orientation.types[t->orientation.index]);
+ t->orient_curr = (short)((t->orient_curr + 1) % (int)ARRAY_SIZE(t->orient));
+ transform_orientations_current_set(t, t->orient_curr);
}
- if (t->orientation.index == 0) {
+ if (t->orient_curr == 0) {
stopConstraint(t);
}
else {
- const short orientation = t->orientation.types[t->orientation.index];
+ const short orientation = t->orient[t->orient_curr].type;
if (is_plane == false) {
setUserConstraint(t, orientation, constraint_axis, msg2);
}
@@ -896,74 +896,59 @@ int transformEvent(TransInfo *t, const wmEvent *event)
break;
case TFM_MODAL_TRANSLATE:
/* only switch when... */
- if (ELEM(t->mode,
- TFM_ROTATION,
- TFM_RESIZE,
- TFM_TRACKBALL,
- TFM_EDGE_SLIDE,
- TFM_VERT_SLIDE)) {
- restoreTransObjects(t);
- resetTransModal(t);
- resetTransRestrictions(t);
- transform_mode_init(t, NULL, TFM_TRANSLATION);
- initSnapping(t, NULL); // need to reinit after mode change
- t->redraw |= TREDRAW_HARD;
- handled = true;
- }
- else if (t->mode == TFM_SEQ_SLIDE) {
- t->flag ^= T_ALT_TRANSFORM;
- t->redraw |= TREDRAW_HARD;
- handled = true;
- }
- else {
- if (t->obedit_type == OB_MESH) {
- if ((t->mode == TFM_TRANSLATION) && (t->spacetype == SPACE_VIEW3D)) {
- restoreTransObjects(t);
+ if (t->mode == TFM_TRANSLATION) {
+ if ((t->obedit_type == OB_MESH) && (t->spacetype == SPACE_VIEW3D)) {
+ restoreTransObjects(t);
+ resetTransModal(t);
+ resetTransRestrictions(t);
+
+ /* first try edge slide */
+ transform_mode_init(t, NULL, TFM_EDGE_SLIDE);
+ /* if that fails, do vertex slide */
+ if (t->state == TRANS_CANCEL) {
resetTransModal(t);
+ t->state = TRANS_STARTING;
+ transform_mode_init(t, NULL, TFM_VERT_SLIDE);
+ }
+ /* vert slide can fail on unconnected vertices (rare but possible) */
+ if (t->state == TRANS_CANCEL) {
+ resetTransModal(t);
+ t->state = TRANS_STARTING;
+ restoreTransObjects(t);
resetTransRestrictions(t);
-
- /* first try edge slide */
- transform_mode_init(t, NULL, TFM_EDGE_SLIDE);
- /* if that fails, do vertex slide */
- if (t->state == TRANS_CANCEL) {
- resetTransModal(t);
- t->state = TRANS_STARTING;
- transform_mode_init(t, NULL, TFM_VERT_SLIDE);
- }
- /* vert slide can fail on unconnected vertices (rare but possible) */
- if (t->state == TRANS_CANCEL) {
- resetTransModal(t);
- t->state = TRANS_STARTING;
- restoreTransObjects(t);
- resetTransRestrictions(t);
- transform_mode_init(t, NULL, TFM_TRANSLATION);
- }
- initSnapping(t, NULL); // need to reinit after mode change
- t->redraw |= TREDRAW_HARD;
- handled = true;
+ transform_mode_init(t, NULL, TFM_TRANSLATION);
}
+ initSnapping(t, NULL); // need to reinit after mode change
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
}
else if (t->options & (CTX_MOVIECLIP | CTX_MASK)) {
- if (t->mode == TFM_TRANSLATION) {
- restoreTransObjects(t);
+ restoreTransObjects(t);
- t->flag ^= T_ALT_TRANSFORM;
- t->redraw |= TREDRAW_HARD;
- handled = true;
- }
+ t->flag ^= T_ALT_TRANSFORM;
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
}
}
+ else if (t->mode == TFM_SEQ_SLIDE) {
+ t->flag ^= T_ALT_TRANSFORM;
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ }
+ else if (transform_mode_is_changeable(t->mode)) {
+ restoreTransObjects(t);
+ resetTransModal(t);
+ resetTransRestrictions(t);
+ transform_mode_init(t, NULL, TFM_TRANSLATION);
+ initSnapping(t, NULL); // need to reinit after mode change
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ }
break;
case TFM_MODAL_ROTATE:
/* only switch when... */
if (!(t->options & CTX_TEXTURE) && !(t->options & (CTX_MOVIECLIP | CTX_MASK))) {
- if (ELEM(t->mode,
- TFM_ROTATION,
- TFM_RESIZE,
- TFM_TRACKBALL,
- TFM_TRANSLATION,
- TFM_EDGE_SLIDE,
- TFM_VERT_SLIDE)) {
+ if (transform_mode_is_changeable(t->mode)) {
restoreTransObjects(t);
resetTransModal(t);
resetTransRestrictions(t);
@@ -982,15 +967,23 @@ int transformEvent(TransInfo *t, const wmEvent *event)
break;
case TFM_MODAL_RESIZE:
/* only switch when... */
- if (ELEM(t->mode,
- TFM_ROTATION,
- TFM_TRANSLATION,
- TFM_TRACKBALL,
- TFM_EDGE_SLIDE,
- TFM_VERT_SLIDE)) {
+ if (t->mode == TFM_RESIZE) {
+ if (t->options & CTX_MOVIECLIP) {
+ restoreTransObjects(t);
+ t->flag ^= T_ALT_TRANSFORM;
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ }
+ }
+ else if (t->mode == TFM_SHRINKFATTEN) {
+ t->flag ^= T_ALT_TRANSFORM;
+ t->redraw |= TREDRAW_HARD;
+ handled = true;
+ }
+ else if (transform_mode_is_changeable(t->mode)) {
/* Scale isn't normally very useful after extrude along normals, see T39756 */
- if ((t->con.mode & CON_APPLY) && (t->con.orientation == V3D_ORIENT_NORMAL)) {
+ if ((t->con.mode & CON_APPLY) && (t->orient[t->orient_curr].type == V3D_ORIENT_NORMAL)) {
stopConstraint(t);
}
@@ -1002,20 +995,6 @@ int transformEvent(TransInfo *t, const wmEvent *event)
t->redraw |= TREDRAW_HARD;
handled = true;
}
- else if (t->mode == TFM_SHRINKFATTEN) {
- t->flag ^= T_ALT_TRANSFORM;
- t->redraw |= TREDRAW_HARD;
- handled = true;
- }
- else if (t->mode == TFM_RESIZE) {
- if (t->options & CTX_MOVIECLIP) {
- restoreTransObjects(t);
-
- t->flag ^= T_ALT_TRANSFORM;
- t->redraw |= TREDRAW_HARD;
- handled = true;
- }
- }
break;
case TFM_MODAL_SNAP_INV_ON:
@@ -1229,7 +1208,7 @@ int transformEvent(TransInfo *t, const wmEvent *event)
break;
}
/* only switch when... */
- if (ELEM(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL)) {
+ if (t->mode != TFM_TRANSLATION && transform_mode_is_changeable(t->mode)) {
restoreTransObjects(t);
resetTransModal(t);
resetTransRestrictions(t);
@@ -1244,7 +1223,7 @@ int transformEvent(TransInfo *t, const wmEvent *event)
break;
}
/* only switch when... */
- if (ELEM(t->mode, TFM_ROTATION, TFM_TRANSLATION, TFM_TRACKBALL)) {
+ if (t->mode != TFM_RESIZE && transform_mode_is_changeable(t->mode)) {
restoreTransObjects(t);
resetTransModal(t);
resetTransRestrictions(t);
@@ -1260,7 +1239,7 @@ int transformEvent(TransInfo *t, const wmEvent *event)
}
/* only switch when... */
if (!(t->options & CTX_TEXTURE)) {
- if (ELEM(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL, TFM_TRANSLATION)) {
+ if (transform_mode_is_changeable(t->mode)) {
restoreTransObjects(t);
resetTransModal(t);
resetTransRestrictions(t);
@@ -1615,6 +1594,17 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op)
int proportional = 0;
PropertyRNA *prop;
+ if (!(t->con.mode & CON_APPLY) && (t->flag & T_MODAL) &&
+ ELEM(t->mode, TFM_TRANSLATION, TFM_RESIZE)) {
+ /* When redoing these modes the first time, it's more convenient to save
+ * the Global orientation. */
+ mul_m3_v3(t->spacemtx, t->values_final);
+ unit_m3(t->spacemtx);
+
+ BLI_assert(t->orient_curr == 0);
+ t->orient[0].type = V3D_ORIENT_GLOBAL;
+ }
+
// Save back mode in case we're in the generic operator
if ((prop = RNA_struct_find_property(op->ptr, "mode"))) {
RNA_property_enum_set(op->ptr, prop, t->mode);
@@ -1723,19 +1713,20 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op)
}
if ((prop = RNA_struct_find_property(op->ptr, "orient_type"))) {
- short orient_set, orient_cur;
- orient_set = RNA_property_is_set(op->ptr, prop) ? RNA_property_enum_get(op->ptr, prop) : -1;
- orient_cur = t->orientation.types[t->orientation.index];
+ short orient_type_set, orient_type_curr;
+ orient_type_set = RNA_property_is_set(op->ptr, prop) ? RNA_property_enum_get(op->ptr, prop) :
+ -1;
+ orient_type_curr = t->orient[t->orient_curr].type;
- if (!ELEM(orient_cur, orient_set, V3D_ORIENT_CUSTOM_MATRIX)) {
- RNA_property_enum_set(op->ptr, prop, orient_cur);
- orient_set = orient_cur;
+ if (!ELEM(orient_type_curr, orient_type_set, V3D_ORIENT_CUSTOM_MATRIX)) {
+ RNA_property_enum_set(op->ptr, prop, orient_type_curr);
+ orient_type_set = orient_type_curr;
}
if (((prop = RNA_struct_find_property(op->ptr, "orient_matrix_type")) &&
!RNA_property_is_set(op->ptr, prop))) {
/* Set the first time to register on redo. */
- RNA_property_enum_set(op->ptr, prop, orient_set);
+ RNA_property_enum_set(op->ptr, prop, orient_type_set);
RNA_float_set_array(op->ptr, "orient_matrix", &t->spacemtx[0][0]);
}
}
@@ -1883,11 +1874,8 @@ bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
initTransInfo(C, t, op, event);
/* Use the custom orientation when it is set. */
- short orientation = t->orientation.types[0] == V3D_ORIENT_CUSTOM_MATRIX ?
- V3D_ORIENT_CUSTOM_MATRIX :
- t->orientation.types[t->orientation.index];
-
- initTransformOrientation(C, t, orientation);
+ short orient_index = t->orient[0].type == V3D_ORIENT_CUSTOM_MATRIX ? 0 : t->orient_curr;
+ transform_orientations_current_set(t, orient_index);
if (t->spacetype == SPACE_VIEW3D) {
t->draw_handle_apply = ED_region_draw_cb_activate(
@@ -2043,7 +2031,7 @@ bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
/* Constraint init from operator */
if (t->con.mode & CON_APPLY) {
- setUserConstraint(t, t->orientation.types[t->orientation.index], t->con.mode, "%s");
+ setUserConstraint(t, t->orient[t->orient_curr].type, t->con.mode, "%s");
}
/* Don't write into the values when non-modal because they are already set from operator redo
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index 503e7bd4691..7720660e2e8 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -113,13 +113,8 @@ typedef struct TransSnap {
} TransSnap;
typedef struct TransCon {
- short orientation;
/** Description of the constraint for header_print. */
char text[50];
- /** Matrix of the constraint space. */
- float mtx[3][3];
- /** Inverse matrix of the constraint space. */
- float imtx[3][3];
/** Projection constraint matrix (same as #imtx with some axis == 0). */
float pmtx[3][3];
/** Initial mouse value for visual calculation
@@ -139,8 +134,7 @@ typedef struct TransCon {
struct TransDataContainer *tc,
struct TransData *td,
const float in[3],
- float out[3],
- float pvec[3]);
+ float out[3]);
/** Apply function pointer for size transformation. */
void (*applySize)(struct TransInfo *t,
struct TransDataContainer *tc,
@@ -520,6 +514,7 @@ typedef struct TransInfo {
/** orientation matrix of the current space. */
float spacemtx[3][3];
+ float spacemtx_inv[3][3];
/** name of the current space, MAX_NAME. */
char spacename[64];
@@ -531,13 +526,11 @@ typedef struct TransInfo {
bool is_launch_event_tweak;
struct {
- short index;
- short types[3];
- /* this gets used when orientation.type[x] is V3D_ORIENT_CUSTOM */
- struct TransformOrientation *custom;
- /* this gets used when orientation.type[0] is V3D_ORIENT_CUSTOM_MATRIX */
- float custom_matrix[3][3];
- } orientation;
+ short type;
+ float matrix[3][3];
+ } orient[3];
+ short orient_curr;
+
/** backup from view3d, to restore on end. */
short gizmo_flag;
@@ -911,8 +904,13 @@ void getViewVector(const TransInfo *t, const float coord[3], float vec[3]);
void transform_data_ext_rotate(TransData *td, float mat[3][3], bool use_drot);
/*********************** Transform Orientations ******************************/
-
-void initTransformOrientation(struct bContext *C, TransInfo *t, short orientation);
+short transform_orientation_matrix_get(struct bContext *C,
+ TransInfo *t,
+ const short orientation,
+ const float custom[3][3],
+ float r_spacemtx[3][3]);
+const char *transform_orientations_spacename_get(TransInfo *t, const short orient_type);
+void transform_orientations_current_set(struct TransInfo *t, const short orient_index);
/* Those two fill in mat and return non-zero on success */
bool createSpaceNormal(float mat[3][3], const float normal[3]);
diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c
index b07eb6edf5a..0a6e0d6b7f5 100644
--- a/source/blender/editors/transform/transform_constraints.c
+++ b/source/blender/editors/transform/transform_constraints.c
@@ -42,6 +42,7 @@
#include "BLI_utildefines.h"
#include "BKE_context.h"
+#include "BKE_scene.h"
#include "ED_view3d.h"
@@ -57,6 +58,27 @@
static void drawObjectConstraint(TransInfo *t);
+static void projection_matrix_calc(const TransInfo *t, float r_pmtx[3][3])
+{
+ unit_m3(r_pmtx);
+
+ if (!(t->con.mode & CON_AXIS0)) {
+ zero_v3(r_pmtx[0]);
+ }
+
+ if (!(t->con.mode & CON_AXIS1)) {
+ zero_v3(r_pmtx[1]);
+ }
+
+ if (!(t->con.mode & CON_AXIS2)) {
+ zero_v3(r_pmtx[2]);
+ }
+
+ float mat[3][3];
+ mul_m3_m3m3(mat, r_pmtx, t->spacemtx_inv);
+ mul_m3_m3m3(r_pmtx, t->spacemtx, mat);
+}
+
/* ************************** CONSTRAINTS ************************* */
static void constraintValuesFinal(TransInfo *t, float vec[3])
{
@@ -121,11 +143,9 @@ void constraintNumInput(TransInfo *t, float vec[3])
}
}
-static void postConstraintChecks(TransInfo *t, float vec[3], float pvec[3])
+static void postConstraintChecks(TransInfo *t, float vec[3])
{
- int i = 0;
-
- mul_m3_v3(t->con.imtx, vec);
+ mul_m3_v3(t->spacemtx_inv, vec);
snapGridIncrement(t, vec);
@@ -155,17 +175,7 @@ static void postConstraintChecks(TransInfo *t, float vec[3], float pvec[3])
/* inverse transformation at the end */
}
- if (t->con.mode & CON_AXIS0) {
- pvec[i++] = vec[0];
- }
- if (t->con.mode & CON_AXIS1) {
- pvec[i++] = vec[1];
- }
- if (t->con.mode & CON_AXIS2) {
- pvec[i++] = vec[2];
- }
-
- mul_m3_v3(t->con.mtx, vec);
+ mul_m3_v3(t->spacemtx, vec);
}
static void viewAxisCorrectCenter(const TransInfo *t, float t_con_center[3])
@@ -298,7 +308,7 @@ static bool isPlaneProjectionViewAligned(const TransInfo *t)
int n = 0;
for (int i = 0; i < 3; i++) {
if (t->con.mode & (CON_AXIS0 << i)) {
- constraint_vector[n++] = t->con.mtx[i];
+ constraint_vector[n++] = t->spacemtx[i];
if (n == 2) {
break;
}
@@ -346,12 +356,8 @@ static void planeProjection(const TransInfo *t, const float in[3], float out[3])
* (in perspective mode, the view vector is relative to the position on screen)
*/
-static void applyAxisConstraintVec(TransInfo *t,
- TransDataContainer *UNUSED(tc),
- TransData *td,
- const float in[3],
- float out[3],
- float pvec[3])
+static void applyAxisConstraintVec(
+ TransInfo *t, TransDataContainer *UNUSED(tc), TransData *td, const float in[3], float out[3])
{
copy_v3_v3(out, in);
if (!td && t->con.mode & CON_APPLY) {
@@ -371,25 +377,25 @@ static void applyAxisConstraintVec(TransInfo *t,
float c[3];
if (t->con.mode & CON_AXIS0) {
- copy_v3_v3(c, t->con.mtx[0]);
+ copy_v3_v3(c, t->spacemtx[0]);
}
else if (t->con.mode & CON_AXIS1) {
- copy_v3_v3(c, t->con.mtx[1]);
+ copy_v3_v3(c, t->spacemtx[1]);
}
else if (t->con.mode & CON_AXIS2) {
- copy_v3_v3(c, t->con.mtx[2]);
+ copy_v3_v3(c, t->spacemtx[2]);
}
axisProjection(t, c, in, out);
}
}
- postConstraintChecks(t, out, pvec);
+ postConstraintChecks(t, out);
}
}
/*
* Generic callback for object based spatial constraints applied to linear motion
*
- * At first, the following is applied to the first data in the array
+ * At first, the following is applied without orientation
* The IN vector in projected into the constrained space and then further
* projected along the view vector.
* (in perspective mode, the view vector is relative to the position on screen)
@@ -397,61 +403,19 @@ static void applyAxisConstraintVec(TransInfo *t,
* Further down, that vector is mapped to each data's space.
*/
-static void applyObjectConstraintVec(TransInfo *t,
- TransDataContainer *tc,
- TransData *td,
- const float in[3],
- float out[3],
- float pvec[3])
+static void applyObjectConstraintVec(
+ TransInfo *t, TransDataContainer *tc, TransData *td, const float in[3], float out[3])
{
- copy_v3_v3(out, in);
- if (t->con.mode & CON_APPLY) {
- if (!td) {
- mul_m3_v3(t->con.pmtx, out);
-
- const int dims = getConstraintSpaceDimension(t);
- if (dims == 2) {
- if (!is_zero_v3(out)) {
- if (!isPlaneProjectionViewAligned(t)) {
- planeProjection(t, in, out);
- }
- }
- }
- else if (dims == 1) {
- float c[3];
-
- if (t->con.mode & CON_AXIS0) {
- copy_v3_v3(c, t->con.mtx[0]);
- }
- else if (t->con.mode & CON_AXIS1) {
- copy_v3_v3(c, t->con.mtx[1]);
- }
- else if (t->con.mode & CON_AXIS2) {
- copy_v3_v3(c, t->con.mtx[2]);
- }
- axisProjection(t, c, in, out);
- }
- postConstraintChecks(t, out, pvec);
- copy_v3_v3(out, pvec);
- }
- else {
- int i = 0;
-
- out[0] = out[1] = out[2] = 0.0f;
- if (t->con.mode & CON_AXIS0) {
- out[0] = in[i++];
- }
- if (t->con.mode & CON_AXIS1) {
- out[1] = in[i++];
- }
- if (t->con.mode & CON_AXIS2) {
- out[2] = in[i++];
- }
-
- mul_m3_v3(td->axismtx, out);
- if (t->flag & T_EDIT) {
- mul_m3_v3(tc->mat3_unit, out);
- }
+ if (!td) {
+ applyAxisConstraintVec(t, tc, td, in, out);
+ }
+ else {
+ /* Specific TransData's space. */
+ copy_v3_v3(out, in);
+ mul_m3_v3(t->spacemtx_inv, out);
+ mul_m3_v3(td->axismtx, out);
+ if (t->flag & T_EDIT) {
+ mul_m3_v3(tc->mat3_unit, out);
}
}
}
@@ -478,8 +442,8 @@ static void applyAxisConstraintSize(TransInfo *t,
smat[2][2] = 1.0f;
}
- mul_m3_m3m3(tmat, smat, t->con.imtx);
- mul_m3_m3m3(smat, t->con.mtx, tmat);
+ mul_m3_m3m3(tmat, smat, t->spacemtx_inv);
+ mul_m3_m3m3(smat, t->spacemtx, tmat);
}
}
@@ -539,15 +503,15 @@ static void applyAxisConstraintRot(
switch (mode) {
case CON_AXIS0:
case (CON_AXIS1 | CON_AXIS2):
- copy_v3_v3(vec, t->con.mtx[0]);
+ copy_v3_v3(vec, t->spacemtx[0]);
break;
case CON_AXIS1:
case (CON_AXIS0 | CON_AXIS2):
- copy_v3_v3(vec, t->con.mtx[1]);
+ copy_v3_v3(vec, t->spacemtx[1]);
break;
case CON_AXIS2:
case (CON_AXIS0 | CON_AXIS1):
- copy_v3_v3(vec, t->con.mtx[2]);
+ copy_v3_v3(vec, t->spacemtx[2]);
break;
}
/* don't flip axis if asked to or if num input */
@@ -620,12 +584,11 @@ static void applyObjectConstraintRot(
/*--------------------- INTERNAL SETUP CALLS ------------------*/
-void setConstraint(TransInfo *t, float space[3][3], int mode, const char text[])
+void setConstraint(TransInfo *t, int mode, const char text[])
{
BLI_strncpy(t->con.text + 1, text, sizeof(t->con.text) - 1);
- copy_m3_m3(t->con.mtx, space);
t->con.mode = mode;
- getConstraintMatrix(t);
+ projection_matrix_calc(t, t->con.pmtx);
startConstraint(t);
@@ -639,41 +602,25 @@ void setConstraint(TransInfo *t, float space[3][3], int mode, const char text[])
/* applies individual td->axismtx constraints */
void setAxisMatrixConstraint(TransInfo *t, int mode, const char text[])
{
- TransDataContainer *tc = t->data_container;
- if (t->data_len_all == 1) {
- float axismtx[3][3];
- if (t->flag & T_EDIT) {
- mul_m3_m3m3(axismtx, tc->mat3_unit, tc->data->axismtx);
- }
- else {
- copy_m3_m3(axismtx, tc->data->axismtx);
- }
-
- setConstraint(t, axismtx, mode, text);
- }
- else {
- BLI_strncpy(t->con.text + 1, text, sizeof(t->con.text) - 1);
- copy_m3_m3(t->con.mtx, tc->data->axismtx);
- t->con.mode = mode;
- getConstraintMatrix(t);
+ BLI_strncpy(t->con.text + 1, text, sizeof(t->con.text) - 1);
+ t->con.mode = mode;
+ projection_matrix_calc(t, t->con.pmtx);
- startConstraint(t);
+ startConstraint(t);
- t->con.drawExtra = drawObjectConstraint;
- t->con.applyVec = applyObjectConstraintVec;
- t->con.applySize = applyObjectConstraintSize;
- t->con.applyRot = applyObjectConstraintRot;
- t->redraw = TREDRAW_HARD;
- }
+ t->con.drawExtra = drawObjectConstraint;
+ t->con.applyVec = applyObjectConstraintVec;
+ t->con.applySize = applyObjectConstraintSize;
+ t->con.applyRot = applyObjectConstraintRot;
+ t->redraw = TREDRAW_HARD;
}
void setLocalConstraint(TransInfo *t, int mode, const char text[])
{
- /* edit-mode now allows local transforms too */
if (t->flag & T_EDIT) {
- /* Use the active (first) edit object. */
- TransDataContainer *tc = t->data_container;
- setConstraint(t, tc->mat3_unit, mode, text);
+ /* Although in edit-mode each object has its local space, use the
+ * orientation of the active object. */
+ setConstraint(t, mode, text);
}
else {
setAxisMatrixConstraint(t, mode, text);
@@ -689,64 +636,30 @@ void setLocalConstraint(TransInfo *t, int mode, const char text[])
void setUserConstraint(TransInfo *t, short orientation, int mode, const char ftext[])
{
char text[256];
+ const char *spacename = transform_orientations_spacename_get(t, orientation);
+ BLI_snprintf(text, sizeof(text), ftext, spacename);
switch (orientation) {
- case V3D_ORIENT_GLOBAL: {
- float mtx[3][3];
- BLI_snprintf(text, sizeof(text), ftext, TIP_("global"));
- unit_m3(mtx);
- setConstraint(t, mtx, mode, text);
- break;
- }
case V3D_ORIENT_LOCAL:
- BLI_snprintf(text, sizeof(text), ftext, TIP_("local"));
setLocalConstraint(t, mode, text);
break;
case V3D_ORIENT_NORMAL:
- BLI_snprintf(text, sizeof(text), ftext, TIP_("normal"));
if (checkUseAxisMatrix(t)) {
setAxisMatrixConstraint(t, mode, text);
+ break;
}
- else {
- setConstraint(t, t->spacemtx, mode, text);
- }
- break;
+ ATTR_FALLTHROUGH;
+ case V3D_ORIENT_GLOBAL:
case V3D_ORIENT_VIEW:
- BLI_snprintf(text, sizeof(text), ftext, TIP_("view"));
- float mtx[3][3];
- copy_m3_m3(mtx, t->spacemtx);
- negate_v3(mtx[2]);
- setConstraint(t, mtx, mode, text);
- break;
case V3D_ORIENT_CURSOR:
- BLI_snprintf(text, sizeof(text), ftext, TIP_("cursor"));
- setConstraint(t, t->spacemtx, mode, text);
- break;
case V3D_ORIENT_GIMBAL:
- BLI_snprintf(text, sizeof(text), ftext, TIP_("gimbal"));
- setConstraint(t, t->spacemtx, mode, text);
- break;
case V3D_ORIENT_CUSTOM_MATRIX:
- BLI_snprintf(text, sizeof(text), ftext, TIP_("custom matrix"));
- setConstraint(t, t->spacemtx, mode, text);
- break;
case V3D_ORIENT_CUSTOM:
default: {
- BLI_assert(orientation >= V3D_ORIENT_CUSTOM);
- char orientation_str[128];
- BLI_snprintf(orientation_str,
- sizeof(orientation_str),
- "%s \"%s\"",
- TIP_("custom orientation"),
- t->orientation.custom->name);
- BLI_snprintf(text, sizeof(text), ftext, orientation_str);
- setConstraint(t, t->spacemtx, mode, text);
+ setConstraint(t, mode, text);
break;
}
}
-
- t->con.orientation = orientation;
-
t->con.mode |= CON_USER;
}
@@ -777,9 +690,9 @@ void drawConstraint(TransInfo *t)
convertViewVec(t, vec, (t->mval[0] - t->con.imval[0]), (t->mval[1] - t->con.imval[1]));
add_v3_v3(vec, t->center_global);
- drawLine(t, t->center_global, tc->mtx[0], 'X', 0);
- drawLine(t, t->center_global, tc->mtx[1], 'Y', 0);
- drawLine(t, t->center_global, tc->mtx[2], 'Z', 0);
+ drawLine(t, t->center_global, t->spacemtx[0], 'X', 0);
+ drawLine(t, t->center_global, t->spacemtx[1], 'Y', 0);
+ drawLine(t, t->center_global, t->spacemtx[2], 'Z', 0);
depth_test_enabled = GPU_depth_test_enabled();
if (depth_test_enabled) {
@@ -813,13 +726,13 @@ void drawConstraint(TransInfo *t)
}
if (tc->mode & CON_AXIS0) {
- drawLine(t, t->center_global, tc->mtx[0], 'X', DRAWLIGHT);
+ drawLine(t, t->center_global, t->spacemtx[0], 'X', DRAWLIGHT);
}
if (tc->mode & CON_AXIS1) {
- drawLine(t, t->center_global, tc->mtx[1], 'Y', DRAWLIGHT);
+ drawLine(t, t->center_global, t->spacemtx[1], 'Y', DRAWLIGHT);
}
if (tc->mode & CON_AXIS2) {
- drawLine(t, t->center_global, tc->mtx[2], 'Z', DRAWLIGHT);
+ drawLine(t, t->center_global, t->spacemtx[2], 'Z', DRAWLIGHT);
}
}
}
@@ -965,28 +878,6 @@ void stopConstraint(TransInfo *t)
t->num.idx_max = t->idx_max;
}
-void getConstraintMatrix(TransInfo *t)
-{
- float mat[3][3];
- invert_m3_m3(t->con.imtx, t->con.mtx);
- unit_m3(t->con.pmtx);
-
- if (!(t->con.mode & CON_AXIS0)) {
- zero_v3(t->con.pmtx[0]);
- }
-
- if (!(t->con.mode & CON_AXIS1)) {
- zero_v3(t->con.pmtx[1]);
- }
-
- if (!(t->con.mode & CON_AXIS2)) {
- zero_v3(t->con.pmtx[2]);
- }
-
- mul_m3_m3m3(mat, t->con.pmtx, t->con.imtx);
- mul_m3_m3m3(t->con.pmtx, t->con.mtx, mat);
-}
-
/*------------------------- MMB Select -------------------------------*/
void initSelectConstraint(TransInfo *t, bool force_global)
@@ -996,11 +887,11 @@ void initSelectConstraint(TransInfo *t, bool force_global)
orientation = V3D_ORIENT_GLOBAL;
}
else {
- if (t->orientation.index == 0) {
- t->orientation.index = 1;
- initTransformOrientation(t->context, t, t->orientation.types[t->orientation.index]);
+ if (t->orient_curr == 0) {
+ t->orient_curr = 1;
+ transform_orientations_current_set(t, t->orient_curr);
}
- orientation = t->orientation.types[t->orientation.index];
+ orientation = t->orient[t->orient_curr].type;
}
setUserConstraint(t, orientation, CON_APPLY | CON_SELECT, "");
@@ -1070,7 +961,7 @@ static void setNearestAxis3d(TransInfo *t)
for (i = 0; i < 3; i++) {
float axis[3], axis_2d[2];
- copy_v3_v3(axis, t->con.mtx[i]);
+ copy_v3_v3(axis, t->spacemtx[i]);
mul_v3_fl(axis, zfac);
/* now we can project to get window coordinate */
@@ -1139,7 +1030,7 @@ void setNearestAxis(TransInfo *t)
setNearestAxis2d(t);
}
- getConstraintMatrix(t);
+ projection_matrix_calc(t, t->con.pmtx);
}
/*-------------- HELPER FUNCTIONS ----------------*/
diff --git a/source/blender/editors/transform/transform_constraints.h b/source/blender/editors/transform/transform_constraints.h
index c98234c83da..b57a7599321 100644
--- a/source/blender/editors/transform/transform_constraints.h
+++ b/source/blender/editors/transform/transform_constraints.h
@@ -27,7 +27,7 @@
struct TransInfo;
void constraintNumInput(TransInfo *t, float vec[3]);
-void setConstraint(TransInfo *t, float space[3][3], int mode, const char text[]);
+void setConstraint(TransInfo *t, int mode, const char text[]);
void setAxisMatrixConstraint(TransInfo *t, int mode, const char text[]);
void setLocalConstraint(TransInfo *t, int mode, const char text[]);
void setUserConstraint(TransInfo *t, short orientation, int mode, const char text[]);
@@ -35,7 +35,6 @@ void drawConstraint(TransInfo *t);
void drawPropCircle(const struct bContext *C, TransInfo *t);
void startConstraint(TransInfo *t);
void stopConstraint(TransInfo *t);
-void getConstraintMatrix(TransInfo *t);
void initSelectConstraint(TransInfo *t, bool force_global);
void selectConstraint(TransInfo *t);
void postSelectConstraint(TransInfo *t);
diff --git a/source/blender/editors/transform/transform_convert.c b/source/blender/editors/transform/transform_convert.c
index b2d87272203..7295a8623d9 100644
--- a/source/blender/editors/transform/transform_convert.c
+++ b/source/blender/editors/transform/transform_convert.c
@@ -83,16 +83,45 @@
#include "transform_convert.h"
#include "transform_mode.h"
+bool transform_mode_use_local_origins(const TransInfo *t)
+{
+ return ELEM(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL);
+}
+
/**
* Transforming around ourselves is no use, fallback to individual origins,
* useful for curve/armatures.
*/
void transform_around_single_fallback(TransInfo *t)
{
- if ((t->data_len_all == 1) &&
- (ELEM(t->around, V3D_AROUND_CENTER_BOUNDS, V3D_AROUND_CENTER_MEDIAN, V3D_AROUND_ACTIVE)) &&
- (ELEM(t->mode, TFM_RESIZE, TFM_ROTATION, TFM_TRACKBALL))) {
- t->around = V3D_AROUND_LOCAL_ORIGINS;
+ if ((ELEM(t->around, V3D_AROUND_CENTER_BOUNDS, V3D_AROUND_CENTER_MEDIAN, V3D_AROUND_ACTIVE)) &&
+ transform_mode_use_local_origins(t)) {
+
+ bool is_data_single = false;
+ if (t->data_len_all == 1) {
+ is_data_single = true;
+ }
+ else if (t->data_len_all == 3) {
+ if (t->obedit_type == OB_CURVE) {
+ /* Special case check for curve, if we have a single curve bezier triple selected
+ * treat */
+ FOREACH_TRANS_DATA_CONTAINER (t, tc) {
+ if (!tc->data_len) {
+ continue;
+ }
+ if (tc->data_len == 3) {
+ const TransData *td = tc->data;
+ if ((td[0].loc == td[1].loc) && (td[1].loc == td[2].loc)) {
+ is_data_single = true;
+ }
+ }
+ break;
+ }
+ }
+ }
+ if (is_data_single) {
+ t->around = V3D_AROUND_LOCAL_ORIGINS;
+ }
}
}
@@ -1840,6 +1869,7 @@ static void special_aftertrans_update__node(bContext *C, TransInfo *t)
nodeRemoveNode(bmain, ntree, node, true);
}
}
+ ntreeUpdateTree(bmain, ntree);
}
}
}
diff --git a/source/blender/editors/transform/transform_convert.h b/source/blender/editors/transform/transform_convert.h
index fccaeb994e9..e5d758135e2 100644
--- a/source/blender/editors/transform/transform_convert.h
+++ b/source/blender/editors/transform/transform_convert.h
@@ -100,6 +100,7 @@ void flushTransTracking(TransInfo *t);
/********************* intern **********************/
/* transform_convert.c */
+bool transform_mode_use_local_origins(const TransInfo *t);
void transform_around_single_fallback(TransInfo *t);
bool constraints_list_needinv(TransInfo *t, ListBase *list);
void calc_distanceCurveVerts(TransData *head, TransData *tail);
diff --git a/source/blender/editors/transform/transform_convert_curve.c b/source/blender/editors/transform/transform_convert_curve.c
index 908cf7707f2..42ffe675dc5 100644
--- a/source/blender/editors/transform/transform_convert_curve.c
+++ b/source/blender/editors/transform/transform_convert_curve.c
@@ -167,6 +167,8 @@ void createTransCurveVerts(TransInfo *t)
((v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_CU_HANDLES) == 0) :
false;
+ bool use_around_origins_for_handles_test = ((t->around == V3D_AROUND_LOCAL_ORIGINS) &&
+ transform_mode_use_local_origins(t));
float mtx[3][3], smtx[3][3];
copy_m3_m4(mtx, tc->obedit->obmat);
@@ -342,7 +344,7 @@ void createTransCurveVerts(TransInfo *t)
if (ELEM(t->mode, TFM_CURVE_SHRINKFATTEN, TFM_TILT, TFM_DUMMY) == 0) {
/* sets the handles based on their selection,
* do this after the data is copied to the TransData */
- BKE_nurb_handles_test(nu, !hide_handles);
+ BKE_nurb_handles_test(nu, !hide_handles, use_around_origins_for_handles_test);
}
}
else {
diff --git a/source/blender/editors/transform/transform_convert_mesh.c b/source/blender/editors/transform/transform_convert_mesh.c
index 24dda8c8464..07b2f07bf2c 100644
--- a/source/blender/editors/transform/transform_convert_mesh.c
+++ b/source/blender/editors/transform/transform_convert_mesh.c
@@ -1450,7 +1450,6 @@ static void UVsToTransData(const float aspect[2],
void createTransUVs(bContext *C, TransInfo *t)
{
SpaceImage *sima = CTX_wm_space_image(C);
- Image *ima = CTX_data_edit_image(C);
Scene *scene = t->scene;
ToolSettings *ts = CTX_data_tool_settings(C);
@@ -1500,7 +1499,7 @@ void createTransUVs(bContext *C, TransInfo *t)
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
BMLoop *l;
- if (!uvedit_face_visible_test(scene, tc->obedit, ima, efa)) {
+ if (!uvedit_face_visible_test(scene, efa)) {
BM_elem_flag_disable(efa, BM_ELEM_TAG);
continue;
}
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index 4472facf183..069e49088de 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -1650,25 +1650,21 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
{
TransformOrientationSlot *orient_slot = &t->scene->orientation_slots[SCE_ORIENT_DEFAULT];
- TransformOrientation *custom_orientation = NULL;
short orient_type_set = -1;
short orient_type_matrix_set = -1;
short orient_type_scene = orient_slot->type;
if (orient_type_scene == V3D_ORIENT_CUSTOM) {
const int index_custom = orient_slot->index_custom;
- custom_orientation = BKE_scene_transform_orientation_find(t->scene, index_custom);
orient_type_scene += index_custom;
}
- short orient_type_default = V3D_ORIENT_GLOBAL;
- short orient_type_constraint[2];
+ short orient_types[3];
+ float custom_matrix[3][3];
+ bool use_orient_axis = false;
if (op && (prop = RNA_struct_find_property(op->ptr, "orient_axis"))) {
t->orient_axis = RNA_property_enum_get(op->ptr, prop);
-
- /* For transfor modes that require "orient_axis" use
- * `V3D_ORIENT_VIEW` as default. */
- orient_type_default = V3D_ORIENT_VIEW;
+ use_orient_axis = true;
}
if (op && (prop = RNA_struct_find_property(op->ptr, "orient_axis_ortho"))) {
t->orient_axis_ortho = RNA_property_enum_get(op->ptr, prop);
@@ -1681,26 +1677,28 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
if (orient_type_set >= V3D_ORIENT_CUSTOM + BIF_countTransformOrientation(C)) {
orient_type_set = V3D_ORIENT_GLOBAL;
}
- else {
- custom_orientation = BKE_scene_transform_orientation_find(
- t->scene, orient_type_default - V3D_ORIENT_CUSTOM);
- }
}
/* Change the default orientation to be used when redoing. */
- orient_type_default = orient_type_set;
- orient_type_constraint[0] = orient_type_set;
- orient_type_constraint[1] = orient_type_scene;
+ orient_types[0] = orient_type_set;
+ orient_types[1] = orient_type_set;
+ orient_types[2] = orient_type_scene;
}
else {
- orient_type_constraint[0] = orient_type_scene;
- orient_type_constraint[1] = orient_type_scene != V3D_ORIENT_GLOBAL ? V3D_ORIENT_GLOBAL :
- V3D_ORIENT_LOCAL;
+ if ((t->flag & T_MODAL) && (use_orient_axis || transform_mode_is_changeable(t->mode))) {
+ orient_types[0] = V3D_ORIENT_VIEW;
+ }
+ else {
+ orient_types[0] = orient_type_scene;
+ }
+ orient_types[1] = orient_type_scene;
+ orient_types[2] = orient_type_scene != V3D_ORIENT_GLOBAL ? V3D_ORIENT_GLOBAL :
+ V3D_ORIENT_LOCAL;
}
if (op && ((prop = RNA_struct_find_property(op->ptr, "orient_matrix")) &&
RNA_property_is_set(op->ptr, prop))) {
- RNA_property_float_get_array(op->ptr, prop, &t->orientation.custom_matrix[0][0]);
+ RNA_property_float_get_array(op->ptr, prop, &custom_matrix[0][0]);
if ((prop = RNA_struct_find_property(op->ptr, "orient_matrix_type")) &&
RNA_property_is_set(op->ptr, prop)) {
@@ -1715,18 +1713,30 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
if (orient_type_matrix_set == orient_type_set) {
/* Constraints are forced to use the custom matrix when redoing. */
- orient_type_default = V3D_ORIENT_CUSTOM_MATRIX;
+ orient_types[0] = V3D_ORIENT_CUSTOM_MATRIX;
}
}
- t->orientation.types[0] = orient_type_default;
- t->orientation.types[1] = orient_type_constraint[0];
- t->orientation.types[2] = orient_type_constraint[1];
- t->orientation.custom = custom_orientation;
-
if (t->con.mode & CON_APPLY) {
- t->orientation.index = 1;
+ t->orient_curr = 1;
}
+
+ /* For efficiency, avoid calculating the same orientation twice. */
+ for (int i = 1; i < 3; i++) {
+ t->orient[i].type = transform_orientation_matrix_get(
+ C, t, orient_types[i], custom_matrix, t->orient[i].matrix);
+ }
+
+ if (orient_types[0] != orient_types[1]) {
+ t->orient[0].type = transform_orientation_matrix_get(
+ C, t, orient_types[0], custom_matrix, t->orient[0].matrix);
+ }
+ else {
+ memcpy(&t->orient[0], &t->orient[1], sizeof(t->orient[0]));
+ }
+
+ const char *spacename = transform_orientations_spacename_get(t, orient_types[0]);
+ BLI_strncpy(t->spacename, spacename, sizeof(t->spacename));
}
if (op && ((prop = RNA_struct_find_property(op->ptr, "release_confirm")) &&
diff --git a/source/blender/editors/transform/transform_gizmo_2d.c b/source/blender/editors/transform/transform_gizmo_2d.c
index 50317d8b395..c63e90ac2b7 100644
--- a/source/blender/editors/transform/transform_gizmo_2d.c
+++ b/source/blender/editors/transform/transform_gizmo_2d.c
@@ -217,14 +217,12 @@ static bool gizmo2d_calc_bounds(const bContext *C, float *r_center, float *r_min
ScrArea *area = CTX_wm_area(C);
bool changed = false;
if (area->spacetype == SPACE_IMAGE) {
- SpaceImage *sima = area->spacedata.first;
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
- Image *ima = ED_space_image(sima);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
view_layer, NULL, &objects_len);
- if (ED_uvedit_minmax_multi(scene, ima, objects, objects_len, r_min, r_max)) {
+ if (ED_uvedit_minmax_multi(scene, objects, objects_len, r_min, r_max)) {
changed = true;
}
MEM_freeN(objects);
diff --git a/source/blender/editors/transform/transform_gizmo_3d.c b/source/blender/editors/transform/transform_gizmo_3d.c
index b575030778f..ddeba206e4a 100644
--- a/source/blender/editors/transform/transform_gizmo_3d.c
+++ b/source/blender/editors/transform/transform_gizmo_3d.c
@@ -1390,21 +1390,21 @@ void drawDial3d(const TransInfo *t)
if (tc->mode & CON_APPLY) {
if (tc->mode & CON_AXIS0) {
axis_idx = MAN_AXIS_ROT_X;
- negate_v3_v3(mat_basis[2], tc->mtx[0]);
+ negate_v3_v3(mat_basis[2], t->spacemtx[0]);
}
else if (tc->mode & CON_AXIS1) {
axis_idx = MAN_AXIS_ROT_Y;
- negate_v3_v3(mat_basis[2], tc->mtx[1]);
+ negate_v3_v3(mat_basis[2], t->spacemtx[1]);
}
else {
BLI_assert((tc->mode & CON_AXIS2) != 0);
axis_idx = MAN_AXIS_ROT_Z;
- negate_v3_v3(mat_basis[2], tc->mtx[2]);
+ negate_v3_v3(mat_basis[2], t->spacemtx[2]);
}
}
else {
axis_idx = MAN_AXIS_ROT_C;
- negate_v3_v3(mat_basis[2], t->spacemtx[t->orient_axis]);
+ copy_v3_v3(mat_basis[2], t->spacemtx[t->orient_axis]);
scale *= 1.2f;
line_with -= 1.0f;
}
@@ -2201,6 +2201,15 @@ static void WIDGETGROUP_xform_cage_refresh(const bContext *C, wmGizmoGroup *gzgr
WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, true);
}
else {
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Object *ob = OBACT(view_layer);
+ if (ob && ob->mode & OB_MODE_EDIT) {
+ copy_m4_m4(gz->matrix_space, ob->obmat);
+ }
+ else {
+ unit_m4(gz->matrix_space);
+ }
+
gizmo_prepare_mat(C, rv3d, &tbounds);
WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, false);
@@ -2258,15 +2267,6 @@ static void WIDGETGROUP_xform_cage_message_subscribe(const bContext *C,
static void WIDGETGROUP_xform_cage_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup)
{
struct XFormCageWidgetGroup *xgzgroup = gzgroup->customdata;
- wmGizmo *gz = xgzgroup->gizmo;
- ViewLayer *view_layer = CTX_data_view_layer(C);
- Object *ob = OBACT(view_layer);
- if (ob && ob->mode & OB_MODE_EDIT) {
- copy_m4_m4(gz->matrix_space, ob->obmat);
- }
- else {
- unit_m4(gz->matrix_space);
- }
RegionView3D *rv3d = CTX_wm_region_view3d(C);
{
diff --git a/source/blender/editors/transform/transform_mode.c b/source/blender/editors/transform/transform_mode.c
index 4c14c3aebd7..c2c880b03ff 100644
--- a/source/blender/editors/transform/transform_mode.c
+++ b/source/blender/editors/transform/transform_mode.c
@@ -61,6 +61,18 @@ bool transdata_check_local_center(TransInfo *t, short around)
(t->options & (CTX_MOVIECLIP | CTX_MASK | CTX_PAINT_CURVE))));
}
+/* Informs if the mode can be switched during modal. */
+bool transform_mode_is_changeable(const int mode)
+{
+ return ELEM(mode,
+ TFM_ROTATION,
+ TFM_RESIZE,
+ TFM_TRACKBALL,
+ TFM_TRANSLATION,
+ TFM_EDGE_SLIDE,
+ TFM_VERT_SLIDE);
+}
+
/* -------------------------------------------------------------------- */
/** \name Transform Locks
* \{ */
diff --git a/source/blender/editors/transform/transform_mode.h b/source/blender/editors/transform/transform_mode.h
index 6180f6d3477..074e89390c2 100644
--- a/source/blender/editors/transform/transform_mode.h
+++ b/source/blender/editors/transform/transform_mode.h
@@ -41,6 +41,7 @@ typedef struct TransDataGenericSlideVert {
/* transform_mode.c */
bool transdata_check_local_center(TransInfo *t, short around);
+bool transform_mode_is_changeable(const int mode);
void protectedTransBits(short protectflag, float vec[3]);
void constraintTransLim(TransInfo *t, TransData *td);
void postInputRotation(TransInfo *t, float values[3]);
diff --git a/source/blender/editors/transform/transform_mode_edge_seq_slide.c b/source/blender/editors/transform/transform_mode_edge_seq_slide.c
index ee91459dcdd..8690cd54a3b 100644
--- a/source/blender/editors/transform/transform_mode_edge_seq_slide.c
+++ b/source/blender/editors/transform/transform_mode_edge_seq_slide.c
@@ -101,9 +101,8 @@ static void applySeqSlide(TransInfo *t, const int mval[2])
snapSequenceBounds(t, mval);
if (t->con.mode & CON_APPLY) {
- float pvec[3] = {0.0f, 0.0f, 0.0f};
float tvec[3];
- t->con.applyVec(t, NULL, NULL, t->values, tvec, pvec);
+ t->con.applyVec(t, NULL, NULL, t->values, tvec);
copy_v3_v3(t->values_final, tvec);
}
else {
diff --git a/source/blender/editors/transform/transform_mode_rotate.c b/source/blender/editors/transform/transform_mode_rotate.c
index f52bfda0d14..55c97630487 100644
--- a/source/blender/editors/transform/transform_mode_rotate.c
+++ b/source/blender/editors/transform/transform_mode_rotate.c
@@ -146,7 +146,8 @@ static void applyRotation(TransInfo *t, const int UNUSED(mval[2]))
snapGridIncrement(t, &final);
float axis_final[3];
- copy_v3_v3(axis_final, t->spacemtx[t->orient_axis]);
+ /* Use the negative axis to match the default Z axis of the view matrix. */
+ negate_v3_v3(axis_final, t->spacemtx[t->orient_axis]);
if ((t->con.mode & CON_APPLY) && t->con.applyRot) {
t->con.applyRot(t, NULL, NULL, axis_final, NULL);
diff --git a/source/blender/editors/transform/transform_mode_shear.c b/source/blender/editors/transform/transform_mode_shear.c
index da34bf50ba3..3eeb8a1e758 100644
--- a/source/blender/editors/transform/transform_mode_shear.c
+++ b/source/blender/editors/transform/transform_mode_shear.c
@@ -56,14 +56,14 @@ static void initShear_mouseInputMode(TransInfo *t)
copy_v3_v3(dir, t->spacemtx[t->orient_axis_ortho]);
/* Needed for axis aligned view gizmo. */
- if (t->orientation.types[t->orientation.index] == V3D_ORIENT_VIEW) {
+ if (t->orient[t->orient_curr].type == V3D_ORIENT_VIEW) {
if (t->orient_axis_ortho == 0) {
- if (t->center2d[1] < t->mouse.imval[1]) {
+ if (t->center2d[1] > t->mouse.imval[1]) {
dir_flip = !dir_flip;
}
}
else if (t->orient_axis_ortho == 1) {
- if (t->center2d[0] < t->mouse.imval[0]) {
+ if (t->center2d[0] > t->mouse.imval[0]) {
dir_flip = !dir_flip;
}
}
diff --git a/source/blender/editors/transform/transform_mode_translate.c b/source/blender/editors/transform/transform_mode_translate.c
index 0a7d8bd90d3..69552eda5bf 100644
--- a/source/blender/editors/transform/transform_mode_translate.c
+++ b/source/blender/editors/transform/transform_mode_translate.c
@@ -277,8 +277,7 @@ static void applyTranslationValue(TransInfo *t, const float vec[3])
}
if (t->con.applyVec) {
- float pvec[3];
- t->con.applyVec(t, tc, td, vec, tvec, pvec);
+ t->con.applyVec(t, tc, td, vec, tvec);
}
else {
copy_v3_v3(tvec, vec);
@@ -319,45 +318,39 @@ static void applyTranslationValue(TransInfo *t, const float vec[3])
static void applyTranslation(TransInfo *t, const int UNUSED(mval[2]))
{
char str[UI_MAX_DRAW_STR];
- float values_final[3];
+ float global_dir[3];
if (t->flag & T_INPUT_IS_VALUES_FINAL) {
- copy_v3_v3(t->values_final, t->values);
+ mul_v3_m3v3(global_dir, t->spacemtx, t->values);
}
else {
- copy_v3_v3(t->values_final, t->values);
+ copy_v3_v3(global_dir, t->values);
if ((t->con.mode & CON_APPLY) == 0) {
- snapGridIncrement(t, t->values_final);
+ snapGridIncrement(t, global_dir);
}
- if (applyNumInput(&t->num, t->values_final)) {
- removeAspectRatio(t, t->values_final);
+ if (applyNumInput(&t->num, global_dir)) {
+ removeAspectRatio(t, global_dir);
}
- applySnapping(t, t->values_final);
+ applySnapping(t, global_dir);
}
- copy_v3_v3(values_final, t->values_final);
if (t->con.mode & CON_APPLY) {
- float pvec[3] = {0.0f, 0.0f, 0.0f};
- t->con.applyVec(t, NULL, NULL, t->values_final, values_final, pvec);
- headerTranslation(t, pvec, str);
-
- /* only so we have re-usable value with redo, see T46741. */
- mul_v3_m3v3(t->values_final, t->con.imtx, values_final);
+ float in[3];
+ copy_v3_v3(in, global_dir);
+ t->con.applyVec(t, NULL, NULL, in, global_dir);
+ headerTranslation(t, global_dir, str);
}
else {
- headerTranslation(t, t->values_final, str);
- copy_v3_v3(values_final, t->values_final);
+ headerTranslation(t, global_dir, str);
}
- /* don't use 't->values' now on */
-
- applyTranslationValue(t, values_final);
+ applyTranslationValue(t, global_dir);
/* evil hack - redo translation if clipping needed */
- if (t->flag & T_CLIP_UV && clipUVTransform(t, values_final, 0)) {
- applyTranslationValue(t, values_final);
+ if (t->flag & T_CLIP_UV && clipUVTransform(t, global_dir, 0)) {
+ applyTranslationValue(t, global_dir);
/* In proportional edit it can happen that */
/* vertices in the radius of the brush end */
@@ -368,8 +361,10 @@ static void applyTranslation(TransInfo *t, const int UNUSED(mval[2]))
}
}
- recalcData(t);
+ /* Set the redo value. */
+ mul_v3_m3v3(t->values_final, t->spacemtx_inv, global_dir);
+ recalcData(t);
ED_area_status_text(t->area, str);
}
diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c
index 81c63278366..4cddb9d3b4a 100644
--- a/source/blender/editors/transform/transform_orientations.c
+++ b/source/blender/editors/transform/transform_orientations.c
@@ -438,79 +438,148 @@ static int armature_bone_transflags_update_recursive(bArmature *arm,
return total;
}
-void initTransformOrientation(bContext *C, TransInfo *t, short orientation)
+/* Sets the matrix of the specified space orientation.
+ * If the matrix cannot be obtained, an orientation different from the one
+ * informed is returned */
+short transform_orientation_matrix_get(bContext *C,
+ TransInfo *t,
+ const short orientation,
+ const float custom[3][3],
+ float r_spacemtx[3][3])
{
Object *ob = CTX_data_active_object(C);
Object *obedit = CTX_data_active_object(C);
switch (orientation) {
case V3D_ORIENT_GLOBAL:
- unit_m3(t->spacemtx);
- BLI_strncpy(t->spacename, TIP_("global"), sizeof(t->spacename));
- break;
+ unit_m3(r_spacemtx);
+ return V3D_ORIENT_GLOBAL;
case V3D_ORIENT_GIMBAL:
- unit_m3(t->spacemtx);
- if (ob && gimbal_axis(ob, t->spacemtx)) {
- BLI_strncpy(t->spacename, TIP_("gimbal"), sizeof(t->spacename));
- break;
+ unit_m3(r_spacemtx);
+ if (ob && gimbal_axis(ob, r_spacemtx)) {
+ return V3D_ORIENT_GIMBAL;
}
ATTR_FALLTHROUGH; /* no gimbal fallthrough to normal */
+
case V3D_ORIENT_NORMAL:
if (obedit || (ob && ob->mode & OB_MODE_POSE)) {
- BLI_strncpy(t->spacename, TIP_("normal"), sizeof(t->spacename));
- ED_getTransformOrientationMatrix(C, t->spacemtx, t->around);
- break;
+ ED_getTransformOrientationMatrix(C, r_spacemtx, t->around);
+ return V3D_ORIENT_NORMAL;
}
ATTR_FALLTHROUGH; /* we define 'normal' as 'local' in Object mode */
- case V3D_ORIENT_LOCAL:
- BLI_strncpy(t->spacename, TIP_("local"), sizeof(t->spacename));
+ case V3D_ORIENT_LOCAL:
if (ob) {
- copy_m3_m4(t->spacemtx, ob->obmat);
- normalize_m3(t->spacemtx);
+ copy_m3_m4(r_spacemtx, ob->obmat);
+ normalize_m3(r_spacemtx);
+ return V3D_ORIENT_LOCAL;
}
- else {
- unit_m3(t->spacemtx);
- }
-
- break;
+ unit_m3(r_spacemtx);
+ return V3D_ORIENT_GLOBAL;
case V3D_ORIENT_VIEW: {
float mat[3][3];
if ((t->spacetype == SPACE_VIEW3D) && (t->region->regiontype == RGN_TYPE_WINDOW)) {
- BLI_strncpy(t->spacename, TIP_("view"), sizeof(t->spacename));
- copy_m3_m4(mat, t->viewinv);
+ RegionView3D *rv3d = t->region->regiondata;
+ copy_m3_m4(mat, rv3d->viewinv);
normalize_m3(mat);
}
else {
unit_m3(mat);
}
- negate_v3(mat[2]);
- copy_m3_m3(t->spacemtx, mat);
- break;
- }
- case V3D_ORIENT_CURSOR: {
- BLI_strncpy(t->spacename, TIP_("cursor"), sizeof(t->spacename));
- BKE_scene_cursor_rot_to_mat3(&t->scene->cursor, t->spacemtx);
- break;
+ copy_m3_m3(r_spacemtx, mat);
+ return V3D_ORIENT_VIEW;
}
+ case V3D_ORIENT_CURSOR:
+ BKE_scene_cursor_rot_to_mat3(&t->scene->cursor, r_spacemtx);
+ return V3D_ORIENT_CURSOR;
+
case V3D_ORIENT_CUSTOM_MATRIX:
- BLI_strncpy(t->spacename, TIP_("custom"), sizeof(t->spacename));
- copy_m3_m3(t->spacemtx, t->orientation.custom_matrix);
- break;
+ copy_m3_m3(r_spacemtx, custom);
+ return V3D_ORIENT_CUSTOM_MATRIX;
+
case V3D_ORIENT_CUSTOM:
default:
BLI_assert(orientation >= V3D_ORIENT_CUSTOM);
- BLI_strncpy(t->spacename, t->orientation.custom->name, sizeof(t->spacename));
- if (applyTransformOrientation(t->orientation.custom, t->spacemtx, t->spacename)) {
+ TransformOrientation *ts = BKE_scene_transform_orientation_find(
+ t->scene, orientation - V3D_ORIENT_CUSTOM);
+ if (applyTransformOrientation(ts, r_spacemtx, t->spacename)) {
/* pass */
}
else {
- unit_m3(t->spacemtx);
+ unit_m3(r_spacemtx);
}
break;
}
+
+ return orientation;
+}
+
+const char *transform_orientations_spacename_get(TransInfo *t, const short orient_type)
+{
+ switch (orient_type) {
+ case V3D_ORIENT_GLOBAL:
+ return TIP_("global");
+ case V3D_ORIENT_GIMBAL:
+ return TIP_("gimbal");
+ case V3D_ORIENT_NORMAL:
+ return TIP_("normal");
+ case V3D_ORIENT_LOCAL:
+ return TIP_("local");
+ case V3D_ORIENT_VIEW:
+ return TIP_("view");
+ case V3D_ORIENT_CURSOR:
+ return TIP_("cursor");
+ case V3D_ORIENT_CUSTOM_MATRIX:
+ return TIP_("custom");
+ case V3D_ORIENT_CUSTOM:
+ default:
+ BLI_assert(orient_type >= V3D_ORIENT_CUSTOM);
+ TransformOrientation *ts = BKE_scene_transform_orientation_find(
+ t->scene, orient_type - V3D_ORIENT_CUSTOM);
+ return ts->name;
+ }
+}
+
+void transform_orientations_current_set(TransInfo *t, const short orient_index)
+{
+ const short orientation = t->orient[orient_index].type;
+ const char *spacename;
+ switch (orientation) {
+ case V3D_ORIENT_GLOBAL:
+ spacename = TIP_("global");
+ break;
+ case V3D_ORIENT_GIMBAL:
+ spacename = TIP_("gimbal");
+ break;
+ case V3D_ORIENT_NORMAL:
+ spacename = TIP_("normal");
+ break;
+ case V3D_ORIENT_LOCAL:
+ spacename = TIP_("local");
+ break;
+ case V3D_ORIENT_VIEW:
+ spacename = TIP_("view");
+ break;
+ case V3D_ORIENT_CURSOR:
+ spacename = TIP_("cursor");
+ break;
+ case V3D_ORIENT_CUSTOM_MATRIX:
+ spacename = TIP_("custom");
+ break;
+ case V3D_ORIENT_CUSTOM:
+ default:
+ BLI_assert(orientation >= V3D_ORIENT_CUSTOM);
+ TransformOrientation *ts = BKE_scene_transform_orientation_find(
+ t->scene, orientation - V3D_ORIENT_CUSTOM);
+ spacename = ts->name;
+ break;
+ }
+
+ BLI_strncpy(t->spacename, spacename, sizeof(t->spacename));
+ copy_m3_m3(t->spacemtx, t->orient[orient_index].matrix);
+ invert_m3_m3(t->spacemtx_inv, t->spacemtx);
}
/**
diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c
index cb4446deb99..d3df68b21da 100644
--- a/source/blender/editors/transform/transform_snap.c
+++ b/source/blender/editors/transform/transform_snap.c
@@ -1106,7 +1106,6 @@ static void CalcSnapGeometry(TransInfo *t, float *UNUSED(vec))
}
else if (t->spacetype == SPACE_IMAGE && t->obedit_type == OB_MESH) {
if (t->tsnap.mode & SCE_SNAP_MODE_VERTEX) {
- Image *ima = ED_space_image(t->area->spacedata.first);
float co[2];
UI_view2d_region_to_view(&t->region->v2d, t->mval[0], t->mval[1], &co[0], &co[1]);
@@ -1117,7 +1116,7 @@ static void CalcSnapGeometry(TransInfo *t, float *UNUSED(vec))
float dist_sq = FLT_MAX;
if (ED_uvedit_nearest_uv_multi(
- t->scene, ima, objects, objects_len, co, &dist_sq, t->tsnap.snapPoint)) {
+ t->scene, objects, objects_len, co, &dist_sq, t->tsnap.snapPoint)) {
t->tsnap.snapPoint[0] *= t->aspect[0];
t->tsnap.snapPoint[1] *= t->aspect[1];
@@ -1750,8 +1749,8 @@ static void applyGridIncrement(
float local_axis[3];
float pos_on_axis[3];
- copy_v3_v3(local_axis, t->con.mtx[i]);
- copy_v3_v3(pos_on_axis, t->con.mtx[i]);
+ copy_v3_v3(local_axis, t->spacemtx[i]);
+ copy_v3_v3(pos_on_axis, t->spacemtx[i]);
/* amount of movement on axis from initial pos */
mul_v3_fl(pos_on_axis, val[i]);
diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c
index 2cfeedbb346..acd76a2e3f5 100644
--- a/source/blender/editors/transform/transform_snap_object.c
+++ b/source/blender/editors/transform/transform_snap_object.c
@@ -1707,8 +1707,14 @@ static short snap_mesh_edge_verts_mixed(SnapObjectContext *sctx,
&nearest.dist_sq,
nearest.co)) {
nearest.index = vindex[v_id];
- nearest2d.copy_vert_no(vindex[v_id], nearest.no, nearest2d.userdata);
elem = SCE_SNAP_MODE_VERTEX;
+ if (r_no) {
+ float imat[4][4];
+ invert_m4_m4(imat, obmat);
+ nearest2d.copy_vert_no(vindex[v_id], r_no, nearest2d.userdata);
+ mul_transposed_mat3_m4_v3(imat, r_no);
+ normalize_v3(r_no);
+ }
}
}
}
@@ -1726,10 +1732,6 @@ static short snap_mesh_edge_verts_mixed(SnapObjectContext *sctx,
vmid,
&nearest.dist_sq,
nearest.co)) {
- float v_nor[2][3];
- nearest2d.copy_vert_no(vindex[0], v_nor[0], nearest2d.userdata);
- nearest2d.copy_vert_no(vindex[1], v_nor[1], nearest2d.userdata);
- mid_v3_v3v3(nearest.no, v_nor[0], v_nor[1]);
nearest.index = *r_index;
elem = SCE_SNAP_MODE_EDGE_MIDPOINT;
}
@@ -1757,11 +1759,6 @@ static short snap_mesh_edge_verts_mixed(SnapObjectContext *sctx,
v_near,
&nearest.dist_sq,
nearest.co)) {
- float v_nor[2][3];
- nearest2d.copy_vert_no(vindex[0], v_nor[0], nearest2d.userdata);
- nearest2d.copy_vert_no(vindex[1], v_nor[1], nearest2d.userdata);
- mid_v3_v3v3(nearest.no, v_nor[0], v_nor[1]);
-
nearest.index = *r_index;
elem = SCE_SNAP_MODE_EDGE_PERPENDICULAR;
}
@@ -1778,15 +1775,6 @@ static short snap_mesh_edge_verts_mixed(SnapObjectContext *sctx,
mul_m4_v3(obmat, r_loc);
}
- if (r_no) {
- float imat[4][4];
- invert_m4_m4(imat, obmat);
-
- copy_v3_v3(r_no, nearest.no);
- mul_transposed_mat3_m4_v3(imat, r_no);
- normalize_v3(r_no);
- }
-
*r_index = nearest.index;
}
diff --git a/source/blender/editors/util/ed_transverts.c b/source/blender/editors/util/ed_transverts.c
index 67a62473dc0..1c56ad878e2 100644
--- a/source/blender/editors/util/ed_transverts.c
+++ b/source/blender/editors/util/ed_transverts.c
@@ -111,7 +111,7 @@ void ED_transverts_update_obedit(TransVertStore *tvs, Object *obedit)
}
BKE_nurb_test_2d(nu);
- BKE_nurb_handles_test(nu, true); /* test for bezier too */
+ BKE_nurb_handles_test(nu, true, false); /* test for bezier too */
nu = nu->next;
}
}
diff --git a/source/blender/editors/uvedit/uvedit_buttons.c b/source/blender/editors/uvedit/uvedit_buttons.c
index c072220842e..edfbfd0cdc3 100644
--- a/source/blender/editors/uvedit/uvedit_buttons.c
+++ b/source/blender/editors/uvedit/uvedit_buttons.c
@@ -58,8 +58,7 @@
/* UV Utilities */
-static int uvedit_center(
- Scene *scene, Object **objects, uint objects_len, Image *ima, float center[2])
+static int uvedit_center(Scene *scene, Object **objects, uint objects_len, float center[2])
{
BMFace *f;
BMLoop *l;
@@ -75,7 +74,7 @@ static int uvedit_center(
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
BM_ITER_MESH (f, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, obedit, ima, f)) {
+ if (!uvedit_face_visible_test(scene, f)) {
continue;
}
@@ -97,8 +96,10 @@ static int uvedit_center(
return tot;
}
-static void uvedit_translate(
- Scene *scene, Object **objects, uint objects_len, Image *ima, const float delta[2])
+static void uvedit_translate(Scene *scene,
+ Object **objects,
+ uint objects_len,
+ const float delta[2])
{
BMFace *f;
BMLoop *l;
@@ -112,7 +113,7 @@ static void uvedit_translate(
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
BM_ITER_MESH (f, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, obedit, ima, f)) {
+ if (!uvedit_face_visible_test(scene, f)) {
continue;
}
@@ -134,7 +135,6 @@ static void uvedit_vertex_buttons(const bContext *C, uiBlock *block)
{
SpaceImage *sima = CTX_wm_space_image(C);
Scene *scene = CTX_data_scene(C);
- Image *ima = sima->image;
float center[2];
int imx, imy, step, digits;
float width = 8 * UI_UNIT_X;
@@ -144,7 +144,7 @@ static void uvedit_vertex_buttons(const bContext *C, uiBlock *block)
ED_space_image_get_size(sima, &imx, &imy);
- if (uvedit_center(scene, objects, objects_len, ima, center)) {
+ if (uvedit_center(scene, objects, objects_len, center)) {
float range_xy[2][2] = {
{-10.0f, 10.0f},
{-10.0f, 10.0f},
@@ -212,7 +212,6 @@ static void do_uvedit_vertex(bContext *C, void *UNUSED(arg), int event)
{
SpaceImage *sima = CTX_wm_space_image(C);
Scene *scene = CTX_data_scene(C);
- Image *ima = sima->image;
float center[2], delta[2];
int imx, imy;
@@ -225,7 +224,7 @@ static void do_uvedit_vertex(bContext *C, void *UNUSED(arg), int event)
CTX_data_view_layer(C), CTX_wm_view3d(C), &objects_len);
ED_space_image_get_size(sima, &imx, &imy);
- uvedit_center(scene, objects, objects_len, ima, center);
+ uvedit_center(scene, objects, objects_len, center);
if (sima->flag & SI_COORDFLOATS) {
delta[0] = uvedit_old_center[0] - center[0];
@@ -236,7 +235,7 @@ static void do_uvedit_vertex(bContext *C, void *UNUSED(arg), int event)
delta[1] = uvedit_old_center[1] / imy - center[1];
}
- uvedit_translate(scene, objects, objects_len, ima, delta);
+ uvedit_translate(scene, objects, objects_len, delta);
WM_event_add_notifier(C, NC_IMAGE, sima->image);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c
index 959ca1eeef1..f8cef95c776 100644
--- a/source/blender/editors/uvedit/uvedit_draw.c
+++ b/source/blender/editors/uvedit/uvedit_draw.c
@@ -216,13 +216,14 @@ static void uvedit_get_batches(Object *ob,
}
}
-static void draw_uvs_shadow(SpaceImage *UNUSED(sima),
+static void draw_uvs_shadow(SpaceImage *sima,
const Scene *scene,
Object *obedit,
Depsgraph *depsgraph)
{
Object *ob_eval = DEG_get_evaluated_object(depsgraph, obedit);
Mesh *me = ob_eval->data;
+ const float overlay_alpha = sima->uv_opacity;
float col[4];
UI_GetThemeColor4fv(TH_UV_SHADOW, col);
@@ -231,9 +232,26 @@ static void draw_uvs_shadow(SpaceImage *UNUSED(sima),
DRW_mesh_batch_cache_create_requested(ob_eval, me, scene, false, false);
if (edges) {
+ if (sima->flag & SI_SMOOTH_UV) {
+ GPU_line_smooth(true);
+ GPU_blend(true);
+ }
+ else if (overlay_alpha < 1.0f) {
+ GPU_blend(true);
+ }
+
+ col[3] = overlay_alpha;
GPU_batch_program_set_builtin(edges, GPU_SHADER_2D_UV_UNIFORM_COLOR);
GPU_batch_uniform_4fv(edges, "color", col);
GPU_batch_draw(edges);
+
+ if (sima->flag & SI_SMOOTH_UV) {
+ GPU_line_smooth(false);
+ GPU_blend(false);
+ }
+ else if (overlay_alpha < 1.0f) {
+ GPU_blend(false);
+ }
}
}
diff --git a/source/blender/editors/uvedit/uvedit_intern.h b/source/blender/editors/uvedit/uvedit_intern.h
index ffab5bd094f..31384d6df17 100644
--- a/source/blender/editors/uvedit/uvedit_intern.h
+++ b/source/blender/editors/uvedit/uvedit_intern.h
@@ -57,13 +57,11 @@ typedef struct UvNearestHit {
}
bool uv_find_nearest_vert(struct Scene *scene,
- struct Image *ima,
struct Object *obedit,
const float co[2],
const float penalty_dist,
struct UvNearestHit *hit_final);
bool uv_find_nearest_vert_multi(struct Scene *scene,
- struct Image *ima,
struct Object **objects,
const uint objects_len,
const float co[2],
@@ -71,24 +69,20 @@ bool uv_find_nearest_vert_multi(struct Scene *scene,
struct UvNearestHit *hit_final);
bool uv_find_nearest_edge(struct Scene *scene,
- struct Image *ima,
struct Object *obedit,
const float co[2],
struct UvNearestHit *hit_final);
bool uv_find_nearest_edge_multi(struct Scene *scene,
- struct Image *ima,
struct Object **objects,
const uint objects_len,
const float co[2],
struct UvNearestHit *hit_final);
bool uv_find_nearest_face(struct Scene *scene,
- struct Image *ima,
struct Object *obedit,
const float co[2],
struct UvNearestHit *hit_final);
bool uv_find_nearest_face_multi(struct Scene *scene,
- struct Image *ima,
struct Object **objects,
const uint objects_len,
const float co[2],
@@ -116,14 +110,11 @@ void UV_OT_stitch(struct wmOperatorType *ot);
/* uvedit_select.c */
-bool uvedit_select_is_any_selected(struct Scene *scene, struct Image *ima, struct Object *obedit);
+bool uvedit_select_is_any_selected(struct Scene *scene, struct Object *obedit);
bool uvedit_select_is_any_selected_multi(struct Scene *scene,
- struct Image *ima,
struct Object **objects,
const uint objects_len);
const float *uvedit_first_selected_uv_from_vertex(struct Scene *scene,
- struct Object *obedit,
- struct Image *ima,
struct BMVert *eve,
const int cd_loop_uv_offset);
diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c
index a99e05cb52b..78b6cfc44ac 100644
--- a/source/blender/editors/uvedit/uvedit_ops.c
+++ b/source/blender/editors/uvedit/uvedit_ops.c
@@ -252,12 +252,8 @@ void uv_poly_copy_aspect(float uv_orig[][2], float uv[][2], float aspx, float as
}
}
-bool ED_uvedit_minmax_multi(const Scene *scene,
- Image *ima,
- Object **objects_edit,
- uint objects_len,
- float r_min[2],
- float r_max[2])
+bool ED_uvedit_minmax_multi(
+ const Scene *scene, Object **objects_edit, uint objects_len, float r_min[2], float r_max[2])
{
bool changed = false;
INIT_MINMAX2(r_min, r_max);
@@ -274,7 +270,7 @@ bool ED_uvedit_minmax_multi(const Scene *scene,
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, obedit, ima, efa)) {
+ if (!uvedit_face_visible_test(scene, efa)) {
continue;
}
@@ -290,10 +286,9 @@ bool ED_uvedit_minmax_multi(const Scene *scene,
return changed;
}
-bool ED_uvedit_minmax(
- const Scene *scene, Image *ima, Object *obedit, float r_min[2], float r_max[2])
+bool ED_uvedit_minmax(const Scene *scene, Object *obedit, float r_min[2], float r_max[2])
{
- return ED_uvedit_minmax_multi(scene, ima, &obedit, 1, r_min, r_max);
+ return ED_uvedit_minmax_multi(scene, &obedit, 1, r_min, r_max);
}
/* Be careful when using this, it bypasses all synchronization options */
@@ -314,8 +309,10 @@ void ED_uvedit_select_all(BMesh *bm)
}
}
-static bool ED_uvedit_median_multi(
- const Scene *scene, Image *ima, Object **objects_edit, uint objects_len, float co[2])
+static bool ED_uvedit_median_multi(const Scene *scene,
+ Object **objects_edit,
+ uint objects_len,
+ float co[2])
{
uint sel = 0;
zero_v2(co);
@@ -332,7 +329,7 @@ static bool ED_uvedit_median_multi(
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, obedit, ima, efa)) {
+ if (!uvedit_face_visible_test(scene, efa)) {
continue;
}
@@ -351,24 +348,20 @@ static bool ED_uvedit_median_multi(
return (sel != 0);
}
-bool ED_uvedit_center_multi(const Scene *scene,
- Image *ima,
- Object **objects_edit,
- uint objects_len,
- float cent[2],
- char mode)
+bool ED_uvedit_center_multi(
+ const Scene *scene, Object **objects_edit, uint objects_len, float cent[2], char mode)
{
bool changed = false;
if (mode == V3D_AROUND_CENTER_BOUNDS) { /* bounding box */
float min[2], max[2];
- if (ED_uvedit_minmax_multi(scene, ima, objects_edit, objects_len, min, max)) {
+ if (ED_uvedit_minmax_multi(scene, objects_edit, objects_len, min, max)) {
mid_v2_v2v2(cent, min, max);
changed = true;
}
}
else {
- if (ED_uvedit_median_multi(scene, ima, objects_edit, objects_len, cent)) {
+ if (ED_uvedit_median_multi(scene, objects_edit, objects_len, cent)) {
changed = true;
}
}
@@ -392,8 +385,7 @@ bool ED_uvedit_center_from_pivot_ex(SpaceImage *sima,
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
view_layer, ((View3D *)NULL), &objects_len);
- *r_has_select = uvedit_select_is_any_selected_multi(
- scene, sima->image, objects, objects_len);
+ *r_has_select = uvedit_select_is_any_selected_multi(scene, objects, objects_len);
MEM_freeN(objects);
}
break;
@@ -402,7 +394,7 @@ bool ED_uvedit_center_from_pivot_ex(SpaceImage *sima,
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
view_layer, ((View3D *)NULL), &objects_len);
- changed = ED_uvedit_center_multi(scene, sima->image, objects, objects_len, r_center, mode);
+ changed = ED_uvedit_center_multi(scene, objects, objects_len, r_center, mode);
MEM_freeN(objects);
if (r_has_select != NULL) {
*r_has_select = changed;
@@ -440,7 +432,6 @@ static void uv_weld_align(bContext *C, eUVWeldAlign tool)
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
SpaceImage *sima = CTX_wm_space_image(C);
- Image *ima = CTX_data_edit_image(C);
const ToolSettings *ts = scene->toolsettings;
const bool synced_selection = (ts->uv_flag & UV_SYNC_SELECTION) != 0;
float cent[2], min[2], max[2];
@@ -467,7 +458,7 @@ static void uv_weld_align(bContext *C, eUVWeldAlign tool)
BMLoop *l;
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, obedit, ima, efa)) {
+ if (!uvedit_face_visible_test(scene, efa)) {
continue;
}
@@ -482,7 +473,7 @@ static void uv_weld_align(bContext *C, eUVWeldAlign tool)
tool = (max[0] - min[0] >= max[1] - min[1]) ? UV_ALIGN_Y : UV_ALIGN_X;
}
- ED_uvedit_center_multi(scene, ima, objects, objects_len, cent, 0);
+ ED_uvedit_center_multi(scene, objects, objects_len, cent, 0);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
@@ -501,7 +492,7 @@ static void uv_weld_align(bContext *C, eUVWeldAlign tool)
BMLoop *l;
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, obedit, ima, efa)) {
+ if (!uvedit_face_visible_test(scene, efa)) {
continue;
}
@@ -521,7 +512,7 @@ static void uv_weld_align(bContext *C, eUVWeldAlign tool)
BMLoop *l;
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, obedit, ima, efa)) {
+ if (!uvedit_face_visible_test(scene, efa)) {
continue;
}
@@ -548,7 +539,7 @@ static void uv_weld_align(bContext *C, eUVWeldAlign tool)
/* tag verts with a selected UV */
BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
BM_ITER_ELEM (l, &liter, eve, BM_LOOPS_OF_VERT) {
- if (!uvedit_face_visible_test(scene, obedit, ima, l->f)) {
+ if (!uvedit_face_visible_test(scene, l->f)) {
continue;
}
@@ -619,9 +610,9 @@ static void uv_weld_align(bContext *C, eUVWeldAlign tool)
/* we know the returns from these must be valid */
const float *uv_start = uvedit_first_selected_uv_from_vertex(
- scene, obedit, ima, eve_line[0], cd_loop_uv_offset);
+ scene, eve_line[0], cd_loop_uv_offset);
const float *uv_end = uvedit_first_selected_uv_from_vertex(
- scene, obedit, ima, eve_line[BLI_array_len(eve_line) - 1], cd_loop_uv_offset);
+ scene, eve_line[BLI_array_len(eve_line) - 1], cd_loop_uv_offset);
/* For UV_STRAIGHTEN_X & UV_STRAIGHTEN_Y modes */
float a = 0.0f;
eUVWeldAlign tool_local = tool;
@@ -646,7 +637,7 @@ static void uv_weld_align(bContext *C, eUVWeldAlign tool)
/* go over all verts except for endpoints */
for (i = 0; i < BLI_array_len(eve_line); i++) {
BM_ITER_ELEM (l, &liter, eve_line[i], BM_LOOPS_OF_VERT) {
- if (!uvedit_face_visible_test(scene, obedit, ima, l->f)) {
+ if (!uvedit_face_visible_test(scene, l->f)) {
continue;
}
@@ -754,7 +745,6 @@ static int uv_remove_doubles_to_selected(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
SpaceImage *sima = CTX_wm_space_image(C);
- Image *ima = CTX_data_edit_image(C);
const ToolSettings *ts = scene->toolsettings;
const float threshold = RNA_float_get(op->ptr, "threshold");
@@ -808,7 +798,7 @@ static int uv_remove_doubles_to_selected(bContext *C, wmOperator *op)
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, obedit, ima, efa)) {
+ if (!uvedit_face_visible_test(scene, efa)) {
continue;
}
@@ -899,7 +889,6 @@ static int uv_remove_doubles_to_unselected(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
SpaceImage *sima = CTX_wm_space_image(C);
- Image *ima = CTX_data_edit_image(C);
const ToolSettings *ts = scene->toolsettings;
const float threshold = RNA_float_get(op->ptr, "threshold");
@@ -939,7 +928,7 @@ static int uv_remove_doubles_to_unselected(bContext *C, wmOperator *op)
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, obedit, ima, efa)) {
+ if (!uvedit_face_visible_test(scene, efa)) {
continue;
}
@@ -972,7 +961,7 @@ static int uv_remove_doubles_to_unselected(bContext *C, wmOperator *op)
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, obedit, ima, efa)) {
+ if (!uvedit_face_visible_test(scene, efa)) {
continue;
}
@@ -1086,10 +1075,12 @@ static void uv_snap_cursor_to_pixels(SpaceImage *sima)
uv_snap_to_pixel(sima->cursor, width, height);
}
-static bool uv_snap_cursor_to_selection(
- Scene *scene, Image *ima, Object **objects_edit, uint objects_len, SpaceImage *sima)
+static bool uv_snap_cursor_to_selection(Scene *scene,
+ Object **objects_edit,
+ uint objects_len,
+ SpaceImage *sima)
{
- return ED_uvedit_center_multi(scene, ima, objects_edit, objects_len, sima->cursor, sima->around);
+ return ED_uvedit_center_multi(scene, objects_edit, objects_len, sima->cursor, sima->around);
}
static int uv_snap_cursor_exec(bContext *C, wmOperator *op)
@@ -1105,13 +1096,12 @@ static int uv_snap_cursor_exec(bContext *C, wmOperator *op)
break;
case 1: {
Scene *scene = CTX_data_scene(C);
- Image *ima = CTX_data_edit_image(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
view_layer, ((View3D *)NULL), &objects_len);
- changed = uv_snap_cursor_to_selection(scene, ima, objects, objects_len, sima);
+ changed = uv_snap_cursor_to_selection(scene, objects, objects_len, sima);
MEM_freeN(objects);
break;
}
@@ -1155,7 +1145,7 @@ static void UV_OT_snap_cursor(wmOperatorType *ot)
/** \name Snap Selection Operator
* \{ */
-static bool uv_snap_uvs_to_cursor(Scene *scene, Image *ima, Object *obedit, const float cursor[2])
+static bool uv_snap_uvs_to_cursor(Scene *scene, Object *obedit, const float cursor[2])
{
BMEditMesh *em = BKE_editmesh_from_object(obedit);
BMFace *efa;
@@ -1167,7 +1157,7 @@ static bool uv_snap_uvs_to_cursor(Scene *scene, Image *ima, Object *obedit, cons
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, obedit, ima, efa)) {
+ if (!uvedit_face_visible_test(scene, efa)) {
continue;
}
@@ -1183,7 +1173,7 @@ static bool uv_snap_uvs_to_cursor(Scene *scene, Image *ima, Object *obedit, cons
return changed;
}
-static bool uv_snap_uvs_offset(Scene *scene, Image *ima, Object *obedit, const float offset[2])
+static bool uv_snap_uvs_offset(Scene *scene, Object *obedit, const float offset[2])
{
BMEditMesh *em = BKE_editmesh_from_object(obedit);
BMFace *efa;
@@ -1195,7 +1185,7 @@ static bool uv_snap_uvs_offset(Scene *scene, Image *ima, Object *obedit, const f
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, obedit, ima, efa)) {
+ if (!uvedit_face_visible_test(scene, efa)) {
continue;
}
@@ -1211,7 +1201,7 @@ static bool uv_snap_uvs_offset(Scene *scene, Image *ima, Object *obedit, const f
return changed;
}
-static bool uv_snap_uvs_to_adjacent_unselected(Scene *scene, Image *ima, Object *obedit)
+static bool uv_snap_uvs_to_adjacent_unselected(Scene *scene, Object *obedit)
{
BMEditMesh *em = BKE_editmesh_from_object(obedit);
BMesh *bm = em->bm;
@@ -1225,7 +1215,7 @@ static bool uv_snap_uvs_to_adjacent_unselected(Scene *scene, Image *ima, Object
/* index every vert that has a selected UV using it, but only once so as to
* get unique indices and to count how much to malloc */
BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
- if (uvedit_face_visible_test(scene, obedit, ima, f)) {
+ if (uvedit_face_visible_test(scene, f)) {
BM_elem_flag_enable(f, BM_ELEM_TAG);
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
BM_elem_flag_set(l, BM_ELEM_TAG, uvedit_uv_select_test(scene, l, cd_loop_uv_offset));
@@ -1269,7 +1259,6 @@ static bool uv_snap_uvs_to_adjacent_unselected(Scene *scene, Image *ima, Object
static bool uv_snap_uvs_to_pixels(SpaceImage *sima, Scene *scene, Object *obedit)
{
BMEditMesh *em = BKE_editmesh_from_object(obedit);
- Image *ima = sima->image;
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
@@ -1285,7 +1274,7 @@ static bool uv_snap_uvs_to_pixels(SpaceImage *sima, Scene *scene, Object *obedit
h = (float)height;
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, obedit, ima, efa)) {
+ if (!uvedit_face_visible_test(scene, efa)) {
continue;
}
@@ -1307,7 +1296,6 @@ static int uv_snap_selection_exec(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
SpaceImage *sima = CTX_wm_space_image(C);
- Image *ima = CTX_data_edit_image(C);
const ToolSettings *ts = scene->toolsettings;
const bool synced_selection = (ts->uv_flag & UV_SYNC_SELECTION) != 0;
const int target = RNA_enum_get(op->ptr, "target");
@@ -1319,7 +1307,7 @@ static int uv_snap_selection_exec(bContext *C, wmOperator *op)
if (target == 2) {
float center[2];
- if (!ED_uvedit_center_multi(scene, ima, objects, objects_len, center, sima->around)) {
+ if (!ED_uvedit_center_multi(scene, objects, objects_len, center, sima->around)) {
MEM_freeN(objects);
return OPERATOR_CANCELLED;
}
@@ -1341,13 +1329,13 @@ static int uv_snap_selection_exec(bContext *C, wmOperator *op)
changed = uv_snap_uvs_to_pixels(sima, scene, obedit);
break;
case 1:
- changed = uv_snap_uvs_to_cursor(scene, ima, obedit, sima->cursor);
+ changed = uv_snap_uvs_to_cursor(scene, obedit, sima->cursor);
break;
case 2:
- changed = uv_snap_uvs_offset(scene, ima, obedit, offset);
+ changed = uv_snap_uvs_offset(scene, obedit, offset);
break;
case 3:
- changed = uv_snap_uvs_to_adjacent_unselected(scene, ima, obedit);
+ changed = uv_snap_uvs_to_adjacent_unselected(scene, obedit);
break;
}
@@ -1398,7 +1386,6 @@ static int uv_pin_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
- Image *ima = CTX_data_edit_image(C);
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
@@ -1423,7 +1410,7 @@ static int uv_pin_exec(bContext *C, wmOperator *op)
}
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, obedit, ima, efa)) {
+ if (!uvedit_face_visible_test(scene, efa)) {
continue;
}
@@ -1501,11 +1488,9 @@ static bool bm_face_is_all_uv_sel(BMFace *f, bool select_test, const int cd_loop
static int uv_hide_exec(bContext *C, wmOperator *op)
{
ViewLayer *view_layer = CTX_data_view_layer(C);
- SpaceImage *sima = CTX_wm_space_image(C);
Scene *scene = CTX_data_scene(C);
const ToolSettings *ts = scene->toolsettings;
const bool swap = RNA_boolean_get(op->ptr, "unselected");
- Image *ima = sima ? sima->image : NULL;
const int use_face_center = (ts->uv_selectmode == UV_SELECT_FACE);
uint objects_len = 0;
@@ -1532,7 +1517,7 @@ static int uv_hide_exec(bContext *C, wmOperator *op)
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
int hide = 0;
- if (!uvedit_face_visible_test(scene, ob, ima, efa)) {
+ if (!uvedit_face_visible_test(scene, efa)) {
continue;
}
@@ -2006,8 +1991,6 @@ static void UV_OT_seams_from_islands(wmOperatorType *ot)
static int uv_mark_seam_exec(bContext *C, wmOperator *op)
{
- SpaceImage *sima = CTX_wm_space_image(C);
- Image *ima = sima ? sima->image : NULL;
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
const ToolSettings *ts = scene->toolsettings;
@@ -2038,7 +2021,7 @@ static int uv_mark_seam_exec(bContext *C, wmOperator *op)
const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
- if (uvedit_face_visible_test(scene, ob, ima, efa)) {
+ if (uvedit_face_visible_test(scene, efa)) {
BM_ITER_ELEM (loop, &liter, efa, BM_LOOPS_OF_FACE) {
if (uvedit_edge_select_test(scene, loop, cd_loop_uv_offset)) {
BM_elem_flag_set(loop->e, BM_ELEM_SEAM, flag_set);
diff --git a/source/blender/editors/uvedit/uvedit_select.c b/source/blender/editors/uvedit/uvedit_select.c
index 6e931b56a85..cc9be9d48c1 100644
--- a/source/blender/editors/uvedit/uvedit_select.c
+++ b/source/blender/editors/uvedit/uvedit_select.c
@@ -70,9 +70,11 @@
#include "uvedit_intern.h"
-static void uv_select_all_perform(Scene *scene, Image *ima, Object *obedit, int action);
-static void uv_select_all_perform_multi(
- Scene *scene, Image *ima, Object **objects, const uint objects_len, int action);
+static void uv_select_all_perform(Scene *scene, Object *obedit, int action);
+static void uv_select_all_perform_multi(Scene *scene,
+ Object **objects,
+ const uint objects_len,
+ int action);
static void uv_select_flush_from_tag_face(SpaceImage *sima,
Scene *scene,
Object *obedit,
@@ -112,7 +114,7 @@ static void uvedit_vertex_select_tagged(BMEditMesh *em,
}
}
-bool uvedit_face_visible_nolocal_ex(const ToolSettings *ts, BMFace *efa)
+bool uvedit_face_visible_test_ex(const ToolSettings *ts, BMFace *efa)
{
if (ts->uv_flag & UV_SYNC_SELECTION) {
return (BM_elem_flag_test(efa, BM_ELEM_HIDDEN) == 0);
@@ -121,25 +123,9 @@ bool uvedit_face_visible_nolocal_ex(const ToolSettings *ts, BMFace *efa)
return (BM_elem_flag_test(efa, BM_ELEM_HIDDEN) == 0 && BM_elem_flag_test(efa, BM_ELEM_SELECT));
}
}
-bool uvedit_face_visible_nolocal(const Scene *scene, BMFace *efa)
+bool uvedit_face_visible_test(const Scene *scene, BMFace *efa)
{
- return uvedit_face_visible_nolocal_ex(scene->toolsettings, efa);
-}
-
-bool uvedit_face_visible_test_ex(const ToolSettings *ts, Object *obedit, Image *ima, BMFace *efa)
-{
- if (ts->uv_flag & UV_SHOW_SAME_IMAGE) {
- Image *face_image;
- ED_object_get_active_image(obedit, efa->mat_nr + 1, &face_image, NULL, NULL, NULL);
- return (face_image == ima) ? uvedit_face_visible_nolocal_ex(ts, efa) : false;
- }
- else {
- return uvedit_face_visible_nolocal_ex(ts, efa);
- }
-}
-bool uvedit_face_visible_test(const Scene *scene, Object *obedit, Image *ima, BMFace *efa)
-{
- return uvedit_face_visible_test_ex(scene->toolsettings, obedit, ima, efa);
+ return uvedit_face_visible_test_ex(scene->toolsettings, efa);
}
bool uvedit_face_select_test_ex(const ToolSettings *ts, BMFace *efa, const int cd_loop_uv_offset)
@@ -437,8 +423,7 @@ void uvedit_uv_select_disable(BMEditMesh *em,
/** \name Find Nearest Elements
* \{ */
-bool uv_find_nearest_edge(
- Scene *scene, Image *ima, Object *obedit, const float co[2], UvNearestHit *hit)
+bool uv_find_nearest_edge(Scene *scene, Object *obedit, const float co[2], UvNearestHit *hit)
{
BMEditMesh *em = BKE_editmesh_from_object(obedit);
BMFace *efa;
@@ -453,7 +438,7 @@ bool uv_find_nearest_edge(
BM_mesh_elem_index_ensure(em->bm, BM_VERT);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, obedit, ima, efa)) {
+ if (!uvedit_face_visible_test(scene, efa)) {
continue;
}
BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
@@ -479,7 +464,6 @@ bool uv_find_nearest_edge(
}
bool uv_find_nearest_edge_multi(Scene *scene,
- Image *ima,
Object **objects,
const uint objects_len,
const float co[2],
@@ -488,7 +472,7 @@ bool uv_find_nearest_edge_multi(Scene *scene,
bool found = false;
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
- if (uv_find_nearest_edge(scene, ima, obedit, co, hit_final)) {
+ if (uv_find_nearest_edge(scene, obedit, co, hit_final)) {
hit_final->ob = obedit;
found = true;
}
@@ -496,8 +480,7 @@ bool uv_find_nearest_edge_multi(Scene *scene,
return found;
}
-bool uv_find_nearest_face(
- Scene *scene, Image *ima, Object *obedit, const float co[2], UvNearestHit *hit_final)
+bool uv_find_nearest_face(Scene *scene, Object *obedit, const float co[2], UvNearestHit *hit_final)
{
BMEditMesh *em = BKE_editmesh_from_object(obedit);
bool found = false;
@@ -507,7 +490,7 @@ bool uv_find_nearest_face(
/* this will fill in hit.vert1 and hit.vert2 */
float dist_sq_init = hit_final->dist_sq;
UvNearestHit hit = *hit_final;
- if (uv_find_nearest_edge(scene, ima, obedit, co, &hit)) {
+ if (uv_find_nearest_edge(scene, obedit, co, &hit)) {
hit.dist_sq = dist_sq_init;
hit.l = NULL;
hit.luv = hit.luv_next = NULL;
@@ -516,7 +499,7 @@ bool uv_find_nearest_face(
BMFace *efa;
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, obedit, ima, efa)) {
+ if (!uvedit_face_visible_test(scene, efa)) {
continue;
}
@@ -539,7 +522,6 @@ bool uv_find_nearest_face(
}
bool uv_find_nearest_face_multi(Scene *scene,
- Image *ima,
Object **objects,
const uint objects_len,
const float co[2],
@@ -548,7 +530,7 @@ bool uv_find_nearest_face_multi(Scene *scene,
bool found = false;
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
- if (uv_find_nearest_face(scene, ima, obedit, co, hit_final)) {
+ if (uv_find_nearest_face(scene, obedit, co, hit_final)) {
hit_final->ob = obedit;
found = true;
}
@@ -567,7 +549,6 @@ static bool uv_nearest_between(const BMLoop *l, const float co[2], const int cd_
}
bool uv_find_nearest_vert(Scene *scene,
- Image *ima,
Object *obedit,
float const co[2],
const float penalty_dist,
@@ -578,7 +559,7 @@ bool uv_find_nearest_vert(Scene *scene,
/* this will fill in hit.vert1 and hit.vert2 */
float dist_sq_init = hit_final->dist_sq;
UvNearestHit hit = *hit_final;
- if (uv_find_nearest_edge(scene, ima, obedit, co, &hit)) {
+ if (uv_find_nearest_edge(scene, obedit, co, &hit)) {
hit.dist_sq = dist_sq_init;
hit.l = NULL;
@@ -593,7 +574,7 @@ bool uv_find_nearest_vert(Scene *scene,
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, obedit, ima, efa)) {
+ if (!uvedit_face_visible_test(scene, efa)) {
continue;
}
@@ -639,7 +620,6 @@ bool uv_find_nearest_vert(Scene *scene,
}
bool uv_find_nearest_vert_multi(Scene *scene,
- Image *ima,
Object **objects,
const uint objects_len,
float const co[2],
@@ -649,7 +629,7 @@ bool uv_find_nearest_vert_multi(Scene *scene,
bool found = false;
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
- if (uv_find_nearest_vert(scene, ima, obedit, co, penalty_dist, hit_final)) {
+ if (uv_find_nearest_vert(scene, obedit, co, penalty_dist, hit_final)) {
hit_final->ob = obedit;
found = true;
}
@@ -657,12 +637,8 @@ bool uv_find_nearest_vert_multi(Scene *scene,
return found;
}
-bool ED_uvedit_nearest_uv(const Scene *scene,
- Object *obedit,
- Image *ima,
- const float co[2],
- float *dist_sq,
- float r_uv[2])
+bool ED_uvedit_nearest_uv(
+ const Scene *scene, Object *obedit, const float co[2], float *dist_sq, float r_uv[2])
{
BMEditMesh *em = BKE_editmesh_from_object(obedit);
BMIter iter;
@@ -671,7 +647,7 @@ bool ED_uvedit_nearest_uv(const Scene *scene,
float dist_best = *dist_sq;
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, obedit, ima, efa)) {
+ if (!uvedit_face_visible_test(scene, efa)) {
continue;
}
BMLoop *l_iter, *l_first;
@@ -697,7 +673,6 @@ bool ED_uvedit_nearest_uv(const Scene *scene,
}
bool ED_uvedit_nearest_uv_multi(const Scene *scene,
- Image *ima,
Object **objects,
const uint objects_len,
const float co[2],
@@ -707,7 +682,7 @@ bool ED_uvedit_nearest_uv_multi(const Scene *scene,
bool found = false;
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
- if (ED_uvedit_nearest_uv(scene, obedit, ima, co, dist_sq, r_uv)) {
+ if (ED_uvedit_nearest_uv(scene, obedit, co, dist_sq, r_uv)) {
found = true;
}
}
@@ -817,12 +792,8 @@ static bool uv_select_edgeloop_edge_tag_faces(BMEditMesh *em,
return true;
}
-static int uv_select_edgeloop(Scene *scene,
- Image *ima,
- Object *obedit,
- UvNearestHit *hit,
- const float limit[2],
- const bool extend)
+static int uv_select_edgeloop(
+ Scene *scene, Object *obedit, UvNearestHit *hit, const float limit[2], const bool extend)
{
BMEditMesh *em = BKE_editmesh_from_object(obedit);
BMFace *efa;
@@ -843,7 +814,7 @@ static int uv_select_edgeloop(Scene *scene,
BM_mesh_elem_index_ensure(em->bm, BM_VERT | BM_FACE);
if (!extend) {
- uv_select_all_perform(scene, ima, obedit, SEL_DESELECT);
+ uv_select_all_perform(scene, obedit, SEL_DESELECT);
}
BM_mesh_elem_hflag_disable_all(em->bm, BM_FACE, BM_ELEM_TAG, false);
@@ -867,8 +838,7 @@ static int uv_select_edgeloop(Scene *scene,
/* find correct valence edges which are not tagged yet, but connect to tagged one */
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!BM_elem_flag_test(efa, BM_ELEM_TAG) &&
- uvedit_face_visible_test(scene, obedit, ima, efa)) {
+ if (!BM_elem_flag_test(efa, BM_ELEM_TAG) && uvedit_face_visible_test(scene, efa)) {
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
/* check face not hidden and not tagged */
if (!(iterv_curr = uv_select_edgeloop_vertex_map_get(vmap, efa, l))) {
@@ -930,7 +900,6 @@ static int uv_select_edgeloop(Scene *scene,
* \{ */
static void uv_select_linked_multi(Scene *scene,
- Image *ima,
Object **objects,
const uint objects_len,
const float limit[2],
@@ -980,7 +949,7 @@ static void uv_select_linked_multi(Scene *scene,
if (hit_final == NULL) {
/* Use existing selection */
BM_ITER_MESH_INDEX (efa, &iter, em->bm, BM_FACES_OF_MESH, a) {
- if (uvedit_face_visible_test(scene, obedit, ima, efa)) {
+ if (uvedit_face_visible_test(scene, efa)) {
if (select_faces) {
if (BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
stack[stacksize] = a;
@@ -1121,14 +1090,15 @@ static void uv_select_linked_multi(Scene *scene,
* \warning This returns first selected UV,
* not ideal in many cases since there could be multiple.
*/
-const float *uvedit_first_selected_uv_from_vertex(
- Scene *scene, Object *obedit, Image *ima, BMVert *eve, const int cd_loop_uv_offset)
+const float *uvedit_first_selected_uv_from_vertex(Scene *scene,
+ BMVert *eve,
+ const int cd_loop_uv_offset)
{
BMIter liter;
BMLoop *l;
BM_ITER_ELEM (l, &liter, eve, BM_LOOPS_OF_VERT) {
- if (!uvedit_face_visible_test(scene, obedit, ima, l->f)) {
+ if (!uvedit_face_visible_test(scene, l->f)) {
continue;
}
@@ -1151,7 +1121,6 @@ static int uv_select_more_less(bContext *C, const bool select)
{
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
- Image *ima = CTX_data_edit_image(C);
SpaceImage *sima = CTX_wm_space_image(C);
BMFace *efa;
@@ -1193,7 +1162,7 @@ static int uv_select_more_less(bContext *C, const bool select)
/* mark loops to be selected */
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (uvedit_face_visible_test(scene, obedit, ima, efa)) {
+ if (uvedit_face_visible_test(scene, efa)) {
#define IS_SEL 1
#define IS_UNSEL 2
@@ -1233,7 +1202,7 @@ static int uv_select_more_less(bContext *C, const bool select)
/* mark loops to be selected */
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (uvedit_face_visible_test(scene, obedit, ima, efa)) {
+ if (uvedit_face_visible_test(scene, efa)) {
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
@@ -1308,7 +1277,7 @@ void UV_OT_select_less(wmOperatorType *ot)
/** \name (De)Select All Operator
* \{ */
-bool uvedit_select_is_any_selected(Scene *scene, Image *ima, Object *obedit)
+bool uvedit_select_is_any_selected(Scene *scene, Object *obedit)
{
const ToolSettings *ts = scene->toolsettings;
BMEditMesh *em = BKE_editmesh_from_object(obedit);
@@ -1323,7 +1292,7 @@ bool uvedit_select_is_any_selected(Scene *scene, Image *ima, Object *obedit)
else {
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, obedit, ima, efa)) {
+ if (!uvedit_face_visible_test(scene, efa)) {
continue;
}
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
@@ -1337,15 +1306,12 @@ bool uvedit_select_is_any_selected(Scene *scene, Image *ima, Object *obedit)
return false;
}
-bool uvedit_select_is_any_selected_multi(Scene *scene,
- Image *ima,
- Object **objects,
- const uint objects_len)
+bool uvedit_select_is_any_selected_multi(Scene *scene, Object **objects, const uint objects_len)
{
bool found = false;
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
- if (uvedit_select_is_any_selected(scene, ima, obedit)) {
+ if (uvedit_select_is_any_selected(scene, obedit)) {
found = true;
break;
}
@@ -1353,7 +1319,7 @@ bool uvedit_select_is_any_selected_multi(Scene *scene,
return found;
}
-static void uv_select_all_perform(Scene *scene, Image *ima, Object *obedit, int action)
+static void uv_select_all_perform(Scene *scene, Object *obedit, int action)
{
const ToolSettings *ts = scene->toolsettings;
BMEditMesh *em = BKE_editmesh_from_object(obedit);
@@ -1365,7 +1331,7 @@ static void uv_select_all_perform(Scene *scene, Image *ima, Object *obedit, int
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
if (action == SEL_TOGGLE) {
- action = uvedit_select_is_any_selected(scene, ima, obedit) ? SEL_DESELECT : SEL_SELECT;
+ action = uvedit_select_is_any_selected(scene, obedit) ? SEL_DESELECT : SEL_SELECT;
}
if (ts->uv_flag & UV_SYNC_SELECTION) {
@@ -1387,7 +1353,7 @@ static void uv_select_all_perform(Scene *scene, Image *ima, Object *obedit, int
}
else {
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, obedit, ima, efa)) {
+ if (!uvedit_face_visible_test(scene, efa)) {
continue;
}
@@ -1410,17 +1376,19 @@ static void uv_select_all_perform(Scene *scene, Image *ima, Object *obedit, int
}
}
-static void uv_select_all_perform_multi(
- Scene *scene, Image *ima, Object **objects, const uint objects_len, int action)
+static void uv_select_all_perform_multi(Scene *scene,
+ Object **objects,
+ const uint objects_len,
+ int action)
{
if (action == SEL_TOGGLE) {
- action = uvedit_select_is_any_selected_multi(scene, ima, objects, objects_len) ? SEL_DESELECT :
- SEL_SELECT;
+ action = uvedit_select_is_any_selected_multi(scene, objects, objects_len) ? SEL_DESELECT :
+ SEL_SELECT;
}
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
- uv_select_all_perform(scene, ima, obedit, action);
+ uv_select_all_perform(scene, obedit, action);
}
}
@@ -1429,7 +1397,6 @@ static int uv_select_all_exec(bContext *C, wmOperator *op)
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
Scene *scene = CTX_data_scene(C);
const ToolSettings *ts = scene->toolsettings;
- Image *ima = CTX_data_edit_image(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
int action = RNA_enum_get(op->ptr, "action");
@@ -1438,7 +1405,7 @@ static int uv_select_all_exec(bContext *C, wmOperator *op)
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
view_layer, ((View3D *)NULL), &objects_len);
- uv_select_all_perform_multi(scene, ima, objects, objects_len, action);
+ uv_select_all_perform_multi(scene, objects, objects_len, action);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
@@ -1510,7 +1477,6 @@ static int uv_mouse_select_multi(bContext *C,
SpaceImage *sima = CTX_wm_space_image(C);
Scene *scene = CTX_data_scene(C);
const ToolSettings *ts = scene->toolsettings;
- Image *ima = CTX_data_edit_image(C);
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
@@ -1563,12 +1529,11 @@ static int uv_mouse_select_multi(bContext *C,
/* find nearest element */
if (loop) {
/* find edge */
- found_item = uv_find_nearest_edge_multi(scene, ima, objects, objects_len, co, &hit);
+ found_item = uv_find_nearest_edge_multi(scene, objects, objects_len, co, &hit);
}
else if (selectmode == UV_SELECT_VERTEX) {
/* find vertex */
- found_item = uv_find_nearest_vert_multi(
- scene, ima, objects, objects_len, co, penalty_dist, &hit);
+ found_item = uv_find_nearest_vert_multi(scene, objects, objects_len, co, penalty_dist, &hit);
found_item = found_item && (!deselect_all || hit.dist_sq < penalty_dist);
if (found_item) {
@@ -1585,7 +1550,7 @@ static int uv_mouse_select_multi(bContext *C,
}
else if (selectmode == UV_SELECT_EDGE) {
/* find edge */
- found_item = uv_find_nearest_edge_multi(scene, ima, objects, objects_len, co, &hit);
+ found_item = uv_find_nearest_edge_multi(scene, objects, objects_len, co, &hit);
found_item = found_item && (!deselect_all || hit.dist_sq < penalty_dist);
if (found_item) {
@@ -1604,7 +1569,7 @@ static int uv_mouse_select_multi(bContext *C,
}
else if (selectmode == UV_SELECT_FACE) {
/* find face */
- found_item = uv_find_nearest_face_multi(scene, ima, objects, objects_len, co, &hit);
+ found_item = uv_find_nearest_face_multi(scene, objects, objects_len, co, &hit);
found_item = found_item && (!deselect_all || hit.dist_sq < penalty_dist);
if (found_item) {
@@ -1628,13 +1593,13 @@ static int uv_mouse_select_multi(bContext *C,
}
}
else if (selectmode == UV_SELECT_ISLAND) {
- found_item = uv_find_nearest_edge_multi(scene, ima, objects, objects_len, co, &hit);
+ found_item = uv_find_nearest_edge_multi(scene, objects, objects_len, co, &hit);
found_item = found_item && (!deselect_all || hit.dist_sq < penalty_dist);
}
if (!found_item) {
if (deselect_all) {
- uv_select_all_perform_multi(scene, ima, objects, objects_len, SEL_DESELECT);
+ uv_select_all_perform_multi(scene, objects, objects_len, SEL_DESELECT);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
@@ -1654,19 +1619,18 @@ static int uv_mouse_select_multi(bContext *C,
if (loop) {
if (!extend) {
/* TODO(MULTI_EDIT): We only need to de-select non-active */
- uv_select_all_perform_multi(scene, ima, objects, objects_len, SEL_DESELECT);
+ uv_select_all_perform_multi(scene, objects, objects_len, SEL_DESELECT);
}
- flush = uv_select_edgeloop(scene, ima, obedit, &hit, limit, extend);
+ flush = uv_select_edgeloop(scene, obedit, &hit, limit, extend);
}
else if (selectmode == UV_SELECT_ISLAND) {
if (!extend) {
/* TODO(MULTI_EDIT): We only need to de-select non-active */
- uv_select_all_perform_multi(scene, ima, objects, objects_len, SEL_DESELECT);
+ uv_select_all_perform_multi(scene, objects, objects_len, SEL_DESELECT);
}
/* Current behavior of 'extend'
* is actually toggling, so pass extend flag as 'toggle' here */
- uv_select_linked_multi(
- scene, ima, objects, objects_len, limit, &hit, false, false, extend, false);
+ uv_select_linked_multi(scene, objects, objects_len, limit, &hit, false, false, extend, false);
}
else if (extend) {
if (selectmode == UV_SELECT_VERTEX) {
@@ -1701,7 +1665,7 @@ static int uv_mouse_select_multi(bContext *C,
BM_mesh_elem_index_ensure(em->bm, BM_VERT);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, obedit, ima, efa)) {
+ if (!uvedit_face_visible_test(scene, efa)) {
continue;
}
@@ -1719,7 +1683,7 @@ static int uv_mouse_select_multi(bContext *C,
}
else {
/* deselect all */
- uv_select_all_perform_multi(scene, ima, objects, objects_len, SEL_DESELECT);
+ uv_select_all_perform_multi(scene, objects, objects_len, SEL_DESELECT);
if (selectmode == UV_SELECT_VERTEX) {
/* select vertex */
@@ -1739,7 +1703,7 @@ static int uv_mouse_select_multi(bContext *C,
/* select sticky uvs */
if (sticky != SI_STICKY_DISABLE) {
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, obedit, ima, efa)) {
+ if (!uvedit_face_visible_test(scene, efa)) {
continue;
}
@@ -1946,7 +1910,6 @@ static int uv_select_linked_internal(bContext *C, wmOperator *op, const wmEvent
Scene *scene = CTX_data_scene(C);
const ToolSettings *ts = scene->toolsettings;
ViewLayer *view_layer = CTX_data_view_layer(C);
- Image *ima = CTX_data_edit_image(C);
float limit[2];
bool extend = true;
bool deselect = false;
@@ -1986,18 +1949,17 @@ static int uv_select_linked_internal(bContext *C, wmOperator *op, const wmEvent
RNA_float_get_array(op->ptr, "location", co);
}
- if (!uv_find_nearest_edge_multi(scene, ima, objects, objects_len, co, &hit)) {
+ if (!uv_find_nearest_edge_multi(scene, objects, objects_len, co, &hit)) {
MEM_freeN(objects);
return OPERATOR_CANCELLED;
}
}
if (!extend) {
- uv_select_all_perform_multi(scene, ima, objects, objects_len, SEL_DESELECT);
+ uv_select_all_perform_multi(scene, objects, objects_len, SEL_DESELECT);
}
uv_select_linked_multi(scene,
- ima,
objects,
objects_len,
limit,
@@ -2117,7 +2079,6 @@ static int uv_select_split_exec(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
const ToolSettings *ts = scene->toolsettings;
- Image *ima = CTX_data_edit_image(C);
BMFace *efa;
BMLoop *l;
@@ -2147,7 +2108,7 @@ static int uv_select_split_exec(bContext *C, wmOperator *op)
bool is_sel = false;
bool is_unsel = false;
- if (!uvedit_face_visible_test(scene, obedit, ima, efa)) {
+ if (!uvedit_face_visible_test(scene, efa)) {
continue;
}
@@ -2483,7 +2444,6 @@ static int uv_box_select_exec(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
const ToolSettings *ts = scene->toolsettings;
ViewLayer *view_layer = CTX_data_view_layer(C);
- Image *ima = CTX_data_edit_image(C);
const ARegion *region = CTX_wm_region(C);
BMFace *efa;
BMLoop *l;
@@ -2518,7 +2478,7 @@ static int uv_box_select_exec(bContext *C, wmOperator *op)
view_layer, ((View3D *)NULL), &objects_len);
if (use_pre_deselect) {
- uv_select_all_perform_multi(scene, ima, objects, objects_len, SEL_DESELECT);
+ uv_select_all_perform_multi(scene, objects, objects_len, SEL_DESELECT);
}
/* don't indent to avoid diff noise! */
@@ -2539,7 +2499,7 @@ static int uv_box_select_exec(bContext *C, wmOperator *op)
/* assume not touched */
BM_elem_flag_disable(efa, BM_ELEM_TAG);
- if (uvedit_face_visible_test(scene, obedit, ima, efa)) {
+ if (uvedit_face_visible_test(scene, efa)) {
uv_poly_center(efa, cent, cd_loop_uv_offset);
if (BLI_rctf_isect_pt_v(&rectf, cent)) {
BM_elem_flag_enable(efa, BM_ELEM_TAG);
@@ -2558,7 +2518,7 @@ static int uv_box_select_exec(bContext *C, wmOperator *op)
BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT, BM_ELEM_TAG, false);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, obedit, ima, efa)) {
+ if (!uvedit_face_visible_test(scene, efa)) {
continue;
}
@@ -2594,7 +2554,7 @@ static int uv_box_select_exec(bContext *C, wmOperator *op)
BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT, BM_ELEM_TAG, false);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, obedit, ima, efa)) {
+ if (!uvedit_face_visible_test(scene, efa)) {
continue;
}
bool has_selected = false;
@@ -2623,7 +2583,7 @@ static int uv_box_select_exec(bContext *C, wmOperator *op)
.efa = efa,
};
uv_select_linked_multi(
- scene, ima, objects, objects_len, limit, &hit, true, !select, false, false);
+ scene, objects, objects_len, limit, &hit, true, !select, false, false);
}
}
@@ -2708,7 +2668,6 @@ static int uv_circle_select_exec(bContext *C, wmOperator *op)
{
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
SpaceImage *sima = CTX_wm_space_image(C);
- Image *ima = CTX_data_edit_image(C);
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
const ToolSettings *ts = scene->toolsettings;
@@ -2757,7 +2716,7 @@ static int uv_circle_select_exec(bContext *C, wmOperator *op)
const bool use_pre_deselect = SEL_OP_USE_PRE_DESELECT(sel_op);
if (use_pre_deselect) {
- uv_select_all_perform_multi(scene, ima, objects, objects_len, SEL_DESELECT);
+ uv_select_all_perform_multi(scene, objects, objects_len, SEL_DESELECT);
}
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
@@ -2792,7 +2751,7 @@ static int uv_circle_select_exec(bContext *C, wmOperator *op)
BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT, BM_ELEM_TAG, false);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, obedit, ima, efa)) {
+ if (!uvedit_face_visible_test(scene, efa)) {
continue;
}
@@ -2826,7 +2785,7 @@ static int uv_circle_select_exec(bContext *C, wmOperator *op)
BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT, BM_ELEM_TAG, false);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, obedit, ima, efa)) {
+ if (!uvedit_face_visible_test(scene, efa)) {
continue;
}
bool has_selected = false;
@@ -2847,7 +2806,7 @@ static int uv_circle_select_exec(bContext *C, wmOperator *op)
.efa = efa,
};
uv_select_linked_multi(
- scene, ima, objects, objects_len, limit, &hit, true, !select, false, false);
+ scene, objects, objects_len, limit, &hit, true, !select, false, false);
}
}
@@ -2920,7 +2879,6 @@ static bool do_lasso_select_mesh_uv(bContext *C,
{
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
SpaceImage *sima = CTX_wm_space_image(C);
- Image *ima = CTX_data_edit_image(C);
const ARegion *region = CTX_wm_region(C);
Scene *scene = CTX_data_scene(C);
const ToolSettings *ts = scene->toolsettings;
@@ -2952,7 +2910,7 @@ static bool do_lasso_select_mesh_uv(bContext *C,
view_layer, ((View3D *)NULL), &objects_len);
if (use_pre_deselect) {
- uv_select_all_perform_multi(scene, ima, objects, objects_len, SEL_DESELECT);
+ uv_select_all_perform_multi(scene, objects, objects_len, SEL_DESELECT);
}
/* don't indent to avoid diff noise! */
@@ -2988,7 +2946,7 @@ static bool do_lasso_select_mesh_uv(bContext *C,
BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT, BM_ELEM_TAG, false);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, obedit, ima, efa)) {
+ if (!uvedit_face_visible_test(scene, efa)) {
continue;
}
@@ -3025,7 +2983,7 @@ static bool do_lasso_select_mesh_uv(bContext *C,
BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT, BM_ELEM_TAG, false);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, obedit, ima, efa)) {
+ if (!uvedit_face_visible_test(scene, efa)) {
continue;
}
bool has_selected = false;
@@ -3047,7 +3005,7 @@ static bool do_lasso_select_mesh_uv(bContext *C,
.efa = efa,
};
uv_select_linked_multi(
- scene, ima, objects, objects_len, limit, &hit, true, !select, false, false);
+ scene, objects, objects_len, limit, &hit, true, !select, false, false);
}
}
@@ -3116,7 +3074,6 @@ static int uv_select_pinned_exec(bContext *C, wmOperator *UNUSED(op))
Scene *scene = CTX_data_scene(C);
const ToolSettings *ts = scene->toolsettings;
ViewLayer *view_layer = CTX_data_view_layer(C);
- Image *ima = CTX_data_edit_image(C);
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
@@ -3134,7 +3091,7 @@ static int uv_select_pinned_exec(bContext *C, wmOperator *UNUSED(op))
bool changed = false;
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, obedit, ima, efa)) {
+ if (!uvedit_face_visible_test(scene, efa)) {
continue;
}
@@ -3208,7 +3165,6 @@ static int uv_select_overlap(bContext *C, const bool extend)
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
- Image *ima = CTX_data_edit_image(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
@@ -3224,13 +3180,13 @@ static int uv_select_overlap(bContext *C, const bool extend)
BM_mesh_elem_index_ensure(em->bm, BM_VERT | BM_FACE);
BM_mesh_elem_hflag_disable_all(em->bm, BM_FACE, BM_ELEM_TAG, false);
if (!extend) {
- uv_select_all_perform(scene, ima, obedit, SEL_DESELECT);
+ uv_select_all_perform(scene, obedit, SEL_DESELECT);
}
BMIter iter;
BMFace *efa;
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test_ex(scene->toolsettings, obedit, ima, efa)) {
+ if (!uvedit_face_visible_test_ex(scene->toolsettings, efa)) {
continue;
}
uv_tri_len += efa->len - 2;
@@ -3261,7 +3217,7 @@ static int uv_select_overlap(bContext *C, const bool extend)
int face_index;
BM_ITER_MESH_INDEX (efa, &iter, em->bm, BM_FACES_OF_MESH, face_index) {
- if (!uvedit_face_visible_test_ex(scene->toolsettings, obedit, ima, efa)) {
+ if (!uvedit_face_visible_test_ex(scene->toolsettings, efa)) {
continue;
}
diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c
index 3a4f12acf9c..594847b7249 100644
--- a/source/blender/editors/uvedit/uvedit_smart_stitch.c
+++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c
@@ -2550,12 +2550,11 @@ static StitchState *stitch_select(bContext *C,
float co[2];
UvNearestHit hit = UV_NEAREST_HIT_INIT;
ARegion *region = CTX_wm_region(C);
- Image *ima = CTX_data_edit_image(C);
UI_view2d_region_to_view(&region->v2d, event->mval[0], event->mval[1], &co[0], &co[1]);
if (ssc->mode == STITCH_VERT) {
- if (uv_find_nearest_vert_multi(scene, ima, ssc->objects, ssc->objects_len, co, 0.0f, &hit)) {
+ if (uv_find_nearest_vert_multi(scene, ssc->objects, ssc->objects_len, co, 0.0f, &hit)) {
/* Add vertex to selection, deselect all common uv's of vert other than selected and
* update the preview. This behavior was decided so that you can do stuff like deselect
* the opposite stitchable vertex and the initial still gets deselected */
@@ -2576,7 +2575,7 @@ static StitchState *stitch_select(bContext *C,
return state;
}
}
- else if (uv_find_nearest_edge_multi(scene, ima, ssc->objects, ssc->objects_len, co, &hit)) {
+ else if (uv_find_nearest_edge_multi(scene, ssc->objects, ssc->objects_len, co, &hit)) {
/* find StitchState from hit->ob */
StitchState *state = NULL;
for (uint ob_index = 0; ob_index < ssc->objects_len; ob_index++) {
diff --git a/source/blender/freestyle/intern/application/Controller.cpp b/source/blender/freestyle/intern/application/Controller.cpp
index 66195745cbb..253d62ea3dc 100644
--- a/source/blender/freestyle/intern/application/Controller.cpp
+++ b/source/blender/freestyle/intern/application/Controller.cpp
@@ -923,19 +923,16 @@ Render *Controller::RenderStrokes(Render *re, bool render)
cout << "Stroke rendering : " << d << endl;
uintptr_t mem_in_use = MEM_get_memory_in_use();
- uintptr_t mmap_in_use = MEM_get_mapped_memory_in_use();
uintptr_t peak_memory = MEM_get_peak_memory();
- float megs_used_memory = (mem_in_use - mmap_in_use) / (1024.0 * 1024.0);
- float mmap_used_memory = (mmap_in_use) / (1024.0 * 1024.0);
+ float megs_used_memory = (mem_in_use) / (1024.0 * 1024.0);
float megs_peak_memory = (peak_memory) / (1024.0 * 1024.0);
- printf("%d objs, %d verts, %d faces, mem %.2fM (%.2fM, peak %.2fM)\n",
+ printf("%d objs, %d verts, %d faces, mem %.2fM (peak %.2fM)\n",
totmesh,
freestyle_render->i.totvert,
freestyle_render->i.totface,
megs_used_memory,
- mmap_used_memory,
megs_peak_memory);
}
delete blenderRenderer;
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c
index 82f9d9a323d..73328d7dd31 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c
@@ -170,9 +170,12 @@ static void deformStroke(GpencilModifierData *md,
float *noise_table_thickness = (mmd->factor_thickness > 0.0f) ? noise_table(len, seed) : NULL;
float *noise_table_uvs = (mmd->factor_uvs > 0.0f) ? noise_table(len, seed + 4) : NULL;
- /* calculate stroke normal*/
+ /* Calculate stroke normal. */
if (gps->totpoints > 2) {
BKE_gpencil_stroke_normal(gps, normal);
+ if (is_zero_v3(normal)) {
+ copy_v3_fl(normal, 1.0f);
+ }
}
else {
copy_v3_fl(normal, 1.0f);
diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c
index e9061f1a029..cef90d57ef5 100644
--- a/source/blender/gpu/intern/gpu_buffers.c
+++ b/source/blender/gpu/intern/gpu_buffers.c
@@ -151,7 +151,10 @@ static bool gpu_pbvh_vert_buf_data_set(GPU_PBVH_Buffers *buffers, uint vert_len)
/* Initialize vertex buffer (match 'VertexBufferFormat'). */
buffers->vert_buf = GPU_vertbuf_create_with_format_ex(&g_vbo_id.format, GPU_USAGE_STATIC);
}
- GPU_vertbuf_data_alloc(buffers->vert_buf, vert_len);
+ if (buffers->vert_buf->data == NULL || buffers->vert_buf->vertex_len != vert_len) {
+ /* Allocate buffer if not allocated yet or size changed. */
+ GPU_vertbuf_data_alloc(buffers->vert_buf, vert_len);
+ }
#endif
return buffers->vert_buf->data != NULL;
@@ -1083,13 +1086,24 @@ short GPU_pbvh_buffers_material_index_get(GPU_PBVH_Buffers *buffers)
return buffers->material_index;
}
+static void gpu_pbvh_buffers_clear(GPU_PBVH_Buffers *buffers)
+{
+ GPU_BATCH_DISCARD_SAFE(buffers->lines);
+ GPU_BATCH_DISCARD_SAFE(buffers->lines_fast);
+ GPU_BATCH_DISCARD_SAFE(buffers->triangles);
+ GPU_BATCH_DISCARD_SAFE(buffers->triangles_fast);
+ GPU_INDEXBUF_DISCARD_SAFE(buffers->index_lines_buf_fast);
+ GPU_INDEXBUF_DISCARD_SAFE(buffers->index_lines_buf);
+ GPU_INDEXBUF_DISCARD_SAFE(buffers->index_buf_fast);
+ GPU_INDEXBUF_DISCARD_SAFE(buffers->index_buf);
+ GPU_VERTBUF_DISCARD_SAFE(buffers->vert_buf);
+}
+
void GPU_pbvh_buffers_update_flush(GPU_PBVH_Buffers *buffers)
{
/* Free empty bmesh node buffers. */
if (buffers->clear_bmesh_on_flush) {
- GPU_BATCH_DISCARD_SAFE(buffers->triangles);
- GPU_INDEXBUF_DISCARD_SAFE(buffers->index_buf);
- GPU_VERTBUF_DISCARD_SAFE(buffers->vert_buf);
+ gpu_pbvh_buffers_clear(buffers);
buffers->clear_bmesh_on_flush = false;
}
@@ -1102,16 +1116,7 @@ void GPU_pbvh_buffers_update_flush(GPU_PBVH_Buffers *buffers)
void GPU_pbvh_buffers_free(GPU_PBVH_Buffers *buffers)
{
if (buffers) {
- GPU_BATCH_DISCARD_SAFE(buffers->lines);
- GPU_BATCH_DISCARD_SAFE(buffers->lines_fast);
- GPU_BATCH_DISCARD_SAFE(buffers->triangles);
- GPU_BATCH_DISCARD_SAFE(buffers->triangles_fast);
- GPU_INDEXBUF_DISCARD_SAFE(buffers->index_lines_buf_fast);
- GPU_INDEXBUF_DISCARD_SAFE(buffers->index_lines_buf);
- GPU_INDEXBUF_DISCARD_SAFE(buffers->index_buf_fast);
- GPU_INDEXBUF_DISCARD_SAFE(buffers->index_buf);
- GPU_VERTBUF_DISCARD_SAFE(buffers->vert_buf);
-
+ gpu_pbvh_buffers_clear(buffers);
MEM_freeN(buffers);
}
}
diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c
index 2a8a4d416d8..7871907a7d4 100644
--- a/source/blender/gpu/intern/gpu_draw.c
+++ b/source/blender/gpu/intern/gpu_draw.c
@@ -905,7 +905,7 @@ GPUTexture *GPU_texture_from_blender(Image *ima, ImageUser *iuser, ImBuf *ibuf,
bindcode = gpu_texture_create_tile_array(ima, ibuf_intern);
}
else if (textarget == GL_TEXTURE_1D_ARRAY) {
- bindcode = gpu_texture_create_tile_mapping(ima, iuser->multiview_eye);
+ bindcode = gpu_texture_create_tile_mapping(ima, iuser ? iuser->multiview_eye : 0);
}
else {
bindcode = gpu_texture_create_from_ibuf(ima, ibuf_intern, textarget);
diff --git a/source/blender/gpu/intern/gpu_extensions.c b/source/blender/gpu/intern/gpu_extensions.c
index e3632b82778..ff745787630 100644
--- a/source/blender/gpu/intern/gpu_extensions.c
+++ b/source/blender/gpu/intern/gpu_extensions.c
@@ -304,6 +304,14 @@ void gpu_extensions_init(void)
GG.context_local_shaders_workaround = GLEW_ARB_get_program_binary;
}
+ /* Special fix for theses specific GPUs. Without thoses workaround, blender crashes on strartup.
+ * (see T72098) */
+ if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_WIN, GPU_DRIVER_OFFICIAL) &&
+ (strstr(renderer, "HD Graphics 620") || strstr(renderer, "HD Graphics 630"))) {
+ GG.mip_render_workaround = true;
+ GG.context_local_shaders_workaround = GLEW_ARB_get_program_binary;
+ }
+
/* df/dy calculation factors, those are dependent on driver */
GG.dfdyfactors[0] = 1.0;
GG.dfdyfactors[1] = 1.0;
diff --git a/source/blender/gpu/intern/gpu_shader_interface.c b/source/blender/gpu/intern/gpu_shader_interface.c
index 1caa88d18ae..3218d12bc0d 100644
--- a/source/blender/gpu/intern/gpu_shader_interface.c
+++ b/source/blender/gpu/intern/gpu_shader_interface.c
@@ -261,7 +261,9 @@ GPUShaderInterface *GPU_shaderinterface_create(int32_t program)
continue;
}
- shaderface->enabled_attr_mask |= (1 << input->location);
+ if (input->location != -1) {
+ shaderface->enabled_attr_mask |= (1 << input->location);
+ }
set_input_name(shaderface, input, name, name_len);
diff --git a/source/blender/imbuf/IMB_colormanagement.h b/source/blender/imbuf/IMB_colormanagement.h
index 1639fb4715f..3158e3419b0 100644
--- a/source/blender/imbuf/IMB_colormanagement.h
+++ b/source/blender/imbuf/IMB_colormanagement.h
@@ -56,6 +56,7 @@ void IMB_colormanagement_validate_settings(
const char *IMB_colormanagement_role_colorspace_name_get(int role);
void IMB_colormanagement_check_is_data(struct ImBuf *ibuf, const char *name);
+void IMB_colormanagegent_copy_settings(struct ImBuf *ibuf_src, struct ImBuf *ibuf_dst);
void IMB_colormanagement_assign_float_colorspace(struct ImBuf *ibuf, const char *name);
void IMB_colormanagement_assign_rect_colorspace(struct ImBuf *ibuf, const char *name);
diff --git a/source/blender/imbuf/intern/allocimbuf.c b/source/blender/imbuf/intern/allocimbuf.c
index 6c17254e697..4b3858e6d5a 100644
--- a/source/blender/imbuf/intern/allocimbuf.c
+++ b/source/blender/imbuf/intern/allocimbuf.c
@@ -380,7 +380,7 @@ void *imb_alloc_pixels(
}
size_t size = (size_t)x * (size_t)y * (size_t)channels * typesize;
- return MEM_mapallocN(size, name);
+ return MEM_callocN(size, name);
}
bool imb_addrectfloatImBuf(ImBuf *ibuf)
diff --git a/source/blender/imbuf/intern/cache.c b/source/blender/imbuf/intern/cache.c
index 176b41d2706..23ce9bd7818 100644
--- a/source/blender/imbuf/intern/cache.c
+++ b/source/blender/imbuf/intern/cache.c
@@ -427,8 +427,8 @@ void IMB_tiles_to_rect(ImBuf *ibuf)
/* don't call imb_addrectImBuf, it frees all mipmaps */
if (!mipbuf->rect) {
- if ((mipbuf->rect = MEM_mapallocN(ibuf->x * ibuf->y * sizeof(unsigned int),
- "imb_addrectImBuf"))) {
+ if ((mipbuf->rect = MEM_callocN(ibuf->x * ibuf->y * sizeof(unsigned int),
+ "imb_addrectImBuf"))) {
mipbuf->mall |= IB_rect;
mipbuf->flags |= IB_rect;
}
diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c
index c57ab70f4e6..3f5a0f25cc5 100644
--- a/source/blender/imbuf/intern/colormanagement.c
+++ b/source/blender/imbuf/intern/colormanagement.c
@@ -1349,6 +1349,23 @@ void IMB_colormanagement_check_is_data(ImBuf *ibuf, const char *name)
}
}
+void IMB_colormanagegent_copy_settings(ImBuf *ibuf_src, ImBuf *ibuf_dst)
+{
+ IMB_colormanagement_assign_rect_colorspace(ibuf_dst,
+ IMB_colormanagement_get_rect_colorspace(ibuf_src));
+ IMB_colormanagement_assign_float_colorspace(ibuf_dst,
+ IMB_colormanagement_get_float_colorspace(ibuf_src));
+ if (ibuf_src->flags & IB_alphamode_premul) {
+ ibuf_dst->flags |= IB_alphamode_premul;
+ }
+ else if (ibuf_src->flags & IB_alphamode_channel_packed) {
+ ibuf_dst->flags |= IB_alphamode_channel_packed;
+ }
+ else if (ibuf_src->flags & IB_alphamode_ignore) {
+ ibuf_dst->flags |= IB_alphamode_ignore;
+ }
+}
+
void IMB_colormanagement_assign_float_colorspace(ImBuf *ibuf, const char *name)
{
ColorSpace *colorspace = colormanage_colorspace_get_named(name);
diff --git a/source/blender/imbuf/intern/divers.c b/source/blender/imbuf/intern/divers.c
index e068a84aab0..bcc8488089d 100644
--- a/source/blender/imbuf/intern/divers.c
+++ b/source/blender/imbuf/intern/divers.c
@@ -788,7 +788,7 @@ void IMB_float_from_rect(ImBuf *ibuf)
size = size * 4 * sizeof(float);
ibuf->channels = 4;
- rect_float = MEM_mapallocN(size, "IMB_float_from_rect");
+ rect_float = MEM_callocN(size, "IMB_float_from_rect");
if (rect_float == NULL) {
return;
diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp
index 62cc2e605e5..882808cbc14 100644
--- a/source/blender/imbuf/intern/openexr/openexr_api.cpp
+++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp
@@ -1598,8 +1598,8 @@ static ExrHandle *imb_exr_begin_read_mem(IStream &file_stream,
for (lay = (ExrLayer *)data->layers.first; lay; lay = lay->next) {
for (pass = (ExrPass *)lay->passes.first; pass; pass = pass->next) {
if (pass->totchan) {
- pass->rect = (float *)MEM_mapallocN(width * height * pass->totchan * sizeof(float),
- "pass rect");
+ pass->rect = (float *)MEM_callocN(width * height * pass->totchan * sizeof(float),
+ "pass rect");
if (pass->totchan == 1) {
echan = pass->chan[0];
echan->rect = pass->rect;
diff --git a/source/blender/io/alembic/intern/abc_reader_nurbs.cc b/source/blender/io/alembic/intern/abc_reader_nurbs.cc
index 10d9a35a8e1..5b9954b3ff6 100644
--- a/source/blender/io/alembic/intern/abc_reader_nurbs.cc
+++ b/source/blender/io/alembic/intern/abc_reader_nurbs.cc
@@ -71,7 +71,7 @@ bool AbcNurbsReader::valid() const
static bool set_knots(const FloatArraySamplePtr &knots, float *&nu_knots)
{
- if (!knots || knots->size() == 0) {
+ if (!knots || knots->size() < 2) {
return false;
}
diff --git a/source/blender/io/avi/intern/avi_mjpeg.c b/source/blender/io/avi/intern/avi_mjpeg.c
index ac622d8b0e4..70ddca28060 100644
--- a/source/blender/io/avi/intern/avi_mjpeg.c
+++ b/source/blender/io/avi/intern/avi_mjpeg.c
@@ -30,6 +30,7 @@
#include "MEM_guardedalloc.h"
+#include "BLI_math_base.h"
#include "IMB_imbuf.h"
#include "jerror.h"
@@ -45,14 +46,16 @@ static size_t numbytes;
static void add_huff_table(j_decompress_ptr dinfo,
JHUFF_TBL **htblptr,
const UINT8 *bits,
- const UINT8 *val)
+ const size_t bits_size,
+ const UINT8 *val,
+ const size_t val_size)
{
if (*htblptr == NULL) {
*htblptr = jpeg_alloc_huff_table((j_common_ptr)dinfo);
}
- memcpy((*htblptr)->bits, bits, sizeof((*htblptr)->bits));
- memcpy((*htblptr)->huffval, val, sizeof((*htblptr)->huffval));
+ memcpy((*htblptr)->bits, bits, min_zz(sizeof((*htblptr)->bits), bits_size));
+ memcpy((*htblptr)->huffval, val, min_zz(sizeof((*htblptr)->huffval), val_size));
/* Initialize sent_table false so table will be written to JPEG file. */
(*htblptr)->sent_table = false;
@@ -200,10 +203,30 @@ static void std_huff_tables(j_decompress_ptr dinfo)
0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa,
};
- add_huff_table(dinfo, &dinfo->dc_huff_tbl_ptrs[0], bits_dc_luminance, val_dc_luminance);
- add_huff_table(dinfo, &dinfo->ac_huff_tbl_ptrs[0], bits_ac_luminance, val_ac_luminance);
- add_huff_table(dinfo, &dinfo->dc_huff_tbl_ptrs[1], bits_dc_chrominance, val_dc_chrominance);
- add_huff_table(dinfo, &dinfo->ac_huff_tbl_ptrs[1], bits_ac_chrominance, val_ac_chrominance);
+ add_huff_table(dinfo,
+ &dinfo->dc_huff_tbl_ptrs[0],
+ bits_dc_luminance,
+ sizeof(bits_dc_luminance),
+ val_dc_luminance,
+ sizeof(val_dc_luminance));
+ add_huff_table(dinfo,
+ &dinfo->ac_huff_tbl_ptrs[0],
+ bits_ac_luminance,
+ sizeof(bits_ac_luminance),
+ val_ac_luminance,
+ sizeof(val_ac_luminance));
+ add_huff_table(dinfo,
+ &dinfo->dc_huff_tbl_ptrs[1],
+ bits_dc_chrominance,
+ sizeof(bits_dc_chrominance),
+ val_dc_chrominance,
+ sizeof(val_dc_chrominance));
+ add_huff_table(dinfo,
+ &dinfo->ac_huff_tbl_ptrs[1],
+ bits_ac_chrominance,
+ sizeof(bits_ac_chrominance),
+ val_ac_chrominance,
+ sizeof(val_ac_chrominance));
}
static int Decode_JPEG(unsigned char *inBuffer,
diff --git a/source/blender/io/usd/intern/abstract_hierarchy_iterator.cc b/source/blender/io/usd/intern/abstract_hierarchy_iterator.cc
index e382fa6bb1d..ab83ea2c3c4 100644
--- a/source/blender/io/usd/intern/abstract_hierarchy_iterator.cc
+++ b/source/blender/io/usd/intern/abstract_hierarchy_iterator.cc
@@ -53,7 +53,7 @@ bool HierarchyContext::operator<(const HierarchyContext &other) const
if (object != other.object) {
return object < other.object;
}
- if (duplicator != NULL && duplicator == other.duplicator) {
+ if (duplicator != nullptr && duplicator == other.duplicator) {
// Only resort to string comparisons when both objects are created by the same duplicator.
return export_name < other.export_name;
}
diff --git a/source/blender/io/usd/intern/usd_capi.cc b/source/blender/io/usd/intern/usd_capi.cc
index f8e0a03abfa..890e2fd205f 100644
--- a/source/blender/io/usd/intern/usd_capi.cc
+++ b/source/blender/io/usd/intern/usd_capi.cc
@@ -185,7 +185,7 @@ bool USD_export(bContext *C,
/* setup job */
WM_jobs_customdata_set(wm_job, job, MEM_freeN);
WM_jobs_timer(wm_job, 0.1, NC_SCENE | ND_FRAME, NC_SCENE | ND_FRAME);
- WM_jobs_callbacks(wm_job, USD::export_startjob, NULL, NULL, USD::export_endjob);
+ WM_jobs_callbacks(wm_job, USD::export_startjob, nullptr, nullptr, USD::export_endjob);
WM_jobs_start(CTX_wm_manager(C), wm_job);
}
diff --git a/source/blender/io/usd/intern/usd_writer_mesh.cc b/source/blender/io/usd/intern/usd_writer_mesh.cc
index 909869d2af1..841501bcf42 100644
--- a/source/blender/io/usd/intern/usd_writer_mesh.cc
+++ b/source/blender/io/usd/intern/usd_writer_mesh.cc
@@ -79,7 +79,7 @@ void USDGenericMeshWriter::do_write(HierarchyContext &context)
bool needsfree = false;
Mesh *mesh = get_export_mesh(object_eval, needsfree);
- if (mesh == NULL) {
+ if (mesh == nullptr) {
return;
}
@@ -100,7 +100,7 @@ void USDGenericMeshWriter::do_write(HierarchyContext &context)
void USDGenericMeshWriter::free_export_mesh(Mesh *mesh)
{
- BKE_id_free(NULL, mesh);
+ BKE_id_free(nullptr, mesh);
}
struct USDMeshData {
diff --git a/source/blender/io/usd/intern/usd_writer_transform.cc b/source/blender/io/usd/intern/usd_writer_transform.cc
index 038f2b17b1a..0694d873002 100644
--- a/source/blender/io/usd/intern/usd_writer_transform.cc
+++ b/source/blender/io/usd/intern/usd_writer_transform.cc
@@ -50,7 +50,7 @@ void USDTransformWriter::do_write(HierarchyContext &context)
bool USDTransformWriter::check_is_animated(const HierarchyContext &context) const
{
- if (context.duplicator != NULL) {
+ if (context.duplicator != nullptr) {
/* This object is being duplicated, so could be emitted by a particle system and thus
* influenced by forces. TODO(Sybren): Make this more strict. Probably better to get from the
* depsgraph whether this object instance has a time source. */
diff --git a/source/blender/makesdna/DNA_fluid_types.h b/source/blender/makesdna/DNA_fluid_types.h
index 6583aa2eeee..7da33a369f3 100644
--- a/source/blender/makesdna/DNA_fluid_types.h
+++ b/source/blender/makesdna/DNA_fluid_types.h
@@ -215,39 +215,54 @@ enum {
#define FLUID_DOMAIN_SMOKE_SCRIPT "smoke_script.py"
#define FLUID_DOMAIN_LIQUID_SCRIPT "liquid_script.py"
-#define FLUID_DOMAIN_FILE_CONFIG "config_####"
-
-#define FLUID_DOMAIN_FILE_DENSITY "density_####"
-#define FLUID_DOMAIN_FILE_SHADOW "shadow_####"
-#define FLUID_DOMAIN_FILE_VEL "vel_####"
-#define FLUID_DOMAIN_FILE_HEAT "heat_####"
-#define FLUID_DOMAIN_FILE_COLORR "color_r_####"
-#define FLUID_DOMAIN_FILE_COLORG "color_g_####"
-#define FLUID_DOMAIN_FILE_COLORB "color_b_####"
-#define FLUID_DOMAIN_FILE_FLAME "flame_####"
-#define FLUID_DOMAIN_FILE_FUEL "fuel_####"
-#define FLUID_DOMAIN_FILE_REACT "react_####"
-
-#define FLUID_DOMAIN_FILE_PHI "phi_####"
-#define FLUID_DOMAIN_FILE_PP "pp_####"
-#define FLUID_DOMAIN_FILE_PVEL "pVel_####"
-
-#define FLUID_DOMAIN_FILE_DENSITYNOISE "density_noise_####"
-#define FLUID_DOMAIN_FILE_COLORRNOISE "color_r_noise_####"
-#define FLUID_DOMAIN_FILE_COLORGNOISE "color_g_noise_####"
-#define FLUID_DOMAIN_FILE_COLORBNOISE "color_b_noise_####"
-#define FLUID_DOMAIN_FILE_FLAMENOISE "flame_noise_####"
-#define FLUID_DOMAIN_FILE_FUELNOISE "fuel_noise_####"
-#define FLUID_DOMAIN_FILE_REACTNOISE "react_noise_####"
-
-#define FLUID_DOMAIN_FILE_MESH "lMesh_####"
-#define FLUID_DOMAIN_FILE_MESHVEL "lVelMesh_####"
-
-#define FLUID_DOMAIN_FILE_PPSND "ppSnd_####"
-#define FLUID_DOMAIN_FILE_PVELSND "pVelSnd_####"
-#define FLUID_DOMAIN_FILE_PLIFESND "pLifeSnd_####"
-
-#define FLUID_DOMAIN_FILE_GUIDEVEL "guidevel_####"
+#define FLUID_FILENAME_CONFIG "config_####"
+
+#define FLUID_FILENAME_DATA "fluid_data_####"
+#define FLUID_FILENAME_NOISE "fluid_noise_####"
+#define FLUID_FILENAME_DENSITY "density_####"
+#define FLUID_FILENAME_SHADOW "shadow_####"
+#define FLUID_FILENAME_VELOCITY "vel_####"
+#define FLUID_FILENAME_HEAT "heat_####"
+#define FLUID_FILENAME_COLORR "color_r_####"
+#define FLUID_FILENAME_COLORG "color_g_####"
+#define FLUID_FILENAME_COLORB "color_b_####"
+#define FLUID_FILENAME_FLAME "flame_####"
+#define FLUID_FILENAME_FUEL "fuel_####"
+#define FLUID_FILENAME_REACT "react_####"
+#define FLUID_FILENAME_PHI "phi_####"
+#define FLUID_FILENAME_PP "pp_####"
+#define FLUID_FILENAME_PVEL "pVel_####"
+#define FLUID_FILENAME_DENSITYNOISE "density_noise_####"
+#define FLUID_FILENAME_COLORRNOISE "color_r_noise_####"
+#define FLUID_FILENAME_COLORGNOISE "color_g_noise_####"
+#define FLUID_FILENAME_COLORBNOISE "color_b_noise_####"
+#define FLUID_FILENAME_FLAMENOISE "flame_noise_####"
+#define FLUID_FILENAME_FUELNOISE "fuel_noise_####"
+#define FLUID_FILENAME_REACTNOISE "react_noise_####"
+#define FLUID_FILENAME_MESH "lMesh_####"
+#define FLUID_FILENAME_MESHVEL "lVelMesh_####"
+#define FLUID_FILENAME_PPSND "ppSnd_####"
+#define FLUID_FILENAME_PVELSND "pVelSnd_####"
+#define FLUID_FILENAME_PLIFESND "pLifeSnd_####"
+#define FLUID_FILENAME_GUIDEVEL "guidevel_####"
+
+#define FLUID_GRIDNAME_DENSITY "density"
+#define FLUID_GRIDNAME_SHADOW "shadow"
+#define FLUID_GRIDNAME_VELOCITY "velocity"
+#define FLUID_GRIDNAME_HEAT "heat"
+#define FLUID_GRIDNAME_COLORR "color_r"
+#define FLUID_GRIDNAME_COLORG "color_g"
+#define FLUID_GRIDNAME_COLORB "color_b"
+#define FLUID_GRIDNAME_FLAME "flame"
+#define FLUID_GRIDNAME_FUEL "fuel"
+#define FLUID_GRIDNAME_REACT "react"
+#define FLUID_GRIDNAME_DENSITYNOISE "density_noise"
+#define FLUID_GRIDNAME_COLORRNOISE "color_r_noise"
+#define FLUID_GRIDNAME_COLORGNOISE "color_g_noise"
+#define FLUID_GRIDNAME_COLORBNOISE "color_b_noise"
+#define FLUID_GRIDNAME_FLAMENOISE "flame_noise"
+#define FLUID_GRIDNAME_FUELNOISE "fuel_noise"
+#define FLUID_GRIDNAME_REACTNOISE "react_noise"
#define FLUID_DOMAIN_EXTENSION_UNI ".uni"
#define FLUID_DOMAIN_EXTENSION_OPENVDB ".vdb"
@@ -256,6 +271,17 @@ enum {
#define FLUID_DOMAIN_EXTENSION_BINOBJ ".bobj.gz"
enum {
+ FLUID_DOMAIN_GRID_FLOAT = 0,
+ FLUID_DOMAIN_GRID_INT = 1,
+ FLUID_DOMAIN_GRID_VEC3F = 2,
+};
+
+enum {
+ FLUID_DOMAIN_CACHE_FILES_SINGLE = 0,
+ FLUID_DOMAIN_CACHE_FILES_COMBINED = 1,
+};
+
+enum {
FLUID_DOMAIN_CACHE_REPLAY = 0,
FLUID_DOMAIN_CACHE_MODULAR = 1,
FLUID_DOMAIN_CACHE_FINAL = 2,
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index 1533b82ad4e..8c34a7cb0a1 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -555,13 +555,14 @@ typedef struct BakeData {
short margin, flag;
float cage_extrusion;
+ float max_ray_distance;
int pass_filter;
char normal_swizzle[3];
char normal_space;
char save_mode;
- char _pad[3];
+ char _pad[7];
struct Object *cage_object;
} BakeData;
diff --git a/source/blender/makesdna/DNA_view3d_defaults.h b/source/blender/makesdna/DNA_view3d_defaults.h
index afade37d0c8..20b491c47f2 100644
--- a/source/blender/makesdna/DNA_view3d_defaults.h
+++ b/source/blender/makesdna/DNA_view3d_defaults.h
@@ -65,7 +65,7 @@
V3D_OVERLAY_EDIT_SHARP | V3D_OVERLAY_EDIT_FREESTYLE_EDGE | \
V3D_OVERLAY_EDIT_FREESTYLE_FACE | V3D_OVERLAY_EDIT_EDGES | \
V3D_OVERLAY_EDIT_CREASES | V3D_OVERLAY_EDIT_BWEIGHTS | \
- V3D_OVERLAY_EDIT_CU_HANDLES | V3D_OVERLAY_EDIT_CU_NORMALS, \
+ V3D_OVERLAY_EDIT_CU_HANDLES, \
\
.gpencil_paper_opacity = 0.5f, \
.gpencil_grid_opacity = 0.9f, \
diff --git a/source/blender/makesdna/intern/CMakeLists.txt b/source/blender/makesdna/intern/CMakeLists.txt
index 1b0bf086269..01e3971a216 100644
--- a/source/blender/makesdna/intern/CMakeLists.txt
+++ b/source/blender/makesdna/intern/CMakeLists.txt
@@ -58,6 +58,10 @@ setup_platform_linker_flags()
add_executable(makesdna ${SRC} ${SRC_DNA_INC})
+if(WIN32 AND NOT UNIX)
+ target_link_libraries(makesdna ${PTHREADS_LIBRARIES})
+endif()
+
# Output dna.c
add_custom_command(
OUTPUT
diff --git a/source/blender/makesrna/intern/CMakeLists.txt b/source/blender/makesrna/intern/CMakeLists.txt
index cd05aba8794..024bdbe5ed5 100644
--- a/source/blender/makesrna/intern/CMakeLists.txt
+++ b/source/blender/makesrna/intern/CMakeLists.txt
@@ -394,6 +394,10 @@ add_executable(makesrna ${SRC} ${SRC_RNA_INC} ${SRC_DNA_INC})
target_link_libraries(makesrna bf_dna)
target_link_libraries(makesrna bf_dna_blenlib)
+if(WIN32 AND NOT UNIX)
+ target_link_libraries(makesrna ${PTHREADS_LIBRARIES})
+endif()
+
# Output rna_*_gen.c
# note (linux only): with crashes try add this after COMMAND: valgrind --leak-check=full --track-origins=yes
add_custom_command(
diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c
index 86a088f38ed..5506bfaaaf0 100644
--- a/source/blender/makesrna/intern/makesrna.c
+++ b/source/blender/makesrna/intern/makesrna.c
@@ -1823,6 +1823,10 @@ static void rna_def_property_funcs(FILE *f, StructRNA *srna, PropertyDefRNA *dp)
case PROP_ENUM: {
EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
+ if (!eprop->get && !eprop->set) {
+ rna_set_raw_property(dp, prop);
+ }
+
eprop->get = (void *)rna_def_property_get_func(f, srna, prop, dp, (const char *)eprop->get);
eprop->set = (void *)rna_def_property_set_func(f, srna, prop, dp, (const char *)eprop->set);
break;
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index 85892758a88..f14e81a38df 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -4386,8 +4386,8 @@ static int rna_raw_access(ReportList *reports,
/* check type */
itemtype = RNA_property_type(itemprop);
- if (!ELEM(itemtype, PROP_BOOLEAN, PROP_INT, PROP_FLOAT)) {
- BKE_report(reports, RPT_ERROR, "Only boolean, int and float properties supported");
+ if (!ELEM(itemtype, PROP_BOOLEAN, PROP_INT, PROP_FLOAT, PROP_ENUM)) {
+ BKE_report(reports, RPT_ERROR, "Only boolean, int float and enum properties supported");
return 0;
}
diff --git a/source/blender/makesrna/intern/rna_action.c b/source/blender/makesrna/intern/rna_action.c
index a3a89db66be..facbf8d59cc 100644
--- a/source/blender/makesrna/intern/rna_action.c
+++ b/source/blender/makesrna/intern/rna_action.c
@@ -345,14 +345,14 @@ static void rna_def_dopesheet(BlenderRNA *brna)
prop = RNA_def_property(srna, "show_only_selected", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "filterflag", ADS_FILTER_ONLYSEL);
RNA_def_property_ui_text(
- prop, "Only Selected", "Only include channels relating to selected objects and data");
+ prop, "Only Show Selected", "Only include channels relating to selected objects and data");
RNA_def_property_ui_icon(prop, ICON_RESTRICT_SELECT_OFF, 0);
RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
prop = RNA_def_property(srna, "show_hidden", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "filterflag", ADS_FILTER_INCL_HIDDEN);
RNA_def_property_ui_text(
- prop, "Display Hidden", "Include channels from objects/bone that are not visible");
+ prop, "Show Hidden", "Include channels from objects/bone that are not visible");
RNA_def_property_ui_icon(prop, ICON_OBJECT_HIDDEN, 0);
RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
@@ -368,8 +368,9 @@ static void rna_def_dopesheet(BlenderRNA *brna)
/* Debug Filtering Settings */
prop = RNA_def_property(srna, "show_only_errors", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "filterflag", ADS_FILTER_ONLY_ERRORS);
- RNA_def_property_ui_text(
- prop, "Show Errors", "Only include F-Curves and drivers that are disabled or have errors");
+ RNA_def_property_ui_text(prop,
+ "Only Show Errors",
+ "Only include F-Curves and drivers that are disabled or have errors");
RNA_def_property_ui_icon(prop, ICON_ERROR, 0);
RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
diff --git a/source/blender/makesrna/intern/rna_armature.c b/source/blender/makesrna/intern/rna_armature.c
index 3afbd0405fe..cd7875d84e3 100644
--- a/source/blender/makesrna/intern/rna_armature.c
+++ b/source/blender/makesrna/intern/rna_armature.c
@@ -176,6 +176,20 @@ static void rna_Armature_redraw_data(Main *UNUSED(bmain), Scene *UNUSED(scene),
WM_main_add_notifier(NC_GEOM | ND_DATA, id);
}
+/* Unselect bones when hidden */
+static void rna_Bone_hide_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
+{
+ bArmature *arm = (bArmature *)ptr->owner_id;
+ Bone *bone = (Bone *)ptr->data;
+
+ if (bone->flag & BONE_HIDDEN_P) {
+ bone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
+ }
+
+ WM_main_add_notifier(NC_OBJECT | ND_POSE, arm);
+ DEG_id_tag_update(&arm->id, ID_RECALC_COPY_ON_WRITE);
+}
+
/* called whenever a bone is renamed */
static void rna_Bone_update_renamed(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
@@ -301,8 +315,7 @@ static void rna_Bone_layer_set(PointerRNA *ptr, const bool *values)
Bone *bone = (Bone *)ptr->data;
rna_bone_layer_set(&bone->layer, values);
-
- BKE_armature_refresh_layer_used(arm);
+ BKE_armature_refresh_layer_used(NULL, arm);
}
/* TODO: remove the deprecation stubs. */
@@ -1144,7 +1157,8 @@ static void rna_def_bone(BlenderRNA *brna)
prop,
"Hide",
"Bone is not visible when it is not in Edit Mode (i.e. in Object or Pose Modes)");
- RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
+ RNA_def_property_ui_icon(prop, ICON_RESTRICT_VIEW_OFF, -1);
+ RNA_def_property_update(prop, 0, "rna_Bone_hide_update");
prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_SELECTED);
diff --git a/source/blender/makesrna/intern/rna_fluid.c b/source/blender/makesrna/intern/rna_fluid.c
index fff39326ada..93c7c1f3480 100644
--- a/source/blender/makesrna/intern/rna_fluid.c
+++ b/source/blender/makesrna/intern/rna_fluid.c
@@ -1725,7 +1725,7 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna)
"resolution of the domain). For best meshing, it is recommended to "
"adjust the mesh particle radius alongside this value");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Fluid_domain_reset");
+ RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Fluid_meshcache_reset");
prop = RNA_def_property(srna, "mesh_generator", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "mesh_generator");
@@ -1754,7 +1754,7 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna)
"Caches velocities of mesh vertices. These will be used "
"(automatically) when rendering with motion blur enabled");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Fluid_domain_reset");
+ RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Fluid_meshcache_reset");
prop = RNA_def_property(srna, "mesh_particle_radius", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, 0.0, 10.0);
@@ -2516,7 +2516,7 @@ static void rna_def_fluid_flow_settings(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_inflow", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", FLUID_FLOW_USE_INFLOW);
- RNA_def_property_ui_text(prop, "Enabled", "Control when to apply inflow");
+ RNA_def_property_ui_text(prop, "Use Flow", "Control when to apply fluid flow");
RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Fluid_flow_reset");
prop = RNA_def_property(srna, "subframes", PROP_INT, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_gpencil.c b/source/blender/makesrna/intern/rna_gpencil.c
index 33bf174be79..5f1ff0d8745 100644
--- a/source/blender/makesrna/intern/rna_gpencil.c
+++ b/source/blender/makesrna/intern/rna_gpencil.c
@@ -1187,7 +1187,6 @@ static void rna_def_gpencil_stroke(BlenderRNA *brna)
* (this is a special flag for fill brush). */
prop = RNA_def_property(srna, "is_nofill_stroke", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_STROKE_NOFILL);
- RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "No Fill", "Special stroke to use as boundary for filling areas");
RNA_def_property_update(prop, 0, "rna_GPencil_update");
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 30d1380417f..32999c91fad 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -960,12 +960,11 @@ static bool rna_NodeTree_check(bNodeTree *ntree, ReportList *reports)
static void rna_NodeTree_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
{
bNodeTree *ntree = (bNodeTree *)ptr->owner_id;
- bNode *node = (bNode *)ptr->data;
WM_main_add_notifier(NC_NODE | NA_EDITED, NULL);
WM_main_add_notifier(NC_SCENE | ND_NODES, &ntree->id);
- ED_node_tag_update_nodetree(bmain, ntree, node);
+ ED_node_tag_update_nodetree(bmain, ntree, NULL);
}
static bNode *rna_NodeTree_node_new(bNodeTree *ntree,
diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c
index c2ee256ad58..a27d77df32a 100644
--- a/source/blender/makesrna/intern/rna_object.c
+++ b/source/blender/makesrna/intern/rna_object.c
@@ -2890,6 +2890,7 @@ static void rna_def_object(BlenderRNA *brna)
prop = RNA_def_property(srna, "matrix_parent_inverse", PROP_FLOAT, PROP_MATRIX);
RNA_def_property_float_sdna(prop, NULL, "parentinv");
RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_4x4);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
RNA_def_property_ui_text(
prop, "Parent Inverse Matrix", "Inverse of object's parent matrix at time of parenting");
RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_Object_internal_update");
diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c
index 17e5f3d3649..8f28fc56712 100644
--- a/source/blender/makesrna/intern/rna_pose.c
+++ b/source/blender/makesrna/intern/rna_pose.c
@@ -295,6 +295,18 @@ static void rna_PoseChannel_name_set(PointerRNA *ptr, const char *value)
ED_armature_bone_rename(G_MAIN, ob->data, oldname, newname);
}
+/* See rna_Bone_update_renamed() */
+static void rna_PoseChannel_name_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
+{
+ ID *id = ptr->owner_id;
+
+ /* redraw view */
+ WM_main_add_notifier(NC_GEOM | ND_DATA, id);
+
+ /* update animation channels */
+ WM_main_add_notifier(NC_ANIMATION | ND_ANIMCHAN, id);
+}
+
static PointerRNA rna_PoseChannel_bone_get(PointerRNA *ptr)
{
Object *ob = (Object *)ptr->owner_id;
@@ -996,6 +1008,7 @@ static void rna_def_pose_channel(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Name", "");
RNA_def_property_editable_func(prop, "rna_PoseChannel_proxy_editable");
RNA_def_struct_name_property(srna, prop);
+ RNA_def_property_update(prop, 0, "rna_PoseChannel_name_update");
/* Baked Bone Path cache data */
rna_def_motionpath_common(srna);
diff --git a/source/blender/makesrna/intern/rna_render.c b/source/blender/makesrna/intern/rna_render.c
index 8322c7ad5f4..6c21e4ad01b 100644
--- a/source/blender/makesrna/intern/rna_render.c
+++ b/source/blender/makesrna/intern/rna_render.c
@@ -181,11 +181,8 @@ static void engine_bake(RenderEngine *engine,
struct Object *object,
const int pass_type,
const int pass_filter,
- const int object_id,
- const struct BakePixel *pixel_array,
- const int num_pixels,
- const int depth,
- void *result)
+ const int width,
+ const int height)
{
extern FunctionRNA rna_RenderEngine_bake_func;
PointerRNA ptr;
@@ -200,11 +197,8 @@ static void engine_bake(RenderEngine *engine,
RNA_parameter_set_lookup(&list, "object", &object);
RNA_parameter_set_lookup(&list, "pass_type", &pass_type);
RNA_parameter_set_lookup(&list, "pass_filter", &pass_filter);
- RNA_parameter_set_lookup(&list, "object_id", &object_id);
- RNA_parameter_set_lookup(&list, "pixel_array", &pixel_array);
- RNA_parameter_set_lookup(&list, "num_pixels", &num_pixels);
- RNA_parameter_set_lookup(&list, "depth", &depth);
- RNA_parameter_set_lookup(&list, "result", &result);
+ RNA_parameter_set_lookup(&list, "width", &width);
+ RNA_parameter_set_lookup(&list, "height", &height);
engine->type->rna_ext.call(NULL, &ptr, func, &list);
RNA_parameter_list_free(&list);
@@ -461,12 +455,6 @@ void rna_RenderPass_rect_set(PointerRNA *ptr, const float *values)
memcpy(rpass->rect, values, sizeof(float) * rpass->rectx * rpass->recty * rpass->channels);
}
-static PointerRNA rna_BakePixel_next_get(PointerRNA *ptr)
-{
- BakePixel *bp = ptr->data;
- return rna_pointer_inherit_refine(ptr, &RNA_BakePixel, bp + 1);
-}
-
static RenderPass *rna_RenderPass_find_by_type(RenderLayer *rl, int passtype, const char *view)
{
return RE_pass_find_by_type(rl, passtype, view);
@@ -535,33 +523,9 @@ static void rna_def_render_engine(BlenderRNA *brna)
0,
INT_MAX);
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
- parm = RNA_def_int(func,
- "object_id",
- 0,
- 0,
- INT_MAX,
- "Object Id",
- "Id of the current object being baked in relation to the others",
- 0,
- INT_MAX);
- RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
- parm = RNA_def_pointer(func, "pixel_array", "BakePixel", "", "");
- RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
- parm = RNA_def_int(func,
- "num_pixels",
- 0,
- 0,
- INT_MAX,
- "Number of Pixels",
- "Size of the baking batch",
- 0,
- INT_MAX);
- RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
- parm = RNA_def_int(
- func, "depth", 0, 0, INT_MAX, "Pixels depth", "Number of channels", 1, INT_MAX);
+ parm = RNA_def_int(func, "width", 0, 0, INT_MAX, "Width", "Image width", 0, INT_MAX);
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
- /* TODO, see how array size of 0 works, this shouldnt be used */
- parm = RNA_def_pointer(func, "result", "AnyType", "", "");
+ parm = RNA_def_int(func, "height", 0, 0, INT_MAX, "Height", "Image height", 0, INT_MAX);
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
/* viewport render callbacks */
@@ -1119,53 +1083,6 @@ static void rna_def_render_pass(BlenderRNA *brna)
RNA_define_verify_sdna(1);
}
-static void rna_def_render_bake_pixel(BlenderRNA *brna)
-{
- StructRNA *srna;
- PropertyRNA *prop;
-
- srna = RNA_def_struct(brna, "BakePixel", NULL);
- RNA_def_struct_ui_text(srna, "Bake Pixel", "");
-
- RNA_define_verify_sdna(0);
-
- prop = RNA_def_property(srna, "primitive_id", PROP_INT, PROP_NONE);
- RNA_def_property_int_sdna(prop, NULL, "primitive_id");
- RNA_def_property_clear_flag(prop, PROP_EDITABLE);
-
- prop = RNA_def_property(srna, "object_id", PROP_INT, PROP_NONE);
- RNA_def_property_int_sdna(prop, NULL, "object_id");
- RNA_def_property_clear_flag(prop, PROP_EDITABLE);
-
- prop = RNA_def_property(srna, "uv", PROP_FLOAT, PROP_NONE);
- RNA_def_property_array(prop, 2);
- RNA_def_property_float_sdna(prop, NULL, "uv");
- RNA_def_property_clear_flag(prop, PROP_EDITABLE);
-
- prop = RNA_def_property(srna, "du_dx", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "du_dx");
- RNA_def_property_clear_flag(prop, PROP_EDITABLE);
-
- prop = RNA_def_property(srna, "du_dy", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "du_dy");
- RNA_def_property_clear_flag(prop, PROP_EDITABLE);
-
- prop = RNA_def_property(srna, "dv_dx", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "dv_dx");
- RNA_def_property_clear_flag(prop, PROP_EDITABLE);
-
- prop = RNA_def_property(srna, "dv_dy", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "dv_dy");
- RNA_def_property_clear_flag(prop, PROP_EDITABLE);
-
- prop = RNA_def_property(srna, "next", PROP_POINTER, PROP_NONE);
- RNA_def_property_struct_type(prop, "BakePixel");
- RNA_def_property_pointer_funcs(prop, "rna_BakePixel_next_get", NULL, NULL, NULL);
- RNA_def_property_clear_flag(prop, PROP_EDITABLE);
-
- RNA_define_verify_sdna(1);
-}
-
void RNA_def_render(BlenderRNA *brna)
{
rna_def_render_engine(brna);
@@ -1173,7 +1090,6 @@ void RNA_def_render(BlenderRNA *brna)
rna_def_render_view(brna);
rna_def_render_layer(brna);
rna_def_render_pass(brna);
- rna_def_render_bake_pixel(brna);
}
#endif /* RNA_RUNTIME */
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index 6423175e2f4..e3d779ce7fb 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -3374,14 +3374,15 @@ static void rna_def_tool_settings(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_keyframe_insert_auto", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "autokey_mode", AUTOKEY_ON);
RNA_def_property_ui_text(
- prop, "Auto Keying", "Automatic keyframe insertion for Objects and Bones");
+ prop, "Auto Keying", "Automatic keyframe insertion for Objects, Bones and Masks");
RNA_def_property_ui_icon(prop, ICON_REC, 0);
prop = RNA_def_property(srna, "auto_keying_mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "autokey_mode");
RNA_def_property_enum_items(prop, auto_key_items);
- RNA_def_property_ui_text(
- prop, "Auto-Keying Mode", "Mode of automatic keyframe insertion for Objects and Bones");
+ RNA_def_property_ui_text(prop,
+ "Auto-Keying Mode",
+ "Mode of automatic keyframe insertion for Objects, Bones and Masks");
prop = RNA_def_property(srna, "use_record_with_nla", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "autokey_flag", ANIMRECORD_FLAG_WITHNLA);
@@ -4884,13 +4885,23 @@ static void rna_def_bake_data(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Margin", "Extends the baked result as a post process filter");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+ prop = RNA_def_property(srna, "max_ray_distance", PROP_FLOAT, PROP_DISTANCE);
+ RNA_def_property_range(prop, 0.0, FLT_MAX);
+ RNA_def_property_ui_range(prop, 0.0, 1.0, 1, 3);
+ RNA_def_property_ui_text(prop,
+ "Max Ray Distance",
+ "The maximum ray distance for matching points between the active and "
+ "selected objects. If zero, there is no limit");
+ RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+
prop = RNA_def_property(srna, "cage_extrusion", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_range(prop, 0.0, FLT_MAX);
RNA_def_property_ui_range(prop, 0.0, 1.0, 1, 3);
RNA_def_property_ui_text(
prop,
"Cage Extrusion",
- "Distance to use for the inward ray cast when using selected to active");
+ "Inflate the active object by the specified distance for baking. This helps matching to "
+ "points nearer to the outside of the selected object meshes");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
prop = RNA_def_property(srna, "normal_space", PROP_ENUM, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c
index 46b8d8647de..9184c54ae88 100644
--- a/source/blender/makesrna/intern/rna_texture.c
+++ b/source/blender/makesrna/intern/rna_texture.c
@@ -1565,7 +1565,11 @@ static void rna_def_texture(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_color_ramp", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", TEX_COLORBAND);
RNA_def_property_boolean_funcs(prop, NULL, "rna_Texture_use_color_ramp_set");
- RNA_def_property_ui_text(prop, "Use Color Ramp", "Toggle color ramp operations");
+ RNA_def_property_ui_text(prop,
+ "Use Color Ramp",
+ "Map the texture intensity to the color ramp. "
+ "Note that the alpha value is used for image textures, "
+ "enable \"Calculate Alpha\" for images without an alpha channel");
RNA_def_property_update(prop, 0, "rna_Texture_update");
prop = RNA_def_property(srna, "color_ramp", PROP_POINTER, PROP_NEVER_NULL);
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index 00d3189dcbe..aa138517209 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -5798,8 +5798,9 @@ static void rna_def_userdef_input(BlenderRNA *brna)
prop = RNA_def_property(srna, "ndof_fly_helicopter", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_FLY_HELICOPTER);
- RNA_def_property_ui_text(
- prop, "Helicopter Mode", "Device up/down directly controls your Z position");
+ RNA_def_property_ui_text(prop,
+ "Helicopter Mode",
+ "Device up/down directly controls the Z position of the 3D viewport");
/* let Python know whether NDOF is enabled */
prop = RNA_def_boolean(srna, "use_ndof", true, "", "");
diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c
index deeb4f5789c..6749aa9495a 100644
--- a/source/blender/makesrna/intern/rna_wm.c
+++ b/source/blender/makesrna/intern/rna_wm.c
@@ -450,7 +450,7 @@ static const EnumPropertyItem operator_flag_items[] = {
"UNDO_GROUPED",
0,
"Grouped Undo",
- "Push a single undo event for repetead instances of this operator"},
+ "Push a single undo event for repeated instances of this operator"},
{OPTYPE_BLOCKING, "BLOCKING", 0, "Blocking", "Block anything else from using the cursor"},
{OPTYPE_MACRO, "MACRO", 0, "Macro", "Use to check if an operator is a macro"},
{OPTYPE_GRAB_CURSOR_XY,
diff --git a/source/blender/modifiers/intern/MOD_mask.cc b/source/blender/modifiers/intern/MOD_mask.cc
index a458e4dd8bc..18b88864926 100644
--- a/source/blender/modifiers/intern/MOD_mask.cc
+++ b/source/blender/modifiers/intern/MOD_mask.cc
@@ -366,6 +366,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
copy_masked_polys_to_new_mesh(
*mesh, *result, vertex_map, edge_map, masked_poly_indices, new_loop_starts);
+ BKE_mesh_calc_edges_loose(result);
/* Tag to recalculate normals later. */
result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
diff --git a/source/blender/nodes/composite/nodes/node_composite_image.c b/source/blender/nodes/composite/nodes/node_composite_image.c
index 382459993b7..53ea02ff8a7 100644
--- a/source/blender/nodes/composite/nodes/node_composite_image.c
+++ b/source/blender/nodes/composite/nodes/node_composite_image.c
@@ -311,8 +311,7 @@ static void cmp_node_rlayer_create_outputs(bNodeTree *ntree,
if ((scene->r.mode & R_EDGE_FRS) &&
(view_layer->freestyle_config.flags & FREESTYLE_AS_RENDER_PASS)) {
- ntreeCompositRegisterPass(
- scene->nodetree, scene, view_layer, RE_PASSNAME_FREESTYLE, SOCK_RGBA);
+ ntreeCompositRegisterPass(ntree, scene, view_layer, RE_PASSNAME_FREESTYLE, SOCK_RGBA);
}
MEM_freeN(data);
diff --git a/source/blender/render/CMakeLists.txt b/source/blender/render/CMakeLists.txt
index a1dd9b3d5b0..f49c68a258d 100644
--- a/source/blender/render/CMakeLists.txt
+++ b/source/blender/render/CMakeLists.txt
@@ -108,4 +108,6 @@ if(APPLE)
endif()
endif()
+add_definitions(${GL_DEFINITIONS})
+
blender_add_lib_nolist(bf_render "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/render/extern/include/RE_bake.h b/source/blender/render/extern/include/RE_bake.h
index 372defbe8db..3bab9179f84 100644
--- a/source/blender/render/extern/include/RE_bake.h
+++ b/source/blender/render/extern/include/RE_bake.h
@@ -67,7 +67,7 @@ bool RE_bake_engine(struct Render *re,
struct Object *object,
const int object_id,
const BakePixel pixel_array[],
- const size_t num_pixels,
+ const BakeImages *bake_images,
const int depth,
const eScenePassType pass_type,
const int pass_filter,
@@ -84,6 +84,7 @@ bool RE_bake_pixels_populate_from_objects(struct Mesh *me_low,
const size_t num_pixels,
const bool is_custom_cage,
const float cage_extrusion,
+ const float max_ray_distance,
float mat_low[4][4],
float mat_cage[4][4],
struct Mesh *me_cage);
diff --git a/source/blender/render/extern/include/RE_engine.h b/source/blender/render/extern/include/RE_engine.h
index fd55a2a01df..77a60854616 100644
--- a/source/blender/render/extern/include/RE_engine.h
+++ b/source/blender/render/extern/include/RE_engine.h
@@ -68,7 +68,6 @@ struct bNodeTree;
#define RE_ENGINE_DO_UPDATE 8
#define RE_ENGINE_RENDERING 16
#define RE_ENGINE_HIGHLIGHT_TILES 32
-#define RE_ENGINE_USED_FOR_VIEWPORT 64
extern ListBase R_engines;
@@ -87,11 +86,8 @@ typedef struct RenderEngineType {
struct Object *object,
const int pass_type,
const int pass_filter,
- const int object_id,
- const struct BakePixel *pixel_array,
- const int num_pixels,
- const int depth,
- void *result);
+ const int width,
+ const int height);
void (*view_update)(struct RenderEngine *engine,
const struct bContext *context,
@@ -140,6 +136,13 @@ typedef struct RenderEngine {
struct ReportList *reports;
+ struct {
+ const struct BakePixel *pixels;
+ float *result;
+ int width, height, depth;
+ int object_id;
+ } bake;
+
/* Depsgraph */
struct Depsgraph *depsgraph;
@@ -155,7 +158,6 @@ typedef struct RenderEngine {
} RenderEngine;
RenderEngine *RE_engine_create(RenderEngineType *type);
-RenderEngine *RE_engine_create_ex(RenderEngineType *type, bool use_for_viewport);
void RE_engine_free(RenderEngine *engine);
void RE_layer_load_from_file(
diff --git a/source/blender/render/intern/include/render_result.h b/source/blender/render/intern/include/render_result.h
index fabbd5fb096..0ed8871b224 100644
--- a/source/blender/render/intern/include/render_result.h
+++ b/source/blender/render/intern/include/render_result.h
@@ -84,11 +84,12 @@ void render_result_exr_file_begin(struct Render *re, struct RenderEngine *engine
void render_result_exr_file_end(struct Render *re, struct RenderEngine *engine);
/* render pass wrapper for gpencil */
-struct RenderPass *gp_add_pass(struct RenderResult *rr,
- struct RenderLayer *rl,
- int channels,
- const char *name,
- const char *viewname);
+struct RenderPass *render_layer_add_pass(struct RenderResult *rr,
+ struct RenderLayer *rl,
+ int channels,
+ const char *name,
+ const char *viewname,
+ const char *chanid);
void render_result_exr_file_merge(struct RenderResult *rr,
struct RenderResult *rrpart,
diff --git a/source/blender/render/intern/source/bake_api.c b/source/blender/render/intern/source/bake_api.c
index e823a481d59..06f77854595 100644
--- a/source/blender/render/intern/source/bake_api.c
+++ b/source/blender/render/intern/source/bake_api.c
@@ -321,11 +321,16 @@ static bool cast_ray_highpoly(BVHTreeFromMesh *treeData,
const float co[3],
const float dir[3],
const int pixel_id,
- const int tot_highpoly)
+ const int tot_highpoly,
+ const float max_ray_distance)
{
int i;
int hit_mesh = -1;
- float hit_distance = FLT_MAX;
+ float hit_distance = max_ray_distance;
+ if (hit_distance == 0.0f) {
+ /* No ray distance set, use maximum. */
+ hit_distance = FLT_MAX;
+ }
BVHTreeRayHit *hits;
hits = MEM_mallocN(sizeof(BVHTreeRayHit) * tot_highpoly, "Bake Highpoly to Lowpoly: BVH Rays");
@@ -520,6 +525,7 @@ bool RE_bake_pixels_populate_from_objects(struct Mesh *me_low,
const size_t num_pixels,
const bool is_custom_cage,
const float cage_extrusion,
+ const float max_ray_distance,
float mat_low[4][4],
float mat_cage[4][4],
struct Mesh *me_cage)
@@ -623,7 +629,8 @@ bool RE_bake_pixels_populate_from_objects(struct Mesh *me_low,
co,
dir,
i,
- tot_highpoly)) {
+ tot_highpoly,
+ max_ray_distance)) {
/* if it fails mask out the original pixel array */
pixel_array_from[i].primitive_id = -1;
}
diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c
index 4770e98bd20..cc685610886 100644
--- a/source/blender/render/intern/source/external_engine.c
+++ b/source/blender/render/intern/source/external_engine.c
@@ -31,6 +31,7 @@
#include "BLI_ghash.h"
#include "BLI_listbase.h"
+#include "BLI_math_bits.h"
#include "BLI_rect.h"
#include "BLI_string.h"
#include "BLI_utildefines.h"
@@ -131,20 +132,9 @@ bool RE_engine_is_opengl(RenderEngineType *render_type)
RenderEngine *RE_engine_create(RenderEngineType *type)
{
- return RE_engine_create_ex(type, false);
-}
-
-RenderEngine *RE_engine_create_ex(RenderEngineType *type, bool use_for_viewport)
-{
RenderEngine *engine = MEM_callocN(sizeof(RenderEngine), "RenderEngine");
engine->type = type;
- if (use_for_viewport) {
- engine->flag |= RE_ENGINE_USED_FOR_VIEWPORT;
-
- BLI_threaded_malloc_begin();
- }
-
BLI_mutex_init(&engine->update_render_passes_mutex);
return engine;
@@ -158,15 +148,94 @@ void RE_engine_free(RenderEngine *engine)
}
#endif
- if (engine->flag & RE_ENGINE_USED_FOR_VIEWPORT) {
- BLI_threaded_malloc_end();
- }
-
BLI_mutex_end(&engine->update_render_passes_mutex);
MEM_freeN(engine);
}
+/* Bake Render Results */
+
+static RenderResult *render_result_from_bake(RenderEngine *engine, int x, int y, int w, int h)
+{
+ /* Create render result with specified size. */
+ RenderResult *rr = MEM_callocN(sizeof(RenderResult), __func__);
+
+ rr->rectx = w;
+ rr->recty = h;
+ rr->tilerect.xmin = x;
+ rr->tilerect.ymin = y;
+ rr->tilerect.xmax = x + w;
+ rr->tilerect.ymax = y + h;
+
+ /* Add single baking render layer. */
+ RenderLayer *rl = MEM_callocN(sizeof(RenderLayer), "bake render layer");
+ rl->rectx = w;
+ rl->recty = h;
+ BLI_addtail(&rr->layers, rl);
+
+ /* Add render passes. */
+ render_layer_add_pass(rr, rl, engine->bake.depth, RE_PASSNAME_COMBINED, "", "RGBA");
+ RenderPass *primitive_pass = render_layer_add_pass(rr, rl, 4, "BakePrimitive", "", "RGBA");
+ RenderPass *differential_pass = render_layer_add_pass(rr, rl, 4, "BakeDifferential", "", "RGBA");
+
+ /* Fill render passes from bake pixel array, to be read by the render engine. */
+ for (int ty = 0; ty < h; ty++) {
+ size_t offset = ty * w * 4;
+ float *primitive = primitive_pass->rect + offset;
+ float *differential = differential_pass->rect + offset;
+
+ size_t bake_offset = (y + ty) * engine->bake.width + x;
+ const BakePixel *bake_pixel = engine->bake.pixels + bake_offset;
+
+ for (int tx = 0; tx < w; tx++) {
+ if (bake_pixel->object_id != engine->bake.object_id) {
+ primitive[0] = int_as_float(-1);
+ primitive[1] = int_as_float(-1);
+ }
+ else {
+ primitive[0] = int_as_float(bake_pixel->object_id);
+ primitive[1] = int_as_float(bake_pixel->primitive_id);
+ primitive[2] = bake_pixel->uv[0];
+ primitive[3] = bake_pixel->uv[1];
+
+ differential[0] = bake_pixel->du_dx;
+ differential[1] = bake_pixel->du_dy;
+ differential[2] = bake_pixel->dv_dx;
+ differential[3] = bake_pixel->dv_dy;
+ }
+
+ primitive += 4;
+ differential += 4;
+ bake_pixel++;
+ }
+ }
+
+ return rr;
+}
+
+static void render_result_to_bake(RenderEngine *engine, RenderResult *rr)
+{
+ RenderPass *rpass = RE_pass_find_by_name(rr->layers.first, RE_PASSNAME_COMBINED, "");
+
+ if (!rpass) {
+ return;
+ }
+
+ /* Copy from tile render result to full image bake result. */
+ int x = rr->tilerect.xmin;
+ int y = rr->tilerect.ymin;
+ int w = rr->tilerect.xmax - rr->tilerect.xmin;
+ int h = rr->tilerect.ymax - rr->tilerect.ymin;
+
+ for (int ty = 0; ty < h; ty++) {
+ size_t offset = ty * w * engine->bake.depth;
+ size_t bake_offset = ((y + ty) * engine->bake.width + x) * engine->bake.depth;
+ size_t size = w * engine->bake.depth * sizeof(float);
+
+ memcpy(engine->bake.result + bake_offset, rpass->rect + offset, size);
+ }
+}
+
/* Render Results */
static RenderPart *get_part_from_result(Render *re, RenderResult *result)
@@ -180,6 +249,12 @@ static RenderPart *get_part_from_result(Render *re, RenderResult *result)
RenderResult *RE_engine_begin_result(
RenderEngine *engine, int x, int y, int w, int h, const char *layername, const char *viewname)
{
+ if (engine->bake.pixels) {
+ RenderResult *result = render_result_from_bake(engine, x, y, w, h);
+ BLI_addtail(&engine->fullresult, result);
+ return result;
+ }
+
Render *re = engine->re;
RenderResult *result;
rcti disprect;
@@ -237,6 +312,11 @@ RenderResult *RE_engine_begin_result(
void RE_engine_update_result(RenderEngine *engine, RenderResult *result)
{
+ if (engine->bake.pixels) {
+ /* No interactive baking updates for now. */
+ return;
+ }
+
Render *re = engine->re;
if (result) {
@@ -270,6 +350,13 @@ void RE_engine_end_result(
return;
}
+ if (engine->bake.pixels) {
+ render_result_to_bake(engine, result);
+ BLI_remlink(&engine->fullresult, result);
+ render_result_free(result);
+ return;
+ }
+
/* merge. on break, don't merge in result for preview renders, looks nicer */
if (!highlight) {
/* for exr tile render, detect tiles that are done */
@@ -574,7 +661,7 @@ bool RE_bake_engine(Render *re,
Object *object,
const int object_id,
const BakePixel pixel_array[],
- const size_t num_pixels,
+ const BakeImages *bake_images,
const int depth,
const eScenePassType pass_type,
const int pass_filter,
@@ -619,16 +706,21 @@ bool RE_bake_engine(Render *re,
type->update(engine, re->main, engine->depsgraph);
}
- type->bake(engine,
- engine->depsgraph,
- object,
- pass_type,
- pass_filter,
- object_id,
- pixel_array,
- num_pixels,
- depth,
- result);
+ for (int i = 0; i < bake_images->size; i++) {
+ const BakeImage *image = bake_images->data + i;
+
+ engine->bake.pixels = pixel_array + image->offset;
+ engine->bake.result = result + image->offset * depth;
+ engine->bake.width = image->width;
+ engine->bake.height = image->height;
+ engine->bake.depth = depth;
+ engine->bake.object_id = object_id;
+
+ type->bake(
+ engine, engine->depsgraph, object, pass_type, pass_filter, image->width, image->height);
+
+ memset(&engine->bake, 0, sizeof(engine->bake));
+ }
engine->depsgraph = NULL;
}
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index 4a910d9e12c..e0c59596c2a 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -187,23 +187,20 @@ static int default_break(void *UNUSED(arg))
static void stats_background(void *UNUSED(arg), RenderStats *rs)
{
- uintptr_t mem_in_use, mmap_in_use, peak_memory;
- float megs_used_memory, mmap_used_memory, megs_peak_memory;
+ uintptr_t mem_in_use, peak_memory;
+ float megs_used_memory, megs_peak_memory;
char info_time_str[32];
mem_in_use = MEM_get_memory_in_use();
- mmap_in_use = MEM_get_mapped_memory_in_use();
peak_memory = MEM_get_peak_memory();
- megs_used_memory = (mem_in_use - mmap_in_use) / (1024.0 * 1024.0);
- mmap_used_memory = (mmap_in_use) / (1024.0 * 1024.0);
+ megs_used_memory = (mem_in_use) / (1024.0 * 1024.0);
megs_peak_memory = (peak_memory) / (1024.0 * 1024.0);
fprintf(stdout,
- TIP_("Fra:%d Mem:%.2fM (%.2fM, Peak %.2fM) "),
+ TIP_("Fra:%d Mem:%.2fM (Peak %.2fM) "),
rs->cfra,
megs_used_memory,
- mmap_used_memory,
megs_peak_memory);
if (rs->curfield) {
@@ -2955,5 +2952,5 @@ RenderPass *RE_create_gp_pass(RenderResult *rr, const char *layername, const cha
BLI_freelinkN(&rl->passes, rp);
}
/* create a totally new pass */
- return gp_add_pass(rr, rl, 4, RE_PASSNAME_COMBINED, viewname);
+ return render_layer_add_pass(rr, rl, 4, RE_PASSNAME_COMBINED, viewname, "RGBA");
}
diff --git a/source/blender/render/intern/source/render_result.c b/source/blender/render/intern/source/render_result.c
index b38c1b573f3..4b74bfb3e5c 100644
--- a/source/blender/render/intern/source/render_result.c
+++ b/source/blender/render/intern/source/render_result.c
@@ -213,12 +213,12 @@ static void set_pass_full_name(
/********************************** New **************************************/
-static RenderPass *render_layer_add_pass(RenderResult *rr,
- RenderLayer *rl,
- int channels,
- const char *name,
- const char *viewname,
- const char *chan_id)
+RenderPass *render_layer_add_pass(RenderResult *rr,
+ RenderLayer *rl,
+ int channels,
+ const char *name,
+ const char *viewname,
+ const char *chan_id)
{
const int view_id = BLI_findstringindex(&rr->views, viewname, offsetof(RenderView, name));
RenderPass *rpass = MEM_callocN(sizeof(RenderPass), name);
@@ -255,7 +255,7 @@ static RenderPass *render_layer_add_pass(RenderResult *rr,
float *rect;
int x;
- rpass->rect = MEM_mapallocN(sizeof(float) * rectsize, name);
+ rpass->rect = MEM_callocN(sizeof(float) * rectsize, name);
if (rpass->rect == NULL) {
MEM_freeN(rpass);
return NULL;
@@ -280,12 +280,6 @@ static RenderPass *render_layer_add_pass(RenderResult *rr,
return rpass;
}
-/* wrapper called from render_opengl */
-RenderPass *gp_add_pass(
- RenderResult *rr, RenderLayer *rl, int channels, const char *name, const char *viewname)
-{
- return render_layer_add_pass(rr, rl, channels, name, viewname, "RGBA");
-}
/* called by main render as well for parts */
/* will read info from Render *re to define layers */
diff --git a/source/blender/windowmanager/CMakeLists.txt b/source/blender/windowmanager/CMakeLists.txt
index 22fd55cd49a..7c749c60168 100644
--- a/source/blender/windowmanager/CMakeLists.txt
+++ b/source/blender/windowmanager/CMakeLists.txt
@@ -168,10 +168,6 @@ if(WITH_BUILDINFO)
add_definitions(-DWITH_BUILDINFO)
endif()
-if(WITH_OPENSUBDIV)
- add_definitions(-DWITH_OPENSUBDIV)
-endif()
-
if(WITH_INPUT_NDOF)
add_definitions(-DWITH_INPUT_NDOF)
endif()
diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c
index 54e6735175d..9aaaa0e2c81 100644
--- a/source/blender/windowmanager/intern/wm.c
+++ b/source/blender/windowmanager/intern/wm.c
@@ -44,8 +44,10 @@
#include "BKE_idprop.h"
#include "BKE_idtype.h"
#include "BKE_lib_id.h"
+#include "BKE_lib_query.h"
#include "BKE_main.h"
#include "BKE_report.h"
+#include "BKE_screen.h"
#include "BKE_workspace.h"
#include "WM_api.h"
@@ -73,6 +75,28 @@ static void window_manager_free_data(ID *id)
wm_close_and_free(NULL, (wmWindowManager *)id);
}
+static void window_manager_foreach_id(ID *id, LibraryForeachIDData *data)
+{
+ wmWindowManager *wm = (wmWindowManager *)id;
+
+ LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
+ BKE_LIB_FOREACHID_PROCESS(data, win->scene, IDWALK_CB_USER_ONE);
+
+ /* This pointer can be NULL during old files reading, better be safe than sorry. */
+ if (win->workspace_hook != NULL) {
+ ID *workspace = (ID *)BKE_workspace_active_get(win->workspace_hook);
+ BKE_LIB_FOREACHID_PROCESS_ID(data, workspace, IDWALK_CB_NOP);
+ /* allow callback to set a different workspace */
+ BKE_workspace_active_set(win->workspace_hook, (WorkSpace *)workspace);
+ }
+ if (BKE_lib_query_foreachid_process_flags_get(data) & IDWALK_INCLUDE_UI) {
+ LISTBASE_FOREACH (ScrArea *, area, &win->global_areas.areabase) {
+ BKE_screen_foreach_id_screen_area(data, area);
+ }
+ }
+ }
+}
+
IDTypeInfo IDType_ID_WM = {
.id_code = ID_WM,
.id_filter = 0,
@@ -87,6 +111,7 @@ IDTypeInfo IDType_ID_WM = {
.copy_data = NULL,
.free_data = window_manager_free_data,
.make_local = NULL,
+ .foreach_id = window_manager_foreach_id,
};
#define MAX_OP_REGISTERED 32
@@ -359,7 +384,7 @@ void wm_add_default(Main *bmain, bContext *C)
WorkSpaceLayout *layout = BKE_workspace_layout_find_global(bmain, screen, &workspace);
CTX_wm_manager_set(C, wm);
- win = wm_window_new(bmain, wm, NULL);
+ win = wm_window_new(bmain, wm, NULL, false);
win->scene = CTX_data_scene(C);
STRNCPY(win->view_layer_name, CTX_data_view_layer(C)->name);
BKE_workspace_active_set(win->workspace_hook, workspace);
diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c
index a01ab1377c1..4cc9f4ee7d1 100644
--- a/source/blender/windowmanager/intern/wm_draw.c
+++ b/source/blender/windowmanager/intern/wm_draw.c
@@ -848,6 +848,7 @@ static void wm_draw_window(bContext *C, wmWindow *win)
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, GPU_texture_opengl_bindcode(texture));
+ wmWindowViewport(win);
if (win->stereo3d_format->display_mode == S3D_DISPLAY_SIDEBYSIDE) {
wm_stereo3d_draw_sidebyside(win, view);
}
@@ -982,10 +983,6 @@ void wm_draw_update(bContext *C)
wmWindowManager *wm = CTX_wm_manager(C);
wmWindow *win;
-#ifdef WITH_OPENSUBDIV
- BKE_subsurf_free_unused_buffers();
-#endif
-
GPU_free_unused_buffers(bmain);
for (win = wm->windows.first; win; win = win->next) {
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 61c99d72695..c7bda0bdae0 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -563,7 +563,7 @@ void wm_event_do_notifiers(bContext *C)
static int wm_event_always_pass(const wmEvent *event)
{
/* some events we always pass on, to ensure proper communication */
- return ISTIMER(event->type) || (event->type == WINDEACTIVATE);
+ return ISTIMER(event->type) || (event->type == WINDEACTIVATE) || (event->type == EVT_FILESELECT);
}
/** \} */
@@ -640,11 +640,11 @@ static int wm_handler_ui_call(bContext *C,
return WM_HANDLER_CONTINUE;
}
-static void wm_handler_ui_cancel(bContext *C)
+void wm_event_handler_ui_cancel_ex(bContext *C,
+ wmWindow *win,
+ ARegion *region,
+ bool reactivate_button)
{
- wmWindow *win = CTX_wm_window(C);
- ARegion *region = CTX_wm_region(C);
-
if (!region) {
return;
}
@@ -656,11 +656,19 @@ static void wm_handler_ui_cancel(bContext *C)
wmEvent event;
wm_event_init_from_window(win, &event);
event.type = EVT_BUT_CANCEL;
+ event.val = reactivate_button ? 0 : 1;
handler->handle_fn(C, &event, handler->user_data);
}
}
}
+static void wm_event_handler_ui_cancel(bContext *C)
+{
+ wmWindow *win = CTX_wm_window(C);
+ ARegion *region = CTX_wm_region(C);
+ wm_event_handler_ui_cancel_ex(C, win, region, true);
+}
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -1365,7 +1373,7 @@ static int wm_operator_invoke(bContext *C,
* while dragging the view or worse, that stay there permanently
* after the modal operator has swallowed all events and passed
* none to the UI handler */
- wm_handler_ui_cancel(C);
+ wm_event_handler_ui_cancel(C);
}
else {
WM_operator_free(op);
@@ -2661,6 +2669,12 @@ static int wm_handlers_do_gizmo_handler(bContext *C,
return action;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Handle Single Event (All Handler Types)
+ * \{ */
+
static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers)
{
const bool do_debug_handler =
@@ -2962,6 +2976,14 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers)
return action;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Event Queue Utilities
+ *
+ * Utilities used by #wm_event_do_handlers.
+ * \{ */
+
static bool wm_event_inside_rect(const wmEvent *event, const rcti *rect)
{
if (wm_event_always_pass(event)) {
@@ -3126,6 +3148,14 @@ static void wm_event_free_and_remove_from_queue_if_valid(wmEvent *event)
}
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Main Event Queue (Every Window)
+ *
+ * Handle events for all windows, run from the #WM_main event loop.
+ * \{ */
+
/* called in main loop */
/* goes over entire hierarchy: events -> window -> screen -> area -> region */
void wm_event_do_handlers(bContext *C)
@@ -3434,19 +3464,13 @@ void WM_event_add_fileselect(bContext *C, wmOperator *op)
wmWindowManager *wm = CTX_wm_manager(C);
wmWindow *win = CTX_wm_window(C);
const bool is_temp_screen = WM_window_is_temp_screen(win);
- const bool opens_window = (U.filebrowser_display_type == USER_TEMP_SPACE_DISPLAY_WINDOW);
- /* Don't add the file handler to the temporary window if one is opened, or else it owns the
- * handlers for itself, causing dangling pointers once it's destructed through a handler. It has
- * a parent which should hold the handlers itself. */
- ListBase *modalhandlers = (is_temp_screen && opens_window) ? &win->parent->modalhandlers :
- &win->modalhandlers;
/* Close any popups, like when opening a file browser from the splash. */
- UI_popup_handlers_remove_all(C, modalhandlers);
+ UI_popup_handlers_remove_all(C, &win->modalhandlers);
if (!is_temp_screen) {
/* only allow 1 file selector open per window */
- LISTBASE_FOREACH_MUTABLE (wmEventHandler *, handler_base, modalhandlers) {
+ LISTBASE_FOREACH_MUTABLE (wmEventHandler *, handler_base, &win->modalhandlers) {
if (handler_base->type == WM_HANDLER_TYPE_OP) {
wmEventHandler_Op *handler = (wmEventHandler_Op *)handler_base;
if (handler->is_fileselect == false) {
@@ -3487,7 +3511,7 @@ void WM_event_add_fileselect(bContext *C, wmOperator *op)
handler->context.area = CTX_wm_area(C);
handler->context.region = CTX_wm_region(C);
- BLI_addhead(modalhandlers, handler);
+ BLI_addhead(&win->modalhandlers, handler);
/* check props once before invoking if check is available
* ensures initial properties are valid */
diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c
index b9f0e3686db..cc81e4f2715 100644
--- a/source/blender/windowmanager/intern/wm_files.c
+++ b/source/blender/windowmanager/intern/wm_files.c
@@ -1212,6 +1212,7 @@ static ImBuf *blend_file_thumb(const bContext *C,
ImBuf *ibuf;
BlendThumbnail *thumb;
wmWindowManager *wm = CTX_wm_manager(C);
+ const float pixelsize_old = U.pixelsize;
wmWindow *windrawable_old = wm->windrawable;
char err_out[256] = "unknown";
@@ -1246,6 +1247,10 @@ static ImBuf *blend_file_thumb(const bContext *C,
/* gets scaled to BLEN_THUMB_SIZE */
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
+ /* Note that with scaling, this ends up being 0.5,
+ * as it's a thumbnail, we don't need object centers and friends to be 1:1 size. */
+ U.pixelsize = 1.0f;
+
if (scene->camera) {
ibuf = ED_view3d_draw_offscreen_imbuf_simple(depsgraph,
scene,
@@ -1276,6 +1281,8 @@ static ImBuf *blend_file_thumb(const bContext *C,
err_out);
}
+ U.pixelsize = pixelsize_old;
+
/* Reset to old drawable. */
if (windrawable_old) {
wm_window_make_drawable(wm, windrawable_old);
diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c
index a93d4c7bf37..fc3f0c87b69 100644
--- a/source/blender/windowmanager/intern/wm_init_exit.c
+++ b/source/blender/windowmanager/intern/wm_init_exit.c
@@ -125,6 +125,8 @@
#include "GPU_material.h"
#include "BKE_sound.h"
+#include "BKE_subdiv.h"
+
#include "COM_compositor.h"
#include "DEG_depsgraph.h"
@@ -132,10 +134,6 @@
#include "DRW_engine.h"
-#ifdef WITH_OPENSUBDIV
-# include "BKE_subsurf.h"
-#endif
-
CLG_LOGREF_DECLARE_GLOBAL(WM_LOG_OPERATORS, "wm.operator");
CLG_LOGREF_DECLARE_GLOBAL(WM_LOG_HANDLERS, "wm.handler");
CLG_LOGREF_DECLARE_GLOBAL(WM_LOG_EVENTS, "wm.event");
@@ -193,9 +191,8 @@ void WM_init_opengl(Main *bmain)
GPU_pass_cache_init();
-#ifdef WITH_OPENSUBDIV
- BKE_subsurf_osd_init();
-#endif
+ BKE_subdiv_init();
+
opengl_is_init = true;
}
@@ -576,11 +573,9 @@ void WM_exit_ex(bContext *C, const bool do_python)
COM_deinitialize();
#endif
- if (opengl_is_init) {
-#ifdef WITH_OPENSUBDIV
- BKE_subsurf_osd_cleanup();
-#endif
+ BKE_subdiv_exit();
+ if (opengl_is_init) {
GPU_free_unused_buffers(G_MAIN);
}
diff --git a/source/blender/windowmanager/intern/wm_splash_screen.c b/source/blender/windowmanager/intern/wm_splash_screen.c
index 8445fac0498..c821f5bfe89 100644
--- a/source/blender/windowmanager/intern/wm_splash_screen.c
+++ b/source/blender/windowmanager/intern/wm_splash_screen.c
@@ -129,6 +129,7 @@ static void get_version_string(char *ver, const int max_length)
version_cycle_number);
}
+#ifndef WITH_HEADLESS
static void wm_block_splash_image_roundcorners_add(ImBuf *ibuf)
{
uchar *rct = (uchar *)ibuf->rect;
@@ -179,6 +180,7 @@ static void wm_block_splash_image_roundcorners_add(ImBuf *ibuf)
}
}
}
+#endif /* WITH_HEADLESS */
static ImBuf *wm_block_splash_image(int width, int *r_height)
{
@@ -219,6 +221,7 @@ static ImBuf *wm_block_splash_image(int width, int *r_height)
return ibuf;
#else
+ UNUSED_VARS(width, r_height);
return NULL;
#endif
}
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index 70601ae5e42..fcb2be0a0bb 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -286,14 +286,15 @@ static int find_free_winid(wmWindowManager *wm)
}
/* don't change context itself */
-wmWindow *wm_window_new(const Main *bmain, wmWindowManager *wm, wmWindow *parent)
+wmWindow *wm_window_new(const Main *bmain, wmWindowManager *wm, wmWindow *parent, bool dialog)
{
wmWindow *win = MEM_callocN(sizeof(wmWindow), "window");
BLI_addtail(&wm->windows, win);
win->winid = find_free_winid(wm);
- win->parent = (parent && parent->parent) ? parent->parent : parent;
+ /* Dialogs may have a child window as parent. Otherwise, a child must not be a parent too. */
+ win->parent = (!dialog && parent && parent->parent) ? parent->parent : parent;
win->stereo3d_format = MEM_callocN(sizeof(Stereo3dFormat), "Stereo 3D Format (window)");
win->workspace_hook = BKE_workspace_instance_hook_create(bmain);
@@ -307,8 +308,9 @@ wmWindow *wm_window_copy(Main *bmain,
const bool duplicate_layout,
const bool child)
{
+ const bool is_dialog = GHOST_IsDialogWindow(win_src->ghostwin);
wmWindow *win_parent = (child) ? win_src : win_src->parent;
- wmWindow *win_dst = wm_window_new(bmain, wm, win_parent);
+ wmWindow *win_dst = wm_window_new(bmain, wm, win_parent, is_dialog);
WorkSpace *workspace = WM_window_get_active_workspace(win_src);
WorkSpaceLayout *layout_old = WM_window_get_active_layout(win_src);
WorkSpaceLayout *layout_new;
@@ -417,7 +419,6 @@ void wm_quit_with_optional_confirmation_prompt(bContext *C, wmWindow *win)
void wm_window_close(bContext *C, wmWindowManager *wm, wmWindow *win)
{
wmWindow *win_other;
- const bool is_dialog = (G.background == false) ? GHOST_IsDialogWindow(win->ghostwin) : false;
/* First check if there is another main window remaining. */
for (win_other = wm->windows.first; win_other; win_other = win_other->next) {
@@ -431,20 +432,11 @@ void wm_window_close(bContext *C, wmWindowManager *wm, wmWindow *win)
return;
}
- /* Close child windows and bring windows back to front that dialogs have pushed behind the main
- * window. */
- LISTBASE_FOREACH (wmWindow *, iter_win, &wm->windows) {
+ /* Close child windows */
+ LISTBASE_FOREACH_MUTABLE (wmWindow *, iter_win, &wm->windows) {
if (iter_win->parent == win) {
wm_window_close(C, wm, iter_win);
}
- else {
- if (G.background == false) {
- if (is_dialog && iter_win != win && iter_win->parent &&
- (GHOST_GetWindowState(iter_win->ghostwin) != GHOST_kWindowStateMinimized)) {
- wm_window_raise(iter_win);
- }
- }
- }
}
bScreen *screen = WM_window_get_active_screen(win);
@@ -834,7 +826,7 @@ wmWindow *WM_window_open(bContext *C, const rcti *rect)
{
wmWindowManager *wm = CTX_wm_manager(C);
wmWindow *win_prev = CTX_wm_window(C);
- wmWindow *win = wm_window_new(CTX_data_main(C), wm, win_prev);
+ wmWindow *win = wm_window_new(CTX_data_main(C), wm, win_prev, false);
win->posx = rect->xmin;
win->posy = rect->ymin;
@@ -905,7 +897,7 @@ wmWindow *WM_window_open_temp(bContext *C,
/* add new window? */
if (win == NULL) {
- win = wm_window_new(bmain, wm, win_prev);
+ win = wm_window_new(bmain, wm, win_prev, dialog);
win->posx = rect.xmin;
win->posy = rect.ymin;
diff --git a/source/blender/windowmanager/wm_event_system.h b/source/blender/windowmanager/wm_event_system.h
index ffa5baae9f1..efcf40d03eb 100644
--- a/source/blender/windowmanager/wm_event_system.h
+++ b/source/blender/windowmanager/wm_event_system.h
@@ -149,6 +149,11 @@ void wm_event_do_depsgraph(bContext *C, bool is_after_open_file);
void wm_event_do_refresh_wm_and_depsgraph(bContext *C);
void wm_event_do_notifiers(bContext *C);
+void wm_event_handler_ui_cancel_ex(bContext *C,
+ wmWindow *win,
+ ARegion *region,
+ bool reactivate_button);
+
/* wm_event_query.c */
float wm_pressure_curve(float raw_pressure);
void wm_tablet_data_from_ghost(const struct GHOST_TabletData *tablet_data, wmTabletData *wmtab);
diff --git a/source/blender/windowmanager/wm_event_types.h b/source/blender/windowmanager/wm_event_types.h
index f16056cc91e..ffed86abfe7 100644
--- a/source/blender/windowmanager/wm_event_types.h
+++ b/source/blender/windowmanager/wm_event_types.h
@@ -333,6 +333,7 @@ enum {
EVT_BUT_OPEN = 0x5021, /* 20513 */
EVT_MODAL_MAP = 0x5022, /* 20514 */
EVT_DROP = 0x5023, /* 20515 */
+ /* When value is 0, re-activate, when 1, don't re-activate the button under the cursor. */
EVT_BUT_CANCEL = 0x5024, /* 20516 */
/* could become gizmo callback */
diff --git a/source/blender/windowmanager/wm_window.h b/source/blender/windowmanager/wm_window.h
index 45cfe1431d7..5ca5711b4f2 100644
--- a/source/blender/windowmanager/wm_window.h
+++ b/source/blender/windowmanager/wm_window.h
@@ -33,7 +33,10 @@ void wm_ghost_exit(void);
void wm_get_screensize(int *r_width, int *r_height);
void wm_get_desktopsize(int *r_width, int *r_height);
-wmWindow *wm_window_new(const struct Main *bmain, wmWindowManager *wm, wmWindow *parent);
+wmWindow *wm_window_new(const struct Main *bmain,
+ wmWindowManager *wm,
+ wmWindow *parent,
+ bool dialog);
wmWindow *wm_window_copy(struct Main *bmain,
wmWindowManager *wm,
wmWindow *win_src,
diff --git a/source/blender/windowmanager/xr/intern/wm_xr.c b/source/blender/windowmanager/xr/intern/wm_xr.c
index 69c9034d51f..90f30809136 100644
--- a/source/blender/windowmanager/xr/intern/wm_xr.c
+++ b/source/blender/windowmanager/xr/intern/wm_xr.c
@@ -126,7 +126,12 @@ void wm_xr_exit(wmWindowManager *wm)
bool wm_xr_events_handle(wmWindowManager *wm)
{
if (wm->xr.runtime && wm->xr.runtime->context) {
- return GHOST_XrEventsHandle(wm->xr.runtime->context);
+ GHOST_XrEventsHandle(wm->xr.runtime->context);
+
+ /* wm_window_process_events() uses the return value to determine if it can put the main thread
+ * to sleep for some milliseconds. We never want that to happen while the VR session runs on
+ * the main thread. So always return true. */
+ return true;
}
return false;
}
diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt
index b3e83b1412f..1a71022869a 100644
--- a/source/creator/CMakeLists.txt
+++ b/source/creator/CMakeLists.txt
@@ -687,6 +687,13 @@ elseif(WIN32)
)
endif()
+ if(WITH_FFTW3)
+ install(
+ FILES ${LIBDIR}/fftw3/lib/libfftw3-3.dll
+ DESTINATION "."
+ )
+ endif()
+
if(WITH_WINDOWS_PDB)
if(WITH_WINDOWS_STRIPPED_PDB)
# Icky hack for older cmake from https://stackoverflow.com/a/21198501
diff --git a/source/creator/creator_args.c b/source/creator/creator_args.c
index bd56d86784e..7acf649c3ab 100644
--- a/source/creator/creator_args.c
+++ b/source/creator/creator_args.c
@@ -959,7 +959,7 @@ static const char arg_handle_debug_mode_generic_set_doc_jobs[] =
"Enable time profiling for background jobs.";
static const char arg_handle_debug_mode_generic_set_doc_gpu[] =
"\n\t"
- "Enable gpu debug context and information for OpenGL 4.3+.";
+ "Enable GPU debug context and information for OpenGL 4.3+.";
static const char arg_handle_debug_mode_generic_set_doc_depsgraph[] =
"\n\t"
"Enable all debug messages from dependency graph.";
@@ -995,7 +995,7 @@ static int arg_handle_debug_mode_generic_set(int UNUSED(argc),
static const char arg_handle_debug_mode_io_doc[] =
"\n\t"
- "Enable debug messages for I/O (collada, ...).";
+ "Enable debug messages for I/O (Collada, ...).";
static int arg_handle_debug_mode_io(int UNUSED(argc),
const char **UNUSED(argv),
void *UNUSED(data))
@@ -1124,7 +1124,7 @@ static int arg_handle_factory_startup_set(int UNUSED(argc),
static const char arg_handle_disable_override_library_doc[] =
"\n\t"
- "Enable Library Override features in the UI.";
+ "Disable Library Override features in the UI.";
static int arg_handle_disable_override_library(int UNUSED(argc),
const char **UNUSED(argv),
void *UNUSED(data))
@@ -1497,7 +1497,7 @@ static int arg_handle_threads_set(int argc, const char **argv, void *UNUSED(data
static const char arg_handle_verbosity_set_doc[] =
"<verbose>\n"
- "\tSet logging verbosity level for debug messages which supports it.";
+ "\tSet the logging verbosity level for debug messages that support it.";
static int arg_handle_verbosity_set(int argc, const char **argv, void *UNUSED(data))
{
const char *arg_id = "--verbose";
@@ -1592,7 +1592,6 @@ static int arg_handle_render_frame(int argc, const char **argv, void *data)
}
re = RE_NewSceneRender(scene);
- BLI_threaded_malloc_begin();
BKE_reports_init(&reports, RPT_STORE);
RE_SetReports(re, &reports);
for (int i = 0; i < frames_range_len; i++) {
@@ -1608,7 +1607,6 @@ static int arg_handle_render_frame(int argc, const char **argv, void *data)
}
RE_SetReports(re, NULL);
BKE_reports_clear(&reports);
- BLI_threaded_malloc_end();
MEM_freeN(frame_range_arr);
return 1;
}
@@ -1634,13 +1632,11 @@ static int arg_handle_render_animation(int UNUSED(argc), const char **UNUSED(arg
Main *bmain = CTX_data_main(C);
Render *re = RE_NewSceneRender(scene);
ReportList reports;
- BLI_threaded_malloc_begin();
BKE_reports_init(&reports, RPT_STORE);
RE_SetReports(re, &reports);
RE_RenderAnim(re, bmain, scene, NULL, NULL, scene->r.sfra, scene->r.efra, scene->r.frame_step);
RE_SetReports(re, NULL);
BKE_reports_clear(&reports);
- BLI_threaded_malloc_end();
}
else {
printf("\nError: no blend loaded. cannot use '-a'.\n");
diff --git a/tests/gtests/blenlib/BLI_linklist_lockfree_test.cc b/tests/gtests/blenlib/BLI_linklist_lockfree_test.cc
index 023d02e5075..d1a527d57ac 100644
--- a/tests/gtests/blenlib/BLI_linklist_lockfree_test.cc
+++ b/tests/gtests/blenlib/BLI_linklist_lockfree_test.cc
@@ -87,9 +87,7 @@ TEST(LockfreeLinkList, InsertMultipleConcurrent)
BLI_task_pool_push(pool, concurrent_insert, POINTER_FROM_INT(i), false, NULL);
}
/* Run all the tasks. */
- BLI_threaded_malloc_begin();
BLI_task_pool_work_and_wait(pool);
- BLI_threaded_malloc_end();
/* Verify we've got all the data properly inserted. */
EXPECT_EQ(list.head, &list.dummy_node);
bool *visited_nodes = (bool *)MEM_callocN(sizeof(bool) * num_nodes, "visited nodes");
diff --git a/tests/gtests/blenlib/BLI_type_construct_mock.hh b/tests/gtests/blenlib/BLI_type_construct_mock.hh
new file mode 100644
index 00000000000..72767631608
--- /dev/null
+++ b/tests/gtests/blenlib/BLI_type_construct_mock.hh
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ */
+
+#ifndef __ANY_TYPE_MOCK_TEST_H__
+#define __ANY_TYPE_MOCK_TEST_H__
+
+#include "BLI_sys_types.h"
+
+class TypeConstructMock {
+ public:
+ bool default_constructed = false;
+ bool copy_constructed = false;
+ bool move_constructed = false;
+ bool copy_assigned = false;
+ bool move_assigned = false;
+
+ TypeConstructMock() : default_constructed(true)
+ {
+ }
+
+ TypeConstructMock(const TypeConstructMock &other) : copy_constructed(true)
+ {
+ }
+
+ TypeConstructMock(TypeConstructMock &&other) : move_constructed(true)
+ {
+ }
+
+ TypeConstructMock &operator=(const TypeConstructMock &other)
+ {
+ if (this == &other) {
+ return *this;
+ }
+
+ copy_assigned = true;
+ return *this;
+ }
+
+ TypeConstructMock &operator=(TypeConstructMock &&other)
+ {
+ if (this == &other) {
+ return *this;
+ }
+
+ move_assigned = true;
+ return *this;
+ }
+};
+
+#endif /* __ANY_TYPE_MOCK_TEST_H__ */
diff --git a/tests/gtests/blenlib/BLI_vector_test.cc b/tests/gtests/blenlib/BLI_vector_test.cc
index e5a1ca2b200..90180feba1f 100644
--- a/tests/gtests/blenlib/BLI_vector_test.cc
+++ b/tests/gtests/blenlib/BLI_vector_test.cc
@@ -1,19 +1,19 @@
+#include "BLI_type_construct_mock.hh"
#include "BLI_vector.hh"
#include "testing/testing.h"
#include <forward_list>
using BLI::Vector;
-using IntVector = Vector<int>;
TEST(vector, DefaultConstructor)
{
- IntVector vec;
+ Vector<int> vec;
EXPECT_EQ(vec.size(), 0);
}
TEST(vector, SizeConstructor)
{
- IntVector vec(3);
+ Vector<int> vec(3);
EXPECT_EQ(vec.size(), 3);
EXPECT_EQ(vec[0], 0);
EXPECT_EQ(vec[1], 0);
@@ -22,7 +22,7 @@ TEST(vector, SizeConstructor)
TEST(vector, SizeValueConstructor)
{
- IntVector vec(4, 10);
+ Vector<int> vec(4, 10);
EXPECT_EQ(vec.size(), 4);
EXPECT_EQ(vec[0], 10);
EXPECT_EQ(vec[1], 10);
@@ -32,7 +32,7 @@ TEST(vector, SizeValueConstructor)
TEST(vector, InitializerListConstructor)
{
- IntVector vec = {1, 3, 4, 6};
+ Vector<int> vec = {1, 3, 4, 6};
EXPECT_EQ(vec.size(), 4);
EXPECT_EQ(vec[0], 1);
EXPECT_EQ(vec[1], 3);
@@ -74,7 +74,7 @@ TEST(vector, ContainerConstructor)
list.push_front(1);
list.push_front(5);
- IntVector vec = IntVector::FromContainer(list);
+ Vector<int> vec = Vector<int>::FromContainer(list);
EXPECT_EQ(vec.size(), 3);
EXPECT_EQ(vec[0], 5);
EXPECT_EQ(vec[1], 1);
@@ -83,8 +83,8 @@ TEST(vector, ContainerConstructor)
TEST(vector, CopyConstructor)
{
- IntVector vec1 = {1, 2, 3};
- IntVector vec2(vec1);
+ Vector<int> vec1 = {1, 2, 3};
+ Vector<int> vec2(vec1);
EXPECT_EQ(vec2.size(), 3);
EXPECT_EQ(vec2[0], 1);
EXPECT_EQ(vec2[1], 2);
@@ -133,8 +133,8 @@ TEST(vector, CopyConstructor4)
TEST(vector, MoveConstructor)
{
- IntVector vec1 = {1, 2, 3, 4};
- IntVector vec2(std::move(vec1));
+ Vector<int> vec1 = {1, 2, 3, 4};
+ Vector<int> vec2(std::move(vec1));
EXPECT_EQ(vec1.size(), 0);
EXPECT_EQ(vec2.size(), 4);
@@ -179,20 +179,20 @@ TEST(vector, MoveConstructor4)
TEST(vector, MoveAssignment)
{
- IntVector vec = {1, 2};
+ Vector<int> vec = {1, 2};
EXPECT_EQ(vec.size(), 2);
EXPECT_EQ(vec[0], 1);
EXPECT_EQ(vec[1], 2);
- vec = IntVector({5});
+ vec = Vector<int>({5});
EXPECT_EQ(vec.size(), 1);
EXPECT_EQ(vec[0], 5);
}
TEST(vector, CopyAssignment)
{
- IntVector vec1 = {1, 2, 3};
- IntVector vec2 = {4, 5};
+ Vector<int> vec1 = {1, 2, 3};
+ Vector<int> vec2 = {4, 5};
EXPECT_EQ(vec1.size(), 3);
EXPECT_EQ(vec2.size(), 2);
@@ -206,7 +206,7 @@ TEST(vector, CopyAssignment)
TEST(vector, Append)
{
- IntVector vec;
+ Vector<int> vec;
vec.append(3);
vec.append(6);
vec.append(7);
@@ -218,7 +218,7 @@ TEST(vector, Append)
TEST(vector, AppendAndGetIndex)
{
- IntVector vec;
+ Vector<int> vec;
EXPECT_EQ(vec.append_and_get_index(10), 0);
EXPECT_EQ(vec.append_and_get_index(10), 1);
EXPECT_EQ(vec.append_and_get_index(10), 2);
@@ -228,7 +228,7 @@ TEST(vector, AppendAndGetIndex)
TEST(vector, AppendNonDuplicates)
{
- IntVector vec;
+ Vector<int> vec;
vec.append_non_duplicates(4);
EXPECT_EQ(vec.size(), 1);
vec.append_non_duplicates(5);
@@ -239,7 +239,7 @@ TEST(vector, AppendNonDuplicates)
TEST(vector, ExtendNonDuplicates)
{
- IntVector vec;
+ Vector<int> vec;
vec.extend_non_duplicates({1, 2});
EXPECT_EQ(vec.size(), 2);
vec.extend_non_duplicates({3, 4});
@@ -250,7 +250,7 @@ TEST(vector, ExtendNonDuplicates)
TEST(vector, Fill)
{
- IntVector vec(5);
+ Vector<int> vec(5);
vec.fill(3);
EXPECT_EQ(vec.size(), 5);
EXPECT_EQ(vec[0], 3);
@@ -262,7 +262,7 @@ TEST(vector, Fill)
TEST(vector, FillIndices)
{
- IntVector vec(5, 0);
+ Vector<int> vec(5, 0);
vec.fill_indices({1, 2}, 4);
EXPECT_EQ(vec[0], 0);
EXPECT_EQ(vec[1], 4);
@@ -273,7 +273,7 @@ TEST(vector, FillIndices)
TEST(vector, Iterator)
{
- IntVector vec({1, 4, 9, 16});
+ Vector<int> vec({1, 4, 9, 16});
int i = 1;
for (int value : vec) {
EXPECT_EQ(value, i * i);
@@ -293,14 +293,14 @@ TEST(vector, BecomeLarge)
}
}
-static IntVector return_by_value_helper()
+static Vector<int> return_by_value_helper()
{
- return IntVector({3, 5, 1});
+ return Vector<int>({3, 5, 1});
}
TEST(vector, ReturnByValue)
{
- IntVector vec = return_by_value_helper();
+ Vector<int> vec = return_by_value_helper();
EXPECT_EQ(vec.size(), 3);
EXPECT_EQ(vec[0], 3);
EXPECT_EQ(vec[1], 5);
@@ -309,10 +309,10 @@ TEST(vector, ReturnByValue)
TEST(vector, VectorOfVectors_Append)
{
- Vector<IntVector> vec;
+ Vector<Vector<int>> vec;
EXPECT_EQ(vec.size(), 0);
- IntVector v({1, 2});
+ Vector<int> v({1, 2});
vec.append(v);
vec.append({7, 8});
EXPECT_EQ(vec.size(), 2);
@@ -324,7 +324,7 @@ TEST(vector, VectorOfVectors_Append)
TEST(vector, VectorOfVectors_Fill)
{
- Vector<IntVector> vec(3);
+ Vector<Vector<int>> vec(3);
vec.fill({4, 5});
EXPECT_EQ(vec[0][0], 4);
@@ -337,7 +337,7 @@ TEST(vector, VectorOfVectors_Fill)
TEST(vector, RemoveLast)
{
- IntVector vec = {5, 6};
+ Vector<int> vec = {5, 6};
EXPECT_EQ(vec.size(), 2);
vec.remove_last();
EXPECT_EQ(vec.size(), 1);
@@ -347,7 +347,7 @@ TEST(vector, RemoveLast)
TEST(vector, IsEmpty)
{
- IntVector vec;
+ Vector<int> vec;
EXPECT_TRUE(vec.is_empty());
vec.append(1);
EXPECT_FALSE(vec.is_empty());
@@ -357,7 +357,7 @@ TEST(vector, IsEmpty)
TEST(vector, RemoveReorder)
{
- IntVector vec = {4, 5, 6, 7};
+ Vector<int> vec = {4, 5, 6, 7};
vec.remove_and_reorder(1);
EXPECT_EQ(vec[0], 4);
EXPECT_EQ(vec[1], 7);
@@ -373,7 +373,7 @@ TEST(vector, RemoveReorder)
TEST(vector, RemoveFirstOccurrenceAndReorder)
{
- IntVector vec = {4, 5, 6, 7};
+ Vector<int> vec = {4, 5, 6, 7};
vec.remove_first_occurrence_and_reorder(5);
EXPECT_EQ(vec[0], 4);
EXPECT_EQ(vec[1], 7);
@@ -389,24 +389,24 @@ TEST(vector, RemoveFirstOccurrenceAndReorder)
TEST(vector, AllEqual_False)
{
- IntVector a = {1, 2, 3};
- IntVector b = {1, 2, 4};
- bool result = IntVector::all_equal(a, b);
+ Vector<int> a = {1, 2, 3};
+ Vector<int> b = {1, 2, 4};
+ bool result = Vector<int>::all_equal(a, b);
EXPECT_FALSE(result);
}
TEST(vector, AllEqual_True)
{
- IntVector a = {4, 5, 6};
- IntVector b = {4, 5, 6};
- bool result = IntVector::all_equal(a, b);
+ Vector<int> a = {4, 5, 6};
+ Vector<int> b = {4, 5, 6};
+ bool result = Vector<int>::all_equal(a, b);
EXPECT_TRUE(result);
}
TEST(vector, ExtendSmallVector)
{
- IntVector a = {2, 3, 4};
- IntVector b = {11, 12};
+ Vector<int> a = {2, 3, 4};
+ Vector<int> b = {11, 12};
b.extend(a);
EXPECT_EQ(b.size(), 5);
EXPECT_EQ(b[0], 11);
@@ -420,7 +420,7 @@ TEST(vector, ExtendArray)
{
int array[] = {3, 4, 5, 6};
- IntVector a;
+ Vector<int> a;
a.extend(array, 2);
EXPECT_EQ(a.size(), 2);
@@ -430,13 +430,13 @@ TEST(vector, ExtendArray)
TEST(vector, Last)
{
- IntVector a{3, 5, 7};
+ Vector<int> a{3, 5, 7};
EXPECT_EQ(a.last(), 7);
}
TEST(vector, AppendNTimes)
{
- IntVector a;
+ Vector<int> a;
a.append_n_times(5, 3);
a.append_n_times(2, 2);
EXPECT_EQ(a.size(), 5);
@@ -460,3 +460,68 @@ TEST(vector, UniquePtrValue)
UNUSED_VARS(a, b);
}
+
+TEST(vector, SizeConstructorCallsDefaultConstructor)
+{
+ Vector<TypeConstructMock> vec(3);
+ EXPECT_TRUE(vec[0].default_constructed);
+ EXPECT_TRUE(vec[1].default_constructed);
+ EXPECT_TRUE(vec[2].default_constructed);
+}
+
+TEST(vector, SizeValueConstructorCallsCopyConstructor)
+{
+ Vector<TypeConstructMock> vec(3, TypeConstructMock());
+ EXPECT_TRUE(vec[0].copy_constructed);
+ EXPECT_TRUE(vec[1].copy_constructed);
+ EXPECT_TRUE(vec[2].copy_constructed);
+}
+
+TEST(vector, AppendCallsCopyConstructor)
+{
+ Vector<TypeConstructMock> vec;
+ TypeConstructMock value;
+ vec.append(value);
+ EXPECT_TRUE(vec[0].copy_constructed);
+}
+
+TEST(vector, AppendCallsMoveConstructor)
+{
+ Vector<TypeConstructMock> vec;
+ vec.append(TypeConstructMock());
+ EXPECT_TRUE(vec[0].move_constructed);
+}
+
+TEST(vector, SmallVectorCopyCallsCopyConstructor)
+{
+ Vector<TypeConstructMock, 2> src(2);
+ Vector<TypeConstructMock, 2> dst(src);
+ EXPECT_TRUE(dst[0].copy_constructed);
+ EXPECT_TRUE(dst[1].copy_constructed);
+}
+
+TEST(vector, LargeVectorCopyCallsCopyConstructor)
+{
+ Vector<TypeConstructMock, 2> src(5);
+ Vector<TypeConstructMock, 2> dst(src);
+ EXPECT_TRUE(dst[0].copy_constructed);
+ EXPECT_TRUE(dst[1].copy_constructed);
+}
+
+TEST(vector, SmallVectorMoveCallsMoveConstructor)
+{
+ Vector<TypeConstructMock, 2> src(2);
+ Vector<TypeConstructMock, 2> dst(std::move(src));
+ EXPECT_TRUE(dst[0].move_constructed);
+ EXPECT_TRUE(dst[1].move_constructed);
+}
+
+TEST(vector, LargeVectorMoveCallsNoConstructor)
+{
+ Vector<TypeConstructMock, 2> src(5);
+ Vector<TypeConstructMock, 2> dst(std::move(src));
+
+ EXPECT_TRUE(dst[0].default_constructed);
+ EXPECT_FALSE(dst[0].move_constructed);
+ EXPECT_FALSE(dst[0].copy_constructed);
+}