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
path: root/source
diff options
context:
space:
mode:
authorJacques Lucke <jacques@blender.org>2020-03-31 10:40:01 +0300
committerJacques Lucke <jacques@blender.org>2020-03-31 10:40:01 +0300
commitebecd0aae5757646c56631840d7c68886ef748fa (patch)
tree44a044edd523f2b15098595a34c322664e67c911 /source
parent118a9f8589e8be8a8052b727f3ca3ebd2a7c4eb3 (diff)
parent24f8c8491d8255b3d10d5fa6fcadf8c7f336076c (diff)
Merge branch 'master' into simulation-data-block
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenfont/BLF_api.h8
-rw-r--r--source/blender/blenfont/CMakeLists.txt2
-rw-r--r--source/blender/blenfont/intern/blf_font_default.c59
-rw-r--r--source/blender/blenfont/intern/blf_font_i18n.c113
-rw-r--r--source/blender/blenkernel/BKE_armature.h2
-rw-r--r--source/blender/blenkernel/BKE_colorband.h2
-rw-r--r--source/blender/blenkernel/BKE_image.h10
-rw-r--r--source/blender/blenkernel/BKE_layer.h11
-rw-r--r--source/blender/blenkernel/BKE_mask.h6
-rw-r--r--source/blender/blenkernel/BKE_modifier.h5
-rw-r--r--source/blender/blenkernel/BKE_multires.h3
-rw-r--r--source/blender/blenkernel/BKE_sequencer.h13
-rw-r--r--source/blender/blenkernel/BKE_sound.h4
-rw-r--r--source/blender/blenkernel/BKE_subdiv.h2
-rw-r--r--source/blender/blenkernel/BKE_subdiv_ccg.h5
-rw-r--r--source/blender/blenkernel/BKE_subdiv_deform.h4
-rw-r--r--source/blender/blenkernel/BKE_subdiv_eval.h4
-rw-r--r--source/blender/blenkernel/BKE_subdiv_foreach.h4
-rw-r--r--source/blender/blenkernel/BKE_texture.h2
-rw-r--r--source/blender/blenkernel/intern/blender_undo.c3
-rw-r--r--source/blender/blenkernel/intern/brush.c3
-rw-r--r--source/blender/blenkernel/intern/constraint.c8
-rw-r--r--source/blender/blenkernel/intern/displist_tangent.c2
-rw-r--r--source/blender/blenkernel/intern/fluid.c26
-rw-r--r--source/blender/blenkernel/intern/gpencil.c6
-rw-r--r--source/blender/blenkernel/intern/gpencil_geom.c2
-rw-r--r--source/blender/blenkernel/intern/image.c50
-rw-r--r--source/blender/blenkernel/intern/key.c2
-rw-r--r--source/blender/blenkernel/intern/layer.c59
-rw-r--r--source/blender/blenkernel/intern/mask.c24
-rw-r--r--source/blender/blenkernel/intern/material.c1
-rw-r--r--source/blender/blenkernel/intern/mesh_convert.c2
-rw-r--r--source/blender/blenkernel/intern/multires.c1
-rw-r--r--source/blender/blenkernel/intern/multires_reshape_vertcos.c3
-rw-r--r--source/blender/blenkernel/intern/multires_subdiv.c6
-rw-r--r--source/blender/blenkernel/intern/scene.c2
-rw-r--r--source/blender/blenkernel/intern/seqcache.c22
-rw-r--r--source/blender/blenkernel/intern/seqeffects.c15
-rw-r--r--source/blender/blenkernel/intern/sound.c8
-rw-r--r--source/blender/blenkernel/intern/subdiv_foreach.c7
-rw-r--r--source/blender/blenkernel/intern/subdiv_mesh.c7
-rw-r--r--source/blender/blenkernel/intern/tracking_region_tracker.c16
-rw-r--r--source/blender/blenkernel/intern/undo_system.c4
-rw-r--r--source/blender/blenkernel/intern/volume.cc4
-rw-r--r--source/blender/blenlib/BLI_fileops.h1
-rw-r--r--source/blender/blenlib/BLI_voronoi_2d.h8
-rw-r--r--source/blender/blenlib/CMakeLists.txt7
-rw-r--r--source/blender/blenlib/intern/storage.c32
-rw-r--r--source/blender/blenlib/intern/storage_apple.mm96
-rw-r--r--source/blender/blenlib/intern/voronoi_2d.c16
-rw-r--r--source/blender/blenloader/BLO_undofile.h1
-rw-r--r--source/blender/blenloader/intern/undofile.c8
-rw-r--r--source/blender/blenloader/intern/versioning_280.c16
-rw-r--r--source/blender/blenloader/intern/versioning_defaults.c8
-rw-r--r--source/blender/blenloader/intern/writefile.c9
-rw-r--r--source/blender/bmesh/operators/bmo_fill_grid.c9
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.cc2
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_scene.cc4
-rw-r--r--source/blender/draw/engines/eevee/eevee_bloom.c4
-rw-r--r--source/blender/draw/engines/eevee/eevee_materials.c293
-rw-r--r--source/blender/draw/engines/eevee/eevee_render.c3
-rw-r--r--source/blender/draw/engines/eevee/shaders/shadow_vert.glsl29
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_cache_utils.c6
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_engine.c3
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_render.c3
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_common_lib.glsl11
-rw-r--r--source/blender/draw/engines/overlay/overlay_antialiasing.c52
-rw-r--r--source/blender/draw/engines/overlay/overlay_engine.c2
-rw-r--r--source/blender/draw/engines/overlay/overlay_image.c2
-rw-r--r--source/blender/draw/engines/overlay/overlay_outline.c16
-rw-r--r--source/blender/draw/engines/overlay/overlay_paint.c61
-rw-r--r--source/blender/draw/engines/overlay/overlay_private.h8
-rw-r--r--source/blender/draw/engines/overlay/overlay_shader.c19
-rw-r--r--source/blender/draw/engines/overlay/overlay_wireframe.c8
-rw-r--r--source/blender/draw/engines/overlay/shaders/edit_gpencil_vert.glsl10
-rw-r--r--source/blender/draw/engines/overlay/shaders/edit_mesh_common_lib.glsl4
-rw-r--r--source/blender/draw/engines/overlay/shaders/edit_mesh_normal_vert.glsl2
-rw-r--r--source/blender/draw/engines/overlay/shaders/edit_mesh_vert.glsl8
-rw-r--r--source/blender/draw/engines/overlay/shaders/wireframe_frag.glsl30
-rw-r--r--source/blender/draw/engines/overlay/shaders/wireframe_vert.glsl9
-rw-r--r--source/blender/draw/engines/workbench/workbench_effect_antialiasing.c22
-rw-r--r--source/blender/draw/engines/workbench/workbench_effect_dof.c2
-rw-r--r--source/blender/draw/engines/workbench/workbench_materials.c2
-rw-r--r--source/blender/draw/engines/workbench/workbench_render.c4
-rw-r--r--source/blender/draw/intern/draw_cache_extract_mesh.c67
-rw-r--r--source/blender/draw/intern/draw_cache_impl_displist.c8
-rw-r--r--source/blender/draw/intern/draw_cache_impl_gpencil.c12
-rw-r--r--source/blender/draw/intern/draw_cache_impl_mesh.c33
-rw-r--r--source/blender/draw/intern/draw_hair.c4
-rw-r--r--source/blender/draw/intern/draw_manager_data.c5
-rw-r--r--source/blender/draw/intern/shaders/common_smaa_lib.glsl15
-rw-r--r--source/blender/editors/animation/anim_draw.c55
-rw-r--r--source/blender/editors/animation/anim_markers.c13
-rw-r--r--source/blender/editors/armature/armature_add.c6
-rw-r--r--source/blender/editors/armature/armature_edit.c266
-rw-r--r--source/blender/editors/armature/armature_intern.h2
-rw-r--r--source/blender/editors/armature/armature_ops.c2
-rw-r--r--source/blender/editors/armature/armature_relations.c2
-rw-r--r--source/blender/editors/armature/armature_select.c317
-rw-r--r--source/blender/editors/armature/armature_utils.c6
-rw-r--r--source/blender/editors/armature/pose_select.c2
-rw-r--r--source/blender/editors/datafiles/CMakeLists.txt2
-rw-r--r--source/blender/editors/gpencil/annotate_draw.c53
-rw-r--r--source/blender/editors/gpencil/annotate_paint.c5
-rw-r--r--source/blender/editors/gpencil/drawgpencil.c534
-rw-r--r--source/blender/editors/gpencil/gpencil_convert.c26
-rw-r--r--source/blender/editors/gpencil/gpencil_data.c9
-rw-r--r--source/blender/editors/gpencil/gpencil_edit.c9
-rw-r--r--source/blender/editors/gpencil/gpencil_fill.c4
-rw-r--r--source/blender/editors/gpencil/gpencil_intern.h4
-rw-r--r--source/blender/editors/gpencil/gpencil_ops_versioning.c1
-rw-r--r--source/blender/editors/gpencil/gpencil_paint.c55
-rw-r--r--source/blender/editors/gpencil/gpencil_primitive.c17
-rw-r--r--source/blender/editors/gpencil/gpencil_sculpt_paint.c3
-rw-r--r--source/blender/editors/gpencil/gpencil_select.c16
-rw-r--r--source/blender/editors/gpencil/gpencil_utils.c15
-rw-r--r--source/blender/editors/gpencil/gpencil_uv.c3
-rw-r--r--source/blender/editors/gpencil/gpencil_vertex_paint.c3
-rw-r--r--source/blender/editors/gpencil/gpencil_weight_paint.c3
-rw-r--r--source/blender/editors/include/ED_datafiles.h6
-rw-r--r--source/blender/editors/include/ED_gpencil.h1
-rw-r--r--source/blender/editors/include/ED_image.h19
-rw-r--r--source/blender/editors/include/ED_mask.h13
-rw-r--r--source/blender/editors/include/ED_uvedit.h2
-rw-r--r--source/blender/editors/include/ED_view3d.h8
-rw-r--r--source/blender/editors/include/UI_interface.h2
-rw-r--r--source/blender/editors/interface/interface_eyedropper.c8
-rw-r--r--source/blender/editors/interface/interface_handlers.c27
-rw-r--r--source/blender/editors/interface/interface_layout.c2
-rw-r--r--source/blender/editors/interface/interface_ops.c4
-rw-r--r--source/blender/editors/interface/interface_style.c53
-rw-r--r--source/blender/editors/interface/interface_widgets.c7
-rw-r--r--source/blender/editors/interface/view2d.c4
-rw-r--r--source/blender/editors/interface/view2d_ops.c42
-rw-r--r--source/blender/editors/mask/CMakeLists.txt1
-rw-r--r--source/blender/editors/mask/mask_add.c153
-rw-r--r--source/blender/editors/mask/mask_draw.c2
-rw-r--r--source/blender/editors/mask/mask_edit.c358
-rw-r--r--source/blender/editors/mask/mask_intern.h65
-rw-r--r--source/blender/editors/mask/mask_ops.c305
-rw-r--r--source/blender/editors/mask/mask_query.c833
-rw-r--r--source/blender/editors/mask/mask_select.c1
-rw-r--r--source/blender/editors/mesh/editface.c6
-rw-r--r--source/blender/editors/mesh/editmesh_bevel.c4
-rw-r--r--source/blender/editors/mesh/editmesh_extrude.c52
-rw-r--r--source/blender/editors/mesh/editmesh_knife.c4
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c128
-rw-r--r--source/blender/editors/object/object_constraint.c152
-rw-r--r--source/blender/editors/object/object_modifier.c137
-rw-r--r--source/blender/editors/object/object_relations.c91
-rw-r--r--source/blender/editors/render/render_shading.c23
-rw-r--r--source/blender/editors/screen/screen_edit.c2
-rw-r--r--source/blender/editors/screen/screen_ops.c10
-rw-r--r--source/blender/editors/sculpt_paint/paint_hide.c3
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_2d.c7
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_proj.c8
-rw-r--r--source/blender/editors/sculpt_paint/paint_ops.c8
-rw-r--r--source/blender/editors/sculpt_paint/paint_stroke.c4
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c901
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_cloth.c14
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_intern.h35
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_pose.c286
-rw-r--r--source/blender/editors/space_clip/clip_intern.h2
-rw-r--r--source/blender/editors/space_clip/clip_ops.c8
-rw-r--r--source/blender/editors/space_clip/space_clip.c2
-rw-r--r--source/blender/editors/space_clip/tracking_ops.c14
-rw-r--r--source/blender/editors/space_clip/tracking_ops_plane.c6
-rw-r--r--source/blender/editors/space_clip/tracking_ops_track.c4
-rw-r--r--source/blender/editors/space_clip/tracking_select.c38
-rw-r--r--source/blender/editors/space_file/file_intern.h8
-rw-r--r--source/blender/editors/space_file/file_ops.c301
-rw-r--r--source/blender/editors/space_file/filelist.c35
-rw-r--r--source/blender/editors/space_file/filelist.h2
-rw-r--r--source/blender/editors/space_file/space_file.c2
-rw-r--r--source/blender/editors/space_image/image_edit.c79
-rw-r--r--source/blender/editors/space_image/image_ops.c16
-rw-r--r--source/blender/editors/space_image/image_undo.c2
-rw-r--r--source/blender/editors/space_image/space_image.c2
-rw-r--r--source/blender/editors/space_info/textview.c17
-rw-r--r--source/blender/editors/space_node/node_edit.c14
-rw-r--r--source/blender/editors/space_node/node_intern.h2
-rw-r--r--source/blender/editors/space_node/space_node.c4
-rw-r--r--source/blender/editors/space_outliner/outliner_collections.c105
-rw-r--r--source/blender/editors/space_outliner/outliner_dragdrop.c22
-rw-r--r--source/blender/editors/space_sequencer/sequencer_draw.c200
-rw-r--r--source/blender/editors/space_sequencer/sequencer_edit.c28
-rw-r--r--source/blender/editors/space_sequencer/sequencer_intern.h8
-rw-r--r--source/blender/editors/space_sequencer/space_sequencer.c13
-rw-r--r--source/blender/editors/space_text/space_text.c4
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c18
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c18
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c16
-rw-r--r--source/blender/editors/space_view3d/view3d_fly.c4
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c4
-rw-r--r--source/blender/editors/space_view3d/view3d_walk.c4
-rw-r--r--source/blender/editors/transform/transform.c4
-rw-r--r--source/blender/editors/transform/transform_convert.c320
-rw-r--r--source/blender/editors/transform/transform_convert_armature.c9
-rw-r--r--source/blender/editors/transform/transform_convert_sequencer.c68
-rw-r--r--source/blender/editors/transform/transform_gizmo_2d.c6
-rw-r--r--source/blender/editors/transform/transform_input.c96
-rw-r--r--source/blender/editors/transform/transform_mode.c14
-rw-r--r--source/blender/editors/transform/transform_ops.c2
-rw-r--r--source/blender/editors/util/numinput.c30
-rw-r--r--source/blender/editors/uvedit/uvedit_draw.c8
-rw-r--r--source/blender/editors/uvedit/uvedit_parametrizer.c155
-rw-r--r--source/blender/editors/uvedit/uvedit_unwrap_ops.c172
-rw-r--r--source/blender/freestyle/FRS_freestyle.h4
-rw-r--r--source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp65
-rw-r--r--source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp14
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c6
-rw-r--r--source/blender/gpu/CMakeLists.txt7
-rw-r--r--source/blender/gpu/GPU_buffers.h2
-rw-r--r--source/blender/gpu/GPU_shader.h27
-rw-r--r--source/blender/gpu/GPU_shader_interface.h2
-rw-r--r--source/blender/gpu/intern/gpu_batch.c39
-rw-r--r--source/blender/gpu/intern/gpu_buffers.c84
-rw-r--r--source/blender/gpu/intern/gpu_shader.c100
-rw-r--r--source/blender/gpu/intern/gpu_shader_interface.c3
-rw-r--r--source/blender/gpu/intern/gpu_texture.c256
-rw-r--r--source/blender/gpu/shaders/gpu_shader_2D_smooth_color_dithered_frag.glsl18
-rw-r--r--source/blender/gpu/shaders/gpu_shader_3D_normal_smooth_color_vert.glsl22
-rw-r--r--source/blender/gpu/shaders/gpu_shader_image_depth_copy_frag.glsl12
-rw-r--r--source/blender/gpu/shaders/gpu_shader_image_depth_linear_frag.glsl16
-rw-r--r--source/blender/gpu/shaders/gpu_shader_image_multisample_resolve_frag.glsl119
-rw-r--r--source/blender/gpu/shaders/gpu_shader_simple_lighting_smooth_color_alpha_frag.glsl14
-rw-r--r--source/blender/gpu/shaders/gpu_shader_simple_lighting_smooth_color_frag.glsl16
-rw-r--r--source/blender/gpu/shaders/gpu_shader_uniform_color_frag.glsl4
-rw-r--r--source/blender/imbuf/IMB_colormanagement.h4
-rw-r--r--source/blender/imbuf/IMB_moviecache.h2
-rw-r--r--source/blender/imbuf/intern/colormanagement.c10
-rw-r--r--source/blender/imbuf/intern/moviecache.c14
-rw-r--r--source/blender/io/usd/intern/abstract_hierarchy_iterator.h2
-rw-r--r--source/blender/makesdna/DNA_brush_types.h19
-rw-r--r--source/blender/makesdna/DNA_gpencil_types.h4
-rw-r--r--source/blender/makesdna/DNA_material_types.h2
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h15
-rw-r--r--source/blender/makesdna/DNA_scene_types.h3
-rw-r--r--source/blender/makesdna/DNA_sound_types.h11
-rw-r--r--source/blender/makesdna/DNA_space_types.h3
-rw-r--r--source/blender/makesrna/intern/rna_action.c6
-rw-r--r--source/blender/makesrna/intern/rna_animation.c6
-rw-r--r--source/blender/makesrna/intern/rna_brush.c69
-rw-r--r--source/blender/makesrna/intern/rna_gpencil.c4
-rw-r--r--source/blender/makesrna/intern/rna_gpencil_modifier.c12
-rw-r--r--source/blender/makesrna/intern/rna_image.c6
-rw-r--r--source/blender/makesrna/intern/rna_material.c7
-rw-r--r--source/blender/makesrna/intern/rna_modifier.c85
-rw-r--r--source/blender/makesrna/intern/rna_object.c19
-rw-r--r--source/blender/makesrna/intern/rna_scene.c16
-rw-r--r--source/blender/makesrna/intern/rna_space.c16
-rw-r--r--source/blender/makesrna/intern/rna_wm_api.c25
-rw-r--r--source/blender/modifiers/intern/MOD_armature.c2
-rw-r--r--source/blender/modifiers/intern/MOD_cast.c2
-rw-r--r--source/blender/modifiers/intern/MOD_collision.c2
-rw-r--r--source/blender/modifiers/intern/MOD_correctivesmooth.c4
-rw-r--r--source/blender/modifiers/intern/MOD_multires.c12
-rw-r--r--source/blender/modifiers/intern/MOD_particlesystem.c2
-rw-r--r--source/blender/modifiers/intern/MOD_screw.c9
-rw-r--r--source/blender/modifiers/intern/MOD_solidify.c15
-rw-r--r--source/blender/modifiers/intern/MOD_solidify_extrude.c33
-rw-r--r--source/blender/modifiers/intern/MOD_solidify_nonmanifold.c51
-rw-r--r--source/blender/modifiers/intern/MOD_subsurf.c5
-rw-r--r--source/blender/modifiers/intern/MOD_surfacedeform.c109
-rw-r--r--source/blender/modifiers/intern/MOD_warp.c41
-rw-r--r--source/blender/modifiers/intern/MOD_weightvg_util.c27
-rw-r--r--source/blender/modifiers/intern/MOD_weightvg_util.h8
-rw-r--r--source/blender/modifiers/intern/MOD_weightvgedit.c5
-rw-r--r--source/blender/modifiers/intern/MOD_weightvgproximity.c22
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_image.c6
-rw-r--r--source/blender/python/generic/py_capi_utils.c32
-rw-r--r--source/blender/python/generic/py_capi_utils.h4
-rw-r--r--source/blender/python/intern/bpy_app_translations.c32
-rw-r--r--source/blender/python/intern/bpy_rna.c68
-rw-r--r--source/blender/python/intern/bpy_rna_array.c12
-rw-r--r--source/blender/render/extern/include/RE_pipeline.h2
-rw-r--r--source/blender/render/intern/include/render_types.h5
-rw-r--r--source/blender/render/intern/source/initrender.c3
-rw-r--r--source/blender/render/intern/source/pipeline.c120
-rw-r--r--source/blender/windowmanager/WM_keymap.h8
-rw-r--r--source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c4
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c6
-rw-r--r--source/blender/windowmanager/intern/wm_files.c8
-rw-r--r--source/blender/windowmanager/intern/wm_files_link.c14
-rw-r--r--source/blender/windowmanager/intern/wm_init_exit.c6
-rw-r--r--source/blender/windowmanager/intern/wm_keymap.c10
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c16
-rw-r--r--source/blender/windowmanager/intern/wm_playanim.c3
-rw-r--r--source/blender/windowmanager/intern/wm_toolsystem.c2
-rw-r--r--source/blender/windowmanager/intern/wm_window.c12
-rw-r--r--source/blender/windowmanager/intern/wm_xr.c12
-rw-r--r--source/creator/CMakeLists.txt28
-rw-r--r--source/creator/blender.map82
-rw-r--r--source/creator/creator.c2
-rw-r--r--source/creator/creator_args.c2
-rw-r--r--source/creator/osx_locals.map64
m---------source/tools0
297 files changed, 6461 insertions, 4267 deletions
diff --git a/source/blender/blenfont/BLF_api.h b/source/blender/blenfont/BLF_api.h
index fd6411f7c69..9aee8c9b78b 100644
--- a/source/blender/blenfont/BLF_api.h
+++ b/source/blender/blenfont/BLF_api.h
@@ -238,11 +238,9 @@ void BLF_thumb_preview(const char *filename,
int h,
int channels) ATTR_NONNULL();
-/* blf_font_i18.c */
-unsigned char *BLF_get_unifont(int *unifont_size);
-void BLF_free_unifont(void);
-unsigned char *BLF_get_unifont_mono(int *unifont_size);
-void BLF_free_unifont_mono(void);
+/* blf_font_default.c */
+int BLF_load_default(const bool unique);
+int BLF_load_mono_default(const bool unique);
#ifdef DEBUG
void BLF_state_print(int fontid);
diff --git a/source/blender/blenfont/CMakeLists.txt b/source/blender/blenfont/CMakeLists.txt
index fa02d6d21c9..ac927dd388d 100644
--- a/source/blender/blenfont/CMakeLists.txt
+++ b/source/blender/blenfont/CMakeLists.txt
@@ -41,7 +41,7 @@ set(SRC
intern/blf.c
intern/blf_dir.c
intern/blf_font.c
- intern/blf_font_i18n.c
+ intern/blf_font_default.c
intern/blf_glyph.c
intern/blf_thumbs.c
intern/blf_util.c
diff --git a/source/blender/blenfont/intern/blf_font_default.c b/source/blender/blenfont/intern/blf_font_default.c
new file mode 100644
index 00000000000..f33d7cd4203
--- /dev/null
+++ b/source/blender/blenfont/intern/blf_font_default.c
@@ -0,0 +1,59 @@
+/*
+ * 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) 2011 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup blf
+ *
+ * API for loading default font files.
+ */
+
+#include <stdio.h>
+
+#include "BLF_api.h"
+
+#include "BLI_path_util.h"
+
+#include "BKE_appdir.h"
+
+static int blf_load_font_default(const char *filename, const bool unique)
+{
+ const char *dir = BKE_appdir_folder_id(BLENDER_DATAFILES, "fonts");
+ if (dir == NULL) {
+ fprintf(stderr,
+ "%s: 'fonts' data path not found for '%s', will not be able to display text\n",
+ __func__,
+ filename);
+ return -1;
+ }
+
+ char filepath[FILE_MAX];
+ BLI_join_dirfile(filepath, sizeof(filepath), dir, filename);
+
+ return (unique) ? BLF_load_unique(filepath) : BLF_load(filepath);
+}
+
+int BLF_load_default(const bool unique)
+{
+ return blf_load_font_default("droidsans.ttf", unique);
+}
+
+int BLF_load_mono_default(const bool unique)
+{
+ return blf_load_font_default("bmonofont-i18n.ttf", unique);
+}
diff --git a/source/blender/blenfont/intern/blf_font_i18n.c b/source/blender/blenfont/intern/blf_font_i18n.c
deleted file mode 100644
index 74113ae4ce1..00000000000
--- a/source/blender/blenfont/intern/blf_font_i18n.c
+++ /dev/null
@@ -1,113 +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) 2011 Blender Foundation.
- * All rights reserved.
- */
-
-/** \file
- * \ingroup blf
- *
- * API for accessing font files.
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "BLF_api.h"
-
-#include "MEM_guardedalloc.h"
-
-#include "BLI_utildefines.h"
-
-#include "BKE_appdir.h"
-
-#ifdef WITH_INTERNATIONAL
-
-# include "BLI_fileops.h"
-# include "BLI_string.h"
-
-struct FontBuf {
- const char *filename;
- uchar *data;
- int data_len;
-};
-
-static struct FontBuf unifont_ttf = {"droidsans.ttf.gz"};
-static struct FontBuf unifont_mono_ttf = {"bmonofont-i18n.ttf.gz"};
-
-static void fontbuf_load(struct FontBuf *fb)
-{
- const char *fontpath = BKE_appdir_folder_id(BLENDER_DATAFILES, "fonts");
- if (fontpath) {
- char unifont_path[1024];
- BLI_snprintf(unifont_path, sizeof(unifont_path), "%s/%s", fontpath, fb->filename);
- fb->data = (uchar *)BLI_file_ungzip_to_mem(unifont_path, &fb->data_len);
- }
- else {
- printf("%s: 'fonts' data path not found for '%s', continuing\n", __func__, fb->filename);
- }
-}
-
-static void fontbuf_free(struct FontBuf *fb)
-{
- MEM_SAFE_FREE(fb->data);
- fb->data_len = 0;
-}
-
-static uchar *fontbuf_get_mem(struct FontBuf *fb, int *r_size)
-{
- if (fb->data == NULL) {
- fontbuf_load(fb);
- }
- *r_size = fb->data_len;
- return fb->data;
-}
-
-#endif /* WITH_INTERNATIONAL */
-
-uchar *BLF_get_unifont(int *r_unifont_size)
-{
-#ifdef WITH_INTERNATIONAL
- return fontbuf_get_mem(&unifont_ttf, r_unifont_size);
-#else
- UNUSED_VARS(r_unifont_size);
- return NULL;
-#endif
-}
-
-uchar *BLF_get_unifont_mono(int *r_unifont_size)
-{
-#ifdef WITH_INTERNATIONAL
- return fontbuf_get_mem(&unifont_mono_ttf, r_unifont_size);
-#else
- UNUSED_VARS(r_unifont_size);
- return NULL;
-#endif
-}
-
-void BLF_free_unifont(void)
-{
-#ifdef WITH_INTERNATIONAL
- fontbuf_free(&unifont_ttf);
-#endif
-}
-
-void BLF_free_unifont_mono(void)
-{
-#ifdef WITH_INTERNATIONAL
- fontbuf_free(&unifont_mono_ttf);
-#endif
-}
diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h
index cd4733a4e62..6c383ae5011 100644
--- a/source/blender/blenkernel/BKE_armature.h
+++ b/source/blender/blenkernel/BKE_armature.h
@@ -61,7 +61,7 @@ typedef struct PoseTree {
int stretch; /* disable stretching */
} PoseTree;
-/* Core armature functionality */
+/* Core armature functionality. */
struct bArmature *BKE_armature_add(struct Main *bmain, const char *name);
struct bArmature *BKE_armature_from_object(struct Object *ob);
diff --git a/source/blender/blenkernel/BKE_colorband.h b/source/blender/blenkernel/BKE_colorband.h
index 6e03f4db3d2..355682671fe 100644
--- a/source/blender/blenkernel/BKE_colorband.h
+++ b/source/blender/blenkernel/BKE_colorband.h
@@ -29,7 +29,7 @@ extern "C" {
struct ColorBand;
-/* in ColorBand struct */
+/** #ColorBand.data length. */
#define MAXCOLORBAND 32
void BKE_colorband_init(struct ColorBand *coba, bool rangetype);
diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h
index 4ce740a1f5a..0d8b6efb4b1 100644
--- a/source/blender/blenkernel/BKE_image.h
+++ b/source/blender/blenkernel/BKE_image.h
@@ -322,12 +322,12 @@ struct ImageTile *BKE_image_get_tile_from_iuser(struct Image *ima, struct ImageU
int BKE_image_get_tile_from_pos(struct Image *ima,
const float uv[2],
- float new_uv[2],
- float ofs[2]);
+ float r_uv[2],
+ float r_ofs[2]);
-void BKE_image_get_size(struct Image *image, struct ImageUser *iuser, int *width, int *height);
-void BKE_image_get_size_fl(struct Image *image, struct ImageUser *iuser, float size[2]);
-void BKE_image_get_aspect(struct Image *image, float *aspx, float *aspy);
+void BKE_image_get_size(struct Image *image, struct ImageUser *iuser, int *r_width, int *r_height);
+void BKE_image_get_size_fl(struct Image *image, struct ImageUser *iuser, float r_size[2]);
+void BKE_image_get_aspect(struct Image *image, float *r_aspx, float *r_aspy);
/* image_gen.c */
void BKE_image_buf_fill_color(
diff --git a/source/blender/blenkernel/BKE_layer.h b/source/blender/blenkernel/BKE_layer.h
index 19eb40debe6..7059675ec7d 100644
--- a/source/blender/blenkernel/BKE_layer.h
+++ b/source/blender/blenkernel/BKE_layer.h
@@ -44,10 +44,19 @@ struct Scene;
struct View3D;
struct ViewLayer;
+typedef enum eViewLayerCopyMethod {
+ VIEWLAYER_ADD_NEW = 0,
+ VIEWLAYER_ADD_EMPTY = 1,
+ VIEWLAYER_ADD_COPY = 2,
+} eViewLayerCopyMethod;
+
struct ViewLayer *BKE_view_layer_default_view(const struct Scene *scene);
struct ViewLayer *BKE_view_layer_default_render(const struct Scene *scene);
struct ViewLayer *BKE_view_layer_find(const struct Scene *scene, const char *layer_name);
-struct ViewLayer *BKE_view_layer_add(struct Scene *scene, const char *name);
+struct ViewLayer *BKE_view_layer_add(Scene *scene,
+ const char *name,
+ ViewLayer *view_layer_source,
+ const int type);
/* DEPRECATED */
struct ViewLayer *BKE_view_layer_context_active_PLACEHOLDER(const struct Scene *scene);
diff --git a/source/blender/blenkernel/BKE_mask.h b/source/blender/blenkernel/BKE_mask.h
index 9c7d19ea151..cef26345980 100644
--- a/source/blender/blenkernel/BKE_mask.h
+++ b/source/blender/blenkernel/BKE_mask.h
@@ -106,10 +106,10 @@ float BKE_mask_spline_project_co(struct MaskSpline *spline,
const eMaskSign sign);
/* point */
-eMaskhandleMode BKE_mask_point_handles_mode_get(struct MaskSplinePoint *point);
-void BKE_mask_point_handle(struct MaskSplinePoint *point,
+eMaskhandleMode BKE_mask_point_handles_mode_get(const struct MaskSplinePoint *point);
+void BKE_mask_point_handle(const struct MaskSplinePoint *point,
eMaskWhichHandle which_handle,
- float handle[2]);
+ float r_handle[2]);
void BKE_mask_point_set_handle(struct MaskSplinePoint *point,
eMaskWhichHandle which_handle,
float loc[2],
diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h
index a25b73625fa..c37e56149eb 100644
--- a/source/blender/blenkernel/BKE_modifier.h
+++ b/source/blender/blenkernel/BKE_modifier.h
@@ -125,6 +125,11 @@ typedef enum ModifierApplyFlag {
/** Ignore scene simplification flag and use subdivisions
* level set in multires modifier. */
MOD_APPLY_IGNORE_SIMPLIFY = 1 << 3,
+ /** The effect of this modifier will be applied to the base mesh
+ * The modifier itself will be removed from the modifier stack.
+ * This flag can be checked to ignore rendering display data to the mesh.
+ * See `OBJECT_OT_modifier_apply` operator. */
+ MOD_APPLY_TO_BASE_MESH = 1 << 4,
} ModifierApplyFlag;
typedef struct ModifierUpdateDepsgraphContext {
diff --git a/source/blender/blenkernel/BKE_multires.h b/source/blender/blenkernel/BKE_multires.h
index c805b5f53a6..fe5b8cff31c 100644
--- a/source/blender/blenkernel/BKE_multires.h
+++ b/source/blender/blenkernel/BKE_multires.h
@@ -197,7 +197,8 @@ void BKE_multires_subdiv_mesh_settings_init(struct SubdivToMeshSettings *mesh_se
const struct Object *object,
const struct MultiresModifierData *mmd,
const bool use_render_params,
- const bool ignore_simplify);
+ const bool ignore_simplify,
+ const bool ignore_control_edges);
/* General helpers. */
diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h
index df0f0e730a5..556cd7105a9 100644
--- a/source/blender/blenkernel/BKE_sequencer.h
+++ b/source/blender/blenkernel/BKE_sequencer.h
@@ -337,11 +337,14 @@ void BKE_sequencer_cache_cleanup_sequence(struct Scene *scene,
struct Sequence *seq,
struct Sequence *seq_changed,
int invalidate_types);
-void BKE_sequencer_cache_iterate(
- struct Scene *scene,
- void *userdata,
- bool callback(void *userdata, struct Sequence *seq, int cfra, int cache_type, float cost));
-size_t BKE_sequencer_cache_get_num_items(struct Scene *scene);
+void BKE_sequencer_cache_iterate(struct Scene *scene,
+ void *userdata,
+ bool callback_init(void *userdata, size_t item_count),
+ bool callback_iter(void *userdata,
+ struct Sequence *seq,
+ int cfra,
+ int cache_type,
+ float cost));
bool BKE_sequencer_cache_is_full(struct Scene *scene);
/* **********************************************************************
diff --git a/source/blender/blenkernel/BKE_sound.h b/source/blender/blenkernel/BKE_sound.h
index af50e61eb2d..685582bcecf 100644
--- a/source/blender/blenkernel/BKE_sound.h
+++ b/source/blender/blenkernel/BKE_sound.h
@@ -117,8 +117,8 @@ void BKE_sound_ensure_scene(struct Scene *scene);
void BKE_sound_destroy_scene(struct Scene *scene);
-void BKE_sound_lock_scene(struct Scene *scene);
-void BKE_sound_unlock_scene(struct Scene *scene);
+void BKE_sound_lock(void);
+void BKE_sound_unlock(void);
void BKE_sound_reset_scene_specs(struct Scene *scene);
diff --git a/source/blender/blenkernel/BKE_subdiv.h b/source/blender/blenkernel/BKE_subdiv.h
index 3b342402ecb..0333d52a464 100644
--- a/source/blender/blenkernel/BKE_subdiv.h
+++ b/source/blender/blenkernel/BKE_subdiv.h
@@ -66,7 +66,7 @@ typedef struct SubdivSettings {
/* This refers to an adaptive isolation when creating patches for the subdivided surface.
*
- * When is set to to false (aka uniform subdivision) fixed depth of isolation is used, which
+ * When is set to false (aka uniform subdivision) fixed depth of isolation is used, which
* allows to iteratively add more subdivisions (uniform subdivision level 2 = uniform subdivision
* level 1 + uniform subdivision level 1). Uniform subdivisions will progressively go to a limit
* surface.
diff --git a/source/blender/blenkernel/BKE_subdiv_ccg.h b/source/blender/blenkernel/BKE_subdiv_ccg.h
index 7d612f293ab..f8534371b17 100644
--- a/source/blender/blenkernel/BKE_subdiv_ccg.h
+++ b/source/blender/blenkernel/BKE_subdiv_ccg.h
@@ -216,7 +216,10 @@ typedef struct SubdivCCG {
} dirty;
} SubdivCCG;
-/* Create real hi-res CCG from subdivision.
+/* Create CCG representation of subdivision surface.
+ *
+ * NOTE: CCG stores dense verticies in a grid-like storage. There is no edges or
+ * polygons informations for the high-poly surface.
*
* NOTE: Subdiv is expected to be refined and ready for evaluation.
* NOTE: CCG becomes an owner of subdiv.
diff --git a/source/blender/blenkernel/BKE_subdiv_deform.h b/source/blender/blenkernel/BKE_subdiv_deform.h
index 72d2b252cf7..11ef225de27 100644
--- a/source/blender/blenkernel/BKE_subdiv_deform.h
+++ b/source/blender/blenkernel/BKE_subdiv_deform.h
@@ -34,6 +34,10 @@ struct Mesh;
struct Subdiv;
/* Special version of subdivision surface which calculates final positions for coarse vertices.
+ * Effectively is pushsing the coarse positions to the limit surface.
+ *
+ * One of the usage examples is calculation of crazy space of subdivision modifier, allowing to
+ * paint on a deformed mesh with subsurf on it.
*
* vertex_cos are supposed to hold coordinates of the coarse mesh. */
void BKE_subdiv_deform_coarse_vertices(struct Subdiv *subdiv,
diff --git a/source/blender/blenkernel/BKE_subdiv_eval.h b/source/blender/blenkernel/BKE_subdiv_eval.h
index 095d3c17d63..3f682716928 100644
--- a/source/blender/blenkernel/BKE_subdiv_eval.h
+++ b/source/blender/blenkernel/BKE_subdiv_eval.h
@@ -50,6 +50,8 @@ void BKE_subdiv_eval_init_displacement(struct Subdiv *subdiv);
/* Single point queries. */
+/* Evaluate point at a limit surface, with optional derivatives and normal. */
+
void BKE_subdiv_eval_limit_point(
struct Subdiv *subdiv, const int ptex_face_index, const float u, const float v, float r_P[3]);
void BKE_subdiv_eval_limit_point_and_derivatives(struct Subdiv *subdiv,
@@ -72,6 +74,7 @@ void BKE_subdiv_eval_limit_point_and_short_normal(struct Subdiv *subdiv,
float r_P[3],
short r_N[3]);
+/* Evaluate face-varying layer (such as UV). */
void BKE_subdiv_eval_face_varying(struct Subdiv *subdiv,
const int face_varying_channel,
const int ptex_face_index,
@@ -93,6 +96,7 @@ void BKE_subdiv_eval_displacement(struct Subdiv *subdiv,
const float dPdv[3],
float r_D[3]);
+/* Evaluate point on a limit surface with displacement applied to it. */
void BKE_subdiv_eval_final_point(
struct Subdiv *subdiv, const int ptex_face_index, const float u, const float v, float r_P[3]);
diff --git a/source/blender/blenkernel/BKE_subdiv_foreach.h b/source/blender/blenkernel/BKE_subdiv_foreach.h
index f1d4adda37c..bef141b5ac5 100644
--- a/source/blender/blenkernel/BKE_subdiv_foreach.h
+++ b/source/blender/blenkernel/BKE_subdiv_foreach.h
@@ -160,6 +160,10 @@ typedef struct SubdivForeachContext {
/* Invokes callbacks in the order and with values which corresponds to creation
* of final subdivided mesh.
*
+ * Main goal is to abstract all the traversal routines to give geometry element
+ * indices (for vertices, edges, loops, polygons) in the same way as subdivision
+ * modifier will do for a dense mesh.
+ *
* Returns truth if the whole topology was traversed, without any early exits.
*
* TODO(sergey): Need to either get rid of subdiv or of coarse_mesh.
diff --git a/source/blender/blenkernel/BKE_texture.h b/source/blender/blenkernel/BKE_texture.h
index 0f852bdc64d..fb925565735 100644
--- a/source/blender/blenkernel/BKE_texture.h
+++ b/source/blender/blenkernel/BKE_texture.h
@@ -39,7 +39,7 @@ struct Tex;
struct TexMapping;
struct TexResult;
-/* in ColorBand struct */
+/** #ColorBand.data length. */
#define MAXCOLORBAND 32
void BKE_texture_default(struct Tex *tex);
diff --git a/source/blender/blenkernel/intern/blender_undo.c b/source/blender/blenkernel/intern/blender_undo.c
index 99eb4dc9122..ab382d0e8ff 100644
--- a/source/blender/blenkernel/intern/blender_undo.c
+++ b/source/blender/blenkernel/intern/blender_undo.c
@@ -124,6 +124,9 @@ MemFileUndoData *BKE_memfile_undo_encode(Main *bmain, MemFileUndoData *mfu_prev)
}
else {
MemFile *prevfile = (mfu_prev) ? &(mfu_prev->memfile) : NULL;
+ if (prevfile) {
+ BLO_memfile_clear_future(prevfile);
+ }
/* success = */ /* UNUSED */ BLO_write_file_mem(bmain, prevfile, &mfu->memfile, G.fileflags);
mfu->undo_size = mfu->memfile.size;
}
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index e6045c45dc8..2306b046026 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -1348,6 +1348,9 @@ void BKE_brush_sculpt_reset(Brush *br)
br->flag &= ~BRUSH_SPACE_ATTEN;
br->spacing = 5;
br->alpha = 0.7f;
+ br->surface_smooth_shape_preservation = 0.5f;
+ br->surface_smooth_current_vertex = 0.5f;
+ br->surface_smooth_iterations = 4;
break;
case SCULPT_TOOL_SNAKE_HOOK:
br->alpha = 1.0f;
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 45e2ff10ba4..04adb642fc0 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -472,9 +472,9 @@ static void contarget_get_mesh_mat(Object *ob, const char *substring, float mat[
/* derive the rotation from the average normal:
* - code taken from transform_gizmo.c,
- * calc_gizmo_stats, V3D_ORIENT_NORMAL case
- */
- /* we need the transpose of the inverse for a normal... */
+ * calc_gizmo_stats, V3D_ORIENT_NORMAL case */
+
+ /* We need the transpose of the inverse for a normal. */
copy_m3_m4(imat, ob->obmat);
invert_m3_m3(tmat, imat);
@@ -577,7 +577,7 @@ static void constraint_target_to_mat4(Object *ob,
copy_m4_m4(mat, ob->obmat);
BKE_constraint_mat_convertspace(ob, NULL, mat, from, to, false);
}
- /* Case VERTEXGROUP */
+ /* Case VERTEXGROUP */
/* Current method just takes the average location of all the points in the
* VertexGroup, and uses that as the location value of the targets. Where
* possible, the orientation will also be calculated, by calculating an
diff --git a/source/blender/blenkernel/intern/displist_tangent.c b/source/blender/blenkernel/intern/displist_tangent.c
index 4ac8d47feba..88fef1a4cfd 100644
--- a/source/blender/blenkernel/intern/displist_tangent.c
+++ b/source/blender/blenkernel/intern/displist_tangent.c
@@ -144,7 +144,7 @@ static int face_to_vert_index(SGLSLDisplistToTangent *dlt,
v += 1;
}
- /* Cyclic correction. */
+ /* Cyclic correction. */
u = u % dlt->dl->nr;
v = v % dlt->dl->parts;
diff --git a/source/blender/blenkernel/intern/fluid.c b/source/blender/blenkernel/intern/fluid.c
index ae51c997a08..b095e6dbeec 100644
--- a/source/blender/blenkernel/intern/fluid.c
+++ b/source/blender/blenkernel/intern/fluid.c
@@ -36,6 +36,7 @@
#include "DNA_fluid_types.h"
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
+#include "DNA_rigidbody_types.h"
#include "BKE_effect.h"
#include "BKE_fluid.h"
@@ -497,6 +498,8 @@ static void manta_set_domain_gravity(Scene *scene, FluidDomainSettings *mds)
copy_v3_v3(mds->gravity, gravity);
}
+
+ mul_v3_fl(mds->gravity, mds->effector_weights->global_gravity);
}
static bool BKE_fluid_modifier_init(
@@ -642,6 +645,11 @@ static bool is_static_object(Object *ob)
}
}
+ /* Active rigid body objects considered to be dynamic fluid objects. */
+ if (ob->rigidbody_object && ob->rigidbody_object->type == RBO_TYPE_ACTIVE) {
+ return false;
+ }
+
/* Finally, check if the object has animation data. If so, it is considered dynamic. */
return !BKE_object_moves_in_time(ob, true);
}
@@ -770,7 +778,9 @@ static void bb_combineMaps(FluidObjectBB *output,
/* Values. */
output->numobjs[index_out] = bb1.numobjs[index_in];
- output->influence[index_out] = bb1.influence[index_in];
+ if (output->influence && bb1.influence) {
+ output->influence[index_out] = bb1.influence[index_in];
+ }
output->distances[index_out] = bb1.distances[index_in];
if (output->velocity && bb1.velocity) {
copy_v3_v3(&output->velocity[index_out * 3], &bb1.velocity[index_in * 3]);
@@ -785,12 +795,14 @@ static void bb_combineMaps(FluidObjectBB *output,
/* Values. */
output->numobjs[index_out] = MAX2(bb2->numobjs[index_in], output->numobjs[index_out]);
- if (additive) {
- output->influence[index_out] += bb2->influence[index_in] * sample_size;
- }
- else {
- output->influence[index_out] = MAX2(bb2->influence[index_in],
- output->influence[index_out]);
+ if (output->influence && bb2->influence) {
+ if (additive) {
+ output->influence[index_out] += bb2->influence[index_in] * sample_size;
+ }
+ else {
+ output->influence[index_out] = MAX2(bb2->influence[index_in],
+ output->influence[index_out]);
+ }
}
output->distances[index_out] = MIN2(bb2->distances[index_in],
output->distances[index_out]);
diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index 555b0af5a63..fc7f15348bc 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -1926,6 +1926,9 @@ void BKE_gpencil_visible_stroke_iter(
}
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
+ if (gps->totpoints == 0) {
+ continue;
+ }
stroke_cb(gpl, gpf, gps, thunk);
}
}
@@ -1939,6 +1942,9 @@ void BKE_gpencil_visible_stroke_iter(
}
LISTBASE_FOREACH (bGPDstroke *, gps, &act_gpf->strokes) {
+ if (gps->totpoints == 0) {
+ continue;
+ }
stroke_cb(gpl, act_gpf, gps, thunk);
}
}
diff --git a/source/blender/blenkernel/intern/gpencil_geom.c b/source/blender/blenkernel/intern/gpencil_geom.c
index c4acc871752..6bdcc9cfbcb 100644
--- a/source/blender/blenkernel/intern/gpencil_geom.c
+++ b/source/blender/blenkernel/intern/gpencil_geom.c
@@ -430,7 +430,7 @@ bool BKE_gpencil_stroke_sample(bGPDstroke *gps, const float dist, const bool sel
stroke_interpolate_deform_weights(gps, 0, 0, 0, &new_dv[0]);
}
- /* the rest */
+ /* The rest. */
while ((next_point_index = stroke_march_next_point(gps,
next_point_index,
last_coord,
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index 953b738213a..5dca9bf2ac5 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -578,16 +578,16 @@ ImageTile *BKE_image_get_tile_from_iuser(Image *ima, ImageUser *iuser)
int BKE_image_get_tile_from_pos(struct Image *ima,
const float uv[2],
- float new_uv[2],
- float ofs[2])
+ float r_uv[2],
+ float r_ofs[2])
{
float local_ofs[2];
- if (ofs == NULL) {
- ofs = local_ofs;
+ if (r_ofs == NULL) {
+ r_ofs = local_ofs;
}
- copy_v2_v2(new_uv, uv);
- zero_v2(ofs);
+ copy_v2_v2(r_uv, uv);
+ zero_v2(r_ofs);
if ((ima->source != IMA_SRC_TILED) || uv[0] < 0.0f || uv[1] < 0.0f || uv[0] >= 10.0f) {
return 0;
@@ -600,9 +600,9 @@ int BKE_image_get_tile_from_pos(struct Image *ima,
if (BKE_image_get_tile(ima, tile_number) == NULL) {
return 0;
}
- ofs[0] = ix;
- ofs[1] = iy;
- sub_v2_v2(new_uv, ofs);
+ r_ofs[0] = ix;
+ r_ofs[1] = iy;
+ sub_v2_v2(r_uv, r_ofs);
return tile_number;
}
@@ -5341,7 +5341,7 @@ bool BKE_image_has_alpha(struct Image *image)
}
}
-void BKE_image_get_size(Image *image, ImageUser *iuser, int *width, int *height)
+void BKE_image_get_size(Image *image, ImageUser *iuser, int *r_width, int *r_height)
{
ImBuf *ibuf = NULL;
void *lock;
@@ -5351,22 +5351,22 @@ void BKE_image_get_size(Image *image, ImageUser *iuser, int *width, int *height)
}
if (ibuf && ibuf->x > 0 && ibuf->y > 0) {
- *width = ibuf->x;
- *height = ibuf->y;
+ *r_width = ibuf->x;
+ *r_height = ibuf->y;
}
else if (image != NULL && image->type == IMA_TYPE_R_RESULT && iuser != NULL &&
iuser->scene != NULL) {
Scene *scene = iuser->scene;
- *width = (scene->r.xsch * scene->r.size) / 100;
- *height = (scene->r.ysch * scene->r.size) / 100;
+ *r_width = (scene->r.xsch * scene->r.size) / 100;
+ *r_height = (scene->r.ysch * scene->r.size) / 100;
if ((scene->r.mode & R_BORDER) && (scene->r.mode & R_CROP)) {
- *width *= BLI_rctf_size_x(&scene->r.border);
- *height *= BLI_rctf_size_y(&scene->r.border);
+ *r_width *= BLI_rctf_size_x(&scene->r.border);
+ *r_height *= BLI_rctf_size_y(&scene->r.border);
}
}
else {
- *width = IMG_SIZE_FALLBACK;
- *height = IMG_SIZE_FALLBACK;
+ *r_width = IMG_SIZE_FALLBACK;
+ *r_height = IMG_SIZE_FALLBACK;
}
if (image != NULL) {
@@ -5374,25 +5374,25 @@ void BKE_image_get_size(Image *image, ImageUser *iuser, int *width, int *height)
}
}
-void BKE_image_get_size_fl(Image *image, ImageUser *iuser, float size[2])
+void BKE_image_get_size_fl(Image *image, ImageUser *iuser, float r_size[2])
{
int width, height;
BKE_image_get_size(image, iuser, &width, &height);
- size[0] = (float)width;
- size[1] = (float)height;
+ r_size[0] = (float)width;
+ r_size[1] = (float)height;
}
-void BKE_image_get_aspect(Image *image, float *aspx, float *aspy)
+void BKE_image_get_aspect(Image *image, float *r_aspx, float *r_aspy)
{
- *aspx = 1.0;
+ *r_aspx = 1.0;
/* x is always 1 */
if (image) {
- *aspy = image->aspy / image->aspx;
+ *r_aspy = image->aspy / image->aspx;
}
else {
- *aspy = 1.0f;
+ *r_aspy = 1.0f;
}
}
diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c
index a6708413f70..e5567a43cd7 100644
--- a/source/blender/blenkernel/intern/key.c
+++ b/source/blender/blenkernel/intern/key.c
@@ -952,7 +952,7 @@ static void do_key(const int start,
k3 = key_block_get_data(key, actkb, k[2], &freek3);
k4 = key_block_get_data(key, actkb, k[3], &freek4);
- /* test for more or less points (per key!) */
+ /* Test for more or less points (per key!) */
if (tot != k[0]->totelem) {
k1tot = 0.0;
flagflo |= 1;
diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c
index 8b3a46a3eb5..ffa1eecc87b 100644
--- a/source/blender/blenkernel/intern/layer.c
+++ b/source/blender/blenkernel/intern/layer.c
@@ -178,27 +178,70 @@ static ViewLayer *view_layer_add(const char *name)
return view_layer;
}
+static void layer_collection_exclude_all(LayerCollection *layer_collection)
+{
+ LayerCollection *sub_collection = layer_collection->layer_collections.first;
+ for (; sub_collection != NULL; sub_collection = sub_collection->next) {
+ sub_collection->flag |= LAYER_COLLECTION_EXCLUDE;
+ layer_collection_exclude_all(sub_collection);
+ }
+}
+
/**
* Add a new view layer
* by default, a view layer has the master collection
*/
-ViewLayer *BKE_view_layer_add(Scene *scene, const char *name)
+ViewLayer *BKE_view_layer_add(Scene *scene,
+ const char *name,
+ ViewLayer *view_layer_source,
+ const int type)
{
- ViewLayer *view_layer = view_layer_add(name);
+ ViewLayer *view_layer_new;
+
+ if (view_layer_source) {
+ name = view_layer_source->name;
+ }
+
+ switch (type) {
+ default:
+ case VIEWLAYER_ADD_NEW: {
+ view_layer_new = view_layer_add(name);
+ BLI_addtail(&scene->view_layers, view_layer_new);
+ BKE_layer_collection_sync(scene, view_layer_new);
+ break;
+ }
+ case VIEWLAYER_ADD_COPY: {
+ /* Allocate and copy view layer data */
+ view_layer_new = MEM_callocN(sizeof(ViewLayer), "View Layer");
+ BLI_addtail(&scene->view_layers, view_layer_new);
+ BKE_view_layer_copy_data(scene, scene, view_layer_new, view_layer_source, 0);
+
+ BLI_strncpy_utf8(view_layer_new->name, name, sizeof(view_layer_new->name));
+ break;
+ }
+ case VIEWLAYER_ADD_EMPTY: {
+ view_layer_new = view_layer_add(name);
+ BLI_addtail(&scene->view_layers, view_layer_new);
- BLI_addtail(&scene->view_layers, view_layer);
+ /* Initialise layercollections */
+ BKE_layer_collection_sync(scene, view_layer_new);
+ layer_collection_exclude_all(view_layer_new->layer_collections.first);
+
+ /* Update collections after changing visibility */
+ BKE_layer_collection_sync(scene, view_layer_new);
+ break;
+ }
+ }
/* unique name */
BLI_uniquename(&scene->view_layers,
- view_layer,
+ view_layer_new,
DATA_("ViewLayer"),
'.',
offsetof(ViewLayer, name),
- sizeof(view_layer->name));
-
- BKE_layer_collection_sync(scene, view_layer);
+ sizeof(view_layer_new->name));
- return view_layer;
+ return view_layer_new;
}
void BKE_view_layer_free(ViewLayer *view_layer)
diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c
index aafbcf0d360..6c835dc5fb2 100644
--- a/source/blender/blenkernel/intern/mask.c
+++ b/source/blender/blenkernel/intern/mask.c
@@ -38,10 +38,6 @@
#include "BLT_translation.h"
#include "DNA_mask_types.h"
-#include "DNA_node_types.h"
-#include "DNA_screen_types.h"
-#include "DNA_sequence_types.h"
-#include "DNA_space_types.h"
#include "BKE_animsys.h"
#include "BKE_curve.h"
@@ -52,8 +48,6 @@
#include "BKE_main.h"
#include "BKE_mask.h"
#include "BKE_movieclip.h"
-#include "BKE_node.h"
-#include "BKE_sequencer.h"
#include "BKE_tracking.h"
#include "DEG_depsgraph_build.h"
@@ -508,9 +502,9 @@ float BKE_mask_spline_project_co(MaskSpline *spline,
/* point */
-eMaskhandleMode BKE_mask_point_handles_mode_get(MaskSplinePoint *point)
+eMaskhandleMode BKE_mask_point_handles_mode_get(const MaskSplinePoint *point)
{
- BezTriple *bezt = &point->bezt;
+ const BezTriple *bezt = &point->bezt;
if (bezt->h1 == bezt->h2 && bezt->h1 == HD_ALIGN) {
return MASK_HANDLE_MODE_STICK;
@@ -519,23 +513,25 @@ eMaskhandleMode BKE_mask_point_handles_mode_get(MaskSplinePoint *point)
return MASK_HANDLE_MODE_INDIVIDUAL_HANDLES;
}
-void BKE_mask_point_handle(MaskSplinePoint *point, eMaskWhichHandle which_handle, float handle[2])
+void BKE_mask_point_handle(const MaskSplinePoint *point,
+ eMaskWhichHandle which_handle,
+ float r_handle[2])
{
- BezTriple *bezt = &point->bezt;
+ const BezTriple *bezt = &point->bezt;
if (which_handle == MASK_WHICH_HANDLE_STICK) {
float vec[2];
sub_v2_v2v2(vec, bezt->vec[0], bezt->vec[1]);
- handle[0] = (bezt->vec[1][0] + vec[1]);
- handle[1] = (bezt->vec[1][1] - vec[0]);
+ r_handle[0] = (bezt->vec[1][0] + vec[1]);
+ r_handle[1] = (bezt->vec[1][1] - vec[0]);
}
else if (which_handle == MASK_WHICH_HANDLE_LEFT) {
- copy_v2_v2(handle, bezt->vec[0]);
+ copy_v2_v2(r_handle, bezt->vec[0]);
}
else if (which_handle == MASK_WHICH_HANDLE_RIGHT) {
- copy_v2_v2(handle, bezt->vec[2]);
+ copy_v2_v2(r_handle, bezt->vec[2]);
}
else {
BLI_assert(!"Unknown handle passed to BKE_mask_point_handle");
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index 31fe93f64ed..16ec4c0a313 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -171,7 +171,6 @@ void BKE_gpencil_material_attr_init(Material *ma)
gp_style->fill_rgba[3] = 1.0f;
ARRAY_SET_ITEMS(gp_style->mix_rgba, 1.0f, 1.0f, 1.0f, 0.2f);
ARRAY_SET_ITEMS(gp_style->texture_scale, 1.0f, 1.0f);
- gp_style->texture_opacity = 1.0f;
gp_style->texture_pixsize = 100.0f;
gp_style->flag |= GP_MATERIAL_STROKE_SHOW;
diff --git a/source/blender/blenkernel/intern/mesh_convert.c b/source/blender/blenkernel/intern/mesh_convert.c
index 955f1aca110..74b79490d67 100644
--- a/source/blender/blenkernel/intern/mesh_convert.c
+++ b/source/blender/blenkernel/intern/mesh_convert.c
@@ -1304,7 +1304,7 @@ Mesh *BKE_mesh_create_derived_for_modifier(struct Depsgraph *depsgraph,
const ModifierTypeInfo *mti = modifierType_getInfo(md_eval->type);
Mesh *result;
KeyBlock *kb;
- ModifierEvalContext mectx = {depsgraph, ob_eval, 0};
+ ModifierEvalContext mectx = {depsgraph, ob_eval, MOD_APPLY_TO_BASE_MESH};
if (!(md_eval->mode & eModifierMode_Realtime)) {
return NULL;
diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c
index b40dfcd3b7f..6ccfabcb5d2 100644
--- a/source/blender/blenkernel/intern/multires.c
+++ b/source/blender/blenkernel/intern/multires.c
@@ -308,6 +308,7 @@ float (*BKE_multires_create_deformed_base_mesh_vert_coords(struct Depsgraph *dep
Object object_for_eval = *object_eval;
object_for_eval.data = object->data;
+ object_for_eval.sculpt = NULL;
const bool use_render = (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER);
ModifierEvalContext mesh_eval_context = {depsgraph, &object_for_eval, 0};
diff --git a/source/blender/blenkernel/intern/multires_reshape_vertcos.c b/source/blender/blenkernel/intern/multires_reshape_vertcos.c
index 5aff0b3caa2..1ece7344f37 100644
--- a/source/blender/blenkernel/intern/multires_reshape_vertcos.c
+++ b/source/blender/blenkernel/intern/multires_reshape_vertcos.c
@@ -182,8 +182,7 @@ static void multires_reshape_vertcos_foreach_vertex_every_edge(
multires_reshape_vertcos_foreach_vertex(foreach_context, &ptex_coord, subdiv_vertex_index);
}
-/* Set displacement grids values at a reshape level to a object coordinates of the the given
- * source. */
+/* Set displacement grids values at a reshape level to a object coordinates of the given source. */
bool multires_reshape_assign_final_coords_from_vertcos(
const MultiresReshapeContext *reshape_context,
const float (*vert_coords)[3],
diff --git a/source/blender/blenkernel/intern/multires_subdiv.c b/source/blender/blenkernel/intern/multires_subdiv.c
index 2ea02ab6974..f7e42942f3e 100644
--- a/source/blender/blenkernel/intern/multires_subdiv.c
+++ b/source/blender/blenkernel/intern/multires_subdiv.c
@@ -50,9 +50,11 @@ void BKE_multires_subdiv_mesh_settings_init(SubdivToMeshSettings *mesh_settings,
const Object *object,
const MultiresModifierData *mmd,
const bool use_render_params,
- const bool ignore_simplify)
+ const bool ignore_simplify,
+ const bool ignore_control_edges)
{
const int level = multires_get_level(scene, object, mmd, use_render_params, ignore_simplify);
mesh_settings->resolution = (1 << level) + 1;
- mesh_settings->use_optimal_display = (mmd->flags & eMultiresModifierFlag_ControlEdges);
+ mesh_settings->use_optimal_display = (mmd->flags & eMultiresModifierFlag_ControlEdges) &&
+ !ignore_control_edges;
}
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 23bd7ae3c8c..b12402d74fc 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -211,7 +211,7 @@ static void scene_init_data(ID *id)
/* Master Collection */
scene->master_collection = BKE_collection_master_add();
- BKE_view_layer_add(scene, "View Layer");
+ BKE_view_layer_add(scene, "View Layer", NULL, VIEWLAYER_ADD_NEW);
}
static void scene_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int flag)
diff --git a/source/blender/blenkernel/intern/seqcache.c b/source/blender/blenkernel/intern/seqcache.c
index d48930e5665..a2c0434a474 100644
--- a/source/blender/blenkernel/intern/seqcache.c
+++ b/source/blender/blenkernel/intern/seqcache.c
@@ -1401,24 +1401,11 @@ void BKE_sequencer_cache_put(const SeqRenderData *context,
}
}
-size_t BKE_sequencer_cache_get_num_items(struct Scene *scene)
-{
- SeqCache *cache = seq_cache_get_from_scene(scene);
- if (!cache) {
- return 0;
- }
-
- seq_cache_lock(scene);
- size_t num_items = BLI_ghash_len(cache->hash);
- seq_cache_unlock(scene);
-
- return num_items;
-}
-
void BKE_sequencer_cache_iterate(
struct Scene *scene,
void *userdata,
- bool callback(void *userdata, struct Sequence *seq, int nfra, int cache_type, float cost))
+ bool callback_init(void *userdata, size_t item_count),
+ bool callback_iter(void *userdata, struct Sequence *seq, int nfra, int cache_type, float cost))
{
SeqCache *cache = seq_cache_get_from_scene(scene);
if (!cache) {
@@ -1426,15 +1413,16 @@ void BKE_sequencer_cache_iterate(
}
seq_cache_lock(scene);
+ bool interrupt = callback_init(userdata, BLI_ghash_len(cache->hash));
+
GHashIterator gh_iter;
BLI_ghashIterator_init(&gh_iter, cache->hash);
- bool interrupt = false;
while (!BLI_ghashIterator_done(&gh_iter) && !interrupt) {
SeqCacheKey *key = BLI_ghashIterator_getKey(&gh_iter);
BLI_ghashIterator_step(&gh_iter);
- interrupt = callback(userdata, key->seq, key->nfra, key->type, key->cost);
+ interrupt = callback_iter(userdata, key->seq, key->nfra, key->type, key->cost);
}
cache->last_key = NULL;
diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c
index 70f92c6d6bd..7c34b676e69 100644
--- a/source/blender/blenkernel/intern/seqeffects.c
+++ b/source/blender/blenkernel/intern/seqeffects.c
@@ -2499,15 +2499,14 @@ static ImBuf *do_transform_effect(const SeqRenderData *context,
/*********************** Glow *************************/
static void RVBlurBitmap2_float(float *map, int width, int height, float blur, int quality)
-/* MUUUCCH better than the previous blur. */
-/* We do the blurring in two passes which is a whole lot faster. */
-/* I changed the math around to implement an actual Gaussian */
-/* distribution. */
-/* */
-/* Watch out though, it tends to misbehaven with large blur values on */
-/* a small bitmap. Avoid avoid avoid. */
-/*=============================== */
{
+ /* Much better than the previous blur!
+ * We do the blurring in two passes which is a whole lot faster.
+ * I changed the math around to implement an actual Gaussian distribution.
+ *
+ * Watch out though, it tends to misbehave with large blur values on
+ * a small bitmap. Avoid avoid! */
+
float *temp = NULL, *swap;
float *filter = NULL;
int x, y, i, fx, fy;
diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c
index 3bb95eaeff0..97a643e88b6 100644
--- a/source/blender/blenkernel/intern/sound.c
+++ b/source/blender/blenkernel/intern/sound.c
@@ -550,12 +550,12 @@ void BKE_sound_destroy_scene(Scene *scene)
}
}
-void BKE_sound_lock_scene(struct Scene *scene)
+void BKE_sound_lock()
{
AUD_Device_lock(sound_device);
}
-void BKE_sound_unlock_scene(struct Scene *scene)
+void BKE_sound_unlock()
{
AUD_Device_unlock(sound_device);
}
@@ -1161,10 +1161,10 @@ void BKE_sound_create_scene(Scene *UNUSED(scene))
void BKE_sound_destroy_scene(Scene *UNUSED(scene))
{
}
-void BKE_sound_lock_scene(Scene *UNUSED(scene))
+void BKE_sound_lock(void)
{
}
-void BKE_sound_unlock_scene(Scene *UNUSED(scene))
+void BKE_sound_unlock(void)
{
}
void BKE_sound_reset_scene_specs(Scene *UNUSED(scene))
diff --git a/source/blender/blenkernel/intern/subdiv_foreach.c b/source/blender/blenkernel/intern/subdiv_foreach.c
index 533279f4425..6e39f9f302b 100644
--- a/source/blender/blenkernel/intern/subdiv_foreach.c
+++ b/source/blender/blenkernel/intern/subdiv_foreach.c
@@ -1875,6 +1875,13 @@ bool BKE_subdiv_foreach_subdiv_geometry(Subdiv *subdiv,
if (context->user_data_tls_free != NULL) {
parallel_range_settings.func_finalize = subdiv_foreach_finalize;
}
+
+ /* TODO(sergey): Possible optimization is to have a single pool and push all
+ * the tasks into it.
+ * NOTE: Watch out for callbacks which needs to run for loose geometry as they
+ * currently are relying on the fact that face/grid callbacks will tag non-
+ * loose geomtry. */
+
BLI_task_parallel_range(
0, coarse_mesh->totpoly, &ctx, subdiv_foreach_task, &parallel_range_settings);
if (context->vertex_loose != NULL) {
diff --git a/source/blender/blenkernel/intern/subdiv_mesh.c b/source/blender/blenkernel/intern/subdiv_mesh.c
index 0bd6fc259c6..cdb766f2507 100644
--- a/source/blender/blenkernel/intern/subdiv_mesh.c
+++ b/source/blender/blenkernel/intern/subdiv_mesh.c
@@ -1120,8 +1120,11 @@ static void subdiv_mesh_vertex_of_loose_edge(const struct SubdivForeachContext *
* it. Maybe even using vertex varying attributes. */
subdiv_vertex->bweight = 0.0f;
/* Reset normal, initialize it in a similar way as edit mode does for a
- * vertices adjacent to a loose edges. */
- normal_float_to_short_v3(subdiv_vertex->no, subdiv_vertex->co);
+ * vertices adjacent to a loose edges.
+ * See `mesh_evaluate#mesh_calc_normals_vert_fallback` */
+ float no[3];
+ normalize_v3_v3(no, subdiv_vertex->co);
+ normal_float_to_short_v3(subdiv_vertex->no, no);
}
/* =============================================================================
diff --git a/source/blender/blenkernel/intern/tracking_region_tracker.c b/source/blender/blenkernel/intern/tracking_region_tracker.c
index 6e8d4146d12..7e37e438e24 100644
--- a/source/blender/blenkernel/intern/tracking_region_tracker.c
+++ b/source/blender/blenkernel/intern/tracking_region_tracker.c
@@ -75,8 +75,8 @@ static void uint8_rgba_to_float_gray(const unsigned char *rgba,
static float *track_get_search_floatbuf(ImBuf *ibuf,
MovieTrackingTrack *track,
MovieTrackingMarker *marker,
- int *width_r,
- int *height_r)
+ int *r_width,
+ int *r_height)
{
ImBuf *searchibuf;
float *gray_pixels;
@@ -85,8 +85,8 @@ static float *track_get_search_floatbuf(ImBuf *ibuf,
searchibuf = BKE_tracking_get_search_imbuf(ibuf, track, marker, false, true);
if (!searchibuf) {
- *width_r = 0;
- *height_r = 0;
+ *r_width = 0;
+ *r_height = 0;
return NULL;
}
@@ -106,8 +106,8 @@ static float *track_get_search_floatbuf(ImBuf *ibuf,
IMB_freeImBuf(searchibuf);
- *width_r = width;
- *height_r = height;
+ *r_width = width;
+ *r_height = height;
return gray_pixels;
}
@@ -138,7 +138,7 @@ static ImBuf *tracking_context_get_keyframed_ibuf(MovieClip *clip,
MovieTrackingTrack *track,
int curfra,
bool backwards,
- MovieTrackingMarker **marker_keyed_r)
+ MovieTrackingMarker **r_marker_keyed)
{
MovieTrackingMarker *marker_keyed;
int keyed_framenr;
@@ -150,7 +150,7 @@ static ImBuf *tracking_context_get_keyframed_ibuf(MovieClip *clip,
keyed_framenr = marker_keyed->framenr;
- *marker_keyed_r = marker_keyed;
+ *r_marker_keyed = marker_keyed;
return tracking_context_get_frame_ibuf(clip, user, clip_flag, keyed_framenr);
}
diff --git a/source/blender/blenkernel/intern/undo_system.c b/source/blender/blenkernel/intern/undo_system.c
index 6d484a7b702..b111dee80ad 100644
--- a/source/blender/blenkernel/intern/undo_system.c
+++ b/source/blender/blenkernel/intern/undo_system.c
@@ -464,12 +464,12 @@ UndoStep *BKE_undosys_step_push_init_with_type(UndoStack *ustack,
}
UndoStep *us = MEM_callocN(ut->step_size, __func__);
- CLOG_INFO(&LOG, 1, "addr=%p, name='%s', type='%s'", us, name, ut->name);
if (name != NULL) {
BLI_strncpy(us->name, name, sizeof(us->name));
}
us->type = ut;
ustack->step_init = us;
+ CLOG_INFO(&LOG, 1, "addr=%p, name='%s', type='%s'", us, us->name, us->type->name);
ut->step_encode_init(C, us);
undosys_stack_validate(ustack, false);
return us;
@@ -552,6 +552,8 @@ bool BKE_undosys_step_push_with_type(UndoStack *ustack,
us->type = ut;
/* Initialized, not added yet. */
+ CLOG_INFO(&LOG, 1, "addr=%p, name='%s', type='%s'", us, us->name, us->type->name);
+
if (!undosys_step_encode(C, G_MAIN, ustack, us)) {
MEM_freeN(us);
undosys_stack_validate(ustack, true);
diff --git a/source/blender/blenkernel/intern/volume.cc b/source/blender/blenkernel/intern/volume.cc
index c568cb66cc5..6e00a942283 100644
--- a/source/blender/blenkernel/intern/volume.cc
+++ b/source/blender/blenkernel/intern/volume.cc
@@ -856,7 +856,7 @@ void BKE_volume_grids_backup_restore(Volume *volume, VolumeGridVector *grids, co
volume->runtime.grids = grids;
}
#else
- UNUSED_VARS(volume, grids);
+ UNUSED_VARS(volume, grids, filepath);
#endif
}
@@ -967,7 +967,7 @@ void BKE_volume_grid_unload(const Volume *volume, VolumeGrid *grid)
const char *volume_name = volume->id.name + 2;
grid->unload(volume_name);
#else
- UNUSED_VARS(grid);
+ UNUSED_VARS(volume, grid);
#endif
}
diff --git a/source/blender/blenlib/BLI_fileops.h b/source/blender/blenlib/BLI_fileops.h
index 89f7d01ffd6..4eb6f184a76 100644
--- a/source/blender/blenlib/BLI_fileops.h
+++ b/source/blender/blenlib/BLI_fileops.h
@@ -147,6 +147,7 @@ int BLI_access(const char *filename, int mode) ATTR_WARN_UNUSED_RESULT ATTR_NONN
bool BLI_file_is_writable(const char *file) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
bool BLI_file_touch(const char *file) ATTR_NONNULL();
+bool BLI_file_alias_target(char *target, const char *filepath);
#if 0 /* UNUSED */
int BLI_file_gzip(const char *from, const char *to) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
diff --git a/source/blender/blenlib/BLI_voronoi_2d.h b/source/blender/blenlib/BLI_voronoi_2d.h
index 947b120f51a..a48f32c283a 100644
--- a/source/blender/blenlib/BLI_voronoi_2d.h
+++ b/source/blender/blenlib/BLI_voronoi_2d.h
@@ -73,10 +73,10 @@ void BLI_voronoi_triangulate(const VoronoiSite *sites,
struct ListBase *edges,
int width,
int height,
- VoronoiTriangulationPoint **triangulated_points_r,
- int *triangulated_points_total_r,
- int (**triangles_r)[3],
- int *triangles_total_r);
+ VoronoiTriangulationPoint **r_triangulated_points,
+ int *r_triangulated_points_total,
+ int (**r_triangles)[3],
+ int *r_triangles_total);
#ifdef __cplusplus
}
diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt
index 1de0c192a20..5f5145cab70 100644
--- a/source/blender/blenlib/CMakeLists.txt
+++ b/source/blender/blenlib/CMakeLists.txt
@@ -277,6 +277,13 @@ if(WIN32)
)
endif()
+
+if(APPLE)
+ list(APPEND SRC
+ intern/storage_apple.mm
+ )
+endif()
+
if(UNIX AND NOT APPLE)
list(APPEND LIB
bf_intern_libc_compat
diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c
index da80777e6d6..7274a15661a 100644
--- a/source/blender/blenlib/intern/storage.c
+++ b/source/blender/blenlib/intern/storage.c
@@ -226,11 +226,12 @@ size_t BLI_file_size(const char *path)
return stats.st_size;
}
+#ifndef __APPLE__
eFileAttributes BLI_file_attributes(const char *path)
{
int ret = 0;
-#ifdef WIN32
+# ifdef WIN32
wchar_t wline[FILE_MAXDIR];
BLI_strncpy_wchar_from_utf8(wline, path, ARRAY_SIZE(wline));
DWORD attr = GetFileAttributesW(wline);
@@ -265,19 +266,9 @@ eFileAttributes BLI_file_attributes(const char *path)
ret |= FILE_ATTR_REPARSE_POINT;
}
-#endif
-
-#ifdef __APPLE__
-
- /* TODO:
- * If Hidden (Invisible) set FILE_ATTR_HIDDEN
- * If Locked set FILE_ATTR_READONLY
- * If Restricted set FILE_ATTR_RESTRICTED
- */
-
-#endif
+# endif
-#ifdef __linux__
+# ifdef __linux__
UNUSED_VARS(path);
/* TODO:
@@ -285,10 +276,23 @@ eFileAttributes BLI_file_attributes(const char *path)
* If Archived set FILE_ATTR_ARCHIVE
*/
-#endif
+# endif
return ret;
}
+#endif
+
+/**
+ * Returns the target path of a file-based redirection, like Mac Alias or Win32 Shortcut file.
+ */
+#ifndef __APPLE__
+bool BLI_file_alias_target(char UNUSED(target[FILE_MAXDIR]), const char *UNUSED(filepath))
+{
+ /* TODO: Find target in Win32 Shortcut - Shell Link (.lnk) file.
+ * Format: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-shllink/ */
+ return false;
+}
+#endif
/**
* Returns the st_mode from stat-ing the specified path name, or 0 if stat fails
diff --git a/source/blender/blenlib/intern/storage_apple.mm b/source/blender/blenlib/intern/storage_apple.mm
new file mode 100644
index 00000000000..0cc246b8d4f
--- /dev/null
+++ b/source/blender/blenlib/intern/storage_apple.mm
@@ -0,0 +1,96 @@
+/*
+ * 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) 2020 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup bli
+ *
+ * macOS specific implementations for storage.c.
+ */
+
+#import <Foundation/Foundation.h>
+
+#include "BLI_fileops.h"
+#include "BLI_path_util.h"
+
+bool BLI_file_alias_target(char targetpath[FILE_MAXDIR], const char *filepath)
+{
+ @autoreleasepool {
+ NSError *error = nil;
+ NSURL *shortcutURL = [[NSURL alloc] initFileURLWithFileSystemRepresentation:filepath
+ isDirectory:NO
+ relativeToURL:nil];
+ NSURL *targetURL = [NSURL URLByResolvingAliasFileAtURL:shortcutURL
+ options:NSURLBookmarkResolutionWithoutUI
+ error:&error];
+ BOOL isSame = [shortcutURL isEqual:targetURL] and
+ ([[[shortcutURL path] stringByStandardizingPath]
+ isEqualToString:[[targetURL path] stringByStandardizingPath]]);
+
+ if (targetURL == nil) {
+ return false;
+ }
+ else if (isSame) {
+ [targetURL getFileSystemRepresentation:targetpath maxLength:FILE_MAXDIR];
+ return false;
+ }
+ else if (![targetURL getFileSystemRepresentation:targetpath maxLength:FILE_MAXDIR]) {
+ return false;
+ }
+
+ NSNumber *targetIsDirectory = 0;
+ [targetURL getResourceValue:&targetIsDirectory forKey:NSURLIsDirectoryKey error:nil];
+ }
+
+ return true;
+}
+
+eFileAttributes BLI_file_attributes(const char *path)
+{
+ int ret = 0;
+
+ @autoreleasepool {
+ NSURL *fileURL = [[NSURL alloc] initFileURLWithFileSystemRepresentation:path
+ isDirectory:NO
+ relativeToURL:nil];
+ NSArray *resourceKeys =
+ @[ NSURLIsAliasFileKey, NSURLIsHiddenKey, NSURLIsReadableKey, NSURLIsWritableKey ];
+
+ NSDictionary *resourceKeyValues = [fileURL resourceValuesForKeys:resourceKeys error:nil];
+
+ const bool is_alias = [resourceKeyValues[(void)(@"@%"), NSURLIsAliasFileKey] boolValue];
+ const bool is_hidden = [resourceKeyValues[(void)(@"@%"), NSURLIsHiddenKey] boolValue];
+ const bool is_readable = [resourceKeyValues[(void)(@"@%"), NSURLIsReadableKey] boolValue];
+ const bool is_writable = [resourceKeyValues[(void)(@"@%"), NSURLIsWritableKey] boolValue];
+
+ if (is_alias) {
+ ret |= FILE_ATTR_ALIAS;
+ }
+ if (is_hidden) {
+ ret |= FILE_ATTR_HIDDEN;
+ }
+ if (is_readable && !is_writable) {
+ ret |= FILE_ATTR_READONLY;
+ }
+ if (!is_readable) {
+ ret |= FILE_ATTR_SYSTEM;
+ }
+ }
+
+ return (eFileAttributes)ret;
+}
diff --git a/source/blender/blenlib/intern/voronoi_2d.c b/source/blender/blenlib/intern/voronoi_2d.c
index 61052aa00f9..59270c58341 100644
--- a/source/blender/blenlib/intern/voronoi_2d.c
+++ b/source/blender/blenlib/intern/voronoi_2d.c
@@ -792,10 +792,10 @@ void BLI_voronoi_triangulate(const VoronoiSite *sites,
ListBase *edges,
int width,
int height,
- VoronoiTriangulationPoint **triangulated_points_r,
- int *triangulated_points_total_r,
- int (**triangles_r)[3],
- int *triangles_total_r)
+ VoronoiTriangulationPoint **r_triangulated_points,
+ int *r_triangulated_points_total,
+ int (**r_triangles)[3],
+ int *r_triangles_total)
{
VoronoiTriangulationPoint *triangulated_points = NULL;
int(*triangles)[3] = NULL;
@@ -853,11 +853,11 @@ void BLI_voronoi_triangulate(const VoronoiSite *sites,
mul_v3_fl(triangulation_point->color, 1.0f / triangulation_point->power);
}
- *triangulated_points_r = triangulated_points;
- *triangulated_points_total_r = triangulated_points_total;
+ *r_triangulated_points = triangulated_points;
+ *r_triangulated_points_total = triangulated_points_total;
- *triangles_r = triangles;
- *triangles_total_r = triangles_total;
+ *r_triangles = triangles;
+ *r_triangles_total = triangles_total;
BLI_freelistN(&boundary_edges);
}
diff --git a/source/blender/blenloader/BLO_undofile.h b/source/blender/blenloader/BLO_undofile.h
index 5f1142cc20e..f280b8f3b9c 100644
--- a/source/blender/blenloader/BLO_undofile.h
+++ b/source/blender/blenloader/BLO_undofile.h
@@ -60,6 +60,7 @@ extern void memfile_chunk_add(MemFile *memfile,
/* exports */
extern void BLO_memfile_free(MemFile *memfile);
extern void BLO_memfile_merge(MemFile *first, MemFile *second);
+extern void BLO_memfile_clear_future(MemFile *memfile);
/* utilities */
extern struct Main *BLO_memfile_main_get(struct MemFile *memfile,
diff --git a/source/blender/blenloader/intern/undofile.c b/source/blender/blenloader/intern/undofile.c
index 06469a0c087..69c4ba2b1f2 100644
--- a/source/blender/blenloader/intern/undofile.c
+++ b/source/blender/blenloader/intern/undofile.c
@@ -92,6 +92,14 @@ void BLO_memfile_merge(MemFile *first, MemFile *second)
BLO_memfile_free(first);
}
+/* Clear is_identical_future before adding next memfile. */
+void BLO_memfile_clear_future(MemFile *memfile)
+{
+ for (MemFileChunk *chunk = memfile->chunks.first; chunk; chunk = chunk->next) {
+ chunk->is_identical_future = false;
+ }
+}
+
void memfile_chunk_add(MemFile *memfile, const char *buf, uint size, MemFileChunk **compchunk_step)
{
MemFileChunk *curchunk = MEM_mallocN(sizeof(MemFileChunk), "MemFileChunk");
diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c
index a7c9c073018..50b1e385dd4 100644
--- a/source/blender/blenloader/intern/versioning_280.c
+++ b/source/blender/blenloader/intern/versioning_280.c
@@ -462,7 +462,7 @@ static void do_version_layers_to_collections(Main *bmain, Scene *scene)
const bool need_default_renderlayer = scene->r.layers.first == NULL;
for (SceneRenderLayer *srl = scene->r.layers.first; srl; srl = srl->next) {
- ViewLayer *view_layer = BKE_view_layer_add(scene, srl->name);
+ ViewLayer *view_layer = BKE_view_layer_add(scene, srl->name, NULL, VIEWLAYER_ADD_NEW);
if (srl->layflag & SCE_LAY_DISABLE) {
view_layer->flag &= ~VIEW_LAYER_RENDER;
@@ -528,7 +528,7 @@ static void do_version_layers_to_collections(Main *bmain, Scene *scene)
/* If render layers included overrides, or there are no render layers,
* we also create a vanilla viewport layer. */
if (have_override || need_default_renderlayer) {
- ViewLayer *view_layer = BKE_view_layer_add(scene, "Viewport");
+ ViewLayer *view_layer = BKE_view_layer_add(scene, "Viewport", NULL, VIEWLAYER_ADD_NEW);
/* If we ported all the original render layers,
* we don't need to make the viewport layer renderable. */
@@ -4852,6 +4852,18 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
wm->xr.session_settings.flag = XR_SESSION_USE_POSITION_TRACKING;
}
}
+
+ /* Surface deform modifier strength*/
+ if (!DNA_struct_elem_find(fd->filesdna, "SurfaceDeformModifierData", "float", "strength")) {
+ for (Object *ob = bmain->objects.first; ob; ob = ob->id.next) {
+ for (ModifierData *md = ob->modifiers.first; md; md = md->next) {
+ if (md->type == eModifierType_SurfaceDeform) {
+ SurfaceDeformModifierData *sdmd = (SurfaceDeformModifierData *)md;
+ sdmd->strength = 1.0f;
+ }
+ }
+ }
+ }
}
/**
diff --git a/source/blender/blenloader/intern/versioning_defaults.c b/source/blender/blenloader/intern/versioning_defaults.c
index 045edc8413f..80395177100 100644
--- a/source/blender/blenloader/intern/versioning_defaults.c
+++ b/source/blender/blenloader/intern/versioning_defaults.c
@@ -582,6 +582,14 @@ void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template)
brush->sculpt_tool = SCULPT_TOOL_SIMPLIFY;
}
+ brush_name = "Draw Face Sets";
+ brush = BLI_findstring(&bmain->brushes, brush_name, offsetof(ID, name) + 2);
+ if (!brush) {
+ brush = BKE_brush_add(bmain, brush_name, OB_MODE_SCULPT);
+ id_us_min(&brush->id);
+ brush->sculpt_tool = SCULPT_TOOL_DRAW_FACE_SETS;
+ }
+
/* Use the same tool icon color in the brush cursor */
for (brush = bmain->brushes.first; brush; brush = brush->id.next) {
if (brush->ob_mode & OB_MODE_SCULPT) {
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 07ff55703d9..3bdca9ca054 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -735,11 +735,6 @@ static void write_iddata(WriteData *wd, ID *id)
}
}
}
-
- /* Clear the accumulated recalc flags in case of undo step saving. */
- if (wd->use_memfile) {
- id->recalc_undo_accumulated = 0;
- }
}
static void write_previews(WriteData *wd, const PreviewImage *prv_orig)
@@ -2214,6 +2209,7 @@ static void write_mesh(WriteData *wd, Mesh *mesh)
mesh->mface = NULL;
mesh->totface = 0;
memset(&mesh->fdata, 0, sizeof(mesh->fdata));
+ memset(&mesh->runtime, 0, sizeof(mesh->runtime));
/* Reduce xdata layers, fill xlayers with layers to be written.
* This makes xdata invalid for Blender, which is why we made a
@@ -4158,6 +4154,9 @@ static bool write_file_handle(Main *mainvar,
/* Very important to do it after every ID write now, otherwise we cannot know whether a
* specific ID changed or not. */
mywrite_flush(wd);
+
+ /* Clear the accumulated recalc flags in case of undo step saving. */
+ id->recalc_undo_accumulated = 0;
}
}
diff --git a/source/blender/bmesh/operators/bmo_fill_grid.c b/source/blender/bmesh/operators/bmo_fill_grid.c
index adc612cfb54..6986655c6de 100644
--- a/source/blender/bmesh/operators/bmo_fill_grid.c
+++ b/source/blender/bmesh/operators/bmo_fill_grid.c
@@ -616,7 +616,14 @@ void bmo_grid_fill_exec(BMesh *bm, BMOperator *op)
count = BM_mesh_edgeloops_find(bm, &eloops, bm_edge_test_cb, (void *)bm);
if (count != 2) {
- BMO_error_raise(bm, op, BMERR_INVALID_SELECTION, "Select two edge loops");
+ /* Note that this error message has been adjusted to make sense when called
+ * from the operator 'MESH_OT_fill_grid' which has a 'prepare' pass which can
+ * extract two 'rail' loops from a single edge loop, see T72075. */
+ BMO_error_raise(bm,
+ op,
+ BMERR_INVALID_SELECTION,
+ "Select two edge loops "
+ "or a single closed edge loop from which two edge loops can be calculated");
goto cleanup;
}
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.cc b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.cc
index e141925725b..c3733cb235c 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.cc
@@ -32,7 +32,7 @@
namespace DEG {
RuntimeBackup::RuntimeBackup(const Depsgraph *depsgraph)
- : have_backup(nullptr),
+ : have_backup(false),
animation_backup(depsgraph),
scene_backup(depsgraph),
sound_backup(depsgraph),
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_scene.cc b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_scene.cc
index 36d0138f697..32b2d0b93c1 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_scene.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_scene.cc
@@ -46,7 +46,7 @@ void SceneBackup::reset()
void SceneBackup::init_from_scene(Scene *scene)
{
- BKE_sound_lock_scene(scene);
+ BKE_sound_lock();
sound_scene = scene->sound_scene;
playback_handle = scene->playback_handle;
@@ -80,7 +80,7 @@ void SceneBackup::restore_to_scene(Scene *scene)
sequencer_backup.restore_to_scene(scene);
- BKE_sound_unlock_scene(scene);
+ BKE_sound_unlock();
reset();
}
diff --git a/source/blender/draw/engines/eevee/eevee_bloom.c b/source/blender/draw/engines/eevee/eevee_bloom.c
index 6545a1bca84..8fd953478d5 100644
--- a/source/blender/draw/engines/eevee/eevee_bloom.c
+++ b/source/blender/draw/engines/eevee/eevee_bloom.c
@@ -323,8 +323,8 @@ void EEVEE_bloom_draw(EEVEE_Data *vedata)
/* Upsample and accumulate */
for (int i = effects->bloom_iteration_len - 2; i >= 0; i--) {
copy_v2_v2(effects->unf_source_texel_size, effects->downsamp_texel_size[i]);
- effects->unf_source_buffer = effects->bloom_downsample[i];
- effects->unf_base_buffer = last;
+ effects->unf_source_buffer = last;
+ effects->unf_base_buffer = effects->bloom_downsample[i];
GPU_framebuffer_bind(fbl->bloom_accum_fb[i]);
DRW_draw_pass(psl->bloom_upsample);
diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c
index 2062f4d83c9..4a1f0a081b2 100644
--- a/source/blender/draw/engines/eevee/eevee_materials.c
+++ b/source/blender/draw/engines/eevee/eevee_materials.c
@@ -134,7 +134,8 @@ extern char datatoc_gpu_shader_uniform_color_frag_glsl[];
render_pass_index_ += 1; \
} \
} \
- }
+ } \
+ ((void)0)
/* *********** FUNCTIONS *********** */
@@ -939,6 +940,45 @@ struct GPUMaterial *EEVEE_material_mesh_depth_get(struct Scene *scene,
return mat;
}
+static struct GPUMaterial *EEVEE_material_hair_depth_get(struct Scene *scene,
+ Material *ma,
+ bool use_hashed_alpha,
+ bool is_shadow)
+{
+ const void *engine = &DRW_engine_viewport_eevee_type;
+ int options = VAR_MAT_MESH | VAR_MAT_HAIR;
+
+ SET_FLAG_FROM_TEST(options, use_hashed_alpha, VAR_MAT_HASH);
+ SET_FLAG_FROM_TEST(options, !use_hashed_alpha, VAR_MAT_CLIP);
+ SET_FLAG_FROM_TEST(options, is_shadow, VAR_MAT_SHADOW);
+
+ GPUMaterial *mat = DRW_shader_find_from_material(ma, engine, options, true);
+ if (mat) {
+ return mat;
+ }
+
+ char *defines = eevee_get_defines(options);
+
+ char *frag_str = BLI_string_joinN(e_data.frag_shader_lib, datatoc_prepass_frag_glsl);
+
+ mat = DRW_shader_create_from_material(scene,
+ ma,
+ engine,
+ options,
+ false,
+ (is_shadow) ? e_data.vert_shadow_shader_str :
+ e_data.vert_shader_str,
+ NULL,
+ frag_str,
+ defines,
+ false);
+
+ MEM_freeN(frag_str);
+ MEM_freeN(defines);
+
+ return mat;
+}
+
struct GPUMaterial *EEVEE_material_hair_get(struct Scene *scene, Material *ma)
{
const void *engine = &DRW_engine_viewport_eevee_type;
@@ -1523,21 +1563,22 @@ static void material_opaque(Material *ma,
}
}
- RENDER_PASS_ITER_BEGIN(stl->g_data->render_passes, render_pass_index, render_pass_flag)
- emsg->material_accum_grp[render_pass_index] = DRW_shgroup_material_create(
- *gpumat, psl->material_accum_pass[render_pass_index]);
- add_standard_uniforms(emsg->material_accum_grp[render_pass_index],
- sldata,
- vedata,
- ssr_id,
- &ma->refract_depth,
- use_diffuse,
- use_glossy,
- use_refract,
- use_ssrefract,
- false,
- render_pass_flag);
- RENDER_PASS_ITER_END(render_pass_index)
+ RENDER_PASS_ITER_BEGIN (stl->g_data->render_passes, render_pass_index, render_pass_flag) {
+ emsg->material_accum_grp[render_pass_index] = DRW_shgroup_material_create(
+ *gpumat, psl->material_accum_pass[render_pass_index]);
+ add_standard_uniforms(emsg->material_accum_grp[render_pass_index],
+ sldata,
+ vedata,
+ ssr_id,
+ &ma->refract_depth,
+ use_diffuse,
+ use_glossy,
+ use_refract,
+ use_ssrefract,
+ false,
+ render_pass_flag);
+ }
+ RENDER_PASS_ITER_END(render_pass_index);
break;
}
@@ -1566,21 +1607,22 @@ static void material_opaque(Material *ma,
DRW_shgroup_uniform_float(emsg->shading_grp, "specular", spec_p, 1);
DRW_shgroup_uniform_float(emsg->shading_grp, "roughness", rough_p, 1);
- RENDER_PASS_ITER_BEGIN(stl->g_data->render_passes, render_pass_index, render_pass_flag)
- DRWShadingGroup *shgrp = EEVEE_default_render_pass_shading_group_get(
- sldata,
- vedata,
- holdout,
- use_ssr,
- psl->material_accum_pass[render_pass_index],
- render_pass_flag);
-
- DRW_shgroup_uniform_vec3(shgrp, "basecol", color_p, 1);
- DRW_shgroup_uniform_float(shgrp, "metallic", metal_p, 1);
- DRW_shgroup_uniform_float(shgrp, "specular", spec_p, 1);
- DRW_shgroup_uniform_float(shgrp, "roughness", rough_p, 1);
- emsg->material_accum_grp[render_pass_index] = shgrp;
- RENDER_PASS_ITER_END(render_pass_index)
+ RENDER_PASS_ITER_BEGIN (stl->g_data->render_passes, render_pass_index, render_pass_flag) {
+ DRWShadingGroup *shgrp = EEVEE_default_render_pass_shading_group_get(
+ sldata,
+ vedata,
+ holdout,
+ use_ssr,
+ psl->material_accum_pass[render_pass_index],
+ render_pass_flag);
+
+ DRW_shgroup_uniform_vec3(shgrp, "basecol", color_p, 1);
+ DRW_shgroup_uniform_float(shgrp, "metallic", metal_p, 1);
+ DRW_shgroup_uniform_float(shgrp, "specular", spec_p, 1);
+ DRW_shgroup_uniform_float(shgrp, "roughness", rough_p, 1);
+ emsg->material_accum_grp[render_pass_index] = shgrp;
+ }
+ RENDER_PASS_ITER_END(render_pass_index);
}
/* Fallback default depth prepass */
@@ -1741,31 +1783,92 @@ static void eevee_hair_cache_populate(EEVEE_Data *vedata,
DRWShadingGroup *shgrp = NULL;
Material *ma = eevee_object_material_get(ob, matnr - 1);
+ const bool holdout = (ob->base_flag & BASE_HOLDOUT) != 0;
+ const bool use_gpumat = ma->use_nodes && ma->nodetree && !holdout;
+ const bool use_alpha_hash = (ma->blend_method == MA_BM_HASHED);
+ const bool use_alpha_clip = (ma->blend_method == MA_BM_CLIP);
+ const bool use_ssr = ((stl->effects->enabled_effects & EFFECT_SSR) != 0);
+
+ GPUMaterial *gpumat = use_gpumat ? EEVEE_material_hair_get(scene, ma) : NULL;
+ eGPUMaterialStatus status_mat_surface = gpumat ? GPU_material_status(gpumat) : GPU_MAT_SUCCESS;
float *color_p = &ma->r;
float *metal_p = &ma->metallic;
float *spec_p = &ma->spec;
float *rough_p = &ma->roughness;
- bool use_ssr = ((stl->effects->enabled_effects & EFFECT_SSR) != 0);
- const bool holdout = (ob->base_flag & BASE_HOLDOUT) != 0;
+ /* Depth prepass. */
+ if (use_gpumat && (use_alpha_clip || use_alpha_hash)) {
+ GPUMaterial *gpumat_depth = EEVEE_material_hair_depth_get(scene, ma, use_alpha_hash, false);
- shgrp = DRW_shgroup_hair_create(ob, psys, md, psl->depth_pass, e_data.default_hair_prepass_sh);
+ eGPUMaterialStatus status_mat_depth = GPU_material_status(gpumat_depth);
- shgrp = DRW_shgroup_hair_create(
- ob, psys, md, psl->depth_pass_clip, e_data.default_hair_prepass_clip_sh);
+ if (status_mat_depth != GPU_MAT_SUCCESS) {
+ /* Mixing both flags. If depth shader fails, show it to the user by not using
+ * the surface shader. */
+ status_mat_surface = status_mat_depth;
+ }
+ else {
+ const bool use_diffuse = GPU_material_flag_get(gpumat_depth, GPU_MATFLAG_DIFFUSE);
+ const bool use_glossy = GPU_material_flag_get(gpumat_depth, GPU_MATFLAG_GLOSSY);
+ const bool use_refract = GPU_material_flag_get(gpumat_depth, GPU_MATFLAG_REFRACT);
+
+ for (int i = 0; i < 2; i++) {
+ DRWPass *pass = (i == 0) ? psl->depth_pass : psl->depth_pass_clip;
+
+ shgrp = DRW_shgroup_material_hair_create(ob, psys, md, pass, gpumat_depth);
+
+ add_standard_uniforms(shgrp,
+ sldata,
+ vedata,
+ NULL,
+ NULL,
+ use_diffuse,
+ use_glossy,
+ use_refract,
+ false,
+ false,
+ DEFAULT_RENDER_PASS_FLAG);
+
+ /* Unfortunately needed for correctness but not 99% of the time not needed.
+ * TODO detect when needed? */
+ DRW_shgroup_uniform_block(shgrp, "probe_block", sldata->probe_ubo);
+ DRW_shgroup_uniform_block(shgrp, "grid_block", sldata->grid_ubo);
+ DRW_shgroup_uniform_block(shgrp, "planar_block", sldata->planar_ubo);
+ DRW_shgroup_uniform_block(shgrp, "light_block", sldata->light_ubo);
+ DRW_shgroup_uniform_block(shgrp, "shadow_block", sldata->shadow_ubo);
+ DRW_shgroup_uniform_block(
+ shgrp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
+ DRW_shgroup_uniform_block(shgrp, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_texture(shgrp, "utilTex", e_data.util_tex);
+
+ if (use_alpha_clip) {
+ DRW_shgroup_uniform_float(shgrp, "alphaThreshold", &ma->alpha_threshold, 1);
+ }
+ }
+ }
+ }
+
+ /* Fallback to default shader */
+ if (shgrp == NULL) {
+ for (int i = 0; i < 2; i++) {
+ DRWPass *depth_pass = (i == 0) ? psl->depth_pass : psl->depth_pass_clip;
+ struct GPUShader *depth_sh = (i == 0) ? e_data.default_hair_prepass_sh :
+ e_data.default_hair_prepass_clip_sh;
+ DRW_shgroup_hair_create(ob, psys, md, depth_pass, depth_sh);
+ }
+ }
shgrp = NULL;
- if (ma->use_nodes && ma->nodetree && !holdout) {
+ if (gpumat) {
static int ssr_id;
ssr_id = (use_ssr) ? 1 : -1;
static float half = 0.5f;
static float error_col[3] = {1.0f, 0.0f, 1.0f};
static float compile_col[3] = {0.5f, 0.5f, 0.5f};
- struct GPUMaterial *gpumat = EEVEE_material_hair_get(scene, ma);
- switch (GPU_material_status(gpumat)) {
+ switch (status_mat_surface) {
case GPU_MAT_SUCCESS: {
bool use_diffuse = GPU_material_flag_get(gpumat, GPU_MATFLAG_DIFFUSE);
bool use_glossy = GPU_material_flag_get(gpumat, GPU_MATFLAG_GLOSSY);
@@ -1793,28 +1896,29 @@ static void eevee_hair_cache_populate(EEVEE_Data *vedata,
DEFAULT_RENDER_PASS_FLAG);
/* Add the hair to all the render_passes that are enabled */
- RENDER_PASS_ITER_BEGIN(stl->g_data->render_passes, render_pass_index, render_pass_flag)
- shgrp = DRW_shgroup_material_hair_create(
- ob, psys, md, psl->material_accum_pass[render_pass_index], gpumat);
- if (!use_diffuse && !use_glossy && !use_refract) {
- /* Small hack to avoid issue when utilTex is needed for
- * world_normals_get and none of the bsdfs that need it are present.
- * This binds `utilTex` even if not needed. */
- DRW_shgroup_uniform_texture(shgrp, "utilTex", e_data.util_tex);
- }
+ RENDER_PASS_ITER_BEGIN (stl->g_data->render_passes, render_pass_index, render_pass_flag) {
+ shgrp = DRW_shgroup_material_hair_create(
+ ob, psys, md, psl->material_accum_pass[render_pass_index], gpumat);
+ if (!use_diffuse && !use_glossy && !use_refract) {
+ /* Small hack to avoid issue when utilTex is needed for
+ * world_normals_get and none of the bsdfs that need it are present.
+ * This binds `utilTex` even if not needed. */
+ DRW_shgroup_uniform_texture(shgrp, "utilTex", e_data.util_tex);
+ }
- add_standard_uniforms(shgrp,
- sldata,
- vedata,
- &ssr_id,
- NULL,
- use_diffuse,
- use_glossy,
- use_refract,
- false,
- false,
- render_pass_flag);
- RENDER_PASS_ITER_END(render_pass_index)
+ add_standard_uniforms(shgrp,
+ sldata,
+ vedata,
+ &ssr_id,
+ NULL,
+ use_diffuse,
+ use_glossy,
+ use_refract,
+ false,
+ false,
+ render_pass_flag);
+ }
+ RENDER_PASS_ITER_END(render_pass_index);
break;
}
@@ -1840,28 +1944,59 @@ static void eevee_hair_cache_populate(EEVEE_Data *vedata,
DRW_shgroup_uniform_float(shgrp, "specular", spec_p, 1);
DRW_shgroup_uniform_float(shgrp, "roughness", rough_p, 1);
- RENDER_PASS_ITER_BEGIN(stl->g_data->render_passes, render_pass_index, render_pass_flag)
- shgrp = EEVEE_default_hair_render_pass_shading_group_get(
- sldata,
- vedata,
- ob,
- psys,
- md,
- holdout,
- use_ssr,
- psl->material_accum_pass[render_pass_index],
- render_pass_flag);
-
- DRW_shgroup_uniform_vec3(shgrp, "basecol", color_p, 1);
- DRW_shgroup_uniform_float(shgrp, "metallic", metal_p, 1);
- DRW_shgroup_uniform_float(shgrp, "specular", spec_p, 1);
- DRW_shgroup_uniform_float(shgrp, "roughness", rough_p, 1);
- RENDER_PASS_ITER_END(render_pass_index)
+ RENDER_PASS_ITER_BEGIN (stl->g_data->render_passes, render_pass_index, render_pass_flag) {
+ shgrp = EEVEE_default_hair_render_pass_shading_group_get(
+ sldata,
+ vedata,
+ ob,
+ psys,
+ md,
+ holdout,
+ use_ssr,
+ psl->material_accum_pass[render_pass_index],
+ render_pass_flag);
+
+ DRW_shgroup_uniform_vec3(shgrp, "basecol", color_p, 1);
+ DRW_shgroup_uniform_float(shgrp, "metallic", metal_p, 1);
+ DRW_shgroup_uniform_float(shgrp, "specular", spec_p, 1);
+ DRW_shgroup_uniform_float(shgrp, "roughness", rough_p, 1);
+ }
+ RENDER_PASS_ITER_END(render_pass_index);
}
/* Shadows */
- DRW_shgroup_hair_create(ob, psys, md, psl->shadow_pass, e_data.default_hair_prepass_sh);
- *cast_shadow = true;
+ char blend_shadow = use_gpumat ? ma->blend_shadow : MA_BS_SOLID;
+ const bool shadow_alpha_hash = (blend_shadow == MA_BS_HASHED);
+ switch (blend_shadow) {
+ case MA_BS_SOLID:
+ DRW_shgroup_hair_create(ob, psys, md, psl->shadow_pass, e_data.default_hair_prepass_sh);
+ *cast_shadow = true;
+ break;
+ case MA_BS_CLIP:
+ case MA_BS_HASHED:
+ gpumat = EEVEE_material_hair_depth_get(scene, ma, shadow_alpha_hash, true);
+ shgrp = DRW_shgroup_material_hair_create(ob, psys, md, psl->shadow_pass, gpumat);
+ /* Unfortunately needed for correctness but not 99% of the time not needed.
+ * TODO detect when needed? */
+ DRW_shgroup_uniform_block(shgrp, "probe_block", sldata->probe_ubo);
+ DRW_shgroup_uniform_block(shgrp, "grid_block", sldata->grid_ubo);
+ DRW_shgroup_uniform_block(shgrp, "planar_block", sldata->planar_ubo);
+ DRW_shgroup_uniform_block(shgrp, "light_block", sldata->light_ubo);
+ DRW_shgroup_uniform_block(shgrp, "shadow_block", sldata->shadow_ubo);
+ DRW_shgroup_uniform_block(
+ shgrp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
+ DRW_shgroup_uniform_block(shgrp, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_texture(shgrp, "utilTex", e_data.util_tex);
+
+ if (!shadow_alpha_hash) {
+ DRW_shgroup_uniform_float(shgrp, "alphaThreshold", &ma->alpha_threshold, 1);
+ }
+ *cast_shadow = true;
+ break;
+ case MA_BS_NONE:
+ default:
+ break;
+ }
}
void EEVEE_materials_cache_populate(EEVEE_Data *vedata,
diff --git a/source/blender/draw/engines/eevee/eevee_render.c b/source/blender/draw/engines/eevee/eevee_render.c
index 255c6c50c2d..076738dcbdf 100644
--- a/source/blender/draw/engines/eevee/eevee_render.c
+++ b/source/blender/draw/engines/eevee/eevee_render.c
@@ -135,9 +135,8 @@ bool EEVEE_render_init(EEVEE_Data *ved, RenderEngine *engine, struct Depsgraph *
float winmat[4][4], viewmat[4][4], viewinv[4][4];
/* TODO(sergey): Shall render hold pointer to an evaluated camera instead? */
struct Object *ob_camera_eval = DEG_get_evaluated_object(depsgraph, RE_GetCamera(engine->re));
- float frame = BKE_scene_frame_get(scene);
- RE_GetCameraWindow(engine->re, ob_camera_eval, frame, winmat);
+ RE_GetCameraWindow(engine->re, ob_camera_eval, winmat);
RE_GetCameraWindowWithOverscan(engine->re, winmat, g_data->overscan);
RE_GetCameraModelMatrix(engine->re, ob_camera_eval, viewinv);
diff --git a/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl b/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl
index 6b06aab34d2..c42f905cf7e 100644
--- a/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl
+++ b/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl
@@ -9,6 +9,14 @@ out vec3 worldNormal;
out vec3 viewNormal;
#endif
+#ifdef HAIR_SHADER
+out vec3 hairTangent;
+out float hairThickTime;
+out float hairThickness;
+out float hairTime;
+flat out int hairStrandID;
+#endif
+
void main()
{
#ifdef GPU_INTEL
@@ -18,13 +26,34 @@ void main()
gl_Position.x = float(gl_VertexID);
#endif
+#ifdef HAIR_SHADER
+ hairStrandID = hair_get_strand_id();
+ vec3 world_pos, binor;
+ hair_get_pos_tan_binor_time((ProjectionMatrix[3][3] == 0.0),
+ ModelMatrixInverse,
+ ViewMatrixInverse[3].xyz,
+ ViewMatrixInverse[2].xyz,
+ world_pos,
+ hairTangent,
+ binor,
+ hairTime,
+ hairThickness,
+ hairThickTime);
+
+ worldNormal = cross(hairTangent, binor);
+#else
vec3 world_pos = point_object_to_world(pos);
+#endif
+
gl_Position = point_world_to_ndc(world_pos);
#ifdef MESH_SHADER
worldPosition = world_pos;
viewPosition = point_world_to_view(worldPosition);
+# ifndef HAIR_SHADER
worldNormal = normalize(normal_object_to_world(nor));
+# endif
+
/* No need to normalize since this is just a rotation. */
viewNormal = normal_world_to_view(worldNormal);
# ifdef USE_ATTR
diff --git a/source/blender/draw/engines/gpencil/gpencil_cache_utils.c b/source/blender/draw/engines/gpencil/gpencil_cache_utils.c
index a5f67b7831e..f8f55843a29 100644
--- a/source/blender/draw/engines/gpencil/gpencil_cache_utils.c
+++ b/source/blender/draw/engines/gpencil/gpencil_cache_utils.c
@@ -314,12 +314,12 @@ GPENCIL_tLayer *gpencil_layer_cache_add(GPENCIL_PrivateData *pd,
break;
case eGplBlendMode_Multiply:
case eGplBlendMode_Divide:
- case eGplBlendMode_Overlay:
+ case eGplBlendMode_HardLight:
state |= DRW_STATE_BLEND_MUL;
break;
}
- if (ELEM(gpl->blend_mode, eGplBlendMode_Subtract, eGplBlendMode_Overlay)) {
+ if (ELEM(gpl->blend_mode, eGplBlendMode_Subtract, eGplBlendMode_HardLight)) {
/* For these effect to propagate, we need a signed floating point buffer. */
pd->use_signed_fb = true;
}
@@ -336,7 +336,7 @@ GPENCIL_tLayer *gpencil_layer_cache_add(GPENCIL_PrivateData *pd,
DRW_shgroup_stencil_mask(grp, 0xFF);
DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
- if (gpl->blend_mode == eGplBlendMode_Overlay) {
+ if (gpl->blend_mode == eGplBlendMode_HardLight) {
/* We cannot do custom blending on MultiTarget framebuffers.
* Workaround by doing 2 passes. */
grp = DRW_shgroup_create(sh, tgp_layer->blend_ps);
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.c b/source/blender/draw/engines/gpencil/gpencil_engine.c
index 7ffa02189e2..9ebd20eb539 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.c
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.c
@@ -905,7 +905,8 @@ void GPENCIL_draw_scene(void *ved)
float clear_cols[2][4] = {{0.0f, 0.0f, 0.0f, 0.0f}, {1.0f, 1.0f, 1.0f, 1.0f}};
/* Fade 3D objects. */
- if ((!pd->is_render) && (pd->fade_3d_object_opacity > -1.0f)) {
+ if ((!pd->is_render) && (pd->fade_3d_object_opacity > -1.0f) && (pd->obact != NULL) &&
+ (pd->obact->type == OB_GPENCIL)) {
float background_color[3];
ED_view3d_background_color_get(pd->scene, pd->v3d, background_color);
/* Blend color. */
diff --git a/source/blender/draw/engines/gpencil/gpencil_render.c b/source/blender/draw/engines/gpencil/gpencil_render.c
index 496122c0483..bb91bdbe396 100644
--- a/source/blender/draw/engines/gpencil/gpencil_render.c
+++ b/source/blender/draw/engines/gpencil/gpencil_render.c
@@ -51,8 +51,7 @@ void GPENCIL_render_init(GPENCIL_Data *vedata,
float winmat[4][4], viewmat[4][4], viewinv[4][4];
struct Object *camera = DEG_get_evaluated_object(depsgraph, RE_GetCamera(engine->re));
- float frame = BKE_scene_frame_get(scene);
- RE_GetCameraWindow(engine->re, camera, frame, winmat);
+ RE_GetCameraWindow(engine->re, camera, winmat);
RE_GetCameraModelMatrix(engine->re, camera, viewinv);
invert_m4_m4(viewmat, viewinv);
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 cb34515a960..54b2369b32b 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_common_lib.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_common_lib.glsl
@@ -77,12 +77,12 @@ layout(std140) uniform gpLightBlock
/* Must match eGPLayerBlendModes */
#define MODE_REGULAR 0
-#define MODE_OVERLAY 1
+#define MODE_HARDLIGHT 1
#define MODE_ADD 2
#define MODE_SUB 3
#define MODE_MULTIPLY 4
#define MODE_DIVIDE 5
-#define MODE_OVERLAY_SECOND_PASS 999
+#define MODE_HARDLIGHT_SECOND_PASS 999
void blend_mode_output(
int blend_mode, vec4 color, float opacity, out vec4 frag_color, out vec4 frag_revealage)
@@ -104,7 +104,7 @@ void blend_mode_output(
color.a *= opacity;
frag_revealage = frag_color = clamp(1.0 / max(vec4(1e-6), 1.0 - color * color.a), 0.0, 1e18);
break;
- case MODE_OVERLAY:
+ case MODE_HARDLIGHT:
/* Reminder: Blending func is multiply blend (dst.rgba * src.rgba).*/
/**
* We need to separate the overlay equation into 2 term (one mul and one add).
@@ -120,11 +120,13 @@ void blend_mode_output(
color = mix(vec4(0.5), color, color.a * opacity);
vec4 s = step(-0.5, -color);
frag_revealage = frag_color = 2.0 * s + 2.0 * color * (1.0 - s * 2.0);
+ frag_revealage = max(vec4(0.0), frag_revealage);
break;
- case MODE_OVERLAY_SECOND_PASS:
+ case MODE_HARDLIGHT_SECOND_PASS:
/* Reminder: Blending func is additive blend (dst.rgba + src.rgba).*/
color = mix(vec4(0.5), color, color.a * opacity);
frag_revealage = frag_color = (-1.0 + 2.0 * color) * step(-0.5, -color);
+ frag_revealage = max(vec4(0.0), frag_revealage);
break;
case MODE_SUB:
case MODE_ADD:
@@ -572,6 +574,7 @@ void fill_vertex()
finalUvs = rot_scale * uv1.xy + loc;
# endif
+ strokeHardeness = 1.0;
strokeThickness = 1e18;
strokeAspect = vec2(1.0);
strokePt1 = strokePt2 = vec2(0.0);
diff --git a/source/blender/draw/engines/overlay/overlay_antialiasing.c b/source/blender/draw/engines/overlay/overlay_antialiasing.c
index 0b7637aa098..efd2f6588ba 100644
--- a/source/blender/draw/engines/overlay/overlay_antialiasing.c
+++ b/source/blender/draw/engines/overlay/overlay_antialiasing.c
@@ -113,16 +113,6 @@ void OVERLAY_antialiasing_init(OVERLAY_Data *vedata)
GPU_ATTACHMENT_TEXTURE(color_tex),
GPU_ATTACHMENT_TEXTURE(line_tex),
});
-
- if (pd->xray_enabled) {
- DRW_texture_ensure_fullscreen_2d(&txl->temp_depth_tx, GPU_DEPTH24_STENCIL8, 0);
-
- GPU_framebuffer_ensure_config(&fbl->overlay_xray_depth_copy_fb,
- {
- GPU_ATTACHMENT_TEXTURE(txl->temp_depth_tx),
- GPU_ATTACHMENT_NONE,
- });
- }
}
void OVERLAY_antialiasing_cache_init(OVERLAY_Data *vedata)
@@ -168,6 +158,7 @@ void OVERLAY_antialiasing_cache_finish(OVERLAY_Data *vedata)
{
OVERLAY_FramebufferList *fbl = vedata->fbl;
OVERLAY_TextureList *txl = vedata->txl;
+ OVERLAY_PassList *psl = vedata->psl;
OVERLAY_PrivateData *pd = vedata->stl->pd;
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
@@ -191,6 +182,24 @@ void OVERLAY_antialiasing_cache_finish(OVERLAY_Data *vedata)
GPU_ATTACHMENT_TEXTURE(dtxl->color_overlay),
GPU_ATTACHMENT_TEXTURE(txl->overlay_line_tx)});
}
+
+ pd->antialiasing.do_depth_copy = !(psl->wireframe_ps == NULL ||
+ DRW_pass_is_empty(psl->wireframe_ps)) ||
+ (pd->xray_enabled && pd->xray_opacity > 0.0f);
+ pd->antialiasing.do_depth_infront_copy = !(psl->wireframe_xray_ps == NULL ||
+ DRW_pass_is_empty(psl->wireframe_xray_ps));
+
+ const bool do_wireframe = pd->antialiasing.do_depth_copy ||
+ pd->antialiasing.do_depth_infront_copy;
+ if (pd->xray_enabled || do_wireframe) {
+ DRW_texture_ensure_fullscreen_2d(&txl->temp_depth_tx, GPU_DEPTH24_STENCIL8, 0);
+
+ GPU_framebuffer_ensure_config(&fbl->overlay_xray_depth_copy_fb,
+ {
+ GPU_ATTACHMENT_TEXTURE(txl->temp_depth_tx),
+ GPU_ATTACHMENT_NONE,
+ });
+ }
}
void OVERLAY_antialiasing_start(OVERLAY_Data *vedata)
@@ -217,18 +226,31 @@ void OVERLAY_xray_depth_copy(OVERLAY_Data *vedata)
OVERLAY_FramebufferList *fbl = vedata->fbl;
OVERLAY_PrivateData *pd = vedata->stl->pd;
+ if (DRW_state_is_fbo() && pd->antialiasing.do_depth_copy) {
+ /* We copy the depth of the rendered geometry to be able to compare to the overlays depth. */
+ GPU_framebuffer_blit(
+ fbl->overlay_default_fb, 0, fbl->overlay_xray_depth_copy_fb, 0, GPU_DEPTH_BIT);
+ }
+
if (DRW_state_is_fbo() && pd->xray_enabled) {
- if (pd->xray_opacity > 0.0f) {
- /* We copy the depth of the rendered geometry to be able to compare to the overlays depth. */
- GPU_framebuffer_blit(
- fbl->overlay_default_fb, 0, fbl->overlay_xray_depth_copy_fb, 0, GPU_DEPTH_BIT);
- }
/* We then clear to not occlude the overlays directly. */
GPU_framebuffer_bind(fbl->overlay_default_fb);
GPU_framebuffer_clear_depth(fbl->overlay_default_fb, 1.0f);
}
}
+void OVERLAY_xray_depth_infront_copy(OVERLAY_Data *vedata)
+{
+ OVERLAY_FramebufferList *fbl = vedata->fbl;
+ OVERLAY_PrivateData *pd = vedata->stl->pd;
+
+ if (DRW_state_is_fbo() && pd->antialiasing.do_depth_infront_copy) {
+ /* We copy the depth of the rendered geometry to be able to compare to the overlays depth. */
+ GPU_framebuffer_blit(
+ fbl->overlay_in_front_fb, 0, fbl->overlay_xray_depth_copy_fb, 0, GPU_DEPTH_BIT);
+ }
+}
+
void OVERLAY_xray_fade_draw(OVERLAY_Data *vedata)
{
OVERLAY_PassList *psl = vedata->psl;
diff --git a/source/blender/draw/engines/overlay/overlay_engine.c b/source/blender/draw/engines/overlay/overlay_engine.c
index adbcd3c7f28..97f6b91b7a9 100644
--- a/source/blender/draw/engines/overlay/overlay_engine.c
+++ b/source/blender/draw/engines/overlay/overlay_engine.c
@@ -466,6 +466,8 @@ static void OVERLAY_draw_scene(void *vedata)
OVERLAY_xray_fade_draw(vedata);
OVERLAY_grid_draw(vedata);
+ OVERLAY_xray_depth_infront_copy(vedata);
+
if (DRW_state_is_fbo()) {
GPU_framebuffer_bind(fbl->overlay_line_in_front_fb);
}
diff --git a/source/blender/draw/engines/overlay/overlay_image.c b/source/blender/draw/engines/overlay/overlay_image.c
index f81c51f0883..057ab4990dd 100644
--- a/source/blender/draw/engines/overlay/overlay_image.c
+++ b/source/blender/draw/engines/overlay/overlay_image.c
@@ -244,7 +244,7 @@ static void image_camera_background_matrix_get(const Camera *cam,
unit_m4(scale);
unit_m4(translate);
- /* Normalized Object space camera frame corners. */
+ /* Normalized Object space camera frame corners. */
float cam_corners[4][3];
BKE_camera_view_frame(draw_ctx->scene, cam, cam_corners);
float cam_width = fabsf(cam_corners[0][0] - cam_corners[3][0]);
diff --git a/source/blender/draw/engines/overlay/overlay_outline.c b/source/blender/draw/engines/overlay/overlay_outline.c
index 0395f6890bd..142421f58d8 100644
--- a/source/blender/draw/engines/overlay/overlay_outline.c
+++ b/source/blender/draw/engines/overlay/overlay_outline.c
@@ -102,14 +102,18 @@ void OVERLAY_outline_init(OVERLAY_Data *vedata)
if (pd->antialiasing.enabled) {
GPU_framebuffer_ensure_config(&fbl->outlines_resolve_fb,
- {GPU_ATTACHMENT_NONE,
- GPU_ATTACHMENT_TEXTURE(txl->overlay_color_tx),
- GPU_ATTACHMENT_TEXTURE(txl->overlay_line_tx)});
+ {
+ GPU_ATTACHMENT_NONE,
+ GPU_ATTACHMENT_TEXTURE(txl->overlay_color_tx),
+ GPU_ATTACHMENT_TEXTURE(txl->overlay_line_tx),
+ });
}
else {
- GPU_framebuffer_ensure_config(
- &fbl->outlines_resolve_fb,
- {GPU_ATTACHMENT_TEXTURE(txl->temp_depth_tx), GPU_ATTACHMENT_TEXTURE(dtxl->color)});
+ GPU_framebuffer_ensure_config(&fbl->outlines_resolve_fb,
+ {
+ GPU_ATTACHMENT_NONE,
+ GPU_ATTACHMENT_TEXTURE(dtxl->color_overlay),
+ });
}
}
}
diff --git a/source/blender/draw/engines/overlay/overlay_paint.c b/source/blender/draw/engines/overlay/overlay_paint.c
index bb0b124f2ae..4a1aa270de0 100644
--- a/source/blender/draw/engines/overlay/overlay_paint.c
+++ b/source/blender/draw/engines/overlay/overlay_paint.c
@@ -28,6 +28,34 @@
#include "overlay_private.h"
+/* Check if the given object is rendered (partially) transparent */
+static bool paint_object_is_rendered_transparent(View3D *v3d, Object *ob)
+{
+ if (v3d->shading.type == OB_WIRE) {
+ return true;
+ }
+ else if (v3d->shading.type == OB_SOLID) {
+ if (v3d->shading.flag & V3D_SHADING_XRAY) {
+ return true;
+ }
+
+ if (ob && v3d->shading.color_type == V3D_SHADING_OBJECT_COLOR) {
+ return ob->color[3] < 1.0f;
+ }
+ else if (ob && ob->type == OB_MESH && ob->data &&
+ v3d->shading.color_type == V3D_SHADING_MATERIAL_COLOR) {
+ Mesh *me = ob->data;
+ for (int i = 0; i < me->totcol; i++) {
+ Material *mat = me->mat[i];
+ if (mat && mat->a < 1.0f) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+}
+
void OVERLAY_paint_init(OVERLAY_Data *vedata)
{
OVERLAY_StorageList *stl = vedata->stl;
@@ -35,6 +63,8 @@ void OVERLAY_paint_init(OVERLAY_Data *vedata)
const DRWContextState *draw_ctx = DRW_context_state_get();
pd->painting.in_front = draw_ctx->obact && (draw_ctx->obact->dtx & OB_DRAWXRAY);
+ pd->painting.alpha_blending = paint_object_is_rendered_transparent(draw_ctx->v3d,
+ draw_ctx->obact);
}
void OVERLAY_paint_cache_init(OVERLAY_Data *vedata)
@@ -46,9 +76,10 @@ void OVERLAY_paint_cache_init(OVERLAY_Data *vedata)
DRWShadingGroup *grp;
DRWState state;
- const bool use_alpha_blending = (draw_ctx->v3d->shading.type == OB_WIRE);
const bool draw_contours = (pd->overlay.wpaint_flag & V3D_OVERLAY_WPAINT_CONTOURS) != 0;
float opacity = 0.0f;
+ pd->paint_depth_grp = NULL;
+ psl->paint_depth_ps = NULL;
switch (pd->ctx_mode) {
case CTX_MODE_POSE:
@@ -56,16 +87,23 @@ void OVERLAY_paint_cache_init(OVERLAY_Data *vedata)
opacity = pd->overlay.weight_paint_mode_opacity;
if (opacity > 0.0f) {
state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL;
- state |= use_alpha_blending ? DRW_STATE_BLEND_ALPHA : DRW_STATE_BLEND_MUL;
+ state |= pd->painting.alpha_blending ? DRW_STATE_BLEND_ALPHA : DRW_STATE_BLEND_MUL;
DRW_PASS_CREATE(psl->paint_color_ps, state | pd->clipping_state);
sh = OVERLAY_shader_paint_weight();
pd->paint_surf_grp = grp = DRW_shgroup_create(sh, psl->paint_color_ps);
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
DRW_shgroup_uniform_bool_copy(grp, "drawContours", draw_contours);
- DRW_shgroup_uniform_bool_copy(grp, "useAlphaBlend", use_alpha_blending);
+ DRW_shgroup_uniform_bool_copy(grp, "useAlphaBlend", pd->painting.alpha_blending);
DRW_shgroup_uniform_float_copy(grp, "opacity", opacity);
DRW_shgroup_uniform_texture(grp, "colorramp", G_draw.weight_ramp);
+
+ if (pd->painting.alpha_blending) {
+ state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL;
+ DRW_PASS_CREATE(psl->paint_depth_ps, state);
+ sh = OVERLAY_shader_depth_only();
+ pd->paint_depth_grp = DRW_shgroup_create(sh, psl->paint_depth_ps);
+ }
}
break;
}
@@ -73,13 +111,13 @@ void OVERLAY_paint_cache_init(OVERLAY_Data *vedata)
opacity = pd->overlay.vertex_paint_mode_opacity;
if (opacity > 0.0f) {
state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL;
- state |= use_alpha_blending ? DRW_STATE_BLEND_ALPHA : DRW_STATE_BLEND_MUL;
+ state |= pd->painting.alpha_blending ? DRW_STATE_BLEND_ALPHA : DRW_STATE_BLEND_MUL;
DRW_PASS_CREATE(psl->paint_color_ps, state | pd->clipping_state);
sh = OVERLAY_shader_paint_vertcol();
pd->paint_surf_grp = grp = DRW_shgroup_create(sh, psl->paint_color_ps);
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
- DRW_shgroup_uniform_bool_copy(grp, "useAlphaBlend", use_alpha_blending);
+ DRW_shgroup_uniform_bool_copy(grp, "useAlphaBlend", pd->painting.alpha_blending);
DRW_shgroup_uniform_float_copy(grp, "opacity", opacity);
}
break;
@@ -173,11 +211,15 @@ void OVERLAY_paint_vertex_cache_populate(OVERLAY_Data *vedata, Object *ob)
const bool use_face_sel = (me_orig->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
const bool use_vert_sel = (me_orig->editflag & ME_EDIT_PAINT_VERT_SEL) != 0;
- if (pd->paint_surf_grp) {
- if (ob->mode == OB_MODE_WEIGHT_PAINT) {
+ if (ob->mode == OB_MODE_WEIGHT_PAINT) {
+ if (pd->paint_surf_grp) {
geom = DRW_cache_mesh_surface_weights_get(ob);
DRW_shgroup_call(pd->paint_surf_grp, geom, ob);
}
+ if (pd->paint_depth_grp) {
+ geom = DRW_cache_mesh_surface_weights_get(ob);
+ DRW_shgroup_call(pd->paint_depth_grp, geom, ob);
+ }
}
if (use_face_sel || use_wire) {
@@ -210,10 +252,13 @@ void OVERLAY_paint_draw(OVERLAY_Data *vedata)
DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
if (DRW_state_is_fbo()) {
- /* Pain overlay needs final color because of multiply blend mode. */
+ /* Paint overlay needs final color because of multiply blend mode. */
GPU_framebuffer_bind(pd->painting.in_front ? dfbl->in_front_fb : dfbl->default_fb);
}
+ if (psl->paint_depth_ps) {
+ DRW_draw_pass(psl->paint_depth_ps);
+ }
if (psl->paint_color_ps) {
DRW_draw_pass(psl->paint_color_ps);
}
diff --git a/source/blender/draw/engines/overlay/overlay_private.h b/source/blender/draw/engines/overlay/overlay_private.h
index 47c52c885b2..bd9583c6a5f 100644
--- a/source/blender/draw/engines/overlay/overlay_private.h
+++ b/source/blender/draw/engines/overlay/overlay_private.h
@@ -93,6 +93,7 @@ typedef struct OVERLAY_PassList {
DRWPass *outlines_detect_ps;
DRWPass *outlines_resolve_ps;
DRWPass *paint_color_ps;
+ DRWPass *paint_depth_ps;
DRWPass *paint_overlay_ps;
DRWPass *particle_ps;
DRWPass *pointcloud_ps;
@@ -245,6 +246,7 @@ typedef struct OVERLAY_PrivateData {
DRWShadingGroup *motion_path_points_grp;
DRWShadingGroup *outlines_grp;
DRWShadingGroup *outlines_gpencil_grp;
+ DRWShadingGroup *paint_depth_grp;
DRWShadingGroup *paint_surf_grp;
DRWShadingGroup *paint_wire_grp;
DRWShadingGroup *paint_wire_selected_grp;
@@ -291,6 +293,8 @@ typedef struct OVERLAY_PrivateData {
struct {
bool enabled;
+ bool do_depth_copy;
+ bool do_depth_infront_copy;
} antialiasing;
struct {
bool show_handles;
@@ -318,6 +322,7 @@ typedef struct OVERLAY_PrivateData {
} armature;
struct {
bool in_front;
+ bool alpha_blending;
} painting;
struct {
DRWCallBuffer *handle[2];
@@ -408,6 +413,7 @@ void OVERLAY_antialiasing_start(OVERLAY_Data *vedata);
void OVERLAY_antialiasing_end(OVERLAY_Data *vedata);
void OVERLAY_xray_fade_draw(OVERLAY_Data *vedata);
void OVERLAY_xray_depth_copy(OVERLAY_Data *vedata);
+void OVERLAY_xray_depth_infront_copy(OVERLAY_Data *vedata);
bool OVERLAY_armature_is_pose_mode(Object *ob, const struct DRWContextState *draw_ctx);
void OVERLAY_armature_cache_init(OVERLAY_Data *vedata);
@@ -610,7 +616,7 @@ GPUShader *OVERLAY_shader_particle_shape(void);
GPUShader *OVERLAY_shader_pointcloud_dot(void);
GPUShader *OVERLAY_shader_sculpt_mask(void);
GPUShader *OVERLAY_shader_volume_velocity(bool use_needle);
-GPUShader *OVERLAY_shader_wireframe(void);
+GPUShader *OVERLAY_shader_wireframe(bool custom_bias);
GPUShader *OVERLAY_shader_wireframe_select(void);
GPUShader *OVERLAY_shader_xray_fade(void);
diff --git a/source/blender/draw/engines/overlay/overlay_shader.c b/source/blender/draw/engines/overlay/overlay_shader.c
index 0b2f98294ec..8b70a0982af 100644
--- a/source/blender/draw/engines/overlay/overlay_shader.c
+++ b/source/blender/draw/engines/overlay/overlay_shader.c
@@ -192,7 +192,7 @@ typedef struct OVERLAY_Shaders {
GPUShader *volume_velocity_needle_sh;
GPUShader *volume_velocity_sh;
GPUShader *wireframe_select;
- GPUShader *wireframe;
+ GPUShader *wireframe[2];
GPUShader *xray_fade;
} OVERLAY_Shaders;
@@ -1372,24 +1372,29 @@ GPUShader *OVERLAY_shader_wireframe_select(void)
return sh_data->wireframe_select;
}
-GPUShader *OVERLAY_shader_wireframe(void)
+GPUShader *OVERLAY_shader_wireframe(bool custom_bias)
{
const DRWContextState *draw_ctx = DRW_context_state_get();
const GPUShaderConfigData *sh_cfg = &GPU_shader_cfg_data[draw_ctx->sh_cfg];
OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg];
- if (!sh_data->wireframe) {
- sh_data->wireframe = GPU_shader_create_from_arrays({
+ if (!sh_data->wireframe[custom_bias]) {
+ sh_data->wireframe[custom_bias] = GPU_shader_create_from_arrays({
.vert = (const char *[]){sh_cfg->lib,
datatoc_common_view_lib_glsl,
datatoc_common_globals_lib_glsl,
datatoc_gpu_shader_common_obinfos_lib_glsl,
datatoc_wireframe_vert_glsl,
NULL},
- .frag = (const char *[]){datatoc_common_view_lib_glsl, datatoc_wireframe_frag_glsl, NULL},
- .defs = (const char *[]){sh_cfg->def, NULL},
+ .frag = (const char *[]){datatoc_common_view_lib_glsl,
+ datatoc_common_globals_lib_glsl,
+ datatoc_wireframe_frag_glsl,
+ NULL},
+ .defs = (const char *[]){sh_cfg->def,
+ custom_bias ? "#define CUSTOM_DEPTH_BIAS\n" : NULL,
+ NULL},
});
}
- return sh_data->wireframe;
+ return sh_data->wireframe[custom_bias];
}
GPUShader *OVERLAY_shader_xray_fade(void)
diff --git a/source/blender/draw/engines/overlay/overlay_wireframe.c b/source/blender/draw/engines/overlay/overlay_wireframe.c
index 17b412b143c..27f3f4ae9af 100644
--- a/source/blender/draw/engines/overlay/overlay_wireframe.c
+++ b/source/blender/draw/engines/overlay/overlay_wireframe.c
@@ -51,6 +51,7 @@ void OVERLAY_wireframe_init(OVERLAY_Data *vedata)
void OVERLAY_wireframe_cache_init(OVERLAY_Data *vedata)
{
OVERLAY_PassList *psl = vedata->psl;
+ OVERLAY_TextureList *txl = vedata->txl;
OVERLAY_PrivateData *pd = vedata->stl->pd;
const DRWContextState *draw_ctx = DRW_context_state_get();
DRWShadingGroup *grp = NULL;
@@ -66,12 +67,14 @@ void OVERLAY_wireframe_cache_init(OVERLAY_Data *vedata)
const bool use_select = (DRW_state_is_select() || DRW_state_is_depth());
GPUShader *wires_sh = use_select ? OVERLAY_shader_wireframe_select() :
- OVERLAY_shader_wireframe();
+ OVERLAY_shader_wireframe(pd->antialiasing.enabled);
for (int xray = 0; xray < (is_material_shmode ? 1 : 2); xray++) {
DRWState state = DRW_STATE_FIRST_VERTEX_CONVENTION | DRW_STATE_WRITE_COLOR |
DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL;
DRWPass *pass;
+ GPUTexture **depth_tx = (pd->xray_enabled || pd->xray_opacity > 0.0f) ? &txl->temp_depth_tx :
+ &txl->dummy_depth_tx;
if (xray == 0) {
DRW_PASS_CREATE(psl->wireframe_ps, state | pd->clipping_state);
@@ -85,6 +88,7 @@ void OVERLAY_wireframe_cache_init(OVERLAY_Data *vedata)
for (int use_coloring = 0; use_coloring < 2; use_coloring++) {
pd->wires_grp[xray][use_coloring] = grp = DRW_shgroup_create(wires_sh, pass);
DRW_shgroup_uniform_block_persistent(grp, "globalsBlock", G_draw.block_ubo);
+ DRW_shgroup_uniform_texture_ref(grp, "depthTex", depth_tx);
DRW_shgroup_uniform_float_copy(grp, "wireStepParam", pd->shdata.wire_step_param);
DRW_shgroup_uniform_bool_copy(grp, "useColoring", use_coloring);
DRW_shgroup_uniform_bool_copy(grp, "isTransform", (G.moving & G_TRANSFORM_OBJ) != 0);
@@ -92,10 +96,12 @@ void OVERLAY_wireframe_cache_init(OVERLAY_Data *vedata)
DRW_shgroup_uniform_bool_copy(grp, "isRandomColor", is_random_color);
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_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);
}
diff --git a/source/blender/draw/engines/overlay/shaders/edit_gpencil_vert.glsl b/source/blender/draw/engines/overlay/shaders/edit_gpencil_vert.glsl
index 3a52e0c73b7..732e392ffe0 100644
--- a/source/blender/draw/engines/overlay/shaders/edit_gpencil_vert.glsl
+++ b/source/blender/draw/engines/overlay/shaders/edit_gpencil_vert.glsl
@@ -21,11 +21,11 @@ void discard_vert()
gl_Position = vec4(0.0, 0.0, -3e36, 0.0);
}
-#define GP_EDIT_POINT_SELECTED (1u << 0u)
-#define GP_EDIT_STROKE_SELECTED (1u << 1u)
-#define GP_EDIT_MULTIFRAME (1u << 2u)
-#define GP_EDIT_STROKE_START (1u << 3u)
-#define GP_EDIT_STROKE_END (1u << 4u)
+#define GP_EDIT_POINT_SELECTED 1u /* 1 << 0 */
+#define GP_EDIT_STROKE_SELECTED 2u /* 1 << 1 */
+#define GP_EDIT_MULTIFRAME 4u /* 1 << 2 */
+#define GP_EDIT_STROKE_START 8u /* 1 << 3 */
+#define GP_EDIT_STROKE_END 16u /* 1 << 4 */
#ifdef USE_POINTS
# define colorUnselect colorGpencilVertex
diff --git a/source/blender/draw/engines/overlay/shaders/edit_mesh_common_lib.glsl b/source/blender/draw/engines/overlay/shaders/edit_mesh_common_lib.glsl
index b79bae45f23..195d2a5a7b7 100644
--- a/source/blender/draw/engines/overlay/shaders/edit_mesh_common_lib.glsl
+++ b/source/blender/draw/engines/overlay/shaders/edit_mesh_common_lib.glsl
@@ -20,7 +20,7 @@ vec4 EDIT_MESH_edge_color_inner(int edge_flag)
color = ((edge_flag & EDGE_SELECTED) != 0) ? color_select : color;
color = ((edge_flag & EDGE_ACTIVE) != 0) ? colorEditMeshActive : color;
- color.a = (selectEdges || (edge_flag & (EDGE_SELECTED | EDGE_ACTIVE)) != 0) ? 1.0 : 0.4;
+ color.a = (selectEdges || (edge_flag & (EDGE_SELECTED | EDGE_ACTIVE)) != 0) ? 1.0 : 0.7;
return color;
}
@@ -32,7 +32,7 @@ vec4 EDIT_MESH_edge_vertex_color(int vertex_flag)
bool edge_selected = (vertex_flag & (VERT_ACTIVE | VERT_SELECTED)) != 0;
color = (edge_selected) ? color_select : color;
- color.a = (selectEdges || edge_selected) ? 1.0 : 0.4;
+ color.a = (selectEdges || edge_selected) ? 1.0 : 0.7;
return color;
}
diff --git a/source/blender/draw/engines/overlay/shaders/edit_mesh_normal_vert.glsl b/source/blender/draw/engines/overlay/shaders/edit_mesh_normal_vert.glsl
index 8833490e818..fd37bc8c534 100644
--- a/source/blender/draw/engines/overlay/shaders/edit_mesh_normal_vert.glsl
+++ b/source/blender/draw/engines/overlay/shaders/edit_mesh_normal_vert.glsl
@@ -40,7 +40,7 @@ void main()
}
else {
nor = norAndFlag.xyz;
- if (all(equal(nor, vec3(0.0)))) {
+ if (all(equal(nor, vec3(0)))) {
finalColor = vec4(0.0);
return;
}
diff --git a/source/blender/draw/engines/overlay/shaders/edit_mesh_vert.glsl b/source/blender/draw/engines/overlay/shaders/edit_mesh_vert.glsl
index 768b0596d17..203f6cb1901 100644
--- a/source/blender/draw/engines/overlay/shaders/edit_mesh_vert.glsl
+++ b/source/blender/draw/engines/overlay/shaders/edit_mesh_vert.glsl
@@ -48,10 +48,10 @@ void main()
gl_PointSize = sizeVertex * 2.0;
/* Make selected and active vertex always on top. */
if ((data.x & VERT_SELECTED) != 0) {
- gl_Position.z -= 1e-7;
+ gl_Position.z -= 5e-7 * abs(gl_Position.w);
}
if ((data.x & VERT_ACTIVE) != 0) {
- gl_Position.z -= 1e-7;
+ gl_Position.z -= 5e-7 * abs(gl_Position.w);
}
bool occluded = test_occlusion();
@@ -69,6 +69,10 @@ void main()
float bweight = float(m_data.w) / 255.0;
finalColorOuter = EDIT_MESH_edge_color_outer(m_data.y, m_data.x, crease, bweight);
+ if (finalColorOuter.a > 0.0) {
+ gl_Position.z -= 5e-7 * abs(gl_Position.w);
+ }
+
bool occluded = false; /* Done in fragment shader */
#elif defined(FACE)
diff --git a/source/blender/draw/engines/overlay/shaders/wireframe_frag.glsl b/source/blender/draw/engines/overlay/shaders/wireframe_frag.glsl
index edfe720da0c..b5442dc1b0b 100644
--- a/source/blender/draw/engines/overlay/shaders/wireframe_frag.glsl
+++ b/source/blender/draw/engines/overlay/shaders/wireframe_frag.glsl
@@ -1,4 +1,7 @@
+/* Scene Depth texture copy for manual depth test. */
+uniform sampler2D depthTex;
+
flat in vec2 edgeStart;
#ifndef SELECT_EDGES
@@ -21,5 +24,32 @@ void main()
lineOutput = pack_line_data(gl_FragCoord.xy, edgeStart, edgePos);
fragColor.rgb = finalColor;
fragColor.a = 1.0;
+
+# ifdef CUSTOM_DEPTH_BIAS
+ vec2 dir = lineOutput.xy * 2.0 - 1.0;
+ bool dir_horiz = abs(dir.x) > abs(dir.y);
+
+ vec2 uv = gl_FragCoord.xy * sizeViewportInv.xy;
+ float depth_occluder = texture(depthTex, uv).r;
+ float depth_min = depth_occluder;
+
+ if (dir_horiz) {
+ depth_min = min(depth_min, texture(depthTex, uv + vec2(-sizeViewportInv.x, 0.0)).r);
+ depth_min = min(depth_min, texture(depthTex, uv + vec2(sizeViewportInv.x, 0.0)).r);
+ }
+ else {
+ depth_min = min(depth_min, texture(depthTex, uv + vec2(0, -sizeViewportInv.y)).r);
+ depth_min = min(depth_min, texture(depthTex, uv + vec2(0, sizeViewportInv.y)).r);
+ }
+
+ float delta = abs(depth_occluder - depth_min);
+
+ if (gl_FragCoord.z < (depth_occluder + delta) && gl_FragCoord.z > depth_occluder) {
+ gl_FragDepth = depth_occluder;
+ }
+ else {
+ gl_FragDepth = gl_FragCoord.z;
+ }
+# endif
#endif
}
diff --git a/source/blender/draw/engines/overlay/shaders/wireframe_vert.glsl b/source/blender/draw/engines/overlay/shaders/wireframe_vert.glsl
index 1abac302cda..3fefe2cc0bf 100644
--- a/source/blender/draw/engines/overlay/shaders/wireframe_vert.glsl
+++ b/source/blender/draw/engines/overlay/shaders/wireframe_vert.glsl
@@ -110,19 +110,22 @@ void main()
vec3 V = (is_persp) ? normalize(ViewMatrixInverse[3].xyz - wpos) : ViewMatrixInverse[2].xyz;
float facing = dot(wnor, V);
+
+ gl_Position = point_world_to_ndc(wpos);
+
+#ifndef CUSTOM_DEPTH_BIAS
float facing_ratio = clamp(1.0 - facing * facing, 0.0, 1.0);
float flip = sign(facing); /* Flip when not facing the normal (i.e.: backfacing). */
float curvature = (1.0 - wd * 0.75); /* Avoid making things worse for curvy areas. */
vec3 wofs = wnor * (facing_ratio * curvature * flip);
wofs = normal_world_to_view(wofs);
- gl_Position = point_world_to_ndc(wpos);
-
/* Push vertex half a pixel (maximum) in normal direction. */
gl_Position.xy += wofs.xy * sizeViewportInv.xy * gl_Position.w;
/* Push the vertex towards the camera. Helps a bit. */
- gl_Position.z -= facing_ratio * curvature * 4.0e-5;
+ gl_Position.z -= facing_ratio * curvature * 1.0e-6 * gl_Position.w;
+#endif
/* Convert to screen position [0..sizeVp]. */
edgeStart = ((gl_Position.xy / gl_Position.w) * 0.5 + 0.5) * sizeViewport.xy;
diff --git a/source/blender/draw/engines/workbench/workbench_effect_antialiasing.c b/source/blender/draw/engines/workbench/workbench_effect_antialiasing.c
index 3050093062f..a0db09e9273 100644
--- a/source/blender/draw/engines/workbench/workbench_effect_antialiasing.c
+++ b/source/blender/draw/engines/workbench/workbench_effect_antialiasing.c
@@ -168,9 +168,9 @@ void workbench_antialiasing_engine_init(WORKBENCH_Data *vedata)
wpd->view = NULL;
- /* reset complete drawing when navigating. */
+ /* reset complete drawing when navigating or during viewport playback. */
if (wpd->taa_sample != 0) {
- if (wpd->is_navigating) {
+ if (wpd->is_navigating || wpd->is_playback) {
wpd->taa_sample = 0;
}
}
@@ -422,6 +422,8 @@ void workbench_antialiasing_draw_pass(WORKBENCH_Data *vedata)
* If TAA accumulation is finished, we only blit the result.
*/
+ const bool last_sample = wpd->taa_sample + 1 == wpd->taa_sample_len;
+ const bool taa_finished = wpd->taa_sample >= wpd->taa_sample_len;
if (wpd->taa_sample == 0) {
/* In playback mode, we are sure the next redraw will not use the same viewmatrix.
* In this case no need to save the depth buffer. */
@@ -432,9 +434,11 @@ void workbench_antialiasing_draw_pass(WORKBENCH_Data *vedata)
}
}
else {
- /* Accumulate result to the TAA buffer. */
- GPU_framebuffer_bind(fbl->antialiasing_fb);
- DRW_draw_pass(psl->aa_accum_ps);
+ if (!taa_finished) {
+ /* Accumulate result to the TAA buffer. */
+ GPU_framebuffer_bind(fbl->antialiasing_fb);
+ DRW_draw_pass(psl->aa_accum_ps);
+ }
/* Copy back the saved depth buffer for correct overlays. */
GPU_framebuffer_blit(fbl->antialiasing_fb, 0, dfbl->default_fb, 0, GPU_DEPTH_BIT);
if (workbench_in_front_history_needed(vedata)) {
@@ -442,10 +446,10 @@ void workbench_antialiasing_draw_pass(WORKBENCH_Data *vedata)
}
}
- if (!DRW_state_is_image_render() || wpd->taa_sample + 1 == wpd->taa_sample_len) {
+ if (!DRW_state_is_image_render() || last_sample) {
/* After a certain point SMAA is no longer necessary. */
wpd->smaa_mix_factor = 1.0f - clamp_f(wpd->taa_sample / 4.0f, 0.0f, 1.0f);
- wpd->taa_sample_inv = 1.0f / (wpd->taa_sample + 1);
+ wpd->taa_sample_inv = 1.0f / min_ii(wpd->taa_sample + 1, wpd->taa_sample_len);
if (wpd->smaa_mix_factor > 0.0f) {
GPU_framebuffer_bind(fbl->smaa_edge_fb);
@@ -459,7 +463,9 @@ void workbench_antialiasing_draw_pass(WORKBENCH_Data *vedata)
DRW_draw_pass(psl->aa_resolve_ps);
}
- wpd->taa_sample++;
+ if (!taa_finished) {
+ wpd->taa_sample++;
+ }
if (!DRW_state_is_image_render() && wpd->taa_sample < wpd->taa_sample_len) {
DRW_viewport_request_redraw();
diff --git a/source/blender/draw/engines/workbench/workbench_effect_dof.c b/source/blender/draw/engines/workbench/workbench_effect_dof.c
index 9716ccd4b44..e13f7bfdd92 100644
--- a/source/blender/draw/engines/workbench/workbench_effect_dof.c
+++ b/source/blender/draw/engines/workbench/workbench_effect_dof.c
@@ -326,7 +326,7 @@ void workbench_dof_cache_init(WORKBENCH_Data *vedata)
/* We reuse the same noise texture. Ensure it is up to date. */
workbench_cavity_samples_ubo_ensure(wpd);
- float offset = wpd->taa_sample / wpd->taa_sample_len;
+ float offset = wpd->taa_sample / (float)max_ii(1, wpd->taa_sample_len);
DRWShadingGroup *grp = DRW_shgroup_create(blur1_sh, psl->dof_blur1_ps);
DRW_shgroup_uniform_block(grp, "dofSamplesBlock", wpd->vldata->dof_sample_ubo);
DRW_shgroup_uniform_texture(grp, "noiseTex", wpd->vldata->cavity_jitter_tx);
diff --git a/source/blender/draw/engines/workbench/workbench_materials.c b/source/blender/draw/engines/workbench/workbench_materials.c
index 45f14c52ec5..a2abecb679f 100644
--- a/source/blender/draw/engines/workbench/workbench_materials.c
+++ b/source/blender/draw/engines/workbench/workbench_materials.c
@@ -267,7 +267,7 @@ DRWShadingGroup *workbench_image_setup_ex(WORKBENCH_PrivateData *wpd,
}
if (tex == NULL) {
- printf("Image not foudn\n");
+ printf("Image not found\n");
tex = wpd->dummy_image_tx;
}
diff --git a/source/blender/draw/engines/workbench/workbench_render.c b/source/blender/draw/engines/workbench/workbench_render.c
index 5a315e80a47..9e66bcb07f4 100644
--- a/source/blender/draw/engines/workbench/workbench_render.c
+++ b/source/blender/draw/engines/workbench/workbench_render.c
@@ -52,14 +52,12 @@ static void workbench_render_cache(void *vedata,
static void workbench_render_matrices_init(RenderEngine *engine, Depsgraph *depsgraph)
{
/* TODO(sergey): Shall render hold pointer to an evaluated camera instead? */
- Scene *scene = DEG_get_evaluated_scene(depsgraph);
struct Object *ob_camera_eval = DEG_get_evaluated_object(depsgraph, RE_GetCamera(engine->re));
- float frame = BKE_scene_frame_get(scene);
/* Set the persective, view and window matrix. */
float winmat[4][4], viewmat[4][4], viewinv[4][4];
- RE_GetCameraWindow(engine->re, ob_camera_eval, frame, winmat);
+ RE_GetCameraWindow(engine->re, ob_camera_eval, winmat);
RE_GetCameraModelMatrix(engine->re, ob_camera_eval, viewinv);
invert_m4_m4(viewmat, viewinv);
diff --git a/source/blender/draw/intern/draw_cache_extract_mesh.c b/source/blender/draw/intern/draw_cache_extract_mesh.c
index 54e745102f0..f54fef63c82 100644
--- a/source/blender/draw/intern/draw_cache_extract_mesh.c
+++ b/source/blender/draw/intern/draw_cache_extract_mesh.c
@@ -191,7 +191,17 @@ static MeshRenderData *mesh_render_data_create(Mesh *me,
else {
mr->me = me;
mr->edit_bmesh = NULL;
- mr->extract_type = MR_EXTRACT_MESH;
+
+ bool use_mapped = mr->me && !mr->me->runtime.is_original;
+ if (use_mapped) {
+ mr->v_origindex = CustomData_get_layer(&mr->me->vdata, CD_ORIGINDEX);
+ mr->e_origindex = CustomData_get_layer(&mr->me->edata, CD_ORIGINDEX);
+ mr->p_origindex = CustomData_get_layer(&mr->me->pdata, CD_ORIGINDEX);
+
+ use_mapped = (mr->v_origindex || mr->e_origindex || mr->p_origindex);
+ }
+
+ mr->extract_type = use_mapped ? MR_EXTRACT_MAPPED : MR_EXTRACT_MESH;
}
if (mr->extract_type != MR_EXTRACT_BMESH) {
@@ -924,10 +934,14 @@ static void extract_lines_paint_mask_loop_mesh(const MeshRenderData *mr,
void *_data)
{
MeshExtract_LinePaintMask_Data *data = (MeshExtract_LinePaintMask_Data *)_data;
- if (!(mr->use_hide && (mpoly->flag & ME_HIDE))) {
+ const int edge_idx = mloop->e;
+ const MEdge *medge = &mr->medge[edge_idx];
+ if (!((mr->use_hide && (medge->flag & ME_HIDE)) ||
+ ((mr->extract_type == MR_EXTRACT_MAPPED) &&
+ (mr->e_origindex[edge_idx] == ORIGINDEX_NONE)))) {
+
int loopend = mpoly->totloop + mpoly->loopstart - 1;
int other_loop = (l == loopend) ? mpoly->loopstart : (l + 1);
- int edge_idx = mloop->e;
if (mpoly->flag & ME_FACE_SEL) {
if (BLI_BITMAP_TEST_AND_SET_ATOMIC(data->select_map, edge_idx)) {
/* Hide edge as it has more than 2 selected loop. */
@@ -945,6 +959,9 @@ static void extract_lines_paint_mask_loop_mesh(const MeshRenderData *mr,
}
}
}
+ else {
+ GPU_indexbuf_set_line_restart(&data->elb, edge_idx);
+ }
}
static void extract_lines_paint_mask_finish(const MeshRenderData *UNUSED(mr),
void *ibo,
@@ -1500,7 +1517,8 @@ static void extract_pos_nor_loop_mesh(const MeshRenderData *mr,
copy_v3_v3(vert->pos, mvert->co);
vert->nor = data->packed_nor[mloop->v];
/* Flag for paint mode overlay. */
- if (mpoly->flag & ME_HIDE || mvert->flag & ME_HIDE) {
+ if (mpoly->flag & ME_HIDE || mvert->flag & ME_HIDE ||
+ ((mr->extract_type == MR_EXTRACT_MAPPED) && (mr->v_origindex[mloop->v] == ORIGINDEX_NONE))) {
vert->nor.w = -1;
}
else if (mvert->flag & SELECT) {
@@ -1617,24 +1635,27 @@ static void extract_lnor_hq_loop_bmesh(const MeshRenderData *mr, int l, BMLoop *
static void extract_lnor_hq_loop_mesh(
const MeshRenderData *mr, int l, const MLoop *mloop, int p, const MPoly *mpoly, void *data)
{
+ gpuHQNor *lnor_data = &((gpuHQNor *)data)[l];
if (mr->loop_normals) {
- normal_float_to_short_v3(&((gpuHQNor *)data)[l].x, mr->loop_normals[l]);
+ normal_float_to_short_v3(&lnor_data->x, mr->loop_normals[l]);
}
else if (mpoly->flag & ME_SMOOTH) {
- copy_v3_v3_short(&((gpuHQNor *)data)[l].x, mr->mvert[mloop->v].no);
+ copy_v3_v3_short(&lnor_data->x, mr->mvert[mloop->v].no);
}
else {
- normal_float_to_short_v3(&((gpuHQNor *)data)[l].x, mr->poly_normals[p]);
+ normal_float_to_short_v3(&lnor_data->x, mr->poly_normals[p]);
}
+
/* Flag for paint mode overlay. */
- if (mpoly->flag & ME_HIDE) {
- ((gpuHQNor *)data)[l].w = -1;
+ if (mpoly->flag & ME_HIDE ||
+ (mr->extract_type == MR_EXTRACT_MAPPED && mr->v_origindex[mloop->v] == ORIGINDEX_NONE)) {
+ lnor_data->w = -1;
}
else if (mpoly->flag & ME_FACE_SEL) {
- ((gpuHQNor *)data)[l].w = 1;
+ lnor_data->w = 1;
}
else {
- ((gpuHQNor *)data)[l].w = 0;
+ lnor_data->w = 0;
}
}
@@ -1690,24 +1711,27 @@ static void extract_lnor_loop_bmesh(const MeshRenderData *mr, int l, BMLoop *loo
static void extract_lnor_loop_mesh(
const MeshRenderData *mr, int l, const MLoop *mloop, int p, const MPoly *mpoly, void *data)
{
+ GPUPackedNormal *lnor_data = &((GPUPackedNormal *)data)[l];
if (mr->loop_normals) {
- ((GPUPackedNormal *)data)[l] = GPU_normal_convert_i10_v3(mr->loop_normals[l]);
+ *lnor_data = GPU_normal_convert_i10_v3(mr->loop_normals[l]);
}
else if (mpoly->flag & ME_SMOOTH) {
- ((GPUPackedNormal *)data)[l] = GPU_normal_convert_i10_s3(mr->mvert[mloop->v].no);
+ *lnor_data = GPU_normal_convert_i10_s3(mr->mvert[mloop->v].no);
}
else {
- ((GPUPackedNormal *)data)[l] = GPU_normal_convert_i10_v3(mr->poly_normals[p]);
+ *lnor_data = GPU_normal_convert_i10_v3(mr->poly_normals[p]);
}
+
/* Flag for paint mode overlay. */
- if (mpoly->flag & ME_HIDE) {
- ((GPUPackedNormal *)data)[l].w = -1;
+ if (mpoly->flag & ME_HIDE ||
+ (mr->extract_type == MR_EXTRACT_MAPPED && mr->v_origindex[mloop->v] == ORIGINDEX_NONE)) {
+ lnor_data->w = -1;
}
else if (mpoly->flag & ME_FACE_SEL) {
- ((GPUPackedNormal *)data)[l].w = 1;
+ lnor_data->w = 1;
}
else {
- ((GPUPackedNormal *)data)[l].w = 0;
+ lnor_data->w = 0;
}
}
@@ -3890,7 +3914,8 @@ static void extract_fdots_nor_finish(const MeshRenderData *mr, void *buf, void *
for (int f = 0; f < mr->poly_len; f++) {
efa = BM_face_at_index(mr->bm, f);
const bool is_face_hidden = BM_elem_flag_test(efa, BM_ELEM_HIDDEN);
- if (is_face_hidden) {
+ if (is_face_hidden ||
+ (mr->extract_type == MR_EXTRACT_MAPPED && mr->p_origindex[f] == ORIGINDEX_NONE)) {
nor[f] = GPU_normal_convert_i10_v3(invalid_normal);
nor[f].w = NOR_AND_FLAG_HIDDEN;
}
@@ -3906,7 +3931,9 @@ static void extract_fdots_nor_finish(const MeshRenderData *mr, void *buf, void *
else {
for (int f = 0; f < mr->poly_len; f++) {
efa = bm_original_face_get(mr, f);
- if (!efa || BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
+ const bool is_face_hidden = efa && BM_elem_flag_test(efa, BM_ELEM_HIDDEN);
+ if (is_face_hidden ||
+ (mr->extract_type == MR_EXTRACT_MAPPED && mr->p_origindex[f] == ORIGINDEX_NONE)) {
nor[f] = GPU_normal_convert_i10_v3(invalid_normal);
nor[f].w = NOR_AND_FLAG_HIDDEN;
}
diff --git a/source/blender/draw/intern/draw_cache_impl_displist.c b/source/blender/draw/intern/draw_cache_impl_displist.c
index 04889463447..f1e5dbcc3cb 100644
--- a/source/blender/draw/intern/draw_cache_impl_displist.c
+++ b/source/blender/draw/intern/draw_cache_impl_displist.c
@@ -406,7 +406,7 @@ static void displist_vertbuf_attr_set_tri_pos_nor_uv(GPUVertBufRaw *pos_step,
}
}
-#define SURFACE_QUAD_ITER_START(dl) \
+#define SURFACE_QUAD_ITER_BEGIN(dl) \
{ \
uint quad[4]; \
int quad_index = 0; \
@@ -446,8 +446,7 @@ static void displist_surf_fnors_ensure(const DispList *dl, float (**fnors)[3])
float(*nor_flat)[3] = MEM_mallocN(sizeof(float) * 3 * u_len * v_len, __func__);
*fnors = nor_flat;
- SURFACE_QUAD_ITER_START(dl)
- {
+ SURFACE_QUAD_ITER_BEGIN (dl) {
normal_quad_v3(*nor_flat, verts[quad[0]], verts[quad[1]], verts[quad[2]], verts[quad[3]]);
nor_flat++;
}
@@ -570,8 +569,7 @@ void DRW_displist_vertbuf_create_loop_pos_and_nor_and_uv_and_tan(ListBase *lb,
BKE_displist_tangent_calc(dl, fnors, &tangents);
}
- SURFACE_QUAD_ITER_START(dl)
- {
+ SURFACE_QUAD_ITER_BEGIN (dl) {
if (vbo_uv) {
surf_uv_quad(dl, quad, uv);
}
diff --git a/source/blender/draw/intern/draw_cache_impl_gpencil.c b/source/blender/draw/intern/draw_cache_impl_gpencil.c
index 349eb6b00ae..3cbcdc1ede6 100644
--- a/source/blender/draw/intern/draw_cache_impl_gpencil.c
+++ b/source/blender/draw/intern/draw_cache_impl_gpencil.c
@@ -62,8 +62,6 @@ typedef struct GpencilBatchCache {
/** Cache is dirty */
bool is_dirty;
- /** Edit mode flag */
- bool is_editmode;
/** Last cache frame */
int cache_frame;
} GpencilBatchCache;
@@ -71,21 +69,17 @@ typedef struct GpencilBatchCache {
static bool gpencil_batch_cache_valid(GpencilBatchCache *cache, bGPdata *gpd, int cfra)
{
bool valid = true;
+
if (cache == NULL) {
return false;
}
- cache->is_editmode = GPENCIL_ANY_EDIT_MODE(gpd);
if (cfra != cache->cache_frame) {
valid = false;
}
else if (gpd->flag & GP_DATA_CACHE_IS_DIRTY) {
valid = false;
}
- else if (gpd->flag & GP_DATA_PYTHON_UPDATED) {
- gpd->flag &= ~GP_DATA_PYTHON_UPDATED;
- valid = false;
- }
else if (cache->is_dirty) {
valid = false;
}
@@ -106,7 +100,6 @@ static GpencilBatchCache *gpencil_batch_cache_init(Object *ob, int cfra)
memset(cache, 0, sizeof(*cache));
}
- cache->is_editmode = GPENCIL_ANY_EDIT_MODE(gpd);
cache->is_dirty = true;
cache->cache_frame = cfra;
return cache;
@@ -542,9 +535,8 @@ static void gpencil_sbuffer_stroke_ensure(bGPdata *gpd, bool do_stroke, bool do_
/* Get origin to reproject points. */
float origin[3];
- bGPDlayer *gpl = BKE_gpencil_layer_active_get(gpd);
ToolSettings *ts = scene->toolsettings;
- ED_gpencil_drawing_reference_get(scene, ob, gpl, ts->gpencil_v3d_align, origin);
+ ED_gpencil_drawing_reference_get(scene, ob, ts->gpencil_v3d_align, origin);
for (int i = 0; i < vert_len; i++) {
ED_gpencil_tpoint_to_point(region, origin, &tpoints[i], &gps->points[i]);
diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c
index aedc86c2eae..fb0423a87a6 100644
--- a/source/blender/draw/intern/draw_cache_impl_mesh.c
+++ b/source/blender/draw/intern/draw_cache_impl_mesh.c
@@ -436,8 +436,7 @@ static void mesh_batch_cache_check_vertex_group(MeshBatchCache *cache,
const struct DRW_MeshWeightState *wstate)
{
if (!drw_mesh_weight_state_compare(&cache->weight_state, wstate)) {
- FOREACH_MESH_BUFFER_CACHE(cache, mbufcache)
- {
+ FOREACH_MESH_BUFFER_CACHE (cache, mbufcache) {
GPU_VERTBUF_DISCARD_SAFE(mbufcache->vbo.weights);
}
GPU_BATCH_CLEAR_SAFE(cache->batch.surface_weights);
@@ -460,8 +459,7 @@ static void mesh_batch_cache_discard_shaded_batches(MeshBatchCache *cache)
static void mesh_batch_cache_discard_shaded_tri(MeshBatchCache *cache)
{
- FOREACH_MESH_BUFFER_CACHE(cache, mbufcache)
- {
+ FOREACH_MESH_BUFFER_CACHE (cache, mbufcache) {
GPU_VERTBUF_DISCARD_SAFE(mbufcache->vbo.pos_nor);
GPU_VERTBUF_DISCARD_SAFE(mbufcache->vbo.uv);
GPU_VERTBUF_DISCARD_SAFE(mbufcache->vbo.tan);
@@ -478,8 +476,7 @@ static void mesh_batch_cache_discard_shaded_tri(MeshBatchCache *cache)
static void mesh_batch_cache_discard_uvedit(MeshBatchCache *cache)
{
- FOREACH_MESH_BUFFER_CACHE(cache, mbufcache)
- {
+ FOREACH_MESH_BUFFER_CACHE (cache, mbufcache) {
GPU_VERTBUF_DISCARD_SAFE(mbufcache->vbo.stretch_angle);
GPU_VERTBUF_DISCARD_SAFE(mbufcache->vbo.stretch_area);
GPU_VERTBUF_DISCARD_SAFE(mbufcache->vbo.uv);
@@ -517,8 +514,7 @@ static void mesh_batch_cache_discard_uvedit(MeshBatchCache *cache)
static void mesh_batch_cache_discard_uvedit_select(MeshBatchCache *cache)
{
- FOREACH_MESH_BUFFER_CACHE(cache, mbufcache)
- {
+ FOREACH_MESH_BUFFER_CACHE (cache, mbufcache) {
GPU_VERTBUF_DISCARD_SAFE(mbufcache->vbo.edituv_data);
GPU_VERTBUF_DISCARD_SAFE(mbufcache->vbo.fdots_edituv_data);
GPU_INDEXBUF_DISCARD_SAFE(mbufcache->ibo.edituv_tris);
@@ -544,8 +540,7 @@ void DRW_mesh_batch_cache_dirty_tag(Mesh *me, int mode)
}
switch (mode) {
case BKE_MESH_BATCH_DIRTY_SELECT:
- FOREACH_MESH_BUFFER_CACHE(cache, mbufcache)
- {
+ FOREACH_MESH_BUFFER_CACHE (cache, mbufcache) {
GPU_VERTBUF_DISCARD_SAFE(mbufcache->vbo.edit_data);
GPU_VERTBUF_DISCARD_SAFE(mbufcache->vbo.fdots_nor);
}
@@ -568,8 +563,7 @@ void DRW_mesh_batch_cache_dirty_tag(Mesh *me, int mode)
case BKE_MESH_BATCH_DIRTY_SELECT_PAINT:
/* Paint mode selection flag is packed inside the nor attrib.
* Note that it can be slow if auto smooth is enabled. (see T63946) */
- FOREACH_MESH_BUFFER_CACHE(cache, mbufcache)
- {
+ FOREACH_MESH_BUFFER_CACHE (cache, mbufcache) {
GPU_INDEXBUF_DISCARD_SAFE(mbufcache->ibo.lines_paint_mask);
GPU_VERTBUF_DISCARD_SAFE(mbufcache->vbo.pos_nor);
GPU_VERTBUF_DISCARD_SAFE(mbufcache->vbo.lnor);
@@ -595,8 +589,7 @@ void DRW_mesh_batch_cache_dirty_tag(Mesh *me, int mode)
mesh_batch_cache_discard_uvedit(cache);
break;
case BKE_MESH_BATCH_DIRTY_UVEDIT_SELECT:
- FOREACH_MESH_BUFFER_CACHE(cache, mbufcache)
- {
+ FOREACH_MESH_BUFFER_CACHE (cache, mbufcache) {
GPU_VERTBUF_DISCARD_SAFE(mbufcache->vbo.edituv_data);
GPU_VERTBUF_DISCARD_SAFE(mbufcache->vbo.fdots_edituv_data);
}
@@ -619,8 +612,7 @@ static void mesh_batch_cache_clear(Mesh *me)
if (!cache) {
return;
}
- FOREACH_MESH_BUFFER_CACHE(cache, mbufcache)
- {
+ FOREACH_MESH_BUFFER_CACHE (cache, mbufcache) {
GPUVertBuf **vbos = (GPUVertBuf **)&mbufcache->vbo;
GPUIndexBuf **ibos = (GPUIndexBuf **)&mbufcache->ibo;
for (int i = 0; i < sizeof(mbufcache->vbo) / sizeof(void *); i++) {
@@ -1060,8 +1052,7 @@ void DRW_mesh_batch_cache_create_requested(
* index ranges initialized. So discard ibo.tris in order to recreate it.
* This needs to happen before saved_elem_ranges is populated. */
if ((batch_requested & MBC_SURF_PER_MAT) != 0 && (cache->batch_ready & MBC_SURF_PER_MAT) == 0) {
- FOREACH_MESH_BUFFER_CACHE(cache, mbuffercache)
- {
+ FOREACH_MESH_BUFFER_CACHE (cache, mbuffercache) {
GPU_INDEXBUF_DISCARD_SAFE(mbuffercache->ibo.tris);
}
/* Clear all batches that reference ibo.tris. */
@@ -1098,8 +1089,7 @@ void DRW_mesh_batch_cache_create_requested(
* material. */
bool cd_overlap = mesh_cd_layers_type_overlap(cache->cd_used, cache->cd_needed);
if (cd_overlap == false) {
- FOREACH_MESH_BUFFER_CACHE(cache, mbuffercache)
- {
+ FOREACH_MESH_BUFFER_CACHE (cache, mbuffercache) {
if ((cache->cd_used.uv & cache->cd_needed.uv) != cache->cd_needed.uv) {
GPU_VERTBUF_DISCARD_SAFE(mbuffercache->vbo.uv);
cd_uv_update = true;
@@ -1145,8 +1135,7 @@ void DRW_mesh_batch_cache_create_requested(
const bool is_uvsyncsel = ts && (ts->uv_flag & UV_SYNC_SELECTION);
if (cd_uv_update || (cache->is_uvsyncsel != is_uvsyncsel)) {
cache->is_uvsyncsel = is_uvsyncsel;
- FOREACH_MESH_BUFFER_CACHE(cache, mbuffercache)
- {
+ FOREACH_MESH_BUFFER_CACHE (cache, mbuffercache) {
GPU_VERTBUF_DISCARD_SAFE(mbuffercache->vbo.edituv_data);
GPU_VERTBUF_DISCARD_SAFE(mbuffercache->vbo.fdots_uv);
GPU_INDEXBUF_DISCARD_SAFE(mbuffercache->ibo.edituv_tris);
diff --git a/source/blender/draw/intern/draw_hair.c b/source/blender/draw/intern/draw_hair.c
index 3055e45a4a5..048adccc4e6 100644
--- a/source/blender/draw/intern/draw_hair.c
+++ b/source/blender/draw/intern/draw_hair.c
@@ -168,6 +168,10 @@ static DRWShadingGroup *drw_shgroup_create_hair_procedural_ex(Object *object,
BLI_assert(0);
}
+ if (shgrp == NULL) {
+ return NULL;
+ }
+
/* TODO optimize this. Only bind the ones GPUMaterial needs. */
for (int i = 0; i < hair_cache->num_uv_layers; i++) {
for (int n = 0; n < MAX_LAYER_NAME_CT && hair_cache->uv_layer_names[i][n][0] != '\0'; n++) {
diff --git a/source/blender/draw/intern/draw_manager_data.c b/source/blender/draw/intern/draw_manager_data.c
index 5a92058001f..94a3e9e8343 100644
--- a/source/blender/draw/intern/draw_manager_data.c
+++ b/source/blender/draw/intern/draw_manager_data.c
@@ -884,6 +884,11 @@ static float sculpt_debug_colors[9][4] = {
static void sculpt_draw_cb(DRWSculptCallbackData *scd, GPU_PBVH_Buffers *buffers)
{
+
+ if (scd->use_mask && !GPU_pbvh_buffers_has_overlays(buffers)) {
+ return;
+ }
+
GPUBatch *geom = GPU_pbvh_buffers_batch_get(buffers, scd->fast_mode, scd->use_wire);
short index = 0;
diff --git a/source/blender/draw/intern/shaders/common_smaa_lib.glsl b/source/blender/draw/intern/shaders/common_smaa_lib.glsl
index 45d9f54d943..a3f592ba5dd 100644
--- a/source/blender/draw/intern/shaders/common_smaa_lib.glsl
+++ b/source/blender/draw/intern/shaders/common_smaa_lib.glsl
@@ -529,8 +529,9 @@
# define SMAATexturePass2D(tex) tex
# define SMAASampleLevelZero(tex, coord) tex2Dlod(tex, float4(coord, 0.0, 0.0))
# define SMAASampleLevelZeroPoint(tex, coord) tex2Dlod(tex, float4(coord, 0.0, 0.0))
-# define SMAASampleLevelZeroOffset(tex, coord, offset) \
- tex2Dlod(tex, float4(coord + offset * SMAA_RT_METRICS.xy, 0.0, 0.0))
+/* clang-format off */
+# define SMAASampleLevelZeroOffset(tex, coord, offset) tex2Dlod(tex, float4(coord + offset * SMAA_RT_METRICS.xy, 0.0, 0.0))
+/* clang-format on */
# define SMAASample(tex, coord) tex2D(tex, coord)
# define SMAASamplePoint(tex, coord) tex2D(tex, coord)
# define SMAASampleOffset(tex, coord, offset) tex2D(tex, coord + offset * SMAA_RT_METRICS.xy)
@@ -554,8 +555,9 @@ SamplerState PointSampler
# define SMAATexturePass2D(tex) tex
# define SMAASampleLevelZero(tex, coord) tex.SampleLevel(LinearSampler, coord, 0)
# define SMAASampleLevelZeroPoint(tex, coord) tex.SampleLevel(PointSampler, coord, 0)
-# define SMAASampleLevelZeroOffset(tex, coord, offset) \
- tex.SampleLevel(LinearSampler, coord, 0, offset)
+/* clang-format off */
+# define SMAASampleLevelZeroOffset(tex, coord, offset) tex.SampleLevel(LinearSampler, coord, 0, offset)
+/* clang-format on */
# define SMAASample(tex, coord) tex.Sample(LinearSampler, coord)
# define SMAASamplePoint(tex, coord) tex.Sample(PointSampler, coord)
# define SMAASampleOffset(tex, coord, offset) tex.Sample(LinearSampler, coord, offset)
@@ -597,10 +599,11 @@ SamplerState PointSampler
# define bool4 bvec4
#endif
-#if !defined(SMAA_HLSL_3) && !defined(SMAA_HLSL_4) && !defined(SMAA_HLSL_4_1) && \
- !defined(SMAA_GLSL_3) && !defined(SMAA_GLSL_4) && !defined(SMAA_CUSTOM_SL)
+/* clang-format off */
+#if !defined(SMAA_HLSL_3) && !defined(SMAA_HLSL_4) && !defined(SMAA_HLSL_4_1) && !defined(SMAA_GLSL_3) && !defined(SMAA_GLSL_4) && !defined(SMAA_CUSTOM_SL)
# error you must define the shading language: SMAA_HLSL_*, SMAA_GLSL_* or SMAA_CUSTOM_SL
#endif
+/* clang-format on */
//-----------------------------------------------------------------------------
// Misc functions
diff --git a/source/blender/editors/animation/anim_draw.c b/source/blender/editors/animation/anim_draw.c
index 77399880b8d..96fd2e94a5e 100644
--- a/source/blender/editors/animation/anim_draw.c
+++ b/source/blender/editors/animation/anim_draw.c
@@ -441,12 +441,45 @@ static float normalization_factor_get(Scene *scene, FCurve *fcu, short flag, flo
min_coord = min_ff(min_coord, prev_bezt->vec[1][1]);
}
else {
- float step_size = (bezt->vec[1][0] - prev_bezt->vec[1][0]) / resol;
- for (int j = 0; j <= resol; j++) {
- float eval_time = prev_bezt->vec[1][0] + step_size * j;
- float eval_value = evaluate_fcurve_only_curve(fcu, eval_time);
- max_coord = max_ff(max_coord, eval_value);
- min_coord = min_ff(min_coord, eval_value);
+ if (!ELEM(prev_bezt->ipo, BEZT_IPO_BACK, BEZT_IPO_ELASTIC)) {
+ /* Calculate min/max using bezier forward differencing. */
+ float data[120];
+ float v1[2], v2[2], v3[2], v4[2];
+
+ v1[0] = prev_bezt->vec[1][0];
+ v1[1] = prev_bezt->vec[1][1];
+ v2[0] = prev_bezt->vec[2][0];
+ v2[1] = prev_bezt->vec[2][1];
+
+ v3[0] = bezt->vec[0][0];
+ v3[1] = bezt->vec[0][1];
+ v4[0] = bezt->vec[1][0];
+ v4[1] = bezt->vec[1][1];
+
+ correct_bezpart(v1, v2, v3, v4);
+
+ BKE_curve_forward_diff_bezier(
+ v1[0], v2[0], v3[0], v4[0], data, resol, sizeof(float) * 3);
+ BKE_curve_forward_diff_bezier(
+ v1[1], v2[1], v3[1], v4[1], data + 1, resol, sizeof(float) * 3);
+
+ for (int j = 0; j <= resol; ++j) {
+ const float *fp = &data[j * 3];
+ max_coord = max_ff(max_coord, fp[1]);
+ min_coord = min_ff(min_coord, fp[1]);
+ }
+ }
+ else {
+ /* Calculate min/max using full fcurve evaluation.
+ * [slower than bezier forward differencing but evaluates Back/Elastic interpolation
+ * as well].*/
+ float step_size = (bezt->vec[1][0] - prev_bezt->vec[1][0]) / resol;
+ for (int j = 0; j <= resol; j++) {
+ float eval_time = prev_bezt->vec[1][0] + step_size * j;
+ float eval_value = evaluate_fcurve_only_curve(fcu, eval_time);
+ max_coord = max_ff(max_coord, eval_value);
+ min_coord = min_ff(min_coord, eval_value);
+ }
}
}
}
@@ -515,7 +548,7 @@ float ANIM_unit_mapping_get_factor(Scene *scene, ID *id, FCurve *fcu, short flag
return 1.0f;
}
-static bool find_prev_next_keyframes(struct bContext *C, int *nextfra, int *prevfra)
+static bool find_prev_next_keyframes(struct bContext *C, int *r_nextfra, int *r_prevfra)
{
Scene *scene = CTX_data_scene(C);
Object *ob = CTX_data_active_object(C);
@@ -594,17 +627,17 @@ static bool find_prev_next_keyframes(struct bContext *C, int *nextfra, int *prev
/* any success? */
if (doneprev || donenext) {
if (doneprev) {
- *prevfra = cfraprev;
+ *r_prevfra = cfraprev;
}
else {
- *prevfra = CFRA - (cfranext - CFRA);
+ *r_prevfra = CFRA - (cfranext - CFRA);
}
if (donenext) {
- *nextfra = cfranext;
+ *r_nextfra = cfranext;
}
else {
- *nextfra = CFRA + (CFRA - cfraprev);
+ *r_nextfra = CFRA + (CFRA - cfraprev);
}
return true;
diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c
index 2215021ce1a..8b0e9b22ce8 100644
--- a/source/blender/editors/animation/anim_markers.c
+++ b/source/blender/editors/animation/anim_markers.c
@@ -197,7 +197,7 @@ int ED_markers_find_nearest_marker_time(ListBase *markers, float x)
return (nearest) ? (nearest->frame) : round_fl_to_int(x);
}
-void ED_markers_get_minmax(ListBase *markers, short sel, float *first, float *last)
+void ED_markers_get_minmax(ListBase *markers, short sel, float *r_first, float *r_last)
{
TimeMarker *marker;
float min, max;
@@ -205,8 +205,8 @@ void ED_markers_get_minmax(ListBase *markers, short sel, float *first, float *la
/* sanity check */
// printf("markers = %p - %p, %p\n", markers, markers->first, markers->last);
if (ELEM(NULL, markers, markers->first, markers->last)) {
- *first = 0.0f;
- *last = 0.0f;
+ *r_first = 0.0f;
+ *r_last = 0.0f;
return;
}
@@ -224,8 +224,8 @@ void ED_markers_get_minmax(ListBase *markers, short sel, float *first, float *la
}
/* set the min/max values */
- *first = min;
- *last = max;
+ *r_first = min;
+ *r_last = max;
}
/**
@@ -235,6 +235,9 @@ void ED_markers_get_minmax(ListBase *markers, short sel, float *first, float *la
static bool ED_operator_markers_region_active(bContext *C)
{
ScrArea *sa = CTX_wm_area(C);
+ if (sa == NULL) {
+ return false;
+ }
switch (sa->spacetype) {
case SPACE_ACTION: {
diff --git a/source/blender/editors/armature/armature_add.c b/source/blender/editors/armature/armature_add.c
index e87040279af..1105633f47e 100644
--- a/source/blender/editors/armature/armature_add.c
+++ b/source/blender/editors/armature/armature_add.c
@@ -742,7 +742,7 @@ static int armature_symmetrize_exec(bContext *C, wmOperator *op)
}
}
- /* Find the selected bones and duplicate them as needed, with mirrored name */
+ /* Find the selected bones and duplicate them as needed, with mirrored name. */
for (ebone_iter = arm->edbo->first; ebone_iter && ebone_iter != ebone_first_dupe;
ebone_iter = ebone_iter->next) {
if (EBONE_VISIBLE(arm, ebone_iter) && (ebone_iter->flag & BONE_SELECTED) &&
@@ -765,7 +765,7 @@ static int armature_symmetrize_exec(bContext *C, wmOperator *op)
}
}
- /* Run through the list and fix the pointers */
+ /* Run through the list and fix the pointers. */
for (ebone_iter = arm->edbo->first; ebone_iter && ebone_iter != ebone_first_dupe;
ebone_iter = ebone_iter->next) {
if (ebone_iter->temp.ebone) {
@@ -1116,7 +1116,7 @@ static int armature_bone_primitive_add_exec(bContext *C, wmOperator *op)
ED_armature_edit_deselect_all(obedit);
- /* Create a bone */
+ /* Create a bone. */
bone = ED_armature_ebone_add(obedit->data, name);
copy_v3_v3(bone->head, curs);
diff --git a/source/blender/editors/armature/armature_edit.c b/source/blender/editors/armature/armature_edit.c
index 4285c7779d7..9a640952253 100644
--- a/source/blender/editors/armature/armature_edit.c
+++ b/source/blender/editors/armature/armature_edit.c
@@ -61,7 +61,10 @@
#include "armature_intern.h"
-/* ************************** Object Tools Exports ******************************* */
+/* -------------------------------------------------------------------- */
+/** \name Object Tools Public API
+ * \{ */
+
/* NOTE: these functions are exported to the Object module to be called from the tools there */
/**
@@ -178,7 +181,11 @@ void ED_armature_origin_set(
}
}
-/* ********************************* Roll ******************************* */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Bone Roll Calculate Operator
+ * \{ */
/* adjust bone roll to align Z axis with vector
* vec is in local space and is normalized
@@ -549,7 +556,11 @@ void ARMATURE_OT_roll_clear(wmOperatorType *ot)
DEG2RADF(360.0f));
}
-/* ******************************** Chain-Based Tools ********************************* */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Chain-Based Tool Utilities
+ * \{ */
/* temporary data-structure for merge/fill bones */
typedef struct EditBonePoint {
@@ -616,7 +627,11 @@ static void chains_find_tips(ListBase *edbo, ListBase *list)
}
}
-/* --------------------- */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Fill Operator
+ * \{ */
static void fill_add_joint(EditBone *ebo, short eb_tail, ListBase *points)
{
@@ -871,216 +886,15 @@ void ARMATURE_OT_fill(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/* --------------------- */
-
-/* this function merges between two bones, removes them and those in-between,
- * and adjusts the parent relationships for those in-between
- */
-static void bones_merge(
- Object *obedit, EditBone *start, EditBone *end, EditBone *endchild, ListBase *chains)
-{
- bArmature *arm = obedit->data;
- EditBone *ebo, *ebone, *newbone;
- LinkData *chain;
- float head[3], tail[3];
-
- /* check if same bone */
- if (start == end) {
- if (G.debug & G_DEBUG) {
- printf("Error: same bone!\n");
- printf("\tstart = %s, end = %s\n", start->name, end->name);
- }
- }
-
- /* step 1: add a new bone
- * - head = head/tail of start (default head)
- * - tail = head/tail of end (default tail)
- * - parent = parent of start
- */
- if ((start->flag & BONE_TIPSEL) && (start->flag & BONE_SELECTED) == 0) {
- copy_v3_v3(head, start->tail);
- }
- else {
- copy_v3_v3(head, start->head);
- }
- if ((end->flag & BONE_ROOTSEL) && (end->flag & BONE_SELECTED) == 0) {
- copy_v3_v3(tail, end->head);
- }
- else {
- copy_v3_v3(tail, end->tail);
- }
- newbone = add_points_bone(obedit, head, tail);
- newbone->parent = start->parent;
-
- /* TODO, copy more things to the new bone */
- newbone->flag = start->flag & (BONE_HINGE | BONE_NO_DEFORM | BONE_NO_CYCLICOFFSET |
- BONE_NO_LOCAL_LOCATION | BONE_DONE);
-
- newbone->inherit_scale_mode = start->inherit_scale_mode;
-
- /* Step 2a: reparent any side chains which may be parented to any bone in the chain
- * of bones to merge - potentially several tips for side chains leading to some tree exist.
- */
- for (chain = chains->first; chain; chain = chain->next) {
- /* Traverse down chain until we hit the bottom or if we run into the tip of the chain of bones
- * we're merging (need to stop in this case to avoid corrupting this chain too!).
- */
- for (ebone = chain->data; (ebone) && (ebone != end); ebone = ebone->parent) {
- short found = 0;
-
- /* Check if this bone is parented to one in the merging chain
- * ! WATCHIT: must only go check until end of checking chain
- */
- for (ebo = end; (ebo) && (ebo != start->parent); ebo = ebo->parent) {
- /* side-chain found? --> remap parent to new bone, then we're done with this chain :) */
- if (ebone->parent == ebo) {
- ebone->parent = newbone;
- found = 1;
- break;
- }
- }
-
- /* carry on to the next tip now */
- if (found) {
- break;
- }
- }
- }
-
- /* step 2b: parent child of end to newbone (child from this chain) */
- if (endchild) {
- endchild->parent = newbone;
- }
-
- /* step 3: delete all bones between and including start and end */
- for (ebo = end; ebo; ebo = ebone) {
- ebone = (ebo == start) ? (NULL) : (ebo->parent);
- bone_free(arm, ebo);
- }
-
- newbone->flag |= (BONE_ROOTSEL | BONE_TIPSEL | BONE_SELECTED);
- ED_armature_edit_sync_selection(arm->edbo);
-}
-
-static int armature_merge_exec(bContext *C, wmOperator *op)
-{
- ViewLayer *view_layer = CTX_data_view_layer(C);
- const short type = RNA_enum_get(op->ptr, "type");
-
- uint objects_len = 0;
- Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &objects_len);
-
- for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
- Object *obedit = objects[ob_index];
- bArmature *arm = obedit->data;
-
- /* for now, there's only really one type of merging that's performed... */
- if (type == 1) {
- /* go down chains, merging bones */
- ListBase chains = {NULL, NULL};
- LinkData *chain, *nchain;
- EditBone *ebo;
-
- armature_tag_select_mirrored(arm);
-
- /* get chains (ends on chains) */
- chains_find_tips(arm->edbo, &chains);
- if (BLI_listbase_is_empty(&chains)) {
- continue;
- }
-
- /* each 'chain' is the last bone in the chain (with no children) */
- for (chain = chains.first; chain; chain = nchain) {
- EditBone *bstart = NULL, *bend = NULL;
- EditBone *bchild = NULL, *child = NULL;
-
- /* temporarily remove chain from list of chains */
- nchain = chain->next;
- BLI_remlink(&chains, chain);
-
- /* only consider bones that are visible and selected */
- for (ebo = chain->data; ebo; child = ebo, ebo = ebo->parent) {
- /* check if visible + selected */
- if (EBONE_VISIBLE(arm, ebo) && ((ebo->flag & BONE_CONNECTED) || (ebo->parent == NULL)) &&
- (ebo->flag & BONE_SELECTED)) {
- /* set either end or start (end gets priority, unless it is already set) */
- if (bend == NULL) {
- bend = ebo;
- bchild = child;
- }
- else {
- bstart = ebo;
- }
- }
- else {
- /* chain is broken... merge any continuous segments then clear */
- if (bstart && bend) {
- bones_merge(obedit, bstart, bend, bchild, &chains);
- }
-
- bstart = NULL;
- bend = NULL;
- bchild = NULL;
- }
- }
-
- /* merge from bstart to bend if something not merged */
- if (bstart && bend) {
- bones_merge(obedit, bstart, bend, bchild, &chains);
- }
-
- /* put back link */
- BLI_insertlinkbefore(&chains, nchain, chain);
- }
-
- armature_tag_unselect(arm);
-
- BLI_freelistN(&chains);
- }
-
- /* updates */
- ED_armature_edit_sync_selection(arm->edbo);
- ED_armature_edit_refresh_layer_used(arm);
- WM_event_add_notifier(C, NC_OBJECT | ND_POSE, obedit);
- DEG_id_tag_update(&arm->id, ID_RECALC_COPY_ON_WRITE);
- }
- MEM_freeN(objects);
-
- return OPERATOR_FINISHED;
-}
-
-void ARMATURE_OT_merge(wmOperatorType *ot)
-{
- static const EnumPropertyItem merge_types[] = {
- {1, "WITHIN_CHAIN", 0, "Within Chains", ""},
- {0, NULL, 0, NULL, NULL},
- };
-
- /* identifiers */
- ot->name = "Merge Bones";
- ot->idname = "ARMATURE_OT_merge";
- ot->description = "Merge continuous chains of selected bones";
-
- /* callbacks */
- ot->invoke = WM_menu_invoke;
- ot->exec = armature_merge_exec;
- ot->poll = ED_operator_editarmature;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- /* properties */
- ot->prop = RNA_def_enum(ot->srna, "type", merge_types, 0, "Type", "");
-}
-
-/* --------------------- */
+/** \} */
-/* Switch Direction operator:
+/* -------------------------------------------------------------------- */
+/** \name Switch Direction Operator
+ *
* Currently, this does not use context loops, as context loops do not make it
* easy to retrieve any hierarchical/chain relationships which are necessary for
* this to be done easily.
- */
+ * \{ */
/* helper to clear BONE_TRANSFORM flags */
static void armature_clear_swap_done_flags(bArmature *arm)
@@ -1210,7 +1024,11 @@ void ARMATURE_OT_switch_direction(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/* ********************************* Align ******************************* */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Align Operator
+ * \{ */
/* helper to fix a ebone position if its parent has moved due to alignment*/
static void fix_connected_bone(EditBone *ebone)
@@ -1354,7 +1172,11 @@ void ARMATURE_OT_align(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/* ********************************* Split ******************************* */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Split Operator
+ * \{ */
static int armature_split_exec(bContext *C, wmOperator *UNUSED(op))
{
@@ -1400,7 +1222,11 @@ void ARMATURE_OT_split(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/* ********************************* Delete ******************************* */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Delete Operator
+ * \{ */
static bool armature_delete_ebone_cb(const char *bone_name, void *arm_p)
{
@@ -1658,7 +1484,11 @@ void ARMATURE_OT_dissolve(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/* ********************************* Show/Hide ******************************* */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Hide Operator
+ * \{ */
static int armature_hide_exec(bContext *C, wmOperator *op)
{
@@ -1719,6 +1549,12 @@ void ARMATURE_OT_hide(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Hide unselected rather than selected");
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Reveal Operator
+ * \{ */
+
static int armature_reveal_exec(bContext *C, wmOperator *op)
{
ViewLayer *view_layer = CTX_data_view_layer(C);
@@ -1771,3 +1607,5 @@ void ARMATURE_OT_reveal(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "select", true, "Select", "");
}
+
+/** \} */
diff --git a/source/blender/editors/armature/armature_intern.h b/source/blender/editors/armature/armature_intern.h
index fa562ab0f44..37f0c7197a9 100644
--- a/source/blender/editors/armature/armature_intern.h
+++ b/source/blender/editors/armature/armature_intern.h
@@ -59,6 +59,7 @@ void ARMATURE_OT_select_mirror(struct wmOperatorType *ot);
void ARMATURE_OT_select_more(struct wmOperatorType *ot);
void ARMATURE_OT_select_less(struct wmOperatorType *ot);
void ARMATURE_OT_select_hierarchy(struct wmOperatorType *ot);
+void ARMATURE_OT_select_linked_pick(struct wmOperatorType *ot);
void ARMATURE_OT_select_linked(struct wmOperatorType *ot);
void ARMATURE_OT_select_similar(struct wmOperatorType *ot);
void ARMATURE_OT_shortest_path_pick(struct wmOperatorType *ot);
@@ -72,7 +73,6 @@ void ARMATURE_OT_hide(struct wmOperatorType *ot);
void ARMATURE_OT_reveal(struct wmOperatorType *ot);
void ARMATURE_OT_click_extrude(struct wmOperatorType *ot);
void ARMATURE_OT_fill(struct wmOperatorType *ot);
-void ARMATURE_OT_merge(struct wmOperatorType *ot);
void ARMATURE_OT_separate(struct wmOperatorType *ot);
void ARMATURE_OT_split(struct wmOperatorType *ot);
diff --git a/source/blender/editors/armature/armature_ops.c b/source/blender/editors/armature/armature_ops.c
index a29d0f5f158..b304ce92a54 100644
--- a/source/blender/editors/armature/armature_ops.c
+++ b/source/blender/editors/armature/armature_ops.c
@@ -56,6 +56,7 @@ void ED_operatortypes_armature(void)
WM_operatortype_append(ARMATURE_OT_select_less);
WM_operatortype_append(ARMATURE_OT_select_hierarchy);
WM_operatortype_append(ARMATURE_OT_select_linked);
+ WM_operatortype_append(ARMATURE_OT_select_linked_pick);
WM_operatortype_append(ARMATURE_OT_select_similar);
WM_operatortype_append(ARMATURE_OT_shortest_path_pick);
@@ -68,7 +69,6 @@ void ED_operatortypes_armature(void)
WM_operatortype_append(ARMATURE_OT_reveal);
WM_operatortype_append(ARMATURE_OT_click_extrude);
WM_operatortype_append(ARMATURE_OT_fill);
- WM_operatortype_append(ARMATURE_OT_merge);
WM_operatortype_append(ARMATURE_OT_separate);
WM_operatortype_append(ARMATURE_OT_split);
diff --git a/source/blender/editors/armature/armature_relations.c b/source/blender/editors/armature/armature_relations.c
index 2c2bf3cd283..4580d2c30ae 100644
--- a/source/blender/editors/armature/armature_relations.c
+++ b/source/blender/editors/armature/armature_relations.c
@@ -280,7 +280,7 @@ int join_armature_exec(bContext *C, wmOperator *op)
float mat[4][4], oimat[4][4];
bool ok = false;
- /* Ensure we're not in editmode and that the active object is an armature*/
+ /* Ensure we're not in edit-mode and that the active object is an armature. */
if (!ob_active || ob_active->type != OB_ARMATURE) {
return OPERATOR_CANCELLED;
}
diff --git a/source/blender/editors/armature/armature_select.c b/source/blender/editors/armature/armature_select.c
index 21eccd2ca1f..99dcd5bb42b 100644
--- a/source/blender/editors/armature/armature_select.c
+++ b/source/blender/editors/armature/armature_select.c
@@ -59,7 +59,9 @@
#define EBONE_PREV_FLAG_GET(ebone) ((void)0, (ebone)->temp.i)
#define EBONE_PREV_FLAG_SET(ebone, val) ((ebone)->temp.i = val)
-/* **************** PoseMode & EditMode Selection Buffer Queries *************************** */
+/* -------------------------------------------------------------------- */
+/** \name Select Buffer Queries for PoseMode & EditMode
+ * \{ */
Base *ED_armature_base_and_ebone_from_select_buffer(Base **bases,
uint bases_len,
@@ -293,104 +295,245 @@ void *get_nearest_bone(bContext *C, const int xy[2], bool findunsel, Base **r_ba
return NULL;
}
-/* **************** EditMode stuff ********************** */
+/** \} */
-static int armature_select_linked_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+/* -------------------------------------------------------------------- */
+/** \name Select Linked Implementation
+ *
+ * Shared logic for select linked all/pick.
+ *
+ * Use #BONE_DONE flag to select linked.
+ * \{ */
+
+/**
+ * \param all_forks: Control how chains are stepped over.
+ * true: select all connected bones traveling up & down forks.
+ * false: select all parents and all children, but not the children of the root bone.
+ */
+static bool armature_select_linked_impl(Object *ob, const bool select, const bool all_forks)
{
- bArmature *arm;
- EditBone *bone, *curBone, *next;
- const bool sel = !RNA_boolean_get(op->ptr, "deselect");
+ bool changed = false;
+ bArmature *arm = ob->data;
- view3d_operator_needs_opengl(C);
- BKE_object_update_select_id(CTX_data_main(C));
+ /* Implementation note, this flood-fills selected bones with the 'TOUCH' flag,
+ * even though this is a loop-within a loop, walking up the parent chain only touches new bones.
+ * Bones that have been touched are skipped, so the complexity is OK. */
- Base *base = NULL;
- bone = get_nearest_bone(C, event->mval, true, &base);
+ enum {
+ /* Bone has been walked over, it's LINK value can be read. */
+ TOUCH = (1 << 0),
+ /* When TOUCH has been set, this flag can be checked to see if the bone is connected. */
+ LINK = (1 << 1),
+ };
- if (!bone) {
- return OPERATOR_CANCELLED;
+#define CHECK_PARENT(ebone) \
+ (((ebone)->flag & BONE_CONNECTED) && \
+ ((ebone)->parent ? EBONE_SELECTABLE(arm, (ebone)->parent) : false))
+
+ for (EditBone *ebone = arm->edbo->first; ebone; ebone = ebone->next) {
+ ebone->temp.i = 0;
}
- arm = base->object->data;
+ /* Select parents. */
+ for (EditBone *ebone_iter = arm->edbo->first; ebone_iter; ebone_iter = ebone_iter->next) {
+ if (ebone_iter->temp.i & TOUCH) {
+ continue;
+ }
+ if ((ebone_iter->flag & BONE_DONE) == 0) {
+ continue;
+ }
+
+ ebone_iter->temp.i |= TOUCH | LINK;
- /* Select parents */
- for (curBone = bone; curBone; curBone = next) {
- if ((curBone->flag & BONE_UNSELECTABLE) == 0) {
- if (sel) {
- curBone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
+ /* We have an un-touched link. */
+ for (EditBone *ebone = ebone_iter; ebone; ebone = CHECK_PARENT(ebone) ? ebone->parent : NULL) {
+ ED_armature_ebone_select_set(ebone, select);
+ changed = true;
+
+ if (all_forks) {
+ ebone->temp.i |= (TOUCH | LINK);
}
else {
- curBone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
+ ebone->temp.i |= TOUCH;
+ }
+ /* Don't walk onto links (messes up 'all_forks' logic). */
+ if (ebone->parent && ebone->parent->temp.i & LINK) {
+ break;
}
}
+ }
- if (curBone->flag & BONE_CONNECTED) {
- next = curBone->parent;
+ /* Select children. */
+ for (EditBone *ebone_iter = arm->edbo->first; ebone_iter; ebone_iter = ebone_iter->next) {
+ /* No need to 'touch' this bone as it won't be walked over when scanning up the chain. */
+ if (!CHECK_PARENT(ebone_iter)) {
+ continue;
}
- else {
- next = NULL;
+ if (ebone_iter->temp.i & TOUCH) {
+ continue;
}
- }
- /* Select children */
- while (bone) {
- for (curBone = arm->edbo->first; curBone; curBone = next) {
- next = curBone->next;
- if ((curBone->parent == bone) && (curBone->flag & BONE_UNSELECTABLE) == 0) {
- if (curBone->flag & BONE_CONNECTED) {
- if (sel) {
- curBone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
- }
- else {
- curBone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
- }
- bone = curBone;
- break;
- }
- else {
- bone = NULL;
- break;
+ /* First check if we're marked. */
+ EditBone *ebone_touched_parent = NULL;
+ for (EditBone *ebone = ebone_iter; ebone; ebone = CHECK_PARENT(ebone) ? ebone->parent : NULL) {
+ if (ebone->temp.i & TOUCH) {
+ ebone_touched_parent = ebone;
+ break;
+ }
+ ebone->temp.i |= TOUCH;
+ }
+
+ if ((ebone_touched_parent != NULL) && (ebone_touched_parent->temp.i & LINK)) {
+ for (EditBone *ebone = ebone_iter; ebone != ebone_touched_parent; ebone = ebone->parent) {
+ if ((ebone->temp.i & LINK) == 0) {
+ ebone->temp.i |= LINK;
+ ED_armature_ebone_select_set(ebone, select);
+ changed = true;
}
}
}
- if (!curBone) {
- bone = NULL;
+ }
+
+#undef CHECK_PARENT
+
+ if (changed) {
+ ED_armature_edit_sync_selection(arm->edbo);
+ DEG_id_tag_update(&arm->id, ID_RECALC_COPY_ON_WRITE);
+ WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, ob);
+ }
+
+ return changed;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select Linked Operator
+ * \{ */
+
+static int armature_select_linked_exec(bContext *C, wmOperator *op)
+{
+ const bool all_forks = RNA_boolean_get(op->ptr, "all_forks");
+
+ bool changed_multi = false;
+ 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(
+ view_layer, CTX_wm_view3d(C), &objects_len);
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *ob = objects[ob_index];
+ bArmature *arm = ob->data;
+
+ bool found = false;
+ for (EditBone *ebone = arm->edbo->first; ebone; ebone = ebone->next) {
+ if (EBONE_VISIBLE(arm, ebone) &&
+ (ebone->flag & (BONE_SELECTED | BONE_ROOTSEL | BONE_TIPSEL))) {
+ ebone->flag |= BONE_DONE;
+ found = true;
+ }
+ else {
+ ebone->flag &= ~BONE_DONE;
+ }
+ }
+
+ if (found) {
+ if (armature_select_linked_impl(ob, true, all_forks)) {
+ changed_multi = true;
+ }
}
}
+ MEM_freeN(objects);
- ED_outliner_select_sync_from_edit_bone_tag(C);
+ if (changed_multi) {
+ ED_outliner_select_sync_from_edit_bone_tag(C);
+ }
+ return OPERATOR_FINISHED;
+}
- ED_armature_edit_sync_selection(arm->edbo);
+void ARMATURE_OT_select_linked(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Select Linked All";
+ ot->idname = "ARMATURE_OT_select_linked";
+ ot->description = "Select all bones linked by parent/child connections to the current selection";
+
+ /* api callbacks */
+ ot->exec = armature_select_linked_exec;
+ ot->poll = ED_operator_editarmature;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* Leave disabled by default as this matches pose mode. */
+ RNA_def_boolean(ot->srna, "all_forks", 0, "All Forks", "Follow forks in the parents chain");
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select Linked (Cursor Pick) Operator
+ * \{ */
- WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, base->object);
- DEG_id_tag_update(&arm->id, ID_RECALC_COPY_ON_WRITE);
+static int armature_select_linked_pick_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ const bool select = !RNA_boolean_get(op->ptr, "deselect");
+ const bool all_forks = RNA_boolean_get(op->ptr, "all_forks");
+
+ view3d_operator_needs_opengl(C);
+ BKE_object_update_select_id(CTX_data_main(C));
+
+ Base *base = NULL;
+ EditBone *ebone_active = get_nearest_bone(C, event->mval, true, &base);
+ bArmature *arm = base->object->data;
+
+ if (ebone_active == NULL || !EBONE_SELECTABLE(arm, ebone_active)) {
+ return OPERATOR_CANCELLED;
+ }
+
+ /* Initialize flags. */
+ for (EditBone *ebone = arm->edbo->first; ebone; ebone = ebone->next) {
+ ebone->flag &= ~BONE_DONE;
+ }
+ ebone_active->flag |= BONE_DONE;
+
+ if (armature_select_linked_impl(base->object, select, all_forks)) {
+ ED_outliner_select_sync_from_edit_bone_tag(C);
+ }
return OPERATOR_FINISHED;
}
-static bool armature_select_linked_poll(bContext *C)
+static bool armature_select_linked_pick_poll(bContext *C)
{
return (ED_operator_view3d_active(C) && ED_operator_editarmature(C));
}
-void ARMATURE_OT_select_linked(wmOperatorType *ot)
+void ARMATURE_OT_select_linked_pick(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Select Connected";
- ot->idname = "ARMATURE_OT_select_linked";
- ot->description = "Select bones related to selected ones by parent/child relationships";
+ ot->name = "Select Linked";
+ ot->idname = "ARMATURE_OT_select_linked_pick";
+ ot->description = "(De)select bones linked by parent/child connections under the mouse cursor";
/* api callbacks */
/* leave 'exec' unset */
- ot->invoke = armature_select_linked_invoke;
- ot->poll = armature_select_linked_poll;
+ ot->invoke = armature_select_linked_pick_invoke;
+ ot->poll = armature_select_linked_pick_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
RNA_def_boolean(ot->srna, "deselect", 0, "Deselect", "");
+ /* Leave disabled by default as this matches pose mode. */
+ RNA_def_boolean(ot->srna, "all_forks", 0, "All Forks", "Follow forks in the parents chain");
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select Buffer Queries EditMode
+ * \{ */
+
/* utility function for get_nearest_editbonepoint */
static int selectbuffer_ret_hits_12(unsigned int *UNUSED(buffer), const int hits12)
{
@@ -595,6 +738,12 @@ cache_end:
return NULL;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select Utility Functions
+ * \{ */
+
bool ED_armature_edit_deselect_all(Object *obedit)
{
bArmature *arm = obedit->data;
@@ -661,6 +810,12 @@ bool ED_armature_edit_deselect_all_visible_multi(bContext *C)
return changed_multi;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Cursor Picking API
+ * \{ */
+
/* accounts for connected parents */
static int ebone_select_flag(EditBone *ebone)
{
@@ -800,6 +955,8 @@ bool ED_armature_edit_select_pick(
return false;
}
+/** \} */
+
/* -------------------------------------------------------------------- */
/** \name Select Op From Tagged
*
@@ -984,7 +1141,9 @@ bool ED_armature_edit_select_op_from_tagged(bArmature *arm, const int sel_op)
/** \} */
-/* **************** Selections ******************/
+/* -------------------------------------------------------------------- */
+/** \name (De)Select All Operator
+ * \{ */
static int armature_de_select_all_exec(bContext *C, wmOperator *op)
{
@@ -1003,7 +1162,7 @@ static int armature_de_select_all_exec(bContext *C, wmOperator *op)
CTX_DATA_END;
}
- /* Set the flags */
+ /* Set the flags. */
CTX_DATA_BEGIN (C, EditBone *, ebone, visible_bones) {
/* ignore bone if selection can't change */
switch (action) {
@@ -1063,7 +1222,11 @@ void ARMATURE_OT_select_all(wmOperatorType *ot)
WM_operator_properties_select_all(ot);
}
-/**************** Select more/less **************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select More/Less Implementation
+ * \{ */
static void armature_select_more(bArmature *arm, EditBone *ebone)
{
@@ -1150,6 +1313,12 @@ static void armature_select_more_less(Object *ob, bool more)
ED_armature_edit_sync_selection(arm->edbo);
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select More Operator
+ * \{ */
+
static int armature_de_select_more_exec(bContext *C, wmOperator *UNUSED(op))
{
ViewLayer *view_layer = CTX_data_view_layer(C);
@@ -1183,6 +1352,12 @@ void ARMATURE_OT_select_more(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select Less Operator
+ * \{ */
+
static int armature_de_select_less_exec(bContext *C, wmOperator *UNUSED(op))
{
ViewLayer *view_layer = CTX_data_view_layer(C);
@@ -1216,6 +1391,12 @@ void ARMATURE_OT_select_less(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select Similar
+ * \{ */
+
enum {
SIMEDBONE_CHILDREN = 1,
SIMEDBONE_CHILDREN_IMMEDIATE,
@@ -1631,7 +1812,11 @@ void ARMATURE_OT_select_similar(wmOperatorType *ot)
RNA_def_float(ot->srna, "threshold", 0.1f, 0.0f, 1.0f, "Threshold", "", 0.0f, 1.0f);
}
-/* ********************* select hierarchy operator ************** */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select Hierarchy Operator
+ * \{ */
/* No need to convert to multi-objects. Just like we keep the non-active bones
* selected we then keep the non-active objects untouched (selected/unselected). */
@@ -1737,7 +1922,11 @@ void ARMATURE_OT_select_hierarchy(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend the selection");
}
-/****************** Mirror Select ****************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select Mirror Operator
+ * \{ */
/**
* \note clone of #pose_select_mirror_exec keep in sync
@@ -1822,7 +2011,11 @@ void ARMATURE_OT_select_mirror(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend the selection");
}
-/****************** Select Path ****************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select Path Operator
+ * \{ */
static bool armature_shortest_path_select(
bArmature *arm, EditBone *ebone_parent, EditBone *ebone_child, bool use_parent, bool is_test)
@@ -1948,3 +2141,5 @@ void ARMATURE_OT_shortest_path_pick(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+
+/** \} */
diff --git a/source/blender/editors/armature/armature_utils.c b/source/blender/editors/armature/armature_utils.c
index 76361f6785b..58ceef5b7db 100644
--- a/source/blender/editors/armature/armature_utils.c
+++ b/source/blender/editors/armature/armature_utils.c
@@ -562,7 +562,7 @@ static EditBone *make_boneList_rec(ListBase *edbo,
BLI_addtail(edbo, eBone);
- /* Add children if necessary */
+ /* Add children if necessary. */
if (curBone->childbase.first) {
eBoneTest = make_boneList_rec(edbo, &curBone->childbase, eBone, actBone);
if (eBoneTest) {
@@ -721,7 +721,7 @@ void ED_armature_from_edit(Main *bmain, bArmature *arm)
}
}
- /* Copy the bones from the editData into the armature */
+ /* Copy the bones from the edit-data into the armature. */
for (eBone = arm->edbo->first; eBone; eBone = eBone->next) {
newBone = MEM_callocN(sizeof(Bone), "bone");
eBone->temp.bone = newBone; /* Associate the real Bones with the EditBones */
@@ -819,7 +819,7 @@ void ED_armature_edit_free(struct bArmature *arm)
{
EditBone *eBone;
- /* Clear the editbones list */
+ /* Clear the edit-bones list. */
if (arm->edbo) {
if (arm->edbo->first) {
for (eBone = arm->edbo->first; eBone; eBone = eBone->next) {
diff --git a/source/blender/editors/armature/pose_select.c b/source/blender/editors/armature/pose_select.c
index 07be2baf1ae..475640fa37c 100644
--- a/source/blender/editors/armature/pose_select.c
+++ b/source/blender/editors/armature/pose_select.c
@@ -497,7 +497,7 @@ static int pose_de_select_all_exec(bContext *C, wmOperator *op)
Object *ob_prev = NULL;
- /* Set the flags */
+ /* Set the flags. */
CTX_DATA_BEGIN_WITH_ID (C, bPoseChannel *, pchan, visible_pose_bones, Object *, ob) {
bArmature *arm = ob->data;
pose_do_bone_select(pchan, action);
diff --git a/source/blender/editors/datafiles/CMakeLists.txt b/source/blender/editors/datafiles/CMakeLists.txt
index 1b147663a7e..1bc0465424d 100644
--- a/source/blender/editors/datafiles/CMakeLists.txt
+++ b/source/blender/editors/datafiles/CMakeLists.txt
@@ -766,8 +766,6 @@ set_property(GLOBAL PROPERTY ICON_GEOM_NAMES
)
data_to_c_simple(../../../../release/datafiles/bfont.pfb SRC)
-data_to_c_simple(../../../../release/datafiles/bfont.ttf SRC)
-data_to_c_simple(../../../../release/datafiles/bmonofont.ttf SRC)
if(WITH_BLENDER)
# blender only (not player)
diff --git a/source/blender/editors/gpencil/annotate_draw.c b/source/blender/editors/gpencil/annotate_draw.c
index 5c396ca9041..fc62defd757 100644
--- a/source/blender/editors/gpencil/annotate_draw.c
+++ b/source/blender/editors/gpencil/annotate_draw.c
@@ -209,7 +209,6 @@ static void annotation_calc_2d_stroke_fxy(
/* draw a given stroke - just a single dot (only one point) */
static void annotation_draw_stroke_point(const bGPDspoint *points,
short thickness,
- short UNUSED(dflag),
short sflag,
int offsx,
int offsy,
@@ -252,12 +251,8 @@ static void annotation_draw_stroke_point(const bGPDspoint *points,
}
/* draw a given stroke in 3d (i.e. in 3d-space), using simple ogl lines */
-static void annotation_draw_stroke_3d(const bGPDspoint *points,
- int totpoints,
- short thickness,
- short UNUSED(sflag),
- const float ink[4],
- bool cyclic)
+static void annotation_draw_stroke_3d(
+ const bGPDspoint *points, int totpoints, short thickness, const float ink[4], bool cyclic)
{
float curpressure = points[0].pressure;
float cyclic_fpt[3];
@@ -550,9 +545,7 @@ static bool annotation_can_draw_stroke(const bGPDstroke *gps, const int dflag)
}
/* draw a set of strokes */
-static void annotation_draw_strokes(bGPdata *UNUSED(gpd),
- bGPDlayer *UNUSED(gpl),
- const bGPDframe *gpf,
+static void annotation_draw_strokes(const bGPDframe *gpf,
int offsx,
int offsy,
int winx,
@@ -587,11 +580,11 @@ static void annotation_draw_strokes(bGPdata *UNUSED(gpd),
/* 3D Lines - OpenGL primitives-based */
if (gps->totpoints == 1) {
annotation_draw_stroke_point(
- gps->points, lthick, dflag, gps->flag, offsx, offsy, winx, winy, color);
+ gps->points, lthick, gps->flag, offsx, offsy, winx, winy, color);
}
else {
annotation_draw_stroke_3d(
- gps->points, gps->totpoints, lthick, gps->flag, color, gps->flag & GP_STROKE_CYCLIC);
+ gps->points, gps->totpoints, lthick, color, gps->flag & GP_STROKE_CYCLIC);
}
if (no_xray) {
@@ -605,7 +598,7 @@ static void annotation_draw_strokes(bGPdata *UNUSED(gpd),
/* 2D Strokes... */
if (gps->totpoints == 1) {
annotation_draw_stroke_point(
- gps->points, lthick, dflag, gps->flag, offsx, offsy, winx, winy, color);
+ gps->points, lthick, gps->flag, offsx, offsy, winx, winy, color);
}
else {
annotation_draw_stroke_2d(gps->points,
@@ -626,15 +619,13 @@ static void annotation_draw_strokes(bGPdata *UNUSED(gpd),
}
/* Draw selected verts for strokes being edited */
-static void annotation_draw_strokes_edit(bGPdata *UNUSED(gpd),
- bGPDlayer *gpl,
+static void annotation_draw_strokes_edit(bGPDlayer *gpl,
const bGPDframe *gpf,
int offsx,
int offsy,
int winx,
int winy,
short dflag,
- short UNUSED(lflag),
float alpha)
{
/* if alpha 0 do not draw */
@@ -754,15 +745,8 @@ static void annotation_draw_strokes_edit(bGPdata *UNUSED(gpd),
/* ----- General Drawing ------ */
/* draw onion-skinning for a layer */
-static void annotation_draw_onionskins(bGPdata *gpd,
- bGPDlayer *gpl,
- bGPDframe *gpf,
- int offsx,
- int offsy,
- int winx,
- int winy,
- int UNUSED(cfra),
- int dflag)
+static void annotation_draw_onionskins(
+ bGPDlayer *gpl, bGPDframe *gpf, int offsx, int offsy, int winx, int winy, int dflag)
{
const float alpha = 1.0f;
float color[4];
@@ -781,8 +765,7 @@ static void annotation_draw_onionskins(bGPdata *gpd,
/* alpha decreases with distance from curframe index */
fac = 1.0f - ((float)(gpf->framenum - gf->framenum) / (float)(gpl->gstep + 1));
color[3] = alpha * fac * 0.66f;
- annotation_draw_strokes(
- gpd, gpl, gf, offsx, offsy, winx, winy, dflag, gpl->thickness, color);
+ annotation_draw_strokes(gf, offsx, offsy, winx, winy, dflag, gpl->thickness, color);
}
else {
break;
@@ -793,8 +776,7 @@ static void annotation_draw_onionskins(bGPdata *gpd,
/* draw the strokes for the ghost frames (at half of the alpha set by user) */
if (gpf->prev) {
color[3] = (alpha / 7);
- annotation_draw_strokes(
- gpd, gpl, gpf->prev, offsx, offsy, winx, winy, dflag, gpl->thickness, color);
+ annotation_draw_strokes(gpf->prev, offsx, offsy, winx, winy, dflag, gpl->thickness, color);
}
}
else {
@@ -815,8 +797,7 @@ static void annotation_draw_onionskins(bGPdata *gpd,
/* alpha decreases with distance from curframe index */
fac = 1.0f - ((float)(gf->framenum - gpf->framenum) / (float)(gpl->gstep_next + 1));
color[3] = alpha * fac * 0.66f;
- annotation_draw_strokes(
- gpd, gpl, gf, offsx, offsy, winx, winy, dflag, gpl->thickness, color);
+ annotation_draw_strokes(gf, offsx, offsy, winx, winy, dflag, gpl->thickness, color);
}
else {
break;
@@ -827,8 +808,7 @@ static void annotation_draw_onionskins(bGPdata *gpd,
/* draw the strokes for the ghost frames (at half of the alpha set by user) */
if (gpf->next) {
color[3] = (alpha / 4);
- annotation_draw_strokes(
- gpd, gpl, gpf->next, offsx, offsy, winx, winy, dflag, gpl->thickness, color);
+ annotation_draw_strokes(gpf->next, offsx, offsy, winx, winy, dflag, gpl->thickness, color);
}
}
else {
@@ -875,11 +855,11 @@ static void annotation_draw_data_layers(
/* Draw 'onionskins' (frame left + right) */
if (gpl->onion_flag & GP_LAYER_ONIONSKIN) {
- annotation_draw_onionskins(gpd, gpl, gpf, offsx, offsy, winx, winy, cfra, dflag);
+ annotation_draw_onionskins(gpl, gpf, offsx, offsy, winx, winy, dflag);
}
/* draw the strokes already in active frame */
- annotation_draw_strokes(gpd, gpl, gpf, offsx, offsy, winx, winy, dflag, lthick, ink);
+ annotation_draw_strokes(gpf, offsx, offsy, winx, winy, dflag, lthick, ink);
/* Draw verts of selected strokes:
* - when doing OpenGL renders, we don't want to be showing these, as that ends up flickering
@@ -892,8 +872,7 @@ static void annotation_draw_data_layers(
/* XXX: perhaps we don't want to show these when users are drawing... */
if ((G.f & G_FLAG_RENDER_VIEWPORT) == 0 && (gpl->flag & GP_LAYER_LOCKED) == 0 &&
(gpd->flag & GP_DATA_STROKE_EDITMODE)) {
- annotation_draw_strokes_edit(
- gpd, gpl, gpf, offsx, offsy, winx, winy, dflag, gpl->flag, alpha);
+ annotation_draw_strokes_edit(gpl, gpf, offsx, offsy, winx, winy, dflag, alpha);
}
/* Check if may need to draw the active stroke cache, only if this layer is the active layer
diff --git a/source/blender/editors/gpencil/annotate_paint.c b/source/blender/editors/gpencil/annotate_paint.c
index 9f2c4070b18..53ada341cc9 100644
--- a/source/blender/editors/gpencil/annotate_paint.c
+++ b/source/blender/editors/gpencil/annotate_paint.c
@@ -816,7 +816,6 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p,
bGPDframe *gpf,
bGPDstroke *gps,
const float mval[2],
- const float mvalo[2],
const int radius,
const rcti *rect)
{
@@ -885,7 +884,7 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p,
* eraser region (either within stroke painted, or on its lines)
* - this assumes that linewidth is irrelevant
*/
- if (gp_stroke_inside_circle(mval, mvalo, radius, pc1[0], pc1[1], pc2[0], pc2[1])) {
+ if (gp_stroke_inside_circle(mval, radius, pc1[0], pc1[1], pc2[0], pc2[1])) {
if ((gp_stroke_eraser_is_occluded(p, pt1, pc1[0], pc1[1]) == false) ||
(gp_stroke_eraser_is_occluded(p, pt2, pc2[0], pc2[1]) == false)) {
/* Edge is affected - Check individual points now */
@@ -938,7 +937,7 @@ static void gp_stroke_doeraser(tGPsdata *p)
* (e.g. 2D space strokes in the 3D view, if the same datablock is shared)
*/
if (ED_gpencil_stroke_can_use_direct(p->sa, gps)) {
- gp_stroke_eraser_dostroke(p, gpf, gps, p->mval, p->mvalo, p->radius, &rect);
+ gp_stroke_eraser_dostroke(p, gpf, gps, p->mval, p->radius, &rect);
}
}
}
diff --git a/source/blender/editors/gpencil/drawgpencil.c b/source/blender/editors/gpencil/drawgpencil.c
index 896ef7a9ad3..6d41e9bddbe 100644
--- a/source/blender/editors/gpencil/drawgpencil.c
+++ b/source/blender/editors/gpencil/drawgpencil.c
@@ -114,13 +114,6 @@ typedef enum eDrawStrokeFlags {
/* ----- Tool Buffer Drawing ------ */
/* helper functions to set color of buffer point */
-static void gp_set_point_uniform_color(const bGPDspoint *pt, const float ink[4])
-{
- float alpha = ink[3] * pt->strength;
- CLAMP(alpha, GPENCIL_STRENGTH_MIN, 1.0f);
- immUniformColor3fvAlpha(ink, alpha);
-}
-
static void gp_set_point_varying_color(const bGPDspoint *pt,
const float ink[4],
uint attr_id,
@@ -134,74 +127,8 @@ static void gp_set_point_varying_color(const bGPDspoint *pt,
immAttr4ub(attr_id, F2UB(ink[0]), F2UB(ink[1]), F2UB(ink[2]), F2UB(alpha));
}
-/* --------- 2D Stroke Drawing Helpers --------- */
-/* change in parameter list */
-static void gp_calc_2d_stroke_fxy(
- const float pt[3], short sflag, int offsx, int offsy, int winx, int winy, float r_co[2])
-{
- if (sflag & GP_STROKE_2DSPACE) {
- r_co[0] = pt[0];
- r_co[1] = pt[1];
- }
- else if (sflag & GP_STROKE_2DIMAGE) {
- const float x = (float)((pt[0] * winx) + offsx);
- const float y = (float)((pt[1] * winy) + offsy);
-
- r_co[0] = x;
- r_co[1] = y;
- }
- else {
- const float x = (float)(pt[0] / 100 * winx) + offsx;
- const float y = (float)(pt[1] / 100 * winy) + offsy;
-
- r_co[0] = x;
- r_co[1] = y;
- }
-}
/* ----------- Volumetric Strokes --------------- */
-/* draw a 2D strokes in "volumetric" style */
-static void gp_draw_stroke_volumetric_2d(const bGPDspoint *points,
- int totpoints,
- short thickness,
- short UNUSED(dflag),
- short sflag,
- int offsx,
- int offsy,
- int winx,
- int winy,
- const float diff_mat[4][4],
- const float ink[4])
-{
- GPUVertFormat *format = immVertexFormat();
- uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- uint size = GPU_vertformat_attr_add(format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
- uint color = GPU_vertformat_attr_add(
- format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
-
- immBindBuiltinProgram(GPU_SHADER_3D_POINT_VARYING_SIZE_VARYING_COLOR);
- GPU_program_point_size(true);
- immBegin(GPU_PRIM_POINTS, totpoints);
-
- const bGPDspoint *pt = points;
- for (int i = 0; i < totpoints; i++, pt++) {
- /* transform position to 2D */
- float co[2];
- float fpt[3];
-
- mul_v3_m4v3(fpt, diff_mat, &pt->x);
- gp_calc_2d_stroke_fxy(fpt, sflag, offsx, offsy, winx, winy, co);
-
- gp_set_point_varying_color(pt, ink, color, false);
- immAttr1f(size, pt->pressure * thickness); /* TODO: scale based on view transform */
- immVertex2f(pos, co[0], co[1]);
- }
-
- immEnd();
- immUnbindProgram();
- GPU_program_point_size(false);
-}
-
/* draw a 3D stroke in "volumetric" style */
static void gp_draw_stroke_volumetric_3d(const bGPDspoint *points,
int totpoints,
@@ -232,136 +159,8 @@ static void gp_draw_stroke_volumetric_3d(const bGPDspoint *points,
GPU_program_point_size(false);
}
-/* --------------- Stroke Fills ----------------- */
-/* add a new fill point and texture coordinates to vertex buffer */
-static void gp_add_filldata_tobuffer(const bGPDspoint *pt,
- uint pos,
- uint texcoord,
- short flag,
- int offsx,
- int offsy,
- int winx,
- int winy,
- const float diff_mat[4][4])
-{
- float fpt[3];
- float co[2];
-
- mul_v3_m4v3(fpt, diff_mat, &pt->x);
- /* if 2d, need conversion */
- if (!(flag & GP_STROKE_3DSPACE)) {
- gp_calc_2d_stroke_fxy(fpt, flag, offsx, offsy, winx, winy, co);
- copy_v2_v2(fpt, co);
- fpt[2] = 0.0f; /* 2d always is z=0.0f */
- }
-
- immAttr2f(texcoord, pt->uv_fill[0], pt->uv_fill[1]); /* texture coordinates */
- immVertex3fv(pos, fpt); /* position */
-}
-
-/* draw fills for shapes */
-static void gp_draw_stroke_fill(bGPdata *gpd,
- bGPDstroke *gps,
- int offsx,
- int offsy,
- int winx,
- int winy,
- const float diff_mat[4][4],
- const float color[4])
-{
- BLI_assert(gps->totpoints >= 3);
- BLI_assert(gps->tot_triangles >= 1);
- const bool use_mat = (gpd->mat != NULL);
-
- Material *ma = (use_mat) ? gpd->mat[gps->mat_nr] : BKE_material_default_gpencil();
- MaterialGPencilStyle *gp_style = (ma) ? ma->gp_style : NULL;
-
- GPUVertFormat *format = immVertexFormat();
- uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
- uint texcoord = GPU_vertformat_attr_add(format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_GPENCIL_FILL);
-
- immUniformColor4fv(color);
- immUniform4fv("color2", gp_style->mix_rgba);
- immUniform1i("fill_type", gp_style->fill_style);
- immUniform1f("mix_factor", gp_style->mix_factor);
-
- immUniform1f("texture_angle", gp_style->texture_angle);
- immUniform2fv("texture_scale", gp_style->texture_scale);
- immUniform2fv("texture_offset", gp_style->texture_offset);
- immUniform1f("texture_opacity", gp_style->texture_opacity);
- immUniform1i("t_mix", (gp_style->flag & GP_MATERIAL_FILL_TEX_MIX) != 0);
- immUniform1i("t_flip", (gp_style->flag & GP_MATERIAL_FLIP_FILL) != 0);
-
- /* Draw all triangles for filling the polygon (cache must be calculated before) */
- immBegin(GPU_PRIM_TRIS, gps->tot_triangles * 3);
- /* TODO: use batch instead of immediate mode, to share vertices */
-
- const bGPDtriangle *stroke_triangle = gps->triangles;
- for (int i = 0; i < gps->tot_triangles; i++, stroke_triangle++) {
- for (int j = 0; j < 3; j++) {
- gp_add_filldata_tobuffer(&gps->points[stroke_triangle->verts[j]],
- pos,
- texcoord,
- gps->flag,
- offsx,
- offsy,
- winx,
- winy,
- diff_mat);
- }
- }
-
- immEnd();
- immUnbindProgram();
-}
-
/* ----- Existing Strokes Drawing (3D and Point) ------ */
-/* draw a given stroke - just a single dot (only one point) */
-static void gp_draw_stroke_point(const bGPDspoint *points,
- short thickness,
- short UNUSED(dflag),
- short sflag,
- int offsx,
- int offsy,
- int winx,
- int winy,
- const float diff_mat[4][4],
- const float ink[4])
-{
- const bGPDspoint *pt = points;
-
- /* get final position using parent matrix */
- float fpt[3];
- mul_v3_m4v3(fpt, diff_mat, &pt->x);
-
- GPUVertFormat *format = immVertexFormat();
- uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
-
- if (sflag & GP_STROKE_3DSPACE) {
- immBindBuiltinProgram(GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA);
- }
- else {
- immBindBuiltinProgram(GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA);
-
- /* get 2D coordinates of point */
- float co[3] = {0.0f};
- gp_calc_2d_stroke_fxy(fpt, sflag, offsx, offsy, winx, winy, co);
- copy_v3_v3(fpt, co);
- }
-
- gp_set_point_uniform_color(pt, ink);
- /* set point thickness (since there's only one of these) */
- immUniform1f("size", (float)(thickness + 2) * pt->pressure);
-
- immBegin(GPU_PRIM_POINTS, 1);
- immVertex3fv(pos, fpt);
- immEnd();
-
- immUnbindProgram();
-}
-
/* draw a given stroke in 3d (i.e. in 3d-space) */
static void gp_draw_stroke_3d(tGPDdraw *tgpw, short thickness, const float ink[4], bool cyclic)
{
@@ -454,200 +253,6 @@ static void gp_draw_stroke_3d(tGPDdraw *tgpw, short thickness, const float ink[4
immUnbindProgram();
}
-/* ----- Fancy 2D-Stroke Drawing ------ */
-
-/* draw a given stroke in 2d */
-static void gp_draw_stroke_2d(const bGPDspoint *points,
- int totpoints,
- short thickness_s,
- short dflag,
- short sflag,
- bool UNUSED(debug),
- int offsx,
- int offsy,
- int winx,
- int winy,
- const float diff_mat[4][4],
- const float ink[4])
-{
- /* otherwise thickness is twice that of the 3D view */
- float thickness = (float)thickness_s * 0.5f;
-
- /* strokes in Image Editor need a scale factor, since units there are not pixels! */
- float scalefac = 1.0f;
- if ((dflag & GP_DRAWDATA_IEDITHACK) && (dflag & GP_DRAWDATA_ONLYV2D)) {
- scalefac = 0.001f;
- }
-
- /* TODO: fancy++ with the magic of shaders */
-
- /* tessellation code - draw stroke as series of connected quads (triangle strips in fact)
- * with connection edges rotated to minimize shrinking artifacts, and rounded endcaps.
- */
- {
- const bGPDspoint *pt1, *pt2;
- float s0[2], s1[2]; /* segment 'center' points */
- float pm[2]; /* normal from previous segment. */
- int i;
- float fpt[3];
-
- GPUVertFormat *format = immVertexFormat();
- const struct {
- uint pos, color;
- } attr_id = {
- .pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT),
- .color = GPU_vertformat_attr_add(
- format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT),
- };
-
- immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
- immBegin(GPU_PRIM_TRI_STRIP, totpoints * 2 + 4);
-
- /* get x and y coordinates from first point */
- mul_v3_m4v3(fpt, diff_mat, &points->x);
- gp_calc_2d_stroke_fxy(fpt, sflag, offsx, offsy, winx, winy, s0);
-
- for (i = 0, pt1 = points, pt2 = points + 1; i < (totpoints - 1); i++, pt1++, pt2++) {
- float t0[2], t1[2]; /* tessellated coordinates */
- float m1[2], m2[2]; /* gradient and normal */
- float mt[2], sc[2]; /* gradient for thickness, point for end-cap */
- float pthick; /* thickness at segment point */
-
- /* Get x and y coordinates from point2
- * (point1 has already been computed in previous iteration). */
- mul_v3_m4v3(fpt, diff_mat, &pt2->x);
- gp_calc_2d_stroke_fxy(fpt, sflag, offsx, offsy, winx, winy, s1);
-
- /* calculate gradient and normal - 'angle'=(ny/nx) */
- m1[1] = s1[1] - s0[1];
- m1[0] = s1[0] - s0[0];
- normalize_v2(m1);
- m2[1] = -m1[0];
- m2[0] = m1[1];
-
- /* always use pressure from first point here */
- pthick = (pt1->pressure * thickness * scalefac);
-
- /* color of point */
- gp_set_point_varying_color(pt1, ink, attr_id.color, false);
-
- /* if the first segment, start of segment is segment's normal */
- if (i == 0) {
- /* draw start cap first
- * - make points slightly closer to center (about halfway across)
- */
- mt[0] = m2[0] * pthick * 0.5f;
- mt[1] = m2[1] * pthick * 0.5f;
- sc[0] = s0[0] - (m1[0] * pthick * 0.75f);
- sc[1] = s0[1] - (m1[1] * pthick * 0.75f);
-
- t0[0] = sc[0] - mt[0];
- t0[1] = sc[1] - mt[1];
- t1[0] = sc[0] + mt[0];
- t1[1] = sc[1] + mt[1];
-
- /* First two points of cap. */
- immVertex2fv(attr_id.pos, t0);
- immVertex2fv(attr_id.pos, t1);
-
- /* calculate points for start of segment */
- mt[0] = m2[0] * pthick;
- mt[1] = m2[1] * pthick;
-
- t0[0] = s0[0] - mt[0];
- t0[1] = s0[1] - mt[1];
- t1[0] = s0[0] + mt[0];
- t1[1] = s0[1] + mt[1];
-
- /* Last two points of start cap (and first two points of first segment). */
- immVertex2fv(attr_id.pos, t0);
- immVertex2fv(attr_id.pos, t1);
- }
- /* if not the first segment, use bisector of angle between segments */
- else {
- float mb[2]; /* bisector normal */
- float athick, dfac; /* actual thickness, difference between thicknesses */
-
- /* calculate gradient of bisector (as average of normals) */
- mb[0] = (pm[0] + m2[0]) / 2;
- mb[1] = (pm[1] + m2[1]) / 2;
- normalize_v2(mb);
-
- /* calculate gradient to apply
- * - as basis, use just pthick * bisector gradient
- * - if cross-section not as thick as it should be, add extra padding to fix it
- */
- mt[0] = mb[0] * pthick;
- mt[1] = mb[1] * pthick;
- athick = len_v2(mt);
- dfac = pthick - (athick * 2);
-
- if (((athick * 2.0f) < pthick) && (IS_EQF(athick, pthick) == 0)) {
- mt[0] += (mb[0] * dfac);
- mt[1] += (mb[1] * dfac);
- }
-
- /* calculate points for start of segment */
- t0[0] = s0[0] - mt[0];
- t0[1] = s0[1] - mt[1];
- t1[0] = s0[0] + mt[0];
- t1[1] = s0[1] + mt[1];
-
- /* Last two points of previous segment, and first two points of current segment. */
- immVertex2fv(attr_id.pos, t0);
- immVertex2fv(attr_id.pos, t1);
- }
-
- /* if last segment, also draw end of segment (defined as segment's normal) */
- if (i == totpoints - 2) {
- /* for once, we use second point's pressure (otherwise it won't be drawn) */
- pthick = (pt2->pressure * thickness * scalefac);
-
- /* color of point */
- gp_set_point_varying_color(pt2, ink, attr_id.color, false);
-
- /* calculate points for end of segment */
- mt[0] = m2[0] * pthick;
- mt[1] = m2[1] * pthick;
-
- t0[0] = s1[0] - mt[0];
- t0[1] = s1[1] - mt[1];
- t1[0] = s1[0] + mt[0];
- t1[1] = s1[1] + mt[1];
-
- /* Last two points of last segment (and first two points of end cap). */
- immVertex2fv(attr_id.pos, t0);
- immVertex2fv(attr_id.pos, t1);
-
- /* draw end cap as last step
- * - make points slightly closer to center (about halfway across)
- */
- mt[0] = m2[0] * pthick * 0.5f;
- mt[1] = m2[1] * pthick * 0.5f;
- sc[0] = s1[0] + (m1[0] * pthick * 0.75f);
- sc[1] = s1[1] + (m1[1] * pthick * 0.75f);
-
- t0[0] = sc[0] - mt[0];
- t0[1] = sc[1] - mt[1];
- t1[0] = sc[0] + mt[0];
- t1[1] = sc[1] + mt[1];
-
- /* Last two points of end cap. */
- immVertex2fv(attr_id.pos, t0);
- immVertex2fv(attr_id.pos, t1);
- }
-
- /* store computed point2 coordinates as point1 ones of next segment. */
- copy_v2_v2(s0, s1);
- /* store stroke's 'natural' normal for next stroke to use */
- copy_v2_v2(pm, m2);
- }
-
- immEnd();
- immUnbindProgram();
- }
-}
-
/* ----- Strokes Drawing ------ */
/* Helper for doing all the checks on whether a stroke can be drawn */
@@ -691,7 +296,6 @@ static bool gp_can_draw_stroke(const bGPDstroke *gps, const int dflag)
static void gp_draw_strokes(tGPDdraw *tgpw)
{
float tcolor[4];
- float tfill[4];
short sthickness;
float ink[4];
const bool is_unique = (tgpw->gps != NULL);
@@ -748,37 +352,6 @@ static void gp_draw_strokes(tGPDdraw *tgpw)
bglPolygonOffset(1.0f, 1.0f);
}
- /* 3D Fill */
- // if ((dflag & GP_DRAWDATA_FILL) && (gps->totpoints >= 3)) {
- if ((gps->totpoints >= 3) && (tgpw->disable_fill != 1)) {
- /* set color using material, tint color and opacity */
- interp_v3_v3v3(tfill, gp_style->fill_rgba, tgpw->tintcolor, tgpw->tintcolor[3]);
- tfill[3] = gp_style->fill_rgba[3] * tgpw->opacity;
- if ((tfill[3] > GPENCIL_ALPHA_OPACITY_THRESH) || (gp_style->fill_style > 0)) {
- const float *color;
- if (!tgpw->onion) {
- color = tfill;
- }
- else {
- if (tgpw->custonion) {
- color = tgpw->tintcolor;
- }
- else {
- ARRAY_SET_ITEMS(tfill, UNPACK3(gp_style->fill_rgba), tgpw->tintcolor[3]);
- color = tfill;
- }
- }
- gp_draw_stroke_fill(tgpw->gpd,
- gps,
- tgpw->offsx,
- tgpw->offsy,
- tgpw->winx,
- tgpw->winy,
- tgpw->diff_mat,
- color);
- }
- }
-
/* 3D Stroke */
/* set color using material tint color and opacity */
if (!tgpw->onion) {
@@ -811,21 +384,7 @@ static void gp_draw_strokes(tGPDdraw *tgpw)
}
else {
/* 3D Lines - OpenGL primitives-based */
- if (gps->totpoints == 1) {
- if (tgpw->disable_fill != 1) {
- gp_draw_stroke_point(gps->points,
- sthickness,
- tgpw->dflag,
- gps->flag,
- tgpw->offsx,
- tgpw->offsy,
- tgpw->winx,
- tgpw->winy,
- tgpw->diff_mat,
- ink);
- }
- }
- else {
+ if (gps->totpoints > 1) {
tgpw->gps = gps;
gp_draw_stroke_3d(tgpw, sthickness, ink, gps->flag & GP_STROKE_CYCLIC);
}
@@ -837,97 +396,6 @@ static void gp_draw_strokes(tGPDdraw *tgpw)
bglPolygonOffset(0.0, 0.0);
}
}
- else {
- /* 2D - Fill */
- if (gps->totpoints >= 3) {
- /* set color using material, tint color and opacity */
- interp_v3_v3v3(tfill, gp_style->fill_rgba, tgpw->tintcolor, tgpw->tintcolor[3]);
- tfill[3] = gp_style->fill_rgba[3] * tgpw->opacity;
- if ((tfill[3] > GPENCIL_ALPHA_OPACITY_THRESH) || (gp_style->fill_style > 0)) {
- const float *color;
- if (!tgpw->onion) {
- color = tfill;
- }
- else {
- if (tgpw->custonion) {
- color = tgpw->tintcolor;
- }
- else {
- ARRAY_SET_ITEMS(tfill, UNPACK3(gp_style->fill_rgba), tgpw->tintcolor[3]);
- color = tfill;
- }
- }
- gp_draw_stroke_fill(tgpw->gpd,
- gps,
- tgpw->offsx,
- tgpw->offsy,
- tgpw->winx,
- tgpw->winy,
- tgpw->diff_mat,
- color);
- }
- }
-
- /* 2D Strokes... */
- /* set color using material, tint color and opacity */
- if (!tgpw->onion) {
- interp_v3_v3v3(tcolor, gp_style->stroke_rgba, tgpw->tintcolor, tgpw->tintcolor[3]);
- tcolor[3] = gp_style->stroke_rgba[3] * tgpw->opacity;
- copy_v4_v4(ink, tcolor);
- }
- else {
- if (tgpw->custonion) {
- copy_v4_v4(ink, tgpw->tintcolor);
- }
- else {
- ARRAY_SET_ITEMS(tcolor, UNPACK3(gp_style->stroke_rgba), tgpw->opacity);
- copy_v4_v4(ink, tcolor);
- }
- }
- if (gp_style->mode == GP_MATERIAL_MODE_DOT) {
- /* blob/disk-based "volumetric" drawing */
- gp_draw_stroke_volumetric_2d(gps->points,
- gps->totpoints,
- sthickness,
- tgpw->dflag,
- gps->flag,
- tgpw->offsx,
- tgpw->offsy,
- tgpw->winx,
- tgpw->winy,
- tgpw->diff_mat,
- ink);
- }
- else {
- /* normal 2D strokes */
- if (gps->totpoints == 1) {
- gp_draw_stroke_point(gps->points,
- sthickness,
- tgpw->dflag,
- gps->flag,
- tgpw->offsx,
- tgpw->offsy,
- tgpw->winx,
- tgpw->winy,
- tgpw->diff_mat,
- ink);
- }
- else {
- gp_draw_stroke_2d(gps->points,
- gps->totpoints,
- sthickness,
- tgpw->dflag,
- gps->flag,
- false,
- tgpw->offsx,
- tgpw->offsy,
- tgpw->winx,
- tgpw->winy,
- tgpw->diff_mat,
- ink);
- }
- }
- }
/* if only one stroke, exit from loop */
if (is_unique) {
break;
diff --git a/source/blender/editors/gpencil/gpencil_convert.c b/source/blender/editors/gpencil/gpencil_convert.c
index 1c55c3b5a8f..8470fcad9d7 100644
--- a/source/blender/editors/gpencil/gpencil_convert.c
+++ b/source/blender/editors/gpencil/gpencil_convert.c
@@ -152,7 +152,6 @@ static const EnumPropertyItem *rna_GPConvert_mode_items(bContext *UNUSED(C),
* - assumes that the active space is the 3D-View
*/
static void gp_strokepoint_convertcoords(bContext *C,
- bGPdata *UNUSED(gpd),
bGPDlayer *gpl,
bGPDstroke *gps,
bGPDspoint *source_pt,
@@ -633,7 +632,6 @@ static void gp_stroke_to_path_add_point(tGpTimingData *gtd,
}
static void gp_stroke_to_path(bContext *C,
- bGPdata *gpd,
bGPDlayer *gpl,
bGPDstroke *gps,
Curve *cu,
@@ -708,7 +706,7 @@ static void gp_stroke_to_path(bContext *C,
bp = &nu->bp[old_nbp - 1];
/* First point */
- gp_strokepoint_convertcoords(C, gpd, gpl, gps, gps->points, p, subrect);
+ gp_strokepoint_convertcoords(C, gpl, gps, gps->points, p, subrect);
if (prev_bp) {
interp_v3_v3v3(p1, bp->vec, prev_bp->vec, -GAP_DFAC);
if (do_gtd) {
@@ -737,7 +735,7 @@ static void gp_stroke_to_path(bContext *C,
/* Second point */
/* Note dt2 is always negative, which marks the gap. */
if (gps->totpoints > 1) {
- gp_strokepoint_convertcoords(C, gpd, gpl, gps, gps->points + 1, next_p, subrect);
+ gp_strokepoint_convertcoords(C, gpl, gps, gps->points + 1, next_p, subrect);
interp_v3_v3v3(p2, p, next_p, -GAP_DFAC);
if (do_gtd) {
dt2 = interpf(gps->points[1].time, gps->points[0].time, -GAP_DFAC);
@@ -759,9 +757,9 @@ static void gp_stroke_to_path(bContext *C,
float p[3], next_p[3];
float dt = 0.0f;
- gp_strokepoint_convertcoords(C, gpd, gpl, gps, gps->points, p, subrect);
+ gp_strokepoint_convertcoords(C, gpl, gps, gps->points, p, subrect);
if (gps->totpoints > 1) {
- gp_strokepoint_convertcoords(C, gpd, gpl, gps, gps->points + 1, next_p, subrect);
+ gp_strokepoint_convertcoords(C, gpl, gps, gps->points + 1, next_p, subrect);
interp_v3_v3v3(p, p, next_p, -GAP_DFAC);
if (do_gtd) {
dt = interpf(gps->points[1].time, gps->points[0].time, -GAP_DFAC);
@@ -794,7 +792,7 @@ static void gp_stroke_to_path(bContext *C,
float width = pt->pressure * (gps->thickness + gpl->line_change) * WIDTH_CORR_FAC;
/* get coordinates to add at */
- gp_strokepoint_convertcoords(C, gpd, gpl, gps, pt, p, subrect);
+ gp_strokepoint_convertcoords(C, gpl, gps, pt, p, subrect);
gp_stroke_to_path_add_point(gtd,
bp,
@@ -882,7 +880,6 @@ static void gp_stroke_to_bezier_add_point(tGpTimingData *gtd,
}
static void gp_stroke_to_bezier(bContext *C,
- bGPdata *gpd,
bGPDlayer *gpl,
bGPDstroke *gps,
Curve *cu,
@@ -934,13 +931,12 @@ static void gp_stroke_to_bezier(bContext *C,
/* get initial coordinates */
pt = gps->points;
if (tot) {
- gp_strokepoint_convertcoords(C, gpd, gpl, gps, pt, (stitch) ? p3d_prev : p3d_cur, subrect);
+ gp_strokepoint_convertcoords(C, gpl, gps, pt, (stitch) ? p3d_prev : p3d_cur, subrect);
if (tot > 1) {
- gp_strokepoint_convertcoords(
- C, gpd, gpl, gps, pt + 1, (stitch) ? p3d_cur : p3d_next, subrect);
+ gp_strokepoint_convertcoords(C, gpl, gps, pt + 1, (stitch) ? p3d_cur : p3d_next, subrect);
}
if (stitch && tot > 2) {
- gp_strokepoint_convertcoords(C, gpd, gpl, gps, pt + 2, p3d_next, subrect);
+ gp_strokepoint_convertcoords(C, gpl, gps, pt + 2, p3d_next, subrect);
}
}
@@ -1106,7 +1102,7 @@ static void gp_stroke_to_bezier(bContext *C,
copy_v3_v3(p3d_cur, p3d_next);
if (i + 2 < tot) {
- gp_strokepoint_convertcoords(C, gpd, gpl, gps, pt + 2, p3d_next, subrect);
+ gp_strokepoint_convertcoords(C, gpl, gps, pt + 2, p3d_next, subrect);
}
prev_bezt = bezt;
@@ -1334,7 +1330,6 @@ static void gp_layer_to_curve(bContext *C,
switch (mode) {
case GP_STROKECONVERT_PATH:
gp_stroke_to_path(C,
- gpd,
gpl,
gps,
cu,
@@ -1350,7 +1345,6 @@ static void gp_layer_to_curve(bContext *C,
case GP_STROKECONVERT_CURVE:
case GP_STROKECONVERT_POLY: /* convert after */
gp_stroke_to_bezier(C,
- gpd,
gpl,
gps,
cu,
@@ -1755,7 +1749,7 @@ void GPENCIL_OT_convert(wmOperatorType *ot)
static bool image_to_gpencil_poll(bContext *C)
{
SpaceLink *sl = CTX_wm_space_data(C);
- if (sl->spacetype == SPACE_IMAGE) {
+ if ((sl != NULL) && (sl->spacetype == SPACE_IMAGE)) {
return true;
}
diff --git a/source/blender/editors/gpencil/gpencil_data.c b/source/blender/editors/gpencil/gpencil_data.c
index 627bc46d06c..898facb86e8 100644
--- a/source/blender/editors/gpencil/gpencil_data.c
+++ b/source/blender/editors/gpencil/gpencil_data.c
@@ -214,6 +214,7 @@ static int gp_layer_add_exec(bContext *C, wmOperator *op)
PointerRNA gpd_owner = {NULL};
Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
bGPdata *gpd = NULL;
if (is_annotation) {
@@ -238,7 +239,13 @@ static int gp_layer_add_exec(bContext *C, wmOperator *op)
Object *ob = CTX_data_active_object(C);
if ((ob != NULL) && (ob->type == OB_GPENCIL)) {
gpd = (bGPdata *)ob->data;
- BKE_gpencil_layer_addnew(gpd, DATA_("GP_Layer"), true);
+ bGPDlayer *gpl = BKE_gpencil_layer_addnew(gpd, DATA_("GP_Layer"), true);
+ ScrArea *sa = CTX_wm_area(C);
+
+ /* In dopesheet add a new frame. */
+ if ((gpl != NULL) && (sa->spacetype == SPACE_ACTION)) {
+ gpl->actframe = BKE_gpencil_layer_frame_get(gpl, CFRA, GP_GETFRAME_ADD_NEW);
+ }
}
}
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c
index 83ecb3ab42f..dc7bbfb99fa 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -1379,7 +1379,8 @@ void GPENCIL_OT_copy(wmOperatorType *ot)
static bool gp_strokes_paste_poll(bContext *C)
{
- if (CTX_wm_area(C)->spacetype != SPACE_VIEW3D) {
+ ScrArea *sa = CTX_wm_area(C);
+ if (!((sa != NULL) && (sa->spacetype == SPACE_VIEW3D))) {
return false;
}
/* 1) Must have GP datablock to paste to
@@ -3545,7 +3546,7 @@ static int gp_strokes_reproject_exec(bContext *C, wmOperator *op)
GP_REPROJECT_TOP,
GP_REPROJECT_CURSOR)) {
if (mode != GP_REPROJECT_CURSOR) {
- ED_gpencil_drawing_reference_get(scene, ob, gpl, ts->gpencil_v3d_align, origin);
+ ED_gpencil_drawing_reference_get(scene, ob, ts->gpencil_v3d_align, origin);
}
else {
copy_v3_v3(origin, scene->cursor.location);
@@ -4248,7 +4249,7 @@ static int gp_stroke_separate_exec(bContext *C, wmOperator *op)
if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
continue;
}
- /* separate selected strokes */
+ /* Separate selected strokes. */
if (gps->flag & GP_STROKE_SELECT) {
/* add layer if not created before */
if (gpl_dst == NULL) {
@@ -4421,7 +4422,7 @@ static int gp_stroke_split_exec(bContext *C, wmOperator *UNUSED(op))
if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
continue;
}
- /* split selected strokes */
+ /* Split selected strokes. */
if (gps->flag & GP_STROKE_SELECT) {
/* make copy of source stroke */
bGPDstroke *gps_dst = BKE_gpencil_stroke_duplicate(gps, true);
diff --git a/source/blender/editors/gpencil/gpencil_fill.c b/source/blender/editors/gpencil/gpencil_fill.c
index f61572fffca..e56017d0bed 100644
--- a/source/blender/editors/gpencil/gpencil_fill.c
+++ b/source/blender/editors/gpencil/gpencil_fill.c
@@ -1143,7 +1143,6 @@ static void gpencil_stroke_from_buffer(tGPDfill *tgpf)
gp_stroke_convertcoords_tpoint(tgpf->scene,
tgpf->region,
tgpf->ob,
- tgpf->gpl,
point2D,
tgpf->depth_arr ? tgpf->depth_arr + i : NULL,
&pt->x);
@@ -1186,8 +1185,7 @@ static void gpencil_stroke_from_buffer(tGPDfill *tgpf)
if ((tgpf->lock_axis > GP_LOCKAXIS_VIEW) &&
((ts->gpencil_v3d_align & GP_PROJECT_DEPTH_VIEW) == 0)) {
float origin[3];
- ED_gpencil_drawing_reference_get(
- tgpf->scene, tgpf->ob, tgpf->gpl, ts->gpencil_v3d_align, origin);
+ ED_gpencil_drawing_reference_get(tgpf->scene, tgpf->ob, ts->gpencil_v3d_align, origin);
ED_gp_project_stroke_to_plane(
tgpf->scene, tgpf->ob, tgpf->rv3d, gps, origin, tgpf->lock_axis - 1);
}
diff --git a/source/blender/editors/gpencil/gpencil_intern.h b/source/blender/editors/gpencil/gpencil_intern.h
index 79f672274a7..61bca235d17 100644
--- a/source/blender/editors/gpencil/gpencil_intern.h
+++ b/source/blender/editors/gpencil/gpencil_intern.h
@@ -257,8 +257,7 @@ typedef struct GP_SpaceConversion {
float mat[4][4]; /* transform matrix on the strokes (introduced in [b770964]) */
} GP_SpaceConversion;
-bool gp_stroke_inside_circle(
- const float mval[2], const float UNUSED(mvalo[2]), int rad, int x0, int y0, int x1, int y1);
+bool gp_stroke_inside_circle(const float mval[2], int rad, int x0, int y0, int x1, int y1);
void gp_point_conversion_init(struct bContext *C, GP_SpaceConversion *r_gsc);
@@ -304,7 +303,6 @@ bool gp_point_xy_to_3d(const GP_SpaceConversion *gsc,
void gp_stroke_convertcoords_tpoint(struct Scene *scene,
struct ARegion *region,
struct Object *ob,
- bGPDlayer *gpl,
const struct tGPspoint *point2D,
float *depth,
float out[3]);
diff --git a/source/blender/editors/gpencil/gpencil_ops_versioning.c b/source/blender/editors/gpencil/gpencil_ops_versioning.c
index df094ff5bd0..96146c60acb 100644
--- a/source/blender/editors/gpencil/gpencil_ops_versioning.c
+++ b/source/blender/editors/gpencil/gpencil_ops_versioning.c
@@ -134,7 +134,6 @@ static int gpencil_convert_old_files_exec(bContext *C, wmOperator *op)
ARRAY_SET_ITEMS(gp_style->mix_rgba, 1.0f, 1.0f, 1.0f, 0.2f);
ARRAY_SET_ITEMS(gp_style->gradient_scale, 1.0f, 1.0f);
ARRAY_SET_ITEMS(gp_style->texture_scale, 1.0f, 1.0f);
- gp_style->texture_opacity = 1.0f;
gp_style->texture_pixsize = 100.0f;
gp_style->flag |= GP_MATERIAL_STROKE_SHOW;
diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c
index 01b0fe80dfc..1a169f9ec89 100644
--- a/source/blender/editors/gpencil/gpencil_paint.c
+++ b/source/blender/editors/gpencil/gpencil_paint.c
@@ -30,6 +30,7 @@
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
+#include "BLI_hash.h"
#include "BLI_math.h"
#include "BLI_math_geom.h"
#include "BLI_rand.h"
@@ -353,7 +354,7 @@ static void gp_get_3d_reference(tGPsdata *p, float vec[3])
if (p->ownerPtr.type == &RNA_Object) {
ob = (Object *)p->ownerPtr.data;
}
- ED_gpencil_drawing_reference_get(p->scene, ob, p->gpl, *p->align_flag, vec);
+ ED_gpencil_drawing_reference_get(p->scene, ob, *p->align_flag, vec);
}
/* Stroke Editing ---------------------------- */
@@ -486,6 +487,7 @@ static void gp_stroke_convertcoords(tGPsdata *p, const float mval[2], float out[
/* Apply jitter to stroke point. */
static void gp_brush_jitter(bGPdata *gpd, tGPspoint *pt, const float amplitude)
{
+ const float axis[2] = {0.0f, 1.0f};
/* Jitter is applied perpendicular to the mouse movement vector (2D space). */
float mvec[2];
/* Mouse movement in ints -> floats. */
@@ -493,16 +495,15 @@ static void gp_brush_jitter(bGPdata *gpd, tGPspoint *pt, const float amplitude)
tGPspoint *pt_prev = pt - 1;
sub_v2_v2v2(mvec, &pt->x, &pt_prev->x);
normalize_v2(mvec);
+ /* Rotate mvec by 90 degrees... */
+ float angle = angle_v2v2(mvec, axis);
+ /* Reduce noise in the direction of the stroke. */
+ mvec[0] *= cos(angle);
+ mvec[1] *= sin(angle);
+
+ /* Scale by displacement amount, and apply. */
+ madd_v2_v2fl(&pt->x, mvec, amplitude * 10.0f);
}
- else {
- mvec[0] = 0.0f;
- mvec[1] = 0.0f;
- }
- /* Rotate mvec by 90 degrees... */
- SWAP(float, mvec[0], mvec[1]);
- mvec[0] -= mvec[0];
- /* Scale by displacement amount, and apply. */
- madd_v2_v2fl(&pt->x, mvec, amplitude);
}
/* apply pressure change depending of the angle of the stroke to simulate a pen with shape */
@@ -788,8 +789,10 @@ static short gp_stroke_addpoint(tGPsdata *p, const float mval[2], float pressure
}
/* apply randomness to uv texture rotation */
if (brush_settings->uv_random > 0.0f) {
- float rand = BLI_rng_get_float(p->rng) * 2.0f - 1.0f;
- pt->uv_rot += rand * M_PI * brush_settings->uv_random;
+ float rand = BLI_hash_int_01(BLI_hash_int_2d((int)pt->x, gpd->runtime.sbuffer_used)) *
+ 2.0f -
+ 1.0f;
+ pt->uv_rot += rand * M_PI_2 * brush_settings->uv_random;
CLAMP(pt->uv_rot, -M_PI_2, M_PI_2);
}
/* apply randomness to color strength */
@@ -1356,7 +1359,6 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p,
bGPDframe *gpf,
bGPDstroke *gps,
const float mval[2],
- const float mvalo[2],
const int radius,
const rcti *rect)
{
@@ -1475,7 +1477,7 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p,
* eraser region (either within stroke painted, or on its lines)
* - this assumes that linewidth is irrelevant
*/
- if (gp_stroke_inside_circle(mval, mvalo, radius, pc0[0], pc0[1], pc2[0], pc2[1])) {
+ if (gp_stroke_inside_circle(mval, radius, pc0[0], pc0[1], pc2[0], pc2[1])) {
if ((gp_stroke_eraser_is_occluded(p, pt0, pc0[0], pc0[1]) == false) ||
(gp_stroke_eraser_is_occluded(p, pt1, pc1[0], pc1[1]) == false) ||
(gp_stroke_eraser_is_occluded(p, pt2, pc2[0], pc2[1]) == false)) {
@@ -1632,7 +1634,7 @@ static void gp_stroke_doeraser(tGPsdata *p)
* (e.g. 2D space strokes in the 3D view, if the same datablock is shared)
*/
if (ED_gpencil_stroke_can_use_direct(p->sa, gps)) {
- gp_stroke_eraser_dostroke(p, gpf, gps, p->mval, p->mvalo, calc_radius, &rect);
+ gp_stroke_eraser_dostroke(p, gpf, gps, p->mval, calc_radius, &rect);
}
}
}
@@ -3142,7 +3144,7 @@ static void gpencil_add_arc_points(tGPsdata *p, float mval[2], int segments)
if (gpd->runtime.sbuffer_used < 3) {
return;
}
-
+ BrushGpencilSettings *brush_settings = p->brush->gpencil_settings;
int idx_prev = gpd->runtime.sbuffer_used;
/* Add space for new arc points. */
@@ -3207,6 +3209,27 @@ static void gpencil_add_arc_points(tGPsdata *p, float mval[2], int segments)
pt->pressure = pt_prev->pressure;
pt->strength = pt_prev->strength;
+ /* Apply randomness to pressure. */
+ if (brush_settings->draw_random_press > 0.0f) {
+ float rand = BLI_rng_get_float(p->rng) * 2.0f - 1.0f;
+ pt->pressure *= 1.0 + rand * 2.0 * brush_settings->draw_random_press;
+ CLAMP(pt->pressure, GPENCIL_STRENGTH_MIN, 1.0f);
+ }
+ /* Apply randomness to color strength. */
+ if (brush_settings->draw_random_strength) {
+ float rand = BLI_rng_get_float(p->rng) * 2.0f - 1.0f;
+ pt->strength *= 1.0 + rand * brush_settings->draw_random_strength;
+ CLAMP(pt->strength, GPENCIL_STRENGTH_MIN, 1.0f);
+ }
+ /* Apply randomness to uv texture rotation. */
+ if (brush_settings->uv_random > 0.0f) {
+ float rand = BLI_hash_int_01(BLI_hash_int_2d((int)pt->x, gpd->runtime.sbuffer_used + i)) *
+ 2.0f -
+ 1.0f;
+ pt->uv_rot += rand * M_PI_2 * brush_settings->uv_random;
+ CLAMP(pt->uv_rot, -M_PI_2, M_PI_2);
+ }
+
a += step;
}
}
diff --git a/source/blender/editors/gpencil/gpencil_primitive.c b/source/blender/editors/gpencil/gpencil_primitive.c
index 2b30a415086..dfd11484d22 100644
--- a/source/blender/editors/gpencil/gpencil_primitive.c
+++ b/source/blender/editors/gpencil/gpencil_primitive.c
@@ -954,8 +954,7 @@ static void gp_primitive_update_strokes(bContext *C, tGPDprimitive *tgpi)
/* get origin to reproject point */
float origin[3];
- ED_gpencil_drawing_reference_get(
- tgpi->scene, tgpi->ob, tgpi->gpl, ts->gpencil_v3d_align, origin);
+ ED_gpencil_drawing_reference_get(tgpi->scene, tgpi->ob, ts->gpencil_v3d_align, origin);
/* reproject current */
ED_gpencil_tpoint_to_point(tgpi->region, origin, tpt, &spt);
ED_gp_project_point_to_plane(
@@ -987,13 +986,8 @@ static void gp_primitive_update_strokes(bContext *C, tGPDprimitive *tgpi)
}
/* convert screen-coordinates to 3D coordinates */
- gp_stroke_convertcoords_tpoint(tgpi->scene,
- tgpi->region,
- tgpi->ob,
- tgpi->gpl,
- p2d,
- depth_arr ? depth_arr + i : NULL,
- &pt->x);
+ gp_stroke_convertcoords_tpoint(
+ tgpi->scene, tgpi->region, tgpi->ob, p2d, depth_arr ? depth_arr + i : NULL, &pt->x);
pt->pressure = pressure;
pt->strength = strength;
@@ -1019,15 +1013,14 @@ static void gp_primitive_update_strokes(bContext *C, tGPDprimitive *tgpi)
for (int i = 0; i < tgpi->gpd->runtime.tot_cp_points; i++) {
bGPDcontrolpoint *cp = &cps[i];
gp_stroke_convertcoords_tpoint(
- tgpi->scene, tgpi->region, tgpi->ob, tgpi->gpl, (tGPspoint *)cp, NULL, &cp->x);
+ tgpi->scene, tgpi->region, tgpi->ob, (tGPspoint *)cp, NULL, &cp->x);
}
}
/* reproject to plane */
if (!is_depth) {
float origin[3];
- ED_gpencil_drawing_reference_get(
- tgpi->scene, tgpi->ob, tgpi->gpl, ts->gpencil_v3d_align, origin);
+ ED_gpencil_drawing_reference_get(tgpi->scene, tgpi->ob, ts->gpencil_v3d_align, origin);
ED_gp_project_stroke_to_plane(
tgpi->scene, tgpi->ob, tgpi->rv3d, gps, origin, ts->gp_sculpt.lock_axis - 1);
}
diff --git a/source/blender/editors/gpencil/gpencil_sculpt_paint.c b/source/blender/editors/gpencil/gpencil_sculpt_paint.c
index 59b14a47d1d..8f3fc5fa268 100644
--- a/source/blender/editors/gpencil/gpencil_sculpt_paint.c
+++ b/source/blender/editors/gpencil/gpencil_sculpt_paint.c
@@ -1495,8 +1495,7 @@ static bool gpsculpt_brush_do_stroke(tGP_BrushEditData *gso,
* brush region (either within stroke painted, or on its lines)
* - this assumes that linewidth is irrelevant
*/
- if (gp_stroke_inside_circle(
- gso->mval, gso->mval_prev, radius, pc1[0], pc1[1], pc2[0], pc2[1])) {
+ if (gp_stroke_inside_circle(gso->mval, radius, pc1[0], pc1[1], pc2[0], pc2[1])) {
/* Apply operation to these points */
bool ok = false;
diff --git a/source/blender/editors/gpencil/gpencil_select.c b/source/blender/editors/gpencil/gpencil_select.c
index 6194b82fed9..97f0a578d9d 100644
--- a/source/blender/editors/gpencil/gpencil_select.c
+++ b/source/blender/editors/gpencil/gpencil_select.c
@@ -919,13 +919,12 @@ static bool gp_stroke_do_circle_sel(bGPdata *UNUSED(gpd),
if (((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(rect, x0, y0)) ||
((!ELEM(V2D_IS_CLIPPED, x1, y1)) && BLI_rcti_isect_pt(rect, x1, y1))) {
float mval[2] = {(float)mx, (float)my};
- float mvalo[2] = {(float)mx, (float)my}; /* dummy - this isn't used... */
/* check if point segment of stroke had anything to do with
* eraser region (either within stroke painted, or on its lines)
* - this assumes that linewidth is irrelevant
*/
- if (gp_stroke_inside_circle(mval, mvalo, radius, x0, y0, x1, y1)) {
+ if (gp_stroke_inside_circle(mval, radius, x0, y0, x1, y1)) {
/* change selection of stroke, and then of both points
* (as the last point otherwise wouldn't get selected
* as we only do n-1 loops through).
@@ -1052,8 +1051,7 @@ static int gpencil_circle_select_exec(bContext *C, wmOperator *op)
rect.ymax = my + radius;
/* find visible strokes, and select if hit */
- GP_EVALUATED_STROKES_BEGIN(gpstroke_iter, C, gpl, gps)
- {
+ GP_EVALUATED_STROKES_BEGIN (gpstroke_iter, C, gpl, gps) {
changed |= gp_stroke_do_circle_sel(gpd,
gpl,
gps,
@@ -1164,7 +1162,7 @@ static int gpencil_generic_select_exec(bContext *C,
gp_point_conversion_init(C, &gsc);
/* deselect all strokes first? */
- if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
+ if (SEL_OP_USE_PRE_DESELECT(sel_op) || (GPENCIL_PAINT_MODE(gpd))) {
CTX_DATA_BEGIN (C, bGPDstroke *, gps, editable_gpencil_strokes) {
bGPDspoint *pt;
@@ -1180,8 +1178,7 @@ static int gpencil_generic_select_exec(bContext *C,
}
/* select/deselect points */
- GP_EVALUATED_STROKES_BEGIN(gpstroke_iter, C, gpl, gps)
- {
+ GP_EVALUATED_STROKES_BEGIN (gpstroke_iter, C, gpl, gps) {
bGPDstroke *gps_active = (gps->runtime.gps_orig) ? gps->runtime.gps_orig : gps;
bGPDspoint *pt;
@@ -1248,7 +1245,7 @@ static int gpencil_generic_select_exec(bContext *C,
GP_EVALUATED_STROKES_END(gpstroke_iter);
/* if paint mode,delete selected points */
- if (gpd->flag & GP_DATA_STROKE_PAINTMODE) {
+ if (GPENCIL_PAINT_MODE(gpd)) {
gp_delete_selected_point_wrap(C);
changed = true;
DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
@@ -1473,8 +1470,7 @@ static int gpencil_select_exec(bContext *C, wmOperator *op)
/* First Pass: Find stroke point which gets hit */
/* XXX: maybe we should go from the top of the stack down instead... */
- GP_EVALUATED_STROKES_BEGIN(gpstroke_iter, C, gpl, gps)
- {
+ GP_EVALUATED_STROKES_BEGIN (gpstroke_iter, C, gpl, gps) {
bGPDstroke *gps_active = (gps->runtime.gps_orig) ? gps->runtime.gps_orig : gps;
bGPDspoint *pt;
int i;
diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c
index 276be071e0b..312cb1b50c0 100644
--- a/source/blender/editors/gpencil/gpencil_utils.c
+++ b/source/blender/editors/gpencil/gpencil_utils.c
@@ -494,8 +494,7 @@ const EnumPropertyItem *ED_gpencil_layers_with_new_enum_itemf(bContext *C,
* \param x0, y0: The screen-space x and y coordinates of the start of the stroke segment
* \param x1, y1: The screen-space x and y coordinates of the end of the stroke segment
*/
-bool gp_stroke_inside_circle(
- const float mval[2], const float UNUSED(mvalo[2]), int rad, int x0, int y0, int x1, int y1)
+bool gp_stroke_inside_circle(const float mval[2], int rad, int x0, int y0, int x1, int y1)
{
/* simple within-radius check for now */
const float screen_co_a[2] = {x0, y0};
@@ -869,8 +868,7 @@ bool gp_point_xy_to_3d(const GP_SpaceConversion *gsc,
const RegionView3D *rv3d = gsc->region->regiondata;
float rvec[3];
- ED_gpencil_drawing_reference_get(
- scene, gsc->ob, gsc->gpl, scene->toolsettings->gpencil_v3d_align, rvec);
+ ED_gpencil_drawing_reference_get(scene, gsc->ob, scene->toolsettings->gpencil_v3d_align, rvec);
float zfac = ED_view3d_calc_zfac(rv3d, rvec, NULL);
@@ -905,7 +903,6 @@ bool gp_point_xy_to_3d(const GP_SpaceConversion *gsc,
void gp_stroke_convertcoords_tpoint(Scene *scene,
ARegion *region,
Object *ob,
- bGPDlayer *gpl,
const tGPspoint *point2D,
float *depth,
float r_out[3])
@@ -929,7 +926,7 @@ void gp_stroke_convertcoords_tpoint(Scene *scene,
/* Current method just converts each point in screen-coordinates to
* 3D-coordinates using the 3D-cursor as reference.
*/
- ED_gpencil_drawing_reference_get(scene, ob, gpl, ts->gpencil_v3d_align, rvec);
+ ED_gpencil_drawing_reference_get(scene, ob, ts->gpencil_v3d_align, rvec);
zfac = ED_view3d_calc_zfac(region->regiondata, rvec, NULL);
if (ED_view3d_project_float_global(region, rvec, mval_prj, V3D_PROJ_TEST_NOP) ==
@@ -948,8 +945,10 @@ void gp_stroke_convertcoords_tpoint(Scene *scene,
* Get drawing reference point for conversion or projection of the stroke
* \param[out] r_vec : Reference point found
*/
-void ED_gpencil_drawing_reference_get(
- const Scene *scene, const Object *ob, bGPDlayer *UNUSED(gpl), char align_flag, float r_vec[3])
+void ED_gpencil_drawing_reference_get(const Scene *scene,
+ const Object *ob,
+ char align_flag,
+ float r_vec[3])
{
const float *fp = scene->cursor.location;
diff --git a/source/blender/editors/gpencil/gpencil_uv.c b/source/blender/editors/gpencil/gpencil_uv.c
index 1da32dcc537..5f15a6f5411 100644
--- a/source/blender/editors/gpencil/gpencil_uv.c
+++ b/source/blender/editors/gpencil/gpencil_uv.c
@@ -176,8 +176,7 @@ static bool gpencil_uv_transform_init(bContext *C, wmOperator *op, const bool is
float center[3] = {0.0f};
int i = 0;
/* Need use evaluated to get the viewport final position. */
- GP_EVALUATED_STROKES_BEGIN(gpstroke_iter, C, gpl, gps)
- {
+ GP_EVALUATED_STROKES_BEGIN (gpstroke_iter, C, gpl, gps) {
if (gps->flag & GP_STROKE_SELECT) {
float r_center[3];
gpencil_stroke_center(gps, r_center);
diff --git a/source/blender/editors/gpencil/gpencil_vertex_paint.c b/source/blender/editors/gpencil/gpencil_vertex_paint.c
index 0c3b29ab1ea..10867bd1e0d 100644
--- a/source/blender/editors/gpencil/gpencil_vertex_paint.c
+++ b/source/blender/editors/gpencil/gpencil_vertex_paint.c
@@ -897,8 +897,7 @@ static void gp_vertexpaint_select_stroke(tGP_BrushVertexpaintData *gso,
* brush region (either within stroke painted, or on its lines)
* - this assumes that linewidth is irrelevant
*/
- if (gp_stroke_inside_circle(
- gso->mval, gso->mval_prev, radius, pc1[0], pc1[1], pc2[0], pc2[1])) {
+ if (gp_stroke_inside_circle(gso->mval, radius, pc1[0], pc1[1], pc2[0], pc2[1])) {
/* To each point individually... */
pt = &gps->points[i];
diff --git a/source/blender/editors/gpencil/gpencil_weight_paint.c b/source/blender/editors/gpencil/gpencil_weight_paint.c
index 51d5df1f405..2ebf1aba353 100644
--- a/source/blender/editors/gpencil/gpencil_weight_paint.c
+++ b/source/blender/editors/gpencil/gpencil_weight_paint.c
@@ -449,8 +449,7 @@ static void gp_weightpaint_select_stroke(tGP_BrushWeightpaintData *gso,
* brush region (either within stroke painted, or on its lines)
* - this assumes that linewidth is irrelevant
*/
- if (gp_stroke_inside_circle(
- gso->mval, gso->mval_prev, radius, pc1[0], pc1[1], pc2[0], pc2[1])) {
+ if (gp_stroke_inside_circle(gso->mval, radius, pc1[0], pc1[1], pc2[0], pc2[1])) {
/* To each point individually... */
pt = &gps->points[i];
diff --git a/source/blender/editors/include/ED_datafiles.h b/source/blender/editors/include/ED_datafiles.h
index a2ad343da37..b6f9593c261 100644
--- a/source/blender/editors/include/ED_datafiles.h
+++ b/source/blender/editors/include/ED_datafiles.h
@@ -60,12 +60,6 @@ extern char datatoc_splash_2x_png[];
extern int datatoc_bfont_pfb_size;
extern char datatoc_bfont_pfb[];
-extern int datatoc_bfont_ttf_size;
-extern char datatoc_bfont_ttf[];
-
-extern int datatoc_bmonofont_ttf_size;
-extern char datatoc_bmonofont_ttf[];
-
/* Brush icon datafiles */
/* TODO: this could be simplified by putting all
* the brush icons in one file */
diff --git a/source/blender/editors/include/ED_gpencil.h b/source/blender/editors/include/ED_gpencil.h
index 66aa301f08c..511e892f29a 100644
--- a/source/blender/editors/include/ED_gpencil.h
+++ b/source/blender/editors/include/ED_gpencil.h
@@ -233,7 +233,6 @@ void ED_gp_project_point_to_plane(const struct Scene *scene,
struct bGPDspoint *pt);
void ED_gpencil_drawing_reference_get(const struct Scene *scene,
const struct Object *ob,
- struct bGPDlayer *gpl,
char align_flag,
float vec[3]);
void ED_gpencil_project_stroke_to_view(struct bContext *C,
diff --git a/source/blender/editors/include/ED_image.h b/source/blender/editors/include/ED_image.h
index 1c260bb826a..910cf362a37 100644
--- a/source/blender/editors/include/ED_image.h
+++ b/source/blender/editors/include/ED_image.h
@@ -65,14 +65,14 @@ int ED_space_image_get_display_channel_mask(struct ImBuf *ibuf);
void ED_space_image_release_buffer(struct SpaceImage *sima, struct ImBuf *ibuf, void *lock);
bool ED_space_image_has_buffer(struct SpaceImage *sima);
-void ED_space_image_get_size(struct SpaceImage *sima, int *width, int *height);
-void ED_space_image_get_size_fl(struct SpaceImage *sima, float size[2]);
-void ED_space_image_get_aspect(struct SpaceImage *sima, float *aspx, float *aspy);
+void ED_space_image_get_size(struct SpaceImage *sima, int *r_width, int *r_height);
+void ED_space_image_get_size_fl(struct SpaceImage *sima, float r_size[2]);
+void ED_space_image_get_aspect(struct SpaceImage *sima, float *r_aspx, float *r_aspy);
void ED_space_image_get_zoom(struct SpaceImage *sima,
struct ARegion *region,
- float *zoomx,
- float *zoomy);
-void ED_space_image_get_uv_aspect(struct SpaceImage *sima, float *aspx, float *aspy);
+ float *r_zoomx,
+ float *r_zoomy);
+void ED_space_image_get_uv_aspect(struct SpaceImage *sima, float *r_aspx, float *r_aspy);
void ED_space_image_scopes_update(const struct bContext *C,
struct SpaceImage *sima,
@@ -83,14 +83,17 @@ void ED_space_image_paint_update(struct Main *bmain,
struct wmWindowManager *wm,
struct Scene *scene);
-void ED_image_get_uv_aspect(struct Image *ima, struct ImageUser *iuser, float *aspx, float *aspy);
+void ED_image_get_uv_aspect(struct Image *ima,
+ struct ImageUser *iuser,
+ float *r_aspx,
+ float *r_aspy);
void ED_image_mouse_pos(struct SpaceImage *sima,
struct ARegion *region,
const int mval[2],
float co[2]);
void ED_image_view_center_to_point(struct SpaceImage *sima, float x, float y);
void ED_image_point_pos(
- struct SpaceImage *sima, struct ARegion *region, float x, float y, float *xr, float *yr);
+ struct SpaceImage *sima, struct ARegion *region, float x, float y, float *r_x, float *r_y);
void ED_image_point_pos__reverse(struct SpaceImage *sima,
struct ARegion *region,
const float co[2],
diff --git a/source/blender/editors/include/ED_mask.h b/source/blender/editors/include/ED_mask.h
index 6abefa98c1a..7d314c0c462 100644
--- a/source/blender/editors/include/ED_mask.h
+++ b/source/blender/editors/include/ED_mask.h
@@ -36,6 +36,13 @@ struct bContext;
struct wmKeyConfig;
/* mask_edit.c */
+void ED_mask_deselect_all(const struct bContext *C);
+
+void ED_operatortypes_mask(void);
+void ED_keymap_mask(struct wmKeyConfig *keyconf);
+void ED_operatormacros_mask(void);
+
+/* mask_query.c */
void ED_mask_get_size(struct ScrArea *sa, int *width, int *height);
void ED_mask_zoom(struct ScrArea *sa, struct ARegion *region, float *zoomx, float *zoomy);
void ED_mask_get_aspect(struct ScrArea *sa, struct ARegion *region, float *aspx, float *aspy);
@@ -54,12 +61,6 @@ void ED_mask_point_pos__reverse(
void ED_mask_cursor_location_get(struct ScrArea *sa, float cursor[2]);
bool ED_mask_selected_minmax(const struct bContext *C, float min[2], float max[2]);
-void ED_mask_deselect_all(const struct bContext *C);
-
-void ED_operatortypes_mask(void);
-void ED_keymap_mask(struct wmKeyConfig *keyconf);
-void ED_operatormacros_mask(void);
-
/* mask_draw.c */
void ED_mask_draw(const struct bContext *C, const char draw_flag, const char draw_type);
void ED_mask_draw_region(struct Depsgraph *depsgraph,
diff --git a/source/blender/editors/include/ED_uvedit.h b/source/blender/editors/include/ED_uvedit.h
index 511b33bacc5..8c565536c71 100644
--- a/source/blender/editors/include/ED_uvedit.h
+++ b/source/blender/editors/include/ED_uvedit.h
@@ -188,7 +188,7 @@ bool ED_uvedit_nearest_uv_multi(const struct Scene *scene,
float r_uv[2]);
void ED_uvedit_get_aspect(
- const struct Scene *scene, struct Object *ob, struct BMesh *em, float *aspx, float *aspy);
+ const struct Scene *scene, struct Object *ob, struct BMesh *em, float *r_aspx, float *r_aspy);
/* uvedit_unwrap_ops.c */
void ED_uvedit_live_unwrap_begin(struct Scene *scene, struct Object *obedit);
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index 06de4705ac6..bb065ee0008 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -674,8 +674,10 @@ bool ED_view3d_distance_set_from_location(struct RegionView3D *rv3d,
const float dist_co[3],
const float dist_min);
-float ED_scene_grid_scale(const struct Scene *scene, const char **grid_unit);
-float ED_view3d_grid_scale(const struct Scene *scene, struct View3D *v3d, const char **grid_unit);
+float ED_scene_grid_scale(const struct Scene *scene, const char **r_grid_unit);
+float ED_view3d_grid_scale(const struct Scene *scene,
+ struct View3D *v3d,
+ const char **r_grid_unit);
void ED_view3d_grid_steps(const struct Scene *scene,
struct View3D *v3d,
struct RegionView3D *rv3d,
@@ -683,7 +685,7 @@ void ED_view3d_grid_steps(const struct Scene *scene,
float ED_view3d_grid_view_scale(struct Scene *scene,
struct View3D *v3d,
struct RegionView3D *rv3d,
- const char **grid_unit);
+ const char **r_grid_unit);
void ED_scene_draw_fps(const struct Scene *scene, int xoffset, int *yoffset);
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index bb2edef8adc..1fa6e5b12c1 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -2362,7 +2362,7 @@ void UI_drop_color_copy(struct wmDrag *drag, struct wmDropBox *drop);
bool UI_drop_color_poll(struct bContext *C,
struct wmDrag *drag,
const struct wmEvent *event,
- const char **tooltip);
+ const char **r_tooltip);
bool UI_context_copy_to_selected_list(struct bContext *C,
struct PointerRNA *ptr,
diff --git a/source/blender/editors/interface/interface_eyedropper.c b/source/blender/editors/interface/interface_eyedropper.c
index f69dbb94f19..5fd1cef6451 100644
--- a/source/blender/editors/interface/interface_eyedropper.c
+++ b/source/blender/editors/interface/interface_eyedropper.c
@@ -54,14 +54,14 @@ wmKeyMap *eyedropper_modal_keymap(wmKeyConfig *keyconf)
{0, NULL, 0, NULL, NULL},
};
- wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "Eyedropper Modal Map");
+ wmKeyMap *keymap = WM_modalkeymap_find(keyconf, "Eyedropper Modal Map");
/* this function is called for each spacetype, only needs to add map once */
if (keymap && keymap->modal_items) {
return NULL;
}
- keymap = WM_modalkeymap_add(keyconf, "Eyedropper Modal Map", modal_items);
+ keymap = WM_modalkeymap_ensure(keyconf, "Eyedropper Modal Map", modal_items);
/* assign to operators */
WM_modalkeymap_assign(keymap, "UI_OT_eyedropper_colorramp");
@@ -84,12 +84,12 @@ wmKeyMap *eyedropper_colorband_modal_keymap(wmKeyConfig *keyconf)
{0, NULL, 0, NULL, NULL},
};
- wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "Eyedropper ColorRamp PointSampling Map");
+ wmKeyMap *keymap = WM_modalkeymap_find(keyconf, "Eyedropper ColorRamp PointSampling Map");
if (keymap && keymap->modal_items) {
return keymap;
}
- keymap = WM_modalkeymap_add(
+ keymap = WM_modalkeymap_ensure(
keyconf, "Eyedropper ColorRamp PointSampling Map", modal_items_point);
/* assign to operators */
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 2dfa29f5646..d378613c035 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -3739,12 +3739,7 @@ static void ui_do_but_textedit(
if (utf8_buf && utf8_buf[0]) {
int utf8_buf_len = BLI_str_utf8_size(utf8_buf);
- /* keep this printf until utf8 is well tested */
- if (utf8_buf_len != 1) {
- printf("%s: utf8 char '%.*s'\n", __func__, utf8_buf_len, utf8_buf);
- }
-
- // strcpy(utf8_buf, "12345");
+ BLI_assert(utf8_buf_len != -1);
changed = ui_textedit_insert_buf(but, data, event->utf8_buf, utf8_buf_len);
}
else {
@@ -9694,15 +9689,9 @@ static int ui_handle_menu_event(bContext *C,
/* Apply scroll operation. */
if (scrolltype == MENU_SCROLL_DOWN) {
but = ui_but_next(but);
- if (but == NULL) {
- but = ui_but_first(block);
- }
}
else if (scrolltype == MENU_SCROLL_UP) {
but = ui_but_prev(but);
- if (but == NULL) {
- but = ui_but_last(block);
- }
}
else if (scrolltype == MENU_SCROLL_TOP) {
but = ui_but_first(block);
@@ -9712,6 +9701,20 @@ static int ui_handle_menu_event(bContext *C,
}
}
+ if (!but) {
+ /* wrap button or no active button*/
+ uiBut *but_wrap = NULL;
+ if (ELEM(scrolltype, MENU_SCROLL_UP, MENU_SCROLL_BOTTOM)) {
+ but_wrap = ui_but_last(block);
+ }
+ else if (ELEM(scrolltype, MENU_SCROLL_DOWN, MENU_SCROLL_TOP)) {
+ but_wrap = ui_but_first(block);
+ }
+ if (but_wrap) {
+ but = but_wrap;
+ }
+ }
+
if (but) {
ui_handle_button_activate(C, region, but, BUTTON_ACTIVATE);
ui_menu_scroll_to_but(region, block, but);
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index fed35ccff59..6c856a0e8dd 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -2771,7 +2771,7 @@ static uiBut *ui_item_menu(uiLayout *layout,
}
else if (icon) {
but = uiDefIconMenuBut(block, func, arg, icon, 0, 0, w, h, tip);
- if (force_menu) {
+ if (force_menu && name[0]) {
UI_but_drawflag_enable(but, UI_BUT_ICON_LEFT);
}
}
diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c
index 7533ebd4397..519ba4cbbdf 100644
--- a/source/blender/editors/interface/interface_ops.c
+++ b/source/blender/editors/interface/interface_ops.c
@@ -1251,7 +1251,7 @@ static bool ui_editsource_uibut_match(uiBut *but_a, uiBut *but_b)
void UI_editsource_active_but_test(uiBut *but)
{
- extern void PyC_FileAndNum_Safe(const char **filename, int *lineno);
+ extern void PyC_FileAndNum_Safe(const char **r_filename, int *r_lineno);
struct uiEditSourceButStore *but_store = MEM_callocN(sizeof(uiEditSourceButStore), __func__);
@@ -1703,7 +1703,7 @@ static void UI_OT_button_string_clear(wmOperatorType *ot)
bool UI_drop_color_poll(struct bContext *C,
wmDrag *drag,
const wmEvent *UNUSED(event),
- const char **UNUSED(tooltip))
+ const char **UNUSED(r_tooltip))
{
/* should only return true for regions that include buttons, for now
* return true always */
diff --git a/source/blender/editors/interface/interface_style.c b/source/blender/editors/interface/interface_style.c
index fa1f222d27f..63fc7825b26 100644
--- a/source/blender/editors/interface/interface_style.c
+++ b/source/blender/editors/interface/interface_style.c
@@ -422,8 +422,6 @@ void uiStyleInit(void)
{
uiFont *font;
uiStyle *style = U.uistyles.first;
- int monofont_size = datatoc_bmonofont_ttf_size;
- uchar *monofont_ttf = (uchar *)datatoc_bmonofont_ttf;
/* recover from uninitialized dpi */
if (U.dpi == 0) {
@@ -463,39 +461,15 @@ void uiStyleInit(void)
}
for (font = U.uifonts.first; font; font = font->next) {
+ const bool unique = false;
if (font->uifont_id == UIFONT_DEFAULT) {
-#ifdef WITH_INTERNATIONAL
- int font_size = datatoc_bfont_ttf_size;
- uchar *font_ttf = (uchar *)datatoc_bfont_ttf;
- static int last_font_size = 0;
-
- /* use unicode font for translation */
- if (U.transopts & USER_DOTRANSLATE) {
- font_ttf = BLF_get_unifont(&font_size);
-
- if (!font_ttf) {
- /* fall back if not found */
- font_size = datatoc_bfont_ttf_size;
- font_ttf = (uchar *)datatoc_bfont_ttf;
- }
- }
-
- /* relload only if needed */
- if (last_font_size != font_size) {
- BLF_unload("default");
- last_font_size = font_size;
- }
-
- font->blf_id = BLF_load_mem("default", font_ttf, font_size);
-#else
- font->blf_id = BLF_load_mem("default", (uchar *)datatoc_bfont_ttf, datatoc_bfont_ttf_size);
-#endif
+ font->blf_id = BLF_load_default(unique);
}
else {
font->blf_id = BLF_load(font->filename);
if (font->blf_id == -1) {
- font->blf_id = BLF_load_mem("default", (uchar *)datatoc_bfont_ttf, datatoc_bfont_ttf_size);
+ font->blf_id = BLF_load_default(unique);
}
}
@@ -521,27 +495,17 @@ void uiStyleInit(void)
ui_style_new(&U.uistyles, "Default Style", UIFONT_DEFAULT);
}
-#ifdef WITH_INTERNATIONAL
- /* use unicode font for text editor and interactive console */
- if (U.transopts & USER_DOTRANSLATE) {
- monofont_ttf = BLF_get_unifont_mono(&monofont_size);
-
- if (!monofont_ttf) {
- /* fall back if not found */
- monofont_size = datatoc_bmonofont_ttf_size;
- monofont_ttf = (uchar *)datatoc_bmonofont_ttf;
- }
- }
-#endif
-
/* XXX, this should be moved into a style,
* but for now best only load the monospaced font once. */
BLI_assert(blf_mono_font == -1);
+ /* Use unique font loading to avoid thread safety issues with mono font
+ * used for render metadata stamp in threads. */
if (U.font_path_ui_mono[0]) {
blf_mono_font = BLF_load_unique(U.font_path_ui_mono);
}
if (blf_mono_font == -1) {
- blf_mono_font = BLF_load_mem_unique("monospace", monofont_ttf, monofont_size);
+ const bool unique = true;
+ blf_mono_font = BLF_load_mono_default(unique);
}
BLF_size(blf_mono_font, 12 * U.pixelsize, 72);
@@ -584,7 +548,8 @@ void uiStyleInit(void)
* keep for now though, since without this there is no way to display many unicode chars.
*/
if (blf_mono_font_render == -1) {
- blf_mono_font_render = BLF_load_mem_unique("monospace", monofont_ttf, monofont_size);
+ const bool unique = true;
+ blf_mono_font_render = BLF_load_mono_default(unique);
}
BLF_size(blf_mono_font_render, 12 * U.pixelsize, 72);
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index 7e6ef11518a..fa4a0a1e07d 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -2520,6 +2520,13 @@ static void widget_draw_text_icon(const uiFontStyle *fstyle,
}
}
else if (but->drawflag & UI_BUT_TEXT_LEFT) {
+
+ /* Reduce the left padding for labels without an icon. */
+ if ((but->type == UI_BTYPE_LABEL) && !(but->flag & UI_HAS_ICON) &&
+ !ui_block_is_menu(but->block)) {
+ text_padding /= 2;
+ }
+
rect->xmin += text_padding;
}
else if (but->drawflag & UI_BUT_TEXT_RIGHT) {
diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c
index a93c80f02d2..adf0d6e372c 100644
--- a/source/blender/editors/interface/view2d.c
+++ b/source/blender/editors/interface/view2d.c
@@ -67,8 +67,8 @@ static void ui_view2d_curRect_validate_resize(View2D *v2d, bool resize, bool mas
BLI_INLINE int clamp_float_to_int(const float f)
{
- const float min = INT_MIN;
- const float max = INT_MAX;
+ const float min = (float)INT_MIN;
+ const float max = (float)INT_MAX;
if (UNLIKELY(f < min)) {
return min;
diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c
index 17af0cff23a..2adf441514b 100644
--- a/source/blender/editors/interface/view2d_ops.c
+++ b/source/blender/editors/interface/view2d_ops.c
@@ -62,7 +62,7 @@ static bool view2d_poll(bContext *C)
/** \} */
/* -------------------------------------------------------------------- */
-/** \name View Pan Operator
+/** \name View Pan Shared Utilities
* \{ */
/**
@@ -74,9 +74,9 @@ static bool view2d_poll(bContext *C)
* - `deltax, deltay` - define how much to move view by (relative to zoom-correction factor)
*/
-/* ------------------ Shared 'core' stuff ---------------------- */
-
-/* temp customdata for operator */
+/**
+ * Temporary custom-data for operator.
+ */
typedef struct v2dViewPanData {
/** screen where view pan was initiated */
bScreen *sc;
@@ -209,7 +209,11 @@ static void view_pan_exit(wmOperator *op)
}
}
-/* ------------------ Modal Drag Version (1) ---------------------- */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name View Pan Operator (modal drag-pan)
+ * \{ */
/* for 'redo' only, with no user input */
static int view_pan_exec(bContext *C, wmOperator *op)
@@ -350,7 +354,11 @@ static void VIEW2D_OT_pan(wmOperatorType *ot)
RNA_def_int(ot->srna, "deltay", 0, INT_MIN, INT_MAX, "Delta Y", "", INT_MIN, INT_MAX);
}
-/* ------------------ Scrollwheel Versions (2) ---------------------- */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name View Pan Operator (single step)
+ * \{ */
/* this operator only needs this single callback, where it calls the view_pan_*() methods */
static int view_scrollright_exec(bContext *C, wmOperator *op)
@@ -541,7 +549,7 @@ static void VIEW2D_OT_scroll_up(wmOperatorType *ot)
/** \} */
/* -------------------------------------------------------------------- */
-/** \name View Zoom Operator (single-step)
+/** \name View Zoom Shared Utilities
* \{ */
/**
@@ -558,9 +566,9 @@ static void VIEW2D_OT_scroll_up(wmOperatorType *ot)
* amount to enlarge 'cur' by.
*/
-/* ------------------ 'Shared' stuff ------------------------ */
-
-/* temp customdata for operator */
+/**
+ * Temporary custom-data for operator.
+ */
typedef struct v2dViewZoomData {
View2D *v2d; /* view2d we're operating in */
ARegion *region;
@@ -768,7 +776,11 @@ static void view_zoomstep_apply(bContext *C, wmOperator *op)
C, vzd, zoom_to_pos, RNA_float_get(op->ptr, "zoomfacx"), RNA_float_get(op->ptr, "zoomfacy"));
}
-/* --------------- Individual Operators ------------------- */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name View Zoom Operator (single step)
+ * \{ */
/* cleanup temp customdata */
static void view_zoomstep_exit(wmOperator *op)
@@ -1400,6 +1412,12 @@ static void VIEW2D_OT_zoom_border(wmOperatorType *ot)
WM_operator_properties_gesture_box_zoom(ot);
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name NDOF Pan/Zoom Operator
+ * \{ */
+
#ifdef WITH_INPUT_NDOF
static int view2d_ndof_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
@@ -1731,8 +1749,6 @@ enum {
SCROLLHANDLE_MAX_OUTSIDE,
} /*eV2DScrollerHandle_Zone*/;
-/* ------------------------ */
-
/**
* Check if mouse is within scroller handle.
*
diff --git a/source/blender/editors/mask/CMakeLists.txt b/source/blender/editors/mask/CMakeLists.txt
index 81c861ab4e4..66c055d9426 100644
--- a/source/blender/editors/mask/CMakeLists.txt
+++ b/source/blender/editors/mask/CMakeLists.txt
@@ -40,6 +40,7 @@ set(SRC
mask_edit.c
mask_editaction.c
mask_ops.c
+ mask_query.c
mask_relationships.c
mask_select.c
mask_shapekey.c
diff --git a/source/blender/editors/mask/mask_add.c b/source/blender/editors/mask/mask_add.c
index 80716195121..9945383211a 100644
--- a/source/blender/editors/mask/mask_add.c
+++ b/source/blender/editors/mask/mask_add.c
@@ -29,7 +29,6 @@
#include "BKE_mask.h"
#include "DEG_depsgraph.h"
-#include "DEG_depsgraph_query.h"
#include "DNA_mask_types.h"
#include "DNA_scene_types.h"
@@ -47,158 +46,6 @@
#include "mask_intern.h" /* own include */
-bool ED_mask_find_nearest_diff_point(const bContext *C,
- struct Mask *mask_orig,
- const float normal_co[2],
- int threshold,
- bool feather,
- float tangent[2],
- const bool use_deform,
- const bool use_project,
- MaskLayer **mask_layer_r,
- MaskSpline **spline_r,
- MaskSplinePoint **point_r,
- float *u_r,
- float *score_r)
-{
- ScrArea *sa = CTX_wm_area(C);
- ARegion *region = CTX_wm_region(C);
-
- MaskLayer *point_mask_layer;
- MaskSpline *point_spline;
- MaskSplinePoint *point = NULL;
- float dist_best_sq = FLT_MAX, co[2];
- int width, height;
- float u = 0.0f;
- float scalex, scaley;
-
- Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
- Mask *mask_eval = (Mask *)DEG_get_evaluated_id(depsgraph, &mask_orig->id);
-
- ED_mask_get_size(sa, &width, &height);
- ED_mask_pixelspace_factor(sa, region, &scalex, &scaley);
-
- co[0] = normal_co[0] * scalex;
- co[1] = normal_co[1] * scaley;
-
- for (MaskLayer *mask_layer_orig = mask_orig->masklayers.first,
- *mask_layer_eval = mask_eval->masklayers.first;
- mask_layer_orig != NULL;
- mask_layer_orig = mask_layer_orig->next, mask_layer_eval = mask_layer_eval->next) {
- if (mask_layer_orig->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) {
- continue;
- }
-
- for (MaskSpline *spline_orig = mask_layer_orig->splines.first,
- *spline_eval = mask_layer_eval->splines.first;
- spline_orig != NULL;
- spline_orig = spline_orig->next, spline_eval = spline_eval->next) {
- int i;
- MaskSplinePoint *cur_point_eval;
-
- for (i = 0, cur_point_eval = use_deform ? spline_eval->points_deform : spline_eval->points;
- i < spline_eval->tot_point;
- i++, cur_point_eval++) {
- unsigned int tot_diff_point;
- float *diff_points = BKE_mask_point_segment_diff(
- spline_eval, cur_point_eval, width, height, &tot_diff_point);
-
- if (diff_points) {
- int j, tot_point;
- unsigned int tot_feather_point;
- float *feather_points = NULL, *points;
-
- if (feather) {
- feather_points = BKE_mask_point_segment_feather_diff(
- spline_eval, cur_point_eval, width, height, &tot_feather_point);
-
- points = feather_points;
- tot_point = tot_feather_point;
- }
- else {
- points = diff_points;
- tot_point = tot_diff_point;
- }
-
- for (j = 0; j < tot_point - 1; j++) {
- float dist_sq, a[2], b[2];
-
- a[0] = points[2 * j] * scalex;
- a[1] = points[2 * j + 1] * scaley;
-
- b[0] = points[2 * j + 2] * scalex;
- b[1] = points[2 * j + 3] * scaley;
-
- dist_sq = dist_squared_to_line_segment_v2(co, a, b);
-
- if (dist_sq < dist_best_sq) {
- if (tangent) {
- sub_v2_v2v2(tangent, &diff_points[2 * j + 2], &diff_points[2 * j]);
- }
-
- point_mask_layer = mask_layer_orig;
- point_spline = spline_orig;
- point = use_deform ?
- &spline_orig->points[(cur_point_eval - spline_eval->points_deform)] :
- &spline_orig->points[(cur_point_eval - spline_eval->points)];
- dist_best_sq = dist_sq;
- u = (float)j / tot_point;
- }
- }
-
- if (feather_points != NULL) {
- MEM_freeN(feather_points);
- }
- MEM_freeN(diff_points);
- }
- }
- }
- }
-
- if (point && dist_best_sq < threshold) {
- if (mask_layer_r) {
- *mask_layer_r = point_mask_layer;
- }
-
- if (spline_r) {
- *spline_r = point_spline;
- }
-
- if (point_r) {
- *point_r = point;
- }
-
- if (u_r) {
- /* TODO(sergey): Projection fails in some weirdo cases.. */
- if (use_project) {
- u = BKE_mask_spline_project_co(point_spline, point, u, normal_co, MASK_PROJ_ANY);
- }
-
- *u_r = u;
- }
-
- if (score_r) {
- *score_r = dist_best_sq;
- }
-
- return true;
- }
-
- if (mask_layer_r) {
- *mask_layer_r = NULL;
- }
-
- if (spline_r) {
- *spline_r = NULL;
- }
-
- if (point_r) {
- *point_r = NULL;
- }
-
- return false;
-}
-
/******************** add vertex *********************/
static void setup_vertex_point(Mask *mask,
diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c
index a532ff9e1f0..2fda383ebb7 100644
--- a/source/blender/editors/mask/mask_draw.c
+++ b/source/blender/editors/mask/mask_draw.c
@@ -54,8 +54,6 @@
#include "DEG_depsgraph_query.h"
-#include "mask_intern.h" /* own include */
-
static void mask_spline_color_get(MaskLayer *mask_layer,
MaskSpline *spline,
const bool is_sel,
diff --git a/source/blender/editors/mask/mask_edit.c b/source/blender/editors/mask/mask_edit.c
index 1606d079462..e696cc37bd3 100644
--- a/source/blender/editors/mask/mask_edit.c
+++ b/source/blender/editors/mask/mask_edit.c
@@ -21,12 +21,9 @@
* \ingroup edmask
*/
-#include "BLI_math.h"
-
#include "BKE_context.h"
#include "BKE_mask.h"
-#include "DNA_mask_types.h"
#include "DNA_scene_types.h"
#include "WM_api.h"
@@ -34,20 +31,16 @@
#include "ED_clip.h"
#include "ED_image.h"
-#include "ED_mask.h" /* own include */
-#include "ED_object.h" /* ED_keymap_proportional_maskmode only */
-#include "ED_screen.h"
-#include "ED_select_utils.h"
+#include "ED_mask.h" /* own include */
#include "ED_sequencer.h"
-#include "ED_transform.h"
-
-#include "UI_view2d.h"
#include "RNA_access.h"
#include "mask_intern.h" /* own include */
-/********************** generic poll functions *********************/
+/* -------------------------------------------------------------------- */
+/** \name Poll Functions
+ * \{ */
bool ED_maskedit_poll(bContext *C)
{
@@ -81,344 +74,11 @@ bool ED_maskedit_mask_poll(bContext *C)
return false;
}
-/********************** registration *********************/
-
-/* takes event->mval */
-void ED_mask_mouse_pos(ScrArea *sa, ARegion *region, const int mval[2], float co[2])
-{
- if (sa) {
- switch (sa->spacetype) {
- case SPACE_CLIP: {
- SpaceClip *sc = sa->spacedata.first;
- ED_clip_mouse_pos(sc, region, mval, co);
- BKE_mask_coord_from_movieclip(sc->clip, &sc->user, co, co);
- break;
- }
- case SPACE_SEQ: {
- UI_view2d_region_to_view(&region->v2d, mval[0], mval[1], &co[0], &co[1]);
- break;
- }
- case SPACE_IMAGE: {
- SpaceImage *sima = sa->spacedata.first;
- ED_image_mouse_pos(sima, region, mval, co);
- BKE_mask_coord_from_image(sima->image, &sima->iuser, co, co);
- break;
- }
- default:
- /* possible other spaces from which mask editing is available */
- BLI_assert(0);
- zero_v2(co);
- break;
- }
- }
- else {
- BLI_assert(0);
- zero_v2(co);
- }
-}
-
-/* input: x/y - mval space
- * output: xr/yr - mask point space */
-void ED_mask_point_pos(ScrArea *sa, ARegion *region, float x, float y, float *xr, float *yr)
-{
- float co[2];
-
- if (sa) {
- switch (sa->spacetype) {
- case SPACE_CLIP: {
- SpaceClip *sc = sa->spacedata.first;
- ED_clip_point_stable_pos(sc, region, x, y, &co[0], &co[1]);
- BKE_mask_coord_from_movieclip(sc->clip, &sc->user, co, co);
- break;
- }
- case SPACE_SEQ:
- zero_v2(co); /* MASKTODO */
- break;
- case SPACE_IMAGE: {
- SpaceImage *sima = sa->spacedata.first;
- ED_image_point_pos(sima, region, x, y, &co[0], &co[1]);
- BKE_mask_coord_from_image(sima->image, &sima->iuser, co, co);
- break;
- }
- default:
- /* possible other spaces from which mask editing is available */
- BLI_assert(0);
- zero_v2(co);
- break;
- }
- }
- else {
- BLI_assert(0);
- zero_v2(co);
- }
-
- *xr = co[0];
- *yr = co[1];
-}
-
-void ED_mask_point_pos__reverse(
- ScrArea *sa, ARegion *region, float x, float y, float *xr, float *yr)
-{
- float co[2];
-
- if (sa) {
- switch (sa->spacetype) {
- case SPACE_CLIP: {
- SpaceClip *sc = sa->spacedata.first;
- co[0] = x;
- co[1] = y;
- BKE_mask_coord_to_movieclip(sc->clip, &sc->user, co, co);
- ED_clip_point_stable_pos__reverse(sc, region, co, co);
- break;
- }
- case SPACE_SEQ:
- zero_v2(co); /* MASKTODO */
- break;
- case SPACE_IMAGE: {
- SpaceImage *sima = sa->spacedata.first;
- co[0] = x;
- co[1] = y;
- BKE_mask_coord_to_image(sima->image, &sima->iuser, co, co);
- ED_image_point_pos__reverse(sima, region, co, co);
- break;
- }
- default:
- /* possible other spaces from which mask editing is available */
- BLI_assert(0);
- zero_v2(co);
- break;
- }
- }
- else {
- BLI_assert(0);
- zero_v2(co);
- }
-
- *xr = co[0];
- *yr = co[1];
-}
-
-void ED_mask_get_size(ScrArea *sa, int *width, int *height)
-{
- if (sa && sa->spacedata.first) {
- switch (sa->spacetype) {
- case SPACE_CLIP: {
- SpaceClip *sc = sa->spacedata.first;
- ED_space_clip_get_size(sc, width, height);
- break;
- }
- case SPACE_SEQ: {
- // Scene *scene = CTX_data_scene(C);
- // *width = (scene->r.size * scene->r.xsch) / 100;
- // *height = (scene->r.size * scene->r.ysch) / 100;
- break;
- }
- case SPACE_IMAGE: {
- SpaceImage *sima = sa->spacedata.first;
- ED_space_image_get_size(sima, width, height);
- break;
- }
- default:
- /* possible other spaces from which mask editing is available */
- BLI_assert(0);
- *width = 0;
- *height = 0;
- break;
- }
- }
- else {
- BLI_assert(0);
- *width = 0;
- *height = 0;
- }
-}
-
-void ED_mask_zoom(ScrArea *sa, ARegion *region, float *zoomx, float *zoomy)
-{
- if (sa && sa->spacedata.first) {
- switch (sa->spacetype) {
- case SPACE_CLIP: {
- SpaceClip *sc = sa->spacedata.first;
- ED_space_clip_get_zoom(sc, region, zoomx, zoomy);
- break;
- }
- case SPACE_SEQ: {
- *zoomx = *zoomy = 1.0f;
- break;
- }
- case SPACE_IMAGE: {
- SpaceImage *sima = sa->spacedata.first;
- ED_space_image_get_zoom(sima, region, zoomx, zoomy);
- break;
- }
- default:
- /* possible other spaces from which mask editing is available */
- BLI_assert(0);
- *zoomx = *zoomy = 1.0f;
- break;
- }
- }
- else {
- BLI_assert(0);
- *zoomx = *zoomy = 1.0f;
- }
-}
-
-void ED_mask_get_aspect(ScrArea *sa, ARegion *UNUSED(region), float *aspx, float *aspy)
-{
- if (sa && sa->spacedata.first) {
- switch (sa->spacetype) {
- case SPACE_CLIP: {
- SpaceClip *sc = sa->spacedata.first;
- ED_space_clip_get_aspect(sc, aspx, aspy);
- break;
- }
- case SPACE_SEQ: {
- *aspx = *aspy = 1.0f; /* MASKTODO - render aspect? */
- break;
- }
- case SPACE_IMAGE: {
- SpaceImage *sima = sa->spacedata.first;
- ED_space_image_get_aspect(sima, aspx, aspy);
- break;
- }
- default:
- /* possible other spaces from which mask editing is available */
- BLI_assert(0);
- *aspx = *aspy = 1.0f;
- break;
- }
- }
- else {
- BLI_assert(0);
- *aspx = *aspy = 1.0f;
- }
-}
-
-void ED_mask_pixelspace_factor(ScrArea *sa, ARegion *region, float *scalex, float *scaley)
-{
- if (sa && sa->spacedata.first) {
- switch (sa->spacetype) {
- case SPACE_CLIP: {
- SpaceClip *sc = sa->spacedata.first;
- float aspx, aspy;
-
- UI_view2d_scale_get(&region->v2d, scalex, scaley);
- ED_space_clip_get_aspect(sc, &aspx, &aspy);
+/** \} */
- *scalex *= aspx;
- *scaley *= aspy;
- break;
- }
- case SPACE_SEQ: {
- *scalex = *scaley = 1.0f; /* MASKTODO? */
- break;
- }
- case SPACE_IMAGE: {
- SpaceImage *sima = sa->spacedata.first;
- float aspx, aspy;
-
- UI_view2d_scale_get(&region->v2d, scalex, scaley);
- ED_space_image_get_aspect(sima, &aspx, &aspy);
-
- *scalex *= aspx;
- *scaley *= aspy;
- break;
- }
- default:
- /* possible other spaces from which mask editing is available */
- BLI_assert(0);
- *scalex = *scaley = 1.0f;
- break;
- }
- }
- else {
- BLI_assert(0);
- *scalex = *scaley = 1.0f;
- }
-}
-
-void ED_mask_cursor_location_get(ScrArea *sa, float cursor[2])
-{
- if (sa) {
- switch (sa->spacetype) {
- case SPACE_CLIP: {
- SpaceClip *space_clip = sa->spacedata.first;
- copy_v2_v2(cursor, space_clip->cursor);
- break;
- }
- case SPACE_SEQ: {
- zero_v2(cursor);
- break;
- }
- case SPACE_IMAGE: {
- SpaceImage *space_image = sa->spacedata.first;
- copy_v2_v2(cursor, space_image->cursor);
- break;
- }
- default:
- /* possible other spaces from which mask editing is available */
- BLI_assert(0);
- zero_v2(cursor);
- break;
- }
- }
- else {
- BLI_assert(0);
- zero_v2(cursor);
- }
-}
-
-bool ED_mask_selected_minmax(const bContext *C, float min[2], float max[2])
-{
- Mask *mask = CTX_data_edit_mask(C);
- bool ok = false;
-
- if (mask == NULL) {
- return ok;
- }
-
- INIT_MINMAX2(min, max);
- for (MaskLayer *mask_layer = mask->masklayers.first; mask_layer != NULL;
- mask_layer = mask_layer->next) {
- if (mask_layer->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) {
- continue;
- }
- for (MaskSpline *spline = mask_layer->splines.first; spline != NULL; spline = spline->next) {
- MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline);
- for (int i = 0; i < spline->tot_point; i++) {
- MaskSplinePoint *point = &spline->points[i];
- MaskSplinePoint *deform_point = &points_array[i];
- BezTriple *bezt = &point->bezt;
- float handle[2];
- if (!MASKPOINT_ISSEL_ANY(point)) {
- continue;
- }
- if (bezt->f2 & SELECT) {
- minmax_v2v2_v2(min, max, deform_point->bezt.vec[1]);
- }
- if (BKE_mask_point_handles_mode_get(point) == MASK_HANDLE_MODE_STICK) {
- BKE_mask_point_handle(deform_point, MASK_WHICH_HANDLE_STICK, handle);
- minmax_v2v2_v2(min, max, handle);
- }
- else {
- if ((bezt->f1 & SELECT) && (bezt->h1 != HD_VECT)) {
- BKE_mask_point_handle(deform_point, MASK_WHICH_HANDLE_LEFT, handle);
- minmax_v2v2_v2(min, max, handle);
- }
- if ((bezt->f3 & SELECT) && (bezt->h2 != HD_VECT)) {
- BKE_mask_point_handle(deform_point, MASK_WHICH_HANDLE_RIGHT, handle);
- minmax_v2v2_v2(min, max, handle);
- }
- }
- ok = true;
- }
- }
- }
- return ok;
-}
-
-/********************** registration *********************/
+/* -------------------------------------------------------------------- */
+/** \name Registration
+ * \{ */
void ED_operatortypes_mask(void)
{
@@ -522,3 +182,5 @@ void ED_operatormacros_mask(void)
RNA_boolean_set(otmacro->ptr, "use_proportional_edit", false);
RNA_boolean_set(otmacro->ptr, "mirror", false);
}
+
+/** \} */
diff --git a/source/blender/editors/mask/mask_intern.h b/source/blender/editors/mask/mask_intern.h
index 091cf4937ae..6a45af4d2a6 100644
--- a/source/blender/editors/mask/mask_intern.h
+++ b/source/blender/editors/mask/mask_intern.h
@@ -31,20 +31,6 @@ struct wmOperatorType;
/* internal exports only */
/* mask_add.c */
-bool ED_mask_find_nearest_diff_point(const struct bContext *C,
- struct Mask *mask,
- const float normal_co[2],
- int threshold,
- bool feather,
- float tangent[2],
- const bool use_deform,
- const bool use_project,
- struct MaskLayer **mask_layer_r,
- struct MaskSpline **spline_r,
- struct MaskSplinePoint **point_r,
- float *u_r,
- float *score_r);
-
void MASK_OT_add_vertex(struct wmOperatorType *ot);
void MASK_OT_add_feather_vertex(struct wmOperatorType *ot);
void MASK_OT_primitive_circle_add(struct wmOperatorType *ot);
@@ -72,25 +58,6 @@ void MASK_OT_normals_make_consistent(struct wmOperatorType *ot);
void MASK_OT_handle_type_set(struct wmOperatorType *ot);
-bool ED_mask_feather_find_nearest(const struct bContext *C,
- struct Mask *mask,
- const float normal_co[2],
- const float threshold,
- struct MaskLayer **mask_layer_r,
- struct MaskSpline **spline_r,
- struct MaskSplinePoint **point_r,
- struct MaskSplinePointUW **uw_r,
- float *score);
-
-struct MaskSplinePoint *ED_mask_point_find_nearest(const struct bContext *C,
- struct Mask *mask,
- const float normal_co[2],
- const float threshold,
- struct MaskLayer **mask_layer_r,
- struct MaskSpline **spline_r,
- eMaskWhichHandle *which_handle_r,
- float *score);
-
void MASK_OT_layer_move(struct wmOperatorType *ot);
void MASK_OT_duplicate(struct wmOperatorType *ot);
@@ -126,6 +93,38 @@ void ED_mask_select_flush_all(struct Mask *mask);
bool ED_maskedit_poll(struct bContext *C);
bool ED_maskedit_mask_poll(struct bContext *C);
+/* mask_query.c */
+bool ED_mask_find_nearest_diff_point(const struct bContext *C,
+ struct Mask *mask,
+ const float normal_co[2],
+ int threshold,
+ bool feather,
+ float tangent[2],
+ const bool use_deform,
+ const bool use_project,
+ struct MaskLayer **r_mask_layer,
+ struct MaskSpline **r_spline,
+ struct MaskSplinePoint **r_point,
+ float *r_u,
+ float *r_score);
+bool ED_mask_feather_find_nearest(const struct bContext *C,
+ struct Mask *mask,
+ const float normal_co[2],
+ const float threshold,
+ struct MaskLayer **r_mask_layer,
+ struct MaskSpline **r_spline,
+ struct MaskSplinePoint **r_point,
+ struct MaskSplinePointUW **r_uw,
+ float *r_score);
+struct MaskSplinePoint *ED_mask_point_find_nearest(const struct bContext *C,
+ struct Mask *mask,
+ const float normal_co[2],
+ const float threshold,
+ struct MaskLayer **r_mask_layer,
+ struct MaskSpline **r_spline,
+ eMaskWhichHandle *r_which_handle,
+ float *r_score);
+
/* mask_shapekey.c */
void MASK_OT_shape_key_insert(struct wmOperatorType *ot);
void MASK_OT_shape_key_clear(struct wmOperatorType *ot);
diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c
index 5e7d94dd567..c4e3763dd94 100644
--- a/source/blender/editors/mask/mask_ops.c
+++ b/source/blender/editors/mask/mask_ops.c
@@ -31,7 +31,6 @@
#include "BKE_mask.h"
#include "DEG_depsgraph.h"
-#include "DEG_depsgraph_query.h"
#include "DNA_mask_types.h"
#include "DNA_object_types.h" /* SELECT */
@@ -52,298 +51,6 @@
#include "mask_intern.h" /* own include */
-/******************** utility functions *********************/
-
-static void mask_point_scaled_handle(/*const*/ MaskSplinePoint *point,
- /*const*/ eMaskWhichHandle which_handle,
- const float scalex,
- const float scaley,
- float handle[2])
-{
- BKE_mask_point_handle(point, which_handle, handle);
- handle[0] *= scalex;
- handle[1] *= scaley;
-}
-
-MaskSplinePoint *ED_mask_point_find_nearest(const bContext *C,
- Mask *mask_orig,
- const float normal_co[2],
- const float threshold,
- MaskLayer **mask_layer_r,
- MaskSpline **spline_r,
- eMaskWhichHandle *which_handle_r,
- float *score)
-{
- ScrArea *sa = CTX_wm_area(C);
- ARegion *region = CTX_wm_region(C);
-
- MaskLayer *point_mask_layer = NULL;
- MaskSpline *point_spline = NULL;
- MaskSplinePoint *point = NULL;
- float co[2];
- const float threshold_sq = threshold * threshold;
- float len_sq = FLT_MAX, scalex, scaley;
- eMaskWhichHandle which_handle = MASK_WHICH_HANDLE_NONE;
- int width, height;
-
- Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
- Mask *mask_eval = (Mask *)DEG_get_evaluated_id(depsgraph, &mask_orig->id);
-
- ED_mask_get_size(sa, &width, &height);
- ED_mask_pixelspace_factor(sa, region, &scalex, &scaley);
-
- co[0] = normal_co[0] * scalex;
- co[1] = normal_co[1] * scaley;
-
- for (MaskLayer *mask_layer_orig = mask_orig->masklayers.first,
- *mask_layer_eval = mask_eval->masklayers.first;
- mask_layer_orig != NULL;
- mask_layer_orig = mask_layer_orig->next, mask_layer_eval = mask_layer_eval->next) {
-
- if (mask_layer_orig->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) {
- continue;
- }
-
- for (MaskSpline *spline_orig = mask_layer_orig->splines.first,
- *spline_eval = mask_layer_eval->splines.first;
- spline_orig != NULL;
- spline_orig = spline_orig->next, spline_eval = spline_eval->next) {
- MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline_eval);
-
- for (int i = 0; i < spline_orig->tot_point; i++) {
- MaskSplinePoint *cur_point_orig = &spline_orig->points[i];
- MaskSplinePoint *cur_point_deform_eval = &points_array[i];
- eMaskWhichHandle cur_which_handle = MASK_WHICH_HANDLE_NONE;
- BezTriple *bezt = &cur_point_deform_eval->bezt;
- float cur_len_sq, vec[2];
-
- vec[0] = bezt->vec[1][0] * scalex;
- vec[1] = bezt->vec[1][1] * scaley;
-
- cur_len_sq = len_squared_v2v2(co, vec);
-
- if (cur_len_sq < len_sq) {
- point_spline = spline_orig;
- point_mask_layer = mask_layer_orig;
- point = cur_point_orig;
- len_sq = cur_len_sq;
- which_handle = MASK_WHICH_HANDLE_NONE;
- }
-
- if (BKE_mask_point_handles_mode_get(cur_point_deform_eval) == MASK_HANDLE_MODE_STICK) {
- float handle[2];
- mask_point_scaled_handle(
- cur_point_deform_eval, MASK_WHICH_HANDLE_STICK, scalex, scaley, handle);
- cur_len_sq = len_squared_v2v2(co, handle);
- cur_which_handle = MASK_WHICH_HANDLE_STICK;
- }
- else {
- float handle_left[2], handle_right[2];
- float len_left_sq, len_right_sq;
- mask_point_scaled_handle(
- cur_point_deform_eval, MASK_WHICH_HANDLE_LEFT, scalex, scaley, handle_left);
- mask_point_scaled_handle(
- cur_point_deform_eval, MASK_WHICH_HANDLE_RIGHT, scalex, scaley, handle_right);
-
- len_left_sq = len_squared_v2v2(co, handle_left);
- len_right_sq = len_squared_v2v2(co, handle_right);
- if (i == 0) {
- if (len_left_sq <= len_right_sq) {
- if (bezt->h1 != HD_VECT) {
- cur_which_handle = MASK_WHICH_HANDLE_LEFT;
- cur_len_sq = len_left_sq;
- }
- }
- else if (bezt->h2 != HD_VECT) {
- cur_which_handle = MASK_WHICH_HANDLE_RIGHT;
- cur_len_sq = len_right_sq;
- }
- }
- else {
- if (len_right_sq <= len_left_sq) {
- if (bezt->h2 != HD_VECT) {
- cur_which_handle = MASK_WHICH_HANDLE_RIGHT;
- cur_len_sq = len_right_sq;
- }
- }
- else if (bezt->h1 != HD_VECT) {
- cur_which_handle = MASK_WHICH_HANDLE_LEFT;
- cur_len_sq = len_left_sq;
- }
- }
- }
-
- if (cur_len_sq <= len_sq && cur_which_handle != MASK_WHICH_HANDLE_NONE) {
- point_mask_layer = mask_layer_orig;
- point_spline = spline_orig;
- point = cur_point_orig;
- len_sq = cur_len_sq;
- which_handle = cur_which_handle;
- }
- }
- }
- }
-
- if (len_sq < threshold_sq) {
- if (mask_layer_r) {
- *mask_layer_r = point_mask_layer;
- }
-
- if (spline_r) {
- *spline_r = point_spline;
- }
-
- if (which_handle_r) {
- *which_handle_r = which_handle;
- }
-
- if (score) {
- *score = sqrtf(len_sq);
- }
-
- return point;
- }
-
- if (mask_layer_r) {
- *mask_layer_r = NULL;
- }
-
- if (spline_r) {
- *spline_r = NULL;
- }
-
- if (which_handle_r) {
- *which_handle_r = MASK_WHICH_HANDLE_NONE;
- }
-
- return NULL;
-}
-
-bool ED_mask_feather_find_nearest(const bContext *C,
- Mask *mask_orig,
- const float normal_co[2],
- const float threshold,
- MaskLayer **mask_layer_r,
- MaskSpline **spline_r,
- MaskSplinePoint **point_r,
- MaskSplinePointUW **uw_r,
- float *score)
-{
- ScrArea *sa = CTX_wm_area(C);
- ARegion *region = CTX_wm_region(C);
-
- MaskLayer *point_mask_layer = NULL;
- MaskSpline *point_spline = NULL;
- MaskSplinePoint *point = NULL;
- MaskSplinePointUW *uw = NULL;
- const float threshold_sq = threshold * threshold;
- float len = FLT_MAX, co[2];
- float scalex, scaley;
- int width, height;
-
- Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
- Mask *mask_eval = (Mask *)DEG_get_evaluated_id(depsgraph, &mask_orig->id);
-
- ED_mask_get_size(sa, &width, &height);
- ED_mask_pixelspace_factor(sa, region, &scalex, &scaley);
-
- co[0] = normal_co[0] * scalex;
- co[1] = normal_co[1] * scaley;
-
- for (MaskLayer *mask_layer_orig = mask_orig->masklayers.first,
- *mask_layer_eval = mask_eval->masklayers.first;
- mask_layer_orig != NULL;
- mask_layer_orig = mask_layer_orig->next, mask_layer_eval = mask_layer_eval->next) {
-
- for (MaskSpline *spline_orig = mask_layer_orig->splines.first,
- *spline_eval = mask_layer_eval->splines.first;
- spline_orig != NULL;
- spline_orig = spline_orig->next, spline_eval = spline_eval->next) {
- // MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline);
-
- int i, tot_feather_point;
- float(*feather_points)[2], (*fp)[2];
-
- if (mask_layer_orig->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) {
- continue;
- }
-
- feather_points = fp = BKE_mask_spline_feather_points(spline_eval, &tot_feather_point);
-
- for (i = 0; i < spline_orig->tot_point; i++) {
- int j;
- MaskSplinePoint *cur_point_orig = &spline_orig->points[i];
- MaskSplinePoint *cur_point_eval = &spline_eval->points[i];
-
- for (j = 0; j <= cur_point_eval->tot_uw; j++) {
- float cur_len_sq, vec[2];
-
- vec[0] = (*fp)[0] * scalex;
- vec[1] = (*fp)[1] * scaley;
-
- cur_len_sq = len_squared_v2v2(vec, co);
-
- if (point == NULL || cur_len_sq < len) {
- if (j == 0) {
- uw = NULL;
- }
- else {
- uw = &cur_point_orig->uw[j - 1];
- }
-
- point_mask_layer = mask_layer_orig;
- point_spline = spline_orig;
- point = cur_point_orig;
- len = cur_len_sq;
- }
-
- fp++;
- }
- }
-
- MEM_freeN(feather_points);
- }
- }
-
- if (len < threshold_sq) {
- if (mask_layer_r) {
- *mask_layer_r = point_mask_layer;
- }
-
- if (spline_r) {
- *spline_r = point_spline;
- }
-
- if (point_r) {
- *point_r = point;
- }
-
- if (uw_r) {
- *uw_r = uw;
- }
-
- if (score) {
- *score = sqrtf(len);
- }
-
- return true;
- }
-
- if (mask_layer_r) {
- *mask_layer_r = NULL;
- }
-
- if (spline_r) {
- *spline_r = NULL;
- }
-
- if (point_r) {
- *point_r = NULL;
- }
-
- return false;
-}
-
/******************** create new mask *********************/
Mask *ED_mask_new(bContext *C, const char *name)
@@ -549,8 +256,8 @@ static void mask_point_undistort_pos(SpaceClip *sc, float r_co[2], const float c
static bool spline_under_mouse_get(const bContext *C,
Mask *mask,
const float co[2],
- MaskLayer **mask_layer_r,
- MaskSpline **mask_spline_r)
+ MaskLayer **r_mask_layer,
+ MaskSpline **r_mask_spline)
{
const float threshold = 19.0f;
ScrArea *sa = CTX_wm_area(C);
@@ -561,8 +268,8 @@ static bool spline_under_mouse_get(const bContext *C,
MaskLayer *closest_layer = NULL;
MaskSpline *closest_spline = NULL;
bool undistort = false;
- *mask_layer_r = NULL;
- *mask_spline_r = NULL;
+ *r_mask_layer = NULL;
+ *r_mask_spline = NULL;
ED_mask_get_size(sa, &width, &height);
pixel_co[0] = co[0] * width;
pixel_co[1] = co[1] * height;
@@ -634,8 +341,8 @@ static bool spline_under_mouse_get(const bContext *C,
}
}
- *mask_layer_r = closest_layer;
- *mask_spline_r = closest_spline;
+ *r_mask_layer = closest_layer;
+ *r_mask_spline = closest_spline;
return true;
}
return false;
diff --git a/source/blender/editors/mask/mask_query.c b/source/blender/editors/mask/mask_query.c
new file mode 100644
index 00000000000..8caf5f2ed7b
--- /dev/null
+++ b/source/blender/editors/mask/mask_query.c
@@ -0,0 +1,833 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2012 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup edmask
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_math.h"
+
+#include "BKE_context.h"
+#include "BKE_mask.h"
+
+#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
+
+#include "DNA_mask_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
+
+#include "ED_clip.h"
+#include "ED_image.h"
+#include "ED_mask.h" /* own include */
+
+#include "UI_view2d.h"
+
+#include "mask_intern.h" /* own include */
+
+/* -------------------------------------------------------------------- */
+/** \name Spatial Queries
+ * \{ */
+
+bool ED_mask_find_nearest_diff_point(const bContext *C,
+ struct Mask *mask_orig,
+ const float normal_co[2],
+ int threshold,
+ bool feather,
+ float tangent[2],
+ const bool use_deform,
+ const bool use_project,
+ MaskLayer **r_mask_layer,
+ MaskSpline **r_spline,
+ MaskSplinePoint **r_point,
+ float *r_u,
+ float *r_score)
+{
+ ScrArea *sa = CTX_wm_area(C);
+ ARegion *region = CTX_wm_region(C);
+
+ MaskLayer *point_mask_layer;
+ MaskSpline *point_spline;
+ MaskSplinePoint *point = NULL;
+ float dist_best_sq = FLT_MAX, co[2];
+ int width, height;
+ float u = 0.0f;
+ float scalex, scaley;
+
+ Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
+ Mask *mask_eval = (Mask *)DEG_get_evaluated_id(depsgraph, &mask_orig->id);
+
+ ED_mask_get_size(sa, &width, &height);
+ ED_mask_pixelspace_factor(sa, region, &scalex, &scaley);
+
+ co[0] = normal_co[0] * scalex;
+ co[1] = normal_co[1] * scaley;
+
+ for (MaskLayer *mask_layer_orig = mask_orig->masklayers.first,
+ *mask_layer_eval = mask_eval->masklayers.first;
+ mask_layer_orig != NULL;
+ mask_layer_orig = mask_layer_orig->next, mask_layer_eval = mask_layer_eval->next) {
+ if (mask_layer_orig->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) {
+ continue;
+ }
+
+ for (MaskSpline *spline_orig = mask_layer_orig->splines.first,
+ *spline_eval = mask_layer_eval->splines.first;
+ spline_orig != NULL;
+ spline_orig = spline_orig->next, spline_eval = spline_eval->next) {
+ int i;
+ MaskSplinePoint *cur_point_eval;
+
+ for (i = 0, cur_point_eval = use_deform ? spline_eval->points_deform : spline_eval->points;
+ i < spline_eval->tot_point;
+ i++, cur_point_eval++) {
+ unsigned int tot_diff_point;
+ float *diff_points = BKE_mask_point_segment_diff(
+ spline_eval, cur_point_eval, width, height, &tot_diff_point);
+
+ if (diff_points) {
+ int j, tot_point;
+ unsigned int tot_feather_point;
+ float *feather_points = NULL, *points;
+
+ if (feather) {
+ feather_points = BKE_mask_point_segment_feather_diff(
+ spline_eval, cur_point_eval, width, height, &tot_feather_point);
+
+ points = feather_points;
+ tot_point = tot_feather_point;
+ }
+ else {
+ points = diff_points;
+ tot_point = tot_diff_point;
+ }
+
+ for (j = 0; j < tot_point - 1; j++) {
+ float dist_sq, a[2], b[2];
+
+ a[0] = points[2 * j] * scalex;
+ a[1] = points[2 * j + 1] * scaley;
+
+ b[0] = points[2 * j + 2] * scalex;
+ b[1] = points[2 * j + 3] * scaley;
+
+ dist_sq = dist_squared_to_line_segment_v2(co, a, b);
+
+ if (dist_sq < dist_best_sq) {
+ if (tangent) {
+ sub_v2_v2v2(tangent, &diff_points[2 * j + 2], &diff_points[2 * j]);
+ }
+
+ point_mask_layer = mask_layer_orig;
+ point_spline = spline_orig;
+ point = use_deform ?
+ &spline_orig->points[(cur_point_eval - spline_eval->points_deform)] :
+ &spline_orig->points[(cur_point_eval - spline_eval->points)];
+ dist_best_sq = dist_sq;
+ u = (float)j / tot_point;
+ }
+ }
+
+ if (feather_points != NULL) {
+ MEM_freeN(feather_points);
+ }
+ MEM_freeN(diff_points);
+ }
+ }
+ }
+ }
+
+ if (point && dist_best_sq < threshold) {
+ if (r_mask_layer) {
+ *r_mask_layer = point_mask_layer;
+ }
+
+ if (r_spline) {
+ *r_spline = point_spline;
+ }
+
+ if (r_point) {
+ *r_point = point;
+ }
+
+ if (r_u) {
+ /* TODO(sergey): Projection fails in some weirdo cases.. */
+ if (use_project) {
+ u = BKE_mask_spline_project_co(point_spline, point, u, normal_co, MASK_PROJ_ANY);
+ }
+
+ *r_u = u;
+ }
+
+ if (r_score) {
+ *r_score = dist_best_sq;
+ }
+
+ return true;
+ }
+
+ if (r_mask_layer) {
+ *r_mask_layer = NULL;
+ }
+
+ if (r_spline) {
+ *r_spline = NULL;
+ }
+
+ if (r_point) {
+ *r_point = NULL;
+ }
+
+ return false;
+}
+
+static void mask_point_scaled_handle(const MaskSplinePoint *point,
+ const eMaskWhichHandle which_handle,
+ const float scalex,
+ const float scaley,
+ float handle[2])
+{
+ BKE_mask_point_handle(point, which_handle, handle);
+ handle[0] *= scalex;
+ handle[1] *= scaley;
+}
+
+MaskSplinePoint *ED_mask_point_find_nearest(const bContext *C,
+ Mask *mask_orig,
+ const float normal_co[2],
+ const float threshold,
+ MaskLayer **r_mask_layer,
+ MaskSpline **r_spline,
+ eMaskWhichHandle *r_which_handle,
+ float *r_score)
+{
+ ScrArea *sa = CTX_wm_area(C);
+ ARegion *region = CTX_wm_region(C);
+
+ MaskLayer *point_mask_layer = NULL;
+ MaskSpline *point_spline = NULL;
+ MaskSplinePoint *point = NULL;
+ float co[2];
+ const float threshold_sq = threshold * threshold;
+ float len_sq = FLT_MAX, scalex, scaley;
+ eMaskWhichHandle which_handle = MASK_WHICH_HANDLE_NONE;
+ int width, height;
+
+ Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
+ Mask *mask_eval = (Mask *)DEG_get_evaluated_id(depsgraph, &mask_orig->id);
+
+ ED_mask_get_size(sa, &width, &height);
+ ED_mask_pixelspace_factor(sa, region, &scalex, &scaley);
+
+ co[0] = normal_co[0] * scalex;
+ co[1] = normal_co[1] * scaley;
+
+ for (MaskLayer *mask_layer_orig = mask_orig->masklayers.first,
+ *mask_layer_eval = mask_eval->masklayers.first;
+ mask_layer_orig != NULL;
+ mask_layer_orig = mask_layer_orig->next, mask_layer_eval = mask_layer_eval->next) {
+
+ if (mask_layer_orig->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) {
+ continue;
+ }
+
+ for (MaskSpline *spline_orig = mask_layer_orig->splines.first,
+ *spline_eval = mask_layer_eval->splines.first;
+ spline_orig != NULL;
+ spline_orig = spline_orig->next, spline_eval = spline_eval->next) {
+ MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline_eval);
+
+ for (int i = 0; i < spline_orig->tot_point; i++) {
+ MaskSplinePoint *cur_point_orig = &spline_orig->points[i];
+ const MaskSplinePoint *cur_point_deform_eval = &points_array[i];
+ eMaskWhichHandle cur_which_handle = MASK_WHICH_HANDLE_NONE;
+ const BezTriple *bezt = &cur_point_deform_eval->bezt;
+ float cur_len_sq, vec[2];
+
+ vec[0] = bezt->vec[1][0] * scalex;
+ vec[1] = bezt->vec[1][1] * scaley;
+
+ cur_len_sq = len_squared_v2v2(co, vec);
+
+ if (cur_len_sq < len_sq) {
+ point_spline = spline_orig;
+ point_mask_layer = mask_layer_orig;
+ point = cur_point_orig;
+ len_sq = cur_len_sq;
+ which_handle = MASK_WHICH_HANDLE_NONE;
+ }
+
+ if (BKE_mask_point_handles_mode_get(cur_point_deform_eval) == MASK_HANDLE_MODE_STICK) {
+ float handle[2];
+ mask_point_scaled_handle(
+ cur_point_deform_eval, MASK_WHICH_HANDLE_STICK, scalex, scaley, handle);
+ cur_len_sq = len_squared_v2v2(co, handle);
+ cur_which_handle = MASK_WHICH_HANDLE_STICK;
+ }
+ else {
+ float handle_left[2], handle_right[2];
+ float len_left_sq, len_right_sq;
+ mask_point_scaled_handle(
+ cur_point_deform_eval, MASK_WHICH_HANDLE_LEFT, scalex, scaley, handle_left);
+ mask_point_scaled_handle(
+ cur_point_deform_eval, MASK_WHICH_HANDLE_RIGHT, scalex, scaley, handle_right);
+
+ len_left_sq = len_squared_v2v2(co, handle_left);
+ len_right_sq = len_squared_v2v2(co, handle_right);
+ if (i == 0) {
+ if (len_left_sq <= len_right_sq) {
+ if (bezt->h1 != HD_VECT) {
+ cur_which_handle = MASK_WHICH_HANDLE_LEFT;
+ cur_len_sq = len_left_sq;
+ }
+ }
+ else if (bezt->h2 != HD_VECT) {
+ cur_which_handle = MASK_WHICH_HANDLE_RIGHT;
+ cur_len_sq = len_right_sq;
+ }
+ }
+ else {
+ if (len_right_sq <= len_left_sq) {
+ if (bezt->h2 != HD_VECT) {
+ cur_which_handle = MASK_WHICH_HANDLE_RIGHT;
+ cur_len_sq = len_right_sq;
+ }
+ }
+ else if (bezt->h1 != HD_VECT) {
+ cur_which_handle = MASK_WHICH_HANDLE_LEFT;
+ cur_len_sq = len_left_sq;
+ }
+ }
+ }
+
+ if (cur_len_sq <= len_sq && cur_which_handle != MASK_WHICH_HANDLE_NONE) {
+ point_mask_layer = mask_layer_orig;
+ point_spline = spline_orig;
+ point = cur_point_orig;
+ len_sq = cur_len_sq;
+ which_handle = cur_which_handle;
+ }
+ }
+ }
+ }
+
+ if (len_sq < threshold_sq) {
+ if (r_mask_layer) {
+ *r_mask_layer = point_mask_layer;
+ }
+
+ if (r_spline) {
+ *r_spline = point_spline;
+ }
+
+ if (r_which_handle) {
+ *r_which_handle = which_handle;
+ }
+
+ if (r_score) {
+ *r_score = sqrtf(len_sq);
+ }
+
+ return point;
+ }
+
+ if (r_mask_layer) {
+ *r_mask_layer = NULL;
+ }
+
+ if (r_spline) {
+ *r_spline = NULL;
+ }
+
+ if (r_which_handle) {
+ *r_which_handle = MASK_WHICH_HANDLE_NONE;
+ }
+
+ return NULL;
+}
+
+bool ED_mask_feather_find_nearest(const bContext *C,
+ Mask *mask_orig,
+ const float normal_co[2],
+ const float threshold,
+ MaskLayer **r_mask_layer,
+ MaskSpline **r_spline,
+ MaskSplinePoint **r_point,
+ MaskSplinePointUW **r_uw,
+ float *r_score)
+{
+ ScrArea *sa = CTX_wm_area(C);
+ ARegion *region = CTX_wm_region(C);
+
+ MaskLayer *point_mask_layer = NULL;
+ MaskSpline *point_spline = NULL;
+ MaskSplinePoint *point = NULL;
+ MaskSplinePointUW *uw = NULL;
+ const float threshold_sq = threshold * threshold;
+ float len = FLT_MAX, co[2];
+ float scalex, scaley;
+ int width, height;
+
+ Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
+ Mask *mask_eval = (Mask *)DEG_get_evaluated_id(depsgraph, &mask_orig->id);
+
+ ED_mask_get_size(sa, &width, &height);
+ ED_mask_pixelspace_factor(sa, region, &scalex, &scaley);
+
+ co[0] = normal_co[0] * scalex;
+ co[1] = normal_co[1] * scaley;
+
+ for (MaskLayer *mask_layer_orig = mask_orig->masklayers.first,
+ *mask_layer_eval = mask_eval->masklayers.first;
+ mask_layer_orig != NULL;
+ mask_layer_orig = mask_layer_orig->next, mask_layer_eval = mask_layer_eval->next) {
+
+ for (MaskSpline *spline_orig = mask_layer_orig->splines.first,
+ *spline_eval = mask_layer_eval->splines.first;
+ spline_orig != NULL;
+ spline_orig = spline_orig->next, spline_eval = spline_eval->next) {
+ // MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline);
+
+ int i, tot_feather_point;
+ float(*feather_points)[2], (*fp)[2];
+
+ if (mask_layer_orig->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) {
+ continue;
+ }
+
+ feather_points = fp = BKE_mask_spline_feather_points(spline_eval, &tot_feather_point);
+
+ for (i = 0; i < spline_orig->tot_point; i++) {
+ int j;
+ MaskSplinePoint *cur_point_orig = &spline_orig->points[i];
+ MaskSplinePoint *cur_point_eval = &spline_eval->points[i];
+
+ for (j = 0; j <= cur_point_eval->tot_uw; j++) {
+ float cur_len_sq, vec[2];
+
+ vec[0] = (*fp)[0] * scalex;
+ vec[1] = (*fp)[1] * scaley;
+
+ cur_len_sq = len_squared_v2v2(vec, co);
+
+ if (point == NULL || cur_len_sq < len) {
+ if (j == 0) {
+ uw = NULL;
+ }
+ else {
+ uw = &cur_point_orig->uw[j - 1];
+ }
+
+ point_mask_layer = mask_layer_orig;
+ point_spline = spline_orig;
+ point = cur_point_orig;
+ len = cur_len_sq;
+ }
+
+ fp++;
+ }
+ }
+
+ MEM_freeN(feather_points);
+ }
+ }
+
+ if (len < threshold_sq) {
+ if (r_mask_layer) {
+ *r_mask_layer = point_mask_layer;
+ }
+
+ if (r_spline) {
+ *r_spline = point_spline;
+ }
+
+ if (r_point) {
+ *r_point = point;
+ }
+
+ if (r_uw) {
+ *r_uw = uw;
+ }
+
+ if (r_score) {
+ *r_score = sqrtf(len);
+ }
+
+ return true;
+ }
+
+ if (r_mask_layer) {
+ *r_mask_layer = NULL;
+ }
+
+ if (r_spline) {
+ *r_spline = NULL;
+ }
+
+ if (r_point) {
+ *r_point = NULL;
+ }
+
+ return false;
+}
+
+/* takes event->mval */
+void ED_mask_mouse_pos(ScrArea *sa, ARegion *region, const int mval[2], float co[2])
+{
+ if (sa) {
+ switch (sa->spacetype) {
+ case SPACE_CLIP: {
+ SpaceClip *sc = sa->spacedata.first;
+ ED_clip_mouse_pos(sc, region, mval, co);
+ BKE_mask_coord_from_movieclip(sc->clip, &sc->user, co, co);
+ break;
+ }
+ case SPACE_SEQ: {
+ UI_view2d_region_to_view(&region->v2d, mval[0], mval[1], &co[0], &co[1]);
+ break;
+ }
+ case SPACE_IMAGE: {
+ SpaceImage *sima = sa->spacedata.first;
+ ED_image_mouse_pos(sima, region, mval, co);
+ BKE_mask_coord_from_image(sima->image, &sima->iuser, co, co);
+ break;
+ }
+ default:
+ /* possible other spaces from which mask editing is available */
+ BLI_assert(0);
+ zero_v2(co);
+ break;
+ }
+ }
+ else {
+ BLI_assert(0);
+ zero_v2(co);
+ }
+}
+
+/* input: x/y - mval space
+ * output: xr/yr - mask point space */
+void ED_mask_point_pos(ScrArea *sa, ARegion *region, float x, float y, float *xr, float *yr)
+{
+ float co[2];
+
+ if (sa) {
+ switch (sa->spacetype) {
+ case SPACE_CLIP: {
+ SpaceClip *sc = sa->spacedata.first;
+ ED_clip_point_stable_pos(sc, region, x, y, &co[0], &co[1]);
+ BKE_mask_coord_from_movieclip(sc->clip, &sc->user, co, co);
+ break;
+ }
+ case SPACE_SEQ:
+ zero_v2(co); /* MASKTODO */
+ break;
+ case SPACE_IMAGE: {
+ SpaceImage *sima = sa->spacedata.first;
+ ED_image_point_pos(sima, region, x, y, &co[0], &co[1]);
+ BKE_mask_coord_from_image(sima->image, &sima->iuser, co, co);
+ break;
+ }
+ default:
+ /* possible other spaces from which mask editing is available */
+ BLI_assert(0);
+ zero_v2(co);
+ break;
+ }
+ }
+ else {
+ BLI_assert(0);
+ zero_v2(co);
+ }
+
+ *xr = co[0];
+ *yr = co[1];
+}
+
+void ED_mask_point_pos__reverse(
+ ScrArea *sa, ARegion *region, float x, float y, float *xr, float *yr)
+{
+ float co[2];
+
+ if (sa) {
+ switch (sa->spacetype) {
+ case SPACE_CLIP: {
+ SpaceClip *sc = sa->spacedata.first;
+ co[0] = x;
+ co[1] = y;
+ BKE_mask_coord_to_movieclip(sc->clip, &sc->user, co, co);
+ ED_clip_point_stable_pos__reverse(sc, region, co, co);
+ break;
+ }
+ case SPACE_SEQ:
+ zero_v2(co); /* MASKTODO */
+ break;
+ case SPACE_IMAGE: {
+ SpaceImage *sima = sa->spacedata.first;
+ co[0] = x;
+ co[1] = y;
+ BKE_mask_coord_to_image(sima->image, &sima->iuser, co, co);
+ ED_image_point_pos__reverse(sima, region, co, co);
+ break;
+ }
+ default:
+ /* possible other spaces from which mask editing is available */
+ BLI_assert(0);
+ zero_v2(co);
+ break;
+ }
+ }
+ else {
+ BLI_assert(0);
+ zero_v2(co);
+ }
+
+ *xr = co[0];
+ *yr = co[1];
+}
+
+bool ED_mask_selected_minmax(const bContext *C, float min[2], float max[2])
+{
+ Mask *mask = CTX_data_edit_mask(C);
+ bool ok = false;
+
+ if (mask == NULL) {
+ return ok;
+ }
+
+ INIT_MINMAX2(min, max);
+ for (MaskLayer *mask_layer = mask->masklayers.first; mask_layer != NULL;
+ mask_layer = mask_layer->next) {
+ if (mask_layer->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) {
+ continue;
+ }
+ for (MaskSpline *spline = mask_layer->splines.first; spline != NULL; spline = spline->next) {
+ MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline);
+ for (int i = 0; i < spline->tot_point; i++) {
+ const MaskSplinePoint *point = &spline->points[i];
+ const MaskSplinePoint *deform_point = &points_array[i];
+ const BezTriple *bezt = &point->bezt;
+ float handle[2];
+ if (!MASKPOINT_ISSEL_ANY(point)) {
+ continue;
+ }
+ if (bezt->f2 & SELECT) {
+ minmax_v2v2_v2(min, max, deform_point->bezt.vec[1]);
+ }
+ if (BKE_mask_point_handles_mode_get(point) == MASK_HANDLE_MODE_STICK) {
+ BKE_mask_point_handle(deform_point, MASK_WHICH_HANDLE_STICK, handle);
+ minmax_v2v2_v2(min, max, handle);
+ }
+ else {
+ if ((bezt->f1 & SELECT) && (bezt->h1 != HD_VECT)) {
+ BKE_mask_point_handle(deform_point, MASK_WHICH_HANDLE_LEFT, handle);
+ minmax_v2v2_v2(min, max, handle);
+ }
+ if ((bezt->f3 & SELECT) && (bezt->h2 != HD_VECT)) {
+ BKE_mask_point_handle(deform_point, MASK_WHICH_HANDLE_RIGHT, handle);
+ minmax_v2v2_v2(min, max, handle);
+ }
+ }
+ ok = true;
+ }
+ }
+ }
+ return ok;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Generic 2D View Queries
+ * \{ */
+
+void ED_mask_get_size(ScrArea *sa, int *width, int *height)
+{
+ if (sa && sa->spacedata.first) {
+ switch (sa->spacetype) {
+ case SPACE_CLIP: {
+ SpaceClip *sc = sa->spacedata.first;
+ ED_space_clip_get_size(sc, width, height);
+ break;
+ }
+ case SPACE_SEQ: {
+ // Scene *scene = CTX_data_scene(C);
+ // *width = (scene->r.size * scene->r.xsch) / 100;
+ // *height = (scene->r.size * scene->r.ysch) / 100;
+ break;
+ }
+ case SPACE_IMAGE: {
+ SpaceImage *sima = sa->spacedata.first;
+ ED_space_image_get_size(sima, width, height);
+ break;
+ }
+ default:
+ /* possible other spaces from which mask editing is available */
+ BLI_assert(0);
+ *width = 0;
+ *height = 0;
+ break;
+ }
+ }
+ else {
+ BLI_assert(0);
+ *width = 0;
+ *height = 0;
+ }
+}
+
+void ED_mask_zoom(ScrArea *sa, ARegion *region, float *zoomx, float *zoomy)
+{
+ if (sa && sa->spacedata.first) {
+ switch (sa->spacetype) {
+ case SPACE_CLIP: {
+ SpaceClip *sc = sa->spacedata.first;
+ ED_space_clip_get_zoom(sc, region, zoomx, zoomy);
+ break;
+ }
+ case SPACE_SEQ: {
+ *zoomx = *zoomy = 1.0f;
+ break;
+ }
+ case SPACE_IMAGE: {
+ SpaceImage *sima = sa->spacedata.first;
+ ED_space_image_get_zoom(sima, region, zoomx, zoomy);
+ break;
+ }
+ default:
+ /* possible other spaces from which mask editing is available */
+ BLI_assert(0);
+ *zoomx = *zoomy = 1.0f;
+ break;
+ }
+ }
+ else {
+ BLI_assert(0);
+ *zoomx = *zoomy = 1.0f;
+ }
+}
+
+void ED_mask_get_aspect(ScrArea *sa, ARegion *UNUSED(region), float *aspx, float *aspy)
+{
+ if (sa && sa->spacedata.first) {
+ switch (sa->spacetype) {
+ case SPACE_CLIP: {
+ SpaceClip *sc = sa->spacedata.first;
+ ED_space_clip_get_aspect(sc, aspx, aspy);
+ break;
+ }
+ case SPACE_SEQ: {
+ *aspx = *aspy = 1.0f; /* MASKTODO - render aspect? */
+ break;
+ }
+ case SPACE_IMAGE: {
+ SpaceImage *sima = sa->spacedata.first;
+ ED_space_image_get_aspect(sima, aspx, aspy);
+ break;
+ }
+ default:
+ /* possible other spaces from which mask editing is available */
+ BLI_assert(0);
+ *aspx = *aspy = 1.0f;
+ break;
+ }
+ }
+ else {
+ BLI_assert(0);
+ *aspx = *aspy = 1.0f;
+ }
+}
+
+void ED_mask_pixelspace_factor(ScrArea *sa, ARegion *region, float *scalex, float *scaley)
+{
+ if (sa && sa->spacedata.first) {
+ switch (sa->spacetype) {
+ case SPACE_CLIP: {
+ SpaceClip *sc = sa->spacedata.first;
+ float aspx, aspy;
+
+ UI_view2d_scale_get(&region->v2d, scalex, scaley);
+ ED_space_clip_get_aspect(sc, &aspx, &aspy);
+
+ *scalex *= aspx;
+ *scaley *= aspy;
+ break;
+ }
+ case SPACE_SEQ: {
+ *scalex = *scaley = 1.0f; /* MASKTODO? */
+ break;
+ }
+ case SPACE_IMAGE: {
+ SpaceImage *sima = sa->spacedata.first;
+ float aspx, aspy;
+
+ UI_view2d_scale_get(&region->v2d, scalex, scaley);
+ ED_space_image_get_aspect(sima, &aspx, &aspy);
+
+ *scalex *= aspx;
+ *scaley *= aspy;
+ break;
+ }
+ default:
+ /* possible other spaces from which mask editing is available */
+ BLI_assert(0);
+ *scalex = *scaley = 1.0f;
+ break;
+ }
+ }
+ else {
+ BLI_assert(0);
+ *scalex = *scaley = 1.0f;
+ }
+}
+
+void ED_mask_cursor_location_get(ScrArea *sa, float cursor[2])
+{
+ if (sa) {
+ switch (sa->spacetype) {
+ case SPACE_CLIP: {
+ SpaceClip *space_clip = sa->spacedata.first;
+ copy_v2_v2(cursor, space_clip->cursor);
+ break;
+ }
+ case SPACE_SEQ: {
+ zero_v2(cursor);
+ break;
+ }
+ case SPACE_IMAGE: {
+ SpaceImage *space_image = sa->spacedata.first;
+ copy_v2_v2(cursor, space_image->cursor);
+ break;
+ }
+ default:
+ /* possible other spaces from which mask editing is available */
+ BLI_assert(0);
+ zero_v2(cursor);
+ break;
+ }
+ }
+ else {
+ BLI_assert(0);
+ zero_v2(cursor);
+ }
+}
+
+/** \} */
diff --git a/source/blender/editors/mask/mask_select.c b/source/blender/editors/mask/mask_select.c
index 53ef398ccd6..b21d20b360a 100644
--- a/source/blender/editors/mask/mask_select.c
+++ b/source/blender/editors/mask/mask_select.c
@@ -38,7 +38,6 @@
#include "ED_clip.h"
#include "ED_mask.h" /* own include */
-#include "ED_screen.h"
#include "ED_select_utils.h"
#include "RNA_access.h"
diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c
index 987447c3663..3d20b58b905 100644
--- a/source/blender/editors/mesh/editface.c
+++ b/source/blender/editors/mesh/editface.c
@@ -493,8 +493,10 @@ void paintvert_tag_select_update(struct bContext *C, struct Object *ob)
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob->data);
}
-/* note: if the caller passes false to flush_flags,
- * then they will need to run paintvert_flush_flags(ob) themselves */
+/**
+ * \note if the caller passes false to flush_flags,
+ * then they will need to run #paintvert_flush_flags(ob) themselves.
+ */
bool paintvert_deselect_all_visible(Object *ob, int action, bool flush_flags)
{
Mesh *me;
diff --git a/source/blender/editors/mesh/editmesh_bevel.c b/source/blender/editors/mesh/editmesh_bevel.c
index 10c290e2be9..e91aaea91e0 100644
--- a/source/blender/editors/mesh/editmesh_bevel.c
+++ b/source/blender/editors/mesh/editmesh_bevel.c
@@ -690,14 +690,14 @@ wmKeyMap *bevel_modal_keymap(wmKeyConfig *keyconf)
{0, NULL, 0, NULL, NULL},
};
- wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "Bevel Modal Map");
+ wmKeyMap *keymap = WM_modalkeymap_find(keyconf, "Bevel Modal Map");
/* This function is called for each spacetype, only needs to add map once */
if (keymap && keymap->modal_items) {
return NULL;
}
- keymap = WM_modalkeymap_add(keyconf, "Bevel Modal Map", modal_items);
+ keymap = WM_modalkeymap_ensure(keyconf, "Bevel Modal Map", modal_items);
WM_modalkeymap_assign(keymap, "MESH_OT_bevel");
diff --git a/source/blender/editors/mesh/editmesh_extrude.c b/source/blender/editors/mesh/editmesh_extrude.c
index 1ea1501fc66..23f622ac359 100644
--- a/source/blender/editors/mesh/editmesh_extrude.c
+++ b/source/blender/editors/mesh/editmesh_extrude.c
@@ -274,11 +274,27 @@ static bool edbm_extrude_ex(Object *obedit,
static int edbm_extrude_repeat_exec(bContext *C, wmOperator *op)
{
- RegionView3D *rv3d = CTX_wm_region_view3d(C);
+
+ PropertyRNA *prop = RNA_struct_find_property(op->ptr, "offset");
const int steps = RNA_int_get(op->ptr, "steps");
- const float offs = RNA_float_get(op->ptr, "offset");
- float dvec[3], tmat[3][3], bmat[3][3];
- short a;
+ const float scale_offset = RNA_float_get(op->ptr, "scale_offset");
+ float offset[3];
+
+ if (!RNA_property_is_set(op->ptr, prop)) {
+ RegionView3D *rv3d = CTX_wm_region_view3d(C);
+ if (rv3d != NULL) {
+ normalize_v3_v3(offset, rv3d->persinv[2]);
+ }
+ else {
+ copy_v3_v3(offset, (const float[3]){0, 0, 1});
+ }
+ RNA_property_float_set_array(op->ptr, prop, offset);
+ }
+ else {
+ RNA_property_float_get_array(op->ptr, prop, offset);
+ }
+
+ mul_v3_fl(offset, scale_offset);
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
@@ -286,22 +302,19 @@ static int edbm_extrude_repeat_exec(bContext *C, wmOperator *op)
view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ float offset_local[3], tmat[3][3];
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
- /* dvec */
- normalize_v3_v3_length(dvec, rv3d->persinv[2], offs);
+ copy_m3_m4(tmat, obedit->obmat);
+ invert_m3(tmat);
+ mul_v3_m3v3(offset_local, tmat, offset);
- /* base correction */
- copy_m3_m4(bmat, obedit->obmat);
- invert_m3_m3(tmat, bmat);
- mul_m3_v3(tmat, dvec);
-
- for (a = 0; a < steps; a++) {
- edbm_extrude_ex(obedit, em, BM_ALL_NOLOOP, BM_ELEM_SELECT, false, false, false);
-
- BMO_op_callf(em->bm, BMO_FLAG_DEFAULTS, "translate vec=%v verts=%hv", dvec, BM_ELEM_SELECT);
+ for (int a = 0; a < steps; a++) {
+ edbm_extrude_ex(obedit, em, BM_ALL_NOLOOP, BM_ELEM_SELECT, false, false, true);
+ BMO_op_callf(
+ em->bm, BMO_FLAG_DEFAULTS, "translate vec=%v verts=%hv", offset_local, BM_ELEM_SELECT);
}
EDBM_mesh_normals_update(em);
@@ -317,20 +330,23 @@ static int edbm_extrude_repeat_exec(bContext *C, wmOperator *op)
void MESH_OT_extrude_repeat(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Extrude Repeat Mesh";
+ ot->name = "Extrude Repeat";
ot->description = "Extrude selected vertices, edges or faces repeatedly";
ot->idname = "MESH_OT_extrude_repeat";
/* api callbacks */
ot->exec = edbm_extrude_repeat_exec;
- ot->poll = ED_operator_editmesh_view3d;
+ ot->poll = ED_operator_editmesh;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* props */
- RNA_def_float_distance(ot->srna, "offset", 2.0f, 0.0f, 1e12f, "Offset", "", 0.0f, 100.0f);
RNA_def_int(ot->srna, "steps", 10, 0, 1000000, "Steps", "", 0, 180);
+ PropertyRNA *prop = RNA_def_float_vector_xyz(
+ ot->srna, "offset", 3, NULL, -100000, 100000, "Offset", "Offset vector", -1000.0f, 1000.0f);
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ RNA_def_float(ot->srna, "scale_offset", 1.0f, 0.0f, 1e12f, "Scale Offset", "", 0.0f, 100.0f);
}
/** \} */
diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c
index 6230eacba94..373dfc811ec 100644
--- a/source/blender/editors/mesh/editmesh_knife.c
+++ b/source/blender/editors/mesh/editmesh_knife.c
@@ -2824,14 +2824,14 @@ wmKeyMap *knifetool_modal_keymap(wmKeyConfig *keyconf)
{0, NULL, 0, NULL, NULL},
};
- wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "Knife Tool Modal Map");
+ wmKeyMap *keymap = WM_modalkeymap_find(keyconf, "Knife Tool Modal Map");
/* this function is called for each spacetype, only needs to add map once */
if (keymap && keymap->modal_items) {
return NULL;
}
- keymap = WM_modalkeymap_add(keyconf, "Knife Tool Modal Map", modal_items);
+ keymap = WM_modalkeymap_ensure(keyconf, "Knife Tool Modal Map", modal_items);
WM_modalkeymap_assign(keymap, "MESH_OT_knife_tool");
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index b52f63e0a1b..5a04822613e 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -1771,8 +1771,93 @@ void MESH_OT_face_make_planar(wmOperatorType *ot)
/** \name Split Edge Operator
* \{ */
+static bool edbm_edge_split_selected_edges(wmOperator *op, Object *obedit, BMEditMesh *em)
+{
+ BMesh *bm = em->bm;
+ if (bm->totedgesel == 0) {
+ return false;
+ }
+ if (!EDBM_op_call_and_selectf(
+ em, op, "edges.out", false, "split_edges edges=%he", BM_ELEM_SELECT)) {
+ return false;
+ }
+
+ EDBM_select_flush(em);
+ EDBM_update_generic(obedit->data, true, true);
+
+ return true;
+}
+
+static bool edbm_edge_split_selected_verts(wmOperator *op, Object *obedit, BMEditMesh *em)
+{
+ BMesh *bm = em->bm;
+
+ /* Note that tracking vertices through the 'split_edges' operator is complicated.
+ * Instead, tag loops for selection. */
+ if (bm->totvertsel == 0) {
+ return false;
+ }
+
+ /* Flush from vertices to edges. */
+ BMIter iter;
+ BMEdge *eed;
+ BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
+ BM_elem_flag_disable(eed, BM_ELEM_TAG);
+ if (eed->l != NULL) {
+ if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) &&
+ (BM_elem_flag_test(eed->v1, BM_ELEM_SELECT) ||
+ BM_elem_flag_test(eed->v2, BM_ELEM_SELECT))) {
+ BM_elem_flag_enable(eed, BM_ELEM_TAG);
+ }
+ /* Store selection in loop tags. */
+ BMLoop *l_iter = eed->l;
+ do {
+ BM_elem_flag_set(l_iter, BM_ELEM_TAG, BM_elem_flag_test(l_iter->v, BM_ELEM_SELECT));
+ } while ((l_iter = l_iter->radial_next) != eed->l);
+ }
+ }
+
+ if (!EDBM_op_callf(em,
+ op,
+ "split_edges edges=%he verts=%hv use_verts=%b",
+ BM_ELEM_TAG,
+ BM_ELEM_SELECT,
+ true)) {
+ return false;
+ }
+
+ BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
+ if (eed->l != NULL) {
+ BMLoop *l_iter = eed->l;
+ do {
+ if (BM_elem_flag_test(l_iter, BM_ELEM_TAG)) {
+ BM_vert_select_set(em->bm, l_iter->v, true);
+ }
+ } while ((l_iter = l_iter->radial_next) != eed->l);
+ }
+ else {
+ /* Split out wire. */
+ for (int i = 0; i < 2; i++) {
+ BMVert *v = *(&eed->v1 + i);
+ if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
+ if (eed != BM_DISK_EDGE_NEXT(eed, v)) {
+ BM_vert_separate(bm, v, &eed, 1, true, NULL, NULL);
+ }
+ }
+ }
+ }
+ }
+
+ EDBM_select_flush(em);
+ EDBM_update_generic(obedit->data, true, true);
+
+ return true;
+}
+
static int edbm_edge_split_exec(bContext *C, wmOperator *op)
{
+ const int type = RNA_enum_get(op->ptr, "type");
+
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(
@@ -1780,20 +1865,21 @@ static int edbm_edge_split_exec(bContext *C, wmOperator *op)
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
- if (em->bm->totedgesel == 0) {
- continue;
- }
- if (!EDBM_op_call_and_selectf(
- em, op, "edges.out", false, "split_edges edges=%he", BM_ELEM_SELECT)) {
- continue;
- }
-
- if (em->selectmode == SCE_SELECT_FACE) {
- EDBM_select_flush(em);
+ switch (type) {
+ case BM_VERT:
+ if (!edbm_edge_split_selected_verts(op, obedit, em)) {
+ continue;
+ }
+ break;
+ case BM_EDGE:
+ if (!edbm_edge_split_selected_edges(op, obedit, em)) {
+ continue;
+ }
+ break;
+ default:
+ BLI_assert(0);
}
-
- EDBM_update_generic(obedit->data, true, true);
}
MEM_freeN(objects);
@@ -1813,6 +1899,20 @@ void MESH_OT_edge_split(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ static const EnumPropertyItem merge_type_items[] = {
+ {BM_EDGE, "EDGE", 0, "Edges", "Split along selected edges"},
+ {BM_VERT,
+ "VERT",
+ 0,
+ "Edges from Vertices",
+ "Split all edges connected to selected vertices"},
+ {0, NULL, 0, NULL, NULL},
+ };
+
+ ot->prop = RNA_def_enum(
+ ot->srna, "type", merge_type_items, BM_EDGE, "Type", "Method to use for splitting");
}
/** \} */
@@ -7694,14 +7794,14 @@ wmKeyMap *point_normals_modal_keymap(wmKeyConfig *keyconf)
};
static const char *keymap_name = "Custom Normals Modal Map";
- wmKeyMap *keymap = WM_modalkeymap_get(keyconf, keymap_name);
+ wmKeyMap *keymap = WM_modalkeymap_find(keyconf, keymap_name);
/* We only need to add map once */
if (keymap && keymap->modal_items) {
return NULL;
}
- keymap = WM_modalkeymap_add(keyconf, keymap_name, modal_items);
+ keymap = WM_modalkeymap_ensure(keyconf, keymap_name, modal_items);
WM_modalkeymap_assign(keymap, "MESH_OT_point_normals");
diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c
index d9fb48afcbf..ba641fb2a39 100644
--- a/source/blender/editors/object/object_constraint.c
+++ b/source/blender/editors/object/object_constraint.c
@@ -76,7 +76,9 @@
#include "object_intern.h"
-/* -------------- Get Active Constraint Data ---------------------- */
+/* ------------------------------------------------------------------- */
+/** \name Constraint Data Accessors
+ * \{ */
/* if object in posemode, active bone constraints, else object constraints */
ListBase *get_active_constraints(Object *ob)
@@ -146,9 +148,13 @@ bConstraint *get_active_constraint(Object *ob)
return BKE_constraints_active_get(get_active_constraints(ob));
}
-/* -------------- Constraint Management (Add New, Remove, Rename) -------------------- */
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name PyConstraints (Unused)
+ * \{ */
+
#ifdef WITH_PYTHON
-/* ------------- PyConstraints ------------------ */
/* this callback sets the text-file to be used for selected menu item */
static void validate_pyconstraint_cb(Main *bmain, void *arg1, void *arg2)
@@ -231,6 +237,12 @@ static void update_pyconstraint_cb(void *arg1, void *arg2)
}
#endif // UNUSED
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Add Constraint Utilities
+ * \{ */
+
/* helper function for add_constriant - sets the last target for the active constraint */
static void set_constraint_nth_target(bConstraint *con,
Object *target,
@@ -272,7 +284,11 @@ static void set_constraint_nth_target(bConstraint *con,
}
}
-/* ------------- Constraint Sanity Testing ------------------- */
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Constraint Sanity Testing
+ * \{ */
static void test_constraint(
Main *bmain, Object *owner, bPoseChannel *pchan, bConstraint *con, int type)
@@ -626,7 +642,11 @@ static void object_test_constraint(Main *bmain, Object *owner, bConstraint *con)
}
}
-/*** generic functions for operators using constraint names and data context *********************/
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Generic Functions for Operators Using Constraint Names and Data Context
+ * \{ */
#define EDIT_CONSTRAINT_OWNER_OBJECT 0
#define EDIT_CONSTRAINT_OWNER_BONE 1
@@ -766,10 +786,13 @@ static bConstraint *edit_constraint_property_get(wmOperator *op, Object *ob, int
return con;
}
-/* ********************** CONSTRAINT-SPECIFIC STUFF ********************* */
+/** \} */
-/* ---------- Distance-Dependent Constraints ---------- */
-/* StretchTo, Limit Distance */
+/* ------------------------------------------------------------------- */
+/** \name Stretch-To/Limit-Distance Constraint (Reset Original Length Operator)
+ *
+ * For Stretch-To & Limit-Distance constraints.
+ * \{ */
static int stretchto_reset_exec(bContext *C, wmOperator *op)
{
@@ -820,6 +843,14 @@ void CONSTRAINT_OT_stretchto_reset(wmOperatorType *ot)
edit_constraint_properties(ot);
}
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Distance Constraint (Reset Operator)
+ *
+ * For Limit-Distance constraint.
+ * \{ */
+
static int limitdistance_reset_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
@@ -869,7 +900,11 @@ void CONSTRAINT_OT_limitdistance_reset(wmOperatorType *ot)
edit_constraint_properties(ot);
}
-/* ------------- Child-Of Constraint ------------------ */
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Child-Of Constraint (Set Inverse Operator)
+ * \{ */
/* Force evaluation so that the 'set inverse' flag is handled.
* No-op when the constraint is enabled, as in such cases the evaluation will happen anyway.
@@ -996,7 +1031,11 @@ void CONSTRAINT_OT_childof_clear_inverse(wmOperatorType *ot)
edit_constraint_properties(ot);
}
-/* --------------- Follow Path Constraint ------------------ */
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Follow Path Constraint (Auto Animate Path Operator)
+ * \{ */
static int followpath_path_animate_exec(bContext *C, wmOperator *op)
{
@@ -1138,7 +1177,11 @@ void CONSTRAINT_OT_followpath_path_animate(wmOperatorType *ot)
MAXFRAME);
}
-/* ------------- Object Solver Constraint ------------------ */
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Object Solver Constraint (Set Inverse Operator)
+ * \{ */
static int objectsolver_set_inverse_exec(bContext *C, wmOperator *op)
{
@@ -1198,6 +1241,12 @@ void CONSTRAINT_OT_objectsolver_set_inverse(wmOperatorType *ot)
edit_constraint_properties(ot);
}
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Object Solver Constraint (Clear Inverse Operator)
+ * \{ */
+
static int objectsolver_clear_inverse_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
@@ -1250,7 +1299,11 @@ void CONSTRAINT_OT_objectsolver_clear_inverse(wmOperatorType *ot)
edit_constraint_properties(ot);
}
-/***************************** BUTTONS ****************************/
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Constraint Management Utilities
+ * \{ */
void ED_object_constraint_set_active(Object *ob, bConstraint *con)
{
@@ -1344,6 +1397,12 @@ static bool constraint_poll(bContext *C)
return (ptr.owner_id && ptr.data);
}
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Delete Constraint Operator
+ * \{ */
+
static int constraint_delete_exec(bContext *C, wmOperator *UNUSED(op))
{
Main *bmain = CTX_data_main(C);
@@ -1388,6 +1447,12 @@ void CONSTRAINT_OT_delete(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Move Down Constraint Operator
+ * \{ */
+
static int constraint_move_down_exec(bContext *C, wmOperator *op)
{
Object *ob = ED_object_active_context(C);
@@ -1438,6 +1503,12 @@ void CONSTRAINT_OT_move_down(wmOperatorType *ot)
edit_constraint_properties(ot);
}
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Move Up Constraint Operator
+ * \{ */
+
static int constraint_move_up_exec(bContext *C, wmOperator *op)
{
Object *ob = ED_object_active_context(C);
@@ -1486,9 +1557,11 @@ void CONSTRAINT_OT_move_up(wmOperatorType *ot)
edit_constraint_properties(ot);
}
-/***************************** OPERATORS ****************************/
+/** \} */
-/************************ remove constraint operators *********************/
+/* ------------------------------------------------------------------- */
+/** \name Clear Pose Constraints Operator
+ * \{ */
static int pose_constraints_clear_exec(bContext *C, wmOperator *UNUSED(op))
{
@@ -1549,6 +1622,12 @@ static int object_constraints_clear_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Clear Object Constraints Operator
+ * \{ */
+
void OBJECT_OT_constraints_clear(wmOperatorType *ot)
{
/* identifiers */
@@ -1561,7 +1640,11 @@ void OBJECT_OT_constraints_clear(wmOperatorType *ot)
ot->poll = ED_operator_object_active_editable;
}
-/************************ copy all constraints operators *********************/
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Copy Pose Constraints Operator
+ * \{ */
static int pose_constraint_copy_exec(bContext *C, wmOperator *op)
{
@@ -1616,6 +1699,12 @@ void POSE_OT_constraints_copy(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Copy Object Constraints Operator
+ * \{ */
+
static int object_constraint_copy_exec(bContext *C, wmOperator *UNUSED(op))
{
Main *bmain = CTX_data_main(C);
@@ -1655,7 +1744,11 @@ void OBJECT_OT_constraints_copy(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/************************ add constraint operators *********************/
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Add Constraints Operator
+ * \{ */
/* get the Object and/or PoseChannel to use as target */
static bool get_new_constraint_target(
@@ -2013,6 +2106,12 @@ void OBJECT_OT_constraint_add(wmOperatorType *ot)
ot->prop = prop;
}
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Add Constraints With Targets Operator
+ * \{ */
+
void OBJECT_OT_constraint_add_with_targets(wmOperatorType *ot)
{
PropertyRNA *prop;
@@ -2078,8 +2177,14 @@ void POSE_OT_constraint_add_with_targets(wmOperatorType *ot)
ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_constraint_type_items, 0, "Type", "");
}
-/************************ IK Constraint operators *********************/
-/* NOTE: only for Pose-Channels */
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Add IK to Bone Operator
+ *
+ * \note Only for pose-channels.
+ * \{ */
+
// TODO: should these be here, or back in editors/armature/poseobject.c again?
/* present menu with options + validation for targets to use */
@@ -2178,9 +2283,14 @@ void POSE_OT_ik_add(wmOperatorType *ot)
"Assign IK Constraint with targets derived from the select bones/objects");
}
-/* ------------------ */
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Clear IK from Bone Operator
+ *
+ * Remove IK constraints from selected bones.
+ * \{ */
-/* remove IK constraints from selected bones */
static int pose_ik_clear_exec(bContext *C, wmOperator *UNUSED(op))
{
Object *prev_ob = NULL;
@@ -2228,3 +2338,5 @@ void POSE_OT_ik_clear(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+
+/** \} */
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index f2629b0b02f..0de2f114b94 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -94,7 +94,9 @@
static void modifier_skin_customdata_delete(struct Object *ob);
-/******************************** API ****************************/
+/* ------------------------------------------------------------------- */
+/** \name Public Api
+ * \{ */
static void object_force_modifier_update_for_bind(Depsgraph *depsgraph, Object *ob)
{
@@ -841,7 +843,11 @@ int ED_object_modifier_copy(ReportList *UNUSED(reports), Object *ob, ModifierDat
return 1;
}
-/************************ add modifier operator *********************/
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Add Modifier Operator
+ * \{ */
static int modifier_add_exec(bContext *C, wmOperator *op)
{
@@ -933,7 +939,13 @@ void OBJECT_OT_modifier_add(wmOperatorType *ot)
ot->prop = prop;
}
-/********** generic functions for operators using mod names and data context *********************/
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Generic Functions For Operators
+ *
+ * Using modifier names and data context.
+ * \{ */
bool edit_modifier_poll_generic(bContext *C,
StructRNA *rna_type,
@@ -1015,7 +1027,11 @@ ModifierData *edit_modifier_property_get(wmOperator *op, Object *ob, int type)
return md;
}
-/************************ remove modifier operator *********************/
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Remove Modifier Operator
+ * \{ */
static int modifier_remove_exec(bContext *C, wmOperator *op)
{
@@ -1067,7 +1083,11 @@ void OBJECT_OT_modifier_remove(wmOperatorType *ot)
edit_modifier_properties(ot);
}
-/************************ move up modifier operator *********************/
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Move Up Modifier Operator
+ * \{ */
static int modifier_move_up_exec(bContext *C, wmOperator *op)
{
@@ -1109,7 +1129,11 @@ void OBJECT_OT_modifier_move_up(wmOperatorType *ot)
edit_modifier_properties(ot);
}
-/************************ move down modifier operator *********************/
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Move Down Modifier Operator
+ * \{ */
static int modifier_move_down_exec(bContext *C, wmOperator *op)
{
@@ -1151,7 +1175,11 @@ void OBJECT_OT_modifier_move_down(wmOperatorType *ot)
edit_modifier_properties(ot);
}
-/************************ apply modifier operator *********************/
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Apply Modifier Operator
+ * \{ */
static bool modifier_apply_poll(bContext *C)
{
@@ -1164,7 +1192,7 @@ static bool modifier_apply_poll(bContext *C)
Object *ob = (ptr.owner_id != NULL) ? (Object *)ptr.owner_id : ED_object_active_context(C);
ModifierData *md = ptr.data; /* May be NULL. */
- if (ID_REAL_USERS(ob->data) > 1) {
+ if ((ob->data != NULL) && ID_REAL_USERS(ob->data) > 1) {
CTX_wm_operator_poll_msg_set(C, "Modifiers cannot be applied to multi-user data");
return false;
}
@@ -1241,7 +1269,11 @@ void OBJECT_OT_modifier_apply(wmOperatorType *ot)
edit_modifier_properties(ot);
}
-/************************ convert modifier operator *********************/
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Convert Modifier Operator
+ * \{ */
static int modifier_convert_exec(bContext *C, wmOperator *op)
{
@@ -1288,7 +1320,11 @@ void OBJECT_OT_modifier_convert(wmOperatorType *ot)
edit_modifier_properties(ot);
}
-/************************ copy modifier operator *********************/
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Copy Modifier Operator
+ * \{ */
static int modifier_copy_exec(bContext *C, wmOperator *op)
{
@@ -1330,7 +1366,11 @@ void OBJECT_OT_modifier_copy(wmOperatorType *ot)
edit_modifier_properties(ot);
}
-/************* multires delete higher levels operator ****************/
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Multires Delete Higher Levels Operator
+ * \{ */
static bool multires_poll(bContext *C)
{
@@ -1385,7 +1425,11 @@ void OBJECT_OT_multires_higher_levels_delete(wmOperatorType *ot)
edit_modifier_properties(ot);
}
-/****************** multires subdivide operator *********************/
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Multires Subdivide Operator
+ * \{ */
static int multires_subdivide_exec(bContext *C, wmOperator *op)
{
@@ -1438,7 +1482,11 @@ void OBJECT_OT_multires_subdivide(wmOperatorType *ot)
edit_modifier_properties(ot);
}
-/****************** multires reshape operator *********************/
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Multires Reshape Operator
+ * \{ */
static int multires_reshape_exec(bContext *C, wmOperator *op)
{
@@ -1505,7 +1553,11 @@ void OBJECT_OT_multires_reshape(wmOperatorType *ot)
edit_modifier_properties(ot);
}
-/****************** multires save external operator *********************/
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Multires Save External Operator
+ * \{ */
static int multires_external_save_exec(bContext *C, wmOperator *op)
{
@@ -1594,7 +1646,11 @@ void OBJECT_OT_multires_external_save(wmOperatorType *ot)
edit_modifier_properties(ot);
}
-/****************** multires pack operator *********************/
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Multires Pack Operator
+ * \{ */
static int multires_external_pack_exec(bContext *C, wmOperator *UNUSED(op))
{
@@ -1624,7 +1680,12 @@ void OBJECT_OT_multires_external_pack(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/********************* multires apply base ***********************/
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Multires Apply Base
+ * \{ */
+
static int multires_base_apply_exec(bContext *C, wmOperator *op)
{
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
@@ -1669,7 +1730,11 @@ void OBJECT_OT_multires_base_apply(wmOperatorType *ot)
edit_modifier_properties(ot);
}
-/************************** skin modifier ***********************/
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Skin Modifier
+ * \{ */
static void modifier_skin_customdata_delete(Object *ob)
{
@@ -2041,7 +2106,11 @@ void OBJECT_OT_skin_armature_create(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
edit_modifier_properties(ot);
}
-/************************ delta mush bind operator *********************/
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Delta Mesh Bind Operator
+ * \{ */
static bool correctivesmooth_poll(bContext *C)
{
@@ -2119,7 +2188,11 @@ void OBJECT_OT_correctivesmooth_bind(wmOperatorType *ot)
edit_modifier_properties(ot);
}
-/************************ mdef bind operator *********************/
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Mesh Deform Bind Operator
+ * \{ */
static bool meshdeform_poll(bContext *C)
{
@@ -2192,7 +2265,11 @@ void OBJECT_OT_meshdeform_bind(wmOperatorType *ot)
edit_modifier_properties(ot);
}
-/****************** explode refresh operator *********************/
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Explode Refresh Operator
+ * \{ */
static bool explode_poll(bContext *C)
{
@@ -2242,7 +2319,11 @@ void OBJECT_OT_explode_refresh(wmOperatorType *ot)
edit_modifier_properties(ot);
}
-/****************** ocean bake operator *********************/
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Ocean Bake Operator
+ * \{ */
static bool ocean_bake_poll(bContext *C)
{
@@ -2444,7 +2525,11 @@ void OBJECT_OT_ocean_bake(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "free", false, "Free", "Free the bake, rather than generating it");
}
-/************************ LaplacianDeform bind operator *********************/
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Laplaciandeform Bind Operator
+ * \{ */
static bool laplaciandeform_poll(bContext *C)
{
@@ -2519,7 +2604,11 @@ void OBJECT_OT_laplaciandeform_bind(wmOperatorType *ot)
edit_modifier_properties(ot);
}
-/************************ sdef bind operator *********************/
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Surface Deform Bind Operator
+ * \{ */
static bool surfacedeform_bind_poll(bContext *C)
{
@@ -2583,3 +2672,5 @@ void OBJECT_OT_surfacedeform_bind(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
edit_modifier_properties(ot);
}
+
+/** \} */
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
index 7c8a9750b36..3166c9ddea1 100644
--- a/source/blender/editors/object/object_relations.c
+++ b/source/blender/editors/object/object_relations.c
@@ -115,7 +115,9 @@
#include "object_intern.h"
-/*********************** Make Vertex Parent Operator ************************/
+/* ------------------------------------------------------------------- */
+/** \name Make Vertex Parent Operator
+ * \{ */
static bool vertex_parent_set_poll(bContext *C)
{
@@ -331,7 +333,11 @@ void OBJECT_OT_vertex_parent_set(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/********************** Make Proxy Operator *************************/
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Make Proxy Operator
+ * \{ */
/* set the object to proxify */
static int make_proxy_invoke(bContext *C, wmOperator *op, const wmEvent *event)
@@ -411,7 +417,12 @@ static int make_proxy_exec(bContext *C, wmOperator *op)
* TODO(sergey): We really need to get rid of this bi-directional links
* in proxies with something like library overrides.
*/
- newob->proxy->proxy_from = newob;
+ if (newob->proxy != NULL) {
+ newob->proxy->proxy_from = newob;
+ }
+ else {
+ BKE_report(op->reports, RPT_ERROR, "Unable to assign proxy");
+ }
/* depsgraph flushes are needed for the new data */
DEG_relations_tag_update(bmain);
@@ -485,7 +496,11 @@ void OBJECT_OT_proxy_make(wmOperatorType *ot)
ot->prop = prop;
}
-/********************** Clear Parent Operator ******************* */
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Clear Parent Operator
+ * \{ */
EnumPropertyItem prop_clear_parent_types[] = {
{CLEAR_PARENT_ALL,
@@ -619,7 +634,11 @@ void OBJECT_OT_parent_clear(wmOperatorType *ot)
ot->prop = RNA_def_enum(ot->srna, "type", prop_clear_parent_types, CLEAR_PARENT_ALL, "Type", "");
}
-/* ******************** Make Parent Operator *********************** */
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Make Parent Operator
+ * \{ */
void ED_object_parent(Object *ob, Object *par, const int type, const char *substr)
{
@@ -1138,7 +1157,11 @@ void OBJECT_OT_parent_set(wmOperatorType *ot)
"Apply transformation before parenting");
}
-/* ************ Make Parent Without Inverse Operator ******************* */
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Make Parent Without Inverse Operator
+ * \{ */
static int parent_noinv_set_exec(bContext *C, wmOperator *op)
{
@@ -1191,7 +1214,11 @@ void OBJECT_OT_parent_no_inverse_set(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/* ******************** Clear Track Operator ******************* */
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Clear Track Operator
+ * \{ */
enum {
CLEAR_TRACK = 1,
@@ -1267,7 +1294,11 @@ void OBJECT_OT_track_clear(wmOperatorType *ot)
ot->prop = RNA_def_enum(ot->srna, "type", prop_clear_track_types, 0, "Type", "");
}
-/************************** Make Track Operator *****************************/
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Make Track Operator
+ * \{ */
enum {
CREATE_TRACK_DAMPTRACK = 1,
@@ -1386,7 +1417,11 @@ void OBJECT_OT_track_set(wmOperatorType *ot)
ot->prop = RNA_def_enum(ot->srna, "type", prop_make_track_types, 0, "Type", "");
}
-/************************** Link to Scene Operator *****************************/
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Link to Scene Operator
+ * \{ */
#if 0
static void link_to_scene(Main *UNUSED(bmain), unsigned short UNUSED(nr))
@@ -1702,7 +1737,11 @@ void OBJECT_OT_make_links_data(wmOperatorType *ot)
ot->prop = RNA_def_enum(ot->srna, "type", make_links_items, 0, "Type", "");
}
-/**************************** Make Single User ********************************/
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Make Single User Operator
+ * \{ */
static void libblock_relink_collection(Collection *collection, const bool do_collection)
{
@@ -2084,7 +2123,11 @@ void ED_object_single_users(Main *bmain,
DEG_relations_tag_update(bmain);
}
-/******************************* Make Local ***********************************/
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Make Local Operator
+ * \{ */
enum {
MAKE_LOCAL_SELECT_OB = 1,
@@ -2324,6 +2367,12 @@ void OBJECT_OT_make_local(wmOperatorType *ot)
ot->prop = RNA_def_enum(ot->srna, "type", type_items, 0, "Type", "");
}
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Make Library Override Operator
+ * \{ */
+
static void make_override_library_tag_object(Object *obact, Object *ob)
{
if (ob == obact) {
@@ -2585,6 +2634,12 @@ void OBJECT_OT_make_override_library(wmOperatorType *ot)
ot->prop = prop;
}
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Make Single User Operator
+ * \{ */
+
enum {
MAKE_SINGLE_USER_ALL = 1,
MAKE_SINGLE_USER_SELECTED = 2,
@@ -2673,6 +2728,12 @@ void OBJECT_OT_make_single_user(wmOperatorType *ot)
ot->srna, "animation", 0, "Object Animation", "Make animation data local to each object");
}
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Drop Named Material on Object Operator
+ * \{ */
+
static int drop_named_material_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
Main *bmain = CTX_data_main(C);
@@ -2716,6 +2777,12 @@ void OBJECT_OT_drop_named_material(wmOperatorType *ot)
RNA_def_string(ot->srna, "name", "Material", MAX_ID_NAME - 2, "Name", "Material name to assign");
}
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Unlink Object Operator
+ * \{ */
+
static int object_unlink_data_exec(bContext *C, wmOperator *op)
{
ID *id;
@@ -2766,3 +2833,5 @@ void OBJECT_OT_unlink_data(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_INTERNAL;
}
+
+/** \} */
diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c
index 62a078bedb7..e1fa4caafbd 100644
--- a/source/blender/editors/render/render_shading.c
+++ b/source/blender/editors/render/render_shading.c
@@ -814,14 +814,16 @@ void WORLD_OT_new(wmOperatorType *ot)
/********************** render layer operators *********************/
-static int view_layer_add_exec(bContext *C, wmOperator *UNUSED(op))
+static int view_layer_add_exec(bContext *C, wmOperator *op)
{
wmWindow *win = CTX_wm_window(C);
Scene *scene = CTX_data_scene(C);
- ViewLayer *view_layer = BKE_view_layer_add(scene, NULL);
+ ViewLayer *view_layer_current = WM_window_get_active_view_layer(win);
+ ViewLayer *view_layer_new = BKE_view_layer_add(
+ scene, view_layer_current->name, view_layer_current, RNA_enum_get(op->ptr, "type"));
if (win) {
- WM_window_set_active_view_layer(win, view_layer);
+ WM_window_set_active_view_layer(win, view_layer_new);
}
DEG_id_tag_update(&scene->id, 0);
@@ -833,6 +835,17 @@ static int view_layer_add_exec(bContext *C, wmOperator *UNUSED(op))
void SCENE_OT_view_layer_add(wmOperatorType *ot)
{
+ static EnumPropertyItem type_items[] = {
+ {VIEWLAYER_ADD_NEW, "NEW", 0, "New", "Add a new view layer"},
+ {VIEWLAYER_ADD_COPY, "COPY", 0, "Copy Settings", "Copy settings of current view layer"},
+ {VIEWLAYER_ADD_EMPTY,
+ "EMPTY",
+ 0,
+ "Blank",
+ "Add a new view layer with all collections disabled"},
+ {0, NULL, 0, NULL, NULL},
+ };
+
/* identifiers */
ot->name = "Add View Layer";
ot->idname = "SCENE_OT_view_layer_add";
@@ -840,9 +853,13 @@ void SCENE_OT_view_layer_add(wmOperatorType *ot)
/* api callbacks */
ot->exec = view_layer_add_exec;
+ ot->invoke = WM_menu_invoke;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+
+ /* properties */
+ ot->prop = RNA_def_enum(ot->srna, "type", type_items, 0, "Type", "");
}
static bool view_layer_remove_poll(bContext *C)
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c
index f25f685f2e1..0151a0fcb0d 100644
--- a/source/blender/editors/screen/screen_edit.c
+++ b/source/blender/editors/screen/screen_edit.c
@@ -1666,7 +1666,7 @@ Scene *ED_screen_scene_find_with_window(const bScreen *screen,
}
}
- BLI_assert(0);
+ /* Can by NULL when accessing a screen that isn't active. */
return NULL;
}
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index 2506c7472e3..ae8dd829d8d 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -3142,7 +3142,7 @@ static void SCREEN_OT_screen_set(wmOperatorType *ot)
ot->poll = ED_operator_screenactive;
/* rna */
- RNA_def_int(ot->srna, "delta", 0, INT_MIN, INT_MAX, "Delta", "", INT_MIN, INT_MAX);
+ RNA_def_int(ot->srna, "delta", 1, -1, 1, "Delta", "", -1, 1);
}
/** \} */
@@ -4796,10 +4796,10 @@ static void SCREEN_OT_box_select(wmOperatorType *ot)
/* -------------------------------------------------------------------- */
/** \name Full Screen Back Operator
+ *
+ * Use for generic full-screen 'back' button.
* \{ */
-/* *********************** generic fullscreen 'back' button *************** */
-
static int fullscreen_back_exec(bContext *C, wmOperator *op)
{
bScreen *screen = CTX_wm_screen(C);
@@ -5517,7 +5517,7 @@ static void keymap_modal_set(wmKeyConfig *keyconf)
wmKeyMap *keymap;
/* Standard Modal keymap ------------------------------------------------ */
- keymap = WM_modalkeymap_add(keyconf, "Standard Modal Map", modal_items);
+ keymap = WM_modalkeymap_ensure(keyconf, "Standard Modal Map", modal_items);
WM_modalkeymap_assign(keymap, "SCREEN_OT_area_move");
}
@@ -5525,7 +5525,7 @@ static void keymap_modal_set(wmKeyConfig *keyconf)
static bool blend_file_drop_poll(bContext *UNUSED(C),
wmDrag *drag,
const wmEvent *UNUSED(event),
- const char **UNUSED(tooltip))
+ const char **UNUSED(r_tooltip))
{
if (drag->type == WM_DRAG_PATH) {
if (drag->icon == ICON_FILE_BLEND) {
diff --git a/source/blender/editors/sculpt_paint/paint_hide.c b/source/blender/editors/sculpt_paint/paint_hide.c
index ce5a80585b0..69ca86efa9d 100644
--- a/source/blender/editors/sculpt_paint/paint_hide.c
+++ b/source/blender/editors/sculpt_paint/paint_hide.c
@@ -403,6 +403,9 @@ static int hide_show_exec(bContext *C, wmOperator *op)
BKE_mesh_flush_hidden_from_verts(me);
}
+ SCULPT_visibility_sync_all_vertex_to_face_sets(ob->sculpt);
+
+ DEG_id_tag_update(&ob->id, ID_RECALC_SHADING);
ED_region_tag_redraw(region);
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/sculpt_paint/paint_image_2d.c b/source/blender/editors/sculpt_paint/paint_image_2d.c
index fc56c5cb6c6..73c099c9407 100644
--- a/source/blender/editors/sculpt_paint/paint_image_2d.c
+++ b/source/blender/editors/sculpt_paint/paint_image_2d.c
@@ -1609,7 +1609,9 @@ void paint_2d_stroke(void *ps,
copy_v2_v2(last_uv, old_uv);
}
- float uv_brush_size[2] = {base_size / s->tiles[0].size[0], base_size / s->tiles[0].size[1]};
+ const float uv_brush_size[2] = {
+ (s->symmetry & PAINT_TILE_X) ? FLT_MAX : base_size / s->tiles[0].size[0],
+ (s->symmetry & PAINT_TILE_Y) ? FLT_MAX : base_size / s->tiles[0].size[1]};
for (int i = 0; i < s->num_tiles; i++) {
ImagePaintTile *tile = &s->tiles[i];
@@ -1640,7 +1642,8 @@ void paint_2d_stroke(void *ps,
paint_2d_uv_to_coord(tile, last_uv, tile->last_paintpos);
/* Second check in pixel coordinates. */
- const float pixel_brush_size[] = {size, size};
+ const float pixel_brush_size[] = {(s->symmetry & PAINT_TILE_X) ? FLT_MAX : size,
+ (s->symmetry & PAINT_TILE_Y) ? FLT_MAX : size};
if (!(is_inside_tile(tile->size, new_coord, pixel_brush_size) ||
is_inside_tile(tile->size, old_coord, pixel_brush_size))) {
continue;
diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c
index 8362a4a576a..c56ce8fd183 100644
--- a/source/blender/editors/sculpt_paint/paint_image_proj.c
+++ b/source/blender/editors/sculpt_paint/paint_image_proj.c
@@ -64,6 +64,7 @@
#include "BKE_colortools.h"
#include "BKE_context.h"
#include "BKE_customdata.h"
+#include "BKE_global.h"
#include "BKE_idprop.h"
#include "BKE_image.h"
#include "BKE_lib_id.h"
@@ -6201,11 +6202,12 @@ void PAINT_OT_project_image(wmOperatorType *ot)
static bool texture_paint_image_from_view_poll(bContext *C)
{
- if (BKE_screen_find_big_area(CTX_wm_screen(C), SPACE_VIEW3D, 0) == NULL) {
+ bScreen *screen = CTX_wm_screen(C);
+ if (!(screen && BKE_screen_find_big_area(screen, SPACE_VIEW3D, 0))) {
CTX_wm_operator_poll_msg_set(C, "No 3D viewport found to create image from");
return false;
}
- if (!GPU_is_initialized()) {
+ if (G.background || !GPU_is_initialized()) {
return false;
}
return true;
@@ -6754,7 +6756,7 @@ void PAINT_OT_add_texture_paint_slot(wmOperatorType *ot)
/* api callbacks */
ot->invoke = texture_paint_add_texture_paint_slot_invoke;
ot->exec = texture_paint_add_texture_paint_slot_exec;
- ot->poll = ED_operator_object_active;
+ ot->poll = ED_operator_object_active_editable_mesh;
/* flags */
ot->flag = OPTYPE_UNDO;
diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c
index 59a0c50d402..cc848b80bb3 100644
--- a/source/blender/editors/sculpt_paint/paint_ops.c
+++ b/source/blender/editors/sculpt_paint/paint_ops.c
@@ -303,7 +303,7 @@ static void PALETTE_OT_color_delete(wmOperatorType *ot)
static bool palette_extract_img_poll(bContext *C)
{
SpaceLink *sl = CTX_wm_space_data(C);
- if (sl->spacetype == SPACE_IMAGE) {
+ if ((sl != NULL) && (sl->spacetype == SPACE_IMAGE)) {
return true;
}
@@ -716,7 +716,8 @@ static bool brush_generic_tool_set(bContext *C,
brush = brush_tool_cycle(bmain, paint, brush_orig, tool);
}
- if (!brush && brush_tool(brush_orig, paint->runtime.tool_offset) != tool && create_missing) {
+ if (((brush == NULL) && create_missing) &&
+ ((brush_orig == NULL) || brush_tool(brush_orig, paint->runtime.tool_offset) != tool)) {
brush = BKE_brush_add(bmain, tool_name, paint->runtime.ob_mode);
id_us_min(&brush->id); /* fake user only */
brush_tool_set(brush, paint->runtime.tool_offset, tool);
@@ -778,6 +779,9 @@ static int brush_select_exec(bContext *C, wmOperator *op)
}
Paint *paint = BKE_paint_get_active_from_paintmode(scene, paint_mode);
+ if (paint == NULL) {
+ return OPERATOR_CANCELLED;
+ }
const EnumPropertyItem *items = BKE_paint_get_tool_enum_from_paintmode(paint_mode);
RNA_enum_name_from_value(items, tool, &tool_name);
diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c
index 01a0e8ddd5b..935b9ef9506 100644
--- a/source/blender/editors/sculpt_paint/paint_stroke.c
+++ b/source/blender/editors/sculpt_paint/paint_stroke.c
@@ -1103,11 +1103,11 @@ struct wmKeyMap *paint_stroke_modal_keymap(struct wmKeyConfig *keyconf)
static const char *name = "Paint Stroke Modal";
- struct wmKeyMap *keymap = WM_modalkeymap_get(keyconf, name);
+ struct wmKeyMap *keymap = WM_modalkeymap_find(keyconf, name);
/* this function is called for each spacetype, only needs to add map once */
if (!keymap) {
- keymap = WM_modalkeymap_add(keyconf, name, modal_items);
+ keymap = WM_modalkeymap_ensure(keyconf, name, modal_items);
}
return keymap;
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index bec44242931..6ccd197c908 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -196,21 +196,15 @@ float SCULPT_vertex_mask_get(SculptSession *ss, int index)
return 0.0f;
}
-static int SCULPT_active_vertex_get(SculptSession *ss)
+int SCULPT_active_vertex_get(SculptSession *ss)
{
- switch (BKE_pbvh_type(ss->pbvh)) {
- case PBVH_FACES:
- return ss->active_vertex_index;
- case PBVH_BMESH:
- return ss->active_vertex_index;
- case PBVH_GRIDS:
- return ss->active_vertex_index;
+ if (ELEM(BKE_pbvh_type(ss->pbvh), PBVH_FACES, PBVH_BMESH, PBVH_GRIDS)) {
+ return ss->active_vertex_index;
}
-
return 0;
}
-static const float *SCULPT_active_vertex_co_get(SculptSession *ss)
+const float *SCULPT_active_vertex_co_get(SculptSession *ss)
{
return SCULPT_vertex_co_get(ss, SCULPT_active_vertex_get(ss));
}
@@ -292,6 +286,14 @@ static void SCULPT_face_sets_visibility_all_set(SculptSession *ss, bool visible)
switch (BKE_pbvh_type(ss->pbvh)) {
case PBVH_FACES:
for (int i = 0; i < ss->totpoly; i++) {
+
+ /* This can run on geometry without a face set assigned, so its ID sign can't be changed to
+ * modify the visibility. Force that geometry to the ID 1 to enable changing the visibility
+ * here. */
+ if (ss->face_sets[i] == SCULPT_FACE_SET_NONE) {
+ ss->face_sets[i] = 1;
+ }
+
if (visible) {
ss->face_sets[i] = abs(ss->face_sets[i]);
}
@@ -365,7 +367,7 @@ static void SCULPT_vertex_face_set_set(SculptSession *ss, int index, int face_se
}
}
-static int SCULPT_vertex_face_set_get(SculptSession *ss, int index)
+int SCULPT_vertex_face_set_get(SculptSession *ss, int index)
{
switch (BKE_pbvh_type(ss->pbvh)) {
case PBVH_FACES: {
@@ -386,7 +388,7 @@ static int SCULPT_vertex_face_set_get(SculptSession *ss, int index)
return 0;
}
-static bool SCULPT_vertex_has_face_set(SculptSession *ss, int index, int face_set)
+bool SCULPT_vertex_has_face_set(SculptSession *ss, int index, int face_set)
{
switch (BKE_pbvh_type(ss->pbvh)) {
case PBVH_FACES: {
@@ -418,7 +420,8 @@ void SCULPT_visibility_sync_all_face_sets_to_vertices(SculptSession *ss)
}
}
-static void sculpt_visibility_sync_vertex_to_face_sets(SculptSession *ss, int index)
+static void UNUSED_FUNCTION(sculpt_visibility_sync_vertex_to_face_sets)(SculptSession *ss,
+ int index)
{
MeshElemMap *vert_map = &ss->pmap[index];
const bool visible = SCULPT_vertex_visible_get(ss, index);
@@ -435,12 +438,27 @@ static void sculpt_visibility_sync_vertex_to_face_sets(SculptSession *ss, int in
void SCULPT_visibility_sync_all_vertex_to_face_sets(SculptSession *ss)
{
- for (int i = 0; i < ss->totvert; i++) {
- sculpt_visibility_sync_vertex_to_face_sets(ss, i);
+ if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES) {
+ for (int i = 0; i < ss->totpoly; i++) {
+ MPoly *poly = &ss->mpoly[i];
+ bool poly_visible = true;
+ for (int l = 0; l < poly->totloop; l++) {
+ MLoop *loop = &ss->mloop[poly->loopstart + l];
+ if (!SCULPT_vertex_visible_get(ss, (int)loop->v)) {
+ poly_visible = false;
+ }
+ }
+ if (poly_visible) {
+ ss->face_sets[i] = abs(ss->face_sets[i]);
+ }
+ else {
+ ss->face_sets[i] = -abs(ss->face_sets[i]);
+ }
+ }
}
}
-static bool sculpt_vertex_has_unique_face_set(SculptSession *ss, int index)
+bool SCULPT_vertex_has_unique_face_set(SculptSession *ss, int index)
{
switch (BKE_pbvh_type(ss->pbvh)) {
case PBVH_FACES: {
@@ -543,18 +561,18 @@ static void sculpt_vertex_neighbors_get_faces(SculptSession *ss,
int index,
SculptVertexNeighborIter *iter)
{
- MeshElemMap *vert_map = &ss->pmap[(int)index];
+ MeshElemMap *vert_map = &ss->pmap[index];
iter->size = 0;
iter->num_duplicates = 0;
iter->capacity = SCULPT_VERTEX_NEIGHBOR_FIXED_CAPACITY;
iter->neighbors = iter->neighbors_fixed;
- for (int i = 0; i < ss->pmap[(int)index].count; i++) {
+ for (int i = 0; i < ss->pmap[index].count; i++) {
const MPoly *p = &ss->mpoly[vert_map->indices[i]];
uint f_adj_v[2];
- if (poly_get_adj_loops_from_vert(p, ss->mloop, (int)index, f_adj_v) != -1) {
+ if (poly_get_adj_loops_from_vert(p, ss->mloop, index, f_adj_v) != -1) {
for (int j = 0; j < ARRAY_SIZE(f_adj_v); j += 1) {
- if (f_adj_v[j] != (int)index) {
+ if (f_adj_v[j] != index) {
sculpt_vertex_neighbor_add(iter, f_adj_v[j]);
}
}
@@ -795,11 +813,35 @@ void SCULPT_floodfill_init(SculptSession *ss, SculptFloodFill *flood)
flood->visited_vertices = MEM_callocN(vertex_count * sizeof(char), "visited vertices");
}
-static void sculpt_floodfill_add_initial(SculptFloodFill *flood, int index)
+void sculpt_floodfill_add_initial(SculptFloodFill *flood, int index)
{
BLI_gsqueue_push(flood->queue, &index);
}
+void SCULPT_floodfill_add_initial_with_symmetry(
+ Sculpt *sd, Object *ob, SculptSession *ss, SculptFloodFill *flood, int index, float radius)
+{
+ /* Add active vertex and symmetric vertices to the queue. */
+ const char symm = sd->paint.symmetry_flags & PAINT_SYMM_AXIS_ALL;
+ for (char i = 0; i <= symm; ++i) {
+ if (SCULPT_is_symmetry_iteration_valid(i, symm)) {
+ int v = -1;
+ if (i == 0) {
+ v = index;
+ }
+ else if (radius > 0.0f) {
+ float radius_squared = (radius == FLT_MAX) ? FLT_MAX : radius * radius;
+ float location[3];
+ flip_v3_v3(location, SCULPT_vertex_co_get(ss, index), i);
+ v = SCULPT_nearest_vertex_get(sd, ob, location, radius_squared, false);
+ }
+ if (v != -1) {
+ sculpt_floodfill_add_initial(flood, v);
+ }
+ }
+ }
+}
+
void SCULPT_floodfill_add_active(
Sculpt *sd, Object *ob, SculptSession *ss, SculptFloodFill *flood, float radius)
{
@@ -834,8 +876,7 @@ void SCULPT_floodfill_execute(
int from_v;
BLI_gsqueue_pop(flood->queue, &from_v);
SculptVertexNeighborIter ni;
- sculpt_vertex_duplicates_and_neighbors_iter_begin(ss, from_v, ni)
- {
+ SCULPT_VERTEX_DUPLICATES_AND_NEIGHBORS_ITER_BEGIN (ss, from_v, ni) {
const int to_v = ni.index;
if (flood->visited_vertices[to_v] == 0 && SCULPT_vertex_visible_get(ss, to_v)) {
flood->visited_vertices[to_v] = 1;
@@ -845,7 +886,7 @@ void SCULPT_floodfill_execute(
}
}
}
- sculpt_vertex_neighbors_iter_end(ni);
+ SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
}
}
@@ -891,6 +932,7 @@ static bool sculpt_tool_needs_original(const char sculpt_tool)
SCULPT_TOOL_LAYER,
SCULPT_TOOL_DRAW_SHARP,
SCULPT_TOOL_ELASTIC_DEFORM,
+ SCULPT_TOOL_SMOOTH,
SCULPT_TOOL_POSE);
}
@@ -1277,6 +1319,8 @@ void SCULPT_brush_test_init(SculptSession *ss, SculptBrushTest *test)
test->radius_squared = ss->cache ? ss->cache->radius_squared :
ss->cursor_radius * ss->cursor_radius;
+ test->radius = sqrtf(test->radius_squared);
+
if (ss->cache) {
copy_v3_v3(test->location, ss->cache->location);
test->mirror_symmetry_pass = ss->cache->mirror_symmetry_pass;
@@ -1659,13 +1703,12 @@ static float *sculpt_boundary_edges_automasking_init(Object *ob,
for (int i = 0; i < totvert; i++) {
if (edge_distance[i] == EDGE_DISTANCE_INF) {
SculptVertexNeighborIter ni;
- sculpt_vertex_neighbors_iter_begin(ss, i, ni)
- {
+ SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, i, ni) {
if (edge_distance[ni.index] == propagation_it) {
edge_distance[i] = propagation_it + 1;
}
}
- sculpt_vertex_neighbors_iter_end(ni);
+ SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
}
}
}
@@ -1843,6 +1886,7 @@ static void calc_area_normal_and_center_task_cb(void *__restrict userdata,
if (!(ss->cache && data->brush->sculpt_tool == SCULPT_TOOL_LAYER)) {
test_radius *= data->brush->normal_radius_factor;
}
+ normal_test.radius = test_radius;
normal_test.radius_squared = test_radius * test_radius;
}
@@ -1863,6 +1907,7 @@ static void calc_area_normal_and_center_task_cb(void *__restrict userdata,
test_radius *= data->brush->normal_radius_factor;
}
}
+ area_test.radius = test_radius;
area_test.radius_squared = test_radius * test_radius;
}
@@ -1896,10 +1941,26 @@ static void calc_area_normal_and_center_task_cb(void *__restrict userdata,
flip_index = (dot_v3v3(ss->cache->view_normal, no) <= 0.0f);
if (use_area_cos && area_test_r) {
+ /* Weight the coordinates towards the center. */
+ float p = 1.0f - (sqrtf(area_test.dist) / area_test.radius);
+ float afactor = 3.0f * p * p - 2.0f * p * p * p;
+ CLAMP(afactor, 0.0f, 1.0f);
+
+ float disp[3];
+ sub_v3_v3v3(disp, co, area_test.location);
+ mul_v3_fl(disp, 1.0f - afactor);
+ add_v3_v3v3(co, area_test.location, disp);
add_v3_v3(anctd->area_cos[flip_index], co);
+
anctd->count_co[flip_index] += 1;
}
if (use_area_nos && normal_test_r) {
+ /* Weight the normals towards the center. */
+ float p = 1.0f - (sqrtf(normal_test.dist) / normal_test.radius);
+ float nfactor = 3.0f * p * p - 2.0f * p * p * p;
+ CLAMP(nfactor, 0.0f, 1.0f);
+ mul_v3_fl(no, nfactor);
+
add_v3_v3(anctd->area_nos[flip_index], no);
anctd->count_no[flip_index] += 1;
}
@@ -1909,54 +1970,73 @@ static void calc_area_normal_and_center_task_cb(void *__restrict userdata,
else {
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- const float *co;
+ float co[3];
+
/* For bm_vert only. */
- const short *no_s;
+ short no_s[3];
if (use_original) {
if (unode->bm_entry) {
- BM_log_original_vert_data(ss->bm_log, vd.bm_vert, &co, &no_s);
+ const float *temp_co;
+ const short *temp_no_s;
+ BM_log_original_vert_data(ss->bm_log, vd.bm_vert, &temp_co, &temp_no_s);
+ copy_v3_v3(co, temp_co);
+ copy_v3_v3_short(no_s, temp_no_s);
}
else {
- co = unode->co[vd.i];
- no_s = unode->no[vd.i];
+ copy_v3_v3(co, unode->co[vd.i]);
+ copy_v3_v3_short(no_s, unode->no[vd.i]);
}
}
else {
- co = vd.co;
+ copy_v3_v3(co, vd.co);
}
normal_test_r = sculpt_brush_normal_test_sq_fn(&normal_test, co);
area_test_r = sculpt_brush_area_test_sq_fn(&area_test, co);
if (normal_test_r || area_test_r) {
- float no_buf[3];
- const float *no;
+ float no[3];
int flip_index;
data->any_vertex_sampled = true;
if (use_original) {
- normal_short_to_float_v3(no_buf, no_s);
- no = no_buf;
+ normal_short_to_float_v3(no, no_s);
}
else {
if (vd.no) {
- normal_short_to_float_v3(no_buf, vd.no);
- no = no_buf;
+ normal_short_to_float_v3(no, vd.no);
}
else {
- no = vd.fno;
+ copy_v3_v3(no, vd.fno);
}
}
flip_index = (dot_v3v3(ss->cache ? ss->cache->view_normal : ss->cursor_view_normal, no) <=
0.0f);
+
if (use_area_cos && area_test_r) {
+ /* Weight the coordinates towards the center. */
+ float p = 1.0f - (sqrtf(area_test.dist) / area_test.radius);
+ float afactor = 3.0f * p * p - 2.0f * p * p * p;
+ CLAMP(afactor, 0.0f, 1.0f);
+
+ float disp[3];
+ sub_v3_v3v3(disp, co, area_test.location);
+ mul_v3_fl(disp, 1.0f - afactor);
+ add_v3_v3v3(co, area_test.location, disp);
+
add_v3_v3(anctd->area_cos[flip_index], co);
anctd->count_co[flip_index] += 1;
}
if (use_area_nos && normal_test_r) {
+ /* Weight the normals towards the center. */
+ float p = 1.0f - (sqrtf(normal_test.dist) / normal_test.radius);
+ float nfactor = 3.0f * p * p - 2.0f * p * p * p;
+ CLAMP(nfactor, 0.0f, 1.0f);
+ mul_v3_fl(no, nfactor);
+
add_v3_v3(anctd->area_nos[flip_index], no);
anctd->count_no[flip_index] += 1;
}
@@ -2836,18 +2916,17 @@ static float bmesh_neighbor_average_mask(BMVert *v, const int cd_vert_mask_offse
}
}
-static void grids_neighbor_average(SculptSession *ss, float result[3], int index)
+static void SCULPT_neighbor_coords_average(SculptSession *ss, float result[3], int index)
{
float avg[3] = {0.0f, 0.0f, 0.0f};
int total = 0;
SculptVertexNeighborIter ni;
- sculpt_vertex_neighbors_iter_begin(ss, index, ni)
- {
+ SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, index, ni) {
add_v3_v3(avg, SCULPT_vertex_co_get(ss, ni.index));
total++;
}
- sculpt_vertex_neighbors_iter_end(ni);
+ SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
if (total > 0) {
mul_v3_v3fl(result, avg, 1.0f / (float)total);
@@ -2863,12 +2942,11 @@ static float grids_neighbor_average_mask(SculptSession *ss, int index)
int total = 0;
SculptVertexNeighborIter ni;
- sculpt_vertex_neighbors_iter_begin(ss, index, ni)
- {
+ SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, index, ni) {
avg += SCULPT_vertex_mask_get(ss, ni.index);
total++;
}
- sculpt_vertex_neighbors_iter_end(ni);
+ SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
if (total > 0) {
return avg / (float)total;
@@ -3132,7 +3210,7 @@ static void do_smooth_brush_multires_task_cb_ex(void *__restrict userdata,
}
else {
float avg[3], val[3];
- grids_neighbor_average(ss, avg, vd.index);
+ SCULPT_neighbor_coords_average(ss, avg, vd.index);
sub_v3_v3v3(val, avg, vd.co);
madd_v3_v3v3fl(val, vd.co, val, fade);
sculpt_clip(sd, ss, vd.co, val);
@@ -3231,6 +3309,152 @@ static void do_smooth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod
SculptSession *ss = ob->sculpt;
smooth(sd, ob, nodes, totnode, ss->cache->bstrength, false);
}
+/* HC Smooth Algorithm. */
+/* From: Improved Laplacian Smoothing of Noisy Surface Meshes */
+
+static void surface_smooth_laplacian_step(SculptSession *ss,
+ float *disp,
+ const float co[3],
+ float (*laplacian_disp)[3],
+ const int v_index,
+ const float origco[3],
+ const float alpha)
+{
+ float laplacian_smooth_co[3];
+ float weigthed_o[3], weigthed_q[3], d[3];
+ SCULPT_neighbor_coords_average(ss, laplacian_smooth_co, v_index);
+
+ mul_v3_v3fl(weigthed_o, origco, alpha);
+ mul_v3_v3fl(weigthed_q, co, 1.0f - alpha);
+ add_v3_v3v3(d, weigthed_o, weigthed_q);
+ sub_v3_v3v3(laplacian_disp[v_index], laplacian_smooth_co, d);
+
+ sub_v3_v3v3(disp, laplacian_smooth_co, co);
+}
+
+static void surface_smooth_displace_step(SculptSession *ss,
+ float *co,
+ float (*laplacian_disp)[3],
+ const int v_index,
+ const float beta,
+ const float fade)
+{
+ float b_avg[3] = {0.0f, 0.0f, 0.0f};
+ float b_current_vertex[3];
+ int total = 0;
+ SculptVertexNeighborIter ni;
+ SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, v_index, ni) {
+ add_v3_v3(b_avg, laplacian_disp[ni.index]);
+ total++;
+ }
+ SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
+ if (total > 0) {
+ mul_v3_v3fl(b_current_vertex, b_avg, (1.0f - beta) / (float)total);
+ madd_v3_v3fl(b_current_vertex, laplacian_disp[v_index], beta);
+ mul_v3_fl(b_current_vertex, clamp_f(fade, 0.0f, 1.0f));
+ sub_v3_v3(co, b_current_vertex);
+ }
+}
+
+static void do_surface_smooth_brush_laplacian_task_cb_ex(void *__restrict userdata,
+ const int n,
+ const TaskParallelTLS *__restrict tls)
+{
+ SculptThreadedTaskData *data = userdata;
+ SculptSession *ss = data->ob->sculpt;
+ const Brush *brush = data->brush;
+ const float bstrength = ss->cache->bstrength;
+ float alpha = brush->surface_smooth_shape_preservation;
+
+ PBVHVertexIter vd;
+ SculptOrigVertData orig_data;
+
+ SculptBrushTest test;
+ SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape(
+ ss, &test, data->brush->falloff_shape);
+
+ SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n]);
+
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
+ {
+ SCULPT_orig_vert_data_update(&orig_data, &vd);
+ if (sculpt_brush_test_sq_fn(&test, vd.co)) {
+ const float fade =
+ bstrength *
+ SCULPT_brush_strength_factor(
+ ss, brush, vd.co, sqrtf(test.dist), vd.no, vd.fno, 0.0f, vd.index, tls->thread_id);
+
+ float disp[3];
+ surface_smooth_laplacian_step(ss,
+ disp,
+ vd.co,
+ ss->cache->surface_smooth_laplacian_disp,
+ vd.index,
+ orig_data.co,
+ alpha);
+ madd_v3_v3fl(vd.co, disp, clamp_f(fade, 0.0f, 1.0f));
+ }
+ BKE_pbvh_vertex_iter_end;
+ }
+}
+
+static void do_surface_smooth_brush_displace_task_cb_ex(void *__restrict userdata,
+ const int n,
+ const TaskParallelTLS *__restrict tls)
+{
+ SculptThreadedTaskData *data = userdata;
+ SculptSession *ss = data->ob->sculpt;
+ const Brush *brush = data->brush;
+ const float bstrength = ss->cache->bstrength;
+ const float beta = brush->surface_smooth_current_vertex;
+
+ PBVHVertexIter vd;
+
+ SculptBrushTest test;
+ SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape(
+ ss, &test, data->brush->falloff_shape);
+
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
+ {
+ if (sculpt_brush_test_sq_fn(&test, vd.co)) {
+ const float fade =
+ bstrength *
+ SCULPT_brush_strength_factor(
+ ss, brush, vd.co, sqrtf(test.dist), vd.no, vd.fno, 0.0f, vd.index, tls->thread_id);
+ surface_smooth_displace_step(
+ ss, vd.co, ss->cache->surface_smooth_laplacian_disp, vd.index, beta, fade);
+ }
+ }
+ BKE_pbvh_vertex_iter_end;
+}
+
+static void do_surface_smooth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
+{
+ Brush *brush = BKE_paint_brush(&sd->paint);
+ SculptSession *ss = ob->sculpt;
+
+ if (ss->cache->mirror_symmetry_pass == 0 && ss->cache->radial_symmetry_pass == 0) {
+ ss->cache->surface_smooth_laplacian_disp = MEM_callocN(
+ SCULPT_vertex_count_get(ss) * 3 * sizeof(float), "HC smooth laplacian b");
+ }
+
+ /* Threaded loop over nodes. */
+ SculptThreadedTaskData data = {
+ .sd = sd,
+ .ob = ob,
+ .brush = brush,
+ .nodes = nodes,
+ };
+
+ PBVHParallelSettings settings;
+ BKE_pbvh_parallel_range_settings(&settings, (sd->flags & SCULPT_USE_OPENMP), totnode);
+ for (int i = 0; i < brush->surface_smooth_iterations; i++) {
+ BKE_pbvh_parallel_range(
+ 0, totnode, &data, do_surface_smooth_brush_laplacian_task_cb_ex, &settings);
+ BKE_pbvh_parallel_range(
+ 0, totnode, &data, do_surface_smooth_brush_displace_task_cb_ex, &settings);
+ }
+}
static void do_mask_brush_draw_task_cb_ex(void *__restrict userdata,
const int n,
@@ -3433,7 +3657,7 @@ static void do_relax_face_sets_brush_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- if (relax_face_sets != sculpt_vertex_has_unique_face_set(ss, vd.index)) {
+ if (relax_face_sets != SCULPT_vertex_has_unique_face_set(ss, vd.index)) {
const float fade = bstrength * SCULPT_brush_strength_factor(ss,
brush,
vd.co,
@@ -3615,8 +3839,7 @@ static void do_topology_slide_task_cb_ex(void *__restrict userdata,
normalize_v3_v3(current_disp_norm, current_disp);
mul_v3_v3fl(current_disp, current_disp_norm, ss->cache->bstrength);
SculptVertexNeighborIter ni;
- sculpt_vertex_neighbors_iter_begin(ss, vd.index, ni)
- {
+ SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.index, ni) {
float vertex_disp[3];
float vertex_disp_norm[3];
sub_v3_v3v3(vertex_disp, SCULPT_vertex_co_get(ss, ni.index), vd.co);
@@ -3625,7 +3848,7 @@ static void do_topology_slide_task_cb_ex(void *__restrict userdata,
madd_v3_v3fl(final_disp, vertex_disp_norm, dot_v3v3(current_disp, vertex_disp));
}
}
- sculpt_vertex_neighbors_iter_end(ni);
+ SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
mul_v3_v3fl(proxy[vd.i], final_disp, fade);
@@ -3649,15 +3872,14 @@ void SCULPT_relax_vertex(SculptSession *ss,
zero_v3(smooth_pos);
SculptVertexNeighborIter ni;
- sculpt_vertex_neighbors_iter_begin(ss, vd->index, ni)
- {
+ SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd->index, ni) {
if (!filter_boundary_face_sets ||
- (filter_boundary_face_sets && !sculpt_vertex_has_unique_face_set(ss, ni.index))) {
+ (filter_boundary_face_sets && !SCULPT_vertex_has_unique_face_set(ss, ni.index))) {
add_v3_v3(smooth_pos, SCULPT_vertex_co_get(ss, ni.index));
count++;
}
}
- sculpt_vertex_neighbors_iter_end(ni);
+ SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
if (count > 0) {
mul_v3_fl(smooth_pos, 1.0f / (float)count);
@@ -5599,10 +5821,10 @@ static void do_clay_thumb_brush_task_cb_ex(void *__restrict userdata,
static float sculpt_clay_thumb_get_stabilized_pressure(StrokeCache *cache)
{
float final_pressure = 0.0f;
- for (int i = 0; i < CLAY_STABILIZER_LEN; i++) {
+ for (int i = 0; i < SCULPT_CLAY_STABILIZER_LEN; i++) {
final_pressure += cache->clay_pressure_stabilizer[i];
}
- return final_pressure / (float)CLAY_STABILIZER_LEN;
+ return final_pressure / (float)SCULPT_CLAY_STABILIZER_LEN;
}
static void do_clay_thumb_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
@@ -5987,7 +6209,12 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe
do_draw_brush(sd, ob, nodes, totnode);
break;
case SCULPT_TOOL_SMOOTH:
- do_smooth_brush(sd, ob, nodes, totnode);
+ if (brush->smooth_deform_type == BRUSH_SMOOTH_DEFORM_LAPLACIAN) {
+ do_smooth_brush(sd, ob, nodes, totnode);
+ }
+ else if (brush->smooth_deform_type == BRUSH_SMOOTH_DEFORM_SURFACE) {
+ do_surface_smooth_brush(sd, ob, nodes, totnode);
+ }
break;
case SCULPT_TOOL_CREASE:
do_crease_brush(sd, ob, nodes, totnode);
@@ -7072,7 +7299,7 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob, Po
/* Clay stabilized pressure. */
if (brush->sculpt_tool == SCULPT_TOOL_CLAY_THUMB) {
if (ss->cache->first_time) {
- for (int i = 0; i < CLAY_STABILIZER_LEN; i++) {
+ for (int i = 0; i < SCULPT_CLAY_STABILIZER_LEN; i++) {
ss->cache->clay_pressure_stabilizer[i] = 0.0f;
}
ss->cache->clay_pressure_stabilizer_index = 0;
@@ -7080,7 +7307,7 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob, Po
else {
cache->clay_pressure_stabilizer[cache->clay_pressure_stabilizer_index] = cache->pressure;
cache->clay_pressure_stabilizer_index += 1;
- if (cache->clay_pressure_stabilizer_index >= CLAY_STABILIZER_LEN) {
+ if (cache->clay_pressure_stabilizer_index >= SCULPT_CLAY_STABILIZER_LEN) {
cache->clay_pressure_stabilizer_index = 0;
}
}
@@ -8128,6 +8355,22 @@ static void sculpt_dynamic_topology_disable_ex(
}
else {
BKE_sculptsession_bm_to_me(ob, true);
+
+ /* Reset Face Sets as they are no longer valid. */
+ if (!CustomData_has_layer(&me->pdata, CD_SCULPT_FACE_SETS)) {
+ CustomData_add_layer(&me->pdata, CD_SCULPT_FACE_SETS, CD_CALLOC, NULL, me->totpoly);
+ }
+ ss->face_sets = CustomData_get_layer(&me->pdata, CD_SCULPT_FACE_SETS);
+ for (int i = 0; i < me->totpoly; i++) {
+ ss->face_sets[i] = 1;
+ }
+ me->face_sets_color_default = 1;
+
+ /* Sync the visibility to vertices manually as the pmap is still not initialized. */
+ for (int i = 0; i < me->totvert; i++) {
+ me->mvert[i].flag &= ~ME_HIDE;
+ me->mvert[i].flag |= ME_VERT_PBVH_UPDATE;
+ }
}
/* Clear data. */
@@ -8853,12 +9096,11 @@ static void sample_detail_voxel(bContext *C, ViewContext *vc, int mx, int my)
float edge_length = 0.0f;
int tot = 0;
SculptVertexNeighborIter ni;
- sculpt_vertex_neighbors_iter_begin(ss, active_vertex, ni)
- {
+ SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, active_vertex, ni) {
edge_length += len_v3v3(active_vertex_co, SCULPT_vertex_co_get(ss, ni.index));
tot += 1;
}
- sculpt_vertex_neighbors_iter_end(ni);
+ SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
if (tot > 0) {
mesh->remesh_voxel_size = edge_length / (float)tot;
}
@@ -9155,7 +9397,9 @@ static void sculpt_filter_cache_free(SculptSession *ss)
if (ss->filter_cache->automask) {
MEM_freeN(ss->filter_cache->automask);
}
-
+ if (ss->filter_cache->surface_smooth_laplacian_disp) {
+ MEM_freeN(ss->filter_cache->surface_smooth_laplacian_disp);
+ }
MEM_freeN(ss->filter_cache);
ss->filter_cache = NULL;
}
@@ -9168,6 +9412,7 @@ typedef enum eSculptMeshFilterTypes {
MESH_FILTER_RANDOM = 4,
MESH_FILTER_RELAX = 5,
MESH_FILTER_RELAX_FACE_SETS = 6,
+ MESH_FILTER_SURFACE_SMOOTH = 7,
} eSculptMeshFilterTypes;
static EnumPropertyItem prop_mesh_filter_types[] = {
@@ -9182,6 +9427,11 @@ static EnumPropertyItem prop_mesh_filter_types[] = {
0,
"Relax Face Sets",
"Smooth the edges of all the Face Sets"},
+ {MESH_FILTER_SURFACE_SMOOTH,
+ "SURFACE_SMOOTH",
+ 0,
+ "Surface Smooth",
+ "Smooth the surface of the mesh, preserving the volume"},
{0, NULL, 0, NULL, NULL},
};
@@ -9198,9 +9448,13 @@ static EnumPropertyItem prop_mesh_filter_deform_axis_items[] = {
{0, NULL, 0, NULL, NULL},
};
-static bool sculpt_mesh_filter_needs_pmap(int filter_type)
+static bool sculpt_mesh_filter_needs_pmap(int filter_type, bool use_face_sets)
{
- return ELEM(filter_type, MESH_FILTER_SMOOTH, MESH_FILTER_RELAX, MESH_FILTER_RELAX_FACE_SETS);
+ return use_face_sets || ELEM(filter_type,
+ MESH_FILTER_SMOOTH,
+ MESH_FILTER_RELAX,
+ MESH_FILTER_RELAX_FACE_SETS,
+ MESH_FILTER_SURFACE_SMOOTH);
}
static void mesh_filter_task_cb(void *__restrict userdata,
@@ -9242,7 +9496,7 @@ static void mesh_filter_task_cb(void *__restrict userdata,
/* Skip the edges of the face set when relaxing or smoothing. There is a relax face set
* option to relax the boindaries independently. */
if (filter_type == MESH_FILTER_RELAX) {
- if (!sculpt_vertex_has_unique_face_set(ss, vd.index)) {
+ if (!SCULPT_vertex_has_unique_face_set(ss, vd.index)) {
continue;
}
}
@@ -9256,7 +9510,7 @@ static void mesh_filter_task_cb(void *__restrict userdata,
}
if (filter_type == MESH_FILTER_RELAX_FACE_SETS) {
- if (relax_face_sets == sculpt_vertex_has_unique_face_set(ss, vd.index)) {
+ if (relax_face_sets == SCULPT_vertex_has_unique_face_set(ss, vd.index)) {
continue;
}
}
@@ -9272,7 +9526,7 @@ static void mesh_filter_task_cb(void *__restrict userdata,
bmesh_neighbor_average(avg, vd.bm_vert);
break;
case PBVH_GRIDS:
- grids_neighbor_average(ss, avg, vd.index);
+ SCULPT_neighbor_coords_average(ss, avg, vd.index);
break;
}
sub_v3_v3v3(val, avg, orig_co);
@@ -9333,6 +9587,16 @@ static void mesh_filter_task_cb(void *__restrict userdata,
sub_v3_v3v3(disp, val, vd.co);
break;
}
+ case MESH_FILTER_SURFACE_SMOOTH: {
+ surface_smooth_laplacian_step(ss,
+ disp,
+ vd.co,
+ ss->filter_cache->surface_smooth_laplacian_disp,
+ vd.index,
+ orig_data.co,
+ ss->filter_cache->surface_smooth_shape_preservation);
+ break;
+ }
}
for (int it = 0; it < 3; it++) {
@@ -9341,7 +9605,12 @@ static void mesh_filter_task_cb(void *__restrict userdata,
}
}
- add_v3_v3v3(final_pos, orig_co, disp);
+ if (filter_type == MESH_FILTER_SURFACE_SMOOTH) {
+ madd_v3_v3v3fl(final_pos, vd.co, disp, clamp_f(fade, 0.0f, 1.0f));
+ }
+ else {
+ add_v3_v3v3(final_pos, orig_co, disp);
+ }
copy_v3_v3(vd.co, final_pos);
if (vd.mvert) {
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
@@ -9352,6 +9621,32 @@ static void mesh_filter_task_cb(void *__restrict userdata,
BKE_pbvh_node_mark_update(node);
}
+static void mesh_filter_surface_smooth_displace_task_cb(
+ void *__restrict userdata, const int i, const TaskParallelTLS *__restrict UNUSED(tls))
+{
+ SculptThreadedTaskData *data = userdata;
+ SculptSession *ss = data->ob->sculpt;
+ PBVHNode *node = data->nodes[i];
+ PBVHVertexIter vd;
+
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_UNIQUE)
+ {
+ float fade = vd.mask ? *vd.mask : 0.0f;
+ fade = 1.0f - fade;
+ fade *= data->filter_strength;
+ if (fade == 0.0f) {
+ continue;
+ }
+ surface_smooth_displace_step(ss,
+ vd.co,
+ ss->filter_cache->surface_smooth_laplacian_disp,
+ vd.index,
+ ss->filter_cache->surface_smooth_current_vertex,
+ clamp_f(fade, 0.0f, 1.0f));
+ }
+ BKE_pbvh_vertex_iter_end;
+}
+
static int sculpt_mesh_filter_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
Object *ob = CTX_data_active_object(C);
@@ -9360,6 +9655,7 @@ static int sculpt_mesh_filter_modal(bContext *C, wmOperator *op, const wmEvent *
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
int filter_type = RNA_enum_get(op->ptr, "type");
float filter_strength = RNA_float_get(op->ptr, "strength");
+ const bool use_face_sets = RNA_boolean_get(op->ptr, "use_face_sets");
if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
sculpt_filter_cache_free(ss);
@@ -9377,7 +9673,7 @@ static int sculpt_mesh_filter_modal(bContext *C, wmOperator *op, const wmEvent *
SCULPT_vertex_random_access_init(ss);
- bool needs_pmap = sculpt_mesh_filter_needs_pmap(filter_type);
+ bool needs_pmap = sculpt_mesh_filter_needs_pmap(filter_type, use_face_sets);
BKE_sculpt_update_object_for_edit(depsgraph, ob, needs_pmap, false);
SculptThreadedTaskData data = {
@@ -9393,6 +9689,14 @@ static int sculpt_mesh_filter_modal(bContext *C, wmOperator *op, const wmEvent *
&settings, (sd->flags & SCULPT_USE_OPENMP), ss->filter_cache->totnode);
BKE_pbvh_parallel_range(0, ss->filter_cache->totnode, &data, mesh_filter_task_cb, &settings);
+ if (filter_type == MESH_FILTER_SURFACE_SMOOTH) {
+ BKE_pbvh_parallel_range(0,
+ ss->filter_cache->totnode,
+ &data,
+ mesh_filter_surface_smooth_displace_task_cb,
+ &settings);
+ }
+
ss->filter_cache->iteration_count++;
if (ss->deform_modifiers_active || ss->shapekey_active) {
@@ -9432,9 +9736,11 @@ static int sculpt_mesh_filter_invoke(bContext *C, wmOperator *op, const wmEvent
SCULPT_cursor_geometry_info_update(C, &sgi, mouse, false);
}
+ const bool use_face_sets = RNA_boolean_get(op->ptr, "use_face_sets");
+
SCULPT_vertex_random_access_init(ss);
- bool needs_pmap = sculpt_mesh_filter_needs_pmap(filter_type);
+ bool needs_pmap = sculpt_mesh_filter_needs_pmap(filter_type, use_face_sets);
BKE_sculpt_update_object_for_edit(depsgraph, ob, needs_pmap, false);
if (BKE_pbvh_type(pbvh) == PBVH_FACES && needs_pmap && !ob->sculpt->pmap) {
@@ -9445,7 +9751,7 @@ static int sculpt_mesh_filter_invoke(bContext *C, wmOperator *op, const wmEvent
sculpt_filter_cache_init(ob, sd);
- if (RNA_boolean_get(op->ptr, "use_face_sets")) {
+ if (use_face_sets) {
ss->filter_cache->active_face_set = SCULPT_vertex_face_set_get(ss,
SCULPT_active_vertex_get(ss));
}
@@ -9453,6 +9759,15 @@ static int sculpt_mesh_filter_invoke(bContext *C, wmOperator *op, const wmEvent
ss->filter_cache->active_face_set = SCULPT_FACE_SET_NONE;
}
+ if (RNA_enum_get(op->ptr, "type") == MESH_FILTER_SURFACE_SMOOTH) {
+ ss->filter_cache->surface_smooth_laplacian_disp = MEM_mallocN(
+ 3 * sizeof(float) * SCULPT_vertex_count_get(ss), "surface smooth disp");
+ ss->filter_cache->surface_smooth_shape_preservation = RNA_float_get(
+ op->ptr, "surface_smooth_shape_preservation");
+ ss->filter_cache->surface_smooth_current_vertex = RNA_float_get(
+ op->ptr, "surface_smooth_current_vertex");
+ }
+
ss->filter_cache->enabled_axis[0] = deform_axis & MESH_FILTER_DEFORM_X;
ss->filter_cache->enabled_axis[1] = deform_axis & MESH_FILTER_DEFORM_Y;
ss->filter_cache->enabled_axis[2] = deform_axis & MESH_FILTER_DEFORM_Z;
@@ -9505,6 +9820,26 @@ static void SCULPT_OT_mesh_filter(struct wmOperatorType *ot)
false,
"Use Face Sets",
"Apply the filter only to the Face Mask under the cursor");
+
+ /* Surface Smooth Mesh Filter properties. */
+ RNA_def_float(ot->srna,
+ "surface_smooth_shape_preservation",
+ 0.5f,
+ 0.0f,
+ 1.0f,
+ "Shape Preservation",
+ "How much of the original shape is preserved when smoothing",
+ 0.0f,
+ 1.0f);
+ RNA_def_float(ot->srna,
+ "surface_smooth_current_vertex",
+ 0.5f,
+ 0.0f,
+ 1.0f,
+ "Per Vertex Displacement",
+ "How much the position of each individual vertex influences the final result",
+ 0.0f,
+ 1.0f);
}
typedef enum eSculptMaskFilterTypes {
@@ -9596,26 +9931,24 @@ static void mask_filter_task_cb(void *__restrict userdata,
}
case MASK_FILTER_GROW:
max = 0.0f;
- sculpt_vertex_neighbors_iter_begin(ss, vd.index, ni)
- {
+ SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.index, ni) {
float vmask_f = data->prev_mask[ni.index];
if (vmask_f > max) {
max = vmask_f;
}
}
- sculpt_vertex_neighbors_iter_end(ni);
+ SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
*vd.mask = max;
break;
case MASK_FILTER_SHRINK:
min = 1.0f;
- sculpt_vertex_neighbors_iter_begin(ss, vd.index, ni)
- {
+ SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.index, ni) {
float vmask_f = data->prev_mask[ni.index];
if (vmask_f < min) {
min = vmask_f;
}
}
- sculpt_vertex_neighbors_iter_end(ni);
+ SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
*vd.mask = min;
break;
case MASK_FILTER_CONTRAST_INCREASE:
@@ -9766,15 +10099,14 @@ static float neighbor_dirty_mask(SculptSession *ss, PBVHVertexIter *vd)
zero_v3(avg);
SculptVertexNeighborIter ni;
- sculpt_vertex_neighbors_iter_begin(ss, vd->index, ni)
- {
+ SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd->index, ni) {
float normalized[3];
sub_v3_v3v3(normalized, SCULPT_vertex_co_get(ss, ni.index), vd->co);
normalize_v3(normalized);
add_v3_v3(avg, normalized);
total++;
}
- sculpt_vertex_neighbors_iter_end(ni);
+ SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
if (total > 0) {
mul_v3_fl(avg, 1.0f / total);
@@ -10323,11 +10655,10 @@ static int sculpt_mask_expand_invoke(bContext *C, wmOperator *op, const wmEvent
for (int i = 0; i < vertex_count; i++) {
float avg = 0.0f;
SculptVertexNeighborIter ni;
- sculpt_vertex_neighbors_iter_begin(ss, i, ni)
- {
+ SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, i, ni) {
avg += ss->filter_cache->normal_factor[ni.index];
}
- sculpt_vertex_neighbors_iter_end(ni);
+ SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
ss->filter_cache->normal_factor[i] = avg / ni.size;
}
}
@@ -10452,8 +10783,7 @@ void SCULPT_geometry_preview_lines_update(bContext *C, SculptSession *ss, float
int from_v;
BLI_gsqueue_pop(not_visited_vertices, &from_v);
SculptVertexNeighborIter ni;
- sculpt_vertex_neighbors_iter_begin(ss, from_v, ni)
- {
+ SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, from_v, ni) {
if (totpoints + (ni.size * 2) < max_preview_vertices) {
int to_v = ni.index;
ss->preview_vert_index_list[totpoints] = from_v;
@@ -10469,7 +10799,7 @@ void SCULPT_geometry_preview_lines_update(bContext *C, SculptSession *ss, float
}
}
}
- sculpt_vertex_neighbors_iter_end(ni);
+ SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
}
BLI_gsqueue_free(not_visited_vertices);
@@ -10798,6 +11128,7 @@ typedef enum eSculptFaceGroupsCreateModes {
SCULPT_FACE_SET_MASKED = 0,
SCULPT_FACE_SET_VISIBLE = 1,
SCULPT_FACE_SET_ALL = 2,
+ SCULPT_FACE_SET_SELECTION = 3,
} eSculptFaceGroupsCreateModes;
static EnumPropertyItem prop_sculpt_face_set_create_types[] = {
@@ -10822,6 +11153,13 @@ static EnumPropertyItem prop_sculpt_face_set_create_types[] = {
"Face Set Full Mesh",
"Create an unique Face Set with all faces in the sculpt",
},
+ {
+ SCULPT_FACE_SET_SELECTION,
+ "SELECTION",
+ 0,
+ "Face Set From Edit Mode Selection",
+ "Create an Face Set corresponding to the Edit Mode face selection",
+ },
{0, NULL, 0, NULL, NULL},
};
@@ -10880,6 +11218,31 @@ static int sculpt_face_set_create_invoke(bContext *C, wmOperator *op, const wmEv
}
}
+ if (mode == SCULPT_FACE_SET_SELECTION) {
+ Mesh *mesh = ob->data;
+ BMesh *bm;
+ const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(mesh);
+ bm = BM_mesh_create(&allocsize,
+ &((struct BMeshCreateParams){
+ .use_toolflags = true,
+ }));
+
+ BM_mesh_bm_from_me(bm,
+ mesh,
+ (&(struct BMeshFromMeshParams){
+ .calc_face_normal = true,
+ }));
+
+ BMIter iter;
+ BMFace *f;
+ BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
+ if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {
+ ss->face_sets[BM_elem_index_get(f)] = next_face_set;
+ }
+ }
+ BM_mesh_free(bm);
+ }
+
for (int i = 0; i < totnode; i++) {
BKE_pbvh_node_mark_redraw(nodes[i]);
}
@@ -10911,6 +11274,349 @@ static void SCULPT_OT_face_sets_create(wmOperatorType *ot)
ot->srna, "mode", prop_sculpt_face_set_create_types, SCULPT_FACE_SET_MASKED, "Mode", "");
}
+typedef enum eSculptFaceSetsInitMode {
+ SCULPT_FACE_SETS_FROM_LOOSE_PARTS = 0,
+ SCULPT_FACE_SETS_FROM_MATERIALS = 1,
+ SCULPT_FACE_SETS_FROM_NORMALS = 2,
+ SCULPT_FACE_SETS_FROM_UV_SEAMS = 3,
+ SCULPT_FACE_SETS_FROM_CREASES = 4,
+ SCULPT_FACE_SETS_FROM_SHARP_EDGES = 5,
+ SCULPT_FACE_SETS_FROM_BEVEL_WEIGHT = 6,
+ SCULPT_FACE_SETS_FROM_FACE_MAPS = 7,
+} eSculptFaceSetsInitMode;
+
+static EnumPropertyItem prop_sculpt_face_sets_init_types[] = {
+ {
+ SCULPT_FACE_SETS_FROM_LOOSE_PARTS,
+ "LOOSE_PARTS",
+ 0,
+ "Face Sets From Loose Parts",
+ "Create a Face Set per loose part in the mesh",
+ },
+ {
+ SCULPT_FACE_SETS_FROM_MATERIALS,
+ "MATERIALS",
+ 0,
+ "Face Sets From Material Slots",
+ "Create a Face Set per Material Slot",
+ },
+ {
+ SCULPT_FACE_SETS_FROM_NORMALS,
+ "NORMALS",
+ 0,
+ "Face Sets From Mesh Normals",
+ "Create Face Sets for Faces that have similar normal",
+ },
+ {
+ SCULPT_FACE_SETS_FROM_UV_SEAMS,
+ "UV_SEAMS",
+ 0,
+ "Face Sets From UV Seams",
+ "Create Face Sets using UV Seams as boundaries",
+ },
+ {
+ SCULPT_FACE_SETS_FROM_CREASES,
+ "CREASES",
+ 0,
+ "Face Sets From Edge Creases",
+ "Create Face Sets using Edge Creases as boundaries",
+ },
+ {
+ SCULPT_FACE_SETS_FROM_BEVEL_WEIGHT,
+ "BEVEL_WEIGHT",
+ 0,
+ "Face Sets From Bevel Weight",
+ "Create Face Sets using Bevel Weights as boundaries",
+ },
+ {
+ SCULPT_FACE_SETS_FROM_SHARP_EDGES,
+ "SHARP_EDGES",
+ 0,
+ "Face Sets From Sharp Edges",
+ "Create Face Sets using Sharp Edges as boundaries",
+ },
+ {
+ SCULPT_FACE_SETS_FROM_FACE_MAPS,
+ "FACE_MAPS",
+ 0,
+ "Face Sets From Face Maps",
+ "Create a Face Set per Face Map",
+ },
+ {0, NULL, 0, NULL, NULL},
+};
+
+typedef bool (*face_sets_flood_fill_test)(
+ BMesh *bm, BMFace *from_f, BMEdge *from_e, BMFace *to_f, const float threshold);
+
+static bool sculpt_face_sets_init_loose_parts_test(BMesh *UNUSED(bm),
+ BMFace *UNUSED(from_f),
+ BMEdge *UNUSED(from_e),
+ BMFace *UNUSED(to_f),
+ const float UNUSED(threshold))
+{
+ return true;
+}
+
+static bool sculpt_face_sets_init_normals_test(
+ BMesh *UNUSED(bm), BMFace *from_f, BMEdge *UNUSED(from_e), BMFace *to_f, const float threshold)
+{
+ return fabsf(dot_v3v3(from_f->no, to_f->no)) > threshold;
+}
+
+static bool sculpt_face_sets_init_uv_seams_test(BMesh *UNUSED(bm),
+ BMFace *UNUSED(from_f),
+ BMEdge *from_e,
+ BMFace *UNUSED(to_f),
+ const float UNUSED(threshold))
+{
+ return !BM_elem_flag_test(from_e, BM_ELEM_SEAM);
+}
+
+static bool sculpt_face_sets_init_crease_test(
+ BMesh *bm, BMFace *UNUSED(from_f), BMEdge *from_e, BMFace *UNUSED(to_f), const float threshold)
+{
+ return BM_elem_float_data_get(&bm->edata, from_e, CD_CREASE) < threshold;
+}
+
+static bool sculpt_face_sets_init_bevel_weight_test(
+ BMesh *bm, BMFace *UNUSED(from_f), BMEdge *from_e, BMFace *UNUSED(to_f), const float threshold)
+{
+ return BM_elem_float_data_get(&bm->edata, from_e, CD_BWEIGHT) < threshold;
+}
+
+static bool sculpt_face_sets_init_sharp_edges_test(BMesh *UNUSED(bm),
+ BMFace *UNUSED(from_f),
+ BMEdge *from_e,
+ BMFace *UNUSED(to_f),
+ const float UNUSED(threshold))
+{
+ return BM_elem_flag_test(from_e, BM_ELEM_SMOOTH);
+}
+
+static void sculpt_face_sets_init_flood_fill(Object *ob,
+ face_sets_flood_fill_test test,
+ const float threshold)
+{
+ SculptSession *ss = ob->sculpt;
+ Mesh *mesh = ob->data;
+ BMesh *bm;
+ const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(mesh);
+ bm = BM_mesh_create(&allocsize,
+ &((struct BMeshCreateParams){
+ .use_toolflags = true,
+ }));
+
+ BM_mesh_bm_from_me(bm,
+ mesh,
+ (&(struct BMeshFromMeshParams){
+ .calc_face_normal = true,
+ }));
+
+ bool *visited_faces = MEM_callocN(sizeof(bool) * mesh->totpoly, "visited faces");
+ const int totfaces = mesh->totpoly;
+
+ int *face_sets = ss->face_sets;
+
+ BM_mesh_elem_table_init(bm, BM_FACE);
+ BM_mesh_elem_table_ensure(bm, BM_FACE);
+
+ int next_face_set = 1;
+
+ for (int i = 0; i < totfaces; i++) {
+ if (!visited_faces[i]) {
+ GSQueue *queue;
+ queue = BLI_gsqueue_new(sizeof(int));
+
+ face_sets[i] = next_face_set;
+ visited_faces[i] = true;
+ BLI_gsqueue_push(queue, &i);
+
+ while (!BLI_gsqueue_is_empty(queue)) {
+ int from_f;
+ BLI_gsqueue_pop(queue, &from_f);
+
+ BMFace *f, *f_neighbor;
+ BMEdge *ed;
+ BMIter iter_a, iter_b;
+
+ f = BM_face_at_index(bm, from_f);
+
+ BM_ITER_ELEM (ed, &iter_a, f, BM_EDGES_OF_FACE) {
+ BM_ITER_ELEM (f_neighbor, &iter_b, ed, BM_FACES_OF_EDGE) {
+ if (f_neighbor != f) {
+ int neighbor_face_index = BM_elem_index_get(f_neighbor);
+ if (!visited_faces[neighbor_face_index]) {
+ if (test(bm, f, ed, f_neighbor, threshold)) {
+ face_sets[neighbor_face_index] = next_face_set;
+ visited_faces[neighbor_face_index] = true;
+ BLI_gsqueue_push(queue, &neighbor_face_index);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ next_face_set += 1;
+
+ BLI_gsqueue_free(queue);
+ }
+ }
+
+ MEM_SAFE_FREE(visited_faces);
+
+ BM_mesh_free(bm);
+}
+
+static void sculpt_face_sets_init_loop(Object *ob, const int mode)
+{
+ Mesh *mesh = ob->data;
+ SculptSession *ss = ob->sculpt;
+ BMesh *bm;
+ const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(mesh);
+ bm = BM_mesh_create(&allocsize,
+ &((struct BMeshCreateParams){
+ .use_toolflags = true,
+ }));
+
+ BM_mesh_bm_from_me(bm,
+ mesh,
+ (&(struct BMeshFromMeshParams){
+ .calc_face_normal = true,
+ }));
+ BMIter iter;
+ BMFace *f;
+
+ const int cd_fmaps_offset = CustomData_get_offset(&bm->pdata, CD_FACEMAP);
+
+ BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
+ if (mode == SCULPT_FACE_SETS_FROM_MATERIALS) {
+ ss->face_sets[BM_elem_index_get(f)] = (int)(f->mat_nr + 1);
+ }
+ else if (mode == SCULPT_FACE_SETS_FROM_FACE_MAPS) {
+ if (cd_fmaps_offset != -1) {
+ ss->face_sets[BM_elem_index_get(f)] = BM_ELEM_CD_GET_INT(f, cd_fmaps_offset) + 2;
+ }
+ else {
+ ss->face_sets[BM_elem_index_get(f)] = 1;
+ }
+ }
+ }
+ BM_mesh_free(bm);
+}
+
+static int sculpt_face_set_init_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+{
+ Object *ob = CTX_data_active_object(C);
+ SculptSession *ss = ob->sculpt;
+ ARegion *region = CTX_wm_region(C);
+ Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
+
+ const int mode = RNA_enum_get(op->ptr, "mode");
+
+ /* Dyntopo and Multires not supported for now. */
+ if (BKE_pbvh_type(ss->pbvh) != PBVH_FACES) {
+ return OPERATOR_CANCELLED;
+ }
+
+ BKE_sculpt_update_object_for_edit(depsgraph, ob, true, false);
+
+ PBVH *pbvh = ob->sculpt->pbvh;
+ PBVHNode **nodes;
+ int totnode;
+ BKE_pbvh_search_gather(pbvh, NULL, NULL, &nodes, &totnode);
+
+ if (!nodes) {
+ return OPERATOR_CANCELLED;
+ }
+
+ SCULPT_undo_push_begin("face set change");
+ SCULPT_undo_push_node(ob, nodes[0], SCULPT_UNDO_FACE_SETS);
+
+ const float threshold = RNA_float_get(op->ptr, "threshold");
+
+ switch (mode) {
+ case SCULPT_FACE_SETS_FROM_LOOSE_PARTS:
+ sculpt_face_sets_init_flood_fill(ob, sculpt_face_sets_init_loose_parts_test, threshold);
+ break;
+ case SCULPT_FACE_SETS_FROM_MATERIALS:
+ sculpt_face_sets_init_loop(ob, SCULPT_FACE_SETS_FROM_MATERIALS);
+ break;
+ case SCULPT_FACE_SETS_FROM_NORMALS:
+ sculpt_face_sets_init_flood_fill(ob, sculpt_face_sets_init_normals_test, threshold);
+ break;
+ case SCULPT_FACE_SETS_FROM_UV_SEAMS:
+ sculpt_face_sets_init_flood_fill(ob, sculpt_face_sets_init_uv_seams_test, threshold);
+ break;
+ case SCULPT_FACE_SETS_FROM_CREASES:
+ sculpt_face_sets_init_flood_fill(ob, sculpt_face_sets_init_crease_test, threshold);
+ break;
+ case SCULPT_FACE_SETS_FROM_SHARP_EDGES:
+ sculpt_face_sets_init_flood_fill(ob, sculpt_face_sets_init_sharp_edges_test, threshold);
+ break;
+ case SCULPT_FACE_SETS_FROM_BEVEL_WEIGHT:
+ sculpt_face_sets_init_flood_fill(ob, sculpt_face_sets_init_bevel_weight_test, threshold);
+ break;
+ case SCULPT_FACE_SETS_FROM_FACE_MAPS:
+ sculpt_face_sets_init_loop(ob, SCULPT_FACE_SETS_FROM_FACE_MAPS);
+ break;
+ }
+
+ SCULPT_undo_push_end();
+
+ /* Sync face sets visibility and vertex visibility as now all Face Sets are visible. */
+ SCULPT_visibility_sync_all_face_sets_to_vertices(ss);
+
+ for (int i = 0; i < totnode; i++) {
+ BKE_pbvh_node_mark_update_visibility(nodes[i]);
+ }
+
+ BKE_pbvh_update_vertex_data(ss->pbvh, PBVH_UpdateVisibility);
+
+ MEM_SAFE_FREE(nodes);
+
+ if (BKE_pbvh_type(pbvh) == PBVH_FACES) {
+ BKE_mesh_flush_hidden_from_verts(ob->data);
+ }
+
+ ED_region_tag_redraw(region);
+ DEG_id_tag_update(&ob->id, ID_RECALC_SHADING);
+
+ View3D *v3d = CTX_wm_view3d(C);
+ if (!BKE_sculptsession_use_pbvh_draw(ob, v3d)) {
+ DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
+ }
+
+ return OPERATOR_FINISHED;
+}
+
+static void SCULPT_OT_face_sets_init(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Init Face Sets";
+ ot->idname = "SCULPT_OT_face_sets_init";
+ ot->description = "Initializes all Face Sets in the mesh";
+
+ /* api callbacks */
+ ot->invoke = sculpt_face_set_init_invoke;
+ ot->poll = SCULPT_mode_poll;
+
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ RNA_def_enum(
+ ot->srna, "mode", prop_sculpt_face_sets_init_types, SCULPT_FACE_SET_MASKED, "Mode", "");
+ RNA_def_float(
+ ot->srna,
+ "threshold",
+ 0.5f,
+ 0.0f,
+ 1.0f,
+ "Threshold",
+ "Minimum value to consider a certain atribute a boundary when creating the Face Sets",
+ 0.0f,
+ 1.0f);
+}
+
typedef enum eSculptFaceGroupVisibilityModes {
SCULPT_FACE_SET_VISIBILITY_TOGGLE = 0,
SCULPT_FACE_SET_VISIBILITY_SHOW_ACTIVE = 1,
@@ -10996,19 +11702,25 @@ static int sculpt_face_sets_change_visibility_invoke(bContext *C,
if (mode == SCULPT_FACE_SET_VISIBILITY_TOGGLE) {
bool hidden_vertex = false;
- for (int i = 0; i < tot_vert; i++) {
- if (!SCULPT_vertex_visible_get(ss, i)) {
- hidden_vertex = true;
- break;
+
+ /* This can fail with regular meshes with non-manifold geometry as the visibility state can't
+ * be synced from face sets to non-manifold vertices. */
+ if (BKE_pbvh_type(ss->pbvh) == PBVH_GRIDS) {
+ for (int i = 0; i < tot_vert; i++) {
+ if (!SCULPT_vertex_visible_get(ss, i)) {
+ hidden_vertex = true;
+ break;
+ }
}
}
for (int i = 0; i < ss->totpoly; i++) {
- if (ss->face_sets[i] < 0) {
+ if (ss->face_sets[i] <= 0) {
hidden_vertex = true;
break;
}
}
+
if (hidden_vertex) {
SCULPT_face_sets_visibility_all_set(ss, true);
}
@@ -11179,4 +11891,5 @@ void ED_operatortypes_sculpt(void)
WM_operatortype_append(SCULPT_OT_face_sets_create);
WM_operatortype_append(SCULPT_OT_face_sets_change_visibility);
WM_operatortype_append(SCULPT_OT_face_sets_randomize_colors);
+ WM_operatortype_append(SCULPT_OT_face_sets_init);
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_cloth.c b/source/blender/editors/sculpt_paint/sculpt_cloth.c
index a1ccae7b5ab..b1cc6d02bbb 100644
--- a/source/blender/editors/sculpt_paint/sculpt_cloth.c
+++ b/source/blender/editors/sculpt_paint/sculpt_cloth.c
@@ -145,12 +145,11 @@ static void do_cloth_brush_build_constraints_task_cb_ex(
int tot_indices = 0;
build_indices[tot_indices] = vd.index;
tot_indices++;
- sculpt_vertex_neighbors_iter_begin(ss, vd.index, ni)
- {
+ SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.index, ni) {
build_indices[tot_indices] = ni.index;
tot_indices++;
}
- sculpt_vertex_neighbors_iter_end(ni);
+ SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
/* As we don't know the order of the neighbor vertices, we create all possible combinations
* between the neighbor and the original vertex as length constraints. */
@@ -446,7 +445,14 @@ static void cloth_brush_satisfy_constraints(SculptSession *ss,
const float constraint_distance = constraint->length +
(cloth_sim->length_constraint_tweak[v1] * 0.5f) +
(cloth_sim->length_constraint_tweak[v2] * 0.5f);
- mul_v3_v3fl(correction_vector, v1_to_v2, 1.0f - (constraint_distance / current_distance));
+
+ if (current_distance > 0.0f) {
+ mul_v3_v3fl(correction_vector, v1_to_v2, 1.0f - (constraint_distance / current_distance));
+ }
+ else {
+ copy_v3_v3(correction_vector, v1_to_v2);
+ }
+
mul_v3_v3fl(correction_vector_half, correction_vector, 0.5f);
const float mask_v1 = (1.0f - SCULPT_vertex_mask_get(ss, v1)) *
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index b8235dc5c95..fe56283dbcb 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -102,7 +102,7 @@ void SCULPT_vertex_neighbors_get(struct SculptSession *ss,
SculptVertexNeighborIter *iter);
/* Iterator over neighboring vertices. */
-#define sculpt_vertex_neighbors_iter_begin(ss, v_index, neighbor_iterator) \
+#define SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN(ss, v_index, neighbor_iterator) \
SCULPT_vertex_neighbors_get(ss, v_index, false, &neighbor_iterator); \
for (neighbor_iterator.i = 0; neighbor_iterator.i < neighbor_iterator.size; \
neighbor_iterator.i++) { \
@@ -110,7 +110,7 @@ void SCULPT_vertex_neighbors_get(struct SculptSession *ss,
/* Iterate over neighboring and duplicate vertices (for PBVH_GRIDS). Duplicates come
* first since they are nearest for floodfill. */
-#define sculpt_vertex_duplicates_and_neighbors_iter_begin(ss, v_index, neighbor_iterator) \
+#define SCULPT_VERTEX_DUPLICATES_AND_NEIGHBORS_ITER_BEGIN(ss, v_index, neighbor_iterator) \
SCULPT_vertex_neighbors_get(ss, v_index, true, &neighbor_iterator); \
for (neighbor_iterator.i = neighbor_iterator.size - 1; neighbor_iterator.i >= 0; \
neighbor_iterator.i--) { \
@@ -118,13 +118,16 @@ void SCULPT_vertex_neighbors_get(struct SculptSession *ss,
neighbor_iterator.is_duplicate = (ni.i >= \
neighbor_iterator.size - neighbor_iterator.num_duplicates);
-#define sculpt_vertex_neighbors_iter_end(neighbor_iterator) \
+#define SCULPT_VERTEX_NEIGHBORS_ITER_END(neighbor_iterator) \
} \
if (neighbor_iterator.neighbors != neighbor_iterator.neighbors_fixed) { \
MEM_freeN(neighbor_iterator.neighbors); \
} \
((void)0)
+int SCULPT_active_vertex_get(SculptSession *ss);
+const float *SCULPT_active_vertex_co_get(SculptSession *ss);
+
/* Sculpt Original Data */
typedef struct {
struct BMLog *bm_log;
@@ -143,6 +146,11 @@ typedef struct {
void SCULPT_orig_vert_data_init(SculptOrigVertData *data, Object *ob, PBVHNode *node);
void SCULPT_orig_vert_data_update(SculptOrigVertData *orig_data, PBVHVertexIter *iter);
+/* Face Sets */
+int SCULPT_vertex_face_set_get(SculptSession *ss, int index);
+bool SCULPT_vertex_has_face_set(SculptSession *ss, int index, int face_set);
+bool SCULPT_vertex_has_unique_face_set(SculptSession *ss, int index);
+
/* Dynamic topology */
void sculpt_pbvh_clear(Object *ob);
void sculpt_dyntopo_node_layers_add(struct SculptSession *ss);
@@ -196,6 +204,13 @@ void SCULPT_floodfill_add_active(struct Sculpt *sd,
struct SculptSession *ss,
SculptFloodFill *flood,
float radius);
+void SCULPT_floodfill_add_initial_with_symmetry(struct Sculpt *sd,
+ struct Object *ob,
+ struct SculptSession *ss,
+ SculptFloodFill *flood,
+ int index,
+ float radius);
+void sculpt_floodfill_add_initial(SculptFloodFill *flood, int index);
void SCULPT_floodfill_execute(
struct SculptSession *ss,
SculptFloodFill *flood,
@@ -441,6 +456,7 @@ typedef struct SculptThreadedTaskData {
/*************** Brush testing declarations ****************/
typedef struct SculptBrushTest {
float radius_squared;
+ float radius;
float location[3];
float dist;
int mirror_symmetry_pass;
@@ -517,7 +533,7 @@ bool SCULPT_pbvh_calc_area_normal(const struct Brush *brush,
* For descriptions of these settings, check the operator properties.
*/
-#define CLAY_STABILIZER_LEN 10
+#define SCULPT_CLAY_STABILIZER_LEN 10
typedef struct StrokeCache {
/* Invariants */
@@ -608,7 +624,7 @@ typedef struct StrokeCache {
/* Angle of the front tilting plane of the brush to simulate clay accumulation. */
float clay_thumb_front_angle;
/* Stores pressure samples to get an stabilized strength and radius variation. */
- float clay_pressure_stabilizer[CLAY_STABILIZER_LEN];
+ float clay_pressure_stabilizer[SCULPT_CLAY_STABILIZER_LEN];
int clay_pressure_stabilizer_index;
/* Cloth brush */
@@ -618,6 +634,10 @@ typedef struct StrokeCache {
float initial_normal[3];
float true_initial_normal[3];
+ /* Surface Smooth Brush */
+ /* Stores the displacement produced by the laplacian step of HC smooth. */
+ float (*surface_smooth_laplacian_disp)[3];
+
float vertex_rotation; /* amount to rotate the vertices when using rotate brush */
struct Dial *dial;
@@ -650,6 +670,11 @@ typedef struct FilterCache {
* achieve certain effects. */
int iteration_count;
+ /* Stores the displacement produced by the laplacian step of HC smooth. */
+ float (*surface_smooth_laplacian_disp)[3];
+ float surface_smooth_shape_preservation;
+ float surface_smooth_current_vertex;
+
/* unmasked nodes */
PBVHNode **nodes;
int totnode;
diff --git a/source/blender/editors/sculpt_paint/sculpt_pose.c b/source/blender/editors/sculpt_paint/sculpt_pose.c
index f1c884f9897..fde4a9d1d23 100644
--- a/source/blender/editors/sculpt_paint/sculpt_pose.c
+++ b/source/blender/editors/sculpt_paint/sculpt_pose.c
@@ -209,12 +209,11 @@ static void pose_brush_grow_factor_task_cb_ex(void *__restrict userdata,
float max = 0.0f;
/* Grow the factor. */
- sculpt_vertex_neighbors_iter_begin(ss, vd.index, ni)
- {
+ SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.index, ni) {
float vmask_f = data->prev_mask[ni.index];
max = MAX2(vmask_f, max);
}
- sculpt_vertex_neighbors_iter_end(ni);
+ SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
/* Keep the count of the vertices that where added to the factors in this grow iteration. */
if (max > data->prev_mask[vd.index]) {
@@ -352,9 +351,29 @@ typedef struct PoseFloodFillData {
float *pose_factor;
float pose_origin[3];
int tot_co;
+
+ int current_face_set;
+ int next_face_set;
+ int prev_face_set;
+ int next_vertex;
+
+ bool next_face_set_found;
+
+ /* Store the visited face sets to avoid going back when calculating the chain. */
+ GSet *visited_face_sets;
+
+ /* In face sets origin mode, each vertex can only be assigned to one face set. */
+ bool *is_weighted;
+
+ bool is_first_iteration;
+
+ /* Fallback origin. If we can't find any face set to continue, use the position of all vertices
+ * that have the current face set. */
+ float fallback_origin[3];
+ int fallback_count;
} PoseFloodFillData;
-static bool pose_floodfill_cb(
+static bool pose_topology_floodfill_cb(
SculptSession *ss, int UNUSED(from_v), int to_v, bool is_duplicate, void *userdata)
{
PoseFloodFillData *data = userdata;
@@ -378,6 +397,100 @@ static bool pose_floodfill_cb(
return false;
}
+static bool pose_face_sets_floodfill_cb(
+ SculptSession *ss, int UNUSED(from_v), int to_v, bool is_duplicate, void *userdata)
+{
+ PoseFloodFillData *data = userdata;
+
+ const int index = to_v;
+ bool visit_next = false;
+
+ const float *co = SCULPT_vertex_co_get(ss, index);
+ const bool symmetry_check = SCULPT_check_vertex_pivot_symmetry(
+ co, data->pose_initial_co, data->symm) &&
+ !is_duplicate;
+
+ /* First iteration. Continue expanding using topology until a vertex is outside the brush radius
+ * to determine the first face set. */
+ if (data->current_face_set == SCULPT_FACE_SET_NONE) {
+
+ data->pose_factor[index] = 1.0f;
+ data->is_weighted[index] = true;
+
+ if (sculpt_pose_brush_is_vertex_inside_brush_radius(
+ co, data->pose_initial_co, data->radius, data->symm)) {
+ const int visited_face_set = SCULPT_vertex_face_set_get(ss, index);
+ BLI_gset_add(data->visited_face_sets, POINTER_FROM_INT(visited_face_set));
+ }
+ else if (symmetry_check) {
+ data->current_face_set = SCULPT_vertex_face_set_get(ss, index);
+ BLI_gset_add(data->visited_face_sets, POINTER_FROM_INT(data->current_face_set));
+ }
+ return true;
+ }
+
+ /* We already have a current face set, so we can start checking the face sets of the vertices. */
+ /* In the first iteration we need to check all face sets we already visited as the flood fill may
+ * still not be finished in some of them. */
+ bool is_vertex_valid = false;
+ if (data->is_first_iteration) {
+ GSetIterator gs_iter;
+ GSET_ITER (gs_iter, data->visited_face_sets) {
+ const int visited_face_set = POINTER_AS_INT(BLI_gsetIterator_getKey(&gs_iter));
+ is_vertex_valid |= SCULPT_vertex_has_face_set(ss, index, visited_face_set);
+ }
+ }
+ else {
+ is_vertex_valid = SCULPT_vertex_has_face_set(ss, index, data->current_face_set);
+ }
+
+ if (is_vertex_valid) {
+
+ if (!data->is_weighted[index]) {
+ data->pose_factor[index] = 1.0f;
+ data->is_weighted[index] = true;
+ visit_next = true;
+ }
+
+ /* Fallback origin accumulation. */
+ if (symmetry_check) {
+ add_v3_v3(data->fallback_origin, SCULPT_vertex_co_get(ss, index));
+ data->fallback_count++;
+ }
+
+ if (symmetry_check && !SCULPT_vertex_has_unique_face_set(ss, index)) {
+
+ /* We only add coordinates for calculating the origin when it is possible to go from this
+ * vertex to another vertex in a valid face set for the next iteration. */
+ bool count_as_boundary = false;
+
+ SculptVertexNeighborIter ni;
+ SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, index, ni) {
+ int next_face_set_candidate = SCULPT_vertex_face_set_get(ss, ni.index);
+
+ /* Check if we can get a valid face set for the next iteration from this neighbor. */
+ if (SCULPT_vertex_has_unique_face_set(ss, ni.index) &&
+ !BLI_gset_haskey(data->visited_face_sets, POINTER_FROM_INT(next_face_set_candidate))) {
+ if (!data->next_face_set_found) {
+ data->next_face_set = next_face_set_candidate;
+ data->next_vertex = ni.index;
+ data->next_face_set_found = true;
+ }
+ count_as_boundary = true;
+ }
+ }
+ SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
+
+ /* Origin accumulation. */
+ if (count_as_boundary) {
+ add_v3_v3(data->pose_origin, SCULPT_vertex_co_get(ss, index));
+ data->tot_co++;
+ }
+ }
+ }
+ return visit_next;
+}
+
/* Public functions. */
/* Calculate the pose origin and (Optionaly the pose factor) that is used when using the pose brush
@@ -408,7 +521,7 @@ void SCULPT_pose_calc_pose_data(Sculpt *sd,
};
zero_v3(fdata.pose_origin);
copy_v3_v3(fdata.pose_initial_co, initial_location);
- SCULPT_floodfill_execute(ss, &flood, pose_floodfill_cb, &fdata);
+ SCULPT_floodfill_execute(ss, &flood, pose_topology_floodfill_cb, &fdata);
SCULPT_floodfill_free(&flood);
if (fdata.tot_co > 0) {
@@ -442,12 +555,11 @@ static void pose_brush_init_task_cb_ex(void *__restrict userdata,
SculptVertexNeighborIter ni;
float avg = 0.0f;
int total = 0;
- sculpt_vertex_neighbors_iter_begin(ss, vd.index, ni)
- {
+ SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.index, ni) {
avg += data->pose_factor[ni.index];
total++;
}
- sculpt_vertex_neighbors_iter_end(ni);
+ SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
if (total > 0) {
data->pose_factor[vd.index] = avg / total;
@@ -456,12 +568,47 @@ static void pose_brush_init_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_end;
}
-SculptPoseIKChain *SCULPT_pose_ik_chain_init(Sculpt *sd,
- Object *ob,
- SculptSession *ss,
- Brush *br,
- const float initial_location[3],
- const float radius)
+/* Init the IK chain with empty weights. */
+static SculptPoseIKChain *pose_ik_chain_new(const int totsegments, const int totverts)
+{
+ SculptPoseIKChain *ik_chain = MEM_callocN(sizeof(SculptPoseIKChain), "Pose IK Chain");
+ ik_chain->tot_segments = totsegments;
+ ik_chain->segments = MEM_callocN(totsegments * sizeof(SculptPoseIKChainSegment),
+ "Pose IK Chain Segments");
+ for (int i = 0; i < totsegments; i++) {
+ ik_chain->segments[i].weights = MEM_callocN(totverts * sizeof(float), "Pose IK weights");
+ }
+ return ik_chain;
+}
+
+/* Init the origin/head pairs of all the segments from the calculated origins. */
+static void pose_ik_chain_origin_heads_init(SculptPoseIKChain *ik_chain,
+ const float initial_location[3])
+{
+ float origin[3];
+ float head[3];
+ for (int i = 0; i < ik_chain->tot_segments; i++) {
+ if (i == 0) {
+ copy_v3_v3(head, initial_location);
+ copy_v3_v3(origin, ik_chain->segments[i].orig);
+ }
+ else {
+ copy_v3_v3(head, ik_chain->segments[i - 1].orig);
+ copy_v3_v3(origin, ik_chain->segments[i].orig);
+ }
+ copy_v3_v3(ik_chain->segments[i].orig, origin);
+ copy_v3_v3(ik_chain->segments[i].initial_orig, origin);
+ copy_v3_v3(ik_chain->segments[i].initial_head, head);
+ ik_chain->segments[i].len = len_v3v3(head, origin);
+ }
+}
+
+static SculptPoseIKChain *pose_ik_chain_init_topology(Sculpt *sd,
+ Object *ob,
+ SculptSession *ss,
+ Brush *br,
+ const float initial_location[3],
+ const float radius)
{
const float chain_segment_len = radius * (1.0f + br->pose_offset);
@@ -482,14 +629,7 @@ SculptPoseIKChain *SCULPT_pose_ik_chain_init(Sculpt *sd,
pose_factor_grow[nearest_vertex_index] = 1.0f;
- /* Init the IK chain with empty weights. */
- SculptPoseIKChain *ik_chain = MEM_callocN(sizeof(SculptPoseIKChain), "Pose IK Chain");
- ik_chain->tot_segments = br->pose_ik_segments;
- ik_chain->segments = MEM_callocN(ik_chain->tot_segments * sizeof(SculptPoseIKChainSegment),
- "Pose IK Chain Segments");
- for (int i = 0; i < br->pose_ik_segments; i++) {
- ik_chain->segments[i].weights = MEM_callocN(totvert * sizeof(float), "Pose IK weights");
- }
+ SculptPoseIKChain *ik_chain = pose_ik_chain_new(br->pose_ik_segments, totvert);
/* Calculate the first segment in the chain using the brush radius and the pose origin offset. */
copy_v3_v3(next_chain_segment_target, initial_location);
@@ -534,30 +674,102 @@ SculptPoseIKChain *SCULPT_pose_ik_chain_init(Sculpt *sd,
}
}
- /* Init the origin/head pairs of all the segments from the calculated origins. */
- float origin[3];
- float head[3];
- for (int i = 0; i < ik_chain->tot_segments; i++) {
- if (i == 0) {
- copy_v3_v3(head, initial_location);
- copy_v3_v3(origin, ik_chain->segments[i].orig);
+ pose_ik_chain_origin_heads_init(ik_chain, initial_location);
+
+ MEM_freeN(pose_factor_grow);
+ MEM_freeN(pose_factor_grow_prev);
+
+ return ik_chain;
+}
+
+static SculptPoseIKChain *pose_ik_chain_init_face_sets(
+ Sculpt *sd, Object *ob, SculptSession *ss, Brush *br, const float radius)
+{
+
+ int totvert = SCULPT_vertex_count_get(ss);
+
+ SculptPoseIKChain *ik_chain = pose_ik_chain_new(br->pose_ik_segments, totvert);
+
+ GSet *visited_face_sets = BLI_gset_int_new_ex("visited_face_sets", ik_chain->tot_segments);
+
+ bool *is_weighted = MEM_callocN(sizeof(bool) * totvert, "weighted");
+
+ int current_face_set = SCULPT_FACE_SET_NONE;
+ int prev_face_set = SCULPT_FACE_SET_NONE;
+
+ int current_vertex = SCULPT_active_vertex_get(ss);
+
+ for (int s = 0; s < ik_chain->tot_segments; s++) {
+
+ SculptFloodFill flood;
+ SCULPT_floodfill_init(ss, &flood);
+ SCULPT_floodfill_add_initial_with_symmetry(sd, ob, ss, &flood, current_vertex, FLT_MAX);
+
+ BLI_gset_add(visited_face_sets, POINTER_FROM_INT(current_face_set));
+
+ PoseFloodFillData fdata = {
+ .radius = radius,
+ .symm = sd->paint.symmetry_flags & PAINT_SYMM_AXIS_ALL,
+ .pose_factor = ik_chain->segments[s].weights,
+ .tot_co = 0,
+ .fallback_count = 0,
+ .current_face_set = current_face_set,
+ .prev_face_set = prev_face_set,
+ .visited_face_sets = visited_face_sets,
+ .is_weighted = is_weighted,
+ .next_face_set_found = false,
+ .is_first_iteration = s == 0,
+ };
+ zero_v3(fdata.pose_origin);
+ zero_v3(fdata.fallback_origin);
+ copy_v3_v3(fdata.pose_initial_co, SCULPT_vertex_co_get(ss, current_vertex));
+ SCULPT_floodfill_execute(ss, &flood, pose_face_sets_floodfill_cb, &fdata);
+ SCULPT_floodfill_free(&flood);
+
+ if (fdata.tot_co > 0) {
+ mul_v3_fl(fdata.pose_origin, 1.0f / (float)fdata.tot_co);
+ copy_v3_v3(ik_chain->segments[s].orig, fdata.pose_origin);
+ }
+ else if (fdata.fallback_count > 0) {
+ mul_v3_fl(fdata.fallback_origin, 1.0f / (float)fdata.fallback_count);
+ copy_v3_v3(ik_chain->segments[s].orig, fdata.fallback_origin);
}
else {
- copy_v3_v3(head, ik_chain->segments[i - 1].orig);
- copy_v3_v3(origin, ik_chain->segments[i].orig);
+ zero_v3(ik_chain->segments[s].orig);
}
- copy_v3_v3(ik_chain->segments[i].orig, origin);
- copy_v3_v3(ik_chain->segments[i].initial_orig, origin);
- copy_v3_v3(ik_chain->segments[i].initial_head, head);
- ik_chain->segments[i].len = len_v3v3(head, origin);
+
+ prev_face_set = fdata.current_face_set;
+ current_face_set = fdata.next_face_set;
+ current_vertex = fdata.next_vertex;
}
- MEM_freeN(pose_factor_grow);
- MEM_freeN(pose_factor_grow_prev);
+ BLI_gset_free(visited_face_sets, NULL);
+
+ pose_ik_chain_origin_heads_init(ik_chain, SCULPT_active_vertex_co_get(ss));
+
+ MEM_SAFE_FREE(is_weighted);
return ik_chain;
}
+SculptPoseIKChain *SCULPT_pose_ik_chain_init(Sculpt *sd,
+ Object *ob,
+ SculptSession *ss,
+ Brush *br,
+ const float initial_location[3],
+ const float radius)
+{
+ switch (br->pose_origin_type) {
+ case BRUSH_POSE_ORIGIN_TOPOLOGY:
+ return pose_ik_chain_init_topology(sd, ob, ss, br, initial_location, radius);
+ break;
+ case BRUSH_POSE_ORIGIN_FACE_SETS:
+ return pose_ik_chain_init_face_sets(sd, ob, ss, br, radius);
+ break;
+ }
+ return NULL;
+}
+
void SCULPT_pose_brush_init(Sculpt *sd, Object *ob, SculptSession *ss, Brush *br)
{
PBVHNode **nodes;
diff --git a/source/blender/editors/space_clip/clip_intern.h b/source/blender/editors/space_clip/clip_intern.h
index b66f7605f41..4dc8d367f2b 100644
--- a/source/blender/editors/space_clip/clip_intern.h
+++ b/source/blender/editors/space_clip/clip_intern.h
@@ -178,7 +178,7 @@ void clip_draw_sfra_efra(struct View2D *v2d, struct Scene *scene);
/* tracking_ops.c */
struct MovieTrackingTrack *tracking_marker_check_slide(
- struct bContext *C, const struct wmEvent *event, int *area_r, int *action_r, int *corner_r);
+ struct bContext *C, const struct wmEvent *event, int *r_area, int *r_action, int *r_corner);
void CLIP_OT_add_marker(struct wmOperatorType *ot);
void CLIP_OT_add_marker_at_click(struct wmOperatorType *ot);
diff --git a/source/blender/editors/space_clip/clip_ops.c b/source/blender/editors/space_clip/clip_ops.c
index efc8c3bb7dd..4e5c6513695 100644
--- a/source/blender/editors/space_clip/clip_ops.c
+++ b/source/blender/editors/space_clip/clip_ops.c
@@ -1315,8 +1315,8 @@ typedef struct ProxyThread {
static unsigned char *proxy_thread_next_frame(ProxyQueue *queue,
MovieClip *clip,
- size_t *size_r,
- int *cfra_r)
+ size_t *r_size,
+ int *r_cfra)
{
unsigned char *mem = NULL;
@@ -1353,8 +1353,8 @@ static unsigned char *proxy_thread_next_frame(ProxyQueue *queue,
return NULL;
}
- *size_r = size;
- *cfra_r = queue->cfra;
+ *r_size = size;
+ *r_cfra = queue->cfra;
queue->cfra++;
close(file);
diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c
index a273487eee9..4b9c872ffce 100644
--- a/source/blender/editors/space_clip/space_clip.c
+++ b/source/blender/editors/space_clip/space_clip.c
@@ -605,7 +605,7 @@ static int clip_context(const bContext *C, const char *member, bContextDataResul
static bool clip_drop_poll(bContext *UNUSED(C),
wmDrag *drag,
const wmEvent *UNUSED(event),
- const char **UNUSED(tooltip))
+ const char **UNUSED(r_tooltip))
{
if (drag->type == WM_DRAG_PATH) {
/* rule might not work? */
diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c
index f88f6113b54..739701b5595 100644
--- a/source/blender/editors/space_clip/tracking_ops.c
+++ b/source/blender/editors/space_clip/tracking_ops.c
@@ -544,7 +544,7 @@ static bool slide_check_corners(float (*corners)[2])
}
MovieTrackingTrack *tracking_marker_check_slide(
- bContext *C, const wmEvent *event, int *area_r, int *action_r, int *corner_r)
+ bContext *C, const wmEvent *event, int *r_area, int *r_action, int *r_corner)
{
const float distance_clip_squared = 12.0f * 12.0f;
SpaceClip *sc = CTX_wm_space_clip(C);
@@ -657,14 +657,14 @@ MovieTrackingTrack *tracking_marker_check_slide(
}
if (global_min_distance_squared < distance_clip_squared / sc->zoom) {
- if (area_r) {
- *area_r = min_area;
+ if (r_area) {
+ *r_area = min_area;
}
- if (action_r) {
- *action_r = min_action;
+ if (r_action) {
+ *r_action = min_action;
}
- if (corner_r) {
- *corner_r = min_corner;
+ if (r_corner) {
+ *r_corner = min_corner;
}
return min_track;
}
diff --git a/source/blender/editors/space_clip/tracking_ops_plane.c b/source/blender/editors/space_clip/tracking_ops_plane.c
index 0cf0e85929c..3c5646911a3 100644
--- a/source/blender/editors/space_clip/tracking_ops_plane.c
+++ b/source/blender/editors/space_clip/tracking_ops_plane.c
@@ -122,7 +122,7 @@ static float mouse_to_plane_slide_zone_distance_squared(const float co[2],
static MovieTrackingPlaneTrack *tracking_plane_marker_check_slide(bContext *C,
const wmEvent *event,
- int *corner_r)
+ int *r_corner)
{
const float distance_clip_squared = 12.0f * 12.0f;
SpaceClip *sc = CTX_wm_space_clip(C);
@@ -162,8 +162,8 @@ static MovieTrackingPlaneTrack *tracking_plane_marker_check_slide(bContext *C,
}
if (min_distance_squared < distance_clip_squared / sc->zoom) {
- if (corner_r != NULL) {
- *corner_r = min_corner;
+ if (r_corner != NULL) {
+ *r_corner = min_corner;
}
return min_plane_track;
}
diff --git a/source/blender/editors/space_clip/tracking_ops_track.c b/source/blender/editors/space_clip/tracking_ops_track.c
index c14895f8483..05623347366 100644
--- a/source/blender/editors/space_clip/tracking_ops_track.c
+++ b/source/blender/editors/space_clip/tracking_ops_track.c
@@ -86,7 +86,7 @@ static int track_count_markers(SpaceClip *sc, MovieClip *clip, int framenr)
return tot;
}
-static void track_init_markers(SpaceClip *sc, MovieClip *clip, int framenr, int *frames_limit_r)
+static void track_init_markers(SpaceClip *sc, MovieClip *clip, int framenr, int *r_frames_limit)
{
ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking);
int frames_limit = 0;
@@ -109,7 +109,7 @@ static void track_init_markers(SpaceClip *sc, MovieClip *clip, int framenr, int
}
}
}
- *frames_limit_r = frames_limit;
+ *r_frames_limit = frames_limit;
}
static bool track_markers_check_direction(int backwards, int curfra, int efra)
diff --git a/source/blender/editors/space_clip/tracking_select.c b/source/blender/editors/space_clip/tracking_select.c
index 2166cff4883..67c453825f7 100644
--- a/source/blender/editors/space_clip/tracking_select.c
+++ b/source/blender/editors/space_clip/tracking_select.c
@@ -52,7 +52,7 @@
#include "clip_intern.h" /* own include */
#include "tracking_ops_intern.h" /* own include */
-static float dist_to_crns(float co[2], float pos[2], float crns[4][2]);
+static float dist_to_crns(const float co[2], const float pos[2], const float crns[4][2]);
/********************** mouse select operator *********************/
@@ -70,8 +70,12 @@ static int mouse_on_side(
return (co[0] >= x1 - epsx && co[0] <= x2 + epsx) && (co[1] >= y1 - epsy && co[1] <= y2 + epsy);
}
-static int mouse_on_rect(
- const float co[2], float pos[2], float min[2], float max[2], float epsx, float epsy)
+static int mouse_on_rect(const float co[2],
+ const float pos[2],
+ const float min[2],
+ const float max[2],
+ float epsx,
+ float epsy)
{
return mouse_on_side(
co, pos[0] + min[0], pos[1] + min[1], pos[0] + max[0], pos[1] + min[1], epsx, epsy) ||
@@ -83,14 +87,15 @@ static int mouse_on_rect(
co, pos[0] + max[0], pos[1] + min[1], pos[0] + max[0], pos[1] + max[1], epsx, epsy);
}
-static int mouse_on_crns(float co[2], float pos[2], float crns[4][2], float epsx, float epsy)
+static int mouse_on_crns(
+ const float co[2], const float pos[2], const float crns[4][2], float epsx, float epsy)
{
float dist = dist_to_crns(co, pos, crns);
return dist < max_ff(epsx, epsy);
}
-static int track_mouse_area(const bContext *C, float co[2], MovieTrackingTrack *track)
+static int track_mouse_area(const bContext *C, const float co[2], MovieTrackingTrack *track)
{
SpaceClip *sc = CTX_wm_space_clip(C);
int framenr = ED_space_clip_get_clip_frame_number(sc);
@@ -142,7 +147,10 @@ static int track_mouse_area(const bContext *C, float co[2], MovieTrackingTrack *
return TRACK_AREA_NONE;
}
-static float dist_to_rect(float co[2], float pos[2], float min[2], float max[2])
+static float dist_to_rect(const float co[2],
+ const float pos[2],
+ const float min[2],
+ const float max[2])
{
float d1, d2, d3, d4;
float p[2] = {co[0] - pos[0], co[1] - pos[1]};
@@ -158,7 +166,7 @@ static float dist_to_rect(float co[2], float pos[2], float min[2], float max[2])
}
/* Distance to quad defined by it's corners, corners are relative to pos */
-static float dist_to_crns(float co[2], float pos[2], float crns[4][2])
+static float dist_to_crns(const float co[2], const float pos[2], const float crns[4][2])
{
float d1, d2, d3, d4;
float p[2] = {co[0] - pos[0], co[1] - pos[1]};
@@ -174,7 +182,7 @@ static float dist_to_crns(float co[2], float pos[2], float crns[4][2])
}
/* Same as above, but all the coordinates are absolute */
-static float dist_to_crns_abs(float co[2], float corners[4][2])
+static float dist_to_crns_abs(const float co[2], const float corners[4][2])
{
float d1, d2, d3, d4;
const float *v1 = corners[0], *v2 = corners[1];
@@ -190,8 +198,8 @@ static float dist_to_crns_abs(float co[2], float corners[4][2])
static MovieTrackingTrack *find_nearest_track(SpaceClip *sc,
ListBase *tracksbase,
- float co[2],
- float *distance_r)
+ const float co[2],
+ float *r_distance)
{
MovieTrackingTrack *track = NULL, *cur;
float mindist = 0.0f;
@@ -231,15 +239,15 @@ static MovieTrackingTrack *find_nearest_track(SpaceClip *sc,
cur = cur->next;
}
- *distance_r = mindist;
+ *r_distance = mindist;
return track;
}
static MovieTrackingPlaneTrack *find_nearest_plane_track(SpaceClip *sc,
ListBase *plane_tracks_base,
- float co[2],
- float *distance_r)
+ const float co[2],
+ float *r_distance)
{
MovieTrackingPlaneTrack *plane_track = NULL, *current_plane_track;
float min_distance = 0.0f;
@@ -259,7 +267,7 @@ static MovieTrackingPlaneTrack *find_nearest_plane_track(SpaceClip *sc,
}
}
- *distance_r = min_distance;
+ *r_distance = min_distance;
return plane_track;
}
@@ -281,7 +289,7 @@ void ed_tracking_deselect_all_plane_tracks(ListBase *plane_tracks_base)
}
}
-static int mouse_select(bContext *C, float co[2], const bool extend, const bool deselect_all)
+static int mouse_select(bContext *C, const float co[2], const bool extend, const bool deselect_all)
{
SpaceClip *sc = CTX_wm_space_clip(C);
MovieClip *clip = ED_space_clip_get_clip(sc);
diff --git a/source/blender/editors/space_file/file_intern.h b/source/blender/editors/space_file/file_intern.h
index 6ef35132087..b7e8d35ffee 100644
--- a/source/blender/editors/space_file/file_intern.h
+++ b/source/blender/editors/space_file/file_intern.h
@@ -75,14 +75,6 @@ void FILE_OT_smoothscroll(struct wmOperatorType *ot);
void FILE_OT_filepath_drop(struct wmOperatorType *ot);
void FILE_OT_start_filter(struct wmOperatorType *ot);
-int file_exec(bContext *C, struct wmOperator *exec_op);
-int file_cancel_exec(bContext *C, struct wmOperator *unused);
-int file_parent_exec(bContext *C, struct wmOperator *unused);
-int file_previous_exec(bContext *C, struct wmOperator *unused);
-int file_next_exec(bContext *C, struct wmOperator *unused);
-int file_directory_new_exec(bContext *C, struct wmOperator *unused);
-int file_delete_exec(bContext *C, struct wmOperator *unused);
-
void file_directory_enter_handle(bContext *C, void *arg_unused, void *arg_but);
void file_filename_enter_handle(bContext *C, void *arg_unused, void *arg_but);
diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c
index c17ca31a7df..5258892d55d 100644
--- a/source/blender/editors/space_file/file_ops.c
+++ b/source/blender/editors/space_file/file_ops.c
@@ -68,7 +68,10 @@
#include <stdlib.h>
#include <string.h>
-/* ---------- FILE SELECTION ------------ */
+/* -------------------------------------------------------------------- */
+/** \name File Selection Utilities
+ * \{ */
+
static FileSelection find_file_mouse_rect(SpaceFile *sfile,
ARegion *region,
const rcti *rect_region)
@@ -344,6 +347,12 @@ static FileSelect file_select(
return retval;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Box Select Operator
+ * \{ */
+
static int file_box_select_find_last_selected(SpaceFile *sfile,
ARegion *region,
const FileSelection *sel,
@@ -484,6 +493,12 @@ void FILE_OT_select_box(wmOperatorType *ot)
WM_operator_properties_select_operation_simple(ot);
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select Pick Operator
+ * \{ */
+
static int file_select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ARegion *region = CTX_wm_region(C);
@@ -577,6 +592,12 @@ void FILE_OT_select(wmOperatorType *ot)
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select Walk Operator
+ * \{ */
+
/**
* \returns true if selection has changed
*/
@@ -822,6 +843,12 @@ void FILE_OT_select_walk(wmOperatorType *ot)
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select All Operator
+ * \{ */
+
static int file_select_all_exec(bContext *C, wmOperator *op)
{
ScrArea *sa = CTX_wm_area(C);
@@ -893,7 +920,11 @@ void FILE_OT_select_all(wmOperatorType *ot)
WM_operator_properties_select_all(ot);
}
-/* ---------- BOOKMARKS ----------- */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select Bookmark Operator
+ * \{ */
/* Note we could get rid of this one, but it's used by some addon so...
* Does not hurt keeping it around for now. */
@@ -936,6 +967,12 @@ void FILE_OT_select_bookmark(wmOperatorType *ot)
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Add Bookmark Operator
+ * \{ */
+
static int bookmark_add_exec(bContext *C, wmOperator *UNUSED(op))
{
ScrArea *sa = CTX_wm_area(C);
@@ -972,6 +1009,12 @@ void FILE_OT_bookmark_add(wmOperatorType *ot)
ot->poll = ED_operator_file_active;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Delete Bookmark Operator
+ * \{ */
+
static int bookmark_delete_exec(bContext *C, wmOperator *op)
{
ScrArea *sa = CTX_wm_area(C);
@@ -1024,6 +1067,12 @@ void FILE_OT_bookmark_delete(wmOperatorType *ot)
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Cleanup Bookmark Operator
+ * \{ */
+
static int bookmark_cleanup_exec(bContext *C, wmOperator *UNUSED(op))
{
ScrArea *sa = CTX_wm_area(C);
@@ -1074,6 +1123,12 @@ void FILE_OT_bookmark_cleanup(wmOperatorType *ot)
/* properties */
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Reorder Bookmark Operator
+ * \{ */
+
enum {
FILE_BOOKMARK_MOVE_TOP = -2,
FILE_BOOKMARK_MOVE_UP = -1,
@@ -1165,6 +1220,12 @@ void FILE_OT_bookmark_move(wmOperatorType *ot)
"Direction to move the active bookmark towards");
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Reset Recent Blend Files Operator
+ * \{ */
+
static int reset_recent_exec(bContext *C, wmOperator *UNUSED(op))
{
ScrArea *sa = CTX_wm_area(C);
@@ -1196,6 +1257,12 @@ void FILE_OT_reset_recent(wmOperatorType *ot)
ot->poll = ED_operator_file_active;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Highlight File Operator
+ * \{ */
+
int file_highlight_set(SpaceFile *sfile, ARegion *region, int mx, int my)
{
View2D *v2d = &region->v2d;
@@ -1263,6 +1330,12 @@ void FILE_OT_highlight(struct wmOperatorType *ot)
ot->poll = ED_operator_file_active;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Sort from Column Operator
+ * \{ */
+
static int file_column_sort_ui_context_invoke(bContext *C,
wmOperator *UNUSED(op),
const wmEvent *event)
@@ -1310,18 +1383,11 @@ void FILE_OT_sort_column_ui_context(wmOperatorType *ot)
ot->flag = OPTYPE_INTERNAL;
}
-int file_cancel_exec(bContext *C, wmOperator *UNUSED(unused))
-{
- wmWindowManager *wm = CTX_wm_manager(C);
- SpaceFile *sfile = CTX_wm_space_file(C);
- wmOperator *op = sfile->op;
-
- sfile->op = NULL;
-
- WM_event_fileselect_event(wm, op, EVT_FILESELECT_CANCEL);
+/** \} */
- return OPERATOR_FINISHED;
-}
+/* -------------------------------------------------------------------- */
+/** \name Cancel File Selector Operator
+ * \{ */
static bool file_operator_poll(bContext *C)
{
@@ -1335,6 +1401,19 @@ static bool file_operator_poll(bContext *C)
return poll;
}
+static int file_cancel_exec(bContext *C, wmOperator *UNUSED(unused))
+{
+ wmWindowManager *wm = CTX_wm_manager(C);
+ SpaceFile *sfile = CTX_wm_space_file(C);
+ wmOperator *op = sfile->op;
+
+ sfile->op = NULL;
+
+ WM_event_fileselect_event(wm, op, EVT_FILESELECT_CANCEL);
+
+ return OPERATOR_FINISHED;
+}
+
void FILE_OT_cancel(struct wmOperatorType *ot)
{
/* identifiers */
@@ -1347,6 +1426,12 @@ void FILE_OT_cancel(struct wmOperatorType *ot)
ot->poll = file_operator_poll;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Operator Utilities
+ * \{ */
+
void file_sfile_to_operator_ex(bContext *C, wmOperator *op, SpaceFile *sfile, char *filepath)
{
Main *bmain = CTX_data_main(C);
@@ -1521,7 +1606,13 @@ bool file_draw_check_exists(SpaceFile *sfile)
return false;
}
-int file_exec(bContext *C, wmOperator *exec_op)
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Execute File Window Operator
+ * \{ */
+
+static int file_exec(bContext *C, wmOperator *exec_op)
{
Main *bmain = CTX_data_main(C);
wmWindowManager *wm = CTX_wm_manager(C);
@@ -1543,7 +1634,9 @@ int file_exec(bContext *C, wmOperator *exec_op)
BLI_path_append(sfile->params->dir, sizeof(sfile->params->dir) - 1, file->relpath);
BLI_add_slash(sfile->params->dir);
}
-
+ if (file->redirection_path) {
+ STRNCPY(sfile->params->dir, file->redirection_path);
+ }
ED_file_change_dir(C);
}
/* opening file - sends events now, so things get handled on windowqueue level */
@@ -1612,7 +1705,50 @@ void FILE_OT_execute(struct wmOperatorType *ot)
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
-int file_parent_exec(bContext *C, wmOperator *UNUSED(unused))
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Refresh File List Operator
+ * \{ */
+
+static int file_refresh_exec(bContext *C, wmOperator *UNUSED(unused))
+{
+ wmWindowManager *wm = CTX_wm_manager(C);
+ SpaceFile *sfile = CTX_wm_space_file(C);
+ struct FSMenu *fsmenu = ED_fsmenu_get();
+
+ ED_fileselect_clear(wm, CTX_data_scene(C), sfile);
+
+ /* refresh system directory menu */
+ fsmenu_refresh_system_category(fsmenu);
+
+ /* Update bookmarks 'valid' state. */
+ fsmenu_refresh_bookmarks_status(wm, fsmenu);
+
+ WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+void FILE_OT_refresh(struct wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Refresh Filelist";
+ ot->description = "Refresh the file list";
+ ot->idname = "FILE_OT_refresh";
+
+ /* api callbacks */
+ ot->exec = file_refresh_exec;
+ ot->poll = ED_operator_file_active; /* <- important, handler is on window level */
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Navigate Parent Operator
+ * \{ */
+
+static int file_parent_exec(bContext *C, wmOperator *UNUSED(unused))
{
Main *bmain = CTX_data_main(C);
SpaceFile *sfile = CTX_wm_space_file(C);
@@ -1645,20 +1781,27 @@ void FILE_OT_parent(struct wmOperatorType *ot)
ot->poll = ED_operator_file_active; /* <- important, handler is on window level */
}
-static int file_refresh_exec(bContext *C, wmOperator *UNUSED(unused))
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Navigate Previous Operator
+ * \{ */
+
+static int file_previous_exec(bContext *C, wmOperator *UNUSED(op))
{
- wmWindowManager *wm = CTX_wm_manager(C);
SpaceFile *sfile = CTX_wm_space_file(C);
- struct FSMenu *fsmenu = ED_fsmenu_get();
- ED_fileselect_clear(wm, CTX_data_scene(C), sfile);
-
- /* refresh system directory menu */
- fsmenu_refresh_system_category(fsmenu);
+ if (sfile->params) {
+ if (!sfile->folders_next) {
+ sfile->folders_next = folderlist_new();
+ }
- /* Update bookmarks 'valid' state. */
- fsmenu_refresh_bookmarks_status(wm, fsmenu);
+ folderlist_pushdir(sfile->folders_next, sfile->params->dir);
+ folderlist_popdir(sfile->folders_prev, sfile->params->dir);
+ folderlist_pushdir(sfile->folders_next, sfile->params->dir);
+ ED_file_change_dir(C);
+ }
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
return OPERATOR_FINISHED;
@@ -1676,18 +1819,25 @@ void FILE_OT_previous(struct wmOperatorType *ot)
ot->poll = ED_operator_file_active; /* <- important, handler is on window level */
}
-int file_previous_exec(bContext *C, wmOperator *UNUSED(unused))
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Navigate Next Operator
+ * \{ */
+
+static int file_next_exec(bContext *C, wmOperator *UNUSED(unused))
{
SpaceFile *sfile = CTX_wm_space_file(C);
-
if (sfile->params) {
if (!sfile->folders_next) {
sfile->folders_next = folderlist_new();
}
- folderlist_pushdir(sfile->folders_next, sfile->params->dir);
- folderlist_popdir(sfile->folders_prev, sfile->params->dir);
- folderlist_pushdir(sfile->folders_next, sfile->params->dir);
+ folderlist_pushdir(sfile->folders_prev, sfile->params->dir);
+ folderlist_popdir(sfile->folders_next, sfile->params->dir);
+
+ // update folders_prev so we can check for it in folderlist_clear_next()
+ folderlist_pushdir(sfile->folders_prev, sfile->params->dir);
ED_file_change_dir(C);
}
@@ -1708,26 +1858,11 @@ void FILE_OT_next(struct wmOperatorType *ot)
ot->poll = ED_operator_file_active; /* <- important, handler is on window level */
}
-int file_next_exec(bContext *C, wmOperator *UNUSED(unused))
-{
- SpaceFile *sfile = CTX_wm_space_file(C);
- if (sfile->params) {
- if (!sfile->folders_next) {
- sfile->folders_next = folderlist_new();
- }
-
- folderlist_pushdir(sfile->folders_prev, sfile->params->dir);
- folderlist_popdir(sfile->folders_next, sfile->params->dir);
-
- // update folders_prev so we can check for it in folderlist_clear_next()
- folderlist_pushdir(sfile->folders_prev, sfile->params->dir);
-
- ED_file_change_dir(C);
- }
- WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
+/** \} */
- return OPERATOR_FINISHED;
-}
+/* -------------------------------------------------------------------- */
+/** \name Smooth Scroll Operator
+ * \{ */
/* only meant for timer usage */
static int file_smoothscroll_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
@@ -1916,6 +2051,12 @@ void FILE_OT_smoothscroll(wmOperatorType *ot)
ot->poll = ED_operator_file_active;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name File Selector Drop Operator
+ * \{ */
+
static int filepath_drop_exec(bContext *C, wmOperator *op)
{
SpaceFile *sfile = CTX_wm_space_file(C);
@@ -1954,6 +2095,12 @@ void FILE_OT_filepath_drop(wmOperatorType *ot)
RNA_def_string_file_path(ot->srna, "filepath", "Path", FILE_MAX, "", "");
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name New Directory Operator
+ * \{ */
+
/**
* Create a new, non-existing folder name, returns 1 if successful, 0 if name couldn't be created.
* The actual name is returned in 'name', 'folder' contains the complete path,
@@ -1978,7 +2125,7 @@ static int new_folder_path(const char *parent, char *folder, char *name)
return (len < FILE_MAXFILE);
}
-int file_directory_new_exec(bContext *C, wmOperator *op)
+static int file_directory_new_exec(bContext *C, wmOperator *op)
{
char name[FILE_MAXFILE];
char path[FILE_MAX];
@@ -2085,6 +2232,12 @@ void FILE_OT_directory_new(struct wmOperatorType *ot)
WM_operator_properties_confirm_or_exec(ot);
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Refresh File List Operator
+ * \{ */
+
/* TODO This should go to BLI_path_utils. */
static void file_expand_directory(bContext *C)
{
@@ -2284,17 +2437,11 @@ void file_filename_enter_handle(bContext *C, void *UNUSED(arg_unused), void *arg
}
}
-void FILE_OT_refresh(struct wmOperatorType *ot)
-{
- /* identifiers */
- ot->name = "Refresh Filelist";
- ot->description = "Refresh the file list";
- ot->idname = "FILE_OT_refresh";
+/** \} */
- /* api callbacks */
- ot->exec = file_refresh_exec;
- ot->poll = ED_operator_file_active; /* <- important, handler is on window level */
-}
+/* -------------------------------------------------------------------- */
+/** \name Toggle Show Hidden Files Operator
+ * \{ */
static int file_hidedot_exec(bContext *C, wmOperator *UNUSED(unused))
{
@@ -2322,6 +2469,12 @@ void FILE_OT_hidedot(struct wmOperatorType *ot)
ot->poll = ED_operator_file_active; /* <- important, handler is on window level */
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Increment Filename Operator
+ * \{ */
+
static bool file_filenum_poll(bContext *C)
{
SpaceFile *sfile = CTX_wm_space_file(C);
@@ -2396,6 +2549,12 @@ void FILE_OT_filenum(struct wmOperatorType *ot)
RNA_def_int(ot->srna, "increment", 1, -100, 100, "Increment", "", -100, 100);
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Rename File/Directory Operator
+ * \{ */
+
static void file_rename_state_activate(SpaceFile *sfile, int file_idx, bool require_selected)
{
const int numfiles = filelist_files_ensure(sfile->files);
@@ -2454,6 +2613,12 @@ void FILE_OT_rename(struct wmOperatorType *ot)
ot->poll = ED_operator_file_active;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Delete File Operator
+ * \{ */
+
static bool file_delete_poll(bContext *C)
{
bool poll = ED_operator_file_active(C);
@@ -2484,7 +2649,7 @@ static bool file_delete_poll(bContext *C)
return poll;
}
-int file_delete_exec(bContext *C, wmOperator *op)
+static int file_delete_exec(bContext *C, wmOperator *op)
{
wmWindowManager *wm = CTX_wm_manager(C);
SpaceFile *sfile = CTX_wm_space_file(C);
@@ -2535,6 +2700,12 @@ void FILE_OT_delete(struct wmOperatorType *ot)
ot->poll = file_delete_poll; /* <- important, handler is on window level */
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Enter Filter Text Operator
+ * \{ */
+
static int file_start_filter_exec(bContext *C, wmOperator *UNUSED(op))
{
ScrArea *sa = CTX_wm_area(C);
@@ -2557,6 +2728,12 @@ void FILE_OT_start_filter(struct wmOperatorType *ot)
ot->poll = ED_operator_file_active;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Macro Operators
+ * \{ */
+
void ED_operatormacros_file(void)
{
// wmOperatorType *ot;
@@ -2564,3 +2741,5 @@ void ED_operatormacros_file(void)
/* future macros */
}
+
+/** \} */
diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c
index cb062cc212a..dec38501d38 100644
--- a/source/blender/editors/space_file/filelist.c
+++ b/source/blender/editors/space_file/filelist.c
@@ -210,12 +210,13 @@ typedef struct FileListInternEntry {
int blentype;
char *relpath;
+ /** Optional argument for shortcuts, aliases etc. */
+ char *redirection_path;
/** not strictly needed, but used during sorting, avoids to have to recompute it there... */
char *name;
/** Defined in BLI_fileops.h */
eFileAttributes attributes;
-
BLI_stat_t st;
} FileListInternEntry;
@@ -961,12 +962,12 @@ ImBuf *filelist_getimage(struct FileList *filelist, const int index)
return file->image;
}
-static ImBuf *filelist_geticon_image_ex(const unsigned int typeflag, const char *relpath)
+static ImBuf *filelist_geticon_image_ex(FileDirEntry *file)
{
ImBuf *ibuf = NULL;
- if (typeflag & FILE_TYPE_DIR) {
- if (FILENAME_IS_PARENT(relpath)) {
+ if (file->typeflag & FILE_TYPE_DIR) {
+ if (FILENAME_IS_PARENT(file->relpath)) {
ibuf = gSpecialFileImages[SPECIAL_IMG_PARENT];
}
else {
@@ -983,8 +984,7 @@ static ImBuf *filelist_geticon_image_ex(const unsigned int typeflag, const char
ImBuf *filelist_geticon_image(struct FileList *filelist, const int index)
{
FileDirEntry *file = filelist_geticon_get_file(filelist, index);
-
- return filelist_geticon_image_ex(file->typeflag, file->relpath);
+ return filelist_geticon_image_ex(file);
}
static int filelist_geticon_ex(FileDirEntry *file,
@@ -1170,6 +1170,9 @@ static void filelist_entry_clear(FileDirEntry *entry)
if (entry->relpath) {
MEM_freeN(entry->relpath);
}
+ if (entry->redirection_path) {
+ MEM_freeN(entry->redirection_path);
+ }
if (entry->image) {
IMB_freeImBuf(entry->image);
}
@@ -1239,6 +1242,9 @@ static void filelist_intern_entry_free(FileListInternEntry *entry)
if (entry->relpath) {
MEM_freeN(entry->relpath);
}
+ if (entry->redirection_path) {
+ MEM_freeN(entry->redirection_path);
+ }
if (entry->name) {
MEM_freeN(entry->name);
}
@@ -1690,6 +1696,9 @@ static FileDirEntry *filelist_file_create_entry(FileList *filelist, const int in
ret->blentype = entry->blentype;
ret->typeflag = entry->typeflag;
ret->attributes = entry->attributes;
+ if (entry->redirection_path) {
+ ret->redirection_path = BLI_strdup(entry->redirection_path);
+ }
BLI_addtail(&cache->cached_entries, ret);
return ret;
}
@@ -2436,9 +2445,9 @@ void filelist_entry_parent_select_set(FileList *filelist,
}
/* WARNING! dir must be FILE_MAX_LIBEXTRA long! */
-bool filelist_islibrary(struct FileList *filelist, char *dir, char **group)
+bool filelist_islibrary(struct FileList *filelist, char *dir, char **r_group)
{
- return BLO_library_path_explode(filelist->filelist.root, dir, group, NULL);
+ return BLO_library_path_explode(filelist->filelist.root, dir, r_group, NULL);
}
static int groupname_to_code(const char *group)
@@ -2523,6 +2532,16 @@ static int filelist_readjob_list_dir(const char *root,
/* Set file attributes. */
entry->attributes = BLI_file_attributes(path);
+ if (entry->attributes & FILE_ATTR_ALIAS) {
+ entry->redirection_path = MEM_callocN(FILE_MAXDIR, __func__);
+ if (BLI_file_alias_target(entry->redirection_path, path)) {
+ if (BLI_is_dir(entry->redirection_path)) {
+ entry->typeflag = FILE_TYPE_DIR;
+ }
+ else
+ entry->typeflag = ED_path_extension_type(entry->redirection_path);
+ }
+ }
#ifndef WIN32
/* Set linux-style dot files hidden too. */
diff --git a/source/blender/editors/space_file/filelist.h b/source/blender/editors/space_file/filelist.h
index e39594bf1da..e90a8659417 100644
--- a/source/blender/editors/space_file/filelist.h
+++ b/source/blender/editors/space_file/filelist.h
@@ -125,7 +125,7 @@ void filelist_entry_parent_select_set(struct FileList *filelist,
void filelist_setrecursion(struct FileList *filelist, const int recursion_level);
struct BlendHandle *filelist_lib(struct FileList *filelist);
-bool filelist_islibrary(struct FileList *filelist, char *dir, char **group);
+bool filelist_islibrary(struct FileList *filelist, char *dir, char **r_group);
void filelist_freelib(struct FileList *filelist);
void filelist_readjob_start(struct FileList *filelist, const struct bContext *C);
diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c
index c3159d38e7e..1574dbbeb76 100644
--- a/source/blender/editors/space_file/space_file.c
+++ b/source/blender/editors/space_file/space_file.c
@@ -663,7 +663,7 @@ static void file_ui_region_listener(wmWindow *UNUSED(win),
static bool filepath_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *UNUSED(event),
- const char **UNUSED(tooltip))
+ const char **UNUSED(r_tooltip))
{
if (drag->type == WM_DRAG_PATH) {
SpaceFile *sfile = CTX_wm_space_file(C);
diff --git a/source/blender/editors/space_image/image_edit.c b/source/blender/editors/space_image/image_edit.c
index 8da67effc94..7f911113b7c 100644
--- a/source/blender/editors/space_image/image_edit.c
+++ b/source/blender/editors/space_image/image_edit.c
@@ -212,7 +212,7 @@ bool ED_space_image_has_buffer(SpaceImage *sima)
return has_buffer;
}
-void ED_space_image_get_size(SpaceImage *sima, int *width, int *height)
+void ED_space_image_get_size(SpaceImage *sima, int *r_width, int *r_height)
{
Scene *scene = sima->iuser.scene;
ImBuf *ibuf;
@@ -222,94 +222,94 @@ void ED_space_image_get_size(SpaceImage *sima, int *width, int *height)
ibuf = ED_space_image_acquire_buffer(sima, &lock, 0);
if (ibuf && ibuf->x > 0 && ibuf->y > 0) {
- *width = ibuf->x;
- *height = ibuf->y;
+ *r_width = ibuf->x;
+ *r_height = ibuf->y;
}
else if (sima->image && sima->image->type == IMA_TYPE_R_RESULT && scene) {
/* not very important, just nice */
- *width = (scene->r.xsch * scene->r.size) / 100;
- *height = (scene->r.ysch * scene->r.size) / 100;
+ *r_width = (scene->r.xsch * scene->r.size) / 100;
+ *r_height = (scene->r.ysch * scene->r.size) / 100;
if ((scene->r.mode & R_BORDER) && (scene->r.mode & R_CROP)) {
- *width *= BLI_rctf_size_x(&scene->r.border);
- *height *= BLI_rctf_size_y(&scene->r.border);
+ *r_width *= BLI_rctf_size_x(&scene->r.border);
+ *r_height *= BLI_rctf_size_y(&scene->r.border);
}
}
/* I know a bit weak... but preview uses not actual image size */
- // XXX else if (image_preview_active(sima, width, height));
+ // XXX else if (image_preview_active(sima, r_width, r_height));
else {
- *width = IMG_SIZE_FALLBACK;
- *height = IMG_SIZE_FALLBACK;
+ *r_width = IMG_SIZE_FALLBACK;
+ *r_height = IMG_SIZE_FALLBACK;
}
ED_space_image_release_buffer(sima, ibuf, lock);
}
-void ED_space_image_get_size_fl(SpaceImage *sima, float size[2])
+void ED_space_image_get_size_fl(SpaceImage *sima, float r_size[2])
{
int size_i[2];
ED_space_image_get_size(sima, &size_i[0], &size_i[1]);
- size[0] = size_i[0];
- size[1] = size_i[1];
+ r_size[0] = size_i[0];
+ r_size[1] = size_i[1];
}
-void ED_space_image_get_aspect(SpaceImage *sima, float *aspx, float *aspy)
+void ED_space_image_get_aspect(SpaceImage *sima, float *r_aspx, float *r_aspy)
{
Image *ima = sima->image;
if ((ima == NULL) || (ima->aspx == 0.0f || ima->aspy == 0.0f)) {
- *aspx = *aspy = 1.0;
+ *r_aspx = *r_aspy = 1.0;
}
else {
- BKE_image_get_aspect(ima, aspx, aspy);
+ BKE_image_get_aspect(ima, r_aspx, r_aspy);
}
}
-void ED_space_image_get_zoom(SpaceImage *sima, ARegion *region, float *zoomx, float *zoomy)
+void ED_space_image_get_zoom(SpaceImage *sima, ARegion *region, float *r_zoomx, float *r_zoomy)
{
int width, height;
ED_space_image_get_size(sima, &width, &height);
- *zoomx = (float)(BLI_rcti_size_x(&region->winrct) + 1) /
- (float)(BLI_rctf_size_x(&region->v2d.cur) * width);
- *zoomy = (float)(BLI_rcti_size_y(&region->winrct) + 1) /
- (float)(BLI_rctf_size_y(&region->v2d.cur) * height);
+ *r_zoomx = (float)(BLI_rcti_size_x(&region->winrct) + 1) /
+ (float)(BLI_rctf_size_x(&region->v2d.cur) * width);
+ *r_zoomy = (float)(BLI_rcti_size_y(&region->winrct) + 1) /
+ (float)(BLI_rctf_size_y(&region->v2d.cur) * height);
}
-void ED_space_image_get_uv_aspect(SpaceImage *sima, float *aspx, float *aspy)
+void ED_space_image_get_uv_aspect(SpaceImage *sima, float *r_aspx, float *r_aspy)
{
int w, h;
- ED_space_image_get_aspect(sima, aspx, aspy);
+ ED_space_image_get_aspect(sima, r_aspx, r_aspy);
ED_space_image_get_size(sima, &w, &h);
- *aspx *= (float)w;
- *aspy *= (float)h;
+ *r_aspx *= (float)w;
+ *r_aspy *= (float)h;
- if (*aspx < *aspy) {
- *aspy = *aspy / *aspx;
- *aspx = 1.0f;
+ if (*r_aspx < *r_aspy) {
+ *r_aspy = *r_aspy / *r_aspx;
+ *r_aspx = 1.0f;
}
else {
- *aspx = *aspx / *aspy;
- *aspy = 1.0f;
+ *r_aspx = *r_aspx / *r_aspy;
+ *r_aspy = 1.0f;
}
}
-void ED_image_get_uv_aspect(Image *ima, ImageUser *iuser, float *aspx, float *aspy)
+void ED_image_get_uv_aspect(Image *ima, ImageUser *iuser, float *r_aspx, float *r_aspy)
{
if (ima) {
int w, h;
- BKE_image_get_aspect(ima, aspx, aspy);
+ BKE_image_get_aspect(ima, r_aspx, r_aspy);
BKE_image_get_size(ima, iuser, &w, &h);
- *aspx *= (float)w;
- *aspy *= (float)h;
+ *r_aspx *= (float)w;
+ *r_aspy *= (float)h;
}
else {
- *aspx = 1.0f;
- *aspy = 1.0f;
+ *r_aspx = 1.0f;
+ *r_aspy = 1.0f;
}
}
@@ -340,7 +340,8 @@ void ED_image_view_center_to_point(SpaceImage *sima, float x, float y)
sima->yof = (y - 0.5f) * height * aspy;
}
-void ED_image_point_pos(SpaceImage *sima, ARegion *region, float x, float y, float *xr, float *yr)
+void ED_image_point_pos(
+ SpaceImage *sima, ARegion *region, float x, float y, float *r_x, float *r_y)
{
int sx, sy, width, height;
float zoomx, zoomy;
@@ -350,8 +351,8 @@ void ED_image_point_pos(SpaceImage *sima, ARegion *region, float x, float y, flo
UI_view2d_view_to_region(&region->v2d, 0.0f, 0.0f, &sx, &sy);
- *xr = ((x - sx) / zoomx) / width;
- *yr = ((y - sy) / zoomy) / height;
+ *r_x = ((x - sx) / zoomx) / width;
+ *r_y = ((y - sy) / zoomy) / height;
}
void ED_image_point_pos__reverse(SpaceImage *sima,
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index 672f32f3c9c..7bd1b8e8291 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -4064,7 +4064,9 @@ void IMAGE_OT_clear_render_border(wmOperatorType *ot)
/** \} */
-/* ********************* Add tile operator ****************** */
+/* -------------------------------------------------------------------- */
+/** \name Add Tile Operator
+ * \{ */
static bool do_fill_tile(PointerRNA *ptr, Image *ima, ImageTile *tile)
{
@@ -4287,7 +4289,11 @@ void IMAGE_OT_tile_add(wmOperatorType *ot)
def_fill_tile(ot->srna);
}
-/* ********************* Remove tile operator ****************** */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Remove Tile Operator
+ * \{ */
static bool tile_remove_poll(bContext *C)
{
@@ -4328,7 +4334,11 @@ void IMAGE_OT_tile_remove(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/* ********************* Fill tile operator ****************** */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Fill Tile Operator
+ * \{ */
static bool tile_fill_poll(bContext *C)
{
diff --git a/source/blender/editors/space_image/image_undo.c b/source/blender/editors/space_image/image_undo.c
index 1394c05d7bc..8f9f4189c8a 100644
--- a/source/blender/editors/space_image/image_undo.c
+++ b/source/blender/editors/space_image/image_undo.c
@@ -714,7 +714,7 @@ static UndoImageBuf *ubuf_lookup_from_reference(ImageUndoStep *us_prev,
int tile_number,
const UndoImageBuf *ubuf)
{
- /* Use name lookup because because the pointer is cleared for previous steps. */
+ /* Use name lookup because the pointer is cleared for previous steps. */
UndoImageHandle *uh_prev = uhandle_lookup_by_name(&us_prev->handles, image, tile_number);
if (uh_prev != NULL) {
UndoImageBuf *ubuf_reference = uhandle_lookup_ubuf(uh_prev, image, ubuf->ibuf_name);
diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c
index a9cbebc5655..12a1dce3a5f 100644
--- a/source/blender/editors/space_image/space_image.c
+++ b/source/blender/editors/space_image/space_image.c
@@ -265,7 +265,7 @@ static void image_keymap(struct wmKeyConfig *keyconf)
static bool image_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
- const char **UNUSED(tooltip))
+ const char **UNUSED(r_tooltip))
{
ScrArea *area = CTX_wm_area(C);
if (ED_region_overlap_isect_any_xy(area, &event->x)) {
diff --git a/source/blender/editors/space_info/textview.c b/source/blender/editors/space_info/textview.c
index 19ada4779a0..c842fa8b4ac 100644
--- a/source/blender/editors/space_info/textview.c
+++ b/source/blender/editors/space_info/textview.c
@@ -102,28 +102,29 @@ static void textview_draw_sel(const char *str,
}
/**
- * \warning Allocated memory for 'offsets' must be freed by caller.
+ * \warning Allocated memory for 'r_offsets' must be freed by caller.
* \return The length in bytes.
*/
-static int textview_wrap_offsets(const char *str, int len, int width, int *lines, int **offsets)
+static int textview_wrap_offsets(
+ const char *str, int len, int width, int *r_lines, int **r_offsets)
{
int i, end; /* Offset as unicode code-point. */
int j; /* Offset as bytes. */
- *lines = 1;
+ *r_lines = 1;
- *offsets = MEM_callocN(
- sizeof(**offsets) *
+ *r_offsets = MEM_callocN(
+ sizeof(**r_offsets) *
(len * BLI_UTF8_WIDTH_MAX / MAX2(1, width - (BLI_UTF8_WIDTH_MAX - 1)) + 1),
__func__);
- (*offsets)[0] = 0;
+ (*r_offsets)[0] = 0;
for (i = 0, end = width, j = 0; j < len && str[j]; j += BLI_str_utf8_size_safe(str + j)) {
int columns = BLI_str_utf8_char_width_safe(str + j);
if (i + columns > end) {
- (*offsets)[*lines] = j;
- (*lines)++;
+ (*r_offsets)[*r_lines] = j;
+ (*r_lines)++;
end = i + width;
}
diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c
index 9d81994bb0b..e50f5a818aa 100644
--- a/source/blender/editors/space_node/node_edit.c
+++ b/source/blender/editors/space_node/node_edit.c
@@ -819,7 +819,7 @@ static int edit_node_invoke_properties(bContext *C, wmOperator *op)
}
static void edit_node_properties_get(
- wmOperator *op, bNodeTree *ntree, bNode **rnode, bNodeSocket **rsock, int *rin_out)
+ wmOperator *op, bNodeTree *ntree, bNode **r_node, bNodeSocket **r_sock, int *r_in_out)
{
bNode *node;
bNodeSocket *sock = NULL;
@@ -842,14 +842,14 @@ static void edit_node_properties_get(
break;
}
- if (rnode) {
- *rnode = node;
+ if (r_node) {
+ *r_node = node;
}
- if (rsock) {
- *rsock = sock;
+ if (r_sock) {
+ *r_sock = sock;
}
- if (rin_out) {
- *rin_out = in_out;
+ if (r_in_out) {
+ *r_in_out = in_out;
}
}
#endif
diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h
index 8c7c490b181..42439e88c96 100644
--- a/source/blender/editors/space_node/node_intern.h
+++ b/source/blender/editors/space_node/node_intern.h
@@ -271,7 +271,7 @@ extern const char *node_context_dir[];
#define NODE_SOCKDY (0.08f * U.widget_unit)
#define NODE_WIDTH(node) (node->width * UI_DPI_FAC)
#define NODE_HEIGHT(node) (node->height * UI_DPI_FAC)
-#define NODE_MARGIN_X (0.75f * U.widget_unit)
+#define NODE_MARGIN_X (0.95f * U.widget_unit)
#define NODE_SOCKSIZE (0.25f * U.widget_unit)
#define NODE_RESIZE_MARGIN (0.20f * U.widget_unit)
#define NODE_LINK_RESOL 12
diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c
index ce351595522..32007d5b971 100644
--- a/source/blender/editors/space_node/space_node.c
+++ b/source/blender/editors/space_node/space_node.c
@@ -635,7 +635,7 @@ static void node_main_region_draw(const bContext *C, ARegion *region)
static bool node_ima_drop_poll(bContext *UNUSED(C),
wmDrag *drag,
const wmEvent *UNUSED(event),
- const char **UNUSED(tooltip))
+ const char **UNUSED(r_tooltip))
{
if (drag->type == WM_DRAG_PATH) {
/* rule might not work? */
@@ -649,7 +649,7 @@ static bool node_ima_drop_poll(bContext *UNUSED(C),
static bool node_mask_drop_poll(bContext *UNUSED(C),
wmDrag *drag,
const wmEvent *UNUSED(event),
- const char **UNUSED(tooltip))
+ const char **UNUSED(r_tooltip))
{
return WM_drag_ID(drag, ID_MSK) != NULL;
}
diff --git a/source/blender/editors/space_outliner/outliner_collections.c b/source/blender/editors/space_outliner/outliner_collections.c
index 8da085f436d..8563b7d8c24 100644
--- a/source/blender/editors/space_outliner/outliner_collections.c
+++ b/source/blender/editors/space_outliner/outliner_collections.c
@@ -53,6 +53,8 @@
#include "outliner_intern.h" /* own include */
/* -------------------------------------------------------------------- */
+/** \name Utility API
+ * \{ */
bool outliner_is_collection_tree_element(const TreeElement *te)
{
@@ -133,8 +135,30 @@ TreeTraversalAction outliner_find_selected_objects(TreeElement *te, void *custom
return TRAVERSE_CONTINUE;
}
+/**
+ * Populates the \param objects: ListBase with all the outliner selected objects
+ * We store it as (Object *)LinkData->data
+ * \param objects: expected to be empty
+ */
+void ED_outliner_selected_objects_get(const bContext *C, ListBase *objects)
+{
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
+ struct IDsSelectedData data = {{NULL}};
+ outliner_tree_traverse(
+ soops, &soops->tree, 0, TSE_SELECTED, outliner_find_selected_objects, &data);
+ LISTBASE_FOREACH (LinkData *, link, &data.selected_array) {
+ TreeElement *ten_selected = (TreeElement *)link->data;
+ Object *ob = (Object *)TREESTORE(ten_selected)->id;
+ BLI_addtail(objects, BLI_genericNodeN(ob));
+ }
+ BLI_freelistN(&data.selected_array);
+}
+
+/** \} */
+
/* -------------------------------------------------------------------- */
-/* Poll functions. */
+/** \name Poll Functions
+ * \{ */
bool ED_outliner_collections_editor_poll(bContext *C)
{
@@ -148,7 +172,11 @@ static bool outliner_view_layer_collections_editor_poll(bContext *C)
return (so != NULL) && (so->outlinevis == SO_VIEW_LAYER);
}
-/********************************* New Collection ****************************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name New Collection
+ * \{ */
struct CollectionNewData {
bool error;
@@ -237,7 +265,11 @@ void OUTLINER_OT_collection_new(wmOperatorType *ot)
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
-/**************************** Delete Collection ******************************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Delete Collection
+ * \{ */
struct CollectionEditData {
Scene *scene;
@@ -369,7 +401,11 @@ void OUTLINER_OT_collection_delete(wmOperatorType *ot)
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
-/****************************** Select Objects *******************************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select/Deselect Collection Objects
+ * \{ */
struct CollectionObjectsSelectData {
bool error;
@@ -457,7 +493,11 @@ void OUTLINER_OT_collection_objects_deselect(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/************************** Duplicate Collection *****************************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Duplicate Collection
+ * \{ */
struct CollectionDuplicateData {
TreeElement *te;
@@ -578,7 +618,11 @@ void OUTLINER_OT_collection_duplicate(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/**************************** Link Collection ******************************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Link Collection
+ * \{ */
static int collection_link_exec(bContext *C, wmOperator *op)
{
@@ -636,7 +680,11 @@ void OUTLINER_OT_collection_link(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/************************** Instance Collection ******************************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Instance Collection
+ * \{ */
static int collection_instance_exec(bContext *C, wmOperator *UNUSED(op))
{
@@ -703,7 +751,11 @@ void OUTLINER_OT_collection_instance(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/************************** Exclude Collection ******************************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Exclude Collection
+ * \{ */
static TreeTraversalAction layer_collection_find_data_to_edit(TreeElement *te, void *customdata)
{
@@ -945,7 +997,11 @@ void OUTLINER_OT_collection_indirect_only_clear(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/************************** Visibility Operators ******************************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Visibility for Collection Operators
+ * \{ */
static int collection_isolate_exec(bContext *C, wmOperator *op)
{
@@ -1129,6 +1185,12 @@ void OUTLINER_OT_collection_hide_inside(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Enable/Disable Collection Operators
+ * \{ */
+
static bool collection_flag_poll(bContext *C, bool clear, int flag)
{
if (!ED_outliner_collections_editor_poll(C)) {
@@ -1310,6 +1372,12 @@ struct OutlinerHideEditData {
GSet *bases_to_edit;
};
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Visibility for Collection & Object Operators
+ * \{ */
+
static TreeTraversalAction outliner_hide_find_data_to_edit(TreeElement *te, void *customdata)
{
struct OutlinerHideEditData *data = customdata;
@@ -1433,21 +1501,4 @@ void OUTLINER_OT_unhide_all(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/**
- * Populates the \param objects: ListBase with all the outliner selected objects
- * We store it as (Object *)LinkData->data
- * \param objects: expected to be empty
- */
-void ED_outliner_selected_objects_get(const bContext *C, ListBase *objects)
-{
- SpaceOutliner *soops = CTX_wm_space_outliner(C);
- struct IDsSelectedData data = {{NULL}};
- outliner_tree_traverse(
- soops, &soops->tree, 0, TSE_SELECTED, outliner_find_selected_objects, &data);
- LISTBASE_FOREACH (LinkData *, link, &data.selected_array) {
- TreeElement *ten_selected = (TreeElement *)link->data;
- Object *ob = (Object *)TREESTORE(ten_selected)->id;
- BLI_addtail(objects, BLI_genericNodeN(ob));
- }
- BLI_freelistN(&data.selected_array);
-}
+/** \} */
diff --git a/source/blender/editors/space_outliner/outliner_dragdrop.c b/source/blender/editors/space_outliner/outliner_dragdrop.c
index 8aeeef277f7..6f071ca128e 100644
--- a/source/blender/editors/space_outliner/outliner_dragdrop.c
+++ b/source/blender/editors/space_outliner/outliner_dragdrop.c
@@ -291,7 +291,7 @@ static bool allow_parenting_without_modifier_key(SpaceOutliner *soops)
static bool parent_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
- const char **UNUSED(tooltip))
+ const char **UNUSED(r_tooltip))
{
SpaceOutliner *soops = CTX_wm_space_outliner(C);
@@ -430,7 +430,7 @@ void OUTLINER_OT_parent_drop(wmOperatorType *ot)
static bool parent_clear_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
- const char **UNUSED(tooltip))
+ const char **UNUSED(r_tooltip))
{
SpaceOutliner *soops = CTX_wm_space_outliner(C);
@@ -516,7 +516,7 @@ void OUTLINER_OT_parent_clear(wmOperatorType *ot)
static bool scene_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
- const char **UNUSED(tooltip))
+ const char **UNUSED(r_tooltip))
{
/* Ensure item under cursor is valid drop target */
Object *ob = (Object *)WM_drag_ID(drag, ID_OB);
@@ -585,7 +585,7 @@ void OUTLINER_OT_scene_drop(wmOperatorType *ot)
static bool material_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
- const char **UNUSED(tooltip))
+ const char **UNUSED(r_tooltip))
{
/* Ensure item under cursor is valid drop target */
Material *ma = (Material *)WM_drag_ID(drag, ID_MA);
@@ -721,7 +721,7 @@ static bool collection_drop_init(bContext *C,
static bool collection_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
- const char **tooltip)
+ const char **r_tooltip)
{
SpaceOutliner *soops = CTX_wm_space_outliner(C);
ARegion *region = CTX_wm_region(C);
@@ -734,7 +734,7 @@ static bool collection_drop_poll(bContext *C,
if (!data.from || event->ctrl) {
tselem->flag |= TSE_DRAG_INTO;
changed = true;
- *tooltip = TIP_("Link inside Collection");
+ *r_tooltip = TIP_("Link inside Collection");
}
else {
switch (data.insert_type) {
@@ -742,26 +742,26 @@ static bool collection_drop_poll(bContext *C,
tselem->flag |= TSE_DRAG_BEFORE;
changed = true;
if (te->prev && outliner_is_collection_tree_element(te->prev)) {
- *tooltip = TIP_("Move between collections");
+ *r_tooltip = TIP_("Move between collections");
}
else {
- *tooltip = TIP_("Move before collection");
+ *r_tooltip = TIP_("Move before collection");
}
break;
case TE_INSERT_AFTER:
tselem->flag |= TSE_DRAG_AFTER;
changed = true;
if (te->next && outliner_is_collection_tree_element(te->next)) {
- *tooltip = TIP_("Move between collections");
+ *r_tooltip = TIP_("Move between collections");
}
else {
- *tooltip = TIP_("Move after collection");
+ *r_tooltip = TIP_("Move after collection");
}
break;
case TE_INSERT_INTO:
tselem->flag |= TSE_DRAG_INTO;
changed = true;
- *tooltip = TIP_("Move inside collection (Ctrl to link, Shift to parent)");
+ *r_tooltip = TIP_("Move inside collection (Ctrl to link, Shift to parent)");
break;
}
}
diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c
index 058d41ab294..0766996c00b 100644
--- a/source/blender/editors/space_sequencer/sequencer_draw.c
+++ b/source/blender/editors/space_sequencer/sequencer_draw.c
@@ -1368,68 +1368,68 @@ static void seq_prefetch_wm_notify(const bContext *C, Scene *scene)
}
static void *sequencer_OCIO_transform_ibuf(
- const bContext *C, ImBuf *ibuf, bool *glsl_used, int *format, int *type)
+ const bContext *C, ImBuf *ibuf, bool *r_glsl_used, int *r_format, int *r_type)
{
void *display_buffer;
void *cache_handle = NULL;
bool force_fallback = false;
- *glsl_used = false;
+ *r_glsl_used = false;
force_fallback |= (ED_draw_imbuf_method(ibuf) != IMAGE_DRAW_METHOD_GLSL);
force_fallback |= (ibuf->dither != 0.0f);
if (force_fallback) {
/* Fallback to CPU based color space conversion */
- *glsl_used = false;
- *format = GL_RGBA;
- *type = GL_UNSIGNED_BYTE;
+ *r_glsl_used = false;
+ *r_format = GL_RGBA;
+ *r_type = GL_UNSIGNED_BYTE;
display_buffer = NULL;
}
else if (ibuf->rect_float) {
display_buffer = ibuf->rect_float;
if (ibuf->channels == 4) {
- *format = GL_RGBA;
+ *r_format = GL_RGBA;
}
else if (ibuf->channels == 3) {
- *format = GL_RGB;
+ *r_format = GL_RGB;
}
else {
BLI_assert(!"Incompatible number of channels for float buffer in sequencer");
- *format = GL_RGBA;
+ *r_format = GL_RGBA;
display_buffer = NULL;
}
- *type = GL_FLOAT;
+ *r_type = GL_FLOAT;
if (ibuf->float_colorspace) {
- *glsl_used = IMB_colormanagement_setup_glsl_draw_from_space_ctx(
+ *r_glsl_used = IMB_colormanagement_setup_glsl_draw_from_space_ctx(
C, ibuf->float_colorspace, ibuf->dither, true);
}
else {
- *glsl_used = IMB_colormanagement_setup_glsl_draw_ctx(C, ibuf->dither, true);
+ *r_glsl_used = IMB_colormanagement_setup_glsl_draw_ctx(C, ibuf->dither, true);
}
}
else if (ibuf->rect) {
display_buffer = ibuf->rect;
- *format = GL_RGBA;
- *type = GL_UNSIGNED_BYTE;
+ *r_format = GL_RGBA;
+ *r_type = GL_UNSIGNED_BYTE;
- *glsl_used = IMB_colormanagement_setup_glsl_draw_from_space_ctx(
+ *r_glsl_used = IMB_colormanagement_setup_glsl_draw_from_space_ctx(
C, ibuf->rect_colorspace, ibuf->dither, false);
}
else {
- *format = GL_RGBA;
- *type = GL_UNSIGNED_BYTE;
+ *r_format = GL_RGBA;
+ *r_type = GL_UNSIGNED_BYTE;
display_buffer = NULL;
}
/* there's a data to be displayed, but GLSL is not initialized
* properly, in this case we fallback to CPU-based display transform
*/
- if ((ibuf->rect || ibuf->rect_float) && !*glsl_used) {
+ if ((ibuf->rect || ibuf->rect_float) && !*r_glsl_used) {
display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, &cache_handle);
- *format = GL_RGBA;
- *type = GL_UNSIGNED_BYTE;
+ *r_format = GL_RGBA;
+ *r_type = GL_UNSIGNED_BYTE;
}
if (cache_handle) {
IMB_display_buffer_release(cache_handle);
@@ -1968,6 +1968,7 @@ typedef struct CacheDrawData {
struct View2D *v2d;
float stripe_offs;
float stripe_ht;
+ int cache_flag;
GPUVertBuf *raw_vbo;
GPUVertBuf *preprocessed_vbo;
GPUVertBuf *composite_vbo;
@@ -1979,7 +1980,25 @@ typedef struct CacheDrawData {
} CacheDrawData;
/* Called as a callback */
-static bool draw_cache_view_cb(
+static bool draw_cache_view_init_cb(void *userdata, size_t item_count)
+{
+ if (item_count == 0) {
+ return true;
+ }
+
+ CacheDrawData *drawdata = userdata;
+ /* We can not get item count per cache type, so using total item count is safe. */
+ size_t max_vert_count = item_count * 6;
+ GPU_vertbuf_data_alloc(drawdata->raw_vbo, max_vert_count);
+ GPU_vertbuf_data_alloc(drawdata->preprocessed_vbo, max_vert_count);
+ GPU_vertbuf_data_alloc(drawdata->composite_vbo, max_vert_count);
+ GPU_vertbuf_data_alloc(drawdata->final_out_vbo, max_vert_count);
+
+ return false;
+}
+
+/* Called as a callback */
+static bool draw_cache_view_iter_cb(
void *userdata, struct Sequence *seq, int nfra, int cache_type, float UNUSED(cost))
{
CacheDrawData *drawdata = userdata;
@@ -1987,44 +2006,43 @@ static bool draw_cache_view_cb(
float stripe_bot, stripe_top, stripe_offs, stripe_ht;
GPUVertBuf *vbo;
size_t *vert_count;
- switch (cache_type) {
- case SEQ_CACHE_STORE_FINAL_OUT:
- stripe_ht = UI_view2d_region_to_view_y(v2d, 4.0f * UI_DPI_FAC * U.pixelsize) - v2d->cur.ymin;
- stripe_bot = UI_view2d_region_to_view_y(v2d, V2D_SCROLL_HANDLE_HEIGHT);
- stripe_top = stripe_bot + stripe_ht;
- vbo = drawdata->final_out_vbo;
- vert_count = &drawdata->final_out_vert_count;
- break;
-
- case SEQ_CACHE_STORE_RAW:
- stripe_offs = drawdata->stripe_offs;
- stripe_ht = drawdata->stripe_ht;
- stripe_bot = seq->machine + SEQ_STRIP_OFSBOTTOM + stripe_offs;
- stripe_top = stripe_bot + stripe_ht;
- vbo = drawdata->raw_vbo;
- vert_count = &drawdata->raw_vert_count;
- break;
- case SEQ_CACHE_STORE_PREPROCESSED:
- stripe_offs = drawdata->stripe_offs;
- stripe_ht = drawdata->stripe_ht;
- stripe_bot = seq->machine + SEQ_STRIP_OFSBOTTOM + (stripe_offs + stripe_ht) + stripe_offs;
- stripe_top = stripe_bot + stripe_ht;
- vbo = drawdata->preprocessed_vbo;
- vert_count = &drawdata->preprocessed_vert_count;
- break;
-
- case SEQ_CACHE_STORE_COMPOSITE:
- stripe_offs = drawdata->stripe_offs;
- stripe_ht = drawdata->stripe_ht;
- stripe_top = seq->machine + SEQ_STRIP_OFSTOP - stripe_offs;
- stripe_bot = stripe_top - stripe_ht;
- vbo = drawdata->composite_vbo;
- vert_count = &drawdata->composite_vert_count;
- break;
-
- default:
- return true;
+ if ((cache_type & SEQ_CACHE_STORE_FINAL_OUT) &&
+ (drawdata->cache_flag & SEQ_CACHE_VIEW_FINAL_OUT)) {
+ stripe_ht = UI_view2d_region_to_view_y(v2d, 4.0f * UI_DPI_FAC * U.pixelsize) - v2d->cur.ymin;
+ stripe_bot = UI_view2d_region_to_view_y(v2d, V2D_SCROLL_HANDLE_HEIGHT);
+ stripe_top = stripe_bot + stripe_ht;
+ vbo = drawdata->final_out_vbo;
+ vert_count = &drawdata->final_out_vert_count;
+ }
+ else if ((cache_type & SEQ_CACHE_STORE_RAW) && (drawdata->cache_flag & SEQ_CACHE_VIEW_RAW)) {
+ stripe_offs = drawdata->stripe_offs;
+ stripe_ht = drawdata->stripe_ht;
+ stripe_bot = seq->machine + SEQ_STRIP_OFSBOTTOM + stripe_offs;
+ stripe_top = stripe_bot + stripe_ht;
+ vbo = drawdata->raw_vbo;
+ vert_count = &drawdata->raw_vert_count;
+ }
+ else if ((cache_type & SEQ_CACHE_STORE_PREPROCESSED) &&
+ (drawdata->cache_flag & SEQ_CACHE_VIEW_PREPROCESSED)) {
+ stripe_offs = drawdata->stripe_offs;
+ stripe_ht = drawdata->stripe_ht;
+ stripe_bot = seq->machine + SEQ_STRIP_OFSBOTTOM + (stripe_offs + stripe_ht) + stripe_offs;
+ stripe_top = stripe_bot + stripe_ht;
+ vbo = drawdata->preprocessed_vbo;
+ vert_count = &drawdata->preprocessed_vert_count;
+ }
+ else if ((cache_type & SEQ_CACHE_STORE_COMPOSITE) &&
+ (drawdata->cache_flag & SEQ_CACHE_VIEW_COMPOSITE)) {
+ stripe_offs = drawdata->stripe_offs;
+ stripe_ht = drawdata->stripe_ht;
+ stripe_top = seq->machine + SEQ_STRIP_OFSTOP - stripe_offs;
+ stripe_bot = stripe_top - stripe_ht;
+ vbo = drawdata->composite_vbo;
+ vert_count = &drawdata->composite_vert_count;
+ }
+ else {
+ return false;
}
int cfra = seq->start + nfra;
@@ -2048,10 +2066,10 @@ static void draw_cache_view_batch(
GPUVertBuf *vbo, size_t vert_count, float col_r, float col_g, float col_b, float col_a)
{
GPUBatch *batch = GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, NULL, GPU_BATCH_OWNS_VBO);
- GPU_vertbuf_data_len_set(vbo, vert_count);
- GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_UNIFORM_COLOR);
- GPU_batch_uniform_4f(batch, "color", col_r, col_g, col_b, col_a);
if (vert_count > 0) {
+ GPU_vertbuf_data_len_set(vbo, vert_count);
+ GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_UNIFORM_COLOR);
+ GPU_batch_uniform_4f(batch, "color", col_r, col_g, col_b, col_a);
GPU_batch_draw(batch);
}
GPU_batch_discard(batch);
@@ -2127,42 +2145,32 @@ static void draw_cache_view(const bContext *C)
immUnbindProgram();
- size_t cache_num_items = BKE_sequencer_cache_get_num_items(scene);
-
- if (cache_num_items > 0) {
- GPUVertFormat format = {0};
- GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
-
- CacheDrawData userdata;
- userdata.v2d = v2d;
- userdata.stripe_offs = stripe_offs;
- userdata.stripe_ht = stripe_ht;
- userdata.raw_vert_count = 0;
- userdata.preprocessed_vert_count = 0;
- userdata.composite_vert_count = 0;
- userdata.final_out_vert_count = 0;
- userdata.raw_vbo = GPU_vertbuf_create_with_format(&format);
- userdata.preprocessed_vbo = GPU_vertbuf_create_with_format(&format);
- userdata.composite_vbo = GPU_vertbuf_create_with_format(&format);
- userdata.final_out_vbo = GPU_vertbuf_create_with_format(&format);
-
- /* We can not get item count per cache type, so using total item count is safe. */
- size_t max_vert_count = cache_num_items * 6;
- GPU_vertbuf_data_alloc(userdata.raw_vbo, max_vert_count);
- GPU_vertbuf_data_alloc(userdata.preprocessed_vbo, max_vert_count);
- GPU_vertbuf_data_alloc(userdata.composite_vbo, max_vert_count);
- GPU_vertbuf_data_alloc(userdata.final_out_vbo, max_vert_count);
-
- BKE_sequencer_cache_iterate(scene, &userdata, draw_cache_view_cb);
-
- draw_cache_view_batch(userdata.raw_vbo, userdata.raw_vert_count, 1.0f, 0.1f, 0.02f, 0.4f);
- draw_cache_view_batch(
- userdata.preprocessed_vbo, userdata.preprocessed_vert_count, 0.1f, 0.1f, 0.75f, 0.4f);
- draw_cache_view_batch(
- userdata.composite_vbo, userdata.composite_vert_count, 1.0f, 0.6f, 0.0f, 0.4f);
- draw_cache_view_batch(
- userdata.final_out_vbo, userdata.final_out_vert_count, 1.0f, 0.4f, 0.2f, 0.4f);
- }
+ GPUVertFormat format = {0};
+ GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+
+ CacheDrawData userdata;
+ userdata.v2d = v2d;
+ userdata.stripe_offs = stripe_offs;
+ userdata.stripe_ht = stripe_ht;
+ userdata.cache_flag = scene->ed->cache_flag;
+ userdata.raw_vert_count = 0;
+ userdata.preprocessed_vert_count = 0;
+ userdata.composite_vert_count = 0;
+ userdata.final_out_vert_count = 0;
+ userdata.raw_vbo = GPU_vertbuf_create_with_format(&format);
+ userdata.preprocessed_vbo = GPU_vertbuf_create_with_format(&format);
+ userdata.composite_vbo = GPU_vertbuf_create_with_format(&format);
+ userdata.final_out_vbo = GPU_vertbuf_create_with_format(&format);
+
+ BKE_sequencer_cache_iterate(scene, &userdata, draw_cache_view_init_cb, draw_cache_view_iter_cb);
+
+ draw_cache_view_batch(userdata.raw_vbo, userdata.raw_vert_count, 1.0f, 0.1f, 0.02f, 0.4f);
+ draw_cache_view_batch(
+ userdata.preprocessed_vbo, userdata.preprocessed_vert_count, 0.1f, 0.1f, 0.75f, 0.4f);
+ draw_cache_view_batch(
+ userdata.composite_vbo, userdata.composite_vert_count, 1.0f, 0.6f, 0.0f, 0.4f);
+ draw_cache_view_batch(
+ userdata.final_out_vbo, userdata.final_out_vert_count, 1.0f, 0.4f, 0.2f, 0.4f);
GPU_blend(false);
}
diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c
index 3f36c844f30..71e63547eae 100644
--- a/source/blender/editors/space_sequencer/sequencer_edit.c
+++ b/source/blender/editors/space_sequencer/sequencer_edit.c
@@ -551,15 +551,15 @@ bool ED_space_sequencer_check_show_strip(SpaceSeq *sseq)
int seq_effect_find_selected(Scene *scene,
Sequence *activeseq,
int type,
- Sequence **selseq1,
- Sequence **selseq2,
- Sequence **selseq3,
- const char **error_str)
+ Sequence **r_selseq1,
+ Sequence **r_selseq2,
+ Sequence **r_selseq3,
+ const char **r_error_str)
{
Editing *ed = BKE_sequencer_editing_get(scene, false);
Sequence *seq1 = NULL, *seq2 = NULL, *seq3 = NULL, *seq;
- *error_str = NULL;
+ *r_error_str = NULL;
if (!activeseq) {
seq2 = BKE_sequencer_active_get(scene);
@@ -568,7 +568,7 @@ int seq_effect_find_selected(Scene *scene,
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
if (seq->flag & SELECT) {
if (seq->type == SEQ_TYPE_SOUND_RAM && BKE_sequence_effect_get_num_inputs(type) != 0) {
- *error_str = N_("Cannot apply effects to audio sequence strips");
+ *r_error_str = N_("Cannot apply effects to audio sequence strips");
return 0;
}
if ((seq != activeseq) && (seq != seq2)) {
@@ -582,7 +582,7 @@ int seq_effect_find_selected(Scene *scene,
seq3 = seq;
}
else {
- *error_str = N_("Cannot apply effect to more than 3 sequence strips");
+ *r_error_str = N_("Cannot apply effect to more than 3 sequence strips");
return 0;
}
}
@@ -599,11 +599,11 @@ int seq_effect_find_selected(Scene *scene,
switch (BKE_sequence_effect_get_num_inputs(type)) {
case 0:
- *selseq1 = *selseq2 = *selseq3 = NULL;
+ *r_selseq1 = *r_selseq2 = *r_selseq3 = NULL;
return 1; /* success */
case 1:
if (seq2 == NULL) {
- *error_str = N_("At least one selected sequence strip is needed");
+ *r_error_str = N_("At least one selected sequence strip is needed");
return 0;
}
if (seq1 == NULL) {
@@ -615,7 +615,7 @@ int seq_effect_find_selected(Scene *scene,
ATTR_FALLTHROUGH;
case 2:
if (seq1 == NULL || seq2 == NULL) {
- *error_str = N_("2 selected sequence strips are needed");
+ *r_error_str = N_("2 selected sequence strips are needed");
return 0;
}
if (seq3 == NULL) {
@@ -625,13 +625,13 @@ int seq_effect_find_selected(Scene *scene,
}
if (seq1 == NULL && seq2 == NULL && seq3 == NULL) {
- *error_str = N_("TODO: in what cases does this happen?");
+ *r_error_str = N_("TODO: in what cases does this happen?");
return 0;
}
- *selseq1 = seq1;
- *selseq2 = seq2;
- *selseq3 = seq3;
+ *r_selseq1 = seq1;
+ *r_selseq2 = seq2;
+ *r_selseq3 = seq3;
return 1;
}
diff --git a/source/blender/editors/space_sequencer/sequencer_intern.h b/source/blender/editors/space_sequencer/sequencer_intern.h
index fe3170e10e0..f70bc06caf7 100644
--- a/source/blender/editors/space_sequencer/sequencer_intern.h
+++ b/source/blender/editors/space_sequencer/sequencer_intern.h
@@ -83,10 +83,10 @@ void recurs_sel_seq(struct Sequence *seqm);
int seq_effect_find_selected(struct Scene *scene,
struct Sequence *activeseq,
int type,
- struct Sequence **selseq1,
- struct Sequence **selseq2,
- struct Sequence **selseq3,
- const char **error_str);
+ struct Sequence **r_selseq1,
+ struct Sequence **r_selseq2,
+ struct Sequence **r_selseq3,
+ const char **r_error_str);
/* operator helpers */
bool sequencer_edit_poll(struct bContext *C);
diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c
index 1aa2a0c9c44..447bf27099d 100644
--- a/source/blender/editors/space_sequencer/space_sequencer.c
+++ b/source/blender/editors/space_sequencer/space_sequencer.c
@@ -363,7 +363,7 @@ static void sequencer_listener(wmWindow *UNUSED(win),
static bool image_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
- const char **UNUSED(tooltip))
+ const char **UNUSED(r_tooltip))
{
ARegion *region = CTX_wm_region(C);
Scene *scene = CTX_data_scene(C);
@@ -383,7 +383,7 @@ static bool image_drop_poll(bContext *C,
static bool movie_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
- const char **UNUSED(tooltip))
+ const char **UNUSED(r_tooltip))
{
ARegion *region = CTX_wm_region(C);
Scene *scene = CTX_data_scene(C);
@@ -402,7 +402,7 @@ static bool movie_drop_poll(bContext *C,
static bool sound_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
- const char **UNUSED(tooltip))
+ const char **UNUSED(r_tooltip))
{
ARegion *region = CTX_wm_region(C);
Scene *scene = CTX_data_scene(C);
@@ -679,19 +679,18 @@ static void sequencer_preview_region_draw(const bContext *C, ARegion *region)
SpaceSeq *sseq = sa->spacedata.first;
Scene *scene = CTX_data_scene(C);
wmWindowManager *wm = CTX_wm_manager(C);
- const bool show_split = (scene->ed && (scene->ed->over_flag & SEQ_EDIT_OVERLAY_SHOW) &&
- (sseq->mainb == SEQ_DRAW_IMG_IMBUF));
+ const bool draw_overlay = (scene->ed && (scene->ed->over_flag & SEQ_EDIT_OVERLAY_SHOW));
/* XXX temp fix for wrong setting in sseq->mainb */
if (sseq->mainb == SEQ_DRAW_SEQUENCE) {
sseq->mainb = SEQ_DRAW_IMG_IMBUF;
}
- if (!show_split || sseq->overlay_type != SEQ_DRAW_OVERLAY_REFERENCE) {
+ if (!draw_overlay || sseq->overlay_type != SEQ_DRAW_OVERLAY_REFERENCE) {
sequencer_draw_preview(C, scene, region, sseq, scene->r.cfra, 0, false, false);
}
- if (show_split && sseq->overlay_type != SEQ_DRAW_OVERLAY_CURRENT) {
+ if (draw_overlay && sseq->overlay_type != SEQ_DRAW_OVERLAY_CURRENT) {
int over_cfra;
if (scene->ed->over_flag & SEQ_EDIT_OVERLAY_ABS) {
diff --git a/source/blender/editors/space_text/space_text.c b/source/blender/editors/space_text/space_text.c
index 92b084a8d0d..d5379a4e76d 100644
--- a/source/blender/editors/space_text/space_text.c
+++ b/source/blender/editors/space_text/space_text.c
@@ -328,7 +328,7 @@ static void text_cursor(wmWindow *win, ScrArea *sa, ARegion *region)
static bool text_drop_poll(bContext *UNUSED(C),
wmDrag *drag,
const wmEvent *UNUSED(event),
- const char **UNUSED(tooltip))
+ const char **UNUSED(r_tooltip))
{
if (drag->type == WM_DRAG_PATH) {
/* rule might not work? */
@@ -348,7 +348,7 @@ static void text_drop_copy(wmDrag *drag, wmDropBox *drop)
static bool text_drop_paste_poll(bContext *UNUSED(C),
wmDrag *drag,
const wmEvent *UNUSED(event),
- const char **UNUSED(tooltip))
+ const char **UNUSED(r_tooltip))
{
return (drag->type == WM_DRAG_ID);
}
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index eb245ae0766..13c5bddd3bf 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -471,7 +471,7 @@ static bool view3d_drop_id_in_main_region_poll(bContext *C,
static bool view3d_ob_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
- const char **UNUSED(tooltip))
+ const char **UNUSED(r_tooltip))
{
return view3d_drop_id_in_main_region_poll(C, drag, event, ID_OB);
}
@@ -479,7 +479,7 @@ static bool view3d_ob_drop_poll(bContext *C,
static bool view3d_collection_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
- const char **UNUSED(tooltip))
+ const char **UNUSED(r_tooltip))
{
return view3d_drop_id_in_main_region_poll(C, drag, event, ID_GR);
}
@@ -487,7 +487,7 @@ static bool view3d_collection_drop_poll(bContext *C,
static bool view3d_mat_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
- const char **UNUSED(tooltip))
+ const char **UNUSED(r_tooltip))
{
return view3d_drop_id_in_main_region_poll(C, drag, event, ID_MA);
}
@@ -495,7 +495,7 @@ static bool view3d_mat_drop_poll(bContext *C,
static bool view3d_ima_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
- const char **UNUSED(tooltip))
+ const char **UNUSED(r_tooltip))
{
if (ED_region_overlap_isect_any_xy(CTX_wm_area(C), &event->x)) {
return false;
@@ -524,9 +524,9 @@ static bool view3d_ima_bg_is_camera_view(bContext *C)
static bool view3d_ima_bg_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
- const char **tooltip)
+ const char **r_tooltip)
{
- if (!view3d_ima_drop_poll(C, drag, event, tooltip)) {
+ if (!view3d_ima_drop_poll(C, drag, event, r_tooltip)) {
return false;
}
@@ -540,9 +540,9 @@ static bool view3d_ima_bg_drop_poll(bContext *C,
static bool view3d_ima_empty_drop_poll(bContext *C,
wmDrag *drag,
const wmEvent *event,
- const char **tooltip)
+ const char **r_tooltip)
{
- if (!view3d_ima_drop_poll(C, drag, event, tooltip)) {
+ if (!view3d_ima_drop_poll(C, drag, event, r_tooltip)) {
return false;
}
@@ -562,7 +562,7 @@ static bool view3d_ima_empty_drop_poll(bContext *C,
static bool view3d_volume_drop_poll(bContext *UNUSED(C),
wmDrag *drag,
const wmEvent *UNUSED(event),
- const char **UNUSED(tooltip))
+ const char **UNUSED(r_tooltip))
{
return (drag->type == WM_DRAG_PATH) && (drag->icon == ICON_FILE_VOLUME);
}
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 8af651c7309..694cb7ee7d4 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -881,7 +881,7 @@ void ED_view3d_draw_depth(Depsgraph *depsgraph, ARegion *region, View3D *v3d, bo
/* ******************** other elements ***************** */
/** could move this elsewhere, but tied into #ED_view3d_grid_scale */
-float ED_scene_grid_scale(const Scene *scene, const char **grid_unit)
+float ED_scene_grid_scale(const Scene *scene, const char **r_grid_unit)
{
/* apply units */
if (scene->unit.system) {
@@ -892,8 +892,8 @@ float ED_scene_grid_scale(const Scene *scene, const char **grid_unit)
if (usys) {
int i = bUnit_GetBaseUnit(usys);
- if (grid_unit) {
- *grid_unit = bUnit_GetNameDisplay(usys, i);
+ if (r_grid_unit) {
+ *r_grid_unit = bUnit_GetNameDisplay(usys, i);
}
return (float)bUnit_GetScaler(usys, i) / scene->unit.scale_length;
}
@@ -902,9 +902,9 @@ float ED_scene_grid_scale(const Scene *scene, const char **grid_unit)
return 1.0f;
}
-float ED_view3d_grid_scale(const Scene *scene, View3D *v3d, const char **grid_unit)
+float ED_view3d_grid_scale(const Scene *scene, View3D *v3d, const char **r_grid_unit)
{
- return v3d->grid * ED_scene_grid_scale(scene, grid_unit);
+ return v3d->grid * ED_scene_grid_scale(scene, r_grid_unit);
}
#define STEPS_LEN 8
@@ -958,7 +958,7 @@ void ED_view3d_grid_steps(const Scene *scene,
float ED_view3d_grid_view_scale(Scene *scene,
View3D *v3d,
RegionView3D *rv3d,
- const char **grid_unit)
+ const char **r_grid_unit)
{
float grid_scale;
if (!rv3d->is_persp && RV3D_VIEW_IS_AXIS(rv3d->view)) {
@@ -977,18 +977,18 @@ float ED_view3d_grid_view_scale(Scene *scene,
}
}
- if (grid_unit) {
+ if (r_grid_unit) {
const void *usys;
int len;
bUnit_GetSystem(scene->unit.system, B_UNIT_LENGTH, &usys, &len);
if (usys) {
- *grid_unit = bUnit_GetNameDisplay(usys, len - i - 1);
+ *r_grid_unit = bUnit_GetNameDisplay(usys, len - i - 1);
}
}
}
else {
- grid_scale = ED_view3d_grid_scale(scene, v3d, grid_unit);
+ grid_scale = ED_view3d_grid_scale(scene, v3d, r_grid_unit);
}
return grid_scale;
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index 67dacca85ba..e650f5581ff 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -627,14 +627,14 @@ void viewrotate_modal_keymap(wmKeyConfig *keyconf)
{0, NULL, 0, NULL, NULL},
};
- wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "View3D Rotate Modal");
+ wmKeyMap *keymap = WM_modalkeymap_find(keyconf, "View3D Rotate Modal");
/* this function is called for each spacetype, only needs to add map once */
if (keymap && keymap->modal_items) {
return;
}
- keymap = WM_modalkeymap_add(keyconf, "View3D Rotate Modal", modal_items);
+ keymap = WM_modalkeymap_ensure(keyconf, "View3D Rotate Modal", modal_items);
/* disabled mode switching for now, can re-implement better, later on */
#if 0
@@ -1702,14 +1702,14 @@ void viewmove_modal_keymap(wmKeyConfig *keyconf)
{0, NULL, 0, NULL, NULL},
};
- wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "View3D Move Modal");
+ wmKeyMap *keymap = WM_modalkeymap_find(keyconf, "View3D Move Modal");
/* this function is called for each spacetype, only needs to add map once */
if (keymap && keymap->modal_items) {
return;
}
- keymap = WM_modalkeymap_add(keyconf, "View3D Move Modal", modal_items);
+ keymap = WM_modalkeymap_ensure(keyconf, "View3D Move Modal", modal_items);
/* items for modal map */
WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, KM_ANY, 0, VIEW_MODAL_CONFIRM);
@@ -1901,14 +1901,14 @@ void viewzoom_modal_keymap(wmKeyConfig *keyconf)
{0, NULL, 0, NULL, NULL},
};
- wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "View3D Zoom Modal");
+ wmKeyMap *keymap = WM_modalkeymap_find(keyconf, "View3D Zoom Modal");
/* this function is called for each spacetype, only needs to add map once */
if (keymap && keymap->modal_items) {
return;
}
- keymap = WM_modalkeymap_add(keyconf, "View3D Zoom Modal", modal_items);
+ keymap = WM_modalkeymap_ensure(keyconf, "View3D Zoom Modal", modal_items);
/* disabled mode switching for now, can re-implement better, later on */
#if 0
@@ -2472,14 +2472,14 @@ void viewdolly_modal_keymap(wmKeyConfig *keyconf)
{0, NULL, 0, NULL, NULL},
};
- wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "View3D Dolly Modal");
+ wmKeyMap *keymap = WM_modalkeymap_find(keyconf, "View3D Dolly Modal");
/* this function is called for each spacetype, only needs to add map once */
if (keymap && keymap->modal_items) {
return;
}
- keymap = WM_modalkeymap_add(keyconf, "View3D Dolly Modal", modal_items);
+ keymap = WM_modalkeymap_ensure(keyconf, "View3D Dolly Modal", modal_items);
/* disabled mode switching for now, can re-implement better, later on */
#if 0
diff --git a/source/blender/editors/space_view3d/view3d_fly.c b/source/blender/editors/space_view3d/view3d_fly.c
index 563e1afa67e..06d1a033a0d 100644
--- a/source/blender/editors/space_view3d/view3d_fly.c
+++ b/source/blender/editors/space_view3d/view3d_fly.c
@@ -125,14 +125,14 @@ void fly_modal_keymap(wmKeyConfig *keyconf)
{0, NULL, 0, NULL, NULL},
};
- wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "View3D Fly Modal");
+ wmKeyMap *keymap = WM_modalkeymap_find(keyconf, "View3D Fly Modal");
/* this function is called for each spacetype, only needs to add map once */
if (keymap && keymap->modal_items) {
return;
}
- keymap = WM_modalkeymap_add(keyconf, "View3D Fly Modal", modal_items);
+ keymap = WM_modalkeymap_ensure(keyconf, "View3D Fly Modal", modal_items);
/* assign map to operators */
WM_modalkeymap_assign(keymap, "VIEW3D_OT_fly");
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index 6e1533e50fd..30587e6084d 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -1557,7 +1557,7 @@ void VIEW3D_OT_localview_remove_from(wmOperatorType *ot)
static uint free_localcollection_bit(Main *bmain,
unsigned short local_collections_uuid,
- bool *reset)
+ bool *r_reset)
{
ScrArea *sa;
bScreen *sc;
@@ -1587,7 +1587,7 @@ static uint free_localcollection_bit(Main *bmain,
/* Otherwise get the first free available. */
for (int i = 0; i < 16; i++) {
if ((local_view_bits & (1 << i)) == 0) {
- *reset = true;
+ *r_reset = true;
return (1 << i);
}
}
diff --git a/source/blender/editors/space_view3d/view3d_walk.c b/source/blender/editors/space_view3d/view3d_walk.c
index 89b5618075a..8ee52756f27 100644
--- a/source/blender/editors/space_view3d/view3d_walk.c
+++ b/source/blender/editors/space_view3d/view3d_walk.c
@@ -160,14 +160,14 @@ void walk_modal_keymap(wmKeyConfig *keyconf)
{0, NULL, 0, NULL, NULL},
};
- wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "View3D Walk Modal");
+ wmKeyMap *keymap = WM_modalkeymap_find(keyconf, "View3D Walk Modal");
/* this function is called for each spacetype, only needs to add map once */
if (keymap && keymap->modal_items) {
return;
}
- keymap = WM_modalkeymap_add(keyconf, "View3D Walk Modal", modal_items);
+ keymap = WM_modalkeymap_ensure(keyconf, "View3D Walk Modal", modal_items);
/* assign map to operators */
WM_modalkeymap_assign(keymap, "VIEW3D_OT_walk");
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index 0ea355e9b6e..a9eaad6868e 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -770,9 +770,9 @@ wmKeyMap *transform_modal_keymap(wmKeyConfig *keyconf)
{0, NULL, 0, NULL, NULL},
};
- wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "Transform Modal Map");
+ wmKeyMap *keymap = WM_modalkeymap_find(keyconf, "Transform Modal Map");
- keymap = WM_modalkeymap_add(keyconf, "Transform Modal Map", modal_items);
+ keymap = WM_modalkeymap_ensure(keyconf, "Transform Modal Map", modal_items);
keymap->poll_modal_item = transform_modal_item_poll;
return keymap;
diff --git a/source/blender/editors/transform/transform_convert.c b/source/blender/editors/transform/transform_convert.c
index 09ee9081baf..1049db74a75 100644
--- a/source/blender/editors/transform/transform_convert.c
+++ b/source/blender/editors/transform/transform_convert.c
@@ -96,7 +96,9 @@ void transform_around_single_fallback(TransInfo *t)
}
}
-/* ************************** Functions *************************** */
+/* -------------------------------------------------------------------- */
+/** \name Proportional Editing
+ * \{ */
static int trans_data_compare_dist(const void *a, const void *b)
{
@@ -333,7 +335,11 @@ static void set_prop_dist(TransInfo *t, const bool with_dist)
MEM_freeN(td_table);
}
-/* ********************* pose mode ************* */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Pose Mode
+ * \{ */
static short apply_targetless_ik(Object *ob)
{
@@ -453,15 +459,20 @@ int count_set_pose_transflags(Object *ob,
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
bone = pchan->bone;
- bone->flag &= ~(BONE_TRANSFORM | BONE_TRANSFORM_MIRROR);
if (PBONE_VISIBLE(arm, bone)) {
if ((bone->flag & BONE_SELECTED)) {
bone->flag |= BONE_TRANSFORM;
}
+ else {
+ bone->flag &= ~BONE_TRANSFORM;
+ }
bone->flag &= ~BONE_HINGE_CHILD_TRANSFORM;
bone->flag &= ~BONE_TRANSFORM_CHILD;
}
+ else {
+ bone->flag &= ~BONE_TRANSFORM;
+ }
}
/* make sure no bone can be transformed when a parent is transformed */
@@ -506,7 +517,11 @@ int count_set_pose_transflags(Object *ob,
return total;
}
-/* -------- Auto-IK ---------- */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Pose Mode (Auto-IK)
+ * \{ */
/* adjust pose-channel's auto-ik chainlen */
static bool pchan_autoik_adjust(bPoseChannel *pchan, short chainlen)
@@ -631,7 +646,11 @@ static void pose_grab_with_ik_clear(Main *bmain, Object *ob)
}
}
-/* ********************* curve/surface ********* */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Curve Surface
+ * \{ */
void calc_distanceCurveVerts(TransData *head, TransData *tail)
{
@@ -701,7 +720,11 @@ TransDataCurveHandleFlags *initTransDataCurveHandles(TransData *td, struct BezTr
return hdata;
}
-/* ********************* UV ****************** */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name UV Coordinates
+ * \{ */
bool clipUVTransform(TransInfo *t, float vec[2], const bool resize)
{
@@ -787,7 +810,11 @@ void clipUVData(TransInfo *t)
}
}
-/* ********************* ANIMATION EDITORS (GENERAL) ************************* */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Animation Editors (General)
+ * \{ */
/**
* For modal operation: `t->center_global` may not have been set yet.
@@ -828,7 +855,11 @@ bool FrameOnMouseSide(char side, float frame, float cframe)
}
}
-/* ********************* ACTION EDITOR ****************** */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Animation Editor
+ * \{ */
static int masklay_shape_cmp_frame(void *thunk, const void *a, const void *b)
{
@@ -1088,7 +1119,11 @@ static void posttrans_action_clean(bAnimContext *ac, bAction *act)
ANIM_animdata_freelist(&anim_data);
}
-/* ********************* GRAPH EDITOR ************************* */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Graph Editor
+ * \{ */
/* struct for use in re-sorting BezTriples during Graph Editor transform */
typedef struct BeztMap {
@@ -1259,6 +1294,12 @@ static void beztmap_to_data(TransInfo *t, FCurve *fcu, BeztMap *bezms, int totve
MEM_freeN(adjusted);
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Transform Utilities
+ * \{ */
+
/* This function is called by recalcData during the Transform loop to recalculate
* the handles of curves and sort the keyframes so that the curves draw correctly.
* It is only called if some keyframes have moved out of order.
@@ -1297,8 +1338,6 @@ void remake_graph_transdata(TransInfo *t, ListBase *anim_data)
}
}
-/* *********************** Transform data ******************* */
-
/* Little helper function for ObjectToTransData used to give certain
* constraints (ChildOf, FollowPath, and others that may be added)
* inverse corrections for transform, so that they aren't in CrazySpace.
@@ -1384,6 +1423,12 @@ bool constraints_list_needinv(TransInfo *t, ListBase *list)
return false;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Transform (Auto-Keyframing)
+ * \{ */
+
/**
* Auto-keyframing feature - for objects
*
@@ -1541,147 +1586,156 @@ void autokeyframe_pose(bContext *C, Scene *scene, Object *ob, int tmode, short t
FCurve *fcu;
// TODO: this should probably be done per channel instead...
- if (autokeyframe_cfra_can_key(scene, id)) {
- ReportList *reports = CTX_wm_reports(C);
- ToolSettings *ts = scene->toolsettings;
- KeyingSet *active_ks = ANIM_scene_get_active_keyingset(scene);
- ListBase nla_cache = {NULL, NULL};
- float cfra = (float)CFRA;
- eInsertKeyFlags flag = 0;
+ if (!autokeyframe_cfra_can_key(scene, id)) {
+ /* tag channels that should have unkeyed data */
+ for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
+ if (pchan->bone->flag & BONE_TRANSFORM) {
+ /* tag this channel */
+ pchan->bone->flag |= BONE_UNKEYED;
+ }
+ }
+ return;
+ }
- /* flag is initialized from UserPref keyframing settings
- * - special exception for targetless IK - INSERTKEY_MATRIX keyframes should get
- * visual keyframes even if flag not set, as it's not that useful otherwise
- * (for quick animation recording)
- */
- flag = ANIM_get_keyframing_flags(scene, true);
+ ReportList *reports = CTX_wm_reports(C);
+ ToolSettings *ts = scene->toolsettings;
+ KeyingSet *active_ks = ANIM_scene_get_active_keyingset(scene);
+ ListBase nla_cache = {NULL, NULL};
+ float cfra = (float)CFRA;
+ eInsertKeyFlags flag = 0;
+
+ /* flag is initialized from UserPref keyframing settings
+ * - special exception for targetless IK - INSERTKEY_MATRIX keyframes should get
+ * visual keyframes even if flag not set, as it's not that useful otherwise
+ * (for quick animation recording)
+ */
+ flag = ANIM_get_keyframing_flags(scene, true);
- if (targetless_ik) {
- flag |= INSERTKEY_MATRIX;
+ if (targetless_ik) {
+ flag |= INSERTKEY_MATRIX;
+ }
+
+ for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
+ if ((pchan->bone->flag & BONE_TRANSFORM) == 0 &&
+ !((pose->flag & POSE_MIRROR_EDIT) && (pchan->bone->flag & BONE_TRANSFORM_MIRROR))) {
+ continue;
}
- for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
- if ((pchan->bone->flag & BONE_TRANSFORM) ||
- ((pose->flag & POSE_MIRROR_EDIT) && (pchan->bone->flag & BONE_TRANSFORM_MIRROR))) {
- ListBase dsources = {NULL, NULL};
-
- /* clear any 'unkeyed' flag it may have */
- pchan->bone->flag &= ~BONE_UNKEYED;
-
- /* add datasource override for the camera object */
- ANIM_relative_keyingset_add_source(&dsources, id, &RNA_PoseBone, pchan);
-
- /* only insert into active keyingset? */
- if (IS_AUTOKEY_FLAG(scene, ONLYKEYINGSET) && (active_ks)) {
- /* run the active Keying Set on the current datasource */
- ANIM_apply_keyingset(C, &dsources, NULL, active_ks, MODIFYKEY_MODE_INSERT, cfra);
- }
- /* only insert into available channels? */
- else if (IS_AUTOKEY_FLAG(scene, INSERTAVAIL)) {
- if (act) {
- for (fcu = act->curves.first; fcu; fcu = fcu->next) {
- /* only insert keyframes for this F-Curve if it affects the current bone */
- if (strstr(fcu->rna_path, "bones")) {
- char *pchanName = BLI_str_quoted_substrN(fcu->rna_path, "bones[");
-
- /* only if bone name matches too...
- * NOTE: this will do constraints too, but those are ok to do here too?
- */
- if (pchanName && STREQ(pchanName, pchan->name)) {
- insert_keyframe(bmain,
- reports,
- id,
- act,
- ((fcu->grp) ? (fcu->grp->name) : (NULL)),
- fcu->rna_path,
- fcu->array_index,
- cfra,
- ts->keyframe_type,
- &nla_cache,
- flag);
- }
-
- if (pchanName) {
- MEM_freeN(pchanName);
- }
- }
- }
- }
- }
- /* only insert keyframe if needed? */
- else if (IS_AUTOKEY_FLAG(scene, INSERTNEEDED)) {
- bool do_loc = false, do_rot = false, do_scale = false;
+ ListBase dsources = {NULL, NULL};
- /* Filter the conditions when this happens
- * (assume that 'curarea->spacetype == SPACE_VIEW3D'). */
- if (tmode == TFM_TRANSLATION) {
- if (targetless_ik) {
- do_rot = true;
- }
- else {
- do_loc = true;
- }
- }
- else if (ELEM(tmode, TFM_ROTATION, TFM_TRACKBALL)) {
- if (ELEM(scene->toolsettings->transform_pivot_point,
- V3D_AROUND_CURSOR,
- V3D_AROUND_ACTIVE)) {
- do_loc = true;
- }
+ /* clear any 'unkeyed' flag it may have */
+ pchan->bone->flag &= ~BONE_UNKEYED;
- if ((scene->toolsettings->transform_flag & SCE_XFORM_AXIS_ALIGN) == 0) {
- do_rot = true;
- }
- }
- else if (tmode == TFM_RESIZE) {
- if (ELEM(scene->toolsettings->transform_pivot_point,
- V3D_AROUND_CURSOR,
- V3D_AROUND_ACTIVE)) {
- do_loc = true;
- }
+ /* add datasource override for the camera object */
+ ANIM_relative_keyingset_add_source(&dsources, id, &RNA_PoseBone, pchan);
- if ((scene->toolsettings->transform_flag & SCE_XFORM_AXIS_ALIGN) == 0) {
- do_scale = true;
- }
+ /* only insert into active keyingset? */
+ if (IS_AUTOKEY_FLAG(scene, ONLYKEYINGSET) && (active_ks)) {
+ /* run the active Keying Set on the current datasource */
+ ANIM_apply_keyingset(C, &dsources, NULL, active_ks, MODIFYKEY_MODE_INSERT, cfra);
+ }
+ /* only insert into available channels? */
+ else if (IS_AUTOKEY_FLAG(scene, INSERTAVAIL)) {
+ if (act) {
+ for (fcu = act->curves.first; fcu; fcu = fcu->next) {
+ /* only insert keyframes for this F-Curve if it affects the current bone */
+ if (strstr(fcu->rna_path, "bones") == NULL) {
+ continue;
}
+ char *pchanName = BLI_str_quoted_substrN(fcu->rna_path, "bones[");
- if (do_loc) {
- KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_LOCATION_ID);
- ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
- }
- if (do_rot) {
- KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_ROTATION_ID);
- ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
+ /* only if bone name matches too...
+ * NOTE: this will do constraints too, but those are ok to do here too?
+ */
+ if (pchanName && STREQ(pchanName, pchan->name)) {
+ insert_keyframe(bmain,
+ reports,
+ id,
+ act,
+ ((fcu->grp) ? (fcu->grp->name) : (NULL)),
+ fcu->rna_path,
+ fcu->array_index,
+ cfra,
+ ts->keyframe_type,
+ &nla_cache,
+ flag);
}
- if (do_scale) {
- KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_SCALING_ID);
- ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
+
+ if (pchanName) {
+ MEM_freeN(pchanName);
}
}
- /* insert keyframe in all (transform) channels */
+ }
+ }
+ /* only insert keyframe if needed? */
+ else if (IS_AUTOKEY_FLAG(scene, INSERTNEEDED)) {
+ bool do_loc = false, do_rot = false, do_scale = false;
+
+ /* Filter the conditions when this happens
+ * (assume that 'curarea->spacetype == SPACE_VIEW3D'). */
+ if (tmode == TFM_TRANSLATION) {
+ if (targetless_ik) {
+ do_rot = true;
+ }
else {
- KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_LOC_ROT_SCALE_ID);
- ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
+ do_loc = true;
+ }
+ }
+ else if (ELEM(tmode, TFM_ROTATION, TFM_TRACKBALL)) {
+ if (ELEM(scene->toolsettings->transform_pivot_point,
+ V3D_AROUND_CURSOR,
+ V3D_AROUND_ACTIVE)) {
+ do_loc = true;
}
- /* free temp info */
- BLI_freelistN(&dsources);
+ if ((scene->toolsettings->transform_flag & SCE_XFORM_AXIS_ALIGN) == 0) {
+ do_rot = true;
+ }
}
- }
+ else if (tmode == TFM_RESIZE) {
+ if (ELEM(scene->toolsettings->transform_pivot_point,
+ V3D_AROUND_CURSOR,
+ V3D_AROUND_ACTIVE)) {
+ do_loc = true;
+ }
- BKE_animsys_free_nla_keyframing_context_cache(&nla_cache);
- }
- else {
- /* tag channels that should have unkeyed data */
- for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
- if (pchan->bone->flag & BONE_TRANSFORM) {
- /* tag this channel */
- pchan->bone->flag |= BONE_UNKEYED;
+ if ((scene->toolsettings->transform_flag & SCE_XFORM_AXIS_ALIGN) == 0) {
+ do_scale = true;
+ }
+ }
+
+ if (do_loc) {
+ KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_LOCATION_ID);
+ ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
+ }
+ if (do_rot) {
+ KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_ROTATION_ID);
+ ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
+ }
+ if (do_scale) {
+ KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_SCALING_ID);
+ ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
}
}
+ /* insert keyframe in all (transform) channels */
+ else {
+ KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_LOC_ROT_SCALE_ID);
+ ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
+ }
+
+ /* free temp info */
+ BLI_freelistN(&dsources);
}
+
+ BKE_animsys_free_nla_keyframing_context_cache(&nla_cache);
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Transform (After-Transform Update)
+ * \{ */
+
/* Return if we need to update motion paths, only if they already exist,
* and we will insert a keyframe at the end of transform. */
bool motionpath_need_update_pose(Scene *scene, Object *ob)
@@ -2383,6 +2437,10 @@ int special_transform_moving(TransInfo *t)
/** \} */
+/* -------------------------------------------------------------------- */
+/** \name Transform Data Create
+ * \{ */
+
static int countAndCleanTransDataContainer(TransInfo *t)
{
BLI_assert(ELEM(t->data_len_all, 0, -1));
@@ -2777,3 +2835,5 @@ void createTransData(bContext *C, TransInfo *t)
BLI_assert((!(t->flag & T_EDIT)) == (!(t->obedit_type != -1)));
}
+
+/** \} */
diff --git a/source/blender/editors/transform/transform_convert_armature.c b/source/blender/editors/transform/transform_convert_armature.c
index 4e8e0cc2369..53dd54d4b53 100644
--- a/source/blender/editors/transform/transform_convert_armature.c
+++ b/source/blender/editors/transform/transform_convert_armature.c
@@ -530,6 +530,12 @@ void pose_transform_mirror_update(TransInfo *t, TransDataContainer *tc, Object *
unit_m4(flip_mtx);
flip_mtx[0][0] = -1;
+ for (bPoseChannel *pchan_orig = ob->pose->chanbase.first; pchan_orig;
+ pchan_orig = pchan_orig->next) {
+ /* Clear the MIRROR flag from previous runs. */
+ pchan_orig->bone->flag &= ~BONE_TRANSFORM_MIRROR;
+ }
+
bPose *pose = ob->pose;
PoseInitData_Mirror *pid = NULL;
if ((t->mode != TFM_BONESIZE) && (pose->flag & POSE_MIRROR_RELATIVE)) {
@@ -565,6 +571,9 @@ void pose_transform_mirror_update(TransInfo *t, TransDataContainer *tc, Object *
}
BKE_pchan_apply_mat4(pchan, pchan_mtx_final, false);
+ /* Set flag to let autokeyframe know to keyframe the mirrred bone. */
+ pchan->bone->flag |= BONE_TRANSFORM_MIRROR;
+
/* In this case we can do target-less IK grabbing. */
if (t->mode == TFM_TRANSLATION) {
bKinematicConstraint *data = has_targetless_ik(pchan);
diff --git a/source/blender/editors/transform/transform_convert_sequencer.c b/source/blender/editors/transform/transform_convert_sequencer.c
index f6dc9b9c412..f2d0f4dfc43 100644
--- a/source/blender/editors/transform/transform_convert_sequencer.c
+++ b/source/blender/editors/transform/transform_convert_sequencer.c
@@ -47,7 +47,7 @@
* seq->depth must be set before running this function so we know if the strips
* are root level or not
*/
-static void SeqTransInfo(TransInfo *t, Sequence *seq, int *recursive, int *count, int *flag)
+static void SeqTransInfo(TransInfo *t, Sequence *seq, int *r_recursive, int *r_count, int *r_flag)
{
/* for extend we need to do some tricks */
if (t->mode == TFM_TIME_EXTEND) {
@@ -60,51 +60,51 @@ static void SeqTransInfo(TransInfo *t, Sequence *seq, int *recursive, int *count
int right = BKE_sequence_tx_get_final_right(seq, true);
if (seq->depth == 0 && ((seq->flag & SELECT) == 0 || (seq->flag & SEQ_LOCK))) {
- *recursive = false;
- *count = 0;
- *flag = 0;
+ *r_recursive = false;
+ *r_count = 0;
+ *r_flag = 0;
}
else if (seq->type == SEQ_TYPE_META) {
/* for meta's we only ever need to extend their children, no matter what depth
* just check the meta's are in the bounds */
if (t->frame_side == 'R' && right <= cfra) {
- *recursive = false;
+ *r_recursive = false;
}
else if (t->frame_side == 'L' && left >= cfra) {
- *recursive = false;
+ *r_recursive = false;
}
else {
- *recursive = true;
+ *r_recursive = true;
}
- *count = 1;
- *flag = (seq->flag | SELECT) & ~(SEQ_LEFTSEL | SEQ_RIGHTSEL);
+ *r_count = 1;
+ *r_flag = (seq->flag | SELECT) & ~(SEQ_LEFTSEL | SEQ_RIGHTSEL);
}
else {
- *recursive = false; /* not a meta, so no thinking here */
- *count = 1; /* unless its set to 0, extend will never set 2 handles at once */
- *flag = (seq->flag | SELECT) & ~(SEQ_LEFTSEL | SEQ_RIGHTSEL);
+ *r_recursive = false; /* not a meta, so no thinking here */
+ *r_count = 1; /* unless its set to 0, extend will never set 2 handles at once */
+ *r_flag = (seq->flag | SELECT) & ~(SEQ_LEFTSEL | SEQ_RIGHTSEL);
if (t->frame_side == 'R') {
if (right <= cfra) {
- *count = *flag = 0;
+ *r_count = *r_flag = 0;
} /* ignore */
else if (left > cfra) {
} /* keep the selection */
else {
- *flag |= SEQ_RIGHTSEL;
+ *r_flag |= SEQ_RIGHTSEL;
}
}
else {
if (left >= cfra) {
- *count = *flag = 0;
+ *r_count = *r_flag = 0;
} /* ignore */
else if (right < cfra) {
} /* keep the selection */
else {
- *flag |= SEQ_LEFTSEL;
+ *r_flag |= SEQ_LEFTSEL;
}
}
}
@@ -121,28 +121,28 @@ static void SeqTransInfo(TransInfo *t, Sequence *seq, int *recursive, int *count
/* Non nested strips (resect selection and handles) */
if ((seq->flag & SELECT) == 0 || (seq->flag & SEQ_LOCK)) {
- *recursive = false;
- *count = 0;
- *flag = 0;
+ *r_recursive = false;
+ *r_count = 0;
+ *r_flag = 0;
}
else {
if ((seq->flag & (SEQ_LEFTSEL | SEQ_RIGHTSEL)) == (SEQ_LEFTSEL | SEQ_RIGHTSEL)) {
- *flag = seq->flag;
- *count = 2; /* we need 2 transdata's */
+ *r_flag = seq->flag;
+ *r_count = 2; /* we need 2 transdata's */
}
else {
- *flag = seq->flag;
- *count = 1; /* selected or with a handle selected */
+ *r_flag = seq->flag;
+ *r_count = 1; /* selected or with a handle selected */
}
/* Recursive */
if ((seq->type == SEQ_TYPE_META) && ((seq->flag & (SEQ_LEFTSEL | SEQ_RIGHTSEL)) == 0)) {
/* if any handles are selected, don't recurse */
- *recursive = true;
+ *r_recursive = true;
}
else {
- *recursive = false;
+ *r_recursive = false;
}
}
}
@@ -150,23 +150,23 @@ static void SeqTransInfo(TransInfo *t, Sequence *seq, int *recursive, int *count
/* Nested, different rules apply */
#ifdef SEQ_TX_NESTED_METAS
- *flag = (seq->flag | SELECT) & ~(SEQ_LEFTSEL | SEQ_RIGHTSEL);
- *count = 1; /* ignore the selection for nested */
- *recursive = (seq->type == SEQ_TYPE_META);
+ *r_flag = (seq->flag | SELECT) & ~(SEQ_LEFTSEL | SEQ_RIGHTSEL);
+ *r_count = 1; /* ignore the selection for nested */
+ *r_recursive = (seq->type == SEQ_TYPE_META);
#else
if (seq->type == SEQ_TYPE_META) {
/* Meta's can only directly be moved between channels since they
* don't have their start and length set directly (children affect that)
* since this Meta is nested we don't need any of its data in fact.
* BKE_sequence_calc() will update its settings when run on the top-level meta. */
- *flag = 0;
- *count = 0;
- *recursive = true;
+ *r_flag = 0;
+ *r_count = 0;
+ *r_recursive = true;
}
else {
- *flag = (seq->flag | SELECT) & ~(SEQ_LEFTSEL | SEQ_RIGHTSEL);
- *count = 1; /* ignore the selection for nested */
- *recursive = false;
+ *r_flag = (seq->flag | SELECT) & ~(SEQ_LEFTSEL | SEQ_RIGHTSEL);
+ *r_count = 1; /* ignore the selection for nested */
+ *r_recursive = false;
}
#endif
}
diff --git a/source/blender/editors/transform/transform_gizmo_2d.c b/source/blender/editors/transform/transform_gizmo_2d.c
index dce2625e8a1..e85b9f0bee1 100644
--- a/source/blender/editors/transform/transform_gizmo_2d.c
+++ b/source/blender/editors/transform/transform_gizmo_2d.c
@@ -300,7 +300,7 @@ static void gizmo2d_xform_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup
/* set up widget data */
RNA_float_set(gz->ptr, "length", 0.8f);
float axis[3] = {0.0f};
- axis[(i + 1) % 2] = 1.0f;
+ axis[i] = 1.0f;
WM_gizmo_set_matrix_rotation_from_z_axis(gz, axis);
float offset[3] = {0, 0, 0};
@@ -336,8 +336,8 @@ static void gizmo2d_xform_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup
/* Assign operator. */
PointerRNA *ptr = WM_gizmo_operator_set(gz, 0, ot_translate, NULL);
if (i < 2) {
- bool constraint[3] = {0};
- constraint[(i + 1) % 2] = 1;
+ bool constraint[3] = {false};
+ constraint[i] = true;
if (RNA_struct_find_property(ptr, "constraint_axis")) {
RNA_boolean_set_array(ptr, "constraint_axis", constraint);
}
diff --git a/source/blender/editors/transform/transform_input.c b/source/blender/editors/transform/transform_input.c
index 75463dcb7db..078020e932e 100644
--- a/source/blender/editors/transform/transform_input.c
+++ b/source/blender/editors/transform/transform_input.c
@@ -35,13 +35,17 @@
#include "MEM_guardedalloc.h"
-/* ************************** INPUT FROM MOUSE *************************** */
+/* -------------------------------------------------------------------- */
+/** \name Callbacks for #MouseInput.apply
+ * \{ */
+/** Callback for #INPUT_VECTOR */
static void InputVector(TransInfo *t, MouseInput *mi, const double mval[2], float output[3])
{
convertViewVec(t, output, mval[0] - mi->imval[0], mval[1] - mi->imval[1]);
}
+/** Callback for #INPUT_SPRING */
static void InputSpring(TransInfo *UNUSED(t),
MouseInput *mi,
const double mval[2],
@@ -57,6 +61,7 @@ static void InputSpring(TransInfo *UNUSED(t),
output[0] = ratio;
}
+/** Callback for #INPUT_SPRING_FLIP */
static void InputSpringFlip(TransInfo *t, MouseInput *mi, const double mval[2], float output[3])
{
InputSpring(t, mi, mval, output);
@@ -70,12 +75,14 @@ static void InputSpringFlip(TransInfo *t, MouseInput *mi, const double mval[2],
}
}
+/** Callback for #INPUT_SPRING_DELTA */
static void InputSpringDelta(TransInfo *t, MouseInput *mi, const double mval[2], float output[3])
{
InputSpring(t, mi, mval, output);
output[0] -= 1.0f;
}
+/** Callback for #INPUT_TRACKBALL */
static void InputTrackBall(TransInfo *UNUSED(t),
MouseInput *mi,
const double mval[2],
@@ -88,6 +95,7 @@ static void InputTrackBall(TransInfo *UNUSED(t),
output[1] *= mi->factor;
}
+/** Callback for #INPUT_HORIZONTAL_RATIO */
static void InputHorizontalRatio(TransInfo *t,
MouseInput *mi,
const double mval[2],
@@ -98,6 +106,7 @@ static void InputHorizontalRatio(TransInfo *t,
output[0] = ((mval[0] - mi->imval[0]) / winx) * 2.0f;
}
+/** Callback for #INPUT_HORIZONTAL_ABSOLUTE */
static void InputHorizontalAbsolute(TransInfo *t,
MouseInput *mi,
const double mval[2],
@@ -119,6 +128,7 @@ static void InputVerticalRatio(TransInfo *t, MouseInput *mi, const double mval[2
output[0] = ((mval[1] - mi->imval[1]) / winy) * -2.0f;
}
+/** Callback for #INPUT_VERTICAL_ABSOLUTE */
static void InputVerticalAbsolute(TransInfo *t,
MouseInput *mi,
const double mval[2],
@@ -133,38 +143,7 @@ static void InputVerticalAbsolute(TransInfo *t,
output[0] = dot_v3v3(t->viewinv[1], vec) * -2.0f;
}
-void setCustomPoints(TransInfo *UNUSED(t),
- MouseInput *mi,
- const int mval_start[2],
- const int mval_end[2])
-{
- int *data;
-
- mi->data = MEM_reallocN(mi->data, sizeof(int) * 4);
-
- data = mi->data;
-
- data[0] = mval_start[0];
- data[1] = mval_start[1];
- data[2] = mval_end[0];
- data[3] = mval_end[1];
-}
-
-void setCustomPointsFromDirection(TransInfo *t, MouseInput *mi, const float dir[2])
-{
- BLI_ASSERT_UNIT_V2(dir);
- const int win_axis = t->region ? ((abs((int)(t->region->winx * dir[0])) +
- abs((int)(t->region->winy * dir[1]))) /
- 2) :
- 1;
- const int mval_start[2] = {
- mi->imval[0] + dir[0] * win_axis,
- mi->imval[1] + dir[1] * win_axis,
- };
- const int mval_end[2] = {mi->imval[0], mi->imval[1]};
- setCustomPoints(t, mi, mval_start, mval_end);
-}
-
+/** Callback for #INPUT_CUSTOM_RATIO_FLIP */
static void InputCustomRatioFlip(TransInfo *UNUSED(t),
MouseInput *mi,
const double mval[2],
@@ -191,6 +170,7 @@ static void InputCustomRatioFlip(TransInfo *UNUSED(t),
}
}
+/** Callback for #INPUT_CUSTOM_RATIO */
static void InputCustomRatio(TransInfo *t, MouseInput *mi, const double mval[2], float output[3])
{
InputCustomRatioFlip(t, mi, mval, output);
@@ -202,6 +182,7 @@ struct InputAngle_Data {
double mval_prev[2];
};
+/** Callback for #INPUT_ANGLE */
static void InputAngle(TransInfo *UNUSED(t), MouseInput *mi, const double mval[2], float output[3])
{
struct InputAngle_Data *data = mi->data;
@@ -270,6 +251,53 @@ static void InputAngleSpring(TransInfo *t, MouseInput *mi, const double mval[2],
output[1] = toutput[0];
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Custom 2D Start/End Coordinate API
+ *
+ * - #INPUT_CUSTOM_RATIO
+ * - #INPUT_CUSTOM_RATIO_FLIP
+ * \{ */
+
+void setCustomPoints(TransInfo *UNUSED(t),
+ MouseInput *mi,
+ const int mval_start[2],
+ const int mval_end[2])
+{
+ int *data;
+
+ mi->data = MEM_reallocN(mi->data, sizeof(int) * 4);
+
+ data = mi->data;
+
+ data[0] = mval_start[0];
+ data[1] = mval_start[1];
+ data[2] = mval_end[0];
+ data[3] = mval_end[1];
+}
+
+void setCustomPointsFromDirection(TransInfo *t, MouseInput *mi, const float dir[2])
+{
+ BLI_ASSERT_UNIT_V2(dir);
+ const int win_axis = t->region ? ((abs((int)(t->region->winx * dir[0])) +
+ abs((int)(t->region->winy * dir[1]))) /
+ 2) :
+ 1;
+ const int mval_start[2] = {
+ mi->imval[0] + dir[0] * win_axis,
+ mi->imval[1] + dir[1] * win_axis,
+ };
+ const int mval_end[2] = {mi->imval[0], mi->imval[1]};
+ setCustomPoints(t, mi, mval_start, mval_end);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Setup & Handle Mouse Input
+ * \{ */
+
void initMouseInput(TransInfo *UNUSED(t),
MouseInput *mi,
const float center[2],
@@ -494,3 +522,5 @@ eRedrawFlag handleMouseInput(TransInfo *t, MouseInput *mi, const wmEvent *event)
return redraw;
}
+
+/** \} */
diff --git a/source/blender/editors/transform/transform_mode.c b/source/blender/editors/transform/transform_mode.c
index 326fb791de3..31aae4f5b05 100644
--- a/source/blender/editors/transform/transform_mode.c
+++ b/source/blender/editors/transform/transform_mode.c
@@ -61,7 +61,9 @@ bool transdata_check_local_center(TransInfo *t, short around)
(t->options & (CTX_MOVIECLIP | CTX_MASK | CTX_PAINT_CURVE))));
}
-/* ************************** TRANSFORM LOCKS **************************** */
+/* -------------------------------------------------------------------- */
+/** \name Transform Locks
+ * \{ */
void protectedTransBits(short protectflag, float vec[3])
{
@@ -211,7 +213,11 @@ static void protectedSizeBits(short protectflag, float size[3])
}
}
-/* ******************* TRANSFORM LIMITS ********************** */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Transform Limits
+ * \{ */
void constraintTransLim(TransInfo *t, TransData *td)
{
@@ -1104,9 +1110,7 @@ void doAnimEdit_SnapFrame(
/** \} */
/* -------------------------------------------------------------------- */
-/* Transform Mode API */
-
-/** \name Transform Frame Utils
+/** \name Transform Mode Initialization
* \{ */
void transform_mode_init(TransInfo *t, wmOperator *op, const int mode)
diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c
index aaf7fbc3108..7e56b34af2f 100644
--- a/source/blender/editors/transform/transform_ops.c
+++ b/source/blender/editors/transform/transform_ops.c
@@ -1031,7 +1031,7 @@ static void TRANSFORM_OT_bbone_resize(struct wmOperatorType *ot)
ot->exec = transform_exec;
ot->modal = transform_modal;
ot->cancel = transform_cancel;
- ot->poll = ED_operator_screenactive;
+ ot->poll = ED_operator_editarmature;
ot->poll_property = transform_poll_property;
RNA_def_float_translation(
diff --git a/source/blender/editors/util/numinput.c b/source/blender/editors/util/numinput.c
index 3c0d0beebe3..be1319c37dd 100644
--- a/source/blender/editors/util/numinput.c
+++ b/source/blender/editors/util/numinput.c
@@ -340,6 +340,21 @@ bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event)
}
}
+#ifdef USE_FAKE_EDIT
+ /* XXX Hack around keyboards without direct access to '=' nor '*'... */
+ if (ELEM(event->ascii, '=', '*')) {
+ if (!(n->flag & NUM_EDIT_FULL)) {
+ n->flag |= NUM_EDIT_FULL;
+ n->val_flag[idx] |= NUM_EDITED;
+ return true;
+ }
+ else if (event->ctrl) {
+ n->flag &= ~NUM_EDIT_FULL;
+ return true;
+ }
+ }
+#endif
+
switch (event->type) {
case EVT_MODAL_MAP:
if (ELEM(event->val, NUM_MODAL_INCREMENT_UP, NUM_MODAL_INCREMENT_DOWN)) {
@@ -523,21 +538,6 @@ bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event)
ascii[0] = event->ascii;
}
-#ifdef USE_FAKE_EDIT
- /* XXX Hack around keyboards without direct access to '=' nor '*'... */
- if (ELEM(ascii[0], '=', '*')) {
- if (!(n->flag & NUM_EDIT_FULL)) {
- n->flag |= NUM_EDIT_FULL;
- n->val_flag[idx] |= NUM_EDITED;
- return true;
- }
- else if (event->ctrl) {
- n->flag &= ~NUM_EDIT_FULL;
- return true;
- }
- }
-#endif
-
/* Up to this point, if we have a ctrl modifier, skip.
* This allows to still access most of modals' shortcuts even in numinput mode.
*/
diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c
index e3504e20464..1e576f6fea4 100644
--- a/source/blender/editors/uvedit/uvedit_draw.c
+++ b/source/blender/editors/uvedit/uvedit_draw.c
@@ -478,9 +478,9 @@ static void draw_uvs(SpaceImage *sima,
}
static void draw_uv_shadows_get(
- SpaceImage *sima, Object *ob, Object *obedit, bool *show_shadow, bool *show_texpaint)
+ SpaceImage *sima, Object *ob, Object *obedit, bool *r_show_shadow, bool *r_show_texpaint)
{
- *show_shadow = *show_texpaint = false;
+ *r_show_shadow = *r_show_texpaint = false;
if (ED_space_image_show_render(sima) || (sima->flag & SI_NO_DRAW_TEXPAINT)) {
return;
@@ -489,10 +489,10 @@ static void draw_uv_shadows_get(
if ((sima->mode == SI_MODE_PAINT) && obedit && obedit->type == OB_MESH) {
struct BMEditMesh *em = BKE_editmesh_from_object(obedit);
- *show_shadow = EDBM_uv_check(em);
+ *r_show_shadow = EDBM_uv_check(em);
}
- *show_texpaint = (ob && ob->type == OB_MESH && ob->mode == OB_MODE_TEXTURE_PAINT);
+ *r_show_texpaint = (ob && ob->type == OB_MESH && ob->mode == OB_MODE_TEXTURE_PAINT);
}
void ED_uvedit_draw_main(SpaceImage *sima,
diff --git a/source/blender/editors/uvedit/uvedit_parametrizer.c b/source/blender/editors/uvedit/uvedit_parametrizer.c
index 5a36c83b62e..936ba750266 100644
--- a/source/blender/editors/uvedit/uvedit_parametrizer.c
+++ b/source/blender/editors/uvedit/uvedit_parametrizer.c
@@ -347,7 +347,7 @@ static PHashLink *phash_next(PHash *ph, PHashKey key, PHashLink *link)
/* Geometry */
-static float p_vec_angle_cos(float *v1, float *v2, float *v3)
+static float p_vec_angle_cos(const float v1[3], const float v2[3], const float v3[3])
{
float d1[3], d2[3];
@@ -365,7 +365,7 @@ static float p_vec_angle_cos(float *v1, float *v2, float *v3)
return d1[0] * d2[0] + d1[1] * d2[1] + d1[2] * d2[2];
}
-static float p_vec_angle(float *v1, float *v2, float *v3)
+static float p_vec_angle(const float v1[3], const float v2[3], const float v3[3])
{
float dot = p_vec_angle_cos(v1, v2, v3);
@@ -380,7 +380,7 @@ static float p_vec_angle(float *v1, float *v2, float *v3)
}
}
-static float p_vec2_angle(float *v1, float *v2, float *v3)
+static float p_vec2_angle(const float v1[2], const float v2[2], const float v3[2])
{
float u1[3], u2[3], u3[3];
@@ -397,19 +397,20 @@ static float p_vec2_angle(float *v1, float *v2, float *v3)
return p_vec_angle(u1, u2, u3);
}
-static void p_triangle_angles(float *v1, float *v2, float *v3, float *a1, float *a2, float *a3)
+static void p_triangle_angles(
+ const float v1[3], const float v2[3], const float v3[3], float *r_a1, float *r_a2, float *r_a3)
{
- *a1 = p_vec_angle(v3, v1, v2);
- *a2 = p_vec_angle(v1, v2, v3);
- *a3 = (float)M_PI - *a2 - *a1;
+ *r_a1 = p_vec_angle(v3, v1, v2);
+ *r_a2 = p_vec_angle(v1, v2, v3);
+ *r_a3 = (float)M_PI - *r_a2 - *r_a1;
}
-static void p_face_angles(PFace *f, float *a1, float *a2, float *a3)
+static void p_face_angles(PFace *f, float *r_a1, float *r_a2, float *r_a3)
{
PEdge *e1 = f->edge, *e2 = e1->next, *e3 = e2->next;
PVert *v1 = e1->vert, *v2 = e2->vert, *v3 = e3->vert;
- p_triangle_angles(v1->co, v2->co, v3->co, a1, a2, a3);
+ p_triangle_angles(v1->co, v2->co, v3->co, r_a1, r_a2, r_a3);
}
static float p_face_area(PFace *f)
@@ -420,7 +421,7 @@ static float p_face_area(PFace *f)
return area_tri_v3(v1->co, v2->co, v3->co);
}
-static float p_area_signed(float *v1, float *v2, float *v3)
+static float p_area_signed(const float v1[2], const float v2[2], const float v3[2])
{
return 0.5f * (((v2[0] - v1[0]) * (v3[1] - v1[1])) - ((v3[0] - v1[0]) * (v2[1] - v1[1])));
}
@@ -527,7 +528,11 @@ static void UNUSED_FUNCTION(p_chart_uv_from_array)(PChart *chart, float (*points
}
}
-static PBool p_intersect_line_2d_dir(float *v1, float *dir1, float *v2, float *dir2, float *isect)
+static PBool p_intersect_line_2d_dir(const float v1[2],
+ const float dir1[2],
+ const float v2[2],
+ const float dir2[2],
+ float r_isect[2])
{
float lmbda, div;
@@ -538,14 +543,18 @@ static PBool p_intersect_line_2d_dir(float *v1, float *dir1, float *v2, float *d
}
lmbda = ((v1[1] - v2[1]) * dir1[0] - (v1[0] - v2[0]) * dir1[1]) / div;
- isect[0] = v1[0] + lmbda * dir2[0];
- isect[1] = v1[1] + lmbda * dir2[1];
+ r_isect[0] = v1[0] + lmbda * dir2[0];
+ r_isect[1] = v1[1] + lmbda * dir2[1];
return P_TRUE;
}
#if 0
-static PBool p_intersect_line_2d(float *v1, float *v2, float *v3, float *v4, float *isect)
+static PBool p_intersect_line_2d(const float v1[2],
+ const float v2[2],
+ const float v3[2],
+ const float v4[2],
+ const float r_isect[2])
{
float dir1[2], dir2[2];
@@ -892,7 +901,7 @@ static PBool p_edge_implicit_seam(PEdge *e, PEdge *ep)
return P_FALSE;
}
-static PBool p_edge_has_pair(PHandle *handle, PEdge *e, PEdge **pair, PBool impl)
+static PBool p_edge_has_pair(PHandle *handle, PEdge *e, PBool impl, PEdge **r_pair)
{
PHashKey key;
PEdge *pe;
@@ -906,7 +915,7 @@ static PBool p_edge_has_pair(PHandle *handle, PEdge *e, PEdge **pair, PBool impl
key = PHASH_edge(key1, key2);
pe = (PEdge *)phash_lookup(handle->hash_edges, key);
- *pair = NULL;
+ *r_pair = NULL;
while (pe) {
if (pe != e) {
@@ -917,34 +926,34 @@ static PBool p_edge_has_pair(PHandle *handle, PEdge *e, PEdge **pair, PBool impl
((v1->u.key == key2) && (v2->u.key == key1))) {
/* don't connect seams and t-junctions */
- if ((pe->flag & PEDGE_SEAM) || *pair || (impl && p_edge_implicit_seam(e, pe))) {
- *pair = NULL;
+ if ((pe->flag & PEDGE_SEAM) || *r_pair || (impl && p_edge_implicit_seam(e, pe))) {
+ *r_pair = NULL;
return P_FALSE;
}
- *pair = pe;
+ *r_pair = pe;
}
}
pe = (PEdge *)phash_next(handle->hash_edges, key, (PHashLink *)pe);
}
- if (*pair && (e->vert == (*pair)->vert)) {
- if ((*pair)->next->pair || (*pair)->next->next->pair) {
+ if (*r_pair && (e->vert == (*r_pair)->vert)) {
+ if ((*r_pair)->next->pair || (*r_pair)->next->next->pair) {
/* non unfoldable, maybe mobius ring or klein bottle */
- *pair = NULL;
+ *r_pair = NULL;
return P_FALSE;
}
}
- return (*pair != NULL);
+ return (*r_pair != NULL);
}
-static PBool p_edge_connect_pair(PHandle *handle, PEdge *e, PEdge ***stack, PBool impl)
+static PBool p_edge_connect_pair(PHandle *handle, PEdge *e, PBool impl, PEdge ***stack)
{
PEdge *pair = NULL;
- if (!e->pair && p_edge_has_pair(handle, e, &pair, impl)) {
+ if (!e->pair && p_edge_has_pair(handle, e, impl, &pair)) {
if (e->vert == pair->vert) {
p_face_flip(pair->face);
}
@@ -992,13 +1001,13 @@ static int p_connect_pairs(PHandle *handle, PBool impl)
/* assign verts to charts so we can sort them later */
f->u.chart = ncharts;
- if (!p_edge_connect_pair(handle, e, &stack, impl)) {
+ if (!p_edge_connect_pair(handle, e, impl, &stack)) {
e->vert->edge = e;
}
- if (!p_edge_connect_pair(handle, e1, &stack, impl)) {
+ if (!p_edge_connect_pair(handle, e1, impl, &stack)) {
e1->vert->edge = e1;
}
- if (!p_edge_connect_pair(handle, e2, &stack, impl)) {
+ if (!p_edge_connect_pair(handle, e2, impl, &stack)) {
e2->vert->edge = e2;
}
}
@@ -1255,16 +1264,16 @@ static PBool p_quad_split_direction(PHandle *handle, float **co, PHashKey *vkeys
/* Construction: boundary filling */
-static void p_chart_boundaries(PChart *chart, int *nboundaries, PEdge **outer)
+static void p_chart_boundaries(PChart *chart, int *r_nboundaries, PEdge **r_outer)
{
PEdge *e, *be;
float len, maxlen = -1.0;
- if (nboundaries) {
- *nboundaries = 0;
+ if (r_nboundaries) {
+ *r_nboundaries = 0;
}
- if (outer) {
- *outer = NULL;
+ if (r_outer) {
+ *r_outer = NULL;
}
for (e = chart->edges; e; e = e->nextlink) {
@@ -1272,8 +1281,8 @@ static void p_chart_boundaries(PChart *chart, int *nboundaries, PEdge **outer)
continue;
}
- if (nboundaries) {
- (*nboundaries)++;
+ if (r_nboundaries) {
+ (*r_nboundaries)++;
}
len = 0.0f;
@@ -1285,8 +1294,8 @@ static void p_chart_boundaries(PChart *chart, int *nboundaries, PEdge **outer)
be = be->next->vert->edge;
} while (be != e);
- if (outer && (len > maxlen)) {
- *outer = e;
+ if (r_outer && (len > maxlen)) {
+ *r_outer = e;
maxlen = len;
}
}
@@ -1427,7 +1436,7 @@ static void p_chart_fill_boundaries(PChart *chart, PEdge *outer)
#if 0
/* Polygon kernel for inserting uv's non overlapping */
-static int p_polygon_point_in(float *cp1, float *cp2, float *p)
+static int p_polygon_point_in(const float cp1[2], const float cp2[2], const float p[2])
{
if ((cp1[0] == p[0]) && (cp1[1] == p[1])) {
return 2;
@@ -1443,43 +1452,43 @@ static int p_polygon_point_in(float *cp1, float *cp2, float *p)
static void p_polygon_kernel_clip(float (*oldpoints)[2],
int noldpoints,
float (*newpoints)[2],
- int *nnewpoints,
- float *cp1,
- float *cp2)
+ int *r_nnewpoints,
+ const float cp1[2],
+ const float cp2[2])
{
float *p2, *p1, isect[2];
int i, p2in, p1in;
p1 = oldpoints[noldpoints - 1];
p1in = p_polygon_point_in(cp1, cp2, p1);
- *nnewpoints = 0;
+ *r_nnewpoints = 0;
for (i = 0; i < noldpoints; i++) {
p2 = oldpoints[i];
p2in = p_polygon_point_in(cp1, cp2, p2);
if ((p2in >= 2) || (p1in && p2in)) {
- newpoints[*nnewpoints][0] = p2[0];
- newpoints[*nnewpoints][1] = p2[1];
- (*nnewpoints)++;
+ newpoints[*r_nnewpoints][0] = p2[0];
+ newpoints[*r_nnewpoints][1] = p2[1];
+ (*r_nnewpoints)++;
}
else if (p1in && !p2in) {
if (p1in != 3) {
p_intersect_line_2d(p1, p2, cp1, cp2, isect);
- newpoints[*nnewpoints][0] = isect[0];
- newpoints[*nnewpoints][1] = isect[1];
- (*nnewpoints)++;
+ newpoints[*r_nnewpoints][0] = isect[0];
+ newpoints[*r_nnewpoints][1] = isect[1];
+ (*r_nnewpoints)++;
}
}
else if (!p1in && p2in) {
p_intersect_line_2d(p1, p2, cp1, cp2, isect);
- newpoints[*nnewpoints][0] = isect[0];
- newpoints[*nnewpoints][1] = isect[1];
- (*nnewpoints)++;
+ newpoints[*r_nnewpoints][0] = isect[0];
+ newpoints[*r_nnewpoints][1] = isect[1];
+ (*r_nnewpoints)++;
- newpoints[*nnewpoints][0] = p2[0];
- newpoints[*nnewpoints][1] = p2[1];
- (*nnewpoints)++;
+ newpoints[*r_nnewpoints][0] = p2[0];
+ newpoints[*r_nnewpoints][1] = p2[1];
+ (*r_nnewpoints)++;
}
p1in = p2in;
@@ -1556,7 +1565,7 @@ static void p_polygon_kernel_center(float (*points)[2], int npoints, float *cent
int NCOLLAPSE = 1;
int NCOLLAPSEX = 0;
-static float p_vert_cotan(float *v1, float *v2, float *v3)
+static float p_vert_cotan(const float v1[3], const float v2[3], const float v3[3])
{
float a[3], b[3], c[3], clen;
@@ -1733,16 +1742,16 @@ static void p_vert_fix_edge_pointer(PVert *v)
}
}
-static void p_collapsing_verts(PEdge *edge, PEdge *pair, PVert **newv, PVert **keepv)
+static void p_collapsing_verts(PEdge *edge, PEdge *pair, PVert **r_newv, PVert **r_keepv)
{
/* the two vertices that are involved in the collapse */
if (edge) {
- *newv = edge->vert;
- *keepv = edge->next->vert;
+ *r_newv = edge->vert;
+ *r_keepv = edge->next->vert;
}
else {
- *newv = pair->next->vert;
- *keepv = pair->vert;
+ *r_newv = pair->next->vert;
+ *r_keepv = pair->vert;
}
}
@@ -2107,20 +2116,20 @@ static float p_collapse_cost(PEdge *edge, PEdge *pair)
return cost;
}
-static void p_collapse_cost_vertex(PVert *vert, float *mincost, PEdge **mine)
+static void p_collapse_cost_vertex(PVert *vert, float *r_mincost, PEdge **r_mine)
{
PEdge *e, *enext, *pair;
- *mine = NULL;
- *mincost = 0.0f;
+ *r_mine = NULL;
+ *r_mincost = 0.0f;
e = vert->edge;
do {
if (p_collapse_allowed(e, e->pair)) {
float cost = p_collapse_cost(e, e->pair);
- if ((*mine == NULL) || (cost < *mincost)) {
- *mincost = cost;
- *mine = e;
+ if ((*r_mine == NULL) || (cost < *r_mincost)) {
+ *r_mincost = cost;
+ *r_mine = e;
}
}
@@ -2133,9 +2142,9 @@ static void p_collapse_cost_vertex(PVert *vert, float *mincost, PEdge **mine)
if (p_collapse_allowed(NULL, pair)) {
float cost = p_collapse_cost(NULL, pair);
- if ((*mine == NULL) || (cost < *mincost)) {
- *mincost = cost;
- *mine = pair;
+ if ((*r_mine == NULL) || (cost < *r_mincost)) {
+ *r_mincost = cost;
+ *r_mine = pair;
}
}
@@ -3549,7 +3558,7 @@ static int p_compare_geometric_uv(const void *a, const void *b)
}
}
-static PBool p_chart_convex_hull(PChart *chart, PVert ***verts, int *nverts, int *right)
+static PBool p_chart_convex_hull(PChart *chart, PVert ***r_verts, int *r_nverts, int *r_right)
{
/* Graham algorithm, taken from:
* http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/117225 */
@@ -3608,9 +3617,9 @@ static PBool p_chart_convex_hull(PChart *chart, PVert ***verts, int *nverts, int
*p = L[i];
}
- *verts = points;
- *nverts = npoints;
- *right = ulen - 1;
+ *r_verts = points;
+ *r_nverts = npoints;
+ *r_right = ulen - 1;
MEM_freeN(U);
MEM_freeN(L);
diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
index 84d38a88902..8ded2c16be8 100644
--- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c
+++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
@@ -77,6 +77,10 @@
#include "uvedit_intern.h"
#include "uvedit_parametrizer.h"
+/* -------------------------------------------------------------------- */
+/** \name Utility Functions
+ * \{ */
+
static void modifier_unwrap_state(Object *obedit, const Scene *scene, bool *r_use_subsurf)
{
ModifierData *md;
@@ -133,13 +137,21 @@ static bool ED_uvedit_ensure_uvs(Object *obedit)
return 1;
}
-/****************** Parametrizer Conversion ***************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Parametrizer Conversion
+ * \{ */
typedef struct UnwrapOptions {
- bool topology_from_uvs; /* Connectivity based on UV coordinates instead of seams. */
- bool only_selected; /* Only affect selected faces. */
- bool fill_holes; /* Fill holes to better preserve shape. */
- bool correct_aspect; /* Correct for mapped image texture aspect ratio. */
+ /** Connectivity based on UV coordinates instead of seams. */
+ bool topology_from_uvs;
+ /** Only affect selected faces. */
+ bool only_selected;
+ /** Fill holes to better preserve shape. */
+ bool fill_holes;
+ /** Correct for mapped image texture aspect ratio. */
+ bool correct_aspect;
} UnwrapOptions;
static bool uvedit_have_selection(const Scene *scene, BMEditMesh *em, const UnwrapOptions *options)
@@ -199,7 +211,7 @@ static bool uvedit_have_selection_multi(const Scene *scene,
}
void ED_uvedit_get_aspect(
- const Scene *UNUSED(scene), Object *ob, BMesh *bm, float *aspx, float *aspy)
+ const Scene *UNUSED(scene), Object *ob, BMesh *bm, float *r_aspx, float *r_aspy)
{
bool sloppy = true;
bool selected = false;
@@ -211,11 +223,11 @@ void ED_uvedit_get_aspect(
if (efa) {
ED_object_get_active_image(ob, efa->mat_nr + 1, &ima, NULL, NULL, NULL);
- ED_image_get_uv_aspect(ima, NULL, aspx, aspy);
+ ED_image_get_uv_aspect(ima, NULL, r_aspx, r_aspy);
}
else {
- *aspx = 1.0f;
- *aspy = 1.0f;
+ *r_aspx = 1.0f;
+ *r_aspy = 1.0f;
}
}
@@ -410,21 +422,21 @@ static ParamHandle *construct_param_handle_multi(const Scene *scene,
return handle;
}
-static void texface_from_original_index(BMFace *efa,
+static void texface_from_original_index(const Scene *scene,
+ const int cd_loop_uv_offset,
+ BMFace *efa,
int index,
- float **uv,
- ParamBool *pin,
- ParamBool *select,
- const Scene *scene,
- const int cd_loop_uv_offset)
+ float **r_uv,
+ ParamBool *r_pin,
+ ParamBool *r_select)
{
BMLoop *l;
BMIter liter;
MLoopUV *luv;
- *uv = NULL;
- *pin = 0;
- *select = 1;
+ *r_uv = NULL;
+ *r_pin = 0;
+ *r_select = 1;
if (index == ORIGINDEX_NONE) {
return;
@@ -433,9 +445,9 @@ static void texface_from_original_index(BMFace *efa,
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
if (BM_elem_index_get(l->v) == index) {
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- *uv = luv->uv;
- *pin = (luv->flag & MLOOPUV_PINNED) ? 1 : 0;
- *select = uvedit_uv_select_test(scene, l, cd_loop_uv_offset);
+ *r_uv = luv->uv;
+ *r_pin = (luv->flag & MLOOPUV_PINNED) ? 1 : 0;
+ *r_select = uvedit_uv_select_test(scene, l, cd_loop_uv_offset);
break;
}
}
@@ -583,34 +595,34 @@ static ParamHandle *construct_param_handle_subsurfed(const Scene *scene,
/* This is where all the magic is done.
* If the vertex exists in the, we pass the original uv pointer to the solver, thus
* flushing the solution to the edit mesh. */
- texface_from_original_index(origFace,
+ texface_from_original_index(scene,
+ cd_loop_uv_offset,
+ origFace,
origVertIndices[mloop[0].v],
&uv[0],
&pin[0],
- &select[0],
- scene,
- cd_loop_uv_offset);
- texface_from_original_index(origFace,
+ &select[0]);
+ texface_from_original_index(scene,
+ cd_loop_uv_offset,
+ origFace,
origVertIndices[mloop[1].v],
&uv[1],
&pin[1],
- &select[1],
- scene,
- cd_loop_uv_offset);
- texface_from_original_index(origFace,
+ &select[1]);
+ texface_from_original_index(scene,
+ cd_loop_uv_offset,
+ origFace,
origVertIndices[mloop[2].v],
&uv[2],
&pin[2],
- &select[2],
- scene,
- cd_loop_uv_offset);
- texface_from_original_index(origFace,
+ &select[2]);
+ texface_from_original_index(scene,
+ cd_loop_uv_offset,
+ origFace,
origVertIndices[mloop[3].v],
&uv[3],
&pin[3],
- &select[3],
- scene,
- cd_loop_uv_offset);
+ &select[3]);
param_face_add(handle, key, 4, vkeys, co, uv, pin, select);
}
@@ -635,7 +647,11 @@ static ParamHandle *construct_param_handle_subsurfed(const Scene *scene,
return handle;
}
-/* ******************** Minimize Stretch operator **************** */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Minimize Stretch Operator
+ * \{ */
typedef struct MinStretch {
const Scene *scene;
@@ -908,7 +924,11 @@ void UV_OT_minimize_stretch(wmOperatorType *ot)
100);
}
-/* ******************** Pack Islands operator **************** */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Pack UV Islands Operator
+ * \{ */
static void uvedit_pack_islands(const Scene *scene, Object *ob, BMesh *bm)
{
@@ -1006,7 +1026,11 @@ void UV_OT_pack_islands(wmOperatorType *ot)
ot->srna, "margin", 0.001f, 0.0f, 1.0f, "Margin", "Space between islands", 0.0f, 1.0f);
}
-/* ******************** Average Islands Scale operator **************** */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Average UV Islands Scale Operator
+ * \{ */
static int average_islands_scale_exec(bContext *C, wmOperator *UNUSED(op))
{
@@ -1065,7 +1089,11 @@ void UV_OT_average_islands_scale(wmOperatorType *ot)
ot->poll = ED_operator_uvedit;
}
-/**************** Live Unwrap *****************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Live UV Unwrap
+ * \{ */
static struct {
ParamHandle **handles;
@@ -1144,7 +1172,11 @@ void ED_uvedit_live_unwrap_end(short cancel)
}
}
-/*************** UV Map Common Transforms *****************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name UV Map Common Transforms
+ * \{ */
#define VIEW_ON_EQUATOR 0
#define VIEW_ON_POLES 1
@@ -1427,7 +1459,18 @@ static void correct_uv_aspect(const Scene *scene, Object *ob, BMEditMesh *em)
}
}
-/******************** Map Clip & Correct ******************/
+#undef VIEW_ON_EQUATOR
+#undef VIEW_ON_POLES
+#undef ALIGN_TO_OBJECT
+
+#undef POLAR_ZX
+#undef POLAR_ZY
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name UV Map Clip & Correct
+ * \{ */
static void uv_map_clip_correct_properties(wmOperatorType *ot)
{
@@ -1542,7 +1585,11 @@ static void uv_map_clip_correct(const Scene *scene, Object *ob, wmOperator *op)
uv_map_clip_correct_multi(scene, &ob, 1, op);
}
-/* ******************** Unwrap operator **************** */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name UV Unwrap Operator
+ * \{ */
/* Assumes UV Map exists, doesn't run update funcs. */
static void uvedit_unwrap(const Scene *scene, Object *obedit, const UnwrapOptions *options)
@@ -1783,7 +1830,12 @@ void UV_OT_unwrap(wmOperatorType *ot)
ot->srna, "margin", 0.001f, 0.0f, 1.0f, "Margin", "Space between islands", 0.0f, 1.0f);
}
-/**************** Project From View operator **************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Project UV From View Operator
+ * \{ */
+
static int uv_from_view_exec(bContext *C, wmOperator *op);
static int uv_from_view_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
@@ -1969,7 +2021,11 @@ void UV_OT_project_from_view(wmOperatorType *ot)
uv_map_clip_correct_properties(ot);
}
-/********************** Reset operator ********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Reset UV Operator
+ * \{ */
static int reset_exec(bContext *C, wmOperator *UNUSED(op))
{
@@ -2017,7 +2073,11 @@ void UV_OT_reset(wmOperatorType *ot)
ot->poll = ED_operator_uvmap;
}
-/****************** Sphere Project operator ***************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Sphere UV Project Operator
+ * \{ */
static void uv_sphere_project(float target[2],
const float source[3],
@@ -2144,7 +2204,11 @@ void UV_OT_sphere_project(wmOperatorType *ot)
uv_map_clip_correct_properties(ot);
}
-/***************** Cylinder Project operator **************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Cylinder UV Project Operator
+ * \{ */
static void uv_cylinder_project(float target[2],
const float source[3],
@@ -2238,7 +2302,9 @@ void UV_OT_cylinder_project(wmOperatorType *ot)
uv_map_clip_correct_properties(ot);
}
-/******************* Cube Project operator ****************/
+/* -------------------------------------------------------------------- */
+/** \name Cube UV Project Operator
+ * \{ */
static void uvedit_unwrap_cube_project(BMesh *bm,
float cube_size,
@@ -2367,7 +2433,11 @@ void UV_OT_cube_project(wmOperatorType *ot)
uv_map_clip_correct_properties(ot);
}
-/************************* Simple UVs for texture painting *****************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Simple UVs for Texture Painting
+ * \{ */
void ED_uvedit_add_simple_uvs(Main *bmain, const Scene *scene, Object *ob)
{
@@ -2403,3 +2473,5 @@ void ED_uvedit_add_simple_uvs(Main *bmain, const Scene *scene, Object *ob)
scene->toolsettings->uv_flag |= UV_SYNC_SELECTION;
}
}
+
+/** \} */
diff --git a/source/blender/freestyle/FRS_freestyle.h b/source/blender/freestyle/FRS_freestyle.h
index dc8a0c79072..876f40b211f 100644
--- a/source/blender/freestyle/FRS_freestyle.h
+++ b/source/blender/freestyle/FRS_freestyle.h
@@ -48,9 +48,7 @@ void FRS_set_context(struct bContext *C);
int FRS_is_freestyle_enabled(struct ViewLayer *view_layer);
void FRS_init_stroke_renderer(struct Render *re);
void FRS_begin_stroke_rendering(struct Render *re);
-struct Render *FRS_do_stroke_rendering(struct Render *re,
- struct ViewLayer *view_layer,
- int render);
+void FRS_do_stroke_rendering(struct Render *re, struct ViewLayer *view_layer);
void FRS_end_stroke_rendering(struct Render *re);
void FRS_free_view_map_cache(void);
void FRS_composite_result(struct Render *re,
diff --git a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
index c88d5f24b5d..a61bad7cf8a 100644
--- a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
+++ b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
@@ -32,19 +32,19 @@ extern "C" {
#include "DNA_camera_types.h"
#include "DNA_collection_types.h"
-#include "DNA_listBase.h"
#include "DNA_linestyle_types.h"
+#include "DNA_listBase.h"
#include "DNA_material_types.h"
-#include "DNA_meshdata_types.h"
#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
-#include "DNA_screen_types.h"
#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
#include "BKE_collection.h"
#include "BKE_customdata.h"
-#include "BKE_idprop.h"
#include "BKE_global.h"
+#include "BKE_idprop.h"
#include "BKE_layer.h"
#include "BKE_lib_id.h" /* free_libblock */
#include "BKE_material.h"
@@ -76,7 +76,16 @@ const char *BlenderStrokeRenderer::uvNames[] = {"along_stroke", "along_stroke_ti
BlenderStrokeRenderer::BlenderStrokeRenderer(Render *re, int render_count) : StrokeRenderer()
{
- freestyle_bmain = re->freestyle_bmain;
+ freestyle_bmain = BKE_main_new();
+
+ /* We use the same window manager for freestyle bmain as
+ * real bmain uses. This is needed because freestyle's
+ * bmain could be used to tag scenes for update, which
+ * implies call of ED_render_scene_update in some cases
+ * and that function requires proper window manager
+ * to present (sergey)
+ */
+ freestyle_bmain->wm = re->main->wm;
// for stroke mesh generation
_width = re->winx;
@@ -170,50 +179,18 @@ BlenderStrokeRenderer::BlenderStrokeRenderer(Render *re, int render_count) : Str
BlenderStrokeRenderer::~BlenderStrokeRenderer()
{
- // The freestyle_scene object is not released here. Instead,
- // the scene is released in free_all_freestyle_renders() in
- // source/blender/render/intern/source/pipeline.c, after the
- // compositor has finished.
-
- // release objects and data blocks
- Base *base_next = NULL;
- ViewLayer *view_layer = (ViewLayer *)freestyle_scene->view_layers.first;
- for (Base *b = (Base *)view_layer->object_bases.first; b; b = base_next) {
- base_next = b->next;
- Object *ob = b->object;
- char *name = ob->id.name;
-#if 0
- if (G.debug & G_DEBUG_FREESTYLE) {
- cout << "removing " << name[0] << name[1] << ":" << (name + 2) << endl;
- }
-#endif
- switch (ob->type) {
- case OB_CAMERA:
- freestyle_scene->camera = NULL;
- ATTR_FALLTHROUGH;
- case OB_MESH:
- BKE_scene_collections_object_remove(freestyle_bmain, freestyle_scene, ob, true);
- break;
- default:
- cerr << "Warning: unexpected object in the scene: " << name[0] << name[1] << ":"
- << (name + 2) << endl;
- }
- }
-
- // release materials
- Link *lnk = (Link *)freestyle_bmain->materials.first;
-
- while (lnk) {
- Material *ma = (Material *)lnk;
- lnk = lnk->next;
- BKE_id_free(freestyle_bmain, ma);
- }
-
BLI_ghash_free(_nodetree_hash, NULL, NULL);
DEG_graph_free(freestyle_depsgraph);
FreeStrokeGroups();
+
+ /* detach the window manager from freestyle bmain (see comments
+ * in add_freestyle() for more detail)
+ */
+ BLI_listbase_clear(&freestyle_bmain->wm);
+
+ BKE_main_free(freestyle_bmain);
}
float BlenderStrokeRenderer::get_stroke_vertex_z(void) const
diff --git a/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp b/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
index 0877107a240..0f4263162a6 100644
--- a/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
+++ b/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
@@ -637,14 +637,8 @@ void FRS_begin_stroke_rendering(Render *re)
init_camera(re);
}
-Render *FRS_do_stroke_rendering(Render *re, ViewLayer *view_layer, int render)
+void FRS_do_stroke_rendering(Render *re, ViewLayer *view_layer)
{
- Render *freestyle_render = NULL;
-
- if (!render) {
- return controller->RenderStrokes(re, false);
- }
-
RenderMonitor monitor(re);
controller->setRenderMonitor(&monitor);
controller->setViewMapCache(
@@ -685,6 +679,7 @@ Render *FRS_do_stroke_rendering(Render *re, ViewLayer *view_layer, int render)
re->i.infostr = NULL;
g_freestyle.scene = DEG_get_evaluated_scene(depsgraph);
int strokeCount = controller->DrawStrokes();
+ Render *freestyle_render = NULL;
if (strokeCount > 0) {
freestyle_render = controller->RenderStrokes(re, true);
}
@@ -694,15 +689,12 @@ Render *FRS_do_stroke_rendering(Render *re, ViewLayer *view_layer, int render)
// composite result
if (freestyle_render) {
FRS_composite_result(re, view_layer, freestyle_render);
- RE_FreeRenderResult(freestyle_render->result);
- freestyle_render->result = NULL;
+ RE_FreeRender(freestyle_render);
}
}
}
DEG_graph_free(depsgraph);
-
- return freestyle_render;
}
void FRS_end_stroke_rendering(Render * /*re*/)
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c
index 3263b78ba85..435559f4881 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c
@@ -116,7 +116,7 @@ static void reduce_stroke_points(bGPDstroke *gps,
{
bGPDspoint *new_points = MEM_callocN(sizeof(bGPDspoint) * num_points, __func__);
MDeformVert *new_dvert = NULL;
- if (gps->dvert != NULL) {
+ if ((gps->dvert != NULL) && (num_points > 0)) {
new_dvert = MEM_callocN(sizeof(MDeformVert) * num_points, __func__);
}
@@ -130,7 +130,7 @@ static void reduce_stroke_points(bGPDstroke *gps,
{
/* copy over point data */
memcpy(new_points, gps->points, sizeof(bGPDspoint) * num_points);
- if (gps->dvert != NULL) {
+ if ((gps->dvert != NULL) && (num_points > 0)) {
memcpy(new_dvert, gps->dvert, sizeof(MDeformVert) * num_points);
/* free unused point weights */
@@ -151,7 +151,7 @@ static void reduce_stroke_points(bGPDstroke *gps,
/* copy over point data */
memcpy(new_points, gps->points + offset, sizeof(bGPDspoint) * num_points);
- if (gps->dvert != NULL) {
+ if ((gps->dvert != NULL) && (num_points > 0)) {
memcpy(new_dvert, gps->dvert + offset, sizeof(MDeformVert) * num_points);
/* free unused weights */
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index cf1d449ad3b..a8a0288f895 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -146,8 +146,6 @@ data_to_c_simple(shaders/gpu_shader_uniform_color_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_checker_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_diag_stripes_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_simple_lighting_frag.glsl SRC)
-data_to_c_simple(shaders/gpu_shader_simple_lighting_smooth_color_frag.glsl SRC)
-data_to_c_simple(shaders/gpu_shader_simple_lighting_smooth_color_alpha_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_flat_color_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_flat_color_alpha_test_0_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_flat_id_frag.glsl SRC)
@@ -165,7 +163,6 @@ data_to_c_simple(shaders/gpu_shader_2D_line_dashed_uniform_color_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_2D_line_dashed_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_2D_smooth_color_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_2D_smooth_color_frag.glsl SRC)
-data_to_c_simple(shaders/gpu_shader_2D_smooth_color_dithered_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_2D_image_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_2D_image_rect_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_2D_image_multi_rect_vert.glsl SRC)
@@ -179,16 +176,12 @@ data_to_c_simple(shaders/gpu_shader_image_modulate_alpha_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_image_alpha_color_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_image_color_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_image_varying_color_frag.glsl SRC)
-data_to_c_simple(shaders/gpu_shader_image_depth_linear_frag.glsl SRC)
-data_to_c_simple(shaders/gpu_shader_image_depth_copy_frag.glsl SRC)
-data_to_c_simple(shaders/gpu_shader_image_multisample_resolve_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_3D_image_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_3D_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_3D_normal_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_3D_flat_color_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_3D_line_dashed_uniform_color_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_3D_smooth_color_vert.glsl SRC)
-data_to_c_simple(shaders/gpu_shader_3D_normal_smooth_color_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_3D_smooth_color_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_3D_passthrough_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_3D_clipped_uniform_color_vert.glsl SRC)
diff --git a/source/blender/gpu/GPU_buffers.h b/source/blender/gpu/GPU_buffers.h
index 9d17b199722..9d91fd79137 100644
--- a/source/blender/gpu/GPU_buffers.h
+++ b/source/blender/gpu/GPU_buffers.h
@@ -113,7 +113,7 @@ struct GPUBatch *GPU_pbvh_buffers_batch_get(GPU_PBVH_Buffers *buffers, bool fast
short GPU_pbvh_buffers_material_index_get(GPU_PBVH_Buffers *buffers);
-bool GPU_pbvh_buffers_has_mask(GPU_PBVH_Buffers *buffers);
+bool GPU_pbvh_buffers_has_overlays(GPU_PBVH_Buffers *buffers);
#ifdef __cplusplus
}
diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h
index 334e295c636..bb26f5d41a3 100644
--- a/source/blender/gpu/GPU_shader.h
+++ b/source/blender/gpu/GPU_shader.h
@@ -107,10 +107,6 @@ typedef enum eGPUBuiltinShader {
GPU_SHADER_TEXT,
GPU_SHADER_KEYFRAME_DIAMOND,
GPU_SHADER_SIMPLE_LIGHTING,
- GPU_SHADER_SIMPLE_LIGHTING_FLAT_COLOR,
- GPU_SHADER_SIMPLE_LIGHTING_SMOOTH_COLOR,
- GPU_SHADER_SIMPLE_LIGHTING_SMOOTH_COLOR_ALPHA,
-
/* for simple 2D drawing */
/**
* Take a single color for all the vertices and a 2D position for each vertex.
@@ -133,7 +129,6 @@ typedef enum eGPUBuiltinShader {
* \param pos: in vec2
*/
GPU_SHADER_2D_SMOOTH_COLOR,
- GPU_SHADER_2D_SMOOTH_COLOR_DITHER,
GPU_SHADER_2D_IMAGE,
GPU_SHADER_2D_IMAGE_COLOR,
GPU_SHADER_2D_IMAGE_DESATURATE_COLOR,
@@ -141,14 +136,6 @@ typedef enum eGPUBuiltinShader {
GPU_SHADER_2D_IMAGE_ALPHA,
GPU_SHADER_2D_IMAGE_RECT_COLOR,
GPU_SHADER_2D_IMAGE_MULTI_RECT_COLOR,
- GPU_SHADER_2D_IMAGE_MULTISAMPLE_2,
- GPU_SHADER_2D_IMAGE_MULTISAMPLE_4,
- GPU_SHADER_2D_IMAGE_MULTISAMPLE_8,
- GPU_SHADER_2D_IMAGE_MULTISAMPLE_16,
- GPU_SHADER_2D_IMAGE_MULTISAMPLE_2_DEPTH_TEST,
- GPU_SHADER_2D_IMAGE_MULTISAMPLE_4_DEPTH_TEST,
- GPU_SHADER_2D_IMAGE_MULTISAMPLE_8_DEPTH_TEST,
- GPU_SHADER_2D_IMAGE_MULTISAMPLE_16_DEPTH_TEST,
GPU_SHADER_2D_CHECKER,
GPU_SHADER_2D_DIAG_STRIPES,
/* for simple 3D drawing */
@@ -159,8 +146,6 @@ typedef enum eGPUBuiltinShader {
* \param pos: in vec3
*/
GPU_SHADER_3D_UNIFORM_COLOR,
- /* Sets Z-depth to 1.0 (draw onto background). */
- GPU_SHADER_3D_UNIFORM_COLOR_BACKGROUND,
/**
* Take a 3D position and color for each vertex without color interpolation.
*
@@ -196,18 +181,6 @@ typedef enum eGPUBuiltinShader {
* \param pos: in vec3
*/
GPU_SHADER_3D_IMAGE_MODULATE_ALPHA,
- /**
- * Draw linearized depth texture relate to near and far distances.
- * Take a 3D position and a 2D texture coordinate for each vertex.
- *
- * \param znear: uniform float
- * \param zfar: uniform float
- * \param image: uniform sampler2D
- * \param texCoord: in vec2
- * \param pos: in vec3
- */
- GPU_SHADER_3D_IMAGE_DEPTH,
- GPU_SHADER_3D_IMAGE_DEPTH_COPY,
/* points */
/**
* Draw round points with a hardcoded size.
diff --git a/source/blender/gpu/GPU_shader_interface.h b/source/blender/gpu/GPU_shader_interface.h
index 8b0d25e51a3..7a8900997d0 100644
--- a/source/blender/gpu/GPU_shader_interface.h
+++ b/source/blender/gpu/GPU_shader_interface.h
@@ -88,6 +88,8 @@ typedef struct GPUShaderInterface {
char *name_buffer;
struct GPUBatch **batches; /* references to batches using this interface */
uint batches_len;
+ /** All enabled attribs in this shader. Used to set default values for unbound attribs. */
+ uint16_t enabled_attrib_mask;
} GPUShaderInterface;
GPUShaderInterface *GPU_shaderinterface_create(int32_t program_id);
diff --git a/source/blender/gpu/intern/gpu_batch.c b/source/blender/gpu/intern/gpu_batch.c
index 6bc3cd27130..fcfa4b7f0af 100644
--- a/source/blender/gpu/intern/gpu_batch.c
+++ b/source/blender/gpu/intern/gpu_batch.c
@@ -42,6 +42,8 @@
#include <stdlib.h>
#include <string.h>
+static GLuint g_default_attrib_vbo = 0;
+
static void batch_update_program_bindings(GPUBatch *batch, uint i_first);
void GPU_batch_vao_cache_clear(GPUBatch *batch)
@@ -414,6 +416,7 @@ void gpu_batch_remove_interface_ref(GPUBatch *batch, const GPUShaderInterface *i
static void create_bindings(GPUVertBuf *verts,
const GPUShaderInterface *interface,
+ uint16_t *attrib_mask,
uint v_first,
const bool use_instancing)
{
@@ -446,6 +449,8 @@ static void create_bindings(GPUVertBuf *verts,
continue;
}
+ *attrib_mask &= ~(1 << input->location);
+
if (a->comp_len == 16 || a->comp_len == 12 || a->comp_len == 8) {
#if TRUST_NO_ONE
assert(a->fetch_mode == GPU_FETCH_FLOAT);
@@ -487,17 +492,35 @@ static void create_bindings(GPUVertBuf *verts,
static void batch_update_program_bindings(GPUBatch *batch, uint i_first)
{
+ uint16_t attrib_mask = batch->interface->enabled_attrib_mask;
+
/* Reverse order so first vbos have more prevalence (in term of attrib override). */
for (int v = GPU_BATCH_VBO_MAX_LEN - 1; v > -1; v--) {
if (batch->verts[v] != NULL) {
- create_bindings(batch->verts[v], batch->interface, 0, false);
+ create_bindings(batch->verts[v], batch->interface, &attrib_mask, 0, false);
}
}
+
for (int v = GPU_BATCH_INST_VBO_MAX_LEN - 1; v > -1; v--) {
if (batch->inst[v]) {
- create_bindings(batch->inst[v], batch->interface, i_first, true);
+ create_bindings(batch->inst[v], batch->interface, &attrib_mask, i_first, true);
+ }
+ }
+
+ if (attrib_mask != 0 && GLEW_ARB_vertex_attrib_binding) {
+ for (uint16_t mask = 1, a = 0; a < 16; a++, mask <<= 1) {
+ if (attrib_mask & mask) {
+ /* This replaces glVertexAttrib4f(a, 0.0f, 0.0f, 0.0f, 1.0f); with a more modern style.
+ * Fix issues for some drivers (see T75069). */
+ glBindVertexBuffer(a, g_default_attrib_vbo, (intptr_t)0, (intptr_t)0);
+
+ glEnableVertexAttribArray(a);
+ glVertexAttribFormat(a, 4, GL_FLOAT, GL_FALSE, 0);
+ glVertexAttribBinding(a, a);
+ }
}
}
+
if (batch->elem) {
GPU_indexbuf_use(batch->elem);
}
@@ -1002,11 +1025,23 @@ void GPU_batch_program_set_imm_shader(GPUBatch *batch)
void gpu_batch_init(void)
{
+ if (g_default_attrib_vbo == 0) {
+ g_default_attrib_vbo = GPU_buf_alloc();
+
+ float default_attrib_data[4] = {0.0f, 0.0f, 0.0f, 1.0f};
+ glBindBuffer(GL_ARRAY_BUFFER, g_default_attrib_vbo);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 4, default_attrib_data, GL_STATIC_DRAW);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ }
+
gpu_batch_presets_init();
}
void gpu_batch_exit(void)
{
+ GPU_buf_free(g_default_attrib_vbo);
+ g_default_attrib_vbo = 0;
+
gpu_batch_presets_exit();
}
diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c
index c377d196eb5..168a3c83a91 100644
--- a/source/blender/gpu/intern/gpu_buffers.c
+++ b/source/blender/gpu/intern/gpu_buffers.c
@@ -92,7 +92,7 @@ struct GPU_PBVH_Buffers {
* smooth-shaded or all faces are flat-shaded */
bool smooth;
- bool show_mask;
+ bool show_overlay;
};
static struct {
@@ -116,7 +116,7 @@ void gpu_pbvh_init()
&g_vbo_id.format, "nor", GPU_COMP_I16, 3, GPU_FETCH_INT_TO_FLOAT_UNIT);
/* TODO: Do not allocate these `.msk` and `.col` when they are not used. */
g_vbo_id.msk = GPU_vertformat_attr_add(
- &g_vbo_id.format, "msk", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
+ &g_vbo_id.format, "msk", GPU_COMP_U8, 1, GPU_FETCH_INT_TO_FLOAT_UNIT);
g_vbo_id.col = GPU_vertformat_attr_add(
&g_vbo_id.format, "ac", GPU_COMP_U16, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
g_vbo_id.fset = GPU_vertformat_attr_add(
@@ -206,6 +206,15 @@ static void face_set_overlay_color_get(const int face_set, const int seed, uchar
rgba_float_to_uchar(r_color, rgba);
}
+static bool gpu_pbvh_is_looptri_visible(const MLoopTri *lt,
+ const MVert *mvert,
+ const MLoop *mloop,
+ const int *sculpt_face_sets)
+{
+ return (!paint_is_face_hidden(lt, mvert, mloop) && sculpt_face_sets &&
+ sculpt_face_sets[lt->poly] > SCULPT_FACE_SET_NONE);
+}
+
/* Threaded - do not call any functions that use OpenGL calls! */
void GPU_pbvh_mesh_buffers_update(GPU_PBVH_Buffers *buffers,
const MVert *mvert,
@@ -224,6 +233,7 @@ void GPU_pbvh_mesh_buffers_update(GPU_PBVH_Buffers *buffers,
const bool show_face_sets = sculpt_face_sets &&
(update_flags & GPU_PBVH_BUFFERS_SHOW_SCULPT_FACE_SETS) != 0;
bool empty_mask = true;
+ bool default_face_set = true;
{
int totelem = (buffers->smooth ? totvert : (buffers->tot_tri * 3));
@@ -254,15 +264,15 @@ void GPU_pbvh_mesh_buffers_update(GPU_PBVH_Buffers *buffers,
copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), v->co);
copy_v3_v3_short(GPU_vertbuf_raw_step(&nor_step), v->no);
- float mask;
+ uchar mask;
if (show_mask) {
- mask = vmask[vidx];
+ mask = (uchar)(vmask[vidx] * 255);
}
else {
mask = 0.0f;
}
- *(float *)GPU_vertbuf_raw_step(&msk_step) = mask;
- empty_mask = empty_mask && (mask == 0.0f);
+ *(uchar *)GPU_vertbuf_raw_step(&msk_step) = mask;
+ empty_mask = empty_mask && (mask == 0);
}
/* Face Sets. */
@@ -275,6 +285,7 @@ void GPU_pbvh_mesh_buffers_update(GPU_PBVH_Buffers *buffers,
/* Skip for the default color Face Set to render it white. */
if (fset != face_sets_color_default) {
face_set_overlay_color_get(fset, face_sets_color_seed, face_set_color);
+ default_face_set = false;
}
}
for (int j = 0; j < 3; j++) {
@@ -313,11 +324,7 @@ void GPU_pbvh_mesh_buffers_update(GPU_PBVH_Buffers *buffers,
buffers->mloop[lt->tri[2]].v,
};
- if (paint_is_face_hidden(lt, mvert, buffers->mloop)) {
- continue;
- }
-
- if (sculpt_face_sets[lt->poly] <= 0) {
+ if (!gpu_pbvh_is_looptri_visible(lt, mvert, buffers->mloop, sculpt_face_sets)) {
continue;
}
@@ -336,12 +343,15 @@ void GPU_pbvh_mesh_buffers_update(GPU_PBVH_Buffers *buffers,
/* Skip for the default color Face Set to render it white. */
if (fset != face_sets_color_default) {
face_set_overlay_color_get(fset, face_sets_color_seed, face_set_color);
+ default_face_set = false;
}
}
float fmask = 0.0f;
+ uchar cmask = 0;
if (show_mask) {
fmask = (vmask[vtri[0]] + vmask[vtri[1]] + vmask[vtri[2]]) / 3.0f;
+ cmask = (uchar)(fmask * 255);
}
for (uint j = 0; j < 3; j++) {
@@ -349,8 +359,8 @@ void GPU_pbvh_mesh_buffers_update(GPU_PBVH_Buffers *buffers,
copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), v->co);
copy_v3_v3_short(GPU_vertbuf_raw_step(&nor_step), no);
- *(float *)GPU_vertbuf_raw_step(&msk_step) = fmask;
- empty_mask = empty_mask && (fmask == 0.0f);
+ *(uchar *)GPU_vertbuf_raw_step(&msk_step) = cmask;
+ empty_mask = empty_mask && (cmask == 0);
/* Face Sets. */
memcpy(GPU_vertbuf_raw_step(&fset_step), face_set_color, sizeof(uchar) * 3);
@@ -377,19 +387,10 @@ void GPU_pbvh_mesh_buffers_update(GPU_PBVH_Buffers *buffers,
const MPoly *mp = &buffers->mpoly[lt->poly];
buffers->material_index = mp->mat_nr;
- buffers->show_mask = !empty_mask;
+ buffers->show_overlay = !empty_mask || !default_face_set;
buffers->mvert = mvert;
}
-static bool gpu_pbvh_is_looptri_visible(const MLoopTri *lt,
- const MVert *mvert,
- const MLoop *mloop,
- const int *sculpt_face_sets)
-{
- return (!paint_is_face_hidden(lt, mvert, mloop) && sculpt_face_sets &&
- sculpt_face_sets[lt->poly] > 0);
-}
-
/* Threaded - do not call any functions that use OpenGL calls! */
GPU_PBVH_Buffers *GPU_pbvh_mesh_buffers_build(const int (*face_vert_indices)[3],
const MPoly *mpoly,
@@ -410,7 +411,7 @@ GPU_PBVH_Buffers *GPU_pbvh_mesh_buffers_build(const int (*face_vert_indices)[3],
/* smooth or flat for all */
buffers->smooth = mpoly[looptri[face_indices[0]].poly].flag & ME_SMOOTH;
- buffers->show_mask = false;
+ buffers->show_overlay = false;
/* Count the number of visible triangles */
for (i = 0, tottri = 0; i < face_indices_len; i++) {
@@ -731,8 +732,9 @@ void GPU_pbvh_grid_buffers_update(GPU_PBVH_Buffers *buffers,
if (has_mask && show_mask) {
float fmask = *CCG_elem_mask(key, elem);
- GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vbo_index, &fmask);
- empty_mask = empty_mask && (fmask == 0.0f);
+ uchar cmask = (uchar)(fmask * 255);
+ GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vbo_index, &cmask);
+ empty_mask = empty_mask && (cmask == 0);
}
if (show_vcol) {
@@ -780,14 +782,15 @@ void GPU_pbvh_grid_buffers_update(GPU_PBVH_Buffers *buffers,
GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.nor, vbo_index + 3, no_short);
if (has_mask && show_mask) {
- float fsets = (*CCG_elem_mask(key, elems[0]) + *CCG_elem_mask(key, elems[1]) +
+ float fmask = (*CCG_elem_mask(key, elems[0]) + *CCG_elem_mask(key, elems[1]) +
*CCG_elem_mask(key, elems[2]) + *CCG_elem_mask(key, elems[3])) *
0.25f;
- GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vbo_index + 0, &fsets);
- GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vbo_index + 1, &fsets);
- GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vbo_index + 2, &fsets);
- GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vbo_index + 3, &fsets);
- empty_mask = empty_mask && (fsets == 0.0f);
+ uchar cmask = (uchar)(fmask * 255);
+ GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vbo_index + 0, &cmask);
+ GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vbo_index + 1, &cmask);
+ GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vbo_index + 2, &cmask);
+ GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vbo_index + 3, &cmask);
+ empty_mask = empty_mask && (cmask == 0);
}
ushort vcol[4] = {USHRT_MAX, USHRT_MAX, USHRT_MAX, USHRT_MAX};
@@ -820,7 +823,7 @@ void GPU_pbvh_grid_buffers_update(GPU_PBVH_Buffers *buffers,
buffers->totgrid = totgrid;
buffers->grid_flag_mats = grid_flag_mats;
buffers->gridkey = *key;
- buffers->show_mask = !empty_mask;
+ buffers->show_overlay = !empty_mask;
}
/* Threaded - do not call any functions that use OpenGL calls! */
@@ -832,7 +835,7 @@ GPU_PBVH_Buffers *GPU_pbvh_grid_buffers_build(int totgrid, BLI_bitmap **grid_hid
buffers->grid_hidden = grid_hidden;
buffers->totgrid = totgrid;
- buffers->show_mask = false;
+ buffers->show_overlay = false;
return buffers;
}
@@ -868,8 +871,9 @@ static void gpu_bmesh_vert_to_buffer_copy(BMVert *v,
if (show_mask) {
float effective_mask = fmask ? *fmask : BM_ELEM_CD_GET_FLOAT(v, cd_vert_mask_offset);
- GPU_vertbuf_attr_set(vert_buf, g_vbo_id.msk, v_index, &effective_mask);
- *empty_mask = *empty_mask && (effective_mask == 0.0f);
+ uchar cmask = (uchar)(effective_mask * 255);
+ GPU_vertbuf_attr_set(vert_buf, g_vbo_id.msk, v_index, &cmask);
+ *empty_mask = *empty_mask && (cmask == 0);
}
if (show_vcol) {
@@ -1095,7 +1099,7 @@ void GPU_pbvh_bmesh_buffers_update(GPU_PBVH_Buffers *buffers,
/* Get material index from the last face we iterated on. */
buffers->material_index = (f) ? f->mat_nr : 0;
- buffers->show_mask = !empty_mask;
+ buffers->show_overlay = !empty_mask;
gpu_pbvh_batch_init(buffers, GPU_PRIM_TRIS);
}
@@ -1114,7 +1118,7 @@ GPU_PBVH_Buffers *GPU_pbvh_bmesh_buffers_build(bool smooth_shading)
buffers = MEM_callocN(sizeof(GPU_PBVH_Buffers), "GPU_Buffers");
buffers->use_bmesh = true;
buffers->smooth = smooth_shading;
- buffers->show_mask = true;
+ buffers->show_overlay = true;
return buffers;
}
@@ -1129,9 +1133,9 @@ GPUBatch *GPU_pbvh_buffers_batch_get(GPU_PBVH_Buffers *buffers, bool fast, bool
}
}
-bool GPU_pbvh_buffers_has_mask(GPU_PBVH_Buffers *buffers)
+bool GPU_pbvh_buffers_has_overlays(GPU_PBVH_Buffers *buffers)
{
- return buffers->show_mask;
+ return buffers->show_overlay;
}
short GPU_pbvh_buffers_material_index_get(GPU_PBVH_Buffers *buffers)
diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c
index c6ffcfa2d86..1a0daf4ac41 100644
--- a/source/blender/gpu/intern/gpu_shader.c
+++ b/source/blender/gpu/intern/gpu_shader.c
@@ -54,9 +54,6 @@ extern char datatoc_gpu_shader_uniform_color_frag_glsl[];
extern char datatoc_gpu_shader_checker_frag_glsl[];
extern char datatoc_gpu_shader_diag_stripes_frag_glsl[];
extern char datatoc_gpu_shader_simple_lighting_frag_glsl[];
-extern char datatoc_gpu_shader_simple_lighting_flat_color_frag_glsl[];
-extern char datatoc_gpu_shader_simple_lighting_smooth_color_frag_glsl[];
-extern char datatoc_gpu_shader_simple_lighting_smooth_color_alpha_frag_glsl[];
extern char datatoc_gpu_shader_flat_color_frag_glsl[];
extern char datatoc_gpu_shader_flat_color_alpha_test_0_frag_glsl[];
extern char datatoc_gpu_shader_flat_id_frag_glsl[];
@@ -67,7 +64,6 @@ extern char datatoc_gpu_shader_2D_flat_color_vert_glsl[];
extern char datatoc_gpu_shader_2D_smooth_color_uniform_alpha_vert_glsl[];
extern char datatoc_gpu_shader_2D_smooth_color_vert_glsl[];
extern char datatoc_gpu_shader_2D_smooth_color_frag_glsl[];
-extern char datatoc_gpu_shader_2D_smooth_color_dithered_frag_glsl[];
extern char datatoc_gpu_shader_2D_image_vert_glsl[];
extern char datatoc_gpu_shader_2D_image_rect_vert_glsl[];
extern char datatoc_gpu_shader_2D_image_multi_rect_vert_glsl[];
@@ -89,15 +85,10 @@ extern char datatoc_gpu_shader_image_alpha_color_frag_glsl[];
extern char datatoc_gpu_shader_image_shuffle_color_frag_glsl[];
extern char datatoc_gpu_shader_image_mask_uniform_color_frag_glsl[];
extern char datatoc_gpu_shader_image_modulate_alpha_frag_glsl[];
-extern char datatoc_gpu_shader_image_depth_linear_frag_glsl[];
-extern char datatoc_gpu_shader_image_depth_copy_frag_glsl[];
-extern char datatoc_gpu_shader_image_multisample_resolve_frag_glsl[];
extern char datatoc_gpu_shader_3D_vert_glsl[];
extern char datatoc_gpu_shader_3D_normal_vert_glsl[];
extern char datatoc_gpu_shader_3D_flat_color_vert_glsl[];
extern char datatoc_gpu_shader_3D_smooth_color_vert_glsl[];
-extern char datatoc_gpu_shader_3D_normal_flat_color_vert_glsl[];
-extern char datatoc_gpu_shader_3D_normal_smooth_color_vert_glsl[];
extern char datatoc_gpu_shader_3D_smooth_color_frag_glsl[];
extern char datatoc_gpu_shader_3D_passthrough_vert_glsl[];
extern char datatoc_gpu_shader_3D_clipped_uniform_color_vert_glsl[];
@@ -884,23 +875,6 @@ static const GPUShaderStages builtin_shader_stages[GPU_SHADER_BUILTIN_LEN] = {
.vert = datatoc_gpu_shader_3D_normal_vert_glsl,
.frag = datatoc_gpu_shader_simple_lighting_frag_glsl,
},
- /* Use 'USE_FLAT_NORMAL' to make flat shader from smooth */
- [GPU_SHADER_SIMPLE_LIGHTING_FLAT_COLOR] =
- {
- .vert = datatoc_gpu_shader_3D_normal_smooth_color_vert_glsl,
- .frag = datatoc_gpu_shader_simple_lighting_smooth_color_frag_glsl,
- .defs = "#define USE_FLAT_NORMAL\n",
- },
- [GPU_SHADER_SIMPLE_LIGHTING_SMOOTH_COLOR] =
- {
- .vert = datatoc_gpu_shader_3D_normal_smooth_color_vert_glsl,
- .frag = datatoc_gpu_shader_simple_lighting_smooth_color_frag_glsl,
- },
- [GPU_SHADER_SIMPLE_LIGHTING_SMOOTH_COLOR_ALPHA] =
- {
- .vert = datatoc_gpu_shader_3D_normal_smooth_color_vert_glsl,
- .frag = datatoc_gpu_shader_simple_lighting_smooth_color_alpha_frag_glsl,
- },
[GPU_SHADER_2D_IMAGE_MASK_UNIFORM_COLOR] =
{
@@ -912,69 +886,6 @@ static const GPUShaderStages builtin_shader_stages[GPU_SHADER_BUILTIN_LEN] = {
.vert = datatoc_gpu_shader_3D_image_vert_glsl,
.frag = datatoc_gpu_shader_image_modulate_alpha_frag_glsl,
},
- [GPU_SHADER_3D_IMAGE_DEPTH] =
- {
- .vert = datatoc_gpu_shader_3D_image_vert_glsl,
- .frag = datatoc_gpu_shader_image_depth_linear_frag_glsl,
- },
- [GPU_SHADER_3D_IMAGE_DEPTH_COPY] =
- {
- .vert = datatoc_gpu_shader_3D_image_vert_glsl,
- .frag = datatoc_gpu_shader_image_depth_copy_frag_glsl,
- },
- [GPU_SHADER_2D_IMAGE_MULTISAMPLE_2] =
- {
- .vert = datatoc_gpu_shader_2D_vert_glsl,
- .frag = datatoc_gpu_shader_image_multisample_resolve_frag_glsl,
- .defs = "#define SAMPLES 2\n",
- },
- [GPU_SHADER_2D_IMAGE_MULTISAMPLE_4] =
- {
- .vert = datatoc_gpu_shader_2D_vert_glsl,
- .frag = datatoc_gpu_shader_image_multisample_resolve_frag_glsl,
- .defs = "#define SAMPLES 4\n",
- },
- [GPU_SHADER_2D_IMAGE_MULTISAMPLE_8] =
- {
- .vert = datatoc_gpu_shader_2D_vert_glsl,
- .frag = datatoc_gpu_shader_image_multisample_resolve_frag_glsl,
- .defs = "#define SAMPLES 8\n",
- },
- [GPU_SHADER_2D_IMAGE_MULTISAMPLE_16] =
- {
- .vert = datatoc_gpu_shader_2D_vert_glsl,
- .frag = datatoc_gpu_shader_image_multisample_resolve_frag_glsl,
- .defs = "#define SAMPLES 16\n",
- },
- [GPU_SHADER_2D_IMAGE_MULTISAMPLE_2_DEPTH_TEST] =
- {
- .vert = datatoc_gpu_shader_2D_vert_glsl,
- .frag = datatoc_gpu_shader_image_multisample_resolve_frag_glsl,
- .defs = "#define SAMPLES 2\n"
- "#define USE_DEPTH\n",
- },
- [GPU_SHADER_2D_IMAGE_MULTISAMPLE_4_DEPTH_TEST] =
- {
- .vert = datatoc_gpu_shader_2D_vert_glsl,
- .frag = datatoc_gpu_shader_image_multisample_resolve_frag_glsl,
- .defs = "#define SAMPLES 4\n"
- "#define USE_DEPTH\n",
- },
- [GPU_SHADER_2D_IMAGE_MULTISAMPLE_8_DEPTH_TEST] =
- {
- .vert = datatoc_gpu_shader_2D_vert_glsl,
- .frag = datatoc_gpu_shader_image_multisample_resolve_frag_glsl,
- .defs = "#define SAMPLES 8\n"
- "#define USE_DEPTH\n",
- },
- [GPU_SHADER_2D_IMAGE_MULTISAMPLE_16_DEPTH_TEST] =
- {
- .vert = datatoc_gpu_shader_2D_vert_glsl,
- .frag = datatoc_gpu_shader_image_multisample_resolve_frag_glsl,
- .defs = "#define SAMPLES 16\n"
- "#define USE_DEPTH\n",
- },
-
[GPU_SHADER_2D_CHECKER] =
{
.vert = datatoc_gpu_shader_2D_vert_glsl,
@@ -1002,11 +913,6 @@ static const GPUShaderStages builtin_shader_stages[GPU_SHADER_BUILTIN_LEN] = {
.vert = datatoc_gpu_shader_2D_smooth_color_vert_glsl,
.frag = datatoc_gpu_shader_2D_smooth_color_frag_glsl,
},
- [GPU_SHADER_2D_SMOOTH_COLOR_DITHER] =
- {
- .vert = datatoc_gpu_shader_2D_smooth_color_vert_glsl,
- .frag = datatoc_gpu_shader_2D_smooth_color_dithered_frag_glsl,
- },
[GPU_SHADER_2D_IMAGE_OVERLAYS_MERGE] =
{
.vert = datatoc_gpu_shader_2D_image_vert_glsl,
@@ -1058,12 +964,6 @@ static const GPUShaderStages builtin_shader_stages[GPU_SHADER_BUILTIN_LEN] = {
.vert = datatoc_gpu_shader_3D_vert_glsl,
.frag = datatoc_gpu_shader_uniform_color_frag_glsl,
},
- [GPU_SHADER_3D_UNIFORM_COLOR_BACKGROUND] =
- {
- .vert = datatoc_gpu_shader_3D_vert_glsl,
- .frag = datatoc_gpu_shader_uniform_color_frag_glsl,
- .defs = "#define USE_BACKGROUND\n",
- },
[GPU_SHADER_3D_FLAT_COLOR] =
{
.vert = datatoc_gpu_shader_3D_flat_color_vert_glsl,
diff --git a/source/blender/gpu/intern/gpu_shader_interface.c b/source/blender/gpu/intern/gpu_shader_interface.c
index f23a0a438d6..349a7217456 100644
--- a/source/blender/gpu/intern/gpu_shader_interface.c
+++ b/source/blender/gpu/intern/gpu_shader_interface.c
@@ -236,6 +236,7 @@ GPUShaderInterface *GPU_shaderinterface_create(int32_t program)
shaderface->name_buffer = MEM_mallocN(name_buffer_len, "name_buffer");
/* Attributes */
+ shaderface->enabled_attrib_mask = 0;
for (uint32_t i = 0; i < attr_len; i++) {
GPUShaderInput *input = MEM_mallocN(sizeof(GPUShaderInput), "GPUShaderInput Attr");
GLsizei remaining_buffer = name_buffer_len - shaderface->name_buffer_offset;
@@ -255,6 +256,8 @@ GPUShaderInterface *GPU_shaderinterface_create(int32_t program)
input->location = glGetAttribLocation(program, name);
+ shaderface->enabled_attrib_mask |= (1 << input->location);
+
set_input_name(shaderface, input, name, name_len);
shader_input_to_bucket(input, shaderface->attr_buckets);
diff --git a/source/blender/gpu/intern/gpu_texture.c b/source/blender/gpu/intern/gpu_texture.c
index 088cf912d6a..075a8e8aeb5 100644
--- a/source/blender/gpu/intern/gpu_texture.c
+++ b/source/blender/gpu/intern/gpu_texture.c
@@ -82,7 +82,7 @@ struct GPUTexture {
eGPUTextureFormat format;
eGPUTextureFormatFlag format_flag;
- uint bytesize; /* number of byte for one pixel */
+ int mipmaps; /* number of mipmaps */
int components; /* number of color/alpha channels */
int samples; /* number of samples for multisamples textures. 0 if not multisample target */
@@ -90,6 +90,8 @@ struct GPUTexture {
GPUFrameBuffer *fb[GPU_TEX_MAX_FBO_ATTACHED];
};
+static uint gpu_get_bytesize(eGPUTextureFormat data_type);
+
/* ------ Memory Management ------- */
/* Records every texture allocation / free
* to estimate the Texture Pool Memory consumption */
@@ -97,23 +99,39 @@ static uint memory_usage;
static uint gpu_texture_memory_footprint_compute(GPUTexture *tex)
{
- int samp = max_ii(tex->samples, 1);
+ uint memsize;
+ const uint bytesize = gpu_get_bytesize(tex->format);
+ const int samp = max_ii(tex->samples, 1);
switch (tex->target_base) {
case GL_TEXTURE_1D:
- return tex->bytesize * tex->w * samp;
+ case GL_TEXTURE_BUFFER:
+ memsize = bytesize * tex->w * samp;
+ break;
case GL_TEXTURE_1D_ARRAY:
case GL_TEXTURE_2D:
- return tex->bytesize * tex->w * tex->h * samp;
+ memsize = bytesize * tex->w * tex->h * samp;
+ break;
case GL_TEXTURE_2D_ARRAY:
case GL_TEXTURE_3D:
- return tex->bytesize * tex->w * tex->h * tex->d * samp;
+ memsize = bytesize * tex->w * tex->h * tex->d * samp;
+ break;
case GL_TEXTURE_CUBE_MAP:
- return tex->bytesize * 6 * tex->w * tex->h * samp;
+ memsize = bytesize * 6 * tex->w * tex->h * samp;
+ break;
case GL_TEXTURE_CUBE_MAP_ARRAY_ARB:
- return tex->bytesize * 6 * tex->w * tex->h * tex->d * samp;
+ memsize = bytesize * 6 * tex->w * tex->h * tex->d * samp;
+ break;
default:
+ BLI_assert(0);
return 0;
}
+ if (tex->mipmaps != 0) {
+ /* Just to get an idea of the memory used here is computed
+ * as if the maximum number of mipmaps was generated. */
+ memsize += memsize / 3;
+ }
+
+ return memsize;
}
static void gpu_texture_memory_footprint_add(GPUTexture *tex)
@@ -362,7 +380,7 @@ static uint gpu_get_bytesize(eGPUTextureFormat data_type)
return 16;
case GPU_RGB16F:
return 12;
- case GPU_DEPTH32F_STENCIL8:
+ case GPU_DEPTH32F_STENCIL8: /* 32-bit depth, 8 bits stencil, and 24 unused bits. */
return 8;
case GPU_RG16F:
case GPU_RG16I:
@@ -396,65 +414,84 @@ static uint gpu_get_bytesize(eGPUTextureFormat data_type)
}
}
-static GLenum gpu_get_gl_internalformat(eGPUTextureFormat format)
+static GLenum gpu_format_to_gl_internalformat(eGPUTextureFormat format)
{
/* You can add any of the available type to this list
* For available types see GPU_texture.h */
switch (format) {
/* Formats texture & renderbuffer */
+ case GPU_RGBA8UI:
+ return GL_RGBA8UI;
+ case GPU_RGBA8I:
+ return GL_RGBA8I;
+ case GPU_RGBA8:
+ return GL_RGBA8;
+ case GPU_RGBA32UI:
+ return GL_RGBA32UI;
+ case GPU_RGBA32I:
+ return GL_RGBA32I;
case GPU_RGBA32F:
return GL_RGBA32F;
+ case GPU_RGBA16UI:
+ return GL_RGBA16UI;
+ case GPU_RGBA16I:
+ return GL_RGBA16I;
case GPU_RGBA16F:
return GL_RGBA16F;
case GPU_RGBA16:
return GL_RGBA16;
+ case GPU_RG8UI:
+ return GL_RG8UI;
+ case GPU_RG8I:
+ return GL_RG8I;
+ case GPU_RG8:
+ return GL_RG8;
+ case GPU_RG32UI:
+ return GL_RG32UI;
+ case GPU_RG32I:
+ return GL_RG32I;
case GPU_RG32F:
return GL_RG32F;
- case GPU_RGB16F:
- return GL_RGB16F;
- case GPU_RG16F:
- return GL_RG16F;
+ case GPU_RG16UI:
+ return GL_RG16UI;
case GPU_RG16I:
return GL_RG16I;
+ case GPU_RG16F:
+ return GL_RGBA32F;
case GPU_RG16:
return GL_RG16;
- case GPU_RGBA8:
- return GL_RGBA8;
- case GPU_RGBA8UI:
- return GL_RGBA8UI;
- case GPU_SRGB8_A8:
- return GL_SRGB8_ALPHA8;
- case GPU_R32F:
- return GL_R32F;
+ case GPU_R8UI:
+ return GL_R8UI;
+ case GPU_R8I:
+ return GL_R8I;
+ case GPU_R8:
+ return GL_R8;
case GPU_R32UI:
return GL_R32UI;
case GPU_R32I:
return GL_R32I;
- case GPU_R16F:
- return GL_R16F;
- case GPU_R16I:
- return GL_R16I;
+ case GPU_R32F:
+ return GL_R32F;
case GPU_R16UI:
return GL_R16UI;
- case GPU_RG8:
- return GL_RG8;
- case GPU_RG16UI:
- return GL_RG16UI;
+ case GPU_R16I:
+ return GL_R16I;
+ case GPU_R16F:
+ return GL_R16F;
case GPU_R16:
return GL_R16;
- case GPU_R8:
- return GL_R8;
- case GPU_R8UI:
- return GL_R8UI;
/* Special formats texture & renderbuffer */
case GPU_R11F_G11F_B10F:
return GL_R11F_G11F_B10F;
- case GPU_DEPTH24_STENCIL8:
- return GL_DEPTH24_STENCIL8;
case GPU_DEPTH32F_STENCIL8:
return GL_DEPTH32F_STENCIL8;
+ case GPU_DEPTH24_STENCIL8:
+ return GL_DEPTH24_STENCIL8;
+ case GPU_SRGB8_A8:
+ return GL_SRGB8_ALPHA8;
/* Texture only format */
- /* ** Add Format here */
+ case GPU_RGB16F:
+ return GL_RGB16F;
/* Special formats texture only */
/* ** Add Format here */
/* Depth Formats */
@@ -470,6 +507,99 @@ static GLenum gpu_get_gl_internalformat(eGPUTextureFormat format)
}
}
+static eGPUTextureFormat gl_internalformat_to_gpu_format(const GLint glformat)
+{
+ /* You can add any of the available type to this list
+ * For available types see GPU_texture.h */
+ switch (glformat) {
+ /* Formats texture & renderbuffer */
+ case GL_RGBA8UI:
+ return GPU_RGBA8UI;
+ case GL_RGBA8I:
+ return GPU_RGBA8I;
+ case GL_RGBA8:
+ return GPU_RGBA8;
+ case GL_RGBA32UI:
+ return GPU_RGBA32UI;
+ case GL_RGBA32I:
+ return GPU_RGBA32I;
+ case GL_RGBA32F:
+ return GPU_RGBA32F;
+ case GL_RGBA16UI:
+ return GPU_RGBA16UI;
+ case GL_RGBA16I:
+ return GPU_RGBA16I;
+ case GL_RGBA16F:
+ return GPU_RGBA16F;
+ case GL_RGBA16:
+ return GPU_RGBA16;
+ case GL_RG8UI:
+ return GPU_RG8UI;
+ case GL_RG8I:
+ return GPU_RG8I;
+ case GL_RG8:
+ return GPU_RG8;
+ case GL_RG32UI:
+ return GPU_RG32UI;
+ case GL_RG32I:
+ return GPU_RG32I;
+ case GL_RG32F:
+ return GPU_RG32F;
+ case GL_RG16UI:
+ return GPU_RG16UI;
+ case GL_RG16I:
+ return GPU_RG16I;
+ case GL_RG16F:
+ return GPU_RGBA32F;
+ case GL_RG16:
+ return GPU_RG16;
+ case GL_R8UI:
+ return GPU_R8UI;
+ case GL_R8I:
+ return GPU_R8I;
+ case GL_R8:
+ return GPU_R8;
+ case GL_R32UI:
+ return GPU_R32UI;
+ case GL_R32I:
+ return GPU_R32I;
+ case GL_R32F:
+ return GPU_R32F;
+ case GL_R16UI:
+ return GPU_R16UI;
+ case GL_R16I:
+ return GPU_R16I;
+ case GL_R16F:
+ return GPU_R16F;
+ case GL_R16:
+ return GPU_R16;
+ /* Special formats texture & renderbuffer */
+ case GL_R11F_G11F_B10F:
+ return GPU_R11F_G11F_B10F;
+ case GL_DEPTH32F_STENCIL8:
+ return GPU_DEPTH32F_STENCIL8;
+ case GL_DEPTH24_STENCIL8:
+ return GPU_DEPTH24_STENCIL8;
+ case GL_SRGB8_ALPHA8:
+ return GPU_SRGB8_A8;
+ /* Texture only format */
+ case GL_RGB16F:
+ return GPU_RGB16F;
+ /* Special formats texture only */
+ /* ** Add Format here */
+ /* Depth Formats */
+ case GL_DEPTH_COMPONENT32F:
+ return GPU_DEPTH_COMPONENT32F;
+ case GL_DEPTH_COMPONENT24:
+ return GPU_DEPTH_COMPONENT24;
+ case GL_DEPTH_COMPONENT16:
+ return GPU_DEPTH_COMPONENT16;
+ default:
+ BLI_assert(!"Internal format incorrect or unsupported\n");
+ }
+ return -1;
+}
+
static GLenum gpu_get_gl_datatype(eGPUDataFormat format)
{
switch (format) {
@@ -690,7 +820,7 @@ GPUTexture *GPU_texture_create_nD(int w,
tex->refcount = 1;
tex->format = tex_format;
tex->components = gpu_get_component_count(tex_format);
- tex->bytesize = gpu_get_bytesize(tex_format);
+ tex->mipmaps = 0;
tex->format_flag = 0;
if (n == 2) {
@@ -726,7 +856,7 @@ GPUTexture *GPU_texture_create_nD(int w,
tex->target = GL_TEXTURE_2D_MULTISAMPLE;
}
- GLenum internalformat = gpu_get_gl_internalformat(tex_format);
+ GLenum internalformat = gpu_format_to_gl_internalformat(tex_format);
GLenum data_format = gpu_get_gl_dataformat(tex_format, &tex->format_flag);
GLenum data_type = gpu_get_gl_datatype(gpu_data_format);
@@ -877,7 +1007,7 @@ GPUTexture *GPU_texture_cube_create(int w,
tex->refcount = 1;
tex->format = tex_format;
tex->components = gpu_get_component_count(tex_format);
- tex->bytesize = gpu_get_bytesize(tex_format);
+ tex->mipmaps = 0;
tex->format_flag = GPU_FORMAT_CUBE;
if (d == 0) {
@@ -901,7 +1031,7 @@ GPUTexture *GPU_texture_cube_create(int w,
}
}
- GLenum internalformat = gpu_get_gl_internalformat(tex_format);
+ GLenum internalformat = gpu_format_to_gl_internalformat(tex_format);
GLenum data_format = gpu_get_gl_dataformat(tex_format, &tex->format_flag);
GLenum data_type = gpu_get_gl_datatype(gpu_data_format);
@@ -1008,9 +1138,9 @@ GPUTexture *GPU_texture_create_buffer(eGPUTextureFormat tex_format, const GLuint
tex->components = gpu_get_component_count(tex_format);
tex->format_flag = 0;
tex->target_base = tex->target = GL_TEXTURE_BUFFER;
- tex->bytesize = gpu_get_bytesize(tex_format);
+ tex->mipmaps = 0;
- GLenum internalformat = gpu_get_gl_internalformat(tex_format);
+ GLenum internalformat = gpu_format_to_gl_internalformat(tex_format);
gpu_get_gl_dataformat(tex_format, &tex->format_flag);
@@ -1043,8 +1173,11 @@ GPUTexture *GPU_texture_create_buffer(eGPUTextureFormat tex_format, const GLuint
glBindTexture(tex->target, tex->bindcode);
glTexBuffer(tex->target, internalformat, buffer);
+ glGetTexLevelParameteriv(tex->target, 0, GL_TEXTURE_WIDTH, &tex->w);
glBindTexture(tex->target, 0);
+ gpu_texture_memory_footprint_add(tex);
+
return tex;
}
@@ -1056,27 +1189,30 @@ GPUTexture *GPU_texture_from_bindcode(int textarget, int bindcode)
tex->refcount = 1;
tex->target = textarget;
tex->target_base = textarget;
- tex->format = -1;
- tex->components = -1;
tex->samples = 0;
if (!glIsTexture(tex->bindcode)) {
GPU_print_error_debug("Blender Texture Not Loaded");
}
else {
- GLint w, h;
-
- GLenum gettarget = textarget;
- if (textarget == GL_TEXTURE_CUBE_MAP) {
- gettarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
- }
+ GLint w, h, gl_format;
+ GLenum gettarget;
+ gettarget = (textarget == GL_TEXTURE_CUBE_MAP) ? GL_TEXTURE_CUBE_MAP_POSITIVE_X : textarget;
glBindTexture(textarget, tex->bindcode);
glGetTexLevelParameteriv(gettarget, 0, GL_TEXTURE_WIDTH, &w);
glGetTexLevelParameteriv(gettarget, 0, GL_TEXTURE_HEIGHT, &h);
+ glGetTexLevelParameteriv(gettarget, 0, GL_TEXTURE_INTERNAL_FORMAT, &gl_format);
tex->w = w;
tex->h = h;
+ tex->format = gl_internalformat_to_gpu_format(gl_format);
+ tex->components = gpu_get_component_count(tex->format);
glBindTexture(textarget, 0);
+
+ /* Depending on how this bindcode was obtained, the memory used here could
+ * already have been computed.
+ * But that is not the case currently. */
+ gpu_texture_memory_footprint_add(tex);
}
return tex;
@@ -1261,10 +1397,11 @@ void GPU_texture_add_mipmap(GPUTexture *tex,
{
BLI_assert((int)tex->format > -1);
BLI_assert(tex->components > -1);
+ BLI_assert(miplvl > tex->mipmaps);
gpu_validate_data_format(tex->format, gpu_data_format);
- GLenum internalformat = gpu_get_gl_internalformat(tex->format);
+ GLenum internalformat = gpu_format_to_gl_internalformat(tex->format);
GLenum data_format = gpu_get_gl_dataformat(tex->format, &tex->format_flag);
GLenum data_type = gpu_get_gl_datatype(gpu_data_format);
@@ -1310,6 +1447,7 @@ void GPU_texture_add_mipmap(GPUTexture *tex,
BLI_assert(!"tex->target mode not supported");
}
+ tex->mipmaps = miplvl;
glTexParameteri(GPU_texture_target(tex), GL_TEXTURE_MAX_LEVEL, miplvl);
glBindTexture(tex->target, 0);
@@ -1328,12 +1466,13 @@ void GPU_texture_update_sub(GPUTexture *tex,
BLI_assert((int)tex->format > -1);
BLI_assert(tex->components > -1);
+ const uint bytesize = gpu_get_bytesize(tex->format);
GLenum data_format = gpu_get_gl_dataformat(tex->format, &tex->format_flag);
GLenum data_type = gpu_get_gl_datatype(gpu_data_format);
GLint alignment;
/* The default pack size for textures is 4, which won't work for byte based textures */
- if (tex->bytesize == 1) {
+ if (bytesize == 1) {
glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
}
@@ -1367,7 +1506,7 @@ void GPU_texture_update_sub(GPUTexture *tex,
BLI_assert(!"tex->target mode not supported");
}
- if (tex->bytesize == 1) {
+ if (bytesize == 1) {
glPixelStorei(GL_UNPACK_ALIGNMENT, alignment);
}
@@ -1376,6 +1515,8 @@ void GPU_texture_update_sub(GPUTexture *tex,
void *GPU_texture_read(GPUTexture *tex, eGPUDataFormat gpu_data_format, int miplvl)
{
+ BLI_assert(miplvl <= tex->mipmaps);
+
int size[3] = {0, 0, 0};
GPU_texture_get_mipmap_size(tex, miplvl, size);
@@ -1428,7 +1569,7 @@ void GPU_texture_clear(GPUTexture *tex, eGPUDataFormat gpu_data_format, const vo
size_t buffer_len = gpu_texture_memory_footprint_compute(tex);
unsigned char *pixels = MEM_mallocN(buffer_len, __func__);
if (color) {
- size_t bytesize = tex->bytesize;
+ const size_t bytesize = (size_t)gpu_get_bytesize(tex->format);
for (size_t byte = 0; byte < buffer_len; byte += bytesize) {
memcpy(&pixels[byte], color, bytesize);
}
@@ -1547,6 +1688,9 @@ void GPU_texture_generate_mipmap(GPUTexture *tex)
{
WARN_NOT_BOUND(tex);
+ gpu_texture_memory_footprint_remove(tex);
+ int levels = 1 + floor(log2(max_ii(tex->w, tex->h)));
+
glActiveTexture(GL_TEXTURE0 + tex->number);
if (GPU_texture_depth(tex)) {
@@ -1554,7 +1698,6 @@ void GPU_texture_generate_mipmap(GPUTexture *tex)
* In this case we just create a complete texture with mipmaps manually without down-sampling.
* You must initialize the texture levels using other methods like
* GPU_framebuffer_recursive_downsample(). */
- int levels = 1 + floor(log2(max_ii(tex->w, tex->h)));
eGPUDataFormat data_format = gpu_get_data_format_from_tex_format(tex->format);
for (int i = 1; i < levels; i++) {
GPU_texture_add_mipmap(tex, data_format, i, NULL);
@@ -1564,6 +1707,9 @@ void GPU_texture_generate_mipmap(GPUTexture *tex)
else {
glGenerateMipmap(tex->target_base);
}
+
+ tex->mipmaps = levels;
+ gpu_texture_memory_footprint_add(tex);
}
void GPU_texture_compare_mode(GPUTexture *tex, bool use_compare)
diff --git a/source/blender/gpu/shaders/gpu_shader_2D_smooth_color_dithered_frag.glsl b/source/blender/gpu/shaders/gpu_shader_2D_smooth_color_dithered_frag.glsl
deleted file mode 100644
index 181b1bf3fad..00000000000
--- a/source/blender/gpu/shaders/gpu_shader_2D_smooth_color_dithered_frag.glsl
+++ /dev/null
@@ -1,18 +0,0 @@
-
-noperspective in vec4 finalColor;
-out vec4 fragColor;
-
-/* 4x4 bayer matrix prepared for 8bit UNORM precision error. */
-#define P(x) (((x + 0.5) * (1.0 / 16.0) - 0.5) * (1.0 / 255.0))
-const vec4 dither_mat4x4[4] = vec4[4](vec4(P(0.0), P(8.0), P(2.0), P(10.0)),
- vec4(P(12.0), P(4.0), P(14.0), P(6.0)),
- vec4(P(3.0), P(11.0), P(1.0), P(9.0)),
- vec4(P(15.0), P(7.0), P(13.0), P(5.0)));
-
-void main()
-{
- ivec2 tx1 = ivec2(gl_FragCoord.xy) % 4;
- ivec2 tx2 = ivec2(gl_FragCoord.xy) % 2;
- float dither_noise = dither_mat4x4[tx1.x][tx1.y];
- fragColor = finalColor + dither_noise;
-}
diff --git a/source/blender/gpu/shaders/gpu_shader_3D_normal_smooth_color_vert.glsl b/source/blender/gpu/shaders/gpu_shader_3D_normal_smooth_color_vert.glsl
deleted file mode 100644
index 7fa571343a2..00000000000
--- a/source/blender/gpu/shaders/gpu_shader_3D_normal_smooth_color_vert.glsl
+++ /dev/null
@@ -1,22 +0,0 @@
-
-uniform mat4 ModelViewProjectionMatrix;
-uniform mat3 NormalMatrix;
-
-in vec3 pos;
-in vec3 nor;
-in vec4 color;
-
-#ifdef USE_FLAT_NORMAL
-flat out vec3 normal;
-flat out vec4 finalColor;
-#else
-out vec3 normal;
-out vec4 finalColor;
-#endif
-
-void main()
-{
- normal = normalize(NormalMatrix * nor);
- gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
- finalColor = color;
-}
diff --git a/source/blender/gpu/shaders/gpu_shader_image_depth_copy_frag.glsl b/source/blender/gpu/shaders/gpu_shader_image_depth_copy_frag.glsl
deleted file mode 100644
index 0f2749362b9..00000000000
--- a/source/blender/gpu/shaders/gpu_shader_image_depth_copy_frag.glsl
+++ /dev/null
@@ -1,12 +0,0 @@
-
-in vec2 texCoord_interp;
-out vec4 fragColor;
-
-uniform sampler2D image;
-
-void main()
-{
- float depth = texture(image, texCoord_interp).r;
- fragColor = vec4(depth);
- gl_FragDepth = depth;
-}
diff --git a/source/blender/gpu/shaders/gpu_shader_image_depth_linear_frag.glsl b/source/blender/gpu/shaders/gpu_shader_image_depth_linear_frag.glsl
deleted file mode 100644
index 017b21076c8..00000000000
--- a/source/blender/gpu/shaders/gpu_shader_image_depth_linear_frag.glsl
+++ /dev/null
@@ -1,16 +0,0 @@
-
-in vec2 texCoord_interp;
-out vec4 fragColor;
-
-uniform float znear;
-uniform float zfar;
-uniform sampler2D image;
-
-void main()
-{
- float depth = texture(image, texCoord_interp).r;
-
- /* normalize */
- fragColor.rgb = vec3((2.0f * znear) / (zfar + znear - (depth * (zfar - znear))));
- fragColor.a = 1.0f;
-}
diff --git a/source/blender/gpu/shaders/gpu_shader_image_multisample_resolve_frag.glsl b/source/blender/gpu/shaders/gpu_shader_image_multisample_resolve_frag.glsl
deleted file mode 100644
index ca425374a1b..00000000000
--- a/source/blender/gpu/shaders/gpu_shader_image_multisample_resolve_frag.glsl
+++ /dev/null
@@ -1,119 +0,0 @@
-
-uniform sampler2DMS depthMulti;
-uniform sampler2DMS colorMulti;
-
-out vec4 fragColor;
-
-#if SAMPLES > 16
-# error "Too many samples"
-#endif
-
-void main()
-{
- ivec2 texel = ivec2(gl_FragCoord.xy);
-
- bvec4 b1, b2, b3, b4;
- vec4 w1, w2, w3, w4;
- vec4 d1, d2, d3, d4;
- vec4 c1, c2, c3, c4, c5, c6, c7, c8;
- vec4 c9, c10, c11, c12, c13, c14, c15, c16;
- d1 = d2 = d3 = d4 = vec4(0.5);
- w1 = w2 = w3 = w4 = vec4(0.0);
- c1 = c2 = c3 = c4 = c5 = c6 = c7 = c8 = vec4(0.0);
- c9 = c10 = c11 = c12 = c13 = c14 = c15 = c16 = vec4(0.0);
-
-#ifdef USE_DEPTH
- /* Depth */
- d1.x = texelFetch(depthMulti, texel, 0).r;
- d1.y = texelFetch(depthMulti, texel, 1).r;
-# if SAMPLES > 2
- d1.z = texelFetch(depthMulti, texel, 2).r;
- d1.w = texelFetch(depthMulti, texel, 3).r;
-# endif
-# if SAMPLES > 4
- d2.x = texelFetch(depthMulti, texel, 4).r;
- d2.y = texelFetch(depthMulti, texel, 5).r;
- d2.z = texelFetch(depthMulti, texel, 6).r;
- d2.w = texelFetch(depthMulti, texel, 7).r;
-# endif
-# if SAMPLES > 8
- d3.x = texelFetch(depthMulti, texel, 8).r;
- d3.y = texelFetch(depthMulti, texel, 9).r;
- d3.z = texelFetch(depthMulti, texel, 10).r;
- d3.w = texelFetch(depthMulti, texel, 11).r;
- d4.x = texelFetch(depthMulti, texel, 12).r;
- d4.y = texelFetch(depthMulti, texel, 13).r;
- d4.z = texelFetch(depthMulti, texel, 14).r;
- d4.w = texelFetch(depthMulti, texel, 15).r;
-# endif
-#endif
-
- /* COLOR */
- b1 = notEqual(d1, vec4(1.0));
- if (any(b1)) {
- c1 = texelFetch(colorMulti, texel, 0);
- c2 = texelFetch(colorMulti, texel, 1);
-#if SAMPLES > 2
- c3 = texelFetch(colorMulti, texel, 2);
- c4 = texelFetch(colorMulti, texel, 3);
-#endif
- w1 = vec4(b1);
- }
-#if SAMPLES > 4
- b2 = notEqual(d2, vec4(1.0));
- if (any(b2)) {
- c5 = texelFetch(colorMulti, texel, 4);
- c6 = texelFetch(colorMulti, texel, 5);
- c7 = texelFetch(colorMulti, texel, 6);
- c8 = texelFetch(colorMulti, texel, 7);
- w2 = vec4(b2);
- }
-#endif
-#if SAMPLES > 8
- b3 = notEqual(d3, vec4(1.0));
- if (any(b3)) {
- c9 = texelFetch(colorMulti, texel, 8);
- c10 = texelFetch(colorMulti, texel, 9);
- c11 = texelFetch(colorMulti, texel, 10);
- c12 = texelFetch(colorMulti, texel, 11);
- w3 = vec4(b3);
- }
- b4 = notEqual(d4, vec4(1.0));
- if (any(b4)) {
- c13 = texelFetch(colorMulti, texel, 12);
- c14 = texelFetch(colorMulti, texel, 13);
- c15 = texelFetch(colorMulti, texel, 14);
- c16 = texelFetch(colorMulti, texel, 15);
- w4 = vec4(b4);
- }
-#endif
-
-#ifdef USE_DEPTH
-# if SAMPLES > 8
- d1 = min(d1, min(d3, d4));
-# endif
-# if SAMPLES > 4
- d1 = min(d1, d2);
- d1 = min(d1, d2);
-# endif
-# if SAMPLES > 2
- d1.xy = min(d1.xy, d1.zw);
-# endif
- gl_FragDepth = min(d1.x, d1.y);
-#endif
-
- c1 = c1 + c2;
-#if SAMPLES > 2
- c1 += c3 + c4;
-#endif
-#if SAMPLES > 4
- c1 += c5 + c6 + c7 + c8;
-#endif
-#if SAMPLES > 8
- c1 += c9 + c10 + c11 + c12 + c13 + c14 + c15 + c16;
-#endif
-
- const float inv_samples = 1.0 / float(SAMPLES);
-
- fragColor = c1 * inv_samples;
-}
diff --git a/source/blender/gpu/shaders/gpu_shader_simple_lighting_smooth_color_alpha_frag.glsl b/source/blender/gpu/shaders/gpu_shader_simple_lighting_smooth_color_alpha_frag.glsl
deleted file mode 100644
index 2ed99be2bcf..00000000000
--- a/source/blender/gpu/shaders/gpu_shader_simple_lighting_smooth_color_alpha_frag.glsl
+++ /dev/null
@@ -1,14 +0,0 @@
-
-uniform vec3 light;
-uniform float alpha;
-uniform float global;
-
-in vec3 normal;
-in vec4 finalColor;
-out vec4 fragColor;
-
-void main()
-{
- fragColor = finalColor * (global + (1.0 - global) * max(0.0, dot(normalize(normal), light)));
- fragColor.a = alpha;
-}
diff --git a/source/blender/gpu/shaders/gpu_shader_simple_lighting_smooth_color_frag.glsl b/source/blender/gpu/shaders/gpu_shader_simple_lighting_smooth_color_frag.glsl
deleted file mode 100644
index 738b0d84e51..00000000000
--- a/source/blender/gpu/shaders/gpu_shader_simple_lighting_smooth_color_frag.glsl
+++ /dev/null
@@ -1,16 +0,0 @@
-
-uniform vec3 light;
-
-#ifdef USE_FLAT_NORMAL
-flat in vec3 normal;
-flat in vec4 finalColor;
-#else
-in vec3 normal;
-in vec4 finalColor;
-#endif
-out vec4 fragColor;
-
-void main()
-{
- fragColor = finalColor * max(0.0, dot(normalize(normal), light));
-}
diff --git a/source/blender/gpu/shaders/gpu_shader_uniform_color_frag.glsl b/source/blender/gpu/shaders/gpu_shader_uniform_color_frag.glsl
index cfa82572e87..d9f84964eb4 100644
--- a/source/blender/gpu/shaders/gpu_shader_uniform_color_frag.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_uniform_color_frag.glsl
@@ -17,8 +17,4 @@ void main()
#else
fragColor = color;
#endif
-
-#if defined(USE_BACKGROUND)
- gl_FragDepth = 1.0;
-#endif
}
diff --git a/source/blender/imbuf/IMB_colormanagement.h b/source/blender/imbuf/IMB_colormanagement.h
index 5f149f0ab71..1639fb4715f 100644
--- a/source/blender/imbuf/IMB_colormanagement.h
+++ b/source/blender/imbuf/IMB_colormanagement.h
@@ -199,8 +199,8 @@ void IMB_colormanagement_buffer_make_display_space(
void IMB_colormanagement_display_settings_from_ctx(
const struct bContext *C,
- struct ColorManagedViewSettings **view_settings_r,
- struct ColorManagedDisplaySettings **display_settings_r);
+ struct ColorManagedViewSettings **r_view_settings,
+ struct ColorManagedDisplaySettings **r_display_settings);
const char *IMB_colormanagement_get_display_colorspace_name(
const struct ColorManagedViewSettings *view_settings,
diff --git a/source/blender/imbuf/IMB_moviecache.h b/source/blender/imbuf/IMB_moviecache.h
index 175a18ef618..5fb158f0d8b 100644
--- a/source/blender/imbuf/IMB_moviecache.h
+++ b/source/blender/imbuf/IMB_moviecache.h
@@ -72,7 +72,7 @@ void IMB_moviecache_cleanup(struct MovieCache *cache,
void *userdata);
void IMB_moviecache_get_cache_segments(
- struct MovieCache *cache, int proxy, int render_flags, int *totseg_r, int **points_r);
+ struct MovieCache *cache, int proxy, int render_flags, int *r_totseg, int **r_points);
struct MovieCacheIter;
struct MovieCacheIter *IMB_moviecacheIter_new(struct MovieCache *cache);
diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c
index a95db5c1de4..c57ab70f4e6 100644
--- a/source/blender/imbuf/intern/colormanagement.c
+++ b/source/blender/imbuf/intern/colormanagement.c
@@ -789,18 +789,18 @@ void colormanage_cache_free(ImBuf *ibuf)
void IMB_colormanagement_display_settings_from_ctx(
const bContext *C,
- ColorManagedViewSettings **view_settings_r,
- ColorManagedDisplaySettings **display_settings_r)
+ ColorManagedViewSettings **r_view_settings,
+ ColorManagedDisplaySettings **r_display_settings)
{
Scene *scene = CTX_data_scene(C);
SpaceImage *sima = CTX_wm_space_image(C);
- *view_settings_r = &scene->view_settings;
- *display_settings_r = &scene->display_settings;
+ *r_view_settings = &scene->view_settings;
+ *r_display_settings = &scene->display_settings;
if (sima && sima->image) {
if ((sima->image->flag & IMA_VIEW_AS_RENDER) == 0) {
- *view_settings_r = NULL;
+ *r_view_settings = NULL;
}
}
}
diff --git a/source/blender/imbuf/intern/moviecache.c b/source/blender/imbuf/intern/moviecache.c
index f3b76288831..96ecbdce9cc 100644
--- a/source/blender/imbuf/intern/moviecache.c
+++ b/source/blender/imbuf/intern/moviecache.c
@@ -479,10 +479,10 @@ void IMB_moviecache_cleanup(MovieCache *cache,
/* get segments of cached frames. useful for debugging cache policies */
void IMB_moviecache_get_cache_segments(
- MovieCache *cache, int proxy, int render_flags, int *totseg_r, int **points_r)
+ MovieCache *cache, int proxy, int render_flags, int *r_totseg, int **r_points)
{
- *totseg_r = 0;
- *points_r = NULL;
+ *r_totseg = 0;
+ *r_points = NULL;
if (!cache->getdatafp) {
return;
@@ -497,8 +497,8 @@ void IMB_moviecache_get_cache_segments(
}
if (cache->points) {
- *totseg_r = cache->totseg;
- *points_r = cache->points;
+ *r_totseg = cache->totseg;
+ *r_points = cache->points;
}
else {
int totframe = BLI_ghash_len(cache->hash);
@@ -555,8 +555,8 @@ void IMB_moviecache_get_cache_segments(
}
}
- *totseg_r = totseg;
- *points_r = points;
+ *r_totseg = totseg;
+ *r_points = points;
cache->totseg = totseg;
cache->points = points;
diff --git a/source/blender/io/usd/intern/abstract_hierarchy_iterator.h b/source/blender/io/usd/intern/abstract_hierarchy_iterator.h
index f7ba1a76bac..08b50e2560d 100644
--- a/source/blender/io/usd/intern/abstract_hierarchy_iterator.h
+++ b/source/blender/io/usd/intern/abstract_hierarchy_iterator.h
@@ -69,7 +69,7 @@ struct HierarchyContext {
* have weak_export=true, this object (and by recursive reasoning all its descendants) will be
* excluded from the export.
*
- * The export hierarchy is kept as close to the the hierarchy in Blender as possible. As such, an
+ * The export hierarchy is kept as close to the hierarchy in Blender as possible. As such, an
* object that serves as a parent for another object, but which should NOT be exported itself, is
* exported only as transform (i.e. as empty). This happens with objects that are part of a
* holdout collection (which prevents them from being exported) but also parent of an exported
diff --git a/source/blender/makesdna/DNA_brush_types.h b/source/blender/makesdna/DNA_brush_types.h
index 1fad828e887..95d9216f550 100644
--- a/source/blender/makesdna/DNA_brush_types.h
+++ b/source/blender/makesdna/DNA_brush_types.h
@@ -281,11 +281,21 @@ typedef enum eBrushClothDeformType {
BRUSH_CLOTH_DEFORM_EXPAND = 6,
} eBrushClothDeformType;
+typedef enum eBrushSmoothDeformType {
+ BRUSH_SMOOTH_DEFORM_LAPLACIAN = 0,
+ BRUSH_SMOOTH_DEFORM_SURFACE = 1,
+} eBrushSmoothDeformType;
+
typedef enum eBrushClothForceFalloffType {
BRUSH_CLOTH_FORCE_FALLOFF_RADIAL = 0,
BRUSH_CLOTH_FORCE_FALLOFF_PLANE = 1,
} eBrushClothForceFalloffType;
+typedef enum eBrushPoseOriginType {
+ BRUSH_POSE_ORIGIN_TOPOLOGY = 0,
+ BRUSH_POSE_ORIGIN_FACE_SETS = 1,
+} eBrushPoseOriginType;
+
/* Gpencilsettings.Vertex_mode */
typedef enum eGp_Vertex_Mode {
/* Affect to Stroke only. */
@@ -401,7 +411,7 @@ typedef struct Brush {
/** Source for fill tool color gradient application. */
char gradient_fill_mode;
- char _pad0[5];
+ char _pad0[1];
/** Projection shape (sphere, circle). */
char falloff_shape;
@@ -462,6 +472,7 @@ typedef struct Brush {
float pose_offset;
int pose_smooth_iterations;
int pose_ik_segments;
+ int pose_origin_type;
/* cloth */
int cloth_deform_type;
@@ -473,6 +484,12 @@ typedef struct Brush {
float cloth_sim_limit;
float cloth_sim_falloff;
+ /* smooth */
+ int smooth_deform_type;
+ float surface_smooth_shape_preservation;
+ float surface_smooth_current_vertex;
+ int surface_smooth_iterations;
+
/* multiplane scrape */
float multiplane_scrape_angle;
diff --git a/source/blender/makesdna/DNA_gpencil_types.h b/source/blender/makesdna/DNA_gpencil_types.h
index a90935bfe62..a3b1f315f04 100644
--- a/source/blender/makesdna/DNA_gpencil_types.h
+++ b/source/blender/makesdna/DNA_gpencil_types.h
@@ -468,7 +468,7 @@ typedef enum eGPDlayer_OnionFlag {
/* layer blend_mode */
typedef enum eGPLayerBlendModes {
eGplBlendMode_Regular = 0,
- eGplBlendMode_Overlay = 1,
+ eGplBlendMode_HardLight = 1,
eGplBlendMode_Add = 2,
eGplBlendMode_Subtract = 3,
eGplBlendMode_Multiply = 4,
@@ -661,8 +661,6 @@ typedef enum eGPdata_Flag {
/* Autolock not active layers */
GP_DATA_AUTOLOCK_LAYERS = (1 << 20),
- /* Internal flag for python update */
- GP_DATA_PYTHON_UPDATED = (1 << 21),
} eGPdata_Flag;
/* gpd->onion_flag */
diff --git a/source/blender/makesdna/DNA_material_types.h b/source/blender/makesdna/DNA_material_types.h
index f2e65ff9251..10a549edc17 100644
--- a/source/blender/makesdna/DNA_material_types.h
+++ b/source/blender/makesdna/DNA_material_types.h
@@ -87,7 +87,7 @@ typedef struct MaterialGPencilStyle {
/** Factor to shift texture in 2d space. */
float texture_offset[2];
/** Texture opacity. */
- float texture_opacity;
+ float texture_opacity DNA_DEPRECATED;
/** Pixel size for uv along the stroke. */
float texture_pixsize;
/** Drawing mode (line or dots). */
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 13c5a0913c6..74cb72a1fae 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -1148,6 +1148,8 @@ typedef struct SolidifyModifierData {
/** Name of vertex group to use, MAX_VGROUP_NAME. */
char defgrp_name[64];
+ char shell_defgrp_name[64];
+ char rim_defgrp_name[64];
/** New surface offset leve.l*/
float offset;
/** Midpoint of the offset . */
@@ -1324,6 +1326,11 @@ typedef struct WarpModifierData {
struct Object *object_from;
struct Object *object_to;
+ /** Optional name of bone target, MAX_ID_NAME-2. */
+ char bone_from[64];
+ /** Optional name of bone target, MAX_ID_NAME-2. */
+ char bone_to[64];
+
struct CurveMapping *curfalloff;
/** Optional vertexgroup name, MAX_VGROUP_NAME. */
char defgrp_name[64];
@@ -1397,7 +1404,8 @@ typedef struct WeightVGEditModifierData {
/* WeightVGEdit flags. */
enum {
- /* (1 << 0) and (1 << 1) are free for future use! */
+ /* (1 << 0) is free for future use! */
+ MOD_WVG_INVERT_FALLOFF = (1 << 1),
MOD_WVG_EDIT_INVERT_VGROUP_MASK = (1 << 2),
/** Add vertices with higher weight than threshold to vgroup. */
MOD_WVG_EDIT_ADD2VG = (1 << 3),
@@ -1541,6 +1549,7 @@ enum {
/* Use nearest faces of target obj, in MOD_WVG_PROXIMITY_GEOMETRY mode. */
MOD_WVG_PROXIMITY_GEOM_FACES = (1 << 2),
MOD_WVG_PROXIMITY_INVERT_VGROUP_MASK = (1 << 3),
+ MOD_WVG_PROXIMITY_INVERT_FALLOFF = (1 << 4),
};
/* Defines common to all WeightVG modifiers. */
@@ -2037,12 +2046,16 @@ typedef struct SurfaceDeformModifierData {
unsigned int numverts, numpoly;
int flags;
float mat[4][4];
+ float strength;
+ char _pad[4];
+ char defgrp_name[64];
} SurfaceDeformModifierData;
/* Surface Deform modifier flags */
enum {
/* This indicates "do bind on next modifier evaluation" as well as "is bound". */
MOD_SDEF_BIND = (1 << 0),
+ MOD_SDEF_INVERT_VGROUP = (1 << 1)
/* MOD_SDEF_USES_LOOPTRI = (1 << 1), */ /* UNUSED */
/* MOD_SDEF_HAS_CONCAVE = (1 << 2), */ /* UNUSED */
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index c1a6265b53b..7837c1265ab 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -731,13 +731,12 @@ typedef struct RenderData {
char seq_rend_type;
/** Flag use for sequence render/draw. */
char seq_flag;
- char _pad5[5];
+ char _pad5[7];
/* render simplify */
short simplify_subsurf;
short simplify_subsurf_render;
short simplify_gpencil;
- short simplify_smoke_ignore_highres;
float simplify_particles;
float simplify_particles_render;
diff --git a/source/blender/makesdna/DNA_sound_types.h b/source/blender/makesdna/DNA_sound_types.h
index 73f0e20efcb..04ac9d4e5be 100644
--- a/source/blender/makesdna/DNA_sound_types.h
+++ b/source/blender/makesdna/DNA_sound_types.h
@@ -26,9 +26,6 @@
#include "DNA_ID.h"
#include "DNA_defs.h"
-/* stupid... could easily be solved */
-#include "DNA_view2d_types.h"
-
struct Ipo;
struct PackedFile;
@@ -104,7 +101,7 @@ typedef enum eSound_Type {
} eSound_Type;
#endif
-/* bSound->flags */
+/** #bSound.flags */
enum {
#ifdef DNA_DEPRECATED_ALLOW
/* deprecated! used for sound actuator loading */
@@ -114,13 +111,11 @@ enum {
SOUND_FLAGS_MONO = (1 << 5),
};
-/* bSound->tags */
+/** #bSound.tags */
enum {
/* Do not free/reset waveform on sound load, only used by undo code. */
SOUND_TAGS_WAVEFORM_NO_RELOAD = 1 << 0,
SOUND_TAGS_WAVEFORM_LOADING = (1 << 6),
};
-/* to DNA_sound_types.h*/
-
-#endif
+#endif /* __DNA_SOUND_TYPES_H__ */
diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h
index d3cce8d1510..3020e5a1708 100644
--- a/source/blender/makesdna/DNA_space_types.h
+++ b/source/blender/makesdna/DNA_space_types.h
@@ -955,7 +955,10 @@ typedef struct FileDirEntry {
/** ID type, in case typeflag has FILE_TYPE_BLENDERLIB set. */
int blentype;
+ /* Path to item that is relative to current folder root. */
char *relpath;
+ /** Optional argument for shortcuts, aliases etc. */
+ char *redirection_path;
/** TODO: make this a real ID pointer? */
void *poin;
diff --git a/source/blender/makesrna/intern/rna_action.c b/source/blender/makesrna/intern/rna_action.c
index 0685fb270f1..a3a89db66be 100644
--- a/source/blender/makesrna/intern/rna_action.c
+++ b/source/blender/makesrna/intern/rna_action.c
@@ -662,6 +662,12 @@ static void rna_def_action_group(BlenderRNA *brna)
prop, "Expanded in Graph Editor", "Action group is expanded in graph editor");
RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
+ prop = RNA_def_property(srna, "use_pin", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NO_DEG_UPDATE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", ADT_CURVES_ALWAYS_VISIBLE);
+ RNA_def_property_ui_text(prop, "Pin in Graph Editor", "");
+ RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
+
/* color set */
rna_def_actionbone_group_common(srna, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
}
diff --git a/source/blender/makesrna/intern/rna_animation.c b/source/blender/makesrna/intern/rna_animation.c
index 036bcfc6311..1ca1bf27156 100644
--- a/source/blender/makesrna/intern/rna_animation.c
+++ b/source/blender/makesrna/intern/rna_animation.c
@@ -1322,6 +1322,12 @@ static void rna_def_animdata(BlenderRNA *brna)
prop, "Use NLA Tweak Mode", "Whether to enable or disable tweak mode in NLA");
RNA_def_property_update(prop, NC_ANIMATION | ND_NLA, "rna_AnimData_update");
+ prop = RNA_def_property(srna, "use_pin", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NO_DEG_UPDATE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", ADT_CURVES_ALWAYS_VISIBLE);
+ RNA_def_property_ui_text(prop, "Pin in Graph Editor", "");
+ RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
+
/* Animation Data API */
RNA_api_animdata(srna);
}
diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c
index a4091718487..75201322094 100644
--- a/source/blender/makesrna/intern/rna_brush.c
+++ b/source/blender/makesrna/intern/rna_brush.c
@@ -1794,6 +1794,35 @@ static void rna_def_brush(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL},
};
+ static const EnumPropertyItem brush_smooth_deform_type_items[] = {
+ {BRUSH_SMOOTH_DEFORM_LAPLACIAN,
+ "LAPLACIAN",
+ 0,
+ "Laplacian",
+ "Smooths the surface and the volume"},
+ {BRUSH_SMOOTH_DEFORM_SURFACE,
+ "SURFACE",
+ 0,
+ "Surface",
+ "Smooths the surface of the mesh, preserving the volue"},
+ {0, NULL, 0, NULL, NULL},
+ };
+
+ static const EnumPropertyItem brush_pose_origin_type_items[] = {
+ {BRUSH_POSE_ORIGIN_TOPOLOGY,
+ "TOPOLOGY",
+ 0,
+ "Topology",
+ "Sets the rotation origin automatically using the topology and shape of the mesh as a "
+ "guide"},
+ {BRUSH_POSE_ORIGIN_FACE_SETS,
+ "FACE_SETS",
+ 0,
+ "Face Sets",
+ "Creates a pose segment per face sets, starting from the active face set"},
+ {0, NULL, 0, NULL, NULL},
+ };
+
srna = RNA_def_struct(brna, "Brush", "ID");
RNA_def_struct_ui_text(
srna, "Brush", "Brush data-block for storing brush settings for painting and sculpting");
@@ -1909,6 +1938,18 @@ static void rna_def_brush(BlenderRNA *brna)
prop, "Force Falloff", "Shape used in the brush to apply force to the cloth");
RNA_def_property_update(prop, 0, "rna_Brush_update");
+ prop = RNA_def_property(srna, "smooth_deform_type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, brush_smooth_deform_type_items);
+ RNA_def_property_ui_text(prop, "Deformation", "Deformation type that is used in the brush");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
+
+ prop = RNA_def_property(srna, "pose_origin_type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, brush_pose_origin_type_items);
+ RNA_def_property_ui_text(prop,
+ "Rotation Origins",
+ "Method to set the rotation origins for the segments of the brush");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
+
prop = RNA_def_property(srna, "jitter_unit", PROP_ENUM, PROP_NONE); /* as an enum */
RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
RNA_def_property_enum_items(prop, brush_jitter_unit_items);
@@ -2101,6 +2142,29 @@ static void rna_def_brush(BlenderRNA *brna)
prop, "Pose Origin Offset", "Offset of the pose origin in relation to the brush radius");
RNA_def_property_update(prop, 0, "rna_Brush_update");
+ prop = RNA_def_property(srna, "surface_smooth_shape_preservation", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_sdna(prop, NULL, "surface_smooth_shape_preservation");
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_ui_text(
+ prop, "Shape Preservation", "How much of the original shape is preserved when smoothing");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
+
+ prop = RNA_def_property(srna, "surface_smooth_current_vertex", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_sdna(prop, NULL, "surface_smooth_current_vertex");
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_ui_text(
+ prop,
+ "Per Vertex Displacement",
+ "How much the position of each individual vertex influences the final result");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
+
+ prop = RNA_def_property(srna, "surface_smooth_iterations", PROP_INT, PROP_UNSIGNED);
+ RNA_def_property_int_sdna(prop, NULL, "surface_smooth_iterations");
+ RNA_def_property_range(prop, 1, 10);
+ RNA_def_property_ui_range(prop, 1, 10, 1, 3);
+ RNA_def_property_ui_text(prop, "Iterations", "Number of smoothing iterations per brush step");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
+
prop = RNA_def_property(srna, "multiplane_scrape_angle", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "multiplane_scrape_angle");
RNA_def_property_range(prop, 0.0f, 160.0f);
@@ -2135,7 +2199,7 @@ static void rna_def_brush(BlenderRNA *brna)
prop = RNA_def_property(srna, "cloth_mass", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "cloth_mass");
RNA_def_property_range(prop, 0.01f, 2.0f);
- RNA_def_property_ui_text(prop, "Cloth mass", "Mass of each simulation particle");
+ RNA_def_property_ui_text(prop, "Cloth Mass", "Mass of each simulation particle");
RNA_def_property_update(prop, 0, "rna_Brush_update");
prop = RNA_def_property(srna, "cloth_damping", PROP_FLOAT, PROP_FACTOR);
@@ -2322,7 +2386,8 @@ static void rna_def_brush(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_automasking_boundary_edges", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "automasking_flags", BRUSH_AUTOMASKING_BOUNDARY_EDGES);
- RNA_def_property_ui_text(prop, "Edges Automasking", "Do not affect non manifold boundary edges");
+ RNA_def_property_ui_text(
+ prop, "Mesh Boundary Auto-masking", "Do not affect non manifold boundary edges");
RNA_def_property_update(prop, 0, "rna_Brush_update");
prop = RNA_def_property(srna, "use_scene_spacing", PROP_ENUM, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_gpencil.c b/source/blender/makesrna/intern/rna_gpencil.c
index deacd8e1cfc..4afa467d2e3 100644
--- a/source/blender/makesrna/intern/rna_gpencil.c
+++ b/source/blender/makesrna/intern/rna_gpencil.c
@@ -114,7 +114,7 @@ static const EnumPropertyItem rna_enum_gplayer_move_type_items[] = {
static const EnumPropertyItem rna_enum_layer_blend_modes_items[] = {
{eGplBlendMode_Regular, "REGULAR", 0, "Regular", ""},
- {eGplBlendMode_Overlay, "OVERLAY", 0, "Overlay", ""},
+ {eGplBlendMode_HardLight, "HARDLIGHT", 0, "Hard Light", ""},
{eGplBlendMode_Add, "ADD", 0, "Add", ""},
{eGplBlendMode_Subtract, "SUBTRACT", 0, "Subtract", ""},
{eGplBlendMode_Multiply, "MULTIPLY", 0, "Multiply", ""},
@@ -642,7 +642,6 @@ static void rna_GPencil_stroke_point_add(
/* Calc geometry data. */
BKE_gpencil_stroke_geometry_update(stroke);
- gpd->flag |= GP_DATA_PYTHON_UPDATED;
DEG_id_tag_update(&gpd->id,
ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE);
@@ -704,7 +703,6 @@ static void rna_GPencil_stroke_point_pop(ID *id,
/* Calc geometry data. */
BKE_gpencil_stroke_geometry_update(stroke);
- gpd->flag |= GP_DATA_PYTHON_UPDATED;
DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE);
WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL);
diff --git a/source/blender/makesrna/intern/rna_gpencil_modifier.c b/source/blender/makesrna/intern/rna_gpencil_modifier.c
index 31775a70af6..6c3f26003fa 100644
--- a/source/blender/makesrna/intern/rna_gpencil_modifier.c
+++ b/source/blender/makesrna/intern/rna_gpencil_modifier.c
@@ -73,6 +73,11 @@ const EnumPropertyItem rna_enum_object_greasepencil_modifier_type_items[] = {
ICON_MOD_MIRROR,
"Mirror",
"Duplicate strokes like a mirror"},
+ {eGpencilModifierType_Multiply,
+ "GP_MULTIPLY",
+ ICON_GP_MULTIFRAME_EDITING,
+ "Multiple Strokes",
+ "Produce multiple strokes along one stroke"},
{eGpencilModifierType_Simplify,
"GP_SIMPLIFY",
ICON_MOD_SIMPLIFY,
@@ -83,11 +88,6 @@ const EnumPropertyItem rna_enum_object_greasepencil_modifier_type_items[] = {
ICON_MOD_SUBSURF,
"Subdivide",
"Subdivide stroke adding more control points"},
- {eGpencilModifierType_Multiply,
- "GP_MULTIPLY",
- ICON_GP_MULTIFRAME_EDITING,
- "Multiple Strokes",
- "Produce multiple strokes along one stroke"},
{0, "", 0, N_("Deform"), ""},
{eGpencilModifierType_Armature,
"GP_ARMATURE",
@@ -1022,7 +1022,7 @@ static void rna_def_modifier_gpenciltint(BlenderRNA *brna)
static EnumPropertyItem tint_mode_types_items[] = {
{GPPAINT_MODE_STROKE, "STROKE", 0, "Stroke", "Vertex Color affects to Stroke only"},
{GPPAINT_MODE_FILL, "FILL", 0, "Fill", "Vertex Color affects to Fill only"},
- {GPPAINT_MODE_BOTH, "BOTH", 0, "Both", "Vertex Color affects to Stroke and Fill"},
+ {GPPAINT_MODE_BOTH, "BOTH", 0, "Stroke and Fill", "Vertex Color affects to Stroke and Fill"},
{0, NULL, 0, NULL, NULL},
};
diff --git a/source/blender/makesrna/intern/rna_image.c b/source/blender/makesrna/intern/rna_image.c
index 2797f3a2d84..73504200020 100644
--- a/source/blender/makesrna/intern/rna_image.c
+++ b/source/blender/makesrna/intern/rna_image.c
@@ -57,7 +57,7 @@ static const EnumPropertyItem image_source_items[] = {
{IMA_SRC_MOVIE, "MOVIE", 0, "Movie", "Movie file"},
{IMA_SRC_GENERATED, "GENERATED", 0, "Generated", "Generated image"},
{IMA_SRC_VIEWER, "VIEWER", 0, "Viewer", "Compositing node viewer"},
- {IMA_SRC_TILED, "TILED", 0, "Tiled", "Tiled image texture"},
+ {IMA_SRC_TILED, "TILED", 0, "UDIM Tiles", "Tiled UDIM image texture"},
{0, NULL, 0, NULL, NULL},
};
@@ -1001,7 +1001,7 @@ static void rna_def_image(BlenderRNA *brna)
RNA_def_property_update(prop, NC_IMAGE | ND_DISPLAY, "rna_Image_generated_update");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- prop = RNA_def_property(srna, "generated_width", PROP_INT, PROP_NONE);
+ prop = RNA_def_property(srna, "generated_width", PROP_INT, PROP_PIXEL);
RNA_def_property_int_sdna(prop, NULL, "gen_x");
RNA_def_property_flag(prop, PROP_PROPORTIONAL);
RNA_def_property_range(prop, 1, 65536);
@@ -1009,7 +1009,7 @@ static void rna_def_image(BlenderRNA *brna)
RNA_def_property_update(prop, NC_IMAGE | ND_DISPLAY, "rna_Image_generated_update");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- prop = RNA_def_property(srna, "generated_height", PROP_INT, PROP_NONE);
+ prop = RNA_def_property(srna, "generated_height", PROP_INT, PROP_PIXEL);
RNA_def_property_int_sdna(prop, NULL, "gen_y");
RNA_def_property_flag(prop, PROP_PROPORTIONAL);
RNA_def_property_range(prop, 1, 65536);
diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c
index 5c1697c70f4..127341e6801 100644
--- a/source/blender/makesrna/intern/rna_material.c
+++ b/source/blender/makesrna/intern/rna_material.c
@@ -520,13 +520,6 @@ static void rna_def_material_greasepencil(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Offset", "Shift Texture in 2d Space");
RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialGpencil_update");
- /* Texture opacity size */
- prop = RNA_def_property(srna, "texture_opacity", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "texture_opacity");
- RNA_def_property_range(prop, 0.0f, 1.0f);
- RNA_def_property_ui_text(prop, "Opacity", "Texture Opacity");
- RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialGpencil_update");
-
/* texture pixsize factor (used for UV along the stroke) */
prop = RNA_def_property(srna, "pixel_size", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "texture_pixsize");
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index a91dd2e33c7..455fb1c50c9 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -93,7 +93,7 @@ const EnumPropertyItem rna_enum_object_modifier_type_items[] = {
"UV_WARP",
ICON_MOD_UVPROJECT,
"UV Warp",
- "Transform the UV map using the the difference between two objects"},
+ "Transform the UV map using the difference between two objects"},
{eModifierType_WeightVGEdit,
"VERTEX_WEIGHT_EDIT",
ICON_MOD_VERTEX_WEIGHT,
@@ -275,6 +275,7 @@ const EnumPropertyItem rna_enum_object_modifier_type_items[] = {
ICON_MOD_EXPLODE,
"Explode",
"Break apart the mesh faces and let them follow particles"},
+ {eModifierType_Fluid, "FLUID", ICON_MOD_FLUIDSIM, "Fluid Simulation", ""},
{eModifierType_Ocean, "OCEAN", ICON_MOD_OCEAN, "Ocean", "Generate a moving ocean surface"},
{eModifierType_ParticleInstance,
"PARTICLE_INSTANCE",
@@ -286,7 +287,6 @@ const EnumPropertyItem rna_enum_object_modifier_type_items[] = {
ICON_MOD_PARTICLES,
"Particle System",
"Spawn particles from the shape"},
- {eModifierType_Fluid, "FLUID", ICON_MOD_FLUIDSIM, "Fluid Simulation", ""},
{eModifierType_Softbody, "SOFT_BODY", ICON_MOD_SOFT, "Soft Body", ""},
{eModifierType_Surface, "SURFACE", ICON_MODIFIER, "Surface", ""},
{0, NULL, 0, NULL, NULL},
@@ -797,6 +797,9 @@ RNA_MOD_VGROUP_NAME_SET(Shrinkwrap, vgroup_name);
RNA_MOD_VGROUP_NAME_SET(SimpleDeform, vgroup_name);
RNA_MOD_VGROUP_NAME_SET(Smooth, defgrp_name);
RNA_MOD_VGROUP_NAME_SET(Solidify, defgrp_name);
+RNA_MOD_VGROUP_NAME_SET(Solidify, shell_defgrp_name);
+RNA_MOD_VGROUP_NAME_SET(Solidify, rim_defgrp_name);
+RNA_MOD_VGROUP_NAME_SET(SurfaceDeform, defgrp_name);
RNA_MOD_VGROUP_NAME_SET(UVWarp, vgroup_name);
RNA_MOD_VGROUP_NAME_SET(Warp, defgrp_name);
RNA_MOD_VGROUP_NAME_SET(Wave, defgrp_name);
@@ -1795,17 +1798,29 @@ static void rna_def_modifier_warp(BlenderRNA *brna)
RNA_def_struct_ui_icon(srna, ICON_MOD_WARP);
prop = RNA_def_property(srna, "object_from", PROP_POINTER, PROP_NONE);
- RNA_def_property_ui_text(prop, "From", "Object to transform from");
+ RNA_def_property_pointer_sdna(prop, NULL, "object_from");
+ RNA_def_property_ui_text(prop, "Object From", "Object to transform from");
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK);
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
+ prop = RNA_def_property(srna, "bone_from", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "bone_from");
+ RNA_def_property_ui_text(prop, "Bone From", "Bone to transform from");
+ RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
+
prop = RNA_def_property(srna, "object_to", PROP_POINTER, PROP_NONE);
- RNA_def_property_ui_text(prop, "To", "Object to transform to");
+ RNA_def_property_pointer_sdna(prop, NULL, "object_to");
+ RNA_def_property_ui_text(prop, "Object To", "Object to transform to");
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK);
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
+ prop = RNA_def_property(srna, "bone_to", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "bone_to");
+ RNA_def_property_ui_text(prop, "Bone To", "Bone defining offset");
+ RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
+
prop = RNA_def_property(srna, "strength", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);
RNA_def_property_ui_range(prop, -100, 100, 10, 2);
@@ -4437,6 +4452,22 @@ static void rna_def_modifier_solidify(BlenderRNA *brna)
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_SolidifyModifier_defgrp_name_set");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
+ prop = RNA_def_property(srna, "shell_vertex_group", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "shell_defgrp_name");
+ RNA_def_property_ui_text(prop,
+ "Shell Vertex Group",
+ "Vertex group that the generated shell geometry will be weighted to");
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_SolidifyModifier_shell_defgrp_name_set");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_property(srna, "rim_vertex_group", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "rim_defgrp_name");
+ RNA_def_property_ui_text(prop,
+ "Rim Vertex Group",
+ "Vertex group that the generated rim geometry will be weighted to");
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_SolidifyModifier_rim_defgrp_name_set");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
prop = RNA_def_property(srna, "use_rim", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_SOLIDIFY_RIM);
RNA_def_property_ui_text(prop,
@@ -4507,14 +4538,14 @@ static void rna_def_modifier_screw(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
prop = RNA_def_property(srna, "steps", PROP_INT, PROP_UNSIGNED);
- RNA_def_property_range(prop, 2, 10000);
- RNA_def_property_ui_range(prop, 3, 512, 1, -1);
+ RNA_def_property_range(prop, 1, 10000);
+ RNA_def_property_ui_range(prop, 1, 512, 1, -1);
RNA_def_property_ui_text(prop, "Steps", "Number of steps in the revolution");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "render_steps", PROP_INT, PROP_UNSIGNED);
- RNA_def_property_range(prop, 2, 10000);
- RNA_def_property_ui_range(prop, 2, 512, 1, -1);
+ RNA_def_property_range(prop, 1, 10000);
+ RNA_def_property_ui_range(prop, 1, 512, 1, -1);
RNA_def_property_ui_text(prop, "Render Steps", "Number of steps in the revolution");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
@@ -4802,6 +4833,16 @@ static void rna_def_modifier_weightvgedit(BlenderRNA *brna)
RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_CURVE); /* Abusing id_curve :/ */
RNA_def_property_update(prop, 0, "rna_Modifier_update");
+ prop = RNA_def_property(srna, "invert_falloff", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "edit_flags", MOD_WVG_INVERT_FALLOFF);
+ RNA_def_property_ui_text(prop, "Invert Falloff", "Invert the resulting falloff weight");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_property(srna, "map_curve", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "cmap_curve");
+ RNA_def_property_ui_text(prop, "Mapping Curve", "Custom mapping curve");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
prop = RNA_def_property(srna, "use_add", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "edit_flags", MOD_WVG_EDIT_ADD2VG);
RNA_def_property_ui_text(prop,
@@ -4827,11 +4868,6 @@ static void rna_def_modifier_weightvgedit(BlenderRNA *brna)
"it is not in the vgroup");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
- prop = RNA_def_property(srna, "map_curve", PROP_POINTER, PROP_NONE);
- RNA_def_property_pointer_sdna(prop, NULL, "cmap_curve");
- RNA_def_property_ui_text(prop, "Mapping Curve", "Custom mapping curve");
- RNA_def_property_update(prop, 0, "rna_Modifier_update");
-
prop = RNA_def_property(srna, "add_threshold", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "add_threshold");
RNA_def_property_range(prop, 0.0, 1.0);
@@ -5060,6 +5096,11 @@ static void rna_def_modifier_weightvgproximity(BlenderRNA *brna)
RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_CURVE); /* Abusing id_curve :/ */
RNA_def_property_update(prop, 0, "rna_Modifier_update");
+ prop = RNA_def_property(srna, "invert_falloff", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "proximity_flags", MOD_WVG_PROXIMITY_INVERT_FALLOFF);
+ RNA_def_property_ui_text(prop, "Invert Falloff", "Invert the resulting falloff weight");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
/* Common masking properties. */
rna_def_modifier_weightvg_mask(brna,
srna,
@@ -6349,6 +6390,24 @@ static void rna_def_modifier_surfacedeform(BlenderRNA *brna)
RNA_def_property_boolean_funcs(prop, "rna_SurfaceDeformModifier_is_bound_get", NULL);
RNA_def_property_ui_text(prop, "Bound", "Whether geometry has been bound to target mesh");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+
+ prop = RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "defgrp_name");
+ RNA_def_property_ui_text(
+ prop, "Vertex Group", "Vertex group name for selecting/weighting the affected areas");
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_SurfaceDeformModifier_defgrp_name_set");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_property(srna, "invert_vertex_group", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_SDEF_INVERT_VGROUP);
+ RNA_def_property_ui_text(prop, "Invert", "Invert vertex group influence");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_property(srna, "strength", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_range(prop, -100, 100);
+ RNA_def_property_ui_range(prop, -100, 100, 10, 2);
+ RNA_def_property_ui_text(prop, "Strength", "Strength of modifier deformations");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
}
static void rna_def_modifier_weightednormal(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c
index 959529450f0..112517a92e0 100644
--- a/source/blender/makesrna/intern/rna_object.c
+++ b/source/blender/makesrna/intern/rna_object.c
@@ -760,6 +760,24 @@ static PointerRNA rna_Object_active_vertex_group_get(PointerRNA *ptr)
ptr, &RNA_VertexGroup, BLI_findlink(&ob->defbase, ob->actdef - 1));
}
+static void rna_Object_active_vertex_group_set(PointerRNA *ptr,
+ PointerRNA value,
+ struct ReportList *reports)
+{
+ Object *ob = (Object *)ptr->owner_id;
+ int index = BLI_findindex(&ob->defbase, value.data);
+ if (index == -1) {
+ BKE_reportf(reports,
+ RPT_ERROR,
+ "VertexGroup '%s' not found in object '%s'",
+ ((bDeformGroup *)value.data)->name,
+ ob->id.name + 2);
+ return;
+ }
+
+ ob->actdef = index + 1;
+}
+
static int rna_Object_active_vertex_group_index_get(PointerRNA *ptr)
{
Object *ob = (Object *)ptr->owner_id;
@@ -2333,6 +2351,7 @@ static void rna_def_object_vertex_groups(BlenderRNA *brna, PropertyRNA *cprop)
"rna_Object_active_vertex_group_set",
NULL,
NULL);
+ RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Active Vertex Group", "Vertex groups of the object");
RNA_def_property_update(prop, NC_GEOM | ND_DATA, "rna_Object_internal_update_data");
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index 932ac72324e..289c5eae869 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -2340,7 +2340,7 @@ static void rna_Stereo3dFormat_update(Main *bmain, Scene *UNUSED(scene), Pointer
static ViewLayer *rna_ViewLayer_new(ID *id, Scene *UNUSED(sce), Main *bmain, const char *name)
{
Scene *scene = (Scene *)id;
- ViewLayer *view_layer = BKE_view_layer_add(scene, name);
+ ViewLayer *view_layer = BKE_view_layer_add(scene, name, NULL, VIEWLAYER_ADD_NEW);
DEG_id_tag_update(&scene->id, 0);
DEG_relations_tag_update(bmain);
@@ -2502,7 +2502,9 @@ static const EnumPropertyItem *rna_UnitSettings_itemf_wrapper(const int system,
}
}
+ RNA_enum_item_end(&items, &totitem);
*r_free = true;
+
return items;
}
@@ -2553,6 +2555,11 @@ static char *rna_UnitSettings_path(PointerRNA *UNUSED(ptr))
return BLI_strdup("unit_settings");
}
+static char *rna_FFmpegSettings_path(PointerRNA *UNUSED(ptr))
+{
+ return BLI_strdup("render.ffmpeg");
+}
+
#else
/* Grease Pencil Interpolation tool settings */
@@ -5459,6 +5466,7 @@ static void rna_def_scene_ffmpeg_settings(BlenderRNA *brna)
srna = RNA_def_struct(brna, "FFmpegSettings", NULL);
RNA_def_struct_sdna(srna, "FFMpegCodecData");
+ RNA_def_struct_path_func(srna, "rna_FFmpegSettings_path");
RNA_def_struct_ui_text(srna, "FFmpeg Settings", "FFmpeg related settings for the scene");
# ifdef WITH_FFMPEG
@@ -6372,12 +6380,6 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
prop, "Simplify Child Particles", "Global child particles percentage during rendering");
RNA_def_property_update(prop, 0, "rna_Scene_simplify_update");
- prop = RNA_def_property(srna, "use_simplify_smoke_highres", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_negative_sdna(prop, NULL, "simplify_smoke_ignore_highres", 1);
- RNA_def_property_ui_text(
- prop, "Use High-resolution Smoke", "Display high-resolution smoke in the viewport");
- RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
-
/* Grease Pencil - Simplify Options */
prop = RNA_def_property(srna, "simplify_gpencil", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "simplify_gpencil", SIMPLIFY_GPENCIL_ENABLE);
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index cf85cc888f8..302495a72af 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -859,7 +859,12 @@ static void rna_SpaceView3D_use_local_camera_set(PointerRNA *ptr, bool value)
if (!value) {
Scene *scene = ED_screen_scene_find(sc, G_MAIN->wm.first);
- v3d->camera = scene->camera;
+ /* NULL if the screen isn't in an active window (happens when setting from Python).
+ * This could be moved to the update function, in that case the scene wont relate to the screen
+ * so keep it working this way. */
+ if (scene != NULL) {
+ v3d->camera = scene->camera;
+ }
}
}
@@ -868,8 +873,13 @@ static float rna_View3DOverlay_GridScaleUnit_get(PointerRNA *ptr)
View3D *v3d = (View3D *)(ptr->data);
bScreen *screen = (bScreen *)ptr->owner_id;
Scene *scene = ED_screen_scene_find(screen, G_MAIN->wm.first);
-
- return ED_view3d_grid_scale(scene, v3d, NULL);
+ if (scene != NULL) {
+ return ED_view3d_grid_scale(scene, v3d, NULL);
+ }
+ else {
+ /* When accessed from non-active screen. */
+ return 1.0f;
+ }
}
static PointerRNA rna_SpaceView3D_region_3d_get(PointerRNA *ptr)
diff --git a/source/blender/makesrna/intern/rna_wm_api.c b/source/blender/makesrna/intern/rna_wm_api.c
index df6abecd365..4bed8c7bb8c 100644
--- a/source/blender/makesrna/intern/rna_wm_api.c
+++ b/source/blender/makesrna/intern/rna_wm_api.c
@@ -392,16 +392,34 @@ static PointerRNA rna_KeyMap_item_match_event(ID *id, wmKeyMap *km, bContext *C,
return kmi_ptr;
}
-static wmKeyMap *rna_keymap_new(
- wmKeyConfig *keyconf, const char *idname, int spaceid, int regionid, bool modal, bool tool)
+static wmKeyMap *rna_keymap_new(wmKeyConfig *keyconf,
+ ReportList *reports,
+ const char *idname,
+ int spaceid,
+ int regionid,
+ bool modal,
+ bool tool)
{
+ if (modal) {
+ /* Sanity check: Don't allow add-ons to override internal modal key-maps
+ * because this isn't supported, the restriction can be removed when
+ * add-ons can define modal key-maps.
+ * Currently this is only useful for add-ons to override built-in modal keymaps
+ * which is not the intended use for add-on keymaps. */
+ wmWindowManager *wm = G_MAIN->wm.first;
+ if (keyconf == wm->addonconf) {
+ BKE_reportf(reports, RPT_ERROR, "Modal key-maps not supported for add-on key-config");
+ return NULL;
+ }
+ }
+
wmKeyMap *keymap;
if (modal == 0) {
keymap = WM_keymap_ensure(keyconf, idname, spaceid, regionid);
}
else {
- keymap = WM_modalkeymap_add(keyconf, idname, NULL); /* items will be lazy init */
+ keymap = WM_modalkeymap_ensure(keyconf, idname, NULL); /* items will be lazy init */
}
if (keymap && tool) {
@@ -1180,6 +1198,7 @@ void RNA_api_keymaps(StructRNA *srna)
PropertyRNA *parm;
func = RNA_def_function(srna, "new", "rna_keymap_new"); /* add_keymap */
+ RNA_def_function_flag(func, FUNC_USE_REPORTS);
parm = RNA_def_string(func, "name", NULL, 0, "Name", "");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
RNA_def_enum(func, "space_type", rna_enum_space_type_items, SPACE_EMPTY, "Space Type", "");
diff --git a/source/blender/modifiers/intern/MOD_armature.c b/source/blender/modifiers/intern/MOD_armature.c
index 3e78662da6c..275c16873a8 100644
--- a/source/blender/modifiers/intern/MOD_armature.c
+++ b/source/blender/modifiers/intern/MOD_armature.c
@@ -234,7 +234,7 @@ static void deformMatrices(ModifierData *md,
amd->defgrp_name,
NULL);
- if (mesh_src != mesh) {
+ if (!ELEM(mesh_src, NULL, mesh)) {
BKE_id_free(NULL, mesh_src);
}
}
diff --git a/source/blender/modifiers/intern/MOD_cast.c b/source/blender/modifiers/intern/MOD_cast.c
index ed4a53ba2f3..eb6292e5e46 100644
--- a/source/blender/modifiers/intern/MOD_cast.c
+++ b/source/blender/modifiers/intern/MOD_cast.c
@@ -513,7 +513,7 @@ static void deformVertsEM(ModifierData *md,
sphere_do(cmd, ctx, ctx->object, mesh_src, vertexCos, numVerts);
}
- if (mesh_src != mesh) {
+ if (!ELEM(mesh_src, NULL, mesh)) {
BKE_id_free(NULL, mesh_src);
}
}
diff --git a/source/blender/modifiers/intern/MOD_collision.c b/source/blender/modifiers/intern/MOD_collision.c
index af468cb2d27..e1595488d08 100644
--- a/source/blender/modifiers/intern/MOD_collision.c
+++ b/source/blender/modifiers/intern/MOD_collision.c
@@ -231,7 +231,7 @@ static void deformVerts(ModifierData *md,
}
}
- if (mesh_src != mesh) {
+ if (!ELEM(mesh_src, NULL, mesh)) {
BKE_id_free(NULL, mesh_src);
}
}
diff --git a/source/blender/modifiers/intern/MOD_correctivesmooth.c b/source/blender/modifiers/intern/MOD_correctivesmooth.c
index 4eea9092e10..52003f8b1d8 100644
--- a/source/blender/modifiers/intern/MOD_correctivesmooth.c
+++ b/source/blender/modifiers/intern/MOD_correctivesmooth.c
@@ -740,7 +740,7 @@ static void deformVerts(ModifierData *md,
correctivesmooth_modifier_do(
md, ctx->depsgraph, ctx->object, mesh_src, vertexCos, (uint)numVerts, NULL);
- if (mesh_src != mesh) {
+ if (!ELEM(mesh_src, NULL, mesh)) {
BKE_id_free(NULL, mesh_src);
}
}
@@ -758,7 +758,7 @@ static void deformVertsEM(ModifierData *md,
correctivesmooth_modifier_do(
md, ctx->depsgraph, ctx->object, mesh_src, vertexCos, (uint)numVerts, editData);
- if (mesh_src != mesh) {
+ if (!ELEM(mesh_src, NULL, mesh)) {
BKE_id_free(NULL, mesh_src);
}
}
diff --git a/source/blender/modifiers/intern/MOD_multires.c b/source/blender/modifiers/intern/MOD_multires.c
index 742d100ac44..ad8e0a9f259 100644
--- a/source/blender/modifiers/intern/MOD_multires.c
+++ b/source/blender/modifiers/intern/MOD_multires.c
@@ -61,7 +61,7 @@ static void initData(ModifierData *md)
mmd->totlvl = 0;
mmd->uv_smooth = SUBSURF_UV_SMOOTH_PRESERVE_CORNERS;
mmd->quality = 4;
- mmd->flags |= eMultiresModifierFlag_UseCrease;
+ mmd->flags |= (eMultiresModifierFlag_UseCrease | eMultiresModifierFlag_ControlEdges);
}
static void copyData(const ModifierData *md_src, ModifierData *md_dst, const int flag)
@@ -119,11 +119,17 @@ static Mesh *multires_as_mesh(MultiresModifierData *mmd,
Mesh *result = mesh;
const bool use_render_params = (ctx->flag & MOD_APPLY_RENDER);
const bool ignore_simplify = (ctx->flag & MOD_APPLY_IGNORE_SIMPLIFY);
+ const bool ignore_control_edges = (ctx->flag & MOD_APPLY_TO_BASE_MESH);
const Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
Object *object = ctx->object;
SubdivToMeshSettings mesh_settings;
- BKE_multires_subdiv_mesh_settings_init(
- &mesh_settings, scene, object, mmd, use_render_params, ignore_simplify);
+ BKE_multires_subdiv_mesh_settings_init(&mesh_settings,
+ scene,
+ object,
+ mmd,
+ use_render_params,
+ ignore_simplify,
+ ignore_control_edges);
if (mesh_settings.resolution < 3) {
return result;
}
diff --git a/source/blender/modifiers/intern/MOD_particlesystem.c b/source/blender/modifiers/intern/MOD_particlesystem.c
index e6229e27e4b..05bfe9aeff0 100644
--- a/source/blender/modifiers/intern/MOD_particlesystem.c
+++ b/source/blender/modifiers/intern/MOD_particlesystem.c
@@ -189,7 +189,7 @@ static void deformVerts(ModifierData *md,
BKE_mesh_tessface_ensure(psmd->mesh_original);
}
- if (mesh_src != psmd->mesh_final && mesh_src != mesh) {
+ if (!ELEM(mesh_src, NULL, mesh, psmd->mesh_final)) {
BKE_id_free(NULL, mesh_src);
}
diff --git a/source/blender/modifiers/intern/MOD_screw.c b/source/blender/modifiers/intern/MOD_screw.c
index 8921ddb894f..e832a23b4ed 100644
--- a/source/blender/modifiers/intern/MOD_screw.c
+++ b/source/blender/modifiers/intern/MOD_screw.c
@@ -352,12 +352,9 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes
* Note! smaller then `FLT_EPSILON * 100`
* gives problems with float precision so its never closed. */
if (fabsf(screw_ofs) <= (FLT_EPSILON * 100.0f) &&
- fabsf(fabsf(angle) - ((float)M_PI * 2.0f)) <= (FLT_EPSILON * 100.0f)) {
+ fabsf(fabsf(angle) - ((float)M_PI * 2.0f)) <= (FLT_EPSILON * 100.0f) && step_tot > 3) {
close = 1;
step_tot--;
- if (step_tot < 3) {
- step_tot = 3;
- }
maxVerts = totvert * step_tot; /* -1 because we're joining back up */
maxEdges = (totvert * step_tot) + /* these are the edges between new verts */
@@ -368,8 +365,8 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes
}
else {
close = 0;
- if (step_tot < 3) {
- step_tot = 3;
+ if (step_tot < 2) {
+ step_tot = 2;
}
maxVerts = totvert * step_tot; /* -1 because we're joining back up */
diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.c
index 8ea0a602b65..0eed2335ed7 100644
--- a/source/blender/modifiers/intern/MOD_solidify.c
+++ b/source/blender/modifiers/intern/MOD_solidify.c
@@ -62,7 +62,8 @@ static void requiredDataMask(Object *UNUSED(ob),
SolidifyModifierData *smd = (SolidifyModifierData *)md;
/* ask for vertexgroups if we need them */
- if (smd->defgrp_name[0] != '\0') {
+ if (smd->defgrp_name[0] != '\0' || smd->shell_defgrp_name[0] != '\0' ||
+ smd->rim_defgrp_name[0] != '\0') {
r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
}
}
@@ -70,11 +71,13 @@ static void requiredDataMask(Object *UNUSED(ob),
static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
{
const SolidifyModifierData *smd = (SolidifyModifierData *)md;
- if (smd->mode == MOD_SOLIDIFY_MODE_EXTRUDE) {
- return MOD_solidify_extrude_applyModifier(md, ctx, mesh);
- }
- else if (smd->mode == MOD_SOLIDIFY_MODE_NONMANIFOLD) {
- return MOD_solidify_nonmanifold_applyModifier(md, ctx, mesh);
+ switch (smd->mode) {
+ case MOD_SOLIDIFY_MODE_EXTRUDE:
+ return MOD_solidify_extrude_applyModifier(md, ctx, mesh);
+ case MOD_SOLIDIFY_MODE_NONMANIFOLD:
+ return MOD_solidify_nonmanifold_applyModifier(md, ctx, mesh);
+ default:
+ BLI_assert(0);
}
return mesh;
}
diff --git a/source/blender/modifiers/intern/MOD_solidify_extrude.c b/source/blender/modifiers/intern/MOD_solidify_extrude.c
index 8febf78fef5..ecd62e5e1fe 100644
--- a/source/blender/modifiers/intern/MOD_solidify_extrude.c
+++ b/source/blender/modifiers/intern/MOD_solidify_extrude.c
@@ -240,6 +240,9 @@ Mesh *MOD_solidify_extrude_applyModifier(ModifierData *md,
MDeformVert *dvert;
const bool defgrp_invert = (smd->flag & MOD_SOLIDIFY_VGROUP_INV) != 0;
int defgrp_index;
+ const int shell_defgrp_index = BKE_object_defgroup_name_index(ctx->object,
+ smd->shell_defgrp_name);
+ const int rim_defgrp_index = BKE_object_defgroup_name_index(ctx->object, smd->rim_defgrp_name);
/* array size is doubled in case of using a shell */
const uint stride = do_shell ? 2 : 1;
@@ -886,6 +889,36 @@ Mesh *MOD_solidify_extrude_applyModifier(ModifierData *md,
}
}
+ /* Add vertex weights for rim and shell vgroups. */
+ if (shell_defgrp_index != -1 || rim_defgrp_index != -1) {
+ dvert = CustomData_duplicate_referenced_layer(&result->vdata, CD_MDEFORMVERT, result->totvert);
+ /* If no vertices were ever added to an object's vgroup, dvert might be NULL. */
+ if (dvert == NULL) {
+ /* Add a valid data layer! */
+ dvert = CustomData_add_layer(
+ &result->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, result->totvert);
+ }
+ /* Ultimate security check. */
+ if (!dvert) {
+ return result;
+ }
+ result->dvert = dvert;
+
+ if (rim_defgrp_index != -1) {
+ for (uint i = 0; i < rimVerts; i++) {
+ BKE_defvert_ensure_index(&result->dvert[new_vert_arr[i]], rim_defgrp_index)->weight = 1.0f;
+ BKE_defvert_ensure_index(&result->dvert[(do_shell ? new_vert_arr[i] : i) + numVerts],
+ rim_defgrp_index)
+ ->weight = 1.0f;
+ }
+ }
+
+ if (shell_defgrp_index != -1) {
+ for (uint i = numVerts; i < result->totvert; i++) {
+ BKE_defvert_ensure_index(&result->dvert[i], shell_defgrp_index)->weight = 1.0f;
+ }
+ }
+ }
if (smd->flag & MOD_SOLIDIFY_RIM) {
uint i;
diff --git a/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c b/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c
index 22fc56bdeaf..0f9f5952a26 100644
--- a/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c
+++ b/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c
@@ -178,6 +178,9 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md,
MDeformVert *dvert;
const bool defgrp_invert = (smd->flag & MOD_SOLIDIFY_VGROUP_INV) != 0;
int defgrp_index;
+ const int shell_defgrp_index = BKE_object_defgroup_name_index(ctx->object,
+ smd->shell_defgrp_name);
+ const int rim_defgrp_index = BKE_object_defgroup_name_index(ctx->object, smd->rim_defgrp_name);
MOD_get_vgroup(ctx->object, mesh, smd->defgrp_name, &dvert, &defgrp_index);
@@ -1778,6 +1781,18 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md,
int *origindex_edge = CustomData_get_layer(&result->edata, CD_ORIGINDEX);
int *origindex_poly = CustomData_get_layer(&result->pdata, CD_ORIGINDEX);
+ /* Checks that result has dvert data. */
+ if (shell_defgrp_index != -1 || rim_defgrp_index != -1) {
+ dvert = CustomData_duplicate_referenced_layer(&result->vdata, CD_MDEFORMVERT, result->totvert);
+ /* If no vertices were ever added to an object's vgroup, dvert might be NULL. */
+ if (dvert == NULL) {
+ /* Add a valid data layer! */
+ dvert = CustomData_add_layer(
+ &result->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, result->totvert);
+ }
+ result->dvert = dvert;
+ }
+
/* Make_new_verts. */
{
gs_ptr = orig_vert_groups_arr;
@@ -2101,12 +2116,20 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md,
MEdge *open_face_edge;
uint open_face_edge_index;
if (!do_flip) {
+ if (rim_defgrp_index != -1) {
+ BKE_defvert_ensure_index(&result->dvert[medge[edge1->new_edge].v1], rim_defgrp_index)
+ ->weight = 1.0f;
+ }
CustomData_copy_data(&mesh->ldata, &result->ldata, loop1, (int)loop_index, 1);
mloop[loop_index].v = medge[edge1->new_edge].v1;
mloop[loop_index++].e = edge1->new_edge;
if (!v2_singularity) {
open_face_edge_index = edge1->link_edge_groups[1]->open_face_edge;
+ if (rim_defgrp_index != -1) {
+ BKE_defvert_ensure_index(&result->dvert[medge[edge1->new_edge].v2], rim_defgrp_index)
+ ->weight = 1.0f;
+ }
CustomData_copy_data(&mesh->ldata, &result->ldata, loop2, (int)loop_index, 1);
mloop[loop_index].v = medge[edge1->new_edge].v2;
open_face_edge = medge + open_face_edge_index;
@@ -2118,12 +2141,20 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md,
}
}
+ if (rim_defgrp_index != -1) {
+ BKE_defvert_ensure_index(&result->dvert[medge[edge2->new_edge].v2], rim_defgrp_index)
+ ->weight = 1.0f;
+ }
CustomData_copy_data(&mesh->ldata, &result->ldata, loop2, (int)loop_index, 1);
mloop[loop_index].v = medge[edge2->new_edge].v2;
mloop[loop_index++].e = edge2->new_edge;
if (!v1_singularity) {
open_face_edge_index = edge2->link_edge_groups[0]->open_face_edge;
+ if (rim_defgrp_index != -1) {
+ BKE_defvert_ensure_index(&result->dvert[medge[edge2->new_edge].v1], rim_defgrp_index)
+ ->weight = 1.0f;
+ }
CustomData_copy_data(&mesh->ldata, &result->ldata, loop1, (int)loop_index, 1);
mloop[loop_index].v = medge[edge2->new_edge].v1;
open_face_edge = medge + open_face_edge_index;
@@ -2138,6 +2169,10 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md,
else {
if (!v1_singularity) {
open_face_edge_index = edge1->link_edge_groups[0]->open_face_edge;
+ if (rim_defgrp_index != -1) {
+ BKE_defvert_ensure_index(&result->dvert[medge[edge1->new_edge].v1], rim_defgrp_index)
+ ->weight = 1.0f;
+ }
CustomData_copy_data(&mesh->ldata, &result->ldata, loop1, (int)loop_index, 1);
mloop[loop_index].v = medge[edge1->new_edge].v1;
open_face_edge = medge + open_face_edge_index;
@@ -2149,12 +2184,20 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md,
}
}
+ if (rim_defgrp_index != -1) {
+ BKE_defvert_ensure_index(&result->dvert[medge[edge2->new_edge].v1], rim_defgrp_index)
+ ->weight = 1.0f;
+ }
CustomData_copy_data(&mesh->ldata, &result->ldata, loop1, (int)loop_index, 1);
mloop[loop_index].v = medge[edge2->new_edge].v1;
mloop[loop_index++].e = edge2->new_edge;
if (!v2_singularity) {
open_face_edge_index = edge2->link_edge_groups[1]->open_face_edge;
+ if (rim_defgrp_index != -1) {
+ BKE_defvert_ensure_index(&result->dvert[medge[edge2->new_edge].v2], rim_defgrp_index)
+ ->weight = 1.0f;
+ }
CustomData_copy_data(&mesh->ldata, &result->ldata, loop2, (int)loop_index, 1);
mloop[loop_index].v = medge[edge2->new_edge].v2;
open_face_edge = medge + open_face_edge_index;
@@ -2166,6 +2209,10 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md,
}
}
+ if (rim_defgrp_index != -1) {
+ BKE_defvert_ensure_index(&result->dvert[medge[edge1->new_edge].v2], rim_defgrp_index)
+ ->weight = 1.0f;
+ }
CustomData_copy_data(&mesh->ldata, &result->ldata, loop2, (int)loop_index, 1);
mloop[loop_index].v = medge[edge1->new_edge].v2;
mloop[loop_index++].e = edge1->new_edge;
@@ -2243,6 +2290,10 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md,
mpoly[poly_index].flag = fr->face->flag;
if (fr->reversed != do_flip) {
for (int l = (int)k - 1; l >= 0; l--) {
+ if (shell_defgrp_index != -1) {
+ BKE_defvert_ensure_index(&result->dvert[face_verts[l]], shell_defgrp_index)
+ ->weight = 1.0f;
+ }
CustomData_copy_data(
&mesh->ldata, &result->ldata, (int)face_loops[l], (int)loop_index, 1);
mloop[loop_index].v = face_verts[l];
diff --git a/source/blender/modifiers/intern/MOD_subsurf.c b/source/blender/modifiers/intern/MOD_subsurf.c
index 56180564be2..b3bc5a66e8c 100644
--- a/source/blender/modifiers/intern/MOD_subsurf.c
+++ b/source/blender/modifiers/intern/MOD_subsurf.c
@@ -58,7 +58,7 @@ static void initData(ModifierData *md)
smd->renderLevels = 2;
smd->uv_smooth = SUBSURF_UV_SMOOTH_PRESERVE_CORNERS;
smd->quality = 3;
- smd->flags |= eSubsurfModifierFlag_UseCrease;
+ smd->flags |= (eSubsurfModifierFlag_UseCrease | eSubsurfModifierFlag_ControlEdges);
}
static void copyData(const ModifierData *md, ModifierData *target, const int flag)
@@ -148,7 +148,8 @@ static void subdiv_mesh_settings_init(SubdivToMeshSettings *settings,
{
const int level = subdiv_levels_for_modifier_get(smd, ctx);
settings->resolution = (1 << level) + 1;
- settings->use_optimal_display = (smd->flags & eSubsurfModifierFlag_ControlEdges);
+ settings->use_optimal_display = (smd->flags & eSubsurfModifierFlag_ControlEdges) &&
+ !(ctx->flag & MOD_APPLY_TO_BASE_MESH);
}
static Mesh *subdiv_as_mesh(SubsurfModifierData *smd,
diff --git a/source/blender/modifiers/intern/MOD_surfacedeform.c b/source/blender/modifiers/intern/MOD_surfacedeform.c
index 57e7e2fa98b..4ef1f32462a 100644
--- a/source/blender/modifiers/intern/MOD_surfacedeform.c
+++ b/source/blender/modifiers/intern/MOD_surfacedeform.c
@@ -36,6 +36,8 @@
#include "BKE_mesh_runtime.h"
#include "BKE_modifier.h"
+#include "BKE_deform.h"
+
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_query.h"
@@ -110,6 +112,8 @@ typedef struct SDefDeformData {
const SDefVert *const bind_verts;
float (*const targetCos)[3];
float (*const vertexCos)[3];
+ float(*const weights);
+ float const strength;
} SDefDeformData;
/* Bind result values */
@@ -136,6 +140,19 @@ static void initData(ModifierData *md)
smd->verts = NULL;
smd->flags = 0;
smd->falloff = 4.0f;
+ smd->strength = 1.0f;
+}
+
+static void requiredDataMask(Object *UNUSED(ob),
+ ModifierData *md,
+ CustomData_MeshMasks *r_cddata_masks)
+{
+ SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
+
+ /* Ask for vertex groups if we need them. */
+ if (smd->defgrp_name[0] != '\0') {
+ r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
+ }
}
static void freeData(ModifierData *md)
@@ -1123,9 +1140,16 @@ static void deformVert(void *__restrict userdata,
const SDefBind *sdbind = data->bind_verts[index].binds;
const int num_binds = data->bind_verts[index].numbinds;
float *const vertexCos = data->vertexCos[index];
- float norm[3], temp[3];
+ float norm[3], temp[3], offset[3];
+ const float weight = (data->weights != NULL) ? data->weights[index] : 1.0f;
- zero_v3(vertexCos);
+ /* Check if this vertex will be deformed. If it is not deformed we return and avoid
+ * unnecessary calculations. */
+ if (weight == 0.0f) {
+ return;
+ }
+
+ zero_v3(offset);
/* Allocate a `coords_buffer` that fits all the temp-data. */
int max_verts = 0;
@@ -1170,8 +1194,13 @@ static void deformVert(void *__restrict userdata,
/* Apply normal offset (generic for all modes) */
madd_v3_v3fl(temp, norm, sdbind->normal_dist);
- madd_v3_v3fl(vertexCos, temp, sdbind->influence);
+ madd_v3_v3fl(offset, temp, sdbind->influence);
}
+ /* Subtract the vertex coord to get the deformation offset. */
+ sub_v3_v3(offset, vertexCos);
+
+ /* Add the offset to start coord multiplied by the strength and weight values. */
+ madd_v3_v3fl(vertexCos, offset, data->strength * weight);
MEM_freeN(coords_buffer);
}
@@ -1179,7 +1208,8 @@ static void surfacedeformModifier_do(ModifierData *md,
const ModifierEvalContext *ctx,
float (*vertexCos)[3],
uint numverts,
- Object *ob)
+ Object *ob,
+ Mesh *mesh)
{
SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
Mesh *target;
@@ -1238,11 +1268,44 @@ static void surfacedeformModifier_do(ModifierData *md,
return;
}
+ /* Early out if modifier would not affect input at all - still *after* the sanity checks (and
+ * potential binding) above.
+ */
+ if (smd->strength == 0.0f) {
+ return;
+ }
+
+ int defgrp_index;
+ MDeformVert *dvert;
+ MOD_get_vgroup(ob, mesh, smd->defgrp_name, &dvert, &defgrp_index);
+ float *weights = NULL;
+ const bool invert_group = (smd->flags & MOD_SDEF_INVERT_VGROUP) != 0;
+
+ if (defgrp_index != -1) {
+ dvert = CustomData_duplicate_referenced_layer(&mesh->vdata, CD_MDEFORMVERT, mesh->totvert);
+ /* If no vertices were ever added to an object's vgroup, dvert might be NULL. */
+ if (dvert == NULL) {
+ /* Add a valid data layer! */
+ dvert = CustomData_add_layer(&mesh->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, mesh->totvert);
+ }
+
+ if (dvert) {
+ weights = MEM_calloc_arrayN((size_t)numverts, sizeof(*weights), __func__);
+ MDeformVert *dv = dvert;
+ for (uint i = 0; i < numverts; i++, dv++) {
+ weights[i] = invert_group ? (1.0f - BKE_defvert_find_weight(dv, defgrp_index)) :
+ BKE_defvert_find_weight(dv, defgrp_index);
+ }
+ }
+ }
+
/* Actual vertex location update starts here */
SDefDeformData data = {
.bind_verts = smd->verts,
.targetCos = MEM_malloc_arrayN(tnumverts, sizeof(float[3]), "SDefTargetVertArray"),
.vertexCos = vertexCos,
+ .weights = weights,
+ .strength = smd->strength,
};
if (data.targetCos != NULL) {
@@ -1259,25 +1322,51 @@ static void surfacedeformModifier_do(ModifierData *md,
MEM_freeN(data.targetCos);
}
+
+ MEM_SAFE_FREE(weights);
}
static void deformVerts(ModifierData *md,
const ModifierEvalContext *ctx,
- Mesh *UNUSED(mesh),
+ Mesh *mesh,
float (*vertexCos)[3],
int numVerts)
{
- surfacedeformModifier_do(md, ctx, vertexCos, numVerts, ctx->object);
+ SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
+ Mesh *mesh_src = NULL;
+
+ if (smd->defgrp_name[0] != '\0') {
+ /* Only need to use mesh_src when a vgroup is used. */
+ mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
+ }
+
+ surfacedeformModifier_do(md, ctx, vertexCos, numVerts, ctx->object, mesh_src);
+
+ if (!ELEM(mesh_src, NULL, mesh)) {
+ BKE_id_free(NULL, mesh_src);
+ }
}
static void deformVertsEM(ModifierData *md,
const ModifierEvalContext *ctx,
- struct BMEditMesh *UNUSED(editData),
- Mesh *UNUSED(mesh),
+ struct BMEditMesh *em,
+ Mesh *mesh,
float (*vertexCos)[3],
int numVerts)
{
- surfacedeformModifier_do(md, ctx, vertexCos, numVerts, ctx->object);
+ SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
+ Mesh *mesh_src = NULL;
+
+ if (smd->defgrp_name[0] != '\0') {
+ /* Only need to use mesh_src when a vgroup is used. */
+ mesh_src = MOD_deform_mesh_eval_get(ctx->object, em, mesh, NULL, numVerts, false, false);
+ }
+
+ surfacedeformModifier_do(md, ctx, vertexCos, numVerts, ctx->object, mesh_src);
+
+ if (!ELEM(mesh_src, NULL, mesh)) {
+ BKE_id_free(NULL, mesh_src);
+ }
}
static bool isDisabled(const Scene *UNUSED(scene), ModifierData *md, bool UNUSED(useRenderParams))
@@ -1309,7 +1398,7 @@ ModifierTypeInfo modifierType_SurfaceDeform = {
/* applyModifier */ NULL,
/* initData */ initData,
- /* requiredDataMask */ NULL,
+ /* requiredDataMask */ requiredDataMask,
/* freeData */ freeData,
/* isDisabled */ isDisabled,
/* updateDepsgraph */ updateDepsgraph,
diff --git a/source/blender/modifiers/intern/MOD_warp.c b/source/blender/modifiers/intern/MOD_warp.c
index 4a98afbb91c..b8db14f610a 100644
--- a/source/blender/modifiers/intern/MOD_warp.c
+++ b/source/blender/modifiers/intern/MOD_warp.c
@@ -32,6 +32,7 @@
#include "BKE_colortools.h"
#include "BKE_deform.h"
+#include "BKE_action.h" /* BKE_pose_channel_find_name */
#include "BKE_editmesh.h"
#include "BKE_lib_id.h"
#include "BKE_lib_query.h"
@@ -85,6 +86,19 @@ static void requiredDataMask(Object *UNUSED(ob),
}
}
+static void matrix_from_obj_pchan(float mat[4][4], float obinv[4][4], Object *ob, const char *bonename)
+{
+ bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, bonename);
+ if (pchan) {
+ float mat_bone_world[4][4];
+ mul_m4_m4m4(mat_bone_world, ob->obmat, pchan->pose_mat);
+ mul_m4_m4m4(mat, obinv, mat_bone_world);
+ }
+ else {
+ mul_m4_m4m4(mat, obinv, ob->obmat);
+ }
+}
+
static bool dependsOnTime(ModifierData *md)
{
WarpModifierData *wmd = (WarpModifierData *)md;
@@ -135,15 +149,29 @@ static void foreachTexLink(ModifierData *md, Object *ob, TexWalkFunc walk, void
walk(userData, ob, md, "texture");
}
+static void warp_deps_object_bone_new(struct DepsNodeHandle *node,
+ Object *object,
+ const char *bonename)
+{
+ if (bonename[0] && object->type == OB_ARMATURE) {
+ DEG_add_object_relation(node, object, DEG_OB_COMP_EVAL_POSE, "Warp Modifier");
+ }
+ else {
+ DEG_add_object_relation(node, object, DEG_OB_COMP_TRANSFORM, "Warp Modifier");
+ }
+}
+
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
{
WarpModifierData *wmd = (WarpModifierData *)md;
+
if (wmd->object_from != NULL && wmd->object_to != NULL) {
- DEG_add_modifier_to_transform_relation(ctx->node, "Warplace Modifier");
- DEG_add_object_relation(
- ctx->node, wmd->object_from, DEG_OB_COMP_TRANSFORM, "Warp Modifier from");
- DEG_add_object_relation(ctx->node, wmd->object_to, DEG_OB_COMP_TRANSFORM, "Warp Modifier to");
+ warp_deps_object_bone_new(ctx->node, wmd->object_from, wmd->bone_from);
+ warp_deps_object_bone_new(ctx->node, wmd->object_to, wmd->bone_to);
+
+ DEG_add_modifier_to_transform_relation(ctx->node, "Warp Modifier");
}
+
if ((wmd->texmapping == MOD_DISP_MAP_OBJECT) && wmd->map_object != NULL) {
DEG_add_object_relation(
ctx->node, wmd->map_object, DEG_OB_COMP_TRANSFORM, "Warp Modifier map");
@@ -197,8 +225,9 @@ static void warpModifier_do(WarpModifierData *wmd,
invert_m4_m4(obinv, ob->obmat);
- mul_m4_m4m4(mat_from, obinv, wmd->object_from->obmat);
- mul_m4_m4m4(mat_to, obinv, wmd->object_to->obmat);
+ /* Checks that the objects/bones are available. */
+ matrix_from_obj_pchan(mat_from, obinv, wmd->object_from, wmd->bone_from);
+ matrix_from_obj_pchan(mat_to, obinv, wmd->object_to, wmd->bone_to);
invert_m4_m4(tmat, mat_from); // swap?
mul_m4_m4m4(mat_final, tmat, mat_to);
diff --git a/source/blender/modifiers/intern/MOD_weightvg_util.c b/source/blender/modifiers/intern/MOD_weightvg_util.c
index e93ab608498..23e4da32ed7 100644
--- a/source/blender/modifiers/intern/MOD_weightvg_util.c
+++ b/source/blender/modifiers/intern/MOD_weightvg_util.c
@@ -54,20 +54,22 @@
* mapping to the real vertex index (in case the weight tables do not cover the whole vertices...).
* cmap might be NULL, in which case curve mapping mode will return unmodified data.
*/
-void weightvg_do_map(int num, float *new_w, short falloff_type, CurveMapping *cmap, RNG *rng)
+void weightvg_do_map(
+ int num, float *new_w, short falloff_type, const bool do_invert, CurveMapping *cmap, RNG *rng)
{
int i;
/* Return immediately, if we have nothing to do! */
/* Also security checks... */
- if (((falloff_type == MOD_WVG_MAPPING_CURVE) && (cmap == NULL)) || !ELEM(falloff_type,
- MOD_WVG_MAPPING_CURVE,
- MOD_WVG_MAPPING_SHARP,
- MOD_WVG_MAPPING_SMOOTH,
- MOD_WVG_MAPPING_ROOT,
- MOD_WVG_MAPPING_SPHERE,
- MOD_WVG_MAPPING_RANDOM,
- MOD_WVG_MAPPING_STEP)) {
+ if (!do_invert && (((falloff_type == MOD_WVG_MAPPING_CURVE) && (cmap == NULL)) ||
+ !ELEM(falloff_type,
+ MOD_WVG_MAPPING_CURVE,
+ MOD_WVG_MAPPING_SHARP,
+ MOD_WVG_MAPPING_SMOOTH,
+ MOD_WVG_MAPPING_ROOT,
+ MOD_WVG_MAPPING_SPHERE,
+ MOD_WVG_MAPPING_RANDOM,
+ MOD_WVG_MAPPING_STEP))) {
return;
}
@@ -103,9 +105,14 @@ void weightvg_do_map(int num, float *new_w, short falloff_type, CurveMapping *cm
case MOD_WVG_MAPPING_STEP:
fac = (fac >= 0.5f) ? 1.0f : 0.0f;
break;
+ case MOD_WVG_MAPPING_NONE:
+ BLI_assert(do_invert);
+ break;
+ default:
+ BLI_assert(0);
}
- new_w[i] = fac;
+ new_w[i] = do_invert ? 1.0f - fac : fac;
}
}
diff --git a/source/blender/modifiers/intern/MOD_weightvg_util.h b/source/blender/modifiers/intern/MOD_weightvg_util.h
index fa3c61a6b6f..bcd1076eac6 100644
--- a/source/blender/modifiers/intern/MOD_weightvg_util.h
+++ b/source/blender/modifiers/intern/MOD_weightvg_util.h
@@ -52,8 +52,12 @@ struct Tex;
*/
#define MOD_WVG_ZEROFLOOR 1.0e-32f
-void weightvg_do_map(
- int num, float *new_w, short mode, struct CurveMapping *cmap, struct RNG *rng);
+void weightvg_do_map(int num,
+ float *new_w,
+ short mode,
+ const bool do_invert,
+ struct CurveMapping *cmap,
+ struct RNG *rng);
void weightvg_do_mask(const ModifierEvalContext *ctx,
const int num,
diff --git a/source/blender/modifiers/intern/MOD_weightvgedit.c b/source/blender/modifiers/intern/MOD_weightvgedit.c
index 6acbbefe745..ba1745f7b5e 100644
--- a/source/blender/modifiers/intern/MOD_weightvgedit.c
+++ b/source/blender/modifiers/intern/MOD_weightvgedit.c
@@ -230,14 +230,15 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes
}
/* Do mapping. */
- if (wmd->falloff_type != MOD_WVG_MAPPING_NONE) {
+ const bool do_invert_mapping = (wmd->edit_flags & MOD_WVG_INVERT_FALLOFF) != 0;
+ if (do_invert_mapping || wmd->falloff_type != MOD_WVG_MAPPING_NONE) {
RNG *rng = NULL;
if (wmd->falloff_type == MOD_WVG_MAPPING_RANDOM) {
rng = BLI_rng_new_srandom(BLI_ghashutil_strhash(ctx->object->id.name + 2));
}
- weightvg_do_map(numVerts, new_w, wmd->falloff_type, wmd->cmap_curve, rng);
+ weightvg_do_map(numVerts, new_w, wmd->falloff_type, do_invert_mapping, wmd->cmap_curve, rng);
if (rng) {
BLI_rng_free(rng);
diff --git a/source/blender/modifiers/intern/MOD_weightvgproximity.c b/source/blender/modifiers/intern/MOD_weightvgproximity.c
index e2e8e732311..7c9242ed900 100644
--- a/source/blender/modifiers/intern/MOD_weightvgproximity.c
+++ b/source/blender/modifiers/intern/MOD_weightvgproximity.c
@@ -239,8 +239,13 @@ static float get_ob2ob_distance(const Object *ob, const Object *obr)
/**
* Maps distances to weights, with an optional "smoothing" mapping.
*/
-static void do_map(
- Object *ob, float *weights, const int nidx, const float min_d, const float max_d, short mode)
+static void do_map(Object *ob,
+ float *weights,
+ const int nidx,
+ const float min_d,
+ const float max_d,
+ short mode,
+ const bool do_invert_mapping)
{
const float range_inv = 1.0f / (max_d - min_d); /* invert since multiplication is faster */
uint i = nidx;
@@ -276,14 +281,15 @@ static void do_map(
}
}
- if (!ELEM(mode, MOD_WVG_MAPPING_NONE, MOD_WVG_MAPPING_CURVE)) {
+ BLI_assert(mode != MOD_WVG_MAPPING_CURVE);
+ if (do_invert_mapping || mode != MOD_WVG_MAPPING_NONE) {
RNG *rng = NULL;
if (mode == MOD_WVG_MAPPING_RANDOM) {
rng = BLI_rng_new_srandom(BLI_ghashutil_strhash(ob->id.name + 2));
}
- weightvg_do_map(nidx, weights, mode, NULL, rng);
+ weightvg_do_map(nidx, weights, mode, do_invert_mapping, NULL, rng);
if (rng) {
BLI_rng_free(rng);
@@ -559,7 +565,13 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes
}
/* Map distances to weights. */
- do_map(ob, new_w, numIdx, wmd->min_dist, wmd->max_dist, wmd->falloff_type);
+ do_map(ob,
+ new_w,
+ numIdx,
+ wmd->min_dist,
+ wmd->max_dist,
+ wmd->falloff_type,
+ (wmd->proximity_flags & MOD_WVG_PROXIMITY_INVERT_FALLOFF) != 0);
/* Do masking. */
struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_image.c b/source/blender/nodes/shader/nodes/node_shader_tex_image.c
index b4b1c1d3698..bfef9341913 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_image.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_image.c
@@ -154,6 +154,12 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat,
/* equivalent to normal_world_to_object */
GPU_link(mat, "normal_transform_transposed_m4v3", vnor, ob_mat, &norm);
+ {
+ /* See SHD_PROJ_FLAT for explanation. */
+ GPU_link(mat, "set_rgb", *texco, texco);
+ GPU_link(mat, "set_rgb", *texco, &input_coords);
+ in[0].link = input_coords;
+ }
GPU_link(
mat, gpu_node_name, *texco, norm, GPU_image(mat, ima, iuser), &col1, &col2, &col3);
GPU_stack_link(
diff --git a/source/blender/python/generic/py_capi_utils.c b/source/blender/python/generic/py_capi_utils.c
index 35fff8699d1..9c84a4bb824 100644
--- a/source/blender/python/generic/py_capi_utils.c
+++ b/source/blender/python/generic/py_capi_utils.c
@@ -360,15 +360,15 @@ void PyC_StackSpit(void)
}
}
-void PyC_FileAndNum(const char **filename, int *lineno)
+void PyC_FileAndNum(const char **r_filename, int *r_lineno)
{
PyFrameObject *frame;
- if (filename) {
- *filename = NULL;
+ if (r_filename) {
+ *r_filename = NULL;
}
- if (lineno) {
- *lineno = -1;
+ if (r_lineno) {
+ *r_lineno = -1;
}
if (!(frame = PyThreadState_GET()->frame)) {
@@ -376,13 +376,13 @@ void PyC_FileAndNum(const char **filename, int *lineno)
}
/* when executing a script */
- if (filename) {
- *filename = _PyUnicode_AsString(frame->f_code->co_filename);
+ if (r_filename) {
+ *r_filename = _PyUnicode_AsString(frame->f_code->co_filename);
}
/* when executing a module */
- if (filename && *filename == NULL) {
- /* try an alternative method to get the filename - module based
+ if (r_filename && *r_filename == NULL) {
+ /* try an alternative method to get the r_filename - module based
* references below are all borrowed (double checked) */
PyObject *mod_name = PyDict_GetItemString(PyEval_GetGlobals(), "__name__");
if (mod_name) {
@@ -390,7 +390,7 @@ void PyC_FileAndNum(const char **filename, int *lineno)
if (mod) {
PyObject *mod_file = PyModule_GetFilenameObject(mod);
if (mod_file) {
- *filename = _PyUnicode_AsString(mod_name);
+ *r_filename = _PyUnicode_AsString(mod_name);
Py_DECREF(mod_file);
}
else {
@@ -399,24 +399,24 @@ void PyC_FileAndNum(const char **filename, int *lineno)
}
/* unlikely, fallback */
- if (*filename == NULL) {
- *filename = _PyUnicode_AsString(mod_name);
+ if (*r_filename == NULL) {
+ *r_filename = _PyUnicode_AsString(mod_name);
}
}
}
- if (lineno) {
- *lineno = PyFrame_GetLineNumber(frame);
+ if (r_lineno) {
+ *r_lineno = PyFrame_GetLineNumber(frame);
}
}
-void PyC_FileAndNum_Safe(const char **filename, int *lineno)
+void PyC_FileAndNum_Safe(const char **r_filename, int *r_lineno)
{
if (!PyC_IsInterpreterActive()) {
return;
}
- PyC_FileAndNum(filename, lineno);
+ PyC_FileAndNum(r_filename, r_lineno);
}
/* Would be nice if python had this built in */
diff --git a/source/blender/python/generic/py_capi_utils.h b/source/blender/python/generic/py_capi_utils.h
index 5fb5737e1f9..e8b2e8ff502 100644
--- a/source/blender/python/generic/py_capi_utils.h
+++ b/source/blender/python/generic/py_capi_utils.h
@@ -38,8 +38,8 @@ PyObject *PyC_Err_SetString_Prefix(PyObject *exception_type_prefix, const char *
void PyC_Err_PrintWithFunc(PyObject *py_func);
-void PyC_FileAndNum(const char **filename, int *lineno);
-void PyC_FileAndNum_Safe(const char **filename, int *lineno); /* checks python is running */
+void PyC_FileAndNum(const char **r_filename, int *r_lineno);
+void PyC_FileAndNum_Safe(const char **r_filename, int *r_lineno); /* checks python is running */
int PyC_AsArray_FAST(void *array,
PyObject *value_fast,
const Py_ssize_t length,
diff --git a/source/blender/python/intern/bpy_app_translations.c b/source/blender/python/intern/bpy_app_translations.c
index cf4550089ba..190d4eb1855 100644
--- a/source/blender/python/intern/bpy_app_translations.c
+++ b/source/blender/python/intern/bpy_app_translations.c
@@ -45,6 +45,10 @@
# include "BLI_string.h"
#endif
+/* ------------------------------------------------------------------- */
+/** \name Local Struct to Store Translation
+ * \{ */
+
typedef struct {
PyObject_HEAD
/** The string used to separate context from actual message in PY_TRANSLATE RNA props. */
@@ -63,9 +67,14 @@ typedef struct {
/* Our singleton instance pointer */
static BlenderAppTranslations *_translations = NULL;
+/** \} */
+
#ifdef WITH_INTERNATIONAL
-/***** Helpers for ghash *****/
+/* ------------------------------------------------------------------- */
+/** \name Helpers for GHash
+ * \{ */
+
typedef struct GHashKey {
const char *msgctxt;
const char *msgid;
@@ -111,7 +120,11 @@ static void _ghashutil_keyfree(void *ptr)
# define _ghashutil_valfree MEM_freeN
-/***** Python's messages cache *****/
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Python'S Messages Cache
+ * \{ */
/* We cache all messages available for a given locale from all py dicts into a single ghash.
* Changing of locale is not so common, while looking for a message translation is,
@@ -389,7 +402,12 @@ static PyObject *app_translations_py_messages_unregister(BlenderAppTranslations
Py_RETURN_NONE;
}
-/***** C-defined contexts *****/
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name C-defined Contexts
+ * \{ */
+
/* This is always available (even when WITH_INTERNATIONAL is not defined). */
static PyTypeObject BlenderAppTranslationsContextsType;
@@ -439,7 +457,11 @@ static PyObject *app_translations_contexts_make(void)
return translations_contexts;
}
-/***** Main BlenderAppTranslations Py object definition *****/
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Main #BlenderAppTranslations #PyObject Definition
+ * \{ */
PyDoc_STRVAR(app_translations_contexts_doc,
"A named tuple containing all pre-defined translation contexts.\n"
@@ -887,3 +909,5 @@ void BPY_app_translations_end(void)
_clear_translations_cache();
#endif
}
+
+/** \} */
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c
index e80c972e8bc..9579f78be30 100644
--- a/source/blender/python/intern/bpy_rna.c
+++ b/source/blender/python/intern/bpy_rna.c
@@ -5092,23 +5092,23 @@ static PyObject *pyrna_prop_collection_find(BPy_PropertyRNA *self, PyObject *key
static bool foreach_attr_type(BPy_PropertyRNA *self,
const char *attr,
/* Values to assign. */
- RawPropertyType *raw_type,
- int *attr_tot,
- bool *attr_signed)
+ RawPropertyType *r_raw_type,
+ int *r_attr_tot,
+ bool *r_attr_signed)
{
PropertyRNA *prop;
bool attr_ok = true;
- *raw_type = PROP_RAW_UNSET;
- *attr_tot = 0;
- *attr_signed = false;
+ *r_raw_type = PROP_RAW_UNSET;
+ *r_attr_tot = 0;
+ *r_attr_signed = false;
/* Note: this is fail with zero length lists, so don't let this get caled in that case. */
RNA_PROP_BEGIN (&self->ptr, itemptr, self->prop) {
prop = RNA_struct_find_property(&itemptr, attr);
if (prop) {
- *raw_type = RNA_property_raw_type(prop);
- *attr_tot = RNA_property_array_length(&itemptr, prop);
- *attr_signed = (RNA_property_subtype(prop) != PROP_UNSIGNED);
+ *r_raw_type = RNA_property_raw_type(prop);
+ *r_attr_tot = RNA_property_array_length(&itemptr, prop);
+ *r_attr_signed = (RNA_property_subtype(prop) != PROP_UNSIGNED);
}
else {
attr_ok = false;
@@ -5125,53 +5125,53 @@ static int foreach_parse_args(BPy_PropertyRNA *self,
PyObject *args,
/* Values to assign. */
- const char **attr,
- PyObject **seq,
- int *tot,
- int *size,
- RawPropertyType *raw_type,
- int *attr_tot,
- bool *attr_signed)
+ const char **r_attr,
+ PyObject **r_seq,
+ int *r_tot,
+ int *r_size,
+ RawPropertyType *r_raw_type,
+ int *r_attr_tot,
+ bool *r_attr_signed)
{
#if 0
int array_tot;
int target_tot;
#endif
- *size = *attr_tot = 0;
- *attr_signed = false;
- *raw_type = PROP_RAW_UNSET;
+ *r_size = *r_attr_tot = 0;
+ *r_attr_signed = false;
+ *r_raw_type = PROP_RAW_UNSET;
- if (!PyArg_ParseTuple(args, "sO:foreach_get/set", attr, seq)) {
+ if (!PyArg_ParseTuple(args, "sO:foreach_get/set", r_attr, r_seq)) {
return -1;
}
- if (!PySequence_Check(*seq) && PyObject_CheckBuffer(*seq)) {
+ if (!PySequence_Check(*r_seq) && PyObject_CheckBuffer(*r_seq)) {
PyErr_Format(
PyExc_TypeError,
"foreach_get/set expected second argument to be a sequence or buffer, not a %.200s",
- Py_TYPE(*seq)->tp_name);
+ Py_TYPE(*r_seq)->tp_name);
return -1;
}
/* TODO - buffer may not be a sequence! array.array() is though. */
- *tot = PySequence_Size(*seq);
+ *r_tot = PySequence_Size(*r_seq);
- if (*tot > 0) {
- if (!foreach_attr_type(self, *attr, raw_type, attr_tot, attr_signed)) {
+ if (*r_tot > 0) {
+ if (!foreach_attr_type(self, *r_attr, r_raw_type, r_attr_tot, r_attr_signed)) {
PyErr_Format(PyExc_AttributeError,
"foreach_get/set '%.200s.%200s[...]' elements have no attribute '%.200s'",
RNA_struct_identifier(self->ptr.type),
RNA_property_identifier(self->prop),
- *attr);
+ *r_attr);
return -1;
}
- *size = RNA_raw_type_sizeof(*raw_type);
+ *r_size = RNA_raw_type_sizeof(*r_raw_type);
#if 0 /* Works fine, but not strictly needed. \
* we could allow RNA_property_collection_raw_* to do the checks */
- if ((*attr_tot) < 1) {
- *attr_tot = 1;
+ if ((*r_attr_tot) < 1) {
+ *r_attr_tot = 1;
}
if (RNA_property_type(self->prop) == PROP_COLLECTION) {
@@ -5181,23 +5181,23 @@ static int foreach_parse_args(BPy_PropertyRNA *self,
array_tot = RNA_property_array_length(&self->ptr, self->prop);
}
- target_tot = array_tot * (*attr_tot);
+ target_tot = array_tot * (*r_attr_tot);
/* rna_access.c - rna_raw_access(...) uses this same method. */
- if (target_tot != (*tot)) {
+ if (target_tot != (*r_tot)) {
PyErr_Format(PyExc_TypeError,
"foreach_get(attr, sequence) sequence length mismatch given %d, needed %d",
- *tot,
+ *r_tot,
target_tot);
return -1;
}
#endif
}
- /* Check 'attr_tot' otherwise we don't know if any values were set.
+ /* Check 'r_attr_tot' otherwise we don't know if any values were set.
* This isn't ideal because it means running on an empty list may
* fail silently when it's not compatible. */
- if (*size == 0 && *attr_tot != 0) {
+ if (*r_size == 0 && *r_attr_tot != 0) {
PyErr_SetString(PyExc_AttributeError, "attribute does not support foreach method");
return -1;
}
diff --git a/source/blender/python/intern/bpy_rna_array.c b/source/blender/python/intern/bpy_rna_array.c
index 29e3a07625a..1e5b53b819e 100644
--- a/source/blender/python/intern/bpy_rna_array.c
+++ b/source/blender/python/intern/bpy_rna_array.c
@@ -262,7 +262,7 @@ static int validate_array_length(PyObject *rvalue,
PointerRNA *ptr,
PropertyRNA *prop,
int lvalue_dim,
- int *totitem,
+ int *r_totitem,
const char *error_prefix)
{
int dimsize[MAX_ARRAY_DIMENSION];
@@ -296,7 +296,7 @@ static int validate_array_length(PyObject *rvalue,
return -1;
}
#else
- *totitem = tot;
+ *r_totitem = tot;
return 0;
#endif
@@ -346,7 +346,7 @@ static int validate_array_length(PyObject *rvalue,
}
}
- *totitem = len;
+ *r_totitem = len;
return 0;
}
@@ -357,7 +357,7 @@ static int validate_array(PyObject *rvalue,
int lvalue_dim,
ItemTypeCheckFunc check_item_type,
const char *item_type_str,
- int *totitem,
+ int *r_totitem,
const char *error_prefix)
{
int dimsize[MAX_ARRAY_DIMENSION];
@@ -405,7 +405,7 @@ static int validate_array(PyObject *rvalue,
return -1;
}
else {
- *totitem = dimsize[0] * dimsize[1];
+ *r_totitem = dimsize[0] * dimsize[1];
return 0;
}
}
@@ -425,7 +425,7 @@ static int validate_array(PyObject *rvalue,
return -1;
}
- return validate_array_length(rvalue, ptr, prop, lvalue_dim, totitem, error_prefix);
+ return validate_array_length(rvalue, ptr, prop, lvalue_dim, r_totitem, error_prefix);
}
}
diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h
index 319d8b1c2ed..54296e16834 100644
--- a/source/blender/render/extern/include/RE_pipeline.h
+++ b/source/blender/render/extern/include/RE_pipeline.h
@@ -363,7 +363,7 @@ struct RenderPass *RE_pass_find_by_type(volatile struct RenderLayer *rl,
#define RE_BAKE_DISPLACEMENT 1
#define RE_BAKE_AO 2
-void RE_GetCameraWindow(struct Render *re, struct Object *camera, int frame, float mat[4][4]);
+void RE_GetCameraWindow(struct Render *re, struct Object *camera, float mat[4][4]);
void RE_GetCameraWindowWithOverscan(struct Render *re, float mat[4][4], float overscan);
void RE_GetCameraModelMatrix(struct Render *re, struct Object *camera, float r_mat[4][4]);
struct Scene *RE_GetScene(struct Render *re);
diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h
index 1318e2498bb..3ae4b9c0b90 100644
--- a/source/blender/render/intern/include/render_types.h
+++ b/source/blender/render/intern/include/render_types.h
@@ -123,11 +123,6 @@ struct Render {
Depsgraph *pipeline_depsgraph;
Scene *pipeline_scene_eval;
-#ifdef WITH_FREESTYLE
- struct Main *freestyle_bmain;
- ListBase freestyle_renders;
-#endif
-
/* callbacks */
void (*display_init)(void *handle, RenderResult *rr);
void *dih;
diff --git a/source/blender/render/intern/source/initrender.c b/source/blender/render/intern/source/initrender.c
index 5a6ecfc3e20..138d95af055 100644
--- a/source/blender/render/intern/source/initrender.c
+++ b/source/blender/render/intern/source/initrender.c
@@ -211,9 +211,8 @@ void RE_SetCamera(Render *re, Object *cam_ob)
re_camera_params_get(re, &params);
}
-void RE_GetCameraWindow(struct Render *re, struct Object *camera, int frame, float mat[4][4])
+void RE_GetCameraWindow(struct Render *re, struct Object *camera, float mat[4][4])
{
- re->r.cfra = frame;
RE_SetCamera(re, camera);
copy_m4_m4(mat, re->winmat);
}
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index 14a9ebcff5d..87568402df3 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -1149,14 +1149,6 @@ void RE_AddObject(Render *UNUSED(re), Object *UNUSED(ob))
}
#endif
-/* *************************************** */
-
-#ifdef WITH_FREESTYLE
-static void init_freestyle(Render *re);
-static void add_freestyle(Render *re, int render);
-static void free_all_freestyle_renders(void);
-#endif
-
/* ************ This part uses API, for rendering Blender scenes ********** */
static void do_render_3d(Render *re)
@@ -1365,87 +1357,6 @@ static void render_composit_stats(void *arg, const char *str)
re->stats_draw(re->sdh, &i);
}
-#ifdef WITH_FREESTYLE
-/* init Freestyle renderer */
-static void init_freestyle(Render *re)
-{
- re->freestyle_bmain = BKE_main_new();
-
- /* We use the same window manager for freestyle bmain as
- * real bmain uses. This is needed because freestyle's
- * bmain could be used to tag scenes for update, which
- * implies call of ED_render_scene_update in some cases
- * and that function requires proper window manager
- * to present (sergey)
- */
- re->freestyle_bmain->wm = re->main->wm;
-
- FRS_init_stroke_renderer(re);
-}
-
-/* invokes Freestyle stroke rendering */
-static void add_freestyle(Render *re, int render)
-{
- ViewLayer *view_layer, *active_view_layer;
- LinkData *link;
- Render *r;
-
- active_view_layer = BLI_findlink(&re->view_layers, re->active_view_layer);
-
- FRS_begin_stroke_rendering(re);
-
- for (view_layer = (ViewLayer *)re->view_layers.first; view_layer;
- view_layer = view_layer->next) {
- link = (LinkData *)MEM_callocN(sizeof(LinkData), "LinkData to Freestyle render");
- BLI_addtail(&re->freestyle_renders, link);
-
- if ((re->r.scemode & R_SINGLE_LAYER) && view_layer != active_view_layer) {
- continue;
- }
- if (FRS_is_freestyle_enabled(view_layer)) {
- r = FRS_do_stroke_rendering(re, view_layer, render);
- link->data = (void *)r;
- }
- }
-
- FRS_end_stroke_rendering(re);
-}
-
-/* releases temporary scenes and renders for Freestyle stroke rendering */
-static void free_all_freestyle_renders(void)
-{
- Render *re1;
- LinkData *link;
-
- for (re1 = RenderGlobal.renderlist.first; re1; re1 = re1->next) {
- for (link = (LinkData *)re1->freestyle_renders.first; link; link = link->next) {
- Render *freestyle_render = (Render *)link->data;
-
- if (freestyle_render) {
- Scene *freestyle_scene = freestyle_render->scene;
- RE_FreeRender(freestyle_render);
-
- if (freestyle_scene) {
- BKE_libblock_unlink(re1->freestyle_bmain, freestyle_scene, false, false);
- BKE_id_free(re1->freestyle_bmain, freestyle_scene);
- }
- }
- }
- BLI_freelistN(&re1->freestyle_renders);
-
- if (re1->freestyle_bmain) {
- /* detach the window manager from freestyle bmain (see comments
- * in add_freestyle() for more detail)
- */
- BLI_listbase_clear(&re1->freestyle_bmain->wm);
-
- BKE_main_free(re1->freestyle_bmain);
- re1->freestyle_bmain = NULL;
- }
- }
-}
-#endif
-
/* returns fully composited render-result on given time step (in RenderData) */
static void do_render_composite(Render *re)
{
@@ -1531,10 +1442,6 @@ static void do_render_composite(Render *re)
}
}
-#ifdef WITH_FREESTYLE
- free_all_freestyle_renders();
-#endif
-
/* weak... the display callback wants an active renderlayer pointer... */
if (re->result != NULL) {
re->result->renlay = render_get_active_layer(re, re->result);
@@ -2181,15 +2088,30 @@ void RE_RenderFreestyleStrokes(Render *re, Main *bmain, Scene *scene, int render
void RE_RenderFreestyleExternal(Render *re)
{
- if (!re->test_break(re->tbh)) {
- RenderView *rv;
+ if (re->test_break(re->tbh)) {
+ return;
+ }
- init_freestyle(re);
+ FRS_init_stroke_renderer(re);
+
+ for (RenderView *rv = re->result->views.first; rv; rv = rv->next) {
+ RE_SetActiveRenderView(re, rv->name);
- for (rv = re->result->views.first; rv; rv = rv->next) {
- RE_SetActiveRenderView(re, rv->name);
- add_freestyle(re, 1);
+ ViewLayer *active_view_layer = BLI_findlink(&re->view_layers, re->active_view_layer);
+ FRS_begin_stroke_rendering(re);
+
+ for (ViewLayer *view_layer = (ViewLayer *)re->view_layers.first; view_layer;
+ view_layer = view_layer->next) {
+ if ((re->r.scemode & R_SINGLE_LAYER) && view_layer != active_view_layer) {
+ continue;
+ }
+
+ if (FRS_is_freestyle_enabled(view_layer)) {
+ FRS_do_stroke_rendering(re, view_layer);
+ }
}
+
+ FRS_end_stroke_rendering(re);
}
}
#endif
diff --git a/source/blender/windowmanager/WM_keymap.h b/source/blender/windowmanager/WM_keymap.h
index 2cf71dcf165..ae2810dfb4d 100644
--- a/source/blender/windowmanager/WM_keymap.h
+++ b/source/blender/windowmanager/WM_keymap.h
@@ -135,10 +135,10 @@ char *WM_modalkeymap_operator_items_to_string_buf(struct wmOperatorType *ot,
int *r_available_len,
char **r_result);
-wmKeyMap *WM_modalkeymap_add(struct wmKeyConfig *keyconf,
- const char *idname,
- const struct EnumPropertyItem *items);
-wmKeyMap *WM_modalkeymap_get(struct wmKeyConfig *keyconf, const char *idname);
+wmKeyMap *WM_modalkeymap_ensure(struct wmKeyConfig *keyconf,
+ const char *idname,
+ const struct EnumPropertyItem *items);
+wmKeyMap *WM_modalkeymap_find(struct wmKeyConfig *keyconf, const char *idname);
wmKeyMapItem *WM_modalkeymap_add_item(
struct wmKeyMap *km, int type, int val, int modifier, int keymodifier, int value);
wmKeyMapItem *WM_modalkeymap_add_item_str(
diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c
index ef270533855..b7fecb31f96 100644
--- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c
+++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c
@@ -665,14 +665,14 @@ wmKeyMap *wm_gizmogroup_tweak_modal_keymap(wmKeyConfig *kc)
};
STRNCPY(name, "Generic Gizmo Tweak Modal Map");
- keymap = WM_modalkeymap_get(kc, name);
+ keymap = WM_modalkeymap_find(kc, name);
/* this function is called for each spacetype, only needs to add map once */
if (keymap && keymap->modal_items) {
return NULL;
}
- keymap = WM_modalkeymap_add(kc, name, modal_items);
+ keymap = WM_modalkeymap_ensure(kc, name, modal_items);
/* items for modal map */
WM_modalkeymap_add_item(keymap, EVT_ESCKEY, KM_PRESS, KM_ANY, 0, TWEAK_MODAL_CANCEL);
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 6f133e063f7..1a794e9bf0b 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -870,6 +870,10 @@ static void wm_operator_reports(bContext *C, wmOperator *op, int retval, bool ca
}
}
+ /* Refresh Info Editor with reports immediately, even if op returned OPERATOR_CANCELLED. */
+ if ((retval & OPERATOR_CANCELLED) && !BLI_listbase_is_empty(&op->reports->list)) {
+ WM_event_add_notifier(C, NC_SPACE | ND_SPACE_INFO_REPORT, NULL);
+ }
/* if the caller owns them, handle this */
wm_add_reports(op->reports);
}
@@ -1864,6 +1868,8 @@ static wmKeyMapItem *wm_eventmatch_modal_keymap_items(const wmKeyMap *keymap,
const wmEvent *event)
{
for (wmKeyMapItem *kmi = keymap->items.first; kmi; kmi = kmi->next) {
+ /* Should already be handled by #wm_user_modal_keymap_set_items. */
+ BLI_assert(kmi->propvalue_str[0] == '\0');
if (wm_eventmatch(event, kmi)) {
if ((keymap->poll_modal_item == NULL) || (keymap->poll_modal_item(op, kmi->propvalue))) {
return kmi;
diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c
index 3f4d082f9f7..fa59bad7a6b 100644
--- a/source/blender/windowmanager/intern/wm_files.c
+++ b/source/blender/windowmanager/intern/wm_files.c
@@ -1047,8 +1047,8 @@ void wm_homefile_read(bContext *C,
}
if (use_userdef) {
- /* Clear keymaps because the current default keymap may have been initialized
- * from user preferences, which have been reset. */
+ /* Clear keymaps because the current default keymap may have been initialized
+ * from user preferences, which have been reset. */
for (wmWindowManager *wm = bmain->wm.first; wm; wm = wm->id.next) {
if (wm->defaultconf) {
wm->defaultconf->flag &= ~KEYCONF_INIT_DEFAULT;
@@ -1532,7 +1532,7 @@ void wm_autosave_timer(Main *bmain, wmWindowManager *wm, wmTimer *UNUSED(wt))
}
}
else {
- /* save as regular blend file */
+ /* Save as regular blend file. */
int fileflags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_HISTORY);
ED_editors_flush_edits(bmain);
@@ -1665,7 +1665,7 @@ static int wm_homefile_write_exec(bContext *C, wmOperator *op)
ED_editors_flush_edits(bmain);
- /* force save as regular blend file */
+ /* Force save as regular blend file. */
fileflags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_HISTORY);
if (BLO_write_file(bmain, filepath, fileflags, op->reports, NULL) == 0) {
diff --git a/source/blender/windowmanager/intern/wm_files_link.c b/source/blender/windowmanager/intern/wm_files_link.c
index c2c3b24469e..5acc8a5fbc6 100644
--- a/source/blender/windowmanager/intern/wm_files_link.c
+++ b/source/blender/windowmanager/intern/wm_files_link.c
@@ -74,7 +74,9 @@
#include "wm_files.h"
-/* **************** link/append *************** */
+/* -------------------------------------------------------------------- */
+/** \name Link/Append Operator
+ * \{ */
static bool wm_link_append_poll(bContext *C)
{
@@ -618,10 +620,12 @@ void WM_OT_append(wmOperatorType *ot)
"Localize all appended data, including those indirectly linked from other libraries");
}
-/** \name Append single datablock and return it.
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Append Single Data-Block & Return it
*
* Used for appending workspace from startup files.
- *
* \{ */
ID *WM_file_append_datablock(Main *bmain,
@@ -660,6 +664,10 @@ ID *WM_file_append_datablock(Main *bmain,
/** \} */
+/* -------------------------------------------------------------------- */
+/** \name Library Relocate Operator & Library Reload API
+ * \{ */
+
static int wm_lib_relocate_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Library *lib;
diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c
index b640fdb59c9..17d697840a0 100644
--- a/source/blender/windowmanager/intern/wm_init_exit.c
+++ b/source/blender/windowmanager/intern/wm_init_exit.c
@@ -217,10 +217,10 @@ static void sound_jack_sync_callback(Main *bmain, int mode, float time)
if (depsgraph == NULL) {
continue;
}
- BKE_sound_lock_scene(scene);
+ BKE_sound_lock();
Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
BKE_sound_jack_scene_update(scene_eval, mode, time);
- BKE_sound_unlock_scene(scene);
+ BKE_sound_unlock();
}
}
@@ -609,8 +609,6 @@ void WM_exit_ex(bContext *C, const bool do_python)
}
#ifdef WITH_INTERNATIONAL
- BLF_free_unifont();
- BLF_free_unifont_mono();
BLT_lang_free();
#endif
diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c
index c1a4595ec6b..890aeb71e1a 100644
--- a/source/blender/windowmanager/intern/wm_keymap.c
+++ b/source/blender/windowmanager/intern/wm_keymap.c
@@ -911,9 +911,9 @@ wmKeyMap *WM_keymap_find_all_spaceid_or_empty(wmWindowManager *wm,
* and filter the keys before sending to #wmOperatorType.modal callback.
* \{ */
-wmKeyMap *WM_modalkeymap_add(wmKeyConfig *keyconf,
- const char *idname,
- const EnumPropertyItem *items)
+wmKeyMap *WM_modalkeymap_ensure(wmKeyConfig *keyconf,
+ const char *idname,
+ const EnumPropertyItem *items)
{
wmKeyMap *km = WM_keymap_ensure(keyconf, idname, 0, 0);
km->flag |= KEYMAP_MODAL;
@@ -937,7 +937,7 @@ wmKeyMap *WM_modalkeymap_add(wmKeyConfig *keyconf,
return km;
}
-wmKeyMap *WM_modalkeymap_get(wmKeyConfig *keyconf, const char *idname)
+wmKeyMap *WM_modalkeymap_find(wmKeyConfig *keyconf, const char *idname)
{
wmKeyMap *km;
@@ -1900,6 +1900,8 @@ void WM_keyconfig_update(wmWindowManager *wm)
addonmap = WM_keymap_list_find(&wm->addonconf->keymaps, km->idname, km->spaceid, km->regionid);
usermap = WM_keymap_list_find(&U.user_keymaps, km->idname, km->spaceid, km->regionid);
+ /* For now only the default map defines modal key-maps,
+ * if we support modal keymaps for 'addonmap', these will need to be enabled too. */
wm_user_modal_keymap_set_items(wm, defaultmap);
/* add */
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 853da714f76..e782b802729 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -3833,14 +3833,14 @@ static void gesture_circle_modal_keymap(wmKeyConfig *keyconf)
};
/* WARNING - name is incorrect, use for non-3d views */
- wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "View3D Gesture Circle");
+ wmKeyMap *keymap = WM_modalkeymap_find(keyconf, "View3D Gesture Circle");
/* this function is called for each spacetype, only needs to add map once */
if (keymap && keymap->modal_items) {
return;
}
- keymap = WM_modalkeymap_add(keyconf, "View3D Gesture Circle", modal_items);
+ keymap = WM_modalkeymap_ensure(keyconf, "View3D Gesture Circle", modal_items);
/* assign map to operators */
WM_modalkeymap_assign(keymap, "VIEW3D_OT_select_circle");
@@ -3863,14 +3863,14 @@ static void gesture_straightline_modal_keymap(wmKeyConfig *keyconf)
{0, NULL, 0, NULL, NULL},
};
- wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "Gesture Straight Line");
+ wmKeyMap *keymap = WM_modalkeymap_find(keyconf, "Gesture Straight Line");
/* this function is called for each spacetype, only needs to add map once */
if (keymap && keymap->modal_items) {
return;
}
- keymap = WM_modalkeymap_add(keyconf, "Gesture Straight Line", modal_items);
+ keymap = WM_modalkeymap_ensure(keyconf, "Gesture Straight Line", modal_items);
/* assign map to operators */
WM_modalkeymap_assign(keymap, "IMAGE_OT_sample_line");
@@ -3889,14 +3889,14 @@ static void gesture_box_modal_keymap(wmKeyConfig *keyconf)
{0, NULL, 0, NULL, NULL},
};
- wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "Gesture Box");
+ wmKeyMap *keymap = WM_modalkeymap_find(keyconf, "Gesture Box");
/* this function is called for each spacetype, only needs to add map once */
if (keymap && keymap->modal_items) {
return;
}
- keymap = WM_modalkeymap_add(keyconf, "Gesture Box", modal_items);
+ keymap = WM_modalkeymap_ensure(keyconf, "Gesture Box", modal_items);
/* assign map to operators */
WM_modalkeymap_assign(keymap, "ACTION_OT_select_box");
@@ -3940,14 +3940,14 @@ static void gesture_zoom_border_modal_keymap(wmKeyConfig *keyconf)
{0, NULL, 0, NULL, NULL},
};
- wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "Gesture Zoom Border");
+ wmKeyMap *keymap = WM_modalkeymap_find(keyconf, "Gesture Zoom Border");
/* this function is called for each spacetype, only needs to add map once */
if (keymap && keymap->modal_items) {
return;
}
- keymap = WM_modalkeymap_add(keyconf, "Gesture Zoom Border", modal_items);
+ keymap = WM_modalkeymap_ensure(keyconf, "Gesture Zoom Border", modal_items);
/* assign map to operators */
WM_modalkeymap_assign(keymap, "VIEW2D_OT_zoom_border");
diff --git a/source/blender/windowmanager/intern/wm_playanim.c b/source/blender/windowmanager/intern/wm_playanim.c
index c6eb1393ffe..8a872010ecc 100644
--- a/source/blender/windowmanager/intern/wm_playanim.c
+++ b/source/blender/windowmanager/intern/wm_playanim.c
@@ -1292,8 +1292,7 @@ static char *wm_main_playanim_intern(int argc, const char **argv)
/* initialize the font */
BLF_init();
- ps.fontid = BLF_load_mem(
- "monospace", (unsigned char *)datatoc_bmonofont_ttf, datatoc_bmonofont_ttf_size);
+ ps.fontid = BLF_load_mono_default(false);
BLF_size(ps.fontid, 11, 72);
ps.ibufx = ibuf->x;
diff --git a/source/blender/windowmanager/intern/wm_toolsystem.c b/source/blender/windowmanager/intern/wm_toolsystem.c
index 4cfd1d1e0c0..551250ec747 100644
--- a/source/blender/windowmanager/intern/wm_toolsystem.c
+++ b/source/blender/windowmanager/intern/wm_toolsystem.c
@@ -73,7 +73,7 @@ struct bToolRef *WM_toolsystem_ref_from_context(struct bContext *C)
WorkSpace *workspace = CTX_wm_workspace(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
ScrArea *sa = CTX_wm_area(C);
- if (((1 << sa->spacetype) & WM_TOOLSYSTEM_SPACE_MASK) == 0) {
+ if ((sa == NULL) || ((1 << sa->spacetype) & WM_TOOLSYSTEM_SPACE_MASK) == 0) {
return NULL;
}
const bToolKey tkey = {
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index a3e1814f8d2..505383d295f 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -414,7 +414,7 @@ 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 = GHOST_IsDialogWindow(win->ghostwin);
+ 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) {
@@ -434,9 +434,13 @@ void wm_window_close(bContext *C, wmWindowManager *wm, wmWindow *win)
if (iter_win->parent == win) {
wm_window_close(C, wm, iter_win);
}
- else if (is_dialog && iter_win != win && iter_win->parent &&
- (GHOST_GetWindowState(iter_win->ghostwin) != GHOST_kWindowStateMinimized)) {
- wm_window_raise(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);
+ }
+ }
}
}
diff --git a/source/blender/windowmanager/intern/wm_xr.c b/source/blender/windowmanager/intern/wm_xr.c
index 95c0f353298..18c3b70ed01 100644
--- a/source/blender/windowmanager/intern/wm_xr.c
+++ b/source/blender/windowmanager/intern/wm_xr.c
@@ -300,7 +300,13 @@ static void wm_xr_draw_data_populate(const wmXrSessionState *state,
wm_xr_base_pose_calc(scene, settings, &r_draw_data->base_pose);
- if (position_tracking_toggled || !state->is_view_data_set) {
+ /* Set the eye position offset, it's used to offset the base pose when changing positional
+ * tracking. */
+ if (!state->is_view_data_set) {
+ /* Always use the exact base pose with no offset when starting the session. */
+ copy_v3_fl(r_draw_data->eye_position_ofs, 0.0f);
+ }
+ else if (position_tracking_toggled) {
if (use_position_tracking) {
copy_v3_fl(r_draw_data->eye_position_ofs, 0.0f);
}
@@ -748,8 +754,8 @@ void wm_xr_draw_view(const GHOST_XrDrawViewInfo *draw_view, void *customdata)
* viewport buffers composited together and potentially color managed for display on screen.
* It needs a bound frame-buffer to draw into, for which we simply reuse the GPUOffscreen one.
*
- * In a next step, Ghost-XR will use the the currently bound frame-buffer to retrieve the image
- * to be submitted to the OpenXR swap-chain. So do not un-bind the offscreen yet! */
+ * In a next step, Ghost-XR will use the currently bound frame-buffer to retrieve the image
+ * to be submitted to the OpenXR swap-chain. So do not un-bind the off-screen yet! */
GPU_offscreen_bind(surface_data->offscreen, false);
diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt
index bbef3a4d52a..ced0532a8fa 100644
--- a/source/creator/CMakeLists.txt
+++ b/source/creator/CMakeLists.txt
@@ -304,12 +304,10 @@ if(WITH_MEM_JEMALLOC)
)
endif()
-if(WITH_INTERNATIONAL)
- list(APPEND BLENDER_TEXT_FILES
- ${CMAKE_SOURCE_DIR}/release/datafiles/LICENSE-droidsans.ttf.txt
- ${CMAKE_SOURCE_DIR}/release/datafiles/LICENSE-bmonofont-i18n.ttf.txt
- )
-endif()
+list(APPEND BLENDER_TEXT_FILES
+ ${CMAKE_SOURCE_DIR}/release/datafiles/LICENSE-droidsans.ttf.txt
+ ${CMAKE_SOURCE_DIR}/release/datafiles/LICENSE-bmonofont-i18n.ttf.txt
+)
# -----------------------------------------------------------------------------
@@ -387,14 +385,15 @@ if(WITH_PYTHON)
unset(FREESTYLE_EXCLUDE_CONDITIONAL)
endif()
+# fonts
+install(
+ DIRECTORY
+ ${CMAKE_SOURCE_DIR}/release/datafiles/fonts
+ DESTINATION ${TARGETDIR_VER}/datafiles
+)
+
# localization
if(WITH_INTERNATIONAL)
- install(
- DIRECTORY
- ${CMAKE_SOURCE_DIR}/release/datafiles/fonts
- DESTINATION ${TARGETDIR_VER}/datafiles
- )
-
set(_locale_dir "${CMAKE_SOURCE_DIR}/release/datafiles/locale")
set(_locale_target_dir ${TARGETDIR_VER}/datafiles/locale)
@@ -922,6 +921,11 @@ elseif(APPLE)
OUTPUT_STRIP_TRAILING_WHITESPACE)
# Give the bundle actual creation/modification date
+ #
+ # Note that the directory might not yet exist, which happens when CMake is first run.
+ if(NOT EXISTS ${EXECUTABLE_OUTPUT_PATH}/Blender.app)
+ file(MAKE_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}/Blender.app)
+ endif()
execute_process(COMMAND SetFile -d ${SETFILE_DATE} -m ${SETFILE_DATE}
${EXECUTABLE_OUTPUT_PATH}/Blender.app)
diff --git a/source/creator/blender.map b/source/creator/blender.map
index 4c34dea3338..3e447ec9e89 100644
--- a/source/creator/blender.map
+++ b/source/creator/blender.map
@@ -6,21 +6,71 @@
{
global:
- *;
- *_boost*;
+ *;
+ *_boost*;
local:
- *default_error_condition*;
- *llvm*;
- *LLVM*;
- decodeInstruction;
- ForceStackAlign;
- _Jv_RegisterClasses;
- Name;
- NumNamedVarArgParams;
- X86CompilationCallback*;
- *boost*;
- *SDL*;
- *embree*;
- cu*;
+ al*;
+ *Alembic*;
+ av*;
+ blosc*;
+ *boost*;
+ *ceres*;
+ *cineon*;
+ *COLLADA*;
+ cu*;
+ decodeInstruction;
+ *default_error_condition*;
+ *dpx*;
+ *embree*;
+ ff_*;
+ fftw*;
+ FLAC*;
+ ForceStackAlign;
+ FT_*;
+ *GeneratedSaxParser*;
+ *google*;
+ gsm*;
+ Gsm*;
+ html*;
+ id3tag*;
+ *Iex*;
+ *Ilm*;
+ *Imath*;
+ *Imf*;
+ jack_*;
+ jpeg_*;
+ jsimd**;
+ _Jv_RegisterClasses;
+ lame_*;
+ *llvm*;
+ *LLVM*;
+ *MathML*;
+ *mkldnn*;
+ Name;
+ NumNamedVarArgParams;
+ oc_*;
+ ogg*;
+ *oidn*;
+ *OpenColorIO*;
+ *OpenImageIO*;
+ *OpenSubdiv*;
+ *openvdb*;
+ opj_*;
+ opus_*;
+ *OSL*;
+ png_*;
+ *SDL*;
+ *squish*;
+ *tbb*;
+ *TIFF*;
+ *tinyformat*;
+ vorbis*;
+ vp8*;
+ vp9*;
+ vpx*;
+ x264_*;
+ X86CompilationCallback*;
+ xml*;
+ xvid*;
+ *YAML*;
};
-
diff --git a/source/creator/creator.c b/source/creator/creator.c
index a6c0e50e527..75523024aa4 100644
--- a/source/creator/creator.c
+++ b/source/creator/creator.c
@@ -108,7 +108,7 @@
#include "creator_intern.h" /* own include */
-/* Local Function prototypes */
+/* Local Function prototypes. */
#ifdef WITH_PYTHON_MODULE
int main_python_enter(int argc, const char **argv);
void main_python_exit(void);
diff --git a/source/creator/creator_args.c b/source/creator/creator_args.c
index 7b5a448fc53..a5b9df166a4 100644
--- a/source/creator/creator_args.c
+++ b/source/creator/creator_args.c
@@ -619,7 +619,7 @@ static int arg_handle_print_help(int UNUSED(argc), const char **UNUSED(argv), vo
printf("Misc Options:\n");
BLI_argsPrintArgDoc(ba, "--app-template");
BLI_argsPrintArgDoc(ba, "--factory-startup");
- BLI_argsPrintArgDoc(ba, "--enable-library-override");
+ BLI_argsPrintArgDoc(ba, "--disable-library-override");
BLI_argsPrintArgDoc(ba, "--enable-event-simulate");
printf("\n");
BLI_argsPrintArgDoc(ba, "--env-system-datafiles");
diff --git a/source/creator/osx_locals.map b/source/creator/osx_locals.map
index 3382ac954e2..908bfdae6cb 100644
--- a/source/creator/osx_locals.map
+++ b/source/creator/osx_locals.map
@@ -1,10 +1,66 @@
## The symbols will be treated as if they were marked as __private_extern__
## (aka visibility=hidden) and will not be global in the output file
+al*
+*Alembic*
+av*
+blosc*
*boost*
-*__ZNSt6vector*
+*ceres*
+*cineon*
+*COLLADA*
+cu*
+decodeInstruction
+*default_error_condition*
+*dpx*
+*embree*
+ff_*
+fftw*
+FLAC*
+ForceStackAlign
+FT_*
+*GeneratedSaxParser*
+*google*
+gsm*
+Gsm*
+html*
+id3tag*
+*Iex*
+*Ilm*
+*Imath*
+*Imf*
+jack_*
+jpeg_*
+jsimd**
+_Jv_RegisterClasses
+lame_*
*llvm*
*LLVM*
+*MathML*
+*mkldnn*
+Name
+NumNamedVarArgParams
+oc_*
+ogg*
+*oidn*
+*OpenColorIO*
+*OpenImageIO*
+*OpenSubdiv*
+*openvdb*
+opj_*
+opus_*
*OSL*
-*embree*
-cu*
-
+png_*
+*SDL*
+*squish*
+*tbb*
+*TIFF*
+*tinyformat*
+vorbis*
+vp8*
+vp9*
+vpx*
+x264_*
+X86CompilationCallback*
+xml*
+xvid*
+*YAML*
diff --git a/source/tools b/source/tools
-Subproject 603f076606f052adc97d937633bfeb9b268ec20
+Subproject 2afbb8ec472cac5102eb239f57b006f8c938768